Add menu item customization/detail pages and configurable currency formatting

Lets customers pick options on a menu item detail page before adding to the
basket, and makes displayed prices respect a configurable currency/locale
via VITE_CURRENCY/VITE_LOCALE. Also crossfades the basket's empty/filled
states with AnimatePresence in wait mode instead of animating both at once.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-10 21:00:45 +02:00
co-authored by Claude Sonnet 5
parent e98b0d86d2
commit d66e09f515
38 changed files with 2099 additions and 229 deletions
@@ -1,5 +1,13 @@
@use '../../styles/variables' as *;
@position-try --cancel-hint-flip {
position-area: bottom;
--hint-arrow-top: auto;
--hint-arrow-bottom: 100%;
--hint-arrow-color-top: transparent;
--hint-arrow-color-bottom: #{$color-text};
}
.page {
max-width: 720px;
margin: 0 auto;
@@ -36,11 +44,17 @@
}
.orderStatus {
margin: 0 0 $space-4;
margin: 0 0 $space-1;
color: $color-text-muted;
text-transform: capitalize;
}
.orderDate {
margin: 0 0 $space-4;
color: $color-text-muted;
font-size: 0.85rem;
}
.error {
color: $color-danger;
}
@@ -73,6 +87,12 @@
color: $color-text-muted;
}
.itemOptions {
margin: 0 0 $space-2;
font-size: 0.85rem;
color: $color-text-muted;
}
.timeline {
margin: 0 0 $space-2;
padding: 0;
@@ -194,6 +214,7 @@
.actions {
display: flex;
flex-wrap: wrap;
gap: $space-2;
align-items: center;
@@ -206,6 +227,11 @@
color: $color-text;
text-decoration: none;
cursor: pointer;
transition: border-color 0.15s ease;
&:hover:not(:disabled) {
border-color: $color-primary;
}
&:disabled {
opacity: 0.5;
@@ -213,6 +239,66 @@
}
}
.infoButton {
display: inline-flex;
align-items: center;
flex-shrink: 0;
gap: $space-1;
padding: $space-1 $space-2;
color: $color-text-muted;
font-size: 0.85rem;
white-space: nowrap;
&:hover:not(:disabled) {
color: $color-primary;
border-color: $color-primary;
}
}
.infoIcon {
width: 1rem;
height: 1rem;
flex-shrink: 0;
}
.cancelHint {
position: fixed;
position-area: top;
position-try-fallbacks: --cancel-hint-flip;
inset: auto;
overflow: visible;
height: auto;
margin: $space-2;
padding: $space-2 $space-3;
width: max-content;
max-width: 260px;
border: none;
border-radius: $radius;
background: $color-text;
color: $color-background;
font-size: 0.8rem;
line-height: 1.4;
text-align: left;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
--hint-arrow-top: 100%;
--hint-arrow-bottom: auto;
--hint-arrow-color-top: #{$color-text};
--hint-arrow-color-bottom: transparent;
&::after {
content: '';
position: absolute;
left: 50%;
top: var(--hint-arrow-top);
bottom: var(--hint-arrow-bottom);
transform: translateX(-50%);
border: 6px solid transparent;
border-top-color: var(--hint-arrow-color-top);
border-bottom-color: var(--hint-arrow-color-bottom);
}
}
.cancelButton {
padding: $space-1 $space-2;
border: none;