# One-Shot Prompt

**Simulation**: Paper / Receipt
**Theme**: Minimal (Tender)
**Generated**: 2026-04-04

## Prompt

Generate a single-file interactive 3D receipt paper physics simulation. The receipt paper hangs from its top edge (simulating a receipt curling off a roll), and can be grabbed, crumpled, folded, and tossed. The paper feels stiff yet pliable — more resistant to bending than cloth, but eventually creases and folds under sufficient force.

### Physics Specification

**Particle Grid**: 22 columns × 32 rows = 704 particles total.
- Spacing: 0.55 units between particles.
- Grid origin: centered horizontally, top row pinned along a slight curve to simulate the roll.

**Integration**: Verlet integration (position-based). Fixed timestep of 1/120s with an accumulator capped at 33ms. 6 substeps per frame. Constraint iterations: 6 per substep.

**Constraints**:
- Structural: horizontal and vertical neighbors (rest length = spacing).
- Shear: diagonal neighbors (rest length = spacing × √2).
- Bending: skip-one horizontal and vertical (rest length = spacing × 2). Bending stiffness factor: 0.3 (weaker than structural).
- Self-collision: repulsion between particles within 2× spacing that are not directly connected.

**Forces**: Gravity = (0, −0.098, 0) per frame. Optional wind: sinusoidal force in X/Z based on time, toggleable.

**Pinning**: Top row particles are pinned to their initial positions (simulating attachment to the receipt roll).

**Floor**: Soft floor at y = −18. Particles below floor are pushed up with position correction + velocity damping.

### Interaction Specification

**Grab**: On mousedown/touchstart, cast a ray from camera through mouse position onto a plane at the grabbed particle's depth. Find nearest particle within grab radius of 2.0 units. Drag particle to ray-plane intersection. On release, particle returns to physics.

**Orbit Camera**: Implemented manually — no OrbitControls import.
- Left-drag: rotate camera around origin (theta/phi spherical coordinates).
- Right-drag or two-finger drag: pan camera.
- Scroll wheel or pinch: zoom (camera.position.distanceTo origin clamped 5–60).

**Keyboard**:
- `R`: Reset all particles to initial positions (animated ease-back over 0.5s).
- `Space`: Toggle pause.
- `W`: Toggle wind.

### Visual Specification

**Background**: Deep charcoal gradient (#1a1a1a to #0d0d0d) via CSS on body.

**Receipt Material**:
- Off-white/cream color (#f5f0e8) with MeshStandardMaterial, roughness 0.9, metalness 0.0.
- DoubleSide rendering.
- Canvas texture (1024×1024) with faint blue horizontal rules (receipt paper aesthetic) and receipt text content: a fictional grocery store receipt with item names, prices, and totals. Text is white or dark gray on the cream background.
- Texture UVs mapped so text deforms with the paper surface.

**Lighting**:
- AmbientLight (#ffffff, intensity 0.4).
- DirectionalLight (#fff8f0, intensity 0.9) from (10, 20, 10), with shadow map (1024×1024), castShadow enabled.
- DirectionalLight (#cce8ff, intensity 0.3) from (−10, 5, −5) for fill (no shadow).

**Ground plane**: Flat PlaneGeometry at y = −18.5, MeshStandardMaterial (#222222, roughness 1.0), receiveShadow enabled. No castShadow.

**Renderer**: antialias: true, setPixelRatio(min(devicePixelRatio, 2)), shadowMap enabled (PCFSoftShadowMap).

**Post-effects**: None (keep it lightweight for 60fps).

### Canvas Texture Content

Generate a procedural receipt text on the canvas:
- Header: "MARKET EXPRESS" in bold, centered.
- Subheader: "123 Main Street, Anytown USA".
- Horizontal rule.
- 8–10 grocery items with prices right-aligned (e.g., "Organic Milk .... $4.99").
- Horizontal rule.
- Subtotals, tax line, total line (double rule).
- Footer text: "Thank you for shopping with us!"
- Barcode-like decorative element at bottom.

### Mobile Specification

- Detect touch via `navigator.maxTouchPoints > 0` or `window.innerWidth < 768`.
- Reduce particle grid to 15×22 (330 particles) for mobile.
- Touch to grab mapped same as mouse.
- Pinch-to-zoom on camera (two touch points).
- `touch-action: none` on canvas.

### HUD

- Top-left overlay (position: absolute).
- Title: "TENDER" in 14px monospace, letter-spacing 0.2em, color #888.
- Instruction: "drag to interact" in 11px monospace, color #555. Fades out after 4 seconds.
- Bottom-right: FPS counter (hidden by default, toggle with `I` key).
- All HUD uses CSS, no external fonts (system monospace).

### States

| State | Behavior |
|---|---|
| **Loading** | Brief "Initializing..." text overlay |
| **Running** | Physics active, interaction enabled |
| **Paused** | Semi-transparent dark overlay, "PAUSED" text |
| **Reset** | Particles ease back to initial positions over 0.5s |

### Output

Write the complete `PROMPT.md` first. Then write the complete `index.html` — every line of code, no truncation, no placeholder comments like `// ...`, no elision. The file must be 1000–1800 lines.

---

**Skill base**: `file:///Users/jp/Repos/jpcaparas/writing/.agents/skills/oneshot-physics`

**Hosting**: CodePen, Vercel, or Cloudflare Pages as a static `index.html`.
