/* header（通常DOM・FLOCSS）。後日 PHP でコンポーネント化する範囲 */

/* ==========================================================================
   ■ 色の状態を足すときの注意（再発防止）

   ヘッダーは #swup の外で永続し、かつ遷移のベールより前面にいる
   （tokens.css の --z-header）。遷移中も見えているので、状態 class の
   付け外しがそのまま画面に出る。

   ヘッダーの色は --dur（0.3s）で渡る。一方、遷移中の class の切り替えは
   数十 ms 単位で連続する。この 2 つが噛み合わないと、渡りの途中で別の
   状態へ移って「一瞬だけ違う色になる」。実測で 3 回踏んだ。

     ・初回ロードでヘッダーが既定色のまま出た（loader.css の凍結で対処）
     ・GNAV から HOME で白抜きが 0.2 秒沈んだ（is-veil-brand の追加で対処）
     ・隠れていたナビが白くなる前に降りてきた（下の凍結と順序で対処）

   新しい色の状態を足すときは、次の 2 点を必ず確認すること。

   1. 幕が出ている全区間をカバーしているか。区間の切れ目に隙間があると、
      そこで --dur の渡りが逆走して見える
   2. 伏せている間の切り替えなら、渡らせず即座に確定させるか。
      「transition を切る + class を外す前に一度スタイルを解決させる」の
      2 点セットで行う（片方だけでは効かない）。実装例は下の .is-scrolled と
      loader.css の is-booting / is-index-intro
   ========================================================================== */

/* 背景を持たない全幅の帯なので、箱のままだと画面上部 --header-height 分の
   コンテンツがクリックできない。当たり判定は中身だけに持たせる */
.c-site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-header);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  height: var(--header-height);
  padding: var(--header-pad-top) var(--space-side) 0;
  pointer-events: none;
}

.c-site-header__logo,
.c-site-header__nav,
.c-site-header__burger {
  pointer-events: auto;
}

/* ★ このリンクの href は JS からも読まれている。page-transition.js の
   isIndexUrl() が「サイトのトップの URL」の基準として使い、遷移の幕を
   MV と同じ青にするかの判定に用いる。href を変える／リンクを別要素へ
   移すときは向こうも見ること（外れても幕がグレーになるだけで壊れはしない）。

   ロゴの href を基準にしているのは、静的段階でも WordPress 化後でも
   （home_url 相当が出力される）つねにサイトのトップを指すため。
   詳しい理由は isIndexUrl() のコメントにある。

   AGENTS.md の「JSからの参照」はクラスセレクタ / data-* / js- の 3 系統しか
   規定していないので、この href 参照は規約の外にある。data-* へ移す案も、
   WordPress では結局ロゴの href として同じ値を出力するので、同じ値を
   2 箇所へ書くことになる。現状は href を正として運用する。 */
.c-site-header__logo {
  flex-shrink: 0;
  width: 240px;
  overflow: visible;
}

.c-site-header__right {
  display: flex;
  align-items: flex-end;   /* 端数を出さず下端で揃える */
  gap: var(--space-y-40) var(--space-x-40);
  padding-bottom: var(--menu-btn-offset);
}

.c-site-header__nav-list {
  display: flex;
  align-items: center;
  gap: var(--space-y-40) var(--space-x-40);
}

.c-site-header__nav-item a {
  font-family: var(--font-en);
  font-weight: 600;
  font-size: var(--fs-18);
  letter-spacing: 0.08em;
  line-height: 1.5;
  color: var(--color-text);   /* 透明度はトークン側が持つ（rgba の a = 0.8） */
  font-feature-settings: "palt" 1;
}

/* 現在地の丸。current-nav.js が付ける is-current / is-current-section を受ける。
   クラスは GNAV / footer のリンクにも付くが、演出はヘッダーだけに持たせる。

   ■ padding と負の margin で場所を作る理由
   c-swap は複製（::after）を隠すため overflow: hidden を持つ。クリップは
   padding box で起きるので、a の外（left: 100% など）へ出した ::before は
   丸ごと消える。そこで padding-right で自分の内側に置き場所を作り、同じ量の
   負の margin で相殺して、レイアウト上の幅は変えないまま文字の右外へ出す。
   丸は項目間の余白（--space-x-40）へはみ出す形になる。

   padding-right は右から順に right + 直径 + 文字との間隔をちょうど収める量。
   0.1 + 0.3 + 0.1 = 0.5em。増やしても見た目は変わらないが、余った分だけ
   クリックできる範囲が右へ広がるので、必要量ちょうどにしておく。

   大きさと位置は em。文字に対する比率で決まるので、fs-18 が変わっても
   一緒に縮む。丸は a 自身の擬似要素なので em が文字サイズ基準で解決する。

   ホバー演出が動かすのは .c-swap__in と ::after の 2 つだけなので、
   ::before は再生中も動かない */
/* ■ 丸は全リンクに常時置き、opacity と Y 移動で出し入れする
   擬似要素は生成・破棄をトランジションできないので、is-current の付け外しで
   作ると瞬間表示になる。場所（padding と負の margin）も常に確保しておく。
   相殺するのでレイアウトは変わらず、現在地が移っても幅が動かない。 */
.c-site-header__nav-item a {
  padding-right: 0.5em;
  margin-right: -0.5em;
  /* 丸の出入りの尺と、出るときの持ち上げ幅。消えるほうを短く、出るほうを
     その倍取って「置きにいく」動きにする。出る間（--dot-in-delay）を消える尺と
     同じにしているので、前の現在地が引き切ってから次が立ち上がる。

     持ち上げ幅は em。丸の大きさと位置（width / height / right）が em なので、
     fs-18 が変わっても一緒に縮む。0.3em は丸の直径ちょうど。
     上限は 1.2em で、それを超えると待機位置が .c-swap のクリップ領域
     （line-height 1.5em）の下端を割り、出はじめの丸が切れる。 */

  /* ★ この 4 つは --dur とも、遷移のベール（page-transition.js の OUT_DUR）とも
     独立している。丸の出し入れは page:view の updateCurrentNav() が起こし、
     ヘッダーはベールより前面にいるので、幕の尺・カーブ・有無のどれにも
     影響されない。0.15s / 0.3s が --dur の 1/2 と 1 倍に一致しているのは
     偶然で、--dur を動かしてもここは動かない（動かす必要もない）。

     擬似要素はカスタムプロパティを親から継承するので、ここで持たせれば
     下の 2 つのルールが同じ値を読める */
  --dot-out-dur: 0.15s;
  --dot-in-dur: 0.3s;
  --dot-in-delay: var(--dot-out-dur);
  --dot-in-shift: 0.3em;
}
.c-site-header__nav-item a::before {
  content: "";
  position: absolute;
  top: 0;               /* 上は要素と同じライン */
  right: 0.1em;
  width: 0.3em;
  height: 0.3em;
  border-radius: 50%;
  background-color: var(--color-brand);
  opacity: 0;
  /* 出るときの待機位置。transform は絶対配置の擬似要素にかかるだけなので、
     リンクの幅にも隣の項目にも影響しない。下へずらすぶんには
     .c-swap の overflow: hidden にも触れない（丸は top: 0 なので、
     上へ動かすとクリップ領域の上端で切れる） */
  transform: translateY(var(--dot-in-shift));
  /* 消えるのはフェードだけ。位置の戻しは透明になり切ってから 0 秒で行う
     （補間しないので、消えながら下へ沈むことはない）。
     gnav のナビ（site-gnav.css の .c-site-gnav__nav）と同じ持ち方。
     background-color だけは共通の --dur のままにする（MV 上での色替え） */
  transition: opacity var(--dot-out-dur) var(--ease),
    transform 0s linear var(--dot-out-dur),
    background-color var(--dur) var(--ease);
}
/* 出るときだけ半拍遅らせて、前の現在地が引くのと時差をつける。
   遷移で現在地が移るとき、2 つの丸が同時に動いて交差するのを避ける */
.c-site-header__nav-item a.is-current::before,
.c-site-header__nav-item a.is-current-section::before {
  opacity: 1;
  /* 下から持ち上げながら現れる */
  transform: none;
  /* 長く・遅らせるのは opacity と transform だけ。background-color を
     巻き込むと、MV 上での色替えまで鈍って半拍遅れる */
  transition: opacity var(--dot-in-dur) var(--ease) var(--dot-in-delay),
    transform var(--dot-in-dur) var(--ease) var(--dot-in-delay),
    background-color var(--dur) var(--ease);
}

/* スクロール時はインラインナビを隠す（ロゴ + ハンバーガーのみ） */
.c-site-header__nav {
  /* 戻すときの visibility は即。遅らせると、表示されているのに
     しばらくフォーカスが当たらない状態ができる */
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
    visibility 0s;
}
/* 隠れているあいだは中身の色を渡らせない。遷移で戻すとき、白抜きの有無は
   content:scroll の syncHeaderOnMv() が決めるが、そこから resetHeader() が
   class を外すまでに再計算が挟まらないと、色の渡りがナビの降下と並走して
   「降りてきてから白くなる」ことになる。header.js が class を外す前に一度
   スタイルを解決させるので、ここを切っておけば降りる時点で最終色になる。
   対象はナビの中だけ。ロゴとハンバーガーのスクロール追従には影響しない。

   同じ手口が loader.css の html.is-booting / html.is-index-intro にもある
   （初回ロードのヘッダー全体が対象）。片方を直すときはもう片方も見ること */
.c-site-header.is-scrolled .c-site-header__nav *,
.c-site-header.is-scrolled .c-site-header__nav *::before,
.c-site-header.is-scrolled .c-site-header__nav *::after {
  transition: none !important;
}
.c-site-header.is-scrolled .c-site-header__nav {
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  /* 隠れている間は Tab 順からも外す。opacity と pointer-events だけだと
     見えないリンクにフォーカスが飛ぶ。visibility は補間されないので、
     フェードが終わってから 0 秒で切り替える（GNAV 展開時の同じ持ち方と揃える） */
  visibility: hidden;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease),
    visibility 0s linear var(--dur);
}

/* GNAV 展開中は必ず隠す。ヘッダーは GNAV より前面にいるので、出したままだと
   GNAV の大きなリンクと二重の導線になる。見え方は is-scrolled と同じだが、
   こちらは visibility まで畳んで Tab 順からも外す（展開中のフォーカスを
   GNAV 内のリンクとトグルだけに回すため）。閉じれば is-scrolled の状態へ
   そのまま戻る。状態は html 側にあるので、ヘッダーは GNAV を参照しない */
html.is-gnav-open .c-site-header__nav {
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  /* スクロールで隠すとき（is-scrolled）と違って Y は動かさない。
     GNAV の開閉はナビが「上へ逃げる」動きではなく、面が入れ替わる動きなので、
     位置を動かすとパネルの掃きと打ち消し合って見える */
  transition: opacity var(--dur) var(--ease), visibility 0s linear var(--dur);
}

/* 3本線を箱の中央に置く（gnav の×ボタンと同じ箱・同じ中心）。
   × の 2 本は ::before / ::after で作るので position: relative を持つ。

   入れ替えの尺は --dur（0.3s）から切り離して持つ。ここはボタンの都合で
   決めるものなので、グローバルを動かしたときに引きずられないようにしておく。

   ★ --burger-blank は合計に比例させていない。合計を詰めるほど空白の占める
     割合が上がるので（0.2s なら 22%）、詰めすぎると入れ替わりではなく
     ちらつきに見える。尺を大きく動かすときはこちらも見ること。

   --burger-shift は向きを持たない。縦横どちらで使うかは下の指定側で決める。

   調整は下の 3 値だけ。--burger-out / -in / -lag はそこから導出する。
     --burger-dur   … 合計。押した瞬間に走る性格は保つので、GNAV の掃き
                       （開 0.9s / 閉 0.6s）へは揃えない
     --burger-blank … 両方が透明な間。これが「一度消える」の実体で、
                       0 にすると溶けたように見え、広げるとボタンが
                       消えたように見える
     --burger-shift … 横へ流す距離 */
.c-site-header__burger {
  position: relative;
  --burger-dur: 0.3s;
  --burger-blank: 0.045s;
  --burger-shift: 6px;
  --burger-out: calc((var(--burger-dur) - var(--burger-blank)) / 2);
  --burger-in: var(--burger-out);
  --burger-lag: calc(var(--burger-out) + var(--burger-blank));
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--menu-btn-gap);
  width: var(--menu-btn-w);
  height: var(--menu-btn-h);
  flex-shrink: 0;
  /* ナビ文字のキャップ中央に合わせる視覚補正 */
  margin-bottom: var(--menu-btn-optical);
}
.c-site-header__burger span {
  display: block;
  width: 100%;
  height: var(--menu-btn-bar);
  /* 色は箱の color で持つ。3 本の span と × の 2 本（擬似要素）が
     同じ指定を共有できるので、白抜きの切り替えが 1 ルールで済む */
  background-color: currentColor;
}

/* --- MV の上に載っている間だけ白抜きにする -------------------------------
   トップのMVが濃色（コーポレートブルー）になったため、その上では既定の
   --color-text（黒80%）もロゴの原色も沈む。切り替えは scroll-effects.js が
   .is-on-mv の付け外しで行い、MVがヘッダーの下端を通過した時点で外れる。

   状態のクラスはコンポーネント側で受ける（ページ固有CSSから共通パーツを
   上書きしない、という既存の分担のため）。トップ以外では誰も付けないので
   他ページには出ない。

   ロゴはインラインSVGで、fill を属性で持っている。CSSの fill は
   presentation attribute より強いので、こちらで上書きできる。
   logo-motion.js が触るのは opacity と transform だけなので干渉しない。
   ただしCMYK4層はすべて白になるため、版ズレの色味は白抜きの間だけ消える。

   色は --dur でフェードする（下記）。ヘッダーは #swup の外にあって遷移で
   作り直されないので、フェード自体は「他ページからトップへ入ると既定色から
   白へ変わっていく」動きにもなり得る。そちらは scroll-effects.js が
   .is-on-mv を入場アニメの前に付けることで潰してあり、到着した時点で
   既に白になっている。フェードが見えるのはスクロールでの切り替わりだけ。
   -------------------------------------------------------------------------- */
/* 色の渡り。ナビの <a> は base.css の a のルールで既に color が --dur で
   渡るので、ハンバーガーとロゴにも同じ尺・同じカーブを持たせて揃える。
   ロゴは fill だけを対象にすること。all にすると logo-motion.js が動かす
   transform / opacity まで巻き込んで、登場モーションが鈍る */
.c-site-header__burger {
  color: var(--color-text);
  transition: color var(--dur) var(--ease);
}
.c-site-header .c-logo__mark path,
.c-site-header .c-logo__layer {
  transition: fill var(--dur) var(--ease);
}

/* ■ 白抜きにする場面は 3 つ。宣言が同一なのでセレクタを併記するだけでよい

   1. .is-on-mv        … トップの MV の上（scroll-effects.js）
   2. html.is-gnav-open … GNAV の面の上。面は --color-brand（gnav.js）
   3. html.is-veil-brand … 遷移の幕が青い間。幕も --color-brand（loader.js）

   3 が要るのは、1 と 2 のあいだに指示の空白ができるため。GNAV から HOME へ
   飛ぶと、closeGnav() で 2 が外れてから page.prepare() の syncHeaderOnMv() で
   1 が付くまでに約 50ms あく。--dur の色の渡りがその間に既定色へ向かって
   走り出し、途中で逆走するので、実測で約 0.2 秒・白から 57 ぶん沈んで見えた。
   幕がグレーなら馴染むが、青い幕では暗く沈んで見える。

   3 は幕が青い区間そのもの（showVeil で付き hideVeil の完了で外れる）なので、
   前は 2 と、後ろは 1 と必ず重なる。どちらが何 ms 遅れても隙間ができない。

   ★ 前提は「is-veil-brand が付いている＝ヘッダーの背後が --color-brand」。
     幕の色として別の色を is-veil-brand に持たせると、この対応が崩れる。

   ★★ 4 つ目の場面を足すときは、下の 4 ルール（ナビの色 / 丸の背景 /
      ハンバーガー / ロゴの fill）すべてにセレクタを足すこと。1 つでも
      漏らすと「ロゴは白いのにナビだけ濃い」が起きる。実際 2 回踏んだ。

      条件を 1 つの導出フラグへ畳めば漏れは消えるが、導出のタイミング管理が
      新たに要り、それこそが上の「区間の隙間」を生む。ここは冗長さを
      受け入れて、OR 条件をセレクタリストで表現している。隙間が構造的に
      できないほうを取っている、という判断。 */
.c-site-header.is-on-mv .c-site-header__nav-item a,
html.is-veil-brand .c-site-header__nav-item a {
  color: #fff;
}
/* 現在地の丸は既定でブランド色。青の上では見えないので白へ。
   丸は全リンクに常時あるので、is-current を問わず一括で指定してよい */
.c-site-header.is-on-mv .c-site-header__nav-item a::before,
html.is-veil-brand .c-site-header__nav-item a::before {
  background-color: #fff;
}
/* バーガーは箱の color で切り替える。中の 3 本も × の 2 本も
   currentColor なので、この 1 ルールで両方に効く */
.c-site-header.is-on-mv .c-site-header__burger,
html.is-gnav-open .c-site-header__burger,
html.is-veil-brand .c-site-header__burger {
  color: #fff;
}
.c-site-header.is-on-mv .c-logo__mark path,
.c-site-header.is-on-mv .c-logo__layer,
html.is-gnav-open .c-site-header .c-logo__mark path,
html.is-gnav-open .c-site-header .c-logo__layer,
html.is-veil-brand .c-site-header .c-logo__mark path,
html.is-veil-brand .c-site-header .c-logo__layer {
  fill: #fff;
}

/* --- GNAV 展開中は × へ入れ替える ------------------------------------------
   3 本が消えてから × が現れる。線が繋がったまま変形する（モーフ）のではなく、
   いったん途切れさせて「メニュー」と「閉じる」を別の記号として読ませる。
   GNAV の面が全画面で切り替わるので、ボタン側も入れ替わるほうを採る。

   ■ 出ていく形と入ってくる形を別の要素にしている理由
   同じ要素を 1 回の状態変化で「消してまた出す」ことはできない。transition は
   1 プロパティにつき片道しか描けないので、opacity を 1→0→1 と往復させられない
   （keyframes と「閉じている最中」の状態 class を足せば可能だが、機構が増える）。
   3 本の span を退場、× の 2 本（::before / ::after）を登場に割り当てれば、
   どちらも片道で済む。HTML は増やさない。

   ■ 向き
   3 本は右へ流れて消え、× は左から差し込まれる。GNAV パネルが横方向の
   マスクで掃かれるので、ボタンの動きも横で揃えている。
   上下（c-text-swap と同じ向き）も試したが、横のほうを採る。

   箱に overflow は持たせていないので、線は箱の外まで動く。透明になり切って
   からしか出ないため見えないが、スリットへ吸い込まれるように見せたい場合は
   .c-site-header__burger へ overflow: clip を足す（× は 45 度に倒した
   30px の線なので縦横 21.2px に収まり、切れない）。

   ■ 尺
   退場 → 空白 → 登場。値は箱に持たせた 3 トークンから導出する（上記）。
   GNAV の掃き（開 0.9s / 閉 0.6s）へは揃えない。押せる状態が変わった瞬間に
   ボタンが変わるほうが自然なので、状態 class の付け外しに対して即座に走らせる。
   遷移中に × から戻るのが見えるのも同じ理由。
   -------------------------------------------------------------------------- */

/* ハンバーガーの 3 本。退場は遅延なし、登場は空白ぶん待ってから */
.c-site-header__burger span {
  transition:
    opacity var(--burger-in) var(--ease) var(--burger-lag),
    translate var(--burger-in) var(--ease) var(--burger-lag);
}
html.is-gnav-open .c-site-header__burger span {
  opacity: 0;
  transition-duration: var(--burger-out);
  transition-delay: 0s;
}

/* × の 2 本。箱の上下中央に重ね、±45 度で交差させる。
   中央の span と同じ中心に来るので、モーフ時代と着地は同じ */
.c-site-header__burger::before,
.c-site-header__burger::after {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 100%;
  height: var(--menu-btn-bar);
  margin-top: calc(var(--menu-btn-bar) / -2);
  background-color: currentColor;
  opacity: 0;
  pointer-events: none;
  transition:
    opacity var(--burger-out) var(--ease),
    translate var(--burger-out) var(--ease);
}
.c-site-header__burger::before { rotate: 45deg; }
.c-site-header__burger::after { rotate: -45deg; }
html.is-gnav-open .c-site-header__burger::before,
html.is-gnav-open .c-site-header__burger::after {
  opacity: 1;
  transition-duration: var(--burger-in);
  transition-delay: var(--burger-lag);
}

/* 3 本は右へ流れて消え、× は左から差し込まれる */
html.is-gnav-open .c-site-header__burger span {
  translate: var(--burger-shift) 0;
}
.c-site-header__burger::before,
.c-site-header__burger::after {
  translate: calc(var(--burger-shift) * -1) 0;
}
html.is-gnav-open .c-site-header__burger::before,
html.is-gnav-open .c-site-header__burger::after {
  translate: 0 0;
}

/* --- 中間層 + SP 共通（max-width: 1023px）---------------------------------
   インラインナビをやめ、ロゴとハンバーガーだけにする。
   944px以下ではナビ項目が縮んでラベルが切れ、ロゴとも重なるため
   （調査は docs/tablet-audit.md の A-2）。GNAVパネルが導線を引き継ぐ。
   DOMは出し分けず表示だけ切る（決定5）。帯の高さと下端揃えはPCのまま。
   -------------------------------------------------------------------------- */
@media (max-width: 1023px) {
  .c-site-header__nav {
    display: none;
  }
}

/* --- SP（Figma 422:2674） -------------------------------------------------
   帯の高さ50px（--header-height / --header-pad-top はトークン側で差し替え）。
   ロゴ157×30とハンバーガー30×27を、上padding下の30px枠で上下中央に置く。
   PCの下端揃え + 視覚補正は、隣に並ぶナビ文字が基準なのでSPでは使わない。
   インラインナビは上の1023pxブロックで既に消えている。
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {
  .c-site-header {
    align-items: center;
  }

  .c-site-header__logo {
    width: 157px;
  }

  .c-site-header__right {
    padding-bottom: 0;
  }

  .c-site-header__burger {
    margin-bottom: 0;
  }
}
