-
NEW
Light / Dark Mode
Added a full theme toggle in the top-right of the header. Click the moon/sun SVG icon to switch between dark and light mode. Preference is saved to localStorage and persists across sessions. Light mode uses an off-white base (`#f4f4f6`), true black for primary text, dark gray for secondary labels, and muted gray for supporting text to maintain visual hierarchy without a wall of pure black.
-
NEW
Lock All / Unlock All
New button in the palette header (between the score widget and Clear Palette). Locks every swatch in the current palette in one click. If all swatches are already locked, the button becomes "Unlock All" and reverses the state. Button reflects locked state visually.
-
NEW
Undo / Redo
Full undo/redo history with a 40-step stack. Undo and Redo buttons appear between the Extraction Settings and Tools panels. Every destructive operation pushes a snapshot — extraction, random generation, sort, shuffle, remove duplicates, lock all, variations. Keyboard shortcuts: `Ctrl+Z` to undo, `Ctrl+Y` or `Ctrl+Shift+Z` to redo.
-
NEW
Expand All Tints / Collapse All Tints
New full-width button at the bottom of the Tools panel. Expands the tint/shade strip on every swatch simultaneously. Click again to collapse all. Tint expanded state now persists through regeneration, sorting, locking, and any other palette operation — expanded tints stay open until you explicitly close them.
-
NEW
Auto-Save Indicator
A subtle pill indicator appears centered in the header every time the palette state is committed. Shows a green checkmark and "Auto-saved" text, fades out after 1.6 seconds. Confirms to the user that their palette is always persisted to history without any manual action.
-
NEW
Gradient Copy Button
A copy icon button sits inline next to the "Generate Gradient" button. Click it to copy the full CSS gradient string to clipboard. Confirms with a checkmark icon and a toast notification.
-
NEW
Version Badge
App version displayed as a silver gradient pill badge inline with the title in the header. Updates with each release.
-
IMP
Theme-Aware Exports
PNG Card and HTML Preview exports now respect the current theme at export time. In dark mode they export with dark backgrounds and light text as before. In light mode they export with light backgrounds (`#f4f4f6`) and dark text. Video export is theme-independent by design.
-
IMP
Proper PWA / Store Files
- `manifest.json` is now a proper standalone file instead of an inline base64 data URL.
- `sw.js` is now a proper standalone service worker file instead of an inline blob.
- The service worker now caches all JS and CSS assets on install, not just `index.html`.
-
IMP
App Icons
Replaced the inline SVG placeholder icon with the official Palette Thief fox icon at all required sizes: 16×16, 32×32, 48×48, 96×96, 192×192, 512×512, and a 512×512 maskable variant with safe-zone padding. PWA install prompt all use the icon.
-
IMP
Panels Reordered
Color + Variations panel moved above Gradient Maker in the left panel for a more logical workflow — color input first, gradient tools second.
-
IMP
Intelligence Score
Score number font size increased from 10px to 16px. The score widget now has additional margin separating it from the action buttons, pushing it visually toward the center of the header row.
-
IMP
Shortcuts Hint Button
The `? shortcuts` button in the bottom-right corner is now larger — increased padding and font size for easier tap and click targeting.
-
IMP
Keyboard Shortcuts Modal
Undo (`Ctrl+Z`) and Redo (`Ctrl+Y`) added to the Palette section of the shortcuts reference modal.
-
FIX
Luminance Formula Inconsistency
`score.js` was using a gamma approximation (`v/255 ** 2.2`) for luminance while `contrast.js` used the correct IEC 61966-2-1 piecewise formula. Both now use the correct formula so WCAG scores and intelligence scores are internally consistent.
-
FIX
Design System Export — Missing Roles
`design-system.js` could silently omit semantic role variables (e.g. `--color-background`, `--color-surface`) when the palette contained no dark or no bright colors. All 7 semantic roles now always get assigned via a fallback to the nearest available color.
-
FIX
Color Namer — Duplicate Name Collisions
When all prefix/base word combinations were exhausted, the fallback appended `index + 1` to an already-used name, producing duplicate names. The fallback now increments a suffix counter until a genuinely unique name is found.
-
FIX
Lock-Merge Index Bug
`_applyGeneratedPalette` had an off-by-one error in the lock-merge loop that caused one generated color to be silently dropped for each locked slot in the palette. Fixed — no more silent color loss when regenerating with locked swatches.
-
FIX
PNG Card Font Reliability
`downloadPngCard` now wraps canvas rendering in `document.fonts.ready` so Fira Code is guaranteed loaded before the canvas draws. Previously the font could silently fall back to system monospace.
-
FIX
Video Cards Style — `roundRect` Polyfill
The Cards animation style used `ctx.roundRect()` directly, which is not available in Chrome < 99, Firefox < 112, or Safari < 15.4. A `canvasRoundRect()` polyfill now handles all browsers.
-
FIX
PWA — Assets Not Cached
The previous service worker only cached `index.html` on install. All script files and the stylesheet would 404 on an offline reload despite the app appearing to be a PWA. The service worker now caches all JS files and the CSS on install.
-
FIX
`hslToRgbArr` Duplication
The function was defined identically in both `app.js` and `sidebar.js`. Moved to `PT.utils.hslToRgbArr` as a single shared implementation.
-
FIX
`renderPalette` Double `updateGradientSelectors` Call
The gradient selectors were being rebuilt twice on every render. Redundant call removed.
-
FIX
`removeDuplicates` — Hex-Exact Only
Previously used strict hex string equality, missing perceptually identical colors that differed by one channel value. Now uses Euclidean RGB distance with the same threshold as the extraction engine.
-
FIX
`btnRegenerate` Enabled on Library Load
Loading a palette from the library enabled the Regenerate button even when there was no image loaded and no random preset selected, leading to a confusing "Load an image first" toast. Regenerate is now correctly disabled when there is nothing to regenerate from.
-
FIX
Light Mode — Invisible Text
Multiple panels had text that became invisible in light mode due to hardcoded rgba white colors in inline styles and CSS rules. Fixed across: extraction settings checkboxes and labels, palette size select, gradient maker labels and selects, score widget "Intelligence" label, score grade, harmony badge, score breakdown tooltip, video export drawer labels and buttons, export dropdown category labels, library action buttons.
-
FIX
Theme Toggle Icon Color
The SVG moon/sun icons use `currentColor`. The toggle button previously inherited a dark color in dark mode making the icon invisible against the dark header. Explicit `color: #c8c8d0` set on `.theme-toggle` in dark mode.
-
FIX
Export Dropdown Hover — Light Mode
The hover background on export items was `rgba(0,0,0,0.05)` — effectively invisible on a white background. Replaced with solid `#d6d6e2` for standard items and appropriately tinted solid backgrounds for the colored items (Figma, Tailwind, Design System, Video).