/* ═══════════════════════════════════════════
   全息卡 · 翻卡页 —— 单屏布局 + 牌堆 + 翻卡/滑动动画
   （卡片本体效果全部来自 css/cards*.css，本文件只管页面布局与交互样式）
   ═══════════════════════════════════════════ */

:root {
  /* 视差默认值（原 Card.svelte 内联 :root）：idle 时由 js/main.js 驱动游移 */
  --pointer-x: 50%;
  --pointer-y: 50%;
  --card-scale: 1;
  --card-opacity: 0.55;
  --translate-x: 0px;
  --translate-y: 0px;
  --rotate-x: 0deg;
  --rotate-y: 0deg;
  --background-x: var(--pointer-x);
  --background-y: var(--pointer-y);
  --pointer-from-center: 0;
  --pointer-from-top: 0.5;
  --pointer-from-left: 0.5;

  /* 右划位移/旋转：由 js 驱动（px / deg），弹回与飞走时配合 transition */
  --swipe-x: 0px;
  --swipe-rot: 0deg;

  /* 黑体（无衬线）字体栈：作者文字与名字方框共用 */
  --font-heiti: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB",
    "Microsoft YaHei", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

html,
body {
  margin: 0;
  padding: 0;
  background: #94a3b8;
  color: #fff;
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  user-select: none;
}

/* ── 故障终端背景（vue-bits FaultyTerminal 移植，颜色 #94a3b8）──
   固定全屏垫底；pointer-events:none 不拦截卡牌手势；WebGL canvas 由 js 填充 */
.bg-terminal {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: #94a3b8;
}
.bg-terminal canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* 单屏舞台：整页就是牌堆，不需要滚动 */
.stage {
  position: relative; /* 盖在终端背景之上 */
  z-index: 1;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(12px, 3vh, 28px);
  padding: max(60px, env(safe-area-inset-top)) 20px max(20px, calc(env(safe-area-inset-bottom) + 14px));
  overflow: hidden;
  box-sizing: border-box;
  /* 卡宽（牌堆与作者标签共用）：手机 ~60vw 封顶 320px（比之前小，点按弹出放大比例更大、一眼可见）；
     矮屏按高度收缩，保证卡+文字一屏放下 */
  --stack-w: min(min(60vw, 320px), calc((100dvh - 230px) * 0.718));
}

/* ── iOS 26 Safari 竖屏 viewport-fit=cover 回归 workaround（WebKit bug #306465/#309743）──
   iOS 26 起 Safari 竖屏不再让页面内容渲染到状态栏（灵动岛）与底部地址栏后面，
   fixed 背景（inset:0）只覆盖安全区，上下露出白/灰条，点阵图案到不了工具栏区域。
   修复思路（.safari26 只由 main.js 加在 iPhone + Safari 26 上，旧系统零影响）：
   ① .bg-terminal 从 fixed 改为 absolute 随文档滚动，并向上/下出血
     （顶部 62px 状态栏+灵动岛区域、底部 136px 地址栏+工具栏区域）；
   ② body 加 62px 顶部滚动跑道（文档恰好可滚 62px）；
   ③ main.js 初始 scrollTo(0,62) → Safari 在工具栏后合成真实页面像素（点阵），
      而非采样纯色/白条；stage 用高度+负 margin 抵消滚动，内容仍精确居中。 */
html.safari26 {
  --safari26-top: 62px;     /* 顶部出血 = 滚动偏移（状态栏 + 灵动岛） */
  --safari26-bottom: 136px; /* 底部出血（底部地址栏 + 工具栏） */
  background: #94a3b8;      /* 滚动跑道外的边角兜底色 */
}
html.safari26 body {
  min-height: calc(100dvh + var(--safari26-top)); /* 可滚范围恰好 = 顶部出血 62px */
}
html.safari26 .bg-terminal {
  position: absolute; /* 随文档滚动：出血区的点阵才能被 Safari 合成到工具栏后 */
  inset: auto;
  top: 0;
  left: 0;
  width: 100%;
  height: calc(100dvh + var(--safari26-top) + var(--safari26-bottom));
}
html.safari26 .stage {
  /* 上下各出血：内容中心 = -(底-顶)/2 + (H+顶+底)/2 = H/2+顶 → 滚动偏移后仍居中 */
  height: calc(100dvh + var(--safari26-top) + var(--safari26-bottom));
  margin-top: calc(-1 * (var(--safari26-bottom) - var(--safari26-top)) / 2);
  margin-bottom: calc(-1 * (var(--safari26-bottom) + var(--safari26-top)) / 2);
}

/* ── 牌堆：fan 层叠在顶层卡后面 ── */
.stack {
  position: relative;
  width: var(--stack-w);
}

.stack .card {
  width: 100%;
}

/* 滑动：覆盖 base.css 的固定 transform，translateX + 旋转由 --swipe-* 驱动 */
.stack .card {
  -webkit-transform: translate3d(var(--swipe-x), 0, 0.01px) rotate(var(--swipe-rot));
  transform: translate3d(var(--swipe-x), 0, 0.01px) rotate(var(--swipe-rot));
}

.card__rotator {
  width: 100%;
  touch-action: none; /* 拖动划卡不让浏览器插手（本页无滚动） */
  /* 弹出 360° 翻转（pokemon-cards-css popover）叠加在视差倾斜之上：
     base.css 的 .card__translater 已接好 --card-scale/--translate-*（放大+抬升），
     这里只补 --pop-rot 这一环，默认 0deg 不影响原行为 */
  transform: rotateY(calc(var(--rotate-x) + var(--pop-rot, 0deg))) rotateX(var(--rotate-y));
}

.stack .card-wrap {
  position: relative;
  z-index: 1;
}

/* ── 牌堆里等待的下一张：恒在顶层卡下方同一位置（卡背朝上）──
   顶层卡划走时它自然露出（牌堆本来就有的下一张，不凭空冒出），
   露出后由 {#key} 重建的 Card 原位接替并自动翻面 */
.stack .card-wrap .next-back {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.stack .card-wrap .next-back .card__rotator {
  pointer-events: none; /* 覆盖 base.css .card__rotator 的 auto：纯装饰不接事件 */
}
.stack .card-wrap .next-back .card__back {
  transform: rotateY(0deg); /* 同 loading 态：背面正面朝上，不镜像 */
}

/* 划走后重建的新卡：从牌堆位置轻微升起（缩小+下移+半透明 → 就位），
   衔接"从牌堆抽出下一张"的节奏——深色卡背亮相的瞬间有运动感，不呆立"闪黑"。
   fill 默认 none：动画结束交还给 .stack .card 的 --swipe-* transform，拖动划卡不受影响 */
.card-wrap > .card:not(.next-back) {
  animation: card-rise 0.32s cubic-bezier(0.22, 0.8, 0.36, 1);
}
@keyframes card-rise {
  0%   { transform: translate3d(0, 14px, 0.01px) scale(0.94); opacity: 0.6; }
  100% { transform: translate3d(0, 0, 0.01px) scale(1); opacity: 1; }
}

/* 装饰牌堆：8 层卡背扇形，从顶层卡下沿露出 */
.stack__fan {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.stack__fan i {
  position: absolute;
  left: 2%;
  right: 2%;
  top: 0;
  aspect-ratio: var(--card-aspect);
  border-radius: var(--card-radius);
  background: url("../img/card-back.webp") center / cover no-repeat;
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 12px 26px rgba(0, 0, 0, 0.5);
  transform-origin: 50% 100%;
}
.stack__fan i:nth-child(1) { transform: rotate(-9deg)  translateY(24px) translateX(-10px); }
.stack__fan i:nth-child(2) { transform: rotate(-6deg)  translateY(18px) translateX(-7px); }
.stack__fan i:nth-child(3) { transform: rotate(-3deg)  translateY(12px) translateX(-4px); }
.stack__fan i:nth-child(4) { transform: rotate(0deg)   translateY(7px); }
.stack__fan i:nth-child(5) { transform: rotate(3deg)   translateY(12px) translateX(4px); }
.stack__fan i:nth-child(6) { transform: rotate(6deg)   translateY(18px) translateX(7px); }
.stack__fan i:nth-child(7) { transform: rotate(9deg)   translateY(24px) translateX(10px); }
.stack__fan i:nth-child(8) { transform: rotate(0deg)   translateY(30px); }

/* ── 翻卡效果（点一下翻开，pokemon-cards-css popover 移植）──
   翻转交给外层 .card__rotator 的 360° 弹簧旋转（--pop-rot，js 驱动）：
   移除 loading 时卡背瞬切到 rotateY(180)，不再自己做 0°→180° 过渡；
   backface visible（同 base.css/原版）→ 旋转到远侧时露出正确卡背，不会穿模 */
.card__back {
  backface-visibility: visible;
}

/* ── 自动翻面（划走后新卡 卡背→正面）：Fallout 卡牌翻卡动画移植 ──
   翻转挂在 back/front 外层 .card__flip 上，绕开 rotator 由 --rotate-* 驱动的
   视差/弹出变换；keyframes 同参考：0.275s linear，中点 -10° Z 轴摆一下 */
.card__flip {
  overflow: visible;             /* 覆盖 base.css .card__rotator * 的 overflow:hidden，保住 preserve-3d */
  transform-style: preserve-3d;
}
.card__flip.flipping { animation: card-flip 0.275s linear forwards; }
@keyframes card-flip {
  0%   { transform: rotateZ(0deg) rotateY(180deg); }
  50%  { transform: rotateZ(-10deg) rotateY(90deg); }
  100% { transform: rotateZ(0deg) rotateY(0deg); }
}
/* 翻转中：卡背必须保持 visible。旧做法给卡背加 backface-hidden 会让起始帧
   （容器 rotateY(180°)，卡背正好转到观众侧）连卡背一起隐掉 → 双面皆隐、
   卡片整片透明、透出下层深色卡背 = 划走时"闪黑"。
   去掉后：起始帧卡背正对观众（正确），随翻转自然转走，后半程前片转过来。
   前片淡入要够快（0.12s < 后半程 0.14s）：转到正面时已盖满，
   半透明期间透不出正后方的镜像卡背 */
.card__flip.flipping .card__front {
  transition: opacity 0.12s ease-out;
}

/* ── 弹回/飞走的过渡：由 js 临时加到 .card 上 ── */
.card.spring {
  transition: transform 0.35s cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* ── 标签与计数 ── */
.draw-label {
  margin: 0;
  font-size: 14px;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.72);
  min-height: 1.4em;
  text-align: center;
  line-height: 1.5;
}
.draw-label strong {
  color: #fff;
  font-weight: 600;
}

/* 作者标签态：与牌堆同宽、居中 → 方框左右两边都随名字长度伸缩；
   整体比默认标签低一些；黑体与方框一致 */
.draw-label.label-author {
  width: var(--stack-w);
  text-align: center;
  margin-top: 32px;
  font-family: var(--font-heiti);
}

/* 作者名字方框：同 pattens 标题旁 shuffle-code（2px 白框 + 乱序落定）。
   黑体（无衬线），不设固定宽度 → 框宽随名字长度自适应，左右两边随名字长短伸缩 */
.author-box {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.3rem 0.6rem;
  border: 2px solid #fff;
  border-radius: 5px;
  font-family: var(--font-heiti);
  font-size: 0.95rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #fff;
  line-height: 1.15;
  white-space: nowrap;
}

/* ── 动效减弱：不翻卡/不飞走/不弹回/不升起，直接切换 ── */
@media (prefers-reduced-motion: reduce) {
  .card.spring {
    transition: none;
  }
  .card-wrap > .card:not(.next-back) {
    animation: none;
  }
}
