/* ============================================================================
 * 创归思伴学 · 通用 AI 协作侧边面板（AiSidePanel）
 * ------------------------------------------------------------
 * 职责（公共组件，零业务逻辑）：
 *   对话展示 / 用户输入 / 语音陪练开关（占位）/ 动态快捷推荐按钮。
 *   只渲染 UI、抛出事件（onSendMessage / onQuickBtnClick / onPanelToggle /
 *   onVoiceAssistChange / onMicClick），业务由调用方实现。
 *
 * 通用约束（强）：
 *   ① 全站通用：错题本 · 随堂充电 · 找坑修复 · 闯关进阶 及未来新增页统一复用，
 *      禁止拷贝多份；调用方通过 props 注入 roleLabel / messages / quickButtons，
 *      通过 events 接回业务。
 *   ② 主题跟随：本文件**只引用全局 CSS 变量**，自动切换「暗灰紫夜间 / 浅色教育白天」。
 *      组件内禁止写死任何色值（含 rgba 字面量）——一切走 var()，带安全兜底。
 *   ③ 折叠：展开 280px / 收起 64px；折叠按钮在面板与相邻区域分割条上。
 *      收起仅显示头像 + 展开按钮，内部全隐藏；收起强制关闭自动语音（杜绝隐形出声）。
 *   ④ 语音陪练开关（组件内固化）：仅控「业务大环节切换时的自动 TTS 播报」，
 *      不隐藏对话文字 / 快捷按钮；开关切换只改语音状态，不增删 DOM，避免布局抖动。
 *      V1.0 为置灰占位（不发声）；V1.1 接 TTS。麦克风语音提问不受此开关控制。
 * ============================================================================ */

.ai-side-panel{
  /* —— 全站统一设计令牌（2026-09-19 规格固化 · 单一真源）——
     面板底 #F9F7FF / 右分割线 #EFEAF8 / AI 气泡 #F0EBFF / 用户气泡·主按钮 #7F4AE0 / 正文 #221838。
     组件自带字面量基线 → 未注入令牌的页面自动获得同一套观感；页面或暗色块可用同名 --asp-* 覆盖。
     暗色不在此写死（见下方 html[data-theme="dark"] 块，走页面语义变量，夜间自动适配）。 */
  --asp-bg:        #F9F7FF;
  --asp-surface:   #FFFFFF;
  --asp-surface-2: #F0EBFF;
  --asp-ink:       #221838;
  --asp-muted:     #6B6382;   /* [2026-09-19] 原 #998FB8 在 #F9F7FF 上仅 2.83:1 → 压深至 5.37:1 */
  --asp-line:      #E7DEFB;
  --asp-track:     #E7DEFB;
  --asp-edge:      #EFEAF8;   /* 规格：右侧 1px 浅紫分割线 */
  --asp-brand:     linear-gradient(135deg,#8B6FE8,#7F4AE0);
  --asp-brand-solid: #7F4AE0;   /* 品牌**填充**（主按钮 / 用户气泡 / 头像底）：压白字 5.31:1 */
  --asp-brand-ink:   #7F4AE0;   /* 品牌**文字/图标**（面板底上）：压 #F9F7FF 5.00:1 */
  --asp-online:    #34C77B;
  --asp-on-brand:  #ffffff;            /* 品牌实底上的文字色（白字压主紫 #7F4AE0 = 5.31:1） */
  --asp-shadow:    var(--shell-shadow-1, 0 6px 22px rgba(44,44,42,.07));
  --asp-radius:    var(--shell-radius, 14px);
  --asp-w:         290px;   /* 规格：全站固定 290px，不忽大忽小 */
  --asp-pad:       16px;    /* 规格：内部安全内边距（内容不贴死边框） */

  /* —— 布局 —— */
  position: relative;
  display: flex;
  flex-direction: column;
  width: var(--asp-w, 290px);
  min-width: 0;
  height: 100%;
  min-height: 0;
  background: var(--asp-bg);
  color: var(--asp-ink);
  border-right: 1px solid var(--asp-edge);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
  font-size: 14px;
  line-height: 1.55;
  overflow: visible; /* 不裁剪折叠分割条（right:-13px 跨在分割线上）；内部滚动由 .asp-body/.asp-msgs 各自处理 */
  transition: transform .3s cubic-bezier(.22,.61,.36,1), visibility 0s linear 0s,
              background .26s ease, color .26s ease;
}
.ai-side-panel *{ box-sizing: border-box; }

/* 夜间主题自动适配：不写死色值，直接吸收页面已有的语义令牌（error-book / shell.css / station-shell 都提供） */
html[data-theme="dark"] .ai-side-panel{
  --asp-bg:        var(--shell-surface, #1E1A2B);
  --asp-surface:   var(--card, #241F33);
  --asp-surface-2: var(--shell-surface-2, #2A2540);
  --asp-line:      var(--line, #352F47);
  --asp-track:     var(--line, #352F47);
  --asp-edge:      var(--line, #352F47);
  --asp-brand:     var(--shell-brand, linear-gradient(135deg,#8E7BFF,#36D2D2));
  /* 暗档：#8E7BFF 压白字只有 3.27:1 → 填充色取深一档（白字 4.86:1）；
     文字/图标反过来要亮紫（压 #2A2540 为 5.45:1）。两个方向不能共用一个色，故分令牌。 */
  --asp-brand-solid: #7A55E8;
  --asp-brand-ink:   #A98BFF;
  --asp-ink:       var(--ink, #ECE9F6);
  --asp-muted:     var(--muted, #A79FB8);
}
/* 收起手柄 .asp-recall 是 .ai-side-panel 的**兄弟**节点（挂在挂载点内），
   拿不到面板自身那套 --asp-* → 暗色下必须单独给，否则深色页会冒出一枚浅色方块。 */
html[data-theme="dark"] .asp-recall{
  background: var(--shell-surface, #1E1A2B);
  border-color: var(--line, #352F47);
  color: var(--asp-brand-ink, #A98BFF);
  box-shadow: 0 6px 18px rgba(0,0,0,.45);
}
html[data-theme="dark"] .asp-recall:hover{
  background: var(--shell-surface-2, #2A2540);
  color: #FFFFFF;
  box-shadow: 0 8px 22px rgba(143,90,240,.35);
}

/* ---------- 折叠分割条按钮（面板与相邻区域的分割条上） ---------- */
.asp-split{
  position: absolute;
  top: 50%;
  right: -13px;
  transform: translateY(-50%);
  z-index: 5;
  width: 26px;
  height: 52px;
  display: grid;
  place-items: center;
  border: 1px solid var(--asp-track);
  border-left: 0;
  border-radius: 0 10px 10px 0;
  background: var(--asp-surface);
  color: var(--asp-muted);
  cursor: pointer;
  font-family: inherit;
  font-size: 13px;
  padding: 0;
  box-shadow: var(--asp-shadow);
  transition: color .18s ease, background .18s ease;
}
.asp-split:hover{ color: var(--asp-brand-ink); background: var(--asp-surface-2); }

/* ---------- 头部：头像 + 角色姿态 + 在线 + 语音陪练开关 ---------- */
.asp-head{
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px var(--asp-pad, 16px) 12px;
  border-bottom: 1px solid var(--asp-track);
  min-height: 0;
}
.asp-avatar{
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border-radius: 50%;           /* 规格：圆形品牌紫头像 */
  overflow: hidden;
  display: grid;
  place-items: center;
  background: var(--asp-brand-solid);
  color: var(--asp-on-brand);
  box-shadow: 0 0 0 1px rgba(127,74,224,.16);
  font-weight: 800;
  font-size: 13px;
}
.asp-avatar svg, .asp-avatar img{ display: block; width: 100%; height: 100%; object-fit: cover; }
.asp-id{ flex: 1 1 auto; min-width: 0; }
.asp-role{
  font-size: 14px;
  font-weight: 800;
  color: var(--asp-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 角色名下方标语（可选）：如「只引导、不代答、帮你找思维陷阱」 */
.asp-tagline{
  font-size: 11px;
  line-height: 1.35;
  color: var(--asp-muted);
  margin-top: 1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.asp-status{
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11.5px;
  color: var(--asp-muted);
  margin-top: 2px;
}
.asp-dot{
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--asp-online);
  display: inline-block; flex: 0 0 auto;
}
/* 语音陪练开关（V1.0 置灰占位：不发声，但状态机/记忆已固化，V1.1 仅接 TTS） */
.asp-voice{
  flex: 0 0 auto;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: 10px;
  border: 1px solid var(--asp-track);
  background: var(--asp-surface-2);
  color: var(--asp-muted);
  cursor: pointer;
  font-size: 15px;
  padding: 0;
  font-family: inherit;
  transition: color .18s ease, border-color .18s ease, background .18s ease;
}
.asp-voice:hover:not([disabled]){ color: var(--asp-brand-ink); border-color: var(--asp-brand-ink); }
.asp-voice[aria-pressed="true"]{
  color: var(--asp-on-brand);
  background: var(--asp-brand-solid);
  border-color: var(--asp-brand-solid);
}
.asp-voice[disabled]{
  opacity: .5;
  cursor: not-allowed;
  filter: grayscale(.4);
}
/* V1.1 语音播报中：按钮脉冲提示（最长 12s 由 JS 兜底熄灭） */
.asp-voice.is-speaking{
  animation: asp-voice-pulse 1.1s ease-in-out infinite;
}
@keyframes asp-voice-pulse{
  0%,100%{ box-shadow: 0 0 0 0 rgba(109,94,252,.45); }
  50%{ box-shadow: 0 0 0 6px rgba(109,94,252,0); }
}

/* ---------- 中部对话滚动区 ---------- */
.asp-body{
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.asp-msgs{
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 14px var(--asp-pad, 16px);
  display: flex;
  flex-direction: column;
  gap: 9px;
  scrollbar-width: thin;
}
.asp-statusline{
  flex: 0 0 auto;
  min-height: 14px;
  font-size: 11px;
  color: var(--asp-muted);
  padding: 2px var(--asp-pad, 16px) 6px;
}
.asp-msg{
  font-size: 13px;
  line-height: 1.5;
  padding: 8px 11px;
  border-radius: 12px;
  max-width: 92%;
  word-break: break-word;
  white-space: pre-wrap;
}
.asp-msg--xb{ align-self: flex-start; background: var(--asp-surface-2); color: var(--asp-ink); border: 1px solid var(--asp-line); border-bottom-left-radius: 4px; }
.asp-msg--me{ align-self: flex-end; background: var(--asp-brand-solid); color: var(--asp-on-brand); border-bottom-right-radius: 4px; }
.asp-msg--refuse{ align-self: flex-start; background: var(--asp-surface-2); color: var(--asp-muted); border-left: 3px solid var(--asp-brand-solid); }

/* ---------- 场景卡片：头像栏下方、对话气泡上方，填充面板空白 ---------- */
.asp-scene{
  flex: 0 0 auto;
  margin: 10px var(--asp-pad, 16px) 0;
  padding: 11px 12px 12px;
  border: 1px solid var(--asp-line);
  border-radius: 12px;
  background: var(--asp-surface-2);
}
.asp-scene[data-empty="1"]{ display: none; }
.asp-scene-title{
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 800;
  color: var(--asp-ink);
  margin-bottom: 7px;
}
.asp-scene-title::before{
  content: '';
  width: 4px; height: 13px;
  border-radius: 3px;
  background: var(--asp-brand-solid);
  flex: 0 0 auto;
}
.asp-scene-line{
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--asp-ink);
  padding: 2px 0;
}
.asp-scene-ico{ flex: 0 0 auto; font-size: 12.5px; }
.asp-scene-text{ flex: 1 1 auto; min-width: 0; }
.asp-scene-hint{
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--asp-line);
  font-size: 11.5px;
  color: var(--asp-muted);
  line-height: 1.5;
}

/* ---------- 今日一句话引导：短文本、每次刷新只出现一次、不循环 ---------- */
.asp-guide{
  flex: 0 0 auto;
  margin: 8px var(--asp-pad, 16px) 0;
  padding: 8px 10px 8px 12px;
  border-left: 3px solid var(--asp-brand-solid);
  border-radius: 0 10px 10px 0;
  background: var(--asp-surface-2);
  color: var(--asp-ink);
  font-size: 12.5px;
  line-height: 1.55;
}
.asp-guide[data-empty="1"]{ display: none; }
.asp-guide b{ color: var(--asp-brand-ink); font-weight: 800; }

/* ---------- 上下文引导卡（.asp-ctx）：联动「中间大盘 -> 左栏」的替换式落点 ----------
   规格（2026-09-19 联动需求）：
   · 全局面板里**永远只有 1 个** —— 重复点击同一项不重刷、也不往气泡区追加（气泡区只留当前对话）
   · 摘要 1~2 行常显；完整引导默认折叠，点「展开完整引导」才出现（大段文字不堆满侧栏）
   · 位置在「当前学习任务」卡下方、气泡区上方 -> flex:0 0 auto，不随气泡滚动
   · 底部快捷按钮另有 .asp-foot{flex:0 0 auto} 兜底，长消息不会把它挤出可视区 */
.asp-ctx{
  flex: 0 0 auto;
  margin: 8px var(--asp-pad, 16px) 0;
  padding: 10px 12px;
  border: 1px solid var(--asp-line);
  border-left: 3px solid var(--asp-brand-ink);
  border-radius: 0 10px 10px 0;
  background: var(--asp-surface-2);
  color: var(--asp-ink);
}
.asp-ctx[data-empty="1"]{ display: none; }
.asp-ctx-hd{ display: flex; align-items: center; gap: 6px; }
.asp-ctx-kicker{ flex: 0 0 auto; font-size: 10px; font-weight: 800; letter-spacing: .5px; color: var(--asp-brand-ink); }
.asp-ctx-title{ flex: 1 1 auto; min-width: 0; font-size: 12.5px; font-weight: 800; color: var(--asp-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.asp-ctx-n{ flex: 0 0 auto; font-size: 11px; font-weight: 800; color: var(--asp-brand-ink); }
.asp-ctx-clear{ flex: 0 0 auto; margin-left: auto; width: 20px; height: 20px; padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--asp-muted); font-size: 15px; line-height: 1; cursor: pointer; }
.asp-ctx-clear:hover{ background: var(--asp-line); color: var(--asp-ink); }
.asp-ctx-clear:focus-visible{ outline: 2px solid var(--asp-brand-solid); outline-offset: 1px; }
.asp-ctx-sum{ margin-top: 5px; font-size: 12.5px; line-height: 1.6; }
.asp-ctx-toggle{ margin-top: 6px; padding: 0; border: 0; border-radius: 4px; background: transparent; color: var(--asp-brand-ink); font-size: 11.5px; font-weight: 700; cursor: pointer; }
.asp-ctx-toggle:hover{ text-decoration: underline; }
.asp-ctx-toggle:focus-visible{ outline: 2px solid var(--asp-brand-solid); outline-offset: 2px; }
.asp-ctx-detail{ margin-top: 6px; padding-top: 6px; border-top: 1px dashed var(--asp-line); font-size: 12px; line-height: 1.68; color: var(--asp-muted); }
.asp-ctx-detail[hidden]{ display: none; }
.asp-ctx-detail ol, .asp-ctx-detail ul{ margin: 4px 0 0; padding-left: 18px; }
.asp-ctx-detail li{ margin: 3px 0; }
.asp-ctx-detail b{ color: var(--asp-ink); font-weight: 800; }

/* ---------- 气泡区「更早的对话」折叠条：只常显当前对话，历史收拢可展开 ---------- */
.asp-more{
  align-self: center;
  margin: 0 0 2px;
  padding: 3px 10px;
  border: 1px dashed var(--asp-line);
  border-radius: 999px;
  background: transparent;
  color: var(--asp-muted);
  font-size: 11px;
  cursor: pointer;
}
.asp-more:hover{ color: var(--asp-brand-ink); border-color: var(--asp-brand-ink); }
.asp-more:focus-visible{ outline: 2px solid var(--asp-brand-solid); outline-offset: 2px; }

/* ---------- 底部：输入 + 快捷按钮 ---------- */
.asp-foot{
  flex: 0 0 auto;
  border-top: 1px solid var(--asp-track);
  padding: 10px var(--asp-pad, 16px) 12px;
  background: var(--asp-surface);
}
.asp-input-row{
  display: flex;
  gap: 7px;
  align-items: stretch;
}
.asp-input{
  flex: 1 1 auto;
  min-width: 0;
  border: 1px solid var(--asp-track);
  border-radius: 10px;
  padding: 8px 10px;
  font-size: 13px;
  font-family: inherit;
  background: var(--asp-bg);
  color: var(--asp-ink);
  outline: none;
}
.asp-input::placeholder{ color: var(--asp-muted); }
.asp-input:focus{ border-color: var(--asp-brand-ink); }
.asp-mic{
  flex: 0 0 auto;
  width: 38px;
  border: 1px solid var(--asp-track);
  border-radius: 10px;
  background: var(--asp-surface-2);
  color: var(--asp-brand-ink);
  cursor: pointer;
  font-size: 15px;
  padding: 0;
  font-family: inherit;
  transition: color .18s ease, background .18s ease;
}
.asp-mic:hover{ background: var(--asp-surface); }
.asp-mic.is-rec{ background: var(--asp-brand-solid); color: var(--asp-on-brand); border-color: var(--asp-brand-solid); }
.asp-send{
  flex: 0 0 auto;
  border: 0;
  border-radius: 10px;
  padding: 0 14px;
  background: var(--asp-brand-solid);
  color: var(--asp-on-brand);
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  font-family: inherit;
}
.asp-send:hover{ filter: brightness(1.06); }
.asp-hint{ font-size: 11px; color: var(--asp-muted); margin: 6px 1px 0; min-height: 14px; }
.asp-hint:empty{ display: none; }

/* 快捷推荐按钮组（外部传入，最多 4 个，第一个为主推荐） */
.asp-chips{
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 9px;
}
.asp-chip{
  border: 1px solid var(--asp-track);
  border-radius: 999px;
  background: var(--asp-surface-2);
  color: var(--asp-brand-ink);
  cursor: pointer;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 12px;
  transition: transform .12s ease, border-color .12s ease, background .12s ease;
}
.asp-chip:hover{ transform: translateY(-1px); border-color: var(--asp-brand-ink); }
.asp-chip--primary{
  background: var(--asp-brand-solid);
  color: var(--asp-on-brand);
  border-color: var(--asp-brand-solid);
}
.asp-chip--primary:hover{ color: var(--asp-on-brand); filter: brightness(1.06); }

/* ---------- 快捷按钮三态（2026-09-20）：置灰保位 / tooltip / 整组 loading ----------
   置灰一律「保位不隐藏」：4 个按钮的数量与排布是硬约束，隐藏会破掉视觉节奏。 */
.asp-chip.is-disabled{
  opacity: .5;
  cursor: not-allowed;
  filter: grayscale(.75);
}
.asp-chip.is-disabled:hover{ transform: none; border-color: var(--asp-track); }
.asp-chip.is-disabled.asp-chip--primary:hover{ filter: grayscale(.75) brightness(1); color: var(--asp-on-brand); }
.asp-chips.is-busy{ opacity: .55; pointer-events: none; }

/* ---------- AI 气泡内快捷动作按钮（如「去随堂充电」） ---------- */
.asp-actions{
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}
.asp-action-btn{
  border: 1px solid var(--asp-brand-solid);
  border-radius: 999px;
  background: var(--asp-brand-solid);
  color: var(--asp-on-brand);
  cursor: pointer;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 700;
  padding: 6px 14px;
  transition: transform .12s ease, filter .15s ease;
}
.asp-action-btn:hover{ transform: translateY(-1px); filter: brightness(1.06); }
.asp-action-btn:active{ transform: translateY(0); }

/* ---------- AI 长文本折叠（2026-09-20）----------
   默认收起 3 行 + 末行渐隐 + 「展开全文」；展开后按钮变「收起」。
   短话术不带 .is-fold，完全不受影响；遮罩用 mask-image，不依赖固定高度。 */
.asp-msg.is-fold{ position: relative; }
.asp-msg.is-fold .asp-msg-body{
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: pre-wrap;
}
.asp-msg.is-fold:not(.is-fold-open) .asp-msg-body{
  -webkit-mask-image: linear-gradient(to bottom, #000 62%, rgba(0,0,0,.15) 100%);
          mask-image: linear-gradient(to bottom, #000 62%, rgba(0,0,0,.15) 100%);
}
.asp-msg.is-fold-open .asp-msg-body{ display: block; overflow: visible; -webkit-line-clamp: unset; }
.asp-msg-more{
  display: block;
  margin: 6px 0 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--asp-brand-ink, #7F4AE0);
  cursor: pointer;
  font-family: inherit;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .02em;
  text-align: left;
}
.asp-msg-more:hover{ text-decoration: underline; }
.asp-msg-more:focus-visible{ outline: 2px solid var(--asp-brand-solid, #7F4AE0); outline-offset: 2px; border-radius: 4px; }

/* ---------- 收起态：整个面板向左完全滑出视口（不再留 64px 窄条）----------
   唤起入口 = 浏览器最左边缘的窄按钮 .asp-recall（position:fixed，挂在挂载点内、
   是面板的兄弟节点，因此不受面板 transform 影响，也不污染 body）。 */
.ai-side-panel[data-collapsed="true"]{
  transform: translateX(-100%);
  visibility: hidden;              /* 位移结束后彻底不可见 / 不可点（延迟 0s→.3s） */
  pointer-events: none;
}
/* 唤起按钮：默认不显示，仅收起态出现 */
.asp-recall{
  position: fixed;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 45;                     /* 高于页内吸顶栏(30)，低于抽屉/弹窗(60/90) */
  display: none;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 62px;
  padding: 0;
  border: 1px solid var(--asp-edge, #EFEAF8);
  border-left: 0;
  border-radius: 0 14px 14px 0;
  background: var(--asp-bg, #F9F7FF);
  color: var(--asp-brand-ink, #7F4AE0);
  box-shadow: 0 6px 18px rgba(74,48,140,.16);
  cursor: pointer;
  font-family: inherit;
  transition: width .16s ease, box-shadow .16s ease, color .16s ease;
}
.ai-side-panel[data-collapsed="true"] ~ .asp-recall{ display: flex; }
.asp-recall:hover{ width: 32px; box-shadow: 0 8px 22px rgba(74,48,140,.24); }
.asp-recall:focus-visible{ outline: 2px solid var(--asp-brand-solid, #7F4AE0); outline-offset: 2px; }
.asp-recall svg{ width: 16px; height: 16px; display: block; }

/* ---------- 窄屏：分割条按钮改双行时避免被裁（与 page.css 同规，不依赖 sticky） ---------- */
@media (max-width: 820px){
  .ai-side-panel{ width: var(--asp-w, 290px); }
}
@media (prefers-reduced-motion: reduce){
  .ai-side-panel, .asp-split, .asp-chip, .asp-voice, .asp-mic, .asp-recall{ transition: none; }
}
