/*
 * フィードのページの見た目（2026-09-17）
 *
 * 使うページ: /games/:tag（public/games-by-tag.html）と /games（public/games-index.html）。
 * どちらもサーバーの HTML は全員同じで、ブラウザで JS が動いたときだけ public/js/games-by-tag-feed.js が
 * フィードに組み替える（フィードの中身はタグに関係なく全ゲーム: founder「中身は全部ぶちこんでいるフィードでいい」）。
 * 以前は games-by-tag.html の <style> にあった規則をそのまま移した（2 枚に写さないため）。
 * 読み込みは各ページの本体の <style> の後（狭い画面のヘッダーの規則が本体の基本の値に勝つ順番）。
 */

/* ── 安全領域（ノッチ / ホームインジケータ）の変数（PR #907 レビュー B [重大4]・2026-09-20）──────
   /css/game-social.css は var(--safe-bottom, 0px) / var(--page-safe-top, var(--safe-top, 0px)) を
   参照しているが（コメントシートの送信ボタンとゲーム中の上のバー）、この殻には変数の定義が無かった。
   移行前の public/game.html は body で 0 を置き、html.native-app のときだけ env() に差し替えていた
   （game.html の body / html.native-app body）。`/game/<id>` がこの殻に移った時点で定義ごと落ちていて、
   iOS アプリの WebView ではコメントの送信ボタンがホームインジケータの下に潜る。

   CLAUDE.md「ネイティブ差分の書き方」に従い **ベース → native 上書き**の順で持つ:
     ルール 3「env(safe-area-inset-*) は Web でも非ゼロになりうる（iPhone Safari / PWA）。
     値で分けるのではなくセレクタで分ける」—— なので Web は常に 0px。
   WHY `:root` ではなく game-feed-page.css に置くのか（殻のインライン <style> ではなく）:
     殻は 2 枚（games-index.html / games-by-tag.html）あり、写しを作らないため。
     公開ゲームの反応 UI の CSS（game-social.css）は C2 担当で衝突するので触らない。
   --page-safe-* も定義するのは、game-social.css:1104 がそちら経由で読むため（game.html と同じ 2 段）。
   MOBILE-ONLY: html.native-app の印は各殻の <head> の同期スクリプトが付ける。
   cover が無いと iOS の env() は 0 を返すので、同じスクリプトが viewport-fit=cover も足す。 */
:root {
  --safe-top: 0px;
  --safe-bottom: 0px;
  --page-safe-top: var(--safe-top);
  --page-safe-bottom: var(--safe-bottom);
}
html.native-app {
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

/* 狭い画面のヘッダーを 1 行に。リンクは折らない（本体の基本の規則に無いページがあるのでここで持つ） */
.header-nav a { white-space: nowrap; }

/* ── フィード化と 2 つの見え方（2026-09-17・計画書 .claude/plans/tag-feed-entry.md §3）──────────────
   サーバーの HTML は全員同じ（見出し・説明・カード・JSON-LD・ページ送り）。ブラウザで JS が動いたときだけ、
   <main> の先頭にフィード（public/js/modules/game-feed.js）を差し込み、画面を 2 つの見え方に分ける:
     フィード（既定）: 白いバー + フィードが画面ちょうど（100dvh）。ページは下へ流れない（一覧を下に積まない）
     一覧（html.tag-view-list）: サーバーが描いたページそのもの（ヘッダー・見出し・説明・タグ・カード・ページ送り・フッター）
   切り替えはバーの「一覧」と一覧の頭の「フィードで遊ぶ」。URL の印は #list（public/js/modules/tag-feed-views.js の WHY）。
   経緯: 以前はフィードの下に一覧を積んでいた → founder「フィードの下に一覧があるのおかしいよね」（2026-09-17）。
   WHY 一覧を見え方の切り替え（タブと同じ）にしてよいのか: 中身は DOM に残り、人が押せる見える操作（バーの「一覧」）で
     いつでも出せる。クローラーには JS 無しの HTML が今までどおり一覧のページとして届き、canonical も変わらない。
   feed-pending: 一覧直後のインラインスクリプトが立てる「これからフィードになる」予告。一覧が一瞬見えてから
     フィードに切り替わるチラつきを消す。#list で来た人は一覧をそのまま見せる。
   feed-on: games-by-tag-feed.js が立てる。最初のページが取れなかったら外して元の一覧に戻す（見え方の規則も全部外れる）。 */

/* ── チラつき止めは「一覧を隠す」ではなく「上に不透明な板を重ねる」（PR #907 レビュー B [重大6]・2026-09-20）──
   以前（2026-09-17〜）はここで .site-header / .main-content > * / .site-footer を visibility: hidden に
   していた。狙い（一覧が一瞬見えてからフィードが被さるのを消す）は正しいが、副作用が 2 つあった:
     1. **SSR の一覧がフィードの JS 一式に人質に取られる**。予告を外すのは 26 本目の JS
        （games-by-tag-feed.js）なので、それが実行されるまでページは 1 ピクセルも描かれない。
        /games・/games/<tag> は検索の着地ページで、LCP がまるごと JS 待ちになっていた。
     2. 隠している間に CSS が壊れる / 予告のスクリプトだけ通って JS が来ない、といった回で
        「白紙のまま」が既定の姿になる（保険の 5 秒に全部を賭ける形）。
   板方式にすると、一覧は**普通のタイミングで描かれたうえで**上を覆われるだけになる。
   ＝ LCP は SSR の中身で決まり、板が出ない回（CSS が届かない・古い版）は一覧がそのまま使える（fail-open）。
   見え方は今までと同じ（人には白い板しか見えない）ので、founder の画面に出る差は無い。

   保険の 5 秒について（レビュー B が「JS 側の 8 秒とずれている」と読んだ点の訂正）:
     games-by-tag-feed.js は**走り出した瞬間に同期で** feed-pending を外して feed-on を立てる
     （同ファイル「html.classList.remove('feed-pending')」）。最初のページの取得（FIRST_PAGE_TIMEOUT_MS
     = 8 秒）を待つのは feed-on になった**後**なので、この 5 秒と競合しない。
     この 5 秒が効くのは「JS が 5 秒たっても走り出さない（読めていない・落ちた）」回だけで、
     そのときに一覧を返すのは正しい。2 つは別々の失敗に対する別々の期限なので、1 つの値には揃えない。 */
.feed-cover { display: none; }
html.feed-pending:not(.tag-view-list) .feed-cover {
  display: block;
  position: fixed;
  inset: 0;
  /* 舞台 5 / レール 6 / 掴み帯 7 / バー 8 より上、シート（--tl-z-sheet 2110）より下。
     一覧の上にしか出ないので、フィードの部品と重なることはない（feed-on で display:none に戻る） */
  z-index: 2000;
  background: #fff;
  /* JS が走り出さなかった回の保険。visibility なので押せるものも一緒に消える（透明な板を残さない） */
  animation: feed-cover-failsafe 0s linear 5s forwards;
}
@keyframes feed-cover-failsafe { to { visibility: hidden; } }
.tag-list-play { display: none; }

/* フィードの見え方: ヘッダー・一覧の中身・フッターは退き、フィードの器だけ。ページ自体を動かさない
   （iframe の上の縦スワイプがページのスクロールに連鎖してゲームが止まるのも、これで起きない） */
html.feed-on:not(.tag-view-list), html.feed-on:not(.tag-view-list) body { overflow: hidden; overscroll-behavior: none; }
html.feed-on:not(.tag-view-list) .site-header,
html.feed-on:not(.tag-view-list) .site-footer,
html.feed-on:not(.tag-view-list) .main-content > :not(.tag-feed) { display: none; }
html.feed-on:not(.tag-view-list) .main-content { max-width: none; padding: 0; }
/* フィードの器: 画面の高さちょうど（dvh はアドレスバーの伸び縮みに追従。解釈しないブラウザは vh）。
   スマホは端から端まで、PC はスマホ幅の列を残りの幅の中央に（左の常設サイドバーは body の左の余白: tag-page-nav.js） */
.tag-feed { position: relative; width: 100%; max-width: 480px; margin: 0 auto; height: 100vh; height: 100dvh; overflow: hidden; }

/* 一覧の見え方: 今までの一覧のページ。フィードの器は画面の同じ位置に**見えないまま**残す。
   WHY display:none にしないのか: フィードは「画面に見えていない」と判定するとゲームを外してセッションを閉じる
   （game-feed.js の visibilityObserver）。一覧の間は一時停止（pause('list_view')）で、戻ったら続きから遊べるようにする */
html.feed-on.tag-view-list .tag-feed {
  position: fixed; top: 0; left: 0; right: 0; margin: 0 auto;
  visibility: hidden; pointer-events: none; z-index: -1;
}
/* 一覧の頭の「フィードで遊ぶ」。ブランドの赤の丸い押しボタン（太い枠・硬い影なし）。
   色は var(--red, #FF3B30)（PR #907 レビュー B [中18]・2026-09-20）: WEBLOX は
   /css/brands/weblox.css が --red を青に上書きする。ベタ書きだとここだけ DreamCore の赤で出る。 */
html.feed-on.tag-view-list .tag-list-play {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 20px; margin: 0 0 20px;
  border: 0; border-radius: 9999px; background: var(--red, #FF3B30); color: #fff;
  font: inherit; font-size: 15px; font-weight: 700; cursor: pointer;
}
html.feed-on.tag-view-list .tag-list-play:focus-visible { outline: 2px solid #171717; outline-offset: 2px; }

/* ── ゲームへの反応（2026-09-17・タイムラインの動画タブと同じ UI）────────────────
   部品の見た目は /css/game-social.css。ここはフィードの枠の中での置き場所だけ:
   表紙のとき = 右下に縦のレール（題名・作者は左下）/ ゲームが表に出たら = フィードの上の 1 本のバー（題名 + 行動・下）。
   遊んでいる間にレールをゲームの上に残すと、ゲーム自身の右側の操作を塞ぐ（タイムラインで実際に起きた）。
   z-index: 舞台 5 < レール・バー 6 < 下の掴み帯 7 < スワイプの案内 9。シートは画面全体の上（--tl-z-sheet）。 */
.dcf-chrome { position: absolute; inset: 0; z-index: 6; pointer-events: none; }
.dcf-chrome .tl-reel-rail { pointer-events: auto; }
.dcf-chrome .tl-reel-rail { right: 16px; bottom: calc(var(--dcf-strip) + 20px); z-index: auto; }
.dcf-item.is-revealed .dcf-chrome .tl-reel-rail { display: none; }
.tag-feed.dcf-social-off .dcf-chrome { display: none; }

/* フィードの上の 1 本のバー（中身は games-by-tag-feed.js）。表紙でもゲーム中でも同じ高さ・同じ位置。
   経緯: 最初は暗い半透明で作ったが、founder「ヘッダーは DreamCore らしく、白いほうが良くない？」（2026-09-17）で白へ。
   色はこのページのサイトヘッダー（白地・下に 1px の線）と、タイムラインのゲーム中の白い上のバー
   （/css/game-social.css のゲーム中の上のバー = --tl-surface の地 + --tl-hairline-strong の線 + --tl-surface-sunk の丸ボタン）の
   トークンをそのまま引く。game-social.css は非同期で読むので、届く前の 1 コマ用に同じ値をフォールバックに書く。
   --tag-feed-bar-h: 44px = 36px の丸いボタン + 上下 4px（押せる大きさを保つ最小）。
   安全領域（ノッチ）はバーの**内側**の余白で吸う（白い地がノッチの下まで伸びる）。フィードの舞台は --dcf-top-inset で下げる。
   DreamCore の作法: 太い枠・硬い影は付けない。暗いフィードとの境はサイトヘッダーと同じ 1px の線だけ。
   z-index 8: 部品の中の要素（舞台 5 < レール 6 < 掴み帯 7）より上、シート（--tl-z-sheet 2110）より下。 */
.tag-feed {
  --tag-feed-bar-h: 44px;
  --dcf-top-inset: calc(var(--tag-feed-bar-h) + env(safe-area-inset-top, 0px));
}
.tag-feed-bar {
  position: absolute; left: 0; right: 0; top: 0; z-index: 8;
  height: var(--dcf-top-inset);
  padding: env(safe-area-inset-top, 0px) 12px 0;
  display: flex; align-items: center; gap: 10px;
  background: var(--tl-surface, #FFFFFF);
  border-bottom: 1px solid var(--tl-hairline-strong, #E5E5E5);
  color: var(--tl-ink, #171717);
}
/* バーの「一覧」: 格子の印 + 短い文字の丸いボタン（右の行動ボタンと同じ窪みの灰）。ゲーム中は題名の幅を残すため印だけ */
.tag-feed-list {
  flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 36px; padding: 0 12px 0 10px; border-radius: 9999px;
  background: var(--tl-surface-sunk, #F5F5F5); color: var(--tl-ink, #171717);
  font-size: 13px; font-weight: 700; line-height: 1; white-space: nowrap; text-decoration: none;
}
html.dcf-playing .tag-feed-list { width: 36px; padding: 0; }
html.dcf-playing .tag-feed-list-text { display: none; }
.tag-feed-list:focus-visible, .tag-feed-bar .tl-reel-topbar-btn:focus-visible { outline: 2px solid var(--tl-ink, #171717); outline-offset: 2px; }
.tag-feed-bar-label { flex: 1 1 auto; min-width: 0; font-size: 14px; font-weight: 700; line-height: 1.2; }
.tag-feed-bar-tag { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 表紙のとき = タグの名前（右は空・行動は表紙の上の右レール）/ ゲーム中（部品が html に dcf-playing）= 行動だけ */
.tag-feed-bar-actions { display: none; }
html.dcf-playing .tag-feed-bar-tag { display: none; }
html.dcf-playing .tag-feed-bar-actions { display: block; flex: none; }
/* 遊んでいる本の題名は**読み上げにだけ**残す（2026-09-20 founder 裁定 1: バーに題名は要らない）。
   display:none だと読み上げからも消えるので、1px に潰して切り抜く昔ながらの形にする。
   幅を取らないので、空いた分はそのまま右の行動ボタンの余裕になる（以前は題名が幅を食って
   スマホで「Si…」まで潰れていた）。文字は games-by-tag-feed.js が itemshown ごとに更新し続ける。 */
.tag-feed-bar-title {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
.tag-feed.dcf-social-off .tag-feed-bar-actions { display: none; }
/* 丸ボタンの見た目はタイムラインの白い上のバーと同じ（game-social.css .tl-reel-topbar-btn: 窪みの灰 + 濃い印、
   押した状態 = 赤の塗り + 白い印）。ここは読み込み前の 1 コマ用のフォールバックだけ */
.tag-feed-bar .tl-reel-topbar-btn { width: 36px; height: 36px; border: 0; border-radius: 50%; background: var(--tl-surface-sunk, #F5F5F5); color: var(--tl-ink-70, #525252); }
.tag-feed-bar .tl-reel-topbar-btn.is-on { background: var(--tl-accent-ink, #CE2820); color: #fff; }
.dcf-creator { display: inline-flex; align-items: center; gap: 8px; min-width: 0; margin-bottom: 4px; color: #fff; font-size: 13px; font-weight: 600; }
.dcf-creator-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dcf-overlay a.tl-profile-link { color: #fff; text-decoration: none; }
/* コメントの中から開くスタンプのシートは、コメントのシートの上に重ねる（タイムラインの #timelineStampSheet と同じ） */
#tagFeedStampSheet { z-index: calc(var(--tl-z-sheet, 2110) + 1); }
html.gs-sheet-open, html.gs-sheet-open body { overflow: hidden; overscroll-behavior: none; }

/* 狭い画面のヘッダーを 1 行に（2026-09-17 founder 実機 349px で右のリンクが 2 行に折れていた）。
   フィードにならない回（JS 無効・フィードの API が返らない・クローラーの描画）で見える形。
   6 言語で一番長い組（es「Todos los juegos」「Crear un juego」）が 320px に 1 行で入る大きさにし、
   それでも入らない端末の文字設定では、折らずにリンクの列だけ横にスクロールさせる（ロゴは縮めない） */
@media (max-width: 480px) {
  .site-header { padding: 12px 16px; gap: 12px; }
  .site-logo { font-size: 17px; flex: none; }
  .header-nav {
    gap: 12px; min-width: 0; overflow-x: auto; scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .header-nav::-webkit-scrollbar { display: none; }
  .header-nav a { font-size: 13px; }
}
@media (max-width: 360px) {
  .site-logo { font-size: 16px; }
  .header-nav { gap: 10px; }
  .header-nav a { font-size: 12px; }
}
/* 左メニューのボタンがヘッダーに入った回（public/js/tag-page-nav.js が .tag-nav-has-toggle を付ける）は、
   400px 以下で「すべてのゲーム」（/games）を出さない。2026-09-17 founder 指摘: 320px の一覧で「つくってみる」が切れて横に流れた。
   WHY このリンクを落とすのか: このページ自体がゲームの一覧で、全タグの索引（/games）へは左メニューからも行ける。
     「つくってみる」は作る側への唯一の入口なので残す。文字をさらに小さくする案は 12px 未満で読みにくくなるので採らない。
   実測（320px・6 言語）: [メニュー][ロゴ][つくってみる] が 1 行に収まり、横のはみ出し 0（レポート参照） */
@media (max-width: 400px) {
  .site-header.tag-nav-has-toggle .header-nav a[href="/games"] { display: none; }
}

/* ── 「プレイ動画が録れた」赤い点（2026-09-18・計画書フェーズ 3-B）─────────────────────────
   印そのもの（大きさ・色・一度だけ脈打つアニメ）の定義は public/css/modules/project-creator.css の
   1 か所だけ（/create → ゲームページ → ここ で同じ物）。あの CSS は .project-creator-view の中でしか
   効かないよう閉じてあるので、rail.js が赤い点を出す回だけシェアのボタン自身にその class を足している。
   ここで足すのは **置き場所（position: relative）だけ**: .tl-reel-topbar-btn は relative を持っておらず、
   絶対配置の点がバーの左上に飛ぶ。色や大きさをここで再定義しないこと（2 か所に割れる）。 */
.tag-feed-bar .tl-reel-topbar-btn[data-reel-share-badge-host] { position: relative; }

/* ── MOBILE-ONLY: アプリ（WebView）の一覧表示でヘッダーがノッチに潜る（2026-09-20・founder 承認済み）──
   実測（iOS シミュレーターの検証用 WKWebView = 本物のアプリと同じ contentInset: never + bridge の印）:
   /games の「List」表示（html.tag-view-list）で header.site-header が top 0〜61pt に出て、
   --safe-top: 62px のダイナミックアイランドに完全に埋まり、ロゴもリンクも読めなかった。
   フィード表示（html.feed-on）はヘッダーを隠して上のセーフエリアを .tag-feed-bar 側で吸っているが、
   一覧の面には吸う場所が無い。viewport-fit=cover は同じ文書（同じ殻）なので外せない ——
   フィードの面がセーフエリアを自分で扱う前提で作られているため。

   CLAUDE.md「ベース → native 上書き」に従い、値は**加算元をベースと合わせる**:
   一覧の殻（games-index.html / games-by-tag.html の <style>）のベースは padding: 16px 24px、
   480px 以下では上の @media がそれを 12px 16px に下げるので、両方ぶんを書く。
   ファイル末尾なのは、同じ詳細度なら後勝ちで、上の @media (max-width: 480px) の 12px より
   後に置かないと広い方の規則が効かないため（public/css/article.css と同じ流儀・同ファイルの WHY 参照）。
   Web（:root の --safe-top: 0px かつ html に native-app が付かない）には 1px も影響しない。 */
html.native-app .site-header { padding-top: calc(16px + var(--safe-top, 0px)); }
@media (max-width: 480px) {
  html.native-app .site-header { padding-top: calc(12px + var(--safe-top, 0px)); }
}
