/* =============================================
   デザインの設定（ここを変えると全画面の見た目が変わる）
   ============================================= */
:root {
  /* 色 */
  --color-bg: #2b3a55; /* 一番うしろの背景 */
  --color-text: #ffffff; /* 基本の文字 */
  --color-text-dark: #2b3a55; /* 白いボタンの上の文字 */
  --color-primary: #ff7a59; /* メインのボタン（落とす・スタートなど） */
  --color-primary-shadow: #c4502f;
  --color-sub: #ffffff; /* サブのボタン（もどる・設定など） */
  --color-sub-shadow: #b9c4d6;
  --color-p1: #ff5d73; /* プレイヤー1 */
  --color-p1-shadow: #b83347;
  --color-p2: #3d8bff; /* プレイヤー2 */
  --color-p2-shadow: #2459a8;
  --color-gold: #ffd84d; /* ハイスコア */
  --color-on: #4cd964; /* スイッチ ON */
  --color-off: #c7cdd8; /* スイッチ OFF */
  --color-dim: rgba(20, 30, 55, 0.6); /* ポーズ画面などで後ろを暗くする色 */
  --color-panel: rgba(255, 255, 255, 0.12); /* 設定の行などの下地 */

  /* フォント */
  --font-main: "Hiragino Maru Gothic ProN", "Rounded Mplus 1c", "BIZ UDPGothic", "Yu Gothic", sans-serif;
  --font-size-s: 13px;
  --font-size-m: 17px;
  --font-size-l: 24px;
  --font-size-xl: 40px;

  /* 角丸 */
  --radius-s: 10px;
  --radius-m: 18px;
  --radius-l: 24px;
  --radius-round: 999px;

  /* 余白 */
  --space-xs: 4px;
  --space-s: 8px;
  --space-m: 16px;
  --space-l: 24px;
  --space-xl: 32px;

  /* ボタン */
  --button-depth: 5px; /* ボタンの立体感（下の影の厚み） */
  --button-height: 60px;

  /* アニメーションの時間 */
  --dur-screen: 0.3s; /* 画面の切りかえ */
  --dur-press: 0.08s; /* ボタンを押したとき */

  /* iPhone のノッチ・ホームバーの分の余白（対応していない端末では 0） */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
}

/* ===== 全体 ===== */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  -webkit-tap-highlight-color: transparent; /* タップしたときの青い枠を消す */
  -webkit-user-select: none;
  user-select: none;
}

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--color-bg);
  font-family: var(--font-main);
  color: var(--color-text);
  overscroll-behavior: none; /* 引っぱって更新、などを防ぐ */
  touch-action: manipulation; /* ダブルタップで画面が拡大されないようにする */
  -webkit-touch-callout: none; /* 長押しで「画像を保存」などのメニューが出ないようにする */
  -webkit-text-size-adjust: 100%; /* 横向きにしたときに文字が勝手に大きくならないようにする */
}

/* 文章の折り返し：
   ・word-break: auto-phrase … 文節（「ランキングに」「載ります」など）の切れ目で改行し、言葉の途中で切らない
     （html の lang="ja" で効く。Chrome・Edge・Android。iPhone の Safari では、今までどおりの改行）
   ・overflow-wrap: break-word … 1つの文節が行に入りきらないときは、その中で改行する（はみ出さないように）
   ・text-wrap: pretty … 最後の行が1〜2文字だけにならないように、前の行から少し送る
   1行に収めたいところ（名前・ボタン・札など）は、それぞれの場所で white-space: nowrap にしている */
body {
  word-break: auto-phrase;
  overflow-wrap: break-word;
  text-wrap: pretty;
}

/* 見出し・ボタンは、行の長さをそろえる（1行目だけ長くて、2行目が短い、にならないように） */
h1,
h2,
h3,
.btn {
  text-wrap: balance;
}

img {
  -webkit-user-drag: none; /* 画像を指で引っぱって動かせないようにする */
}

/* 入力欄では、文字の選択やコピー・貼り付けができるように戻す */
input,
select {
  -webkit-touch-callout: default;
}

/* ゲーム画面全体。縦長（9:16）より横に広がらないようにして、画面の中央に置く。
   スマホの縦画面ではほぼ画面いっぱい。パソコンなど横長の画面では、中央に縦長の画面が出る
   （横に広げると、縦に入る範囲が狭くなって、土台が画面の外に出てしまうため） */
#app {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  width: 100%;
  max-width: calc(100vh * 9 / 16);
  max-width: calc(100dvh * 9 / 16); /* スマホのアドレスバーを除いた高さ（対応ブラウザのみ） */
  margin: 0 auto;
  overflow: hidden;
  box-shadow: 0 0 40px rgba(0, 0, 0, 0.35);
}

.hidden {
  display: none !important;
}

/* ゲームのキャンバス：画面いっぱい。指の操作をブラウザに取られないようにする */
#game-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  touch-action: none;
}

/* =============================================
   ボタン（全画面共通）
   ============================================= */
.btn {
  border: none;
  font-family: inherit;
  font-weight: bold;
  color: var(--color-text-dark);
  background: var(--color-sub);
  box-shadow: 0 var(--button-depth) 0 var(--color-sub-shadow);
  touch-action: manipulation;
  cursor: pointer;
  transition: transform var(--dur-press), box-shadow var(--dur-press), filter var(--dur-press);
}

/* 押したとき：少し縮んで、沈んで、色が暗くなる */
.btn:active:not(:disabled) {
  transform: translateY(calc(var(--button-depth) - 1px)) scale(0.95);
  box-shadow: 0 1px 0 var(--color-sub-shadow);
  filter: brightness(0.88);
}

.btn:disabled {
  opacity: 0.5;
  cursor: default;
}

/* 色のちがうボタン */
.btn-primary { color: #fff; background: var(--color-primary); --color-sub-shadow: var(--color-primary-shadow); }
.btn-p1 { color: #fff; background: var(--color-p1); --color-sub-shadow: var(--color-p1-shadow); }
.btn-p2 { color: #fff; background: var(--color-p2); --color-sub-shadow: var(--color-p2-shadow); }
.btn-sub { /* 白（基本のまま） */ }

/* 大きいボタン（メニュー用） */
.btn-big {
  width: 100%;
  min-height: var(--button-height);
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-l);
  font-size: var(--font-size-l);
}

.btn-big small {
  display: block;
  margin-top: 2px;
  font-size: var(--font-size-s);
  line-height: 1.3;
  opacity: 0.9;
}

.btn-sub.btn-big {
  font-size: var(--font-size-m);
}

/* 丸いアイコンボタン（ポーズ） */
.btn-icon {
  width: 46px;
  height: 46px;
  flex-shrink: 0;
  border-radius: var(--radius-round);
  font-size: 16px;
  --button-depth: 3px;
}

/* ゲーム中の操作ボタン */
.btn-ctrl {
  flex: 1;
  height: 64px;
  border-radius: var(--radius-m);
  font-size: 20px;
  white-space: nowrap; /* 回転・反転・落とすの3つが、スマホの幅に1行で並ぶように */
}

.btn-ctrl.btn-primary {
  flex: 1.4;
}

/* =============================================
   ゲーム中の表示（HUD・操作ボタン）
   ============================================= */
.game-ui {
  position: absolute;
  left: 0;
  right: 0;
  z-index: 5;
  transition: opacity var(--dur-screen), transform var(--dur-screen);
}

/* ゲーム中以外は、上下にスッと隠れる */
.game-ui.off {
  opacity: 0;
  pointer-events: none;
}

#hud.off { transform: translateY(-20px); }
#controls.off { transform: translateY(20px); }

#hud {
  top: 0;
  display: flex;
  align-items: flex-start;
  gap: var(--space-s);
  padding: calc(var(--space-s) + var(--safe-top)) calc(var(--space-m) + var(--safe-right)) 0 calc(var(--space-m) + var(--safe-left));
  pointer-events: none; /* キャンバスのドラッグを邪魔しない */
}

#hud .btn {
  pointer-events: auto;
}

#hud-info {
  flex: 1;
  font-size: 15px;
  font-weight: bold;
  line-height: 1.4;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
}

#hud-info .big {
  font-size: 26px;
}

#controls {
  bottom: 0;
  display: flex;
  gap: var(--space-m);
  padding: var(--space-m) calc(var(--space-m) + var(--safe-right)) calc(var(--space-m) + var(--safe-bottom)) calc(var(--space-m) + var(--safe-left));
}

/* プレイヤーの色のラベル */
.player-tag {
  display: inline-block;
  max-width: 100%;
  padding: var(--space-xs) var(--space-m);
  border-radius: var(--radius-round);
  color: #fff;
  /* 長い名前のときだけ小さくして、1行に収める（--fit は名前の長さ。main.js の UI.fit） */
  font-size: clamp(13px, calc(min(52vw, 240px) / var(--fit, 1)), 20px);
  white-space: nowrap;
  text-shadow: none;
}

.p1 { background: var(--color-p1); }
.p2 { background: var(--color-p2); }

/* 「P1 の番」バナー */
#turn-banner {
  position: absolute;
  left: 0;
  right: 0;
  top: 38%;
  z-index: 6;
  padding: var(--space-m) var(--space-s);
  text-align: center;
  /* 長い名前のときだけ小さくする（--fit は文字の長さ。main.js の showTurnBanner） */
  font-size: clamp(22px, calc(min(88vw, 400px) / var(--fit, 1)), 44px);
  font-weight: bold;
  letter-spacing: 0.05em;
  pointer-events: none;
  animation: banner 1.2s ease-out forwards;
}

@keyframes banner {
  0% { transform: scaleY(0); opacity: 0; }
  15% { transform: scaleY(1); opacity: 1; }
  80% { opacity: 1; }
  100% { opacity: 0; }
}

/* =============================================
   画面（タイトル・モード選択・ポーズ・設定・リザルト）
   ============================================= */
.screen {
  position: absolute;
  inset: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow-y: auto;
  padding: calc(var(--space-l) + var(--safe-top)) calc(var(--space-m) + var(--safe-right)) calc(var(--space-l) + var(--safe-bottom)) calc(var(--space-m) + var(--safe-left));
  text-align: center;
  background: rgba(30, 45, 80, 0.45);
  /* 非表示のとき：透明で、少し下にずれている */
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--dur-screen) ease, visibility 0s linear var(--dur-screen);
}

.screen-inner {
  width: 100%;
  max-width: 340px;
  transform: translateY(24px);
  transition: transform var(--dur-screen) ease;
}

/* 表示中：フェードインしながら、中身が下からスッと上がってくる */
.screen.active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity var(--dur-screen) ease, visibility 0s;
}

.screen.active .screen-inner {
  transform: none;
}

/* ゲームの上に重ねる画面（ポーズ・設定・リザルト）は後ろを暗くする */
.screen-dim {
  background: var(--color-dim);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

/* =============================================
   タイトル画面
   ============================================= */
/* 背景はキャンバス（空・雲・デモ）が見えるように透明にする */
.screen-clear {
  background: none;
}

/* 上・中央・下の3段に分ける。縦長の端末でも間延びしないよう、全体の高さに上限をつける */
.title-layout {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 340px;
  height: 100%;
  max-height: 760px;
  padding: max(6vh, 56px) 0 3vh;
}

/* タイトル画面ではボタンなどが操作できるよう、デモ（キャンバス）より手前に */
.title-top,
.title-middle,
.title-bottom {
  width: 100%;
}

/* ハイスコアはロゴのすぐ下に寄せ、真ん中の空間はデモの塔が見えるように空けておく */
.title-middle {
  margin-top: var(--space-m);
}

.title-bottom {
  margin-top: auto;
}

/* =============================================
   タイトル画面の演出（タイミングの数値は config.js の titleFx。title-fx.js が CSS の変数にする）
   登場：ロゴが1文字ずつ弾んで出る → タグライン → スタートボタン・メニューが下から出る
   ============================================= */
/* ロゴ：1文字ずつ弾んで登場（.logo-char）→ その後ふわふわ上下（.logo）、ときどきキラッ（.logo-shine） */
.logo {
  position: relative;
  font-size: 44px;
  line-height: 1.15;
  text-shadow: 0 5px 0 var(--color-primary), 0 8px 14px rgba(0, 0, 0, 0.3);
  animation: float var(--float-time, 3.2s) ease-in-out var(--logo-done, 0.8s) infinite;
}

.logo-char {
  display: inline-block;
  animation: char-pop 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) calc(var(--logo-start, 0.15s) + var(--i) * var(--logo-step, 0.07s)) both;
}

@keyframes char-pop {
  0% { transform: translateY(-40px) scale(0.3); opacity: 0; }
  55% { transform: translateY(4px) scale(1.2, 0.85); opacity: 1; }
  75% { transform: translateY(-4px) scale(0.95, 1.08); }
  100% { transform: none; opacity: 1; }
}

/* キラッと光る層：同じ文字を透明にして重ね、斜めの光の帯を文字の形で切り抜いて流す */
.logo-shine {
  position: absolute;
  inset: 0;
  color: transparent;
  text-shadow: none;
  background: linear-gradient(105deg, transparent 40%, rgba(255, 255, 255, 0.95) 50%, transparent 60%) no-repeat;
  background-size: 300% 100%;
  background-position: 100% 0;
  -webkit-background-clip: text;
  background-clip: text;
  pointer-events: none;
}

.logo-shine.on {
  animation: logo-shine 0.9s ease-in-out;
}

@keyframes logo-shine {
  from { background-position: 100% 0; }
  to { background-position: 0 0; }
}

/* 下から弾んで出てくる（スタートボタン・メニュー） */
@keyframes rise-up {
  0% { transform: translateY(60px); opacity: 0; }
  70% { transform: translateY(-6px); opacity: 1; }
  100% { transform: none; opacity: 1; }
}

/* メニューのアイコンを押したとき：少し縮んで、ぽよんと戻る */
.menu-icon.pressed {
  animation: icon-press 0.32s ease-out;
}

@keyframes icon-press {
  0% { transform: scale(1); }
  35% { transform: scale(0.86); }
  70% { transform: scale(1.06); }
  100% { transform: scale(1); }
}

/* タイトル以外の画面のあいだは、タイトルのくり返しの動きを止める（スマホを重くしないため） */
#screen-title:not(.active) * {
  animation-play-state: paused !important;
}

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

.tagline {
  margin-top: var(--space-m);
  font-size: 18px;
  font-weight: bold;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
  animation: fade-up 0.5s ease var(--tagline-at, 0.5s) both;
}

/* ハイスコアのカード */
.best-card {
  display: inline-block;
  min-width: 180px;
  padding: 6px var(--space-l);
  border-radius: var(--radius-m);
  background: rgba(30, 45, 80, 0.45);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  font-size: var(--font-size-s);
  animation: fade-up 0.5s ease calc(var(--tagline-at, 0.5s) + 0.1s) both;
}

.best-card b {
  display: block;
  font-size: 26px;
  line-height: 1.15;
  color: var(--color-gold);
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.2);
}

/* スタートボタン：下から弾んで出てくる → 脈打つように拡大縮小をくり返す */
/* スタートボタン
   登場（下からせり上がる）と、脈打つ動きは、外側の .btn-start-wrap に付ける。
   ボタンそのものにアニメーションを付けて、押したあいだだけ止める（animation: none）書き方にすると、
   iPhone の Safari では指を離した瞬間にアニメーションが最初からやり直しになり、ボタンが下へ消えるため、
   「指を離した場所にボタンが無い」ことになって押せなくなる。
   脈打つ動きは、押せるようになってから（main.js が .ready を付けてから） */
.btn-start-wrap {
  width: 100%;
  animation: rise-up 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) var(--button-at, 0.9s) both;
}

.btn-start-wrap.ready {
  animation: rise-up 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) var(--button-at, 0.9s) both,
    breathe var(--pulse-time, 1.6s) ease-in-out calc(var(--button-at, 0.9s) + 0.6s) infinite;
}

.btn-start {
  min-height: 72px;
  font-size: 28px;
}

@keyframes fade-up {
  from { transform: translateY(16px); opacity: 0; }
  to { transform: none; opacity: 1; }
}

@keyframes breathe {
  0%, 100% { transform: scale(1); }
  12% { transform: scale(1.06); }
  24% { transform: scale(1.01); }
  36% { transform: scale(1.04); }
  60% { transform: scale(1); }
}

/* 押している間は、拡大縮小より「押した見た目」を優先 */
/* 右上の小さいボタン（歯車） */
.btn-corner {
  position: absolute;
  top: calc(var(--space-m) + var(--safe-top));
  right: calc(var(--space-m) + var(--safe-right));
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: fade-up 0.5s ease 1s both;
}

/* タイトル画面：アプリとしてインストールの案内（メニューのすぐ下の小さな帯。pwa.js） */
.install-hint {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-s);
  margin-top: var(--space-s);
  animation: fade-up 0.5s ease 1.4s both;
}

.install-hint-main {
  padding: 6px 14px;
  border: 0;
  border-radius: var(--radius-round);
  color: var(--color-text-dark);
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 2px 0 var(--color-sub-shadow);
  font-family: inherit;
  font-size: 13px;
  font-weight: bold;
  cursor: pointer;
}

.install-hint-later {
  padding: 6px 8px;
  border: 0;
  color: inherit;
  background: none;
  font-family: inherit;
  font-size: 12px;
  text-decoration: underline;
  opacity: 0.85;
  cursor: pointer;
}

/* リザルト画面：初めてのゲームのあとに1度だけ出る、アプリとしてインストールの案内 */
.result-install {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px var(--space-s);
  margin: var(--space-s) 0;
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-m);
  font-size: 13px;
  font-weight: bold;
  background: rgba(255, 255, 255, 0.14);
}

/* インストールの手順のダイアログ */
.install-guide-box {
  text-align: left;
}

.dialog-box .install-guide-title {
  margin: 0 0 var(--space-s);
  font-size: 17px;
  text-align: center;
}

.install-guide-steps {
  margin: 0 0 var(--space-m);
  text-align: left;
  padding-left: 1.4em;
  font-size: 14px;
  line-height: 1.7;
}

.install-guide-steps li + li {
  margin-top: 6px;
}

/* 共有ボタン（□に↑）・ホーム画面に追加（□に＋）の絵 */
.install-share-icon {
  display: inline-block;
  width: 22px;
  height: 22px;
  margin: 0 2px;
  padding: 2px;
  border-radius: 6px;
  vertical-align: middle;
  color: #2f7cf6;
  background: #eef3fb;
}

/* 右下のバージョン番号 */
.version {
  position: absolute;
  right: calc(var(--space-m) + var(--safe-right));
  bottom: calc(var(--space-s) + var(--safe-bottom));
  font-size: 11px;
  opacity: 0.7;
  padding: 6px 0 6px 12px; /* 管理者モードの入り口なので、少しだけタップしやすく */
  cursor: default;
}

/* タイトル下部のアイコンメニュー（6つを横に並べる） */
.title-menu {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--space-xs);
  margin-top: var(--space-m);
  animation: rise-up 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) var(--menu-at, 1.1s) both;
}

.menu-icon {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: var(--space-s) 0 6px;
  border: none;
  border-radius: var(--radius-s);
  font-family: inherit;
  font-size: 10px;
  font-weight: bold;
  color: var(--color-text);
  background: rgba(30, 45, 80, 0.45);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  touch-action: manipulation;
  cursor: pointer;
  transition: transform var(--dur-press), filter var(--dur-press);
}

.menu-icon:active {
  transform: scale(0.92);
  filter: brightness(0.85);
}

.menu-icon svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.menu-icon span {
  white-space: nowrap;
  letter-spacing: -0.03em;
}

/* 未読があることを知らせる赤い点 */
.badge {
  position: absolute;
  top: 4px;
  right: 8px;
  width: 10px;
  height: 10px;
  border: 2px solid #fff;
  border-radius: 50%;
  background: #ff3b30;
}

/* 左上のプロフィール表示 */
.profile-chip {
  position: absolute;
  top: calc(var(--space-m) + var(--safe-top));
  left: calc(var(--space-m) + var(--safe-left));
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--space-s);
  max-width: 60%;
  padding: 4px var(--space-m) 4px 4px;
  border: none;
  border-radius: var(--radius-round);
  font-family: inherit;
  color: var(--color-text);
  text-align: left;
  background: rgba(30, 45, 80, 0.45);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  cursor: pointer;
  animation: fade-up 0.5s ease 1s both;
  transition: transform var(--dur-press);
}

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

.profile-chip-text {
  min-width: 0;
  line-height: 1.2;
}

.profile-chip-text b,
.profile-chip-text small {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.profile-chip-text b {
  font-size: 14px;
}

.profile-chip-text small {
  font-size: 10px;
  color: var(--color-gold);
}

/* 丸いアイコン（写真は背景画像として表示し、丸く切り抜く） */
.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border: 2px solid #fff;
  border-radius: 50%;
  background: #8fa3c4 center / cover no-repeat;
  color: #fff;
  font-size: 16px;
  font-weight: bold;
}

/* 写真が無いときは、名前の1文字目を表示 */
.avatar-empty {
  background-color: var(--color-primary);
}

.avatar-xl {
  width: 112px;
  height: 112px;
  border-width: 4px;
  font-size: 44px;
}

/* =============================================
   サブ画面（プロフィール・お知らせ・ランキングなど）
   上に「もどる＋見出し」、その下に縦にスクロールする中身
   ============================================= */
.screen.page {
  align-items: stretch;
  padding: calc(var(--space-s) + var(--safe-top)) calc(var(--space-m) + var(--safe-right)) var(--safe-bottom) calc(var(--space-m) + var(--safe-left));
  overflow: hidden;
}

.page-inner {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 420px;
  height: 100%;
  margin: 0 auto;
  transform: translateY(24px);
  transition: transform var(--dur-screen) ease;
}

.screen.active .page-inner {
  transform: none;
}

.page-header {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  padding: var(--space-s) 0;
}

.page-header .btn-icon {
  font-size: 28px;
  line-height: 1;
}

.page-header h2 {
  min-width: 0;
  overflow: hidden;
  font-size: clamp(18px, 5.6vw, var(--font-size-l)); /* 小さいスマホでは少し小さく（右の数と並んでも1行に） */
  white-space: nowrap;
  text-overflow: ellipsis;
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.2);
}

.page-body {
  flex: 1;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: var(--space-s) 0 var(--space-xl);
  text-align: left;
}

/* 画面の一番下に固定する欄（ランキングの「あなたの記録」など） */
.page-footer {
  padding: var(--space-s) 0 calc(var(--space-m));
}

.page-note {
  margin-top: var(--space-m);
  font-size: var(--font-size-s);
  line-height: 1.5;
  opacity: 0.8;
}

/* 下地のある四角（詳細の本文などを入れる） */
.panel {
  padding: var(--space-m);
  border-radius: var(--radius-m);
  background: var(--color-panel);
}

/* 一覧の1行（タップできる） */
.list-row {
  display: block;
  width: 100%;
  margin-bottom: var(--space-s);
  padding: var(--space-m);
  border: none;
  border-radius: var(--radius-m);
  font-family: inherit;
  color: var(--color-text);
  text-align: left;
  background: var(--color-panel);
  cursor: pointer;
  transition: transform var(--dur-press), filter var(--dur-press);
}

.list-row:active {
  transform: scale(0.98);
  filter: brightness(0.9);
}

/* 一覧が空のとき・読み込めないときの文 */
.empty-message {
  margin-top: var(--space-xl);
  font-size: var(--font-size-m);
  line-height: 1.7;
  text-align: center;
  opacity: 0.85;
}

/* お知らせ */
.news-meta {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  font-size: 12px;
}

.type-tag {
  padding: 2px var(--space-s);
  border-radius: var(--radius-round);
  font-weight: bold;
  color: #fff;
}

.type-update { background: var(--color-p2); }
.type-event { background: var(--color-p1); }

.news-date {
  opacity: 0.8;
}

.new-tag {
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: bold;
  color: var(--color-text-dark);
  background: var(--color-gold);
}

.news-title {
  display: block;
  margin-top: 6px;
  font-size: var(--font-size-m);
  line-height: 1.4;
}

.news-detail-title {
  margin-top: var(--space-s);
  font-size: 20px;
  line-height: 1.4;
}

.news-body {
  margin-top: var(--space-m);
  font-size: 15px;
  line-height: 1.8;
  white-space: pre-line; /* JSON の本文の \n で改行する */
  -webkit-user-select: text;
  user-select: text;
}

/* 起動時のポップアップ（白い箱なので文字は濃い色） */
.dialog-box.news-popup-box {
  text-align: left;
}

.news-popup-box #news-popup-content {
  max-height: 50vh;
  overflow-y: auto;
}

.news-popup-box .news-date {
  color: var(--color-text-dark);
}

.news-popup-box .news-body,
.news-popup-box .news-more {
  font-size: 15px;
  font-weight: normal;
}

.news-more {
  margin-top: var(--space-m);
  font-size: var(--font-size-s);
  opacity: 0.7;
}

/* ランキング */
.ranking-updated {
  margin-bottom: var(--space-s);
  font-size: 12px;
  text-align: right;
  opacity: 0.8;
}

.rank-row {
  display: flex;
  align-items: center;
  gap: clamp(6px, 2.2vw, var(--space-m)); /* スマホでは間を少しつめて、名前・称号の幅を広げる */
  height: 84px; /* どの人の行も同じ高さ（名前・称号・積んだ数がそれぞれ1行） */
  margin-bottom: var(--space-s);
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-m);
  background: var(--color-panel);
}

.rank-num {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  font-size: var(--font-size-m);
  font-weight: bold;
  background: rgba(255, 255, 255, 0.15);
}

.rank-main {
  flex: 1;
  min-width: 0;
  line-height: 1.3;
}

.rank-main b {
  display: block;
  overflow: hidden;
  font-size: clamp(14px, 4.4vw, var(--font-size-m));
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* 名前・称号・積んだ数などは、それぞれ1行（長いときは「…」）。どの人の行も同じ高さになるように */
.rank-main small {
  display: block;
  overflow: hidden;
  font-size: 11px;
  white-space: nowrap;
  text-overflow: ellipsis;
  opacity: 0.8;
}

.rank-main .title-badge {
  display: block;
  width: fit-content;
  max-width: 100%;
  margin: 1px 0;
}

/* ランキングの名前の行：長い名前だけ「…」にして、開発者の印・「あなた」はいつも全部見せる */
.rank-main b.rank-name {
  display: flex;
  align-items: center;
  min-width: 0;
}

.rank-name-text {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.rank-name .rank-you {
  flex-shrink: 0;
}

/* ランキングの行では、開発者の印は名前のすぐ下（称号の札の場所）に出す */
.rank-dev {
  display: block;
  margin: 1px 0;
}

.rank-dev .title-badge {
  margin-left: 0;
}

/* ランキングの1〜3位の王冠（アイコンの上。ふちの星よりさらに上） */
.rank-avatar-wrap {
  position: relative;
  flex-shrink: 0;
  display: inline-flex;
}

.rank-crown {
  position: absolute;
  left: 50%;
  top: -24px;
  width: 22px;
  height: 15px;
  transform: translateX(-50%);
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.35));
  pointer-events: none;
}

.rank-crown svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* 部門の見出し（手で書く ranking.json に divisions があるとき） */
.ranking-division {
  margin: var(--space-m) 0 var(--space-s);
}

/* 称号を選んでいない人（ランキング） */
.title-badge.title-empty {
  color: rgba(255, 255, 255, 0.75);
  background: rgba(255, 255, 255, 0.12);
  font-weight: normal;
}

/* パソコンの横長の画面だけで使う、表の列（積んだ数・高さ・日付）と見出しの行。スマホでは出さない */
.rank-col,
.rank-head {
  display: none;
}

.rank-score {
  flex-shrink: 0;
  font-size: clamp(16px, 5vw, 22px); /* スマホでは少し小さく（名前・称号の幅を広げる） */
  font-weight: bold;
  text-align: right;
  line-height: 1.1;
}

.rank-score small {
  margin-left: 2px;
  font-size: 12px;
}

.rank-score em {
  display: block;
  font-size: 11px;
  font-style: normal;
  font-weight: normal;
  opacity: 0.8;
}

/* 上位3位：金・銀・銅 */
.rank-gold { background: linear-gradient(135deg, rgba(255, 216, 77, 0.45), rgba(255, 216, 77, 0.15)); }
.rank-silver { background: linear-gradient(135deg, rgba(220, 228, 240, 0.45), rgba(220, 228, 240, 0.15)); }
.rank-bronze { background: linear-gradient(135deg, rgba(214, 140, 80, 0.5), rgba(214, 140, 80, 0.15)); }
.rank-gold .rank-num { color: #5a4300; background: #ffd84d; }
.rank-silver .rank-num { color: #3c4656; background: #dce4f0; }
.rank-bronze .rank-num { color: #fff; background: #c27a45; }
.rank-gold, .rank-silver, .rank-bronze { padding-top: var(--space-m); padding-bottom: var(--space-m); }
.rank-gold .rank-score { color: var(--color-gold); font-size: clamp(18px, 5.8vw, 26px); }

/* ランキングがまだ無いとき（準備中） */
.coming-soon {
  margin-top: var(--space-xl);
  padding: var(--space-xl) var(--space-l);
  border-radius: var(--radius-l);
  text-align: center;
  background: var(--color-panel);
}

.coming-soon span {
  display: block;
  font-size: 48px;
}

.coming-soon b {
  display: block;
  margin-top: var(--space-s);
  font-size: 20px;
}

.coming-soon p {
  margin-top: var(--space-s);
  font-size: var(--font-size-s);
  line-height: 1.7;
  opacity: 0.85;
}

/* 画面の下の「あなたのハイスコア」 */
.my-record {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  padding: var(--space-l) var(--space-m) var(--space-s);
  border-radius: var(--radius-m);
  background: rgba(255, 122, 89, 0.35);
}

.my-record .player-badge {
  margin: 0;
  min-width: 0;
}

/* 名前は1行で（長ければ「…」）。右のスコアと注意書きは、名前を押しつぶさないよう縮めて折り返す */
.my-record .player-badge b {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.my-record .player-badge > :last-child {
  min-width: 0;
}

.my-record .rank-score {
  flex-shrink: 1;
  min-width: 0;
}

/* 「120体・30.55m」は1行で */
.my-record .rank-score em {
  white-space: nowrap;
}

.my-record-label {
  position: absolute;
  top: 6px;
  left: var(--space-m);
  font-size: 11px;
  font-weight: bold;
}

.my-record-none {
  font-size: var(--font-size-s);
  opacity: 0.85;
}

/* 戦績 */
.section-title {
  margin: var(--space-l) 0 var(--space-s);
  font-size: var(--font-size-m);
}

.section-title:first-child {
  margin-top: var(--space-s);
}

.stat-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-s);
}

.stat-item {
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-m);
  background: var(--color-panel);
}

.stat-item span {
  display: block;
  overflow: hidden;
  font-size: 12px;
  white-space: nowrap;
  text-overflow: ellipsis;
  opacity: 0.85;
}

.stat-item b {
  font-size: 24px;
}

.stat-item small {
  margin-left: 2px;
  font-size: 12px;
}

/* 見出しの右の数（図鑑の「3 / 12体」など） */
.header-count {
  flex-shrink: 0;
  margin-left: auto;
  padding: 4px var(--space-m);
  border-radius: var(--radius-round);
  font-size: clamp(11px, 3.4vw, var(--font-size-s));
  white-space: nowrap;
  font-weight: bold;
  background: var(--color-panel);
}

/* キャラ図鑑 */
.dex-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)); /* 3列を同じ幅に（長い名前で列が広がらないように） */
  gap: var(--space-s);
}

.dex-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: var(--space-s) var(--space-xs);
  border: none;
  border-radius: var(--radius-m);
  font-family: inherit;
  color: var(--color-text);
  background: var(--color-panel);
  cursor: pointer;
  transition: transform var(--dur-press);
}

.dex-card:active:not(:disabled) {
  transform: scale(0.95);
}

.dex-img {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 84px;
}

.dex-img img {
  max-width: 100%;
  max-height: 100%;
}

/* 未登録：画像を黒く塗りつぶしてシルエットにする */
.dex-locked {
  cursor: default;
}

.dex-locked img {
  filter: brightness(0);
  opacity: 0.55;
}

.dex-no {
  margin-top: var(--space-xs);
  font-size: 10px;
  opacity: 0.7;
}

.dex-name {
  max-width: 100%;
  font-size: 12px;
  line-height: 1.3;
  text-align: center;
  overflow-wrap: anywhere; /* 長い名前（ビッグブンリキエイリアンなど）は、切らずに折り返す */
}

.dex-detail-img {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 200px;
  border-radius: var(--radius-m);
  background: linear-gradient(#bfe4fa, #e8f5ff);
}

.dex-detail-img img {
  max-width: 90%;
  max-height: 90%;
}

.dex-detail-name {
  margin-top: var(--space-m);
  font-size: 22px;
}

.dialog-box .dex-detail-text {
  margin-top: var(--space-s);
  font-size: 15px;
  font-weight: normal;
  text-align: left;
}

.dialog-box .dex-detail-date {
  margin-top: var(--space-s);
  font-size: 12px;
  font-weight: normal;
  opacity: 0.6;
}

/* 実績 */
.ach-row {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  margin-bottom: var(--space-s);
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-m);
  background: var(--color-panel);
}

.ach-done {
  background: linear-gradient(135deg, rgba(255, 216, 77, 0.35), rgba(255, 216, 77, 0.1));
}

.ach-locked {
  opacity: 0.6;
}

.ach-icon {
  flex-shrink: 0;
  font-size: 26px;
}

.ach-main {
  flex: 1;
  min-width: 0;
  line-height: 1.35;
}

.ach-main b {
  display: block;
  font-size: 15px;
}

.ach-main small {
  display: block;
  font-size: 12px;
  opacity: 0.85;
}

.ach-title {
  font-size: 12px;
  font-weight: bold;
  color: var(--color-gold);
}

.ach-locked .ach-title {
  color: inherit;
}

/* 実績のごほうび（背景・土台。achievements.json の reward） */
.ach-reward {
  display: inline-block;
  margin-left: 6px;
  color: #8fe3ff;
  white-space: nowrap;
}

.ach-locked .ach-reward {
  color: inherit;
  opacity: 0.85;
}

.ach-date {
  flex-shrink: 0;
  font-size: 11px;
  opacity: 0.8;
}

.toast-medal {
  font-size: 24px;
}

.toast-sub {
  display: block;
  font-size: 11px;
  opacity: 0.75;
}

/* 通知の中の小さい画像（図鑑登録など） */
.toast-img {
  height: 32px;
}

/* レアキャラが出たときの「レア！」 */
.rare-banner {
  position: absolute;
  top: 34%;
  left: 0;
  right: 0;
  z-index: 6;
  text-align: center;
  pointer-events: none;
  animation: rare-pop 1.6s ease-out forwards;
}

.rare-banner span {
  display: inline-block;
  padding: 4px 24px;
  border-radius: var(--radius-round);
  font-size: clamp(20px, 8vw, 34px); /* 「みたことない！！！」もスマホの幅で1行に */
  white-space: nowrap;
  font-weight: bold;
  color: #fff;
  background: var(--rare-color);
  box-shadow: 0 0 24px var(--rare-color);
  text-shadow: 0 2px 0 rgba(0, 0, 0, 0.25);
}

.rare-banner small {
  display: block;
  margin-top: 6px;
  font-size: 15px;
  font-weight: bold;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}

/* めっちゃレア（★3）は虹色に光る */
.rare-banner.super span {
  background: linear-gradient(90deg, #ff5d73, #ffc21a, #4cd964, #3d8bff, #b65cf0);
  box-shadow: 0 0 30px #ffc21a;
}

@keyframes rare-pop {
  0% { opacity: 0; transform: scale(0.3); }
  15% { opacity: 1; transform: scale(1.15); }
  25% { transform: scale(1); }
  80% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-20px); }
}

/* 図鑑のレア度（★） */
.rarity-stars {
  font-size: 11px;
  letter-spacing: -1px;
  color: var(--rare-color);
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
}

/* ★5（まぼろし）の図鑑のカード：虹色の枠と、ゆっくり回る光 */
.dex-card.dex-legend {
  position: relative;
  border: 3px solid transparent;
  background:
    linear-gradient(var(--color-bg), var(--color-bg)) padding-box,
    conic-gradient(from var(--legend-angle, 0deg), #ff5d73, #ffc21a, #4cd964, #3d8bff, #b65cf0, #ff5d73) border-box;
  box-shadow: 0 0 14px rgba(126, 240, 255, 0.55);
  animation: legend-border 4s linear infinite;
}

@property --legend-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

@keyframes legend-border {
  to { --legend-angle: 360deg; }
}

/* ★6（シークレット）の図鑑のカード：黒い地に、金色の枠がゆっくり光りながら回る */
.dex-card.dex-secret {
  position: relative;
  border: 3px solid transparent;
  background:
    linear-gradient(#1a1408, #050402) padding-box,
    conic-gradient(from var(--legend-angle, 0deg), #ffd54a, #6b4a00, #fff1a8, #e0a000, #2a1d00, #ffd54a) border-box;
  box-shadow: 0 0 16px rgba(255, 213, 74, 0.6);
  animation: legend-border 3s linear infinite;
}

.dex-card.dex-secret .dex-name,
.dex-card.dex-secret .dex-no {
  color: #ffe9a0;
}

.dex-card.dex-secret .dex-question {
  color: #ffd54a;
  text-shadow: 0 0 10px rgba(255, 213, 74, 0.9);
}

/* ★6 の詳細：画像の後ろを黒く、金色の光で囲む */
.dex-detail-secret {
  border-radius: 12px;
  background: radial-gradient(circle at 50% 45%, rgba(255, 213, 74, 0.45), #0d0a03 70%);
  box-shadow: 0 0 0 2px #ffd54a, 0 0 18px rgba(255, 213, 74, 0.6);
}

/* まだ見つけていない★5は、シルエットではなく「？」 */
.dex-question {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 40px;
  font-weight: bold;
  color: #7ef0ff;
  text-shadow: 0 0 10px rgba(126, 240, 255, 0.8);
}

/* サイズ違いのキャラ：絵を大きく・小さく見せて、「BIG」「MINI」の札 */
.dex-img {
  position: relative;
}

.dex-variant-big img {
  transform: scale(1.15);
}

.dex-variant-small img {
  transform: scale(0.65);
}

.dex-size {
  position: absolute;
  right: 2px;
  bottom: 2px;
  padding: 0 5px;
  border-radius: 6px;
  color: #fff;
  background: #ff7a59;
  font-size: 9px;
  font-style: normal;
  font-weight: bold;
  line-height: 1.6;
}

.dex-size-small {
  background: #3d9bff;
}

/* 出現率のテスト（管理者メニュー） */
.admin-draw table {
  width: 100%;
  margin: var(--space-s) 0;
  border-collapse: collapse;
  font-size: 12px;
}

.admin-draw th,
.admin-draw td {
  padding: 3px 6px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.15);
  text-align: left;
  white-space: nowrap;
}

.admin-draw .admin-draw-rarity th,
.admin-draw .admin-draw-rarity td {
  padding-top: 8px;
  font-weight: bold;
  color: var(--color-gold);
}

@media (prefers-reduced-motion: reduce) {
  .dex-card.dex-legend,
  .dex-card.dex-secret {
    animation: none;
  }
}

.dex-card.dex-rare {
  box-shadow: inset 0 0 0 2px var(--rare-color);
}

.rarity-label {
  display: inline-block;
  margin-top: var(--space-xs);
  padding: 2px 12px;
  border-radius: var(--radius-round);
  font-size: 12px;
  font-weight: bold;
  color: #fff;
  background: var(--rare-color);
}

/* 背景・土台を選ぶ見本 */
.theme-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}

/* ===== 名前の色・お気に入りのキャラ（プロフィール。custom.js） ===== */
/* 色つきの名前：金（光が流れる）・虹色（色が流れる）。ほかの色は style の color */
.pname-gold,
.pname-rainbow {
  background-size: 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: pname-flow 3s linear infinite;
}

.pname-gold {
  background-image: linear-gradient(100deg, #c99a1e, #ffe58a 30%, #fff8d6 45%, #ffd54a 60%, #c99a1e);
}

.pname-rainbow {
  background-image: linear-gradient(90deg, #ff5d73, #ffb347, #ffe066, #6ee07a, #5ab8ff, #b07cff, #ff5d73);
}

@keyframes pname-flow {
  to { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .pname-gold,
  .pname-rainbow {
    animation: none;
  }
}

.name-colors {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  margin-bottom: var(--space-s);
}

.name-color {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 0;
  padding: 8px 4px;
  border: 2px solid transparent;
  border-radius: var(--radius-s);
  color: #fff;
  background: rgba(10, 16, 34, 0.55);
  font: inherit;
  cursor: pointer;
}

.name-color b {
  max-width: 100%;
  overflow: hidden;
  font-size: var(--font-size-s);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.name-color small {
  font-size: 10px;
  line-height: 1.3;
  opacity: 0.8;
}

.name-color.selected {
  border-color: var(--color-gold, #ffd54a);
}

.name-color.locked {
  cursor: default;
  opacity: 0.6;
}

.fav-row {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  margin-bottom: var(--space-s);
}

.fav-slot {
  flex: none;
  width: 72px;
}

.fav-slot small {
  font-size: var(--font-size-s);
  opacity: 0.8;
}

.fav-name {
  flex: 1;
  min-width: 0;
  font-weight: bold;
}

/* 対戦カードの、お気に入りのキャラ（名前の右） */
.vs-fav {
  flex: none;
  width: 40px;
  height: 52px;
  margin-left: auto;
  object-fit: contain;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.4));
}

/* ランキングのプロフィールの、お気に入りのキャラ */
.rp-fav {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: var(--space-s);
}

.rp-fav img {
  width: 48px;
  height: 56px;
  object-fit: contain;
}

.rp-fav span {
  display: flex;
  flex-direction: column;
}

.rp-fav small {
  font-size: 11px;
  opacity: 0.75;
}

.theme-tile {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 2px;
  min-width: 0;
  padding: 4px 4px 5px;
  border: 3px solid transparent;
  border-radius: var(--radius-s);
  font-family: inherit;
  color: var(--color-text);
  background: var(--color-panel);
  cursor: pointer;
  transition: transform var(--dur-press);
}

.theme-tile:active {
  transform: scale(0.96);
}

.theme-tile.selected {
  border-color: var(--color-gold);
}

/* 名前は1行（長いときは「…」） */
.theme-tile b {
  overflow: hidden;
  font-size: 12px;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* 解放条件：見本の下に小さく2行まで（切れないように）。タップすると全文（.expanded） */
.theme-tile small {
  display: -webkit-box;
  overflow: hidden;
  font-size: 9px;
  line-height: 1.3;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  opacity: 0.85;
}

.theme-tile.expanded small {
  display: block;
  white-space: normal;
}

/* 見本の絵（ゲームと同じ描き方の土台・背景を、小さくした画像） */
.theme-preview {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 6px;
  overflow: hidden;
}

.theme-preview img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* 未解放：見本を暗くして鍵マーク */
.theme-tile.locked .theme-preview img {
  filter: grayscale(0.7) brightness(0.55);
}

.theme-preview em {
  position: relative;
  font-size: 18px;
  font-style: normal;
}

/* オンライン対戦 */
.btn-online {
  color: #fff;
  background: #15a37f;
  --color-sub-shadow: #0b6e55;
}

.online-body {
  text-align: center;
}

.online-label {
  margin-top: var(--space-l);
  font-size: var(--font-size-s);
  font-weight: bold;
  opacity: 0.85;
}

/* ルームコード（大きく、1文字ずつ間をあけて） */
.online-code {
  margin-top: var(--space-s);
  padding: var(--space-m) 0;
  border-radius: var(--radius-l);
  font-size: 48px;
  font-weight: bold;
  letter-spacing: 0.25em;
  text-indent: 0.25em;
  color: var(--color-text-dark);
  background: #fff;
  -webkit-user-select: all;
  user-select: all; /* 長押しでコピーしやすいように */
}

.online-code-input {
  width: 100%;
  height: 72px;
  margin: var(--space-s) 0 var(--space-m);
  border: none;
  border-radius: var(--radius-l);
  font-family: inherit;
  font-size: 40px;
  font-weight: bold;
  letter-spacing: 0.25em;
  text-align: center;
  color: var(--color-text-dark);
  -webkit-user-select: text;
  user-select: text;
}

.online-status {
  min-height: 3em;
  margin-top: var(--space-m);
  font-size: 15px;
  font-weight: bold;
  line-height: 1.6;
}

.online-notes {
  margin-top: var(--space-xl);
  padding: var(--space-m);
  border-radius: var(--radius-m);
  font-size: 12px;
  line-height: 1.7;
  text-align: left;
  background: var(--color-panel);
}

.online-notes p + p {
  margin-top: var(--space-xs);
}

/* リザルトの「あなたの勝ち！／負け…」 */
.result-you {
  margin-bottom: var(--space-s);
  font-size: var(--font-size-l);
  font-weight: bold;
}

/* 対戦相手を選ぶ画面 */
.menu-label {
  margin-bottom: calc(var(--space-s) * -1);
  font-size: var(--font-size-s);
  font-weight: bold;
  opacity: 0.85;
}

.cpu-levels {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-s);
}

.btn-cpu {
  padding: var(--space-s) 0;
  font-size: var(--font-size-m);
  color: #fff;
  background: #4a5a78;
  --color-sub-shadow: #2c3850;
}

/* CPU が考えている間の表示 */
.cpu-thinking {
  position: absolute;
  top: 30%;
  left: 50%;
  z-index: 6;
  padding: var(--space-s) var(--space-l);
  border-radius: var(--radius-l);
  font-size: var(--font-size-m);
  font-weight: bold;
  line-height: 1.5;
  text-align: center;
  color: #fff;
  background: rgba(61, 139, 255, 0.9);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
  transform: translateX(-50%);
  pointer-events: none;
}

/* 「考え中...」の点が増えたり減ったりする */
.dots::after {
  content: "";
  display: inline-block;
  width: 1.5em;
  text-align: left;
  animation: dots 1.2s steps(4) infinite;
}

@keyframes dots {
  0% { content: ""; }
  25% { content: "・"; }
  50% { content: "・・"; }
  75% { content: "・・・"; }
}

/* 特殊ルール */
.btn-special {
  color: #fff;
  background: #8e5cf0;
  --color-sub-shadow: #5d36ad;
}

.rule-row {
  display: flex;
  align-items: center;
  gap: var(--space-m);
}

.rule-icon {
  flex-shrink: 0;
  font-size: 32px;
}

.rule-main {
  flex: 1;
  min-width: 0;
  line-height: 1.4;
}

/* ルールの名前：スマホでは少し小さく（「スコアアタック」が言葉の途中で改行しないように）。
   「ランキング対象」の札は、入らなければ下の行に回る */
.rule-main b {
  display: block;
  font-size: clamp(17px, 5.2vw, var(--font-size-m));
}

.rule-main small {
  display: block;
  font-size: 12px;
  opacity: 0.85;
}

.rule-best {
  flex-shrink: 0;
  font-size: 10px;
  text-align: right;
  opacity: 0.9;
}

.rule-best b {
  display: block;
  font-size: 18px;
  color: var(--color-gold);
}

/* スコアアタックの「ふつう」：いちばん上に大きく（ランキング対象） */
.rule-row.rule-normal {
  padding: var(--space-l) var(--space-m);
  border: 2px solid rgba(255, 216, 77, 0.7);
  background: linear-gradient(135deg, rgba(255, 93, 115, 0.45), rgba(255, 122, 89, 0.3));
}

.rule-normal .rule-icon {
  font-size: 40px;
}

.rule-normal .rule-main b {
  font-size: clamp(17px, 4.8vw, var(--font-size-l));
}

/* ルールの名前は、言葉の途中で改行しない（横の札は、入らなければ下の行へ） */
.rule-name {
  white-space: nowrap;
}

.rule-normal .rule-best b {
  font-size: 22px;
}

/* 「ランキング対象」の札 */
.ranking-tag {
  display: inline-block;
  padding: 1px 8px;
  border-radius: var(--radius-round);
  color: var(--color-text-dark);
  background: #fff;
  font-size: 11px;
  font-weight: bold;
  white-space: nowrap;
  vertical-align: middle;
}

/* モード選択のスコアアタックのボタンの、ハイスコア */
.mode-best {
  display: inline-block;
  margin-top: 4px;
  padding: 0 10px;
  border-radius: var(--radius-round);
  background: rgba(0, 0, 0, 0.18);
  font-size: 12px;
  line-height: 1.6;
}

/* ゲーム中・リザルトのルール名の札 */
.rule-tag {
  display: inline-block;
  padding: 2px 10px;
  border-radius: var(--radius-round);
  font-size: 12px;
  vertical-align: middle;
  background: rgba(142, 92, 240, 0.85);
  text-shadow: none;
}

.result-rule {
  margin-bottom: var(--space-s);
}

/* ---------- 競技モード ---------- */
/* ゲーム中・リザルト・挑戦状の「🏁 競技」の札（特殊ルールの紫とちがう、青緑） */
.rule-tag.comp-tag {
  background: rgba(20, 150, 140, 0.9);
}

/* 「ひとりで」の画面の、競技のボタンと「ランキング（競技）対象」の札 */
.rule-row.rule-comp {
  margin-top: var(--space-s);
  background: linear-gradient(120deg, rgba(20, 150, 140, 0.45), rgba(40, 90, 160, 0.35));
}

.ranking-tag.ranking-tag-comp {
  color: #fff;
  background: #14968c;
}

/* ランキングへの参加の同意（ranking.js の ensureConsent） */
.consent-dialog-box {
  text-align: left;
}

.consent-dialog-box .consent-title {
  margin: 0 0 var(--space-s);
  font-size: 18px;
  font-weight: bold;
  text-align: center;
}

.consent-dialog-box .consent-text {
  margin: 0 0 var(--space-s);
  font-size: 15px;
  font-weight: bold;
}

.consent-dialog-box .consent-list {
  margin: 0 0 var(--space-s);
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-s);
  font-size: 13px;
  background: rgba(0, 0, 0, 0.06);
}

.consent-dialog-box .consent-note {
  margin: 0 0 var(--space-s);
  font-size: 12px;
  opacity: 0.8;
}

.consent-profile {
  display: flex;
  margin: 0 auto var(--space-m);
}

/* 設定画面：説明だけの行（制限時間）・ランキングへの参加の状態 */
.setting-row.setting-info {
  cursor: default;
}

.ranking-consent-row .btn:disabled,
.ranking-consent-row .btn.hidden {
  display: none;
}

/* 競技の説明のダイアログ */
.comp-dialog-box {
  text-align: left;
}

.comp-dialog-title {
  margin: 0 0 var(--space-s);
  font-size: 18px;
  font-weight: bold;
  text-align: center;
}

.comp-dialog-rules {
  margin: 0 0 var(--space-m);
  padding-left: 1.2em;
  font-size: 14px;
  line-height: 1.6;
}

.comp-dialog-rules li + li {
  margin-top: 4px;
}

.comp-dialog-rules .comp-dialog-warn {
  color: #ffd84d;
}

.comp-dialog-rules b {
  white-space: nowrap;
}

.comp-dialog-hide {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-s);
  margin-bottom: var(--space-m);
  font-size: 14px;
}

.comp-dialog-hide input {
  width: 20px;
  height: 20px;
  accent-color: var(--color-primary);
}

/* ランキング画面の上の「フリー / 競技」のタブ */
/* シーズン：左に見ているシーズンの名前と始まった日、右に前のシーズンへの切りかえ（ranking.js・seasons.js） */
.ranking-season {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  margin: 0 var(--space-m) var(--space-s);
}

.ranking-season-info {
  display: flex;
  flex-direction: column;
  text-align: left;
  flex: 1;
  min-width: 0;
  line-height: 1.3;
}

.ranking-season-info b {
  font-size: var(--font-size-s);
  text-wrap: balance;
}

.ranking-season-info small {
  font-size: 11px;
  opacity: 0.8;
}

/* シーズンのタブ：「S2 今」「S1」「歴代」（列の数は ranking.js が決める）。短く、改行しない */
.ranking-tabs.ranking-season-tabs .ranking-tab {
  height: 32px;
  font-size: 14px;
  white-space: nowrap;
}

.ranking-season-tabs .ranking-tab small {
  font-size: 11px;
  opacity: 0.8;
}

/* 前のシーズンが2つ以上あるとき：2つ目のタブが、シーズンを選ぶ欄になる */
.ranking-tab.ranking-tab-select {
  min-width: 0;
  padding: 0 18px 0 8px;
  -webkit-appearance: none;
  appearance: none;
  text-align: center;
  text-align-last: center;
  background: transparent url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23888' stroke-width='1.6'/%3E%3C/svg%3E") right 8px center / 9px 6px no-repeat;
}

.ranking-tab.ranking-tab-select.active {
  background-color: #fff;
}

.ranking-tab-select option {
  color: var(--color-text-dark);
}

/* 歴代の記録の横の、そのスコアを出したシーズン（「S1」） */
.rank-season-tag {
  display: inline-block;
  margin-left: 4px;
  padding: 0 5px;
  border-radius: 999px;
  color: var(--color-text-dark);
  background: rgba(255, 255, 255, 0.85);
  font-size: 10px;
  font-weight: bold;
  line-height: 1.5;
  vertical-align: 0.25em;
  white-space: nowrap;
}

.ranking-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  margin: 0 var(--space-m) var(--space-s);
  padding: 4px;
  border-radius: var(--radius-round);
  background: rgba(0, 0, 0, 0.22);
}

.ranking-tab {
  height: 36px;
  border: 0;
  border-radius: var(--radius-round);
  color: inherit;
  background: transparent;
  font-family: inherit;
  font-size: 15px;
  font-weight: bold;
  opacity: 0.75;
  cursor: pointer;
}

.ranking-tab.active {
  color: var(--color-text-dark);
  background: #fff;
  opacity: 1;
}

/* 危ない操作（リセットなど）のボタン */
.btn.btn-danger {
  display: flex;
  margin: var(--space-xl) auto 0;
  color: #fff;
  background: #e5484d;
  --color-sub-shadow: #a3262b;
}

/* 小さいボタン */
.btn-small {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 40px;
  padding: 0 var(--space-m);
  border-radius: var(--radius-round);
  font-size: var(--font-size-s);
  --button-depth: 3px;
}

/* 入力欄 */
.field {
  display: block;
  margin-top: var(--space-m);
}

.field > span {
  display: flex;
  align-items: baseline;
  gap: var(--space-s);
  margin-bottom: var(--space-xs);
  font-size: var(--font-size-s);
  font-weight: bold;
}

.field small {
  font-weight: normal;
  opacity: 0.7;
}

.field input,
.field select {
  width: 100%;
  height: 48px;
  padding: 0 var(--space-m);
  border: 2px solid transparent;
  border-radius: var(--radius-m);
  font-family: inherit;
  font-size: 16px; /* 16px 未満だと、iPhone で入力時に画面が拡大されてしまう */
  color: var(--color-text-dark);
  background: #fff;
  -webkit-user-select: text;
  user-select: text;
}

.field input:focus,
.field select:focus {
  border-color: var(--color-primary);
  outline: none;
}

/* プロフィールのアイコン欄 */
.profile-icon-area {
  display: flex;
  align-items: center;
  gap: var(--space-l);
  padding: var(--space-m);
  border-radius: var(--radius-l);
  background: var(--color-panel);
}

.profile-icon-buttons {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

/* リザルト画面などの「アイコン＋名前＋称号」 */
.player-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-s);
  margin-bottom: var(--space-m);
  padding: 4px var(--space-m) 4px 4px;
  border-radius: var(--radius-round);
  background: var(--color-panel);
  text-align: left;
  line-height: 1.2;
}

.player-badge b {
  display: block;
  font-size: var(--font-size-m);
}

.player-badge small {
  display: block;
  font-size: 11px;
  color: var(--color-gold);
}

/* 2人対戦の勝者の名前（長い名前のときだけ小さくして、1行に収める。--fit は名前の長さ。main.js の UI.fit） */
.winner-name {
  display: block;
  max-width: 280px;
  overflow: hidden;
  font-size: clamp(22px, calc(min(72vw, 280px) / var(--fit, 1)), 44px);
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* アイコンの調整画面 */
.crop-body {
  text-align: center;
}

.crop-frame {
  width: 260px;
  height: 260px;
  margin: var(--space-m) auto;
  border-radius: var(--radius-m);
  overflow: hidden;
}

.crop-frame canvas {
  display: block;
  width: 260px;
  height: 260px;
  touch-action: none; /* 指の操作をブラウザのスクロールに取られないように */
}

#crop-zoom {
  width: 260px;
  accent-color: var(--color-primary);
}

/* =============================================
   確認ダイアログ
   ============================================= */
.dialog {
  position: absolute;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-l);
  background: rgba(10, 15, 30, 0.6);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s, visibility 0s linear 0.2s;
}

.dialog.active {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.2s, visibility 0s;
}

.dialog-box {
  width: 100%;
  max-width: 320px;
  padding: var(--space-l);
  border-radius: var(--radius-l);
  color: var(--color-text-dark);
  background: #fff;
  text-align: center;
  transform: scale(0.9);
  transition: transform 0.2s;
}

.dialog.active .dialog-box {
  transform: none;
}

.dialog-box p {
  font-size: var(--font-size-m);
  font-weight: bold;
  line-height: 1.6;
  white-space: pre-line; /* 文章の中の改行をそのまま表示 */
}

.dialog-buttons {
  display: flex;
  gap: var(--space-s);
  margin-top: var(--space-l);
}

.dialog-buttons .btn {
  flex: 1;
  height: 48px;
  border-radius: var(--radius-m);
  font-size: var(--font-size-m);
}

.dialog-buttons .btn-sub {
  background: #eef1f6;
}

/* =============================================
   通知（画面の上からスッと出てくる）
   ============================================= */
#toasts {
  position: absolute;
  top: calc(76px + var(--safe-top)); /* ゲーム中のスコアや、各画面の見出しより下に出す */
  left: var(--space-m);
  right: var(--space-m);
  z-index: 45;
  display: flex;
  flex-direction: column;
  align-items: center;
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  max-width: 100%;
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-m);
  color: var(--color-text-dark);
  background: #fff;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
  font-size: var(--font-size-s);
  animation: toast-in 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) both;
  transition: opacity 0.3s, transform 0.3s;
}

.toast.leave {
  opacity: 0;
  transform: translateY(-20px);
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(-30px); }
  to { opacity: 1; transform: none; }
}

/* =============================================
   読み込み中の表示（スプラッシュの後ろ。読み込みが長いときだけ見える）
   ============================================= */
.loading-screen {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-m);
  font-size: var(--font-size-m);
  font-weight: bold;
  background: linear-gradient(#7ec8f0, #d8f0ff);
  color: var(--color-text-dark);
  transition: opacity 0.4s, visibility 0s linear 0.4s;
}

.loading-screen.done {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.spinner {
  width: 44px;
  height: 44px;
  border: 5px solid rgba(43, 58, 85, 0.2);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}

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

.loading-bar {
  width: 200px;
  height: 8px;
  border-radius: var(--radius-round);
  background: rgba(43, 58, 85, 0.15);
  overflow: hidden;
}

#loading-bar-fill {
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--color-primary);
  transition: width 0.2s;
}

.loading-count {
  font-size: var(--font-size-s);
  opacity: 0.7;
}

/* =============================================
   スプラッシュ画面（起動時の会社名）
   ============================================= */
#splash {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-l);
  background: var(--color-splash-bg, #ffffff);
  transition: opacity 0.6s ease;
}

#splash.fade-out {
  opacity: 0;
  pointer-events: none;
}

#splash-text {
  color: var(--color-text-dark);
  font-size: 22px;
  font-weight: bold;
  letter-spacing: 0.12em;
  text-align: center;
}

/* 1文字ずつ、少し下から浮き上がる（--i は何文字目か。JS で設定） */
#splash-text span {
  display: inline-block;
  opacity: 0;
  transform: translateY(10px);
  animation: splash-char 0.6s ease forwards;
  animation-delay: calc(var(--i) * 0.06s + 0.2s);
}

@keyframes splash-char {
  to { opacity: 1; transform: none; }
}

.screen-title {
  font-size: 32px;
  text-shadow: 0 3px 0 rgba(0, 0, 0, 0.2);
}

.menu {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  margin-top: var(--space-l);
}

.notice {
  margin-top: var(--space-m);
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-s);
  font-size: var(--font-size-s);
  text-align: left;
  background: rgba(255, 200, 60, 0.25);
}

/* アップデートの予告・「更新する」ボタン（タイトル画面。updates.js） */
.update-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px 10px;
  margin-top: var(--space-s);
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-s);
  font-size: var(--font-size-s);
  font-weight: bold;
  text-align: center;
  color: #3a2a00;
  background: rgba(255, 213, 74, 0.92);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
}

.update-banner small {
  flex-basis: 100%;
  font-weight: normal;
}

.update-banner.update-ready {
  color: #fff;
  background: rgba(43, 140, 90, 0.95);
}

/* ===== 設定画面 ===== */
/* 設定画面：上に「‹ 設定」、その下が見出しごとに分かれたリスト（リストだけスクロール） */
.settings-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.settings-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.settings-group.hidden {
  display: none;
}

/* 行は縮めない（行が増えて画面からはみ出したとき、縮んで中身が下の行に重ならないように。はみ出した分はスクロール） */
.settings-list > *,
.settings-group > * {
  flex-shrink: 0;
}

.settings-heading {
  margin: var(--space-m) 0 2px 4px;
  font-size: 13px;
  opacity: 0.75;
}

.settings-heading:first-child {
  margin-top: 0;
}

.setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  min-height: 56px;
  padding: 10px var(--space-m);
  border-radius: var(--radius-m);
  font-size: 16px;
  font-weight: bold;
  text-align: left;
  background: var(--color-panel);
}

.setting-row small {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.35;
  font-weight: normal;
  opacity: 0.8;
}

/* スイッチの行は、行のどこを押しても切りかわる */
.setting-row.setting-tap {
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: filter var(--dur-press);
}

.setting-row.setting-tap:active {
  filter: brightness(1.15);
}

/* ランキングに参加したときだけ選べる行：少し右にずらして、親の項目の下だと分かるように */
.setting-row.setting-sub {
  margin-left: var(--space-m);
}

.setting-row.setting-tap.disabled {
  cursor: default;
}

/* 設定画面のバックアップの行（ボタンが2つ並ぶ） */
.setting-data {
  flex-wrap: wrap;
}

.setting-data-buttons {
  display: flex;
  gap: var(--space-s);
}

.setting-data .btn-small {
  min-height: 36px;
  padding: 0 14px;
}

/* ON/OFF スイッチ */
.toggle {
  position: relative;
  flex-shrink: 0;
  width: 58px;
  height: 34px;
  border: none;
  border-radius: var(--radius-round);
  background: var(--color-off);
  touch-action: manipulation;
  cursor: pointer;
  transition: background var(--dur-screen);
}

.toggle::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
  transition: transform 0.2s;
}

.toggle[aria-checked="true"] {
  background: var(--color-on);
}

.toggle[aria-checked="true"]::after {
  transform: translateX(24px);
}

.toggle:active::after {
  width: 32px; /* 押したとき、つまみが少し伸びる */
}

/* ===== リザルト画面 ===== */
.result-heading {
  font-size: var(--font-size-xl);
  text-shadow: 0 4px 0 rgba(0, 0, 0, 0.25);
}

.result-score {
  margin-top: var(--space-s);
  font-size: 64px;
  font-weight: bold;
  line-height: 1.1;
}

.result-score small {
  font-size: var(--font-size-l);
}

.result-stats {
  display: flex;
  justify-content: center;
  gap: var(--space-s);
  margin-top: var(--space-m);
}

.result-stats div {
  flex: 1;
  padding: var(--space-s);
  border-radius: var(--radius-m);
  background: var(--color-panel);
  font-size: var(--font-size-s);
}

.result-stats b {
  display: block;
  margin-top: 2px;
  font-size: var(--font-size-l);
}

.new-record {
  display: inline-block;
  margin-bottom: var(--space-s);
  padding: var(--space-xs) var(--space-m);
  border-radius: var(--radius-s);
  color: var(--color-text-dark);
  background: var(--color-gold);
  font-size: var(--font-size-l);
  font-weight: bold;
  animation: pop 0.5s ease-out both, pulse 0.9s ease-in-out 0.5s infinite alternate;
}

@keyframes pop {
  0% { transform: scale(0) rotate(-10deg); }
  70% { transform: scale(1.25) rotate(3deg); }
  100% { transform: scale(1) rotate(0); }
}

@keyframes pulse {
  from { transform: scale(1); }
  to { transform: scale(1.08); }
}

/* 2人対戦の勝者 */
.winner {
  display: inline-block;
  padding: var(--space-m) var(--space-l);
  border-radius: var(--radius-l);
  font-size: 56px;
  font-weight: bold;
  line-height: 1.1;
  animation: pop 0.5s ease-out both;
}

.winner small {
  display: block;
  font-size: var(--font-size-xl);
}

.result-sub {
  margin-top: var(--space-m);
  font-size: var(--font-size-m);
}

/* 紙吹雪（ハイスコア更新・勝利のとき） */
#confetti {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

/* 合言葉の紙吹雪（ダイアログの中に降らせる。codes.js） */
.code-confetti {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

#confetti span,
.code-confetti span {
  position: absolute;
  top: -20px;
  width: 10px;
  height: 14px;
  border-radius: 2px;
  animation: confetti linear forwards;
}

@keyframes confetti {
  to { transform: translateY(110vh) rotate(720deg); }
}

/* ===== 合言葉（codes.js） ===== */
.code-dialog-box {
  position: relative;
  overflow: hidden;
}

.code-title {
  margin-bottom: var(--space-s);
  font-size: var(--font-size-m);
  font-weight: bold;
}

.code-title.code-ok {
  color: #d97a00; /* 白いダイアログの上でも読める、濃い金色 */
}

.code-note {
  margin-bottom: var(--space-m);
  font-size: var(--font-size-s);
  word-break: keep-all; /* 「ごほうび」などが、言葉の途中で改行しないように（読点で改行する） */
  text-wrap: balance;
  opacity: 0.85;
}

.code-input {
  width: 100%;
  padding: 12px var(--space-m);
  border: 2px solid #c9d2e3;
  border-radius: var(--radius-s);
  color: var(--color-text-dark);
  background: #f4f6fb;
  font: inherit;
  font-size: 20px;
  font-weight: bold;
  text-align: center;
  letter-spacing: 0.1em;
}

.code-message {
  min-height: 1.5em;
  margin: var(--space-s) 0;
  font-size: var(--font-size-s);
  font-weight: bold;
}

.code-message.code-error {
  color: #ff8a8a;
}

.code-message.code-info {
  color: #8fe3ff;
}

.code-result-name {
  margin-bottom: var(--space-m);
  font-size: var(--font-size-l);
  font-weight: bold;
}

.code-result-list {
  display: grid;
  gap: var(--space-s);
  margin: 0 0 var(--space-m);
  padding: 0;
  list-style: none;
}

.code-reward {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  padding: var(--space-s);
  border-radius: var(--radius-s);
  background: rgba(255, 255, 255, 0.1);
  animation: rise-up 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

.code-reward:nth-child(2) { animation-delay: 0.15s; }
.code-reward:nth-child(3) { animation-delay: 0.3s; }

.code-reward img {
  width: 96px;
  border-radius: 6px;
}

.code-reward-kind {
  flex: none;
  padding: 2px 8px;
  border-radius: var(--radius-round);
  color: var(--color-text-dark);
  background: #ffd54a;
  font-size: 11px;
  font-weight: bold;
}

/* =============================================
   端末の「視差効果を減らす」設定が ON のとき
   動きのある演出を止めて、フェードだけにする
   ============================================= */
@media (prefers-reduced-motion: reduce) {
  .logo-char,
  .logo,
  .tagline,
  .best-card,
  .btn-start-wrap,
  .btn-start-wrap.ready,
  .btn-corner,
  .new-record,
  .winner,
  .title-menu,
  .profile-chip,
  .toast {
    animation: fade-in 0.4s ease both;
  }

  .page-inner,
  .screen.active .page-inner {
    transform: none;
  }

  .logo {
    transform: rotate(-4deg);
  }

  /* キラッと光る・アイコンが弾む動きはしない */
  .logo-shine.on,
  .menu-icon.pressed {
    animation: none;
  }

  .screen-inner,
  .screen.active .screen-inner {
    transform: none;
  }

  #splash-text span {
    transform: none;
    animation-name: fade-in;
  }

  #confetti {
    display: none;
  }

  #turn-banner {
    animation: fade-in-out 1.2s ease forwards;
  }
}

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

@keyframes fade-in-out {
  0% { opacity: 0; }
  15%, 80% { opacity: 1; }
  100% { opacity: 0; }
}

/* オンライン対戦：待ち受けの状態とバージョン（つながらないときの手がかり） */
.online-wait-state,
.online-version {
  margin-top: var(--space-s);
  font-size: 12px;
  opacity: 0.8;
}

/* 管理者モード */
.admin-buttons {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-s);
}

/* 日時のかんたん入力（30分後・1時間後・今夜21時・明日21時） */
.admin-buttons.admin-quick {
  grid-template-columns: repeat(4, 1fr);
  margin-bottom: var(--space-s);
}

.admin-quick .btn {
  padding-left: 2px;
  padding-right: 2px;
  font-size: var(--font-size-s);
  white-space: nowrap;
}

/* 管理者メニューの見出し：タップで開く・閉じる（<details>）。見出しの横に、今の状態を小さく出す */
.admin-sec {
  margin-bottom: var(--space-s);
  padding: 0 var(--space-m);
  border-radius: var(--radius-s);
  background: rgba(255, 255, 255, 0.06);
}

.admin-sec > summary.section-title {
  display: flex;
  align-items: baseline;
  gap: 4px;
  margin: 0 calc(-1 * var(--space-m));
  padding: var(--space-s) var(--space-m);
  cursor: pointer;
  list-style: none;
  user-select: none;
}

.admin-sec > summary::-webkit-details-marker {
  display: none;
}

.admin-sec > summary::before {
  content: "▶";
  display: inline-block;
  margin-right: 6px;
  font-size: 0.7em;
  transition: transform 0.15s;
}

.admin-sec[open] > summary::before {
  transform: rotate(90deg);
}

.admin-sec-state {
  overflow: hidden;
  font-size: var(--font-size-s);
  font-weight: normal;
  white-space: nowrap;
  text-overflow: ellipsis;
  opacity: 0.75;
}

.admin-sec[open] {
  padding-bottom: var(--space-m);
}

.admin-sec-all {
  margin-bottom: var(--space-m);
}

.admin-net {
  margin-bottom: var(--space-s);
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-s);
  font-size: 11px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-all;
  background: rgba(0, 0, 0, 0.25);
}

/* ホームの右上（歯車の左）の 🛠：管理者メニュー（管理者モードの端末だけ） */
/* 合言葉の 🔑（歯車の左）。管理者モードの 🛠 は、そのさらに左 */
.btn-codes-home {
  right: calc(var(--space-m) + var(--safe-right) + 46px + var(--space-s));
}

.btn-admin-home {
  right: calc(var(--space-m) + var(--safe-right) + (46px + var(--space-s)) * 2);
  font-size: 20px;
}

/* 管理者メニューの、チェックボックスの一覧 */
.admin-checks {
  display: grid;
  gap: 2px;
  margin: var(--space-s) 0;
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-s);
  background: var(--color-panel);
}

.admin-checks label,
.admin-check-backup {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  min-height: 36px;
  font-size: 14px;
}

.admin-checks small {
  font-size: 11px;
  opacity: 0.7;
}

/* 補足（小さい字）は、見出し・チェックの文字を押しつぶさないように、下の行に回す */
.admin-checks label,
#admin-panel .field > span {
  flex-wrap: wrap;
  column-gap: var(--space-s);
  row-gap: 0;
}

.admin-checks label small,
#admin-panel .field > span small {
  flex-basis: 100%;
}

.admin-checks label small {
  padding-left: 22px; /* チェックの四角の分だけ下げて、文字とそろえる */
}

.admin-checks input,
.admin-check-backup input {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  accent-color: var(--color-primary);
}

.admin-check-backup {
  margin-bottom: var(--space-s);
}

.admin-wide {
  width: 100%;
  margin-top: var(--space-s);
}

.admin-wide:disabled {
  opacity: 0.45;
}

/* 出現率のテスト：回数の入力とボタンを横に並べる */
.admin-draw-form {
  display: flex;
  align-items: flex-end;
  gap: var(--space-s);
}

.admin-draw-form .field {
  flex: 1;
  margin-top: 0;
}

.admin-draw-form .btn {
  height: 48px;
}

.admin-draw td {
  line-height: 1.3;
}

.admin-draw .admin-diff-big {
  color: #ff8a8a;
  font-weight: bold;
}

/* 管理者モード：画面の上の札（「デバッグ中・記録されません」「テスト日付：10/31」）。タップは下に通す */
#admin-flags {
  position: absolute;
  top: calc(4px + var(--safe-top));
  left: 50%;
  z-index: 60;
  display: flex;
  gap: 6px;
  transform: translateX(-50%);
  pointer-events: none;
  white-space: nowrap;
}

.admin-flag {
  padding: 3px 10px;
  border-radius: var(--radius-round);
  font-size: 12px;
  font-weight: bold;
  color: #2b1d00;
  background: #ffd84d;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}

.admin-flag-date {
  color: #fff;
  background: #7b4dff;
}

/* 管理者モード：左上の数値（FPS・キャラの数と高さ） */
.admin-hud {
  position: absolute;
  top: calc(30px + var(--safe-top));
  left: calc(4px + var(--safe-left));
  z-index: 60;
  margin: 0;
  padding: 4px 8px;
  border-radius: 6px;
  color: #b9ffb9;
  background: rgba(0, 0, 0, 0.6);
  font: 11px/1.45 ui-monospace, Menlo, Consolas, monospace;
  pointer-events: none;
}

/* ---------- 自由配置モード（sandbox.js） ---------- */
/* 遊んでいるあいだは、ふつうのゲームの表示（スコア・操作ボタン）を消す */
body.sandbox-on .game-ui,
body.sandbox-on #turn-banner,
body.sandbox-on #rare-banner {
  display: none !important;
}

#sandbox-ui {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  padding: var(--space-s) calc(var(--space-m) + var(--safe-right)) calc(var(--space-s) + var(--safe-bottom)) calc(var(--space-m) + var(--safe-left));
  background: linear-gradient(to top, rgba(20, 30, 55, 0.85), rgba(20, 30, 55, 0.6));
}

.sandbox-top {
  display: flex;
  gap: var(--space-s);
}

.sandbox-top select {
  flex: 1;
  min-width: 0;
  height: 40px;
  padding: 0 var(--space-s);
  border: 0;
  border-radius: var(--radius-s);
  font-family: inherit;
  font-size: 16px;
  color: var(--color-text-dark);
  background: #fff;
}

.sandbox-info {
  margin: 6px 0;
  font-size: 12px;
  opacity: 0.9;
}

.sandbox-tools {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}

.sandbox-tools .btn {
  padding-left: 0;
  padding-right: 0;
}

.sandbox-tools .btn:disabled {
  opacity: 0.45;
}

/* 読み込み状況（load-status.js）は、自由配置モードのボタンの帯より上に出す */
body.sandbox-on .load-status {
  bottom: calc(150px + var(--safe-bottom));
}

/* 合言葉から作った番号（コピーしやすいように、選択できる文字にする） */
.admin-made {
  margin-top: var(--space-m);
  font-family: monospace;
  font-size: 12px;
  word-break: break-all;
  -webkit-user-select: all;
  user-select: all;
}

/* 設定の行の小さいボタン：文字が折り返さないように */
.setting-row .btn-small {
  flex-shrink: 0;
  white-space: nowrap;
}

/* =============================================
   挑戦状
   ============================================= */
/* 受け取ったときのポップアップ */
.challenge-label {
  display: inline-block;
  padding: 2px 14px;
  border-radius: var(--radius-round);
  color: #fff;
  background: var(--color-p2);
  font-size: var(--font-size-s) !important;
  letter-spacing: 0.2em;
}

.challenge-from {
  margin-top: var(--space-s);
}

.challenge-score {
  font-size: 44px;
  font-weight: bold;
  line-height: 1.2;
  color: var(--color-primary);
}

.challenge-score small {
  font-size: var(--font-size-m);
}

.challenge-box .rule-tag {
  color: #fff;
}

.challenge-note {
  margin-top: var(--space-s);
  font-size: var(--font-size-s) !important;
  font-weight: normal !important;
  opacity: 0.7;
}

/* ゲーム中の「〇〇さんの 1270点 に挑戦中」 */
.hud-challenge {
  font-size: 13px;
}

/* リザルトの勝ち負け */
.challenge-result {
  display: inline-block;
  margin-bottom: var(--space-s);
  padding: var(--space-xs) var(--space-l);
  border-radius: var(--radius-m);
  font-size: var(--font-size-l);
  font-weight: bold;
  background: var(--color-panel);
  animation: pop 0.5s ease-out both;
}

.challenge-result.win { color: var(--color-text-dark); background: var(--color-gold); }
.challenge-result.lose { background: rgba(0, 0, 0, 0.3); }

.challenge-result small {
  display: block;
  font-size: var(--font-size-s);
  font-weight: normal;
}

/* 共有できないときの URL 欄 */
.share-url {
  width: 100%;
  margin-top: var(--space-s);
  padding: var(--space-s);
  border: 2px solid #dde3ec;
  border-radius: var(--radius-s);
  font-family: inherit;
  font-size: var(--font-size-s);
  color: var(--color-text-dark);
}

/* =============================================
   リザルトカード
   ============================================= */
.card-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

.card-preview {
  display: flex;
  justify-content: center;
}

.card-img {
  display: block;
  max-width: 100%;
  border-radius: var(--radius-s);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
}

/* 縦長は画面からはみ出さないよう、高さで抑える */
.card-img.portrait {
  max-height: 46vh;
}

/* 2つから選ぶボタン（横長・縦長） */
.seg {
  display: flex;
  gap: var(--space-s);
}

.seg-btn {
  flex: 1;
  padding: var(--space-s);
  border: 2px solid transparent;
  border-radius: var(--radius-m);
  color: var(--color-text);
  background: var(--color-panel);
  font-family: inherit;
  font-size: var(--font-size-m);
  font-weight: bold;
  cursor: pointer;
}

.seg-btn small {
  display: block;
  font-size: 12px;
  opacity: 0.75;
}

.seg-btn.selected {
  border-color: var(--color-gold);
  background: rgba(255, 216, 77, 0.2);
}

/* 「雲の上に到達！」（高さで変わる背景） */
.toast-sky {
  font-size: var(--font-size-s);
}

/* =============================================
   フォトモード
   ============================================= */
/* 画面は透明。指の操作は後ろのキャンバスに通し、ボタンだけ押せるようにする */
.screen.screen-photo,
.screen.screen-photo.active {
  align-items: flex-end;
  background: none;
  pointer-events: none;
}

.screen-photo .btn {
  pointer-events: auto;
}

.photo-hint {
  position: absolute;
  top: calc(var(--space-m) + var(--safe-top));
  left: 0;
  right: 0;
  font-size: var(--font-size-s);
  font-weight: bold;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
  animation: photo-hint 3s ease forwards;
}

@keyframes photo-hint {
  0%, 70% { opacity: 1; }
  100% { opacity: 0; }
}

.photo-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-l);
  width: 100%;
}

.btn-photo-shoot {
  min-width: 160px;
  height: 64px;
  border-radius: var(--radius-round);
  font-size: 22px;
}

/* 撮影したときに、画面が一瞬白く光る */
.photo-flash {
  position: absolute;
  inset: 0;
  background: #fff;
  opacity: 0;
  pointer-events: none;
}

.photo-flash.on {
  animation: photo-flash 0.4s ease-out;
}

@keyframes photo-flash {
  from { opacity: 0.8; }
  to { opacity: 0; }
}

/* 期間限定（イベントの特殊ルール） */
.limited-tag {
  display: inline-block;
  padding: 1px 8px;
  border-radius: var(--radius-round);
  color: var(--color-text-dark);
  background: var(--color-gold);
  font-size: 11px;
  vertical-align: middle;
}

/* ランキング：自分の行 */
.rank-row.rank-me {
  outline: 3px solid var(--color-primary);
  outline-offset: -3px;
}

.rank-you {
  display: inline-block;
  margin-left: var(--space-xs);
  padding: 0 8px;
  border-radius: var(--radius-round);
  color: #fff;
  background: var(--color-primary);
  font-size: 11px;
  font-style: normal;
  vertical-align: middle;
}

.my-rank {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  font-weight: normal;
}

.my-rank b {
  color: var(--color-gold);
}

/* ランキング：アイコンと称号 */
.rank-avatar {
  width: 36px;
  height: 36px;
  font-size: 16px;
  font-weight: bold;
}

.rank-title {
  display: inline-block;
  margin: 2px 0;
  padding: 0 8px;
  border-radius: var(--radius-round);
  color: var(--color-text-dark);
  background: var(--color-gold);
  font-size: 11px;
  font-weight: bold;
}

/* =============================================
   スタンプ（オンライン対戦のリザルト）
   ============================================= */
/* プロフィール画面の4つの枠 */
.section-title small {
  margin-left: var(--space-s);
  font-size: 11px;
  font-weight: normal;
  opacity: 0.8;
}

.stamp-slots {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-s);
}

.stamp-slot {
  position: relative;
  min-width: 0;
  aspect-ratio: 1;
  padding: 6px;
  border: 2px dashed rgba(255, 255, 255, 0.5);
  border-radius: var(--radius-m);
  background: var(--color-panel);
  cursor: pointer;
}

.stamp-slot img,
.stamp-choice img,
.stamp-send img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
}

.stamp-slot small {
  position: absolute;
  right: 4px;
  bottom: 4px;
  padding: 0 6px;
  border-radius: var(--radius-round);
  color: var(--color-text-dark);
  background: rgba(255, 255, 255, 0.85);
  font-size: 10px;
  font-weight: bold;
}

/* キャラを選ぶダイアログ */
.dialog-box.stamp-picker-box {
  max-width: 360px;
}

.stamp-picker-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  max-height: 46vh;
  overflow-x: hidden;
  overflow-y: auto;
  margin-top: var(--space-s);
}

.stamp-choice {
  min-width: 0;
  aspect-ratio: 1;
  padding: 4px;
  border: 2px solid transparent;
  border-radius: var(--radius-s);
  background: #eef1f6;
  cursor: pointer;
}

.stamp-choice.selected {
  border-color: var(--color-primary);
}

/* まだ図鑑にいないキャラは、黒いシルエットで選べない */
.stamp-choice.locked {
  cursor: default;
}

.stamp-choice.locked img {
  filter: brightness(0) opacity(0.35);
}

.dialog-box .stamp-picker-note {
  margin-top: var(--space-s);
  font-size: 12px;
  font-weight: normal;
  opacity: 0.6;
}

/* リザルト画面の下の、送るボタンの欄 */
.screen.with-stamps {
  padding-bottom: calc(120px + var(--safe-bottom));
}

.stamp-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 12;
  padding: var(--space-s) var(--space-m) calc(var(--space-m) + var(--safe-bottom));
  background: linear-gradient(transparent, rgba(10, 15, 30, 0.6) 30%);
}

.stamp-status {
  min-height: 1.2em;
  margin-bottom: var(--space-xs);
  font-size: var(--font-size-s);
  font-weight: bold;
  text-align: center;
}

.stamp-buttons {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-s);
}

.stamp-send {
  position: relative;
  height: 72px;
  padding: 4px;
  border: none;
  border-radius: var(--radius-m);
  background: rgba(255, 255, 255, 0.9);
  box-shadow: 0 4px 0 var(--color-sub-shadow);
  overflow: hidden;
  cursor: pointer;
  touch-action: manipulation;
  transition: transform var(--dur-press);
}

.stamp-send:active:not(:disabled) {
  transform: translateY(3px) scale(0.94);
}

.stamp-send:disabled {
  opacity: 0.45;
  cursor: default;
}

/* 送ったあとの「待ち」：ボタンの下に、残り時間の帯がのびる */
.stamp-bar.cooling .stamp-send::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 4px;
  background: var(--color-primary);
  animation: stamp-cool 1.5s linear forwards;
}

@keyframes stamp-cool {
  from { width: 100%; }
  to { width: 0; }
}

/* 出てきたスタンプ（自分は右、相手は左） */
.stamp-layer {
  position: absolute;
  inset: 0;
  z-index: 13;
  overflow: hidden;
  pointer-events: none;
}

.stamp-pop {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 120px;
  padding: var(--space-s);
  border-radius: var(--radius-l);
  background: #fff;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  animation: stamp-pop 2.6s ease forwards;
}

.stamp-pop.me {
  right: var(--space-m);
  transform-origin: bottom right;
  border-bottom-right-radius: 4px;
}

.stamp-pop.them {
  left: var(--space-m);
  transform-origin: bottom left;
  border-bottom-left-radius: 4px;
}

.stamp-pop img {
  width: 96px;
  height: 96px;
  object-fit: contain;
}

.stamp-pop small {
  max-width: 100%;
  overflow: hidden;
  color: #fff;
  font-size: 11px;
  font-weight: bold;
  white-space: nowrap;
  text-overflow: ellipsis;
  padding: 0 8px;
  border-radius: var(--radius-round);
}

.stamp-pop.me small { background: var(--color-primary); }
.stamp-pop.them small { background: var(--color-p2); }

/* ポンッと弾んで出て、少しのあいだ止まり、フッと消える */
@keyframes stamp-pop {
  0% { transform: scale(0); opacity: 0; }
  12% { transform: scale(1.18); opacity: 1; }
  20% { transform: scale(0.94); }
  27% { transform: scale(1); }
  85% { transform: scale(1); opacity: 1; }
  100% { transform: scale(0.9) translateY(-10px); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .stamp-pop {
    animation: fade-in-out 2.6s ease forwards;
  }
}

/* =============================================
   オンライン対戦の「もう一度」（お互いが押したら再戦）
   ============================================= */
/* 「〇〇さんが再戦を希望しています」 */
.rematch-note {
  margin-bottom: calc(var(--space-s) * -1);
  font-size: var(--font-size-s);
  font-weight: bold;
  color: var(--color-gold);
  animation: fade-in 0.3s ease both;
}

/* 自分が押して、相手を待っているとき（押すと取り消し） */
#btn-retry.waiting {
  color: var(--color-text-dark);
  background: #e9edf4;
  --color-sub-shadow: #b9c4d6;
  font-size: var(--font-size-m);
}

/* 相手が押しているとき：光って、ときどき揺れる */
#btn-retry.attention {
  animation: retry-glow 1.2s ease-in-out infinite, retry-wiggle 2.4s ease-in-out infinite;
}

@keyframes retry-glow {
  0%, 100% { box-shadow: 0 var(--button-depth) 0 var(--color-primary-shadow), 0 0 0 0 rgba(255, 216, 77, 0); }
  50% { box-shadow: 0 var(--button-depth) 0 var(--color-primary-shadow), 0 0 18px 6px rgba(255, 216, 77, 0.75); }
}

@keyframes retry-wiggle {
  0%, 70%, 100% { transform: none; }
  76% { transform: rotate(-2.5deg) scale(1.03); }
  82% { transform: rotate(2.5deg) scale(1.03); }
  88% { transform: rotate(-1.5deg); }
  94% { transform: rotate(1deg); }
}

/* 「再戦！」 */
#rematch-banner {
  position: absolute;
  left: 0;
  right: 0;
  top: 40%;
  z-index: 35;
  padding: var(--space-m) 0;
  text-align: center;
  font-size: 56px;
  font-weight: bold;
  color: #fff;
  background: linear-gradient(90deg, transparent, rgba(255, 122, 89, 0.92) 15%, rgba(255, 122, 89, 0.92) 85%, transparent);
  text-shadow: 0 4px 0 rgba(0, 0, 0, 0.2);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
}

#rematch-banner.show {
  visibility: visible;
  animation: banner 1.2s ease-out forwards;
}

@media (prefers-reduced-motion: reduce) {
  #btn-retry.attention {
    animation: retry-glow 1.2s ease-in-out infinite;
  }

  #rematch-banner.show {
    animation: fade-in-out 1.2s ease forwards;
  }
}

/* =============================================
   ★4（激レア）とオーラ
   ============================================= */
/* 出たときのバナー：光る帯が流れる、大きめの札 */
.rare-banner.ultimate {
  animation: rare-pop 2.2s ease-out forwards;
}

.rare-banner.ultimate span {
  padding: 6px 26px;
  font-size: clamp(22px, 8.6vw, 36px);
  letter-spacing: 0.02em;
  background: linear-gradient(100deg, #ff5ec8, #ffd34d 30%, #ffffff 45%, #ffd34d 60%, #8a3dff) 0 0 / 220% 100%;
  box-shadow: 0 0 36px #ff5ec8, 0 0 70px rgba(255, 211, 77, 0.7);
  animation: ultimate-shine 1s linear infinite;
}

.rare-banner.ultimate.aura-dark span {
  background-image: linear-gradient(100deg, #2a0040, #8a3dff 30%, #e3ccff 45%, #8a3dff 60%, #14031f);
  box-shadow: 0 0 36px #8a3dff, 0 0 70px rgba(20, 3, 31, 0.8);
}

@keyframes ultimate-shine {
  from { background-position: 100% 0; }
  to { background-position: -120% 0; }
}

/* 横向きのスマホ（高さが低く、指で操作する画面）：画面いっぱいに「縦向きにすると遊べます」。
   このゲームは縦長の画面で作っているため（横向きだと、ゲームの場とメニューが細い列になってしまう）。
   パソコン・タブレットの横向き（高さが 500px より大きい）は、今までどおり */
.rotate-notice {
  display: none;
}

@media (orientation: landscape) and (max-height: 500px) and (pointer: coarse) {
  .rotate-notice {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-m);
    color: #fff;
    background: var(--color-bg);
    font-size: var(--font-size-m);
    font-weight: bold;
    text-align: center;
  }

  .rotate-notice-icon {
    font-size: 48px;
    animation: rotate-hint 2.4s ease-in-out infinite;
  }
}

@keyframes rotate-hint {
  0%, 30% { transform: rotate(-90deg); }
  60%, 100% { transform: rotate(0deg); }
}

@media (prefers-reduced-motion: reduce) {
  .rotate-notice-icon {
    animation: none;
  }
}

/* 画面が一瞬、白く光る */
#flash {
  position: absolute;
  inset: 0;
  z-index: 7;
  background: radial-gradient(circle at 50% 30%, #ffffff, rgba(255, 245, 210, 0.85) 60%, rgba(255, 94, 200, 0.4));
  opacity: 0;
  pointer-events: none;
}

#flash.on {
  animation: ultimate-flash 0.6s ease-out;
}

/* ★5（まぼろし）：虹色の光が回りながら、画面全体が長めに光る */
#flash.on.legendary {
  background:
    radial-gradient(circle at 50% 34%, #ffffff 0, rgba(255, 255, 255, 0.9) 18%, transparent 55%),
    conic-gradient(from 0deg at 50% 34%, rgba(255, 93, 115, 0.6), rgba(255, 194, 26, 0.6), rgba(76, 217, 100, 0.6), rgba(61, 139, 255, 0.6), rgba(182, 92, 240, 0.6), rgba(255, 93, 115, 0.6));
  animation: legendary-flash 1.6s ease-out;
}

@keyframes legendary-flash {
  0% { opacity: 1; filter: hue-rotate(0deg); }
  30% { opacity: 0.9; }
  100% { opacity: 0; filter: hue-rotate(160deg); }
}

.rare-banner.legendary {
  animation: rare-pop 3s ease-out forwards;
}

.rare-banner.legendary span {
  padding: 8px 28px;
  font-size: 40px;
  color: #ffffff;
  text-shadow: 0 0 10px rgba(255, 255, 255, 0.9), 0 2px 4px rgba(0, 0, 0, 0.5);
  background: linear-gradient(100deg, #ff5d73, #ffc21a 20%, #ffffff 35%, #4cd964 50%, #3d8bff 70%, #b65cf0) 0 0 / 240% 100%;
  box-shadow: 0 0 40px #7ef0ff, 0 0 90px rgba(182, 92, 240, 0.8), 0 0 140px rgba(255, 194, 26, 0.6);
  animation: ultimate-shine 0.8s linear infinite;
}

/* ★6（シークレット）：まぼろしより豪華に、3段階で見せる（全部で約3.6秒）
   1. 画面が真っ暗になる（#flash。最初の約0.7秒）
   2. ドンッと白〜金色に光り（::after）、ゲームの画面が揺れる（#game-canvas.secret-shake）
   3. まん中の上のほうから金色の光の筋が回りながら広がり（::before）、金色の粒が降ってくる（.secret-rain。main.js） */
#flash.on.secret {
  overflow: hidden;
  background: rgba(5, 4, 1, 0.94);
  animation: secret-dark 3.6s ease-out;
}

#flash.on.secret::before {
  content: "";
  position: absolute;
  inset: -50%; /* 回しても角が欠けないように大きめ。50% 42% が、画面の 50% 34% の位置 */
  background:
    radial-gradient(circle at 50% 42%, #fffbe6 0, rgba(255, 213, 74, 0.95) 7%, rgba(224, 160, 0, 0.55) 18%, transparent 36%),
    repeating-conic-gradient(from 0deg at 50% 42%, rgba(255, 213, 74, 0.42) 0 5deg, transparent 5deg 12deg);
  transform-origin: 50% 42%;
  opacity: 0;
  animation: secret-burst 3.6s ease-out;
}

#flash.on.secret::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 34%, #ffffff 0, #fff4c2 35%, rgba(255, 213, 74, 0.85) 70%, rgba(224, 160, 0, 0.7));
  opacity: 0;
  animation: secret-impact 3.6s ease-out;
}

@keyframes secret-dark {
  0% { opacity: 0; }
  5% { opacity: 1; }
  20% { opacity: 1; }
  70% { opacity: 0.8; }
  100% { opacity: 0; }
}

@keyframes secret-impact {
  0%, 19% { opacity: 0; }
  21% { opacity: 1; }
  34% { opacity: 0; }
  100% { opacity: 0; }
}

@keyframes secret-burst {
  0%, 20% { opacity: 0; transform: scale(0.05) rotate(0deg); }
  30% { opacity: 1; transform: scale(1) rotate(10deg); }
  80% { opacity: 0.9; transform: scale(1.15) rotate(50deg); }
  100% { opacity: 0; transform: scale(1.25) rotate(64deg); }
}

/* ゲームの画面が、ドンッと揺れる（光った瞬間に合わせて少し遅らせる） */
#game-canvas.secret-shake {
  animation: secret-shake 0.7s ease-out 0.7s;
}

@keyframes secret-shake {
  0% { transform: translate(0, 0); }
  15% { transform: translate(-9px, 6px); }
  30% { transform: translate(8px, -7px); }
  45% { transform: translate(-6px, -4px); }
  60% { transform: translate(5px, 5px); }
  80% { transform: translate(-2px, 2px); }
  100% { transform: translate(0, 0); }
}

/* 上から降ってくる金色の粒（main.js の showSecretFx が作って、終わったら消す） */
.secret-rain {
  position: absolute;
  inset: 0;
  z-index: 8;
  overflow: hidden;
  pointer-events: none;
}

.secret-rain i {
  position: absolute;
  top: -5%;
  left: var(--x);
  width: var(--s);
  height: var(--s);
  background: radial-gradient(circle, #fffbe6, #ffd54a 45%, #b07800);
  clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%); /* キラッとした星の形 */
  opacity: 0;
  animation: secret-fall var(--d) ease-in var(--delay) forwards;
}

@keyframes secret-fall {
  0% { top: -5%; opacity: 1; transform: rotate(0deg) scale(1); }
  70% { opacity: 1; }
  100% { top: 105%; opacity: 0; transform: rotate(var(--r)) scale(0.6); }
}

/* バナー：暗いあいだは出さず、光った瞬間に大きく飛び出す。まぼろしより大きく、上に★6つ */
.rare-banner.secret {
  z-index: 9; /* 暗くなった画面（#flash）と、降ってくる粒の手前に出す */
  animation: secret-pop 4.4s ease-out forwards;
}

@keyframes secret-pop {
  0%, 16% { opacity: 0; transform: scale(2.4); }
  22% { opacity: 1; transform: scale(0.92); }
  27% { transform: scale(1.06); }
  32% { transform: scale(1); }
  85% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: translateY(-20px); }
}

.rare-banner.secret span {
  padding: 10px 26px;
  font-size: clamp(30px, 9vw, 46px); /* スマホの幅でも1行に収まるように */
  white-space: nowrap;
  letter-spacing: 1px;
  color: #1a1100;
  text-shadow: 0 1px 0 rgba(255, 250, 220, 0.8);
  background: linear-gradient(100deg, #6b4a00, #ffd54a 25%, #fffbe6 38%, #ffd54a 50%, #e0a000 70%, #6b4a00) 0 0 / 240% 100%;
  box-shadow: 0 0 0 3px #0d0a03, 0 0 0 6px #ffd54a, 0 0 50px #ffd54a, 0 0 120px rgba(255, 179, 0, 0.9), 0 0 200px rgba(255, 213, 74, 0.6);
}

.rare-banner.secret span::before {
  content: "★★★★★★";
  display: block;
  font-size: 15px;
  letter-spacing: 6px;
  line-height: 1.2;
  color: #6b4a00;
}

.rare-banner.secret small {
  color: #ffe9a0;
  font-size: 16px;
  text-shadow: 0 0 8px rgba(255, 213, 74, 0.9), 0 1px 2px #000;
}

@media (prefers-reduced-motion: reduce) {
  #flash.on.legendary,
  #flash.on.secret {
    animation: ultimate-flash 0.8s ease-out;
  }

  #flash.on.secret::before,
  #flash.on.secret::after {
    display: none;
  }

  .rare-banner.secret {
    animation: rare-pop 3.6s ease-out forwards;
  }

  .rare-banner.legendary span {
    animation: none;
  }
}

@keyframes ultimate-flash {
  0% { opacity: 0.95; }
  100% { opacity: 0; }
}

/* 図鑑のカードと詳細：★4のオーラを、キャラの後ろで動かす（opacity と transform だけ） */
.aura-card {
  position: relative;
}

.aura-card img {
  position: relative;
  z-index: 1;
}

.aura-card::before,
.aura-card::after {
  content: "";
  position: absolute;
  inset: 4% 12%;
  border-radius: 50%;
  pointer-events: none;
}

/* 光：白〜金の光が外へ広がる。光の粒が昇る */
.aura-light::before {
  background: radial-gradient(circle, rgba(255, 251, 232, 0.95) 0%, rgba(255, 201, 60, 0.55) 45%, transparent 70%);
  animation: aura-light 1.8s ease-out infinite;
}

.aura-light::after {
  z-index: 2;
  background:
    radial-gradient(circle, #fff 0 1.5px, transparent 2px) 20% 80% / 30% 40%,
    radial-gradient(circle, #ffe9a3 0 1.5px, transparent 2px) 70% 60% / 35% 45%;
  animation: aura-rise 2.4s linear infinite;
}

@keyframes aura-light {
  0% { transform: scale(0.75); opacity: 1; }
  100% { transform: scale(1.25); opacity: 0; }
}

@keyframes aura-rise {
  0% { transform: translateY(20%); opacity: 0; }
  30% { opacity: 1; }
  100% { transform: translateY(-30%); opacity: 0; }
}

/* 闇：紫〜黒のもやがゆらゆら。ときどき暗い光（稲妻）がはしる */
.aura-dark::before {
  background: radial-gradient(ellipse at 50% 60%, rgba(20, 3, 31, 0.85) 0%, rgba(138, 61, 255, 0.6) 40%, transparent 70%);
  animation: aura-dark 2.6s ease-in-out infinite;
}

.aura-dark::after {
  z-index: 2;
  background: radial-gradient(ellipse, rgba(201, 164, 255, 0.7), transparent 60%);
  opacity: 0;
  animation: aura-bolt 3.2s steps(1) infinite;
}

@keyframes aura-dark {
  0%, 100% { transform: scale(1, 1) translateY(0); opacity: 0.85; }
  33% { transform: scale(1.08, 0.96) translateY(-4%); opacity: 1; }
  66% { transform: scale(0.95, 1.08) translateY(-8%); opacity: 0.75; }
}

@keyframes aura-bolt {
  0%, 70%, 76%, 100% { opacity: 0; }
  72%, 78% { opacity: 1; }
}

/* 未登録のカード（シルエット）では、オーラは出さない */
.dex-locked .aura-card::before,
.dex-locked .aura-card::after {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .rare-banner.ultimate span {
    animation: none;
  }

  #flash.on {
    animation: fade-in-out 0.6s ease;
  }

  .aura-card::before,
  .aura-card::after {
    animation: none;
  }
}

/* 図鑑：レア度ごとの見出し（3列のグリッドの横いっぱいに） */
.dex-section {
  grid-column: 1 / -1;
  display: flex;
  align-items: baseline;
  gap: var(--space-s);
  margin-top: var(--space-s);
  padding: 2px var(--space-xs);
  border-bottom: 2px solid var(--rare-color);
  font-size: var(--font-size-m);
}

.dex-section:first-child {
  margin-top: 0;
}

.dex-section .rarity-stars {
  font-size: 13px;
}

.dex-section small {
  margin-left: auto;
  font-size: 12px;
  opacity: 0.9;
}

/* =============================================
   実績：分類の見出し・進み具合のバー・隠し実績
   ============================================= */
.ach-section {
  display: flex;
  align-items: baseline;
  margin: var(--space-m) 0 var(--space-s);
  padding-bottom: 2px;
  border-bottom: 2px solid rgba(255, 255, 255, 0.35);
  font-size: var(--font-size-m);
}

.ach-section:first-child {
  margin-top: 0;
}

.ach-section small {
  margin-left: auto;
  font-size: 12px;
  opacity: 0.85;
}

/* 累計の実績の進み具合（例 347 / 1000） */
.ach-progress {
  display: block;
  height: 6px;
  margin-top: 4px;
  border-radius: var(--radius-round);
  background: rgba(255, 255, 255, 0.2);
  overflow: hidden;
}

.ach-progress i {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--color-gold);
}

.ach-progress-text {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  font-weight: bold;
  opacity: 0.85;
}

/* 隠し実績（まだ達成していない） */
.ach-secret {
  background: rgba(20, 10, 40, 0.35);
}

/* =============================================
   ハロウィンイベント
   ============================================= */
/* モード選択画面・ステージ画面のボタン（かぼちゃ色） */
.btn-halloween {
  color: #fff;
  background: linear-gradient(135deg, #ff8a1f, #b8410e);
  --color-sub-shadow: #6b2a0c;
}

.btn-halloween small {
  opacity: 0.95;
}

/* ステージの説明 */
.halloween-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.hw-stage {
  padding: var(--space-m);
  border-radius: var(--radius-m);
  background: linear-gradient(160deg, rgba(40, 14, 64, 0.85), rgba(16, 6, 28, 0.85));
}

.hw-stage b {
  font-size: var(--font-size-l);
}

.hw-stage p {
  margin: var(--space-xs) 0;
  font-size: 14px;
  line-height: 1.5;
}

.hw-stage small {
  font-size: 12px;
  opacity: 0.8;
}

.halloween-body .section-title small {
  margin-left: var(--space-s);
  font-size: 13px;
  color: var(--color-gold);
}

/* ごほうび（もらったものにはチェック、まだのものは「？」） */
.hw-reward {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  margin-bottom: var(--space-s);
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-m);
  background: var(--color-panel);
}

.hw-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  font-weight: bold;
  background: rgba(255, 255, 255, 0.2);
}

.hw-reward.got {
  background: rgba(255, 138, 31, 0.35);
}

.hw-reward.got .hw-mark {
  color: #fff;
  background: #ff8a1f;
}

.hw-reward-main b {
  display: block;
  font-size: 15px;
}

.hw-reward-main small {
  font-size: 13px;
}

.hw-done {
  font-weight: bold;
  color: var(--color-gold);
  text-align: center;
}

/* リザルトの「ごほうびゲット！」 */
.reward-get {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: var(--space-m);
  padding: var(--space-m);
  border-radius: var(--radius-l);
  color: #fff;
  background: linear-gradient(135deg, #ff8a1f, #7a2bb0);
  box-shadow: 0 0 24px rgba(255, 138, 31, 0.7);
  animation: pop 0.6s ease-out 0.4s both;
}

.reward-get span {
  font-size: 30px;
  font-weight: bold;
}

.reward-get b {
  font-size: var(--font-size-m);
}

.reward-get small {
  font-size: 12px;
  opacity: 0.9;
}

.reward-note {
  margin-top: var(--space-s);
  font-size: var(--font-size-s);
  font-weight: bold;
}

/* タイトル画面：ロゴの横のかぼちゃと、横切るこうもり（期間中だけ。#screen-title.halloween） */
.title-top {
  position: relative;
}

.hw-pumpkin,
.hw-bats {
  display: none;
}

#screen-title.halloween .hw-pumpkin {
  display: block;
  position: absolute;
  top: 4px;
  right: 2px;
  font-size: 44px;
  animation: hw-pumpkin 2.4s ease-in-out infinite;
}

@keyframes hw-pumpkin {
  0%, 100% { transform: rotate(-8deg) translateY(0); }
  50% { transform: rotate(8deg) translateY(-6px); }
}

#screen-title.halloween .hw-bats {
  display: block;
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.hw-bats span {
  position: absolute;
  left: -40px;
  font-size: 26px;
  animation: hw-bat 9s linear infinite;
}

.hw-bats span:nth-child(1) { top: 22%; animation-delay: 0s; }
.hw-bats span:nth-child(2) { top: 34%; font-size: 20px; animation-delay: 3.2s; animation-duration: 11s; }
.hw-bats span:nth-child(3) { top: 14%; font-size: 18px; animation-delay: 6.1s; animation-duration: 8s; }

@keyframes hw-bat {
  0% { transform: translate(0, 0); }
  25% { transform: translate(calc(25vw + 30px), -18px); }
  50% { transform: translate(calc(50vw + 40px), 10px); }
  75% { transform: translate(calc(75vw + 50px), -14px); }
  100% { transform: translate(calc(100vw + 80px), 0); }
}

/* 実績：期間限定 */
.ach-limited {
  color: var(--color-gold);
}

.ach-closed {
  opacity: 0.6;
}

@media (prefers-reduced-motion: reduce) {
  #screen-title.halloween .hw-pumpkin,
  .hw-bats span {
    animation: none;
  }

  .hw-bats span {
    left: auto;
    right: 12%;
  }
}

/* 読み込みの状況（開発用。load-status.js）。タップは下に通す */
.load-status {
  position: fixed;
  left: 4px;
  bottom: 4px;
  z-index: 1000;
  max-width: min(92vw, 420px);
  max-height: 45vh;
  overflow: hidden;
  padding: 6px 8px;
  border-radius: 6px;
  color: #b9ffb9;
  background: rgba(0, 0, 0, 0.72);
  font: 11px/1.45 ui-monospace, Menlo, Consolas, monospace;
  white-space: pre-wrap;
  word-break: break-all;
  pointer-events: none;
}

/* =============================================
   アイコンのまわりの枠（.frame）と、称号の札（.title-badge.ranked）
   形はすべての格で同じ（輪＋てっぺんの小さな星）。違うのは色だけ。
   色は下の「格ごとの色」で変数を切りかえる。新しい格を足すときは、そこに1行足すだけでよい
     --frame-color … 輪・星の色 ／ --frame-dark … 輪の外側のふち・札のふち
     --frame-light … 札の上側の明るい色 ／ --frame-text … 札の文字の色
     --frame-star  … 星の塗り（ふだんは輪の色。虹色など特別なときだけ書く）
     --frame-badge … 札の塗り（ふだんは light → color のグラデーション）
     --frame-ring  … （まぼろし・期間限定・隠しだけ）輪の塗り。札と同じ色にする（下の「札と同じ色の輪」）
   枠の太さ・星の大きさは、アイコンの大きさ（--av）に合わせて変わる
   ============================================= */
.avatar { --av: 38px; }
.avatar-xl { --av: 112px; }
.rank-avatar { --av: 36px; }
.vs-avatar { --av: 52px; }

/* 格ごとの色（アイコンの .frame-〇〇 と、札の .rank-〇〇 で同じ色を使う） */
.frame-bronze, .rank-bronze { --frame-color: #cd8a4f; --frame-dark: #6e4019; --frame-light: #f2c79c; --frame-text: #3d2208; }
.frame-silver, .rank-silver { --frame-color: #c9d1da; --frame-dark: #6f7984; --frame-light: #ffffff; --frame-text: #2b3a55; }
.frame-gold, .rank-gold { --frame-color: #ffd84d; --frame-dark: #a87700; --frame-light: #fff3b0; --frame-text: #4a3500; }
.frame-legend, .rank-legend {
  --frame-color: #b65cf0;
  --frame-dark: #4a2470;
  --frame-text: #ffffff;
  --frame-star: linear-gradient(90deg, #ff5d73, #ffc21a, #4cd964, #3d8bff, #b65cf0);
  --frame-badge: linear-gradient(90deg, #ff5d73, #ffc21a, #4cd964, #3d8bff, #b65cf0, #ff5d73) 0 0 / 300% 100%;
}
/* まぼろし：夜空色の札に、虹の星（輪は虹が回り、白く光る。下の「まぼろしの枠」） */
/* まぼろし：輪も札も夜空色（紺→紫→青）で、ふちはクリーム色。星もクリーム色で光る */
.frame-mythic, .rank-mythic {
  --frame-color: #fff6d6;
  --frame-dark: #fff6d6;
  --frame-text: #ffffff;
  --frame-star: linear-gradient(#ffffff, #fff6d6);
  --frame-badge: linear-gradient(90deg, #2a1660, #4b2a9a, #1d4f8a, #2a1660) 0 0 / 300% 100%;
  --frame-ring: conic-gradient(#2a1660, #4b2a9a, #1d4f8a, #2a1660, #4b2a9a, #1d4f8a, #2a1660);
}
/* 隠し：紫×黒（ふちには「？」。achievements.json の decoration: "question"）。輪も札と同じ紫→黒 */
.frame-secret, .rank-secret { --frame-color: #8f5bff; --frame-dark: #1a0b2e; --frame-light: #c9a8ff; --frame-text: #f3e6ff; --frame-badge: linear-gradient(#3a1a66, #1a0b2e); --frame-ring: linear-gradient(#3a1a66, #1a0b2e); }
/* 合言葉（合言葉でもらう称号だけ）：深い緑の札に金の文字。輪は深い緑に金色がゆっくり回る（下の「合言葉の枠」）。ふちには鍵 */
.frame-code, .rank-code {
  --frame-color: #f4c542;
  --frame-dark: #06302a;
  --frame-light: #ffe39a;
  --frame-text: #ffe39a;
  --frame-badge: linear-gradient(#11705f, #073d35);
  --frame-ring: conic-gradient(#11705f, #f4c542 12%, #11705f 25%, #073d35 50%, #11705f 62%, #f4c542 75%, #11705f 88%, #073d35);
}
/* 期間限定：輪も札と同じ紫。星（飾り）は札の文字と同じオレンジ */
.frame-event, .rank-event { --frame-color: #ff8a1f; --frame-dark: #3b1458; --frame-light: #ffc27a; --frame-text: #ffb15c; --frame-badge: linear-gradient(#5a2380, #3b1458); --frame-ring: linear-gradient(#5a2380, #3b1458); }
/* まだ取っていない称号（称号を選ぶ画面だけ） */
.frame-locked, .rank-locked { --frame-color: #9aa1aa; --frame-dark: #5d636b; --frame-light: #c4c9cf; --frame-text: #3a3f46; }

/* 枠の形（全部の格で共通） */
.avatar.frame {
  position: relative;
  border-color: var(--frame-color);
  border-width: max(2px, calc(var(--av) * 0.07));
  box-shadow: 0 0 0 max(1px, calc(var(--av) * 0.025)) var(--frame-dark);
}

/* ふちに並ぶ星（格の数だけ。.stars-〇 で数を決める）
   丸いアイコンのふちに沿って、円のてっぺんから左右に等間隔で並べる。数が増えるほど、星を小さく・間を詰める。
   --p1〜--p4：星の置き場所（::after の箱の左上から）、--sz：星の大きさ。どちらもアイコンの大きさ（--av）に対する割合なので、
   どの大きさのアイコンでも同じ並びになる。称号の飾り（.deco-〇〇。下の「称号の飾り」）も、同じ場所に置く。
   この数値は、星の角度と大きさの表から計算して作ったもの（1つ：真上 / 2つ：±20度 / 3つ：0・±34度 / 4つ：±16・±48度 / 5つ：0・±32・±64度） */
.stars-1 { --sz: calc(var(--av) * 0.34); --p1: calc(var(--av) * 0.63) calc(var(--av) * 0.11); --p2: -9999px -9999px; --p3: -9999px -9999px; --p4: -9999px -9999px; --p5: -9999px -9999px; }
.stars-2 { --sz: calc(var(--av) * 0.3); --p1: calc(var(--av) * 0.4721) calc(var(--av) * 0.1614); --p2: calc(var(--av) * 0.8279) calc(var(--av) * 0.1614); --p3: -9999px -9999px; --p4: -9999px -9999px; --p5: -9999px -9999px; }
.stars-3 { --sz: calc(var(--av) * 0.27); --p1: calc(var(--av) * 0.3742) calc(var(--av) * 0.2339); --p2: calc(var(--av) * 0.665) calc(var(--av) * 0.145); --p3: calc(var(--av) * 0.9558) calc(var(--av) * 0.2339); --p4: -9999px -9999px; --p5: -9999px -9999px; }
.stars-4 { --sz: calc(var(--av) * 0.24); --p1: calc(var(--av) * 0.2936) calc(var(--av) * 0.3321); --p2: calc(var(--av) * 0.5367) calc(var(--av) * 0.1801); --p3: calc(var(--av) * 0.8233) calc(var(--av) * 0.1801); --p4: calc(var(--av) * 1.0664) calc(var(--av) * 0.3321); --p5: -9999px -9999px; }
.stars-5 { --sz: calc(var(--av) * 0.21); --p1: calc(var(--av) * 0.2276) calc(var(--av) * 0.467); --p2: calc(var(--av) * 0.4194) calc(var(--av) * 0.254); --p3: calc(var(--av) * 0.695) calc(var(--av) * 0.175); --p4: calc(var(--av) * 0.9706) calc(var(--av) * 0.254); --p5: calc(var(--av) * 1.1626) calc(var(--av) * 0.467); }

.avatar.frame::after {
  content: "";
  position: absolute;
  /* アイコンより、まわりに --av の 0.3 倍だけ広い箱（星がふちからはみ出すぶん）。枠の太さのぶんもずらして、円の真ん中に合わせる */
  inset: calc(var(--av) * -0.3 - max(2px, calc(var(--av) * 0.07)));
  background: var(--frame-star, linear-gradient(var(--frame-light, var(--frame-color)), var(--frame-color)));
  -webkit-mask:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2 61 37 98 37 68 58 79 93 50 72 21 93 32 58 2 37 39 37Z'/%3E%3C/svg%3E") var(--p1) / var(--sz) var(--sz) no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2 61 37 98 37 68 58 79 93 50 72 21 93 32 58 2 37 39 37Z'/%3E%3C/svg%3E") var(--p2) / var(--sz) var(--sz) no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2 61 37 98 37 68 58 79 93 50 72 21 93 32 58 2 37 39 37Z'/%3E%3C/svg%3E") var(--p3) / var(--sz) var(--sz) no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2 61 37 98 37 68 58 79 93 50 72 21 93 32 58 2 37 39 37Z'/%3E%3C/svg%3E") var(--p4) / var(--sz) var(--sz) no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2 61 37 98 37 68 58 79 93 50 72 21 93 32 58 2 37 39 37Z'/%3E%3C/svg%3E") var(--p5) / var(--sz) var(--sz) no-repeat;
  mask:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2 61 37 98 37 68 58 79 93 50 72 21 93 32 58 2 37 39 37Z'/%3E%3C/svg%3E") var(--p1) / var(--sz) var(--sz) no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2 61 37 98 37 68 58 79 93 50 72 21 93 32 58 2 37 39 37Z'/%3E%3C/svg%3E") var(--p2) / var(--sz) var(--sz) no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2 61 37 98 37 68 58 79 93 50 72 21 93 32 58 2 37 39 37Z'/%3E%3C/svg%3E") var(--p3) / var(--sz) var(--sz) no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2 61 37 98 37 68 58 79 93 50 72 21 93 32 58 2 37 39 37Z'/%3E%3C/svg%3E") var(--p4) / var(--sz) var(--sz) no-repeat,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2 61 37 98 37 68 58 79 93 50 72 21 93 32 58 2 37 39 37Z'/%3E%3C/svg%3E") var(--p5) / var(--sz) var(--sz) no-repeat;
  pointer-events: none;
}

/* 称号の飾り（achievements.json の decoration。frames.js の DECORATIONS）
   星の代わりに、ふちの星と同じ場所・同じ数に画像（images/decorations/）を置く。飾りを足すときは、ここに1つ足す */
.deco-pumpkin { --deco-img: url("../images/decorations/pumpkin.svg"); }
.deco-snow { --deco-img: url("../images/decorations/snowflake.svg"); }
.deco-question { --deco-img: url("../images/decorations/question.svg"); }
.deco-key { --deco-img: url("../images/decorations/key.svg"); } /* 合言葉でもらう称号だけの飾り（codes.js） */

.avatar.frame[class*="deco-"]::after {
  -webkit-mask: none;
  mask: none;
  background:
    var(--deco-img) var(--p1) / var(--sz) var(--sz) no-repeat,
    var(--deco-img) var(--p2) / var(--sz) var(--sz) no-repeat,
    var(--deco-img) var(--p3) / var(--sz) var(--sz) no-repeat,
    var(--deco-img) var(--p4) / var(--sz) var(--sz) no-repeat,
    var(--deco-img) var(--p5) / var(--sz) var(--sz) no-repeat;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.4));
}

/* まだ取っていない称号の見本では、飾りも灰色に */
.avatar.frame-locked[class*="deco-"]::after {
  filter: grayscale(1) opacity(0.6);
}

/* 称号を選ぶ画面・実績画面：みんなの取得率（「持っている人 〇%」。ranking.gs の集計） */
.title-rate,
.ach-rate {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  opacity: 0.75;
}

/* 称号を選ぶ画面：その格の称号を、まだ1つも持っていないとき */
.title-group-empty {
  margin: 0 0 var(--space-s);
  font-size: 12px;
  opacity: 0.6;
}

/* =============================================
   スタッフの称号の枠（.frame-staff）と札（.staff-title）：管理者・社員・運営（frames.js の STAFF）
   色の輪に外側のふち。星の代わりに、枠の下に小さな札（ADMIN・STAFF・運営）。card.js の STAFF_COLORS と同じ色
   ============================================= */
.frame-staff-admin { --staff-ring: #141414; --staff-edge: #e8c25a; --staff-tag-bg: #e8c25a; --staff-tag: #141414; --staff-label: "ADMIN"; }
.frame-staff-employee { --staff-ring: #1d3a6e; --staff-edge: #ffffff; --staff-tag-bg: #ffffff; --staff-tag: #1d3a6e; --staff-label: "STAFF"; }
.frame-staff-operator { --staff-ring: #d62f3a; --staff-edge: #ffffff; --staff-tag-bg: #ffffff; --staff-tag: #d62f3a; --staff-label: "運営"; }

.avatar.frame.frame-staff {
  border-color: var(--staff-ring);
  border-width: max(3px, calc(var(--av) * 0.08));
  box-shadow: 0 0 0 max(1.5px, calc(var(--av) * 0.035)) var(--staff-edge), 0 2px 6px rgba(0, 0, 0, 0.35);
}

/* 枠の下の札（星の並びの代わり） */
.avatar.frame.frame-staff::after {
  content: var(--staff-label);
  inset: auto;
  left: 50%;
  bottom: calc(var(--av) * -0.2);
  padding: 0 calc(var(--av) * 0.08);
  border-radius: 999px;
  color: var(--staff-tag);
  background: var(--staff-tag-bg);
  -webkit-mask: none;
  mask: none;
  font-size: max(7px, calc(var(--av) * 0.16));
  font-weight: bold;
  line-height: 1.35;
  letter-spacing: 0.04em;
  white-space: nowrap;
  transform: translateX(-50%);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}

/* 称号の札 */
.title-badge.staff-title {
  color: #ffffff;
  background: var(--staff-badge, #333);
  box-shadow: inset 0 0 0 1px var(--staff-badge-line, #fff);
}

.title-badge.rank-staff-admin { --staff-badge: linear-gradient(#2a2a2a, #0d0d0d); --staff-badge-line: #e8c25a; color: #f3d27a; }
.title-badge.rank-staff-employee { --staff-badge: linear-gradient(#2b4f8f, #1d3a6e); --staff-badge-line: #ffffff; }
.title-badge.rank-staff-operator { --staff-badge: linear-gradient(#e8434e, #c22731); --staff-badge-line: #ffffff; }

/* 管理者メニュー：スタッフの称号の一覧 */
.admin-staff-row {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  margin-bottom: var(--space-s);
  padding: var(--space-s) var(--space-m) calc(var(--space-s) + 6px);
  border-radius: var(--radius-m);
  background: var(--color-panel);
}

.admin-staff-avatar {
  --av: 40px;
  flex-shrink: 0;
}

.admin-staff-main {
  flex: 1;
  min-width: 0;
  text-align: left;
}

.admin-staff-main small {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  opacity: 0.8;
}

/* =============================================
   ランキングの称号の枠（.frame-champ）と札（.champ-title）：ランキングの上位の人だけ（rank-titles.js）
   ほかの称号とちがう形：星は付けず、三重の輪（ふち・太い帯・ふち・帯・ふち）に光がゆっくり回り、まわりがゆっくり光る。
   札は、両はしが切れこんだリボンの形で、ときどき光が走る。色は card.js の CHAMP_COLORS と同じ
     champ-1 … 1位：★6（シークレット）のような黒×金
     champ-2 … 2・3位：★5（まぼろし）のような夜空色に虹
   「視差効果を減らす」では動かない
   ============================================= */
.frame-champ-1, .rank-champ-1 {
  --champ-band: #120d04;
  --champ-edge: #ffd76a;
  --champ-glow: rgba(255, 196, 64, 0.8);
  --champ-light: conic-gradient(from 0deg, transparent 0 50%, #6b4c0e 62%, #ffe9a6 76%, #fffbe8 80%, #ffd76a 84%, transparent 96%);
  --champ-badge: linear-gradient(180deg, #2e2209, #0b0803 55%, #1d1507);
  --champ-text: #ffe27a;
}

.frame-champ-2, .rank-champ-2 {
  --champ-band: #2a1660;
  --champ-edge: #fff6d6;
  --champ-glow: rgba(186, 150, 255, 0.75);
  --champ-light: conic-gradient(#ff5d73, #ffc21a, #4cd964, #3d8bff, #b65cf0, #ff5d73);
  --champ-badge: linear-gradient(90deg, #2a1660, #4b2a9a, #1d4f8a, #2a1660) 0 0 / 300% 100%;
  --champ-text: #ffffff;
}

.avatar.frame.frame-champ {
  --ring: max(3px, calc(var(--av) * 0.09));
  border-color: var(--champ-band);
  border-width: var(--ring);
  box-shadow:
    0 0 0 max(1px, calc(var(--av) * 0.022)) var(--champ-edge),
    0 0 0 max(2px, calc(var(--av) * 0.05)) var(--champ-band),
    0 0 0 max(3px, calc(var(--av) * 0.072)) var(--champ-edge),
    0 0 calc(var(--av) * 0.3) var(--champ-glow);
  animation: champ-glow 3.2s ease-in-out infinite;
}

/* 太い帯の上を回る光（1位は金の光が1つ、2・3位は虹がまるごと回る） */
.avatar.frame.frame-champ::before {
  content: "";
  position: absolute;
  inset: calc(var(--ring) * -1);
  border-radius: 50%;
  background: var(--champ-light);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - var(--ring)), #000 calc(100% - var(--ring) + 0.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - var(--ring)), #000 calc(100% - var(--ring) + 0.5px));
  animation: frame-spin 4.5s linear infinite;
  pointer-events: none;
}

/* 星は付けない */
.avatar.frame.frame-champ::after {
  content: none;
}

@keyframes champ-glow {
  50% {
    box-shadow:
      0 0 0 max(1px, calc(var(--av) * 0.022)) var(--champ-edge),
      0 0 0 max(2px, calc(var(--av) * 0.05)) var(--champ-band),
      0 0 0 max(3px, calc(var(--av) * 0.072)) var(--champ-edge),
      0 0 calc(var(--av) * 0.5) var(--champ-glow);
  }
}

/* 札：リボンの形（両はしに切れこみ）。上下に枠と同じ色の細い線 */
.title-badge.champ-title {
  padding: 0 10px;
  border-radius: 0;
  color: var(--champ-text);
  background: var(--champ-badge);
  box-shadow: inset 0 1px 0 var(--champ-edge), inset 0 -1px 0 var(--champ-edge);
  -webkit-clip-path: polygon(0 0, 100% 0, calc(100% - 6px) 50%, 100% 100%, 0 100%, 6px 50%);
  clip-path: polygon(0 0, 100% 0, calc(100% - 6px) 50%, 100% 100%, 0 100%, 6px 50%);
  text-shadow: 0 0 5px var(--champ-glow);
}

.title-badge.rank-champ-2 {
  animation: badge-rainbow 6s linear infinite;
}

/* ときどき光が走る（金の札と同じ動き） */
.title-badge.champ-title::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 40%, rgba(255, 255, 255, 0.75) 50%, transparent 60%) no-repeat;
  background-size: 300% 100%;
  background-position: 100% 0;
  animation: frame-shine 3.6s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .avatar.frame.frame-champ,
  .avatar.frame.frame-champ::before,
  .title-badge.champ-title,
  .title-badge.champ-title::after {
    animation: none;
  }
}

/* 管理者メニュー：ランキングの称号の一覧（見た目の確認用）とランキングの行の見本 */
.admin-rank-preview {
  margin-top: var(--space-s);
  pointer-events: none;
}

/* =============================================
   開発者の枠（.frame-dev）と札（.dev-title）：ほかの称号とちがう「コード風」
   黒っぽい輪に、緑に光るふち。ふちに沿って </> と 0・1 が並び、ゆっくり回りながら、ときどき点滅する。
   ふちの光が、輪に沿ってゆっくり流れる。「視差効果を減らす」では動かない
   ============================================= */
.avatar.frame.frame-dev {
  border-color: #0b1410;
  box-shadow:
    0 0 0 max(1px, calc(var(--av) * 0.025)) #39ff88,
    0 0 calc(var(--av) * 0.2) rgba(57, 255, 136, 0.55);
}

/* ふちに沿った </> と 0・1（images/decorations/code-ring.svg を、アイコンより少し大きく重ねる） */
.avatar.frame.frame-dev::after {
  inset: calc(var(--av) * -0.2 - max(2px, calc(var(--av) * 0.07)));
  -webkit-mask: none;
  mask: none;
  background: url("../images/decorations/code-ring.svg") center / 100% 100% no-repeat;
  filter: drop-shadow(0 0 2px rgba(57, 255, 136, 0.9));
  animation: dev-ring 24s linear infinite, dev-blink 3.2s steps(1) infinite;
}

/* ふちを流れる光（緑の光の帯が、輪に沿ってゆっくり回る） */
.avatar.frame.frame-dev::before {
  content: "";
  position: absolute;
  --ring: max(2px, calc(var(--av) * 0.07));
  inset: calc(var(--ring) * -1);
  border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0 70%, rgba(57, 255, 136, 0.15) 80%, #b9ffd4 92%, transparent 96%);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - var(--ring)), #000 calc(100% - var(--ring) + 0.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - var(--ring)), #000 calc(100% - var(--ring) + 0.5px));
  animation: frame-spin 5s linear infinite;
  pointer-events: none;
}

@keyframes dev-ring {
  to { transform: rotate(360deg); }
}

@keyframes dev-blink {
  0%, 88%, 92%, 100% { opacity: 1; }
  90% { opacity: 0.35; }
}

/* 開発者の札：黒地に緑の等幅の文字、頭に </>、うしろに点滅するカーソル */
.title-badge.dev-title {
  padding: 0 8px;
  border: 1px solid #39ff88;
  border-radius: 4px;
  color: #39ff88;
  background: #07110c;
  box-shadow: 0 0 6px rgba(57, 255, 136, 0.55);
  font-family: Menlo, Consolas, "Courier New", monospace;
  text-shadow: 0 0 4px rgba(57, 255, 136, 0.8);
}

.dev-code {
  margin-right: 5px;
  opacity: 0.85;
}

.dev-caret {
  display: inline-block;
  width: 0.5em;
  height: 1em;
  margin-left: 3px;
  vertical-align: -0.12em;
  background: #39ff88;
  animation: dev-caret 1s steps(1) infinite;
}

@keyframes dev-caret {
  50% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .avatar.frame.frame-dev::after,
  .avatar.frame.frame-dev::before,
  .dev-caret {
    animation: none;
  }
}

/* 金：ときどき、丸の中をななめの光が通る */
.avatar.frame-gold {
  box-shadow: 0 0 0 max(1px, calc(var(--av) * 0.025)) var(--frame-dark), 0 0 calc(var(--av) * 0.25) rgba(255, 216, 77, 0.6);
}

.avatar.frame-gold::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: linear-gradient(115deg, transparent 40%, rgba(255, 255, 255, 0.75) 50%, transparent 60%) no-repeat;
  background-size: 300% 100%;
  background-position: 100% 0;
  animation: frame-shine 4s ease-in-out infinite;
  pointer-events: none;
}

@keyframes frame-shine {
  0%, 70% { background-position: 100% 0; }
  100% { background-position: -50% 0; }
}

/* 伝説：虹色の輪が、ゆっくり回る（輪の形に切り抜いた虹を、回すだけ。太さは共通の輪と同じ） */
.avatar.frame-legend {
  border-color: transparent;
}

.avatar.frame-legend::before {
  content: "";
  position: absolute;
  --ring: max(2px, calc(var(--av) * 0.07));
  inset: calc(var(--ring) * -1);
  border-radius: 50%;
  background: conic-gradient(#ff5d73, #ffc21a, #4cd964, #3d8bff, #b65cf0, #ff5d73);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - var(--ring)), #000 calc(100% - var(--ring) + 0.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - var(--ring)), #000 calc(100% - var(--ring) + 0.5px));
  animation: frame-spin 6s linear infinite;
  pointer-events: none;
}

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

/* 札と同じ色の輪（まぼろし・期間限定・隠し）：輪の形に切り抜いた --frame-ring を、ふちの上に重ねる（太さは共通の輪と同じ） */
.avatar.frame-mythic,
.avatar.frame-event,
.avatar.frame-secret,
.avatar.frame-code {
  border-color: transparent;
}

.avatar.frame-mythic::before,
.avatar.frame-event::before,
.avatar.frame-secret::before,
.avatar.frame-code::before {
  content: "";
  position: absolute;
  --ring: max(2px, calc(var(--av) * 0.07));
  inset: calc(var(--ring) * -1);
  border-radius: 50%;
  background: var(--frame-ring);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - var(--ring)), #000 calc(100% - var(--ring) + 0.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - var(--ring)), #000 calc(100% - var(--ring) + 0.5px));
  pointer-events: none;
}

/* まぼろしの枠：夜空色の輪がゆっくり回り（札の色が流れるのと同じ）、まわりが白く光ったり弱まったりする。星も光る */
.avatar.frame-mythic {
  animation: frame-mythic-glow 2.4s ease-in-out infinite;
}

.avatar.frame-mythic::before {
  animation: frame-spin 6s linear infinite;
}

.avatar.frame-mythic::after {
  filter: drop-shadow(0 0 calc(var(--av) * 0.04) rgba(255, 246, 214, 0.9));
}

@keyframes frame-mythic-glow {
  0%, 100% { box-shadow: 0 0 0 max(1px, calc(var(--av) * 0.025)) var(--frame-dark), 0 0 calc(var(--av) * 0.12) rgba(255, 255, 255, 0.5); }
  50% { box-shadow: 0 0 0 max(1px, calc(var(--av) * 0.025)) var(--frame-dark), 0 0 calc(var(--av) * 0.3) rgba(255, 246, 214, 0.95); }
}

/* 合言葉の枠：金色の光が、深い緑の輪をゆっくり回る。まわりが、ほんのり金色に光る */
.avatar.frame-code {
  box-shadow: 0 0 0 max(1px, calc(var(--av) * 0.025)) var(--frame-dark), 0 0 calc(var(--av) * 0.14) rgba(244, 197, 66, 0.55);
}

.avatar.frame-code::before {
  animation: frame-spin 8s linear infinite;
}

/* 合言葉の札：深い緑に金のふち。金色の光が、ときどき横に走る */
.title-badge.rank-code {
  position: relative;
  overflow: hidden;
  box-shadow: inset 0 0 0 1px #f4c542;
}

.title-badge.rank-code::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 35%, rgba(255, 243, 190, 0.55) 50%, transparent 65%) 100% 0 / 300% 100% no-repeat;
  animation: frame-shine 4s ease-in-out infinite;
  pointer-events: none;
}

/* まぼろしの札：夜空色の上を、ゆっくり色が流れる。文字は白く光る */
.title-badge.rank-mythic {
  text-shadow: 0 0 6px rgba(255, 255, 255, 0.9);
  box-shadow: inset 0 0 0 1px #fff6d6, 0 0 6px rgba(255, 246, 214, 0.7);
  animation: badge-rainbow 6s linear infinite;
}

/* 称号の札（形は全部の格で共通。色だけ変わる） */
.title-badge {
  position: relative;
  display: inline-block;
  max-width: 100%;
  margin-top: 2px;
  padding: 0 8px;
  overflow: hidden;
  border-radius: var(--radius-round);
  font-size: 11px;
  font-weight: bold;
  line-height: 1.6;
  white-space: nowrap;
  text-overflow: ellipsis;
  vertical-align: middle;
  color: var(--color-gold);
}

.title-badge.ranked {
  color: var(--frame-text);
  background: var(--frame-badge, linear-gradient(var(--frame-light), var(--frame-color)));
  box-shadow: inset 0 0 0 1px var(--frame-dark);
}



.title-badge.rank-legend {
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
  animation: badge-rainbow 6s linear infinite;
}



/* 金の札：ときどき光が走る */
.title-badge.rank-gold::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 40%, rgba(255, 255, 255, 0.8) 50%, transparent 60%) no-repeat;
  background-size: 300% 100%;
  background-position: 100% 0;
  animation: frame-shine 4s ease-in-out infinite;
}

@keyframes badge-rainbow {
  to { background-position: 300% 0; }
}

/* タイトル画面左上・リザルトのバッジでは、札の上下を少しつめる */
.profile-chip-text .title-badge,
.player-badge .title-badge {
  display: block;
  width: fit-content;
  margin-top: 2px;
  font-size: 10px;
}

/* プロフィール画面：アイコンの下に称号の札 */
.profile-avatar-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-s);
  max-width: 150px;
}

.profile-title-badge .title-badge {
  font-size: 12px;
}

/* オンライン対戦のリザルト：相手の名前と称号の枠 */
.opponent-badge {
  margin-top: var(--space-m);
}

.opponent-badge > small {
  display: block;
  margin-bottom: 4px;
  font-size: 11px;
  opacity: 0.8;
}

.opponent-badge .player-badge {
  margin-bottom: 0;
}

@media (prefers-reduced-motion: reduce) {
  .avatar.frame-gold::before,
  .avatar.frame-legend::before,
  .avatar.frame-mythic,
  .avatar.frame-mythic::before,
  .avatar.frame-code::before,
  .title-badge.rank-code::after,
  .title-badge.rank-mythic,
  .title-badge.rank-legend,
  .title-badge.rank-gold::after {
    animation: none;
  }
}

/* =============================================
   オンライン対戦の、試合の前の対戦カード（vs-intro.js）
   相手のカード（赤）は右上から、自分のカード（青）は左下から、ななめにすべり込む。
   --vs-slide：すべり込む時間 / --vs-exit：抜けて消える時間（config.js の online から）
   ============================================= */
#vs-intro {
  position: absolute;
  inset: 0;
  z-index: 36;
  overflow: hidden;
  cursor: pointer;
}

#vs-intro .vs-dim {
  position: absolute;
  inset: 0;
  background: rgba(10, 16, 34, 0.74);
  opacity: 0;
  transition: opacity 0.25s ease;
}

#vs-intro.show .vs-dim {
  opacity: 1;
}

#vs-intro.out .vs-dim {
  opacity: 0;
  transition-duration: var(--vs-exit);
}

#vs-intro.closed {
  opacity: 0;
  transition: opacity 0.2s ease;
  pointer-events: none;
}

.vs-stage {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-m);
  padding: var(--space-m);
}

/* ---------- カード ---------- */
.vs-card {
  position: relative;
  width: min(88%, 340px);
  padding: 22px 14px 12px;
  border: 3px solid rgba(255, 255, 255, 0.85);
  border-radius: var(--radius-m);
  color: #fff;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.35);
  opacity: 0;
}

.vs-card.vs-them {
  align-self: flex-end;
  background: linear-gradient(135deg, #ff6f82, #c2364b);
}

.vs-card.vs-me {
  align-self: flex-start;
  background: linear-gradient(135deg, #4f9bff, #2459a8);
}

/* 色を背景にしたカード（プロフィールで選んだ背景の絵を下地に。自分・相手は枠の色で分かる） */
.vs-card.has-bg {
  background-size: cover;
  background-position: center;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}

.vs-card.vs-me.has-bg {
  border-color: #4f9bff;
}

.vs-card.vs-them.has-bg {
  border-color: #ff6f82;
}

/* プロフィール画面の、自分の対戦カードの見本（演出の外なので、最初から見えるように） */
.card-preview .vs-card {
  width: 100%;
  max-width: 340px;
  margin: 16px auto 10px;
  opacity: 1;
}

/* 対戦カードの色の「いつもの色」の見本 */
.card-default-swatch {
  display: block;
  aspect-ratio: 16 / 9;
  border-radius: 6px;
  background: linear-gradient(135deg, #4f9bff, #2459a8);
}

/* 「あなた」「相手」の札 */
.vs-side {
  position: absolute;
  top: -12px;
  left: 14px;
  padding: 1px 12px;
  border-radius: var(--radius-round);
  background: #fff;
  font-size: 12px;
  font-weight: bold;
  line-height: 1.6;
}

.vs-them .vs-side {
  color: #c2364b;
}

.vs-me .vs-side {
  color: #2459a8;
}

.vs-head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.vs-avatar {
  width: 52px;
  height: 52px;
  border-width: 3px;
  font-size: 22px;
}

/* 名前と称号（長い称号は折り返す。切らない） */
.vs-who {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
}

/* 長い名前のときだけ小さくして、1行に収める（--fit は名前の長さ。vs-intro.js の UI.fit） */
.vs-who b {
  max-width: 100%;
  overflow: hidden;
  font-size: clamp(13px, calc(min(38vw, 190px) / var(--fit, 1)), 19px);
  line-height: 1.3;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.vs-who .title-badge {
  white-space: normal;
  text-align: left;
}

.vs-stats {
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
}

.vs-stats li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  padding: 3px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.25);
  font-size: 13px;
}

.vs-stats li span {
  opacity: 0.85;
  white-space: nowrap;
}

.vs-stats li b {
  font-size: 15px;
  text-align: right;
}

.vs-stats li small {
  margin-left: 6px;
  font-size: 12px;
  font-weight: normal;
  opacity: 0.9;
}

/* ---------- 真ん中の「VS」 ---------- */
.vs-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
}

.vs-mark {
  font-size: 76px;
  line-height: 1;
  font-style: italic;
  color: var(--color-gold);
  -webkit-text-stroke: 3px #5a3b00;
  text-shadow: 0 5px 0 rgba(0, 0, 0, 0.35);
  opacity: 0;
  transform: scale(0);
}

.vs-mark.vs-round {
  font-size: 54px;
  font-style: normal;
}

.vs-note,
.vs-names {
  max-width: 100%;
  padding: 2px 14px;
  border-radius: var(--radius-round);
  background: rgba(255, 255, 255, 0.92);
  color: var(--color-text-dark);
  font-size: 14px;
  font-weight: bold;
  overflow-wrap: anywhere;
  opacity: 0;
}

.vs-names {
  background: transparent;
  color: #fff;
  font-size: 16px;
}

/* 2戦目の短い VS：名前の途中では改行しない（「〇〇 vs △△」の vs のところで改行する） */
.vs-names em {
  font-style: normal;
  white-space: nowrap;
}

.vs-name-me {
  color: #8ec0ff;
}

.vs-name-them {
  color: #ff9aa8;
}

/* ---------- 動き ---------- */
/* すべり込む（勢いよく入って、少し行きすぎてから止まる） */
#vs-intro.show .vs-them {
  animation: vs-in-them var(--vs-slide) cubic-bezier(0.2, 0.9, 0.3, 1) forwards;
}

#vs-intro.show .vs-me {
  animation: vs-in-me var(--vs-slide) cubic-bezier(0.2, 0.9, 0.3, 1) forwards;
}

@keyframes vs-in-them {
  0% { opacity: 1; transform: translate(120%, -180%) rotate(8deg); }
  70% { opacity: 1; transform: translate(-5%, 8%) rotate(-2deg); }
  100% { opacity: 1; transform: translate(0, 0) rotate(0); }
}

@keyframes vs-in-me {
  0% { opacity: 1; transform: translate(-120%, 180%) rotate(8deg); }
  70% { opacity: 1; transform: translate(5%, -8%) rotate(-2deg); }
  100% { opacity: 1; transform: translate(0, 0) rotate(0); }
}

/* VS が弾む・画面が少し揺れる */
#vs-intro.hit .vs-mark {
  animation: vs-pop 0.45s cubic-bezier(0.3, 1.6, 0.5, 1) forwards;
}

#vs-intro.hit .vs-note,
#vs-intro.hit .vs-names {
  animation: vs-fade 0.3s 0.15s ease forwards;
}

#vs-intro.hit .vs-stage {
  animation: vs-shake 0.35s ease-out;
}

@keyframes vs-pop {
  0% { opacity: 0; transform: scale(2.4); }
  55% { opacity: 1; transform: scale(0.85); }
  100% { opacity: 1; transform: scale(1); }
}

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

@keyframes vs-shake {
  0%, 100% { transform: translate(0, 0); }
  20% { transform: translate(-7px, 4px); }
  40% { transform: translate(6px, -5px); }
  60% { transform: translate(-4px, 3px); }
  80% { transform: translate(2px, -1px); }
}

/* 来た方向へ抜けて消える */
#vs-intro.out .vs-them {
  opacity: 1;
  animation: vs-out-them var(--vs-exit) ease-in forwards;
}

#vs-intro.out .vs-me {
  opacity: 1;
  animation: vs-out-me var(--vs-exit) ease-in forwards;
}

#vs-intro.out .vs-center {
  opacity: 0;
  transition: opacity var(--vs-exit) ease;
}

@keyframes vs-out-them {
  from { transform: translate(0, 0); }
  to { transform: translate(120%, -180%); }
}

@keyframes vs-out-me {
  from { transform: translate(0, 0); }
  to { transform: translate(-120%, 180%); }
}

/* 「視差効果を減らす」が ON：すべり込みと揺れをやめて、フェードだけ */
@media (prefers-reduced-motion: reduce) {
  #vs-intro.show .vs-them,
  #vs-intro.show .vs-me {
    animation: vs-fade var(--vs-slide) ease forwards;
  }

  #vs-intro.hit .vs-mark {
    transform: none;
    animation: vs-fade 0.3s ease forwards;
  }

  .vs-mark {
    transform: none;
  }

  #vs-intro.hit .vs-stage {
    animation: none;
  }

  #vs-intro.out .vs-them,
  #vs-intro.out .vs-me {
    animation: vs-fade var(--vs-exit) ease reverse forwards;
  }
}

/* =============================================
   称号を選ぶ画面（#screen-titles）と、プロフィール画面の称号の欄（.title-pick）
   ============================================= */
/* プロフィール画面：今のアイコン＋枠＋称号の札（押すと選ぶ画面へ） */
.title-pick {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  width: 100%;
  min-height: 60px;
  padding: 10px var(--space-m) 8px;
  border: none;
  border-radius: var(--radius-m);
  font-family: inherit;
  color: var(--color-text);
  text-align: left;
  background: var(--color-panel);
  cursor: pointer;
}

.title-pick:active {
  filter: brightness(1.15);
}

.title-pick .player-badge {
  margin-bottom: 0;
  background: none;
  padding: 0;
  min-width: 0;
}

.title-pick-none {
  opacity: 0.7;
  font-size: 12px;
}

.title-pick-go {
  flex-shrink: 0;
  margin-left: auto;
  font-size: 13px;
  font-weight: bold;
  opacity: 0.85;
}

/* 上の見本：大きなアイコン＋枠＋名前＋称号の札 */
.title-preview {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  margin: var(--space-s) 0;
  padding: 20px var(--space-m) var(--space-m);
  border-radius: var(--radius-m);
  background: var(--color-panel);
}

.title-preview-avatar {
  --av: 84px;
  width: 84px;
  height: 84px;
  font-size: 34px;
}

.title-preview-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;
}

.title-preview-text b {
  max-width: 100%;
  overflow: hidden;
  font-size: clamp(16px, calc(min(52vw, 240px) / var(--fit, 1)), var(--font-size-l));
  white-space: nowrap;
  text-overflow: ellipsis;
}

.title-preview-text .title-badge {
  font-size: 14px;
  white-space: normal;
}

.title-preview-text small {
  opacity: 0.7;
}

/* 一覧 */
.title-group small {
  margin-left: var(--space-s);
  font-size: 12px;
  font-weight: normal;
  opacity: 0.75;
}

.title-row {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 64px;
  margin-bottom: var(--space-s);
  padding: 14px var(--space-m) 10px;
  border: 2px solid transparent;
  border-radius: var(--radius-m);
  font-family: inherit;
  color: var(--color-text);
  text-align: left;
  background: var(--color-panel);
}

button.title-row {
  cursor: pointer;
}

button.title-row:active {
  transform: scale(0.98);
}

.title-row.selected {
  border-color: var(--color-gold);
  background: rgba(255, 216, 77, 0.16);
}

.title-row.locked {
  opacity: 0.75;
}

.title-row-main {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  flex: 1;
  min-width: 0;
}

.title-row-main .title-badge {
  font-size: 13px;
  white-space: normal;
}

.title-row-main small {
  font-size: 11px;
  line-height: 1.4;
  opacity: 0.85;
}

.title-none {
  font-size: var(--font-size-m);
}

/* 選んでいる印 */
.title-check {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  color: var(--color-text-dark);
  background: var(--color-gold);
  font-weight: bold;
}

/* 下の「もどる」「これにする」 */
.title-actions {
  display: flex;
  gap: var(--space-s);
}

.title-actions .btn {
  flex: 1;
  min-height: 54px;
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-l);
  font-size: var(--font-size-m);
}

/* =============================================
   ランキングの人のプロフィール（#rank-profile。ranking.js）
   枠・称号の札は、自分のプロフィールと同じ部品（frames.js・「称号の枠」）
   ============================================= */
/* ランキングの行は、タップできるボタン */
button.rank-row {
  width: 100%;
  border: none;
  font-family: inherit;
  color: var(--color-text);
  text-align: left;
  cursor: pointer;
  transition: transform var(--dur-press), filter var(--dur-press);
}

button.rank-row:active {
  transform: scale(0.98);
  filter: brightness(1.12);
}

/* ポップアップ：枠の色が見やすいよう、暗い下地にする */
.dialog-box.rank-profile-box {
  max-width: 340px;
  color: var(--color-text);
  background: linear-gradient(160deg, #3a4d70, #24324b);
  text-align: left;
}

/* 中身が長いときは、ポップアップの中でスクロール */
#rank-profile-content {
  max-height: calc(100dvh - 200px);
  overflow-y: auto;
}

.rp-head {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  padding-top: 10px; /* 枠のてっぺんの星の分 */
}

.rp-avatar {
  --av: 84px;
  width: 84px;
  height: 84px;
  font-size: 34px;
}

.rp-who {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;
}

/* 名前は、長い名前のときだけ小さくして1行に収める（--fit は名前の長さ。ranking.js の UI.fit）。
   開発者などの札・「あなた」は、入らなければ下の行へ */
.rp-who b {
  max-width: 100%;
  font-size: clamp(14px, calc(min(43vw, 170px) / var(--fit, 1)), var(--font-size-l));
  line-height: 1.25;
}

.rp-name {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  vertical-align: bottom;
}

.rp-who .title-badge {
  font-size: 13px;
  white-space: normal;
}

.rp-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-s);
  margin-top: var(--space-m);
}

.rp-stat {
  padding: 8px 12px;
  border-radius: var(--radius-m);
  background: rgba(255, 255, 255, 0.1);
}

.rp-stat span {
  display: block;
  font-size: 12px;
  opacity: 0.8;
}

.rp-stat b {
  font-size: 20px;
  color: var(--color-gold);
}

.rp-stat small {
  margin-left: 2px;
  font-size: 12px;
}

/* 公開しているプロフィール */
.rp-section {
  margin: var(--space-m) 0 0;
  font-size: 13px;
  font-weight: bold;
  opacity: 0.85;
}

.rp-themes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-s);
  margin-top: var(--space-s);
}

.rp-theme img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-s);
}

.rp-theme small {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  opacity: 0.85;
  overflow-wrap: anywhere;
}

/* ランキングに参加していないときの「プロフィールを公開」（選べない） */
.setting-row.disabled {
  opacity: 0.5;
}

/* 記録した日：横いっぱいに（日付が折り返さないように） */
.rp-stat.wide {
  grid-column: 1 / -1;
}

.rp-stat.wide b {
  font-size: 17px;
}

/* =============================================
   パソコン（マウス・キーボード・横長の画面）
   パソコン向けにするかは、機種名ではなく、画面の幅と (hover: hover) and (pointer: fine) で決める。
   スマホ（指で操作する機器）には、ここのレイアウトは効かない（ヒントの見た目・選んでいる枠だけは共通）
   ============================================= */

/* キーボードで選んでいるボタンがわかる枠（Tab で選んだときだけ。指やマウスで押したときは出ない） */
.btn:focus-visible,
.menu-icon:focus-visible,
.list-row:focus-visible,
.profile-chip:focus-visible,
.toggle:focus-visible,
.ranking-tab:focus-visible,
.theme-tile:focus-visible,
.title-row:focus-visible,
.dex-card:focus-visible,
button:focus-visible {
  outline: 3px solid var(--color-gold);
  outline-offset: 3px;
}

/* キーの名前（設定画面の「操作方法」・ヒント・右のパネル） */
kbd {
  display: inline-block;
  min-width: 1.6em;
  padding: 1px 7px;
  border-radius: 6px;
  color: var(--color-text-dark);
  background: #fff;
  box-shadow: 0 2px 0 #b9c4d6;
  font-family: inherit;
  font-size: 12px;
  font-weight: bold;
  text-align: center;
  white-space: nowrap;
}

/* 操作の一覧（設定画面の「操作方法」・横長の画面の右のパネル） */
.controls-help h4,
.side-keys h4 {
  margin: var(--space-s) 0 4px;
  font-size: 13px;
  opacity: 0.85;
}

.control-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.control-list li {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  padding: 4px 0;
  font-size: 13px;
  text-align: left;
}

.control-list kbd {
  flex-shrink: 0;
}

.settings-controls .controls-help {
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-s);
  background: var(--color-panel);
}

/* キーやマウスを初めて使ったときの、操作のヒント（画面の下に少しのあいだ出る。タップは下に通す） */
.control-hint {
  position: absolute;
  left: 50%;
  bottom: calc(110px + var(--safe-bottom));
  z-index: 40;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 14px;
  width: max-content;
  max-width: 92%;
  padding: 8px 14px;
  border-radius: var(--radius-m);
  font-size: 13px;
  font-weight: bold;
  background: rgba(20, 30, 55, 0.82);
  opacity: 0;
  transform: translate(-50%, 8px);
  transition: opacity 0.3s, transform 0.3s;
  pointer-events: none;
}

.control-hint.show {
  opacity: 1;
  transform: translate(-50%, 0);
}

.control-hint span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* 横長の画面の左右のパネル（ふだんは出さない） */
.side-panel {
  display: none;
}

/* ---------- タブレット（幅が中くらい）：今の縦長の表示を、少し大きくする ----------
   ゲームの場は game.js が「画面の高さ × 9/16」までにするので、広がった分は左右の背景になる（ゲームの条件は同じ） */
@media (min-width: 700px) and (max-width: 1023.98px) {
  #app {
    max-width: calc(100vh * 2 / 3);
    max-width: calc(100dvh * 2 / 3);
  }
}

/* ---------- パソコンの横長の画面 ----------
   幅 1024px 以上・横長・マウスなど細かく指せる機器（(hover: hover) and (pointer: fine)）のとき：
   ・背景（空・雲・地面）を画面いっぱいに広げる。ゲームの場は真ん中（幅 --field-w。game.js と同じ「高さ × 9/16」）
   ・場の左右にパネル（左：スコアなど／右：手番・制限時間・操作の一覧）。上の表示（hud）と下の操作ボタンは出さない
   ・メニューの画面は、最大の幅を決めて真ん中に。一覧の画面（図鑑・ランキング・実績など）は、列を増やす */
@media (min-width: 1024px) and (orientation: landscape) and (hover: hover) and (pointer: fine) {
  #app {
    max-width: none;
    box-shadow: none;
    /* ゲームの場の幅と、場の左右の余白（どちらも #app の幅に対する値） */
    --field-w: min(100%, calc(100dvh * 9 / 16));
    --side: calc((100% - var(--field-w)) / 2);
  }

  /* ゲームの場の上に重ねるものは、場の幅に合わせる */
  #hud,
  #turn-banner,
  #rematch-banner,
  #rare-banner,
  #toasts,
  #stamp-bar,
  #vs-intro,
  #sandbox-ui,
  #screen-title,
  .control-hint {
    left: var(--side);
    right: var(--side);
  }

  .control-hint {
    right: auto;
    left: 50%;
    bottom: calc(40px + var(--safe-bottom));
  }

  .cpu-thinking {
    left: 50%;
  }

  /* 上の表示（スコア・手番）と下の操作ボタンは、パネルとマウス・キーで操作できるので出さない（ポーズボタンは残す） */
  #hud-info,
  #controls {
    display: none;
  }

  #hud {
    justify-content: flex-end;
  }

  /* 左右のパネル */
  .side-panel {
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: 5;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--space-m);
    width: var(--side);
    padding: var(--space-xl) var(--space-l);
  }

  /* .game-ui の left: 0・right: 0 を、片側だけにする */
  .side-left {
    left: 0;
    right: auto;
    align-items: flex-end;
  }

  .side-right {
    left: auto;
    right: 0;
    align-items: flex-start;
  }

  .side-panel > div:empty {
    display: none;
  }

  .side-left #side-left-body,
  .side-turn,
  .side-timer,
  .side-keys {
    width: 100%;
    max-width: 300px;
    padding: var(--space-m) var(--space-l);
    border-radius: var(--radius-l);
    background: rgba(20, 30, 55, 0.55);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  }

  .side-item {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-m);
    padding: 6px 0;
    font-size: 15px;
  }

  .side-item + .side-item {
    border-top: 1px solid rgba(255, 255, 255, 0.15);
  }

  .side-item b {
    font-size: 24px;
  }

  .side-item b small {
    margin-left: 2px;
    font-size: 13px;
  }

  .side-item.side-score b {
    font-size: 44px;
    color: var(--color-gold);
  }

  .side-rule {
    margin-bottom: var(--space-s);
  }

  .side-note {
    margin: var(--space-s) 0 0;
    font-size: 13px;
  }

  .side-player {
    padding: 8px 12px;
    border-radius: var(--radius-m);
    font-size: 17px;
    font-weight: bold;
    opacity: 0.55;
  }

  .side-player small {
    margin-left: 6px;
    font-size: 12px;
  }

  .side-player.now {
    opacity: 1;
  }

  .side-player.p1.now {
    background: var(--color-p1);
  }

  .side-player.p2.now {
    background: var(--color-p2);
  }

  .side-player + .side-player {
    margin-top: 6px;
  }

  .side-timer {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    font-size: 15px;
  }

  .side-timer b {
    font-size: 36px;
  }

  .side-timer b.hurry {
    color: #ff8a8a;
  }

  .side-keys .control-list li {
    font-size: 13px;
  }

  /* メニューの画面：最大の幅を決めて真ん中に。文字とボタンを少し大きく */
  .screen-inner {
    max-width: 400px;
    zoom: 1.12;
  }

  .page-inner {
    max-width: 640px;
  }

  .screen.page .page-body {
    font-size: 17px;
  }

  /* 一覧の画面は、広さを活かして列を増やす */
  #screen-dex .page-inner,
  #screen-ranking .page-inner,
  #screen-achievements .page-inner,
  #screen-records .page-inner,
  #screen-titles .page-inner,
  #screen-profile .page-inner {
    max-width: 980px;
  }

  .dex-grid {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }

  #achievements-list,
  #title-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--space-m);
    align-content: start;
  }

  #achievements-list > :not(.ach-row),
  #title-list > :not(.title-row) {
    grid-column: 1 / -1;
  }

  /* フリー・競技のタブは、一覧と同じ幅 */
  .ranking-tabs {
    width: 100%;
    margin-left: 0;
    margin-right: 0;
  }

  /* ランキング：1列で、1人分の行を表のように横に並べる（見出しの行と、列の幅をそろえる）
     順位 | アイコン | 名前・称号 | スコア | 積んだ数 | 高さ | 記録した日 */
  .rank-row,
  .rank-head {
    display: grid;
    grid-template-columns: 44px 52px minmax(0, 1fr) 130px 84px 90px 92px;
    align-items: center;
    column-gap: var(--space-m);
    width: 100%;
  }

  .rank-row {
    padding-left: var(--space-l);
    padding-right: var(--space-l);
    text-align: left;
  }

  .rank-head {
    padding: 0 var(--space-l) 6px;
    font-size: 12px;
    font-weight: bold;
    opacity: 0.75;
  }

  /* 数字の列（スコア・積んだ数・高さ・記録した日）は右にそろえる */
  .rank-head span:nth-child(n + 4),
  .rank-col {
    text-align: right;
  }

  .rank-col {
    display: block;
    font-size: 16px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }

  .rank-col-date {
    font-size: 14px;
    opacity: 0.8;
  }

  .rank-score {
    font-variant-numeric: tabular-nums;
  }

  /* 名前の下の「積んだ数・高さ・日付」の1行は、列に出すので隠す。名前・称号は長ければ「…」で省略 */
  .rank-main small {
    display: none;
  }

  .rank-main .title-badge {
    max-width: 100%;
  }

  .rank-num {
    justify-self: center;
  }
}
