The site
How the page is put together, for anyone changing it.
The palette
The colors come from the Counter-Strike 2 menu rather than from crypto convention: a slate blue field, a greige inventory drawer, light blue for anything active, and the logo's yellow to orange for labels. Rarity colors are Steam's own. Everything is defined once in app/globals.css.
Page
--bg#222c3bBars and wells
--deep#151b25Inventory drawer
--drawer#4a4845Active
--hi#a8d0ffLabels
--gold#f5a623Cases
--case#e2b13cBase grade
--base-grade#b0c3d9Unlock button
--unlock#5c9a2bThe components
| File | What it does |
|---|---|
app/*/page.tsx | One server-rendered page per section, each revalidated on a timer. |
components/Depot.tsx | The canvas of crates. It picks its own zoom so the view widens as the reserve grows, and draws real case sprites when they are large enough to see. |
components/Unbox.tsx | The case-opening reel, driven by GSAP. Real skins at Steam's real odds, unlimited practice openings, a session haul, and a per-device total in local storage. |
components/CaseScene.tsx | The case in the hero, built in three.js: gold base, glass dome, a skin inside. Falls back to the Steam render without WebGL. |
components/RankLadder.tsx | The 18 competitive badges mapped to case milestones. |
app/docs/ | These pages. Same theme, same build, no separate deploy. |
The depot, the reel and the case scene are the only client components on the landing page. Everything else is known at build time and rendered on the server.
Running it locally
pnpm install
pnpm dev # http://localhost:3000
pnpm lint
pnpm build
Pages that read Steam are rendered on the server and cached for 30 minutes. Set RESERVE_STEAM_ID to read a real inventory; without it the reserve figures are samples.