fix(badges): use direct token classes for field_actions buttons

btn + preset-filled-* renders transparent on gray/surface backgrounds
(Skeleton v4 CSS variable specificity issue — documented in
GUIDE__AE_UI_Style_Guidelines.md §12).

Replace all three buttons in field_actions (Save, Revert, Cancel) with
direct Tailwind token classes: bg-warning-500, bg-error-500,
bg-success-500, bg-surface-200-800 etc. Save button now visibly renders
in amber (dirty), red + pulse (pending_close), green (saved).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-04-14 17:19:03 -04:00
parent 0199c2e2c9
commit a68b85e1f1

View File

@@ -918,11 +918,16 @@ let allow_tracking_open = $derived(
)}
{@const status = field_save_status[field_key]}
{@const save_visible = is_dirty || (status && status !== 'idle')}
<!-- btn + preset-filled-* goes transparent on gray/surface backgrounds (Skeleton v4
CSS variable specificity issue — see GUIDE__AE_UI_Style_Guidelines.md §12).
Use direct Tailwind token classes for all three buttons here. -->
<div class="mt-2 flex gap-2">
<!-- Revert: always occupies left slot; invisible when no override exists -->
<button
type="button"
class="btn btn-sm preset-tonal-warning shrink-0"
class="flex h-8 shrink-0 cursor-pointer items-center justify-center rounded-lg px-2
bg-warning-500/15 text-warning-700 dark:text-warning-300
hover:bg-warning-500/30 transition-colors"
class:invisible={!on_revert}
class:pointer-events-none={!on_revert}
onclick={on_revert}
@@ -936,18 +941,16 @@ let allow_tracking_open = $derived(
to close while dirty. They must save OR press X again to discard. -->
<button
type="button"
class="btn btn-sm flex-1 transition-colors"
class="flex h-8 flex-1 cursor-pointer items-center justify-center gap-1
rounded-lg px-3 text-sm font-semibold text-white transition-colors
disabled:cursor-not-allowed disabled:opacity-50"
class:invisible={!save_visible}
class:pointer-events-none={!save_visible}
class:preset-filled-error={pending_close && is_dirty && (!status || status === 'idle')}
class:bg-error-500={(pending_close && is_dirty && (!status || status === 'idle')) || (status === 'error' && !pending_close)}
class:animate-pulse={pending_close && is_dirty && (!status || status === 'idle')}
class:preset-filled-warning={!pending_close &&
save_visible &&
is_dirty &&
(!status || status === 'idle')}
class:preset-tonal-surface={status === 'saving'}
class:preset-filled-success={status === 'done'}
class:preset-tonal-error={status === 'error' && !pending_close}
class:bg-warning-500={!pending_close && save_visible && is_dirty && (!status || status === 'idle')}
class:bg-surface-400={status === 'saving'}
class:bg-success-500={status === 'done'}
disabled={!save_visible || status === 'saving'}
tabindex={save_visible ? 0 : -1}
onclick={on_save}
@@ -955,25 +958,27 @@ let allow_tracking_open = $derived(
aria-label="Save changes"
aria-hidden={!save_visible}>
{#if status === 'saving'}
<LoaderCircle size="14" class="mr-1 animate-spin" /> Saving…
<LoaderCircle size="14" class="animate-spin" /> Saving…
{:else if status === 'done'}
<Check size="14" class="mr-1" /> Saved
<Check size="14" /> Saved
{:else if status === 'error' && !pending_close}
Error — retry
{:else if pending_close}
Save first (or × to discard)
{:else}
<Check size="14" class="mr-1" /> Save
<Check size="14" /> Save
{/if}
</button>
<!-- Cancel: always visible at right end.
When pending_close is active the label changes to "Discard" so the
user knows a second tap will throw away their edit. -->
When pending_close is active, turns red so the user knows
a second tap will actually discard their edit. -->
<button
type="button"
class="btn btn-sm"
class:preset-tonal-surface={!pending_close}
class:preset-tonal-error={pending_close}
class="flex h-8 cursor-pointer items-center justify-center rounded-lg px-2 transition-colors"
class:bg-surface-200-800={!pending_close}
class:hover:bg-surface-300-700={!pending_close}
class:bg-error-500={pending_close}
class:text-white={pending_close}
onclick={on_cancel}
title={pending_close ? 'Discard changes' : 'Cancel'}
aria-label={pending_close ? 'Discard changes' : 'Cancel editing'}>