/* ============================================
   Game Creator - "Kashiwa Sato × Nintendo" Vision
   極限のミニマル × 遊び心 × 本物のガラス
   ============================================ */

/* ===== Design Tokens ===== */
:root {
  /* Signature Color - Nintendo Red meets Modern */
  --red: #FF3B30;
  /* --gold: #FFC400 は 2026-07-29 に廃止。使用箇所は完成カードの3つ（二重枠/★/NEWピル）だけで、
     カードの作り直しで全部消えた。定義を残すと「使われない2色目」がいつか場当たりに使われ、
     赤単色運用が崩れる。レア感が必要になったら、遺物を引き継がず改めて設計して足すこと。 */
  --red-light: rgba(255, 59, 48, 0.1);
  --red-glow: rgba(255, 59, 48, 0.4);

  /* Minimal Palette */
  --white: #FFFFFF;
  --black: #000000;
  --gray-50: #FAFAFA;
  --gray-100: #F5F5F5;
  --gray-200: #E5E5E5;
  --gray-300: #D4D4D4;
  --gray-400: #A3A3A3;
  --gray-500: #737373;
  --gray-600: #525252;
  --gray-700: #404040;
  --gray-900: #171717;
  --red-dark: #D70015;

  /* Glass */
  --glass-white: rgba(255, 255, 255, 0.72);
  --glass-white-strong: rgba(255, 255, 255, 0.88);
  --glass-border: rgba(255, 255, 255, 0.5);
  --glass-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
  --blur: 24px;

  /* Spacing - 8px grid */
  --s-2: 2px;
  --s-4: 4px;
  --s-6: 6px;
  --s-8: 8px;
  --s-10: 10px;
  --s-12: 12px;
  --s-14: 14px;
  --s-16: 16px;
  --s-18: 18px;
  --s-20: 20px;
  --s-22: 22px;
  --s-24: 24px;
  --s-28: 28px;
  --s-30: 30px;
  --s-32: 32px;
  --s-40: 40px;
  --s-48: 48px;
  --s-56: 56px;
  --s-64: 64px;

  /* Radius */
  --r-6: 6px;
  --r-8: 8px;
  --r-12: 12px;
  --r-16: 16px;
  --r-20: 20px;
  --r-24: 24px;
  --r-full: 9999px;

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --duration: 0.4s;

  /* Safe area defaults: web keeps 0, native overrides via html.native-app */
  --safe-top: 0px;
  --safe-bottom: 0px;
  --page-safe-top: 0px;
  --page-safe-bottom: 0px;
  --effective-safe-bottom: 0px;
  /* 下ナビの高さ（2026-09-23: 52 → 60。founder 承認の新しい下ナビ。見た目は css/modules/navigation.css）。
     各ページの「下ナビの分の余白」（--bottom-nav-reserved-space*）はこの値から出るので、ここを直せば全ページが追従する */
  --bottom-nav-height: 60px;
  --bottom-nav-float-gap: max(12px, var(--safe-bottom));
  --bottom-nav-reserved-space-tight: calc(var(--bottom-nav-height) + var(--bottom-nav-float-gap));
  --bottom-nav-reserved-space: calc(var(--bottom-nav-reserved-space-tight) + 8px);
  --bottom-nav-reserved-space-comfy: calc(var(--bottom-nav-reserved-space-tight) + 12px);
}

html.native-app {
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

/* ===== Animations ===== */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

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

@keyframes scaleIn {
  from {
    opacity: 0;
    transform: scale(0.95);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* ===== Typography - Inter (loaded via HTML <link> for performance) ===== */
/* Font is loaded in HTML with rel="preconnect" to avoid render-blocking */

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  height: 100dvh;
  overflow: hidden;
  overscroll-behavior: none;
}

html {
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  background: var(--gray-100);
  color: var(--gray-900);
  line-height: 1.5;
}

body[data-page] {
  --page-safe-top: var(--safe-top);
  --page-safe-bottom: var(--safe-bottom);
  --effective-safe-bottom: var(--page-safe-bottom);
}

/* ===== Background - Gradient Mesh ===== */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  background:
    radial-gradient(ellipse 80% 50% at 20% -10%, rgba(255, 59, 48, 0.15), transparent),
    radial-gradient(ellipse 60% 40% at 80% 110%, rgba(255, 59, 48, 0.1), transparent),
    linear-gradient(180deg, var(--white) 0%, var(--gray-100) 100%);
  z-index: -1;
}

.hidden {
  display: none !important;
}

/* ===== Main Layout ===== */
.container {
  display: flex;
  height: 100%;
  width: 100%;
  max-width: 100%;
  overflow: hidden;
}

/* ===== Project List View - Nintendo × Kashiwa Sato ===== */
.project-list-view {
  --create-header-height: calc(56px + var(--page-safe-top, var(--safe-top, 0px)));
  /* --create-hero-space / --create-hero-gap は 2026-07-29 に廃止。
     .create-hero が position:fixed をやめて通常フローに戻ったので、
     「見えない固定ヒーローの高さを数えて棚を押し下げる」仕掛けごと不要になった。
     （旧: 252px を style.css 6箇所＋app.js updateComposerHeroSpace の実測で維持していた） */
  height: 100%;
  width: 100%;
  max-width: 100%;
  background: var(--white);
  display: flex;
  flex-direction: column;
  overflow-x: clip;
  overflow-y: auto;
  touch-action: pan-y;
  overscroll-behavior-x: none;
}

/* Minimal Header */
.list-header {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--s-16) var(--s-32);
  padding-top: calc(var(--s-16) + var(--page-safe-top, var(--safe-top)));
  background: rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--gray-100);
  overflow: visible;
}

.list-header-left {
  display: flex;
  align-items: center;
  gap: var(--s-12);
}

.brand-mark {
  width: 28px;
  height: 28px;
  background: url('/icons/icon-192.png') center/contain no-repeat;
  border-radius: 8px;
}

.brand-text {
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--gray-900);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.list-header-back {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--white);
  border: 1px solid var(--gray-200);
  color: var(--gray-900);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.15s ease;
  flex-shrink: 0;
}

.list-header-back:active {
  transform: scale(0.95);
}

@media (hover: hover) {
  .list-header-back:hover {
    background: var(--gray-50);
    border-color: var(--gray-400);
  }
}

.list-header-title {
  font-size: 1rem;
  font-weight: 800;
  color: var(--gray-900);
  letter-spacing: -0.01em;
}

.list-header-right {
  display: flex;
  align-items: center;
  gap: var(--s-16);
  min-width: 0;
}

/* 匿名ユーザー向けヘッダーログインボタン（Twitter/X の "Log in" ピルに倣ったデザイン）。
   デフォルト非表示、body.dc-anon のときだけ表示。ログイン済みでは dc-anon が外れるので自動で消える。 */

body.dc-anon .anon-login-cta { display: inline-flex; }

.user-id {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--gray-600);
}

.sign-out-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  background: transparent;
  border: none;
  border-radius: var(--r-8);
  color: var(--gray-400);
  cursor: pointer;
  transition: all 0.2s ease;
}

.sign-out-btn:hover {
  background: var(--gray-100);
  color: var(--gray-600);
}

.notifications-badge {
  position: absolute;
  top: 4px;
  right: 4px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  background: var(--red);
  color: var(--white);
  font-size: 0.625rem;
  font-weight: 700;
  border-radius: var(--r-full);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: scaleIn 0.3s var(--ease-out);
}

/* 入口一本化コンポーザー(.dc-composer)のコンテナ。
   founder決定 2026-07-28: 旧「つくる/自由につくる」2ボタン(.create-btn/.create-free)は廃止。

   2026-07-29 リデザイン: position:fixed をやめ、通常フローに戻した。
   ■ なぜ
     fixed だったが .create-hero 自身に background の宣言が1行も無く、不透明なのは中の
     .dc-composer（--glass-white-strong 0.88）だけだった。結果、スクロールするとプロジェクト
     カードやテンプレ棚がチップ行・余白の裏を通り、文字が二重に重なって読めなくなっていた
     （375x812 実測 2026-07-29）。
     さらにその代償として、棚の開始位置 --create-hero-space を JS(updateComposerHeroSpace)が
     毎フレーム実測して追随させる構造になっており、値の宣言が style.css の6箇所に散っていた。
     通常フローに戻すと、ヒーローは自分の高さを自分で占めるので、重なりが構造的に起こり得ず、
     実測ロジックも --create-hero-space も丸ごと不要になる（可士和: 2つのものが同じ場所を主張しない）。
   ■ 上に戻る手段
     スクロールするとヒーローは画面外に出るが、その戻り道は新しいバーではなく
     ヘッダー自身の変身（.create-header-cta）で払う＝レイヤーを1つも増やさない。 */
.create-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-12);
  justify-content: center;
  padding: var(--s-28) var(--s-32) var(--s-16);
}

/* この画面で唯一の第1段見出し。問いを placeholder から出してここに置いた。
   1.75rem/900/-0.045em = 本番の最大見出し(.create-section-head h2 = 1.2rem/900)より一段上を新設。
   ページで一番大きい文字がこれである＝この画面の用件は1つ、という宣言（可士和: タイポグラフィで語る）。 */

/* ══════════════════════════════════════════════════════════════════════
   入口一本化チャットコンポーザー (.dc-composer)
   founder決定 2026-07-28: /create の入口を「つくる/自由につくる」2ボタンから
   チャット欄1本に統合。data-driven（直近30日 studio 1,521件 vs make 404件だが、
   新規ユーザーの初回選択は studio 97 vs make 84 とほぼ互角＝チャット導線の
   可視性がボトルネック）。Alex Zhu原則「ユーザーを教育しない」＝2択を見せず、
   入力欄1本+サジェストチップで「書きたくなる」設計にする。
   見た目/挙動は合意済みモック
   /private/tmp/.../scratchpad/dreamcore-mock/create.html に準拠（値も流用）。
   詳細: .claude/plans/create-entry-unification.md
   ══════════════════════════════════════════════════════════════════════ */

/* 送信ボタン（2026-07-29: 丸アイコン → ラベル付きピル）。
   ■ なぜラベルを書くか
     旧は 44px の丸に矢印アイコンだけで、押すと何が起きるかを画面が説明していなかった。
     任天堂の作法では A ボタンには必ずラベルがある。ここは動詞「つくる」を書く
     ＝この画面の唯一の動詞を、押す場所そのものに刻む。
   ■ なぜ未入力時に opacity ではなく色で伝えるか
     旧は opacity:.4。アイコンだけなら成立するが、ラベルを載せると赤地に白文字が
     薄ピンク×白になって読めない。押せないことは「灰色である」で十分伝わる。
   ■ 位置
     旧は textarea の横。下段(.dc-composer-foot)へ出したので入力欄が全幅になり、
     「書ける場所」が広く見える（Alex Zhu: 書かせたいなら広くする）。 */

/* コンポーザー下段: 左に修飾語［画像 / 2D / 3D］、右に動詞［つくる］。
   修飾語と動詞を左右に分けるのは、3つのツールが「別々の入口」ではなく
   「つくるの条件」であることを配置で言うため（可士和: 同じ強さのものを並べない）。 */

.dc-tool.active { color: var(--red); }

/* 画像だけ塗りのピルにして一段強くする。DreamCore のコアバリュー「プリクラ化」に
   最も近い入口がこれなので、3つ横並びの中で画像を主・2D/3D を従にする。 */

.dc-tool--image.active { background: var(--red); color: var(--white); }

/* 2D / 3D は排他トグル。押さない＝おまかせ が既定に見えるよう、灰色の連結セグメントに畳む。
   ラベルから「でつくる」を落としたのは i18n（6言語）で語順が壊れないようにするため。
   "2D"/"3D" は全言語共通の記号なので、どの locale でも幅が変わらない。 */

.dc-dim.active { background: var(--white); color: var(--gray-900); box-shadow: 0 1px 3px rgba(0, 0, 0, .10); }

/* コンテキスト/添付ピル行: 写真添付・3Dトグルをチャットの「コンテキスト」として畳んで見せる。
   makeウィザードの「写真ステップ」「2D/3D選択」の代替（founder決定・機械的なフォームを出さない）。 */

.dc-ctx-pill {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--red-light); color: var(--red);
  border-radius: var(--r-full); padding: 5px 10px 5px 6px;
  font-size: 12.5px; font-weight: 700;
  animation: dcPillIn .25s var(--ease-out);
}
@keyframes dcPillIn { from { opacity: 0; transform: scale(.9); } to { opacity: 1; transform: scale(1); } }
.dc-ctx-pill .thumb {
  width: 24px; height: 24px; border-radius: 8px; overflow: hidden;
  background: var(--white); display: grid; place-items: center; font-size: 13px;
}
.dc-ctx-pill .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dc-ctx-pill button {
  border: 0; background: none; color: var(--red); cursor: pointer;
  font-size: 14px; line-height: 1; padding: 2px; opacity: .7; font-family: inherit;
}

.dc-chip {
  flex-shrink: 0;
  background: var(--white); border: 1px solid var(--gray-200);
  border-radius: var(--r-full); padding: 8px 14px;
  font-size: 13px; font-weight: 600; color: var(--gray-600);
  cursor: pointer; white-space: nowrap; font-family: inherit;
  transition: all .2s var(--ease-out);
}
.dc-chip:hover { border-color: var(--red); color: var(--red); }
.dc-chip:active { transform: scale(.95); }
/* チップの語彙を分類名から実文に変えたため、長い例文だと1枚目が画面幅を超えて
   「途中で切れた文が1本」しか見えなくなる（375px 実測: ja/en/es/pt/ko で発生）。
   出す文自体を短いものに絞る（app.js rollComposerChips）うえで、保険として幅上限も置く。
   72% = 2枚目の頭が必ず見える上限（横に続きがあることが伝わる） */
.dc-chip { max-width: 72%; overflow: hidden; text-overflow: ellipsis; }

/* 🎲おまかせ（2026-07-29）: 隣の例文チップと役割が違う（例＝読むもの / これ＝押すもの）ので、
   同じ白いピルのままだと「例のひとつ」に埋もれる。赤の淡色で塗り分けて「操作」だと分からせる。
   押すと1回転しながら、例文が1文字ずつ入力欄に書き込まれる（app.js rollComposerIdeaIntoInput）。
   この画面で演出はここ1箇所だけ（任天堂: 発見の喜びは1つに絞る。多いと散らかる）。 */

@keyframes dcDiceRoll {
  from { transform: rotate(0deg) scale(1); }
  50%  { transform: rotate(200deg) scale(1.25); }
  to   { transform: rotate(360deg) scale(1); }
}

/* 白紙Studio導線（founder指摘 2026-07-29）: チャット欄が主・これは副次、の階層を
   視覚で保つため、控えめなテキストリンク意匠（チップより弱く・ただしタップ領域は44px確保） */

/* ===== Daily Prompt（今日のお題）===== */

.daily-prompt-card.hidden {
  display: none;
}

.daily-prompt-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-12);
}

.daily-prompt-kicker {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  background: var(--red, #ff3b30);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  border-radius: 100px;
}

.daily-prompt-reroll {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: transparent;
  border: none;
  color: var(--gray-500, #8a8a8e);
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  border-radius: 100px;
  transition: color 0.2s ease, background 0.2s ease;
}

.daily-prompt-reroll:hover {
  color: var(--red, #ff3b30);
  background: rgba(255, 59, 48, 0.08);
}

.daily-prompt-reroll svg {
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.daily-prompt-reroll:active svg {
  transform: rotate(-180deg);
}

.daily-prompt-text {
  margin: 0;
  font-size: 1.18rem;
  font-weight: 800;
  line-height: 1.5;
  color: var(--gray-900, #1c1c1e);
  letter-spacing: 0.01em;
}

.daily-prompt-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  align-self: flex-start;
  padding: 14px 28px;
  background: linear-gradient(135deg, var(--red, #ff3b30) 0%, #e0312a 100%);
  color: #fff;
  border: none;
  border-radius: 100px;
  font-size: 1rem;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 6px 18px -4px rgba(255, 59, 48, 0.5);
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.2s ease;
}

.daily-prompt-cta:hover {
  transform: translateY(-2px) scale(1.02);
  box-shadow: 0 10px 24px -4px rgba(255, 59, 48, 0.55);
}

.daily-prompt-cta:active {
  transform: scale(0.97);
}

.daily-prompt-pick {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  align-self: flex-start;
  margin-top: 2px;
  padding: 4px 2px;
  color: var(--gray-500, #8a8a8e);
  font-size: 0.85rem;
  font-weight: 700;
  text-decoration: none;
  transition: color 0.2s ease;
}
.daily-prompt-pick:hover { color: var(--red, #ff3b30); }

@media (max-width: 520px) {
  .daily-prompt-text {
    font-size: 1.05rem;
  }
  .daily-prompt-cta {
    align-self: stretch;
  }
}

/* Games Section */
.games-section {
  flex: 1;
  padding: 0 var(--s-32) var(--bottom-nav-reserved-space-comfy);
  /* 2026-07-29: margin-top: var(--create-hero-space, 252px) を撤去。
     .create-hero が position:fixed をやめて通常フローで高さを占めるようになったため、
     棚を押し下げる仕掛け自体が不要になった（=JS の実測追随も不要）。 */
}

/* ===== User Characters ===== */

.character-call-button {
  min-height: 42px;
  display: inline-flex;
  align-items: center;
  gap: var(--s-8);
  padding: 0 var(--s-14);
  border: 1px solid var(--gray-200);
  border-radius: 999px;
  background: var(--white);
  color: var(--gray-900);
  font-size: 0.9rem;
  font-weight: 900;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}

.character-call-button[aria-expanded="true"] {
  border-color: var(--gray-900);
}

.character-call-icon {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--gray-900);
  color: var(--white);
  font-size: 1rem;
  line-height: 1;
}

.character-shelf-link--quiet {
  display: inline-flex;
  align-items: center;
  color: var(--gray-500);
  text-decoration: none;
}

.character-shelf-title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 800;
  line-height: 1.2;
  color: var(--gray-900);
}

.character-shelf-actions {
  display: flex;
  align-items: center;
  gap: var(--s-8);
}

.character-callout-empty {
  width: fit-content;
  display: inline-flex;
  align-items: center;
  gap: var(--s-10);
  padding: var(--s-10);
  color: var(--gray-600);
  font-size: 0.82rem;
  font-weight: 800;
}

.character-callout-empty button {
  min-height: 34px;
  padding: 0 var(--s-12);
  border: 1px solid var(--gray-900);
  border-radius: var(--r-8);
  background: var(--gray-900);
  color: var(--white);
  font-weight: 900;
  cursor: pointer;
}

.character-style-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-6);
  margin-top: var(--s-8);
}

.character-style-chip {
  min-height: 26px;
  padding: 0 var(--s-8);
  border: 1px solid var(--gray-200);
  border-radius: var(--r-8);
  background: var(--gray-50);
  color: var(--gray-700);
  font-size: 0.72rem;
  font-weight: 800;
  cursor: pointer;
}

.character-style-chip.is-default {
  border-color: var(--red);
  background: var(--red-light);
  color: var(--red-dark);
}

.character-style-chip:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.character-card-actions {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s-6);
  margin-top: var(--s-10);
}

.character-retry-button {
  background: var(--gray-100);
  color: var(--gray-700);
}

.character-empty-card {
  min-height: 176px;
  border: 1px dashed var(--gray-300);
  border-radius: var(--r-8);
  background: rgba(255, 255, 255, 0.65);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-16);
}

.character-empty-card button {
  min-height: 40px;
  padding: 0 var(--s-16);
  border: 1px solid var(--gray-300);
  border-radius: var(--r-8);
  background: var(--white);
  color: var(--gray-900);
  font-weight: 800;
  cursor: pointer;
}

.character-input-list .character-mini-card {
  flex: 0 0 auto;
}

.character-mini-card-action {
  margin-top: var(--s-6);
  min-height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-6);
  background: var(--gray-900);
  color: var(--white);
  font-size: 0.72rem;
  font-weight: 900;
}

.character-mini-card:disabled .character-mini-card-action {
  background: var(--gray-200);
  color: var(--gray-500);
}

/* ===== Characters page ===== */

html[data-page="characters"],
body[data-page="characters"] {
  height: auto;
  min-height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior-y: auto;
}

/* CHALLENGE-FEATURE: お題棚（/challenge/:slug・/challenges）はロングフォームのページ。
   shell の既定は html,body overflow:hidden（ゲーム面基準）なので、characters と同じ形で
   body スクロールをオプトインする。これが無いと棚がスクロールできない（2026-08-03 実機で検出）。
   x-campaign（/x/:slug の X キャンペーン棚）も同型のロングフォーム棚なので同じ形で
   オプトイン（2026-08-29 の app-shell 化直後、founder 実機で「スクロールできない」を再検出）。 */
html[data-page="challenge"],
body[data-page="challenge"],
html[data-page="x-campaign"],
body[data-page="x-campaign"] {
  height: auto;
  min-height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior-y: auto;
}

body[data-page="characters"] {
  background: #FFFFFF;
  -webkit-overflow-scrolling: touch;
}

.characters-kicker {
  margin: 0 0 var(--s-6);
  color: #8A8F98;
  font-size: 0.66rem;
  font-weight: 900;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

/* ── Empty state (0 characters) ──────────────────────────
   Visual language matches the onboarding intro panel so the
   moment you tap はじめる, the next page feels continuous.
   - Cream stage with warm radial gradients (Nintendo splash feel)
   - Rotated black sticker badge (Sato signature)
   - Big asymmetric title, yellow underline accent on the key word
   - Chunky red CTA with offset black shadow (arcade button)
   - Soft yellow glow blob top-right for depth */

.characters-empty-title-line {
  display: block;
  position: relative;
}

/* Chunky arcade-button CTA. Overrides the default character-create-button
   styling when inside the empty state. */

/* ── Detail view mode ─────────────────────────────────────
   When a character is selected we want the page to feel like
   a shrine to that character. Hide the page title row, the
   stock strip, the sort, and the roster grid — the spotlight
   owns the page. The back link inside the spotlight is the
   only way out. */

/* タッチ端末は hover がないので常時表示 */

@keyframes chm-preview-frames {
  to { background-position: 100% var(--movement-preview-row); }
}

@keyframes chm-preview-walk {
  0%, 100% { transform: translateX(-8px); }
  50% { transform: translateX(8px); }
}

@keyframes chm-preview-hop {
  0%, 100% { transform: translate(0, 0); }
  45% { transform: translate(8px, -14px); }
  70% { transform: translate(13px, 0); }
}

/* 走って跳ぶ: キャラ中央固定。地面がスクロールして走ってる感を表現。
   定期的に小さくジャンプ。マリオ風サイドスクロール演出。 */
@keyframes chm-side-character-hop {
  0%, 60%, 100% { transform: translate(0, 0); }
  20% { transform: translate(0, -18%); }   /* ぴょん */
  35% { transform: translate(0, 0); }
}

@keyframes chm-side-ground-scroll {
  from { background-position-x: 0; }
  to   { background-position-x: -36px; }   /* 1サイクル分 = ダッシュ16 + 空白20 = 36px */
}

@keyframes chm-side-cloud-drift-a {
  0%   { left: 70%; }
  100% { left: -10%; }
}

@keyframes chm-side-cloud-drift-b {
  0%   { left: 90%; }
  100% { left: -10%; }
}

@keyframes chm-preview-eight-way {
  0%   { background-position: 0%   0%;   transform: scaleX(1); }
  6%   { background-position: 50%  0%;   transform: scaleX(1); }
  12%  { background-position: 100% 0%;   transform: scaleX(1); }
  13%  { background-position: 0%   25%;  transform: scaleX(1); }
  19%  { background-position: 50%  25%;  transform: scaleX(1); }
  25%  { background-position: 100% 25%;  transform: scaleX(1); }
  26%  { background-position: 0%   50%;  transform: scaleX(1); }
  32%  { background-position: 50%  50%;  transform: scaleX(1); }
  38%  { background-position: 100% 50%;  transform: scaleX(1); }
  39%  { background-position: 0%   75%;  transform: scaleX(1); }
  45%  { background-position: 50%  75%;  transform: scaleX(1); }
  51%  { background-position: 100% 75%;  transform: scaleX(1); }
  52%  { background-position: 0%   100%; transform: scaleX(1); }
  58%  { background-position: 50%  100%; transform: scaleX(1); }
  64%  { background-position: 100% 100%; transform: scaleX(1); }
  65%  { background-position: 0%   25%;  transform: scaleX(-1); }
  71%  { background-position: 50%  25%;  transform: scaleX(-1); }
  77%  { background-position: 100% 25%;  transform: scaleX(-1); }
  100% { background-position: 0%   0%;   transform: scaleX(1); }
}

.characters-primary-action,
.characters-secondary-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-10);
  align-self: flex-start;
  min-width: 220px;
  min-height: 56px;
  padding: 0 var(--s-24);
  border: 0;
  border-radius: 999px;
  background: #E60012;
  color: #FFFFFF;
  font-size: 1.02rem;
  font-weight: 900;
  letter-spacing: 0.02em;
  cursor: pointer;
  box-shadow: 0 2px 0 #B8000E;
  transition: transform 0.06s ease, background-color 0.16s ease, box-shadow 0.16s ease;
}

.characters-secondary-action {
  border: 1.5px solid #D8D6CE;
  background: #FFFFFF;
  color: #0F1115;
  box-shadow: 0 2px 0 #D8D6CE;
}

.characters-primary-action svg,
.characters-secondary-action svg {
  flex: 0 0 auto;
}

.characters-primary-action:not(:disabled):hover {
  background: #FF1A1F;
}

.characters-secondary-action:not(:disabled):hover {
  border-color: #0F1115;
  background: #F8F8F5;
}

.characters-primary-action:not(:disabled):active,
.characters-secondary-action:not(:disabled):active {
  transform: translateY(2px);
}

.characters-primary-action:not(:disabled):active {
  box-shadow: 0 0 0 #B8000E;
  background: #B8000E;
}

.characters-secondary-action:not(:disabled):active {
  box-shadow: 0 0 0 #D8D6CE;
}

.characters-primary-action:disabled,
.characters-secondary-action:disabled {
  opacity: 1;
  cursor: not-allowed;
  box-shadow: none;
  background: #D7D7D2;
  color: rgba(15, 17, 21, 0.45);
  border-color: transparent;
}

.characters-source-strip,
.characters-assets-strip {
  margin-top: var(--s-24);
  padding-top: var(--s-16);
  border-top: 1px solid #ECEBE6;
}

.characters-source-strip > span,
.characters-assets-strip > span {
  display: block;
  margin-bottom: var(--s-6);
  color: #8A8F98;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0;
}

.characters-source-strip > small {
  display: block;
  margin: calc(-1 * var(--s-6)) 0 var(--s-10);
  color: #8A8F98;
  font-size: 0.72rem;
  font-weight: 800;
}

.characters-source-strip > div,
.characters-assets-strip > div {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-8);
}

.characters-asset-pill {
  display: flex;
  align-items: center;
  gap: var(--s-8);
  min-height: 42px;
  padding: var(--s-6) var(--s-12) var(--s-6) var(--s-6);
  border: 1px solid #ECEBE6;
  border-radius: 999px;
  background: var(--white);
  color: #0F1115;
  font-size: 0.78rem;
  font-weight: 800;
}

.characters-asset-thumb {
  width: 34px;
  height: 34px;
  border-radius: 999px;
}

/* ─── Character stock (toolbar HUD) ──────────────────────────
   Sits inline in the grid toolbar (left of sort). No border,
   no background — it's a HUD line, not a banner. The pips do
   the work; copy stays in microscale. Red is reserved for
   over-limit and only colors the pips + overflow chip. */

@keyframes character-spin {
  to { transform: rotate(360deg); }
}

.characters-more-menu-roster {
  position: absolute;
  top: 8px;
  right: 8px;
  opacity: 0;
  transform: scale(0.94);
  transition: opacity 0.16s ease, transform 0.16s ease;
}

.characters-roster-item:hover .characters-more-menu-roster,
.characters-roster-item:focus-within .characters-more-menu-roster,
.characters-more-menu-roster[open] {
  opacity: 1;
  transform: scale(1);
}

.characters-more-menu-roster summary {
  width: 34px;
  height: 34px;
  background: rgba(255, 255, 255, 0.92);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

@media (hover: none) {
  .characters-more-menu-roster {
    opacity: 1;
    transform: scale(1);
  }
}

@media (max-width: 760px) {

  .characters-primary-action,
  .characters-secondary-action {
    align-self: stretch;
    min-width: 0;
  }

}

/* ===== Featured Remix Shelf - Nintendo × Kashiwa Sato ===== */

.featured-remix-section {
  margin-bottom: var(--s-32);
  animation: fadeIn 0.5s var(--ease-out);
}

.featured-remix-section.hidden {
  display: none;
}

/* --- Header --- */

.featured-remix-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-12);
  margin-bottom: var(--s-16);
}

/* テンプレ棚（3D TPS・FPS / 3D その他 / 2D）の見出しはフォトRemix見出しより一段小ぶりに
   （founder 決定 2026-07-23: 4棚を並べた時にフォトRemixが視覚的な主役として残るよう差をつける） */
.template-shelf-title {
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--gray-700, #48484a);
}

/* フォトRemix棚見出し横の「すべて見る」（旧: create-section-head 直下から移設） */
.featured-remix-header-link {
  flex: 0 0 auto;
  color: var(--gray-400);
  font-size: 0.8rem;
  font-weight: 800;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

/* --- Shelf wrapper with right-edge fade --- */

.featured-remix-shelf-wrap {
  position: relative;
}

.featured-remix-shelf-wrap::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 40px;
  background: linear-gradient(to left, var(--white), transparent);
  pointer-events: none;
  z-index: 2;
}

/* --- Shelf grid --- */

.featured-remix-shelf {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 172px;
  gap: var(--s-12);
  overflow-x: auto;
  overflow-y: hidden;
  padding: var(--s-4) 0 var(--s-16);
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.featured-remix-shelf::-webkit-scrollbar {
  display: none;
}

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

/* Play button on thumbnail */

.featured-remix-play-btn {
  position: absolute;
  bottom: var(--s-8);
  right: var(--s-8);
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--glass-white-strong);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  cursor: pointer;
  transition: all 0.25s var(--ease-out);
  z-index: 1;
}

.featured-remix-play-btn svg {
  width: 14px;
  height: 14px;
  fill: var(--gray-900);
  margin-left: 2px;
}

.featured-remix-play-btn:hover {
  transform: scale(1.12);
  background: var(--white);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}

.featured-remix-play-btn:active {
  transform: scale(0.95);
}

/* Badge */

.featured-remix-badge {
  position: absolute;
  top: var(--s-8);
  left: var(--s-8);
  padding: 4px 8px;
  border-radius: var(--r-full);
  background: var(--glass-white-strong);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--gray-900);
  font-size: 0.625rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1;
}

.featured-remix-card-meta {
  margin: 0;
  font-size: 0.75rem;
  color: var(--gray-400);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Remix CTA */

.featured-remix-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 38px;
  margin-top: auto;
  padding: 0;
  border: 1.5px solid rgba(255, 59, 48, 0.3);
  border-radius: var(--r-full);
  background: var(--white);
  color: var(--red);
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: all 0.25s var(--ease-out);
}

/* Desktop: subtle at rest, fills red on hover */
@media (hover: hover) and (pointer: fine) {
  .featured-remix-cta {
    border-color: var(--gray-200);
  }

  .featured-remix-cta:hover {
    background: var(--red);
    color: var(--white);
    border-color: var(--red);
    box-shadow: 0 4px 16px var(--red-glow);
    transform: scale(1.04);
  }
}

.featured-remix-cta:active {
  transform: scale(0.97);
}

/* Desktop: larger cards, bigger title */
@media (min-width: 769px) {
  .featured-remix-shelf {
    grid-auto-columns: 220px;
    gap: var(--s-16);
  }

  .featured-remix-play-btn {
    width: 40px;
    height: 40px;
  }

  .featured-remix-play-btn svg {
    width: 16px;
    height: 16px;
  }

  .featured-remix-cta {
    height: 40px;
  }
}

.featured-remix-more-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--gray-400);
}
.featured-remix-more-text {
  font-size: 0.75rem;
  font-weight: 700;
}

.featured-remix-more:hover .featured-remix-more-inner {
  color: var(--red);
}

.bookmark-content {
  flex: 1 1 0%;
  padding: 0 var(--s-32) var(--bottom-nav-reserved-space-comfy);
}

.filter-tab:hover {
  color: var(--gray-600);
}

.filter-tab.active {
  color: var(--gray-900);
}

/* Project Grid */
.project-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: var(--s-12);
}

/* Project Card - Minimal */
.project-card {
  position: relative;
  background: var(--gray-50);
  border-radius: var(--r-16);
  cursor: pointer;
  transition: all 0.3s var(--ease-out);
  border: 1px solid transparent;
  overflow: hidden;
}

.project-card::before {
  content: '';
  position: absolute;
  top: var(--s-8);
  right: var(--s-8);
  width: 8px;
  height: 8px;
  background: var(--red);
  border-radius: 50%;
  opacity: 0;
  transform: scale(0);
  transition: all 0.3s var(--ease-out);
  z-index: 2;
}

/* Project Card Thumbnail */
.project-card-thumbnail {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  background: var(--gray-100);
  overflow: hidden;
}

.project-card-thumbnail img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.project-card-thumbnail-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-16);
  box-sizing: border-box;
}

.project-card-thumbnail-placeholder .placeholder-title {
  font-size: 1.25rem;
  font-weight: 900;
  color: var(--white);
  text-align: center;
  line-height: 1.3;
  text-shadow:
    0 2px 4px rgba(0, 0, 0, 0.2),
    0 1px 0 rgba(255, 255, 255, 0.3);
  word-break: break-word;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
}

.project-card:hover {
  background: var(--white);
  border-color: var(--gray-200);
  transform: translateY(-4px);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.08);
}

.project-card:hover::before {
  opacity: 1;
  transform: scale(1);
}

.project-card-header {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--s-12);
  padding: var(--s-16) var(--s-16) 0;
}

.project-card-title {
  font-size: 1rem;
  font-weight: 700;
  color: var(--gray-900);
  line-height: 1.4;
  letter-spacing: -0.01em;
  min-width: 0;
  min-height: 2.8em;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.project-card-actions button.delete-btn:hover {
  background: var(--red-light);
  border-color: var(--red);
}

.project-card-meta {
  display: grid;
  gap: var(--s-8);
  padding: var(--s-8) var(--s-16) var(--s-16);
}

.project-card-date {
  font-size: 0.75rem;
  color: var(--gray-400);
  font-weight: 500;
}

/* Studio (chat editor) entry — compact, left-aligned, SUBORDINATE secondary action.
   The card itself opens the Creator editor (primary, via tap + chevron + hover-lift);
   Studio is the alternate chat editor, kept visually quiet so it doesn't outweigh the card. */

/* Empty State */
.project-empty {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--s-64);
  color: var(--gray-400);
}

.project-empty-icon {
  font-size: 3rem;
  margin-bottom: var(--s-16);
  opacity: 0.5;
}

.project-empty p {
  font-size: 0.875rem;
  margin-bottom: var(--s-24);
}

.bookmark-page-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 24px;
  padding: 0 8px;
  border-radius: 999px;
  background: var(--gray-100);
  color: var(--gray-500);
  font-size: 0.75rem;
  font-weight: 700;
}

.bookmark-chips {
  display: flex;
  gap: 8px;
  padding: var(--s-16) 0 var(--s-12);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.bookmark-chips::-webkit-scrollbar {
  display: none;
}

.bookmark-chip {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 32px;
  padding: 0 14px;
  border: 1.5px solid var(--gray-200);
  border-radius: 8px;
  background: var(--white);
  color: var(--gray-600);
  font-size: 0.8125rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: all 0.15s ease;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}

.bookmark-chip:active {
  transform: scale(0.95);
}

.bookmark-chip.active {
  background: var(--gray-900);
  color: var(--white);
  border-color: var(--gray-900);
}

.bookmark-chip.active::after {
  content: '';
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 2px;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  transition: transform 0.2s ease;
}

.bookmark-chip.active.asc::after {
  transform: rotate(180deg);
}

body[data-page="bookmarks"] .project-card {
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}

body[data-page="bookmarks"] .project-card:active {
  transform: scale(0.97);
}

@media (hover: hover) {
  body[data-page="bookmarks"] .project-card:hover {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  }
}

body[data-page="bookmarks"] .project-card-meta {
  padding-bottom: var(--s-12);
}

.bookmark-card-description {
  padding: 0 var(--s-16);
  color: var(--gray-500);
  font-size: 0.875rem;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

body[data-page="bookmarks"] .project-empty {
  padding-top: 80px;
}

body[data-page="bookmarks"] .project-empty-icon {
  font-size: 48px;
  opacity: 0.3;
}

.bookmark-empty-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: var(--s-8);
  padding: 10px 20px;
  border-radius: 999px;
  background: var(--gray-900);
  color: var(--white);
  font-size: 0.875rem;
  font-weight: 600;
  text-decoration: none;
  transition: transform 0.15s ease, opacity 0.15s ease;
}

.bookmark-empty-cta:active {
  transform: scale(0.97);
  opacity: 0.8;
}

@media (max-width: 640px) {
  .bookmark-content {
    padding-left: var(--s-16);
    padding-right: var(--s-16);
  }

}

/* ===== Chat Panel - Main Glass Container ===== */
.chat-panel {
  width: 440px;
  min-width: 360px;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--glass-white);
  backdrop-filter: blur(var(--blur));
  -webkit-backdrop-filter: blur(var(--blur));
  border-right: 1px solid var(--glass-border);
  overflow: hidden;
}

.chat-header {
  flex-shrink: 0;
  padding: var(--s-16);
  display: flex;
  align-items: center;
  gap: var(--s-12);
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
}

.chat-header h1 {
  font-size: 1.25rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--gray-900);
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.home-btn {
  width: 40px;
  height: 40px;
  border-radius: var(--r-12);
  background: transparent;
  border: none;
  color: var(--gray-600);
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.home-btn:hover {
  background: var(--gray-100);
  color: var(--gray-900);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--s-8);
}

#playGameButton {
  display: flex;
  align-items: center;
  gap: var(--s-8);
  padding: var(--s-12) var(--s-16);
  background: var(--red);
  border: none;
  border-radius: var(--r-full);
  color: var(--white);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  transition: all var(--duration) var(--ease-out);
  box-shadow: 0 4px 12px var(--red-glow);
}

#playGameButton:hover {
  transform: scale(1.05);
  box-shadow: 0 6px 20px var(--red-glow);
}

#playGameButton svg {
  width: 16px;
  height: 16px;
}

#publishButton {
  display: flex;
  align-items: center;
  gap: var(--s-8);
  padding: var(--s-12) var(--s-16);
  background: transparent;
  border: 0;
  border-radius: 0;
  color: var(--gray-900);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s ease;
}

#publishButton:hover:not(:disabled) {
  background: var(--gray-50);
}

#publishButton:active:not(:disabled) {
  background: var(--gray-100);
}

#publishButton:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

#publishButton:focus-visible {
  outline: none;
}

#publishButton svg {
  width: 16px;
  height: 16px;
}

/* Studio ヘッダーの副ボタン「…」（founder 2026-09-17）: 塗りなし・灰色のアイコンだけ。
   赤くしない（主役の「投稿」と競合させない）。主ボタン側は css/routes/editor.css。
   ここ（critical）に置く理由: scripts/route-css-pinned.json が .publish-menu-btn を据え置き指定している。 */
.publish-menu-btn {
  position: relative; /* クリップ完成バッジ（absolute）の基準 */
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: var(--r-full);
  color: var(--gray-600);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

/* :hover / [aria-expanded] / :active / :focus-visible / svg / バッジ位置 は css/routes/editor.css
   （台帳が据え置き指定しているのは素の .publish-menu-btn だけ。修飾付きは分割スクリプトが editor バンドルへ振る）。 */

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}

/* ===== Chat Messages ===== */
.chat-messages {
  flex: 1 1 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--s-16);
  padding-bottom: var(--s-32);
  display: flex;
  flex-direction: column;
  gap: var(--s-12);
  position: relative;
}

/* Extra space at bottom for scroll visibility */
.chat-messages::after {
  content: '';
  display: block;
  height: var(--s-16);
  flex-shrink: 0;
}

/* Message Bubbles */
.message {
  max-width: 85%;
  padding: var(--s-16) var(--s-24);
  border-radius: var(--r-24);
  font-size: 0.9375rem;
  line-height: 1.6;
  animation: messageIn 0.4s var(--ease-out);
}

/* AI返信のマークダウン: ブラウザ既定の ul/p マージンだと吹き出しが縦に
   間延びするため、チャットバブル内はコンパクトに詰める */
.message p {
  margin: 0 0 0.5em;
}

.message p:last-child {
  margin-bottom: 0;
}

.message ul {
  margin: 0.25em 0 0.5em;
  padding-left: 1.25em;
}

.message ul:last-child {
  margin-bottom: 0;
}

.message li {
  margin: 0.15em 0;
}

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

.message.user {
  background: var(--red);
  color: var(--white);
  align-self: flex-end;
  border-bottom-right-radius: var(--r-8);
  box-shadow: 0 4px 16px var(--red-glow);
}

.message.assistant {
  background: var(--glass-white-strong);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--glass-border);
  color: var(--gray-900);
  align-self: flex-start;
  border-bottom-left-radius: var(--r-8);
  box-shadow: var(--glass-shadow);
}

.message.system {
  background: var(--gray-100);
  color: var(--gray-600);
  align-self: center;
  font-size: 0.875rem;
  max-width: 100%;
  text-align: center;
}

.message.error {
  background: rgba(255, 59, 48, 0.1);
  color: var(--red);
  border: 1px solid rgba(255, 59, 48, 0.2);
}

/* Code Blocks */
.message pre {
  background: var(--gray-900);
  color: var(--gray-100);
  padding: var(--s-16);
  border-radius: var(--r-12);
  margin-top: var(--s-12);
  overflow-x: auto;
  font-family: 'SF Mono', Monaco, monospace;
  font-size: 0.8125rem;
}

.message code {
  font-family: 'SF Mono', Monaco, monospace;
  font-size: 0.875em;
  background: var(--gray-100);
  padding: 2px 6px;
  border-radius: var(--r-8);
}

.message.user code {
  background: rgba(255, 255, 255, 0.2);
}

/* Gemini Code Display */
.message.gemini-code {
  background: var(--glass-white-strong);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--glass-border);
  padding: 0;
  overflow: hidden;
}

.gemini-header {
  background: var(--gray-900);
  color: var(--white);
  padding: var(--s-12) var(--s-16);
  font-weight: 600;
  font-size: 0.8125rem;
  display: flex;
  align-items: center;
  gap: var(--s-8);
}

.gemini-header::before {
  content: "✦";
  color: var(--red);
}

.gemini-code-block {
  background: var(--gray-900);
  padding: var(--s-16);
  overflow-x: auto;
  max-height: 400px;
}

.gemini-code-block pre {
  margin: 0;
  background: transparent;
  padding: 0;
}

.gemini-code-block code {
  font-family: 'SF Mono', Monaco, monospace;
  font-size: 0.8125rem;
  color: var(--gray-100);
  background: transparent;
  padding: 0;
  line-height: 1.7;
}

.gemini-code-block code.diff-old {
  display: block;
  background: rgba(255, 59, 48, 0.15);
  color: #FF6B6B;
  padding: var(--s-8);
  border-radius: var(--r-8);
  margin-bottom: var(--s-8);
}

.gemini-code-block code.diff-new {
  display: block;
  background: rgba(52, 199, 89, 0.15);
  color: #6EE7A8;
  padding: var(--s-8);
  border-radius: var(--r-8);
}

/* ===== Welcome Message ===== */

/* ===== Remix Success Message ===== */

/* ===== Input Area ===== */

.attached-assets.hidden {
  display: none;
}

/* The visual "pill" has moved to .chat-input-wrapper; the textarea is
   now a transparent text surface inside it. */

/* Chat input wrapper — this is the visual "pill".
   Default: a single row holding the textarea.
   ガイドなし ON: a second row appears inside this same pill,
   revealing the red chip. The container literally announces
   the mode rather than tacking a label beside it. */

/* Expand button pinned to top-right so it never collides with the
   chip row when the pill grows. */

.button-row {
  display: flex;
  gap: var(--s-8);
  margin-top: var(--s-12);
}

/* ===== Mobile Plus Menu ===== */

.plus-menu-btn:hover {
  transform: scale(1.05);
  box-shadow: 0 4px 12px rgba(221, 160, 221, 0.4);
}

.plus-menu-btn:active {
  transform: scale(0.95);
}

.plus-menu-btn.active {
  transform: rotate(45deg);
  background: linear-gradient(135deg, #DDA0DD 0%, #FFB6C1 100%);
}

/* Plus menu popup — Kashiwa Sato × Nintendo:
   pure white surface, confident shadow, no glass noise. */

.plus-menu-popup.hidden {
  display: none;
}

.plus-menu-character-context.hidden {
  display: none;
}

/* Stronger breathing room before destructive "Delete save data".
   Horizontal inset keeps the rule visually paired with its neighbours
   instead of splitting the card edge-to-edge. */

/* ─────────────────────────────────────────────
   Guide mode — "ガイドなし" toggle
   ON state = Nintendo red, consistent across
   three surfaces (menu row, badge, desktop btn).
   ───────────────────────────────────────────── */

/* Menu row: ON state — row tints red, icon fills red. */
.plus-menu-item.generation-mode-menu-item.active {
  background: var(--red-light);
  color: var(--red);
}

.plus-menu-item.generation-mode-menu-item.active .plus-menu-item-text small {
  color: var(--gray-600);
}

/* Pre-send chip: lives inside the input pill. Its appearance is
   the mode's signal — the pill literally grows to make room for it. */

.generation-mode-badge.hidden {
  display: none;
}

.input-extras button.generation-mode-desktop-toggle.active:hover {
  background: var(--red);
  border-color: var(--red);
  filter: brightness(1.05);
}

.image-menu-btn.active {
  background: linear-gradient(135deg, #98D8C8 0%, #87CEEB 100%);
}

.image-menu-popup.hidden {
  display: none;
}

/* Mobile styles */

/* ===== Streaming Container ===== */
.streaming-container {
  flex-shrink: 0;
  margin: var(--s-16);
  background: var(--glass-white-strong);
  backdrop-filter: blur(var(--blur));
  -webkit-backdrop-filter: blur(var(--blur));
  border: 1px solid var(--glass-border);
  border-radius: var(--r-16);
  overflow: hidden;
}

/* ===== Preview Panel ===== */
.preview-panel {
  flex: 1;
  height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--gray-50);
  min-width: 0;
  overflow: hidden;
}

.preview-header {
  flex-shrink: 0;
  padding: var(--s-16) var(--s-24);
  background: var(--white);
  border-bottom: 1px solid var(--gray-200);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

#previewTitle {
  font-size: 1rem;
  font-weight: 700;
  color: var(--gray-900);
}

.preview-actions {
  display: flex;
  gap: var(--s-8);
  overflow: visible;
}

.preview-actions button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-4);
  padding: var(--s-8) var(--s-12);
  background: var(--gray-100);
  border: none;
  border-radius: var(--r-8);
  color: var(--gray-600);
  font-size: 0.8125rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
}

.preview-actions button:hover {
  background: var(--gray-200);
  color: var(--gray-900);
}

.preview-actions button svg {
  width: 16px;
  height: 16px;
}

/* ===== Version Panel ===== */

.version-panel.hidden {
  transform: translateX(100%);
  pointer-events: none;
}

/* Mobile: Version panel as full-screen overlay */
@media (max-width: 768px) {

  .version-panel.hidden {
    transform: translateY(100%);
  }

}

.version-changes-inline.hidden {
  display: none;
}

/* ===== Modals ===== */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 5000;
  opacity: 0;
  visibility: hidden;
  transition: all 0.3s ease;
}

.modal-overlay.visible {
  opacity: 1;
  visibility: visible;
}

.modal-content {
  background: var(--white);
  border-radius: var(--r-24);
  width: 90%;
  max-width: 480px;
  max-height: 85vh;
  overflow: hidden;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.2);
  transform: scale(0.95) translateY(20px);
  transition: transform var(--duration) var(--ease-out);
}

.modal-overlay.visible .modal-content {
  transform: scale(1) translateY(0);
}

.modal-header {
  padding: var(--s-24);
  border-bottom: 1px solid var(--gray-200);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.modal-header h2 {
  font-size: 1.25rem;
  font-weight: 700;
}

.modal-close {
  width: 36px;
  height: 36px;
  border-radius: var(--r-8);
  background: var(--gray-100);
  border: none;
  font-size: 1.25rem;
  cursor: pointer;
  color: var(--gray-600);
  transition: all 0.2s ease;
}

.modal-close:hover {
  background: var(--gray-200);
  color: var(--gray-900);
}

.modal-body {
  padding: var(--s-24);
  overflow-y: auto;
  max-height: 60vh;
}

.modal-footer {
  padding: var(--s-24);
  border-top: 1px solid var(--gray-200);
  display: flex;
  gap: var(--s-12);
  justify-content: flex-end;
}

/* ===== Image Generation Modal ===== */

/* ===== Back to Chat Button (Mobile only) ===== */
.back-to-chat-btn {
  display: none;
  align-items: center;
  gap: var(--s-8);
  padding: var(--s-8) var(--s-16);
  background: var(--gray-100);
  border: none;
  border-radius: var(--r-12);
  color: var(--gray-600);
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s ease;
}

.back-to-chat-btn:hover {
  background: var(--gray-200);
  color: var(--gray-900);
}

.back-to-chat-btn svg {
  width: 20px;
  height: 20px;
}

/* ===== Style Selection ===== */

/* ===== Photo Choice Cards（Before/After 図解カード） =====
   founder決定 2026-07-29: 従来のテキスト7択ピルは初心者に違いが判別不能だったため、
   図解カードUIに置き換え。.style-scroll-container/.style-scroll-track（横スクロール
   ストリップの構造）はスタイル選択カードと共有し、カード本体だけ専用クラスにする
   （幅がスタイルカードの140pxより大きい168px = 2コマ図解が判読できるサイズのため）。 */

/* 画像未着（onerror）時のフォールバック: カード自体は消さずテキストピルへ劣化させる。
   onerror ハンドラ（app.js displayPhotoChoice）が img を remove() し、このクラスを
   付与する。選択肢が消えるとユーザーが詰むため、カードのdisabled化はせず常に
   クリック可能な状態を保つ（画像なしでもラベルクリックで選択できる）。 */

/* style-selection-message と同じ流儀でメッセージ全幅化。photo-choice も横スクロール
   ストリップを持つため、モバイルの .message{max-width:90%} を上書きして全幅にする
   （390px 幅で 168px カード2枚 + 次カードのチラ見えが見えるようにする） */

/* ===== Responsive ===== */
@media (max-width: 768px) {
  body {
    height: 100vh;
    height: 100dvh;
  }

  .container {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    height: auto;
    flex-direction: column;
  }

  .chat-panel {
    width: 100%;
    min-width: 0;
    flex: 1;
    min-height: 0;
    border-right: none;
  }

  .chat-header {
    padding-top: calc(var(--s-16) + var(--page-safe-top, var(--safe-top, 0px)));
  }

  .chat-panel.mobile-hidden {
    display: none;
  }

  .preview-panel {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 50;
    display: none;
  }

  .preview-panel.mobile-active {
    display: flex;
  }

  .preview-header {
    padding-top: calc(var(--s-16) + var(--page-safe-top, var(--safe-top, 0px)));
  }

  .back-to-chat-btn {
    display: flex;
  }

  .chat-header h1 {
    font-size: 1.125rem;
  }

  .message {
    max-width: 90%;
  }

  /* Project List View - Mobile */
  .list-header {
    padding: var(--s-12) var(--s-16);
    padding-top: calc(var(--s-12) + var(--page-safe-top, var(--safe-top)));
  }

  .brand-text {
    font-size: 1rem;
  }

  .create-hero {
    padding: var(--s-24) var(--s-16) var(--s-12);
  }

  .games-section {
    padding: 0 var(--s-16) var(--bottom-nav-reserved-space-comfy);
  }

  .project-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--s-8);
  }

  .project-card {
    background: var(--white);
    border-color: var(--gray-200);
  }

  .project-card-thumbnail {
    aspect-ratio: 1 / 1;
  }

  .project-card-header {
    padding: var(--s-8) var(--s-8) 0;
  }

  .project-card-meta {
    gap: var(--s-6);
    padding: var(--s-4) var(--s-8) var(--s-8);
  }

  .project-card-title {
    font-size: 0.875rem;
  }

  .project-card-date {
    font-size: 0.6875rem;
  }

  .project-card-thumbnail-placeholder {
    padding: var(--s-8);
  }

  .project-card-thumbnail-placeholder .placeholder-title {
    font-size: 0.875rem;
    -webkit-line-clamp: 3;
  }

  /* Show red dot by default on mobile */
  .project-card::before {
    opacity: 1;
    transform: scale(1);
  }

  .project-card:active {
    transform: scale(0.98);
    background: var(--gray-50);
  }
}

@media (max-width: 480px) {
  .chat-header h1 {
    font-size: 1rem;
  }

}

/* ===== iOS Keyboard Fix ===== */
/* iOS Safari uses sticky instead of JS-controlled fixed positioning */
@supports (-webkit-touch-callout: none) {
  @media (max-width: 768px) {
    .container {
      position: relative;
      height: 100dvh;
    }

    .chat-panel {
      display: flex;
      flex-direction: column;
      height: 100%;
    }

    .chat-input-container {
      position: sticky;
      bottom: 0;
      padding-bottom: max(var(--s-16), var(--page-safe-bottom, var(--safe-bottom, 0px)));
      background: white;
    }
  }
}

/* ===== High Contrast Mode ===== */
@media (prefers-contrast: high) {
  :root {
    --glass-white: rgba(255, 255, 255, 0.95);
    --glass-border: var(--gray-400);
  }
}

/* ===== Reduced Motion ===== */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ===== Login View ===== */
.login-view {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-24);
}

.login-container {
  width: 100%;
  max-width: 400px;
  background: var(--glass-white-strong);
  backdrop-filter: blur(var(--blur));
  -webkit-backdrop-filter: blur(var(--blur));
  border: 1px solid var(--glass-border);
  border-radius: var(--r-24);
  padding: var(--s-48);
  box-shadow: var(--glass-shadow);
}

.login-header {
  text-align: center;
  margin-bottom: var(--s-32);
}

.login-header h1 {
  font-size: 1.75rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--gray-900);
  margin-bottom: var(--s-8);
}

.login-subtitle {
  font-size: 0.875rem;
  color: var(--gray-400);
  font-weight: 500;
}

.login-form {
  display: flex;
  flex-direction: column;
  gap: var(--s-24);
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: var(--s-8);
}

.form-group label {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--gray-600);
}

.form-group input {
  padding: var(--s-16);
  background: var(--white);
  border: 2px solid var(--gray-200);
  border-radius: var(--r-12);
  font-family: inherit;
  font-size: 1rem;
  outline: none;
  transition: all 0.2s ease;
}

.form-group input:focus {
  border-color: var(--red);
  box-shadow: 0 0 0 4px var(--red-light);
}

.form-group input::placeholder {
  color: var(--gray-400);
}

.login-error {
  padding: var(--s-12) var(--s-16);
  background: rgba(255, 59, 48, 0.1);
  border: 1px solid rgba(255, 59, 48, 0.2);
  border-radius: var(--r-12);
  color: var(--red);
  font-size: 0.875rem;
  font-weight: 500;
  text-align: center;
}

.login-button {
  padding: var(--s-16) var(--s-24);
  background: var(--red);
  border: none;
  border-radius: var(--r-12);
  color: var(--white);
  font-size: 1rem;
  font-weight: 600;
  cursor: pointer;
  transition: all var(--duration) var(--ease-out);
  box-shadow: 0 4px 12px var(--red-glow);
}

.login-button:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px var(--red-glow);
}

.login-button:active:not(:disabled) {
  transform: translateY(0);
}

.login-button:disabled {
  background: var(--gray-200);
  color: var(--gray-400);
  box-shadow: none;
  cursor: not-allowed;
}

/* User Info in Header */
.user-info {
  display: flex;
  align-items: center;
  gap: var(--s-12);
}

.user-name {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--gray-600);
}

.logout-btn {
  padding: var(--s-8) var(--s-12);
  background: transparent;
  border: 1px solid var(--gray-200);
  border-radius: var(--r-8);
  color: var(--gray-600);
  font-size: 0.75rem;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
}

.logout-btn:hover {
  border-color: var(--gray-400);
  color: var(--gray-900);
  background: var(--gray-50);
}

@media (max-width: 480px) {
  .login-container {
    padding: var(--s-32);
  }

  .login-header h1 {
    font-size: 1.5rem;
  }
}

/* ===== Input Buttons ===== */

/* ===== Modal Base ===== */
.modal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal.hidden {
  display: none;
}

.modal .modal-content {
  background: var(--white);
  border-radius: var(--r-24);
  width: 90%;
  max-width: 640px;
  max-height: 85vh;
  overflow: hidden;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.2);
}

.modal .modal-header {
  padding: var(--s-24);
  border-bottom: 1px solid var(--gray-200);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.modal .modal-header h3 {
  font-size: 1.25rem;
  font-weight: 700;
}

.modal .modal-close {
  width: 36px;
  height: 36px;
  border-radius: var(--r-8);
  background: var(--gray-100);
  border: none;
  font-size: 1.5rem;
  cursor: pointer;
  color: var(--gray-600);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.modal .modal-close:hover {
  background: var(--gray-200);
  color: var(--gray-900);
}

/* ===== New Game Modal - Nintendo × Kashiwa Sato ===== */

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

@keyframes modalSlideUp {
  from {
    opacity: 0;
    transform: translateY(24px) scale(0.96);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* AutoFix 確認モーダル（founder 指示 2026-08-27②: 可愛くポップに出現 + ゲーム中の
   誤タップ対策）。overshoot 付きバウンス = 「エラー出ちゃった、てへ」のトーン。
   出現中は .dc-armed が付くまで pointer-events を切る（app.js が 450ms 後に付与）—
   ゲームを連打している指がそのままボタンを押してしまう事故のガード。
   overlay（.new-game-modal 側）は最初からタッチを吸うので、ゲームへの誤入力は無い */

@keyframes autofixConfirmPop {
  0% { opacity: 0; transform: scale(0.5) rotate(-3deg); }
  60% { opacity: 1; transform: scale(1.06) rotate(1.5deg); }
  80% { transform: scale(0.97) rotate(-0.5deg); }
  100% { opacity: 1; transform: scale(1) rotate(0deg); }
}

@keyframes autofixConfirmWiggle {
  0%, 100% { transform: rotate(0deg); }
  25% { transform: rotate(-8deg); }
  50% { transform: rotate(8deg); }
  75% { transform: rotate(-4deg); }
}
@media (prefers-reduced-motion: reduce) {

  /* アニメを切っても誤タップガード（450ms 後の .dc-armed）はそのまま効く */
}

.character-mini-card-add {
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  flex: 0 0 auto;
  padding: 0 var(--s-12);
  border: 2px dashed #D8D6D0;
  border-radius: var(--r-8);
  background: #FAFAF7;
  color: #555A62;
  font-weight: 900;
  cursor: pointer;
}

.character-mini-card-add:hover {
  border-color: #FF3933;
  color: #101114;
  background: #FFF7F6;
}

@keyframes character-project-orbit {
  to { transform: rotate(calc(var(--a, 0deg) + 360deg)) translateX(20px); }
}

.character-style-picker-heading {
  margin: 0 0 var(--s-4);
  color: var(--gray-900);
  font-size: 0.86rem;
  font-weight: 800;
}

/* 1枚だけの時は主役として大きく (高さに余裕がある時のみ) */
.character-modal-preview-grid.is-single img {
  width: clamp(160px, 46vw, 220px);
  height: clamp(160px, 46vw, 220px);
  border-radius: var(--r-16);
}

.character-modal-preview-strip {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-8);
  margin: 0 0 var(--s-20);
}

.character-modal-preview-strip img {
  width: 64px;
  height: 64px;
  object-fit: cover;
  border-radius: var(--r-12);
  border: 1px solid var(--gray-200);
}

.character-modal-preview-strip.is-single img {
  width: 96px;
  height: 96px;
}

.character-upload-change {
  display: block;
  margin-top: var(--s-10);
  text-align: center;
  color: var(--gray-600);
  font-size: 0.78rem;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
}

@media (max-width: 520px) {

  /* .character-style-picker is now flex column at all sizes — no breakpoint override needed */
}

/* ===== Asset Modal ===== */

/* Prevent iOS Safari/WKWebView focus-zoom in asset library search */

@keyframes audio-spin {
  to { transform: rotate(360deg); }
}

.upload-area:hover {
  border-color: var(--red);
  background: var(--red-light);
}

.upload-area.dragging {
  border-color: var(--red);
  background: var(--red-light);
}

/* Prevent iOS Safari/WKWebView focus-zoom in asset upload form inputs */

@keyframes upload-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* ===== Asset Footer - Nintendo + Sato Kashiwa Style ===== */

.icon-btn {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1.5px solid var(--gray-300);
  background: var(--white);
  color: var(--gray-500);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s ease;
  flex-shrink: 0;
}

.icon-btn:hover {
  border-color: var(--gray-400);
  background: var(--gray-100);
  color: var(--gray-800);
}

.icon-btn:active {
  transform: scale(0.95);
}

.icon-btn svg {
  width: 20px;
  height: 20px;
}

/* Ghost button (edit) - Secondary text action */
.ghost-btn {
  height: 44px;
  padding: 0 var(--s-16) 0 0;
  background: transparent;
  border: 1.5px solid var(--gray-300);
  border-radius: 22px;
  color: var(--gray-600);
  font-weight: 600;
  font-size: 0.875rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-6);
  transition: all 0.2s ease;
  flex-shrink: 0;
}

.ghost-btn:hover {
  border-color: var(--gray-500);
  background: var(--gray-100);
  color: var(--gray-900);
}

.ghost-btn:active {
  transform: scale(0.97);
}

.ghost-btn svg {
  width: 18px;
  height: 18px;
}

/* Mobile adjustments */
@media (max-width: 600px) {

  .icon-btn {
    width: 38px;
    height: 38px;
  }

  .icon-btn svg {
    width: 18px;
    height: 18px;
  }

  .ghost-btn {
    height: 40px;
    padding: 0 var(--s-12) 0 0;
    font-size: 0.8125rem;
  }

}

/* ===== Image Editor Modal ===== */

/* 保存中（2026-09-01）: 読み込み中と違い編集結果を隠さない —
   半透明オーバーレイ + スピナーで「処理は進んでいる」ことだけ伝える */

/* Only the original preview <img> (direct child) — NOT Cropper's internal .cropper-canvas img,
   which Cropper sizes itself. Constraining that one with max-width desyncs Cropper's coordinate
   math from the rendered image, so the crop box can't reach the true image edges. */

/* 2026-08-31 「クロップが機能しない」対策:
   見た目のハンドル（上の 4px バー/L字）はそのまま、::before で透明な当たり判定だけ
   40px 四方に拡張する。実測でエッジハンドルの命中域が 4-6px しかなく、マウスでも
   数px外すと掴めない・指では実質不可能だった。擬似要素へのクリックはイベント上
   親の .cropper-point が target になるため、Cropper の data-cropper-action 解決は
   そのまま機能する（Cropper 本体の改造は不要）。 */

.crop-overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  touch-action: none;
}

.crop-overlay.active {
  pointer-events: auto;
  z-index: 50;
}

.tool-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: var(--s-8) var(--s-12);
  background: var(--gray-100);
  border: 2px solid transparent;
  border-radius: var(--r-8);
  cursor: pointer;
  transition: all 0.2s ease;
  min-width: 64px;
  flex-shrink: 0;
}

.tool-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.tool-btn:disabled:hover {
  background: var(--gray-100);
}

.tool-btn:hover {
  background: var(--gray-200);
}

.tool-btn[data-tool].active {
  background: var(--red-light);
  border-color: var(--red);
  color: var(--red);
}

.tool-btn svg {
  width: 24px;
  height: 24px;
}

.tool-btn span {
  font-size: 0.75rem;
  font-weight: 600;
}

.panel-title {
  font-weight: 600;
  margin-bottom: var(--s-12);
  color: var(--gray-700);
}

.rotate-buttons {
  display: flex;
  gap: var(--s-8);
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.bg-error-message {
  margin-top: var(--s-12);
  padding: var(--s-12);
  background: rgba(220, 53, 69, 0.1);
  border: 1px solid rgba(220, 53, 69, 0.2);
  border-radius: var(--radius-md);
  color: #dc3545;
  font-size: 0.8125rem;
  text-align: center;
}

/* Background removal threshold control */
.bg-threshold-control {
  margin-bottom: var(--s-16);
}

.secondary-btn {
  padding: var(--s-12) var(--s-20);
  background: var(--white);
  border: 1.5px solid var(--gray-300);
  border-radius: var(--r-8);
  color: var(--gray-700);
  font-weight: 600;
  font-size: 0.9375rem;
  cursor: pointer;
  transition: all 0.2s ease;
}

.secondary-btn:hover {
  background: var(--gray-100);
  border-color: var(--gray-400);
}

.secondary-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.primary-btn {
  padding: var(--s-12) var(--s-24);
  background: var(--red);
  border: none;
  border-radius: var(--r-8);
  color: var(--white);
  font-weight: 600;
  font-size: 0.9375rem;
  cursor: pointer;
  transition: all 0.2s ease;
}

.primary-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px var(--red-glow);
}

/* ===== Mobile Image Editor - Instagram/X Style (Light) ===== */
@media (max-width: 768px) {

  /* Ensure crop overlay covers canvas properly on mobile */
  .crop-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    touch-action: none;
  }

  /* Tool buttons */
  .tool-btn {
    flex: 0 0 auto;
    min-width: 56px;
    padding: var(--s-8) var(--s-8);
    background: transparent;
    border: none;
    border-radius: 0;
    color: var(--gray-500);
    transition: all 0.15s ease;
    position: relative;
  }

  .tool-btn:disabled {
    opacity: 0.35;
  }

  .tool-btn::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 0;
    height: 2px;
    background: var(--red);
    transition: width 0.2s ease;
  }

  .tool-btn:hover,
  .tool-btn:active {
    background: var(--gray-50);
    color: var(--gray-700);
  }

  .tool-btn[data-tool].active {
    color: var(--red);
    background: transparent;
  }

  .tool-btn[data-tool].active::after {
    width: 24px;
  }

  .tool-btn svg {
    width: 24px;
    height: 24px;
    stroke-width: 1.5;
  }

  .tool-btn span {
    font-size: 0.625rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    margin-top: var(--s-4);
  }

  .panel-title {
    color: var(--gray-800);
    font-size: 0.875rem;
    font-weight: 600;
    margin-bottom: var(--s-12);
    text-align: center;
    padding-top: var(--s-4);
  }

  /* Rotate buttons */
  .rotate-buttons {
    display: flex;
    gap: var(--s-8);
    justify-content: center;
  }

  /* `.image-editor-footer .secondary-btn` 系は /css/deferred-modals.css に居る（分割時の順序反転対策の :hover/:disabled もそちら） */

  .secondary-btn:hover {
    background: var(--gray-200);
  }

  .secondary-btn:disabled {
    color: var(--gray-400);
    background: var(--gray-50);
  }

  .primary-btn {
    padding: var(--s-10) var(--s-20);
    background: var(--red);
    color: var(--white);
    border-radius: 8px;
    font-size: 0.875rem;
    font-weight: 600;
  }

  .primary-btn:hover {
    transform: none;
    box-shadow: none;
    opacity: 0.9;
  }

}

/* ===== Image Generation Modal ===== */

@media (max-width: 768px) {

  .option-label {
    font-size: 0.625rem;
  }

}

.form-label {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--gray-600);
}

.option-label {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--gray-400);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.spinner {
  width: 40px;
  height: 40px;
  border: 3px solid var(--gray-200);
  border-top-color: var(--red);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* ===== Preview Container ===== */
.preview-container {
  flex: 1 1 0;
  position: relative;
  overflow: hidden;
}

/* ===== Error Panel ===== */

.error-icon {
  color: var(--red);
}

.close-btn {
  width: 28px;
  height: 28px;
  background: transparent;
  border: none;
  border-radius: var(--r-8);
  color: var(--gray-600);
  font-size: 1.25rem;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.close-btn:hover {
  background: var(--gray-100);
  color: var(--gray-900);
}

.close-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ===== Game Status ===== */

/* ===== Game Preview iframe ===== */
#gamePreview {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: none;
  background: var(--white);
}

/* ===== Toggle Switch (Debug) ===== */

/* ===== Chat Suggestions (2Dで作成/3Dで作成 etc) ===== */

/* ===== Style Selection Custom/Skip ===== */

/* ===== Restore Buttons ===== */

/* ===== Markdown Body ===== */
.markdown-body {
  line-height: 1.6;
}

.markdown-body p {
  margin: 0 0 0.8em 0;
}

.markdown-body p:last-child {
  margin-bottom: 0;
}

.markdown-body h2,
.markdown-body h3,
.markdown-body h4 {
  margin: 1em 0 0.5em 0;
  color: var(--gray-900);
}

.markdown-body h2 { font-size: 1.2rem; }
.markdown-body h3 { font-size: 1.1rem; }
.markdown-body h4 { font-size: 1rem; }

.markdown-body strong {
  color: var(--gray-900);
}

.markdown-body code {
  background: var(--gray-100);
  padding: 2px 6px;
  border-radius: var(--r-8);
  font-family: 'SF Mono', Monaco, monospace;
  font-size: 0.9em;
  color: var(--red);
}

.markdown-body ul {
  margin: 0.5em 0;
  padding-left: 1.5em;
}

.markdown-body li {
  margin: 0.3em 0;
}

/* ===== Gemini Code Display Extended ===== */
.gemini-summary {
  padding: var(--s-8) var(--s-12);
  color: var(--gray-600);
  font-size: 0.85rem;
  border-bottom: 1px solid var(--gray-200);
}

.gemini-file {
  border-top: 1px solid var(--gray-200);
}

.gemini-file:first-of-type {
  border-top: none;
}

.gemini-file-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--s-8) var(--s-12);
  background: var(--gray-100);
}

.gemini-filename {
  font-family: 'SF Mono', Monaco, monospace;
  color: var(--red);
  font-size: 0.85rem;
}

.gemini-toggle {
  background: var(--gray-200);
  color: var(--gray-600);
  border: none;
  padding: var(--s-4) var(--s-8);
  border-radius: var(--r-8);
  cursor: pointer;
  font-size: 0.75rem;
  transition: all 0.2s ease;
}

.gemini-toggle:hover {
  background: var(--gray-300);
  color: var(--gray-900);
}

.gemini-code-block.collapsed {
  display: none;
}

/* ===== Preset Buttons (Mobile) ===== */
.preset-buttons {
  display: none;
  padding: var(--s-8) var(--s-12);
  background: var(--glass-white);
  border-top: 1px solid var(--glass-border);
  overflow-x: auto;
  white-space: nowrap;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.preset-buttons::-webkit-scrollbar {
  display: none;
}

.preset-btn {
  display: inline-block;
  padding: var(--s-8) var(--s-16);
  background: var(--white);
  border: 1px solid var(--gray-200);
  border-radius: var(--r-full);
  color: var(--gray-600);
  font-size: 0.8125rem;
  cursor: pointer;
  transition: all 0.2s ease;
  margin-right: var(--s-8);
}

.preset-btn:hover {
  border-color: var(--red);
  color: var(--red);
}

/* ===== Scrollbar Styling ===== */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: var(--gray-100);
}

::-webkit-scrollbar-thumb {
  background: var(--gray-300);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--gray-400);
}

/* ===== Code Viewer Modal ===== */

/* ===== Version Restore Modal - Nintendo × Kashiwa Sato ===== */

/* ===== 「作り方を公開」ダイアログ（#chatShareModal の中身だけ）=====
   枠（背景・カード・ヘッダー・下部アクション）は上の .restore-modal 系を
   そのまま使う。ここにあるのは「確認2択のモーダル」には無い部品 ―― トグル・
   リンク欄・注記 ―― の分だけ。値は public/project-view.html にあった共有
   パネル（.pv-share-*）から持ってきたもので、見た目を作り直したわけではない
   （2026-08-02 に共有 UI をビューアからエディタへ移設した際の引っ越し）。 */

/* ============================================
   Bottom Navigation Bar (SNS-style)
   ============================================ */
/* 下ナビ本体（.bottom-nav / .nav-item）の見た目は 2026-09-23 に css/modules/navigation.css へ移した
   （game.html・guestbook*.html にあった写しと合わせて 1 箇所に集約）。ここに戻さないこと。
   このファイルに残すのは、ページごとの「下ナビの下の安全領域の棚」（下の body[data-page]::after）だけ。 */

/* Safe-area shelf under floating bottom nav (iOS viewport-fit=cover) */
body[data-page="create"]::after,
body[data-page="discover"]::after,
body[data-page="notifications"]::after,
body[data-page="mypage"]::after,
body[data-page="profile"]::after,
body[data-page="characters"]::after,
body[data-page="character-play"]::after,
body[data-page="timeline"]::after,
body[data-page="photo-remix"]::after {
  content: '';
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  height: max(0px, calc(var(--safe-bottom) - 16px));
  background: var(--nav-shelf-bg, rgba(248, 248, 248, 0.72));
  backdrop-filter: blur(14px) saturate(130%);
  -webkit-backdrop-filter: blur(14px) saturate(130%);
  pointer-events: none;
  z-index: 120;
}

body[data-page="create"] { --nav-shelf-bg: rgba(255, 255, 255, 0.74); }
body[data-page="discover"] { --nav-shelf-bg: rgba(250, 250, 250, 0.74); }
body[data-page="notifications"] { --nav-shelf-bg: rgba(255, 255, 255, 0.74); }
body[data-page="mypage"] { --nav-shelf-bg: rgba(248, 248, 248, 0.74); }
body[data-page="profile"] { --nav-shelf-bg: rgba(248, 248, 248, 0.74); }
body[data-page="characters"] { --nav-shelf-bg: rgba(255, 255, 255, 0.74); }
body[data-page="character-play"] { --nav-shelf-bg: rgba(255, 255, 255, 0.74); }
body[data-page="timeline"] { --nav-shelf-bg: rgba(253, 251, 247, 0.74); }
body[data-page="photo-remix"] { --nav-shelf-bg: rgba(250, 248, 244, 0.74); }

/* ============================================
   Discover View
   ============================================ */
.discover-view {
  position: fixed;
  inset: 0;
  background: var(--gray-50);
  padding-bottom: var(--bottom-nav-reserved-space);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.discover-header {
  position: sticky;
  top: 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  padding-top: calc(16px + var(--page-safe-top, var(--safe-top, 0px)));
  background: var(--glass-white-strong);
  backdrop-filter: blur(var(--blur));
  -webkit-backdrop-filter: blur(var(--blur));
  border-bottom: 1px solid var(--glass-border);
  z-index: 10;
}

.discover-header h1 {
  font-size: 24px;
  font-weight: 800;
  color: var(--gray-900);
}

.search-btn {
  width: 40px;
  height: 40px;
  border-radius: var(--r-full);
  background: var(--gray-100);
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--gray-600);
  cursor: pointer;
  transition: background 0.2s ease;
}

.search-btn:active {
  background: var(--gray-200);
}

.discover-content {
  padding: 16px;
}

.discover-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

.discover-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 64px 20px;
  color: var(--gray-400);
  text-align: center;
}

.discover-empty svg {
  margin-bottom: 16px;
  opacity: 0.5;
}

.discover-empty p {
  font-size: 14px;
}

/* ============================================
   Zapping Mode (Fullscreen Game Carousel)
   ============================================ */
.zapping-mode {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: var(--bottom-nav-reserved-space);
  background: var(--gray-100);
  z-index: 1500;
  display: flex;
  flex-direction: column;
  animation: fadeIn 0.3s var(--ease-out);
}

/* Top bar - glass morphism */
.zapping-topbar {
  height: 56px;
  padding: 0 12px;
  padding-top: var(--page-safe-top, var(--safe-top, 0px));
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--glass-white-strong);
  backdrop-filter: blur(var(--blur));
  -webkit-backdrop-filter: blur(var(--blur));
  border-bottom: 1px solid var(--glass-border);
  flex-shrink: 0;
}

.zapping-back {
  width: 40px;
  height: 40px;
  border-radius: var(--r-full);
  background: transparent;
  border: none;
  color: var(--gray-900);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.2s ease;
}

.zapping-back:active {
  background: var(--gray-200);
}

.zapping-topbar-info {
  flex: 1;
  min-width: 0;
}

.zapping-game-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--gray-900);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.zapping-creator {
  font-size: 12px;
  color: var(--gray-600);
}

.zapping-topbar-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}

.zapping-topbar-action {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 8px 12px;
  background: transparent;
  border: none;
  color: var(--gray-900);
  cursor: pointer;
  border-radius: var(--r-12);
  transition: background 0.2s ease;
}

.zapping-topbar-action:active {
  background: var(--gray-200);
}

.zapping-topbar-action svg {
  width: 20px;
  height: 20px;
}

.zapping-topbar-action span {
  font-size: 13px;
  font-weight: 500;
}

.zapping-topbar-action.liked svg {
  fill: var(--red);
  stroke: var(--red);
}

.zapping-container {
  flex: 1;
  position: relative;
  overflow: hidden;
  touch-action: pan-y;
  margin: 12px;
  margin-top: 0;
  border-radius: var(--r-16);
  box-shadow: var(--glass-shadow);
}

/* Nav zapping button - accent style */
.nav-zapping {
  color: var(--red);
  background: var(--red-light);
}

.nav-zapping svg {
  stroke: var(--red);
}

.nav-zapping span {
  color: var(--red);
}

/* Zapping play overlay */
.zapping-play-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.3);
  z-index: 5;
  cursor: pointer;
  transition: opacity 0.3s ease;
}

.zapping-play-overlay.hidden {
  opacity: 0;
  pointer-events: none;
}

.zapping-play-btn {
  width: 80px;
  height: 80px;
  border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
}

.zapping-play-btn svg {
  width: 32px;
  height: 32px;
  color: var(--gray-900);
  margin-left: 4px;
}

/* Adjust existing views when bottom nav is visible */
.project-list-view.with-nav {
  padding-bottom: calc(var(--bottom-nav-reserved-space) + 20px);
}

/* Mobile adjustments for editor with bottom nav */
@media (max-width: 768px) {
  .container.with-nav {
    padding-bottom: var(--bottom-nav-reserved-space);
  }
}

/* ===== Message Buttons Container ===== */

/* ===== Message Share Button - Nintendo × Kashiwa Sato ===== */

/* ===== Changes Modal - Nintendo × Kashiwa Sato ===== */

/* Summary Card - Clean & Minimal */

/* Mobile Responsive */

/* ===========================================
   My Page - Nintendo Showcase Style
   "Fill Your Collection" Psychology
   =========================================== */

@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

@keyframes pulseGlow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 59, 48, 0.3); }
  50% { box-shadow: 0 0 20px 4px rgba(255, 59, 48, 0.15); }
}

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}

.mypage-view {
  height: 100%;
  height: 100dvh;
  background:
    radial-gradient(ellipse 100% 60% at 50% -20%, rgba(255, 59, 48, 0.06), transparent),
    linear-gradient(180deg, var(--white) 0%, var(--gray-50) 100%);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: var(--bottom-nav-reserved-space);
}

/* Header */
.mypage-header {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--s-12) var(--s-16);
  padding-top: calc(var(--s-12) + var(--page-safe-top, var(--safe-top, 0px)));
}

.mypage-header-title {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--gray-400);
  letter-spacing: 0.05em;
}

.mypage-header-spacer {
  width: 40px;
}

.mypage-back-btn {
  width: 40px;
  height: 40px;
  border-radius: var(--r-full);
  background: var(--white);
  border: 1px solid var(--gray-100);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--gray-500);
  cursor: pointer;
  transition: all 0.2s ease;
}

.mypage-back-btn:active {
  transform: scale(0.95);
  background: var(--gray-100);
}

/* ========================================
   Profile Section - Instagram Style
   ======================================== */

/* アバターの縁のリング。プレイXP（仕様 docs/PLAYER-XP-SPEC.md §6-1）でレベル内進捗を表す。
   --xp-pct = 現在のレベル内進捗（0-100 の無単位数）。自分のプロフィールでだけ JS が
   GET /api/me/xp の next.current / next.needed から入れる。他人のプロフィールでは 0 のまま
   ＝「他人の進み具合は見せない」（企画書§8-3 の裁定: 数字＝地位にしない）。

   WHY 3層構造か: 「0 のときは 2026-09-04 以前とまったく同じ見た目」を CSS だけで満たすため。
     クラス切り替え（.has-xp）でも書けるが、リングの見た目の分岐が JS 側の都合に依存し、
     HTML を読んだだけでは今どちらが出るのか分からなくなるので、値ひとつで決まる形にした。
   WHY color-mix を使わないか: iOS Safari 16.2 未満で宣言ごと無効になり、リングが消える
     （＝古い端末だけ壊れる）。min()/calc() なら 2020 年以降のブラウザで安全。 */
.mypage-avatar-ring {
  padding: 3px;
  background:
    /* 1層目: 進捗の弧。--xp-pct=0 なら長さ 0 で完全に見えない */
    conic-gradient(var(--red) calc(var(--xp-pct, 0) * 1%), transparent 0),
    /* 2層目: 進捗の「残り」を示すトラック。
       min(--xp-pct * 1000, 100) は「0 なら 0 / 0.1 以上なら 100」の階段関数として使っている。
       進捗が入っているときだけ一周させ、0 のときは長さ 0 にして 3 層目を素通しする */
    conic-gradient(var(--gray-200) 0 calc(min(var(--xp-pct, 0) * 1000, 100) * 1%), transparent 0),
    /* 3層目: 従来のブランドグラデ。--xp-pct が 0／未設定のときはこれだけが見える＝現状維持 */
    linear-gradient(135deg, var(--red), #FF6B6B);
  border-radius: var(--r-full);
}

.mypage-avatar {
  width: 80px;
  height: 80px;
  border-radius: var(--r-full);
  background: var(--gray-200);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--gray-500);
  overflow: hidden;
}

.mypage-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Lv.n チップ（プレイXP §6-1）。名前の下に小さく置く。
   WHY tabular-nums か: Lv.9 → Lv.10 で桁が増えたときに幅が跳ねてレイアウトが揺れるのを防ぐ。
   WHY 名前の右ではなく下の行か: .mypage-name は長い表示名で折り返す。同じ行に入れると
     チップだけが取り残されて「名前の一部」に見える事故が起きる。 */
.mypage-level {
  display: inline-block;
  /* 2026-09-05: このチップは <a href="/xp">（mypage）と <span>（他人のプロフィール）の
     両方で使う。アンカー側の既定の下線と青字を打ち消して、どちらでも同じ見た目にする。 */
  text-decoration: none;
  margin-bottom: var(--s-4);
  padding: 1px 8px;
  border-radius: var(--r-full);
  background: var(--gray-100);
  color: var(--gray-600);
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ⚠️ 必須（レビュー指摘 2026-09-05）。上の `display: inline-block` は作者スタイルなので、
   ブラウザ既定の `[hidden] { display: none }`（UAスタイル）に**勝ってしまう**。
   これが無いと、XPがOFF／未ログイン／サーバーが xp を返さない環境で
   `<span class="mypage-level" hidden>` が空チップとして名前の下に居座る
   （幅8px+背景ありの灰色の粒が残り、誰も理由が分からない）。
   game.html:567 の .action-btn[hidden] と同じ罠・同じ対処。
   JS 側（mypage.js / profile.js）は el.hidden の付け外しだけで出し分けている。 */
.mypage-level[hidden] {
  display: none;
}

/* リンクであることを見せる（レビュー指摘 2026-09-05（第2回）・C4）。
   このチップは mypage では <a href="/xp">、他人のプロフィールでは <span> で、
   上のルールが下線も色も消しているため、**押せることが誰にも分からなかった**
   （/xp への唯一の入口なのに、丸バッジ＝ただの状態表示にしか見えない）。
   WHY 下線を常時ではなく hover/focus か: チップは名前のすぐ下にある小さな飾りで、
     常時下線だと表示名より視覚的に強くなる。触れた瞬間だけリンクの顔を出す。
   WHY 山括弧（›）を足すか: hover を持たないタッチ端末には hover の下線が届かない。
     「この先がある」ことを静止状態でも伝えられるのは形だけ。擬似要素にしてあるので
     読み上げには乗らない（span 側には付かないので、他人のプロフィールは従来どおり）。 */
a.mypage-level::after {
  content: '\203A';   /* › — 半角スペースを挟まないよう margin で間を取る（日本語の行間ルール） */
  margin-left: 3px;
  font-weight: 700;
}

a.mypage-level:hover,
a.mypage-level:focus-visible {
  text-decoration: underline;
  color: var(--gray-900);
}

/* 儀式ゲートの1行ヒント（xp.hint.*）。Lv チップの直下に muted で1行だけ。
   WHY チップと別要素か: チップは幅の狭い丸バッジで、文章を入れると崩れる。
   WHY 常に1行か: 「次に何をすれば上がるか」を思い出させるだけの補助線で、
     プロフィールの主役（名前・作品）より目立ってはいけない。語「儀式」は出さない。 */

/* ========================================
   Guestbook Preview Card
   ======================================== */

/* ========================================
   Game Showcase - Miyamoto Style
   "触って楽しい、見て嬉しい"
   ======================================== */

@keyframes cardBounceIn {
  0% {
    opacity: 0;
    transform: translateY(24px) scale(0.92);
  }
  60% {
    opacity: 1;
    transform: translateY(-4px) scale(1.02);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes emptyPulse {
  0%, 100% {
    transform: scale(1);
    opacity: 0.6;
  }
  50% {
    transform: scale(1.05);
    opacity: 1;
  }
}

@keyframes iconBounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-6px); }
}

.mypage-plan-name.light { color: #4F46E5; }
.mypage-plan-name.unlimited { color: var(--red); }
.mypage-plan-name.team { color: #16A34A; }

.mypage-notification-section {
  padding: 0 var(--s-16);
  margin-bottom: var(--s-16);
}

.mypage-notification-groups {
  display: flex;
  flex-direction: column;
  gap: var(--s-8);
  margin-top: var(--s-12);
}

.mypage-notification-group {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-16);
  padding: var(--s-14, 14px) var(--s-16);
  background: var(--white);
  border: 1px solid var(--gray-200);
  border-radius: var(--r-12);
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;
}

.mypage-notification-group:hover {
  background: var(--gray-50);
}

.mypage-notification-group.is-disabled {
  opacity: 0.6;
  pointer-events: none;
}

.mypage-notification-group-copy {
  min-width: 0;
}

.mypage-notification-group-label {
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--gray-900);
  letter-spacing: -0.01em;
}

.mypage-notification-group-description {
  margin-top: 2px;
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--gray-500);
}

.mypage-switch {
  position: relative;
  flex-shrink: 0;
  width: 46px;
  height: 28px;
}

.mypage-switch input {
  position: absolute;
  inset: 0;
  opacity: 0;
  margin: 0;
}

.mypage-switch-track {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: var(--gray-200);
  transition: background 0.18s ease;
}

.mypage-switch-track::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--white);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.16);
  transition: transform 0.18s ease;
}

.mypage-switch input:checked + .mypage-switch-track {
  background: var(--red);
}

.mypage-switch input:checked + .mypage-switch-track::after {
  transform: translateX(18px);
}

.mypage-switch input:focus-visible + .mypage-switch-track {
  outline: 2px solid rgba(255, 59, 48, 0.28);
  outline-offset: 2px;
}

.mypage-notification-feedback {
  margin-top: var(--s-12);
  padding: var(--s-12) var(--s-16);
  border-radius: var(--r-12);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.4;
}

.mypage-notification-feedback[data-state="error"] {
  background: rgba(255, 59, 48, 0.08);
  color: #b42318;
  border: 1px solid rgba(255, 59, 48, 0.16);
}

/* Settings Page */
.settings-view {
  height: 100vh;
  height: 100dvh;
  background:
    radial-gradient(ellipse 100% 60% at 50% -20%, rgba(255, 59, 48, 0.06), transparent),
    linear-gradient(180deg, var(--white) 0%, var(--gray-50) 100%);
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  padding-bottom: var(--bottom-nav-reserved-space);
  transition: margin-left 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

/* body.drawer-desktop = PC でサイドバーが開いている（280px）/ たたんだ柱（72px）の両方。幅は --dc-drawer-width（navigation.css :root） */
body.drawer-desktop .settings-view {
  margin-left: var(--dc-drawer-width, 280px);
}

.settings-content {
  max-width: 600px;
  margin: 0 auto;
  padding: var(--s-16);
  padding-top: calc(60px + env(safe-area-inset-top, 0px));
}

.settings-section {
  margin-bottom: var(--s-24, 24px);
}

.settings-section-title {
  font-size: 0.8125rem;
  font-weight: 700;
  color: var(--gray-500);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: var(--s-12);
}

.settings-notification-groups {
  display: flex;
  flex-direction: column;
  gap: var(--s-8);
}

/* 設定内の遷移リンク行（公式記事「使い方」「お知らせ」への導線, 2026-08-02）。
   トグル行（.mypage-notification-group）と見た目を揃えつつ、右端の chevron で
   「押すと別ページに行く」ことを示す。 */
.settings-link-rows {
  display: flex;
  flex-direction: column;
  gap: var(--s-8);
}

.settings-link-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-12);
  padding: var(--s-16, 16px);
  border-radius: 14px;
  background: var(--gray-50, #fafafa);
  text-decoration: none;
  color: inherit;
  transition: background 0.15s ease;
}

.settings-link-row:hover {
  background: var(--gray-100, #f5f5f5);
}

.settings-link-row-label {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--gray-900);
}

.settings-link-row-chevron {
  display: inline-flex;
  color: var(--gray-400);
  flex: none;
}

.settings-notification-section-header {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--gray-400);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-top: var(--s-16, 16px);
  margin-bottom: var(--s-4, 4px);
  padding-left: var(--s-4, 4px);
}

.settings-notification-section-header:first-child {
  margin-top: 0;
}

/* ========================================
   Brand Splash (YouTube-style)
   ======================================== */

/* 棚に重ねる版。JS（mypage.js / profile.js の showLoadingSkeleton /
   showLoadingAnimation）が .mypage-showcase 直下に差し込む。
   pointer-events:none = 退場フェード中に下のカードをタップできる。 */

/* スプラッシュ表示中に棚の高さを確保しておく（レビュー指摘 2026-09-02 [MAJOR]）。
   以前は「空(0px) → スプラッシュ(260px) → カード」で縦位置が2回跳ねていた。
   重ねる方式では、下の棚に高さが無いと overlay(inset:0) も 0px になって
   スプラッシュ自体が見えなくなるので、この min-height は装飾ではなく前提。
   値はスプラッシュの min-height と同じ 260px。カード描画後は
   カードのほうが高い（200px 幅 × 9:14 の visual + タイトル）ので無効化される。
   favorites 側の棚には効かせない（空のとき巨大な余白になるため id 限定）。

   #gamesGrid は mypage.html と user.html の**両方**の棚に付いており、この min-height も
   両方に効く（profile.js の overlay も同じ前提なので、効かせること自体は必要）。
   副作用として、公開作品ゼロの他人プロフィールでは .mypage-games-empty（実高 ~85px）が
   260px の箱に伸びて以前より空白が広い。壊れではないので許容している
   （レビュー D3 [NIT] 2026-09-02）。 */

@keyframes dotBounce {
  0% {
    transform: scale(0.6) translateY(0);
    opacity: 0.5;
  }
  100% {
    transform: scale(1.2) translateY(-12px);
    opacity: 1;
  }
}

/* ========================================
   Game Start Animation - Card Insert
   サムネイルが「カチャッ」と差し込まれる
   ======================================== */

@keyframes cardInsert {
  0% {
    transform: translate(-50%, -120%) scale(1);
  }
  50% {
    transform: translate(-50%, -45%) scale(1);
  }
  65% {
    transform: translate(-50%, -55%) scale(1);
  }
  80% {
    transform: translate(-50%, -48%) scale(1);
  }
  100% {
    transform: translate(-50%, -50%) scale(1);
  }
}

@keyframes slotGlow {
  0% { box-shadow: 0 0 0 rgba(255, 59, 48, 0); }
  50% { box-shadow: 0 0 40px rgba(255, 59, 48, 0.6); }
  100% { box-shadow: 0 0 60px rgba(255, 59, 48, 0.8); }
}

@keyframes flashBang {
  0% { opacity: 0; }
  50% { opacity: 1; }
  100% { opacity: 1; }
}

.game-start-overlay {
  position: fixed;
  inset: 0;
  background: var(--gray-900);
  z-index: 9999;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
}

.game-start-overlay.active {
  opacity: 1;
  pointer-events: auto;
}

/* Slot - 差し込み口 */
.game-start-slot {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 180px;
  height: 320px;
  border: 4px solid var(--gray-700);
  border-radius: var(--r-24);
  opacity: 0;
  transition: opacity 0.2s ease;
}

.game-start-overlay.active .game-start-slot {
  opacity: 1;
  animation: slotGlow 0.5s ease-out 0.3s forwards;
}

/* The Card - サムネイルカード */
.game-start-card {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 160px;
  height: 280px;
  border-radius: var(--r-16);
  background-size: cover;
  background-position: center;
  background-color: var(--gray-800);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  transform: translate(-50%, -120%);
}

.game-start-overlay.active .game-start-card {
  animation: cardInsert 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) 0.1s forwards;
}

/* Flash */
.game-start-flash {
  position: absolute;
  inset: 0;
  background: white;
  opacity: 0;
  pointer-events: none;
}

.game-start-overlay.active .game-start-flash {
  animation: flashBang 0.3s ease-out 0.55s forwards;
}

/* ============================================
   Notifications Page
   ============================================ */
/* Enable scroll on notifications page */
html[data-page="notifications"] {
  overflow-y: auto;
  height: auto;
}

body[data-page="notifications"] {
  overflow-y: auto;
  overflow-x: hidden;
  height: auto;
  min-height: 100vh;
  min-height: 100dvh;
}

.notifications-view {
  height: 100vh;
  height: 100dvh;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  background:
    radial-gradient(ellipse 80% 50% at 20% -10%, rgba(255, 59, 48, 0.08), transparent),
    radial-gradient(ellipse 60% 40% at 80% 110%, rgba(255, 59, 48, 0.06), transparent),
    linear-gradient(180deg, var(--white) 0%, var(--gray-100) 100%);
}

.notifications-tab:hover {
  background: var(--gray-100);
  color: var(--gray-600);
}

.notifications-tab.active {
  background: var(--red);
  color: var(--white);
}

/* Guestbook Summary Card */
/* Notifications Content */

@keyframes spin {
  to { transform: rotate(360deg); }
}

.notification-icon.system {
  background: var(--gray-100);
  color: var(--gray-600);
}

.notification-icon.project {
  background: var(--red-light);
  color: var(--red);
}

.notification-icon.success {
  background: rgba(52, 199, 89, 0.15);
  color: #34C759;
}

.notification-icon.warning {
  background: rgba(255, 149, 0, 0.15);
  color: #FF9500;
}

.notification-icon.social {
  background: rgba(59, 130, 246, 0.15);
  color: #3B82F6;
}

.notification-badge {
  padding: 2px var(--s-8);
  border-radius: var(--r-full);
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.notification-badge.system {
  background: var(--gray-100);
  color: var(--gray-600);
}

.notification-badge.project {
  background: var(--red-light);
  color: var(--red);
}

.notification-badge.social {
  background: #F0F4FF;
  color: #3B82F6;
}

/* Notifications Mobile */

/* ===== Project Title Animation ===== */
#projectTitle {
  transition: opacity 0.15s ease, transform 0.3s var(--ease-out), color 0.3s ease;
}

@keyframes titlePop {
  0% {
    opacity: 0;
    transform: translateY(4px);
  }
  50% {
    transform: translateY(-2px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

/* =============================================
   PLAY SCREEN - Full Screen Game View
   ============================================= */

/* Play Screen Mobile Optimizations */

/* ===== Quota Display ===== */

.quota-display.hidden {
  display: none;
}

@keyframes quotaPopupIn {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 上限モーダルの主CTA（<a> を .new-game-confirm と併用、2026-08-24）。
   以前の color: var(--red) は白背景のキャンセル風リンク時代の名残で、
   赤背景の主ボタン化に伴い文字が消えるため中央寄せのリンクリセットのみ残す。 */

/* Quota Exceeded Error */

/* Quota Error - Mobile: smaller font and icon to fit */

/* ===== Language Selector ===== */
.lang-selector {
  position: relative;
  display: flex;
  align-items: center;
  z-index: 1100;
}

.lang-selector-btn {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px 10px;
  background: transparent;
  border: 1px solid var(--gray-200);
  border-radius: var(--r-8);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--gray-600);
  cursor: pointer;
  transition: all 0.2s ease;
}

.lang-selector-btn:hover {
  background: var(--gray-50);
  border-color: var(--gray-400);
}

.lang-selector-btn svg {
  width: 12px;
  height: 12px;
  transition: transform 0.2s ease;
}

.lang-selector.open .lang-selector-btn svg {
  transform: rotate(180deg);
}

.lang-selector-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  min-width: 100px;
  background: var(--white);
  border: 1px solid var(--gray-200);
  border-radius: var(--r-8);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: all 0.2s ease;
  z-index: 1000;
}

.lang-selector.open .lang-selector-dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.lang-option {
  display: block;
  width: 100%;
  padding: 8px 12px;
  background: transparent;
  border: none;
  text-align: left;
  font-size: 0.875rem;
  color: var(--gray-600);
  cursor: pointer;
  transition: background 0.15s ease;
}

.lang-option:first-child {
  border-radius: var(--r-8) var(--r-8) 0 0;
}

.lang-option:last-child {
  border-radius: 0 0 var(--r-8) var(--r-8);
}

.lang-option:hover {
  background: var(--gray-50);
}

.lang-option.active {
  color: var(--red);
  font-weight: 500;
}

/* ============================================================
   First-run character onboarding — "Nintendo Direct" redesign
   ============================================================ */

:root {
  --onb-cream: #FFF7E8;
  --onb-cream-deep: #FFEFD2;
  --onb-ink: #1C1A17;
  --onb-ink-soft: #4A463F;
  --onb-paper: #FFFDF7;
  --onb-paper-line: rgba(28, 26, 23, 0.08);
  --onb-red: #FF3B30;
  --onb-red-deep: #E5251A;
  --onb-yellow: #FFC727;
  --onb-yellow-deep: #F0B000;
  --onb-blue: #00AEEF;
  --onb-green: #22C55E;
  --onb-purple: #A855F7;
  --onb-easing: cubic-bezier(0.34, 1.56, 0.64, 1);
}

body[data-page="onboarding"] {
  height: 100dvh;
  overflow-x: hidden !important;
  overflow-y: auto !important;
  overscroll-behavior-y: contain;
  background: var(--onb-cream);
}

@keyframes onb-sparkle-float {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); opacity: 0.5; }
  50%      { transform: translate3d(0, -12px, 0) scale(1.18); opacity: 0.9; }
}

@keyframes onb-float {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  100% { transform: translate3d(40px, -30px, 0) scale(1.08); }
}

@keyframes onb-twinkle {
  0%, 100% { opacity: 0.3; transform: rotate(45deg) scale(1); }
  50%      { opacity: 0.9; transform: rotate(45deg) scale(1.5); }
}

.onboarding-stepper-dot.is-active {
  width: 28px;
  background: var(--onb-red);
  box-shadow: 0 0 0 3px rgba(255, 59, 48, 0.18);
}

.onboarding-stepper-dot.is-done {
  background: var(--onb-ink);
}

/* -------- main / panel layout -------- */
/* Onboarding panels are locked to the viewport so the CTA is always
   visible — no scroll required to reach the button. We do this by:
   1. Sizing .onboarding-main to viewport height (not min-height).
   2. Making .onboarding-panel a flex column that fills main.
   3. Pinning .onboarding-cta to the bottom with margin-top:auto.
   4. Making the per-panel "hero" element flexible so it absorbs the
      remaining space and shrinks on short screens.
   5. Using vh-aware clamp() on titles, copy, paddings.            */

.onboarding-panel.hidden {
  display: none;
}

@keyframes onb-pulse {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 3px rgba(255, 199, 39, 0.3); }
  50%      { transform: scale(1.3); box-shadow: 0 0 0 8px rgba(255, 199, 39, 0); }
}

/* -------- title -------- */
/* Title uses min(vw, vh) so it shrinks both on narrow AND short screens. */

/* -------- intro demo strip (legacy, retained in case other panels use it) -------- */
.onboarding-intro-demo {
  width: 100%;
  margin: 36px 0 0;
  display: grid;
  grid-template-columns: 1fr auto 1fr auto 1fr;
  align-items: center;
  gap: 12px;
}

/* Flat illustrative panels — explicitly NOT buttons.
   No shadow, no thick border, no tilt. Color lives only in the
   icon chip so the page's only "raised" element is the CTA. */
.onboarding-intro-card {
  position: relative;
  display: grid;
  place-items: center;
  gap: 6px;
  min-height: 112px;
  padding: 16px 12px;
  text-align: center;
  background: transparent;
  border: 0;
  border-radius: 18px;
  color: var(--onb-ink);
  font-size: 0.95rem;
  font-weight: 800;
  box-shadow: none;
  cursor: default;
  pointer-events: none;
}

.onboarding-intro-card small {
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--onb-ink-soft);
  letter-spacing: 0.02em;
}

.onboarding-intro-card-icon {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 999px;
  background: var(--onb-cream-deep, #FFEFD2);
  color: var(--onb-ink);
}

.onboarding-intro-card-icon svg {
  width: 28px;
  height: 28px;
}

.onboarding-intro-card.is-character .onboarding-intro-card-icon {
  background: var(--onb-red);
  color: #fff;
}

.onboarding-intro-card.is-game .onboarding-intro-card-icon {
  background: var(--onb-yellow);
  color: var(--onb-ink);
}

.onboarding-intro-arrow {
  display: grid;
  place-items: center;
  color: var(--onb-ink);
  font-size: 1.6rem;
  font-weight: 900;
  animation: onb-arrow-bounce 1.4s ease-in-out infinite;
}

.onboarding-intro-arrow:nth-of-type(2) { animation-delay: 0.3s; }

@keyframes onb-arrow-bounce {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(4px); }
}

/* Once a file is selected, the inner image(s) already have their own chunky
   frame + shadow. Drop the outer frame so we don't end up with a double-bordered
   "frame inside a frame" look. */

/* Input is visually hidden (not an overlay) so it never sits on top of the
   × buttons. The zone opens the picker via a JS click handler instead. */

@keyframes onb-icon-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}

/* Drag-over state — give clear "drop here" feedback when a file is
   being dragged over. Class is added by JS on dragenter, removed on
   dragleave/drop. Without the class, normal style applies. */

/* A lone photo gets a touch more room, but still leaves space for the
   add tile beside it. */

/* "Add more" tile — pointer-events:none so a tap falls through to the
   label and opens the picker, same as the empty placeholder. */

/* -------- tips list -------- */
.onboarding-tips {
  margin: 24px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 8px;
}

.onboarding-tips li {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  background: var(--onb-cream);
  border: 1px solid var(--onb-paper-line);
  border-radius: 14px;
  color: var(--onb-ink-soft);
  font-size: 0.96rem;
  font-weight: 700;
}

.onboarding-tip-num {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex: 0 0 auto;
  font-size: 0.85rem;
  font-weight: 900;
  color: #fff;
  background: var(--onb-ink);
  border-radius: 999px;
}

/* -------- action buttons -------- */
.onboarding-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 32px;
}

@keyframes onb-celebrate-glow {
  0%, 100% { box-shadow: 0 6px 0 var(--onb-ink), 0 18px 32px rgba(255, 59, 48, 0.32); }
  50%      { box-shadow: 0 6px 0 var(--onb-ink), 0 18px 44px rgba(255, 59, 48, 0.55); }
}

@keyframes onb-magic-spin {
  to { transform: rotate(360deg); }
}

@keyframes onb-magic-bob {
  0%, 100% { transform: translateY(0) scale(1); }
  50%      { transform: translateY(-6px) scale(1.04); }
}

@keyframes onb-spark-pulse {
  0%, 100% { opacity: 0.4; transform: rotate(var(--a)) translate(76px, -4px) scale(0.8); }
  50%      { opacity: 1; transform: rotate(var(--a)) translate(86px, -4px) scale(1.2); }
}

/* legacy spinner (kept for safety) */
.onboarding-spinner {
  width: 72px;
  height: 72px;
  margin: 0 auto 24px;
  border: 8px solid rgba(255, 59, 48, 0.16);
  border-top-color: var(--onb-red);
  border-radius: 999px;
  animation: character-spin 0.9s linear infinite;
  display: none;
}

@keyframes onb-magic-burst {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.2); filter: brightness(1.4); }
  100% { transform: scale(0.9); opacity: 0.4; }
}

.onboarding-sheet-stage {
  position: relative;
  width: min(620px, 100%);
  margin: 26px auto 0;
}

.onboarding-sheet-spotlight {
  position: absolute;
  inset: -16% -8%;
  background: radial-gradient(circle, rgba(255, 199, 39, 0.45), transparent 60%);
  filter: blur(20px);
  z-index: 0;
  pointer-events: none;
}

.onboarding-sheet-stage--celebrate .onboarding-sheet-spotlight {
  background: radial-gradient(circle, rgba(255, 59, 48, 0.35), rgba(255, 199, 39, 0.3), transparent 65%);
  animation: onb-spotlight-pulse 2.4s ease-in-out infinite;
}

@keyframes onb-spotlight-pulse {
  0%, 100% { transform: scale(1); opacity: 0.85; }
  50%      { transform: scale(1.06); opacity: 1; }
}

.onboarding-sheet-preview {
  position: relative;
  z-index: 1;
}

.onboarding-birth-panel .onboarding-character-sheet {
  animation: onb-sheet-pop 0.9s var(--onb-easing);
}

@keyframes onb-sheet-pop {
  0%   { transform: scale(0.7) rotate(-4deg); opacity: 0; }
  60%  { transform: scale(1.06) rotate(2deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); }
}

@keyframes onb-confetti-fall {
  0%   { transform: translateY(0) rotate(var(--r)); opacity: 0; }
  10%  { opacity: 1; }
  100% { transform: translateY(120vh) rotate(calc(var(--r) + 540deg)); opacity: 0.8; }
}

@keyframes onb-panel-enter {
  0%   { opacity: 0; transform: translateY(20px) scale(0.985); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

.onboarding-panel .onboarding-badge,
.onboarding-panel .onboarding-title,
.onboarding-panel .onboarding-copy,
.onboarding-panel .onboarding-intro-demo,
.onboarding-panel .onboarding-upload,
.onboarding-panel .onboarding-tips,
.onboarding-panel .onboarding-actions,
.onboarding-panel .onboarding-magic,
.onboarding-panel .onboarding-steps,
.onboarding-panel .onboarding-sheet-stage,
.onboarding-panel .onboarding-name-field {
  animation: onb-bubble-in 0.55s var(--onb-easing) both;
}

.onboarding-panel .onboarding-badge          { animation-delay: 0.10s; }
.onboarding-panel .onboarding-title          { animation-delay: 0.18s; }
.onboarding-panel .onboarding-copy           { animation-delay: 0.28s; }
.onboarding-panel .onboarding-intro-demo     { animation-delay: 0.38s; }
.onboarding-panel .onboarding-upload         { animation-delay: 0.30s; }
.onboarding-panel .onboarding-tips           { animation-delay: 0.42s; }
.onboarding-panel .onboarding-magic          { animation-delay: 0.20s; }
.onboarding-panel .onboarding-steps          { animation-delay: 0.34s; }
.onboarding-panel .onboarding-sheet-stage    { animation-delay: 0.34s; }
.onboarding-panel .onboarding-name-field     { animation-delay: 0.44s; }
.onboarding-panel .onboarding-actions        { animation-delay: 0.52s; }

@keyframes onb-bubble-in {
  0%   { opacity: 0; transform: translateY(14px) scale(0.96); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* -------- responsive -------- */
@media (max-width: 720px) {
  /* Make the background art more present on mobile so the area below the
     compressed panel doesn't feel empty. */

  .onboarding-stepper-dot.is-active {
    width: 22px;
  }

  /* Keep the panel's chunky card frame on mobile — the cream-white card with
     dashed inner border anchors the content and is what users prefer. */

  .onboarding-actions {
    flex-direction: column;
    align-items: stretch;
  }

  /* Diagram stays horizontal on mobile so the arrows line up with the flow.
     Cards are taller and richer so they carry visual weight. */
  .onboarding-intro-demo {
    grid-template-columns: 1fr auto 1fr auto 1fr;
    gap: 8px;
    margin-top: 36px;
  }

  .onboarding-intro-arrow {
    transform: none;
    justify-self: center;
    font-size: 1.2rem;
  }

  .onboarding-intro-card {
    min-height: 140px;
    padding: 18px 8px;
    gap: 10px;
    font-size: 0.88rem;
  }

  .onboarding-intro-card small {
    font-size: 0.7rem;
  }

  .onboarding-intro-card-icon {
    width: 56px;
    height: 56px;
  }

  .onboarding-intro-card-icon svg {
    width: 28px;
    height: 28px;
  }

}

/* ============================================================
   Onboarding v2 additions
   - Header skip pill
   - CTA layout (replaces .onboarding-actions)
   - Hero variant primary button (full-width + pulse halo)
   - Hint label above intro CTA
   - Fineprint (privacy note)
   - Subdued name screen with small avatar
   - Birth overlay modal with rays + spotlight + dramatic entrance
   ============================================================ */

/* ---- header right ---- */

/* ---- new CTA container (replaces .onboarding-actions where used) ----
   Panels are auto-height so they hug their content. CTA gets a natural
   gap from the previous element (no margin-top:auto needed). */

@keyframes onb-cta-halo {
  0%, 100% { opacity: 0; transform: scale(0.92); }
  50%      { opacity: 1; transform: scale(1.06); }
}

/* ---- hint label above intro CTA ---- */
.onboarding-cta-hint {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: center;
  margin-bottom: -2px;
  padding: 6px 14px;
  background: rgba(28, 26, 23, 0.06);
  border-radius: 999px;
  color: var(--onb-ink);
  font-size: 0.86rem;
  font-weight: 800;
  animation: onb-hint-bounce 1.6s ease-in-out infinite;
}

.onboarding-cta-hint svg {
  width: 16px;
  height: 16px;
}

.onboarding-cta-hint em {
  font-style: normal;
}

@keyframes onb-hint-bounce {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(4px); }
}

/* ---- intro card kept flat (overrides removed; cards are info, not buttons) ---- */

/* ---- subdued name screen ---- */

/* When hydrateCharacterImages loads the actual character sheet asset
   (via data-character-asset-id), use `contain` so the whole sheet fits
   inside the polaroid frame without being cropped to a corner. */
/* hydrateCharacterImages sets inline `background-image: url(...)` once the
   asset loads. Always use `contain` so the full image (uploaded photo OR
   character sheet) fits inside the polaroid frame — no cropping. */

.onboarding-birth-overlay.hidden {
  display: none;
}

@keyframes onb-birth-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes onb-birth-pop {
  0%   { opacity: 0; transform: scale(0.4) translateY(40px) rotate(-6deg); }
  60%  { opacity: 1; transform: scale(1.06) translateY(-6px) rotate(2deg); }
  80%  { transform: scale(0.98) translateY(2px) rotate(-1deg); }
  100% { transform: scale(1) translateY(0) rotate(0); }
}

@keyframes onb-birth-badge {
  0%   { opacity: 0; transform: scale(0.3) rotate(-20deg); }
  60%  { opacity: 1; transform: scale(1.15) rotate(4deg); }
  100% { transform: scale(1) rotate(1.5deg); }
}

@keyframes onb-birth-title {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes onb-birth-stage {
  from { opacity: 0; transform: scale(0.6) rotate(-8deg); }
  to   { opacity: 1; transform: scale(1) rotate(0); }
}

@keyframes onb-birth-spotlight {
  0%, 100% { transform: scale(1); opacity: 0.85; }
  50%      { transform: scale(1.08); opacity: 1; }
}

@keyframes onb-birth-rays-spin {
  to { transform: rotate(360deg); }
}

@keyframes onb-birth-sheet-bob {
  0%, 100% { transform: translateY(0) rotate(-1deg); }
  50%      { transform: translateY(-6px) rotate(1deg); }
}

/* ---- mobile tweaks for the new bits ---- */

@keyframes onb-magic-shine {
  0%, 100% { opacity: 0.6; }
  50%      { opacity: 1; }
}

/* (legacy stale overrides removed — see the polaroid name-avatar rules above) */

/* ---- dev reset button ---- */

/* =====================================================================
   完成カードは 2026-07-30 に廃止した（クラス .caj-card / .caj-print / .caj-play …）。
   founder 指摘:「いきなりカードがでてきて、これは何だ？ってなる。完成したという高揚感もない」。
   実装を追うと、生成完了の本当のお祝いは /project/:id/make の完成画面
   （showProjectCompleteView：ゲーム本体・タイトル編集・共有・録画・コンテスト応募・
   赤ペン先生導線）にあり、/create のカードは2つ目のお祝いをやろうとして
   名乗りも高揚感も中途半端になっていた。/create は「つくる」入口であって完成の舞台ではない。

   受け皿は下の「つづきから」の行の NEW チップ（.project-card-state.is-new）。
   通知から来た人もその行から直接ゲームへ行ける（行は updatedAt 順なので必ず先頭）。

   この廃止で同時に消えたもの: 日本語ベタ書き8箇所 / --gold（プロダクト唯一の2色目）/
   固定キャラ画像フォールバック / 紙吹雪の DOM 残留 / 描画のたびの share-ready prepare 再送。
   ※ .caj-receipt-* / .caj-ai-reply-summary は /project/:id/make の AI タブと共用なので
     21460行付近に残してある（消さないこと）。
   ===================================================================== */

/* 完成直後でまだ開いていない行の印。塗りの赤にして、下書き/公開中の淡色チップより一段強くする
   （「まだ見ていないものが1つある」ことだけを伝える。祝いは完成画面が持つ） */

.current-active-job-dismiss {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 2;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.92);
  color: var(--gray-700);
  font-size: 1.25rem;
  font-weight: 800;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 8px 18px rgba(28, 28, 30, 0.08);
  transition: transform 0.15s ease, background 0.15s ease, color 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}

.current-active-job-dismiss:hover {
  background: var(--white);
  color: var(--gray-900);
}

.current-active-job-dismiss:active {
  transform: scale(0.94);
}

.current-active-job-dismiss:focus-visible {
  outline: 3px solid rgba(255, 59, 48, 0.28);
  outline-offset: 2px;
}

.current-active-job-dismiss span {
  transform: translateY(-1px);
}
/* 旧 .current-active-job-card.is-completed 向けの reduced-motion 指定はここにあったが、
   そのクラス自体が 2026-07-29 に .caj-card へ置き換わったので削除した（対象が存在しない）。
   新しい reduced-motion は .caj-card の定義側にある。 */

/* =====================================================================
   Project Complete view + Image Editor v2 (creator feature) — ported
   from the creator worktree 2026-06-10. Appended last so the v2 editor
   rules win cascade ties against the older editor styles above.
   ===================================================================== */

/* ===== Project Complete Page ===== */

/* Desktop: when the drawer is pinned open, offset the creator/complete surface
   so the game preview centers in the space beside the drawer rather than the
   full viewport. Without this the centered preview slides under the fixed 280px
   drawer at narrow desktop widths (~1024–1090px). Mirrors .settings-view. */

/* Confirm dialog before leaving Studio for the public page (same-tab nav).
   Brand: flat, Nintendo-red primary, dimmed backdrop, clean white card. */

.project-complete-view.hidden {
  display: none;
}

.project-complete-game-loading.hidden {
  display: none;
}

.project-complete-title-row h1 {
  margin: 0;
  font-size: clamp(1.8rem, 4vw, 3rem);
  line-height: 1.12;
  font-weight: 900;
  letter-spacing: 0;
}

.project-complete-title-edit {
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 999px;
  background: #fff;
  color: var(--gray-700);
  font: inherit;
  font-size: 0.82rem;
  font-weight: 850;
  cursor: pointer;
}

.project-complete-asset-editor.hidden {
  display: none;
}

.project-complete-asset-actions button.active {
  border-color: var(--red);
  background: var(--red);
  color: #fff;
  box-shadow: 0 10px 22px rgba(255, 59, 48, 0.2);
}

.project-complete-crop-ratios {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding: 2px 0 4px;
  scrollbar-width: none;
}

.project-complete-crop-ratios::-webkit-scrollbar {
  display: none;
}

.project-complete-crop-ratios.hidden {
  display: none;
}

.project-complete-crop-ratios button {
  flex: 0 0 auto;
  min-width: 54px;
  min-height: 52px;
  display: grid;
  place-items: center;
  gap: 4px;
  padding: 7px 9px;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 14px;
  background: #fff;
  color: var(--gray-700);
  font: inherit;
  cursor: pointer;
}

.project-complete-crop-ratios button.active {
  border-color: var(--red);
  background: #fff1f0;
  color: var(--red);
}

.project-complete-crop-ratios .ratio-shape {
  border-color: currentColor;
}

.project-complete-crop-ratios strong {
  font-size: 0.66rem;
  line-height: 1;
  font-weight: 900;
}

.project-complete-asset-apply {
  width: 100%;
  min-height: 50px;
  padding: 0 16px;
  border: 0;
  border-radius: 18px;
  background: var(--red);
  color: #fff;
  font: inherit;
  font-size: 0.92rem;
  font-weight: 900;
  cursor: pointer;
  box-shadow: 0 12px 28px rgba(255, 59, 48, 0.22);
}

.project-complete-asset-apply:disabled {
  background: #ece8e6;
  color: var(--gray-400);
  box-shadow: none;
  cursor: not-allowed;
}

.project-complete-tool-dock button.active {
  background: #111;
  color: #fff;
}

.project-complete-view[data-active-tool="image"] .project-complete-panel {
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
}

.project-complete-view[data-active-tool="image"] .project-complete-hero-card {
  grid-template-columns: 1fr;
}

.project-complete-view[data-active-tool="image"] .project-complete-visual {
  width: min(100%, 420px);
}

.project-complete-view[data-active-tool="image"] .project-complete-asset-workbench {
  position: fixed;
  left: 50%;
  bottom: max(92px, calc(env(safe-area-inset-bottom) + 92px));
  z-index: 3380;
  width: min(720px, calc(100vw - 24px));
  gap: 8px;
  padding: 9px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 26px;
  background: rgba(255, 255, 255, 0.96);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.14);
  transform: translateX(-50%);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}

.project-complete-view[data-active-tool="image"] .project-complete-asset-list {
  min-height: 72px;
  gap: 8px;
  margin: 0;
  padding: 0 2px 2px;
}

.project-complete-view[data-active-tool="image"] .project-complete-asset-empty {
  min-height: 70px;
  border-radius: 18px;
  background: #f8f8f8;
  font-size: 0.82rem;
}

.project-complete-view[data-active-tool="image"] .project-complete-asset-tile {
  flex-basis: 60px;
  gap: 0;
  padding: 4px;
  border-width: 2px;
  border-radius: 18px;
  box-shadow: none;
}

.project-complete-view[data-active-tool="image"] .project-complete-asset-editor {
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
}

.project-complete-view[data-active-tool="image"] .project-complete-crop-ratios {
  margin-top: -1px;
}

.project-complete-view[data-active-tool="image"] .project-complete-asset-apply {
  min-height: 48px;
  border-radius: 999px;
}

.project-complete-visibility {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  padding-top: 4px;
}

.project-complete-visibility button {
  min-height: 48px;
  padding: 0 12px;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 999px;
  background: #fff;
  color: var(--gray-700);
  font: inherit;
  font-size: 0.88rem;
  font-weight: 850;
  cursor: pointer;
}

.project-complete-visibility button.active {
  border-color: var(--red);
  color: var(--red);
  background: #fff6f5;
}

.project-complete-share-step.hidden {
  display: none;
}

/* 作者スタイルの display:inline-flex は UA の [hidden]{display:none} に勝つ。
   この1行が無いと、`hidden` で閉じているつもりの「詳しい分析を見る」と
   「DreamCoreの人にあそんでもらう」が、公開前・未計測の状態でも出たままになる
   （レビュー指摘 2026-09-05（第2回）・C-M3）。
   hidden 属性で出し入れする要素に display を与えたら、必ずこの相棒を置くこと。 */

/* 「あそんでもらう」ボタンの補足行（押せない理由・残枚数）。C3。
   WHY 画面に出すか: 以前は title 属性だけだったので、タッチ端末では長押ししない限り
   永久に出てこない＝実質的に存在しない情報だった。券が0枚・行列が満席という状態は
   「次に何をすればいいか」を決める材料なので、必ず見えるところに置く。
   ゲーム詳細の #infoStaffReviewHint と同じ役割・同じ見え方にそろえてある。 */

.project-complete-primary,
.project-complete-secondary {
  min-height: 60px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border-radius: 999px;
  font: inherit;
  font-size: 1rem;
  font-weight: 900;
  cursor: pointer;
}

.project-complete-primary {
  border: 0;
  background: var(--red);
  color: #fff;
  box-shadow: 0 14px 30px rgba(255, 59, 48, 0.28);
}

.project-complete-secondary {
  border: 1px solid rgba(0, 0, 0, 0.12);
  background: #fff;
  color: var(--gray-900);
}

.project-complete-primary:disabled,
.project-complete-secondary:disabled {
  opacity: 0.68;
  cursor: default;
}

.project-complete-settings-modal.hidden {
  display: none;
}

@media (max-width: 760px) {

  .project-complete-primary,
  .project-complete-secondary {
    min-height: 54px;
    font-size: 0.94rem;
  }

}

/* =======================================================================
   Image Editor v2 — TikTok/Instagram-style, DreamCore white theme
   Re-skins #imageEditorModal (cropper.js wiring unchanged). Scoped so it
   cannot leak to other modals. Appended last → wins by source order.
   ======================================================================= */

/* Full-bleed sheet — beat .modal .modal-content (max-height:85vh) */

/* ...but the thumbnail editor (publish.html) keeps its ONLY Save/Cancel in the
   footer — it has no header e2-actions like the full Studio editor. The blanket
   hide above made the confirm button invisible (users could rotate/flip but
   never apply the crop — reported 2026-06-23). Re-show it for that variant,
   pinned at the bottom of the 100dvh sheet (header flex-shrink:0 + body flex:1
   keep it on screen at any height). Specificity 0,0,3,0 + later source order
   beats the hide. */

/* Creator image editing uses the shared Studio image editor. While it is open,
   keep the Creator asset dock out of the stacking context so Cropper controls
   and crop handles remain usable. */

/* Toolbar stays visible at all times (TikTok editor-style) so rotate/flip can
   be tapped repeatedly. When a tool panel is open it appears ABOVE the toolbar
   as a slim contextual row (see flex order below). */

/* When a tool is active, the panel docks IN FLOW at the bottom and the canvas
   shrinks to fit above it — so crop handles are never hidden behind the sheet. */

/* ===== Image editor crop footer — TikTok-style ↺ Reset / ✓ ===== */

/* ===== Intended /create design (ported from snapshot claude/admiring-bohr-491d0e) ===== */

/* Grid items default to min-width:auto (=intrinsic content width), which lets a horizontally
   scrolling shelf (.featured-remix-shelf) blow out its grid track instead of clipping to the
   viewport. create-template-section now holds 4 such shelves directly (テンプレ棚 founder 決定
   2026-07-23), so it needs the standard CSS-grid overflow fix: min-width: 0 on the item itself. */

body[data-page="create"] .create-draft-list .project-empty {
  grid-column: auto;
  padding: var(--s-24);
  border: 1px solid var(--gray-200);
  border-radius: var(--r-16);
  background: var(--white);
  box-shadow: var(--shadow-card, 0 1px 2px rgba(28,28,30,.04), 0 12px 32px -18px rgba(28,28,30,.20));
}

body[data-page="create"] .create-draft-list .project-card {
  position: relative;
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 12px;
  min-height: 76px;
  padding: 12px;
  border: 1px solid var(--gray-200);
  border-radius: 14px;
  background: var(--white);
  box-shadow: var(--shadow-card, 0 1px 2px rgba(28,28,30,.04), 0 12px 32px -18px rgba(28,28,30,.20));
  overflow: hidden;
}

body[data-page="create"] .create-draft-list .project-card::before {
  display: none;
}

body[data-page="create"] .create-draft-list .project-card::after {
  display: none;
}

@keyframes template-create-spin {
  to { transform: rotate(360deg); }
}

body[data-page="create"] .create-draft-list .project-card-link-overlay {
  z-index: 2;
}

body[data-page="create"] .create-draft-list .project-card-thumbnail {
  grid-column: 1;
  width: 56px;
  height: 56px;
  aspect-ratio: auto;
  border-radius: 12px;
}

body[data-page="create"] .create-draft-list .placeholder-title {
  display: none;
}

body[data-page="create"] .create-draft-list .project-card-body {
  grid-column: 2;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
body[data-page="create"] .create-draft-list .project-card-meta-line {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  flex-wrap: wrap;
}

body[data-page="create"] .create-template-grid .featured-remix-section:not(.hidden),
body[data-page="create"] .create-template-grid .featured-remix-shelf-wrap,
body[data-page="create"] .create-template-grid .featured-remix-shelf {
  display: contents;
}

body[data-page="create"] .create-template-grid .featured-remix-shelf-wrap::after {
  display: none;
}

body[data-page="create"] .create-template-tile,
body[data-page="create"] .create-template-grid .featured-remix-card {
  position: relative;
  min-width: 0;
  border: 1px solid var(--gray-200);
  border-radius: var(--r-16);
  background: var(--white);
  box-shadow: var(--shadow-card, 0 1px 2px rgba(28,28,30,.04), 0 12px 32px -18px rgba(28,28,30,.20));
  overflow: hidden;
  opacity: 1;
  animation: none;
  transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.25s ease;
}

body[data-page="create"] .create-template-tile:not(.hidden) {
  display: flex;
  flex-direction: column;
}

body[data-page="create"] .create-template-tile:hover,
body[data-page="create"] .create-template-grid .featured-remix-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 16px 36px -18px rgba(28,28,30,.35);
}

body[data-page="create"] .create-template-tile {
  aspect-ratio: 9 / 16;
  justify-content: flex-end;
  padding: 14px;
  border-color: rgba(255, 59, 48, 0.42);
  background: linear-gradient(135deg, #fff, #ffe7e5 48%, #f7f7f8);
}

body[data-page="create"] .create-template-tile .daily-prompt-kicker {
  position: absolute;
  left: 12px;
  bottom: 58px;
  margin: 0;
  color: var(--red);
  font-size: 0.76rem;
  font-weight: 900;
  letter-spacing: 0;
}

body[data-page="create"] .create-template-tile .daily-prompt-text {
  margin: auto 0 14px;
  color: var(--gray-900);
  font-size: clamp(0.95rem, 4vw, 1.18rem);
  font-weight: 900;
  line-height: 1.28;
  letter-spacing: -0.035em;
}

body[data-page="create"] .daily-prompt-actions {
  display: grid;
  gap: 7px;
}

body[data-page="create"] .create-template-tile .daily-prompt-cta,
body[data-page="create"] .create-template-tile .daily-prompt-reroll {
  width: 100%;
  min-height: 34px;
  margin: 0;
  border-radius: var(--r-full);
  font-size: 0.76rem;
  font-weight: 900;
}

body[data-page="create"] .create-template-tile .daily-prompt-reroll {
  border: 1px solid var(--gray-200);
  background: var(--white);
  color: var(--gray-600);
}

body[data-page="create"] .create-template-grid .featured-remix-card {
  display: block;
  scroll-snap-align: unset;
}

body[data-page="create"] .create-template-grid .featured-remix-cover {
  aspect-ratio: 9 / 16;
  background: var(--gray-100);
}

body[data-page="create"] .create-template-grid .featured-remix-body {
  padding: 10px 12px 13px;
}

body[data-page="create"] .create-template-grid .featured-remix-card-title {
  color: var(--gray-900);
  font-size: 0.92rem;
  font-weight: 900;
  line-height: 1.25;
  letter-spacing: -0.025em;
}

body[data-page="create"] .create-template-grid .featured-remix-more {
  aspect-ratio: 9 / 16;
  display: grid;
  place-items: center;
}

body[data-page="create"] .project-list-view.projects-list-mode .create-v2-section {
  gap: 0;
  margin-top: 0;
  padding-top: 22px;
}

body[data-page="create"] .project-list-view.projects-list-mode .create-hero,
body[data-page="create"] .project-list-view.projects-list-mode .create-template-section {
  display: none !important;
}

body[data-page="create"] .project-list-view.projects-list-mode .games-filter-bar {
  display: flex;
  min-height: 66px;
  margin-bottom: 18px;
  padding: 5px;
  border-radius: 22px;
}

body[data-page="create"] .project-list-view.projects-list-mode .projects-controls {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  margin-bottom: 16px;
}

body[data-page="create"] .project-list-view.projects-list-mode .project-card-actions > button.delete-btn {
  color: var(--gray-700);
}

body[data-page="create"] .project-list-view.projects-list-mode .project-card-actions > button.delete-btn:hover {
  border-color: rgba(255, 59, 48, 0.32);
  background: #fff1f0;
  color: var(--red);
}

/* /projects grid-card overlay: the Studio chip is icon-only (matches the ⋮ icon button).
   The "Studio" text label only shows in the /create list-card actions row. */

body[data-page="create"] .create-template-grid .featured-remix-card,
body[data-page="create"] .create-template-tile {
  position: relative;
  width: 100%;
  margin: 0 0 10px;
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: var(--shadow-card, 0 1px 2px rgba(28,28,30,.04), 0 12px 32px -18px rgba(28,28,30,.20));
}

body[data-page="create"] .create-template-grid .featured-remix-card {
  display: inline-block;
  aspect-ratio: 3 / 4;
  background: var(--gray-100);
  border: 0;
}

body[data-page="create"] .create-template-grid .featured-remix-card:nth-child(2n) {
  aspect-ratio: 1 / 1;
}

body[data-page="create"] .create-template-grid .featured-remix-card:nth-child(3n) {
  aspect-ratio: 4 / 5;
}

body[data-page="create"] .create-template-grid .featured-remix-card:nth-child(5n) {
  aspect-ratio: 9 / 16;
}

body[data-page="create"] .create-template-grid .featured-remix-cover {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  border-radius: 0;
  background: var(--gray-100);
}

body[data-page="create"] .create-template-grid .featured-remix-body {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  padding: 26px 10px 10px;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.74), rgba(0, 0, 0, 0));
}

body[data-page="create"] .create-template-grid .featured-remix-card-title {
  color: var(--white);
  font-size: 0.85rem;
  font-weight: 900;
  line-height: 1.25;
  letter-spacing: -0.02em;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.45);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

body[data-page="create"] .create-template-grid .featured-remix-more {
  display: inline-grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--gray-200);
  background: var(--white);
}

body[data-page="create"] .create-template-tile.hidden {
  display: none !important;
}

body[data-page="create"] .create-template-tile:not(.hidden) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 3 / 4;
  padding: 14px;
  border: 1px solid rgba(255, 59, 48, 0.4);
  background: linear-gradient(135deg, #fff, #ffe7e5 48%, #f7f7f8);
  cursor: pointer;
}

body[data-page="create"] .create-template-tile .daily-prompt-kicker {
  position: absolute;
  top: 8px;
  left: 8px;
  bottom: auto;
  z-index: 3;
  padding: 4px 9px;
  border-radius: var(--r-full);
  background: rgba(255, 59, 48, 0.95);
  color: var(--white);
  font-size: 0.6rem;
  font-weight: 900;
  letter-spacing: 0.04em;
  box-shadow: 0 2px 8px rgba(255, 59, 48, 0.3);
}

body[data-page="create"] .create-template-tile .daily-prompt-text {
  margin: 0;
  color: var(--gray-900);
  font-size: clamp(0.9rem, 4vw, 1.08rem);
  font-weight: 900;
  line-height: 1.3;
  letter-spacing: -0.035em;
  text-align: center;
}

body[data-page="create"] .create-template-tile .daily-prompt-actions {
  display: none;
}

@media (max-width: 520px) {

  body[data-page="create"] .project-list-view.projects-list-mode .projects-controls {
    grid-template-columns: 1fr;
  }

}

/* ===== 反映レシート（make 愛着施策 2026-07-03） =====
   完成カード内の「このゲームは、あなたのアイデアでできています」。
   idea = 作成者の言葉（💡）、result = ゲーム内のどこに登場したか（→）。 */

.project-complete-ai-reply-body .caj-receipt{margin-top:0}

/* ══════════════════════════════════════════════════════════════════════════
   /create リデザイン 2026-07-29
   任天堂（1画面1動詞・触りたくなる手応え）× 佐藤可士和（整理・階層3段・色は1色）
   × Alex Zhu（ユーザーを教育しない・消費と創造の距離をゼロに）
   ここは「新しく足したもの」だけ。既存部品の変更は各部品の定義位置に直接書いてある。
   ══════════════════════════════════════════════════════════════════════════ */

/* ── ヘッダーの変身ボタン ────────────────────────────────────────────
   .create-hero を通常フローに戻したので、下までスクロールすると入力欄が画面外に出る。
   その戻り道を新しいバーではなくヘッダー自身に持たせる＝重なるレイヤーを1つも増やさない。
   375px でも収まるよう、出ている間はワードマークを引っ込めて幅を空ける。 */
/* ⚠ display:none が既定。opacity:0 だけで隠すと以下が全部起きる（実測 375px, 2026-07-29）:
     ・CSS の display:flex が HTML の hidden 属性（UA の [hidden]{display:none}）に勝つため、
       透明なボタンがヘッダーの幅を 69〜131px 占有し続ける。
     ・その結果 body.dc-anon（匿名）の英語表示で「Log in / Sign up」の右端が 392px となり、
       375px の画面から 17px はみ出して .project-list-view{overflow-x:clip} に切り落とされる。
       匿名 /create は非ログイン→クリエイター転換ファネルの入口で、その唯一の CTA が欠ける。
     ・/create/deleted の back モードでヘッダーが 61→73px に太る。
     ・透明のままタブ順とアクセシビリティツリーに残り、/projects で「なにをつくる？」に
       フォーカスが乗る。押しても composerInput は display:none 配下なので何も起きない。
   visibility:hidden ではボックスが残るので不可（タブ順しか直らない）。display で切る。 */

body.create-scrolled .create-header-cta {
  display: flex;
  animation: createHeaderCtaIn .25s var(--ease-out);
}
@keyframes createHeaderCtaIn {
  from { opacity: 0; transform: translateY(-6px) scale(.96); }
  to   { opacity: 1; transform: none; }
}
/* /projects（マイプロジェクト）のタイルの入場（2026-09-23・founder 承認モック uiux-demo/projects.html）。
   使う側は css/routes/create.css の「マイプロジェクト」節（.myproj-enter）。@keyframes はルート別バンドルに
   置けない（scripts/split-route-css.js の決め事: バンドル側の animation 名が参照する定義は常に critical）ので、ここにある。
   動かすのは opacity / transform だけ（合成のみ・レイアウトを揺らさない）。 */
@keyframes myprojEnter {
  from { opacity: 0; transform: translateY(14px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  body.create-scrolled .create-header-cta { animation: none; }
}
/* ⚠ opacity の transition で消してはいけない。
   app-shell はルート遷移のたびに viewport.replaceChildren() で .project-list-view を
   DOM から外して付け直すため、遷移中の opacity トランジションが宙に浮き、
   body.create-scrolled が外れた後も computed opacity:0 のまま固まる
   （実測 2026-07-29: /create をスクロール → /create/deleted → /create → /projects で、
    body="" なのにワードマークが opacity:0・幅91px を占めたまま残った）。
   display で切れば中間状態が存在しないので、この事故は構造的に起こらない。 */

/* ── PC 幅のヒーロー ────────────────────────────────────────────────
   モバイル（〜768px）は中央寄せ・max-width 560px のままでよい（画面幅とほぼ同じなので
   中央寄せと左揃えの区別が生まれない）。
   問題は PC。1440px 実測で、ヒーロー（h1 / コンポーザー / チップ）が 560px で中央
   （x=436〜996）なのに対し、下のテンプレ格子は左端 x=32 から 1368px を使う。
   結果、(a) 入力欄だけが極端に狭く見え、(b) 縦の基準線が2本になって画面が整理されていない
   （可士和: 要素の左端が揃っていないのは論外）。founder 指摘 2026-07-29。

   ■ 対処
     1. 中央寄せをやめ、.games-section と同じ 32px のガターに左端を揃える
        → ページ全体を貫く縦線が1本になる。
     2. 入力欄の上限を 560 → 760px に広げる
        → 全幅（1368px）にはしない。1行のプロンプトを打つ欄が1368px あると視線移動が長く、
          読み返しづらい。760px は「主役として十分大きく、かつ1行を読み切れる」上限。
        → チップ行も 760px になるので、PC では例文が3枚見えるようになる（従来は2枚）。
   ══════════════════════════════════════════════════════════════════════ */
@media (min-width: 769px) {
  /* ページ全体を1本の柱に収めて中央に置く。
     founder 指摘 2026-07-30「このスペースに違和感しかない」。
     1680px 実測で、ヒーロー（コンポーザー/完成カード）が右端 792px で終わるのに対し
     テンプレ格子は 1640px まで伸びており、右に 848px の空白が残っていた。
     これは「余白」ではなく「余り」で、上が760px・下が全幅という2つの幅が
     同じページに同居していることの結果（可士和: グリッドは1つ）。
     コンテンツ全体に上限を与えて中央に置けば、余りは左右対称の余白になり
     意図した設計として読める。上限 1040px は、
       ・テンプレ格子7列が1列139pxになる（モバイル3列の112pxより大きく、絵が潰れない）
       ・ヒーロー760pxとの差が216pxに収まり、内側の段差が気にならない
     の2条件から決めた値。 */
  .create-hero,
  body[data-page="create"] .games-section {
    width: 100%;
    max-width: 1040px;
    margin-inline: auto;
  }
  .create-hero {
    align-items: flex-start;
    padding-left: var(--s-32);
    padding-right: var(--s-32);
  }
  /* ページ自体に 1040px の上限が付いたので、ヒーロー側の 760px 上限は外す。
     760px を残すと「上が760・下が976」という2つ目の幅ができ、
     コンポーザーの右に216pxの余りが残る＝founder が2度指摘した違和感の原因そのもの。
     可士和の原則どおりグリッドは1つにする（h1・入力欄・チップ・完成カード・
     つづきから・テンプレ格子すべてが同じ左右端に載る）。
     1368px のような極端な幅にはならないのは、上のページ上限が効いているため。 */

}

/* ── テンプレのジャンル節（3D / 2D / 画像を差し替える）──────────────────
   見出しの第3段。h2「テンプレートから作る」(1.2rem/900) より一段落として、
   「マイプロジェクト / おすすめテンプレート / 3D TPS・FPS / 3D その他 / 2D / ピクトミックス」が
   同じ強さで6本並んでいた状態（＝階層が無い）に戻らないようにする。 */

/* ジャンルごとの「すべて見る」（founder 指示 2026-07-29: ジャンルごとのリンクは必須）。
   総数を出すのは「18件だけの棚」ではなく「95本の入口」だと分からせるため。 */

/* ── テンプレ格子（3列マソンリー）──────────────────────────────────
   本番 style.css には既に Pinterest 型の .create-template-grid（column-count:2 /
   nth-child で 3:4・1:1・4:5・9:16 と比率を変える / 画像全面＋下からの黒グラデにタイトルを白抜き）
   が眠っていたので、それをそのまま起こして列数だけ 2→3 にした。
   横スクロール棚は1画面に2枚しか映らなかったが、3列格子なら9〜11枚が同時に見える
   （founder 指摘 2026-07-29: テンプレートが多く画面に写っている方がいい）。
   サムネは 260x563 のスマホ実機スクショなので、112px 幅でも何のゲームかは読める。 */

/* モバイルに hover は無い。押した手応え（:active）は必ず返す。
   本番の .featured-remix-card:hover（translateY）は @media で隔離されておらず、
   Jayden/Sofia の指には一切返っていなかった＝カードは押しても無反応だった。 */

/* ── つづきから: 状態チップ + 相対時刻 + 単色サムネ ──────────────────
   旧実装は4件すべて「新しいゲーム / 2026年7月29日」で、サムネは index から機械生成した
   ランダムなグラデーション（赤→黄, 緑→黄…）だった。行を見分ける手がかりが無く、
   しかも1色運用（--red のみ）をページ内で唯一壊していた。 */

/* ==================== お知らせモーダル ====================
   ログイン時に1回だけ出すポップアップ。本文は DB（announcements テーブル）から来る。
   .modal-overlay / .modal-content の既存作法に乗っているので、表示制御は `visible` クラス。 */

/* CTA は <a> なので .btn-primary が効かない（ボタン要素向けに書かれている）。
   継承に頼って素のリンク色で出てしまったため、ブランド色で明示指定する（2026-08-04）。 */

/* MOBILE-ONLY: ネイティブアプリではモーダルがノッチ／ホームインジケータに被りうる。
   値ではなくセレクタで分ける（env() は Web の iPhone Safari でも非ゼロになるため）。 */
