/* ============================================================
   page-transitions.css — macOS 风格页面切换
   设计语言（呼应 macOS 窗口动画）：
     · 退场：当前页面像窗口被「收起」——整体缩小 + 轻微下坠 + 模糊 + 变暗，
       而非单纯的平面淡出，营造纵深。
     · 遮罩：磨砂玻璃（backdrop blur），与项目已有的液态玻璃 / 导航亚克力一致。
     · 弹性：统一使用 macOS 标准缓动 cubic-bezier(.32,.72,0,1)（spring 化）。
     · 入场：新页面从缩放 .98 + 轻微模糊 + 上移 8px 「浮现」（materialize），
       收尾略微 overshoot 再回弹，带 macOS 的「启动」手感。
   仅使用 JS 覆盖层动画，禁用 View Transitions API 自动跨文档切换，
   避免两套动画同时运行导致的「一闪一闪」。
   ============================================================ */

html { background: #07101f; }
html[data-theme="light"] { background: #edf3fb; }

/* ============================================================
   磨砂玻璃覆盖层（单一模糊层：舞台提供磨砂，遮罩仅做色调，
   避免多层 backdrop-filter 叠加在 Chromium 下抖动）
   ============================================================ */
.pt-veil {
  position: fixed; inset: 0; z-index: 2147483100; pointer-events: none;
  background: rgba(4,8,19,.35);
  opacity: 0;
  will-change: opacity;
  transition: opacity 300ms cubic-bezier(.32,.72,0,1);
}
.pt-veil.is-in { opacity: 1; }
html[data-theme="light"] .pt-veil { background: rgba(237,243,251,.4); }

/* ---------- 退场：macOS「窗口收起」 ---------- */
html.pt-nav-switching,
html.pt-home-closing { overflow: hidden !important; }
/* 退场只锁滚动，不再对 body 做 opacity/transform 动画：
   在含 backdrop-filter/blur 的重页面上动 body 的 opacity 会让浏览器每帧
   重算全部滤镜，在大视口的电脑端会严重掉帧。转场遮盖交给 veil + 新页黑屏遮罩。 */
html.pt-nav-switching body,
html.pt-home-closing body {
  overflow: hidden !important;
}

/* ---------- 退场舞台：磨砂 + 中央「正在打开」卡片（带弹性启动） ---------- */
.pt-switch-stage {
  position: fixed; z-index: 2147483200; inset: 0; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  background: rgba(3,7,17,.45);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  will-change: opacity;
  animation: pt-stage-in 300ms cubic-bezier(.32,.72,0,1) both;
}
.pt-incoming-label {
  position: relative; z-index: 2;
  display: flex; align-items: center; gap: 12px;
  min-width: min(300px, calc(100% - 32px)); padding: 14px 18px;
  border: 1px solid rgba(255,255,255,.22); border-radius: 18px;
  color: #f6f9ff;
  background: rgba(16,24,44,.82);
  box-shadow: 0 24px 60px rgba(0,0,0,.42), inset 0 1px 0 rgba(255,255,255,.14);
  transform: scale(.92); opacity: 0;
  animation: pt-label-pop 420ms cubic-bezier(.32,.72,0,1) 60ms both;
}
@keyframes pt-stage-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes pt-label-pop {
  0%   { opacity: 0; transform: scale(.88) translateY(6px); }
  60%  { opacity: 1; transform: scale(1.015); }
  100% { opacity: 1; transform: scale(1); }
}
.pt-loading-emoji { font-size: 26px; line-height: 1; }
.pt-loading-copy b { display: block; font-size: clamp(14px,2vw,22px); letter-spacing: -.03em; }
.pt-loading-copy small { display: block; margin-top: 3px; font-size: 11px; opacity: .68; }

.pt-home-stage {
  position: fixed; z-index: 2147483300; inset: 0; display: grid; place-items: center;
  pointer-events: none;
  background: radial-gradient(circle at 50% 46%, rgba(102,174,255,.22), rgba(4,8,19,.5) 42%, rgba(3,6,15,.85) 78%);
  animation: pt-stage-in 280ms cubic-bezier(.32,.72,0,1) both;
}
.pt-home-label {
  position: relative; z-index: 2;
  display: flex; align-items: center; gap: 12px;
  min-width: min(300px, calc(100% - 34px)); padding: 14px 18px;
  border: 1px solid rgba(255,255,255,.2); border-radius: 18px;
  color: #f7faff;
  background: rgba(12,20,38,.82);
  box-shadow: 0 24px 60px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.14);
  transform: scale(.92); opacity: 0;
  animation: pt-label-pop 420ms cubic-bezier(.32,.72,0,1) 60ms both;
}

/* ---------- 磁贴 / 卡片展开：来源卡片放大铺满 ---------- */
.pt-route-overlay {
  position: fixed; z-index: 2147483000; inset: 0; pointer-events: none; opacity: 0;
  background: radial-gradient(120% 100% at var(--pt-x,50%) var(--pt-y,50%), rgba(93,164,255,.16), rgba(4,8,19,.72) 66%);
  backdrop-filter: blur(10px) saturate(150%);
  -webkit-backdrop-filter: blur(10px) saturate(150%);
  will-change: opacity;
  transition: opacity 300ms linear;
}
.pt-route-overlay.is-active { opacity: 1; }
.pt-route-card {
  position: fixed; display: flex; align-items: center; gap: 14px; overflow: hidden;
  border: 1px solid rgba(255,255,255,.3); border-radius: 20px; color: #f8fbff;
  background: linear-gradient(135deg, rgba(103,183,255,.85), rgba(127,105,245,.82) 54%, rgba(31,39,78,.9));
  box-shadow: 0 30px 80px rgba(0,0,0,.45), inset 0 1px 1px rgba(255,255,255,.3);
  transform: translate3d(0,0,0) scale(.96);
  transform-origin: top left;
  will-change: transform;
  transition: transform 400ms cubic-bezier(.32,.72,0,1);
}
.pt-route-card > * { position: relative; z-index: 1; }
.pt-route-icon { font-size: clamp(26px,4vw,54px); line-height: 1; }
.pt-route-copy { min-width: 0; }
.pt-route-copy b { display: block; font-size: clamp(15px,2vw,25px); letter-spacing: -.03em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pt-route-copy small { display: block; margin-top: 4px; opacity: .76; font-size: 12px; }
.pt-route-overlay[data-kind="nav"] .pt-route-card { padding: 0 18px; }
.pt-route-overlay[data-kind="tile"] .pt-route-card { justify-content: center; text-align: center; flex-direction: column; padding: 22px; }

/* ---------- 全屏「摩天轮」切换（PPT Ferris Wheel） ---------- */
/* 纯 rotate（GPU 合成），无 backdrop-filter，不卡顿。卡片画面 = 真实页面截图（--shot）。 */
.pt-flip {
  position: fixed; inset: 0; z-index: 2147483000; pointer-events: none;
  display: grid; place-items: center;
  background: #05080f;
  opacity: 0;
  transition: opacity 240ms ease;
}
.pt-flip.is-in { opacity: 1; }
.pt-flip-deck {
  position: relative;
  width: 100vw; height: 100vh;
}
.pt-flip-card {
  position: absolute; inset: 0;
  background: linear-gradient(135deg, rgba(30,44,80,.97), rgba(12,20,42,.99));
  border: 1px solid rgba(255,255,255,.12);
  box-shadow: 0 40px 120px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.18);
  color: #eaf2ff;
  backface-visibility: hidden;
  transform-origin: 130% 50%;            /* 屏幕右侧外的偏心轴 → 摩天轮 */
  will-change: transform;
  transition: transform 720ms cubic-bezier(.45,.05,.25,1);
  background-image: var(--shot, none);   /* 有真实截图则覆盖渐变占位 */
  background-size: cover;
  background-position: center;
}
.pt-flip-from { transform: rotate(0deg); }
.pt-flip-to   { transform: rotate(100deg); }
.pt-flip-card .pt-fc-sub {
  position: absolute; left: 50%; bottom: 26px; transform: translateX(-50%);
  display:grid;grid-template-columns:auto 1fr auto;align-items:center;column-gap:10px;
  width:min(480px,calc(100% - 32px));font-size:14px;
  background: rgba(4,10,22,.72);padding:12px 15px;border:1px solid rgba(255,255,255,.16);border-radius:18px;
  box-shadow:0 16px 48px rgba(0,0,0,.34);backdrop-filter:blur(12px) saturate(140%);
}
.pt-fc-sub i{grid-row:1/3;font-style:normal;font-size:26px;line-height:1}
.pt-fc-sub b{font-size:14px;letter-spacing:.02em}
.pt-fc-sub small{grid-column:2;color:rgba(234,242,255,.7);font-size:11px;margin-top:2px}
.pt-fc-sub em{grid-column:3;grid-row:1/3;width:18px;height:18px;border:2px solid rgba(255,255,255,.22);border-top-color:#7fc2ff;border-radius:50%;animation:pt-spin .75s linear infinite}
@keyframes pt-spin{to{transform:rotate(360deg)}}
@media(max-width:520px){
  .pt-flip-card .pt-fc-sub{bottom:18px}
}

/* ---------- 入场：macOS「浮现 / 启动」 ---------- */
/* 两段式：先让 body 在首屏即隐藏（露出暗色背景，避免白屏/内容未就绪就闪现），
   待资源(window.load，含 nav.js 构建的导航)就绪后，再由 .pt-reveal 触发 materialize，
   这样背景与内容同步到位，消除「一闪一闪」。 */
/* 入场不再对 body 做 opacity/materialize 动画（同样会触发全屏滤镜每帧重算）。
   新页面的黑屏加载遮罩(page-anims 的 html::before)已负责首屏遮盖并平滑淡出，
   body 保持可见即可，转场路径与「直接刷新」一致，顺滑不卡。 */
html.pt-entering body { opacity: 1; }
html.pt-entering.pt-reveal body { animation: none; }

/* ---------- 减少动效：全面退化 ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; transition-duration: 1ms !important; }
  .pt-veil, .pt-switch-stage, .pt-home-stage, .pt-route-overlay { display: none !important; }
  html.pt-entering body { opacity: 1 !important; }   /* 减弱动效时直接显示，不被 prep 隐藏卡住 */
}
