All notable changes to Spectral are documented here. This project follows Semantic Versioning.
1.0.14
Changed
Domain migration — all references updated from spectral.platvlak.nl to spectral.platvlak.com (CNAME, Astro config, CORS origins, workers, robots.txt, OG images)
OG images regenerated with correct Spectral logo matching favicon.svg — now produces all 6 locale variants in a single script run
Cloudflare Web Analytics token updated for new .com domain
Mollie coffee payment link updated to new payment URL
i18n completeness test expanded from NL-only to all 5 locales (168 tests, 1556 total)
Changelog preview titles migrated from hardcoded English to i18n translation keys
Removed
canvas devDependency — only needed locally for OG image generation, not for CI builds
1.0.13
Added
Full platform localization — all 6 locales (EN, NL, DE, FR, ES, IT) now have complete translations with 1173 keys each
New translation dictionaries: de.ts, fr.ts, es.ts, it.ts — 4 new locale files with full coverage
Localized blog content — 10 articles translated into DE, FR, ES, IT, and NL (50 new blog posts total)
Localized changelog page serving /nl/changelog/, /de/changelog/, etc.
Localized blog overview with translated titles, categories, and reading time
Localized OG images for NL, DE, FR, ES, IT with translated taglines
RoadmapPreview component on the landing page for upcoming Pro features
E2E routing spec for locale switching and 404 handling
Changed
Locale routing expanded — all content pages now generate routes for all 5 non-EN locales via [lang] dynamic segments
Locale default changed from 'nl' to 'en' across all page files
Landing page components now use locale-aware links via getCurrentLanguage()
404 page detects all 6 locales from URL path and localizes editor link
Layout JSON-LD featureList now uses dynamic translation keys
E2E tests switched from Dutch to English locale with English text matchers
Fixed
French translation build error — fixed double-escaped apostrophe in fr.ts
Removed
Unused Inter font — removed @font-face, preload, and woff2 file (48KB saved)
Migrated inline SVGs to a centralized Icon component to improve accessibility (aria-hidden) and streamline markup
Normalized CSS fallbacks across UI components, removing hardcoded hex values in favor of strict CSS variables for better theming consistency
Fixed
Further refined Spectral Pro email templates with robust layout tables (bgcolor) ensuring perfect dark-theme contrast and compatibility across rigidly styled email clients (like Outlook) without relying on MJML
1.0.11
Added
Expectations Disclaimer — a transparent breakdown on the landing page to manage expectations around browser-based RAW processing and the "indie project" model
Pro Banner Recovery — integrated a direct "Restore purchase" link inside the Pro Banner for returning users who cleared their cache
Changed
Refined English and Dutch copy across the landing page for a more natural, authentic tone
Improved accessibility and focus styles across multiple UI components
1.0.10
Fixed
Updated Spectral Pro email templates with full HTML structure and explicit dark backgrounds to prevent readability issues in certain email clients
Fixed a syntax error in Dutch localization (nl.ts) regarding apostrophes in disclaimer text that caused the build to crash
1.0.9
Changed
Refined free and Pro messaging for Spectral — emphasizing affordability and clarifying Pro features as a one-time purchase
Updated liability and privacy statements (Terms of Service / Privacy Policy) to clarify Mollie payment processing and implement a liability cap
Removed
Removed outdated data-store.json to simplify project structure
1.0.8
Added
Spectral Pro — one-time purchase (€20) that unlocks Effects, Camera Calibration, and Local Adjustments via a gated paywall with upgrade modal, feature checklist, and Mollie checkout
Pro upgrade modal with email input, feature list, and one-click checkout flow to Mollie payment page
Pro recovery modal — restore a previously purchased license via Magic Link email (powered by Resend)
Pro badge on section headers (Effects, Calibration, Local Adjustments) indicating which sections require Pro
Golden "PRO" badge next to the SPECTRAL logo in both the Editor and Library top bars when Pro is active
ProGate component — locks Pro-only section content behind a sleek overlay with unlock call-to-action
Pro licensing utilities with admin bypass via URL parameter or localStorage key
Cloudflare Worker API for secure Mollie payment creation, webhook verification, KV license storage, and Magic Link email delivery
Pro banner on English and Dutch landing pages linking to the editor upgrade flow
30+ new i18n keys for Pro UI strings in English and Dutch
11 new unit tests for Pro licensing utilities
9 new E2E test cases for Pro gating, upgrade modal, admin bypass, and unlock verification
Changed
Controls component updated to wrap Effects, Calibration, and Local Adjustments sections in ProGate
E2E test helpers updated with locale-independent selectors (EN/NL dual matching)
CSP headers updated to allow connections to the Pro Worker API
1.0.7
Added
Reconnect originals — re-link full-resolution files by selecting a folder with your originals after restoring from backup
Reconnect banner in project detail — automatically detects disconnected photos and shows a call-to-action to re-link originals
"Add Fujifilm Recipe" action button in the Cookbook panel for discovering film recipe imports
Import/export icon buttons in the Cookbook section header for quick access to recipe management
10 new i18n keys for reconnect flow (EN + NL)
Changed
Cookbook UI modernized — full-width CTA buttons for Save and Add Fujifilm Recipe, recipe list as primary content
Section component refactored — header toggle zone separated from action buttons to prevent accidental collapse
Improved error handling in backup restore with descriptive messages
Fixed
Section header action buttons no longer toggle the section's collapsed state
Recipe validation handles edge cases with stricter sanitisation
Two bare English strings in ShareRecipeModal wrapped with i18n translation function
1.0.6
Added
Full backup & restore — export all projects, photos, recipes, custom LUTs, and settings as a single compressed file; restore from any backup to pick up where you left off
Backup status indicator in the Projects overview showing time since last backup and estimated file size
File System Access API integration — save backups directly to cloud-synced folders (iCloud Drive, Google Drive, Dropbox) on supported browsers; standard download fallback on others
Restore confirmation dialog with import summary (project/photo/recipe/LUT counts) before committing
Progress overlays for both backup and restore operations
18 new i18n keys for backup/restore UI (EN + NL)
19 new tests for full backup validation — test suite now at 87 files, 1461 tests
Fixed
TypeScript errors in CommunityRecipes and CookbookAdmin — category field references corrected after API migration to tags
TypeScript compilation now passes with zero errors
Changed
Blog article "Your Photos Deserve Privacy" updated — backup section rewritten to highlight the new one-click backup feature
1.0.5
Added
Illustrative screenshots embedded in blog articles — tone curves, HSL panel, full editor view, LUT export dialog, gradient tool, and applied LUT examples
Image styling for markdown content images — responsive sizing, rounded corners, and subtle shadow
Changed
Blog articles enriched with personal photography workflow details, gear preferences, and first-hand editing experiences for a more authentic voice
Editorial content column widened from 65ch to 75ch for improved readability on larger screens
Body copy typography updated to fluid sizing with relaxed 1.8 line height
About and Maker page copy refined with subtle emoji accents in both English and Dutch translations
1.0.4
Fixed
Crash when applying community recipes with missing nested state objects — corrupted data from incomplete recipe settings caused cascading TypeErrors across the WebGL renderer, histogram, and offscreen export pipeline
State migration now deep-merges all nested objects instead of shallow-spreading, preventing corrupted IndexedDB data from overwriting safe defaults
Recipe validation handles undefined selectedFilter without crashing
Curves, histogram, and offscreen render utilities guard against undefined or partial state
WebGL render loop guards halationColor and bwTintColor tuples with fallback defaults
CSS media query syntax error in reset.css corrected
Changed
Recipe import now sanitizes all settings before applying, ensuring community recipes with missing fields get proper defaults
Gallery page removed from site navigation — page exists but is not publicly linked
Cookbook API CORS updated with correct allowed origins
1.0.3
Added
Community Cookbook gallery — browse, search, and import shared recipes from a public gallery powered by a Cloudflare Worker API
Recipe sharing modal — share your grading recipes to the community gallery with title, description, and tags
Cookbook admin panel for moderating submitted recipes
Blog section with 10 SEO-optimized articles on color grading, LUTs, RAW editing, tone curves, privacy, and Fujifilm film simulations
Blog layout with article listing page, individual article pages, and reading time estimates
Community page for discovering shared recipes and connecting with other photographers
Gallery page showcasing sample edits and use cases
Maker page with creator background and project story
Custom 404 error page with navigation back to the app
Dutch localized variants for all new content pages
Machine-readable llms.txt project summary for AI agent discoverability
Seed script for populating the cookbook API with sample recipes during development
Cookbook API Cloudflare Worker with recipe CRUD, moderation, search, and CORS support
Changed
WebGL shader source extracted into a dedicated shaders.ts module for cleaner architecture
Site navigation restructured with new sections (Community, Blog, Gallery, Maker)
Landing page content and layout refreshed with updated feature sections
Content pages refactored into reusable Astro content components
Astro configuration updated with blog content collection and sitemap integration
Expanded i18n translations for new pages, navigation items, and community features
Project documentation consolidated for efficient AI agent onboarding
1.0.2
Added
Comprehensive E2E test suite — 8 new Playwright spec files covering editor load, tone controls, crop, filters, panels, shortcuts, undo/redo, export, and navigation
Reusable E2E helper module with shared functions for seeding test data, navigating to the editor, dismissing tours, and interacting with sliders
Playwright configuration with webServer auto-start, nl-NL locale, and Chromium-only project
BrowserGate component — blocks rendering with a friendly message when WebGL 2 is unavailable instead of crashing
Histogram core module — extracted pixel tallying, statistics, and smoothing from the Web Worker for shared use and easier testing
Shared canvasToBlob and blobToImage utilities, eliminating duplicate implementations across export and share modules
New tests for crop, project export, export, HSL target, View Transitions, and LUT export modules
Changed
Histogram Web Worker refactored to import pure functions from a shared core module — reduced from ~120 lines to ~20 lines
IndexedDB helper (db.ts) simplified with consolidated migration logic
Settings module refactored for reduced complexity and DRY configuration access
Auto-save and filmstrip navigation hooks refactored to eliminate duplicated logic
Batch export and share modules now use shared canvas-to-blob utilities instead of local copies
Likes API CORS policy — replaced hardcoded origin allowlist with dynamic localhost matching for local development
Test suite expanded to 87 files and 1442 tests
Fixed
CORS error when calling the likes API from non-standard local dev ports
ERR_CONNECTION_REFUSED when running E2E tests without a running dev server
Vite error overlay blocking all pointer events during test navigation
Incorrect dev server URL in README
1.0.0
Spectral's first stable release. A browser-based color grading tool with a full GPU-accelerated pipeline, now production-ready.
Highlights
Complete Color Grading Pipeline — exposure, contrast, curves, HSL mixer, color wheels, B&W conversion with channel mixer and tinting
7 Cinematic Film LUTs — Chrome, Soft Tone, Amber Haze, Golden Hour, Daylight, Pacific, Evergreen — plus custom .cube LUT import
LUT Export — export your grade as a standard .cube 3D LUT file
RAW Support — full WebAssembly-based sensor demosaicing (CR2, CR3, NEF, ARW, DNG, RAF, ORF, RW2)
Effects — film grain, halation, bloom, diffusion, chromatic fringe, vignette
Local Adjustments — linear and radial gradient masks with per-mask controls
Library & Projects — organize photos with star ratings, color labels, batch import, and folder scanner
Cookbook — save, share, and import grading recipes as portable JSON
Privacy-first — all processing local via WebGL 2, no uploads, no analytics
PWA — fully installable with offline support
Added
Browser compatibility gate — shows a friendly message when WebGL 2 is unavailable instead of crashing
Comprehensive test suite hardening — 87 test files, 1442 tests, all passing
New test coverage for HSL target, View Transitions, LUT export, crop, and project export modules
Fixed
All TypeScript compiler errors and ESLint warnings resolved
Vite chunk size warnings eliminated via manualChunks build configuration
0.2.0-beta.11
Added
Settings modal with tabbed interface for Performance, Editor, Export, and General preferences (RAW decode quality, auto-tone, slider hints, undo history limit, canvas background)
View Transition API integration for animated photo grid reordering during filter and sort changes
Crossfade photo transitions in the editor with reduced-motion support
Comprehensive test suite hardening — 10 new test files covering hooks and utilities, from 76 → 86 files and 1346 → 1412 tests
Global localStorage polyfill for Node v25 compatibility in the test runner
Changed
Replaced hardcoded UI strings with internationalized labels across Controls, EditorTopBar, Filmstrip, Loupe, and export components
Added focus ring and touch device styles for improved keyboard and mobile accessibility
Optimized CSS with consistent component styling, spacing tokens, and responsive adjustments
Fixed
Module-level localStorage access in i18n.ts now safely guards against incomplete Storage implementations, resolving 14 failing test files
0.2.0-beta.10
Added
Numbered 3-step workflow section on the landing page (Import → Grade → Export) with animated step indicators
Changelog preview component on the landing page showing the latest release highlights
Contextual hint icons on editor sliders to aid user understanding of each control
Import result toast notifications — clear feedback after batch photo imports
Changed
Merged filter bar and selection bar in the library into a single streamlined toolbar, reducing visual clutter
Smoother opacity transitions across interactive UI elements for improved responsiveness
Enhanced press and hover interaction states with tactile feedback effects
Refined pseudo-element styling for better slider group visual separation
Improved visual consistency across subtle UI elements (borders, shadows, spacing)
0.2.0-beta.9
Added
Resizable editor panels — drag the edges of the left and right panels to adjust their width, persisted across sessions
ResizeHandle component with accessible separator role, pointer-capture drag, and col-resize cursor feedback
Half-resolution proxy rendering while dragging sliders — reduces GPU workload during interaction
"As Shot" (neutral) white balance preset with Aperture icon as the default WB state
Icons for all white balance presets (Sun, Cloud, TreePine, Lightbulb, CircleDot, Zap)
Local adjustments now applied during HQ export — each enabled gradient is composited in a multi-pass WebGL pipeline
Export status overlay with smooth fade transition instead of conditional mount (prevents flicker)
Internationalized export status strings (RAW decoding, filter application) in English and Dutch
"No photos match filters" empty state message for the library
Changed
Landing page English content visible by default for improved SEO and First Contentful Paint
IndexedDB migration logic consolidated — fresh installs now create the full v6 schema in a single step instead of replaying six incremental migrations
Redo in edit history now synchronises state ref before calling setState, fixing a stale-ref bug
Feedback modal heading uses an explicit id for aria-labelledby focus management
Fixed
Redo state sync — state ref was not updated during redo, causing subsequent edits to reference stale state
Export overlay no longer flickers when toggling between status messages
0.2.0-beta.8
Added
Export quality picker — choose between high, medium, and low quality when exporting photos
Compact export menu variant for the library selection banner with quality badge indicator
Changed
"Select All" and shift-click range selection now operate on the filtered photo list instead of all photos
Batch export accepts a quality parameter, defaulting to high quality
Fixed
Shift-click multi-select no longer selects photos hidden by the active filter
0.2.0-beta.7
Added
Web Share API integration — share photos via the native OS share sheet or copy to clipboard from the library
Batch sharing — select and share multiple photos at once from the project library
Custom SVG cursors for all editor tools — crosshair, eyedropper, grab/grabbing, rotate, resize handles, and a Lightroom-inspired target-adjust cursor for the HSL tool
Grabbing cursor state on slider thumb interaction for improved tactile feedback
Keyboard shortcut for sharing photos from the library
LibraryTopBar component — dedicated top bar for the library module with search and actions
Changed
Filmstrip filter bar redesigned with surface-level hierarchy instead of horizontal dividers
Keyboard shortcuts modal split into more granular categories (rating, labels) for better scannability
HSL Targeted Adjustment Tool automatically deactivates when switching to other tools or navigating between photos
Crop tool edge dragging improved — single-edge dragging now works reliably after initial adjustment
Context menu streamlined — color labels moved exclusively to right-click menu, rating options removed from context menu
Share functionality restricted to the library module — removed from the editor for a cleaner develop workflow
Fixed
Crop tool drag handles no longer collapse the crop rectangle due to incorrect clamping logic
Filmstrip no longer disappears when filtering on non-existent criteria
0.2.0-beta.6
Added
View Transitions API integration — smooth morphing animations between library grid and editor views
Compression Streams API for gzipped project exports — smaller, faster .spectral archive downloads
Web Locks API — prevents data corruption when multiple tabs access the IndexedDB simultaneously
Histogram computation offloaded to a dedicated Web Worker for non-blocking UI performance
LRU-based undo history pruning — automatically evicts oldest entries to bound memory usage
Changed
ARIA landmarks and keyboard-accessible skip links refined for improved screen reader navigation
0.2.0-beta.5
Added
Loupe photo viewer — Lightroom-style fullscreen culling view with star rating, color labels, and keyboard navigation
Full-resolution image loading in Loupe — loads the embedded JPEG preview on-demand, with the thumbnail as instant placeholder
Prefetch of next/previous photos in the Loupe for instant arrow-key navigation
Multi-file recipe import — import multiple .json recipe files at once in the Cookbook
Skip-to-content link and ARIA landmarks for screen reader accessibility
Dutch translations for Loupe, recipe import, and accessibility labels
Changed
Extracted filter/sort logic from ProjectDetail into dedicated useLibraryFilters hook
Extracted collapsible section state into useSectionState hook
Refactored editor component internals for reduced complexity
Fixed
Loupe now shows full-quality images immediately — previously only showed blurry thumbnails until the photo was opened in the editor
0.2.0-beta.4
Added
Arrow key navigation in the filmstrip — press ← / → to cycle through photos like a carousel