53 Commits
Author SHA1 Message Date
Æmotion StudioandClaude Opus 5.5 b808a9d583 feat: add kaleido shader and temporal_rate, fix drift under coherence and gaussian channel 0
- kaleido: a field folded about the frame centre for symmetric compositions; octaves is the fold order
- temporal_rate socket on Direct, Walk and Source sets how fast a held pattern evolves across a clip
- drift with use_temporal_coherence no longer collapses to jump; each draw holds its own seed
- gaussian no longer shares its first channel's seed with the sampler's base noise
- verification/describe_field.py scores a shader type without rendering; analyze.py --bands

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 09:59:28 -07:00
Æmotion StudioandClaude Fable 5.1 5c849d6698 feat: live previews for every shader type
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 01:49:12 -07:00
Æmotion StudioandClaude Fable 5.1 cf42fc020d docs: every shader type is free
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 01:48:47 -07:00
Æmotion StudioandClaude Opus 5 f91c1e4954 feat: choosing a preset writes the widgets it controls
A preset was applied at execution time, so the panel lied: select explore and
shader_strength kept showing its old value while the run used 0.30.

web/src/preset_widgets.ts wraps the preset widget's callback and writes the
bundle into the widgets it names, running each widget's own callback so the
shader preview follows. Editing one of those widgets to a value the preset does
not hold drops the preset back to custom -- otherwise the panel would just lie
the other way. The Walk node keeps the parameter it ramps, and a saved workflow is
never rewritten on load.

The table comes from GET /shader_noise_ksampler/presets rather than a copy in
TypeScript, because preset values get recalibrated and a copy would drift. The
Python override stays the authority: API submissions and the Walk node never run
the JS.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 14:04:01 -07:00
Æmotion StudioandClaude Opus 5 1bd794c353 feat(web): show the shader preview on the Direct node
The preview now attaches to ShaderNoiseKSamplerDirect as well. That node
already exposes every shader control as a real input, so instead of adding a
second, unconnected copy of each widget, the preview mirrors the node's own
inputs into the properties its WebGL uniforms read, and follows them as they
change.

Its four preview-only widgets (Show Shader, Show Tooltips, Animation Speed,
Pixel Resolution) are marked serialize: false there. Saved workflows map widget
values by position, so serializing them would shift every stored input when an
older workflow loads.

The deprecated display node keeps its own widgets and behaviour unchanged.

Also adds vitest coverage for the sampling-mode migration helpers.
Typecheck clean, 91 web tests pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 15:52:03 -07:00
Æmotion StudioandClaude Opus 5 3af34338ab feat: add sampling_mode and route the node to the corrected pipeline
The Direct node now dispatches: "standard" (default) runs the new pipeline,
"legacy" runs the frozen pre-2.0 one. Measured through the node with a
recording sampler, 20 steps:

  standard, 1 stage       1 call  x 20 steps, from sigma 14.61
  standard, 2 stages      2 calls x 10 steps, from 14.61 then 1.48
  standard, denoise 0.6   1 call  x 20 steps, from 2.23
  standard, 3 injections  4 calls x  5 steps, 14.61 / 3.87 / 1.48 / 0.60
  legacy,   2 stages      2 calls, each rebuilding a full schedule

The 1.48 is the fix: stages continue one trajectory instead of restarting at
maximum noise, where flow models discard the previous stage entirely. The 2.23
is denoise finally reaching the schedule.

Also on the node:
- sequential_distribution, injection_distribution and fast_high_channel_noise
  become real optional inputs. As V1 `hidden` tuple inputs ComfyUI never
  delivered them, so they were stuck at their defaults.
- the debug/visualisation hidden inputs are gone; they drove stub no-ops.
- IS_CHANGED is removed: it only restated widget values that are already part
  of the cache key, and would have rejected the new input.
- new widgets are appended last, so saved workflows keep their widget order.

web/src/sampling_mode_migration.ts switches nodes loaded from pre-2.0
workflows to "legacy", recognising them by the absence of the snk_version
property, so existing seeds keep reproducing.

186 Python tests and 85 web tests pass; the 11 legacy goldens now exercise the
legacy branch through this dispatch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 15:35:14 -07:00
Æmotion StudioandClaude Opus 5 711981a734 refactor: delete the dead mapper, duplicate node module and stale artifacts
- direct_shader_ksampler: remove ParameterResponseMapper and its call site.
  Its only trigger, target_attribute_changes, is a V1 `hidden` tuple input,
  which ComfyUI never passes to a node, so the block was unreachable.
- advanced_comparer.py: an older duplicate of nodes/comparer.py that nothing
  imported (the live class is exported through nodes/__init__.py).
- web/types/*.js(.map): compiled leftovers of the type-only .ts declarations.
  ComfyUI loads web/**/*.js recursively, so these were served to the browser
  as extensions for no reason. The .ts sources stay.

All 11 legacy goldens, 64 generator smoke tests and 85 web tests still pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 15:17:21 -07:00
Æmotion Studio 3bfb894b96 fix: Adjust shader canvas drawing order to render on top of the node's title gradient. 2026-03-24 16:23:57 -07:00
Æmotion Studio ddf0fc0f83 feat: Add GLSL shader definitions and adjust gradient title drawing order to render as a background layer. 2026-03-24 16:10:10 -07:00
Æmotion Studio 8527a73958 fix: resolve 6 PR review issues - resource leaks, debug logs, normalize safety 2026-02-14 10:47:42 -08:00
Æmotion Studio cf372430fb fix: resolve PR review issues - smoothstep ordering and HSV hue wrapping 2026-02-14 10:35:07 -08:00
Æmotion Studio 1b2aae8260 fix: restore complete v260 GLSL shaders with Chromium compatibility 2026-02-14 10:26:29 -08:00
google-labs-jules[bot]andAEmotionStudio dfd2fe0611 feat(ux): improve accessibility for matrix modal and copy button
- Restore focus to main canvas when closing the matrix modal to support keyboard navigation
- Update aria-label to 'Copied' on copy button success to support screen readers
- Conditionally restore original aria-label to prevent overwriting on error

Co-authored-by: AEmotionStudio <163354043+AEmotionStudio@users.noreply.github.com>
2026-02-09 23:32:27 +00:00
google-labs-jules[bot]andAEmotionStudio 5fdd35ff05 feat(ux): improve accessibility for matrix modal and copy button
- Restore focus to main canvas when closing the matrix modal to support keyboard navigation
- Update aria-label to 'Copied' on copy button success to support screen readers
- Restore original aria-label after timeout

Co-authored-by: AEmotionStudio <163354043+AEmotionStudio@users.noreply.github.com>
2026-02-09 16:07:22 +00:00
AEmotionStudio b78538578b feat: Add server-side parameter saving API and changelog
- Add api_routes.py with POST /shader_noise_ksampler/save_params endpoint
- Update frontend to use fetch() API instead of browser download
- Register API routes with PromptServer in __init__.py
- Add CHANGELOG.md with version history
- Update README.md with navigation links and version 1.3.0
- Video comparer optimizations for memory efficiency
2026-01-29 23:53:29 -08:00
AEmotionStudio 7c4c806687 Fix shader imports and refactor video comparer
- Fix absolute imports in shaders/ to use relative paths
- Correct indentation in shader files
- Refactor video_comparer.py and nodes/video_comparer.py
- Add new example workflows
- Update gitignore and package.json
2026-01-29 17:44:22 -08:00
AEmotionStudio 50b37bea2c fix: Make TITLE_GRADIENT_COLORS module-private
Remove export keyword from TITLE_GRADIENT_COLORS since it's only used
internally by createTitleGradient() and never imported elsewhere.

All 85 tests pass.
2026-01-28 12:38:25 -08:00
AEmotionStudio ca4704bff0 fix: Address PR #41 review comments (round 7)
- Simplify redundant shimmer conditionals:
  Both branches called calculateShimmerPosition(1.0) identically.
  Now unconditionally compute shimmer, only cache lastTime conditionally.

- Use TITLE_CORNER_RADIUS constant:
  Replaced local 'const cornerRadius = 8' in both golden_eyeball.ts and
  gradient_title.ts with the shared TITLE_CORNER_RADIUS constant.

All 85 tests pass.
2026-01-28 12:02:31 -08:00
AEmotionStudio 829189e15e fix: Address PR #41 review comments (round 6)
- Remove debug console.log statements:
  - matrix_button.ts: 'MatrixButton module loaded'
  - video_comparer.ts: module load, widget constructor/setter, setup logs
  - shader_renderer.ts: 'ShaderRenderer module loaded'
  - advanced_comparer.ts: module load and setup complete logs

- Extract shared animation utilities to golden_eyeball.ts:
  - shouldUpdateFrame(): frame counter advancement
  - resetShadowContext(): context shadow property reset
  - createTitleGradient(): standard vertical background gradient
  - calculateShimmerPosition(): shimmer math calculation
  - TITLE_GRADIENT_COLORS: shared color constants
  - TITLE_CORNER_RADIUS: shared corner radius constant

- Refactor to use shared utilities:
  - gradient_title.ts now imports and uses shared utilities
  - golden_eyeball.ts drawGradientTitle uses its own exports

All 85 tests pass.
2026-01-28 04:26:42 -08:00
AEmotionStudio 00ba3bc17f fix: Address PR #41 review comments (round 5)
- Remove redundant Side-by-Side case in computeSize():
  The case set height = Math.max(500, width) which was identical to the
  default initialization, so it was effectively dead code.

- Extract resetButtonTimeout helper in copyCodeSection():
  Both success and error handlers had identical timeout reset logic.
  Consolidated into a single helper function, reducing ~25 lines.

All 85 tests pass.
2026-01-28 04:10:04 -08:00
AEmotionStudio a17ba641d5 fix: Address PR #41 review comments (round 4)
- Restore getExtraMenuOptions context menu in advanced_comparer.ts:
  - Layout Mode submenu with all 8 comparison modes
  - Reset to Default Size option
  - Consistent with video_comparer.ts implementation

- Create COMPARER_MODES constant to eliminate duplicate arrays:
  - Used in @comparer_mode property definition
  - Used in layoutWidget combo values
  - Used in context menu submenu

- Share AnimationCache type in gradient_title.ts:
  - Import AnimationCache from golden_eyeball.js
  - Remove duplicate RenderCache interface definition
  - Note: gradient_title.ts intentionally has its own drawGradientTitle
    for equation-styled titles (different visual from golden eyeball)

All 85 tests pass.
2026-01-28 03:56:07 -08:00
AEmotionStudio 1112364bb2 fix: Address PR #41 review comments (round 3)
- Add .js extension to local imports for browser ES module compatibility
  (./golden_eyeball → ./golden_eyeball.js, ./comfy_utils → ./comfy_utils.js)

- Remove unused api import from advanced_comparer.ts and video_comparer.ts
  (no longer needed since imageDataToUrl moved to comfy_utils)

- Remove unreachable dead code in gradient_title.ts
  (else branch was never reached due to early return for collapsed state)

All 85 tests pass.
2026-01-28 03:42:24 -08:00
AEmotionStudio 3dc9cc1b29 fix: Address PR #41 review comments (round 2)
- Remove export from drawGoldenEyeball (internal function only)
  Makes it a private implementation detail in golden_eyeball.ts

- Remove unused CACHE properties in video_comparer.ts:
  - titleCanvas, titleCtx, lastWidth, lastHeight, collapsed
  - Now only keeps frameCount, frameSkip, lastTime needed by AnimationCache
  - Remove dead cleanup code in onRemoved

- Extract shared imageDataToUrl utility:
  - Create new comfy_utils.ts module
  - Update advanced_comparer.ts to import shared function
  - Update video_comparer.ts to import shared function
  - Eliminates duplicated URL building logic

All 85 tests pass.
2026-01-28 03:26:52 -08:00
AEmotionStudio d8e7f48127 refactor: Extract shared golden eyeball rendering functions
- Create new golden_eyeball.ts module with:
  - drawGoldenEyeball: parameterized rayCount (8 for advanced, 6 for video)
  - drawGradientTitle: shared gradient background with animated eyeball
  - AnimationCache type for frame timing optimization

- Update advanced_comparer.ts:
  - Import shared functions from golden_eyeball.ts
  - Remove duplicate (~200 lines) drawGoldenEyeball and drawGradientTitle
  - Pass rayCount=8 for fuller eyeball effect

- Update video_comparer.ts:
  - Import shared functions from golden_eyeball.ts
  - Remove duplicate (~157 lines) drawGoldenEyeball and drawGradientTitle
  - Pass rayCount=6 for simpler eyeball effect

Addresses PR #41 review comments about code duplication across widget files.
Net reduction: ~350 lines of duplicated rendering code.
2026-01-28 03:01:34 -08:00
AEmotionStudio c9042f9571 refactor: Extract duplicated image scaling logic into helper method
- Add calculateScaledDimensions() private method to AdvancedImageComparerWidget
- Replace duplicated aspect ratio calculation in 5 draw methods:
  - drawImage
  - drawImageSideBySide
  - drawImageStacked
  - drawImageInCell
  - drawImageInPair

The helper calculates scaled dimensions to fit an image within usable area
while maintaining aspect ratio, eliminating ~15 lines of repeated logic.

Addresses PR #41 review comment about code duplication.
2026-01-28 02:39:30 -08:00
AEmotionStudio 50b21d6f12 fix: Remove dead code flagged in PR review #41 (additional)
- Remove unused 'last_y' property from AdvancedImageComparerWidget class
  (property was set but never read)
- Remove unused 'declare const app' statement in gradient_title.ts
- Simplify import handling: use direct 'import { app }' instead of alias

Files modified:
- web/src/advanced_comparer.ts
- web/src/gradient_title.ts
2026-01-28 02:02:52 -08:00
AEmotionStudio f0127c0ffc fix: Remove dead code flagged in PR review #41
- Remove unreachable else branch in drawGradientTitle that could never execute
  after early return for collapsed state (line 301-303)
- Remove hidden clearCacheButton debug widget that served no functional purpose
  (lines 768-771, also from interface)

Files modified:
- web/src/advanced_comparer.ts
2026-01-28 01:49:31 -08:00
AEmotionStudio b543ba3e98 fix: Remove unused CACHE properties flagged in PR review
- Remove unused titleCanvas, titleCtx, lastWidth, lastHeight,
  collapsed.canvas, collapsed.ctx, collapsed.lastWidth from CACHE
- Keep only animation-related properties: lastTime, frameCount, frameSkip
- Remove dead cleanup code in onRemoved that referenced removed properties
- Addresses PR #41 review comments (cursor[bot])

Files modified:
- web/src/gradient_title.ts
- web/src/advanced_comparer.ts
2026-01-28 01:35:04 -08:00
AEmotionStudio 1b59dc2ac8 feat: Complete TypeScript migration with 85 unit tests
- Migrate 7 JavaScript files to TypeScript with full type annotations
- Add TypeScript infrastructure: tsconfig.json, package.json, vitest.config.ts
- Add type declarations for ComfyUI and LiteGraph APIs (web/types/)
- Add comprehensive test suite with Vitest:
  - noise_visualizer.test.ts (29 tests) - Canvas rendering methods
  - matrix_button.test.ts (19 tests) - Window utilities
  - integration.test.ts (16 tests) - Extension registration
  - shader_rendering.test.ts (21 tests) - WebGL pipeline
- Add test mocks for Canvas 2D, WebGL, and ComfyUI APIs
- Update .gitignore to track TypeScript sources

Files migrated:
- gradient_title.ts (245 lines)
- shader_params_save_button.ts (540 lines)
- noise_visualizer.ts (1,578 lines)
- advanced_comparer.ts (905 lines, optimized from 1,772)
- shader_renderer.ts (615 lines, optimized from 2,396)
- video_comparer.ts (1,179 lines, optimized from 2,402)
- matrix_button.ts (3,360 lines, fully typed)
2026-01-28 01:00:10 -08:00
google-labs-jules[bot] 5b2c5868bc 🎨 Palette: Improve modal accessibility and copy feedback
💡 What:
- Exposed the `showToast` utility from `web/shader_params_save_button.js` as `window.showComfyToast`.
- Updated `web/matrix_button.js` to use `window.showComfyToast` for the "Copy Code" feedback.
- Added `:focus-visible` styles to the "Shader Matrix" modal buttons and tabs.

🎯 Why:
- To provide consistent and delightful feedback when copying code snippets.
- To improve accessibility for keyboard users by making focus states clearly visible.

📸 Before/After:
- Before: Copy button text changed to "Copied!". No visible focus ring on dark modal buttons.
- After: "Code copied to clipboard!" toast appears. Interactive elements have a bright purple focus ring.

♿ Accessibility:
- Added `:focus-visible` outline styles using the theme's accent color.
2026-01-24 07:19:36 +00:00
google-labs-jules[bot] 56f05b1794 🎨 Palette: Add Toast Notification for Shader Params Save
💡 What: Replaced subtle button text changes and console logs with a Toast notification system for the "Save Shader Parameters" button.
🎯 Why: Users need clear, accessible feedback when saving parameters to know if the action succeeded or failed. The previous method was easy to miss.
📸 Verification: Verified via Playwright script `verify_toast.py` with mock environment. Screenshot confirms visibility and styling.
♿ Accessibility: Included `role='alert'` and high-contrast styling for the notifications.
🔧 Fixes:
- Addressed potential zombie process in verification script.
- Added fallback cleanup for toast elements if CSS transitions are disabled.
- Fixed event listener memory leak in toast fallback.
- Standardized fallback logic in test environment.
2026-01-23 09:22:55 +00:00
google-labs-jules[bot] c5c3c226f2 🎨 Palette: Add Toast Notification for Shader Params Save
💡 What: Replaced subtle button text changes and console logs with a Toast notification system for the "Save Shader Parameters" button.
🎯 Why: Users need clear, accessible feedback when saving parameters to know if the action succeeded or failed. The previous method was easy to miss.
📸 Verification: Verified via Playwright script `verify_toast.py` with mock environment. Screenshot confirms visibility and styling.
♿ Accessibility: Included `role='alert'` and high-contrast styling for the notifications.
🔧 Fixes:
- Addressed potential zombie process in verification script.
- Added fallback cleanup for toast elements if CSS transitions are disabled.
2026-01-23 09:09:22 +00:00
google-labs-jules[bot] ffbfe9bfcd 🎨 Palette: Add Toast Notification for Shader Params Save
💡 What: Replaced subtle button text changes and console logs with a Toast notification system for the "Save Shader Parameters" button.
🎯 Why: Users need clear, accessible feedback when saving parameters to know if the action succeeded or failed. The previous method was easy to miss.
📸 Verification: Verified via Playwright script `verify_toast.py` with mock environment. Screenshot confirms visibility and styling.
♿ Accessibility: Included `role='alert'` and high-contrast styling for the notifications.
2026-01-23 07:19:10 +00:00
google-labs-jules[bot] dbeeeaf4e3 feat(ux): add keyboard focus trap to Shader Matrix modal
- Implements a `keydown` listener on the modal to intercept Tab and Shift+Tab key presses.
- Dynamically queries visible focusable elements (`button`, `input`, etc.) that have a valid `offsetParent`.
- Loops focus between the first and last focusable elements to prevent keyboard users from tabbing out of the modal into obscured content.
- Enhances accessibility for screen reader and keyboard-only users.
2026-01-22 07:17:55 +00:00
google-labs-jules[bot] 4378caadaf feat(a11y): fix acronym capitalization in aria-labels
Updated the noise name generation logic to correctly capitalize 'FBM' and '3D' acronyms in aria-labels, ensuring consistency with the UI titles and better screen reader experience.
2026-01-21 08:33:03 +00:00
google-labs-jules[bot] 0fd5e2640b feat(a11y): add role=img and aria-label to noise visualization canvases
Enhance accessibility for the noise visualization modal by:
- Adding `role="img"` to all generated canvas elements.
- Adding descriptive `aria-label` attributes derived from the noise type ID (e.g., "Visualization of Perlin noise pattern").
- This ensures screen reader users perceive these visualizations as images with meaningful descriptions rather than empty, untagged content.

Verified with `verification/verify_canvas_a11y.js` which mocks the DOM environment.
2026-01-21 07:38:52 +00:00
google-labs-jules[bot] edd8e630ea 🎨 Palette: Add Copy to Clipboard button for code blocks
- Added `window.copyCodeSection` helper in `web/matrix_button.js`.
- Updated documentation modal HTML to include "Copy" buttons next to "Show" buttons for all code examples.
- Added CSS for `.button-group` and `.copy-code-button` with hover and success states.
- Implemented robust error handling for clipboard access and success/error feedback loops.
- Fixed race condition in button state reset by using explicit string "Copy" and clearing timeouts.
- Restored `verification/verify_dos_fix.py` which was inadvertently deleted.
- Hardened error handler to clean up state and manage timeouts correctly.
2026-01-20 08:22:38 +00:00
google-labs-jules[bot] f3214779ef 🎨 Palette: Add Copy to Clipboard button for code blocks
- Added `window.copyCodeSection` helper in `web/matrix_button.js`.
- Updated documentation modal HTML to include "Copy" buttons next to "Show" buttons for all code examples.
- Added CSS for `.button-group` and `.copy-code-button` with hover and success states.
- Implemented robust error handling for clipboard access and success/error feedback loops.
- Fixed race condition in button state reset by using explicit string "Copy" and clearing timeouts.
- Restored `verification/verify_dos_fix.py` which was inadvertently deleted.
2026-01-20 08:04:40 +00:00
google-labs-jules[bot] 622c14bb45 🎨 Palette: Add Copy to Clipboard button for code blocks
- Added `window.copyCodeSection` helper in `web/matrix_button.js`.
- Updated documentation modal HTML to include "Copy" buttons next to "Show" buttons for all code examples.
- Added CSS for `.button-group` and `.copy-code-button` with hover and success states.
- Implemented robust error handling for clipboard access and success/error feedback loops.
- Restored `verification/verify_dos_fix.py` which was inadvertently deleted.
2026-01-20 07:27:57 +00:00
google-labs-jules[bot] 5683211dfe Improve accessibility of documentation modal navigation logic 2026-01-19 07:31:17 +00:00
google-labs-jules[bot] 87a52a7207 🎨 Palette: Improve Scroll-to-Top Accessibility 2026-01-18 07:25:13 +00:00
google-labs-jules[bot] 23ca91e5d9 feat(ux): add accessibility attributes to code toggle buttons
- Add `aria-expanded` and `aria-controls` to code block toggle buttons in `web/matrix_button.js`.
- Add unique IDs to collapsible code `pre` blocks.
- Update `toggleCodeSection` to dynamically toggle `aria-expanded` state.
- Improve screen reader support for the Shader Matrix modal.
2026-01-17 07:37:37 +00:00
Æmotion Studio 473c6e3232 Merge pull request #14 from AEmotionStudio/sentinel-url-encoding-fix-10896124739983365592
🛡️ Sentinel: [HIGH] Fix parameter injection vulnerability in frontend extensions
2026-01-15 23:42:38 -08:00
google-labs-jules[bot] 6c5c7d6c33 🛡️ Sentinel: [HIGH] Fix parameter injection vulnerability in frontend extensions
🚨 Severity: HIGH
💡 Vulnerability: User-controlled input in `subfolder` and `type` parameters was concatenated directly into API URLs without encoding in `web/video_comparer.js` and `web/advanced_comparer.js`.
🎯 Impact: This could allow parameter injection or result in broken URLs if filenames/subfolders contain special characters.
🔧 Fix: Wrapped `type` and `subfolder` parameters with `encodeURIComponent` when constructing the `view` API URL.
✅ Verification: Manual verification of the code.
2026-01-16 07:35:06 +00:00
google-labs-jules[bot] ee6e41b2b3 🎨 Palette: Make Shader Matrix tabs keyboard accessible
Add full ARIA support and keyboard navigation (Arrow keys, Enter/Space) to the documentation tabs in the Shader Matrix modal.

- Add `role="tablist"`, `role="tab"`, `role="tabpanel"`.
- Implement roving `tabindex` and `aria-selected` management.
- Add `window.handleTabNavigation` to support Arrow Left/Right navigation between tabs.
- Ensure visual focus order matches logical tab order.
2026-01-16 07:21:27 +00:00
google-labs-jules[bot] ea2f7407ff 🎨 Palette: Improve accessibility of Shader Matrix modal
- Added `role="dialog"`, `aria-modal="true"`, and `aria-label` to the modal container.
- Added `aria-label` to the icon-only "Close" and "Scroll to top" buttons.
- Implemented initial focus management to set focus on the "Close" button when the modal opens.

These changes ensure screen reader users can correctly identify the modal and navigate its controls.
2026-01-15 07:05:26 +00:00
Æmotion d32b5d8392 Enhanced Advanced Image Comparer for improved display and layout. Implemented aggressive resizing logic to ensure prominent image visibility, adjusted minimum size requirements, and refined padding for better image presentation. Added clipping for images to prevent overlap and optimized layout controls for various modes. 2025-09-02 01:08:41 -07:00
Æmotion 5e9b8d8af7 widget fixes for advanced comparer and video comparer 2025-06-20 01:41:49 -07:00
Æmotion 8245166117 Improved Memory Management for Video Comparer and Fixed JSON Issue 2025-06-13 19:45:03 -07:00
Æmotion 6b005381e0 Added Auto-Fill Function for Comparers 2025-06-12 19:50:25 -07:00