Systems

major system

Cryptogrator

B2B casino platform site in React 19, procedural Three.js, and Web Audio

I built Cryptogrator's public site from the ground up. A roulette world made in Three.js carries the sales story, and it adapts to phones, weak GPUs, and reduced motion.

scale
849 source files, about 46.9K lines. The wheel scene alone is 2,200+ lines of code that builds the table, façade, light, and camera.
latency
The wheel loads after hydration, caps pixel ratio, and picks a render tier per device. Poster frames show until WebGL is ready.
reliability
Reduced-motion and low-power devices get composed still poses. The renderer and scene dispose cleanly.
automation
Scripts prepare provider marks and image derivatives. Demo requests are validated, honeypot-checked, rate-limited, and sent through Resend.
Full walkthrough recorded on the live site, from the entry ritual to the footer.
0:00 / 0:00
Context

Problem had shape before code did.

A B2B site for a white-label crypto casino platform. A roulette world shows the craft; the scroll then walks operators through product, payments, games, brands, launch, and compliance.

  • Built the roulette table and casino world procedurally in Three.js, so light, materials, and camera stay editable in code.
  • Tied the camera to the site's single Lenis scroll signal. No second animation loop, no ScrollTrigger.
  • Added a full fallback ladder: client-only hydration, desktop and phone poses, quality tiers, reduced motion, and poster frames.
  • Synthesized the lounge ambience and wheel strikes with the Web Audio API, behind a sound toggle.
Rendering
Content, navigation, and the demo form work before or without WebGL.
Motion
The scene follows the page's scroll signal. It never owns scrolling.
Audio
Sound is opt-in and never needed to understand the page.
Build

Structure had to survive job.

  • React 19 and strict TypeScript on Vinext/Vite/Nitro, with Tailwind CSS 4 and Zustand.
  • Feature-Sliced layers keep the Three.js scene inside one entity, so rendering never leaks into page code.
  • One shared transmission feeds Lenis progress to the camera, which moves between named desktop and phone poses.
  • The demo request is a server action: schema validation, a honeypot, a rate limit, and Resend. Nothing is stored.
The site needs a real 3D scene without turning every route into a WebGL app. Isolating the scene, mounting it after hydration, and feeding it the existing scroll signal keeps the rest of the page fast and semantic.
Working stack

React 19 / TypeScript (strict) / Bun 1.3 / Vinext / Vite / Nitro / Tailwind CSS 4 / Three.js / GSAP + Lenis / Zustand / Web Audio API / Resend

Evidence

Browser becomes part of argument.

Evidence viewerKeyboard arrows change proof

01 / 22Hero: the live Three.js roulette table.

Decisions

Small cuts make system trustworthy.

  • The scene builds geometry, canvas textures, lights, reflections, and camera states in code. Nothing is baked.
  • High and low render tiers, a DPR cap, SMAA on weak devices, and shader warm-up keep frames steady.
  • Audio is synthesized in the browser: no files, a lounge bed, and wheel sounds timed to the scene.
Pressure

What resisted, broke, stayed expensive.

Constraints in motion

  • Make the centerpiece feel like a physical product inside a marketing-page budget.
  • Let scroll-linked camera moves support reading, not fight Lenis.
  • Give weak GPUs, phones, and reduced-motion users a finished experience, not a broken one.

Failure modes

  • A second scroll or animation loop would fight the first, so motion reads from the shared transmission.
  • An autoplaying soundtrack would be intrusive and unreliable, so sound starts only when the visitor asks.

Keeping the wheel cinematic without wasting frames

  1. The hero needed a live roulette world, not an illustration.
  2. An always-on high-quality loop overspent GPU on phones and idle tabs.
  3. The scene gained tiers, a DPR cap, warm-up, settled poses, and disposal.

Repair: Treat device capacity and lifecycle as scene inputs.

Held: Rich on strong hardware, steady and legible everywhere else.

Trade

  • A code-built scene costs more time than a video hero, but light and camera respond to the page in real time.
  • Demo requests are emailed, not stored. The site stays simple; lead tracking lives downstream.
Result

What held. What carries forward.

source review

A procedural roulette world, not a pre-rendered video

A 2,200+ line scene factory builds the table, environment, light, and camera in Three.js.

source review

A deliberate low-power path

Hydration gating, device tiers, DPR limits, poster fallback, and reduced-motion poses are built into the scene.

source review

Sound made in the browser

Web Audio synthesizes the ambience and wheel strikes. No audio files ship.

If rebuilt

  • Measure render tiers on real devices and move the quality thresholds to match.
  • Add visual regression checks across more GPU and browser combinations.
結論

A 3D centerpiece earns its cost when it is part of the argument. The boundaries around it are what make it believable.

Make it hold together

Complex frontend system need steady hand?

Architecture, interface, production constraints. Together.