/* ==========================================================================
   Shiro · 动效系统  (static/motion.css)
   ==========================================================================
   设计原则
   ---------------------------------------------------------------------------
   1. 每个页面类型有【自己的一套】动画语言，不重样。
   2. 幅度必须明显 —— 位移 40~150px、缩放 0.2~1.3、含旋转与模糊，一眼能看出。
   3. 安全降级：解析到本文件时元素默认【可见】。只有 motion.js 给 <html> 加上
      .mo-on 之后，元素才会先隐藏、再动画进场。JS 挂了 / 被禁用 → 一切照常。
   4. 尊重 prefers-reduced-motion：直接不启用（见文件末尾）。

   机制
   ---------------------------------------------------------------------------
   .mo          参与动画的元素（由 motion.js 打标）
   --mo-i       交错序号，JS 写入；delay = --mo-i * --mo-gap
   --mo-name    动画名，按 body[data-page] 分配
   .mo.mo-in    进入视口后才加，这才真正开始播

   改外观只需要动这个文件。
   ========================================================================== */

/* --------------------------------------------------------------------------
   基础
   -------------------------------------------------------------------------- */

.mo {
    --mo-name: moRise;
    --mo-dur: 0.9s;
    --mo-gap: 80ms;
    --mo-ease: cubic-bezier(0.22, 1, 0.36, 1);
}

html.mo-on .mo {
    opacity: 0;
    animation-duration: var(--mo-dur);
    animation-timing-function: var(--mo-ease);
    animation-fill-mode: both;
    animation-delay: calc(var(--mo-i, 0) * var(--mo-gap));
    will-change: transform, opacity;
}

html.mo-on .mo.mo-in {
    animation-name: var(--mo-name);
}

/* 播完之后：
   1. 必须显式写回 opacity: 1 —— 因为 .mo-in 已移除、animation-name 变为 none，
      fill-mode 的填充不再生效，否则 html.mo-on .mo 的 opacity:0 会把元素永久隐藏。
   2. 顺手撤掉 will-change，别一直占着合成层。
   注意这里【不能】写 transform —— 写了会盖掉 .mo-hover:hover 的抬升效果。 */
html.mo-on .mo.mo-done {
    opacity: 1;
    will-change: auto;
}

/* --------------------------------------------------------------------------
   1. home —— 弹性堆叠：从下方大幅弹起，回弹感强
   -------------------------------------------------------------------------- */

@keyframes moPopStack {
    0%   { opacity: 0; transform: translateY(76px) scale(0.55); }
    55%  { opacity: 1; transform: translateY(-14px) scale(1.06); }
    75%  { transform: translateY(6px) scale(0.98); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   1b. home 的 hero 逐段 —— 行内元素专用
   --------------------------------------------------------------------------
   .hero__seg 是 display:inline，transform 在行内元素上不生效，所以改用
   模糊聚焦 + 光晕收束。位移类的效果由同一页的 .hero__line / 卡片承担。
   -------------------------------------------------------------------------- */

@keyframes moSegFocus {
    0%   { opacity: 0; filter: blur(16px); }
    70%  { opacity: 1; filter: blur(0) drop-shadow(0 0 20px rgba(197, 100, 115, 0.65)); }
    100% { opacity: 1; filter: blur(0) drop-shadow(0 0 0 transparent); }
}

/* --------------------------------------------------------------------------
   2. posts —— 左侧强势滑入
   -------------------------------------------------------------------------- */

@keyframes moSlideLeftHard {
    0%   { opacity: 0; transform: translateX(-150px) skewX(6deg); }
    60%  { opacity: 1; transform: translateX(14px) skewX(-1deg); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   3. post —— 阅读型：从模糊与下沉中清晰浮现
   -------------------------------------------------------------------------- */

@keyframes moBlurUp {
    0%   { opacity: 0; filter: blur(14px); transform: translateY(48px); }
    55%  { opacity: 1; filter: blur(0); }
    100% { opacity: 1; filter: blur(0); transform: none; }
}

/* --------------------------------------------------------------------------
   4. notes —— 卡片 3D 翻牌
   -------------------------------------------------------------------------- */

@keyframes moFlip3D {
    0%   { opacity: 0; transform: perspective(1100px) rotateX(-78deg) translateY(56px); }
    62%  { opacity: 1; transform: perspective(1100px) rotateX(4deg) translateY(-6px); }
    100% { opacity: 1; transform: perspective(1100px) rotateX(0) translateY(0); }
}

/* --------------------------------------------------------------------------
   5. note —— 右侧滑入
   -------------------------------------------------------------------------- */

@keyframes moSlideRight {
    0%   { opacity: 0; transform: translateX(160px); }
    62%  { opacity: 1; transform: translateX(-12px); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   6. topics —— 自上方落下并弹跳
   -------------------------------------------------------------------------- */

@keyframes moDropBounce {
    0%   { opacity: 0; transform: translateY(-120px) scale(0.9); }
    50%  { opacity: 1; transform: translateY(0) scale(1); }
    65%  { transform: translateY(-22px) scale(1.02); }
    80%  { transform: translateY(0); }
    90%  { transform: translateY(-8px); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   7. topic —— 旋转进入
   -------------------------------------------------------------------------- */

@keyframes moRotateIn {
    0%   { opacity: 0; transform: rotate(-20deg) scale(0.5); }
    70%  { opacity: 1; transform: rotate(4deg) scale(1.05); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   8. says —— 瀑布下落（配合更大的 --mo-gap 形成落差）
   -------------------------------------------------------------------------- */

@keyframes moWaterfall {
    0%   { opacity: 0; transform: translateY(-70px) scale(0.86); }
    60%  { opacity: 1; transform: translateY(8px) scale(1.01); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   9. thinking —— 左侧滑入并轻微倾斜
   -------------------------------------------------------------------------- */

@keyframes moSlideLeftTilt {
    0%   { opacity: 0; transform: translateX(-96px) rotate(-7deg); }
    65%  { opacity: 1; transform: translateX(8px) rotate(1deg); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   10. archive —— 沿时间轴左右两侧展开（奇偶交替）
   -------------------------------------------------------------------------- */

@keyframes moSpreadLeft {
    0%   { opacity: 0; transform: translateX(-110px) scale(0.92); }
    100% { opacity: 1; transform: none; }
}
@keyframes moSpreadRight {
    0%   { opacity: 0; transform: translateX(110px) scale(0.92); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   11. tags —— 从中心爆散
   -------------------------------------------------------------------------- */

@keyframes moBurst {
    0%   { opacity: 0; transform: scale(0.18) rotate(-34deg); }
    62%  { opacity: 1; transform: scale(1.14) rotate(5deg); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   12. tag —— 缩放弹出
   -------------------------------------------------------------------------- */

@keyframes moZoomOut {
    0%   { opacity: 0; transform: scale(0.28); }
    58%  { opacity: 1; transform: scale(1.12); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   13. photos —— 网格翻牌
   -------------------------------------------------------------------------- */

@keyframes moFlipCard {
    0%   { opacity: 0; transform: perspective(1000px) rotateY(178deg) scale(0.75); }
    100% { opacity: 1; transform: perspective(1000px) rotateY(0) scale(1); }
}

/* --------------------------------------------------------------------------
   14. projects —— 卡片堆叠上浮
   -------------------------------------------------------------------------- */

@keyframes moStackUp {
    0%   { opacity: 0; transform: translateY(96px) scale(0.86); }
    60%  { opacity: 1; transform: translateY(-10px) scale(1.02); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   15. friends —— 波浪起伏
   -------------------------------------------------------------------------- */

@keyframes moWave {
    0%   { opacity: 0; transform: translateY(58px) scale(0.6); }
    50%  { opacity: 1; transform: translateY(-16px) scale(1.07); }
    75%  { transform: translateY(6px) scale(0.98); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   16. about —— 逐行擦除揭示
   -------------------------------------------------------------------------- */

@keyframes moRevealLine {
    0%   { opacity: 0; clip-path: inset(0 100% 0 0); transform: translateX(-26px); }
    60%  { opacity: 1; }
    100% { opacity: 1; clip-path: inset(0 0 0 0); transform: none; }
}

/* --------------------------------------------------------------------------
   17. search —— 由大收缩聚焦
   -------------------------------------------------------------------------- */

@keyframes moZoomIn {
    0%   { opacity: 0; transform: scale(1.32); filter: blur(6px); }
    60%  { opacity: 1; filter: blur(0); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   18. 404 —— 故障抖动
   -------------------------------------------------------------------------- */

@keyframes moGlitch {
    0%   { opacity: 0; transform: translateX(-34px) skewX(12deg); }
    20%  { opacity: 1; transform: translateX(22px) skewX(-8deg); }
    38%  { transform: translateX(-14px) skewX(5deg); }
    55%  { transform: translateX(9px) skewX(-3deg); }
    72%  { transform: translateX(-4px) skewX(1deg); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   兜底动画
   -------------------------------------------------------------------------- */

@keyframes moRise {
    0%   { opacity: 0; transform: translateY(40px); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   19. archPosts —— 档案卡侧向滑入，像翻档案
   -------------------------------------------------------------------------- */

@keyframes moIndexSlide {
    0%   { opacity: 0; transform: translateX(-64px) rotate(-1.6deg); }
    62%  { opacity: 1; transform: translateX(6px) rotate(0.4deg); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   20. archPost —— 纸张自上而下展开
   -------------------------------------------------------------------------- */

@keyframes moPaperUnfold {
    0%   { opacity: 0; transform: perspective(1200px) rotateX(-72deg); transform-origin: top center; }
    62%  { opacity: 1; transform: perspective(1200px) rotateX(6deg); }
    100% { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   21. site —— 面板错落浮起
   -------------------------------------------------------------------------- */

@keyframes moPanelIn {
    0%   { opacity: 0; transform: translateY(32px) scale(0.94); }
    60%  { opacity: 1; transform: translateY(-6px) scale(1.012); }
    100% { opacity: 1; transform: none; }
}

@keyframes moSlowAwake {
    0%   { opacity: 0; filter: blur(10px) grayscale(1); transform: translateY(18px); }
    70%  { opacity: 1; filter: blur(0) grayscale(0); }
    100% { opacity: 1; transform: none; }
}

@keyframes moAxisGrow {
    0%   { opacity: 0; transform: translateY(-22px) scaleY(0.86); transform-origin: top center; }
    100% { opacity: 1; transform: none; }
}

@keyframes moQuietFade {
    0%   { opacity: 0; filter: blur(7px); transform: translateY(14px); }
    100% { opacity: 1; filter: blur(0); transform: none; }
}

@keyframes moDateRail {
    0%   { opacity: 0; transform: translateX(-26px); }
    60%  { opacity: 1; transform: translateX(4px); }
    100% { opacity: 1; transform: none; }
}

@keyframes moDiaryOpen {
    0%   { opacity: 0; transform: translateY(-18px) scale(0.985); }
    100% { opacity: 1; transform: none; }
}

/* ==========================================================================
   按页面分配动画语言
   ========================================================================== */

body[data-page="home"]     .mo { --mo-name: moPopStack;       --mo-ease: cubic-bezier(0.34, 1.56, 0.64, 1); --mo-gap: 95ms; }
/* hero 逐段是行内元素，用不含 transform 的动画 */
body[data-page="home"] .hero__seg.mo { --mo-name: moSegFocus; --mo-gap: 55ms; --mo-dur: 0.8s; }
body[data-page="posts"]    .mo { --mo-name: moSlideLeftHard;   --mo-gap: 85ms; }
body[data-page="post"]     .mo { --mo-name: moBlurUp;          --mo-dur: 1s;      --mo-gap: 120ms; }
body[data-page="archPosts"] .mo { --mo-name: moIndexSlide;      --mo-gap: 90ms; }
body[data-page="archPost"]  .mo { --mo-name: moPaperUnfold;     --mo-dur: 1s;      --mo-gap: 115ms; }
body[data-page="site"]      .mo { --mo-name: moPanelIn;         --mo-gap: 100ms; }
body[data-page="maintenance"] .mo { --mo-name: moSlowAwake;    --mo-dur: 1.3s;  --mo-gap: 120ms; }
body[data-page="history"]     .mo { --mo-name: moAxisGrow;    --mo-gap: 130ms; }
body[data-page="reflections"] .mo { --mo-name: moQuietFade;   --mo-dur: 1.15s; --mo-gap: 160ms; }
body[data-page="archNotes"] .mo { --mo-name: moDateRail;     --mo-gap: 110ms; }
body[data-page="archNote"]  .mo { --mo-name: moDiaryOpen;    --mo-dur: 0.95s; --mo-gap: 115ms; }
body[data-page="notes"]    .mo { --mo-name: moFlip3D;          --mo-dur: 1.05s;   --mo-gap: 110ms; }
body[data-page="notes"]    .mo { transform-origin: bottom center; }
body[data-page="note"]     .mo { --mo-name: moSlideRight;      --mo-dur: 1s;      --mo-gap: 120ms; }
body[data-page="topics"]   .mo { --mo-name: moDropBounce;      --mo-dur: 1.15s;   --mo-gap: 100ms; }
body[data-page="topic"]    .mo { --mo-name: moRotateIn;        --mo-dur: 1s;      --mo-gap: 110ms; }
body[data-page="says"]     .mo { --mo-name: moWaterfall;       --mo-dur: 1.05s;   --mo-gap: 150ms; }
body[data-page="thinking"] .mo { --mo-name: moSlideLeftTilt;   --mo-gap: 100ms; }
body[data-page="archive"]  .mo { --mo-name: moSpreadLeft;      --mo-gap: 90ms; }
body[data-page="tags"]     .mo { --mo-name: moBurst;           --mo-dur: 1s;      --mo-gap: 55ms; }
body[data-page="tag"]      .mo { --mo-name: moZoomOut;         --mo-dur: 0.95s;   --mo-gap: 90ms; }
body[data-page="photos"]   .mo { --mo-name: moFlipCard;        --mo-dur: 1.1s;    --mo-gap: 110ms; }
body[data-page="projects"] .mo { --mo-name: moStackUp;         --mo-dur: 1s;      --mo-gap: 120ms; }
body[data-page="friends"]  .mo { --mo-name: moWave;            --mo-ease: cubic-bezier(0.34, 1.56, 0.64, 1); --mo-gap: 130ms; }
body[data-page="about"]    .mo { --mo-name: moRevealLine;      --mo-dur: 1s;      --mo-gap: 110ms; }
body[data-page="search"]   .mo { --mo-name: moZoomIn;          --mo-dur: 0.85s;   --mo-gap: 100ms; }
body[data-page="404"]      .mo { --mo-name: moGlitch;          --mo-dur: 1.1s;    --mo-gap: 140ms; }

/* 归档：左右交替，形成"沿中轴展开"的观感 */
body[data-page="archive"] .mo:nth-child(even) { --mo-name: moSpreadRight; }

/* ==========================================================================
   交互触发动画（悬停 / 点击 / 开关）
   ========================================================================== */

/* —— 卡片悬停：整体抬升 + 轻微放大 —— */
.mo-hover {
    transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
                box-shadow 0.4s cubic-bezier(0.22, 1, 0.36, 1),
                border-color 0.4s ease;
}
.mo-hover:hover {
    transform: translateY(-7px) scale(1.022);
    box-shadow: 0 18px 40px -18px rgba(0, 0, 0, 0.28);
}

/* —— 标签：悬停放大并微微旋转 —— */
.mo-chip { transition: transform 0.32s cubic-bezier(0.34, 1.56, 0.64, 1); }
.mo-chip:hover { transform: scale(1.16) rotate(-3deg); }

/* —— 按钮：按下时压实 —— */
.mo-press { transition: transform 0.14s ease; }
.mo-press:active { transform: scale(0.94); }

/* —— 点击涟漪：JS 插入 .mo-ripple 元素 —— */
.mo-ripple {
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
    background: color-mix(in srgb, var(--accent, #c56473) 42%, transparent);
    transform: scale(0);
    animation: moRipple 0.62s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

@keyframes moRipple {
    to { transform: scale(2.6); opacity: 0; }
}

/* —— 导航链接悬停：下划线扫过 —— */
.capsule-nav .nav-link { position: relative; }
.capsule-nav .nav-link::after {
    content: '';
    position: absolute;
    left: 0.55rem; right: 0.55rem; bottom: 0.15rem;
    height: 2px;
    background: var(--accent);
    border-radius: 2px;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.34s cubic-bezier(0.22, 1, 0.36, 1);
}
.capsule-nav .nav-link:hover::after,
.capsule-nav .nav-link.is-active::after { transform: scaleX(1); }

/* —— 图片载入：淡入 + 从略放大回落 —— */
.mo-img { animation: moImgIn 0.7s cubic-bezier(0.22, 1, 0.36, 1) both; }
@keyframes moImgIn {
    from { opacity: 0; transform: scale(1.06); filter: blur(8px); }
    to   { opacity: 1; transform: none; filter: blur(0); }
}

/* ==========================================================================
   减弱动态效果
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    html.mo-on .mo {
        opacity: 1 !important;
        animation: none !important;
        transform: none !important;
        filter: none !important;
        clip-path: none !important;
    }
    .mo-hover:hover, .mo-chip:hover { transform: none !important; }
    .mo-ripple { display: none !important; }
    .capsule-nav .nav-link::after { transition: none !important; }
}
