/* ============================================================
   scene.css —— 三个场景：加载 / 封面 / 正片
   ============================================================ */

html, body {
  height: 100%;
  overflow: hidden;
  background: var(--bg-0);
}

/* ---------- 场景容器 ---------- */
.scene {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-0);
  opacity: 0;
  pointer-events: none;
  transition: opacity .7s ease;
}

.scene.is-on {
  opacity: 1;
  pointer-events: auto;
}

.scene .dots {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(circle at 1px 1px, var(--dot) 1.2px, transparent 0);
  background-size: 9px 9px;
  pointer-events: none;
}

/* ============================================================
   1. 加载
   ============================================================ */
.ld {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  z-index: 2;
}

.ring-wrap {
  position: relative;
  width: 132px;
  height: 132px;
}

.ring {
  width: 100%;
  height: 100%;
  transform: rotate(-90deg);
}

.ring-track {
  fill: none;
  stroke: var(--dot);
  stroke-width: 3;
}

.ring-bar {
  fill: none;
  stroke: var(--blue);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 326.73;      /* 2πr, r=52 */
  stroke-dashoffset: 326.73;
  transition: stroke-dashoffset .35s linear;
}

/* 百分比文字：绝对居在环里，不写死像素 */
.ld-pct {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--f-mono);
  font-size: 22px;
  color: var(--ink);
  letter-spacing: .02em;
}

.ld-cn {
  margin-top: 34px;
  font-size: 26px;
  font-weight: 400;
  color: var(--ink);
  letter-spacing: .18em;
}

.ld-en {
  margin-top: 10px;
  font-family: var(--f-mono);
  font-size: 13px;
  color: var(--sub);
  letter-spacing: .1em;
}

.ld-soon {
  margin-top: 46px;
  font-family: var(--f-mono);
  font-size: 12px;
  color: var(--deco);
  letter-spacing: .34em;
  text-transform: uppercase;
}

/* ============================================================
   2. 封面
   ============================================================ */
.cover-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  z-index: 2;
  transition: opacity .45s ease, transform .45s ease;
}

.cover-inner.is-out {
  opacity: 0;
  transform: translateY(-12px);
}

/* From / To —— 标题上方的署名行 */
.cover-from {
  display: flex;
  flex-direction: column;
  gap: .55em;
  margin-bottom: clamp(30px, 4.5vh, 52px);
  font-family: var(--f-mono);
  font-size: clamp(19px, 1.85vw, 34px);
  letter-spacing: .05em;
  color: var(--sub);
  line-height: 1.35;
}

.cover-from span:last-child { color: var(--ink); }

.cover-cn {
  margin: 0;
  font-size: clamp(64px, 8.6vw, 168px);
  font-weight: 400;              /* 封面仍用 Normal 字体，靠描边把笔画加粗 */
  -webkit-text-stroke: .045em currentColor;   /* ← 视觉加粗，不换字体 */
  paint-order: stroke fill;
  letter-spacing: .04em;
  line-height: 1.08;
  color: var(--ink);
}

.cover-cn em {
  font-style: normal;
  color: var(--orange);
}

.cover-en {
  margin: 22px 0 0;
  font-family: var(--f-mono);
  font-size: clamp(15px, 1.5vw, 28px);
  -webkit-text-stroke: .035em currentColor;
  paint-order: stroke fill;
  color: var(--sub);
  letter-spacing: .02em;
}

.cover-en em {
  font-style: normal;
  color: var(--blue);
}

.cover-hint {
  margin-top: clamp(38px, 6.5vh, 78px);
  padding: 16px 42px;
  border: 2px solid var(--green);
  border-radius: 999px;
  background: rgba(0, 135, 90, .08);
  cursor: pointer;
  font-family: var(--f-mono);
  font-size: clamp(17px, 1.65vw, 27px);
  font-weight: 400;
  -webkit-text-stroke: .012em currentColor;
  letter-spacing: .18em;
  color: var(--green);
  box-shadow: 0 3px 0 rgba(0, 135, 90, .14);
  animation: hintBreath 2.6s ease-in-out infinite;
}

.cover-hint:hover { opacity: .55; animation-play-state: paused; }

@keyframes hintBreath {
  0%, 100% { opacity: .45; }
  50%      { opacity: 1; }
}

.cover-robot {
  position: absolute;
  left: 50%;
  bottom: 8%;
  transform: translateX(-50%);
  margin: 0;
  font-family: var(--f-mono);
  font-size: 17px;
  line-height: 1.05;
  color: var(--ink);
  opacity: .8;
  z-index: 1;
}

.cover-robot em { color: var(--green-l); font-style: normal; }

/* ============================================================
   3. 正片
   ============================================================ */
.film-stage {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.film-stage .stage {
  position: absolute;
  left: 50%;
  top: 50%;
  transform-origin: center center;   /* 缩放由 js/film.js 的 fit() 设置 */
  transition: background-color .8s ease;
}

/* 重击点白闪：从"爆闪"改成"一次柔和的呼吸"，只提亮一下 */
.flash {
  position: absolute;
  inset: 0;
  background: #F7FBFF;
  opacity: 0;
  pointer-events: none;
  z-index: 9;
}

.flash.is-fire {
  animation: flashFire 240ms ease-out;
}

@keyframes flashFire {
  0%   { opacity: 0; }
  14%  { opacity: .32; }
  100% { opacity: 0; }
}

.pause-tip {
  position: absolute;
  left: 50%;
  bottom: 6%;
  transform: translateX(-50%);
  font-family: var(--f-mono);
  font-size: 13px;
  letter-spacing: .16em;
  color: var(--sub);
  opacity: 0;
  transition: opacity .3s;
  pointer-events: none;
  z-index: 10;
}

.pause-tip.is-on { opacity: 1; }

/* ============================================================
   正片的入场动画（由 js/film.js 在每次切镜时加 .enter 触发）
   原则：只有"透明度 + 6~10px 的轻微上浮"，不用 scale、不用回弹，
        时长 0.5s 以上，靠"错开"而不是"弹出"来制造节奏
   ============================================================ */
.stage.enter .hero .line {
  /* 行不再整体动，动效交给逐字 */
  animation: none;
}

/* 逐字浮现：每个字只做"淡入 + 8px 上浮"，靠 --i 错开 */
.stage.enter .ch {
  display: inline-block;
  animation: chIn .42s cubic-bezier(.22, .61, .36, 1) both;
  animation-delay: calc(var(--i, 0) * var(--step, 45ms));
}

@keyframes chIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* 重复堆叠镜头里的"历史行"：已经在画面上了，不再重播动画 */
.stage.enter .hero .line.is-static .ch {
  animation: none;
  opacity: 1;
  transform: none;
}

.stage.enter .eng {
  animation: softIn .5s cubic-bezier(.22, .61, .36, 1) .3s both;
}

@keyframes softIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: .95; transform: none; }
}

/* 文字与上一镜完全相同时（4-7 → 4-8 这类），整屏都不重播入场，
   只有内容差异（比如代码消失）真正发生变化 */
.stage.no-entry .ch,
.stage.no-entry .eng,
.stage.no-entry .code,
.stage.no-entry .deco,
.stage.no-entry .emoji {
  animation: none !important;
  opacity: 1;
}

.stage.no-entry .hero .ch { transform: none; }

.stage.enter .code {
  animation: softIn .6s cubic-bezier(.22, .61, .36, 1) .25s both;
}

/* 8-1：JSON 里那一行 "validity_time": "forever" 缓缓放大，放大到看得见 */
.stage.enter .code .zoom {
  animation: codeZoom 6.4s cubic-bezier(.25, .1, .25, 1) .8s both;
}

@keyframes codeZoom {
  from { transform: scale(1); }
  to   { transform: scale(1.45); }
}

.stage.enter .deco {
  animation: decoIn .7s cubic-bezier(.22, .61, .36, 1) both;
}

@keyframes decoIn {
  from { opacity: 0; transform: translate(-50%, calc(-50% + 10px)); }
  to   { opacity: 1; transform: translate(-50%, -50%); }
}

/* worry 被「bye bye」赶走：镜头一开始就在，唱到 bye bye 之后向左飘出画外 */
.stage.enter .deco[data-fly] {
  animation: decoIn .7s cubic-bezier(.22, .61, .36, 1) both,
             flyOut 1.5s cubic-bezier(.4, 0, .7, 1) forwards;
  animation-delay: 0s, var(--fly, 3s);
}

@keyframes flyOut {
  from { opacity: 1; transform: translate(-50%, -50%); }
  to   { opacity: 0; transform: translate(calc(-50% - 58vw), -50%) scale(.9); }
}

.stage.enter .emoji {
  animation: emojiIn .6s cubic-bezier(.22, .61, .36, 1) both;
}

/* 留言页：语音条从左边依次浮入 */
.stage.enter .voicelist .voice {
  animation: voiceIn .7s cubic-bezier(.22, .61, .36, 1) both;
}

.stage.enter .voicelist .voice:nth-child(2) { animation-delay: .12s; }
.stage.enter .voicelist .voice:nth-child(3) { animation-delay: .24s; }
.stage.enter .voicelist .voice:nth-child(4) { animation-delay: .36s; }
.stage.enter .voicelist .voice:nth-child(5) { animation-delay: .48s; }

@keyframes voiceIn {
  from { opacity: 0; transform: translateX(-18px); }
  to   { opacity: 1; transform: none; }
}

.stage.enter .voicesub {
  animation: softIn .8s cubic-bezier(.22, .61, .36, 1) .5s both;
}

@keyframes emojiIn {
  from { opacity: 0; transform: translate(-50%, calc(-50% + 12px)); }
  to   { opacity: 1; transform: translate(-50%, -50%); }
}

/* 整词（bye bye / hi hi）：作为一个单元进场，比单个字更明显 */
.stage.enter .ch.phrase {
  animation: phraseIn .62s cubic-bezier(.22, .61, .36, 1) both;
  animation-delay: calc(var(--i, 0) * 45ms);
}

@keyframes phraseIn {
  from { opacity: 0; transform: translateY(16px) scale(.94); }
  to   { opacity: 1; transform: none; }
}

/* 刚插入的代码片段：从右侧滑进来，落位时底色闪一下再退掉 */
.stage.enter .code .ins {
  animation: insIn .55s cubic-bezier(.22, .61, .36, 1) both;
}

@keyframes insIn {
  from { opacity: 0; transform: translateX(16px); background: rgba(34, 197, 94, .55); }
  to   { opacity: 1; transform: none; background: rgba(34, 197, 94, .16); }
}
