.changelog/3154.md
info.json can declare a haptic block with style (light/medium/heavy/soft/rigid) and intensity (0.0–1.0); falls back to the default UIImpactFeedbackGenerator when absent.backgroundAnimation block (type: frames/apng/gif, frames, fps, loops); rendered by DeltaSkinAnimatedBackgroundView beneath the game screen, pausing when the app is backgrounded.keyboardOverlay config now display a toggleable virtual keyboard during gameplay; auto-shows when autoShow: true. Supports QWERTY, compact, C64, ZX Spectrum, Amstrad CPC, and Atari ST layouts via the existing VirtualKeyboardView infrastructure.UIImage(pdfData:preserveTransparency:) gains an optional size: CGSize? parameter; when provided, PDFs rasterise at exactly that logical size × screen scale for crisp HiDPI output instead of an uncapped 4096 px default.states block (Manic EMU format) with normal, pressed, and optional animated (frames/fps/loops) image references; DeltaSkinView loads and caches per-button images, falling back to the legacy asset path for existing skins.DeltaSkinModelTests covers DeltaSkinHaptic, DeltaSkinBackgroundAnimation, DeltaSkinButtonStates, and DeltaSkinValidationResult with Codable round-trip, equality, and edge-case tests.DeltaSkinScreen now correctly decodes filters from skin info.json and constructs CIFilter instances at import time; CRT, scanline, sepia, and blur filters specified in skins now apply at runtime instead of always being nil.