/* ============================================================================
   KIOSK V2 DESIGN SYSTEM: kiosk-design.css (2026-10-29, KIOSK_V2_SPEC.md)
   One stylesheet renders EVERY design: values come from --kd-* custom properties written inline on the
   page root by KioskDesignCss.ToStyle(); structure variants come from the kd-* classes of ToClasses().
   Used by the kiosk v2 pages (RTT.Kiosk.UI, PgOrder kiosk branch) and the back-office live preview.
   Signature: the cart is a thermal order ticket that prints a new line for every product added; the
   thanks screen hands the order number out of a ticket slot.
   Rules: no hardcoded brand colors (only --kd-* tokens; #fff/#000 only for photo scrims and paper ink),
   portrait 32" kiosk first (arm's length), touch targets >= 64px, motion only answers actions + one
   welcome entrance, reduced-motion and AnimLevel respected.
   ============================================================================ */

/* ---------------------------------------------------------------- root */
.kd {
    /* fallbacks = REYSTI_NIGHT so a page without inline tokens still renders */
    --kd-bg: #0a0a14; --kd-surface: #15152b; --kd-surface-2: #1f1f3d; --kd-text: #f2f2f7; --kd-dim: #a4a4c4;
    --kd-primary: #84baf8; --kd-on-primary: #0a0a14; --kd-accent: #ffb547; --kd-on-accent: #1a1206;
    --kd-price: #ffd27a; --kd-line: #2b2b4d;
    --kd-font-display: 'Bricolage Grotesque', 'Sora', system-ui, sans-serif;
    --kd-font-body: 'Sora', system-ui, sans-serif;
    --kd-display-weight: 800; --kd-display-case: none; --kd-display-track: -0.02em; --kd-fs: 1;
    --kd-card-r: 22px; --kd-btn-r: 16px; --kd-border: 1px; --kd-logo-h: 88px; --kd-overlay: 0.55;

    /* derived */
    /* SCREEN SCALE (12" tablet ... 42" 4K): one unitless --kd-scale chosen per screen class (media tiers below),
       every size derives from it. 1 = a 1080p kiosk (short side ~1080 CSS px, DPR 1) read at arm's length. */
    --kd-scale: 1;
    --kd-u: calc(17px * var(--kd-scale) * var(--kd-fs));                  /* type/spacing unit */
    --kd-gap: calc(var(--kd-u) * 1.1);
    --kd-pad: calc(var(--kd-u) * 1.5);
    --kd-touch: max(60px, calc(var(--kd-u) * 3.4));
    --kd-primary-soft: color-mix(in srgb, var(--kd-primary) 16%, transparent);
    --kd-accent-soft: color-mix(in srgb, var(--kd-accent) 18%, transparent);
    --kd-veil: color-mix(in srgb, var(--kd-bg) 72%, transparent);
    --kd-paper: #fffcf3; --kd-ink: #1f1c18; --kd-ink-rgb: 31, 28, 24;      /* tokens Paper / Ink */
    --kd-ink-dim: color-mix(in srgb, var(--kd-ink) 62%, var(--kd-paper));
    --kd-ink-line: rgba(var(--kd-ink-rgb), .25);
    --kd-shadow-rgb: 0, 0, 0;           /* shadow tint */
    --kd-scrim-rgb: 0, 0, 0;            /* photo scrim under text on pictures (not a brand color) */
    --kd-on-photo: #fff;                /* text on that scrim */
    --kd-term-x: #d62828;               /* the physical red cancel key drawn in the terminal hint */
    --kd-term-x-on: #fff;
    --kd-qr-bg: #fff;                   /* QR codes must stay dark-on-light to scan */
    --kd-preview-bezel: #15151c; --kd-preview-bezel-edge: #2a2a34;
    --kd-ease: cubic-bezier(.2, .8, .2, 1);
    --kd-ease-out: cubic-bezier(.16, 1, .3, 1);
    --kd-shadow: none;
    --kd-shadow-lift: 0 10px 30px -14px rgba(var(--kd-shadow-rgb), .35);

    position: fixed;
    inset: 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background-color: var(--kd-bg);
    color: var(--kd-text);
    font-family: var(--kd-font-body);
    font-size: var(--kd-u);
    line-height: 1.4;
    -webkit-font-smoothing: antialiased;
    -webkit-tap-highlight-color: transparent;
    user-select: none;
    -webkit-user-select: none;
    font-variant-numeric: tabular-nums;
}

.kd *, .kd *::before, .kd *::after { box-sizing: border-box; }
.kd img { max-width: 100%; }
.kd.kd-bigtxt { --kd-u: calc(17px * var(--kd-scale) * var(--kd-fs) * 1.15); }

/* ---------------------------------------------------------------- SCREEN TIERS
   Pixels mean different physical sizes: a 12" tablet has small dense CSS pixels (DPR >= 1.5, held ~40 cm away),
   a 32-42" kiosk large ones (DPR 1, ~60 cm). Tiers key on the SHORT side + density; the kiosk UI keeps a similar
   physical size of type and touch targets on every screen. Preview frames override --kd-scale themselves. */
@media (max-width: 699px), (max-height: 699px) { .kd { --kd-scale: .9; } }                                              /* small tablets / split screens */
@media (min-width: 700px) and (min-height: 700px) and (min-resolution: 1.5dppx) { .kd { --kd-scale: 1.1; } }         /* 10-12" tablets (800-900 CSS px short side) */
@media (min-width: 1000px) and (min-height: 1000px) and (min-resolution: 1.5dppx) { .kd { --kd-scale: 1.25; } }       /* 12.9-13" tablets (1024 short side) */
@media (min-width: 1300px) and (min-height: 1300px) { .kd { --kd-scale: 1.32; } }                                       /* 1440p screens */
@media (min-width: 1800px) and (min-height: 1800px) { .kd { --kd-scale: 1.95; } }                                       /* 4K kiosks (2160 short side), 42"+ */

/* shadow families */
.kd.kd-shadow-soft { --kd-shadow: 0 1px 2px rgba(var(--kd-shadow-rgb), .06), 0 14px 34px -16px rgba(var(--kd-shadow-rgb), .28); }
.kd.kd-shadow-hard { --kd-shadow: calc(6px * var(--kd-scale)) calc(6px * var(--kd-scale)) 0 var(--kd-line); --kd-shadow-lift: calc(9px * var(--kd-scale)) calc(9px * var(--kd-scale)) 0 var(--kd-line); }
.kd.kd-shadow-glow { --kd-shadow: 0 0 0 1px rgba(var(--kd-primary-rgb), .14), 0 18px 48px -22px rgba(var(--kd-primary-rgb), .55); --kd-shadow-lift: 0 0 0 1px rgba(var(--kd-primary-rgb), .3), 0 22px 60px -18px rgba(var(--kd-primary-rgb), .7); }

/* background image (owner photo) + pattern layer, behind all content */
.kd::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -2;
    pointer-events: none;
    background-repeat: repeat;
}
.kd.kd-has-bkg::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -3;
    background: var(--kd-bkg-img) center / cover no-repeat;
}
.kd.kd-has-bkg::before { background-color: rgba(var(--kd-bg-rgb), var(--kd-overlay)); }

.kd.kd-pattern-dots::before { background-image: radial-gradient(rgba(var(--kd-text-rgb), .07) 1.6px, transparent 1.8px); background-size: 26px 26px; }
.kd.kd-pattern-stripes::before { background-image: repeating-linear-gradient(90deg, rgba(var(--kd-primary-rgb), .045) 0 34px, transparent 34px 68px), repeating-linear-gradient(0deg, rgba(var(--kd-primary-rgb), .045) 0 34px, transparent 34px 68px); }
.kd.kd-pattern-checker::before { background-image: conic-gradient(rgba(var(--kd-text-rgb), .055) 25%, transparent 0 50%, rgba(var(--kd-text-rgb), .055) 0 75%, transparent 0); background-size: 56px 56px; }
.kd.kd-pattern-waves::before { background-image: radial-gradient(60vmax 40vmax at 10% 0%, rgba(var(--kd-primary-rgb), .22), transparent 60%), radial-gradient(50vmax 40vmax at 100% 100%, rgba(var(--kd-accent-rgb), .18), transparent 60%); }
.kd.kd-pattern-grain::before {
    background-image: radial-gradient(70vmax 50vmax at 50% -10%, rgba(var(--kd-primary-rgb), .14), transparent 65%),
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 .05 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
    background-size: auto, 160px 160px;
}

/* ---------------------------------------------------------------- type */
.kd-display {
    font-family: var(--kd-font-display);
    font-weight: var(--kd-display-weight);
    text-transform: var(--kd-display-case);
    letter-spacing: var(--kd-display-track);
    line-height: 1.02;
    text-wrap: balance;
}
.kd-dim { color: var(--kd-dim); }
.kd-price { color: var(--kd-price); font-weight: 700; white-space: nowrap; }
.kd-price-old { color: var(--kd-dim); text-decoration: line-through; font-size: .85em; white-space: nowrap; }

/* ---------------------------------------------------------------- buttons
   Telerik renders <button class="k-button ...">: .kd .k-button.kd-btn (0,3,0) beats the Telerik theme. */
.kd .kd-btn, .kd .k-button.kd-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .55em;
    min-height: var(--kd-touch);
    padding: 0 1.4em;
    border: var(--kd-border) solid transparent;
    border-radius: var(--kd-btn-r);
    background: var(--kd-primary);
    color: var(--kd-on-primary);
    font-family: var(--kd-font-display);
    font-weight: var(--kd-display-weight);
    text-transform: var(--kd-display-case);
    letter-spacing: var(--kd-display-track);
    font-size: calc(var(--kd-u) * 1.15);
    line-height: 1;
    box-shadow: var(--kd-shadow);
    cursor: pointer;
    transition: transform .14s var(--kd-ease), box-shadow .2s var(--kd-ease), background-color .2s var(--kd-ease), opacity .2s;
    -webkit-tap-highlight-color: transparent;
}
.kd .kd-btn svg, .kd .k-button.kd-btn svg { width: 1.15em; height: 1.15em; fill: currentColor; flex: none; }
.kd .kd-btn:active, .kd .k-button.kd-btn:active { transform: scale(.965); }
.kd .kd-btn:focus-visible, .kd .k-button.kd-btn:focus-visible { outline: 3px solid var(--kd-accent); outline-offset: 3px; }
.kd .kd-btn[disabled], .kd .k-button.kd-btn.k-disabled { opacity: .45; }
.kd .kd-btn-accent, .kd .k-button.kd-btn-accent { background: var(--kd-accent); color: var(--kd-on-accent); }
.kd .kd-btn-ghost, .kd .k-button.kd-btn-ghost { background: transparent; color: var(--kd-text); border-color: var(--kd-line); box-shadow: none; }
.kd .kd-btn-quiet, .kd .k-button.kd-btn-quiet { background: var(--kd-surface-2); color: var(--kd-text); box-shadow: none; }
.kd .kd-btn-xl, .kd .k-button.kd-btn-xl { min-height: calc(var(--kd-touch) * 1.25); font-size: calc(var(--kd-u) * 1.45); padding: 0 1.8em; }
.kd .kd-btn-round, .kd .k-button.kd-btn-round { width: var(--kd-touch); padding: 0; border-radius: 999px; }
.kd.kd-shadow-hard .kd-btn { border-color: var(--kd-line); }

/* hidden long-press corners (reload / exit fullscreen: admin gestures, kept from CLASSIC) */
.kd #divHidMenu_Left, .kd #divHidMenu_Right { position: absolute; top: 0; width: calc(120px * var(--kd-scale)); height: calc(120px * var(--kd-scale)); z-index: 50; background: transparent; }
.kd #divHidMenu_Left { left: 0; }
.kd #divHidMenu_Right { right: 0; }

/* ================================================================= WELCOME */
.kd-welcome { justify-content: flex-end; }
.kd-welcome-media { position: absolute; inset: 0; z-index: -1; overflow: hidden; }
.kd-welcome-media img, .kd-welcome-media video, .kd-welcome-media .k-scrollview { width: 100%; height: 100%; object-fit: cover; }
.kd-welcome-media .k-scrollview { border: 0; background: transparent; }
.kd-welcome-media .kd-hero-img { background: var(--kd-welcome-img) center / cover no-repeat; position: absolute; inset: 0; }
.kd-welcome-media::after {
    /* scrim: owner photos must never fight with the title */
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(var(--kd-bg-rgb), calc(var(--kd-overlay) * .55)) 0%, rgba(var(--kd-bg-rgb), 0) 28%, rgba(var(--kd-bg-rgb), calc(var(--kd-overlay) + .2)) 62%, rgba(var(--kd-bg-rgb), .96) 100%);
}
.kd-welcome-fallback { position: absolute; inset: 0; background: radial-gradient(80vmax 60vmax at 80% 10%, rgba(var(--kd-primary-rgb), .35), transparent 60%), radial-gradient(70vmax 50vmax at 0% 90%, rgba(var(--kd-accent-rgb), .3), transparent 60%), var(--kd-bg); }

.kd-welcome-top { position: absolute; top: calc(var(--kd-pad) * 1.6); left: 0; right: 0; display: flex; justify-content: center; }
.kd-welcome-logo { height: calc(var(--kd-logo-h) * 1.4 * var(--kd-scale)); max-width: 70vw; object-fit: contain; filter: drop-shadow(0 6px 24px rgba(var(--kd-shadow-rgb), .25)); }

.kd-welcome-body { padding: 0 calc(var(--kd-pad) * 1.6) calc(var(--kd-pad) * 2.2); display: flex; flex-direction: column; gap: calc(var(--kd-gap) * 1.6); }
.kd-welcome-title { font-size: max(calc(var(--kd-u) * 3), 12vmin); margin: 0; max-width: 14ch; }
.kd-welcome-sub { font-size: calc(var(--kd-u) * 1.5); color: var(--kd-dim); max-width: 34ch; margin: 0; line-height: 1.35; }
.kd-welcome-msg { font-size: calc(var(--kd-u) * 1.2); padding: .9em 1.2em; border-radius: var(--kd-card-r); background: var(--kd-veil); border: var(--kd-border) solid var(--kd-line); max-width: 40ch; backdrop-filter: blur(10px); }
.kd-welcome-ask { font-size: calc(var(--kd-u) * 1.05); color: var(--kd-dim); margin: 0 0 calc(var(--kd-gap) * -.6); }

/* language = start action (touch-to-start removed, user decision 2026-07-07) */
.kd-lang-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--kd-gap); }
.kd-lang {
    display: flex;
    align-items: center;
    gap: .9em;
    min-height: calc(var(--kd-touch) * 1.45);
    padding: 0 1.2em;
    border-radius: var(--kd-btn-r);
    background: var(--kd-surface);
    border: var(--kd-border) solid var(--kd-line);
    color: var(--kd-text);
    box-shadow: var(--kd-shadow);
    font-family: var(--kd-font-display);
    font-weight: var(--kd-display-weight);
    font-size: calc(var(--kd-u) * 1.35);
    text-transform: var(--kd-display-case);
    letter-spacing: var(--kd-display-track);
    cursor: pointer;
    transition: transform .14s var(--kd-ease), background-color .2s;
}
.kd-lang img { width: 2.1em; height: 1.4em; object-fit: cover; border-radius: 4px; flex: none; box-shadow: 0 0 0 1px rgba(var(--kd-shadow-rgb), .12); }
.kd-lang:active { transform: scale(.97); background: var(--kd-primary); color: var(--kd-on-primary); }
/* 2026-10-29: the CURRENT language is highlighted (was: :first-child, which looked selected whatever the screen language) */
.kd-lang.on { background: var(--kd-primary); color: var(--kd-on-primary); border-color: transparent; }

/* dine-in / take-away */
.kd-where { display: grid; grid-template-columns: 1fr 1fr; gap: calc(var(--kd-gap) * 1.4); }
.kd-where-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--kd-gap);
    aspect-ratio: 4 / 5;
    padding: var(--kd-pad);
    border-radius: calc(var(--kd-card-r) * 1.3);
    background: var(--kd-surface);
    border: var(--kd-border) solid var(--kd-line);
    box-shadow: var(--kd-shadow);
    color: var(--kd-text);
    cursor: pointer;
    transition: transform .16s var(--kd-ease);
}
.kd-where-card img { width: 52%; aspect-ratio: 1; object-fit: contain; }
.kd-where-card .kd-display { font-size: calc(var(--kd-u) * 2); text-align: center; }
.kd-where-card:active { transform: scale(.97); }
.kd-where-card:first-child { background: var(--kd-primary); color: var(--kd-on-primary); border-color: transparent; }
/* 2026-10-29 fix (Marc: "the BACK button does not work"): z-index 5 put the button UNDER the invisible long-press
   reload corner (#divHidMenu_Left, z-index 50, top-left 120 px), which swallowed every click. 60 = above it; the
   admin long-press still works on the rest of the corner. */
.kd .kd-back, .kd .k-button.kd-back { position: absolute; top: calc(var(--kd-pad) * 1.2); left: var(--kd-pad); z-index: 60; }
.kd-back svg { transform: rotate(180deg); }

/* ================================================================= MENU */
.kd-menu { --kd-rail-w: min(24vw, calc(var(--kd-u) * 11.5)); --kd-ticket-w: min(36vw, calc(var(--kd-u) * 21)); }

.kd-header {
    flex: none;
    display: flex;
    align-items: center;
    gap: var(--kd-gap);
    padding: calc(var(--kd-pad) * .8) var(--kd-pad);
    border-bottom: var(--kd-border) solid var(--kd-line);
    background: color-mix(in srgb, var(--kd-bg) 86%, transparent);
    backdrop-filter: blur(12px);
    z-index: 4;
}
.kd-header-logo { height: calc(var(--kd-logo-h) * var(--kd-scale)); max-width: 40vw; object-fit: contain; cursor: pointer; }
.kd-header-logo-ph { height: var(--kd-touch); width: var(--kd-touch); } /* invisible fullscreen tap target only */
.kd-header-spacer { flex: 1 1 auto; }
.kd-header-title { font-size: calc(var(--kd-u) * 1.6); margin: 0; }

.kd-banner { flex: none; height: 16vmin; margin: var(--kd-gap) var(--kd-pad) 0; border-radius: var(--kd-card-r); background: var(--kd-banner-img) center / cover no-repeat; box-shadow: var(--kd-shadow); }

.kd-body { position: relative; flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
.kd-menu-rail .kd-body { grid-template-columns: var(--kd-rail-w) 1fr; grid-template-rows: 1fr; }

/* categories */
.kd-cats { display: flex; gap: calc(var(--kd-gap) * .7); overflow: auto; scrollbar-width: none; -ms-overflow-style: none; }
.kd-cats::-webkit-scrollbar { display: none; }
.kd-menu-tabs .kd-cats { padding: var(--kd-gap) var(--kd-pad); flex-direction: row; border-bottom: var(--kd-border) solid var(--kd-line); }
.kd-menu-rail .kd-cats { flex-direction: column; padding: var(--kd-gap) calc(var(--kd-gap) * .8) calc(var(--kd-touch) * 2.4); border-right: var(--kd-border) solid var(--kd-line); }

.kd-cat {
    position: relative;
    flex: none;
    display: flex;
    align-items: center;
    gap: .7em;
    min-height: var(--kd-touch);
    padding: .45em 1em .45em .45em;
    border-radius: var(--kd-btn-r);
    color: var(--kd-text);
    font-weight: 600;
    font-size: calc(var(--kd-u) * 1.02);
    line-height: 1.15;
    cursor: pointer;
    transition: background-color .2s var(--kd-ease), color .2s;
}
.kd-cat img { width: calc(var(--kd-touch) * .82); height: calc(var(--kd-touch) * .82); border-radius: calc(var(--kd-btn-r) * .7); object-fit: cover; flex: none; background: var(--kd-surface-2); }
.kd-menu-rail .kd-cat { flex-direction: column; align-items: center; text-align: center; padding: .7em .5em; gap: .5em; }
.kd-menu-rail .kd-cat img { width: min(72%, calc(var(--kd-touch) * 1.6)); height: auto; aspect-ratio: 1; }
.kd-cat.active { background: var(--kd-accent); color: var(--kd-on-accent); }
.kd-cat.active img { box-shadow: 0 0 0 3px var(--kd-on-accent); }
.kd-cat:active { transform: scale(.97); }

/* product grid */
.kd-grid {
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: var(--kd-pad) var(--kd-pad) calc(var(--kd-touch) * 3);
    display: grid;
    /* fluid: as many columns as fit the design's minimum card width (token ProdCols): adapts to any size/orientation */
    grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--kd-card-min, calc(var(--kd-u) * 14))), 1fr));
    gap: calc(var(--kd-gap) * 1.2);
    align-content: start;
    grid-auto-rows: max-content; /* rows size to the card content (cards are overflow:hidden → min-content 0 otherwise collapses rows) */
    scrollbar-width: thin;
    scroll-behavior: smooth;
}
.kd.kd-cols-2 { --kd-card-min: calc(var(--kd-u) * 17); } .kd.kd-cols-3 { --kd-card-min: calc(var(--kd-u) * 14); } .kd.kd-cols-4 { --kd-card-min: calc(var(--kd-u) * 11); }
.kd.kd-density-compact { --kd-gap: calc(var(--kd-u) * .75); --kd-pad: calc(var(--kd-u) * 1.1); }
.kd.kd-density-compact.kd-cols-3 { --kd-card-min: calc(var(--kd-u) * 12.5); }

.kd-section-title { grid-column: 1 / -1; font-size: calc(var(--kd-u) * 1.7); margin: calc(var(--kd-gap) * .4) 0 0; }
.kd-sep { grid-column: 1 / -1; height: 0; border-top: 2px dashed var(--kd-line); margin: calc(var(--kd-gap) * .3) 0; }

/* card: shared */
.kd-card {
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    border-radius: var(--kd-card-r);
    background: var(--kd-surface);
    border: var(--kd-border) solid var(--kd-line);
    box-shadow: var(--kd-shadow);
    overflow: hidden;
    flex-shrink: 0;
    cursor: pointer;
    transition: transform .16s var(--kd-ease), box-shadow .25s var(--kd-ease);
}
.kd-card:active { transform: scale(.98); }
.kd-card-pic { position: relative; width: 100%; aspect-ratio: 4 / 3; background: var(--kd-surface-2); overflow: hidden; }
.kd-card-pic img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .6s var(--kd-ease-out); }
.kd-card-body { display: flex; flex-direction: column; gap: .35em; padding: calc(var(--kd-gap) * .9) var(--kd-gap) var(--kd-gap); flex: 1 1 auto; min-width: 0; }
.kd-card-name { font-family: var(--kd-font-display); font-weight: var(--kd-display-weight); text-transform: var(--kd-display-case); letter-spacing: var(--kd-display-track); font-size: calc(var(--kd-u) * 1.25); line-height: 1.1; overflow-wrap: anywhere; }
.kd-card-desc { color: var(--kd-dim); font-size: calc(var(--kd-u) * .86); line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.kd-card-meta { color: var(--kd-dim); font-size: calc(var(--kd-u) * .78); }
.kd-card-foot { margin-top: auto; padding-top: .5em; display: flex; align-items: center; justify-content: space-between; gap: .6em; flex-wrap: wrap; }
.kd-card-price { font-size: calc(var(--kd-u) * 1.3); }
.kd .kd-add, .kd .k-button.kd-add { min-height: calc(var(--kd-touch) * .9); min-width: calc(var(--kd-touch) * .9); padding: 0 .9em; font-size: var(--kd-u); }
.kd-card.kd-off { opacity: .5; filter: grayscale(.8); }
.kd-badge { position: absolute; top: .7em; left: .7em; z-index: 2; padding: .25em .7em; border-radius: 999px; font-size: calc(var(--kd-u) * .74); font-weight: 700; background: var(--kd-accent); color: var(--kd-on-accent); }
.kd-badge.kd-badge-off { background: var(--kd-text); color: var(--kd-bg); }
.kd-badge-suggest { position: absolute; top: .55em; right: .55em; z-index: 2; width: 2.4em; height: 2.4em; }
.kd-badge-suggest img { width: 100%; height: 100%; object-fit: contain; }

/* card: FILL: the photo IS the card, name + price over a scrim (white text on scrim on purpose) */
.kd-card-fill .kd-card.kd-has-pic { aspect-ratio: 4 / 5; background: var(--kd-surface-2); }
.kd-card-fill .kd-card.kd-has-pic .kd-card-pic { position: absolute; inset: 0; aspect-ratio: auto; height: 100%; }
.kd-card-fill .kd-card.kd-has-pic .kd-card-pic::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(var(--kd-scrim-rgb), 0) 38%, rgba(var(--kd-scrim-rgb), .78) 100%); }
.kd-card-fill .kd-card.kd-has-pic .kd-card-body { position: relative; margin-top: auto; flex: none; color: var(--kd-on-photo); }
.kd-card-fill .kd-card.kd-has-pic .kd-card-desc, .kd-card-fill .kd-card.kd-has-pic .kd-card-meta { color: color-mix(in srgb, var(--kd-on-photo) 78%, transparent); -webkit-line-clamp: 2; }
.kd-card-fill .kd-card.kd-has-pic .kd-card-price { color: var(--kd-on-photo); }

/* card: LIST: one row, readable from far away */
.kd.kd-card-list { --kd-card-min: calc(var(--kd-u) * 30); }
.kd-card-list .kd-card { flex-direction: row; align-items: stretch; min-height: calc(var(--kd-touch) * 1.7); }
.kd-card-list .kd-card-pic { width: calc(var(--kd-touch) * 2.1); aspect-ratio: 1; flex: none; }
.kd-card-list .kd-card-body { flex-direction: row; align-items: center; gap: var(--kd-gap); flex-wrap: wrap; }
.kd-card-list .kd-card-text { flex: 1 1 14em; min-width: 0; display: flex; flex-direction: column; gap: .25em; }
.kd-card-list .kd-card-foot { margin-top: 0; padding-top: 0; flex: none; }

/* upsell (shown once before paying) */
.kd-upsell { grid-column: 1 / -1; display: flex; align-items: center; gap: var(--kd-gap); flex-wrap: wrap; padding: var(--kd-gap) calc(var(--kd-gap) * 1.2); border-radius: var(--kd-card-r); background: var(--kd-accent-soft); border: var(--kd-border) solid var(--kd-accent); }
.kd-upsell-msg { flex: 1 1 16em; font-size: calc(var(--kd-u) * 1.35); margin: 0; }
.kd-menu-upsell .kd-body { grid-template-columns: 1fr; }

/* ---------------------------------------------------------------- the TICKET (cart) */
.kd-ticket-wrap { position: absolute; right: var(--kd-pad); bottom: var(--kd-pad); width: var(--kd-ticket-w); max-height: 36%; display: flex; flex-direction: column; z-index: 6; filter: drop-shadow(0 18px 30px rgba(var(--kd-shadow-rgb), .32)); }
@media (orientation: landscape) {
    .kd-cart-ticket:not(.kd-port) .kd-body { grid-template-columns: 1fr var(--kd-ticket-w); }
    .kd-menu-rail.kd-cart-ticket:not(.kd-port) .kd-body { grid-template-columns: var(--kd-rail-w) 1fr var(--kd-ticket-w); }
    .kd-cart-ticket:not(.kd-port) .kd-ticket-wrap { position: relative; right: auto; bottom: auto; width: auto; max-height: none; height: 100%; padding: var(--kd-gap) var(--kd-pad) var(--kd-pad) 0; }
}
.kd-cart-ticket.kd-land .kd-body { grid-template-columns: 1fr var(--kd-ticket-w); }
.kd-menu-rail.kd-cart-ticket.kd-land .kd-body { grid-template-columns: var(--kd-rail-w) 1fr var(--kd-ticket-w); }
.kd-cart-ticket.kd-land .kd-ticket-wrap { position: relative; right: auto; bottom: auto; width: auto; max-height: none; height: 100%; padding: var(--kd-gap) var(--kd-pad) var(--kd-pad) 0; }
.kd-ticket {
    position: relative;
    display: flex;
    flex-direction: column;
    min-height: 0;
    background: var(--kd-paper);
    color: var(--kd-ink);
    font-family: var(--kd-font-body);
    padding: calc(var(--kd-gap) * 1.2) calc(var(--kd-gap) * 1.1) var(--kd-gap);
    border-radius: 0 0 6px 6px;
    margin-top: 10px;
}
/* torn top edge: the paper just came out of the printer */
.kd-ticket::before, .kd-thanks-ticket::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    height: 10px;
    background: linear-gradient(-45deg, var(--kd-paper) 7px, transparent 0) 0 100% / 14px 10px repeat-x, linear-gradient(45deg, var(--kd-paper) 7px, transparent 0) 0 100% / 14px 10px repeat-x;
}
.kd-ticket::before { top: -10px; }
.kd-thanks-ticket::after { bottom: -10px; transform: scaleY(-1); }
.kd-ticket-head { display: flex; align-items: baseline; justify-content: space-between; gap: .5em; padding-bottom: .6em; border-bottom: 2px dashed var(--kd-ink-line); }
.kd-ticket-head .kd-display { font-size: calc(var(--kd-u) * 1.2); }
.kd-ticket-count { font-size: calc(var(--kd-u) * .85); color: var(--kd-ink-dim); }
.kd-ticket-lines { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: .4em 0; scrollbar-width: none; display: flex; flex-direction: column-reverse; } /* newest line next to the "printer" */
.kd-ticket-lines-inner { display: flex; flex-direction: column; }
.kd-tline { display: grid; grid-template-columns: auto 1fr auto; gap: .55em; align-items: baseline; padding: .32em 0; font-size: calc(var(--kd-u) * .92); line-height: 1.25; }
.kd-tline-qty { font-weight: 700; min-width: 1.6em; }
.kd-tline-name { overflow-wrap: anywhere; }
.kd-tline-sub { grid-column: 2 / 3; color: var(--kd-ink-dim); font-size: .86em; margin-top: -.2em; }
.kd-tline.kd-tline-child { padding-left: 1.6em; font-size: calc(var(--kd-u) * .82); color: var(--kd-ink-dim); }
.kd-ticket-empty { color: var(--kd-ink-dim); font-size: calc(var(--kd-u) * .92); padding: .8em 0; text-align: center; }
.kd-ticket-total { display: flex; justify-content: space-between; align-items: baseline; padding: .7em 0 .8em; border-top: 2px dashed var(--kd-ink-line); font-size: calc(var(--kd-u) * 1.25); font-weight: 800; }
.kd-ticket .kd-btn, .kd-ticket .k-button.kd-btn { width: 100%; }
.kd-ticket-actions { display: flex; flex-direction: column; gap: .5em; }
.kd .kd-ticket .k-button.kd-btn-ghost { color: var(--kd-ink); border-color: var(--kd-ink-line); }

/* portrait TICKET floats bottom-right: the grid scrolls far enough that no product stays hidden under it */
.kd-cart-ticket .kd-grid { padding-bottom: calc(36vh + var(--kd-pad)); }
/* landscape screens (tablets on their side, wide kiosks): shorter cards so 2+ rows stay visible */
@media (orientation: landscape) {
    .kd-cart-ticket:not(.kd-port) .kd-grid { padding-bottom: var(--kd-pad); }
    .kd-card-fill:not(.kd-port) .kd-card.kd-has-pic { aspect-ratio: 1 / 1; }
    .kd:not(.kd-port) .kd-card-pic { aspect-ratio: 16 / 10; }
    .kd-menu:not(.kd-port) { --kd-ticket-w: min(30vw, calc(var(--kd-u) * 19)); }
}
.kd-cart-ticket.kd-land .kd-grid { padding-bottom: var(--kd-pad); }
.kd-card-fill.kd-land .kd-card.kd-has-pic { aspect-ratio: 1 / 1; }
.kd.kd-land .kd-card-pic { aspect-ratio: 16 / 10; }
.kd-menu.kd-land { --kd-ticket-w: min(30vw, calc(var(--kd-u) * 19)); }
.kd-card-list .kd-card-pic { aspect-ratio: 1 !important; }

/* the BAR (cart) */
.kd-bar { flex: none; display: flex; align-items: center; gap: var(--kd-gap); padding: var(--kd-gap) var(--kd-pad); border-top: var(--kd-border) solid var(--kd-line); background: var(--kd-surface); z-index: 6; }
.kd-bar-count { min-width: 2.2em; height: 2.2em; padding: 0 .5em; border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; background: var(--kd-accent); color: var(--kd-on-accent); font-weight: 800; }
.kd-bar-total { font-size: calc(var(--kd-u) * 1.5); font-weight: 800; }
.kd-bar .kd-header-spacer { flex: 1; }
.kd-ad { flex: none; display: flex; justify-content: center; padding: .4em; }
.kd-ad img { max-height: calc(100px * var(--kd-scale)); border-radius: 8px; }

/* ================================================================= OPTIONS (PgProdOptSelection) */
.kd-opts-head { flex: none; padding: calc(var(--kd-pad) * 1.4) var(--kd-pad) var(--kd-gap); display: flex; flex-direction: column; gap: .4em; }
.kd-opts-step { color: var(--kd-dim); font-size: calc(var(--kd-u) * 1.05); margin: 0; }
.kd-opts-title { font-size: calc(var(--kd-u) * 2.3); margin: 0; }
.kd-opts-grid { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: var(--kd-gap) var(--kd-pad) calc(var(--kd-touch) * 2); display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, calc(var(--kd-u) * 12)), 1fr)); grid-auto-rows: max-content; gap: var(--kd-gap); align-content: start; }
.kd-opt {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .5em;
    padding: var(--kd-gap);
    border-radius: var(--kd-card-r);
    background: var(--kd-surface);
    border: max(2px, var(--kd-border)) solid var(--kd-line);
    box-shadow: var(--kd-shadow);
    text-align: center;
    cursor: pointer;
    transition: transform .14s var(--kd-ease), border-color .2s, background-color .2s;
}
.kd-opt img { width: 72%; aspect-ratio: 1; object-fit: contain; }
.kd-opt-name { font-weight: 700; font-size: calc(var(--kd-u) * 1.05); line-height: 1.2; }
.kd-opt-price { color: var(--kd-price); font-weight: 700; font-size: calc(var(--kd-u) * .92); }
.kd-opt:active { transform: scale(.97); }
.kd-opt.selected { border-color: var(--kd-accent); background: var(--kd-accent-soft); }
.kd-opt-check { position: absolute; top: .5em; right: .5em; width: 2em; height: 2em; border-radius: 999px; display: grid; place-items: center; background: var(--kd-accent); color: var(--kd-on-accent); font-weight: 900; }
.kd-stepper { display: flex; align-items: center; gap: .6em; margin-top: .2em; }
.kd-stepper-val { min-width: 1.6em; font-size: calc(var(--kd-u) * 1.3); font-weight: 800; }
.kd .kd-step, .kd .k-button.kd-step { width: calc(var(--kd-touch) * .82); min-height: calc(var(--kd-touch) * .82); padding: 0; border-radius: 999px; font-size: var(--kd-u); }
.kd-opts-foot { flex: none; display: flex; align-items: center; gap: var(--kd-gap); padding: var(--kd-gap) var(--kd-pad) calc(var(--kd-pad) * 1.2); border-top: var(--kd-border) solid var(--kd-line); background: var(--kd-surface); }
.kd-opts-hint { flex: 1 1 auto; color: var(--kd-dim); font-size: calc(var(--kd-u) * .9); }
.kd-opts-count { padding: .35em .8em; border-radius: 999px; background: var(--kd-accent); color: var(--kd-on-accent); font-weight: 800; }

/* ================================================================= ORDER REVIEW (PgOrder kiosk branch) */
.kd-review { align-items: center; }
.kd-review-inner { width: min(100%, calc(var(--kd-u) * 58)); flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; padding: calc(var(--kd-pad) * 1.4) var(--kd-pad) 0; gap: var(--kd-gap); }
.kd-review-head { display: flex; align-items: center; gap: var(--kd-gap); }
.kd-review-head .kd-display { font-size: calc(var(--kd-u) * 2.4); margin: 0; }
.kd-review .kd-ticket { flex: 1 1 auto; min-height: 0; padding: calc(var(--kd-gap) * 1.6) calc(var(--kd-gap) * 1.6) var(--kd-gap); }
.kd-rline { display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: var(--kd-gap); padding: .7em 0; border-bottom: 1px dashed rgba(var(--kd-ink-rgb), .18); }
.kd-rline-name { font-weight: 700; font-size: calc(var(--kd-u) * 1.1); overflow-wrap: anywhere; }
.kd-rline-sub { color: var(--kd-ink-dim); font-size: calc(var(--kd-u) * .84); margin-top: .15em; }
.kd-rline.kd-rline-child { padding-left: 1.4em; }
.kd-rline.kd-rline-child .kd-rline-name { font-weight: 500; font-size: var(--kd-u); }
.kd-rline.kd-rline-warn { background: color-mix(in srgb, var(--kd-accent) 22%, transparent); }
.kd-rline-qty { display: flex; align-items: center; gap: .5em; }
.kd-rline-qty b { min-width: 1.8em; text-align: center; font-size: calc(var(--kd-u) * 1.2); }
.kd .kd-ticket .k-button.kd-step { background: rgba(var(--kd-ink-rgb), .08); color: var(--kd-ink); }
.kd-rline-price { font-weight: 800; font-size: calc(var(--kd-u) * 1.1); min-width: 5em; text-align: right; }
.kd-review-total { display: flex; justify-content: space-between; align-items: baseline; padding: 1em 0 .4em; font-size: calc(var(--kd-u) * 1.7); font-weight: 900; }
.kd-review-disc { display: flex; justify-content: space-between; color: var(--kd-ink-dim); font-size: calc(var(--kd-u) * 1.05); }
.kd-review-foot { width: 100%; flex: none; display: grid; grid-template-columns: 1fr 1.6fr; gap: var(--kd-gap); padding: var(--kd-gap) var(--kd-pad) calc(var(--kd-pad) * 1.3); max-width: calc(var(--kd-u) * 58); }

/* ================================================================= PAYMENT */
.kd-pay { align-items: center; justify-content: center; text-align: center; gap: calc(var(--kd-gap) * 1.6); padding: var(--kd-pad); }
.kd-pay-amount { font-size: max(calc(var(--kd-u) * 3.2), 12vmin); margin: 0; }
.kd-pay-title { font-size: calc(var(--kd-u) * 2); margin: 0; max-width: 22ch; }
.kd-pay-sub { color: var(--kd-dim); font-size: calc(var(--kd-u) * 1.1); margin: 0; max-width: 40ch; }
.kd-pay-stage { display: inline-flex; align-items: center; gap: .6em; padding: .5em 1.1em; border-radius: 999px; background: var(--kd-primary-soft); color: var(--kd-text); font-weight: 700; }
.kd-pay-stage::before { content: ""; width: .7em; height: .7em; border-radius: 50%; background: var(--kd-primary); }
.kd-pay-hint { padding: 1em 1.3em; border-radius: var(--kd-card-r); background: var(--kd-accent-soft); border: var(--kd-border) solid var(--kd-accent); font-size: calc(var(--kd-u) * 1.2); font-weight: 700; max-width: 30ch; }
.kd-pay-hint .kd-x { display: inline-grid; place-items: center; width: 1.5em; height: 1.5em; border-radius: 6px; background: var(--kd-term-x); color: var(--kd-term-x-on); font-weight: 900; margin: 0 .2em; vertical-align: -.2em; }
.kd-pay-staff { padding: var(--kd-pad); border-radius: var(--kd-card-r); background: var(--kd-surface); border: var(--kd-border) solid var(--kd-line); max-width: 32ch; }
.kd-pay-staff .kd-display { font-size: calc(var(--kd-u) * 3.6); color: var(--kd-accent); margin: .1em 0; }

/* terminal illustration: card glides toward the reader, contactless arcs answer */
.kd-term { position: relative; width: max(calc(var(--kd-u) * 12), 34vmin); aspect-ratio: 1; }
.kd-term-reader { position: absolute; left: 22%; top: 8%; width: 56%; height: 84%; border-radius: 22px; background: var(--kd-surface); border: 3px solid var(--kd-line); box-shadow: var(--kd-shadow); }
.kd-term-reader::before { content: ""; position: absolute; left: 12%; right: 12%; top: 9%; height: 34%; border-radius: 10px; background: var(--kd-primary-soft); border: 2px solid var(--kd-primary); }
.kd-term-reader::after { content: ""; position: absolute; left: 18%; right: 18%; bottom: 10%; height: 36%; background: radial-gradient(circle, var(--kd-line) 22%, transparent 24%) 0 0 / 33.3% 33.3%; }
.kd-term-card { position: absolute; left: 50%; top: 52%; width: 48%; aspect-ratio: 1.586; border-radius: 10px; background: linear-gradient(135deg, var(--kd-primary), var(--kd-accent)); box-shadow: 0 12px 30px -10px rgba(var(--kd-shadow-rgb), .5); transform: translate(-50%, 70%) rotate(-8deg); }
.kd-term-card::before { content: ""; position: absolute; left: 12%; top: 30%; width: 18%; height: 24%; border-radius: 4px; background: color-mix(in srgb, var(--kd-on-photo) 55%, transparent); }
.kd-term-waves { position: absolute; left: 50%; top: 24%; width: 0; height: 0; }
.kd-term-waves i { position: absolute; left: 0; top: 0; width: 40px; height: 40px; margin: -20px; border-radius: 50%; border: 3px solid var(--kd-primary); opacity: 0; }

/* ================================================================= THANKS */
.kd-thanks { align-items: center; justify-content: center; gap: calc(var(--kd-gap) * 1.6); padding: var(--kd-pad); text-align: center; }
.kd-thanks-slot { flex: none; width: min(84vw, calc(var(--kd-u) * 42)); height: calc(22px * var(--kd-scale)); margin-bottom: calc(var(--kd-gap) * -1.6 - 10px); border-radius: 999px; background: var(--kd-surface-2); box-shadow: inset 0 6px 10px rgba(var(--kd-shadow-rgb), .45); position: relative; z-index: 3; }
.kd-thanks-ticket {
    width: 100%;
    margin-top: 0;
    padding: calc(var(--kd-pad) * 1.6) var(--kd-pad) calc(var(--kd-pad) * 1.4);
    background: var(--kd-paper);
    color: var(--kd-ink);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: calc(var(--kd-gap) * .9);
    position: relative;
    transform-origin: top center;
}
.kd-thanks-title { font-size: calc(var(--kd-u) * 1.7); margin: 0; }
.kd-thanks-label { color: var(--kd-ink-dim); font-size: calc(var(--kd-u) * 1.05); margin: 0; }
.kd-thanks-nr { font-size: min(22vmin, 15vw); line-height: .9; margin: 0; color: var(--kd-ink); }
.kd-thanks-msg { font-size: calc(var(--kd-u) * 1.05); max-width: 32ch; margin: 0; }
.kd-thanks-qr { padding: .6em; background: var(--kd-qr-bg); border-radius: 12px; }
.kd-thanks-img { width: 100%; height: 14vmin; background: var(--kd-thanks-img) center / cover no-repeat; border-radius: 10px; }
.kd-thanks-rule { width: 100%; border-top: 2px dashed var(--kd-ink-line); }
.kd-thanks-foot { padding-top: var(--kd-gap); display: flex; flex-direction: column; align-items: center; gap: .6em; }
.kd-countdown { position: relative; display: inline-grid; place-items: center; }
.kd-countdown svg { position: absolute; inset: -10px; width: calc(100% + 20px); height: calc(100% + 20px); pointer-events: none; overflow: visible; }
.kd-countdown rect { x: 1.5px; y: 1.5px; width: calc(100% - 3px); height: calc(100% - 3px); rx: var(--kd-btn-r); fill: none; stroke: var(--kd-primary); stroke-width: 3; stroke-dasharray: 1; stroke-dashoffset: 0; }

/* ================================================================= UNAVAILABLE (PgKioskMsg) */
.kd-offline { align-items: center; justify-content: center; gap: calc(var(--kd-gap) * 2); text-align: center; padding: var(--kd-pad); }
.kd-offline img { height: calc(var(--kd-logo-h) * 1.4 * var(--kd-scale)); max-width: 70vw; object-fit: contain; }
.kd-offline-card { font-size: calc(var(--kd-u) * 1.5); max-width: 26ch; padding: 1.2em 1.4em; border-radius: var(--kd-card-r); background: var(--kd-surface); border: var(--kd-border) solid var(--kd-line); }

/* ================================================================= MOTION
   Gate: kd-anim-off kills everything; kd-anim-subtle keeps fades only; kd-anim-full adds movement.
   Every keyframe is opacity/transform only (GPU-cheap on kiosk SoCs). */
@keyframes kd-rise { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
@keyframes kd-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes kd-slide { from { opacity: 0; transform: translateX(42px); } to { opacity: 1; transform: none; } }
@keyframes kd-zoom { from { transform: scale(1.0); } to { transform: scale(1.09); } }
@keyframes kd-print { from { opacity: 0; transform: translateY(-14px); clip-path: inset(0 0 100% 0); } to { opacity: 1; transform: none; clip-path: inset(0 0 0 0); } }
@keyframes kd-feed { from { transform: translateY(-100%); } to { transform: none; } }
@keyframes kd-pop { 0% { transform: scale(1); } 40% { transform: scale(1.12); } 100% { transform: scale(1); } }
@keyframes kd-glide { 0% { transform: translate(-50%, 70%) rotate(-8deg); } 55%, 70% { transform: translate(-50%, -22%) rotate(0deg); } 100% { transform: translate(-50%, 70%) rotate(-8deg); } }
@keyframes kd-wave { 0% { opacity: .9; transform: scale(.4); } 100% { opacity: 0; transform: scale(3.2); } }
@keyframes kd-draw { from { stroke-dashoffset: 0; } to { stroke-dashoffset: 1; } }
@keyframes kd-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/* welcome: the one orchestrated entrance */
.kd-anim-subtle .kd-welcome-body > *, .kd-anim-full .kd-welcome-body > * { animation: kd-fade .7s var(--kd-ease-out) both; }
.kd-anim-full .kd-welcome-body > * { animation-name: kd-rise; }
.kd-welcome-body > :nth-child(2) { animation-delay: .08s; } .kd-welcome-body > :nth-child(3) { animation-delay: .16s; } .kd-welcome-body > :nth-child(4) { animation-delay: .26s; } .kd-welcome-body > :nth-child(5) { animation-delay: .36s; }
.kd-anim-full .kd-lang { animation: kd-rise .6s var(--kd-ease-out) both; }
.kd-anim-full .kd-lang:nth-child(2) { animation-delay: .42s; } .kd-anim-full .kd-lang:nth-child(3) { animation-delay: .48s; } .kd-anim-full .kd-lang:nth-child(4) { animation-delay: .54s; } .kd-anim-full .kd-lang:nth-child(5) { animation-delay: .6s; } .kd-anim-full .kd-lang:nth-child(n+6) { animation-delay: .66s; }
.kd-anim-full .kd-welcome-logo { animation: kd-fade 1s ease both; }
.kd-anim-full .kd-welcome-media .kd-hero-img, .kd-anim-full .kd-welcome-media > img { animation: kd-zoom 24s ease-in-out infinite alternate; }
.kd-anim-full .kd-where-card { animation: kd-rise .55s var(--kd-ease-out) both; }
.kd-anim-full .kd-where-card + .kd-where-card { animation-delay: .08s; }

/* page transitions (design token PageTrans): on the content block of each page */
.kd-anim-subtle .kd-enter, .kd-trans-fade.kd-anim-full .kd-enter { animation: kd-fade .45s ease both; }
.kd-trans-rise.kd-anim-full .kd-enter { animation: kd-rise .5s var(--kd-ease-out) both; }
.kd-trans-slide.kd-anim-full .kd-enter { animation: kd-slide .45s var(--kd-ease-out) both; }

/* menu: products answer a category change; ticket prints the new line */
.kd-anim-full .kd-grid > .kd-card { animation: kd-rise .42s var(--kd-ease-out) both; }
.kd-anim-full .kd-grid > .kd-card:nth-child(2) { animation-delay: .03s; } .kd-anim-full .kd-grid > .kd-card:nth-child(3) { animation-delay: .06s; } .kd-anim-full .kd-grid > .kd-card:nth-child(4) { animation-delay: .09s; } .kd-anim-full .kd-grid > .kd-card:nth-child(5) { animation-delay: .12s; } .kd-anim-full .kd-grid > .kd-card:nth-child(6) { animation-delay: .15s; } .kd-anim-full .kd-grid > .kd-card:nth-child(n+7) { animation-delay: .18s; }
.kd-anim-subtle .kd-tline, .kd-anim-full .kd-tline { animation: kd-print .5s var(--kd-ease-out) both; }
.kd-anim-full .kd-bar-count, .kd-anim-full .kd-ticket-count { animation: kd-pop .4s var(--kd-ease) both; }
.kd-anim-full .kd-cat.active { animation: kd-pop .35s var(--kd-ease) both; }
.kd-anim-full .kd-card:active .kd-card-pic img { transform: scale(1.05); }

/* payment */
.kd-anim-subtle .kd-term-waves i, .kd-anim-full .kd-term-waves i { animation: kd-wave 2.4s ease-out infinite; }
.kd-term-waves i:nth-child(2) { animation-delay: .8s !important; } .kd-term-waves i:nth-child(3) { animation-delay: 1.6s !important; }
.kd-anim-full .kd-term-card { animation: kd-glide 3.2s var(--kd-ease) infinite; }
.kd-anim-subtle .kd-pay-stage::before, .kd-anim-full .kd-pay-stage::before { animation: kd-pulse 1.4s ease-in-out infinite; }

/* thanks: the ticket is fed out of the slot */
.kd-anim-subtle .kd-thanks-ticket { animation: kd-fade .6s ease both; }
.kd-anim-full .kd-thanks-ticket { animation: kd-feed 1.1s cubic-bezier(.3, 1.2, .4, 1) both; }
/* clip box always present */ .kd-thanks-ticket-clip { width: min(76vw, calc(var(--kd-u) * 37)); overflow: hidden; padding: 0 30px 40px; margin: 0 -30px; box-sizing: content-box; filter: drop-shadow(0 22px 34px rgba(var(--kd-shadow-rgb), .3)); }
.kd-countdown rect { animation: kd-draw var(--kd-count, 30s) linear both; }

/* POP add animation (design token AddAnim=POP): ticket/bar bounces instead of a flying picture */
.kd-add-pop .kd-ticket-wrap.kd-bump, .kd-add-pop .kd-bar.kd-bump { animation: kd-pop .45s var(--kd-ease) both; }

.kd-anim-off *, .kd-anim-off *::before, .kd-anim-off *::after { animation: none !important; transition: none !important; }
@media (prefers-reduced-motion: reduce) {
    .kd *, .kd *::before, .kd *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
    .kd-countdown rect { animation: none !important; }
}

/* ================================================================= BACK-OFFICE PREVIEW FRAME
   The preview renders a real kd root inside a device frame: position fixed -> absolute, and vmin-based
   units are emulated through --kd-preview-vmin set by the frame (container query units). */
.kd-preview-frame { position: relative; width: 100%; container-type: inline-size; border-radius: 18px; overflow: hidden; background: var(--kd-preview-bezel); box-shadow: 0 0 0 10px var(--kd-preview-bezel), 0 0 0 11px var(--kd-preview-bezel-edge), 0 30px 60px -20px rgba(var(--kd-shadow-rgb), .6); }
.kd-preview-frame.kd-preview-port { aspect-ratio: 9 / 16; }
.kd-preview-frame.kd-preview-land { aspect-ratio: 16 / 9; }
.kd-preview-frame > .kd { position: absolute; --kd-scale: .46; --kd-u: calc(var(--kd-fs) * 1.57cqmin); --kd-touch: calc(var(--kd-u) * 3.4); }
.kd-preview-frame .kd-welcome-title { font-size: 12cqmin; }
.kd-preview-frame .kd-pay-amount { font-size: 12cqmin; }
.kd-preview-frame .kd-thanks-nr { font-size: 17cqmin; }
.kd-preview-port .kd-ticket-wrap { position: absolute; }
.kd-preview-frame .kd-thanks-slot { width: 84%; } .kd-preview-frame .kd-thanks-ticket-clip { width: 74%; }
.kd-preview-frame * { pointer-events: none; }
.kd-preview-frame .kd-preview-click { pointer-events: auto; }
.kd .kd-stop { display: contents; }

/* kiosk demo 2026-10-29 (v2 overlap root cause): the boot splash of the kiosk hosts (index.html → divEffects.js
   apply3dGlowingTextEffect("divLogo_index")) injects <style id="divfx_style_glow3d"> with UNSCOPED global rules
   (h1 { position:absolute; width:100%; text-align:center; text-transform:uppercase; animation:glow },
   h1:nth-child(n) { transform:translateZ() }, figure { animation:wobble }) that stay in <head> for the whole session.
   Every v2 <h1> (welcome / options / payment / thanks / review titles) was therefore absolutely positioned and
   overlapped its siblings. Neutralized here for the v2 skin only (.kd): CLASSIC is untouched. Specificity (0,2,1)
   beats both injected selectors; .kd-enter titles keep their entrance animation. */
.kd h1:nth-child(n) { position: static; width: auto; text-align: inherit; transform: none; }
.kd h1:nth-child(n):not(.kd-enter) { animation: none; }
.kd figure:nth-child(n) { animation: none; transform-style: flat; }

/* =================================================================================================================
   2026-10-29 DEMO REDESIGN (user: too simple, looks cheap): appended on purpose so it layers over the base rules.
   Photography-first: product CUT-OUTS on a warm spotlight (token PicStyle=CUTOUT), photo cards for eat-in /
   take-away, landscape hero variant, a new message box (UcKdMsgBox), richer payment stage, demo theme bar offset.
   Still tokens only.
   ================================================================================================================= */

/* ---------------------------------------------------------------- demo theme bar (UcKioskDemoRibbon) pushes the screen down */
body:has(.kd-demo-bar) { --kd-demo-bar-h: 64px; }
body:has(.kd-demo-bar) .kd:not(.kd-mb):not(.kd-pd) { top: var(--kd-demo-bar-h); } /* .kd-pd = in-flow sheet inside a popup window, not a screen */

/* ---------------------------------------------------------------- welcome */
@media (orientation: landscape) {
    .kd-welcome-media .kd-hero-img { background-image: var(--kd-welcome-img-land, var(--kd-welcome-img)); }
    .kd.kd-has-welcome .kd-welcome-body { max-width: min(100%, calc(var(--kd-u) * 40)); }
    /* the landscape scenes keep their LEFT half calm for the text: a side scrim under the title */
    .kd.kd-has-welcome .kd-welcome-media::before { content: ""; position: absolute; inset: 0; z-index: 1; background: linear-gradient(90deg, rgba(var(--kd-bg-rgb), .82) 0%, rgba(var(--kd-bg-rgb), .35) 42%, rgba(var(--kd-bg-rgb), 0) 62%); }
}
.kd-welcome-media::after { z-index: 1; }
.kd-welcome-logo { filter: drop-shadow(0 10px 30px rgba(var(--kd-shadow-rgb), .45)); }
.kd-welcome-title { font-size: max(calc(var(--kd-u) * 3.4), 13vmin); line-height: .96; }
.kd-welcome-sub { color: color-mix(in srgb, var(--kd-text) 78%, transparent); }
.kd-lang { backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); background: color-mix(in srgb, var(--kd-surface) 78%, transparent); }
.kd-lang.on { background: var(--kd-primary); }
.kd-lang img { width: 1.7em; height: 1.7em; border-radius: 50%; box-shadow: 0 0 0 2px color-mix(in srgb, var(--kd-text) 14%, transparent); }
.kd-lang.on img { box-shadow: 0 0 0 2px color-mix(in srgb, var(--kd-on-primary) 35%, transparent); }
/* narrow screens (split view, small tablets): long language names ("NEDERLANDS") stay inside the button */
.kd-lang { min-width: 0; font-size: min(calc(var(--kd-u) * 1.35), 4.4vw); padding: 0 min(1.2em, 3vw); gap: min(.9em, 2.4vw); }
.kd-lang span { min-width: 0; overflow-wrap: anywhere; line-height: 1.1; }

/* eat-in / take-away: photo cards, the label rides on the photo */
.kd-where-card { padding: 0; overflow: hidden; isolation: isolate; justify-content: flex-end; align-items: stretch; aspect-ratio: 4 / 5; background: var(--kd-surface-2); border-color: var(--kd-line); }
.kd-where-card:first-child { background: var(--kd-surface-2); color: var(--kd-on-photo); border-color: var(--kd-line); }
.kd-where-card img { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; aspect-ratio: auto; object-fit: cover; transition: transform .9s var(--kd-ease-out); }
.kd-where-card::after { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(180deg, rgba(var(--kd-scrim-rgb), 0) 38%, rgba(var(--kd-scrim-rgb), .84) 100%); }
.kd-where-label { display: flex; align-items: center; justify-content: space-between; gap: .6em; width: 100%; padding: calc(var(--kd-pad) * 1.1); color: var(--kd-on-photo); text-align: left; }
/* label ABOVE the arrow (user 2026-10-29: "TAKEAWA-Y" was cut inside the word): the word gets the card's full width,
   never breaks inside a word, and only shrinks if a single word is still wider than the card.
   was: .kd-where-card .kd-display { font-size: min(calc(var(--kd-u) * 2.1), 6vw); text-align: left; min-width: 0; overflow-wrap: anywhere; }
   was: .kd-where-label { padding: min(calc(var(--kd-pad) * 1.1), 4vw); } (label and arrow on one row) */
.kd-where-card .kd-display { font-size: min(calc(var(--kd-u) * 2.1), 5.6vw); text-align: left; min-width: 0; max-width: 100%; overflow-wrap: normal; word-break: keep-all; hyphens: manual; line-height: 1.05; }
.kd-where-label { flex-direction: column; align-items: flex-start; justify-content: flex-end; gap: .55em; padding: min(calc(var(--kd-pad) * 1.1), 4vw); }
.kd-where-go { width: min(calc(var(--kd-touch) * .95), 11vw); }
.kd-where-go { flex: none; width: calc(var(--kd-touch) * .95); aspect-ratio: 1; border-radius: 50%; display: grid; place-items: center; background: var(--kd-primary); color: var(--kd-on-primary); box-shadow: 0 10px 24px -10px rgba(var(--kd-shadow-rgb), .7); }
.kd-where-go svg { width: 44%; height: 44%; fill: currentColor; }
.kd-where-card:active img { transform: scale(1.07); }
.kd-anim-full .kd-where-card img { animation: kd-zoom 20s ease-in-out infinite alternate; }

/* ---------------------------------------------------------------- menu */
.kd-banner { position: relative; overflow: hidden; height: 18vmin; }
.kd-banner::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 1px rgba(var(--kd-text-rgb), .08), inset 0 -40px 60px -30px rgba(var(--kd-bg-rgb), .55); }
.kd-header { border-bottom-color: color-mix(in srgb, var(--kd-line) 70%, transparent); }
.kd-header-logo { height: calc(var(--kd-logo-h) * .62 * var(--kd-scale)); }
/* rail: the selected category is a rounded tile, not a pill (a 999px pill on a tall rail item read as a blob) */
.kd-menu-rail .kd-cat { border-radius: var(--kd-card-r); min-width: 0; padding-left: .3em; padding-right: .3em; }
/* rail names wrap inside the rail on narrow screens ("Acompañamientos", "Hamburguesas") instead of being clipped */
.kd-menu-rail .kd-cat span { max-width: 100%; min-width: 0; overflow-wrap: anywhere; hyphens: auto; font-size: min(1em, 3.3vw); }

/* upsell step ("anything else?"): the question + Pay button stay pinned at the top while the products scroll
   (user 2026-10-29); solid ground so the cards never show through it */
.kd-upsell {
    position: sticky;
    top: 0;
    z-index: 4;
    background: color-mix(in srgb, var(--kd-accent) 16%, var(--kd-bg));
    box-shadow: 0 14px 28px -18px rgba(var(--kd-shadow-rgb), .65);
}

/* upsell entrance (replaces the legacy shake + word-by-word effects in v2): the banner drops in, the cards cascade
   (base rule .kd-grid > .kd-card), the Pay button glows twice to say "you can pay now": then everything rests */
.kd-anim-subtle.kd-menu-upsell .kd-upsell, .kd-anim-full.kd-menu-upsell .kd-upsell { animation: kd-upsell-in .6s var(--kd-ease-out) both; }
.kd-anim-full.kd-menu-upsell .kd-upsell .kd-btn { animation: kd-cta-glow 1.4s ease-out .9s 2 both; }
@keyframes kd-upsell-in { from { opacity: 0; transform: translateY(-18px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes kd-cta-glow {
    0% { box-shadow: 0 0 0 0 rgba(var(--kd-accent-rgb), .55); }
    70% { box-shadow: 0 0 0 calc(var(--kd-u) * 1.1) rgba(var(--kd-accent-rgb), 0); }
    100% { box-shadow: 0 0 0 0 rgba(var(--kd-accent-rgb), 0); }
}

/* best-seller seal (was the legacy Suggest.png) */
.kd-badge-suggest { width: 2.6em; height: 2.6em; border-radius: 50%; display: grid; place-items: center; background: var(--kd-accent); box-shadow: 0 8px 18px -8px rgba(var(--kd-shadow-rgb), .6), 0 0 0 3px color-mix(in srgb, var(--kd-accent) 30%, transparent); }
.kd-badge-suggest svg { width: 56%; height: 56%; fill: var(--kd-on-accent); }
.kd-anim-full .kd-badge-suggest { animation: kd-seal 3.6s var(--kd-ease) infinite; }
@keyframes kd-seal { 0%, 82%, 100% { transform: rotate(0) scale(1); } 88% { transform: rotate(-14deg) scale(1.12); } 94% { transform: rotate(8deg) scale(1.04); } }

.kd-card-name { line-height: 1.12; }
.kd-card-price { font-size: calc(var(--kd-u) * 1.4); letter-spacing: -.01em; }

/* ---- CUT-OUT pictures (transparent product photos float on a warm spotlight) ---- */
.kd-pic-cutout .kd-card-pic {
    background:
        radial-gradient(ellipse 62% 46% at 50% 64%, color-mix(in srgb, var(--kd-primary) 26%, transparent) 0%, transparent 72%),
        radial-gradient(ellipse 90% 70% at 50% 40%, color-mix(in srgb, var(--kd-text) 7%, var(--kd-surface-2)) 0%, var(--kd-surface-2) 75%);
}
.kd-pic-cutout .kd-card-pic img { object-fit: contain; padding: 6% 9% 3%; transform-origin: 50% 72%; filter: drop-shadow(0 16px 14px rgba(var(--kd-shadow-rgb), .38)); }
.kd-pic-cutout.kd-dark .kd-card-pic img { filter: drop-shadow(0 18px 16px rgba(var(--kd-shadow-rgb), .55)); }
.kd-pic-cutout .kd-card:active .kd-card-pic img { transform: scale(1.07) translateY(-2%) rotate(-1.5deg); }
/* FILL + cut-out: the product sits in the upper card, name and price on the card's own ground (no black photo scrim) */
.kd-card-fill.kd-pic-cutout .kd-card.kd-has-pic .kd-card-pic img { padding: 5% 9% 34%; }
.kd-card-fill.kd-pic-cutout .kd-card.kd-has-pic .kd-card-pic::after { background: linear-gradient(180deg, transparent 50%, color-mix(in srgb, var(--kd-surface-2) 96%, transparent) 80%); }
.kd-card-fill.kd-pic-cutout .kd-card.kd-has-pic .kd-card-body { color: var(--kd-text); }
.kd-card-fill.kd-pic-cutout .kd-card.kd-has-pic .kd-card-desc, .kd-card-fill.kd-pic-cutout .kd-card.kd-has-pic .kd-card-meta { color: var(--kd-dim); }
.kd-card-fill.kd-pic-cutout .kd-card.kd-has-pic .kd-card-price { color: var(--kd-price); }
/* LIST + cut-out */
.kd-card-list.kd-pic-cutout .kd-card-pic img { padding: 8%; }
/* categories + options */
.kd-pic-cutout .kd-cat img { object-fit: contain; padding: 7%; background: radial-gradient(circle at 50% 60%, color-mix(in srgb, var(--kd-primary) 20%, var(--kd-surface-2)) 0%, var(--kd-surface-2) 70%); filter: drop-shadow(0 6px 6px rgba(var(--kd-shadow-rgb), .25)); }
.kd-pic-cutout .kd-cat.active img { background: color-mix(in srgb, var(--kd-on-accent) 12%, var(--kd-accent)); }
.kd-pic-cutout .kd-opt img { filter: drop-shadow(0 12px 12px rgba(var(--kd-shadow-rgb), .32)); transition: transform .3s var(--kd-ease); }
.kd-pic-cutout .kd-opt.selected img { transform: scale(1.06) rotate(-2deg); }

/* ---------------------------------------------------------------- payment: a breathing light behind the terminal, a shine on the card */
.kd-term::before { content: ""; position: absolute; inset: -22%; border-radius: 50%; background: radial-gradient(closest-side, rgba(var(--kd-primary-rgb), .28), transparent 70%); }
.kd-anim-full .kd-term::before, .kd-anim-subtle .kd-term::before { animation: kd-breathe 3.2s ease-in-out infinite; }
.kd-term-card { overflow: hidden; }
.kd-term-card::after { content: ""; position: absolute; inset: 0; background: linear-gradient(105deg, transparent 35%, color-mix(in srgb, var(--kd-on-photo) 45%, transparent) 50%, transparent 65%); transform: translateX(-120%); }
.kd-anim-full .kd-term-card::after { animation: kd-shine 3.2s var(--kd-ease) infinite; }
@keyframes kd-breathe { 0%, 100% { opacity: .55; transform: scale(.94); } 50% { opacity: 1; transform: scale(1.04); } }
@keyframes kd-shine { 0%, 40% { transform: translateX(-120%); } 70%, 100% { transform: translateX(120%); } }

/* ---------------------------------------------------------------- ticket: press the head to unroll the full ticket on the
   compact strip (narrow portrait, see the COMPACT TICKET block below: these selectors carry .kd-ticket-wrap/.kd-ticket-open
   on purpose so they win over it without being placed after it). The chevron only exists on the compact strip. */
.kd-ticket-chev { display: none; }
.kd-ticket-head[role="button"] { cursor: pointer; }
@media (max-width: 820px) and (orientation: portrait) {
    .kd-cart-ticket:not(.kd-land) .kd-ticket-wrap .kd-ticket-chev {
        display: grid; place-items: center; flex: none; order: 0;
        width: calc(var(--kd-touch) * .8); height: calc(var(--kd-touch) * .8); border: 0; border-radius: 50%;
        background: rgba(var(--kd-ink-rgb), .08); color: var(--kd-ink); cursor: pointer;
    }
    .kd-ticket-chev svg { width: 46%; height: 46%; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; transition: transform .3s var(--kd-ease); }
    .kd-cart-ticket:not(.kd-land) .kd-ticket-wrap .kd-ticket-head { order: 0; }
    .kd-cart-ticket:not(.kd-land) .kd-ticket-wrap .kd-ticket-total { order: 1; }
    .kd-cart-ticket:not(.kd-land) .kd-ticket-wrap .kd-ticket-actions { order: 3; }
    .kd-cart-ticket:not(.kd-land) .kd-ticket-wrap.kd-ticket-open .kd-ticket-lines {
        display: flex; order: 2; flex: 1 1 100%; max-height: min(52vh, calc(var(--kd-u) * 30)); overflow-y: auto;
        border-top: 2px dashed var(--kd-ink-line); border-bottom: 2px dashed var(--kd-ink-line); padding: .3em 0;
    }
    .kd-cart-ticket:not(.kd-land) .kd-ticket-wrap.kd-ticket-open .kd-ticket-chev svg { transform: rotate(180deg); }
    .kd-anim-full .kd-ticket-wrap.kd-ticket-open .kd-ticket-lines, .kd-anim-subtle .kd-ticket-wrap.kd-ticket-open .kd-ticket-lines { animation: kd-unroll .38s var(--kd-ease-out) both; }
}
/* BAR designs: mini receipt that peeks above the cart bar after "Add" (kiosk-design.js kdAddToOrder → peek) */
.kd-peek {
    position: absolute; right: var(--kd-pad); z-index: 8; pointer-events: none;
    display: flex; align-items: center; gap: .8em; min-width: min(80vw, calc(var(--kd-u) * 20)); max-width: calc(100% - var(--kd-pad) * 2);
    padding: .7em 1em .7em .7em; border-radius: 4px 4px 10px 10px;
    background: var(--kd-paper); color: var(--kd-ink); font-family: var(--kd-font-body);
    box-shadow: 0 22px 40px -18px rgba(var(--kd-shadow-rgb), .55);
}
.kd-peek::before { content: ""; position: absolute; left: 0; right: 0; top: -8px; height: 8px; background: linear-gradient(-45deg, var(--kd-paper) 6px, transparent 0) 0 100% / 12px 8px repeat-x, linear-gradient(45deg, var(--kd-paper) 6px, transparent 0) 0 100% / 12px 8px repeat-x; }
.kd-peek img { width: calc(var(--kd-u) * 3.4); height: calc(var(--kd-u) * 3.4); object-fit: contain; flex: none; filter: drop-shadow(0 6px 6px rgba(var(--kd-shadow-rgb), .3)); }
.kd-peek-txt { display: flex; flex-direction: column; gap: .15em; min-width: 0; flex: 1 1 auto; }
.kd-peek-txt b { font-size: calc(var(--kd-u) * 1.02); line-height: 1.15; overflow-wrap: anywhere; }
.kd-peek-txt span { font-size: calc(var(--kd-u) * .9); color: var(--kd-ink-dim); font-weight: 700; }
.kd-peek-ok { flex: none; width: 1.9em; height: 1.9em; border-radius: 50%; display: grid; place-items: center; font-style: normal; font-weight: 900; background: var(--kd-primary); color: var(--kd-on-primary); }

@keyframes kd-unroll { from { opacity: 0; clip-path: inset(100% 0 0 0); } to { opacity: 1; clip-path: inset(0 0 0 0); } }

/* thanks: the photo strip on the ticket */
.kd-thanks-img { height: 16vmin; border-radius: 12px; box-shadow: inset 0 0 0 1px rgba(var(--kd-ink-rgb), .08); }

/* ================================================================= POPUP WINDOWS (RTT.UI UcCtrlPopup / UcCtrlPopup2, class kd-win)
   2026-10-29 demo redesign (user: "these windows kept my legacy design"). The hosts put the design tokens on the
   window element (inline <style> .k-window.kd-win { --kd-*: ... }); the derived values a .kd root normally defines
   are repeated here because the window is not a .kd root. !important beats the hosts' own legacy <style> blocks. */
.k-window.kd-win {
    --kd-scale: 1; --kd-u: calc(17px * var(--kd-scale) * var(--kd-fs, 1)); --kd-gap: calc(var(--kd-u) * 1.1); --kd-pad: calc(var(--kd-u) * 1.5);
    --kd-touch: max(60px, calc(var(--kd-u) * 3.4)); --kd-shadow-rgb: 0, 0, 0; --kd-ease: cubic-bezier(.2, .8, .2, 1); --kd-ease-out: cubic-bezier(.16, 1, .3, 1);
    background: var(--kd-surface) !important;
    color: var(--kd-text) !important;
    border: var(--kd-border, 1px) solid var(--kd-line) !important;
    border-radius: calc(var(--kd-card-r, 20px) * 1.4) !important;
    box-shadow: 0 40px 90px -30px rgba(var(--kd-shadow-rgb), .7) !important;
    font-family: var(--kd-font-body);
    overflow: hidden;
    max-width: min(92vw, 760px) !important;
    animation: kd-mb-in .44s var(--kd-ease-out) both;
}
.k-window.kd-win[style*="100vw"] { border-radius: 0 !important; border: 0 !important; max-width: none !important; animation: kd-fade .3s ease both; }
.k-window.kd-win .k-window-content { padding: 0; background: transparent; color: inherit; }
.k-window.kd-win .k-window-titlebar { display: none; }
body:has(.k-window.kd-win) .k-overlay { background: rgba(0, 0, 0, .5); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); opacity: 1; animation: kd-fade .25s ease both; }
/* review 2026-10-29: the tablet tiers of the .kd root were missing here: on 10-13" tablets the page ran at 1.1 / 1.25
   while its popups stayed at 1 (smaller text and touch targets in every dialog). Same tiers as the root. */
@media (max-width: 699px), (max-height: 699px) { .k-window.kd-win { --kd-scale: .9; } }
@media (min-width: 700px) and (min-height: 700px) and (min-resolution: 1.5dppx) { .k-window.kd-win { --kd-scale: 1.1; } }
@media (min-width: 1000px) and (min-height: 1000px) and (min-resolution: 1.5dppx) { .k-window.kd-win { --kd-scale: 1.25; } }
@media (min-width: 1300px) and (min-height: 1300px) { .k-window.kd-win { --kd-scale: 1.32; max-width: min(92vw, 1000px) !important; } }
@media (min-width: 1800px) and (min-height: 1800px) { .k-window.kd-win { --kd-scale: 1.95; max-width: min(92vw, 1400px) !important; } }

/* legacy dialog content inside a v2 window (cooking preference, note, options list...): the design's type, colors
   and buttons instead of the black 'adlib' look: the content keeps its own layout */
.k-window.kd-win :is(#divCtrl, #divCtrl2):not(:has(> .kd)) { padding: var(--kd-pad); font-size: var(--kd-u); }
.k-window.kd-win :is(#divCtrl, #divCtrl2):not(:has(> .kd)) [id^="uc"], .k-window.kd-win :is(#divCtrl, #divCtrl2):not(:has(> .kd)) [id^="div"] { background-color: transparent !important; }
.k-window.kd-win :is(#divCtrl, #divCtrl2):not(:has(> .kd)), .k-window.kd-win :is(#divCtrl, #divCtrl2):not(:has(> .kd)) :is(div, label, span, p, input, textarea) { font-family: var(--kd-font-body) !important; color: var(--kd-text); }
.k-window.kd-win :is(#divCtrl, #divCtrl2):not(:has(> .kd)) :is(h1, h2, h3, [id*="Title"], [id*="title"]) { font-family: var(--kd-font-display) !important; font-weight: var(--kd-display-weight); letter-spacing: var(--kd-display-track); }
.k-window.kd-win :is(#divCtrl, #divCtrl2):not(:has(> .kd)) .k-button:not(.kd-btn) {
    min-height: calc(var(--kd-touch) * .85); padding: 0 1.2em; border-radius: var(--kd-btn-r) !important;
    background: var(--kd-surface-2) !important; color: var(--kd-text) !important; border: var(--kd-border, 1px) solid var(--kd-line) !important;
    font-family: var(--kd-font-display) !important; font-weight: var(--kd-display-weight); text-transform: var(--kd-display-case);
}
.k-window.kd-win :is(#divCtrl, #divCtrl2):not(:has(> .kd)) .k-button:not(.kd-btn):last-of-type { background: var(--kd-primary) !important; color: var(--kd-on-primary) !important; border-color: transparent !important; }
.k-window.kd-win :is(#divCtrl, #divCtrl2):not(:has(> .kd)) .k-button svg { fill: currentColor; }
.k-window.kd-win :is(#divCtrl, #divCtrl2):not(:has(> .kd)) :is(input, textarea, .k-input) { background: var(--kd-surface-2) !important; border: 1px solid var(--kd-line) !important; border-radius: calc(var(--kd-btn-r) * .6); color: var(--kd-text) !important; }

/* ---------------------------------------------------------------- product sheet (RTT.Ordering UcProdDet, v2 branch) */
.kd.kd-pd { position: relative; inset: auto; z-index: auto; display: flex; flex-direction: column; width: min(88vw, calc(var(--kd-u) * 38)); max-height: 88vh; overflow: hidden; background: transparent; user-select: none; }
.kd.kd-pd::before, .kd.kd-pd::after { display: none; }
.kd-pd-pic {
    position: relative; flex: none; aspect-ratio: 4 / 3; max-height: 46vh; display: grid; place-items: center; overflow: hidden;
    background:
        radial-gradient(ellipse 62% 46% at 50% 64%, color-mix(in srgb, var(--kd-primary) 28%, transparent) 0%, transparent 72%),
        radial-gradient(ellipse 90% 70% at 50% 40%, color-mix(in srgb, var(--kd-text) 7%, var(--kd-surface-2)) 0%, var(--kd-surface-2) 75%);
}
.kd-pd-pic img { width: 100%; height: 100%; object-fit: contain; padding: 6% 10% 3%; filter: drop-shadow(0 22px 20px rgba(var(--kd-shadow-rgb), .45)); }
.kd-pd:not(.kd-pic-cutout) .kd-pd-pic img { object-fit: cover; padding: 0; filter: none; }
.kd-pd .kd-badge-suggest { position: absolute; top: 1em; right: 1em; font-size: calc(var(--kd-u) * 1.2); }
.kd-anim-full .kd-pd-pic img, .kd-anim-subtle .kd-pd-pic img { animation: kd-pd-in .7s var(--kd-ease-out) .08s both; }
@keyframes kd-pd-in { from { opacity: 0; transform: translateY(24px) scale(.86) rotate(-3deg); } to { opacity: 1; transform: none; } }
.kd-pd-body { display: flex; flex-direction: column; gap: .7em; padding: var(--kd-pad) calc(var(--kd-pad) * 1.2) calc(var(--kd-pad) * 1.2); overflow-y: auto; min-height: 0; }
.kd-pd-off { position: static; align-self: flex-start; }
.kd-pd-title { font-size: calc(var(--kd-u) * 2.1); margin: 0; line-height: 1.05; }
.kd-pd-desc { font-size: calc(var(--kd-u) * 1.1); color: var(--kd-dim); margin: 0; line-height: 1.45; max-width: 46ch; }
.kd-pd-meta { font-size: calc(var(--kd-u) * .85); color: var(--kd-dim); margin: 0; }
.kd-pd-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--kd-gap); flex-wrap: wrap; margin-top: .3em; }
.kd-pd-price { font-size: calc(var(--kd-u) * 2); letter-spacing: -.01em; }
.kd-pd-btns { display: grid; grid-template-columns: 1fr 1fr; gap: var(--kd-gap); margin-top: .5em; }
.kd .kd-pd-btns .kd-btn { width: 100%; padding: 0 .8em; }

/* option tiles without a picture (PgProdOptSelection): a token-colored initial instead of the legacy placeholder */
.kd-opt-glyph { width: 72%; aspect-ratio: 1; display: grid; place-items: center; border-radius: 50%; background: radial-gradient(circle at 50% 40%, color-mix(in srgb, var(--kd-primary) 22%, var(--kd-surface-2)) 0%, var(--kd-surface-2) 72%); color: var(--kd-primary); font-family: var(--kd-font-display); font-weight: var(--kd-display-weight); font-size: calc(var(--kd-u) * 3); line-height: 1; }
.kd-opt.selected .kd-opt-glyph { background: var(--kd-accent); color: var(--kd-on-accent); }
/* option steps: each step's tiles cascade in (the grid is keyed per step): replaces the legacy 1 s slide + dead wait */
.kd-anim-full .kd-opts-grid > .kd-opt { animation: kd-rise .42s var(--kd-ease-out) both; }
.kd-anim-subtle .kd-opts-grid > .kd-opt { animation: kd-fade .3s ease both; }
.kd-anim-full .kd-opts-grid > .kd-opt:nth-child(2) { animation-delay: .03s; } .kd-anim-full .kd-opts-grid > .kd-opt:nth-child(3) { animation-delay: .06s; }
.kd-anim-full .kd-opts-grid > .kd-opt:nth-child(4) { animation-delay: .09s; } .kd-anim-full .kd-opts-grid > .kd-opt:nth-child(5) { animation-delay: .12s; }
.kd-anim-full .kd-opts-grid > .kd-opt:nth-child(n+6) { animation-delay: .15s; }

/* removal options ("No onions"): the ingredient photo + a round "no" mark; once chosen the photo fades back */
.kd-opt-no { position: absolute; top: .55em; left: .55em; z-index: 2; width: 2.3em; height: 2.3em; border-radius: 50%; display: grid; place-items: center; background: var(--kd-surface); color: var(--kd-primary); box-shadow: 0 4px 12px -4px rgba(var(--kd-shadow-rgb), .45); }
.kd-opt-no svg { width: 70%; height: 70%; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; }
.kd-opt-remove.selected img { opacity: .45; filter: grayscale(.6) drop-shadow(0 12px 12px rgba(var(--kd-shadow-rgb), .2)); }
.kd-opt-remove.selected .kd-opt-no { background: var(--kd-primary); color: var(--kd-on-primary); }

/* "No, thanks" card (optional steps): quiet until chosen, then it wears the same selected state as an option */
.kd-opt-none { border-style: dashed; }
.kd-opt-none.selected { border-style: solid; }
.kd-opt-glyph-none { background: var(--kd-surface-2); color: var(--kd-dim); }
.kd-opt-none.selected .kd-opt-glyph-none { background: var(--kd-accent); color: var(--kd-on-accent); }
.kd-opts-foot .k-button.k-disabled { opacity: .4; }
.kd-opt-glyph svg { width: 46%; height: 46%; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
/* cooking: a cut through the meat, pale → deep in the design's main color (data order = doneness) */
.kd-opt-glyph-cook { background: radial-gradient(circle at 50% 50%, var(--kd-cook) 0 46%, color-mix(in srgb, var(--kd-text) 30%, var(--kd-surface-2)) 47% 56%, var(--kd-surface-2) 57%); }
.kd-opt-cook-1 { --kd-cook: color-mix(in srgb, var(--kd-primary) 30%, var(--kd-surface-2)); }
.kd-opt-cook-2 { --kd-cook: color-mix(in srgb, var(--kd-primary) 60%, var(--kd-surface-2)); }
.kd-opt-cook-3 { --kd-cook: var(--kd-primary); }
.kd-opt-cook-4 { --kd-cook: color-mix(in srgb, var(--kd-primary) 70%, var(--kd-text)); }
.kd-opt.selected .kd-opt-glyph-cook { background: radial-gradient(circle at 50% 50%, var(--kd-cook) 0 46%, var(--kd-accent) 47% 60%, var(--kd-surface-2) 61%); }

/* ================================================================= DEMO BUSINESS PICKER (PgKioskDemo, 2026-10-29)
   "What do you sell?": one photo card per business type; the label rides on the photo like the eat-in cards. */
.kd.kd-biz { overflow-y: auto; overflow-x: hidden; }
.kd-biz-inner { width: min(100%, calc(var(--kd-u) * 70)); margin: 0 auto; padding: calc(var(--kd-pad) * 1.6) var(--kd-pad) calc(var(--kd-pad) * 2); display: flex; flex-direction: column; gap: calc(var(--kd-gap) * 1.6); }
.kd-biz-head { display: flex; flex-direction: column; gap: .5em; }
.kd-biz-title { margin: 0; font-size: max(calc(var(--kd-u) * 2.8), 8vmin); line-height: 1; }
.kd-biz-sub { margin: 0; max-width: 40ch; color: var(--kd-dim); font-size: calc(var(--kd-u) * 1.25); }
.kd-biz-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: calc(var(--kd-gap) * 1.1); }
@media (orientation: landscape) { .kd-biz-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.kd-biz-card {
    position: relative; isolation: isolate; overflow: hidden;
    aspect-ratio: 1; padding: 0; border: var(--kd-border) solid var(--kd-line); border-radius: calc(var(--kd-card-r) * 1.2);
    background: var(--kd-surface-2); color: var(--kd-on-photo); cursor: pointer; text-align: left;
    display: flex; align-items: flex-end;
    box-shadow: var(--kd-shadow);
    transition: transform .16s var(--kd-ease);
}
.kd-biz-card img { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; transition: transform .9s var(--kd-ease-out); }
.kd-biz-card::after { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(180deg, rgba(var(--kd-scrim-rgb), 0) 45%, rgba(var(--kd-scrim-rgb), .86) 100%); }
.kd-biz-card:active { transform: scale(.97); }
.kd-biz-card:active img { transform: scale(1.06); }
.kd-biz-card:focus-visible { outline: 3px solid var(--kd-accent); outline-offset: 3px; }
.kd-biz-label { display: flex; flex-direction: column; gap: .2em; width: 100%; padding: calc(var(--kd-gap) * 1.1); }
.kd-biz-name { font-size: min(calc(var(--kd-u) * 1.7), 5.5vw); line-height: 1.05; overflow-wrap: anywhere; }
.kd-biz-tag { font-size: min(calc(var(--kd-u) * .9), 3.4vw); opacity: .85; }
.kd-anim-full .kd-biz-card { animation: kd-rise .5s var(--kd-ease-out) both; }
.kd-anim-full .kd-biz-card:nth-child(2) { animation-delay: .05s; } .kd-anim-full .kd-biz-card:nth-child(3) { animation-delay: .1s; }
.kd-anim-full .kd-biz-card:nth-child(4) { animation-delay: .15s; } .kd-anim-full .kd-biz-card:nth-child(5) { animation-delay: .2s; }
.kd-anim-full .kd-biz-card:nth-child(6) { animation-delay: .25s; } .kd-anim-full .kd-biz-card:nth-child(n+7) { animation-delay: .3s; }
.kd-biz-langs { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; }
.kd-biz-lang { min-width: 3em; height: 2.6em; border: var(--kd-border) solid var(--kd-line); border-radius: 999px; background: var(--kd-surface); color: var(--kd-dim); font-weight: 700; cursor: pointer; }
.kd-biz-lang.on { background: var(--kd-primary); color: var(--kd-on-primary); border-color: transparent; }

/* ================================================================= MESSAGE BOX (UcKdMsgBox) */
.kd.kd-mb { z-index: 15000; background: transparent; align-items: center; justify-content: center; padding: var(--kd-pad); }
.kd.kd-mb::before, .kd.kd-mb::after { display: none; }
.kd-mb-scrim { position: absolute; inset: 0; background: rgba(var(--kd-bg-rgb), .62); backdrop-filter: blur(10px) saturate(1.1); -webkit-backdrop-filter: blur(10px) saturate(1.1); animation: kd-fade .25s ease both; }
.kd-mb-soft .kd-mb-scrim { background: rgba(var(--kd-bg-rgb), .3); backdrop-filter: none; -webkit-backdrop-filter: none; }
.kd-mb-card {
    position: relative;
    width: min(100%, calc(var(--kd-u) * 34));
    max-height: 100%;
    /* was: overflow: auto; : the 140 % wide glow (::before) gave the card a horizontal scrollbar ("Are you still there?") */
    overflow-x: hidden;
    overflow-y: auto;
    scrollbar-width: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: calc(var(--kd-gap) * 1.1);
    padding: calc(var(--kd-pad) * 1.8) calc(var(--kd-pad) * 1.4) calc(var(--kd-pad) * 1.3);
    border-radius: calc(var(--kd-card-r) * 1.4);
    background: var(--kd-surface);
    color: var(--kd-text);
    border: var(--kd-border) solid var(--kd-line);
    box-shadow: 0 40px 90px -30px rgba(var(--kd-shadow-rgb), .65), 0 0 0 1px rgba(var(--kd-text-rgb), .04);
    text-align: center;
    animation: kd-mb-in .44s var(--kd-ease-out) both;
}
/* a soft glow of the design's main color behind the icon */
.kd-mb-card::before { content: ""; position: absolute; left: 50%; top: 0; width: 140%; height: 60%; transform: translate(-50%, -38%); background: radial-gradient(closest-side, rgba(var(--kd-primary-rgb), .2), transparent); pointer-events: none; }
.kd-mb-icon { position: relative; width: calc(var(--kd-u) * 4.4); aspect-ratio: 1; border-radius: 50%; display: grid; place-items: center; background: var(--kd-primary-soft); color: var(--kd-primary); box-shadow: 0 0 0 calc(var(--kd-u) * .55) color-mix(in srgb, var(--kd-primary) 8%, transparent); animation: kd-mb-icon .6s var(--kd-ease) .1s both; }
.kd-mb-icon-ask { background: var(--kd-accent-soft); color: var(--kd-accent); box-shadow: 0 0 0 calc(var(--kd-u) * .55) color-mix(in srgb, var(--kd-accent) 9%, transparent); }
.kd.kd-light .kd-mb-icon-ask { color: color-mix(in srgb, var(--kd-accent) 70%, var(--kd-text)); }
.kd-mb-icon svg { width: 54%; height: 54%; fill: none; stroke: currentColor; stroke-width: 2.3; stroke-linecap: round; stroke-linejoin: round; }
.kd-mb-icon svg circle { fill: currentColor; stroke: none; }
.kd-mb-icon-wait svg { width: 70%; height: 70%; }
.kd-mb-icon-wait svg circle { fill: none; stroke-width: 4; }
.kd-mb-icon-wait .kd-mb-spin-track { stroke: rgba(var(--kd-primary-rgb), .18); }
.kd-mb-icon-wait .kd-mb-spin { stroke: var(--kd-primary); stroke-linecap: round; stroke-dasharray: 34 120; transform-origin: 50% 50%; animation: kd-mb-rot 1s linear infinite; }
.kd-mb-text { position: relative; font-size: calc(var(--kd-u) * 1.35); font-weight: 600; line-height: 1.4; max-width: 30ch; white-space: pre-line; text-wrap: balance; overflow-wrap: anywhere; }
.kd-mb-timer { width: 56%; height: 6px; border-radius: 999px; background: var(--kd-surface-2); overflow: hidden; }
.kd-mb-timer i { display: block; height: 100%; background: var(--kd-primary); transform-origin: left center; animation: kd-mb-timer linear both; }
.kd-mb-btns { position: relative; width: 100%; display: grid; gap: var(--kd-gap); margin-top: calc(var(--kd-gap) * .4); }
.kd-mb-btns-2 { grid-template-columns: 1fr 1fr; } /* was: 1fr 1.3fr: user: both answers the same size */
.kd .kd-mb-btns .kd-btn { width: 100%; padding: 0 .8em; }
.kd .kd-mb-btns-big .kd-btn { min-height: calc(var(--kd-touch) * 1.6); }
.kd-mb-close { position: absolute; top: .7em; right: .7em; z-index: 1; width: calc(var(--kd-touch) * .85); height: calc(var(--kd-touch) * .85); border: 0; border-radius: 50%; display: grid; place-items: center; background: var(--kd-surface-2); color: var(--kd-text); cursor: pointer; }
.kd-mb-close svg { width: 42%; height: 42%; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.kd-mb-leaving .kd-mb-card { animation: kd-mb-out .18s ease-in both; }
.kd-mb-leaving .kd-mb-scrim { animation: kd-mb-fadeout .18s ease-in both; }
@keyframes kd-mb-in { from { opacity: 0; transform: translateY(26px) scale(.94); } to { opacity: 1; transform: none; } }
@keyframes kd-mb-out { to { opacity: 0; transform: translateY(12px) scale(.97); } }
@keyframes kd-mb-fadeout { to { opacity: 0; } }
@keyframes kd-mb-icon { 0% { opacity: 0; transform: scale(.4); } 60% { opacity: 1; transform: scale(1.1); } 100% { transform: scale(1); } }
@keyframes kd-mb-rot { to { transform: rotate(360deg); } }
@keyframes kd-mb-timer { from { transform: scaleX(1); } to { transform: scaleX(0); } }
/* ================================================================= BUTTON TEXT FIT (2026-10-29)
   User: "the text is too big for the button and too close to its edges: check the whole application". The base rule
   gave text buttons a fixed min-height, NO vertical padding and line-height 1, so a label that wraps (long Spanish /
   French / Dutch texts, narrow screens) ran into the edges. Every text button now has real padding, a readable line
   height and balanced wrapping; the big (xl) buttons scale their text down on narrow screens. Icon-only buttons (round,
   steppers) keep their geometry. */
.kd .kd-btn:not(.kd-btn-round):not(.kd-step), .kd .k-button.kd-btn:not(.kd-btn-round):not(.kd-step) {
    height: auto;
    max-width: 100%;
    padding: .62em 1.3em;
    line-height: 1.15;
    text-align: center;
    text-wrap: balance;
    /* was: overflow-wrap: anywhere; hyphens: auto; : cut words in the middle ("ANUL-AR", "SIGUIEN-TE"). A button may
       wrap BETWEEN words only; a single word always stays whole. */
    overflow-wrap: normal;
    word-break: keep-all;
    hyphens: manual;
}
.kd .k-button.kd-btn .k-button-text { white-space: normal; line-height: inherit; text-align: center; min-width: 0; }
/* one- or two-word action buttons in footers keep their natural width on one line; the hint text gives way instead */
.kd-opts-foot { flex-wrap: wrap; row-gap: .6em; justify-content: flex-end; }
/* was: .kd-opts-hint { flex: 1 1 16em; min-width: 0; }: "Next" then wrapped alone onto a second row, left. Now the hint
   always has its own centred row; count + Cancel + Next stay together on the row below, aligned right. */
.kd-opts-hint { flex: 1 1 100%; min-width: 0; text-align: center; }
.kd-opts-foot .kd-btn, .kd-opts-foot .k-button.kd-btn, .kd-opts-count { flex: none; white-space: nowrap; }
.kd-bar .kd-btn, .kd-bar .k-button.kd-btn, .kd-ticket-actions .kd-btn, .kd-ticket-actions .k-button.kd-btn { white-space: nowrap; }
.kd .kd-add, .kd .k-button.kd-add, .kd .kd-step, .kd .k-button.kd-step { white-space: nowrap; }
.kd .kd-btn-xl:not(.kd-btn-round), .kd .k-button.kd-btn-xl:not(.kd-btn-round) {
    font-size: clamp(calc(var(--kd-u) * 1.02), 3.6vw, calc(var(--kd-u) * 1.45));
    padding: .7em 1.45em;
}
.kd .kd-add, .kd .k-button.kd-add { padding: .5em 1em; }
/* message box: the pair of answers stacks (full width each) when a label is long: UcKdMsgBox adds kd-mb-btns-stack */
.kd .kd-mb-btns .kd-btn { font-size: calc(var(--kd-u) * 1.15); }
.kd-mb-btns-2.kd-mb-btns-stack { grid-template-columns: 1fr; }
.kd-mb-btns-2.kd-mb-btns-stack .kd-btn:last-child { order: -1; } /* the main answer first, on top */

/* the countdown and the spinner are information, not decoration: they keep running with AnimLevel OFF */
.kd-anim-off .kd-mb-timer i { animation: kd-mb-timer linear both !important; }
.kd-anim-off .kd-mb-icon-wait .kd-mb-spin { animation: kd-mb-rot 1s linear infinite !important; }

/* ---------------------------------------------------------------- category bar scrolling (2026-10-29)
   The scrollbar stays hidden (kiosk look); kiosk-design.js adds wheel + mouse-drag scrolling and toggles
   kd-can-back / kd-can-fwd so the edges FADE when more categories are off-screen. The mask is an alpha
   mask (black = visible), not a UI color. */
.kd .kd-cats { cursor: grab; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.kd .kd-cats.kd-dragging { cursor: grabbing; user-select: none; }
.kd .kd-cats.kd-dragging .kd-cat { pointer-events: none; }
.kd-menu-tabs .kd-cats.kd-can-fwd { -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 56px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 56px), transparent); }
.kd-menu-tabs .kd-cats.kd-can-back { -webkit-mask-image: linear-gradient(90deg, transparent, #000 56px); mask-image: linear-gradient(90deg, transparent, #000 56px); }
.kd-menu-tabs .kd-cats.kd-can-back.kd-can-fwd { -webkit-mask-image: linear-gradient(90deg, transparent, #000 56px, #000 calc(100% - 56px), transparent); mask-image: linear-gradient(90deg, transparent, #000 56px, #000 calc(100% - 56px), transparent); }
.kd-menu-rail .kd-cats.kd-can-fwd { -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 56px), transparent); mask-image: linear-gradient(180deg, #000 calc(100% - 56px), transparent); }
.kd-menu-rail .kd-cats.kd-can-back { -webkit-mask-image: linear-gradient(180deg, transparent, #000 56px); mask-image: linear-gradient(180deg, transparent, #000 56px); }
.kd-menu-rail .kd-cats.kd-can-back.kd-can-fwd { -webkit-mask-image: linear-gradient(180deg, transparent, #000 56px, #000 calc(100% - 56px), transparent); mask-image: linear-gradient(180deg, transparent, #000 56px, #000 calc(100% - 56px), transparent); }

/* ============================================================================
   2026-10-29 CARD TEXT PLATE (user: "the text is above the images, you can't read that, it doesn't look good")
   FILL cards used to lay name / description / allergens / price OVER the photo (dark scrim, or for kd-pic-cutout a
   surface fade over the bottom third). Real menus have 2-3 text lines + allergens + a button, which is taller than
   any scrim zone → text across the food. Now: the photo keeps the full card width at the top (still photo-first),
   and the text sits on an OPAQUE plate (surface color) that overlaps the photo's bottom edge with rounded corners.
   Text never touches the picture, in every design and orientation. Appended last so it layers over the base FILL
   rules and the DEMO REDESIGN block; .kd-pic-cutout variants keep their contained, shadowed product image.
   ============================================================================ */
.kd-card-fill .kd-card.kd-has-pic { aspect-ratio: auto; background: var(--kd-surface); }
.kd-card-fill .kd-card.kd-has-pic .kd-card-pic { position: relative; inset: auto; height: auto; aspect-ratio: 1 / 1; flex: none; }
.kd-card-fill .kd-card.kd-has-pic .kd-card-pic::after { content: none; }
.kd-card-fill .kd-card.kd-has-pic .kd-card-body {
    position: relative;
    z-index: 1;
    margin-top: calc(var(--kd-card-r) * -1);
    flex: 1 1 auto;
    background: var(--kd-surface);
    border-radius: var(--kd-card-r) var(--kd-card-r) 0 0;
    color: var(--kd-text);
}
.kd-card-fill .kd-card.kd-has-pic .kd-card-desc, .kd-card-fill .kd-card.kd-has-pic .kd-card-meta { color: var(--kd-dim); -webkit-line-clamp: 2; }
.kd-card-fill .kd-card.kd-has-pic .kd-card-price { color: var(--kd-price); }
/* cutout photos: no reserved text zone inside the image any more: the dish is centered in its square */
.kd-card-fill.kd-pic-cutout .kd-card.kd-has-pic .kd-card-pic { background: var(--kd-surface-2); }
.kd-card-fill.kd-pic-cutout .kd-card.kd-has-pic .kd-card-pic img { padding: 7% 9% calc(7% + var(--kd-card-r)); }
.kd-card-fill.kd-pic-cutout .kd-card.kd-has-pic .kd-card-pic::after { content: none; }
.kd-card-fill.kd-pic-cutout .kd-card.kd-has-pic .kd-card-body { color: var(--kd-text); }
/* landscape: shorter picture so two rows stay visible */
@media (orientation: landscape) {
    .kd-card-fill:not(.kd-port) .kd-card.kd-has-pic { aspect-ratio: auto; }
    .kd-card-fill:not(.kd-port) .kd-card.kd-has-pic .kd-card-pic { aspect-ratio: 4 / 3; }
}
.kd-card-fill.kd-land .kd-card.kd-has-pic { aspect-ratio: auto; }
.kd-card-fill.kd-land .kd-card.kd-has-pic .kd-card-pic { aspect-ratio: 4 / 3; }

/* 2026-10-29 COMPACT TICKET on narrow portrait screens (tablets, browser windows < 820 px): the floating ticket
   covered half of a one-column product card (incl. its Add button). It docks as a full-width strip at the bottom:
   head + total + "Review and pay" in one row, line list hidden (the review page shows the full ticket). Large
   kiosks keep the printed ticket. Also applies to the back-office preview frame. */
@media (max-width: 820px) and (orientation: portrait) {
    .kd-menu.kd-cart-ticket:not(.kd-land) .kd-ticket-wrap { left: var(--kd-pad); right: var(--kd-pad); bottom: var(--kd-gap); width: auto; max-height: none; }
    .kd-menu.kd-cart-ticket:not(.kd-land) .kd-ticket { flex-direction: row; align-items: center; flex-wrap: wrap; gap: .4em var(--kd-gap); padding: calc(var(--kd-gap) * .8) var(--kd-gap); }
    .kd-menu.kd-cart-ticket:not(.kd-land) .kd-ticket-head { border-bottom: 0; padding: 0; flex: 1 1 auto; flex-direction: column; align-items: flex-start; gap: 0; }
    .kd-menu.kd-cart-ticket:not(.kd-land) .kd-ticket-lines { display: none; }
    .kd-menu.kd-cart-ticket:not(.kd-land) .kd-ticket-total { border-top: 0; padding: 0; flex: none; gap: .5em; }
    .kd-menu.kd-cart-ticket:not(.kd-land) .kd-ticket-total > span:first-child { display: none; }
    .kd-menu.kd-cart-ticket:not(.kd-land) .kd-ticket-actions { flex: 1 1 100%; }
    .kd-menu.kd-cart-ticket:not(.kd-land) .kd-grid { padding-bottom: calc(var(--kd-touch) * 3.2); }
}

/* 2026-10-29 KIOSK TICKETS (RECEIPT_SPEC.md §3): thanks page ticket state: "printing…" spinner, printed check,
   print-failed note + digital-ticket QR. Tokens only (the ticket sits on --kd-paper, so it uses the --kd-ink family). */
.kd-tk-status { display: flex; align-items: center; justify-content: center; gap: .6em; font-size: calc(var(--kd-u) * 1.15); color: var(--kd-ink); margin: 0; }
.kd-tk-spinner { flex: none; width: 1.3em; height: 1.3em; border-radius: 50%; border: .2em solid var(--kd-ink-line); border-top-color: var(--kd-primary); animation: kd-tk-spin .9s linear infinite; }
.kd-tk-check { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 1.6em; height: 1.6em; border-radius: 50%; background: var(--kd-primary); color: var(--kd-on-primary); font-weight: 700; animation: kd-pop .45s var(--kd-ease-out) both; }
.kd-tk-printed { font-family: var(--kd-font-display); font-weight: var(--kd-display-weight); }
.kd-tk-failed { font-size: calc(var(--kd-u) * 1.0); color: var(--kd-ink-dim); margin: 0; max-width: 32ch; }
.kd-tk-qr { animation: kd-fade .4s ease both; }
.kd-tk-scan { font-weight: 600; color: var(--kd-ink); }
@keyframes kd-tk-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .kd-tk-spinner { animation-duration: 2.4s; }
    .kd-tk-check, .kd-tk-qr { animation: none; }
}

/* ---------------------------------------------------------------- 2026-11-09 welcome loop video
   The design's photo sits under the video (same scene: the demo loops start from it); the video fades in once over it.
   A vertical video (.kd-vid-port, Kiosk_VideoHorizontal 0) is for portrait kiosks: landscape screens keep the photo.
   Reduced motion = the photo only. */
.kd-welcome-media video.kd-welcome-video { position: absolute; inset: 0; animation: kd-vid-in 1.2s ease-out .4s both; }
@keyframes kd-vid-in { from { opacity: 0; } to { opacity: 1; } }
@media (orientation: landscape) { .kd-welcome-media video.kd-vid-port { display: none; } }
@media (prefers-reduced-motion: reduce) { .kd-welcome-media video.kd-welcome-video { display: none; } }

/* ---------------------------------------------------------------- 2026-11-09 review line: "Edit" (change the options) */
/* was: .kd .kd-rline-edit { margin-top: .45em; min-height: calc(var(--kd-touch) * .8); padding: 0 1em; font-size: calc(var(--kd-u) * .85); gap: .4em; }
   2026-11-09 (Marc: "much too big"): a small pill sized to its label (the full kiosk-button look stretched across the line) */
.kd .kd-btn.kd-rline-edit, .kd .k-button.kd-btn.kd-rline-edit {
    display: inline-flex; width: auto; max-width: max-content; margin-top: .5em;
    min-height: 0; height: calc(var(--kd-u) * 2.1); padding: 0 .85em; gap: .35em;
    font-family: var(--kd-font-body); font-weight: 700; text-transform: none; letter-spacing: 0;
    font-size: calc(var(--kd-u) * .8); border-radius: 999px; box-shadow: none;
}
.kd .kd-rline-edit .kd-ico { width: 1em; height: 1em; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }

/* ================================================================= 2026-11-09 DEMO INTRO + UPRIGHT-SCREEN GUARD
   PgKioskDemo intro (language, "hold it upright", Start) and the UcKioskDemoRibbon rotate overlay. The orientation state
   is pure CSS (media queries react live when the device turns). One memorable element: the drawn tablet that turns upright. */
.kd.kd-intro { overflow-y: auto; overflow-x: hidden; }
/* the intro is read from a step back on a big upright screen: scale the whole column up with the screen width */
@media (orientation: portrait) and (min-width: 760px) { .kd-intro-inner { zoom: 1.35; } }
@media (orientation: portrait) and (min-width: 1000px) { .kd-intro-inner { zoom: 1.6; } }
.kd-intro-inner {
    width: min(100%, calc(var(--kd-u) * 40)); margin: auto; padding: calc(var(--kd-pad) * 1.6) var(--kd-pad);
    display: flex; flex-direction: column; align-items: center; text-align: center; gap: calc(var(--kd-gap) * 1.3);
}
.kd-intro-title { font-size: calc(var(--kd-u) * 3.4); line-height: 1.02; margin: 0; }
.kd-intro-sub { margin: .6em auto 0; color: var(--kd-dim); font-size: calc(var(--kd-u) * 1.15); max-width: 32ch; }

/* the device */
.kd-intro-device { position: relative; width: calc(var(--kd-u) * 9); height: calc(var(--kd-u) * 11); display: grid; place-items: center; }
.kd-intro-tablet {
    width: calc(var(--kd-u) * 5.4); height: calc(var(--kd-u) * 9.4); border-radius: calc(var(--kd-u) * .9);
    border: calc(var(--kd-u) * .32) solid var(--kd-text); padding: calc(var(--kd-u) * .3);
    box-shadow: 0 calc(var(--kd-u) * 1) calc(var(--kd-u) * 2.4) -1em rgba(var(--kd-shadow-rgb), .55);
    transform-origin: 50% 50%;
}
.kd-intro-tablet span { display: block; width: 100%; height: 100%; border-radius: calc(var(--kd-u) * .5);
    background: linear-gradient(160deg, var(--kd-primary), var(--kd-accent)); }
.kd-intro-ok {
    position: absolute; right: calc(var(--kd-u) * .2); bottom: calc(var(--kd-u) * .4); width: calc(var(--kd-u) * 2.6); height: calc(var(--kd-u) * 2.6);
    display: grid; place-items: center; border-radius: 50%; background: var(--kd-accent); color: var(--kd-on-accent);
    font-size: calc(var(--kd-u) * 1.4); font-weight: 800; box-shadow: 0 0 0 calc(var(--kd-u) * .3) var(--kd-bg);
    animation: kd-intro-pop .5s cubic-bezier(.3, 1.6, .5, 1) .3s both;
}
/* was: a full-size ring over the tablet (it crossed the drawing); now a small turn arrow at its top right */
.kd-intro-turn { position: absolute; top: 0; right: calc(var(--kd-u) * -1.2); width: calc(var(--kd-u) * 3.2); height: calc(var(--kd-u) * 3.2);
    fill: none; stroke: var(--kd-accent); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; display: none; }

.kd-intro-orient { margin: 0; font-weight: 800; font-size: calc(var(--kd-u) * 1.25); }
.kd-intro-orient .kd-intro-port::before { content: "\2713\00a0"; color: var(--kd-accent); }
.kd-intro-hold { margin: -.4em auto 0; color: var(--kd-dim); max-width: 34ch; }
.kd-intro-land { display: none; }

/* 2026-11-10 "how to try it": touch first, then voice (PgKioskDemo intro) */
.kd-intro-how { width: 100%; text-align: left; border: var(--kd-border) solid var(--kd-line); border-radius: var(--kd-card-r);
    background: var(--kd-surface); padding: calc(var(--kd-pad) * .8) var(--kd-pad); }
.kd-intro-how-title { margin: 0 0 .6em; font-size: calc(var(--kd-u) * 1.1); font-weight: 800; letter-spacing: .04em; text-transform: uppercase; color: var(--kd-accent); }
.kd-intro-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: calc(var(--kd-gap) * .8); }
.kd-intro-step { display: flex; align-items: flex-start; gap: .8em; }
.kd-intro-step-nr { flex: none; width: 1.9em; height: 1.9em; display: grid; place-items: center; border-radius: 50%;
    background: var(--kd-accent); color: var(--kd-on-accent); font-weight: 800; font-size: calc(var(--kd-u) * 1.05); }
.kd-intro-step-txt { display: flex; flex-direction: column; gap: .15em; min-width: 0; }
.kd-intro-step-txt b { font-size: calc(var(--kd-u) * 1.1); }
.kd-intro-step-txt span { color: var(--kd-dim); line-height: 1.3; }

/* languages: large, equal, flags first */
.kd-intro-langs { width: 100%; display: grid; grid-template-columns: repeat(auto-fit, minmax(calc(var(--kd-u) * 10), 1fr)); gap: calc(var(--kd-gap) * .6); }
.kd-intro-lang {
    min-height: var(--kd-touch); display: flex; align-items: center; gap: .7em; padding: 0 1.1em;
    border: var(--kd-border) solid var(--kd-line); border-radius: var(--kd-btn-r); background: var(--kd-surface); color: var(--kd-text);
    font: inherit; font-weight: 700; font-size: calc(var(--kd-u) * 1.05); cursor: pointer; transition: transform .12s, background .15s;
}
.kd-intro-lang img { width: 1.7em; height: 1.7em; border-radius: 50%; object-fit: cover; flex: none; }
.kd-intro-lang:active { transform: scale(.97); }
.kd-intro-lang.on { background: var(--kd-primary); color: var(--kd-on-primary); border-color: transparent; }
.kd-intro-lang:focus-visible { outline: 3px solid var(--kd-accent); outline-offset: 3px; }
.kd .kd-btn.kd-intro-start { width: 100%; justify-content: center; }

/* horizontal screen: the tablet turns upright again and again, the texts switch to the warning */
@media (orientation: landscape) {
    .kd-intro .kd-intro-port { display: none; }
    .kd-intro .kd-intro-land, .kd-rotate .kd-intro-land { display: inline; }
    .kd-intro-orient .kd-intro-land { color: var(--kd-accent); }
    .kd-intro .kd-intro-ok { display: none; }
    .kd-intro-device .kd-intro-turn { display: block; }
    .kd-intro-device .kd-intro-tablet { animation: kd-intro-turn 2.6s cubic-bezier(.6, 0, .25, 1) infinite; }
}

/* rotate overlay over the running demo (only on a horizontal screen, unless the visitor chose to continue) */
.kd.kd-rotate { display: none; z-index: 30000; align-items: center; justify-content: center; background: var(--kd-veil);
    backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
@media (orientation: landscape) { .kd.kd-rotate { display: flex; } }
html.kd-rot-ok .kd.kd-rotate { display: none; }
/* 2026-11-09 fix: the overlay lives in the demo bar host (pointer-events: none so the kiosk below stays usable) and inherited
   it: "Continue anyway" could not be pressed */
.kd.kd-rotate { pointer-events: auto; }
/* computer (mouse) = the window can be resized, not turned; tablet / phone = turn it */
.kd-rotate .kd-rot-desk { display: none; }
@media (hover: hover) and (pointer: fine) {
    .kd-rotate .kd-rot-desk { display: revert; }
    .kd-rotate .kd-rot-touch { display: none; }
    .kd-rotate .kd-intro-device .kd-intro-tablet { animation: none; transform: rotate(-90deg); }
}
.kd-rotate-card { display: flex; flex-direction: column; align-items: center; text-align: center; gap: .7em; padding: 2em 2.4em;
    max-width: min(92vw, 30rem); border-radius: var(--kd-card-r); background: var(--kd-surface); color: var(--kd-text);
    box-shadow: 0 30px 70px -30px rgba(var(--kd-shadow-rgb), .8); }
.kd-rotate-card b { font-size: calc(var(--kd-u) * 1.8); line-height: 1.1; }
.kd-rotate-card > span { color: var(--kd-dim); }

@keyframes kd-intro-turn {
    0%, 15% { transform: rotate(-90deg); }
    55%, 100% { transform: rotate(0deg); }
}
@keyframes kd-intro-pop { from { transform: scale(0); } to { transform: scale(1); } }

@media (prefers-reduced-motion: reduce) {
    .kd-intro-device .kd-intro-tablet, .kd-intro-ok { animation: none; }
}

/* =================================================================================================================
   V4 KD 2026-11-12 (BACKOFFICE_V4_SPEC.md, stream KD): "let the owner shape the kiosk look completely".
   Every rule below hangs on a class KioskDesignCss.ToClasses() writes ONLY for a non-default token value, or on a
   --kd-* variable ToStyle() writes only when set: a design without the V4 tokens renders exactly as before.
   Appended last on purpose (it layers over the base, demo-redesign and text-plate blocks). Tokens only.
   ================================================================================================================= */

/* ---------------------------------------------------------------- button size (token BtnSize; --kd-touch drives every target) */
.kd.kd-btnsz-s { --kd-touch: max(52px, calc(var(--kd-u) * 2.9)); }
.kd.kd-btnsz-l { --kd-touch: max(64px, calc(var(--kd-u) * 3.9)); }
.kd.kd-btnsz-xl { --kd-touch: max(72px, calc(var(--kd-u) * 4.5)); }
.kd.kd-btnsz-l .kd-btn, .kd.kd-btnsz-l .k-button.kd-btn { font-size: calc(var(--kd-u) * 1.25); }
.kd.kd-btnsz-xl .kd-btn, .kd.kd-btnsz-xl .k-button.kd-btn { font-size: calc(var(--kd-u) * 1.35); }

/* ---------------------------------------------------------------- product picture ratio (token CardAspect; LIST rows keep their square) */
.kd.kd-aspect-square:not(.kd-card-list) .kd-card-pic { aspect-ratio: 1 / 1 !important; }
.kd.kd-aspect-portrait:not(.kd-card-list) .kd-card-pic { aspect-ratio: 3 / 4 !important; }
.kd.kd-aspect-landscape:not(.kd-card-list) .kd-card-pic { aspect-ratio: 4 / 3 !important; }
.kd.kd-aspect-wide:not(.kd-card-list) .kd-card-pic { aspect-ratio: 16 / 9 !important; }

/* ---------------------------------------------------------------- fixed product columns (tokens ColsPort / ColsLand; AUTO = fluid ProdCols) */
@media (orientation: portrait) { .kd.kd-colsp:not(.kd-land) .kd-grid { grid-template-columns: repeat(var(--kd-cols-port, 3), minmax(0, 1fr)); } }
.kd.kd-colsp.kd-port .kd-grid { grid-template-columns: repeat(var(--kd-cols-port, 3), minmax(0, 1fr)); }
@media (orientation: landscape) { .kd.kd-colsl:not(.kd-port) .kd-grid { grid-template-columns: repeat(var(--kd-cols-land, 4), minmax(0, 1fr)); } }
.kd.kd-colsl.kd-land .kd-grid { grid-template-columns: repeat(var(--kd-cols-land, 4), minmax(0, 1fr)); }

/* ---------------------------------------------------------------- picture fit + corners (tokens ImgFit / ImgCorner) */
.kd.kd-fit-cover .kd-card-pic img { object-fit: cover !important; padding: 0 !important; }
.kd.kd-fit-contain .kd-card-pic img { object-fit: contain !important; }
.kd.kd-fit-contain:not(.kd-pic-cutout) .kd-card-pic img { padding: 5% !important; }
.kd.kd-pcorner-square:not(.kd-card-list) .kd-card-pic,
.kd.kd-pcorner-round:not(.kd-card-list) .kd-card-pic { width: auto; margin: calc(var(--kd-gap) * .6) calc(var(--kd-gap) * .6) 0; }
.kd.kd-pcorner-square .kd-card-pic { border-radius: 0; }
.kd.kd-pcorner-round .kd-card-pic { border-radius: calc(var(--kd-card-r) * .75); }
.kd.kd-pcorner-circle:not(.kd-card-list) .kd-card-pic { width: 78%; margin: var(--kd-gap) auto 0; aspect-ratio: 1 / 1 !important; border-radius: 50%; }
.kd.kd-pcorner-circle.kd-card-list .kd-card-pic { border-radius: 50%; margin: .5em; }
.kd.kd-card-list.kd-pcorner-round .kd-card-pic, .kd.kd-card-list.kd-pcorner-square .kd-card-pic { margin: .5em; }
/* FILL text plate: an inset picture needs no overlap */
.kd.kd-card-fill.kd-pcorner-round .kd-card.kd-has-pic .kd-card-body,
.kd.kd-card-fill.kd-pcorner-square .kd-card.kd-has-pic .kd-card-body,
.kd.kd-card-fill.kd-pcorner-circle .kd-card.kd-has-pic .kd-card-body { margin-top: 0; }

/* ---------------------------------------------------------------- category navigation (token CatNav; MenuLayout follows it in Normalize) */
/* rail, round icons */
.kd.kd-nav-rail-icons .kd-cat img { width: calc(var(--kd-touch) * .95); height: auto; aspect-ratio: 1; border-radius: 50%; }
/* rail, big pictures */
.kd.kd-nav-rail-images .kd-cat { padding: .45em .45em .7em; }
.kd.kd-nav-rail-images .kd-cat img { width: 100%; height: auto; aspect-ratio: 4 / 3; border-radius: calc(var(--kd-card-r) * .7); }
/* rail, text only */
.kd.kd-nav-rail-text .kd-cat img, .kd.kd-nav-tabs .kd-cat img { display: none; }
.kd.kd-nav-rail-text .kd-cat { flex-direction: row; justify-content: flex-start; text-align: left; padding: .6em 1em; min-height: var(--kd-touch); }
.kd.kd-nav-rail-text .kd-cat span { font-size: calc(var(--kd-u) * 1.05); }
/* tabs with an underline */
.kd.kd-nav-tabs .kd-cat { border-radius: 0; background: transparent; padding: .4em 1.1em; border-bottom: 4px solid transparent; }
.kd.kd-nav-tabs .kd-cat.active { background: transparent; color: var(--kd-text); border-bottom-color: var(--kd-accent); }
/* chips */
.kd.kd-nav-chips .kd-cat { border-radius: 999px; background: var(--kd-surface); border: var(--kd-border) solid var(--kd-line); min-height: calc(var(--kd-touch) * .82); padding: .25em 1.1em .25em .3em; }
.kd.kd-nav-chips .kd-cat img { width: calc(var(--kd-touch) * .62); height: calc(var(--kd-touch) * .62); border-radius: 50%; }
.kd.kd-nav-chips .kd-cat.active { background: var(--kd-accent); color: var(--kd-on-accent); border-color: transparent; }
/* tile grid (every category visible at once) */
.kd.kd-nav-tiles .kd-cats { display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(var(--kd-u) * 8.5), 1fr)); max-height: 34vh; overflow-y: auto; overflow-x: hidden; -webkit-mask-image: none !important; mask-image: none !important; }
.kd.kd-nav-tiles .kd-cat { flex-direction: column; align-items: center; text-align: center; border-radius: var(--kd-card-r); background: var(--kd-surface); border: var(--kd-border) solid var(--kd-line); padding: .5em; gap: .4em; }
.kd.kd-nav-tiles .kd-cat img { width: 100%; height: auto; aspect-ratio: 4 / 3; border-radius: calc(var(--kd-card-r) * .6); }
.kd.kd-nav-tiles .kd-cat.active { background: var(--kd-accent); color: var(--kd-on-accent); border-color: transparent; }

/* ---------------------------------------------------------------- header (tokens HeaderLogo / HeaderSize / HeaderStyle) */
.kd.kd-hdrlogo-center .kd-header { position: relative; }
.kd.kd-hdrlogo-center .kd-header-logo, .kd.kd-hdrlogo-center .kd-header-logo-ph { position: absolute; left: 50%; transform: translateX(-50%); }
.kd.kd-hdrsz-s .kd-header { padding: calc(var(--kd-pad) * .4) var(--kd-pad); }
.kd.kd-hdrsz-s .kd-header-logo { height: calc(var(--kd-logo-h) * .42 * var(--kd-scale)); }
.kd.kd-hdrsz-l .kd-header { padding: calc(var(--kd-pad) * 1.2) var(--kd-pad); }
.kd.kd-hdrsz-l .kd-header-logo { height: calc(var(--kd-logo-h) * .9 * var(--kd-scale)); }
.kd.kd-hdrst-float .kd-header { background: transparent; border-bottom-color: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; }
.kd.kd-hdrst-accent .kd-header { --kd-text: var(--kd-on-accent); --kd-line: color-mix(in srgb, var(--kd-on-accent) 40%, transparent); background: var(--kd-accent); color: var(--kd-on-accent); border-bottom-color: transparent; }

/* ---------------------------------------------------------------- prices + badges (tokens PriceStyle / BadgeStyle) */
.kd.kd-pricest-badge .kd-card-price { display: inline-block; padding: .12em .5em; border-radius: calc(var(--kd-btn-r) * .35); background: var(--kd-accent); color: var(--kd-on-accent) !important; }
.kd.kd-pricest-pill .kd-card-price { display: inline-block; padding: .08em .65em; border-radius: 999px; border: 2px solid currentColor; }
.kd.kd-badgest-square .kd-badge { border-radius: 4px; }
.kd.kd-badgest-ribbon .kd-badge { top: 0; left: 0; border-radius: 0 0 var(--kd-card-r) 0; padding: .45em 1em .45em .9em; }
.kd.kd-badgest-outline .kd-badge { background: var(--kd-surface); color: var(--kd-text); box-shadow: inset 0 0 0 2px var(--kd-accent); }

/* ---------------------------------------------------------------- icons inside labelled buttons (token IconStyle) */
.kd.kd-icons-outline .kd-btn svg, .kd.kd-icons-outline .k-button.kd-btn svg { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; }
.kd.kd-icons-none .kd-btn:not(.kd-btn-round):not(.kd-step):not(.kd-back) svg { display: none; }

/* ---------------------------------------------------------------- focus ring (token FocusColor) */
.kd.kd-has-focus .kd-btn:focus-visible, .kd.kd-has-focus .k-button.kd-btn:focus-visible, .kd.kd-has-focus .kd-lang:focus-visible,
.kd.kd-has-focus .kd-cat:focus-visible, .kd.kd-has-focus .kd-card:focus-visible, .kd.kd-has-focus .kd-where-card:focus-visible,
.kd.kd-has-focus .kd-opt:focus-visible { outline: 3px solid var(--kd-focus); outline-offset: 3px; }

/* ---------------------------------------------------------------- quantity stepper (token StepperStyle) */
.kd.kd-stepst-square .kd-step, .kd.kd-stepst-square .k-button.kd-step { border-radius: calc(6px * var(--kd-scale)); }
.kd.kd-stepst-pill .kd-stepper { background: var(--kd-surface-2); border-radius: 999px; padding: .25em; gap: .3em; }
.kd.kd-stepst-pill .kd-stepper-val { text-align: center; }

/* ---------------------------------------------------------------- background: gradient, picture blur, picture tint */
.kd.kd-has-grad { background-image: var(--kd-bg-grad); }
.kd.kd-has-bkg.kd-has-blur::after { filter: blur(var(--kd-bkg-blur)); inset: calc(var(--kd-bkg-blur) * -2); }
.kd.kd-has-bkg.kd-has-tint::before { background-color: rgba(var(--kd-overlay-rgb), var(--kd-overlay)); }

/* ---------------------------------------------------------------- welcome layouts (token WelcomeLayout; FULL = the base full-bleed picture) */
/* SPLIT: picture on top (portrait) / on the right (landscape), text on the solid page */
.kd.kd-wl-split .kd-welcome-media { inset: 0 0 46% 0; }
.kd.kd-wl-split .kd-welcome-media::after { background: linear-gradient(180deg, rgba(var(--kd-bg-rgb), 0) 55%, rgba(var(--kd-bg-rgb), 1) 100%); }
.kd.kd-wl-split .kd-welcome-media::before { display: none; }
.kd.kd-wl-split .kd-welcome-body { min-height: 46%; justify-content: center; }
@media (orientation: landscape) {
    .kd.kd-wl-split:not(.kd-port) .kd-welcome-media { inset: 0 0 0 50%; }
    .kd.kd-wl-split:not(.kd-port) .kd-welcome-media::after { background: linear-gradient(90deg, rgba(var(--kd-bg-rgb), 1) 0%, rgba(var(--kd-bg-rgb), 0) 35%); }
    .kd.kd-wl-split:not(.kd-port) .kd-welcome-body { max-width: 50%; min-height: 100%; }
}
.kd.kd-wl-split.kd-land .kd-welcome-media { inset: 0 0 0 50%; }
.kd.kd-wl-split.kd-land .kd-welcome-media::after { background: linear-gradient(90deg, rgba(var(--kd-bg-rgb), 1) 0%, rgba(var(--kd-bg-rgb), 0) 35%); }
.kd.kd-wl-split.kd-land .kd-welcome-body { max-width: 50%; min-height: 100%; }
/* MINIMAL: no picture, logo + title + languages centered on the page ground (gradient / pattern still apply) */
.kd.kd-wl-minimal .kd-welcome-media { display: none; }
.kd.kd-wl-minimal.kd-welcome { justify-content: center; }
.kd.kd-wl-minimal .kd-welcome-body { align-items: center; text-align: center; }
.kd.kd-wl-minimal .kd-welcome-title, .kd.kd-wl-minimal .kd-welcome-sub { margin-left: auto; margin-right: auto; }
.kd.kd-wl-minimal .kd-lang-grid { width: min(100%, calc(var(--kd-u) * 36)); }
/* CAROUSEL: up to 3 design pictures cross-fade on the hero (WelcomeImgUrl, WelcomeImg2Url, WelcomeImg3Url), CSS only */
.kd.kd-wl-carousel.kd-has-welcome2 .kd-hero-img::before,
.kd.kd-wl-carousel.kd-has-welcome3 .kd-hero-img::after { content: ""; position: absolute; inset: 0; opacity: 0; background-position: center; background-size: cover; background-repeat: no-repeat; }
.kd.kd-wl-carousel.kd-has-welcome2 .kd-hero-img::before { background-image: var(--kd-welcome-img-2); }
.kd.kd-wl-carousel.kd-has-welcome3 .kd-hero-img::after { background-image: var(--kd-welcome-img-3); }
.kd.kd-wl-carousel.kd-has-welcome2:not(.kd-has-welcome3) .kd-hero-img::before { animation: kd-car-2of2 14s ease-in-out infinite; }
.kd.kd-wl-carousel.kd-has-welcome2.kd-has-welcome3 .kd-hero-img::before { animation: kd-car-2of3 21s ease-in-out infinite; }
.kd.kd-wl-carousel.kd-has-welcome3 .kd-hero-img::after { animation: kd-car-3of3 21s ease-in-out infinite; }
@keyframes kd-car-2of2 { 0%, 42% { opacity: 0; } 50%, 92% { opacity: 1; } 100% { opacity: 0; } }
@keyframes kd-car-2of3 { 0%, 28% { opacity: 0; } 34%, 61% { opacity: 1; } 67%, 100% { opacity: 0; } }
@keyframes kd-car-3of3 { 0%, 61% { opacity: 0; } 67%, 94% { opacity: 1; } 100% { opacity: 0; } }

/* ---------------------------------------------------------------- cart position (token CartPos; CartStyle follows it in Normalize) */
/* SIDE: the ticket stays docked on the right, also on a portrait kiosk (narrow portrait screens keep the compact strip) */
@media (min-width: 821px), (orientation: landscape) {
    .kd.kd-cartpos-side:not(.kd-menu-rail) .kd-body { grid-template-columns: 1fr var(--kd-ticket-w); }
    .kd.kd-cartpos-side.kd-menu-rail .kd-body { grid-template-columns: var(--kd-rail-w) 1fr var(--kd-ticket-w); }
    .kd.kd-cartpos-side .kd-ticket-wrap { position: relative; right: auto; bottom: auto; width: auto; max-height: none; height: 100%; padding: var(--kd-gap) var(--kd-pad) var(--kd-pad) 0; }
    .kd.kd-cartpos-side .kd-grid { padding-bottom: var(--kd-pad); }
}
/* DRAWER: a compact ticket (head + total + pay) floats bottom-right, pressing its head unrolls the lines */
.kd.kd-cartpos-drawer:not(.kd-menu-rail) .kd-body { grid-template-columns: 1fr; }
.kd.kd-cartpos-drawer.kd-menu-rail .kd-body { grid-template-columns: var(--kd-rail-w) 1fr; }
.kd.kd-cartpos-drawer .kd-ticket-wrap { position: absolute; left: auto; right: var(--kd-pad); bottom: var(--kd-gap); width: min(calc(100% - var(--kd-pad) * 2), calc(var(--kd-u) * 26)); height: auto; max-height: none; padding: 0; }
.kd.kd-cartpos-drawer .kd-ticket { flex-direction: row; align-items: center; flex-wrap: wrap; gap: .4em var(--kd-gap); padding: calc(var(--kd-gap) * .8) var(--kd-gap); }
.kd.kd-cartpos-drawer .kd-ticket-head { order: 0; border-bottom: 0; padding: 0; flex: 1 1 auto; }
.kd.kd-cartpos-drawer .kd-ticket-chev { display: grid; place-items: center; flex: none; order: 0; width: calc(var(--kd-touch) * .8); height: calc(var(--kd-touch) * .8); border: 0; border-radius: 50%; background: rgba(var(--kd-ink-rgb), .08); color: var(--kd-ink); cursor: pointer; }
.kd.kd-cartpos-drawer .kd-ticket-chev svg { width: 46%; height: 46%; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; transition: transform .3s var(--kd-ease); }
.kd.kd-cartpos-drawer .kd-ticket-lines { display: none; }
.kd.kd-cartpos-drawer .kd-ticket-total { order: 1; border-top: 0; padding: 0; flex: none; gap: .5em; }
.kd.kd-cartpos-drawer .kd-ticket-actions { order: 3; flex: 1 1 100%; }
.kd.kd-cartpos-drawer .kd-ticket-wrap.kd-ticket-open .kd-ticket-lines { display: flex; order: 2; flex: 1 1 100%; max-height: min(52vh, calc(var(--kd-u) * 30)); overflow-y: auto; border-top: 2px dashed var(--kd-ink-line); border-bottom: 2px dashed var(--kd-ink-line); padding: .3em 0; }
.kd.kd-cartpos-drawer .kd-ticket-wrap.kd-ticket-open .kd-ticket-chev svg { transform: rotate(180deg); }
.kd.kd-cartpos-drawer .kd-grid { padding-bottom: calc(var(--kd-touch) * 3.6); }

/* ---------------------------------------------------------------- thanks layouts (token ThanksLayout; TICKET = the printed ticket) */
.kd.kd-thx-card .kd-thanks-slot, .kd.kd-thx-big .kd-thanks-slot, .kd.kd-thx-minimal .kd-thanks-slot { display: none; }
.kd.kd-thx-card .kd-thanks-ticket::after, .kd.kd-thx-big .kd-thanks-ticket::after, .kd.kd-thx-minimal .kd-thanks-ticket::after { display: none; }
.kd.kd-thx-card .kd-thanks-ticket, .kd.kd-thx-big .kd-thanks-ticket, .kd.kd-thx-minimal .kd-thanks-ticket { --kd-ink: var(--kd-text); --kd-ink-dim: var(--kd-dim); --kd-ink-line: var(--kd-line); color: var(--kd-text); }
.kd.kd-thx-card .kd-thanks-ticket { background: var(--kd-surface); border: var(--kd-border) solid var(--kd-line); border-radius: calc(var(--kd-card-r) * 1.2); box-shadow: var(--kd-shadow-lift); }
.kd.kd-thx-big .kd-thanks-ticket, .kd.kd-thx-minimal .kd-thanks-ticket { background: transparent; }
.kd.kd-thx-big .kd-thanks-ticket-clip, .kd.kd-thx-minimal .kd-thanks-ticket-clip { filter: none; }
.kd.kd-thx-big .kd-thanks-nr { font-size: min(34vmin, 26vw); }
.kd.kd-thx-big .kd-thanks-rule, .kd.kd-thx-minimal .kd-thanks-rule, .kd.kd-thx-minimal .kd-thanks-img { display: none; }
.kd.kd-thx-minimal .kd-thanks-nr { font-size: min(18vmin, 13vw); }
.kd-preview-frame .kd.kd-thx-big .kd-thanks-nr { font-size: 30cqmin; }
.kd-preview-frame .kd.kd-thx-minimal .kd-thanks-nr { font-size: 15cqmin; }

/* ---------------------------------------------------------------- back-office preview: tablet frame (V4 KD) */
.kd-preview-frame.kd-preview-tab { aspect-ratio: 3 / 4; }
.kd-preview-tab .kd-ticket-wrap { position: absolute; }
.kd-preview-frame .kd-welcome-media video.kd-welcome-video { object-fit: cover; width: 100%; height: 100%; }
