# One-Shot Prompt

**Simulation**: Paper / Receipt (preferred default)
**Theme**: Minimal — off-white paper, receipt aesthetic, soft industrial lighting
**Generated**: 2026-04-17

## Prompt

Generate a single-file interactive 3D receipt paper physics simulation. The simulation must be completely self-contained in one HTML file with all CSS and JavaScript inline. No external images, models, or dependencies except a single Three.js CDN import.

### Physics Specification

- **Particle grid**: 40 columns × 56 rows (receipt aspect ratio ~2:3)
- **Integration**: Verlet integration with fixed timestep accumulator (dt capped at 33ms)
- **Substeps**: 6 physics steps per animation frame
- **Constraint solving**: 6 constraint iterations per substep
- **Constraints**:
  - Structural distance constraints on horizontal and vertical edges (rest length = grid spacing)
  - Shear constraints on diagonal edges (rest length = √2 × grid spacing)
  - Bending constraints connecting particles 2 steps apart (to resist folding — stiffness set lower than structural)
  - Pin constraint on top-left and top-right corners (fixed in world space)
- **Self-collision**: Repulsion between non-adjacent particles when distance < 1.5 × rest length (spatial hash for O(n) broadphase)
- **Gravity**: (0, -9.8, 0) in world units
- **Damping**: 0.99 velocity damping per frame (subtle air resistance)

### Interaction Specification

- **Mouse grab**: On mousedown, cast ray from camera through mouse position onto a plane at the grabbed particle's depth. Grab the nearest particle within a radius. On mousemove, project mouse position onto the 3D plane and move grabbed particle to that position. On mouseup, release and let momentum carry.
- **Touch grab**: Map touchstart/touchmove/touchend to mouse equivalent events
- **3D cursor**: A small sphere (radius 0.08) rendered at grab point, color-coded (light blue when idle, warm orange when actively grabbing)
- **Raycasting**: Use Three.js Raycaster with a virtual plane positioned at the grabbed particle's Z depth, refreshed each frame while dragging
- **Release physics**: When released, the paper responds naturally — momentum, settling, swinging from pin points

### Visual Treatment

- **Background**: Very dark warm gray (#1a1a1a) with subtle radial gradient lighter at center, simulating a soft studio light from above
- **Paper material**: `MeshStandardMaterial`, off-white (#f5f0e8), roughness 0.85, metalness 0.0, double-sided rendering
- **Text texture**: Canvas-drawn receipt text — store name "PAPER + INK", date, a list of 4-5 line items with prices, and a subtle border. Canvas mapped to mesh UV. Text must deform with the surface.
- **Lighting**:
  - Ambient light: (0xffffff, intensity 0.4)
  - Directional light: warm white (0xfff8e7), intensity 1.2, position (5, 10, 7), casts shadows (shadowMap 1024×1024)
  - Hemisphere light: sky (0xffffff) ground (0x444422), intensity 0.3
- **Ground plane**: None (paper floats in space, shadow falls on an invisible plane below — use only shadow receiver, no visible geometry)
- **Shadows**: Paper casts shadow; a flat invisible shadow plane at y = -4 receives shadow only

### Camera & Controls

- **Camera**: PerspectiveCamera, FOV 50, position (0, 0, 12)
- **Orbit**: Basic orbit on right-drag (rotate around origin), scroll to zoom (distance clamped 5–20), no panning needed
- **Orbit implementation**: Track mouse drag delta on right-button; rotate camera in azimuth/elevation around origin

### UI Overlay (DOM)

- **Top-left HUD**: Simulation name "TENDER" in monospace, small instruction text "click + drag to interact" (fades after 4 seconds)
- **Bottom-right**: FPS counter (hidden by default, toggle with 'I' key)
- **Controls hint**: Bottom-center, "R: reset · Space: pause · W: wind", small muted text
- **States**:
  - Loading: Brief "Initializing..." text centered
  - Running: Physics active, instruction fades
  - Paused: Semi-transparent dark overlay, "PAUSED" text centered, press Space to resume
  - Reset: Particles animate back to rest positions (lerp over 0.8s), not snap

### Performance

- **Buffer geometry**: Float32Array for particle positions, updated in-place with `needsUpdate = true`
- **Mobile**: Detect via `navigator.maxTouchPoints > 0 || window.innerWidth < 768` — reduce grid to 24×34, particle count ~816
- **Target FPS**: 60fps with 2240 particles (desktop), 60fps with 816 particles (mobile)
- **Typed arrays**: Physics state in Float32Array — positions, previous positions, velocities

### Wind Feature

- **Wind toggle**: Press 'W' to toggle a gentle oscillating wind force (magnitude 0–3, direction primarily +X with sinusoidal variation over time)
- **Visual indicator**: None needed — user sees it in the paper movement

### SEO Metadata

```html
<meta name="description" content="Interactive receipt paper physics — grab, crumple, fold, and release. A one-shot 3D simulation built in a single HTML file.">
<meta property="og:title" content="Tender — Receipt Paper Physics">
<meta property="og:description" content="Interactive receipt paper physics — grab, crumple, fold, and release.">
<meta property="og:type" content="website">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Tender — Receipt Paper Physics">
<meta name="twitter:description" content="Interactive receipt paper physics.">
```

### Page Title
`<title>Tender — Receipt Paper Physics</title>`

### Inline SVG Favicon
A small paper sheet icon (white rectangle with subtle fold lines) in SVG, data URI encoded.

### Accessibility
- `prefers-reduced-motion`: Skip wind oscillation, reduce particle count by 50%, no idle sway animation

## Notes

- Physics approach: Verlet integration is the right choice here — it's stable, handles constraints naturally, and produces the right "heavy paper" feel that Euler integration can't match.
- Bending stiffness should be ~20% of structural stiffness — paper resists folding initially but can crease under sufficient force.
- Self-collision is essential for the "crumple into a ball" moment — without it, paper self-intersects unrealistically.
- Text texture: draw on a 1024×1024 canvas for high resolution; the UV mapping will handle deformation naturally.
- Hosting: Works as a standalone `index.html` — CodePen paste, Vercel static deploy, or Cloudflare Pages drop-in.

## Output Files

1. `PROMPT.md` — this document
2. `index.html` — the complete simulation, target 800–1200 lines, every physics loop and constraint written in full, no elision, no placeholders