/* ============================================================
   animations.css · 骨架呼吸、漂浮爱心、图钉 pop-in、sheet 入场、
   toast、口令层抖动、prefers-reduced-motion 降级
   ============================================================ */

/* ── 骨架呼吸 ── */
@keyframes cmm-breathe {
  0%   { background-position:120% 0; opacity:.75; }
  50%  { background-position:0 0;    opacity:1; }
  100% { background-position:-120% 0; opacity:.75; }
}

.cmm-skel {
  background:linear-gradient(90deg,
    rgba(255,255,255,.30) 0%,
    rgba(255,255,255,.72) 50%,
    rgba(255,255,255,.30) 100%);
  background-size:220% 100%;
  border-radius:var(--r-chip);
  animation:cmm-breathe 1.6s var(--ease-out) infinite;
}

/* ── 漂浮爱心上升 ── */
@keyframes cmm-heart-rise {
  0%   { transform:translateY(0) scale(.6) rotate(-8deg); opacity:0; }
  15%  { opacity:.9; }
  100% { transform:translateY(-110px) scale(1) rotate(10deg); opacity:0; }
}

.cmm-hearts__heart {
  position:absolute;
  bottom:-24px;
  color:var(--pink);
  opacity:0;
  animation:cmm-heart-rise 4.5s var(--ease-out) infinite;
}
.cmm-hearts__heart svg { width:16px; height:16px; display:block; }

/* ── 图钉 pop-in（T04 图钉依次落下时复用） ── */
@keyframes cmm-pin-pop {
  0%   { transform:scale(.4) translateY(-8px); opacity:0; }
  60%  { transform:scale(1.08) translateY(0);   opacity:1; }
  100% { transform:scale(1) translateY(0);      opacity:1; }
}

.cmm-pin-pop { animation:cmm-pin-pop 240ms var(--ease-out) both; }

/* ── 列表项入场（T03 数据渲染的轻淡入） ── */
@keyframes cmm-rise-in {
  0%   { transform:translateY(12px); opacity:0; }
  100% { transform:translateY(0);    opacity:1; }
}

.cmm-rise-in {
  animation:cmm-rise-in var(--d-base) var(--ease-out) both;
}

/* ── 口令层输错抖动（不清空输入，只抖动提示） ── */
@keyframes cmm-shake {
  0%, 100% { transform:translateX(0); }
  20% { transform:translateX(-8px); }
  40% { transform:translateX(7px); }
  60% { transform:translateX(-5px); }
  80% { transform:translateX(3px); }
}

.cmm-shake { animation:cmm-shake 320ms var(--ease-out); }

/* ── toast ── */
@keyframes cmm-toast-in {
  0%   { transform:translate(-50%, 12px); opacity:0; }
  100% { transform:translate(-50%, 0);    opacity:1; }
}

.cmm-toast {
  position:fixed;
  left:50%;
  bottom:calc(var(--safe-b) + var(--sp-6));
  transform:translate(-50%, 0);
  z-index:var(--z-toast);
  max-width:86vw;
  padding:var(--sp-3) var(--sp-5);
  border-radius:var(--r-chip);
  font-size:14px;
  color:var(--ink);
  box-shadow:var(--shadow-card);
  animation:cmm-toast-in var(--d-fast) var(--ease-out) both;
}
.cmm-toast--error { box-shadow:inset 0 0 0 1.5px var(--pink), var(--shadow-card); }
.cmm-toast--ok { box-shadow:inset 0 0 0 1.5px var(--blue-200), var(--shadow-card); }

/* ── 全屏错误横幅（不打断操作，贴在顶部下方） ── */
@keyframes cmm-banner-in {
  0%   { transform:translateY(-100%); opacity:0; }
  100% { transform:translateY(0);     opacity:1; }
}

.cmm-banner {
  position:fixed;
  top:calc(var(--safe-t) + var(--sp-2));
  left:50%;
  transform:translateX(-50%);
  z-index:var(--z-toast);
  max-width:86vw;
  display:flex;
  align-items:center;
  gap:var(--sp-2);
  padding:var(--sp-2) var(--sp-4);
  border-radius:var(--r-chip);
  font-size:13px;
  color:var(--ink);
  box-shadow:inset 0 0 0 1.5px var(--pink), var(--shadow-card);
  animation:cmm-banner-in var(--d-base) var(--ease-out) both;
}

/* ── 口令层 / 确认弹窗的遮罩 ── */
@keyframes cmm-fade-in {
  0%   { opacity:0; }
  100% { opacity:1; }
}

.cmm-overlay-mask {
  position:fixed;
  inset:0;
  z-index:var(--z-modal);
  background:rgba(36,64,95,.35);
  animation:cmm-fade-in var(--d-fast) var(--ease-out) both;
}

/* 口令层卡片入场 */
@keyframes cmm-passcode-in {
  0%   { transform:translate(-50%, 24px) scale(.96); opacity:0; }
  100% { transform:translate(-50%, 0) scale(1);      opacity:1; }
}

/* ── 云朵横向漂移（T04 L1 装饰，先就位） ── */
@keyframes cmm-cloud-drift {
  0%   { transform:translateX(-12vw); }
  100% { transform:translateX(112vw); }
}

/* ── 减弱动态效果：全部动画停用（含骨架呼吸改为静态高亮） ── */
@media (prefers-reduced-motion: reduce) {
  .cmm-skel {
    animation:none;
    background:rgba(255,255,255,.55);
  }
  .cmm-hearts__heart,
  .cmm-pin-pop,
  .cmm-rise-in,
  .cmm-shake,
  .cmm-toast,
  .cmm-banner,
  .cmm-overlay-mask,
  .cmm-passcode,
  .cmm-cloud { animation:none !important; }
  .cmm-hearts__heart { display:none; }
  .cmm-sheet { transition:none; }
}
