refactor: 简化 landing page 优化字体样式

- 回退复杂的功能介绍区域,保留简洁设计
- 优化副标题可读性:添加柔和背景 + serif 字体
- 保持整体禅意风格不变

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
ddshi 2026-02-10 17:22:27 +08:00
parent 25f999cb1f
commit 69953c43cf

View File

@ -1,5 +1,5 @@
import { useEffect, useRef } from 'react'; import { useEffect, useRef } from 'react';
import { Button, Container, Title, Text, Group, Stack, Paper, ThemeIcon, SimpleGrid, Box } from '@mantine/core'; import { Button, Container, Title, Text, Group, Stack } from '@mantine/core';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import iconUrl from '../assets/icon.png'; import iconUrl from '../assets/icon.png';
@ -22,12 +22,10 @@ function ZenBackground() {
resize(); resize();
window.addEventListener('resize', resize); window.addEventListener('resize', resize);
// 简化的伪随机
const random = (min = 0, max = 1) => { const random = (min = 0, max = 1) => {
return min + Math.random() * (max - min); return min + Math.random() * (max - min);
}; };
// 简化的噪声函数
const noise = (x: number, y: number, t: number) => { const noise = (x: number, y: number, t: number) => {
return (Math.sin(x * 0.01 + t) * Math.cos(y * 0.01 + t * 0.7) + 1) * 0.5; return (Math.sin(x * 0.01 + t) * Math.cos(y * 0.01 + t * 0.7) + 1) * 0.5;
}; };
@ -50,7 +48,6 @@ function ZenBackground() {
let lastStrokeTime = 0; let lastStrokeTime = 0;
const strokeInterval = 30; const strokeInterval = 30;
// 生成随机笔触
const createStroke = (): InkStroke | null => { const createStroke = (): InkStroke | null => {
const angle = random(0, Math.PI * 2); const angle = random(0, Math.PI * 2);
const radius = random(canvas.width * 0.1, canvas.width * 0.4); const radius = random(canvas.width * 0.1, canvas.width * 0.4);
@ -71,7 +68,6 @@ function ZenBackground() {
}; };
}; };
// 初始化一些笔触
const initStrokes = () => { const initStrokes = () => {
strokes = []; strokes = [];
for (let i = 0; i < 8; i++) { for (let i = 0; i < 8; i++) {
@ -85,20 +81,17 @@ function ZenBackground() {
initStrokes(); initStrokes();
// 清空画布
ctx.fillStyle = '#faf9f7'; ctx.fillStyle = '#faf9f7';
ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillRect(0, 0, canvas.width, canvas.height);
const animate = () => { const animate = () => {
time += 0.008; time += 0.008;
// 快速淡出背景
if (Math.floor(time * 125) % 3 === 0) { if (Math.floor(time * 125) % 3 === 0) {
ctx.fillStyle = 'rgba(250, 249, 247, 0.12)'; ctx.fillStyle = 'rgba(250, 249, 247, 0.12)';
ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillRect(0, 0, canvas.width, canvas.height);
} }
// 定期生成新笔触
if (time - lastStrokeTime > strokeInterval * 0.01) { if (time - lastStrokeTime > strokeInterval * 0.01) {
lastStrokeTime = time; lastStrokeTime = time;
strokes = strokes.filter(s => !s.complete || s.currentLength < s.maxLength); strokes = strokes.filter(s => !s.complete || s.currentLength < s.maxLength);
@ -109,7 +102,6 @@ function ZenBackground() {
} }
} }
// 更新和绘制笔触
for (const stroke of strokes) { for (const stroke of strokes) {
if (stroke.complete) continue; if (stroke.complete) continue;
@ -162,7 +154,6 @@ function ZenBackground() {
} }
} }
// 绘制圆相Ensō
const centerX = canvas.width / 2; const centerX = canvas.width / 2;
const centerY = canvas.height / 2; const centerY = canvas.height / 2;
const breathScale = 1 + Math.sin(time * 0.3) * 0.015; const breathScale = 1 + Math.sin(time * 0.3) * 0.015;
@ -214,40 +205,6 @@ function ZenBackground() {
); );
} }
// 功能特性卡片
function FeatureCard({
icon,
title,
description,
}: {
icon: string;
title: string;
description: string;
}) {
return (
<Paper
p="lg"
radius="sm"
style={{
background: 'rgba(255, 255, 255, 0.6)',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(0, 0, 0, 0.05)',
height: '100%',
}}
>
<Stack gap="sm">
<Text size="xl" fw={300} style={{ letterSpacing: '0.1em' }}>{icon}</Text>
<Text size="md" fw={500} style={{ letterSpacing: '0.08em', color: '#1a1a1a' }}>
{title}
</Text>
<Text size="sm" c="#666" style={{ lineHeight: 1.8, fontWeight: 300 }}>
{description}
</Text>
</Stack>
</Paper>
);
}
export function LandingPage() { export function LandingPage() {
const navigate = useNavigate(); const navigate = useNavigate();
@ -309,62 +266,54 @@ export function LandingPage() {
</svg> </svg>
<Container <Container
size="lg" size="sm"
style={{ style={{
position: 'relative', position: 'relative',
zIndex: 1, zIndex: 1,
minHeight: '100vh', minHeight: '100vh',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
padding: '3rem 1rem', justifyContent: 'center',
}}
>
{/* Hero 区域 */}
<Box
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center', alignItems: 'center',
textAlign: 'center', textAlign: 'center',
paddingTop: 'min(15vh, 120px)', padding: '2rem',
paddingBottom: 'min(10vh, 80px)',
}} }}
> >
<Stack align="center" gap="lg">
{/* 产品图标 */} {/* 产品图标 */}
<div <div
style={{ style={{
width: 100, width: 90,
height: 100, height: 90,
borderRadius: '50%', borderRadius: '50%',
background: 'rgba(26, 26, 26, 0.04)', background: 'rgba(26, 26, 26, 0.03)',
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
marginBottom: '2rem', marginBottom: '0.5rem',
}} }}
> >
<img <img
src={iconUrl} src={iconUrl}
alt="掐日子" alt="掐日子"
style={{ style={{
width: 65, width: 60,
height: 65, height: 60,
borderRadius: '50%', borderRadius: '50%',
}} }}
/> />
</div> </div>
{/* 主标题 */} {/* 主标题 - 优化字体 */}
<Title <Title
order={1} order={1}
style={{ style={{
fontWeight: 200, fontWeight: 300,
fontSize: 'clamp(2.5rem, 8vw, 4rem)', fontSize: 'clamp(2.2rem, 7vw, 3.2rem)',
letterSpacing: '0.2em', letterSpacing: '0.25em',
color: '#1a1a1a', color: '#1a1a1a',
fontFamily: 'Noto Serif SC, Georgia, serif', fontFamily: 'Noto Serif SC, Georgia, serif',
marginBottom: '0.5rem', lineHeight: 1.3,
textShadow: '0 2px 10px rgba(0,0,0,0.03)',
}} }}
> >
@ -374,16 +323,14 @@ export function LandingPage() {
<Text <Text
size="lg" size="lg"
style={{ style={{
letterSpacing: '0.35em',
color: '#444',
fontWeight: 400, fontWeight: 400,
fontSize: 'clamp(1rem, 2.5vw, 1.25rem)', fontSize: '1rem',
letterSpacing: '0.3em',
color: '#333',
fontFamily: 'Noto Serif SC, serif', fontFamily: 'Noto Serif SC, serif',
marginBottom: '1rem', padding: '0.4rem 1rem',
padding: '0.5rem 1.5rem', background: 'rgba(250, 250, 250, 0.8)',
background: 'rgba(255, 255, 255, 0.7)', borderRadius: 2,
backdropFilter: 'blur(4px)',
borderRadius: '2px',
}} }}
> >
AI · AI ·
@ -391,13 +338,13 @@ export function LandingPage() {
{/* 描述文案 */} {/* 描述文案 */}
<Text <Text
size="sm" size="xs"
style={{ style={{
color: '#666', color: '#777',
maxWidth: 360, maxWidth: 320,
lineHeight: 2, lineHeight: 2,
fontWeight: 300, fontWeight: 300,
fontSize: '0.9rem', fontSize: '0.85rem',
}} }}
> >
便 便
@ -405,70 +352,57 @@ export function LandingPage() {
</Text> </Text>
<Group gap="md" mt="xl"> <Group gap="md" mt="md">
<Button <Button
size="md" size="sm"
onClick={() => navigate('/login')} onClick={() => navigate('/login')}
style={{ style={{
background: '#1a1a1a', background: '#1a1a1a',
border: '1px solid #1a1a1a', border: '1px solid #1a1a1a',
padding: '0.75rem 2.5rem', padding: '0 2rem',
fontWeight: 400, fontWeight: 400,
letterSpacing: '0.2em', letterSpacing: '0.15em',
borderRadius: 2, borderRadius: 2,
fontSize: '0.85rem',
}} }}
> >
</Button> </Button>
<Button <Button
size="md" size="sm"
variant="outline" variant="outline"
onClick={() => navigate('/register')} onClick={() => navigate('/register')}
style={{ style={{
borderColor: '#999', borderColor: '#ccc',
color: '#1a1a1a', color: '#1a1a1a',
padding: '0.75rem 2.5rem', padding: '0 2rem',
fontWeight: 400, fontWeight: 400,
letterSpacing: '0.2em', letterSpacing: '0.15em',
borderRadius: 2, borderRadius: 2,
fontSize: '0.85rem',
}} }}
> >
</Button> </Button>
</Group> </Group>
</Box>
{/* 功能介绍区域 */} <Group gap={40} mt={40} style={{ opacity: 0.6 }}>
<Box <Stack gap={3} align="center">
style={{ <Text size="xs" fw={300} c="#444"></Text>
paddingBottom: 'min(15vh, 120px)', <Text size="xs" c="#666" style={{ letterSpacing: '0.1em' }}></Text>
}} </Stack>
> <Stack gap={3} align="center">
<SimpleGrid cols={{ base: 1, sm: 2, md: 4 }} spacing="lg"> <Text size="xs" fw={300} c="#444"></Text>
<FeatureCard <Text size="xs" c="#666" style={{ letterSpacing: '0.1em' }}></Text>
icon="◯" </Stack>
title="纪念日" <Stack gap={3} align="center">
description="记录生日、结婚纪念日等重要日子。支持农历日期,自动计算倒数日。轻松掌握还有多少天到来,让每个值得纪念的日子都不被遗忘。" <Text size="xs" fw={300} c="#444"></Text>
/> <Text size="xs" c="#666" style={{ letterSpacing: '0.1em' }}>AI</Text>
<FeatureCard </Stack>
icon="◎" <Stack gap={3} align="center">
title="提醒" <Text size="xs" fw={300} c="#444"></Text>
description="设置一次性或重复提醒事项。支持多种提前提醒时间准时、提前5/15分钟、1小时、1天。重要事项准时送达不错过任何关键节点。" <Text size="xs" c="#666" style={{ letterSpacing: '0.1em' }}>便</Text>
/> </Stack>
<FeatureCard </Group>
icon="◇" </Stack>
title="AI 智能"
description="AI 智能解析自然语言快速创建事件。只需输入「生日是3月15日」AI 自动识别日期、类型和重复规则。创建提醒从未如此简单。"
/>
<FeatureCard
icon="▫"
title="便签"
description="支持 Markdown 的个人笔记空间。随时记录想法、灵感或待办事项。与纪念日和提醒功能无缝配合,打造完整的个人时间管理工具。"
/>
</SimpleGrid>
</Box>
</Container> </Container>
</div> </div>
); );