TypeScript 97.6%
SQL 1.4%
JavaScript 0.5%
1import Link from "next/link";2import { ArrowRight, ShieldCheck, Sparkles, UserRound, Coins, Gamepad2, Clock, Ban } from "lucide-react";3import type { GameCard as GameCardData } from "@spinza/shared";4import { STARTING_BALANCE, formatSC } from "@spinza/shared";5import { Button } from "@/components/ui";6import { GameArt } from "./game-art";7import { GameRow } from "./game-card";8import { SiteFooter } from "./site-footer";910const FLAGSHIP = { slug: "spinza-original", name: "Spinza Original", palette: { primary: "#8b5cf6", secondary: "#22d3ee", glow: "#a78bfa", bg: "#06040f" } };1112const STEPS = [13 { icon: UserRound, title: "Pick a username", body: "That is the whole sign-up. No email address, no phone number, no card. A recovery code protects your account." },14 { icon: Coins, title: `Receive ${formatSC(STARTING_BALANCE)}`, body: "Every new player starts with 10,000 Spinza Credits. They are fictional, they refill daily and they can never be bought." },15 { icon: Gamepad2, title: "Play 20 original games", body: "Cascades, expanding wilds, hold-and-respin jackpots, meters and mystery symbols — all designed and built in-house." },16];1718export function Landing({ games, apiDown }: { games: GameCardData[]; apiDown: boolean }) {19 const flagship = games.find((g) => g.slug === FLAGSHIP.slug);20 const featured = games.filter((g) => g.isFeatured);21 const featuredRow = (featured.length ? featured : games).slice(0, 10);2223 return (24 <div className="page py-6 lg:py-10">25 {/* ----------------------------------------------------------- hero */}26 <section className="relative overflow-hidden rounded-xl border border-line bg-bg-1" aria-labelledby="hero-title">27 <div className="absolute inset-0">28 <GameArt slug={FLAGSHIP.slug} name={FLAGSHIP.name} palette={flagship?.palette ?? FLAGSHIP.palette} variant="hero" showName={false} className="opacity-90" />29 <div className="absolute inset-0 bg-[linear-gradient(90deg,rgba(7,8,12,0.94)_0%,rgba(7,8,12,0.78)_45%,rgba(7,8,12,0.25)_100%)]" />30 <div className="absolute inset-x-0 bottom-0 h-1/2 bg-[linear-gradient(180deg,transparent,rgba(7,8,12,0.9))]" />31 </div>32 <div className="relative flex min-h-[520px] flex-col justify-end p-6 sm:min-h-[580px] sm:p-10 lg:min-h-[640px] lg:p-14">33 <div className="eyebrow mb-4 flex items-center gap-2 text-accent">34 <Sparkles className="h-3.5 w-3.5" /> Spinza Original · Fictional credits35 </div>36 <h1 id="hero-title" className="max-w-3xl text-[44px] font-semibold leading-[0.95] tracking-[-0.04em] sm:text-6xl lg:text-7xl">37 Play. <span className="shimmer-text">Spin.</span> Unlock.38 </h1>39 <p className="mt-5 max-w-xl text-base leading-relaxed text-fg-2 sm:text-lg">Twenty original casino-style games, a premium lobby and a living progression system — played entirely with fictional credits. Nothing to buy, nothing to lose.</p>40 <div className="mt-8 flex flex-col gap-3 sm:flex-row">41 <Button variant="accent" size="xl" href="/register" className="sm:min-w-[200px]">42 PLAY FREE43 </Button>44 <Button variant="outline" size="xl" href="/games" className="glass sm:min-w-[200px]">45 EXPLORE GAMES <ArrowRight className="h-4 w-4" />46 </Button>47 </div>48 <p className="mt-6 max-w-xl text-[13px] leading-relaxed text-fg-3">49 <span className="font-semibold text-fg-2">Virtual credits only. No deposits. No withdrawals. No cash value.</span> Spinza is for adults 18 and over. Already have an account?{" "}50 <Link href="/login" className="text-accent-2 underline-offset-4 hover:underline">51 Sign in52 </Link>53 .54 </p>55 </div>56 </section>5758 {/* -------------------------------------------------- how it works */}59 <section className="mt-16 lg:mt-24" aria-labelledby="how-title">60 <div className="mb-8 max-w-2xl">61 <div className="eyebrow mb-2">How it works</div>62 <h2 id="how-title" className="text-3xl font-semibold tracking-tight sm:text-4xl">63 Three steps. Zero friction.64 </h2>65 </div>66 <ol className="grid gap-4 md:grid-cols-3">67 {STEPS.map((s, i) => (68 <li key={s.title} className="surface relative rounded-lg p-6">69 <div className="flex items-center justify-between">70 <span className="grid h-11 w-11 place-items-center rounded-md metal text-accent-2">71 <s.icon className="h-5 w-5" />72 </span>73 <span className="font-mono text-sm text-fg-4">0{i + 1}</span>74 </div>75 <h3 className="mt-5 text-lg font-semibold tracking-tight">{s.title}</h3>76 <p className="mt-2 text-sm leading-relaxed text-fg-3">{s.body}</p>77 </li>78 ))}79 </ol>80 <div className="mt-6">81 <Link href="/how-it-works" className="tap inline-flex h-10 min-h-0 items-center gap-1 text-sm font-medium text-fg-2 hover:text-fg">82 Read the full guide <ArrowRight className="h-4 w-4" />83 </Link>84 </div>85 </section>8687 {/* ----------------------------------------------------- featured */}88 <section className="mt-16 lg:mt-24" aria-labelledby="featured-title">89 {featuredRow.length ? (90 <GameRow id="featured" title="Featured games" eyebrow="Tonight in the lobby" games={featuredRow} href="/games" />91 ) : (92 <div className="surface rounded-lg p-8 text-center">93 <div className="eyebrow mb-2">Featured games</div>94 <h2 id="featured-title" className="text-xl font-semibold tracking-tight">95 {apiDown ? "The lobby is warming up." : "New titles are being certified."}96 </h2>97 <p className="mx-auto mt-2 max-w-md text-sm text-fg-3">{apiDown ? "We could not reach the game service right now. Refresh in a moment — your credits and progress are safe." : "Every Spinza game is verified against its published math before it opens. Check back soon."}</p>98 </div>99 )}100 </section>101102 {/* ------------------------------------------------- originals */}103 <section className="mt-16 grid gap-6 lg:mt-24 lg:grid-cols-[1.1fr_0.9fr]" aria-labelledby="originals-title">104 <div className="surface relative overflow-hidden rounded-xl p-8 sm:p-10">105 <div className="eyebrow mb-3">Original games</div>106 <h2 id="originals-title" className="text-3xl font-semibold tracking-tight sm:text-4xl">107 Built from scratch. Every reel, every rule.108 </h2>109 <p className="mt-4 max-w-lg text-[15px] leading-relaxed text-fg-2">Spinza games are not clones. Each title is designed in-house with its own symbol set, math model, feature logic and artwork — from the tumbling multipliers of Cosmic Collapse to the hold-and-respin vault of Diamond Heist. Every game is simulated across millions of rounds and certified against its published math before it reaches the lobby.</p>110 <ul className="mt-6 grid gap-2 text-sm text-fg-2 sm:grid-cols-2">111 {["Provably consistent math", "Original artwork and symbols", "Transparent Game Info on every title", "Fair, server-side outcomes"].map((t) => (112 <li key={t} className="flex items-center gap-2">113 <ShieldCheck className="h-4 w-4 text-accent" /> {t}114 </li>115 ))}116 </ul>117 </div>118 <div className="grid gap-4">119 <div className="surface rounded-xl p-8">120 <div className="flex items-center gap-2 text-accent">121 <Coins className="h-5 w-5" />122 <h3 className="text-lg font-semibold tracking-tight text-fg">What are Spinza Credits?</h3>123 </div>124 <p className="mt-3 text-sm leading-relaxed text-fg-2">Spinza Credits (SC) are a fictional currency that exists only inside Spinza. They have no monetary value and cannot be bought, sold, transferred, withdrawn or exchanged for anything. Run low and they refill through daily rewards, missions, level-ups and rescue credits — always for free.</p>125 <div className="mt-4 flex flex-wrap gap-2 text-[12px] font-semibold text-fg-3">126 {["No purchases", "No withdrawals", "No prizes", "No cash value"].map((t) => (127 <span key={t} className="inline-flex items-center gap-1 rounded-full border border-line px-2.5 py-1">128 <Ban className="h-3 w-3" /> {t}129 </span>130 ))}131 </div>132 </div>133 <div className="surface rounded-xl p-8">134 <div className="flex items-center gap-2 text-accent">135 <Clock className="h-5 w-5" />136 <h3 className="text-lg font-semibold tracking-tight text-fg">Play responsibly</h3>137 </div>138 <p className="mt-3 text-sm leading-relaxed text-fg-2">Even with fictional credits, time matters. Spinza includes session reminders, break prompts, animation controls and an opt-out for leaderboards. Spinza is for adults 18 and over.</p>139 <Link href="/responsible-play" className="tap mt-3 inline-flex h-10 min-h-0 items-center gap-1 text-sm font-medium text-accent-2 hover:underline">140 Responsible play tools <ArrowRight className="h-4 w-4" />141 </Link>142 </div>143 </div>144 </section>145146 {/* -------------------------------------------------------- CTA */}147 <section className="mt-16 rounded-xl border border-accent/25 bg-[radial-gradient(ellipse_at_top,rgba(201,169,97,0.16),transparent_60%)] p-8 text-center sm:p-12 lg:mt-24">148 <h2 className="text-3xl font-semibold tracking-tight sm:text-4xl">Your first {formatSC(STARTING_BALANCE)} are waiting.</h2>149 <p className="mx-auto mt-3 max-w-md text-sm text-fg-2">Create a username, save your recovery code, and you are in the lobby in under a minute.</p>150 <div className="mt-6 flex flex-col justify-center gap-3 sm:flex-row">151 <Button variant="accent" size="lg" href="/register">152 PLAY FREE153 </Button>154 <Button variant="ghost" size="lg" href="/login">155 Sign in156 </Button>157 </div>158 </section>159160 <SiteFooter className="mt-16 lg:mt-24" />161 </div>162 );163}164