/* ==========================================================================
   引擎吉祥物 · 动画层（零依赖，可复用）
   --------------------------------------------------------------------------
   适配美术：用户提供的单色扁平图标（viewBox 10 60 1014 856，1024 画布）
   颜色：默认 currentColor（#e26c05），改品牌色只要给 .xj 设 color。
   --------------------------------------------------------------------------
   分组约定（换美术时保持这套 class 即可复用本文件）：
     .xj                   根 svg
     .xj-shadow            地面投影（独立，不参与呼吸）
     .xj-breathe           呼吸包裹层（无限循环）
       .xj-char            角色本体（点头 / 侧转 / 小跳）
         .xj-body          身体 + 天线（脸部为 evenodd 挖空，透出页面背景）
         .xj-face          脸层（张望时双眼整体平移）
           .xj-eye         眼睛（眨眼时纵向压缩）
           .xj-eye--l/--r  左 / 右眼
   坐标原点（1024 画布）：
     角色底部中心 (507, 877)；双眼中心 (369.5, 383.5) / (653.5, 383.5)
   ========================================================================== */

.xj {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  color: #f37021; /* 兜底色：平涂时用；默认皮肤走渐变 */
  -webkit-tap-highlight-color: transparent;
}

.xj-body,
.xj-eye {
  fill: currentColor;
}

/* ---------- 配色方案（只改填色，不影响任何动画） ---------- */
.xj-face-bg {
  fill: #fffdf8; /* 暖白，同小吉的面部基调 */
}

/* 小吉渐变：身体/天线用品牌三色渐变，眼睛用墨色（同小吉原版眼睛） */
.xj--brand .xj-body {
  fill: url(#xj-body-grad);
}
.xj--brand .xj-eye {
  fill: #23140b;
}

/* 保留原眼：身体渐变，眼睛保留图标原本的橙 */
.xj--faithful .xj-body {
  fill: url(#xj-body-grad);
}
.xj--faithful .xj-eye {
  fill: #e26c05;
}

/* 原始图标：平涂 #e26c05，脸部恢复挖空（透出页面背景） */
.xj--original .xj-body,
.xj--original .xj-eye {
  fill: #e26c05;
}
.xj--original .xj-face-bg {
  display: none;
}

/* 需要旋转/缩放的 SVG 分组：统一 view-box 坐标原点，跨浏览器轴心一致 */
.xj-shadow,
.xj-breathe,
.xj-char,
.xj-face,
.xj-eye {
  transform-box: view-box;
  will-change: transform;
}

.xj-shadow {
  transform-origin: 507px 892px;
  opacity: 0.3;
  filter: blur(7px);
}
.xj-breathe {
  transform-origin: 507px 877px;
  animation: xj-breathe 4.4s ease-in-out infinite;
}
.xj-char {
  transform-origin: 507px 877px;
}
.xj-face {
  transform-origin: 507px 383.5px;
}
.xj-eye--l {
  transform-origin: 369.5px 383.5px;
}
.xj-eye--r {
  transform-origin: 653.5px 383.5px;
}

/* ---------- 待机：呼吸 ---------- */

@keyframes xj-breathe {
  0%,
  100% {
    transform: translateY(0) scale(1);
  }
  50% {
    transform: translateY(-7px) scale(1.006);
  }
}

/* ---------- 眨眼：160ms，竖胶囊眼睛压成一条线 ---------- */

.xj.is-blink .xj-eye {
  animation: xj-blink 0.16s cubic-bezier(0.3, 0, 0.2, 1);
}
.xj.is-blink .xj-eye--r {
  animation-delay: 0.014s;
}

@keyframes xj-blink {
  0%,
  100% {
    transform: scaleY(1);
  }
  46%,
  62% {
    transform: scaleY(0.07);
  }
}

/* ---------- 点头：约 580ms，以底部为轴前倾 + 双眼跟着下沉 ---------- */

.xj.is-nod .xj-char {
  animation: xj-nod 0.58s cubic-bezier(0.3, 0.7, 0.4, 1.15);
}
.xj.is-nod .xj-face {
  animation: xj-face-nod 0.58s cubic-bezier(0.3, 0.7, 0.4, 1.15);
}

@keyframes xj-nod {
  0%,
  100% {
    transform: rotate(0deg) translateY(0);
  }
  38% {
    transform: rotate(2.8deg) translateY(6px);
  }
  66% {
    transform: rotate(-1.1deg) translateY(0);
  }
  84% {
    transform: rotate(0.5deg) translateY(0);
  }
}

@keyframes xj-face-nod {
  0%,
  100% {
    transform: translateY(0);
  }
  38%,
  58% {
    transform: translateY(5px);
  }
}

/* ---------- 张望：约 1.8s，双眼在脸内左右移动 + 身体微转 ---------- */

.xj.is-look .xj-face {
  animation: xj-face-look 1.8s cubic-bezier(0.4, 0, 0.2, 1);
}
.xj.is-look .xj-char {
  animation: xj-char-look 1.8s cubic-bezier(0.4, 0, 0.2, 1);
}

@keyframes xj-face-look {
  0%,
  100% {
    transform: translateX(0);
  }
  16%,
  34% {
    transform: translateX(26px);
  }
  56%,
  76% {
    transform: translateX(-22px);
  }
}

@keyframes xj-char-look {
  0%,
  100% {
    transform: rotate(0deg);
  }
  16%,
  34% {
    transform: rotate(1.1deg);
  }
  56%,
  76% {
    transform: rotate(-0.9deg);
  }
}

/* ---------- 侧转身：约 1.25s，横向压扁 + 双眼侧移（2D 假转身） ---------- */

.xj.is-turn .xj-char {
  animation: xj-turn 1.25s cubic-bezier(0.45, 0, 0.25, 1);
}
.xj.is-turn .xj-face {
  animation: xj-face-turn 1.25s cubic-bezier(0.45, 0, 0.25, 1);
}
.xj.is-turn .xj-shadow {
  animation: xj-shadow-turn 1.25s cubic-bezier(0.45, 0, 0.25, 1);
}

@keyframes xj-turn {
  0% {
    transform: none;
  }
  24%,
  58% {
    transform: scaleX(0.85) translateX(4px) rotate(0.8deg);
  }
  80% {
    transform: scaleX(1.02) rotate(-0.4deg);
  }
  100% {
    transform: none;
  }
}

@keyframes xj-face-turn {
  0% {
    transform: none;
  }
  24%,
  58% {
    transform: translateX(16px) scaleX(0.92);
  }
  100% {
    transform: none;
  }
}

@keyframes xj-shadow-turn {
  0%,
  100% {
    transform: scaleX(1);
    opacity: 0.45;
  }
  24%,
  58% {
    transform: scaleX(0.88);
    opacity: 0.4;
  }
}

/* ---------- 小跳：约 660ms，先蹲后弹，投影同步缩放 ---------- */

.xj.is-hop .xj-char {
  animation: xj-hop 0.66s cubic-bezier(0.3, 0.6, 0.3, 1);
}
.xj.is-hop .xj-shadow {
  animation: xj-shadow-hop 0.66s cubic-bezier(0.3, 0.6, 0.3, 1);
}
.xj.is-hop .xj-face {
  animation: xj-face-hop 0.66s cubic-bezier(0.3, 0.6, 0.3, 1);
}

@keyframes xj-hop {
  0% {
    transform: none;
  }
  16% {
    transform: translateY(14px) scaleY(0.94) scaleX(1.035);
  }
  40% {
    transform: translateY(-52px) scaleY(1.035) scaleX(0.975);
  }
  64% {
    transform: translateY(0) scaleY(0.965) scaleX(1.025);
  }
  82% {
    transform: translateY(0) scaleY(1.008) scaleX(0.997);
  }
  100% {
    transform: none;
  }
}

@keyframes xj-face-hop {
  0%,
  100% {
    transform: translateY(0);
  }
  16% {
    transform: translateY(8px);
  }
  40% {
    transform: translateY(-26px);
  }
  64% {
    transform: translateY(4px);
  }
}

@keyframes xj-shadow-hop {
  0%,
  100% {
    transform: scaleX(1) scaleY(1);
    opacity: 0.45;
  }
  16% {
    transform: scaleX(1.06) scaleY(0.9);
    opacity: 0.5;
  }
  40% {
    transform: scaleX(0.8) scaleY(0.65);
    opacity: 0.26;
  }
  64% {
    transform: scaleX(1.04) scaleY(0.95);
    opacity: 0.46;
  }
}

/* ---------- 无障碍：减少动态偏好 ---------- */
/* 待机呼吸是纯装饰，直接停掉；用户主动触发的动作保留但压到 1 帧内 */
@media (prefers-reduced-motion: reduce) {
  .xj-breathe {
    animation: none !important;
  }
  .xj.is-blink .xj-eye,
  .xj.is-blink .xj-eye--r,
  .xj.is-nod .xj-char,
  .xj.is-nod .xj-face,
  .xj.is-look .xj-face,
  .xj.is-look .xj-char,
  .xj.is-turn .xj-char,
  .xj.is-turn .xj-face,
  .xj.is-turn .xj-shadow,
  .xj.is-hop .xj-char,
  .xj.is-hop .xj-shadow,
  .xj.is-hop .xj-face {
    animation-duration: 0.001ms !important;
  }
}

/* ==========================================================================
   引擎门面 · AI 输入卡右上角悬浮吉祥物（不可拖动；点一下会小跳 + 说一句话）
   ========================================================================== */
.xj-float {
  position: fixed;
  right: 24px; /* 兜底位置：无 JS 或卡片不在页面里时用；脚本定位后会覆盖为卡片右上角 */
  bottom: 20px;
  z-index: 40;
  width: 48px; /* PC 与移动端统一 48px（桌面原 150px 的三分之一） */
  pointer-events: none;
  user-select: none;
  visibility: hidden; /* 定位完成（.is-ready）后再出现，避免脚本没跑时先闪在右下角 */
}
.xj-float.is-ready {
  visibility: visible;
}
.xj-float-btn {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 24px;
  cursor: pointer;
  pointer-events: auto;
  touch-action: manipulation; /* 连续点按换句时不触发双击缩放，但保留页面滚动 */
  -webkit-user-drag: none;
  filter: drop-shadow(0 14px 22px rgba(243, 112, 33, 0.16));
  transition: transform 0.22s ease, filter 0.22s ease;
}
.xj-float-btn:hover {
  transform: translateY(-2px);
  filter: drop-shadow(0 18px 26px rgba(243, 112, 33, 0.24));
}
.xj-float-btn:focus-visible {
  outline: 2px solid #f37021;
  outline-offset: 6px;
}
.xj-float svg {
  -webkit-user-drag: none;
  user-select: none;
}

/* 点击 pop：CSS px 的位移 + 缩放。SVG 内部的 is-hop 在 48px 渲染下只有 3~4px，肉眼几乎看不到 */
@keyframes xj-float-pop {
  0% { transform: translateY(0) scale(1); }
  30% { transform: translateY(-9px) scale(1.07); }
  60% { transform: translateY(-2px) scale(0.98); }
  100% { transform: translateY(0) scale(1); }
}
.xj-float-btn.is-pop {
  animation: xj-float-pop 400ms cubic-bezier(0.34, 1.4, 0.4, 1);
  filter: drop-shadow(0 18px 26px rgba(243, 112, 33, 0.28));
}

/* 会话气泡：首屏打招呼、点小吉换一句、10s 自动收起（文案与 www.gity.vip/home 一致）。
   默认（手机窄屏）落在底部做轻提示，避免压住标语区；
   平板 / 桌面脚本会给 .xj-float 加 .is-bubble-side，气泡改挂到小吉左边、尾巴指向嘴边。 */
.xj-float .xj-bubble {
  position: fixed;
  left: 50%;
  bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  z-index: 1;
  width: max-content;
  max-width: min(420px, calc(100vw - 32px));
  padding: 9px 14px;
  border: 1px solid rgba(35, 20, 11, 0.08);
  border-radius: 14px;
  background: #fffdf8;
  box-shadow: 0 10px 26px rgba(28, 22, 16, 0.1);
  font-size: 12.5px;
  line-height: 1.6;
  font-weight: 400;
  color: #5a4a3c;
  text-align: center;
  white-space: pre-line;
  cursor: default;
  pointer-events: none; /* 收起时不挡点击；显示时才接管，点它就收起，避免点穿到下面的链接 */
  opacity: 0;
  transform: translate(-50%, 6px);
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.xj-float .xj-bubble.is-on {
  pointer-events: auto;
  opacity: 1;
  transform: translate(-50%, 0);
}
.xj-float.is-bubble-side .xj-bubble {
  position: absolute;
  right: calc(100% + 6px); /* 放在小吉左侧、留 6px，尾巴从右下角指向嘴边 */
  left: auto;
  bottom: auto;
  top: -10px; /* 与小吉垂直居中：避开上方标语，只压住卡片上沿空白 */
  max-width: var(--xj-bubble-max, 230px);
  border-radius: 14px 14px 4px 14px;
  text-align: left;
  transform: translateY(4px);
}
.xj-float.is-bubble-side .xj-bubble.is-on {
  transform: none;
}
/* 气泡尖角：指向左下方的小吉 */
.xj-float.is-bubble-side .xj-bubble::after {
  content: "";
  position: absolute;
  right: -6px;
  bottom: 24px; /* 尾巴尖对齐小吉嘴部高度（气泡右下角指向小吉左脸） */
  width: 12px;
  height: 12px;
  background: #fffdf8;
  border-right: 1px solid rgba(35, 20, 11, 0.08);
  border-bottom: 1px solid rgba(35, 20, 11, 0.08);
  transform: rotate(-45deg);
}

@media (max-width: 767px) {
  .xj-float {
    /* 尺寸与 PC 一致（48px），移动端只调位置 */
    right: 12px;
    bottom: max(12px, env(safe-area-inset-bottom, 0px));
  }
  .xj-float .xj-bubble {
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  }
}

@media (prefers-reduced-motion: reduce) {
  .xj-float-btn { transition: none; }
  .xj-float-btn.is-pop { animation: none; }
  .xj-float .xj-bubble { transition: none; }
}
