跳到主要内容

UI 视觉设计规范

本规范基于已完成的设计页面(static/ui/fap/static/ui/lsp/)提取,参考客户原始需求文档制定。

平台概览

平台技术栈设备尺寸用户角色设计特点
Family AppUniApp(iOS + Android)390×844px(iPhone 16 Pro)子女/家属(中年用户)传统触控界面,适老化要求:字号 ≥ 16pt
Luma App嵌入式 Linux + Web 前端1280×800px(音箱屏幕)老年人(65岁以上)语音优先 + 触控辅助,适老化要求:字号 ≥ 18pt

1. Family App(儿女端)

1.1 设计令牌(Design Tokens)

所有 Family App 页面共享 __design_tokens.css 中的 CSS 变量:

/* ═══════════════════════════════════════════
1. 墨色系列(文字)
═══════════════════════════════════════════ */
--ink: #1A1814; /* 主墨色/深色文字 */
--ink-mid: #4A4540; /* 中等墨色 */
--ink-soft: #7A7570; /* 柔和墨色 */
--ink-dim: #B0AAA5; /* 暗淡墨色 */

/* ═══════════════════════════════════════════
2. 纸张系列(背景)
═══════════════════════════════════════════ */
--paper: #F8F6F2; /* 主背景色 */
--paper2: #F0EDE8; /* 次背景色 */
--paper3: #E8E4DE; /* 第三背景色 */
--white: #FFFFFF; /* 纯白 */

/* ═══════════════════════════════════════════
3. 绿色系(安全/正常状态)
═══════════════════════════════════════════ */
--green: #2D6A4F; /* 深绿色(规范定义) */
--green: #4A8A5A; /* 实际使用值 */
--green-light: #EAF4EF; /* 浅绿色背景 */
--green-border: rgba(74,138,90,0.2);

/* ═══════════════════════════════════════════
4. 琥珀色系(警告状态)
═══════════════════════════════════════════ */
--amber: #92400E; /* 深琥珀色(规范定义) */
--amber: #8A7040; /* 实际使用值 */
--amber-light: #FEF3C7; /* 浅琥珀色背景 */
--amber-border: rgba(138,112,64,0.2);

/* ═══════════════════════════════════════════
5. 红色系(紧急/错误状态)
═══════════════════════════════════════════ */
--red: #991B1B; /* 深红色(规范定义) */
--red: #9A5040; /* 实际使用值 */
--red-light: #FEF2F2; /* 浅红色背景 */
--red-border: rgba(154,80,64,0.2);

/* ═══════════════════════════════════════════
6. 蓝色系(信息状态)
═══════════════════════════════════════════ */
--blue: #1E3A8A; /* 深蓝色(规范定义) */
--blue: #3D6B9A; /* 实际使用值 */
--blue-light: #EFF6FF; /* 浅蓝色背景 */
--blue-border: rgba(61,106,154,0.2);

/* ═══════════════════════════════════════════
7. 边框色
═══════════════════════════════════════════ */
--border: rgba(26,24,20,0.1);
--border2: rgba(26,24,20,0.06);

/* ═══════════════════════════════════════════
8. 阴影
═══════════════════════════════════════════ */
--shadow-soft: 0 2px 8px rgba(0,0,0,0.04);
--shadow-medium: 0 4px 16px rgba(0,0,0,0.06);

/* ═══════════════════════════════════════════
9. 字体
═══════════════════════════════════════════ */
--font-display: 'Fraunces', Georgia, serif; /* 品牌/标题 */
--font-body: 'DM Sans', -apple-system, BlinkMacSystemFont, sans-serif; /* 界面正文 */
--font-mono: 'JetBrains Mono', 'SF Mono', monospace; /* 等宽字体 */

/* ═══════════════════════════════════════════
10. 动画缓动函数
═══════════════════════════════════════════ */
--ease-spring: cubic-bezier(0.22,1,0.36,1);
--ease-out-expo: cubic-bezier(0.16,1,0.3,1);

1.2 颜色语义

状态背景色强调色说明
CALM 安全#EAF4EF#4A8A5A首页安全、正常消息
REMINDER 提醒#FEF3C7#8A7040待确认提醒
ALERT 关注#F8EDE9#9A5040预警横幅、紧急 CTA
HELP 求助#F8EDE9#9A5040紧急横幅、求助 CTA
FAMILY 家人#E8F0F8#3D6B9A家人消息通知
OFFLINE 离线#E8E4DE#5A6060设备离线状态

1.3 字体规范

元素字号字体字重说明
老人姓名30pxFraunces display600衬线字体,温暖感
Hero 标题28pxFraunces display600状态主标题
品牌名36pxLora600登录页品牌展示
正文14pxDM Sans400适老化底线
Section 标签11pxDM Sans600text-transform: uppercase; letter-spacing: 1px
按钮文字15-16pxDM Sans600主 CTA 按钮
底部 Tab10pxDM Sans600无障碍支持
徽章文字9-10pxDM Sans700状态徽章

1.4 按钮规范

主按钮(.btn-primary

.btn-primary {
width: 100%;
padding: 17px 24px; /* 高度 ≥56dp */
font-size: 16px;
font-weight: 600;
border: none;
border-radius: 14px;
background: var(--green); /* CALM 态 */
color: #fff;
box-shadow: 0 4px 16px rgba(74,138,90,0.28);
transition: all 0.25s var(--ease-spring);
}
.btn-primary:hover:not(:disabled) {
filter: brightness(1.08);
transform: translateY(-2px);
box-shadow: 0 8px 28px rgba(74,138,90,0.35);
}
.btn-primary:active:not(:disabled) { transform: scale(0.98); }
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }

次按钮(.btn-secondary

.btn-secondary {
background: var(--paper);
color: var(--ink-soft);
border: 1px solid var(--border);
border-radius: 10px;
padding: 10px 16px;
font-size: 11px;
font-weight: 600;
}

危险按钮(.btn-danger

.btn-danger {
background: var(--red);
color: #fff;
border: none;
border-radius: 10px;
padding: 10px 16px;
font-size: 11px;
font-weight: 600;
}

1.5 表单输入规范

输入框(.form-input / .input

.form-input {
width: 100%;
padding: 15px 18px;
font-size: 16px; /* 防止 iOS 自动缩放 */
font-family: var(--font-body);
border: 1.5px solid var(--border-subtle);
border-radius: 14px;
background: var(--white);
color: var(--ink);
transition: border-color 0.22s ease, box-shadow 0.22s ease;
-webkit-appearance: none;
}
.form-input:focus {
outline: none;
border-color: var(--green);
box-shadow: 0 0 0 3px rgba(74,138,90,0.1);
}
.form-input.is-error { border-color: #C0392B; box-shadow: 0 0 0 3px rgba(192,57,43,0.1); }
.form-input::placeholder { color: var(--ink-dim); }

表单标签(.form-label

.form-label {
display: block;
font-size: 11px;
font-weight: 700;
color: var(--ink-soft);
text-transform: uppercase;
letter-spacing: 1.2px;
margin-bottom: 9px;
}

字段错误(.field-error

.field-error { font-size: 12px; color: #C0392B; margin-top: 6px; display: none; }
.field-error.visible { display: block; }

1.6 卡片组件规范

Hero 卡片(首页状态卡片)

.hero-card {
background: var(--green-light);
border: 1.5px solid var(--green-border);
border-radius: 24px;
padding: 26px 24px;
margin-bottom: 16px;
position: relative;
overflow: hidden;
}
.hero-card::before {
content: '';
position: absolute; top: 0; left: 0; right: 0; height: 3px;
background: linear-gradient(90deg, var(--green), transparent 80%);
opacity: 0.8;
}
.hero-card::after {
content: '';
position: absolute; top: -50px; right: -60px;
width: 180px; height: 180px; border-radius: 50%;
background: radial-gradient(circle, var(--green) 0%, transparent 70%);
opacity: 0.06;
}

通用卡片(.card

.card {
background: var(--white);
border: 1px solid var(--border2);
border-radius: 12px;
padding: 16px;
}
.card-hero {
background: var(--green-light);
border: 1px solid rgba(45,106,79,0.15);
border-radius: 16px;
padding: 14px;
}
.card-hero.warning { background: var(--amber-light); border-color: rgba(180,83,9,0.15); }
.card-hero.danger { background: var(--red-light); border-color: rgba(153,27,27,0.15); }

Recent 卡片(消息列表卡片)

.timeline-card {
background: var(--bg-card);
border: 1px solid var(--border-subtle);
border-radius: 18px;
padding: 14px 16px;
cursor: pointer;
transition: all 0.2s var(--ease-spring);
}
.timeline-card:hover { background: var(--bg-card-subtle); transform: translateX(3px); box-shadow: 0 4px 12px rgba(0,0,0,0.05); }

1.7 徽章规范

.badge {
display: inline-flex;
align-items: center;
padding: 3px 8px;
border-radius: 20px;
font-size: 9px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
}
.badge-safe { background: var(--green); color: #fff; }
.badge-warning { background: var(--amber-mid); color: #fff; }
.badge-danger { background: var(--red); color: #fff; }
.badge-info { background: var(--ink); color: #fff; }

消息类型徽章(Timeline Card)

.card-type { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.6px; padding: 3px 8px; border-radius: 10px; }
.card-type.checkin { background: var(--green-light); color: var(--green); }
.card-type.voice { background: var(--amber-light); color: var(--amber); }
.card-type.text { background: var(--blue-light); color: var(--blue); }
.card-type.reminder { background: var(--amber-light); color: var(--amber); }
.card-type.alert { background: var(--red-light); color: var(--red); }
.card-type.video { background: var(--teal-light); color: var(--teal); }
.card-type.safe { background: var(--green-light); color: var(--green); }

1.8 老人头像规范

.elder-avatar-wrapper { position: relative; }
.elder-avatar {
width: 50px; height: 50px; border-radius: 50%;
background: linear-gradient(135deg, var(--green), color-mix(in srgb, var(--green) 75%, #000));
display: flex; align-items: center; justify-content: center;
color: #fff; font-family: var(--font-display); font-weight: 600; font-size: 20px;
box-shadow: 0 4px 14px rgba(0,0,0,0.1);
}
.status-ring {
position: absolute; top: -4px; left: -4px; right: -4px; bottom: -4px;
border-radius: 50%; border: 2px solid var(--green);
opacity: 0.35;
animation: ringPulse 3.5s ease-in-out infinite; /* CALM 态 */
}
.status-dot {
position: absolute; bottom: -1px; right: -1px;
width: 13px; height: 13px; border-radius: 50%;
background: var(--green); border: 2.5px solid var(--bg-cloud);
animation: dotBlink 2.5s ease-in-out infinite;
}

1.9 导航规范

底部导航(.bottom-nav

.bottom-nav {
position: fixed; bottom: 0; left: 0; right: 0;
display: flex;
border-top: 1px solid var(--border-subtle);
padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 8px);
background: rgba(255,255,255,0.95);
backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
box-shadow: 0 -2px 12px rgba(0,0,0,0.04);
z-index: 100;
}
@media (min-width: 768px) {
.bottom-nav { left: 50%; transform: translateX(-50%); width: 414px; max-width: 100%; border-radius: 24px 24px 0 0; }
}
.nav-item {
flex: 1; display: flex; flex-direction: column; align-items: center;
padding: 12px 4px 8px;
color: var(--text-tertiary); text-decoration: none;
font-size: 10px; font-weight: 600; gap: 4px;
cursor: pointer; transition: all 0.25s ease;
position: relative;
}
.nav-item::before {
content: ''; position: absolute; top: -1px; left: 50%;
transform: translateX(-50%) scaleX(0);
width: 28px; height: 3px;
background: var(--green);
border-radius: 0 0 3px 3px;
transition: transform 0.3s var(--ease-spring);
}
.nav-item.active { color: var(--green); }
.nav-item.active::before { transform: translateX(-50%) scaleX(1); }
.nav-item svg { width: 22px; height: 22px; fill: currentColor; }

1.10 动画规范

动画CSS 类时长缓动触发时机
页面入场fadeIn0.6svar(--ease-out)页面加载
内容块入场slideUp0.5svar(--ease-spring)延迟 0.05-0.3s 依次入场
卡片脉冲cardPulse2.5sease-in-outALERT 状态持续循环
状态环脉冲ringPulse1.5-3.5sease-in-out老人头像状态环(ALERT=1.5s, CALM=3.5s)
状态点闪烁dotBlink1-2.5sease-in-out老人头像状态点
未读脉冲unreadPulse2sease-in-out消息未读点
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes slideUp { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
@keyframes cardPulse { 0%,100% { box-shadow: 0 4px 20px rgba(154,80,64,0.15); } 50% { box-shadow: 0 8px 36px rgba(154,80,64,0.28), 0 0 0 2px rgba(154,80,64,0.08); } }
@keyframes ringPulse { 0%,100% { transform: scale(1); opacity: 0.35; } 50% { transform: scale(1.06); opacity: 0.15; } }
@keyframes dotBlink { 0%,100% { opacity: 1; } 50% { opacity: 0.5; } }
@keyframes unreadPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } }

1.11 Toast 通知

.toast {
position: fixed;
top: calc(22px + env(safe-area-inset-top, 0px));
left: 50%;
transform: translateX(-50%) translateY(-16px);
padding: 13px 24px;
border-radius: 12px;
font-size: 14px; font-weight: 500;
box-shadow: 0 8px 32px rgba(0,0,0,0.14);
opacity: 0; pointer-events: none; z-index: 2000; white-space: nowrap;
}
.toast.toast-show { animation: toastSlide 3.2s var(--ease-out) forwards; }
.toast-error { background: #C0392B; color: #fff; }
.toast-success { background: var(--green); color: #fff; }
@keyframes toastSlide {
0% { transform: translateX(-50%) translateY(-16px); opacity: 0; }
12% { transform: translateX(-50%) translateY(0); opacity: 1; }
88% { transform: translateX(-50%) translateY(0); opacity: 1; }
100% { transform: translateX(-50%) translateY(-16px); opacity: 0; }
}

1.12 登录页特殊样式

登录页有独特的环境光球(Ambient Orbs)效果:

body {
background: var(--bg-mist);
background-image:
radial-gradient(ellipse at 25% 6%, rgba(232,244,235,0.75) 0%, transparent 50%),
radial-gradient(ellipse at 78% 92%, rgba(232,244,235,0.5) 0%, transparent 50%),
radial-gradient(ellipse at 55% 50%, rgba(74,138,90,0.04) 0%, transparent 60%);
}
.orb {
position: fixed; border-radius: 50%; pointer-events: none; z-index: 0;
}
.orb-1 { width: 320px; height: 320px; background: radial-gradient(circle, rgba(232,244,235,0.8) 0%, transparent 68%); top: -100px; left: -90px; animation: orbFloat 8s ease-in-out infinite; }
@keyframes orbFloat {
0%, 100% { transform: translateY(0) scale(1); opacity: 1; }
50% { transform: translateY(-14px) scale(1.05); opacity: 0.85; }
}

1.13 触控规范

指标最小值说明
按钮高度≥56dp主 CTA 使用 padding: 16-17px 24px
触控区域≥44dp × 44dp卡片最小触控面积
按钮间距≥8-12dp避免误触
圆角≥12px卡片和按钮统一 border-radius

2. Luma App(老人端)

2.1 设计令牌(Design Tokens)

Luma App 页面无共享 CSS 文件,每个 HTML 独立定义 :root 变量。按状态分类:

CALM / 倾听态

:root {
--bg-app: #FAFAF7; /* 暖白背景 */
--bg-card: #FFFFFF;
--text-primary: #1A1A1A;
--text-secondary: #374151;
--text-tertiary: #4B5563;
--accent-primary: #8A6A00; /* 琥珀强调 */
--accent-secondary: #B45309; /* 琥珀次强调 */
--border: #E5E4DF;
--surface-warm: rgba(138, 106, 0, 0.04);
}

FAMILY / 家人态

:root {
--bg: #0D1117; /* 深黑背景 */
--family-color: #3D6A9A; /* 家庭蓝 */
--family-glow: rgba(61, 106, 154, 0.15);
--card-bg: #1D2D3D;
--text-primary: rgba(255, 255, 255, 0.90);
--text-secondary: rgba(255, 255, 255, 0.65);
--text-dim: rgba(255, 255, 255, 0.35);
}

OFFLINE / 离线态

:root {
--gray-color: #5A6060; /* 灰色 */
--gray-bg: #2D2D2D;
--device-bg: #0D1117; /* 深黑 */
--amber-bg: rgba(124, 107, 63, 0.16);
--amber-border: rgba(124, 107, 63, 0.22);
--glow-outer: rgba(90, 96, 96, 0.15);
--glow-inner: rgba(90, 96, 96, 0.08);
}

ALERT / HELP / 紧急态

:root {
--bg-app: #FAFAF7;
--state-danger: #B91C1C; /* 深红 */
--surface-warm: rgba(180, 69, 9, 0.06); /* ALERT 氛围光 */
}
:root {
--state-help: #8A3030; /* HELP 深红 */
--state-help-mid: rgba(138, 48, 48, 0.35);
--state-help-soft: rgba(138, 48, 48, 0.15);
--state-help-glow: rgba(138, 48, 48, 0.22);
--bg-dark: #0D1117;
--bg-help-deep: #2A0E0E;
--green-confirm: #4A8A5A; /* 已接听确认色 */
}

2.2 颜色语义

状态背景色强调色说明
CALM 平静#FAFAF7(暖白)#8A6A00(琥珀)正常陪伴界面
ALERT 关注#FAFAF7(暖白)#B91C1C(深红)跌倒询问,保持克制
HELP 求助#0D1117(深黑)#8A3030(深红)求助界面
OFFLINE 离线#0D1117(深黑)#5A6060(灰色)诚实但温和
FAMILY 家人#0D1117(深黑)#3D6A9A(家庭蓝)语音消息卡片

Luma App 所有深色状态均使用 #0D1117 作为基础背景,配合氛围光渐变。

2.3 字体规范

元素字号字体字重说明
时间显示≥52pxLibre Baskerville400远距离可读,衬线字体
日期18-24pxDM Sans300大写字母间距
问候语≥48pxLibre Baskerville400情感连接核心元素
状态信息26-28pxDM Sans300浅色文字
存在感文字20-24pxDM Sans400 italic引导下一步操作
帮助提示16pxDM Sans300最淡层级的提示
紧急标题44pxFraunces400HELP 态主标题
紧急副文本19pxFraunces300HELP 态说明文字

2.4 屏幕结构规范

<!-- Luma App 固定尺寸容器 -->
<div class="screen"> <!-- 1280×800 固定尺寸,响应式缩放 -->
<div class="device-screen"> <!-- 等效根容器(离线/HELP 态) -->

<!-- CALM/FAMILY 态分层结构 -->
<div class="layer-time"> <!-- 时间层:时间 + 日期 -->
<div class="layer-card"> <!-- 内容层:状态卡片/消息 -->
<div class="layer-presence"> <!-- 存在感层:底部提示 -->

<!-- 辅助层 -->
<div class="ambient-glow"> <!-- 径向渐变氛围光 -->
<div class="grain-layer"> <!-- SVG 颗粒纹理叠加 -->
<div class="grain-overlay"> <!-- 等效颗粒层(HELP 态) -->

2.5 倾听动画规范

Wave 动画(5 根声波条,CALM/Home/Listening 共用):

.listening-indicator {
display: flex; align-items: center; gap: 8-10px;
margin-top: 36-40px;
}
.wave {
width: 6-7px;
border-radius: 3-4px;
background: var(--accent-primary);
animation: wave 1.3-1.4s ease-in-out infinite;
}
/* 5 根波条,不同高度 + 不同 delay */
.wave:nth-child(1) { height: 18-22px; animation-delay: 0s; }
.wave:nth-child(2) { height: 30-36px; animation-delay: 0.12-0.13s; }
.wave:nth-child(3) { height: 22-28px; animation-delay: 0.24-0.26s; }
.wave:nth-child(4) { height: 36-40px; animation-delay: 0.36-0.39s; }
.wave:nth-child(5) { height: 18-22px; animation-delay: 0.48-0.52s; }

@keyframes wave {
0%, 100% { transform: scaleY(0.5); opacity: 0.45-0.5; }
50% { transform: scaleY(1); opacity: 1; }
}

Voice Pulse 动画(FAMILY 态消息卡片的语音点):

.voice-dot {
width: 10px; height: 10px; border-radius: 50%;
background: var(--family-color); opacity: 0.6;
animation: voicePulse 1.5s ease-in-out infinite;
}
.voice-dot:nth-child(2) { animation-delay: 0.2s; }
.voice-dot:nth-child(3) { animation-delay: 0.4s; }
.voice-dot:nth-child(4) { animation-delay: 0.6s; }
.voice-dot:nth-child(5) { animation-delay: 0.8s; }

@keyframes voicePulse {
0%, 100% { transform: scale(1); opacity: 0.4; }
50% { transform: scale(1.3); opacity: 0.8; }
}

Amber Pulse 动画(ALERT 态倾听点):

.dot {
width: 10px; height: 10px; border-radius: 50%;
background-color: var(--accent-secondary);
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 0.4; transform: scale(1); }
50% { opacity: 1; transform: scale(1.35); }
}

2.6 氛围光规范

CALM 状态(暖白背景):

.screen::before {
background: radial-gradient(
ellipse 70% 50% at 20% 40%,
rgba(138, 106, 0, 0.04) 0%,
transparent 60%
);
}

ALERT 状态(暖白 + 琥珀/红氛围):

body {
background-image:
radial-gradient(ellipse 60% 50% at 30% 55%, rgba(138,106,0,0.10) 0%, transparent 70%),
radial-gradient(ellipse 40% 35% at 70% 40%, rgba(180,83,9,0.06) 0%, transparent 60%);
}

HELP 状态(深色 + 深红氛围呼吸):

.device-screen::before {
background: radial-gradient(
ellipse 80% 70% at 50% 50%,
rgba(138,48,48,0.22) 0%,
rgba(138,48,48,0.08) 35%,
transparent 65%
);
animation: ambientBreath 7s ease-in-out infinite;
}
@keyframes ambientBreath {
0%, 100% { opacity: 0.7; transform: scale(1); }
50% { opacity: 1; transform: scale(1.03); }
}

FAMILY 状态(深色 + 家庭蓝氛围):

.screen::before {
background: radial-gradient(
ellipse 60% 40% at 50% 40%,
rgba(61,106,154,0.15) 0%,
transparent 65%
);
}

OFFLINE 状态(深黑 + 颗粒纹理 + 中心光晕):

.device-screen {
background: #0D0D0D;
box-shadow: 0 0 80px rgba(90,96,96,0.15), 0 0 40px rgba(90,96,96,0.08);
}
.grain-layer {
/* SVG feTurbulence 颗粒纹理,opacity: 0.045,animation: grainShift 8s */
opacity: 0.045;
background-size: 300px 300px;
animation: grainShift 8s steps(1) infinite;
}
@keyframes grainShift {
0% { transform: translate(0, 0); }
10% { transform: translate(-1%, -1%); }
20% { transform: translate(1%, 0%); }
30% { transform: translate(0%, 1%); }
/* ... 10% 步进,共 10 步 */
100% { transform: translate(0, 0); }
}
.ambient-glow {
/* 中心圆形光晕 rgba(90,96,96,0.10) */
position: absolute; top: 38%; left: 50%;
transform: translate(-50%, -50%);
width: 600px; height: 600px; border-radius: 50%;
background: radial-gradient(circle,
rgba(90,96,96,0.10) 0%,
rgba(90,96,96,0.04) 45%,
transparent 70%
);
}

2.7 SOS 紧急动画

SOS 脉冲环(HELP 态):

.sos-ring::before {
content: ''; position: absolute; inset: 0; border-radius: 50%;
border: 2px solid rgba(138,48,48,0.55);
animation: sosPulse 2.2s ease-out infinite;
}
.sos-ring::after {
content: ''; position: absolute; inset: 12px; border-radius: 50%;
border: 1px solid rgba(138,48,48,0.30);
animation: sosPulse 2.2s ease-out infinite 0.5s;
}
@keyframes sosPulse {
0% { transform: scale(1); opacity: 0.8; }
100% { transform: scale(1.8); opacity: 0; }
}

Spin Ring 动画(OFFLINE 态图标环):

.spin-ring {
position: absolute; inset: 0; border-radius: 50%;
border: 1.5px solid rgba(90,96,96,0.18);
animation: spinRing 9s linear infinite;
}
@keyframes spinRing {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.cloud-icon { animation: opacityPulse 5s ease-in-out infinite; }
@keyframes opacityPulse {
0%, 100% { opacity: 0.55; }
50% { opacity: 1; }
}

2.8 布局规范

左对齐布局(常态 Home):

.layout {
padding: 60px 100px 60px 160px; /* 左侧留白更大(屏幕宽广) */
text-align: left;
align-items: flex-start;
}

居中布局(Care Card、倾听态):

/* 消息卡片居中 */
.layer-card {
display: flex; align-items: center; justify-content: center;
padding: 40px 100px;
}
.card {
background: var(--card-bg);
border-radius: 24px;
padding: 48px 56px;
max-width: 800px;
text-align: center;
box-shadow: 0 0 80px rgba(61,106,154,0.12), 0 0 40px rgba(61,106,154,0.06), 0 16px 48px rgba(0,0,0,0.4);
}

2.9 安全与紧急规范

OFFLINE 安全提示条

.safety-strip {
background: var(--amber-bg);
border-top: 1px solid var(--amber-border);
padding: 18px 80px;
display: flex; align-items: center; justify-content: center; gap: 12px;
}
/* 固定文案:"If you need help right now, please call 911" */
.safety-text {
font-family: 'Fraunces', Georgia, serif;
font-size: 15px; font-weight: 400;
color: rgba(255,255,255,0.78);
}

存在感文字(最底部,淡色):

.presence-line {
background: #0D0D0D;
padding: 14px 80px 26px;
text-align: center;
}
.presence-text {
font-family: 'Fraunces', Georgia, serif;
font-size: 12px; font-weight: 300; font-style: italic;
color: rgba(255,255,255,0.28);
letter-spacing: 0.6px;
}

2.10 响应式缩放

Luma App 屏幕按宽度分级缩放:

屏幕宽度行为
≥1280px原始尺寸居中
900px-1279px按比例缩放(width: 100vw; height: 56.25vw
<900px字号逐级缩小(time 52→40→22px,greeting 48→38→22px)
@media (max-width: 1280px) {
.screen { width: 100vw; height: 56.25vw; max-height: 100vh; }
}
@media (max-width: 900px) {
.time { font-size: 40px; }
.greeting { font-size: 38px; }
.info { font-size: 22px; }
.presence { font-size: 20px; }
}

2.11 动画入场规范

动画时长缓动延迟规律
fadeInUp0.7-1sease-out依次递增 0.1-0.2s
softAppear1.2-1.4scubic-bezier(0.22,1,0.36,1)同上
cardGlow(ALERT/HELP)持续ease-in-out0.5s 开始
grainShift8ssteps(1)循环
spinRing(OFFLINE)9slinear持续旋转
opacityPulse(OFFLINE 图标)5sease-in-out持续
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes softAppear {
from { opacity: 0; transform: translateY(12px); }
to { opacity: 1; transform: translateY(0); }
}
/* 入场延迟约定 */
.time { animation: fadeInUp 1s ease-out 0.1s both; }
.date { animation: fadeInUp 1s ease-out 0.2s both; }
.greeting { animation: fadeInUp 1s ease-out 0.4s both; }
.info { animation: fadeInUp 1s ease-out 0.5s both; }
.presence { animation: fadeInUp 1s ease-out 0.6s both; }
.listening-indicator { animation: fadeInUp 1s ease-out 0.65s both; }
.help-hint { animation: fadeInUp 1s ease-out 0.8s both; }

3. 通用规范

3.1 字体使用规则

字体用途Family AppLuma App
Fraunces / Libre Baskerville品牌标题、时间、问候语
Lora登录页品牌名(Family App 独有)
DM Sans正文、界面文字、标签
JetBrains Mono紧急状态标签、等宽数据

3.2 禁用颜色

无论 Family App 还是 Luma App,均严格禁用以下颜色:

禁用颜色色值原因
医疗蓝#007AFF与 Apple 系统色冲突,不符合 Reflekt 品牌
亮红#FF3B30过于刺激,不符合"冷静技术"原则
任何形式的渐变背景(装饰性)分散注意力

3.3 组件复用约定

Family App 全局组件(CSS 类名规范):

组件类名说明
页面根容器.app-containerfadeIn 入场动画
认证壳.app-shell固定 390px 宽,含登录页背景
状态 Hero 卡片.hero-card状态色背景 + 顶部渐变条
CTA 按钮.btn-primary全宽主操作按钮
次按钮.btn-secondary描边次要操作
危险按钮.btn-danger红色警示操作
Quick Send 网格.send-grid / .send-card三列操作入口
Timeline 卡片.timeline-card消息列表项
底部导航.bottom-nav3-tab 固定导航
状态徽章.badge-safe / .badge-warning / .badge-danger圆角药丸形
老人头像包装.elder-avatar-wrapper头像 + 状态环 + 状态点
表单输入.form-input统一输入框样式
表单标签.form-label小号大写标签
Toast 通知.toast顶部居中提示

Luma App 全局组件(CSS 类名规范):

组件类名说明
屏幕根容器.screen / .device-screen1280×800 固定尺寸
时间层.layer-time时间 + 日期
内容层.layer-card状态内容/消息卡片
存在感层.layer-presence底部引导文字
倾听动画.listening-indicator + .wave5 根声波条动画
氛围光晕.ambient-glow径向渐变光晕
颗粒纹理.grain-layerSVG 噪点叠加(OFFLINE/HELP 态)
安全提示条.safety-stripOFFLINE 态底部警示
旋转环.spin-ringOFFLINE 态图标装饰环
SOS 脉冲环.sos-ringHELP 态紧急指示
联系人项.contact-itemHELP 态紧急联系人列表
消息卡片.cardFAMILY 态家属消息展示
语音脉冲点.voice-dotFAMILY 态播放中指示

4. 参考文档

文档说明
Family App Design TokensFamily App CSS 变量全集
Reflekt Home Redesign v2.2首页设计规范
Family App State Playbook v1.1Family App 六状态规范
Luma Daily Presence Playbook v1.2Luma App 六状态规范
颜色选择参考(广州团队)颜色 token 规范
Phase1屏幕系统Phase1 屏幕系统
Phase2感官层动效与音效规范