TITLE: Particle Galaxy — a gravity well you can steer PROMPT: Build a single self-contained HTML page containing a full-bleed interactive spiral galaxy on a 2D canvas. Palette: void #030308, violet #8a7dff, cyan #4cc9f0, magenta #f72585, warm star #fff1c9. Canvas is position:fixed inset 0, width/height 100%, touch-action:none, cursor crosshair; a second fixed layer paints a radial-gradient vignette (transparent 42% to rgba(0,0,0,.62)) above the canvas but below the UI. Sizing: DPR = Math.min(devicePixelRatio, 2); canvas.width = Math.round(cssW * DPR); canvas.height likewise; ctx.setTransform(DPR,0,0,DPR,0,0); fill the surface with #030308; recompute CX/CY and rebuild the particle field on a debounced resize (160ms). Particle field: 1400–3200 particles chosen by Math.max(1400, Math.min(3200, round(W*H/620))), stored in Float32Array typed arrays (px, py, pvx, pvy, pph, pamp, psz) plus a Uint8Array colour index; seed three log-spiral arms with r = RMIN * pow(RMAX/RMIN, pow(random,0.82)), phi = arm*(2π/3) + ln(r/RMIN)/0.34 + jitter, initial tangential velocity from omega = OMEGA * pow(RMAX/(r+RMAX), 0.55) with OMEGA = 2π/15. Physics per frame: a central force ax = -dx*omega², ay = -dy*omega² (near-solid-body rotation so the arms keep their shape), plus a clamped inverse-square cursor force ax += cx*inv*mag with mag = gravLevel*3200/d² clamped to 900 and inv = 1/sqrt(d²+700); the sign flips to repel while the pointer is held. Render: source-over fade of rgba(3,3,8,0.16) for low-alpha trails, then composite 'lighter' additive, four pre-bucketed colour passes (violet/cyan/magenta/warm-star) each with one fillStyle write and per-particle fillRect with a 0.5–2.8px sinusoidal shimmer offset; a pulsing radial-gradient core (0.5 warm star → 0.2 magenta → transparent) breathing on sin(T*1.35); expanding cyan shockwave arcs on detonation. Interaction: pointermove attracts, pointerdown holds to repel, dragging applies a velocity impulse to particles within half the viewport weighted by 1-distance/R, a short unmoved click detonates a supernova (radial impulse over 0.34 * min(W,H) plus a 1.1s shockwave), the wheel scales glow 0.35×–2.2×, and a styled range input drives gravity 0–100%. A bottom-left mono legend (Particles / Gravity / Glow / FPS, .58rem, .2em tracking, uppercase) refreshes every 15 frames. Centred system-ui 200 title clamp(1.6rem,4vw,3rem) slides in via transform and fades out after 8s. prefers-reduced-motion: reduce scales simulation time by 0.18 and removes the title animation. One inline style block, one inline IIFE script at the end of body, no external references, and the substring "http" must never appear. DESCRIPTION: A galaxy seen face-on, drawn live. Three thousand points sit on three log-spiral arms seeded around a luminous core; each carries its own shimmer phase and size, and they are composited additively so overlapping points bloom into white. The core breathes, the arms rotate with a near-solid-body curve that keeps them legible, and every frame is laid over a 16%-alpha black wash so each particle leaves a short luminous tail. The cursor is a physical object in the scene: move it and particles bend toward it under a clamped inverse-square force; hold and the force inverts, pushing the field outward in a slow ripple; drag and you fling nearby stars tangentially, spinning the disc by hand; click and a supernova fires — a radial impulse and an expanding cyan shockwave. A bottom-left mono readout reports particle count, gravity, glow and live FPS, with a hairline-thin gravity slider that changes how strongly the cursor bites. The title sits centred in system-ui 200, drifting up into place, then quietly leaving the stage to the galaxy. TECHNIQUES: - Typed arrays (Float32Array/Uint8Array) for all particle state; pre-bucketed colour indices so each frame makes only four fillStyle writes - Additive 'lighter' compositing over a low-alpha source-over fade for motion-blur trails - Log-spiral arm seeding with a twist constant plus per-particle jitter - Near-solid-body rotation curve (central force from omega²r) so spiral arms survive differential shear - Clamped inverse-square cursor force with softening term to avoid singularities - Per-particle sinusoidal shimmer offset applied at draw time only, keeping physics clean - DPR-aware canvas sizing with ctx.setTransform and debounced rebuild on resize - Radial-gradient pulsing core and expanding stroke shockwaves, both in additive mode - Dirty-ish legend updates every 15 frames instead of every frame INTERACTION: - Move the pointer over the canvas: the cursor attracts nearby particles; the field visibly bends toward it - Hold the pointer down: the force inverts and particles are pushed away in a ripple - Drag: flings particles within half the viewport tangentially, spinning the disc by hand - Click without moving (under 420ms, under 1.5px): detonates a supernova impulse plus an expanding cyan shockwave - Wheel scroll: scales the glow between 0.35× and 2.2× and updates the legend - Drag the Gravity slider: sets cursor force strength from 0% to 100% live - Resize the window: the canvas re-fits to the new size with DPR scaling and the galaxy is rebuilt - prefers-reduced-motion: reduce: simulation time drops to 18% speed and the title entrance animation is removed