/* ═══════════════════════════════════════════════════════════════════════
   人生探微 · 动效层
   ─────────────────────────────────────────────────────────────────────
   方向：纸墨的质感 + 抖音式的物理反馈。
        宣纸可以静，但手按下去必须「弹」——点、按、拖都要有回应。

   ★ 刻意保留弹簧回弹 ★
     impeccable 的检测器会把回弹缓动判为「过时且廉价」（bounce-easing）。
     那条规则对本项目不适用：老板要的就是有物理反馈的弹跳，
     而回弹正是抖音动效的第一号手法。检测器报它时手动豁免，不要改。
     （2026-09-18 同一条规则害我在德语项目删掉全站弹簧，被评价"太丑了"。）

   原则：
   · 只动 transform / opacity（合成层，不触发重排）
   · 每次交互都要有反馈；反馈强度与操作重要性成正比
   · 高频操作（打字、滚动）不做动画——注意力成本会重复付出
   · prefers-reduced-motion 仍要尊重（这是无障碍底线，不是审美）
   ═══════════════════════════════════════════════════════════════════════ */

/* impeccable-disable bounce-easing: 本项目刻意使用弹簧回弹缓动 —— 老板明确要求物理反馈的弹跳（抖音式），回弹是该手法核心。这条规则属于审美取向，与本项目方向冲突。 */

/* ═══ 1. 入场：纸页推上来 ═══════════════════════════════════════════
   错峰入场（stagger）：一段一段落下来，比整块淡入有层次。
   ★ 只用于低频的首次进入——不要在每次切板块时都重播，那会烦。 */
@keyframes paper-in {
  from { opacity: 0; transform: translateY(18px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
@keyframes paper-in-left {
  from { opacity: 0; transform: translateX(-14px); }
  to   { opacity: 1; transform: none; }
}

.reveal { animation: paper-in var(--dur-reveal) var(--ease-spring-soft) both; }
.reveal-1 { animation-delay: .04s; }
.reveal-2 { animation-delay: .10s; }
.reveal-3 { animation-delay: .16s; }
.reveal-4 { animation-delay: .22s; }
.reveal-5 { animation-delay: .28s; }

/* ═══ 2. 按下：先压再弹 ═════════════════════════════════════════════
   按下要快（.09s，手感"实"），回弹要慢（spring，看得见弹）。
   所以 transition 的进和出用不同时长——这是"有物理感"的关键。 */
.btn, .icon-btn, .seg > button, .boards > button,
.tabbar > button, .hours > button, .pitem, .row, .card-link {
  transition-duration: var(--dur-tap);
  transition-timing-function: var(--ease-spring);
}
.btn:active:not(:disabled),
.icon-btn:active,
.seg > button:active,
.boards > button:active,
.hours > button:active,
.pitem:active {
  transform: var(--press);
  transition-duration: .09s;
  transition-timing-function: ease-out;
}

/* 底栏的按压反馈在 components.css 里（只动图标底下的药丸，不动整颗按钮）。
   这里只保留当前项的朱砂点。 */

/* ═══ 3. 可点卡片：悬停浮起 ═════════════════════════════════════════
   原站的设计注释写过"悬停只提亮描边，不上浮不发光"。
   那条按现在的方向作废——但浮起要克制：只给"整块可点"的元素，
   不要给每个按钮都加，否则满屏在动，反而廉价。 */
.card-link, .pitem {
  transition: transform var(--dur-state) var(--ease-spring),
              border-color var(--dur-state) ease,
              box-shadow var(--dur-state) ease;
}
.card-link:hover, .pitem:hover {
  transform: translateY(-3px);
  box-shadow: 0 8px 22px rgba(31,27,22,.10);
}
.card-link:active, .pitem:active { transform: translateY(0) var(--press); }

/* ═══ 4. 朱砂印盖章 ═════════════════════════════════════════════════
   全站签名元素。盖下去要有"落印"的重量：从上落下 + 转正 + 过冲回弹。 */
@keyframes seal-stamp {
  0%   { opacity: 0; transform: scale(2.6) rotate(-22deg); filter: blur(3px); }
  45%  { opacity: 1; transform: scale(.86) rotate(-1deg);  filter: blur(0); }
  70%  { transform: scale(1.08) rotate(-7deg); }
  100% { transform: scale(1) rotate(-6deg); }
}
.stamp { animation: seal-stamp .62s var(--ease-spring-real) both; }

/* 小朱砂印（必填标记、当前页标记）落下来 */
@keyframes seal-pop {
  0%   { opacity: 0; transform: scale(0) rotate(-30deg); }
  60%  { opacity: 1; transform: scale(1.25) rotate(3deg); }
  100% { transform: scale(1) rotate(-4deg); }
}
.seal { animation: seal-pop .42s var(--ease-spring) both; }
.field-head .req { animation: seal-pop .42s var(--ease-spring) both; }

/* ═══ 5. 五行条：墨迹晕开 ═══════════════════════════════════════════
   从左边推出来，用弹簧缓动，末端轻微过冲——像墨在宣纸上散开。 */
.wx-bar > i {
  transition: transform .75s var(--ease-spring-soft);
}
/* 错峰：五行一根接一根，不要齐刷刷同时出现 */
.wx-row:nth-child(1) .wx-bar > i { transition-delay: .02s; }
.wx-row:nth-child(2) .wx-bar > i { transition-delay: .09s; }
.wx-row:nth-child(3) .wx-bar > i { transition-delay: .16s; }
.wx-row:nth-child(4) .wx-bar > i { transition-delay: .23s; }
.wx-row:nth-child(5) .wx-bar > i { transition-delay: .30s; }

/* ═══ 6. 干支字逐个落位 ═════════════════════════════════════════════
   四柱是盘面的主角，让它一个一个字落下来。 */
@keyframes glyph-drop {
  0%   { opacity: 0; transform: translateY(-14px) scale(.8); }
  60%  { opacity: 1; transform: translateY(3px) scale(1.06); }
  100% { transform: none; }
}
.pillar .glyph { animation: glyph-drop .5s var(--ease-spring) both; }
.pillars .pillar:nth-child(1) .glyph { animation-delay: .05s; }
.pillars .pillar:nth-child(2) .glyph { animation-delay: .13s; }
.pillars .pillar:nth-child(3) .glyph { animation-delay: .21s; }
.pillars .pillar:nth-child(4) .glyph { animation-delay: .29s; }

/* ═══ 7. 时辰格：选中的那一下弹 ═════════════════════════════════════ */
@keyframes tile-pop {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.12); }
  100% { transform: scale(1); }
}
.hours > button[aria-pressed="true"] { animation: tile-pop .38s var(--ease-spring); }

/* 性别/分段控件选中 */
@keyframes seg-pop {
  0% { transform: scale(.94); }
  55% { transform: scale(1.04); }
  100% { transform: scale(1); }
}
.seg > button[aria-pressed="true"] { animation: seg-pop .34s var(--ease-spring); }

/* ═══ 8. 板块切换：面板滑入 ═════════════════════════════════════════ */
@keyframes panel-in {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: none; }
}
[role="tabpanel"]:not([hidden]) { animation: panel-in var(--dur-view) var(--ease-spring-soft) both; }

/* ═══ 9. 底栏当前项：朱砂点弹出来 ═══════════════════════════════════ */


/* ═══ 10. 弹窗 / 底部面板 ═══════════════════════════════════════════ */
@keyframes modal-pop {
  0%   { opacity: 0; transform: scale(.9) translateY(14px); }
  60%  { opacity: 1; transform: scale(1.02) translateY(-3px); }
  100% { opacity: 1; transform: none; }
}
.modal.open .modal-panel { animation: modal-pop .46s var(--ease-spring) both; }

@keyframes sheet-up {
  from { transform: translateY(102%); }
  to   { transform: none; }
}
.sheet.open { animation: sheet-up .46s var(--ease-spring) both; }

/* ═══ 11. 提示条 ════════════════════════════════════════════════════ */
@keyframes toast-pop {
  0%   { opacity: 0; transform: translateY(20px) scale(.94); }
  65%  { opacity: 1; transform: translateY(-3px) scale(1.02); }
  100% { opacity: 1; transform: none; }
}
.toast { animation: toast-pop .44s var(--ease-spring) both; }

/* ═══ 12. 聚焦：描边弹一下 ═════════════════════════════════════════
   输入框拿到焦点时，外圈轻轻涨一下再落定。 */
@keyframes focus-ring {
  0%   { box-shadow: 0 0 0 0 var(--cinnabar-soft); }
  60%  { box-shadow: 0 0 0 6px var(--cinnabar-soft); }
  100% { box-shadow: 0 0 0 3px var(--cinnabar-soft); }
}
.input:focus, select:focus, .select:focus { animation: focus-ring .38s var(--ease-spring) both; }

/* ═══ 13. 加载：太极转圈已经有了，这里给骨架屏加呼吸 ═══════════════ */
@keyframes skeleton-breathe {
  0%, 100% { opacity: .55; }
  50%      { opacity: 1; }
}
.skeleton { animation: skeleton-breathe 1.5s ease-in-out infinite; }

/* ═══ 14. 空状态：插图轻浮 ═════════════════════════════════════════ */
@keyframes float-soft {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
.empty .empty-title { animation: float-soft 3.2s ease-in-out infinite; }

/* ═══ 15. 页面级：卡片依次入场 ═════════════════════════════════════
   只有首页和「我的」这种"一次看到多块"的页面才用；
   对话页是高频交互，不加。 */
.stagger > * { animation: paper-in var(--dur-reveal) var(--ease-spring-soft) both; }
.stagger > *:nth-child(1) { animation-delay: .02s; }
.stagger > *:nth-child(2) { animation-delay: .08s; }
.stagger > *:nth-child(3) { animation-delay: .14s; }
.stagger > *:nth-child(4) { animation-delay: .20s; }
.stagger > *:nth-child(5) { animation-delay: .26s; }
.stagger > *:nth-child(6) { animation-delay: .32s; }

/* ═══ 16. 无障碍底线：不是审美问题，不能省 ═══════════════════════
   系统开了"减弱动态效果"就把动画全关。
   注意：这里关的是动画，不是交互反馈——按钮按下的颜色变化要保留。 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}
