/* ==========================================================================
   loader.css — 初回ローディングとページ遷移のベール

   ■ 3 点セット（どれか 1 つでも欠けると壊れる）
     1. この CSS
     2. assets/js/loader.js  … ベールを開ける側
     3. <head> のインラインスクリプト … html.is-loading を付ける側
   CSS とインラインスクリプトだけ移植して JS を忘れると、フェイルセーフの
   10 秒が経つまで白画面のままになる。必ず 3 つセットで運ぶこと。

   ■ 素の状態は「見えない」
   可視化するのは html.is-loading が付いているときだけ。JS が 1 行も動かない
   環境ではクラスが付かないので、ベールも出ずコンテンツがそのまま読める。
   opacity は loader.js（GSAP）がインラインで書くので、ここでは扱わない。
   ========================================================================== */

/* --- ベールの地 ------------------------------------------------------------
   既定は通常遷移。ページ地（--color-surface）と同じ薄いグレー + 紙目。
   トップへの入場だけ MV と同じ青（html.is-veil-brand）。
   初回イントロは白の無地のまま（html.is-index-intro）。
   切り替えは loader.js が幕の不透明な間に行うので、色が変わる瞬間は見えない */
.c-loader {
  --loader-bg: var(--color-surface);
  --loader-texture-blend: multiply;              /* body 地と同じ合成 */
  --loader-texture-opacity: var(--texture-body-opacity);
  position: fixed;
  inset: 0;
  z-index: var(--z-loader);
  display: grid;
  place-items: center;
  background-color: var(--loader-bg);
  /* 遷移中のクリックを物理的に塞ぐ。swup は進行中の visit を中断して次を
     始められるが、中断されると入場アニメの Promise が解決されないまま
     ベールが残ることがある。見えている間は触らせない */
  pointer-events: auto;
  visibility: hidden;
}
html.is-loading .c-loader {
  visibility: visible;
  cursor: wait;
}

/* 紙目。地の色で合成方法が変わるので、値は上の 3 つの変数で持つ。
   .c-loader__intro は position を持たないため、この絶対配置の擬似要素が
   前に出る。イントロ中は下のルールで消しているので衝突しない */
.c-loader::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("../../img/texture.jpg");
  background-repeat: repeat;
  background-size: var(--texture-size);
  mix-blend-mode: var(--loader-texture-blend);
  opacity: var(--loader-texture-opacity);
  pointer-events: none;
}

/* GNAV を開いた状態から HOME へ飛ぶときだけ、幕を MV と同じ青にする。
   GNAV のパネルも MV も --color-brand なので、あいだにグレーを挟むと
   同じ青と青のあいだが一度切れる。紙目も MV と同じ overlay 10% に合わせる。

   ★ 通常のリンクからの HOME への遷移と、リロード・直アクセスはグレーのまま。
     リロードは幕がインラインスクリプトの is-loading で最初から出ていて
     showVeil() を通らないため、色を決められるのが enterPage()＝不透明な
     ローディングの後になり、グレーから青へのカットが見えてしまう */
html.is-veil-brand .c-loader {
  --loader-bg: var(--color-brand);
  --loader-texture-blend: overlay;
  --loader-texture-opacity: var(--texture-opacity);
}

/* 白の無地にする場面。is-veil-brand より後に置いて必ず勝たせる。

   ・is-veil-plain … 初回のフルロード（リロード・直アクセス）と、これから
     トップのイントロを出す遷移。前者は head のインラインスクリプトが付ける。
     初回を白にするのは、紙目が外部画像（texture.jpg）で、まだ落ちていない
     うちはグレーの地だけが出て、あとから粒が乗る＝崩れて見えるため。
     幕が晴れるまで保つ必要があるので、is-booting ではなくこちらで持つ
     （is-booting はヘッダーを出す時点で外れてしまう）。
   ・is-index-intro … イントロの表示中。上と重なるが、遷移で来た場合は
     こちらが起点になる */
html.is-veil-plain .c-loader,
html.is-index-intro .c-loader {
  --loader-bg: var(--color-bg);
}
html.is-veil-plain .c-loader::before,
html.is-index-intro .c-loader::before {
  display: none;
}

/* DOM 差し替え中の新しい #swup は、ベールの不透明度に依存せず伏せる。
   素の状態は表示なので、JS が止まって class が外れれば本文へ戻れる */
html.is-page-swapping #swup {
  opacity: 0;
}

/* 初回ロードの間だけヘッダーを伏せる。
   ヘッダーはベールより前面（tokens.css の --z-header）なので、伏せないと
   白幕の上に出て、トップのイントロの大ロゴと二重になる。
   ページ遷移では is-booting が付かない＝遷移中のヘッダーは見せる。これが
   この構成の目的（ベールに覆わせないことでホバーの再発火を止める）。
   外すのは loader.js の enterPage() / forceRevealPage()。 */
html.is-booting .c-site-header,
/* トップのイントロが出ている間も伏せる。is-booting は初回のフルロードにしか
   付かないので、これが無いと「他ページから遷移でトップへ初めて来た」経路で
   イントロの大ロゴとヘッダーが同時に出る。

   出るときの復帰は loader.js の revealHeader() が GSAP のインラインで行う。
   こちらの transition は伏せる向き（class が付く瞬間）だけに効く。遷移で
   来た場合はヘッダーが幕の上に見えているので、そこから静かに引かせる */
html.is-index-intro .c-site-header {
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}

/* 伏せている間、ヘッダーの中身は色も位置も渡らせない。

   scroll-effects.js の syncHeaderOnMv() は page.prepare() の中で is-on-mv を
   付ける（＝トップなら白抜きが決まる）。ヘッダーはまだ伏せているので、その
   切り替えは見せる必要がなく、渡らせると害になる。実測では、トップのリロードで
   ヘッダーが全表示になった時点のロゴがまだ既定色で、そこから 0.3s（--dur）かけて
   白へ渡っていた。ベールがまだ白い区間なので、白地に濃いロゴが出て最も目立つ。

   ここで transition を切り、loader.js の revealHiddenHeader() が外す前に一度
   スタイルを解決させることで、姿を現す時点では白へ確定させる。
   対象は中身だけ。ヘッダー自身の opacity は上のルールが持つ。

   同じ手口が site-header.css の .is-scrolled にもある（遷移でナビを戻すとき
   が対象）。片方を直すときはもう片方も見ること */
html.is-booting .c-site-header *,
html.is-booting .c-site-header *::before,
html.is-booting .c-site-header *::after,
html.is-index-intro .c-site-header *,
html.is-index-intro .c-site-header *::before,
html.is-index-intro .c-site-header *::after {
  transition: none !important;
}

/* --- index 固有のイントロ ------------------------------------------------
   ロゴを中央、数字カウンターを右下に配置する。初回の読み込みが終わったら loader.js が
   この要素を DOM ごと取り除き、以降 .c-loader は遷移用の無地ベールとして
   使い回される（＝デザインは index 固有、仕組みは全ページ共通）。 */
.c-loader__intro {
  display: none;
  align-items: center;
}
html.is-index-intro .c-loader__intro {
  display: flex;
}

.c-loader__logo {
  display: block;
  width: var(--space-x-480);
  /* 視覚中心を上へ寄せる下余白。センタリングされるのは SVG と padding を
     含めたボックスなので、持ち上がる量はこの値の半分になる。
     ベール自身が inset: 0 で、アドレスバーの開閉に合わせて中心が動く。
     svh で固定してもロゴが動くのは変わらず、余白だけが実際の高さから外れる */
  padding-bottom: 6dvh;
  overflow: visible;
}
/* ロゴは enter 前に伏せる。ベールと同じく html.is-loading に
   ぶら下げてあるので、JS が動かない環境ではそもそも適用されない */
html.is-loading .c-loader__logo {
  opacity: 0;
}

/* 読み込みに手間取ったときだけ出す。遅延のあいだに速い読み込みは終わり、
   イントロごと DOM から消えるので、CSS 側は経過時間を知らずに済む。
   3s は最速経路（ロゴ入場 1.4s + INTRO_HOLD + VEIL_OUT ≒ 2.6s）の上。
   下回らせるとキャッシュ済みの再訪でも一瞬出る。

   transition ではなく animation なのは、初回描画にはトランジションの
   起点になる変化が無いため。base.css の prefers-reduced-motion は
   animation-duration しか潰さないので、この遅延はリデュース時も効く。

   数値の供給は loader.js の makeCounter が持っている。表示を止めても
   await counter.finish() はイントロの進行を待たせ続けるので、
   出さないからといって JS 側を外すと尺が変わる */
.c-loader__status {
  position: absolute;
  right: var(--space-x-40);
  bottom: var(--space-y-40);
  font-family: var(--font-en);
  font-weight: 400;
  font-size: var(--fs-18);
  line-height: 1;
  letter-spacing: 0.08em;
  color: var(--color-text);
  animation: c-loader-status-late 0.3s linear 3s both;
}

@keyframes c-loader-status-late {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* 数字は等幅で送る。桁が増えるたびに中央位置がずれるのを防ぐ。
   3桁ぶんを先に確保するのは、0 → 100 で LOADING を押さないため。
   % をこの要素へ入れられないのは、loader.js が textContent で
   数値を書き込むため。ひとつにまとめると % が消える */
.c-loader__count {
  display: inline-block;
  min-width: 3ch;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* ==========================================================================
   SP（max-width: 767px）
   ========================================================================== */

@media (max-width: 767px) {
  /* --space-x-480 は 1280px 以下で 336px に張り付くため、320px では画面幅を
     超えて見切れる。幅へ追従させ、上限は 768px 以降と同じ値で止める
     （480px で頭打ちになり、そこから 767px までは境界の向こうと同値） */
  .c-loader__logo {
    width: min(70vw, var(--space-x-480));
  }
}
