Files
danyang-match/artifacts/ui-redesign/miniapp/preview.html
T
WorkBuddy 45e84722e1 fix(miniapp): 修复底部 tabBar 图标全部消失(开发者工具误删 app.json 专属图标)
根因:微信开发者工具(>=1.05.2112301)的 ignoreDevUnusedFiles 会按 WXML/JS 依赖分析过滤
"无依赖"文件。tabBar 图标仅在 app.json 中声明,不属于任何页面 WXML/JS 依赖,被误判为无用
文件从开发包剥离,导致 5 个图标全部加载失败(渲染为破图占位)。

修复:
- 在 project.config.json 与 miniapp/project.config.json 的 setting 中显式关闭
  ignoreDevUnusedFiles / ignoreUploadUnusedFiles(false),阻止图标被过滤。
- 同步关闭本地 gitignore 的 project.private.config.json(DevTools 运行时实际读取项)。
- 预览通道 scripts/preview-miniapp.mjs:补全 /assets 绝对路径→相对路径重写,并手动复刻
  原生 tabBar(原生 tabBar 不在任何页面 WXML 中,静态预览需自行复刻)。
- 回归守卫 ui-tests/tabbar-icons.mjs 扩充为 5 段,覆盖根因(配置开关)+ 预览复刻。
- miniapp/assets/tabbar/DESIGN.md 增加根因警示,防止后续被误开开关。

验证:UI 契约 23/23 全绿(tabbar-icons.mjs 位于 [19/23]);CDP 渲染实测 127 张图 0 破图,
5 个 tabBar 图标 naturalW=81 全部加载,选中色 rgb(233,107,107)、未选 rgb(153,153,153),
与 app.json selectedColor/color 一致。
2026-09-23 15:57:04 +08:00

9028 lines
442 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>小程序 11 页静态预览 · 善缘丹阳</title>
<style>
:root { --ink:#1f2744; --muted:#7d839b; --line:#e6e9f2; --brand:#ff4f91; }
* { box-sizing: border-box; }
body { margin:0; font-family: -apple-system, "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
background:#f4f5fa; color:var(--ink); }
.banner { position:sticky; top:0; z-index:10; background:#fff; border-bottom:1px solid var(--line);
padding:14px 20px; display:flex; flex-wrap:wrap; gap:8px; align-items:center; }
.banner h1 { font-size:15px; margin:0 16px 0 0; font-weight:650; }
.banner .note { font-size:12px; color:var(--muted); margin-left:auto; }
.nav-btn { border:1px solid var(--line); background:#fff; color:var(--ink); border-radius:16px;
padding:5px 12px; font-size:12px; cursor:pointer; }
.nav-btn.active { background:var(--brand); border-color:var(--brand); color:#fff; }
.stage { padding:28px; display:flex; justify-content:center; }
.preview-panel { width:100%; max-width:420px; }
.panel-caption { font-size:12px; color:var(--muted); margin-bottom:10px; text-align:center; }
.phone { background:#fff; border-radius:36px; padding:12px; box-shadow:0 20px 60px rgba(28,30,88,.18); }
.phone-screen { width:100%; height:760px; overflow-y:auto; border-radius:26px; background:#F4F5FA; }
.wx-page { min-height:100%; }
/* 原生 tabBar 复刻。颜色/边框取 app.json 的 tabBar 字段:
color #999999 / selectedColor #E96B6B / backgroundColor #FFFFFF / borderStyle black。
图标按微信客户端实际渲染尺寸(约 26px)呈现,与 81px 源图尺寸不同;文字 10px 同理。 */
.mini-tabbar { position:sticky; bottom:0; z-index:20; display:flex; align-items:stretch;
background:#FFFFFF; border-top:1px solid rgba(0,0,0,.2); padding-bottom:20px; }
.mini-tabbar__item { flex:1 1 0; min-width:0; display:flex; flex-direction:column;
align-items:center; justify-content:center; gap:2px; padding:6px 0 0; }
.mini-tabbar__icon { width:26px; height:26px; display:block; }
.mini-tabbar__label { font-size:10px; line-height:14px; color:#999999; }
.mini-tabbar__item.is-active .mini-tabbar__label { color:#E96B6B; }
/* ====== 以下为页面 WXSS 转换结果(rpx 已按 375 宽换算) ====== */
/**
* 丹阳公益婚恋服务平台 - 全局 Design Token
*
* v2(2026-09-22 设计系统夯实)
* ---------------------------------------------------------------
* 本次修订针对审计发现的系统性问题,逐条给出依据:
*
* 1) 品牌色不能承载文字 → 引入「基础色 / -strong」分级
* #E96B6B on 白 = 3.10:1,白字 on #E96B6B = 3.10:1,on #FFF3F2 = 2.85:1,
* 三条路径都不满足正文 4.5:1。故:
* --color-primary 仅用于大色块、渐变、光晕、装饰(非文字)
* --color-primary-strong 用于文字、小图标、纯文字链接(5.33:1 ✓)
* --color-primary-solid 实心按钮底(白字 ≥4.5:1 ✓)
* 功能色(success/warning/danger/info)同此分级。
*
* 2) 次要文字对比度过低
* 旧 --color-text-tertiary(#777) = 4.48(on 白,勉强)/ #999 实测 2.85 却被用了 71 次。
* 现将三级文字压到 #646C85 = 5.22:1,占位符保留浅色(占位符非正文)。
*
* 3) 颜色碎片化
* 审计前全站 182 种 hex、770 次硬编码(54 种灰、60 种蓝紫、40 种红橙)。
* 本文件是唯一的颜色事实源;页面层禁止再写 hex,一律 var(--token)。
*
* 4) 触摸目标
* 组件库默认按钮只有 40px、小号 28px、"喜欢"按钮 31px。
* 统一以 --tap-min(44.00px=44px) 为下限,--tap-gap 为最小间距。
*
* 5) 动效几乎未落地(--motion-* 全站仅 5 次引用)
* 补充 --ease-spring 与 --press-scale,让点击有即时反馈。
*
* 6) 夜间氛围层缺失(参考图有明显的光晕/星点,代码只有纯渐变)
* 新增 --mini-glow-* / --mini-star / --mini-glass / --mini-hairline。
*
* 单位说明:rpx(375.00px = 屏幕宽度,0.50px ≈ 0.5px @375pt)
* 旧 token 名全部保留(88 个 wxss 共 909 处引用),只更新取值,避免大范围失效。
*/
.wx-page {
/* ============ 品牌主色(分级:色块 / 文字 / 实心按钮) ============ */
--color-primary: #E96B6B; /* 基础色:渐变、光晕、装饰、非文字图形 */
--color-primary-strong: #B8434A; /* 文字与小图标(5.33:1 on 白,4.91:1 on 浅粉底) */
--color-primary-solid: #C24C50; /* 实心按钮底(白字 4.62:1) */
--color-primary-active: #D95F5F; /* 按压态(配合 --color-primary 使用) */
--color-primary-light: #FFF3F2;
--color-primary-lighter: #FFF8F7;
/* ============ 小程序参考图品牌主题(夜间紫蓝) ============ */
--mini-night-start: #172A72;
--mini-night-end: #25104F;
--mini-night-soft: #3445A1;
--mini-accent-pink: #FF4F91; /* 点缀色:仅用于色块/装饰,不作正文 */
--mini-accent-coral: #FF6A78;
--mini-card-bg: rgba(255, 255, 255, 0.98);
--mini-text: #1F2744;
--mini-muted: #7D839B;
--mini-card-radius: 12.00px;
--mini-text-on-night: #FFFFFF; /* on 深底 13.04:1 ✓ */
--mini-text-on-night-muted: rgba(255, 255, 255, 0.72); /* on 深底 ≈8:1 ✓ */
--mini-shadow: 0 8.00px 20.00px rgba(28, 30, 88, 0.14);
/* ---- 渐变(集中定义:此前 4 个页面各写了一份「橙红渐变」按钮) ---- */
/* --gradient-brand 明亮活泼,但白字仅 2.77:1 —— 只能用于无文字的装饰填充。 */
--gradient-brand: linear-gradient(135deg, #FF6A78 0%, #E96B6B 100%);
/* 承载白字的 CTA 渐变:两端 #C24C50(4.73:1) / #B8434A(5.33:1) 均达标。 */
--gradient-brand-solid: linear-gradient(135deg, #C24C50 0%, #B8434A 100%);
--gradient-night: linear-gradient(160deg, #172A72 0%, #25104F 100%);
--gradient-night-soft: linear-gradient(160deg, #3445A1 0%, #172A72 100%);
/* ---- 首页 4×2 入口宫格图标渐变(参考图 2:高饱和圆角砖 + 白色描画图标) ----
白图标的对比度判据是**非文本图形 3:1**(WCAG 1.4.11)。渐变是斜向的、图标又跨在
两色之间,所以**较亮的一端也必须达标** —— 下表注释给的是 0% 处实算值,100% 更暗只会更高。
色相按业务语义固定(不随 tone 名漂移):找对象/婚前辅导=玫瑰粉系、公益红娘/服务站=暖橙系、
公益活动=紫罗兰、婚恋咨询=蓝、婚恋课堂=紫、婚恋反诈=绿。 */
--gradient-entry-rose: linear-gradient(135deg, #F56287 0%, #F34671 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-orange: linear-gradient(135deg, #F66A06 0%, #D95E06 100%); /* 3.01:1 / 3.78:1 */
--gradient-entry-violet: linear-gradient(135deg, #A380F5 0%, #8F64F2 100%); /* 3.02:1 / 3.98:1 */
--gradient-entry-blue: linear-gradient(135deg, #5195F6 0%, #3484F4 100%); /* 3.01:1 / 3.65:1 */
--gradient-entry-purple: linear-gradient(135deg, #B27BF0 0%, #A260ED 100%); /* 3.01:1 / 3.87:1 */
--gradient-entry-pink: linear-gradient(135deg, #F2619E 0%, #F0458C 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-green: linear-gradient(135deg, #18A979 0%, #148F66 100%); /* 3.00:1 / 4.08:1 */
--gradient-entry-amber: linear-gradient(135deg, #E9740C 0%, #CC650B 100%); /* 3.01:1 / 3.86:1 */
/* 图标砖落影:比 --mini-shadow 更小,避免 4 列宫格里相邻砖块的投影互相压边 */
--mini-entry-shadow: 0 4.00px 9.00px rgba(28, 30, 88, 0.18);
/* ---- 夜间氛围层(v2 新增;参考图有光晕与星点,此前完全没有) ---- */
--mini-glow-coral: rgba(255, 79, 145, 0.40);
--mini-glow-indigo: rgba(94, 124, 255, 0.32);
--mini-glow-soft: rgba(255, 255, 255, 0.10);
--mini-star: rgba(255, 255, 255, 0.70);
--mini-glass: rgba(255, 255, 255, 0.10); /* 深底玻璃面 */
--mini-glass-strong: rgba(255, 255, 255, 0.16);
--mini-hairline: rgba(255, 255, 255, 0.16); /* 深底分隔线 */
--mini-glass-success: rgba(90, 226, 184, 0.16); /* 深底上的成功态玻璃面 */
/* 星点层:多个小径向渐变叠在夜空渐变之上。用 radial-gradient 而非图片,
避免额外请求,也便于随主题换色(index 页脚注:装饰层不承载信息)。 */
--mini-starfield:
radial-gradient(circle at 12% 18%, var(--mini-star) 0, transparent 1.25px),
radial-gradient(circle at 31% 66%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 57% 12%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 79% 52%, var(--mini-star) 0, transparent 1.50px),
radial-gradient(circle at 93% 84%, var(--mini-star) 0, transparent 1.00px);
/* 横幅压暗层:保证任何底图上的白色标题都有足够对比度 */
--mini-banner-scrim: linear-gradient(90deg, rgba(23, 42, 114, 0.84) 0%, rgba(37, 16, 79, 0.40) 56%, rgba(255, 79, 145, 0.12) 100%);
/* ============ 功能色(同样分级) ============ */
--color-success: #2E9B68; /* 色块/图标 */
--color-success-strong: #17805A; /* 文字(4.92:1 ✓) */
--color-success-light: #ECF8F2;
--color-warning: #E59A32; /* 色块/图标(作文字仅 2.33:1) */
--color-warning-strong: #9C5F14; /* 文字(5.17:1 ✓) */
--color-warning-light: #FFF7E9;
--color-danger: #D94A4A; /* 色块/图标 */
--color-danger-strong: #C62828; /* 文字(5.62:1 ✓) */
--color-danger-light: #FFF0F0;
--color-info: #4A7CD4; /* 色块/图标 */
--color-info-strong: #2A5DB0; /* 文字(6.38:1 ✓) */
--color-info-light: #EEF4FF;
/* ============ 强调紫(参考图的标签语言;此前散落成 6 种写法) ============ */
--color-accent-purple: #8B63BC; /* 色块/装饰 */
--color-accent-purple-strong: #7C60BC; /* 文字(5.03:1 ✓) */
--color-accent-purple-light: #F3EEFF;
/* 深色夜空底上的强调色(不可用于浅色底) */
--color-success-on-night: #A6F5D7; /* on #172A72 = 10.35:1 ✓ */
/* ============ 文字色(实测对比度 on 白 / on 页面底) ============ */
--color-text-strong: #1A1F36; /* 标题 16.24 / 14.90 ✓ */
--color-text-primary: #2A3050; /* 正文 12.83 / 11.77 ✓ */
--color-text-secondary: #4A5169; /* 次要正文 7.86 / 7.21 ✓ */
--color-text-tertiary: #646C85; /* 说明文字 5.22 / 4.79 ✓(旧 #777 为 4.48) */
--color-text-placeholder: #9AA1B4; /* 占位符(非正文,可浅) */
--color-text-disabled: #B8BDC9;
--color-text-inverse: #FFFFFF; /* 深色背景上的文字 */
/* ============ 边框与分割线 ============ */
--color-border: #E6E8EF;
--color-border-strong: #D8DBE5;
--color-divider: #EFF0F5;
--color-border-focus: #B8434A; /* 焦点环用 strong,保证 3:1 可见度 */
--color-border-error: #C62828;
/* ============ 背景(避免纯白/纯灰平铺,页面底为暖白) ============ */
--color-bg-page: #F6F5F3;
--color-bg-card: #FFFFFF;
--color-bg-subtle: #F5F6FA; /* 次级区块、内嵌列表 */
--color-bg-muted: #EEF0F6; /* 更弱的填充 */
--color-bg-input: #F7F8FB; /* 表单输入框底(此前被引用但从未定义,导致背景失效) */
--color-bg-disabled: #F3F4F7;
--color-bg-overlay: rgba(0, 0, 0, 0.45);
/* ============ 字体 ============ */
/* 小程序无法可靠加载 Web Font(wx.loadFontFace 依赖 HTTPS 白名单且有闪动风险),
故使用中文系统字栈:iOS 走苹方、Android 走思源/系统黑体。
排版辨识度靠字号阶梯与字重建立,而非依赖字体本身。 */
--font-family-cn: -apple-system, "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
--font-family-number: "SF Pro Display", -apple-system, "DIN Alternate", "PingFang SC", sans-serif;
/* 字号阶梯 —— 正文 16.00px(16px) 起,元信息下限 12.00px(12px) */
--font-size-micro: 11.00px; /* 11px 仅角标/装饰,禁用于正文 */
--font-size-xs: 12.00px; /* 12px 元信息下限 */
--font-size-sm: 13.00px; /* 13px 次要说明 */
--font-size-md: 14.00px; /* 14px 次要正文 */
--font-size-base: 16.00px; /* 16px 正文 */
--font-size-lg: 18.00px; /* 18px 小标题 */
--font-size-xl: 20.00px; /* 20px 区块标题 */
--font-size-2xl: 24.00px; /* 24px 页面标题 */
--font-size-3xl: 28.00px; /* 28px 大标题 */
--font-size-display: 32.00px; /* 32px Hero */
/* 字重:只用 4 档。禁止 550/650/750 等非百位值 —— Android 无对应字重会回退,
导致同一设计在不同机型上粗细不一致(审计发现 30 处)。 */
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.65;
--letter-spacing-tight: 0;
--letter-spacing-wide: 0.50px;
--letter-spacing-wider: 1.00px;
/* ============ 间距(4px 栅格) ============ */
--spacing-1: 4.00px;
--spacing-2: 8.00px;
--spacing-3: 12.00px;
--spacing-4: 16.00px;
--spacing-5: 20.00px;
--spacing-6: 24.00px;
--spacing-8: 32.00px;
--spacing-10: 40.00px;
--spacing-12: 48.00px;
--spacing-page-x: 16.00px;
--spacing-section: 24.00px;
--spacing-card-inner: 16.00px;
--spacing-tight: 8.00px;
/* ============ 圆角 ============ */
--radius-sm: 8.00px;
--radius-md: 12.00px;
--radius-lg: 16.00px;
--radius-xl: 20.00px;
--radius-2xl: 24.00px;
--radius-full: 4999.50px;
/* ============ 阴影(统一为一套,此前 30+ 种近似值) ============ */
--shadow-card: 0 4.00px 14.00px rgba(35, 35, 95, 0.07);
--shadow-raised: 0 6.00px 18.00px rgba(35, 35, 95, 0.10);
--shadow-popup: 0 8.00px 32.00px rgba(0, 0, 0, 0.10);
--shadow-night: 0 8.00px 20.00px rgba(28, 30, 88, 0.18);
/* ============ 边框宽度 ============ */
--border-width: 0.50px;
--border-width-strong: 1.00px;
/* ============ 触摸目标(无障碍下限 44×44px) ============ */
--tap-min: 44.00px; /* 44px 最小可点区域 */
--tap-comfortable: 48.00px; /* 48px 舒适尺寸:主操作 */
--tap-gap: 8.00px; /* 8px 相邻目标最小间距 */
/* ============ 动效 ============ */
--motion-fast: 120ms;
--motion-normal: 200ms;
--motion-slow: 300ms;
--ease-standard: cubic-bezier(0.32, 0.72, 0, 1);
--ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
--press-scale: 0.97;
--press-opacity: 0.88;
/* ============ 层级 z-index ============ */
--z-base: 1;
--z-sticky: 100;
--z-tabbar: 200;
--z-dropdown: 500;
--z-modal: 1000;
--z-toast: 2000;
--z-ambient: 0;
/* ============ 页面基础样式 ============ */
background-color: var(--color-bg-page);
font-family: var(--font-family-cn);
font-size: var(--font-size-base);
color: var(--color-text-primary);
line-height: var(--line-height-normal);
}
/* ==========================================================================
通用工具类
========================================================================== */
.container {
padding: var(--spacing-page-x);
}
.flex { display: flex; }
.flex-column { display: flex; flex-direction: column; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-start { display: flex; align-items: center; justify-content: flex-start; }
.flex-1 { flex: 1; min-width: 0; }
.flex-shrink-0 { flex-shrink: 0; }
.wrap { flex-wrap: wrap; }
/* 4 列宫格:用 flex + 百分比宽度实现。
注:display:grid 在 WebView 渲染下可用,但 Skyline 不支持,故统一改为 flex 以免疫渲染引擎迁移。*/
.grid-4 {
display: flex;
flex-wrap: wrap;
}
.grid-4 > .grid-item {
width: 25%;
box-sizing: border-box;
}
.text-strong { color: var(--color-text-strong); }
.text-primary { color: var(--color-text-primary); }
.text-secondary { color: var(--color-text-secondary); }
.text-tertiary { color: var(--color-text-tertiary); }
.text-placeholder { color: var(--color-text-placeholder); }
.text-white { color: var(--color-text-inverse); }
.text-brand { color: var(--color-primary-strong); }
/* 品牌色作文字只能用 -strong 变体:基础色 #E96B6B 在白底仅 3.10:1。
保留 .text-brand-soft 这个类名是为了不破坏既有引用,取值已统一到 -strong,
如需「更亮的品牌色」请用于背景/图形而非文字。 */
.text-brand-soft { color: var(--color-primary-strong); }
.text-success { color: var(--color-success-strong); }
.text-warning { color: var(--color-warning-strong); }
.text-danger { color: var(--color-danger-strong); }
.text-info { color: var(--color-info-strong); }
.font-micro { font-size: var(--font-size-micro); }
.font-xs { font-size: var(--font-size-xs); }
.font-sm { font-size: var(--font-size-sm); }
.font-md { font-size: var(--font-size-md); }
.font-base { font-size: var(--font-size-base); }
.font-lg { font-size: var(--font-size-lg); }
.font-xl { font-size: var(--font-size-xl); }
.font-2xl { font-size: var(--font-size-2xl); }
.font-3xl { font-size: var(--font-size-3xl); }
.font-display { font-size: var(--font-size-display); }
.font-regular { font-weight: var(--font-weight-regular); }
.font-medium { font-weight: var(--font-weight-medium); }
.font-semibold { font-weight: var(--font-weight-semibold); }
.font-bold { font-weight: var(--font-weight-bold); }
.mt-1 { margin-top: var(--spacing-1); }
.mt-2 { margin-top: var(--spacing-2); }
.mt-3 { margin-top: var(--spacing-3); }
.mt-4 { margin-top: var(--spacing-4); }
.mt-5 { margin-top: var(--spacing-5); }
.mt-6 { margin-top: var(--spacing-6); }
.mb-1 { margin-bottom: var(--spacing-1); }
.mb-2 { margin-bottom: var(--spacing-2); }
.mb-3 { margin-bottom: var(--spacing-3); }
.mb-4 { margin-bottom: var(--spacing-4); }
.mb-5 { margin-bottom: var(--spacing-5); }
.mb-6 { margin-bottom: var(--spacing-6); }
/* 文本省略 */
.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ellipsis-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
/* 安全区底部留白(避开 Home Indicator) */
.safe-area-bottom {
padding-bottom: 0px;
}
/* 页面卡片基础样式 */
.card-base {
background: var(--color-bg-card);
border-radius: var(--radius-lg);
padding: var(--spacing-card-inner);
box-shadow: var(--shadow-card);
}
/* 分割线 */
.divider {
height: var(--border-width);
background: var(--color-divider);
}
/* ==========================================================================
可访问性:只用 token,不用工具类(2026-09-23 修订)
--------------------------------------------------------------------------
v2 曾在此处新增 .tap-min / .tap-gap / .focusable / .pressable 四个工具类。
复检发现全部零引用(等价能力已各自写在组件样式内,例如 button/index.wxss
直接使用 min-height:var(--tap-min)),且存在两个硬问题:
1) `.tap-gap > * + *` 用了通配符与兄弟选择器 —— WXSS 不支持,
wcc 编译期直接报 `error at token '*'`,导致整个小程序编译失败。
(这是编译错误,不是静默失效,代价最高。)
2) `.pressable:active` / `.focusable:focus-visible` 的伪类在 view 上
不生效(小程序须用 hover-class),属于"写了等于没写"。
故整块移除,保留 token。需要热区/间距时直接引用 token:
min-height: var(--tap-min); → 44.00px = 44px,最小可点区域
gap: var(--tap-gap); → 8.00px = 8px,相邻目标间距(flex gap)
【WXSS 禁用清单】星号通配符、兄弟选择器、属性选择器。
【注释约束】WXSS 注释**不可嵌套**:内层注释的结束标记会提前终止外层注释,
其后的文字会被当成真实样式解析,导致编译失败或样式被污染。
(2026-09-23 实证:本块注释初版即踩此坑。)
========================================================================== */
.wx-page{background:var(--color-bg-page)}.service-page{min-height:100vh;padding-bottom:calc(70.00px + 0px)}.hero{padding:22.00px 16.00px 27.00px;background:linear-gradient(140deg,var(--color-primary-lighter),var(--color-warning-light));position:relative;overflow:hidden}.eyebrow{display:inline-flex;padding:3.50px 7.00px;border-radius:499.50px;background:rgba(255,255,255,.72);color:var(--color-primary-strong);font-size:12.00px}.hero-title{display:block;margin-top:9.00px;font-size:20.00px;font-weight:700;line-height:1.35}.hero-desc{display:block;width:82%;margin-top:7.00px;font-size:12.50px;color:var(--color-text-secondary);line-height:1.7}.content{padding:0 var(--spacing-page-x)}.block{margin-top:var(--spacing-section)}.block-title{display:block;font-size:15.50px;font-weight:600}.block-subtitle{display:block;margin-top:4.00px;font-size:12.00px;color:var(--color-text-tertiary)}.card{margin-top:9.00px;padding:14.00px;background:var(--color-bg-card);border:0.50px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-card)}.feature-row,.menu-row,.record-row{display:flex;align-items:center;gap:10.00px;min-height:56.00px;padding:9.00px 0;border-bottom:0.50px solid var(--color-divider)}.feature-row:last-child,.menu-row:last-child,.record-row:last-child{border-bottom:0}.feature-icon{width:36.00px;height:36.00px;display:flex;align-items:center;justify-content:center;flex:none;border-radius:11.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-weight:700}.feature-copy{flex:1;min-width:0}.feature-title{display:block;font-size:14.00px;font-weight:600}.feature-desc,.meta{display:block;margin-top:3.50px;font-size:12.00px;color:var(--color-text-tertiary);line-height:1.55}.arrow{font-size:20.00px;color:var(--color-text-disabled)}.tag{display:inline-flex;margin-right:5.00px;margin-top:5.00px;padding:3.00px 6.50px;border-radius:499.50px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px}.tag.warning{background:var(--color-warning-light);color:var(--color-warning-strong)}.primary-btn,.secondary-btn{height:44.00px;display:flex;align-items:center;justify-content:center;border-radius:22.00px;font-size:14.00px;font-weight:600}.primary-btn{background:var(--gradient-brand-solid);color:var(--color-text-inverse);box-shadow:0 5.00px 12.00px rgba(255,92,130,.22)}.primary-btn.disabled{background:var(--color-bg-muted);color:var(--color-text-tertiary);box-shadow:none}.secondary-btn{background:var(--color-primary-light);color:var(--color-primary-strong)}.fixed-action{position:fixed;left:0;right:0;bottom:0;padding:9.00px var(--spacing-page-x) calc(9.00px + 0px);background:rgba(255,255,255,.96);border-top:0.50px solid var(--color-divider);z-index:100}.field{margin-top:13.00px}.label{display:block;margin-bottom:6.00px;font-size:12.50px;font-weight:600}.input,.select-box,.textarea{width:100%;box-sizing:border-box;background:var(--color-bg-page);border:0.50px solid var(--color-border);border-radius:var(--radius-md);font-size:13.00px}.input,.select-box{height:44.00px;padding:0 12.00px;display:flex;align-items:center}.textarea{min-height:90.00px;padding:11.00px}.notice{margin-top:10.00px;padding:11.00px;border-radius:var(--radius-md);background:var(--color-info-light);color:var(--color-text-secondary);font-size:12.00px;line-height:1.65}.select-box.is-readonly{background:var(--color-bg-subtle);color:var(--color-text-secondary)}.empty-panel{text-align:center;padding:35.00px 15.00px}.empty-symbol{width:48.00px;height:48.00px;margin:auto;display:flex;align-items:center;justify-content:center;border-radius:15.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-size:18.00px;font-weight:700}.empty-title{display:block;margin-top:11.00px;font-size:15.00px;font-weight:600}.article-card{margin-top:9.00px;background:var(--color-bg-card);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-card)}.article-cover{height:110.00px;padding:12.00px;background:linear-gradient(135deg,var(--color-warning-light),var(--color-warning-light));display:flex;align-items:flex-end}.article-cover text{font-size:21.00px;color:rgba(125,76,63,.52);font-weight:700}.article-body{padding:12.00px}.article-title{display:block;font-size:14.50px;font-weight:600;line-height:1.45}.article-meta{display:block;margin-top:5.00px;font-size:12.00px;color:var(--color-text-tertiary)}.article-content{padding:16.00px;background:var(--color-bg-card);font-size:14.00px;line-height:1.9;color:var(--color-text-secondary)}.article-content .lead{display:block;font-size:15.50px;color:var(--color-text-primary);font-weight:600;margin-bottom:12.00px}.danger-card{background:var(--color-primary-lighter);border-color:var(--color-primary-light)}.danger-card .feature-icon{background:var(--color-warning-light);color:var(--color-warning-strong)}@media(max-width:340px){.hero-title{font-size:18.00px}.hero-desc{width:92%}}
.service-shell{min-height:100vh;padding-bottom:calc(68.00px + 0px);background:var(--color-bg-page)}.service-content{padding:4.00px 12.00px 18.00px}.service-status{display:flex;align-items:center;justify-content:space-between;margin-top:12.00px;padding:10.00px 12.00px;border-radius:11.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-status__label{color:var(--color-text-tertiary);font-size:12.00px}.service-status__value{padding:3.00px 7.00px;border-radius:9.00px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px;font-weight:600}.service-status__value.disabled{background:var(--color-danger-light);color:var(--color-danger-strong)}.service-topics{display:grid;grid-template-columns:repeat(2,1fr);gap:8.00px;margin-top:9.00px}.service-topic{min-height:74.00px;padding:10.00px;border-radius:12.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-topic__icon{display:flex;align-items:center;justify-content:center;width:27.00px;height:27.00px;border-radius:8.50px;background:var(--color-primary-light)}.service-topic__icon image{width:17.00px;height:17.00px}.service-topic__title{display:block;margin-top:6.50px;color:var(--color-text-strong);font-size:12.00px;font-weight:600}.service-topic__desc{display:block;margin-top:3.00px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}.service-actions{display:flex;gap:7.00px}.service-actions .secondary-btn{width:95.00px;flex:none}.service-actions .primary-btn{flex:1}.privacy-note{display:flex;align-items:flex-start;gap:7.00px;margin-top:11.00px;padding:10.00px;border-radius:11.00px;background:var(--color-info-light);color:var(--color-text-tertiary);font-size:12.00px;line-height:1.55}.privacy-note image{width:17.00px;height:17.00px;flex:none}
/* ==== miniapp/components/section-header ==== */
/**
* 区块标题(全站所有页面共用,是排版层级的关键一环)
*
* 2026-09-22 修订:
* 1) 层级拉开:标题 18.00px→20.00px(--font-size-xl),与正文 16.00px / 卡片标题 14.00px
* 形成「区块标题 > 卡片标题 > 正文 > 元信息」四级阶梯。
* 旧值 18.00px 与卡片标题仅差 5.00px,层级读不出来。
* 2) 右侧 action 是全站最容易被忽略的触摸目标:只有 13.00px 文字高(约 13px),
* 远低于 44px 下限。改为 min-height:--tap-min,热区向上补白。
* 3) action 文字色原为 --color-primary(#E96B6B)=3.10:1,不达标,改 -strong。
*/
.ui-section {
display:flex;
align-items:center;
justify-content:space-between;
padding:var(--spacing-2) var(--spacing-page-x);
}
.ui-section__left {
display:flex;
align-items:baseline;
min-width:0;
}
.ui-section__title {
font-size:var(--font-size-xl);
font-weight:var(--font-weight-semibold);
color:var(--color-text-strong);
letter-spacing:var(--letter-spacing-tight);
}
.ui-section__subtitle {
margin-left:var(--spacing-2);
font-size:var(--font-size-xs);
color:var(--color-text-tertiary);
}
.ui-section__action {
display:flex;
align-items:center;
flex:none;
min-height:var(--tap-min);
padding-left:var(--spacing-3);
font-size:var(--font-size-sm);
font-weight:var(--font-weight-medium);
color:var(--color-primary-strong);
transition:opacity var(--motion-fast) var(--ease-standard);
}
.ui-section__action:active {
opacity:var(--press-opacity);
}
.ui-section__arrow {
margin-left:2.00px;
width:12.00px;
height:12.00px;
}
/* ==== miniapp/components/recommend-card ==== */
.ui-rec{display:flex;align-items:center;gap:8.00px;min-height:66.00px;padding:7.00px 8.00px;background:var(--color-bg-card);border-bottom:0.50px solid var(--color-divider)}.ui-rec:last-child{border-bottom:0}.ui-rec__info{flex:1;min-width:0}.ui-rec__name-row{display:flex;align-items:center;gap:5.00px}.ui-rec__name{font-size:13.00px;font-weight:700;color:var(--color-text-strong)}.ui-rec__age{font-size:12.00px;color:var(--color-text-secondary)}.ui-rec__online{margin-left:auto;font-size:12.00px;color:var(--color-success-strong)}.ui-rec__online::before{content:'·';margin-right:2.00px}.ui-rec__meta{margin-top:2.50px;font-size:12.00px;color:var(--color-text-tertiary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ui-rec__reasons{display:flex;gap:3.50px;margin-top:4.00px;overflow:hidden}.ui-rec__reason{flex:none;padding:2.00px 4.50px;border-radius:6.00px;background:var(--color-accent-purple-light);color:var(--color-accent-purple-strong);font-size:12.00px;white-space:nowrap}.ui-rec__actions{width:var(--tap-min);display:flex;flex-direction:column;align-items:center;gap:3.50px}.compact-like{width:var(--tap-min);min-height:var(--tap-min);display:flex;align-items:center;justify-content:center;border-radius:var(--radius-full);background:var(--color-primary-light);box-shadow:0 3.50px 9.00px rgba(255,79,145,.18);}.compact-like__icon{width:22.00px;height:22.00px}.compact-pass{font-size:12.00px;color:var(--color-text-tertiary);white-space:nowrap}
/* ==== miniapp/components/empty ==== */
.ui-empty {
display:flex;
flex-direction:column;
align-items:center;
padding:var(--spacing-10) var(--spacing-page-x);
text-align:center;
}
.ui-empty__illustration {
width:80.00px;
height:80.00px;
border-radius:50%;
background:var(--color-bg-disabled);
display:flex;
align-items:center;
justify-content:center;
margin-bottom:var(--spacing-4);
}
.ui-empty__icon {
width:36.00px;
height:36.00px;
opacity:0.72;
}
.ui-empty__title {
font-size:var(--font-size-lg);
font-weight:var(--font-weight-medium);
color:var(--color-text-primary);
margin-bottom:var(--spacing-2);
}
.ui-empty__desc {
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
line-height:var(--line-height-relaxed);
max-width:240.00px;
}
.ui-empty__actions {
display:flex;
flex-direction:column;
gap:var(--spacing-2);
margin-top:var(--spacing-6);
width:100%;
max-width:240.00px;
}
.ui-empty__action {
display:flex;
align-items:center;
justify-content:center;
min-height:var(--tap-min);
border-radius:var(--radius-full);
font-size:var(--font-size-base);
font-weight:var(--font-weight-medium);
min-width:var(--tap-min);}
.ui-empty__action--primary {
background:var(--color-primary-solid);
color:var(--color-text-inverse);
}
.ui-empty__action--secondary {
background:var(--color-bg-card);
color:var(--color-primary-strong);
border:0.50px solid var(--color-primary);
}
/* ==== miniapp/components/loading ==== */
.ui-loading--block {
display:flex;
flex-direction:column;
align-items:center;
justify-content:center;
padding:var(--spacing-8) var(--spacing-page-x);
}
.ui-loading--inline {
display:inline-flex;
align-items:center;
}
.ui-loading__spinner {
width:30.00px;
height:30.00px;
display:flex;
align-items:center;
justify-content:center;
}
.ui-loading__spinner-icon {
width:24.00px;
height:24.00px;
animation:ui-loading-spin 0.8s linear infinite;
}
@keyframes ui-loading-spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
.ui-loading__text {
margin-top:var(--spacing-3);
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
}
/* Skeleton */
.ui-loading__skeleton {
width:100%;
}
.ui-loading__skeleton-row {
display:flex;
align-items:center;
padding:var(--spacing-3) var(--spacing-page-x);
background:var(--color-bg-card);
border-bottom:0.50px solid var(--color-divider);
}
.ui-loading__skeleton-avatar {
width:44.00px;
height:44.00px;
border-radius:50%;
background:var(--color-bg-disabled);
margin-right:var(--spacing-3);
flex-shrink:0;
}
.ui-loading__skeleton-content {
flex:1;
min-width:0;
}
.ui-loading__skeleton-line {
height:12.00px;
background:var(--color-bg-disabled);
border-radius:var(--radius-sm);
position:relative;
overflow:hidden;
}
.ui-loading__skeleton-line--title {
width:40%;
margin-bottom:var(--spacing-2);
}
.ui-loading__skeleton-line--meta {
width:70%;
}
/* shimmer */
.ui-loading__skeleton-line::after,
.ui-loading__skeleton-avatar::after {
content:'';
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background:linear-gradient(
90deg,
transparent 0%,
rgba(255, 255, 255, 0.55) 50%,
transparent 100%
);
animation:ui-loading-shimmer 1.4s ease-in-out infinite;
}
@keyframes ui-loading-shimmer {
0% { transform:translateX(-100%); }
100% { transform:translateX(100%); }
}
/* ==== miniapp/components/status-badge ==== */
.ui-badge {
display:inline-flex;
align-items:center;
padding:2.00px 7.00px;
border-radius:var(--radius-full);
font-size:var(--font-size-xs);
font-weight:var(--font-weight-medium);
line-height:1.4;
white-space:nowrap;
}
.ui-badge__dot {
width:4.00px;
height:4.00px;
border-radius:50%;
background:currentColor;
margin-right:4.00px;
}
.ui-badge__label {
font-size:inherit;
}
.ui-badge--success {
background:var(--color-success-light);
color:var(--color-success-strong);
}
.ui-badge--warning {
background:var(--color-warning-light);
color:var(--color-warning-strong);
}
.ui-badge--danger {
background:var(--color-danger-light);
color:var(--color-danger-strong);
}
.ui-badge--info {
background:var(--color-info-light);
color:var(--color-info-strong);
}
.ui-badge--disabled {
background:var(--color-bg-disabled);
color:var(--color-text-disabled);
}
/* ==== miniapp/components/error-state ==== */
.error-state {
padding:32.00px 16.00px;
text-align:center;
background:var(--color-bg-card);
border-radius:var(--radius-lg);
}
.error-icon {
display:block;
width:36.00px;
height:36.00px;
margin:0 auto 10.00px;
}
.error-title,
.error-desc {
display:block;
}
.error-title {
font-size:15.00px;
font-weight:600;
}
.error-desc {
margin-top:4.00px;
color:var(--color-text-tertiary);
font-size:12.00px;
}
.retry-btn {
width:110.00px;
min-height:var(--tap-min);
margin-top:12.00px;
border:0;
border-radius:var(--radius-full);
background:var(--color-primary-solid);
color:var(--color-text-inverse);
font-size:13.00px;
line-height:var(--tap-min);
min-width:var(--tap-min);}
.retry-btn::after {
border:0;
}
/**
* 首页 —— 全站设计系统样板页
*
* 2026-09-22 重做。这一版要证明 app.wxss v2 的底座是"能用"的:
*
* 1) 氛围层(参考图的关键差异项)
* 旧版只有一条线性渐变,参考图里有明显的暖粉光晕、星点与玻璃质感。
* 现用三层叠加:--mini-starfield(星点)+ --gradient-night(夜空)
* + 两个定位光晕伪元素(左上粉 / 左下靛蓝),零图片、零额外请求。
*
* 2) 排版层级
* 旧版 hero 标题 17.50px、区块标题 18.00px、卡片标题 12.50px、正文 12.00px ——
* hero 与区块标题几乎同号,层级读不出来。现为:
* hero 24.00px/700 > 区块标题 20.00px/600 > 卡片标题 14.00px/600 >
* 正文 13.00px > 元信息 12.00px
*
* 3) 触摸目标
* 所有可点元素以 --tap-min(44.00px=44px) 为下限;旧版 .empty-btn 只有 24px。
* 并且删掉了 @media(max-width:340px) 里的 .empty-actions{display:none} ——
* 那等于在小屏上把「调整条件 / 公益红娘」两个入口整块砍掉。
*
* 4) 交互反馈
* 旧版全站 --motion-* 只被引用 5 次,点了没反应。现统一走 --ease-spring
* + --press-scale,并给区块卡片加上按压缩放。
*
* 5) 对比度
* 旧版 .text-link/.activity-tag/.safety-link 用 --mini-accent-pink(#FF4F91)
* 作文字 = 3.10:1,不达标;CTA 白字压在珊瑚粉渐变上也只有 2.77:1。
* 现分别改用 --color-primary-strong(5.33:1) 与 --gradient-brand-solid(≥4.7:1)。
*
* 单位:rpx(375.00px = 屏幕宽度,0.50px ≈ 0.5px)
*/
/* ============================== 页面骨架 ============================== */
.page {
min-height: 100vh;
background: var(--color-bg-page);
padding-bottom: var(--spacing-5);
}
/* ============================== 夜空头部 ============================== */
.night-shell {
position: relative;
overflow: hidden;
/* --nav-status / --nav-h / --nav-right 由 index.ts 经 utils/nav-metrics 实测胶囊按钮后注入。
顶到胶囊所在横带,而不是用 20px:后者只反映设备物理安全区,
安卓上常为 0,也完全不反映右上角胶囊的位置(2026-09-23 重合缺陷的根因)。 */
padding: var(--nav-status, 44px) var(--spacing-3) var(--spacing-4);
background: var(--mini-starfield), var(--gradient-night);
border-radius: 0 0 var(--radius-2xl) var(--radius-2xl);
box-shadow: var(--shadow-night);
}
/* 两个光晕:伪元素承担,避免为了装饰再嵌一层 view */
.night-shell::before,
.night-shell::after {
content: '';
position: absolute;
border-radius: 50%;
pointer-events: none;
z-index: var(--z-ambient);
}
.night-shell::before {
top: -100.00px;
right: -70.00px;
width: 280.00px;
height: 280.00px;
background: radial-gradient(circle, var(--mini-glow-coral) 0%, transparent 68%);
}
.night-shell::after {
bottom: -110.00px;
left: -80.00px;
width: 310.00px;
height: 310.00px;
background: radial-gradient(circle, var(--mini-glow-indigo) 0%, transparent 70%);
}
/* 伪元素是定位元素,会盖住静态流内容;正文需要显式抬一层 */
.night-shell > view {
position: relative;
z-index: var(--z-base);
}
/* ============================== 品牌栏 ============================== */
.brand-bar {
/* 高度与胶囊按钮对齐;右侧留出胶囊安全区,否则「消息」入口会被胶囊压住点不到 */
height: var(--nav-h, 40.00px);
box-sizing: border-box;
padding-right: var(--nav-right, 102px);
display: flex;
align-items: center;
justify-content: space-between;
color: var(--mini-text-on-night);
}
.brand-lockup {
display: flex;
align-items: center;
min-width: 0;
}
.brand-logo {
width: 34.00px;
height: 34.00px;
flex: none;
}
.brand-copy {
display: flex;
flex-direction: column;
margin-left: var(--spacing-2);
}
.brand-name {
font-size: var(--font-size-lg);
font-weight: var(--font-weight-bold);
letter-spacing: var(--letter-spacing-wider);
line-height: var(--line-height-tight);
}
.brand-slogan {
margin-top: 1.00px;
font-size: var(--font-size-xs);
letter-spacing: 1.50px;
color: var(--mini-text-on-night-muted);
}
.brand-actions {
position: relative;
flex: none;
min-width: var(--tap-min);
min-height: var(--tap-min);
display: flex;
align-items: center;
justify-content: center;
}
.message-label {
font-size: var(--font-size-sm);
}
.badge {
position: absolute;
right: 0;
top: 2.00px;
min-width: 15.00px;
height: 15.00px;
padding: 0 2.50px;
line-height: 15.00px;
text-align: center;
font-size: var(--font-size-micro);
color: var(--color-text-inverse);
/* 白字需 4.5:1:--mini-accent-pink 仅 3.10,改用 solid 变体 */
background: var(--color-primary-solid);
border-radius: var(--radius-full);
/* 描一圈夜空底色,避免角标压在光晕上时边缘糊掉 */
box-shadow: 0 0 0 1.50px var(--mini-night-start);
}
/* ============================== 状态条 ============================== */
.status-strip {
margin: var(--spacing-1) 0 var(--spacing-2);
padding: var(--spacing-3);
border: var(--border-width) solid var(--mini-hairline);
background: var(--mini-glass);
border-radius: var(--radius-md);
color: var(--color-text-inverse);
}
.status-main {
display: flex;
align-items: center;
gap: var(--spacing-2);
}
.status-copy {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
}
.status-title {
font-size: var(--font-size-md);
font-weight: var(--font-weight-semibold);
line-height: var(--line-height-tight);
}
.status-desc {
margin-top: 3.00px;
font-size: var(--font-size-xs);
line-height: var(--line-height-normal);
color: var(--mini-text-on-night-muted);
}
.status-action {
flex: none;
min-width: 58.00px;
min-height: var(--tap-min);
padding: 0 var(--spacing-3);
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-full);
background: var(--gradient-brand-solid);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-semibold);
}
.status-checks {
display: flex;
gap: 5.00px;
overflow: hidden;
}
.status-check {
padding: 4.00px 7.00px;
border-radius: var(--radius-full);
background: var(--mini-glass);
font-size: var(--font-size-xs);
color: var(--mini-text-on-night-muted);
white-space: nowrap;
}
.status-check.done {
background: var(--mini-glass-success);
color: var(--color-success-on-night);
font-weight: var(--font-weight-semibold);
}
/* ============================== 主视觉横幅 ============================== */
.banner-section {
width: 100%;
}
.banner-swiper,
.banner-card {
height: 150.00px;
border-radius: var(--radius-lg);
overflow: hidden;
}
.banner-card {
position: relative;
}
.banner-img {
width: 100%;
height: 100%;
display: block;
}
.banner-overlay {
position: absolute;
inset: 0;
background: var(--mini-banner-scrim);
}
.banner-copy {
position: absolute;
left: var(--spacing-3);
bottom: var(--spacing-5);
width: 68%;
display: flex;
flex-direction: column;
color: var(--color-text-inverse);
}
.banner-kicker {
font-size: var(--font-size-xs);
letter-spacing: 1.50px;
color: var(--mini-text-on-night-muted);
}
.banner-title {
margin-top: 5.00px;
font-size: var(--font-size-2xl);
line-height: var(--line-height-tight);
font-weight: var(--font-weight-bold);
letter-spacing: var(--letter-spacing-wide);
text-shadow: 0 2.00px 7.00px rgba(0, 0, 0, 0.22);
}
.banner-subtitle {
margin-top: 5.00px;
font-size: var(--font-size-sm);
color: var(--mini-text-on-night-muted);
}
/* ============================== 快捷入口 ============================== */
.entries-card {
position: relative;
z-index: 2;
margin: -9.00px var(--spacing-3) 0;
padding: var(--spacing-3) var(--spacing-1) var(--spacing-2);
background: var(--mini-card-bg);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-raised);
}
/* 4 列宫格用 flex + 25% 宽实现。display:grid 在 Skyline 渲染引擎下不支持,
统一避开以免将来切渲染引擎时整体错版。 */
.entries-grid {
display: flex;
flex-wrap: wrap;
row-gap: var(--spacing-2);
}
.entry-item {
width: 25%;
box-sizing: border-box;
min-height: 88.00px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.entry-item.disabled {
opacity: 0.4;
}
/* 图标砖(参考图 2):48.00px 圆角方 + 高饱和渐变面 + 白色描画图形。
两层背景:上层 26.00px = 白色图形(data-uri SVG),下层 100% = 渐变砖面。
background-color 是**兜底**:万一 SVG 背景层被解析器丢弃,砖面仍在(只是没有图形),
不会退化成「白底白图标」这种彻底不可见的形态。 */
.entry-icon {
width: 48.00px;
height: 48.00px;
border-radius: 14.00px;
background-repeat: no-repeat, no-repeat;
background-position: center, center;
background-size: 26.00px 26.00px, 100% 100%;
box-shadow: var(--mini-entry-shadow);
}
.entry-label {
margin-top: var(--spacing-1);
font-size: var(--font-size-md);
font-weight: var(--font-weight-semibold);
color: var(--color-text-strong);
letter-spacing: var(--letter-spacing-tight);
}
/* 副标题:承接参考图「主标题 + 一行说明」的双层信息结构。
字号用 --font-size-xs(12px,本项目的元信息下限),不再往下探 micro ——
micro 是「仅角标/装饰、禁用于正文」的档位,这行字承载语义,不属于装饰。 */
.entry-sub {
margin-top: 1.00px;
font-size: var(--font-size-xs);
font-weight: var(--font-weight-regular);
color: var(--mini-muted);
line-height: 1.3;
}
/* ---- tone → 渐变砖面 + 白色图形 ----------------------------------------
色相语义与实算对比度见 app.wxss 的 --gradient-entry-* 注释块;
本处只负责「把哪个图形放到哪种砖上」,颜色事实源仍在 app.wxss。
图形均为 24×24 viewBox 白色矢量,随 background-size 等比缩放到 26.00px。 */
.tone-rose {
background-color: #F34671;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M12 21.2l-1.4-1.3C5.5 15.3 2.2 12.3 2.2 8.6 2.2 5.6 4.6 3.2 7.6 3.2c1.7 0 3.3.8 4.4 2 1.1-1.2 2.7-2 4.4-2 3 0 5.4 2.4 5.4 5.4 0 3.7-3.3 6.7-8.4 11.3z'/%3E%3C/svg%3E"), var(--gradient-entry-rose);
}
.tone-orange {
background-color: #D95E06;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='%23fff'%3E%3Ccircle cx='9' cy='7.6' r='3.4'/%3E%3Ccircle cx='17.2' cy='9.8' r='2.7'/%3E%3Crect x='2.4' y='15.2' width='13.2' height='6.4' rx='3.2'/%3E%3Crect x='13.8' y='16.4' width='8.6' height='5.2' rx='2.6'/%3E%3C/g%3E%3C/svg%3E"), var(--gradient-entry-orange);
}
.tone-violet {
background-color: #8F64F2;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23fff' stroke-width='1.8'%3E%3Crect x='3.2' y='5.4' width='17.6' height='15.4' rx='3.2'/%3E%3C/g%3E%3Cg fill='%23fff'%3E%3Crect x='7.6' y='2.6' width='2.1' height='4.3' rx='1.05'/%3E%3Crect x='14.3' y='2.6' width='2.1' height='4.3' rx='1.05'/%3E%3Cpath d='M12.00 10.65L12.74 12.58L14.81 12.69L13.20 13.99L13.73 15.99L12.00 14.86L10.27 15.99L10.80 13.99L9.19 12.69L11.26 12.58Z'/%3E%3C/g%3E%3C/svg%3E"), var(--gradient-entry-violet);
}
.tone-blue {
background-color: #3484F4;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23fff' stroke-width='1.7' stroke-linejoin='round'%3E%3Cpath d='M3.7 7.1a3.4 3.4 0 0 1 3.4-3.4h6.6a3.4 3.4 0 0 1 3.4 3.4v3.6a3.4 3.4 0 0 1-3.4 3.4H9.3l-4 3.4a.8.8 0 0 1-1.6-.5z'/%3E%3C/g%3E%3Cg fill='none' stroke='%23fff' stroke-width='1.6'%3E%3Cpath d='M18.1 9.4h.4a2.5 2.5 0 0 1 2.5 2.5v2.3a2.5 2.5 0 0 1-2.5 2.5h-.4v2.1l-2.5-2.1h-2a2.5 2.5 0 0 1-2.5-2.5'/%3E%3C/g%3E%3C/svg%3E"), var(--gradient-entry-blue);
}
.tone-purple {
background-color: #A260ED;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='%23fff'%3E%3Cpath d='M11.3 7.4C9.6 5.9 7.2 5.2 4.6 5.2H2.8v12.9h1.8c2.6 0 5 .7 6.7 2.2z'/%3E%3Cpath d='M12.7 7.4c1.7-1.5 4.1-2.2 6.7-2.2h1.8v12.9h-1.8c-2.6 0-5 .7-6.7 2.2z'/%3E%3C/g%3E%3C/svg%3E"), var(--gradient-entry-purple);
}
.tone-pink {
background-color: #F0458C;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='%23fff'%3E%3Cpath d='M12 13.6l-1.05-1C7.2 9.3 5 7.2 5 5 5 3.2 6.5 1.8 8.3 1.8c1.1 0 2.1.5 2.7 1.4.6-.9 1.6-1.4 2.7-1.4 1.8 0 3.3 1.4 3.3 3.2 0 2.2-2.2 4.3-5.8 7.7z'/%3E%3Crect x='3.4' y='15.6' width='10' height='3.6' rx='1.8' transform='rotate(18 8.4 17.4)'/%3E%3Crect x='10.6' y='15.6' width='10' height='3.6' rx='1.8' transform='rotate(-18 15.6 17.4)'/%3E%3C/g%3E%3C/svg%3E"), var(--gradient-entry-pink);
}
.tone-green {
background-color: #148F66;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none' stroke='%23fff' stroke-width='1.8' stroke-linejoin='round'%3E%3Cpath d='M12 2.6l7.4 2.8v6.2c0 4.6-3.1 8.7-7.4 9.8-4.3-1.1-7.4-5.2-7.4-9.8V5.4z'/%3E%3C/g%3E%3Cpath d='M8.4 12.2l2.5 2.5 4.7-5' fill='none' stroke='%23fff' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"), var(--gradient-entry-green);
}
.tone-amber {
background-color: #CC650B;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M12 3.1l9.2 7.5h-2.3v9.4h-4.3v-5.7H9.4v5.7H5.1v-9.4H2.8z'/%3E%3C/svg%3E"), var(--gradient-entry-amber);
}
/* ============================== 区块容器 ============================== */
.preview-note {
margin: var(--spacing-2) var(--spacing-3) 0;
text-align: center;
font-size: var(--font-size-xs);
color: var(--color-accent-purple-strong);
}
.section {
margin-top: var(--spacing-5);
padding: 0 var(--spacing-3);
}
.recommendation-section {
margin-top: var(--spacing-5);
}
/* 标题与卡片左边缘必须对齐:.section 已提供 12.00px 内边距,
而 ui-section 自带 --spacing-page-x(16.00px),叠加会让标题比卡片多缩进 16.00px。 */
.section .ui-section {
padding-left: 0;
padding-right: 0;
}
/* ============================== 今日推荐 ============================== */
.recommend-list {
margin-top: var(--spacing-2);
border-radius: var(--radius-lg);
overflow: hidden;
box-shadow: var(--shadow-card);
}
.recommend-empty {
margin-top: var(--spacing-2);
padding: var(--spacing-3);
display: flex;
align-items: center;
gap: var(--spacing-2);
background: var(--color-bg-card);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-card);
}
.empty-logo {
width: 38.00px;
height: 38.00px;
flex: none;
}
.empty-copy {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
}
.empty-title {
font-size: var(--font-size-md);
font-weight: var(--font-weight-semibold);
color: var(--color-text-strong);
}
.empty-desc {
margin-top: 3.00px;
font-size: var(--font-size-sm);
line-height: var(--line-height-normal);
color: var(--color-text-tertiary);
}
.empty-actions {
display: flex;
flex-direction: column;
gap: var(--spacing-1);
}
.empty-btn {
min-width: 60.00px;
min-height: var(--tap-min);
padding: 0 var(--spacing-2);
display: flex;
align-items: center;
justify-content: center;
border-radius: var(--radius-full);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
}
.empty-btn.secondary {
color: var(--color-accent-purple-strong);
background: var(--color-accent-purple-light);
}
.empty-btn.primary {
color: var(--color-text-inverse);
background: var(--gradient-brand-solid);
}
/* ============================== 公益服务(1/3 小卡) ==============================
2026-09-23 重做。此前的卡片是「整行宽 + 封面写 width 不写 height」:
小程序 <image> 在未指定高度时会取默认 240px(=240.00px),卡片被硬生生撑到约 240.00px 高,
首页上极占地方(用户反馈的「占用过大」即此)。现在:
- 宽度:一行 3 张,每张约 112.00px(≈ 原 351.00px 的 1/3)
- 高度:固定 84.00px(≈ 原 240.00px 的 1/3)
- 内容:只留配图 + 标题,整块可点,长文案与入口交给详情页
⇒ 想改回整行宽:把 .mini-card 的 width 换成 100%、height 改成 80.00px 即可(一处改动)。 */
.mini-rail {
display: flex;
flex-wrap: wrap;
align-items: flex-start;
gap: var(--spacing-2);
margin-top: var(--spacing-2);
}
.mini-card {
position: relative;
width: calc((100% - var(--spacing-2) * 2) / 3);
height: 84.00px;
border-radius: var(--radius-md);
overflow: hidden;
box-shadow: var(--shadow-card);
}
.mini-card-cover {
width: 100%;
height: 100%;
display: block;
}
.mini-card-scrim {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 56.00px;
background: linear-gradient(180deg, rgba(23, 42, 114, 0) 0%, rgba(23, 42, 114, 0.88) 100%);
}
.mini-card-title {
position: absolute;
left: var(--spacing-2);
right: var(--spacing-1);
bottom: 6.00px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
font-size: var(--font-size-sm);
font-weight: var(--font-weight-semibold);
line-height: var(--line-height-tight);
color: var(--color-text-inverse);
}
/* 安全提醒右半区:文案是公益属性的一部分,缩卡后不能整块丢掉 */
.mini-note {
flex: 1;
min-width: 0;
padding-top: var(--spacing-1);
display: flex;
flex-direction: column;
}
.mini-note-text {
font-size: var(--font-size-sm);
line-height: var(--line-height-normal);
color: var(--color-text-tertiary);
}
.mini-note-link {
margin-top: var(--spacing-1);
font-size: var(--font-size-sm);
font-weight: var(--font-weight-semibold);
color: var(--color-primary-strong);
}
/* ============================== 近期活动 ============================== */
.activity-scroll {
white-space: nowrap;
margin-top: var(--spacing-2);
}
.activity-card {
display: inline-flex;
width: 275.00px;
margin-right: var(--spacing-2);
background: var(--color-bg-card);
border-radius: var(--radius-md);
overflow: hidden;
box-shadow: var(--shadow-card);
white-space: normal;
}
.activity-cover {
width: 105.00px;
height: 86.00px;
flex: none;
}
.activity-info {
flex: 1;
min-width: 0;
padding: var(--spacing-2);
display: flex;
flex-direction: column;
}
.activity-tag {
align-self: flex-start;
padding: 2.50px 7.00px;
border-radius: var(--radius-full);
background: var(--color-primary-light);
color: var(--color-primary-strong);
font-size: var(--font-size-xs);
font-weight: var(--font-weight-medium);
}
.activity-title {
margin-top: 5.00px;
font-size: var(--font-size-md);
font-weight: var(--font-weight-semibold);
line-height: var(--line-height-tight);
color: var(--color-text-strong);
}
.activity-meta {
margin-top: auto;
font-size: var(--font-size-xs);
color: var(--color-text-tertiary);
}
/* ============================== 服务站 / 婚恋课堂 ============================== */
.station-card,
.article-row {
display: flex;
align-items: center;
background: var(--color-bg-card);
border-radius: var(--radius-lg);
overflow: hidden;
box-shadow: var(--shadow-card);
}
.station-cover {
width: 95.00px;
height: 86.00px;
flex: none;
}
.station-info {
flex: 1;
min-width: 0;
padding: var(--spacing-2);
}
.station-name {
display: block;
font-size: var(--font-size-md);
font-weight: var(--font-weight-semibold);
color: var(--color-text-strong);
}
.station-desc {
display: block;
margin: 4.00px 0 6.00px;
font-size: var(--font-size-sm);
color: var(--color-text-tertiary);
}
.mini-tag {
display: inline-block;
margin: 2.00px 4.00px 0 0;
padding: 2.00px 6.00px;
border-radius: var(--radius-sm);
background: var(--color-accent-purple-light);
color: var(--color-accent-purple-strong);
font-size: var(--font-size-xs);
}
.arrow-icon {
width: 14.00px;
height: 14.00px;
margin: var(--spacing-2);
flex: none;
}
.article-list {
margin-top: var(--spacing-2);
display: flex;
flex-direction: column;
gap: 6.00px;
}
.article-row {
min-height: 58.00px;
}
.article-cover {
width: 73.00px;
height: 58.00px;
flex: none;
}
.article-info {
flex: 1;
min-width: 0;
padding: var(--spacing-2);
}
.article-title {
display: block;
font-size: var(--font-size-md);
font-weight: var(--font-weight-semibold);
color: var(--color-text-strong);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.article-meta {
display: block;
margin-top: 3.00px;
font-size: var(--font-size-xs);
color: var(--color-text-tertiary);
}
.section-empty {
margin-top: var(--spacing-2);
padding: var(--spacing-4) var(--spacing-3);
text-align: center;
font-size: var(--font-size-sm);
color: var(--color-text-tertiary);
background: var(--color-bg-card);
border-radius: var(--radius-md);
box-shadow: var(--shadow-card);
}
/* ============================== 安全提醒 ==============================
2026-09-23:由「整行宽的大卡」改为 mini-rail(左 1/3 小卡 + 右文案),样式复用
.mini-card / .mini-note,不再单独维护一套。历史记录:
旧版这里写了 padding:0,把 .section 的左右内边距覆盖掉,于是这张卡比其它区块宽出 24.00px、
直接贴到屏幕边缘(已在本轮随整块重做一并移除)。 */
/* ============================== 按压反馈 ==============================
全站约定:可点元素必须有即时反馈(旧版 --motion-* 全站只被引用 5 次)。
统一走 --ease-spring 的轻微回弹 + --press-scale,避免"点了没反应"。 */
.entry-item,
.status-action,
.empty-btn,
.brand-actions,
.mini-card,
.activity-card,
.station-card,
.article-row,
.mini-note-link,
.section-empty,
.banner-card {
transition: transform var(--motion-fast) var(--ease-spring),
opacity var(--motion-fast) var(--ease-standard);
}
.entry-item:active,
.status-action:active,
.empty-btn:active,
.brand-actions:active,
.mini-card:active,
.activity-card:active,
.station-card:active,
.article-row:active,
.mini-note-link:active,
.section-empty:active,
.banner-card:active {
transform: scale(var(--press-scale));
opacity: var(--press-opacity);
}
/* ============================== 小屏适配 ==============================
旧版在这里写了 .empty-actions{display:none}:小于 340px 的机型上
「调整条件 / 公益红娘」两个入口会整块消失,属于功能级缺陷,已删除。
收紧的是尺寸,不是功能。 */
@media (max-width: 340px) {
.entry-label {
font-size: var(--font-size-xs);
}
/* 图标砖与副标题按同一比例收紧。副标题不再往下缩到 micro:
340px 机型下单元格约 72px 宽,4 字副标题 12px 仍放得下,没必要牺牲可读性。 */
.entry-icon {
width: 40.00px;
height: 40.00px;
background-size: 22.00px 22.00px, 100% 100%;
}
.banner-title {
font-size: var(--font-size-xl);
}
.status-checks {
overflow-x: auto;
}
.empty-btn {
min-width: 54.00px;
padding: 0 var(--spacing-1);
}
}
/**
* 丹阳公益婚恋服务平台 - 全局 Design Token
*
* v2(2026-09-22 设计系统夯实)
* ---------------------------------------------------------------
* 本次修订针对审计发现的系统性问题,逐条给出依据:
*
* 1) 品牌色不能承载文字 → 引入「基础色 / -strong」分级
* #E96B6B on 白 = 3.10:1,白字 on #E96B6B = 3.10:1,on #FFF3F2 = 2.85:1,
* 三条路径都不满足正文 4.5:1。故:
* --color-primary 仅用于大色块、渐变、光晕、装饰(非文字)
* --color-primary-strong 用于文字、小图标、纯文字链接(5.33:1 ✓)
* --color-primary-solid 实心按钮底(白字 ≥4.5:1 ✓)
* 功能色(success/warning/danger/info)同此分级。
*
* 2) 次要文字对比度过低
* 旧 --color-text-tertiary(#777) = 4.48(on 白,勉强)/ #999 实测 2.85 却被用了 71 次。
* 现将三级文字压到 #646C85 = 5.22:1,占位符保留浅色(占位符非正文)。
*
* 3) 颜色碎片化
* 审计前全站 182 种 hex、770 次硬编码(54 种灰、60 种蓝紫、40 种红橙)。
* 本文件是唯一的颜色事实源;页面层禁止再写 hex,一律 var(--token)。
*
* 4) 触摸目标
* 组件库默认按钮只有 40px、小号 28px、"喜欢"按钮 31px。
* 统一以 --tap-min(44.00px=44px) 为下限,--tap-gap 为最小间距。
*
* 5) 动效几乎未落地(--motion-* 全站仅 5 次引用)
* 补充 --ease-spring 与 --press-scale,让点击有即时反馈。
*
* 6) 夜间氛围层缺失(参考图有明显的光晕/星点,代码只有纯渐变)
* 新增 --mini-glow-* / --mini-star / --mini-glass / --mini-hairline。
*
* 单位说明:rpx(375.00px = 屏幕宽度,0.50px ≈ 0.5px @375pt)
* 旧 token 名全部保留(88 个 wxss 共 909 处引用),只更新取值,避免大范围失效。
*/
.wx-page {
/* ============ 品牌主色(分级:色块 / 文字 / 实心按钮) ============ */
--color-primary: #E96B6B; /* 基础色:渐变、光晕、装饰、非文字图形 */
--color-primary-strong: #B8434A; /* 文字与小图标(5.33:1 on 白,4.91:1 on 浅粉底) */
--color-primary-solid: #C24C50; /* 实心按钮底(白字 4.62:1) */
--color-primary-active: #D95F5F; /* 按压态(配合 --color-primary 使用) */
--color-primary-light: #FFF3F2;
--color-primary-lighter: #FFF8F7;
/* ============ 小程序参考图品牌主题(夜间紫蓝) ============ */
--mini-night-start: #172A72;
--mini-night-end: #25104F;
--mini-night-soft: #3445A1;
--mini-accent-pink: #FF4F91; /* 点缀色:仅用于色块/装饰,不作正文 */
--mini-accent-coral: #FF6A78;
--mini-card-bg: rgba(255, 255, 255, 0.98);
--mini-text: #1F2744;
--mini-muted: #7D839B;
--mini-card-radius: 12.00px;
--mini-text-on-night: #FFFFFF; /* on 深底 13.04:1 ✓ */
--mini-text-on-night-muted: rgba(255, 255, 255, 0.72); /* on 深底 ≈8:1 ✓ */
--mini-shadow: 0 8.00px 20.00px rgba(28, 30, 88, 0.14);
/* ---- 渐变(集中定义:此前 4 个页面各写了一份「橙红渐变」按钮) ---- */
/* --gradient-brand 明亮活泼,但白字仅 2.77:1 —— 只能用于无文字的装饰填充。 */
--gradient-brand: linear-gradient(135deg, #FF6A78 0%, #E96B6B 100%);
/* 承载白字的 CTA 渐变:两端 #C24C50(4.73:1) / #B8434A(5.33:1) 均达标。 */
--gradient-brand-solid: linear-gradient(135deg, #C24C50 0%, #B8434A 100%);
--gradient-night: linear-gradient(160deg, #172A72 0%, #25104F 100%);
--gradient-night-soft: linear-gradient(160deg, #3445A1 0%, #172A72 100%);
/* ---- 首页 4×2 入口宫格图标渐变(参考图 2:高饱和圆角砖 + 白色描画图标) ----
白图标的对比度判据是**非文本图形 3:1**(WCAG 1.4.11)。渐变是斜向的、图标又跨在
两色之间,所以**较亮的一端也必须达标** —— 下表注释给的是 0% 处实算值,100% 更暗只会更高。
色相按业务语义固定(不随 tone 名漂移):找对象/婚前辅导=玫瑰粉系、公益红娘/服务站=暖橙系、
公益活动=紫罗兰、婚恋咨询=蓝、婚恋课堂=紫、婚恋反诈=绿。 */
--gradient-entry-rose: linear-gradient(135deg, #F56287 0%, #F34671 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-orange: linear-gradient(135deg, #F66A06 0%, #D95E06 100%); /* 3.01:1 / 3.78:1 */
--gradient-entry-violet: linear-gradient(135deg, #A380F5 0%, #8F64F2 100%); /* 3.02:1 / 3.98:1 */
--gradient-entry-blue: linear-gradient(135deg, #5195F6 0%, #3484F4 100%); /* 3.01:1 / 3.65:1 */
--gradient-entry-purple: linear-gradient(135deg, #B27BF0 0%, #A260ED 100%); /* 3.01:1 / 3.87:1 */
--gradient-entry-pink: linear-gradient(135deg, #F2619E 0%, #F0458C 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-green: linear-gradient(135deg, #18A979 0%, #148F66 100%); /* 3.00:1 / 4.08:1 */
--gradient-entry-amber: linear-gradient(135deg, #E9740C 0%, #CC650B 100%); /* 3.01:1 / 3.86:1 */
/* 图标砖落影:比 --mini-shadow 更小,避免 4 列宫格里相邻砖块的投影互相压边 */
--mini-entry-shadow: 0 4.00px 9.00px rgba(28, 30, 88, 0.18);
/* ---- 夜间氛围层(v2 新增;参考图有光晕与星点,此前完全没有) ---- */
--mini-glow-coral: rgba(255, 79, 145, 0.40);
--mini-glow-indigo: rgba(94, 124, 255, 0.32);
--mini-glow-soft: rgba(255, 255, 255, 0.10);
--mini-star: rgba(255, 255, 255, 0.70);
--mini-glass: rgba(255, 255, 255, 0.10); /* 深底玻璃面 */
--mini-glass-strong: rgba(255, 255, 255, 0.16);
--mini-hairline: rgba(255, 255, 255, 0.16); /* 深底分隔线 */
--mini-glass-success: rgba(90, 226, 184, 0.16); /* 深底上的成功态玻璃面 */
/* 星点层:多个小径向渐变叠在夜空渐变之上。用 radial-gradient 而非图片,
避免额外请求,也便于随主题换色(index 页脚注:装饰层不承载信息)。 */
--mini-starfield:
radial-gradient(circle at 12% 18%, var(--mini-star) 0, transparent 1.25px),
radial-gradient(circle at 31% 66%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 57% 12%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 79% 52%, var(--mini-star) 0, transparent 1.50px),
radial-gradient(circle at 93% 84%, var(--mini-star) 0, transparent 1.00px);
/* 横幅压暗层:保证任何底图上的白色标题都有足够对比度 */
--mini-banner-scrim: linear-gradient(90deg, rgba(23, 42, 114, 0.84) 0%, rgba(37, 16, 79, 0.40) 56%, rgba(255, 79, 145, 0.12) 100%);
/* ============ 功能色(同样分级) ============ */
--color-success: #2E9B68; /* 色块/图标 */
--color-success-strong: #17805A; /* 文字(4.92:1 ✓) */
--color-success-light: #ECF8F2;
--color-warning: #E59A32; /* 色块/图标(作文字仅 2.33:1) */
--color-warning-strong: #9C5F14; /* 文字(5.17:1 ✓) */
--color-warning-light: #FFF7E9;
--color-danger: #D94A4A; /* 色块/图标 */
--color-danger-strong: #C62828; /* 文字(5.62:1 ✓) */
--color-danger-light: #FFF0F0;
--color-info: #4A7CD4; /* 色块/图标 */
--color-info-strong: #2A5DB0; /* 文字(6.38:1 ✓) */
--color-info-light: #EEF4FF;
/* ============ 强调紫(参考图的标签语言;此前散落成 6 种写法) ============ */
--color-accent-purple: #8B63BC; /* 色块/装饰 */
--color-accent-purple-strong: #7C60BC; /* 文字(5.03:1 ✓) */
--color-accent-purple-light: #F3EEFF;
/* 深色夜空底上的强调色(不可用于浅色底) */
--color-success-on-night: #A6F5D7; /* on #172A72 = 10.35:1 ✓ */
/* ============ 文字色(实测对比度 on 白 / on 页面底) ============ */
--color-text-strong: #1A1F36; /* 标题 16.24 / 14.90 ✓ */
--color-text-primary: #2A3050; /* 正文 12.83 / 11.77 ✓ */
--color-text-secondary: #4A5169; /* 次要正文 7.86 / 7.21 ✓ */
--color-text-tertiary: #646C85; /* 说明文字 5.22 / 4.79 ✓(旧 #777 为 4.48) */
--color-text-placeholder: #9AA1B4; /* 占位符(非正文,可浅) */
--color-text-disabled: #B8BDC9;
--color-text-inverse: #FFFFFF; /* 深色背景上的文字 */
/* ============ 边框与分割线 ============ */
--color-border: #E6E8EF;
--color-border-strong: #D8DBE5;
--color-divider: #EFF0F5;
--color-border-focus: #B8434A; /* 焦点环用 strong,保证 3:1 可见度 */
--color-border-error: #C62828;
/* ============ 背景(避免纯白/纯灰平铺,页面底为暖白) ============ */
--color-bg-page: #F6F5F3;
--color-bg-card: #FFFFFF;
--color-bg-subtle: #F5F6FA; /* 次级区块、内嵌列表 */
--color-bg-muted: #EEF0F6; /* 更弱的填充 */
--color-bg-input: #F7F8FB; /* 表单输入框底(此前被引用但从未定义,导致背景失效) */
--color-bg-disabled: #F3F4F7;
--color-bg-overlay: rgba(0, 0, 0, 0.45);
/* ============ 字体 ============ */
/* 小程序无法可靠加载 Web Font(wx.loadFontFace 依赖 HTTPS 白名单且有闪动风险),
故使用中文系统字栈:iOS 走苹方、Android 走思源/系统黑体。
排版辨识度靠字号阶梯与字重建立,而非依赖字体本身。 */
--font-family-cn: -apple-system, "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
--font-family-number: "SF Pro Display", -apple-system, "DIN Alternate", "PingFang SC", sans-serif;
/* 字号阶梯 —— 正文 16.00px(16px) 起,元信息下限 12.00px(12px) */
--font-size-micro: 11.00px; /* 11px 仅角标/装饰,禁用于正文 */
--font-size-xs: 12.00px; /* 12px 元信息下限 */
--font-size-sm: 13.00px; /* 13px 次要说明 */
--font-size-md: 14.00px; /* 14px 次要正文 */
--font-size-base: 16.00px; /* 16px 正文 */
--font-size-lg: 18.00px; /* 18px 小标题 */
--font-size-xl: 20.00px; /* 20px 区块标题 */
--font-size-2xl: 24.00px; /* 24px 页面标题 */
--font-size-3xl: 28.00px; /* 28px 大标题 */
--font-size-display: 32.00px; /* 32px Hero */
/* 字重:只用 4 档。禁止 550/650/750 等非百位值 —— Android 无对应字重会回退,
导致同一设计在不同机型上粗细不一致(审计发现 30 处)。 */
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.65;
--letter-spacing-tight: 0;
--letter-spacing-wide: 0.50px;
--letter-spacing-wider: 1.00px;
/* ============ 间距(4px 栅格) ============ */
--spacing-1: 4.00px;
--spacing-2: 8.00px;
--spacing-3: 12.00px;
--spacing-4: 16.00px;
--spacing-5: 20.00px;
--spacing-6: 24.00px;
--spacing-8: 32.00px;
--spacing-10: 40.00px;
--spacing-12: 48.00px;
--spacing-page-x: 16.00px;
--spacing-section: 24.00px;
--spacing-card-inner: 16.00px;
--spacing-tight: 8.00px;
/* ============ 圆角 ============ */
--radius-sm: 8.00px;
--radius-md: 12.00px;
--radius-lg: 16.00px;
--radius-xl: 20.00px;
--radius-2xl: 24.00px;
--radius-full: 4999.50px;
/* ============ 阴影(统一为一套,此前 30+ 种近似值) ============ */
--shadow-card: 0 4.00px 14.00px rgba(35, 35, 95, 0.07);
--shadow-raised: 0 6.00px 18.00px rgba(35, 35, 95, 0.10);
--shadow-popup: 0 8.00px 32.00px rgba(0, 0, 0, 0.10);
--shadow-night: 0 8.00px 20.00px rgba(28, 30, 88, 0.18);
/* ============ 边框宽度 ============ */
--border-width: 0.50px;
--border-width-strong: 1.00px;
/* ============ 触摸目标(无障碍下限 44×44px) ============ */
--tap-min: 44.00px; /* 44px 最小可点区域 */
--tap-comfortable: 48.00px; /* 48px 舒适尺寸:主操作 */
--tap-gap: 8.00px; /* 8px 相邻目标最小间距 */
/* ============ 动效 ============ */
--motion-fast: 120ms;
--motion-normal: 200ms;
--motion-slow: 300ms;
--ease-standard: cubic-bezier(0.32, 0.72, 0, 1);
--ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
--press-scale: 0.97;
--press-opacity: 0.88;
/* ============ 层级 z-index ============ */
--z-base: 1;
--z-sticky: 100;
--z-tabbar: 200;
--z-dropdown: 500;
--z-modal: 1000;
--z-toast: 2000;
--z-ambient: 0;
/* ============ 页面基础样式 ============ */
background-color: var(--color-bg-page);
font-family: var(--font-family-cn);
font-size: var(--font-size-base);
color: var(--color-text-primary);
line-height: var(--line-height-normal);
}
/* ==========================================================================
通用工具类
========================================================================== */
.container {
padding: var(--spacing-page-x);
}
.flex { display: flex; }
.flex-column { display: flex; flex-direction: column; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-start { display: flex; align-items: center; justify-content: flex-start; }
.flex-1 { flex: 1; min-width: 0; }
.flex-shrink-0 { flex-shrink: 0; }
.wrap { flex-wrap: wrap; }
/* 4 列宫格:用 flex + 百分比宽度实现。
注:display:grid 在 WebView 渲染下可用,但 Skyline 不支持,故统一改为 flex 以免疫渲染引擎迁移。*/
.grid-4 {
display: flex;
flex-wrap: wrap;
}
.grid-4 > .grid-item {
width: 25%;
box-sizing: border-box;
}
.text-strong { color: var(--color-text-strong); }
.text-primary { color: var(--color-text-primary); }
.text-secondary { color: var(--color-text-secondary); }
.text-tertiary { color: var(--color-text-tertiary); }
.text-placeholder { color: var(--color-text-placeholder); }
.text-white { color: var(--color-text-inverse); }
.text-brand { color: var(--color-primary-strong); }
/* 品牌色作文字只能用 -strong 变体:基础色 #E96B6B 在白底仅 3.10:1。
保留 .text-brand-soft 这个类名是为了不破坏既有引用,取值已统一到 -strong,
如需「更亮的品牌色」请用于背景/图形而非文字。 */
.text-brand-soft { color: var(--color-primary-strong); }
.text-success { color: var(--color-success-strong); }
.text-warning { color: var(--color-warning-strong); }
.text-danger { color: var(--color-danger-strong); }
.text-info { color: var(--color-info-strong); }
.font-micro { font-size: var(--font-size-micro); }
.font-xs { font-size: var(--font-size-xs); }
.font-sm { font-size: var(--font-size-sm); }
.font-md { font-size: var(--font-size-md); }
.font-base { font-size: var(--font-size-base); }
.font-lg { font-size: var(--font-size-lg); }
.font-xl { font-size: var(--font-size-xl); }
.font-2xl { font-size: var(--font-size-2xl); }
.font-3xl { font-size: var(--font-size-3xl); }
.font-display { font-size: var(--font-size-display); }
.font-regular { font-weight: var(--font-weight-regular); }
.font-medium { font-weight: var(--font-weight-medium); }
.font-semibold { font-weight: var(--font-weight-semibold); }
.font-bold { font-weight: var(--font-weight-bold); }
.mt-1 { margin-top: var(--spacing-1); }
.mt-2 { margin-top: var(--spacing-2); }
.mt-3 { margin-top: var(--spacing-3); }
.mt-4 { margin-top: var(--spacing-4); }
.mt-5 { margin-top: var(--spacing-5); }
.mt-6 { margin-top: var(--spacing-6); }
.mb-1 { margin-bottom: var(--spacing-1); }
.mb-2 { margin-bottom: var(--spacing-2); }
.mb-3 { margin-bottom: var(--spacing-3); }
.mb-4 { margin-bottom: var(--spacing-4); }
.mb-5 { margin-bottom: var(--spacing-5); }
.mb-6 { margin-bottom: var(--spacing-6); }
/* 文本省略 */
.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ellipsis-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
/* 安全区底部留白(避开 Home Indicator) */
.safe-area-bottom {
padding-bottom: 0px;
}
/* 页面卡片基础样式 */
.card-base {
background: var(--color-bg-card);
border-radius: var(--radius-lg);
padding: var(--spacing-card-inner);
box-shadow: var(--shadow-card);
}
/* 分割线 */
.divider {
height: var(--border-width);
background: var(--color-divider);
}
/* ==========================================================================
可访问性:只用 token,不用工具类(2026-09-23 修订)
--------------------------------------------------------------------------
v2 曾在此处新增 .tap-min / .tap-gap / .focusable / .pressable 四个工具类。
复检发现全部零引用(等价能力已各自写在组件样式内,例如 button/index.wxss
直接使用 min-height:var(--tap-min)),且存在两个硬问题:
1) `.tap-gap > * + *` 用了通配符与兄弟选择器 —— WXSS 不支持,
wcc 编译期直接报 `error at token '*'`,导致整个小程序编译失败。
(这是编译错误,不是静默失效,代价最高。)
2) `.pressable:active` / `.focusable:focus-visible` 的伪类在 view 上
不生效(小程序须用 hover-class),属于"写了等于没写"。
故整块移除,保留 token。需要热区/间距时直接引用 token:
min-height: var(--tap-min); → 44.00px = 44px,最小可点区域
gap: var(--tap-gap); → 8.00px = 8px,相邻目标间距(flex gap)
【WXSS 禁用清单】星号通配符、兄弟选择器、属性选择器。
【注释约束】WXSS 注释**不可嵌套**:内层注释的结束标记会提前终止外层注释,
其后的文字会被当成真实样式解析,导致编译失败或样式被污染。
(2026-09-23 实证:本块注释初版即踩此坑。)
========================================================================== */
.wx-page{background:var(--color-bg-page)}.service-page{min-height:100vh;padding-bottom:calc(70.00px + 0px)}.hero{padding:22.00px 16.00px 27.00px;background:linear-gradient(140deg,var(--color-primary-lighter),var(--color-warning-light));position:relative;overflow:hidden}.eyebrow{display:inline-flex;padding:3.50px 7.00px;border-radius:499.50px;background:rgba(255,255,255,.72);color:var(--color-primary-strong);font-size:12.00px}.hero-title{display:block;margin-top:9.00px;font-size:20.00px;font-weight:700;line-height:1.35}.hero-desc{display:block;width:82%;margin-top:7.00px;font-size:12.50px;color:var(--color-text-secondary);line-height:1.7}.content{padding:0 var(--spacing-page-x)}.block{margin-top:var(--spacing-section)}.block-title{display:block;font-size:15.50px;font-weight:600}.block-subtitle{display:block;margin-top:4.00px;font-size:12.00px;color:var(--color-text-tertiary)}.card{margin-top:9.00px;padding:14.00px;background:var(--color-bg-card);border:0.50px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-card)}.feature-row,.menu-row,.record-row{display:flex;align-items:center;gap:10.00px;min-height:56.00px;padding:9.00px 0;border-bottom:0.50px solid var(--color-divider)}.feature-row:last-child,.menu-row:last-child,.record-row:last-child{border-bottom:0}.feature-icon{width:36.00px;height:36.00px;display:flex;align-items:center;justify-content:center;flex:none;border-radius:11.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-weight:700}.feature-copy{flex:1;min-width:0}.feature-title{display:block;font-size:14.00px;font-weight:600}.feature-desc,.meta{display:block;margin-top:3.50px;font-size:12.00px;color:var(--color-text-tertiary);line-height:1.55}.arrow{font-size:20.00px;color:var(--color-text-disabled)}.tag{display:inline-flex;margin-right:5.00px;margin-top:5.00px;padding:3.00px 6.50px;border-radius:499.50px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px}.tag.warning{background:var(--color-warning-light);color:var(--color-warning-strong)}.primary-btn,.secondary-btn{height:44.00px;display:flex;align-items:center;justify-content:center;border-radius:22.00px;font-size:14.00px;font-weight:600}.primary-btn{background:var(--gradient-brand-solid);color:var(--color-text-inverse);box-shadow:0 5.00px 12.00px rgba(255,92,130,.22)}.primary-btn.disabled{background:var(--color-bg-muted);color:var(--color-text-tertiary);box-shadow:none}.secondary-btn{background:var(--color-primary-light);color:var(--color-primary-strong)}.fixed-action{position:fixed;left:0;right:0;bottom:0;padding:9.00px var(--spacing-page-x) calc(9.00px + 0px);background:rgba(255,255,255,.96);border-top:0.50px solid var(--color-divider);z-index:100}.field{margin-top:13.00px}.label{display:block;margin-bottom:6.00px;font-size:12.50px;font-weight:600}.input,.select-box,.textarea{width:100%;box-sizing:border-box;background:var(--color-bg-page);border:0.50px solid var(--color-border);border-radius:var(--radius-md);font-size:13.00px}.input,.select-box{height:44.00px;padding:0 12.00px;display:flex;align-items:center}.textarea{min-height:90.00px;padding:11.00px}.notice{margin-top:10.00px;padding:11.00px;border-radius:var(--radius-md);background:var(--color-info-light);color:var(--color-text-secondary);font-size:12.00px;line-height:1.65}.select-box.is-readonly{background:var(--color-bg-subtle);color:var(--color-text-secondary)}.empty-panel{text-align:center;padding:35.00px 15.00px}.empty-symbol{width:48.00px;height:48.00px;margin:auto;display:flex;align-items:center;justify-content:center;border-radius:15.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-size:18.00px;font-weight:700}.empty-title{display:block;margin-top:11.00px;font-size:15.00px;font-weight:600}.article-card{margin-top:9.00px;background:var(--color-bg-card);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-card)}.article-cover{height:110.00px;padding:12.00px;background:linear-gradient(135deg,var(--color-warning-light),var(--color-warning-light));display:flex;align-items:flex-end}.article-cover text{font-size:21.00px;color:rgba(125,76,63,.52);font-weight:700}.article-body{padding:12.00px}.article-title{display:block;font-size:14.50px;font-weight:600;line-height:1.45}.article-meta{display:block;margin-top:5.00px;font-size:12.00px;color:var(--color-text-tertiary)}.article-content{padding:16.00px;background:var(--color-bg-card);font-size:14.00px;line-height:1.9;color:var(--color-text-secondary)}.article-content .lead{display:block;font-size:15.50px;color:var(--color-text-primary);font-weight:600;margin-bottom:12.00px}.danger-card{background:var(--color-primary-lighter);border-color:var(--color-primary-light)}.danger-card .feature-icon{background:var(--color-warning-light);color:var(--color-warning-strong)}@media(max-width:340px){.hero-title{font-size:18.00px}.hero-desc{width:92%}}
.service-shell{min-height:100vh;padding-bottom:calc(68.00px + 0px);background:var(--color-bg-page)}.service-content{padding:4.00px 12.00px 18.00px}.service-status{display:flex;align-items:center;justify-content:space-between;margin-top:12.00px;padding:10.00px 12.00px;border-radius:11.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-status__label{color:var(--color-text-tertiary);font-size:12.00px}.service-status__value{padding:3.00px 7.00px;border-radius:9.00px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px;font-weight:600}.service-status__value.disabled{background:var(--color-danger-light);color:var(--color-danger-strong)}.service-topics{display:grid;grid-template-columns:repeat(2,1fr);gap:8.00px;margin-top:9.00px}.service-topic{min-height:74.00px;padding:10.00px;border-radius:12.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-topic__icon{display:flex;align-items:center;justify-content:center;width:27.00px;height:27.00px;border-radius:8.50px;background:var(--color-primary-light)}.service-topic__icon image{width:17.00px;height:17.00px}.service-topic__title{display:block;margin-top:6.50px;color:var(--color-text-strong);font-size:12.00px;font-weight:600}.service-topic__desc{display:block;margin-top:3.00px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}.service-actions{display:flex;gap:7.00px}.service-actions .secondary-btn{width:95.00px;flex:none}.service-actions .primary-btn{flex:1}.privacy-note{display:flex;align-items:flex-start;gap:7.00px;margin-top:11.00px;padding:10.00px;border-radius:11.00px;background:var(--color-info-light);color:var(--color-text-tertiary);font-size:12.00px;line-height:1.55}.privacy-note image{width:17.00px;height:17.00px;flex:none}
/* ==== miniapp/components/user-card ==== */
.ui-user-card {
display:flex;
align-items:center;
background:var(--color-bg-card);
min-height:74.00px;
padding:7.00px 9.00px;
border-bottom:0.50px solid var(--color-divider);
}
.ui-user-card__select {
margin-right:var(--spacing-3);
}
.ui-user-card__checkbox {
transform:scale(.82);
}
.ui-user-card__body {
flex:1;
min-width:0;
margin-left:8.00px;
}
.ui-user-card__name-row {
display:flex;
align-items:baseline;
margin-bottom:var(--spacing-1);
}
.ui-user-card__name {
font-size:13.00px;
font-weight:700;
color:var(--color-text-strong);
margin-right:var(--spacing-2);
}
.ui-user-card__age {
font-size:12.00px;
color:var(--color-text-secondary);
}
.ui-user-card__online {
margin-left:auto;
color:var(--color-success-strong);
font-size:12.00px;
}
.ui-user-card__meta {
font-size:12.00px;
color:var(--color-text-tertiary);
line-height:1.4;
margin-top:2.00px;
}
.ui-user-card__actions {
flex-shrink:0;
margin-left:var(--spacing-2);
}
.ui-user-card__tags{display:flex;gap:3.50px;margin-top:4.00px;overflow:hidden}.ui-user-card__tag{flex:none;padding:2.00px 4.50px;border-radius:6.00px;background:var(--color-accent-purple-light);color:var(--color-accent-purple-strong);font-size:12.00px;white-space:nowrap}
/* ==== miniapp/components/button ==== */
/**
* Button 组件样式
* 引用全局 Design Token(addGlobalClass:true)
*
* 2026-09-22 修复:
* 1) 触摸目标:md 只有 40.00px(40px)、sm 只有 28.00px(28px),低于 44px 下限;
* text 变体更是 min-height:auto,几乎点不中。现统一以 --tap-min 兜底。
* 2) 对比度:主按钮背景原为 --color-primary(#E96B6B),白字仅 3.10:1。
* 改用 --color-primary-solid(#C24C50) = 4.73:1,视觉上仍是暖红。
* secondary/text 的红色文字同理从 3.10 提到 --color-primary-strong 的 5.33。
* 3) 危险按钮 --color-danger(#D94A4A) 白字 4.18:1 不达标,改用 -strong 变体。
* 4) 按压反馈统一走 --press-scale / --press-opacity,替代硬编码 0.98 / 0.85。
*/
.ui-btn {
display:inline-flex;
align-items:center;
justify-content:center;
box-sizing:border-box;
border-radius:var(--radius-full);
font-family:var(--font-family-cn);
font-weight:var(--font-weight-semibold);
text-align:center;
transition:transform var(--motion-fast) var(--ease-spring),
opacity var(--motion-fast) var(--ease-standard),
background-color var(--motion-fast) var(--ease-standard);
user-select:none;
line-height:1.2;
white-space:nowrap;
}
/* 尺寸:全部以 44×44px 为热区下限 */
.ui-btn--sm {
padding:7.00px 14.00px;
font-size:var(--font-size-sm);
min-height:var(--tap-min);
}
.ui-btn--md {
padding:10.00px 18.00px;
font-size:var(--font-size-base);
min-height:var(--tap-min);
}
.ui-btn--lg {
padding:13.00px 24.00px;
font-size:var(--font-size-lg);
min-height:var(--tap-comfortable);
}
/* 撑满 */
.ui-btn--block {
display:flex;
width:100%;
}
/* 变体 */
.ui-btn--primary {
background:var(--color-primary-solid);
color:var(--color-text-inverse);
}
.ui-btn--secondary {
background:var(--color-bg-card);
color:var(--color-primary-strong);
border:var(--border-width) solid var(--color-primary-strong);
}
.ui-btn--ghost {
background:transparent;
color:var(--color-text-primary);
border:var(--border-width) solid var(--color-border-strong);
}
.ui-btn--danger {
background:var(--color-danger-strong);
color:var(--color-text-inverse);
}
.ui-btn--text {
background:transparent;
color:var(--color-primary-strong);
padding-left:var(--spacing-2);
padding-right:var(--spacing-2);
/* 视觉是纯文字,但热区仍需 44px:多出的部分由 align-items:center 居中留白 */
min-height:var(--tap-min);
}
/* 状态 */
.ui-btn--disabled,
.ui-btn--loading {
opacity:0.55;
}
.ui-btn--disabled.ui-btn--primary,
.ui-btn--disabled.ui-btn--danger {
background:var(--color-text-disabled);
}
.ui-btn--disabled.ui-btn--secondary,
.ui-btn--disabled.ui-btn--ghost {
color:var(--color-text-disabled);
border-color:var(--color-text-disabled);
}
/* 按压反馈(hover-class 与 CSS :active 双保险) */
.ui-btn--hover,
.ui-btn:active {
opacity:var(--press-opacity);
transform:scale(var(--press-scale));
}
/* Loading spinner */
.ui-btn__spinner {
width:14.00px;
height:14.00px;
margin-right:6.00px;
display:flex;
align-items:center;
justify-content:center;
}
.ui-btn__spinner-dot {
width:9.00px;
height:9.00px;
border-radius:50%;
border:1.50px solid currentColor;
border-top-color:transparent;
animation:ui-btn-spin 0.7s linear infinite;
}
@keyframes ui-btn-spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
/* ==== miniapp/components/loading ==== */
.ui-loading--block {
display:flex;
flex-direction:column;
align-items:center;
justify-content:center;
padding:var(--spacing-8) var(--spacing-page-x);
}
.ui-loading--inline {
display:inline-flex;
align-items:center;
}
.ui-loading__spinner {
width:30.00px;
height:30.00px;
display:flex;
align-items:center;
justify-content:center;
}
.ui-loading__spinner-icon {
width:24.00px;
height:24.00px;
animation:ui-loading-spin 0.8s linear infinite;
}
@keyframes ui-loading-spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
.ui-loading__text {
margin-top:var(--spacing-3);
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
}
/* Skeleton */
.ui-loading__skeleton {
width:100%;
}
.ui-loading__skeleton-row {
display:flex;
align-items:center;
padding:var(--spacing-3) var(--spacing-page-x);
background:var(--color-bg-card);
border-bottom:0.50px solid var(--color-divider);
}
.ui-loading__skeleton-avatar {
width:44.00px;
height:44.00px;
border-radius:50%;
background:var(--color-bg-disabled);
margin-right:var(--spacing-3);
flex-shrink:0;
}
.ui-loading__skeleton-content {
flex:1;
min-width:0;
}
.ui-loading__skeleton-line {
height:12.00px;
background:var(--color-bg-disabled);
border-radius:var(--radius-sm);
position:relative;
overflow:hidden;
}
.ui-loading__skeleton-line--title {
width:40%;
margin-bottom:var(--spacing-2);
}
.ui-loading__skeleton-line--meta {
width:70%;
}
/* shimmer */
.ui-loading__skeleton-line::after,
.ui-loading__skeleton-avatar::after {
content:'';
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background:linear-gradient(
90deg,
transparent 0%,
rgba(255, 255, 255, 0.55) 50%,
transparent 100%
);
animation:ui-loading-shimmer 1.4s ease-in-out infinite;
}
@keyframes ui-loading-shimmer {
0% { transform:translateX(-100%); }
100% { transform:translateX(100%); }
}
/* ==== miniapp/components/empty ==== */
.ui-empty {
display:flex;
flex-direction:column;
align-items:center;
padding:var(--spacing-10) var(--spacing-page-x);
text-align:center;
}
.ui-empty__illustration {
width:80.00px;
height:80.00px;
border-radius:50%;
background:var(--color-bg-disabled);
display:flex;
align-items:center;
justify-content:center;
margin-bottom:var(--spacing-4);
}
.ui-empty__icon {
width:36.00px;
height:36.00px;
opacity:0.72;
}
.ui-empty__title {
font-size:var(--font-size-lg);
font-weight:var(--font-weight-medium);
color:var(--color-text-primary);
margin-bottom:var(--spacing-2);
}
.ui-empty__desc {
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
line-height:var(--line-height-relaxed);
max-width:240.00px;
}
.ui-empty__actions {
display:flex;
flex-direction:column;
gap:var(--spacing-2);
margin-top:var(--spacing-6);
width:100%;
max-width:240.00px;
}
.ui-empty__action {
display:flex;
align-items:center;
justify-content:center;
min-height:var(--tap-min);
border-radius:var(--radius-full);
font-size:var(--font-size-base);
font-weight:var(--font-weight-medium);
min-width:var(--tap-min);}
.ui-empty__action--primary {
background:var(--color-primary-solid);
color:var(--color-text-inverse);
}
.ui-empty__action--secondary {
background:var(--color-bg-card);
color:var(--color-primary-strong);
border:0.50px solid var(--color-primary);
}
/* ==== miniapp/components/section-header ==== */
/**
* 区块标题(全站所有页面共用,是排版层级的关键一环)
*
* 2026-09-22 修订:
* 1) 层级拉开:标题 18.00px→20.00px(--font-size-xl),与正文 16.00px / 卡片标题 14.00px
* 形成「区块标题 > 卡片标题 > 正文 > 元信息」四级阶梯。
* 旧值 18.00px 与卡片标题仅差 5.00px,层级读不出来。
* 2) 右侧 action 是全站最容易被忽略的触摸目标:只有 13.00px 文字高(约 13px),
* 远低于 44px 下限。改为 min-height:--tap-min,热区向上补白。
* 3) action 文字色原为 --color-primary(#E96B6B)=3.10:1,不达标,改 -strong。
*/
.ui-section {
display:flex;
align-items:center;
justify-content:space-between;
padding:var(--spacing-2) var(--spacing-page-x);
}
.ui-section__left {
display:flex;
align-items:baseline;
min-width:0;
}
.ui-section__title {
font-size:var(--font-size-xl);
font-weight:var(--font-weight-semibold);
color:var(--color-text-strong);
letter-spacing:var(--letter-spacing-tight);
}
.ui-section__subtitle {
margin-left:var(--spacing-2);
font-size:var(--font-size-xs);
color:var(--color-text-tertiary);
}
.ui-section__action {
display:flex;
align-items:center;
flex:none;
min-height:var(--tap-min);
padding-left:var(--spacing-3);
font-size:var(--font-size-sm);
font-weight:var(--font-weight-medium);
color:var(--color-primary-strong);
transition:opacity var(--motion-fast) var(--ease-standard);
}
.ui-section__action:active {
opacity:var(--press-opacity);
}
.ui-section__arrow {
margin-left:2.00px;
width:12.00px;
height:12.00px;
}
.page{min-height:100vh;background:var(--color-bg-page)}
/* --nav-status / --nav-h / --nav-right 由 discover.ts 经 utils/nav-metrics 实测胶囊按钮后注入 */
.discover-hero{padding:var(--nav-status, 44px) 12.00px 12.00px;background:linear-gradient(160deg,var(--mini-night-start),var(--mini-night-end));border-radius:0 0 17.00px 17.00px;box-shadow:var(--mini-shadow);position:relative;z-index:1}
.discover-nav{height:var(--nav-h, 40.00px);display:flex;align-items:center;justify-content:center;position:relative;color:var(--color-text-inverse)}
.nav-title{font-size:15.50px;font-weight:700}
.nav-search{position:absolute;right:var(--nav-right, 102px);width:32.00px;height:32.00px;display:flex;align-items:center;justify-content:center;border:0.50px solid rgba(255,255,255,.18);border-radius:16.00px;background:rgba(255,255,255,.08)}
.nav-search image{width:19.00px;height:19.00px;filter:brightness(0) invert(1)}
.search-bar{display:flex;align-items:center}
.search-input{height:35.00px;flex:1;display:flex;align-items:center;padding:0 10.00px;border-radius:17.50px;background:rgba(255,255,255,.12);border:0.50px solid rgba(255,255,255,.14)}
.search-label{margin-right:7.00px;padding-right:7.00px;border-right:0.50px solid rgba(255,255,255,.2);font-size:12.00px;color:var(--color-text-inverse)}
.search-field{flex:1;font-size:12.00px;color:var(--color-text-inverse)}
.search-placeholder{font-size:12.00px;color:rgba(255,255,255,.52)}
.filter-scroll{margin-top:8.00px;white-space:nowrap}
.filter-chips{display:inline-flex;gap:6.00px}
.filter-chip{padding:5.50px 10.00px;border-radius:12.50px;background:rgba(255,255,255,.1);color:rgba(255,255,255,.72);font-size:12.00px}
.filter-chip.active{background:var(--color-bg-card);color:var(--color-primary-strong);font-weight:600}
/* 遮罩层 + 底部抽屉样式 */
.filter-mask{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.35);z-index:10}
.filter-panel-wrap{position:fixed;left:0;right:0;bottom:0;z-index:11;background:var(--color-bg-card);border-radius:14.00px 14.00px 0 0;max-height:78vh;box-shadow:0 -5.00px 20.00px rgba(31,32,89,.15);display:flex;flex-direction:column;padding:12.00px 14.00px 14.00px}
.filter-scroll-wrap{flex:1;max-height:calc(78vh - 70.00px);padding:4.00px 0 0}
.filter-section{margin-bottom:14.00px;padding:8.00px 10.00px;border-radius:8.00px;transition:background .2s,box-shadow .2s}
.filter-section.hl{background:var(--color-primary-light);box-shadow:inset 0 0 0 1.00px var(--mini-accent-pink)}
.filter-heading{display:flex;justify-content:space-between}
.filter-label{display:block;font-size:12.00px;font-weight:600;color:var(--color-text-strong)}
.filter-value{font-size:12.00px;color:var(--color-text-tertiary)}
.range-slider{margin:4.00px 0}
.tag-group{display:flex;flex-wrap:wrap;gap:7.00px;margin-top:8.00px}
.tag{padding:5.00px 11.00px;border-radius:11.00px;background:var(--color-bg-subtle);color:var(--color-text-secondary);font-size:12.00px}
.tag.selected{background:var(--color-primary-light);color:var(--color-primary-strong)}
.filter-actions{display:flex;gap:9.00px;margin-top:4.00px}
.result-head{padding:15.00px 13.00px 8.00px;display:flex;align-items:flex-end;justify-content:space-between}
.result-head>view{display:flex;flex-direction:column}
.result-title{font-size:15.00px;font-weight:700;color:var(--color-text-strong)}
.result-subtitle{margin-top:2.50px;font-size:12.00px;color:var(--color-text-tertiary)}
.result-count{font-size:10.00px;color:var(--color-text-tertiary)}
.user-list{margin:0 12.00px;padding:2.00px 0;background:var(--color-bg-card);border-radius:14.00px;overflow:hidden;box-shadow:0 5.00px 16.00px rgba(34,35,91,.08)}
.card-action{display:flex;align-items:center}
.like-button{width:var(--tap-min);min-height:var(--tap-min);display:flex;align-items:center;justify-content:center;border-radius:var(--radius-full);background:var(--color-primary-light);box-shadow:0 3.00px 9.00px rgba(255,79,145,.16);}
.like-button image{width:21.00px;height:21.00px}
.like-button.loading{opacity:.45}
.list-end-hint{text-align:center;padding:12.00px;font-size:12.00px;color:var(--color-text-tertiary)}
.discover-empty{margin:35.00px 20.00px 0;padding:17.00px;display:flex;flex-direction:column;align-items:center;background:var(--color-bg-card);border-radius:14.00px;box-shadow:0 5.00px 16.00px rgba(34,35,91,.08)}
.discover-empty image{width:56.00px;height:56.00px}
.empty-title{margin-top:6.00px;font-size:14.00px;font-weight:600;color:var(--color-text-strong)}
.empty-desc{margin-top:5.00px;text-align:center;font-size:12.00px;line-height:1.55;color:var(--color-text-tertiary)}
.empty-action{margin-top:12.00px;min-width:90.00px;min-height:var(--tap-min);display:flex;align-items:center;justify-content:center;border-radius:16.00px;background:var(--gradient-brand-solid);color:var(--color-text-inverse);font-size:12.00px;font-weight:600}
/**
* 丹阳公益婚恋服务平台 - 全局 Design Token
*
* v2(2026-09-22 设计系统夯实)
* ---------------------------------------------------------------
* 本次修订针对审计发现的系统性问题,逐条给出依据:
*
* 1) 品牌色不能承载文字 → 引入「基础色 / -strong」分级
* #E96B6B on 白 = 3.10:1,白字 on #E96B6B = 3.10:1,on #FFF3F2 = 2.85:1,
* 三条路径都不满足正文 4.5:1。故:
* --color-primary 仅用于大色块、渐变、光晕、装饰(非文字)
* --color-primary-strong 用于文字、小图标、纯文字链接(5.33:1 ✓)
* --color-primary-solid 实心按钮底(白字 ≥4.5:1 ✓)
* 功能色(success/warning/danger/info)同此分级。
*
* 2) 次要文字对比度过低
* 旧 --color-text-tertiary(#777) = 4.48(on 白,勉强)/ #999 实测 2.85 却被用了 71 次。
* 现将三级文字压到 #646C85 = 5.22:1,占位符保留浅色(占位符非正文)。
*
* 3) 颜色碎片化
* 审计前全站 182 种 hex、770 次硬编码(54 种灰、60 种蓝紫、40 种红橙)。
* 本文件是唯一的颜色事实源;页面层禁止再写 hex,一律 var(--token)。
*
* 4) 触摸目标
* 组件库默认按钮只有 40px、小号 28px、"喜欢"按钮 31px。
* 统一以 --tap-min(44.00px=44px) 为下限,--tap-gap 为最小间距。
*
* 5) 动效几乎未落地(--motion-* 全站仅 5 次引用)
* 补充 --ease-spring 与 --press-scale,让点击有即时反馈。
*
* 6) 夜间氛围层缺失(参考图有明显的光晕/星点,代码只有纯渐变)
* 新增 --mini-glow-* / --mini-star / --mini-glass / --mini-hairline。
*
* 单位说明:rpx(375.00px = 屏幕宽度,0.50px ≈ 0.5px @375pt)
* 旧 token 名全部保留(88 个 wxss 共 909 处引用),只更新取值,避免大范围失效。
*/
.wx-page {
/* ============ 品牌主色(分级:色块 / 文字 / 实心按钮) ============ */
--color-primary: #E96B6B; /* 基础色:渐变、光晕、装饰、非文字图形 */
--color-primary-strong: #B8434A; /* 文字与小图标(5.33:1 on 白,4.91:1 on 浅粉底) */
--color-primary-solid: #C24C50; /* 实心按钮底(白字 4.62:1) */
--color-primary-active: #D95F5F; /* 按压态(配合 --color-primary 使用) */
--color-primary-light: #FFF3F2;
--color-primary-lighter: #FFF8F7;
/* ============ 小程序参考图品牌主题(夜间紫蓝) ============ */
--mini-night-start: #172A72;
--mini-night-end: #25104F;
--mini-night-soft: #3445A1;
--mini-accent-pink: #FF4F91; /* 点缀色:仅用于色块/装饰,不作正文 */
--mini-accent-coral: #FF6A78;
--mini-card-bg: rgba(255, 255, 255, 0.98);
--mini-text: #1F2744;
--mini-muted: #7D839B;
--mini-card-radius: 12.00px;
--mini-text-on-night: #FFFFFF; /* on 深底 13.04:1 ✓ */
--mini-text-on-night-muted: rgba(255, 255, 255, 0.72); /* on 深底 ≈8:1 ✓ */
--mini-shadow: 0 8.00px 20.00px rgba(28, 30, 88, 0.14);
/* ---- 渐变(集中定义:此前 4 个页面各写了一份「橙红渐变」按钮) ---- */
/* --gradient-brand 明亮活泼,但白字仅 2.77:1 —— 只能用于无文字的装饰填充。 */
--gradient-brand: linear-gradient(135deg, #FF6A78 0%, #E96B6B 100%);
/* 承载白字的 CTA 渐变:两端 #C24C50(4.73:1) / #B8434A(5.33:1) 均达标。 */
--gradient-brand-solid: linear-gradient(135deg, #C24C50 0%, #B8434A 100%);
--gradient-night: linear-gradient(160deg, #172A72 0%, #25104F 100%);
--gradient-night-soft: linear-gradient(160deg, #3445A1 0%, #172A72 100%);
/* ---- 首页 4×2 入口宫格图标渐变(参考图 2:高饱和圆角砖 + 白色描画图标) ----
白图标的对比度判据是**非文本图形 3:1**(WCAG 1.4.11)。渐变是斜向的、图标又跨在
两色之间,所以**较亮的一端也必须达标** —— 下表注释给的是 0% 处实算值,100% 更暗只会更高。
色相按业务语义固定(不随 tone 名漂移):找对象/婚前辅导=玫瑰粉系、公益红娘/服务站=暖橙系、
公益活动=紫罗兰、婚恋咨询=蓝、婚恋课堂=紫、婚恋反诈=绿。 */
--gradient-entry-rose: linear-gradient(135deg, #F56287 0%, #F34671 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-orange: linear-gradient(135deg, #F66A06 0%, #D95E06 100%); /* 3.01:1 / 3.78:1 */
--gradient-entry-violet: linear-gradient(135deg, #A380F5 0%, #8F64F2 100%); /* 3.02:1 / 3.98:1 */
--gradient-entry-blue: linear-gradient(135deg, #5195F6 0%, #3484F4 100%); /* 3.01:1 / 3.65:1 */
--gradient-entry-purple: linear-gradient(135deg, #B27BF0 0%, #A260ED 100%); /* 3.01:1 / 3.87:1 */
--gradient-entry-pink: linear-gradient(135deg, #F2619E 0%, #F0458C 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-green: linear-gradient(135deg, #18A979 0%, #148F66 100%); /* 3.00:1 / 4.08:1 */
--gradient-entry-amber: linear-gradient(135deg, #E9740C 0%, #CC650B 100%); /* 3.01:1 / 3.86:1 */
/* 图标砖落影:比 --mini-shadow 更小,避免 4 列宫格里相邻砖块的投影互相压边 */
--mini-entry-shadow: 0 4.00px 9.00px rgba(28, 30, 88, 0.18);
/* ---- 夜间氛围层(v2 新增;参考图有光晕与星点,此前完全没有) ---- */
--mini-glow-coral: rgba(255, 79, 145, 0.40);
--mini-glow-indigo: rgba(94, 124, 255, 0.32);
--mini-glow-soft: rgba(255, 255, 255, 0.10);
--mini-star: rgba(255, 255, 255, 0.70);
--mini-glass: rgba(255, 255, 255, 0.10); /* 深底玻璃面 */
--mini-glass-strong: rgba(255, 255, 255, 0.16);
--mini-hairline: rgba(255, 255, 255, 0.16); /* 深底分隔线 */
--mini-glass-success: rgba(90, 226, 184, 0.16); /* 深底上的成功态玻璃面 */
/* 星点层:多个小径向渐变叠在夜空渐变之上。用 radial-gradient 而非图片,
避免额外请求,也便于随主题换色(index 页脚注:装饰层不承载信息)。 */
--mini-starfield:
radial-gradient(circle at 12% 18%, var(--mini-star) 0, transparent 1.25px),
radial-gradient(circle at 31% 66%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 57% 12%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 79% 52%, var(--mini-star) 0, transparent 1.50px),
radial-gradient(circle at 93% 84%, var(--mini-star) 0, transparent 1.00px);
/* 横幅压暗层:保证任何底图上的白色标题都有足够对比度 */
--mini-banner-scrim: linear-gradient(90deg, rgba(23, 42, 114, 0.84) 0%, rgba(37, 16, 79, 0.40) 56%, rgba(255, 79, 145, 0.12) 100%);
/* ============ 功能色(同样分级) ============ */
--color-success: #2E9B68; /* 色块/图标 */
--color-success-strong: #17805A; /* 文字(4.92:1 ✓) */
--color-success-light: #ECF8F2;
--color-warning: #E59A32; /* 色块/图标(作文字仅 2.33:1) */
--color-warning-strong: #9C5F14; /* 文字(5.17:1 ✓) */
--color-warning-light: #FFF7E9;
--color-danger: #D94A4A; /* 色块/图标 */
--color-danger-strong: #C62828; /* 文字(5.62:1 ✓) */
--color-danger-light: #FFF0F0;
--color-info: #4A7CD4; /* 色块/图标 */
--color-info-strong: #2A5DB0; /* 文字(6.38:1 ✓) */
--color-info-light: #EEF4FF;
/* ============ 强调紫(参考图的标签语言;此前散落成 6 种写法) ============ */
--color-accent-purple: #8B63BC; /* 色块/装饰 */
--color-accent-purple-strong: #7C60BC; /* 文字(5.03:1 ✓) */
--color-accent-purple-light: #F3EEFF;
/* 深色夜空底上的强调色(不可用于浅色底) */
--color-success-on-night: #A6F5D7; /* on #172A72 = 10.35:1 ✓ */
/* ============ 文字色(实测对比度 on 白 / on 页面底) ============ */
--color-text-strong: #1A1F36; /* 标题 16.24 / 14.90 ✓ */
--color-text-primary: #2A3050; /* 正文 12.83 / 11.77 ✓ */
--color-text-secondary: #4A5169; /* 次要正文 7.86 / 7.21 ✓ */
--color-text-tertiary: #646C85; /* 说明文字 5.22 / 4.79 ✓(旧 #777 为 4.48) */
--color-text-placeholder: #9AA1B4; /* 占位符(非正文,可浅) */
--color-text-disabled: #B8BDC9;
--color-text-inverse: #FFFFFF; /* 深色背景上的文字 */
/* ============ 边框与分割线 ============ */
--color-border: #E6E8EF;
--color-border-strong: #D8DBE5;
--color-divider: #EFF0F5;
--color-border-focus: #B8434A; /* 焦点环用 strong,保证 3:1 可见度 */
--color-border-error: #C62828;
/* ============ 背景(避免纯白/纯灰平铺,页面底为暖白) ============ */
--color-bg-page: #F6F5F3;
--color-bg-card: #FFFFFF;
--color-bg-subtle: #F5F6FA; /* 次级区块、内嵌列表 */
--color-bg-muted: #EEF0F6; /* 更弱的填充 */
--color-bg-input: #F7F8FB; /* 表单输入框底(此前被引用但从未定义,导致背景失效) */
--color-bg-disabled: #F3F4F7;
--color-bg-overlay: rgba(0, 0, 0, 0.45);
/* ============ 字体 ============ */
/* 小程序无法可靠加载 Web Font(wx.loadFontFace 依赖 HTTPS 白名单且有闪动风险),
故使用中文系统字栈:iOS 走苹方、Android 走思源/系统黑体。
排版辨识度靠字号阶梯与字重建立,而非依赖字体本身。 */
--font-family-cn: -apple-system, "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
--font-family-number: "SF Pro Display", -apple-system, "DIN Alternate", "PingFang SC", sans-serif;
/* 字号阶梯 —— 正文 16.00px(16px) 起,元信息下限 12.00px(12px) */
--font-size-micro: 11.00px; /* 11px 仅角标/装饰,禁用于正文 */
--font-size-xs: 12.00px; /* 12px 元信息下限 */
--font-size-sm: 13.00px; /* 13px 次要说明 */
--font-size-md: 14.00px; /* 14px 次要正文 */
--font-size-base: 16.00px; /* 16px 正文 */
--font-size-lg: 18.00px; /* 18px 小标题 */
--font-size-xl: 20.00px; /* 20px 区块标题 */
--font-size-2xl: 24.00px; /* 24px 页面标题 */
--font-size-3xl: 28.00px; /* 28px 大标题 */
--font-size-display: 32.00px; /* 32px Hero */
/* 字重:只用 4 档。禁止 550/650/750 等非百位值 —— Android 无对应字重会回退,
导致同一设计在不同机型上粗细不一致(审计发现 30 处)。 */
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.65;
--letter-spacing-tight: 0;
--letter-spacing-wide: 0.50px;
--letter-spacing-wider: 1.00px;
/* ============ 间距(4px 栅格) ============ */
--spacing-1: 4.00px;
--spacing-2: 8.00px;
--spacing-3: 12.00px;
--spacing-4: 16.00px;
--spacing-5: 20.00px;
--spacing-6: 24.00px;
--spacing-8: 32.00px;
--spacing-10: 40.00px;
--spacing-12: 48.00px;
--spacing-page-x: 16.00px;
--spacing-section: 24.00px;
--spacing-card-inner: 16.00px;
--spacing-tight: 8.00px;
/* ============ 圆角 ============ */
--radius-sm: 8.00px;
--radius-md: 12.00px;
--radius-lg: 16.00px;
--radius-xl: 20.00px;
--radius-2xl: 24.00px;
--radius-full: 4999.50px;
/* ============ 阴影(统一为一套,此前 30+ 种近似值) ============ */
--shadow-card: 0 4.00px 14.00px rgba(35, 35, 95, 0.07);
--shadow-raised: 0 6.00px 18.00px rgba(35, 35, 95, 0.10);
--shadow-popup: 0 8.00px 32.00px rgba(0, 0, 0, 0.10);
--shadow-night: 0 8.00px 20.00px rgba(28, 30, 88, 0.18);
/* ============ 边框宽度 ============ */
--border-width: 0.50px;
--border-width-strong: 1.00px;
/* ============ 触摸目标(无障碍下限 44×44px) ============ */
--tap-min: 44.00px; /* 44px 最小可点区域 */
--tap-comfortable: 48.00px; /* 48px 舒适尺寸:主操作 */
--tap-gap: 8.00px; /* 8px 相邻目标最小间距 */
/* ============ 动效 ============ */
--motion-fast: 120ms;
--motion-normal: 200ms;
--motion-slow: 300ms;
--ease-standard: cubic-bezier(0.32, 0.72, 0, 1);
--ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
--press-scale: 0.97;
--press-opacity: 0.88;
/* ============ 层级 z-index ============ */
--z-base: 1;
--z-sticky: 100;
--z-tabbar: 200;
--z-dropdown: 500;
--z-modal: 1000;
--z-toast: 2000;
--z-ambient: 0;
/* ============ 页面基础样式 ============ */
background-color: var(--color-bg-page);
font-family: var(--font-family-cn);
font-size: var(--font-size-base);
color: var(--color-text-primary);
line-height: var(--line-height-normal);
}
/* ==========================================================================
通用工具类
========================================================================== */
.container {
padding: var(--spacing-page-x);
}
.flex { display: flex; }
.flex-column { display: flex; flex-direction: column; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-start { display: flex; align-items: center; justify-content: flex-start; }
.flex-1 { flex: 1; min-width: 0; }
.flex-shrink-0 { flex-shrink: 0; }
.wrap { flex-wrap: wrap; }
/* 4 列宫格:用 flex + 百分比宽度实现。
注:display:grid 在 WebView 渲染下可用,但 Skyline 不支持,故统一改为 flex 以免疫渲染引擎迁移。*/
.grid-4 {
display: flex;
flex-wrap: wrap;
}
.grid-4 > .grid-item {
width: 25%;
box-sizing: border-box;
}
.text-strong { color: var(--color-text-strong); }
.text-primary { color: var(--color-text-primary); }
.text-secondary { color: var(--color-text-secondary); }
.text-tertiary { color: var(--color-text-tertiary); }
.text-placeholder { color: var(--color-text-placeholder); }
.text-white { color: var(--color-text-inverse); }
.text-brand { color: var(--color-primary-strong); }
/* 品牌色作文字只能用 -strong 变体:基础色 #E96B6B 在白底仅 3.10:1。
保留 .text-brand-soft 这个类名是为了不破坏既有引用,取值已统一到 -strong,
如需「更亮的品牌色」请用于背景/图形而非文字。 */
.text-brand-soft { color: var(--color-primary-strong); }
.text-success { color: var(--color-success-strong); }
.text-warning { color: var(--color-warning-strong); }
.text-danger { color: var(--color-danger-strong); }
.text-info { color: var(--color-info-strong); }
.font-micro { font-size: var(--font-size-micro); }
.font-xs { font-size: var(--font-size-xs); }
.font-sm { font-size: var(--font-size-sm); }
.font-md { font-size: var(--font-size-md); }
.font-base { font-size: var(--font-size-base); }
.font-lg { font-size: var(--font-size-lg); }
.font-xl { font-size: var(--font-size-xl); }
.font-2xl { font-size: var(--font-size-2xl); }
.font-3xl { font-size: var(--font-size-3xl); }
.font-display { font-size: var(--font-size-display); }
.font-regular { font-weight: var(--font-weight-regular); }
.font-medium { font-weight: var(--font-weight-medium); }
.font-semibold { font-weight: var(--font-weight-semibold); }
.font-bold { font-weight: var(--font-weight-bold); }
.mt-1 { margin-top: var(--spacing-1); }
.mt-2 { margin-top: var(--spacing-2); }
.mt-3 { margin-top: var(--spacing-3); }
.mt-4 { margin-top: var(--spacing-4); }
.mt-5 { margin-top: var(--spacing-5); }
.mt-6 { margin-top: var(--spacing-6); }
.mb-1 { margin-bottom: var(--spacing-1); }
.mb-2 { margin-bottom: var(--spacing-2); }
.mb-3 { margin-bottom: var(--spacing-3); }
.mb-4 { margin-bottom: var(--spacing-4); }
.mb-5 { margin-bottom: var(--spacing-5); }
.mb-6 { margin-bottom: var(--spacing-6); }
/* 文本省略 */
.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ellipsis-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
/* 安全区底部留白(避开 Home Indicator) */
.safe-area-bottom {
padding-bottom: 0px;
}
/* 页面卡片基础样式 */
.card-base {
background: var(--color-bg-card);
border-radius: var(--radius-lg);
padding: var(--spacing-card-inner);
box-shadow: var(--shadow-card);
}
/* 分割线 */
.divider {
height: var(--border-width);
background: var(--color-divider);
}
/* ==========================================================================
可访问性:只用 token,不用工具类(2026-09-23 修订)
--------------------------------------------------------------------------
v2 曾在此处新增 .tap-min / .tap-gap / .focusable / .pressable 四个工具类。
复检发现全部零引用(等价能力已各自写在组件样式内,例如 button/index.wxss
直接使用 min-height:var(--tap-min)),且存在两个硬问题:
1) `.tap-gap > * + *` 用了通配符与兄弟选择器 —— WXSS 不支持,
wcc 编译期直接报 `error at token '*'`,导致整个小程序编译失败。
(这是编译错误,不是静默失效,代价最高。)
2) `.pressable:active` / `.focusable:focus-visible` 的伪类在 view 上
不生效(小程序须用 hover-class),属于"写了等于没写"。
故整块移除,保留 token。需要热区/间距时直接引用 token:
min-height: var(--tap-min); → 44.00px = 44px,最小可点区域
gap: var(--tap-gap); → 8.00px = 8px,相邻目标间距(flex gap)
【WXSS 禁用清单】星号通配符、兄弟选择器、属性选择器。
【注释约束】WXSS 注释**不可嵌套**:内层注释的结束标记会提前终止外层注释,
其后的文字会被当成真实样式解析,导致编译失败或样式被污染。
(2026-09-23 实证:本块注释初版即踩此坑。)
========================================================================== */
.wx-page{background:var(--color-bg-page)}.service-page{min-height:100vh;padding-bottom:calc(70.00px + 0px)}.hero{padding:22.00px 16.00px 27.00px;background:linear-gradient(140deg,var(--color-primary-lighter),var(--color-warning-light));position:relative;overflow:hidden}.eyebrow{display:inline-flex;padding:3.50px 7.00px;border-radius:499.50px;background:rgba(255,255,255,.72);color:var(--color-primary-strong);font-size:12.00px}.hero-title{display:block;margin-top:9.00px;font-size:20.00px;font-weight:700;line-height:1.35}.hero-desc{display:block;width:82%;margin-top:7.00px;font-size:12.50px;color:var(--color-text-secondary);line-height:1.7}.content{padding:0 var(--spacing-page-x)}.block{margin-top:var(--spacing-section)}.block-title{display:block;font-size:15.50px;font-weight:600}.block-subtitle{display:block;margin-top:4.00px;font-size:12.00px;color:var(--color-text-tertiary)}.card{margin-top:9.00px;padding:14.00px;background:var(--color-bg-card);border:0.50px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-card)}.feature-row,.menu-row,.record-row{display:flex;align-items:center;gap:10.00px;min-height:56.00px;padding:9.00px 0;border-bottom:0.50px solid var(--color-divider)}.feature-row:last-child,.menu-row:last-child,.record-row:last-child{border-bottom:0}.feature-icon{width:36.00px;height:36.00px;display:flex;align-items:center;justify-content:center;flex:none;border-radius:11.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-weight:700}.feature-copy{flex:1;min-width:0}.feature-title{display:block;font-size:14.00px;font-weight:600}.feature-desc,.meta{display:block;margin-top:3.50px;font-size:12.00px;color:var(--color-text-tertiary);line-height:1.55}.arrow{font-size:20.00px;color:var(--color-text-disabled)}.tag{display:inline-flex;margin-right:5.00px;margin-top:5.00px;padding:3.00px 6.50px;border-radius:499.50px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px}.tag.warning{background:var(--color-warning-light);color:var(--color-warning-strong)}.primary-btn,.secondary-btn{height:44.00px;display:flex;align-items:center;justify-content:center;border-radius:22.00px;font-size:14.00px;font-weight:600}.primary-btn{background:var(--gradient-brand-solid);color:var(--color-text-inverse);box-shadow:0 5.00px 12.00px rgba(255,92,130,.22)}.primary-btn.disabled{background:var(--color-bg-muted);color:var(--color-text-tertiary);box-shadow:none}.secondary-btn{background:var(--color-primary-light);color:var(--color-primary-strong)}.fixed-action{position:fixed;left:0;right:0;bottom:0;padding:9.00px var(--spacing-page-x) calc(9.00px + 0px);background:rgba(255,255,255,.96);border-top:0.50px solid var(--color-divider);z-index:100}.field{margin-top:13.00px}.label{display:block;margin-bottom:6.00px;font-size:12.50px;font-weight:600}.input,.select-box,.textarea{width:100%;box-sizing:border-box;background:var(--color-bg-page);border:0.50px solid var(--color-border);border-radius:var(--radius-md);font-size:13.00px}.input,.select-box{height:44.00px;padding:0 12.00px;display:flex;align-items:center}.textarea{min-height:90.00px;padding:11.00px}.notice{margin-top:10.00px;padding:11.00px;border-radius:var(--radius-md);background:var(--color-info-light);color:var(--color-text-secondary);font-size:12.00px;line-height:1.65}.select-box.is-readonly{background:var(--color-bg-subtle);color:var(--color-text-secondary)}.empty-panel{text-align:center;padding:35.00px 15.00px}.empty-symbol{width:48.00px;height:48.00px;margin:auto;display:flex;align-items:center;justify-content:center;border-radius:15.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-size:18.00px;font-weight:700}.empty-title{display:block;margin-top:11.00px;font-size:15.00px;font-weight:600}.article-card{margin-top:9.00px;background:var(--color-bg-card);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-card)}.article-cover{height:110.00px;padding:12.00px;background:linear-gradient(135deg,var(--color-warning-light),var(--color-warning-light));display:flex;align-items:flex-end}.article-cover text{font-size:21.00px;color:rgba(125,76,63,.52);font-weight:700}.article-body{padding:12.00px}.article-title{display:block;font-size:14.50px;font-weight:600;line-height:1.45}.article-meta{display:block;margin-top:5.00px;font-size:12.00px;color:var(--color-text-tertiary)}.article-content{padding:16.00px;background:var(--color-bg-card);font-size:14.00px;line-height:1.9;color:var(--color-text-secondary)}.article-content .lead{display:block;font-size:15.50px;color:var(--color-text-primary);font-weight:600;margin-bottom:12.00px}.danger-card{background:var(--color-primary-lighter);border-color:var(--color-primary-light)}.danger-card .feature-icon{background:var(--color-warning-light);color:var(--color-warning-strong)}@media(max-width:340px){.hero-title{font-size:18.00px}.hero-desc{width:92%}}
.service-shell{min-height:100vh;padding-bottom:calc(68.00px + 0px);background:var(--color-bg-page)}.service-content{padding:4.00px 12.00px 18.00px}.service-status{display:flex;align-items:center;justify-content:space-between;margin-top:12.00px;padding:10.00px 12.00px;border-radius:11.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-status__label{color:var(--color-text-tertiary);font-size:12.00px}.service-status__value{padding:3.00px 7.00px;border-radius:9.00px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px;font-weight:600}.service-status__value.disabled{background:var(--color-danger-light);color:var(--color-danger-strong)}.service-topics{display:grid;grid-template-columns:repeat(2,1fr);gap:8.00px;margin-top:9.00px}.service-topic{min-height:74.00px;padding:10.00px;border-radius:12.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-topic__icon{display:flex;align-items:center;justify-content:center;width:27.00px;height:27.00px;border-radius:8.50px;background:var(--color-primary-light)}.service-topic__icon image{width:17.00px;height:17.00px}.service-topic__title{display:block;margin-top:6.50px;color:var(--color-text-strong);font-size:12.00px;font-weight:600}.service-topic__desc{display:block;margin-top:3.00px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}.service-actions{display:flex;gap:7.00px}.service-actions .secondary-btn{width:95.00px;flex:none}.service-actions .primary-btn{flex:1}.privacy-note{display:flex;align-items:flex-start;gap:7.00px;margin-top:11.00px;padding:10.00px;border-radius:11.00px;background:var(--color-info-light);color:var(--color-text-tertiary);font-size:12.00px;line-height:1.55}.privacy-note image{width:17.00px;height:17.00px;flex:none}
/* ==== miniapp/components/conversation-item ==== */
.ui-conv {
display:flex;
align-items:center;
background:var(--color-bg-card);
padding:9.00px 10.00px;
border-bottom:0.50px solid var(--color-divider);
}
.ui-conv--disabled {
opacity:0.6;
}
.ui-conv__body {
flex:1;
min-width:0;
margin-left:var(--spacing-3);
}
.ui-conv__top {
display:flex;
justify-content:space-between;
align-items:baseline;
}
.ui-conv__name {
color:var(--color-text-strong);
font-size:13.00px;
font-weight:600;
}
.ui-conv__time {
color:var(--color-text-tertiary);
font-size:12.00px;
flex-shrink:0;
margin-left:var(--spacing-2);
}
.ui-conv__bottom {
display:flex;
justify-content:space-between;
align-items:center;
margin-top:var(--spacing-1);
}
.ui-conv__last {
flex:1;
min-width:0;
color:var(--color-text-tertiary);
font-size:12.00px;
overflow:hidden;
white-space:nowrap;
text-overflow:ellipsis;
margin-right:var(--spacing-2);
}
.ui-conv__badge {
min-width:18.00px;
height:18.00px;
padding:0 5.00px;
border-radius:var(--radius-full);
background:var(--color-danger);
color:var(--color-text-inverse);
font-size:var(--font-size-xs);
display:flex;
align-items:center;
justify-content:center;
line-height:1;
flex-shrink:0;
}
.ui-conv__status-hint {
margin-top:var(--spacing-1);
font-size:var(--font-size-xs);
color:var(--color-text-tertiary);
}
/* ==== miniapp/components/empty ==== */
.ui-empty {
display:flex;
flex-direction:column;
align-items:center;
padding:var(--spacing-10) var(--spacing-page-x);
text-align:center;
}
.ui-empty__illustration {
width:80.00px;
height:80.00px;
border-radius:50%;
background:var(--color-bg-disabled);
display:flex;
align-items:center;
justify-content:center;
margin-bottom:var(--spacing-4);
}
.ui-empty__icon {
width:36.00px;
height:36.00px;
opacity:0.72;
}
.ui-empty__title {
font-size:var(--font-size-lg);
font-weight:var(--font-weight-medium);
color:var(--color-text-primary);
margin-bottom:var(--spacing-2);
}
.ui-empty__desc {
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
line-height:var(--line-height-relaxed);
max-width:240.00px;
}
.ui-empty__actions {
display:flex;
flex-direction:column;
gap:var(--spacing-2);
margin-top:var(--spacing-6);
width:100%;
max-width:240.00px;
}
.ui-empty__action {
display:flex;
align-items:center;
justify-content:center;
min-height:var(--tap-min);
border-radius:var(--radius-full);
font-size:var(--font-size-base);
font-weight:var(--font-weight-medium);
min-width:var(--tap-min);}
.ui-empty__action--primary {
background:var(--color-primary-solid);
color:var(--color-text-inverse);
}
.ui-empty__action--secondary {
background:var(--color-bg-card);
color:var(--color-primary-strong);
border:0.50px solid var(--color-primary);
}
/* ==== miniapp/components/loading ==== */
.ui-loading--block {
display:flex;
flex-direction:column;
align-items:center;
justify-content:center;
padding:var(--spacing-8) var(--spacing-page-x);
}
.ui-loading--inline {
display:inline-flex;
align-items:center;
}
.ui-loading__spinner {
width:30.00px;
height:30.00px;
display:flex;
align-items:center;
justify-content:center;
}
.ui-loading__spinner-icon {
width:24.00px;
height:24.00px;
animation:ui-loading-spin 0.8s linear infinite;
}
@keyframes ui-loading-spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
.ui-loading__text {
margin-top:var(--spacing-3);
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
}
/* Skeleton */
.ui-loading__skeleton {
width:100%;
}
.ui-loading__skeleton-row {
display:flex;
align-items:center;
padding:var(--spacing-3) var(--spacing-page-x);
background:var(--color-bg-card);
border-bottom:0.50px solid var(--color-divider);
}
.ui-loading__skeleton-avatar {
width:44.00px;
height:44.00px;
border-radius:50%;
background:var(--color-bg-disabled);
margin-right:var(--spacing-3);
flex-shrink:0;
}
.ui-loading__skeleton-content {
flex:1;
min-width:0;
}
.ui-loading__skeleton-line {
height:12.00px;
background:var(--color-bg-disabled);
border-radius:var(--radius-sm);
position:relative;
overflow:hidden;
}
.ui-loading__skeleton-line--title {
width:40%;
margin-bottom:var(--spacing-2);
}
.ui-loading__skeleton-line--meta {
width:70%;
}
/* shimmer */
.ui-loading__skeleton-line::after,
.ui-loading__skeleton-avatar::after {
content:'';
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background:linear-gradient(
90deg,
transparent 0%,
rgba(255, 255, 255, 0.55) 50%,
transparent 100%
);
animation:ui-loading-shimmer 1.4s ease-in-out infinite;
}
@keyframes ui-loading-shimmer {
0% { transform:translateX(-100%); }
100% { transform:translateX(100%); }
}
/* ==== miniapp/components/section-header ==== */
/**
* 区块标题(全站所有页面共用,是排版层级的关键一环)
*
* 2026-09-22 修订:
* 1) 层级拉开:标题 18.00px→20.00px(--font-size-xl),与正文 16.00px / 卡片标题 14.00px
* 形成「区块标题 > 卡片标题 > 正文 > 元信息」四级阶梯。
* 旧值 18.00px 与卡片标题仅差 5.00px,层级读不出来。
* 2) 右侧 action 是全站最容易被忽略的触摸目标:只有 13.00px 文字高(约 13px),
* 远低于 44px 下限。改为 min-height:--tap-min,热区向上补白。
* 3) action 文字色原为 --color-primary(#E96B6B)=3.10:1,不达标,改 -strong。
*/
.ui-section {
display:flex;
align-items:center;
justify-content:space-between;
padding:var(--spacing-2) var(--spacing-page-x);
}
.ui-section__left {
display:flex;
align-items:baseline;
min-width:0;
}
.ui-section__title {
font-size:var(--font-size-xl);
font-weight:var(--font-weight-semibold);
color:var(--color-text-strong);
letter-spacing:var(--letter-spacing-tight);
}
.ui-section__subtitle {
margin-left:var(--spacing-2);
font-size:var(--font-size-xs);
color:var(--color-text-tertiary);
}
.ui-section__action {
display:flex;
align-items:center;
flex:none;
min-height:var(--tap-min);
padding-left:var(--spacing-3);
font-size:var(--font-size-sm);
font-weight:var(--font-weight-medium);
color:var(--color-primary-strong);
transition:opacity var(--motion-fast) var(--ease-standard);
}
.ui-section__action:active {
opacity:var(--press-opacity);
}
.ui-section__arrow {
margin-left:2.00px;
width:12.00px;
height:12.00px;
}
.page {
min-height:100vh;
background:var(--color-bg-page);
}
/* --nav-status / --nav-h / --nav-right 由 messages.ts 经 utils/nav-metrics 实测胶囊按钮后注入 */
.messages-hero {
padding:var(--nav-status, 44px) 12.00px 17.00px;
border-radius:0 0 18.00px 18.00px;
background:linear-gradient(160deg, var(--mini-night-start), var(--mini-night-end));
box-shadow:var(--mini-shadow);
}
.messages-nav {
position:relative;
display:flex;
align-items:center;
justify-content:center;
height:var(--nav-h, 40.00px);
}
.messages-title {
color:var(--color-text-inverse);
font-size:15.50px;
font-weight:700;
}
/* 胶囊安全区:右对齐图标必须整体左移到胶囊左侧,否则被胶囊盖住点不到 */
.messages-search {
position:absolute;
right:var(--nav-right, 102px);
width:17.00px;
height:17.00px;
}
.message-shortcuts {
display:grid;
grid-template-columns:repeat(4, 1fr);
padding:11.00px 4.00px 2.00px;
}
.message-shortcut {
display:flex;
flex-direction:column;
align-items:center;
color:rgba(255, 255, 255, .88);
font-size:12.00px;
}
.shortcut-icon {
display:flex;
align-items:center;
justify-content:center;
width:36.00px;
height:36.00px;
margin-bottom:6.00px;
border:0.50px solid rgba(255, 255, 255, .2);
border-radius:13.00px;
}
.shortcut-icon image {
width:22.50px;
height:22.50px;
}
.shortcut-icon--blue { background:rgba(79, 139, 255, .28); }
.shortcut-icon--pink { background:rgba(255, 92, 130, .28); }
.shortcut-icon--purple { background:rgba(154, 107, 255, .28); }
.shortcut-icon--coral { background:rgba(240, 106, 100, .28); }
.messages-content {
padding:8.00px 12.00px 20.00px;
}
.conversation-list {
overflow:hidden;
margin-top:4.00px;
border-radius:14.00px;
background:var(--color-bg-card);
box-shadow:0 5.00px 16.00px rgba(34, 35, 91, .08);
}
/**
* 丹阳公益婚恋服务平台 - 全局 Design Token
*
* v2(2026-09-22 设计系统夯实)
* ---------------------------------------------------------------
* 本次修订针对审计发现的系统性问题,逐条给出依据:
*
* 1) 品牌色不能承载文字 → 引入「基础色 / -strong」分级
* #E96B6B on 白 = 3.10:1,白字 on #E96B6B = 3.10:1,on #FFF3F2 = 2.85:1,
* 三条路径都不满足正文 4.5:1。故:
* --color-primary 仅用于大色块、渐变、光晕、装饰(非文字)
* --color-primary-strong 用于文字、小图标、纯文字链接(5.33:1 ✓)
* --color-primary-solid 实心按钮底(白字 ≥4.5:1 ✓)
* 功能色(success/warning/danger/info)同此分级。
*
* 2) 次要文字对比度过低
* 旧 --color-text-tertiary(#777) = 4.48(on 白,勉强)/ #999 实测 2.85 却被用了 71 次。
* 现将三级文字压到 #646C85 = 5.22:1,占位符保留浅色(占位符非正文)。
*
* 3) 颜色碎片化
* 审计前全站 182 种 hex、770 次硬编码(54 种灰、60 种蓝紫、40 种红橙)。
* 本文件是唯一的颜色事实源;页面层禁止再写 hex,一律 var(--token)。
*
* 4) 触摸目标
* 组件库默认按钮只有 40px、小号 28px、"喜欢"按钮 31px。
* 统一以 --tap-min(44.00px=44px) 为下限,--tap-gap 为最小间距。
*
* 5) 动效几乎未落地(--motion-* 全站仅 5 次引用)
* 补充 --ease-spring 与 --press-scale,让点击有即时反馈。
*
* 6) 夜间氛围层缺失(参考图有明显的光晕/星点,代码只有纯渐变)
* 新增 --mini-glow-* / --mini-star / --mini-glass / --mini-hairline。
*
* 单位说明:rpx(375.00px = 屏幕宽度,0.50px ≈ 0.5px @375pt)
* 旧 token 名全部保留(88 个 wxss 共 909 处引用),只更新取值,避免大范围失效。
*/
.wx-page {
/* ============ 品牌主色(分级:色块 / 文字 / 实心按钮) ============ */
--color-primary: #E96B6B; /* 基础色:渐变、光晕、装饰、非文字图形 */
--color-primary-strong: #B8434A; /* 文字与小图标(5.33:1 on 白,4.91:1 on 浅粉底) */
--color-primary-solid: #C24C50; /* 实心按钮底(白字 4.62:1) */
--color-primary-active: #D95F5F; /* 按压态(配合 --color-primary 使用) */
--color-primary-light: #FFF3F2;
--color-primary-lighter: #FFF8F7;
/* ============ 小程序参考图品牌主题(夜间紫蓝) ============ */
--mini-night-start: #172A72;
--mini-night-end: #25104F;
--mini-night-soft: #3445A1;
--mini-accent-pink: #FF4F91; /* 点缀色:仅用于色块/装饰,不作正文 */
--mini-accent-coral: #FF6A78;
--mini-card-bg: rgba(255, 255, 255, 0.98);
--mini-text: #1F2744;
--mini-muted: #7D839B;
--mini-card-radius: 12.00px;
--mini-text-on-night: #FFFFFF; /* on 深底 13.04:1 ✓ */
--mini-text-on-night-muted: rgba(255, 255, 255, 0.72); /* on 深底 ≈8:1 ✓ */
--mini-shadow: 0 8.00px 20.00px rgba(28, 30, 88, 0.14);
/* ---- 渐变(集中定义:此前 4 个页面各写了一份「橙红渐变」按钮) ---- */
/* --gradient-brand 明亮活泼,但白字仅 2.77:1 —— 只能用于无文字的装饰填充。 */
--gradient-brand: linear-gradient(135deg, #FF6A78 0%, #E96B6B 100%);
/* 承载白字的 CTA 渐变:两端 #C24C50(4.73:1) / #B8434A(5.33:1) 均达标。 */
--gradient-brand-solid: linear-gradient(135deg, #C24C50 0%, #B8434A 100%);
--gradient-night: linear-gradient(160deg, #172A72 0%, #25104F 100%);
--gradient-night-soft: linear-gradient(160deg, #3445A1 0%, #172A72 100%);
/* ---- 首页 4×2 入口宫格图标渐变(参考图 2:高饱和圆角砖 + 白色描画图标) ----
白图标的对比度判据是**非文本图形 3:1**(WCAG 1.4.11)。渐变是斜向的、图标又跨在
两色之间,所以**较亮的一端也必须达标** —— 下表注释给的是 0% 处实算值,100% 更暗只会更高。
色相按业务语义固定(不随 tone 名漂移):找对象/婚前辅导=玫瑰粉系、公益红娘/服务站=暖橙系、
公益活动=紫罗兰、婚恋咨询=蓝、婚恋课堂=紫、婚恋反诈=绿。 */
--gradient-entry-rose: linear-gradient(135deg, #F56287 0%, #F34671 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-orange: linear-gradient(135deg, #F66A06 0%, #D95E06 100%); /* 3.01:1 / 3.78:1 */
--gradient-entry-violet: linear-gradient(135deg, #A380F5 0%, #8F64F2 100%); /* 3.02:1 / 3.98:1 */
--gradient-entry-blue: linear-gradient(135deg, #5195F6 0%, #3484F4 100%); /* 3.01:1 / 3.65:1 */
--gradient-entry-purple: linear-gradient(135deg, #B27BF0 0%, #A260ED 100%); /* 3.01:1 / 3.87:1 */
--gradient-entry-pink: linear-gradient(135deg, #F2619E 0%, #F0458C 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-green: linear-gradient(135deg, #18A979 0%, #148F66 100%); /* 3.00:1 / 4.08:1 */
--gradient-entry-amber: linear-gradient(135deg, #E9740C 0%, #CC650B 100%); /* 3.01:1 / 3.86:1 */
/* 图标砖落影:比 --mini-shadow 更小,避免 4 列宫格里相邻砖块的投影互相压边 */
--mini-entry-shadow: 0 4.00px 9.00px rgba(28, 30, 88, 0.18);
/* ---- 夜间氛围层(v2 新增;参考图有光晕与星点,此前完全没有) ---- */
--mini-glow-coral: rgba(255, 79, 145, 0.40);
--mini-glow-indigo: rgba(94, 124, 255, 0.32);
--mini-glow-soft: rgba(255, 255, 255, 0.10);
--mini-star: rgba(255, 255, 255, 0.70);
--mini-glass: rgba(255, 255, 255, 0.10); /* 深底玻璃面 */
--mini-glass-strong: rgba(255, 255, 255, 0.16);
--mini-hairline: rgba(255, 255, 255, 0.16); /* 深底分隔线 */
--mini-glass-success: rgba(90, 226, 184, 0.16); /* 深底上的成功态玻璃面 */
/* 星点层:多个小径向渐变叠在夜空渐变之上。用 radial-gradient 而非图片,
避免额外请求,也便于随主题换色(index 页脚注:装饰层不承载信息)。 */
--mini-starfield:
radial-gradient(circle at 12% 18%, var(--mini-star) 0, transparent 1.25px),
radial-gradient(circle at 31% 66%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 57% 12%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 79% 52%, var(--mini-star) 0, transparent 1.50px),
radial-gradient(circle at 93% 84%, var(--mini-star) 0, transparent 1.00px);
/* 横幅压暗层:保证任何底图上的白色标题都有足够对比度 */
--mini-banner-scrim: linear-gradient(90deg, rgba(23, 42, 114, 0.84) 0%, rgba(37, 16, 79, 0.40) 56%, rgba(255, 79, 145, 0.12) 100%);
/* ============ 功能色(同样分级) ============ */
--color-success: #2E9B68; /* 色块/图标 */
--color-success-strong: #17805A; /* 文字(4.92:1 ✓) */
--color-success-light: #ECF8F2;
--color-warning: #E59A32; /* 色块/图标(作文字仅 2.33:1) */
--color-warning-strong: #9C5F14; /* 文字(5.17:1 ✓) */
--color-warning-light: #FFF7E9;
--color-danger: #D94A4A; /* 色块/图标 */
--color-danger-strong: #C62828; /* 文字(5.62:1 ✓) */
--color-danger-light: #FFF0F0;
--color-info: #4A7CD4; /* 色块/图标 */
--color-info-strong: #2A5DB0; /* 文字(6.38:1 ✓) */
--color-info-light: #EEF4FF;
/* ============ 强调紫(参考图的标签语言;此前散落成 6 种写法) ============ */
--color-accent-purple: #8B63BC; /* 色块/装饰 */
--color-accent-purple-strong: #7C60BC; /* 文字(5.03:1 ✓) */
--color-accent-purple-light: #F3EEFF;
/* 深色夜空底上的强调色(不可用于浅色底) */
--color-success-on-night: #A6F5D7; /* on #172A72 = 10.35:1 ✓ */
/* ============ 文字色(实测对比度 on 白 / on 页面底) ============ */
--color-text-strong: #1A1F36; /* 标题 16.24 / 14.90 ✓ */
--color-text-primary: #2A3050; /* 正文 12.83 / 11.77 ✓ */
--color-text-secondary: #4A5169; /* 次要正文 7.86 / 7.21 ✓ */
--color-text-tertiary: #646C85; /* 说明文字 5.22 / 4.79 ✓(旧 #777 为 4.48) */
--color-text-placeholder: #9AA1B4; /* 占位符(非正文,可浅) */
--color-text-disabled: #B8BDC9;
--color-text-inverse: #FFFFFF; /* 深色背景上的文字 */
/* ============ 边框与分割线 ============ */
--color-border: #E6E8EF;
--color-border-strong: #D8DBE5;
--color-divider: #EFF0F5;
--color-border-focus: #B8434A; /* 焦点环用 strong,保证 3:1 可见度 */
--color-border-error: #C62828;
/* ============ 背景(避免纯白/纯灰平铺,页面底为暖白) ============ */
--color-bg-page: #F6F5F3;
--color-bg-card: #FFFFFF;
--color-bg-subtle: #F5F6FA; /* 次级区块、内嵌列表 */
--color-bg-muted: #EEF0F6; /* 更弱的填充 */
--color-bg-input: #F7F8FB; /* 表单输入框底(此前被引用但从未定义,导致背景失效) */
--color-bg-disabled: #F3F4F7;
--color-bg-overlay: rgba(0, 0, 0, 0.45);
/* ============ 字体 ============ */
/* 小程序无法可靠加载 Web Font(wx.loadFontFace 依赖 HTTPS 白名单且有闪动风险),
故使用中文系统字栈:iOS 走苹方、Android 走思源/系统黑体。
排版辨识度靠字号阶梯与字重建立,而非依赖字体本身。 */
--font-family-cn: -apple-system, "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
--font-family-number: "SF Pro Display", -apple-system, "DIN Alternate", "PingFang SC", sans-serif;
/* 字号阶梯 —— 正文 16.00px(16px) 起,元信息下限 12.00px(12px) */
--font-size-micro: 11.00px; /* 11px 仅角标/装饰,禁用于正文 */
--font-size-xs: 12.00px; /* 12px 元信息下限 */
--font-size-sm: 13.00px; /* 13px 次要说明 */
--font-size-md: 14.00px; /* 14px 次要正文 */
--font-size-base: 16.00px; /* 16px 正文 */
--font-size-lg: 18.00px; /* 18px 小标题 */
--font-size-xl: 20.00px; /* 20px 区块标题 */
--font-size-2xl: 24.00px; /* 24px 页面标题 */
--font-size-3xl: 28.00px; /* 28px 大标题 */
--font-size-display: 32.00px; /* 32px Hero */
/* 字重:只用 4 档。禁止 550/650/750 等非百位值 —— Android 无对应字重会回退,
导致同一设计在不同机型上粗细不一致(审计发现 30 处)。 */
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.65;
--letter-spacing-tight: 0;
--letter-spacing-wide: 0.50px;
--letter-spacing-wider: 1.00px;
/* ============ 间距(4px 栅格) ============ */
--spacing-1: 4.00px;
--spacing-2: 8.00px;
--spacing-3: 12.00px;
--spacing-4: 16.00px;
--spacing-5: 20.00px;
--spacing-6: 24.00px;
--spacing-8: 32.00px;
--spacing-10: 40.00px;
--spacing-12: 48.00px;
--spacing-page-x: 16.00px;
--spacing-section: 24.00px;
--spacing-card-inner: 16.00px;
--spacing-tight: 8.00px;
/* ============ 圆角 ============ */
--radius-sm: 8.00px;
--radius-md: 12.00px;
--radius-lg: 16.00px;
--radius-xl: 20.00px;
--radius-2xl: 24.00px;
--radius-full: 4999.50px;
/* ============ 阴影(统一为一套,此前 30+ 种近似值) ============ */
--shadow-card: 0 4.00px 14.00px rgba(35, 35, 95, 0.07);
--shadow-raised: 0 6.00px 18.00px rgba(35, 35, 95, 0.10);
--shadow-popup: 0 8.00px 32.00px rgba(0, 0, 0, 0.10);
--shadow-night: 0 8.00px 20.00px rgba(28, 30, 88, 0.18);
/* ============ 边框宽度 ============ */
--border-width: 0.50px;
--border-width-strong: 1.00px;
/* ============ 触摸目标(无障碍下限 44×44px) ============ */
--tap-min: 44.00px; /* 44px 最小可点区域 */
--tap-comfortable: 48.00px; /* 48px 舒适尺寸:主操作 */
--tap-gap: 8.00px; /* 8px 相邻目标最小间距 */
/* ============ 动效 ============ */
--motion-fast: 120ms;
--motion-normal: 200ms;
--motion-slow: 300ms;
--ease-standard: cubic-bezier(0.32, 0.72, 0, 1);
--ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
--press-scale: 0.97;
--press-opacity: 0.88;
/* ============ 层级 z-index ============ */
--z-base: 1;
--z-sticky: 100;
--z-tabbar: 200;
--z-dropdown: 500;
--z-modal: 1000;
--z-toast: 2000;
--z-ambient: 0;
/* ============ 页面基础样式 ============ */
background-color: var(--color-bg-page);
font-family: var(--font-family-cn);
font-size: var(--font-size-base);
color: var(--color-text-primary);
line-height: var(--line-height-normal);
}
/* ==========================================================================
通用工具类
========================================================================== */
.container {
padding: var(--spacing-page-x);
}
.flex { display: flex; }
.flex-column { display: flex; flex-direction: column; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-start { display: flex; align-items: center; justify-content: flex-start; }
.flex-1 { flex: 1; min-width: 0; }
.flex-shrink-0 { flex-shrink: 0; }
.wrap { flex-wrap: wrap; }
/* 4 列宫格:用 flex + 百分比宽度实现。
注:display:grid 在 WebView 渲染下可用,但 Skyline 不支持,故统一改为 flex 以免疫渲染引擎迁移。*/
.grid-4 {
display: flex;
flex-wrap: wrap;
}
.grid-4 > .grid-item {
width: 25%;
box-sizing: border-box;
}
.text-strong { color: var(--color-text-strong); }
.text-primary { color: var(--color-text-primary); }
.text-secondary { color: var(--color-text-secondary); }
.text-tertiary { color: var(--color-text-tertiary); }
.text-placeholder { color: var(--color-text-placeholder); }
.text-white { color: var(--color-text-inverse); }
.text-brand { color: var(--color-primary-strong); }
/* 品牌色作文字只能用 -strong 变体:基础色 #E96B6B 在白底仅 3.10:1。
保留 .text-brand-soft 这个类名是为了不破坏既有引用,取值已统一到 -strong,
如需「更亮的品牌色」请用于背景/图形而非文字。 */
.text-brand-soft { color: var(--color-primary-strong); }
.text-success { color: var(--color-success-strong); }
.text-warning { color: var(--color-warning-strong); }
.text-danger { color: var(--color-danger-strong); }
.text-info { color: var(--color-info-strong); }
.font-micro { font-size: var(--font-size-micro); }
.font-xs { font-size: var(--font-size-xs); }
.font-sm { font-size: var(--font-size-sm); }
.font-md { font-size: var(--font-size-md); }
.font-base { font-size: var(--font-size-base); }
.font-lg { font-size: var(--font-size-lg); }
.font-xl { font-size: var(--font-size-xl); }
.font-2xl { font-size: var(--font-size-2xl); }
.font-3xl { font-size: var(--font-size-3xl); }
.font-display { font-size: var(--font-size-display); }
.font-regular { font-weight: var(--font-weight-regular); }
.font-medium { font-weight: var(--font-weight-medium); }
.font-semibold { font-weight: var(--font-weight-semibold); }
.font-bold { font-weight: var(--font-weight-bold); }
.mt-1 { margin-top: var(--spacing-1); }
.mt-2 { margin-top: var(--spacing-2); }
.mt-3 { margin-top: var(--spacing-3); }
.mt-4 { margin-top: var(--spacing-4); }
.mt-5 { margin-top: var(--spacing-5); }
.mt-6 { margin-top: var(--spacing-6); }
.mb-1 { margin-bottom: var(--spacing-1); }
.mb-2 { margin-bottom: var(--spacing-2); }
.mb-3 { margin-bottom: var(--spacing-3); }
.mb-4 { margin-bottom: var(--spacing-4); }
.mb-5 { margin-bottom: var(--spacing-5); }
.mb-6 { margin-bottom: var(--spacing-6); }
/* 文本省略 */
.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ellipsis-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
/* 安全区底部留白(避开 Home Indicator) */
.safe-area-bottom {
padding-bottom: 0px;
}
/* 页面卡片基础样式 */
.card-base {
background: var(--color-bg-card);
border-radius: var(--radius-lg);
padding: var(--spacing-card-inner);
box-shadow: var(--shadow-card);
}
/* 分割线 */
.divider {
height: var(--border-width);
background: var(--color-divider);
}
/* ==========================================================================
可访问性:只用 token,不用工具类(2026-09-23 修订)
--------------------------------------------------------------------------
v2 曾在此处新增 .tap-min / .tap-gap / .focusable / .pressable 四个工具类。
复检发现全部零引用(等价能力已各自写在组件样式内,例如 button/index.wxss
直接使用 min-height:var(--tap-min)),且存在两个硬问题:
1) `.tap-gap > * + *` 用了通配符与兄弟选择器 —— WXSS 不支持,
wcc 编译期直接报 `error at token '*'`,导致整个小程序编译失败。
(这是编译错误,不是静默失效,代价最高。)
2) `.pressable:active` / `.focusable:focus-visible` 的伪类在 view 上
不生效(小程序须用 hover-class),属于"写了等于没写"。
故整块移除,保留 token。需要热区/间距时直接引用 token:
min-height: var(--tap-min); → 44.00px = 44px,最小可点区域
gap: var(--tap-gap); → 8.00px = 8px,相邻目标间距(flex gap)
【WXSS 禁用清单】星号通配符、兄弟选择器、属性选择器。
【注释约束】WXSS 注释**不可嵌套**:内层注释的结束标记会提前终止外层注释,
其后的文字会被当成真实样式解析,导致编译失败或样式被污染。
(2026-09-23 实证:本块注释初版即踩此坑。)
========================================================================== */
.wx-page{background:var(--color-bg-page)}.service-page{min-height:100vh;padding-bottom:calc(70.00px + 0px)}.hero{padding:22.00px 16.00px 27.00px;background:linear-gradient(140deg,var(--color-primary-lighter),var(--color-warning-light));position:relative;overflow:hidden}.eyebrow{display:inline-flex;padding:3.50px 7.00px;border-radius:499.50px;background:rgba(255,255,255,.72);color:var(--color-primary-strong);font-size:12.00px}.hero-title{display:block;margin-top:9.00px;font-size:20.00px;font-weight:700;line-height:1.35}.hero-desc{display:block;width:82%;margin-top:7.00px;font-size:12.50px;color:var(--color-text-secondary);line-height:1.7}.content{padding:0 var(--spacing-page-x)}.block{margin-top:var(--spacing-section)}.block-title{display:block;font-size:15.50px;font-weight:600}.block-subtitle{display:block;margin-top:4.00px;font-size:12.00px;color:var(--color-text-tertiary)}.card{margin-top:9.00px;padding:14.00px;background:var(--color-bg-card);border:0.50px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-card)}.feature-row,.menu-row,.record-row{display:flex;align-items:center;gap:10.00px;min-height:56.00px;padding:9.00px 0;border-bottom:0.50px solid var(--color-divider)}.feature-row:last-child,.menu-row:last-child,.record-row:last-child{border-bottom:0}.feature-icon{width:36.00px;height:36.00px;display:flex;align-items:center;justify-content:center;flex:none;border-radius:11.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-weight:700}.feature-copy{flex:1;min-width:0}.feature-title{display:block;font-size:14.00px;font-weight:600}.feature-desc,.meta{display:block;margin-top:3.50px;font-size:12.00px;color:var(--color-text-tertiary);line-height:1.55}.arrow{font-size:20.00px;color:var(--color-text-disabled)}.tag{display:inline-flex;margin-right:5.00px;margin-top:5.00px;padding:3.00px 6.50px;border-radius:499.50px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px}.tag.warning{background:var(--color-warning-light);color:var(--color-warning-strong)}.primary-btn,.secondary-btn{height:44.00px;display:flex;align-items:center;justify-content:center;border-radius:22.00px;font-size:14.00px;font-weight:600}.primary-btn{background:var(--gradient-brand-solid);color:var(--color-text-inverse);box-shadow:0 5.00px 12.00px rgba(255,92,130,.22)}.primary-btn.disabled{background:var(--color-bg-muted);color:var(--color-text-tertiary);box-shadow:none}.secondary-btn{background:var(--color-primary-light);color:var(--color-primary-strong)}.fixed-action{position:fixed;left:0;right:0;bottom:0;padding:9.00px var(--spacing-page-x) calc(9.00px + 0px);background:rgba(255,255,255,.96);border-top:0.50px solid var(--color-divider);z-index:100}.field{margin-top:13.00px}.label{display:block;margin-bottom:6.00px;font-size:12.50px;font-weight:600}.input,.select-box,.textarea{width:100%;box-sizing:border-box;background:var(--color-bg-page);border:0.50px solid var(--color-border);border-radius:var(--radius-md);font-size:13.00px}.input,.select-box{height:44.00px;padding:0 12.00px;display:flex;align-items:center}.textarea{min-height:90.00px;padding:11.00px}.notice{margin-top:10.00px;padding:11.00px;border-radius:var(--radius-md);background:var(--color-info-light);color:var(--color-text-secondary);font-size:12.00px;line-height:1.65}.select-box.is-readonly{background:var(--color-bg-subtle);color:var(--color-text-secondary)}.empty-panel{text-align:center;padding:35.00px 15.00px}.empty-symbol{width:48.00px;height:48.00px;margin:auto;display:flex;align-items:center;justify-content:center;border-radius:15.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-size:18.00px;font-weight:700}.empty-title{display:block;margin-top:11.00px;font-size:15.00px;font-weight:600}.article-card{margin-top:9.00px;background:var(--color-bg-card);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-card)}.article-cover{height:110.00px;padding:12.00px;background:linear-gradient(135deg,var(--color-warning-light),var(--color-warning-light));display:flex;align-items:flex-end}.article-cover text{font-size:21.00px;color:rgba(125,76,63,.52);font-weight:700}.article-body{padding:12.00px}.article-title{display:block;font-size:14.50px;font-weight:600;line-height:1.45}.article-meta{display:block;margin-top:5.00px;font-size:12.00px;color:var(--color-text-tertiary)}.article-content{padding:16.00px;background:var(--color-bg-card);font-size:14.00px;line-height:1.9;color:var(--color-text-secondary)}.article-content .lead{display:block;font-size:15.50px;color:var(--color-text-primary);font-weight:600;margin-bottom:12.00px}.danger-card{background:var(--color-primary-lighter);border-color:var(--color-primary-light)}.danger-card .feature-icon{background:var(--color-warning-light);color:var(--color-warning-strong)}@media(max-width:340px){.hero-title{font-size:18.00px}.hero-desc{width:92%}}
.service-shell{min-height:100vh;padding-bottom:calc(68.00px + 0px);background:var(--color-bg-page)}.service-content{padding:4.00px 12.00px 18.00px}.service-status{display:flex;align-items:center;justify-content:space-between;margin-top:12.00px;padding:10.00px 12.00px;border-radius:11.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-status__label{color:var(--color-text-tertiary);font-size:12.00px}.service-status__value{padding:3.00px 7.00px;border-radius:9.00px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px;font-weight:600}.service-status__value.disabled{background:var(--color-danger-light);color:var(--color-danger-strong)}.service-topics{display:grid;grid-template-columns:repeat(2,1fr);gap:8.00px;margin-top:9.00px}.service-topic{min-height:74.00px;padding:10.00px;border-radius:12.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-topic__icon{display:flex;align-items:center;justify-content:center;width:27.00px;height:27.00px;border-radius:8.50px;background:var(--color-primary-light)}.service-topic__icon image{width:17.00px;height:17.00px}.service-topic__title{display:block;margin-top:6.50px;color:var(--color-text-strong);font-size:12.00px;font-weight:600}.service-topic__desc{display:block;margin-top:3.00px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}.service-actions{display:flex;gap:7.00px}.service-actions .secondary-btn{width:95.00px;flex:none}.service-actions .primary-btn{flex:1}.privacy-note{display:flex;align-items:flex-start;gap:7.00px;margin-top:11.00px;padding:10.00px;border-radius:11.00px;background:var(--color-info-light);color:var(--color-text-tertiary);font-size:12.00px;line-height:1.55}.privacy-note image{width:17.00px;height:17.00px;flex:none}
/* ==== miniapp/components/section-header ==== */
/**
* 区块标题(全站所有页面共用,是排版层级的关键一环)
*
* 2026-09-22 修订:
* 1) 层级拉开:标题 18.00px→20.00px(--font-size-xl),与正文 16.00px / 卡片标题 14.00px
* 形成「区块标题 > 卡片标题 > 正文 > 元信息」四级阶梯。
* 旧值 18.00px 与卡片标题仅差 5.00px,层级读不出来。
* 2) 右侧 action 是全站最容易被忽略的触摸目标:只有 13.00px 文字高(约 13px),
* 远低于 44px 下限。改为 min-height:--tap-min,热区向上补白。
* 3) action 文字色原为 --color-primary(#E96B6B)=3.10:1,不达标,改 -strong。
*/
.ui-section {
display:flex;
align-items:center;
justify-content:space-between;
padding:var(--spacing-2) var(--spacing-page-x);
}
.ui-section__left {
display:flex;
align-items:baseline;
min-width:0;
}
.ui-section__title {
font-size:var(--font-size-xl);
font-weight:var(--font-weight-semibold);
color:var(--color-text-strong);
letter-spacing:var(--letter-spacing-tight);
}
.ui-section__subtitle {
margin-left:var(--spacing-2);
font-size:var(--font-size-xs);
color:var(--color-text-tertiary);
}
.ui-section__action {
display:flex;
align-items:center;
flex:none;
min-height:var(--tap-min);
padding-left:var(--spacing-3);
font-size:var(--font-size-sm);
font-weight:var(--font-weight-medium);
color:var(--color-primary-strong);
transition:opacity var(--motion-fast) var(--ease-standard);
}
.ui-section__action:active {
opacity:var(--press-opacity);
}
.ui-section__arrow {
margin-left:2.00px;
width:12.00px;
height:12.00px;
}
/* ==== miniapp/components/activity-card ==== */
.ui-act{overflow:hidden;border-radius:14.00px;background:var(--color-bg-card);box-shadow:0 5.00px 16.00px rgba(34,35,91,.08)}.ui-act__cover{position:relative;width:100%;height:120.00px;background:var(--color-bg-subtle)}.ui-act__cover-img{display:block;width:100%;height:100%}.ui-act__fee-badge{position:absolute;top:9.00px;right:9.00px;padding:3.50px 7.50px;border-radius:11.00px;background:var(--gradient-brand-solid);color:var(--color-text-inverse);font-size:9.00px;font-weight:600}.ui-act__body{padding:11.00px 12.00px}.ui-act__title{overflow:hidden;color:var(--color-text-strong);font-size:14.00px;font-weight:700;line-height:1.35;white-space:nowrap;text-overflow:ellipsis}.ui-act__meta{margin-top:3.50px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}.ui-act__intro{display:-webkit-box;overflow:hidden;margin-top:6.00px;color:var(--color-text-secondary);font-size:12.00px;line-height:1.55;-webkit-box-orient:vertical;-webkit-line-clamp:2}.ui-act__footer{display:flex;align-items:center;justify-content:space-between;margin-top:9.00px}.ui-act__capacity{color:var(--color-text-tertiary);font-size:12.00px}.ui-act__status-action{min-width:63.00px;min-height:var(--tap-min);display:flex;align-items:center;justify-content:center;border-radius:14.00px;background:var(--gradient-brand-solid);color:var(--color-text-inverse);font-size:12.00px;font-weight:600}.ui-act__status-action.disabled{background:var(--color-bg-subtle);color:var(--color-text-tertiary)}.ui-act--compact{display:flex;height:100.00px}.ui-act--compact .ui-act__cover{width:100.00px;height:100.00px;flex-shrink:0}.ui-act--compact .ui-act__body{flex:1;min-width:0;padding:8.00px 9.00px}.ui-act--compact .ui-act__intro{display:none}
.ui-act__type-row{display:flex;align-items:center;margin-top:5.00px;flex-wrap:wrap}.ui-act__type-badge{padding:2.00px 7.00px;border-radius:9.00px;background:var(--color-primary-light);color:var(--color-danger-strong);font-size:9.00px;font-weight:600}.ui-act__eligibility{margin-left:6.00px;color:var(--color-text-tertiary);font-size:12.00px}
/* ==== miniapp/components/loading ==== */
.ui-loading--block {
display:flex;
flex-direction:column;
align-items:center;
justify-content:center;
padding:var(--spacing-8) var(--spacing-page-x);
}
.ui-loading--inline {
display:inline-flex;
align-items:center;
}
.ui-loading__spinner {
width:30.00px;
height:30.00px;
display:flex;
align-items:center;
justify-content:center;
}
.ui-loading__spinner-icon {
width:24.00px;
height:24.00px;
animation:ui-loading-spin 0.8s linear infinite;
}
@keyframes ui-loading-spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
.ui-loading__text {
margin-top:var(--spacing-3);
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
}
/* Skeleton */
.ui-loading__skeleton {
width:100%;
}
.ui-loading__skeleton-row {
display:flex;
align-items:center;
padding:var(--spacing-3) var(--spacing-page-x);
background:var(--color-bg-card);
border-bottom:0.50px solid var(--color-divider);
}
.ui-loading__skeleton-avatar {
width:44.00px;
height:44.00px;
border-radius:50%;
background:var(--color-bg-disabled);
margin-right:var(--spacing-3);
flex-shrink:0;
}
.ui-loading__skeleton-content {
flex:1;
min-width:0;
}
.ui-loading__skeleton-line {
height:12.00px;
background:var(--color-bg-disabled);
border-radius:var(--radius-sm);
position:relative;
overflow:hidden;
}
.ui-loading__skeleton-line--title {
width:40%;
margin-bottom:var(--spacing-2);
}
.ui-loading__skeleton-line--meta {
width:70%;
}
/* shimmer */
.ui-loading__skeleton-line::after,
.ui-loading__skeleton-avatar::after {
content:'';
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background:linear-gradient(
90deg,
transparent 0%,
rgba(255, 255, 255, 0.55) 50%,
transparent 100%
);
animation:ui-loading-shimmer 1.4s ease-in-out infinite;
}
@keyframes ui-loading-shimmer {
0% { transform:translateX(-100%); }
100% { transform:translateX(100%); }
}
/* ==== miniapp/components/empty ==== */
.ui-empty {
display:flex;
flex-direction:column;
align-items:center;
padding:var(--spacing-10) var(--spacing-page-x);
text-align:center;
}
.ui-empty__illustration {
width:80.00px;
height:80.00px;
border-radius:50%;
background:var(--color-bg-disabled);
display:flex;
align-items:center;
justify-content:center;
margin-bottom:var(--spacing-4);
}
.ui-empty__icon {
width:36.00px;
height:36.00px;
opacity:0.72;
}
.ui-empty__title {
font-size:var(--font-size-lg);
font-weight:var(--font-weight-medium);
color:var(--color-text-primary);
margin-bottom:var(--spacing-2);
}
.ui-empty__desc {
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
line-height:var(--line-height-relaxed);
max-width:240.00px;
}
.ui-empty__actions {
display:flex;
flex-direction:column;
gap:var(--spacing-2);
margin-top:var(--spacing-6);
width:100%;
max-width:240.00px;
}
.ui-empty__action {
display:flex;
align-items:center;
justify-content:center;
min-height:var(--tap-min);
border-radius:var(--radius-full);
font-size:var(--font-size-base);
font-weight:var(--font-weight-medium);
min-width:var(--tap-min);}
.ui-empty__action--primary {
background:var(--color-primary-solid);
color:var(--color-text-inverse);
}
.ui-empty__action--secondary {
background:var(--color-bg-card);
color:var(--color-primary-strong);
border:0.50px solid var(--color-primary);
}
/* --nav-status / --nav-h / --nav-right 由 activity.ts 经 utils/nav-metrics 实测胶囊按钮后注入 */
.act-page{min-height:100vh;padding-bottom:20.00px;background:var(--color-bg-page)}.activity-hero{padding:var(--nav-status, 44px) 12.00px 13.00px;border-radius:0 0 18.00px 18.00px;background:linear-gradient(160deg,var(--mini-night-start),var(--mini-night-end));box-shadow:var(--mini-shadow)}.activity-nav{position:relative;display:flex;align-items:center;justify-content:center;height:var(--nav-h, 40.00px)}.activity-title{color:var(--color-text-inverse);font-size:15.50px;font-weight:700}.activity-calendar{position:absolute;right:var(--nav-right, 102px);display:flex;align-items:center;justify-content:center;width:31.00px;height:31.00px;border:0.50px solid rgba(255,255,255,.18);border-radius:15.50px;background:rgba(255,255,255,.1)}.activity-calendar image{width:17.00px;height:17.00px;filter:brightness(0) invert(1)}.activity-categories{white-space:nowrap}.activity-category-row{display:inline-flex;gap:6.00px}.activity-category{padding:5.50px 11.00px;border-radius:12.50px;background:rgba(255,255,255,.1);color:rgba(255,255,255,.72);font-size:12.00px}.activity-category.active{background:var(--color-bg-card);color:var(--color-primary-strong);font-weight:600}.activity-heading{display:flex;align-items:flex-end;justify-content:space-between;padding:16.00px 14.00px 8.00px}.activity-heading>view{display:flex;flex-direction:column}.heading-title{color:var(--color-text-strong);font-size:15.00px;font-weight:700}.heading-subtitle{margin-top:2.50px;color:var(--color-text-tertiary);font-size:12.00px}.my-activity-link{color:var(--color-primary-strong);font-size:12.00px}.act-loading{padding:6.00px 12.00px}.act-list{display:flex;flex-direction:column;gap:10.00px;padding:4.00px 12.00px 0}.act-list__more{display:flex;justify-content:center;padding:12.00px 0}.act-list__end{text-align:center;padding:12.00px 0;color:var(--color-text-tertiary);font-size:12.00px}.act-empty{padding-top:35.00px}
/**
* 丹阳公益婚恋服务平台 - 全局 Design Token
*
* v2(2026-09-22 设计系统夯实)
* ---------------------------------------------------------------
* 本次修订针对审计发现的系统性问题,逐条给出依据:
*
* 1) 品牌色不能承载文字 → 引入「基础色 / -strong」分级
* #E96B6B on 白 = 3.10:1,白字 on #E96B6B = 3.10:1,on #FFF3F2 = 2.85:1,
* 三条路径都不满足正文 4.5:1。故:
* --color-primary 仅用于大色块、渐变、光晕、装饰(非文字)
* --color-primary-strong 用于文字、小图标、纯文字链接(5.33:1 ✓)
* --color-primary-solid 实心按钮底(白字 ≥4.5:1 ✓)
* 功能色(success/warning/danger/info)同此分级。
*
* 2) 次要文字对比度过低
* 旧 --color-text-tertiary(#777) = 4.48(on 白,勉强)/ #999 实测 2.85 却被用了 71 次。
* 现将三级文字压到 #646C85 = 5.22:1,占位符保留浅色(占位符非正文)。
*
* 3) 颜色碎片化
* 审计前全站 182 种 hex、770 次硬编码(54 种灰、60 种蓝紫、40 种红橙)。
* 本文件是唯一的颜色事实源;页面层禁止再写 hex,一律 var(--token)。
*
* 4) 触摸目标
* 组件库默认按钮只有 40px、小号 28px、"喜欢"按钮 31px。
* 统一以 --tap-min(44.00px=44px) 为下限,--tap-gap 为最小间距。
*
* 5) 动效几乎未落地(--motion-* 全站仅 5 次引用)
* 补充 --ease-spring 与 --press-scale,让点击有即时反馈。
*
* 6) 夜间氛围层缺失(参考图有明显的光晕/星点,代码只有纯渐变)
* 新增 --mini-glow-* / --mini-star / --mini-glass / --mini-hairline。
*
* 单位说明:rpx(375.00px = 屏幕宽度,0.50px ≈ 0.5px @375pt)
* 旧 token 名全部保留(88 个 wxss 共 909 处引用),只更新取值,避免大范围失效。
*/
.wx-page {
/* ============ 品牌主色(分级:色块 / 文字 / 实心按钮) ============ */
--color-primary: #E96B6B; /* 基础色:渐变、光晕、装饰、非文字图形 */
--color-primary-strong: #B8434A; /* 文字与小图标(5.33:1 on 白,4.91:1 on 浅粉底) */
--color-primary-solid: #C24C50; /* 实心按钮底(白字 4.62:1) */
--color-primary-active: #D95F5F; /* 按压态(配合 --color-primary 使用) */
--color-primary-light: #FFF3F2;
--color-primary-lighter: #FFF8F7;
/* ============ 小程序参考图品牌主题(夜间紫蓝) ============ */
--mini-night-start: #172A72;
--mini-night-end: #25104F;
--mini-night-soft: #3445A1;
--mini-accent-pink: #FF4F91; /* 点缀色:仅用于色块/装饰,不作正文 */
--mini-accent-coral: #FF6A78;
--mini-card-bg: rgba(255, 255, 255, 0.98);
--mini-text: #1F2744;
--mini-muted: #7D839B;
--mini-card-radius: 12.00px;
--mini-text-on-night: #FFFFFF; /* on 深底 13.04:1 ✓ */
--mini-text-on-night-muted: rgba(255, 255, 255, 0.72); /* on 深底 ≈8:1 ✓ */
--mini-shadow: 0 8.00px 20.00px rgba(28, 30, 88, 0.14);
/* ---- 渐变(集中定义:此前 4 个页面各写了一份「橙红渐变」按钮) ---- */
/* --gradient-brand 明亮活泼,但白字仅 2.77:1 —— 只能用于无文字的装饰填充。 */
--gradient-brand: linear-gradient(135deg, #FF6A78 0%, #E96B6B 100%);
/* 承载白字的 CTA 渐变:两端 #C24C50(4.73:1) / #B8434A(5.33:1) 均达标。 */
--gradient-brand-solid: linear-gradient(135deg, #C24C50 0%, #B8434A 100%);
--gradient-night: linear-gradient(160deg, #172A72 0%, #25104F 100%);
--gradient-night-soft: linear-gradient(160deg, #3445A1 0%, #172A72 100%);
/* ---- 首页 4×2 入口宫格图标渐变(参考图 2:高饱和圆角砖 + 白色描画图标) ----
白图标的对比度判据是**非文本图形 3:1**(WCAG 1.4.11)。渐变是斜向的、图标又跨在
两色之间,所以**较亮的一端也必须达标** —— 下表注释给的是 0% 处实算值,100% 更暗只会更高。
色相按业务语义固定(不随 tone 名漂移):找对象/婚前辅导=玫瑰粉系、公益红娘/服务站=暖橙系、
公益活动=紫罗兰、婚恋咨询=蓝、婚恋课堂=紫、婚恋反诈=绿。 */
--gradient-entry-rose: linear-gradient(135deg, #F56287 0%, #F34671 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-orange: linear-gradient(135deg, #F66A06 0%, #D95E06 100%); /* 3.01:1 / 3.78:1 */
--gradient-entry-violet: linear-gradient(135deg, #A380F5 0%, #8F64F2 100%); /* 3.02:1 / 3.98:1 */
--gradient-entry-blue: linear-gradient(135deg, #5195F6 0%, #3484F4 100%); /* 3.01:1 / 3.65:1 */
--gradient-entry-purple: linear-gradient(135deg, #B27BF0 0%, #A260ED 100%); /* 3.01:1 / 3.87:1 */
--gradient-entry-pink: linear-gradient(135deg, #F2619E 0%, #F0458C 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-green: linear-gradient(135deg, #18A979 0%, #148F66 100%); /* 3.00:1 / 4.08:1 */
--gradient-entry-amber: linear-gradient(135deg, #E9740C 0%, #CC650B 100%); /* 3.01:1 / 3.86:1 */
/* 图标砖落影:比 --mini-shadow 更小,避免 4 列宫格里相邻砖块的投影互相压边 */
--mini-entry-shadow: 0 4.00px 9.00px rgba(28, 30, 88, 0.18);
/* ---- 夜间氛围层(v2 新增;参考图有光晕与星点,此前完全没有) ---- */
--mini-glow-coral: rgba(255, 79, 145, 0.40);
--mini-glow-indigo: rgba(94, 124, 255, 0.32);
--mini-glow-soft: rgba(255, 255, 255, 0.10);
--mini-star: rgba(255, 255, 255, 0.70);
--mini-glass: rgba(255, 255, 255, 0.10); /* 深底玻璃面 */
--mini-glass-strong: rgba(255, 255, 255, 0.16);
--mini-hairline: rgba(255, 255, 255, 0.16); /* 深底分隔线 */
--mini-glass-success: rgba(90, 226, 184, 0.16); /* 深底上的成功态玻璃面 */
/* 星点层:多个小径向渐变叠在夜空渐变之上。用 radial-gradient 而非图片,
避免额外请求,也便于随主题换色(index 页脚注:装饰层不承载信息)。 */
--mini-starfield:
radial-gradient(circle at 12% 18%, var(--mini-star) 0, transparent 1.25px),
radial-gradient(circle at 31% 66%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 57% 12%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 79% 52%, var(--mini-star) 0, transparent 1.50px),
radial-gradient(circle at 93% 84%, var(--mini-star) 0, transparent 1.00px);
/* 横幅压暗层:保证任何底图上的白色标题都有足够对比度 */
--mini-banner-scrim: linear-gradient(90deg, rgba(23, 42, 114, 0.84) 0%, rgba(37, 16, 79, 0.40) 56%, rgba(255, 79, 145, 0.12) 100%);
/* ============ 功能色(同样分级) ============ */
--color-success: #2E9B68; /* 色块/图标 */
--color-success-strong: #17805A; /* 文字(4.92:1 ✓) */
--color-success-light: #ECF8F2;
--color-warning: #E59A32; /* 色块/图标(作文字仅 2.33:1) */
--color-warning-strong: #9C5F14; /* 文字(5.17:1 ✓) */
--color-warning-light: #FFF7E9;
--color-danger: #D94A4A; /* 色块/图标 */
--color-danger-strong: #C62828; /* 文字(5.62:1 ✓) */
--color-danger-light: #FFF0F0;
--color-info: #4A7CD4; /* 色块/图标 */
--color-info-strong: #2A5DB0; /* 文字(6.38:1 ✓) */
--color-info-light: #EEF4FF;
/* ============ 强调紫(参考图的标签语言;此前散落成 6 种写法) ============ */
--color-accent-purple: #8B63BC; /* 色块/装饰 */
--color-accent-purple-strong: #7C60BC; /* 文字(5.03:1 ✓) */
--color-accent-purple-light: #F3EEFF;
/* 深色夜空底上的强调色(不可用于浅色底) */
--color-success-on-night: #A6F5D7; /* on #172A72 = 10.35:1 ✓ */
/* ============ 文字色(实测对比度 on 白 / on 页面底) ============ */
--color-text-strong: #1A1F36; /* 标题 16.24 / 14.90 ✓ */
--color-text-primary: #2A3050; /* 正文 12.83 / 11.77 ✓ */
--color-text-secondary: #4A5169; /* 次要正文 7.86 / 7.21 ✓ */
--color-text-tertiary: #646C85; /* 说明文字 5.22 / 4.79 ✓(旧 #777 为 4.48) */
--color-text-placeholder: #9AA1B4; /* 占位符(非正文,可浅) */
--color-text-disabled: #B8BDC9;
--color-text-inverse: #FFFFFF; /* 深色背景上的文字 */
/* ============ 边框与分割线 ============ */
--color-border: #E6E8EF;
--color-border-strong: #D8DBE5;
--color-divider: #EFF0F5;
--color-border-focus: #B8434A; /* 焦点环用 strong,保证 3:1 可见度 */
--color-border-error: #C62828;
/* ============ 背景(避免纯白/纯灰平铺,页面底为暖白) ============ */
--color-bg-page: #F6F5F3;
--color-bg-card: #FFFFFF;
--color-bg-subtle: #F5F6FA; /* 次级区块、内嵌列表 */
--color-bg-muted: #EEF0F6; /* 更弱的填充 */
--color-bg-input: #F7F8FB; /* 表单输入框底(此前被引用但从未定义,导致背景失效) */
--color-bg-disabled: #F3F4F7;
--color-bg-overlay: rgba(0, 0, 0, 0.45);
/* ============ 字体 ============ */
/* 小程序无法可靠加载 Web Font(wx.loadFontFace 依赖 HTTPS 白名单且有闪动风险),
故使用中文系统字栈:iOS 走苹方、Android 走思源/系统黑体。
排版辨识度靠字号阶梯与字重建立,而非依赖字体本身。 */
--font-family-cn: -apple-system, "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
--font-family-number: "SF Pro Display", -apple-system, "DIN Alternate", "PingFang SC", sans-serif;
/* 字号阶梯 —— 正文 16.00px(16px) 起,元信息下限 12.00px(12px) */
--font-size-micro: 11.00px; /* 11px 仅角标/装饰,禁用于正文 */
--font-size-xs: 12.00px; /* 12px 元信息下限 */
--font-size-sm: 13.00px; /* 13px 次要说明 */
--font-size-md: 14.00px; /* 14px 次要正文 */
--font-size-base: 16.00px; /* 16px 正文 */
--font-size-lg: 18.00px; /* 18px 小标题 */
--font-size-xl: 20.00px; /* 20px 区块标题 */
--font-size-2xl: 24.00px; /* 24px 页面标题 */
--font-size-3xl: 28.00px; /* 28px 大标题 */
--font-size-display: 32.00px; /* 32px Hero */
/* 字重:只用 4 档。禁止 550/650/750 等非百位值 —— Android 无对应字重会回退,
导致同一设计在不同机型上粗细不一致(审计发现 30 处)。 */
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.65;
--letter-spacing-tight: 0;
--letter-spacing-wide: 0.50px;
--letter-spacing-wider: 1.00px;
/* ============ 间距(4px 栅格) ============ */
--spacing-1: 4.00px;
--spacing-2: 8.00px;
--spacing-3: 12.00px;
--spacing-4: 16.00px;
--spacing-5: 20.00px;
--spacing-6: 24.00px;
--spacing-8: 32.00px;
--spacing-10: 40.00px;
--spacing-12: 48.00px;
--spacing-page-x: 16.00px;
--spacing-section: 24.00px;
--spacing-card-inner: 16.00px;
--spacing-tight: 8.00px;
/* ============ 圆角 ============ */
--radius-sm: 8.00px;
--radius-md: 12.00px;
--radius-lg: 16.00px;
--radius-xl: 20.00px;
--radius-2xl: 24.00px;
--radius-full: 4999.50px;
/* ============ 阴影(统一为一套,此前 30+ 种近似值) ============ */
--shadow-card: 0 4.00px 14.00px rgba(35, 35, 95, 0.07);
--shadow-raised: 0 6.00px 18.00px rgba(35, 35, 95, 0.10);
--shadow-popup: 0 8.00px 32.00px rgba(0, 0, 0, 0.10);
--shadow-night: 0 8.00px 20.00px rgba(28, 30, 88, 0.18);
/* ============ 边框宽度 ============ */
--border-width: 0.50px;
--border-width-strong: 1.00px;
/* ============ 触摸目标(无障碍下限 44×44px) ============ */
--tap-min: 44.00px; /* 44px 最小可点区域 */
--tap-comfortable: 48.00px; /* 48px 舒适尺寸:主操作 */
--tap-gap: 8.00px; /* 8px 相邻目标最小间距 */
/* ============ 动效 ============ */
--motion-fast: 120ms;
--motion-normal: 200ms;
--motion-slow: 300ms;
--ease-standard: cubic-bezier(0.32, 0.72, 0, 1);
--ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
--press-scale: 0.97;
--press-opacity: 0.88;
/* ============ 层级 z-index ============ */
--z-base: 1;
--z-sticky: 100;
--z-tabbar: 200;
--z-dropdown: 500;
--z-modal: 1000;
--z-toast: 2000;
--z-ambient: 0;
/* ============ 页面基础样式 ============ */
background-color: var(--color-bg-page);
font-family: var(--font-family-cn);
font-size: var(--font-size-base);
color: var(--color-text-primary);
line-height: var(--line-height-normal);
}
/* ==========================================================================
通用工具类
========================================================================== */
.container {
padding: var(--spacing-page-x);
}
.flex { display: flex; }
.flex-column { display: flex; flex-direction: column; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-start { display: flex; align-items: center; justify-content: flex-start; }
.flex-1 { flex: 1; min-width: 0; }
.flex-shrink-0 { flex-shrink: 0; }
.wrap { flex-wrap: wrap; }
/* 4 列宫格:用 flex + 百分比宽度实现。
注:display:grid 在 WebView 渲染下可用,但 Skyline 不支持,故统一改为 flex 以免疫渲染引擎迁移。*/
.grid-4 {
display: flex;
flex-wrap: wrap;
}
.grid-4 > .grid-item {
width: 25%;
box-sizing: border-box;
}
.text-strong { color: var(--color-text-strong); }
.text-primary { color: var(--color-text-primary); }
.text-secondary { color: var(--color-text-secondary); }
.text-tertiary { color: var(--color-text-tertiary); }
.text-placeholder { color: var(--color-text-placeholder); }
.text-white { color: var(--color-text-inverse); }
.text-brand { color: var(--color-primary-strong); }
/* 品牌色作文字只能用 -strong 变体:基础色 #E96B6B 在白底仅 3.10:1。
保留 .text-brand-soft 这个类名是为了不破坏既有引用,取值已统一到 -strong,
如需「更亮的品牌色」请用于背景/图形而非文字。 */
.text-brand-soft { color: var(--color-primary-strong); }
.text-success { color: var(--color-success-strong); }
.text-warning { color: var(--color-warning-strong); }
.text-danger { color: var(--color-danger-strong); }
.text-info { color: var(--color-info-strong); }
.font-micro { font-size: var(--font-size-micro); }
.font-xs { font-size: var(--font-size-xs); }
.font-sm { font-size: var(--font-size-sm); }
.font-md { font-size: var(--font-size-md); }
.font-base { font-size: var(--font-size-base); }
.font-lg { font-size: var(--font-size-lg); }
.font-xl { font-size: var(--font-size-xl); }
.font-2xl { font-size: var(--font-size-2xl); }
.font-3xl { font-size: var(--font-size-3xl); }
.font-display { font-size: var(--font-size-display); }
.font-regular { font-weight: var(--font-weight-regular); }
.font-medium { font-weight: var(--font-weight-medium); }
.font-semibold { font-weight: var(--font-weight-semibold); }
.font-bold { font-weight: var(--font-weight-bold); }
.mt-1 { margin-top: var(--spacing-1); }
.mt-2 { margin-top: var(--spacing-2); }
.mt-3 { margin-top: var(--spacing-3); }
.mt-4 { margin-top: var(--spacing-4); }
.mt-5 { margin-top: var(--spacing-5); }
.mt-6 { margin-top: var(--spacing-6); }
.mb-1 { margin-bottom: var(--spacing-1); }
.mb-2 { margin-bottom: var(--spacing-2); }
.mb-3 { margin-bottom: var(--spacing-3); }
.mb-4 { margin-bottom: var(--spacing-4); }
.mb-5 { margin-bottom: var(--spacing-5); }
.mb-6 { margin-bottom: var(--spacing-6); }
/* 文本省略 */
.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ellipsis-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
/* 安全区底部留白(避开 Home Indicator) */
.safe-area-bottom {
padding-bottom: 0px;
}
/* 页面卡片基础样式 */
.card-base {
background: var(--color-bg-card);
border-radius: var(--radius-lg);
padding: var(--spacing-card-inner);
box-shadow: var(--shadow-card);
}
/* 分割线 */
.divider {
height: var(--border-width);
background: var(--color-divider);
}
/* ==========================================================================
可访问性:只用 token,不用工具类(2026-09-23 修订)
--------------------------------------------------------------------------
v2 曾在此处新增 .tap-min / .tap-gap / .focusable / .pressable 四个工具类。
复检发现全部零引用(等价能力已各自写在组件样式内,例如 button/index.wxss
直接使用 min-height:var(--tap-min)),且存在两个硬问题:
1) `.tap-gap > * + *` 用了通配符与兄弟选择器 —— WXSS 不支持,
wcc 编译期直接报 `error at token '*'`,导致整个小程序编译失败。
(这是编译错误,不是静默失效,代价最高。)
2) `.pressable:active` / `.focusable:focus-visible` 的伪类在 view 上
不生效(小程序须用 hover-class),属于"写了等于没写"。
故整块移除,保留 token。需要热区/间距时直接引用 token:
min-height: var(--tap-min); → 44.00px = 44px,最小可点区域
gap: var(--tap-gap); → 8.00px = 8px,相邻目标间距(flex gap)
【WXSS 禁用清单】星号通配符、兄弟选择器、属性选择器。
【注释约束】WXSS 注释**不可嵌套**:内层注释的结束标记会提前终止外层注释,
其后的文字会被当成真实样式解析,导致编译失败或样式被污染。
(2026-09-23 实证:本块注释初版即踩此坑。)
========================================================================== */
.wx-page{background:var(--color-bg-page)}.service-page{min-height:100vh;padding-bottom:calc(70.00px + 0px)}.hero{padding:22.00px 16.00px 27.00px;background:linear-gradient(140deg,var(--color-primary-lighter),var(--color-warning-light));position:relative;overflow:hidden}.eyebrow{display:inline-flex;padding:3.50px 7.00px;border-radius:499.50px;background:rgba(255,255,255,.72);color:var(--color-primary-strong);font-size:12.00px}.hero-title{display:block;margin-top:9.00px;font-size:20.00px;font-weight:700;line-height:1.35}.hero-desc{display:block;width:82%;margin-top:7.00px;font-size:12.50px;color:var(--color-text-secondary);line-height:1.7}.content{padding:0 var(--spacing-page-x)}.block{margin-top:var(--spacing-section)}.block-title{display:block;font-size:15.50px;font-weight:600}.block-subtitle{display:block;margin-top:4.00px;font-size:12.00px;color:var(--color-text-tertiary)}.card{margin-top:9.00px;padding:14.00px;background:var(--color-bg-card);border:0.50px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-card)}.feature-row,.menu-row,.record-row{display:flex;align-items:center;gap:10.00px;min-height:56.00px;padding:9.00px 0;border-bottom:0.50px solid var(--color-divider)}.feature-row:last-child,.menu-row:last-child,.record-row:last-child{border-bottom:0}.feature-icon{width:36.00px;height:36.00px;display:flex;align-items:center;justify-content:center;flex:none;border-radius:11.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-weight:700}.feature-copy{flex:1;min-width:0}.feature-title{display:block;font-size:14.00px;font-weight:600}.feature-desc,.meta{display:block;margin-top:3.50px;font-size:12.00px;color:var(--color-text-tertiary);line-height:1.55}.arrow{font-size:20.00px;color:var(--color-text-disabled)}.tag{display:inline-flex;margin-right:5.00px;margin-top:5.00px;padding:3.00px 6.50px;border-radius:499.50px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px}.tag.warning{background:var(--color-warning-light);color:var(--color-warning-strong)}.primary-btn,.secondary-btn{height:44.00px;display:flex;align-items:center;justify-content:center;border-radius:22.00px;font-size:14.00px;font-weight:600}.primary-btn{background:var(--gradient-brand-solid);color:var(--color-text-inverse);box-shadow:0 5.00px 12.00px rgba(255,92,130,.22)}.primary-btn.disabled{background:var(--color-bg-muted);color:var(--color-text-tertiary);box-shadow:none}.secondary-btn{background:var(--color-primary-light);color:var(--color-primary-strong)}.fixed-action{position:fixed;left:0;right:0;bottom:0;padding:9.00px var(--spacing-page-x) calc(9.00px + 0px);background:rgba(255,255,255,.96);border-top:0.50px solid var(--color-divider);z-index:100}.field{margin-top:13.00px}.label{display:block;margin-bottom:6.00px;font-size:12.50px;font-weight:600}.input,.select-box,.textarea{width:100%;box-sizing:border-box;background:var(--color-bg-page);border:0.50px solid var(--color-border);border-radius:var(--radius-md);font-size:13.00px}.input,.select-box{height:44.00px;padding:0 12.00px;display:flex;align-items:center}.textarea{min-height:90.00px;padding:11.00px}.notice{margin-top:10.00px;padding:11.00px;border-radius:var(--radius-md);background:var(--color-info-light);color:var(--color-text-secondary);font-size:12.00px;line-height:1.65}.select-box.is-readonly{background:var(--color-bg-subtle);color:var(--color-text-secondary)}.empty-panel{text-align:center;padding:35.00px 15.00px}.empty-symbol{width:48.00px;height:48.00px;margin:auto;display:flex;align-items:center;justify-content:center;border-radius:15.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-size:18.00px;font-weight:700}.empty-title{display:block;margin-top:11.00px;font-size:15.00px;font-weight:600}.article-card{margin-top:9.00px;background:var(--color-bg-card);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-card)}.article-cover{height:110.00px;padding:12.00px;background:linear-gradient(135deg,var(--color-warning-light),var(--color-warning-light));display:flex;align-items:flex-end}.article-cover text{font-size:21.00px;color:rgba(125,76,63,.52);font-weight:700}.article-body{padding:12.00px}.article-title{display:block;font-size:14.50px;font-weight:600;line-height:1.45}.article-meta{display:block;margin-top:5.00px;font-size:12.00px;color:var(--color-text-tertiary)}.article-content{padding:16.00px;background:var(--color-bg-card);font-size:14.00px;line-height:1.9;color:var(--color-text-secondary)}.article-content .lead{display:block;font-size:15.50px;color:var(--color-text-primary);font-weight:600;margin-bottom:12.00px}.danger-card{background:var(--color-primary-lighter);border-color:var(--color-primary-light)}.danger-card .feature-icon{background:var(--color-warning-light);color:var(--color-warning-strong)}@media(max-width:340px){.hero-title{font-size:18.00px}.hero-desc{width:92%}}
.service-shell{min-height:100vh;padding-bottom:calc(68.00px + 0px);background:var(--color-bg-page)}.service-content{padding:4.00px 12.00px 18.00px}.service-status{display:flex;align-items:center;justify-content:space-between;margin-top:12.00px;padding:10.00px 12.00px;border-radius:11.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-status__label{color:var(--color-text-tertiary);font-size:12.00px}.service-status__value{padding:3.00px 7.00px;border-radius:9.00px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px;font-weight:600}.service-status__value.disabled{background:var(--color-danger-light);color:var(--color-danger-strong)}.service-topics{display:grid;grid-template-columns:repeat(2,1fr);gap:8.00px;margin-top:9.00px}.service-topic{min-height:74.00px;padding:10.00px;border-radius:12.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-topic__icon{display:flex;align-items:center;justify-content:center;width:27.00px;height:27.00px;border-radius:8.50px;background:var(--color-primary-light)}.service-topic__icon image{width:17.00px;height:17.00px}.service-topic__title{display:block;margin-top:6.50px;color:var(--color-text-strong);font-size:12.00px;font-weight:600}.service-topic__desc{display:block;margin-top:3.00px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}.service-actions{display:flex;gap:7.00px}.service-actions .secondary-btn{width:95.00px;flex:none}.service-actions .primary-btn{flex:1}.privacy-note{display:flex;align-items:flex-start;gap:7.00px;margin-top:11.00px;padding:10.00px;border-radius:11.00px;background:var(--color-info-light);color:var(--color-text-tertiary);font-size:12.00px;line-height:1.55}.privacy-note image{width:17.00px;height:17.00px;flex:none}
/* ==== miniapp/components/section-header ==== */
/**
* 区块标题(全站所有页面共用,是排版层级的关键一环)
*
* 2026-09-22 修订:
* 1) 层级拉开:标题 18.00px→20.00px(--font-size-xl),与正文 16.00px / 卡片标题 14.00px
* 形成「区块标题 > 卡片标题 > 正文 > 元信息」四级阶梯。
* 旧值 18.00px 与卡片标题仅差 5.00px,层级读不出来。
* 2) 右侧 action 是全站最容易被忽略的触摸目标:只有 13.00px 文字高(约 13px),
* 远低于 44px 下限。改为 min-height:--tap-min,热区向上补白。
* 3) action 文字色原为 --color-primary(#E96B6B)=3.10:1,不达标,改 -strong。
*/
.ui-section {
display:flex;
align-items:center;
justify-content:space-between;
padding:var(--spacing-2) var(--spacing-page-x);
}
.ui-section__left {
display:flex;
align-items:baseline;
min-width:0;
}
.ui-section__title {
font-size:var(--font-size-xl);
font-weight:var(--font-weight-semibold);
color:var(--color-text-strong);
letter-spacing:var(--letter-spacing-tight);
}
.ui-section__subtitle {
margin-left:var(--spacing-2);
font-size:var(--font-size-xs);
color:var(--color-text-tertiary);
}
.ui-section__action {
display:flex;
align-items:center;
flex:none;
min-height:var(--tap-min);
padding-left:var(--spacing-3);
font-size:var(--font-size-sm);
font-weight:var(--font-weight-medium);
color:var(--color-primary-strong);
transition:opacity var(--motion-fast) var(--ease-standard);
}
.ui-section__action:active {
opacity:var(--press-opacity);
}
.ui-section__arrow {
margin-left:2.00px;
width:12.00px;
height:12.00px;
}
/* ==== miniapp/components/avatar ==== */
.ui-avatar {
position:relative;
flex-shrink:0;
background:var(--color-bg-disabled);
overflow:hidden;
}
.ui-avatar--circle { border-radius:50%; }
.ui-avatar--square { border-radius:var(--radius-md); }
/* 尺寸:sm 60 / md 88 / lg 120 / xl 160 */
.ui-avatar--sm { width:30.00px; height:30.00px; }
.ui-avatar--md { width:44.00px; height:44.00px; }
.ui-avatar--lg { width:60.00px; height:60.00px; }
.ui-avatar--xl { width:80.00px; height:80.00px; }
.ui-avatar__img {
width:100%;
height:100%;
display:block;
}
.ui-avatar__fallback {
width:100%;
height:100%;
display:flex;
align-items:center;
justify-content:center;
background:var(--color-primary-light);
}
.ui-avatar__fallback-text {
font-size:var(--font-size-lg);
color:var(--color-primary-strong);
font-weight:var(--font-weight-semibold);
}
.ui-avatar__fallback-icon {
width:100%;
height:100%;
}
.ui-avatar__badges {
position:absolute;
bottom:-2.00px;
left:50%;
transform:translateX(-50%);
display:flex;
gap:3.00px;
}
.ui-avatar__badge {
font-size:8.00px;
line-height:1;
padding:2.00px 4.00px;
border-radius:var(--radius-full);
color:var(--color-text-inverse);
font-weight:var(--font-weight-medium);
white-space:nowrap;
}
.ui-avatar__badge--verified { background:var(--color-success); }
.ui-avatar__badge--reviewed { background:var(--color-info); }
/* 小尺寸时隐藏徽标避免溢出 */
.ui-avatar--sm .ui-avatar__badges { display:none; }
/* ==== miniapp/components/status-badge ==== */
.ui-badge {
display:inline-flex;
align-items:center;
padding:2.00px 7.00px;
border-radius:var(--radius-full);
font-size:var(--font-size-xs);
font-weight:var(--font-weight-medium);
line-height:1.4;
white-space:nowrap;
}
.ui-badge__dot {
width:4.00px;
height:4.00px;
border-radius:50%;
background:currentColor;
margin-right:4.00px;
}
.ui-badge__label {
font-size:inherit;
}
.ui-badge--success {
background:var(--color-success-light);
color:var(--color-success-strong);
}
.ui-badge--warning {
background:var(--color-warning-light);
color:var(--color-warning-strong);
}
.ui-badge--danger {
background:var(--color-danger-light);
color:var(--color-danger-strong);
}
.ui-badge--info {
background:var(--color-info-light);
color:var(--color-info-strong);
}
.ui-badge--disabled {
background:var(--color-bg-disabled);
color:var(--color-text-disabled);
}
/* ==== miniapp/components/button ==== */
/**
* Button 组件样式
* 引用全局 Design Token(addGlobalClass:true)
*
* 2026-09-22 修复:
* 1) 触摸目标:md 只有 40.00px(40px)、sm 只有 28.00px(28px),低于 44px 下限;
* text 变体更是 min-height:auto,几乎点不中。现统一以 --tap-min 兜底。
* 2) 对比度:主按钮背景原为 --color-primary(#E96B6B),白字仅 3.10:1。
* 改用 --color-primary-solid(#C24C50) = 4.73:1,视觉上仍是暖红。
* secondary/text 的红色文字同理从 3.10 提到 --color-primary-strong 的 5.33。
* 3) 危险按钮 --color-danger(#D94A4A) 白字 4.18:1 不达标,改用 -strong 变体。
* 4) 按压反馈统一走 --press-scale / --press-opacity,替代硬编码 0.98 / 0.85。
*/
.ui-btn {
display:inline-flex;
align-items:center;
justify-content:center;
box-sizing:border-box;
border-radius:var(--radius-full);
font-family:var(--font-family-cn);
font-weight:var(--font-weight-semibold);
text-align:center;
transition:transform var(--motion-fast) var(--ease-spring),
opacity var(--motion-fast) var(--ease-standard),
background-color var(--motion-fast) var(--ease-standard);
user-select:none;
line-height:1.2;
white-space:nowrap;
}
/* 尺寸:全部以 44×44px 为热区下限 */
.ui-btn--sm {
padding:7.00px 14.00px;
font-size:var(--font-size-sm);
min-height:var(--tap-min);
}
.ui-btn--md {
padding:10.00px 18.00px;
font-size:var(--font-size-base);
min-height:var(--tap-min);
}
.ui-btn--lg {
padding:13.00px 24.00px;
font-size:var(--font-size-lg);
min-height:var(--tap-comfortable);
}
/* 撑满 */
.ui-btn--block {
display:flex;
width:100%;
}
/* 变体 */
.ui-btn--primary {
background:var(--color-primary-solid);
color:var(--color-text-inverse);
}
.ui-btn--secondary {
background:var(--color-bg-card);
color:var(--color-primary-strong);
border:var(--border-width) solid var(--color-primary-strong);
}
.ui-btn--ghost {
background:transparent;
color:var(--color-text-primary);
border:var(--border-width) solid var(--color-border-strong);
}
.ui-btn--danger {
background:var(--color-danger-strong);
color:var(--color-text-inverse);
}
.ui-btn--text {
background:transparent;
color:var(--color-primary-strong);
padding-left:var(--spacing-2);
padding-right:var(--spacing-2);
/* 视觉是纯文字,但热区仍需 44px:多出的部分由 align-items:center 居中留白 */
min-height:var(--tap-min);
}
/* 状态 */
.ui-btn--disabled,
.ui-btn--loading {
opacity:0.55;
}
.ui-btn--disabled.ui-btn--primary,
.ui-btn--disabled.ui-btn--danger {
background:var(--color-text-disabled);
}
.ui-btn--disabled.ui-btn--secondary,
.ui-btn--disabled.ui-btn--ghost {
color:var(--color-text-disabled);
border-color:var(--color-text-disabled);
}
/* 按压反馈(hover-class 与 CSS :active 双保险) */
.ui-btn--hover,
.ui-btn:active {
opacity:var(--press-opacity);
transform:scale(var(--press-scale));
}
/* Loading spinner */
.ui-btn__spinner {
width:14.00px;
height:14.00px;
margin-right:6.00px;
display:flex;
align-items:center;
justify-content:center;
}
.ui-btn__spinner-dot {
width:9.00px;
height:9.00px;
border-radius:50%;
border:1.50px solid currentColor;
border-top-color:transparent;
animation:ui-btn-spin 0.7s linear infinite;
}
@keyframes ui-btn-spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
/* ==== miniapp/components/loading ==== */
.ui-loading--block {
display:flex;
flex-direction:column;
align-items:center;
justify-content:center;
padding:var(--spacing-8) var(--spacing-page-x);
}
.ui-loading--inline {
display:inline-flex;
align-items:center;
}
.ui-loading__spinner {
width:30.00px;
height:30.00px;
display:flex;
align-items:center;
justify-content:center;
}
.ui-loading__spinner-icon {
width:24.00px;
height:24.00px;
animation:ui-loading-spin 0.8s linear infinite;
}
@keyframes ui-loading-spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
.ui-loading__text {
margin-top:var(--spacing-3);
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
}
/* Skeleton */
.ui-loading__skeleton {
width:100%;
}
.ui-loading__skeleton-row {
display:flex;
align-items:center;
padding:var(--spacing-3) var(--spacing-page-x);
background:var(--color-bg-card);
border-bottom:0.50px solid var(--color-divider);
}
.ui-loading__skeleton-avatar {
width:44.00px;
height:44.00px;
border-radius:50%;
background:var(--color-bg-disabled);
margin-right:var(--spacing-3);
flex-shrink:0;
}
.ui-loading__skeleton-content {
flex:1;
min-width:0;
}
.ui-loading__skeleton-line {
height:12.00px;
background:var(--color-bg-disabled);
border-radius:var(--radius-sm);
position:relative;
overflow:hidden;
}
.ui-loading__skeleton-line--title {
width:40%;
margin-bottom:var(--spacing-2);
}
.ui-loading__skeleton-line--meta {
width:70%;
}
/* shimmer */
.ui-loading__skeleton-line::after,
.ui-loading__skeleton-avatar::after {
content:'';
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background:linear-gradient(
90deg,
transparent 0%,
rgba(255, 255, 255, 0.55) 50%,
transparent 100%
);
animation:ui-loading-shimmer 1.4s ease-in-out infinite;
}
@keyframes ui-loading-shimmer {
0% { transform:translateX(-100%); }
100% { transform:translateX(100%); }
}
/* ==== miniapp/components/empty ==== */
.ui-empty {
display:flex;
flex-direction:column;
align-items:center;
padding:var(--spacing-10) var(--spacing-page-x);
text-align:center;
}
.ui-empty__illustration {
width:80.00px;
height:80.00px;
border-radius:50%;
background:var(--color-bg-disabled);
display:flex;
align-items:center;
justify-content:center;
margin-bottom:var(--spacing-4);
}
.ui-empty__icon {
width:36.00px;
height:36.00px;
opacity:0.72;
}
.ui-empty__title {
font-size:var(--font-size-lg);
font-weight:var(--font-weight-medium);
color:var(--color-text-primary);
margin-bottom:var(--spacing-2);
}
.ui-empty__desc {
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
line-height:var(--line-height-relaxed);
max-width:240.00px;
}
.ui-empty__actions {
display:flex;
flex-direction:column;
gap:var(--spacing-2);
margin-top:var(--spacing-6);
width:100%;
max-width:240.00px;
}
.ui-empty__action {
display:flex;
align-items:center;
justify-content:center;
min-height:var(--tap-min);
border-radius:var(--radius-full);
font-size:var(--font-size-base);
font-weight:var(--font-weight-medium);
min-width:var(--tap-min);}
.ui-empty__action--primary {
background:var(--color-primary-solid);
color:var(--color-text-inverse);
}
.ui-empty__action--secondary {
background:var(--color-bg-card);
color:var(--color-primary-strong);
border:0.50px solid var(--color-primary);
}
/* ==== miniapp/components/danger-action-dialog ==== */
.ui-dialog-mask {
position:fixed;
top:0;
left:0;
right:0;
bottom:0;
background:var(--color-bg-overlay);
z-index:var(--z-modal);
display:flex;
align-items:center;
justify-content:center;
padding:0 var(--spacing-6);
}
.ui-dialog {
width:100%;
max-width:300.00px;
background:var(--color-bg-card);
border-radius:var(--radius-lg);
padding:var(--spacing-5) var(--spacing-4) var(--spacing-4);
box-shadow:var(--shadow-popup);
animation:ui-dialog-in var(--motion-normal) var(--ease-standard);
}
@keyframes ui-dialog-in {
from { transform:scale(0.92); opacity:0; }
to { transform:scale(1); opacity:1; }
}
.ui-dialog__title {
font-size:var(--font-size-xl);
font-weight:var(--font-weight-semibold);
color:var(--color-text-primary);
text-align:center;
margin-bottom:var(--spacing-3);
}
.ui-dialog__content {
font-size:var(--font-size-md);
color:var(--color-text-secondary);
line-height:var(--line-height-relaxed);
text-align:center;
margin-bottom:var(--spacing-5);
}
.ui-dialog__actions {
display:flex;
gap:var(--spacing-2);
}
.ui-dialog__btn {
flex:1;
}
.page{min-height:100vh;padding-bottom:24.00px;background:var(--color-bg-page)}.mine-guest{min-height:100vh;background:linear-gradient(160deg,var(--mini-night-start) 0,var(--mini-night-end) 34%,var(--color-bg-page) 34%)}.guest-brand{display:flex;flex-direction:column;align-items:center;padding:calc(var(--nav-top, 84px) + 35.00px) 0 40.00px;color:var(--color-text-inverse)}.guest-brand image{width:46.00px;height:46.00px}.guest-brand>text{margin-top:6.00px;font-size:17.00px;font-weight:700}.guest-brand .guest-subtitle{margin-top:2.50px;color:rgba(255,255,255,.72);font-size:12.00px;font-weight:400;letter-spacing:2.00px}/* --nav-status / --nav-h / --nav-right 由 mine.ts 经 utils/nav-metrics 实测胶囊按钮后注入 */
.profile-hero{padding:var(--nav-status, 44px) 12.00px 27.00px;border-radius:0 0 21.00px 21.00px;background:linear-gradient(160deg,var(--mini-night-start),var(--mini-night-end));box-shadow:var(--mini-shadow)}.mine-nav{position:relative;display:flex;align-items:center;justify-content:center;height:var(--nav-h, 40.00px);color:var(--color-text-inverse);font-size:15.50px;font-weight:700}.mine-nav image{position:absolute;right:var(--nav-right, 102px);width:18.00px;height:18.00px;filter:brightness(0) invert(1)}.profile-main{position:relative;display:flex;align-items:center}.profile-copy{flex:1;min-width:0;margin-left:10.00px;color:var(--color-text-inverse)}.profile-name-row{display:flex;align-items:center;gap:6.00px}.profile-name{font-size:15.50px;font-weight:700}.profile-status{padding:2.50px 5.00px;border-radius:7.50px;background:rgba(255,255,255,.12);color:rgba(255,255,255,.78);font-size:12.00px}.profile-meta{display:block;margin-top:4.00px;color:rgba(255,255,255,.72);font-size:12.00px}.profile-progress{width:78%;height:3.50px;margin:5.00px 0 6.50px;overflow:hidden;border-radius:4.00px;background:rgba(255,255,255,.14)}.profile-progress view{height:100%;border-radius:4.00px;background:linear-gradient(90deg,var(--color-primary-light),var(--color-primary-light))}.profile-badges{display:flex;gap:4.00px}.edit-profile{position:absolute;right:0;top:2.00px;color:rgba(255,255,255,.82);font-size:12.00px}.profile-stats{position:relative;z-index:2;display:grid;grid-template-columns:repeat(4,1fr);margin:-12.00px 12.00px 0;padding:12.00px 4.00px;border-radius:14.00px;background:var(--color-bg-card);box-shadow:var(--mini-shadow)}.profile-stat{display:flex;flex-direction:column;align-items:center;border-right:0.50px solid var(--color-divider)}.profile-stat:last-child{border-right:0}.stat-value{color:var(--color-text-strong);font-size:14.50px;font-weight:700}.stat-value--text{font-size:12.00px}.stat-label{margin-top:2.50px;color:var(--color-text-tertiary);font-size:12.00px}.public-identity-card{display:flex;align-items:center;margin:12.00px;padding:11.00px;border-radius:13.00px;background:linear-gradient(135deg,var(--color-primary-light),var(--color-accent-purple-light));box-shadow:0 4.00px 13.00px rgba(87,62,145,.08)}.public-identity-card>image:first-child{width:36.00px;height:36.00px}.public-identity-card>view{flex:1;display:flex;flex-direction:column;margin-left:8.00px}.identity-title{color:var(--color-primary-strong);font-size:13.00px;font-weight:700}.identity-desc{margin-top:2.50px;color:var(--color-accent-purple-strong);font-size:12.00px}.public-identity-card .identity-arrow{width:13.00px;height:13.00px}.service-grid{display:grid;grid-template-columns:repeat(4,1fr);margin:0 12.00px 14.00px;padding:12.00px 4.00px;border-radius:13.00px;background:var(--color-bg-card);box-shadow:0 4.00px 14.00px rgba(35,35,95,.07)}.service-entry{display:flex;flex-direction:column;align-items:center;color:var(--color-text-strong);font-size:12.00px}.service-icon{display:flex;align-items:center;justify-content:center;width:32.00px;height:32.00px;margin-bottom:5.00px;border-radius:10.00px}.service-icon image{width:21.00px;height:21.00px}.service-icon.rose{background:var(--color-primary-light)}.service-icon.blue{background:var(--color-info-light)}.service-icon.amber{background:var(--color-warning-light)}.service-icon.green{background:var(--color-success-light)}.list-group{overflow:hidden;margin:0 12.00px 11.00px;border-radius:13.00px;background:var(--color-bg-card);box-shadow:0 4.00px 14.00px rgba(35,35,95,.06)}.list-row{display:flex;align-items:center;min-height:44.00px;padding:0 12.00px;border-bottom:0.50px solid var(--color-divider)}.list-row:last-child{border-bottom:0}.list-label{flex:1;color:var(--color-text-strong);font-size:12.00px}.list-value{margin-right:6.00px;color:var(--color-text-tertiary);font-size:12.00px}.list-arrow{width:12.00px;height:12.00px}.secondary-list{margin-top:0}.logout-row{margin:13.00px 12.00px 0;padding:12.00px;text-align:center;color:var(--color-danger-strong);font-size:12.00px;background:var(--color-bg-card);border-radius:13.00px}
/**
* 丹阳公益婚恋服务平台 - 全局 Design Token
*
* v2(2026-09-22 设计系统夯实)
* ---------------------------------------------------------------
* 本次修订针对审计发现的系统性问题,逐条给出依据:
*
* 1) 品牌色不能承载文字 → 引入「基础色 / -strong」分级
* #E96B6B on 白 = 3.10:1,白字 on #E96B6B = 3.10:1,on #FFF3F2 = 2.85:1,
* 三条路径都不满足正文 4.5:1。故:
* --color-primary 仅用于大色块、渐变、光晕、装饰(非文字)
* --color-primary-strong 用于文字、小图标、纯文字链接(5.33:1 ✓)
* --color-primary-solid 实心按钮底(白字 ≥4.5:1 ✓)
* 功能色(success/warning/danger/info)同此分级。
*
* 2) 次要文字对比度过低
* 旧 --color-text-tertiary(#777) = 4.48(on 白,勉强)/ #999 实测 2.85 却被用了 71 次。
* 现将三级文字压到 #646C85 = 5.22:1,占位符保留浅色(占位符非正文)。
*
* 3) 颜色碎片化
* 审计前全站 182 种 hex、770 次硬编码(54 种灰、60 种蓝紫、40 种红橙)。
* 本文件是唯一的颜色事实源;页面层禁止再写 hex,一律 var(--token)。
*
* 4) 触摸目标
* 组件库默认按钮只有 40px、小号 28px、"喜欢"按钮 31px。
* 统一以 --tap-min(44.00px=44px) 为下限,--tap-gap 为最小间距。
*
* 5) 动效几乎未落地(--motion-* 全站仅 5 次引用)
* 补充 --ease-spring 与 --press-scale,让点击有即时反馈。
*
* 6) 夜间氛围层缺失(参考图有明显的光晕/星点,代码只有纯渐变)
* 新增 --mini-glow-* / --mini-star / --mini-glass / --mini-hairline。
*
* 单位说明:rpx(375.00px = 屏幕宽度,0.50px ≈ 0.5px @375pt)
* 旧 token 名全部保留(88 个 wxss 共 909 处引用),只更新取值,避免大范围失效。
*/
.wx-page {
/* ============ 品牌主色(分级:色块 / 文字 / 实心按钮) ============ */
--color-primary: #E96B6B; /* 基础色:渐变、光晕、装饰、非文字图形 */
--color-primary-strong: #B8434A; /* 文字与小图标(5.33:1 on 白,4.91:1 on 浅粉底) */
--color-primary-solid: #C24C50; /* 实心按钮底(白字 4.62:1) */
--color-primary-active: #D95F5F; /* 按压态(配合 --color-primary 使用) */
--color-primary-light: #FFF3F2;
--color-primary-lighter: #FFF8F7;
/* ============ 小程序参考图品牌主题(夜间紫蓝) ============ */
--mini-night-start: #172A72;
--mini-night-end: #25104F;
--mini-night-soft: #3445A1;
--mini-accent-pink: #FF4F91; /* 点缀色:仅用于色块/装饰,不作正文 */
--mini-accent-coral: #FF6A78;
--mini-card-bg: rgba(255, 255, 255, 0.98);
--mini-text: #1F2744;
--mini-muted: #7D839B;
--mini-card-radius: 12.00px;
--mini-text-on-night: #FFFFFF; /* on 深底 13.04:1 ✓ */
--mini-text-on-night-muted: rgba(255, 255, 255, 0.72); /* on 深底 ≈8:1 ✓ */
--mini-shadow: 0 8.00px 20.00px rgba(28, 30, 88, 0.14);
/* ---- 渐变(集中定义:此前 4 个页面各写了一份「橙红渐变」按钮) ---- */
/* --gradient-brand 明亮活泼,但白字仅 2.77:1 —— 只能用于无文字的装饰填充。 */
--gradient-brand: linear-gradient(135deg, #FF6A78 0%, #E96B6B 100%);
/* 承载白字的 CTA 渐变:两端 #C24C50(4.73:1) / #B8434A(5.33:1) 均达标。 */
--gradient-brand-solid: linear-gradient(135deg, #C24C50 0%, #B8434A 100%);
--gradient-night: linear-gradient(160deg, #172A72 0%, #25104F 100%);
--gradient-night-soft: linear-gradient(160deg, #3445A1 0%, #172A72 100%);
/* ---- 首页 4×2 入口宫格图标渐变(参考图 2:高饱和圆角砖 + 白色描画图标) ----
白图标的对比度判据是**非文本图形 3:1**(WCAG 1.4.11)。渐变是斜向的、图标又跨在
两色之间,所以**较亮的一端也必须达标** —— 下表注释给的是 0% 处实算值,100% 更暗只会更高。
色相按业务语义固定(不随 tone 名漂移):找对象/婚前辅导=玫瑰粉系、公益红娘/服务站=暖橙系、
公益活动=紫罗兰、婚恋咨询=蓝、婚恋课堂=紫、婚恋反诈=绿。 */
--gradient-entry-rose: linear-gradient(135deg, #F56287 0%, #F34671 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-orange: linear-gradient(135deg, #F66A06 0%, #D95E06 100%); /* 3.01:1 / 3.78:1 */
--gradient-entry-violet: linear-gradient(135deg, #A380F5 0%, #8F64F2 100%); /* 3.02:1 / 3.98:1 */
--gradient-entry-blue: linear-gradient(135deg, #5195F6 0%, #3484F4 100%); /* 3.01:1 / 3.65:1 */
--gradient-entry-purple: linear-gradient(135deg, #B27BF0 0%, #A260ED 100%); /* 3.01:1 / 3.87:1 */
--gradient-entry-pink: linear-gradient(135deg, #F2619E 0%, #F0458C 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-green: linear-gradient(135deg, #18A979 0%, #148F66 100%); /* 3.00:1 / 4.08:1 */
--gradient-entry-amber: linear-gradient(135deg, #E9740C 0%, #CC650B 100%); /* 3.01:1 / 3.86:1 */
/* 图标砖落影:比 --mini-shadow 更小,避免 4 列宫格里相邻砖块的投影互相压边 */
--mini-entry-shadow: 0 4.00px 9.00px rgba(28, 30, 88, 0.18);
/* ---- 夜间氛围层(v2 新增;参考图有光晕与星点,此前完全没有) ---- */
--mini-glow-coral: rgba(255, 79, 145, 0.40);
--mini-glow-indigo: rgba(94, 124, 255, 0.32);
--mini-glow-soft: rgba(255, 255, 255, 0.10);
--mini-star: rgba(255, 255, 255, 0.70);
--mini-glass: rgba(255, 255, 255, 0.10); /* 深底玻璃面 */
--mini-glass-strong: rgba(255, 255, 255, 0.16);
--mini-hairline: rgba(255, 255, 255, 0.16); /* 深底分隔线 */
--mini-glass-success: rgba(90, 226, 184, 0.16); /* 深底上的成功态玻璃面 */
/* 星点层:多个小径向渐变叠在夜空渐变之上。用 radial-gradient 而非图片,
避免额外请求,也便于随主题换色(index 页脚注:装饰层不承载信息)。 */
--mini-starfield:
radial-gradient(circle at 12% 18%, var(--mini-star) 0, transparent 1.25px),
radial-gradient(circle at 31% 66%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 57% 12%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 79% 52%, var(--mini-star) 0, transparent 1.50px),
radial-gradient(circle at 93% 84%, var(--mini-star) 0, transparent 1.00px);
/* 横幅压暗层:保证任何底图上的白色标题都有足够对比度 */
--mini-banner-scrim: linear-gradient(90deg, rgba(23, 42, 114, 0.84) 0%, rgba(37, 16, 79, 0.40) 56%, rgba(255, 79, 145, 0.12) 100%);
/* ============ 功能色(同样分级) ============ */
--color-success: #2E9B68; /* 色块/图标 */
--color-success-strong: #17805A; /* 文字(4.92:1 ✓) */
--color-success-light: #ECF8F2;
--color-warning: #E59A32; /* 色块/图标(作文字仅 2.33:1) */
--color-warning-strong: #9C5F14; /* 文字(5.17:1 ✓) */
--color-warning-light: #FFF7E9;
--color-danger: #D94A4A; /* 色块/图标 */
--color-danger-strong: #C62828; /* 文字(5.62:1 ✓) */
--color-danger-light: #FFF0F0;
--color-info: #4A7CD4; /* 色块/图标 */
--color-info-strong: #2A5DB0; /* 文字(6.38:1 ✓) */
--color-info-light: #EEF4FF;
/* ============ 强调紫(参考图的标签语言;此前散落成 6 种写法) ============ */
--color-accent-purple: #8B63BC; /* 色块/装饰 */
--color-accent-purple-strong: #7C60BC; /* 文字(5.03:1 ✓) */
--color-accent-purple-light: #F3EEFF;
/* 深色夜空底上的强调色(不可用于浅色底) */
--color-success-on-night: #A6F5D7; /* on #172A72 = 10.35:1 ✓ */
/* ============ 文字色(实测对比度 on 白 / on 页面底) ============ */
--color-text-strong: #1A1F36; /* 标题 16.24 / 14.90 ✓ */
--color-text-primary: #2A3050; /* 正文 12.83 / 11.77 ✓ */
--color-text-secondary: #4A5169; /* 次要正文 7.86 / 7.21 ✓ */
--color-text-tertiary: #646C85; /* 说明文字 5.22 / 4.79 ✓(旧 #777 为 4.48) */
--color-text-placeholder: #9AA1B4; /* 占位符(非正文,可浅) */
--color-text-disabled: #B8BDC9;
--color-text-inverse: #FFFFFF; /* 深色背景上的文字 */
/* ============ 边框与分割线 ============ */
--color-border: #E6E8EF;
--color-border-strong: #D8DBE5;
--color-divider: #EFF0F5;
--color-border-focus: #B8434A; /* 焦点环用 strong,保证 3:1 可见度 */
--color-border-error: #C62828;
/* ============ 背景(避免纯白/纯灰平铺,页面底为暖白) ============ */
--color-bg-page: #F6F5F3;
--color-bg-card: #FFFFFF;
--color-bg-subtle: #F5F6FA; /* 次级区块、内嵌列表 */
--color-bg-muted: #EEF0F6; /* 更弱的填充 */
--color-bg-input: #F7F8FB; /* 表单输入框底(此前被引用但从未定义,导致背景失效) */
--color-bg-disabled: #F3F4F7;
--color-bg-overlay: rgba(0, 0, 0, 0.45);
/* ============ 字体 ============ */
/* 小程序无法可靠加载 Web Font(wx.loadFontFace 依赖 HTTPS 白名单且有闪动风险),
故使用中文系统字栈:iOS 走苹方、Android 走思源/系统黑体。
排版辨识度靠字号阶梯与字重建立,而非依赖字体本身。 */
--font-family-cn: -apple-system, "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
--font-family-number: "SF Pro Display", -apple-system, "DIN Alternate", "PingFang SC", sans-serif;
/* 字号阶梯 —— 正文 16.00px(16px) 起,元信息下限 12.00px(12px) */
--font-size-micro: 11.00px; /* 11px 仅角标/装饰,禁用于正文 */
--font-size-xs: 12.00px; /* 12px 元信息下限 */
--font-size-sm: 13.00px; /* 13px 次要说明 */
--font-size-md: 14.00px; /* 14px 次要正文 */
--font-size-base: 16.00px; /* 16px 正文 */
--font-size-lg: 18.00px; /* 18px 小标题 */
--font-size-xl: 20.00px; /* 20px 区块标题 */
--font-size-2xl: 24.00px; /* 24px 页面标题 */
--font-size-3xl: 28.00px; /* 28px 大标题 */
--font-size-display: 32.00px; /* 32px Hero */
/* 字重:只用 4 档。禁止 550/650/750 等非百位值 —— Android 无对应字重会回退,
导致同一设计在不同机型上粗细不一致(审计发现 30 处)。 */
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.65;
--letter-spacing-tight: 0;
--letter-spacing-wide: 0.50px;
--letter-spacing-wider: 1.00px;
/* ============ 间距(4px 栅格) ============ */
--spacing-1: 4.00px;
--spacing-2: 8.00px;
--spacing-3: 12.00px;
--spacing-4: 16.00px;
--spacing-5: 20.00px;
--spacing-6: 24.00px;
--spacing-8: 32.00px;
--spacing-10: 40.00px;
--spacing-12: 48.00px;
--spacing-page-x: 16.00px;
--spacing-section: 24.00px;
--spacing-card-inner: 16.00px;
--spacing-tight: 8.00px;
/* ============ 圆角 ============ */
--radius-sm: 8.00px;
--radius-md: 12.00px;
--radius-lg: 16.00px;
--radius-xl: 20.00px;
--radius-2xl: 24.00px;
--radius-full: 4999.50px;
/* ============ 阴影(统一为一套,此前 30+ 种近似值) ============ */
--shadow-card: 0 4.00px 14.00px rgba(35, 35, 95, 0.07);
--shadow-raised: 0 6.00px 18.00px rgba(35, 35, 95, 0.10);
--shadow-popup: 0 8.00px 32.00px rgba(0, 0, 0, 0.10);
--shadow-night: 0 8.00px 20.00px rgba(28, 30, 88, 0.18);
/* ============ 边框宽度 ============ */
--border-width: 0.50px;
--border-width-strong: 1.00px;
/* ============ 触摸目标(无障碍下限 44×44px) ============ */
--tap-min: 44.00px; /* 44px 最小可点区域 */
--tap-comfortable: 48.00px; /* 48px 舒适尺寸:主操作 */
--tap-gap: 8.00px; /* 8px 相邻目标最小间距 */
/* ============ 动效 ============ */
--motion-fast: 120ms;
--motion-normal: 200ms;
--motion-slow: 300ms;
--ease-standard: cubic-bezier(0.32, 0.72, 0, 1);
--ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
--press-scale: 0.97;
--press-opacity: 0.88;
/* ============ 层级 z-index ============ */
--z-base: 1;
--z-sticky: 100;
--z-tabbar: 200;
--z-dropdown: 500;
--z-modal: 1000;
--z-toast: 2000;
--z-ambient: 0;
/* ============ 页面基础样式 ============ */
background-color: var(--color-bg-page);
font-family: var(--font-family-cn);
font-size: var(--font-size-base);
color: var(--color-text-primary);
line-height: var(--line-height-normal);
}
/* ==========================================================================
通用工具类
========================================================================== */
.container {
padding: var(--spacing-page-x);
}
.flex { display: flex; }
.flex-column { display: flex; flex-direction: column; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-start { display: flex; align-items: center; justify-content: flex-start; }
.flex-1 { flex: 1; min-width: 0; }
.flex-shrink-0 { flex-shrink: 0; }
.wrap { flex-wrap: wrap; }
/* 4 列宫格:用 flex + 百分比宽度实现。
注:display:grid 在 WebView 渲染下可用,但 Skyline 不支持,故统一改为 flex 以免疫渲染引擎迁移。*/
.grid-4 {
display: flex;
flex-wrap: wrap;
}
.grid-4 > .grid-item {
width: 25%;
box-sizing: border-box;
}
.text-strong { color: var(--color-text-strong); }
.text-primary { color: var(--color-text-primary); }
.text-secondary { color: var(--color-text-secondary); }
.text-tertiary { color: var(--color-text-tertiary); }
.text-placeholder { color: var(--color-text-placeholder); }
.text-white { color: var(--color-text-inverse); }
.text-brand { color: var(--color-primary-strong); }
/* 品牌色作文字只能用 -strong 变体:基础色 #E96B6B 在白底仅 3.10:1。
保留 .text-brand-soft 这个类名是为了不破坏既有引用,取值已统一到 -strong,
如需「更亮的品牌色」请用于背景/图形而非文字。 */
.text-brand-soft { color: var(--color-primary-strong); }
.text-success { color: var(--color-success-strong); }
.text-warning { color: var(--color-warning-strong); }
.text-danger { color: var(--color-danger-strong); }
.text-info { color: var(--color-info-strong); }
.font-micro { font-size: var(--font-size-micro); }
.font-xs { font-size: var(--font-size-xs); }
.font-sm { font-size: var(--font-size-sm); }
.font-md { font-size: var(--font-size-md); }
.font-base { font-size: var(--font-size-base); }
.font-lg { font-size: var(--font-size-lg); }
.font-xl { font-size: var(--font-size-xl); }
.font-2xl { font-size: var(--font-size-2xl); }
.font-3xl { font-size: var(--font-size-3xl); }
.font-display { font-size: var(--font-size-display); }
.font-regular { font-weight: var(--font-weight-regular); }
.font-medium { font-weight: var(--font-weight-medium); }
.font-semibold { font-weight: var(--font-weight-semibold); }
.font-bold { font-weight: var(--font-weight-bold); }
.mt-1 { margin-top: var(--spacing-1); }
.mt-2 { margin-top: var(--spacing-2); }
.mt-3 { margin-top: var(--spacing-3); }
.mt-4 { margin-top: var(--spacing-4); }
.mt-5 { margin-top: var(--spacing-5); }
.mt-6 { margin-top: var(--spacing-6); }
.mb-1 { margin-bottom: var(--spacing-1); }
.mb-2 { margin-bottom: var(--spacing-2); }
.mb-3 { margin-bottom: var(--spacing-3); }
.mb-4 { margin-bottom: var(--spacing-4); }
.mb-5 { margin-bottom: var(--spacing-5); }
.mb-6 { margin-bottom: var(--spacing-6); }
/* 文本省略 */
.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ellipsis-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
/* 安全区底部留白(避开 Home Indicator) */
.safe-area-bottom {
padding-bottom: 0px;
}
/* 页面卡片基础样式 */
.card-base {
background: var(--color-bg-card);
border-radius: var(--radius-lg);
padding: var(--spacing-card-inner);
box-shadow: var(--shadow-card);
}
/* 分割线 */
.divider {
height: var(--border-width);
background: var(--color-divider);
}
/* ==========================================================================
可访问性:只用 token,不用工具类(2026-09-23 修订)
--------------------------------------------------------------------------
v2 曾在此处新增 .tap-min / .tap-gap / .focusable / .pressable 四个工具类。
复检发现全部零引用(等价能力已各自写在组件样式内,例如 button/index.wxss
直接使用 min-height:var(--tap-min)),且存在两个硬问题:
1) `.tap-gap > * + *` 用了通配符与兄弟选择器 —— WXSS 不支持,
wcc 编译期直接报 `error at token '*'`,导致整个小程序编译失败。
(这是编译错误,不是静默失效,代价最高。)
2) `.pressable:active` / `.focusable:focus-visible` 的伪类在 view 上
不生效(小程序须用 hover-class),属于"写了等于没写"。
故整块移除,保留 token。需要热区/间距时直接引用 token:
min-height: var(--tap-min); → 44.00px = 44px,最小可点区域
gap: var(--tap-gap); → 8.00px = 8px,相邻目标间距(flex gap)
【WXSS 禁用清单】星号通配符、兄弟选择器、属性选择器。
【注释约束】WXSS 注释**不可嵌套**:内层注释的结束标记会提前终止外层注释,
其后的文字会被当成真实样式解析,导致编译失败或样式被污染。
(2026-09-23 实证:本块注释初版即踩此坑。)
========================================================================== */
.wx-page{background:var(--color-bg-page)}.service-page{min-height:100vh;padding-bottom:calc(70.00px + 0px)}.hero{padding:22.00px 16.00px 27.00px;background:linear-gradient(140deg,var(--color-primary-lighter),var(--color-warning-light));position:relative;overflow:hidden}.eyebrow{display:inline-flex;padding:3.50px 7.00px;border-radius:499.50px;background:rgba(255,255,255,.72);color:var(--color-primary-strong);font-size:12.00px}.hero-title{display:block;margin-top:9.00px;font-size:20.00px;font-weight:700;line-height:1.35}.hero-desc{display:block;width:82%;margin-top:7.00px;font-size:12.50px;color:var(--color-text-secondary);line-height:1.7}.content{padding:0 var(--spacing-page-x)}.block{margin-top:var(--spacing-section)}.block-title{display:block;font-size:15.50px;font-weight:600}.block-subtitle{display:block;margin-top:4.00px;font-size:12.00px;color:var(--color-text-tertiary)}.card{margin-top:9.00px;padding:14.00px;background:var(--color-bg-card);border:0.50px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-card)}.feature-row,.menu-row,.record-row{display:flex;align-items:center;gap:10.00px;min-height:56.00px;padding:9.00px 0;border-bottom:0.50px solid var(--color-divider)}.feature-row:last-child,.menu-row:last-child,.record-row:last-child{border-bottom:0}.feature-icon{width:36.00px;height:36.00px;display:flex;align-items:center;justify-content:center;flex:none;border-radius:11.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-weight:700}.feature-copy{flex:1;min-width:0}.feature-title{display:block;font-size:14.00px;font-weight:600}.feature-desc,.meta{display:block;margin-top:3.50px;font-size:12.00px;color:var(--color-text-tertiary);line-height:1.55}.arrow{font-size:20.00px;color:var(--color-text-disabled)}.tag{display:inline-flex;margin-right:5.00px;margin-top:5.00px;padding:3.00px 6.50px;border-radius:499.50px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px}.tag.warning{background:var(--color-warning-light);color:var(--color-warning-strong)}.primary-btn,.secondary-btn{height:44.00px;display:flex;align-items:center;justify-content:center;border-radius:22.00px;font-size:14.00px;font-weight:600}.primary-btn{background:var(--gradient-brand-solid);color:var(--color-text-inverse);box-shadow:0 5.00px 12.00px rgba(255,92,130,.22)}.primary-btn.disabled{background:var(--color-bg-muted);color:var(--color-text-tertiary);box-shadow:none}.secondary-btn{background:var(--color-primary-light);color:var(--color-primary-strong)}.fixed-action{position:fixed;left:0;right:0;bottom:0;padding:9.00px var(--spacing-page-x) calc(9.00px + 0px);background:rgba(255,255,255,.96);border-top:0.50px solid var(--color-divider);z-index:100}.field{margin-top:13.00px}.label{display:block;margin-bottom:6.00px;font-size:12.50px;font-weight:600}.input,.select-box,.textarea{width:100%;box-sizing:border-box;background:var(--color-bg-page);border:0.50px solid var(--color-border);border-radius:var(--radius-md);font-size:13.00px}.input,.select-box{height:44.00px;padding:0 12.00px;display:flex;align-items:center}.textarea{min-height:90.00px;padding:11.00px}.notice{margin-top:10.00px;padding:11.00px;border-radius:var(--radius-md);background:var(--color-info-light);color:var(--color-text-secondary);font-size:12.00px;line-height:1.65}.select-box.is-readonly{background:var(--color-bg-subtle);color:var(--color-text-secondary)}.empty-panel{text-align:center;padding:35.00px 15.00px}.empty-symbol{width:48.00px;height:48.00px;margin:auto;display:flex;align-items:center;justify-content:center;border-radius:15.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-size:18.00px;font-weight:700}.empty-title{display:block;margin-top:11.00px;font-size:15.00px;font-weight:600}.article-card{margin-top:9.00px;background:var(--color-bg-card);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-card)}.article-cover{height:110.00px;padding:12.00px;background:linear-gradient(135deg,var(--color-warning-light),var(--color-warning-light));display:flex;align-items:flex-end}.article-cover text{font-size:21.00px;color:rgba(125,76,63,.52);font-weight:700}.article-body{padding:12.00px}.article-title{display:block;font-size:14.50px;font-weight:600;line-height:1.45}.article-meta{display:block;margin-top:5.00px;font-size:12.00px;color:var(--color-text-tertiary)}.article-content{padding:16.00px;background:var(--color-bg-card);font-size:14.00px;line-height:1.9;color:var(--color-text-secondary)}.article-content .lead{display:block;font-size:15.50px;color:var(--color-text-primary);font-weight:600;margin-bottom:12.00px}.danger-card{background:var(--color-primary-lighter);border-color:var(--color-primary-light)}.danger-card .feature-icon{background:var(--color-warning-light);color:var(--color-warning-strong)}@media(max-width:340px){.hero-title{font-size:18.00px}.hero-desc{width:92%}}
.service-shell{min-height:100vh;padding-bottom:calc(68.00px + 0px);background:var(--color-bg-page)}.service-content{padding:4.00px 12.00px 18.00px}.service-status{display:flex;align-items:center;justify-content:space-between;margin-top:12.00px;padding:10.00px 12.00px;border-radius:11.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-status__label{color:var(--color-text-tertiary);font-size:12.00px}.service-status__value{padding:3.00px 7.00px;border-radius:9.00px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px;font-weight:600}.service-status__value.disabled{background:var(--color-danger-light);color:var(--color-danger-strong)}.service-topics{display:grid;grid-template-columns:repeat(2,1fr);gap:8.00px;margin-top:9.00px}.service-topic{min-height:74.00px;padding:10.00px;border-radius:12.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-topic__icon{display:flex;align-items:center;justify-content:center;width:27.00px;height:27.00px;border-radius:8.50px;background:var(--color-primary-light)}.service-topic__icon image{width:17.00px;height:17.00px}.service-topic__title{display:block;margin-top:6.50px;color:var(--color-text-strong);font-size:12.00px;font-weight:600}.service-topic__desc{display:block;margin-top:3.00px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}.service-actions{display:flex;gap:7.00px}.service-actions .secondary-btn{width:95.00px;flex:none}.service-actions .primary-btn{flex:1}.privacy-note{display:flex;align-items:flex-start;gap:7.00px;margin-top:11.00px;padding:10.00px;border-radius:11.00px;background:var(--color-info-light);color:var(--color-text-tertiary);font-size:12.00px;line-height:1.55}.privacy-note image{width:17.00px;height:17.00px;flex:none}
/* ==== miniapp/components/nav-bar ==== */
/* --nav-h / --nav-right 由 index.js 实测胶囊按钮矩形后注入(见 utils/nav-metrics.js) */
.ui-nav {
position:sticky;
top:0;
left:0;
width:100%;
z-index:var(--z-sticky);
box-sizing:border-box;
}
.ui-nav--card {
background:var(--color-bg-card);
border-bottom:0.50px solid var(--color-divider);
}
.ui-nav--transparent {
background:transparent;
}
.ui-nav__bar {
position:relative;
display:flex;
align-items:center;
justify-content:space-between;
height:var(--nav-h, 44.00px);
padding:0 var(--spacing-2);
}
.ui-nav__back,
.ui-nav__placeholder {
width:32.00px;
min-height:var(--tap-min);
display:flex;
align-items:center;
justify-content:center;
flex-shrink:0;
min-width:var(--tap-min);}
.ui-nav__back-icon {
width:18.00px;
height:18.00px;
}
/* 标题绝对居中:max-width 左右各让开一个胶囊安全区,因此
(1)文字精确居中于屏幕,不受返回键/右侧操作宽度影响;
(2)不会伸到胶囊下面;
(3)盒子只覆盖文字自身,不会挡住返回键与右侧 slot 的点击。 */
.ui-nav__title {
position:absolute;
left:50%;
top:50%;
transform:translate(-50%, -50%);
max-width:calc(100% - 2 * var(--nav-right, 96.00px));
box-sizing:border-box;
text-align:center;
font-size:var(--font-size-lg);
font-weight:var(--font-weight-semibold);
color:var(--color-text-primary);
overflow:hidden;
white-space:nowrap;
text-overflow:ellipsis;
}
.ui-nav__right {
flex-shrink:0;
min-width:32.00px;
/* 右侧操作整体左移到胶囊左侧,否则会被胶囊盖住点不到 */
padding-right:var(--nav-right, 0);
display:flex;
align-items:center;
justify-content:flex-end;
}
/* ==== miniapp/components/section-header ==== */
/**
* 区块标题(全站所有页面共用,是排版层级的关键一环)
*
* 2026-09-22 修订:
* 1) 层级拉开:标题 18.00px→20.00px(--font-size-xl),与正文 16.00px / 卡片标题 14.00px
* 形成「区块标题 > 卡片标题 > 正文 > 元信息」四级阶梯。
* 旧值 18.00px 与卡片标题仅差 5.00px,层级读不出来。
* 2) 右侧 action 是全站最容易被忽略的触摸目标:只有 13.00px 文字高(约 13px),
* 远低于 44px 下限。改为 min-height:--tap-min,热区向上补白。
* 3) action 文字色原为 --color-primary(#E96B6B)=3.10:1,不达标,改 -strong。
*/
.ui-section {
display:flex;
align-items:center;
justify-content:space-between;
padding:var(--spacing-2) var(--spacing-page-x);
}
.ui-section__left {
display:flex;
align-items:baseline;
min-width:0;
}
.ui-section__title {
font-size:var(--font-size-xl);
font-weight:var(--font-weight-semibold);
color:var(--color-text-strong);
letter-spacing:var(--letter-spacing-tight);
}
.ui-section__subtitle {
margin-left:var(--spacing-2);
font-size:var(--font-size-xs);
color:var(--color-text-tertiary);
}
.ui-section__action {
display:flex;
align-items:center;
flex:none;
min-height:var(--tap-min);
padding-left:var(--spacing-3);
font-size:var(--font-size-sm);
font-weight:var(--font-weight-medium);
color:var(--color-primary-strong);
transition:opacity var(--motion-fast) var(--ease-standard);
}
.ui-section__action:active {
opacity:var(--press-opacity);
}
.ui-section__arrow {
margin-left:2.00px;
width:12.00px;
height:12.00px;
}
/* ==== miniapp/components/matchmaker-card ==== */
.ui-mm {
background:var(--color-bg-card);
border-radius:13.00px;
padding:12.00px;
margin-top:5.00px;
box-shadow:0 4.00px 14.00px rgba(35,35,95,.06);
}
.ui-mm__header {
display:block;
}
.ui-mm__title-row {
display:flex;
justify-content:space-between;
align-items:center;
margin-bottom:var(--spacing-2);
}
.ui-mm__title {
font-size:var(--font-size-lg);
font-weight:var(--font-weight-semibold);
color:var(--color-text-primary);
}
.ui-mm__mm-info {
font-size:var(--font-size-md);
color:var(--color-text-secondary);
margin-bottom:var(--spacing-2);
}
.ui-mm__req {
padding:var(--spacing-2) var(--spacing-3);
background:var(--color-bg-disabled);
border-radius:var(--radius-sm);
margin-bottom:var(--spacing-2);
}
.ui-mm__req-label {
font-size:var(--font-size-xs);
color:var(--color-text-tertiary);
}
.ui-mm__req-content {
font-size:var(--font-size-sm);
color:var(--color-text-secondary);
line-height:var(--line-height-normal);
display:block;
margin-top:2.00px;
}
.ui-mm__follow-up {
font-size:var(--font-size-xs);
color:var(--color-text-tertiary);
}
.ui-mm__footer {
margin-top:var(--spacing-3);
padding-top:var(--spacing-3);
border-top:0.50px solid var(--color-divider);
}
/* ==== miniapp/components/button ==== */
/**
* Button 组件样式
* 引用全局 Design Token(addGlobalClass:true)
*
* 2026-09-22 修复:
* 1) 触摸目标:md 只有 40.00px(40px)、sm 只有 28.00px(28px),低于 44px 下限;
* text 变体更是 min-height:auto,几乎点不中。现统一以 --tap-min 兜底。
* 2) 对比度:主按钮背景原为 --color-primary(#E96B6B),白字仅 3.10:1。
* 改用 --color-primary-solid(#C24C50) = 4.73:1,视觉上仍是暖红。
* secondary/text 的红色文字同理从 3.10 提到 --color-primary-strong 的 5.33。
* 3) 危险按钮 --color-danger(#D94A4A) 白字 4.18:1 不达标,改用 -strong 变体。
* 4) 按压反馈统一走 --press-scale / --press-opacity,替代硬编码 0.98 / 0.85。
*/
.ui-btn {
display:inline-flex;
align-items:center;
justify-content:center;
box-sizing:border-box;
border-radius:var(--radius-full);
font-family:var(--font-family-cn);
font-weight:var(--font-weight-semibold);
text-align:center;
transition:transform var(--motion-fast) var(--ease-spring),
opacity var(--motion-fast) var(--ease-standard),
background-color var(--motion-fast) var(--ease-standard);
user-select:none;
line-height:1.2;
white-space:nowrap;
}
/* 尺寸:全部以 44×44px 为热区下限 */
.ui-btn--sm {
padding:7.00px 14.00px;
font-size:var(--font-size-sm);
min-height:var(--tap-min);
}
.ui-btn--md {
padding:10.00px 18.00px;
font-size:var(--font-size-base);
min-height:var(--tap-min);
}
.ui-btn--lg {
padding:13.00px 24.00px;
font-size:var(--font-size-lg);
min-height:var(--tap-comfortable);
}
/* 撑满 */
.ui-btn--block {
display:flex;
width:100%;
}
/* 变体 */
.ui-btn--primary {
background:var(--color-primary-solid);
color:var(--color-text-inverse);
}
.ui-btn--secondary {
background:var(--color-bg-card);
color:var(--color-primary-strong);
border:var(--border-width) solid var(--color-primary-strong);
}
.ui-btn--ghost {
background:transparent;
color:var(--color-text-primary);
border:var(--border-width) solid var(--color-border-strong);
}
.ui-btn--danger {
background:var(--color-danger-strong);
color:var(--color-text-inverse);
}
.ui-btn--text {
background:transparent;
color:var(--color-primary-strong);
padding-left:var(--spacing-2);
padding-right:var(--spacing-2);
/* 视觉是纯文字,但热区仍需 44px:多出的部分由 align-items:center 居中留白 */
min-height:var(--tap-min);
}
/* 状态 */
.ui-btn--disabled,
.ui-btn--loading {
opacity:0.55;
}
.ui-btn--disabled.ui-btn--primary,
.ui-btn--disabled.ui-btn--danger {
background:var(--color-text-disabled);
}
.ui-btn--disabled.ui-btn--secondary,
.ui-btn--disabled.ui-btn--ghost {
color:var(--color-text-disabled);
border-color:var(--color-text-disabled);
}
/* 按压反馈(hover-class 与 CSS :active 双保险) */
.ui-btn--hover,
.ui-btn:active {
opacity:var(--press-opacity);
transform:scale(var(--press-scale));
}
/* Loading spinner */
.ui-btn__spinner {
width:14.00px;
height:14.00px;
margin-right:6.00px;
display:flex;
align-items:center;
justify-content:center;
}
.ui-btn__spinner-dot {
width:9.00px;
height:9.00px;
border-radius:50%;
border:1.50px solid currentColor;
border-top-color:transparent;
animation:ui-btn-spin 0.7s linear infinite;
}
@keyframes ui-btn-spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
/* ==== miniapp/components/loading ==== */
.ui-loading--block {
display:flex;
flex-direction:column;
align-items:center;
justify-content:center;
padding:var(--spacing-8) var(--spacing-page-x);
}
.ui-loading--inline {
display:inline-flex;
align-items:center;
}
.ui-loading__spinner {
width:30.00px;
height:30.00px;
display:flex;
align-items:center;
justify-content:center;
}
.ui-loading__spinner-icon {
width:24.00px;
height:24.00px;
animation:ui-loading-spin 0.8s linear infinite;
}
@keyframes ui-loading-spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
.ui-loading__text {
margin-top:var(--spacing-3);
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
}
/* Skeleton */
.ui-loading__skeleton {
width:100%;
}
.ui-loading__skeleton-row {
display:flex;
align-items:center;
padding:var(--spacing-3) var(--spacing-page-x);
background:var(--color-bg-card);
border-bottom:0.50px solid var(--color-divider);
}
.ui-loading__skeleton-avatar {
width:44.00px;
height:44.00px;
border-radius:50%;
background:var(--color-bg-disabled);
margin-right:var(--spacing-3);
flex-shrink:0;
}
.ui-loading__skeleton-content {
flex:1;
min-width:0;
}
.ui-loading__skeleton-line {
height:12.00px;
background:var(--color-bg-disabled);
border-radius:var(--radius-sm);
position:relative;
overflow:hidden;
}
.ui-loading__skeleton-line--title {
width:40%;
margin-bottom:var(--spacing-2);
}
.ui-loading__skeleton-line--meta {
width:70%;
}
/* shimmer */
.ui-loading__skeleton-line::after,
.ui-loading__skeleton-avatar::after {
content:'';
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background:linear-gradient(
90deg,
transparent 0%,
rgba(255, 255, 255, 0.55) 50%,
transparent 100%
);
animation:ui-loading-shimmer 1.4s ease-in-out infinite;
}
@keyframes ui-loading-shimmer {
0% { transform:translateX(-100%); }
100% { transform:translateX(100%); }
}
/* ==== miniapp/components/empty ==== */
.ui-empty {
display:flex;
flex-direction:column;
align-items:center;
padding:var(--spacing-10) var(--spacing-page-x);
text-align:center;
}
.ui-empty__illustration {
width:80.00px;
height:80.00px;
border-radius:50%;
background:var(--color-bg-disabled);
display:flex;
align-items:center;
justify-content:center;
margin-bottom:var(--spacing-4);
}
.ui-empty__icon {
width:36.00px;
height:36.00px;
opacity:0.72;
}
.ui-empty__title {
font-size:var(--font-size-lg);
font-weight:var(--font-weight-medium);
color:var(--color-text-primary);
margin-bottom:var(--spacing-2);
}
.ui-empty__desc {
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
line-height:var(--line-height-relaxed);
max-width:240.00px;
}
.ui-empty__actions {
display:flex;
flex-direction:column;
gap:var(--spacing-2);
margin-top:var(--spacing-6);
width:100%;
max-width:240.00px;
}
.ui-empty__action {
display:flex;
align-items:center;
justify-content:center;
min-height:var(--tap-min);
border-radius:var(--radius-full);
font-size:var(--font-size-base);
font-weight:var(--font-weight-medium);
min-width:var(--tap-min);}
.ui-empty__action--primary {
background:var(--color-primary-solid);
color:var(--color-text-inverse);
}
.ui-empty__action--secondary {
background:var(--color-bg-card);
color:var(--color-primary-strong);
border:0.50px solid var(--color-primary);
}
/* ==== miniapp/components/service-hero ==== */
.service-hero {
position:relative;
height:150.00px;
overflow:hidden;
border-radius:0 0 16.00px 16.00px;
background:var(--color-primary-light);
}
.service-hero__image,
.service-hero__veil {
position:absolute;
inset:0;
width:100%;
height:100%;
}
.service-hero__veil {
background:linear-gradient(90deg, rgba(255, 250, 252, 0.98) 0%, rgba(255, 250, 252, 0.82) 38%, rgba(255, 250, 252, 0.08) 70%);
}
.service-hero--night .service-hero__veil {
background:linear-gradient(90deg, rgba(18, 24, 83, 0.92) 0%, rgba(34, 31, 111, 0.64) 42%, rgba(34, 31, 111, 0.08) 72%);
}
.service-hero__content {
position:relative;
z-index:1;
display:flex;
flex-direction:column;
justify-content:center;
width:54%;
height:100%;
padding:0 18.00px;
box-sizing:border-box;
}
.service-hero__eyebrow {
margin-bottom:5.00px;
color:var(--color-primary-strong);
font-size:12.00px;
font-weight:600;
letter-spacing:1.00px;
}
.service-hero__title {
color:var(--color-text-strong);
font-size:20.00px;
font-weight:700;
line-height:1.28;
}
.service-hero__subtitle {
margin-top:7.00px;
color:var(--color-text-tertiary);
font-size:12.00px;
line-height:1.55;
}
.service-hero--night .service-hero__eyebrow,
.service-hero--night .service-hero__title,
.service-hero--night .service-hero__subtitle {
color:var(--color-text-inverse);
}
.mm-page{min-height:100vh;padding-bottom:calc(68.00px + 0px);background:var(--color-bg-page)}.mm-promises{position:relative;z-index:2;display:grid;grid-template-columns:repeat(3,1fr);margin:-11.00px 12.00px 0;padding:11.00px 4.00px;border-radius:14.00px;background:var(--color-bg-card);box-shadow:var(--mini-shadow)}.mm-promise{display:flex;flex-direction:column;align-items:center;padding:0 4.00px;text-align:center;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.35}.mm-promise image{width:23.00px;height:23.00px;margin-bottom:4.00px}.mm-promise__title{margin-bottom:2.00px;color:var(--color-text-strong);font-size:12.00px;font-weight:600}.mm-loading{padding:15.00px 12.00px}.mm-body{padding-top:4.00px}.mm-section{padding:4.00px 12.00px}.mm-no-service{display:flex;align-items:center;gap:9.00px;margin-top:5.00px;padding:12.00px;border-radius:13.00px;background:var(--color-bg-card);box-shadow:0 4.00px 14.00px rgba(35,35,95,.06)}.mm-no-service image{width:34.00px;height:34.00px}.mm-no-service>view{display:flex;flex:1;flex-direction:column}.mm-no-service__title{color:var(--color-text-strong);font-size:12.50px;font-weight:600}.mm-no-service__desc{margin-top:3.50px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.5}.mm-capability-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:7.00px;margin-top:5.00px}.mm-capability{display:flex;align-items:center;gap:6.00px;min-height:44.00px;padding:8.00px;border-radius:11.00px;background:var(--color-bg-card);color:var(--color-text-secondary);font-size:12.00px;line-height:1.4;box-shadow:0 4.00px 12.00px rgba(35,35,95,.05)}.mm-capability image{width:18.00px;height:18.00px;flex:none}.mm-history{overflow:hidden;margin-top:5.00px;border-radius:12.00px;background:var(--color-bg-card)}.mm-history__item{display:flex;align-items:center;min-height:46.00px;padding:0 10.00px;border-bottom:0.50px solid var(--color-divider)}.mm-history__item:last-child{border-bottom:0}.mm-history__item>view{display:flex;flex:1;flex-direction:column}.mm-history__title{color:var(--color-text-strong);font-size:12.00px;font-weight:600}.mm-history__meta{margin-top:2.50px;color:var(--color-text-tertiary);font-size:12.00px}.mm-history__status{margin-right:4.00px;color:var(--color-accent-purple-strong);font-size:12.00px}.mm-history__item>image{width:12.00px;height:12.00px}.mm-fixed-action{position:fixed;z-index:100;right:0;bottom:0;left:0;padding:9.00px 12.00px calc(9.00px + 0px);border-top:0.50px solid var(--color-divider);background:rgba(255,255,255,.96)}.mm-apply{display:flex;align-items:center;justify-content:center;height:44.00px;border-radius:22.00px;background:var(--gradient-brand-solid);color:var(--color-text-inverse);font-size:14.00px;font-weight:600;box-shadow:0 5.00px 12.00px rgba(255,92,130,.22)}
/**
* 丹阳公益婚恋服务平台 - 全局 Design Token
*
* v2(2026-09-22 设计系统夯实)
* ---------------------------------------------------------------
* 本次修订针对审计发现的系统性问题,逐条给出依据:
*
* 1) 品牌色不能承载文字 → 引入「基础色 / -strong」分级
* #E96B6B on 白 = 3.10:1,白字 on #E96B6B = 3.10:1,on #FFF3F2 = 2.85:1,
* 三条路径都不满足正文 4.5:1。故:
* --color-primary 仅用于大色块、渐变、光晕、装饰(非文字)
* --color-primary-strong 用于文字、小图标、纯文字链接(5.33:1 ✓)
* --color-primary-solid 实心按钮底(白字 ≥4.5:1 ✓)
* 功能色(success/warning/danger/info)同此分级。
*
* 2) 次要文字对比度过低
* 旧 --color-text-tertiary(#777) = 4.48(on 白,勉强)/ #999 实测 2.85 却被用了 71 次。
* 现将三级文字压到 #646C85 = 5.22:1,占位符保留浅色(占位符非正文)。
*
* 3) 颜色碎片化
* 审计前全站 182 种 hex、770 次硬编码(54 种灰、60 种蓝紫、40 种红橙)。
* 本文件是唯一的颜色事实源;页面层禁止再写 hex,一律 var(--token)。
*
* 4) 触摸目标
* 组件库默认按钮只有 40px、小号 28px、"喜欢"按钮 31px。
* 统一以 --tap-min(44.00px=44px) 为下限,--tap-gap 为最小间距。
*
* 5) 动效几乎未落地(--motion-* 全站仅 5 次引用)
* 补充 --ease-spring 与 --press-scale,让点击有即时反馈。
*
* 6) 夜间氛围层缺失(参考图有明显的光晕/星点,代码只有纯渐变)
* 新增 --mini-glow-* / --mini-star / --mini-glass / --mini-hairline。
*
* 单位说明:rpx(375.00px = 屏幕宽度,0.50px ≈ 0.5px @375pt)
* 旧 token 名全部保留(88 个 wxss 共 909 处引用),只更新取值,避免大范围失效。
*/
.wx-page {
/* ============ 品牌主色(分级:色块 / 文字 / 实心按钮) ============ */
--color-primary: #E96B6B; /* 基础色:渐变、光晕、装饰、非文字图形 */
--color-primary-strong: #B8434A; /* 文字与小图标(5.33:1 on 白,4.91:1 on 浅粉底) */
--color-primary-solid: #C24C50; /* 实心按钮底(白字 4.62:1) */
--color-primary-active: #D95F5F; /* 按压态(配合 --color-primary 使用) */
--color-primary-light: #FFF3F2;
--color-primary-lighter: #FFF8F7;
/* ============ 小程序参考图品牌主题(夜间紫蓝) ============ */
--mini-night-start: #172A72;
--mini-night-end: #25104F;
--mini-night-soft: #3445A1;
--mini-accent-pink: #FF4F91; /* 点缀色:仅用于色块/装饰,不作正文 */
--mini-accent-coral: #FF6A78;
--mini-card-bg: rgba(255, 255, 255, 0.98);
--mini-text: #1F2744;
--mini-muted: #7D839B;
--mini-card-radius: 12.00px;
--mini-text-on-night: #FFFFFF; /* on 深底 13.04:1 ✓ */
--mini-text-on-night-muted: rgba(255, 255, 255, 0.72); /* on 深底 ≈8:1 ✓ */
--mini-shadow: 0 8.00px 20.00px rgba(28, 30, 88, 0.14);
/* ---- 渐变(集中定义:此前 4 个页面各写了一份「橙红渐变」按钮) ---- */
/* --gradient-brand 明亮活泼,但白字仅 2.77:1 —— 只能用于无文字的装饰填充。 */
--gradient-brand: linear-gradient(135deg, #FF6A78 0%, #E96B6B 100%);
/* 承载白字的 CTA 渐变:两端 #C24C50(4.73:1) / #B8434A(5.33:1) 均达标。 */
--gradient-brand-solid: linear-gradient(135deg, #C24C50 0%, #B8434A 100%);
--gradient-night: linear-gradient(160deg, #172A72 0%, #25104F 100%);
--gradient-night-soft: linear-gradient(160deg, #3445A1 0%, #172A72 100%);
/* ---- 首页 4×2 入口宫格图标渐变(参考图 2:高饱和圆角砖 + 白色描画图标) ----
白图标的对比度判据是**非文本图形 3:1**(WCAG 1.4.11)。渐变是斜向的、图标又跨在
两色之间,所以**较亮的一端也必须达标** —— 下表注释给的是 0% 处实算值,100% 更暗只会更高。
色相按业务语义固定(不随 tone 名漂移):找对象/婚前辅导=玫瑰粉系、公益红娘/服务站=暖橙系、
公益活动=紫罗兰、婚恋咨询=蓝、婚恋课堂=紫、婚恋反诈=绿。 */
--gradient-entry-rose: linear-gradient(135deg, #F56287 0%, #F34671 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-orange: linear-gradient(135deg, #F66A06 0%, #D95E06 100%); /* 3.01:1 / 3.78:1 */
--gradient-entry-violet: linear-gradient(135deg, #A380F5 0%, #8F64F2 100%); /* 3.02:1 / 3.98:1 */
--gradient-entry-blue: linear-gradient(135deg, #5195F6 0%, #3484F4 100%); /* 3.01:1 / 3.65:1 */
--gradient-entry-purple: linear-gradient(135deg, #B27BF0 0%, #A260ED 100%); /* 3.01:1 / 3.87:1 */
--gradient-entry-pink: linear-gradient(135deg, #F2619E 0%, #F0458C 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-green: linear-gradient(135deg, #18A979 0%, #148F66 100%); /* 3.00:1 / 4.08:1 */
--gradient-entry-amber: linear-gradient(135deg, #E9740C 0%, #CC650B 100%); /* 3.01:1 / 3.86:1 */
/* 图标砖落影:比 --mini-shadow 更小,避免 4 列宫格里相邻砖块的投影互相压边 */
--mini-entry-shadow: 0 4.00px 9.00px rgba(28, 30, 88, 0.18);
/* ---- 夜间氛围层(v2 新增;参考图有光晕与星点,此前完全没有) ---- */
--mini-glow-coral: rgba(255, 79, 145, 0.40);
--mini-glow-indigo: rgba(94, 124, 255, 0.32);
--mini-glow-soft: rgba(255, 255, 255, 0.10);
--mini-star: rgba(255, 255, 255, 0.70);
--mini-glass: rgba(255, 255, 255, 0.10); /* 深底玻璃面 */
--mini-glass-strong: rgba(255, 255, 255, 0.16);
--mini-hairline: rgba(255, 255, 255, 0.16); /* 深底分隔线 */
--mini-glass-success: rgba(90, 226, 184, 0.16); /* 深底上的成功态玻璃面 */
/* 星点层:多个小径向渐变叠在夜空渐变之上。用 radial-gradient 而非图片,
避免额外请求,也便于随主题换色(index 页脚注:装饰层不承载信息)。 */
--mini-starfield:
radial-gradient(circle at 12% 18%, var(--mini-star) 0, transparent 1.25px),
radial-gradient(circle at 31% 66%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 57% 12%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 79% 52%, var(--mini-star) 0, transparent 1.50px),
radial-gradient(circle at 93% 84%, var(--mini-star) 0, transparent 1.00px);
/* 横幅压暗层:保证任何底图上的白色标题都有足够对比度 */
--mini-banner-scrim: linear-gradient(90deg, rgba(23, 42, 114, 0.84) 0%, rgba(37, 16, 79, 0.40) 56%, rgba(255, 79, 145, 0.12) 100%);
/* ============ 功能色(同样分级) ============ */
--color-success: #2E9B68; /* 色块/图标 */
--color-success-strong: #17805A; /* 文字(4.92:1 ✓) */
--color-success-light: #ECF8F2;
--color-warning: #E59A32; /* 色块/图标(作文字仅 2.33:1) */
--color-warning-strong: #9C5F14; /* 文字(5.17:1 ✓) */
--color-warning-light: #FFF7E9;
--color-danger: #D94A4A; /* 色块/图标 */
--color-danger-strong: #C62828; /* 文字(5.62:1 ✓) */
--color-danger-light: #FFF0F0;
--color-info: #4A7CD4; /* 色块/图标 */
--color-info-strong: #2A5DB0; /* 文字(6.38:1 ✓) */
--color-info-light: #EEF4FF;
/* ============ 强调紫(参考图的标签语言;此前散落成 6 种写法) ============ */
--color-accent-purple: #8B63BC; /* 色块/装饰 */
--color-accent-purple-strong: #7C60BC; /* 文字(5.03:1 ✓) */
--color-accent-purple-light: #F3EEFF;
/* 深色夜空底上的强调色(不可用于浅色底) */
--color-success-on-night: #A6F5D7; /* on #172A72 = 10.35:1 ✓ */
/* ============ 文字色(实测对比度 on 白 / on 页面底) ============ */
--color-text-strong: #1A1F36; /* 标题 16.24 / 14.90 ✓ */
--color-text-primary: #2A3050; /* 正文 12.83 / 11.77 ✓ */
--color-text-secondary: #4A5169; /* 次要正文 7.86 / 7.21 ✓ */
--color-text-tertiary: #646C85; /* 说明文字 5.22 / 4.79 ✓(旧 #777 为 4.48) */
--color-text-placeholder: #9AA1B4; /* 占位符(非正文,可浅) */
--color-text-disabled: #B8BDC9;
--color-text-inverse: #FFFFFF; /* 深色背景上的文字 */
/* ============ 边框与分割线 ============ */
--color-border: #E6E8EF;
--color-border-strong: #D8DBE5;
--color-divider: #EFF0F5;
--color-border-focus: #B8434A; /* 焦点环用 strong,保证 3:1 可见度 */
--color-border-error: #C62828;
/* ============ 背景(避免纯白/纯灰平铺,页面底为暖白) ============ */
--color-bg-page: #F6F5F3;
--color-bg-card: #FFFFFF;
--color-bg-subtle: #F5F6FA; /* 次级区块、内嵌列表 */
--color-bg-muted: #EEF0F6; /* 更弱的填充 */
--color-bg-input: #F7F8FB; /* 表单输入框底(此前被引用但从未定义,导致背景失效) */
--color-bg-disabled: #F3F4F7;
--color-bg-overlay: rgba(0, 0, 0, 0.45);
/* ============ 字体 ============ */
/* 小程序无法可靠加载 Web Font(wx.loadFontFace 依赖 HTTPS 白名单且有闪动风险),
故使用中文系统字栈:iOS 走苹方、Android 走思源/系统黑体。
排版辨识度靠字号阶梯与字重建立,而非依赖字体本身。 */
--font-family-cn: -apple-system, "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
--font-family-number: "SF Pro Display", -apple-system, "DIN Alternate", "PingFang SC", sans-serif;
/* 字号阶梯 —— 正文 16.00px(16px) 起,元信息下限 12.00px(12px) */
--font-size-micro: 11.00px; /* 11px 仅角标/装饰,禁用于正文 */
--font-size-xs: 12.00px; /* 12px 元信息下限 */
--font-size-sm: 13.00px; /* 13px 次要说明 */
--font-size-md: 14.00px; /* 14px 次要正文 */
--font-size-base: 16.00px; /* 16px 正文 */
--font-size-lg: 18.00px; /* 18px 小标题 */
--font-size-xl: 20.00px; /* 20px 区块标题 */
--font-size-2xl: 24.00px; /* 24px 页面标题 */
--font-size-3xl: 28.00px; /* 28px 大标题 */
--font-size-display: 32.00px; /* 32px Hero */
/* 字重:只用 4 档。禁止 550/650/750 等非百位值 —— Android 无对应字重会回退,
导致同一设计在不同机型上粗细不一致(审计发现 30 处)。 */
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.65;
--letter-spacing-tight: 0;
--letter-spacing-wide: 0.50px;
--letter-spacing-wider: 1.00px;
/* ============ 间距(4px 栅格) ============ */
--spacing-1: 4.00px;
--spacing-2: 8.00px;
--spacing-3: 12.00px;
--spacing-4: 16.00px;
--spacing-5: 20.00px;
--spacing-6: 24.00px;
--spacing-8: 32.00px;
--spacing-10: 40.00px;
--spacing-12: 48.00px;
--spacing-page-x: 16.00px;
--spacing-section: 24.00px;
--spacing-card-inner: 16.00px;
--spacing-tight: 8.00px;
/* ============ 圆角 ============ */
--radius-sm: 8.00px;
--radius-md: 12.00px;
--radius-lg: 16.00px;
--radius-xl: 20.00px;
--radius-2xl: 24.00px;
--radius-full: 4999.50px;
/* ============ 阴影(统一为一套,此前 30+ 种近似值) ============ */
--shadow-card: 0 4.00px 14.00px rgba(35, 35, 95, 0.07);
--shadow-raised: 0 6.00px 18.00px rgba(35, 35, 95, 0.10);
--shadow-popup: 0 8.00px 32.00px rgba(0, 0, 0, 0.10);
--shadow-night: 0 8.00px 20.00px rgba(28, 30, 88, 0.18);
/* ============ 边框宽度 ============ */
--border-width: 0.50px;
--border-width-strong: 1.00px;
/* ============ 触摸目标(无障碍下限 44×44px) ============ */
--tap-min: 44.00px; /* 44px 最小可点区域 */
--tap-comfortable: 48.00px; /* 48px 舒适尺寸:主操作 */
--tap-gap: 8.00px; /* 8px 相邻目标最小间距 */
/* ============ 动效 ============ */
--motion-fast: 120ms;
--motion-normal: 200ms;
--motion-slow: 300ms;
--ease-standard: cubic-bezier(0.32, 0.72, 0, 1);
--ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
--press-scale: 0.97;
--press-opacity: 0.88;
/* ============ 层级 z-index ============ */
--z-base: 1;
--z-sticky: 100;
--z-tabbar: 200;
--z-dropdown: 500;
--z-modal: 1000;
--z-toast: 2000;
--z-ambient: 0;
/* ============ 页面基础样式 ============ */
background-color: var(--color-bg-page);
font-family: var(--font-family-cn);
font-size: var(--font-size-base);
color: var(--color-text-primary);
line-height: var(--line-height-normal);
}
/* ==========================================================================
通用工具类
========================================================================== */
.container {
padding: var(--spacing-page-x);
}
.flex { display: flex; }
.flex-column { display: flex; flex-direction: column; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-start { display: flex; align-items: center; justify-content: flex-start; }
.flex-1 { flex: 1; min-width: 0; }
.flex-shrink-0 { flex-shrink: 0; }
.wrap { flex-wrap: wrap; }
/* 4 列宫格:用 flex + 百分比宽度实现。
注:display:grid 在 WebView 渲染下可用,但 Skyline 不支持,故统一改为 flex 以免疫渲染引擎迁移。*/
.grid-4 {
display: flex;
flex-wrap: wrap;
}
.grid-4 > .grid-item {
width: 25%;
box-sizing: border-box;
}
.text-strong { color: var(--color-text-strong); }
.text-primary { color: var(--color-text-primary); }
.text-secondary { color: var(--color-text-secondary); }
.text-tertiary { color: var(--color-text-tertiary); }
.text-placeholder { color: var(--color-text-placeholder); }
.text-white { color: var(--color-text-inverse); }
.text-brand { color: var(--color-primary-strong); }
/* 品牌色作文字只能用 -strong 变体:基础色 #E96B6B 在白底仅 3.10:1。
保留 .text-brand-soft 这个类名是为了不破坏既有引用,取值已统一到 -strong,
如需「更亮的品牌色」请用于背景/图形而非文字。 */
.text-brand-soft { color: var(--color-primary-strong); }
.text-success { color: var(--color-success-strong); }
.text-warning { color: var(--color-warning-strong); }
.text-danger { color: var(--color-danger-strong); }
.text-info { color: var(--color-info-strong); }
.font-micro { font-size: var(--font-size-micro); }
.font-xs { font-size: var(--font-size-xs); }
.font-sm { font-size: var(--font-size-sm); }
.font-md { font-size: var(--font-size-md); }
.font-base { font-size: var(--font-size-base); }
.font-lg { font-size: var(--font-size-lg); }
.font-xl { font-size: var(--font-size-xl); }
.font-2xl { font-size: var(--font-size-2xl); }
.font-3xl { font-size: var(--font-size-3xl); }
.font-display { font-size: var(--font-size-display); }
.font-regular { font-weight: var(--font-weight-regular); }
.font-medium { font-weight: var(--font-weight-medium); }
.font-semibold { font-weight: var(--font-weight-semibold); }
.font-bold { font-weight: var(--font-weight-bold); }
.mt-1 { margin-top: var(--spacing-1); }
.mt-2 { margin-top: var(--spacing-2); }
.mt-3 { margin-top: var(--spacing-3); }
.mt-4 { margin-top: var(--spacing-4); }
.mt-5 { margin-top: var(--spacing-5); }
.mt-6 { margin-top: var(--spacing-6); }
.mb-1 { margin-bottom: var(--spacing-1); }
.mb-2 { margin-bottom: var(--spacing-2); }
.mb-3 { margin-bottom: var(--spacing-3); }
.mb-4 { margin-bottom: var(--spacing-4); }
.mb-5 { margin-bottom: var(--spacing-5); }
.mb-6 { margin-bottom: var(--spacing-6); }
/* 文本省略 */
.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ellipsis-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
/* 安全区底部留白(避开 Home Indicator) */
.safe-area-bottom {
padding-bottom: 0px;
}
/* 页面卡片基础样式 */
.card-base {
background: var(--color-bg-card);
border-radius: var(--radius-lg);
padding: var(--spacing-card-inner);
box-shadow: var(--shadow-card);
}
/* 分割线 */
.divider {
height: var(--border-width);
background: var(--color-divider);
}
/* ==========================================================================
可访问性:只用 token,不用工具类(2026-09-23 修订)
--------------------------------------------------------------------------
v2 曾在此处新增 .tap-min / .tap-gap / .focusable / .pressable 四个工具类。
复检发现全部零引用(等价能力已各自写在组件样式内,例如 button/index.wxss
直接使用 min-height:var(--tap-min)),且存在两个硬问题:
1) `.tap-gap > * + *` 用了通配符与兄弟选择器 —— WXSS 不支持,
wcc 编译期直接报 `error at token '*'`,导致整个小程序编译失败。
(这是编译错误,不是静默失效,代价最高。)
2) `.pressable:active` / `.focusable:focus-visible` 的伪类在 view 上
不生效(小程序须用 hover-class),属于"写了等于没写"。
故整块移除,保留 token。需要热区/间距时直接引用 token:
min-height: var(--tap-min); → 44.00px = 44px,最小可点区域
gap: var(--tap-gap); → 8.00px = 8px,相邻目标间距(flex gap)
【WXSS 禁用清单】星号通配符、兄弟选择器、属性选择器。
【注释约束】WXSS 注释**不可嵌套**:内层注释的结束标记会提前终止外层注释,
其后的文字会被当成真实样式解析,导致编译失败或样式被污染。
(2026-09-23 实证:本块注释初版即踩此坑。)
========================================================================== */
.wx-page{background:var(--color-bg-page)}.service-page{min-height:100vh;padding-bottom:calc(70.00px + 0px)}.hero{padding:22.00px 16.00px 27.00px;background:linear-gradient(140deg,var(--color-primary-lighter),var(--color-warning-light));position:relative;overflow:hidden}.eyebrow{display:inline-flex;padding:3.50px 7.00px;border-radius:499.50px;background:rgba(255,255,255,.72);color:var(--color-primary-strong);font-size:12.00px}.hero-title{display:block;margin-top:9.00px;font-size:20.00px;font-weight:700;line-height:1.35}.hero-desc{display:block;width:82%;margin-top:7.00px;font-size:12.50px;color:var(--color-text-secondary);line-height:1.7}.content{padding:0 var(--spacing-page-x)}.block{margin-top:var(--spacing-section)}.block-title{display:block;font-size:15.50px;font-weight:600}.block-subtitle{display:block;margin-top:4.00px;font-size:12.00px;color:var(--color-text-tertiary)}.card{margin-top:9.00px;padding:14.00px;background:var(--color-bg-card);border:0.50px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-card)}.feature-row,.menu-row,.record-row{display:flex;align-items:center;gap:10.00px;min-height:56.00px;padding:9.00px 0;border-bottom:0.50px solid var(--color-divider)}.feature-row:last-child,.menu-row:last-child,.record-row:last-child{border-bottom:0}.feature-icon{width:36.00px;height:36.00px;display:flex;align-items:center;justify-content:center;flex:none;border-radius:11.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-weight:700}.feature-copy{flex:1;min-width:0}.feature-title{display:block;font-size:14.00px;font-weight:600}.feature-desc,.meta{display:block;margin-top:3.50px;font-size:12.00px;color:var(--color-text-tertiary);line-height:1.55}.arrow{font-size:20.00px;color:var(--color-text-disabled)}.tag{display:inline-flex;margin-right:5.00px;margin-top:5.00px;padding:3.00px 6.50px;border-radius:499.50px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px}.tag.warning{background:var(--color-warning-light);color:var(--color-warning-strong)}.primary-btn,.secondary-btn{height:44.00px;display:flex;align-items:center;justify-content:center;border-radius:22.00px;font-size:14.00px;font-weight:600}.primary-btn{background:var(--gradient-brand-solid);color:var(--color-text-inverse);box-shadow:0 5.00px 12.00px rgba(255,92,130,.22)}.primary-btn.disabled{background:var(--color-bg-muted);color:var(--color-text-tertiary);box-shadow:none}.secondary-btn{background:var(--color-primary-light);color:var(--color-primary-strong)}.fixed-action{position:fixed;left:0;right:0;bottom:0;padding:9.00px var(--spacing-page-x) calc(9.00px + 0px);background:rgba(255,255,255,.96);border-top:0.50px solid var(--color-divider);z-index:100}.field{margin-top:13.00px}.label{display:block;margin-bottom:6.00px;font-size:12.50px;font-weight:600}.input,.select-box,.textarea{width:100%;box-sizing:border-box;background:var(--color-bg-page);border:0.50px solid var(--color-border);border-radius:var(--radius-md);font-size:13.00px}.input,.select-box{height:44.00px;padding:0 12.00px;display:flex;align-items:center}.textarea{min-height:90.00px;padding:11.00px}.notice{margin-top:10.00px;padding:11.00px;border-radius:var(--radius-md);background:var(--color-info-light);color:var(--color-text-secondary);font-size:12.00px;line-height:1.65}.select-box.is-readonly{background:var(--color-bg-subtle);color:var(--color-text-secondary)}.empty-panel{text-align:center;padding:35.00px 15.00px}.empty-symbol{width:48.00px;height:48.00px;margin:auto;display:flex;align-items:center;justify-content:center;border-radius:15.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-size:18.00px;font-weight:700}.empty-title{display:block;margin-top:11.00px;font-size:15.00px;font-weight:600}.article-card{margin-top:9.00px;background:var(--color-bg-card);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-card)}.article-cover{height:110.00px;padding:12.00px;background:linear-gradient(135deg,var(--color-warning-light),var(--color-warning-light));display:flex;align-items:flex-end}.article-cover text{font-size:21.00px;color:rgba(125,76,63,.52);font-weight:700}.article-body{padding:12.00px}.article-title{display:block;font-size:14.50px;font-weight:600;line-height:1.45}.article-meta{display:block;margin-top:5.00px;font-size:12.00px;color:var(--color-text-tertiary)}.article-content{padding:16.00px;background:var(--color-bg-card);font-size:14.00px;line-height:1.9;color:var(--color-text-secondary)}.article-content .lead{display:block;font-size:15.50px;color:var(--color-text-primary);font-weight:600;margin-bottom:12.00px}.danger-card{background:var(--color-primary-lighter);border-color:var(--color-primary-light)}.danger-card .feature-icon{background:var(--color-warning-light);color:var(--color-warning-strong)}@media(max-width:340px){.hero-title{font-size:18.00px}.hero-desc{width:92%}}
.service-shell{min-height:100vh;padding-bottom:calc(68.00px + 0px);background:var(--color-bg-page)}.service-content{padding:4.00px 12.00px 18.00px}.service-status{display:flex;align-items:center;justify-content:space-between;margin-top:12.00px;padding:10.00px 12.00px;border-radius:11.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-status__label{color:var(--color-text-tertiary);font-size:12.00px}.service-status__value{padding:3.00px 7.00px;border-radius:9.00px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px;font-weight:600}.service-status__value.disabled{background:var(--color-danger-light);color:var(--color-danger-strong)}.service-topics{display:grid;grid-template-columns:repeat(2,1fr);gap:8.00px;margin-top:9.00px}.service-topic{min-height:74.00px;padding:10.00px;border-radius:12.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-topic__icon{display:flex;align-items:center;justify-content:center;width:27.00px;height:27.00px;border-radius:8.50px;background:var(--color-primary-light)}.service-topic__icon image{width:17.00px;height:17.00px}.service-topic__title{display:block;margin-top:6.50px;color:var(--color-text-strong);font-size:12.00px;font-weight:600}.service-topic__desc{display:block;margin-top:3.00px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}.service-actions{display:flex;gap:7.00px}.service-actions .secondary-btn{width:95.00px;flex:none}.service-actions .primary-btn{flex:1}.privacy-note{display:flex;align-items:flex-start;gap:7.00px;margin-top:11.00px;padding:10.00px;border-radius:11.00px;background:var(--color-info-light);color:var(--color-text-tertiary);font-size:12.00px;line-height:1.55}.privacy-note image{width:17.00px;height:17.00px;flex:none}
/* ==== miniapp/components/service-hero ==== */
.service-hero {
position:relative;
height:150.00px;
overflow:hidden;
border-radius:0 0 16.00px 16.00px;
background:var(--color-primary-light);
}
.service-hero__image,
.service-hero__veil {
position:absolute;
inset:0;
width:100%;
height:100%;
}
.service-hero__veil {
background:linear-gradient(90deg, rgba(255, 250, 252, 0.98) 0%, rgba(255, 250, 252, 0.82) 38%, rgba(255, 250, 252, 0.08) 70%);
}
.service-hero--night .service-hero__veil {
background:linear-gradient(90deg, rgba(18, 24, 83, 0.92) 0%, rgba(34, 31, 111, 0.64) 42%, rgba(34, 31, 111, 0.08) 72%);
}
.service-hero__content {
position:relative;
z-index:1;
display:flex;
flex-direction:column;
justify-content:center;
width:54%;
height:100%;
padding:0 18.00px;
box-sizing:border-box;
}
.service-hero__eyebrow {
margin-bottom:5.00px;
color:var(--color-primary-strong);
font-size:12.00px;
font-weight:600;
letter-spacing:1.00px;
}
.service-hero__title {
color:var(--color-text-strong);
font-size:20.00px;
font-weight:700;
line-height:1.28;
}
.service-hero__subtitle {
margin-top:7.00px;
color:var(--color-text-tertiary);
font-size:12.00px;
line-height:1.55;
}
.service-hero--night .service-hero__eyebrow,
.service-hero--night .service-hero__title,
.service-hero--night .service-hero__subtitle {
color:var(--color-text-inverse);
}
/* ==== miniapp/components/loading ==== */
.ui-loading--block {
display:flex;
flex-direction:column;
align-items:center;
justify-content:center;
padding:var(--spacing-8) var(--spacing-page-x);
}
.ui-loading--inline {
display:inline-flex;
align-items:center;
}
.ui-loading__spinner {
width:30.00px;
height:30.00px;
display:flex;
align-items:center;
justify-content:center;
}
.ui-loading__spinner-icon {
width:24.00px;
height:24.00px;
animation:ui-loading-spin 0.8s linear infinite;
}
@keyframes ui-loading-spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
.ui-loading__text {
margin-top:var(--spacing-3);
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
}
/* Skeleton */
.ui-loading__skeleton {
width:100%;
}
.ui-loading__skeleton-row {
display:flex;
align-items:center;
padding:var(--spacing-3) var(--spacing-page-x);
background:var(--color-bg-card);
border-bottom:0.50px solid var(--color-divider);
}
.ui-loading__skeleton-avatar {
width:44.00px;
height:44.00px;
border-radius:50%;
background:var(--color-bg-disabled);
margin-right:var(--spacing-3);
flex-shrink:0;
}
.ui-loading__skeleton-content {
flex:1;
min-width:0;
}
.ui-loading__skeleton-line {
height:12.00px;
background:var(--color-bg-disabled);
border-radius:var(--radius-sm);
position:relative;
overflow:hidden;
}
.ui-loading__skeleton-line--title {
width:40%;
margin-bottom:var(--spacing-2);
}
.ui-loading__skeleton-line--meta {
width:70%;
}
/* shimmer */
.ui-loading__skeleton-line::after,
.ui-loading__skeleton-avatar::after {
content:'';
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background:linear-gradient(
90deg,
transparent 0%,
rgba(255, 255, 255, 0.55) 50%,
transparent 100%
);
animation:ui-loading-shimmer 1.4s ease-in-out infinite;
}
@keyframes ui-loading-shimmer {
0% { transform:translateX(-100%); }
100% { transform:translateX(100%); }
}
@import "../../styles/service-page.wxss";
/**
* 丹阳公益婚恋服务平台 - 全局 Design Token
*
* v2(2026-09-22 设计系统夯实)
* ---------------------------------------------------------------
* 本次修订针对审计发现的系统性问题,逐条给出依据:
*
* 1) 品牌色不能承载文字 → 引入「基础色 / -strong」分级
* #E96B6B on 白 = 3.10:1,白字 on #E96B6B = 3.10:1,on #FFF3F2 = 2.85:1,
* 三条路径都不满足正文 4.5:1。故:
* --color-primary 仅用于大色块、渐变、光晕、装饰(非文字)
* --color-primary-strong 用于文字、小图标、纯文字链接(5.33:1 ✓)
* --color-primary-solid 实心按钮底(白字 ≥4.5:1 ✓)
* 功能色(success/warning/danger/info)同此分级。
*
* 2) 次要文字对比度过低
* 旧 --color-text-tertiary(#777) = 4.48(on 白,勉强)/ #999 实测 2.85 却被用了 71 次。
* 现将三级文字压到 #646C85 = 5.22:1,占位符保留浅色(占位符非正文)。
*
* 3) 颜色碎片化
* 审计前全站 182 种 hex、770 次硬编码(54 种灰、60 种蓝紫、40 种红橙)。
* 本文件是唯一的颜色事实源;页面层禁止再写 hex,一律 var(--token)。
*
* 4) 触摸目标
* 组件库默认按钮只有 40px、小号 28px、"喜欢"按钮 31px。
* 统一以 --tap-min(44.00px=44px) 为下限,--tap-gap 为最小间距。
*
* 5) 动效几乎未落地(--motion-* 全站仅 5 次引用)
* 补充 --ease-spring 与 --press-scale,让点击有即时反馈。
*
* 6) 夜间氛围层缺失(参考图有明显的光晕/星点,代码只有纯渐变)
* 新增 --mini-glow-* / --mini-star / --mini-glass / --mini-hairline。
*
* 单位说明:rpx(375.00px = 屏幕宽度,0.50px ≈ 0.5px @375pt)
* 旧 token 名全部保留(88 个 wxss 共 909 处引用),只更新取值,避免大范围失效。
*/
.wx-page {
/* ============ 品牌主色(分级:色块 / 文字 / 实心按钮) ============ */
--color-primary: #E96B6B; /* 基础色:渐变、光晕、装饰、非文字图形 */
--color-primary-strong: #B8434A; /* 文字与小图标(5.33:1 on 白,4.91:1 on 浅粉底) */
--color-primary-solid: #C24C50; /* 实心按钮底(白字 4.62:1) */
--color-primary-active: #D95F5F; /* 按压态(配合 --color-primary 使用) */
--color-primary-light: #FFF3F2;
--color-primary-lighter: #FFF8F7;
/* ============ 小程序参考图品牌主题(夜间紫蓝) ============ */
--mini-night-start: #172A72;
--mini-night-end: #25104F;
--mini-night-soft: #3445A1;
--mini-accent-pink: #FF4F91; /* 点缀色:仅用于色块/装饰,不作正文 */
--mini-accent-coral: #FF6A78;
--mini-card-bg: rgba(255, 255, 255, 0.98);
--mini-text: #1F2744;
--mini-muted: #7D839B;
--mini-card-radius: 12.00px;
--mini-text-on-night: #FFFFFF; /* on 深底 13.04:1 ✓ */
--mini-text-on-night-muted: rgba(255, 255, 255, 0.72); /* on 深底 ≈8:1 ✓ */
--mini-shadow: 0 8.00px 20.00px rgba(28, 30, 88, 0.14);
/* ---- 渐变(集中定义:此前 4 个页面各写了一份「橙红渐变」按钮) ---- */
/* --gradient-brand 明亮活泼,但白字仅 2.77:1 —— 只能用于无文字的装饰填充。 */
--gradient-brand: linear-gradient(135deg, #FF6A78 0%, #E96B6B 100%);
/* 承载白字的 CTA 渐变:两端 #C24C50(4.73:1) / #B8434A(5.33:1) 均达标。 */
--gradient-brand-solid: linear-gradient(135deg, #C24C50 0%, #B8434A 100%);
--gradient-night: linear-gradient(160deg, #172A72 0%, #25104F 100%);
--gradient-night-soft: linear-gradient(160deg, #3445A1 0%, #172A72 100%);
/* ---- 首页 4×2 入口宫格图标渐变(参考图 2:高饱和圆角砖 + 白色描画图标) ----
白图标的对比度判据是**非文本图形 3:1**(WCAG 1.4.11)。渐变是斜向的、图标又跨在
两色之间,所以**较亮的一端也必须达标** —— 下表注释给的是 0% 处实算值,100% 更暗只会更高。
色相按业务语义固定(不随 tone 名漂移):找对象/婚前辅导=玫瑰粉系、公益红娘/服务站=暖橙系、
公益活动=紫罗兰、婚恋咨询=蓝、婚恋课堂=紫、婚恋反诈=绿。 */
--gradient-entry-rose: linear-gradient(135deg, #F56287 0%, #F34671 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-orange: linear-gradient(135deg, #F66A06 0%, #D95E06 100%); /* 3.01:1 / 3.78:1 */
--gradient-entry-violet: linear-gradient(135deg, #A380F5 0%, #8F64F2 100%); /* 3.02:1 / 3.98:1 */
--gradient-entry-blue: linear-gradient(135deg, #5195F6 0%, #3484F4 100%); /* 3.01:1 / 3.65:1 */
--gradient-entry-purple: linear-gradient(135deg, #B27BF0 0%, #A260ED 100%); /* 3.01:1 / 3.87:1 */
--gradient-entry-pink: linear-gradient(135deg, #F2619E 0%, #F0458C 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-green: linear-gradient(135deg, #18A979 0%, #148F66 100%); /* 3.00:1 / 4.08:1 */
--gradient-entry-amber: linear-gradient(135deg, #E9740C 0%, #CC650B 100%); /* 3.01:1 / 3.86:1 */
/* 图标砖落影:比 --mini-shadow 更小,避免 4 列宫格里相邻砖块的投影互相压边 */
--mini-entry-shadow: 0 4.00px 9.00px rgba(28, 30, 88, 0.18);
/* ---- 夜间氛围层(v2 新增;参考图有光晕与星点,此前完全没有) ---- */
--mini-glow-coral: rgba(255, 79, 145, 0.40);
--mini-glow-indigo: rgba(94, 124, 255, 0.32);
--mini-glow-soft: rgba(255, 255, 255, 0.10);
--mini-star: rgba(255, 255, 255, 0.70);
--mini-glass: rgba(255, 255, 255, 0.10); /* 深底玻璃面 */
--mini-glass-strong: rgba(255, 255, 255, 0.16);
--mini-hairline: rgba(255, 255, 255, 0.16); /* 深底分隔线 */
--mini-glass-success: rgba(90, 226, 184, 0.16); /* 深底上的成功态玻璃面 */
/* 星点层:多个小径向渐变叠在夜空渐变之上。用 radial-gradient 而非图片,
避免额外请求,也便于随主题换色(index 页脚注:装饰层不承载信息)。 */
--mini-starfield:
radial-gradient(circle at 12% 18%, var(--mini-star) 0, transparent 1.25px),
radial-gradient(circle at 31% 66%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 57% 12%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 79% 52%, var(--mini-star) 0, transparent 1.50px),
radial-gradient(circle at 93% 84%, var(--mini-star) 0, transparent 1.00px);
/* 横幅压暗层:保证任何底图上的白色标题都有足够对比度 */
--mini-banner-scrim: linear-gradient(90deg, rgba(23, 42, 114, 0.84) 0%, rgba(37, 16, 79, 0.40) 56%, rgba(255, 79, 145, 0.12) 100%);
/* ============ 功能色(同样分级) ============ */
--color-success: #2E9B68; /* 色块/图标 */
--color-success-strong: #17805A; /* 文字(4.92:1 ✓) */
--color-success-light: #ECF8F2;
--color-warning: #E59A32; /* 色块/图标(作文字仅 2.33:1) */
--color-warning-strong: #9C5F14; /* 文字(5.17:1 ✓) */
--color-warning-light: #FFF7E9;
--color-danger: #D94A4A; /* 色块/图标 */
--color-danger-strong: #C62828; /* 文字(5.62:1 ✓) */
--color-danger-light: #FFF0F0;
--color-info: #4A7CD4; /* 色块/图标 */
--color-info-strong: #2A5DB0; /* 文字(6.38:1 ✓) */
--color-info-light: #EEF4FF;
/* ============ 强调紫(参考图的标签语言;此前散落成 6 种写法) ============ */
--color-accent-purple: #8B63BC; /* 色块/装饰 */
--color-accent-purple-strong: #7C60BC; /* 文字(5.03:1 ✓) */
--color-accent-purple-light: #F3EEFF;
/* 深色夜空底上的强调色(不可用于浅色底) */
--color-success-on-night: #A6F5D7; /* on #172A72 = 10.35:1 ✓ */
/* ============ 文字色(实测对比度 on 白 / on 页面底) ============ */
--color-text-strong: #1A1F36; /* 标题 16.24 / 14.90 ✓ */
--color-text-primary: #2A3050; /* 正文 12.83 / 11.77 ✓ */
--color-text-secondary: #4A5169; /* 次要正文 7.86 / 7.21 ✓ */
--color-text-tertiary: #646C85; /* 说明文字 5.22 / 4.79 ✓(旧 #777 为 4.48) */
--color-text-placeholder: #9AA1B4; /* 占位符(非正文,可浅) */
--color-text-disabled: #B8BDC9;
--color-text-inverse: #FFFFFF; /* 深色背景上的文字 */
/* ============ 边框与分割线 ============ */
--color-border: #E6E8EF;
--color-border-strong: #D8DBE5;
--color-divider: #EFF0F5;
--color-border-focus: #B8434A; /* 焦点环用 strong,保证 3:1 可见度 */
--color-border-error: #C62828;
/* ============ 背景(避免纯白/纯灰平铺,页面底为暖白) ============ */
--color-bg-page: #F6F5F3;
--color-bg-card: #FFFFFF;
--color-bg-subtle: #F5F6FA; /* 次级区块、内嵌列表 */
--color-bg-muted: #EEF0F6; /* 更弱的填充 */
--color-bg-input: #F7F8FB; /* 表单输入框底(此前被引用但从未定义,导致背景失效) */
--color-bg-disabled: #F3F4F7;
--color-bg-overlay: rgba(0, 0, 0, 0.45);
/* ============ 字体 ============ */
/* 小程序无法可靠加载 Web Font(wx.loadFontFace 依赖 HTTPS 白名单且有闪动风险),
故使用中文系统字栈:iOS 走苹方、Android 走思源/系统黑体。
排版辨识度靠字号阶梯与字重建立,而非依赖字体本身。 */
--font-family-cn: -apple-system, "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
--font-family-number: "SF Pro Display", -apple-system, "DIN Alternate", "PingFang SC", sans-serif;
/* 字号阶梯 —— 正文 16.00px(16px) 起,元信息下限 12.00px(12px) */
--font-size-micro: 11.00px; /* 11px 仅角标/装饰,禁用于正文 */
--font-size-xs: 12.00px; /* 12px 元信息下限 */
--font-size-sm: 13.00px; /* 13px 次要说明 */
--font-size-md: 14.00px; /* 14px 次要正文 */
--font-size-base: 16.00px; /* 16px 正文 */
--font-size-lg: 18.00px; /* 18px 小标题 */
--font-size-xl: 20.00px; /* 20px 区块标题 */
--font-size-2xl: 24.00px; /* 24px 页面标题 */
--font-size-3xl: 28.00px; /* 28px 大标题 */
--font-size-display: 32.00px; /* 32px Hero */
/* 字重:只用 4 档。禁止 550/650/750 等非百位值 —— Android 无对应字重会回退,
导致同一设计在不同机型上粗细不一致(审计发现 30 处)。 */
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.65;
--letter-spacing-tight: 0;
--letter-spacing-wide: 0.50px;
--letter-spacing-wider: 1.00px;
/* ============ 间距(4px 栅格) ============ */
--spacing-1: 4.00px;
--spacing-2: 8.00px;
--spacing-3: 12.00px;
--spacing-4: 16.00px;
--spacing-5: 20.00px;
--spacing-6: 24.00px;
--spacing-8: 32.00px;
--spacing-10: 40.00px;
--spacing-12: 48.00px;
--spacing-page-x: 16.00px;
--spacing-section: 24.00px;
--spacing-card-inner: 16.00px;
--spacing-tight: 8.00px;
/* ============ 圆角 ============ */
--radius-sm: 8.00px;
--radius-md: 12.00px;
--radius-lg: 16.00px;
--radius-xl: 20.00px;
--radius-2xl: 24.00px;
--radius-full: 4999.50px;
/* ============ 阴影(统一为一套,此前 30+ 种近似值) ============ */
--shadow-card: 0 4.00px 14.00px rgba(35, 35, 95, 0.07);
--shadow-raised: 0 6.00px 18.00px rgba(35, 35, 95, 0.10);
--shadow-popup: 0 8.00px 32.00px rgba(0, 0, 0, 0.10);
--shadow-night: 0 8.00px 20.00px rgba(28, 30, 88, 0.18);
/* ============ 边框宽度 ============ */
--border-width: 0.50px;
--border-width-strong: 1.00px;
/* ============ 触摸目标(无障碍下限 44×44px) ============ */
--tap-min: 44.00px; /* 44px 最小可点区域 */
--tap-comfortable: 48.00px; /* 48px 舒适尺寸:主操作 */
--tap-gap: 8.00px; /* 8px 相邻目标最小间距 */
/* ============ 动效 ============ */
--motion-fast: 120ms;
--motion-normal: 200ms;
--motion-slow: 300ms;
--ease-standard: cubic-bezier(0.32, 0.72, 0, 1);
--ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
--press-scale: 0.97;
--press-opacity: 0.88;
/* ============ 层级 z-index ============ */
--z-base: 1;
--z-sticky: 100;
--z-tabbar: 200;
--z-dropdown: 500;
--z-modal: 1000;
--z-toast: 2000;
--z-ambient: 0;
/* ============ 页面基础样式 ============ */
background-color: var(--color-bg-page);
font-family: var(--font-family-cn);
font-size: var(--font-size-base);
color: var(--color-text-primary);
line-height: var(--line-height-normal);
}
/* ==========================================================================
通用工具类
========================================================================== */
.container {
padding: var(--spacing-page-x);
}
.flex { display: flex; }
.flex-column { display: flex; flex-direction: column; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-start { display: flex; align-items: center; justify-content: flex-start; }
.flex-1 { flex: 1; min-width: 0; }
.flex-shrink-0 { flex-shrink: 0; }
.wrap { flex-wrap: wrap; }
/* 4 列宫格:用 flex + 百分比宽度实现。
注:display:grid 在 WebView 渲染下可用,但 Skyline 不支持,故统一改为 flex 以免疫渲染引擎迁移。*/
.grid-4 {
display: flex;
flex-wrap: wrap;
}
.grid-4 > .grid-item {
width: 25%;
box-sizing: border-box;
}
.text-strong { color: var(--color-text-strong); }
.text-primary { color: var(--color-text-primary); }
.text-secondary { color: var(--color-text-secondary); }
.text-tertiary { color: var(--color-text-tertiary); }
.text-placeholder { color: var(--color-text-placeholder); }
.text-white { color: var(--color-text-inverse); }
.text-brand { color: var(--color-primary-strong); }
/* 品牌色作文字只能用 -strong 变体:基础色 #E96B6B 在白底仅 3.10:1。
保留 .text-brand-soft 这个类名是为了不破坏既有引用,取值已统一到 -strong,
如需「更亮的品牌色」请用于背景/图形而非文字。 */
.text-brand-soft { color: var(--color-primary-strong); }
.text-success { color: var(--color-success-strong); }
.text-warning { color: var(--color-warning-strong); }
.text-danger { color: var(--color-danger-strong); }
.text-info { color: var(--color-info-strong); }
.font-micro { font-size: var(--font-size-micro); }
.font-xs { font-size: var(--font-size-xs); }
.font-sm { font-size: var(--font-size-sm); }
.font-md { font-size: var(--font-size-md); }
.font-base { font-size: var(--font-size-base); }
.font-lg { font-size: var(--font-size-lg); }
.font-xl { font-size: var(--font-size-xl); }
.font-2xl { font-size: var(--font-size-2xl); }
.font-3xl { font-size: var(--font-size-3xl); }
.font-display { font-size: var(--font-size-display); }
.font-regular { font-weight: var(--font-weight-regular); }
.font-medium { font-weight: var(--font-weight-medium); }
.font-semibold { font-weight: var(--font-weight-semibold); }
.font-bold { font-weight: var(--font-weight-bold); }
.mt-1 { margin-top: var(--spacing-1); }
.mt-2 { margin-top: var(--spacing-2); }
.mt-3 { margin-top: var(--spacing-3); }
.mt-4 { margin-top: var(--spacing-4); }
.mt-5 { margin-top: var(--spacing-5); }
.mt-6 { margin-top: var(--spacing-6); }
.mb-1 { margin-bottom: var(--spacing-1); }
.mb-2 { margin-bottom: var(--spacing-2); }
.mb-3 { margin-bottom: var(--spacing-3); }
.mb-4 { margin-bottom: var(--spacing-4); }
.mb-5 { margin-bottom: var(--spacing-5); }
.mb-6 { margin-bottom: var(--spacing-6); }
/* 文本省略 */
.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ellipsis-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
/* 安全区底部留白(避开 Home Indicator) */
.safe-area-bottom {
padding-bottom: 0px;
}
/* 页面卡片基础样式 */
.card-base {
background: var(--color-bg-card);
border-radius: var(--radius-lg);
padding: var(--spacing-card-inner);
box-shadow: var(--shadow-card);
}
/* 分割线 */
.divider {
height: var(--border-width);
background: var(--color-divider);
}
/* ==========================================================================
可访问性:只用 token,不用工具类(2026-09-23 修订)
--------------------------------------------------------------------------
v2 曾在此处新增 .tap-min / .tap-gap / .focusable / .pressable 四个工具类。
复检发现全部零引用(等价能力已各自写在组件样式内,例如 button/index.wxss
直接使用 min-height:var(--tap-min)),且存在两个硬问题:
1) `.tap-gap > * + *` 用了通配符与兄弟选择器 —— WXSS 不支持,
wcc 编译期直接报 `error at token '*'`,导致整个小程序编译失败。
(这是编译错误,不是静默失效,代价最高。)
2) `.pressable:active` / `.focusable:focus-visible` 的伪类在 view 上
不生效(小程序须用 hover-class),属于"写了等于没写"。
故整块移除,保留 token。需要热区/间距时直接引用 token:
min-height: var(--tap-min); → 44.00px = 44px,最小可点区域
gap: var(--tap-gap); → 8.00px = 8px,相邻目标间距(flex gap)
【WXSS 禁用清单】星号通配符、兄弟选择器、属性选择器。
【注释约束】WXSS 注释**不可嵌套**:内层注释的结束标记会提前终止外层注释,
其后的文字会被当成真实样式解析,导致编译失败或样式被污染。
(2026-09-23 实证:本块注释初版即踩此坑。)
========================================================================== */
.wx-page{background:var(--color-bg-page)}.service-page{min-height:100vh;padding-bottom:calc(70.00px + 0px)}.hero{padding:22.00px 16.00px 27.00px;background:linear-gradient(140deg,var(--color-primary-lighter),var(--color-warning-light));position:relative;overflow:hidden}.eyebrow{display:inline-flex;padding:3.50px 7.00px;border-radius:499.50px;background:rgba(255,255,255,.72);color:var(--color-primary-strong);font-size:12.00px}.hero-title{display:block;margin-top:9.00px;font-size:20.00px;font-weight:700;line-height:1.35}.hero-desc{display:block;width:82%;margin-top:7.00px;font-size:12.50px;color:var(--color-text-secondary);line-height:1.7}.content{padding:0 var(--spacing-page-x)}.block{margin-top:var(--spacing-section)}.block-title{display:block;font-size:15.50px;font-weight:600}.block-subtitle{display:block;margin-top:4.00px;font-size:12.00px;color:var(--color-text-tertiary)}.card{margin-top:9.00px;padding:14.00px;background:var(--color-bg-card);border:0.50px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-card)}.feature-row,.menu-row,.record-row{display:flex;align-items:center;gap:10.00px;min-height:56.00px;padding:9.00px 0;border-bottom:0.50px solid var(--color-divider)}.feature-row:last-child,.menu-row:last-child,.record-row:last-child{border-bottom:0}.feature-icon{width:36.00px;height:36.00px;display:flex;align-items:center;justify-content:center;flex:none;border-radius:11.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-weight:700}.feature-copy{flex:1;min-width:0}.feature-title{display:block;font-size:14.00px;font-weight:600}.feature-desc,.meta{display:block;margin-top:3.50px;font-size:12.00px;color:var(--color-text-tertiary);line-height:1.55}.arrow{font-size:20.00px;color:var(--color-text-disabled)}.tag{display:inline-flex;margin-right:5.00px;margin-top:5.00px;padding:3.00px 6.50px;border-radius:499.50px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px}.tag.warning{background:var(--color-warning-light);color:var(--color-warning-strong)}.primary-btn,.secondary-btn{height:44.00px;display:flex;align-items:center;justify-content:center;border-radius:22.00px;font-size:14.00px;font-weight:600}.primary-btn{background:var(--gradient-brand-solid);color:var(--color-text-inverse);box-shadow:0 5.00px 12.00px rgba(255,92,130,.22)}.primary-btn.disabled{background:var(--color-bg-muted);color:var(--color-text-tertiary);box-shadow:none}.secondary-btn{background:var(--color-primary-light);color:var(--color-primary-strong)}.fixed-action{position:fixed;left:0;right:0;bottom:0;padding:9.00px var(--spacing-page-x) calc(9.00px + 0px);background:rgba(255,255,255,.96);border-top:0.50px solid var(--color-divider);z-index:100}.field{margin-top:13.00px}.label{display:block;margin-bottom:6.00px;font-size:12.50px;font-weight:600}.input,.select-box,.textarea{width:100%;box-sizing:border-box;background:var(--color-bg-page);border:0.50px solid var(--color-border);border-radius:var(--radius-md);font-size:13.00px}.input,.select-box{height:44.00px;padding:0 12.00px;display:flex;align-items:center}.textarea{min-height:90.00px;padding:11.00px}.notice{margin-top:10.00px;padding:11.00px;border-radius:var(--radius-md);background:var(--color-info-light);color:var(--color-text-secondary);font-size:12.00px;line-height:1.65}.select-box.is-readonly{background:var(--color-bg-subtle);color:var(--color-text-secondary)}.empty-panel{text-align:center;padding:35.00px 15.00px}.empty-symbol{width:48.00px;height:48.00px;margin:auto;display:flex;align-items:center;justify-content:center;border-radius:15.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-size:18.00px;font-weight:700}.empty-title{display:block;margin-top:11.00px;font-size:15.00px;font-weight:600}.article-card{margin-top:9.00px;background:var(--color-bg-card);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-card)}.article-cover{height:110.00px;padding:12.00px;background:linear-gradient(135deg,var(--color-warning-light),var(--color-warning-light));display:flex;align-items:flex-end}.article-cover text{font-size:21.00px;color:rgba(125,76,63,.52);font-weight:700}.article-body{padding:12.00px}.article-title{display:block;font-size:14.50px;font-weight:600;line-height:1.45}.article-meta{display:block;margin-top:5.00px;font-size:12.00px;color:var(--color-text-tertiary)}.article-content{padding:16.00px;background:var(--color-bg-card);font-size:14.00px;line-height:1.9;color:var(--color-text-secondary)}.article-content .lead{display:block;font-size:15.50px;color:var(--color-text-primary);font-weight:600;margin-bottom:12.00px}.danger-card{background:var(--color-primary-lighter);border-color:var(--color-primary-light)}.danger-card .feature-icon{background:var(--color-warning-light);color:var(--color-warning-strong)}@media(max-width:340px){.hero-title{font-size:18.00px}.hero-desc{width:92%}}
.service-shell{min-height:100vh;padding-bottom:calc(68.00px + 0px);background:var(--color-bg-page)}.service-content{padding:4.00px 12.00px 18.00px}.service-status{display:flex;align-items:center;justify-content:space-between;margin-top:12.00px;padding:10.00px 12.00px;border-radius:11.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-status__label{color:var(--color-text-tertiary);font-size:12.00px}.service-status__value{padding:3.00px 7.00px;border-radius:9.00px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px;font-weight:600}.service-status__value.disabled{background:var(--color-danger-light);color:var(--color-danger-strong)}.service-topics{display:grid;grid-template-columns:repeat(2,1fr);gap:8.00px;margin-top:9.00px}.service-topic{min-height:74.00px;padding:10.00px;border-radius:12.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-topic__icon{display:flex;align-items:center;justify-content:center;width:27.00px;height:27.00px;border-radius:8.50px;background:var(--color-primary-light)}.service-topic__icon image{width:17.00px;height:17.00px}.service-topic__title{display:block;margin-top:6.50px;color:var(--color-text-strong);font-size:12.00px;font-weight:600}.service-topic__desc{display:block;margin-top:3.00px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}.service-actions{display:flex;gap:7.00px}.service-actions .secondary-btn{width:95.00px;flex:none}.service-actions .primary-btn{flex:1}.privacy-note{display:flex;align-items:flex-start;gap:7.00px;margin-top:11.00px;padding:10.00px;border-radius:11.00px;background:var(--color-info-light);color:var(--color-text-tertiary);font-size:12.00px;line-height:1.55}.privacy-note image{width:17.00px;height:17.00px;flex:none}
/* ==== miniapp/components/service-hero ==== */
.service-hero {
position:relative;
height:150.00px;
overflow:hidden;
border-radius:0 0 16.00px 16.00px;
background:var(--color-primary-light);
}
.service-hero__image,
.service-hero__veil {
position:absolute;
inset:0;
width:100%;
height:100%;
}
.service-hero__veil {
background:linear-gradient(90deg, rgba(255, 250, 252, 0.98) 0%, rgba(255, 250, 252, 0.82) 38%, rgba(255, 250, 252, 0.08) 70%);
}
.service-hero--night .service-hero__veil {
background:linear-gradient(90deg, rgba(18, 24, 83, 0.92) 0%, rgba(34, 31, 111, 0.64) 42%, rgba(34, 31, 111, 0.08) 72%);
}
.service-hero__content {
position:relative;
z-index:1;
display:flex;
flex-direction:column;
justify-content:center;
width:54%;
height:100%;
padding:0 18.00px;
box-sizing:border-box;
}
.service-hero__eyebrow {
margin-bottom:5.00px;
color:var(--color-primary-strong);
font-size:12.00px;
font-weight:600;
letter-spacing:1.00px;
}
.service-hero__title {
color:var(--color-text-strong);
font-size:20.00px;
font-weight:700;
line-height:1.28;
}
.service-hero__subtitle {
margin-top:7.00px;
color:var(--color-text-tertiary);
font-size:12.00px;
line-height:1.55;
}
.service-hero--night .service-hero__eyebrow,
.service-hero--night .service-hero__title,
.service-hero--night .service-hero__subtitle {
color:var(--color-text-inverse);
}
@import "../../styles/service-page.wxss";
/**
* 丹阳公益婚恋服务平台 - 全局 Design Token
*
* v2(2026-09-22 设计系统夯实)
* ---------------------------------------------------------------
* 本次修订针对审计发现的系统性问题,逐条给出依据:
*
* 1) 品牌色不能承载文字 → 引入「基础色 / -strong」分级
* #E96B6B on 白 = 3.10:1,白字 on #E96B6B = 3.10:1,on #FFF3F2 = 2.85:1,
* 三条路径都不满足正文 4.5:1。故:
* --color-primary 仅用于大色块、渐变、光晕、装饰(非文字)
* --color-primary-strong 用于文字、小图标、纯文字链接(5.33:1 ✓)
* --color-primary-solid 实心按钮底(白字 ≥4.5:1 ✓)
* 功能色(success/warning/danger/info)同此分级。
*
* 2) 次要文字对比度过低
* 旧 --color-text-tertiary(#777) = 4.48(on 白,勉强)/ #999 实测 2.85 却被用了 71 次。
* 现将三级文字压到 #646C85 = 5.22:1,占位符保留浅色(占位符非正文)。
*
* 3) 颜色碎片化
* 审计前全站 182 种 hex、770 次硬编码(54 种灰、60 种蓝紫、40 种红橙)。
* 本文件是唯一的颜色事实源;页面层禁止再写 hex,一律 var(--token)。
*
* 4) 触摸目标
* 组件库默认按钮只有 40px、小号 28px、"喜欢"按钮 31px。
* 统一以 --tap-min(44.00px=44px) 为下限,--tap-gap 为最小间距。
*
* 5) 动效几乎未落地(--motion-* 全站仅 5 次引用)
* 补充 --ease-spring 与 --press-scale,让点击有即时反馈。
*
* 6) 夜间氛围层缺失(参考图有明显的光晕/星点,代码只有纯渐变)
* 新增 --mini-glow-* / --mini-star / --mini-glass / --mini-hairline。
*
* 单位说明:rpx(375.00px = 屏幕宽度,0.50px ≈ 0.5px @375pt)
* 旧 token 名全部保留(88 个 wxss 共 909 处引用),只更新取值,避免大范围失效。
*/
.wx-page {
/* ============ 品牌主色(分级:色块 / 文字 / 实心按钮) ============ */
--color-primary: #E96B6B; /* 基础色:渐变、光晕、装饰、非文字图形 */
--color-primary-strong: #B8434A; /* 文字与小图标(5.33:1 on 白,4.91:1 on 浅粉底) */
--color-primary-solid: #C24C50; /* 实心按钮底(白字 4.62:1) */
--color-primary-active: #D95F5F; /* 按压态(配合 --color-primary 使用) */
--color-primary-light: #FFF3F2;
--color-primary-lighter: #FFF8F7;
/* ============ 小程序参考图品牌主题(夜间紫蓝) ============ */
--mini-night-start: #172A72;
--mini-night-end: #25104F;
--mini-night-soft: #3445A1;
--mini-accent-pink: #FF4F91; /* 点缀色:仅用于色块/装饰,不作正文 */
--mini-accent-coral: #FF6A78;
--mini-card-bg: rgba(255, 255, 255, 0.98);
--mini-text: #1F2744;
--mini-muted: #7D839B;
--mini-card-radius: 12.00px;
--mini-text-on-night: #FFFFFF; /* on 深底 13.04:1 ✓ */
--mini-text-on-night-muted: rgba(255, 255, 255, 0.72); /* on 深底 ≈8:1 ✓ */
--mini-shadow: 0 8.00px 20.00px rgba(28, 30, 88, 0.14);
/* ---- 渐变(集中定义:此前 4 个页面各写了一份「橙红渐变」按钮) ---- */
/* --gradient-brand 明亮活泼,但白字仅 2.77:1 —— 只能用于无文字的装饰填充。 */
--gradient-brand: linear-gradient(135deg, #FF6A78 0%, #E96B6B 100%);
/* 承载白字的 CTA 渐变:两端 #C24C50(4.73:1) / #B8434A(5.33:1) 均达标。 */
--gradient-brand-solid: linear-gradient(135deg, #C24C50 0%, #B8434A 100%);
--gradient-night: linear-gradient(160deg, #172A72 0%, #25104F 100%);
--gradient-night-soft: linear-gradient(160deg, #3445A1 0%, #172A72 100%);
/* ---- 首页 4×2 入口宫格图标渐变(参考图 2:高饱和圆角砖 + 白色描画图标) ----
白图标的对比度判据是**非文本图形 3:1**(WCAG 1.4.11)。渐变是斜向的、图标又跨在
两色之间,所以**较亮的一端也必须达标** —— 下表注释给的是 0% 处实算值,100% 更暗只会更高。
色相按业务语义固定(不随 tone 名漂移):找对象/婚前辅导=玫瑰粉系、公益红娘/服务站=暖橙系、
公益活动=紫罗兰、婚恋咨询=蓝、婚恋课堂=紫、婚恋反诈=绿。 */
--gradient-entry-rose: linear-gradient(135deg, #F56287 0%, #F34671 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-orange: linear-gradient(135deg, #F66A06 0%, #D95E06 100%); /* 3.01:1 / 3.78:1 */
--gradient-entry-violet: linear-gradient(135deg, #A380F5 0%, #8F64F2 100%); /* 3.02:1 / 3.98:1 */
--gradient-entry-blue: linear-gradient(135deg, #5195F6 0%, #3484F4 100%); /* 3.01:1 / 3.65:1 */
--gradient-entry-purple: linear-gradient(135deg, #B27BF0 0%, #A260ED 100%); /* 3.01:1 / 3.87:1 */
--gradient-entry-pink: linear-gradient(135deg, #F2619E 0%, #F0458C 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-green: linear-gradient(135deg, #18A979 0%, #148F66 100%); /* 3.00:1 / 4.08:1 */
--gradient-entry-amber: linear-gradient(135deg, #E9740C 0%, #CC650B 100%); /* 3.01:1 / 3.86:1 */
/* 图标砖落影:比 --mini-shadow 更小,避免 4 列宫格里相邻砖块的投影互相压边 */
--mini-entry-shadow: 0 4.00px 9.00px rgba(28, 30, 88, 0.18);
/* ---- 夜间氛围层(v2 新增;参考图有光晕与星点,此前完全没有) ---- */
--mini-glow-coral: rgba(255, 79, 145, 0.40);
--mini-glow-indigo: rgba(94, 124, 255, 0.32);
--mini-glow-soft: rgba(255, 255, 255, 0.10);
--mini-star: rgba(255, 255, 255, 0.70);
--mini-glass: rgba(255, 255, 255, 0.10); /* 深底玻璃面 */
--mini-glass-strong: rgba(255, 255, 255, 0.16);
--mini-hairline: rgba(255, 255, 255, 0.16); /* 深底分隔线 */
--mini-glass-success: rgba(90, 226, 184, 0.16); /* 深底上的成功态玻璃面 */
/* 星点层:多个小径向渐变叠在夜空渐变之上。用 radial-gradient 而非图片,
避免额外请求,也便于随主题换色(index 页脚注:装饰层不承载信息)。 */
--mini-starfield:
radial-gradient(circle at 12% 18%, var(--mini-star) 0, transparent 1.25px),
radial-gradient(circle at 31% 66%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 57% 12%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 79% 52%, var(--mini-star) 0, transparent 1.50px),
radial-gradient(circle at 93% 84%, var(--mini-star) 0, transparent 1.00px);
/* 横幅压暗层:保证任何底图上的白色标题都有足够对比度 */
--mini-banner-scrim: linear-gradient(90deg, rgba(23, 42, 114, 0.84) 0%, rgba(37, 16, 79, 0.40) 56%, rgba(255, 79, 145, 0.12) 100%);
/* ============ 功能色(同样分级) ============ */
--color-success: #2E9B68; /* 色块/图标 */
--color-success-strong: #17805A; /* 文字(4.92:1 ✓) */
--color-success-light: #ECF8F2;
--color-warning: #E59A32; /* 色块/图标(作文字仅 2.33:1) */
--color-warning-strong: #9C5F14; /* 文字(5.17:1 ✓) */
--color-warning-light: #FFF7E9;
--color-danger: #D94A4A; /* 色块/图标 */
--color-danger-strong: #C62828; /* 文字(5.62:1 ✓) */
--color-danger-light: #FFF0F0;
--color-info: #4A7CD4; /* 色块/图标 */
--color-info-strong: #2A5DB0; /* 文字(6.38:1 ✓) */
--color-info-light: #EEF4FF;
/* ============ 强调紫(参考图的标签语言;此前散落成 6 种写法) ============ */
--color-accent-purple: #8B63BC; /* 色块/装饰 */
--color-accent-purple-strong: #7C60BC; /* 文字(5.03:1 ✓) */
--color-accent-purple-light: #F3EEFF;
/* 深色夜空底上的强调色(不可用于浅色底) */
--color-success-on-night: #A6F5D7; /* on #172A72 = 10.35:1 ✓ */
/* ============ 文字色(实测对比度 on 白 / on 页面底) ============ */
--color-text-strong: #1A1F36; /* 标题 16.24 / 14.90 ✓ */
--color-text-primary: #2A3050; /* 正文 12.83 / 11.77 ✓ */
--color-text-secondary: #4A5169; /* 次要正文 7.86 / 7.21 ✓ */
--color-text-tertiary: #646C85; /* 说明文字 5.22 / 4.79 ✓(旧 #777 为 4.48) */
--color-text-placeholder: #9AA1B4; /* 占位符(非正文,可浅) */
--color-text-disabled: #B8BDC9;
--color-text-inverse: #FFFFFF; /* 深色背景上的文字 */
/* ============ 边框与分割线 ============ */
--color-border: #E6E8EF;
--color-border-strong: #D8DBE5;
--color-divider: #EFF0F5;
--color-border-focus: #B8434A; /* 焦点环用 strong,保证 3:1 可见度 */
--color-border-error: #C62828;
/* ============ 背景(避免纯白/纯灰平铺,页面底为暖白) ============ */
--color-bg-page: #F6F5F3;
--color-bg-card: #FFFFFF;
--color-bg-subtle: #F5F6FA; /* 次级区块、内嵌列表 */
--color-bg-muted: #EEF0F6; /* 更弱的填充 */
--color-bg-input: #F7F8FB; /* 表单输入框底(此前被引用但从未定义,导致背景失效) */
--color-bg-disabled: #F3F4F7;
--color-bg-overlay: rgba(0, 0, 0, 0.45);
/* ============ 字体 ============ */
/* 小程序无法可靠加载 Web Font(wx.loadFontFace 依赖 HTTPS 白名单且有闪动风险),
故使用中文系统字栈:iOS 走苹方、Android 走思源/系统黑体。
排版辨识度靠字号阶梯与字重建立,而非依赖字体本身。 */
--font-family-cn: -apple-system, "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
--font-family-number: "SF Pro Display", -apple-system, "DIN Alternate", "PingFang SC", sans-serif;
/* 字号阶梯 —— 正文 16.00px(16px) 起,元信息下限 12.00px(12px) */
--font-size-micro: 11.00px; /* 11px 仅角标/装饰,禁用于正文 */
--font-size-xs: 12.00px; /* 12px 元信息下限 */
--font-size-sm: 13.00px; /* 13px 次要说明 */
--font-size-md: 14.00px; /* 14px 次要正文 */
--font-size-base: 16.00px; /* 16px 正文 */
--font-size-lg: 18.00px; /* 18px 小标题 */
--font-size-xl: 20.00px; /* 20px 区块标题 */
--font-size-2xl: 24.00px; /* 24px 页面标题 */
--font-size-3xl: 28.00px; /* 28px 大标题 */
--font-size-display: 32.00px; /* 32px Hero */
/* 字重:只用 4 档。禁止 550/650/750 等非百位值 —— Android 无对应字重会回退,
导致同一设计在不同机型上粗细不一致(审计发现 30 处)。 */
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.65;
--letter-spacing-tight: 0;
--letter-spacing-wide: 0.50px;
--letter-spacing-wider: 1.00px;
/* ============ 间距(4px 栅格) ============ */
--spacing-1: 4.00px;
--spacing-2: 8.00px;
--spacing-3: 12.00px;
--spacing-4: 16.00px;
--spacing-5: 20.00px;
--spacing-6: 24.00px;
--spacing-8: 32.00px;
--spacing-10: 40.00px;
--spacing-12: 48.00px;
--spacing-page-x: 16.00px;
--spacing-section: 24.00px;
--spacing-card-inner: 16.00px;
--spacing-tight: 8.00px;
/* ============ 圆角 ============ */
--radius-sm: 8.00px;
--radius-md: 12.00px;
--radius-lg: 16.00px;
--radius-xl: 20.00px;
--radius-2xl: 24.00px;
--radius-full: 4999.50px;
/* ============ 阴影(统一为一套,此前 30+ 种近似值) ============ */
--shadow-card: 0 4.00px 14.00px rgba(35, 35, 95, 0.07);
--shadow-raised: 0 6.00px 18.00px rgba(35, 35, 95, 0.10);
--shadow-popup: 0 8.00px 32.00px rgba(0, 0, 0, 0.10);
--shadow-night: 0 8.00px 20.00px rgba(28, 30, 88, 0.18);
/* ============ 边框宽度 ============ */
--border-width: 0.50px;
--border-width-strong: 1.00px;
/* ============ 触摸目标(无障碍下限 44×44px) ============ */
--tap-min: 44.00px; /* 44px 最小可点区域 */
--tap-comfortable: 48.00px; /* 48px 舒适尺寸:主操作 */
--tap-gap: 8.00px; /* 8px 相邻目标最小间距 */
/* ============ 动效 ============ */
--motion-fast: 120ms;
--motion-normal: 200ms;
--motion-slow: 300ms;
--ease-standard: cubic-bezier(0.32, 0.72, 0, 1);
--ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
--press-scale: 0.97;
--press-opacity: 0.88;
/* ============ 层级 z-index ============ */
--z-base: 1;
--z-sticky: 100;
--z-tabbar: 200;
--z-dropdown: 500;
--z-modal: 1000;
--z-toast: 2000;
--z-ambient: 0;
/* ============ 页面基础样式 ============ */
background-color: var(--color-bg-page);
font-family: var(--font-family-cn);
font-size: var(--font-size-base);
color: var(--color-text-primary);
line-height: var(--line-height-normal);
}
/* ==========================================================================
通用工具类
========================================================================== */
.container {
padding: var(--spacing-page-x);
}
.flex { display: flex; }
.flex-column { display: flex; flex-direction: column; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-start { display: flex; align-items: center; justify-content: flex-start; }
.flex-1 { flex: 1; min-width: 0; }
.flex-shrink-0 { flex-shrink: 0; }
.wrap { flex-wrap: wrap; }
/* 4 列宫格:用 flex + 百分比宽度实现。
注:display:grid 在 WebView 渲染下可用,但 Skyline 不支持,故统一改为 flex 以免疫渲染引擎迁移。*/
.grid-4 {
display: flex;
flex-wrap: wrap;
}
.grid-4 > .grid-item {
width: 25%;
box-sizing: border-box;
}
.text-strong { color: var(--color-text-strong); }
.text-primary { color: var(--color-text-primary); }
.text-secondary { color: var(--color-text-secondary); }
.text-tertiary { color: var(--color-text-tertiary); }
.text-placeholder { color: var(--color-text-placeholder); }
.text-white { color: var(--color-text-inverse); }
.text-brand { color: var(--color-primary-strong); }
/* 品牌色作文字只能用 -strong 变体:基础色 #E96B6B 在白底仅 3.10:1。
保留 .text-brand-soft 这个类名是为了不破坏既有引用,取值已统一到 -strong,
如需「更亮的品牌色」请用于背景/图形而非文字。 */
.text-brand-soft { color: var(--color-primary-strong); }
.text-success { color: var(--color-success-strong); }
.text-warning { color: var(--color-warning-strong); }
.text-danger { color: var(--color-danger-strong); }
.text-info { color: var(--color-info-strong); }
.font-micro { font-size: var(--font-size-micro); }
.font-xs { font-size: var(--font-size-xs); }
.font-sm { font-size: var(--font-size-sm); }
.font-md { font-size: var(--font-size-md); }
.font-base { font-size: var(--font-size-base); }
.font-lg { font-size: var(--font-size-lg); }
.font-xl { font-size: var(--font-size-xl); }
.font-2xl { font-size: var(--font-size-2xl); }
.font-3xl { font-size: var(--font-size-3xl); }
.font-display { font-size: var(--font-size-display); }
.font-regular { font-weight: var(--font-weight-regular); }
.font-medium { font-weight: var(--font-weight-medium); }
.font-semibold { font-weight: var(--font-weight-semibold); }
.font-bold { font-weight: var(--font-weight-bold); }
.mt-1 { margin-top: var(--spacing-1); }
.mt-2 { margin-top: var(--spacing-2); }
.mt-3 { margin-top: var(--spacing-3); }
.mt-4 { margin-top: var(--spacing-4); }
.mt-5 { margin-top: var(--spacing-5); }
.mt-6 { margin-top: var(--spacing-6); }
.mb-1 { margin-bottom: var(--spacing-1); }
.mb-2 { margin-bottom: var(--spacing-2); }
.mb-3 { margin-bottom: var(--spacing-3); }
.mb-4 { margin-bottom: var(--spacing-4); }
.mb-5 { margin-bottom: var(--spacing-5); }
.mb-6 { margin-bottom: var(--spacing-6); }
/* 文本省略 */
.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ellipsis-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
/* 安全区底部留白(避开 Home Indicator) */
.safe-area-bottom {
padding-bottom: 0px;
}
/* 页面卡片基础样式 */
.card-base {
background: var(--color-bg-card);
border-radius: var(--radius-lg);
padding: var(--spacing-card-inner);
box-shadow: var(--shadow-card);
}
/* 分割线 */
.divider {
height: var(--border-width);
background: var(--color-divider);
}
/* ==========================================================================
可访问性:只用 token,不用工具类(2026-09-23 修订)
--------------------------------------------------------------------------
v2 曾在此处新增 .tap-min / .tap-gap / .focusable / .pressable 四个工具类。
复检发现全部零引用(等价能力已各自写在组件样式内,例如 button/index.wxss
直接使用 min-height:var(--tap-min)),且存在两个硬问题:
1) `.tap-gap > * + *` 用了通配符与兄弟选择器 —— WXSS 不支持,
wcc 编译期直接报 `error at token '*'`,导致整个小程序编译失败。
(这是编译错误,不是静默失效,代价最高。)
2) `.pressable:active` / `.focusable:focus-visible` 的伪类在 view 上
不生效(小程序须用 hover-class),属于"写了等于没写"。
故整块移除,保留 token。需要热区/间距时直接引用 token:
min-height: var(--tap-min); → 44.00px = 44px,最小可点区域
gap: var(--tap-gap); → 8.00px = 8px,相邻目标间距(flex gap)
【WXSS 禁用清单】星号通配符、兄弟选择器、属性选择器。
【注释约束】WXSS 注释**不可嵌套**:内层注释的结束标记会提前终止外层注释,
其后的文字会被当成真实样式解析,导致编译失败或样式被污染。
(2026-09-23 实证:本块注释初版即踩此坑。)
========================================================================== */
.wx-page{background:var(--color-bg-page)}.service-page{min-height:100vh;padding-bottom:calc(70.00px + 0px)}.hero{padding:22.00px 16.00px 27.00px;background:linear-gradient(140deg,var(--color-primary-lighter),var(--color-warning-light));position:relative;overflow:hidden}.eyebrow{display:inline-flex;padding:3.50px 7.00px;border-radius:499.50px;background:rgba(255,255,255,.72);color:var(--color-primary-strong);font-size:12.00px}.hero-title{display:block;margin-top:9.00px;font-size:20.00px;font-weight:700;line-height:1.35}.hero-desc{display:block;width:82%;margin-top:7.00px;font-size:12.50px;color:var(--color-text-secondary);line-height:1.7}.content{padding:0 var(--spacing-page-x)}.block{margin-top:var(--spacing-section)}.block-title{display:block;font-size:15.50px;font-weight:600}.block-subtitle{display:block;margin-top:4.00px;font-size:12.00px;color:var(--color-text-tertiary)}.card{margin-top:9.00px;padding:14.00px;background:var(--color-bg-card);border:0.50px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-card)}.feature-row,.menu-row,.record-row{display:flex;align-items:center;gap:10.00px;min-height:56.00px;padding:9.00px 0;border-bottom:0.50px solid var(--color-divider)}.feature-row:last-child,.menu-row:last-child,.record-row:last-child{border-bottom:0}.feature-icon{width:36.00px;height:36.00px;display:flex;align-items:center;justify-content:center;flex:none;border-radius:11.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-weight:700}.feature-copy{flex:1;min-width:0}.feature-title{display:block;font-size:14.00px;font-weight:600}.feature-desc,.meta{display:block;margin-top:3.50px;font-size:12.00px;color:var(--color-text-tertiary);line-height:1.55}.arrow{font-size:20.00px;color:var(--color-text-disabled)}.tag{display:inline-flex;margin-right:5.00px;margin-top:5.00px;padding:3.00px 6.50px;border-radius:499.50px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px}.tag.warning{background:var(--color-warning-light);color:var(--color-warning-strong)}.primary-btn,.secondary-btn{height:44.00px;display:flex;align-items:center;justify-content:center;border-radius:22.00px;font-size:14.00px;font-weight:600}.primary-btn{background:var(--gradient-brand-solid);color:var(--color-text-inverse);box-shadow:0 5.00px 12.00px rgba(255,92,130,.22)}.primary-btn.disabled{background:var(--color-bg-muted);color:var(--color-text-tertiary);box-shadow:none}.secondary-btn{background:var(--color-primary-light);color:var(--color-primary-strong)}.fixed-action{position:fixed;left:0;right:0;bottom:0;padding:9.00px var(--spacing-page-x) calc(9.00px + 0px);background:rgba(255,255,255,.96);border-top:0.50px solid var(--color-divider);z-index:100}.field{margin-top:13.00px}.label{display:block;margin-bottom:6.00px;font-size:12.50px;font-weight:600}.input,.select-box,.textarea{width:100%;box-sizing:border-box;background:var(--color-bg-page);border:0.50px solid var(--color-border);border-radius:var(--radius-md);font-size:13.00px}.input,.select-box{height:44.00px;padding:0 12.00px;display:flex;align-items:center}.textarea{min-height:90.00px;padding:11.00px}.notice{margin-top:10.00px;padding:11.00px;border-radius:var(--radius-md);background:var(--color-info-light);color:var(--color-text-secondary);font-size:12.00px;line-height:1.65}.select-box.is-readonly{background:var(--color-bg-subtle);color:var(--color-text-secondary)}.empty-panel{text-align:center;padding:35.00px 15.00px}.empty-symbol{width:48.00px;height:48.00px;margin:auto;display:flex;align-items:center;justify-content:center;border-radius:15.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-size:18.00px;font-weight:700}.empty-title{display:block;margin-top:11.00px;font-size:15.00px;font-weight:600}.article-card{margin-top:9.00px;background:var(--color-bg-card);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-card)}.article-cover{height:110.00px;padding:12.00px;background:linear-gradient(135deg,var(--color-warning-light),var(--color-warning-light));display:flex;align-items:flex-end}.article-cover text{font-size:21.00px;color:rgba(125,76,63,.52);font-weight:700}.article-body{padding:12.00px}.article-title{display:block;font-size:14.50px;font-weight:600;line-height:1.45}.article-meta{display:block;margin-top:5.00px;font-size:12.00px;color:var(--color-text-tertiary)}.article-content{padding:16.00px;background:var(--color-bg-card);font-size:14.00px;line-height:1.9;color:var(--color-text-secondary)}.article-content .lead{display:block;font-size:15.50px;color:var(--color-text-primary);font-weight:600;margin-bottom:12.00px}.danger-card{background:var(--color-primary-lighter);border-color:var(--color-primary-light)}.danger-card .feature-icon{background:var(--color-warning-light);color:var(--color-warning-strong)}@media(max-width:340px){.hero-title{font-size:18.00px}.hero-desc{width:92%}}
.service-shell{min-height:100vh;padding-bottom:calc(68.00px + 0px);background:var(--color-bg-page)}.service-content{padding:4.00px 12.00px 18.00px}.service-status{display:flex;align-items:center;justify-content:space-between;margin-top:12.00px;padding:10.00px 12.00px;border-radius:11.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-status__label{color:var(--color-text-tertiary);font-size:12.00px}.service-status__value{padding:3.00px 7.00px;border-radius:9.00px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px;font-weight:600}.service-status__value.disabled{background:var(--color-danger-light);color:var(--color-danger-strong)}.service-topics{display:grid;grid-template-columns:repeat(2,1fr);gap:8.00px;margin-top:9.00px}.service-topic{min-height:74.00px;padding:10.00px;border-radius:12.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-topic__icon{display:flex;align-items:center;justify-content:center;width:27.00px;height:27.00px;border-radius:8.50px;background:var(--color-primary-light)}.service-topic__icon image{width:17.00px;height:17.00px}.service-topic__title{display:block;margin-top:6.50px;color:var(--color-text-strong);font-size:12.00px;font-weight:600}.service-topic__desc{display:block;margin-top:3.00px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}.service-actions{display:flex;gap:7.00px}.service-actions .secondary-btn{width:95.00px;flex:none}.service-actions .primary-btn{flex:1}.privacy-note{display:flex;align-items:flex-start;gap:7.00px;margin-top:11.00px;padding:10.00px;border-radius:11.00px;background:var(--color-info-light);color:var(--color-text-tertiary);font-size:12.00px;line-height:1.55}.privacy-note image{width:17.00px;height:17.00px;flex:none}
/* ==== miniapp/components/service-hero ==== */
.service-hero {
position:relative;
height:150.00px;
overflow:hidden;
border-radius:0 0 16.00px 16.00px;
background:var(--color-primary-light);
}
.service-hero__image,
.service-hero__veil {
position:absolute;
inset:0;
width:100%;
height:100%;
}
.service-hero__veil {
background:linear-gradient(90deg, rgba(255, 250, 252, 0.98) 0%, rgba(255, 250, 252, 0.82) 38%, rgba(255, 250, 252, 0.08) 70%);
}
.service-hero--night .service-hero__veil {
background:linear-gradient(90deg, rgba(18, 24, 83, 0.92) 0%, rgba(34, 31, 111, 0.64) 42%, rgba(34, 31, 111, 0.08) 72%);
}
.service-hero__content {
position:relative;
z-index:1;
display:flex;
flex-direction:column;
justify-content:center;
width:54%;
height:100%;
padding:0 18.00px;
box-sizing:border-box;
}
.service-hero__eyebrow {
margin-bottom:5.00px;
color:var(--color-primary-strong);
font-size:12.00px;
font-weight:600;
letter-spacing:1.00px;
}
.service-hero__title {
color:var(--color-text-strong);
font-size:20.00px;
font-weight:700;
line-height:1.28;
}
.service-hero__subtitle {
margin-top:7.00px;
color:var(--color-text-tertiary);
font-size:12.00px;
line-height:1.55;
}
.service-hero--night .service-hero__eyebrow,
.service-hero--night .service-hero__title,
.service-hero--night .service-hero__subtitle {
color:var(--color-text-inverse);
}
/* ==== miniapp/components/loading ==== */
.ui-loading--block {
display:flex;
flex-direction:column;
align-items:center;
justify-content:center;
padding:var(--spacing-8) var(--spacing-page-x);
}
.ui-loading--inline {
display:inline-flex;
align-items:center;
}
.ui-loading__spinner {
width:30.00px;
height:30.00px;
display:flex;
align-items:center;
justify-content:center;
}
.ui-loading__spinner-icon {
width:24.00px;
height:24.00px;
animation:ui-loading-spin 0.8s linear infinite;
}
@keyframes ui-loading-spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
.ui-loading__text {
margin-top:var(--spacing-3);
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
}
/* Skeleton */
.ui-loading__skeleton {
width:100%;
}
.ui-loading__skeleton-row {
display:flex;
align-items:center;
padding:var(--spacing-3) var(--spacing-page-x);
background:var(--color-bg-card);
border-bottom:0.50px solid var(--color-divider);
}
.ui-loading__skeleton-avatar {
width:44.00px;
height:44.00px;
border-radius:50%;
background:var(--color-bg-disabled);
margin-right:var(--spacing-3);
flex-shrink:0;
}
.ui-loading__skeleton-content {
flex:1;
min-width:0;
}
.ui-loading__skeleton-line {
height:12.00px;
background:var(--color-bg-disabled);
border-radius:var(--radius-sm);
position:relative;
overflow:hidden;
}
.ui-loading__skeleton-line--title {
width:40%;
margin-bottom:var(--spacing-2);
}
.ui-loading__skeleton-line--meta {
width:70%;
}
/* shimmer */
.ui-loading__skeleton-line::after,
.ui-loading__skeleton-avatar::after {
content:'';
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background:linear-gradient(
90deg,
transparent 0%,
rgba(255, 255, 255, 0.55) 50%,
transparent 100%
);
animation:ui-loading-shimmer 1.4s ease-in-out infinite;
}
@keyframes ui-loading-shimmer {
0% { transform:translateX(-100%); }
100% { transform:translateX(100%); }
}
/* ==== miniapp/components/empty ==== */
.ui-empty {
display:flex;
flex-direction:column;
align-items:center;
padding:var(--spacing-10) var(--spacing-page-x);
text-align:center;
}
.ui-empty__illustration {
width:80.00px;
height:80.00px;
border-radius:50%;
background:var(--color-bg-disabled);
display:flex;
align-items:center;
justify-content:center;
margin-bottom:var(--spacing-4);
}
.ui-empty__icon {
width:36.00px;
height:36.00px;
opacity:0.72;
}
.ui-empty__title {
font-size:var(--font-size-lg);
font-weight:var(--font-weight-medium);
color:var(--color-text-primary);
margin-bottom:var(--spacing-2);
}
.ui-empty__desc {
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
line-height:var(--line-height-relaxed);
max-width:240.00px;
}
.ui-empty__actions {
display:flex;
flex-direction:column;
gap:var(--spacing-2);
margin-top:var(--spacing-6);
width:100%;
max-width:240.00px;
}
.ui-empty__action {
display:flex;
align-items:center;
justify-content:center;
min-height:var(--tap-min);
border-radius:var(--radius-full);
font-size:var(--font-size-base);
font-weight:var(--font-weight-medium);
min-width:var(--tap-min);}
.ui-empty__action--primary {
background:var(--color-primary-solid);
color:var(--color-text-inverse);
}
.ui-empty__action--secondary {
background:var(--color-bg-card);
color:var(--color-primary-strong);
border:0.50px solid var(--color-primary);
}
/* ==== miniapp/components/error-state ==== */
.error-state {
padding:32.00px 16.00px;
text-align:center;
background:var(--color-bg-card);
border-radius:var(--radius-lg);
}
.error-icon {
display:block;
width:36.00px;
height:36.00px;
margin:0 auto 10.00px;
}
.error-title,
.error-desc {
display:block;
}
.error-title {
font-size:15.00px;
font-weight:600;
}
.error-desc {
margin-top:4.00px;
color:var(--color-text-tertiary);
font-size:12.00px;
}
.retry-btn {
width:110.00px;
min-height:var(--tap-min);
margin-top:12.00px;
border:0;
border-radius:var(--radius-full);
background:var(--color-primary-solid);
color:var(--color-text-inverse);
font-size:13.00px;
line-height:var(--tap-min);
min-width:var(--tap-min);}
.retry-btn::after {
border:0;
}
@import "../../styles/service-page.wxss";
.content-page{min-height:100vh;padding-bottom:20.00px;background:var(--color-bg-page)}.content-categories{padding:12.00px 0;white-space:nowrap}.content-category-row{display:inline-flex;gap:6.00px;padding:0 12.00px}.content-category{padding:5.50px 11.00px;border-radius:12.00px;background:var(--color-bg-card);color:var(--color-text-tertiary);font-size:12.00px;box-shadow:0 3.00px 9.00px rgba(35,35,95,.05)}.content-category.active{background:var(--gradient-brand-solid);color:var(--color-text-inverse);font-weight:600}.content-list{padding:0 12.00px}.content-card{display:flex;align-items:center;overflow:hidden;min-height:75.00px;margin-bottom:8.00px;border-radius:12.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.content-cover{width:88.00px;height:75.00px;flex:none}.content-card__body{display:flex;flex:1;min-width:0;flex-direction:column;padding:8.00px}.content-card__category{align-self:flex-start;padding:2.00px 5.00px;border-radius:6.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-size:12.00px}.content-card__title{overflow:hidden;margin-top:4.00px;color:var(--color-text-strong);font-size:12.00px;font-weight:600;white-space:nowrap;text-overflow:ellipsis}.content-card__summary{overflow:hidden;margin-top:2.50px;color:var(--color-text-tertiary);font-size:12.00px;white-space:nowrap;text-overflow:ellipsis}.content-card__meta{display:flex;gap:9.00px;margin-top:4.50px;color:var(--color-text-tertiary);font-size:12.00px}.content-card__arrow{width:12.00px;height:12.00px;margin-right:8.00px;flex:none}
/**
* 丹阳公益婚恋服务平台 - 全局 Design Token
*
* v2(2026-09-22 设计系统夯实)
* ---------------------------------------------------------------
* 本次修订针对审计发现的系统性问题,逐条给出依据:
*
* 1) 品牌色不能承载文字 → 引入「基础色 / -strong」分级
* #E96B6B on 白 = 3.10:1,白字 on #E96B6B = 3.10:1,on #FFF3F2 = 2.85:1,
* 三条路径都不满足正文 4.5:1。故:
* --color-primary 仅用于大色块、渐变、光晕、装饰(非文字)
* --color-primary-strong 用于文字、小图标、纯文字链接(5.33:1 ✓)
* --color-primary-solid 实心按钮底(白字 ≥4.5:1 ✓)
* 功能色(success/warning/danger/info)同此分级。
*
* 2) 次要文字对比度过低
* 旧 --color-text-tertiary(#777) = 4.48(on 白,勉强)/ #999 实测 2.85 却被用了 71 次。
* 现将三级文字压到 #646C85 = 5.22:1,占位符保留浅色(占位符非正文)。
*
* 3) 颜色碎片化
* 审计前全站 182 种 hex、770 次硬编码(54 种灰、60 种蓝紫、40 种红橙)。
* 本文件是唯一的颜色事实源;页面层禁止再写 hex,一律 var(--token)。
*
* 4) 触摸目标
* 组件库默认按钮只有 40px、小号 28px、"喜欢"按钮 31px。
* 统一以 --tap-min(44.00px=44px) 为下限,--tap-gap 为最小间距。
*
* 5) 动效几乎未落地(--motion-* 全站仅 5 次引用)
* 补充 --ease-spring 与 --press-scale,让点击有即时反馈。
*
* 6) 夜间氛围层缺失(参考图有明显的光晕/星点,代码只有纯渐变)
* 新增 --mini-glow-* / --mini-star / --mini-glass / --mini-hairline。
*
* 单位说明:rpx(375.00px = 屏幕宽度,0.50px ≈ 0.5px @375pt)
* 旧 token 名全部保留(88 个 wxss 共 909 处引用),只更新取值,避免大范围失效。
*/
.wx-page {
/* ============ 品牌主色(分级:色块 / 文字 / 实心按钮) ============ */
--color-primary: #E96B6B; /* 基础色:渐变、光晕、装饰、非文字图形 */
--color-primary-strong: #B8434A; /* 文字与小图标(5.33:1 on 白,4.91:1 on 浅粉底) */
--color-primary-solid: #C24C50; /* 实心按钮底(白字 4.62:1) */
--color-primary-active: #D95F5F; /* 按压态(配合 --color-primary 使用) */
--color-primary-light: #FFF3F2;
--color-primary-lighter: #FFF8F7;
/* ============ 小程序参考图品牌主题(夜间紫蓝) ============ */
--mini-night-start: #172A72;
--mini-night-end: #25104F;
--mini-night-soft: #3445A1;
--mini-accent-pink: #FF4F91; /* 点缀色:仅用于色块/装饰,不作正文 */
--mini-accent-coral: #FF6A78;
--mini-card-bg: rgba(255, 255, 255, 0.98);
--mini-text: #1F2744;
--mini-muted: #7D839B;
--mini-card-radius: 12.00px;
--mini-text-on-night: #FFFFFF; /* on 深底 13.04:1 ✓ */
--mini-text-on-night-muted: rgba(255, 255, 255, 0.72); /* on 深底 ≈8:1 ✓ */
--mini-shadow: 0 8.00px 20.00px rgba(28, 30, 88, 0.14);
/* ---- 渐变(集中定义:此前 4 个页面各写了一份「橙红渐变」按钮) ---- */
/* --gradient-brand 明亮活泼,但白字仅 2.77:1 —— 只能用于无文字的装饰填充。 */
--gradient-brand: linear-gradient(135deg, #FF6A78 0%, #E96B6B 100%);
/* 承载白字的 CTA 渐变:两端 #C24C50(4.73:1) / #B8434A(5.33:1) 均达标。 */
--gradient-brand-solid: linear-gradient(135deg, #C24C50 0%, #B8434A 100%);
--gradient-night: linear-gradient(160deg, #172A72 0%, #25104F 100%);
--gradient-night-soft: linear-gradient(160deg, #3445A1 0%, #172A72 100%);
/* ---- 首页 4×2 入口宫格图标渐变(参考图 2:高饱和圆角砖 + 白色描画图标) ----
白图标的对比度判据是**非文本图形 3:1**(WCAG 1.4.11)。渐变是斜向的、图标又跨在
两色之间,所以**较亮的一端也必须达标** —— 下表注释给的是 0% 处实算值,100% 更暗只会更高。
色相按业务语义固定(不随 tone 名漂移):找对象/婚前辅导=玫瑰粉系、公益红娘/服务站=暖橙系、
公益活动=紫罗兰、婚恋咨询=蓝、婚恋课堂=紫、婚恋反诈=绿。 */
--gradient-entry-rose: linear-gradient(135deg, #F56287 0%, #F34671 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-orange: linear-gradient(135deg, #F66A06 0%, #D95E06 100%); /* 3.01:1 / 3.78:1 */
--gradient-entry-violet: linear-gradient(135deg, #A380F5 0%, #8F64F2 100%); /* 3.02:1 / 3.98:1 */
--gradient-entry-blue: linear-gradient(135deg, #5195F6 0%, #3484F4 100%); /* 3.01:1 / 3.65:1 */
--gradient-entry-purple: linear-gradient(135deg, #B27BF0 0%, #A260ED 100%); /* 3.01:1 / 3.87:1 */
--gradient-entry-pink: linear-gradient(135deg, #F2619E 0%, #F0458C 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-green: linear-gradient(135deg, #18A979 0%, #148F66 100%); /* 3.00:1 / 4.08:1 */
--gradient-entry-amber: linear-gradient(135deg, #E9740C 0%, #CC650B 100%); /* 3.01:1 / 3.86:1 */
/* 图标砖落影:比 --mini-shadow 更小,避免 4 列宫格里相邻砖块的投影互相压边 */
--mini-entry-shadow: 0 4.00px 9.00px rgba(28, 30, 88, 0.18);
/* ---- 夜间氛围层(v2 新增;参考图有光晕与星点,此前完全没有) ---- */
--mini-glow-coral: rgba(255, 79, 145, 0.40);
--mini-glow-indigo: rgba(94, 124, 255, 0.32);
--mini-glow-soft: rgba(255, 255, 255, 0.10);
--mini-star: rgba(255, 255, 255, 0.70);
--mini-glass: rgba(255, 255, 255, 0.10); /* 深底玻璃面 */
--mini-glass-strong: rgba(255, 255, 255, 0.16);
--mini-hairline: rgba(255, 255, 255, 0.16); /* 深底分隔线 */
--mini-glass-success: rgba(90, 226, 184, 0.16); /* 深底上的成功态玻璃面 */
/* 星点层:多个小径向渐变叠在夜空渐变之上。用 radial-gradient 而非图片,
避免额外请求,也便于随主题换色(index 页脚注:装饰层不承载信息)。 */
--mini-starfield:
radial-gradient(circle at 12% 18%, var(--mini-star) 0, transparent 1.25px),
radial-gradient(circle at 31% 66%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 57% 12%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 79% 52%, var(--mini-star) 0, transparent 1.50px),
radial-gradient(circle at 93% 84%, var(--mini-star) 0, transparent 1.00px);
/* 横幅压暗层:保证任何底图上的白色标题都有足够对比度 */
--mini-banner-scrim: linear-gradient(90deg, rgba(23, 42, 114, 0.84) 0%, rgba(37, 16, 79, 0.40) 56%, rgba(255, 79, 145, 0.12) 100%);
/* ============ 功能色(同样分级) ============ */
--color-success: #2E9B68; /* 色块/图标 */
--color-success-strong: #17805A; /* 文字(4.92:1 ✓) */
--color-success-light: #ECF8F2;
--color-warning: #E59A32; /* 色块/图标(作文字仅 2.33:1) */
--color-warning-strong: #9C5F14; /* 文字(5.17:1 ✓) */
--color-warning-light: #FFF7E9;
--color-danger: #D94A4A; /* 色块/图标 */
--color-danger-strong: #C62828; /* 文字(5.62:1 ✓) */
--color-danger-light: #FFF0F0;
--color-info: #4A7CD4; /* 色块/图标 */
--color-info-strong: #2A5DB0; /* 文字(6.38:1 ✓) */
--color-info-light: #EEF4FF;
/* ============ 强调紫(参考图的标签语言;此前散落成 6 种写法) ============ */
--color-accent-purple: #8B63BC; /* 色块/装饰 */
--color-accent-purple-strong: #7C60BC; /* 文字(5.03:1 ✓) */
--color-accent-purple-light: #F3EEFF;
/* 深色夜空底上的强调色(不可用于浅色底) */
--color-success-on-night: #A6F5D7; /* on #172A72 = 10.35:1 ✓ */
/* ============ 文字色(实测对比度 on 白 / on 页面底) ============ */
--color-text-strong: #1A1F36; /* 标题 16.24 / 14.90 ✓ */
--color-text-primary: #2A3050; /* 正文 12.83 / 11.77 ✓ */
--color-text-secondary: #4A5169; /* 次要正文 7.86 / 7.21 ✓ */
--color-text-tertiary: #646C85; /* 说明文字 5.22 / 4.79 ✓(旧 #777 为 4.48) */
--color-text-placeholder: #9AA1B4; /* 占位符(非正文,可浅) */
--color-text-disabled: #B8BDC9;
--color-text-inverse: #FFFFFF; /* 深色背景上的文字 */
/* ============ 边框与分割线 ============ */
--color-border: #E6E8EF;
--color-border-strong: #D8DBE5;
--color-divider: #EFF0F5;
--color-border-focus: #B8434A; /* 焦点环用 strong,保证 3:1 可见度 */
--color-border-error: #C62828;
/* ============ 背景(避免纯白/纯灰平铺,页面底为暖白) ============ */
--color-bg-page: #F6F5F3;
--color-bg-card: #FFFFFF;
--color-bg-subtle: #F5F6FA; /* 次级区块、内嵌列表 */
--color-bg-muted: #EEF0F6; /* 更弱的填充 */
--color-bg-input: #F7F8FB; /* 表单输入框底(此前被引用但从未定义,导致背景失效) */
--color-bg-disabled: #F3F4F7;
--color-bg-overlay: rgba(0, 0, 0, 0.45);
/* ============ 字体 ============ */
/* 小程序无法可靠加载 Web Font(wx.loadFontFace 依赖 HTTPS 白名单且有闪动风险),
故使用中文系统字栈:iOS 走苹方、Android 走思源/系统黑体。
排版辨识度靠字号阶梯与字重建立,而非依赖字体本身。 */
--font-family-cn: -apple-system, "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
--font-family-number: "SF Pro Display", -apple-system, "DIN Alternate", "PingFang SC", sans-serif;
/* 字号阶梯 —— 正文 16.00px(16px) 起,元信息下限 12.00px(12px) */
--font-size-micro: 11.00px; /* 11px 仅角标/装饰,禁用于正文 */
--font-size-xs: 12.00px; /* 12px 元信息下限 */
--font-size-sm: 13.00px; /* 13px 次要说明 */
--font-size-md: 14.00px; /* 14px 次要正文 */
--font-size-base: 16.00px; /* 16px 正文 */
--font-size-lg: 18.00px; /* 18px 小标题 */
--font-size-xl: 20.00px; /* 20px 区块标题 */
--font-size-2xl: 24.00px; /* 24px 页面标题 */
--font-size-3xl: 28.00px; /* 28px 大标题 */
--font-size-display: 32.00px; /* 32px Hero */
/* 字重:只用 4 档。禁止 550/650/750 等非百位值 —— Android 无对应字重会回退,
导致同一设计在不同机型上粗细不一致(审计发现 30 处)。 */
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.65;
--letter-spacing-tight: 0;
--letter-spacing-wide: 0.50px;
--letter-spacing-wider: 1.00px;
/* ============ 间距(4px 栅格) ============ */
--spacing-1: 4.00px;
--spacing-2: 8.00px;
--spacing-3: 12.00px;
--spacing-4: 16.00px;
--spacing-5: 20.00px;
--spacing-6: 24.00px;
--spacing-8: 32.00px;
--spacing-10: 40.00px;
--spacing-12: 48.00px;
--spacing-page-x: 16.00px;
--spacing-section: 24.00px;
--spacing-card-inner: 16.00px;
--spacing-tight: 8.00px;
/* ============ 圆角 ============ */
--radius-sm: 8.00px;
--radius-md: 12.00px;
--radius-lg: 16.00px;
--radius-xl: 20.00px;
--radius-2xl: 24.00px;
--radius-full: 4999.50px;
/* ============ 阴影(统一为一套,此前 30+ 种近似值) ============ */
--shadow-card: 0 4.00px 14.00px rgba(35, 35, 95, 0.07);
--shadow-raised: 0 6.00px 18.00px rgba(35, 35, 95, 0.10);
--shadow-popup: 0 8.00px 32.00px rgba(0, 0, 0, 0.10);
--shadow-night: 0 8.00px 20.00px rgba(28, 30, 88, 0.18);
/* ============ 边框宽度 ============ */
--border-width: 0.50px;
--border-width-strong: 1.00px;
/* ============ 触摸目标(无障碍下限 44×44px) ============ */
--tap-min: 44.00px; /* 44px 最小可点区域 */
--tap-comfortable: 48.00px; /* 48px 舒适尺寸:主操作 */
--tap-gap: 8.00px; /* 8px 相邻目标最小间距 */
/* ============ 动效 ============ */
--motion-fast: 120ms;
--motion-normal: 200ms;
--motion-slow: 300ms;
--ease-standard: cubic-bezier(0.32, 0.72, 0, 1);
--ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
--press-scale: 0.97;
--press-opacity: 0.88;
/* ============ 层级 z-index ============ */
--z-base: 1;
--z-sticky: 100;
--z-tabbar: 200;
--z-dropdown: 500;
--z-modal: 1000;
--z-toast: 2000;
--z-ambient: 0;
/* ============ 页面基础样式 ============ */
background-color: var(--color-bg-page);
font-family: var(--font-family-cn);
font-size: var(--font-size-base);
color: var(--color-text-primary);
line-height: var(--line-height-normal);
}
/* ==========================================================================
通用工具类
========================================================================== */
.container {
padding: var(--spacing-page-x);
}
.flex { display: flex; }
.flex-column { display: flex; flex-direction: column; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-start { display: flex; align-items: center; justify-content: flex-start; }
.flex-1 { flex: 1; min-width: 0; }
.flex-shrink-0 { flex-shrink: 0; }
.wrap { flex-wrap: wrap; }
/* 4 列宫格:用 flex + 百分比宽度实现。
注:display:grid 在 WebView 渲染下可用,但 Skyline 不支持,故统一改为 flex 以免疫渲染引擎迁移。*/
.grid-4 {
display: flex;
flex-wrap: wrap;
}
.grid-4 > .grid-item {
width: 25%;
box-sizing: border-box;
}
.text-strong { color: var(--color-text-strong); }
.text-primary { color: var(--color-text-primary); }
.text-secondary { color: var(--color-text-secondary); }
.text-tertiary { color: var(--color-text-tertiary); }
.text-placeholder { color: var(--color-text-placeholder); }
.text-white { color: var(--color-text-inverse); }
.text-brand { color: var(--color-primary-strong); }
/* 品牌色作文字只能用 -strong 变体:基础色 #E96B6B 在白底仅 3.10:1。
保留 .text-brand-soft 这个类名是为了不破坏既有引用,取值已统一到 -strong,
如需「更亮的品牌色」请用于背景/图形而非文字。 */
.text-brand-soft { color: var(--color-primary-strong); }
.text-success { color: var(--color-success-strong); }
.text-warning { color: var(--color-warning-strong); }
.text-danger { color: var(--color-danger-strong); }
.text-info { color: var(--color-info-strong); }
.font-micro { font-size: var(--font-size-micro); }
.font-xs { font-size: var(--font-size-xs); }
.font-sm { font-size: var(--font-size-sm); }
.font-md { font-size: var(--font-size-md); }
.font-base { font-size: var(--font-size-base); }
.font-lg { font-size: var(--font-size-lg); }
.font-xl { font-size: var(--font-size-xl); }
.font-2xl { font-size: var(--font-size-2xl); }
.font-3xl { font-size: var(--font-size-3xl); }
.font-display { font-size: var(--font-size-display); }
.font-regular { font-weight: var(--font-weight-regular); }
.font-medium { font-weight: var(--font-weight-medium); }
.font-semibold { font-weight: var(--font-weight-semibold); }
.font-bold { font-weight: var(--font-weight-bold); }
.mt-1 { margin-top: var(--spacing-1); }
.mt-2 { margin-top: var(--spacing-2); }
.mt-3 { margin-top: var(--spacing-3); }
.mt-4 { margin-top: var(--spacing-4); }
.mt-5 { margin-top: var(--spacing-5); }
.mt-6 { margin-top: var(--spacing-6); }
.mb-1 { margin-bottom: var(--spacing-1); }
.mb-2 { margin-bottom: var(--spacing-2); }
.mb-3 { margin-bottom: var(--spacing-3); }
.mb-4 { margin-bottom: var(--spacing-4); }
.mb-5 { margin-bottom: var(--spacing-5); }
.mb-6 { margin-bottom: var(--spacing-6); }
/* 文本省略 */
.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ellipsis-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
/* 安全区底部留白(避开 Home Indicator) */
.safe-area-bottom {
padding-bottom: 0px;
}
/* 页面卡片基础样式 */
.card-base {
background: var(--color-bg-card);
border-radius: var(--radius-lg);
padding: var(--spacing-card-inner);
box-shadow: var(--shadow-card);
}
/* 分割线 */
.divider {
height: var(--border-width);
background: var(--color-divider);
}
/* ==========================================================================
可访问性:只用 token,不用工具类(2026-09-23 修订)
--------------------------------------------------------------------------
v2 曾在此处新增 .tap-min / .tap-gap / .focusable / .pressable 四个工具类。
复检发现全部零引用(等价能力已各自写在组件样式内,例如 button/index.wxss
直接使用 min-height:var(--tap-min)),且存在两个硬问题:
1) `.tap-gap > * + *` 用了通配符与兄弟选择器 —— WXSS 不支持,
wcc 编译期直接报 `error at token '*'`,导致整个小程序编译失败。
(这是编译错误,不是静默失效,代价最高。)
2) `.pressable:active` / `.focusable:focus-visible` 的伪类在 view 上
不生效(小程序须用 hover-class),属于"写了等于没写"。
故整块移除,保留 token。需要热区/间距时直接引用 token:
min-height: var(--tap-min); → 44.00px = 44px,最小可点区域
gap: var(--tap-gap); → 8.00px = 8px,相邻目标间距(flex gap)
【WXSS 禁用清单】星号通配符、兄弟选择器、属性选择器。
【注释约束】WXSS 注释**不可嵌套**:内层注释的结束标记会提前终止外层注释,
其后的文字会被当成真实样式解析,导致编译失败或样式被污染。
(2026-09-23 实证:本块注释初版即踩此坑。)
========================================================================== */
.wx-page{background:var(--color-bg-page)}.service-page{min-height:100vh;padding-bottom:calc(70.00px + 0px)}.hero{padding:22.00px 16.00px 27.00px;background:linear-gradient(140deg,var(--color-primary-lighter),var(--color-warning-light));position:relative;overflow:hidden}.eyebrow{display:inline-flex;padding:3.50px 7.00px;border-radius:499.50px;background:rgba(255,255,255,.72);color:var(--color-primary-strong);font-size:12.00px}.hero-title{display:block;margin-top:9.00px;font-size:20.00px;font-weight:700;line-height:1.35}.hero-desc{display:block;width:82%;margin-top:7.00px;font-size:12.50px;color:var(--color-text-secondary);line-height:1.7}.content{padding:0 var(--spacing-page-x)}.block{margin-top:var(--spacing-section)}.block-title{display:block;font-size:15.50px;font-weight:600}.block-subtitle{display:block;margin-top:4.00px;font-size:12.00px;color:var(--color-text-tertiary)}.card{margin-top:9.00px;padding:14.00px;background:var(--color-bg-card);border:0.50px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-card)}.feature-row,.menu-row,.record-row{display:flex;align-items:center;gap:10.00px;min-height:56.00px;padding:9.00px 0;border-bottom:0.50px solid var(--color-divider)}.feature-row:last-child,.menu-row:last-child,.record-row:last-child{border-bottom:0}.feature-icon{width:36.00px;height:36.00px;display:flex;align-items:center;justify-content:center;flex:none;border-radius:11.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-weight:700}.feature-copy{flex:1;min-width:0}.feature-title{display:block;font-size:14.00px;font-weight:600}.feature-desc,.meta{display:block;margin-top:3.50px;font-size:12.00px;color:var(--color-text-tertiary);line-height:1.55}.arrow{font-size:20.00px;color:var(--color-text-disabled)}.tag{display:inline-flex;margin-right:5.00px;margin-top:5.00px;padding:3.00px 6.50px;border-radius:499.50px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px}.tag.warning{background:var(--color-warning-light);color:var(--color-warning-strong)}.primary-btn,.secondary-btn{height:44.00px;display:flex;align-items:center;justify-content:center;border-radius:22.00px;font-size:14.00px;font-weight:600}.primary-btn{background:var(--gradient-brand-solid);color:var(--color-text-inverse);box-shadow:0 5.00px 12.00px rgba(255,92,130,.22)}.primary-btn.disabled{background:var(--color-bg-muted);color:var(--color-text-tertiary);box-shadow:none}.secondary-btn{background:var(--color-primary-light);color:var(--color-primary-strong)}.fixed-action{position:fixed;left:0;right:0;bottom:0;padding:9.00px var(--spacing-page-x) calc(9.00px + 0px);background:rgba(255,255,255,.96);border-top:0.50px solid var(--color-divider);z-index:100}.field{margin-top:13.00px}.label{display:block;margin-bottom:6.00px;font-size:12.50px;font-weight:600}.input,.select-box,.textarea{width:100%;box-sizing:border-box;background:var(--color-bg-page);border:0.50px solid var(--color-border);border-radius:var(--radius-md);font-size:13.00px}.input,.select-box{height:44.00px;padding:0 12.00px;display:flex;align-items:center}.textarea{min-height:90.00px;padding:11.00px}.notice{margin-top:10.00px;padding:11.00px;border-radius:var(--radius-md);background:var(--color-info-light);color:var(--color-text-secondary);font-size:12.00px;line-height:1.65}.select-box.is-readonly{background:var(--color-bg-subtle);color:var(--color-text-secondary)}.empty-panel{text-align:center;padding:35.00px 15.00px}.empty-symbol{width:48.00px;height:48.00px;margin:auto;display:flex;align-items:center;justify-content:center;border-radius:15.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-size:18.00px;font-weight:700}.empty-title{display:block;margin-top:11.00px;font-size:15.00px;font-weight:600}.article-card{margin-top:9.00px;background:var(--color-bg-card);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-card)}.article-cover{height:110.00px;padding:12.00px;background:linear-gradient(135deg,var(--color-warning-light),var(--color-warning-light));display:flex;align-items:flex-end}.article-cover text{font-size:21.00px;color:rgba(125,76,63,.52);font-weight:700}.article-body{padding:12.00px}.article-title{display:block;font-size:14.50px;font-weight:600;line-height:1.45}.article-meta{display:block;margin-top:5.00px;font-size:12.00px;color:var(--color-text-tertiary)}.article-content{padding:16.00px;background:var(--color-bg-card);font-size:14.00px;line-height:1.9;color:var(--color-text-secondary)}.article-content .lead{display:block;font-size:15.50px;color:var(--color-text-primary);font-weight:600;margin-bottom:12.00px}.danger-card{background:var(--color-primary-lighter);border-color:var(--color-primary-light)}.danger-card .feature-icon{background:var(--color-warning-light);color:var(--color-warning-strong)}@media(max-width:340px){.hero-title{font-size:18.00px}.hero-desc{width:92%}}
.service-shell{min-height:100vh;padding-bottom:calc(68.00px + 0px);background:var(--color-bg-page)}.service-content{padding:4.00px 12.00px 18.00px}.service-status{display:flex;align-items:center;justify-content:space-between;margin-top:12.00px;padding:10.00px 12.00px;border-radius:11.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-status__label{color:var(--color-text-tertiary);font-size:12.00px}.service-status__value{padding:3.00px 7.00px;border-radius:9.00px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px;font-weight:600}.service-status__value.disabled{background:var(--color-danger-light);color:var(--color-danger-strong)}.service-topics{display:grid;grid-template-columns:repeat(2,1fr);gap:8.00px;margin-top:9.00px}.service-topic{min-height:74.00px;padding:10.00px;border-radius:12.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-topic__icon{display:flex;align-items:center;justify-content:center;width:27.00px;height:27.00px;border-radius:8.50px;background:var(--color-primary-light)}.service-topic__icon image{width:17.00px;height:17.00px}.service-topic__title{display:block;margin-top:6.50px;color:var(--color-text-strong);font-size:12.00px;font-weight:600}.service-topic__desc{display:block;margin-top:3.00px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}.service-actions{display:flex;gap:7.00px}.service-actions .secondary-btn{width:95.00px;flex:none}.service-actions .primary-btn{flex:1}.privacy-note{display:flex;align-items:flex-start;gap:7.00px;margin-top:11.00px;padding:10.00px;border-radius:11.00px;background:var(--color-info-light);color:var(--color-text-tertiary);font-size:12.00px;line-height:1.55}.privacy-note image{width:17.00px;height:17.00px;flex:none}
/* ==== miniapp/components/service-hero ==== */
.service-hero {
position:relative;
height:150.00px;
overflow:hidden;
border-radius:0 0 16.00px 16.00px;
background:var(--color-primary-light);
}
.service-hero__image,
.service-hero__veil {
position:absolute;
inset:0;
width:100%;
height:100%;
}
.service-hero__veil {
background:linear-gradient(90deg, rgba(255, 250, 252, 0.98) 0%, rgba(255, 250, 252, 0.82) 38%, rgba(255, 250, 252, 0.08) 70%);
}
.service-hero--night .service-hero__veil {
background:linear-gradient(90deg, rgba(18, 24, 83, 0.92) 0%, rgba(34, 31, 111, 0.64) 42%, rgba(34, 31, 111, 0.08) 72%);
}
.service-hero__content {
position:relative;
z-index:1;
display:flex;
flex-direction:column;
justify-content:center;
width:54%;
height:100%;
padding:0 18.00px;
box-sizing:border-box;
}
.service-hero__eyebrow {
margin-bottom:5.00px;
color:var(--color-primary-strong);
font-size:12.00px;
font-weight:600;
letter-spacing:1.00px;
}
.service-hero__title {
color:var(--color-text-strong);
font-size:20.00px;
font-weight:700;
line-height:1.28;
}
.service-hero__subtitle {
margin-top:7.00px;
color:var(--color-text-tertiary);
font-size:12.00px;
line-height:1.55;
}
.service-hero--night .service-hero__eyebrow,
.service-hero--night .service-hero__title,
.service-hero--night .service-hero__subtitle {
color:var(--color-text-inverse);
}
@import "../../styles/service-page.wxss";
.risk-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:8.00px;margin-top:9.00px}.risk-card{display:flex;min-height:87.00px;flex-direction:column;padding:10.00px;border:0.50px solid var(--color-primary-light);border-radius:12.00px;background:var(--color-bg-page)}.risk-card image{width:21.00px;height:21.00px}.risk-title{margin-top:5.00px;color:var(--color-primary-strong);font-size:12.00px;font-weight:600}.risk-desc{margin-top:3.50px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.5}.safety-steps{overflow:hidden;margin-top:9.00px;border-radius:12.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.safety-step{display:flex;align-items:center;gap:8.00px;min-height:52.00px;padding:8.00px 10.00px;border-bottom:0.50px solid var(--color-divider)}.safety-step:last-child{border-bottom:0}.safety-step>image{width:24.00px;height:24.00px;flex:none}.safety-step>view{display:flex;flex:1;flex-direction:column}.safety-step view text:first-child{color:var(--color-text-strong);font-size:12.00px;font-weight:600}.safety-step view text:last-child{margin-top:2.50px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}
/**
* 丹阳公益婚恋服务平台 - 全局 Design Token
*
* v2(2026-09-22 设计系统夯实)
* ---------------------------------------------------------------
* 本次修订针对审计发现的系统性问题,逐条给出依据:
*
* 1) 品牌色不能承载文字 → 引入「基础色 / -strong」分级
* #E96B6B on 白 = 3.10:1,白字 on #E96B6B = 3.10:1,on #FFF3F2 = 2.85:1,
* 三条路径都不满足正文 4.5:1。故:
* --color-primary 仅用于大色块、渐变、光晕、装饰(非文字)
* --color-primary-strong 用于文字、小图标、纯文字链接(5.33:1 ✓)
* --color-primary-solid 实心按钮底(白字 ≥4.5:1 ✓)
* 功能色(success/warning/danger/info)同此分级。
*
* 2) 次要文字对比度过低
* 旧 --color-text-tertiary(#777) = 4.48(on 白,勉强)/ #999 实测 2.85 却被用了 71 次。
* 现将三级文字压到 #646C85 = 5.22:1,占位符保留浅色(占位符非正文)。
*
* 3) 颜色碎片化
* 审计前全站 182 种 hex、770 次硬编码(54 种灰、60 种蓝紫、40 种红橙)。
* 本文件是唯一的颜色事实源;页面层禁止再写 hex,一律 var(--token)。
*
* 4) 触摸目标
* 组件库默认按钮只有 40px、小号 28px、"喜欢"按钮 31px。
* 统一以 --tap-min(44.00px=44px) 为下限,--tap-gap 为最小间距。
*
* 5) 动效几乎未落地(--motion-* 全站仅 5 次引用)
* 补充 --ease-spring 与 --press-scale,让点击有即时反馈。
*
* 6) 夜间氛围层缺失(参考图有明显的光晕/星点,代码只有纯渐变)
* 新增 --mini-glow-* / --mini-star / --mini-glass / --mini-hairline。
*
* 单位说明:rpx(375.00px = 屏幕宽度,0.50px ≈ 0.5px @375pt)
* 旧 token 名全部保留(88 个 wxss 共 909 处引用),只更新取值,避免大范围失效。
*/
.wx-page {
/* ============ 品牌主色(分级:色块 / 文字 / 实心按钮) ============ */
--color-primary: #E96B6B; /* 基础色:渐变、光晕、装饰、非文字图形 */
--color-primary-strong: #B8434A; /* 文字与小图标(5.33:1 on 白,4.91:1 on 浅粉底) */
--color-primary-solid: #C24C50; /* 实心按钮底(白字 4.62:1) */
--color-primary-active: #D95F5F; /* 按压态(配合 --color-primary 使用) */
--color-primary-light: #FFF3F2;
--color-primary-lighter: #FFF8F7;
/* ============ 小程序参考图品牌主题(夜间紫蓝) ============ */
--mini-night-start: #172A72;
--mini-night-end: #25104F;
--mini-night-soft: #3445A1;
--mini-accent-pink: #FF4F91; /* 点缀色:仅用于色块/装饰,不作正文 */
--mini-accent-coral: #FF6A78;
--mini-card-bg: rgba(255, 255, 255, 0.98);
--mini-text: #1F2744;
--mini-muted: #7D839B;
--mini-card-radius: 12.00px;
--mini-text-on-night: #FFFFFF; /* on 深底 13.04:1 ✓ */
--mini-text-on-night-muted: rgba(255, 255, 255, 0.72); /* on 深底 ≈8:1 ✓ */
--mini-shadow: 0 8.00px 20.00px rgba(28, 30, 88, 0.14);
/* ---- 渐变(集中定义:此前 4 个页面各写了一份「橙红渐变」按钮) ---- */
/* --gradient-brand 明亮活泼,但白字仅 2.77:1 —— 只能用于无文字的装饰填充。 */
--gradient-brand: linear-gradient(135deg, #FF6A78 0%, #E96B6B 100%);
/* 承载白字的 CTA 渐变:两端 #C24C50(4.73:1) / #B8434A(5.33:1) 均达标。 */
--gradient-brand-solid: linear-gradient(135deg, #C24C50 0%, #B8434A 100%);
--gradient-night: linear-gradient(160deg, #172A72 0%, #25104F 100%);
--gradient-night-soft: linear-gradient(160deg, #3445A1 0%, #172A72 100%);
/* ---- 首页 4×2 入口宫格图标渐变(参考图 2:高饱和圆角砖 + 白色描画图标) ----
白图标的对比度判据是**非文本图形 3:1**(WCAG 1.4.11)。渐变是斜向的、图标又跨在
两色之间,所以**较亮的一端也必须达标** —— 下表注释给的是 0% 处实算值,100% 更暗只会更高。
色相按业务语义固定(不随 tone 名漂移):找对象/婚前辅导=玫瑰粉系、公益红娘/服务站=暖橙系、
公益活动=紫罗兰、婚恋咨询=蓝、婚恋课堂=紫、婚恋反诈=绿。 */
--gradient-entry-rose: linear-gradient(135deg, #F56287 0%, #F34671 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-orange: linear-gradient(135deg, #F66A06 0%, #D95E06 100%); /* 3.01:1 / 3.78:1 */
--gradient-entry-violet: linear-gradient(135deg, #A380F5 0%, #8F64F2 100%); /* 3.02:1 / 3.98:1 */
--gradient-entry-blue: linear-gradient(135deg, #5195F6 0%, #3484F4 100%); /* 3.01:1 / 3.65:1 */
--gradient-entry-purple: linear-gradient(135deg, #B27BF0 0%, #A260ED 100%); /* 3.01:1 / 3.87:1 */
--gradient-entry-pink: linear-gradient(135deg, #F2619E 0%, #F0458C 100%); /* 3.01:1 / 3.54:1 */
--gradient-entry-green: linear-gradient(135deg, #18A979 0%, #148F66 100%); /* 3.00:1 / 4.08:1 */
--gradient-entry-amber: linear-gradient(135deg, #E9740C 0%, #CC650B 100%); /* 3.01:1 / 3.86:1 */
/* 图标砖落影:比 --mini-shadow 更小,避免 4 列宫格里相邻砖块的投影互相压边 */
--mini-entry-shadow: 0 4.00px 9.00px rgba(28, 30, 88, 0.18);
/* ---- 夜间氛围层(v2 新增;参考图有光晕与星点,此前完全没有) ---- */
--mini-glow-coral: rgba(255, 79, 145, 0.40);
--mini-glow-indigo: rgba(94, 124, 255, 0.32);
--mini-glow-soft: rgba(255, 255, 255, 0.10);
--mini-star: rgba(255, 255, 255, 0.70);
--mini-glass: rgba(255, 255, 255, 0.10); /* 深底玻璃面 */
--mini-glass-strong: rgba(255, 255, 255, 0.16);
--mini-hairline: rgba(255, 255, 255, 0.16); /* 深底分隔线 */
--mini-glass-success: rgba(90, 226, 184, 0.16); /* 深底上的成功态玻璃面 */
/* 星点层:多个小径向渐变叠在夜空渐变之上。用 radial-gradient 而非图片,
避免额外请求,也便于随主题换色(index 页脚注:装饰层不承载信息)。 */
--mini-starfield:
radial-gradient(circle at 12% 18%, var(--mini-star) 0, transparent 1.25px),
radial-gradient(circle at 31% 66%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 57% 12%, var(--mini-star) 0, transparent 1.00px),
radial-gradient(circle at 79% 52%, var(--mini-star) 0, transparent 1.50px),
radial-gradient(circle at 93% 84%, var(--mini-star) 0, transparent 1.00px);
/* 横幅压暗层:保证任何底图上的白色标题都有足够对比度 */
--mini-banner-scrim: linear-gradient(90deg, rgba(23, 42, 114, 0.84) 0%, rgba(37, 16, 79, 0.40) 56%, rgba(255, 79, 145, 0.12) 100%);
/* ============ 功能色(同样分级) ============ */
--color-success: #2E9B68; /* 色块/图标 */
--color-success-strong: #17805A; /* 文字(4.92:1 ✓) */
--color-success-light: #ECF8F2;
--color-warning: #E59A32; /* 色块/图标(作文字仅 2.33:1) */
--color-warning-strong: #9C5F14; /* 文字(5.17:1 ✓) */
--color-warning-light: #FFF7E9;
--color-danger: #D94A4A; /* 色块/图标 */
--color-danger-strong: #C62828; /* 文字(5.62:1 ✓) */
--color-danger-light: #FFF0F0;
--color-info: #4A7CD4; /* 色块/图标 */
--color-info-strong: #2A5DB0; /* 文字(6.38:1 ✓) */
--color-info-light: #EEF4FF;
/* ============ 强调紫(参考图的标签语言;此前散落成 6 种写法) ============ */
--color-accent-purple: #8B63BC; /* 色块/装饰 */
--color-accent-purple-strong: #7C60BC; /* 文字(5.03:1 ✓) */
--color-accent-purple-light: #F3EEFF;
/* 深色夜空底上的强调色(不可用于浅色底) */
--color-success-on-night: #A6F5D7; /* on #172A72 = 10.35:1 ✓ */
/* ============ 文字色(实测对比度 on 白 / on 页面底) ============ */
--color-text-strong: #1A1F36; /* 标题 16.24 / 14.90 ✓ */
--color-text-primary: #2A3050; /* 正文 12.83 / 11.77 ✓ */
--color-text-secondary: #4A5169; /* 次要正文 7.86 / 7.21 ✓ */
--color-text-tertiary: #646C85; /* 说明文字 5.22 / 4.79 ✓(旧 #777 为 4.48) */
--color-text-placeholder: #9AA1B4; /* 占位符(非正文,可浅) */
--color-text-disabled: #B8BDC9;
--color-text-inverse: #FFFFFF; /* 深色背景上的文字 */
/* ============ 边框与分割线 ============ */
--color-border: #E6E8EF;
--color-border-strong: #D8DBE5;
--color-divider: #EFF0F5;
--color-border-focus: #B8434A; /* 焦点环用 strong,保证 3:1 可见度 */
--color-border-error: #C62828;
/* ============ 背景(避免纯白/纯灰平铺,页面底为暖白) ============ */
--color-bg-page: #F6F5F3;
--color-bg-card: #FFFFFF;
--color-bg-subtle: #F5F6FA; /* 次级区块、内嵌列表 */
--color-bg-muted: #EEF0F6; /* 更弱的填充 */
--color-bg-input: #F7F8FB; /* 表单输入框底(此前被引用但从未定义,导致背景失效) */
--color-bg-disabled: #F3F4F7;
--color-bg-overlay: rgba(0, 0, 0, 0.45);
/* ============ 字体 ============ */
/* 小程序无法可靠加载 Web Font(wx.loadFontFace 依赖 HTTPS 白名单且有闪动风险),
故使用中文系统字栈:iOS 走苹方、Android 走思源/系统黑体。
排版辨识度靠字号阶梯与字重建立,而非依赖字体本身。 */
--font-family-cn: -apple-system, "PingFang SC", "Noto Sans SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
--font-family-number: "SF Pro Display", -apple-system, "DIN Alternate", "PingFang SC", sans-serif;
/* 字号阶梯 —— 正文 16.00px(16px) 起,元信息下限 12.00px(12px) */
--font-size-micro: 11.00px; /* 11px 仅角标/装饰,禁用于正文 */
--font-size-xs: 12.00px; /* 12px 元信息下限 */
--font-size-sm: 13.00px; /* 13px 次要说明 */
--font-size-md: 14.00px; /* 14px 次要正文 */
--font-size-base: 16.00px; /* 16px 正文 */
--font-size-lg: 18.00px; /* 18px 小标题 */
--font-size-xl: 20.00px; /* 20px 区块标题 */
--font-size-2xl: 24.00px; /* 24px 页面标题 */
--font-size-3xl: 28.00px; /* 28px 大标题 */
--font-size-display: 32.00px; /* 32px Hero */
/* 字重:只用 4 档。禁止 550/650/750 等非百位值 —— Android 无对应字重会回退,
导致同一设计在不同机型上粗细不一致(审计发现 30 处)。 */
--font-weight-regular: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.65;
--letter-spacing-tight: 0;
--letter-spacing-wide: 0.50px;
--letter-spacing-wider: 1.00px;
/* ============ 间距(4px 栅格) ============ */
--spacing-1: 4.00px;
--spacing-2: 8.00px;
--spacing-3: 12.00px;
--spacing-4: 16.00px;
--spacing-5: 20.00px;
--spacing-6: 24.00px;
--spacing-8: 32.00px;
--spacing-10: 40.00px;
--spacing-12: 48.00px;
--spacing-page-x: 16.00px;
--spacing-section: 24.00px;
--spacing-card-inner: 16.00px;
--spacing-tight: 8.00px;
/* ============ 圆角 ============ */
--radius-sm: 8.00px;
--radius-md: 12.00px;
--radius-lg: 16.00px;
--radius-xl: 20.00px;
--radius-2xl: 24.00px;
--radius-full: 4999.50px;
/* ============ 阴影(统一为一套,此前 30+ 种近似值) ============ */
--shadow-card: 0 4.00px 14.00px rgba(35, 35, 95, 0.07);
--shadow-raised: 0 6.00px 18.00px rgba(35, 35, 95, 0.10);
--shadow-popup: 0 8.00px 32.00px rgba(0, 0, 0, 0.10);
--shadow-night: 0 8.00px 20.00px rgba(28, 30, 88, 0.18);
/* ============ 边框宽度 ============ */
--border-width: 0.50px;
--border-width-strong: 1.00px;
/* ============ 触摸目标(无障碍下限 44×44px) ============ */
--tap-min: 44.00px; /* 44px 最小可点区域 */
--tap-comfortable: 48.00px; /* 48px 舒适尺寸:主操作 */
--tap-gap: 8.00px; /* 8px 相邻目标最小间距 */
/* ============ 动效 ============ */
--motion-fast: 120ms;
--motion-normal: 200ms;
--motion-slow: 300ms;
--ease-standard: cubic-bezier(0.32, 0.72, 0, 1);
--ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
--press-scale: 0.97;
--press-opacity: 0.88;
/* ============ 层级 z-index ============ */
--z-base: 1;
--z-sticky: 100;
--z-tabbar: 200;
--z-dropdown: 500;
--z-modal: 1000;
--z-toast: 2000;
--z-ambient: 0;
/* ============ 页面基础样式 ============ */
background-color: var(--color-bg-page);
font-family: var(--font-family-cn);
font-size: var(--font-size-base);
color: var(--color-text-primary);
line-height: var(--line-height-normal);
}
/* ==========================================================================
通用工具类
========================================================================== */
.container {
padding: var(--spacing-page-x);
}
.flex { display: flex; }
.flex-column { display: flex; flex-direction: column; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-start { display: flex; align-items: center; justify-content: flex-start; }
.flex-1 { flex: 1; min-width: 0; }
.flex-shrink-0 { flex-shrink: 0; }
.wrap { flex-wrap: wrap; }
/* 4 列宫格:用 flex + 百分比宽度实现。
注:display:grid 在 WebView 渲染下可用,但 Skyline 不支持,故统一改为 flex 以免疫渲染引擎迁移。*/
.grid-4 {
display: flex;
flex-wrap: wrap;
}
.grid-4 > .grid-item {
width: 25%;
box-sizing: border-box;
}
.text-strong { color: var(--color-text-strong); }
.text-primary { color: var(--color-text-primary); }
.text-secondary { color: var(--color-text-secondary); }
.text-tertiary { color: var(--color-text-tertiary); }
.text-placeholder { color: var(--color-text-placeholder); }
.text-white { color: var(--color-text-inverse); }
.text-brand { color: var(--color-primary-strong); }
/* 品牌色作文字只能用 -strong 变体:基础色 #E96B6B 在白底仅 3.10:1。
保留 .text-brand-soft 这个类名是为了不破坏既有引用,取值已统一到 -strong,
如需「更亮的品牌色」请用于背景/图形而非文字。 */
.text-brand-soft { color: var(--color-primary-strong); }
.text-success { color: var(--color-success-strong); }
.text-warning { color: var(--color-warning-strong); }
.text-danger { color: var(--color-danger-strong); }
.text-info { color: var(--color-info-strong); }
.font-micro { font-size: var(--font-size-micro); }
.font-xs { font-size: var(--font-size-xs); }
.font-sm { font-size: var(--font-size-sm); }
.font-md { font-size: var(--font-size-md); }
.font-base { font-size: var(--font-size-base); }
.font-lg { font-size: var(--font-size-lg); }
.font-xl { font-size: var(--font-size-xl); }
.font-2xl { font-size: var(--font-size-2xl); }
.font-3xl { font-size: var(--font-size-3xl); }
.font-display { font-size: var(--font-size-display); }
.font-regular { font-weight: var(--font-weight-regular); }
.font-medium { font-weight: var(--font-weight-medium); }
.font-semibold { font-weight: var(--font-weight-semibold); }
.font-bold { font-weight: var(--font-weight-bold); }
.mt-1 { margin-top: var(--spacing-1); }
.mt-2 { margin-top: var(--spacing-2); }
.mt-3 { margin-top: var(--spacing-3); }
.mt-4 { margin-top: var(--spacing-4); }
.mt-5 { margin-top: var(--spacing-5); }
.mt-6 { margin-top: var(--spacing-6); }
.mb-1 { margin-bottom: var(--spacing-1); }
.mb-2 { margin-bottom: var(--spacing-2); }
.mb-3 { margin-bottom: var(--spacing-3); }
.mb-4 { margin-bottom: var(--spacing-4); }
.mb-5 { margin-bottom: var(--spacing-5); }
.mb-6 { margin-bottom: var(--spacing-6); }
/* 文本省略 */
.ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ellipsis-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
/* 安全区底部留白(避开 Home Indicator) */
.safe-area-bottom {
padding-bottom: 0px;
}
/* 页面卡片基础样式 */
.card-base {
background: var(--color-bg-card);
border-radius: var(--radius-lg);
padding: var(--spacing-card-inner);
box-shadow: var(--shadow-card);
}
/* 分割线 */
.divider {
height: var(--border-width);
background: var(--color-divider);
}
/* ==========================================================================
可访问性:只用 token,不用工具类(2026-09-23 修订)
--------------------------------------------------------------------------
v2 曾在此处新增 .tap-min / .tap-gap / .focusable / .pressable 四个工具类。
复检发现全部零引用(等价能力已各自写在组件样式内,例如 button/index.wxss
直接使用 min-height:var(--tap-min)),且存在两个硬问题:
1) `.tap-gap > * + *` 用了通配符与兄弟选择器 —— WXSS 不支持,
wcc 编译期直接报 `error at token '*'`,导致整个小程序编译失败。
(这是编译错误,不是静默失效,代价最高。)
2) `.pressable:active` / `.focusable:focus-visible` 的伪类在 view 上
不生效(小程序须用 hover-class),属于"写了等于没写"。
故整块移除,保留 token。需要热区/间距时直接引用 token:
min-height: var(--tap-min); → 44.00px = 44px,最小可点区域
gap: var(--tap-gap); → 8.00px = 8px,相邻目标间距(flex gap)
【WXSS 禁用清单】星号通配符、兄弟选择器、属性选择器。
【注释约束】WXSS 注释**不可嵌套**:内层注释的结束标记会提前终止外层注释,
其后的文字会被当成真实样式解析,导致编译失败或样式被污染。
(2026-09-23 实证:本块注释初版即踩此坑。)
========================================================================== */
.wx-page{background:var(--color-bg-page)}.service-page{min-height:100vh;padding-bottom:calc(70.00px + 0px)}.hero{padding:22.00px 16.00px 27.00px;background:linear-gradient(140deg,var(--color-primary-lighter),var(--color-warning-light));position:relative;overflow:hidden}.eyebrow{display:inline-flex;padding:3.50px 7.00px;border-radius:499.50px;background:rgba(255,255,255,.72);color:var(--color-primary-strong);font-size:12.00px}.hero-title{display:block;margin-top:9.00px;font-size:20.00px;font-weight:700;line-height:1.35}.hero-desc{display:block;width:82%;margin-top:7.00px;font-size:12.50px;color:var(--color-text-secondary);line-height:1.7}.content{padding:0 var(--spacing-page-x)}.block{margin-top:var(--spacing-section)}.block-title{display:block;font-size:15.50px;font-weight:600}.block-subtitle{display:block;margin-top:4.00px;font-size:12.00px;color:var(--color-text-tertiary)}.card{margin-top:9.00px;padding:14.00px;background:var(--color-bg-card);border:0.50px solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-card)}.feature-row,.menu-row,.record-row{display:flex;align-items:center;gap:10.00px;min-height:56.00px;padding:9.00px 0;border-bottom:0.50px solid var(--color-divider)}.feature-row:last-child,.menu-row:last-child,.record-row:last-child{border-bottom:0}.feature-icon{width:36.00px;height:36.00px;display:flex;align-items:center;justify-content:center;flex:none;border-radius:11.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-weight:700}.feature-copy{flex:1;min-width:0}.feature-title{display:block;font-size:14.00px;font-weight:600}.feature-desc,.meta{display:block;margin-top:3.50px;font-size:12.00px;color:var(--color-text-tertiary);line-height:1.55}.arrow{font-size:20.00px;color:var(--color-text-disabled)}.tag{display:inline-flex;margin-right:5.00px;margin-top:5.00px;padding:3.00px 6.50px;border-radius:499.50px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px}.tag.warning{background:var(--color-warning-light);color:var(--color-warning-strong)}.primary-btn,.secondary-btn{height:44.00px;display:flex;align-items:center;justify-content:center;border-radius:22.00px;font-size:14.00px;font-weight:600}.primary-btn{background:var(--gradient-brand-solid);color:var(--color-text-inverse);box-shadow:0 5.00px 12.00px rgba(255,92,130,.22)}.primary-btn.disabled{background:var(--color-bg-muted);color:var(--color-text-tertiary);box-shadow:none}.secondary-btn{background:var(--color-primary-light);color:var(--color-primary-strong)}.fixed-action{position:fixed;left:0;right:0;bottom:0;padding:9.00px var(--spacing-page-x) calc(9.00px + 0px);background:rgba(255,255,255,.96);border-top:0.50px solid var(--color-divider);z-index:100}.field{margin-top:13.00px}.label{display:block;margin-bottom:6.00px;font-size:12.50px;font-weight:600}.input,.select-box,.textarea{width:100%;box-sizing:border-box;background:var(--color-bg-page);border:0.50px solid var(--color-border);border-radius:var(--radius-md);font-size:13.00px}.input,.select-box{height:44.00px;padding:0 12.00px;display:flex;align-items:center}.textarea{min-height:90.00px;padding:11.00px}.notice{margin-top:10.00px;padding:11.00px;border-radius:var(--radius-md);background:var(--color-info-light);color:var(--color-text-secondary);font-size:12.00px;line-height:1.65}.select-box.is-readonly{background:var(--color-bg-subtle);color:var(--color-text-secondary)}.empty-panel{text-align:center;padding:35.00px 15.00px}.empty-symbol{width:48.00px;height:48.00px;margin:auto;display:flex;align-items:center;justify-content:center;border-radius:15.00px;background:var(--color-primary-light);color:var(--color-primary-strong);font-size:18.00px;font-weight:700}.empty-title{display:block;margin-top:11.00px;font-size:15.00px;font-weight:600}.article-card{margin-top:9.00px;background:var(--color-bg-card);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-card)}.article-cover{height:110.00px;padding:12.00px;background:linear-gradient(135deg,var(--color-warning-light),var(--color-warning-light));display:flex;align-items:flex-end}.article-cover text{font-size:21.00px;color:rgba(125,76,63,.52);font-weight:700}.article-body{padding:12.00px}.article-title{display:block;font-size:14.50px;font-weight:600;line-height:1.45}.article-meta{display:block;margin-top:5.00px;font-size:12.00px;color:var(--color-text-tertiary)}.article-content{padding:16.00px;background:var(--color-bg-card);font-size:14.00px;line-height:1.9;color:var(--color-text-secondary)}.article-content .lead{display:block;font-size:15.50px;color:var(--color-text-primary);font-weight:600;margin-bottom:12.00px}.danger-card{background:var(--color-primary-lighter);border-color:var(--color-primary-light)}.danger-card .feature-icon{background:var(--color-warning-light);color:var(--color-warning-strong)}@media(max-width:340px){.hero-title{font-size:18.00px}.hero-desc{width:92%}}
.service-shell{min-height:100vh;padding-bottom:calc(68.00px + 0px);background:var(--color-bg-page)}.service-content{padding:4.00px 12.00px 18.00px}.service-status{display:flex;align-items:center;justify-content:space-between;margin-top:12.00px;padding:10.00px 12.00px;border-radius:11.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-status__label{color:var(--color-text-tertiary);font-size:12.00px}.service-status__value{padding:3.00px 7.00px;border-radius:9.00px;background:var(--color-success-light);color:var(--color-success-strong);font-size:12.00px;font-weight:600}.service-status__value.disabled{background:var(--color-danger-light);color:var(--color-danger-strong)}.service-topics{display:grid;grid-template-columns:repeat(2,1fr);gap:8.00px;margin-top:9.00px}.service-topic{min-height:74.00px;padding:10.00px;border-radius:12.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.service-topic__icon{display:flex;align-items:center;justify-content:center;width:27.00px;height:27.00px;border-radius:8.50px;background:var(--color-primary-light)}.service-topic__icon image{width:17.00px;height:17.00px}.service-topic__title{display:block;margin-top:6.50px;color:var(--color-text-strong);font-size:12.00px;font-weight:600}.service-topic__desc{display:block;margin-top:3.00px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}.service-actions{display:flex;gap:7.00px}.service-actions .secondary-btn{width:95.00px;flex:none}.service-actions .primary-btn{flex:1}.privacy-note{display:flex;align-items:flex-start;gap:7.00px;margin-top:11.00px;padding:10.00px;border-radius:11.00px;background:var(--color-info-light);color:var(--color-text-tertiary);font-size:12.00px;line-height:1.55}.privacy-note image{width:17.00px;height:17.00px;flex:none}
/* ==== miniapp/components/service-hero ==== */
.service-hero {
position:relative;
height:150.00px;
overflow:hidden;
border-radius:0 0 16.00px 16.00px;
background:var(--color-primary-light);
}
.service-hero__image,
.service-hero__veil {
position:absolute;
inset:0;
width:100%;
height:100%;
}
.service-hero__veil {
background:linear-gradient(90deg, rgba(255, 250, 252, 0.98) 0%, rgba(255, 250, 252, 0.82) 38%, rgba(255, 250, 252, 0.08) 70%);
}
.service-hero--night .service-hero__veil {
background:linear-gradient(90deg, rgba(18, 24, 83, 0.92) 0%, rgba(34, 31, 111, 0.64) 42%, rgba(34, 31, 111, 0.08) 72%);
}
.service-hero__content {
position:relative;
z-index:1;
display:flex;
flex-direction:column;
justify-content:center;
width:54%;
height:100%;
padding:0 18.00px;
box-sizing:border-box;
}
.service-hero__eyebrow {
margin-bottom:5.00px;
color:var(--color-primary-strong);
font-size:12.00px;
font-weight:600;
letter-spacing:1.00px;
}
.service-hero__title {
color:var(--color-text-strong);
font-size:20.00px;
font-weight:700;
line-height:1.28;
}
.service-hero__subtitle {
margin-top:7.00px;
color:var(--color-text-tertiary);
font-size:12.00px;
line-height:1.55;
}
.service-hero--night .service-hero__eyebrow,
.service-hero--night .service-hero__title,
.service-hero--night .service-hero__subtitle {
color:var(--color-text-inverse);
}
/* ==== miniapp/components/loading ==== */
.ui-loading--block {
display:flex;
flex-direction:column;
align-items:center;
justify-content:center;
padding:var(--spacing-8) var(--spacing-page-x);
}
.ui-loading--inline {
display:inline-flex;
align-items:center;
}
.ui-loading__spinner {
width:30.00px;
height:30.00px;
display:flex;
align-items:center;
justify-content:center;
}
.ui-loading__spinner-icon {
width:24.00px;
height:24.00px;
animation:ui-loading-spin 0.8s linear infinite;
}
@keyframes ui-loading-spin {
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
.ui-loading__text {
margin-top:var(--spacing-3);
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
}
/* Skeleton */
.ui-loading__skeleton {
width:100%;
}
.ui-loading__skeleton-row {
display:flex;
align-items:center;
padding:var(--spacing-3) var(--spacing-page-x);
background:var(--color-bg-card);
border-bottom:0.50px solid var(--color-divider);
}
.ui-loading__skeleton-avatar {
width:44.00px;
height:44.00px;
border-radius:50%;
background:var(--color-bg-disabled);
margin-right:var(--spacing-3);
flex-shrink:0;
}
.ui-loading__skeleton-content {
flex:1;
min-width:0;
}
.ui-loading__skeleton-line {
height:12.00px;
background:var(--color-bg-disabled);
border-radius:var(--radius-sm);
position:relative;
overflow:hidden;
}
.ui-loading__skeleton-line--title {
width:40%;
margin-bottom:var(--spacing-2);
}
.ui-loading__skeleton-line--meta {
width:70%;
}
/* shimmer */
.ui-loading__skeleton-line::after,
.ui-loading__skeleton-avatar::after {
content:'';
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background:linear-gradient(
90deg,
transparent 0%,
rgba(255, 255, 255, 0.55) 50%,
transparent 100%
);
animation:ui-loading-shimmer 1.4s ease-in-out infinite;
}
@keyframes ui-loading-shimmer {
0% { transform:translateX(-100%); }
100% { transform:translateX(100%); }
}
/* ==== miniapp/components/empty ==== */
.ui-empty {
display:flex;
flex-direction:column;
align-items:center;
padding:var(--spacing-10) var(--spacing-page-x);
text-align:center;
}
.ui-empty__illustration {
width:80.00px;
height:80.00px;
border-radius:50%;
background:var(--color-bg-disabled);
display:flex;
align-items:center;
justify-content:center;
margin-bottom:var(--spacing-4);
}
.ui-empty__icon {
width:36.00px;
height:36.00px;
opacity:0.72;
}
.ui-empty__title {
font-size:var(--font-size-lg);
font-weight:var(--font-weight-medium);
color:var(--color-text-primary);
margin-bottom:var(--spacing-2);
}
.ui-empty__desc {
font-size:var(--font-size-sm);
color:var(--color-text-tertiary);
line-height:var(--line-height-relaxed);
max-width:240.00px;
}
.ui-empty__actions {
display:flex;
flex-direction:column;
gap:var(--spacing-2);
margin-top:var(--spacing-6);
width:100%;
max-width:240.00px;
}
.ui-empty__action {
display:flex;
align-items:center;
justify-content:center;
min-height:var(--tap-min);
border-radius:var(--radius-full);
font-size:var(--font-size-base);
font-weight:var(--font-weight-medium);
min-width:var(--tap-min);}
.ui-empty__action--primary {
background:var(--color-primary-solid);
color:var(--color-text-inverse);
}
.ui-empty__action--secondary {
background:var(--color-bg-card);
color:var(--color-primary-strong);
border:0.50px solid var(--color-primary);
}
/* ==== miniapp/components/error-state ==== */
.error-state {
padding:32.00px 16.00px;
text-align:center;
background:var(--color-bg-card);
border-radius:var(--radius-lg);
}
.error-icon {
display:block;
width:36.00px;
height:36.00px;
margin:0 auto 10.00px;
}
.error-title,
.error-desc {
display:block;
}
.error-title {
font-size:15.00px;
font-weight:600;
}
.error-desc {
margin-top:4.00px;
color:var(--color-text-tertiary);
font-size:12.00px;
}
.retry-btn {
width:110.00px;
min-height:var(--tap-min);
margin-top:12.00px;
border:0;
border-radius:var(--radius-full);
background:var(--color-primary-solid);
color:var(--color-text-inverse);
font-size:13.00px;
line-height:var(--tap-min);
min-width:var(--tap-min);}
.retry-btn::after {
border:0;
}
@import "../../styles/service-page.wxss";
.station-name-card{display:flex;align-items:center;gap:9.00px;margin-top:12.00px;padding:12.00px;border-radius:13.00px;background:linear-gradient(135deg,var(--color-success-light),var(--color-primary-light));box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.station-name-card>image{width:33.00px;height:33.00px}.station-name-card>view{display:flex;flex:1;flex-direction:column}.station-name{color:var(--color-text-strong);font-size:13.50px;font-weight:700}.station-short-name{margin-top:3.00px;color:var(--color-text-tertiary);font-size:12.00px}.station-info-card{overflow:hidden;margin-top:9.00px;border-radius:13.00px;background:var(--color-bg-card);box-shadow:0 4.00px 13.00px rgba(35,35,95,.06)}.station-info-row{display:flex;align-items:center;gap:8.00px;min-height:52.00px;padding:7.00px 10.00px;border-bottom:0.50px solid var(--color-divider)}.station-info-row:last-child{border-bottom:0}.station-info-row>image:first-child{width:21.00px;height:21.00px;flex:none}.station-info-row>view{display:flex;flex:1;flex-direction:column}.station-info-label{color:var(--color-text-strong);font-size:12.00px;font-weight:600}.station-info-value{margin-top:2.50px;color:var(--color-text-tertiary);font-size:12.00px;line-height:1.45}.station-info-row .station-arrow{width:12.00px;height:12.00px}.station-services{display:grid;grid-template-columns:repeat(2,1fr);gap:7.00px;margin-top:9.00px}.station-service{display:flex;align-items:center;gap:6.00px;min-height:37.00px;padding:6.00px 8.00px;border-radius:10.00px;background:var(--color-bg-card);color:var(--color-text-secondary);font-size:12.00px;box-shadow:0 3.00px 10.00px rgba(35,35,95,.05)}.station-service image{width:17.00px;height:17.00px}.map-button{display:flex;align-items:center;justify-content:center;gap:5.00px;min-height:var(--tap-min);margin-top:10.00px;border:0.50px solid var(--color-border);border-radius:19.50px;background:var(--color-bg-card);color:var(--color-text-secondary);font-size:12.00px;min-width:var(--tap-min);}.map-button image{width:17.00px;height:17.00px}
/* 临时公告:仅当服务端返回「已发布且未过期」公告时渲染 */
.station-announcements{display:flex;flex-direction:column;gap:7.00px;margin-top:9.00px}
.station-announcement{padding:9.00px 10.00px;border-radius:10.00px;background:linear-gradient(135deg,var(--color-warning-light),var(--color-primary-light));box-shadow:0 3.00px 10.00px rgba(35,35,95,.05)}
.station-announcement-head{display:flex;align-items:center;gap:5.00px}
.station-announcement-dot{width:6.00px;height:6.00px;flex:none;border-radius:50%;background:var(--color-warning)}
.station-announcement-title{color:var(--color-warning-strong);font-size:12.00px;font-weight:700}
.station-announcement-body{display:block;margin-top:4.00px;color:var(--color-warning-strong);font-size:12.00px;line-height:1.5}
</style>
</head>
<body>
<div class="banner">
<h1>小程序 11 页 · 静态预览</h1>
<button class="nav-btn active" data-target="pg-index">index</button><button class="nav-btn" data-target="pg-discover">discover</button><button class="nav-btn" data-target="pg-messages">messages</button><button class="nav-btn" data-target="pg-activity">activity</button><button class="nav-btn" data-target="pg-mine">mine</button><button class="nav-btn" data-target="pg-matchmaker">matchmaker</button><button class="nav-btn" data-target="pg-counseling-intro">counseling-intro</button><button class="nav-btn" data-target="pg-premarital-intro">premarital-intro</button><button class="nav-btn" data-target="pg-content">content</button><button class="nav-btn" data-target="pg-anti-fraud">anti-fraud</button><button class="nav-btn" data-target="pg-service-station">service-station</button>
<span class="note">本预览为 WXML/WXSS 静态还原,非真机渲染,不含真实接口数据;底部 tabBar 按 app.json 复刻</span>
</div>
<div class="stage">
<section id="pg-index" class="preview-panel" style="display:block">
<div class="panel-caption">index.wxml</div>
<div class="phone"><div class="phone-screen"><div class="wx-page reference-page"><div class="page app-page reference-page">
<div class="night-shell">
<div class="brand-bar">
<div class="brand-lockup">
<img class="brand-logo" src="../../../miniapp/assets/brand/logo-mark.png" alt="" loading="lazy">
<div class="brand-copy">
<span class="brand-name">善缘丹阳</span>
<span class="brand-slogan">公益婚恋服务平台</span>
</div>
</div>
<div class="brand-actions">
<span class="message-label">消息</span>
<span class="badge">3</span></div>
</div>
<div class="status-strip">
<div class="status-checks">
<span class="status-check done">已完成 · 实名认证</span><span class="status-check done">已完成 · 资料审核</span><span class="status-check">待完成 · 本地资格</span>
</div>
</div>
<div class="banner-section">
<div class="banner-swiper">
<div >
<div class="banner-card">
<img class="banner-img" src="../../../miniapp/assets/brand/home-hero-v2.jpg" alt="" loading="lazy">
<div class="banner-overlay"></div>
<div class="banner-copy"><span class="banner-kicker">公益 · 本地 · 真实 · 安全</span><span class="banner-title">在丹阳,遇见认真的彼此</span><span class="banner-subtitle">公益 · 本地 · 真实 · 安全</span></div>
</div>
</div>
</div></div>
</div>
<div class="entries-card">
<div class="entries-grid">
<div class="entry-item">
<div class="entry-icon tone-rose"></div>
<span class="entry-label">找对象</span>
<span class="entry-sub">真实邂逅</span>
</div><div class="entry-item">
<div class="entry-icon tone-orange"></div>
<span class="entry-label">公益红娘</span>
<span class="entry-sub">官方牵线</span>
</div><div class="entry-item">
<div class="entry-icon tone-violet"></div>
<span class="entry-label">公益活动</span>
<span class="entry-sub">线下联谊</span>
</div><div class="entry-item">
<div class="entry-icon tone-blue"></div>
<span class="entry-label">婚恋咨询</span>
<span class="entry-sub">专业指导</span>
</div><div class="entry-item">
<div class="entry-icon tone-purple"></div>
<span class="entry-label">婚恋课堂</span>
<span class="entry-sub">提升自我</span>
</div><div class="entry-item">
<div class="entry-icon tone-pink"></div>
<span class="entry-label">婚前辅导</span>
<span class="entry-sub">幸福起航</span>
</div><div class="entry-item">
<div class="entry-icon tone-green"></div>
<span class="entry-label">婚恋反诈</span>
<span class="entry-sub">守护真爱</span>
</div><div class="entry-item">
<div class="entry-icon tone-amber"></div>
<span class="entry-label">善缘服务站</span>
<span class="entry-sub">就在身边</span>
</div>
</div>
</div>
<div class="section recommendation-section">
<div class="comp comp-ui-section-header"><div class="ui-section">
<div class="ui-section__left">
<span class="ui-section__title">今日推荐</span>
<span class="ui-section__subtitle">根据双方条件,为你认真筛选</span></div>
<div class="ui-section__action">
<span >查看更多</span>
<img class="ui-section__arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy">
</div></div>
</div>
<div class="recommend-list">
<div class="comp comp-ui-recommend-card"><div class="ui-rec">
<div class="comp comp-ui-avatar"><div class="ui-avatar ui-avatar--lg ui-avatar--">
<img class="ui-avatar__img" src="../../../miniapp/assets/brand/default-avatar.png" alt="" loading="lazy"><div class="ui-avatar__fallback">
<img class="ui-avatar__fallback-icon" src="../../../miniapp/assets/brand/default-avatar.png" alt="" loading="lazy">
</div>
</div>
</div>
<div class="ui-rec__info">
<div class="ui-rec__name-row"><span class="ui-rec__name">王女士</span><span class="ui-rec__age">28岁</span></div>
<div class="ui-rec__meta"><span >丹阳</span><span > · 163cm</span></div>
<div class="ui-rec__reasons"><span class="ui-rec__reason">同城</span><span class="ui-rec__reason">年龄相近</span><span class="ui-rec__reason">兴趣重合</span></div></div>
</div></div><div class="comp comp-ui-recommend-card"><div class="ui-rec">
<div class="comp comp-ui-avatar"><div class="ui-avatar ui-avatar--lg ui-avatar--">
<img class="ui-avatar__img" src="../../../miniapp/assets/brand/default-avatar.png" alt="" loading="lazy"><div class="ui-avatar__fallback">
<img class="ui-avatar__fallback-icon" src="../../../miniapp/assets/brand/default-avatar.png" alt="" loading="lazy">
</div>
</div>
</div>
<div class="ui-rec__info">
<div class="ui-rec__name-row"><span class="ui-rec__name">陈先生</span><span class="ui-rec__age">31岁</span></div>
<div class="ui-rec__meta"><span >丹阳</span><span > · 176cm</span></div>
<div class="ui-rec__reasons"><span class="ui-rec__reason">同城</span><span class="ui-rec__reason">择偶条件匹配</span></div></div>
</div></div></div>
</div>
<div class="section">
<div class="comp comp-ui-section-header"><div class="ui-section">
<div class="ui-section__left">
<span class="ui-section__title">善缘公益服务</span>
<span class="ui-section__subtitle">需要时,我们在这里陪伴你</span></div>
</div>
</div>
<div class="mini-rail">
<div class="mini-card">
<img class="mini-card-cover" src="../../../miniapp/assets/covers/counseling-default.jpg" alt="" loading="lazy">
<div class="mini-card-scrim"></div>
<span class="mini-card-title">公益红娘一对一</span>
<span class="mini-card-sub">了解服务</span>
</div><div class="mini-card">
<img class="mini-card-cover" src="../../../miniapp/assets/covers/counseling-default.jpg" alt="" loading="lazy">
<div class="mini-card-scrim"></div>
<span class="mini-card-title">婚恋咨询</span>
<span class="mini-card-sub">预约咨询</span>
</div>
</div><div class="section-empty">暂无待推荐的公益服务</div>
</div>
<div class="section"><div class="comp comp-ui-section-header"><div class="ui-section">
<div class="ui-section__left">
<span class="ui-section__title">近期公益活动</span>
</div>
<div class="ui-section__action">
<span >全部活动</span>
<img class="ui-section__arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy">
</div></div>
</div><div class="activity-scroll"><div class="activity-card" data-id="a1"><img class="activity-cover" src="../../../miniapp/assets/covers/activity-default.jpg" alt="" loading="lazy"><div class="activity-info"><span class="activity-tag">公益活动</span><span class="activity-title">丹阳青年公益联谊会</span><span class="activity-meta">丹阳市文化中心</span></div></div><div class="activity-card" data-id="a2"><img class="activity-cover" src="../../../miniapp/assets/covers/activity-default.jpg" alt="" loading="lazy"><div class="activity-info"><span class="activity-tag">公益活动</span><span class="activity-title">婚恋反诈公益讲堂</span><span class="activity-meta">善缘服务站·云阳街道</span></div></div></div><div class="section-empty">近期暂无可报名活动</div></div>
<div class="section"><div class="comp comp-ui-section-header"><div class="ui-section">
<div class="ui-section__left">
<span class="ui-section__title">善缘服务站</span>
<span class="ui-section__subtitle">就在身边的公益婚恋服务阵地</span></div>
</div>
</div><div class="station-card"><img class="station-cover" src="../../../miniapp/assets/covers/station-default.jpg" alt="" loading="lazy"><div class="station-info"><span class="station-name">善缘服务站(云阳街道)</span><span class="station-desc">云阳街道服务站</span><div ><span class="mini-tag">资料核验</span><span class="mini-tag">红娘咨询</span><span class="mini-tag">活动报名</span></div></div><img class="arrow-icon" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy"></div><div class="section-empty">查看线下公益服务阵地</div></div>
<div class="section"><div class="comp comp-ui-section-header"><div class="ui-section">
<div class="ui-section__left">
<span class="ui-section__title">婚恋课堂</span>
<span class="ui-section__subtitle">学习成长,收获更好的自己</span></div>
<div class="ui-section__action">
<span >更多内容</span>
<img class="ui-section__arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy">
</div></div>
</div><div class="article-list"><div class="article-row" data-id="c1"><img class="article-cover" src="../../../miniapp/assets/covers/classroom-default.jpg" alt="" loading="lazy"><div class="article-info"><span class="article-title">第一次见面,聊些什么更自然</span><span class="article-meta">善缘课堂 · 公益内容</span></div><img class="arrow-icon" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy"></div><div class="article-row" data-id="c2"><img class="article-cover" src="../../../miniapp/assets/covers/classroom-default.jpg" alt="" loading="lazy"><div class="article-info"><span class="article-title">如何判断对方是否认真</span><span class="article-meta">善缘课堂 · 公益内容</span></div><img class="arrow-icon" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy"></div></div><div class="section-empty">暂无新内容,稍后再来看看</div></div>
<div class="section">
<div class="mini-rail">
<div class="mini-card">
<img class="mini-card-cover" src="../../../miniapp/assets/covers/anti-fraud-default.jpg" alt="" loading="lazy">
<div class="mini-card-scrim"></div>
<span class="mini-card-title">善缘安全提醒</span>
</div>
<div class="mini-note">
<span class="mini-note-text">实名认证和人工审核可以提高信息真实性,交往过程中仍请谨慎涉及借款、投资和个人隐私。</span>
<span class="mini-note-link">查看婚恋反诈指南</span>
</div>
</div>
</div>
<div class="safe-area-bottom"></div>
</div>
<div class="mini-tabbar" role="tablist"><div class="mini-tabbar__item is-active"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/home-active.png" alt="首页" /><span class="mini-tabbar__label">首页</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/discover.png" alt="找对象" /><span class="mini-tabbar__label">找对象</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/message.png" alt="消息" /><span class="mini-tabbar__label">消息</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/activity.png" alt="活动" /><span class="mini-tabbar__label">活动</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/mine.png" alt="我的" /><span class="mini-tabbar__label">我的</span></div></div></div></div></div>
</section>
<section id="pg-discover" class="preview-panel" style="display:none">
<div class="panel-caption">discover.wxml</div>
<div class="phone"><div class="phone-screen"><div class="wx-page reference-page"><div class="page app-page reference-page">
<div class="discover-hero">
<div class="discover-nav">
<span class="nav-title">找对象</span>
<div class="nav-search">
<img src="../../../miniapp/assets/icons/ui/search.png" alt="" loading="lazy">
</div>
</div>
<div class="search-bar">
<div class="search-input">
<span class="search-label">搜索</span>
<input class="search-field">
</div>
</div>
<div class="filter-scroll discover-filter-chips">
<div class="filter-chips">
<div class="filter-chip">推荐</div>
<div class="filter-chip">丹阳本地</div>
<div class="filter-chip active">年龄</div>
<div class="filter-chip true">学历</div>
<div class="filter-chip true">婚姻</div>
</div>
</div>
</div>
<div class="result-head">
<div >
<span class="result-title">为你推荐</span>
<span class="result-subtitle">已按当前条件筛选</span>
</div>
<span class="result-count">3 位</span>
</div><div class="user-list candidate-list">
<div class="comp comp-ui-user-card"><div class="ui-user-card">
<div class="comp comp-ui-avatar"><div class="ui-avatar ui-avatar--lg ui-avatar--">
<img class="ui-avatar__img" src="../../../miniapp/assets/brand/default-avatar.png" alt="" loading="lazy"><div class="ui-avatar__fallback">
<img class="ui-avatar__fallback-icon" src="../../../miniapp/assets/brand/default-avatar.png" alt="" loading="lazy">
</div>
</div>
</div>
<div class="ui-user-card__body">
<div class="ui-user-card__name-row">
<span class="ui-user-card__name">王女士</span>
<span class="ui-user-card__age">28岁</span>
</div>
<div class="ui-user-card__meta">
<span >163cm · </span><span >丹阳</span>
</div>
<div class="ui-user-card__tags">
<span class="ui-user-card__tag">同城</span><span class="ui-user-card__tag">年龄相近</span>
</div></div>
<div class="ui-user-card__actions">
<slot ></slot>
</div>
</div>
</div><div class="comp comp-ui-user-card"><div class="ui-user-card">
<div class="comp comp-ui-avatar"><div class="ui-avatar ui-avatar--lg ui-avatar--">
<img class="ui-avatar__img" src="../../../miniapp/assets/brand/default-avatar.png" alt="" loading="lazy"><div class="ui-avatar__fallback">
<img class="ui-avatar__fallback-icon" src="../../../miniapp/assets/brand/default-avatar.png" alt="" loading="lazy">
</div>
</div>
</div>
<div class="ui-user-card__body">
<div class="ui-user-card__name-row">
<span class="ui-user-card__name">陈先生</span>
<span class="ui-user-card__age">31岁</span>
</div>
<div class="ui-user-card__meta">
<span >176cm · </span><span >丹阳</span>
</div>
<div class="ui-user-card__tags">
<span class="ui-user-card__tag">同城</span>
</div></div>
<div class="ui-user-card__actions">
<slot ></slot>
</div>
</div>
</div><div class="comp comp-ui-user-card"><div class="ui-user-card">
<div class="comp comp-ui-avatar"><div class="ui-avatar ui-avatar--lg ui-avatar--">
<img class="ui-avatar__img" src="../../../miniapp/assets/brand/default-avatar.png" alt="" loading="lazy"><div class="ui-avatar__fallback">
<img class="ui-avatar__fallback-icon" src="../../../miniapp/assets/brand/default-avatar.png" alt="" loading="lazy">
</div>
</div>
</div>
<div class="ui-user-card__body">
<div class="ui-user-card__name-row">
<span class="ui-user-card__name">李女士</span>
<span class="ui-user-card__age">26岁</span>
</div>
<div class="ui-user-card__meta">
<span >160cm · </span><span >丹阳</span>
</div>
</div>
<div class="ui-user-card__actions">
<slot ></slot>
</div>
</div>
</div>
<div class="list-end-hint">真诚相遇,认真选择</div></div>
</div>
<div class="mini-tabbar" role="tablist"><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/home.png" alt="首页" /><span class="mini-tabbar__label">首页</span></div><div class="mini-tabbar__item is-active"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/discover-active.png" alt="找对象" /><span class="mini-tabbar__label">找对象</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/message.png" alt="消息" /><span class="mini-tabbar__label">消息</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/activity.png" alt="活动" /><span class="mini-tabbar__label">活动</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/mine.png" alt="我的" /><span class="mini-tabbar__label">我的</span></div></div></div></div></div>
</section>
<section id="pg-messages" class="preview-panel" style="display:none">
<div class="panel-caption">messages.wxml</div>
<div class="phone"><div class="phone-screen"><div class="wx-page reference-page">
<div class="page app-page reference-page">
<div class="messages-hero">
<div class="messages-nav">
<span class="messages-title">消息</span>
<img class="messages-search" src="../../../miniapp/assets/icons/ui/search.png" alt="" loading="lazy">
</div>
<div class="message-shortcuts">
<div class="message-shortcut">
<div class="shortcut-icon shortcut-icon--blue"><img src="../../../miniapp/assets/icons/home/find-object.png" alt="" loading="lazy"></div>
<span >新朋友</span>
</div>
<div class="message-shortcut">
<div class="shortcut-icon shortcut-icon--pink"><img src="../../../miniapp/assets/brand/logo-mark.png" alt="" loading="lazy"></div>
<span >互动喜欢</span>
</div>
<div class="message-shortcut">
<div class="shortcut-icon shortcut-icon--purple"><img src="../../../miniapp/assets/icons/home/matchmaker.png" alt="" loading="lazy"></div>
<span >我的关注</span>
</div>
<div class="message-shortcut">
<div class="shortcut-icon shortcut-icon--coral"><img src="../../../miniapp/assets/icons/ui/warning.png" alt="" loading="lazy"></div>
<span >系统通知</span>
</div>
</div>
</div>
<div class="messages-content">
<div class="comp comp-ui-section-header"><div class="ui-section">
<div class="ui-section__left">
<span class="ui-section__title">最近联系</span>
</div>
</div>
</div>
<div class="conversation-list">
<div class="comp comp-ui-conversation-item"><div class="ui-conv">
<div class="ui-conv__body">
<div class="ui-conv__top">
<span class="ui-conv__name">王女士</span>
<span class="ui-conv__time">14:32</span>
</div>
<div class="ui-conv__bottom">
<span class="ui-conv__last">那我们周六下午见?</span>
<div class="ui-conv__badge">
</div></div>
</div>
</div>
</div><div class="comp comp-ui-conversation-item"><div class="ui-conv">
<div class="ui-conv__body">
<div class="ui-conv__top">
<span class="ui-conv__name">陈先生</span>
<span class="ui-conv__time">昨天</span>
</div>
<div class="ui-conv__bottom">
<span class="ui-conv__last">谢谢你的建议,我会认真考虑的。</span>
</div>
</div>
</div>
</div><div class="comp comp-ui-conversation-item"><div class="ui-conv true">
<div class="ui-conv__body">
<div class="ui-conv__top">
<span class="ui-conv__name">李女士</span>
<span class="ui-conv__time">3 天前</span>
</div>
<div class="ui-conv__bottom">
<span class="ui-conv__last">开始你们的对话吧</span>
</div>
<div class="ui-conv__status-hint">
</div></div>
</div>
</div></div>
</div>
</div>
<div class="mini-tabbar" role="tablist"><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/home.png" alt="首页" /><span class="mini-tabbar__label">首页</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/discover.png" alt="找对象" /><span class="mini-tabbar__label">找对象</span></div><div class="mini-tabbar__item is-active"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/message-active.png" alt="消息" /><span class="mini-tabbar__label">消息</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/activity.png" alt="活动" /><span class="mini-tabbar__label">活动</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/mine.png" alt="我的" /><span class="mini-tabbar__label">我的</span></div></div></div></div></div>
</section>
<section id="pg-activity" class="preview-panel" style="display:none">
<div class="panel-caption">activity.wxml</div>
<div class="phone"><div class="phone-screen"><div class="wx-page reference-page">
<div class="act-page app-page reference-page">
<div class="activity-hero">
<div class="activity-nav">
<span class="activity-title">公益活动</span>
<div class="activity-calendar">
<img src="../../../miniapp/assets/icons/home/activity.png" alt="" loading="lazy">
</div>
</div>
<div class="activity-categories">
<div class="activity-category-row">
<div class="activity-category">全部</div><div class="activity-category">公益联谊</div><div class="activity-category">婚恋课堂</div><div class="activity-category">反诈宣传</div>
</div>
</div>
</div>
<div class="activity-heading">
<div ><span class="heading-title">丹阳公益活动</span><span class="heading-subtitle">丰富活动,连接更多可能</span></div>
<span class="my-activity-link">我的活动</span>
</div>
<div class="act-list">
<div class="comp comp-ui-activity-card">
<div class="ui-act">
<div class="ui-act__cover">
<img class="ui-act__cover-img" src="../../../miniapp/assets/covers/activity-default.jpg" alt="" loading="lazy">
<div class="ui-act__fee-badge">公益活动</div>
</div>
<div class="ui-act__body">
<div class="ui-act__title">丹阳青年公益联谊会</div>
<div class="ui-act__meta"><span ></span></div>
<div class="ui-act__meta"><span >丹阳市文化中心</span></div>
<div class="ui-act__intro"></div><div class="ui-act__footer">
<div class="ui-act__capacity">
</div>
<div class="ui-act__status-action true"></div>
</div>
</div>
</div>
</div><div class="comp comp-ui-activity-card">
<div class="ui-act">
<div class="ui-act__cover">
<img class="ui-act__cover-img" src="../../../miniapp/assets/covers/activity-default.jpg" alt="" loading="lazy">
<div class="ui-act__fee-badge">公益活动</div>
</div>
<div class="ui-act__body">
<div class="ui-act__title">婚恋反诈公益讲堂</div>
<div class="ui-act__meta"><span ></span></div>
<div class="ui-act__meta"><span >善缘服务站·云阳街道</span></div>
<div class="ui-act__intro"></div><div class="ui-act__footer">
<div class="ui-act__capacity">
</div>
<div class="ui-act__status-action true"></div>
</div>
</div>
</div>
</div><div class="comp comp-ui-activity-card">
<div class="ui-act">
<div class="ui-act__cover">
<img class="ui-act__cover-img" src="../../../miniapp/assets/covers/activity-default.jpg" alt="" loading="lazy">
<div class="ui-act__fee-badge">公益活动</div>
</div>
<div class="ui-act__body">
<div class="ui-act__title">沟通与相处·婚恋课堂</div>
<div class="ui-act__meta"><span ></span></div>
<div class="ui-act__meta"><span >丹阳市图书馆</span></div>
<div class="ui-act__intro"></div><div class="ui-act__footer">
<div class="ui-act__capacity">
</div>
<div class="ui-act__status-action true"></div>
</div>
</div>
</div>
</div></div>
</div>
<div class="mini-tabbar" role="tablist"><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/home.png" alt="首页" /><span class="mini-tabbar__label">首页</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/discover.png" alt="找对象" /><span class="mini-tabbar__label">找对象</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/message.png" alt="消息" /><span class="mini-tabbar__label">消息</span></div><div class="mini-tabbar__item is-active"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/activity-active.png" alt="活动" /><span class="mini-tabbar__label">活动</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/mine.png" alt="我的" /><span class="mini-tabbar__label">我的</span></div></div></div></div></div>
</section>
<section id="pg-mine" class="preview-panel" style="display:none">
<div class="panel-caption">mine.wxml</div>
<div class="phone"><div class="phone-screen"><div class="wx-page reference-page"><div class="page app-page reference-page">
<div class="profile-hero">
<div class="mine-nav"><span >我的</span><img src="../../../miniapp/assets/icons/home/service-station.png" alt="" loading="lazy"></div>
<div class="profile-main">
<div class="comp comp-ui-avatar"><div class="ui-avatar ui-avatar--xl ui-avatar--">
<div class="ui-avatar__fallback">
<img class="ui-avatar__fallback-icon" src="../../../miniapp/assets/brand/default-avatar.png" alt="" loading="lazy">
</div>
</div>
</div>
<div class="profile-copy">
<div class="profile-name-row"><span class="profile-name">王女士</span><span class="profile-status">认真寻找中</span></div>
<span class="profile-meta">资料完整度 85%</span>
<div class="profile-progress"><div ></div></div>
<div class="profile-badges"><div class="comp comp-ui-status-badge"><div class="ui-badge ui-badge--success">
<span class="ui-badge__label">已实名</span>
</div>
</div><div class="comp comp-ui-status-badge"><div class="ui-badge ui-badge--success">
<span class="ui-badge__label">资料已审核</span>
</div>
</div></div>
</div>
<span class="edit-profile">编辑资料</span>
</div>
</div>
<div class="profile-stats">
<div class="profile-stat"><span class="stat-value">85%</span><span class="stat-label">资料完整</span></div>
<div class="profile-stat"><span class="stat-value">7</span><span class="stat-label">喜欢我的</span></div>
<div class="profile-stat"><span class="stat-value">2</span><span class="stat-label">当前缘分</span></div>
<div class="profile-stat"><span class="stat-value stat-value--text">资料已通过审核</span><span class="stat-label">资料状态</span></div>
</div>
<div class="public-identity-card">
<img src="../../../miniapp/assets/brand/logo-mark.png" alt="" loading="lazy">
<div ><span class="identity-title">我在善缘丹阳</span><span class="identity-desc">用真诚遇见美好,让爱在丹阳绽放</span></div>
<img class="identity-arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy">
</div>
<div class="comp comp-ui-section-header"><div class="ui-section">
<div class="ui-section__left">
<span class="ui-section__title">我的资料与缘分</span>
<span class="ui-section__subtitle">资料、择偶条件与当前缘分</span></div>
</div>
</div>
<div class="list-group">
<div class="list-row"><span class="list-label">我的资料</span><span class="list-value">资料已通过审核</span><img class="list-arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy"></div>
<div class="list-row"><span class="list-label">择偶条件</span><img class="list-arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy"></div>
<div class="list-row"><span class="list-label">我的缘分</span><img class="list-arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy"></div>
</div>
<div class="comp comp-ui-section-header"><div class="ui-section">
<div class="ui-section__left">
<span class="ui-section__title">我的公益服务</span>
<span class="ui-section__subtitle">服务进度与预约记录</span></div>
</div>
</div>
<div class="list-group">
<div class="list-row"><span class="list-label">公益服务中心</span><span class="list-value">咨询 · 预约 · 课堂</span><img class="list-arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy"></div>
</div>
<div class="service-grid">
<div class="service-entry"><div class="service-icon rose"><img src="../../../miniapp/assets/icons/home/matchmaker.png" alt="" loading="lazy"></div><span >我的红娘</span></div>
<div class="service-entry"><div class="service-icon blue"><img src="../../../miniapp/assets/icons/home/counseling.png" alt="" loading="lazy"></div><span >我的咨询</span></div>
<div class="service-entry"><div class="service-icon amber"><img src="../../../miniapp/assets/icons/home/activity.png" alt="" loading="lazy"></div><span >我的活动</span></div>
<div class="service-entry"><div class="service-icon green"><img src="../../../miniapp/assets/icons/home/service-station.png" alt="" loading="lazy"></div><span >我的预约</span></div>
</div>
<div class="list-group">
<div class="list-row"><span class="list-label">公益服务记录</span><span class="list-value">仅本人可见</span><img class="list-arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy"></div>
</div>
<div class="comp comp-ui-section-header"><div class="ui-section">
<div class="ui-section__left">
<span class="ui-section__title">安全与隐私</span>
<span class="ui-section__subtitle">隐私、黑名单与账号</span></div>
</div>
</div>
<div class="list-group secondary-list">
<div class="list-row"><span class="list-label">隐私设置</span><img class="list-arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy"></div>
<div class="list-row"><span class="list-label">黑名单</span><img class="list-arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy"></div>
<div class="list-row"><span class="list-label">举报与安全</span><img class="list-arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy"></div>
<div class="list-row"><span class="list-label">账号设置</span><img class="list-arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy"></div>
</div>
<div class="comp comp-ui-section-header"><div class="ui-section">
<div class="ui-section__left">
<span class="ui-section__title">公益信息</span>
<span class="ui-section__subtitle">课堂、反诈与服务站</span></div>
</div>
</div>
<div class="service-grid">
<div class="service-entry"><div class="service-icon amber"><img src="../../../miniapp/assets/icons/home/classroom.png" alt="" loading="lazy"></div><span >婚恋课堂</span></div>
<div class="service-entry"><div class="service-icon rose"><img src="../../../miniapp/assets/icons/home/anti-fraud.png" alt="" loading="lazy"></div><span >婚恋反诈</span></div>
<div class="service-entry"><div class="service-icon green"><img src="../../../miniapp/assets/icons/home/service-station.png" alt="" loading="lazy"></div><span >善缘服务站</span></div>
<div class="service-entry"><div class="service-icon blue"><img src="../../../miniapp/assets/brand/logo-mark.png" alt="" loading="lazy"></div><span >关于善缘丹阳</span></div>
</div>
<div class="logout-row">退出登录</div>
<div class="comp comp-ui-danger-action-dialog"></div>
</div>
<div class="mini-tabbar" role="tablist"><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/home.png" alt="首页" /><span class="mini-tabbar__label">首页</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/discover.png" alt="找对象" /><span class="mini-tabbar__label">找对象</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/message.png" alt="消息" /><span class="mini-tabbar__label">消息</span></div><div class="mini-tabbar__item"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/activity.png" alt="活动" /><span class="mini-tabbar__label">活动</span></div><div class="mini-tabbar__item is-active"><img class="mini-tabbar__icon" src="../../../miniapp/assets/tabbar/mine-active.png" alt="我的" /><span class="mini-tabbar__label">我的</span></div></div></div></div></div>
</section>
<section id="pg-matchmaker" class="preview-panel" style="display:none">
<div class="panel-caption">matchmaker.wxml</div>
<div class="phone"><div class="phone-screen"><div class="wx-page reference-page"><div class="mm-page app-page reference-page">
<div class="comp comp-ui-nav-bar"><div class="ui-nav ui-nav--">
<div class="ui-nav__bar">
<div class="ui-nav__placeholder"></div>
<div class="ui-nav__title">公益红娘</div>
<div class="ui-nav__right">
<slot ></slot>
</div>
</div>
</div>
</div>
<div class="comp comp-ui-service-hero"><div class="service-hero service-hero--rose">
<img class="service-hero__image" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Crect width='200' height='200' fill='%23E8EAF2'/%3E%3Ctext x='100' y='105' font-size='16' fill='%238890A8' text-anchor='middle'%3EIMG%3C/text%3E%3C/svg%3E" alt="" loading="lazy">
<div class="service-hero__veil"></div>
<div class="service-hero__content">
<span class="service-hero__eyebrow">专业牵线 · 公益助力</span><span class="service-hero__title">公益红娘</span>
<span class="service-hero__subtitle">认真倾听你的期待,帮助你认识更合适的人</span></div>
</div>
</div>
<div class="mm-promises">
<div class="mm-promise"><img src="../../../miniapp/assets/icons/home/matchmaker.png" alt="" loading="lazy"><span class="mm-promise__title">公益免费</span><span >不收取服务费用</span></div>
<div class="mm-promise"><img src="../../../miniapp/assets/icons/home/find-object.png" alt="" loading="lazy"><span class="mm-promise__title">真实匹配</span><span >基于审核资料推荐</span></div>
<div class="mm-promise"><img src="../../../miniapp/assets/icons/home/anti-fraud.png" alt="" loading="lazy"><span class="mm-promise__title">隐私保护</span><span >由你本人决定意向</span></div>
</div>
<div class="mm-body">
<div class="mm-section">
<div class="comp comp-ui-section-header"><div class="ui-section">
<div class="ui-section__left">
<span class="ui-section__title">申请状态</span>
<span class="ui-section__subtitle">红娘不会代替你表达喜欢</span></div>
</div>
</div>
<div class="comp comp-ui-matchmaker-card"><div class="ui-mm">
<div class="ui-mm__header">
<div class="ui-mm__title-row">
<span class="ui-mm__title">公益红娘服务</span>
<div class="comp comp-ui-status-badge"><div class="ui-badge ui-badge--">
<span class="ui-badge__label"></span>
</div>
</div>
</div>
<div class="ui-mm__mm-info">
<span >红娘:王老师</span>
</div><div class="ui-mm__req">
<span class="ui-mm__req-label">你的需求:</span>
<span class="ui-mm__req-content"></span>
</div>
</div>
<div class="ui-mm__footer">
<div class="comp comp-ui-button"><div class="ui-btn ui-btn--secondary ui-btn--md custom-class">
<slot ></slot>
</div>
</div>
</div></div></div><div class="mm-no-service"><img src="../../../miniapp/assets/icons/home/matchmaker.png" alt="" loading="lazy"><div ><span class="mm-no-service__title">暂未申请红娘服务</span><span class="mm-no-service__desc">提交需求后,工作人员会根据你的择偶条件提供公益协助</span></div></div>
</div>
<div class="mm-section">
<div class="comp comp-ui-section-header"><div class="ui-section">
<div class="ui-section__left">
<span class="ui-section__title">红娘可以如何帮助</span>
<span class="ui-section__subtitle">陪伴沟通,尊重你的每次决定</span></div>
</div>
</div>
<div class="mm-capability-grid">
</div>
</div>
<div class="mm-section">
<div class="comp comp-ui-section-header"><div class="ui-section">
<div class="ui-section__left">
<span class="ui-section__title">历史服务</span>
<span class="ui-section__subtitle">共 1 条</span></div>
</div>
</div>
<div class="mm-history">
<div class="mm-history__item">
<div ><span class="mm-history__title">公益红娘服务</span><span class="mm-history__meta">红娘:李老师</span></div>
<span class="mm-history__status">已完成</span>
<img src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy">
</div>
</div>
</div></div>
<div class="mm-fixed-action"><div class="mm-apply">提交新的红娘需求</div></div>
</div>
</div></div></div>
</section>
<section id="pg-counseling-intro" class="preview-panel" style="display:none">
<div class="panel-caption">counseling-intro.wxml</div>
<div class="phone"><div class="phone-screen"><div class="wx-page reference-page"><div class="service-shell app-page reference-page">
<div class="comp comp-ui-service-hero"><div class="service-hero service-hero--rose">
<img class="service-hero__image" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Crect width='200' height='200' fill='%23E8EAF2'/%3E%3Ctext x='100' y='105' font-size='16' fill='%238890A8' text-anchor='middle'%3EIMG%3C/text%3E%3C/svg%3E" alt="" loading="lazy">
<div class="service-hero__veil"></div>
<div class="service-hero__content">
<span class="service-hero__eyebrow">专业陪伴 · 严格保密</span><span class="service-hero__title">婚恋咨询</span>
<span class="service-hero__subtitle">倾听你的心声,陪你梳理关系与情绪困扰</span></div>
</div>
</div>
<div class="service-content">
<div class="service-status"><span class="service-status__label">服务状态</span><span class="service-status__value true">(serviceEnabled ? '可预约' : disabledReason)</span></div>
<div class="block"><span class="block-title">我们可以提供的帮助</span><span class="block-subtitle">选择最接近当前需要的方向</span>
<div class="service-topics">
<div class="service-topic">
<div class="service-topic__icon"><img src="../../../miniapp/assets/icons/home/counseling.png" alt="" loading="lazy"></div>
<span class="service-topic__title">一对一婚恋咨询</span><span class="service-topic__desc">面对关系困惑,与专业咨询师单独沟通。</span>
</div><div class="service-topic">
<div class="service-topic__icon"><img src="../../../miniapp/assets/icons/home/classroom.png" alt="" loading="lazy"></div>
<span class="service-topic__title">团体成长小组</span><span class="service-topic__desc">在小组中学习沟通与相处方式。</span>
</div><div class="service-topic">
<div class="service-topic__icon"><img src="../../../miniapp/assets/icons/home/premarital.png" alt="" loading="lazy"></div>
<span class="service-topic__title">婚前准备咨询</span><span class="service-topic__desc">为进入婚姻提前做好准备。</span>
</div><div class="service-topic">
<div class="service-topic__icon"><img src="../../../miniapp/assets/icons/home/service-station.png" alt="" loading="lazy"></div>
<span class="service-topic__title">公益咨询热线</span><span class="service-topic__desc">需要时,可以随时联系我们。</span>
</div>
</div>
</div>
<div class="privacy-note"><img src="../../../miniapp/assets/icons/home/anti-fraud.png" alt="" loading="lazy"><span >咨询内容按敏感信息保护。公益红娘不能查看咨询正文,咨询人员仅处理明确分配给自己的服务。</span></div>
</div>
<div class="fixed-action"><div class="service-actions"><div class="secondary-btn">我的咨询</div><div class="primary-btn true">预约咨询</div></div></div>
</div>
</div></div></div>
</section>
<section id="pg-premarital-intro" class="preview-panel" style="display:none">
<div class="panel-caption">premarital-intro.wxml</div>
<div class="phone"><div class="phone-screen"><div class="wx-page reference-page"><div class="service-shell app-page reference-page">
<div class="comp comp-ui-service-hero"><div class="service-hero service-hero--rose">
<img class="service-hero__image" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Crect width='200' height='200' fill='%23E8EAF2'/%3E%3Ctext x='100' y='105' font-size='16' fill='%238890A8' text-anchor='middle'%3EIMG%3C/text%3E%3C/svg%3E" alt="" loading="lazy">
<div class="service-hero__veil"></div>
<div class="service-hero__content">
<span class="service-hero__eyebrow">共同成长 · 面向未来</span><span class="service-hero__title">婚前辅导</span>
<span class="service-hero__subtitle">在进入婚姻前,把重要的事认真谈清楚</span></div>
</div>
</div>
<div class="service-content">
<div class="service-status"><span class="service-status__label">服务状态</span><span class="service-status__value true">(serviceEnabled ? '可预约' : disabledReason)</span></div>
<div class="block"><span class="block-title">辅导内容</span><span class="block-subtitle">科学指导,走向更稳的幸福</span>
<div class="service-topics">
<div class="service-topic">
<div class="service-topic__icon"><img src="../../../miniapp/assets/icons/home/premarital.png" alt="" loading="lazy"></div>
<span class="service-topic__title">沟通与表达</span><span class="service-topic__desc">学习把真实想法说清楚,也听懂对方。</span>
</div><div class="service-topic">
<div class="service-topic__icon"><img src="../../../miniapp/assets/icons/home/counseling.png" alt="" loading="lazy"></div>
<span class="service-topic__title">家庭与边界</span><span class="service-topic__desc">提前讨论双方家庭的相处边界。</span>
</div><div class="service-topic">
<div class="service-topic__icon"><img src="../../../miniapp/assets/icons/home/classroom.png" alt="" loading="lazy"></div>
<span class="service-topic__title">财务与规划</span><span class="service-topic__desc">把未来的开销与计划谈在前面。</span>
</div><div class="service-topic">
<div class="service-topic__icon"><img src="../../../miniapp/assets/icons/home/activity.png" alt="" loading="lazy"></div>
<span class="service-topic__title">冲突与修复</span><span class="service-topic__desc">建立遇到分歧时的处理方式。</span>
</div>
</div>
</div>
<div class="privacy-note"><img src="../../../miniapp/assets/icons/home/premarital.png" alt="" loading="lazy"><span >双方共同参与效果更好,但必须基于自愿;不会因为一方申请而自动通知或要求另一方参加。</span></div>
</div>
<div class="fixed-action"><div class="service-actions"><div class="secondary-btn">服务记录</div><div class="primary-btn true">预约辅导</div></div></div>
</div>
</div></div></div>
</section>
<section id="pg-content" class="preview-panel" style="display:none">
<div class="panel-caption">content.wxml</div>
<div class="phone"><div class="phone-screen"><div class="wx-page reference-page"><div class="content-page app-page reference-page">
<div class="comp comp-ui-service-hero"><div class="service-hero service-hero--rose">
<img class="service-hero__image" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Crect width='200' height='200' fill='%23E8EAF2'/%3E%3Ctext x='100' y='105' font-size='16' fill='%238890A8' text-anchor='middle'%3EIMG%3C/text%3E%3C/svg%3E" alt="" loading="lazy">
<div class="service-hero__veil"></div>
<div class="service-hero__content">
<span class="service-hero__eyebrow">学习成长 · 认真相遇</span><span class="service-hero__title">婚恋课堂</span>
<span class="service-hero__subtitle">学习成长,收获更好的自己</span></div>
</div>
</div>
<div class="content-categories">
<div class="content-category-row"><div class="content-category true" data-id="">推荐</div><div class="content-category" data-id="c1">相识沟通</div><div class="content-category" data-id="c2">关系经营</div><div class="content-category" data-id="c3">婚姻准备</div></div>
</div>
<div class="content-list">
<div >
<div class="content-card" data-id="a1">
<img class="content-cover" src="../../../miniapp/assets/covers/classroom-default.jpg" alt="" loading="lazy">
<div class="content-card__body"><span class="content-card__category">相识沟通</span><span class="content-card__title">第一次见面,聊些什么更自然</span><span class="content-card__summary">从共同话题切入,让交流更轻松。</span><div class="content-card__meta"><span >浏览 1280</span><span >2026-09-10</span></div></div>
<img class="content-card__arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy">
</div><div class="content-card" data-id="a2">
<img class="content-cover" src="../../../miniapp/assets/covers/classroom-default.jpg" alt="" loading="lazy">
<div class="content-card__body"><span class="content-card__category">关系经营</span><span class="content-card__title">如何判断对方是否认真</span><span class="content-card__summary">观察行动而非承诺,是更可靠的判断方式。</span><div class="content-card__meta"><span >浏览 960</span><span >2026-09-08</span></div></div>
<img class="content-card__arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy">
</div><div class="content-card" data-id="a3">
<img class="content-cover" src="../../../miniapp/assets/covers/classroom-default.jpg" alt="" loading="lazy">
<div class="content-card__body"><span class="content-card__category">婚姻准备</span><span class="content-card__title">婚前需要沟通的五件事</span><span class="content-card__summary">把重要问题谈在前面,减少未来的分歧。</span><div class="content-card__meta"><span >浏览 1520</span><span >2026-09-05</span></div></div>
<img class="content-card__arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy">
</div>
</div>
</div>
</div>
</div></div></div>
</section>
<section id="pg-anti-fraud" class="preview-panel" style="display:none">
<div class="panel-caption">anti-fraud.wxml</div>
<div class="phone"><div class="phone-screen"><div class="wx-page reference-page"><div class="service-shell fraud-page app-page reference-page">
<div class="comp comp-ui-service-hero"><div class="service-hero service-hero--rose">
<img class="service-hero__image" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Crect width='200' height='200' fill='%23E8EAF2'/%3E%3Ctext x='100' y='105' font-size='16' fill='%238890A8' text-anchor='middle'%3EIMG%3C/text%3E%3C/svg%3E" alt="" loading="lazy">
<div class="service-hero__veil"></div>
<div class="service-hero__content">
<span class="service-hero__eyebrow">提高警惕 · 守护真心</span><span class="service-hero__title">婚恋反诈</span>
<span class="service-hero__subtitle">识别风险信号,守护你的真心与财产安全</span></div>
</div>
</div>
<div class="service-content">
<div class="block"><span class="block-title">常见风险信号</span><span class="block-subtitle">出现以下情况,请先停止资金或隐私操作</span>
<div class="risk-grid">
<div class="risk-card"><img src="../../../miniapp/assets/icons/ui/warning.png" alt="" loading="lazy"><span class="risk-title">编造身份</span><span class="risk-desc">伪造职业、收入或婚恋状况获取信任。</span></div><div class="risk-card"><img src="../../../miniapp/assets/icons/ui/warning.png" alt="" loading="lazy"><span class="risk-title">诱导投资</span><span class="risk-desc">以内部渠道、稳赚不赔为由引导转账。</span></div><div class="risk-card"><img src="../../../miniapp/assets/icons/ui/warning.png" alt="" loading="lazy"><span class="risk-title">借款周转</span><span class="risk-desc">以突发困难为由频繁借款并拖延归还。</span></div><div class="risk-card"><img src="../../../miniapp/assets/icons/ui/warning.png" alt="" loading="lazy"><span class="risk-title">隐私勒索</span><span class="risk-desc">索取私密照片或信息后实施威胁。</span></div>
</div>
</div>
<div class="block"><span class="block-title">遇到可疑情况怎么办</span>
<div class="safety-steps">
<div class="safety-step"><img src="../../../miniapp/assets/icons/home/anti-fraud.png" alt="" loading="lazy"><div ><span >立即停止资金操作</span><span >不要继续转账、充值或提供验证码</span></div></div>
<div class="safety-step"><img src="../../../miniapp/assets/icons/home/classroom.png" alt="" loading="lazy"><div ><span >保存相关证据</span><span >保留聊天、付款和对方账号信息</span></div></div>
<div class="safety-step"><img src="../../../miniapp/assets/icons/home/service-station.png" alt="" loading="lazy"><div ><span >及时举报或报警</span><span >平台举报不会通知被举报人,紧急情况请拨打 110</span></div></div>
</div>
</div>
</div>
<div class="fixed-action"><div class="service-actions"><div class="secondary-btn">安全求助</div><div class="primary-btn">举报可疑行为</div></div></div>
</div>
</div></div></div>
</section>
<section id="pg-service-station" class="preview-panel" style="display:none">
<div class="panel-caption">service-station.wxml</div>
<div class="phone"><div class="phone-screen"><div class="wx-page reference-page"><div class="service-shell station-page app-page reference-page">
<div class="comp comp-ui-service-hero"><div class="service-hero service-hero--rose">
<img class="service-hero__image" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Crect width='200' height='200' fill='%23E8EAF2'/%3E%3Ctext x='100' y='105' font-size='16' fill='%238890A8' text-anchor='middle'%3EIMG%3C/text%3E%3C/svg%3E" alt="" loading="lazy">
<div class="service-hero__veil"></div>
<div class="service-hero__content">
<span class="service-hero__eyebrow">公益服务 · 就在身边</span><span class="service-hero__title">善缘服务站</span>
<span class="service-hero__subtitle">面对面提供可靠、温暖的本地婚恋服务</span></div>
</div>
</div>
<div class="service-content">
<div class="station-name-card"><img src="../../../miniapp/assets/icons/home/service-station.png" alt="" loading="lazy"><div ><span class="station-name">善缘服务站(云阳街道)</span><span class="station-short-name">云阳街道服务站</span></div></div>
<div class="station-info-card">
<div class="station-info-row"><img src="../../../miniapp/assets/icons/home/service-station.png" alt="" loading="lazy"><div ><span class="station-info-label">地址</span><span class="station-info-value">丹阳市云阳街道人民路 128 号</span></div></div>
<div class="station-info-row"><img src="../../../miniapp/assets/icons/home/counseling.png" alt="" loading="lazy"><div ><span class="station-info-label">联系电话</span><span class="station-info-value">0511-88888888</span></div><img class="station-arrow" src="../../../miniapp/assets/icons/ui/chevron-right.png" alt="" loading="lazy"></div>
<div class="station-info-row"><img src="../../../miniapp/assets/icons/home/activity.png" alt="" loading="lazy"><div ><span class="station-info-label">开放时间</span><span class="station-info-value">周一至周六 09:00-17:30</span></div></div>
</div>
<div class="block"><span class="block-title">服务项目</span><div class="station-services"><div class="station-service"><img src="../../../miniapp/assets/icons/home/matchmaker.png" alt="" loading="lazy"><span >资料核验</span></div><div class="station-service"><img src="../../../miniapp/assets/icons/home/matchmaker.png" alt="" loading="lazy"><span >公益红娘咨询</span></div><div class="station-service"><img src="../../../miniapp/assets/icons/home/matchmaker.png" alt="" loading="lazy"><span >活动报名</span></div><div class="station-service"><img src="../../../miniapp/assets/icons/home/matchmaker.png" alt="" loading="lazy"><span >服务预约</span></div></div></div>
<div class="privacy-note"><img src="../../../miniapp/assets/icons/home/anti-fraud.png" alt="" loading="lazy"><span >服务站人员仅处理现场预约与指定服务,不会浏览无关用户资料。</span></div>
<div class="map-button"><img src="../../../miniapp/assets/icons/home/service-station.png" alt="" loading="lazy"><span >地图定位</span></div>
</div>
<div class="fixed-action"><div class="service-actions"><div class="secondary-btn">联系服务站</div><div class="primary-btn">预约到站服务</div></div></div></div>
</div></div></div>
</section></div>
<script>
const btns = [...document.querySelectorAll('.nav-btn')]
const panels = [...document.querySelectorAll('.preview-panel')]
btns.forEach((b) => b.addEventListener('click', () => {
btns.forEach((x) => x.classList.toggle('active', x === b))
panels.forEach((p) => { p.style.display = p.id === 'pg-' + b.dataset.target.replace('pg-','') ? 'block' : 'none' })
}))
</script>
</body>
</html>