paperlab 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -7
- package/dist/chunk-3IMUEESH.js +7035 -0
- package/dist/chunk-3IMUEESH.js.map +1 -0
- package/dist/index.cjs +1938 -1753
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +582 -4400
- package/dist/index.d.ts +582 -4400
- package/dist/index.js +225 -6727
- package/dist/index.js.map +1 -1
- package/dist/slots-D0Nc_5dq.d.cts +6661 -0
- package/dist/slots-D0Nc_5dq.d.ts +6661 -0
- package/dist/stage.cjs +8871 -0
- package/dist/stage.cjs.map +1 -0
- package/dist/stage.d.cts +1156 -0
- package/dist/stage.d.ts +1156 -0
- package/dist/stage.js +2214 -0
- package/dist/stage.js.map +1 -0
- package/package.json +37 -8
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Paper.tsx","../src/PaperMesh.tsx","../src/config/schema.ts","../src/config/merge.ts","../src/behaviors/peel.ts","../src/deformers/curl.ts","../src/behaviors/unroll.ts","../src/behaviors/flip.ts","../src/behaviors/letter-fold.ts","../src/behaviors/hang.ts","../src/behaviors/fly.ts","../src/behaviors/fall.ts","../src/behaviors/carry.ts","../src/behaviors/flight.ts","../src/physics/aero.ts","../src/behaviors/crumple.ts","../src/config/serialize.ts","../src/core/sheet.ts","../src/core/stock.ts","../src/config/presets/index.ts","../src/content/texture.ts","../src/content/receipt.ts","../src/deformers/compose.ts","../src/deformers/registry.ts","../src/deformers/roll.ts","../src/deformers/bend.ts","../src/deformers/fold.ts","../src/deformers/wave.ts","../src/deformers/drape.ts","../src/deformers/crumple.ts","../src/behaviors/registry.ts","../src/physics/idle.ts","../src/physics/cloth.ts","../src/surface/PaperMaterial.tsx","../src/surface/compose.ts","../src/surface/translucency.ts","../src/scene/lighting.ts","../src/a11y/index.tsx","../src/motion/onTwos.ts","../src/states/usePaperStates.ts","../src/states/machine.ts","../src/scene/PaperLighting.tsx","../src/PaperField.tsx","../src/field/dropZones.tsx","../src/field/sheetGrid.ts","../src/field/slots.ts","../src/field/fieldGroup.tsx","../src/content/atlas.ts","../src/field/compose.ts","../src/field/layouts/index.ts","../src/stage/path.ts","../src/field/stack.ts","../src/field/backingSheet.tsx","../src/content/backing.ts","../src/field/interactiveField.tsx","../src/field/keyboardMirror.tsx","../src/field/framing.ts","../src/stage/PaperStage.tsx","../src/stage/camera.ts","../src/stage/Figure.tsx","../src/stage/gait.ts","../src/stage/Surround.tsx","../src/stage/schema.ts","../src/stage/quality.ts","../src/stage/walks.ts","../src/stage/presets.ts","../src/config/diff.ts","../src/config/agent-payload.ts","../src/stage/export.ts","../src/field/parity.ts","../src/config/field-export.ts","../src/core/modes.ts"],"sourcesContent":["import { Canvas } from '@react-three/fiber'\nimport { forwardRef, useMemo } from 'react'\nimport {\n PaperMesh,\n resolveConfig,\n resolveConfigKey,\n type PaperHandle,\n type PaperMeshProps,\n} from './PaperMesh'\nimport { PaperFallback, PaperMirror, supportsWebGL } from './a11y'\nimport { PaperLighting } from './scene/PaperLighting'\n\nexport interface PaperProps extends PaperMeshProps {\n /** Extra children rendered inside the canvas (lights are provided). */\n children?: React.ReactNode\n className?: string\n style?: React.CSSProperties\n}\n\n/**\n * `<Paper />` owns its own `<Canvas>` and fills its parent container —\n * the parent must have a height. Use `<PaperMesh />` inside an existing\n * R3F scene instead.\n *\n * Ships with its accessibility layer: a hidden DOM mirror of the content,\n * `prefers-reduced-motion` support, and a flat DOM fallback when WebGL is\n * unavailable.\n */\nexport const Paper = forwardRef<PaperHandle, PaperProps>(function Paper(\n { children, className, style, ...meshProps },\n ref,\n) {\n // Keyed on every prop resolveConfig reads — a content/stock/behavior change\n // must refresh the fallback, mirror, and lighting, not just the mesh.\n // biome-ignore lint/correctness/useExhaustiveDependencies: resolveConfigKey serializes every prop resolveConfig reads — the props object itself is new each render.\n const config = useMemo(() => resolveConfig(meshProps), [resolveConfigKey(meshProps)])\n const webgl = useMemo(() => (typeof window === 'undefined' ? true : supportsWebGL()), [])\n\n return (\n <div className={className} style={{ width: '100%', height: '100%', ...style }}>\n {webgl ? (\n <Canvas shadows camera={{ position: [0, 0.35, 2.4], fov: 40 }} dpr={[1, 2]}>\n <PaperLighting\n preset={config.scene.lighting}\n floor={-1.05}\n scale={8}\n reducedMotion={meshProps.reducedMotion}\n />\n <PaperMesh ref={ref} {...meshProps} />\n {children}\n </Canvas>\n ) : (\n <PaperFallback config={config} />\n )}\n <PaperMirror config={config} />\n </div>\n )\n})\n","import * as THREE from 'three'\nimport { gsap } from 'gsap'\nimport { useFrame, useThree } from '@react-three/fiber'\nimport type { ThreeEvent } from '@react-three/fiber'\nimport { forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from 'react'\nimport type {\n BehaviorConfigInput,\n ClothConfig,\n ContentConfigInput,\n DeformerInstanceConfigInput,\n PaperConfig,\n PaperConfigInput,\n PhysicsConfigInput,\n SceneConfigInput,\n SheetConfig,\n StockName,\n SurfaceConfigInput,\n} from './config/schema'\nimport { paperConfigSchema } from './config/schema'\nimport { mergeConfig, parsePreset, serializePreset } from './config/serialize'\nimport { createSheetGeometry, resolveSegments } from './core/sheet'\nimport { getStock } from './core/stock'\nimport { getPreset } from './config/presets'\nimport { useContentTexture } from './content/texture'\nimport { applyDeformerStack, displacePoint, stackMinSegments } from './deformers/compose'\nimport { stackIsAnimated } from './deformers/registry'\nimport type { DeformerInstance } from './deformers/types'\nimport { getBehavior } from './behaviors/registry'\nimport { resolveDeformerStack } from './deformers/registry'\nimport type { Behavior } from './behaviors/types'\nimport { getIdlePreset, type IdleName, type IdlePose } from './physics/idle'\nimport { ClothSim } from './physics/cloth'\nimport { PaperMaterial } from './surface/PaperMaterial'\nimport { usePrefersReducedMotion } from './a11y'\nimport { quantizeProgress, quantizeTime } from './motion/onTwos'\nimport { usePaperStates } from './states/usePaperStates'\nimport type { PaperStateMachine, StateEvent } from './states/machine'\n\nexport interface PaperMeshProps {\n /** Built-in preset name, or a (partial) preset object. Props below override it. */\n preset?: string | PaperConfigInput\n sheet?: Partial<SheetConfig>\n stock?: StockName\n /**\n * These take the schema's INPUT types, not its parsed ones: writing\n * `content={{ type: 'text', text: 'hi' }}` has to compile, and with the\n * inferred type it does not — it demands every field of every nested\n * object. Every default stays a default.\n */\n content?: ContentConfigInput\n behavior?: BehaviorConfigInput\n deformers?: DeformerInstanceConfigInput[]\n /** Fragment-side effects: grain, aging, deckle, creases, perforation. */\n surface?: SurfaceConfigInput\n /** Scene-level presentation that travels with the paper (lighting). */\n scene?: SceneConfigInput\n physics?: PhysicsConfigInput | 'cloth'\n onTwos?: boolean\n /** Show draggable behavior handles; cloth sheets become grabbable. */\n interactive?: boolean\n /** Start the behavior's transport loop on mount. */\n autoplay?: boolean\n /** Override prefers-reduced-motion (default: follow the system setting). */\n reducedMotion?: boolean\n position?: [number, number, number]\n rotation?: [number, number, number]\n /** Fires every animation tick with the behavior's progress (0..1). */\n onProgress?(value: number): void\n /** Fires when a handle drag ends, with the params the drag changed. */\n onBehaviorChange?(patch: Record<string, unknown>): void\n /**\n * Interaction states: when the config carries `states`, pointer triggers\n * are live by default. Set false to sculpt a stateful paper without the\n * machine firing (the editor's state-editing mode).\n */\n stateTriggers?: boolean\n /** Fires when the state machine changes state. */\n onStateChange?(state: string): void\n /** Fires for `onEnter` actions ('emit:<event>'). */\n onStateAction?(event: string, state: string): void\n}\n\nexport interface PaperHandle {\n play(): void\n pause(): void\n readonly playing: boolean\n /** Live-override a behavior param. 'progress' always maps to the behavior's progress param. */\n set(param: string, value: unknown): void\n getProgress(): number\n /** Current full state (including live overrides) as a preset. */\n snapshot(): PaperConfig\n toJSON(): string\n readonly mesh: THREE.Mesh | null\n /** Interaction-state machine access (null when the config has no states). */\n readonly state: string\n sendState(event: StateEvent): string | null\n /**\n * Drive to 'picked' through the legal chain (rest→hover→pressed→picked),\n * instantly, so every side effect fires — the keyboard/a11y entry point\n * where no pointer hover/press ever ran. Returns true if it landed.\n */\n pickProgrammatic(): boolean\n /** Instant, legal place (picked → placed) so onEnter/emit fires. */\n placeProgrammatic(): boolean\n /** Instant, legal return (picked → rest). */\n returnProgrammatic(): boolean\n}\n\n/**\n * Stable memo key over every prop {@link resolveConfig} reads. Consumers that\n * cache a resolved config must key on this, not on `preset` alone.\n */\nexport function resolveConfigKey(props: PaperMeshProps): string {\n return JSON.stringify([\n props.preset ?? null,\n props.sheet ?? null,\n props.stock ?? null,\n props.content ?? null,\n props.behavior ?? null,\n props.deformers ?? null,\n props.surface ?? null,\n props.scene ?? null,\n props.physics ?? null,\n props.onTwos ?? null,\n ])\n}\n\n/** Resolve preset + prop overrides into a validated config. */\nexport function resolveConfig(props: PaperMeshProps): PaperConfig {\n const base = props.preset\n ? typeof props.preset === 'string'\n ? getPreset(props.preset)\n : parsePreset(props.preset)\n : paperConfigSchema.parse({})\n const overrides: PaperConfigInput = {}\n if (props.sheet) overrides.sheet = { ...base.sheet, ...props.sheet }\n if (props.stock) overrides.stock = props.stock\n if (props.content) overrides.content = props.content\n if (props.behavior) overrides.behavior = props.behavior\n if (props.deformers) overrides.deformers = props.deformers\n // Surface merges over the stock's defaults rather than replacing them, so\n // `surface={{ grain: 0.6 }}` on thermal keeps thermal's banding.\n if (props.surface) overrides.surface = { ...base.surface, ...props.surface }\n if (props.scene) overrides.scene = { ...base.scene, ...props.scene }\n if (props.physics) overrides.physics = props.physics\n if (props.onTwos !== undefined) overrides.onTwos = props.onTwos\n return paperConfigSchema.parse(mergeConfig(base as PaperConfigInput, overrides))\n}\n\n/** Cloth grids cap their resolution — 5k verlet particles is the budget ceiling. */\nconst CLOTH_MAX_SEGMENTS = 28\n\nconst dragPlane = new THREE.Plane()\nconst dragPoint = new THREE.Vector3()\nconst planeNormal = new THREE.Vector3()\nconst anchorScratch = new THREE.Vector3()\nconst worldScratch = new THREE.Vector3()\nconst quatScratch = new THREE.Quaternion()\n\n/**\n * The atom: one sheet of paper, hero-mode CPU path. The deformer stack (or\n * the cloth sim — never both) writes geometry positions each frame. GSAP\n * owns animated values; useFrame owns geometry writes.\n */\nexport const PaperMesh = forwardRef<PaperHandle, PaperMeshProps>(function PaperMesh(props, ref) {\n // Each resolveConfig call is several zod parses (superRefine re-parses every\n // state override) — memoized so a render without config-prop changes is free.\n // biome-ignore lint/correctness/useExhaustiveDependencies: resolveConfigKey serializes every prop resolveConfig reads — the props object itself is new each render.\n const resolved = useMemo(() => resolveConfig(props), [resolveConfigKey(props)])\n // Reduced motion: behaviors freeze at their resting pose, physics is off,\n // idle motion is off. The sheet still renders fully sculpted.\n const reduced = usePrefersReducedMotion(props.reducedMotion)\n // Interaction states: the machine animates a live config between state\n // overrides; `config` below is that animated view (the base when no states).\n // Reduced motion keeps the machine but makes transitions instant.\n const statesLive = Boolean(resolved.states) && props.stateTriggers !== false\n const {\n config,\n machine,\n state: machineState,\n } = usePaperStates(resolved, statesLive, reduced, props.onStateAction, props.onStateChange)\n const behavior: Behavior | null = config.behavior ? getBehavior(config.behavior.type) : null\n const machineRef = useRef<PaperStateMachine | null>(null)\n machineRef.current = machine\n // The animated `config` has `states` stripped — keep the resolved preset\n // around so snapshot()/toJSON() never lose the state machine.\n const resolvedRef = useRef(resolved)\n resolvedRef.current = resolved\n const isCloth = !reduced && typeof config.physics === 'object'\n const idle =\n !reduced && typeof config.physics === 'string' && config.physics !== 'none'\n ? getIdlePreset(config.physics as IdleName)\n : null\n\n const meshRef = useRef<THREE.Mesh>(null)\n const groupRef = useRef<THREE.Group>(null)\n const handleRefs = useRef<(THREE.Mesh | null)[]>([])\n\n const overridesRef = useRef<Record<string, unknown>>({})\n const dirtyRef = useRef(true)\n const playingRef = useRef(false)\n const tweenRef = useRef<gsap.core.Tween | null>(null)\n const draggingRef = useRef<string | null>(null)\n\n const configRef = useRef(config)\n configRef.current = config\n\n const controls = useThree((s) => s.controls) as { enabled?: boolean } | null\n const camera = useThree((s) => s.camera)\n\n const behaviorKey = JSON.stringify(config.behavior ?? null)\n const deformersKey = JSON.stringify(config.deformers ?? null)\n const sheetKey = JSON.stringify(config.sheet)\n const physicsKey = JSON.stringify(config.physics)\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: The keys are change triggers; the body only touches refs.\n useEffect(() => {\n if (!draggingRef.current && !playingRef.current) overridesRef.current = {}\n dirtyRef.current = true\n }, [behaviorKey, deformersKey, sheetKey, physicsKey])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: Keyed on the stack shape — the probe reads config off a ref.\n const minSegments = useMemo(() => {\n const probe = buildStack(configRef.current, {})\n return probe ? stackMinSegments(probe) : 2\n }, [behaviorKey, deformersKey, physicsKey])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: Keyed on the sheet — rebuilding geometry on identity would orphan GPU buffers every render.\n const geometry = useMemo(() => {\n if (!isCloth) return createSheetGeometry(config.sheet, minSegments)\n // Cloth: explicit capped grid so sim particles == mesh vertices.\n const [sx, sy] = resolveSegments(config.sheet, 2)\n const capped = Math.min(Math.max(sx, sy), CLOTH_MAX_SEGMENTS)\n return new THREE.PlaneGeometry(config.sheet.width, config.sheet.height, capped, capped)\n }, [sheetKey, minSegments, isCloth])\n\n // Imperatively-created geometry is ours to free — R3F only auto-disposes\n // JSX-created objects, so a sheet change would otherwise orphan GPU buffers.\n useEffect(() => () => geometry.dispose(), [geometry])\n\n const basePositions = useMemo(\n () => Float32Array.from(geometry.attributes.position!.array as Float32Array),\n [geometry],\n )\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: Rebuild only on geometry or pin layout change — sliders update the sim in place.\n const sim = useMemo(() => {\n if (!isCloth) return null\n const cloth = configRef.current.physics as ClothConfig\n const cols = (geometry.parameters as { widthSegments: number }).widthSegments + 1\n const rows = (geometry.parameters as { heightSegments: number }).heightSegments + 1\n return new ClothSim(cols, rows, config.sheet.width, config.sheet.height, cloth.pins, {\n stiffness: cloth.stiffness,\n gravity: cloth.gravity,\n wind: cloth.wind,\n floor: cloth.floor,\n })\n }, [geometry, isCloth, isCloth ? (config.physics as ClothConfig).pins : ''])\n\n const stock = getStock(config.stock)\n const texture = useContentTexture(config.content, config.sheet, stock)\n const backTexture = useContentTexture(config.content.back, config.sheet, stock)\n\n // Per-frame config: when a state machine is live it OWNS the animated numeric\n // values (GSAP tweens them); we poll its mutable liveConfig each frame rather\n // than routing every tick through React. Falls back to the React config for\n // non-stateful papers.\n const liveConfig = (): PaperConfig => machineRef.current?.liveConfig ?? configRef.current\n\n const effectiveOptions = (t: number): Record<string, unknown> | null => {\n const cfg = liveConfig()\n if (!cfg.behavior || !behavior) return null\n const o = { ...cfg.behavior, ...overridesRef.current }\n return behavior.loop ? { ...o, ...behavior.loop(o, t) } : o\n }\n\n const play = () => {\n if (!behavior) return\n playingRef.current = true\n if (tweenRef.current) {\n tweenRef.current.play()\n return\n }\n const param = behavior.progressParam\n const start = (effectiveOptions(0)?.[param] as number) ?? 0\n const state = { p: start }\n tweenRef.current = gsap.to(state, {\n p: 1,\n duration: behavior.duration * (1 - start),\n ease: 'power2.inOut',\n yoyo: behavior.loopMode === 'yoyo',\n repeat: -1,\n onRepeat: () => {\n if (behavior.loopMode === 'restart') state.p = 0\n },\n onUpdate: () => {\n const p = configRef.current.onTwos ? quantizeProgress(state.p, behavior.duration) : state.p\n overridesRef.current[param] = p\n dirtyRef.current = true\n props.onProgress?.(p)\n },\n })\n }\n\n const pause = () => {\n playingRef.current = false\n tweenRef.current?.pause()\n }\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: Mount-only: autoplay starts once, and the cleanup kills the tween on unmount.\n useEffect(() => {\n if (props.autoplay && !reduced) play()\n return () => {\n tweenRef.current?.kill()\n tweenRef.current = null\n }\n }, [])\n\n const snapshot = (): PaperConfig => {\n // Re-attach `states`: the rendered config is the animated view with the\n // machine stripped, but a snapshot is a preset — states are part of it.\n const states = resolvedRef.current.states\n const cfg = states ? { ...configRef.current, states } : configRef.current\n if (!cfg.behavior) return states ? paperConfigSchema.parse(cfg) : cfg\n return paperConfigSchema.parse({\n ...cfg,\n behavior: { ...cfg.behavior, ...overridesRef.current },\n })\n }\n\n useImperativeHandle(ref, () => ({\n play,\n pause,\n get playing() {\n return playingRef.current\n },\n set(param: string, value: unknown) {\n const key = param === 'progress' && behavior ? behavior.progressParam : param\n overridesRef.current[key] = value\n dirtyRef.current = true\n if (behavior && key === behavior.progressParam) props.onProgress?.(value as number)\n },\n getProgress() {\n if (!behavior) return 0\n return (effectiveOptions(0)?.[behavior.progressParam] as number) ?? 0\n },\n snapshot,\n toJSON: () => serializePreset(snapshot()),\n get mesh() {\n return meshRef.current\n },\n get state() {\n return machineState\n },\n sendState: (event: StateEvent) => machineRef.current?.send(event) ?? null,\n pickProgrammatic: () => machineRef.current?.pickProgrammatic() ?? false,\n placeProgrammatic: () => machineRef.current?.placeProgrammatic() ?? false,\n returnProgrammatic: () => machineRef.current?.returnProgrammatic() ?? false,\n }))\n\n const idlePose = useRef<IdlePose>({ position: [0, 0, 0], rotation: [0, 0, 0] })\n\n useFrame(({ clock }, delta) => {\n const cfg = liveConfig()\n // Reduced motion freezes time-driven deformers at their resting phase.\n const now = reduced ? 0 : cfg.onTwos ? quantizeTime(clock.elapsedTime) : clock.elapsedTime\n\n // Whole-sheet motion — idle presets and behavior transforms (flight's\n // travel across the scene) compose additively; vertices stay untouched.\n const hasBehaviorTransform = Boolean(behavior?.transform && cfg.behavior)\n if ((idle?.transform || hasBehaviorTransform) && groupRef.current) {\n const pose = idlePose.current\n pose.position[0] = pose.position[1] = pose.position[2] = 0\n pose.rotation[0] = pose.rotation[1] = pose.rotation[2] = 0\n idle?.transform?.(now, pose)\n if (hasBehaviorTransform) {\n const o = effectiveOptions(now)\n if (o) behavior!.transform!(o, now, pose)\n }\n const base = props.position ?? [0, 0, 0]\n const baseRot = props.rotation ?? [0, 0, 0]\n groupRef.current.position.set(\n base[0] + pose.position[0],\n base[1] + pose.position[1],\n base[2] + pose.position[2],\n )\n groupRef.current.rotation.set(\n baseRot[0] + pose.rotation[0],\n baseRot[1] + pose.rotation[1],\n baseRot[2] + pose.rotation[2],\n )\n }\n\n // Simulation path: cloth owns the vertices.\n if (isCloth && sim) {\n const cloth = cfg.physics as ClothConfig\n sim.setParams({\n wind: cloth.wind,\n gravity: cloth.gravity,\n stiffness: cloth.stiffness,\n floor: cloth.floor,\n })\n sim.step(delta)\n if (!sim.asleep) {\n const position = geometry.attributes.position as THREE.BufferAttribute\n ;(position.array as Float32Array).set(sim.positions)\n position.needsUpdate = true\n geometry.computeVertexNormals()\n }\n return\n }\n\n // Shape path: the deformer stack.\n const stack = buildStack(cfg, overridesRef.current, behavior, now)\n if (!stack) return\n const animated = !reduced && stackIsAnimated(stack)\n const hasLoop = !reduced && Boolean(cfg.behavior && behavior?.loop)\n // A state transition tweens numeric leaves off the React path, so the\n // stack must re-apply every frame while the machine is transitioning.\n const machineAnimating = Boolean(machineRef.current?.transitioning)\n if (!dirtyRef.current && !hasLoop && !animated && !machineAnimating) return\n dirtyRef.current = false\n\n const ctx = { t: now, sheet: cfg.sheet }\n applyDeformerStack(geometry, basePositions, stack, ctx)\n\n if (props.interactive && behavior?.handles) {\n const o = effectiveOptions(now)\n behavior.handles.forEach((h, i) => {\n const mesh = handleRefs.current[i]\n if (!mesh || !o) return\n const [u, v] = h.anchor(o, cfg.sheet)\n anchorScratch.set((u - 0.5) * cfg.sheet.width, (v - 0.5) * cfg.sheet.height, 0)\n displacePoint(anchorScratch, u, v, stack, ctx)\n mesh.position.copy(anchorScratch)\n })\n }\n })\n\n const localDragPoint = (e: ThreeEvent<PointerEvent>): { x: number; y: number } | null => {\n const group = groupRef.current\n if (!group) return null\n planeNormal.set(0, 0, 1).applyQuaternion(group.getWorldQuaternion(quatScratch))\n dragPlane.setFromNormalAndCoplanarPoint(planeNormal, group.getWorldPosition(dragPoint))\n const hit = e.ray.intersectPlane(dragPlane, dragPoint)\n if (!hit) return null\n group.worldToLocal(hit)\n return { x: hit.x, y: hit.y }\n }\n\n const onHandleDrag = (e: ThreeEvent<PointerEvent>) => {\n if (!behavior?.handles || !draggingRef.current) return\n const handleSpec = behavior.handles.find((h) => h.id === draggingRef.current)\n const local = localDragPoint(e)\n const o = effectiveOptions(0)\n if (!handleSpec || !local || !o) return\n Object.assign(overridesRef.current, handleSpec.drag(local, o, configRef.current.sheet))\n dirtyRef.current = true\n const p = overridesRef.current[behavior.progressParam]\n if (typeof p === 'number') props.onProgress?.(p)\n }\n\n // Cloth grab: pick the nearest particle, then drag it on a camera-facing\n // plane through the grab point — full 3D pull, not just in-plane.\n const grabAnchor = useRef(new THREE.Vector3())\n const clothDown = (e: ThreeEvent<PointerEvent>) => {\n if (!isCloth || !sim || !props.interactive || !groupRef.current) return\n e.stopPropagation()\n if (controls) controls.enabled = false\n grabAnchor.current.copy(e.point) // world-space anchor for the drag plane\n const local = groupRef.current.worldToLocal(worldScratch.copy(e.point))\n sim.grabNearest(local.x, local.y, local.z)\n draggingRef.current = 'cloth'\n ;(e.target as Element).setPointerCapture(e.pointerId)\n }\n const clothMove = (e: ThreeEvent<PointerEvent>) => {\n if (draggingRef.current !== 'cloth' || !sim || !groupRef.current) return\n camera.getWorldDirection(planeNormal)\n dragPlane.setFromNormalAndCoplanarPoint(planeNormal, grabAnchor.current)\n const hit = e.ray.intersectPlane(dragPlane, dragPoint)\n if (!hit) return\n groupRef.current.worldToLocal(hit)\n sim.moveGrab(hit.x, hit.y, hit.z)\n }\n const clothUp = (e: ThreeEvent<PointerEvent>) => {\n if (draggingRef.current !== 'cloth' || !sim) return\n draggingRef.current = null\n if (controls) controls.enabled = true\n sim.release()\n ;(e.target as Element).releasePointerCapture(e.pointerId)\n }\n\n // Interaction-state triggers (rest ↔ hover ↔ pressed); pick/place/return\n // are driven by the field's carry controller through `sendState`.\n const sendState = (event: StateEvent) => machineRef.current?.send(event)\n\n return (\n <group ref={groupRef} position={props.position} rotation={props.rotation}>\n <mesh\n ref={meshRef}\n geometry={geometry}\n castShadow\n receiveShadow\n frustumCulled={false}\n onPointerOver={statesLive ? () => sendState('enter') : undefined}\n onPointerOut={statesLive ? () => sendState('leave') : undefined}\n onPointerDown={\n isCloth || statesLive\n ? (e) => {\n if (isCloth) clothDown(e)\n if (statesLive) sendState('down')\n }\n : undefined\n }\n onPointerMove={isCloth ? clothMove : undefined}\n onPointerUp={\n isCloth || statesLive\n ? (e) => {\n if (isCloth) clothUp(e)\n if (statesLive) sendState('up')\n }\n : undefined\n }\n >\n <PaperMaterial\n stock={stock}\n texture={texture}\n backTexture={backTexture}\n surface={config.surface}\n thickness={config.sheet.thickness}\n sheet={config.sheet}\n lighting={config.scene.lighting}\n />\n </mesh>\n {props.interactive &&\n !isCloth &&\n behavior?.handles?.map((h, i) => (\n <mesh\n key={h.id}\n ref={(m) => {\n handleRefs.current[i] = m\n }}\n onPointerDown={(e) => {\n e.stopPropagation()\n draggingRef.current = h.id\n pause()\n if (controls) controls.enabled = false\n ;(e.target as Element).setPointerCapture(e.pointerId)\n }}\n onPointerMove={onHandleDrag}\n onPointerUp={(e) => {\n if (!draggingRef.current) return\n draggingRef.current = null\n if (controls) controls.enabled = true\n ;(e.target as Element).releasePointerCapture(e.pointerId)\n props.onBehaviorChange?.({ ...overridesRef.current })\n }}\n >\n <sphereGeometry args={[0.035, 16, 16]} />\n <meshBasicMaterial color=\"#4f7cff\" depthTest={false} transparent opacity={0.9} />\n </mesh>\n ))}\n </group>\n )\n})\n\n/** Expand the config into the deformer stack that should run this frame. */\nfunction buildStack(\n config: PaperConfig,\n overrides: Record<string, unknown>,\n behavior?: Behavior | null,\n t = 0,\n): DeformerInstance[] | null {\n // Cloth owns the vertices — no deformer stack.\n if (typeof config.physics === 'object') return null\n const idle =\n typeof config.physics === 'string' && config.physics !== 'none'\n ? getIdlePreset(config.physics as IdleName)\n : null\n const idleStack = idle?.stack?.() ?? []\n\n let shapeStack: DeformerInstance[] = []\n if (config.deformers) {\n // Raw deformer stack wins — it's the Advanced fork of a behavior.\n shapeStack = resolveDeformerStack(config.deformers)\n } else if (config.behavior) {\n const b = behavior ?? getBehavior(config.behavior.type)\n let options: Record<string, unknown> = { ...config.behavior, ...overrides }\n if (b.loop) options = { ...options, ...b.loop(options, t) }\n shapeStack = b.stack(options, config.sheet)\n }\n\n const combined = [...shapeStack, ...idleStack]\n return combined.length > 0 ? combined : null\n}\n","import { z } from 'zod'\nimport { mergeConfig } from './merge'\nimport { peelOptionsSchema } from '../behaviors/peel'\nimport { unrollOptionsSchema } from '../behaviors/unroll'\nimport { flipOptionsSchema } from '../behaviors/flip'\nimport { letterFoldOptionsSchema } from '../behaviors/letter-fold'\nimport { hangOptionsSchema } from '../behaviors/hang'\nimport { flyOptionsSchema } from '../behaviors/fly'\nimport { fallOptionsSchema } from '../behaviors/fall'\nimport { carryOptionsSchema } from '../behaviors/carry'\nimport { flightOptionsSchema } from '../behaviors/flight'\nimport { crumpleBehaviorOptionsSchema } from '../behaviors/crumple'\n\n/**\n * The zod schema is the single source of truth: it validates the public API,\n * generates editor panels, defines the `.paper` preset format, and feeds the docs.\n * If a feature can't serialize into this schema, it waits.\n *\n * Every schema here exports BOTH of its types, and the difference is\n * load-bearing. `z.infer` is the parsed config — every default filled in,\n * every field present — and it is what the renderer reads. `z.input` is what\n * a caller is allowed to write, where anything with a default is optional,\n * and it is what every public prop must take. Handing a component the\n * inferred type instead demands that the caller supply every field of every\n * nested object, which turns the documented one-liner into a type error.\n */\n\n// ── Sheet ────────────────────────────────────────────────────────────────────\n\nexport const sheetSchema = z.object({\n /** World units. A letter sheet is ~1 × 1.4, a receipt ~1 × 2.6. */\n width: z.number().positive().max(20).default(1),\n height: z.number().positive().max(20).default(1.4),\n /** Visual thickness in mm-ish units; drives edge/shadow treatment, not geometry (yet). */\n thickness: z.number().min(0).max(2).default(0.2),\n /**\n * `'auto'` gives the LONG side 72 segments, whatever is on the sheet — a\n * deformer's `minSegments` can only raise that floor, never lower it, so in\n * practice a blank sheet is tessellated exactly as finely as a crumpled\n * one. Set a number to take the decision yourself.\n */\n segments: z.union([z.literal('auto'), z.number().int().min(2).max(256)]).default('auto'),\n cornerRadius: z.number().min(0).max(0.5).default(0),\n})\n\nexport type SheetConfig = z.infer<typeof sheetSchema>\n\n// ── Stock ────────────────────────────────────────────────────────────────────\n\nexport const stockNames = [\n 'printer',\n 'thermal',\n 'kraft',\n 'newsprint',\n 'vellum',\n 'photo-gloss',\n 'sticker',\n] as const\nexport const stockSchema = z.enum(stockNames)\nexport type StockName = z.infer<typeof stockSchema>\n\n// ── Content ──────────────────────────────────────────────────────────────────\n\nconst blankContentBase = z.object({\n type: z.literal('blank'),\n})\n\nconst imageContentBase = z.object({\n type: z.literal('image'),\n src: z.string(),\n fit: z.enum(['cover', 'contain']).default('cover'),\n /** Read by the hidden DOM mirror and the no-WebGL fallback. */\n alt: z.string().optional(),\n})\n\nconst textContentBase = z.object({\n type: z.literal('text'),\n text: z.string().default('Dear reader,'),\n font: z.string().default('Georgia, \"Times New Roman\", serif'),\n /** px at texture resolution (long edge = 1024 logical px before DPR). */\n size: z.number().min(8).max(256).default(44),\n weight: z.number().min(100).max(900).default(400),\n color: z.string().default('#2b2620'),\n align: z.enum(['left', 'center', 'right']).default('left'),\n /** Fraction of the short edge. */\n padding: z.number().min(0).max(0.4).default(0.09),\n lineHeight: z.number().min(0.8).max(3).default(1.45),\n})\n\nconst receiptContentBase = z.object({\n type: z.literal('receipt'),\n store: z.string().default('PAPERLAB'),\n address: z.string().default('124 PAPER ST'),\n items: z.array(z.object({ name: z.string(), price: z.number() })).default([\n { name: 'CURL, TRUE', price: 12 },\n { name: 'ROLL, TIGHT', price: 8.5 },\n { name: 'SHEET, ONE', price: 0.99 },\n ]),\n taxRate: z.number().min(0).max(1).default(0.08),\n barcode: z.boolean().default(true),\n /** Fixed so presets render deterministically; omit for \"now\". */\n timestamp: z.string().optional(),\n footer: z.string().default('KEEP FOR YOUR RECORDS'),\n})\n\n/** What can print on the reverse side (letter front / blank back, printed front / kraft back). */\nexport const backContentSchema = z.discriminatedUnion('type', [\n blankContentBase,\n imageContentBase,\n textContentBase,\n receiptContentBase,\n])\n\nexport type BackContentConfig = z.infer<typeof backContentSchema>\n\nconst withBack = { back: backContentSchema.optional() }\n\nexport const blankContentSchema = blankContentBase.extend(withBack)\nexport const imageContentSchema = imageContentBase.extend(withBack)\nexport const textContentSchema = textContentBase.extend(withBack)\nexport const receiptContentSchema = receiptContentBase.extend(withBack)\n\nexport const contentSchema = z.discriminatedUnion('type', [\n blankContentSchema,\n imageContentSchema,\n textContentSchema,\n receiptContentSchema,\n])\n\nexport type ContentConfig = z.infer<typeof contentSchema>\n/** What a caller may WRITE — defaults still unfilled. This is the prop type. */\nexport type ContentConfigInput = z.input<typeof contentSchema>\n\n// ── Surface ──────────────────────────────────────────────────────────────────\n\nexport const paperEdges = ['top', 'right', 'bottom', 'left'] as const\n\n/**\n * Fragment-side effects, composed in registration order into one shader\n * program. Stocks contribute defaults (thermal → banding + yellowing);\n * explicit surface config overrides per effect.\n */\nexport const surfaceSchema = z.object({\n /** Paper fiber noise, 0..1. */\n grain: z.number().min(0).max(1).optional(),\n /** Light passing through the sheet from behind, 0..1. Stock defaults apply. */\n translucency: z.number().min(0).max(1).optional(),\n /** Torn-edge alpha with a lightened fiber band. */\n deckle: z\n .object({\n edges: z.array(z.enum(paperEdges)).default(['bottom']),\n roughness: z.number().min(0).max(1).default(0.5),\n })\n .optional(),\n /** Visual AO/highlight companion to the fold deformer. */\n creaseLines: z\n .object({\n /** Crease line direction, degrees (0 = horizontal lines). */\n angle: z.number().min(-360).max(360).default(0),\n /** Positions across the sheet, 0..1 fractions. */\n positions: z.array(z.number().min(0).max(1)).default([1 / 3, 2 / 3]),\n strength: z.number().min(0).max(1).default(0.5),\n })\n .optional(),\n /** Yellowing + foxing spots, 0..1. */\n aging: z.number().min(0).max(1).optional(),\n /** Reversed front-content ghost on the backside, 0..1. Stock defaults apply. */\n showThrough: z.number().min(0).max(1).optional(),\n /**\n * Postage-stamp perforation: alpha-punched semicircular holes along chosen\n * edges. `state` flips an edge to a ripped-through profile (torn) — set\n * automatically when a paper detaches from a `sheet` field, manual wins.\n */\n perforation: z\n .object({\n edges: z.union([z.array(z.enum(paperEdges)), z.literal('all')]).default('all'),\n /** World units — default tuned to stamp scale. */\n holeRadius: z.number().min(0.002).max(0.1).default(0.016),\n spacing: z.number().min(0.01).max(0.5).default(0.055),\n state: z\n .object({\n top: z.enum(['intact', 'torn']).optional(),\n right: z.enum(['intact', 'torn']).optional(),\n bottom: z.enum(['intact', 'torn']).optional(),\n left: z.enum(['intact', 'torn']).optional(),\n })\n .default({}),\n })\n .optional(),\n})\n\nexport type SurfaceConfig = z.infer<typeof surfaceSchema>\nexport type SurfaceConfigInput = z.input<typeof surfaceSchema>\nexport type PaperEdge = (typeof paperEdges)[number]\n\n// ── Behavior & deformers ─────────────────────────────────────────────────────\n\nexport const behaviorConfigSchema = z.discriminatedUnion('type', [\n peelOptionsSchema.extend({ type: z.literal('peel') }),\n unrollOptionsSchema.extend({ type: z.literal('unroll') }),\n flipOptionsSchema.extend({ type: z.literal('flip') }),\n letterFoldOptionsSchema.extend({ type: z.literal('letter-fold') }),\n hangOptionsSchema.extend({ type: z.literal('hang') }),\n flyOptionsSchema.extend({ type: z.literal('fly') }),\n fallOptionsSchema.extend({ type: z.literal('fall') }),\n carryOptionsSchema.extend({ type: z.literal('carry') }),\n flightOptionsSchema.extend({ type: z.literal('flight') }),\n crumpleBehaviorOptionsSchema.extend({ type: z.literal('crumple') }),\n])\n\nexport type BehaviorConfig = z.infer<typeof behaviorConfigSchema>\nexport type BehaviorConfigInput = z.input<typeof behaviorConfigSchema>\n\n/** Advanced escape hatch: a raw deformer stack (editing one forks the behavior). */\nexport const deformerInstanceSchema = z.object({\n type: z.string(),\n options: z.record(z.unknown()).default({}),\n enabled: z.boolean().default(true),\n})\n\nexport type DeformerInstanceConfig = z.infer<typeof deformerInstanceSchema>\nexport type DeformerInstanceConfigInput = z.input<typeof deformerInstanceSchema>\n\n// ── Physics ──────────────────────────────────────────────────────────────────\n\n/** Kept in sync with `idleNames` in physics/idle.ts (asserted by test). */\nexport const physicsNames = ['none', 'float', 'tumble', 'dangle', 'taped', 'breeze'] as const\n\nexport const clothConfigSchema = z.object({\n type: z.literal('cloth'),\n pins: z.enum(['top-edge', 'top-corners', 'corner', 'none']).default('top-edge'),\n wind: z.number().min(0).max(1).default(0.3),\n /** Bend stiffness: 1 = crisp paper, 0 = silk. */\n stiffness: z.number().min(0).max(1).default(0.8),\n gravity: z.number().min(0).max(2).default(1),\n /** Local-space ground plane the sheet settles onto. */\n floor: z.number().min(-5).max(0).default(-1.4),\n})\n\nexport type ClothConfig = z.infer<typeof clothConfigSchema>\n\nexport const physicsSchema = z.union([\n z.enum(physicsNames),\n z.literal('cloth').transform(() => clothConfigSchema.parse({ type: 'cloth' })),\n clothConfigSchema,\n])\n\nexport type PhysicsConfig = z.infer<typeof physicsSchema>\nexport type PhysicsConfigInput = z.input<typeof physicsSchema>\n\n// ── Scene ────────────────────────────────────────────────────────────────────\n\nexport const lightingNames = ['studio', 'window', 'leaves', 'goldenhour', 'noir', 'nave'] as const\n\n/** Scene-level presentation, serialized with the paper. */\nexport const sceneSchema = z.object({\n lighting: z.enum(lightingNames).default('studio'),\n})\n\nexport type SceneConfig = z.infer<typeof sceneSchema>\nexport type SceneConfigInput = z.input<typeof sceneSchema>\nexport type LightingName = (typeof lightingNames)[number]\n\n// ── Interaction states ───────────────────────────────────────────────────────\n\n/**\n * A state is a set of parameter overrides on the base preset — never a\n * separate preset. The base stays the single source of truth; states are\n * diffs. Triggers are fixed and built-in for v1 (pointer + pick/drop flow);\n * `custom:*` names are the escape hatch for editor v2.\n */\nexport const coreStateNames = ['rest', 'hover', 'pressed', 'picked', 'placed'] as const\nexport type CoreStateName = (typeof coreStateNames)[number]\nexport type StateName = CoreStateName | `custom:${string}`\n\nconst isStateName = (s: string): boolean =>\n (coreStateNames as readonly string[]).includes(s) || s.startsWith('custom:')\n\n// Typed as plain string (not the template-literal union) so PaperConfig stays\n// assignable to PaperConfigInput; the refine still enforces valid names.\nconst stateNameSchema = z.string().refine(isStateName, {\n message: `state names are ${coreStateNames.join(', ')} or \"custom:<name>\"`,\n})\n\nexport const stateTransitionSchema = z.object({\n duration: z.number().min(0).max(5).default(0.35),\n /** GSAP ease name. */\n ease: z.string().default('power2.out'),\n})\n\nexport const stateDefSchema = z.object({\n /** Deep-partial override of the paper schema (behavior params, surface, …). */\n overrides: z.record(z.unknown()).default({}),\n /** Transition INTO this state. */\n transition: stateTransitionSchema.default({}),\n /** Chained actions after arriving. v1: 'emit:<event>' only. */\n onEnter: z.array(z.string().regex(/^emit:[\\w-]+$/, 'v1 actions are \"emit:<event>\"')).default([]),\n})\n\nexport const paperStatesSchema = z.object({\n initial: stateNameSchema.default('rest'),\n states: z\n .record(z.string(), stateDefSchema)\n .default({})\n .refine((rec) => Object.keys(rec).every(isStateName), {\n message: `state names are ${coreStateNames.join(', ')} or \"custom:<name>\"`,\n }),\n /** World-units drag distance that flips pressed → picked (pick-enabled behaviors only). */\n pickThreshold: z.number().min(0.005).max(1).default(0.1),\n})\n\nexport type StateTransitionConfig = z.infer<typeof stateTransitionSchema>\nexport type StateDef = z.infer<typeof stateDefSchema>\nexport type PaperStates = z.infer<typeof paperStatesSchema>\nexport type PaperStatesInput = z.input<typeof paperStatesSchema>\n\n// ── Paper config ─────────────────────────────────────────────────────────────\n\nexport const metaSchema = z.object({\n name: z.string().default('untitled'),\n author: z.string().optional(),\n version: z.string().default('0'),\n tags: z.array(z.string()).default([]),\n})\n\nexport const paperConfigSchema = z\n .object({\n meta: metaSchema.default({}),\n sheet: sheetSchema.default({}),\n stock: stockSchema.default('printer'),\n content: contentSchema.default({ type: 'blank' }),\n /** A behavior OR a raw deformer stack — if both are present, `deformers` wins (it's the fork). */\n behavior: behaviorConfigSchema.optional(),\n deformers: z.array(deformerInstanceSchema).optional(),\n surface: surfaceSchema.default({}),\n physics: physicsSchema.default('none'),\n scene: sceneSchema.default({}),\n onTwos: z.boolean().default(false),\n /** Interaction state machine — overrides-on-base diffs (spec M6 §1). */\n states: paperStatesSchema.optional(),\n })\n .superRefine((config, ctx) => {\n // Cloth owns vertex positions: Shape (behavior/deformers) and Simulation\n // (cloth) are alternatives, not layers. Idle presets compose fine.\n if (typeof config.physics === 'object' && (config.behavior || config.deformers)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['physics'],\n message:\n 'cloth physics and behavior/deformers are exclusive — cloth owns the vertices (pick Shape OR Simulation)',\n })\n }\n // State overrides must stay serializable schema paths: merging them over\n // the base must still parse. (`paperConfigSchema` is initialized by the\n // time any parse runs; the merged candidate carries no `states`, so this\n // cannot recurse.)\n if (config.states) {\n const { states: _states, ...baseSansStates } = config\n for (const [name, def] of Object.entries(config.states.states)) {\n if (!def) continue\n if ((def.overrides as Record<string, unknown>).states !== undefined) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['states', 'states', name, 'overrides'],\n message: 'state overrides cannot override `states` (no nested state machines)',\n })\n continue\n }\n const candidate = mergeConfig(baseSansStates as Record<string, unknown>, def.overrides)\n const result = paperConfigSchema.safeParse(candidate)\n if (!result.success) {\n const first = result.error.issues[0]\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['states', 'states', name, 'overrides'],\n message: `state \"${name}\" overrides don't validate against the paper schema: ${\n first ? `${first.path.join('.')} — ${first.message}` : 'invalid'\n }`,\n })\n }\n }\n }\n })\n\nexport type PaperConfig = z.infer<typeof paperConfigSchema>\nexport type PaperConfigInput = z.input<typeof paperConfigSchema>\n","/**\n * Deep-merge preset config with prop overrides (overrides win; arrays and\n * discriminated unions replace wholesale, plain objects merge).\n *\n * Lives in its own module (not serialize.ts) because the schema needs it to\n * validate state overrides — schema → serialize would be circular.\n */\nexport function mergeConfig<T>(base: T, override: unknown): T {\n if (override === undefined) return base\n if (\n base !== null &&\n override !== null &&\n typeof base === 'object' &&\n typeof override === 'object' &&\n !Array.isArray(base) &&\n !Array.isArray(override)\n ) {\n // A content/behavior union with a different `type` replaces wholesale —\n // merging { type: 'text' } over { type: 'image', src } would leak `src`.\n const b = base as Record<string, unknown>\n const o = override as Record<string, unknown>\n if ('type' in b && 'type' in o && b.type !== o.type) return override as T\n const out: Record<string, unknown> = { ...b }\n for (const key of Object.keys(o)) {\n out[key] = mergeConfig(b[key], o[key])\n }\n return out as T\n }\n return override as T\n}\n\n/**\n * Like {@link mergeConfig}, but an explicit `undefined` DELETES its key instead\n * of being ignored — the semantics a BASE-config write needs: structural\n * setters can clear `behavior`/`deformers` or toggle a surface effect off.\n * Discriminated unions (differing `type`) still replace wholesale.\n */\nexport function mergeWithDeletes<T>(base: T, patch: unknown): T {\n if (\n base !== null &&\n patch !== null &&\n typeof base === 'object' &&\n typeof patch === 'object' &&\n !Array.isArray(base) &&\n !Array.isArray(patch)\n ) {\n const b = base as Record<string, unknown>\n const p = patch as Record<string, unknown>\n if ('type' in b && 'type' in p && b.type !== p.type) return patch as T\n const out: Record<string, unknown> = { ...b }\n for (const [key, value] of Object.entries(p)) {\n if (value === undefined) delete out[key]\n else out[key] = mergeWithDeletes(b[key], value)\n }\n return out as T\n }\n return patch as T\n}\n","import { z } from 'zod'\nimport type { Behavior } from './types'\nimport { cornerNames } from '../deformers/curl'\n\nexport const peelOptionsSchema = z.object({\n progress: z.number().min(0).max(1).default(0.35),\n /** 'auto' resolves per slot in a `sheet` field (outward-facing corner); standalone it means bottom-right. */\n corner: z.enum([...cornerNames, 'auto']).default('bottom-right'),\n /** Curl sharpness — small is a tight dog-ear, large a soft lift. */\n radius: z.number().min(0.05).max(0.6).default(0.16),\n})\n\nexport type PeelOptions = z.infer<typeof peelOptionsSchema>\n\nconst CORNER_UV: Record<(typeof cornerNames)[number], [number, number]> = {\n 'top-left': [0, 1],\n 'top-right': [1, 1],\n 'bottom-left': [0, 0],\n 'bottom-right': [1, 0],\n}\n\n/** Fields resolve 'auto' per slot; anywhere else it falls back to the default corner. */\nconst concreteCorner = (c: PeelOptions['corner']) => (c === 'auto' ? 'bottom-right' : c)\n\n/** A corner lifts and curls back — the hero-image hover peel. */\nexport const peel: Behavior<PeelOptions> = {\n id: 'peel',\n label: 'Peel',\n defaults: peelOptionsSchema.parse({}),\n optionsSchema: peelOptionsSchema,\n progressParam: 'progress',\n duration: 2.2,\n loopMode: 'yoyo',\n stack(o) {\n // A deep peel lifts on a softer cylinder — a fixed tight radius would\n // wind the sheet into a dart. Growing the radius with progress keeps the\n // curl reading as a page lift at every depth.\n return [\n {\n type: 'curl',\n options: {\n corner: concreteCorner(o.corner),\n amount: o.progress,\n radius: o.radius + o.progress * 0.3,\n skew: 0,\n },\n },\n ]\n },\n handles: [\n {\n id: 'corner',\n anchor: (o) => CORNER_UV[concreteCorner(o.corner)],\n drag(local, o, sheet) {\n // Pull toward the sheet center = more peel: distance from the flat\n // corner along the inward diagonal, normalized to half the diagonal.\n const [ux, uy] = CORNER_UV[concreteCorner(o.corner)]\n const cx = (ux - 0.5) * sheet.width\n const cy = (uy - 0.5) * sheet.height\n const diag = Math.hypot(sheet.width, sheet.height)\n const inX = -cx / Math.hypot(cx, cy)\n const inY = -cy / Math.hypot(cx, cy)\n const dist = (local.x - cx) * inX + (local.y - cy) * inY\n return { progress: Math.min(1, Math.max(0, dist / (diag * 0.5))) }\n },\n },\n ],\n}\n","import { z } from 'zod'\nimport type { Deformer } from './types'\n\nexport const cornerNames = ['top-left', 'top-right', 'bottom-left', 'bottom-right'] as const\n\nexport const curlOptionsSchema = z.object({\n corner: z.enum(cornerNames).default('bottom-right'),\n /** How far the curl has traveled from the corner, as a fraction of the diagonal. */\n amount: z.number().min(0).max(1).default(0.35),\n /** Cylinder radius — curl sharpness. */\n radius: z.number().min(0.02).max(1).default(0.16),\n /** Skew of the fold line away from the corner diagonal, degrees. */\n skew: z.number().min(-40).max(40).default(0),\n})\n\nexport type CurlOptions = z.infer<typeof curlOptionsSchema>\n\nconst DEG = Math.PI / 180\n\nconst CORNER_SIGNS: Record<(typeof cornerNames)[number], [number, number]> = {\n 'top-left': [-1, 1],\n 'top-right': [1, 1],\n 'bottom-left': [-1, -1],\n 'bottom-right': [1, -1],\n}\n\n/**\n * Corner-anchored cylinder wrap — the peel/dog-ear deformer, and the\n * crown-jewel realism case: the mesh genuinely wraps the cylinder so content\n * bends with perfect continuity and the backside becomes visible.\n *\n * The fold line runs perpendicular to the corner diagonal and travels inward\n * with `amount`; everything cornerward of it wraps around the cylinder.\n */\nexport const curl: Deformer<CurlOptions> = {\n id: 'curl',\n label: 'Curl',\n defaults: curlOptionsSchema.parse({}),\n optionsSchema: curlOptionsSchema,\n geometry: { minSegments: 48 },\n displace(out, _uv, o, ctx) {\n const [sx, sy] = CORNER_SIGNS[o.corner]\n const { width, height } = ctx.sheet\n const cx = (sx * width) / 2\n const cy = (sy * height) / 2\n\n // Outward direction: from sheet center toward the corner, plus skew.\n const diag = Math.hypot(width, height)\n const baseX = (sx * width) / diag\n const baseY = (sy * height) / diag\n const skew = o.skew * DEG\n const cosK = Math.cos(skew)\n const sinK = Math.sin(skew)\n const dirX = baseX * cosK - baseY * sinK\n const dirY = baseX * sinK + baseY * cosK\n\n // Signed distance past the fold line (fold travels inward with amount).\n const travel = o.amount * diag * 0.5\n const e = (out.x - cx) * dirX + (out.y - cy) * dirY\n const s = e + travel\n if (s <= 0) return\n\n const theta = s / o.radius\n const sin = Math.sin(theta)\n const cos = Math.cos(theta)\n const boundary = e - s // = -travel\n const newE = boundary + (o.radius - out.z) * sin\n const newZ = o.radius * (1 - cos) + out.z * cos\n\n out.x += dirX * (newE - e)\n out.y += dirY * (newE - e)\n out.z = newZ\n },\n glsl: {\n chunk: /* glsl */ `\nvoid FN(inout vec3 p, vec2 uv, float t) {\n vec2 c = U_cornerSign * uSheet * 0.5;\n float diag = length(uSheet);\n vec2 base = U_cornerSign * uSheet / diag;\n float cosK = cos(U_skew);\n float sinK = sin(U_skew);\n vec2 dir = vec2(base.x * cosK - base.y * sinK, base.x * sinK + base.y * cosK);\n float travel = U_amount * diag * 0.5;\n float e = dot(p.xy - c, dir);\n float s = e + travel;\n if (s <= 0.0) return;\n float theta = s / U_radius;\n float sn = sin(theta);\n float cs = cos(theta);\n float newE = (e - s) + (U_radius - p.z) * sn;\n float newZ = U_radius * (1.0 - cs) + p.z * cs;\n p.xy += dir * (newE - e);\n p.z = newZ;\n}\n`,\n strength: 'amount',\n uniforms: (o) => {\n const [sx, sy] = CORNER_SIGNS[o.corner]\n return {\n cornerSign: [sx, sy],\n amount: o.amount,\n radius: o.radius,\n skew: o.skew * DEG,\n }\n },\n },\n}\n","import { z } from 'zod'\nimport type { Behavior } from './types'\n\nexport const unrollOptionsSchema = z.object({\n /** 0 = fully rolled cylinder, 1 = flat sheet. */\n progress: z.number().min(0).max(1).default(0.5),\n /** How tightly the paper is wound. */\n tightness: z.number().min(0).max(1).default(0.5),\n /** Idle rocking of the rolled end. */\n sway: z.number().min(0).max(1).default(0.25),\n})\n\nexport type UnrollOptions = z.infer<typeof unrollOptionsSchema>\n\n/**\n * A receipt unrolls from the bottom: the sheet hangs flat from its top edge\n * and the remaining paper is wound in a roll at the bottom. Content bends\n * true around the roll — the reference-image requirement.\n */\nexport const unroll: Behavior<UnrollOptions> = {\n id: 'unroll',\n label: 'Unroll',\n defaults: unrollOptionsSchema.parse({}),\n optionsSchema: unrollOptionsSchema,\n progressParam: 'progress',\n duration: 3,\n loopMode: 'yoyo',\n stack(o, sheet) {\n const radius = 0.28 - o.tightness * 0.22\n // Rolling direction points down (-y): the region below the boundary is\n // wound. progress sweeps the boundary from the top edge (fully rolled)\n // past the bottom edge (flat, plus slack so the last bit fully relaxes).\n const start = -sheet.height / 2\n const end = sheet.height / 2 + radius * 2\n return [\n {\n type: 'roll',\n options: {\n angle: 270,\n boundary: start + o.progress * (end - start),\n radius,\n spiral: 0.02,\n },\n },\n ]\n },\n loop(o, t) {\n if (o.sway === 0) return {}\n // The rolled tail rocks gently; transient — never persisted.\n const wobble = Math.sin(t * 1.5) * 0.01 * o.sway\n return { progress: Math.min(1, Math.max(0, o.progress + wobble)) }\n },\n handles: [\n {\n id: 'roll-edge',\n anchor: (o) => [0.5, Math.max(0.02, Math.min(0.98, 1 - o.progress))],\n drag(local, _o, sheet) {\n // Dragging the roll edge down unrolls the paper.\n return { progress: Math.min(1, Math.max(0, 0.5 - local.y / sheet.height)) }\n },\n },\n ],\n}\n","import { z } from 'zod'\nimport type { Behavior } from './types'\n\nexport const flipOptionsSchema = z.object({\n /** 0 = flat, 1 = page fully turned over the spine. */\n progress: z.number().min(0).max(1).default(0.3),\n /** Which edge is the spine. */\n spine: z.enum(['left', 'right']).default('left'),\n /** Softness of the turning curl. */\n radius: z.number().min(0.1).max(0.8).default(0.3),\n})\n\nexport type FlipOptions = z.infer<typeof flipOptionsSchema>\n\n/**\n * A page turn: the free edge curls up and rolls over toward the spine —\n * the roll deformer with its boundary swept across the page.\n */\nexport const flip: Behavior<FlipOptions> = {\n id: 'flip',\n label: 'Flip',\n defaults: flipOptionsSchema.parse({}),\n optionsSchema: flipOptionsSchema,\n progressParam: 'progress',\n duration: 1.8,\n loopMode: 'yoyo',\n stack(o, sheet) {\n // Rolling direction points at the free edge; the boundary starts past\n // the free edge (flat) and sweeps to the spine (fully turned).\n const angle = o.spine === 'left' ? 0 : 180\n const start = sheet.width / 2\n const end = -sheet.width / 2\n return [\n {\n type: 'roll',\n options: {\n angle,\n boundary: start + o.progress * (end - start),\n radius: o.radius,\n spiral: 0,\n },\n },\n ]\n },\n handles: [\n {\n id: 'free-edge',\n anchor: (o) => (o.spine === 'left' ? [0.98, 0.5] : [0.02, 0.5]),\n drag(local, o, sheet) {\n // Dragging the free edge toward the spine turns the page.\n const x = o.spine === 'left' ? local.x : -local.x\n return { progress: Math.min(1, Math.max(0, 0.5 - x / sheet.width)) }\n },\n },\n ],\n}\n","import { z } from 'zod'\nimport type { Behavior } from './types'\n\nexport const letterFoldOptionsSchema = z.object({\n /** 0 = flat letter, 1 = fully tri-folded. */\n progress: z.number().min(0).max(1).default(0.4),\n /** Softness of the two creases. */\n crease: z.number().min(0).max(1).default(0.3),\n})\n\nexport type LetterFoldOptions = z.infer<typeof letterFoldOptionsSchema>\n\n/**\n * The classic tri-fold: the bottom third folds up first, then the top third\n * folds down over it. Two fold deformers stacked — order is the physics.\n */\nexport const letterFold: Behavior<LetterFoldOptions> = {\n id: 'letter-fold',\n label: 'Letter fold',\n defaults: letterFoldOptionsSchema.parse({}),\n optionsSchema: letterFoldOptionsSchema,\n progressParam: 'progress',\n duration: 2.6,\n loopMode: 'yoyo',\n stack(o, sheet) {\n const radius = 0.02 + o.crease * 0.06\n // The bottom flap leads, the top flap follows slightly behind so the\n // motion reads as two deliberate folds, not one collapse.\n const bottom = Math.min(1, o.progress * 1.25)\n const top = Math.max(0, o.progress * 1.25 - 0.25)\n return [\n {\n // Bottom third folds up and over (fold travels downward from -h/6).\n type: 'fold',\n options: {\n angle: 270,\n offset: sheet.height / 6,\n foldAngle: bottom * 165,\n radius,\n },\n },\n {\n // Top third folds down across the (already folded) bottom flap.\n type: 'fold',\n options: {\n angle: 90,\n offset: sheet.height / 6,\n foldAngle: top * 150,\n radius: radius * 1.6,\n },\n },\n ]\n },\n handles: [\n {\n id: 'top-flap',\n anchor: () => [0.5, 1],\n drag(local, _o, sheet) {\n // Pulling the top edge down folds the letter.\n return { progress: Math.min(1, Math.max(0, (sheet.height / 2 - local.y) / sheet.height)) }\n },\n },\n ],\n}\n","import { z } from 'zod'\nimport type { Behavior } from './types'\n\nexport const hangOptionsSchema = z.object({\n /** Wind strength driving the ripple. */\n wind: z.number().min(0).max(1).default(0.4),\n /** Gravity bulge of the hanging sheet. */\n sag: z.number().min(0).max(1).default(0.3),\n})\n\nexport type HangOptions = z.infer<typeof hangOptionsSchema>\n\n/** A poster hanging from its top edge, rippling in wind. */\nexport const hang: Behavior<HangOptions> = {\n id: 'hang',\n label: 'Hang',\n defaults: hangOptionsSchema.parse({}),\n optionsSchema: hangOptionsSchema,\n progressParam: 'wind',\n duration: 4,\n loopMode: 'yoyo',\n stack(o) {\n return [\n { type: 'bend', options: { curvature: 0.15 + o.sag * 0.55, angle: 90 } },\n {\n type: 'wave',\n options: {\n amplitude: o.wind * 0.055,\n wavelength: 0.45,\n speed: 0.9 + o.wind * 0.8,\n angle: 75,\n pinnedEdge: 'top',\n },\n },\n ]\n },\n}\n","import { z } from 'zod'\nimport type { Behavior } from './types'\n\nexport const flyOptionsSchema = z.object({\n /** Ripple energy. */\n flutter: z.number().min(0).max(1).default(0.5),\n /** Aerodynamic arc of the sheet. */\n curve: z.number().min(0).max(1).default(0.4),\n})\n\nexport type FlyOptions = z.infer<typeof flyOptionsSchema>\n\n/** A note carried on air — arched and fluttering. Pair with the `tumble` idle. */\nexport const fly: Behavior<FlyOptions> = {\n id: 'fly',\n label: 'Fly',\n defaults: flyOptionsSchema.parse({}),\n optionsSchema: flyOptionsSchema,\n progressParam: 'flutter',\n duration: 3.5,\n loopMode: 'yoyo',\n stack(o) {\n return [\n { type: 'bend', options: { curvature: 0.25 + o.curve, angle: 0 } },\n {\n type: 'wave',\n options: {\n amplitude: o.flutter * 0.07,\n wavelength: 0.7,\n speed: 1.6,\n angle: 30,\n pinnedEdge: 'none',\n },\n },\n ]\n },\n}\n","import { z } from 'zod'\nimport type { Behavior } from './types'\n\nexport const fallOptionsSchema = z.object({\n /** Air resistance ripple while falling. */\n flutter: z.number().min(0).max(1).default(0.6),\n /** A falling sheet always lifts a corner. */\n curl: z.number().min(0).max(1).default(0.3),\n})\n\nexport type FallOptions = z.infer<typeof fallOptionsSchema>\n\n/** A dropped sheet — corner lifted, rippling. Pair with the `tumble` idle for the descent. */\nexport const fall: Behavior<FallOptions> = {\n id: 'fall',\n label: 'Fall',\n defaults: fallOptionsSchema.parse({}),\n optionsSchema: fallOptionsSchema,\n progressParam: 'flutter',\n duration: 3,\n loopMode: 'yoyo',\n stack(o) {\n return [\n {\n type: 'curl',\n options: { corner: 'top-right', amount: o.curl * 0.4, radius: 0.3, skew: 0 },\n },\n {\n type: 'wave',\n options: {\n amplitude: o.flutter * 0.055,\n wavelength: 0.85,\n speed: 1.3,\n angle: 60,\n pinnedEdge: 'none',\n },\n },\n ]\n },\n}\n","import { z } from 'zod'\nimport type { Behavior } from './types'\nimport { cornerNames } from '../deformers/curl'\n\nexport const carryOptionsSchema = z.object({\n /**\n * The grab point — where the pointer was on the paper at pick time.\n * 'auto' is resolved by the carry controller (usually the peeled corner:\n * continuity from peel → carry is the immersion moment).\n */\n grab: z.enum([...cornerNames, 'auto']).default('auto'),\n /** From stock feel: a stamp is stiff — it flutters, it doesn't flow. */\n stiffness: z.number().min(0).max(1).default(0.7),\n flutter: z.number().min(0).max(1).default(0.5),\n /** How far the paper's yaw trails the drag direction (runtime transform). */\n lag: z.number().min(0).max(1).default(0.35),\n /** Drag-speed drive (0..1). Written live by the carry controller. */\n drive: z.number().min(0).max(1).default(0.25),\n})\n\nexport type CarryOptions = z.infer<typeof carryOptionsSchema>\n\ntype Corner = (typeof cornerNames)[number]\n\nconst concreteGrab = (g: CarryOptions['grab']): Corner => (g === 'auto' ? 'top-left' : g)\n\n/** Bend-axis angle pointing from the grab corner toward the sheet center. */\nconst DROOP_ANGLE: Record<Corner, number> = {\n 'top-left': -45,\n 'top-right': -135,\n 'bottom-left': 45,\n 'bottom-right': 135,\n}\n\n/** The edge the grab corner hangs from — that edge doesn't flutter. */\nconst PIN_EDGE: Record<Corner, 'top' | 'bottom'> = {\n 'top-left': 'top',\n 'top-right': 'top',\n 'bottom-left': 'bottom',\n 'bottom-right': 'bottom',\n}\n\n/**\n * A held paper, alive from motion (spec M6 §4.1, the field/cheap path):\n * droop away from the grab point + drag-velocity flutter. The hero path —\n * cloth with a single pin following the cursor — is the existing\n * `physics: 'cloth'` grab; this behavior is what fields and exports run.\n */\nexport const carry: Behavior<CarryOptions> = {\n id: 'carry',\n label: 'Carry',\n defaults: carryOptionsSchema.parse({}),\n optionsSchema: carryOptionsSchema,\n progressParam: 'drive',\n duration: 2.4,\n loopMode: 'yoyo',\n stack(o) {\n const grab = concreteGrab(o.grab)\n // Softer paper droops harder from the pinch; motion adds a touch more.\n const droop = (1 - o.stiffness) * 1.6 + o.drive * 0.35\n return [\n {\n type: 'bend',\n options: { curvature: -droop, angle: DROOP_ANGLE[grab] },\n },\n {\n type: 'wave',\n options: {\n amplitude: o.flutter * (0.012 + o.drive * 0.085),\n wavelength: 0.55,\n speed: 1.4 + o.drive * 1.8,\n angle: DROOP_ANGLE[grab],\n pinnedEdge: PIN_EDGE[grab],\n },\n },\n ]\n },\n}\n","import { z } from 'zod'\nimport type { Behavior } from './types'\nimport { flightPose } from '../physics/aero'\n\nexport const flightOptionsSchema = z.object({\n /** Directional wind vector — paper travels ACROSS the scene, not just down. */\n wind: z\n .tuple([z.number().min(-2).max(2), z.number().min(-2).max(2), z.number().min(-2).max(2)])\n .default([0.6, 0.08, 0]),\n gustiness: z.number().min(0).max(1).default(0.4),\n tumble: z.number().min(0).max(1).default(0.6),\n /** 'loop' is a seamless idle cycle; 'drift' travels along the wind. */\n path: z.enum(['drift', 'loop']).default('drift'),\n /** Drift only: exit the scene → re-enter the opposite side. */\n respawn: z.boolean().default(true),\n /** Half-extent of the travel before respawn wraps it. */\n range: z.number().min(0.5).max(12).default(3.5),\n})\n\nexport type FlightOptions = z.infer<typeof flightOptionsSchema>\n\n/**\n * Untethered paper carried across the scene on the wind (spec M6 §4.2) —\n * the falling-leaf tumble core + directional travel + lift. Transform +\n * deformer based, so it's instancing-safe: a `scatter` layout + `flight`\n * idle = papers blowing through a hero section.\n */\nexport const flight: Behavior<FlightOptions> = {\n id: 'flight',\n label: 'Flight',\n defaults: flightOptionsSchema.parse({}),\n optionsSchema: flightOptionsSchema,\n progressParam: 'tumble',\n duration: 6,\n loopMode: 'yoyo',\n stack(o) {\n // The sheet itself arcs and ripples; travel/tumble live in `transform`.\n return [\n { type: 'bend', options: { curvature: 0.35 + o.tumble * 0.4, angle: 20 } },\n {\n type: 'wave',\n options: {\n amplitude: 0.02 + o.gustiness * 0.03,\n wavelength: 0.8,\n speed: 1.1 + o.gustiness,\n angle: 35,\n pinnedEdge: 'none',\n },\n },\n ]\n },\n transform(o, t, pose) {\n flightPose(t, o, 0, pose)\n },\n}\n","/**\n * The shared fake-aerodynamics core (spec M6 §4): velocity-linked lift +\n * curated noise, per v0.2's \"reads more real than a true sim\" doctrine.\n * Pure math, no three.js, no allocation in the per-frame paths — `carry`\n * and `flight` both source their motion here.\n */\n\nexport interface AeroPose {\n position: [number, number, number]\n rotation: [number, number, number]\n}\n\n/**\n * Critically-damped spring toward a target — the carry pin's cursor\n * follow. Mutates `state` in place; returns nothing.\n */\nexport interface DampedValue {\n value: number\n velocity: number\n}\n\nexport function dampTo(state: DampedValue, target: number, smoothing: number, dt: number): void {\n // Critically damped: ω from smoothing (≈ time to close 90% of the gap).\n const omega = 2 / Math.max(smoothing, 1e-4)\n const x = omega * dt\n const exp = 1 / (1 + x + 0.48 * x * x + 0.235 * x * x * x)\n const change = state.value - target\n const temp = (state.velocity + omega * change) * dt\n state.velocity = (state.velocity - omega * temp) * exp\n state.value = target + (change + temp) * exp\n}\n\n/** Coherent gust factor in [1-g, 1+g] — curated, seeded, cheap. */\nexport function gust(t: number, seed: number, gustiness: number): number {\n const n =\n Math.sin(t * 1.7 + seed * 12.9898) * 0.6 +\n Math.sin(t * 0.53 + seed * 78.233) * 0.3 +\n Math.sin(t * 3.1 + seed * 3.7) * 0.1\n return 1 + n * gustiness\n}\n\nexport interface FlightParams {\n wind: [number, number, number]\n gustiness: number\n tumble: number\n path: 'drift' | 'loop'\n /** Exit the scene → re-enter the opposite side (drift only). */\n respawn: boolean\n /** Half-extent of the drift travel before respawn wraps it. */\n range: number\n}\n\n/**\n * Free paper on the wind: the falling-leaf tumble core + a directional wind\n * vector + lift, so paper travels ACROSS, not just down. A pure function of\n * time and phase — instancing-safe, deterministic, loopable.\n */\nexport function flightPose(t: number, o: FlightParams, phase: number, pose: AeroPose): void {\n const g = gust(t + phase * 7.3, phase, o.gustiness)\n const time = t + phase * 11.7\n\n if (o.path === 'loop') {\n // A seamless closed circuit: travel scaled by the wind vector.\n const s = Math.max(0.2, Math.hypot(o.wind[0], o.wind[1], o.wind[2]))\n const a = time * 0.35\n pose.position[0] = Math.sin(a) * o.range * 0.8 * Math.sign(o.wind[0] || 1)\n pose.position[1] = Math.sin(a * 2) * o.range * 0.18 * s\n pose.position[2] = Math.cos(a) * o.range * 0.35\n } else {\n // Drift: travel along the wind; respawn wraps the along-wind coordinate.\n const travel = time * 0.55 * g\n const wrap = (v: number, r: number) => (o.respawn ? ((((v + r) % (2 * r)) + 2 * r) % (2 * r)) - r : v)\n pose.position[0] = wrap(o.wind[0] * travel, o.range)\n pose.position[1] = wrap(o.wind[1] * travel, o.range * 0.6) + Math.sin(time * 1.3) * 0.08 * g\n pose.position[2] = wrap(o.wind[2] * travel, o.range)\n }\n\n // The falling-leaf tumble: see-saw pitch/roll with a lift bob, gust-scaled.\n pose.rotation[0] = Math.sin(time * 0.5 + 1) * 0.65 * o.tumble\n pose.rotation[1] = Math.sin(time * 0.23) * 0.4 * o.tumble\n pose.rotation[2] = Math.sin(time * 0.7) * 0.55 * o.tumble\n pose.position[1] += Math.sin(time * 1.4) * 0.06 * o.tumble * g\n}\n\n/**\n * Carry flutter drive: how much a held paper ripples for a given drag speed\n * (world units/s). Saturates — a violent drag doesn't tear the illusion.\n */\nexport function carryDrive(speed: number): number {\n return Math.min(1, speed * 0.55)\n}\n","import { z } from 'zod'\nimport type { Behavior } from './types'\n\nexport const crumpleBehaviorOptionsSchema = z.object({\n /** 0 = flat sheet, 1 = crushed. */\n progress: z.number().min(0).max(1).default(0.55),\n /** Few big facets at 0, many small ones at 1. */\n coarseness: z.number().min(0).max(1).default(0.35),\n /** How far the sheet curls in on itself as it crushes. */\n ball: z.number().min(0).max(1).default(0.5),\n /** A different crush of the same paper. */\n seed: z.number().int().min(0).max(7).default(0),\n})\n\nexport type CrumpleBehaviorOptions = z.infer<typeof crumpleBehaviorOptionsSchema>\n\n/**\n * A sheet being screwed up in a fist.\n *\n * Two deformers, in this order for a reason: `crumple` reads the flat sheet\n * position to place its creases, so it has to run before anything that moves\n * the sheet around. Crush the paper, then curl the crushed paper — the other\n * way round would crease a curved sheet as if it were still flat.\n */\nexport const crumpleBehavior: Behavior<CrumpleBehaviorOptions> = {\n id: 'crumple',\n label: 'Crumple',\n defaults: crumpleBehaviorOptionsSchema.parse({}),\n optionsSchema: crumpleBehaviorOptionsSchema,\n progressParam: 'progress',\n duration: 2.6,\n loopMode: 'yoyo',\n stack(o) {\n return [\n {\n type: 'crumple',\n options: {\n amount: o.progress,\n scale: 1.5 + o.coarseness * 4.5,\n pull: 0.5,\n seed: o.seed,\n },\n },\n // The sheet closing in on itself. Paper does not crush flat, and\n // without this the result reads as texture rather than as a ball.\n {\n type: 'bend',\n options: { curvature: o.progress * o.ball * 0.9, angle: 35 },\n },\n ]\n },\n}\n","import { paperConfigSchema, type PaperConfig, type PaperConfigInput } from './schema'\n\nexport { mergeConfig, mergeWithDeletes } from './merge'\n\n/** Parse anything preset-shaped (object or JSON string) into a full, defaulted config. */\nexport function parsePreset(input: PaperConfigInput | string): PaperConfig {\n const raw = typeof input === 'string' ? JSON.parse(input) : input\n return paperConfigSchema.parse(raw)\n}\n\n/** Serialize a config to `.paper` JSON. */\nexport function serializePreset(config: PaperConfig): string {\n return JSON.stringify(config, null, 2)\n}\n","import * as THREE from 'three'\nimport type { SheetConfig } from '../config/schema'\n\n/** Longest side gets this many segments in 'auto' mode (hero path). */\nconst AUTO_LONG_SIDE_SEGMENTS = 72\n\n/**\n * Resolve the subdivision grid for a sheet. Deformers can raise the floor via\n * `minSegments` (a tight roll needs density along the roll direction).\n */\nexport function resolveSegments(sheet: SheetConfig, minSegments = 2): [number, number] {\n if (sheet.segments !== 'auto') {\n const s = Math.max(sheet.segments, minSegments)\n return [s, s]\n }\n const long = Math.max(sheet.width, sheet.height)\n const sx = Math.round((sheet.width / long) * AUTO_LONG_SIDE_SEGMENTS)\n const sy = Math.round((sheet.height / long) * AUTO_LONG_SIDE_SEGMENTS)\n return [Math.max(sx, minSegments, 2), Math.max(sy, minSegments, 2)]\n}\n\n/**\n * Geometry factory. The sheet lives in its local XY plane, centered on the\n * origin, facing +Z. Deformers displace these vertices; the base (flat)\n * positions are kept by the caller for re-deformation each frame.\n */\nexport function createSheetGeometry(sheet: SheetConfig, minSegments = 2): THREE.PlaneGeometry {\n const [sx, sy] = resolveSegments(sheet, minSegments)\n return new THREE.PlaneGeometry(sheet.width, sheet.height, sx, sy)\n}\n","import type { StockName } from '../config/schema'\n\n/**\n * A stock is a named bundle of material + geometry defaults — choosing paper\n * at a print shop. Individual controls always override; schema-wise these are\n * just defaults.\n */\nexport interface Stock {\n id: StockName\n label: string\n /** Base tint, also used as the canvas background behind content. */\n color: string\n roughness: number\n /** 0 = opaque. Vellum is translucent. */\n opacity: number\n /**\n * How much light passes THROUGH the sheet when something is behind it,\n * 0..1. Distinct from `opacity`: newsprint is fully opaque to look at and\n * still glows on a lightbox. This is what makes a backlit banner read.\n */\n translucency: number\n /** Ink multiply tint for content drawn on this stock (thermal prints grey-black). */\n inkColor: string\n /** Thermal-printer banding intensity baked into the grain effect. */\n banding: number\n /** Surface effects this stock ships with; explicit surface config overrides per key. */\n defaultSurface: { grain?: number; aging?: number }\n /** Reversed front-content ghost on the backside (thin stocks let ink show). */\n showThrough: number\n /** Glossy near-white glue underside (stickers) — forces showThrough 0. */\n adhesive: boolean\n}\n\nexport const stocks: Record<StockName, Stock> = {\n printer: {\n id: 'printer',\n label: 'Printer',\n color: '#fbfaf7',\n roughness: 0.88,\n opacity: 1,\n translucency: 0.2,\n inkColor: '#222222',\n banding: 0,\n defaultSurface: { grain: 0.12 },\n showThrough: 0,\n adhesive: false,\n },\n thermal: {\n id: 'thermal',\n label: 'Thermal',\n color: '#f6f3e9',\n roughness: 0.62,\n opacity: 1,\n translucency: 0.34,\n inkColor: '#3a3a3a',\n banding: 0.35,\n defaultSurface: { aging: 0.1 },\n showThrough: 0.06,\n adhesive: false,\n },\n kraft: {\n id: 'kraft',\n label: 'Kraft',\n color: '#c9a06c',\n roughness: 0.96,\n opacity: 1,\n translucency: 0.08,\n inkColor: '#33261a',\n banding: 0,\n defaultSurface: { grain: 0.5 },\n showThrough: 0,\n adhesive: false,\n },\n newsprint: {\n id: 'newsprint',\n label: 'Newsprint',\n color: '#e9e4d6',\n roughness: 0.95,\n opacity: 1,\n translucency: 0.38,\n inkColor: '#3d3a34',\n banding: 0,\n defaultSurface: { grain: 0.7, aging: 0.15 },\n showThrough: 0.06,\n adhesive: false,\n },\n vellum: {\n id: 'vellum',\n label: 'Vellum',\n color: '#f4f2ec',\n roughness: 0.42,\n opacity: 0.62,\n translucency: 0.86,\n inkColor: '#4a453d',\n banding: 0,\n defaultSurface: {},\n showThrough: 0.55,\n adhesive: false,\n },\n 'photo-gloss': {\n id: 'photo-gloss',\n label: 'Photo gloss',\n color: '#ffffff',\n roughness: 0.22,\n opacity: 1,\n translucency: 0.03,\n inkColor: '#111111',\n banding: 0,\n defaultSurface: {},\n showThrough: 0,\n adhesive: false,\n },\n // Photo-gloss-like face, glossy near-white glue underside. The default\n // carrier for perforated stamp sheets.\n sticker: {\n id: 'sticker',\n label: 'Sticker',\n color: '#ffffff',\n roughness: 0.3,\n opacity: 1,\n translucency: 0.06,\n inkColor: '#1a1a1a',\n banding: 0,\n defaultSurface: {},\n showThrough: 0,\n adhesive: true,\n },\n}\n\nexport function getStock(name: StockName): Stock {\n return stocks[name]\n}\n","import { paperConfigSchema, type PaperConfig, type PaperConfigInput } from '../schema'\n\n/**\n * Built-in `.paper` presets. A preset is the serialized closure of one Paper —\n * the unit of saving, sharing, and code export. Stored as plain JSON-safe\n * objects, validated on access.\n */\nconst builtins: Record<string, PaperConfigInput> = {\n 'receipt-unroll': {\n meta: { name: 'Receipt unroll', tags: ['receipt', 'unroll', 'hero'] },\n sheet: { width: 1, height: 2.6 },\n stock: 'thermal',\n content: {\n type: 'receipt',\n store: 'nawwara.studio',\n address: '124 Paper St',\n items: [\n { name: 'Curl, true', price: 12 },\n { name: 'Roll, tight', price: 8.5 },\n { name: 'Sheet, one', price: 0.99 },\n ],\n timestamp: '11.07.2026 18:42',\n },\n behavior: { type: 'unroll', progress: 0.55, tightness: 0.55, sway: 0.3 },\n surface: { deckle: { edges: ['bottom'], roughness: 0.6 } },\n },\n 'letter-fold': {\n meta: { name: 'Letter fold', tags: ['fold', 'text'] },\n sheet: { width: 1, height: 1.4 },\n stock: 'printer',\n content: {\n type: 'text',\n text: 'Dear you,\\n\\nSome things are worth folding carefully.\\n\\nYours,\\nN.',\n },\n behavior: { type: 'letter-fold', progress: 0.4, crease: 0.3 },\n surface: { creaseLines: { angle: 0, positions: [1 / 3, 2 / 3], strength: 0.5 } },\n },\n 'vintage-note': {\n meta: { name: 'Vintage note', tags: ['aging', 'text'] },\n sheet: { width: 1.1, height: 1.4 },\n stock: 'newsprint',\n content: {\n type: 'text',\n text: 'FOUND, ONE PAPER ENGINE.\\n\\nReward if returned to the web.',\n font: 'Georgia, serif',\n size: 40,\n },\n behavior: { type: 'peel', progress: 0.18, corner: 'top-right', radius: 0.22 },\n surface: { aging: 0.55, grain: 0.6, deckle: { edges: ['top', 'bottom'], roughness: 0.4 } },\n },\n 'hero-peel': {\n meta: { name: 'Hero peel', tags: ['peel', 'image', 'hero'] },\n sheet: { width: 1.5, height: 1 },\n stock: 'photo-gloss',\n content: {\n type: 'image',\n src: 'https://images.unsplash.com/photo-1501854140801-50d01698950b?w=1200&q=80',\n fit: 'cover',\n },\n behavior: { type: 'peel', progress: 0.35, corner: 'bottom-right', radius: 0.16 },\n },\n 'page-flip': {\n meta: { name: 'Page flip', tags: ['flip', 'text'] },\n sheet: { width: 1, height: 1.4 },\n stock: 'printer',\n content: {\n type: 'text',\n text: 'Chapter One\\n\\nIt was a paper town, and everything in it folded.',\n },\n behavior: { type: 'flip', progress: 0.3, spine: 'left', radius: 0.3 },\n },\n 'hanging-poster': {\n meta: { name: 'Hanging poster', tags: ['hang', 'image', 'wind'] },\n sheet: { width: 1.1, height: 1.55 },\n stock: 'printer',\n content: {\n type: 'image',\n src: 'https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?w=1200&q=80',\n fit: 'cover',\n },\n behavior: { type: 'hang', wind: 0.45, sag: 0.3 },\n },\n 'pinned-sheet': {\n meta: { name: 'Pinned sheet', tags: ['cloth', 'wind', 'interactive'] },\n sheet: { width: 1.2, height: 1.5 },\n stock: 'printer',\n content: {\n type: 'text',\n text: 'Grab me.\\n\\n(cloth: pinned at the top edge,\\nwind from the left)',\n size: 40,\n },\n physics: { type: 'cloth', pins: 'top-edge', wind: 0.45, stiffness: 0.8, gravity: 1, floor: -1.4 },\n },\n 'flying-note': {\n meta: { name: 'Flying note', tags: ['fly', 'tumble', 'text'] },\n sheet: { width: 1, height: 0.7 },\n stock: 'printer',\n content: {\n type: 'text',\n text: 'meet me where\\nthe paper lands',\n size: 52,\n align: 'center',\n padding: 0.16,\n },\n behavior: { type: 'fly', flutter: 0.55, curve: 0.45 },\n physics: 'tumble',\n },\n 'blank-sheet': {\n meta: { name: 'Blank sheet', tags: ['starter'] },\n stock: 'printer',\n },\n // The M6 driving use case: one stamp of the 2×5 block. Hover peels the\n // outward-facing corner ('auto' resolves per sheet slot), pressing deepens\n // the peel; the perforation tears when it detaches (field auto-wiring).\n 'postage-stamp': {\n meta: { name: 'Postage stamp', tags: ['sticker', 'stamp', 'states', 'sheet'] },\n sheet: { width: 0.64, height: 0.78, thickness: 0.08 },\n stock: 'sticker',\n content: {\n type: 'image',\n src: 'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=600&q=80',\n fit: 'cover',\n alt: 'A forest stamp',\n },\n behavior: { type: 'peel', progress: 0, corner: 'auto', radius: 0.12 },\n surface: { perforation: { edges: 'all', holeRadius: 0.014, spacing: 0.05 } },\n states: {\n initial: 'rest',\n states: {\n hover: {\n overrides: { behavior: { progress: 0.22 } },\n transition: { duration: 0.25, ease: 'power2.out' },\n },\n pressed: {\n overrides: { behavior: { progress: 0.5 } },\n transition: { duration: 0.16, ease: 'power3.out' },\n },\n // Picked is auto-choreographed at pick time (carry hanging from the\n // peeled corner); placed announces itself for a host postmark overlay.\n placed: { overrides: {}, onEnter: ['emit:postmark'] },\n },\n pickThreshold: 0.08,\n },\n },\n 'photo-print': {\n meta: { name: 'Photo print', tags: ['image', 'starter'] },\n sheet: { width: 1.2, height: 0.9 },\n stock: 'photo-gloss',\n content: {\n type: 'image',\n src: 'https://images.unsplash.com/photo-1501854140801-50d01698950b?w=1200&q=80',\n fit: 'cover',\n },\n // No print lies perfectly flat. A shade of bow is the whole difference\n // between a sheet of paper and a rectangle — and since this is the field\n // starter, it is what a layout's per-sheet bias has to scale.\n deformers: [{ type: 'bend', options: { curvature: 0.35, angle: 0 } }],\n },\n 'crumpled-note': {\n meta: { name: 'Crumpled note', tags: ['crumple', 'text', 'handled'] },\n sheet: { width: 1.1, height: 1.4 },\n stock: 'printer',\n content: {\n type: 'text',\n text: 'I wrote it out three times\\nand threw all three away.',\n size: 42,\n },\n behavior: { type: 'crumple', progress: 0.62, coarseness: 0.4, ball: 0.55 },\n // Handled paper is dirty paper: the grain is what stops the facets\n // reading as folded plastic.\n surface: { grain: 0.5, aging: 0.18 },\n },\n 'typed-note': {\n meta: { name: 'Typed note', tags: ['text', 'starter'] },\n sheet: { width: 1, height: 1.4 },\n stock: 'printer',\n content: {\n type: 'text',\n text: 'Dear reader,\\n\\nPaper is the product. Everything else hangs off the sheet.\\n\\n— Paperlab',\n },\n },\n}\n\n/** User presets registered at runtime (the editor persists these to localStorage). */\nconst userPresets = new Map<string, PaperConfigInput>()\n\nexport function getPreset(name: string): PaperConfig {\n const raw = builtins[name] ?? userPresets.get(name)\n if (!raw) {\n throw new Error(`[paperlab] Unknown preset \"${name}\". Registered: ${listPresets().join(', ')}`)\n }\n return paperConfigSchema.parse(raw)\n}\n\n/** Register a user preset (validated). Built-in names are reserved. */\nexport function registerPreset(name: string, input: PaperConfigInput): void {\n if (name in builtins) {\n throw new Error(`[paperlab] \"${name}\" is a built-in preset — pick another name.`)\n }\n paperConfigSchema.parse(input) // fail fast on invalid configs\n userPresets.set(name, input)\n}\n\nexport function unregisterPreset(name: string): void {\n userPresets.delete(name)\n}\n\nexport function isBuiltinPreset(name: string): boolean {\n return name in builtins\n}\n\nexport function listPresets(): string[] {\n return [...Object.keys(builtins), ...userPresets.keys()]\n}\n\n/**\n * A collision-free preset name built from `base`: `base`, else `base 2`,\n * `base 3`, … The disambiguating suffix always grows from the SAME base — a\n * name derived from a synthetic base (e.g. an untitled import → \"imported\")\n * must not fall back to the original when it collides. `taken` reports whether\n * a candidate is already used (built-in or user preset).\n */\nexport function uniquePresetName(base: string, taken: (name: string) => boolean): string {\n if (!taken(base)) return base\n let n = 2\n let name = `${base} ${n}`\n while (taken(name)) name = `${base} ${++n}`\n return name\n}\n","import * as THREE from 'three'\nimport { useEffect, useState } from 'react'\nimport type { BackContentConfig, ContentConfig, SheetConfig } from '../config/schema'\nimport type { Stock } from '../core/stock'\nimport { paintReceipt } from './receipt'\n\n/**\n * All content is composited onto a canvas and applied as a texture — content\n * deforms with the mesh because the mesh deforms, never a 2D trick.\n * Long edge = 1024 logical px × DPR 2 so text stays crisp when curled.\n */\nconst LONG_EDGE = 1024\nconst DPR = 2\n\nexport function contentCanvasSize(sheet: SheetConfig): [number, number] {\n const long = Math.max(sheet.width, sheet.height)\n const w = Math.round((sheet.width / long) * LONG_EDGE * DPR)\n const h = Math.round((sheet.height / long) * LONG_EDGE * DPR)\n return [w, h]\n}\n\nfunction paintBackground(ctx: CanvasRenderingContext2D, w: number, h: number, stock: Stock) {\n ctx.fillStyle = stock.color\n ctx.fillRect(0, 0, w, h)\n}\n\nfunction paintImage(\n ctx: CanvasRenderingContext2D,\n w: number,\n h: number,\n img: HTMLImageElement,\n fit: 'cover' | 'contain',\n) {\n const scale =\n fit === 'cover' ? Math.max(w / img.width, h / img.height) : Math.min(w / img.width, h / img.height)\n const dw = img.width * scale\n const dh = img.height * scale\n ctx.drawImage(img, (w - dw) / 2, (h - dh) / 2, dw, dh)\n}\n\nfunction paintText(\n ctx: CanvasRenderingContext2D,\n w: number,\n h: number,\n content: Extract<ContentConfig, { type: 'text' }>,\n stock: Stock,\n) {\n const size = content.size * DPR\n const pad = content.padding * Math.min(w, h)\n ctx.font = `${content.weight} ${size}px ${content.font}`\n ctx.fillStyle = content.color === '#2b2620' ? stock.inkColor : content.color\n ctx.textBaseline = 'top'\n ctx.textAlign = content.align\n\n const maxWidth = w - pad * 2\n const x = content.align === 'left' ? pad : content.align === 'right' ? w - pad : w / 2\n const lineStep = size * content.lineHeight\n\n // Word-wrap each paragraph (explicit \\n preserved).\n let y = pad\n for (const paragraph of content.text.split('\\n')) {\n let line = ''\n for (const word of paragraph.split(/\\s+/).filter(Boolean)) {\n const attempt = line ? `${line} ${word}` : word\n if (line && ctx.measureText(attempt).width > maxWidth) {\n ctx.fillText(line, x, y)\n y += lineStep\n line = word\n } else {\n line = attempt\n }\n }\n ctx.fillText(line, x, y)\n y += lineStep\n if (y > h - pad) return\n }\n}\n\n/**\n * Render content to a canvas. Synchronous — image content needs a decoded\n * HTMLImageElement passed in (the hook below handles loading).\n */\nexport function renderContentToCanvas(\n content: ContentConfig | BackContentConfig,\n sheet: SheetConfig,\n stock: Stock,\n image?: HTMLImageElement,\n): HTMLCanvasElement {\n const [w, h] = contentCanvasSize(sheet)\n const canvas = document.createElement('canvas')\n canvas.width = w\n canvas.height = h\n const ctx = canvas.getContext('2d')!\n paintBackground(ctx, w, h, stock)\n if (content.type === 'image' && image) paintImage(ctx, w, h, image, content.fit)\n if (content.type === 'text') paintText(ctx, w, h, content, stock)\n if (content.type === 'receipt') paintReceipt(ctx, w, h, content, stock)\n return canvas\n}\n\nfunction makeTexture(canvas: HTMLCanvasElement): THREE.CanvasTexture {\n const tex = new THREE.CanvasTexture(canvas)\n tex.colorSpace = THREE.SRGBColorSpace\n tex.anisotropy = 8\n tex.generateMipmaps = true\n return tex\n}\n\n/**\n * React hook: content config → texture. Re-renders only on content change,\n * never per-frame. Waits for image decode / document.fonts.ready.\n */\nexport function useContentTexture(\n content: ContentConfig | BackContentConfig | undefined,\n sheet: SheetConfig,\n stock: Stock,\n): THREE.CanvasTexture | null {\n const [texture, setTexture] = useState<THREE.CanvasTexture | null>(null)\n const key = JSON.stringify({ content: content ?? null, w: sheet.width, h: sheet.height, stock: stock.id })\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: key serializes the content, sheet and stock the canvas draws from.\n useEffect(() => {\n let disposed = false\n let tex: THREE.CanvasTexture | null = null\n\n if (!content) {\n setTexture(null)\n return\n }\n\n const commit = (canvas: HTMLCanvasElement) => {\n if (disposed) return\n tex = makeTexture(canvas)\n setTexture(tex)\n }\n\n if (content.type === 'image') {\n const img = new Image()\n img.crossOrigin = 'anonymous'\n img.onload = () => commit(renderContentToCanvas(content, sheet, stock, img))\n img.src = content.src\n } else if (content.type === 'text' || content.type === 'receipt') {\n // Fonts may still be loading on first paint; render after they settle.\n document.fonts.ready.then(() => commit(renderContentToCanvas(content, sheet, stock)))\n } else {\n commit(renderContentToCanvas(content, sheet, stock))\n }\n\n return () => {\n disposed = true\n tex?.dispose()\n }\n }, [key])\n\n return texture\n}\n","import type { ContentConfig } from '../config/schema'\nimport type { Stock } from '../core/stock'\n\nexport type ReceiptContent = Extract<ContentConfig, { type: 'receipt' }>\n\nexport interface ReceiptTotals {\n subtotal: number\n tax: number\n total: number\n}\n\nexport function receiptTotals(content: ReceiptContent): ReceiptTotals {\n const subtotal = content.items.reduce((sum, item) => sum + item.price, 0)\n const tax = subtotal * content.taxRate\n return { subtotal, tax, total: subtotal + tax }\n}\n\n/** Deterministic bar widths from a string — stylized Code-128 look. */\nexport function barcodeBars(seed: string): number[] {\n // Not a scannable Code 128 (real encoding tracked for later) — but the\n // start/stop guard structure and 1–4 module widths match the real thing.\n let h = 2166136261\n for (let i = 0; i < seed.length; i++) {\n h ^= seed.charCodeAt(i)\n h = Math.imul(h, 16777619)\n }\n const bars: number[] = [2, 1, 1, 4] // start guard\n for (let i = 0; i < 30; i++) {\n h = Math.imul(h ^ (h >>> 15), 2246822519)\n bars.push(1 + (Math.abs(h) % 4))\n }\n bars.push(2, 3, 3, 1, 1, 2) // stop guard\n return bars\n}\n\nconst money = (v: number) => v.toFixed(2)\n\n/**\n * The procedural receipt: store header, line items, totals, barcode,\n * timestamp, footer. Pairs with `deckle: { edges: ['bottom'] }` for the\n * jagged thermal tear. One-liner meme potential by design.\n */\nexport function paintReceipt(\n ctx: CanvasRenderingContext2D,\n w: number,\n h: number,\n content: ReceiptContent,\n stock: Stock,\n): void {\n const ink = stock.inkColor\n const pad = w * 0.09\n const colWidth = w - pad * 2\n const base = Math.round(w / 15) // font size scales with receipt width\n const mono = (size: number, weight = 400) => `${weight} ${size}px ui-monospace, Menlo, Consolas, monospace`\n\n let y = h * 0.045\n const line = (step = 1.6) => (y += base * step)\n\n const center = (text: string, size = base, weight = 400) => {\n ctx.font = mono(size, weight)\n ctx.textAlign = 'center'\n ctx.fillText(text, w / 2, y)\n }\n const row = (left: string, right: string, size = base) => {\n ctx.font = mono(size)\n ctx.textAlign = 'left'\n ctx.fillText(left, pad, y)\n ctx.textAlign = 'right'\n ctx.fillText(right, w - pad, y)\n }\n const divider = () => {\n ctx.font = mono(base)\n ctx.textAlign = 'center'\n ctx.fillText('- '.repeat(Math.floor(colWidth / (base * 1.1))).trim(), w / 2, y)\n }\n\n ctx.fillStyle = ink\n ctx.textBaseline = 'top'\n\n center(content.store.toUpperCase(), base * 1.5, 700)\n line(2.4)\n center(content.address.toUpperCase())\n line(1.8)\n divider()\n line(1.8)\n\n for (const item of content.items) {\n row(item.name.toUpperCase(), money(item.price))\n line()\n }\n line(0.4)\n divider()\n line(1.8)\n\n const totals = receiptTotals(content)\n row('SUBTOTAL', money(totals.subtotal))\n line()\n row(`TAX ${(content.taxRate * 100).toFixed(0)}%`, money(totals.tax))\n line()\n row('TOTAL', money(totals.total), base * 1.15)\n line(2)\n\n center(content.timestamp ?? new Date().toLocaleString('en-GB'), base * 0.9)\n line(2.2)\n\n if (content.barcode) {\n const bars = barcodeBars(content.store)\n const modules = bars.reduce((a, b) => a + b, 0)\n const module = (colWidth * 0.85) / modules\n const barH = base * 3.2\n let x = (w - modules * module) / 2\n bars.forEach((width, i) => {\n if (i % 2 === 0) ctx.fillRect(x, y, width * module, barH)\n x += width * module\n })\n y += barH\n line(1.8)\n }\n\n center(content.footer.toUpperCase(), base * 0.9)\n}\n","import * as THREE from 'three'\nimport type { DeformerContext, DeformerInstance } from './types'\nimport { getDeformer } from './registry'\n\n// Preallocated scratch — deformer loops are allocation-free.\nconst scratchPos = new THREE.Vector3()\nconst scratchUv = new THREE.Vector2()\n\n/**\n * Run an ordered deformer stack over a sheet geometry: each vertex starts\n * from its flat base position and flows through every enabled deformer in\n * order. Writes positions in place and recomputes normals.\n */\nexport function applyDeformerStack(\n geometry: THREE.BufferGeometry,\n basePositions: Float32Array,\n stack: DeformerInstance[],\n ctx: DeformerContext,\n): void {\n const position = geometry.attributes.position as THREE.BufferAttribute\n const uv = geometry.attributes.uv as THREE.BufferAttribute\n const array = position.array as Float32Array\n const active = stack.filter((i) => i.enabled !== false)\n\n for (let v = 0; v < position.count; v++) {\n const i3 = v * 3\n scratchPos.set(basePositions[i3]!, basePositions[i3 + 1]!, basePositions[i3 + 2]!)\n scratchUv.set(uv.getX(v), uv.getY(v))\n for (const instance of active) {\n getDeformer(instance.type).displace(scratchPos, scratchUv, instance.options, ctx)\n }\n array[i3] = scratchPos.x\n array[i3 + 1] = scratchPos.y\n array[i3 + 2] = scratchPos.z\n }\n\n position.needsUpdate = true\n geometry.computeVertexNormals()\n}\n\n/** A single point through the stack — used for handle anchors and tests. */\nexport function displacePoint(\n point: THREE.Vector3,\n uvX: number,\n uvY: number,\n stack: DeformerInstance[],\n ctx: DeformerContext,\n): THREE.Vector3 {\n scratchUv.set(uvX, uvY)\n for (const instance of stack) {\n if (instance.enabled === false) continue\n getDeformer(instance.type).displace(point, scratchUv, instance.options, ctx)\n }\n return point\n}\n\n/** The densest grid any deformer in the stack asks for. */\nexport function stackMinSegments(stack: DeformerInstance[]): number {\n let min = 2\n for (const instance of stack) {\n const req = getDeformer(instance.type).geometry?.minSegments ?? 2\n if (req > min) min = req\n }\n return min\n}\n","import { z } from 'zod'\nimport type { AnyOptions, Deformer, DeformerInstance } from './types'\nimport { roll } from './roll'\nimport { curl } from './curl'\nimport { bend } from './bend'\nimport { fold } from './fold'\nimport { wave } from './wave'\nimport { drape } from './drape'\nimport { crumple } from './crumple'\n\nconst registry = new Map<string, Deformer<AnyOptions>>()\n\n/** Community deformers register here; built-ins are pre-registered. */\nexport function registerDeformer(deformer: Deformer<AnyOptions>): void {\n registry.set(deformer.id, deformer)\n}\n\nexport function getDeformer(id: string): Deformer<AnyOptions> {\n const d = registry.get(id)\n if (!d) {\n throw new Error(`[paperlab] Unknown deformer \"${id}\". Registered: ${[...registry.keys()].join(', ')}`)\n }\n return d\n}\n\nexport function listDeformers(): string[] {\n return [...registry.keys()]\n}\n\nregisterDeformer(roll)\nregisterDeformer(curl)\nregisterDeformer(bend)\nregisterDeformer(fold)\nregisterDeformer(wave)\nregisterDeformer(drape)\nregisterDeformer(crumple)\n\n/**\n * Resolve a raw `deformers` stack — the Advanced fork of a behavior — into\n * instances safe to render.\n *\n * The escape hatch used to pass its options straight through, so a preset\n * naming an option that doesn't exist (`frequency` where wave wants\n * `wavelength`) reached the GLSL builder as `undefined` and died there with\n * a message about `.length`, or reached the CPU path and quietly produced\n * NaN vertices. Parsing through each deformer's own schema turns that into\n * the validation error it always was, and fills in defaults for whatever a\n * hand-written preset left out.\n *\n * Disabled entries keep their slot: the GLSL uniform namespace is indexed by\n * position, so dropping one here would rename every uniform after it.\n */\nexport function resolveDeformerStack(\n raw: { type: string; options?: Record<string, unknown>; enabled?: boolean }[],\n): DeformerInstance[] {\n return raw.map((instance, i) => {\n const deformer = getDeformer(instance.type)\n // Strict: an unknown key here is almost always a typo for a real option,\n // and silently dropping it means the preset renders wrong with no clue\n // why. Every built-in schema is a plain object; anything exotic a\n // community deformer brings is parsed as it comes.\n const schema =\n deformer.optionsSchema instanceof z.ZodObject ? deformer.optionsSchema.strict() : deformer.optionsSchema\n const parsed = schema.safeParse(instance.options ?? {})\n if (!parsed.success) {\n const issue = parsed.error.issues[0]\n throw new Error(\n `[paperlab] deformers[${i}] (\"${instance.type}\"): ${\n issue ? `${issue.path.join('.') || 'options'} — ${issue.message}` : 'invalid options'\n }`,\n )\n }\n return {\n type: instance.type,\n options: parsed.data as Record<string, unknown>,\n enabled: instance.enabled,\n }\n })\n}\n\n/** True if any enabled instance re-deforms every frame (wave etc.). */\nexport function stackIsAnimated(stack: { type: string; enabled?: boolean }[]): boolean {\n return stack.some((i) => i.enabled !== false && registry.get(i.type)?.animated)\n}\n","import { z } from 'zod'\nimport type { Deformer } from './types'\n\nexport const rollOptionsSchema = z.object({\n /** Direction of rolling in the sheet plane, degrees. 0 = +x, 90 = +y. */\n angle: z.number().min(-360).max(360).default(90),\n /** Signed distance (along the roll direction, from sheet center) where the roll begins. */\n boundary: z.number().min(-20).max(20).default(0),\n /** Cylinder radius — sharpness of the roll. */\n radius: z.number().min(0.01).max(2).default(0.12),\n /** Radius growth per radian so multi-turn rolls spiral instead of z-fighting. */\n spiral: z.number().min(0).max(0.2).default(0.015),\n})\n\nexport type RollOptions = z.infer<typeof rollOptionsSchema>\n\nconst DEG = Math.PI / 180\n\n/**\n * Wrap the sheet around a virtual cylinder lying across the roll direction.\n * Everything past `boundary` wraps; the wrap is C¹-continuous at the\n * boundary and preserves arc length (content never stretches).\n *\n * Points arriving with z ≠ 0 (from earlier deformers in the stack) ride\n * along the rolled surface's normal, so stacks compose sanely.\n */\nexport const roll: Deformer<RollOptions> = {\n id: 'roll',\n label: 'Roll',\n defaults: rollOptionsSchema.parse({}),\n optionsSchema: rollOptionsSchema,\n geometry: { minSegments: 48 },\n displace(out, _uv, o) {\n const dirX = Math.cos(o.angle * DEG)\n const dirY = Math.sin(o.angle * DEG)\n const d = out.x * dirX + out.y * dirY\n const s = d - o.boundary\n if (s <= 0) return\n\n const theta = s / o.radius\n const r = o.radius + o.spiral * theta\n const sin = Math.sin(theta)\n const cos = Math.cos(theta)\n // Surface point on the cylinder + incoming z offset along the surface normal.\n const newD = o.boundary + (r - out.z) * sin\n const newZ = r * (1 - cos) + out.z * cos\n\n out.x += dirX * (newD - d)\n out.y += dirY * (newD - d)\n out.z = newZ\n },\n glsl: {\n chunk: /* glsl */ `\nvoid FN(inout vec3 p, vec2 uv, float t) {\n vec2 dir = vec2(cos(U_angle), sin(U_angle));\n float d = dot(p.xy, dir);\n float s = d - U_boundary;\n if (s <= 0.0) return;\n float theta = s / U_radius;\n float r = U_radius + U_spiral * theta;\n float sn = sin(theta);\n float cs = cos(theta);\n float newD = U_boundary + (r - p.z) * sn;\n float newZ = r * (1.0 - cs) + p.z * cs;\n p.xy += dir * (newD - d);\n p.z = newZ;\n}\n`,\n uniforms: (o) => ({\n angle: o.angle * DEG,\n boundary: o.boundary,\n radius: o.radius,\n spiral: o.spiral,\n }),\n },\n}\n","import { z } from 'zod'\nimport type { Deformer } from './types'\n\nexport const bendOptionsSchema = z.object({\n /** 1/radius in world units; sign flips the arc direction. 0 = flat. */\n curvature: z.number().min(-4).max(4).default(0.6),\n /** Bend axis direction in the sheet plane, degrees. 0 bends across x. */\n angle: z.number().min(-360).max(360).default(0),\n})\n\nexport type BendOptions = z.infer<typeof bendOptionsSchema>\n\nconst DEG = Math.PI / 180\nconst EPS = 1e-5\n\n/**\n * `sin(x) − x`, without the cancellation that eats it for small x.\n *\n * The arc's in-plane shift is `r·sin θ − d`, and `d` IS `r·θ` — so for a\n * gentle bend it is a difference of two nearly-equal large numbers, and the\n * answer is the few bits that survive. JS computes that in float64 and gets\n * away with it; the GLSL twin computes it in float32 and does not, which put\n * the two paths 6e-4 apart at low curvature — past the parity gate's epsilon.\n * The series is exact to well under a float32 ulp below |x| = 1 and both\n * implementations take the same branch, so the two paths agree by\n * construction rather than by luck.\n */\nfunction sinMinusX(x: number): number {\n if (Math.abs(x) > 1) return Math.sin(x) - x\n const x2 = x * x\n return ((-x * x2) / 6) * (1 - (x2 / 20) * (1 - (x2 / 42) * (1 - x2 / 72)))\n}\n\n/**\n * Gentle global arc around a cylinder centered on the sheet — a standing\n * paper's lean. Arc-length preserving, like roll, but symmetric about the\n * center instead of one-sided.\n *\n * Written in its cancellation-free form throughout: `r(1 − cos θ)` is\n * `2r·sin²(θ/2)`, and the in-plane shift goes through `sinMinusX`. Same arc,\n * same numbers to sixteen places — it is only the float32 half that could\n * tell the difference, and that is exactly the half the parity gate checks.\n */\nexport const bend: Deformer<BendOptions> = {\n id: 'bend',\n label: 'Bend',\n defaults: bendOptionsSchema.parse({}),\n optionsSchema: bendOptionsSchema,\n geometry: { minSegments: 16 },\n displace(out, _uv, o) {\n if (Math.abs(o.curvature) < EPS) return\n const dirX = Math.cos(o.angle * DEG)\n const dirY = Math.sin(o.angle * DEG)\n const d = out.x * dirX + out.y * dirY\n\n const r = 1 / o.curvature\n const theta = d * o.curvature\n const sin = Math.sin(theta)\n const halfSin = Math.sin(theta * 0.5)\n const z0 = out.z\n\n // (r − z)·sin θ − d, with d = r·θ folded in so the big terms never meet.\n const shift = r * sinMinusX(theta) - z0 * sin\n out.x += dirX * shift\n out.y += dirY * shift\n out.z = 2 * r * halfSin * halfSin + z0 * Math.cos(theta)\n },\n glsl: {\n chunk: /* glsl */ `\nfloat FN_sinm(float x) {\n if (abs(x) > 1.0) return sin(x) - x;\n float x2 = x * x;\n return (-x * x2 / 6.0) * (1.0 - (x2 / 20.0) * (1.0 - (x2 / 42.0) * (1.0 - x2 / 72.0)));\n}\n\nvoid FN(inout vec3 p, vec2 uv, float t) {\n if (abs(U_curvature) < 1e-5) return;\n vec2 dir = vec2(cos(U_angle), sin(U_angle));\n float d = dot(p.xy, dir);\n float r = 1.0 / U_curvature;\n float theta = d * U_curvature;\n float sn = sin(theta);\n float hs = sin(theta * 0.5);\n float z0 = p.z;\n float shift = r * FN_sinm(theta) - z0 * sn;\n p.xy += dir * shift;\n p.z = 2.0 * r * hs * hs + z0 * cos(theta);\n}\n`,\n strength: 'curvature',\n uniforms: (o) => ({ curvature: o.curvature, angle: o.angle * DEG }),\n },\n}\n","import { z } from 'zod'\nimport type { Deformer } from './types'\n\nexport const foldOptionsSchema = z.object({\n /** Direction of the fold travel in the sheet plane, degrees (the crease line runs perpendicular). */\n angle: z.number().min(-360).max(360).default(90),\n /** Signed distance of the crease line from the sheet center, along the travel direction. */\n offset: z.number().min(-20).max(20).default(0),\n /** How far the flap folds over, degrees. 180 = flat against the sheet. */\n foldAngle: z.number().min(-180).max(180).default(90),\n /** Width of the soft hinge — paper never creases to a mathematical edge. */\n radius: z.number().min(0.005).max(0.5).default(0.04),\n})\n\nexport type FoldOptions = z.infer<typeof foldOptionsSchema>\n\nconst DEG = Math.PI / 180\n\n/**\n * Angular crease across a line: within the hinge width the sheet wraps a\n * small cylinder (a roll), beyond it the flap continues rigid at the full\n * fold angle. n folds = n instances stacked (half-fold, letter-fold,\n * accordion). Arc-length preserving like every Paperlab deformer.\n */\nexport const fold: Deformer<FoldOptions> = {\n id: 'fold',\n label: 'Fold',\n defaults: foldOptionsSchema.parse({}),\n optionsSchema: foldOptionsSchema,\n geometry: { minSegments: 48 },\n displace(out, _uv, o) {\n const phi = o.foldAngle * DEG\n if (Math.abs(phi) < 1e-6) return\n const dirX = Math.cos(o.angle * DEG)\n const dirY = Math.sin(o.angle * DEG)\n const d = out.x * dirX + out.y * dirY\n const s = d - o.offset\n if (s <= 0) return\n\n // Signed hinge cylinder: radius R = radius/phi carries the fold\n // direction, so one code path serves folds up and down.\n const R = o.radius / phi\n let newD: number\n let newZ: number\n if (s <= o.radius) {\n // Inside the hinge: identical to a roll of signed radius R.\n const theta = (s / o.radius) * phi\n const sin = Math.sin(theta)\n const cos = Math.cos(theta)\n newD = o.offset + (R - out.z) * sin\n newZ = R * (1 - cos) + out.z * cos\n } else {\n // Past the hinge: rigid flap continuing from the arc's end along its\n // tangent; incoming z rides the rotated surface normal.\n const rest = s - o.radius\n const sin = Math.sin(phi)\n const cos = Math.cos(phi)\n newD = o.offset + R * sin + rest * cos - out.z * sin\n newZ = R * (1 - cos) + rest * sin + out.z * cos\n }\n\n out.x += dirX * (newD - d)\n out.y += dirY * (newD - d)\n out.z = newZ\n },\n glsl: {\n chunk: /* glsl */ `\nvoid FN(inout vec3 p, vec2 uv, float t) {\n if (abs(U_foldAngle) < 1e-6) return;\n vec2 dir = vec2(cos(U_angle), sin(U_angle));\n float d = dot(p.xy, dir);\n float s = d - U_offset;\n if (s <= 0.0) return;\n float R = U_radius / U_foldAngle;\n float newD;\n float newZ;\n if (s <= U_radius) {\n float theta = (s / U_radius) * U_foldAngle;\n float sn = sin(theta);\n float cs = cos(theta);\n newD = U_offset + (R - p.z) * sn;\n newZ = R * (1.0 - cs) + p.z * cs;\n } else {\n float rest = s - U_radius;\n float sn = sin(U_foldAngle);\n float cs = cos(U_foldAngle);\n newD = U_offset + R * sn + rest * cs - p.z * sn;\n newZ = R * (1.0 - cs) + rest * sn + p.z * cs;\n }\n p.xy += dir * (newD - d);\n p.z = newZ;\n}\n`,\n strength: 'foldAngle',\n uniforms: (o) => ({\n angle: o.angle * DEG,\n offset: o.offset,\n foldAngle: o.foldAngle * DEG,\n radius: o.radius,\n }),\n },\n}\n","import { z } from 'zod'\nimport type { Deformer } from './types'\n\nexport const waveOptionsSchema = z.object({\n amplitude: z.number().min(0).max(0.3).default(0.04),\n wavelength: z.number().min(0.05).max(2).default(0.5),\n /** Travel speed; 0 freezes the ripple. */\n speed: z.number().min(0).max(3).default(0.8),\n /** Travel direction in the sheet plane, degrees. */\n angle: z.number().min(-360).max(360).default(90),\n /** Zero the displacement at one edge (a taped/pinned edge doesn't ripple). */\n pinnedEdge: z.enum(['none', 'top', 'bottom', 'left', 'right']).default('none'),\n})\n\nexport type WaveOptions = z.infer<typeof waveOptionsSchema>\n\nconst DEG = Math.PI / 180\nconst TAU = Math.PI * 2\n\n/**\n * Traveling sine displacement with a quieter second harmonic — idle flutter\n * and wind ripple. The only time-driven deformer so far: stacks containing\n * it re-deform every frame.\n */\nexport const wave: Deformer<WaveOptions> = {\n id: 'wave',\n label: 'Wave',\n defaults: waveOptionsSchema.parse({}),\n optionsSchema: waveOptionsSchema,\n geometry: { minSegments: 32 },\n animated: true,\n displace(out, uv, o, ctx) {\n if (o.amplitude === 0) return\n const dirX = Math.cos(o.angle * DEG)\n const dirY = Math.sin(o.angle * DEG)\n const d = out.x * dirX + out.y * dirY\n const phase = (d / o.wavelength - o.speed * ctx.t) * TAU\n let env = 1\n if (o.pinnedEdge === 'top') env = 1 - uv.y\n else if (o.pinnedEdge === 'bottom') env = uv.y\n else if (o.pinnedEdge === 'left') env = uv.x\n else if (o.pinnedEdge === 'right') env = 1 - uv.x\n out.z += o.amplitude * env * (Math.sin(phase) + 0.35 * Math.sin(phase * 2.7 + 1.3))\n },\n glsl: {\n chunk: /* glsl */ `\nvoid FN(inout vec3 p, vec2 uv, float t) {\n if (U_amplitude == 0.0) return;\n vec2 dir = vec2(cos(U_angle), sin(U_angle));\n float d = dot(p.xy, dir);\n float phase = (d / U_wavelength - U_speed * t) * 6.283185307179586;\n float env = 1.0;\n if (U_pin == 1.0) env = 1.0 - uv.y;\n else if (U_pin == 2.0) env = uv.y;\n else if (U_pin == 3.0) env = uv.x;\n else if (U_pin == 4.0) env = 1.0 - uv.x;\n p.z += U_amplitude * env * (sin(phase) + 0.35 * sin(phase * 2.7 + 1.3));\n}\n`,\n strength: 'amplitude',\n uniforms: (o) => ({\n amplitude: o.amplitude,\n wavelength: o.wavelength,\n speed: o.speed,\n angle: o.angle * DEG,\n pin: { none: 0, top: 1, bottom: 2, left: 3, right: 4 }[o.pinnedEdge],\n }),\n },\n}\n","import { z } from 'zod'\nimport type { Deformer } from './types'\n\nexport const drapeOptionsSchema = z.object({\n /** Fold depth at the free edge, world units. */\n amplitude: z.number().min(0).max(0.6).default(0.12),\n /** How many folds run down the drop. */\n folds: z.number().min(0.5).max(16).default(4),\n /**\n * How fast folds deepen away from the pinned edge. 1 is linear; higher\n * holds the top flat and gathers all the movement at the free end, which\n * is what a sheet hung from a rod actually does.\n */\n falloff: z.number().min(0.3).max(4).default(1.6),\n /** How much a second, non-harmonic fold breaks the regularity. */\n irregular: z.number().min(0).max(1).default(0.45),\n /** How much the sheet narrows as its folds deepen. */\n gather: z.number().min(0).max(1).default(0.5),\n pinnedEdge: z.enum(['top', 'bottom']).default('top'),\n})\n\nexport type DrapeOptions = z.infer<typeof drapeOptionsSchema>\n\nconst TAU = Math.PI * 2\n\n/**\n * Hung paper: vertical folds running the length of the drop, shallow at the\n * fixed edge and deepening toward the free one.\n *\n * `wave` can put ripples on a sheet, but a traveling sine is a flag, not a\n * curtain — it kinks the sheet ACROSS its drop and it is uniform end to end.\n * Cloth hung from an edge does the opposite: the folds run WITH the drop and\n * they grow as they get further from whatever is holding the sheet up. Two\n * details do most of the work:\n *\n * - the folds are not harmonic. A pure sine reads as corrugated metal, so a\n * second wave at an incommensurate frequency breaks the repeat.\n * - gathered paper is narrower than flat paper. Pulling the surface toward\n * its centerline in proportion to fold depth is what stops the drape from\n * looking like a texture painted on a rectangle.\n */\nexport const drape: Deformer<DrapeOptions> = {\n id: 'drape',\n label: 'Drape',\n defaults: drapeOptionsSchema.parse({}),\n optionsSchema: drapeOptionsSchema,\n geometry: { minSegments: 48 },\n displace(out, uv, o) {\n if (o.amplitude === 0) return\n // Distance from the pinned edge, 0 at the fixing and 1 at the free end.\n const drop = o.pinnedEdge === 'top' ? 1 - uv.y : uv.y\n const depth = drop ** o.falloff\n const u = uv.x * TAU * o.folds\n const fold = Math.sin(u) + o.irregular * 0.6 * Math.sin(u * 1.7 + 2.1)\n out.z += o.amplitude * depth * fold\n const pinch = o.gather * depth * Math.min(o.amplitude * o.folds * 0.8, 0.6)\n out.x *= 1 - pinch\n },\n glsl: {\n chunk: /* glsl */ `\nvoid FN(inout vec3 p, vec2 uv, float t) {\n if (U_amplitude == 0.0) return;\n float drop = U_pin == 1.0 ? 1.0 - uv.y : uv.y;\n float depth = pow(drop, U_falloff);\n float u = uv.x * 6.283185307179586 * U_folds;\n float fold = sin(u) + U_irregular * 0.6 * sin(u * 1.7 + 2.1);\n p.z += U_amplitude * depth * fold;\n float pinch = U_gather * depth * min(U_amplitude * U_folds * 0.8, 0.6);\n p.x *= 1.0 - pinch;\n}\n`,\n strength: 'amplitude',\n uniforms: (o) => ({\n amplitude: o.amplitude,\n folds: o.folds,\n falloff: o.falloff,\n irregular: o.irregular,\n gather: o.gather,\n pin: o.pinnedEdge === 'top' ? 1 : 2,\n }),\n },\n}\n","import { z } from 'zod'\nimport type { Deformer } from './types'\n\nexport const crumpleOptionsSchema = z.object({\n /** How crushed, 0..1. Peak-to-peak height, and it drives the pull too. */\n amount: z.number().min(0).max(1).default(0.35),\n /** Facets per world unit. Higher is finer, and needs more segments to resolve. */\n scale: z.number().min(0.5).max(8).default(3),\n /**\n * How much the sheet draws in on itself. Crumpled paper occupies a smaller\n * footprint than flat paper; without this it reads as an embossed sheet\n * rather than a crushed one.\n */\n pull: z.number().min(0).max(1).default(0.4),\n /** A different crush of the same paper. */\n seed: z.number().int().min(0).max(7).default(0),\n})\n\nexport type CrumpleOptions = z.infer<typeof crumpleOptionsSchema>\n\n/**\n * GLSL's `mod`, which is not JS's `%`.\n *\n * `%` keeps the sign of the dividend, so a cell at a negative coordinate\n * hashes to a different bucket on the two paths — and the sheet is centred on\n * the origin, so HALF of every sheet is at a negative coordinate. Mirroring\n * `x - y·floor(x/y)` is the whole reason the two halves agree.\n */\nfunction mod(x: number, y: number): number {\n return x - y * Math.floor(x / y)\n}\n\n/**\n * Where the feature point of a cell sits, 0..1 within it.\n *\n * Deliberately integer arithmetic on small numbers rather than the usual\n * `fract(sin(dot(…)) * 43758.5)` hash: that one takes the sine of a large\n * argument and multiplies the result by forty thousand, which turns a\n * last-bit difference between a CPU and a GPU into a completely different\n * number. Every product here stays under 2^13, which is exact in float32 and\n * in a double alike, so the two implementations land on the same point rather\n * than on nearby ones. The pattern repeats every 64 cells — far outside any\n * sheet you would put on screen.\n */\nfunction jitter(cx: number, cy: number, seed: number): [number, number] {\n const hx = mod(cx * 37 + cy * 17 + seed * 5, 64)\n const hy = mod(cx * 23 + cy * 41 + seed * 11, 64)\n return [0.2 + (0.6 * mod(hx * 13, 7)) / 6, 0.2 + (0.6 * mod(hy * 29, 11)) / 10]\n}\n\n/**\n * `F2 − F1` tops out at 0.9315 of a cell on this jitter (measured across\n * every seed and the whole `scale` range), so this brings the field back to\n * ±amount/2 — `amount` is then a peak-to-peak height you can reason about\n * rather than an arbitrary knob. `crumple.test.ts` holds the bound.\n */\nconst NORM = 0.5366\n\n/** Which way a cell's facet is pushed — half up, half down. */\nfunction cellSign(cx: number, cy: number, seed: number): number {\n return 1 - 2 * mod(cx * 11 + cy * 7 + seed * 3, 2)\n}\n\n/**\n * Paper that has been handled.\n *\n * Six deformers and not one of them crushed a sheet — `wave` and `fold` were\n * the nearest and neither reads as crumpled. This is the missing primitive.\n *\n * The field is a jittered grid of cells, each pushed up or down, with the\n * height going to zero exactly on the boundary between them: `F2 − F1`, the\n * gap between the two nearest cell points, signed per cell. That vanishes on\n * every boundary, so the sheet stays continuous, and its gradient flips\n * across one — which is a crease. The result is an irregular polygonal\n * network of facets alternating toward and away from you, which is what a\n * sheet crushed in a fist actually is.\n *\n * **The normals matter more than the displacement here**, and getting there\n * took three tries worth recording. Three summed triangle waves: periodic,\n * an egg-crate. Plain distance-to-nearest (`F1`): irregular but smooth cone\n * tips, so it read as hammered metal. Only creases with a sign change across\n * them shade like paper.\n *\n * Both normal paths agree with that: the hero path averages vertex normals\n * over a dense grid, the field path probes two tangents a hundredth of a\n * sheet apart. Both need facets several segments wide.\n *\n * Cost, measured rather than assumed: a field of these runs about 45% longer\n * per frame than the same field of an undeformed preset, and almost none of\n * that is geometry — `segments: 'auto'` already gives every sheet 72 a side.\n * It is the nine cell lookups per probe, three probes deep for the normal.\n */\nexport const crumple: Deformer<CrumpleOptions> = {\n id: 'crumple',\n label: 'Crumple',\n defaults: crumpleOptionsSchema.parse({}),\n optionsSchema: crumpleOptionsSchema,\n // A crease the grid cannot resolve is a smooth bump, and a sheet of smooth\n // bumps is not a crumple. Note this is a FLOOR, and `segments: 'auto'`\n // already hands the long side 72 — so this only bites when a preset asks\n // for a coarser grid by hand. Measured (`pnpm perf:field`), the real cost\n // of this deformer is not geometry at all: it is nine cell evaluations per\n // probe and three probes per vertex for the normal.\n geometry: { minSegments: 72 },\n displace(out, _uv, o) {\n if (o.amount === 0) return\n const qx = out.x * o.scale\n const qy = out.y * o.scale\n const gx = Math.floor(qx)\n const gy = Math.floor(qy)\n\n // Nearest and second-nearest cell point, and which cell won.\n let f1 = 1e9\n let f2 = 1e9\n let winX = gx\n let winY = gy\n for (let dy = -1; dy <= 1; dy++) {\n for (let dx = -1; dx <= 1; dx++) {\n const cx = gx + dx\n const cy = gy + dy\n const [jx, jy] = jitter(cx, cy, o.seed)\n const ex = cx + jx - qx\n const ey = cy + jy - qy\n const dist = Math.sqrt(ex * ex + ey * ey)\n if (dist < f1) {\n f2 = f1\n f1 = dist\n winX = cx\n winY = cy\n } else if (dist < f2) {\n f2 = dist\n }\n }\n }\n\n // Zero on every cell boundary, so the sheet never tears; the sign flips\n // as you cross one, which is what makes the boundary a crease.\n out.z += cellSign(winX, winY, o.seed) * (f2 - f1) * o.amount * NORM\n // Drawing in happens after the cell lookup reads the flat position, so\n // both implementations hash the same cell.\n const pull = 1 - o.amount * o.pull * 0.35\n out.x *= pull\n out.y *= pull\n },\n glsl: {\n chunk: /* glsl */ `\nvec2 FN_jitter(float cx, float cy, float seed) {\n float hx = mod(cx * 37.0 + cy * 17.0 + seed * 5.0, 64.0);\n float hy = mod(cx * 23.0 + cy * 41.0 + seed * 11.0, 64.0);\n return vec2(0.2 + 0.6 * mod(hx * 13.0, 7.0) / 6.0, 0.2 + 0.6 * mod(hy * 29.0, 11.0) / 10.0);\n}\n\nfloat FN_sign(float cx, float cy, float seed) {\n return 1.0 - 2.0 * mod(cx * 11.0 + cy * 7.0 + seed * 3.0, 2.0);\n}\n\nvoid FN(inout vec3 p, vec2 uv, float t) {\n if (U_amount == 0.0) return;\n vec2 flat2 = p.xy;\n vec2 q = flat2 * U_scale;\n vec2 g = floor(q);\n\n float f1 = 1e9;\n float f2 = 1e9;\n vec2 win = g;\n for (int dy = -1; dy <= 1; dy++) {\n for (int dx = -1; dx <= 1; dx++) {\n vec2 c = g + vec2(float(dx), float(dy));\n float dist = length(c + FN_jitter(c.x, c.y, U_seed) - q);\n if (dist < f1) { f2 = f1; f1 = dist; win = c; }\n else if (dist < f2) { f2 = dist; }\n }\n }\n\n p.z += FN_sign(win.x, win.y, U_seed) * (f2 - f1) * U_amount * ${NORM};\n float pull = 1.0 - U_amount * U_pull * 0.35;\n p.xy = flat2 * pull;\n}\n`,\n // `amount` drives both the height and the pull, so a field instance's\n // bias scales the whole crush rather than half of it.\n strength: 'amount',\n uniforms: (o) => ({ amount: o.amount, scale: o.scale, pull: o.pull, seed: o.seed }),\n },\n}\n","import type { AnyOptions } from '../deformers/types'\nimport type { Behavior } from './types'\nimport { peel } from './peel'\nimport { unroll } from './unroll'\nimport { flip } from './flip'\nimport { letterFold } from './letter-fold'\nimport { hang } from './hang'\nimport { fly } from './fly'\nimport { fall } from './fall'\nimport { carry } from './carry'\nimport { flight } from './flight'\nimport { crumpleBehavior } from './crumple'\n\nconst registry = new Map<string, Behavior<AnyOptions>>()\n\n/** Community behaviors register here; built-ins are pre-registered. */\nexport function registerBehavior(behavior: Behavior<AnyOptions>): void {\n registry.set(behavior.id, behavior)\n}\n\nexport function getBehavior(id: string): Behavior<AnyOptions> {\n const b = registry.get(id)\n if (!b) {\n throw new Error(`[paperlab] Unknown behavior \"${id}\". Registered: ${[...registry.keys()].join(', ')}`)\n }\n return b\n}\n\nexport function listBehaviors(): string[] {\n return [...registry.keys()]\n}\n\nregisterBehavior(peel)\nregisterBehavior(unroll)\nregisterBehavior(flip)\nregisterBehavior(letterFold)\nregisterBehavior(hang)\nregisterBehavior(fly)\nregisterBehavior(fall)\nregisterBehavior(carry)\nregisterBehavior(flight)\nregisterBehavior(crumpleBehavior)\n","import type { DeformerInstance } from '../deformers/types'\n\nexport const idleNames = ['float', 'tumble', 'dangle', 'taped', 'breeze'] as const\nexport type IdleName = (typeof idleNames)[number]\n\nexport interface IdlePose {\n /** Offsets added to the paper's base transform each frame. */\n position: [number, number, number]\n rotation: [number, number, number]\n}\n\n/**\n * Curated fake physics: hand-tuned motion presets, no simulation. Cheap\n * enough for both hero and field modes, and — for things like the\n * falling-leaf tumble — they read *more* real than a true sim.\n */\nexport interface IdlePreset {\n id: IdleName\n label: string\n /** Whole-sheet motion, written into `pose` (allocation-free). */\n transform?(t: number, pose: IdlePose): void\n /** Extra deformers appended after the behavior's stack. */\n stack?(): DeformerInstance[]\n}\n\nexport const idlePresets: Record<IdleName, IdlePreset> = {\n float: {\n id: 'float',\n label: 'Float',\n transform(t, pose) {\n pose.position[1] = Math.sin(t * 0.9) * 0.05\n pose.rotation[1] = Math.sin(t * 0.31) * 0.16\n pose.rotation[2] = Math.sin(t * 0.23 + 1.2) * 0.05\n },\n },\n tumble: {\n id: 'tumble',\n label: 'Tumble',\n transform(t, pose) {\n // Falling-leaf: velocity-linked lift bob + curated wobble.\n pose.rotation[0] = Math.sin(t * 0.5 + 1) * 0.6\n pose.rotation[2] = Math.sin(t * 0.7) * 0.5\n pose.position[1] = Math.sin(t * 1.4) * 0.07\n pose.position[0] = Math.sin(t * 0.35) * 0.14\n },\n stack: () => [\n {\n type: 'wave',\n options: { amplitude: 0.02, wavelength: 0.9, speed: 0.9, angle: 25, pinnedEdge: 'none' },\n },\n ],\n },\n dangle: {\n id: 'dangle',\n label: 'Dangle',\n transform(t, pose) {\n // A hung tail's pendulum sway.\n pose.rotation[2] = Math.sin(t * 1.5) * 0.06\n pose.rotation[0] = Math.sin(t * 1.1 + 0.7) * 0.03\n },\n },\n taped: {\n id: 'taped',\n label: 'Taped',\n // Taped at the top of a wall: the free bottom edge breathes.\n stack: () => [\n {\n type: 'wave',\n options: { amplitude: 0.025, wavelength: 1.2, speed: 0.45, angle: 90, pinnedEdge: 'top' },\n },\n ],\n },\n breeze: {\n id: 'breeze',\n label: 'Breeze',\n stack: () => [\n {\n type: 'wave',\n options: { amplitude: 0.035, wavelength: 0.5, speed: 1.0, angle: 20, pinnedEdge: 'none' },\n },\n ],\n },\n}\n\nexport function getIdlePreset(name: IdleName): IdlePreset {\n return idlePresets[name]\n}\n","export type PinMode = 'top-edge' | 'top-corners' | 'corner' | 'none'\n\nexport interface ClothParams {\n /** Bend-spring strength: 1 = crisp paper, 0 = silk. Fabric mode falls out for free. */\n stiffness: number\n gravity: number\n wind: number\n /** Local-space y of the ground plane; particles settle onto it. */\n floor: number\n}\n\ninterface Constraint {\n a: number\n b: number\n rest: number\n /** 0 = structural, 1 = shear, 2 = bend (scaled by stiffness at solve time). */\n kind: 0 | 1 | 2\n}\n\nconst FIXED_DT = 1 / 120\nconst SOLVER_ITERATIONS = 5\nconst SLEEP_EPSILON = 1e-6\nconst SLEEP_FRAMES = 45\n\n/**\n * Verlet mass-spring grid on the sheet's own vertices — structural + shear +\n * bend springs, pins as the interface, wind as a force field, fixed timestep\n * with substeps, sleep when kinetic energy is negligible.\n *\n * Constraint (enforced in the schema): cloth OWNS vertex positions — a paper\n * runs a behavior (deformer stack) OR cloth, never both. Pure JS, no three\n * dependency: the PaperMesh adapter copies `positions` into the geometry.\n */\nexport class ClothSim {\n readonly cols: number\n readonly rows: number\n readonly count: number\n readonly positions: Float32Array\n private readonly prev: Float32Array\n private readonly pinned: Uint8Array\n private readonly pinTargets: Float32Array\n private readonly constraints: Constraint[] = []\n private params: ClothParams\n private time = 0\n private accumulator = 0\n private stillFrames = 0\n private grabbedIndex = -1\n /** True when the sim has settled and steps are skipped. */\n asleep = false\n\n constructor(cols: number, rows: number, width: number, height: number, pins: PinMode, params: ClothParams) {\n this.cols = cols\n this.rows = rows\n this.count = cols * rows\n this.params = { ...params }\n this.positions = new Float32Array(this.count * 3)\n this.prev = new Float32Array(this.count * 3)\n this.pinned = new Uint8Array(this.count)\n this.pinTargets = new Float32Array(this.count * 3)\n\n // Grid matches PlaneGeometry vertex order: row-major, top row first,\n // x left→right, y top→bottom (from +h/2 down).\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const i3 = (r * cols + c) * 3\n this.positions[i3] = (c / (cols - 1) - 0.5) * width\n this.positions[i3 + 1] = (0.5 - r / (rows - 1)) * height\n this.positions[i3 + 2] = 0\n }\n }\n this.prev.set(this.positions)\n\n const idx = (r: number, c: number) => r * cols + c\n const link = (a: number, b: number, kind: 0 | 1 | 2) => {\n const dx = this.positions[a * 3]! - this.positions[b * 3]!\n const dy = this.positions[a * 3 + 1]! - this.positions[b * 3 + 1]!\n this.constraints.push({ a, b, rest: Math.hypot(dx, dy), kind })\n }\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n if (c + 1 < cols) link(idx(r, c), idx(r, c + 1), 0)\n if (r + 1 < rows) link(idx(r, c), idx(r + 1, c), 0)\n if (c + 1 < cols && r + 1 < rows) {\n link(idx(r, c), idx(r + 1, c + 1), 1)\n link(idx(r, c + 1), idx(r + 1, c), 1)\n }\n if (c + 2 < cols) link(idx(r, c), idx(r, c + 2), 2)\n if (r + 2 < rows) link(idx(r, c), idx(r + 2, c), 2)\n }\n }\n\n // Pins hold their rest-pose position.\n const pin = (r: number, c: number) => {\n const i = idx(r, c)\n this.pinned[i] = 1\n this.pinTargets.set(this.positions.subarray(i * 3, i * 3 + 3), i * 3)\n }\n if (pins === 'top-edge') for (let c = 0; c < cols; c++) pin(0, c)\n if (pins === 'top-corners') {\n pin(0, 0)\n pin(0, cols - 1)\n }\n if (pins === 'corner') pin(0, 0)\n }\n\n setParams(params: Partial<ClothParams>): void {\n // Called every frame while cloth renders — plain numeric compare, no JSON.\n let changed = false\n for (const key of ['stiffness', 'gravity', 'wind', 'floor'] as const) {\n const value = params[key]\n if (value !== undefined && value !== this.params[key]) {\n this.params[key] = value\n changed = true\n }\n }\n if (changed) this.wake()\n }\n\n wake(): void {\n this.asleep = false\n this.stillFrames = 0\n }\n\n /** Nearest particle to a local-space point — the grab interface. */\n grabNearest(x: number, y: number, z: number): number {\n let best = -1\n let bestDist = Infinity\n for (let i = 0; i < this.count; i++) {\n const dx = this.positions[i * 3]! - x\n const dy = this.positions[i * 3 + 1]! - y\n const dz = this.positions[i * 3 + 2]! - z\n const d = dx * dx + dy * dy + dz * dz\n if (d < bestDist) {\n bestDist = d\n best = i\n }\n }\n this.grabbedIndex = best\n this.wake()\n return best\n }\n\n moveGrab(x: number, y: number, z: number): void {\n if (this.grabbedIndex < 0) return\n const i3 = this.grabbedIndex * 3\n this.positions[i3] = x\n this.positions[i3 + 1] = y\n this.positions[i3 + 2] = z\n this.prev[i3] = x\n this.prev[i3 + 1] = y\n this.prev[i3 + 2] = z\n this.wake()\n }\n\n release(): void {\n this.grabbedIndex = -1\n }\n\n step(delta: number): void {\n if (this.asleep) return\n this.accumulator = Math.min(this.accumulator + delta, FIXED_DT * 4)\n while (this.accumulator >= FIXED_DT) {\n this.substep(FIXED_DT)\n this.accumulator -= FIXED_DT\n }\n }\n\n private substep(dt: number): void {\n const { gravity, wind, stiffness, floor } = this.params\n const p = this.positions\n const damping = 0.985\n const dt2 = dt * dt\n this.time += dt\n\n let maxTravel = 0\n for (let i = 0; i < this.count; i++) {\n const i3 = i * 3\n if (this.pinned[i] || i === this.grabbedIndex) {\n if (this.pinned[i]) {\n p[i3] = this.pinTargets[i3]!\n p[i3 + 1] = this.pinTargets[i3 + 1]!\n p[i3 + 2] = this.pinTargets[i3 + 2]!\n }\n this.prev[i3] = p[i3]!\n this.prev[i3 + 1] = p[i3 + 1]!\n this.prev[i3 + 2] = p[i3 + 2]!\n continue\n }\n const x = p[i3]!\n const y = p[i3 + 1]!\n const z = p[i3 + 2]!\n // Gusty wind: coherent noise over time and position, pushing along +z\n // with a sideways component.\n const gust = wind * (0.55 + 0.45 * Math.sin(this.time * 1.7 + x * 2.1 + y * 1.3)) * 0.9\n const ax = gust * 0.25\n const az = gust\n const vx = (x - this.prev[i3]!) * damping\n const vy = (y - this.prev[i3 + 1]!) * damping\n const vz = (z - this.prev[i3 + 2]!) * damping\n this.prev[i3] = x\n this.prev[i3 + 1] = y\n this.prev[i3 + 2] = z\n p[i3] = x + vx + ax * dt2\n p[i3 + 1] = y + vy - gravity * 3.2 * dt2\n p[i3 + 2] = z + vz + az * dt2\n maxTravel = Math.max(maxTravel, vx * vx + vy * vy + vz * vz)\n }\n\n for (let iter = 0; iter < SOLVER_ITERATIONS; iter++) {\n for (const c of this.constraints) {\n const k = c.kind === 2 ? 0.25 + stiffness * 0.7 : c.kind === 1 ? 0.85 : 1\n const a3 = c.a * 3\n const b3 = c.b * 3\n const dx = p[b3]! - p[a3]!\n const dy = p[b3 + 1]! - p[a3 + 1]!\n const dz = p[b3 + 2]! - p[a3 + 2]!\n const dist = Math.sqrt(dx * dx + dy * dy + dz * dz)\n if (dist === 0) continue\n const diff = ((dist - c.rest) / dist) * 0.5 * k\n const aPinned = this.pinned[c.a] || c.a === this.grabbedIndex\n const bPinned = this.pinned[c.b] || c.b === this.grabbedIndex\n if (aPinned && bPinned) continue\n const aw = aPinned ? 0 : bPinned ? 2 : 1\n const bw = bPinned ? 0 : aPinned ? 2 : 1\n p[a3] = p[a3]! + dx * diff * aw\n p[a3 + 1] = p[a3 + 1]! + dy * diff * aw\n p[a3 + 2] = p[a3 + 2]! + dz * diff * aw\n p[b3] = p[b3]! - dx * diff * bw\n p[b3 + 1] = p[b3 + 1]! - dy * diff * bw\n p[b3 + 2] = p[b3 + 2]! - dz * diff * bw\n }\n }\n\n // Ground plane with friction.\n for (let i = 0; i < this.count; i++) {\n const i3 = i * 3\n if (p[i3 + 1]! < floor) {\n p[i3 + 1] = floor\n this.prev[i3] = this.prev[i3]! + (p[i3]! - this.prev[i3]!) * 0.5\n this.prev[i3 + 2] = this.prev[i3 + 2]! + (p[i3 + 2]! - this.prev[i3 + 2]!) * 0.5\n }\n }\n\n // Sleep bookkeeping: wind keeps the sheet awake by design.\n if (wind === 0 && this.grabbedIndex < 0) {\n if (maxTravel < SLEEP_EPSILON) {\n if (++this.stillFrames > SLEEP_FRAMES) this.asleep = true\n } else {\n this.stillFrames = 0\n }\n }\n }\n}\n","import * as THREE from 'three'\nimport { useEffect, useMemo } from 'react'\nimport CustomShaderMaterial from 'three-custom-shader-material'\nimport type { LightingName, SurfaceConfig } from '../config/schema'\nimport type { Stock } from '../core/stock'\nimport { composeSurface } from './compose'\n\nexport interface PaperMaterialProps {\n stock: Stock\n texture: THREE.Texture | null\n /** content.back rendered on the reverse side (stock color otherwise). */\n backTexture?: THREE.Texture | null\n surface: SurfaceConfig\n thickness: number\n /** World dims — perforation holes are sized in world units. */\n sheet?: { width: number; height: number }\n /** Scene lighting — transmission is measured against its key light. */\n lighting?: LightingName\n}\n\n/**\n * The paper's skin: MeshStandardMaterial (real lighting preserved) extended\n * with the composed surface-effect chunks. Content textures are sampled by\n * OUR fragment (not material.map) so front and back faces can differ — real\n * paper doesn't mirror its front through the sheet. Programs rebuild only\n * on structure change; value edits mutate uniforms in place.\n */\nexport function PaperMaterial({\n stock,\n texture,\n backTexture,\n surface,\n thickness,\n sheet,\n lighting = 'studio',\n}: PaperMaterialProps) {\n const composed = composeSurface(\n surface,\n stock,\n thickness,\n {\n hasFrontMap: Boolean(texture),\n hasBackMap: Boolean(backTexture),\n },\n sheet,\n lighting,\n )\n\n // Uniform objects bound to the current program; stable per structure.\n // biome-ignore lint/correctness/useExhaustiveDependencies: Uniform objects are bound per shader program — rebinding on value change would drop the binding every frame.\n const bound = useMemo(() => composed.uniforms, [composed.structureKey])\n useEffect(() => {\n for (const [key, uniform] of Object.entries(composed.uniforms)) {\n if (!bound[key] || key === 'uFrontMap' || key === 'uBackMap') continue\n if (bound[key].value instanceof THREE.Color && uniform.value instanceof THREE.Color) {\n ;(bound[key].value as THREE.Color).copy(uniform.value)\n } else {\n bound[key].value = uniform.value\n }\n }\n })\n useEffect(() => {\n if (bound.uFrontMap) bound.uFrontMap.value = texture\n if (bound.uBackMap) bound.uBackMap.value = backTexture ?? null\n }, [bound, texture, backTexture])\n\n return (\n <CustomShaderMaterial\n key={composed.structureKey}\n baseMaterial={THREE.MeshStandardMaterial}\n vertexShader={composed.vertexShader}\n fragmentShader={composed.fragmentShader}\n uniforms={bound}\n color=\"#ffffff\"\n roughness={stock.roughness}\n metalness={0}\n transparent={stock.opacity < 1}\n opacity={stock.opacity}\n alphaTest={composed.alphaTest}\n side={THREE.DoubleSide}\n />\n )\n}\n","import * as THREE from 'three'\nimport {\n paperEdges as paperEdgesOrder,\n type LightingName,\n type PaperEdge,\n type SurfaceConfig,\n} from '../config/schema'\nimport type { Stock } from '../core/stock'\nimport {\n TRANSLUCENCY_FRAGMENT,\n TRANSLUCENCY_VARYINGS,\n translucencyUniforms,\n translucencyVertexChunk,\n} from './translucency'\n\n/**\n * Surface effects are fragment-side chunks composed into ONE shader program\n * per effect set (grain + deckle + aging = one program). Uniforms are\n * namespaced per effect; shared helpers (noise) are included once.\n */\n\nexport interface ComposedSurface {\n /** Distinguishes shader *structures* — same key ⇒ same program, only uniforms change. */\n structureKey: string\n vertexShader: string\n fragmentShader: string\n uniforms: Record<string, { value: unknown }>\n /** Deckle discards via alphaTest (not blending) so shadows stay correct. */\n alphaTest: number\n}\n\n/** Which content textures exist — part of the shader structure. */\nexport interface SurfaceMaps {\n hasFrontMap: boolean\n hasBackMap: boolean\n}\n\nconst VERTEX = /* glsl */ `\nvarying vec2 vPaperUv;\n${TRANSLUCENCY_VARYINGS}\nvoid main() {\n vPaperUv = uv;\n${translucencyVertexChunk({ model: 'modelMatrix', position: 'position', normal: 'normal' })}\n}\n`\n\nconst HELPERS = /* glsl */ `\nvarying vec2 vPaperUv;\nuniform float uBackDarken;\n\nfloat plHash(vec2 p) {\n return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453123);\n}\n\nfloat plNoise(vec2 p) {\n vec2 i = floor(p);\n vec2 f = fract(p);\n vec2 u = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(plHash(i), plHash(i + vec2(1.0, 0.0)), u.x),\n mix(plHash(i + vec2(0.0, 1.0)), plHash(i + vec2(1.0, 1.0)), u.x),\n u.y\n );\n}\n\nfloat plFbm(vec2 p) {\n float v = 0.0;\n float a = 0.5;\n for (int i = 0; i < 4; i++) {\n v += a * plNoise(p);\n p *= 2.03;\n a *= 0.5;\n }\n return v;\n}\n`\n\nconst edgeFlags = (edges: PaperEdge[]): THREE.Vector4 =>\n new THREE.Vector4(\n edges.includes('top') ? 1 : 0,\n edges.includes('right') ? 1 : 0,\n edges.includes('bottom') ? 1 : 0,\n edges.includes('left') ? 1 : 0,\n )\n\nconst GRAIN_CHUNK = /* glsl */ `\nuniform float uGrainAmount;\nuniform float uGrainBanding;\n\nvoid plGrain(inout vec4 color, inout float rough) {\n float fiber = plFbm(vPaperUv * 240.0);\n float fleck = plNoise(vPaperUv * 900.0);\n float g = mix(0.5, fiber * 0.75 + fleck * 0.25, uGrainAmount);\n color.rgb *= 0.92 + g * 0.16;\n rough = clamp(rough + (g - 0.5) * uGrainAmount * 0.35, 0.0, 1.0);\n // Thermal-printer banding: faint horizontal density stripes.\n if (uGrainBanding > 0.0) {\n float band = sin(vPaperUv.y * 700.0) * 0.5 + 0.5;\n color.rgb *= 1.0 - uGrainBanding * 0.05 * band;\n }\n}\n`\n\nconst DECKLE_CHUNK = /* glsl */ `\nuniform vec4 uDeckleEdges; // top, right, bottom, left\nuniform float uDeckleRoughness;\n\nvoid plDeckle(inout vec4 color) {\n // Distance to each selected edge, gnawed by low-frequency noise.\n float depth = 0.012 + uDeckleRoughness * 0.05;\n float tear = 1.0;\n float fiberBand = 0.0;\n vec4 dists = vec4(1.0 - vPaperUv.y, 1.0 - vPaperUv.x, vPaperUv.y, vPaperUv.x);\n vec4 alongs = vec4(vPaperUv.x, vPaperUv.y, vPaperUv.x, vPaperUv.y);\n for (int e = 0; e < 4; e++) {\n if (uDeckleEdges[e] < 0.5) continue;\n float n = plFbm(vec2(alongs[e] * 26.0, float(e) * 7.31)) - 0.5;\n float boundary = depth * (0.55 + n * 1.6);\n float d = dists[e] - boundary;\n tear = min(tear, step(0.0, d));\n // Lightened fiber band just inside the tear.\n fiberBand = max(fiberBand, smoothstep(depth * 1.4, 0.0, d) * step(0.0, d));\n }\n color.a *= tear;\n color.rgb = mix(color.rgb, vec3(1.0), fiberBand * 0.35);\n}\n`\n\nconst CREASE_CHUNK = /* glsl */ `\nuniform float uCreaseAngle;\nuniform float uCreaseStrength;\nuniform float uCreasePositions[4];\nuniform int uCreaseCount;\n\nvoid plCrease(inout vec4 color, inout float rough) {\n vec2 dir = vec2(cos(uCreaseAngle), sin(uCreaseAngle));\n // Coordinate across the crease lines (0..1 over the sheet).\n float t = dot(vPaperUv - 0.5, vec2(-dir.y, dir.x)) + 0.5;\n for (int i = 0; i < 4; i++) {\n if (i >= uCreaseCount) break;\n float d = abs(t - uCreasePositions[i]);\n float shadow = smoothstep(0.014, 0.0, d);\n float sheen = smoothstep(0.02, 0.006, d) - smoothstep(0.006, 0.0, d);\n color.rgb *= 1.0 - shadow * uCreaseStrength * 0.28;\n color.rgb += sheen * uCreaseStrength * 0.05;\n rough = clamp(rough + shadow * uCreaseStrength * 0.2, 0.0, 1.0);\n }\n}\n`\n\nconst PERFORATION_CHUNK = /* glsl */ `\nuniform vec4 uPerfEdges; // top, right, bottom, left enabled\nuniform vec4 uPerfTorn; // 1 = ripped-through profile, 0 = clean punches\nuniform float uPerfRadius; // world units\nuniform float uPerfSpacing;\nuniform vec2 uSheetSize;\n\nvoid plPerforation(inout vec4 color) {\n // Per-edge distance/along coordinates, converted from UV to world units so\n // hole size is stable across sheet dimensions.\n vec4 dists = vec4(1.0 - vPaperUv.y, 1.0 - vPaperUv.x, vPaperUv.y, vPaperUv.x);\n vec4 alongs = vec4(vPaperUv.x, vPaperUv.y, vPaperUv.x, vPaperUv.y);\n vec4 distScale = vec4(uSheetSize.y, uSheetSize.x, uSheetSize.y, uSheetSize.x);\n vec4 alongScale = vec4(uSheetSize.x, uSheetSize.y, uSheetSize.x, uSheetSize.y);\n float fiber = 0.0;\n for (int e = 0; e < 4; e++) {\n if (uPerfEdges[e] < 0.5) continue;\n float d = dists[e] * distScale[e];\n float a = alongs[e] * alongScale[e];\n // Signed distance along the edge to the nearest hole center.\n float cell = mod(a + uPerfSpacing * 0.5, uPerfSpacing) - uPerfSpacing * 0.5;\n if (uPerfTorn[e] < 0.5) {\n // Intact: clean semicircular punches on the edge line (alphaTest, not\n // blending — shadow correctness per v0.2 §4.5).\n if (length(vec2(cell, d)) < uPerfRadius) color.a = 0.0;\n } else {\n // Torn: ripped profile following the hole rhythm — alternating tabs and\n // notches, gnawed by noise, with a lightened fiber band along the tear.\n float rhythm = abs(sin(a / uPerfSpacing * 3.14159265));\n float n = plNoise(vec2(a * 40.0, float(e) * 7.31)) - 0.5;\n float cut = uPerfRadius * (0.35 + rhythm * 1.35 + n * 0.9);\n if (d < cut) color.a = 0.0;\n fiber = max(fiber, smoothstep(uPerfRadius * 2.4, 0.0, d - cut) * step(cut, d));\n }\n }\n color.rgb = mix(color.rgb, vec3(1.0), fiber * 0.4);\n}\n`\n\nconst AGING_CHUNK = /* glsl */ `\nuniform float uAgingAmount;\n\nvoid plAging(inout vec4 color) {\n // Yellowing deepens toward the edges, like light exposure.\n float edge = max(abs(vPaperUv.x - 0.5), abs(vPaperUv.y - 0.5)) * 2.0;\n vec3 yellowed = color.rgb * vec3(1.0, 0.94, 0.78);\n color.rgb = mix(color.rgb, yellowed, uAgingAmount * (0.45 + edge * 0.55));\n // Foxing: sparse rusty blotches.\n float fox = plFbm(vPaperUv * 14.0 + 3.7);\n float spots = smoothstep(0.62, 0.78, fox) * uAgingAmount;\n color.rgb = mix(color.rgb, vec3(0.62, 0.45, 0.26), spots * 0.5);\n}\n`\n\n/**\n * Compose the enabled effects into one program. The shader owns the base\n * color entirely: the FRONT face samples the content texture, the BACK face\n * renders the stock (or content.back) with an optional reversed show-through\n * ghost — a single DoubleSide map would mirror the front content onto the\n * back, which real paper doesn't do.\n */\nexport function composeSurface(\n surface: SurfaceConfig,\n stock: Stock,\n thickness: number,\n maps: SurfaceMaps = { hasFrontMap: false, hasBackMap: false },\n /** World dims — perforation holes are sized in world units. */\n sheet: { width: number; height: number } = { width: 1, height: 1.4 },\n /** Whose key light transmission is measured against. */\n lighting: LightingName = 'studio',\n): ComposedSurface {\n const grain = surface.grain ?? stock.defaultSurface.grain\n const aging = surface.aging ?? stock.defaultSurface.aging\n const deckle = surface.deckle\n const creases = surface.creaseLines\n const perforation = surface.perforation\n const banding = stock.banding\n // Adhesive undersides are opaque backing-paper white — nothing shows through.\n const showThrough = stock.adhesive ? 0 : (surface.showThrough ?? stock.showThrough)\n\n const chunks: string[] = []\n const calls: string[] = []\n const uniforms: Record<string, { value: unknown }> = {\n // Backside darkening: thicker/opaque stock lets less light through.\n // Adhesive backs skip it — the glue layer is its own bright surface.\n uBackDarken: {\n value: stock.adhesive ? 1 : 1 - Math.min(0.45, 0.12 + thickness * 0.9) * stock.opacity,\n },\n uStockColor: { value: new THREE.Color(stock.color) },\n uOpacity: { value: stock.opacity },\n uShowThrough: { value: showThrough },\n // Always compiled in: the shader early-outs at zero translucency, which\n // is cheaper than carrying a second program structure for it.\n ...translucencyUniforms(surface.translucency ?? stock.translucency, lighting),\n }\n if (maps.hasFrontMap) uniforms.uFrontMap = { value: null }\n if (maps.hasBackMap) uniforms.uBackMap = { value: null }\n\n if (grain !== undefined || banding > 0) {\n chunks.push(GRAIN_CHUNK)\n calls.push('plGrain(csm_DiffuseColor, csm_Roughness);')\n uniforms.uGrainAmount = { value: grain ?? 0 }\n uniforms.uGrainBanding = { value: banding }\n }\n if (deckle) {\n chunks.push(DECKLE_CHUNK)\n calls.push('plDeckle(csm_DiffuseColor);')\n uniforms.uDeckleEdges = { value: edgeFlags(deckle.edges) }\n uniforms.uDeckleRoughness = { value: deckle.roughness }\n }\n if (perforation) {\n const edges = perforation.edges === 'all' ? [...paperEdgesOrder] : perforation.edges\n chunks.push(PERFORATION_CHUNK)\n calls.push('plPerforation(csm_DiffuseColor);')\n uniforms.uPerfEdges = { value: edgeFlags(edges) }\n uniforms.uPerfTorn = {\n value: new THREE.Vector4(\n ...paperEdgesOrder.map((e) => (edges.includes(e) && perforation.state[e] === 'torn' ? 1 : 0)),\n ),\n }\n uniforms.uPerfRadius = { value: perforation.holeRadius }\n uniforms.uPerfSpacing = { value: perforation.spacing }\n uniforms.uSheetSize = { value: new THREE.Vector2(sheet.width, sheet.height) }\n }\n if (creases) {\n chunks.push(CREASE_CHUNK)\n calls.push('plCrease(csm_DiffuseColor, csm_Roughness);')\n uniforms.uCreaseAngle = { value: (creases.angle * Math.PI) / 180 }\n uniforms.uCreaseStrength = { value: creases.strength }\n uniforms.uCreasePositions = { value: padPositions(creases.positions) }\n uniforms.uCreaseCount = { value: Math.min(creases.positions.length, 4) }\n }\n if (aging !== undefined) {\n chunks.push(AGING_CHUNK)\n calls.push('plAging(csm_DiffuseColor);')\n uniforms.uAgingAmount = { value: aging }\n }\n\n const frontExpr = maps.hasFrontMap ? 'texture2D(uFrontMap, vPaperUv).rgb' : 'uStockColor'\n // The back reads correctly when the sheet is flipped → mirror x. Adhesive\n // undersides (sticker stock) are glossy near-white regardless of the front.\n const backBaseExpr = stock.adhesive\n ? 'vec3(0.965, 0.96, 0.945)'\n : maps.hasBackMap\n ? 'texture2D(uBackMap, vec2(1.0 - vPaperUv.x, vPaperUv.y)).rgb'\n : 'uStockColor'\n\n const fragmentShader = /* glsl */ `\n${HELPERS}\nuniform vec3 uStockColor;\nuniform float uOpacity;\nuniform float uShowThrough;\n${maps.hasFrontMap ? 'uniform sampler2D uFrontMap;' : ''}\n${maps.hasBackMap && !stock.adhesive ? 'uniform sampler2D uBackMap;' : ''}\n${TRANSLUCENCY_FRAGMENT}\n${chunks.join('\\n')}\nvoid main() {\n vec3 front = ${frontExpr};\n if (gl_FrontFacing) {\n csm_DiffuseColor = vec4(front, uOpacity);\n } else {\n vec3 backBase = ${backBaseExpr};\n csm_DiffuseColor = vec4(backBase * mix(vec3(1.0), front, uShowThrough), uOpacity);\n }\n ${calls.join('\\n ')}\n if (!gl_FrontFacing) csm_DiffuseColor.rgb *= uBackDarken;\n ${stock.adhesive ? '// Adhesive underside: higher specular than the printed face.\\n if (!gl_FrontFacing) csm_Roughness = 0.18;' : ''}\n // What the key light pushes through the sheet, filtered by the ink on it.\n csm_Emissive = plTransmission(front);\n}\n`\n\n return {\n structureKey: `${[\n grain !== undefined || banding > 0 ? 'g' : '',\n deckle ? 'd' : '',\n creases ? 'c' : '',\n aging !== undefined ? 'a' : '',\n perforation ? 'p' : '',\n stock.adhesive ? 'A' : '',\n ].join('')}:${maps.hasFrontMap ? 'F' : ''}${maps.hasBackMap ? 'B' : ''}`,\n vertexShader: VERTEX,\n fragmentShader,\n uniforms,\n alphaTest: deckle || perforation ? 0.5 : 0,\n }\n}\n\nfunction padPositions(positions: number[]): number[] {\n const out = positions.slice(0, 4)\n while (out.length < 4) out.push(-1)\n return out\n}\n","import * as THREE from 'three'\nimport type { LightingName } from '../config/schema'\nimport { getLightingPreset } from '../scene/lighting'\n\n/**\n * Light passing THROUGH the paper.\n *\n * Every reference image for stage mode is lit from behind: the paper is a\n * filter, not a surface catching a key light. That single change is what\n * separates \"a render of some paper\" from the look — and it is cheap,\n * because paper is thin and diffuse. No refraction, no transmission pass,\n * no `MeshPhysicalMaterial` (which does not instance): one dot product and\n * an additive emissive term, so it works identically in the instanced field\n * path and the hero path.\n *\n * The detail that sells it is the ink filter. What comes through a backlit\n * sheet is the lamp MINUS whatever is printed on it, which is why the\n * calligraphy on a lit banner reads dark against a glowing field instead of\n * blowing out with everything else.\n */\n\n/** Declared by both stages of both pipelines. */\nexport const TRANSLUCENCY_VARYINGS = /* glsl */ `\nvarying vec3 vPlWorldNormal;\nvarying vec3 vPlViewDir;\n`\n\nexport interface TranslucencyVertexSlots {\n /** Object → world matrix expression. Instanced meshes must fold in `instanceMatrix`. */\n model: string\n /** Final object-space position expression. */\n position: string\n /** Final object-space normal expression. */\n normal: string\n}\n\n/**\n * Vertex side: publish the world-space normal and view vector. Doing this in\n * the vertex shader (rather than reconstructing from `vNormal`) keeps the\n * chunk independent of where in three's fragment pipeline it gets injected.\n */\nexport function translucencyVertexChunk(slots: TranslucencyVertexSlots): string {\n return /* glsl */ `\n {\n mat4 plModel = ${slots.model};\n vec4 plWorld = plModel * vec4(${slots.position}, 1.0);\n // Uniform scale only — layouts scale sheets evenly, so the plain 3×3 is\n // the correct normal matrix here and skips an inverse-transpose.\n vPlWorldNormal = normalize(mat3(plModel) * ${slots.normal});\n vPlViewDir = cameraPosition - plWorld.xyz;\n }\n`\n}\n\n/** How much of the incident key light a fully translucent sheet passes on. */\nexport const TRANSMISSION_GAIN = 0.5\n\n/** Fragment side: uniforms plus `plTransmission(inkFilter)`. */\nexport const TRANSLUCENCY_FRAGMENT = /* glsl */ `\nuniform float uTranslucency;\nuniform vec3 uBackLightDir;\nuniform vec3 uBackLightColor;\nuniform float uAmbientTransmission;\n${TRANSLUCENCY_VARYINGS}\n\nvec3 plTransmission(vec3 inkFilter) {\n if (uTranslucency <= 0.0) return vec3(0.0);\n vec3 n = normalize(vPlWorldNormal);\n // Sheets render double-sided; the back face needs the normal it actually shows.\n if (!gl_FrontFacing) n = -n;\n // The lamp is BEHIND this sheet when the face we are looking at points away\n // from it — that is the whole test.\n float behind = clamp(-dot(n, uBackLightDir), 0.0, 1.0);\n // A grazing view looks through more paper, and more paper passes less light.\n float thickness = abs(dot(n, normalize(vPlViewDir)));\n // Paper in a lit room glows whatever way it is turned — a sheet standing\n // edge-on to the only lamp is not black. Without this floor, a banner\n // whose face runs parallel to the key light gets neither diffuse nor\n // transmission and drops out of the picture entirely.\n vec3 arriving = uBackLightColor * behind + uAmbientTransmission;\n return arriving * uTranslucency * mix(0.25, 1.0, thickness) * inkFilter;\n}\n`\n\nexport interface TranslucencyValues {\n translucency: number\n /** Unit world direction from the scene toward the key light. */\n direction: THREE.Vector3\n color: THREE.Color\n /** Light the room passes through the sheet from every direction at once. */\n ambient: number\n}\n\n/**\n * Resolve the transmission uniforms from the paper and the scene's lighting\n * preset — the key light's own position and color, so translucency can never\n * disagree with the lamp casting the shadows.\n */\nexport function translucencyValues(translucency: number, lighting: LightingName): TranslucencyValues {\n const preset = getLightingPreset(lighting)\n const [x, y, z] = preset.key.position\n const direction = new THREE.Vector3(x, y, z)\n // A key light at the origin has no direction to give; treat it as overhead.\n if (direction.lengthSq() < 1e-12) direction.set(0, 1, 0)\n direction.normalize()\n const color = new THREE.Color(preset.key.color).multiplyScalar(preset.key.intensity * TRANSMISSION_GAIN)\n return { translucency, direction, color, ambient: preset.ambient * TRANSMISSION_GAIN }\n}\n\n/** Ready-to-bind uniform objects for a shader program. */\nexport function translucencyUniforms(\n translucency: number,\n lighting: LightingName,\n): Record<string, { value: unknown }> {\n const values = translucencyValues(translucency, lighting)\n return {\n uTranslucency: { value: values.translucency },\n uBackLightDir: { value: values.direction },\n uBackLightColor: { value: values.color },\n uAmbientTransmission: { value: values.ambient },\n }\n}\n","import type { LightingName } from '../config/schema'\n\n/**\n * Lighting presets: each is a key light + ambient level + contact shadow +\n * optional gobo (a texture the key light projects — window blinds, foliage).\n * Pure data here (testable in node); textures and R3F live in\n * PaperLighting.tsx. Serialized into presets as `scene.lighting`.\n */\n\nexport interface LightingPreset {\n id: LightingName\n label: string\n ambient: number\n key: { color: string; intensity: number; position: [number, number, number] }\n contactShadowOpacity: number\n /** Contact shadow blur — hard for noir, long and soft for golden hour. */\n contactShadowBlur: number\n /** Renderer tone-mapping exposure while active. */\n exposure: number\n shadow: { mapSize: number; radius: number }\n gobo?: { kind: 'blinds' | 'leaves'; drift: number; angle: number }\n /**\n * Distance haze. Depth in a deep space is staged almost entirely by fog —\n * it is what turns a row of banners into a receding colonnade instead of\n * a flat row of rectangles.\n */\n fog?: { color: string; near: number; far: number }\n}\n\nexport const lightingPresets: Record<LightingName, LightingPreset> = {\n studio: {\n id: 'studio',\n label: 'Studio',\n ambient: 0.65,\n key: { color: '#ffffff', intensity: 1.6, position: [2.5, 4, 3] },\n contactShadowOpacity: 0.3,\n contactShadowBlur: 2.4,\n exposure: 1,\n shadow: { mapSize: 1024, radius: 4 },\n },\n window: {\n id: 'window',\n label: 'Window',\n ambient: 0.5,\n key: { color: '#ffe3c0', intensity: 1.9, position: [3, 2.6, 2.6] },\n contactShadowOpacity: 0.35,\n contactShadowBlur: 2.6,\n exposure: 1,\n shadow: { mapSize: 1024, radius: 5 },\n gobo: { kind: 'blinds', drift: 0.004, angle: 0.62 },\n },\n leaves: {\n id: 'leaves',\n label: 'Leaves',\n ambient: 0.45,\n key: { color: '#fff2d8', intensity: 2.0, position: [2.2, 3.6, 2.4] },\n contactShadowOpacity: 0.4,\n contactShadowBlur: 2.8,\n exposure: 1,\n shadow: { mapSize: 1024, radius: 6 },\n gobo: { kind: 'leaves', drift: 0.012, angle: 0.7 },\n },\n goldenhour: {\n id: 'goldenhour',\n label: 'Golden hour',\n ambient: 0.32,\n key: { color: '#ffb066', intensity: 2.4, position: [4, 0.9, 2.2] },\n contactShadowOpacity: 0.45,\n contactShadowBlur: 3.2,\n exposure: 1.15,\n shadow: { mapSize: 1024, radius: 7 },\n },\n noir: {\n id: 'noir',\n label: 'Noir',\n ambient: 0.07,\n key: { color: '#ffffff', intensity: 2.6, position: [2, 3, 1.6] },\n contactShadowOpacity: 0.7,\n contactShadowBlur: 1.1,\n exposure: 1.05,\n shadow: { mapSize: 2048, radius: 1 },\n },\n nave: {\n id: 'nave',\n label: 'Nave',\n // Dim, and the key sits BEHIND the walk rather than beside it: this mode\n // is carried by light coming through the paper, not off it. Ambient is\n // nearly nothing so the only bright thing in frame is the source itself.\n ambient: 0.09,\n key: { color: '#fff1dc', intensity: 3.4, position: [0, 7, -16] },\n contactShadowOpacity: 0.55,\n contactShadowBlur: 3.6,\n exposure: 1.2,\n shadow: { mapSize: 2048, radius: 6 },\n // Warm and light, not black: distance in a backlit hall washes TOWARD\n // the source, which is what separates haze from murk.\n fog: { color: '#c9baa3', near: 5, far: 38 },\n },\n}\n\nexport function getLightingPreset(name: LightingName): LightingPreset {\n return lightingPresets[name]\n}\n","import { useEffect, useState } from 'react'\nimport type { PaperConfig } from '../config/schema'\nimport { getStock } from '../core/stock'\nimport { receiptTotals, type ReceiptContent } from '../content/receipt'\n\n/**\n * Accessibility layer: reduced-motion handling, a hidden DOM mirror so the\n * paper's content exists for screen readers and find-in-page, and a no-WebGL\n * DOM fallback.\n */\n\nexport function usePrefersReducedMotion(override?: boolean): boolean {\n const [system, setSystem] = useState(\n () => typeof window !== 'undefined' && window.matchMedia?.('(prefers-reduced-motion: reduce)').matches,\n )\n useEffect(() => {\n const query = window.matchMedia?.('(prefers-reduced-motion: reduce)')\n if (!query) return\n const onChange = () => setSystem(query.matches)\n query.addEventListener('change', onChange)\n return () => query.removeEventListener('change', onChange)\n }, [])\n return override ?? system\n}\n\nlet webglSupport: boolean | null = null\n\nexport function supportsWebGL(): boolean {\n if (webglSupport !== null) return webglSupport\n try {\n const canvas = document.createElement('canvas')\n webglSupport = Boolean(canvas.getContext('webgl2') ?? canvas.getContext('webgl'))\n } catch {\n webglSupport = false\n }\n return webglSupport\n}\n\n/** Human-readable text equivalent of a paper's content. */\nexport function contentText(config: PaperConfig): string {\n const content = config.content\n if (content.type === 'text') return content.text\n if (content.type === 'image') return content.alt ?? 'An image printed on paper.'\n if (content.type === 'receipt') {\n const totals = receiptTotals(content as ReceiptContent)\n const items = content.items.map((i) => `${i.name} ${i.price.toFixed(2)}`).join(', ')\n return `Receipt from ${content.store}: ${items}. Total ${totals.total.toFixed(2)}. ${content.footer}`\n }\n return 'A blank sheet of paper.'\n}\n\nconst visuallyHidden: React.CSSProperties = {\n position: 'absolute',\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: 'hidden',\n clip: 'rect(0 0 0 0)',\n whiteSpace: 'nowrap',\n border: 0,\n}\n\n/** Hidden DOM twin of the 3D paper — screen readers read it, ctrl-F finds it. */\nexport function PaperMirror({ config }: { config: PaperConfig }) {\n return (\n <div style={visuallyHidden} aria-hidden={false}>\n {contentText(config)}\n </div>\n )\n}\n\n/** No WebGL: the paper renders flat — content on a stock-tinted card. */\nexport function PaperFallback({ config }: { config: PaperConfig }) {\n const stock = getStock(config.stock)\n const isImage = config.content.type === 'image'\n return (\n <div\n role=\"img\"\n aria-label={contentText(config)}\n style={{\n width: '100%',\n height: '100%',\n display: 'grid',\n placeItems: 'center',\n background: 'transparent',\n }}\n >\n <div\n style={{\n aspectRatio: `${config.sheet.width} / ${config.sheet.height}`,\n maxWidth: '80%',\n maxHeight: '90%',\n background: stock.color,\n color: stock.inkColor,\n boxShadow: '0 6px 24px rgba(0,0,0,0.25)',\n padding: '8%',\n overflow: 'hidden',\n fontFamily: config.content.type === 'receipt' ? 'ui-monospace, monospace' : 'Georgia, serif',\n whiteSpace: 'pre-wrap',\n fontSize: 14,\n }}\n >\n {isImage && config.content.type === 'image' ? (\n <img\n src={config.content.src}\n alt={config.content.alt ?? ''}\n style={{ width: '100%', height: '100%', objectFit: 'cover', margin: '-8%' }}\n />\n ) : (\n contentText(config)\n )}\n </div>\n </div>\n )\n}\n","/**\n * Stop-motion feel: quantize continuous time to animation \"twos\"\n * (12 steps per second, like shooting on twos at 24fps). Applies to\n * deformer time, idle motion, and behavior progress; the camera is\n * excluded by default — quantized cameras read as jank, not craft.\n */\nexport const ON_TWOS_FPS = 12\n\nexport function quantizeTime(t: number, fps: number = ON_TWOS_FPS): number {\n return Math.floor(t * fps) / fps\n}\n\n/** Snap a 0..1 progress that plays over `duration` seconds to whole frames. */\nexport function quantizeProgress(p: number, duration: number, fps: number = ON_TWOS_FPS): number {\n const steps = Math.max(1, Math.round(duration * fps))\n return Math.round(p * steps) / steps\n}\n","import { useEffect, useMemo, useRef, useState } from 'react'\nimport type { PaperConfig } from '../config/schema'\nimport { PaperStateMachine, stripStates } from './machine'\n\nexport interface UsePaperStatesResult {\n /** The config to render this frame — animated when a machine is live. */\n config: PaperConfig\n /** Current state name ('rest' when no machine). */\n state: string\n /** Send triggers through this; null when states are absent or disabled. */\n machine: PaperStateMachine | null\n}\n\n/**\n * Bind a state machine to a config with `states`. The machine survives\n * config edits via `rebase` (current state and live values are kept —\n * flipping perforation to torn mid-pick must not snap the stamp to rest);\n * it is only rebuilt when states are toggled on/off.\n *\n * `animated` holds an IMMUTABLE structural snapshot for the React tree; it\n * updates only on structural boundaries (transition start/settle, state swap,\n * rebase), not per frame. Per-tick numeric values are read straight off\n * `machine.liveConfig` by the caller's frame loop — GSAP owns values, useFrame\n * owns uploads. `machine` is returned so the caller can poll it.\n */\nexport function usePaperStates(\n config: PaperConfig,\n enabled: boolean,\n instant: boolean,\n onAction?: (event: string, state: string) => void,\n onStateChange?: (state: string) => void,\n): UsePaperStatesResult {\n const live = enabled && Boolean(config.states)\n const key = useMemo(() => JSON.stringify(config), [config])\n\n // Callbacks live in refs so machine identity doesn't churn on new closures.\n const onActionRef = useRef(onAction)\n onActionRef.current = onAction\n const onStateChangeRef = useRef(onStateChange)\n onStateChangeRef.current = onStateChange\n\n const machineRef = useRef<PaperStateMachine | null>(null)\n const lastStateRef = useRef<string>('rest')\n const [animated, setAnimated] = useState<{ config: PaperConfig; state: string } | null>(null)\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: key serializes the config — the machine rebases onto a new config instead of being rebuilt.\n useEffect(() => {\n if (!live) {\n machineRef.current?.dispose()\n machineRef.current = null\n setAnimated(null)\n return\n }\n if (machineRef.current) {\n machineRef.current.rebase(config)\n return\n }\n const machine = new PaperStateMachine(config, {\n instant,\n // Structural boundaries only (not per tick) — safe to route to React.\n onChange: (c, state) => {\n if (state !== lastStateRef.current) {\n lastStateRef.current = state\n onStateChangeRef.current?.(state)\n }\n setAnimated({ config: c, state })\n },\n onAction: (event, state) => onActionRef.current?.(event, state),\n })\n machineRef.current = machine\n lastStateRef.current = machine.state\n setAnimated({ config: machine.structuralConfig(), state: machine.state })\n }, [key, live, instant])\n\n useEffect(\n () => () => {\n machineRef.current?.dispose()\n machineRef.current = null\n },\n [],\n )\n\n return {\n config: live && animated ? animated.config : stripStates(config),\n state: live && animated ? animated.state : 'rest',\n machine: live ? machineRef.current : null,\n }\n}\n","import { gsap } from 'gsap'\nimport { mergeConfig } from '../config/merge'\nimport {\n paperConfigSchema,\n paperStatesSchema,\n stateDefSchema,\n type PaperConfig,\n type StateName,\n} from '../config/schema'\n\n/**\n * The interaction-state engine. A state is a set of parameter overrides on\n * the base preset — never a separate preset (spec M6 §1.1). The machine\n * resolves each state to a full config (base + overrides), keeps ONE live\n * tween target of flattened numeric leaves, and always tweens FROM CURRENT\n * VALUES: a pointer that enters/leaves rapidly retargets the same tween\n * values instead of stacking or snapping.\n *\n * Delivery split (spec v0.2 §4: GSAP owns values, useFrame owns uploads):\n * GSAP animates the STABLE `flat` object in place; per-tick values are polled\n * off `liveConfig` by the consumer's frame loop, never pushed through React.\n * `onChange` fires only on STRUCTURAL boundaries (a transition's start and\n * settle, a state swap, a rebase) so the React tree re-renders a handful of\n * times per interaction instead of once per frame.\n */\n\n/** Built-in trigger events (v1 — user-defined wiring is parked for editor v2). */\nexport type StateEvent = 'enter' | 'leave' | 'down' | 'up' | 'pick' | 'place' | 'return'\n\n/** The fixed v1 transition table: pointer flow + pick/drop flow. */\nexport const stateEventTransitions: Record<string, Partial<Record<StateEvent, StateName>>> = {\n rest: { enter: 'hover' },\n hover: { leave: 'rest', down: 'pressed' },\n pressed: { up: 'hover', pick: 'picked' },\n picked: { place: 'placed', return: 'rest' },\n placed: {},\n}\n\nconst DEFAULT_TRANSITION = { duration: 0.35, ease: 'power2.out' }\n\n/** The base config with `states` stripped — what a state resolves against. */\nexport function stripStates(config: PaperConfig): PaperConfig {\n if (!config.states) return config\n const { states: _states, ...rest } = config\n return rest as PaperConfig\n}\n\n/**\n * Resolve a state name to its full config: base + that state's overrides.\n * States without a recorded def (e.g. an untouched 'rest') are the base.\n * The merge re-parses so a structural override (a behavior swapped to\n * `{ type: 'carry' }`) comes back with every default filled.\n */\nexport function resolveStateConfig(base: PaperConfig, state: string): PaperConfig {\n const def = base.states?.states[state]\n const flat = stripStates(base)\n if (!def || Object.keys(def.overrides).length === 0) return flat\n return paperConfigSchema.parse(mergeConfig(flat as Record<string, unknown>, def.overrides))\n}\n\n/** Drop `undefined` leaves at every depth, and any object left empty by that. */\nfunction pruneUndefined(value: unknown): unknown {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return value\n const out: Record<string, unknown> = {}\n for (const [key, v] of Object.entries(value as Record<string, unknown>)) {\n if (v === undefined) continue\n const pruned = pruneUndefined(v)\n const isEmptyObject =\n pruned !== null &&\n typeof pruned === 'object' &&\n !Array.isArray(pruned) &&\n Object.keys(pruned).length === 0\n if (!isEmptyObject) out[key] = pruned\n }\n return out\n}\n\n/**\n * Record a patch into ONE state's override diff (Figma's overridden\n * affordance), returning a new base config with that state updated — the base\n * params and every other state stay untouched. This is how an authoring tool\n * writes while a state chip is active. `undefined` values are dropped at every\n * depth: an override can only SET a base param, never remove one. Re-parsing\n * runs the schema's per-state validation, so an override that wouldn't merge\n * cleanly throws here.\n */\nexport function recordStateOverride(\n config: PaperConfig,\n stateName: string,\n patch: Record<string, unknown>,\n): PaperConfig {\n const cleaned = pruneUndefined(patch) as Record<string, unknown>\n const states = config.states ?? paperStatesSchema.parse({})\n const def = states.states[stateName] ?? stateDefSchema.parse({})\n const overrides = mergeConfig(def.overrides, cleaned) as Record<string, unknown>\n return paperConfigSchema.parse({\n ...config,\n states: {\n ...states,\n states: { ...states.states, [stateName]: { ...def, overrides } },\n },\n })\n}\n\n// ── Numeric flattening (dot paths, array indices included) ──────────────────\n\nexport function flattenNumeric(\n value: unknown,\n prefix = '',\n out: Record<string, number> = {},\n): Record<string, number> {\n if (typeof value === 'number') {\n if (prefix) out[prefix] = value\n return out\n }\n if (value !== null && typeof value === 'object') {\n const entries = Array.isArray(value)\n ? value.map((v, i) => [String(i), v] as const)\n : Object.entries(value)\n for (const [key, v] of entries) {\n flattenNumeric(v, prefix ? `${prefix}.${key}` : key, out)\n }\n }\n return out\n}\n\nfunction setPath(target: Record<string, unknown>, path: string, value: number): void {\n const keys = path.split('.')\n let node: Record<string, unknown> = target\n for (let i = 0; i < keys.length - 1; i++) {\n const next = node[keys[i]!]\n if (next === null || typeof next !== 'object') return // structure changed under us\n node = next as Record<string, unknown>\n }\n node[keys[keys.length - 1]!] = value\n}\n\n/** Apply the flat numeric leaves onto a config object in place (no allocation). */\nfunction applyFlat(target: Record<string, unknown>, flat: Record<string, number>): void {\n for (const path in flat) setPath(target, path, flat[path]!)\n}\n\nconst clone = <T>(v: T): T => JSON.parse(JSON.stringify(v)) as T\n\n// ── The machine ──────────────────────────────────────────────────────────────\n\nexport interface PaperStateMachineOptions {\n /** Reduced motion: every transition applies instantly (duration 0). */\n instant?: boolean\n /**\n * Fires on STRUCTURAL boundaries only — a transition's start and settle, a\n * state swap, a rebase — with an immutable config snapshot. NOT per tick;\n * per-frame numeric values are polled off `liveConfig`.\n */\n onChange?: (config: PaperConfig, state: string) => void\n /** `onEnter` actions — v1 is 'emit:<event>' only; fires after arrival. */\n onAction?: (event: string, state: string) => void\n}\n\nexport class PaperStateMachine {\n state: string\n private base: PaperConfig\n private readonly opts: PaperStateMachineOptions\n /** Structural target of the current state; numeric leaves live in `flat`. */\n private structure: PaperConfig\n /**\n * The single live tween target — flattened numeric leaves of the config.\n * STABLE IDENTITY for the machine's lifetime: `goto`/`rebase` mutate it in\n * place (add/remove/keep keys) and never reassign, so an in-flight GSAP\n * tween keeps animating the same object across a rebase instead of freezing.\n */\n private readonly flat: Record<string, number> = {}\n /** Mutable working config, polled by the consumer's frame loop via `liveConfig`. */\n private live: PaperConfig\n private tween: gsap.core.Tween | null = null\n private resolved = new Map<string, PaperConfig>()\n\n constructor(base: PaperConfig, opts: PaperStateMachineOptions = {}) {\n this.base = base\n this.opts = opts\n this.state = base.states?.initial ?? 'rest'\n const target = this.resolve(this.state)\n this.structure = clone(target)\n this.live = clone(target)\n Object.assign(this.flat, flattenNumeric(target))\n }\n\n /** World-units drag distance that flips pressed → picked. */\n get pickThreshold(): number {\n return this.base.states?.pickThreshold ?? 0.1\n }\n\n /**\n * The live config — the mutable working object with the current tween values\n * applied in place. Cheap (no allocation); meant to be polled every frame.\n * Never hand this to React; use `structuralConfig()` for an immutable snapshot.\n */\n get liveConfig(): PaperConfig {\n applyFlat(this.live as unknown as Record<string, unknown>, this.flat)\n return this.live\n }\n\n /** Back-compat alias for `liveConfig` (tests, imperative reads). */\n get config(): PaperConfig {\n return this.liveConfig\n }\n\n /** True while a transition tween is in flight — consumers gate frame work on it. */\n get transitioning(): boolean {\n return this.tween !== null\n }\n\n /** Exposed for tests: the in-flight transition tween, if any. */\n get activeTween(): gsap.core.Tween | null {\n return this.tween\n }\n\n /** An immutable structural snapshot for React consumers (never the live object). */\n structuralConfig(): PaperConfig {\n const out = clone(this.structure) as unknown as Record<string, unknown>\n applyFlat(out, this.flat)\n return out as unknown as PaperConfig\n }\n\n /** Fire a built-in trigger; returns the new state or null if it doesn't apply. */\n send(event: StateEvent): string | null {\n const next = stateEventTransitions[this.state]?.[event]\n if (!next || next === this.state) return null\n this.goto(next)\n return next\n }\n\n /**\n * Drive to 'picked' through the legal chain (rest→hover→pressed→picked),\n * each hop instant so EVERY side effect fires (behavior override, backing\n * silhouette, onChange state reports, placed onEnter chain). This is the\n * keyboard/a11y entry point — it never produced pointer hover/press events,\n * so raw `send('pick')` from 'rest' was a no-op. Returns true if it landed.\n */\n pickProgrammatic(): boolean {\n for (const event of ['enter', 'down', 'pick'] as StateEvent[]) {\n const next = stateEventTransitions[this.state]?.[event]\n if (next && next !== this.state) this.goto(next, { instant: true })\n }\n return this.state === 'picked'\n }\n\n /** Instant, legal place (picked → placed) so onEnter/emit fires. */\n placeProgrammatic(): boolean {\n return this.driveInstant('place')\n }\n\n /** Instant, legal return (picked → rest). */\n returnProgrammatic(): boolean {\n return this.driveInstant('return')\n }\n\n private driveInstant(event: StateEvent): boolean {\n const next = stateEventTransitions[this.state]?.[event]\n if (!next || next === this.state) return false\n this.goto(next, { instant: true })\n return true\n }\n\n /** Transition to a state (escape hatch for custom states; `send` for triggers). */\n goto(state: string, opts?: { instant?: boolean }): void {\n const def = this.base.states?.states[state]\n const target = this.resolve(state)\n this.state = state\n\n const targetFlat = flattenNumeric(target)\n // Structure swaps immediately (content/stock changes don't interpolate);\n // numeric leaves keep their CURRENT values and tween to the target.\n this.structure = clone(target)\n this.live = clone(target)\n const changed: Record<string, number> = {}\n // Mutate `flat` in place (stable identity): drop stale keys, keep live\n // values for shared paths, seed new paths at their target.\n for (const path in this.flat) {\n if (!(path in targetFlat)) delete this.flat[path]\n }\n for (const [path, value] of Object.entries(targetFlat)) {\n const current = this.flat[path]\n // Paths new to this structure appear at their target value — there is\n // no current value to tween from.\n if (current === undefined) this.flat[path] = value\n else if (current !== value) changed[path] = value\n }\n\n const duration =\n this.opts.instant || opts?.instant ? 0 : (def?.transition.duration ?? DEFAULT_TRANSITION.duration)\n const ease = def?.transition.ease ?? DEFAULT_TRANSITION.ease\n\n // One tween, ever — kill the previous instead of stacking. Values pick up\n // exactly where the killed tween left them (this.flat is the target).\n this.tween?.kill()\n this.tween = null\n\n const arrive = () => {\n for (const [path, value] of Object.entries(changed)) this.flat[path] = value\n this.emitStructure()\n for (const action of def?.onEnter ?? []) {\n if (action.startsWith('emit:')) this.opts.onAction?.(action.slice(5), state)\n }\n }\n\n if (duration === 0 || Object.keys(changed).length === 0) {\n arrive()\n return\n }\n // Structural boundary #1: the start of the transition (React sees the new\n // state and structure). Ticks below never emit — GSAP mutates `flat`, the\n // consumer polls `liveConfig`; #2 is the settle in `arrive`.\n this.emitStructure()\n this.tween = gsap.to(this.flat, {\n ...changed,\n duration,\n ease,\n onComplete: () => {\n this.tween = null\n arrive()\n },\n })\n }\n\n /**\n * Swap the base config without resetting the machine — parameter edits and\n * runtime patches (torn perforation on detach) keep the current state and\n * live values instead of snapping back to `initial`. An in-flight tween is\n * left running on the SAME `flat` object, so the transition continues\n * smoothly to its target across the rebase (no freeze, no snap).\n */\n rebase(base: PaperConfig): void {\n this.base = base\n this.resolved.clear()\n const target = this.resolve(this.state)\n this.structure = clone(target)\n this.live = clone(target)\n const targetFlat = flattenNumeric(target)\n // In-place, identity-preserving: drop stale keys, seed genuinely new paths\n // at target, keep every existing (possibly mid-tween) value untouched.\n for (const path in this.flat) {\n if (!(path in targetFlat)) delete this.flat[path]\n }\n for (const [path, value] of Object.entries(targetFlat)) {\n if (!(path in this.flat)) this.flat[path] = value\n }\n // Structural change (e.g. perforation flipped to torn) → re-render the\n // structure; the tween keeps animating `flat`, so values never snap.\n this.emitStructure()\n }\n\n dispose(): void {\n this.tween?.kill()\n this.tween = null\n }\n\n private resolve(state: string): PaperConfig {\n let config = this.resolved.get(state)\n if (!config) {\n config = resolveStateConfig(this.base, state)\n this.resolved.set(state, config)\n }\n return config\n }\n\n private emitStructure(): void {\n this.opts.onChange?.(this.structuralConfig(), this.state)\n }\n}\n","import * as THREE from 'three'\nimport { useEffect, useMemo, useRef } from 'react'\nimport { useFrame, useThree } from '@react-three/fiber'\nimport { ContactShadows } from '@react-three/drei'\nimport type { LightingName } from '../config/schema'\nimport { getLightingPreset } from './lighting'\nimport { usePrefersReducedMotion } from '../a11y'\n\n/** Deterministic PRNG so gobos render identically everywhere. */\nfunction mulberry32(seed: number) {\n let a = seed\n return () => {\n a |= 0\n a = (a + 0x6d2b79f5) | 0\n let t = Math.imul(a ^ (a >>> 15), 1 | a)\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\n/**\n * Procedural gobo textures — no binary assets in the repo. White passes\n * light, dark blocks it (SpotLight.map multiplies the beam).\n */\nexport function makeGoboTexture(kind: 'blinds' | 'leaves'): THREE.CanvasTexture {\n const size = 512\n const canvas = document.createElement('canvas')\n canvas.width = canvas.height = size\n const ctx = canvas.getContext('2d')!\n ctx.fillStyle = '#ffffff'\n ctx.fillRect(0, 0, size, size)\n\n if (kind === 'blinds') {\n // Venetian slats: soft-edged dark bars, slightly rotated.\n ctx.save()\n ctx.translate(size / 2, size / 2)\n ctx.rotate(-0.06)\n const slat = 34\n const gap = 30\n for (let y = -size; y < size; y += slat + gap) {\n const grad = ctx.createLinearGradient(0, y, 0, y + slat)\n grad.addColorStop(0, 'rgba(20,20,20,0)')\n grad.addColorStop(0.25, 'rgba(20,20,20,0.92)')\n grad.addColorStop(0.75, 'rgba(20,20,20,0.92)')\n grad.addColorStop(1, 'rgba(20,20,20,0)')\n ctx.fillStyle = grad\n ctx.fillRect(-size, y, size * 2, slat)\n }\n ctx.restore()\n } else {\n // Dappled foliage: three scales of soft dark blobs.\n const rand = mulberry32(7)\n for (const [count, radius, alpha] of [\n [26, 70, 0.75],\n [40, 38, 0.6],\n [70, 16, 0.5],\n ] as const) {\n for (let i = 0; i < count; i++) {\n const x = rand() * size\n const y = rand() * size\n const r = radius * (0.6 + rand() * 0.8)\n const grad = ctx.createRadialGradient(x, y, 0, x, y, r)\n grad.addColorStop(0, `rgba(15,20,12,${alpha})`)\n grad.addColorStop(0.7, `rgba(15,20,12,${alpha * 0.55})`)\n grad.addColorStop(1, 'rgba(15,20,12,0)')\n ctx.fillStyle = grad\n ctx.beginPath()\n ctx.ellipse(x, y, r, r * (0.6 + rand() * 0.5), rand() * Math.PI, 0, Math.PI * 2)\n ctx.fill()\n }\n }\n }\n\n const texture = new THREE.CanvasTexture(canvas)\n texture.wrapS = texture.wrapT = THREE.RepeatWrapping\n return texture\n}\n\nexport interface PaperLightingProps {\n preset?: LightingName\n /** Local y of the ground the contact shadow sits on. */\n floor?: number\n /** Contact shadow footprint. */\n scale?: number\n /** Override prefers-reduced-motion (freezes gobo drift). */\n reducedMotion?: boolean\n /**\n * Shadow map resolution, overriding the preset's. 0 turns the shadow pass\n * off — it re-renders the scene's geometry, so on a weak machine it is\n * often the single most expensive thing in the frame.\n */\n shadowMapSize?: number\n /** Draw the soft contact shadow. It is its own render pass. */\n contactShadow?: boolean\n}\n\n/**\n * A scene's lighting rig from one serialized name: key light (spot with a\n * procedural gobo, or directional), ambient fill, tone-mapping exposure,\n * and the contact shadow. Swap presets to restyle the same paper.\n */\nexport function PaperLighting({\n preset = 'studio',\n floor = -1.2,\n scale = 10,\n reducedMotion,\n shadowMapSize,\n contactShadow = true,\n}: PaperLightingProps) {\n const p = getLightingPreset(preset)\n const mapSize = shadowMapSize ?? p.shadow.mapSize\n const castShadow = mapSize > 0\n const reduced = usePrefersReducedMotion(reducedMotion)\n const gl = useThree((s) => s.gl)\n const scene = useThree((s) => s.scene)\n\n useEffect(() => {\n const previous = gl.toneMappingExposure\n gl.toneMappingExposure = p.exposure\n return () => {\n gl.toneMappingExposure = previous\n }\n }, [gl, p.exposure])\n\n // Set imperatively rather than via <fog attach=\"fog\" />, which would bind\n // to whatever group this rig happens to be mounted under instead of the scene.\n useEffect(() => {\n if (!p.fog) return\n const previous = scene.fog\n scene.fog = new THREE.Fog(p.fog.color, p.fog.near, p.fog.far)\n return () => {\n scene.fog = previous\n }\n }, [scene, p.fog])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: Only the gobo kind rebuilds the texture — drift and intensity animate in place.\n const goboMap = useMemo(() => (p.gobo ? makeGoboTexture(p.gobo.kind) : null), [p.gobo?.kind])\n useEffect(() => () => goboMap?.dispose(), [goboMap])\n\n const driftRef = useRef(0)\n useFrame((_, delta) => {\n if (!goboMap || !p.gobo || reduced) return\n driftRef.current += delta * p.gobo.drift\n goboMap.offset.set(driftRef.current, driftRef.current * 0.6)\n })\n\n return (\n <>\n <ambientLight intensity={p.ambient} />\n {p.gobo && goboMap ? (\n <spotLight\n position={p.key.position}\n color={p.key.color}\n // decay 0 keeps intensity art-directable rather than distance-driven.\n intensity={p.key.intensity * 3.2}\n angle={p.gobo.angle}\n penumbra={0.5}\n decay={0}\n castShadow={castShadow}\n map={goboMap}\n shadow-mapSize={[mapSize || 1, mapSize || 1]}\n shadow-radius={p.shadow.radius}\n shadow-normalBias={0.05}\n />\n ) : (\n <directionalLight\n position={p.key.position}\n color={p.key.color}\n intensity={p.key.intensity}\n castShadow={castShadow}\n shadow-mapSize={[mapSize || 1, mapSize || 1]}\n shadow-radius={p.shadow.radius}\n shadow-normalBias={0.05}\n />\n )}\n {contactShadow && (\n <ContactShadows\n position={[0, floor, 0]}\n opacity={p.contactShadowOpacity}\n scale={scale}\n blur={p.contactShadowBlur}\n far={3}\n />\n )}\n </>\n )\n}\n","import * as THREE from 'three'\nimport { gsap } from 'gsap'\nimport { Canvas, useFrame, useThree } from '@react-three/fiber'\nimport { forwardRef, useEffect, useMemo, useRef } from 'react'\nimport type { PaperConfigInput } from './config/schema'\nimport { usePrefersReducedMotion } from './a11y'\nimport { DropZoneContext, DropZoneRegistry, type DropZoneConfig, type PlacedPaper } from './field/dropZones'\nimport {\n EMPTY_SET,\n effectiveFieldPapers,\n fieldIsInteractive,\n groupFieldPapers,\n type FieldPaperSlot,\n} from './field/slots'\nimport { FieldGroup, type SharedMotion } from './field/fieldGroup'\nimport { BackingSheet } from './field/backingSheet'\nimport { InteractiveField, type FieldA11yController } from './field/interactiveField'\nimport { FieldKeyboardMirror } from './field/keyboardMirror'\nimport { DEFAULT_SHEET, getLayout } from './field/layouts'\nimport type { SheetLayoutOptions } from './field/sheetGrid'\nimport { fitCamera, resolveLayoutOptions } from './field/framing'\n\n// The field system lives in field/*; this module is the public composition.\n// Re-exported here so `import { … } from './PaperField'` (index.ts, tests,\n// consumers) keeps working across the split.\nexport {\n DropZone,\n DropZoneRegistry,\n zoneAccepts,\n type DropZoneConfig,\n type DropZoneProps,\n type PlacedPaper,\n} from './field/dropZones'\nexport {\n groupFieldPapers,\n resolveFieldSlotConfig,\n type FieldPaperSlot,\n type FieldGroupData,\n} from './field/slots'\nexport type { FieldA11yController } from './field/interactiveField'\nexport {\n fieldKeyboardStep,\n type KeyboardCarry,\n type KeyboardStepResult,\n} from './field/keyboardMirror'\n\nexport interface PaperFieldMeshProps {\n /** Per-paper slots; length sets the instance count. Slot presets override the shared one. */\n papers?: FieldPaperSlot[]\n /** Sugar: image URLs → papers with image content. */\n images?: string[]\n /** Shared preset for slots that don't name their own. */\n preset?: string | PaperConfigInput\n layout?: string\n layoutOptions?: Record<string, unknown>\n motion?: { driver?: 'autoplay' | 'drag' | 'none'; speed?: number }\n entrance?: { type?: 'rise' | 'scatter' | 'none'; stagger?: number; duration?: number }\n /** Override prefers-reduced-motion (default: follow the system setting). */\n reducedMotion?: boolean\n /**\n * Per-paper interaction (hero CPU path per slot instead of one instanced\n * draw call). Defaults to true when any slot's preset carries `states` —\n * a stateful field is interactive by nature.\n */\n interactive?: boolean\n /** Fires when any slot's state machine changes state. */\n onSlotStateChange?(slot: number, state: string): void\n /** Serialized drop zones (the editor's path); `<DropZone>` children also work. */\n zones?: DropZoneConfig[]\n /** Fires when a picked paper settles into any zone. */\n onPlace?(paper: PlacedPaper, zone: string): void\n /** Imperative controls for the hidden keyboard flow (wired by PaperField). */\n a11yControllerRef?: React.MutableRefObject<FieldA11yController | null>\n}\n\nexport interface PaperFieldProps extends PaperFieldMeshProps {\n children?: React.ReactNode\n className?: string\n style?: React.CSSProperties\n}\n\n/**\n * Field mode: sheets render as one instanced draw call PER DISTINCT PRESET\n * (usually one). Deformer stacks run as composed GLSL vertex chunks\n * (parity-tested against the CPU path); content lives in per-group atlases;\n * motion state (driver phase, entrance clock, layout morph) is shared so\n * mixed-preset fields move as one field.\n */\nexport const PaperFieldMesh = forwardRef<THREE.Group, PaperFieldMeshProps>(\n function PaperFieldMesh(props, ref) {\n const reduced = usePrefersReducedMotion(props.reducedMotion)\n\n const papers = useMemo<FieldPaperSlot[]>(\n () => effectiveFieldPapers(props.papers, props.images),\n [props.papers, props.images],\n )\n // biome-ignore lint/correctness/useExhaustiveDependencies: Serialized deps — papers and preset are fresh objects every render.\n const groups = useMemo(\n () => groupFieldPapers(papers, props.preset),\n [JSON.stringify(papers), JSON.stringify(props.preset ?? null)],\n )\n const total = papers.length\n\n const layoutId = props.layout ?? 'ring'\n const layout = getLayout(layoutId)\n const firstSheet = groups[0]?.config.sheet\n // biome-ignore lint/correctness/useExhaustiveDependencies: Serialized deps — layoutOptions and the first sheet are fresh objects every render.\n const layoutOptions = useMemo(\n // Sheet grids size their cells from the papers themselves — gutter is\n // then literally the spacing between stamps (explicit cell dims win).\n () => resolveLayoutOptions(layoutId, layout, props.layoutOptions, firstSheet),\n [layoutId, JSON.stringify(props.layoutOptions ?? {}), firstSheet?.width, firstSheet?.height],\n )\n\n // ── Shared motion state: one driver phase / entrance clock / morph for\n // every group, so a mixed-preset field moves as one field. ──\n const phaseRef = useRef(0)\n const dragVelRef = useRef(0)\n const mountTimeRef = useRef(-1)\n const morphRef = useRef<SharedMotion['morphRef']['current']>({ from: null, t: 1 })\n const prevLayout = useRef({ id: layoutId, options: layoutOptions })\n const gl = useThree((s) => s.gl)\n\n const driver = reduced ? 'none' : (props.motion?.driver ?? 'autoplay')\n const speed = props.motion?.speed ?? 0.5\n const entranceType = reduced ? 'none' : (props.entrance?.type ?? 'rise')\n\n useEffect(() => {\n const prev = prevLayout.current\n if (prev.id !== layoutId || JSON.stringify(prev.options) !== JSON.stringify(layoutOptions)) {\n morphRef.current = { from: prev, t: 0 }\n gsap.to(morphRef.current, { t: 1, duration: 0.9, ease: 'power2.inOut' })\n prevLayout.current = { id: layoutId, options: layoutOptions }\n }\n }, [layoutId, layoutOptions])\n\n useEffect(() => {\n if (driver !== 'drag') return\n const el = gl.domElement\n let lastX: number | null = null\n const down = (e: PointerEvent) => {\n lastX = e.clientX\n }\n const move = (e: PointerEvent) => {\n if (lastX === null) return\n const dx = e.clientX - lastX\n lastX = e.clientX\n phaseRef.current += dx * 0.0012\n dragVelRef.current = dx * 0.0012\n }\n const up = () => {\n lastX = null\n }\n el.addEventListener('pointerdown', down)\n window.addEventListener('pointermove', move)\n window.addEventListener('pointerup', up)\n return () => {\n el.removeEventListener('pointerdown', down)\n window.removeEventListener('pointermove', move)\n window.removeEventListener('pointerup', up)\n }\n }, [driver, gl])\n\n useFrame(({ clock }, delta) => {\n if (mountTimeRef.current < 0) mountTimeRef.current = clock.elapsedTime\n if (driver === 'autoplay') phaseRef.current += delta * speed * 0.02\n if (driver === 'drag') {\n phaseRef.current += dragVelRef.current * 0.5\n dragVelRef.current *= 0.94\n }\n })\n\n const shared: SharedMotion = {\n phaseRef,\n mountTimeRef,\n morphRef,\n layoutId,\n layoutOptions,\n sheet: firstSheet ?? DEFAULT_SHEET,\n entranceType,\n stagger: props.entrance?.stagger ?? 0.06,\n entranceDuration: props.entrance?.duration ?? 0.9,\n total,\n reduced,\n }\n\n // A stateful field is interactive by nature: per-paper hero path (CPU,\n // raycastable, per-slot state machines) instead of one instanced call.\n // (`groups` already resolved every preset, so reuse them for the check.)\n const interactive =\n props.interactive ?? (papers.some((s) => s.states) || groups.some((g) => Boolean(g.config.states)))\n\n const isSheet = layoutId === 'sheet'\n const sheetOptions = isSheet ? (layoutOptions as SheetLayoutOptions) : null\n\n if (interactive) {\n return (\n <group ref={ref}>\n <InteractiveField\n papers={papers}\n fallback={props.preset}\n layoutId={layoutId}\n layoutOptions={layoutOptions}\n sheetOptions={sheetOptions}\n sheet={firstSheet ?? DEFAULT_SHEET}\n reducedMotion={props.reducedMotion}\n zones={props.zones}\n onSlotStateChange={props.onSlotStateChange}\n onPlace={props.onPlace}\n a11yRef={props.a11yControllerRef}\n />\n </group>\n )\n }\n\n return (\n <group ref={ref}>\n {sheetOptions?.backing && <BackingSheet options={sheetOptions} count={total} removed={EMPTY_SET} />}\n {groups.map((group, gi) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: groups are derived from the slot list in order, so position is their only identity.\n <FieldGroup key={`${gi}:${group.indices.length}`} group={group} shared={shared} />\n ))}\n </group>\n )\n },\n)\n\n/**\n * Frames whatever the layout actually lays out. A fixed camera can only suit\n * one layout — a `wall` of 12 runs past the top of a frame that a `pile`\n * leaves nearly empty — and layouts are pure, so the right distance is just\n * arithmetic over their poses.\n */\nfunction FitCamera(meshProps: PaperFieldMeshProps) {\n const camera = useThree((s) => s.camera)\n const width = useThree((s) => s.size.width)\n const height = useThree((s) => s.size.height)\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: Serialized deps — the camera refits on prop *content*, not on identity.\n const field = useMemo(() => {\n const papers = effectiveFieldPapers(meshProps.papers, meshProps.images)\n const layoutId = meshProps.layout ?? 'ring'\n const layout = getLayout(layoutId)\n const sheet = groupFieldPapers(papers, meshProps.preset)[0]?.config.sheet\n const options = resolveLayoutOptions(layoutId, layout, meshProps.layoutOptions, sheet)\n return { layout, n: papers.length, options, sheet: sheet ?? DEFAULT_SHEET }\n }, [\n JSON.stringify(meshProps.papers ?? null),\n JSON.stringify(meshProps.images ?? null),\n JSON.stringify(meshProps.preset ?? null),\n meshProps.layout,\n JSON.stringify(meshProps.layoutOptions ?? {}),\n ])\n\n useEffect(() => {\n if (!(camera instanceof THREE.PerspectiveCamera)) return\n const { position, target } = fitCamera(\n field.layout,\n field.n,\n field.options,\n field.sheet,\n camera.fov,\n width / Math.max(height, 1),\n )\n camera.position.set(...position)\n camera.lookAt(...target)\n camera.updateProjectionMatrix()\n }, [camera, width, height, field])\n\n return null\n}\n\n/** `<PaperField />` owns its own Canvas; PaperFieldMesh drops into existing scenes. */\nexport const PaperField = forwardRef<THREE.Group, PaperFieldProps>(function PaperField(\n { children, className, style, ...meshProps },\n ref,\n) {\n const registry = useMemo(() => new DropZoneRegistry(), [])\n const a11yRef = useRef<FieldA11yController | null>(null)\n\n // The SAME derivations PaperFieldMesh uses — a slot naming a stateful\n // preset by string, or an images-driven field, must get the keyboard\n // mirror exactly when the mesh goes interactive.\n const papers = useMemo(\n () => effectiveFieldPapers(meshProps.papers, meshProps.images),\n [meshProps.papers, meshProps.images],\n )\n // biome-ignore lint/correctness/useExhaustiveDependencies: Serialized deps — must match the mesh derivation above exactly.\n const interactive = useMemo(\n () => fieldIsInteractive(papers, meshProps.preset, meshProps.interactive),\n [JSON.stringify(papers), JSON.stringify(meshProps.preset ?? null), meshProps.interactive],\n )\n\n return (\n <div className={className} style={{ width: '100%', height: '100%', ...style }}>\n <DropZoneContext.Provider value={registry}>\n <Canvas shadows camera={{ position: [0, 0.6, 5.2], fov: 45 }} dpr={[1, 2]}>\n <FitCamera {...meshProps} />\n <ambientLight intensity={0.7} />\n <directionalLight\n position={[3, 5, 4]}\n intensity={1.4}\n castShadow\n shadow-mapSize={[1024, 1024]}\n shadow-normalBias={0.05}\n />\n <PaperFieldMesh ref={ref} a11yControllerRef={a11yRef} {...meshProps} />\n {children}\n </Canvas>\n {interactive && <FieldKeyboardMirror papers={papers} controller={a11yRef} />}\n </DropZoneContext.Provider>\n </div>\n )\n})\n","import * as THREE from 'three'\nimport { createContext, useContext, useEffect, useMemo, useSyncExternalStore } from 'react'\nimport type { PaperConfig } from '../config/schema'\n\n// ── Drop zones (spec M6 §5) ──────────────────────────────────────────────────\n\nexport interface DropZoneConfig {\n id: string\n /** Preset-name globs ('stamp-*'); omitted = accept all. */\n accept?: string[]\n /** World-space rect on the field plane. */\n bounds: { position: [number, number, number]; size: [number, number] }\n highlight?: 'none' | 'glow' | 'outline'\n}\n\nexport interface PlacedPaper {\n slot: number\n presetName: string\n config: PaperConfig\n}\n\nexport interface DropZoneProps extends DropZoneConfig {\n onPlace?(paper: PlacedPaper, zone: string): void\n}\n\nexport interface ZoneEntry extends DropZoneConfig {\n onPlace?: DropZoneProps['onPlace']\n}\n\n/** Shared zone state: `<DropZone>` children register; the carry loop hit-tests. */\nexport class DropZoneRegistry {\n private zones = new Map<string, ZoneEntry>()\n private hoveredId: string | null = null\n private listeners = new Set<() => void>()\n private version = 0\n\n register(zone: ZoneEntry): () => void {\n this.zones.set(zone.id, zone)\n this.notify()\n return () => {\n this.zones.delete(zone.id)\n this.notify()\n }\n }\n\n list(): ZoneEntry[] {\n return [...this.zones.values()]\n }\n\n get(id: string): ZoneEntry | undefined {\n return this.zones.get(id)\n }\n\n get hovered(): string | null {\n return this.hoveredId\n }\n\n setHovered(id: string | null): void {\n if (this.hoveredId === id) return\n this.hoveredId = id\n this.notify()\n }\n\n subscribe = (fn: () => void): (() => void) => {\n this.listeners.add(fn)\n return () => this.listeners.delete(fn)\n }\n\n getVersion = (): number => this.version\n\n private notify(): void {\n this.version++\n for (const fn of this.listeners) fn()\n }\n}\n\nexport const DropZoneContext = createContext<DropZoneRegistry | null>(null)\n\n// Compiled accept-globs, cached — zoneAccepts runs every frame in the carry\n// loop, and a fresh RegExp per glob per frame is pure GC churn.\nconst globCache = new Map<string, RegExp>()\nconst globRegExp = (glob: string): RegExp => {\n let re = globCache.get(glob)\n if (!re) {\n re = new RegExp(`^${glob.replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '.*')}$`, 'i')\n globCache.set(glob, re)\n }\n return re\n}\n\n/** True when `name` matches the zone's accept globs (all zones accept by default). */\nexport function zoneAccepts(zone: Pick<DropZoneConfig, 'accept'>, name: string): boolean {\n if (!zone.accept || zone.accept.length === 0) return true\n return zone.accept.some((glob) => globRegExp(glob).test(name))\n}\n\nexport const zoneContains = (zone: ZoneEntry, x: number, y: number): boolean =>\n Math.abs(x - zone.bounds.position[0]) <= zone.bounds.size[0] / 2 &&\n Math.abs(y - zone.bounds.position[1]) <= zone.bounds.size[1] / 2\n\n/**\n * A drop target inside a `<PaperField>`. While a paper is picked, its center\n * is tested against the bounds each frame; hovering applies the highlight\n * and release inside fires `placed` + `onPlace`.\n */\nexport function DropZone(props: DropZoneProps) {\n const registry = useContext(DropZoneContext)\n const { id, accept, bounds, highlight = 'glow', onPlace } = props\n // biome-ignore lint/correctness/useExhaustiveDependencies: Serialized deps — re-registering on object identity would thrash the registry.\n useEffect(() => {\n if (!registry) return\n return registry.register({ id, accept, bounds, highlight, onPlace })\n }, [registry, id, JSON.stringify(accept ?? null), JSON.stringify(bounds), highlight, onPlace])\n if (!registry) return null\n return <DropZoneVisual registry={registry} config={{ id, accept, bounds, highlight }} />\n}\n\n/** The translucent target — brightens when the carried paper is over it. */\nexport function DropZoneVisual({ registry, config }: { registry: DropZoneRegistry; config: DropZoneConfig }) {\n useSyncExternalStore(registry.subscribe, registry.getVersion, registry.getVersion)\n const hovered = registry.hovered === config.id\n const style = config.highlight ?? 'glow'\n const [w, h] = config.bounds.size\n // Memoized: an inline `new THREE.PlaneGeometry` in args would rebuild (and\n // leak) the edges every render — and this re-renders on every hover change.\n const edges = useMemo(() => {\n const plane = new THREE.PlaneGeometry(w, h)\n const geo = new THREE.EdgesGeometry(plane)\n plane.dispose()\n return geo\n }, [w, h])\n useEffect(() => () => edges.dispose(), [edges])\n return (\n <group position={config.bounds.position}>\n {style !== 'outline' && (\n <mesh>\n <planeGeometry args={[w, h]} />\n <meshBasicMaterial\n color={hovered && style === 'glow' ? '#8ea8ff' : '#5c6f9e'}\n transparent\n opacity={hovered && style === 'glow' ? 0.32 : 0.14}\n depthWrite={false}\n />\n </mesh>\n )}\n <lineSegments geometry={edges}>\n <lineBasicMaterial color={hovered ? '#aebfff' : '#6b7da8'} />\n </lineSegments>\n </group>\n )\n}\n","import { z } from 'zod'\nimport type { PaperEdge } from '../config/schema'\nimport type { CurlOptions } from '../deformers/curl'\n\n/**\n * Pure grid math for the `sheet` layout — a block of stamps on a shared\n * backing. Shared by the layout's pose function, the backing silhouette\n * renderer, the outward-corner smart default, and the torn-perforation\n * auto-wiring, so they can never disagree about where a slot sits.\n */\n\nexport const sheetLayoutSchema = z.object({\n rows: z.number().int().min(1).max(12).default(2),\n columns: z.number().int().min(1).max(12).default(5),\n /** World-units gap between slots. Stamps are printed in register — no jitter. */\n gutter: z.number().min(0).max(1).default(0.08),\n /** Slot footprint in world units (the paper preset should match). */\n cellWidth: z.number().min(0.1).max(4).default(0.72),\n cellHeight: z.number().min(0.1).max(4).default(0.86),\n /** Render the shared backing sheet behind the grid. */\n backing: z.boolean().default(true),\n backingMargin: z.number().min(0).max(1).default(0.12),\n})\n\nexport type SheetLayoutOptions = z.infer<typeof sheetLayoutSchema>\n\n/** Backing thickness + ε — papers float just above the backing sheet. */\nexport const SHEET_LIFT = 0.012\n\n/**\n * Cell footprint = the paper's own sheet dims unless the user set an\n * explicit cellWidth/cellHeight — so `gutter` is literally the spacing\n * between stamps, whatever preset populates the grid.\n */\nexport function withSheetCellFromPaper(\n parsed: SheetLayoutOptions,\n rawOptions: Record<string, unknown> | undefined,\n paperDims: { width: number; height: number } | undefined,\n): SheetLayoutOptions {\n if (!paperDims) return parsed\n const hasW = rawOptions !== undefined && rawOptions.cellWidth !== undefined\n const hasH = rawOptions !== undefined && rawOptions.cellHeight !== undefined\n if (hasW && hasH) return parsed\n return {\n ...parsed,\n cellWidth: hasW ? parsed.cellWidth : paperDims.width,\n cellHeight: hasH ? parsed.cellHeight : paperDims.height,\n }\n}\n\nexport function sheetSlotXY(i: number, o: SheetLayoutOptions): { x: number; y: number } {\n const col = i % o.columns\n const row = Math.floor(i / o.columns)\n return {\n x: (col - (o.columns - 1) / 2) * (o.cellWidth + o.gutter),\n y: ((o.rows - 1) / 2 - row) * (o.cellHeight + o.gutter),\n }\n}\n\n/** Grid bounds + margin — the backing sheet's size. */\nexport function sheetBackingSize(o: SheetLayoutOptions): { width: number; height: number } {\n return {\n width: o.columns * o.cellWidth + (o.columns - 1) * o.gutter + o.backingMargin * 2,\n height: o.rows * o.cellHeight + (o.rows - 1) * o.gutter + o.backingMargin * 2,\n }\n}\n\ntype Corner = CurlOptions['corner']\n\n/**\n * The corner facing away from the sheet's center — what a thumb would find\n * (spec M6 §1.3). A tie (an odd grid's exact-center row/column, where the\n * cell straddles the midline) breaks outward-and-down: strict `<` on both\n * axes sends the center right and down, so a dead-center cell peels\n * bottom-right — the standalone peel default.\n */\nexport function outwardCorner(i: number, o: Pick<SheetLayoutOptions, 'rows' | 'columns'>): Corner {\n const col = i % o.columns\n const row = Math.floor(i / o.columns)\n // Row 0 renders at the top of the grid.\n const horizontal = col + 0.5 < o.columns / 2 ? 'left' : 'right'\n const vertical = row + 0.5 < o.rows / 2 ? 'top' : 'bottom'\n return `${vertical}-${horizontal}` as Corner\n}\n\n/**\n * Perforation auto-wiring on detach: edges that faced a neighboring slot tear\n * through; edges on the sheet's outer boundary keep their clean punches.\n */\nexport function tornEdgesOnDetach(\n i: number,\n o: Pick<SheetLayoutOptions, 'rows' | 'columns'>,\n): Partial<Record<PaperEdge, 'torn' | 'intact'>> {\n const col = i % o.columns\n const row = Math.floor(i / o.columns)\n return {\n top: row > 0 ? 'torn' : 'intact',\n bottom: row < o.rows - 1 ? 'torn' : 'intact',\n left: col > 0 ? 'torn' : 'intact',\n right: col < o.columns - 1 ? 'torn' : 'intact',\n }\n}\n","import {\n paperConfigSchema,\n type ContentConfig,\n type PaperConfig,\n type PaperConfigInput,\n type PaperStatesInput,\n} from '../config/schema'\nimport { mergeConfig } from '../config/merge'\nimport { resolveConfig } from '../PaperMesh'\nimport { outwardCorner, sheetLayoutSchema } from './sheetGrid'\n\n/** A field slot references a preset — the spec's component/instance model. */\nexport interface FieldPaperSlot {\n preset?: string | PaperConfigInput\n content?: ContentConfig\n /** Per-instance state overrides, merged over the preset's states (spec M6 §1.1). */\n states?: PaperStatesInput\n}\n\nexport interface FieldGroupData {\n config: PaperConfig\n /** Global slot indices this group renders (layout poses use global i / total n). */\n indices: number[]\n contents: ContentConfig[]\n}\n\nexport const EMPTY_SET: ReadonlySet<number> = new Set()\n\n/**\n * The effective slot list: explicit `papers`, the `images` sugar, or the\n * twelve-blank default. ONE derivation shared by PaperFieldMesh and the\n * PaperField wrapper, so the mesh and the keyboard mirror always agree on\n * which papers exist.\n */\nexport function effectiveFieldPapers(papers?: FieldPaperSlot[], images?: string[]): FieldPaperSlot[] {\n if (papers) return papers\n if (images) {\n return images.map((src) => ({\n content: { type: 'image', src, fit: 'cover' } as ContentConfig,\n }))\n }\n return Array.from({ length: 12 }, () => ({}))\n}\n\n/** Group slots by resolved preset — one instanced draw call per distinct preset. */\nexport function groupFieldPapers(\n papers: FieldPaperSlot[],\n fallback?: string | PaperConfigInput,\n): FieldGroupData[] {\n const groups = new Map<string, FieldGroupData>()\n papers.forEach((slot, i) => {\n const config = resolveConfig({ preset: slot.preset ?? fallback })\n const key = JSON.stringify(config)\n let group = groups.get(key)\n if (!group) {\n group = { config, indices: [], contents: [] }\n groups.set(key, group)\n }\n group.indices.push(i)\n group.contents.push(slot.content ?? config.content)\n })\n return [...groups.values()]\n}\n\n/**\n * Whether a field runs the per-paper interactive path. A stateful field is\n * interactive by nature — and \"stateful\" must RESOLVE presets: a slot naming\n * a stateful preset by string counts exactly like an inline `states` object.\n * The single decision shared by PaperFieldMesh (render path) and PaperField\n * (keyboard mirror), so pointer interaction and keyboard access never diverge.\n */\nexport function fieldIsInteractive(\n papers: FieldPaperSlot[],\n fallback?: string | PaperConfigInput,\n explicit?: boolean,\n): boolean {\n if (explicit !== undefined) return explicit\n return (\n papers.some((s) => s.states) || groupFieldPapers(papers, fallback).some((g) => Boolean(g.config.states))\n )\n}\n\n/**\n * Resolve one slot to its final render config: preset (or fallback) + slot\n * content + slot-level state overrides merged over the preset's states + the\n * `sheet` smart default (an 'auto' peel corner resolves to the corner facing\n * away from the sheet's center — what a thumb would find).\n */\nexport function resolveFieldSlotConfig(\n slot: FieldPaperSlot,\n fallback: string | PaperConfigInput | undefined,\n index: number,\n layoutId: string,\n layoutOptions: Record<string, unknown>,\n): PaperConfig {\n let config = resolveConfig({ preset: slot.preset ?? fallback })\n const patch: Record<string, unknown> = {}\n if (slot.content) patch.content = slot.content\n if (slot.states) patch.states = slot.states\n if (layoutId === 'sheet' && config.behavior?.type === 'peel' && config.behavior.corner === 'auto') {\n const o = sheetLayoutSchema.parse(layoutOptions)\n patch.behavior = { corner: outwardCorner(index, o) }\n }\n if (Object.keys(patch).length > 0) {\n config = paperConfigSchema.parse(mergeConfig(config as Record<string, unknown>, patch))\n }\n return config\n}\n","import * as THREE from 'three'\nimport { gsap } from 'gsap'\nimport { useFrame } from '@react-three/fiber'\nimport { useEffect, useMemo, useRef } from 'react'\nimport CustomShaderMaterial from 'three-custom-shader-material'\nimport { getStock } from '../core/stock'\nimport { createSheetGeometry } from '../core/sheet'\nimport { getBehavior } from '../behaviors/registry'\nimport { stackMinSegments } from '../deformers/compose'\nimport type { DeformerInstance, SheetDims } from '../deformers/types'\nimport type { AeroPose } from '../physics/aero'\nimport { useContentAtlas } from '../content/atlas'\nimport {\n buildDisplacementGLSL,\n buildFieldFragmentShader,\n buildFieldVertexShader,\n stackUniformValues,\n} from './compose'\nimport { getLayout, type PaperPose } from './layouts'\nimport { translucencyUniforms } from '../surface/translucency'\nimport { fieldShapeStack } from './stack'\nimport type { FieldGroupData } from './slots'\n\nconst scratchObj = new THREE.Object3D()\nconst scratchAero: AeroPose = { position: [0, 0, 0], rotation: [0, 0, 0] }\nexport const FIELD_SEGMENT_CAP = 48\n\n/** Motion state shared across groups so a mixed-preset field moves as one field. */\nexport interface SharedMotion {\n phaseRef: React.MutableRefObject<number>\n mountTimeRef: React.MutableRefObject<number>\n morphRef: React.MutableRefObject<{ from: { id: string; options: unknown } | null; t: number }>\n layoutId: string\n layoutOptions: Record<string, unknown>\n /** The field's paper size — one sheet for every group, so layouts agree. */\n sheet: SheetDims\n entranceType: 'rise' | 'scatter' | 'none'\n stagger: number\n entranceDuration: number\n total: number\n reduced: boolean\n}\n\n/** One instanced mesh: one preset's sheet/stock/behavior across its slots. */\nexport function FieldGroup({ group, shared }: { group: FieldGroupData; shared: SharedMotion }) {\n const { config, indices, contents } = group\n const count = indices.length\n const stock = getStock(config.stock)\n // A raw deformer stack is the Advanced fork of a behavior and wins over one\n // — the same precedence the hero path's buildStack applies. Field mode used\n // to read `behavior` only, so a preset shaped by `deformers` rendered flat.\n const behavior = config.behavior && !config.deformers ? getBehavior(config.behavior.type) : null\n\n const progressRef = useRef(\n behavior ? ((config.behavior as Record<string, unknown>)[behavior.progressParam] as number) : 0,\n )\n const buildStackAt = (progress: number): DeformerInstance[] => fieldShapeStack(config, progress)\n // biome-ignore lint/correctness/useExhaustiveDependencies: Serialized deps — the stack rebuilds on shape, not on identity.\n const initialStack = useMemo(\n () => buildStackAt(progressRef.current),\n [\n JSON.stringify(config.behavior ?? null),\n JSON.stringify(config.deformers ?? null),\n JSON.stringify(config.sheet),\n ],\n )\n const structureKey = initialStack.map((i) => i.type).join('|')\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: Keyed on sheet, stack structure and count — the only things that change the buffer.\n const geometry = useMemo(() => {\n const geo = createSheetGeometry(\n {\n ...config.sheet,\n segments:\n config.sheet.segments === 'auto' ? 'auto' : Math.min(config.sheet.segments, FIELD_SEGMENT_CAP),\n },\n Math.min(stackMinSegments(initialStack), FIELD_SEGMENT_CAP),\n )\n const atlasIdx = new Float32Array(count)\n const phase = new Float32Array(count)\n const bias = new Float32Array(count).fill(1)\n for (let i = 0; i < count; i++) {\n atlasIdx[i] = i\n phase[i] = ((indices[i]! * 0.618034) % 1) * 4 // golden-ratio spread by global slot\n }\n geo.setAttribute('aAtlas', new THREE.InstancedBufferAttribute(atlasIdx, 1))\n geo.setAttribute('aPhase', new THREE.InstancedBufferAttribute(phase, 1))\n // Per-sheet deformation strength, written from the layout's pose each\n // frame — how a single instanced draw call bends every sheet differently.\n geo.setAttribute('aBias', new THREE.InstancedBufferAttribute(bias, 1))\n return geo\n }, [JSON.stringify(config.sheet), structureKey, count])\n\n // Imperatively created — R3F won't auto-dispose a geometry passed via args.\n useEffect(() => () => geometry.dispose(), [geometry])\n\n const atlas = useContentAtlas(contents, config.sheet, stock)\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: Keyed on the stack structure — uniforms update in place, the program does not.\n const shader = useMemo(() => {\n const composed = buildDisplacementGLSL(initialStack, config.sheet)\n const uniforms: Record<string, { value: unknown }> = {}\n for (const [name, value] of Object.entries(composed.uniforms)) {\n uniforms[name] = {\n value: Array.isArray(value) && value.length === 2 ? new THREE.Vector2(...value) : value,\n }\n }\n uniforms.uPlTime = { value: 0 }\n uniforms.uAtlas = { value: null }\n uniforms.uAtlasGrid = { value: new THREE.Vector2(1, 1) }\n uniforms.uBackDarken = {\n value: 1 - Math.min(0.45, 0.12 + config.sheet.thickness * 0.9) * stock.opacity,\n }\n uniforms.uStockColor = { value: new THREE.Color(stock.color) }\n uniforms.uShowThrough = { value: config.surface.showThrough ?? stock.showThrough }\n // Transmission reads the scene's own key light, so a backlit sheet can\n // never disagree with the lamp casting its shadow.\n Object.assign(\n uniforms,\n translucencyUniforms(config.surface.translucency ?? stock.translucency, config.scene.lighting),\n )\n return {\n vertexShader: buildFieldVertexShader(composed),\n fragmentShader: buildFieldFragmentShader(),\n uniforms,\n }\n }, [\n structureKey,\n JSON.stringify(config.sheet),\n stock.id,\n config.surface.showThrough,\n config.surface.translucency,\n config.scene.lighting,\n ])\n\n useEffect(() => {\n if (!atlas) return\n shader.uniforms.uAtlas!.value = atlas.texture\n ;(shader.uniforms.uAtlasGrid!.value as THREE.Vector2).set(atlas.cols, atlas.rows)\n }, [atlas, shader])\n\n // Behavior progress loops on GSAP — the field is always alive.\n // biome-ignore lint/correctness/useExhaustiveDependencies: Keyed on the behavior itself; progress lives on a ref so the tween is not restarted each render.\n useEffect(() => {\n if (!behavior || shared.reduced) return\n const state = { p: progressRef.current }\n const tween = gsap.to(state, {\n p: 1,\n duration: behavior.duration * Math.max(0.05, 1 - state.p),\n ease: 'power2.inOut',\n yoyo: behavior.loopMode === 'yoyo',\n repeat: -1,\n onUpdate: () => {\n progressRef.current = state.p\n },\n })\n return () => {\n tween.kill()\n }\n }, [structureKey, shared.reduced])\n\n const meshRef = useRef<THREE.InstancedMesh>(null)\n\n useFrame(({ clock }) => {\n const mesh = meshRef.current\n if (!mesh) return\n const elapsed = clock.elapsedTime - Math.max(shared.mountTimeRef.current, 0)\n\n shader.uniforms.uPlTime!.value = shared.reduced ? 0 : clock.elapsedTime\n if (behavior) {\n const values = stackUniformValues(buildStackAt(progressRef.current), config.sheet)\n for (const [name, value] of Object.entries(values)) {\n const uniform = shader.uniforms[name]\n if (!uniform) continue\n if (uniform.value instanceof THREE.Vector2 && Array.isArray(value)) {\n uniform.value.set(value[0]!, value[1]!)\n } else {\n uniform.value = value\n }\n }\n }\n\n const layout = getLayout(shared.layoutId)\n const morph = shared.morphRef.current\n const behaviorTransform = behavior?.transform && config.behavior ? behavior : null\n const biasAttr = geometry.getAttribute('aBias') as THREE.InstancedBufferAttribute\n const biases = biasAttr.array as Float32Array\n let biasChanged = false\n for (let j = 0; j < count; j++) {\n const i = indices[j]!\n let pose = layout.pose(i, shared.total, shared.layoutOptions, shared.phaseRef.current, shared.sheet)\n if (morph.from && morph.t < 1) {\n const prev = getLayout(morph.from.id).pose(\n i,\n shared.total,\n morph.from.options,\n shared.phaseRef.current,\n shared.sheet,\n )\n pose = lerpPose(prev, pose, easeInOut(morph.t))\n }\n if (shared.entranceType !== 'none') {\n const tIn = Math.min(1, Math.max(0, (elapsed - i * shared.stagger) / shared.entranceDuration))\n if (tIn < 1) {\n pose = lerpPose(entrancePose(shared.entranceType, i, pose), pose, easeOut(tIn))\n }\n }\n const bias = Math.min(1, Math.max(0, pose.bias ?? 1))\n if (biases[j] !== bias) {\n biases[j] = bias\n biasChanged = true\n }\n scratchObj.position.set(...pose.position)\n scratchObj.rotation.set(...pose.rotation)\n scratchObj.scale.setScalar(pose.scale)\n // Behavior whole-sheet transforms (flight) run per instance, offset in\n // time by the same golden-ratio phase the shader flutter uses — pure\n // functions of t, so instancing stays exact.\n if (behaviorTransform) {\n const pose2 = scratchAero\n pose2.position[0] = pose2.position[1] = pose2.position[2] = 0\n pose2.rotation[0] = pose2.rotation[1] = pose2.rotation[2] = 0\n const t = shared.reduced ? 0 : clock.elapsedTime + ((i * 0.618034) % 1) * 4\n behaviorTransform.transform!(\n { ...config.behavior, [behaviorTransform.progressParam]: progressRef.current },\n t,\n pose2,\n )\n scratchObj.position.x += pose2.position[0]\n scratchObj.position.y += pose2.position[1]\n scratchObj.position.z += pose2.position[2]\n scratchObj.rotation.x += pose2.rotation[0]\n scratchObj.rotation.y += pose2.rotation[1]\n scratchObj.rotation.z += pose2.rotation[2]\n }\n scratchObj.updateMatrix()\n mesh.setMatrixAt(j, scratchObj.matrix)\n }\n mesh.instanceMatrix.needsUpdate = true\n if (biasChanged) biasAttr.needsUpdate = true\n })\n\n return (\n <instancedMesh\n ref={meshRef}\n args={[geometry, undefined, count]}\n frustumCulled={false}\n castShadow\n receiveShadow\n >\n <CustomShaderMaterial\n key={`${structureKey}:${count}`}\n baseMaterial={THREE.MeshStandardMaterial}\n vertexShader={shader.vertexShader}\n fragmentShader={shader.fragmentShader}\n uniforms={shader.uniforms}\n roughness={stock.roughness}\n metalness={0}\n side={THREE.DoubleSide}\n />\n </instancedMesh>\n )\n}\n\nfunction entrancePose(type: 'rise' | 'scatter', i: number, target: PaperPose): PaperPose {\n if (type === 'rise') {\n return {\n position: [target.position[0], target.position[1] - 3.2, target.position[2] - 0.5],\n rotation: [target.rotation[0] - 0.7, target.rotation[1], target.rotation[2] + 0.25],\n scale: target.scale * 0.85,\n bias: target.bias,\n }\n }\n const a = i * 2.399\n return {\n position: [Math.cos(a) * 7, Math.sin(a * 1.3) * 4, Math.sin(a) * 6],\n rotation: [Math.sin(a) * 2, a, Math.cos(a) * 2],\n scale: target.scale * 0.6,\n bias: target.bias,\n }\n}\n\nfunction lerpPose(a: PaperPose, b: PaperPose, t: number): PaperPose {\n const lerp = (x: number, y: number) => x + (y - x) * t\n return {\n position: [\n lerp(a.position[0], b.position[0]),\n lerp(a.position[1], b.position[1]),\n lerp(a.position[2], b.position[2]),\n ],\n rotation: [\n lerp(a.rotation[0], b.rotation[0]),\n lerp(a.rotation[1], b.rotation[1]),\n lerp(a.rotation[2], b.rotation[2]),\n ],\n scale: lerp(a.scale, b.scale),\n bias: lerp(a.bias ?? 1, b.bias ?? 1),\n }\n}\n\nconst easeOut = (t: number) => 1 - (1 - t) ** 3\nconst easeInOut = (t: number) => (t < 0.5 ? 2 * t * t : 1 - (-2 * t + 2) ** 2 / 2)\n","import * as THREE from 'three'\nimport { useEffect, useState } from 'react'\nimport type { ContentConfig, SheetConfig } from '../config/schema'\nimport type { Stock } from '../core/stock'\nimport { renderContentToCanvas } from './texture'\n\n/**\n * Field mode packs every paper's content into one grid atlas — one texture,\n * one draw call. Tiles keep the sheet's aspect; images redraw their tile as\n * they decode (LQIP-ish: stock tint first, pixels when ready).\n */\n\nconst MAX_ATLAS = 4096\n\n/**\n * Grid shape for `count` tiles of a given aspect (height / width).\n *\n * Square tiles want a square grid, but a stage banner is 5.7 times taller\n * than it is wide, and packing those into a square GRID makes an atlas five\n * times taller than it is wide — which then has to be squashed to fit the\n * texture budget, and the content with it. Choosing cols/rows ≈ aspect keeps\n * the atlas itself roughly square whatever shape the paper is.\n */\nexport function atlasGrid(count: number, aspect = 1): { cols: number; rows: number } {\n const cols = Math.max(1, Math.min(count, Math.ceil(Math.sqrt(count * Math.max(aspect, 0.01)))))\n return { cols, rows: Math.max(1, Math.ceil(count / cols)) }\n}\n\nexport interface ContentAtlas {\n texture: THREE.CanvasTexture\n cols: number\n rows: number\n}\n\nexport function useContentAtlas(\n contents: ContentConfig[],\n sheet: SheetConfig,\n stock: Stock,\n): ContentAtlas | null {\n const [atlas, setAtlas] = useState<ContentAtlas | null>(null)\n const key = JSON.stringify({ contents, w: sheet.width, h: sheet.height, stock: stock.id })\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: key serializes the contents, sheet and stock the atlas draws from.\n useEffect(() => {\n let disposed = false\n const aspect = sheet.height / sheet.width\n const { cols, rows } = atlasGrid(contents.length, aspect)\n // Fit the tile to the budget WITHOUT breaking its aspect: a tile squashed\n // to fit renders its content squashed too. Resolution is the thing that\n // gives, never shape.\n let tileW = Math.min(1024, Math.floor(MAX_ATLAS / cols))\n let tileH = Math.round(tileW * aspect)\n if (tileH * rows > MAX_ATLAS) {\n tileH = Math.floor(MAX_ATLAS / rows)\n tileW = Math.max(1, Math.round(tileH / aspect))\n }\n\n const canvas = document.createElement('canvas')\n canvas.width = tileW * cols\n canvas.height = tileH * rows\n const ctx = canvas.getContext('2d')!\n ctx.fillStyle = stock.color\n ctx.fillRect(0, 0, canvas.width, canvas.height)\n\n const texture = new THREE.CanvasTexture(canvas)\n texture.colorSpace = THREE.SRGBColorSpace\n texture.anisotropy = 4\n setAtlas({ texture, cols, rows })\n\n const drawTile = (index: number, tile: HTMLCanvasElement) => {\n if (disposed) return\n const x = (index % cols) * tileW\n const y = Math.floor(index / cols) * tileH\n ctx.drawImage(tile, x, y, tileW, tileH)\n texture.needsUpdate = true\n }\n\n contents.forEach((content, index) => {\n if (content.type === 'image') {\n const img = new Image()\n img.crossOrigin = 'anonymous'\n img.onload = () => drawTile(index, renderContentToCanvas(content, sheet, stock, img))\n img.src = content.src\n } else if (content.type === 'text' || content.type === 'receipt') {\n document.fonts.ready.then(() => drawTile(index, renderContentToCanvas(content, sheet, stock)))\n } else {\n drawTile(index, renderContentToCanvas(content, sheet, stock))\n }\n })\n\n return () => {\n disposed = true\n texture.dispose()\n }\n }, [key])\n\n return atlas\n}\n","import type { DeformerInstance, SheetDims } from '../deformers/types'\nimport { getDeformer } from '../deformers/registry'\nimport {\n TRANSLUCENCY_FRAGMENT,\n TRANSLUCENCY_VARYINGS,\n translucencyVertexChunk,\n} from '../surface/translucency'\n\n/**\n * Compose a deformer stack into GLSL — the GPU twin of deformers/compose.ts.\n * Each stack entry gets its own uniform namespace (`uRoll0_angle`,\n * `uFold1_offset`, …) so the same deformer type can appear twice\n * (letter-fold is two folds). Golden-vector parity with the JS path is\n * enforced by the GPU harness test.\n */\n\nexport interface ComposedDisplacement {\n /** Uniform declarations + displacement functions. */\n functionsSrc: string\n /** `vec3 plDisplace(vec3 p, vec2 uv, float t)` applying the whole stack. */\n displaceSrc: string\n /** Initial uniform values, keyed by their namespaced GLSL names (uSheet included). */\n uniforms: Record<string, number | number[]>\n}\n\nfunction glslType(value: number | number[]): string {\n if (typeof value === 'number') return 'float'\n return ['float', 'vec2', 'vec3', 'vec4'][value.length - 1]!\n}\n\n/**\n * Just the uniform VALUES for a stack (same namespaced keys as\n * buildDisplacementGLSL) — cheap enough to call every frame while a behavior\n * animates. Structure (names) is stable as long as the stack's type order is.\n */\nexport function stackUniformValues(\n stack: DeformerInstance[],\n sheet: SheetDims,\n): Record<string, number | number[]> {\n const uniforms: Record<string, number | number[]> = { uSheet: [sheet.width, sheet.height] }\n stack.forEach((instance, i) => {\n if (instance.enabled === false) return\n const deformer = getDeformer(instance.type)\n if (!deformer.glsl) return\n const ns = `u${cap(instance.type)}${i}_`\n const values = deformer.glsl.uniforms(instance.options) as Record<string, number | number[]>\n for (const [key, value] of Object.entries(values)) uniforms[ns + key] = value\n })\n return uniforms\n}\n\nexport function buildDisplacementGLSL(stack: DeformerInstance[], sheet: SheetDims): ComposedDisplacement {\n const decls: string[] = ['uniform vec2 uSheet;', 'float plBias = 1.0;']\n const functions: string[] = []\n const calls: string[] = []\n const uniforms: Record<string, number | number[]> = { uSheet: [sheet.width, sheet.height] }\n\n stack.forEach((instance, i) => {\n if (instance.enabled === false) return\n const deformer = getDeformer(instance.type)\n if (!deformer.glsl) {\n throw new Error(\n `[paperlab] Deformer \"${instance.type}\" has no GLSL implementation — it can't run in field mode.`,\n )\n }\n const ns = `u${cap(instance.type)}${i}_`\n const fn = `pl_${instance.type}${i}`\n const values = deformer.glsl.uniforms(instance.options) as Record<string, number | number[]>\n for (const [key, value] of Object.entries(values)) {\n decls.push(`uniform ${glslType(value)} ${ns}${key};`)\n uniforms[ns + key] = value\n }\n const strength = deformer.glsl.strength\n functions.push(\n deformer.glsl.chunk.replaceAll('FN', fn).replace(/U_(\\w+)/g, (_, name: string) =>\n // The strength uniform reads through the per-instance bias, so one\n // instanced draw call can bend every sheet by a different amount.\n name === strength ? `(${ns}${name} * plBias)` : ns + name,\n ),\n )\n calls.push(`${fn}(q, uv, t);`)\n })\n\n const displaceSrc = /* glsl */ `\nvec3 plDisplace(vec3 p, vec2 uv, float t, float bias) {\n plBias = bias;\n vec3 q = p;\n ${calls.join('\\n ')}\n return q;\n}\n`\n\n return { functionsSrc: `${decls.join('\\n')}\\n${functions.join('\\n')}`, displaceSrc, uniforms }\n}\n\n/**\n * The field-mode CSM vertex shader: displaced position + numerically\n * recomputed normal (two tangent probes — exact normals of an arbitrary\n * stack have no closed form).\n */\nexport function buildFieldVertexShader(composed: ComposedDisplacement): string {\n return /* glsl */ `\nuniform float uPlTime;\nattribute float aPhase;\nattribute float aAtlas;\nattribute float aBias;\nvarying vec2 vPaperUv;\nvarying float vAtlas;\n${TRANSLUCENCY_VARYINGS}\n${composed.functionsSrc}\n${composed.displaceSrc}\nvoid main() {\n float t = uPlTime + aPhase;\n vec3 p = plDisplace(position, uv, t, aBias);\n vec2 step = uSheet * 0.01;\n vec3 px = plDisplace(position + vec3(step.x, 0.0, 0.0), uv + vec2(0.01, 0.0), t, aBias);\n vec3 py = plDisplace(position + vec3(0.0, step.y, 0.0), uv + vec2(0.0, 0.01), t, aBias);\n vec3 n = cross(px - p, py - p);\n csm_Normal = length(n) > 1e-12 ? normalize(n) : vec3(0.0, 0.0, 1.0);\n csm_Position = p;\n${translucencyVertexChunk({ model: 'modelMatrix * instanceMatrix', position: 'p', normal: 'csm_Normal' })}\n vPaperUv = uv;\n vAtlas = aAtlas;\n}\n`\n}\n\n/**\n * Field fragment shader: per-instance tile from the shared content atlas on\n * the FRONT face; the BACK face renders the stock with an optional reversed\n * show-through ghost (per-paper back textures are a hero-mode feature).\n */\nexport function buildFieldFragmentShader(): string {\n return /* glsl */ `\nuniform sampler2D uAtlas;\nuniform vec2 uAtlasGrid;\nuniform float uBackDarken;\nuniform vec3 uStockColor;\nuniform float uShowThrough;\nvarying vec2 vPaperUv;\nvarying float vAtlas;\n${TRANSLUCENCY_FRAGMENT}\nvoid main() {\n float col = mod(vAtlas, uAtlasGrid.x);\n float row = floor(vAtlas / uAtlasGrid.x);\n vec2 tiled = (vPaperUv + vec2(col, uAtlasGrid.y - 1.0 - row)) / uAtlasGrid;\n vec4 front = texture2D(uAtlas, tiled);\n if (gl_FrontFacing) {\n csm_DiffuseColor = front;\n } else {\n csm_DiffuseColor = vec4(uStockColor * mix(vec3(1.0), front.rgb, uShowThrough), 1.0);\n csm_DiffuseColor.rgb *= uBackDarken;\n }\n // Light coming through the sheet, filtered by what is printed on it. Same\n // ink either side — the light passes through the same fibres regardless of\n // which face happens to be turned toward the camera.\n csm_Emissive = plTransmission(front.rgb);\n}\n`\n}\n\nfunction cap(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1).replace(/-(\\w)/g, (_, c: string) => c.toUpperCase())\n}\n","import { z } from 'zod'\nimport type { AnyOptions, SheetDims } from '../../deformers/types'\nimport { SHEET_LIFT, sheetLayoutSchema, sheetSlotXY, type SheetLayoutOptions } from '../sheetGrid'\nimport { getWalkPath, walkPathSchema } from '../../stage/path'\n\n/**\n * A layout is a pure `pose(i, n, options, phase)` function — no state, no\n * three.js. `phase` is the motion driver's continuous offset in turns\n * (0..1 = one full cycle); cyclic layouts use it, static ones ignore it.\n * Community layouts are ~30 lines.\n *\n * Every built-in names a place paper actually sits — a fanned swatch deck, a\n * slipped stack, a heap on a desk — because arrangement alone is what makes a\n * field read as a photo carousel instead of as paper. The other half of that\n * is `bias`: paper in the world does not all bend alike.\n */\n\nexport interface PaperPose {\n position: [number, number, number]\n rotation: [number, number, number]\n scale: number\n /**\n * How strongly this sheet takes the field's deformation: 1 = exactly as the\n * preset configures it, 0 = flat. Lets one instanced draw call curl the top\n * of a pile while the sheets pressed underneath stay flat. Omitted = 1.\n */\n bias?: number\n}\n\nexport interface Layout<O = Record<string, unknown>> {\n id: string\n label: string\n defaults: O\n optionsSchema: z.ZodType<O, z.ZodTypeDef, unknown>\n /**\n * `sheet` is the field's paper size. Layouts that arrange by CONTACT —\n * edges meeting, sheets resting on each other — cannot work without it,\n * and a layout that ignores it may simply omit the parameter.\n */\n pose(i: number, n: number, o: O, phase: number, sheet: SheetDims): PaperPose\n}\n\n/** For the odd caller that has no papers yet to measure. */\nexport const DEFAULT_SHEET: SheetDims = { width: 1, height: 1.4 }\n\nconst TAU = Math.PI * 2\nconst DEG = Math.PI / 180\n\n/** Deterministic per-index jitter — layouts must be pure. */\nfunction jitter(seed: number, i: number): number {\n let h = Math.imul((seed * 1000 + i + 1) ^ 0x9e3779b9, 2654435761)\n h = Math.imul(h ^ (h >>> 13), 3266489917)\n return (((h ^ (h >>> 16)) >>> 0) / 4294967295) * 2 - 1\n}\n\n/** 0 at the first sheet, 1 at the last — the spine of most layouts. */\nfunction ramp(i: number, n: number): number {\n return n > 1 ? i / (n - 1) : 1\n}\n\nconst ringSchema = z.object({\n radius: z.number().min(0.5).max(12).default(2.6),\n tiltDeg: z.number().min(-45).max(45).default(8),\n})\n/** Prints pegged around a circle — the one carousel worth keeping. */\nexport const ring: Layout<z.infer<typeof ringSchema>> = {\n id: 'ring',\n label: 'Ring',\n defaults: ringSchema.parse({}),\n optionsSchema: ringSchema,\n pose(i, n, o, phase) {\n const theta = (i / n + phase) * TAU\n return {\n position: [Math.sin(theta) * o.radius, 0, Math.cos(theta) * o.radius],\n // Face radially OUTWARD so the papers nearest the camera show their\n // front (content) side — you stand outside the ring, not inside it.\n rotation: [(o.tiltDeg * Math.PI) / 180, theta, 0],\n scale: 1,\n }\n },\n}\n\nconst fanSchema = z.object({\n /** Total angular sweep from the first sheet to the last, degrees. */\n sweep: z.number().min(0).max(180).default(72),\n /** Where the shared pin sits, in half-sheet-heights below center. 1 = the bottom edge. */\n hinge: z.number().min(0).max(4).default(1.15),\n /** Thickness step so the sheets stack in order instead of z-fighting. */\n lift: z.number().min(0.002).max(0.08).default(0.012),\n /** How much flatter the middle of the fan sits than its outer sheets. */\n bow: z.number().min(0).max(1).default(0.7),\n})\n/**\n * A Pantone deck, a paint-chip book, a hand of cards: every sheet pinned at\n * one shared point and swung open. The sheets nearest the outside of the\n * sweep carry the most curl, which is what sells the hinge as a hinge.\n */\nexport const fan: Layout<z.infer<typeof fanSchema>> = {\n id: 'fan',\n label: 'Fan',\n defaults: fanSchema.parse({}),\n optionsSchema: fanSchema,\n pose(i, n, o, _phase, sheet) {\n const f = n > 1 ? i / (n - 1) : 0.5\n const theta = (f - 0.5) * o.sweep * DEG\n const hinge = (o.hinge * sheet.height) / 2\n // Swing the sheet about the shared pivot, then shift so the middle sheet\n // sits at the origin — the fan stays centered as `sweep` opens and closes.\n const open = Math.abs(f - 0.5) * 2\n return {\n position: [-Math.sin(theta) * hinge, Math.cos(theta) * hinge - hinge, i * o.lift],\n rotation: [0, 0, theta],\n scale: 1,\n bias: 1 - (1 - open) * o.bow,\n }\n },\n}\n\nconst spreadSchema = z.object({\n /** How far each sheet slides past the one below it. */\n slip: z.number().min(0.02).max(2).default(0.3),\n /** Direction of the slide, degrees. 0 slides right, 90 slides up. */\n angle: z.number().min(-180).max(180).default(28),\n lift: z.number().min(0.002).max(0.08).default(0.012),\n /** How much more the sheets at the far end of the slide bow. */\n bow: z.number().min(0).max(1).default(0.6),\n /** Nothing hand-slid is perfectly square — a touch of per-sheet rotation. */\n drift: z.number().min(0).max(1).default(0.15),\n})\n/**\n * A ream pushed sideways, or a deck dealt across a table: parallel sheets at\n * a constant offset, each one bowing a little more as it comes free of the\n * stack's weight.\n */\nexport const spread: Layout<z.infer<typeof spreadSchema>> = {\n id: 'spread',\n label: 'Spread',\n defaults: spreadSchema.parse({}),\n optionsSchema: spreadSchema,\n pose(i, n, o) {\n const centered = i - (n - 1) / 2\n const a = o.angle * DEG\n return {\n position: [Math.cos(a) * o.slip * centered, Math.sin(a) * o.slip * centered, i * o.lift],\n rotation: [0, 0, jitter(11, i) * 0.2 * o.drift],\n scale: 1,\n bias: 1 - (1 - ramp(i, n)) * o.bow,\n }\n },\n}\n\nconst pileSchema = z.object({\n /** How far sheets wander from the center of the heap. */\n scatter: z.number().min(0).max(2).default(0.22),\n /** Widest angle a sheet sits off square, degrees. */\n turn: z.number().min(0).max(180).default(24),\n lift: z.number().min(0.002).max(0.08).default(0.011),\n /** How flat the sheets underneath are pressed by the ones on top. */\n press: z.number().min(0).max(1).default(0.85),\n seed: z.number().int().min(0).max(9999).default(3),\n})\n/**\n * The heap on a desk. The physical tell no parametric curve can fake: sheets\n * rest ON each other, so only the top of the pile keeps its curl and\n * everything below is pressed flat by the weight above it.\n */\nexport const pile: Layout<z.infer<typeof pileSchema>> = {\n id: 'pile',\n label: 'Pile',\n defaults: pileSchema.parse({}),\n optionsSchema: pileSchema,\n pose(i, n, o) {\n return {\n position: [jitter(o.seed, i) * o.scatter, jitter(o.seed + 1, i) * o.scatter * 0.8, i * o.lift],\n rotation: [0, 0, jitter(o.seed + 2, i) * o.turn * DEG],\n scale: 1,\n bias: 1 - (1 - ramp(i, n)) * o.press,\n }\n },\n}\n\nconst wallSchema = z.object({\n gapX: z.number().min(0.05).max(1).default(0.22),\n gapY: z.number().min(0.05).max(1).default(0.3),\n jitterAmt: z.number().min(0).max(1).default(0.25),\n /** Spread of sag across the wall — no two pinned sheets hang alike. */\n sag: z.number().min(0).max(1).default(0.45),\n})\n/** A studio wall of pinned sheets: a grid, but nothing hangs quite square. */\nexport const wall: Layout<z.infer<typeof wallSchema>> = {\n id: 'wall',\n label: 'Wall',\n defaults: wallSchema.parse({}),\n optionsSchema: wallSchema,\n pose(i, n, o, _phase, sheet) {\n const cols = Math.ceil(Math.sqrt((n * sheet.height) / sheet.width))\n const rows = Math.ceil(n / cols)\n const col = i % cols\n const row = Math.floor(i / cols)\n // Gaps are breathing room around the real paper — a wall of 1.2×0.9\n // prints and a wall of 1×1.4 letters both want even gutters.\n const cellW = sheet.width + o.gapX\n const cellH = sheet.height + o.gapY\n return {\n position: [\n (col - (cols - 1) / 2) * cellW,\n ((rows - 1) / 2 - row) * cellH,\n jitter(5, i) * 0.04 * o.jitterAmt * 4,\n ],\n rotation: [0, 0, jitter(6, i) * 0.05 * o.jitterAmt * 4],\n scale: 1,\n bias: 1 - Math.abs(jitter(7, i)) * o.sag,\n }\n },\n}\n\nconst spillSchema = z.object({\n spreadX: z.number().min(0.5).max(8).default(2.4),\n spreadY: z.number().min(0.5).max(8).default(1.5),\n depth: z.number().min(0).max(6).default(1.6),\n /** How far sheets pitch and roll out of the picture plane. */\n tumble: z.number().min(0).max(1).default(0.5),\n /** Spread of bend across the sheets — a spill does not fold them alike. */\n vary: z.number().min(0).max(1).default(0.6),\n seed: z.number().int().min(0).max(9999).default(7),\n})\n/**\n * A dropped folder's worth of paper, mid-air — what a `pile` looks like the\n * moment before it settles. Loose in all three axes, and (the part that\n * separates it from confetti) every sheet caught at its own angle AND its\n * own amount of bend.\n */\nexport const spill: Layout<z.infer<typeof spillSchema>> = {\n id: 'spill',\n label: 'Spill',\n defaults: spillSchema.parse({}),\n optionsSchema: spillSchema,\n pose(i, _n, o) {\n const tumble = o.tumble * 2\n return {\n position: [\n jitter(o.seed, i) * o.spreadX,\n jitter(o.seed + 1, i) * o.spreadY,\n jitter(o.seed + 2, i) * o.depth,\n ],\n rotation: [\n jitter(o.seed + 3, i) * 0.4 * tumble,\n jitter(o.seed + 4, i) * 0.5 * tumble,\n jitter(o.seed + 5, i) * 0.4 * tumble,\n ],\n scale: 0.85 + Math.abs(jitter(o.seed + 6, i)) * 0.3,\n bias: 1 - Math.abs(jitter(o.seed + 7, i)) * o.vary,\n }\n },\n}\n\nconst sweepSchema = z.object({\n columns: z.number().int().min(1).max(24).default(5),\n /** Breathing room around each specimen. */\n gap: z.number().min(0).max(2).default(0.22),\n /** Deformation at the first specimen and at the last. */\n from: z.number().min(0).max(1).default(0),\n to: z.number().min(0).max(1).default(1),\n})\n/**\n * A specimen chart: the same sheet mounted in a grid, its deformation ramped\n * across the series so one image shows a curl at ten stages instead of one.\n * The layout the rest of this library exists to make possible — and the one\n * that documents every deformer for free.\n *\n * Only as legible as the preset it charts: a sheet with no behavior or\n * deformers has nothing for the ramp to scale, and every specimen comes out\n * identical.\n */\nexport const sweep: Layout<z.infer<typeof sweepSchema>> = {\n id: 'sweep',\n label: 'Sweep',\n defaults: sweepSchema.parse({}),\n optionsSchema: sweepSchema,\n pose(i, n, o, _phase, sheet) {\n const cols = Math.min(o.columns, Math.max(n, 1))\n const rows = Math.ceil(n / cols)\n const col = i % cols\n const row = Math.floor(i / cols)\n return {\n position: [\n (col - (cols - 1) / 2) * (sheet.width + o.gap),\n ((rows - 1) / 2 - row) * (sheet.height + o.gap),\n 0,\n ],\n rotation: [0, 0, 0],\n scale: 1,\n bias: o.from + (o.to - o.from) * ramp(i, n),\n }\n },\n}\n\nconst bookSchema = z.object({\n /** How far the outermost page lifts off the block, degrees. */\n spread: z.number().min(0).max(150).default(55),\n /** Fraction of the pages bound to the left. 0 = a one-sided sample book. */\n split: z.number().min(0).max(1).default(0.5),\n /** Page thickness — the gap between pages of one block. */\n lift: z.number().min(0.001).max(0.05).default(0.008),\n /** How much more a lifted page arcs than one lying flat in the block. */\n gutter: z.number().min(0).max(1).default(0.6),\n})\n/**\n * An open codex: pages hinged on a shared spine, each block splaying away\n * from the gutter. `split` slides it between the two bound forms paper takes\n * — 0.5 is a book lying open, 0 is a swatch deck or sample book bound down\n * one side. Pages lying flat in the block are pressed by the ones above;\n * only the lifted pages keep their arc.\n */\nexport const book: Layout<z.infer<typeof bookSchema>> = {\n id: 'book',\n label: 'Book',\n defaults: bookSchema.parse({}),\n optionsSchema: bookSchema,\n pose(i, n, o, _phase, sheet) {\n const half = sheet.width / 2\n const left = Math.round(n * o.split)\n const onLeft = i < left\n const count = onLeft ? left : n - left\n const k = onLeft ? i : i - left\n const f = count > 1 ? k / (count - 1) : 1\n const theta = f * o.spread * DEG\n // Swing the page about the spine at x = 0; `side` mirrors the left block.\n const side = onLeft ? -1 : 1\n const cos = Math.cos(theta)\n const sin = Math.sin(theta)\n // Stack along the page's own normal so pages standing near-vertical\n // separate sideways rather than sinking into each other.\n const offset = k * o.lift\n return {\n position: [side * (half * cos - offset * sin), 0, half * sin + offset * cos],\n rotation: [0, -side * theta, 0],\n scale: 1,\n bias: 1 - (1 - f) * o.gutter,\n }\n },\n}\n\nconst accordionSchema = z.object({\n /** How far each panel tilts off the strip's line, degrees. 0 = flat, 90 = shut. */\n angle: z.number().min(0).max(89).default(55),\n /** A concertina holds its creases — how much bow the panels keep. */\n slack: z.number().min(0).max(1).default(0.15),\n})\n/**\n * A concertina: panels alternating about creases they genuinely share, so\n * the sheets read as ONE folded strip rather than as N separate papers —\n * the only layout here where that is true. Adjacent edges are solved to\n * meet, which is why it needs the sheet's real width.\n */\nexport const accordion: Layout<z.infer<typeof accordionSchema>> = {\n id: 'accordion',\n label: 'Accordion',\n defaults: accordionSchema.parse({}),\n optionsSchema: accordionSchema,\n pose(i, n, o, _phase, sheet) {\n const theta = o.angle * DEG\n const side = i % 2 === 0 ? 1 : -1\n // Solving edge-meets-edge for alternating ±angle puts every panel center\n // on one line, spaced by the panel's foreshortened width.\n const step = sheet.width * Math.cos(theta)\n return {\n position: [(i - (n - 1) / 2) * step, 0, 0],\n rotation: [0, side * theta, 0],\n scale: 1,\n bias: o.slack,\n }\n },\n}\n\nconst rackSchema = z.object({\n /** Gap along the row, as a fraction of the paper's width. Under 1 they overlap. */\n spacing: z.number().min(0.05).max(2).default(0.82),\n /** How far a sheet leans back off vertical, degrees. */\n lean: z.number().min(0).max(70).default(16),\n /** How much that lean differs sheet to sheet — nothing propped is uniform. */\n vary: z.number().min(0).max(1).default(0.55),\n /** Small rotations off square. */\n sway: z.number().min(0).max(1).default(0.35),\n seed: z.number().int().min(0).max(9999).default(5),\n})\n/**\n * Prints stood in a row and leaning back — against a wall, in a rack, propped\n * along a shelf. The one arrangement here that RESTS on a surface rather than\n * floating: every sheet pivots on the bottom edge it actually stands on, so\n * the row shares a floor. The further a sheet has leaned, the more it bows\n * under its own weight.\n *\n * (Stacking these front-to-back the way a letter tray really holds paper is\n * physically honest and visually useless — the front sheet hides the rest.\n * A row is the arrangement you can actually see.)\n */\nexport const rack: Layout<z.infer<typeof rackSchema>> = {\n id: 'rack',\n label: 'Rack',\n defaults: rackSchema.parse({}),\n optionsSchema: rackSchema,\n pose(i, n, o, _phase, sheet) {\n const lean = o.lean * DEG * (1 + jitter(o.seed, i) * o.vary)\n const half = sheet.height / 2\n return {\n position: [\n (i - (n - 1) / 2) * sheet.width * o.spacing,\n // Standing on the floor: the bottom edge stays at y = 0 as it leans.\n half * Math.cos(lean),\n -half * Math.sin(lean) + i * 0.004,\n ],\n rotation: [-lean, jitter(o.seed + 1, i) * 0.12 * o.sway, jitter(o.seed + 2, i) * 0.06 * o.sway],\n scale: 1,\n // A sheet leaning further has more of its own weight to carry.\n bias: o.lean === 0 ? 0 : Math.min(1, lean / (o.lean * DEG * (1 + o.vary))),\n }\n },\n}\n\nconst colonnadeSchema = z.object({\n /** The walk the colonnade is built along — see `stage/path`. */\n path: walkPathSchema.default({}),\n /** Half-width of the clear aisle: how far each banner stands off the walk line. */\n aisle: z.number().min(0.2).max(20).default(2.4),\n /** How much that gap opens and closes along the walk. Nothing hung by hand is a corridor. */\n breathe: z.number().min(0).max(1).default(0.3),\n /** Widest angle a banner turns off square to the aisle, degrees. */\n twist: z.number().min(0).max(90).default(22),\n /** Fraction of the walk left clear at each end, so the figure has somewhere to enter from. */\n margin: z.number().min(0).max(0.45).default(0.05),\n /** Spread of banner heights, 0..1. */\n rise: z.number().min(0).max(1).default(0.28),\n /** How far the banners lift off the floor, as a fraction of their height. 0 = they pool on it. */\n hover: z.number().min(0).max(1).default(0),\n /** Spread of deformation — no two lengths of hung paper drape alike. */\n drape: z.number().min(0).max(1).default(0.5),\n seed: z.number().int().min(0).max(9999).default(2),\n})\n/**\n * A nave of hanging banners flanking a walk: paper as ARCHITECTURE rather\n * than as an object on a desk. The first layout here that arranges along a\n * path instead of around an origin, which is what lets a figure walk through\n * it — the aisle is guaranteed clear because the banners are placed off the\n * walk line, not merely near it.\n *\n * Banners alternate ranks (left, right, left…) and the two ranks are\n * staggered by a quarter step, so you pass them one at a time rather than\n * through a ladder of matched pairs. Each faces across the aisle: a banner\n * ahead of you presents its face, which is the whole reason to print\n * anything on it.\n */\nexport const colonnade: Layout<z.infer<typeof colonnadeSchema>> = {\n id: 'colonnade',\n label: 'Colonnade',\n defaults: colonnadeSchema.parse({}),\n optionsSchema: colonnadeSchema,\n pose(i, n, o, phase, sheet) {\n const path = getWalkPath(o.path)\n const side = i % 2 === 0 ? 1 : -1\n const pairs = Math.max(Math.ceil(n / 2), 1)\n const k = Math.floor(i / 2)\n const span = 1 - o.margin * 2\n const step = pairs > 1 ? span / (pairs - 1) : 0\n const base = o.margin + (pairs > 1 ? k * step : span / 2) + side * step * 0.25\n // Only a closed walk can slide: on an open one, offsetting by phase would\n // teleport the far banner back to the near end mid-shot.\n const s = path.closed ? base + phase : base\n const [px, pz] = path.pointAt(s)\n const [nx, nz] = path.normalAt(s)\n const scale = 1 + jitter(o.seed, i) * o.rise * 0.5\n const offset = o.aisle * (1 + jitter(o.seed + 1, i) * o.breathe)\n const height = sheet.height * scale\n // Face the centerline: the inward direction is the aisle normal, negated\n // on whichever rank this banner stands in.\n const yaw = Math.atan2(-side * nx, -side * nz) + jitter(o.seed + 2, i) * o.twist * DEG\n return {\n position: [px + nx * side * offset, height / 2 + height * o.hover, pz + nz * side * offset],\n rotation: [0, yaw, 0],\n scale,\n bias: 1 - Math.abs(jitter(o.seed + 3, i)) * o.drape,\n }\n },\n}\n\n/**\n * A block of stamps: flat rows × columns grid in register, floating a hair\n * above the (field-rendered) backing sheet. Standard layout contract — it\n * also works standalone as a plain grid; `backing`/`backingMargin` are read\n * by the field renderer, not by `pose`.\n */\nexport const sheet: Layout<SheetLayoutOptions> = {\n id: 'sheet',\n label: 'Sheet',\n defaults: sheetLayoutSchema.parse({}),\n optionsSchema: sheetLayoutSchema,\n pose(i, _n, o) {\n const { x, y } = sheetSlotXY(i, o)\n return { position: [x, y, SHEET_LIFT], rotation: [0, 0, 0], scale: 1 }\n },\n}\n\nconst registry = new Map<string, Layout<AnyOptions>>()\n\nexport function registerLayout(layout: Layout<AnyOptions>): void {\n registry.set(layout.id, layout)\n}\n\nexport function getLayout(id: string): Layout<AnyOptions> {\n const layout = registry.get(id)\n if (!layout) {\n throw new Error(`[paperlab] Unknown layout \"${id}\". Registered: ${[...registry.keys()].join(', ')}`)\n }\n return layout\n}\n\nexport function listLayouts(): string[] {\n return [...registry.keys()]\n}\n\nregisterLayout(ring)\nregisterLayout(fan)\nregisterLayout(spread)\nregisterLayout(pile)\nregisterLayout(wall)\nregisterLayout(spill)\nregisterLayout(sweep)\nregisterLayout(book)\nregisterLayout(accordion)\nregisterLayout(rack)\nregisterLayout(colonnade)\nregisterLayout(sheet)\n","import { z } from 'zod'\n\n/**\n * The walk — a path across the ground plane that a figure follows and that\n * layouts arrange paper along. Pure 2D math (x, z on the floor, y is always\n * up), no three.js, so it tests in node and is cheap enough to call from\n * inside a layout's pure `pose`.\n *\n * Centripetal Catmull-Rom through the control points — it will not cusp or\n * overshoot when two points bunch together, which a uniform spline does —\n * resampled to a uniform arc-length polyline. That resampling is the point:\n * `pointAt(s)` advances at constant SPEED, so a figure stepping `s` forward\n * at a steady rate covers ground at a steady rate. A raw spline parameter\n * would have it sprint through the straights and crawl around the corners.\n */\n\n/** A point on the floor. */\nexport type Ground = [x: number, z: number]\n\nexport const walkPathSchema = z.object({\n /**\n * Control points on the ground plane, [x, z]. The default walks away from\n * the camera down -Z — the shot every reference image is composed on.\n */\n points: z\n .array(z.tuple([z.number(), z.number()]))\n .min(2)\n .default([\n [0, 9],\n [0, -9],\n ]),\n /** Join the last point back to the first: an endless walk, and the only form `phase` can slide. */\n closed: z.boolean().default(false),\n})\n\nexport type WalkPathOptions = z.infer<typeof walkPathSchema>\n\nexport interface WalkPath {\n /** Total arc length in world units. */\n readonly length: number\n readonly closed: boolean\n /** `s` is normalized arc length: 0 = the start, 1 = the end. Closed paths wrap, open paths clamp. */\n pointAt(s: number): Ground\n /** Unit forward direction at `s`. */\n tangentAt(s: number): Ground\n /** Unit LEFT-hand normal at `s` — the side of the aisle a walker's left hand points to. */\n normalAt(s: number): Ground\n}\n\n/** Polyline resolution. 24 per segment holds a tight curve to well under a millimetre of chord error. */\nconst SAMPLES_PER_SEGMENT = 24\n\n/** Coincident control points would collapse the knot spacing and divide by zero. */\nconst EPSILON = 1e-6\n\n/** Centripetal: alpha = 0.5. (0 would be uniform, 1 chordal.) */\nconst ALPHA = 0.5\n\nfunction knot(a: Ground, b: Ground, t: number): number {\n return t + Math.max(Math.hypot(b[0] - a[0], b[1] - a[1]), EPSILON) ** ALPHA\n}\n\n/** Linear interpolation in knot space — the Barry-Goldman building block. */\nfunction lerpKnot(a: Ground, b: Ground, ta: number, tb: number, t: number): Ground {\n const span = tb - ta\n const k = span === 0 ? 0 : (t - ta) / span\n return [a[0] + (b[0] - a[0]) * k, a[1] + (b[1] - a[1]) * k]\n}\n\n/** One centripetal Catmull-Rom segment p1→p2, `u` in 0..1. */\nfunction segmentPoint(p0: Ground, p1: Ground, p2: Ground, p3: Ground, u: number): Ground {\n const t0 = 0\n const t1 = knot(p0, p1, t0)\n const t2 = knot(p1, p2, t1)\n const t3 = knot(p2, p3, t2)\n const t = t1 + (t2 - t1) * u\n const a1 = lerpKnot(p0, p1, t0, t1, t)\n const a2 = lerpKnot(p1, p2, t1, t2, t)\n const a3 = lerpKnot(p2, p3, t2, t3, t)\n const b1 = lerpKnot(a1, a2, t0, t2, t)\n const b2 = lerpKnot(a2, a3, t1, t3, t)\n return lerpKnot(b1, b2, t1, t2, t)\n}\n\n/** The phantom control point beyond an open path's end: reflect the interior neighbor. */\nfunction reflect(end: Ground, inner: Ground): Ground {\n return [2 * end[0] - inner[0], 2 * end[1] - inner[1]]\n}\n\nexport function createWalkPath(options: WalkPathOptions): WalkPath {\n const pts = options.points as Ground[]\n const n = pts.length\n const closed = options.closed && n > 2\n const segments = closed ? n : n - 1\n\n // Resample the spline into a uniformly-indexed polyline, carrying the\n // cumulative arc length so `s` can be inverted by search.\n const samples: Ground[] = []\n const cumulative: number[] = []\n let total = 0\n for (let seg = 0; seg < segments; seg++) {\n const p1 = pts[seg]!\n const p2 = pts[(seg + 1) % n]!\n const p0 = closed ? pts[(seg - 1 + n) % n]! : seg > 0 ? pts[seg - 1]! : reflect(pts[0]!, pts[1]!)\n const p3 = closed ? pts[(seg + 2) % n]! : seg + 2 < n ? pts[seg + 2]! : reflect(pts[n - 1]!, pts[n - 2]!)\n // The last sample of a segment is the first of the next — emit it only\n // at the very end of an open path, where nothing follows to repeat it.\n const last = seg === segments - 1 && !closed ? SAMPLES_PER_SEGMENT : SAMPLES_PER_SEGMENT - 1\n for (let k = 0; k <= last; k++) {\n const point = segmentPoint(p0, p1, p2, p3, k / SAMPLES_PER_SEGMENT)\n const previous = samples[samples.length - 1]\n if (previous) total += Math.hypot(point[0] - previous[0], point[1] - previous[1])\n samples.push(point)\n cumulative.push(total)\n }\n }\n if (closed) {\n // Close the ring: the start point repeats as the final sample so a\n // search near s = 1 has a segment to land in.\n const first = samples[0]!\n const previous = samples[samples.length - 1]!\n total += Math.hypot(first[0] - previous[0], first[1] - previous[1])\n samples.push([first[0], first[1]])\n cumulative.push(total)\n }\n\n const length = total\n\n function normalize(s: number): number {\n if (!Number.isFinite(s)) return 0\n if (!closed) return Math.min(Math.max(s, 0), 1)\n const wrapped = s - Math.floor(s)\n return wrapped\n }\n\n function pointAt(s: number): Ground {\n const target = normalize(s) * length\n if (length === 0) return [samples[0]![0], samples[0]![1]]\n // Binary search for the first sample at or past the target distance.\n let low = 0\n let high = cumulative.length - 1\n while (low < high) {\n const mid = (low + high) >> 1\n if (cumulative[mid]! < target) low = mid + 1\n else high = mid\n }\n const i = Math.max(low, 1)\n const before = cumulative[i - 1]!\n const span = cumulative[i]! - before\n const k = span <= 0 ? 0 : (target - before) / span\n const a = samples[i - 1]!\n const b = samples[i]!\n return [a[0] + (b[0] - a[0]) * k, a[1] + (b[1] - a[1]) * k]\n }\n\n /** Central difference over a fixed world-space step — stable at any path length. */\n function tangentAt(s: number): Ground {\n const ds = length > 0 ? Math.min(0.01, 0.5 / length) : 0.01\n const here = normalize(s)\n const a = pointAt(closed ? here - ds : Math.max(here - ds, 0))\n const b = pointAt(closed ? here + ds : Math.min(here + ds, 1))\n const dx = b[0] - a[0]\n const dz = b[1] - a[1]\n const len = Math.hypot(dx, dz)\n // A degenerate path has no direction to report; -Z is the house forward.\n return len < EPSILON ? [0, -1] : [dx / len, dz / len]\n }\n\n function normalAt(s: number): Ground {\n const [tx, tz] = tangentAt(s)\n // Left of forward, with +Y up: right = forward × up, so left is its negation.\n return [tz, -tx]\n }\n\n return { length, closed, pointAt, tangentAt, normalAt }\n}\n\n/**\n * Building the arc-length table costs a few hundred flops, and `pose` runs\n * per sheet per frame — so paths are memoized by value. Same options in,\n * same object out, which keeps layouts pure from the outside.\n */\nconst cache = new Map<string, WalkPath>()\nconst CACHE_LIMIT = 32\n\nexport function getWalkPath(options: WalkPathOptions): WalkPath {\n const key = `${options.closed ? 'c' : 'o'}|${options.points.map((p) => `${p[0]},${p[1]}`).join(';')}`\n const hit = cache.get(key)\n if (hit) return hit\n const path = createWalkPath(options)\n if (cache.size >= CACHE_LIMIT) {\n const oldest = cache.keys().next().value\n if (oldest !== undefined) cache.delete(oldest)\n }\n cache.set(key, path)\n return path\n}\n","import { getBehavior } from '../behaviors/registry'\nimport { resolveDeformerStack } from '../deformers/registry'\nimport type { PaperConfig } from '../config/schema'\nimport type { DeformerInstance } from '../deformers/types'\n\n/**\n * The deformer stack one field group renders, at a given behavior progress.\n *\n * A raw `deformers` array is the Advanced fork of a behavior and wins over\n * one — the same precedence the hero path's `buildStack` applies. Field mode\n * once read `behavior` only, so a preset shaped by `deformers` (the way to\n * say \"this print has a permanent bow\") silently rendered flat.\n */\nexport function fieldShapeStack(config: PaperConfig, progress: number): DeformerInstance[] {\n if (config.deformers) return resolveDeformerStack(config.deformers)\n if (!config.behavior) return []\n const behavior = getBehavior(config.behavior.type)\n const options = { ...config.behavior, [behavior.progressParam]: progress }\n return behavior.stack(options, config.sheet)\n}\n","import * as THREE from 'three'\nimport { useEffect, useMemo } from 'react'\nimport { drawBacking } from '../content/backing'\nimport { sheetBackingSize, type SheetLayoutOptions } from './sheetGrid'\n\n/** Warmer than printer stock — the classic gummed backing paper. */\nconst BACKING_TINT = '#f3ecdd'\n\n/**\n * The shared sheet behind a stamp grid: one extra paper sized to the grid\n * bounds + margin, non-interactive, excluded from `papers` indices. Its\n * content is a generated canvas of ghost silhouettes, redrawn on state\n * change (never per-frame).\n */\nexport function BackingSheet({\n options,\n count,\n removed,\n}: {\n options: SheetLayoutOptions\n count: number\n removed: ReadonlySet<number>\n}) {\n const { width, height } = sheetBackingSize(options)\n const canvas = useMemo(() => {\n if (typeof document === 'undefined') return null\n const c = document.createElement('canvas')\n const scale = Math.min(1024, Math.round(360 * Math.max(width, height))) / Math.max(width, height)\n c.width = Math.max(2, Math.round(width * scale))\n c.height = Math.max(2, Math.round(height * scale))\n return c\n }, [width, height])\n const texture = useMemo(() => (canvas ? new THREE.CanvasTexture(canvas) : null), [canvas])\n\n const removedKey = [...removed].sort((a, b) => a - b).join(',')\n // biome-ignore lint/correctness/useExhaustiveDependencies: Serialized deps — options and the removed set are fresh objects every render.\n useEffect(() => {\n if (!canvas || !texture) return\n drawBacking(canvas, { options, count, tint: BACKING_TINT, removed })\n texture.needsUpdate = true\n }, [canvas, texture, JSON.stringify(options), count, removedKey])\n useEffect(() => () => texture?.dispose(), [texture])\n\n return (\n <mesh receiveShadow>\n <planeGeometry args={[width, height]} />\n <meshStandardMaterial map={texture} color=\"#ffffff\" roughness={0.92} metalness={0} />\n </mesh>\n )\n}\n","import { sheetBackingSize, sheetSlotXY, type SheetLayoutOptions } from '../field/sheetGrid'\n\n/**\n * The backing sheet's generated content: per-slot ghost silhouettes a few\n * percent lighter than the backing tint. When a slot's paper detaches\n * (picked/placed), its silhouette lightens further and gains a faint\n * adhesive-sheen gradient — the visual proof of removal. Redrawn on state\n * change, never per-frame.\n */\n\nexport interface SilhouetteRect {\n /** Canvas-UV rect (0..1, y down) of slot i on the backing sheet. */\n x: number\n y: number\n w: number\n h: number\n}\n\n/** Pure: where each slot's silhouette sits on the backing, in canvas UV. */\nexport function silhouetteRects(o: SheetLayoutOptions, count: number): SilhouetteRect[] {\n const { width, height } = sheetBackingSize(o)\n const rects: SilhouetteRect[] = []\n for (let i = 0; i < count; i++) {\n const { x, y } = sheetSlotXY(i, o)\n rects.push({\n x: (x - o.cellWidth / 2 + width / 2) / width,\n // World y up → canvas y down.\n y: (height / 2 - y - o.cellHeight / 2) / height,\n w: o.cellWidth / width,\n h: o.cellHeight / height,\n })\n }\n return rects\n}\n\n/** Lighten a hex tint toward white by `amount` (0..1). */\nexport function lightenHex(hex: string, amount: number): string {\n const n = parseInt(hex.replace('#', ''), 16)\n const ch = (shift: number) => {\n const c = (n >> shift) & 0xff\n return Math.min(255, Math.round(c + (255 - c) * amount))\n }\n return `#${((ch(16) << 16) | (ch(8) << 8) | ch(0)).toString(16).padStart(6, '0')}`\n}\n\nexport interface BackingDrawSpec {\n options: SheetLayoutOptions\n count: number\n tint: string\n /** Slot indices whose paper has been picked/placed away. */\n removed: ReadonlySet<number>\n}\n\n/** Draw the backing content onto a canvas (called on state change only). */\nexport function drawBacking(canvas: HTMLCanvasElement, spec: BackingDrawSpec): void {\n const ctx = canvas.getContext('2d')\n if (!ctx) return\n const { width: cw, height: chh } = canvas\n ctx.fillStyle = spec.tint\n ctx.fillRect(0, 0, cw, chh)\n\n const rects = silhouetteRects(spec.options, spec.count)\n rects.forEach((r, i) => {\n const removed = spec.removed.has(i)\n const x = r.x * cw\n const y = r.y * chh\n const w = r.w * cw\n const h = r.h * chh\n const radius = Math.min(w, h) * 0.06\n\n ctx.fillStyle = lightenHex(spec.tint, removed ? 0.5 : 0.07)\n roundedRect(ctx, x, y, w, h, radius)\n ctx.fill()\n\n if (removed) {\n // Faint adhesive sheen: a diagonal highlight across the bare silhouette.\n const sheen = ctx.createLinearGradient(x, y, x + w, y + h)\n sheen.addColorStop(0, 'rgba(255,255,255,0)')\n sheen.addColorStop(0.5, 'rgba(255,255,255,0.35)')\n sheen.addColorStop(1, 'rgba(255,255,255,0)')\n ctx.fillStyle = sheen\n roundedRect(ctx, x, y, w, h, radius)\n ctx.fill()\n }\n })\n}\n\nfunction roundedRect(\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n w: number,\n h: number,\n r: number,\n): void {\n ctx.beginPath()\n ctx.moveTo(x + r, y)\n ctx.arcTo(x + w, y, x + w, y + h, r)\n ctx.arcTo(x + w, y + h, x, y + h, r)\n ctx.arcTo(x, y + h, x, y, r)\n ctx.arcTo(x, y, x + w, y, r)\n ctx.closePath()\n}\n","import * as THREE from 'three'\nimport { gsap } from 'gsap'\nimport { useFrame, useThree, type ThreeEvent } from '@react-three/fiber'\nimport { useContext, useEffect, useMemo, useRef, useState } from 'react'\nimport { paperConfigSchema, type PaperConfigInput } from '../config/schema'\nimport { mergeConfig } from '../config/merge'\nimport { PaperMesh, type PaperHandle } from '../PaperMesh'\nimport { carryDrive, dampTo, type DampedValue } from '../physics/aero'\nimport { usePrefersReducedMotion } from '../a11y'\nimport type { SheetDims } from '../deformers/types'\nimport { getLayout, type PaperPose } from './layouts'\nimport { tornEdgesOnDetach, type SheetLayoutOptions } from './sheetGrid'\nimport {\n DropZoneContext,\n DropZoneRegistry,\n DropZoneVisual,\n zoneAccepts,\n zoneContains,\n type DropZoneConfig,\n type PlacedPaper,\n type ZoneEntry,\n} from './dropZones'\nimport { BackingSheet } from './backingSheet'\nimport { EMPTY_SET, resolveFieldSlotConfig, type FieldPaperSlot } from './slots'\n\n/** Imperative field controls for the hidden a11y keyboard flow. */\nexport interface FieldA11yController {\n pick(slot: number): boolean\n placeAtZone(slot: number, zoneId: string): void\n cancel(slot: number): void\n zoneIds(): string[]\n slotState(slot: number): string\n}\n\nexport interface InteractiveFieldProps {\n papers: FieldPaperSlot[]\n fallback?: string | PaperConfigInput\n layoutId: string\n layoutOptions: Record<string, unknown>\n sheetOptions: SheetLayoutOptions | null\n /** The field's paper size, for layouts that arrange by contact. */\n sheet: SheetDims\n reducedMotion?: boolean\n /** Serialized zones (the editor's) — merged with `<DropZone>` children. */\n zones?: DropZoneConfig[]\n onSlotStateChange?(slot: number, state: string): void\n onPlace?(paper: PlacedPaper, zone: string): void\n a11yRef?: React.MutableRefObject<FieldA11yController | null>\n}\n\n/** Behaviors with a grab point — the only ones a drag can pick (spec §1.1). */\nconst PICK_BEHAVIORS = new Set(['peel', 'carry'])\n\ninterface CarriedPaper {\n slot: number\n pointerId: number | null\n x: DampedValue\n y: DampedValue\n targetX: number\n targetY: number\n lastX: number\n lastY: number\n homePose: PaperPose\n settling: boolean\n}\n\ninterface PressState {\n slot: number\n pointerId: number\n startX: number\n startY: number\n}\n\n/**\n * The interactive field: one hero-path PaperMesh per slot posed by the\n * layout, plus the carry controller — press past `pickThreshold` tears the\n * paper off (perforation auto-wires torn), it flies with the cursor\n * fluttering from drag velocity, zones test its center each frame, release\n * settles (snap → press → flatten) or flutters back to its slot.\n */\nexport function InteractiveField(props: InteractiveFieldProps) {\n const { papers, fallback, layoutId, layoutOptions, sheetOptions } = props\n const total = papers.length\n const layout = getLayout(layoutId)\n const reduced = usePrefersReducedMotion(props.reducedMotion)\n const contextRegistry = useContext(DropZoneContext)\n // Editor-serialized zones need hover state even without a provider.\n const registry = useMemo(() => contextRegistry ?? new DropZoneRegistry(), [contextRegistry])\n const camera = useThree((s) => s.camera)\n const gl = useThree((s) => s.gl)\n const controls = useThree((s) => s.controls) as { enabled?: boolean } | null\n\n // Once a stamp leaves its slot the silhouette stays bare — paper has\n // memory: a returned stamp sits ON its silhouette, detached.\n const [removed, setRemoved] = useState<ReadonlySet<number>>(EMPTY_SET)\n // Runtime config patches (torn perforation, carry override) — merged over\n // the slot config; the machine `rebase`s instead of resetting.\n const [slotPatches, setSlotPatches] = useState<Record<number, Record<string, unknown>>>({})\n const [slotStates, setSlotStates] = useState<Record<number, string>>({})\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: Serialized deps — slots and layout options are fresh objects every render.\n const slotConfigs = useMemo(\n () =>\n papers.map((slot, i) => {\n const config = resolveFieldSlotConfig(slot, fallback, i, layoutId, layoutOptions)\n const patch = slotPatches[i]\n return patch ? paperConfigSchema.parse(mergeConfig(config as Record<string, unknown>, patch)) : config\n }),\n [\n JSON.stringify(papers),\n JSON.stringify(fallback ?? null),\n layoutId,\n JSON.stringify(layoutOptions),\n slotPatches,\n ],\n )\n // biome-ignore lint/correctness/useExhaustiveDependencies: Serialized deps — poses depend on the layout, not on config identity.\n const poses = useMemo(\n () => slotConfigs.map((_, i) => layout.pose(i, total, layoutOptions, 0, props.sheet)),\n [layoutId, JSON.stringify(layoutOptions), total, props.sheet.width, props.sheet.height],\n )\n\n const groupRefs = useRef<(THREE.Group | null)[]>([])\n const handleRefs = useRef<(PaperHandle | null)[]>([])\n const pressRef = useRef<PressState | null>(null)\n const carriedRef = useRef<CarriedPaper | null>(null)\n\n // Registry zones can register after mount; read live in the frame loop.\n const zonesLive = (): ZoneEntry[] => [...(props.zones ?? []), ...registry.list()]\n\n const slotName = (i: number): string => {\n const preset = papers[i]?.preset ?? fallback\n return typeof preset === 'string' ? preset : (slotConfigs[i]?.meta.name ?? 'paper')\n }\n\n const onSlotState = (i: number, state: string) => {\n setSlotStates((prev) => ({ ...prev, [i]: state }))\n if (state === 'picked' || state === 'placed') {\n setRemoved((prev) => (prev.has(i) ? prev : new Set(prev).add(i)))\n }\n props.onSlotStateChange?.(i, state)\n }\n\n // ── Pointer → field-plane projection ──\n const raycaster = useMemo(() => new THREE.Raycaster(), [])\n const planeScratch = useMemo(() => new THREE.Plane(new THREE.Vector3(0, 0, 1), 0), [])\n const pointScratch = useMemo(() => new THREE.Vector3(), [])\n const ndcScratch = useMemo(() => new THREE.Vector2(), [])\n const planePoint = (clientX: number, clientY: number, planeZ: number): [number, number] | null => {\n const rect = gl.domElement.getBoundingClientRect()\n ndcScratch.set(\n ((clientX - rect.left) / rect.width) * 2 - 1,\n -((clientY - rect.top) / rect.height) * 2 + 1,\n )\n raycaster.setFromCamera(ndcScratch, camera)\n planeScratch.constant = -planeZ\n const hit = raycaster.ray.intersectPlane(planeScratch, pointScratch)\n return hit ? [hit.x, hit.y] : null\n }\n\n // ── Pick: the tear ──\n const pick = (slot: number, atX: number, atY: number, pointerId: number | null = null): boolean => {\n const config = slotConfigs[slot]\n const handle = handleRefs.current[slot]\n const home = poses[slot]\n if (!config?.states || !handle || !home) return false\n if (!config.behavior || !PICK_BEHAVIORS.has(config.behavior.type)) return false\n if (slotStates[slot] === 'placed' || carriedRef.current) return false\n\n // Auto-wire the sticker model: perforation edges that faced neighbors\n // tear through (manual state wins), and `picked` defaults to a carry\n // hanging from the peeled corner unless the preset choreographs its own.\n const patch: Record<string, unknown> = {}\n if (sheetOptions && config.surface.perforation) {\n const auto = tornEdgesOnDetach(slot, sheetOptions)\n patch.surface = {\n perforation: { state: { ...auto, ...config.surface.perforation.state } },\n }\n }\n const pickedOverrides = config.states.states.picked?.overrides as { behavior?: unknown } | undefined\n if (!pickedOverrides?.behavior) {\n const grab =\n config.behavior.type === 'peel' && config.behavior.corner !== 'auto'\n ? config.behavior.corner\n : 'top-left'\n patch.states = {\n states: {\n picked: { overrides: { behavior: { type: 'carry', grab, drive: 0.3 } } },\n },\n }\n }\n if (Object.keys(patch).length > 0) {\n setSlotPatches((prev) => ({ ...prev, [slot]: mergeConfig(prev[slot] ?? {}, patch) }))\n }\n\n // Drive the machine through rest→hover→pressed→picked so every side effect\n // fires for BOTH pointer (already at 'pressed') and keyboard (still at\n // 'rest') entry — raw send('pick') from 'rest' was a silent no-op.\n handle.pickProgrammatic()\n carriedRef.current = {\n slot,\n pointerId,\n x: { value: atX, velocity: 0 },\n y: { value: atY, velocity: 0 },\n targetX: atX,\n targetY: atY,\n lastX: atX,\n lastY: atY,\n homePose: home,\n settling: false,\n }\n if (controls) controls.enabled = false\n return true\n }\n\n // ── The settle: the 400ms that sells everything (spec §5.3) ──\n const settleInto = (carried: CarriedPaper, zone: ZoneEntry) => {\n const group = groupRefs.current[carried.slot]\n const handle = handleRefs.current[carried.slot]\n if (!group || !handle) return\n carried.settling = true\n handle.placeProgrammatic()\n handle.set('drive', 0)\n registry.setHovered(null)\n\n const paper: PlacedPaper = {\n slot: carried.slot,\n presetName: slotName(carried.slot),\n config: slotConfigs[carried.slot]!,\n }\n const zoneZ = zone.bounds.position[2]\n const done = () => {\n carriedRef.current = null\n if (controls) controls.enabled = true\n zone.onPlace?.(paper, zone.id)\n props.onPlace?.(paper, zone.id)\n }\n if (reduced) {\n group.position.set(group.position.x, group.position.y, zoneZ + 0.005)\n group.rotation.set(0, 0, 0)\n group.scale.setScalar(1)\n done()\n return\n }\n const tl = gsap.timeline({ onComplete: done })\n // 1 · Snap — position tweens to the drop point on the zone plane.\n tl.to(group.position, { z: zoneZ + 0.005, duration: 0.12, ease: 'power3.out' }, 0)\n tl.to(group.rotation, { x: 0, y: 0, z: 0, duration: 0.12, ease: 'power3.out' }, 0)\n // 2 · Press — the paper bows into the surface, shadow tightening.\n tl.to(group.scale, { x: 1.02, y: 1.02, z: 1, duration: 0.09, ease: 'power2.in' }, 0.12)\n tl.to(group.position, { z: zoneZ + 0.001, duration: 0.18, ease: 'power2.out' }, 0.12)\n // 3 · Flatten — tiny overshoot on scale (1.0 → 0.985 → 1.0).\n tl.to(group.scale, { x: 0.985, y: 0.985, duration: 0.06, ease: 'power1.inOut' }, 0.3)\n tl.to(group.scale, { x: 1, y: 1, duration: 0.06, ease: 'power1.out' }, 0.36)\n }\n\n // ── The return: flutter back to the slot on a slight arc (spec §5.4) ──\n const returnHome = (carried: CarriedPaper) => {\n const group = groupRefs.current[carried.slot]\n const handle = handleRefs.current[carried.slot]\n if (!group || !handle) return\n carried.settling = true\n registry.setHovered(null)\n\n const home = carried.homePose\n const done = () => {\n handle.returnProgrammatic()\n carriedRef.current = null\n if (controls) controls.enabled = true\n }\n if (reduced) {\n group.position.set(...home.position)\n group.rotation.set(...home.rotation)\n group.scale.setScalar(home.scale)\n done()\n return\n }\n const from = { x: group.position.x, y: group.position.y, z: group.position.z }\n const dist = Math.hypot(from.x - home.position[0], from.y - home.position[1])\n const duration = Math.min(0.8, Math.max(0.25, dist * 0.55))\n // Curved path: a slight arc perpendicular to the travel, not linear.\n const arc = Math.min(0.35, dist * 0.25)\n const proxy = { t: 0 }\n gsap.to(proxy, {\n t: 1,\n duration,\n ease: 'power2.inOut',\n onUpdate: () => {\n const t = proxy.t\n const lift = Math.sin(t * Math.PI) * arc\n group.position.x = from.x + (home.position[0] - from.x) * t\n group.position.y = from.y + (home.position[1] - from.y) * t + lift\n group.position.z = from.z + (home.position[2] - from.z) * t\n // Flutter decays as it approaches.\n handle.set('drive', (1 - t) * 0.5)\n },\n onComplete: done,\n })\n gsap.to(group.rotation, { x: home.rotation[0], y: home.rotation[1], z: home.rotation[2], duration })\n gsap.to(group.scale, { x: home.scale, y: home.scale, z: home.scale, duration: duration * 0.5 })\n }\n\n // ── Press / drag / release wiring ──\n // Handlers close over the current render's state, so the fresh closures live\n // in refs and the window listeners attach ONCE — re-subscribing per render\n // (worst: per slot-state change mid-drag) is listener churn for nothing.\n const onPointerMoveRef = useRef<(e: PointerEvent) => void>(() => {})\n onPointerMoveRef.current = (e: PointerEvent) => {\n const press = pressRef.current\n const carried = carriedRef.current\n if (carried && !carried.settling && (carried.pointerId === null || e.pointerId === carried.pointerId)) {\n const hit = planePoint(e.clientX, e.clientY, carried.homePose.position[2] + 0.15)\n if (hit) {\n carried.targetX = hit[0]\n carried.targetY = hit[1]\n }\n return\n }\n if (!press) return\n const hit = planePoint(e.clientX, e.clientY, poses[press.slot]?.position[2] ?? 0)\n if (!hit) return\n const dist = Math.hypot(hit[0] - press.startX, hit[1] - press.startY)\n const threshold = slotConfigs[press.slot]?.states?.pickThreshold ?? 0.1\n if (dist > threshold) {\n const { slot, pointerId } = press\n pressRef.current = null\n pick(slot, hit[0], hit[1], pointerId)\n }\n }\n const onPointerUpRef = useRef<(e: PointerEvent) => void>(() => {})\n onPointerUpRef.current = (e: PointerEvent) => {\n pressRef.current = null\n const carried = carriedRef.current\n if (!carried || carried.settling) return\n if (carried.pointerId !== null && e.pointerId !== carried.pointerId) return\n const name = slotName(carried.slot)\n const zone = zonesLive().find(\n (z) => zoneContains(z, carried.x.value, carried.y.value) && zoneAccepts(z, name),\n )\n if (zone) settleInto(carried, zone)\n else returnHome(carried)\n }\n useEffect(() => {\n const move = (e: PointerEvent) => onPointerMoveRef.current(e)\n const up = (e: PointerEvent) => onPointerUpRef.current(e)\n window.addEventListener('pointermove', move)\n window.addEventListener('pointerup', up)\n return () => {\n window.removeEventListener('pointermove', move)\n window.removeEventListener('pointerup', up)\n }\n }, [])\n\n // ── The carry loop: damped follow, velocity flutter, zone hover ──\n useFrame((_, delta) => {\n const carried = carriedRef.current\n if (!carried || carried.settling) return\n const group = groupRefs.current[carried.slot]\n const handle = handleRefs.current[carried.slot]\n if (!group || !handle) return\n const dt = Math.min(delta, 1 / 30)\n\n if (reduced) {\n // Reduced motion: direct cursor-following, no flutter, no lag.\n carried.x.value = carried.lastX = carried.targetX\n carried.y.value = carried.lastY = carried.targetY\n group.position.x = carried.targetX\n group.position.y = carried.targetY\n group.position.z = carried.homePose.position[2] + 0.15\n } else {\n dampTo(carried.x, carried.targetX, 0.09, dt)\n dampTo(carried.y, carried.targetY, 0.09, dt)\n const vx = (carried.x.value - carried.lastX) / dt\n const vy = (carried.y.value - carried.lastY) / dt\n carried.lastX = carried.x.value\n carried.lastY = carried.y.value\n const speed = Math.hypot(vx, vy)\n group.position.x = carried.x.value\n group.position.y = carried.y.value\n group.position.z = carried.homePose.position[2] + 0.15\n // Drag velocity becomes flutter + rotational lag: yaw trails the drag.\n handle.set('drive', carryDrive(speed))\n const lag = 0.25\n group.rotation.y += (THREE.MathUtils.clamp(-vx * lag, -0.6, 0.6) - group.rotation.y) * 0.12\n group.rotation.x += (THREE.MathUtils.clamp(vy * lag * 0.7, -0.5, 0.5) - group.rotation.x) * 0.12\n }\n\n // Zone hover: center test each frame; scale-up is the \"this will stick\" cue.\n const name = slotName(carried.slot)\n const zone = zonesLive().find(\n (z) => zoneContains(z, group.position.x, group.position.y) && zoneAccepts(z, name),\n )\n registry.setHovered(zone?.id ?? null)\n const targetScale = (zone ? 1.03 : 1) * carried.homePose.scale\n group.scale.x += (targetScale - group.scale.x) * 0.15\n group.scale.y = group.scale.z = group.scale.x\n })\n\n // ── a11y controller: keyboard pick → move between zones → place/escape ──\n // Same ref-delegation as the pointer listeners: the real implementation is\n // rebuilt per render (fresh closures), the published object is stable.\n const a11yImplRef = useRef<FieldA11yController | null>(null)\n a11yImplRef.current = {\n pick: (slot) => {\n const home = poses[slot]\n if (!home) return false\n // pick() drives the machine (rest→…→picked) itself — no raw events.\n return pick(slot, home.position[0], home.position[1])\n },\n placeAtZone: (slot, zoneId) => {\n const carried = carriedRef.current\n const zone = zonesLive().find((z) => z.id === zoneId)\n const group = groupRefs.current[slot]\n if (!carried || carried.slot !== slot || !zone || !group) return\n group.position.x = zone.bounds.position[0]\n group.position.y = zone.bounds.position[1]\n carried.x.value = group.position.x\n carried.y.value = group.position.y\n settleInto(carried, zone)\n },\n cancel: (slot) => {\n const carried = carriedRef.current\n if (carried && carried.slot === slot && !carried.settling) returnHome(carried)\n },\n zoneIds: () => zonesLive().map((z) => z.id),\n slotState: (slot) => slotStates[slot] ?? 'rest',\n }\n useEffect(() => {\n const ref = props.a11yRef\n if (!ref) return\n ref.current = {\n pick: (slot) => a11yImplRef.current?.pick(slot) ?? false,\n placeAtZone: (slot, zoneId) => a11yImplRef.current?.placeAtZone(slot, zoneId),\n cancel: (slot) => a11yImplRef.current?.cancel(slot),\n zoneIds: () => a11yImplRef.current?.zoneIds() ?? [],\n slotState: (slot) => a11yImplRef.current?.slotState(slot) ?? 'rest',\n }\n return () => {\n ref.current = null\n }\n }, [props.a11yRef])\n\n return (\n <group>\n {sheetOptions?.backing && <BackingSheet options={sheetOptions} count={total} removed={removed} />}\n {(props.zones ?? []).map((zone) => (\n <DropZoneVisual key={zone.id} registry={registry} config={zone} />\n ))}\n {slotConfigs.map((config, i) => {\n const pose = poses[i]!\n return (\n <group\n // biome-ignore lint/suspicious/noArrayIndexKey: a slot IS its index — refs, poses, drags and drops all address a paper by slot number.\n key={i}\n ref={(g) => {\n groupRefs.current[i] = g\n }}\n position={pose.position}\n rotation={pose.rotation}\n scale={pose.scale}\n onPointerDown={(e: ThreeEvent<PointerEvent>) => {\n if (carriedRef.current) return\n const hit = planePoint(e.clientX, e.clientY, pose.position[2])\n if (!hit) return\n pressRef.current = { slot: i, pointerId: e.pointerId, startX: hit[0], startY: hit[1] }\n }}\n >\n <PaperMesh\n ref={(h) => {\n handleRefs.current[i] = h\n }}\n preset={config}\n reducedMotion={props.reducedMotion}\n onStateChange={(state) => onSlotState(i, state)}\n />\n </group>\n )\n })}\n </group>\n )\n}\n","import { useState } from 'react'\nimport { contentText } from '../a11y'\nimport { resolveConfig } from '../PaperMesh'\nimport type { FieldA11yController } from './interactiveField'\nimport type { FieldPaperSlot } from './slots'\n\n/** Carry state of the hidden keyboard mirror: which paper is aloft, which zone is focused. */\nexport interface KeyboardCarry {\n slot: number\n zoneIndex: number\n}\n\n/** A keyboard step's decision: the next carry state and whether it consumed the key. */\nexport interface KeyboardStepResult {\n carry: KeyboardCarry | null\n handled: boolean\n}\n\n/**\n * The M6 §6 keyboard flow as a pure step (so it's testable without a DOM):\n * given the current carry state, the focused paper `slot`, and the pressed\n * `key`, it drives the field `controller` (pick → move between zones → place /\n * cancel) and returns the next carry state. All side effects go through\n * `controller`; the caller applies `carry` to its state and calls\n * `preventDefault()` when `handled` is true.\n */\nexport function fieldKeyboardStep(\n carry: KeyboardCarry | null,\n slot: number,\n key: string,\n controller: FieldA11yController,\n): KeyboardStepResult {\n if (!carry) {\n // Not carrying: Enter/Space on a focused paper picks it up.\n if (key === 'Enter' || key === ' ') {\n return { carry: controller.pick(slot) ? { slot, zoneIndex: 0 } : null, handled: true }\n }\n return { carry, handled: false }\n }\n // Carrying: only the paper actually aloft responds.\n if (carry.slot !== slot) return { carry, handled: false }\n const zoneCount = Math.max(controller.zoneIds().length, 1)\n if (key === 'ArrowRight' || key === 'ArrowDown') {\n return { carry: { ...carry, zoneIndex: (carry.zoneIndex + 1) % zoneCount }, handled: true }\n }\n if (key === 'ArrowLeft' || key === 'ArrowUp') {\n return {\n carry: { ...carry, zoneIndex: (carry.zoneIndex - 1 + zoneCount) % zoneCount },\n handled: true,\n }\n }\n if (key === 'Enter' || key === ' ') {\n const zone = controller.zoneIds()[carry.zoneIndex]\n if (zone) controller.placeAtZone(slot, zone)\n return { carry: null, handled: true }\n }\n if (key === 'Escape') {\n controller.cancel(slot)\n return { carry: null, handled: true }\n }\n return { carry, handled: false }\n}\n\nconst mirrorHidden: React.CSSProperties = {\n position: 'absolute',\n width: 1,\n height: 1,\n padding: 0,\n margin: -1,\n overflow: 'hidden',\n clip: 'rect(0 0 0 0)',\n whiteSpace: 'nowrap',\n border: 0,\n}\n\n/**\n * The hidden DOM mirror of an interactive field: each paper is a button.\n * Keyboard flow — focus a paper, Enter picks it, arrow keys move between\n * zones, Enter places, Escape returns it to its slot (spec M6 §6). The key\n * handling lives in the pure {@link fieldKeyboardStep} so it can be tested.\n */\nexport function FieldKeyboardMirror({\n papers,\n controller,\n}: {\n papers: FieldPaperSlot[]\n controller: React.MutableRefObject<FieldA11yController | null>\n}) {\n const [carrying, setCarrying] = useState<{ slot: number; zoneIndex: number } | null>(null)\n\n const paperLabel = (slot: FieldPaperSlot, i: number): string => {\n try {\n const config = resolveConfig({ preset: slot.preset })\n return `Paper ${i + 1}: ${contentText({ ...config, content: slot.content ?? config.content })}`\n } catch {\n return `Paper ${i + 1}`\n }\n }\n\n const onKeyDown = (i: number) => (e: React.KeyboardEvent) => {\n const ctl = controller.current\n if (!ctl) return\n const { carry, handled } = fieldKeyboardStep(carrying, i, e.key, ctl)\n if (handled) e.preventDefault()\n if (carry !== carrying) setCarrying(carry)\n }\n\n return (\n <fieldset style={mirrorHidden}>\n <legend>Interactive papers</legend>\n {papers.map((slot, i) => (\n <button\n // biome-ignore lint/suspicious/noArrayIndexKey: a slot IS its index — the carry state and every keyboard step address a paper by slot number.\n key={i}\n type=\"button\"\n onKeyDown={onKeyDown(i)}\n aria-label={paperLabel(slot, i)}\n aria-pressed={carrying?.slot === i}\n >\n {paperLabel(slot, i)}\n {carrying?.slot === i && (\n <span aria-live=\"polite\">\n {' '}\n — carrying; zone {controller.current?.zoneIds()[carrying.zoneIndex] ?? 'none'}; Enter places,\n Escape returns\n </span>\n )}\n </button>\n ))}\n </fieldset>\n )\n}\n","import type { AnyOptions, SheetDims } from '../deformers/types'\nimport type { Layout } from './layouts'\nimport { withSheetCellFromPaper, type SheetLayoutOptions } from './sheetGrid'\n\n/**\n * Framing a field is arithmetic, not guesswork: layouts are pure `pose`\n * functions, so we can just ask one where all its sheets are and put the\n * camera where they all fit. Community layouts get framed for free.\n */\n\nexport interface FieldBounds {\n center: [number, number, number]\n /** Half-extents — the box reaches `center ± half`. */\n half: [number, number, number]\n}\n\n/** Cyclic layouts sweep as `phase` advances; frame the whole cycle, not one instant. */\nconst PHASE_SAMPLES = 8\n\n/**\n * Resolve a layout's options the one way both the renderer and the camera\n * must agree on — sheet grids size their cells from the papers themselves.\n */\nexport function resolveLayoutOptions(\n layoutId: string,\n layout: Layout<AnyOptions>,\n propOptions: Record<string, unknown> | undefined,\n firstSheet: SheetDims | undefined,\n): Record<string, unknown> {\n const parsed = layout.optionsSchema.parse({\n ...layout.defaults,\n ...propOptions,\n }) as Record<string, unknown>\n if (layoutId !== 'sheet') return parsed\n return withSheetCellFromPaper(\n parsed as unknown as SheetLayoutOptions,\n propOptions,\n firstSheet,\n ) as unknown as Record<string, unknown>\n}\n\n/**\n * The box `n` sheets occupy under a layout. Each sheet is treated as a ball\n * of its half-diagonal, which covers every rotation the pose can apply\n * without having to build the pose matrices.\n */\nexport function fieldBounds(\n layout: Layout<AnyOptions>,\n n: number,\n options: unknown,\n sheet: SheetDims,\n): FieldBounds {\n const reach = Math.hypot(sheet.width, sheet.height) / 2\n if (n <= 0) return { center: [0, 0, 0], half: [reach, reach, 0] }\n\n const min = [Infinity, Infinity, Infinity]\n const max = [-Infinity, -Infinity, -Infinity]\n for (let s = 0; s < PHASE_SAMPLES; s++) {\n for (let i = 0; i < n; i++) {\n const pose = layout.pose(i, n, options, s / PHASE_SAMPLES, sheet)\n const r = reach * Math.max(pose.scale, 0)\n for (let axis = 0; axis < 3; axis++) {\n min[axis] = Math.min(min[axis]!, pose.position[axis]! - r)\n max[axis] = Math.max(max[axis]!, pose.position[axis]! + r)\n }\n }\n }\n return {\n center: [(min[0]! + max[0]!) / 2, (min[1]! + max[1]!) / 2, (min[2]! + max[2]!) / 2],\n half: [(max[0]! - min[0]!) / 2, (max[1]! - min[1]!) / 2, (max[2]! - min[2]!) / 2],\n }\n}\n\n/** The field has always been viewed from a shade above eye level — keep that. */\nconst LIFT = 0.11\nconst DEG = Math.PI / 180\n\n/**\n * Where to put a perspective camera so every sheet a layout poses lands in\n * frame. Solved per sheet at its own depth rather than against the field's\n * bounding box: a `ring`'s widest sheets sit at mid-depth, and pretending\n * that width exists at the near face would shove the camera far enough back\n * to lose the gallery entirely.\n */\nexport function fitCamera(\n layout: Layout<AnyOptions>,\n n: number,\n options: unknown,\n sheet: SheetDims,\n fovDeg: number,\n aspect: number,\n margin = 1.06,\n): { position: [number, number, number]; target: [number, number, number] } {\n const { center } = fieldBounds(layout, n, options, sheet)\n const reach = (Math.hypot(sheet.width, sheet.height) / 2) * margin\n const vTan = Math.tan((fovDeg * DEG) / 2)\n const hTan = vTan * Math.max(aspect, 0.01)\n\n let distance = 0.1\n for (let s = 0; s < PHASE_SAMPLES; s++) {\n for (let i = 0; i < Math.max(n, 0); i++) {\n const pose = layout.pose(i, n, options, s / PHASE_SAMPLES, sheet)\n const r = reach * Math.max(pose.scale, 0)\n // Depth of this sheet in front of the field's center — a sheet further\n // back needs correspondingly less distance to fit.\n const depth = pose.position[2]! - center[2]!\n distance = Math.max(\n distance,\n (Math.abs(pose.position[0]! - center[0]!) + r) / hTan + depth,\n (Math.abs(pose.position[1]! - center[1]!) + r) / vTan + depth,\n )\n }\n }\n return {\n position: [center[0], center[1] + distance * LIFT, center[2] + distance],\n target: center,\n }\n}\n","import * as THREE from 'three'\nimport { Canvas, useFrame, useThree } from '@react-three/fiber'\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport { z } from 'zod'\nimport { usePrefersReducedMotion } from '../a11y'\nimport type { ContentConfig, PaperConfigInput } from '../config/schema'\nimport { PaperFieldMesh } from '../PaperField'\nimport { resolveConfig } from '../PaperMesh'\nimport type { FieldPaperSlot } from '../field/slots'\nimport { getLayout } from '../field/layouts'\nimport { PaperLighting } from '../scene/PaperLighting'\nimport { getWalkPath } from './path'\nimport { stageCamera, walkPoint } from './camera'\nimport { Figure } from './Figure'\nimport { Source, Surround } from './Surround'\nimport { stageSchema, type StageConfig, type StageConfigInput } from './schema'\nimport {\n FIRST_WINDOW,\n INITIAL_TIER,\n SETTLE_FRAMES,\n STEADY_WINDOW,\n qualityFor,\n qualityTiers,\n tierDown,\n tierUp,\n type QualityName,\n type QualityTier,\n} from './quality'\n\n/**\n * Stage mode: paper as architecture, with a figure walking through it.\n *\n * The one guarantee worth stating — every part of the scene reads the SAME\n * walk. The layout arranges along it, the figure follows it, the camera is\n * stationed on it, and the source stands at the end of it. Handing those\n * four their own copies of a path is the failure this component exists to\n * prevent: a colonnade whose aisle the figure does not walk down is not a\n * near-miss, it is a completely different picture.\n */\n\n/** A banner: tall, translucent, with folds running the length of its drop. */\nconst BANNER: PaperConfigInput = {\n sheet: { width: 1.5, height: 8.5, segments: 'auto' },\n stock: 'vellum',\n surface: { grain: 0.22 },\n deformers: [{ type: 'drape', options: { amplitude: 0.16, folds: 3, falloff: 1.7, gather: 0.28 } }],\n}\n\nexport interface PaperStageSceneProps {\n /** Walk, shot, figure, lighting — see `stageSchema`. */\n stage?: StageConfigInput\n /** Any layout, but `colonnade` is the one built to arrange along a walk. */\n layout?: string\n layoutOptions?: Record<string, unknown>\n /** Per-banner slots, exactly as in field mode. */\n papers?: FieldPaperSlot[]\n images?: string[]\n /**\n * Words on the banners. A string is split across them a line at a time; an\n * array is used as given. This is the whole point of the mode — a space\n * built out of something the viewer wrote.\n */\n text?: string | string[]\n /** Shared preset behind every banner. */\n preset?: string | PaperConfigInput\n /** How many banners, when none of `papers` / `images` / `text` says. */\n count?: number\n /**\n * How far along the walk the figure is, 0..1. Bind it to scroll and the\n * page scrolls the walk. Omit and it walks on the clock at its own speed.\n */\n progress?: number\n reducedMotion?: boolean\n /**\n * How much the render is allowed to cost. `auto` (the default) starts in\n * the middle and adapts to whatever the machine turns out to manage — this\n * scene runs on hardware nobody developing it owns. Not part of the stage\n * config: quality describes the DEVICE, not the artwork, so it must never\n * travel in a preset or a shared link.\n */\n quality?: QualityName\n /**\n * Fires when `auto` moves the tier. Useful for showing the viewer what\n * they are getting, and for measuring what real machines settle on.\n */\n onQualityChange?(tier: QualityTier): void\n}\n\nexport interface PaperStageProps extends PaperStageSceneProps {\n children?: React.ReactNode\n className?: string\n style?: React.CSSProperties\n}\n\n/**\n * Split a paragraph across banners, and stack each banner's share DOWN its\n * drop rather than across its width.\n *\n * A banner is roughly six times taller than it is wide, so a line of prose\n * set across it wraps to nothing and leaves the other 90% of the paper\n * blank. Every reference image runs its text as a vertical column, which is\n * both what the shape wants and what makes the paper read as printed rather\n * than as a rectangle with a caption.\n */\nexport function splitAcrossBanners(text: string, banners: number): string[] {\n const words = text.split(/\\s+/).filter(Boolean)\n if (words.length === 0 || banners <= 0) return []\n const per = Math.ceil(words.length / banners)\n const out: string[] = []\n for (let i = 0; i < words.length; i += per) out.push(words.slice(i, i + per).join('\\n'))\n return out\n}\n\n/**\n * Type size for a banner carrying `lines` stacked lines — chosen to FILL the\n * drop, because a column of type that stops a third of the way down reads as\n * a mistake rather than as a design.\n *\n * The banner's texture is 1024px on its long edge and the column is set at\n * 1.25 line-height inside a 6% margin, so `lines × size × 1.25 ≈ 900` is the\n * size that lands the last line at the bottom of the paper. Clamped at both\n * ends: two words on an eight-metre drop should be enormous, but not so\n * enormous they crop, and a dense column still has to stay legible.\n */\nexport function bannerTextSize(lines: number): number {\n return Math.round(Math.min(150, Math.max(26, 720 / Math.max(lines, 1))))\n}\n\n/** The walk drives the camera; nothing else is allowed to move it. */\nfunction ShotRig({\n stage,\n paperHeight,\n progress,\n still,\n}: {\n stage: StageConfig\n paperHeight: number\n progress?: number\n still: boolean\n}) {\n const camera = useThree((s) => s.camera)\n const path = useMemo(() => getWalkPath(stage.path), [stage.path])\n const scale = useMemo(\n () => ({ figure: stage.figure.height, paper: paperHeight }),\n [stage.figure.height, paperHeight],\n )\n\n useFrame((state) => {\n const walked = stageWalked(path.length, stage, progress, still ? 0 : state.clock.elapsedTime)\n const { position, target } = stageCamera(path, walked, scale, stage.shot)\n camera.position.set(position[0], position[1], position[2])\n camera.lookAt(target[0], target[1], target[2])\n })\n return null\n}\n\n/**\n * Distance walked, from whichever driver is in charge. Shared by the camera\n * and the figure so they cannot drift apart by a frame or a formula.\n */\nfunction stageWalked(\n length: number,\n stage: StageConfig,\n progress: number | undefined,\n elapsed: number,\n): number {\n if (progress !== undefined) return progress * length\n return elapsed * stage.figure.speed\n}\n\n/** Below this, step down. Above the upper one, step up. */\nconst FLOOR_FPS = 26\nconst CEILING_FPS = 55\n\n/**\n * Watches the real frame rate and moves the tier.\n *\n * Deliberately hysteretic and slow: the two thresholds are far apart and\n * there is a settling period after every change, because a monitor that\n * reacts fast oscillates — dropping quality raises the frame rate, which\n * immediately argues for raising quality again, and the scene visibly\n * pumps. A machine that cannot hold the floor should sink once and stay.\n */\nfunction QualityWatch({ tier, onChange }: { tier: QualityTier; onChange: (tier: QualityTier) => void }) {\n const samples = useRef<number[]>([])\n const settle = useRef(SETTLE_FRAMES)\n // The first verdict comes quickly; later ones are measured carefully.\n const window = useRef(FIRST_WINDOW)\n\n const settled = useCallback((next: QualityTier) => {\n samples.current = []\n settle.current = SETTLE_FRAMES\n window.current = STEADY_WINDOW\n return next\n }, [])\n\n useFrame((_, delta) => {\n if (settle.current > 0) {\n settle.current -= 1\n return\n }\n // A tab returning from the background delivers one enormous delta;\n // it says nothing about the hardware.\n if (delta > 0.5) return\n samples.current.push(delta)\n if (samples.current.length < window.current) return\n\n const sorted = [...samples.current].sort((a, b) => a - b)\n const median = sorted[Math.floor(sorted.length / 2)]!\n const fps = 1 / median\n samples.current = []\n // Even if the tier does not move, stop judging on the short window.\n window.current = STEADY_WINDOW\n\n if (fps < FLOOR_FPS) {\n const next = tierDown(tier)\n if (next !== tier) onChange(settled(next))\n } else if (fps > CEILING_FPS) {\n const next = tierUp(tier)\n if (next !== tier) onChange(settled(next))\n }\n })\n return null\n}\n\nexport function PaperStageScene({\n stage: stageInput,\n quality = 'auto',\n onQualityChange,\n layout = 'colonnade',\n layoutOptions,\n papers,\n images,\n text,\n preset,\n count = 22,\n progress,\n reducedMotion,\n}: PaperStageSceneProps) {\n const still = usePrefersReducedMotion(reducedMotion)\n // `auto` starts mid and is stepped by the frame-rate watcher below.\n const [tier, setTier] = useState<QualityTier>(quality === 'auto' ? INITIAL_TIER : (quality as QualityTier))\n useEffect(() => {\n if (quality !== 'auto') setTier(quality as QualityTier)\n }, [quality])\n useEffect(() => {\n onQualityChange?.(tier)\n }, [tier, onQualityChange])\n const settings = quality === 'auto' ? qualityTiers[tier] : qualityFor(quality)\n\n const stage = useMemo(() => stageSchema.parse(stageInput ?? {}), [stageInput])\n const path = useMemo(() => getWalkPath(stage.path), [stage.path])\n // The shot frames the ARCHITECTURE, so it has to know how tall the paper\n // is — read from the preset in play rather than assumed.\n const paperHeight = useMemo(() => resolveConfig({ preset: preset ?? BANNER }).sheet.height, [preset])\n\n // Subdivision is the biggest single cost and the easiest to scale: every\n // sheet is a grid, so halving it quarters the vertex work.\n const paper = useMemo(() => {\n const base = (preset ?? BANNER) as Record<string, unknown>\n if (typeof base !== 'object') return preset ?? BANNER\n const sheet = (base.sheet ?? {}) as Record<string, unknown>\n return { ...base, sheet: { ...sheet, segments: settings.segments } } as typeof BANNER\n }, [preset, settings.segments])\n\n // The walk reaches the layout too. A layout that arranges along a path and\n // a figure that walks a different one is the one bug this whole component\n // is arranged to make impossible, so the stage's path always wins.\n const resolvedLayoutOptions = useMemo(() => {\n const schema = getLayout(layout).optionsSchema\n const takesPath = schema instanceof z.ZodObject && 'path' in schema.shape\n return takesPath ? { ...layoutOptions, path: stage.path } : layoutOptions\n }, [layout, layoutOptions, stage.path])\n\n const slots = useMemo<FieldPaperSlot[] | undefined>(() => {\n if (papers) return papers\n if (images) return undefined\n if (text !== undefined) {\n const columns = Array.isArray(text) ? text : splitAcrossBanners(text, count)\n const longest = columns.reduce((n, c) => Math.max(n, c.split('\\n').length), 1)\n const size = bannerTextSize(longest)\n return columns.map((column) => ({\n content: {\n type: 'text',\n text: column,\n size,\n align: 'center',\n color: '#241f1a',\n lineHeight: 1.25,\n font: 'Georgia, \"Times New Roman\", serif',\n weight: 400,\n padding: 0.06,\n } satisfies ContentConfig,\n }))\n }\n return Array.from({ length: count }, () => ({}))\n }, [papers, images, text, count])\n\n const figureDistance = progress !== undefined ? progress * path.length : undefined\n\n // One radius for the room: the sky, the floor and the far clip all measure\n // from it, and they have to agree or the horizon tears.\n const surroundRadius = useMemo(\n () => Math.max(path.length * 1.6, paperHeight * 9),\n [path.length, paperHeight],\n )\n\n // The source stands past the end of the walk, facing back down it.\n const source = useMemo(() => {\n const [x, z] = walkPoint(path, path.length + stage.source.beyond)\n const [tx, tz] = path.tangentAt(1)\n const size = paperHeight * stage.source.spread\n return { position: [x, size * 0.35, z] as const, yaw: Math.atan2(-tx, -tz), size }\n }, [path, stage.source.beyond, stage.source.spread, paperHeight])\n\n return (\n <>\n <ShotRig stage={stage} paperHeight={paperHeight} progress={progress} still={still} />\n <PaperLighting\n preset={stage.lighting}\n floor={0}\n scale={60}\n reducedMotion={reducedMotion}\n shadowMapSize={settings.shadowMapSize}\n contactShadow={settings.contactShadow}\n />\n {quality === 'auto' && <QualityWatch tier={tier} onChange={setTier} />}\n\n {stage.source.surround && settings.surround && (\n <Surround radius={surroundRadius} horizon={stage.source.color} zenith={stage.source.zenith} />\n )}\n\n {stage.source.enabled && (\n <Source size={source.size} position={source.position} yaw={source.yaw} color={stage.source.color} />\n )}\n\n {stage.ground.enabled && (\n <mesh rotation={[-Math.PI / 2, 0, 0]} receiveShadow>\n {/* A square of side s has corners at s·0.707 — keep them inside the\n surround, or the floor punches out through the sky. */}\n <planeGeometry args={[surroundRadius * 1.3, surroundRadius * 1.3]} />\n <meshStandardMaterial color={stage.ground.color} roughness={1} />\n </mesh>\n )}\n\n <PaperFieldMesh\n preset={paper}\n papers={slots}\n images={images}\n layout={layout}\n layoutOptions={resolvedLayoutOptions}\n motion={{ driver: 'none' }}\n entrance={{ type: 'none' }}\n reducedMotion={reducedMotion}\n />\n\n {stage.showFigure && (\n <Figure path={stage.path} figure={stage.figure} distance={figureDistance} frozen={reducedMotion} />\n )}\n </>\n )\n}\n\n/** `<PaperStage />` owns its Canvas; `<PaperStageScene />` drops into an existing one. */\nexport function PaperStage({ children, className, style, ...sceneProps }: PaperStageProps) {\n // Fragment cost scales with the SQUARE of pixel ratio, and this scene is\n // fragment-heavy. The canvas is created once, so the cap is taken from the\n // tier the scene starts at rather than followed live.\n const dpr = qualityFor(sceneProps.quality ?? 'auto').dpr\n return (\n <div className={className} style={{ width: '100%', height: '100%', ...style }}>\n <Canvas\n shadows\n dpr={[1, dpr]}\n camera={{ fov: 38, near: 0.05, far: 400 }}\n onCreated={({ gl, scene }) => {\n gl.toneMapping = THREE.ACESFilmicToneMapping\n scene.background = new THREE.Color('#0c0a0b')\n }}\n >\n <PaperStageScene {...sceneProps} />\n {children}\n </Canvas>\n </div>\n )\n}\n","import { z } from 'zod'\nimport type { Ground, WalkPath } from './path'\n\n/**\n * Where to put the camera on a walk.\n *\n * `fitCamera` in field/framing.ts solves a different problem — get every\n * sheet inside the frustum — and solving it here would produce the neutral\n * three-quarter product shot that stage mode exists to avoid. These are\n * SHOTS: a camera stationed relative to the walking figure, framing the\n * space rather than the objects, with the vanishing point doing the work.\n */\n\nexport const shotNames = ['follow', 'lead', 'low', 'wide'] as const\nexport type ShotName = (typeof shotNames)[number]\n\nexport const shotSchema = z.object({\n shot: z.enum(shotNames).default('follow'),\n /**\n * How far the camera stands off the figure ALONG the walk, world units.\n * `wide` reads it as how far back it stands; how far it steps aside is\n * derived from the paper, since that is what it has to clear.\n */\n distance: z.number().min(0.2).max(40).default(4.5),\n /** Multiplier on the shot's natural camera height. 1 is as designed. */\n height: z.number().min(0).max(6).default(1),\n /** How far up the walk the camera looks past the figure, world units. */\n lookAhead: z.number().min(0).max(40).default(7),\n /** Sideways step off the walk line, world units. Positive is the walker's left. */\n offset: z.number().min(-20).max(20).default(0),\n})\n\nexport type ShotOptions = z.infer<typeof shotSchema>\n\nexport interface StageShot {\n position: [x: number, y: number, z: number]\n target: [x: number, y: number, z: number]\n}\n\n/**\n * What each shot is FOR. A stage has two subjects at very different scales —\n * a body about 1.75 units tall and paper five times that — and a camera that\n * only knows about the body frames the body, which is how a colonnade of\n * printed banners ends up showing its bottom third and the tops of some\n * letterforms. Camera height stays a body measurement (eye level is eye\n * level); where it AIMS is a blend, and the paper carries most of it.\n */\nexport interface StageScale {\n /** Standing height of the figure. */\n figure: number\n /** Height of the tallest paper on the stage. */\n paper: number\n}\n\n/** Camera height per shot, as a multiple of the figure's own height. */\nconst EYE: Record<ShotName, number> = {\n follow: 0.95,\n lead: 0.95,\n // Down near the floor, where the banners tower — the worm's-eye of the\n // reference frames, and the cheapest way to make paper read as architecture.\n low: 0.12,\n wide: 1.1,\n}\n\n/** Where each shot aims: a blend of the figure's height and the paper's. */\nconst AIM: Record<ShotName, StageScale> = {\n // Chest height on the figure, a third of the way up the paper — enough\n // tilt that a printed banner reads, not so much that the floor is lost.\n follow: { figure: 0.62, paper: 0.3 },\n // Framing the figure itself, so the paper only lifts the aim a little.\n lead: { figure: 0.62, paper: 0.1 },\n // Up the banners. The figure is incidental to this shot.\n low: { figure: 0, paper: 0.62 },\n wide: { figure: 0.62, paper: 0.2 },\n}\n\n/**\n * A point measured in DISTANCE along the walk rather than normalized `s`,\n * extrapolating straight past either end of an open path. Without that, a\n * following camera at the start of a walk would clamp onto the figure's own\n * feet instead of standing back off it.\n */\n/** How far `wide` stands off the walk line, as a multiple of the paper's height. */\nconst WIDE_STANDOFF = 1.5\n\n/** A tall banner runs about five times the height of the person beside it. */\nexport const DEFAULT_PAPER_RATIO = 4.9\n\nfunction resolveScale(scale: StageScale | number): StageScale {\n if (typeof scale === 'number') return { figure: scale, paper: scale * DEFAULT_PAPER_RATIO }\n return scale\n}\n\nexport function walkPoint(path: WalkPath, distance: number): Ground {\n if (path.length === 0) return path.pointAt(0)\n if (path.closed) return path.pointAt(distance / path.length)\n if (distance < 0) {\n const [x, z] = path.pointAt(0)\n const [tx, tz] = path.tangentAt(0)\n return [x + tx * distance, z + tz * distance]\n }\n if (distance > path.length) {\n const over = distance - path.length\n const [x, z] = path.pointAt(1)\n const [tx, tz] = path.tangentAt(1)\n return [x + tx * over, z + tz * over]\n }\n return path.pointAt(distance / path.length)\n}\n\n/** Normal at a distance along the walk, extrapolation included. */\nfunction walkNormal(path: WalkPath, distance: number): Ground {\n if (path.length === 0) return path.normalAt(0)\n if (path.closed) return path.normalAt(distance / path.length)\n return path.normalAt(Math.min(Math.max(distance, 0), path.length) / path.length)\n}\n\n/**\n * Station the camera for a figure that has walked `walked` units along the\n * path. Every height is expressed as a multiple of something in the frame —\n * the body, or the paper — so a shot holds its composition when the stage is\n * rescaled rather than needing to be re-tuned.\n *\n * `scale` accepts a bare number for the figure's height, in which case the\n * paper is assumed to be the banner-ish proportion of it.\n */\nexport function stageCamera(\n path: WalkPath,\n walked: number,\n scale: StageScale | number,\n options: ShotOptions,\n): StageShot {\n const { figure, paper } = resolveScale(scale)\n const eye = figure * EYE[options.shot] * options.height\n const aim = figure * AIM[options.shot].figure + paper * AIM[options.shot].paper\n\n // Where the camera stands along the walk, and where it points.\n let station: number\n let mark: number\n if (options.shot === 'lead') {\n // Ahead of the figure, walking backward in front of it.\n station = walked + options.distance\n mark = walked\n } else if (options.shot === 'wide') {\n // An establishing shot: back along the walk AND out to one side.\n station = walked - options.distance\n mark = walked\n } else {\n station = walked - options.distance\n mark = walked + options.lookAhead\n }\n\n const [sx, sz] = walkPoint(path, station)\n const [mx, mz] = walkPoint(path, mark)\n const [nx, nz] = walkNormal(path, station)\n // How far `wide` steps aside cannot come from `distance`: an aisle is only\n // a few units across, so any sane walk-distance drops the camera inside\n // the colonnade looking at the back of one banner. It has to clear the\n // paper, so it is the paper that sets it.\n const step = options.offset + (options.shot === 'wide' ? paper * WIDE_STANDOFF : 0)\n\n return {\n position: [sx + nx * step, eye, sz + nz * step],\n target: [mx, aim, mz],\n }\n}\n","import * as THREE from 'three'\nimport { useEffect, useMemo, useRef } from 'react'\nimport { useFrame } from '@react-three/fiber'\nimport { usePrefersReducedMotion } from '../a11y'\nimport { getWalkPath, walkPathSchema, type WalkPathOptions } from './path'\nimport { PROPORTIONS, figureSchema, placeFigure, type FigureOptions } from './gait'\n\n/**\n * The walking silhouette. Capsules, no rig, unlit near-black — see\n * `figure.ts` for why crude is the correct amount of fidelity here.\n *\n * `distance` is the whole interaction model. Leave it off and the figure\n * walks on the clock; drive it from scroll and the page scrolls the walk,\n * which is the same scene doing duty as both a shareable loop and a\n * scroll-driven hero.\n */\n\nexport interface FigureProps {\n /** The walk to follow. Defaults to the straight walk away from camera. */\n path?: WalkPathOptions\n /** Height, pace, stride, color — see `figureSchema`. */\n figure?: Partial<FigureOptions>\n /**\n * Distance walked in world units. Omit to advance on the clock at the\n * figure's own speed; supply it to drive the walk from scroll or a timeline.\n */\n distance?: number\n /** Freeze the gait (also forced by `prefers-reduced-motion`). */\n frozen?: boolean\n}\n\n/** A limb segment hanging from its joint: a capsule whose top end is the pivot. */\nfunction Segment({ length, radius, material }: { length: number; radius: number; material: THREE.Material }) {\n // CapsuleGeometry's `length` is the cylinder between the caps, so the\n // rounded ends have to come out of the segment's own length.\n const shaft = Math.max(length - radius * 2, 0.001)\n return (\n <mesh position={[0, -length / 2, 0]} material={material} castShadow>\n <capsuleGeometry args={[radius, shaft, 4, 10]} />\n </mesh>\n )\n}\n\nexport function Figure({ path, figure, distance, frozen }: FigureProps) {\n const reducedMotion = usePrefersReducedMotion()\n const still = frozen ?? reducedMotion\n\n const options = useMemo(() => figureSchema.parse(figure ?? {}), [figure])\n const walk = useMemo(() => getWalkPath(walkPathSchema.parse(path ?? {})), [path])\n\n const root = useRef<THREE.Group>(null)\n const hips = useRef<THREE.Group>(null)\n const legL = useRef<THREE.Group>(null)\n const legR = useRef<THREE.Group>(null)\n const kneeL = useRef<THREE.Group>(null)\n const kneeR = useRef<THREE.Group>(null)\n const armL = useRef<THREE.Group>(null)\n const armR = useRef<THREE.Group>(null)\n\n // One material for the whole body: a silhouette is a single shape, and an\n // unlit one survives a scene lit from behind, where a shaded figure would\n // dissolve into the very haze it has to stand against.\n const material = useMemo(\n () => new THREE.MeshBasicMaterial({ color: options.color, toneMapped: false }),\n [options.color],\n )\n useEffect(() => () => material.dispose(), [material])\n\n const h = options.height\n const p = PROPORTIONS\n const torso = (p.shoulder - p.hip) * h\n\n useFrame((state) => {\n // A frozen figure still stands wherever `distance` puts it — it stops\n // stepping, it does not teleport to the start of the walk.\n const walked = distance ?? (still ? 0 : state.clock.elapsedTime * options.speed)\n const { position, yaw, pose } = placeFigure(walk, walked, options)\n\n root.current?.position.set(position[0], position[1], position[2])\n if (root.current) root.current.rotation.y = yaw\n\n if (hips.current) {\n hips.current.position.y = p.hip * h + (still ? 0 : pose.bob)\n hips.current.rotation.x = pose.lean\n }\n // Limbs hang downward, so a forward swing is a NEGATIVE rotation about X.\n if (legL.current) legL.current.rotation.x = still ? 0 : -pose.leftThigh\n if (legR.current) legR.current.rotation.x = still ? 0 : -pose.rightThigh\n if (kneeL.current) kneeL.current.rotation.x = still ? 0 : -pose.leftKnee\n if (kneeR.current) kneeR.current.rotation.x = still ? 0 : -pose.rightKnee\n if (armL.current) armL.current.rotation.x = still ? 0 : -pose.leftArm\n if (armR.current) armR.current.rotation.x = still ? 0 : -pose.rightArm\n })\n\n return (\n <group ref={root}>\n <group ref={hips}>\n <mesh position={[0, torso / 2, 0]} material={material} castShadow>\n <capsuleGeometry args={[(p.torsoWidth * h) / 2, torso * 0.72, 4, 12]} />\n </mesh>\n <mesh position={[0, (p.headCenter - p.hip) * h, 0]} material={material} castShadow>\n <sphereGeometry args={[p.headRadius * h, 14, 12]} />\n </mesh>\n\n {[-1, 1].map((side) => {\n const leg = side < 0 ? legL : legR\n const knee = side < 0 ? kneeL : kneeR\n return (\n <group key={`leg${side}`} ref={leg} position={[(side * p.hipWidth * h) / 2, 0, 0]}>\n <Segment length={p.thigh * h} radius={p.limbRadius * h} material={material} />\n <group ref={knee} position={[0, -p.thigh * h, 0]}>\n <Segment length={p.shin * h} radius={p.limbRadius * h * 0.9} material={material} />\n </group>\n </group>\n )\n })}\n\n {[-1, 1].map((side) => (\n <group\n key={`arm${side}`}\n ref={side < 0 ? armL : armR}\n position={[(side * p.torsoWidth * h) / 2, torso, 0]}\n >\n <Segment\n length={(p.upperArm + p.foreArm) * h}\n radius={p.limbRadius * h * 0.8}\n material={material}\n />\n </group>\n ))}\n </group>\n </group>\n )\n}\n","import { z } from 'zod'\nimport type { WalkPath } from './path'\n\n/**\n * The figure — a silhouette walking the path. It exists for one reason:\n * SCALE. A banner is just a rectangle until there is a body beside it, and\n * every reference image for this mode is carried by one small dark shape\n * that never competes for attention.\n *\n * Which is also why the model is deliberately crude. At the size the figure\n * reads on screen it is forty pixels of unlit black; fidelity buys nothing,\n * and the CONTACT SHADOW does the work of selling the floor. So: procedural\n * gait, capsule limbs, no rig, no asset, no download. Pure math here (it\n * tests in node); the meshes live in Figure.tsx.\n */\n\nexport const figureSchema = z.object({\n /** Standing height in world units — the scale reference the whole stage is read against. */\n height: z.number().min(0.5).max(4).default(1.75),\n /** World units per second along the walk. A relaxed indoor pace is ~1.2. */\n speed: z.number().min(0).max(4).default(1.2),\n /** Stride length as a fraction of height — how far one step carries. */\n stride: z.number().min(0.1).max(1).default(0.42),\n /** Arm swing, 0..1. Drop it toward 0 for hands-in-pockets stillness. */\n swing: z.number().min(0).max(1).default(1),\n /** Silhouette color. Near-black by default: it should read as an absence, not an object. */\n color: z.string().default('#0a0a0c'),\n})\n\nexport type FigureOptions = z.infer<typeof figureSchema>\n\n/**\n * Segment lengths as fractions of standing height, roughly canonical human\n * proportions. Shared by the gait, the renderer, and anything that needs to\n * know how tall the hips are.\n */\nexport const PROPORTIONS = {\n hip: 0.53,\n shoulder: 0.82,\n headRadius: 0.045,\n headCenter: 0.935,\n thigh: 0.245,\n shin: 0.235,\n upperArm: 0.185,\n foreArm: 0.165,\n torsoWidth: 0.19,\n hipWidth: 0.095,\n limbRadius: 0.028,\n} as const\n\n/** Peak thigh swing, radians (~24°). */\nconst THIGH_SWING = 0.42\n/** Peak arm swing, radians (~29°). */\nconst ARM_SWING = 0.5\n/** Peak knee flex during swing-through, radians (~63°). */\nconst KNEE_FLEX = 1.1\n/** Hip rise and fall, as a fraction of height. */\nconst BOB = 0.016\n/** Forward lean at full speed, radians. */\nconst LEAN = 0.045\n\nconst TAU = Math.PI * 2\n\n/**\n * One instant of the gait. Angles are radians about the figure's X axis;\n * positive swings a limb FORWARD, along the direction of travel.\n */\nexport interface FigurePose {\n /** Where in the two-step cycle, 0..1. */\n phase: number\n /** Vertical offset of the hips from standing, world units (always ≤ 0). */\n bob: number\n /** Forward lean of the torso. */\n lean: number\n leftThigh: number\n rightThigh: number\n /** Knee flex, relative to the thigh. Always ≤ 0 — a knee folds backward only. */\n leftKnee: number\n rightKnee: number\n leftArm: number\n rightArm: number\n}\n\n/** Length of one full two-step cycle, in world units. */\nexport function cycleLength(o: FigureOptions): number {\n return o.stride * o.height * 2\n}\n\n/**\n * The gait at a given distance walked. Driven by DISTANCE, not by time, so\n * the feet cannot skate: however the figure is paced — clock, scroll, or a\n * scrubbed timeline — a step always covers a step's worth of ground.\n */\nexport function figureGait(distance: number, o: FigureOptions): FigurePose {\n const cycle = cycleLength(o)\n const phase = cycle > 0 ? (((distance / cycle) % 1) + 1) % 1 : 0\n const w = phase * TAU\n\n const leftThigh = THIGH_SWING * Math.sin(w)\n const rightThigh = THIGH_SWING * Math.sin(w + Math.PI)\n\n // The knee folds through the swing — the leg is travelling forward and has\n // to clear the floor — and stays straight through the stance, where it is\n // carrying weight. Peak flex sits at mid-swing, three quarters of a cycle\n // after the leg is furthest forward.\n const flex = (at: number) => -KNEE_FLEX * Math.max(0, Math.cos(w - at)) ** 1.5\n const leftKnee = flex((7 * Math.PI) / 4)\n const rightKnee = flex((3 * Math.PI) / 4)\n\n // Arms oppose legs — the counter-rotation that stops a walk reading as a shamble.\n const leftArm = -ARM_SWING * o.swing * Math.sin(w)\n const rightArm = -ARM_SWING * o.swing * Math.sin(w + Math.PI)\n\n // Hips rise over each stance leg and drop through double support: twice a cycle.\n const bob = -BOB * o.height * (1 - Math.abs(Math.cos(w)))\n\n return {\n phase,\n bob,\n lean: LEAN * Math.min(o.speed / 1.2, 1),\n leftThigh,\n rightThigh,\n leftKnee,\n rightKnee,\n leftArm,\n rightArm,\n }\n}\n\n/** Where the figure stands, which way it faces, and what its limbs are doing. */\nexport interface FigurePlacement {\n /** Ground contact point — the renderer lifts the body off it. */\n position: [x: number, y: number, z: number]\n /** Facing, radians about Y. The figure model faces +Z at yaw 0, as sheets do. */\n yaw: number\n pose: FigurePose\n /** Normalized arc length along the walk, after wrapping or clamping. */\n s: number\n}\n\n/**\n * Put the figure on the walk at a given distance travelled. An open path\n * clamps at its end (the figure arrives and stands); a closed one wraps\n * forever, which is what a looping shot wants.\n */\nexport function placeFigure(path: WalkPath, distance: number, o: FigureOptions): FigurePlacement {\n const raw = path.length > 0 ? distance / path.length : 0\n const s = path.closed ? ((raw % 1) + 1) % 1 : Math.min(Math.max(raw, 0), 1)\n const [x, z] = path.pointAt(s)\n const [tx, tz] = path.tangentAt(s)\n // An open path holds the last pose once the walk runs out, rather than\n // marching the figure on through the far wall.\n const travelled = path.closed ? distance : Math.min(distance, path.length)\n return {\n position: [x, 0, z],\n yaw: Math.atan2(tx, tz),\n pose: figureGait(travelled, o),\n s,\n }\n}\n","import * as THREE from 'three'\nimport { useEffect, useMemo } from 'react'\n\n/**\n * The cyclorama: an inverted sphere graded from the source colour at the\n * horizon to near-dark overhead.\n *\n * A single bright plane at the end of the walk is enough for a shot pointed\n * down that walk, and nothing at all for one pointed across it — `wide`\n * framed the figure against an unlit void. A room has walls in every\n * direction, and grading them toward the light is what puts the haze and the\n * distance on the same side of the frame as the source.\n */\n\n/** Procedural, so the repo carries no binary and the grade stays editable. */\nexport function makeSkyTexture(horizon: string, zenith: string): THREE.CanvasTexture {\n const canvas = document.createElement('canvas')\n canvas.width = 4\n canvas.height = 256\n const ctx = canvas.getContext('2d')!\n const grade = ctx.createLinearGradient(0, 0, 0, canvas.height)\n // Canvas row 0 is the top of the sphere. The grade has to travel most of\n // the way down: held flat until near the horizon it reads as a dark lid\n // over a bright slot, which is the black void this is here to remove.\n grade.addColorStop(0, zenith)\n grade.addColorStop(0.35, zenith)\n grade.addColorStop(0.92, horizon)\n grade.addColorStop(1, horizon)\n ctx.fillStyle = grade\n ctx.fillRect(0, 0, canvas.width, canvas.height)\n const texture = new THREE.CanvasTexture(canvas)\n texture.colorSpace = THREE.SRGBColorSpace\n return texture\n}\n\n/**\n * The source itself: bright at the centre, falling to nothing at the edges.\n *\n * A flat rectangle of light has a BORDER, and the moment a shot is not\n * pointed straight down the walk that border draws a hard diagonal across\n * the sky. Fading it out is what lets a finite plane read as an opening\n * rather than as a panel hung in the room.\n */\nexport function makeGlowTexture(color: string): THREE.CanvasTexture {\n const size = 256\n const canvas = document.createElement('canvas')\n canvas.width = canvas.height = size\n const ctx = canvas.getContext('2d')!\n const glow = ctx.createRadialGradient(size / 2, size / 2, 0, size / 2, size / 2, size / 2)\n glow.addColorStop(0, color)\n glow.addColorStop(0.55, color)\n // Same colour throughout — only the alpha falls, so the fade never tints.\n glow.addColorStop(1, 'rgba(0, 0, 0, 0)')\n ctx.fillStyle = glow\n ctx.fillRect(0, 0, size, size)\n const texture = new THREE.CanvasTexture(canvas)\n texture.colorSpace = THREE.SRGBColorSpace\n return texture\n}\n\nexport function Source({\n size,\n position,\n yaw,\n color,\n}: {\n size: number\n position: readonly [number, number, number]\n yaw: number\n color: string\n}) {\n const texture = useMemo(() => makeGlowTexture(color), [color])\n useEffect(() => () => texture.dispose(), [texture])\n return (\n <mesh position={position as unknown as THREE.Vector3} rotation={[0, yaw, 0]}>\n <planeGeometry args={[size * 2.4, size * 1.8]} />\n <meshBasicMaterial\n map={texture}\n transparent\n // It is light, not an object: it must not occlude, tone-map or fog.\n depthWrite={false}\n toneMapped={false}\n fog={false}\n />\n </mesh>\n )\n}\n\nexport function Surround({ radius, horizon, zenith }: { radius: number; horizon: string; zenith: string }) {\n const texture = useMemo(() => makeSkyTexture(horizon, zenith), [horizon, zenith])\n useEffect(() => () => texture.dispose(), [texture])\n\n return (\n <mesh>\n <sphereGeometry args={[radius, 32, 24]} />\n {/* Unlit and unfogged — it IS the distance, so haze must not stack on it. */}\n <meshBasicMaterial map={texture} side={THREE.BackSide} fog={false} />\n </mesh>\n )\n}\n","import { z } from 'zod'\nimport { lightingNames } from '../config/schema'\nimport { walkPathSchema } from './path'\nimport { shotSchema } from './camera'\nimport { figureSchema } from './gait'\n\n/**\n * A stage serializes like everything else here: one object that fully\n * describes the walk, who walks it, where the camera stands, and how the\n * space is lit. Same rule as the paper schema — a feature that can't\n * serialize into this waits.\n */\n\nexport const stageSourceSchema = z.object({\n /** The bright void the walk resolves toward. Without it the vanishing point is a hole. */\n enabled: z.boolean().default(true),\n color: z.string().default('#fff4e2'),\n /** How far past the end of the walk it stands, world units. */\n beyond: z.number().min(0).max(80).default(10),\n /**\n * A cyclorama around the whole stage, graded from the source colour at the\n * horizon to near-dark overhead. The source plane only faces down the walk,\n * so without this every shot that isn't axial — `wide` especially — looks\n * out at a black void where the room should be.\n */\n surround: z.boolean().default(true),\n /** Colour overhead. The horizon takes the source's own colour. */\n zenith: z.string().default('#241c17'),\n /** Size, as a multiple of the PAPER height — it only has to out-fill the frame. */\n spread: z.number().min(1).max(60).default(5),\n})\n\nexport const stageGroundSchema = z.object({\n /** The floor. Without something to catch the shadows there is no ground and no scale. */\n enabled: z.boolean().default(true),\n color: z.string().default('#0e0b09'),\n})\n\nexport const stageSchema = z.object({\n path: walkPathSchema.default({}),\n shot: shotSchema.default({}),\n figure: figureSchema.default({}),\n /** Stage mode is built for `nave`; the others are all front-lit. */\n lighting: z.enum(lightingNames).default('nave'),\n showFigure: z.boolean().default(true),\n source: stageSourceSchema.default({}),\n ground: stageGroundSchema.default({}),\n})\n\nexport type StageConfig = z.infer<typeof stageSchema>\nexport type StageConfigInput = z.input<typeof stageSchema>\n","/**\n * Render quality tiers.\n *\n * A stage is the heaviest thing this library draws — tens of thousands of\n * subdivided vertices, a shadow pass, a translucent fragment shader and a\n * full-screen backdrop — and it has to run on machines nobody developing it\n * owns. Quality is deliberately NOT part of `stageSchema`: it describes the\n * device, not the artwork, so it must never travel in a preset or a shared\n * link. Two people opening the same link should see the same scene at\n * whatever fidelity their hardware can hold.\n *\n * The four knobs, in the order they actually cost:\n *\n * - `segments` — subdivisions along a banner's long edge. Quadratic: every\n * sheet is a grid, so halving this quarters the vertex work.\n * - `shadowMapSize` — the shadow pass re-renders the scene's geometry. 0\n * turns shadows off, which on a weak machine is the difference between\n * moving and not.\n * - `dpr` — fragment cost scales with the square of it, and this scene is\n * fragment-heavy (translucency, fog, a full-screen backdrop).\n * - `surround` — one more full-screen draw; cheap, but free to drop.\n */\n\nexport const qualityNames = ['auto', 'low', 'medium', 'high'] as const\nexport type QualityName = (typeof qualityNames)[number]\nexport type QualityTier = Exclude<QualityName, 'auto'>\n\nexport interface QualitySettings {\n /** Cap on device pixel ratio. */\n dpr: number\n /** Shadow map resolution. 0 turns the shadow pass off entirely. */\n shadowMapSize: number\n /** Subdivisions along a sheet's long edge. */\n segments: number\n /** Draw the cyclorama behind everything. */\n surround: boolean\n /** Soft contact shadow under the scene — its own render pass. */\n contactShadow: boolean\n}\n\nexport const qualityTiers: Record<QualityTier, QualitySettings> = {\n /** Anything with a GPU. */\n high: { dpr: 2, shadowMapSize: 2048, segments: 72, surround: true, contactShadow: true },\n /** The default worth aiming at: an integrated laptop GPU from the last few years. */\n medium: { dpr: 1.5, shadowMapSize: 1024, segments: 48, surround: true, contactShadow: false },\n /**\n * Old integrated graphics, a throttled phone, a software rasterizer. The\n * scene still READS — banners, figure, backlight, walk — it just stops\n * paying for the parts nobody would miss at this framerate.\n */\n low: { dpr: 1, shadowMapSize: 0, segments: 28, surround: true, contactShadow: false },\n}\n\n/** The tier to start `auto` from before anything has been measured. */\nexport const INITIAL_TIER: QualityTier = 'medium'\n\n/**\n * Frames the watcher averages before it will move a tier.\n *\n * The FIRST judgement is deliberately made on far less evidence than the\n * rest. A machine that cannot hold the opening scene should not have to\n * stutter through a hundred frames — several seconds, at the frame rate\n * that is the whole problem — before anything is done about it. After that\n * first correction the window widens, because by then the cost is to be\n * measured carefully rather than reacted to.\n */\nexport const FIRST_WINDOW = 20\nexport const STEADY_WINDOW = 60\n/** Frames ignored after a change, while new programs and shadow maps land. */\nexport const SETTLE_FRAMES = 45\n\nexport const TIER_ORDER: QualityTier[] = ['low', 'medium', 'high']\n\nexport function qualityFor(name: QualityName): QualitySettings {\n return qualityTiers[name === 'auto' ? INITIAL_TIER : name]\n}\n\n/** One step better, or the same tier if already at the top. */\nexport function tierUp(tier: QualityTier): QualityTier {\n return TIER_ORDER[Math.min(TIER_ORDER.indexOf(tier) + 1, TIER_ORDER.length - 1)]!\n}\n\n/** One step worse, or the same tier if already at the bottom. */\nexport function tierDown(tier: QualityTier): QualityTier {\n return TIER_ORDER[Math.max(TIER_ORDER.indexOf(tier) - 1, 0)]!\n}\n","import type { WalkPathOptions } from './path'\n\n/**\n * Named walks. A path is a list of control points, which is the right thing\n * to serialize and the wrong thing to put in front of someone — nobody wants\n * to type coordinates to find out what a curved colonnade looks like. These\n * are the shapes worth starting from; every one resolves to ordinary points,\n * so editing on from here stays possible.\n */\n\nexport const walkNames = ['straight', 'bend', 'ess', 'ring', 'spiral'] as const\nexport type WalkName = (typeof walkNames)[number]\n\nexport const walks: Record<WalkName, WalkPathOptions> = {\n /** Straight down the nave, away from the camera. The reference shot. */\n straight: {\n points: [\n [0, 16],\n [0, -20],\n ],\n closed: false,\n },\n /** One long curve, so the far end of the colonnade stays hidden until you reach it. */\n bend: {\n points: [\n [-2, 16],\n [0, 6],\n [5, -3],\n [12, -10],\n ],\n closed: false,\n },\n /** Two opposed curves — the walk turns twice and the banners turn with it. */\n ess: {\n points: [\n [6, 17],\n [-3, 7],\n [3, -5],\n [-6, -17],\n ],\n closed: false,\n },\n /** A closed loop: the only walk `phase` can slide, and the only endless one. */\n ring: {\n points: [\n [11, 0],\n [0, 11],\n [-11, 0],\n [0, -11],\n ],\n closed: true,\n },\n /** Inward and tightening — the space closes as the figure goes deeper. */\n spiral: {\n points: [\n [14, 2],\n [2, 13],\n [-11, 1],\n [-1, -9],\n [7, -2],\n [1, 4],\n ],\n closed: false,\n },\n}\n\nexport function getWalk(name: WalkName): WalkPathOptions {\n return walks[name]\n}\n","import type { PaperConfigInput } from '../config/schema'\nimport type { StageConfigInput } from './schema'\nimport { walks } from './walks'\n\n/**\n * Named stages. A mode with no presets asks its visitor to invent a space\n * out of eleven sliders before it will show them anything — and stage mode\n * takes about fifteen seconds to understand once you have seen one, which\n * means the presets ARE the explanation.\n *\n * Each names somewhere paper is actually hung at architectural scale, the\n * same rule the layouts follow.\n */\n\nexport interface StagePreset {\n id: string\n label: string\n /** One line, shown under the name. What you are about to look at. */\n description: string\n stage: StageConfigInput\n layout: string\n layoutOptions?: Record<string, unknown>\n /** The paper itself — banners differ per stage more than anything else. */\n paper?: PaperConfigInput\n count: number\n text?: string\n}\n\n/** A banner: tall, translucent, folds running the length of its drop. */\nconst banner = (width: number, height: number, drape: Record<string, unknown> = {}): PaperConfigInput => ({\n sheet: { width, height, segments: 'auto' },\n stock: 'vellum',\n surface: { grain: 0.22 },\n deformers: [\n { type: 'drape', options: { amplitude: 0.16, folds: 3, falloff: 1.7, gather: 0.28, ...drape } },\n ],\n})\n\nexport const stagePresets: Record<string, StagePreset> = {\n nave: {\n id: 'nave',\n label: 'Nave',\n description: 'A straight aisle of hanging banners, lit from the far end.',\n stage: {\n path: walks.straight,\n shot: { shot: 'follow', distance: 5, lookAhead: 12, offset: 1.5 },\n lighting: 'nave',\n },\n layout: 'colonnade',\n layoutOptions: { aisle: 2.6, twist: 22, drape: 0.6, rise: 0.3 },\n paper: banner(1.5, 8.5),\n count: 18,\n text: 'the paper remembers every hand that folded it and every room it was carried through',\n },\n procession: {\n id: 'procession',\n label: 'Procession',\n description: 'The walk turns twice, so the far end stays hidden until you reach it.',\n stage: {\n path: walks.ess,\n shot: { shot: 'low', distance: 4, lookAhead: 9, offset: 1.1 },\n lighting: 'nave',\n figure: { speed: 1.05 },\n },\n layout: 'colonnade',\n layoutOptions: { aisle: 2.2, twist: 34, breathe: 0.45, drape: 0.7 },\n paper: banner(1.3, 9.5, { folds: 4, amplitude: 0.2 }),\n count: 28,\n text: 'every letter you did not send is still folded somewhere in the dark waiting to be read aloud',\n },\n cloister: {\n id: 'cloister',\n label: 'Cloister',\n description: 'A closed loop. The figure walks it forever and the banners drift past.',\n stage: {\n path: walks.ring,\n shot: { shot: 'follow', distance: 4.5, lookAhead: 8, offset: 1.2 },\n lighting: 'nave',\n },\n layout: 'colonnade',\n layoutOptions: { aisle: 2.4, twist: 18, rise: 0.22 },\n paper: banner(1.6, 7.5),\n count: 24,\n text: 'around and around and the same words come back changed',\n },\n threshold: {\n id: 'threshold',\n label: 'Threshold',\n description: 'A few enormous sheets, wide enough apart to walk between and read.',\n stage: {\n // Its own short walk. A colonnade spreads over the WHOLE path whatever\n // it is populating, so ten banners on the default 36-unit walk stand\n // seven apart and the shot looks down an empty corridor.\n path: {\n points: [\n [0, 9],\n [0, -11],\n ],\n closed: false,\n },\n // The aisle has to stay inside the frustum at the distance the shot\n // stands: paper half a frame-width off the walk line is paper you\n // never see. `lead` fails here for the same reason and worse.\n shot: { shot: 'follow', distance: 6.5, lookAhead: 9, offset: 0.9 },\n lighting: 'nave',\n figure: { speed: 0.85 },\n source: { spread: 4 },\n },\n layout: 'colonnade',\n layoutOptions: { aisle: 2.4, twist: 14, breathe: 0.18, margin: 0.12, rise: 0.2 },\n paper: banner(2.6, 10, { folds: 2, amplitude: 0.24, falloff: 2 }),\n count: 10,\n text: 'stand closer and read what it cost to write this down',\n },\n archive: {\n id: 'archive',\n label: 'Archive',\n description: 'Narrow strips packed tight — a corridor of records you edge through.',\n stage: {\n path: walks.bend,\n // Far enough back that the figure reads as small; a `low` camera\n // three units behind a body is all body.\n shot: { shot: 'low', distance: 8, lookAhead: 13, offset: 0.5 },\n lighting: 'nave',\n ground: { color: '#0b0908' },\n },\n layout: 'colonnade',\n layoutOptions: { aisle: 1.7, twist: 44, breathe: 0.5, drape: 0.75, rise: 0.4 },\n paper: banner(0.85, 11, { folds: 2, amplitude: 0.12 }),\n count: 44,\n text: 'catalogued indexed cross referenced filed and never once opened by anyone at all',\n },\n}\n\nexport function getStagePreset(id: string): StagePreset {\n const preset = stagePresets[id]\n if (!preset) {\n throw new Error(\n `[paperlab] Unknown stage preset \"${id}\". Available: ${Object.keys(stagePresets).join(', ')}`,\n )\n }\n return preset\n}\n\nexport function listStagePresets(): string[] {\n return Object.keys(stagePresets)\n}\n","import {\n behaviorConfigSchema,\n clothConfigSchema,\n contentSchema,\n paperConfigSchema,\n sheetSchema,\n type PaperConfig,\n type PaperConfigInput,\n} from './schema'\n\n/**\n * Presets are diffable: exports emit only non-default values, so a shared\n * `.paper` file or JSX snippet reads like intent, not like a database dump.\n */\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v)\n}\n\n/** Keys of `value` that differ from `defaults` (deep compare, shallow recurse). */\nfunction diffAgainst(\n value: Record<string, unknown>,\n defaults: Record<string, unknown>,\n keep: string[] = [],\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [key, v] of Object.entries(value)) {\n if (keep.includes(key)) {\n out[key] = v\n continue\n }\n if (JSON.stringify(v) !== JSON.stringify(defaults[key])) {\n out[key] =\n isPlainObject(v) && isPlainObject(defaults[key])\n ? diffAgainst(v, defaults[key] as Record<string, unknown>)\n : v\n }\n }\n return out\n}\n\n/** The minimal PaperConfigInput that parses back to `config`. */\nexport function diffConfig(config: PaperConfig): PaperConfigInput {\n const base = paperConfigSchema.parse({})\n const out: Record<string, unknown> = {}\n\n const sheet = diffAgainst(config.sheet as never, sheetSchema.parse({}) as never)\n if (Object.keys(sheet).length > 0) out.sheet = sheet\n\n if (config.stock !== base.stock) out.stock = config.stock\n\n if (config.content.type !== 'blank') {\n // Defaults for this content type; required fields (image src) always kept.\n const defaults = contentSchema.parse(\n config.content.type === 'image'\n ? { type: 'image', src: config.content.src }\n : { type: config.content.type },\n ) as Record<string, unknown>\n out.content = {\n type: config.content.type,\n ...diffAgainst(config.content as never, defaults, config.content.type === 'image' ? ['src'] : []),\n }\n }\n\n if (config.behavior) {\n const defaults = behaviorConfigSchema.parse({ type: config.behavior.type }) as Record<string, unknown>\n out.behavior = { type: config.behavior.type, ...diffAgainst(config.behavior as never, defaults) }\n }\n if (config.deformers) out.deformers = config.deformers\n\n if (Object.keys(config.surface).length > 0) out.surface = config.surface\n\n if (typeof config.physics === 'object') {\n const defaults = clothConfigSchema.parse({ type: 'cloth' }) as Record<string, unknown>\n out.physics = { type: 'cloth', ...diffAgainst(config.physics as never, defaults) }\n } else if (config.physics !== 'none') {\n out.physics = config.physics\n }\n\n if (config.scene.lighting !== 'studio') out.scene = { lighting: config.scene.lighting }\n if (config.onTwos) out.onTwos = true\n // States are already diffs on the base — emit them whole.\n if (config.states) out.states = config.states\n const meta = diffAgainst(config.meta as never, paperConfigSchema.parse({}).meta as never)\n if (Object.keys(meta).length > 0) out.meta = meta\n\n return out as PaperConfigInput\n}\n\n/** Render a value as compact JSX-attribute source. */\nfunction jsxValue(value: unknown): string {\n if (typeof value === 'string') return `\"${value}\"`\n return `{${JSON.stringify(value)}}`\n}\n\n/**\n * A plain `<Paper />` snippet with only the non-default props — the\n * secondary export for people who read code.\n */\nexport function buildJsxSnippet(config: PaperConfig): string {\n const diff = diffConfig(config) as Record<string, unknown>\n delete diff.meta\n const props = Object.entries(diff).map(([key, value]) => ` ${key}=${jsxValue(value)}`)\n if (props.length === 0) return '<Paper />'\n return `<Paper\\n${props.join('\\n')}\\n/>`\n}\n","import type { PaperConfig } from './schema'\nimport { getStock } from '../core/stock'\nimport { diffConfig } from './diff'\n\n/**\n * The primary export consumer is a coding agent; the human is the courier.\n * This template IS product surface: versioned, snapshot-tested, regenerated\n * from the config. Anatomy is fixed — install → inlined code → placement\n * contract → a verification step the agent can self-check → pre-empted\n * failure modes.\n */\n/**\n * v2: field exports (multi-preset galleries with inlined preset consts).\n * v3: interaction states, sheet/backing fields, drop zones, carry/flight.\n */\nexport const AGENT_PAYLOAD_VERSION = 3\n\nconst BEHAVIOR_PHRASES: Record<string, (o: Record<string, unknown>) => string> = {\n peel: (o) => `its ${String(o.corner ?? 'bottom-right').replace('-', ' ')} corner peeling up`,\n unroll: (o) =>\n (o.progress as number) < 0.35\n ? 'mostly wound into a roll at the bottom'\n : 'unrolling from a paper roll at the bottom',\n flip: () => 'mid page-turn',\n 'letter-fold': () => 'tri-folding like a letter',\n hang: () => 'hanging from its top edge, rippling',\n fly: () => 'arched and fluttering like it is airborne',\n fall: () => 'rippling with one corner lifted, like a dropped sheet',\n carry: () => 'drooping from a pinched corner, fluttering as if being carried',\n flight: (o) =>\n o.path === 'loop' ? 'tumbling through a seamless airborne loop' : 'tumbling across the scene on the wind',\n crumple: (o) =>\n (o.progress as number) < 0.3\n ? 'lightly handled — a few soft creases across it'\n : (o.progress as number) < 0.7\n ? 'crushed into irregular creased facets, as if screwed up and flattened out again'\n : 'balled up in a fist',\n}\n\n/** One line an agent can verify against what it sees after `npm run dev`. */\nexport function describeConfig(config: PaperConfig): string {\n const stock = getStock(config.stock)\n const size = `${config.sheet.width}×${config.sheet.height}`\n\n let contentPhrase = 'a blank sheet'\n if (config.content.type === 'image') contentPhrase = 'a sheet printed with an image'\n if (config.content.type === 'text') contentPhrase = 'a sheet with typeset text'\n if (config.content.type === 'receipt') contentPhrase = `a store receipt for \"${config.content.store}\"`\n\n const parts = [`${contentPhrase} on ${stock.label.toLowerCase()} paper stock (${size})`]\n\n if (typeof config.physics === 'object') {\n parts.push(\n config.physics.pins === 'none'\n ? 'falling and settling as cloth'\n : `pinned (${config.physics.pins}) and moving like cloth in wind`,\n )\n } else if (config.behavior) {\n const phrase = BEHAVIOR_PHRASES[config.behavior.type]\n if (phrase) parts.push(phrase(config.behavior as Record<string, unknown>))\n }\n\n if (config.surface.deckle) {\n parts.push(\n `torn (deckled) ${config.surface.deckle.edges.join(' and ')} edge${config.surface.deckle.edges.length > 1 ? 's' : ''}`,\n )\n }\n if ((config.surface.aging ?? 0) > 0.3) parts.push('visibly aged and yellowed')\n\n return parts.join(', ')\n}\n\nfunction componentName(config: PaperConfig): string {\n const raw = config.meta.name === 'untitled' ? 'PaperlabPaper' : config.meta.name\n const pascal = raw\n .replace(/[^a-zA-Z0-9]+(.)/g, (_, c: string) => c.toUpperCase())\n .replace(/^./, (c) => c.toUpperCase())\n .replace(/[^a-zA-Z0-9]/g, '')\n return /^[A-Za-z]/.test(pascal) ? pascal : `Paper${pascal}`\n}\n\n/** The self-contained integration brief — one paste into a coding agent. */\nexport function buildAgentPayload(config: PaperConfig): string {\n const name = componentName(config)\n const preset = JSON.stringify(diffConfig(config), null, 2)\n\n return `Integrate a Paperlab paper component into this project. (paperlab agent-payload v${AGENT_PAYLOAD_VERSION})\n\n1. Install the dependencies:\n\n npm i paperlab three @react-three/fiber gsap\n\n2. Create the component below as \\`components/${name}.tsx\\` (or the project's\n component convention). It is self-contained and owns its own <Canvas>:\n\n\\`\\`\\`tsx\nimport { Paper, type PaperConfigInput } from 'paperlab'\n\nconst preset = ${preset.replace(/\\n/g, '\\n')} satisfies PaperConfigInput\n\nexport function ${name}() {\n return <Paper preset={preset} />\n}\n\\`\\`\\`\n\n3. Sizing: the component fills its parent container. Place it where I ask;\n give the parent an explicit height.\n\n4. Verify: run the dev server. You should see ${describeConfig(config)}.\n If the canvas is blank, the parent container almost certainly has no height —\n give it one (this is the classic React Three Fiber integration bug, not a\n paperlab bug).\n\nConstraints: don't modify the preset values; three >= 0.160 and React 19 are\nrequired; the component needs no props.`\n}\n","import { AGENT_PAYLOAD_VERSION } from '../config/agent-payload'\nimport { diffConfig } from '../config/diff'\nimport { paperConfigSchema, type PaperConfigInput } from '../config/schema'\nimport { getLayout } from '../field/layouts'\nimport { stageSchema, type StageConfig, type StageConfigInput } from './schema'\nimport { walkNames, walks } from './walks'\nimport type { WalkName } from './walks'\n\n/**\n * Stage-mode export. Same anatomy and version as the paper and field\n * exports, with one addition that matters more than the rest: the scroll\n * variant. `progress` is the whole interaction model of a stage, and a\n * scroll-driven hero is what most people opening this menu actually want —\n * so the export writes the pinning and the scroll math, which is the part\n * that is fiddly to get right and boring to write.\n */\n\nexport interface StageExportInput {\n stage: StageConfigInput\n layout: string\n layoutOptions?: Record<string, unknown>\n /** The banner itself — dims, stock, drape. Omitted uses the built-in banner. */\n paper?: PaperConfigInput\n /** The words the space is built from. Omitted renders blank banners. */\n text?: string\n count?: number\n /** Bind the walk to page scroll, pinned, rather than to the clock. */\n scroll?: boolean\n /** Exported component name. */\n componentName?: string\n}\n\n/** How many viewport-heights of scroll the walk is spread over. */\nconst SCROLL_HEIGHTS = 4\n\n/** Which named walk these points are, if any — the export reads better for it. */\nexport function walkNameFor(path: StageConfig['path']): WalkName | undefined {\n const key = JSON.stringify({ points: path.points, closed: path.closed })\n return walkNames.find(\n (name) => JSON.stringify({ points: walks[name].points, closed: walks[name].closed }) === key,\n )\n}\n\n/** Deep-strip anything that already equals the schema default. */\nfunction stripDefaults(value: unknown, defaults: unknown): unknown {\n if (Array.isArray(value) || Array.isArray(defaults)) {\n return JSON.stringify(value) === JSON.stringify(defaults) ? undefined : value\n }\n if (value && defaults && typeof value === 'object' && typeof defaults === 'object') {\n const out: Record<string, unknown> = {}\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n const kept = stripDefaults(child, (defaults as Record<string, unknown>)[key])\n if (kept !== undefined) out[key] = kept\n }\n return Object.keys(out).length > 0 ? out : undefined\n }\n return value === defaults ? undefined : value\n}\n\n/** The stage config with defaults removed — what actually needs writing down. */\nexport function diffStage(stage: StageConfigInput): Record<string, unknown> {\n const resolved = stageSchema.parse(stage)\n const defaults = stageSchema.parse({})\n const diff = (stripDefaults(resolved, defaults) as Record<string, unknown>) ?? {}\n // A path is atomic. Field-by-field stripping would export a curved walk's\n // points while dropping `closed: false` for matching the default — which\n // parses correctly today and quietly breaks the moment someone edits those\n // points into a loop. Emit the whole walk or none of it.\n if (diff.path !== undefined) diff.path = resolved.path\n return diff\n}\n\n/**\n * JSON.stringify, except an array of plain numbers stays on one line. A walk\n * is a list of coordinate pairs, and the default pretty-printer spreads each\n * `[6, 17]` over four lines — twenty lines of punctuation for one gentle\n * curve. Exported code is a product surface; it should read like something a\n * person wrote.\n */\nexport function stringifyStage(value: unknown, indent = 0): string {\n const pad = ' '.repeat(indent)\n const inner = ' '.repeat(indent + 1)\n if (Array.isArray(value)) {\n if (value.length === 0) return '[]'\n if (value.every((v) => typeof v === 'number')) return `[${value.join(', ')}]`\n const items = value.map((v) => `${inner}${stringifyStage(v, indent + 1)}`)\n return `[\\n${items.join(',\\n')}\\n${pad}]`\n }\n if (value && typeof value === 'object') {\n const entries = Object.entries(value as Record<string, unknown>)\n if (entries.length === 0) return '{}'\n const items = entries.map(([k, v]) => `${inner}${JSON.stringify(k)}: ${stringifyStage(v, indent + 1)}`)\n return `{\\n${items.join(',\\n')}\\n${pad}}`\n }\n return JSON.stringify(value)\n}\n\nconst SHOT_PHRASES: Record<string, string> = {\n follow: 'from behind and a little above them, looking up the walk',\n lead: 'from in front, walking backward as they come on',\n low: 'from down at floor level, looking up the banners',\n wide: 'from off to one side, level with them',\n}\n\n/** The one-line visual an agent verifies after `npm run dev`. */\nexport function describeStage(input: StageExportInput): string {\n const stage = stageSchema.parse(input.stage)\n const count = input.count ?? 22\n const walk = walkNameFor(stage.path)\n const parts: string[] = []\n\n const shape =\n walk === 'straight' || walk === undefined\n ? 'a straight walk'\n : walk === 'ring'\n ? 'a closed loop of a walk'\n : `an \"${walk}\" walk that curves as it goes`\n parts.push(`${count} tall paper banners standing along ${shape}`)\n\n if (input.text?.trim()) {\n parts.push('each printed with a column of your text running down it')\n }\n if (stage.showFigure) {\n parts.push(`a small dark figure walking between them, seen ${SHOT_PHRASES[stage.shot.shot]}`)\n }\n parts.push(\n stage.lighting === 'nave'\n ? 'the whole space dim and lit from behind, so the paper glows and the far end of the walk is a bright void'\n : `lit with the \"${stage.lighting}\" preset`,\n )\n if (input.scroll) parts.push('and scrolling the page walks the figure deeper into it')\n return parts.join(', ')\n}\n\nfunction propLines(input: StageExportInput, indent: string): string {\n const lines: string[] = []\n if (input.paper) lines.push(`${indent}preset={banner}`)\n if (input.text?.trim()) lines.push(`${indent}text={text}`)\n if (input.count !== undefined) lines.push(`${indent}count={${input.count}}`)\n if (input.layout !== 'colonnade') lines.push(`${indent}layout=\"${input.layout}\"`)\n const layoutOptions = input.layoutOptions ?? {}\n const layoutDefaults = getLayout(input.layout).defaults as Record<string, unknown>\n const changed: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(layoutOptions)) {\n if (JSON.stringify(value) !== JSON.stringify(layoutDefaults[key])) changed[key] = value\n }\n if (Object.keys(changed).length > 0) {\n lines.push(`${indent}layoutOptions={${stringifyStage(changed).replace(/\\n\\s*/g, ' ')}}`)\n }\n lines.push(`${indent}stage={stage}`)\n return lines.join('\\n')\n}\n\n/** Component source shared by the JSX snippet and the agent payload. */\nexport function buildStageComponentSource(input: StageExportInput): string {\n const name = input.componentName ?? 'PaperNave'\n const stage = diffStage(input.stage)\n const stageConst = `const stage = ${stringifyStage(stage)} satisfies StageConfigInput`\n // The banner is inlined for the same reason field presets are: the receiver\n // does not have the sender's preset library.\n const bannerConst = input.paper\n ? `\\n\\nconst banner = ${stringifyStage(diffConfig(paperConfigSchema.parse(input.paper)))} satisfies PaperConfigInput`\n : ''\n const textConst = input.text?.trim() ? `\\n\\nconst text = ${JSON.stringify(input.text)}` : ''\n\n if (!input.scroll) {\n return `import { PaperStage, type StageConfigInput${input.paper ? ', type PaperConfigInput' : ''} } from 'paperlab'\n\n${stageConst}${bannerConst}${textConst}\n\nexport function ${name}() {\n return (\n <PaperStage\n${propLines(input, ' ')}\n />\n )\n}`\n }\n\n return `import { useEffect, useRef, useState } from 'react'\nimport { PaperStage, type StageConfigInput${input.paper ? ', type PaperConfigInput' : ''} } from 'paperlab'\n\n${stageConst}${bannerConst}${textConst}\n\nexport function ${name}() {\n const ref = useRef<HTMLDivElement>(null)\n const [progress, setProgress] = useState(0)\n\n // Scroll the section, walk the figure. The stage is pinned for the height\n // of the section, so the page scrolling past it IS the walk.\n useEffect(() => {\n const el = ref.current\n if (!el) return\n const onScroll = () => {\n const { top, height } = el.getBoundingClientRect()\n const travel = Math.max(height - window.innerHeight, 1)\n setProgress(Math.min(Math.max(-top / travel, 0), 1))\n }\n onScroll()\n window.addEventListener('scroll', onScroll, { passive: true })\n window.addEventListener('resize', onScroll)\n return () => {\n window.removeEventListener('scroll', onScroll)\n window.removeEventListener('resize', onScroll)\n }\n }, [])\n\n return (\n <div ref={ref} style={{ height: '${SCROLL_HEIGHTS * 100}vh' }}>\n <div style={{ position: 'sticky', top: 0, height: '100vh' }}>\n <PaperStage\n${propLines(input, ' ')}\n progress={progress}\n />\n </div>\n </div>\n )\n}`\n}\n\n/** The self-contained stage integration brief — one paste into a coding agent. */\nexport function buildStageAgentPayload(input: StageExportInput): string {\n const name = input.componentName ?? 'PaperNave'\n const sizing = input.scroll\n ? `4. Sizing: the component brings its own height — it reserves ${SCROLL_HEIGHTS} viewport\n heights of scroll and pins the canvas inside that. Drop it into the page\n flow as a section; do NOT wrap it in a fixed-height container.`\n : `4. Sizing: the component fills its parent container. Place it where I ask;\n give the parent an explicit height.`\n\n return `Integrate a Paperlab stage — paper as architecture, with a figure walking through it — into this project. (paperlab agent-payload v${AGENT_PAYLOAD_VERSION})\n\n1. Install the dependencies:\n\n npm i paperlab three @react-three/fiber gsap\n\n2. Create the component below as \\`components/${name}.tsx\\` (or the project's\n component convention). It is self-contained — it owns its own <Canvas>,\n its own camera and its own lighting:\n\n\\`\\`\\`tsx\n${buildStageComponentSource(input)}\n\\`\\`\\`\n\n3. Placement: this is a full-bleed scene, not an inline element. Give it the\n full width of the viewport.\n\n${sizing}\n\n5. Verify: run the dev server. You should see ${describeStage(input)}.\n If the canvas is blank, the container almost certainly has no height — give\n it one (this is the classic React Three Fiber integration bug, not a\n paperlab bug).\n\nConstraints: don't modify the stage values; the camera is driven by the\nstage's own shot, so don't add OrbitControls; three >= 0.160 and React 19 are\nrequired; the component needs no props.`\n}\n","import * as THREE from 'three'\nimport type { DeformerInstance, SheetDims } from '../deformers/types'\nimport { displacePoint } from '../deformers/compose'\nimport { getDeformer } from '../deformers/registry'\nimport { buildDisplacementGLSL } from './compose'\n\n/**\n * Golden-vector parity: the JS (hero) and GLSL (field) implementations of a\n * deformer must produce identical displacements. This harness evaluates the\n * GLSL path on the real GPU — the stack's displacement functions run in a\n * fragment shader over an N×N grid, rendered to a float target and read\n * back — then epsilon-compares against the JS path. Browser-only (WebGL2);\n * driven by tools/parity.mjs in CI.\n */\n\nconst GRID = 48\n/** highp float + sin/cos implementation differences across GPUs. */\nexport const PARITY_EPSILON = 5e-4\n\nexport interface ParityCase {\n name: string\n stack: DeformerInstance[]\n sheet: SheetDims\n t: number\n}\n\nexport interface ParityResult {\n name: string\n maxError: number\n pass: boolean\n}\n\n/** One case per deformer feature worth guarding, both easy and adversarial. */\nexport const parityCases: ParityCase[] = [\n {\n name: 'roll: defaults',\n stack: [{ type: 'roll', options: { angle: 90, boundary: 0, radius: 0.12, spiral: 0.015 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'roll: tight receipt roll, rolling down',\n stack: [{ type: 'roll', options: { angle: 270, boundary: -0.4, radius: 0.07, spiral: 0.02 } }],\n sheet: { width: 1, height: 2.6 },\n t: 0,\n },\n {\n name: 'curl: bottom-right peel',\n stack: [{ type: 'curl', options: { corner: 'bottom-right', amount: 0.45, radius: 0.2, skew: 0 } }],\n sheet: { width: 1.5, height: 1 },\n t: 0,\n },\n {\n name: 'curl: skewed top-left',\n stack: [{ type: 'curl', options: { corner: 'top-left', amount: 0.7, radius: 0.3, skew: 15 } }],\n sheet: { width: 1, height: 1 },\n t: 0,\n },\n {\n name: 'bend: positive arc at an angle',\n stack: [{ type: 'bend', options: { curvature: 1.2, angle: 33 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n /**\n * The gentle end, which nothing used to cover: the gate only ever tried\n * |curvature| ≥ 0.6, and `photo-print` — the field starter preset — bends\n * at 0.35. That band is where the arc's float32 evaluation loses its\n * cancellation, and where the two paths were 6e-4 apart until `bend` was\n * rewritten in cancellation-free form. Keep a case down here.\n */\n name: 'bend: barely-there arc (the band photo-print lives in)',\n stack: [{ type: 'bend', options: { curvature: 0.35, angle: 0 } }],\n sheet: { width: 1.2, height: 0.9 },\n t: 0,\n },\n {\n name: 'bend: the gentlest arc the schema allows',\n stack: [{ type: 'bend', options: { curvature: 0.02, angle: 61 } }],\n sheet: { width: 2, height: 2.6 },\n t: 0,\n },\n {\n name: 'bend: negative arc',\n stack: [{ type: 'bend', options: { curvature: -0.8, angle: 0 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'fold: 90° hinge',\n stack: [{ type: 'fold', options: { angle: 90, offset: 0, foldAngle: 90, radius: 0.06 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'fold: deep fold, travelling down',\n stack: [{ type: 'fold', options: { angle: 270, offset: 0.2, foldAngle: 165, radius: 0.04 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'wave: free ripple at t=1.234',\n stack: [\n {\n type: 'wave',\n options: { amplitude: 0.05, wavelength: 0.5, speed: 1, angle: 20, pinnedEdge: 'none' },\n },\n ],\n sheet: { width: 1, height: 1 },\n t: 1.234,\n },\n {\n name: 'wave: pinned top at t=2.5',\n stack: [\n {\n type: 'wave',\n options: { amplitude: 0.04, wavelength: 0.4, speed: 1.5, angle: 80, pinnedEdge: 'top' },\n },\n ],\n sheet: { width: 1.2, height: 1.5 },\n t: 2.5,\n },\n {\n name: 'drape: banner hung from the top',\n stack: [\n {\n type: 'drape',\n options: { amplitude: 0.17, folds: 5, falloff: 1.6, irregular: 0.45, gather: 0.5, pinnedEdge: 'top' },\n },\n ],\n sheet: { width: 1.5, height: 8.5 },\n t: 0,\n },\n {\n name: 'drape: deep irregular folds pinned at the bottom',\n stack: [\n {\n type: 'drape',\n options: { amplitude: 0.55, folds: 11, falloff: 0.4, irregular: 1, gather: 1, pinnedEdge: 'bottom' },\n },\n ],\n sheet: { width: 2.2, height: 3 },\n t: 0,\n },\n {\n name: 'crumple: defaults',\n stack: [{ type: 'crumple', options: { amount: 0.35, scale: 3, pull: 0.4, seed: 0 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n // The adversarial one. `fract` is a sawtooth, so the two halves disagree\n // hardest where a crease lands exactly on a sample — a fine scale and a\n // seed whose fold directions are near-axis puts the most creases in\n // reach of the grid.\n name: 'crumple: fully crushed, fine creases, off-axis seed',\n stack: [{ type: 'crumple', options: { amount: 1, scale: 7.5, pull: 1, seed: 5 } }],\n sheet: { width: 1.3, height: 0.9 },\n t: 0,\n },\n {\n // Crush then curl, which is the order the crumple BEHAVIOR stacks them:\n // the creases have to be placed on the flat sheet, not on a bent one.\n name: 'stacked: crumple ∘ bend (the crumple behavior)',\n stack: [\n { type: 'crumple', options: { amount: 0.62, scale: 3.3, pull: 0.5, seed: 2 } },\n { type: 'bend', options: { curvature: 0.31, angle: 35 } },\n ],\n sheet: { width: 1.1, height: 1.4 },\n t: 0,\n },\n {\n name: 'stacked: letter-fold pair (fold ∘ fold)',\n stack: [\n { type: 'fold', options: { angle: 270, offset: 0.2333, foldAngle: 120, radius: 0.05 } },\n { type: 'fold', options: { angle: 90, offset: 0.2333, foldAngle: 100, radius: 0.08 } },\n ],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'stacked: bend ∘ roll ∘ wave',\n stack: [\n { type: 'bend', options: { curvature: 0.6, angle: 0 } },\n { type: 'roll', options: { angle: 90, boundary: 0.1, radius: 0.15, spiral: 0 } },\n {\n type: 'wave',\n options: { amplitude: 0.02, wavelength: 0.6, speed: 0.7, angle: 45, pinnedEdge: 'none' },\n },\n ],\n sheet: { width: 1, height: 1.4 },\n t: 0.8,\n },\n]\n\nfunction buildParityFragment(stack: DeformerInstance[], sheet: SheetDims): string {\n const composed = buildDisplacementGLSL(stack, sheet)\n return /* glsl */ `#version 300 es\nprecision highp float;\nuniform float uPlTime;\nuniform float uPlBias;\n${composed.functionsSrc}\n${composed.displaceSrc}\nout vec4 outColor;\nvoid main() {\n vec2 uv = (gl_FragCoord.xy - 0.5) / float(${GRID - 1});\n vec3 p = vec3((uv - 0.5) * uSheet, 0.0);\n outColor = vec4(plDisplace(p, uv, uPlTime, uPlBias), 1.0);\n}\n`\n}\n\nconst VERT = `#version 300 es\nin vec2 aPos;\nvoid main() { gl_Position = vec4(aPos, 0.0, 1.0); }\n`\n\nfunction compile(gl: WebGL2RenderingContext, type: number, src: string): WebGLShader {\n const shader = gl.createShader(type)!\n gl.shaderSource(shader, src)\n gl.compileShader(shader)\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n throw new Error(`[paperlab parity] shader compile failed: ${gl.getShaderInfoLog(shader)}`)\n }\n return shader\n}\n\nfunction runCaseOnGPU(gl: WebGL2RenderingContext, c: ParityCase, bias = 1): Float32Array {\n const composed = buildDisplacementGLSL(c.stack, c.sheet)\n const program = gl.createProgram()!\n gl.attachShader(program, compile(gl, gl.VERTEX_SHADER, VERT))\n gl.attachShader(program, compile(gl, gl.FRAGMENT_SHADER, buildParityFragment(c.stack, c.sheet)))\n gl.linkProgram(program)\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error(`[paperlab parity] link failed: ${gl.getProgramInfoLog(program)}`)\n }\n // biome-ignore lint/correctness/useHookAtTopLevel: WebGL's gl.useProgram, not a React hook\n gl.useProgram(program)\n\n for (const [name, value] of Object.entries(composed.uniforms)) {\n const loc = gl.getUniformLocation(program, name)\n if (!loc) continue\n if (typeof value === 'number') gl.uniform1f(loc, value)\n else if (value.length === 2) gl.uniform2f(loc, value[0]!, value[1]!)\n else if (value.length === 3) gl.uniform3f(loc, value[0]!, value[1]!, value[2]!)\n else gl.uniform4f(loc, value[0]!, value[1]!, value[2]!, value[3]!)\n }\n const timeLoc = gl.getUniformLocation(program, 'uPlTime')\n if (timeLoc) gl.uniform1f(timeLoc, c.t)\n const biasLoc = gl.getUniformLocation(program, 'uPlBias')\n if (biasLoc) gl.uniform1f(biasLoc, bias)\n\n const quad = gl.createBuffer()!\n gl.bindBuffer(gl.ARRAY_BUFFER, quad)\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), gl.STATIC_DRAW)\n const posLoc = gl.getAttribLocation(program, 'aPos')\n gl.enableVertexAttribArray(posLoc)\n gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0)\n\n const tex = gl.createTexture()!\n gl.bindTexture(gl.TEXTURE_2D, tex)\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, GRID, GRID, 0, gl.RGBA, gl.FLOAT, null)\n const fbo = gl.createFramebuffer()!\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)\n gl.viewport(0, 0, GRID, GRID)\n gl.drawArrays(gl.TRIANGLES, 0, 3)\n\n const out = new Float32Array(GRID * GRID * 4)\n gl.readPixels(0, 0, GRID, GRID, gl.RGBA, gl.FLOAT, out)\n gl.bindFramebuffer(gl.FRAMEBUFFER, null)\n return out\n}\n\n/**\n * The bias contract, checked on the GPU: a stack of strength-bearing\n * deformers must go completely flat at bias 0, and a stack of deformers that\n * opt out (roll) must ignore bias entirely. Parity alone can't catch this —\n * it only ever evaluates bias 1.\n */\nfunction runBiasCases(gl: WebGL2RenderingContext): ParityResult[] {\n const results: ParityResult[] = []\n for (const c of parityCases) {\n const strengths = c.stack.map((i) => getDeformer(i.type).glsl?.strength !== undefined)\n // Mixed stacks flatten only partway — nothing crisp to assert.\n if (!strengths.every((h) => h === strengths[0])) continue\n const scales = strengths[0]\n\n const at0 = runCaseOnGPU(gl, c, 0)\n const reference = scales ? null : runCaseOnGPU(gl, c, 1)\n let maxError = 0\n for (let row = 0; row < GRID; row++) {\n for (let col = 0; col < GRID; col++) {\n const i4 = (row * GRID + col) * 4\n // At bias 0 a scaling stack collapses onto the flat sheet; an opted-out\n // stack must land exactly where bias 1 put it.\n const ex = reference ? reference[i4]! : (col / (GRID - 1) - 0.5) * c.sheet.width\n const ey = reference ? reference[i4 + 1]! : (row / (GRID - 1) - 0.5) * c.sheet.height\n const ez = reference ? reference[i4 + 2]! : 0\n maxError = Math.max(\n maxError,\n Math.abs(at0[i4]! - ex),\n Math.abs(at0[i4 + 1]! - ey),\n Math.abs(at0[i4 + 2]! - ez),\n )\n }\n }\n results.push({\n name: `bias: ${c.name} → ${scales ? 'flat at 0' : 'ignores bias'}`,\n maxError,\n pass: maxError < PARITY_EPSILON,\n })\n }\n return results\n}\n\n/** Run every parity case. Requires a WebGL2 context with float render targets. */\nexport function runParityHarness(canvas?: HTMLCanvasElement): ParityResult[] {\n const cnv = canvas ?? document.createElement('canvas')\n const gl = cnv.getContext('webgl2')\n if (!gl) throw new Error('[paperlab parity] WebGL2 unavailable')\n if (!gl.getExtension('EXT_color_buffer_float')) {\n throw new Error('[paperlab parity] EXT_color_buffer_float unavailable')\n }\n\n const point = new THREE.Vector3()\n const parity = parityCases.map((c) => {\n const gpu = runCaseOnGPU(gl, c)\n let maxError = 0\n for (let row = 0; row < GRID; row++) {\n for (let col = 0; col < GRID; col++) {\n const u = col / (GRID - 1)\n const v = row / (GRID - 1)\n point.set((u - 0.5) * c.sheet.width, (v - 0.5) * c.sheet.height, 0)\n displacePoint(point, u, v, c.stack, { t: c.t, sheet: c.sheet })\n const i4 = (row * GRID + col) * 4\n maxError = Math.max(\n maxError,\n Math.abs(gpu[i4]! - point.x),\n Math.abs(gpu[i4 + 1]! - point.y),\n Math.abs(gpu[i4 + 2]! - point.z),\n )\n }\n }\n return { name: c.name, maxError, pass: maxError < PARITY_EPSILON }\n })\n return [...parity, ...runBiasCases(gl)]\n}\n","import type { ContentConfig, PaperConfig, PaperStatesInput } from './schema'\nimport { diffConfig } from './diff'\nimport { AGENT_PAYLOAD_VERSION } from './agent-payload'\nimport { getLayout } from '../field/layouts'\n\n/**\n * Field-mode export. Every preset a field references is INLINED as a const —\n * receivers don't have the sender's local preset library. Same fixed payload\n * anatomy as the single-paper export, same version.\n */\n\nexport interface FieldExportPaper {\n /** Display name of the preset this slot uses (const naming + description). */\n presetName: string\n /** The RESOLVED preset config (user presets included — nothing to fetch). */\n preset: PaperConfig\n content?: ContentConfig\n /** Per-slot state overrides (slot 3's hover deeper than slot 4's). */\n states?: PaperStatesInput\n}\n\nexport interface FieldExportZone {\n id: string\n accept?: string[]\n bounds: { position: [number, number, number]; size: [number, number] }\n highlight?: 'none' | 'glow' | 'outline'\n}\n\nexport interface FieldExportInput {\n layout: string\n layoutOptions?: Record<string, unknown>\n motion?: { driver?: 'autoplay' | 'drag' | 'none'; speed?: number }\n entrance?: { type?: 'rise' | 'scatter' | 'none'; stagger?: number; duration?: number }\n papers: FieldExportPaper[]\n /** Drop zones — exported as `<DropZone>` children with an onPlace stub. */\n zones?: FieldExportZone[]\n}\n\nconst MOTION_DEFAULTS = { driver: 'autoplay', speed: 0.5 }\nconst ENTRANCE_DEFAULTS = { type: 'rise', stagger: 0.06, duration: 0.9 }\n\nfunction camel(name: string): string {\n const id = name.replace(/[^a-zA-Z0-9]+(.)/g, (_, c: string) => c.toUpperCase()).replace(/[^a-zA-Z0-9]/g, '')\n const safe = /^[A-Za-z]/.test(id) ? id : `preset${id}`\n return safe.charAt(0).toLowerCase() + safe.slice(1)\n}\n\ninterface DistinctPreset {\n varName: string\n presetName: string\n preset: PaperConfig\n}\n\n/** Distinct presets in slot order, with collision-safe const names. */\nexport function distinctFieldPresets(input: FieldExportInput): DistinctPreset[] {\n const byKey = new Map<string, DistinctPreset>()\n const usedNames = new Set<string>()\n for (const paper of input.papers) {\n const key = JSON.stringify(paper.preset)\n if (byKey.has(key)) continue\n let varName = camel(paper.presetName)\n while (usedNames.has(varName)) varName += '2'\n usedNames.add(varName)\n byKey.set(key, { varName, presetName: paper.presetName, preset: paper.preset })\n }\n return [...byKey.values()]\n}\n\nfunction nonDefault<T extends Record<string, unknown>>(\n value: T | undefined,\n defaults: Record<string, unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value ?? {})) {\n if (v !== undefined && v !== defaults[k]) out[k] = v\n }\n return out\n}\n\n/** The layout/motion/entrance props of the export, defaults stripped. */\nexport function diffFieldProps(input: FieldExportInput): Record<string, unknown> {\n const out: Record<string, unknown> = { layout: input.layout }\n const layout = getLayout(input.layout)\n const layoutOptions = nonDefault(input.layoutOptions ?? {}, layout.defaults as Record<string, unknown>)\n if (Object.keys(layoutOptions).length > 0) out.layoutOptions = layoutOptions\n const motion = nonDefault(input.motion, MOTION_DEFAULTS)\n if (Object.keys(motion).length > 0) out.motion = motion\n const entrance = nonDefault(input.entrance, ENTRANCE_DEFAULTS)\n if (Object.keys(entrance).length > 0) out.entrance = entrance\n return out\n}\n\nconst LAYOUT_PHRASES: Record<string, string> = {\n ring: 'a ring you can see around',\n fan: 'a fanned swatch deck hinged at one corner',\n spread: 'a stack slid sideways, each sheet bowing further than the last',\n pile: 'a heap on a desk, the sheets underneath pressed flat',\n wall: 'a pinned studio wall of sheets, none hanging quite square',\n spill: 'a dropped stack caught mid-air, each sheet bent its own way',\n sweep: 'a specimen chart of one sheet at every stage of its deformation',\n book: 'an open book, its pages splayed from a shared spine',\n accordion: 'one continuous strip folded into a concertina',\n rack: 'prints stood in a row and leaning back against a wall',\n sheet: 'a stamp-block grid on a shared backing sheet',\n}\n\n/** The one-line visual an agent verifies after `npm run dev`. */\nexport function describeFieldConfig(input: FieldExportInput): string {\n const n = input.papers.length\n const stateful = input.papers.some((p) => p.preset.states || p.states)\n const zones = input.zones ?? []\n const parts: string[] = []\n\n if (input.layout === 'sheet') {\n const rows = Number(input.layoutOptions?.rows ?? 2)\n const columns = Number(input.layoutOptions?.columns ?? 5)\n parts.push(`a ${rows}×${columns} sheet of papers on a shared backing`)\n } else {\n const layoutPhrase = LAYOUT_PHRASES[input.layout] ?? `a ${input.layout} layout`\n parts.push(`${n} papers arranged in ${layoutPhrase}`)\n }\n\n const driver = input.motion?.driver ?? 'autoplay'\n if (stateful) {\n // Stateful fields render static and interactive — the motion driver is moot.\n parts.push('hovering peels/reacts per paper (interaction states)')\n if (zones.length > 0) {\n parts.push(\n `dragging one past its tear threshold detaches it to carry to the ${zones\n .map((z) => z.id)\n .join(' or ')} zone (release elsewhere flutters it back)`,\n )\n }\n } else {\n if (driver === 'autoplay') parts.push('slowly orbiting on their own')\n if (driver === 'drag') parts.push('draggable sideways with the pointer')\n if (zones.length > 0) parts.push(`${zones.length} drop zone${zones.length > 1 ? 's' : ''}`)\n }\n\n const distinct = distinctFieldPresets(input)\n if (distinct.length > 1) {\n parts.push(`mixing ${distinct.length} paper presets (${distinct.map((d) => d.presetName).join(', ')})`)\n }\n return parts.join(', ')\n}\n\n/** Component source shared by the JSX snippet and the agent payload. */\nexport function buildFieldComponentSource(input: FieldExportInput): string {\n const distinct = distinctFieldPresets(input)\n const varByKey = new Map(distinct.map((d) => [JSON.stringify(d.preset), d.varName]))\n\n // `satisfies` (not `as const`) — const-asserted arrays turn readonly and\n // stop matching the library's input types.\n const consts = distinct\n .map(\n (d) =>\n `const ${d.varName} = ${JSON.stringify(diffConfig(d.preset), null, 2)} satisfies PaperConfigInput`,\n )\n .join('\\n\\n')\n\n const slots = input.papers\n .map((paper) => {\n const varName = varByKey.get(JSON.stringify(paper.preset))!\n const content = paper.content ? `, content: ${JSON.stringify(paper.content)}` : ''\n const states = paper.states ? `, states: ${JSON.stringify(paper.states)}` : ''\n return ` { preset: ${varName}${content}${states} },`\n })\n .join('\\n')\n\n const props = Object.entries(diffFieldProps(input))\n .map(([key, value]) =>\n typeof value === 'string' ? ` ${key}=\"${value}\"` : ` ${key}={${JSON.stringify(value)}}`,\n )\n .join('\\n')\n\n const zones = input.zones ?? []\n const zoneImport = zones.length > 0 ? ', DropZone' : ''\n const zoneChildren = zones\n .map((zone) => {\n const accept = zone.accept ? ` accept={${JSON.stringify(zone.accept)}}` : ''\n const highlight = zone.highlight && zone.highlight !== 'glow' ? ` highlight=\"${zone.highlight}\"` : ''\n return ` <DropZone\n id=\"${zone.id}\"${accept}\n bounds={${JSON.stringify(zone.bounds)}}${highlight}\n onPlace={(paper, zone) => {\n // First-run smoke test — you should see this in the console on drop:\n console.log(paper.presetName, '→', zone.id)\n // Then replace it: stamp a postmark, advance the flow, persist the placement, …\n }}\n />`\n })\n .join('\\n')\n\n if (zones.length === 0) {\n return `import { PaperField, type FieldPaperSlot, type PaperConfigInput${zoneImport} } from 'paperlab'\n\n${consts}\n\nconst papers: FieldPaperSlot[] = [\n${slots}\n]\n\nexport function PaperGallery() {\n return (\n <PaperField\n papers={papers}\n${props}\n />\n )\n}`\n }\n\n return `import { PaperField, type FieldPaperSlot, type PaperConfigInput${zoneImport} } from 'paperlab'\n\n${consts}\n\nconst papers: FieldPaperSlot[] = [\n${slots}\n]\n\nexport function PaperGallery() {\n return (\n <PaperField\n papers={papers}\n${props}\n >\n${zoneChildren}\n </PaperField>\n )\n}`\n}\n\n/** The self-contained field integration brief — one paste into a coding agent. */\nexport function buildFieldAgentPayload(input: FieldExportInput): string {\n return `Integrate a Paperlab paper gallery into this project. (paperlab agent-payload v${AGENT_PAYLOAD_VERSION})\n\n1. Install the dependencies:\n\n npm i paperlab three @react-three/fiber gsap\n\n2. Create the component below as \\`components/PaperGallery.tsx\\` (or the\n project's component convention). It is self-contained — every preset it\n uses is inlined, and it owns its own <Canvas>:\n\n\\`\\`\\`tsx\n${buildFieldComponentSource(input)}\n\\`\\`\\`\n\n3. Sizing: the component fills its parent container. Place it where I ask;\n give the parent an explicit height.\n\n4. Verify: run the dev server. You should see ${describeFieldConfig(input)}.\n If the canvas is blank, the parent container almost certainly has no height —\n give it one (this is the classic React Three Fiber integration bug, not a\n paperlab bug).\n\nConstraints: don't modify the preset values; three >= 0.160 and React 19 are\nrequired; the component needs no props.`\n}\n","export type PaperMode = 'hero' | 'field'\nexport type PaperModeRequest = PaperMode | 'auto'\n\nexport interface ModeContext {\n interactive: boolean\n physics: string\n count: number\n}\n\n/**\n * Hero mode: deformer stack runs in JS on the CPU, writing BufferGeometry\n * positions (correct raycasting, shadows, physics, handle drags).\n * Field mode: composed GLSL vertex chunks, instanced (galleries, 10+ sheets).\n * The same preset JSON drives both.\n */\nexport function resolveMode(requested: PaperModeRequest, ctx: ModeContext): PaperMode {\n if (requested !== 'auto') return requested\n if (ctx.interactive || ctx.physics !== 'none' || ctx.count <= 10) return 'hero'\n return 'field'\n}\n"],"mappings":"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","names":["forwardRef","useMemo","THREE","gsap","useEffect","useMemo","useRef","z","z","z","sheet","z","sheet","z","sheet","z","sheet","z","z","z","z","z","z","z","z","z","sheet","THREE","sheet","THREE","z","z","DEG","z","DEG","z","DEG","z","DEG","z","TAU","fold","z","z","registry","z","gust","THREE","useEffect","THREE","THREE","z","sheet","sheet","useEffect","useEffect","useState","jsx","useState","useEffect","useEffect","useMemo","useState","useMemo","useState","useEffect","jsx","PaperMesh","useMemo","useRef","useEffect","gsap","THREE","useEffect","useMemo","useRef","useFrame","useThree","jsx","jsxs","useThree","useEffect","useMemo","useRef","useFrame","jsx","jsxs","forwardRef","Paper","useMemo","THREE","gsap","Canvas","useFrame","useThree","forwardRef","useEffect","useMemo","useRef","THREE","useEffect","useMemo","jsx","jsxs","registry","z","THREE","gsap","useFrame","useEffect","useMemo","useRef","CustomShaderMaterial","THREE","useEffect","useState","sheet","useState","useEffect","sheet","z","z","TAU","DEG","jitter","z","sheet","registry","jsx","useRef","useMemo","useEffect","gsap","useFrame","CustomShaderMaterial","THREE","useEffect","useMemo","jsx","jsxs","useMemo","useEffect","THREE","gsap","useFrame","useThree","useContext","useEffect","useMemo","useRef","useState","jsx","jsxs","useContext","registry","useMemo","useThree","useState","useRef","gsap","hit","z","useEffect","useFrame","useState","jsx","jsxs","carry","useState","sheet","DEG","jsx","jsxs","forwardRef","PaperFieldMesh","useMemo","useRef","useThree","useEffect","gsap","useFrame","sheet","PaperField","registry","Canvas","THREE","Canvas","useFrame","useThree","useEffect","useMemo","useRef","useState","z","z","THREE","useEffect","useMemo","useRef","useFrame","z","TAU","jsx","jsxs","useMemo","useRef","useEffect","useFrame","THREE","useEffect","useMemo","jsx","jsxs","z","z","Fragment","jsx","jsxs","useThree","useMemo","useFrame","useRef","window","useState","useEffect","sheet","z","Canvas","drape","sheet","THREE","sheet","z"]}
|
|
1
|
+
{"version":3,"sources":["../src/Paper.tsx","../src/field/parity.ts","../src/config/field-export.ts","../src/core/modes.ts"],"sourcesContent":["import { Canvas } from '@react-three/fiber'\nimport { forwardRef, useMemo } from 'react'\nimport { PaperMesh, useResolvedConfig, type PaperHandle, type PaperMeshProps } from './PaperMesh'\nimport { PaperFallback, PaperMirror, supportsWebGL } from './a11y'\nimport { PaperLighting } from './scene/PaperLighting'\n\nexport interface PaperProps extends PaperMeshProps {\n /** Extra children rendered inside the canvas (lights are provided). */\n children?: React.ReactNode\n className?: string\n style?: React.CSSProperties\n}\n\n/**\n * `<Paper />` owns its own `<Canvas>` and fills its parent container —\n * the parent must have a height. Use `<PaperMesh />` inside an existing\n * R3F scene instead.\n *\n * Ships with its accessibility layer: a hidden DOM mirror of the content,\n * `prefers-reduced-motion` support, and a flat DOM fallback when WebGL is\n * unavailable.\n */\nexport const Paper = forwardRef<PaperHandle, PaperProps>(function Paper(\n { children, className, style, ...meshProps },\n ref,\n) {\n // Keyed on every prop resolveConfig reads — a content/stock/behavior change\n // must refresh the fallback, mirror, and lighting, not just the mesh.\n const config = useResolvedConfig(meshProps)\n const webgl = useMemo(() => (typeof window === 'undefined' ? true : supportsWebGL()), [])\n\n return (\n <div className={className} style={{ width: '100%', height: '100%', ...style }}>\n {webgl ? (\n <Canvas shadows camera={{ position: [0, 0.35, 2.4], fov: 40 }} dpr={[1, 2]}>\n <PaperLighting\n preset={config.scene.lighting}\n floor={-1.05}\n scale={8}\n reducedMotion={meshProps.reducedMotion}\n />\n <PaperMesh ref={ref} {...meshProps} />\n {children}\n </Canvas>\n ) : (\n <PaperFallback config={config} />\n )}\n <PaperMirror config={config} />\n </div>\n )\n})\n","import * as THREE from 'three'\nimport type { DeformerInstance, SheetDims } from '../deformers/types'\nimport { displacePoint } from '../deformers/compose'\nimport { getDeformer } from '../deformers/registry'\nimport { buildDisplacementGLSL } from './compose'\n\n/**\n * Golden-vector parity: the JS (hero) and GLSL (field) implementations of a\n * deformer must produce identical displacements. This harness evaluates the\n * GLSL path on the real GPU — the stack's displacement functions run in a\n * fragment shader over an N×N grid, rendered to a float target and read\n * back — then epsilon-compares against the JS path. Browser-only (WebGL2);\n * driven by tools/parity.mjs in CI.\n */\n\nconst GRID = 48\n/** highp float + sin/cos implementation differences across GPUs. */\nexport const PARITY_EPSILON = 5e-4\n\nexport interface ParityCase {\n name: string\n stack: DeformerInstance[]\n sheet: SheetDims\n t: number\n}\n\nexport interface ParityResult {\n name: string\n maxError: number\n pass: boolean\n}\n\n/** One case per deformer feature worth guarding, both easy and adversarial. */\nexport const parityCases: ParityCase[] = [\n {\n name: 'roll: defaults',\n stack: [{ type: 'roll', options: { angle: 90, boundary: 0, radius: 0.12, spiral: 0.015 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'roll: tight receipt roll, rolling down',\n stack: [{ type: 'roll', options: { angle: 270, boundary: -0.4, radius: 0.07, spiral: 0.02 } }],\n sheet: { width: 1, height: 2.6 },\n t: 0,\n },\n {\n name: 'curl: bottom-right peel',\n stack: [{ type: 'curl', options: { corner: 'bottom-right', amount: 0.45, radius: 0.2, skew: 0 } }],\n sheet: { width: 1.5, height: 1 },\n t: 0,\n },\n {\n name: 'curl: skewed top-left',\n stack: [{ type: 'curl', options: { corner: 'top-left', amount: 0.7, radius: 0.3, skew: 15 } }],\n sheet: { width: 1, height: 1 },\n t: 0,\n },\n {\n name: 'bend: positive arc at an angle',\n stack: [{ type: 'bend', options: { curvature: 1.2, angle: 33 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n /**\n * The gentle end, which nothing used to cover: the gate only ever tried\n * |curvature| ≥ 0.6, and `photo-print` — the field starter preset — bends\n * at 0.35. That band is where the arc's float32 evaluation loses its\n * cancellation, and where the two paths were 6e-4 apart until `bend` was\n * rewritten in cancellation-free form. Keep a case down here.\n */\n name: 'bend: barely-there arc (the band photo-print lives in)',\n stack: [{ type: 'bend', options: { curvature: 0.35, angle: 0 } }],\n sheet: { width: 1.2, height: 0.9 },\n t: 0,\n },\n {\n name: 'bend: the gentlest arc the schema allows',\n stack: [{ type: 'bend', options: { curvature: 0.02, angle: 61 } }],\n sheet: { width: 2, height: 2.6 },\n t: 0,\n },\n {\n name: 'bend: negative arc',\n stack: [{ type: 'bend', options: { curvature: -0.8, angle: 0 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'fold: 90° hinge',\n stack: [{ type: 'fold', options: { angle: 90, offset: 0, foldAngle: 90, radius: 0.06 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'fold: deep fold, travelling down',\n stack: [{ type: 'fold', options: { angle: 270, offset: 0.2, foldAngle: 165, radius: 0.04 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'wave: free ripple at t=1.234',\n stack: [\n {\n type: 'wave',\n options: { amplitude: 0.05, wavelength: 0.5, speed: 1, angle: 20, pinnedEdge: 'none' },\n },\n ],\n sheet: { width: 1, height: 1 },\n t: 1.234,\n },\n {\n name: 'wave: pinned top at t=2.5',\n stack: [\n {\n type: 'wave',\n options: { amplitude: 0.04, wavelength: 0.4, speed: 1.5, angle: 80, pinnedEdge: 'top' },\n },\n ],\n sheet: { width: 1.2, height: 1.5 },\n t: 2.5,\n },\n {\n name: 'drape: banner hung from the top',\n stack: [\n {\n type: 'drape',\n options: { amplitude: 0.17, folds: 5, falloff: 1.6, irregular: 0.45, gather: 0.5, pinnedEdge: 'top' },\n },\n ],\n sheet: { width: 1.5, height: 8.5 },\n t: 0,\n },\n {\n name: 'drape: deep irregular folds pinned at the bottom',\n stack: [\n {\n type: 'drape',\n options: { amplitude: 0.55, folds: 11, falloff: 0.4, irregular: 1, gather: 1, pinnedEdge: 'bottom' },\n },\n ],\n sheet: { width: 2.2, height: 3 },\n t: 0,\n },\n {\n name: 'crumple: defaults',\n stack: [{ type: 'crumple', options: { amount: 0.35, scale: 3, pull: 0.4, seed: 0 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n // The adversarial one. `fract` is a sawtooth, so the two halves disagree\n // hardest where a crease lands exactly on a sample — a fine scale and a\n // seed whose fold directions are near-axis puts the most creases in\n // reach of the grid.\n name: 'crumple: fully crushed, fine creases, off-axis seed',\n stack: [{ type: 'crumple', options: { amount: 1, scale: 7.5, pull: 1, seed: 5 } }],\n sheet: { width: 1.3, height: 0.9 },\n t: 0,\n },\n {\n // Crush then curl, which is the order the crumple BEHAVIOR stacks them:\n // the creases have to be placed on the flat sheet, not on a bent one.\n name: 'stacked: crumple ∘ bend (the crumple behavior)',\n stack: [\n { type: 'crumple', options: { amount: 0.62, scale: 3.3, pull: 0.5, seed: 2 } },\n { type: 'bend', options: { curvature: 0.31, angle: 35 } },\n ],\n sheet: { width: 1.1, height: 1.4 },\n t: 0,\n },\n {\n name: 'stacked: letter-fold pair (fold ∘ fold)',\n stack: [\n { type: 'fold', options: { angle: 270, offset: 0.2333, foldAngle: 120, radius: 0.05 } },\n { type: 'fold', options: { angle: 90, offset: 0.2333, foldAngle: 100, radius: 0.08 } },\n ],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'stacked: bend ∘ roll ∘ wave',\n stack: [\n { type: 'bend', options: { curvature: 0.6, angle: 0 } },\n { type: 'roll', options: { angle: 90, boundary: 0.1, radius: 0.15, spiral: 0 } },\n {\n type: 'wave',\n options: { amplitude: 0.02, wavelength: 0.6, speed: 0.7, angle: 45, pinnedEdge: 'none' },\n },\n ],\n sheet: { width: 1, height: 1.4 },\n t: 0.8,\n },\n]\n\nfunction buildParityFragment(stack: DeformerInstance[], sheet: SheetDims): string {\n const composed = buildDisplacementGLSL(stack, sheet)\n return /* glsl */ `#version 300 es\nprecision highp float;\nuniform float uPlTime;\nuniform float uPlBias;\n${composed.functionsSrc}\n${composed.displaceSrc}\nout vec4 outColor;\nvoid main() {\n vec2 uv = (gl_FragCoord.xy - 0.5) / float(${GRID - 1});\n vec3 p = vec3((uv - 0.5) * uSheet, 0.0);\n outColor = vec4(plDisplace(p, uv, uPlTime, uPlBias), 1.0);\n}\n`\n}\n\nconst VERT = `#version 300 es\nin vec2 aPos;\nvoid main() { gl_Position = vec4(aPos, 0.0, 1.0); }\n`\n\nfunction compile(gl: WebGL2RenderingContext, type: number, src: string): WebGLShader {\n const shader = gl.createShader(type)!\n gl.shaderSource(shader, src)\n gl.compileShader(shader)\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n throw new Error(`[paperlab parity] shader compile failed: ${gl.getShaderInfoLog(shader)}`)\n }\n return shader\n}\n\nfunction runCaseOnGPU(gl: WebGL2RenderingContext, c: ParityCase, bias = 1): Float32Array {\n const composed = buildDisplacementGLSL(c.stack, c.sheet)\n const program = gl.createProgram()!\n gl.attachShader(program, compile(gl, gl.VERTEX_SHADER, VERT))\n gl.attachShader(program, compile(gl, gl.FRAGMENT_SHADER, buildParityFragment(c.stack, c.sheet)))\n gl.linkProgram(program)\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error(`[paperlab parity] link failed: ${gl.getProgramInfoLog(program)}`)\n }\n // biome-ignore lint/correctness/useHookAtTopLevel: WebGL's gl.useProgram, not a React hook\n gl.useProgram(program)\n\n for (const [name, value] of Object.entries(composed.uniforms)) {\n const loc = gl.getUniformLocation(program, name)\n if (!loc) continue\n if (typeof value === 'number') gl.uniform1f(loc, value)\n else if (value.length === 2) gl.uniform2f(loc, value[0]!, value[1]!)\n else if (value.length === 3) gl.uniform3f(loc, value[0]!, value[1]!, value[2]!)\n else gl.uniform4f(loc, value[0]!, value[1]!, value[2]!, value[3]!)\n }\n const timeLoc = gl.getUniformLocation(program, 'uPlTime')\n if (timeLoc) gl.uniform1f(timeLoc, c.t)\n const biasLoc = gl.getUniformLocation(program, 'uPlBias')\n if (biasLoc) gl.uniform1f(biasLoc, bias)\n\n const quad = gl.createBuffer()!\n gl.bindBuffer(gl.ARRAY_BUFFER, quad)\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), gl.STATIC_DRAW)\n const posLoc = gl.getAttribLocation(program, 'aPos')\n gl.enableVertexAttribArray(posLoc)\n gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0)\n\n const tex = gl.createTexture()!\n gl.bindTexture(gl.TEXTURE_2D, tex)\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, GRID, GRID, 0, gl.RGBA, gl.FLOAT, null)\n const fbo = gl.createFramebuffer()!\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)\n gl.viewport(0, 0, GRID, GRID)\n gl.drawArrays(gl.TRIANGLES, 0, 3)\n\n const out = new Float32Array(GRID * GRID * 4)\n gl.readPixels(0, 0, GRID, GRID, gl.RGBA, gl.FLOAT, out)\n gl.bindFramebuffer(gl.FRAMEBUFFER, null)\n return out\n}\n\n/**\n * The bias contract, checked on the GPU: a stack of strength-bearing\n * deformers must go completely flat at bias 0, and a stack of deformers that\n * opt out (roll) must ignore bias entirely. Parity alone can't catch this —\n * it only ever evaluates bias 1.\n */\nfunction runBiasCases(gl: WebGL2RenderingContext): ParityResult[] {\n const results: ParityResult[] = []\n for (const c of parityCases) {\n const strengths = c.stack.map((i) => getDeformer(i.type).glsl?.strength !== undefined)\n // Mixed stacks flatten only partway — nothing crisp to assert.\n if (!strengths.every((h) => h === strengths[0])) continue\n const scales = strengths[0]\n\n const at0 = runCaseOnGPU(gl, c, 0)\n const reference = scales ? null : runCaseOnGPU(gl, c, 1)\n let maxError = 0\n for (let row = 0; row < GRID; row++) {\n for (let col = 0; col < GRID; col++) {\n const i4 = (row * GRID + col) * 4\n // At bias 0 a scaling stack collapses onto the flat sheet; an opted-out\n // stack must land exactly where bias 1 put it.\n const ex = reference ? reference[i4]! : (col / (GRID - 1) - 0.5) * c.sheet.width\n const ey = reference ? reference[i4 + 1]! : (row / (GRID - 1) - 0.5) * c.sheet.height\n const ez = reference ? reference[i4 + 2]! : 0\n maxError = Math.max(\n maxError,\n Math.abs(at0[i4]! - ex),\n Math.abs(at0[i4 + 1]! - ey),\n Math.abs(at0[i4 + 2]! - ez),\n )\n }\n }\n results.push({\n name: `bias: ${c.name} → ${scales ? 'flat at 0' : 'ignores bias'}`,\n maxError,\n pass: maxError < PARITY_EPSILON,\n })\n }\n return results\n}\n\n/** Run every parity case. Requires a WebGL2 context with float render targets. */\nexport function runParityHarness(canvas?: HTMLCanvasElement): ParityResult[] {\n const cnv = canvas ?? document.createElement('canvas')\n const gl = cnv.getContext('webgl2')\n if (!gl) throw new Error('[paperlab parity] WebGL2 unavailable')\n if (!gl.getExtension('EXT_color_buffer_float')) {\n throw new Error('[paperlab parity] EXT_color_buffer_float unavailable')\n }\n\n const point = new THREE.Vector3()\n const parity = parityCases.map((c) => {\n const gpu = runCaseOnGPU(gl, c)\n let maxError = 0\n for (let row = 0; row < GRID; row++) {\n for (let col = 0; col < GRID; col++) {\n const u = col / (GRID - 1)\n const v = row / (GRID - 1)\n point.set((u - 0.5) * c.sheet.width, (v - 0.5) * c.sheet.height, 0)\n displacePoint(point, u, v, c.stack, { t: c.t, sheet: c.sheet })\n const i4 = (row * GRID + col) * 4\n maxError = Math.max(\n maxError,\n Math.abs(gpu[i4]! - point.x),\n Math.abs(gpu[i4 + 1]! - point.y),\n Math.abs(gpu[i4 + 2]! - point.z),\n )\n }\n }\n return { name: c.name, maxError, pass: maxError < PARITY_EPSILON }\n })\n return [...parity, ...runBiasCases(gl)]\n}\n","import type { ContentConfig, PaperConfig, PaperStatesInput } from './schema'\nimport { diffConfig } from './diff'\nimport { AGENT_PAYLOAD_VERSION } from './agent-payload'\nimport { getLayout } from '../field/layouts'\n\n/**\n * Field-mode export. Every preset a field references is INLINED as a const —\n * receivers don't have the sender's local preset library. Same fixed payload\n * anatomy as the single-paper export, same version.\n */\n\nexport interface FieldExportPaper {\n /** Display name of the preset this slot uses (const naming + description). */\n presetName: string\n /** The RESOLVED preset config (user presets included — nothing to fetch). */\n preset: PaperConfig\n content?: ContentConfig\n /** Per-slot state overrides (slot 3's hover deeper than slot 4's). */\n states?: PaperStatesInput\n}\n\nexport interface FieldExportZone {\n id: string\n accept?: string[]\n bounds: { position: [number, number, number]; size: [number, number] }\n highlight?: 'none' | 'glow' | 'outline'\n}\n\nexport interface FieldExportInput {\n layout: string\n layoutOptions?: Record<string, unknown>\n motion?: { driver?: 'autoplay' | 'drag' | 'none'; speed?: number }\n entrance?: { type?: 'rise' | 'scatter' | 'none'; stagger?: number; duration?: number }\n papers: FieldExportPaper[]\n /** Drop zones — exported as `<DropZone>` children with an onPlace stub. */\n zones?: FieldExportZone[]\n}\n\nconst MOTION_DEFAULTS = { driver: 'autoplay', speed: 0.5 }\nconst ENTRANCE_DEFAULTS = { type: 'rise', stagger: 0.06, duration: 0.9 }\n\nfunction camel(name: string): string {\n const id = name.replace(/[^a-zA-Z0-9]+(.)/g, (_, c: string) => c.toUpperCase()).replace(/[^a-zA-Z0-9]/g, '')\n const safe = /^[A-Za-z]/.test(id) ? id : `preset${id}`\n return safe.charAt(0).toLowerCase() + safe.slice(1)\n}\n\ninterface DistinctPreset {\n varName: string\n presetName: string\n preset: PaperConfig\n}\n\n/** Distinct presets in slot order, with collision-safe const names. */\nexport function distinctFieldPresets(input: FieldExportInput): DistinctPreset[] {\n const byKey = new Map<string, DistinctPreset>()\n const usedNames = new Set<string>()\n for (const paper of input.papers) {\n const key = JSON.stringify(paper.preset)\n if (byKey.has(key)) continue\n let varName = camel(paper.presetName)\n while (usedNames.has(varName)) varName += '2'\n usedNames.add(varName)\n byKey.set(key, { varName, presetName: paper.presetName, preset: paper.preset })\n }\n return [...byKey.values()]\n}\n\nfunction nonDefault<T extends Record<string, unknown>>(\n value: T | undefined,\n defaults: Record<string, unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value ?? {})) {\n if (v !== undefined && v !== defaults[k]) out[k] = v\n }\n return out\n}\n\n/** The layout/motion/entrance props of the export, defaults stripped. */\nexport function diffFieldProps(input: FieldExportInput): Record<string, unknown> {\n const out: Record<string, unknown> = { layout: input.layout }\n const layout = getLayout(input.layout)\n const layoutOptions = nonDefault(input.layoutOptions ?? {}, layout.defaults as Record<string, unknown>)\n if (Object.keys(layoutOptions).length > 0) out.layoutOptions = layoutOptions\n const motion = nonDefault(input.motion, MOTION_DEFAULTS)\n if (Object.keys(motion).length > 0) out.motion = motion\n const entrance = nonDefault(input.entrance, ENTRANCE_DEFAULTS)\n if (Object.keys(entrance).length > 0) out.entrance = entrance\n return out\n}\n\nconst LAYOUT_PHRASES: Record<string, string> = {\n ring: 'a ring you can see around',\n fan: 'a fanned swatch deck hinged at one corner',\n spread: 'a stack slid sideways, each sheet bowing further than the last',\n pile: 'a heap on a desk, the sheets underneath pressed flat',\n wall: 'a pinned studio wall of sheets, none hanging quite square',\n spill: 'a dropped stack caught mid-air, each sheet bent its own way',\n sweep: 'a specimen chart of one sheet at every stage of its deformation',\n book: 'an open book, its pages splayed from a shared spine',\n accordion: 'one continuous strip folded into a concertina',\n rack: 'prints stood in a row and leaning back against a wall',\n sheet: 'a stamp-block grid on a shared backing sheet',\n}\n\n/** The one-line visual an agent verifies after `npm run dev`. */\nexport function describeFieldConfig(input: FieldExportInput): string {\n const n = input.papers.length\n const stateful = input.papers.some((p) => p.preset.states || p.states)\n const zones = input.zones ?? []\n const parts: string[] = []\n\n if (input.layout === 'sheet') {\n const rows = Number(input.layoutOptions?.rows ?? 2)\n const columns = Number(input.layoutOptions?.columns ?? 5)\n parts.push(`a ${rows}×${columns} sheet of papers on a shared backing`)\n } else {\n const layoutPhrase = LAYOUT_PHRASES[input.layout] ?? `a ${input.layout} layout`\n parts.push(`${n} papers arranged in ${layoutPhrase}`)\n }\n\n const driver = input.motion?.driver ?? 'autoplay'\n if (stateful) {\n // Stateful fields render static and interactive — the motion driver is moot.\n parts.push('hovering peels/reacts per paper (interaction states)')\n if (zones.length > 0) {\n parts.push(\n `dragging one past its tear threshold detaches it to carry to the ${zones\n .map((z) => z.id)\n .join(' or ')} zone (release elsewhere flutters it back)`,\n )\n }\n } else {\n if (driver === 'autoplay') parts.push('slowly orbiting on their own')\n if (driver === 'drag') parts.push('draggable sideways with the pointer')\n if (zones.length > 0) parts.push(`${zones.length} drop zone${zones.length > 1 ? 's' : ''}`)\n }\n\n const distinct = distinctFieldPresets(input)\n if (distinct.length > 1) {\n parts.push(`mixing ${distinct.length} paper presets (${distinct.map((d) => d.presetName).join(', ')})`)\n }\n return parts.join(', ')\n}\n\n/** Component source shared by the JSX snippet and the agent payload. */\nexport function buildFieldComponentSource(input: FieldExportInput): string {\n const distinct = distinctFieldPresets(input)\n const varByKey = new Map(distinct.map((d) => [JSON.stringify(d.preset), d.varName]))\n\n // `satisfies` (not `as const`) — const-asserted arrays turn readonly and\n // stop matching the library's input types.\n const consts = distinct\n .map(\n (d) =>\n `const ${d.varName} = ${JSON.stringify(diffConfig(d.preset), null, 2)} satisfies PaperConfigInput`,\n )\n .join('\\n\\n')\n\n const slots = input.papers\n .map((paper) => {\n const varName = varByKey.get(JSON.stringify(paper.preset))!\n const content = paper.content ? `, content: ${JSON.stringify(paper.content)}` : ''\n const states = paper.states ? `, states: ${JSON.stringify(paper.states)}` : ''\n return ` { preset: ${varName}${content}${states} },`\n })\n .join('\\n')\n\n const props = Object.entries(diffFieldProps(input))\n .map(([key, value]) =>\n typeof value === 'string' ? ` ${key}=\"${value}\"` : ` ${key}={${JSON.stringify(value)}}`,\n )\n .join('\\n')\n\n const zones = input.zones ?? []\n const zoneImport = zones.length > 0 ? ', DropZone' : ''\n const zoneChildren = zones\n .map((zone) => {\n const accept = zone.accept ? ` accept={${JSON.stringify(zone.accept)}}` : ''\n const highlight = zone.highlight && zone.highlight !== 'glow' ? ` highlight=\"${zone.highlight}\"` : ''\n return ` <DropZone\n id=\"${zone.id}\"${accept}\n bounds={${JSON.stringify(zone.bounds)}}${highlight}\n onPlace={(paper, zone) => {\n // First-run smoke test — you should see this in the console on drop:\n console.log(paper.presetName, '→', zone.id)\n // Then replace it: stamp a postmark, advance the flow, persist the placement, …\n }}\n />`\n })\n .join('\\n')\n\n if (zones.length === 0) {\n return `import { PaperField, type FieldPaperSlot, type PaperConfigInput${zoneImport} } from 'paperlab'\n\n${consts}\n\nconst papers: FieldPaperSlot[] = [\n${slots}\n]\n\nexport function PaperGallery() {\n return (\n <PaperField\n papers={papers}\n${props}\n />\n )\n}`\n }\n\n return `import { PaperField, type FieldPaperSlot, type PaperConfigInput${zoneImport} } from 'paperlab'\n\n${consts}\n\nconst papers: FieldPaperSlot[] = [\n${slots}\n]\n\nexport function PaperGallery() {\n return (\n <PaperField\n papers={papers}\n${props}\n >\n${zoneChildren}\n </PaperField>\n )\n}`\n}\n\n/** The self-contained field integration brief — one paste into a coding agent. */\nexport function buildFieldAgentPayload(input: FieldExportInput): string {\n return `Integrate a Paperlab paper gallery into this project. (paperlab agent-payload v${AGENT_PAYLOAD_VERSION})\n\n1. Install the dependencies:\n\n npm i paperlab three @react-three/fiber gsap\n\n2. Create the component below as \\`components/PaperGallery.tsx\\` (or the\n project's component convention). It is self-contained — every preset it\n uses is inlined, and it owns its own <Canvas>:\n\n\\`\\`\\`tsx\n${buildFieldComponentSource(input)}\n\\`\\`\\`\n\n3. Sizing: the component fills its parent container. Place it where I ask;\n give the parent an explicit height.\n\n4. Verify: run the dev server. You should see ${describeFieldConfig(input)}.\n If the canvas is blank, the parent container almost certainly has no height —\n give it one (this is the classic React Three Fiber integration bug, not a\n paperlab bug).\n\nConstraints: don't modify the preset values; three >= 0.160 and React 19 are\nrequired; the component needs no props.`\n}\n","export type PaperMode = 'hero' | 'field'\nexport type PaperModeRequest = PaperMode | 'auto'\n\nexport interface ModeContext {\n interactive: boolean\n physics: string\n count: number\n}\n\n/**\n * Hero mode: deformer stack runs in JS on the CPU, writing BufferGeometry\n * positions (correct raycasting, shadows, physics, handle drags).\n * Field mode: composed GLSL vertex chunks, instanced (galleries, 10+ sheets).\n * The same preset JSON drives both.\n */\nexport function resolveMode(requested: PaperModeRequest, ctx: ModeContext): PaperMode {\n if (requested !== 'auto') return requested\n if (ctx.interactive || ctx.physics !== 'none' || ctx.count <= 10) return 'hero'\n return 'field'\n}\n"],"mappings":"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","names":["Paper","sheet"]}
|