style: apply consistent professional layout to login page
CI / check (push) Successful in 35s
CI / release (push) Skipped
CI / deploy (push) Successful in 52s

Reuse the SectionCard component to unify the neon section headers, center
the page in a max-w-6xl container, and give the welcome panel and login
card consistent rounded corners and subtle shadows, matching the home
and register pages.
This commit is contained in:
openhands committed 2026-08-27 15:32:32 +02:00
1 parent 9f0ee74ce8
commit 087dd7d873
1 file changed
+82 -168
+82 -168
View File
@@ -5,6 +5,7 @@ import Link from "next/link";
import { getTranslations } from "next-intl/server"; import { getTranslations } from "next-intl/server";
import { LoginForm } from "@/components/auth/login-form"; import { LoginForm } from "@/components/auth/login-form";
import { Clock } from "@/components/clock"; import { Clock } from "@/components/clock";
import { SectionCard } from "@/components/home-section";
import { LanguageSwitcher } from "@/components/language-switcher"; import { LanguageSwitcher } from "@/components/language-switcher";
import { Reveal } from "@/components/motion-reveal"; import { Reveal } from "@/components/motion-reveal";
import { UserAvatarThumbnail } from "@/components/shared/user-avatar-thumbnail"; import { UserAvatarThumbnail } from "@/components/shared/user-avatar-thumbnail";
@@ -48,7 +49,7 @@ export default async function LoginPage() {
]); ]);
return ( return (
<div className="flex flex-col gap-10 pb-14"> <div className="mx-auto w-full max-w-6xl flex flex-col gap-8 pb-16">
{/* ── Top Bar ── */} {/* ── Top Bar ── */}
<Reveal> <Reveal>
<div <div
@@ -117,16 +118,19 @@ export default async function LoginPage() {
</div> </div>
</div> </div>
</Reveal> </Reveal>
<Reveal> <Reveal>
<div className="flex flex-col lg:flex-row gap-10 stagger-children"> <div className="flex flex-col gap-8 lg:flex-row">
{/* Left panel */} {/* Left panel */}
<div className="lg:w-80 shrink-0 space-y-4"> <div className="lg:w-80 shrink-0 space-y-4">
<div <div
className="relative overflow-hidden rounded-2xl border p-6 text-center card-premium" className="relative overflow-hidden rounded-2xl border p-6 text-center"
style={{ style={{
borderColor: borderColor:
"color-mix(in srgb, var(--color-primary) 20%, transparent)", "color-mix(in srgb, var(--color-primary) 20%, transparent)",
background: `url(/assets/images/background.png) center/cover no-repeat`, background: `url(/assets/images/background.png) center/cover no-repeat`,
boxShadow:
"0 1px 2px color-mix(in srgb, var(--color-text-muted) 12%, transparent), 0 8px 24px -12px color-mix(in srgb, var(--color-text-muted) 25%, transparent)",
}} }}
> >
<div <div
@@ -147,7 +151,7 @@ export default async function LoginPage() {
priority priority
/> />
<div <div
className="inline-flex items-center gap-2 px-3.5 py-1 rounded-full text-xs font-bold uppercase tracking-wider mt-4 mb-3 border backdrop-blur-sm" className="inline-flex items-center gap-2 px-3.5 py-1 rounded-full text-xs font-bold uppercase tracking-wider mt-4 mb-3 border"
style={{ style={{
borderColor: borderColor:
"color-mix(in srgb, var(--color-primary) 18%, transparent)", "color-mix(in srgb, var(--color-primary) 18%, transparent)",
@@ -182,133 +186,71 @@ export default async function LoginPage() {
</div> </div>
{recentUsers.length > 0 && ( {recentUsers.length > 0 && (
<div <SectionCard
className="overflow-hidden rounded-xl border" title={th("online", { count: online, hotel: "" }).trim()}
style={{ icon="/assets/images/icons/navigation/goody.png"
borderColor: bodyClassName="p-4"
"color-mix(in srgb, var(--color-text-muted) 12%, transparent)",
}}
> >
<div <div className="grid grid-cols-4 gap-1.5">
className="flex items-center gap-2.5 px-4 py-3" {recentUsers.map((u) => (
style={{ <div
background: key={u.username}
"linear-gradient(140deg, #0A1F0A 0%, #0F2D0F 20%, #153C15 40%, #1B4A1B 60%, #205820 75%, #1A4A1A 90%, #143814 100%)", className="flex flex-col items-center gap-0.5 p-1.5 rounded-lg"
}} style={{
> background:
<Image "color-mix(in srgb, var(--color-primary) 4%, transparent)",
src="/assets/images/icons/navigation/goody.png" }}
alt="" >
width={18} <UserAvatarThumbnail
height={18} figure={u.look}
unoptimized alt=""
/> options={{ direction: 2 }}
<h3 className="rounded-md"
className="text-sm font-bold text-white" />
style={{ fontFamily: "var(--font-nunito)" }} <span
> className="text-[8px] font-bold truncate w-full text-center leading-tight"
{th("online", { count: online, hotel: "" }).trim()} style={{ color: "var(--color-text-readable)" }}
</h3>
</div>
<div
className="p-4"
style={{
background:
"color-mix(in srgb, var(--color-surface) 70%, transparent)",
}}
>
<div className="grid grid-cols-4 gap-1.5">
{recentUsers.map((u) => (
<div
key={u.username}
className="flex flex-col items-center gap-0.5 p-1.5 rounded-lg"
style={{
background:
"color-mix(in srgb, var(--color-primary) 4%, transparent)",
}}
> >
<UserAvatarThumbnail {u.username}
figure={u.look} </span>
alt="" </div>
options={{ direction: 2 }} ))}
className="rounded-md"
/>
<span
className="text-[8px] font-bold truncate w-full text-center leading-tight"
style={{ color: "var(--color-text-readable)" }}
>
{u.username}
</span>
</div>
))}
</div>
</div> </div>
</div> </SectionCard>
)} )}
{latestUsers.length > 0 && ( {latestUsers.length > 0 && (
<div <SectionCard
className="overflow-hidden rounded-xl border" title="Newest citizens"
style={{ icon="/assets/images/icons/friends.png"
borderColor: bodyClassName="p-4"
"color-mix(in srgb, var(--color-text-muted) 12%, transparent)",
}}
> >
<div <div className="grid grid-cols-4 gap-1.5">
className="flex items-center gap-2.5 px-4 py-3" {latestUsers.map((u) => (
style={{ <div
background: key={u.username}
"linear-gradient(140deg, #5a2d82 0%, #6b3a9e 20%, #7d47b8 40%, #8f54d0 60%, #7d47b8 75%, #6b3a9e 90%, #5a2d82 100%)", className="flex flex-col items-center gap-0.5 p-1.5 rounded-lg"
}} style={{
> background:
<Image "color-mix(in srgb, var(--color-primary) 4%, transparent)",
src="/assets/images/icons/friends.png" }}
alt="" >
width={18} <UserAvatarThumbnail
height={18} figure={u.look}
unoptimized alt=""
/> options={{ direction: 2 }}
<h3 className="rounded-md"
className="text-sm font-bold text-white" />
style={{ fontFamily: "var(--font-nunito)" }} <span
> className="text-[8px] font-bold truncate w-full text-center leading-tight"
Newest citizens style={{ color: "var(--color-text-readable)" }}
</h3>
</div>
<div
className="p-4"
style={{
background:
"color-mix(in srgb, var(--color-surface) 70%, transparent)",
}}
>
<div className="grid grid-cols-4 gap-1.5">
{latestUsers.map((u) => (
<div
key={u.username}
className="flex flex-col items-center gap-0.5 p-1.5 rounded-lg"
style={{
background:
"color-mix(in srgb, var(--color-primary) 4%, transparent)",
}}
> >
<UserAvatarThumbnail {u.username}
figure={u.look} </span>
alt="" </div>
options={{ direction: 2 }} ))}
className="rounded-md"
/>
<span
className="text-[8px] font-bold truncate w-full text-center leading-tight"
style={{ color: "var(--color-text-readable)" }}
>
{u.username}
</span>
</div>
))}
</div>
</div> </div>
</div> </SectionCard>
)} )}
<p <p
@@ -330,54 +272,26 @@ export default async function LoginPage() {
{/* Right: form */} {/* Right: form */}
<div className="flex-1"> <div className="flex-1">
<div <SectionCard
className="overflow-hidden rounded-xl border" title={t("title")}
style={{ icon="/assets/images/icons/navigation/me.png"
borderColor: bodyClassName="p-6"
"color-mix(in srgb, var(--color-text-muted) 12%, transparent)",
}}
> >
<div <p
className="flex items-center gap-2.5 px-4 py-3" className="text-sm mb-6"
style={{ style={{ color: "var(--color-text-muted)" }}
background: >
"linear-gradient(140deg, #1a3a5c 0%, #1e4a6e 20%, #2a5a80 40%, #3a6a90 60%, #4a7aa0 75%, #3a6a90 90%, #2a5a80 100%)", {t("subtitle")}
</p>
<LoginForm
captcha={{
provider: cfg.provider,
siteKey: cfg.siteKey || undefined,
field: cfg.field || undefined,
}} }}
> nonce={nonce}
<Image />
src="/assets/images/icons/navigation/me.png" </SectionCard>
alt=""
width={18}
height={18}
unoptimized
/>
<h2
className="text-sm font-bold text-white"
style={{ fontFamily: "var(--font-nunito)" }}
>
{t("title")}
</h2>
</div>
<div
className="p-6"
style={{ backgroundColor: "var(--color-surface)" }}
>
<p
className="text-sm mb-6"
style={{ color: "var(--color-text-muted)" }}
>
{t("subtitle")}
</p>
<LoginForm
captcha={{
provider: cfg.provider,
siteKey: cfg.siteKey || undefined,
field: cfg.field || undefined,
}}
nonce={nonce}
/>
</div>
</div>
</div> </div>
</div> </div>
</Reveal> </Reveal>