Preload the LCP image (install.webp) from the HTML and add
fetchpriority="high" so the browser discovers it before JS executes.
Use a <main> landmark for the primary content container to satisfy
the "document has a main landmark" accessibility audit.
* Organize public assets into subdirectories
Group 80+ flat files into images/, textures/, pdf/, and audio/ subdirectories
for easier navigation. Update all references across 14 source files.
* Add apple-touch-icon
* Add vehicle texture editing
Parse and serialize Act1State textures in save files. Add a texture
picker modal with default presets (from .tex files) and custom uploads
persisted to IndexedDB per texture name. Quantize uploaded images
against the WDB palette and render texture changes in the 3D preview.
Support resetting textures to the WDB default.
* Fix vehicle texture not updating when switching save slots
Include slot number in the part key so that switching save slots
triggers a full part reload with the new slot's textures.
* Preload default textures for instant texture picker opening
Fetch and parse .tex files in the background when a textured part
loads, and pass the results to TexturePickerModal as a prop. The
modal no longer fetches on mount, eliminating the loading delay.
* Cleanup: parallel fetching, error recovery, dead code removal
- Fetch .tex files in parallel with Promise.all instead of sequentially
- Clear cached IndexedDB promise on rejection so subsequent calls retry
- Remove unused textureOrder array from Act1State parser
- Unify selectDefault/applyCustom into single applyTexture function
- Remove redundant squareTexture call on already-squared wdbTexture
* Add vehicle texture editor to February 2026 changelog
* Fix mouseenter error on non-Element targets
- Temporarily expand tooltip for accurate size measurement before positioning
- Use @media (hover: hover) to prevent CSS :hover triggering on touch tap
- Await position calculation before showing tooltip
- Use @floating-ui/dom for intelligent tooltip placement
- Tooltips now shift/flip to stay within viewport bounds
- Collapse hidden tooltips to prevent horizontal scroll overflow
- Move tooltip setup to App.svelte for global coverage
* WIP
* stuff
* WIP: Interactive 3D score cube for save editor
* Conditionally render ScoreCube to properly clean up WebGL canvas
Only mount the ScoreCube component when on the save-editor page.
This ensures onDestroy is called when navigating away, properly
disposing of the WebGL renderer and removing the canvas from DOM.
* Refactor: Consolidate formats and genericize WDB rendering
- Move parsing/serialization code to src/core/formats/:
- BinaryReader.js, BinaryWriter.js (shared utilities)
- SaveGameParser.js, SaveGameSerializer.js
- PlayersParser.js, PlayersSerializer.js
- Create formats/index.js as barrel export
- Extract generic WdbModelRenderer from ScoreCubeRenderer:
- WdbModelRenderer handles D3DRM geometry and paletted textures
- ScoreCubeRenderer extends it with score-specific logic
- Prepares for rendering other WDB models in the future
- Keep savegame/constants.js for domain-specific constants
- savegame/index.js remains as high-level API facade
* Save editor UI improvements
- Make save slot cards fixed width (85px) to prevent resizing with name length
- Make save slot cards more compact (smaller icons, padding, font)
- Remove Act selection from Character section
- Remove box-shadow from selected character to fix collapsed section bleed
* Improve score cube lighting to match in-game appearance
- Use flat, even lighting (high ambient + soft front light)
- Remove harsh directional shadows from edges
- Adjust camera position slightly for better framing
* Add spacing below score cube canvas
* Add spinning loader while loading score cube
* Update three.js to 0.182.0 and fix npm audit issues
- Update three.js from 0.170.0 to 0.182.0
- Fix npm audit vulnerabilities (devalue, lodash, svelte)
- Remaining vulns are in dev dependencies (vite, workbox-cli)
* Fix score cube overflow on mobile
Add max-width constraints to prevent the score cube from expanding
its container on narrow viewports while preserving its natural
200x200 size on desktop.
* Add save slot carousel and improve empty states
- Add reusable Carousel component with arrow navigation, drag-to-scroll,
and click-to-scroll-into-view functionality
- Replace static save slot list with horizontal carousel
- Add empty state with image when no save files exist
- Add prompt state when saves exist but none is selected
- Reset selected slot when entering Save Editor page
* Add February 2026 changelog entry for Save Editor
* Add missing January 2026 changelog entries for Safari and mobile fixes
* Remove unused mission images
* Refactor opfs.js to reduce code duplication
- Consolidate getFileHandle to use getOpfsRoot internally
- Add writeTextFile helper that uses writeBinaryFile
- Extract showToast helper for toast notifications
- Simplify saveConfig to use writeTextFile instead of duplicate worker
- Simplify fileExists and readBinaryFile to use getFileHandle
* Remove unused ScoreColorButton component
* Remove unused UI components
- Show "DEVELOPMENT MODE" in footer instead of timestamp
- Disable offline install/uninstall when service worker unavailable
- Set __BUILD_TIME__ to null in dev mode for conditional rendering
- Replace vanilla JS with Svelte 5 components
- Add Vite build system with Terser optimization
- Reorganize assets into src/ and public/ directories
- Update README with setup instructions