fix(mp): 修正 design token 字号对齐原型 + ContentCard margin prop

- tokens.scss: 修正字号 token 对齐 18 份原型稿 fontSize 统计
  --tk-font-h1: 26→28px, --tk-font-h2: 24→22px
  --tk-font-body-lg: 28→18px, --tk-font-body: 22→16px
  --tk-font-body-sm: 16→14px
  elder-mode 同步重新计算比例系数
- ContentCard: 新增 margin prop ('none'|'md'),margin-bottom
  从 CSS 类移至 inline style,支持列表容器内无间距模式
- Profile 页: 用户卡片添加 profile-user-card flex 布局
  菜单组/积分卡片使用 margin="none",修复布局对齐
- Login 页: SCSS 全部改为 design token 引用
This commit is contained in:
iven
2026-05-17 12:48:38 +08:00
parent 6841c45846
commit 551d19d921
6 changed files with 107 additions and 90 deletions

View File

@@ -4,7 +4,6 @@
background: var(--tk-card-bg);
border-radius: var(--tk-card-radius);
box-shadow: $shadow-sm;
margin-bottom: var(--tk-gap-md);
transition: background 0.15s, opacity 0.15s, transform 0.15s;
&--outlined {

View File

@@ -7,6 +7,7 @@ interface ContentCardProps {
variant?: 'default' | 'outlined' | 'elevated';
onPress?: () => void;
padding?: 'none' | 'sm' | 'md' | 'lg';
margin?: 'none' | 'md';
activeFeedback?: 'bg' | 'opacity' | 'scale' | 'none';
className?: string;
style?: CSSProperties;
@@ -20,10 +21,16 @@ const PADDING_MAP = {
lg: 'var(--tk-card-padding-lg)',
} as const;
const MARGIN_MAP = {
none: '0',
md: 'var(--tk-gap-md)',
} as const;
const ContentCard: React.FC<ContentCardProps> = ({
variant = 'default',
onPress,
padding = 'md',
margin = 'md',
activeFeedback = 'bg',
className,
style,
@@ -31,8 +38,9 @@ const ContentCard: React.FC<ContentCardProps> = ({
}) => {
const innerStyle = useMemo(() => ({
padding: PADDING_MAP[padding],
marginBottom: MARGIN_MAP[margin],
...style,
}), [padding, style]);
}), [padding, margin, style]);
const hasPress = !!onPress;
const cls = [

View File

@@ -1,8 +1,7 @@
@import '../../styles/variables.scss';
@import '../../styles/mixins.scss';
// 登录页使用原型精确数值,不走 design token
// 原型参考docs/design/mp-01-login.html
// 登录页 — 全部使用 design token,原型参考 docs/design/mp-01-login.html
.login-page {
min-height: 100vh;
@@ -40,14 +39,14 @@
.login-title {
font-family: 'Georgia', 'Times New Roman', serif;
font-size: 28px;
font-size: var(--tk-font-h1);
font-weight: 700;
color: $tx;
margin-bottom: 8px;
}
.login-subtitle {
font-size: 14px;
font-size: var(--tk-font-body-sm);
color: $tx3;
}
@@ -56,7 +55,7 @@
height: 56px;
background: $card;
border: 1.5px solid $bd;
border-radius: 16px;
border-radius: $r;
display: flex;
align-items: center;
padding: 0 16px;
@@ -66,17 +65,17 @@
.login-input {
flex: 1;
height: 100%;
font-size: 16px;
font-size: var(--tk-font-body);
color: $tx;
}
.login-placeholder {
color: $tx3;
font-size: 16px;
font-size: var(--tk-font-body);
}
.login-eye {
font-size: 14px;
font-size: var(--tk-font-body-sm);
color: var(--tk-pri);
font-weight: 500;
padding: 6px 0;
@@ -86,7 +85,7 @@
/* ─── 登录按钮 ─── */
.login-submit {
height: 54px;
border-radius: 16px;
border-radius: $r;
background: var(--tk-pri);
@include flex-center;
margin-top: 12px;
@@ -99,7 +98,7 @@
}
.login-submit-text {
font-size: 18px;
font-size: var(--tk-font-body-lg);
font-weight: 600;
color: $white;
}
@@ -119,14 +118,14 @@
}
.login-divider-text {
font-size: 12px;
font-size: var(--tk-font-cap);
color: $tx3;
}
/* ─── 微信登录 ─── */
.login-wechat-btn {
height: 54px;
border-radius: 16px;
border-radius: $r;
background: $wechat;
display: flex;
align-items: center;
@@ -140,13 +139,13 @@
}
.login-wechat-icon {
font-size: 16px;
font-size: var(--tk-font-body);
color: $white;
font-weight: bold;
}
.login-wechat-text {
font-size: 18px;
font-size: var(--tk-font-body-lg);
font-weight: 600;
color: $white;
}
@@ -161,9 +160,9 @@
height: 54px;
background: var(--tk-pri);
color: $white;
font-size: 18px;
font-size: var(--tk-font-body-lg);
font-weight: 600;
border-radius: 16px;
border-radius: $r;
border: none;
@include flex-center;
box-shadow: 0 4px 16px rgba($pri, 0.25);
@@ -198,14 +197,14 @@
}
.agreement-check-mark {
font-size: 14px;
font-size: var(--tk-font-body-sm);
color: $white;
font-weight: bold;
line-height: 1;
}
.agreement-text {
font-size: 12px;
font-size: var(--tk-font-cap);
color: $tx3;
line-height: 1.8;
}
@@ -220,7 +219,7 @@
text-align: center;
padding: 12px;
border: 1px dashed $bd;
border-radius: 12px;
border-radius: $r-sm;
margin-top: 16px;
&:active {
@@ -229,6 +228,6 @@
}
.login-dev-btn-text {
font-size: 13px;
font-size: var(--tk-font-cap);
color: $tx3;
}

View File

@@ -1,6 +1,8 @@
@import '../../styles/variables.scss';
@import '../../styles/mixins.scss';
// 个人中心页 — 全部使用 design token原型参考 docs/design/mp-redesign-home.html → ProfileA
.profile-page {
padding-bottom: calc(var(--tk-tabbar-space) + env(safe-area-inset-bottom));
}
@@ -16,7 +18,7 @@
.profile-avatar {
width: 60px;
height: 60px;
border-radius: $r-pill;
border-radius: 30px;
background: linear-gradient(135deg, var(--tk-pri-l) 0%, var(--tk-pri) 100%);
@include flex-center;
flex-shrink: 0;
@@ -24,9 +26,10 @@
.profile-avatar-char {
font-family: Georgia, 'Times New Roman', serif;
font-size: var(--tk-font-body-lg);
font-size: var(--tk-font-h1);
font-weight: 700;
color: $white;
line-height: 1;
}
.profile-user-info {
@@ -35,8 +38,8 @@
}
.profile-name {
@include serif-number;
font-size: var(--tk-font-body);
font-family: Georgia, 'Times New Roman', serif;
font-size: var(--tk-font-h2);
font-weight: 700;
color: $tx;
display: block;
@@ -44,20 +47,20 @@
}
.profile-phone {
font-size: var(--tk-font-cap);
color: var(--tk-text-secondary);
font-size: var(--tk-font-body-sm);
color: $tx3;
}
.profile-arrow {
font-size: var(--tk-font-body-sm);
color: var(--tk-text-secondary);
font-size: var(--tk-font-body);
color: $tx3;
flex-shrink: 0;
}
/* ─── 积分 + 打卡 ─── */
.profile-stats-row {
display: flex;
gap: var(--tk-gap-sm);
gap: 10px;
margin-bottom: var(--tk-gap-lg);
}
@@ -67,8 +70,8 @@
}
.stat-value {
@include serif-number;
font-size: var(--tk-font-body-lg);
font-family: Georgia, 'Times New Roman', serif;
font-size: var(--tk-font-h1);
font-weight: 700;
display: block;
margin-bottom: 2px;
@@ -83,27 +86,29 @@
}
.stat-unit {
font-size: var(--tk-font-body-sm);
font-size: var(--tk-font-body);
font-weight: 400;
}
.stat-label {
font-size: var(--tk-font-cap);
color: var(--tk-text-secondary);
color: $tx3;
margin-top: 2px;
display: block;
}
/* ─── 分组菜单 ─── */
.menu-group {
margin-bottom: var(--tk-gap-sm);
margin-bottom: 14px;
}
.menu-group-title {
font-size: var(--tk-font-cap);
font-size: var(--tk-font-body-sm);
font-weight: 600;
color: $tx2;
display: block;
margin-bottom: var(--tk-gap-xs);
padding-left: var(--tk-gap-2xs);
padding-left: 4px;
}
.menu-group-card {
@@ -113,9 +118,9 @@
.menu-item {
display: flex;
align-items: center;
gap: var(--tk-gap-sm);
padding: var(--tk-gap-md);
min-height: 48px;
gap: 14px;
padding: 14px var(--tk-gap-md);
min-height: var(--tk-touch-min);
position: relative;
&:active {
@@ -153,8 +158,8 @@
}
.menu-icon-text {
@include serif-number;
font-size: var(--tk-font-body-sm);
font-family: Georgia, 'Times New Roman', serif;
font-size: var(--tk-font-body);
font-weight: 700;
&.menu-icon-text--pri {
@@ -172,13 +177,13 @@
.menu-label {
flex: 1;
font-size: var(--tk-font-cap);
font-size: var(--tk-font-body);
color: $tx;
}
.menu-arrow {
font-size: var(--tk-font-cap);
color: var(--tk-text-secondary);
font-size: var(--tk-font-body-sm);
color: $tx3;
flex-shrink: 0;
}
@@ -207,6 +212,6 @@
}
.logout-text {
font-size: var(--tk-font-cap);
color: var(--tk-text-secondary);
font-size: var(--tk-font-body-sm);
color: $tx3;
}

View File

@@ -135,7 +135,7 @@ export default function Profile() {
<PageShell padding="md" safeBottom={false} scroll={false} className={`profile-page ${modeClass}`}>
{/* 用户信息卡片 */}
{isGuest ? (
<ContentCard variant="elevated" onPress={navigateToLogin}>
<ContentCard variant="elevated" onPress={navigateToLogin} className="profile-user-card">
<View className='profile-avatar profile-avatar--guest'>
<Text className='profile-avatar-char'>?</Text>
</View>
@@ -147,7 +147,7 @@ export default function Profile() {
</ContentCard>
) : (
<>
<ContentCard variant="elevated">
<ContentCard variant="elevated" className="profile-user-card">
<View className='profile-avatar'>
<Text className='profile-avatar-char'>{displayInitial}</Text>
</View>
@@ -165,13 +165,17 @@ export default function Profile() {
<Loading />
) : (
<View className='profile-stats-row'>
<ContentCard padding="sm">
<Text className='stat-value stat-pri'>{(pointsAccount?.balance ?? 0).toLocaleString()}</Text>
<Text className='stat-label'></Text>
<ContentCard padding="sm" margin="none">
<View className='stat-card'>
<Text className='stat-value stat-pri'>{(pointsAccount?.balance ?? 0).toLocaleString()}</Text>
<Text className='stat-label'></Text>
</View>
</ContentCard>
<ContentCard padding="sm">
<Text className='stat-value stat-acc'>{checkinInfo?.consecutive_days ?? 0}<Text className='stat-unit'></Text></Text>
<Text className='stat-label'></Text>
<ContentCard padding="sm" margin="none">
<View className='stat-card'>
<Text className='stat-value stat-acc'>{checkinInfo?.consecutive_days ?? 0}<Text className='stat-unit'></Text></Text>
<Text className='stat-label'></Text>
</View>
</ContentCard>
</View>
)}
@@ -183,6 +187,7 @@ export default function Profile() {
<View className='menu-group'>
<ContentCard
padding="none"
margin="none"
onPress={() => Taro.navigateTo({ url: '/pages/pkg-profile/notifications/index' })}
>
<View className='menu-item'>
@@ -205,7 +210,7 @@ export default function Profile() {
{groups.map((group) => (
<View className='menu-group' key={group.title}>
<Text className='menu-group-title'>{group.title}</Text>
<ContentCard padding="none">
<ContentCard padding="none" margin="none">
{group.items.map((item, idx) => (
<View
className='menu-item'

View File

@@ -1,10 +1,11 @@
// Design Token — CSS 自定义属性
// 基准参考docs/design/mp-redesign-home.html 原型设计
// 基准参考docs/design/mp-*.html 原型设计
// 页面样式应引用 var(--tk-*) 而非硬编码 px 值
// 关怀模式通过 .elder-mode 覆盖 token 值自动生效
// ═══════════════════════════════════════
// 正常模式 Token对齐原型 mp-redesign-home.html
// 正常模式 Token对齐 docs/design/mp-*.html 原型
// 字号来源18 份原型稿 fontSize 统计
// ═══════════════════════════════════════
page {
// ─── 色彩 TokenCSS 变量级联,医生端可覆盖)───
@@ -14,47 +15,47 @@ page {
--tk-shadow-btn: #{$shadow-btn};
--tk-shadow-tab: #{$shadow-tab};
// ─── 字号11 级)───
--tk-font-display: 72px;
--tk-font-hero: 48px;
--tk-font-h1: 26px; // 页面标题(原型 fontSize:26 serif bold
--tk-font-h2: 24px; // 副标题
--tk-font-body-lg: 28px; // 按钮字、页面默认
--tk-font-body: 22px; // 正文
--tk-font-body-sm: 16px; // 列表项、副文本(原型 15-16px
--tk-font-num: 30px; // 数值(原型 fontSize:30 serif bold
--tk-font-num-lg: 34px; // 大数值
--tk-font-cap: 13px; // 说明文字(原型 fontSize:13
--tk-font-nav: 18px; // 导航栏标题(原型 fontSize:18 serif bold
--tk-font-micro: 11px; // 角标(原型 fontSize:11
// ─── 字号11 级,对齐原型 fontSize 统计)───
--tk-font-display: 72px; // 大屏展示
--tk-font-hero: 48px; // 启动页标题
--tk-font-h1: 28px; // 页面标题(原型 28px serif bold
--tk-font-h2: 22px; // 副标题、用户名(原型 22px serif bold
--tk-font-body-lg: 18px; // 按钮字、section 标题(原型 17-18px fontWeight:600
--tk-font-body: 16px; // 正文、输入框、icon 文字(原型 16px最常用 UI 字号)
--tk-font-body-sm: 14px; // 副文本、描述(原型 14px第二大用量
--tk-font-num: 30px; // 数值(原型 30px serif bold
--tk-font-num-lg: 34px; // 大数值
--tk-font-cap: 13px; // 说明文字(原型 13px第一高频字号
--tk-font-nav: 18px; // 导航栏标题(原型 18px serif bold
--tk-font-micro: 11px; // 角标、tag原型 11px
// ─── 结构 ───
--tk-line-height: 1.5;
--tk-touch-min: 48px;
--tk-btn-primary-h: 52px; // 按钮高度(原型 height:52
--tk-btn-primary-h: 52px;
--tk-text-secondary: #78716C;
// ─── 统一组件库结构化 Token ───
--tk-card-bg: #FFFFFF;
--tk-card-padding: 20px; // 卡片内边距(原型 padding:16-20
--tk-card-padding-sm: 16px; // 紧凑卡片
--tk-card-padding-lg: 28px; // 大卡片
--tk-card-radius: 16px; // 卡片圆角(原型 borderRadius:16
--tk-card-padding: 20px;
--tk-card-padding-sm: 16px;
--tk-card-padding-lg: 28px;
--tk-card-radius: 16px;
--tk-gap-2xs: 4px;
--tk-gap-xs: 8px;
--tk-gap-sm: 12px; // 网格/列表项间距(原型 gap:10
--tk-gap-md: 16px; // 区块间距(原型 marginBottom:16
--tk-section-gap: 20px; // 大区块间距
--tk-gap-sm: 12px;
--tk-gap-md: 16px;
--tk-section-gap: 20px;
--tk-gap-lg: 24px;
--tk-gap-xl: 32px;
--tk-gap-2xl: 48px;
--tk-page-padding: 20px; // 页面边距(原型 padding:20
--tk-page-padding: 20px;
--tk-input-height: 56px;
--tk-tabbar-space: 100px;
--tk-touch-feedback-opacity: 0.85;
--tk-tag-font-size: 11px; // 标签字号(原型 fontSize:11
--tk-tag-padding-v: 3px; // 标签纵向(原型 padding:3px
--tk-tag-padding-h: 8px; // 标签横向(原型 padding:8px
--tk-tag-font-size: 11px;
--tk-tag-padding-v: 3px;
--tk-tag-padding-h: 8px;
}
// ═══════════════════════════════════════
@@ -64,15 +65,15 @@ page {
.elder-mode {
--tk-font-display: 80px;
--tk-font-hero: 56px;
--tk-font-h1: 30px; // 26×1.15
--tk-font-h2: 28px; // 24×1.15
--tk-font-body-lg: 34px;
--tk-font-body: 30px; // 22×1.35
--tk-font-body-sm: 22px; // 16×1.35
--tk-font-h1: 32px; // 28×1.15
--tk-font-h2: 25px; // 22×1.15
--tk-font-body-lg: 22px; // 18×1.22(交互元素适度放大)
--tk-font-body: 22px; // 16×1.35
--tk-font-body-sm: 19px; // 14×1.35
--tk-font-num: 34px;
--tk-font-num-lg: 40px;
--tk-font-cap: 18px; // 13×1.4
--tk-font-nav: 22px; // 18×1.2(标题轻度放大)
--tk-font-nav: 22px; // 18×1.22
--tk-font-micro: 17px; // 11×1.55
--tk-line-height: 1.7;