/* ============================================================
   动效 —— 节奏要慢、要软，像纸落下来，不是弹跳玩具
   ============================================================ */

@keyframes bootBounce { 0%,100% { transform: translateY(0); opacity: .5; } 50% { transform: translateY(-7px); opacity: 1; } }
@keyframes spinSlow { to { transform: rotate(360deg); } }
@keyframes shimmer { to { background-position: -220% 0; } }

@keyframes riseIn {
  from { opacity: 0; transform: translateY(14px) rotate(-.7deg) scale(.985); }
  to   { opacity: 1; transform: translateY(0) rotate(0) scale(1); }
}
@keyframes slideInLeft {
  from { opacity: 0; transform: translateX(-16px); }
  to   { opacity: 1; transform: translateX(0); }
}
@keyframes popIn {
  0% { opacity: 0; transform: scale(.82) rotate(-4deg); }
  70% { opacity: 1; transform: scale(1.04) rotate(1deg); }
  100% { opacity: 1; transform: scale(1) rotate(0); }
}
@keyframes veilIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes modalIn {
  0%   { opacity: 0; transform: scale3d(.28, .28, 1) translate3d(0, 10px, 0) rotate(-1.4deg); }
  68%  { opacity: 1; transform: scale3d(1.016, 1.016, 1) translate3d(0, -2px, 0) rotate(.2deg); }
  100% { opacity: 1; transform: scale3d(1, 1, 1) translate3d(0, 0, 0) rotate(0); }
}
@keyframes menuOriginUnfold {
  0%   { opacity: 0; transform: scale3d(.36, .36, 1) translate3d(0, -6px, 0) rotate(-1deg); }
  70%  { opacity: 1; transform: scale3d(1.02, 1.02, 1) translate3d(0, 1px, 0) rotate(.15deg); }
  100% { opacity: 1; transform: scale3d(1, 1, 1) translate3d(0, 0, 0) rotate(0); }
}
@keyframes toastIn {
  from { opacity: 0; transform: translate3d(28px, 0, 0) scale3d(.92, .92, 1) rotate(1.8deg); }
  to   { opacity: 1; transform: translate3d(0, 0, 0) scale3d(1, 1, 1) rotate(0); }
}
@keyframes toastOut {
  to { opacity: 0; transform: translate3d(24px, 0, 0) scale3d(.94, .94, 1) rotate(1.2deg); }
}
@keyframes reactionPop {
  0% { transform: scale(1); }
  35% { transform: scale(1.35) rotate(-8deg); }
  70% { transform: scale(.94) rotate(3deg); }
  100% { transform: scale(1); }
}
/* 纯 GPU 合成器脉动：不改 box-shadow，零重绘 */
@keyframes livePulse {
  0%   { transform: scale3d(1, 1, 1); opacity: .75; }
  75%  { transform: scale3d(2.35, 2.35, 1); opacity: 0; }
  100% { transform: scale3d(2.35, 2.35, 1); opacity: 0; }
}
@keyframes stampIn {
  0% { opacity: 0; transform: scale(1.7) rotate(-16deg); }
  55% { opacity: 1; transform: scale(.92) rotate(-6deg); }
  100% { opacity: 1; transform: scale(1) rotate(-4deg); }
}
@keyframes drawLine { from { stroke-dashoffset: var(--dash, 300); } to { stroke-dashoffset: 0; } }
@keyframes floatY { 0%,100% { transform: translate3d(0, 0, 0); } 50% { transform: translate3d(0, -4px, 0); } }
@keyframes glowOnce {
  0% { background-color: color-mix(in srgb, var(--highlight) 70%, transparent); }
  100% { background-color: transparent; }
}
@keyframes sparkle {
  0% { opacity: 0; transform: translate(0, 0) scale(.4); }
  40% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx, 10px), var(--dy, -18px)) scale(1.1); }
}
@keyframes pageSweep {
  0%   { opacity: 0; transform: translate3d(0, 12px, 0) scale3d(.985, .985, 1); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale3d(1, 1, 1); }
}
/* 从触发图标/卡片坐标展开子层级页面（展示空间层级关系） */
@keyframes pageDrillIn {
  0%   { opacity: 0; transform: scale3d(.86, .86, 1) translate3d(0, 14px, 0); }
  68%  { opacity: 1; transform: scale3d(1.006, 1.006, 1) translate3d(0, -1px, 0); }
  100% { opacity: 1; transform: scale3d(1, 1, 1) translate3d(0, 0, 0); }
}
/* 从子页面退回父层级页面 */
@keyframes pagePopBack {
  0%   { opacity: 0; transform: translate3d(-24px, 0, 0) scale3d(.965, .965, 1); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale3d(1, 1, 1); }
}
/* 同级主栏横向滑动切换 */
@keyframes pageSlideFromRight {
  0%   { opacity: 0; transform: translate3d(32px, 0, 0) scale3d(.988, .988, 1); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale3d(1, 1, 1); }
}
@keyframes pageSlideFromLeft {
  0%   { opacity: 0; transform: translate3d(-32px, 0, 0) scale3d(.988, .988, 1); }
  100% { opacity: 1; transform: translate3d(0, 0, 0) scale3d(1, 1, 1); }
}
@keyframes breathe { 0%,100% { transform: scale3d(1, 1, 1); } 50% { transform: scale3d(1.05, 1.05, 1); } }
@keyframes heartBeat {
  0%,100% { transform: scale(1); }
  20% { transform: scale(1.18); }
  40% { transform: scale(.98); }
  60% { transform: scale(1.1); }
}

/* 页面进入：根据层级与方向采用非线性物理曲线 */
.page-enter {
  animation: pageSweep 340ms var(--ease-spring) backwards;
}
.page-enter-drill {
  transform-origin: var(--page-origin-x, 50%) var(--page-origin-y, 35%);
  animation: pageDrillIn 380ms var(--ease-spring) backwards;
}
.page-enter-pop {
  transform-origin: 20% 50%;
  animation: pagePopBack 320ms var(--ease-morph) backwards;
}
.page-enter-right {
  animation: pageSlideFromRight 320ms var(--ease-spring) backwards;
}
.page-enter-left {
  animation: pageSlideFromLeft 320ms var(--ease-spring) backwards;
}

/* 交错进场：JS 给每个元素设 --i */
.enter {
  animation: riseIn var(--t-slow) var(--ease-hand) backwards;
  animation-delay: calc(var(--i, 0) * 42ms);
}

.stamp-anim { animation: stampIn 460ms var(--ease-pop); }
.pop { animation: popIn 380ms var(--ease-pop); }
.float { animation: floatY 3.6s var(--ease-hand) infinite; }
.breathe { animation: breathe 3.2s var(--ease-hand) infinite; }
.beating { animation: heartBeat 1.4s var(--ease-hand); }
.glow-new { animation: glowOnce 1.8s var(--ease-hand); }

/* 图标描线：进来时像正在被画出来 */
.draw svg path, .draw svg line, .draw svg circle, .draw svg rect, .draw svg polyline {
  stroke-dasharray: var(--dash, 320);
  stroke-dashoffset: var(--dash, 320);
  animation: drawLine 900ms var(--ease-hand) forwards;
}
.draw svg > *:nth-child(2) { animation-delay: 120ms; }
.draw svg > *:nth-child(3) { animation-delay: 240ms; }
.draw svg > *:nth-child(4) { animation-delay: 340ms; }
.draw svg > *:nth-child(5) { animation-delay: 440ms; }

/* 小星星（纪念日 / 里程碑） */
.sparkle { position: absolute; width: 8px; height: 8px; pointer-events: none; }
.sparkle i {
  display: block; width: 100%; height: 100%;
  background: var(--mustard);
  clip-path: polygon(50% 0, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0 50%, 40% 40%);
  animation: sparkle 1.1s var(--ease-hand) forwards;
}

/* 日历 / 打卡格子的按压反馈 */
.pressable { transition: transform var(--t-fast) var(--ease-pop); }
.pressable:active { transform: scale(.9); }

/* 聊天消息飘入 */
.msg-enter { animation: riseIn var(--t-base) var(--ease-hand) backwards; }

/* 进度条（习惯 / 配额） */
.bar {
  height: 10px;
  border-radius: 999px;
  background: var(--paper-3);
  position: relative;
  overflow: hidden;
}
.bar::before { content: ""; position: absolute; inset: 0; border: 1.4px solid var(--line-soft); border-radius: inherit; pointer-events: none; }
.bar > i {
  display: block; height: 100%;
  background: repeating-linear-gradient(45deg, var(--accent) 0 6px, color-mix(in srgb, var(--accent) 72%, var(--paper-2)) 6px 12px);
  border-radius: 999px;
  transition: width var(--t-slow) var(--ease-hand);
}

[data-motion="calm"] .enter,
[data-motion="calm"] .page-enter,
[data-motion="calm"] .page-enter-drill,
[data-motion="calm"] .page-enter-pop,
[data-motion="calm"] .page-enter-right,
[data-motion="calm"] .page-enter-left,
[data-motion="calm"] .float,
[data-motion="calm"] .breathe { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .enter, .page-enter, .page-enter-drill, .page-enter-pop, .page-enter-right, .page-enter-left, .stamp-anim, .pop, .float, .breathe, .beating, .draw svg *, .sparkle i { animation: none !important; }
  .draw svg path, .draw svg line, .draw svg circle, .draw svg rect, .draw svg polyline { stroke-dasharray: none; stroke-dashoffset: 0; }
}

/* ---------- 封面那张画：描线 / 填色 / 弹出来 ----------
   这些类直接长在 <path>、<g> 上，不是包在 svg 外面，
   所以得单独写一遍；--d 是各自的出场延迟。 */
path.draw, line.draw, circle.draw, rect.draw, polyline.draw {
  stroke-dasharray: var(--dash, 320);
  stroke-dashoffset: var(--dash, 320);
  animation: drawLine 900ms var(--ease-hand) var(--d, 0s) forwards;
}
path.pop, g.pop, circle.pop {
  transform-box: fill-box;
  transform-origin: center;
  animation: popIn 420ms var(--ease-pop) var(--d, 0s) both;
}
.fill-in {
  transform-box: fill-box;
  transform-origin: center bottom;
  animation: fillIn 560ms var(--ease-hand) var(--d, 0s) both;
}
@keyframes fillIn {
  from { opacity: 0; transform: translateY(8px) scale(.96) rotate(-.6deg); }
  to   { opacity: 1; transform: none; }
}

/* 安静模式：封面那张画也不动 */
@media (prefers-reduced-motion: reduce) {
  path.draw, line.draw, circle.draw, rect.draw, polyline.draw {
    animation: none !important;
    stroke-dasharray: none; stroke-dashoffset: 0;
  }
  path.pop, g.pop, circle.pop, .fill-in { animation: none !important; }
}
