/* =============================================================================
   Self-Kiosk design system
   =============================================================================
   Every colour, radius and font below resolves through a CSS custom property
   (--kiosk-*) with a sane fallback. The real values are pushed at runtime by
   KioskLayout.razor from the theme the Internal app's "Bestellterminal-
   Oberfläche" admin page (TerminalUiPanel.razor → TerminalUiTheme) manages —
   so staff can restyle every kiosk in the fleet without touching this file or
   redeploying the app. The fallbacks here only matter before that theme has
   loaded (Pairing screen, first paint of Attract).
   ============================================================================= */

:root {
    --kiosk-primary: #ff7a1a;
    --kiosk-primary-text: #ffffff;
    --kiosk-accent: #e8590c;
    --kiosk-bg: #ffffff;
    --kiosk-surface: #ffffff;
    --kiosk-text: #1a1a1a;
    --kiosk-muted: #6b6b70;
    --kiosk-border: #ececef;
    --kiosk-success: #2e9e5b;
    --kiosk-danger: #d9364a;
    --kiosk-radius-btn: 999px;
    --kiosk-radius-card: 24px;
    --kiosk-font: 'Plus Jakarta Sans', 'Segoe UI', system-ui, sans-serif;

    /* Single source of truth for the fixed bottom cart bar's height, so the
       scrollable/flex content areas above it (.menu-main, .menu-main-minimal)
       always reserve exactly enough space — never more (wasted space) and
       never less (content hidden behind the bar). */
    --kiosk-bottom-bar-height: 12vh;

    /* Derived, not configurable individually — always in sync with the two
       colours staff actually control, so hover/active states never drift out
       of the brand palette (see the button-states design guidance). */
    --kiosk-primary-hover: color-mix(in srgb, var(--kiosk-primary) 88%, black);
    --kiosk-primary-active: color-mix(in srgb, var(--kiosk-primary) 78%, black);
    --kiosk-surface-hover: color-mix(in srgb, var(--kiosk-surface) 96%, black);
    --kiosk-surface-active: color-mix(in srgb, var(--kiosk-surface) 90%, black);

    /* Subtle, warm-tinted "page" colour behind the white cards — Material-style tonal
       separation without resorting to a grey that would read as dull/dated. */
    --kiosk-canvas: #fbf8f5;

    /* Soft, diffuse Material-style elevation — never the harsh dark-mode drop-shadows of a
       black surface, which would look like a smudge on a white card. */
    --kiosk-shadow-sm: 0 1px 3px rgba(20, 15, 10, 0.06), 0 1px 2px rgba(20, 15, 10, 0.08);
    --kiosk-shadow-md: 0 4px 16px rgba(20, 15, 10, 0.08), 0 2px 6px rgba(20, 15, 10, 0.06);
    --kiosk-shadow-lg: 0 16px 48px rgba(20, 15, 10, 0.16), 0 4px 12px rgba(20, 15, 10, 0.08);

    --kiosk-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --kiosk-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

*, *::before, *::after {
    box-sizing: border-box;
}

html, body {
    height: 100%;
    margin: 0;
    padding: 0;
    background: var(--kiosk-bg);
    color: var(--kiosk-text);
    font-family: var(--kiosk-font);
    overflow: hidden; /* kiosk: no page scroll chrome */
    -ms-content-zooming: none;
    touch-action: manipulation; /* large touch targets, no accidental double-tap zoom */
    -webkit-user-select: none;
    user-select: none; /* a public kiosk has no use for text selection handles */
}

/* A public kiosk has no mouse, so a visible scrollbar track/thumb is just visual noise —
   every scrollable panel below still scrolls fine via touch/swipe, just without OS chrome. */
* {
    scrollbar-width: none;
}

*::-webkit-scrollbar {
    display: none;
}

.kiosk-shell {
    height: 100vh;
    width: 100vw;
    display: flex;
    flex-direction: column;
    position: relative;
    background: var(--kiosk-canvas);
}

#blazor-error-ui {
    background: var(--kiosk-primary);
    color: var(--kiosk-primary-text);
    bottom: 0;
    box-shadow: var(--kiosk-shadow-md);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

/* -----------------------------------------------------------------------
   Page transitions — every route change replays a gentle fade + rise, never
   a hard cut. Keyed on the URL in KioskLayout.razor so this animation
   actually restarts on navigation instead of running once at first paint.
----------------------------------------------------------------------- */

.page-transition {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-height: 0;
    animation: page-enter 320ms var(--kiosk-ease-out) both;
}

@keyframes page-enter {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* -----------------------------------------------------------------------
   Toast — brief, non-blocking confirmation (SessionState.ShowToast), e.g.
   "✓ Zum Warenkorb hinzugefügt". Auto-dismisses; never stacks.
----------------------------------------------------------------------- */

.kiosk-toast {
    position: fixed;
    left: 50%;
    top: 2rem;
    bottom: auto;
    transform: translateX(-50%);
    background: var(--kiosk-surface);
    color: var(--kiosk-text);
    border: 1px solid var(--kiosk-border);
    border-radius: var(--kiosk-radius-btn);
    padding: 0.9rem 1.75rem;
    font-weight: 700;
    box-shadow: var(--kiosk-shadow-lg);
    z-index: 2000;
    animation: toast-in 260ms var(--kiosk-ease-spring) both, toast-out 220ms ease-in 1560ms forwards;
}

@keyframes toast-in {
    from { opacity: 0; transform: translate(-50%, -16px) scale(0.96); }
    to   { opacity: 1; transform: translate(-50%, 0) scale(1); }
}

@keyframes toast-out {
    to { opacity: 0; transform: translate(-50%, -8px) scale(0.98); }
}

/* -----------------------------------------------------------------------
   Typography scale — headings get real hierarchy instead of ad-hoc sizes.
----------------------------------------------------------------------- */

h1 { font-size: clamp(2rem, 3.2vw, 3.25rem); font-weight: 800; letter-spacing: -0.01em; margin: 0; }
h2 { font-size: clamp(1.4rem, 2vw, 1.75rem); font-weight: 800; margin: 0; }
h3 { font-size: 1.05rem; font-weight: 700; color: var(--kiosk-muted); margin: 0; }
p  { margin: 0; }

/* -----------------------------------------------------------------------
   Buttons — one component family, six states each (rest/hover/active/
   focus/disabled/loading), colours derived algorithmically via color-mix()
   so a single admin-configured brand colour stays coherent everywhere.
   Per the Sacred Rule of component stability: no dimension changes on
   hover; only a restrained scale(0.97) on :active for tactile press
   feedback, which is standard and expected on touchscreen kiosks.
----------------------------------------------------------------------- */

button {
    font-family: inherit;
    cursor: pointer;
    border: none;
}

.btn-primary, .btn-secondary, .btn-start {
    border-radius: var(--kiosk-radius-btn);
    padding: 1rem 2rem;
    font-size: 1.15rem;
    font-weight: 700;
    min-height: 64px; /* large touch target */
    transition: background-color 140ms ease-out, border-color 140ms ease-out,
        box-shadow 140ms ease-out, transform 80ms ease-out, opacity 140ms ease-out;
}

.btn-primary, .btn-start {
    background: var(--kiosk-primary);
    color: var(--kiosk-primary-text);
    box-shadow: var(--kiosk-shadow-sm);
}

.btn-primary:hover, .btn-start:hover {
    background: var(--kiosk-primary-hover);
}

.btn-primary:active, .btn-start:active {
    background: var(--kiosk-primary-active);
    transform: scale(0.97);
    box-shadow: none;
}

.btn-secondary {
    background: transparent;
    color: var(--kiosk-text);
    border: 2px solid var(--kiosk-border);
}

.btn-secondary:hover {
    background: var(--kiosk-surface-hover);
    border-color: var(--kiosk-muted);
}

.btn-secondary:active {
    background: var(--kiosk-surface-active);
    transform: scale(0.97);
}

.btn-primary:focus-visible, .btn-secondary:focus-visible, .btn-start:focus-visible,
.product-tile:focus-visible, .option-chip:focus-visible, .serving-type-tile:focus-visible,
.suggestion-chip:focus-visible, .start-language-tile:focus-visible, .category-sidebar-tile:focus-visible {
    outline: 3px solid var(--kiosk-primary);
    outline-offset: 3px;
}

.btn-primary:disabled, .btn-secondary:disabled, .btn-start:disabled {
    opacity: 0.4;
    cursor: not-allowed;
    pointer-events: none;
    transform: none;
}

.btn-text {
    background: transparent;
    color: var(--kiosk-muted);
    font-size: 0.9rem;
    font-weight: 600;
    padding: 0.4rem 0.75rem;
    border-radius: 999px;
    transition: background-color 120ms ease-out, color 120ms ease-out;
}

.btn-text:hover {
    background: rgba(0, 0, 0, 0.05);
    color: var(--kiosk-text);
}

.btn-text:active {
    background: rgba(0, 0, 0, 0.09);
}

/* --- Language picker sheet (Start screen inline row + Menu bottom-bar "Sprache ändern") --- */
.start-language-row {
    display: flex;
    gap: 1rem;
    justify-content: center;
    flex-wrap: wrap;
}

.start-language-tile {
    background: var(--kiosk-surface);
    border: 2px solid var(--kiosk-border);
    border-radius: var(--kiosk-radius-card);
    padding: 0.85rem 1.5rem;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--kiosk-text);
    box-shadow: var(--kiosk-shadow-sm);
    transition: background-color 140ms ease-out, border-color 140ms ease-out, transform 80ms ease-out;
}

.start-language-flag {
    font-size: 1.5rem;
}

.start-language-tile:hover {
    background: var(--kiosk-surface-hover);
}

.start-language-tile:active {
    transform: scale(0.97);
}

.start-language-tile.selected {
    border-color: var(--kiosk-primary);
    background: color-mix(in srgb, var(--kiosk-primary) 10%, white);
}

.language-menu-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(20, 15, 10, 0.35);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    z-index: 200;
    animation: backdrop-in 180ms ease-out both;
}

.language-menu-sheet {
    background: var(--kiosk-surface);
    border-radius: var(--kiosk-radius-card) var(--kiosk-radius-card) 0 0;
    padding: 1.5rem 2rem 2rem;
    width: 100%;
    max-width: 560px;
    box-shadow: var(--kiosk-shadow-lg);
    animation: sheet-in 280ms var(--kiosk-ease-spring) both;
    text-align: center;
}

/* --- Attract screen --- */
.attract-screen {
    position: relative;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: #0f0f14; /* only visible behind the image/gradient during first paint */
}

.attract-background {
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at 20% 20%, color-mix(in srgb, var(--kiosk-primary) 35%, transparent), transparent 45%),
                radial-gradient(circle at 80% 80%, color-mix(in srgb, var(--kiosk-accent) 35%, transparent), transparent 45%),
                #12100e;
    background-size: 200% 200%;
    animation: attract-drift 18s ease-in-out infinite;
}

@keyframes attract-drift {
    0% { background-position: 0% 0%; }
    50% { background-position: 100% 100%; }
    100% { background-position: 0% 0%; }
}

/* Operator-uploaded fullscreen hero image (see TerminalUiPanel.razor's "Startbildschirm-
   Hintergrund") — a scrim underneath the text keeps "Touch to order" readable over any photo. */
.attract-background-image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.attract-scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.65) 0%, rgba(0, 0, 0, 0.15) 45%, rgba(0, 0, 0, 0.35) 100%);
}

/* Whole screen is tappable once the theme is ready (see ScreenCssClass) — not just the visible
   "touch to order" button — so guests can start ordering from anywhere on the display. */
.attract-clickable {
    cursor: pointer;
}

.attract-touch-target {
    background: transparent;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding-bottom: 6vh;
}

.attract-content {
    position: relative;
    text-align: center;
    max-width: 720px;
    padding: 2rem;
    color: #ffffff;
    animation: attract-content-in 700ms var(--kiosk-ease-out) both;
}

@keyframes attract-content-in {
    from { opacity: 0; transform: translateY(20px); }
    to   { opacity: 1; transform: translateY(0); }
}

.attract-content h1 {
    margin-bottom: 0.5rem;
    color: #ffffff;
}

.attract-content p {
    font-size: 1.4rem;
    color: rgba(255, 255, 255, 0.85);
    margin-bottom: 1.5rem;
}

.attract-touch-cue {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 1.2rem;
    font-weight: 700;
    color: #ffffff;
    border: 2px solid rgba(255, 255, 255, 0.7);
    border-radius: var(--kiosk-radius-btn);
    padding: 0.9rem 2rem;
    animation: touch-cue-pulse 1.8s ease-in-out infinite;
}

.attract-touch-icon {
    font-size: 1.4rem;
    animation: touch-cue-tap 1.8s ease-in-out infinite;
}

@keyframes touch-cue-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.25); }
    50% { box-shadow: 0 0 0 10px rgba(255, 255, 255, 0); }
}

@keyframes touch-cue-tap {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-4px); }
}

.attract-error {
    color: #ff8fa3;
}

.attract-skeleton {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

.attract-skeleton .skeleton-bar {
    height: 1.5rem;
    border-radius: 8px;
    background: linear-gradient(90deg,
        rgba(255,255,255,0.08) 25%, rgba(255,255,255,0.18) 37%, rgba(255,255,255,0.08) 63%);
    background-size: 400% 100%;
    animation: skeleton-shimmer 1.4s ease-in-out infinite;
}

.attract-skeleton .skeleton-bar.wide { width: 320px; height: 2.5rem; }
.attract-skeleton .skeleton-bar.narrow { width: 220px; }

@keyframes skeleton-shimmer {
    0% { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
}

/* --- Start screen: serving type (top half, larger) + language (bottom half, smaller) --- */
.start-screen {
    height: 100%;
    display: flex;
    flex-direction: column;
    padding: 2rem;
    gap: 1rem;
}

.start-section {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 1.5rem;
}

.start-section-serving {
    flex: 3;
}

.start-section-serving h1 {
    margin-bottom: 0.5rem;
}

.start-section-language {
    flex: 2;
    border-top: 1px solid var(--kiosk-border);
    padding-top: 1.5rem;
    gap: 1rem;
}

.start-section-language h2 {
    color: var(--kiosk-muted);
    font-size: 1.1rem;
}

.serving-type-options {
    display: flex;
    gap: 2rem;
}

.serving-type-tile {
    background: var(--kiosk-surface);
    border: 2px solid var(--kiosk-border);
    border-radius: var(--kiosk-radius-card);
    padding: 2.5rem 3rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    font-size: 1.3rem;
    font-weight: 700;
    color: var(--kiosk-text);
    min-width: 220px;
    box-shadow: var(--kiosk-shadow-sm);
    transition: background-color 140ms ease-out, box-shadow 140ms ease-out, transform 80ms ease-out, border-color 140ms ease-out;
}

.serving-type-tile:hover {
    background: var(--kiosk-surface-hover);
    box-shadow: var(--kiosk-shadow-md);
}

.serving-type-tile:active {
    background: var(--kiosk-surface-active);
    transform: scale(0.97);
}

.serving-type-icon {
    font-size: 3rem;
    transition: transform 200ms var(--kiosk-ease-spring);
}

.serving-type-tile:hover .serving-type-icon {
    transform: translateY(-4px);
}

.serving-type-tile.selected {
    border-color: var(--kiosk-primary);
    background: color-mix(in srgb, var(--kiosk-primary) 10%, white);
}

.start-continue {
    align-self: center;
    min-width: 260px;
    margin-top: 1rem;
}

/* --- Menu screen: category sidebar (1/12–2/12 width) + main product area --- */
.menu-screen {
    display: flex;
    height: 100%;
    min-height: 0;
}

.category-sidebar {
    width: clamp(96px, 12vw, 168px);
    flex: none;
    background: var(--kiosk-surface);
    border-right: 1px solid var(--kiosk-border);
    display: flex;
    flex-direction: column;
    padding: 1rem 0.5rem;
    gap: 0.5rem;
    overflow-y: auto;
}

.category-sidebar-logo {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.5rem 0 1rem;
    margin-bottom: 0.5rem;
    border-bottom: 1px solid var(--kiosk-border);
}

.category-sidebar-logo img {
    max-width: 100%;
    max-height: var(--kiosk-logo-size, 56px);
    object-fit: contain;
}

.category-sidebar-tile {
    background: transparent;
    border: none;
    border-radius: 16px;
    padding: 1rem 0.4rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    color: var(--kiosk-muted);
    transition: background-color 140ms ease-out, color 140ms ease-out, transform 80ms ease-out;
}

.category-sidebar-icon {
    font-size: 1.5rem;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: radial-gradient(circle at 32% 28%, #ffffff 0%, var(--kiosk-canvas) 70%);
    box-shadow: inset 0 0 0 1px rgba(20, 15, 10, 0.04), var(--kiosk-shadow-sm);
}

.category-sidebar-label {
    font-size: 0.8rem;
    font-weight: 700;
    text-align: center;
    line-height: 1.15;
}

.category-sidebar-tile:hover {
    background: color-mix(in srgb, var(--kiosk-primary) 8%, transparent);
    color: var(--kiosk-text);
}

.category-sidebar-tile:active {
    transform: scale(0.95);
}

.category-sidebar-tile.selected {
    background: color-mix(in srgb, var(--kiosk-primary) 14%, transparent);
    color: var(--kiosk-primary);
}

.menu-main {
    flex: 1;
    /* Bottom padding clears the fixed bottom cart bar — kept in sync via
       --kiosk-bottom-bar-height plus a small breathing-room margin so content
       never peeks out from underneath it. */
    padding: 2rem 2rem calc(var(--kiosk-bottom-bar-height) + 1.5rem);
    overflow-y: auto;
    min-width: 0;
}

.menu-banner {
    border-radius: var(--kiosk-radius-card);
    overflow: hidden;
    box-shadow: var(--kiosk-shadow-md);
    margin-bottom: 2rem;
}

.menu-banner img {
    width: 100%;
    max-height: 220px;
    object-fit: cover;
    display: block;
}

.section-heading {
    margin: 0 0 1.25rem;
}

.popular-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.75rem;
    margin-bottom: 2rem;
}

.popular-tile, .product-tile {
    /* Material "elevated card": borderless, defined purely by soft tonal elevation so the
       product photo (the actual selling point) reads as floating on the canvas rather than
       being boxed in by a hard outline — a transparent border is kept only so the hover/press
       state can add a colour tint without the card's size shifting. */
    background: linear-gradient(180deg, #ffffff 0%, #fdfbfa 100%);
    border: 1px solid transparent;
    border-radius: var(--kiosk-radius-card);
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.65rem;
    color: var(--kiosk-text);
    min-height: 300px;
    box-shadow: var(--kiosk-shadow-sm);
    transition: box-shadow 160ms ease-out, transform 80ms ease-out, border-color 160ms ease-out;
    animation: tile-in 380ms var(--kiosk-ease-out) both;
    animation-delay: calc(var(--tile-index, 0) * 35ms);
}

@keyframes tile-in {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
}

.popular-tile:hover, .product-tile:hover {
    border-color: color-mix(in srgb, var(--kiosk-primary) 25%, transparent);
    box-shadow: var(--kiosk-shadow-md);
}

.popular-tile:active, .product-tile:active {
    transform: scale(0.97);
    box-shadow: var(--kiosk-shadow-sm);
}

.product-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 1.75rem;
}

/* "Minimal" product list template — for shops with just a handful of products per category
   (e.g. a döner imbiss: Döner/Dürüm/Dönerteller). Instead of a wrapping grid that leaves empty
   space, every product gets an equal vertical share of the full available screen height. Only
   .product-grid itself grows (flex: 1) inside the now-flex-column .menu-main-minimal — the
   banner/section heading above it keep their natural size — so the tiles always fill exactly
   the remaining height, regardless of how few products there are. */
.menu-main-minimal {
    display: flex;
    flex-direction: column;
}

.product-grid-minimal {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    flex: 1;
    min-height: 0;
}

.product-tile-minimal {
    flex: 1 1 0;
    min-height: 0;
    width: 100%;
    flex-direction: row;
    justify-content: flex-start;
    text-align: left;
    gap: 1.75rem;
    padding: 1.25rem 2rem;
}

.product-tile-minimal .product-tile-image {
    /* Square frame (aspect-ratio 1:1) honouring the configurable product image size, but never
       larger than the row's own fixed height — the row height is flex-distributed evenly across
       the screen (see .product-grid-minimal/.product-tile-minimal above) and must stay constant
       regardless of this setting. min() lets a small size shrink the image within the row, while
       a size larger than the row simply gets capped/cropped to the available height instead of
       growing the tile — object-fit: cover then fills whatever square box results. */
    height: min(var(--kiosk-product-image-size, 200px), 100%);
    width: auto;
    aspect-ratio: 1 / 1;
    max-width: 40%;
    object-fit: cover;
    flex: none;
}

.product-tile-minimal .product-tile-name {
    font-size: 1.6rem;
}

.product-tile-minimal .product-tile-price {
    font-size: 1.4rem;
}

.product-tile-minimal .product-tile-name,
.product-tile-minimal .product-tile-outofstock,
.product-tile-minimal .product-tile-price {
    text-align: left;
}

.product-tile-image, .popular-tile-image {
    width: 100%;
    height: var(--kiosk-product-image-size, 200px);
    object-fit: contain;
    border-radius: 16px;
    transition: transform 220ms var(--kiosk-ease-out);
}

.product-tile:hover .product-tile-image, .popular-tile:hover .popular-tile-image {
    transform: scale(1.05);
}

.product-tile-image-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 4rem;
    background: radial-gradient(circle at 35% 30%, #ffffff 0%, var(--kiosk-canvas) 75%);
    box-shadow: inset 0 0 0 1px rgba(20, 15, 10, 0.04);
}

.product-tile-name {
    font-weight: 700;
    text-align: center;
    font-size: 1.15rem;
}

.product-tile-price {
    color: var(--kiosk-primary);
    font-weight: 800;
    font-size: 1.1rem;
}

.product-tile-disabled {
    opacity: 0.45;
    filter: grayscale(1);
    cursor: not-allowed;
    transform: none !important;
}

.product-tile-outofstock {
    color: var(--kiosk-danger);
    font-size: 0.85rem;
    text-align: center;
}

/* Optional per-category banner (KioskCategory), uploaded via TerminalUiPanel.razor's
   "Design" tab and shown above that category's product grid on the kiosk menu screen. */
.category-header-banner {
    width: 100%;
    margin-bottom: 1.5rem;
    border-radius: var(--kiosk-radius-card);
    overflow: hidden;
    box-shadow: var(--kiosk-shadow-sm);
}

.category-header-banner img {
    display: block;
    width: 100%;
    max-height: 260px;
    object-fit: cover;
}



.show-more-row {
    display: flex;
    justify-content: center;
    margin-top: 1.5rem;
}

.btn-show-more {
    background: color-mix(in srgb, var(--kiosk-primary) 12%, transparent);
    color: var(--kiosk-primary);
    border-radius: var(--kiosk-radius-btn);
    padding: 0.85rem 2rem;
    font-weight: 700;
    font-size: 1rem;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    transition: background-color 140ms ease-out, transform 80ms ease-out;
}

.btn-show-more:hover {
    background: color-mix(in srgb, var(--kiosk-primary) 20%, transparent);
}

.btn-show-more:active {
    transform: scale(0.97);
}

.show-more-caret {
    font-size: 1.1rem;
}

/* --- Suggestions modal (image-led "Passt dazu" after add-to-cart) --- */
.suggestions-dialog {
    max-width: 1040px;
}

.suggestions-subtitle {
    color: var(--kiosk-muted);
    margin-top: 0.35rem;
}

.suggestions-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 1.5rem;
    margin: 1.5rem 0 2rem;
    min-height: 260px;
}

.suggestions-tile {
    min-height: 240px;
    padding: 1.5rem 1.25rem;
}

.suggestions-tile .popular-tile-image {
    height: var(--kiosk-suggestion-image-size, 150px);
    border-radius: var(--kiosk-suggestion-image-radius, 14px);
}

/* --- Bottom bar: fixed, present on the Menu screen. --- */
.kiosk-bottom-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    min-height: var(--kiosk-bottom-bar-height);
    background: #ffffff;
    border-top: 1px solid var(--kiosk-border);
    box-shadow: 0 -4px 20px rgba(20, 15, 10, 0.08);
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0.75rem 1.75rem;
    z-index: 40;
}

.kiosk-bottom-bar-cart-icon {
    position: relative;
    width: 44px;
    height: 44px;
    flex: none;
    border-radius: 999px;
    background: radial-gradient(circle at 32% 28%, #ffffff 0%, var(--kiosk-canvas) 75%);
    box-shadow: inset 0 0 0 1px rgba(20, 15, 10, 0.05);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.3rem;
}

.kiosk-bottom-bar-badge {
    position: absolute;
    top: -6px;
    right: -6px;
    background: var(--kiosk-accent);
    color: #ffffff;
    font-size: 0.7rem;
    font-weight: 800;
    min-width: 20px;
    height: 20px;
    border-radius: 999px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 4px;
}

.kiosk-bottom-bar-total {
    font-size: 1.25rem;
    font-weight: 800;
    flex: none;
}

.kiosk-bottom-bar-spacer {
    flex: 1;
}

.kiosk-bottom-bar-actions {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.3rem;
}

.kiosk-bottom-bar-cart-btn {
    min-width: 220px;
}

.kiosk-bottom-bar-secondary {
    display: flex;
    gap: 0.5rem;
}

/* --- Bottom-sheet cart / suggestions dialog reuse the shared cart-line/cart-total styles. --- */
.cart-empty {
    color: var(--kiosk-muted);
}

.cart-lines {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    flex: 1;
    max-height: 45vh;
    overflow-y: auto;
}

.cart-line {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    background: var(--kiosk-canvas);
    border-radius: 16px;
    padding: 0.6rem 0.75rem;
    animation: cart-line-in 260ms var(--kiosk-ease-spring) both;
}

.cart-line-thumb {
    width: 48px;
    height: 48px;
    flex: none;
    border-radius: 12px;
    background: #ffffff;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.cart-line-thumb img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

@keyframes cart-line-in {
    from { opacity: 0; transform: translateX(12px); }
    to   { opacity: 1; transform: translateX(0); }
}

.cart-line-info {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

.cart-line-summary {
    color: var(--kiosk-muted);
    font-size: 0.82rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.cart-line-price {
    color: var(--kiosk-muted);
    font-size: 0.9rem;
}

.cart-line-edit {
    background: transparent;
    color: var(--kiosk-primary);
    font-size: 0.85rem;
    font-weight: 700;
    padding: 0.4rem 0.75rem;
    border-radius: 999px;
    transition: background-color 120ms ease-out;
    flex: none;
}

.cart-line-edit:hover {
    background: color-mix(in srgb, var(--kiosk-primary) 12%, transparent);
}

.cart-line-remove {
    background: transparent;
    color: var(--kiosk-danger);
    font-size: 0.85rem;
    padding: 0.4rem 0.6rem;
    border-radius: 999px;
    transition: background-color 120ms ease-out;
    flex: none;
}

.cart-line-remove:hover {
    background: color-mix(in srgb, var(--kiosk-danger) 12%, transparent);
}

.cart-total {
    display: flex;
    justify-content: space-between;
    font-size: 1.3rem;
    font-weight: 800;
    margin: 1rem 0;
}

/* --- Product detail dialog: bottom sheet (McDonald's-kiosk style) — anchored to the
   bottom edge, rounded only at the top, sliding up instead of scaling in from the
   center. --- */
.product-dialog-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(20, 15, 10, 0.4);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    z-index: 100;
    animation: backdrop-in 180ms ease-out both;
}

@keyframes backdrop-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.product-dialog {
    background: var(--kiosk-surface);
    border: 1px solid var(--kiosk-border);
    border-bottom: none;
    border-radius: var(--kiosk-radius-card) var(--kiosk-radius-card) 0 0;
    padding: 1.5rem 2rem 2rem;
    max-width: 720px;
    width: 100%;
    min-height: 90vh;
    max-height: 95vh;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    scrollbar-width: none;
    position: relative;
    box-shadow: var(--kiosk-shadow-lg);
    animation: sheet-in 300ms var(--kiosk-ease-spring) both;
}

/* Wider variant for the product customize dialog, cart sheet and suggestions modal — enough
   room for a real 2-column ingredient grid without cramming. */
.product-dialog-wide {
    max-width: 98vh;
}

.product-dialog::-webkit-scrollbar {
    display: none;
}

/* Small drag-handle bar, purely decorative — signals "this can be dismissed" the way a
   native bottom sheet does, without needing an actual swipe gesture implementation. */
.product-dialog::before {
    content: "";
    display: block;
    width: 48px;
    height: 5px;
    border-radius: 999px;
    background: var(--kiosk-border);
    margin: 0 auto 0.75rem;
}

@keyframes sheet-in {
    from { opacity: 0; transform: translateY(100%); }
    to   { opacity: 1; transform: translateY(0); }
}

.product-dialog-close {
    position: absolute;
    top: 1rem;
    right: 1rem;
    background: var(--kiosk-canvas);
    border-radius: 999px;
    width: 44px;
    height: 44px;
    color: var(--kiosk-text);
    font-size: 1.1rem;
    transition: background-color 120ms ease-out, transform 80ms ease-out;
    z-index: 10; /* must stay above the sticky customize header (z-index: 1) below it */
    box-shadow: var(--kiosk-shadow-sm);
}

.product-dialog-close:hover {
    background: color-mix(in srgb, var(--kiosk-canvas) 60%, black);
}

/* -----------------------------------------------------------------------
   "Order without sauce?" confirmation — a small centered dialog stacked
   above the customize sheet (higher z-index via being appended after it),
   confirming an easy-to-make mistake before it reaches the kitchen.
----------------------------------------------------------------------- */
.no-sauce-confirm-backdrop {
    z-index: 1200;
    align-items: center;
    background: rgba(20, 15, 10, 0.55);
}

.no-sauce-confirm-dialog {
    background: var(--kiosk-surface);
    border: 1px solid var(--kiosk-border);
    border-radius: var(--kiosk-radius-card);
    box-shadow: var(--kiosk-shadow-lg);
    padding: 2rem;
    max-width: 420px;
    width: calc(100% - 3rem);
    text-align: center;
    animation: modal-pop-in 220ms var(--kiosk-ease-spring) both;
}

.no-sauce-confirm-icon {
    font-size: 2.75rem;
    margin-bottom: 0.5rem;
}

.no-sauce-confirm-dialog h3 {
    margin: 0 0 0.5rem;
    font-size: 1.2rem;
}

.no-sauce-confirm-dialog p {
    color: var(--kiosk-text-dim);
    margin: 0 0 1.5rem;
}

.no-sauce-confirm-actions {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.no-sauce-confirm-actions .btn-primary,
.no-sauce-confirm-actions .btn-secondary {
    width: 100%;
}

@keyframes modal-pop-in {
    from { opacity: 0; transform: scale(0.94); }
    to   { opacity: 1; transform: scale(1); }
}

.product-dialog-close:active {
    transform: scale(0.9);
}

.product-dialog-image {
    width: 100%;
    max-width: 420px;
    max-height: var(--kiosk-customize-hero-size, 380px);
    object-fit: contain;
    margin-bottom: 1rem;
    border-radius: var(--kiosk-radius-card);
}

.product-dialog-price {
    color: var(--kiosk-primary);
    font-size: 1.4rem;
    font-weight: 700;
}

.product-dialog-section {
    margin-top: 1.25rem;
}

.product-dialog-section h3 {
    margin-bottom: 0.5rem;
}

.product-dialog-confirm {
    width: 100%;
    margin-top: 1.5rem;
}

/* -----------------------------------------------------------------------
   Product dialog — summary phase (image, name, price, quantity) and
   customize phase (picture-based meat/spice tiles, thumbnail ingredient
   rows) so configuring a dish stays as image-first as picking one.
----------------------------------------------------------------------- */

.product-dialog-summary {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.5rem;
}

.product-dialog-image-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 3rem;
    background: var(--kiosk-canvas);
    border-radius: 16px;
}

.product-dialog-actions {
    display: flex;
    gap: 0.75rem;
    width: 100%;
    margin-top: 1rem;
}

.product-dialog-actions .btn-primary,
.product-dialog-actions .btn-secondary {
    flex: 1;
}

.qty-stepper {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin: 0.5rem 0;
}

.qty-stepper-lg .qty-btn {
    width: 52px;
    height: 52px;
    font-size: 1.5rem;
}

.qty-btn {
    background: var(--kiosk-canvas);
    border-radius: 999px;
    width: 40px;
    height: 40px;
    color: var(--kiosk-text);
    font-weight: 700;
    transition: background-color 120ms ease-out, transform 80ms ease-out;
}

.qty-btn:hover:not(:disabled) {
    background: color-mix(in srgb, var(--kiosk-canvas) 60%, black);
}

.qty-btn:active:not(:disabled) {
    transform: scale(0.9);
}

.qty-btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

.qty-value {
    font-size: 1.3rem;
    font-weight: 700;
    min-width: 2ch;
    text-align: center;
}

.product-dialog-customize-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 1rem;
    padding: 0.25rem 3.5rem 1.25rem; /* side padding clears the fixed close button */
    border-bottom: 1px solid var(--kiosk-border);
    position: sticky;
    top: 0;
    background: var(--kiosk-surface);
    z-index: 1;
}

.product-dialog-customize-header h2 {
    margin: 0;
    font-size: 1.6rem;
    text-align: center;
}

.product-dialog-back {
    align-self: flex-start;
    flex: none;
}

.product-dialog-sticky-info {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.4rem;
}

.product-dialog-sticky-image {
    width: var(--kiosk-customize-hero-size, 220px);
    height: var(--kiosk-customize-hero-size, 220px);
    object-fit: contain;
    border-radius: 20px;
    flex: none;
}

.product-dialog-sticky-image.product-dialog-image-placeholder {
    background: var(--kiosk-canvas);
}

.product-dialog-sticky-info .product-dialog-price {
    font-size: 1.35rem;
    margin: 0;
}

.picture-option-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.picture-option {
    background: var(--kiosk-canvas);
    border: 2px solid transparent;
    border-radius: var(--kiosk-radius-card);
    padding: 0.6rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.4rem;
    color: var(--kiosk-text);
    width: 100px;
    transition: background-color 140ms ease-out, border-color 140ms ease-out, transform 80ms ease-out;
}

.picture-option img {
    width: var(--kiosk-meatbread-image-size, 56px);
    height: var(--kiosk-meatbread-image-size, 56px);
    object-fit: contain;
    border-radius: 999px;
}

.picture-option-placeholder {
    width: var(--kiosk-meatbread-image-size, 56px);
    height: var(--kiosk-meatbread-image-size, 56px);
    border-radius: 999px;
    background: radial-gradient(circle at 32% 28%, #ffffff 0%, var(--kiosk-canvas) 75%);
    box-shadow: inset 0 0 0 1px rgba(20, 15, 10, 0.05);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.6rem;
}

.picture-option span {
    font-size: 0.85rem;
    font-weight: 600;
    text-align: center;
}

/* Menu slot option grid: Hauptgericht slots always split the full dialog width across their
   option count (like Meat/Bread); Getränk/Dessert/Beilage slots use the admin-configurable
   "items per row" theme setting instead, capped to however many options actually exist so a
   single drink doesn't get stretched across the whole row. */
.menu-slot-options {
    display: grid;
    grid-template-columns: repeat(var(--menu-slot-cols, 2), minmax(0, 1fr));
    gap: 0.75rem;
}

.menu-slot-options .picture-option {
    width: 100%;
}

/* Full-width, dynamic-column card grid used for Meat/Bread selection — the column count is
   set inline per section (--option-card-grid-cols) from the number of available options, so
   e.g. 3 compatible breads always span the whole dialog width as 3 equal cards instead of
   wrapping a fixed-width tile row. Cards reuse the ingredient-row visual style (thumb + info
   + toggle) so Meat/Bread look consistent with Sauces/Toppings. */
.option-card-grid {
    display: grid;
    grid-template-columns: repeat(var(--option-card-grid-cols, 2), minmax(0, 1fr));
    gap: 0.6rem;
}

.option-card-grid .ingredient-row {
    min-height: calc(var(--kiosk-meatbread-image-size, 56px) + 1rem);
}

/* Meat/Bread cards keep their own (usually larger) configured image size instead of the
   sauce/topping ingredient image size. */
.ingredient-thumb-meatbread {
    width: var(--kiosk-meatbread-image-size, 56px);
    height: var(--kiosk-meatbread-image-size, 56px);
}

/* Hauptzutaten (side-dish add-ons) get their own configurable image size, shown in a
   dedicated section separate from the regular Zutaten/Sauces. */
.ingredient-thumb-main {
    width: var(--kiosk-mainingredient-image-size, 56px);
    height: var(--kiosk-mainingredient-image-size, 56px);
}

.ingredient-row-main {
    min-height: calc(var(--kiosk-mainingredient-image-size, 56px) + 1rem);
}

.menu-config-surcharge {
    font-size: 0.72rem !important;
    font-weight: 500 !important;
    color: var(--kiosk-text-dim);
}

.menu-config-description {
    color: var(--kiosk-text-dim);
    margin: -0.25rem 0 0.5rem;
}

.menu-config-slot-label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--kiosk-text-dim);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin: 0.5rem 0 0.4rem;
}

/* Reopens the nested meat/bread/sauce/topping step for an already-configured menu slot. */
.menu-config-edit-slot {
    margin: 0.4rem 0 0.75rem;
    padding: 0.4rem 0.9rem;
    font-size: 0.85rem;
}

.picture-option:hover {
    background: color-mix(in srgb, var(--kiosk-canvas) 60%, black);
}

.picture-option:active {
    transform: scale(0.96);
}

.picture-option.selected {
    border-color: var(--kiosk-primary);
    background: color-mix(in srgb, var(--kiosk-primary) 12%, white);
}

/* 2-column ingredient grid (sauces/toppings) — halves the vertical space a long ingredient
   list would otherwise take up in the wider customize dialog. */
.ingredient-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.6rem;
}

.ingredient-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    background: var(--kiosk-canvas);
    border: 2px solid transparent;
    border-radius: 14px;
    padding: 0.5rem 0.75rem;
    min-height: calc(var(--kiosk-ingredient-image-size, 44px) + 1rem);
    cursor: pointer;
    transition: background-color 120ms ease-out, border-color 120ms ease-out, transform 80ms ease-out;
}

.ingredient-row.selected {
    border-color: var(--kiosk-primary);
    background: color-mix(in srgb, var(--kiosk-primary) 12%, white);
}

.ingredient-row:hover {
    background: color-mix(in srgb, var(--kiosk-canvas) 60%, black);
}

.ingredient-row:active {
    transform: scale(0.98);
}

.ingredient-row-disabled {
    opacity: 0.4;
    filter: grayscale(1);
    cursor: not-allowed;
    pointer-events: none;
}

.ingredient-thumb {
    width: var(--kiosk-ingredient-image-size, 44px);
    height: var(--kiosk-ingredient-image-size, 44px);
    flex: none;
    border-radius: var(--kiosk-ingredient-image-radius, 999px);
    background: radial-gradient(circle at 32% 28%, #ffffff 0%, var(--kiosk-canvas) 75%);
    box-shadow: inset 0 0 0 1px rgba(20, 15, 10, 0.05);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    font-size: 1.3rem;
}

.ingredient-thumb img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.ingredient-info {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-width: 0;
}

.ingredient-name {
    font-weight: 600;
}

.ingredient-note {
    font-size: 0.8rem;
    color: var(--kiosk-muted);
}

.ingredient-note-danger {
    color: var(--kiosk-danger);
}

.ingredient-toggle {
    width: 40px;
    height: 40px;
    flex: none;
    border-radius: 999px;
    background: #ffffff;
    color: var(--kiosk-text);
    font-weight: 700;
    font-size: 1.1rem;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 120ms ease-out, transform 80ms ease-out;
}

.ingredient-row:hover .ingredient-toggle {
    background: color-mix(in srgb, #ffffff 85%, var(--kiosk-canvas));
}

.ingredient-toggle.selected {
    background: var(--kiosk-primary);
    color: var(--kiosk-primary-text);
}

/* --- Checkout screen --- */
.checkout-screen {
    max-width: 640px;
    margin: 0 auto;
    padding: 2rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    width: 100%;
    overflow-y: auto;
}

.checkout-back {
    align-self: flex-start;
    padding: 0.6rem 1.25rem;
}

/* --- Floating scroll indicator (see wwwroot/js/scrollIndicators.js) ---
   Any container with the `scroll-indicator-host` class gets these two arrows injected
   automatically. Only one is ever visible at a time: pointing down at the bottom edge
   while there's more content below, pointing up at the top edge once scrolled down and
   there's more content above — both hidden once the container doesn't scroll or is
   scrolled all the way to that extreme. */
.scroll-indicator {
    position: fixed;
    left: 50%;
    top: 0;
    width: 3.5rem;
    height: 3.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: var(--kiosk-primary);
    color: var(--kiosk-primary-text);
    font-size: 1.8rem;
    font-weight: 700;
    box-shadow: var(--kiosk-shadow-md, var(--kiosk-shadow-sm));
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    z-index: 999;
    transform: translateX(-50%);
    transition: opacity 200ms ease-out, visibility 200ms ease-out;
}

.scroll-indicator-top,
.scroll-indicator-bottom {
    transform: translateX(-50%);
}

.scroll-indicator.visible {
    opacity: 0.95;
    visibility: visible;
    animation: scroll-indicator-bob 1.6s ease-in-out infinite;
}

@keyframes scroll-indicator-bob {
    0%, 100% { transform: translateX(-50%) translateY(0); }
    50% { transform: translateX(-50%) translateY(8px); }
}

.checkout-summary {
    background: var(--kiosk-surface);
    border: 1px solid var(--kiosk-border);
    border-radius: var(--kiosk-radius-card);
    padding: 1.25rem;
}

.checkout-line {
    display: flex;
    justify-content: space-between;
    padding: 0.4rem 0;
}

.checkout-total {
    display: flex;
    justify-content: space-between;
    font-size: 1.3rem;
    font-weight: 700;
    border-top: 1px solid var(--kiosk-border);
    padding-top: 0.75rem;
    margin-top: 0.5rem;
}

.checkout-coupon {
    display: flex;
    gap: 0.5rem;
}

.checkout-coupon input {
    flex: 1;
    border-radius: 12px;
    border: 1px solid var(--kiosk-border);
    background: transparent;
    color: var(--kiosk-text);
    padding: 0.75rem 1rem;
    font-size: 1rem;
    transition: border-color 140ms ease-out;
}

.checkout-coupon input:focus-visible {
    outline: none;
    border-color: var(--kiosk-primary);
}

.checkout-coupon-applied {
    color: var(--kiosk-success);
    animation: fade-in 200ms ease-out both;
}

.checkout-line-discount {
    color: var(--kiosk-success);
}

.checkout-coupon-error {
    color: var(--kiosk-danger);
    animation: shake 340ms ease-in-out;
}

.checkout-payment-methods {
    margin-top: 0.5rem;
}

.checkout-payment-label {
    text-align: center;
    font-weight: 600;
    color: var(--kiosk-text-dim);
    margin-bottom: 0.75rem;
}

.checkout-payment-tiles {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
}

.checkout-payment-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
    background: var(--kiosk-surface);
    border: 1px solid var(--kiosk-border);
    border-radius: var(--kiosk-radius-card);
    padding: 1.5rem 1rem;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--kiosk-text);
    box-shadow: var(--kiosk-shadow-sm);
    transition: transform 100ms ease-out, box-shadow 140ms ease-out, border-color 140ms ease-out;
}

.checkout-payment-tile:hover {
    border-color: var(--kiosk-primary);
    box-shadow: var(--kiosk-shadow-md);
    transform: translateY(-2px);
}

.checkout-payment-tile:active {
    transform: scale(0.98);
}

.checkout-payment-tile-icon {
    font-size: 2.25rem;
}

.checkout-pay-at-counter-icon {
    font-size: 3rem;
}

.checkout-pay-at-counter-hint {
    color: var(--kiosk-text-dim);
    max-width: 360px;
}

@keyframes fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes shake {
    0%, 100% { transform: translateX(0); }
    25% { transform: translateX(-4px); }
    75% { transform: translateX(4px); }
}

.checkout-processing {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    text-align: center;
    margin-top: 4rem;
    animation: fade-in 220ms ease-out both;
}

.checkout-error {
    color: var(--kiosk-danger);
    font-size: 1.1rem;
}

.checkout-terminal-hint {
    color: var(--kiosk-muted, #6b7280);
    font-size: 1rem;
    white-space: pre-line;
}

.spinner {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    border: 6px solid var(--kiosk-border);
    border-top-color: var(--kiosk-primary);
    animation: spin 900ms linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* --- Confirmation screen --- */
.confirmation-screen {
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    text-align: center;
}

.confirmation-screen h1 {
    animation: fade-in 260ms ease-out both;
}

.confirmation-label {
    color: var(--kiosk-muted);
    font-size: 1.2rem;
}

.confirmation-number {
    font-size: 5rem;
    font-weight: 800;
    color: var(--kiosk-primary);
    margin-bottom: 2rem;
    animation: confirmation-number-in 500ms var(--kiosk-ease-spring) 120ms both;
}

@keyframes confirmation-number-in {
    from { opacity: 0; transform: scale(0.8); }
    to   { opacity: 1; transform: scale(1); }
}

.confirmation-print-warning {
    color: var(--kiosk-danger);
    max-width: 480px;
}

.confirmation-receipt {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
    animation: fade-in 260ms ease-out 200ms both;
}

.confirmation-receipt-hint {
    color: var(--kiosk-muted);
    font-size: 0.9rem;
}

/* --- Pairing screen --- */
.pairing-screen {
    max-width: 480px;
    margin: 4rem auto;
    padding: 2rem;
    text-align: center;
}

.pairing-form {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    text-align: left;
    margin: 1.5rem 0;
}

.pairing-form input {
    border-radius: 12px;
    border: 1px solid var(--kiosk-border);
    background: transparent;
    color: var(--kiosk-text);
    padding: 0.75rem 1rem;
    font-size: 1.1rem;
    transition: border-color 140ms ease-out;
}

.pairing-form input:focus-visible {
    outline: none;
    border-color: var(--kiosk-primary);
}

.pairing-error {
    color: var(--kiosk-danger);
}

.pairing-success {
    color: var(--kiosk-success);
    animation: fade-in 220ms ease-out both;
}

/* -----------------------------------------------------------------------
   Accessibility & performance guardrails
----------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        background-attachment: initial !important;
    }
}
