/* ng-chat-vnext.css — CHAT-VNEXT turn anatomy + Tron glass (2026-09-05).
   Neural AURA canon: var(--x-cyan, #37e8ff)/var(--x-cyan, #00e5ff) cyan, var(--x-violet, #8f6dff)/var(--x-violet, #9b6bff) violet, var(--x-red, #ff5d5d)
   red, deep-space neutrals. One accent per lane; glass bubbles; animated
   gradient border ONLY on the live streaming bubble; reduced-motion honored.
   Loads AFTER ng-v8/ng-v9 + inline styles — overrides are deliberate. */

/* ---------- assistant turn anatomy: avatar rail + glass bubble ---------- */
.msg-assistant{
  position:relative;
  border-left:0!important;border-image:none!important;
  padding:0 0 0 46px;min-height:38px;
  /* 2026-09-05 the operator: "crowded" — clear air between turns; the glass panel
     insets -10px, so real separation needs real margin. */
  margin:26px 0 16px;
  /* flex-shrink:0 is load-bearing: #stream is an overflow flex column, and an
     explicit min-height replaces min-height:auto — without this the items
     squash to min-height and the text overlaps (caught in verify, 2026-09-05) */
  flex-shrink:0;
}
.ngx-av{position:absolute;left:0;top:2px;width:34px;height:34px;pointer-events:none}
.ngx-av svg{width:34px;height:34px;overflow:visible;filter:drop-shadow(0 0 6px color-mix(in srgb, var(--x-cyan, #37e8ff) 35%, transparent))}
/* BASTION-fallback stream state: beacon + dashes wake while the turn is live */
/* CALM GLOW 2026-09-06: avatar accents breathe with the bubble (5s), not against it */
.ngx-av svg.s-stream .beacon{animation:ngx-beacon 5s ease-in-out infinite}
.ngx-av svg.s-stream .dash{stroke-dasharray:10 14;animation:ngx-dash 3.2s linear infinite}
.ngx-av svg.s-stream .dash2{stroke-dasharray:8 18;animation:ngx-dash 4.8s linear infinite reverse}
/* BIT speak state: voice-light seam glow (seam markup lives in sp-bit.svg) */
.ngx-av svg.m-speak{filter:drop-shadow(0 0 9px color-mix(in srgb, var(--x-cyan, #37e8ff) 60%, transparent))}
@keyframes ngx-beacon{0%,100%{opacity:.6}50%{opacity:.95}}
@keyframes ngx-dash{to{stroke-dashoffset:-24}}

/* glass panel behind the assistant content (excludes the avatar column) */
.msg-assistant::before{
  content:"";position:absolute;inset:-10px -14px -8px 34px;z-index:0;
  border-radius:16px;
  background:linear-gradient(160deg,color-mix(in srgb, var(--s2, #0a1426) 58%, transparent),color-mix(in srgb, var(--s1, #060c18) 42%, transparent));
  border:1px solid color-mix(in srgb, var(--x-cyan, #37e8ff) 14%, transparent);
  box-shadow:inset 0 1px 0 color-mix(in srgb, var(--t0, #eaf6ff) 5%, transparent),0 6px 22px rgba(0,0,0,.28);
  -webkit-backdrop-filter:blur(14px) saturate(150%);backdrop-filter:blur(14px) saturate(150%);
  pointer-events:none;
}
.msg-assistant>*{position:relative;z-index:1}
.msg-assistant>.ngx-av{position:absolute;z-index:2}   /* re-assert over the >* rule */

/* RING-ONLY 2026-09-06 pm (the operator: "rings about the circle doing some tracing
   are fine, just don't need the whole chat glowing -- cool but not distracting"):
   the box-wide conic ring + drop-shadows are gone. A live bubble is marked by a
   slightly brighter static panel border; all motion lives on the emblem circle
   (beacon/dash tracing, orbit) and the small inline spinner. */
.msg-assistant.lane-running::before{border-color:color-mix(in srgb, var(--x-cyan, #37e8ff) 24%, transparent)}
.msg-assistant.lane-err::before{border-color:color-mix(in srgb, var(--x-red, #ff5d5d) 30%, transparent)}

/* user bubble: same glass family, blue-shifted, right-aligned as before */
.msg-user,.msg.msg-user{margin:22px 0 6px}
.msg-bubble{
  background:linear-gradient(150deg,color-mix(in srgb, var(--x-blue, #00b4ff) 14%, transparent),color-mix(in srgb, var(--x-cyan, #00e5ff) 5%, transparent));
  border:1px solid color-mix(in srgb, var(--x-blue, #00b4ff) 30%, transparent);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  box-shadow:0 0 18px color-mix(in srgb, var(--x-blue, #00b4ff) 10%, transparent);
  font:430 15px/1.5 var(--fu);
}

/* ---------- typography: readable prose ---------- */
.msg-text{font:400 15px/1.55 var(--fu);color:var(--t1);max-width:72ch}
.msg-text.ngmd{white-space:normal}   /* real block layout, not <br> soup */
.ngmd p{margin:.6em 0}
.ngmd p:first-child{margin-top:0}
.ngmd p:last-child{margin-bottom:0}
.ngmd h1,.ngmd h2,.ngmd h3,.ngmd h4{color:var(--t0);line-height:1.3;margin:1em 0 .4em;font-weight:620}
.ngmd h1{font-size:1.35em}.ngmd h2{font-size:1.22em}.ngmd h3{font-size:1.1em}
.ngmd h4,.ngmd h5,.ngmd h6{font-size:1em;letter-spacing:.02em}
.ngmd h1:first-child,.ngmd h2:first-child,.ngmd h3:first-child{margin-top:.1em}
.ngmd ul,.ngmd ol{margin:.5em 0;padding-left:1.5em}
.ngmd li{margin:.28em 0}
.ngmd li::marker{color:var(--x-cyan)}
.ngmd blockquote{margin:.7em 0;padding:.35em 0 .35em 12px;border-left:2px solid var(--x-violet);
  color:var(--t2);background:color-mix(in srgb, var(--x-violet, #8f6dff) 6%, transparent);border-radius:0 8px 8px 0}
.ngmd hr{border:0;height:1px;margin:14px 0;
  background:linear-gradient(90deg,transparent,color-mix(in srgb, var(--x-cyan, #37e8ff) 35%, transparent),transparent)}
.ngmd b,.ngmd strong{color:var(--x-cyan);font-weight:560}
.ngmd em{color:var(--t0)}
.ngmd a.md-link{color:var(--x-cyan);text-decoration:none;border-bottom:1px solid color-mix(in srgb, var(--x-cyan, #00e5ff) 35%, transparent)}
.ngmd a.md-link:hover{border-bottom-color:var(--x-cyan);text-shadow:0 0 8px color-mix(in srgb, var(--x-cyan, #00e5ff) 50%, transparent)}
.ngmd code:not(pre code){font:12.5px/1.4 var(--fm,ui-monospace,monospace);color:var(--x-mint);
  background:color-mix(in srgb, var(--x-mint, #00ffc8) 8%, transparent);border:1px solid color-mix(in srgb, var(--x-mint, #00ffc8) 20%, transparent);border-radius:5px;padding:1px 5px}

/* jumbo: a message that is only 1-3 emoji */
.ngmd-jumbo p{font-size:2.4em;line-height:1.2;margin:.1em 0}

/* tables scroll INSIDE the bubble */
.ngmd .md-scroll{overflow-x:auto;max-width:100%;margin:9px 0;border:1px solid color-mix(in srgb, var(--x-cyan, #37e8ff) 14%, transparent);border-radius:10px}
.ngmd table.md-table{border-collapse:collapse;min-width:100%;font:400 12.5px/1.5 var(--fu);margin:0}
.ngmd .md-table th{font:620 9.5px/1.4 var(--fu);letter-spacing:.1em;text-transform:uppercase;color:var(--x-cyan);
  padding:7px 12px;border-bottom:1px solid var(--line2,#2a3242);white-space:nowrap;text-align:left;
  background:color-mix(in srgb, var(--x-cyan, #00e5ff) 6%, transparent)}
.ngmd .md-table td{padding:6px 12px;border-bottom:1px solid rgba(255,255,255,.06);color:var(--t1);vertical-align:top}
.ngmd .md-table tbody tr:last-child td{border-bottom:0}
.ngmd .md-table tbody tr:hover td{background:color-mix(in srgb, var(--x-cyan, #00e5ff) 5%, transparent)}

/* inline images / GIFs */
.ngmd img.md-img{max-height:240px;max-width:min(100%,340px);border-radius:10px;cursor:zoom-in;
  border:1px solid color-mix(in srgb, var(--x-cyan, #37e8ff) 18%, transparent);box-shadow:0 4px 16px rgba(0,0,0,.35);display:inline-block;vertical-align:middle}
#ngmd-lightbox{position:fixed;inset:0;z-index:9000;display:none;align-items:center;justify-content:center;
  background:color-mix(in srgb, var(--s0, #02060e) 86%, transparent);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);cursor:zoom-out}
#ngmd-lightbox.on{display:flex}
#ngmd-lightbox img{max-width:92vw;max-height:92vh;border-radius:12px;
  border:1px solid color-mix(in srgb, var(--x-cyan, #37e8ff) 35%, transparent);box-shadow:0 0 60px color-mix(in srgb, var(--x-cyan, #00e5ff) 25%, transparent)}

/* ---------- code blocks: header bar + highlight + collapse ---------- */
.ngmd .code-block{margin:10px 0;border:1px solid color-mix(in srgb, var(--x-cyan, #37e8ff) 16%, transparent);border-radius:10px;overflow:hidden;
  background:color-mix(in srgb, var(--s0, #02060e) 60%, transparent)}
.ngmd .code-bar{display:flex;justify-content:space-between;align-items:center;padding:5px 10px;
  border-bottom:1px solid color-mix(in srgb, var(--x-cyan, #37e8ff) 12%, transparent);font:620 9px/1 var(--fu);letter-spacing:.14em;
  color:var(--x-cyan);text-transform:uppercase;background:color-mix(in srgb, var(--x-cyan, #00e5ff) 5%, transparent)}
.ngmd .code-block pre{margin:0;padding:11px 12px;overflow:auto}
.ngmd .code-block code{font:12.5px/1.55 var(--fm,ui-monospace,SFMono-Regular,Menlo,monospace);
  color:var(--t1);white-space:pre;background:none;border:0;padding:0}
.ngmd .cb-expand{display:block;width:100%;background:color-mix(in srgb, var(--x-cyan, #00e5ff) 5%, transparent);border:0;
  border-top:1px solid color-mix(in srgb, var(--x-cyan, #37e8ff) 12%, transparent);color:var(--x-cyan);font:620 9px/1 var(--fu);
  letter-spacing:.12em;padding:7px;cursor:pointer}
.ngmd .cb-expand:hover{background:color-mix(in srgb, var(--x-cyan, #00e5ff) 12%, transparent)}
.ngmd .code-block.collapsed pre{max-height:calc(40 * 1.55 * 12.5px);overflow:hidden;
  -webkit-mask-image:linear-gradient(#000 82%,transparent);mask-image:linear-gradient(#000 82%,transparent)}
/* hljs → AURA palette */
.ngmd .hljs-comment,.ngmd .hljs-quote{color:var(--t3);font-style:italic}
.ngmd .hljs-string,.ngmd .hljs-regexp,.ngmd .hljs-addition{color:var(--x-mint)}
.ngmd .hljs-number,.ngmd .hljs-literal,.ngmd .hljs-symbol{color:var(--x-violet)}
.ngmd .hljs-keyword,.ngmd .hljs-selector-tag,.ngmd .hljs-tag,.ngmd .hljs-name{color:var(--x-cyan)}
.ngmd .hljs-title,.ngmd .hljs-section,.ngmd .hljs-function,.ngmd .hljs-built_in{color:var(--x-amber, #d9a53f)}
.ngmd .hljs-attr,.ngmd .hljs-attribute,.ngmd .hljs-variable,.ngmd .hljs-template-variable{color:var(--x-blue, #7fd4ff)}
.ngmd .hljs-deletion{color:var(--x-red,#ff5d5d)}
.ngmd .hljs-meta{color:var(--t2)}
.ngmd .hljs-emphasis{font-style:italic}.ngmd .hljs-strong{font-weight:600}

/* ---------- meta + footer rows, status chips ---------- */
.msg-assistant .msg-meta{font:500 10px/1.6 var(--fm,monospace);letter-spacing:.08em;color:var(--t3);opacity:.85}
.msg-actions{opacity:.5;transition:opacity .2s}
.msg:hover .msg-actions{opacity:1}
.cc-chip{opacity:.6;font-size:10px}
.cc-note{opacity:.6}

/* ---------- streaming polish ---------- */
/* skeleton shimmer before the first token (empty live msg-text) */
.msg-assistant.lane-running .msg-text:empty{min-height:30px}
.msg-assistant.lane-running .msg-text:empty::before,
.msg-assistant.lane-running .msg-text:empty::after{
  content:"";display:block;height:11px;border-radius:6px;margin:4px 0;
  background:linear-gradient(90deg,color-mix(in srgb, var(--x-cyan, #37e8ff) 5%, transparent) 25%,color-mix(in srgb, var(--x-cyan, #37e8ff) 20%, transparent) 50%,color-mix(in srgb, var(--x-cyan, #37e8ff) 5%, transparent) 75%);
  background-size:200% 100%;animation:ngx-shimmer 1.3s linear infinite;
}
.msg-assistant.lane-running .msg-text:empty::before{width:min(72%,420px)}
.msg-assistant.lane-running .msg-text:empty::after{width:min(46%,280px);animation-delay:.25s}
@keyframes ngx-shimmer{to{background-position:-200% 0}}

/* "↓ new tokens" pill (anchored-scroll escape hatch) */
#ngx-newtok{
  position:absolute;left:50%;bottom:86px;transform:translateX(-50%);z-index:40;
  background:color-mix(in srgb, var(--s1, #050f1c) 90%, transparent);border:1px solid color-mix(in srgb, var(--x-cyan, #00e5ff) 50%, transparent);border-radius:999px;
  color:var(--x-cyan);font:620 10px/1 var(--fu);letter-spacing:.12em;padding:8px 16px;cursor:pointer;
  box-shadow:0 0 18px color-mix(in srgb, var(--x-cyan, #00e5ff) 30%, transparent);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  animation:ngx-pill-in .18s ease-out;
}
#ngx-newtok:hover{background:color-mix(in srgb, var(--x-cyan, #00e5ff) 14%, transparent)}
@keyframes ngx-pill-in{from{opacity:0;transform:translate(-50%,6px)}to{opacity:1;transform:translate(-50%,0)}}

/* ---------- composer: emoji + GIF buttons and panels ---------- */
/* .msg-assistant>* carries z-index:1; without a z-index of its own the
   composer (z auto) would paint UNDER message text — and so would the emoji/
   GIF panels inside it (caught in verify, 2026-09-05). */
.composer{z-index:6}

.ngx-emo-btn,.ngx-gif-btn{
  width:34px;height:34px;flex:none;display:grid;place-items:center;position:relative;
  background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.14);border-radius:var(--r1,8px);
  color:var(--t2);cursor:pointer;font:620 10px/1 var(--fu);transition:border-color .15s,box-shadow .15s;
}
.ngx-emo-btn{font-size:16px}
.ngx-emo-btn:hover,.ngx-gif-btn:hover{border-color:color-mix(in srgb, var(--x-cyan, #00e5ff) 50%, transparent);box-shadow:0 0 12px color-mix(in srgb, var(--x-cyan, #00e5ff) 25%, transparent);color:var(--x-cyan)}

.ngx-emo-panel,.ngx-gif-panel{
  position:absolute;right:0;bottom:calc(100% + 10px);z-index:60;
  width:min(360px,92vw);max-height:min(420px,60vh);display:flex;flex-direction:column;
  background:color-mix(in srgb, var(--s1, #060d1a) 94%, transparent);border:1px solid color-mix(in srgb, var(--x-cyan, #37e8ff) 25%, transparent);border-radius:14px;
  box-shadow:0 12px 40px rgba(0,0,0,.5),0 0 24px color-mix(in srgb, var(--x-cyan, #00e5ff) 12%, transparent);
  -webkit-backdrop-filter:blur(18px) saturate(160%);backdrop-filter:blur(18px) saturate(160%);
  overflow:hidden;animation:ngx-pill-in .15s ease-out;
}
.ngx-emo-top{padding:8px 8px 0}
.ngx-emo-search{width:100%;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.12);
  border-radius:8px;color:var(--t0);font:430 12px/1.4 var(--fu);padding:7px 10px;outline:0}
.ngx-emo-search:focus{border-color:color-mix(in srgb, var(--x-cyan, #00e5ff) 45%, transparent)}
.ngx-emo-tabs{display:flex;gap:2px;padding:6px 8px;border-bottom:1px solid rgba(255,255,255,.07)}
.ngx-emo-tabs button{flex:1;background:none;border:0;border-radius:7px;font-size:14px;padding:4px 0;
  cursor:pointer;opacity:.55;transition:opacity .12s,background .12s}
.ngx-emo-tabs button:hover{opacity:1}
.ngx-emo-tabs button.on{opacity:1;background:color-mix(in srgb, var(--x-cyan, #00e5ff) 12%, transparent)}
.ngx-emo-grid{flex:1;overflow-y:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(34px,1fr));
  gap:2px;padding:8px}
.ngx-emo-grid button{background:none;border:0;border-radius:7px;font-size:20px;line-height:1.5;
  cursor:pointer;padding:2px 0;transition:background .1s,transform .1s}
.ngx-emo-grid button:hover{background:color-mix(in srgb, var(--x-cyan, #00e5ff) 14%, transparent);transform:scale(1.18)}
.ngx-emo-empty,.ngx-gif-empty{grid-column:1/-1;text-align:center;color:var(--t3);
  font:500 11px/1.6 var(--fm,monospace);letter-spacing:.08em;padding:22px 10px}

.ngx-emo-strip{position:absolute;left:12px;bottom:calc(100% + 10px);z-index:61;display:flex;gap:4px;
  max-width:92vw;overflow-x:auto;background:color-mix(in srgb, var(--s1, #060d1a) 94%, transparent);border:1px solid color-mix(in srgb, var(--x-cyan, #37e8ff) 25%, transparent);
  border-radius:10px;padding:5px;box-shadow:0 8px 24px rgba(0,0,0,.45);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
.ngx-emo-strip button{background:none;border:1px solid transparent;border-radius:7px;
  color:var(--t1);font:500 12px/1.5 var(--fm,monospace);padding:4px 8px;cursor:pointer;white-space:nowrap}
.ngx-emo-strip button.on{border-color:color-mix(in srgb, var(--x-cyan, #00e5ff) 50%, transparent);background:color-mix(in srgb, var(--x-cyan, #00e5ff) 12%, transparent);color:var(--x-cyan)}

.ngx-gif-top{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:9px 10px;border-bottom:1px solid rgba(255,255,255,.07)}
.ngx-gif-ttl{font:620 9px/1 var(--fm,monospace);letter-spacing:.16em;color:var(--x-cyan)}
.ngx-gif-up{background:color-mix(in srgb, var(--x-cyan, #00e5ff) 8%, transparent);border:1px solid color-mix(in srgb, var(--x-cyan, #00e5ff) 40%, transparent);border-radius:7px;
  color:var(--x-cyan);font:620 9px/1 var(--fu);letter-spacing:.12em;padding:5px 10px;cursor:pointer}
.ngx-gif-up:hover{background:color-mix(in srgb, var(--x-cyan, #00e5ff) 18%, transparent)}
.ngx-gif-note{font:500 10px/1.5 var(--fm,monospace);color:var(--x-amber,#d9a53f);padding:0 10px}
.ngx-gif-note:empty{display:none}
.ngx-gif-grid{flex:1;overflow-y:auto;display:grid;grid-template-columns:repeat(3,1fr);gap:6px;padding:10px}
.ngx-gif-cell{background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.1);border-radius:9px;
  padding:0;overflow:hidden;cursor:pointer;aspect-ratio:4/3;transition:border-color .12s,box-shadow .12s}
.ngx-gif-cell img{width:100%;height:100%;object-fit:cover;display:block}
.ngx-gif-cell:hover{border-color:color-mix(in srgb, var(--x-cyan, #00e5ff) 55%, transparent);box-shadow:0 0 14px color-mix(in srgb, var(--x-cyan, #00e5ff) 30%, transparent)}
.ngx-gif-panel.drop{border-color:var(--x-mint,#00ffc8);box-shadow:0 0 24px color-mix(in srgb, var(--x-mint, #00ffc8) 35%, transparent)}

/* ---------- identity split (2026-09-05): VIGIL badge + E-STOP mark ---------- */
/* 2026-09-05 the operator: the owl must LOOK GREAT everywhere. The statusbar clips
   vertical overflow, so VIGIL sizes to the bar (never negative margins) and the
   lockup centers it. Hot enough to read on deep-navy at every size. */
.sb-mark{display:flex;align-items:center;gap:10px}
.sb-vigil{height:34px;width:auto;display:block;
  filter:brightness(2.4) saturate(1.5) drop-shadow(0 0 9px color-mix(in srgb, var(--x-cyan, #00e5ff) 85%, transparent));
  animation:ngx-vigil-breathe 5s ease-in-out infinite}
@keyframes ngx-vigil-breathe{50%{filter:brightness(2.0) saturate(1.4) drop-shadow(0 0 5px color-mix(in srgb, var(--x-cyan, #00e5ff) 50%, transparent))}}
@media (prefers-reduced-motion:reduce){.sb-vigil{animation:none}}
/* tablet: a touch smaller, still glowing */
@media (max-width:1024px){.sb-vigil{height:30px}}
/* phone: the owl IS the brand mark — keep it, let text truncate instead */
@media (max-width:640px){
  .sb-vigil{height:28px;filter:brightness(2.6) saturate(1.5) drop-shadow(0 0 7px color-mix(in srgb, var(--x-cyan, #00e5ff) 90%, transparent))}
  .sb-mark{gap:7px;min-width:0}
}
#ngx-estop-mark{display:inline-flex;width:30px;height:30px;margin-right:2px;
  filter:drop-shadow(0 0 8px color-mix(in srgb, var(--x-red, #ff5d5d) 60%, transparent));animation:none}
#ngx-estop-mark svg{width:30px;height:30px;overflow:visible}
/* .estop-red treatment: red edges (var(--x-red, #ff5d5d)), every animation stopped */
svg.estop-red *{animation:none!important;transition:none!important}
svg.estop-red .ngx-eb .redl{opacity:1!important}
svg.estop-red .ngx-eb .cy,svg.estop-red .ngx-eb .vio,
svg.estop-red .ngx-eb .dash,svg.estop-red .ngx-eb .dash2{opacity:0!important}
svg.estop-red .ngx-ebit{opacity:.35;filter:saturate(.3)}
body.ngx-estop .sb-health .micro-label{color:var(--x-red,#ff5d5d)}
body.ngx-estop .sb-health .dot{background:var(--x-red,#ff5d5d);box-shadow:0 0 8px color-mix(in srgb, var(--x-red, #ff5d5d) 70%, transparent);animation:none}

/* BIT avatar states beyond speak (consumer-owned per sp-bit.svg contract) */
.ngx-av svg.m-work .orbit circle{fill:var(--x-violet, #8f6dff)}
.ngx-av svg:not(.m-speak) .voice{opacity:0}
.ngx-av svg.m-speak .voice{opacity:1;animation:ngx-voice 1s ease-in-out infinite}
.ngx-av svg.m-speak .orbit{animation:ngx-orbit 2.6s linear infinite;transform-origin:0 0}
@keyframes ngx-voice{0%,100%{transform:scaleY(.55)}50%{transform:scaleY(1)}}
@keyframes ngx-orbit{to{transform:rotate(360deg)}}

/* ---------- motion discipline ---------- */
@media (prefers-reduced-motion:reduce){
  .msg-assistant.lane-running .msg-text:empty::before,
  .msg-assistant.lane-running .msg-text:empty::after{animation:none}
  .ngx-av svg.s-stream .beacon,.ngx-av svg.s-stream .dash,.ngx-av svg.s-stream .dash2{animation:none}
  .ngx-av svg.m-speak .voice,.ngx-av svg.m-speak .orbit{animation:none}
  #ngx-newtok{animation:none}
}

/* mobile: avatar rail shrinks, panels go full-width-ish */
@media (max-width:640px){
  .msg-assistant{padding-left:36px}
  .ngx-av,.ngx-av svg{width:26px;height:26px}
  .msg-assistant::before{inset:-8px -10px -6px 26px}
  .ngx-emo-panel,.ngx-gif-panel{right:-6px;width:min(340px,94vw)}
}

/* ---------- MOBILE PICKER DISMISS (2026-09-05) --------------------------
   iOS could OPEN the emoji/GIF pickers but not close them (document `click`
   never fires for taps on non-interactive elements; Escape needs a keyboard).
   ng-emoji/ng-gif now add a .ngx-pick-close ✕ and a pointerdown outside-
   dismiss; these style the ✕ (44px thumb target on phones) plus the new GIF
   name filter, and keep the picker search inputs at 16px on phones so iOS
   does not zoom the page on focus. */
.ngx-emo-top{display:flex;gap:8px;align-items:center}
.ngx-emo-search{flex:1 1 auto;width:auto}
.ngx-pick-close{flex:0 0 auto;min-width:34px;min-height:34px;background:color-mix(in srgb, var(--x-red, #ff5470) 8%, transparent);
  border:1px solid color-mix(in srgb, var(--x-red, #ff5470) 40%, transparent);border-radius:8px;color:var(--x-red, #ff5470);
  font:700 13px/1 var(--fm,monospace);cursor:pointer;-webkit-tap-highlight-color:transparent}
.ngx-pick-close:hover{background:color-mix(in srgb, var(--x-red, #ff5470) 18%, transparent)}
.ngx-gif-filter{flex:1 1 60px;min-width:0;background:rgba(255,255,255,.05);
  border:1px solid rgba(255,255,255,.12);border-radius:8px;color:var(--t0);
  font:430 12px/1.4 var(--fu);padding:6px 9px;outline:0}
.ngx-gif-filter:focus{border-color:color-mix(in srgb, var(--x-cyan, #00e5ff) 45%, transparent)}
@media (max-width:600px){
  .ngx-emo-search,.ngx-gif-filter{font-size:16px}
  .ngx-pick-close{min-width:44px;min-height:44px}
}
/* THE actual close bug: these panels set display:flex in author origin, which
   beats the UA [hidden] rule (same scar as .act-btn, mockup-v11.html ~1820) —
   so panel.hidden=true dismissed NOTHING on any input method. */
.ngx-emo-panel[hidden],.ngx-gif-panel[hidden]{display:none!important}
