Ten thousand canvas particles breathing around a serif wordmark.

Build a one-screen generative landing page for a creative-AI research collective called "Heliotrope" using React, TypeScript, Vite and Tailwind CSS. No 3D library — a hand-rolled 2D canvas particle field.
FONTS: "Fraunces" (weights 400, 600, italic 400) and "IBM Plex Mono" (400, 500) from Google Fonts. `.font-fraunces` and `.font-plex` utility classes in src/styles.css.
CANVAS FIELD (full-screen, `fixed inset-0 z-0`, background `#f5f1e8`): a useEffect-driven canvas rendering exactly 9000 particles:
- Each particle: `{ x, y, angle, radius, speed, size }`, drifting on a sunflower-phyllotaxis spiral around the viewport center: angle += speed each frame, position = center + radius * [cos(angle), sin(angle)]
- radius values distributed between 40 and min(width, height) * 0.48; speed between 0.0006 and 0.0022; size between 0.4 and 1.4
- Fill style `rgba(31, 27, 22, alpha)` where alpha = 0.12 + (1 - radius / maxRadius) * 0.5
- The WHOLE field slowly breathes: a global scale of `1 + 0.03 * sin(t / 2400)` applied around center
- Repaint with `ctx.fillStyle = 'rgba(245, 241, 232, 0.28)'` full-rect each frame (motion trails, no hard clears)
- Drive with requestAnimationFrame; cancel on unmount; resize handler keeps the canvas at devicePixelRatio-scaled full size
CONTENT (relative z-10, h-screen, grid place-items-center, text-center):
- Wordmark: "Heliotrope" in `font-fraunces italic text-[clamp(3.5rem,11vw,9rem)] text-[#1f1b16] leading-none tracking-[-2px]`
- Under it: "Machines that turn toward the light" in `font-plex text-[13px] sm:text-sm tracking-[0.3em] uppercase text-[#1f1b16]/60 mt-6`
- Bottom-center (absolute bottom-10 inset-x-0): three mono stats in a flex row gap-10 justify-center, each `font-plex text-[11px] tracking-[0.2em] uppercase text-[#1f1b16]/50`: "9,000 PARTICLES", "60 FPS", "0 IMAGES"
TOP BAR (absolute top-0 inset-x-0 z-10, flex justify-between px-6 sm:px-10 py-6, font-plex `text-[12px] tracking-[0.25em] uppercase text-[#1f1b16]/70`): left "HELIOTROPE.SYSTEMS", right a mailto link "hello@heliotrope.systems" with `underline underline-offset-4`.
Wordmark and subline fade-in with `@keyframes ink { from { opacity: 0; letter-spacing: 6px; } to { opacity: 1; letter-spacing: -2px; } }` over 1.4s ease-out, subline delayed 0.5s. Single App.tsx + src/styles.css, no routing.canvasparticleslighteditorial