Animate the empty orders state in and make its CTA more inviting

Fades/slides the empty state in on mount, gives the icon a tinted
circle badge instead of a bare stroke icon, and gives the "Browse the
menu" button a shadow, hover lift, and a shifting arrow instead of a
flat opacity hover.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-13 20:07:39 +02:00
co-authored by Claude Sonnet 5
parent f4f3c26e1e
commit c5ed038bca
2 changed files with 57 additions and 7 deletions
@@ -10,6 +10,17 @@
margin: 0 0 $space-4; margin: 0 0 $space-4;
} }
@keyframes empty-state-enter {
from {
opacity: 0;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.empty { .empty {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -21,11 +32,25 @@
border-radius: $radius; border-radius: $radius;
background: $color-surface; background: $color-surface;
svg { @media (prefers-reduced-motion: no-preference) {
width: 2.5rem; animation: empty-state-enter 0.32s cubic-bezier(0.2, 0, 0, 1) both;
height: 2.5rem; }
}
.emptyIcon {
display: flex;
align-items: center;
justify-content: center;
width: 3.5rem;
height: 3.5rem;
margin-bottom: $space-2; margin-bottom: $space-2;
color: $color-text-muted; border-radius: 999px;
background: color-mix(in srgb, $color-primary 12%, transparent);
svg {
width: 1.75rem;
height: 1.75rem;
color: $color-primary;
} }
} }
@@ -41,17 +66,37 @@
} }
.emptyCta { .emptyCta {
display: inline-flex;
align-items: center;
gap: $space-1;
padding: $space-2 $space-4; padding: $space-2 $space-4;
border-radius: $radius; border-radius: $radius;
background: $color-primary; background: $color-primary;
color: $color-primary-contrast; color: $color-primary-contrast;
font-weight: 600; font-weight: 600;
text-decoration: none; text-decoration: none;
transition: opacity 0.15s ease; box-shadow: 0 2px 8px color-mix(in srgb, $color-primary 35%, transparent);
transition:
transform 0.15s ease,
box-shadow 0.15s ease;
&:hover { &:hover {
opacity: 0.9; transform: translateY(-2px);
box-shadow: 0 6px 16px color-mix(in srgb, $color-primary 45%, transparent);
} }
&:active {
transform: translateY(0);
box-shadow: 0 2px 8px color-mix(in srgb, $color-primary 35%, transparent);
}
}
.emptyCtaArrow {
transition: transform 0.15s ease;
}
.emptyCta:hover .emptyCtaArrow {
transform: translateX(3px);
} }
.orders { .orders {
+5
View File
@@ -64,13 +64,18 @@ export const OrdersListView = ({ orders }: OrdersListViewProps) => {
<h1 className={styles.heading}>Your orders</h1> <h1 className={styles.heading}>Your orders</h1>
{displayedOrders.length === 0 ? ( {displayedOrders.length === 0 ? (
<div className={styles.empty}> <div className={styles.empty}>
<div className={styles.emptyIcon}>
<OrdersIcon /> <OrdersIcon />
</div>
<p className={styles.emptyTitle}>No orders yet</p> <p className={styles.emptyTitle}>No orders yet</p>
<p className={styles.emptyText}> <p className={styles.emptyText}>
Your placed orders will show up here. Your placed orders will show up here.
</p> </p>
<Link to="/" className={styles.emptyCta}> <Link to="/" className={styles.emptyCta}>
Browse the menu Browse the menu
<span className={styles.emptyCtaArrow} aria-hidden="true">
→
</span>
</Link> </Link>
</div> </div>
) : ( ) : (