Skip to content

Commit ae5b182

Browse files
committed
refactor: update loading and home-hero components for improved text rendering and visual consistency
1 parent 8d03f9c commit ae5b182

File tree

2 files changed

+65
-63
lines changed

2 files changed

+65
-63
lines changed

app/loading.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@ export default function Loading() {
66
<div className="container mx-auto my-auto flex items-center justify-center px-4 py-8">
77
<div className="w-full space-y-6">
88
{/* Hero */}
9-
<div className="flex w-full flex-col items-center justify-center gap-y-2 sm:flex-row sm:items-baseline sm:gap-y-0">
10-
<h1 className="flex w-full flex-col items-center justify-center gap-y-2 text-center font-semibold text-3xl leading-none tracking-tight sm:flex-row sm:items-baseline sm:gap-y-0 sm:text-4xl md:text-5xl">
11-
<span className="whitespace-nowrap text-foreground/90">
12-
Inspect any domain's
9+
<h1 className="flex w-full flex-col items-center justify-center gap-y-2 text-center font-semibold text-3xl leading-none tracking-tight sm:flex-row sm:items-baseline sm:gap-y-0 sm:text-4xl md:text-5xl">
10+
<span className="whitespace-nowrap text-foreground/90">
11+
Inspect any domain&rsquo;s
12+
</span>
13+
<span className="ml-2.5 inline-flex items-center rounded-lg bg-muted/70 px-2 py-0.5 text-foreground shadow-sm ring-1 ring-border/60 backdrop-blur supports-[backdrop-filter]:backdrop-blur-md sm:rounded-xl sm:px-3 sm:py-1">
14+
<span className="relative flex h-[1.15em] w-full items-center overflow-hidden whitespace-nowrap">
15+
<span className="inline-block">registration</span>
1316
</span>
14-
<span className="ml-2.5 inline-flex items-center rounded-lg bg-muted/70 px-2 py-0.5 text-foreground shadow-sm ring-1 ring-border/60 backdrop-blur supports-[backdrop-filter]:backdrop-blur-md sm:rounded-xl sm:px-3 sm:py-1">
15-
registration
16-
</span>
17-
<span className="hidden whitespace-nowrap text-foreground/90 sm:inline">
18-
.
19-
</span>
20-
</h1>
21-
</div>
17+
</span>
18+
<span className="hidden whitespace-nowrap text-foreground/90 sm:inline">
19+
.
20+
</span>
21+
</h1>
2222

2323
{/* Search section skeleton */}
2424
<div className="mx-auto w-full max-w-3xl space-y-5">

components/home-hero.tsx

Lines changed: 53 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { AnimatePresence, motion } from "motion/react";
44
import { useEffect, useLayoutEffect, useRef, useState } from "react";
5+
import { cn } from "@/lib/utils";
56

67
type HomeHeroProps = {
78
words?: string[];
@@ -51,59 +52,60 @@ export function HomeHero({ intervalMs = 2400, className }: HomeHeroProps) {
5152
// Width updates are driven by ResizeObserver measuring the hidden mirror node
5253

5354
return (
54-
<div className={className}>
55-
<h1 className="flex w-full flex-col items-center justify-center gap-y-2 text-center font-semibold text-3xl leading-none tracking-tight sm:flex-row sm:items-baseline sm:gap-y-0 sm:text-4xl md:text-5xl">
56-
<span className="whitespace-nowrap text-foreground/90">
57-
Inspect any domain’s
58-
</span>
59-
<motion.span
60-
className="ml-2.5 inline-flex items-center rounded-lg bg-muted/70 px-2 py-0.5 text-foreground shadow-sm ring-1 ring-border/60 backdrop-blur supports-[backdrop-filter]:backdrop-blur-md sm:rounded-xl sm:px-3 sm:py-1"
61-
aria-live="polite"
62-
aria-atomic="true"
63-
initial={false}
64-
animate={{ width: measuredWidth ?? undefined }}
65-
transition={{ duration: 0.85, ease: [0.22, 1, 0.36, 1] }}
66-
style={{ willChange: "width", width: measuredWidth ?? undefined }}
67-
>
68-
<span className="relative flex h-[1.15em] w-full items-center overflow-hidden whitespace-nowrap">
69-
<span className="-translate-x-1/2 absolute left-1/2">
70-
<AnimatePresence mode="wait" initial={false}>
71-
<motion.span
72-
key={rotatingWords[index]}
73-
initial={{ y: "100%", opacity: 0, x: 0 }}
74-
animate={{ y: 0, opacity: 1, x: 0 }}
75-
exit={{ y: "-100%", opacity: 0, x: 0 }}
76-
transition={{
77-
type: "tween",
78-
ease: [0.22, 1, 0.36, 1],
79-
duration: 0.5,
80-
}}
81-
className="inline-block transform-gpu will-change-transform"
82-
>
83-
{rotatingWords[index]}
84-
</motion.span>
85-
</AnimatePresence>
86-
</span>
87-
{/* in-flow baseline shim so the pill aligns with surrounding text baseline */}
88-
<span className="invisible select-none">
89-
{rotatingWords[index]}
90-
</span>
91-
</span>
92-
</motion.span>
93-
{/* measurement element for smooth width animation (inherits h1 font sizing) */}
94-
<span
95-
ref={measureRef}
96-
className="pointer-events-none invisible absolute inline-flex items-center rounded-lg bg-muted/70 px-2 py-0.5 align-baseline text-foreground shadow-sm ring-1 ring-border/60 sm:rounded-xl sm:px-3 sm:py-1"
97-
aria-hidden="true"
98-
>
99-
<span className="inline-flex items-center whitespace-nowrap">
100-
{rotatingWords[index]}
55+
<h1
56+
className={cn(
57+
"flex w-full flex-col items-center justify-center gap-y-2 text-center font-semibold text-3xl leading-none tracking-tight sm:flex-row sm:items-baseline sm:gap-y-0 sm:text-4xl md:text-5xl",
58+
className,
59+
)}
60+
>
61+
<span className="whitespace-nowrap text-foreground/90">
62+
Inspect any domain&rsquo;s
63+
</span>
64+
<motion.span
65+
className="ml-2.5 inline-flex items-center rounded-lg bg-muted/70 px-2 py-0.5 text-foreground shadow-sm ring-1 ring-border/60 backdrop-blur supports-[backdrop-filter]:backdrop-blur-md sm:rounded-xl sm:px-3 sm:py-1"
66+
aria-live="polite"
67+
aria-atomic="true"
68+
initial={false}
69+
animate={{ width: measuredWidth ?? undefined }}
70+
transition={{ duration: 0.85, ease: [0.22, 1, 0.36, 1] }}
71+
style={{ willChange: "width", width: measuredWidth ?? undefined }}
72+
>
73+
<span className="relative flex h-[1.15em] w-full items-center overflow-hidden whitespace-nowrap">
74+
<span className="-translate-x-1/2 absolute left-1/2">
75+
<AnimatePresence mode="wait" initial={false}>
76+
<motion.span
77+
key={rotatingWords[index]}
78+
initial={{ y: "100%", opacity: 0, x: 0 }}
79+
animate={{ y: 0, opacity: 1, x: 0 }}
80+
exit={{ y: "-100%", opacity: 0, x: 0 }}
81+
transition={{
82+
type: "tween",
83+
ease: [0.22, 1, 0.36, 1],
84+
duration: 0.5,
85+
}}
86+
className="inline-block transform-gpu will-change-transform"
87+
>
88+
{rotatingWords[index]}
89+
</motion.span>
90+
</AnimatePresence>
10191
</span>
92+
{/* in-flow baseline shim so the pill aligns with surrounding text baseline */}
93+
<span className="invisible select-none">{rotatingWords[index]}</span>
10294
</span>
103-
<span className="hidden whitespace-nowrap text-foreground/90 sm:inline">
104-
.
95+
</motion.span>
96+
{/* measurement element for smooth width animation (inherits h1 font sizing) */}
97+
<span
98+
ref={measureRef}
99+
className="pointer-events-none invisible absolute inline-flex items-center rounded-lg bg-muted/70 px-2 py-0.5 align-baseline text-foreground shadow-sm ring-1 ring-border/60 sm:rounded-xl sm:px-3 sm:py-1"
100+
aria-hidden="true"
101+
>
102+
<span className="inline-flex items-center whitespace-nowrap">
103+
{rotatingWords[index]}
105104
</span>
106-
</h1>
107-
</div>
105+
</span>
106+
<span className="hidden whitespace-nowrap text-foreground/90 sm:inline">
107+
.
108+
</span>
109+
</h1>
108110
);
109111
}

0 commit comments

Comments
 (0)