/*!
 * OpsIQ — Universal AI Platform
 * Copyright (c) 2026 Nabtech Digitalnet Limited. All rights reserved.
 * Proprietary — Commercial Licence (see LICENCE)
 *
 * PHASE_PORTAL_ASSISTANT — the portal-native AI answer assistant, as ONE module.
 *
 * Loaded by BOTH surfaces:
 *   portal.php  — alongside portal-core.css / portal-runtime.css
 *   help.php    — the /hc surface, which prints ONLY theme_css + chrome_css from the design
 *                 bundle and never loads the portal stylesheets. That is why this file exists:
 *                 the assistant could not appear on /hc while its CSS lived in portal-core.css,
 *                 and a second copy for /hc would be a dual-copy trap.
 *
 * Everything here is namespaced #px-ask-root / .pxa-* / .px-fab / body.pxf-*, so it cannot touch
 * the Help Centre's own design. It styles from the portal design TOKENS (--accent, --card, --ink,
 * --ink-2, --ink-3, --bg, --line, --ease, --accent-bg), all of which /hc already defines — they
 * are emitted by theme_css inside #px-unify. Verified live on /hc before this file was split out.
 */

/* ═══ PHASE_PORTAL_ASSISTANT — portal-native AI answer assistant (separate from the embed widget) ═══ */
#px-ask-root{--pxa:var(--accent);}
.pxa-launch{position:fixed;bottom:24px;z-index:75;display:inline-flex;align-items:center;gap:10px;cursor:pointer;border:none;
  background:linear-gradient(135deg,var(--pxa),color-mix(in srgb,var(--pxa) 78%,#000));color:#fff;font-family:inherit;font-weight:800;
  box-shadow:0 14px 34px -10px color-mix(in srgb,var(--pxa) 60%,transparent);transition:transform .18s,box-shadow .18s;animation:pxaPop .4s cubic-bezier(.2,.8,.3,1) both}
.pxa-launch:hover{transform:translateY(-2px);box-shadow:0 20px 42px -10px color-mix(in srgb,var(--pxa) 66%,transparent)}
.pxa-launch:focus-visible{outline:2px solid var(--pxa);outline-offset:3px}
.pxa-launch.pos-right{right:24px}.pxa-launch.pos-left{left:24px}
.pxa-launch.lc-bubble{width:52px;height:52px;border-radius:50%;justify-content:center;padding:0}
.pxa-launch.lc-bubble .pxa-lt{display:none}
.pxa-launch.lc-bar{padding:11px 18px;border-radius:999px;font-size:13.5px}
.pxa-launch.lc-tab{padding:10px 15px;border-radius:14px 14px 0 0;bottom:0;font-size:13.5px}
.pxa-launch svg{width:22px;height:22px;flex-shrink:0}
.pxa-badge{position:absolute;top:-4px;right:-4px;min-width:20px;height:20px;padding:0 5px;border-radius:999px;background:#ef4444;color:#fff;font-size:11.5px;font-weight:900;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 6px rgba(0,0,0,.3);border:2px solid var(--card)}
.pxa-badge[hidden]{display:none}
.pxa-launch.lc-bubble{position:fixed}
@keyframes pxaPop{from{opacity:0;transform:scale(.6) translateY(10px)}to{opacity:1;transform:none}}
.pxa-panel{position:fixed;bottom:24px;z-index:76;width:390px;max-width:calc(100vw - 32px);height:600px;max-height:calc(100vh - 48px);
  background:var(--card);border:1px solid var(--line);border-radius:20px;box-shadow:0 30px 80px -20px rgba(2,6,23,.55);
  display:none;flex-direction:column;overflow:hidden;animation:pxaUp .28s cubic-bezier(.2,.8,.3,1)}
.pxa-panel.pos-right{right:24px}.pxa-panel.pos-left{left:24px}
.pxa-panel.open{display:flex}
@keyframes pxaUp{from{opacity:0;transform:translateY(16px) scale(.98)}to{opacity:1;transform:none}}
.pxa-head{display:flex;align-items:center;gap:11px;padding:15px 16px;color:#fff;
  background:linear-gradient(135deg,var(--pxa),color-mix(in srgb,var(--pxa) 76%,#000))}
.pxa-head .pxa-ava{width:34px;height:34px;border-radius:11px;background:rgba(255,255,255,.18);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.pxa-head .pxa-ava svg{width:19px;height:19px}
.pxa-head .pxa-hn{font-weight:800;font-size:14.5px;line-height:1.2}
.pxa-head .pxa-hs{font-size:11.5px;opacity:.85;margin-top:1px}
.pxa-head .pxa-x{margin-inline-start:auto;background:rgba(255,255,255,.16);border:none;color:#fff;width:30px;height:30px;border-radius:9px;cursor:pointer;font-size:15px;line-height:1}
.pxa-head .pxa-x:hover{background:rgba(255,255,255,.28)}
.pxa-body{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px;background:var(--bg)}
.pxa-msg{max-width:88%;padding:11px 14px;border-radius:15px;font-size:13.5px;line-height:1.55;white-space:pre-wrap;word-wrap:break-word}
.pxa-msg.me{align-self:flex-end;background:var(--pxa);color:#fff;border-bottom-right-radius:5px}
.pxa-msg.ai{align-self:flex-start;background:var(--card);color:var(--ink);border:1px solid var(--line);border-bottom-left-radius:5px}
.pxa-msg.ai a{color:var(--pxa);font-weight:600}
.pxa-cards{align-self:flex-start;max-width:92%;display:flex;flex-direction:column;gap:7px}
.pxa-card{display:block;text-decoration:none;padding:10px 12px;border:1px solid var(--line);border-radius:12px;background:var(--card);transition:.15s}
.pxa-card:hover{border-color:var(--pxa);transform:translateY(-1px)}
.pxa-card .pc-t{font-size:12.7px;font-weight:700;color:var(--ink);display:flex;align-items:center;gap:6px}
.pxa-card .pc-t svg{width:14px;height:14px;color:var(--pxa);flex-shrink:0}
.pxa-card .pc-e{font-size:11.5px;color:var(--ink-2);margin-top:2px;line-height:1.45}
.pxa-sugg{display:flex;flex-wrap:wrap;gap:7px;align-self:flex-start;max-width:92%}
.pxa-chip{border:1px solid var(--line);background:var(--card);color:var(--ink);border-radius:999px;padding:7px 13px;font-size:12.5px;font-weight:600;cursor:pointer;font-family:inherit;transition:.15s}
.pxa-chip:hover{border-color:var(--pxa);color:var(--pxa)}
.pxa-deflect{align-self:flex-start;margin-top:2px;display:flex;gap:8px;flex-wrap:wrap}
.pxa-deflect button{border:none;background:var(--pxa);color:#fff;border-radius:11px;padding:10px 16px;font-weight:800;font-size:12.5px;cursor:pointer;font-family:inherit}
.pxa-deflect button.pxa-act-ghost{background:transparent;color:var(--pxa);border:1px solid color-mix(in srgb,var(--pxa) 40%,var(--line))}
/* PHASE_PORTAL_LIVECHAT — live conversation states */
.pxa-head.pxa-live-head .pxa-ava{background:rgba(255,255,255,.22)}
.pxa-livedot{display:inline-block;width:7px;height:7px;border-radius:50%;background:#34d399;margin-right:6px;box-shadow:0 0 0 0 rgba(52,211,153,.6);animation:pxaPulse 1.8s infinite}
@keyframes pxaPulse{0%{box-shadow:0 0 0 0 rgba(52,211,153,.55)}70%{box-shadow:0 0 0 6px rgba(52,211,153,0)}100%{box-shadow:0 0 0 0 rgba(52,211,153,0)}}
.pxa-sys{align-self:center;max-width:90%;text-align:center;font-size:11.5px;color:var(--ink-3);background:color-mix(in srgb,var(--ink) 5%,transparent);padding:6px 12px;border-radius:999px}
.pxa-agentmsg{align-self:flex-start;max-width:88%;display:flex;flex-direction:column;gap:3px}
.pxa-agent-n{font-size:10.5px;font-weight:800;color:var(--ink-2);text-transform:uppercase;letter-spacing:.4px;padding-left:4px}
.pxa-emrow{align-self:stretch;display:flex;gap:8px;margin-top:2px}
.pxa-em{flex:1;border:1px solid var(--line);border-radius:11px;padding:10px 12px;font-size:13.5px;font-family:inherit;background:var(--bg);color:var(--ink)}
.pxa-em:focus{outline:none;border-color:var(--pxa)}
.pxa-emgo{border:none;background:var(--pxa);color:#fff;border-radius:11px;padding:0 16px;font-weight:800;font-size:12.5px;cursor:pointer;font-family:inherit;white-space:nowrap}
.pxa-typing{align-self:flex-start;display:inline-flex;gap:4px;padding:12px 15px;background:var(--card);border:1px solid var(--line);border-radius:15px}
.pxa-typing span{width:7px;height:7px;border-radius:50%;background:var(--ink-3);animation:pxaBlink 1.2s infinite}
.pxa-typing span:nth-child(2){animation-delay:.2s}.pxa-typing span:nth-child(3){animation-delay:.4s}
@keyframes pxaBlink{0%,60%,100%{opacity:.3}30%{opacity:1}}
.pxa-foot{border-top:1px solid var(--line);padding:12px 14px;background:var(--card)}
.pxa-inrow{display:flex;gap:8px;align-items:flex-end}
.pxa-in{flex:1;border:1px solid var(--line);border-radius:12px;padding:10px 12px;font-size:13.5px;font-family:inherit;background:var(--bg);color:var(--ink);resize:none;max-height:110px;line-height:1.4}
.pxa-in:focus{outline:none;border-color:var(--pxa)}
.pxa-send{border:none;background:var(--pxa);color:#fff;width:40px;height:40px;border-radius:11px;cursor:pointer;flex-shrink:0;display:flex;align-items:center;justify-content:center}
.pxa-send:disabled{opacity:.5;cursor:default}
.pxa-send svg{width:19px;height:19px}
.pxa-note{text-align:center;font-size:10.5px;color:var(--ink-3);margin-top:8px}
@media (max-width:480px){ .pxa-panel{width:100vw;max-width:100vw;height:100vh;max-height:100vh;bottom:0;right:0;left:0;border-radius:0} }
@media(prefers-reduced-motion:reduce){.pxa-launch,.pxa-panel{animation:none}}
/* ══════════════════════════════════════════════════════════════════════════════════════════
   PHASE_PORTAL_FLOAT_ANCHORS — six anchors + auto-stacking for floating controls.

   Measured collision on defaults: the assistant launcher (z-index 75) sat at 1349→1401 directly
   over the reply FAB (z-index 70) at 1251→1401, hiding its right end so "Send reply" read as
   "Send r…", with the reCAPTCHA badge underneath both. Three independent things claimed one
   corner and none of them knew the others existed.

   Two parts:
   1. ANCHORS — bottom/middle/top × left/right, for the assistant and the reply FAB alike.
   2. AUTO-STACK — --pxf-slot is set per element by pxStackFloats(); each control shifts along
      its own axis by slot × step, so whatever combination of anchors the operator picks, two
      controls sharing one anchor can never sit on top of each other.
   ══════════════════════════════════════════════════════════════════════════════════════════ */
.px-fab, .pxa-launch{
  --pxf-slot:0;                 /* stacking index within this anchor, set from JS */
  --pxf-base:0px;               /* exact px a FOREIGN launcher (the chat widget) needs, from JS */
  --pxf-step:62px;              /* one control's height plus breathing room */
  --pxf-edge:24px;
}
/* ── BOTTOM ── stack upward, away from the edge. */
.px-fab.fab-bottom-right,.pxa-launch.pos-bottom-right,
.px-fab.fab-right,.pxa-launch.pos-right{
  right:var(--pxf-edge);left:auto;top:auto;
  bottom:calc(var(--pxf-edge) + var(--pxf-base,0px) + (var(--pxf-slot) * var(--pxf-step)));
}
.px-fab.fab-bottom-left,.pxa-launch.pos-bottom-left,
.px-fab.fab-left,.pxa-launch.pos-left{
  left:var(--pxf-edge);right:auto;top:auto;
  bottom:calc(var(--pxf-edge) + var(--pxf-base,0px) + (var(--pxf-slot) * var(--pxf-step)));
}
/* ── TOP ── stack downward. The nav is sticky at z-50, so these sit clear of it. */
.px-fab.fab-top-right,.pxa-launch.pos-top-right{
  right:var(--pxf-edge);left:auto;bottom:auto;
  top:calc(88px + (var(--pxf-slot) * var(--pxf-step)));
}
.px-fab.fab-top-left,.pxa-launch.pos-top-left{
  left:var(--pxf-edge);right:auto;bottom:auto;
  top:calc(88px + (var(--pxf-slot) * var(--pxf-step)));
}
/* ── MIDDLE ── vertically centred, stacking downward from centre. translate does the centring,
   so hover must re-declare it or the control jumps on hover. */
.px-fab.fab-middle-right,.pxa-launch.pos-middle-right{
  right:var(--pxf-edge);left:auto;bottom:auto;
  top:50%;translate:0 calc(-50% + (var(--pxf-slot) * var(--pxf-step)));
}
.px-fab.fab-middle-left,.pxa-launch.pos-middle-left{
  left:var(--pxf-edge);right:auto;bottom:auto;
  top:50%;translate:0 calc(-50% + (var(--pxf-slot) * var(--pxf-step)));
}
/* transform is already used for the lift on hover, so the middle anchors centre with `translate`
   (a separate property) instead — otherwise the two fight and the control snaps to the edge. */

/* ── BOTTOM-CENTRE — kept from the original fab-center, now stack-aware.
   ⚠ `.px-fab` carries `animation:pxFabIn … both`, and that keyframe ends on `transform:none`.
   A filled animation beats a normal declaration, so the original `transform:translateX(-50%)`
   never survived the entry animation — measured left edge sat at 50% of the viewport instead of
   centred. Centring here uses the separate `translate` property, which the animation never
   touches, and it also leaves `transform` free for the hover lift. */
.px-fab.fab-bottom-center,.px-fab.fab-center{
  left:50%;right:auto;top:auto;
  bottom:calc(var(--pxf-edge) + var(--pxf-base,0px) + (var(--pxf-slot) * var(--pxf-step)));
  translate:-50% 0;transform:none;
}
/* The assistant launcher has no centre anchor in the schema, but a stored value could still
   normalise to one — without this it would land with left/right both auto, i.e. off-anchor. */
.pxa-launch.pos-bottom-center{
  left:50%;right:auto;top:auto;
  bottom:calc(var(--pxf-edge) + var(--pxf-base,0px) + (var(--pxf-slot) * var(--pxf-step)));
  translate:-50% 0;
}

/* The reCAPTCHA badge is a third occupant of the bottom-right that we do not control. When
   anything of ours is anchored there, lift the badge clear rather than letting it sit under. */
body.pxf-br-busy .grecaptcha-badge{bottom:calc(var(--pxf-recap,86px))!important}

@media(max-width:600px){
  /* Tighter edges and a shorter step on a phone, where 62px per control eats the screen. */
  .px-fab,.pxa-launch{--pxf-edge:14px;--pxf-step:56px}
}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   PHASE_PORTAL_ASSISTANT_COMPOSER — one composer shell instead of two competing controls.

   Before: `.pxa-inrow` was a flex row holding a bordered textarea and a 40px square button side
   by side, so the writing area was 40px + 8px narrower than the panel and the two boxes read as
   unrelated widgets with two separate borders. Past the 110px cap the textarea also grew a native
   scrollbar inside a 390px panel.

   After: the SHELL carries the border and the focus ring, the textarea fills it edge to edge, and
   the send button sits inside the shell's bottom-right corner. Scrollbars are hidden on every
   engine — the field still scrolls once it hits its cap, it just does it silently.
   ══════════════════════════════════════════════════════════════════════════════════════════ */
.pxa-foot{padding:12px 12px 14px}
.pxa-inrow{
  position:relative;display:block;                 /* was a flex row — the shell is now one box */
  border:1.5px solid var(--line);border-radius:16px;background:var(--bg);
  transition:border-color .16s var(--ease,ease),box-shadow .16s var(--ease,ease);
}
.pxa-inrow:focus-within{
  border-color:var(--pxa);
  box-shadow:0 0 0 3.5px color-mix(in srgb,var(--pxa) 16%,transparent);
}
.pxa-in{
  display:block;width:100%;box-sizing:border-box;
  border:0;border-radius:16px;background:transparent;
  /* right padding reserves the send button's corner so the last line never runs underneath it */
  padding:12px 52px 12px 14px;
  font-size:13.5px;line-height:1.45;
  /* ⚠ portal-core.css carries a BARE `textarea{min-height:118px}` for the ticket compose form.
     It was landing on the assistant field too, which is why the composer sat five rows tall next
     to a 40px button and read as two unrelated boxes. Reset it and grow from one row instead. */
  min-height:44px;max-height:132px;
  scrollbar-width:none;-ms-overflow-style:none;    /* Firefox / legacy Edge */
}
.pxa-in::-webkit-scrollbar{width:0;height:0;display:none}   /* Chrome / Safari */
.pxa-in:focus{outline:none;border-color:transparent}         /* the shell owns the focus ring now */
.pxa-send{
  position:absolute;right:7px;bottom:7px;
  width:36px;height:36px;border-radius:12px;
  box-shadow:0 6px 16px -6px color-mix(in srgb,var(--pxa) 70%,transparent);
  transition:transform .14s var(--ease,ease),opacity .14s ease;
}
.pxa-send:hover:not(:disabled){transform:translateY(-1px) scale(1.04)}
.pxa-send:active:not(:disabled){transform:translateY(0) scale(.95)}
.pxa-send svg{width:17px;height:17px}
@media(max-width:480px){
  /* Full-screen panel on a phone: a slightly larger tap target, same shell. */
  .pxa-send{width:40px;height:40px;right:6px;bottom:6px}
  .pxa-in{padding-right:56px;font-size:15px}       /* 15px+ stops iOS zooming the panel on focus */
}

/* The "Showing results for …" line — a quiet note, not a message bubble, so it never reads as
   the assistant talking about the visitor's spelling. */
.pxa-corrected{
  align-self:center;max-width:92%;
  font-size:11.5px;font-weight:700;letter-spacing:.01em;
  color:var(--ink-3);opacity:.85;text-align:center;
  padding:2px 10px;border-radius:999px;background:color-mix(in srgb,var(--ink) 6%,transparent);
}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   PHASE_PORTAL_ASSISTANT_LAUNCHER — five launcher shapes, long-and-labelled by default.

   A 52px circle in the bottom-right corner is the universal signature of LIVE CHAT. On a portal
   that also runs the chat widget it is the same button twice, and neither one says which is which
   — while this control is something else again: it answers from the knowledge base and opens a
   request when it cannot. So the default now carries words.

   search (default) — reads as a search field: magnifier, label, and a hint of an input
   bar              — a solid pill with the label
   card             — two lines: what it is, and what it does
   tab              — docked to the very bottom edge
   bubble           — the plain circle, kept for anyone who wants it
   ══════════════════════════════════════════════════════════════════════════════════════════ */
.pxa-launch .pxa-lt{display:flex;flex-direction:column;align-items:flex-start;line-height:1.2;text-align:left}
.pxa-launch .pxa-ls{font-size:11px;font-weight:600;opacity:.82;letter-spacing:.01em}

/* ── SEARCH — the KB-native shape. Light surface, accent glyph, so it does not read as a second
   live-chat button even at a glance. */
.pxa-launch.lc-search{
  padding:0 6px 0 14px;height:50px;border-radius:999px;gap:9px;
  background:var(--card);color:var(--ink);
  border:1.5px solid color-mix(in srgb,var(--pxa) 26%,var(--line));
  box-shadow:0 14px 34px -14px rgba(2,6,23,.34),0 2px 6px rgba(2,6,23,.06);
  font-size:13.5px;font-weight:700;
}
.pxa-launch.lc-search svg{color:var(--pxa)}
.pxa-launch.lc-search .pxa-lt{color:color-mix(in srgb,var(--ink) 72%,transparent);font-weight:700}
/* The trailing accent chip is what makes it read as a field with an action, not a text pill.
   It carries an arrow: an empty coloured circle reads as a loading dot. */
.pxa-launch.lc-search::after{
  content:'\2192';width:38px;height:38px;border-radius:50%;flex:0 0 auto;margin-left:4px;
  display:grid;place-items:center;
  font-size:18px;font-weight:700;line-height:1;color:#fff;
  background:var(--accent-bg,linear-gradient(135deg,var(--pxa),color-mix(in srgb,var(--pxa) 78%,#000)));
  box-shadow:0 6px 16px -6px color-mix(in srgb,var(--pxa) 70%,transparent);
}
/* RTL portals read the other way, so the arrow must too. */
[dir="rtl"] .pxa-launch.lc-search::after{content:'\2190'}
.pxa-launch.lc-search:hover{border-color:color-mix(in srgb,var(--pxa) 55%,var(--line))}

/* ── BAR — the accent pill. Single line by definition: the subtitle belongs to the card and the
   search bar, and letting it through here made bar and card render identically. */
.pxa-launch.lc-bar{padding:12px 20px;border-radius:999px;font-size:13.5px}
.pxa-launch.lc-bar .pxa-ls,.pxa-launch.lc-tab .pxa-ls{display:none}

/* ── CARD — two lines, for portals that want the launcher to explain itself. */
.pxa-launch.lc-card{
  padding:11px 18px 11px 14px;border-radius:16px;font-size:13.5px;gap:11px;max-width:280px;
}
.pxa-launch.lc-card svg{width:26px;height:26px}
.pxa-launch.lc-card .pxa-ls{opacity:.86}

/* ── TAB — docked to the edge. Its own bottom overrides the anchor's, so it stays flush. */
.pxa-launch.lc-tab{padding:11px 17px;border-radius:14px 14px 0 0;font-size:13.5px}
.pxa-launch.lc-tab.pos-bottom-right,.pxa-launch.lc-tab.pos-bottom-left,
.pxa-launch.lc-tab.pos-bottom-center,.pxa-launch.lc-tab.pos-right,.pxa-launch.lc-tab.pos-left{bottom:0}

/* ── BUBBLE — the circle. No words fit, so hide them rather than clip them. */
.pxa-launch.lc-bubble{width:52px;height:52px;border-radius:50%;justify-content:center;padding:0}
.pxa-launch.lc-bubble .pxa-lt{display:none}

@media(max-width:600px){
  /* A phone has no room for a subtitle beside the thread it is floating over. */
  .pxa-launch.lc-search{height:46px;padding-left:12px;font-size:13px}
  .pxa-launch.lc-search::after{width:34px;height:34px}
  .pxa-launch .pxa-ls{display:none}
  .pxa-launch.lc-card{max-width:calc(100vw - 32px)}
}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   The panel clears a foreign launcher the same way the launcher does.

   Measured: with the client chat widget on the page, the assistant panel opened at bottom:24px
   and the widget's bubble sat on top of its composer, covering the send button. The widget host
   is z-index 2147483647 — the maximum — so no stacking order of ours can ever paint above it.
   --pxf-lift is set by pxStackFloats() to the room the widget needs, and the panel both moves up
   by it and gives back the same height so it cannot grow off the top of the screen.

   min-width guard: on a phone the panel is deliberately full-screen at bottom:0, and that rule is
   earlier in this file — without the guard this would override it and reintroduce a gap.
   ══════════════════════════════════════════════════════════════════════════════════════════ */
@media (min-width:481px){
  .pxa-panel{
    bottom:calc(24px + var(--pxf-lift,0px));
    max-height:calc(100vh - 48px - var(--pxf-lift,0px));
  }
}

/* ── EXPAND ────────────────────────────────────────────────────────────────────────────────
   390 × 600 is right for asking a quick question and wrong for reading a long answer or holding a
   live conversation, so the panel can be widened from its own header. The expanded size is capped
   against the viewport rather than fixed, and it still respects --pxf-lift so expanding never
   pushes the composer back under a chat-widget bubble. */
.pxa-head .pxa-exp{
  margin-inline-start:auto;display:flex;align-items:center;justify-content:center;padding:0;
}
.pxa-head .pxa-exp + .pxa-x{margin-inline-start:6px}
.pxa-head .pxa-exp svg{width:15px;height:15px}
@media (min-width:481px){
  .pxa-panel.pxa-wide{
    width:min(760px, calc(100vw - 48px));
    height:min(860px, calc(100vh - 48px - var(--pxf-lift,0px)));
  }
  /* Wider panel, wider reading measure — bubbles that stay at 88% of 760px read as a wall. */
  .pxa-panel.pxa-wide .pxa-msg{max-width:74%}
  .pxa-panel.pxa-wide .pxa-body{padding:20px 22px;gap:14px}
  .pxa-panel.pxa-wide .pxa-cards{max-width:78%}
}
@media (max-width:480px){
  /* The phone panel is already full-screen, so there is nothing to expand into. */
  .pxa-head .pxa-exp{display:none}
}

/* ── HEADER ICONS: NO PLATE UNTIL HOVER ────────────────────────────────────────────────────
   All three header glyphs (the avatar, expand and close) shipped with a permanent translucent
   plate behind them, so the header read as three grey boxes on a coloured band — and the expand
   button, being new, made that obvious. The plate is now a hover affordance: it appears when the
   pointer is over an actual button, and the avatar loses it entirely because it is not one.

   The focus ring is restated too: the browser default drew a heavy dark box against the accent
   header, which looked like a rendering fault rather than a focus state. */
.pxa-head .pxa-ava{background:transparent}
.pxa-head .pxa-x,
.pxa-head .pxa-exp{
  background:transparent;
  transition:background .14s ease, transform .14s ease;
}
.pxa-head .pxa-x:hover,
.pxa-head .pxa-exp:hover{background:rgba(255,255,255,.22)}
.pxa-head .pxa-x:active,
.pxa-head .pxa-exp:active{background:rgba(255,255,255,.3);transform:scale(.94)}
.pxa-head .pxa-x:focus-visible,
.pxa-head .pxa-exp:focus-visible{
  outline:2px solid rgba(255,255,255,.85);outline-offset:1px;background:rgba(255,255,255,.18);
}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   PHASE_PORTAL_ASSISTANT_SCROLLBAR — a tiny scrollbar on every engine, Firefox included.

   ⚠ WHY FIREFOX "HARDLY RESPECTS IT": Firefox has never implemented ::-webkit-scrollbar, so a
   webkit-only rule is ignored there and the OS scrollbar returns at full width. Firefox honours
   only the STANDARD properties, `scrollbar-width` and `scrollbar-color`.

   ⚠ BUT THE TWO FIGHT, AND THE STANDARD ONE WINS: Chrome 121+ also implements the standard
   properties, and the moment `scrollbar-color` is set Chrome switches to the standard renderer and
   STOPS applying ::-webkit-scrollbar. Measured here: declaring both gave Chrome a 10px gutter
   instead of the 6px bar the webkit rules ask for. So the standard properties are fenced to the
   engines that have NOTHING ELSE — `not selector(::-webkit-scrollbar)` is true only in Firefox —
   and the webkit rules are left unconditional, which Firefox ignores anyway.

   Result: 6px in Chrome/Edge/Safari, and Firefox's `thin` with no track and a faded thumb.

   HONEST LIMIT: Firefox accepts only `auto | thin | none`, never a pixel width, so `thin` is as
   small as it can be told to go there — roughly 10px depending on platform. `scrollbar-color` is
   what makes it read as a hairline rather than a grey channel.
   ══════════════════════════════════════════════════════════════════════════════════════════ */
.pxa-body::-webkit-scrollbar{width:6px;height:6px}
.pxa-body::-webkit-scrollbar-track{background:transparent}
.pxa-body::-webkit-scrollbar-thumb{
  background:color-mix(in srgb,var(--ink) 24%,transparent);
  border-radius:99px;
}
.pxa-body:hover::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--ink) 40%,transparent)}
.pxa-body::-webkit-scrollbar-corner{background:transparent}

/* Firefox — the only engine without the webkit pseudo-element. */
@supports (scrollbar-width: thin) and (not selector(::-webkit-scrollbar)){
  .pxa-body{
    scrollbar-width:thin;
    scrollbar-color:color-mix(in srgb,var(--ink) 26%,transparent) transparent;   /* thumb, track */
  }
  .pxa-body:hover{scrollbar-color:color-mix(in srgb,var(--ink) 40%,transparent) transparent}
}
/* Firefox older than @supports selector() (roughly pre-111) never matches the query above, so it
   would fall through to the OS scrollbar. @-moz-document is parsed by Firefox ONLY — every other
   engine drops the whole block — which is exactly the discriminator needed here. */
@-moz-document url-prefix(){
  .pxa-body{
    scrollbar-width:thin;
    scrollbar-color:color-mix(in srgb,var(--ink) 26%,transparent) transparent;
  }
}
