/* ══════════════════════════════════════════════════════════════════
   XENON — Ambient AI presence
   A voice-first, immersive presence layer. Not a chat app: a calm,
   near-invisible space where light, motion and typography carry the
   interaction. The only kept legacy element is the Siri-style edge
   glow that frames the display when Xenon is active.
   ══════════════════════════════════════════════════════════════════ */

@property --ai-angle {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

/* ── Atmosphere palette (refined, calm — no rainbow) ──────────────── */
:root {
  --xn-cyan:   #7ad7ff;   /* soft electric cyan  */
  --xn-violet: #b69dff;   /* soft electric violet */
  --xn-ink:    #06080c;   /* deep ambient black   */
}

/* ── Motion vocabulary ────────────────────────────────────────────── */
@keyframes xn-spin        { to { --ai-angle: 360deg; } }
@keyframes xn-breathe     { 0%,100%{ transform: scale(1); }   50%{ transform: scale(1.05); } }
@keyframes xn-pulse       { 0%,100%{ opacity: .55; }          50%{ opacity: 1; } }
@keyframes xn-space-in    { from{ opacity:0; } to{ opacity:1; } }
@keyframes xn-emerge      { from{ opacity:0; transform:translateY(12px); filter:blur(7px); }
                            to  { opacity:1; transform:translateY(0);    filter:blur(0); } }
@keyframes xn-msg-in      { from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:translateY(0); } }
@keyframes xn-think-dot   { 0%,60%,100%{ transform:translateY(0); opacity:.35; } 30%{ transform:translateY(-5px); opacity:1; } }

/* ══════════════════════════════════════════════════════════════════
   1 · EDGE GLOW  (the one kept element — refined, calmer)
   A conic light that breathes around the display rim while Xenon is
   present. It is the ambient "tell" that the presence is awake.
   ══════════════════════════════════════════════════════════════════ */
.ai-siri-ring {
  position: fixed;
  inset: 0;
  z-index: 9998;
  pointer-events: none;
  padding: 2.5px;
  background: conic-gradient(from var(--ai-angle),
    var(--accent)   0%,
    var(--xn-cyan)  28%,
    var(--xn-violet) 58%,
    var(--accent)   100%
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
  opacity: 0;
  filter: blur(.3px) saturate(1.05);
  transition: opacity .6s ease;
  animation: xn-spin 5s linear infinite paused;
  will-change: transform;
}

body.ai-open .ai-siri-ring,
body.ai-active .ai-siri-ring,
body.ai-listening .ai-siri-ring {
  opacity: 1;
  animation-play-state: running;
}
/* Listening = quicker, more alive */
body.ai-listening .ai-siri-ring { animation-duration: 2.2s; }
/* Speaking = energetic but smooth */
body.voice-speaking .ai-siri-ring { animation-duration: 3s; }



/* ══════════════════════════════════════════════════════════════════
   3 · THE SPACE  (overlay + panel)
   Entering Xenon dims the dashboard into a deep ambient field — space,
   light and a breathing aura, rather than a glass card over widgets.
   ══════════════════════════════════════════════════════════════════ */
.ai-overlay {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: flex;
}
.ai-overlay[hidden] { display: none !important; }

.ai-panel {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  animation: xn-space-in .42s ease both;

  background:
    radial-gradient(130% 90% at 50% 30%, rgba(var(--accent-rgb), .08), transparent 60%),
    radial-gradient(120% 120% at 50% 120%, rgba(182,157,255,.06), transparent 55%),
    linear-gradient(180deg, #090b11 0%, var(--xn-ink) 55%, #04050a 100%);
  backdrop-filter: blur(46px) saturate(1.4);
  -webkit-backdrop-filter: blur(46px) saturate(1.4);
  box-shadow: inset 0 0 140px rgba(0,0,0,.55);
}

/* A slow breathing aura behind everything — the room is alive */
.ai-panel::before {
  content: '';
  position: absolute;
  left: 50%; top: 34%;
  width: 70vmin; height: 70vmin;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--accent-rgb), .07), transparent 62%);
  pointer-events: none;
  z-index: 0;
  animation: xn-breathe 9s ease-in-out infinite;
  will-change: transform;
}

/* ── Header — minimal presence line ──────────────────────────────── */
.ai-header {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 17px 20px 14px;
  position: relative;
  z-index: 2;
  flex-shrink: 0;
}

.ai-avatar {
  width: 30px; height: 30px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  position: relative;
  flex-shrink: 0;
  background: conic-gradient(from var(--ai-angle), var(--accent), var(--xn-cyan), var(--xn-violet), var(--accent));
  animation: xn-spin 6s linear infinite;
  will-change: transform;
}
.ai-avatar::after {
  content: '';
  position: absolute;
  inset: 2px;
  border-radius: 50%;
  background: var(--xn-ink);
}
.ai-avatar svg {
  width: 16px; height: 16px;
  position: relative;
  z-index: 1;
  fill: none;
  color: var(--accent);
  stroke: currentColor;
}

.ai-header-title {
  flex: 1;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255,255,255,.78);
}

.ai-header-actions { display: flex; align-items: center; gap: 6px; }

.ai-clear-btn {
  font-size: 14px;
  color: rgba(255,255,255,.30);
  background: none;
  border: none;
  cursor: pointer;
  width: 26px; height: 26px;
  border-radius: 8px;
  display: grid; place-items: center;
  transition: color .2s, background .2s;
}
.ai-clear-btn:hover { color: rgba(255,255,255,.72); background: rgba(255,255,255,.06); }

/* Wake word removed — these body states are kept for forward compat but are never set now */

.ai-header-close {
  width: 26px; height: 26px;
  border-radius: 50%;
  border: none;
  background: rgba(255,255,255,.05);
  color: rgba(255,255,255,.55);
  cursor: pointer;
  display: grid; place-items: center;
  transition: background .2s, color .2s;
  flex-shrink: 0;
}
.ai-header-close svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; }
.ai-header-close:hover { background: rgba(255,255,255,.14); color: rgba(255,255,255,.92); }

/* ══════════════════════════════════════════════════════════════════
   4 · CONVERSATION  (chat = calm transcript, not a messaging app)
   Assistant speaks as borderless typography with a soft accent marker.
   Only the user gets a minimal tinted pill, to mark the voice.
   ══════════════════════════════════════════════════════════════════ */
.ai-chat {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 10px 22px 6px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  position: relative;
  z-index: 1;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,.10) transparent;
  min-height: 0;
}
.ai-chat::-webkit-scrollbar { width: 3px; }
.ai-chat::-webkit-scrollbar-track { background: transparent; }
.ai-chat::-webkit-scrollbar-thumb { background: rgba(255,255,255,.10); border-radius: 2px; }

.ai-msg {
  display: flex;
  max-width: 92%;
  animation: xn-msg-in .22s ease;
}
.ai-msg-user      { align-self: flex-end; max-width: 80%; }
.ai-msg-assistant { align-self: flex-start; max-width: 94%; position: relative; padding-left: 16px; }

/* soft accent marker beside Xenon's words */
.ai-msg-assistant::before {
  content: '';
  position: absolute;
  left: 0; top: 4px; bottom: 4px;
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--accent), transparent);
  opacity: .55;
}

.ai-msg-bubble {
  font-size: 14px;
  line-height: 1.62;
  color: rgba(255,255,255,.90);
  word-break: break-word;
  white-space: pre-wrap;
  /* Chat replies must be selectable/copyable — the body sets user-select:none
     globally for the touch UI, so re-enable it here for the message text. */
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}

/* Per-message copy button — sits beside the bubble, quiet until the message is
   hovered/focused (and faintly visible on touch, which has no hover). */
.ai-msg-copy {
  flex: 0 0 auto;
  align-self: flex-start;
  margin-top: 2px;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: rgba(255,255,255,.55);
  cursor: pointer;
  opacity: 0;
  transition: opacity .16s ease, background .16s ease, color .16s ease;
  -webkit-tap-highlight-color: transparent;
}
.ai-msg-copy svg { width: 15px; height: 15px; }
.ai-msg:hover .ai-msg-copy,
.ai-msg-copy:focus-visible { opacity: 1; }
.ai-msg-copy:hover { background: rgba(255,255,255,.08); color: rgba(255,255,255,.9); }
.ai-msg-copy.is-copied { opacity: 1; color: rgba(var(--accent-rgb), 1); }
/* Touch (no hover): keep the button discoverable at rest. */
@media (hover: none) {
  .ai-msg-copy { opacity: .4; }
}

/* user — minimal tinted pill */
.ai-msg-user .ai-msg-bubble {
  padding: 9px 15px;
  border-radius: 16px 16px 5px 16px;
  background: rgba(var(--accent-rgb), .15);
  border: 1px solid rgba(var(--accent-rgb), .22);
  color: rgba(255,255,255,.94);
  font-size: 13.5px;
  line-height: 1.5;
}

/* assistant — pure typography, no box */
.ai-msg-assistant .ai-msg-bubble {
  padding: 0;
  background: none;
  border: none;
  color: rgba(255,255,255,.88);
}

/* ── Status / thinking ───────────────────────────────────────────── */
.ai-status {
  min-height: 22px;
  padding: 2px 22px 4px;
  position: relative;
  z-index: 1;
  font-size: 11.5px;
  letter-spacing: .02em;
  color: rgba(255,255,255,.38);
  flex-shrink: 0;
  display: flex;
  align-items: center;
}

.ai-thinking-dots { display: inline-flex; align-items: center; gap: 5px; }
.ai-thinking-dots span {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: rgba(var(--accent-rgb), .75);
  animation: xn-think-dot 1.2s ease-in-out infinite;
  will-change: transform, opacity;
}
.ai-thinking-dots span:nth-child(2) { animation-delay: .18s; }
.ai-thinking-dots span:nth-child(3) { animation-delay: .36s; }

/* ══════════════════════════════════════════════════════════════════
   5 · INPUT  (emerges quietly, recedes visually)
   ══════════════════════════════════════════════════════════════════ */
.ai-input-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 18px 18px;
  position: relative;
  z-index: 1;
  flex-shrink: 0;
}

.ai-text-input {
  flex: 1;
  /* A flex item's `min-width` defaults to `auto`, and for an <input> that
     resolves to the intrinsic width of its `size` attribute — about 20
     characters — measured in whatever font actually loaded. So `flex: 1` can
     grow this box but never shrink it below that floor, and when the floor is
     wider than the row the overflow lands on the LAST sibling: the send button
     gets clipped by the panel edge. Seen on Linux, where neither Inter nor
     Segoe UI exists and the stack falls through to Noto Sans, whose wider
     metrics push the floor past the available width. `min-width: 0` is what
     makes `flex: 1` mean what it reads like. */
  min-width: 0;
  height: 42px;
  border-radius: 21px;
  border: 1px solid rgba(255,255,255,.10);
  background: rgba(255,255,255,.04);
  color: rgba(255,255,255,.92);
  font-size: 13.5px;
  padding: 0 16px;
  outline: none;
  transition: border-color .25s, background .25s, box-shadow .25s;
}
.ai-text-input::placeholder { color: rgba(255,255,255,.30); }
.ai-text-input:focus {
  border-color: rgba(var(--accent-rgb), .45);
  background: rgba(255,255,255,.07);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), .08);
}

.ai-send-btn,
.ai-attach-btn,
.ai-screen-btn,
.ai-dictate-btn {
  width: 42px; height: 42px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.08);
  background: rgba(255,255,255,.035);
  color: rgba(255,255,255,.48);
  cursor: pointer;
  display: grid; place-items: center;
  flex-shrink: 0;
  transition: background .18s, color .18s, border-color .18s, transform .12s;
}
.ai-send-btn:hover,
.ai-attach-btn:hover, .ai-screen-btn:hover,
.ai-dictate-btn:hover {
  background: rgba(255,255,255,.09);
  color: rgba(255,255,255,.92);
}
.ai-send-btn:active,
.ai-attach-btn:active, .ai-screen-btn:active,
.ai-dictate-btn:active { transform: scale(.94); }

.ai-send-btn svg, .ai-dictate-btn svg { width: 17px; height: 17px; fill: currentColor; }
.ai-attach-btn svg, .ai-screen-btn svg { width: 16px; height: 16px; flex-shrink: 0; }

/* Inline dictation: recording pulses in the accent; the brief transcription
   round-trip dims the button and blocks re-entry. */
.ai-dictate-btn.active {
  background: rgba(var(--accent-rgb), .22);
  border-color: rgba(var(--accent-rgb), .50);
  color: var(--accent);
  animation: xn-pulse 1.2s ease-in-out infinite;
  will-change: opacity;
}
.ai-dictate-btn.busy { opacity: .55; pointer-events: none; }

.ai-send-btn {
  background: rgba(var(--accent-rgb), .16);
  border-color: rgba(var(--accent-rgb), .30);
  color: var(--accent);
}
.ai-send-btn:hover { background: rgba(var(--accent-rgb), .26); }

.ai-screen-btn.active {
  background: rgba(var(--accent-rgb), .20);
  border-color: rgba(var(--accent-rgb), .46);
  color: var(--accent);
}

/* ── Pending attachment preview strip ────────────────────────────── */
.ai-attach-preview {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 20px 2px;
  flex-wrap: wrap;
  flex-shrink: 0;
  position: relative;
  z-index: 1;
}
.ai-attach-preview[hidden] { display: none !important; }
.ai-attach-thumb-wrap { position: relative; flex-shrink: 0; }
.ai-attach-thumb {
  width: 52px; height: 52px;
  object-fit: cover;
  border-radius: 11px;
  border: 1px solid rgba(255,255,255,.14);
  display: block;
}
.ai-attach-thumb-rm {
  position: absolute;
  top: -5px; right: -5px;
  width: 17px; height: 17px;
  border-radius: 50%;
  border: none;
  background: rgba(20,22,28,.92);
  color: rgba(255,255,255,.82);
  font-size: 11px;
  line-height: 1;
  cursor: pointer;
  display: grid; place-items: center;
  padding: 0;
}
.ai-attach-thumb-rm:hover { background: rgba(220,60,60,.9); color: #fff; }

/* ── Images inside conversation ──────────────────────────────────── */
.ai-bubble-images { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 7px; }
.ai-bubble-img {
  max-width: 200px; max-height: 130px;
  border-radius: 12px;
  object-fit: cover;
  border: 1px solid rgba(255,255,255,.12);
  display: block;
}

/* ── Document attachments (PDF / text) — pending preview + in bubble ─ */
.ai-attach-doc,
.ai-bubble-doc {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 200px;
  padding: 8px 12px 8px 8px;
  border-radius: 11px;
  border: 1px solid rgba(255,255,255,.14);
  background: rgba(255,255,255,.05);
}
.ai-attach-doc { height: 52px; }
.ai-attach-doc-ext {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  border-radius: 8px;
  background: rgba(var(--accent-rgb), .18);
  color: var(--accent);
  font-size: 9.5px;
  font-weight: 900;
  letter-spacing: .4px;
}
.ai-attach-doc-name,
.ai-bubble-doc .ai-attach-doc-name {
  min-width: 0;
  font-size: 11.5px;
  font-weight: 650;
  color: rgba(255,255,255,.82);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* legacy in-chat monitor picker (text mode) — kept, restyled subtle */
.ai-screen-picker {
  padding: 8px 20px 6px;
  flex-shrink: 0;
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.ai-screen-picker-label { font-size: 11.5px; color: rgba(255,255,255,.38); }
.ai-screen-picker-row { display: flex; gap: 7px; flex-wrap: wrap; }
.ai-screen-picker-btn {
  padding: 6px 14px;
  border-radius: 20px;
  border: 1px solid rgba(255,255,255,.12);
  background: rgba(255,255,255,.04);
  color: rgba(255,255,255,.75);
  font-size: 12px;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
  white-space: nowrap;
}
.ai-screen-picker-btn:hover {
  background: rgba(var(--accent-rgb), .16);
  border-color: rgba(var(--accent-rgb), .32);
  color: rgba(255,255,255,.95);
}
.ai-screen-picker-primary { border-color: rgba(var(--accent-rgb), .28); color: rgba(255,255,255,.88); }

/* ══════════════════════════════════════════════════════════════════
   6 · VOICE MODE — the centerpiece
   Almost-empty space: a living presence, then language emerging as
   large, light typography. Tap anywhere to interrupt.
   ══════════════════════════════════════════════════════════════════ */
.ai-voice-view { display: none; }
/* Hide the chat composer that lives INSIDE the overlay while the voice view takes
   over — scoped to .ai-overlay so it never touches the same chat elements once
   they've been relocated into the Media tile's Chat tab (otherwise the ambient,
   see-through voice mode would blank that tab behind it). */
body.ai-voice-mode .ai-overlay .ai-chat,
body.ai-voice-mode .ai-overlay .ai-status,
body.ai-voice-mode .ai-overlay .ai-attach-preview,
body.ai-voice-mode .ai-overlay .ai-input-row { display: none !important; }

body.ai-voice-mode .ai-voice-view {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  flex: 1;
  gap: 22px;
  padding: 56px 30px 32px;
  cursor: pointer;
  text-align: center;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  scroll-behavior: smooth;
}

/* ── The presence — Xenon Resonance Orb ──────────────────────────────
   A volumetric sphere of living light. There are NO hard edges: the orb's
   rim melts into its own glow through a radial mask, so it floats in the
   black rather than sitting on a visible disc. Light is built from four
   drifting colour blobs (a Gemini-style fluid mesh) over a deep base, with
   a bright beating core. Three behaviours — listen / think / speak — read
   through the aura, the radiating waves and the processing ring. */
.ai-presence {
  position: relative;
  width: 264px; height: 264px;
  display: grid;
  place-items: center;
  will-change: transform;
}

/* ══════════════════════════════════════════════════════════════════
   Voice presence — circular AUDIO EQUALISER (replaces the orb).
   A ring of luminous radial bars around a soft breathing core, with
   expanding ripples. A staggered per-bar delay makes a wave travel
   around the ring (hypnotic, never stutters). The glowing border
   (.ai-siri-ring) is kept. Coherent across the body.voice-* states:
     listening → gentle calm wave
     thinking  → a tight bright pulse races around the ring (scanning)
     speaking  → big energetic wave + outward ripples
   GPU-friendly: only transform / opacity animate.
   ══════════════════════════════════════════════════════════════════ */
.ai-voice-aura {
  position: absolute;
  width: 240px; height: 240px;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%,
    rgba(var(--accent-rgb), .32) 0%,
    rgba(var(--accent-rgb), .12) 32%,
    transparent 66%);
  filter: blur(18px);
  animation: vx-breathe 4.6s ease-in-out infinite;
  will-change: transform, opacity;
}
.ai-voice-core {
  position: absolute;
  width: 100px; height: 100px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  /* Soft formless glow — fades fully out, so there is no hard "ball" edge. */
  background: radial-gradient(circle,
    rgba(var(--accent-rgb), .45) 0%,
    rgba(var(--accent-rgb), .16) 36%,
    transparent 70%);
  animation: vx-core 3.2s ease-in-out infinite;
  will-change: transform, opacity;
}
.ai-voice-core svg {
  width: 42px; height: 42px;
  fill: rgb(var(--accent-rgb));
  filter: drop-shadow(0 0 7px rgba(var(--accent-rgb), .9)) drop-shadow(0 0 2px rgba(255,255,255,.5));
  animation: vx-spark 7s linear infinite;
  will-change: transform;
}
@keyframes vx-spark { to { transform: rotate(360deg); } }

/* Keep every voice layer perfectly concentric (inset:0 + margin:auto centres a
   fixed-size absolute element without a transform, leaving transforms free for
   the animations). */
.ai-voice-aura,
.ai-eq,
.ai-voice-core,
.ai-voice-ripple { inset: 0; margin: auto; }
.ai-voice-ripple {
  position: absolute;
  width: 116px; height: 116px;
  border-radius: 50%;
  border: 1.5px solid rgba(var(--accent-rgb), .5);
  opacity: 0;
  animation: vx-ripple 3.6s ease-out infinite;
  will-change: transform, opacity;
}
.ai-voice-ripple.r2 { animation-delay: 1.8s; }
.ai-eq {
  position: absolute;
  width: 200px; height: 200px;
  animation: vx-spin 44s linear infinite;
  will-change: transform;
}
.ai-eq-bar {
  position: absolute;
  left: 50%; top: 50%;
  width: 3.5px; height: 26px;
  margin-left: -1.75px;
  border-radius: 3px;
  background: linear-gradient(to top, rgba(var(--accent-rgb), .12), rgb(var(--accent-rgb)));
  transform-origin: 50% 100%;
  transform: rotate(calc(var(--i) * 15deg)) translateY(-66px) scaleY(.4);
  filter: drop-shadow(0 0 3px rgba(var(--accent-rgb), .6));
  animation: vx-bar 1.7s ease-in-out infinite;
  animation-delay: calc(var(--i) * -0.065s);
  will-change: transform, opacity;
}

@keyframes vx-bar {
  0%, 100% { transform: rotate(calc(var(--i) * 15deg)) translateY(-66px) scaleY(.35); opacity: .5; }
  50%      { transform: rotate(calc(var(--i) * 15deg)) translateY(-66px) scaleY(1);   opacity: 1; }
}
@keyframes vx-spin { to { transform: rotate(360deg); } }
@keyframes vx-core { 0%, 100% { transform: scale(.9); opacity: .85; } 50% { transform: scale(1.14); opacity: 1; } }
@keyframes vx-breathe { 0%, 100% { transform: scale(.9); opacity: .7; } 50% { transform: scale(1.08); opacity: 1; } }
@keyframes vx-ripple { 0% { transform: scale(.55); opacity: .65; } 100% { transform: scale(2); opacity: 0; } }

/* State: listening — gentle, calm wave */
body.voice-listening .ai-eq-bar { animation-duration: 2s; }
body.voice-listening .ai-eq { animation-duration: 64s; }
body.voice-listening .ai-voice-core { animation-duration: 3.8s; }

/* State: thinking — a tight bright pulse races around the ring */
body.voice-thinking .ai-eq-bar { animation-duration: .7s; animation-delay: calc(var(--i) * -0.04s); }
body.voice-thinking .ai-eq { animation-duration: 7s; }
body.voice-thinking .ai-voice-core { animation-duration: 1.1s; }
body.voice-thinking .ai-voice-core svg { animation-duration: 2.6s; }
body.voice-thinking .ai-voice-ripple { animation: none; opacity: 0; }

/* State: speaking — big energetic wave + outward ripples */
body.voice-speaking .ai-eq-bar { animation-duration: .9s; }
body.voice-speaking .ai-voice-core { animation-duration: 1.2s; }
body.voice-speaking .ai-voice-core svg { animation-duration: 4s; filter: drop-shadow(0 0 12px rgba(var(--accent-rgb), 1)) drop-shadow(0 0 3px rgba(255,255,255,.7)); }
body.voice-speaking .ai-voice-ripple { animation-duration: 1.9s; }
body.voice-speaking .ai-voice-aura { animation-duration: 1.7s; }

@media (prefers-reduced-motion: reduce) {
  .ai-voice-aura, .ai-voice-core, .ai-voice-core svg, .ai-voice-ripple, .ai-eq, .ai-eq-bar { animation: none !important; }
  .ai-eq-bar { transform: rotate(calc(var(--i) * 15deg)) translateY(-66px) scaleY(.7); }
}

/* ── Language emerging — large, light, expressive typography ──────── */
.ai-voice-user {
  font-size: 15px;
  font-weight: 400;
  letter-spacing: .01em;
  color: rgba(255,255,255,.52);
  max-width: min(720px, 88%);
  width: 88%;
  line-height: 1.4;
  text-align: center;
  word-break: normal;
  overflow-wrap: break-word;
  opacity: 1;
  visibility: visible;
}
.ai-voice-user:not(:empty) { animation: xn-emerge .5s cubic-bezier(.22,1,.36,1) both; }

.ai-voice-reply {
  font-size: clamp(20px, 2.2vw, 28px);
  font-weight: 300;
  letter-spacing: -.018em;
  color: rgba(255,255,255,.97);
  max-width: min(900px, 92%);
  width: 92%;
  line-height: 1.4;
  text-align: center;
  word-break: normal;
  overflow-wrap: break-word;
  max-height: 60vh;
  overflow-y: auto;
  scrollbar-width: none;
  /* Belt-and-braces: ensure the element is always rendered visible, even on
     WebViews that mishandle :not(:empty) animation states (Xeneon Edge LCD). */
  opacity: 1;
  visibility: visible;
}
.ai-voice-reply::-webkit-scrollbar { display: none; }
.ai-voice-reply:not(:empty) { animation: xn-emerge .55s cubic-bezier(.22,1,.36,1) both; }
/* Long answers (capability rundowns, etc.): shrink, left-align and honour the
   line breaks between points so nothing overflows the compact voice view. */
.ai-voice-reply.ai-voice-reply-long {
  font-size: clamp(14px, 1.5vw, 18px);
  line-height: 1.5;
  font-weight: 400;
  text-align: left;
  white-space: pre-line;
  max-height: 52vh;
  padding: 0 6px;
}

.ai-voice-hint {
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: .04em;
  color: rgba(var(--accent-rgb), .82);
  min-height: 16px;
}
body.voice-listening .ai-voice-hint { animation: xn-pulse 1.6s ease-in-out infinite; }

/* ══════════════════════════════════════════════════════════════════
   6b · AMBIENT VOICE — the dashboard stays visible, only the edge glows
   Opt-in (Settings → Xenon AI → "Chat vocale trasparente"). The opaque
   "room" is peeled away: the panel turns transparent, the orb steps aside,
   and the screen border breathes in the accent to signal listen / think /
   speak. Live captions sit in a compact glass strip at the bottom so they
   stay readable over any widget behind them.
   ══════════════════════════════════════════════════════════════════ */
body.ai-voice-mode.ai-voice-ambient .ai-panel {
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  box-shadow: none !important;
}
body.ai-voice-mode.ai-voice-ambient .ai-panel::before { display: none; } /* kill the breathing aura */

/* The reactive edge glow — an inset halo hugging the screen border. It rides
   above the (now see-through) panel but never eats taps (pointer-events:none). */
body.ai-voice-mode.ai-voice-ambient .ai-overlay::after {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 4;
  box-shadow:
    inset 0 0 3px  rgba(var(--accent-rgb), .55),
    inset 0 0 34px rgba(var(--accent-rgb), .30),
    inset 0 0 90px rgba(var(--accent-rgb), .12);
  transition: box-shadow .45s ease;
  animation: xn-edge-breathe 4.4s ease-in-out infinite;
  will-change: opacity;
}
body.ai-voice-mode.ai-voice-ambient.voice-listening .ai-overlay::after { animation-duration: 2.6s; }
body.ai-voice-mode.ai-voice-ambient.voice-thinking .ai-overlay::after {
  animation-duration: 1.5s;
  box-shadow:
    inset 0 0 3px  rgba(182,157,255, .55),
    inset 0 0 34px rgba(182,157,255, .30),
    inset 0 0 90px rgba(182,157,255, .12);
}
body.ai-voice-mode.ai-voice-ambient.voice-speaking .ai-overlay::after {
  animation-duration: 1.9s;
  box-shadow:
    inset 0 0 4px   rgba(var(--accent-rgb), .78),
    inset 0 0 46px  rgba(var(--accent-rgb), .42),
    inset 0 0 120px rgba(var(--accent-rgb), .18);
}
@keyframes xn-edge-breathe {
  0%, 100% { opacity: .55; }
  50%      { opacity: .95; }
}

/* The orb steps aside; captions anchor to the bottom, near the edge glow. */
body.ai-voice-mode.ai-voice-ambient .ai-presence { display: none; }
body.ai-voice-mode.ai-voice-ambient .ai-voice-view {
  justify-content: flex-end;
  gap: 10px;
  padding: 30px 30px 42px;
}

/* Legible glass strip behind each live caption so it reads over any widget. */
body.ai-voice-mode.ai-voice-ambient .ai-voice-user:not(:empty),
body.ai-voice-mode.ai-voice-ambient .ai-voice-reply:not(:empty),
body.ai-voice-mode.ai-voice-ambient .ai-voice-hint:not(:empty) {
  padding: 9px 18px;
  border-radius: 15px;
  background: rgba(10, 12, 18, .58);
  border: 1px solid rgba(255, 255, 255, .09);
  backdrop-filter: blur(16px) saturate(1.25);
  -webkit-backdrop-filter: blur(16px) saturate(1.25);
  box-shadow: 0 10px 34px rgba(0, 0, 0, .4);
}
/* Reply drops from hero size to a readable caption in ambient mode. */
body.ai-voice-mode.ai-voice-ambient .ai-voice-user  { width: auto; color: rgba(255, 255, 255, .72); }
body.ai-voice-mode.ai-voice-ambient .ai-voice-reply {
  width: auto;
  font-size: clamp(16px, 1.7vw, 21px);
  max-height: 34vh;
}
body.ai-voice-mode.ai-voice-ambient .ai-voice-reply.ai-voice-reply-long { max-height: 30vh; }
/* The header floats over the dashboard now — keep its text/controls legible. */
body.ai-voice-mode.ai-voice-ambient .ai-header { text-shadow: 0 1px 8px rgba(0, 0, 0, .6); }

/* ══════════════════════════════════════════════════════════════════
   7 · MONITOR PICKER  (clean modal inside the space)
   ══════════════════════════════════════════════════════════════════ */
.ai-voice-monitor-picker {
  position: absolute;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(5,7,11,.6);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  animation: xn-space-in .22s ease both;
}

.ai-monitor-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: 100%;
  max-width: 340px;
  padding: 24px 22px;
  background: linear-gradient(180deg, rgba(20,22,30,.94), rgba(12,14,20,.94));
  border: 1px solid rgba(255,255,255,.10);
  border-radius: 24px;
  box-shadow: 0 20px 60px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.06);
  animation: xn-emerge .3s cubic-bezier(.22,1,.36,1) both;
}

.ai-voice-monitor-label {
  color: rgba(255,255,255,.55);
  font-size: .72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .14em;
  text-align: center;
}

.ai-monitor-grid { display: flex; flex-direction: column; gap: 10px; }

.ai-voice-monitor-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  width: 100%;
  min-height: 62px;
  padding: 13px 16px;
  border: 1.5px solid rgba(255,255,255,.12);
  border-radius: 16px;
  background: rgba(255,255,255,.04);
  color: #fff;
  cursor: pointer;
  transition: background .15s, border-color .15s, transform .1s;
  will-change: transform;
}
.ai-voice-monitor-btn:hover,
.ai-voice-monitor-btn:focus {
  background: rgba(var(--accent-rgb), .18);
  border-color: rgba(var(--accent-rgb), .6);
  outline: none;
}
.ai-voice-monitor-btn:active { transform: scale(.97); }
.ai-voice-monitor-btn.primary { border-color: rgba(var(--accent-rgb), .5); background: rgba(var(--accent-rgb), .12); }
.ai-monitor-num { font-size: .98rem; font-weight: 700; letter-spacing: .01em; }
.ai-monitor-res { font-size: .8rem; font-weight: 500; color: rgba(255,255,255,.55); font-variant-numeric: tabular-nums; }

/* While the picker is open, hide the presence so nothing shows through */
body.ai-picker-open .ai-presence,
body.ai-picker-open .ai-voice-user,
body.ai-picker-open .ai-voice-reply,
body.ai-picker-open .ai-voice-hint { visibility: hidden; }

/* ── PC Control confirmation card (consent-gated run_pc_command) ─────── */
.ai-pc-confirm { position: fixed; z-index: 1200; padding: 16px; overflow-y: auto; }
.ai-pc-card {
  max-width: 440px;
  width: 100%;
  gap: 12px;
  text-align: left;
  /* Never exceed the display: the whole card scrolls if content is tall, so the
     command output and the Chiudi/Consenti buttons are always reachable. */
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.ai-pc-actions {
  position: sticky;
  bottom: 0;
  padding-top: 10px;
  margin-top: 2px;
  background: linear-gradient(180deg, rgba(14,16,22,0), rgba(14,16,22,.96) 24%);
}
.ai-pc-title { font-size: 1.02rem; font-weight: 700; letter-spacing: .01em; }
.ai-pc-desc { font-size: .9rem; line-height: 1.5; color: rgba(255,255,255,.72); }
.ai-pc-cmd {
  margin: 0;
  padding: 12px 14px;
  max-height: 220px;
  overflow: auto;
  background: rgba(0,0,0,.42);
  border: 1px solid rgba(255,255,255,.10);
  border-radius: 12px;
  font-family: 'Consolas', 'Menlo', monospace;
  font-size: .82rem;
  line-height: 1.5;
  color: #eef1f6;
  white-space: pre-wrap;
  word-break: break-word;
}
.ai-pc-warn {
  display: flex;
  gap: 8px;
  font-size: .8rem;
  line-height: 1.45;
  color: #ffcf8a;
}
.ai-pc-warn::before { content: '⚠'; }
.ai-pc-actions { display: flex; gap: 10px; margin-top: 2px; }
.ai-pc-btn {
  flex: 1 1 auto;
  min-height: 46px;
  padding: 12px 16px;
  border-radius: 14px;
  border: 1.5px solid rgba(255,255,255,.14);
  background: rgba(255,255,255,.05);
  color: #fff;
  font-size: .92rem;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, border-color .15s, transform .1s;
  will-change: transform;
}
.ai-pc-btn:active { transform: scale(.97); }
.ai-pc-btn:disabled { opacity: .55; cursor: default; }
.ai-pc-run { border-color: rgba(var(--accent-rgb), .6); background: rgba(var(--accent-rgb), .18); }
.ai-pc-run:hover:not(:disabled) { background: rgba(var(--accent-rgb), .28); }
.ai-pc-cancel:hover:not(:disabled) { background: rgba(255,255,255,.10); }
.ai-pc-result-head { font-size: .9rem; font-weight: 700; margin-bottom: 8px; }
.ai-pc-result.ok .ai-pc-result-head { color: var(--color-success); }
.ai-pc-result.err .ai-pc-result-head { color: var(--color-danger); }
.ai-pc-out { max-height: 260px; }

/* ══════════════════════════════════════════════════════════════════
   8 · MARKDOWN  (assistant typography inside the transcript)
   ══════════════════════════════════════════════════════════════════ */
.ai-msg-markdown { display: block; }

.ai-msg-markdown .ai-h3,
.ai-msg-markdown .ai-h4 {
  font-size: .92rem;
  font-weight: 700;
  color: rgba(255,255,255,.96);
  margin: .7em 0 .25em;
  line-height: 1.25;
}
.ai-msg-markdown .ai-h4 { font-size: .85rem; }

.ai-msg-markdown .ai-p { margin: .2em 0; line-height: 1.6; }

.ai-msg-markdown .ai-ul,
.ai-msg-markdown .ai-ol {
  margin: .3em 0 .3em 1em;
  padding: 0;
  list-style-position: outside;
}
.ai-msg-markdown .ai-ul { list-style-type: disc; }
.ai-msg-markdown .ai-ol { list-style-type: decimal; }
.ai-msg-markdown li { margin: .15em 0; line-height: 1.5; }

.ai-msg-markdown .ai-inline-code {
  background: rgba(255,255,255,.10);
  border-radius: 5px;
  padding: 1px 6px;
  font-family: 'Consolas', 'Menlo', monospace;
  font-size: .82em;
  color: rgba(var(--accent-rgb), 1);
}

.ai-msg-markdown .ai-hr { border: none; border-top: 1px solid rgba(255,255,255,.12); margin: .6em 0; }
.ai-msg-markdown strong { font-weight: 700; color: rgba(255,255,255,.98); }
.ai-msg-markdown em     { font-style: italic; color: rgba(255,255,255,.85); }
.ai-msg-markdown .ai-link {
  color: rgba(var(--accent-rgb), .95);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.ai-msg-markdown .ai-link:hover { color: rgba(var(--accent-rgb), 1); }

/* ── Reduced-motion: honour the system preference ────────────────── */
@media (prefers-reduced-motion: reduce) {
  .ai-siri-ring, .ai-avatar, .ai-panel::before,
  .ai-presence, .ai-dictate-btn.active, .ai-voice-hint,
  body.ai-voice-mode.ai-voice-ambient .ai-overlay::after { animation: none !important; }
  /* The edge glow stays lit (static) so ambient mode still signals it's active. */
  body.ai-voice-mode.ai-voice-ambient .ai-overlay::after { opacity: .8; }
}

/* ── Undo affordance under a state-changing AI reply ─────────────────────────── */
.ai-undo-row { display: flex; justify-content: flex-start; margin: 2px 0 6px; }
.ai-undo-btn {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 12px; border-radius: 999px; cursor: pointer;
  font-size: 12px; font-weight: 650; line-height: 1;
  color: var(--accent);
  background: rgba(var(--accent-rgb), 0.10);
  border: 1px solid rgba(var(--accent-rgb), 0.34);
  transition: background .15s ease, border-color .15s ease, opacity .15s ease;
}
.ai-undo-btn:hover { background: rgba(var(--accent-rgb), 0.18); border-color: rgba(var(--accent-rgb), 0.5); }
.ai-undo-btn:disabled { cursor: default; }
.ai-undo-btn.ai-undo-done {
  color: var(--muted-text); background: rgba(255,255,255,0.05);
  border-color: rgba(255,255,255,0.12); opacity: 0.8;
}
