/* ══════════════════════════════════════════════════════════════
   ゲーム本体（PLAY）のリンク先について

   現在の向き先： https://kawa50451-prog.github.io/bousai-card-game/game_online.html
   将来の向き先： https://toshibousai-cardgame.web.app/

   配布用の Firebase 版は 2026-08-12 時点で GitHub Pages 版より古く、
   協力モード・復興回数・都市HP・マイ都市・問題工房が入っていない。
   サイトは協力モードの詳細ページを持つため、同期が済むまで Firebase を
   指してはいけない（存在しない機能を宣伝することになる）。

   同期後の切り替えは、site/ 配下の全HTMLに対する1回の置換で済む：
     旧 https://kawa50451-prog.github.io/bousai-card-game/game_online.html
     新 https://toshibousai-cardgame.web.app/
   ══════════════════════════════════════════════════════════════ */
/* ══════════════════════════════════════════════════════════════
   Ready or Not 公式サイト ── 共通スタイル（site.css）
   design/official_site_spec.md §10 準拠。

   2026-08-12：site/v5-proto.html（LP）から複数ページ共通の部分を切り出した。
   共通化したのは、トークン（--fs-*・--s*・色・地の軌跡の基盤）、基本タイポグラフィ、
   .reveal / .headRule、下部固定バー、ローディング演出、カーソルレティクル、グレイン、
   グリッド（.wrap/.g12）、画像マスク開き（.maskReveal）。
   LPの各節のレイアウト（ヒーロー・なぜ作ったか・カードマーキー・軌道セレクタ・
   遊び方・締め）と、そこでしか使わない演出（地の軌跡のスクロール連動・読み位置の
   色スイープ・ドーナツグラフ）は v5-proto.html 側にページ固有のまま残している。
   加えて、/modes/* サブページ共通の骨格（パンくず・モード見出し・実機画面・
   1ターンの流れ・リスク方程式・学びの対応表・設定パネル）もここに含めた
   （§13〜§15）。

   ⚠️ この切り出しは整理であって改修ではない。v5-proto.html の見た目と挙動が
   切り出し前と一切変わらないことを最優先にしている。

   2026-08-12 第6次（§20 リッチ化）：下部バーからアイコンを外し、画面左上固定の
   .siteLogo（ロゴの組み。ナビではない）へ独立させた。下部バーは角丸の浮いた板に
   作り直し、ファーストビューでは透明、スクロールで不透明度が上がる。カーソル
   レティクルはホバーで拡大・押下でgoldへ変わる2信号に分けた。.reveal の移動量を
   強め、テキストリンク群（下部バー・パンくず）にホバー／押下の2段階を追加した。

   2026-08-13 第3次：下部固定バーをPLAY専用に縮小し、ページ移動（HOME/VERSUS/
   CO-OP/FEATURES/CARDS/CONTACT）を画面右上のハンバーガー（.hamburgerBtn）
   経由の全画面メニュー（.navScrim/.navMenu/.navMenuPanel/.navMenuList）へ
   移した。開くとページ本体（.pageScale）がわずかに縮んでから一覧が現れる。
   すりガラスの質感（blur(20px) saturate(165%)＋groundの半透明）は、縮んだ
   PLAY・ハンバーガー・開いた一覧の3面すべてに同じ値で通してある。 ══════════════════════ */

:root{
  /* ── 地の色（§18.1。2026-08-12：地の軌跡＝STOPS配列とpaintGroundは廃止した）。
     全節・全ページ共通の固定値。ここを書き換えるだけで --ground/--surface/--border
     （すぐ下で var(--gL)/var(--gC)/var(--gH) から自動導出される）が全ページ一括で
     追従するため、個々のUIコンポーネント側は一切変更していない。
     節ごとの進行感（旧・地の軌跡が担っていた役割）はインク層の色（§18.2）が引き継ぐ。
     サブページ（/modes/*・features/cards/contact）も同じ値に揃えてある。 ── */
  --gL:.265; --gC:.090; --gH:255;
  --ground : oklch(var(--gL) var(--gC) var(--gH));
  --surface: oklch(calc(var(--gL) + .06) calc(var(--gC) * .95) var(--gH));
  --border : oklch(calc(var(--gL) + .15) calc(var(--gC) * .75) var(--gH));

  /* ── 文字と意味色（§10.3.5） ── */
  --t1:#eef3f9; --t2:#b9c6d8; --t3:#7d8ba0;
  --accent:#fa2a4e; --accent-rgb:250,42,78;   /* 面と図形専用。文字色には使わない */
  --gold:#ffd24a;                             /* 第2アクセント。文の中の要点だけを金にする */
  /* 見出しの四角囲み（今回追加）の塗り色。--gold の明度・彩度に、--ground の
     色相 --gH（255°）の補色（+180°＝75°）を掛け合わせたもの。非対応ブラウザ
     向けのフォールバックはオフラインで計算した実測値（詳細は下の@supportsブロック
     と§10.3.5相当のコメントを参照）。 */
  --headFill:#ffc751;

  /* ── モジュラースケール 1.333（§10.4.2）。この9段以外を font-size に書かない ── */
  --fs-d3:5.61rem; --fs-d2:4.21rem; --fs-d1:3.16rem; --fs-h1:2.37rem;
  --fs-h2:1.78rem; --fs-h3:1.33rem; --fs-b:1rem; --fs-s:.75rem; --fs-xs:.563rem;

  /* ── スペーシング 8px・7段（§10.5.2）。この7段以外を margin/padding/gap に書かない ── */
  --s1:.5rem; --s2:1rem; --s3:1.5rem; --s4:2.5rem; --s5:4rem; --s6:6.5rem; --s7:10.5rem;

  /* ── 組み（§10.4.3） ── */
  --lh-d:1.15; --lh-h:1.4; --lh-b:1.8;
  --tr-jp:.02em;        /* 和文・基本層（Zen Kaku Gothic New）。角ゴシックは大きくすると詰まって見えるため開く */
  --tr-jp-accent:.01em; /* 和文・強調層（Shippori Mincho B1） */
  --tr-label:.14em;     /* 欧文ラベル・大文字（.en＝Archivo 600） */
  --tr-en-d:-.02em;     /* 欧文ディスプレイ（Archivo・Playfair Display）。大きくすると空いて見えるため詰める */

  /* ── グリッド（§10.5.1） ── */
  --gut:24px;
  --pad:clamp(24px,5vw,80px);

  --e:cubic-bezier(.16,1,.3,1); /* GSAPのpower4.out相当。跳ねずに長く尾を引いて減速する。
    全リベール（.reveal/.headRule/.maskReveal/.hSlide/.barFill）で共通に使う既定イージング */
  --e-back:cubic-bezier(.34,1.56,.64,1); /* オーバーシュート専用。y値が一瞬1を超える。
    2026-08-15：見出し横スライド（.hSlide）から撤去した（「勢いが良すぎる」という指摘の
    原因だったため）。現在どこからも参照されていないが、跳ね返りが意図的に必要になる
    箇所のために定義だけ残す */
}

/* 相対カラー構文（§10.8.3-3）。対応ブラウザでは面・罫を地の色から直接導出し、
   手書きcalc()を消す。非対応時は:root既定のcalc()版（--gC*.95等）を残す。 */
@supports (color: oklch(from red l c h)){
  :root{
    --surface: oklch(from var(--ground) calc(l + .06) calc(c * .95) h);
    --border : oklch(from var(--ground) calc(l + .15) calc(c * .75) h);
    /* --headFill＝地の濃紺の補色。oklch(from …) は1色の l/c/h しか取り出せない
       ため、明度・彩度は --gold から、色相だけ --gH（:root の地の色相トークン。
       今は255°）+180° に差し替える。calc(var(--gH) + 180) は435°になるが、
       hue は周期量なのでブラウザ側で360°を引いた75°として解決される。
       実測：oklch(from #ffd24a l c 75) ≈ #ffc751（--gold #ffd24a とほぼ同じ
       明るさの黄色で、地 --ground #00244f との補色関係を満たす）。 */
    --headFill: oklch(from var(--gold) l c calc(var(--gH) + 180));
  }
}

*{box-sizing:border-box}
/* ルートを流動化する（§10.4.2）。PCで文字が小さいという指摘への対処。
   表にない数値を font-size に書かないため、個々の clamp() を手で書き換えるのでは
   なく、基準そのものを動かして9段のスケールを丸ごと持ち上げる。16px→21px（1900px以上）。 */
html{font-size:clamp(16px, .42vw + 12.6px, 21px);
  overflow-x:clip;background:var(--ground);transition:background-color .4s linear}
body{margin:0;overflow-x:clip;color:var(--t1);background:transparent;
  font-family:'Zen Kaku Gothic New',system-ui,sans-serif;font-weight:400;
  font-size:var(--fs-b);line-height:var(--lh-b);-webkit-font-smoothing:antialiased}
h1,h2,p{margin:0}
/* height:auto は必須。width/height 属性で固有比率を伝えると、
   CSS側で高さを解放しない限り属性値がそのまま高さになる（画像が縦に伸びる）。 */
img{max-width:100%;display:block;height:auto}
a{color:inherit;text-decoration:none}

/* ══════ タイポグラフィ：基本層＋強調層の2層構造（§10.4.1） ══════ */
.jpBase{font-family:'Zen Kaku Gothic New',sans-serif;font-weight:900;
  line-height:var(--lh-d);letter-spacing:var(--tr-jp);
  text-box:cap alphabetic}
.enBase{font-family:'Archivo',sans-serif;font-weight:800;letter-spacing:var(--tr-en-d)}
/* 強調層。タグライン・キャッチコピー・節見出しに使う
   （2026-08-12 拡張。節見出し「現実とリンクした世界観」「遊び方」を
   キャッチと同じ書体に揃えるというユーザー判断による。
   🚫 本文・UI・ラベルへの流用は引き続き禁止）。 */
.jpAccent{font-family:'Shippori Mincho B1',serif;font-weight:800;
  line-height:var(--lh-d);letter-spacing:var(--tr-jp-accent);
  text-box:cap alphabetic}
.enAccent{font-family:'Playfair Display',serif;font-weight:900;letter-spacing:var(--tr-en-d)}
.en{font-family:'Archivo',sans-serif;font-weight:600;letter-spacing:var(--tr-label)}

/* グレインは装飾ではなくディザである。極暗の大面積グラデーションが
   8bit表示で起こすバンディングを潰す（§10.3.3）。縮退時も残す。 */
body::after{content:'';position:fixed;inset:0;pointer-events:none;z-index:97;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E")}

/* ══════ スクロール出現（§11.3-1・§20.7で移動量を強化） ══════
   すべての主要要素を、ビューポートに入ったら下からふわりと出現させる。
   translateY(--s6)→0・scale(.96)→1・opacity 0→1（2026-08-12：--s5→--s6へ、
   わずかな拡大を追加してリベールをいまより強く見せる）。対応ブラウザは
   animation-timeline:view() だけで駆動し、rAFループを増やさない。非対応時は
   IntersectionObserver でクラス .is-in を付与し、通常の transition に
   切り替える（各ページの site.js が担う）。stagger は data-d="0"〜"3" の4段。
   ⚠️ .reveal は <section> そのものには付けない。節全体が薄くなり、読んでいる
   最中に内容が消える不具合が実際に起きたため（§20.7）。 */
.reveal{opacity:0;transform:translateY(var(--s6)) scale(.96)}

@supports (animation-timeline: view()){
  .reveal{
    /* 2026-08-15：timing-functionをlinearからvar(--e)へ変更した。linearは
       スクロール量にそのまま比例するだけで「慣性が働いている感じがしない」
       （ユーザー指摘）。var(--e)＝power4.out相当にすると、スクロール駆動でも
       進行の後半でしっかり減速するため、time-based transitionと同じ「勢いよく
       出て長く尾を引く」体感になる（.barFillが元々この考え方で作られており、
       それに揃えた）。range開始も entry 0% → entry 28% へ後ろにずらし、要素が
       画面にある程度入ってから動き出すようにした（「表示タイミングが早い」の
       指摘への対処）。 */
    animation-name:revealIn;animation-timing-function:var(--e);animation-fill-mode:both;
    animation-timeline:view();animation-range:entry 46% entry 100%}
  .reveal[data-d="1"]{animation-delay:12%}
  .reveal[data-d="2"]{animation-delay:24%}
  .reveal[data-d="3"]{animation-delay:36%}
}
@supports not (animation-timeline: view()){
  .reveal{transition:opacity .7s var(--e),transform .7s var(--e)}
  .reveal[data-d="1"]{transition-delay:.12s}
  .reveal[data-d="2"]{transition-delay:.24s}
  .reveal[data-d="3"]{transition-delay:.36s}
  .reveal.is-in{opacity:1;transform:translateY(0) scale(1)}
}
@keyframes revealIn{
  from{opacity:0;transform:translateY(var(--s6)) scale(.96)}
  to{opacity:1;transform:translateY(0) scale(1)}
}

/* 見出し直後の細い罫（2026-08-12：見出しの上から下へ移設）。太さ1〜2pxは
   margin/padding/gap ではないため §10.5.2 の7段規律の対象外。scaleX(0)→1・
   transform-origin:left で左から右へ伸びる。data-d="0" を持たせ、DOM順は
   見出し（data-d="1"）の直後だが、アニメーションは data-d の遅延段で見出しより
   先に動き出す（罫→見出し→本文の出現順序は維持。位置だけ動かした）。
   margin-bottom はあえて持たせない。罫の直後に来る本文側要素（.whyBody や
   .modeBody 等）が既に §10.5.2 の7段から選んだ margin-top を持っており、
   それをそのまま罫→本文の間隔として使う。ここに margin-bottom を足すと
   文脈によって（通常フローでの隣接マージン相殺／グリッドアイテムでの非相殺）
   合計間隔が場所ごとにばらつくため、罫側は見出しとの間隔（margin-top）だけを持つ。 */
.headRule{display:block;transform-origin:left;transform:scaleX(0);
  width:clamp(4rem,34%,18rem);height:1px;background:var(--gold);
  margin-top:var(--s2)}
@supports (animation-timeline: view()){
  /* 2026-08-15：.reveal と同じ理由でvar(--e)へ、rangeも entry 20% から開始に変更した。 */
  .headRule{animation-name:ruleIn;animation-timing-function:var(--e);animation-fill-mode:both;
    animation-timeline:view();animation-range:entry 40% entry 90%}
}
@supports not (animation-timeline: view()){
  .headRule{transition:transform .6s var(--e)}
  .headRule.is-in{transform:scaleX(1)}
}
@keyframes ruleIn{ from{transform:scaleX(0)} to{transform:scaleX(1)} }

/* ══════ 見出しの帯モーション（2026-08-15：2回目の作り直し） ══════
   参照：showdot.jp をヘッドレスChromeでDOM走査して実測し直した（ユーザー
   指摘2件への対応）。「文字の移動量と幅がまだ速い」「四角が出てくるまでの
   モーションが速くて再現できていない。四角が出る前に細かい小さい円のような
   動きがある」。
   ⚠️ 2026-08-17：この節の元になった「点が育って融合する」表現は廃止した
   （ユーザー指示。WORKTRACK 12-3）。showdot.jp の小円1006個を
   radial-gradient の繰り返しで近似していた実装は、次の1段に置き換えてある。
     1. 帯：::before を scaleX(0→1) で左から右へ伸ばす
     2. 文字：.hText を opacity 0→1 ＋ わずかな translateY（.3em→.12emへ
        縮小。「移動量がまだ速い」への対応）で、帯が伸び切ってから現す
   順序（帯 → 文字）とイージングは変えていない。
   イージングは両方とも --e（cubic-bezier(.16,1,.3,1)＝GSAPのpower4.out
   相当）のまま。跳ねさせない。
   ⚠️ animation-range は entry ではなく cover を使う。この見出し（2行・
   約114px）は entry 0%→100% の実スクロール幅が要素自身の高さに縛られる
   （＝仕様上 min(要素の高さ, ビューポート高さ) しかない。PCで実測約114px）
   ため、%を広げても実際に動く距離が伸びない。cover は「要素が入り始めて
   から完全に出きるまで」＝viewportHeight＋要素の高さ が母数になり、PCで
   実測約1000px（entryの約9倍）。同じ開始トリガー（要素が入り始める点＝
   どちらも0%）を保ったまま、実際に動く距離だけを稼げる。
   対象は節見出しだけ（.catch/.secTitle/.wayHead＝LP、.modeSecTitle＝
   サブページ共通の節見出し）。本文・ラベル・UIには広げない。
   これらの見出しは既存の .reveal（§11.3-1・縦フェード＋scale）も同時に
   持っているため、演出を .hSlide 側へ一本化するにあたり .reveal 側の
   動きだけを打ち消す（対象外の .reveal はそのまま）。 */
:is(.catch,.secTitle,.wayHead,.modeSecTitle).reveal{
  opacity:1;transform:none;animation:none}

/* .hSlide 自身は帯の土台（position:relative）だけを担う。isolation:isolate
   は下の ::before（z-index:-1）が .barPlay/.btnFill と同じ考え方で自分の
   内側だけに留まり、ページ全体のスタッキングへ漏れ出さないようにするため。
   ::before の transform:scaleX(0) が初期値。対応環境では下の @supports
   ブロックがスクロール駆動（animation-timeline:view()）で scaleX(1) まで
   伸ばし、非対応環境では site.js の .is-in による transition で伸ばす。
   ⚠️ 2026-08-17：対応・非対応で別実装だった状態を解消し、どちらも
      「帯が左から右へ伸びる」1つの表現に統一した。 */
.hSlide{display:inline-block;position:relative;isolation:isolate;vertical-align:top}
.hSlide::before{content:'';position:absolute;inset:0;z-index:-1;
  transform-origin:left;transform:scaleX(0)}
.hText{display:inline-block;opacity:0;transform:translateY(.12em)}

/* ⚠️ @property は @supports の外（トップレベル）に置く。中に入れると登録に
   失敗した環境で var() が解決できず、宣言ごと無効になる（厳守事項2）。
   ⚠️ 2026-08-17：ここにあった --dotR / --dotSweep の @property 登録は削除した。
   点の列が育って融合する演出そのものを廃止し、帯を左から右へ伸ばすだけに
   したため（ユーザー指示。WORKTRACK 12-3）。 */

/* ══════ 見出しの四角囲み（§25.2の土台。塗り色と余白） ══════
   参照：showdot.jp。節見出しの文字を --headFill で塗った帯の上に置く。
   文字色は指示どおり --ground そのもの（濃紺）。--headFill（実測
   #ffc751相当）に対するコントラスト比は9.92:1（AAA）で4.5:1を大きく上回る。
   color は .hSlide に置いたまま子の .hText へ継承させる（color は継承
   プロパティなので二重定義が要らない）。
   ⚠️ ここは background（ショートハンド）ではなく background-color だけを
   使う。ショートハンドの background は他の background-* をまとめて初期値へ
   リセットしてしまうため、同じ詳細度の別ルールと組み合わせたときに意図しない
   打ち消しが起きる（厳守事項3。実際に点の列が消える事故を踏んだ）。
   このルールを @supports ブロックより前に置くこと自体は動作上必須ではない
   （同じ詳細度なら @supports 側が後勝ちする）が、読む順を「土台→上書き」に
   揃えるために先に置いている。 */
:is(.catch,.secTitle,.wayHead,.modeSecTitle) .hSlide::before{
  background-color:var(--headFill)}
:is(.catch,.secTitle,.wayHead,.modeSecTitle) .hSlide{
  color:var(--ground);padding:var(--s2) var(--s3)}
/* ⚠️ 見出し本体（h2）は .jpAccent/.jpBase の text-box:cap alphabetic により、
   自分の行ボックスを字面の高さぶんだけに詰めている。この詰めは h2 自身の
   レイアウト高さ（＝直後の兄弟要素の開始位置の基準）には影響するが、内側の
   .hSlide に足したパディングつきの背景box（見た目の高さ）には影響しない
   ため、そのままでは直後の本文（.whyBody 等）が四角の下辺に食い込んで重なる
   （実機で確認）。margin-bottom ではなく padding-bottom を使う：直後の
   要素側が既に持つ margin-top（--s5 等）はブロックの垂直マージンどうしの
   相殺の対象だが、padding は相殺されないため、四角の視覚的なはみ出し分を
   確実に別枠で確保できる。 */
:is(.catch,.secTitle,.wayHead,.modeSecTitle){padding-bottom:var(--s5)}

@supports (animation-timeline: view()){
  /* 帯（2026-08-17改訂）。スクロール量に連れて左から右へ伸びるだけにした。
     ⚠️ 旧実装は「点の列が現れて育ち、融合して帯になる」2段構えだったが、
        ユーザー指示により廃止した（WORKTRACK 12-3）。文字が出るのは帯が
        伸び切ってから、という順序は変えていない。 */
  :is(.catch,.secTitle,.wayHead,.modeSecTitle) .hSlide::before{
    animation-name:hBandGrow;
    animation-timing-function:var(--e);
    animation-fill-mode:both;
    animation-timeline:view();
    /* cover 10%を起点にする理由は上の大コメント参照。cover換算でこの見出しの
       entry完了（＝要素が画面に全部入りきる点）はおよそ15%相当なので、10%は
       まだそのentry途中＝旧実装とほぼ同じ体感の始点を保っている。 */
    animation-range:cover 22% cover 46%;
  }
  /* 文字は帯が伸び切る cover 34% から始め、cover 50% で
     完了させる。この見出し・このビューポートでは「画面に全部入りきって
     いる」期間（containに相当）がおよそcover 85%付近まで続くため、文字が
     出そろう時点でも見出しはまだ画面内に留まっている（実測は
     design/official_site_spec.md §を参照）。 */
  .hText{
    animation-name:hTextIn;animation-timing-function:var(--e);animation-fill-mode:both;
    animation-timeline:view();animation-range:cover 46% cover 62%;
  }
}
@supports not (animation-timeline: view()){
  /* 非対応環境では点を経ずに素の帯を出す（情報が欠けないこと）。既存どおり
     scaleX(0→1) の板で表現し、site.js の IntersectionObserver が付与する
     .is-in で駆動する。 */
  .hSlide::before{transition:transform .6s var(--e)}
  .hText{transition:opacity .6s var(--e) .12s, transform .6s var(--e) .12s}
  :is(.catch,.secTitle,.wayHead,.modeSecTitle).is-in .hSlide::before{transform:scaleX(1)}
  :is(.catch,.secTitle,.wayHead,.modeSecTitle).is-in .hText{opacity:1;transform:translateY(0)}
}
/* 帯の伸長。イージングは共通の --e（power4.out）。
   ⚠️ 2026-08-17：旧 hDotGrow（点を育てて融合させる多段キーフレーム）を
      廃止して、この2点の伸長に置き換えた。 */
@keyframes hBandGrow{ from{transform:scaleX(0)} to{transform:scaleX(1)} }
@keyframes hTextIn{ from{opacity:0;transform:translateY(.12em)} to{opacity:1;transform:translateY(0)} }

@media (prefers-reduced-motion: reduce){
  /* transform・mask-image・background-imageの3経路すべてを打ち消し、対応・
     非対応どちらの実装でも「完成した帯＋見える文字」の最終状態へ確実に
     固定する（情報が欠けないこと）。 */
  html:not([data-motion="on"]) .hSlide::before{
    transform:scaleX(1) !important;
    mask-image:none !important; -webkit-mask-image:none !important;
    background-image:none !important; background-color:var(--headFill) !important}
  html:not([data-motion="on"]) .hText{opacity:1 !important;transform:none !important}
}

/* ══════ 画像がマスクで開く（§12.1） ══════
   clip-path:inset() を scroll-driven で動かし、マスクが横に開いて中身が現れる
   動きにする。親に overflow:hidden を持たせ、子（img）を逆方向にわずかに動かして
   視差を作る。--mo の @property 初期値は 0%（＝マスクなし＝全面表示）にして
   あるため、非対応ブラウザや prefers-reduced-motion では
   アニメーションが走らず、そのまま情報が欠けずに全体表示される。 */
.maskReveal{position:relative;overflow:hidden}
/* ⚠️ @property は @supports の外に置く（v5-proto.html の --p と同じ理由）。
   登録に失敗した環境で var(--mo) が解決できず、clip-path ごと無効になる。 */
@property --mo{ syntax:'<percentage>'; inherits:false; initial-value:0% }

@supports (animation-timeline: view()){
  /* 2026-08-15：マスク開き本体（maskOpen）は .reveal と同じ理由で
     timing-functionをlinearからvar(--e)へ、rangeもentry 0%→entry 25%へ
     後ろにずらした。画像の視差（maskParallax）はマスクの開きに従属する
     副次的な動きなので、rangeだけ揃えてtiming-functionはlinearのまま
     残す（視差はスクロール量に素直に追従させたい）。 */
  .maskReveal{
    clip-path:inset(0 var(--mo, 0%) 0 0);
    animation:maskOpen var(--e) both;
    animation-timeline:view();
    animation-range:entry 25% entry 85%;
  }
  .maskReveal > img{
    animation:maskParallax linear both;
    animation-timeline:view();
    animation-range:entry 25% entry 85%;
  }
  @keyframes maskOpen{ from{ --mo:100% } to{ --mo:0% } }
  @keyframes maskParallax{ from{ transform:translateX(-4%) scale(1.06) } to{ transform:translateX(0) scale(1.06) } }
}
@media (prefers-reduced-motion: reduce){ html:not([data-motion="on"]) .maskReveal{ clip-path:none } }

/* ══════ 背景の粒子と幾何学的な線（今回追加。全ページ共通） ══════
   参照：showdot.jp／yoasobi-music.jp。紺の地（--ground）の上に、静かに横流れする奥行きを
   足す。演出だけを採り、ライブラリは採らない。新しい色は作らず、粒子・
   線とも白（--t1）または既存の罫トークン（--border）の低不透明度で
   表現する。
   ⚠️ 負荷対策（ユーザーのPCが重いための最優先事項）：
     ・要素は粒子18個＋線4本の計22個に絞った（粒子20個以内の指示を満たす）
     ・動かすのは transform と opacity だけ（left/top/width等は静的に
       置くのみで、アニメーションはさせない）
     ・JSのrAFループは増やしていない。すべてCSSアニメーションのみ
     ・canvas / WebGL は使わない
     ・幾何学的な線は静止させ、アニメーションを持たせていない
       （粒子の18本だけが常時走るアニメーションになる）
   本文（.sec）より確実に後ろに敷くため、.bgField は z-index:0 の
   position:fixed とする（.sec/footer が z-index:1 を持つのはそのまま。
   厳守事項8参照）。.pageScale の外（body直下）に置くことで、ハンバーガー
   メニューを開いたときの scale(.94) の影響を受けない（.loadOverlay/
   .siteLogo と同じ理由）。
   3層（速度・大きさ・不透明度が段ごとに違う）にして奥行きを出す：
   --a＝遠景（小さい・薄い・遅い）／--b＝中景／--c＝近景（大きい・濃い・速い）。
   各粒子は要素ごとに --y（縦位置）と animation-delay（負値）だけを
   インラインで持たせ、同じ帯に固まって流れないよう出発位置をずらす。
   prefers-reduced-motion では、既存の
   `html:not([data-motion="on"]) *{animation:none!important}` が
   .bgDot のアニメーションにもそのまま効くため、個別の @media は
   重ねて書いていない（要素は残り、静止した点と線になるだけで情報は
   何も持たないため欠落もしない）。 */
.bgField{position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none}

.bgDot{position:absolute;left:-8%;top:var(--y,50%);border-radius:50%;
  background:var(--t1);
  animation-name:bgDotDrift;animation-timing-function:linear;animation-iteration-count:infinite;
  will-change:transform}
.bgDot--a{width:2px;height:2px;opacity:.16;animation-duration:95s}
.bgDot--b{width:3px;height:3px;opacity:.28;animation-duration:76s}
.bgDot--c{width:5px;height:5px;opacity:.42;animation-duration:58s}
/* 横流れ（左→右）。⚠️ 直線移動だと機械的に見えるので、上下にわずかに揺らして
   水中の粒のような不規則さを出す。transformだけなので負荷は変わらない。
   ⚠️ 2026-08-17：一度この向きを縦へ変えたが、向きの変更は指示ではなかったため
      横へ戻した。yoasobi-music.jp の実測から採ったのは**向き以外**の4点である。
        ・秒数を約1.5倍に遅くした（52〜100秒の領域。旧 65/45/32 → 95/76/58）
        ・負の animation-delay を各層の秒数いっぱいに散らした
        ・出発位置（--x）の等間隔をやめて不規則にした
        ・揺れを残した（YOASOBIは完全な直線だが、硬く見えるため採らなかった）
   🚫 YOASOBI は top プロパティ自体をアニメーションさせているが採らない。
      毎フレームのレイアウト再計算が走るため。transform のままにする。 */
@keyframes bgDotDrift{
  0%   { transform:translate(0, 0) }
  25%  { transform:translate(29vw, -1.4vh) }
  50%  { transform:translate(58vw, 1.1vh) }
  75%  { transform:translate(87vw, -0.7vh) }
  100% { transform:translate(116vw, 0) }
}
/* ⚠️ 移動距離は 116vw なので、画面が狭いスマホでは同じ秒数でも絶対的な速さが
   1/4以下になり、著しく緩慢に見える（実機で指摘された）。狭い画面では秒数を
   詰めて体感の速さを揃える。⚠️ 2026-08-17に基準秒数を 65/45/32 → 95/76/58 へ
   遅くしたので、この上書きも同じ比率（約0.4倍）で引き直してある。 */
@media(max-width:899px){
  .bgDot--a{animation-duration:38s}
  .bgDot--b{animation-duration:30s}
  .bgDot--c{animation-duration:23s}
}

.bgLine{position:absolute;height:1px;background:var(--t1);opacity:.1;transform-origin:left center}

/* ⚠️ 粒子は left:-8%（画面外）から始まり、アニメーションだけが画面内へ運ぶ。
   そのため prefers-reduced-motion で animation が止まると、18個すべてが
   画面外に留まって1つも見えなくなる（実機で実際にそうなった）。
   縮退時は各粒子の --x（HTML側にインラインで持たせた静止位置）へ置き、
   動かないだけで「見えている」状態にする。 */
/* ⚠️ 粒子は left:-8%（画面外）から始まり、アニメーションだけが画面内へ運ぶ。
   そのため縮退で animation が止まると18個すべてが画面外に留まって1つも
   見えなくなる（実機で実際にそうなった）。縮退時は各粒子の --x（HTML側に
   インラインで持たせた静止位置）へ置き、動かないだけで「見えている」状態にする。 */
@media (prefers-reduced-motion: reduce){
  html:not([data-motion="on"]) .bgDot{ left:var(--x, 50%) }
}

/* ══════ 起動演出：4幕ローディング（§20.1・2026-08-12。§12.4を置き換え） ══════
   合計2.2秒、4幕で構成する。
     幕1 0.0–0.5s：真っ白な画面。中央に produced/by Ready or Lab（2行）と
                   見出し線が小さくフェードイン
     幕2 0.5–1.3s：黒いインクの染みが中心から全方向へ、速度と衝撃を持って
                   広がる。feTurbulence + feDisplacementMap で有機的に歪ませる
                   （WebGL不使用。ENABLE_GL_INKとは無関係の別系統）。画面が
                   真っ暗になるまで
     幕3 1.3–1.9s：暗転した画面にブランドロゴがイーズインで登場
     幕4 1.9–2.2s：ロゴ＋オーバーレイ全体がフェードし、下に先に描画済みの
                   ヒーローが現れる
   演出そのものはCSSのanimation-delayだけで進行する（JSのクラス切り替えに
   依存しない）。これにより site.js の initIntro が完全に失敗しても4幕は
   最後まで自動再生され、オーバーレイも自動的に消える。JSが担うのは
   幕2終了後にインクの<svg>を実際にDOMから外すこと（コストを0.8秒に
   閉じ込める。ただし.loadInk自体にも同じ目的のCSSオンリーの
   display:none落としを二重で持たせてある）と、演出完了後にオーバーレイ
   ノードを片付けることだけである。
   🚫 JSが失敗してもオーバーレイが残ってページが操作不能にならないこと。
   これが最優先。CSSだけで効く失効タイマーを二重に置く
   （2.4秒＝一次・8秒＝二次。8秒は既存の保険をそのまま踏襲）。
   prefers-reduced-motion は下の @media だけで確実に無効化する（JS非依存）。
   sessionStorage で同一セッション中は2回目以降出さない（各ページ<head>の
   同期スクリプトが判定する）。 */
.loadOverlay{position:fixed;inset:0;z-index:200;
  overflow:hidden;background:#fff;
  animation:loadOverlayOut .45s var(--e) 4.45s both,
            loadOverlayHide 0s 5.2s forwards,
            introHideForce 0s 8s forwards}
@keyframes loadOverlayOut{ from{opacity:1} to{opacity:0;pointer-events:none} }
@keyframes loadOverlayHide{ to{ display:none } }
.loadOverlay.is-leaving{opacity:0;pointer-events:none}
html.intro-skip .loadOverlay{display:none}
@keyframes introHideForce{ to{ display:none } }

html.intro-lock{overflow:hidden;
  animation:introUnlockPrimary 0s 4.9s forwards, introUnlockForce 0s 8s forwards}
@keyframes introUnlockPrimary{ to{ overflow:visible } }
@keyframes introUnlockForce{ to{ overflow:visible } }

/* ── 幕1（0–0.5s）：produced / by Ready or Lab ── */
.loadCredit{position:absolute;inset:0;z-index:1;display:flex;flex-direction:column;
  align-items:center;justify-content:center;
  opacity:0;transform:translateY(var(--s1));
  animation:loadCreditIn .70s var(--e) 1.55s both}
@keyframes loadCreditIn{
  0%{opacity:0;transform:translateY(var(--s1))}
  100%{opacity:1;transform:translateY(0)}
}
.loadCreditLine{display:block;font-size:var(--fs-xs);letter-spacing:var(--tr-label);
  color:#0b1420;text-align:center;line-height:1.7}
.loadCreditRule{display:block;width:2.5rem;height:1px;background:#0b1420;
  margin-top:var(--s1);transform-origin:center;transform:scaleX(0);
  animation:loadCreditRuleIn .52s var(--e) 1.73s both}
@keyframes loadCreditRuleIn{ to{ transform:scaleX(1) } }

/* ── 幕2（0.5–1.3s）：黒いインクの染み ──
   feTurbulence（fractalNoise）で歪みの元ノイズを作り、feGaussianBlurで
   丸めて「表面張力」らしい滑らかな凹凸にしてからfeDisplacementMapへ渡す
   （要件1：有機的な歪み）。baseFrequencyを時間で下げ、粗い高周波ノイズから
   大ぶりな低周波の歪みへ移すことで、拡大しながら形そのものが育つ動きにする。
   displacementのscaleを0から一気に上げて触手状の突起を伸ばし（要件3）、
   出力側の最終feGaussianBlurで輪郭をわずかに滲ませる（要件2）。
   フィルタの発火はこの0.8秒のみ（SMILのbegin/durで自己完結、JS不要）。 */
.loadInk{position:absolute;inset:0;z-index:2;width:100%;height:100%;overflow:hidden;
  display:block;pointer-events:none;
  /* ⚠️ 乗算はこの親に掛ける。動画側に掛けてはいけない。
     .loadInk は z-index を持つため合成のグループを分離する。その内側で
     mix-blend-mode を指定すると、合成相手が「グループ内の何もない透明」に
     なり、白が抜けずに動画の白い矩形がクレジットを覆う。ここに掛ければ
     .loadOverlay の白地とクレジットを相手に合成される。 */
  mix-blend-mode:multiply;
  /* 幕2が終わったら描画から外す。JSが止まっていても効くCSS側の保険。 */
  animation:loadInkHide 0s 4.50s forwards}
@keyframes loadInkHide{ to{ display:none } }

/* 幕2（0.75〜2.65秒）：実写のインク動画。
   ⚠️ 過去の失敗を繰り返さないための経緯。
     1. invert(1) …… 画像の大半が白い矩形になり、白地の上でインクが見えなかった
     2. 輝度マスク … PCでは出たが iPhone で消えた。mask-mode:luminance が Safari
                     未対応で、不透明なWebPがアルファマスク扱いになり矩形が真っ黒に
     3. 巨大レイヤー… 150vmax を scale(3.4) で拡大していたため、iPhone（画素密度3）
                     で内部1万数千ピクセルとなりテクスチャ上限を超えて描画ごと消滅
   結局どれもコードで流体を描こうとしたのが原因である。実写の動画素材を
   mix-blend-mode:multiply で重ねる方式に変えた。multiply は白を透過させ
   黒だけを残すので、白地のオーバーレイにそのまま馴染む。
   素材は ffmpeg で加工済み（assets/ink/ink_load_timed.mp4・240KB）。
     ・白点を 214→255 へ持ち上げて地を純白にした（元素材の地はグレー）
     ・setpts で時間を再マッピングし「静か→不意打ちの爆発」を焼き込んだ
       （尺2.10秒・緩急0.25・素材0.00〜5.80秒。2026-08-12 ユーザー決定）
     ・1.9秒に切り詰めた。元は9.8秒・2.25MB
   ⚠️ 緩急は素材側にある。playbackRate や currentTime で操作しないこと。 */
.loadInkVid{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:center;
  /* 滴の落下点をクレジットの少し上へ逃がす。真上に落とすと、読ませたい
     produced / by Ready or Lab が現れた直後に黒い塊で塗り潰され、墨消しの
     ように見える。上へ逃がすと、文字が読めている状態からインクが下りてきて
     呑み込む流れになる。scale は translate で空く端を埋めるためのもので、
     画面の1.18倍までしか広げない（巨大レイヤーを作らないこと）。 */
  transform:translateY(-9%) scale(1.18);
  opacity:0;animation:loadVidShow 0s linear 2.25s both}
@keyframes loadVidShow{ from{opacity:0} to{opacity:1} }

/* 安全網：SVGフィルタやtransformの解釈差があっても、幕2の終わりには必ず
   画面が真っ暗になるようにする（インクの見た目の成否と独立した保険）。
   幕3のあいだ黒を維持し、幕4はオーバーレイ本体（loadOverlayOut）と
   歩調を合わせてロゴごと消える。 */
.loadBlackout{position:absolute;inset:0;z-index:3;background:#04070c;
  opacity:0;animation:loadBlackoutSeq .60s linear 3.90s both}
@keyframes loadBlackoutSeq{
  0%{opacity:0}
  35%{opacity:0}
  80%{opacity:1}
  100%{opacity:1}
}

/* ── 0→100 のカウント（今回追加。参照：showdot.jp の素材読み込みカウント） ──
   目的は素材（動画・CSS・JS）の読み込み時間を演出として見せること。
   JSに依存しない形にするため、@propertyで整数として登録したカスタム
   プロパティ --n と、CSSの counter() だけで組む。
   幕1の頭（0.00s）から幕2がインクで画面を覆い切る瞬間（2.85s）に100へ
   到達するよう animation-duration を2.85sに合わせてある。インクの尺・
   タイミング自体はここでは一切変更していない。
   位置は右下の隅。produced/by Ready or Lab のクレジット（画面中央）と
   喧嘩しないよう小さく控えめに置く。z-indexは.loadCreditと同じ1にして
   あるため、幕2のインクが中央から広がって覆っていく過程で、クレジットと
   同じタイミングでこの数字も呑み込まれる（100に達する頃に自然と隠れる）。
   ⚠️ @property は @supports の外（トップレベル）に置く。@supports の中に
   入れると登録に失敗した環境で var(--n) が解決できず宣言ごと無効になる
   （実際に踏んだ不具合。上の .maskReveal の --mo と同じ注意点）。
   ⚠️ カウンタが出ない環境（@property非対応など）でも破綻しないよう、
   counter-reset に var(--n, 0) のフォールバックを渡してある。その場合は
   「0%」で静止するだけで、要素が消えたり空白のまま浮いたりはしない。 */
/* ⚠️ inherits:true にしてある（2026-08-16）。円弧の stroke-dashoffset と
   数字の両方が同じ --n を読むため、進捗の出どころが1つに保たれる。
   inherits:false のままだと子孫が値を読めず、円弧と数字が別々に動く。 */
@property --n{ syntax:'<integer>'; inherits:true; initial-value:0 }

/* 幕0（2026-08-16 作り直し）：画面中心の周回リング＋LOAD＋0→100 のダイヤル。
   ⚠️ 順序を守ること。ローディングの目的は produced by 以降のモーションが
      カクついたり飛んだりしないための時間稼ぎであり、0→100 が終わってから
      produced by を始める（過去に一度この順序を崩して指摘を受けている）。
      カウント(0.10〜1.40秒) → クレジット(1.55〜2.25秒) → インク(2.25〜4.35秒)。 */
.loadGauge{position:absolute;z-index:1;inset:0;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:var(--s3);
  pointer-events:none;opacity:0;
  /* 進捗の唯一の出どころ。ここで --n を動かし、子孫が読む。
     緩急は「勢いよく出て終盤で締まる」形にする（実際の読み込みの体感に近い）。 */
  animation-name:loadGaugeIn,loadCountUp,loadGaugeOut;
  animation-duration:.30s,1.30s,.18s;
  /* ⚠️ 前寄せを強くしすぎない。cubic-bezier(.16,.84,.30,1) では200msで35%・
     700msで93%まで飛び、残り600msが93→100でほぼ止まって「固まった」ように
     見えた（実測して差し替え）。下の曲線は終盤を緩めつつ停滞させない。 */
  animation-timing-function:var(--e),cubic-bezier(.33,.62,.42,1),var(--e);
  animation-delay:.05s,.10s,1.40s;
  animation-fill-mode:both,both,forwards}
@keyframes loadGaugeIn{ to{opacity:1} }
@keyframes loadGaugeOut{ to{opacity:0} }
@keyframes loadCountUp{ from{--n:0} to{--n:100} }

.loadRing{position:relative;width:clamp(104px,26vmin,168px);aspect-ratio:1;
  display:grid;place-items:center}
/* 円は常に回り続ける。進捗は円弧の長さが担い、回転は「読み込み中である」
   という信号だけを担う（2つの意味を1つの動きに混ぜない）。 */
.loadRingSvg{position:absolute;inset:0;width:100%;height:100%;
  transform:rotate(-90deg);animation:loadRingSpin 2.6s linear infinite}
@keyframes loadRingSpin{ to{ transform:rotate(270deg) } }
.loadRingTrack{fill:none;stroke:#0b1420;stroke-width:1.5;opacity:.14}
/* 2πr = 2 × π × 54 ≒ 339.29。--n が増えるほど offset が減って弧が伸びる。 */
.loadRingArc{fill:none;stroke:#0b1420;stroke-width:1.5;stroke-linecap:round;
  stroke-dasharray:339.29;
  stroke-dashoffset:calc(339.29 * (100 - var(--n, 0)) / 100)}
.loadRingWord{position:relative;font-size:var(--fs-xs);letter-spacing:var(--tr-label);
  color:#0b1420;opacity:.75}

.loadCount{display:flex;align-items:baseline;
  font-size:var(--fs-xs);letter-spacing:var(--tr-label);color:#0b1420;opacity:.55;
  font-variant-numeric:tabular-nums}
/* フォールバック：JSが動かない環境ではCSSの counter() がそのまま出る。
   JSが桁を組んだら html.has-loaddial 側でこちらを黙らせる。 */
.loadNum{counter-reset:n var(--n, 0)}
.loadNum::before{content:counter(n)}
html.has-loaddial .loadNum::before{content:none}
/* ダイヤル：桁が変わるときだけ、上から緩急をつけて新しい数字が降りてくる。
   ⚠️ 桁の箱に overflow:hidden を掛け、はみ出した旧数字を隠す。1emの箱に
      2枚重ねて片方を送り出す方式にしてあり、レイアウトは動かない。 */
.loadDigit{position:relative;display:inline-block;width:.62em;height:1.15em;
  overflow:hidden;vertical-align:baseline}
.loadDigit > i{position:absolute;inset:0;display:flex;align-items:center;
  justify-content:center;font-style:normal;line-height:1}

/* ── 幕3は廃止した（2026-08-12）──
   ローディングの最後にロゴを出すのをやめ、タイトルはファーストビューだけで
   見せる。同じ字を2度続けて出す必要がないため。暗転したままオーバーレイごと
   退場し、ファーストビューへ引き渡す。 */
/* ══════ カスタムカーソル：照準レティクル（§10.8.3-7・§20.3で拡大／色変化を追加） ══════
   2026-08-16（ユーザー指摘「2モードの説明ら辺でしかカーソルが変わらない。
   どこでも一貫してその形にする」）：旧仕様は「地の部分では出さない。押せる
   要素にホバーしたときだけ現れる」だったため、レティクルが出るのは
   a / button / .orbitNode / .modeShotWrap の上だけで、区画によって
   カーソルの見た目が変わっていた。ポインタが動いた時点から常時表示に改める
   （.is-live）。押せる要素での拡大（.is-active）と押下の色変化（.is-pressed）は
   従来どおり残し、「常にこの形／押せる所で大きくなる」の2段構えにする。
   PC（hover:hoverとpointer:fineの両方）に限定する。
   🚫 cursor:none にしない。ネイティブカーソルは残したまま重ねる。
   ホバー＝拡大（.is-active）、押下＝色変化（.is-pressed）の2つの信号を分ける。
   拡大と色変化は独立に効くため、ホバー中に押すと両方が同時に見える。 */
@media (hover:hover) and (pointer:fine){
  .cursorReticle{position:fixed;top:0;left:0;width:2.5rem;height:2.5rem;
    margin-top:-1.25rem;margin-left:-1.25rem;border-radius:50%;
    border:1px solid var(--t1);pointer-events:none;z-index:98;
    opacity:0;translate:-100px -100px;scale:.55;
    transition:opacity .2s var(--e),scale .3s var(--e),border-color .15s var(--e);
    will-change:translate}
  .cursorReticle::before, .cursorReticle::after{content:'';position:absolute;background:var(--t1);
    transition:background-color .15s var(--e)}
  .cursorReticle::before{left:50%;top:-6px;bottom:-6px;width:1px;transform:translateX(-50%)}
  .cursorReticle::after{top:50%;left:-6px;right:-6px;height:1px;transform:translateY(-50%)}
  /* 常時表示（2026-08-16）：ポインタが一度でも動いたら地の上でも出す。
     控えめな不透明度に留め、押せる要素での拡大（.is-active）を主役にする。
     ⚠️ この行は .is-active より前に置くこと。詳細度が同じ(0,2,0)なので
        後に書いたほうが勝つ。逆順にすると拡大時の opacity:1 が打ち消される。 */
  .cursorReticle.is-live{opacity:.45}
  /* ホバー：2.5rem→約4.5rem相当（scale 1.8）まで明確に広がる。 */
  .cursorReticle.is-active{opacity:1;scale:1.8}
  /* 押下：goldへ。§20.5のテキストのタップ反応と同じ規則。 */
  .cursorReticle.is-pressed{border-color:var(--gold)}
  .cursorReticle.is-pressed::before, .cursorReticle.is-pressed::after{background:var(--gold)}
}

/* ── グリッド：12カラム／ガター24px。全ページ共通の基盤（§10.5.1） ── */
.wrap{max-width:1280px;margin:0 auto;padding-inline:var(--pad);position:relative}
.g12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));column-gap:var(--gut)}
@media(max-width:899px){ .g12{display:block} }
/* ⚠️ z-index を明示する。inkGL キャンバスが z-index:0 の固定要素なので、
   節が z-index:auto のままだと描画順が保証されず、キャンバスが本文や
   カードの上に被って全体が霞む。footer も同様に持ち上げる。 */
.sec{position:relative;z-index:1}
body > footer{position:relative;z-index:1}

.srOnly{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}

/* ══════ スマホ改行の出し分け（今回3箇所で共通使用） ══════
   新しいブレークポイントは増やさず、既存の @media(max-width:899px) を使う。
   .mobileBr：PCでは無い扱い（改行しない）、スマホでだけ改行する <br> に使う。
   .pcBr  ：その逆。PCでだけ改行し、スマホでは改行しない <br> に使う。
   .pcOnly：スマホでだけ非表示にする（区切り記号などPC版限定の表示に使う）。
   ⚠️ 打ち消しは必ずこの @media ブロックの中に入れること。@media は詳細度を
      上げないため、定義より前に書くと後勝ちで無効になる（.closeKV で実際に踏んだ）。 */
.mobileBr{display:none}
.pcBr{display:block}
.pcOnly{display:inline}
@media(max-width:899px){
  .mobileBr{display:block}
  .pcBr{display:none}
  .pcOnly{display:none}
}

/* ══════ 02の見出し「現実とリンクした世界観」の組版（2026-08-16） ══════
   ⚠️ 見出し・短文は気持ち悪いところで改行しない。1〜2文字だけを次行へ送らない。
   修正前の実測（ヘッドレスChromeで各幅を計測）：
     390px  → 「現実とリンクし／た／世界観」（8文字で303px、使える幅294pxに9px足りない）
     900px  → 「現実とリン／クした世界／観」（mobileBrが切れて自動折返しに落ちる）
     1180px → 「現実とリンク／した世界観」
   対策は2つ。①仮名を .74em に落としてジャンプ率を付け、行の実幅を 6.44em まで縮める
   （2em＋6×.74em）。②改行を <br> で明示し、スマホ2行・PC3行に固定して自動折返しに
   委ねない。字の大小と改行位置は文の意味に属する組版であり、幅で偶然決まってはいけない。 */
.wvTitle .wvKana{font-size:.74em}

/* ══════ ロゴ：画面左上に固定（§20.4） ══════
   2026-08-12 第6次：アイコンを下部バーから外し、ここへ独立させた。役割は
   ナビではなくロゴの組みなので、§13.2で下部バーへナビを一本化した判断とは
   矛盾しない（これは上部ヘッダの部分復活ではなくロゴだけの復活）。
   ヒーローのキービジュアルに重なる前提のため、drop-shadowで可読性を確保する
   （背景がどんな明るさでも輪郭が沈まないよう2段のシャドウを重ねる）。 */
.siteLogo{position:fixed;top:var(--s3);left:var(--pad);z-index:85;
  display:flex;align-items:center;gap:var(--s2);
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.6)) drop-shadow(0 0 10px rgba(0,0,0,.35))}
.siteLogo .brandTile{flex:none;width:calc(var(--fs-h2) * 1.7);aspect-ratio:1;
  display:block;overflow:hidden;border-radius:8px;background:var(--surface);
  box-shadow:inset 0 0 0 1px var(--border)}
.siteLogo .brandTile img{width:100%;height:100%;object-fit:cover;display:block}
/* 項目9で他ページへのテキストリンクに下線を足したが、ロゴは「サイトを
   離れるリンク」ではなく識別マークなので同列に扱わない（2026-08-13修正）。
   下線は付けず、ホバー／タップの色だけボタンと同じ gold に揃える。 */
.siteLogoText{font-size:var(--fs-s);letter-spacing:var(--tr-label);color:var(--t1);
  transition:color .2s var(--e)}
.siteLogo:hover .siteLogoText,.siteLogo:active .siteLogoText{color:var(--gold)}
.siteLogo:focus-visible{outline:2px solid var(--gold);outline-offset:4px;border-radius:8px}
@media(max-width:640px){ .siteLogoText{display:none} }

/* ══════ 下部固定バー（§13.2・§20.4で角丸の浮いた板へ・今回さらにPLAY専用へ縮小） ══════
   ページ移動用のリンク（HOME/VERSUS/CO-OP/FEATURES/CONTACT）はここから外し、
   画面右上の .hamburgerBtn 経由の .navMenu へ移した（下のブロック参照）。
   下部バーはPLAYだけを収める細い浮き板になった。
   ファーストビューでは--barPの初期値0により完全に透明。スクロールに応じて
   site.jsが0〜1へ書き込み、不透明度が上がる。グラスモフィズムはblurに
   saturateを重ねて質感を強める（§2-⑤の例外＝固定ヘッダ相当のナビなので許容）。
   JSが失敗した場合やprefers-reduced-motionでは常時フル表示に倒す
   （縮退で情報が欠けないための保険。下の@mediaブロックを参照）。 */
/* ⚠️ 2026-08-17：PLAYボタンの背後にあった半透明の面（グラスモフィズム）を
   削除した（ユーザー指示）。ハンバーガーの囲みを外したときと同じ判断で、
   面を消して要素だけを残す。どんな地の上でもPLAYが見えるように、面の代わりに
   影で浮かせる（.hamburgerBtn と同じ作法）。 */
.bottomBar{position:fixed;right:var(--pad);bottom:var(--s3);z-index:80;
  display:flex;padding:0;
  border-radius:0;overflow:visible;
  opacity:var(--barP,0);
  transition:opacity .3s var(--e);
  background:transparent;box-shadow:none;
  -webkit-backdrop-filter:none;backdrop-filter:none;
  filter:drop-shadow(0 4px 14px rgba(0,0,0,.55))}
.bottomBar:hover,.bottomBar:focus-within{opacity:1}

/* ══════ ハンバーガーメニュー（今回新設） ══════
   ロゴの対角＝画面右上に固定する。押すとページ一覧（.navMenu）が開閉する。
   面はPLAYボタンを包む .bottomBar と全く同じグラスモフィズムの値
   （ground 62%のcolor-mix・inset罫・blur(20px) saturate(165%)）を使い、
   縮んだPLAY・ハンバーガー・開いた一覧の3面で質感を揃える（指示のとおり）。
   3本線→×へのモーフィングは html.menu-visible で切り替える。開閉の実処理
   （aria-expanded・Escape・フォーカストラップ・スクロールロック）はsite.jsが担う。 */
/* 囲みの丸四角は外す（ユーザー指示）。線だけを置き、どんな地の上でも
   見えるように影で浮かせる。 */
.hamburgerBtn{position:fixed;top:var(--s3);right:var(--pad);z-index:90;
  width:calc(var(--fs-h2) * 1.7);aspect-ratio:1;display:grid;place-items:center;
  border:0;border-radius:0;padding:0;cursor:pointer;
  background:transparent;box-shadow:none;
  -webkit-backdrop-filter:none;backdrop-filter:none;
  filter:drop-shadow(0 1px 3px rgba(0,0,0,.85))}
.hamburgerBtn:focus-visible{outline:2px solid var(--gold);outline-offset:4px}
.hamburgerBox{position:relative;width:1.1em;height:.78em;display:block;font-size:var(--fs-h3)}
/* ⚠️ 今回改訂：3本線→×のモーフィングを「線の回転・消失を滑らかにつなぐ」よう
   作り直した。以前は外側2本のtransform（.3s）と中央のopacity（.2s）が別の
   長さで動いており、終わるタイミングがずれて「バラバラに変化して見える」
   問題があった。3本とも同じduration/easing（.32s・var(--e)）に揃え、中央の
   線はopacityだけでなくtransform-origin:centerでscaleX(0)も同時に動かす
   ことで「中央の線が線分として縮んでから消える」→外側2本が同じ拍で回転して
   Xを形づくる、という1つの動きに見えるようにした。animationショートハンドは
   使わず個別プロパティのままなので、他の指定を潰す事故（厳守事項1）は起きない。 */
.hamburgerBox span{position:absolute;left:0;right:0;height:2px;margin:0;background:var(--t1);border-radius:1px;
  transform-origin:center;
  transition:transform .32s var(--e),opacity .32s var(--e),background-color .2s var(--e)}
.hamburgerBox span:nth-child(1){top:0}
.hamburgerBox span:nth-child(2){top:50%;margin-top:-1px}
.hamburgerBox span:nth-child(3){bottom:0}
.hamburgerBtn:hover .hamburgerBox span,.hamburgerBtn:focus-visible .hamburgerBox span{background:var(--gold)}
html.menu-visible .hamburgerBox span:nth-child(1){transform:translateY(.36em) rotate(45deg)}
html.menu-visible .hamburgerBox span:nth-child(2){opacity:0;transform:scaleX(0)}
html.menu-visible .hamburgerBox span:nth-child(3){transform:translateY(-.36em) rotate(-45deg)}
@media(max-width:480px){ .hamburgerBtn{width:calc(var(--fs-h3) * 2.1)} }

/* 背後の暗転スクリム。押すと閉じる。 */
.navScrim{position:fixed;inset:0;z-index:82;
  background:color-mix(in oklch, var(--ground) 78%, transparent);
  opacity:0;pointer-events:none;transition:opacity .4s var(--e)}
html.menu-open .navScrim{opacity:1;pointer-events:auto}

/* ページ一覧パネル。既定（JS未実行・閉時）は透明×クリック不能だが、
   .navMenu自身をdisplay:noneにはしない。.bottomBarと同じ理由（§13.2の
   フォールバック）で、キーボードでTabして中のリンクにフォーカスが入れば
   :focus-within が働いて可視化される（JSが完全に落ちても情報を欠かさない）。
   開く動き（§慣性）：.pageScale が縮み始めた少し後（site.jsのOPEN_DELAY）に
   html.menu-visible が付き、パネルは弾みのある拡大で現れる。閉じるときは
   逆順（パネルが先に縮み、その後に .pageScale が戻る）。 */
.navMenu{position:fixed;inset:0;z-index:84;display:flex;align-items:center;justify-content:center;
  padding:var(--pad);
  opacity:0;visibility:hidden;pointer-events:none;transform:scale(.96);
  transition:opacity .35s var(--e),transform .35s var(--e),visibility 0s linear .35s}
.navMenu:focus-within{opacity:1;visibility:visible;pointer-events:auto;transform:scale(1);
  transition:opacity .3s var(--e),transform .3s var(--e),visibility 0s linear 0s}
html.menu-visible .navMenu{opacity:1;visibility:visible;pointer-events:auto;transform:scale(1);
  transition:opacity .45s var(--e),transform .45s cubic-bezier(.34,1.56,.64,1),visibility 0s linear 0s}

/* ⚠️ 今回改訂：taotajima.jp（参照）のように各項目へ画像を付けたぶん、6項目を
   1画面に収めきる制約は外した（旧コメント「6項目が1画面に必ず収まる寸法に」
   は撤回）。.navMenuPanel の overflow-y:auto は元から持たせてあったが、
   今回はじめて実際にスクロールが働く前提の設計にする。 */
.navMenuPanel{width:min(92vw,26rem);max-height:calc(100svh - var(--pad) * 2);overflow-y:auto;
  overscroll-behavior:contain;
  border-radius:20px;padding:var(--s4) var(--s5);
  background:color-mix(in oklch, var(--ground) 62%, transparent);
  box-shadow:inset 0 0 0 1px var(--border), 0 24px 60px rgba(0,0,0,.5);
  -webkit-backdrop-filter:blur(20px) saturate(165%);backdrop-filter:blur(20px) saturate(165%)}

.navMenuList{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
/* 画像付きの行（今回追加）。左に画像、右にラベル。.navMenuPanel の
   overflow-y:auto が最も近いスクロールコンテナになるため、animation-timeline:
   view() は追加のコンテナ指定なしでこのスクロールに連動する。 */
.navMenuList a{display:flex;align-items:center;gap:var(--s3);padding:var(--s2) 0;
  font-size:clamp(var(--fs-b),3.2vw,var(--fs-h3));letter-spacing:var(--tr-label);
  color:var(--t2);border-bottom:1px solid var(--border);
  transition:color .2s var(--e)}
.navMenuList li:last-child a{border-bottom:0}
.navMenuList a:hover{color:var(--gold)}
.navMenuList a:active{color:var(--gold)}
.navMenuList a:focus-visible{color:var(--gold);outline:2px solid var(--gold);outline-offset:3px}
.navMenuList a[aria-current="page"]{color:var(--gold)}
.navMenuLabel{flex:1 1 auto}

/* 参照サイトはVERSUSなど各項目に写真を添えている。既存アセット（ゲーム内
   スクリーンショット・キービジュアル）を流用し、新しい画像は増やさない
   （表示サイズに対して過大にならないよう width/height はサムネイル用に
   縮小した固定寸法・object-fit:coverで切り出す）。 */
/* ⚠️ 枠は横長にすること。差し込む絵（assets/navicons/）は 480x360 の横長で、
   縦長の枠に cover で嵌めると構図の左右が切り落とされ、意味が読めなくなる
   （5つ並べたアイコンが3つしか見えない等）。 */
.navMenuImg{flex:none;width:clamp(5.2rem,19vw,6.8rem);aspect-ratio:4/3;
  object-fit:cover;border-radius:6px;
  box-shadow:inset 0 0 0 1px var(--border);
  transition:transform .25s var(--e)}
.navMenuList a:hover .navMenuImg,.navMenuList a:focus-visible .navMenuImg{transform:scale(1.06)}

/* ══════ スクロール上下端での変形・フェード（今回追加） ══════
   参照：taotajima.jp。画像・文字が端に近づくにつれて縮小しながら薄くなる。
   ライブラリなしで animation-timeline:view() だけで作る。.navMenuList の
   最も近いスクロール祖先は .navMenuPanel（overflow-y:auto）なので、追加の
   scroll-timeline名や祖先指定は不要（view()は自分自身の可視範囲を見る）。
   animation-range:cover 0%〜100% は「要素がスクロールポートに入り始めてから
   完全に出きるまで」の全区間を0〜100%に割り当てる。0%/100%（＝上下端で
   隠れかけ）を縮小・低opacityに、15%〜85%（＝ほぼ全体が見えている中間）を
   等倍・不透明にすることで、上下端でだけ変形させる。 */
@supports (animation-timeline: view()){
  .navMenuList li{
    animation-name:navItemEdge;animation-timing-function:linear;animation-fill-mode:both;
    animation-timeline:view();animation-range:cover 0% cover 100%}
}
@keyframes navItemEdge{
  0%{opacity:.12;transform:scale(.8)}
  15%{opacity:1;transform:scale(1)}
  85%{opacity:1;transform:scale(1)}
  100%{opacity:.12;transform:scale(.8)}
}
@media (prefers-reduced-motion: reduce){
  html:not([data-motion="on"]) .navMenuList li{
    animation:none!important;opacity:1!important;transform:none!important}
}

/* ══════ ページ本体の「奥へ縮む」演出（今回新設） ══════
   .pageScale はloadOverlay／siteLogo／hamburgerBtn／navScrim／navMenuの
   外側（=固定要素は含まない）で、実際にスクロールする本文だけを包む。
   固定要素を含めないため、この transform は position:fixed の要素の
   containing block を書き換えない（安全条件）。.fvIntro（sticky）は
   .pageScale の内側にあるが、sticky の基準は最も近い「スクロールコンテナ」
   （overflow が visible でない祖先）であって transform では変わらないため、
   ここに overflow:hidden を足さない限り §23.10 で見つかった sticky の
   挙動には影響しない（意図して overflow:hidden を持たせていない）。 */
.pageScale{transition:transform .5s var(--e);transform-origin:center top}
html.menu-open .pageScale{transform:scale(.94)}
html.menu-open{overflow:hidden}

@media (prefers-reduced-motion: reduce){
  html:not([data-motion="on"]) .pageScale{transition:none!important;transform:none!important}
  html:not([data-motion="on"]) .navMenu,
  html:not([data-motion="on"]) .navMenu:focus-within{transition:none!important}
  html:not([data-motion="on"]) .navScrim{transition:none!important}
  html:not([data-motion="on"]) .hamburgerBox span{transition:none!important}
}

/* ══════ PLAYボタン（項目9） ══════
   四角で囲まれたボタンに、ユーザー指定の斜め塗りホバーを実装する。
   指定コードはborder-trickで疑似要素の高さを60px固定にしていたため、
   ボタンの高さが変わると破綻する（⚠️指示の警告どおり）。ここでは
   clip-path:polygon() を使い、疑似要素自身のサイズを親と同じ inset:0 に
   したうえで多角形の頂点だけを rest（幅0の帯）→hover（右端だけ1.2em
   斜めに欠けた台形）へ transition する。頂点座標はすべて%か em なので、
   ボタンの高さ・幅が変わっても破綻しない（相対値で組む）。
   色はこのサイトのトークンへ読み替えた：#333 は使わず、塗りは gold
   （第2アクセント。地に対して9.41のAAAコントラストがあり、文字色にも使える
   §10.3.5）、地の文字は白（アイコンで既にaccent赤を敷いているため、赤の
   上に赤を重ねても変化が見えない。ゆえに赤の上に金を重ねる）。ホバー中の
   文字色は暗い --ground に替える（gold地に白文字はコントラストが取れない
   ため）。
   ⚠️ 既存の金色2段階ホバー（--gold。§20.5）との整理：四角ボタン自体には
   元々2段階ホバーが無く（filter:brightness(1.08)のみ）、今回はそれを
   斜め塗りに置き換えた。四角で「囲まれていない」テキストリンク側
   （.navMenuList a・.crumb a・.siteLogoText・.cardMoreLink）は逆に、既存の
   金色ホバーの仕組みをそのまま残し、下線を新設しただけである。理由は、
   ボタンの塗り色を gold に決めた以上、テキストリンクのホバー色も同じ
   gold に揃えるのが「その色はボタンと同じ色にする」という指示に最も
   素直に合致し、かつ既存の gold システムを壊さずに済むため。2段階
   （ホバー＝中間色／押下＝純gold）だった箇所は単一のgoldへ単純化した
   （押下時だけ変わる意味が、下線という新しい常時シグナルの追加で薄れた
   ため）。
   PLAYボタンは元々 ::before/::after を「RGB分解グリッチ」に使っていたため
   （PC限定の既存演出）、斜め塗り用の ::before と衝突する。グリッチ側を
   内側の .barPlayText 要素へ移し、.barPlay 自身の ::before を新設した
   斜め塗りに空ける。 ══════ */
.barPlay{position:relative;isolation:isolate;overflow:hidden;flex:none;display:flex;align-items:center;
  padding:var(--s2) var(--s4);background:var(--accent);color:#fff;
  font-weight:700;font-size:var(--fs-s);
  transition:color .2s var(--e)}
.barPlay::before{content:'';position:absolute;inset:0;z-index:-1;background:var(--gold);
  clip-path:polygon(0 0,0 0,0 100%,0 100%);transition:clip-path .32s var(--e)}
.barPlay:hover::before,.barPlay:focus-visible::before,.barPlay:active::before{
  clip-path:polygon(0 0,100% 0,calc(100% - 1.2em) 100%,0 100%)}
.barPlay:hover,.barPlay:focus-visible,.barPlay:active{color:var(--ground)}
.barPlay:focus-visible{outline:2px solid var(--t1);outline-offset:-4px}

.barPlayText{position:relative;display:inline-block}

/* ══════ PLAYボタンのグリッチ（既存。00i ファーストビュー作り直しに合わせて
   追加したもの）。カーソルを乗せた一瞬だけ、文字がRGB分解したようにブレる。
   2026-08-13：斜め塗りホバー新設にともない、.barPlay 自身の ::before/::after
   から内側の .barPlayText::before/::after へ移設した（マークアップ側は
   <span class="barPlayText">PLAY</span> に更新済み）。CSSのみ・JS不要。
   PC限定（hover:hover and pointer:fine）。 ══════ */
@media (hover:hover) and (pointer:fine){
  .barPlayText::before,.barPlayText::after{
    content:'PLAY';position:absolute;inset:0;
    display:flex;align-items:center;justify-content:center;
    font-weight:700;font-size:var(--fs-s);letter-spacing:inherit;
    opacity:0;pointer-events:none;mix-blend-mode:screen}
  /* 新色は増やさない。--accent（赤）と、site.css .why の --ink-color と
     同じ都市青（#388bfd）をそのまま使う。 */
  .barPlayText::before{color:var(--accent)}
  .barPlayText::after{color:#388bfd}
  .barPlay:hover .barPlayText::before{animation:fvPlayGlitchR .32s steps(2,jump-none) 1}
  .barPlay:hover .barPlayText::after{animation:fvPlayGlitchB .32s steps(2,jump-none) 1}
  @keyframes fvPlayGlitchR{
    0%{opacity:0;transform:translate(0,0)}
    12%{opacity:.85;transform:translate(-3px,1px)}
    32%{opacity:0;transform:translate(2px,-1px)}
    58%{opacity:.7;transform:translate(-2px,0)}
    80%{opacity:0;transform:translate(1px,1px)}
    100%{opacity:0;transform:translate(0,0)}
  }
  @keyframes fvPlayGlitchB{
    0%{opacity:0;transform:translate(0,0)}
    14%{opacity:.75;transform:translate(3px,-1px)}
    34%{opacity:0;transform:translate(-2px,1px)}
    60%{opacity:.6;transform:translate(2px,0)}
    82%{opacity:0;transform:translate(-1px,-1px)}
    100%{opacity:0;transform:translate(0,0)}
  }
}
@media (prefers-reduced-motion: reduce){
  /* *{animation:none!important} は疑似要素には及ばないため個別に無効化する。 */
  html:not([data-motion="on"]) .barPlayText::before,
  html:not([data-motion="on"]) .barPlayText::after{animation:none!important;opacity:0!important}
}

.foot{padding:var(--s5) 0 var(--s6);font-size:var(--fs-xs);color:var(--t3);
  letter-spacing:.04em;border-top:1px solid var(--border)}

/* ══════ サブページ共通の骨格（/modes/*。§13〜§15） ══════ */

/* パンくず（§13.3）。サブページの左上に置く。HOME / MODES / VERSUS の形。
   padding-topは--s5→--s6へ（2026-08-12・§20.4）。左上固定の.siteLogoと
   同じ左端（--pad）から始まるため、--s5のままだとロゴの真下に重なる。
   ロゴの実測高さ（--fs-h2 * 1.7 ≒ 3rem前後）と上オフセット（--s3）を
   足した分より確実に大きい--s6を取り、常に逃げ切る余白にする。 */
.crumb{padding-top:var(--s6);font-size:var(--fs-xs);letter-spacing:var(--tr-label);color:var(--t3)}
/* 項目9：下線を常設し、ホバー／タップの色をボタンと同じgoldに揃える
   （整理の判断は .barPlay の「斜め塗りホバー」コメント参照）。 */
.crumb a{color:var(--t2);text-decoration:underline;text-underline-offset:.2em;
  transition:color .2s var(--e)}
.crumb a:hover,.crumb a:active{color:var(--gold)}
.crumb a:focus-visible{color:var(--gold);outline:2px solid var(--gold);outline-offset:3px}
.crumb span{color:var(--t3);margin:0 var(--s1)}
.crumb b{color:var(--t1);font-weight:600}

/* 1. モード名＋人数・所要時間 */
.modeHead{padding-top:var(--s6)}
.modeName{font-size:clamp(var(--fs-d1),9vw,var(--fs-d3))}
.modeMeta{margin-top:var(--s3);font-size:var(--fs-s);letter-spacing:var(--tr-label);color:var(--gold)}

/* 2. 実機画面を大きく */
.modeShot{padding-top:var(--s7)}
.modeShotWrap{max-width:clamp(240px,30vw,340px);margin:0 auto;border-radius:16px;
  aspect-ratio:1080/2340;background:var(--surface);box-shadow:inset 0 0 0 1px var(--border)}
.modeShotWrap img{width:100%;display:block}

/* 3. 1ターンの流れ（フェーズ図） */
.flowSec{padding-top:var(--s7)}
.flowRow{margin-top:var(--s5);display:flex;flex-wrap:wrap;align-items:stretch;gap:var(--s3)}
.flowStep{flex:1 1 clamp(160px,22%,220px);display:flex;flex-direction:column;gap:var(--s1);
  padding:var(--s3);background:var(--surface);box-shadow:inset 0 0 0 1px var(--border);border-radius:4px}
.flowStep b{font-size:var(--fs-h3);color:var(--t1);line-height:var(--lh-h)}
.flowStep span{font-size:var(--fs-s);color:var(--t2);line-height:var(--lh-b)}

/* 縦のタイムライン（2026-08-23）。旧 .flowRow はPCで4段が横に潰れて読みにくく、
   VERSUS・CO-OP の両方で置き換えた。.flowRow/.flowStep は他で使っていないが、
   参照が残っていないか確認したうえで消すこと（今回は残置）。 */
/* ══════ 1ターンの流れ：縦のタイムライン（2026-08-23 作り直し） ══════
   旧・横並び（.flowRow）はPCで4段が横に潰れて読みにくかった。丸囲みの番号を
   縦線でつなぎ、右に英字ラベル・見出し・説明を置く。 */
.flowList{margin-top:var(--s5);list-style:none;padding:0;max-width:44em}
.flowItem{--flowDot:2.5rem;position:relative;display:grid;
  grid-template-columns:var(--flowDot) 1fr;column-gap:var(--s3);padding-bottom:var(--s4)}
.flowItem:last-child{padding-bottom:0}
/* 縦線は丸の中心から次の丸へ。最後の項目には引かない。 */
.flowItem::before{content:'';position:absolute;left:calc(var(--flowDot) / 2);
  top:var(--flowDot);bottom:0;width:1px;background:var(--border);transform:translateX(-50%)}
.flowItem:last-child::before{display:none}
.flowNum{width:var(--flowDot);height:var(--flowDot);display:grid;place-items:center;
  border-radius:50%;box-shadow:inset 0 0 0 1px var(--accent);color:var(--accent);
  background:var(--ground);font-size:var(--fs-s);letter-spacing:0}
.flowLabel{display:block;font-size:var(--fs-xs);letter-spacing:var(--tr-label);color:var(--gold)}
.flowName{display:block;margin-top:var(--s1);font-size:var(--fs-h3);line-height:var(--lh-h)}
.flowText{display:block;margin-top:var(--s1);font-size:var(--fs-s);
  color:var(--t2);line-height:var(--lh-b)}

/* 行ごとの出現（2026-08-23）。⚠️ .reveal は <ol> ではなく各 <li> に付ける。
   まとめて1つにすると4行が同時に出て「順に流れる」感じが出ない。
   行そのものの出現は既存の .reveal に任せ、ここでは丸囲み番号と縦線だけを足す。 */
@supports (animation-timeline: view()){
  /* 番号は行より少し遅れて拡大しながら入る（行→番号の順に視線が動く）。 */
  .flowNum{animation:flowNumIn linear both;animation-timeline:view();
    animation-range:entry 36% entry 76%;animation-timing-function:var(--e)}
  /* 縦線は上から下へ伸びて次の番号へつながる。
     ⚠️ 既定の transform:translateX(-50%) を消さないよう、キーフレーム側でも
     translateX を書く。origin を top にしないと中央から両側へ伸びる。 */
  .flowItem::before{transform-origin:top center;
    animation:flowLineGrow linear both;animation-timeline:view();
    animation-range:entry 44% entry 96%}
}
@keyframes flowNumIn{ from{opacity:0;transform:scale(.4)} to{opacity:1;transform:scale(1)} }
@keyframes flowLineGrow{ from{transform:translateX(-50%) scaleY(0)}
                         to{transform:translateX(-50%) scaleY(1)} }
@media (prefers-reduced-motion: reduce){
  html:not([data-motion="on"]) .flowNum,
  html:not([data-motion="on"]) .flowItem::before{animation:none!important;opacity:1}
  html:not([data-motion="on"]) .flowItem::before{transform:translateX(-50%)}
}

.flowStep i{font-style:normal;font-size:var(--fs-xs);letter-spacing:var(--tr-label);color:var(--gold)}
.flowArrow{align-self:center;flex:none;font-size:var(--fs-h3);color:var(--t3)}
@media(max-width:640px){ .flowArrow{display:none} }

/* 4. 何を決めるゲームか／本文パネル共通 */
.modeSec{padding-top:var(--s7)}
.modeSecTitle{font-size:clamp(var(--fs-h1),5vw,var(--fs-d1))}
.modeBody{margin-top:var(--s4);max-width:36em;color:var(--t2);line-height:var(--lh-b)}
.modeBody p + p{margin-top:var(--s3)}

/* 5. リスク方程式（ハザード×曝露×脆弱性） */
.eq{margin-top:var(--s5);display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--s2);
  font-size:clamp(var(--fs-h3),3vw,var(--fs-h1))}
.eq b{color:var(--t1)}
.eq i{font-style:normal;color:var(--t3);font-size:.7em;padding:0 var(--s1)}

.pairGrid{margin-top:var(--s5);display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s3)}
@media(max-width:899px){ .pairGrid{grid-template-columns:1fr;gap:var(--s3)} }
.pairCard{--c:var(--gold);padding:var(--s4) var(--s3);background:var(--surface);
  box-shadow:inset 0 0 0 1px var(--border),inset 3px 0 0 var(--c);border-radius:4px}
/* 3枚の色はベン図の円と揃える（2026-08-23）。 */
.pairCard--haz{--c:#f85149}
.pairCard--exp{--c:#388bfd}
.pairCard--vul{--c:#3fb950}
.pairCard b{display:block;font-size:var(--fs-xs);letter-spacing:var(--tr-label);color:var(--c)}
/* 各項目で扱うカードの代表を3枚並べる。 */
.pairCards{margin-top:var(--s3);display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s1)}
.pairCards img{width:100%;height:auto;border-radius:4px;
  box-shadow:0 8px 18px rgba(0,0,0,.5),0 0 0 1px rgba(255,255,255,.06)}
.pairCard h3{margin-top:var(--s2);font-size:var(--fs-h2);color:var(--t1);line-height:var(--lh-h)}
.pairCard p{margin-top:var(--s2);font-size:var(--fs-s);color:var(--t2);line-height:var(--lh-b)}

.insight{margin-top:var(--s6);max-width:40em}
.insight h3{font-size:var(--fs-h2);color:var(--t1);line-height:var(--lh-h)}
.insight p{margin-top:var(--s3);font-size:var(--fs-b);color:var(--t2);line-height:var(--lh-b)}
.insight p + p{margin-top:var(--s3)}

/* 6. 設定でできること → PLAY */
.settingsList{margin-top:var(--s4);display:grid;gap:var(--s2)}
.settingsItem{display:flex;flex-wrap:wrap;gap:var(--s1) var(--s3);padding:var(--s3) 0;
  border-top:1px solid var(--border);font-size:var(--fs-s);line-height:var(--lh-b)}
.settingsItem dt{flex:0 0 auto;min-width:9em;color:var(--gold);font-weight:700;letter-spacing:var(--tr-jp)}
.settingsItem dd{flex:1 1 20em;margin:0;color:var(--t2)}

/* 斜め塗りホバー（項目9。.barPlay と同じ仕組み。詳しい設計判断はそちらの
   コメント参照）。 */
.btnFill{position:relative;isolation:isolate;display:inline-flex;align-items:center;margin-top:var(--s5);
  padding:var(--s3) var(--s6);background:var(--accent);color:#fff;font-weight:700;
  font-size:var(--fs-h3);letter-spacing:var(--tr-label);
  /* 角の斜め欠けは外した（ユーザー指示。指定コードに無い要素だった）。 */
  transition:color .2s var(--e),transform .2s var(--e)}
.btnFill::before{content:'';position:absolute;inset:0;z-index:-1;background:var(--gold);
  clip-path:polygon(0 0,0 0,0 100%,0 100%);transition:clip-path .32s var(--e)}
.btnFill:hover::before,.btnFill:focus-visible::before,.btnFill:active::before{
  clip-path:polygon(0 0,100% 0,calc(100% - 1.2em) 100%,0 100%)}
.btnFill:hover,.btnFill:focus-visible,.btnFill:active{color:var(--ground)}
@media(hover:hover){ .btnFill:hover{transform:translateY(-2px)} }
.btnFill:focus-visible{outline:2px solid var(--t1);outline-offset:3px}

@media (prefers-reduced-motion: reduce){
  html:not([data-motion="on"]) *{animation:none !important;transition:none !important}
  html:not([data-motion="on"]) .reveal{opacity:1 !important;transform:none !important}
  html:not([data-motion="on"]) .headRule{transform:scaleX(1) !important}
  html:not([data-motion="on"]) .maskReveal > img{ transform:none !important }
  html:not([data-motion="on"]) .loadOverlay{display:none !important}
  html:not([data-motion="on"]).intro-lock{overflow:visible !important}
  html:not([data-motion="on"]) .bottomBar{opacity:1 !important}}

/* ══════ 画面遷移：View Transitions（§20.2） ══════
   6ページ（LP・modes/versus・modes/co-op・features・cards・contact）が
   共通で読み込む本ファイルに1回書くだけで全ページに効く。JSは使わない。
   非対応ブラウザでは @view-transition が丸ごと無視され、通常のページ遷移に
   そのまま落ちる（未知の @規則はパース時に無害に読み飛ばされる仕様のため、
   コンソールエラーにもならない）。
   既定のクロスフェードは新旧スナップショットの背景が食い違う一瞬に白が
   挟まりやすいため、::view-transition-image-pair(root) の背景を地の色
   （--ground）で明示的に固定し、スライドやスケールを使わない単純な
   不透明度クロスフェードだけに絞る（地の色を保ったまま重なる。§20.2）。 */
@view-transition{ navigation:auto }

::view-transition-group(root){ animation-duration:.42s; animation-timing-function:var(--e) }
::view-transition-image-pair(root){ background-color:var(--ground) }
::view-transition-old(root),
::view-transition-new(root){
  animation-duration:.42s;animation-timing-function:linear;
  mix-blend-mode:normal;height:100%}
::view-transition-old(root){ animation-name:ronFadeOut }
::view-transition-new(root){ animation-name:ronFadeIn }
@keyframes ronFadeOut{ from{opacity:1} to{opacity:0} }
@keyframes ronFadeIn{ from{opacity:0} to{opacity:1} }

@media (prefers-reduced-motion: reduce){
  ::view-transition-group(root),
  ::view-transition-old(root),
  ::view-transition-new(root){ animation:none !important }
}

/* 検証用：ローディング演出の一時停止（?introfreeze=1）。本番の挙動には影響しない。 */
html[data-introfreeze] .loadOverlay,
html[data-introfreeze] .loadOverlay *{ animation-play-state:paused !important }
html[data-introfreeze] .loadOverlay{ display:flex !important }
html[data-introfreeze] .loadInk{ display:block !important }

/* ══════════════════════════════════════════════════════════════════════
   インク背景・下層ページ共通（2026-08-23 新設。§18／§19）

   これまでインク層は v5-proto.html のページ内 <style> にしか無く、下層5ページは
   地のベタ塗りだけだった。HOMEと背景を揃えるため、ここへ切り出す。

   ⚠️ **v5-proto.html のページ内CSSは触っていない。**あちらは <link> より後に
      書かれているので同名ルールは後勝ちし、HOMEの見た目は一切変わらない。
   ⚠️ **url() の基準はこのファイル（assets/site.css）自身になる。**
      'assets/ink/…' ではなく 'ink/…' と書くこと。前者だと assets/assets/ink/…
      を見に行って全ページでインクが消える。modes/ 配下が1階層深い問題も、
      CSS側で解決するのでページ相対パスの差は出ない。
   ══════════════════════════════════════════════════════════════════════ */

/* 下層ページは <div class="wrap"> の内側に節が並ぶ構造で、HOMEのように節が
   画面幅いっぱいではない。そのままインクを敷くと 1280px で切れて左右に
   地のベタ塗りが残るため、この修飾子で画面幅まで広げる。
   ⚠️ HOMEは .inkLayer（inset:0）だけを使い、この修飾子は使わない。 */
.inkLayer--bleed{position:absolute;top:0;bottom:0;left:50%;width:100vw;
  transform:translateX(-50%);z-index:0;overflow:hidden;pointer-events:none}

/* インク本体。既定は静止1段階・低い不透明度で、mask 非対応でもここで完結する
   （HOMEの .inkStage と同じ設計。background-blend-mode:multiply で
   輝度×色を合成し、黒は地に溶けて消える）。 */
.inkStage{position:absolute;inset:0;
  --ink-peak:.30;--ink-peak-far:.18;
  --ink-url:url('ink/ink_2.webp');
  background-image:var(--ink-url);
  background-color:var(--ink-color,transparent);
  background-blend-mode:multiply;
  background-repeat:no-repeat;background-position:center;background-size:contain;
  opacity:var(--ink-peak);filter:blur(1px);transform:scale(1.05);
  transition:background-color .3s linear}

/* 節の意味色。site.css に既にある色だけを使い、新しい値は足していない
   （#f85149 #388bfd #3fb950 #a371f7 はいずれも既出）。
   上限は「補助文字 --t2 が地に対して4.5:1 を保てる最大値の85%」で、
   HOMEの .why/.marq/.ways と同じ根拠・同じ数値である。 */
.ink-red{--ink-color:#f85149}      .ink-red .inkStage{--ink-peak:.45;--ink-peak-far:.27}
.ink-blue{--ink-color:#388bfd}     .ink-blue .inkStage{--ink-peak:.37;--ink-peak-far:.22}
.ink-green{--ink-color:#3fb950}    .ink-green .inkStage{--ink-peak:.32;--ink-peak-far:.19}
.ink-purple{--ink-color:#a371f7}   .ink-purple .inkStage{--ink-peak:.39;--ink-peak-far:.23}
.ink-gold{--ink-color:#e3b341}     .ink-gold .inkStage{--ink-peak:.29;--ink-peak-far:.17}

/* mask 対応ブラウザでは輝度マスクへ切り替える（multiply版より発色が純粋になる）。 */
@supports ((mask-image: linear-gradient(#000,#000)) or (-webkit-mask-image: linear-gradient(#000,#000))){
  .inkStage{
    background-image:none;background-blend-mode:normal;
    background-color:var(--ink-color,transparent);
    -webkit-mask-image:var(--ink-url);mask-image:var(--ink-url);
    -webkit-mask-source-type:luminance;-webkit-mask-mode:luminance;mask-mode:luminance;
    -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
    -webkit-mask-position:center;mask-position:center;
    -webkit-mask-size:contain;mask-size:contain;
  }
}

/* スクロールに応じて ink_1〜ink_5 を切り替えつつ拡大・ぼかし・不透明度で奥行きを作る。
   near は節の入場中に一気に広がり（速い＝手前）、far は節が画面を通過し終える
   まで遅れて広がる（遅い＝奥）。HOMEと同じ2枚重ねの視差である。
   ⚠️ HOMEは同名の @keyframes をページ内で再定義するため、HOME上ではあちらが勝つ。 */
@supports (animation-timeline: view()){
  @keyframes inkNear{
    0%   { --ink-url:url('ink/ink_1.webp'); opacity:calc(var(--ink-peak) * .36); filter:blur(0px); transform:scale(1) }
    30%  { --ink-url:url('ink/ink_2.webp'); opacity:var(--ink-peak);             filter:blur(1px); transform:scale(1.04) }
    60%  { --ink-url:url('ink/ink_3.webp'); opacity:calc(var(--ink-peak) * .82); filter:blur(2px); transform:scale(1.10) }
    100% { --ink-url:url('ink/ink_4.webp'); opacity:calc(var(--ink-peak) * .55); filter:blur(3px); transform:scale(1.18) }
  }
  @keyframes inkFar{
    0%   { --ink-url:url('ink/ink_2.webp'); opacity:calc(var(--ink-peak-far) * .40); filter:blur(2px); transform:scale(1.1) }
    50%  { --ink-url:url('ink/ink_3.webp'); opacity:var(--ink-peak-far);             filter:blur(3px); transform:scale(1.14) }
    100% { --ink-url:url('ink/ink_5.webp'); opacity:calc(var(--ink-peak-far) * .60); filter:blur(4px); transform:scale(1.26) }
  }
  .inkStage.near{animation:inkNear linear both;animation-timeline:view();
    animation-range:entry 0% entry 100%}
  .inkStage.far{animation:inkFar linear both;animation-timeline:view();
    animation-range:entry 0% exit 100%}
}

/* 縮退（§5.3）：拡散もぼかしも動かさず静止1段階のみ。情報はインクの色だけなので
   静止しても何も欠けない。 */
@media (prefers-reduced-motion: reduce){
  html:not([data-motion="on"]) .inkStage{
    animation:none !important;--ink-url:url('ink/ink_2.webp') !important;
    opacity:.12 !important;filter:none !important;transform:none !important}
}


/* ══════════════════════════════════════════════════════════════════════
   3円の図：災害リスク＝ハザード×曝露×脆弱性（2026-08-23 第2版）

   受領したスライド画像の構図に合わせて作り直した。第1版は円が小さく題も
   図の外にあり、別物になっていた。第2版で合わせたのは次の4点。
     ・題「災害リスク」を明朝で左上に大きく置く
     ・題から中心の重なりへ**引出線**を引き、先端に点を打つ
     ・ラベル（ハザード／曝露／脆弱性）を大きく、低コントラストの白で円に重ねる
     ・カードを各円の**上寄り**に置き、円の縁をまたがせる
   色だけはサイトのカード色（#f85149／#388bfd／#3fb950）にした。同じページの
   HAZARD／EXPOSURE／VULNERABILITY の3枚、CARDSページの色分けと揃えるため
   （2026-08-23 ユーザー判断）。

   ⚠️ stage は正方形にする。長方形にすると width:% で決めた円の高さが縦横比の
      ぶん膨らみ、画面いっぱいの巨大な円になる（第1版で実際にそうなった）。
   ⚠️ 寸法は cqw（stage の幅）で取る。vw だと本文の段組み幅と無関係に効いて、
      画面幅を変えたときだけ図の中身が崩れる。
   ══════════════════════════════════════════════════════════════════════ */
.venn{margin:var(--s5) 0 0;position:relative;z-index:1}
/* ⚠️ 円・引出線・中心の重なりは SVG で描く。3円の共通部分は clipPath を
   入れ子にして正確に切り出す（div の重ね合わせでは出せない形である）。
   座標は正本の実測値：曝露(1081,1223) 脆弱性(1692,1223) ハザード(1386.5,630)、
   いずれも半径528。viewBox は正本と同じ 2231×1762。 */
.vennStage{container-type:inline-size;position:relative;
  width:100%;max-width:44rem;margin-inline:auto;aspect-ratio:2231/1762}
.vennArt{position:absolute;inset:0;width:100%;height:100%;z-index:1;overflow:visible}
.vArc{stroke-width:5}
.vArc--haz{stroke:#f85149;fill:rgba(248,81,73,.10)}
.vArc--exp{stroke:#388bfd;fill:rgba(56,139,253,.10)}
.vArc--vul{stroke:#3fb950;fill:rgba(63,185,80,.10)}
/* 3円の共通部分。⚠️ 正本は白地なので「暗い灰」で沈めているが、こちらは
   暗い地なので同じことをすると消える。逆に**明るい中間色**で持ち上げる。 */
/* ⚠️ 中心の塗りは3円が出そろってから。題と引出線はさらにその後。
   （2026-08-23 ユーザー指示。順番＝円→円→円→カード→中心→題→線→点） */
.vCore{fill:rgba(233,239,247,.26);stroke:none;opacity:0}
.vLead{stroke:rgba(255,255,255,.72);stroke-width:4;stroke-linecap:round;fill:none}
.vDot{fill:rgba(255,255,255,.95)}

/* 題は黒帯に白抜き（正本どおり）。 */
/* ⚠️ 円の群れを画面中央に置くため、正本の座標から左へ 12.1%（viewBox 270）
   ずらしてある。題と引出線もその分だけ動かした（2026-08-23 ユーザー指示）。
   題は小さくして、赤い円の左肩に掛からない位置に置く。 */
.vennTitle{position:absolute;left:1.5%;top:4%;z-index:5;opacity:0;
  display:inline-block;padding:.10em .34em;background:#000;color:#fff;
  font-size:5.4cqw;line-height:1.22;white-space:nowrap}
/* ラベルは円と同じ色。正本では円の下寄りに置かれている。 */
.vennLabel{position:absolute;z-index:2;white-space:nowrap;
  font-size:6.6cqw;line-height:1;letter-spacing:0}
/* ⚠️ ハザードは下2枚のカード（新潟 32.4〜47.4%／耐震補強 75.3〜90.3%）の
   あいだ、かつカード上端(45.4%)より上に置く。ここを外すと札に文字が乗る。 */
.vennLabel--haz{left:36.1%;top:35.5%;color:rgba(248,81,73,.82)}
.vennLabel--exp{left:28.9%;top:81.0%;color:rgba(56,139,253,.82)}
.vennLabel--vul{left:52.9%;top:81.0%;color:rgba(63,185,80,.82)}
.vennCard{position:absolute;z-index:4;width:15%;height:auto;border-radius:6px;
  box-shadow:0 14px 34px rgba(0,0,0,.6),0 0 0 1px rgba(255,255,255,.08)}
.vennCard--haz{left:42.4%;top:0.3%}
.vennCard--exp{left:20.3%;top:45.4%}
.vennCard--vul{left:63.2%;top:45.4%}
/* 役割の注記。CO-OP だけ出す（自然側＝ハザード／都市側＝曝露と脆弱性）。 */
.vennRole{position:absolute;z-index:5;display:none;align-items:center;gap:.4em;
  font-size:clamp(.7rem,2.6cqw,1.1rem);letter-spacing:var(--tr-label);
  color:rgba(255,255,255,.82)}
.vennRole::before{content:'';width:.7em;height:.7em;border-radius:50%;background:var(--roleC)}
.venn--roles .vennRole{display:inline-flex}
.vennRole--nature{left:64%;top:2%;  --roleC:#f85149}
.vennRole--city{left:22%;top:95%;   --roleC:#388bfd}
.vennCap{margin-top:var(--s3);text-align:center;
  font-size:var(--fs-s);color:var(--t3);line-height:var(--lh-b)}

/* 進行：円→円→円→カード→引出線。⚠️ scroll-driven では animation-delay が
   効かないので、順番は animation-range でずらす。 */
.vArc,.vennCard{opacity:0}
/* ⚠️ SVG の拡大は transform-box:fill-box を付けないと、viewBox の原点を
   基準に飛んでいく。 */
.vArc{transform:scale(.5);transform-box:fill-box;transform-origin:center}
.vennCard{transform:translateY(-1.6em)}
.vLead{stroke-dasharray:880;stroke-dashoffset:880}
.vDot{opacity:0}
@keyframes vennPop{ from{opacity:0;transform:scale(.5)} to{opacity:1;transform:scale(1)} }
@keyframes vennDrop{ from{opacity:0;transform:translateY(-1.6em)} to{opacity:1;transform:translateY(0)} }
/* ⚠️ 線を伸ばしたら dasharray も引き直すこと。短いと線が途中までしか出ない。
   現在の線長は約864（(700,258)→(1110,1018)）。 */
@keyframes vennDraw{ from{stroke-dashoffset:880} to{stroke-dashoffset:0} }
@keyframes vennDot{ from{opacity:0} to{opacity:1} }
@supports (animation-timeline: view()){
  .vArc,.vennCard,.vCore,.vennTitle,.vLead,.vDot{
    animation-timeline:view();animation-fill-mode:both;animation-timing-function:var(--e)}
  /* 3円とカードが出そろってから中心が塗られ、その後に題→線→点と続く。 */
  .vCore{animation-name:vennDot;animation-range:entry 76% entry 86%}
  .vennTitle{animation-name:vennDot;animation-range:entry 86% entry 94%}
  .vArc{animation-name:vennPop}
  .vennCard{animation-name:vennDrop}
  .vLead{animation-name:vennDraw;animation-timing-function:linear}
  .vDot{animation-name:vennDot}
  .vArc--haz{animation-range:entry 26% entry 46%}
  .vArc--exp{animation-range:entry 32% entry 52%}
  .vArc--vul{animation-range:entry 38% entry 58%}
  .vennCard--haz{animation-range:entry 46% entry 62%}
  .vennCard--exp{animation-range:entry 52% entry 68%}
  .vennCard--vul{animation-range:entry 58% entry 74%}
  .vLead{animation-range:entry 88% entry 97%}
  .vDot{animation-range:entry 97% entry 100%}
}
/* scroll-driven 非対応：site.js が .reveal へ付ける .is-in で時間駆動に落とす。
   ⚠️ .is-in は scroll-driven 非対応のときだけ付く（site.js の supportsScrollTimeline）。 */
@supports not (animation-timeline: view()){
  .venn.is-in .vArc{animation:vennPop .8s var(--e) both}
  .venn.is-in .vArc--exp{animation-delay:.12s}
  .venn.is-in .vArc--vul{animation-delay:.24s}
  .venn.is-in .vennCard{animation:vennDrop .7s var(--e) both}
  .venn.is-in .vennCard--haz{animation-delay:.36s}
  .venn.is-in .vennCard--exp{animation-delay:.48s}
  .venn.is-in .vennCard--vul{animation-delay:.60s}
  .venn.is-in .vCore{animation:vennDot .5s linear .78s both}
  .venn.is-in .vennTitle{animation:vennDot .5s linear 1.08s both}
  .venn.is-in .vLead{animation:vennDraw .8s linear 1.3s both}
  .venn.is-in .vDot{animation:vennDot .3s linear 2.1s both}
}
@media (prefers-reduced-motion: reduce){
  html:not([data-motion="on"]) .vArc{animation:none!important;opacity:1;transform:none}
  html:not([data-motion="on"]) .vennCard{animation:none!important;opacity:1;transform:none}
  html:not([data-motion="on"]) .vLead{animation:none!important;stroke-dashoffset:0}
  html:not([data-motion="on"]) .vDot{animation:none!important;opacity:1}
  html:not([data-motion="on"]) .vCore,
  html:not([data-motion="on"]) .vennTitle{animation:none!important;opacity:1}
}


/* ══════ モードページのヒーロー：左＝面／右＝実機画面（2026-08-23） ══════
   HOMEの赤青パネルと同じ面を、VERSUS・CO-OP の冒頭へ持ってきた。
   面の色は --panelBg で切り替える（VERSUS 赤 #E60B00／CO-OP 紺 #002A6C）。
   ⚠️ ここはリンクにしない（すでに VERSUS を開いているため）。
   ⚠️ スマホでは実機画面を出さない（2026-08-23 ユーザー確定）。面のすぐ下に
      「1ターンの流れ」が続き、本題へ早く入る。 */
.modeHero{margin-top:var(--s4);display:grid;grid-template-columns:7fr 5fr;
  column-gap:var(--s4);align-items:center}
.modePanel{position:relative;overflow:hidden;padding:var(--s6) var(--s5);
  background:var(--panelBg,#E60B00);color:var(--t1)}
.modePanelInner{position:relative;z-index:1;max-width:26em}
.modeLabel{display:block;font-size:clamp(var(--fs-h1),5vw,var(--fs-d1));line-height:var(--lh-d)}
.modeLabel::after{content:'';display:block;width:clamp(3rem,26%,10rem);height:1px;
  background:#fff;opacity:.9;margin-top:var(--s2)}
.modeSub{display:block;margin-top:var(--s2);font-size:var(--fs-b);color:rgba(255,255,255,.86)}
.modeCount{margin-top:var(--s3);display:flex;flex-wrap:wrap;align-items:center;
  gap:var(--s2);color:rgba(255,255,255,.86)}
.modeCountGroup{display:inline-flex;align-items:center;gap:.28em}
.modeIcon{width:1.1em;height:1.1em;color:#fff}
.modeCountSep{color:rgba(255,255,255,.6)}
.modePanelBody{display:block;margin-top:var(--s3);font-size:var(--fs-s);
  color:rgba(255,255,255,.86);line-height:var(--lh-b)}
/* HOME の .wayNote と同じ添え書き。⚠️ 面の文章はHOMEと1字も変えない
   （2026-08-23 ユーザー指示）。棲み分けの説明は下の「何を決めるゲームか」に置く。 */
.modePanelNote{display:block;margin-top:var(--s2);font-size:var(--fs-s);
  color:rgba(255,255,255,.66);line-height:var(--lh-b)}
/* 縦組みの VERSUS。HOMEの .wayArtWord と同じ作法。
   ⚠️ 1語のまま writing-mode で流すと面の高さより長くなったとき端が欠ける。
      1文字ずつの子要素にして縦flexで space-between すれば必ず収まる。 */
/* HOME の .wayArtWord と同じ作法・同じ大きさに揃えた（2026-08-23）。
   ⚠️ 詳しい理由は v5-proto.html の .wayArtWord のコメントを見ること
      （space-between は負の余白を作れず、文字が溢れて切れる）。 */
/* HOME の .wayArtWord と**同じ値**にしてある（2026-08-23 ユーザー指示）。
   スマホ用の上書き（26vw＝390pxで90px・right の負値ではみ出す）まで含めて複製する。
   ⚠️ ここを HOME と食い違わせない。過去に小さくして「改悪」と指摘された。 */
.modeArtWord{position:absolute;top:var(--s4);bottom:var(--s4);right:var(--s4);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.04em;
  line-height:1;pointer-events:none;
  font-size:clamp(var(--fs-h1),9vw,calc(var(--fs-d3) * 1.3));
  color:transparent;-webkit-text-stroke:1px rgba(255,255,255,.5);opacity:.9}
.modeArtWord > span{display:block}
@supports not (-webkit-text-stroke: 1px #fff){ .modeArtWord{color:rgba(255,255,255,.14)} }
/* ⚠️ 実機画面は縦長（1080:2340）なので、幅で決めると面より背が高くなり、
   面が中央で浮いて見える。高さ側で決めて面の高さに近づける。 */
.modeHeroShot .modeShotWrap{max-width:none;width:auto;margin:0 auto;
  height:clamp(17rem,27vw,24rem)}
@media(max-width:899px){
  .modeHero{display:block;
    /* ⚠️ HOMEの赤青パネルは .wrap の外にあり画面幅いっぱいを覆う。下層の面は
       .wrap の内側にあるため、そのままだと左右に地が見えて別物になる。
       負のマージンで画面幅まで広げて揃える（2026-08-23 ユーザー指示）。 */
    margin-inline:calc(50% - 50vw)}
  .modeHeroShot{display:none}
  .modePanel{padding:var(--s6) var(--pad)}
  /* 縦組み英字もHOMEのスマホ指定と同じに。右端の外へ少しはみ出させる。 */
  .modeArtWord{right:calc(var(--pad) * -.35);opacity:.55;
    font-size:clamp(var(--fs-d2),26vw,var(--fs-d3))}
  .modePanelInner{max-width:none}
}
