/* ====== クロゼッタ シンプル版: バトルの見た目(ステージ・レーン・HUD) ======
   対象: docs/specs/DANCE_ARCH.md §3 のバトルの土台DOM
   - 色・文字は tokens.css の変数だけを使う(canvas の中の色も battle.js が変数から読む)
   - グラデーション文字・文字の発光・絵文字は使わない(文字の影は、読みやすくするためのベタの影だけ)
   - 主役は動画。文字と部品は少なく、画面の端へ寄せる
   - 上の表示(一時停止・ターンの帯・点・点差のゲージ)は、上の1本の帯にまとめる。動画はその帯の下に置く
     (2026-09-29 オーナーの実機プレイの指摘「上のゲージと顔が重なる」。全キャラ共通の直し) */

/* ===== 土台 =====
   :where() は優先度が0。画面担当の screens.css が同じものを決めたら、そちらが必ず勝つ */
:where(html, body) {
  height: 100%; margin: 0; overflow: hidden;
  background: var(--bg); color: var(--text);
  font-family: var(--font-jp); font-synthesis: none;
  touch-action: manipulation; overscroll-behavior: none;
  -webkit-touch-callout: none; -webkit-text-size-adjust: 100%;
}
:where(#app) {
  position: relative; height: 100%; height: 100dvh;
  max-width: 480px; margin: 0 auto; overflow: hidden;
  background: var(--bg);
}
:where(#app, #app *) { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* ===== 上の帯の大きさ =====
   帯の高さ = 端末の切り欠き + 100px。1段目 = 一時停止とターンの帯 / 2段目 = 点・点差のゲージ・点 */
#app {
  --hud-h: calc(var(--safe-t) + 100px);
  --hud-row2: calc(var(--safe-t) + 48px);
  --hud-side: 8px;
  --score-w: 104px;
}

/* ===== ステージ(動画): 上の帯の下から、画面の下まで =====
   帯の部分は地の色のまま(リザルトの間も暗い地)。動画は頭が切れない側(上)へ寄せる。足元はレーンの下になる */
#stage { position: absolute; inset: 0; overflow: hidden; background: var(--bg); }
#stage video, #stage img.poster {
  position: absolute; left: 0; right: 0; top: var(--hud-h); bottom: 0;
  width: 100%; height: calc(100% - var(--hud-h));
  object-fit: cover; object-position: 50% 0; border: 0;
  transition: filter .3s;
}
/* 帯の下のふちを、動画へなじませる(短いぼかし) */
#stage::after {
  content: ''; position: absolute; left: 0; right: 0; top: var(--hud-h); height: 14px;
  background: linear-gradient(180deg, var(--bg), transparent);
  pointer-events: none;
}
/* 絵がまだ決まっていないときは、こわれた絵の印を出さない */
#stage img.poster:not([src]) { visibility: hidden; }
/* コンボ4未満・よろけ・負けのときに動画を暗くする */
#stage .dimmed { filter: brightness(.45) saturate(.6); }
#stage.shake { animation: cdbStageShake .5s ease-out; }
@keyframes cdbStageShake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-9px) rotate(-.6deg); }
  40% { transform: translateX(8px) rotate(.5deg); }
  60% { transform: translateX(-6px); }
  80% { transform: translateX(4px); }
}

/* ===== レーン(動画に重ねる全画面。画面そのものがタップする場所) ===== */
#laneWrap {
  position: absolute; inset: 0; z-index: 3;
  touch-action: none; user-select: none; -webkit-user-select: none;
}
#cv { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* ===== HUD(バトル中だけ出す。タップはレーンへ通す) ===== */
/* 重なりの順番(下から): 動画 → 判定とコンボの文字(2) → レーンとマーク(3) → 光(4) → 帯の部品・数字(5) → 一時停止(6)
   判定とコンボの文字は、マークの「下」に敷く。文字がマークの通り道に重なっても、マークが隠れない
   (2026-09-29 検証担当の指摘: むずかしいの同時押しが、文字に隠れて読みにくかった)。
   そのため #hud 自身は重なりの層を作らない(z-index を付けない)。子が1つずつ順番を持つ */
#hud {
  position: absolute; inset: 0; pointer-events: none;
  font-family: var(--font-jp); color: var(--text);
}
#missFlash, #finishFlash { z-index: 4; }
#countdown, #turnBanner, #scores, #leadBar { z-index: 5; }
#combo, #judge { z-index: 2; }

/* ミスの赤いふち(動画の上だけ。上の帯には掛けない) */
#missFlash {
  position: absolute; inset: var(--hud-h) 0 0 0; opacity: 0;
  background: radial-gradient(ellipse at center, transparent 35%, var(--miss) 100%);
}
#missFlash.on { animation: cdbMissFlash .5s ease-out; }
@keyframes cdbMissFlash { 0% { opacity: .5; } 100% { opacity: 0; } }

/* キメを当てた光(決めポーズと同じ瞬間) */
#finishFlash {
  position: absolute; inset: var(--hud-h) 0 0 0; opacity: 0;
  background: radial-gradient(ellipse at 50% 46%, var(--text) 0%, var(--gold) 28%, transparent 72%);
  mix-blend-mode: screen;
}
#finishFlash.on { animation: cdbFinishFlash .6s ease-out; }
#finishFlash.on.cpu { animation-name: cdbFinishFlashCpu; }
@keyframes cdbFinishFlash { 0% { opacity: .9; } 100% { opacity: 0; } }
@keyframes cdbFinishFlashCpu { 0% { opacity: .35; } 100% { opacity: 0; } }

/* 3・2・1 と GO!(動画を帯の下へ下げたので、数字も下げる。小さい画面でも顔に重ならない高さ) */
#countdown {
  position: absolute; top: 54%; left: 50%; transform: translate(-50%, -50%);
  font-family: var(--font-num); font-size: calc(var(--fs-xl) * 2.8); line-height: 1;
  color: var(--text); opacity: 0; white-space: nowrap;
  text-shadow: 0 4px 0 var(--bg);
}
/* ターンの切り替わりの合図は小さく、レーンの近くに出す(決めポーズを隠さない) */
#countdown.mini { top: 50%; font-size: calc(var(--fs-xl) * 1.6); text-shadow: 0 3px 0 var(--bg); }
#countdown.pop { animation: cdbCountPop .42s ease-out forwards; }
@keyframes cdbCountPop {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(1.7); }
  30% { opacity: 1; }
  100% { opacity: .92; transform: translate(-50%, -50%) scale(1); }
}

/* ===== 上の帯 1段目: ターンの帯(まんなか)。一時停止ボタンは左(下のほうに書いてある) ===== */
#turnBanner {
  position: absolute; top: calc(7px + var(--safe-t)); left: 50%; transform: translateX(-50%);
  min-height: 34px; padding: 6px 18px; border-radius: 999px;
  display: flex; align-items: center;
  font-size: var(--fs-m); font-weight: 900; letter-spacing: .08em; white-space: nowrap;
  background: var(--pink); color: var(--text);
}
#turnBanner.cpu { background: var(--cyan); color: var(--bg); }
#turnBanner:empty { display: none; }

/* ===== 上の帯 2段目: 自分の点(左)・点差のゲージ(まんなか)・相手の点(右) =====
   箱は、名前(13px)・点(24px)・リベンジの表示(12px)の3行で49px。帯の中(100px)に収まる。
   だれのターンかは、外側の色の棒で示す */
#scores {
  position: absolute; top: var(--hud-row2); left: 0; right: 0;
  display: flex; justify-content: space-between; align-items: flex-start;
  padding: 0 var(--hud-side);
}
.scoreBox {
  width: var(--score-w); min-width: 0; padding: 0 0 0 8px;
  border-left: 3px solid var(--line);
  opacity: .72; transition: opacity .2s, border-color .2s;
}
#cpuBox { padding: 0 8px 0 0; border-left: 0; border-right: 3px solid var(--line); text-align: right; }
.scoreBox.active { opacity: 1; }
#p1Box.active { border-color: var(--pink); }
#cpuBox.active { border-color: var(--cyan); }
.scoreBox .name {
  font-family: var(--font-num); font-size: calc(var(--fs-s) * .92); letter-spacing: .1em;
  color: var(--text-dim); line-height: 13px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.scoreBox .val {
  font-family: var(--font-num); font-size: calc(var(--fs-l) * 1.1); line-height: 24px;
  font-variant-numeric: tabular-nums; letter-spacing: .02em; white-space: nowrap;
}
/* リベンジボーナスは、自分の点の下に小さく */
.scoreBox .tag {
  font-size: calc(var(--fs-s) * .85); font-weight: 700; line-height: 12px; color: var(--gold);
  white-space: nowrap;
}
.scoreBox .tag:empty { display: none; }

/* 点差のゲージ(左=自分・右=相手。まんなかの線より右まで桃色が伸びていれば、自分が勝っている)。
   2つの点のあいだ、点の数字と同じ高さに置く */
#leadBar {
  position: absolute; top: calc(var(--hud-row2) + 20px);
  left: calc(var(--hud-side) + var(--score-w) + 10px);
  right: calc(var(--hud-side) + var(--score-w) + 10px);
  height: 10px; border-radius: 999px; overflow: hidden;
  background: var(--cyan); border: 1px solid var(--line);
}
#leadFill {
  display: block; height: 100%; width: 50%;
  background: var(--pink);
  transition: width .25s ease-out;
}
#leadBar::after {
  content: ''; position: absolute; top: 0; bottom: 0; left: 50%;
  width: 2px; margin-left: -1px; background: var(--text);
}

/* コンボと判定(レーンの少し上) */
/* 判定とコンボは、判定の線に着く直前のマークに重ならない高さに出す(線は下から14%)。
   コンボは白(キメの帯が金色なので、重なっても読めるように) */
#combo {
  position: absolute; bottom: 39%; left: 50%; transform: translateX(-50%);
  font-family: var(--font-num); font-size: var(--fs-l); letter-spacing: .06em;
  color: var(--text); white-space: nowrap;
  text-shadow: 0 2px 0 var(--bg);
}
#judge {
  position: absolute; bottom: 31%; left: 50%; transform: translateX(-50%);
  font-family: var(--font-num); font-size: var(--fs-xl); letter-spacing: .06em; line-height: 1;
  opacity: 0; white-space: nowrap;
  text-shadow: 0 3px 0 var(--bg);
}
#judge.perfect { color: var(--perfect); }
#judge.good { color: var(--good); }
#judge.miss { color: var(--miss); font-size: calc(var(--fs-xl) * 1.3); }
/* 相手の判定は小さく(主役はダンス) */
#judge.cpu { font-size: var(--fs-l); }
#judge.cpu.miss { font-size: var(--fs-l); }
#judge.pop { animation: cdbJudgePop .45s ease-out; }
#judge.cpu.pop { animation-name: cdbJudgePopCpu; }
@keyframes cdbJudgePop {
  0% { opacity: 0; transform: translateX(-50%) scale(.6); }
  25% { opacity: 1; transform: translateX(-50%) scale(1.15); }
  70% { opacity: 1; }
  100% { opacity: 0; transform: translateX(-50%) scale(1); }
}
@keyframes cdbJudgePopCpu {
  0% { opacity: 0; transform: translateX(-50%) scale(.8); }
  25% { opacity: .7; transform: translateX(-50%) scale(1); }
  70% { opacity: .7; }
  100% { opacity: 0; transform: translateX(-50%) scale(1); }
}

/* 一時停止ボタン(縦棒2本の図形。HUDはタップを通すので、ここだけ受ける) */
#pauseBtn {
  position: absolute; top: calc(2px + var(--safe-t)); left: 6px;
  width: 44px; height: 44px; padding: 0; border-radius: 50%;
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  cursor: pointer; pointer-events: auto; z-index: 6;
  -webkit-appearance: none; appearance: none;
}
#pauseBtn::before, #pauseBtn::after {
  content: ''; position: absolute; top: 14px; width: 5px; height: 14px;
  border-radius: 2px; background: currentColor;
}
#pauseBtn::before { left: 13px; }
#pauseBtn::after { right: 13px; }
#pauseBtn:focus-visible { outline: 3px solid var(--cyan); outline-offset: 2px; }

/* 幅のせまい画面では、点の箱を少しせまくして、ゲージの幅を残す */
@media (max-width: 340px) {
  #app { --score-w: 96px; }
  #turnBanner { font-size: var(--fs-s); padding: 6px 12px; }
}

/* 高さの低い画面(スマホを横にしたとき等)では、判定とコンボを受け皿から離す */
@media (max-height: 520px) {
  #combo { bottom: 44%; }
  #judge { bottom: 33%; }
  #countdown, #countdown.mini { top: 50%; }
}

/* ===== 動きを減らす設定のときは、揺れ・点滅を止める ===== */
@media (prefers-reduced-motion: reduce) {
  #stage.shake, #missFlash.on, #finishFlash.on { animation: none !important; }
  #judge.pop, #countdown.pop { animation: none !important; opacity: 1; }
  #judge.cpu.pop { opacity: .7; }
  #stage video, #stage img.poster, #leadFill, .scoreBox { transition: none; }
}
