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

+62 -55
View File
@@ -82,6 +82,21 @@ export default async function RegisterPage() {
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-6 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="flex items-center gap-4">
@@ -102,16 +117,24 @@ export default async function RegisterPage() {
className="inline-flex items-center gap-2 px-3 py-1 rounded-full text-xs font-bold uppercase tracking-wider mb-2 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>
{tpr("usersOnline", { count: online })}
</div>
@@ -148,26 +171,18 @@ export default async function RegisterPage() {
<div
key={u.username}
title={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)",
}}
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>
@@ -186,13 +201,7 @@ export default async function RegisterPage() {
<div
key={u.username}
title={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)",
}}
className="avatar-tile"
>
<UserAvatarThumbnail
figure={u.look}
@@ -200,12 +209,7 @@ export default async function RegisterPage() {
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>
@@ -215,26 +219,29 @@ export default async function RegisterPage() {
{/* Right: form */}
<div className="flex-1 lg:sticky lg:top-6">
<SurfaceCard
title={tpr("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={tpr("title")}
icon={ICON_NAV_ME}
bodyClassName="p-6 sm:p-7"
className="card-glow"
>
{tpr("subtitle")}
</p>
<RegisterForm
hotelName={hotelName}
captcha={{
provider: cfg.provider,
siteKey: cfg.siteKey || undefined,
}}
nonce={nonce}
/>
</SurfaceCard>
<p
className="text-sm mb-6 leading-relaxed"
style={{ color: "var(--color-text-muted)" }}
>
{tpr("subtitle")}
</p>
<RegisterForm
hotelName={hotelName}
captcha={{
provider: cfg.provider,
siteKey: cfg.siteKey || undefined,
}}
nonce={nonce}
/>
</SurfaceCard>
</div>
</div>
</div>
</Reveal>