/* ============================================================================
 * zzerfu-scene.css — 首页 ↔ 子页面「整场退场 / 入场」动效（最后加载）
 * ----------------------------------------------------------------------------
 * 一次切换里同时有三位演员，各自按自己的节拍走：
 *   1. 入口卡：左卡（相册）往左移出，右侧四卡往右移出；
 *   2. 首屏插画：高度从首页的 630 缩到子页面的 340，插画跟着缩放（背景比例由
 *      JS 每帧写 --zf-illu-h / --zf-illu-y，避免 background-size 不参与过渡）；
 *   3. 计时往左、诗往右，各自退场。
 * 三者都走完之后，新页面内容才从底部滑进来；回首页时反过来：
 * 下半部分内容先下滑，插画放大回首页尺寸，主内容再从两侧滑入。
 *
 * 状态机（都挂在 <html> 上，一次只可能有两个类同时存在）：
 *   zf-scene            场景进行中（屏蔽内容点击、裁掉横向溢出）
 *   data-zf-dir="sub"   首页 → 子页面；"home" 子页面 → 首页
 *   zf-scene-exiting    退场段
 *   zf-scene-entering   已换页、但还没开始入场（新内容停在起始位）
 *   zf-scene-running    入场段
 *
 * 为什么位移全部用 translate / scale / opacity，而不是 transform：
 * 卡片本身带着 transform: rotate(-3.2deg)（手账纸卡）、悬停还有 translateY，
 * 用独立的 translate 属性可以叠加在既有 transform 之上，不会把它们顶掉。
 * ========================================================================== */

html.zf-scene {
    /* 卡片往两侧飞出时会顶到屏幕右缘，clip 不建立滚动容器，sticky 照常工作 */
    overflow-x: clip;
    /* 整站默认 scroll-behavior: smooth，逐帧 scrollTo 会被它再平滑一次，
       退场时「回到顶部」就会和插画脱节 —— 场景期间改回瞬时滚动 */
    scroll-behavior: auto !important;
    --zf-out: cubic-bezier(0.4, 0, 0.62, 1);
    --zf-in: cubic-bezier(0.22, 1, 0.36, 1);
}

html.zf-scene #pjax-container {
    pointer-events: none;
}

/* 留言弹窗是 position:fixed 的整屏遮罩（默认 visibility:hidden）。它绝不能
   跟着内容一起淡入 —— 一旦被本场景的 opacity 规则点亮，就会在换页那一瞬
   闪出整张表单；这里直接把它排除在动画之外，并强制关着的时候不可见。
   （手机上 Safari 对「隐藏的 fixed 元素 + opacity 过渡」尤其容易画出来） */
html.zf-scene #pjax-container > .message-modal:not(.is-open) {
    display: none !important;
}

/* 场景本身就在交代「正在换页」，NProgress 的蓝条这时只会从画面顶上划一道 */
html.zf-scene #nprogress {
    display: none !important;
}

/* ============================================================
   1. 首次加载：不做任何入场（场景只负责「切换」，不负责进站）
   ============================================================ */

/* ============================================================
   2. 首屏插画：高度由 JS 逐帧写，背景比例同步缩放
   ============================================================ */
html.zf-scene[data-zf-dir="sub"] .bg-img::before {
    /* 118% → 100%：房间跟着画框一起缩小，而不是被裁掉 */
    background-size: auto var(--zf-illu-h, 100%) !important;
    background-position: center var(--zf-illu-y, 0%) !important;
}

html.zf-scene[data-zf-dir="home"] .bg-img::before {
    background-size: auto var(--zf-illu-h, 118%) !important;
    background-position: center var(--zf-illu-y, 8%) !important;
}

/* 插画底下的墙面渐变：两种页面用的是两套渐变，换页那一刻会跳，
   这里让子页面那层先透明，等场景结束再交还，接缝就看不到了 */
html.zf-scene .bg-img {
    transition: none !important;
}

/* ============================================================
   3. 退场：首页 → 子页面
   ============================================================ */

/* 3.1 入口卡：相册往左，其余四张往右（延迟由 JS 逐张写） */
html.zf-scene[data-zf-dir="sub"].zf-scene-exiting .entry-grid > .card {
    transition:
        translate 0.5s var(--zf-out),
        opacity 0.36s ease-in;
    will-change: translate, opacity;
}

html.zf-scene[data-zf-dir="sub"].zf-scene-exiting .entry-grid > .card--feature {
    translate: calc(-100% - 6vw) 0;
    opacity: 0;
}

html.zf-scene[data-zf-dir="sub"].zf-scene-exiting .entry-grid > .card:not(.card--feature) {
    translate: calc(100% + 6vw) 0;
    opacity: 0;
}

/* 3.2 计时往左、诗往右 */
html.zf-scene[data-zf-dir="sub"].zf-scene-exiting .time--hero {
    transition:
        translate 0.52s var(--zf-out) 0.04s,
        opacity 0.28s ease-in 0.04s;
    translate: -84px 0;
    opacity: 0;
}

html.zf-scene[data-zf-dir="sub"].zf-scene-exiting .home-poem {
    transition:
        translate 0.52s var(--zf-out) 0.04s,
        opacity 0.28s ease-in 0.04s;
    translate: 76px 0;
    opacity: 0;
}

/* 3.3 头像：不再虚焦消失 —— 三枚图形（两张猫头像 + 心形）由 zzerfu-scene.js
   逐帧驱动，从本页位姿移动 + 等比缩放到目标页位姿，与插画共用同一条时间轴。
   名字不参与飞行：飞行期间收起，落定后再浮出（否则文字会被非等比拉伸，
   或落定时字号从 13px 跳到 18px）。 */
html.zf-scene[data-zf-dir="sub"] .bg-img .middle .img-male span,
html.zf-scene[data-zf-dir="sub"] .bg-img .middle .img-female span,
html.zf-scene[data-zf-dir="home"] .bg-img .middle .img-male span,
html.zf-scene[data-zf-dir="home"] .bg-img .middle .img-female span {
    transition: opacity 0.16s ease-in;
    opacity: 0;
}

html.zf-scene.zf-scene-running .bg-img .middle .img-male span,
html.zf-scene.zf-scene-running .bg-img .middle .img-female span {
    transition: opacity 0.36s ease 0.1s;
    opacity: 1;
}

/* 3.3.1 头像框：那圈 5px 的实心色环只在首页有，子页面没有。
   不处理的话，换页那一帧 is-home 一摘，整圈环「啪」地消失（回首页时反过来突然冒出）。
   这里在场景期间固定写上带环的 box-shadow，环的透明度交给 --zf-ring-a：
   zzerfu-scene.js 在飞行的每一帧按同一个进度写它（出发页 1→0、目标页 0→1），
   落定时正好落定，is-home 中途切换就看不出接缝了。
   选择器压过两套页面样式，所以换页那一帧 is-home 切换也不会打断这条曲线；
   变量会一直留到整场收尾（finish）才清掉，中间的 entering / running 段同样有效。 */
html.zf-scene[data-zf-dir="sub"] .bg-img .middle .img-male img,
html.zf-scene[data-zf-dir="home"] .bg-img .middle .img-male img {
    box-shadow: 0 16px 28px rgba(15, 155, 134, 0.22), 0 0 0 var(--zf-ring-w, 5px) rgba(15, 155, 134, var(--zf-ring-a, 1)) !important;
}

html.zf-scene[data-zf-dir="sub"] .bg-img .middle .img-female img,
html.zf-scene[data-zf-dir="home"] .bg-img .middle .img-female img {
    box-shadow: 0 16px 28px rgba(224, 154, 122, 0.26), 0 0 0 var(--zf-ring-w, 5px) rgba(224, 154, 122, var(--zf-ring-a, 1)) !important;
}

/* 3.4 底部返回条：一起退掉 */
html.zf-scene.zf-scene-exiting .page-back-row {
    transition: opacity 0.28s ease-in, translate 0.32s var(--zf-out);
    opacity: 0;
    translate: 0 -6px;
}

/* 3.5 换页兜底：计时 / 诗 在子页面是 display:none，换页一发生就会直接消失。
   给 entering 段的它们补一条 opacity:0，保证消失时已经是全透明。 */
html.zf-scene[data-zf-dir="sub"].zf-scene-entering .time--hero,
html.zf-scene[data-zf-dir="sub"].zf-scene-entering .home-poem {
    opacity: 0 !important;
}

/* ============================================================
   4. 退场：子页面 → 首页
   ============================================================ */
html.zf-scene[data-zf-dir="home"].zf-scene-exiting #pjax-container > *:not(.lg-sidebar):not(.message-modal) {
    transition:
        translate 0.38s var(--zf-out),
        opacity 0.3s ease-in;
    translate: 0 46px;
    opacity: 0;
    will-change: translate, opacity;
}

/* 头像块同样由 JS 驱动飞回首页位姿，这里不再做虚焦退场 */

/* ============================================================
   5. 入场：新页面内容（首页 → 子页面）
   ============================================================ */
html.zf-scene[data-zf-dir="sub"].zf-scene-entering #pjax-container > *:not(.lg-sidebar):not(.message-modal) {
    opacity: 0;
    translate: 0 52px;
}

html.zf-scene[data-zf-dir="sub"].zf-scene-running #pjax-container > *:not(.lg-sidebar):not(.message-modal) {
    transition:
        translate 0.72s var(--zf-in),
        opacity 0.56s var(--zf-in);
    opacity: 1;
    translate: 0 0;
}

html.zf-scene[data-zf-dir="sub"].zf-scene-entering #pjax-container > *:not(.lg-sidebar):not(.message-modal):nth-child(2) {
    translate: 0 64px;
}

html.zf-scene[data-zf-dir="sub"].zf-scene-running #pjax-container > *:not(.lg-sidebar):not(.message-modal):nth-child(2) {
    transition-delay: 0.07s;
}

/* 5.1 新页面里的返回条：跟着内容一起浮上来 */
html.zf-scene[data-zf-dir="sub"].zf-scene-entering .page-back-row {
    opacity: 0;
    translate: 0 -8px;
}

html.zf-scene[data-zf-dir="sub"].zf-scene-running .page-back-row {
    transition:
        opacity 0.5s ease 0.24s,
        translate 0.6s var(--zf-in) 0.24s;
    opacity: 1;
    translate: 0 0;
}

/* 5.2 头像已在退场段随 JS 飞到位，入场段不再虚焦、也不再延迟浮回 */

/* ============================================================
   6. 入场：回首页（内容从两侧滑入）
   ============================================================ */
html.zf-scene[data-zf-dir="home"].zf-scene-entering .entry-grid > .card {
    opacity: 0;
}

html.zf-scene[data-zf-dir="home"].zf-scene-entering .entry-grid > .card--feature {
    translate: -13% 0;
}

html.zf-scene[data-zf-dir="home"].zf-scene-entering .entry-grid > .card:not(.card--feature) {
    translate: 15% 0;
}

html.zf-scene[data-zf-dir="home"].zf-scene-running .entry-grid > .card {
    transition:
        translate 0.82s var(--zf-in),
        opacity 0.5s ease;
    opacity: 1;
    translate: 0 0;
}

/* 计时从左侧、诗从右侧回到位 */
html.zf-scene[data-zf-dir="home"].zf-scene-entering .time--hero {
    opacity: 0;
    translate: -64px 0;
}

html.zf-scene[data-zf-dir="home"].zf-scene-entering .home-poem {
    opacity: 0;
    translate: 58px 0;
}

html.zf-scene[data-zf-dir="home"].zf-scene-running .time--hero {
    transition:
        translate 0.78s var(--zf-in) 0.08s,
        opacity 0.5s ease 0.08s;
    opacity: 1;
    translate: 0 0;
}

html.zf-scene[data-zf-dir="home"].zf-scene-running .home-poem {
    transition:
        translate 0.78s var(--zf-in) 0.12s,
        opacity 0.5s ease 0.12s;
    opacity: 1;
    translate: 0 0;
}

/* ============================================================
   7. 子页面之间互相切换：内容下滑退场、新内容从底部上来
   ============================================================ */
html.zf-scene[data-zf-dir="page"].zf-scene-exiting #pjax-container > *:not(.lg-sidebar):not(.message-modal) {
    transition:
        translate 0.36s var(--zf-out),
        opacity 0.28s ease-in;
    translate: 0 40px;
    opacity: 0;
}

html.zf-scene[data-zf-dir="page"].zf-scene-entering #pjax-container > *:not(.lg-sidebar):not(.message-modal) {
    opacity: 0;
    translate: 0 44px;
}

html.zf-scene[data-zf-dir="page"].zf-scene-running #pjax-container > *:not(.lg-sidebar):not(.message-modal) {
    transition:
        translate 0.7s var(--zf-in),
        opacity 0.54s var(--zf-in);
    opacity: 1;
    translate: 0 0;
}


/* ============================================================
   8.1 手机端插画：尺寸与渐隐同源
   ------------------------------------------------------------
   手机首屏的插画按「首屏高度的 50%」定尺（见 zzerfu-home.css），
   渐隐线必须落在插画底边而不是首屏底边 —— 否则缩放半途会切出一条硬边。
   退场段让 background-size 与 mask 共用 JS 逐帧写入的 --zf-illu-h；
   入场段变量已经交还给 CSS，这里只补一个手机端的兜底尺寸。
   ============================================================ */
@media (max-width: 767px) {

    /* 退场：两边都跟着变量走，渐隐永远贴着插画底边 */
    html.zf-scene.zf-scene-exiting .bg-img::before {
        -webkit-mask-image: linear-gradient(to bottom,
                #000 calc(var(--zf-illu-h, 50%) - 76px),
                rgba(0, 0, 0, 0) var(--zf-illu-h, 50%));
        mask-image: linear-gradient(to bottom,
                #000 calc(var(--zf-illu-h, 50%) - 76px),
                rgba(0, 0, 0, 0) var(--zf-illu-h, 50%));
    }

    /* 入场：变量已清空，兜底值要跟各页面自己的定尺一致（首页 50%，子页 100%） */
    html.zf-scene[data-zf-dir="home"] .bg-img::before {
        background-size: auto var(--zf-illu-h, 50%) !important;
        background-position: center var(--zf-illu-y, 0%) !important;
    }
}

/* ============================================================
   8. 降低动效：整场关掉，直接换页
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
    html.zf-scene,
    html.zf-scene * {
        transition: none !important;
        animation: none !important;
    }
}
