style(landing): polish the public index, login and register screens
Gitea Actions Runner Test / test-job (push) Successful in 1s
CI / check (push) Failing after 26s
CI / tests-unit (push) Skipped
CI / tests-integration (push) Skipped
CI / tests-ui (push) Skipped
CI / preflight (push) Skipped
CI / deploy (push) Skipped

- add theme-aware helpers: btn-brand, btn-glass-dark, auth-input, auth-label,
  auth-alert, explore-pill, avatar-tile, aurora blobs and a hero scroll cue
- reorder backdrop-filter declarations so the glass blur survives the
  production CSS optimizer in modern Chromium
- hero: aurora glow, frosted recent-users chip, premium CTA buttons and cue
- explore nav: icon pills with hover arrows; features: gradient icon tiles
- stats: single glass panel with column dividers; join CTA: aurora + ring
- auth forms: visible labels, icon inputs, eye/password toggle, gradient
  submit and pill footer links
- auth pages: gradient card frame, aurora accents on the intro panel and
  hover-lift avatar tiles; unified pill-shaped top bar
- drop the hard-coded register banner image in favor of the framed card
This commit is contained in:
openhands committed 2026-10-06 22:00:02 +02:00
1 parent 5b2eb91c5c
commit 57710a7fe3
8 files changed
+879 -521

No files matched your search

+65 -56
View File
@@ -72,6 +72,21 @@ export default async function LoginPage() {
className="absolute inset-0 overflow-hidden"
>
<div className="brand-halo left-1/2 top-0 h-64 w-[460px] max-w-full -translate-x-1/2 -translate-y-1/2" />
<div
className="aurora-blob -left-16 top-10 h-56 w-56"
style={{
background:
"color-mix(in srgb, var(--color-primary) 45%, transparent)",
}}
/>
<div
className="aurora-blob -right-16 bottom-0 h-56 w-56"
style={{
background:
"color-mix(in srgb, var(--color-accent) 40%, transparent)",
animationDelay: "-8s",
}}
/>
</div>
<div className="relative">
<div className="brand-halo left-1/2 top-8 h-52 w-52 -translate-x-1/2" />
@@ -88,16 +103,24 @@ export default async function LoginPage() {
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={{
borderColor:
"color-mix(in srgb, var(--color-primary) 18%, transparent)",
"color-mix(in srgb, var(--color-primary) 30%, transparent)",
background:
"color-mix(in srgb, var(--color-primary) 10%, transparent)",
"color-mix(in srgb, var(--color-surface) 72%, transparent)",
color:
"var(--color-primary-readable, var(--color-primary))",
boxShadow:
"0 8px 20px -12px color-mix(in srgb, var(--color-primary) 70%, transparent)",
}}
>
<span className="relative flex h-2 w-2">
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75" />
<span className="relative inline-flex rounded-full h-2 w-2 bg-primary" />
<span
className="animate-ping absolute inline-flex h-full w-full rounded-full opacity-75"
style={{ background: "var(--color-primary)" }}
/>
<span
className="relative inline-flex rounded-full h-2 w-2"
style={{ background: "var(--color-primary)" }}
/>
</span>
{t("usersOnline", { count: online })}
</div>
@@ -111,7 +134,7 @@ export default async function LoginPage() {
{t("welcomeBack")}
</h1>
<p
className="text-xs mt-1 mx-auto max-w-[200px] leading-relaxed"
className="text-xs mt-1.5 mx-auto max-w-[220px] leading-relaxed"
style={{ color: "var(--color-text-muted)" }}
>
{t("welcomeBackSub", { hotelName })}
@@ -130,26 +153,19 @@ export default async function LoginPage() {
{recentUsers.map((u) => (
<div
key={u.username}
className="flex flex-col items-center gap-1.5 rounded-xl border px-1 py-2 transition-all duration-200 hover:-translate-y-0.5 hover:ring-1 hover:ring-[color-mix(in_srgb,var(--color-primary)_35%,transparent)]"
style={{
background:
"color-mix(in srgb, var(--color-primary) 4%, transparent)",
borderColor:
"color-mix(in srgb, var(--color-primary) 10%, transparent)",
}}
title={u.username}
className="avatar-tile"
>
<UserAvatarThumbnail
figure={u.look}
alt=""
options={{ direction: 2 }}
className="rounded-lg"
/>
<span
className="w-full truncate text-center text-[9px] font-bold leading-tight"
style={{ color: "var(--color-text-readable)" }}
>
{u.username}
</span>
<div className="relative">
<UserAvatarThumbnail
figure={u.look}
alt=""
options={{ direction: 2 }}
className="rounded-lg"
/>
<span className="avatar-online absolute -bottom-0.5 -right-0.5" />
</div>
<span className="avatar-name">{u.username}</span>
</div>
))}
</div>
@@ -167,13 +183,8 @@ export default async function LoginPage() {
{latestUsers.map((u) => (
<div
key={u.username}
className="flex flex-col items-center gap-1.5 rounded-xl border px-1 py-2 transition-all duration-200 hover:-translate-y-0.5 hover:ring-1 hover:ring-[color-mix(in_srgb,var(--color-primary)_35%,transparent)]"
style={{
background:
"color-mix(in srgb, var(--color-primary) 4%, transparent)",
borderColor:
"color-mix(in srgb, var(--color-primary) 10%, transparent)",
}}
title={u.username}
className="avatar-tile"
>
<UserAvatarThumbnail
figure={u.look}
@@ -181,12 +192,7 @@ export default async function LoginPage() {
options={{ direction: 2 }}
className="rounded-lg"
/>
<span
className="w-full truncate text-center text-[9px] font-bold leading-tight"
style={{ color: "var(--color-text-readable)" }}
>
{u.username}
</span>
<span className="avatar-name">{u.username}</span>
</div>
))}
</div>
@@ -196,26 +202,29 @@ export default async function LoginPage() {
{/* Right: form */}
<div className="flex-1 lg:sticky lg:top-6">
<SurfaceCard
title={t("title")}
icon={ICON_NAV_ME}
bodyClassName="p-6 sm:p-7"
>
<p
className="text-sm mb-6"
style={{ color: "var(--color-text-muted)" }}
<div className="gradient-border">
<SurfaceCard
title={t("title")}
icon={ICON_NAV_ME}
bodyClassName="p-6 sm:p-7"
className="card-glow"
>
{t("subtitle")}
</p>
<LoginForm
captcha={{
provider: cfg.provider,
siteKey: cfg.siteKey || undefined,
field: cfg.field || undefined,
}}
nonce={nonce}
/>
</SurfaceCard>
<p
className="text-sm mb-6 leading-relaxed"
style={{ color: "var(--color-text-muted)" }}
>
{t("subtitle")}
</p>
<LoginForm
captcha={{
provider: cfg.provider,
siteKey: cfg.siteKey || undefined,
field: cfg.field || undefined,
}}
nonce={nonce}
/>
</SurfaceCard>
</div>
</div>
</div>
</Reveal>