596 lines
28 KiB
HTML
596 lines
28 KiB
HTML
<!DOCTYPE html><html class="light" lang="zh-CN"><head>
|
||
<meta charset="utf-8">
|
||
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
||
<title>Daily Care - Health Dashboard</title>
|
||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&display=swap" rel="stylesheet">
|
||
<script id="tailwind-config">
|
||
tailwind.config = {
|
||
darkMode: "class",
|
||
theme: {
|
||
extend: {
|
||
"colors": {
|
||
"secondary-fixed": "#d9e6dd",
|
||
"surface-container": "#e8f0e9",
|
||
"surface-dim": "#d4dcd5",
|
||
"surface-variant": "#dde4dd",
|
||
"error-container": "#ffdad6",
|
||
"inverse-surface": "#2b322d",
|
||
"secondary": "#55615a",
|
||
"primary": "#006c49",
|
||
"on-secondary-fixed": "#131e19",
|
||
"surface-bright": "#f4fbf4",
|
||
"on-tertiary-container": "#711419",
|
||
"on-primary-fixed-variant": "#005236",
|
||
"outline-variant": "#bbcabf",
|
||
"primary-container": "#10b981",
|
||
"surface": "#f4fbf4",
|
||
"on-tertiary-fixed-variant": "#842225",
|
||
"tertiary-fixed-dim": "#ffb3af",
|
||
"tertiary-fixed": "#ffdad7",
|
||
"error": "#ba1a1a",
|
||
"surface-container-lowest": "#ffffff",
|
||
"surface-container-highest": "#dde4dd",
|
||
"primary-fixed": "#6ffbbe",
|
||
"on-primary-container": "#00422b",
|
||
"secondary-fixed-dim": "#bdcac1",
|
||
"on-tertiary": "#ffffff",
|
||
"on-primary-fixed": "#002113",
|
||
"on-error-container": "#93000a",
|
||
"tertiary-container": "#fc7c78",
|
||
"on-error": "#ffffff",
|
||
"inverse-primary": "#4edea3",
|
||
"inverse-on-surface": "#ebf3eb",
|
||
"on-secondary-container": "#5b6760",
|
||
"surface-container-high": "#e3eae3",
|
||
"surface-container-low": "#eef6ee",
|
||
"on-secondary-fixed-variant": "#3e4943",
|
||
"outline": "#6c7a71",
|
||
"secondary-container": "#d9e6dd",
|
||
"on-primary": "#ffffff",
|
||
"on-surface": "#161d19",
|
||
"on-background": "#161d19",
|
||
"tertiary": "#a43a3a",
|
||
"primary-fixed-dim": "#4edea3",
|
||
"on-secondary": "#ffffff",
|
||
"background": "#f4fbf4",
|
||
"on-surface-variant": "#3c4a42",
|
||
"surface-tint": "#006c49",
|
||
"on-tertiary-fixed": "#410005"
|
||
},
|
||
"borderRadius": {
|
||
"DEFAULT": "0.25rem",
|
||
"lg": "0.5rem",
|
||
"xl": "0.75rem",
|
||
"2xl": "1rem",
|
||
"3xl": "1.5rem",
|
||
"full": "9999px"
|
||
},
|
||
"spacing": {
|
||
"card-padding": "20px",
|
||
"section-margin": "32px",
|
||
"inline-gap": "12px",
|
||
"stack-gap": "16px",
|
||
"container-margin": "20px"
|
||
},
|
||
"fontFamily": {
|
||
"headline-md": ["Manrope"],
|
||
"headline-lg-mobile": ["Manrope"],
|
||
"body-lg": ["Manrope"],
|
||
"headline-lg": ["Manrope"],
|
||
"display-lg": ["Manrope"],
|
||
"body-md": ["Manrope"],
|
||
"label-md": ["Manrope"]
|
||
},
|
||
"fontSize": {
|
||
"headline-md": ["20px", {"lineHeight": "28px", "fontWeight": "700"}],
|
||
"headline-lg-mobile": ["22px", {"lineHeight": "28px", "fontWeight": "700"}],
|
||
"body-lg": ["16px", {"lineHeight": "24px", "fontWeight": "500"}],
|
||
"headline-lg": ["24px", {"lineHeight": "32px", "letterSpacing": "-0.01em", "fontWeight": "700"}],
|
||
"display-lg": ["32px", {"lineHeight": "40px", "letterSpacing": "-0.02em", "fontWeight": "800"}],
|
||
"body-md": ["14px", {"lineHeight": "20px", "fontWeight": "400"}],
|
||
"label-md": ["12px", {"lineHeight": "16px", "letterSpacing": "0.02em", "fontWeight": "600"}]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
<style>
|
||
body { font-family: 'Manrope', sans-serif; -webkit-tap-highlight-color: transparent; }
|
||
.material-symbols-outlined { font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24; display: inline-block; vertical-align: middle; }
|
||
.ambient-shadow { box-shadow: 0 20px 30px -10px rgba(0, 108, 73, 0.08); }
|
||
.active-scale:active { transform: scale(0.98); transition: all 0.2s ease; }
|
||
.hide-scrollbar::-webkit-scrollbar { display: none; }
|
||
.hide-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
|
||
|
||
/* Watering Animation Styles */
|
||
@keyframes fall {
|
||
0% { transform: translateY(-20px); opacity: 0; }
|
||
50% { opacity: 1; }
|
||
100% { transform: translateY(40px); opacity: 0; }
|
||
}
|
||
.droplet {
|
||
position: absolute;
|
||
width: 4px;
|
||
height: 10px;
|
||
background: #3b82f6;
|
||
border-radius: 50%;
|
||
animation: fall 0.6s linear infinite;
|
||
}
|
||
@keyframes pulse-growth {
|
||
0% { transform: scale(1); filter: drop-shadow(0 0 0px rgba(78, 222, 163, 0)); }
|
||
50% { transform: scale(1.15); filter: drop-shadow(0 0 15px rgba(78, 222, 163, 0.6)); }
|
||
100% { transform: scale(1); filter: drop-shadow(0 0 0px rgba(78, 222, 163, 0)); }
|
||
}
|
||
.growth-pulse {
|
||
animation: pulse-growth 0.8s ease-out;
|
||
}
|
||
@keyframes shimmer {
|
||
0% { opacity: 0; transform: scale(0) rotate(0deg); }
|
||
50% { opacity: 1; transform: scale(1.2) rotate(180deg); }
|
||
100% { opacity: 0; transform: scale(0) rotate(360deg); }
|
||
}
|
||
.shimmer-particle {
|
||
position: absolute;
|
||
color: #4edea3;
|
||
font-size: 14px;
|
||
pointer-events: none;
|
||
animation: shimmer 1s ease-out forwards;
|
||
}
|
||
|
||
/* Blood Sugar Decrease Animation */
|
||
@keyframes float-up-fade {
|
||
0% { transform: translateY(20px); opacity: 0; }
|
||
20% { opacity: 1; }
|
||
80% { opacity: 1; }
|
||
100% { transform: translateY(-100px); opacity: 0; }
|
||
}
|
||
.sugar-decrease-text {
|
||
position: fixed;
|
||
color: #10b981;
|
||
font-weight: 800;
|
||
font-size: 24px;
|
||
pointer-events: none;
|
||
z-index: 100;
|
||
text-shadow: 0 4px 12px rgba(16, 185, 129, 0.3);
|
||
animation: float-up-fade 2s ease-out forwards;
|
||
}
|
||
@keyframes fall-arrow {
|
||
0% { transform: translateY(-50vh) scale(0.5); opacity: 0; }
|
||
50% { opacity: 0.8; }
|
||
100% { transform: translateY(110vh) scale(1.2); opacity: 0; }
|
||
}
|
||
.sugar-particle {
|
||
position: fixed;
|
||
color: #10b981;
|
||
pointer-events: none;
|
||
z-index: 90;
|
||
animation: fall-arrow 1.5s linear forwards;
|
||
}
|
||
</style>
|
||
<style>
|
||
body {
|
||
min-height: max(884px, 100dvh);
|
||
}
|
||
</style>
|
||
</head>
|
||
<body class="bg-background text-on-background min-h-screen pb-24">
|
||
<!-- Top App Bar -->
|
||
<header class="bg-primary docked full-width top-0 h-48 flex items-end pb-6 px-5 fixed left-0 right-0 z-40">
|
||
<div class="flex justify-between items-center w-full">
|
||
<div class="flex items-center gap-3">
|
||
<div class="w-10 h-10 rounded-full border-2 border-on-primary overflow-hidden">
|
||
<img class="w-full h-full object-cover" data-alt="A professional studio portrait" src="https://lh3.googleusercontent.com/aida-public/AB6AXuCXIPbeivladmw0-SmLno2vkwVvsObW2D5HUtodItlBnxdhFF8TvZdQYrTt14QCk3n5VXXIpdk3cuWTJHXJgDXd_clQyjLsb477e5h2313zh76yRVns01Q5pLpM-2_RbheRcUioLvObwJtIPJbkDcbkNA61-LyBnbStRcPoh6YOvNHSHjUUR_nDJpPm18ga87ggphbFWF-pt7lRF027swmyitUeVF7HXQDfcG7Mq7E0pqsbhyA7jKxtzmbN-HLh7GIrhc6LOAUaXiX9">
|
||
</div>
|
||
<div>
|
||
<h1 class="text-on-primary font-bold text-headline-lg-mobile leading-tight">Daily Care</h1>
|
||
<p class="text-on-primary/80 text-body-md">吕帅</p>
|
||
</div>
|
||
</div>
|
||
<div class="flex gap-2">
|
||
<button class="bg-on-primary/10 hover:bg-on-primary/20 text-on-primary rounded-full px-4 py-1.5 flex items-center gap-2 active-scale transition-all">
|
||
<span class="material-symbols-outlined text-[18px]" style="font-variation-settings: 'FILL' 1;">bloodtype</span>
|
||
<span class="text-label-md">血糖</span>
|
||
</button>
|
||
<button class="bg-on-primary/10 hover:bg-on-primary/20 text-on-primary w-10 h-10 rounded-full flex items-center justify-center active-scale transition-all">
|
||
<span class="material-symbols-outlined text-[20px]">refresh</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
<main class="pt-52 px-container-margin space-y-6">
|
||
<!-- Toggle Switch -->
|
||
<div class="bg-surface-container-high rounded-full p-1 flex items-center">
|
||
<button class="flex-1 bg-primary text-on-primary rounded-full py-2 text-label-md font-bold shadow-md transition-all">最近 7 天</button>
|
||
<button class="flex-1 text-on-surface-variant py-2 text-label-md font-bold transition-all">最近 30 天</button>
|
||
</div>
|
||
<!-- Health Calendar -->
|
||
<section class="bg-surface-container-lowest rounded-3xl p-card-padding ambient-shadow">
|
||
<div class="flex justify-between items-start mb-4">
|
||
<div>
|
||
<h2 class="text-headline-md font-headline-md text-on-surface">健康日历</h2>
|
||
<p class="text-body-md text-outline">2026年5月 · 已记录 3 / 7 天</p>
|
||
</div>
|
||
<button class="text-primary"><span class="material-symbols-outlined">chevron_right</span></button>
|
||
</div>
|
||
<div class="grid grid-cols-7 gap-1 text-center mb-4">
|
||
<span class="text-label-md text-outline">一</span>
|
||
<span class="text-label-md text-outline">二</span>
|
||
<span class="text-label-md text-outline">三</span>
|
||
<span class="text-label-md text-outline">四</span>
|
||
<span class="text-label-md text-outline">五</span>
|
||
<span class="text-label-md text-outline">六</span>
|
||
<span class="text-label-md text-tertiary">日</span>
|
||
<span class="py-2 text-body-md text-outline/30">18</span>
|
||
<span class="py-2 text-body-md text-outline/30">19</span>
|
||
<span class="py-2 text-body-md text-outline/30">20</span>
|
||
<span class="py-2 text-body-md text-outline/30">21</span>
|
||
<span class="py-2 text-body-md text-outline/30">22</span>
|
||
<div class="py-2 relative"><span class="text-body-md font-bold text-on-surface">23</span></div>
|
||
<div class="py-2 relative bg-primary-container/10 rounded-lg">
|
||
<span class="text-body-md font-bold text-primary">24</span>
|
||
<span class="absolute bottom-1 left-1/2 -translate-x-1/2 w-1 h-1 bg-primary rounded-full"></span>
|
||
</div>
|
||
<div class="py-2 relative bg-primary-container/10 rounded-lg">
|
||
<span class="text-body-md font-bold text-primary">25</span>
|
||
<span class="absolute bottom-1 left-1/2 -translate-x-1/2 w-1 h-1 bg-primary rounded-full"></span>
|
||
</div>
|
||
<div class="py-2 relative bg-primary-container/10 rounded-lg">
|
||
<span class="text-body-md font-bold text-primary">26</span>
|
||
<span class="absolute bottom-1 left-1/2 -translate-x-1/2 w-1 h-1 bg-primary rounded-full"></span>
|
||
</div>
|
||
<span class="py-2 text-body-md text-on-surface">27</span>
|
||
<span class="py-2 text-body-md text-on-surface">28</span>
|
||
<div class="py-2 relative bg-tertiary-container rounded-lg">
|
||
<span class="text-body-md font-bold text-on-tertiary">29</span>
|
||
</div>
|
||
<span class="py-2 text-body-md text-outline/40">30</span>
|
||
<span class="py-2 text-body-md text-outline/40">31</span>
|
||
</div>
|
||
<div class="flex items-center justify-between border-t border-outline-variant/30 pt-4 mt-2">
|
||
<span class="text-body-md text-outline">今日还没有记录</span>
|
||
<button class="bg-primary text-on-primary px-6 py-3 rounded-2xl text-label-md font-bold active-scale transition-all flex items-center gap-2">去记血糖</button>
|
||
</div>
|
||
</section>
|
||
<!-- Blood Sugar Details Section -->
|
||
<section class="space-y-4">
|
||
<div class="flex justify-between items-center">
|
||
<h3 class="text-headline-md font-headline-md text-on-surface">血糖明细</h3>
|
||
<span class="text-body-md text-outline">共 3 天</span>
|
||
</div>
|
||
<div class="space-y-4">
|
||
<div class="bg-surface-container-lowest rounded-3xl p-card-padding ambient-shadow">
|
||
<div class="flex justify-between items-center mb-4">
|
||
<span class="text-headline-md font-bold">05-26</span>
|
||
<span class="text-body-md text-outline">周二</span>
|
||
</div>
|
||
<div class="space-y-2">
|
||
<div class="bg-background/50 border border-outline-variant/20 rounded-2xl p-4 flex justify-between items-center">
|
||
<span class="text-body-md text-outline">空腹</span>
|
||
<div class="text-right">
|
||
<span class="text-headline-lg font-extrabold text-error">10.4</span>
|
||
<span class="text-label-md text-outline ml-1">mmol/L</span>
|
||
</div>
|
||
</div>
|
||
<div class="bg-background/50 border border-outline-variant/20 rounded-2xl p-4 flex justify-between items-center">
|
||
<span class="text-body-md text-outline">餐后</span>
|
||
<span class="text-headline-md font-bold text-outline-variant">—— <small class="text-label-md">mmol/L</small></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="bg-surface-container-lowest rounded-3xl p-card-padding ambient-shadow">
|
||
<div class="flex justify-between items-center mb-4">
|
||
<span class="text-headline-md font-bold">05-25</span>
|
||
<span class="text-body-md text-outline">周一</span>
|
||
</div>
|
||
<div class="bg-background/50 border border-outline-variant/20 rounded-2xl p-4 flex justify-between items-center">
|
||
<span class="text-body-md text-outline">空腹</span>
|
||
<div class="text-right">
|
||
<span class="text-headline-lg font-extrabold text-error">10.2</span>
|
||
<span class="text-label-md text-outline ml-1">mmol/L</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<!-- Reward Section: 稳糖乐园 -->
|
||
<section class="bg-surface-container-lowest rounded-3xl p-card-padding ambient-shadow overflow-hidden relative" id="sugar-paradise">
|
||
<div class="flex justify-between items-start mb-6">
|
||
<div>
|
||
<h3 class="text-headline-md font-headline-md text-on-surface">稳糖乐园</h3>
|
||
<p class="text-body-md text-outline">用健康打卡浇灌你的稳糖树</p>
|
||
</div>
|
||
<div class="bg-primary/10 rounded-xl px-3 py-1 text-center">
|
||
<span class="block text-headline-lg font-extrabold text-primary" id="total-points">110</span>
|
||
<span class="text-[10px] text-primary/70 font-bold">稳糖积分</span>
|
||
</div>
|
||
</div>
|
||
<!-- Mini Quick Actions -->
|
||
<div class="grid grid-cols-4 gap-2 mb-8">
|
||
<button class="bg-surface-container-low p-3 rounded-2xl flex flex-col items-center gap-1 active-scale transition-all">
|
||
<span class="material-symbols-outlined text-primary" style="font-variation-settings: 'FILL' 1;">bloodtype</span>
|
||
<span class="text-label-md text-on-surface">血糖</span>
|
||
</button>
|
||
<button class="bg-surface-container-low p-3 rounded-2xl flex flex-col items-center gap-1 active-scale transition-all">
|
||
<span class="material-symbols-outlined text-primary">monitoring</span>
|
||
<span class="text-label-md text-on-surface">血压</span>
|
||
</button>
|
||
<button class="bg-surface-container-low p-3 rounded-2xl flex flex-col items-center gap-1 active-scale transition-all">
|
||
<span class="material-symbols-outlined text-primary">restaurant</span>
|
||
<span class="text-label-md text-on-surface">饮食</span>
|
||
</button>
|
||
<button class="bg-surface-container-low p-3 rounded-2xl flex flex-col items-center gap-1 active-scale transition-all">
|
||
<span class="material-symbols-outlined text-primary">exercise</span>
|
||
<span class="text-label-md text-on-surface">运动</span>
|
||
</button>
|
||
</div>
|
||
<h4 class="text-label-md font-bold text-on-surface mb-3">今日控糖任务</h4>
|
||
<div class="space-y-3">
|
||
<div class="flex items-center justify-between">
|
||
<div class="flex items-center gap-3">
|
||
<div class="w-8 h-8 rounded-full border-2 border-primary flex items-center justify-center">
|
||
<span class="material-symbols-outlined text-[16px] text-primary" style="font-variation-settings: 'wght' 700;">check</span>
|
||
</div>
|
||
<span class="text-body-md text-on-surface">测血糖血压</span>
|
||
</div>
|
||
<div class="flex items-center gap-3">
|
||
<span class="text-label-md text-primary font-bold">+10积分</span>
|
||
<span class="text-outline text-label-md font-bold italic">已完成</span>
|
||
</div>
|
||
</div>
|
||
<div class="flex items-center justify-between">
|
||
<div class="flex items-center gap-3">
|
||
<div class="w-8 h-8 rounded-full border-2 border-outline-variant/30 flex items-center justify-center">
|
||
<span class="w-2 h-2 rounded-full bg-outline-variant"></span>
|
||
</div>
|
||
<span class="text-body-md text-on-surface">记今日饮食</span>
|
||
</div>
|
||
<div class="flex items-center gap-3">
|
||
<span class="text-label-md text-primary font-bold">+10积分</span>
|
||
<button class="bg-on-surface text-surface rounded-full px-4 py-1 text-label-md font-bold active-scale transition-all">去记录</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- Optimized Level System & Gamification -->
|
||
<div class="mt-8 bg-gradient-to-br from-primary/5 to-primary/20 rounded-3xl p-6 border border-primary/10 relative overflow-hidden">
|
||
<!-- Level Indicator Header -->
|
||
<div class="flex justify-between items-end mb-6">
|
||
<div class="space-y-1">
|
||
<div class="flex items-center gap-2">
|
||
<span class="bg-primary text-on-primary text-[10px] px-2 py-0.5 rounded-full font-extrabold" id="level-label">Lv.4</span>
|
||
<span class="text-body-lg font-extrabold text-primary" id="stage-name">枝繁叶茂</span>
|
||
</div>
|
||
<p class="text-[11px] text-primary/60">还差 <span class="font-bold">15 XP</span> 升级至 Lv.4</p>
|
||
</div>
|
||
<div class="text-right">
|
||
<span class="text-label-md font-bold text-primary" id="xp-text">5/50 XP</span>
|
||
</div>
|
||
</div>
|
||
<!-- Progress Bar -->
|
||
<div class="w-full h-2.5 bg-white/50 rounded-full mb-8 overflow-hidden backdrop-blur-sm border border-white/20">
|
||
<div class="h-full bg-gradient-to-r from-primary to-primary-container rounded-full transition-all duration-500 shadow-inner" id="xp-progress" style="width: 10%;"></div>
|
||
</div>
|
||
<!-- Plant Growth Display -->
|
||
<div class="flex items-center justify-center py-8 relative min-h-[160px]">
|
||
<!-- Watering Animation Container -->
|
||
<div class="absolute top-0 left-0 w-full h-full pointer-events-none z-10" id="rain-container"></div>
|
||
<!-- Visual Stage Indicator Background -->
|
||
<div class="absolute inset-0 flex items-center justify-center opacity-10 pointer-events-none">
|
||
<span class="text-[120px] material-symbols-outlined text-primary" style="font-variation-settings: 'FILL' 1;">eco</span>
|
||
</div>
|
||
<!-- Current Plant State -->
|
||
<div class="relative z-20 transition-all duration-300" id="plant-container">
|
||
<span class="text-7xl drop-shadow-2xl filter block" id="plant-emoji">🪴</span>
|
||
</div>
|
||
</div>
|
||
<!-- Watering Action -->
|
||
<div class="relative z-30">
|
||
<button class="w-full bg-primary text-on-primary py-4 rounded-2xl text-body-lg font-bold flex items-center justify-center gap-3 shadow-lg active:scale-95 transition-all active:bg-primary-container group" id="water-btn">
|
||
<span class="material-symbols-outlined text-[24px] transition-transform group-active:-rotate-12 group-hover:scale-110">opacity</span>
|
||
给小树浇水
|
||
</button>
|
||
<p class="text-[11px] text-center text-outline mt-3 italic">浇水可消耗 5 积分,获得 10 XP</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<!-- Social Interaction -->
|
||
<section class="bg-surface-container-lowest rounded-3xl p-card-padding ambient-shadow flex items-center justify-between">
|
||
<div class="flex items-center gap-3">
|
||
<div class="w-10 h-10 bg-tertiary-container/20 rounded-2xl flex items-center justify-center">
|
||
<span class="material-symbols-outlined text-tertiary" style="font-variation-settings: 'FILL' 1;">favorite</span>
|
||
</div>
|
||
<div>
|
||
<h4 class="text-body-md font-bold text-on-surface">邀请家人点赞</h4>
|
||
<p class="text-[12px] text-outline">分享战报给家人,邀请他们为您点赞鼓励</p>
|
||
</div>
|
||
</div>
|
||
<span class="material-symbols-outlined text-outline">chevron_right</span>
|
||
</section>
|
||
<!-- Status Tip -->
|
||
<div class="flex items-start gap-3 px-2">
|
||
<span class="material-symbols-outlined text-primary-container text-[20px]">chat_bubble</span>
|
||
<div>
|
||
<p class="text-body-md text-on-surface">先完成血糖记录,<span class="text-primary font-bold">今日第一格就亮起来</span>。</p>
|
||
<button class="text-outline text-label-md hover:text-primary transition-colors">轻触换一句鼓励 ›</button>
|
||
</div>
|
||
</div>
|
||
<!-- Care List Horizontal -->
|
||
<div class="flex items-center gap-3 overflow-x-auto hide-scrollbar -mx-container-margin px-container-margin pb-2">
|
||
<div class="shrink-0 flex items-center gap-2 bg-white px-3 py-2 rounded-xl shadow-sm border border-outline-variant/20">
|
||
<span class="text-label-md text-outline">就诊卡</span>
|
||
<span class="text-label-md font-extrabold text-on-surface">10 张</span>
|
||
</div>
|
||
<div class="shrink-0 flex items-center gap-2 bg-primary text-on-primary px-3 py-2 rounded-xl shadow-md">
|
||
<span class="text-label-md font-bold">吕帅</span>
|
||
<span class="text-[10px] bg-white/20 rounded px-1">23岁</span>
|
||
</div>
|
||
<div class="shrink-0 flex items-center gap-2 bg-surface-container-high text-on-surface-variant px-3 py-2 rounded-xl border border-outline-variant/30">
|
||
<span class="text-label-md font-bold">霍爱玲</span>
|
||
<span class="text-[10px] text-outline">57岁</span>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
<!-- Footer Note -->
|
||
<footer class="mt-8 text-center px-container-margin pb-12">
|
||
<p class="text-[11px] text-outline-variant/60">数据每日同步 · 阈值仅作参考,请遵医嘱</p>
|
||
</footer>
|
||
<!-- Navigation Bar -->
|
||
|
||
<script>
|
||
// State Management
|
||
let currentXP = 35;
|
||
let currentLevel = 3;
|
||
let totalPoints = 120;
|
||
const maxLevel = 10;
|
||
const xpPerLevel = 50;
|
||
|
||
const stageNames = [
|
||
"种子眠", "破土而出", "茁壮成长", "枝繁叶茂", "初绽花蕾",
|
||
"繁花似锦", "硕果初步", "丰收在望", "参天大树", "森林守护"
|
||
];
|
||
|
||
const plantEmojis = [
|
||
"🫘", "🌱", "🌿", "🪴", "🎍",
|
||
"🌸", "🍒", "🍎", "🌳", "🌲"
|
||
];
|
||
|
||
// DOM Elements
|
||
const waterBtn = document.getElementById('water-btn');
|
||
const rainContainer = document.getElementById('rain-container');
|
||
const plantContainer = document.getElementById('plant-container');
|
||
const plantEmoji = document.getElementById('plant-emoji');
|
||
const xpProgress = document.getElementById('xp-progress');
|
||
const xpText = document.getElementById('xp-text');
|
||
const levelLabel = document.getElementById('level-label');
|
||
const stageNameLabel = document.getElementById('stage-name');
|
||
const totalPointsLabel = document.getElementById('total-points');
|
||
|
||
// Watering Animation Logic
|
||
function createRain() {
|
||
for (let i = 0; i < 15; i++) {
|
||
const droplet = document.createElement('div');
|
||
droplet.className = 'droplet';
|
||
droplet.style.left = `${Math.random() * 100}%`;
|
||
droplet.style.animationDelay = `${Math.random() * 0.4}s`;
|
||
rainContainer.appendChild(droplet);
|
||
|
||
// Cleanup
|
||
setTimeout(() => droplet.remove(), 600);
|
||
}
|
||
}
|
||
|
||
function triggerGrowthPulse() {
|
||
plantContainer.classList.add('growth-pulse');
|
||
setTimeout(() => {
|
||
plantContainer.classList.remove('growth-pulse');
|
||
}, 800);
|
||
}
|
||
|
||
function createSparkles() {
|
||
for (let i = 0; i < 12; i++) {
|
||
const sparkle = document.createElement('span');
|
||
sparkle.className = 'material-symbols-outlined shimmer-particle';
|
||
sparkle.textContent = 'sparkles';
|
||
sparkle.style.left = `${40 + (Math.random() - 0.5) * 40}%`;
|
||
sparkle.style.top = `${40 + (Math.random() - 0.5) * 40}%`;
|
||
sparkle.style.animationDuration = `${0.6 + Math.random() * 0.4}s`;
|
||
plantContainer.appendChild(sparkle);
|
||
|
||
setTimeout(() => sparkle.remove(), 1000);
|
||
}
|
||
}
|
||
|
||
function triggerSugarDecreaseEffect() {
|
||
// 1. Floating Text
|
||
const floatingText = document.createElement('div');
|
||
floatingText.className = 'sugar-decrease-text';
|
||
floatingText.textContent = '-0.5 mmol/L';
|
||
|
||
// Randomize spawn position near the plant
|
||
const rect = plantContainer.getBoundingClientRect();
|
||
floatingText.style.left = `${rect.left + rect.width / 2}px`;
|
||
floatingText.style.top = `${rect.top}px`;
|
||
|
||
document.body.appendChild(floatingText);
|
||
setTimeout(() => floatingText.remove(), 2000);
|
||
|
||
// 2. Full-screen Downward Particles
|
||
for (let i = 0; i < 20; i++) {
|
||
setTimeout(() => {
|
||
const particle = document.createElement('div');
|
||
particle.className = 'sugar-particle text-primary-container';
|
||
// Mix arrows and symbols
|
||
particle.innerHTML = Math.random() > 0.5 ? '<span class="material-symbols-outlined">south</span>' : '▼';
|
||
particle.style.left = `${Math.random() * 100}vw`;
|
||
particle.style.fontSize = `${16 + Math.random() * 16}px`;
|
||
particle.style.opacity = '0';
|
||
|
||
document.body.appendChild(particle);
|
||
setTimeout(() => particle.remove(), 1500);
|
||
}, i * 50);
|
||
}
|
||
}
|
||
|
||
function updateDisplay() {
|
||
const progress = (currentXP / xpPerLevel) * 100;
|
||
xpProgress.style.width = `${progress}%`;
|
||
xpText.textContent = `${currentXP}/${xpPerLevel} XP`;
|
||
levelLabel.textContent = `Lv.${currentLevel}`;
|
||
stageNameLabel.textContent = stageNames[currentLevel - 1];
|
||
plantEmoji.textContent = plantEmojis[currentLevel - 1];
|
||
totalPointsLabel.textContent = totalPoints;
|
||
}
|
||
|
||
// Action Logic
|
||
waterBtn.addEventListener('click', () => {
|
||
if (totalPoints < 5) {
|
||
alert("积分不足,快去完成任务领积分吧!");
|
||
return;
|
||
}
|
||
|
||
// Lock button briefly
|
||
waterBtn.disabled = true;
|
||
waterBtn.classList.add('opacity-50');
|
||
|
||
// 1. Consume Points
|
||
totalPoints -= 5;
|
||
|
||
// 2. Trigger Animations
|
||
createRain();
|
||
|
||
setTimeout(() => {
|
||
triggerGrowthPulse();
|
||
createSparkles();
|
||
triggerSugarDecreaseEffect(); // New Effect
|
||
|
||
// 3. Update State
|
||
currentXP += 10;
|
||
if (currentXP >= xpPerLevel && currentLevel < maxLevel) {
|
||
currentXP -= xpPerLevel;
|
||
currentLevel++;
|
||
}
|
||
|
||
updateDisplay();
|
||
|
||
// Unlock button
|
||
waterBtn.disabled = false;
|
||
waterBtn.classList.remove('opacity-50');
|
||
}, 600);
|
||
});
|
||
|
||
// Initialize
|
||
updateDisplay();
|
||
|
||
// Simple button micro-interactions for others
|
||
document.querySelectorAll('button:not(#water-btn)').forEach(btn => {
|
||
btn.addEventListener('click', () => {
|
||
if(!btn.classList.contains('cursor-not-allowed')) {
|
||
// Interaction logic
|
||
}
|
||
});
|
||
});
|
||
</script>
|
||
|
||
|
||
</body></html> |