diff --git a/src/app/(site)/apply/staff/page.tsx b/src/app/(site)/apply/staff/page.tsx index ce8c9493..0b917712 100644 --- a/src/app/(site)/apply/staff/page.tsx +++ b/src/app/(site)/apply/staff/page.tsx @@ -96,7 +96,7 @@ export default async function ApplyStaffPage({ const appliedRankIds = new Set(myApps.map((a) => a.rankId)); return ( -
+
{submitted === "1" ? (
{t("success.submitted")} diff --git a/src/app/(site)/apply/team/page.tsx b/src/app/(site)/apply/team/page.tsx index eff964c4..82d4a130 100644 --- a/src/app/(site)/apply/team/page.tsx +++ b/src/app/(site)/apply/team/page.tsx @@ -75,7 +75,7 @@ export default async function ApplyTeamPage({ const appliedTeamIds = new Set(myApps.map((a) => a.rankId)); return ( -
+
{submitted === "1" ? (
{t("success.submitted")} diff --git a/src/app/(site)/badges/page.tsx b/src/app/(site)/badges/page.tsx index d374f6fb..94f927c5 100644 --- a/src/app/(site)/badges/page.tsx +++ b/src/app/(site)/badges/page.tsx @@ -18,7 +18,7 @@ export default async function BadgesPage() { .catch(() => []); return ( -
+
diff --git a/src/app/(site)/community/page.tsx b/src/app/(site)/community/page.tsx index 49a697e6..c4139f7d 100644 --- a/src/app/(site)/community/page.tsx +++ b/src/app/(site)/community/page.tsx @@ -41,7 +41,7 @@ export default function CommunityPage() { const t = useTranslations("pages.community"); return ( -
+
diff --git a/src/app/(site)/developers/page.tsx b/src/app/(site)/developers/page.tsx index db575deb..35c3209d 100644 --- a/src/app/(site)/developers/page.tsx +++ b/src/app/(site)/developers/page.tsx @@ -389,7 +389,7 @@ export default function DevelopersPage() { const totalEndpoints = GROUPS.reduce((n, g) => n + g.endpoints.length, 0); return ( -
+
+
+

{t("back")}

diff --git a/src/app/(site)/events/page.tsx b/src/app/(site)/events/page.tsx index 89f66a36..26e78e65 100644 --- a/src/app/(site)/events/page.tsx +++ b/src/app/(site)/events/page.tsx @@ -65,7 +65,7 @@ export default async function EventsPage() { })); return ( -
+
diff --git a/src/app/(site)/friends/page.tsx b/src/app/(site)/friends/page.tsx index 8376ca44..b88c2ac4 100644 --- a/src/app/(site)/friends/page.tsx +++ b/src/app/(site)/friends/page.tsx @@ -90,7 +90,7 @@ export default async function FriendsPage({ : null; return ( -
+
{removed === "1" ? (
{t("success.removed")} diff --git a/src/app/(site)/guilds/[id]/forum/[threadId]/page.tsx b/src/app/(site)/guilds/[id]/forum/[threadId]/page.tsx index f20b456b..fe0fb2c4 100644 --- a/src/app/(site)/guilds/[id]/forum/[threadId]/page.tsx +++ b/src/app/(site)/guilds/[id]/forum/[threadId]/page.tsx @@ -159,7 +159,7 @@ export default async function GuildForumThreadPage({ : null; return ( -
+
{replied === "1" ? (
{t("success.replied")} diff --git a/src/app/(site)/guilds/[id]/forum/new/page.tsx b/src/app/(site)/guilds/[id]/forum/new/page.tsx index 7fc66365..452d4bba 100644 --- a/src/app/(site)/guilds/[id]/forum/new/page.tsx +++ b/src/app/(site)/guilds/[id]/forum/new/page.tsx @@ -70,7 +70,7 @@ export default async function NewThreadPage({ : null; return ( -
+
{errorMessage ? (
{errorMessage} diff --git a/src/app/(site)/guilds/[id]/forum/page.tsx b/src/app/(site)/guilds/[id]/forum/page.tsx index ae4df681..04bc7532 100644 --- a/src/app/(site)/guilds/[id]/forum/page.tsx +++ b/src/app/(site)/guilds/[id]/forum/page.tsx @@ -120,7 +120,7 @@ export default async function GuildForumPage({ const usernameById = new Map(users.map((u) => [u.id, u.username])); return ( -
+
{posted === "1" ? (
{t("success.posted")} diff --git a/src/app/(site)/guilds/[id]/page.tsx b/src/app/(site)/guilds/[id]/page.tsx index ff595863..40ea33c1 100644 --- a/src/app/(site)/guilds/[id]/page.tsx +++ b/src/app/(site)/guilds/[id]/page.tsx @@ -125,7 +125,7 @@ export default async function GuildPage({ const created = formatDate(new Date(guild.dateCreated * 1000), "date"); return ( -
+

{t("allGuilds")}

diff --git a/src/app/(site)/guilds/page.tsx b/src/app/(site)/guilds/page.tsx index c1f80ddc..e7c9a7b4 100644 --- a/src/app/(site)/guilds/page.tsx +++ b/src/app/(site)/guilds/page.tsx @@ -36,7 +36,7 @@ export default async function GuildsPage() { const guilds = await getGuilds(); return ( -
+
diff --git a/src/app/(site)/help/[category]/page.tsx b/src/app/(site)/help/[category]/page.tsx index 65cb9e52..0114203c 100644 --- a/src/app/(site)/help/[category]/page.tsx +++ b/src/app/(site)/help/[category]/page.tsx @@ -103,7 +103,7 @@ export default async function HelpCategoryPage({ const hasButton = Boolean(cat.buttonText && cat.buttonText.trim() !== ""); return ( -
+

{t("back")}

diff --git a/src/app/(site)/help/page.tsx b/src/app/(site)/help/page.tsx index 7b758b5e..c8472e1e 100644 --- a/src/app/(site)/help/page.tsx +++ b/src/app/(site)/help/page.tsx @@ -112,7 +112,7 @@ export default async function HelpCenterPage() { } return ( -
+
+
{replied === "1" ? (
{t("success.replied")} diff --git a/src/app/(site)/help/tickets/page.tsx b/src/app/(site)/help/tickets/page.tsx index 1812f6ab..17f0667a 100644 --- a/src/app/(site)/help/tickets/page.tsx +++ b/src/app/(site)/help/tickets/page.tsx @@ -67,7 +67,7 @@ export default async function HelpTicketsPage({ : null; return ( -
+
{created === "1" ? (
{t("success.created")} diff --git a/src/app/(site)/leaderboard/page.tsx b/src/app/(site)/leaderboard/page.tsx index 77724944..ccc21b5f 100644 --- a/src/app/(site)/leaderboard/page.tsx +++ b/src/app/(site)/leaderboard/page.tsx @@ -142,7 +142,7 @@ export default async function LeaderboardPage({ : null; return ( -
+
{t("emptyState")} ) : ( - - - - - - - - - - - {rows.map((row, i) => { - return ( - - - - - + + + ); + })} + +
#{t("colAvatar")}{t("colPlayer")}{t(`tab_${active}`)}
- - - - - - {row.username} - - - {activeCurrency ? ( - + + + + + + + + + + + {rows.map((row, i) => { + return ( + + + + - - ); - })} - -
#{t("colAvatar")}{t("colPlayer")}{t(`tab_${active}`)}
+ + + + + - - {row.value.toLocaleString()} - - ) : ( - {formatValue(active, row.value)} - )} -
+ {row.username} + +
+ {activeCurrency ? ( + + + {row.value.toLocaleString()} + + ) : ( + {formatValue(active, row.value)} + )} +
+
)}
diff --git a/src/app/(site)/login/page.tsx b/src/app/(site)/login/page.tsx index 40bbb392..029916e1 100644 --- a/src/app/(site)/login/page.tsx +++ b/src/app/(site)/login/page.tsx @@ -2,14 +2,12 @@ import { count, desc, eq } from "drizzle-orm"; import { headers } from "next/headers"; import Image from "next/image"; import { getTranslations } from "next-intl/server"; +import { AuthTopBar } from "@/components/auth/auth-top-bar"; import { LoginForm } from "@/components/auth/login-form"; -import { Clock } from "@/components/clock"; -import { LanguageSwitcher } from "@/components/language-switcher"; import Link from "@/components/link"; import { Reveal } from "@/components/motion-reveal"; import { UserAvatarThumbnail } from "@/components/shared/user-avatar-thumbnail"; import { SurfaceCard } from "@/components/surface-card"; -import { ThemeSwitcher } from "@/components/theme-switcher"; import { cached } from "@/lib/cache"; import { db, User } from "@/lib/db"; import { resolveHotelName } from "@/lib/hotel-name"; @@ -50,74 +48,7 @@ export default async function LoginPage() { return (
- {/* ── Top Bar ── */} - -
-
- {logo ? ( - {hotelName} - ) : ( - {hotelName} - )} - - {hotelName} - -
-
- -
- -
- -
-
- +
diff --git a/src/app/(site)/marketplace/page.tsx b/src/app/(site)/marketplace/page.tsx index 540dd3b4..f0a1fb61 100644 --- a/src/app/(site)/marketplace/page.tsx +++ b/src/app/(site)/marketplace/page.tsx @@ -70,7 +70,7 @@ export default async function MarketplacePage() { const total = offers.reduce((sum, o) => sum + o.price, 0); return ( -
+
+
{accepted === "1" ? (
{t("success.accepted")} diff --git a/src/app/(site)/news/[...slug]/page.tsx b/src/app/(site)/news/[...slug]/page.tsx index 695c41e7..932c9d2e 100644 --- a/src/app/(site)/news/[...slug]/page.tsx +++ b/src/app/(site)/news/[...slug]/page.tsx @@ -194,7 +194,7 @@ export default async function ArticlePage({ : null; return ( -
+
{comment === "posted" ? (
{t("success.posted")} diff --git a/src/app/(site)/news/page.tsx b/src/app/(site)/news/page.tsx index ccee03a4..24c65940 100644 --- a/src/app/(site)/news/page.tsx +++ b/src/app/(site)/news/page.tsx @@ -14,7 +14,7 @@ export default async function NewsPage() { const articles = await getNewsList(30); return ( -
+
diff --git a/src/app/(site)/photos/page.tsx b/src/app/(site)/photos/page.tsx index 91c2f04b..f921d0f0 100644 --- a/src/app/(site)/photos/page.tsx +++ b/src/app/(site)/photos/page.tsx @@ -42,7 +42,7 @@ export default async function PhotosPage() { })); return ( -
+
diff --git a/src/app/(site)/polls/[id]/page.tsx b/src/app/(site)/polls/[id]/page.tsx index 1acbb61b..3c92de01 100644 --- a/src/app/(site)/polls/[id]/page.tsx +++ b/src/app/(site)/polls/[id]/page.tsx @@ -96,7 +96,7 @@ export default async function PollDetailPage({ } return ( -
+

{t("back")}

diff --git a/src/app/(site)/polls/page.tsx b/src/app/(site)/polls/page.tsx index 37a09b4e..71becaf0 100644 --- a/src/app/(site)/polls/page.tsx +++ b/src/app/(site)/polls/page.tsx @@ -48,7 +48,7 @@ export default async function PollsPage() { })); return ( -
+
diff --git a/src/app/(site)/radio/apply/page.tsx b/src/app/(site)/radio/apply/page.tsx index cfa66ed0..8a9fae1b 100644 --- a/src/app/(site)/radio/apply/page.tsx +++ b/src/app/(site)/radio/apply/page.tsx @@ -65,7 +65,7 @@ export default async function RadioApplyPage({ : null; return ( -
+
{submitted === "1" ? (
{t("success.submitted")} diff --git a/src/app/(site)/radio/contests/[id]/page.tsx b/src/app/(site)/radio/contests/[id]/page.tsx index df9bb32e..1a69893c 100644 --- a/src/app/(site)/radio/contests/[id]/page.tsx +++ b/src/app/(site)/radio/contests/[id]/page.tsx @@ -33,7 +33,7 @@ export default async function RadioContestDetailPage({ const active = contest.isActive ? "Active" : "Ended"; return ( -
+

← Back to contests

diff --git a/src/app/(site)/radio/contests/page.tsx b/src/app/(site)/radio/contests/page.tsx index c49cee23..bdbfb02e 100644 --- a/src/app/(site)/radio/contests/page.tsx +++ b/src/app/(site)/radio/contests/page.tsx @@ -23,7 +23,7 @@ export default async function RadioContestsPage() { .catch(() => []); return ( -
+
diff --git a/src/app/(site)/radio/giveaways/[id]/page.tsx b/src/app/(site)/radio/giveaways/[id]/page.tsx index 03561567..42cda4a7 100644 --- a/src/app/(site)/radio/giveaways/[id]/page.tsx +++ b/src/app/(site)/radio/giveaways/[id]/page.tsx @@ -38,7 +38,7 @@ export default async function RadioGiveawayDetailPage({ : null); return ( -
+

← Back to giveaways

diff --git a/src/app/(site)/radio/giveaways/page.tsx b/src/app/(site)/radio/giveaways/page.tsx index 6341b101..e41dab47 100644 --- a/src/app/(site)/radio/giveaways/page.tsx +++ b/src/app/(site)/radio/giveaways/page.tsx @@ -25,7 +25,7 @@ export default async function RadioGiveawaysPage() { .catch(() => []); return ( -
+
diff --git a/src/app/(site)/radio/leaderboard/page.tsx b/src/app/(site)/radio/leaderboard/page.tsx index e6821b0c..803a09cf 100644 --- a/src/app/(site)/radio/leaderboard/page.tsx +++ b/src/app/(site)/radio/leaderboard/page.tsx @@ -38,7 +38,7 @@ export default async function RadioLeaderboardPage() { const rows = await loadRows(); return ( -
+
diff --git a/src/app/(site)/radio/page.tsx b/src/app/(site)/radio/page.tsx index 0041e245..208c360f 100644 --- a/src/app/(site)/radio/page.tsx +++ b/src/app/(site)/radio/page.tsx @@ -105,7 +105,7 @@ export default async function RadioPage() { const isLive = Boolean(streamUrl); return ( -
+
{/* ── Header: live stream + now playing ─────────────────────── */} 0; return ( -
+
diff --git a/src/app/(site)/radio/shouts/page.tsx b/src/app/(site)/radio/shouts/page.tsx index d4c74309..92b6b573 100644 --- a/src/app/(site)/radio/shouts/page.tsx +++ b/src/app/(site)/radio/shouts/page.tsx @@ -73,7 +73,7 @@ export default async function RadioShoutsPage({ : null; return ( -
+
{posted === "1" ? (
{t("success.posted")} diff --git a/src/app/(site)/rankings/page.tsx b/src/app/(site)/rankings/page.tsx index 5c969182..4ae06ead 100644 --- a/src/app/(site)/rankings/page.tsx +++ b/src/app/(site)/rankings/page.tsx @@ -44,7 +44,7 @@ export default async function RankingsPage() { } return ( -
+
diff --git a/src/app/(site)/rares/[category]/page.tsx b/src/app/(site)/rares/[category]/page.tsx index fe6c687e..b06b65b3 100644 --- a/src/app/(site)/rares/[category]/page.tsx +++ b/src/app/(site)/rares/[category]/page.tsx @@ -96,7 +96,7 @@ export default async function RareCategoryPage({ badgeBase && cat.badge ? `${badgeBase}/${cat.badge}.gif` : ""; return ( -
+
+
{categories.length === 0 ? ( diff --git a/src/app/(site)/redeem/page.tsx b/src/app/(site)/redeem/page.tsx index 9d21d6a0..1780a8f2 100644 --- a/src/app/(site)/redeem/page.tsx +++ b/src/app/(site)/redeem/page.tsx @@ -29,7 +29,7 @@ export default async function RedeemPage() { if (!user) redirect("/login"); return ( -
+
diff --git a/src/app/(site)/register/page.tsx b/src/app/(site)/register/page.tsx index b0ee224e..7eb4742e 100644 --- a/src/app/(site)/register/page.tsx +++ b/src/app/(site)/register/page.tsx @@ -2,14 +2,12 @@ import { count, desc, eq } from "drizzle-orm"; import { headers } from "next/headers"; import Image from "next/image"; import { getTranslations } from "next-intl/server"; +import { AuthTopBar } from "@/components/auth/auth-top-bar"; import { RegisterForm } from "@/components/auth/register-form"; -import { Clock } from "@/components/clock"; -import { LanguageSwitcher } from "@/components/language-switcher"; import Link from "@/components/link"; import { Reveal } from "@/components/motion-reveal"; import { UserAvatarThumbnail } from "@/components/shared/user-avatar-thumbnail"; import { SurfaceCard } from "@/components/surface-card"; -import { ThemeSwitcher } from "@/components/theme-switcher"; import { cached } from "@/lib/cache"; import { db, User } from "@/lib/db"; import { resolveHotelName } from "@/lib/hotel-name"; @@ -51,74 +49,7 @@ export default async function RegisterPage() { return (
- {/* ── Top Bar ── */} - -
-
- {logo ? ( - {hotelName} - ) : ( - {hotelName} - )} - - {hotelName} - -
-
- -
- -
- -
-
- +
diff --git a/src/app/(site)/room/[id]/page.tsx b/src/app/(site)/room/[id]/page.tsx index 549fa7cd..995e1ad4 100644 --- a/src/app/(site)/room/[id]/page.tsx +++ b/src/app/(site)/room/[id]/page.tsx @@ -101,7 +101,7 @@ export default async function RoomPage({ .filter(Boolean); return ( -
+

← Back to the hotel diff --git a/src/app/(site)/settings/page.tsx b/src/app/(site)/settings/page.tsx index c57ac1d8..9c30dea7 100644 --- a/src/app/(site)/settings/page.tsx +++ b/src/app/(site)/settings/page.tsx @@ -44,7 +44,7 @@ export default async function SettingsPage() { const avatar = avatarImageUrl(user.look); return ( -

+
{/* Header */}
+
{signedOutAll === "1" ? (

+

{boughtMessage ? (
{boughtMessage} @@ -230,7 +230,7 @@ export default async function ShopPage({ borderRadius: "var(--radius-sm)", display: "grid", placeItems: "center", - background: "#f8fafc", + background: "var(--color-background)", border: `2px solid ${a.color || "var(--border-color)"}`, flexShrink: 0, overflow: "hidden", diff --git a/src/app/(site)/shop/topup/page.tsx b/src/app/(site)/shop/topup/page.tsx index 5119fb8a..b7904b9f 100644 --- a/src/app/(site)/shop/topup/page.tsx +++ b/src/app/(site)/shop/topup/page.tsx @@ -41,7 +41,7 @@ export default async function TopUpPage({ const rate = creditsPerUnit(); return ( -
+
{sp.status === "cancel" ? ( diff --git a/src/app/(site)/staff/page.tsx b/src/app/(site)/staff/page.tsx index effe5b02..83838c6c 100644 --- a/src/app/(site)/staff/page.tsx +++ b/src/app/(site)/staff/page.tsx @@ -57,7 +57,7 @@ export default async function StaffPage() { ]); return ( -
+
{teams.length > 0 ? ( @@ -96,26 +96,30 @@ export default async function StaffPage() { {staff.length === 0 ? ( {t("emptyState")} ) : ( - - - - - - - - - - {staff.map((u) => ( - - - - +
+
{t("colUsername")}{t("colRank")}{t("colMotto")}
- {u.username} - {u.rank}{u.motto || "—"}
+ + + + + - ))} - -
{t("colUsername")}{t("colRank")}{t("colMotto")}
+ + + {staff.map((u) => ( + + + {u.username} + + {u.rank} + + {u.motto || "—"} + + + ))} + + +
)}
diff --git a/src/app/(site)/u/[username]/page.tsx b/src/app/(site)/u/[username]/page.tsx index 299a119a..da3caf36 100644 --- a/src/app/(site)/u/[username]/page.tsx +++ b/src/app/(site)/u/[username]/page.tsx @@ -317,7 +317,7 @@ export default async function ProfilePage({ const authorById = new Map(authors.map((a) => [a.id, a])); return ( -
+
{friend === "sent" ? (
{t("success.sent")} diff --git a/src/app/globals.css b/src/app/globals.css index b46e4565..fd00b5cb 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1400,16 +1400,36 @@ a.content-card { } } +/* Rich content-page grid (replaces repeated inline `display:grid;gap:1.5rem`). */ +.page-grid { + display: grid; + gap: 1.5rem; +} + /* make tables scroll on small screens */ @media (max-width: 640px) { table { + display: table; + } + .table-scroll { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: var(--radius-sm); + -ms-overflow-style: none; + scrollbar-width: thin; } } +/* Cell text truncation helper for dense tables so long values (motto, URLs) + collapse gracefully instead of blowing out row width on small screens. */ +.table-cell-truncate { + max-width: 14rem; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + /* Safe-area insets for notched phones (header/nav/footer sit at screen edges) */ @supports (padding: max(0px)) { .site-header, diff --git a/src/components/auth/auth-top-bar.tsx b/src/components/auth/auth-top-bar.tsx new file mode 100644 index 00000000..3fe731a4 --- /dev/null +++ b/src/components/auth/auth-top-bar.tsx @@ -0,0 +1,95 @@ +import Image from "next/image"; +import { Clock } from "@/components/clock"; +import { LanguageSwitcher } from "@/components/language-switcher"; +import { Reveal } from "@/components/motion-reveal"; +import { ThemeSwitcher } from "@/components/theme-switcher"; + +/** + * Shared frosted-glass top bar for the public auth pages (login, register, + * etc.). Shows the hotel logo + name on the left and language / clock / theme + * controls on the right. Defaults mirror the homepage top bar so auth pages + * share one consistent look. + */ +export function AuthTopBar({ + hotelName, + logo, + showHotelName = true, +}: { + hotelName: string; + logo?: string | null; + showHotelName?: boolean; +}) { + return ( + +
+
+ {logo ? ( + {hotelName} + ) : ( + {hotelName} + )} + {showHotelName ? ( + + {hotelName} + + ) : null} +
+
+ +
+ +
+ +
+
+ + ); +}