@charset "utf-8";

.yg-stage,
.yg-stage * {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.yg-stage a {
  color: #c9a86a;
  text-decoration: none;
}

.yg-stage a:hover {
  color: #e8d3a6;
}

.yg-stage img {
  max-width: 100%;
}

.yg-stage {
  background: #05050a;
  color: #f2ede4;
  font-family: "Zen Kaku Gothic New", sans-serif;

  --yg-shutter: 0.5s;     /* シャッターが開ききるまでの時間 */
  --yg-shutter-at: 0.2s;  /* シャッターが動き出す時刻 */
  --yg-cut: 0.62s;        /* フラッシュカット1枚あたりの長さ */
  --yg-logo-span: 0s;     /* PC のロゴイントロの尺（SP は使わない） */
  --yg-catch-at: 0.2s;    /* キャッチコピーが出る時刻 */
  --yg-cuts-at: 9.2s;     /* フラッシュカットが始まる時刻 */
  --yg-reveal-at: 14.2s;  /* 最後の絵が現れる時刻 */

  position: relative;

  height: calc(100vh - var(--yg-banner-h));

  display: grid;
  grid-template-rows: 1fr auto 1fr;
  overflow: hidden;
}

.pane-header picture {
  display: block;
}

.pane-header img {
  display: block;
  width: 100%;
  height: auto;

  /* 中の img には .yg-intro__logo が付いているため、
     イントロ用の指定（幅 520px・スクリーン合成・金の滲み）を打ち消しておく。 */
  max-width: none;
  mix-blend-mode: normal;
  filter: none;
}

/* -----------------------------------------------------------------------------
   イントロ（PC 専用）
     SP はロゴを最初から上部に出しておく流れなので、イントロは使わない。
   -------------------------------------------------------------------------- */
.yg-intro {
  display: none;
}

/* -----------------------------------------------------------------------------
   ヘッダー（ロゴ）
   -------------------------------------------------------------------------- */
.yg-site-header {
  align-self: end; /* 上の余白の下端＝映像のすぐ上に置く */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 56px 24px 40px;
}

.yg-site-header__logo {
  display: block;
  width: 300px;
  max-width: 70vw;
  height: auto;
  /* ロゴ画像そのものが白なので、色は変えず金色の滲みだけ足す */
  mix-blend-mode: screen;
  filter: drop-shadow(0 0 24px rgba(201, 168, 106, 0.28));
}

/* -----------------------------------------------------------------------------
   映像ビューア（16:9）
   -------------------------------------------------------------------------- */
.yg-site-main {
  position: relative;
  margin: 0 auto;
  width: 100%;
  max-width: 1040px;
  padding: 0 24px;
}

.yg-viewer {
  position: relative;
  width: 100%;
  /* 素材（721x541）に合わせる。ここが合っていないと
     object-fit: cover が効いて天地または左右が切れる。 */
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: #000;
}

/* ビューア内に敷く画像は共通でこの見え方にする */
.yg-viewer img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 背景（ゆっくり寄り引きを繰り返す） */
.yg-viewer__bg {
  position: absolute;
  inset: 0;
  animation: ygSlowZoom 18s ease-in-out infinite;
}

/* 四隅を落とす */
.yg-viewer__vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 0 140px 40px rgba(5, 5, 10, 0.85);
}

/* 上下から閉じるシャッター */
.yg-shutter {
  position: absolute;
  left: 0;
  right: 0;
  height: 50.2%;
  background: #05050a;
  pointer-events: none;
}

.yg-shutter--top {
  top: 0;
  animation: ygShutterTop var(--yg-shutter) cubic-bezier(0.16, 1, 0.3, 1) var(--yg-shutter-at) 1 both;
}

.yg-shutter--bottom {
  bottom: 0;
  animation: ygShutterBottom var(--yg-shutter) cubic-bezier(0.16, 1, 0.3, 1) var(--yg-shutter-at) 1 both;
}

/* 中央から滲む光 */
.yg-viewer__glow {
  position: absolute;
  inset: -20% -6%;
  pointer-events: none;
  background: radial-gradient(ellipse at center, rgba(201, 168, 106, 0.16), transparent 62%);
  animation: ygGlowPulse var(--yg-shutter) ease-out var(--yg-shutter-at) 1 both;
}

/* フラッシュカットの下地
   ygFlashCut はカットとカットの合間に opacity が 0 まで落ちる。
   シャッターが閉じなくなったため、そのままだと合間に最初の絵が覗いてしまう。
   カット開始と同時に黒を差し込んで、下にあるもの（最初の絵・光・四隅の影）をまとめて塞ぐ。 */
.yg-viewer__backdrop {
  position: absolute;
  inset: 0;
  background: #05050a;
  opacity: 0;
  animation: ygShowBackdrop 0.01s linear var(--yg-cuts-at) 1 both;
}

@keyframes ygShowBackdrop {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* フラッシュカット（JS で生成。animation-delay は要素側で指定する）
   m1〜m8 は透過画像なので、地の色を敷いておかないと
   下のヴィネット（四隅の影）が透けてしまう。 */
.yg-viewer__cut {
  position: absolute;
  inset: 0;
  opacity: 0;
  background: #05050a;
  animation: ygFlashCut var(--yg-cut) steps(1, end) 1 both;
}

/* 最後の1枚だけ、明滅したあと消えずに残る。
   明滅の速さは他のカットと同じ（尺は var(--yg-cut) のまま）で、
   animation-fill-mode: both により終了後は最終キーフレームを保ち続ける。
   どこまで残るかは js/main.js の hold（最後の絵が現れる時刻）で決まる。 */
.yg-viewer__cut--last {
  animation-name: ygFlashCutHold;
}

/* 最後に残る絵。PC は背景だけ、SP は文字が焼き込まれた1枚 */
.yg-viewer__reveal {
  position: absolute;
  inset: 0;
  opacity: 0;
  animation: ygFinalReveal 1.33s ease-out var(--yg-reveal-at) 1 both;
}

/* 最後の絵に重ねる文字。PC でだけ使う層。
   SP は img/sp/last.webp に文字が入っているため、ここでは背景画像を指定しない
   （指定しなければブラウザは画像を取りに行かないので、SP に余計な通信が増えない）。 */
.yg-reveal-text {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

/* -----------------------------------------------------------------------------
   フッター（キャッチコピー / 情報）
   -------------------------------------------------------------------------- */
.yg-site-footer {
  align-self: start; /* 下の余白の上端＝映像のすぐ下に置く */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
  padding: 44px 24px 64px;
  /* SP はキャッチコピーを最初から出しておく（フェードインなし）。
     PC は最後の絵と同時に出すので、下のメディアクエリで指定している。 */
}

/* キャッチコピー
   中身は SVG 画像。映像と同じコンテンツ幅の半分にして中央へ置く
   （中央寄せは .yg-site-footer の align-items: center が効いている）。
   文字に戻したときのために、書体まわりの指定は残してある。 */
.yg-site-footer__catch {
  width: 30%;
  max-width: 496px; /* 映像のコンテンツ幅 1040 - 24*2 = 992 の半分 */

  font-family: "Shippori Mincho", serif;
  font-size: 26px;
  line-height: 1.9;
  letter-spacing: 0.2em;
  text-align: center;
  text-wrap: pretty;
  color: #f2ede4;
}

.yg-site-footer__catch img {
  display: block;
  width: 100%;
  height: auto;
}

/* -----------------------------------------------------------------------------
   アニメーション定義
   -------------------------------------------------------------------------- */
/* シャッター
   開くだけの単純な動き。尺は var(--yg-shutter)、動き出す時刻は var(--yg-shutter-at) で、
   どちらも js/main.js の TIMELINE（shutter / beat）が決めている。
   開ききったあとは animation-fill-mode: both で開いたまま保たれ、
   閉じずにフラッシュカットへ引き継ぐ。 */
@keyframes ygShutterTop {
  from { transform: translateY(0); }
  to   { transform: translateY(-100%); }
}

@keyframes ygShutterBottom {
  from { transform: translateY(0); }
  to   { transform: translateY(100%); }
}

/* 光もシャッターと同じ尺で差し込み、そのまま保つ
   （フラッシュカットが不透明なので、カットが始まれば隠れる） */
@keyframes ygGlowPulse {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes ygFinalReveal {
  from { opacity: 0; transform: scale(1.04); }
  to   { opacity: 1; transform: scale(1); }
}

/* 文字は背景より少しだけ強く寄ってから止まる（予告らしく叩き込む） */
@keyframes ygRevealText {
  from { opacity: 0; transform: scale(1.08); }
  to   { opacity: 1; transform: scale(1); }
}

@keyframes ygFlashCut {
  0%, 4%    { opacity: 0; }
  8%        { opacity: 1; }
  16%       { opacity: 0.15; }
  22%       { opacity: 1; }
  72%       { opacity: 1; }
  84%, 100% { opacity: 0; }
}

/* PC のロゴイントロ
   尺のなかで、真っ黒 → 出て → 見せて → 消える、までを1本で行う。
     0〜15%   真っ黒のまま待つ（ここがあると、続く浮かび上がりが遅く感じられる）
    15〜55%   ゆっくり浮かび上がる
    55〜78%   見せたまま保つ
    78〜100%  消える
   animation-fill-mode: both により終了後は opacity 0 のまま戻らない。

   ・冒頭の黒を長くする  → 15% を大きくする
   ・出をゆっくりにする  → 15% と 55% の差を広げる
   尺全体は js/main.js の logo なので、区間を広げるときは logo も併せて延ばすこと。 */
@keyframes ygLogoIntro {
  0%, 15%  { opacity: 0; transform: translateY(12px); }
  55%, 78% { opacity: 1; transform: translateY(0); }
  100%     { opacity: 0; }
}

/* ygFlashCut と同じ明滅だが、最後に消えずそのまま残る */
@keyframes ygFlashCutHold {
  0%, 4%    { opacity: 0; }
  8%        { opacity: 1; }
  16%       { opacity: 0.15; }
  22%       { opacity: 1; }
  100%      { opacity: 1; }
}

@keyframes ygSlowZoom {
  0%   { transform: scale(1.06); }
  50%  { transform: scale(1.0); }
  100% { transform: scale(1.06); }
}

@keyframes ygFadeUp {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* -----------------------------------------------------------------------------
   スマートフォン
     上の帯を含めて1画面に収める。
       body を縦並びにして、帯は自分の高さぶん、.yg-stage が残りを埋める。
       そのうえで映像の高さを頭打ちにし、はみ出さないようにしている。
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {
  .yg-stage {
    /* 帯の高さ。img/sp/header.png（590x142）の比率から幅で決まるので、
       画面幅が変わっても実際の高さと一致する。
       帯の画像を差し替えたら 142 / 590 も合わせること。 */
    --yg-banner-h: calc(100vw * 142 / 590);

    /* 映像の上下に確保する高さ。下のロゴ／コピーの実高のうち
       大きいほう（ロゴ 90 + 上下 padding 16 ＝ 106px）の2倍。
       余白を変えたらここも合わせる。 */
    --yg-reserve: 212px;
  }

  /* ロゴは、上に空いた黒い帯の天地中央に置く。
     ベースは align-self: end（下寄せ）で余りがロゴの上に溜まるため、
     行いっぱいに広げてから中央に寄せている。
     上下の padding は同じにしておくこと（違うと中央からずれる）。 */
  .yg-site-header {
    align-self: stretch;
    justify-content: center; /* flex-direction: column なので縦方向の中央 */
    padding: 8px 20px;
  }

  /* キャッチコピーも、下に空いた黒い帯の天地中央に置く。
     ヘッダーと同じ扱い（行いっぱいに広げてから中央）にしておくと、
     映像の上下に見える黒帯が同じ高さになる。 */
  .yg-site-footer {
    align-self: stretch;
    justify-content: center; /* flex-direction: column なので縦方向の中央 */
    padding: 8px 24px;
  }

  /* 映像は画面幅いっぱい（左右の余白と最大幅を外す） */
  .yg-site-main {
    max-width: none;
    padding: 0;
  }

  /* 収まらないぶんは映像の高さを頭打ちにする
     （上限に当たっているあいだは object-fit: cover で天地が切れる） */
  .yg-viewer {
    max-height: calc(100vh - var(--yg-banner-h) - var(--yg-reserve));
  }

  /* 映像を画面幅いっぱいにしたぶん、コピーも少し大きくして釣り合わせる。
     上下の黒帯（--yg-reserve の半分）にはまだ余裕があるので、
     ここは高さではなく見た目の釣り合いで決めてよい。 */
  .yg-site-footer__catch {
    width: 55%;
    font-size: 19px;
    letter-spacing: 0.16em;
  }
}

/* -----------------------------------------------------------------------------
   PC
     流れが SP と異なる：
       1 ロゴを画面中央に単独で見せる
       2 ロゴが消えて真っ黒
       3 シャッターが開く
       4 最初の絵
       5 フラッシュカット
       6 最後の絵＋キャッチコピー（ここで初めてコピーが出る）
     尺は js/main.js の TIMELINE（PC 側）が CSS 変数として流し込む。
     幅の境目は index.html の <source media="..."> と揃えること。
   -------------------------------------------------------------------------- */
@media (min-width: 768px) {
  /* イントロのロゴ。グリッドから外して全面に重ね、中央に置く。
     .yg-stage はグリッドなので、重ねただけだと基準が特定の行になってしまう。
     全行にまたがらせて画面全体に重ねる。 */
  .yg-intro {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    inset: 0;
    grid-row: 1 / -1;
    align-self: stretch;
    z-index: 2;
    padding: 24px;
    pointer-events: none;
    animation: ygLogoIntro var(--yg-logo-span) ease 1 both;
  }

  .yg-intro__logo {
    display: block;
    width: 520px;
    max-width: 60vw;
    height: auto;
    /* ロゴ画像そのものが白なので、色は変えず金色の滲みだけ足す */
    mix-blend-mode: screen;
    filter: drop-shadow(0 0 24px rgba(201, 168, 106, 0.28));
  }

  /* 終盤のロゴ。最後の絵と同時に、画面上部へ浮かび上がる。
     映像の上に空いている帯（--yg-reserve の半分）とちょうど同じ高さにして、
     その中で天地中央に置く。こうすると幅が変わっても映像に重ならない。 */
  .yg-site-header {
    /* 重ねずにグリッドの1行目に置く。行いっぱいに広げて中央に配置すれば、
       帯の高さが変わっても常に天地中央に収まり、映像にも重ならない。
       （重ね要素にすると基準がグリッド全体になり、行の中央に置けない）
       ロゴの高さは帯に収まるよう下で上限をかけているため、
       この行が --yg-reserve の半分を超えて広がることはない。 */
    position: relative;
    grid-row: 1;
    align-self: stretch;
    z-index: 2;
    justify-content: center; /* flex-direction: column なので縦方向の中央 */
    gap: 0;
    padding: 12px 24px;
    pointer-events: none;
    animation: ygFadeUp 1.17s ease var(--yg-catch-at) both;
  }

  /* 帯の高さに収める。
     間に <picture> が挟まっていて height: 100% は解決できないため、
     高さの上限（帯の実高 − 上下の padding）で抑える。
     幅・高さとも auto なので、両方の上限に収まるよう比率を保って縮む。
     上限までしか伸びない＝元画像より大きくはならないので、ぼやけない。 */
  .yg-site-header__logo {
    width: auto;
    height: auto;
    max-width: 46vw;
    max-height: calc(var(--yg-band-h) - 24px);
  }

  /* ヘッダーが重なりに移ったぶん、残り2つの行を明示する
     （1fr / 映像 / 1fr となり、映像が画面の天地中央にくる） */
  .yg-site-main {
    grid-row: 2;
  }

  /* キャッチコピーは最後の絵と同時に浮かび上がらせる
     （--yg-catch-at は js/main.js が最後の絵の時刻と同じ値を入れている）。
     行いっぱいに広げたうえで中央に置き、映像の下に余った黒帯の
     天地中央にコピーが来るようにする。 */
  .yg-site-footer {
    grid-row: 3;
    align-self: stretch;
    justify-content: center; /* flex-direction: column なので縦方向の中央 */
    animation: ygFadeUp 1.17s ease var(--yg-catch-at) both;
  }

  /* 映像の上下に確保しておく高さ。
     .yg-stage は 1fr / 映像 / 1fr の3段で、上下の 1fr は同じ高さになる。
     下段にはキャッチコピーが入るので、その高さ × 2 をここに入れておく。

     この値を小さくするほど映像の高さ上限が上がり、天地が切れにくくなる。
     ただし下限は「下の .yg-site-footer の実高 × 2」。それより小さくすると
     行が収まらず、また画面からはみ出す。
     さらに減らしたい場合は、先にフッターの padding を詰めること。 */
  .yg-stage {
    --yg-reserve: 194px;

    /* 帯の高さ。img/pc/header.png（2317x226）の比率から幅で決まる。
       帯の画像を差し替えたら 226 / 2317 も合わせること。 */
    --yg-banner-h: calc(100vw * 226 / 2317);

    /* 映像の実高。幅は「画面いっぱい（100vw）」か「収まる高さから逆算した上限
       （下の .yg-viewer の max-width）」のうち小さいほうで、高さはその 1141/2881。
       レイアウトを参照せず画面寸法だけで出しているので、CSS だけで完結する。 */
    --yg-viewer-h: min(100vw * 1141 / 2881, 100vh - var(--yg-banner-h) - var(--yg-reserve));

    /* 映像の上下に実際に空く黒帯の高さ。
       映像が高さ上限に当たっているときは --yg-reserve の半分（97px）でこれが下限。
       縦に余裕のある画面では映像が幅で頭打ちになり、そのぶん帯が広くなる。 */
    --yg-band-h: calc((100vh - var(--yg-banner-h) - var(--yg-viewer-h)) / 2);
  }

  /* 上下の余白は帯側（--yg-reserve）で確保するので、ここは詰めておく */
  .yg-site-footer {
    padding: 12px 24px;
  }

  /* PC は映像が横長で文字も大きく入っているので、コピーは控えめにする
     （SP は逆に大きくしているため、そちらは max-width: 767px 側で指定） */
  .yg-site-footer__catch {
    width: 22%;
  }

  /* 映像は画面幅いっぱい（左右の余白と最大幅を外す） */
  .yg-site-main {
    max-width: none;
    padding: 0;
  }

  .yg-viewer {
    /* PC 素材（2881x1141）に合わせる */
    aspect-ratio: 2881 / 1141;

    /* 天地を切らずに見せたいので、収まる高さ（画面 − 帯 − 上下の余白）から
       逆算して幅のほうを抑える。高さで頭打ちにすると object-fit: cover が
       効いて天地が切れるが、この形なら絵は常に全部見える。
       縦が足りない画面では横に余白が出て、そのぶん絵は小さくなる。 */
    max-width: calc((100vh - var(--yg-banner-h) - var(--yg-reserve)) * 2881 / 1141);
    margin-inline: auto;
  }

  /* 文字を背景の上に重ねる（PC のみ）。
     素材の実測値が基準。img/pc/last.webp（2881x1141）の上で
     文字画像（1376x650）が左上 747,165 に置かれていたので、それを割合にしている。
     PC の .yg-viewer は素材と同じ比率（2881/1141）で object-fit の切れが起きないため、
     この割合がそのまま元画像の座標と一致する。

     大きさは --yg-text-scale だけで調整する。中心（--yg-text-cx / --yg-text-cy）を
     固定したまま前後に広げるので、いくら変えても文字は同じ位置に留まる。
     ※ .yg-viewer の aspect-ratio を変えるとここもずれる。素材を差し替えるときは
       下の4つの割合を計算し直すこと。 */
  .yg-reveal-text {
    --yg-text-w: 47.76%;   /* 幅   1376/2881 */
    --yg-text-h: 56.97%;   /* 高さ  650/1141 */
    --yg-text-cx: 49.81%;  /* 中心X (747 + 1376/2) / 2881 */
    --yg-text-cy: 42.95%;  /* 中心Y (165 +  650/2) / 1141 */

    /* 素材どおりなら 1。大きくしたいときはここだけ上げる */
    --yg-text-scale: 1.3;

    width: calc(var(--yg-text-w) * var(--yg-text-scale));
    height: calc(var(--yg-text-h) * var(--yg-text-scale));
    left: calc(var(--yg-text-cx) - var(--yg-text-w) * var(--yg-text-scale) / 2);
    top: calc(var(--yg-text-cy) - var(--yg-text-h) * var(--yg-text-scale) / 2);
    background: url(/cms/contents/brand/yugioh/img/pc/last_text.webp) center / 100% 100% no-repeat;

    /* 背景のフェードの途中から入れる。0.36s は背景（1.064s）の約3分の1。
       背景の速さを変えたら、同じ割合になるようここも合わせること。 */
    animation: ygRevealText 0.9s ease-out calc(var(--yg-reveal-at) + 0.36s) 1 both;
  }

  /* m8.webp から last.webp へ切り替わる速さ。
     基の 1.33s を 1.25倍速くして 1.064s にしている（PC だけ。SP は基のまま）。
     切り替わり始める時刻は js/main.js の hold が決めていて、ここでは変わらない。 */
  .yg-viewer__reveal {
    animation-duration: 1.064s;
  }
}

/* -----------------------------------------------------------------------------
   動きを減らす設定の端末向け
     演出そのものは見せたいので止めない。
     強い明滅（フラッシュカット）だけ静かな切り替えに差し替え、
     終わりのない寄り引きを止めるにとどめる。
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  /* 18秒周期で延々と動き続ける背景は止める */
  .yg-viewer__bg {
    animation: none;
  }

  /* 明滅させず、ふわりと切り替える（尺と開始秒はそのまま） */
  .yg-viewer__cut {
    animation-name: ygSoftCut;
    animation-timing-function: ease-in-out;
  }

  /* 最後の1枚が残る挙動は、明滅を抑えた場合も同じにする */
  .yg-viewer__cut--last {
    animation-name: ygSoftCutHold;
  }

  /* 文字は寄りをやめ、背景と同時にそのまま出す */
  .yg-reveal-text {
    animation-name: ygFadeInText;
    animation-delay: var(--yg-reveal-at);
  }
}

@keyframes ygFadeInText {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes ygSoftCutHold {
  0%        { opacity: 0; }
  20%, 100% { opacity: 1; }
}

@keyframes ygSoftCut {
  0%        { opacity: 0; }
  20%, 80%  { opacity: 1; }
  100%      { opacity: 0; }
}
