120 lines
3.7 KiB
TypeScript
120 lines
3.7 KiB
TypeScript
|
|
import React from "react";
|
||
|
|
import { createRoot } from "react-dom/client";
|
||
|
|
import "./home.css";
|
||
|
|
|
||
|
|
const features = [
|
||
|
|
{
|
||
|
|
title: "Instant Sessions",
|
||
|
|
text: "Spin up a banker-led lobby, invite players with a code or QR, and launch the game in seconds.",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: "Real-Time Banking",
|
||
|
|
text: "Track balances, history, and transfers with live updates designed for fast tabletop play.",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: "Control the Chaos",
|
||
|
|
text: "Blackouts, forced transfers, and dummy players give the Banker full city authority.",
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
const steps = [
|
||
|
|
{
|
||
|
|
label: "Banker opens the vault",
|
||
|
|
detail: "Create a session, name the banker, and get the invite code instantly.",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
label: "Citizens join NegoCity",
|
||
|
|
detail: "Players join from their phones and the lobby updates in real time.",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
label: "Let the deals fly",
|
||
|
|
detail: "Transfers, chats, and group deals all flow through the app.",
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
function Home() {
|
||
|
|
return (
|
||
|
|
<div className="home">
|
||
|
|
<header className="hero reveal" style={{ "--delay": "0.05s" } as React.CSSProperties}>
|
||
|
|
<div className="hero__badge">Negopoly companion bank</div>
|
||
|
|
<div>
|
||
|
|
<h1>Welcome to NegoCity.</h1>
|
||
|
|
<p>
|
||
|
|
Negopoly is a Monopoly parody where every deal goes through the Bank of NegoCity. This
|
||
|
|
companion app keeps the money moving, the chats flowing, and the Banker in total
|
||
|
|
control.
|
||
|
|
</p>
|
||
|
|
<div className="hero__actions">
|
||
|
|
<a className="btn primary" href="/play">
|
||
|
|
Enter the bank
|
||
|
|
</a>
|
||
|
|
<a className="btn ghost" href="#how-it-works">
|
||
|
|
How it works
|
||
|
|
</a>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</header>
|
||
|
|
|
||
|
|
<section className="grid">
|
||
|
|
{features.map((feature, index) => (
|
||
|
|
<article
|
||
|
|
key={feature.title}
|
||
|
|
className="card reveal"
|
||
|
|
style={{ "--delay": `${0.1 + index * 0.1}s` } as React.CSSProperties}
|
||
|
|
>
|
||
|
|
<h3>{feature.title}</h3>
|
||
|
|
<p>{feature.text}</p>
|
||
|
|
</article>
|
||
|
|
))}
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section id="how-it-works" className="map">
|
||
|
|
<div
|
||
|
|
className="map__panel reveal"
|
||
|
|
style={{ "--delay": "0.2s" } as React.CSSProperties}
|
||
|
|
>
|
||
|
|
<div className="map__panel-content">
|
||
|
|
<span>Route map</span>
|
||
|
|
<h2>NegoCity money flow</h2>
|
||
|
|
<p>
|
||
|
|
Banker-driven sessions, private group chats, and live balance sync. Everything you
|
||
|
|
need for fast-paced tabletop finance.
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div className="map__legend">
|
||
|
|
<h2 className="section-title reveal" style={{ "--delay": "0.25s" } as React.CSSProperties}>
|
||
|
|
The game loop
|
||
|
|
</h2>
|
||
|
|
{steps.map((step, index) => (
|
||
|
|
<div
|
||
|
|
key={step.label}
|
||
|
|
className="legend-item reveal"
|
||
|
|
style={{ "--delay": `${0.3 + index * 0.1}s` } as React.CSSProperties}
|
||
|
|
>
|
||
|
|
<span className={`legend-dot ${index === 1 ? "orange" : index === 2 ? "sun" : ""}`} />
|
||
|
|
<div>
|
||
|
|
<div>{step.label}</div>
|
||
|
|
<span>{step.detail}</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<footer className="footer reveal" style={{ "--delay": "0.35s" } as React.CSSProperties}>
|
||
|
|
<div>
|
||
|
|
<strong>Ready for NegoCity?</strong>
|
||
|
|
<p>Make every deal official. Let the Banker run the show.</p>
|
||
|
|
</div>
|
||
|
|
<a className="btn primary" href="/play">
|
||
|
|
Start a session
|
||
|
|
</a>
|
||
|
|
</footer>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
const root = createRoot(document.getElementById("root")!);
|
||
|
|
root.render(<Home />);
|