/* ════════════════════════════════════════════════════════════════════════
   ai-float.css — Eney-style floating AI assistant
   Loaded LAST so it wins over app.css + enhance.css. Frontend only.
════════════════════════════════════════════════════════════════════════ */

/* ── 1. PANEL IS INVISIBLE — only its children float ──────────────── */
.ai-panel,
[data-theme="dark"] .ai-panel {
  background: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border: none !important;
  border-left: none !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  overflow: visible !important;
  gap: 10px;
  padding: 0;
  /* starting height only — JS (_aiPanelFollowFab) sets the real height
     inline based on the room above the blob, so NO !important here */
  height: min(520px, calc(100vh - 190px));
  /* enhance.css collapses this under 680px viewport — hold the width */
  width: min(390px, calc(100vw - 28px)) !important;
  max-width: none !important;
  min-width: 0;
}
/* kill the glass sheen overlay from enhance.css */
.ai-panel::before { display: none !important; }

/* ── 2. HEADER — floating pill (this is the drag handle) ──────────── */
.ai-panel .ai-head,
[data-theme="dark"] .ai-panel .ai-head {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: 999px !important;
  box-shadow: 0 2px 6px rgba(0,0,0,.12), 0 10px 26px rgba(0,0,0,.16) !important;
  padding: 8px 10px 8px 8px !important;
  margin: 0 2px;
  flex-shrink: 0;
  cursor: grab;
  touch-action: none;          /* required for pointer-drag on touch */
}
.ai-panel .ai-head:active { cursor: grabbing; }
/* header text must be readable in BOTH themes */
.ai-panel .ai-head h3 { color: var(--text) !important; font-size: 13.5px; }
.ai-panel .ai-head .ai-sub { color: var(--text-3) !important; font-size: 10.5px; }
.ai-panel .ai-head .ai-ava { width: 32px !important; height: 32px !important; border-radius: 50% !important; }
.ai-panel .ai-head .ai-ava svg { width: 17px !important; height: 17px !important; }
.ai-panel .ai-head-btn {
  width: 27px !important; height: 27px !important;
  border-color: var(--border) !important;
  background: var(--surface-2) !important;
  color: var(--text-3) !important;
}
.ai-panel .ai-head-btn:hover { background: var(--brand) !important; color: #fff !important; }
.ai-panel .ai-head-btn svg { width: 14px !important; height: 14px !important; }

/* ── 3. MACHINE SELECT — floating pill ────────────────────────────── */
.ai-panel > div:has(> #ai-machine-sel) { padding: 0 2px !important; flex-shrink: 0; }
#ai-machine-sel {
  border-radius: 999px !important;
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  box-shadow: 0 2px 6px rgba(0,0,0,.1), 0 8px 20px rgba(0,0,0,.13);
  padding: 8px 14px !important;
}

/* ── 4. CHAT AREA — no container, bubbles float free ──────────────── */
.ai-panel .ai-body {
  background: none !important;
  padding: 4px 2px !important;
  gap: 12px !important;
  overflow-y: auto;
  scrollbar-width: thin;
}
.ai-panel .ai-body::-webkit-scrollbar { width: 5px; }
.ai-panel .ai-body::-webkit-scrollbar-thumb { background: rgba(128,128,128,.3); border-radius: 3px; }
.ai-panel .ai-body::-webkit-scrollbar-track { background: transparent; }

.ai-panel .ai-msg.bot,
[data-theme="dark"] .ai-panel .ai-msg.bot {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  backdrop-filter: none !important;
  border-radius: 20px !important;
  border-bottom-left-radius: 7px !important;
  box-shadow: 0 2px 6px rgba(0,0,0,.13), 0 10px 26px rgba(0,0,0,.17) !important;
  color: var(--text) !important;
}
.ai-panel .ai-msg.me {
  background: linear-gradient(135deg, #2563eb, #7c3aed) !important;
  color: #fff !important;
  border: none !important;
  border-radius: 20px !important;
  border-bottom-right-radius: 7px !important;
  box-shadow: 0 2px 8px rgba(37,99,235,.32), 0 10px 28px rgba(124,58,237,.34) !important;
}
.ai-panel .ai-thinking {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: 20px !important;
  border-bottom-left-radius: 7px !important;
  box-shadow: 0 2px 6px rgba(0,0,0,.13), 0 10px 26px rgba(0,0,0,.17) !important;
}

/* ── 5. PRESET CHIPS — floating ───────────────────────────────────── */
.ai-panel .ai-presets { background: none !important; border: none !important; padding: 2px !important; flex-shrink: 0; }
.ai-panel .ai-preset,
[data-theme="dark"] .ai-panel .ai-preset {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  backdrop-filter: none !important;
  border-radius: 999px !important;
  box-shadow: 0 2px 5px rgba(0,0,0,.1), 0 6px 16px rgba(0,0,0,.13);
  transition: transform .15s var(--ease), box-shadow .15s;
}
.ai-panel .ai-preset:hover { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0,0,0,.14), 0 12px 26px rgba(0,0,0,.18); }

/* ── 6. INPUT BAR — floating pill ─────────────────────────────────── */
.ai-panel .ai-input,
[data-theme="dark"] .ai-panel .ai-input {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-top-color: var(--border) !important;
  border-radius: 999px !important;
  box-shadow: 0 2px 8px rgba(0,0,0,.14), 0 12px 30px rgba(0,0,0,.2) !important;
  margin: 0 2px 2px;
  padding: 6px 6px 6px 16px !important;
  flex-shrink: 0;
}
.ai-panel .ai-input textarea,
[data-theme="dark"] .ai-panel .ai-input textarea {
  background: none !important;
  border: none !important;
  color: var(--text) !important;
}
.ai-panel .ai-send { border-radius: 50% !important; flex-shrink: 0; }

/* usage / history popovers still need a solid backing */
.ai-panel .ai-usage-panel {
  background: var(--surface) !important;
  border: 1px solid var(--border) !important;
  border-radius: 18px !important;
  box-shadow: 0 10px 30px rgba(0,0,0,.22);
  margin: 0 2px;
}

/* ── 7. FULLSCREEN ─────────────────────────────────────────────────
   NOTE: `[data-theme="dark"] .ai-panel` above is specificity (0,2,0) —
   the same as `.ai-panel.fullscreen` in app.css — and this file loads
   later, so it was winning and pinning the width to 390px. These rules
   are (0,3,0) so fullscreen actually takes over.                      */
html .ai-panel.fullscreen,
[data-theme="dark"] .ai-panel.fullscreen {
  width: 100vw !important;
  max-width: 100vw !important;
  height: 100vh !important;
  left: 0 !important; top: 0 !important;
  right: auto !important; bottom: auto !important;
  background: var(--bg) !important;
  border-radius: 0 !important;
  padding: 22px 20px !important;
  gap: 14px;
  align-items: center;              /* centre the stack of floating parts */
}
/* Each part keeps its own floating container, just centred and wider */
html .ai-panel.fullscreen .ai-head,
html .ai-panel.fullscreen > div:has(> #ai-machine-sel),
html .ai-panel.fullscreen .ai-body,
html .ai-panel.fullscreen .ai-presets,
html .ai-panel.fullscreen .ai-input,
html .ai-panel.fullscreen .ai-usage-panel {
  width: 100%;
  max-width: 860px;
}
html .ai-panel.fullscreen .ai-body {
  padding: 8px 4px !important;
  gap: 16px !important;
}
/* bubbles can breathe on a big screen, but stay individual cards */
html .ai-panel.fullscreen .ai-msg { max-width: 74%; font-size: 14px; }
html .ai-panel.fullscreen .ai-presets { display: flex; flex-wrap: wrap; gap: 8px; }
/* the blob is meaningless in fullscreen — hidden from JS via .hidden */

/* ── 9. BLOB MASCOT — eyes that look around ───────────────────────── */
.ai-fab {
  overflow: visible !important;
  cursor: grab;
  touch-action: none;          /* let us drag it on touch screens */
}
.ai-fab:active { cursor: grabbing; }
/* the idle bob uses transform — kill it while dragging so it can't fight
   the left/top we are setting */
.ai-fab[style*="left"] { animation: none !important; }
/* smooth slide when parking / popping out of an edge */
.ai-fab { transition: left .3s cubic-bezier(.34,1.56,.64,1),
                      top  .3s cubic-bezier(.34,1.56,.64,1),
                      box-shadow .2s; }

/* ── 9c. EDGE PEEK — half the blob tucked off screen ──────────────── */
.ai-fab.peek-left, .ai-fab.peek-right {
  animation: none !important;
  box-shadow: 0 6px 22px rgba(37,99,235,.5) !important;
}
/* hide the eye that sits on the off-screen half */
.ai-fab.peek-left  .ai-eye:first-child { opacity: 0; }
.ai-fab.peek-right .ai-eye:last-child  { opacity: 0; }
.ai-fab.peek-left  .ai-eye, .ai-fab.peek-right .ai-eye { transition: opacity .2s; }
/* squash it against the edge it is pressed into */
.ai-fab.peek-left  { border-radius: 0 50% 50% 0 / 0 50% 50% 0 !important; }
.ai-fab.peek-right { border-radius: 50% 0 0 50% / 50% 0 0 50% !important; }
/* the tooltip would hang off screen while parked */
.ai-fab.peek-left .ai-fab-tip, .ai-fab.peek-right .ai-fab-tip { display: none; }

/* ── 9d. ALARM CHIP — sits above the blob ─────────────────────────────
   Shown only while a machine is actually in alarm. A chip that is always
   there stops being read, so this one earns attention by being rare. */
.ai-fab-alarm {
  position: absolute;
  /* ANCHORED TO THE BLOB'S RIGHT EDGE, GROWING LEFT (22 Sep 2026).
     It used to be centred on the blob (left:50%, translateX(-50%)) while the
     blob sits 26px from the right edge, so a real alarm line -- "VMC-5:
     ALM-501: (X)-AXIS..." -- ran straight off the screen and the operator saw
     half of it. A speech bubble opening to the left always has room. */
  bottom: calc(100% + 12px);
  right: 0;
  left: auto;
  transform: none;
  display: block;
  width: max-content;
  max-width: min(330px, calc(100vw - 48px));
  padding: 9px 12px;
  border-radius: 14px 14px 4px 14px;   /* chat bubble: tail corner at the blob */
  background: #dc2626;
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.35;
  white-space: normal;                 /* wrap instead of cutting the text */
  overflow: hidden;
  text-align: left;
  box-shadow: 0 6px 18px rgba(220, 38, 38, .42);
  pointer-events: none;              /* the blob underneath takes the tap */
  z-index: 3;
  animation: aiAlarmPulse 1.8s ease-in-out infinite;
}
/* the machine name, then one line per alarm -- like a message, not a label */
.ai-fab-alarm .aia-name {
  display: flex; align-items: center; gap: 6px;
  font-size: 12.5px; font-weight: 800; margin-bottom: 2px;
}
.ai-fab-alarm .aia-name::before {
  content: '';
  width: 7px; height: 7px; border-radius: 50%;
  background: #fff; flex: none;
}
.ai-fab-alarm .aia-line {
  display: block;
  font-weight: 600;
  opacity: .96;
  /* two lines per alarm is plenty; the full text is in the tooltip and on
     the machine card. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.ai-fab-alarm .aia-more { display: block; opacity: .85; font-weight: 600; margin-top: 3px; }
/* little tail pointing down at the blob */
.ai-fab-alarm::after {
  content: '';
  position: absolute; right: 16px; bottom: -5px;
  width: 10px; height: 10px; background: #dc2626;
  transform: rotate(45deg); border-radius: 2px;
}
/* Dragged to the left half of the screen: open to the RIGHT instead, or the
   bubble would hang off that edge just as badly. */
.ai-fab.alarm-left .ai-fab-alarm {
  right: auto; left: 0;
  border-radius: 14px 14px 14px 4px;
}
.ai-fab.alarm-left .ai-fab-alarm::after { right: auto; left: 16px; }
/* Parked half off screen, the bubble must not go with it. */
.ai-fab.peek-left  .ai-fab-alarm { right: auto; left: 34px; }
.ai-fab.peek-right .ai-fab-alarm { right: 34px; left: auto; }

@keyframes aiAlarmPulse {
  0%, 100% { box-shadow: 0 6px 18px rgba(220, 38, 38, .42); }
  50%      { box-shadow: 0 6px 26px rgba(220, 38, 38, .75); }
}
@media (prefers-reduced-motion: reduce) {
  .ai-fab-alarm { animation: none; }
}

.ai-fab svg { display: none; }              /* old robot icon — replaced by eyes */
.ai-eyes {
  display: flex; gap: 9px; align-items: center;
  pointer-events: none; position: relative; z-index: 2;
  transition: transform .18s cubic-bezier(.22,.61,.36,1);
}
.ai-eye {
  width: 13px; height: 13px; border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(8,15,30,.3), inset 0 -2px 3px rgba(8,15,30,.1);
  transition: transform .12s ease;
  transform-origin: center;
}
/* blink is driven from JS so the timing feels random, not metronomic */
.ai-fab.blink .ai-eye { transform: scaleY(.1); }
/* one-eye wink */
.ai-fab.wink .ai-eye:first-child { transform: scaleY(.1); }

/* thinking — blob wobbles, eyes roll */
.ai-fab.thinking { animation: aiBlobThink 1.1s ease-in-out infinite !important; }
.ai-fab.thinking .ai-eyes { animation: aiEyeRoll 1.4s ease-in-out infinite; }
@keyframes aiBlobThink {
  0%,100% { transform: rotate(-6deg) scale(1,1); }
  50%     { transform: rotate(6deg)  scale(1.05,.95); }
}
@keyframes aiEyeRoll {
  0%,100% { transform: translate(-3px,-2px); }
  25%     { transform: translate(3px,-2px); }
  50%     { transform: translate(3px,2px); }
  75%     { transform: translate(-3px,2px); }
}

/* click squash */
.ai-fab.poke { animation: aiPoke .45s cubic-bezier(.34,1.56,.64,1) !important; }
@keyframes aiPoke {
  0%   { transform: scale(1,1); }
  30%  { transform: scale(1.2,.78) translateY(6px); }
  55%  { transform: scale(.88,1.16) translateY(-8px); }
  78%  { transform: scale(1.06,.95) translateY(2px); }
  100% { transform: scale(1,1) translateY(0); }
}

/* ── 9b. BLOB EMOTIONS ────────────────────────────────────────────── */
/* happy — squinty ^ ^ smile (on click) */
.ai-fab.happy .ai-eye {
  height: 5px !important;
  border-radius: 8px 8px 3px 3px !important;
  transform: scaleX(1.25);
}
.ai-fab.happy { animation: aiHappyHop .7s ease-in-out !important; }
@keyframes aiHappyHop {
  0%,100% { transform: translateY(0)    scale(1,1); }
  30%     { transform: translateY(-9px) scale(.94,1.08); }
  60%     { transform: translateY(0)    scale(1.06,.94); }
}

/* typing — eyes shrink and look down at the input */
.ai-fab.typing .ai-eyes { transform: translateY(3.5px) !important; }
.ai-fab.typing .ai-eye  { height: 9px !important; width: 11px !important; }

/* wow — wide eyes when the answer lands */
.ai-fab.wow .ai-eye { width: 16px !important; height: 16px !important; }
.ai-fab.wow { animation: aiWowPop .5s cubic-bezier(.34,1.56,.64,1) !important; }
@keyframes aiWowPop {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.14); }
  100% { transform: scale(1); }
}

/* thinking overrides cursor-tracking */
.ai-fab.thinking .ai-eyes { transition: none; }

/* ── 10. Feedback thumbs ──────────────────────────────────────────── */
.ai-fb button { background: var(--surface-2) !important; border-color: var(--border) !important; }

/* ── 12. Light blur behind the panel while AI is open ─────────────── */
.ai-scrim {
  display: block !important;
  position: fixed; inset: 0; z-index: 90;
  background: rgba(8,15,30,.18);
  backdrop-filter: blur(3px) saturate(.9);
  -webkit-backdrop-filter: blur(3px) saturate(.9);
  opacity: 0; pointer-events: none;
  transition: opacity .28s var(--ease);
}
.ai-scrim.open { opacity: 1; }        /* stays click-through: clicks fall to the page handler */
[data-theme="dark"] .ai-scrim { background: rgba(0,0,0,.34); }
/* panel + blob must sit above the blur */
.ai-panel { z-index: 100 !important; }
.ai-fab   { z-index: 101 !important; }

/* ── 11. Mobile ───────────────────────────────────────────────────── */
@media (max-width: 640px) {
  .ai-panel { width: calc(100vw - 24px) !important; }
}


/* ── "Build this screen" card — shown when Lumo writes a dashboard prompt ── */
.ai-build-card{
  margin-top:10px;padding:12px 14px;border-radius:12px;
  background:rgba(41,121,255,.10);border:1px solid rgba(41,121,255,.35);
}
.ai-build-title{font-size:13px;font-weight:700;color:#fff;margin-bottom:2px}
.ai-build-sub{font-size:11px;color:rgba(255,255,255,.55);margin-bottom:10px}
.ai-build-btn{
  width:100%;padding:8px 14px;border-radius:9px;border:none;cursor:pointer;
  background:#2979ff;color:#fff;font-size:12.5px;font-weight:700;
  font-family:inherit;transition:background .15s;
}
.ai-build-btn:hover{background:#1c66e0}

/* ── Report ready card ─────────────────────────────────────────────────── */
.ai-report-card{
  margin-top:10px;padding:12px 14px;border-radius:12px;
  background:rgba(200,120,14,.10);border:1px solid rgba(200,120,14,.35);
  display:flex;align-items:center;gap:10px;
}
.ai-report-icon{font-size:22px;flex-shrink:0}
.ai-report-info{flex:1;min-width:0}
/* Take the text colour from the theme. Hard-coding near-white here made the
   card unreadable in light mode, which is the app's default. */
.ai-report-title{font-size:13px;font-weight:700;color:var(--text,#0f1b2d);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ai-report-date{font-size:11px;color:var(--text-3,#6b88a8);margin-top:1px}
.ai-report-btns{display:flex;gap:7px;flex-shrink:0}
.ai-report-btn-preview{
  padding:7px 12px;border-radius:8px;border:1px solid rgba(200,120,14,.5);
  cursor:pointer;background:transparent;color:#c8780e;
  font-size:11.5px;font-weight:600;font-family:inherit;
  transition:background .15s;white-space:nowrap;
}
.ai-report-btn-preview:hover{background:rgba(200,120,14,.15)}
.ai-report-btn-dl{
  padding:7px 12px;border-radius:8px;border:none;cursor:pointer;
  background:#c8780e;color:#fff;font-size:11.5px;font-weight:700;
  font-family:inherit;transition:background .15s;white-space:nowrap;
}
.ai-report-btn-dl:hover{background:#a86510}

/* ── Fullscreen report preview overlay ─────────────────────────────────── */
#ai-preview-overlay{
  position:fixed;inset:0;z-index:99999;
  background:#060c12;
  display:flex;flex-direction:column;
  animation:ai-preview-in .18s ease;
}
@keyframes ai-preview-in{from{opacity:0;transform:scale(.97)}to{opacity:1;transform:scale(1)}}
.ai-preview-bar{
  display:flex;align-items:center;justify-content:space-between;
  padding:10px 18px;background:#0d1821;
  border-bottom:2px solid #c8780e;flex-shrink:0;
}
.ai-preview-label{font-size:13px;font-weight:700;color:#f0f4f8}
.ai-preview-actions{display:flex;gap:8px}
.ai-preview-dl{
  padding:6px 14px;border-radius:8px;border:1px solid rgba(200,120,14,.5);
  cursor:pointer;background:transparent;color:#c8780e;
  font-size:12px;font-weight:600;font-family:inherit;
  text-decoration:none;display:inline-flex;align-items:center;
}
.ai-preview-dl:hover{background:rgba(200,120,14,.15)}
.ai-preview-close{
  padding:6px 14px;border-radius:8px;border:none;cursor:pointer;
  background:#c8780e;color:#fff;font-size:12px;font-weight:700;font-family:inherit;
}
.ai-preview-close:hover{background:#a86510}
.ai-preview-frame{
  flex:1;width:100%;border:none;background:#fff;
}

/* ── HTML report preview (mirrors the PDF layout) ───────────────────────── */
.ai-preview-scroll{flex:1;overflow-y:auto;background:#e9edf3;padding:22px 12px 40px}
.ai-rep-page{
  max-width:820px;margin:0 auto;background:#fff;color:#0f1b2d;
  border-radius:6px;overflow:hidden;box-shadow:0 6px 28px rgba(0,0,0,.35);
  font-family:'Segoe UI',Helvetica,Arial,sans-serif;
}
.ai-rep-head{display:flex;align-items:center;gap:16px;background:#0f1f35;padding:14px 20px}
/* The logo is a wide lockup on a light ground, so it gets a white plate to
   sit on rather than being dropped straight onto the navy. */
.ai-rep-plate{background:#fff;border-radius:4px;padding:6px 8px;flex-shrink:0;line-height:0}
.ai-rep-plate img{height:44px;width:auto;display:block}
.ai-rep-brand{flex:1;min-width:0}
.ai-rep-kicker{font-size:9px;font-weight:700;color:#fbbf24;letter-spacing:.7px}
.ai-rep-mach{font-size:20px;font-weight:700;color:#fff;line-height:1.2;margin-top:1px}
.ai-rep-tiny{font-size:9px;color:#7d90ac;margin-top:3px}
.ai-rep-meta{text-align:right;flex-shrink:0}
.ai-rep-gen{font-size:10px;color:#c3d0e4;font-weight:600}
.ai-rep-period{
  background:#213650;color:#fbbf24;font-size:11px;font-weight:700;
  padding:7px 20px;letter-spacing:.2px;
}
.ai-rep-body{padding:18px 20px 24px}
.ai-rep-sec{margin-bottom:18px}
.ai-rep-sec-h{
  background:#0f1f35;color:#fff;font-size:11px;font-weight:700;
  padding:7px 12px;letter-spacing:.6px;
}
.ai-rep-tbl{width:100%;border-collapse:collapse;font-size:12px}
.ai-rep-tbl th{
  background:#213650;color:#fff;font-size:10px;font-weight:700;
  padding:7px 8px;text-align:center;letter-spacing:.3px;
}
.ai-rep-tbl td{padding:6px 10px;color:#0f1b2d}
.ai-rep-tbl tbody tr{background:#f8fafc}
.ai-rep-tbl tbody tr.odd{background:#f0f4ff}
.ai-rep-tbl:not(.kv) td{text-align:center}
.ai-rep-tbl.kv td.k{width:62%}
.ai-rep-tbl.kv td.v{font-weight:700;text-align:left}
.ai-rep-sum{
  background:#f8fafc;padding:12px 14px;font-size:12px;line-height:1.65;color:#0f1b2d;
}
.ai-rep-foot{
  display:flex;justify-content:space-between;align-items:center;
  background:#0f1f35;padding:10px 20px;font-size:10px;font-weight:600;color:#c3d0e4;
}
.ai-rep-foot span:last-child{color:#a78bfa}
@media(max-width:640px){
  .ai-rep-head{flex-wrap:wrap;gap:10px}
  .ai-rep-meta{text-align:left}
  .ai-rep-tbl{font-size:11px}
  .ai-rep-tbl td{padding:5px 7px}
}

/* ── Live voice on the Lumo blob (14 Sep) ──────────────────────────────── */
.ai-fab.lv-listening { animation: none !important; background: linear-gradient(135deg, #0ea5e9, #2563eb); }
.ai-fab.lv-listening::after {
  opacity: 1; border-color: rgba(14,165,233,.7);
  animation: lvListen 1.6s ease-out infinite;
}
@keyframes lvListen {
  0%   { opacity: .8; transform: scale(.95); }
  100% { opacity: 0;  transform: scale(1.55); }
}
.ai-fab.lv-speaking, .ai-fab.lv-speaking[style*="left"] { animation: lvTalk .5s ease-in-out infinite alternate !important;
  background: linear-gradient(135deg, #8b5cf6, #ec4899); }
.ai-fab.lv-speaking::after {
  opacity: 1; border-color: rgba(236,72,153,.75);
  animation: lvListen .8s ease-out infinite;
}
.ai-fab.lv-speaking .ai-eye { animation: lvEye .5s ease-in-out infinite alternate; }
@keyframes lvTalk {
  from { transform: scale(1, 1); }
  to   { transform: scale(1.08, .94); }
}
@keyframes lvEye {
  from { transform: scaleY(1); }
  to   { transform: scaleY(.55); }
}
@media (prefers-reduced-motion: reduce) {
  .ai-fab.lv-listening::after, .ai-fab.lv-speaking, .ai-fab.lv-speaking::after,
  .ai-fab.lv-speaking .ai-eye { animation: none; }
}
