/* Neooverse platform — shared stylesheet.
   Every colour, font, radius and the avatar shape come from CSS custom
   properties written by the server from each instance's brand config, so this
   file never needs editing to rebrand or re-theme. */

:root{
  --bg-deep:#07080f; --bg-panel:#0d0f1a; --bg-surface:#141726; --bg-input:#1a1e30;
  --border:rgba(80,110,160,.15); --border-focus:rgba(80,140,220,.4);
  --text-primary:rgba(220,230,245,.95); --text-secondary:rgba(170,185,210,.75);
  --text-muted:rgba(130,150,180,.5);
  --accent:#4a8cd8; --accent-glow:rgba(74,140,216,.25); --danger:#d84a4a;
  --ok:#4ab482; --warn:#d8a34a;
  --radius:14px; --avatar-radius:130px;
  --font-body:'DM Sans',sans-serif; --font-display:'Syne',sans-serif;
}
*,*::before,*::after{box-sizing:border-box}
html,body{margin:0;padding:0;width:100%;min-height:100%;background:var(--bg-deep);
  color:var(--text-primary);font-family:var(--font-body);-webkit-font-smoothing:antialiased}
body{background:radial-gradient(ellipse at 20% 0%,var(--accent-glow) 0%,transparent 55%),var(--bg-deep);
  background-attachment:fixed}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}
code,pre,.mono{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.8rem}
pre{background:var(--bg-surface);border:1px solid var(--border);border-radius:10px;padding:12px;
  overflow-x:auto;white-space:pre-wrap;word-break:break-all;color:var(--text-secondary)}

/* ══ chrome ═══════════════════════════════════════ */
.topbar{display:flex;align-items:center;gap:16px;padding:14px 26px;
  background:linear-gradient(135deg,rgba(30,40,70,.5),rgba(20,28,50,.3));
  border-bottom:1px solid var(--border);position:sticky;top:0;z-index:30;backdrop-filter:blur(10px)}
.brand{font-family:var(--font-display);font-size:1.25rem;font-weight:700;letter-spacing:-.01em}
.brand span{color:var(--accent)}
/* The brand's logo, in the wordmark's place (or beside it). A large logo
   spills into the bar's padding instead of making the bar taller, so no
   screen's layout moves whichever size is chosen. */
.brand.has-logo{display:inline-flex;align-items:center;gap:10px;min-width:0;line-height:1;
  height:1.2em}                  /* the wordmark's own line: the logo overflows into the padding */
.brand .brand-logo{display:block;flex-shrink:0;height:34px;width:auto;max-width:240px;
  object-fit:contain;object-position:left center}
.brand.logo-s .brand-logo{height:26px;max-width:190px}
.brand.logo-l .brand-logo{height:44px;max-width:300px}
.brand .brand-word{color:inherit;white-space:nowrap}
.topbar nav{display:flex;gap:18px;margin-left:auto;align-items:center;flex-wrap:wrap}
.topbar nav a{color:var(--text-secondary);font-size:.9rem;transition:.2s}
.topbar nav a:hover,.topbar nav a.on{color:var(--accent);text-decoration:none}

.wrap{max-width:1240px;margin:0 auto;padding:28px 26px 80px}
.wrap.narrow{max-width:520px}
h1{font-family:var(--font-display);font-size:1.9rem;font-weight:700;margin:0 0 6px;letter-spacing:-.02em}
h2{font-family:var(--font-display);font-size:1.15rem;font-weight:600;margin:34px 0 14px}
h3{font-size:.72rem;margin:18px 0 8px;color:var(--text-muted);text-transform:uppercase;letter-spacing:.09em;font-weight:600}
.sub{color:var(--text-secondary);margin:0 0 22px;font-size:.95rem}

.card{background:var(--bg-panel);border:1px solid var(--border);border-radius:16px;padding:20px;
  margin-bottom:16px;box-shadow:0 12px 40px rgba(0,0,0,.25)}
.grid{display:grid;gap:16px}
.grid.c2{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.grid.c3{grid-template-columns:repeat(auto-fit,minmax(220px,1fr))}
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.spread{display:flex;justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap}

/* ══ forms ════════════════════════════════════════ */
label{display:block;font-size:.78rem;color:var(--text-secondary);margin:14px 0 6px}
input[type=text],input[type=password],input[type=number],input[type=file],select,textarea{
  width:100%;background:var(--bg-input);color:var(--text-primary);border:1px solid var(--border);
  border-radius:10px;padding:10px 13px;font-family:var(--font-body);font-size:.9rem;outline:none;transition:.2s}
textarea{min-height:96px;resize:vertical;font-size:.85rem;line-height:1.55}
input:focus,select:focus,textarea:focus{border-color:var(--border-focus);box-shadow:0 0 0 3px var(--accent-glow)}
input[type=checkbox]{width:auto;accent-color:var(--accent)}

.btn{display:inline-flex;align-items:center;gap:8px;background:var(--accent);color:#fff;border:0;
  border-radius:10px;padding:10px 17px;font-size:.88rem;font-weight:600;cursor:pointer;
  font-family:var(--font-body);transition:.2s;box-shadow:0 6px 22px var(--accent-glow)}
.btn:hover{filter:brightness(1.12);text-decoration:none}
.btn.ghost{background:var(--bg-surface);color:var(--text-secondary);border:1px solid var(--border);box-shadow:none}
.btn.ghost:hover{border-color:var(--accent);color:var(--accent)}
.btn.danger{background:var(--danger);box-shadow:0 6px 22px rgba(216,74,74,.22)}
.btn.sm{padding:7px 12px;font-size:.8rem}
.btn:disabled{opacity:.35;cursor:not-allowed;box-shadow:none}

table{width:100%;border-collapse:collapse;font-size:.88rem}
th,td{text-align:left;padding:12px 14px;border-bottom:1px solid var(--border);vertical-align:middle}
th{color:var(--text-muted);font-size:.68rem;text-transform:uppercase;letter-spacing:.08em;font-weight:600}
tr:last-child td{border-bottom:0}

.pill{display:inline-flex;align-items:center;gap:6px;font-size:.7rem;padding:4px 10px;border-radius:99px;
  background:var(--bg-surface);color:var(--text-secondary);border:1px solid var(--border);font-weight:600}
.pill.ok{color:var(--ok);border-color:rgba(74,180,130,.35);background:rgba(74,180,130,.1)}
.pill.warn{color:var(--warn);border-color:rgba(216,163,74,.35);background:rgba(216,163,74,.1)}
.pill.err{color:var(--danger);border-color:rgba(216,74,74,.35);background:rgba(216,74,74,.1)}
.pill.robot{color:var(--accent);border-color:rgba(74,140,216,.35);background:rgba(74,140,216,.1)}
.dot{width:6px;height:6px;border-radius:50%;background:currentColor;display:inline-block}

.alert{padding:12px 15px;border-radius:11px;margin-bottom:16px;font-size:.88rem;border:1px solid}
.alert.err{background:rgba(216,74,74,.1);border-color:rgba(216,74,74,.35)}
.alert.ok{background:rgba(74,180,130,.1);border-color:rgba(74,180,130,.35)}
.alert.warn{background:rgba(216,163,74,.1);border-color:rgba(216,163,74,.35)}

.muted{color:var(--text-secondary)}
.tiny{font-size:.74rem}
.empty{text-align:center;padding:52px 20px;color:var(--text-muted)}
.kv{display:grid;grid-template-columns:190px 1fr;gap:8px 16px;font-size:.88rem}
.kv dt{color:var(--text-muted)}
.kv dd{margin:0}
.inherited{opacity:.6}
.badge-over{font-size:.58rem;background:var(--accent);color:#fff;padding:2px 6px;border-radius:5px;
  margin-left:7px;vertical-align:middle;font-weight:700;letter-spacing:.04em}
.copy{cursor:pointer;border:1px dashed var(--border);border-radius:9px;padding:10px 12px;
  background:var(--bg-surface);font-family:ui-monospace,monospace;font-size:.76rem;word-break:break-all}
.copy:hover{border-color:var(--accent)}
hr{border:0;border-top:1px solid var(--border);margin:24px 0}

/* ══ operator stage ═══════════════════════════════ */
.stage{display:flex;gap:18px;align-items:stretch;
  height:calc(100vh - 190px);min-height:520px}
.panel-left{flex:1 1 auto;display:flex;flex-direction:column;min-width:260px;min-height:0;
  background:var(--bg-panel);
  border-radius:18px;border:1px solid var(--border);overflow:hidden;box-shadow:0 16px 50px rgba(0,0,0,.4)}
.panel-right{flex:0 0 360px;display:flex;flex-direction:column;align-items:center;gap:14px}

/* Public view: presentation hidden, persona enlarged. The chat stays — it is
   how the visitor talks to the persona — but it narrows so the video grows. */
.stage-toggle{margin-left:auto;display:flex;align-items:center;gap:8px;cursor:pointer;
  background:var(--bg-surface);border:1px solid var(--border);border-radius:999px;
  color:var(--text-secondary);font-family:var(--font-body);font-size:.82rem;padding:7px 15px;transition:.2s}
.stage-toggle:hover{color:var(--accent);border-color:var(--accent)}
/* Presentation hidden: the conversation becomes the page. It used to keep the
   380px column it had while sharing space with the slides, which left a narrow
   strip of chat floating beside a large portrait. */
.stage.focus-avatar .slide-viewer{display:none}
.stage.focus-avatar .panel-left{flex:1 1 auto;min-width:0}
.stage.focus-avatar .panel-right{flex:0 0 clamp(260px,26vw,380px)}
.stage.focus-avatar .avatar-wrap{max-width:100%;max-height:52vh}
.stage.focus-avatar .chat-section{flex:1 1 auto;min-height:0}
.stage.focus-avatar .chat-messages{max-height:none}

.slide-viewer{flex:1 1 62%;display:flex;flex-direction:column;min-height:0;border-bottom:1px solid var(--border)}
.slide-header{display:flex;align-items:center;padding:12px 18px;gap:12px;
  background:linear-gradient(135deg,rgba(30,40,70,.6),rgba(20,28,50,.4));border-bottom:1px solid var(--border)}
/* The deck's title is the operator's own text — "neooverse" must stay
   lowercase. The display face is a brand font with only capital forms, so a
   title set in it came out shouting. */
.slide-title{flex:1;font-family:var(--font-body);font-weight:600;font-size:.92rem;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.slide-counter{font-size:.78rem;color:var(--text-muted);white-space:nowrap}
.slide-image-wrap{flex:1;min-height:260px;display:flex;align-items:center;justify-content:center;
  padding:12px;background:#080a14;overflow:hidden;position:relative}
.slide-image-wrap img{max-width:100%;max-height:100%;object-fit:contain;border-radius:8px;
  transition:opacity .25s ease,transform .25s ease}
.slide-nav{display:flex;gap:9px;padding:10px 16px;justify-content:center;flex-shrink:0;flex-wrap:wrap}
.slide-nav-btn{padding:9px 16px;border-radius:9px;border:1px solid var(--border);background:var(--bg-surface);
  color:var(--text-secondary);font-family:var(--font-body);font-size:.8rem;cursor:pointer;transition:.2s;
  display:inline-flex;align-items:center;gap:7px}
.slide-nav-btn:hover:not(:disabled){border-color:var(--accent);color:var(--accent)}
.slide-nav-btn:disabled{opacity:.3;cursor:not-allowed}
.slide-nav-btn.teach{border-color:rgba(74,180,130,.35);color:rgba(74,180,130,.85)}
.slide-nav-btn.teach:hover{border-color:rgba(74,180,130,.7)}
.slide-nav-btn.danger{border-color:rgba(216,74,74,.35);color:rgba(216,74,74,.85)}
.slide-nav-btn.on{border-color:var(--accent);color:var(--accent);background:rgba(74,140,216,.12)}

.chat-section{flex:1 1 38%;display:flex;flex-direction:column;min-height:0}
.chat-messages{flex:1 1 0;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:14px 16px;display:flex;flex-direction:column;gap:10px;
  scrollbar-width:thin;scrollbar-color:rgba(80,110,160,.3) transparent;font-size:.88rem}
.chat-messages::-webkit-scrollbar{width:5px}
.chat-messages::-webkit-scrollbar-thumb{background:rgba(80,110,160,.3);border-radius:3px}
.message{display:flex;flex-direction:column;max-width:88%;animation:slideUp .3s ease-out}
.message.user{align-self:flex-end}
.message.assistant{align-self:flex-start}
.message-label{font-size:.6rem;font-weight:500;text-transform:uppercase;letter-spacing:.06em;
  color:var(--text-muted);margin-bottom:3px;padding:0 3px}
.message.user .message-label{text-align:right}
.message-bubble{padding:11px 15px;border-radius:12px;font-size:.87rem;line-height:1.55;
  word-wrap:break-word;white-space:pre-wrap}
.message.user .message-bubble{background:rgba(74,140,216,.14);border:1px solid rgba(74,140,216,.22);
  border-bottom-right-radius:4px}
.message.assistant .message-bubble{background:rgba(40,50,75,.5);border:1px solid rgba(80,100,140,.15);
  border-bottom-left-radius:4px}
@keyframes slideUp{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.welcome-message{text-align:center;padding:20px;color:var(--text-muted);font-size:.85rem}

.chat-input-area{padding:12px 16px;border-top:1px solid var(--border);flex-shrink:0}
@media (max-width:980px){
  /* On a phone the persona, slide and conversation stack tall; without this the
     "Ask about anything" field sat a full screen below the fold. Sticking it to
     the bottom of the viewport keeps it — and the newest reply above it — in
     reach while scrolling. */
  .chat-input-area{position:sticky;bottom:0;z-index:5;background:var(--bg-panel);
    padding-bottom:max(12px, env(safe-area-inset-bottom))}
}
.input-row{display:flex;gap:9px;align-items:center}
.input-row input{flex:1}

/* the persona: a tall portrait capsule, exactly as the classroom presents it */
.avatar-container{width:100%;display:flex;align-items:flex-start;justify-content:center}
.avatar-wrap{width:100%;max-width:300px;aspect-ratio:9/16;max-height:52vh;border-radius:var(--avatar-radius);
  overflow:hidden;background:#0a0c16;box-shadow:0 20px 50px rgba(0,0,0,.6);position:relative;
  border:1px solid var(--border)}
.avatar-wrap video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .3s}
.avatar-badge{position:absolute;left:50%;bottom:14px;transform:translateX(-50%);z-index:3}

.mic-container{display:flex;align-items:center;gap:14px}
.mic-btn{width:66px;height:66px;border-radius:50%;border:1px solid var(--border);background:var(--bg-surface);
  color:var(--text-secondary);font-size:1.25rem;cursor:pointer;transition:.2s;
  display:flex;align-items:center;justify-content:center}
.mic-btn:hover{border-color:var(--accent);color:var(--accent)}
.mic-btn.recording{background:var(--danger);color:#fff;border-color:var(--danger);
  animation:pulse 1.1s ease-in-out infinite}
@keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(216,74,74,.4)}50%{box-shadow:0 0 0 14px rgba(216,74,74,0)}}
.mic-label{font-size:.62rem;letter-spacing:.14em;color:var(--text-muted);text-transform:uppercase}
.eq-bar{width:4px;height:10px;border-radius:2px;background:var(--accent);opacity:.5;transition:height .1s}

.side-card{width:100%;background:var(--bg-panel);border:1px solid var(--border);border-radius:16px;padding:14px 16px}
.mode-toggles{display:flex;gap:18px;justify-content:center;flex-wrap:wrap}
.toggle-item{display:flex;align-items:center;gap:8px}
.toggle-switch{position:relative;display:inline-block;width:38px;height:21px}
.toggle-switch input{opacity:0;width:0;height:0}
.toggle-slider{position:absolute;cursor:pointer;inset:0;background:var(--bg-surface);
  border:1px solid var(--border);border-radius:21px;transition:.25s}
.toggle-slider:before{position:absolute;content:"";height:13px;width:13px;left:3px;bottom:3px;
  background:var(--text-muted);border-radius:50%;transition:.25s}
.toggle-switch input:checked + .toggle-slider{background:rgba(74,140,216,.25);border-color:var(--accent)}
.toggle-switch input:checked + .toggle-slider:before{transform:translateX(17px);background:var(--accent)}
.toggle-label{font-size:.76rem;color:var(--text-secondary)}

.thumbs{display:flex;gap:7px;overflow-x:auto;padding:10px 16px;border-top:1px solid var(--border)}
.thumbs img{height:52px;border-radius:6px;border:2px solid transparent;cursor:pointer;flex:0 0 auto;opacity:.6;transition:.2s}
.thumbs img:hover{opacity:1}
.thumbs img.on{border-color:var(--accent);opacity:1}

/* ══ tablet & phone ═══════════════════════════════
   The persona leads, then the slides, then the conversation. Nothing is
   allowed to stretch into dead space: the slide keeps its aspect ratio and
   the chat gets its own scroll area. */
@media (max-width:980px){
  /* 16px is the threshold below which iOS Safari zooms the page when a field
     is focused — which then leaves the layout zoomed-in and panned. Keep every
     text field at 16px on phones. */
  input[type=text],input[type=password],input[type=number],select,textarea{font-size:16px}
  .stage{height:auto;min-height:0}
  .chat-messages{max-height:46vh}

  /* Presentation hidden on a tall screen: the persona keeps a sensible size
     and the conversation takes everything else. It used to sit at its 150px
     minimum under a 600px portrait, with a screenful of empty space below. */
  .stage.focus-avatar{height:calc(100dvh - 130px);min-height:0}
  .stage.focus-avatar .panel-left{flex:1 1 auto;min-height:0}
  .stage.focus-avatar .panel-right{flex:0 0 auto}
  .stage.focus-avatar .avatar-wrap{max-width:min(58vw,300px);max-height:34vh}
  .stage.focus-avatar .chat-section{flex:1 1 auto;min-height:0}
  .stage.focus-avatar .chat-messages{flex:1 1 auto;max-height:none;min-height:0}
  .stage-toggle span{display:none}

  .wrap{padding:16px 12px 60px}
  .topbar{padding:10px 14px;gap:10px;flex-wrap:wrap}
  .topbar .row{min-width:0;flex-wrap:wrap}
  .topbar .stage-toggle span{display:none}   /* icons only on a narrow bar */
  .brand{font-size:1.05rem;flex-shrink:0}
  .brand .brand-logo{height:30px;max-width:170px}
  .brand.logo-s .brand-logo{height:24px;max-width:140px}
  .brand.logo-l .brand-logo{height:38px;max-width:210px}
  .topbar nav{gap:14px;flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;
              -webkit-overflow-scrolling:touch}
  .topbar nav::-webkit-scrollbar{display:none}
  .topbar nav a{white-space:nowrap;font-size:.82rem}
  h1{font-size:1.45rem}
  .spread{flex-direction:column;align-items:stretch;gap:10px}
  .spread .row{width:100%}
  .spread .row select{flex:1 1 100%;min-width:0 !important}
  .spread .row .btn{flex:1}

  .stage{flex-direction:column-reverse;min-height:0;gap:14px}
  .panel-right{flex:none;width:100%;flex-direction:column;align-items:center;gap:12px}
  .avatar-container{order:-1}
  .avatar-wrap{max-width:min(58vw,230px);max-height:36vh}
  .side-card{width:100%}

  .panel-left{min-height:0}
  .slide-viewer{flex:none;display:flex}
  .slide-image-wrap{flex:none;aspect-ratio:16/9;min-height:0;padding:8px}
  .slide-nav{padding:8px 8px;gap:6px}
  .slide-nav-btn{padding:8px 10px;font-size:.72rem;gap:5px}
  .thumbs{padding:8px 10px}
  .thumbs img{height:42px}
  .chat-section{flex:none;min-height:0}
  .chat-messages{max-height:38vh;min-height:150px}
  .mic-btn{width:60px;height:60px;font-size:1.1rem}
  .grid.c2,.grid.c3{grid-template-columns:1fr}
  .kv{grid-template-columns:130px 1fr}
  th,td{padding:9px 8px;font-size:.8rem}
  .card{padding:14px}
}
@media (max-width:520px){
  .avatar-wrap{max-width:52vw;max-height:30vh;border-radius:calc(var(--avatar-radius) * .6)}
  .avatar-wrap video{border-radius:inherit}
  h1{font-size:1.25rem}
  .slide-nav-btn{padding:7px 8px;font-size:.68rem}
  .row .btn{flex:1 1 auto;justify-content:center}
}


/* ── audience question queue ──────────────────────────────────────────────
   One persona has one voice, so questions wait their turn. The line is shown
   to everyone: the audience sees fairness, the host sees the workload. */
.queue-strip{border-bottom:1px solid var(--border);background:var(--bg-surface);
  padding:10px 14px;max-height:34vh;overflow-y:auto;flex:0 0 auto}
.queue-head{display:flex;align-items:center;justify-content:space-between;
  font-size:.74rem;text-transform:uppercase;letter-spacing:.08em;color:var(--text-muted);
  font-weight:600;margin-bottom:8px}
.queue-count{background:var(--accent);color:#fff;border-radius:999px;
  min-width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;
  font-size:.74rem;padding:0 7px;letter-spacing:0}
.queue-mine{font-size:.82rem;color:var(--accent);margin-bottom:8px;font-weight:600}
.queue-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}
.queue-item{display:flex;align-items:center;gap:8px;font-size:.85rem;
  background:var(--bg-input);border:1px solid var(--border);border-radius:10px;
  padding:8px 11px;color:var(--text-secondary)}
.queue-item .queue-text{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.queue-item.now{border-color:var(--accent);color:var(--text-primary)}
.queue-item.mine{border-left:3px solid var(--accent)}
.queue-badge{font-size:.68rem;text-transform:uppercase;letter-spacing:.07em;
  color:var(--accent);white-space:nowrap}
.queue-btn{background:transparent;border:1px solid var(--border);border-radius:8px;
  color:var(--text-muted);width:26px;height:26px;cursor:pointer;transition:.2s;flex:0 0 auto}
.queue-btn:hover{color:var(--accent);border-color:var(--accent)}
.queue-btn.danger:hover{color:var(--danger);border-color:var(--danger)}
.audience-status{justify-content:center}

/* ── host controls ───────────────────────────────────────────────────────── */
.host-controls{padding:12px 16px;border-top:1px solid var(--border);background:var(--bg-surface)}
.slide-nav-btn.danger:hover{color:var(--danger);border-color:var(--danger)}
.slide-nav-btn:disabled,.btn:disabled{opacity:.4;cursor:not-allowed}

/* ── one face: the robot's ────────────────────────────────────────────────
   Pages that are not the robot's own screen add .no-avatar: the persona's
   video column disappears and each page is laid out for its actual job. */
.no-avatar .avatar-container,
.no-avatar .avatar-wrap{display:none !important}

/* ── the guest app ────────────────────────────────────────────────────────
   A guest's phone is a conversation with the persona, nothing more: who you
   are talking to and what the room is doing on top, the chat filling the
   screen, and one row to ask — text, send, or hold the mic. The deck lives on
   the robot and the TV; the persona's face lives on the robot. */
.guest-head{display:none}
body.guest .guest-head{display:flex;align-items:center;justify-content:space-between;
  gap:12px;padding:10px 16px;background:var(--bg-panel);border-bottom:1px solid var(--border)}
.guest-id{display:flex;flex-direction:column;gap:2px;min-width:0}
.guest-name{font-family:var(--font-display);font-weight:700;font-size:1.05rem}
.guest-status{display:flex;align-items:center;gap:6px;font-size:.78rem;color:var(--text-secondary)}
.guest-status .dot{width:7px;height:7px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 6px var(--accent-glow);flex:0 0 auto}
.guest-quiet{display:flex;align-items:center;gap:6px;font-size:.78rem;
  color:var(--text-secondary);cursor:pointer;white-space:nowrap}
.guest-quiet input{width:auto;accent-color:var(--accent)}

body.guest .stage-toggle{display:none}
body.guest .slide-viewer{display:none}
body.guest .panel-right{display:none}
body.guest .wrap{padding:0}
body.guest .stage{height:calc(100dvh - 51px - 55px);min-height:0;gap:0;
  flex-direction:column}
body.guest .panel-left{flex:1 1 auto;min-height:0;border-radius:0;border-left:0;border-right:0;
  width:100%;max-width:760px;margin:0 auto}
body.guest .chat-section{flex:1 1 auto;min-height:0;display:flex;flex-direction:column}
body.guest .chat-messages{flex:1 1 auto;max-height:none;min-height:0}
body.guest .chat-input-area{position:static;padding-bottom:max(10px, env(safe-area-inset-bottom))}

/* ── the host rail ────────────────────────────────────────────────────────
   The host's right column is the room's operations: the audience queue gets
   the space the avatar used to take (it is the host's actual work), the robot
   card sits under it, the host's own voice at the bottom. */
.host-rail{align-items:stretch}
.host-rail .queue-card{flex:1 1 auto;min-height:180px;display:flex;flex-direction:column;overflow:hidden}
.host-rail .queue-card .queue-strip{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;background:transparent}
.host-rail .queue-card .queue-list{flex:1 1 auto;overflow-y:auto;min-height:0}
.host-rail .host-voice .mic-btn{width:58px;height:58px}
@media (max-width:980px){
  .host-rail .queue-card{min-height:0}
  .host-rail{width:100%}
}

.mic-inline{display:none}
body.guest .mic-inline{display:flex;align-items:center;justify-content:center;
  width:46px;height:46px;flex:0 0 auto;border-radius:50%;cursor:pointer;
  background:var(--bg-input);border:1px solid var(--border);color:var(--accent);
  font-size:1.05rem;transition:.15s;-webkit-user-select:none;user-select:none;
  touch-action:none}
.mic-inline:active{background:var(--accent);color:#fff;transform:scale(1.06)}
.guest-mic-hint{display:none;text-align:center;margin-top:6px}
body.guest .guest-mic-hint{display:block}

/* ── television ──────────────────────────────────────────────────────────
   Read from across a room: the slide takes the wall, the persona sits beside
   it, and there is nothing to type into. */
.tv{display:flex;gap:22px;align-items:stretch;height:100vh;padding:22px;box-sizing:border-box}
.tv-slide{flex:1 1 auto;display:flex;align-items:center;justify-content:center;
  background:var(--bg-panel);border:1px solid var(--border);border-radius:18px;overflow:hidden}
.tv-slide img{max-width:100%;max-height:100%;object-fit:contain}
.tv-idle{text-align:center;padding:30px}
.tv-wordmark{font-family:var(--font-display);font-size:3.2rem;font-weight:700}
.tv-wordmark span{color:var(--accent)}
/* On the television the logo is the idle screen's centrepiece. */
.tv-wordmark.has-logo{display:flex;flex-direction:column;align-items:center;gap:18px}
.tv-wordmark .brand-logo{display:block;height:120px;width:auto;max-width:70vw;object-fit:contain}
.tv-wordmark.logo-s .brand-logo{height:90px}
.tv-wordmark.logo-l .brand-logo{height:160px}
.tv-wordmark .brand-word{color:inherit}
.tv-name{font-size:1.5rem;color:var(--text-secondary);margin-top:10px}
.tv-hint{font-size:1rem;color:var(--text-muted);margin-top:18px}
.tv-side{flex:0 0 300px;display:flex;flex-direction:column;gap:14px;align-items:center}
.tv-side .avatar-wrap{width:100%;max-width:300px;aspect-ratio:9/16;max-height:56vh}
.tv-caption{font-size:1.05rem;line-height:1.5;color:var(--text-primary);text-align:center;
  max-height:22vh;overflow:hidden}
.tv-queue{width:100%;background:var(--bg-surface);border:1px solid var(--border);
  border-radius:14px;padding:12px 14px;margin-top:auto}
.tv-queue-head{font-size:.8rem;color:var(--text-muted);text-transform:uppercase;
  letter-spacing:.08em;font-weight:600}
.tv-queue-now{font-size:.95rem;color:var(--text-secondary);margin-top:6px}
.tv-tap{position:fixed;inset:auto 0 26px 0;text-align:center;font-size:1.1rem;
  color:var(--accent);z-index:50}

@media (max-width:900px){
  .tv{flex-direction:column;height:auto}
  .tv-side{flex:0 0 auto;flex-direction:row;align-items:flex-start}
  .tv-side .avatar-wrap{max-width:150px;max-height:40vh}
}
/* Without the persona column the presentation is the whole point of the wall:
   the caption sits under the slide, the queue floats small in the corner. */
.no-avatar .tv-side{flex:0 0 300px}
.no-avatar.tv-caption-empty .tv-side{display:none}

/* Protocol samples in the robot instructions: readable, scrollable, and never
   pushing the page sideways. */
pre.code{background:var(--bg-input);border:1px solid var(--border);border-radius:10px;
  padding:10px 12px;overflow-x:auto;white-space:pre;line-height:1.45;margin:6px 0 0;
  color:var(--text-secondary);font-size:.72rem}
details summary{cursor:pointer;padding:6px 0}
details summary:hover{color:var(--accent)}

/* "Start here": present only while a persona is still incomplete, so a working
   one is never nagged. Done steps recede, the next one stands out. */
.setup-guide{border-left:3px solid var(--accent)}
.steps{list-style:none;counter-reset:step;margin:10px 0 0;padding:0;
  display:flex;flex-direction:column;gap:10px}
.steps li{counter-increment:step;position:relative;padding-left:32px;
  font-size:.88rem;color:var(--text-secondary);line-height:1.5}
.steps li::before{content:counter(step);position:absolute;left:0;top:0;
  width:22px;height:22px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  font-size:.72rem;font-weight:600;border:1px solid var(--border);color:var(--text-muted)}
.steps li.done{color:var(--text-muted)}
.steps li.done::before{content:"\2713";background:var(--accent);color:#fff;border-color:var(--accent)}
.steps li.done strong{font-weight:500}

.queue-item.failed{border-color:var(--danger);opacity:.85}
.queue-badge.err{color:var(--danger)}

/* ── kiosk on-screen keyboard ─────────────────────────────────────────────
   Slides up over the bottom of a touchscreen kiosk; the site's own theme, not
   the desktop's. Hidden entirely until attachKioskKeyboard decides the device
   actually needs it. */
.kiosk-kb{position:fixed;left:0;right:0;bottom:0;z-index:60;
  transform:translateY(105%);transition:transform .22s ease-out;
  background:var(--bg-panel);border-top:1px solid var(--border);
  box-shadow:0 -12px 40px rgba(0,0,0,.5);padding:6px 10px calc(10px + env(safe-area-inset-bottom))}
.kiosk-kb.open{transform:translateY(0)}
.kiosk-kb-bar{display:flex;justify-content:flex-end;padding:2px 4px}
.kiosk-kb-close{background:var(--bg-surface);border:1px solid var(--border);
  border-radius:8px;color:var(--text-secondary);width:44px;height:30px;cursor:pointer}
.kiosk-kb-close:hover{color:var(--accent);border-color:var(--accent)}
.kiosk-kb .simple-keyboard{max-width:900px;margin:0 auto;background:transparent}
.kiosk-kb-theme.hg-theme-default{background:transparent;font-family:var(--font-body)}
.kiosk-kb-theme.hg-theme-default .hg-button{background:var(--bg-surface);
  border:1px solid var(--border);border-bottom-width:2px;border-radius:8px;
  color:var(--text-primary);height:52px;font-size:1.05rem}
.kiosk-kb-theme.hg-theme-default .hg-button:active{background:var(--accent);color:#fff}
.kiosk-kb-theme .hg-button.hg-functionBtn{color:var(--text-secondary)}
.kiosk-kb-theme .hg-button[data-skbtn="{enter}"]{background:var(--accent);color:#fff;
  border-color:var(--accent);max-width:140px}

/* While the kiosk keyboard is open the page yields its height, so the input
   being typed into — and the newest messages — sit just above the keys
   instead of underneath them. */
body.kb-open .stage{height:calc(100vh - 190px - var(--kb-h, 320px));min-height:0}
body.kb-open{padding-bottom:var(--kb-h, 320px)}
/* On screens without room for slides AND keys, the slide yields while typing —
   the conversation and the input are what matter mid-question. */
@media (max-height:1050px){
  body.kb-open .slide-viewer{display:none}
  body.kb-open .chat-section{flex:1 1 auto}
}
/* The stacked layout runs persona, slide, conversation and input down one
   column, so a tall portrait panel can still have no room for the input above
   the keys — height alone does not decide it. While typing, the slide and a
   full-height persona yield; both return the moment the keyboard closes. */
@media (max-width:980px){
  /* Claim exactly the space above the keys. With height:auto the column
     collapses to its content and .chat-messages (flex-basis 0) is left with
     nothing to grow into — the conversation shrinks to a single line, which
     is what "squished" looked like on the panel. */
  body.kb-open .stage{height:calc(100vh - var(--kb-h, 320px) - 90px);min-height:0}
  body.kb-open .slide-viewer,
  body.kb-open .thumbs{display:none}
  body.kb-open .avatar-wrap{max-height:20vh}
  body.kb-open .chat-section{flex:1 1 auto}
  /* The conversation scrolls inside itself while typing; letting it grow
     would push the input back down under the keys on a long thread. */
  body.kb-open .chat-messages{max-height:34vh;min-height:0}
}

/* The hidden attribute always wins over a class's display value. */
[hidden]{display:none !important}

/* ══ reaching a person ════════════════════════════════════════════════════
   The robot's screen gets two tiles in the row of its controls, at the bottom
   just above the chat: "Message the team" on the left of the mic, the guest QR
   on the right. Nothing overlaps the persona, which keeps exactly its size. */
.robot-dock.with-tiles{display:grid !important;grid-template-columns:1fr 210px 1fr;
  align-items:end;gap:14px}
.robot-side{display:flex;flex-direction:column;align-items:center;gap:7px;text-align:center;
  min-width:0;justify-self:center}
.team-tile{width:min(168px,100%);min-height:94px;border-radius:18px;border:1px solid var(--border);
  background:var(--bg-surface);color:var(--text-primary);display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:8px;cursor:pointer;font-family:var(--font-body);
  font-size:.92rem;font-weight:600;line-height:1.25;padding:14px 10px;transition:.25s;
  -webkit-tap-highlight-color:transparent}
.team-tile i{font-size:1.7rem;color:var(--accent);transition:.25s}
.team-tile:active{transform:scale(.97)}
.team-tile.glow{background:var(--accent);color:#fff;border-color:var(--accent);
  animation:tileglow 1.6s ease-in-out infinite}
.team-tile.glow i{color:#fff}
@keyframes tileglow{0%,100%{box-shadow:0 0 0 4px var(--accent-glow),0 0 20px var(--accent-glow)}
  50%{box-shadow:0 0 0 8px var(--accent-glow),0 0 44px var(--accent-glow)}}
.robot-hint{font-size:.72rem;line-height:1.35;color:var(--text-secondary);max-width:180px}
.robot-hint.on{color:var(--accent);font-weight:600}
.qr-tile{width:min(112px,100%);border-radius:12px;background:#fff;padding:7px;border:0;
  cursor:zoom-in;display:block}
.qr-tile img{width:100%;height:auto;display:block;image-rendering:pixelated}
.mic-btn.team{background:var(--accent);color:#fff;border-color:var(--accent);
  box-shadow:0 0 0 5px var(--accent-glow),0 0 26px var(--accent-glow)}
.mic-label.team{color:var(--accent);font-weight:600}
.qr-overlay{position:fixed;inset:0;z-index:95;background:rgba(3,5,12,.86);display:flex;
  flex-direction:column;align-items:center;justify-content:center;gap:18px;cursor:zoom-out}
.qr-overlay img{width:min(72vw,440px);background:#fff;padding:18px;border-radius:20px}
.qr-overlay div{color:#fff;font-size:1.15rem;text-align:center;padding:0 20px}

/* The robot's chat: who you are talking to, and a clean start for the next
   visitor. */
.chat-head{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:9px 14px;border-bottom:1px solid var(--border);flex-shrink:0}
.chat-head-title{font-size:.74rem;letter-spacing:.07em;text-transform:uppercase;
  color:var(--text-muted);font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chat-new{background:var(--bg-surface);border:1px solid var(--border);color:var(--text-secondary);
  border-radius:999px;padding:8px 15px;font-family:var(--font-body);font-size:.84rem;cursor:pointer;
  display:inline-flex;align-items:center;gap:7px;transition:.2s;flex-shrink:0;white-space:nowrap}
.chat-new:hover{color:var(--accent);border-color:var(--accent)}
.chat-new.confirm{background:var(--danger);border-color:var(--danger);color:#fff}

/* ══ suggested questions ═══════════════════════════════════════════════════
   One slim row at the top of the chat — never taller than one line of
   buttons. More than fit scroll sideways, and the edge that has more fades
   and carries an arrow. Tints follow the brand's accent where the browser
   can mix colours, and fall back to the default blue where it cannot. */
.suggest-bar{position:relative;display:flex;align-items:center;flex-shrink:0;
  border-bottom:1px solid var(--border);
  background:linear-gradient(180deg,rgba(74,140,216,.08),rgba(74,140,216,0) 85%);
  background:linear-gradient(180deg,color-mix(in srgb,var(--accent) 9%,transparent),transparent 85%)}
.suggest-track{display:flex;align-items:center;gap:8px;overflow-x:auto;overflow-y:hidden;
  flex:1 1 auto;min-width:0;padding:9px 14px;scroll-behavior:smooth;scrollbar-width:none;
  -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
.suggest-track::-webkit-scrollbar{display:none}
.suggest-bar.more-right .suggest-track{
  -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 64px),transparent);
  mask-image:linear-gradient(90deg,#000 calc(100% - 64px),transparent)}
.suggest-bar.more-left .suggest-track{
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 64px);
  mask-image:linear-gradient(90deg,transparent,#000 64px)}
.suggest-bar.more-left.more-right .suggest-track{
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 64px,#000 calc(100% - 64px),transparent);
  mask-image:linear-gradient(90deg,transparent,#000 64px,#000 calc(100% - 64px),transparent)}
.suggest-lead{display:inline-flex;align-items:center;gap:6px;flex-shrink:0;font-size:.64rem;
  font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--text-muted);
  white-space:nowrap;padding-right:2px}
.suggest-lead i{color:var(--accent);font-size:.82rem}
.suggest-chip{flex-shrink:0;display:inline-flex;align-items:center;gap:7px;max-width:250px;
  min-height:36px;padding:7px 15px;border-radius:999px;cursor:pointer;white-space:nowrap;
  font-family:var(--font-body);font-size:.85rem;font-weight:500;line-height:1.2;
  color:var(--text-primary);transition:background .18s,border-color .18s,
  transform .12s,box-shadow .18s;-webkit-tap-highlight-color:transparent;
  border:1px solid rgba(74,140,216,.4);background:rgba(74,140,216,.1);
  border-color:color-mix(in srgb,var(--accent) 42%,transparent);
  background:color-mix(in srgb,var(--accent) 11%,transparent)}
.suggest-chip span{overflow:hidden;text-overflow:ellipsis}
.suggest-chip i{color:var(--accent);font-size:.8rem;flex-shrink:0}
.suggest-chip:hover{border-color:var(--accent);background:rgba(74,140,216,.2);
  background:color-mix(in srgb,var(--accent) 20%,transparent)}
.suggest-chip:active{transform:scale(.96)}
.suggest-chip.sent{background:var(--accent);border-color:var(--accent);color:#fff;
  box-shadow:0 0 0 4px var(--accent-glow)}
.suggest-chip.sent i{color:#fff}
.suggest-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:2;width:32px;height:32px;
  border-radius:50%;border:1px solid var(--border);background:var(--bg-panel);cursor:pointer;
  color:var(--text-secondary);display:flex;align-items:center;justify-content:center;font-size:.78rem;
  box-shadow:0 2px 12px rgba(0,0,0,.35)}
.suggest-nav:hover{color:var(--accent);border-color:var(--accent)}
.suggest-nav.prev{left:6px}
.suggest-nav.next{right:6px}

/* The admin's editor for them: one card per suggestion, in order. */
.sg-list{display:flex;flex-direction:column;gap:10px;margin-top:14px}
.sg-row{display:grid;grid-template-columns:30px 1fr auto;gap:12px;align-items:start;
  padding:12px;border:1px solid var(--border);border-radius:12px;background:var(--bg-surface)}
.sg-num{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  font-size:.8rem;font-weight:600;color:var(--accent);border:1px solid var(--accent);margin-top:22px}
.sg-fields{display:flex;flex-direction:column;gap:8px;min-width:0}
.sg-top{display:flex;gap:10px;flex-wrap:wrap}
.sg-field{display:flex;flex-direction:column;min-width:0}
.sg-field label{margin:0 0 4px}
.sg-grow{flex:1 1 240px}
.sg-place{flex:0 1 220px;min-width:160px}
.sg-field textarea{min-height:58px;resize:vertical}
.sg-hint{color:var(--text-secondary);line-height:1.5}
.sg-hint.warn{color:var(--warn)}
.sg-tools{display:flex;flex-direction:column;gap:6px;margin-top:22px}
.sg-tools .btn{justify-content:center;width:34px;padding:6px 0}
.sg-tools .btn:disabled{opacity:.35;cursor:default}
.sg-empty{margin-top:14px;padding:16px;border:1px dashed var(--border);border-radius:12px;
  text-align:center;color:var(--text-muted);font-size:.85rem}
.sg-empty i{color:var(--accent)}
.sg-preview{margin-top:16px;padding-top:12px;border-top:1px solid var(--border);transition:opacity .2s}
.sg-preview .suggest-bar{border:1px solid var(--border);border-radius:12px;overflow:hidden}
.sg-preview .suggest-chip{cursor:default}
.sg-unsaved{color:var(--warn);font-weight:600}
.sg-saved{color:var(--ok)}
@media (max-width:640px){
  .sg-row{grid-template-columns:1fr;gap:8px}
  .sg-num{margin-top:0}
  .sg-tools{flex-direction:row;margin-top:0}
}

/* Team lines in a visitor's chat. */
.message.team{align-self:flex-start}
.message.team .message-label{color:var(--ok)}
.message.team .message-bubble{background:rgba(74,180,130,.13);border:1px solid rgba(74,180,130,.38);
  border-bottom-left-radius:4px}
.message.user.to-team .message-bubble{border-color:var(--accent);background:rgba(74,140,216,.2)}
.to-team-tag{display:flex;align-items:center;gap:5px;justify-content:flex-end;font-size:.64rem;
  letter-spacing:.06em;text-transform:uppercase;color:var(--accent);margin-top:4px;padding:0 3px}
.team-status{align-self:flex-end;font-size:.72rem;color:var(--text-muted);display:flex;
  align-items:center;gap:6px;padding:0 4px}
.team-status.ok{color:var(--ok)}
.chat-divider{align-self:stretch;text-align:center;font-size:.68rem;color:var(--text-muted);
  letter-spacing:.07em;text-transform:uppercase;border-top:1px dashed var(--border);
  padding-top:8px;margin:6px 0 2px}
.offer-chips{display:flex;gap:8px;flex-wrap:wrap;align-self:flex-start}
.offer-chips button{border-radius:999px;padding:8px 14px;font-family:var(--font-body);font-size:.84rem;
  cursor:pointer;border:1px solid var(--accent);background:var(--accent);color:#fff;
  display:inline-flex;align-items:center;gap:6px}
.offer-chips button.ghost{background:transparent;color:var(--text-secondary);border-color:var(--border)}

/* The guest's phone: ask the persona, or message the team — one switch, and
   a line saying what happens either way. */
.ask-mode,.ask-mode-hint{display:none}
body.guest .ask-mode{display:flex;gap:4px;background:var(--bg-surface);border:1px solid var(--border);
  border-radius:999px;padding:4px;margin-bottom:6px}
.ask-mode button{flex:1;border:0;background:transparent;color:var(--text-secondary);
  border-radius:999px;padding:9px 8px;font-family:var(--font-body);font-size:.86rem;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;gap:6px;min-width:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ask-mode button.on{background:var(--accent);color:#fff}
body.guest .ask-mode-hint{display:block;text-align:center;margin:0 0 8px;font-size:.74rem}
body.guest.team-mode .mic-inline{background:var(--accent);color:#fff;border-color:var(--accent)}
body.guest.team-mode .ask-mode-hint{color:var(--accent)}

/* ══ the host app ═══════════════════════════════════════════════════════
   The host page, signed in and installable: a Control tab (the page as it
   always was) and a Messages tab — a messaging app for visitors reaching a
   person. Tabs sit at the top on a computer and at the bottom on a phone. */
.app-tabs{display:flex;gap:8px;margin:0 0 14px}
.app-tab{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--border);
  background:var(--bg-surface);color:var(--text-secondary);border-radius:999px;padding:9px 18px;
  font-family:var(--font-body);font-size:.9rem;cursor:pointer;transition:.2s;position:relative}
.app-tab.on{background:var(--accent);border-color:var(--accent);color:#fff}
.app-badge{min-width:20px;height:20px;border-radius:999px;background:var(--danger);color:#fff;
  font-size:.72rem;display:inline-flex;align-items:center;justify-content:center;padding:0 6px}
.app-badge[hidden]{display:none}
.app-user{display:inline-flex;align-items:center;gap:8px;font-size:.82rem;color:var(--text-secondary)}
.msg-view{display:grid;grid-template-columns:minmax(270px,370px) 1fr;gap:16px;
  height:calc(100vh - 175px);min-height:460px}
.msg-pane{background:var(--bg-panel);border:1px solid var(--border);border-radius:18px;
  display:flex;flex-direction:column;min-height:0;overflow:hidden}
.msg-pane-head{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:12px 14px;border-bottom:1px solid var(--border);flex-shrink:0}
.msg-pane-head b{font-family:var(--font-body);font-size:.98rem}
.msg-list{overflow-y:auto;flex:1;min-height:0}
.msg-group{padding:10px 14px 4px;font-size:.66rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--text-muted)}
.msg-item{display:flex;gap:11px;padding:12px 14px;border-bottom:1px solid var(--border);
  cursor:pointer;transition:background .15s;align-items:flex-start}
.msg-item:hover,.msg-item.on{background:var(--bg-surface)}
.msg-avatar{width:40px;height:40px;border-radius:50%;background:var(--bg-surface);flex:0 0 40px;
  display:flex;align-items:center;justify-content:center;color:var(--accent);font-size:1rem;
  border:1px solid var(--border)}
.msg-item.done .msg-avatar{color:var(--text-muted)}
.msg-body{flex:1;min-width:0}
.msg-top{display:flex;justify-content:space-between;gap:8px;align-items:baseline}
.msg-name{font-size:.88rem;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.msg-time{font-size:.7rem;color:var(--text-muted);white-space:nowrap}
.msg-preview{font-size:.82rem;color:var(--text-secondary);overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;margin-top:2px}
.msg-item.unread .msg-preview{color:var(--text-primary);font-weight:600}
.msg-meta{font-size:.7rem;color:var(--text-muted);margin-top:3px}
.msg-empty{padding:26px 18px;text-align:center;color:var(--text-muted);font-size:.86rem;line-height:1.5}
.app-card{margin:12px;padding:12px 14px;border-radius:14px;background:var(--bg-surface);
  border:1px solid var(--border);font-size:.84rem;line-height:1.45}
.app-card .row{margin-top:8px;gap:8px;flex-wrap:wrap}
.thread-context{margin:10px 14px 0;padding:9px 12px;border-radius:12px;background:var(--bg-surface);
  border:1px dashed var(--border);font-size:.78rem;color:var(--text-secondary);flex-shrink:0}
.thread-context summary{cursor:pointer;color:var(--text-muted)}
.thread-context p{margin:6px 0 0}
.msg-thread{flex:1;overflow-y:auto;padding:14px;display:flex;flex-direction:column;gap:8px;min-height:0}
.bubble{max-width:82%;padding:9px 13px;border-radius:14px;font-size:.88rem;line-height:1.45;
  word-wrap:break-word;white-space:pre-wrap}
.bubble-wrap{display:flex;flex-direction:column;max-width:100%}
.bubble-wrap.visitor{align-self:flex-start}
.bubble-wrap.team{align-self:flex-end;align-items:flex-end}
.bubble-wrap.persona{align-self:flex-start}
.bubble-wrap.visitor .bubble{background:var(--bg-surface);border:1px solid var(--border);
  border-bottom-left-radius:4px}
.bubble-wrap.team .bubble{background:var(--accent);color:#fff;border-bottom-right-radius:4px}
.bubble-wrap.persona .bubble{background:transparent;border:1px dashed var(--border);
  color:var(--text-secondary);font-size:.82rem}
.bubble-meta{font-size:.68rem;color:var(--text-muted);margin:3px 4px 0}
.bubble-sys{align-self:center;font-size:.72rem;color:var(--text-muted);text-align:center;padding:2px 10px}
.msg-typing{padding:0 16px 6px;font-size:.74rem;color:var(--accent);min-height:1.2em;flex-shrink:0}
.msg-quick{display:flex;gap:6px;flex-wrap:wrap;padding:8px 12px 0;flex-shrink:0}
.quick{border:1px solid var(--border);background:var(--bg-surface);border-radius:999px;padding:7px 12px;
  font-size:.8rem;cursor:pointer;color:var(--text-secondary);font-family:var(--font-body)}
.quick:hover{border-color:var(--accent);color:var(--accent)}
.msg-compose{display:flex;gap:8px;padding:10px 12px calc(10px + env(safe-area-inset-bottom));
  border-top:1px solid var(--border);flex-shrink:0;align-items:center}
.msg-compose input{flex:1}
.msg-back{display:none}
.app-modal{position:fixed;inset:0;z-index:95;background:rgba(3,5,12,.7);display:flex;
  align-items:center;justify-content:center;padding:18px}
.app-modal[hidden]{display:none}
.app-modal-card{background:var(--bg-panel);border:1px solid var(--border);border-radius:18px;
  padding:18px;max-width:420px;width:100%}
.app-modal-card h3{margin:0 0 8px}
@media (max-width:980px){
  body.app .wrap{padding-bottom:96px}
  body.app .app-tabs{position:fixed;left:0;right:0;bottom:0;z-index:40;margin:0;
    padding:8px 10px calc(8px + env(safe-area-inset-bottom));background:var(--bg-panel);
    border-top:1px solid var(--border);justify-content:space-around}
  body.app .app-tab{flex:1;justify-content:center}
  .msg-view{grid-template-columns:1fr;height:calc(100dvh - 170px);min-height:0}
  .msg-view.thread-open .msg-list-pane{display:none}
  .msg-view:not(.thread-open) .msg-thread-pane{display:none}
  .msg-back{display:inline-flex}
}

/* ══ branding: the logo card ═══════════════════════════════════════════════
   Three ways to show the brand, each drawn as it will look; a size switch;
   and a preview that is the real top-left corner. */
.logo-modes{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px;margin-top:12px}
.logo-mode{margin:0;cursor:pointer;display:flex;flex-direction:column;gap:10px;padding:13px 14px;
  border:1px solid var(--border);border-radius:12px;background:var(--bg-surface);transition:.15s}
.logo-mode:hover{border-color:var(--accent)}
.logo-mode.on{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow)}
.lm-title{display:flex;align-items:center;gap:8px;font-size:.86rem;font-weight:600;color:var(--text-primary)}
.lm-title input{margin:0;accent-color:var(--accent)}
.lm-demo{display:flex;align-items:center;gap:9px;height:42px;padding:0 12px;border-radius:9px;
  background:var(--bg-deep);border:1px solid var(--border);overflow:hidden;
  font-family:var(--font-display);font-weight:700;font-size:1rem;white-space:nowrap}
.lm-word span{color:var(--accent)}
.lm-logo{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:26px;
  color:var(--accent);flex-shrink:0}
.lm-logo img{height:26px;width:auto;max-width:110px;object-fit:contain}
.logo-sizes{display:inline-flex;gap:4px;background:var(--bg-surface);border:1px solid var(--border);
  border-radius:999px;padding:4px}
.logo-sizes label{margin:0;cursor:pointer}
.logo-sizes input{position:absolute;opacity:0;pointer-events:none}
.logo-sizes span{display:inline-block;padding:7px 16px;border-radius:999px;font-size:.84rem;
  color:var(--text-secondary);transition:.15s}
.logo-sizes input:checked + span{background:var(--accent);color:#fff}
.logo-sizes input:focus-visible + span{box-shadow:0 0 0 3px var(--accent-glow)}
.logo-current{display:flex;align-items:center;gap:12px;margin-top:10px;padding:10px 12px;
  border:1px dashed var(--border);border-radius:10px}
.logo-current img{height:44px;width:auto;max-width:180px;object-fit:contain;padding:4px;border-radius:6px;
  background:repeating-conic-gradient(#2a2f45 0% 25%,#1c2033 0% 50%) 50% / 14px 14px}
.logo-current .btn{margin-left:auto}
.logo-preview{display:flex;align-items:center;gap:18px;flex-wrap:wrap;padding:14px 26px;min-height:62px;
  border:1px solid var(--border);border-radius:12px;
  background:linear-gradient(135deg,rgba(30,40,70,.5),rgba(20,28,50,.3)),var(--bg-deep)}
.logo-unsaved{color:var(--warn);font-weight:600}

/* ══ a persona's storage ═══════════════════════════════════════════════════
   One bar: what each kind of thing takes of the allowance. Amber when nearly
   full, red when full — and the words say what to delete. */
.storage-line{margin-top:6px;font-size:1rem;color:var(--text-secondary)}
.storage-line b{color:var(--text-primary)}
.storage-bar{display:flex;height:12px;margin:14px 0 10px;border-radius:999px;overflow:hidden;
  background:var(--bg-surface);border:1px solid var(--border)}
.storage-bar span{display:block;height:100%;min-width:2px}
.sb-presentations{background:var(--accent)}
.sb-videos{background:#8a6ae0}
.sb-knowledge{background:var(--ok)}
.sb-other{background:rgba(160,175,200,.55)}
.storage-legend{display:flex;gap:16px;flex-wrap:wrap}
.storage-legend span{display:inline-flex;align-items:center;gap:6px}
.storage-legend i{display:inline-block;width:10px;height:10px;border-radius:3px}
.storage-warn{color:var(--warn);font-weight:600}
.storage-card.near{border-color:rgba(216,163,74,.45)}
.storage-card.full{border-color:rgba(216,74,74,.55)}
.storage-card.full .storage-warn{color:var(--danger)}
.fleet-store{white-space:nowrap}
.fleet-store .bar{display:block;width:120px;height:6px;margin-top:5px;border-radius:999px;
  background:var(--bg-surface);overflow:hidden}
.fleet-store .bar i{display:block;height:100%;background:var(--accent)}
.fleet-store.near .bar i{background:var(--warn)}
.fleet-store.full .bar i{background:var(--danger)}
.linkish{background:none;border:0;padding:0;font:inherit;color:var(--accent);cursor:pointer;
  text-decoration:underline dotted;text-underline-offset:3px}
