/* 2512 班级网站 — 动画层
   粒子汇聚 / 墨色晕染（canvas）+ 折纸展开（CSS 3D）
   与 gate.css 配合；低端设备由 fx.js 自动跳过 canvas 部分 */

/* ---------- canvas 舞台 ---------- */
.fx-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  display: block;
}
/* 悬停微粒层：压在内容下面一点，不挡点击 */
.fx-spark { z-index: 5; }

/* ---------- 入口卡片：粒子成形后才淡入 ---------- */
/* fx.js 跑粒子时，先把卡片藏起来 */
.gate.fx-wait .gate-inner {
  opacity: 0;
  transform: translateY(14px) scale(0.985);
}
.gate .gate-inner {
  transition: opacity 0.72s cubic-bezier(0.25, 0.6, 0.3, 1),
              transform 0.72s cubic-bezier(0.25, 0.6, 0.3, 1);
}
/* 粒子收尾 → 加 fx-ready，卡片升起 */
.gate.fx-ready .gate-inner {
  opacity: 1;
  transform: none;
}

/* 卡片内部元素错落浮现 */
.gate.fx-ready .g-num   { animation: fx-rise 0.62s cubic-bezier(0.25, 0.6, 0.3, 1) 0.04s both; }
.gate.fx-ready .g-sub   { animation: fx-rise 0.62s cubic-bezier(0.25, 0.6, 0.3, 1) 0.10s both; }
.gate.fx-ready .g-hint  { animation: fx-rise 0.62s cubic-bezier(0.25, 0.6, 0.3, 1) 0.16s both; }
.gate.fx-ready .g-q     { animation: fx-rise 0.62s cubic-bezier(0.25, 0.6, 0.3, 1) 0.22s both; }
.gate.fx-ready input    { animation: fx-rise 0.62s cubic-bezier(0.25, 0.6, 0.3, 1) 0.28s both; }
.gate.fx-ready .g-btn   { animation: fx-rise 0.62s cubic-bezier(0.25, 0.6, 0.3, 1) 0.34s both; }
.gate.fx-ready .g-credits { animation: fx-rise 0.62s cubic-bezier(0.25, 0.6, 0.3, 1) 0.42s both; }

@keyframes fx-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* 墨色晕染接管退场时，不要再叠 gate.css 的淡出位移 */
.gate.ink-exit {
  transition: none;
  opacity: 1;
}
.gate.ink-exit .gate-inner { transition: none; }

/* ---------- 区块进场：按场景分配不同手法 ---------- */
/* 统一的基座：每个区块用 data-fx 声明自己的进场方式，
   fx.js 进视口时加 .fold-in。默认（未声明）走"浮纸上升"。
   .reveal 可能挂在 <section> 也可能挂在 <main>，故只用 class 选择 */
/* 基座只放各场景共用的属性，不含任何视觉初始态 ——
   避免基座的 .fold-in 规则（特异性更高）反向覆盖场景声明 */
.reveal > .wrap,
.fold > .wrap {
  position: relative;
  will-change: transform, opacity;
}

/* ===== 默认 / data-fx="paper" —— 浮纸上升 + 景深虚化 =====
   用于正文型区块（建议页等），克制干净。
   用 :not([data-fx]) 限定，使其只作用于未声明场景的区块 */
.reveal:not([data-fx]),
.fold:not([data-fx]),
[data-fx="paper"] { perspective: 1600px; }

.reveal:not([data-fx]) > .wrap,
.fold:not([data-fx]) > .wrap,
[data-fx="paper"] > .wrap {
  transform-origin: center bottom;
  transform: translateZ(-120px) translateY(24px) rotateX(6deg);
  opacity: 0;
  filter: blur(4px);
  transition: transform 0.82s cubic-bezier(0.16, 0.84, 0.44, 1),
              opacity 0.6s cubic-bezier(0.25, 0.6, 0.3, 1),
              filter 0.6s cubic-bezier(0.25, 0.6, 0.3, 1);
}
.reveal:not([data-fx]).fold-in > .wrap,
.fold:not([data-fx]).fold-in > .wrap,
[data-fx="paper"].fold-in > .wrap {
  transform: none;
  opacity: 1;
  filter: blur(0);
}

/* ===== data-fx="scroll" —— 卷轴展开 =====
   用于时间线：从左往右舒展，像摊开一卷纪年 */
[data-fx="scroll"] { perspective: 1900px; }
[data-fx="scroll"] > .wrap {
  transform-origin: left center;
  transform: rotateY(38deg) scaleX(0.86);
  opacity: 0;
  filter: none;
  box-shadow: 18px 0 32px -20px rgba(38, 36, 31, 0.3);
  transition: transform 0.95s cubic-bezier(0.2, 0.8, 0.3, 1),
              opacity 0.6s ease,
              box-shadow 0.95s ease;
}
[data-fx="scroll"].fold-in > .wrap {
  transform: none;
  opacity: 1;
  box-shadow: none;
}

/* ===== data-fx="ink" —— 墨滴扩散显影 =====
   用于相册：从中心一点晕开，起笔处带朱砂墨晕 */
[data-fx="ink"] { perspective: none; }
[data-fx="ink"] > .wrap {
  transform: none;
  filter: none;
  clip-path: circle(0% at 50% 42%);
  opacity: 0;
  transition: clip-path 1.15s cubic-bezier(0.24, 0.78, 0.3, 1),
              opacity 0.5s ease;
}
[data-fx="ink"].fold-in > .wrap {
  clip-path: circle(140% at 50% 42%);
  opacity: 1;
}
/* 未显影时中心的墨晕，显影后散去 */
[data-fx="ink"] > .wrap::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(circle at 50% 42%,
    rgba(164, 52, 42, 0.13), rgba(164, 52, 42, 0.04) 38%, transparent 62%);
  opacity: 1;
  transition: opacity 0.9s ease;
}
[data-fx="ink"].fold-in > .wrap::after { opacity: 0; }

/* ===== data-fx="stagger" —— 分块错位入场 =====
   用于留言墙：区块内元素左右交错滑入，带轻微回弹 */
[data-fx="stagger"] { perspective: none; }
[data-fx="stagger"] > .wrap {
  transform: none;
  filter: none;
  opacity: 0;
  transition: opacity 0.45s ease;
}
[data-fx="stagger"].fold-in > .wrap { opacity: 1; }
[data-fx="stagger"] > .wrap > * {
  opacity: 0;
  transform: translateX(var(--fx-dx, -16px)) translateY(9px);
  transition: transform 0.72s cubic-bezier(0.2, 1.14, 0.4, 1),
              opacity 0.5s ease;
  transition-delay: calc(var(--fx-i, 0) * 0.085s);
}
[data-fx="stagger"] > .wrap > *:nth-child(even) { --fx-dx: 18px; }
[data-fx="stagger"].fold-in > .wrap > * {
  opacity: 1;
  transform: none;
}

/* ===== data-fx="fold" —— 折纸展开（保留） =====
   用于同学名单：与内部"书页翻开"同属纸张语汇 */
[data-fx="fold"] { perspective: 1400px; }
[data-fx="fold"] > .wrap {
  transform-origin: top center;
  transform: rotateX(-72deg) translateY(10px);
  opacity: 0;
  filter: none;
  backface-visibility: hidden;
  transition: transform 0.86s cubic-bezier(0.22, 0.72, 0.24, 1),
              opacity 0.62s cubic-bezier(0.25, 0.6, 0.3, 1);
}
[data-fx="fold"].fold-in > .wrap {
  transform: none;
  opacity: 1;
}
/* 折痕阴影，摊平即消失 */
[data-fx="fold"] > .wrap::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 42px;
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(38, 36, 31, 0.14), transparent);
  opacity: 1;
  transition: opacity 0.7s ease;
}
[data-fx="fold"].fold-in > .wrap::before { opacity: 0; }

/* hero 不做区块级变换（首屏要立刻可读），只靠内部元素墨色浮起 */
.hero,
[data-fx="hero"] { perspective: none; }
.hero > .wrap,
[data-fx="hero"] > .wrap {
  transform: none !important;
  opacity: 1 !important;
  filter: none !important;
  clip-path: none !important;
}
.hero > .wrap::before,
.hero > .wrap::after { display: none; }

/* 首屏标题：墨色由淡转浓 */
body.gate-open .hero h1,
body:not(.gated) .hero h1 {
  animation: fx-ink-in 1.05s cubic-bezier(0.25, 0.6, 0.3, 1) both;
}
@keyframes fx-ink-in {
  from { opacity: 0; color: var(--ink-faint); filter: blur(3px); transform: translateY(12px); }
  60%  { opacity: 1; filter: blur(0); }
  to   { opacity: 1; color: var(--ink); filter: blur(0); transform: none; }
}
body.gate-open .hero .sub,
body:not(.gated) .hero .sub { animation: fx-rise 0.8s cubic-bezier(0.25, 0.6, 0.3, 1) 0.26s both; }
body.gate-open .hero .cta,
body:not(.gated) .hero .cta { animation: fx-rise 0.8s cubic-bezier(0.25, 0.6, 0.3, 1) 0.38s both; }

/* ---------- 名单：字母组像书页翻开 ---------- */
.letter-group {
  perspective: 1200px;
}
.letter-group .names {
  transform-origin: left center;
  animation: fx-page 0.78s cubic-bezier(0.22, 0.72, 0.24, 1) both;
  animation-delay: calc(var(--group-i, 0) * 0.075s);
}
@keyframes fx-page {
  from { transform: rotateY(-32deg) translateX(-10px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
.letter-group .letter {
  animation: fx-rise 0.7s cubic-bezier(0.25, 0.6, 0.3, 1) both;
  animation-delay: calc(var(--group-i, 0) * 0.075s);
}

/* 名字悬停：轻微上浮（下划线由 main.css 的 ::before 负责，不重复） */
.letter-group .name:hover { transform: translateY(-2px); }

/* ---------- 照片卡：翻页倾斜 ---------- */
.photos { perspective: 1000px; }
.ph {
  transform-style: preserve-3d;
  transition: transform 0.5s cubic-bezier(0.22, 0.72, 0.24, 1), box-shadow 0.5s;
}
.ph:hover {
  transform: translateY(-5px) rotateY(-7deg) rotateX(3deg);
  box-shadow: -10px 16px 34px -16px rgba(38, 36, 31, 0.36);
}

/* ---------- 时间线：墨点扩散 ---------- */
.tl-item::before {
  transition: box-shadow 0.45s cubic-bezier(0.25, 0.6, 0.3, 1),
              background-color 0.3s;
}
.tl-item:hover::before {
  box-shadow: 0 0 0 5px rgba(164, 52, 42, 0.14),
              0 0 0 11px rgba(164, 52, 42, 0.06);
}

/* ---------- 留言卡：墨边扩散 ---------- */
.msg {
  position: relative;
  overflow: hidden;
}
.msg::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(circle at 12% 0%, rgba(164, 52, 42, 0.07), transparent 62%);
  opacity: 0;
  transition: opacity 0.45s ease;
}
.msg:hover::after { opacity: 1; }

/* ---------- 减少动态效果：全部退回朴素淡入 ---------- */
@media (prefers-reduced-motion: reduce) {
  .fx-canvas { display: none !important; }

  .gate.fx-wait .gate-inner,
  .gate.fx-ready .gate-inner { opacity: 1; transform: none; animation: none; }
  .gate.fx-ready .g-num, .gate.fx-ready .g-sub, .gate.fx-ready .g-hint,
  .gate.fx-ready .g-q, .gate.fx-ready input, .gate.fx-ready .g-btn,
  .gate.fx-ready .g-credits { animation: none; }

  .section.reveal > .wrap, .fold > .wrap,
  [data-fx] > .wrap, [data-fx] > .wrap > * {
    transform: none !important;
    opacity: 1 !important;
    filter: none !important;
    clip-path: none !important;
    box-shadow: none !important;
    transition: none !important;
  }
  .section.reveal > .wrap::before, .fold > .wrap::before,
  [data-fx] > .wrap::before, [data-fx] > .wrap::after { display: none !important; }

  .hero h1, .hero .sub, .hero .cta,
  .letter-group .names, .letter-group .letter { animation: none !important; }

  .ph:hover { transform: none; }
  .letter-group .name:hover { transform: none; }
}
