Buttons were egui's plain one, a fill set by hand where one had to stand out (a dialog's confirm,
About's Discord link), with no hover or press shade on a filled one and no shared sizes.
- `crate::button::Button`: what it is for (`Kind`: Primary filled with the accent, Secondary
with a neutral fill and a border, Danger filled red, Ghost with no fill until hovered), how
big (`Size`: Small 24, Medium 30, Large 36 points, each with its padding, text and icon size),
and what it shows (text, an icon before the text, or an icon alone, which takes a name for
screen readers and its tooltip).
- Hover and press darken it; disabled (or in a disabled part of the window) fades it and takes
no click, its tooltip or name still shown; a focused one shows an accent ring. A filled kind's
fill is darkened as little as needed for white to read at 4.5:1 (the light themes' accent and
the red would be too pale), in every state. Drawn within its own rectangle.
- Named for screen readers, registered for scripts and tests (`.widget(id)`). Its egui id comes
from the widget id (salted with `.id_salt`, e.g. the dialog's kind, so the keyboard's place
doesn't carry from one dialog to the next) or from its place in the ui, moved on so buttons
with the same text side by side stay apart.
- Dialogs' footers (Cancel, the confirm; at least 72 points wide) and About's Discord link use
it. The Export dialog's expected height in `tests_dialog_fit` grows by the 8 points of its
footer's 30-point buttons.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A design critique of the first run found the import review's "Import N Photos" a plain button at
the bottom left beside Cancel, though the welcome before it had taught that blue means go.
- Every dialog's footer is right-aligned: the confirm on the right, Cancel to its left, added in
that order so the keyboard goes through them as the eye does. The row spans the width the
window gives its content this frame, so it reaches the window's edge without widening it.
- The confirm is filled with the accent when it makes or brings in something (`confirm_style`);
Delete and Remove, and an informational dialog's Close, stay plain. Which dialogs only show
something is one list (`only_shows`).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Treat a zero-width feather transition as a hard edge so exact-radius pixels remain unchanged, including at zero opacity. Add actual image regressions for all spot modes, image corners and two clone output sizes.
Validation: both new regressions failed on the original implementation and pass here. Formatting, workspace Clippy, HEIF and a generated-photo app smoke test pass. The unfiltered workspace gate remains blocked by the existing all-masks overlay test tracked by #1599; later parity, layers, assets and WASM stages are pending. This is a source checkpoint, not a green release candidate.
Contributor: @eliets2