/* ==========================================================================
   motion.css — 報道・密着カメラ風アニメーション

   設計方針:
   - 全部「短く・速く・言い切る」。1つあたり 0.28〜0.5秒で終わらせる。
   - スクロールを途中で止めても、要素は必ず最終状態（完全表示）で落ち着く。
     ＝ 進捗を巻き戻さない一方向トリガー。sticky でピンもしない。
   - 数値は scroll-cam.js が --in（0→1、一度1になったら戻らない）で供給する。
   ========================================================================== */

/* --- 基本の出現: 下から突き上げる ---------------------------------------- */
/* ふわっと出さない。短距離を速く、終端でピタッと止める。 */
[data-cam] {
  opacity: var(--in, 0);
  transform: translate3d(0, calc((1 - var(--in, 0)) * 18px), 0);
  transition: opacity 0.32s cubic-bezier(0.2, 0.9, 0.25, 1),
    transform 0.32s cubic-bezier(0.2, 0.9, 0.25, 1);
  will-change: opacity, transform;
}

/* --- 赤テロップのワイプイン --------------------------------------------- */
/* 番組テロップが左から一気に差し込まれる動き。密着番組の記号。 */
[data-cam-telop] {
  position: relative;
  overflow: hidden;
}

[data-cam-telop]::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background-color: var(--color-accent);
  transform: scaleX(var(--wipe, 0));
  transform-origin: left center;
  pointer-events: none;
}

/* 帯が走り抜けたあとに中身が出る */
[data-cam-telop] > * {
  opacity: var(--in, 0);
  transition: opacity 0.18s linear;
}

/* --- 見出し: 行が下から迫り上がる ---------------------------------------- */
.cam-line {
  display: block;
  overflow: hidden;
}

.cam-line > span {
  display: block;
  transform: translate3d(0, calc((1 - var(--in, 0)) * 108%), 0);
  transition: transform 0.42s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
}

/* --- REC インジケータの点滅 ---------------------------------------------- */
/* 撮影中であることを示す赤点。常時ゆっくり明滅させる。 */
.video-card__badge-dot {
  animation: rec-blink 1.6s steps(1, end) infinite;
}

@keyframes rec-blink {
  0%, 55% { opacity: 1; }
  56%, 100% { opacity: 0.15; }
}

/* --- ヒーロー背景: サムネの壁 -------------------------------------------- */
/* 番組サムネを大量に敷き詰め、列ごとに逆方向へ流し続ける。
   「これだけ撮ってきた」という物量そのものでヤバさを出す。 */
.hero-wall {
  position: absolute;
  inset: -18% -12%;
  z-index: -2;
  display: flex;
  gap: 8px;
  pointer-events: none;
  user-select: none;
  /* 斜めに倒して実際より広く・大量に見せる。
     1枚を小さくして枚数で見せたいので、拡大はかけずに縮める。 */
  transform: rotate(-8deg) scale(1.05);
  /* 中央の縦帯（ロゴ〜ボタンまで）を落として可読性を確保する。
     ロゴだけでなくタグライン・CTAの高さまで覆う必要があるため、
     円ではなく「縦に長い楕円」でマスクする。 */
  /* 中央はわずかに抜くだけにして、暗さは .hero::before の暗幕に任せる。
     ここで削りすぎるとサムネの物量が見えなくなる。 */
  mask-image: radial-gradient(
    ellipse 40% 52% at 50% 48%,
    oklch(0 0 0 / 0.30) 0%,
    oklch(0 0 0 / 0.62) 45%,
    oklch(0 0 0) 82%
  );
}

/* 壁の上に暗幕を1枚重ね、文字のコントラストを確実に確保する。
   マスクだけだと端の明るいサムネが文字に干渉するため。
   .hero-wall は rotate しているので、暗幕は回転しない .hero 側に置く。 */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* 画像を明るくしたぶん、中央の暗幕を強めて文字の可読性を守る。
     中央は濃く、外側へ抜けるほど薄くしてサムネを見せる。 */
  background:
    radial-gradient(
      ellipse 44% 56% at 50% 48%,
      oklch(0.10 0.005 260 / 0.96) 0%,
      oklch(0.10 0.005 260 / 0.88) 34%,
      oklch(0.10 0.005 260 / 0.45) 62%,
      transparent 84%
    ),
    linear-gradient(
      to bottom,
      oklch(0.10 0.005 260 / 0.70) 0%,
      transparent 20%,
      transparent 76%,
      oklch(0.10 0.005 260 / 0.85) 100%
    );
}

.hero-wall__col {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  will-change: transform;
}

/* 2周ぶん出力しているので、1周ぶん(-50%)動かせば継ぎ目なくループする。
   --delay は負値で、読み込み時点で既に流れている途中の状態から始める。 */
.hero-wall__col--down {
  animation: wall-down var(--dur, 20s) linear infinite;
  animation-delay: var(--delay, 0s);
}

.hero-wall__col--up {
  animation: wall-up var(--dur, 20s) linear infinite;
  animation-delay: var(--delay, 0s);
}

@keyframes wall-down {
  from { transform: translate3d(0, -50%, 0); }
  to   { transform: translate3d(0, 0, 0); }
}

@keyframes wall-up {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(0, -50%, 0); }
}

.hero-wall__cell {
  position: relative;
  display: block;
  flex: none;
  overflow: hidden;
  background-color: var(--color-bg-raise);
}

.hero-wall__cell img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  /* サムネの絵が判別できる明るさを保ちつつ、彩度だけ抑えて
     前面の赤ロゴと喧嘩しないようにする。
     暗さは中央の暗幕（.hero::before）で担保しているので、
     画像自体は落としすぎない。 */
  filter: grayscale(0.35) contrast(1.05) brightness(0.85) saturate(0.9);
}

/* モバイルでは列を減らして負荷を下げる。
   画面が狭く6列だと1枚が小さすぎて何か分からないため、見た目上も4列が適切。 */
@media (max-width: 640px) {
  .hero-wall__col:nth-child(n + 5) {
    display: none;
  }

  .hero-wall {
    inset: -22% -20%;
    transform: rotate(-8deg) scale(1.28);
  }
}

/* ランダムに1枚だけ差し替わる瞬間の演出（監視カメラのチャンネル切替） */
.hero-wall__cell.is-swapping img {
  animation: cell-glitch 0.42s steps(2, end);
}

/* 終点は通常時の filter と必ず一致させる（ズレると復帰時に一瞬跳ねる） */
@keyframes cell-glitch {
  0%   { filter: grayscale(0) contrast(2.2) brightness(1.15); transform: translate3d(-4px, 0, 0); }
  35%  { filter: grayscale(1) contrast(0.6) brightness(0.14); transform: translate3d(5px, 0, 0); }
  70%  { filter: grayscale(0) contrast(1.7) brightness(0.85); transform: translate3d(-2px, 0, 0); }
  100% { filter: grayscale(0.8) contrast(0.95) brightness(0.34); transform: none; }
}

/* 差し替わる瞬間に赤いフラッシュを重ねる */
.hero-wall__cell.is-swapping::after {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--color-accent);
  animation: cell-flash 0.42s ease-out;
}

@keyframes cell-flash {
  0%   { opacity: 0.55; }
  100% { opacity: 0; }
}

/* --- 走査線の流れ（フィルムのざらつき） ---------------------------------- */
/* 画面全体に薄い走査線を1本流し、映像素材を見ている感を出す。 */
.scanline {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.5;
  background-image: repeating-linear-gradient(
    0deg,
    oklch(0 0 0 / 0.10) 0 1px,
    transparent 1px 3px
  );
}

.scanline::after {
  content: "";
  position: absolute;
  left: 0;
  width: 100%;
  height: 22vh;
  background-image: linear-gradient(
    to bottom,
    transparent,
    oklch(1 0 0 / 0.022),
    transparent
  );
  animation: scan-sweep 7s linear infinite;
}

@keyframes scan-sweep {
  0% { top: -25vh; }
  100% { top: 100vh; }
}

/* --- カウントアップ数値 --------------------------------------------------- */
/* 実績値が回って止まる。数字は scroll-cam.js が書き換える。 */
.stat__value {
  font-variant-numeric: tabular-nums;
}

/* --- 視差（背景だけ遅れて動く） ------------------------------------------ */
[data-cam-parallax] {
  transform: translate3d(0, var(--shift, 0px), 0);
  will-change: transform;
}

/* --- ホバー: カードに寄る ------------------------------------------------- */
.video-card__thumb,
.member-card .ph {
  overflow: hidden;
}

.video-card__thumb .ph,
.video-card__img,
.member-card .ph {
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}

.video-card:hover .ph,
.video-card:hover .video-card__img,
.member-card:hover .ph {
  transform: scale(1.06);
}

/* ホバー時に赤帯が一瞬走る */
.video-card::after,
.member-card::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 2px;
  background-color: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.32s cubic-bezier(0.2, 0.9, 0.25, 1);
}

.video-card,
.member-card {
  position: relative;
}

.video-card:hover::after,
.member-card:hover::after {
  transform: scaleX(1);
}

/* --- 動きを減らす設定 ----------------------------------------------------- */
.motion-off [data-cam],
.motion-off [data-cam-telop] > *,
.motion-off .cam-line > span {
  opacity: 1 !important;
  transform: none !important;
}

.motion-off [data-cam-telop]::before {
  display: none;
}

.motion-off .scanline,
.motion-off .video-card__badge-dot,
.motion-off .hero-wall__col {
  animation: none;
}

/* サムネ壁は動かさず、静止した背景として残す */
.motion-off .hero-wall__cell.is-swapping img,
.motion-off .hero-wall__cell.is-swapping::after {
  animation: none;
}

.motion-off .scanline::after {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  [data-cam],
  [data-cam-telop] > *,
  .cam-line > span {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  [data-cam-telop]::before {
    display: none;
  }

  .scanline,
  .video-card__badge-dot,
  .hero-wall__col,
  .hero-wall__cell.is-swapping img,
  .hero-wall__cell.is-swapping::after {
    animation: none;
  }

  .scanline::after {
    display: none;
  }
}
