polish(wardrobe): make Try-On CTA the dominant element + shrink secondary actions

Feedback from the latest screenshot: on the dark workbench theme the
earlier "lift + shadow" polish was too subtle — the Try-On button
read as equal weight to "Heute getragen" / "Archivieren" / "Löschen",
so it didn't telegraph "this is THE action on the page". The
primary-tinted shadow I used (shadow-primary/20) didn't have enough
contrast against the dark card.

Stronger visual hierarchy:

- CTA bumps to rounded-xl + px-6 py-4 + text-lg + font-semibold (was
  rounded-lg + px-5 py-3.5 + text-base + font-medium).
- At rest: neutral shadow-lg + primary/40 ring-2 so the button has a
  visible glow on both dark and light themes (neutral shadow works
  regardless of bg contrast; the primary ring carries the accent).
- Hover: lift -translate-y-0.5 + shadow-xl + ring-4 at primary/50.
- Active-press: back to baseline (translate-y-0, shadow-md, ring-2)
  for tactile feedback.
- Sparkle icon 18 → 20; gap tightens to 2.5.
- Applied identically to both GarmentTryOnButton + TryOnButton so
  solo and outfit surfaces share the same CTA weight.

Secondary-action row collapses from three equal full-width buttons
into one labelled button + two icon-only buttons:

- "Heute getragen" keeps the full label and takes the remaining row
  width — it's the frequent positive action.
- "Archivieren" + "Löschen" shrink to 36×36 icon buttons with
  tooltips (aria-label + title) carrying the full label. Archive
  uses the primary-tinted hover; Löschen keeps its destructive-red
  hover.

Net effect: the Try-On CTA is now clearly the loudest element on the
page, Heute-getragen sits cleanly below as a secondary action, and
Archive/Löschen recede to minimal icon-only controls — no more
visual competition with the primary CTA.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-24 16:35:18 +02:00
parent 91ae58f2af
commit e7398b2dee
3 changed files with 45 additions and 37 deletions

View file

@ -163,26 +163,30 @@
disabled={running}
/>
<!-- Primary CTA: lifted + shadowed so it reads as the most
important action on the page. Hover raises the button
subtly (translate + stronger shadow); active-press sinks
it back flat for tactile feedback. -->
<!-- Primary CTA: the biggest, loudest element on the page.
Rests with a visible ring + shadow so the user instantly
sees "this is THE action" without hovering. Hover lifts
the button by 1px and strengthens the ring; active-press
sinks back to 0 for a tactile feel. Shadow uses neutral
black (works across light + dark + tinted themes), ring
uses the primary color at 40 % for visible glow even on
a dark card background. -->
<button
type="button"
onclick={handleClick}
disabled={running || !canTryOn}
class="flex w-full flex-col items-center justify-center gap-0.5 rounded-lg bg-primary px-5 py-3.5 text-base font-semibold text-primary-foreground shadow-md shadow-primary/20 transition-all hover:-translate-y-0.5 hover:bg-primary/95 hover:shadow-lg hover:shadow-primary/30 active:translate-y-0 active:shadow-sm disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:translate-y-0 disabled:hover:shadow-md"
class="flex w-full flex-col items-center justify-center gap-1 rounded-xl bg-primary px-6 py-4 text-lg font-semibold text-primary-foreground shadow-lg ring-2 ring-primary/40 transition-all hover:-translate-y-0.5 hover:bg-primary/95 hover:shadow-xl hover:ring-4 hover:ring-primary/50 active:translate-y-0 active:shadow-md active:ring-2 disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:translate-y-0 disabled:hover:shadow-lg disabled:hover:ring-2"
>
{#if running}
<span class="flex items-center gap-2">
<span class="flex items-center gap-2.5">
<span
class="h-5 w-5 animate-spin rounded-full border-2 border-current border-r-transparent"
></span>
Rendere…
</span>
{:else}
<span class="flex items-center gap-2">
<Sparkle size={18} weight="fill" />
<span class="flex items-center gap-2.5">
<Sparkle size={20} weight="fill" />
An mir anprobieren
</span>
<span class="text-xs font-normal opacity-80">{estimatedCredits} Credits</span>

View file

@ -160,25 +160,26 @@
disabled={running}
/>
<!-- Primary CTA: matches GarmentTryOnButton's lift + shadow
treatment so both surfaces use the same visual weight for
"produce the generation". -->
<!-- Primary CTA — matches GarmentTryOnButton's lift + ring +
shadow treatment so both surfaces use the same visual
weight for "produce the generation". See that file for
the full rationale on ring / shadow / translate choices. -->
<button
type="button"
onclick={handleClick}
disabled={running || !canTryOn}
class="flex w-full flex-col items-center justify-center gap-0.5 rounded-lg bg-primary px-5 py-3.5 text-base font-semibold text-primary-foreground shadow-md shadow-primary/20 transition-all hover:-translate-y-0.5 hover:bg-primary/95 hover:shadow-lg hover:shadow-primary/30 active:translate-y-0 active:shadow-sm disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:translate-y-0 disabled:hover:shadow-md"
class="flex w-full flex-col items-center justify-center gap-1 rounded-xl bg-primary px-6 py-4 text-lg font-semibold text-primary-foreground shadow-lg ring-2 ring-primary/40 transition-all hover:-translate-y-0.5 hover:bg-primary/95 hover:shadow-xl hover:ring-4 hover:ring-primary/50 active:translate-y-0 active:shadow-md active:ring-2 disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:translate-y-0 disabled:hover:shadow-lg disabled:hover:ring-2"
>
{#if running}
<span class="flex items-center gap-2">
<span class="flex items-center gap-2.5">
<span
class="h-5 w-5 animate-spin rounded-full border-2 border-current border-r-transparent"
></span>
Rendere…
</span>
{:else}
<span class="flex items-center gap-2">
<Sparkle size={18} weight="fill" />
<span class="flex items-center gap-2.5">
<Sparkle size={20} weight="fill" />
Anprobieren
</span>
<span class="text-xs font-normal opacity-80">{estimatedCredits} Credits</span>

View file

@ -234,37 +234,40 @@
<!-- Try-on — "wie sähe das an mir aus" -->
<GarmentTryOnButton {garment} />
<!-- Wear-tracking — same primary-tinted hover as edit /
model picker / try-on thumbs. -->
<button
type="button"
onclick={handleMarkWorn}
disabled={markingWorn}
class="flex w-full items-center justify-center gap-2 rounded-md border border-border bg-background px-4 py-2 text-sm text-foreground transition-colors hover:border-primary/50 hover:bg-primary/5 disabled:opacity-50 disabled:hover:border-border disabled:hover:bg-background"
>
<CheckCircle size={14} />
{markingWorn ? 'Gespeichert…' : 'Heute getragen'}
</button>
<!-- Secondary actions. Archive keeps the primary-tint hover;
Löschen stays destructive-red so the action reads as
dangerous even at a glance. -->
<!-- Secondary-action row: "Heute getragen" is the frequent
positive action and takes most of the width; Archive and
Löschen shrink to icon-only buttons on the right so they
stop competing with the primary CTA for attention. All
three share the primary-tinted hover; Löschen keeps its
destructive-red tint. Tooltips (title+aria-label) carry
the full label for discoverability. -->
<div class="flex gap-2">
<button
type="button"
onclick={handleArchive}
class="flex flex-1 items-center justify-center gap-2 rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground transition-colors hover:border-primary/50 hover:bg-primary/5"
onclick={handleMarkWorn}
disabled={markingWorn}
class="flex flex-1 items-center justify-center gap-2 rounded-md border border-border bg-background px-4 py-2 text-sm text-foreground transition-colors hover:border-primary/50 hover:bg-primary/5 disabled:opacity-50 disabled:hover:border-border disabled:hover:bg-background"
>
<Archive size={14} />
{garment.isArchived ? 'Wieder aktiv' : 'Archivieren'}
<CheckCircle size={14} />
{markingWorn ? 'Gespeichert…' : 'Heute getragen'}
</button>
<button
type="button"
onclick={handleArchive}
aria-label={garment.isArchived ? 'Wieder aktiv setzen' : 'Archivieren'}
title={garment.isArchived ? 'Wieder aktiv setzen' : 'Archivieren'}
class="flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-md border border-border bg-background text-muted-foreground transition-colors hover:border-primary/50 hover:bg-primary/5 hover:text-foreground"
>
<Archive size={16} />
</button>
<button
type="button"
onclick={handleDelete}
class="flex flex-1 items-center justify-center gap-2 rounded-md border border-border bg-background px-3 py-2 text-sm text-error transition-colors hover:border-error/50 hover:bg-error/10"
aria-label="Löschen"
title="Löschen"
class="flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-md border border-border bg-background text-error transition-colors hover:border-error/50 hover:bg-error/10"
>
<Trash size={14} />
Löschen
<Trash size={16} />
</button>
</div>
{/if}