feat: prioritize game iframe, gated register terms and polished register page

Fetch the Nitro client iframe with high priority so the browser starts the
game document before competing resources, and replace the bare /client
spinner with a branded boot screen. Preconnect and eager loading were already
in place; typing support for the iframe fetchPriority prop is added in a
React type augmentation.

Rework the register terms block into a single clickable accept control with
a custom check state, error shake and inline hint, and dim the submit button
until the terms are accepted. The register page gets labeled sections
(account details / credentials), a corrected banner overlay, translated
show/hide toggles and a captcha slot that reserves height to avoid layout
shifts. English is the source of truth; other locales fall back to it.
This commit is contained in:
openhands committed 2026-08-29 21:14:02 +02:00
1 parent 7f39ba4257
commit b59d6c21af
6 files changed
+374 -168

No files matched your search

+1
View File
@@ -383,6 +383,7 @@ export function ClientView({
allow="autoplay; gamepad; fullscreen"
referrerPolicy="no-referrer"
loading="eager"
fetchPriority={"high" as const}
/>
</div>
</>
+37 -5
View File
@@ -1,16 +1,48 @@
import Image from "next/image";
export default function ClientLoading() {
return (
<div
className="flex items-center justify-center min-h-screen"
style={{ background: "var(--color-background)" }}
className="relative flex items-center justify-center min-h-screen overflow-hidden"
style={{
background:
"radial-gradient(ellipse at center, color-mix(in srgb, var(--color-surface) 80%, transparent) 0%, var(--color-background) 75%)",
}}
>
<div
className="animate-spin w-10 h-10 border-4 rounded-full"
className="absolute inset-0 animate-pulse-glow"
style={{
borderColor: "var(--color-primary)",
borderTopColor: "transparent",
background:
"radial-gradient(circle at 50% 45%, color-mix(in srgb, var(--color-primary) 12%, transparent) 0%, transparent 55%)",
}}
/>
<div className="relative flex flex-col items-center gap-6">
<div
className="w-20 h-20 rounded-2xl flex items-center justify-center shadow-2xl"
style={{
background:
"linear-gradient(135deg, var(--color-primary) 0%, color-mix(in srgb, var(--color-primary) 70%, black) 100%)",
boxShadow:
"0 12px 40px color-mix(in srgb, var(--color-primary) 35%, transparent)",
}}
>
<Image
src="/assets/images/icons/lighthouse.png"
alt=""
width={44}
height={44}
unoptimized
/>
</div>
<div
className="animate-spin w-9 h-9 border-[3px] rounded-full"
style={{
borderColor:
"color-mix(in srgb, var(--color-text-muted) 18%, transparent)",
borderTopColor: "var(--color-primary)",
}}
/>
</div>
</div>
);
}
+22
View File
@@ -1701,6 +1701,28 @@ details[open] > summary .details-open\:rotate-180 {
.animate-pulse-glow {
animation: pulse-glow 2s ease-in-out infinite;
}
.animate-shake {
animation: shake 0.45s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}
@keyframes shake {
10%,
90% {
transform: translateX(-2px);
}
20%,
80% {
transform: translateX(4px);
}
30%,
50%,
70% {
transform: translateX(-6px);
}
40%,
60% {
transform: translateX(6px);
}
}
/* Glass morphism */
.glass {