mirror of
https://github.com/hanzo-apps/waitlist.git
synced 2026-10-30 14:48:32 +00:00
Adds real social proof and a glossy depth pass on top of the existing
brand-neutral monochrome. Every new piece is configurable end-to-end.
Activity feed
• Mock-api: GET /v1/waitlist/activity?waitlist=&limit=&types= returning
most-recent events with a server-now timestamp so clients render
consistent relative times across clock skew. Ring-buffer last 200
events (env override: ACTIVITY_MAX_HISTORY). Cap on limit: 100
(env: ACTIVITY_LIMIT_CAP). Types filter (join,share,invite,referral)
is server-validated, unknown types silently dropped.
• join handler pushes a `join` event + a `referral` event when the
sender's refCode resolves. track-share pushes a `share` event the
same day-it-was-credited (skipped on duplicate same-day to match
the daily-cap economy). invite pushes one event per accepted email.
• Seeder synthesizes 30 backdated events on first boot so the ticker
is alive on first paint, not waiting on real traffic.
• Widget: <WaitlistActivity waitlist baseUrl limit types pollInterval
formatEvent formatRelative showHeading heading emptyLabel theme
className style /> — every visible knob is a prop. Polling interval
is configurable (0 disables, default 12s). Default formatter handles
copy/webshare/email/sms with natural copy ("copied their link",
"shared via system", "shared by email", "texted their link"); other
platforms get a clean platformLabel mapping (twitter→X, etc.).
Animated count-up
• useCountUp(target, { duration, ease, retrigger }) hook — 1200ms
cubic-out by default, honors prefers-reduced-motion, 0 disables.
• <WaitlistLeaderboard animateTotal={true | false | { duration }}/>
runs the count-up on the "N on the list" subtitle when the meta
first lands. Truly off-switchable.
Glossy aesthetic (all monochrome — no new color tokens)
• Cards: multi-layer shadow + a 1px inner highlight on the top edge
using inset color-mix(--hw-bg). Reads as real material without
breaking neutrality.
• Leaderboard rows: 6px radius, translateX(2px) on hover (skipped
under prefers-reduced-motion).
• Activity pulse: 8px accent dot with a soft expanding ring keyframe
(1.8s loop). Reduced-motion turns it off.
• Demo hero: subtle radial gradient halo via .section--glow::before
using color-mix(--fg 6%) to stay neutral. Disabled when the user
prefers reduced transparency.
• Topbar Join pill: inset top highlight + accentuated drop shadow
on hover for that glossy CTA look.
• Two-column board grid on desktop (leaderboard + Live activity),
stacks on <=880px.
• OpenGraph + Twitter card metadata on the demo for proper social
previews when someone tweets the page URL.
26 lines
720 B
TypeScript
26 lines
720 B
TypeScript
import './globals.css'
|
|
import '@hanzo/waitlist/styles.css'
|
|
|
|
export const metadata = {
|
|
title: 'Hanzo · Waitlist',
|
|
description: 'Reserve your spot. Climb the list. Refer friends, share, invite — every action earns points.',
|
|
openGraph: {
|
|
title: 'Hanzo · Waitlist',
|
|
description: 'Reserve your spot. Climb the list — every action earns points.',
|
|
type: 'website',
|
|
},
|
|
twitter: {
|
|
card: 'summary_large_image',
|
|
title: 'Hanzo · Waitlist',
|
|
description: 'Reserve your spot. Climb the list — every action earns points.',
|
|
},
|
|
}
|
|
|
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
return (
|
|
<html lang="en">
|
|
<body>{children}</body>
|
|
</html>
|
|
)
|
|
}
|