/** * 丹阳公益婚恋服务平台 - 全局 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(88rpx=44px) 为下限,--tap-gap 为最小间距。 * * 5) 动效几乎未落地(--motion-* 全站仅 5 次引用) * 补充 --ease-spring 与 --press-scale,让点击有即时反馈。 * * 6) 夜间氛围层缺失(参考图有明显的光晕/星点,代码只有纯渐变) * 新增 --mini-glow-* / --mini-star / --mini-glass / --mini-hairline。 * * 单位说明:rpx(750rpx = 屏幕宽度,1rpx ≈ 0.5px @375pt) * 旧 token 名全部保留(88 个 wxss 共 909 处引用),只更新取值,避免大范围失效。 */ 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: 24rpx; --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 16rpx 40rpx 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%); /* ---- 夜间氛围层(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 2.5rpx), radial-gradient(circle at 31% 66%, var(--mini-star) 0, transparent 2rpx), radial-gradient(circle at 57% 12%, var(--mini-star) 0, transparent 2rpx), radial-gradient(circle at 79% 52%, var(--mini-star) 0, transparent 3rpx), radial-gradient(circle at 93% 84%, var(--mini-star) 0, transparent 2rpx); /* 横幅压暗层:保证任何底图上的白色标题都有足够对比度 */ --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; /* 字号阶梯 —— 正文 32rpx(16px) 起,元信息下限 24rpx(12px) */ --font-size-micro: 22rpx; /* 11px 仅角标/装饰,禁用于正文 */ --font-size-xs: 24rpx; /* 12px 元信息下限 */ --font-size-sm: 26rpx; /* 13px 次要说明 */ --font-size-md: 28rpx; /* 14px 次要正文 */ --font-size-base: 32rpx; /* 16px 正文 */ --font-size-lg: 36rpx; /* 18px 小标题 */ --font-size-xl: 40rpx; /* 20px 区块标题 */ --font-size-2xl: 48rpx; /* 24px 页面标题 */ --font-size-3xl: 56rpx; /* 28px 大标题 */ --font-size-display: 64rpx; /* 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: 1rpx; --letter-spacing-wider: 2rpx; /* ============ 间距(4px 栅格) ============ */ --spacing-1: 8rpx; --spacing-2: 16rpx; --spacing-3: 24rpx; --spacing-4: 32rpx; --spacing-5: 40rpx; --spacing-6: 48rpx; --spacing-8: 64rpx; --spacing-10: 80rpx; --spacing-12: 96rpx; --spacing-page-x: 32rpx; --spacing-section: 48rpx; --spacing-card-inner: 32rpx; --spacing-tight: 16rpx; /* ============ 圆角 ============ */ --radius-sm: 16rpx; --radius-md: 24rpx; --radius-lg: 32rpx; --radius-xl: 40rpx; --radius-2xl: 48rpx; --radius-full: 9999rpx; /* ============ 阴影(统一为一套,此前 30+ 种近似值) ============ */ --shadow-card: 0 8rpx 28rpx rgba(35, 35, 95, 0.07); --shadow-raised: 0 12rpx 36rpx rgba(35, 35, 95, 0.10); --shadow-popup: 0 16rpx 64rpx rgba(0, 0, 0, 0.10); --shadow-night: 0 16rpx 40rpx rgba(28, 30, 88, 0.18); /* ============ 边框宽度 ============ */ --border-width: 1rpx; --border-width-strong: 2rpx; /* ============ 触摸目标(无障碍下限 44×44px) ============ */ --tap-min: 88rpx; /* 44px 最小可点区域 */ --tap-comfortable: 96rpx; /* 48px 舒适尺寸:主操作 */ --tap-gap: 16rpx; /* 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: env(safe-area-inset-bottom); } /* 页面卡片基础样式 */ .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); → 88rpx = 44px,最小可点区域 gap: var(--tap-gap); → 16rpx = 8px,相邻目标间距(flex gap) 【WXSS 禁用清单】星号通配符、兄弟选择器、属性选择器。 【注释约束】WXSS 注释**不可嵌套**:内层注释的结束标记会提前终止外层注释, 其后的文字会被当成真实样式解析,导致编译失败或样式被污染。 (2026-09-23 实证:本块注释初版即踩此坑。) ========================================================================== */