From e10e3c823019c40f7273241bf7c44826bc39fc5a Mon Sep 17 00:00:00 2001 From: kurihada Date: Thu, 26 Feb 2026 11:27:18 +0800 Subject: [PATCH] =?UTF-8?q?ui:=20=E5=85=A8=E7=AB=99=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E6=9A=97=E8=89=B2=E4=B8=BB=E9=A2=98=E8=AE=BE=E8=AE=A1=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - globals.css 定义语义化 token (background/surface/elevated/border/muted/dim/accent) - 所有页面和组件迁移至暗色 token,移除硬编码 bg-white/text-zinc-*/bg-gray-* - RestaurantCard 和 MatchResult 适配暗色卡片风格 - 按钮颜色分层:系统CTA(accent)/模式强调(橙/紫)/危险(rose)/次级(surface) - 修复 room 页深色文字在深背景不可见的可访问性问题 --- src/app/globals.css | 23 +++++- src/app/invite/[id]/page.tsx | 62 +++++++-------- src/app/profile/page.tsx | 109 +++++++++++++-------------- src/app/room/[id]/page.tsx | 10 +-- src/components/ActionButtons.tsx | 4 +- src/components/AuthModal.tsx | 40 +++++----- src/components/LeaveConfirmModal.tsx | 16 ++-- src/components/MatchResult.tsx | 87 +++++++++++---------- src/components/QrInviteModal.tsx | 24 +++--- src/components/RestaurantCard.tsx | 28 +++---- src/components/RoomManageModal.tsx | 38 +++++----- src/components/SwipeDeck.tsx | 32 ++++---- src/components/TopNav.tsx | 18 ++--- 13 files changed, 258 insertions(+), 233 deletions(-) diff --git a/src/app/globals.css b/src/app/globals.css index 22f9ba3..0790fe0 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,13 +1,27 @@ @import "tailwindcss"; :root { - --background: #f8f9fa; - --foreground: #171717; + --background: #030712; + --foreground: #f3f4f6; } @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); + + --color-surface: #111827; + --color-elevated: #1f2937; + --color-inset: #0a0f1a; + + --color-border: #1f2937; + --color-subtle: #374151; + + --color-muted: #6b7280; + --color-dim: #4b5563; + + --color-accent: #10b981; + --color-accent-hover: #059669; + --font-sans: var(--font-geist-sans); --font-mono: var(--font-geist-mono); } @@ -39,3 +53,8 @@ body { from { opacity: 1; } to { opacity: 0; } } + +@keyframes shimmer { + 0% { transform: translateX(-100%); } + 100% { transform: translateX(100%); } +} diff --git a/src/app/invite/[id]/page.tsx b/src/app/invite/[id]/page.tsx index 84ef7e8..cccc86b 100644 --- a/src/app/invite/[id]/page.tsx +++ b/src/app/invite/[id]/page.tsx @@ -62,7 +62,7 @@ export default function InvitePage() { if (status === "loading") { return (
-
+
); } @@ -70,16 +70,16 @@ export default function InvitePage() { if (status === "not_found") { return (
-
- +
+
-

房间不存在

-

+

房间不存在

+

这个房间已过期或不存在,请让朋友重新分享链接

@@ -88,44 +88,44 @@ export default function InvitePage() { } return ( -
+
-
+
{scene === "drink" ? : }
-

+

NoWhatever

-

+

别说随便

-

+

{sceneConfig.inviteText}

-
- +
+ {roomId}
{userCount > 0 && ( -
+
- 已有 {userCount} 人在房间 + 已有 {userCount} 人在房间
)} @@ -138,35 +138,35 @@ export default function InvitePage() { transition={{ duration: 0.5, delay: 0.2 }} >
-
- +
+
- 加入房间 - + 加入房间 + 和朋友一起
- +
-
- +
+
- 各自滑卡 - + 各自滑卡 + 右滑喜欢的店
- +
-
- +
+
- 匹配结果 - + 匹配结果 + 滑中同一家就去
@@ -181,7 +181,7 @@ export default function InvitePage() { -

个人中心

+

个人中心

{/* Profile card */} @@ -290,7 +289,7 @@ export default function ProfilePage() { className={`relative flex h-14 w-14 items-center justify-center rounded-2xl text-2xl transition-transform active:scale-95 ${getAvatarBg(profile.avatar)}`} > {profile.avatar} - + @@ -306,34 +305,34 @@ export default function ProfilePage() { }} maxLength={16} autoFocus - className="h-8 flex-1 rounded-lg border border-zinc-200 px-2 text-sm text-zinc-800 outline-none focus:border-emerald-400 focus:ring-2 focus:ring-emerald-100" + className="h-8 flex-1 rounded-lg border-none bg-elevated px-2 text-sm text-white outline-none ring-1 ring-border focus:ring-2 focus:ring-accent/50" />
) : (
-

{profile.username}

+

{profile.username}

)} - {usernameMsg &&

{usernameMsg}

} + {usernameMsg &&

{usernameMsg}

}
@@ -354,8 +353,8 @@ export default function ProfilePage() { onClick={() => handleSaveAvatar(a.emoji)} className={`flex h-11 w-11 items-center justify-center rounded-xl text-xl transition-all ${ profile.avatar === a.emoji - ? `${a.bg} scale-110 ring-2 ring-emerald-400 ring-offset-1` - : "bg-zinc-50 hover:bg-zinc-100" + ? `${a.bg} scale-110 ring-2 ring-accent ring-offset-1 ring-offset-surface` + : "bg-elevated hover:bg-subtle" }`} > {a.emoji} @@ -369,7 +368,7 @@ export default function ProfilePage() { {/* Change password */} { setEditingPassword(!editingPassword); setPasswordMsg(""); }} className="flex w-full items-center gap-2" > - -

修改密码

+ +

修改密码

@@ -393,46 +392,46 @@ export default function ProfilePage() { >
-

当前密码

+

当前密码

{ setCurrentPassword(e.target.value); setPasswordMsg(""); }} - className="h-9 w-full rounded-lg border border-zinc-200 px-3 pr-9 text-sm text-zinc-800 outline-none focus:border-emerald-400 focus:ring-2 focus:ring-emerald-100" + className="h-9 w-full rounded-lg border-none bg-elevated px-3 pr-9 text-sm text-white outline-none ring-1 ring-border focus:ring-2 focus:ring-accent/50" />
-

新密码

+

新密码

{ setNewPassword(e.target.value); setPasswordMsg(""); }} placeholder="至少 6 个字符" - className="mt-1 h-9 w-full rounded-lg border border-zinc-200 px-3 text-sm text-zinc-800 outline-none placeholder:text-zinc-300 focus:border-emerald-400 focus:ring-2 focus:ring-emerald-100" + className="mt-1 h-9 w-full rounded-lg border-none bg-elevated px-3 text-sm text-white outline-none ring-1 ring-border placeholder:text-dim focus:ring-2 focus:ring-accent/50" />
-

确认新密码

+

确认新密码

{ setConfirmPassword(e.target.value); setPasswordMsg(""); }} placeholder="再次输入新密码" - className="mt-1 h-9 w-full rounded-lg border border-zinc-200 px-3 text-sm text-zinc-800 outline-none placeholder:text-zinc-300 focus:border-emerald-400 focus:ring-2 focus:ring-emerald-100" + className="mt-1 h-9 w-full rounded-lg border-none bg-elevated px-3 text-sm text-white outline-none ring-1 ring-border placeholder:text-dim focus:ring-2 focus:ring-accent/50" />
{passwordMsg && ( -

+

{passwordMsg}

)} @@ -440,7 +439,7 @@ export default function ProfilePage() { @@ -452,15 +451,15 @@ export default function ProfilePage() { {/* Email binding */}
- -

绑定邮箱

- (可选) + +

绑定邮箱

+ (可选)
{emailMsg && ( -

+

{emailMsg}

)} @@ -490,7 +489,7 @@ export default function ProfilePage() { {/* Decision History */}
- -

+ +

决策记录 {history.length > 0 && `(${history.length})`}

@@ -525,10 +524,10 @@ export default function ProfilePage() { > {historyLoading ? (
- +
) : history.length === 0 ? ( -

+

还没有决策记录

) : ( @@ -539,7 +538,7 @@ export default function ProfilePage() { href={amapNavUrl(d.restaurantData)} target="_blank" rel="noopener noreferrer" - className="flex gap-3 rounded-xl bg-zinc-50 p-2.5 transition-colors active:bg-zinc-100" + className="flex gap-3 rounded-xl bg-elevated p-2.5 transition-colors active:bg-subtle" > {firstImage(d.restaurantData) && ( )}
-

{d.restaurantName}

-
+

{d.restaurantName}

+
{d.matchType === "unanimous" ? "全员一致" : "最佳匹配"} {d.participants} 人参与 {new Date(d.createdAt).toLocaleDateString("zh-CN", { month: "short", day: "numeric" })} @@ -568,7 +567,7 @@ export default function ProfilePage() { {/* Favorites */}
- -

+ +

收藏餐厅 {favorites.length > 0 && `(${favorites.length})`}

@@ -603,10 +602,10 @@ export default function ProfilePage() { > {favLoading ? (
- +
) : favorites.length === 0 ? ( -

+

还没有收藏的餐厅

) : ( @@ -616,7 +615,7 @@ export default function ProfilePage() { return (
{firstImage(r) && ( )}
-

{r.name}

-
+

{r.name}

+
{r.rating} @@ -644,7 +643,7 @@ export default function ProfilePage() {
@@ -667,7 +666,7 @@ export default function ProfilePage() { > @@ -113,8 +113,8 @@ export default function RoomPage() { if (!ready) { return (
-
-

正在加载数据...

+
+

正在加载数据...

); } diff --git a/src/components/ActionButtons.tsx b/src/components/ActionButtons.tsx index 86f4238..29f600f 100644 --- a/src/components/ActionButtons.tsx +++ b/src/components/ActionButtons.tsx @@ -16,7 +16,7 @@ export default function ActionButtons({ return (
onAction("left")} @@ -27,7 +27,7 @@ export default function ActionButtons({ onAction("right")} diff --git a/src/components/AuthModal.tsx b/src/components/AuthModal.tsx index 1a233ba..3bcaf1b 100644 --- a/src/components/AuthModal.tsx +++ b/src/components/AuthModal.tsx @@ -117,7 +117,7 @@ export default function AuthModal({ open, onClose, onAuth }: AuthModalProps) { {open && (
- 欢迎 + 欢迎
{/* Tabs */} -
+
{(["login", "register"] as const).map((t) => ( @@ -208,7 +208,7 @@ export default function AuthModal({ open, onClose, onAuth }: AuthModalProps) { {/* Confirm password (register only) */} {tab === "register" && (
-

确认密码

+

确认密码

)} @@ -225,9 +225,9 @@ export default function AuthModal({ open, onClose, onAuth }: AuthModalProps) { {/* Avatar picker (register only) */} {tab === "register" && (
-

+

选择头像 - (可选) + (可选)

{AVATARS.map((a) => ( @@ -236,8 +236,8 @@ export default function AuthModal({ open, onClose, onAuth }: AuthModalProps) { onClick={() => setAvatar(a.emoji)} className={`flex h-11 w-11 items-center justify-center rounded-xl text-xl transition-all ${ avatar === a.emoji - ? `${a.bg} scale-110 ring-2 ring-emerald-400 ring-offset-1` - : "bg-zinc-50 hover:bg-zinc-100" + ? `${a.bg} scale-110 ring-2 ring-accent ring-offset-1 ring-offset-surface` + : "bg-elevated hover:bg-subtle" }`} > {a.emoji} @@ -249,7 +249,7 @@ export default function AuthModal({ open, onClose, onAuth }: AuthModalProps) { {error && ( @@ -260,7 +260,7 @@ export default function AuthModal({ open, onClose, onAuth }: AuthModalProps) { diff --git a/src/components/MatchResult.tsx b/src/components/MatchResult.tsx index bef706b..deb561d 100644 --- a/src/components/MatchResult.tsx +++ b/src/components/MatchResult.tsx @@ -58,7 +58,7 @@ function NoMatchResult({ return ( - + @@ -107,7 +107,7 @@ function NoMatchResult({ router.push("/")} - className="flex items-center justify-center gap-2 rounded-full bg-white/15 px-8 py-3 text-sm font-bold text-white backdrop-blur-sm transition-colors hover:bg-white/25" + className="flex items-center justify-center gap-2 rounded-full bg-surface px-8 py-3 text-sm font-bold text-muted ring-1 ring-border transition-colors hover:bg-elevated" whileTap={{ scale: 0.95 }} > @@ -132,7 +132,7 @@ function RunnerUpCard({ href={buildNavUrl(restaurant)} target="_blank" rel="noopener noreferrer" - className="flex gap-3 rounded-xl bg-white/10 p-2.5 backdrop-blur-sm transition-colors hover:bg-white/20" + className="flex gap-3 rounded-xl bg-surface/80 p-2.5 ring-1 ring-border/50 backdrop-blur-sm transition-colors hover:bg-elevated/80" > {restaurant.images?.[0] && ( {restaurant.name}

-
+
{restaurant.rating} @@ -159,7 +159,7 @@ function RunnerUpCard({ )}
-

+

{likes}/{userCount} 人想去

@@ -282,25 +282,28 @@ export default function MatchResult({ return ( -
+ {/* Accent glow behind icon */} +
+ +
{isUnanimous ? ( - + ) : ( - + )} @@ -314,7 +317,7 @@ export default function MatchResult({ - - + + 默契度 100% · {userCount} 人全员一致 - + )} + {/* Result card */}
-

+

{restaurant.name}

{restaurant.category && ( - + {restaurant.category} )}
-
+
{restaurant.rating} - + {restaurant.price} {restaurant.distance && ( @@ -387,13 +391,13 @@ export default function MatchResult({
{restaurant.address && ( -

+

{restaurant.address}

)} {restaurant.openTime && ( -
+
{restaurant.openTime}
@@ -407,7 +411,7 @@ export default function MatchResult({ .map((t) => ( {t.trim()} @@ -417,6 +421,7 @@ export default function MatchResult({
+ {/* Action buttons */} @@ -439,7 +442,7 @@ export default function MatchResult({ {restaurant.tel && ( @@ -449,7 +452,7 @@ export default function MatchResult({ @@ -457,6 +460,7 @@ export default function MatchResult({ + {/* Runner ups */} {!isUnanimous && runnerUpRestaurants.length > 0 && (
-
- +
+

邀请饭搭子

-

+

{sceneConfig.qrSubtitle}

-
+
- 房间号 - + 房间号 + {roomId}
@@ -116,14 +116,14 @@ export default function QrInviteModal({
- -

房间管理

+ +

房间管理

-

+

房间号 {roomId}

@@ -131,8 +131,8 @@ export default function RoomManageModal({ disabled={loading !== null} className={`flex h-11 w-full items-center justify-center gap-2 rounded-xl text-sm font-semibold transition-colors disabled:opacity-50 ${ locked - ? "border border-emerald-200 bg-emerald-50 text-emerald-700 active:bg-emerald-100" - : "border border-zinc-200 bg-white text-zinc-700 active:bg-zinc-50" + ? "bg-accent/15 text-accent ring-1 ring-accent/30 active:bg-accent/25" + : "bg-elevated text-gray-300 ring-1 ring-border active:bg-subtle" }`} > {loading === "lock" || loading === "unlock" ? ( @@ -148,7 +148,7 @@ export default function RoomManageModal({ {/* User list with kick */}
-

+

房间成员({users.length})

@@ -164,7 +164,7 @@ export default function RoomManageModal({ return (
{isCreator && ( - + 房主 )} - + {displayName}
{swiped}/{totalCards} {finished ? " 已完成" : " 进行中"} @@ -211,7 +211,7 @@ export default function RoomManageModal({ @@ -219,7 +219,7 @@ export default function RoomManageModal({ ) : ( @@ -265,7 +265,7 @@ export default function RoomManageModal({
-

+

NoWhatever - + 别说随便

-
+
{locked && ( )} - + {roomId}
- {userCount} + {userCount}