/* TotemWidget - Author: Msadeg.BenSaied@mapsgroup.it
   Built with the help of an AI agent and the open-source community. */

/* ── Totem kiosk redesign v3 — "Servizi Digitali" ────────────────────────
 * Loaded ONLY by index-new.html (body.kiosk). Visual language taken from
 * the PX Servizi Totem spec (03.2026): light institutional UI, one primary
 * blue applied to buttons/borders/call-to-action, white service cards with
 * the letterbox on the left, big clock in the header, centred navy
 * instruction text, Titillium Web (the spec's default typeface, bundled
 * offline in vendor/fonts/titillium). The avatar keeps its dark stage —
 * it is the "face" screen of the machine, framed like a display panel.
 * app.js is untouched: pills + step logic live in the inline shim. */

@font-face{font-family:"Titillium Web";src:url("vendor/fonts/titillium/TitilliumWeb-Regular.ttf");font-weight:400;font-display:swap}
@font-face{font-family:"Titillium Web";src:url("vendor/fonts/titillium/TitilliumWeb-SemiBold.ttf");font-weight:600;font-display:swap}
@font-face{font-family:"Titillium Web";src:url("vendor/fonts/titillium/TitilliumWeb-Bold.ttf");font-weight:700;font-display:swap}
@font-face{font-family:"Titillium Web";src:url("vendor/fonts/titillium/TitilliumWeb-Black.ttf");font-weight:900;font-display:swap}

body.kiosk{
  --tk-primary:#1758a7;   /* the one primary color (spec §1.2: pulsanti,
                             bordi, evidenziazioni, call to action) */
  --tk-primary-dark:#124a8d;
  --tk-navy:#16365c;      /* text */
  --tk-page:#e8eef5;      /* page background */
  --tk-card:#ffffff;
  --tk-line:#c2d2e2;      /* card borders */
  --tk-sub:#64788c;       /* secondary text */
  --tk-green:#1e8a5a;     /* listening / success */
  background:var(--tk-page);color:var(--tk-navy);
  font-family:"Titillium Web",var(--font-body),sans-serif;
}
/* replace the dark fixed backdrop with a faint cool one on light gray */
body.kiosk::before{background:
  radial-gradient(900px 460px at 50% -8%,rgba(23,88,167,.10),transparent 62%),
  var(--tk-page)}

/* one centered totem column (the kiosk screen is landscape 1920×1080) */
body.kiosk .app{max-width:920px}
body.kiosk.fs .app{max-width:960px;padding:14px}
body.kiosk main{display:flex;flex-direction:column;min-height:0}
body.kiosk .chat{flex:1;min-height:0;background:none;border:none;box-shadow:none}

/* ── header: brand left, big clock right ─────────────────────────────── */
body.kiosk header{background:var(--tk-card);border:1px solid var(--tk-line);
  border-radius:16px;padding:10px 18px;margin-bottom:6px;
  box-shadow:0 2px 10px rgba(22,54,92,.06);
  animation:tk-drop .5s cubic-bezier(.2,.8,.3,1) both}
body.kiosk .logo{display:inline-block;width:40px;height:40px;font-size:0;
  background:linear-gradient(115deg,var(--tk-primary) 0 34%,#3f83c9 34% 56%,
             #8db9e2 56% 74%,#e2523f 74% 100%);
  border-radius:9px;transform:skewX(-8deg)}
body.kiosk .brand h1{color:var(--tk-navy);font-family:inherit;font-weight:900;
  font-size:1.35rem;letter-spacing:.01em}
body.kiosk .brand h1 .accent{color:var(--tk-primary)}
body.kiosk .brand .tag{color:var(--tk-sub);text-transform:uppercase;
  letter-spacing:.14em;font-size:.62rem;font-weight:600}
body.kiosk .clock{color:var(--tk-navy);font-family:inherit;font-weight:900;
  font-size:2rem;letter-spacing:.02em;margin-right:6px}
body.kiosk .status .pill{font-size:.6rem;opacity:.55}
body.kiosk .iconbtn{background:none;border:1px solid transparent;opacity:.4;
  color:var(--tk-navy)}
body.kiosk .iconbtn:hover{opacity:1;border-color:var(--tk-line)}
body.kiosk #themeBtn{display:none}   /* the kiosk look is the theme */

/* ── the avatar stage: the machine's face, framed as a display panel ──── */
body.kiosk #avatarBox{flex:0 0 32vh;margin:6px 0 0;border-radius:18px;
  overflow:hidden;border:1px solid var(--tk-line);background:#c2d2e2;
  animation:tk-fade .7s ease both .1s}
/* the 2D robot reads these variables and paints the stage to match;
 * the Live2D renderer instead sets an inline dark gradient on the
 * container — !important beats the style attribute so Haru also
 * stands on the totem color */
body.kiosk #avatarContainer{--avatar2d-bg:#c2d2e2;
  --avatar2d-shadow:rgba(22,54,92,.22);
  background:#c2d2e2 !important}
/* Live2D paints its dark backdrop inline on its own canvas — outrank it */
body.kiosk #avatarL2dCanvas{background:#c2d2e2 !important}
@media (max-height:760px){body.kiosk #avatarBox{flex-basis:26vh}}
/* footlight recolored to the primary while it speaks, green while it hears */
body.kiosk.speaking #avatarBox::after{
  background:radial-gradient(50% 100% at 50% 100%,rgba(63,131,201,.5),transparent 70%)}
body.kiosk.listening #avatarBox::after{
  background:radial-gradient(50% 100% at 50% 100%,rgba(30,138,90,.45),transparent 70%)}

/* mic "magic ball" — the listening indicator, floats beside the avatar's head
 * (mirrors the native single-binary totem). mic-orb.js paints/animates it and
 * toggles .hidden; keep it clear of pointer events so taps reach the avatar. */
body.kiosk #avatarBox .mic-orb{position:absolute;right:3%;top:3%;
  width:396px;height:396px;z-index:6;pointer-events:none;
  filter:drop-shadow(0 10px 26px rgba(120,60,200,.35))}
@media (max-height:760px){body.kiosk #avatarBox .mic-orb{width:230px;height:230px;top:10%;left:55%}}

/* ── AI message: the instruction line (centred navy, spec style).
 * FIXED two-line height: the layout must never shift while text streams ── */
body.kiosk .bot-echo{flex:0 0 auto;height:84px;margin:12px 0 0;padding:6px 26px;
  display:flex;align-items:center;justify-content:center;
  background:var(--tk-card);border:1px solid var(--tk-line);border-radius:14px;
  border-top:4px solid var(--tk-primary);
  color:var(--tk-navy);font-size:1.28rem;font-weight:700;line-height:1.35;
  text-align:center;overflow:hidden;
  box-shadow:0 2px 10px rgba(22,54,92,.06);
  animation:tk-drop .5s cubic-bezier(.2,.8,.3,1) both .2s}
body.kiosk .bot-echo span{display:-webkit-box;-webkit-box-orient:vertical;
  -webkit-line-clamp:2;line-clamp:2;overflow:hidden;white-space:normal;word-break:break-word}
body.kiosk .bot-echo.flash{animation:tk-instr .45s ease}
body.kiosk.speaking .bot-echo{border-top-color:#3f83c9;
  box-shadow:0 2px 18px rgba(23,88,167,.22)}
body.kiosk .bot-echo.empty{color:var(--tk-sub);font-weight:400;font-style:italic}

/* ── user message: what the totem heard.
 * FIXED two-line height and width: no reflow while the transcript grows ── */
body.kiosk .user-echo{flex:0 0 auto;height:58px;width:min(680px,80%);
  margin:10px auto 0;padding:4px 22px;border-radius:999px;gap:6px;
  display:flex;align-items:center;justify-content:center;
  background:#dbe7f3;border:1px solid var(--tk-line);color:var(--tk-navy);
  font-size:1rem;font-weight:600;line-height:1.3;text-align:center;
  overflow:hidden;animation:tk-fade .7s ease both .3s}
body.kiosk .user-echo span{display:-webkit-box;-webkit-box-orient:vertical;
  -webkit-line-clamp:2;line-clamp:2;overflow:hidden;white-space:normal;word-break:break-word}
body.kiosk .user-echo::before{content:"🎤 ";font-size:.85em}
body.kiosk .user-echo.empty{background:transparent;border-color:transparent;
  color:var(--tk-sub);font-weight:400;font-style:italic}
body.kiosk.listening .user-echo{border-color:var(--tk-green);
  color:var(--tk-green);background:#e2f2ea;animation:tk-listen 1.6s ease-in-out infinite}

/* ── the service area: white card, one step at a time ────────────────── */
body.kiosk .messages{margin:12px 0;border:1px solid var(--tk-line);
  border-radius:18px;background:var(--tk-card);padding:18px 22px;
  box-shadow:0 2px 10px rgba(22,54,92,.06);
  animation:tk-fade .7s ease both .35s}
body.kiosk .messages{scrollbar-color:var(--tk-line) transparent}
body.kiosk .messages::-webkit-scrollbar-thumb{background:var(--tk-line)}
body.kiosk .messages .msg.user{display:none}
body.kiosk .messages .msg.bot:not(.current){display:none}
body.kiosk .messages .time{display:none}
body.kiosk .messages .msg.current{margin:auto 0;align-items:stretch;width:100%}

/* attract state: nothing to choose yet → invite the touch */
body.kiosk #attract{display:none;margin:auto;text-align:center}
body.kiosk .messages.nostep #attract{display:block}
body.kiosk #attract .ring{position:relative;width:76px;height:76px;margin:0 auto 14px}
body.kiosk #attract .ring::before,body.kiosk #attract .ring::after{content:"";
  position:absolute;inset:0;border-radius:50%;border:3px solid var(--tk-primary);
  opacity:0;animation:tk-ripple 2.4s ease-out infinite}
body.kiosk #attract .ring::after{animation-delay:1.2s}
body.kiosk #attract .hand{position:absolute;inset:0;display:flex;align-items:center;
  justify-content:center;font-size:2.1rem;animation:tk-tap 2.4s ease-in-out infinite}
body.kiosk #attractBtn{font:700 1.15rem/1 "Titillium Web",sans-serif;
  color:#fff;background:var(--tk-primary);border:none;border-radius:14px;
  padding:10px 34px 14px;cursor:pointer;box-shadow:0 4px 14px rgba(23,88,167,.35)}
body.kiosk #attractBtn:active{transform:scale(.96);background:var(--tk-primary-dark)}
body.kiosk #attract p{color:var(--tk-sub);font-size:.92rem;margin-top:10px}

/* ── explanatory animations (spec §1.3: "immagini dinamiche esplicative") —
 * shown by the shim when the bot's reply asks for a physical action ────── */
body.kiosk #usbAnim,body.kiosk #printAnim{display:none;text-align:center;
  padding:8px 0 2px}
body.kiosk .messages.show-usb #usbAnim{display:block}
body.kiosk .messages.show-print #printAnim{display:block}
body.kiosk .anim-label{color:var(--tk-sub);font-size:.92rem;font-weight:600;
  margin-top:10px}
/* ── USB key sliding into the port (continuous loop) ─────────────────────── */
body.kiosk .usb-scene{height:170px;position:relative}
/* the port panel at the bottom (the machine's front face) */
body.kiosk .usb-device{position:absolute;left:50%;bottom:6px;transform:translateX(-50%);
  width:204px;height:52px;border-radius:12px;
  background:linear-gradient(180deg,#eef3f9,#c7d4e2);
  border:1px solid var(--tk-line);box-shadow:0 6px 16px rgba(22,54,92,.18)}
body.kiosk .usb-slot{position:absolute;left:50%;top:-4px;transform:translateX(-50%);
  width:38px;height:13px;background:#12202f;border-radius:3px;
  box-shadow:inset 0 2px 4px rgba(0,0,0,.65)}
/* status LED on the port: goes green the moment the key seats */
body.kiosk .usb-led{position:absolute;right:16px;top:50%;margin-top:-5px;
  width:10px;height:10px;border-radius:50%;background:#9db4cc;
  animation:tk-usb-led 3s ease-in-out infinite}
/* data-transfer dots that pulse while the key is "read" */
body.kiosk .usb-dots{position:absolute;left:16px;top:50%;margin-top:-4px;
  display:flex;gap:6px}
body.kiosk .usb-dots i{width:7px;height:7px;border-radius:50%;background:var(--tk-primary);
  opacity:.15;animation:tk-usb-dot 3s ease-in-out infinite}
body.kiosk .usb-dots i:nth-child(2){animation-delay:.16s}
body.kiosk .usb-dots i:nth-child(3){animation-delay:.32s}
/* green acceptance glow the moment the key seats */
body.kiosk .usb-device::after{content:"";position:absolute;left:50%;top:2px;
  transform:translateX(-50%);width:38px;height:6px;border-radius:3px;
  animation:tk-usb-glow 3s ease-in-out infinite}
/* the moving key: body on top, metal connector below (plunges into the slot) */
body.kiosk .usb-key{position:absolute;left:50%;top:6px;margin-left:-16px;width:32px;
  display:flex;flex-direction:column;align-items:center;
  animation:tk-usb-in 3s cubic-bezier(.45,0,.4,1) infinite}
body.kiosk .usb-body{position:relative;width:32px;height:46px;border-radius:7px;
  background:linear-gradient(135deg,#4a90d9,#1758a7);
  box-shadow:0 3px 8px rgba(22,54,92,.32)}
body.kiosk .usb-body::before{content:"";position:absolute;top:9px;left:50%;
  transform:translateX(-50%);width:13px;height:13px;border:2px solid rgba(255,255,255,.85);
  border-radius:50%}
body.kiosk .usb-cap{width:22px;height:17px;
  background:linear-gradient(180deg,#dbe1e8,#93a1b0);border-radius:0 0 3px 3px;
  box-shadow:inset 0 -2px 3px rgba(0,0,0,.25)}

/* ── printer: a ticket feeding out of the slot (continuous loop) ─────────── */
body.kiosk .print-scene{height:170px;position:relative;overflow:hidden}
body.kiosk .printer{position:absolute;left:50%;top:2px;transform:translateX(-50%);
  width:216px;height:60px;border-radius:14px 14px 8px 8px;
  background:linear-gradient(180deg,#eef3f9,#c7d4e2);
  border:1px solid var(--tk-line);box-shadow:0 6px 16px rgba(22,54,92,.18);z-index:3}
/* status LED that keeps blinking while it prints */
body.kiosk .printer::before{content:"";position:absolute;top:13px;left:18px;
  width:10px;height:10px;border-radius:50%;background:var(--tk-green);
  box-shadow:0 0 7px rgba(30,138,90,.8);animation:tk-print-led 1s ease-in-out infinite}
body.kiosk .printer-slot{position:absolute;left:50%;bottom:-3px;transform:translateX(-50%);
  width:164px;height:9px;background:#12202f;border-radius:4px;
  box-shadow:inset 0 2px 4px rgba(0,0,0,.55)}
/* the sheet feeds downward out of the slot, printed lines appearing in turn */
body.kiosk .print-sheet{position:absolute;left:50%;top:54px;width:136px;height:96px;
  background:#fff;border-radius:0 0 6px 6px;box-shadow:0 8px 18px rgba(22,54,92,.22);
  z-index:2;transform:translateX(-50%);clip-path:inset(0 0 100% 0);
  animation:tk-print-feed 3s cubic-bezier(.35,.65,.3,1) infinite}
body.kiosk .print-sheet span{display:block;height:6px;margin:14px 16px 0;
  border-radius:3px;background:#dbe4ef;opacity:0;
  animation:tk-print-line 3s ease-in-out infinite}
body.kiosk .print-sheet span:nth-child(1){width:60%;animation-delay:.35s}
body.kiosk .print-sheet span:nth-child(2){width:90%;animation-delay:.6s}
body.kiosk .print-sheet span:nth-child(3){width:75%;animation-delay:.85s}
body.kiosk .print-sheet span:nth-child(4){width:85%;animation-delay:1.1s}

/* ── service cards (spec: letterbox + title + subtitle, white on blue) ── */
body.kiosk .wtitle{grid-column:1 / -1;width:100%;text-align:center;
  color:var(--tk-primary);font-weight:700;font-size:1.02rem;
  text-transform:uppercase;letter-spacing:.12em;margin:0}
body.kiosk .choices{display:grid;grid-template-columns:1fr 1fr;gap:12px;
  max-width:100%;justify-content:stretch}
body.kiosk .chip{display:flex;align-items:center;gap:14px;width:100%;
  background:var(--tk-card);border:1.5px solid var(--tk-line);border-radius:14px;
  padding:12px 16px;min-height:72px;cursor:pointer;text-align:left;
  font-family:inherit;color:var(--tk-navy);
  transition:transform .12s ease,border-color .15s,box-shadow .15s;
  animation:tk-card .4s cubic-bezier(.2,.8,.3,1) both}
body.kiosk .chip:nth-child(2){animation-delay:.05s}
body.kiosk .chip:nth-child(3){animation-delay:.1s}
body.kiosk .chip:nth-child(4){animation-delay:.15s}
body.kiosk .chip:nth-child(5){animation-delay:.2s}
body.kiosk .chip:nth-child(6){animation-delay:.25s}
body.kiosk .chip:nth-child(7){animation-delay:.3s}
body.kiosk .chip:nth-child(8){animation-delay:.35s}
body.kiosk .chip:hover{border-color:var(--tk-primary)}
body.kiosk .chip:active{transform:scale(.97);border-color:var(--tk-primary);
  box-shadow:0 0 0 3px rgba(23,88,167,.18)}
body.kiosk .letterbox{flex:0 0 46px;height:46px;display:flex;align-items:center;
  justify-content:center;background:var(--tk-primary);color:#fff;
  font-weight:900;font-size:1.3rem;border-radius:10px}
body.kiosk .chipbody .lbl{color:var(--tk-navy);font-weight:700;font-size:1.12rem}
body.kiosk .chipbody .sub{color:var(--tk-sub);font-size:.86rem;font-weight:400}
body.kiosk .chip.parent .chipbody .lbl::after{content:"  ›";color:var(--tk-primary)}
body.kiosk .chip.chosen{border-color:var(--tk-green);background:#f0f9f4}
body.kiosk .choices.done .chip:not(.chosen){opacity:.45}
/* the back action reads as a footer button (spec: ‹ Torna al menu) */
body.kiosk .chip.back{grid-column:1 / -1;min-height:52px;justify-content:center;
  background:none;border:1.5px solid var(--tk-primary);color:var(--tk-primary)}
body.kiosk .chip.back .lbl{color:var(--tk-primary);font-size:1rem}

/* ── the ticket: paper printing out of the machine (signature moment) ── */
body.kiosk .msg.current:has(.ticket){align-items:center}
/* the printer slot the paper slides out of */
body.kiosk .msg.current:has(.ticket)::before{content:"";width:min(330px,78%);
  height:10px;border-radius:999px;background:#cdd9e6;margin:0 auto 16px;
  box-shadow:inset 0 2px 5px rgba(22,54,92,.3);
  animation:tk-slot-pulse 2.2s ease-in-out infinite}
body.kiosk .ticket{position:relative;background:#fff;border:none;
  border-radius:10px 10px 0 0;padding:20px 34px 18px;min-width:290px;
  text-align:center;font-family:inherit;color:var(--tk-navy);
  box-shadow:0 10px 28px rgba(22,54,92,.22);
  animation:tk-print 1s cubic-bezier(.2,.85,.3,1) both,
            tk-ticket-bob 2.8s ease-in-out 1.1s infinite}
/* torn paper edge: white sawtooth strip under the ticket */
body.kiosk .ticket::after{content:"";position:absolute;left:0;right:0;
  bottom:-9px;height:10px;
  background:
    linear-gradient(-45deg,#fff 7px,transparent 0) left bottom/16px 16px repeat-x,
    linear-gradient(45deg,#fff 7px,transparent 0) left bottom/16px 16px repeat-x}
body.kiosk .ticket .tlabel{color:var(--tk-sub);font-size:.72rem;font-weight:700;
  text-transform:uppercase;letter-spacing:.22em;margin-bottom:2px}
body.kiosk .ticket .tcode{color:var(--tk-primary);font-family:inherit;
  font-weight:900;font-size:3.4rem;line-height:1.1;letter-spacing:.04em}
body.kiosk .ticket .tservice{color:var(--tk-navy);font-weight:700;font-size:1.1rem}
body.kiosk .ticket .tmeta{color:var(--tk-sub);font-size:.82rem}
body.kiosk .ticket .tnote{color:var(--tk-navy);font-size:.9rem;margin-top:8px;
  padding-top:8px;border-top:1px dashed var(--tk-line)}

/* ── composer: one big voice button + wide input, kiosk sized ─────────── */
body.kiosk .composer{background:var(--tk-card);border:1px solid var(--tk-line);
  border-radius:999px;padding:8px 10px;margin:0 0 4px;gap:10px;
  box-shadow:0 2px 10px rgba(22,54,92,.06);
  animation:tk-rise .5s cubic-bezier(.2,.8,.3,1) both .45s}
body.kiosk .mic,body.kiosk .kb,body.kiosk .send,body.kiosk .stop,body.kiosk .mutebtn{
  width:56px;height:56px;border-radius:50%;font-size:1.4rem;border:none;
  transition:transform .12s ease}
body.kiosk .mic{background:var(--tk-primary);color:#fff;
  box-shadow:0 4px 12px rgba(23,88,167,.35)}
body.kiosk .mic:active{transform:scale(.94)}
body.kiosk .mic.live{background:var(--tk-green);animation:tk-mic 1.6s ease-in-out infinite}
body.kiosk .kb{background:#e5edf5;color:var(--tk-navy)}
body.kiosk .send{background:var(--tk-primary);color:#fff}
body.kiosk .stop{background:#c0392b;color:#fff}
body.kiosk #textInput{background:transparent;border:none;color:var(--tk-navy);
  font-family:inherit;font-size:1.15rem;font-weight:600}
body.kiosk #textInput::placeholder{color:var(--tk-sub);font-weight:400}

/* on-screen keyboard sits on the light theme */
body.kiosk .simple-keyboard{border-radius:14px;border:1px solid var(--tk-line)}

/* ── settings stay a staff drawer ────────────────────────────────────── */
body.kiosk .panel{position:fixed;top:70px;right:14px;bottom:14px;
  width:min(360px,88vw);z-index:60;transform:translateX(115%);
  transition:transform .25s ease;box-shadow:0 12px 40px rgba(0,0,0,.45)}
body.kiosk.nopanel .panel{display:flex}
body.kiosk:not(.nopanel) .panel,body.kiosk .panel.open{transform:none}

/* ── motion ───────────────────────────────────────────────────────────── */
@keyframes tk-drop{from{opacity:0;transform:translateY(-14px)}to{opacity:1;transform:none}}
@keyframes tk-rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes tk-fade{from{opacity:0}to{opacity:1}}
@keyframes tk-card{from{opacity:0;transform:translateY(10px) scale(.97)}to{opacity:1;transform:none}}
@keyframes tk-instr{0%{transform:scale(.985);opacity:.4}100%{transform:none;opacity:1}}
@keyframes tk-listen{0%,100%{box-shadow:0 0 0 0 rgba(30,138,90,.35)}
  50%{box-shadow:0 0 0 9px rgba(30,138,90,0)}}
@keyframes tk-mic{0%,100%{box-shadow:0 0 0 0 rgba(30,138,90,.45)}
  50%{box-shadow:0 0 0 12px rgba(30,138,90,0)}}
@keyframes tk-ripple{0%{transform:scale(.4);opacity:.8}100%{transform:scale(1.5);opacity:0}}
@keyframes tk-tap{0%,20%,100%{transform:none}10%{transform:scale(.82)}}
@keyframes tk-print{0%{transform:translateY(-70%);opacity:0}
  55%{transform:translateY(6%);opacity:1}75%{transform:translateY(-2%)}
  100%{transform:none;opacity:1}}
/* USB: hover, plunge into the slot, seat (LED+dots+glow fire), lift back out */
@keyframes tk-usb-in{0%,10%{transform:translateY(-10px)}
  40%,72%{transform:translateY(44px)}100%{transform:translateY(-10px)}}
@keyframes tk-usb-glow{0%,38%{box-shadow:0 0 0 0 rgba(30,138,90,0)}
  50%{box-shadow:0 0 0 10px rgba(30,138,90,.4)}72%,100%{box-shadow:0 0 0 0 rgba(30,138,90,0)}}
@keyframes tk-usb-led{0%,38%{background:#9db4cc;box-shadow:none}
  50%,70%{background:#1e8a5a;box-shadow:0 0 8px rgba(30,138,90,.85)}
  84%,100%{background:#9db4cc;box-shadow:none}}
@keyframes tk-usb-dot{0%,40%{opacity:.15}48%{opacity:1}
  56%{opacity:.15}64%{opacity:1}72%,100%{opacity:.15}}
/* printer: sheet feeds downward out of the slot, then clears; LED blinks */
@keyframes tk-print-feed{0%,8%{clip-path:inset(0 0 100% 0);transform:translateX(-50%) translateY(-6px)}
  55%{clip-path:inset(0 0 0 0);transform:translateX(-50%) translateY(0)}
  86%{clip-path:inset(0 0 0 0);transform:translateX(-50%) translateY(0);opacity:1}
  100%{clip-path:inset(0 0 0 0);transform:translateX(-50%) translateY(0);opacity:0}}
@keyframes tk-print-line{0%,14%{opacity:0}30%{opacity:1}84%{opacity:1}100%{opacity:0}}
@keyframes tk-print-led{0%,100%{opacity:.35}50%{opacity:1}}
/* ticket: gentle continuous bob once printed, and a glowing print slot */
@keyframes tk-ticket-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
@keyframes tk-slot-pulse{0%,100%{box-shadow:inset 0 2px 5px rgba(22,54,92,.3)}
  50%{box-shadow:inset 0 2px 5px rgba(22,54,92,.3),0 0 14px 2px rgba(23,88,167,.4)}}
@media (prefers-reduced-motion:reduce){
  body.kiosk *,body.kiosk *::before,body.kiosk *::after{animation:none !important}
  /* …EXCEPT the explanatory kiosk animations (USB / printer / ticket / card):
   * these are informational — they show the user the physical action to take —
   * so on the totem they must keep playing even when the OS asks to reduce
   * motion. Higher-specificity !important rules re-enable exactly these. */
  body.kiosk .usb-key{animation:tk-usb-in 3s cubic-bezier(.45,0,.4,1) infinite !important}
  body.kiosk .usb-device::after{animation:tk-usb-glow 3s ease-in-out infinite !important}
  body.kiosk .usb-led{animation:tk-usb-led 3s ease-in-out infinite !important}
  body.kiosk .usb-dots i{animation:tk-usb-dot 3s ease-in-out infinite !important}
  body.kiosk .usb-dots i:nth-child(2){animation-delay:.16s !important}
  body.kiosk .usb-dots i:nth-child(3){animation-delay:.32s !important}
  body.kiosk .printer::before{animation:tk-print-led 1s ease-in-out infinite !important}
  body.kiosk .print-sheet{animation:tk-print-feed 3s cubic-bezier(.35,.65,.3,1) infinite !important}
  body.kiosk .print-sheet span{animation:tk-print-line 3s ease-in-out infinite !important}
  body.kiosk .print-sheet span:nth-child(1){animation-delay:.35s !important}
  body.kiosk .print-sheet span:nth-child(2){animation-delay:.6s !important}
  body.kiosk .print-sheet span:nth-child(3){animation-delay:.85s !important}
  body.kiosk .print-sheet span:nth-child(4){animation-delay:1.1s !important}
  body.kiosk .msg.current:has(.ticket)::before{animation:tk-slot-pulse 2.2s ease-in-out infinite !important}
  body.kiosk .ticket{animation:tk-print 1s cubic-bezier(.2,.85,.3,1) both,
    tk-ticket-bob 2.8s ease-in-out 1.1s infinite !important}
  body.kiosk .card-laser{animation:tk-scan 1.8s ease-in-out infinite !important}
  body.kiosk .card-card{animation:tk-swipe 2.6s ease-in-out infinite !important}
}

/* ═══════════════════════════════════════════════════════════════════════
 * v5 — "Assistente Virtuale" arrangement (client-mockup layout):
 * branded header (brand card left · title + signal right, hatched band),
 * compact echo captions, accessibility toolbar, physical-action animations,
 * text-scale + high-contrast modes, and the "Chiama aiuto" overlay.
 * ═══════════════════════════════════════════════════════════════════════ */

/* ── branded header ─────────────────────────────────────────────────────── */
body.kiosk .tk-header{display:flex;align-items:stretch;gap:14px;
  position:relative;overflow:hidden;
  /* faint diagonal hatch band behind the title (spec: texture, not color) */
  background-image:
    repeating-linear-gradient(135deg,rgba(22,54,92,.05) 0 2px,transparent 2px 11px),
    linear-gradient(0deg,var(--tk-card),var(--tk-card))}
body.kiosk .tk-brand-card{display:flex;align-items:center;gap:12px;
  background:var(--tk-card);border:1px solid var(--tk-line);border-radius:12px;
  padding:8px 16px;box-shadow:0 1px 4px rgba(22,54,92,.08);flex:0 0 auto}
body.kiosk .tk-logo{width:44px;height:44px;border-radius:9px;flex:0 0 auto;
  background:linear-gradient(115deg,var(--tk-primary) 0 34%,#3f83c9 34% 56%,
             #8db9e2 56% 74%,#e2523f 74% 100%);transform:skewX(-8deg)}
body.kiosk .tk-brand-name{color:var(--tk-navy);font-weight:900;font-size:1.08rem;
  line-height:1.02;letter-spacing:.005em}
body.kiosk .tk-header-right{margin-left:auto;display:flex;align-items:center;
  gap:16px}
body.kiosk .tk-title{color:var(--tk-navy);font-weight:900;font-size:1.7rem;
  line-height:.98;text-align:right;letter-spacing:.005em}
/* signal bars (connection indicator) */
body.kiosk .tk-signal{display:inline-flex;align-items:flex-end;gap:3px;height:26px}
body.kiosk .tk-signal i{width:5px;background:var(--tk-primary);border-radius:2px;
  opacity:.9}
body.kiosk .tk-signal i:nth-child(1){height:35%}
body.kiosk .tk-signal i:nth-child(2){height:55%}
body.kiosk .tk-signal i:nth-child(3){height:78%}
body.kiosk .tk-signal i:nth-child(4){height:100%}
body.kiosk.disconnected .tk-signal i{background:var(--tk-sub);opacity:.35}
/* staff controls: fullscreen + settings sit at the top-right, clearly visible;
 * the rest (clock, connection/mic/tts pills, reset — covered by the toolbar) stay hidden */
body.kiosk .tk-header .status{display:flex;align-items:center;gap:8px}
body.kiosk .tk-header .clock,body.kiosk .tk-header #connState,
body.kiosk .tk-header #micState,body.kiosk .tk-header #ttsState,
body.kiosk .tk-header #resetBtn{display:none}
body.kiosk .tk-header #fsBtn,body.kiosk .tk-header #panelBtn{
  opacity:1;width:42px;height:42px;font-size:1.3rem;line-height:1;
  display:inline-flex;align-items:center;justify-content:center;
  color:var(--tk-primary);background:var(--tk-card);
  border:1.5px solid var(--tk-line);border-radius:11px;cursor:pointer}
body.kiosk .tk-header #fsBtn:hover,body.kiosk .tk-header #panelBtn:hover{
  border-color:var(--tk-primary);background:#eaf1fa}
body.kiosk .tk-header #fsBtn:active,body.kiosk .tk-header #panelBtn:active{
  transform:scale(.95)}

/* ── compact echo captions (kept, slimmed to one line each) ─────────────── */
body.kiosk .bot-echo.compact{height:46px;margin:8px 0 0;padding:4px 22px;
  font-size:1.05rem;border-top-width:3px}
body.kiosk .bot-echo.compact span{-webkit-line-clamp:1;line-clamp:1}
body.kiosk .user-echo.compact{height:34px;width:min(560px,86%);margin:7px auto 0;
  font-size:.92rem;padding:2px 18px}
body.kiosk .user-echo.compact span{-webkit-line-clamp:1;line-clamp:1}

/* ── helper line (speaker icon + accessibility hint) ────────────────────── */
body.kiosk .tk-help{display:flex;align-items:center;gap:8px;margin:10px 2px 0;
  color:var(--tk-sub);font-size:.82rem;font-weight:600;line-height:1.25}
body.kiosk .tk-help-ico{color:var(--tk-primary);font-size:1rem;flex:0 0 auto}

/* ── accessibility toolbar ──────────────────────────────────────────────── */
body.kiosk .tk-toolbar{display:flex;flex-wrap:wrap;gap:8px;margin:8px 0 0;
  animation:tk-rise .5s cubic-bezier(.2,.8,.3,1) both .25s}
body.kiosk .tk-tool{flex:1 1 0;min-width:88px;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:3px;min-height:70px;padding:8px 6px;
  background:var(--tk-card);border:1.5px solid var(--tk-line);border-radius:12px;
  color:var(--tk-navy);font-family:inherit;cursor:pointer;text-align:center;
  transition:transform .12s ease,border-color .15s,box-shadow .15s,background .15s}
body.kiosk .tk-tool:hover{border-color:var(--tk-primary)}
body.kiosk .tk-tool:active{transform:scale(.96);
  box-shadow:0 0 0 3px rgba(23,88,167,.18)}
body.kiosk .tk-tool .ti{font-size:1.35rem;line-height:1}
body.kiosk .tk-tool .tk-aa{font-weight:900;letter-spacing:.02em;color:var(--tk-primary)}
body.kiosk .tk-tool .tl{font-size:.74rem;font-weight:700;line-height:1.05;
  color:var(--tk-navy)}
body.kiosk .tk-tool .tl-2{display:flex;flex-direction:column;gap:1px}
body.kiosk .tk-tool .tl-2 b{font-size:.74rem;font-weight:700}
body.kiosk .tk-tool .tl-2 small{font-size:.62rem;font-weight:400;color:var(--tk-sub)}
/* active accessibility modes read as "on" */
body.kiosk .tk-tool.active{border-color:var(--tk-primary);background:#eaf1fa}
/* mic: green while listening */
body.kiosk .tk-tool-mic.on{border-color:var(--tk-green);background:#e9f6ef}
body.kiosk .tk-tool-mic.on .ti{filter:none}
body.kiosk .tk-tool-mic.on .tl-2 b{color:var(--tk-green)}
body.kiosk .tk-tool-mic.on::before{content:"●";color:var(--tk-green);
  position:absolute;font-size:.6rem}
body.kiosk .tk-tool-mic{position:relative}
body.kiosk .tk-tool-mic.on::before{top:8px;left:10px}
/* help: red call-to-action */
body.kiosk .tk-tool-help{border-color:#d9534f;background:#fdeceb}
body.kiosk .tk-tool-help .ti,body.kiosk .tk-tool-help .tl{color:#c0392b}
body.kiosk .tk-tool-help:hover{border-color:#c0392b}
/* language on a non-native model: subtle hint it's UI-only for now */
body.kiosk .tk-tool.tk-nonnative .tl{color:var(--tk-primary)}

/* ── composer: input + labelled "Invia", mic/keyboard live in the toolbar.
 * It only appears in touch mode (Tastiera on); then it + the keyboard REPLACE
 * the menu/animation area, exactly as in the mockup. Voice is the default. ── */
body.kiosk .composer{margin-top:8px;display:none}
body.kiosk.tk-kb-on .composer{display:flex}
body.kiosk.tk-kb-on .messages{display:none}
body.kiosk .composer .mic,body.kiosk .composer .kb{display:none}
body.kiosk .composer .send{width:auto;min-width:96px;height:52px;border-radius:26px;
  display:flex;align-items:center;justify-content:center;gap:8px;padding:0 20px;
  font-family:inherit;font-weight:700;font-size:1.05rem}
body.kiosk .composer .send .send-ico{font-size:1.1rem}
body.kiosk .composer .stop{width:52px;height:52px}

/* ── card-swipe animation (spec: "Passa la tessera sul barcode") ────────── */
body.kiosk #cardAnim{display:none;text-align:center;padding:6px 0 2px}
body.kiosk .messages.show-card #cardAnim{display:block}
body.kiosk #cardAnim .anim-title{color:var(--tk-navy);font-weight:900;
  font-size:1.25rem;margin-bottom:14px}
body.kiosk .card-scene{position:relative;height:120px;max-width:340px;margin:0 auto}
/* the reader: a dark slab with a glowing scan line */
body.kiosk .card-reader{position:absolute;right:8px;bottom:0;width:150px;height:96px;
  background:linear-gradient(160deg,#20344b,#16263a);border-radius:12px;
  box-shadow:0 8px 20px rgba(22,54,92,.3)}
body.kiosk .card-glass{position:absolute;inset:12px 14px auto;height:34px;
  background:#0c1826;border-radius:6px;overflow:hidden}
body.kiosk .card-laser{position:absolute;left:0;right:0;top:6px;height:3px;
  background:#e2523f;box-shadow:0 0 8px 2px rgba(226,82,63,.7);
  animation:tk-scan 1.8s ease-in-out infinite}
/* the card sweeps across the reader, barcode down */
body.kiosk .card-card{position:absolute;left:10px;bottom:26px;width:120px;height:76px;
  background:linear-gradient(135deg,#3f83c9,#1758a7);border-radius:10px;
  box-shadow:0 6px 16px rgba(22,54,92,.28);animation:tk-swipe 2.6s ease-in-out infinite}
body.kiosk .card-chip{position:absolute;top:12px;left:12px;width:20px;height:15px;
  background:#f2c94c;border-radius:3px}
body.kiosk .card-bars{position:absolute;bottom:10px;left:12px;right:12px;height:20px;
  background:repeating-linear-gradient(90deg,#16365c 0 2px,#fff 2px 5px);
  border-radius:2px}

/* ── text scale (accessibility) ─────────────────────────────────────────── */
body.kiosk.tk-lg .bot-echo.compact{font-size:1.32rem;height:auto;min-height:52px}
body.kiosk.tk-lg .user-echo.compact{font-size:1.12rem;height:auto;min-height:42px}
body.kiosk.tk-lg .tk-help{font-size:1rem}
body.kiosk.tk-lg .tk-tool .tl,body.kiosk.tk-lg .tk-tool .tl-2 b{font-size:.9rem}
body.kiosk.tk-lg .tk-tool .tl-2 small{font-size:.74rem}
body.kiosk.tk-lg .chipbody .lbl{font-size:1.32rem}
body.kiosk.tk-lg .chipbody .sub{font-size:1rem}
body.kiosk.tk-lg #textInput,body.kiosk.tk-lg .composer .send{font-size:1.28rem}
body.kiosk.tk-lg #cardAnim .anim-title,body.kiosk.tk-lg .anim-label{font-size:1.35rem}

body.kiosk.tk-xl .bot-echo.compact{font-size:1.6rem;height:auto;min-height:64px}
body.kiosk.tk-xl .user-echo.compact{font-size:1.32rem;height:auto;min-height:52px}
body.kiosk.tk-xl .tk-help{font-size:1.18rem}
body.kiosk.tk-xl .tk-tool{min-height:82px}
body.kiosk.tk-xl .tk-tool .tl,body.kiosk.tk-xl .tk-tool .tl-2 b{font-size:1.02rem}
body.kiosk.tk-xl .tk-tool .tl-2 small{font-size:.82rem}
body.kiosk.tk-xl .tk-tool .ti{font-size:1.6rem}
body.kiosk.tk-xl .chipbody .lbl{font-size:1.55rem}
body.kiosk.tk-xl .chipbody .sub{font-size:1.15rem}
body.kiosk.tk-xl #textInput,body.kiosk.tk-xl .composer .send{font-size:1.5rem}
body.kiosk.tk-xl #cardAnim .anim-title,body.kiosk.tk-xl .anim-label{font-size:1.6rem}

/* ── high contrast (accessibility) ──────────────────────────────────────── */
body.kiosk.tk-hc{--tk-navy:#000;--tk-sub:#1a1a1a;--tk-line:#000;
  --tk-page:#fff;--tk-card:#fff;--tk-primary:#0a3f80;--tk-primary-dark:#062a58}
body.kiosk.tk-hc::before{background:#fff}
body.kiosk.tk-hc .tk-header,body.kiosk.tk-hc .bot-echo,body.kiosk.tk-hc .user-echo,
body.kiosk.tk-hc .messages,body.kiosk.tk-hc .composer,body.kiosk.tk-hc .tk-tool,
body.kiosk.tk-hc .chip,body.kiosk.tk-hc .tk-brand-card{border-width:2px;
  box-shadow:none}
body.kiosk.tk-hc .tk-help,body.kiosk.tk-hc .chipbody .sub,
body.kiosk.tk-hc .tk-tool .tl-2 small{color:#1a1a1a}
body.kiosk.tk-hc .user-echo.compact{background:#fff}
body.kiosk.tk-hc #avatarBox,body.kiosk.tk-hc #avatarContainer,
body.kiosk.tk-hc #avatarL2dCanvas{background:#fff !important}

/* ── "Chiama aiuto" overlay ─────────────────────────────────────────────── */
body.kiosk .tk-overlay{position:fixed;inset:0;z-index:200;display:flex;
  align-items:center;justify-content:center;background:rgba(16,32,52,.55);
  backdrop-filter:blur(2px);animation:tk-fade .2s ease both}
body.kiosk .tk-overlay.hidden{display:none}
body.kiosk .tk-overlay-card{background:var(--tk-card);border-radius:20px;
  padding:36px 44px;max-width:520px;text-align:center;
  box-shadow:0 24px 60px rgba(0,0,0,.4);animation:tk-drop .35s cubic-bezier(.2,.8,.3,1) both}
body.kiosk .tk-overlay-ico{font-size:3.2rem;margin-bottom:10px}
body.kiosk .tk-overlay-card h2{color:var(--tk-navy);font-weight:900;
  font-size:1.7rem;margin:0 0 10px}
body.kiosk .tk-overlay-card p{color:var(--tk-sub);font-size:1.05rem;
  line-height:1.4;margin:0 0 22px}
body.kiosk .tk-overlay-btn{background:var(--tk-primary);color:#fff;border:none;
  border-radius:14px;padding:12px 40px;font:700 1.1rem/1 "Titillium Web",sans-serif;
  cursor:pointer;box-shadow:0 4px 14px rgba(23,88,167,.35)}
body.kiosk .tk-overlay-btn:active{transform:scale(.96);background:var(--tk-primary-dark)}

/* ── extra motion ───────────────────────────────────────────────────────── */
@keyframes tk-scan{0%,100%{top:4px}50%{top:24px}}
@keyframes tk-swipe{0%,10%{left:6px;bottom:26px}
  45%,55%{left:120px;bottom:12px}90%,100%{left:6px;bottom:26px}}

/* ═══════════════════════════════════════════════════════════════════════
 * v6 — top bar moved INSIDE the avatar canvas (client request): the header
 * (brand card · title · signal · staff controls) floats as a translucent
 * overlay pinned to the top of the avatar stage, so the stage itself grows
 * taller. The <header> is now the FIRST CHILD of #avatarBox; the id-scoped
 * rules below outrank the standalone-header styling from v5. app.js binds
 * the same element IDs regardless of where they sit, so it is untouched.
 * ═══════════════════════════════════════════════════════════════════════ */
/* The avatar is the main canvas: let it occupy all remaining page space.
 * The header and controls stay above the artwork as overlays. */
body.kiosk #avatarBox{flex:1 1 auto;min-height:0;margin:2px 0 0}
body.kiosk #avatarContainer{position:absolute;inset:0;min-height:0}
@media (max-height:760px){body.kiosk #avatarBox{flex:1 1 auto}}

/* the header as an overlay clipped to the rounded canvas (overflow:hidden
 * on #avatarBox keeps it INSIDE the stage) */
body.kiosk #avatarBox>.tk-header{position:absolute;top:0;left:0;right:0;z-index:7;
  display:flex;align-items:center;gap:12px;margin:0;padding:10px 14px;
  border:0;border-radius:0;box-shadow:none;overflow:visible;
  /* fully transparent: no scrim/band — the avatar shows through the whole bar */
  background:transparent;animation:none}
/* soft halo keeps the title legible over the avatar without any background box */
body.kiosk #avatarBox>.tk-header .tk-title{
  text-shadow:0 1px 2px rgba(255,255,255,.85),0 0 10px rgba(255,255,255,.6)}
/* trim the brand card + type a touch so the bar sits neatly in the corner */
body.kiosk #avatarBox>.tk-header .tk-brand-card{padding:6px 12px}
body.kiosk #avatarBox>.tk-header .tk-logo{width:38px;height:38px}
body.kiosk #avatarBox>.tk-header .tk-brand-name{font-size:1rem}
body.kiosk #avatarBox>.tk-header .tk-title{font-size:1.5rem}
/* high-contrast mode: keep the bar transparent, drop the light halo (the HC
 * avatar background is white and the title is black — already max contrast) */
body.kiosk.tk-hc #avatarBox>.tk-header{background:transparent}
body.kiosk.tk-hc #avatarBox>.tk-header .tk-title{text-shadow:none}

/* The renderer belongs to the page-sized stage, not the small avatarBox
 * layout slot. avatarBox now only owns the overlay controls; the canvas in
 * avatarContainer sits behind the complete chat surface. */
body.kiosk #chat{position:relative}
body.kiosk #avatarBox{position:static;flex:0 0 0;height:0;min-height:0;margin:0;
  border:0;border-radius:0;overflow:visible;background:transparent;z-index:1;
  pointer-events:none}
body.kiosk #avatarContainer{position:absolute;inset:0;width:auto;height:auto;
  min-height:0;z-index:0}
body.kiosk #avatarBox>.tk-header,
body.kiosk #avatarBox>#avatarLoading,
body.kiosk #avatarBox>#avatarSubtitle,
body.kiosk #avatarBox>.mic-orb{pointer-events:auto}
/* Keep spoken captions above the compact bottom interaction cluster. */
body.kiosk #avatarSubtitle{bottom:calc(19vh + 74px); background: transparent;}
@media (max-height:760px){body.kiosk #avatarSubtitle{bottom:calc(19vh + 64px)}}
body.kiosk #botEcho,body.kiosk #userEcho,body.kiosk .tk-help,
body.kiosk .tk-toolbar,body.kiosk .messages{position:relative;z-index:1}

/* Keep the interaction cluster at the bottom of the page-sized avatar stage:
 * the flexible top margin absorbs the unused space, while the dynamic area
 * keeps a bounded scrollable height for menus, keyboard input, and animations. */
body.kiosk .tk-help{margin-top:auto}
body.kiosk .tk-accessibility-toggle{align-self:flex-start;position:relative;z-index:2;
  width:30px;height:30px;margin:3px 0 0;padding:0;border:1px solid var(--tk-line);
  border-radius:50%;background:rgba(255,255,255,.9);color:var(--tk-primary);
  font-size:.9rem;line-height:1;cursor:pointer;box-shadow:0 2px 6px rgba(22,54,92,.18)}
body.kiosk .tk-accessibility-toggle:hover{border-color:var(--tk-primary);background:#fff}
body.kiosk .tk-toolbar{gap:2px;margin-top:3px}
body.kiosk .tk-tool{min-width:60px;min-height:38px;padding:2px 2px;gap:1px;border-radius:7px}
body.kiosk .tk-tool .ti{font-size:.85rem}
body.kiosk .tk-tool .tl{font-size:.55rem;line-height:1}
body.kiosk .tk-tool .tl-2 b{font-size:.55rem}
body.kiosk .tk-tool .tl-2 small{font-size:.46rem}
body.kiosk .messages{flex:0 1 30vh ;min-height:120px ;max-height:34vh;overflow-y:auto;background:transparent}
@media (max-height:760px){body.kiosk .messages{flex-basis:27vh;min-height:105px ;max-height:31vh}}

/* Compact the contents of the bottom interaction card as well. */
body.kiosk .messages{margin:6px 0;padding:8px 10px;border-radius:12px}
body.kiosk .messages .msg.current{margin:auto 0}
body.kiosk #attract .ring{width:48px;height:48px;margin-bottom:6px}
body.kiosk #attract .hand{font-size:1.45rem}
body.kiosk #attractBtn{font-size:.9rem;border-radius:10px;padding:7px 20px 9px}
body.kiosk #attract p{font-size:.72rem;margin-top:5px}
body.kiosk .wtitle{font-size:.78rem;letter-spacing:.08em}
body.kiosk .choices{gap:4px}
body.kiosk .chip{gap:5px;border-radius:7px;padding:4px 6px;min-height:32px}
body.kiosk .letterbox{flex-basis:24px;height:24px;font-size:.72rem;border-radius:5px}
body.kiosk .chipbody .lbl{font-size:.68rem;line-height:1}
body.kiosk .chipbody .sub{font-size:.56rem;line-height:1}
body.kiosk .chip.back{padding:4px 8px;min-height:28px}
body.kiosk .chip.back{min-height:38px}
body.kiosk .anim-label{font-size:.72rem;margin-top:5px}
body.kiosk .usb-scene,body.kiosk .print-scene{height:105px;transform:scale(.68);transform-origin:center top;margin-bottom:-32px}
body.kiosk #cardAnim .anim-title{font-size:.78rem}
body.kiosk .card-scene{transform:scale(.68);transform-origin:center top;margin-bottom:-32px}

/* Final compact pass: let the active dynamic state size itself instead of
 * forcing it into a fixed-height scrolling box. */
body.kiosk .messages{flex:0 0 auto !important;height:auto !important;
  min-height:0 !important;max-height:none !important;overflow:visible !important}
body.kiosk .msg.current:has(.ticket)::before{width:min(240px,70%);height:6px;margin-bottom:7px}
body.kiosk .ticket{min-width:220px;padding:10px 18px 9px;border-radius:7px}
body.kiosk .ticket .tcode{font-size:2.1rem}
body.kiosk .ticket .tservice{font-size:.82rem}
body.kiosk .ticket .tmeta{font-size:.64rem}
body.kiosk .ticket .tnote{font-size:.7rem;margin-top:4px;padding-top:4px}
body.kiosk .ticket .tlabel{font-size:.58rem}
/* Use zoom rather than a parent transform: child translate/rotate animations
 * retain their intended geometry and do not appear skewed. */
body.kiosk .usb-scene,body.kiosk .print-scene{height:150px;transform:none;zoom:.58;margin-bottom:-58px}
body.kiosk .card-scene{height:150px;transform:none;zoom:.58;margin-bottom:-58px}
body.kiosk #cardAnim .anim-title{font-size:.7rem;margin-bottom:5px}

/* Spoken/user echo text: a small cloud bubble floating on the right side of
 * the avatar instead of occupying a full-width row in the bottom layout. */
body.kiosk .echo-cloud{position:absolute;right:38%;top:1%;width:min(340px,34%);
  z-index:4;display:flex;flex-direction:column;gap:3px;padding:9px 12px;border-radius:22px;
  background:transparent;backdrop-filter:blur(5px);
  box-shadow:0 5px 18px rgba(22,54,92,.18);pointer-events:none}
body.kiosk .echo-cloud::after{content:"";position:absolute;right:24px;bottom:-9px;
  width:18px;height:18px;background:transparent;
  transform:rotate(45deg)}
body.kiosk .echo-cloud #botEcho,body.kiosk .echo-cloud #userEcho{width:100%;height:auto;
  min-height:0;margin:0;padding:3px 5px;border:0;border-radius:10px;
  background:transparent;box-shadow:none;animation:none;color:var(--tk-navy)}
body.kiosk .echo-cloud #botEcho{font-size:.72rem;line-height:1.1}
body.kiosk .echo-cloud #userEcho{font-size:.62rem;line-height:1.05;color:var(--tk-sub)}
body.kiosk .echo-cloud #userEcho.empty{display:none}
body.kiosk .echo-cloud .echo-pill span{max-width:100%}
