:root {
  color-scheme: dark;
  --felt: #0b5d3b;
  --felt-dark: #063f28;
  --gold: #e8c46b;
  --panel: rgba(10, 20, 15, 0.82);
  --text: #f3ead9;
}

* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0; height: 100%;
  background: #05130d;
  color: var(--text);
  font-family: "Hiragino Sans", "Yu Gothic", "Meiryo", system-ui, sans-serif;
  overflow: hidden;
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none;
  /* タップしたときに出る四角い灰色の点滅を消す */
  -webkit-tap-highlight-color: transparent;
  /* 素早く2回さわったときの拡大をやめる。牌を続けて押すと勝手に拡大していた */
  touch-action: manipulation;
}
/* 子要素にも確実に効かせる(iOSは要素ごとに見るため、body だけだと漏れる)。
   touch-action は受け継がれないので、ここでも指定する */
*, *::before, *::after {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  touch-action: manipulation;
}
img, svg, canvas { -webkit-user-drag: none; user-drag: none; }
/* 選択の帯そのものを透明にする(選べてしまった場合の保険) */
::selection { background: transparent; }
::-moz-selection { background: transparent; }
/* 文字を入れる欄だけは、選択もコピーもできないと困る */
input, textarea {
  user-select: text; -webkit-user-select: text;
  -webkit-touch-callout: default; touch-action: auto;
}
input::selection, textarea::selection { background: rgba(232,196,107,.45); }

.hidden { display: none !important; }

/* 強制横画面。幅/高さは ui.js が visualViewport の実測値でインラインに指定する
   (iOS Safari の 100vh はツールバーが隠れた時の高さなので、CSSで 100vh のままだと
    回転後の横幅が実際の表示幅を超え、右端が画面外に切れてしまう)。
   保険として 100vh/100vw をフォールバックに残す。 */
/* ============ ノッチ(カメラ)を避ける ============
   iPhoneを横に持つと、カメラのある側に隠れる帯ができる。
   全画面の画面はその帯を避けないと、左端の品や文字が読めなくなる。

   端末を横にして遊んでもらうので、端の向きは端末のまま使う。 */
:root {
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
}



/* ---------- 掛け声フラッシュ・和了演出 ---------- */
#callFlash {
  position: fixed; top: 38%; left: 50%; z-index: 40;
  height: max(64px, calc(var(--u, 23px) * 5)); width: auto;
  pointer-events: none;
}
#callFlash:not(.hidden) {
  animation: callFlashText 900ms ease-out forwards;
  filter: drop-shadow(0 0 18px rgba(232,196,107,.85)) drop-shadow(0 4px 10px rgba(0,0,0,.6));
}
#callFlash.riichi:not(.hidden) {
  filter: hue-rotate(-48deg) saturate(1.35) drop-shadow(0 0 20px rgba(255,95,109,.85)) drop-shadow(0 4px 10px rgba(0,0,0,.6));
}
@keyframes callFlashText {
  0% { transform: translate(-50%, -50%) scale(.4) rotate(-8deg); opacity: 0; }
  18% { transform: translate(-50%, -50%) scale(1.18) rotate(2deg); opacity: 1; }
  32% { transform: translate(-50%, -50%) scale(1) rotate(0deg); opacity: 1; }
  78% { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.04); }
}

#fxLayer { position: fixed; inset: 0; pointer-events: none; z-index: 70; overflow: hidden; }
.winFlashPulse {
  position: absolute; inset: 0;
  background: radial-gradient(circle, rgba(255,255,255,.85), rgba(232,196,107,.35) 42%, transparent 72%);
  animation: flashPulse 750ms ease-out forwards;
}
@keyframes flashPulse { 0% { opacity: 0; } 14% { opacity: 1; } 100% { opacity: 0; } }
.confettiBit {
  position: absolute; top: -24px; height: auto; pointer-events: none;
  filter: drop-shadow(0 1px 3px rgba(0,0,0,.4));
  animation-name: confettiFall; animation-timing-function: linear; animation-fill-mode: forwards;
}
@keyframes confettiFall {
  0% { transform: translateY(0) rotate(0deg); opacity: 1; }
  100% { transform: translateY(112vh) rotate(var(--spin, 720deg)); opacity: .85; }
}
/* タイトル画面でゆっくり舞う金箔(和了時の派手な紙吹雪とは別に、控えめに漂わせる) */
.titleEmber {
  position: absolute; top: -24px; height: auto; pointer-events: none; opacity: 0;
  filter: drop-shadow(0 0 4px rgba(255,215,110,.5));
  animation-name: titleEmberFall; animation-timing-function: linear; animation-fill-mode: forwards;
}
@keyframes titleEmberFall {
  0% { transform: translateY(0) translateX(0) rotate(0deg); opacity: 0; }
  10% { opacity: .5; }
  50% { transform: translateY(56vh) translateX(24px) rotate(var(--spin, 360deg)); }
  90% { opacity: .45; }
  100% { transform: translateY(112vh) translateX(-18px) rotate(0deg); opacity: 0; }
}

#title {
  height: 100%;
  display: flex; flex-direction: column; align-items: center;
  /* safe center: 中身が入りきらないときは中央寄せをやめて上端から並べる。
     ふつうの center のままだと、あふれた分が画面の外(上と下)に出て、
     下にあるものに指が届かなくなる（2026-10-08） */
  justify-content: safe center;
  background: #05130d url('../img/title_bg.jpg') center / cover no-repeat;
  text-align: center;
  gap: 8px;
  padding: 8px 16px calc(8px + env(safe-area-inset-bottom));
  /* 万一それでも入りきらないときは、最後の手段として動かせるようにしておく */
  overflow-y: auto;
  overflow-x: hidden;
}
/* 「前回の対局を再開」が出ている日は、ボタンが1つ増えるぶん絵を小さくして場所を作る。
   これが無いと、いちばん下(なまえの札)が画面の外に出る */
#title.hasResume #titleArt { max-height: 104px; }
/* 背の低い画面で再開ボタンが出る日は、絵をしまって場所を作る。
   小さくするだけでは足りず、いちばん下のなまえの札が画面の外に出てしまう */
@media (max-height: 470px) {
  #title.hasResume #titleArt { display: none; }
  #title.hasResume { gap: 5px; }
}
@media (max-height: 340px) {
  #title.hasResume #titleMenu { gap: 2px; }
  #title.hasResume .cmdBtn { padding: 2px 8px; }
}
#titleArt {
  width: auto;
  max-width: 92%;
  /* 背の低い画面ほど絵を控える。150px固定だと、縦430pxの端末で品書きが入りきらない */
  max-height: min(150px, 22vh);
  height: auto;
  border-radius: 10px;
  box-shadow: 0 10px 40px rgba(0,0,0,.6);
  flex: 0 0 auto;
}
#title .titleNote { font-size: .78em; opacity: .55; }
#title .galleryLink { flex-basis: 100%; text-align: center; font-size: max(11px, 1.5vh); color: #efe7d4; opacity: .55; text-decoration: none; letter-spacing: .04em; }
#title .galleryLink:hover, #title .galleryLink:active { opacity: .95; }
#titleButtonRow { display: flex; gap: 10px; width: 100%; max-width: 520px; }
#titleButtonRow .bigbtn { flex: 1 1 0; min-width: 0; font-size: .92em; padding: 10px 12px; }

/* 見た目選択・対戦相手選択:
   「キャラ画像そのものがカード」で、名前と★は画像の上に重ねる(デザイン優先・画像を最大化)。
   カードは横一列に flex:1 で並べ、高さは箱いっぱい。これで固定pxやJSの寸法計算に頼らず、
   どんな画面サイズでも「はみ出さない・スクロールしない・余白を使い切る」が同時に成立する。 */
#foeSelectPanel, #myAvatarPanel {
  position: fixed; inset: 0; background: rgba(3,8,5,.97);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; z-index: 65; overflow: hidden;
  padding: var(--safe-t) var(--safe-r) var(--safe-b) var(--safe-l);
  box-sizing: border-box;
  /* 回転していない時、position:fixed は body の余白を無視してビューポート基準になるため、
     パネル自身にもノッチ分の余白(ui.jsが軸を読み替えてセットした --safe-*)を持たせる。
     回転中は body の padding 側で確保済みなので二重に取らない。 */
  padding: calc(4px + var(--safe-t, 0px)) calc(8px + var(--safe-r, 0px)) calc(4px + var(--safe-b, 0px)) calc(8px + var(--safe-l, 0px));
}

.selectHeaderRow { display: flex; align-items: baseline; justify-content: center; gap: 10px; flex: 0 0 auto; }
.selectHeaderRow h2 { color: var(--gold); margin: 0; font-size: 1em; }
#foeSelectHint { font-size: .78em; opacity: .85; margin: 0; }
#foeSelectScroll, #myAvatarScroll {
  flex: 1 1 auto; width: 100%; max-width: 1100px; min-height: 0;
  display: flex; justify-content: center;
}
/* 自分をえらぶ画面は4人だけなので、真ん中にそろえて収める */
#myAvatarScroll { overflow: hidden; align-items: center; }
/* 相手は18人。顔の大きさを優先して、あふれたぶんは縦にスクロールしてもらう */
#foeSelectScroll {
  overflow-y: auto; overflow-x: hidden; align-items: flex-start;
  -webkit-overflow-scrolling: touch;
  /* 下に少し余白を残して、まだ続くことが分かるようにする */
  padding-bottom: 4px;
}
#foeGrid { align-content: start; }
/* キャラ画像は正方形(300x300)なので、カードも正方形にして object-fit:cover でも一切切り取られないようにする。
   1辺のpx(--card)は ui.js が「箱に収まる最大の正方形」を実測して入れる。 */
#foeGrid {
  /* 列数は ui.js が --cols に入れる(人数が増えても顔が潰れないように) */
  display: grid; grid-template-columns: repeat(var(--cols, 3), auto); gap: 6px;
  justify-content: center; align-content: center;
}
/* 見た目は「なし」＋3人の4枚だったが、第2部を突破すると7枚に増える（2026-10-16）。
   横1列のまま(nowrap)だと、増えたぶんが画面の外へ押し出されて端の札が切れる。
   相手の画面と同じく、列数は ui.js が --cols に入れる */
#myAvatarGrid {
  display: grid; grid-template-columns: repeat(var(--cols, 4), auto); gap: 6px;
  justify-content: center; align-content: center;
}
.foeSelectCard {
  position: relative; overflow: hidden; flex: 0 0 auto;
  width: var(--card, 110px); height: var(--card, 110px);
  border-radius: 10px; border: 2px solid rgba(232,196,107,.3);
  background: rgba(255,255,255,.04); cursor: pointer;
  transition: border-color .15s, box-shadow .15s;
}
.foeSelectCard img { width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; }
.foeSelectCard.selected { border-color: var(--gold); box-shadow: 0 0 0 2px var(--gold), 0 0 18px rgba(232,196,107,.55); }
/* 選択済みが一目で分かるチェック印 */
.foeSelectCard.selected::after {
  content: '✓'; position: absolute; top: 4px; right: 4px;
  width: 1.5em; height: 1.5em; border-radius: 50%;
  background: var(--gold); color: #2b1d05; font-weight: 700; font-size: .9em;
  display: flex; align-items: center; justify-content: center;
}
/* 名前と★は画像下部にグラデーションを敷いて重ねる */
.cardLabel {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 14px 3px 3px;
  background: linear-gradient(to top, rgba(0,0,0,.92), rgba(0,0,0,.6) 55%, rgba(0,0,0,0));
  display: flex; flex-direction: column; align-items: center; gap: 0; overflow: hidden;
}
.foeSelectName {
  font-size: .8em; font-weight: 700; white-space: nowrap; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 3px #000;
}
.foeSelectStars { font-size: .78em; color: var(--gold); letter-spacing: .03em; text-shadow: 0 1px 3px #000; }
/* 画像が無い「なし」用の代替表示(カード全面) */
.avatarFallback {
  width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;
  font-size: 3em; background: rgba(255,255,255,.06);
}
/* 下部のコマンドは必ず横1列(以前はID指定のcolumnがクラス指定のrowに勝ってしまい、
   横並びにしたつもりが一度も効いていなかった。クラス側で完結させて詳細度の競合を避ける) */
.selectActions { display: flex; flex-direction: row; gap: 8px; width: 100%; max-width: 1100px; flex: 0 0 auto; }
.selectActions .bigbtn { flex: 1 1 0; min-width: 0; padding: 10px 12px; font-size: 1em; }

#lengthChoice { display: flex; gap: 8px; }
.lenBtn {
  padding: 6px 16px; border-radius: 999px; border: 1px solid rgba(232,196,107,.5);
  background: rgba(255,255,255,.06); color: var(--text); font-size: .88em; cursor: pointer;
}
.lenBtn.selected { background: var(--gold); color: #2b1d05; font-weight: 700; border-color: var(--gold); }

.linkbtn {
  background: none; border: none; color: var(--gold); font-size: .9em;
  text-decoration: underline; cursor: pointer; opacity: .9; padding: 4px;
}

.bigbtn {
  font-size: 1.1em;
  padding: 14px 34px;
  border-radius: 999px;
  border: none;
  background: linear-gradient(180deg, var(--gold), #c79a3a);
  color: #2b1d05;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0,0,0,.4);
}
.bigbtn:active { transform: translateY(1px); }
.bigbtn:disabled { opacity: .4; cursor: default; }
.bigbtn.secondary { background: rgba(255,255,255,.08); color: var(--text); box-shadow: none; border: 1px solid rgba(232,196,107,.4); }

/* ---------- 卓のレイアウト ----------
   すべて牌1枚の幅 --u を単位に、卓(#table)の中心からの絶対配置で組む。
   --u は ui.js が画面サイズから計算して #game に設定する(vh/vw は強制横画面の回転で
   軸がズレるため使わない)。捨て牌は各家の正面に1段目を置き外側へ伸ばし、鳴き牌は
   各家から見て右手側の隅に置く、日本の麻雀のオーソドックスな配置。 */
#game {
  --u: 23px;
  height: 100%;
  display: flex;
  flex-direction: column;
}

#table {
  flex: 1 1 auto;
  background: #05100b url('../img/table-bg.jpg') center / cover no-repeat;
  position: relative;
  min-height: 0;
  overflow: hidden;
}

.seatCard { display: flex; align-items: center; gap: 4px; }
/* 左右の名札はアイコンの下に置く。横に並べると狭い画面で名前が先に削られる */
#table .cornerRight .seatCard,
#table .cornerLeft .seatCard {
  flex-direction: column; gap: 1px;
}
/* 対面の名札だけは横並び。縦積みだと背が高く、卓を大きくしたとき
   下家の鳴き牌(カン4組)が上まで伸びてぶつかる。横に並べると高さが半分になる */
#table .seatCard.nameTop { flex-direction: row; gap: 5px; }
/* 名札はアイコンより横に広い。枠の外へあふれる向きを、卓の内側にそろえる
   (狭い画面では下家の枠が50px弱しかなく、中央ぞろえだと卓の外へ出てしまう) */
#table .cornerRight .seatCard { align-items: flex-end; }
#table .cornerLeft .seatCard { align-items: flex-start; }
#table .seatCard.nameTop { align-items: center; }
/* アイコンボタンを下段へ移したので、対面の名札は右端ぎりぎりまで寄せられる */
.seatAvatar {
  width: calc(var(--u) * 1.65); height: calc(var(--u) * 1.65); border-radius: 50%; flex: 0 0 auto;
  background: linear-gradient(180deg, #3c3c3c, #161616);
  border: 2px solid var(--gold);
  display: flex; align-items: center; justify-content: center;
  font-size: .72em; font-weight: 700; color: var(--gold);
}
.seatAvatar.turnOn { border-color: #fff; box-shadow: 0 0 8px 2px rgba(255,215,110,.85); }
/* 相手の顔は小さいと誰か分からないので、自分の名札より大きく出す。
   大きくした分の幅は名札から自風を外して捻出している(renderSeat) */
.seatAvatar.foeAvatar { width: var(--foe-av, calc(var(--u) * 1.65)); height: var(--foe-av, calc(var(--u) * 1.65)); }
.seatAvatar.hasImg { background-size: cover; background-position: center top; }

/* 隅の配置。配牌ストリップ用のレーン(--lane、盤の三辺)には絶対に侵入しないよう、全て内側へ寄せる。
   これにより鳴きが何組増えても配牌の位置・大きさに影響しない。 */
/* 対面の鳴き牌。配牌レーンのすぐ下から始める。ここを下げると、下から積み上がる
   上家の鳴き牌(カン4組)とぶつかる(実測で2px重なっていた) */
.cornerTop {
  position: absolute; top: var(--lane, 34px); left: calc(4px + var(--lane, 34px));
  display: flex; gap: 6px; align-items: flex-start; flex-wrap: wrap;
}
/* 対面の名札は右上、アイコンボタンの手前に置く */
.nameTop { position: absolute; top: 3px; right: calc(8px + var(--lane, 34px)); }
/* 下家の枠はアイコンボタンの下・右レーンの内側。鳴き牌は横方向に並べて縦にあふれないようにする。
   column-reverse にして、鳴き牌を名札より「上」に置く。
   名札が上にあると、そのぶん鳴き牌の開始位置が下へ押し下げられ、
   カンのように背の高い組を出したとき卓の下端ぎりぎり(実測で余白1px)まで届いて
   見切れたように見えていた。上家(cornerLeft)と同じ並べ方にそろえてある。 */
/* 右端に空ける量は下家の配牌レーン(.handStripBoxRight)と必ずそろえること。
   ここが広すぎると、下家だけ鳴き牌が縮んでカンの牌が読めなくなる。 */
/* 上家(.cornerLeft)の左右を反転しただけの形にそろえる。下端で固定し、名札を一番下、
   鳴き牌はその上へ積む。top で固定していたころは、カンのように背の高い組を出すと
   名札が下へ押し出されて卓からはみ出していた。 */
.cornerRight {
  position: absolute; bottom: 6px;
  left: calc(50% + var(--corner-x, 189px)); right: calc(4px + var(--lane, 34px));
  display: flex; flex-direction: column-reverse; align-items: flex-end; gap: 4px;
}
.cornerRight .seatCard { width: 100%; }
#table .cornerRight .seatLabel { max-width: calc(var(--u) * 6.4); flex: 0 0 auto; min-width: 0; }
#table .nameTop .seatLabel { max-width: calc(var(--u) * 6.4); }
.cornerLeft {
  position: absolute; bottom: 6px; left: calc(4px + var(--lane, 34px));
  display: flex; flex-direction: column-reverse; align-items: flex-start; gap: 4px;
}
#table .seatLabel { max-width: calc(var(--u) * 5.2); font-size: .66em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 中央パネル: 点数は四辺(左右は本場の卓と同じくその人の向きに90度回転)、
   真ん中に「局・本場 / 残り枚数 / 供託」を1行、その下にドラ表示と直近の出来事 */
#centerInfo {
  position: absolute; left: 50%; top: calc(50% + var(--tshift, 0px)); transform: translate(-50%, -50%);
  /* 幅は中身(局表示+王牌)に合わせて伸ばす。伸びた実測値を ui.js が読み、左右の河をその外側へ置く */
  width: max-content; min-width: var(--center-w, 184px); max-width: 50%;
  height: var(--center-h, 88px);
  box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;
  color: var(--gold);
  font-size: max(9px, calc(var(--u) * .42));
  text-align: center;
  background: rgba(20,16,10,.42);
  border: 1px solid rgba(232,196,107,.45);
  border-radius: 10px;
  padding: 2px calc(var(--u) * .45);
  backdrop-filter: blur(1px);
}
.cp-score {
  position: absolute; font-weight: 700; white-space: nowrap; line-height: 1;
  padding: 1px 6px; border-radius: 8px; background: rgba(255,255,255,.08);
  /* 幅を決め打ちすると、親のときに付く「●」の分だけ字があふれて切れる。
     中身に合わせて伸ばし、4人ぶんの見た目を揃えるために最低幅だけ決めておく */
  min-width: calc(var(--u) * 2.8); box-sizing: border-box; text-align: center;
}
.cp-top { top: 2px; left: 50%; transform: translateX(-50%); }
.cp-bottom { bottom: 2px; left: 50%; transform: translateX(-50%); }
.cp-left { left: calc(var(--u) * -1.05); top: 50%; transform: translateY(-50%) rotate(90deg); }
.cp-right { right: calc(var(--u) * -1.05); top: 50%; transform: translateY(-50%) rotate(-90deg); }
.cp-core { display: flex; flex-direction: row; align-items: center; justify-content: center; gap: calc(var(--u) * .3); min-width: 0; line-height: 1.15; }
/* 局・残り枚数・供託は縦に積む。中央パネルを横に伸ばさずに済み、その分だけ左右の隅に幅を残せる */
.cp-line { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; white-space: nowrap; }
.cp-score.turnOn { background: var(--gold); color: #2b1d05; }
.cp-score.dealerChip::before { content: '●'; color: #ff6b6b; margin-right: 2px; font-size: .62em; vertical-align: middle; }
.cp-round { font-weight: 700; font-size: 1.05em; letter-spacing: .03em; }
.cp-sub { opacity: .85; font-size: .9em; }

/* 供託(リーチ棒)の表示。リーチが1本以上出ている間だけ見せる */
#riichiPot { display: inline-flex; align-items: center; gap: 2px; }
#riichiPot img { width: calc(var(--u) * 1.4); height: auto; filter: drop-shadow(0 1px 2px rgba(0,0,0,.6)); }
#riichiPot span { font-size: .75em; color: var(--gold); font-weight: 700; }

/* 王牌(ドラ表示)を積み牌風に見せる: 各山は裏牌の上にもう1枚が少しずらして乗っている見た目 */
.doraWall {
  display: flex; align-items: flex-end; gap: 2px;
  background: rgba(20,16,10,.2);
  border: 1px solid rgba(232,196,107,.3);
  border-radius: 5px;
  padding: 1px 3px;
  margin-top: 0;
}
.doraStack { position: relative; width: var(--dora-w, 15px); height: calc(var(--dora-h, 23px) + var(--u) * .3); flex: 0 0 auto; }
.doraStack .tile {
  position: absolute; left: 0; width: var(--dora-w, 17px); height: var(--dora-h, 25px);
  border-radius: 2px; box-shadow: 0 1px 2px rgba(0,0,0,.6);
}
.doraStack .tile.stackBottom { bottom: 0; filter: brightness(.72); }
.doraStack .tile.stackTop { bottom: calc(var(--u) * .3); }

/* 卓が大きくなって名札が布の柄の上に乗るようになったので、下地を濃くして読めるようにする
   (薄い .32 のままだと、金の柄に名前が溶けて読めなかった) */
.seatLabel {
  font-size: .72em; opacity: 1; background: rgba(6,14,10,.78);
  padding: 1px 8px; border-radius: 10px; text-shadow: 0 1px 3px rgba(0,0,0,.9);
}
/* あと何枚で和了れるか(シャンテン数)。テンパイなら待ち牌も出す */
/* 手の進み具合の「表示」。操作ボタン(金色の角丸)と同じ見た目にすると、
   「リーチ 5索」がリーチ宣言ボタンに見えてしまう(実際に誤解された)。
   ・角丸を小さく、左端だけ色の帯 → ボタンではなく計器の表示に見せる
   ・光らせない、押せない(pointer-events:none) */
#shantenView {
  font-size: .72em; font-weight: 600; white-space: nowrap;
  padding: 2px 8px; border-radius: 3px;
  /* 文が長いときは枠の中で切る。flex:0 0 auto のままだと縮まず、
     狭い画面で名札の枠からあふれて画面の外まで出ていた */
  flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  background: rgba(12,10,6,.55); border: none; border-left: 3px solid rgba(255,255,255,.3);
  color: #cfc7b8;
  pointer-events: none; user-select: none; -webkit-user-select: none;
}
#shantenView.shantenFar { color: #cfc7b8; }
#shantenView.shantenTenpai { color: #ffe9a8; border-left-color: var(--gold); }
#shantenView.shantenWin { color: #ffb0b0; border-left-color: #ff6b6b; }
.seatLabel.turnOn { background: var(--gold); color: #2b1d05; font-weight: 700; }
.seatLabel.riichiOn::after { content: ' 立'; color: #ff6b6b; font-weight: 800; }

/* 捨て牌(河): 6枚ごとに1段、3段目は横に伸びる(4段目は作らない、本場の並べ方)。 */
.river { width: calc(var(--river-w, 21px) * 6 + 5px); }
.river .tile { width: var(--river-w, 21px); height: var(--river-h, 32px); }
.river .tile.riichiTile { margin: 0 calc((var(--river-h, 32px) - var(--river-w, 21px)) / 2); }
.riverLine { display: flex; gap: 1px; height: var(--river-h, 29px); margin-bottom: 1px; align-items: flex-end; }
.riverBottom { position: absolute; left: 50%; top: calc(50% + var(--tshift, 0px) + var(--river-voff, 48px)); transform: translateX(-50%); }
/* 対面: 180度回転すると1段目(回転前の上端)が中央寄りになり、段が増えると上へ伸びる */
.riverTop { position: absolute; left: 50%; bottom: calc(50% - var(--tshift, 0px) + var(--river-voff, 48px)); transform: translateX(-50%) rotate(180deg); }
/* 左右: 見た目の縦横が入れ替わるので、回転後の大きさの箱を先に置き、その箱の中で
   回転前サイズの河を「角を軸に90度回して押し込む」。1段目が中央寄り・段は外側へ伸びる。 */
.riverWrap { position: absolute; top: calc(50% + var(--tshift, 0px)); transform: translateY(-50%); width: calc(var(--river-h, 32px) * 3 + 3px); height: calc(var(--river-w, 21px) * 6 + 5px); }
.riverLeft { right: calc(50% + var(--river-hoff, 88px)); }
.riverRight { left: calc(50% + var(--river-hoff, 88px)); }
.riverLeft .river { position: absolute; top: 0; right: 0; transform-origin: top right; transform: rotate(90deg) translateX(100%); }
.riverRight .river { position: absolute; top: 0; left: 0; transform-origin: top left; transform: rotate(-90deg) translateX(-100%); }

/* 鳴き牌: 1組ごとの箱(.meldGroup)の中に牌の列(.meldInner)を入れ、席ごとに向きを変える */
.meldRow { display: flex; gap: 3px; flex-wrap: nowrap; align-items: flex-end; }
.meldGroup { display: block; flex: 0 0 auto; }
.meldInner { display: flex; gap: 1px; align-items: flex-end; }
.tile.meldCalled { transform: rotate(90deg); margin: 0 calc((var(--tile-h, 29px) - var(--u)) / 2); }
/* 自分: 手牌の右側に、最初の鳴きが一番右(隅側) */
#meld0 { flex-direction: row-reverse; }
/* 対面: 左上に、最初の鳴きが一番左(隅側)。各組を180度回す */
#meld2 .meldGroup { transform: rotate(180deg); }
/* 左右: 1組=縦長の箱(幅1.7u・高さ4.8u)にして、箱の中で牌の列を90度回す。
   組が増えるときは横方向に並べる(縦に積むと4組で盤の高さを超えてしまうため) */
.meldCol { flex-direction: row-reverse; gap: 2px; align-items: flex-start; }
.meldColLeft { flex-direction: row; }
/* 横向きに倒した1組の枠。牌の実寸から必要な分だけ確保する(決め打ちの係数にしない)。
   幅  = 倒した牌1枚ぶん = --tile-h
   高さ= 中身の牌を横一列に並べたときの長さ:
         ポン/チー(3枚・うち1枚が横向き) → --u*2 + --tile-h + 隙間2px
         暗槓(4枚・横向き無し)            → --u*4 + 隙間3px
         大明槓/加槓(4枚・うち1枚が横向き) → --u*3 + --tile-h + 隙間3px */
.meldCol .meldGroup { position: relative; width: var(--tile-h, 29px); height: calc(var(--u) * 2 + var(--tile-h, 29px) + 2px); }
.meldCol .meldGroup.mgAnkan { height: calc(var(--u) * 4 + 3px); }
.meldCol .meldGroup.mgKan { height: calc(var(--u) * 3 + var(--tile-h, 29px) + 3px); }
.meldColRight .meldInner { position: absolute; top: 0; left: 0; transform-origin: top left; transform: rotate(-90deg) translateX(-100%); }
.meldColLeft .meldInner { position: absolute; top: 0; right: 0; transform-origin: top right; transform: rotate(90deg) translateX(100%); }

/* 牌の寸法は必ず整数px(ui.jsが計算)。calc()で小数倍すると牌ごとに丸めがズレて並びがガタつく */
.tile {
  width: var(--u); height: var(--tile-h, 29px);
  border-radius: 3px;
  box-shadow: 0 1px 3px rgba(0,0,0,.5);
  flex: 0 0 auto;
  overflow: hidden;
  /* 牌画像は角が丸く透明なので、下地に色を敷くと角だけ黒く見える。下地は敷かない */
  background: transparent;
  position: relative;
}
.tile img { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; }
.tile.riichiTile { transform: rotate(90deg); margin: 0 calc((var(--tile-h, 29px) - var(--u)) / 2); }
.tile.kanTile { outline: 2px solid #ffd766; }
/* 赤5は牌の絵そのものが赤いので、まわりに枠は出さない(枠があると盤面がうるさい) */
.tile.akaDora { }

/* 鳴き(ポン・チー・カン)が起きた瞬間、その牌をしばらく光らせる(ui.js が経過時間に応じて box-shadow を直接更新する) */
.tile.meldGlow { border-radius: 5px; }

/* 他家の配牌(裏向き)。現実の卓のように「その人から見て正しい向き」で並べ、和了時だけ表向きの実物大タイルに切り替える。
   対面=180度回転(自分と正対)、下家/上家=90度回転した縦の列(自分の手牌のように横一列を、箱ごと縦に倒して見せる)。
   箱の位置・サイズ(top/height/width と --hst)は、名札・鳴き牌・河と絶対に重ならないよう
   ui.js の layoutHandStrips() が実測して毎回書き込む(固定pxの決め打ちにしない)。 */
.handStrip { display: flex; gap: 1px; pointer-events: none; z-index: 3; }
/* 幅・高さは ui.js が整数pxで入れる(小数だと牌ごとに丸めがズレて大きさがバラバラに見える)。
   黒い縁に見えていた牌の暗い下地と影も、ここでは消して全ての牌を同じ矩形に揃える。 */
.handStrip .tile {
  width: var(--hst, 14px); height: var(--hst-h, 21px);
  border-radius: 1px; box-shadow: none; background: none;
}
.handStripBox { position: absolute; overflow: visible; }
/* 対面: 中央上部で自分と正対する向き(180度) */
.handStripBoxTop .handStrip { transform: rotate(180deg); }
/* 下家(右)・上家(左): 縦長の箱(鳴き牌の縦列と同じ考え方)の中で、横一列の手牌を90度倒して1列に見せる */
/* 右上のアイコンボタンを下段へ移したので、左(.handStripBoxLeft)と同じ 4px まで寄せられる。
   このぶん下家の鳴き牌を置ける幅が40px以上ひろがる */
.handStripBoxRight { right: 4px; }
.handStripBoxLeft { left: 4px; }
.handStripBoxRight .handStrip { position: absolute; top: 0; left: 0; transform-origin: top left; transform: rotate(-90deg) translateX(-100%); }
.handStripBoxLeft .handStrip { position: absolute; top: 0; right: 0; transform-origin: top right; transform: rotate(90deg) translateX(100%); }
/* 和了した席は手牌を表向きの実寸タイルで並べ直す(向きはそのまま、裏向きのときと矩形サイズが違ってよい) */
.handStrip.revealed .tile { width: var(--rev-w, 16px); height: var(--rev-h, 22px); border-radius: 3px; animation: handRevealFlip 380ms ease-out both; }
.handStripBoxTop .handStrip.revealed { max-width: none; overflow: visible; }
@keyframes handRevealFlip {
  0% { transform: rotateY(90deg) scale(.7); opacity: .2; }
  100% { transform: rotateY(0deg) scale(1); opacity: 1; }
}
/* ポン・チー・カン・ロンの判断中、対象になっている捨て牌を光らせる(和了牌の金色と区別できる水色) */
.tile.callTargetMark { animation: callTargetPulse .9s ease-in-out infinite; z-index: 5; }
/* その捨て牌でロンできるときは、ポン/チーの対象(水色)と区別して赤く強く光らせる */
.tile.ronTargetMark { animation: ronTargetPulse .7s ease-in-out infinite; z-index: 6; }
@keyframes ronTargetPulse {
  0%, 100% { box-shadow: 0 0 0 2px #fff, 0 0 12px 4px rgba(255,70,70,.9); transform: translateY(-2px); }
  50% { box-shadow: 0 0 0 3px #fff, 0 0 24px 10px rgba(255,70,70,1); transform: translateY(-4px); }
}
@keyframes callTargetPulse {
  0%, 100% { box-shadow: 0 0 0 2px #fff, 0 0 8px 3px rgba(120,220,255,.85); }
  50% { box-shadow: 0 0 0 3px #fff, 0 0 18px 7px rgba(120,220,255,1); }
}

/* 和了牌そのものをしばらく光らせて、どの牌で和了ったのか一目で分かるようにする */
.tile.winTileMark { animation: winTilePulse 1.1s ease-in-out infinite; }
@keyframes winTilePulse {
  0%, 100% { box-shadow: 0 0 0 2px #fff, 0 0 8px 3px rgba(232,196,107,.8); }
  50% { box-shadow: 0 0 0 3px #fff, 0 0 20px 8px rgba(232,196,107,1); }
}

/* 下段は「手牌の行」と「名札+操作ボタンの行」だけ。ここで余らせた高さは
   そのまま卓の高さになる(卓は flex:1 で残り全部を取る)ので、余白は最小限にする。
   左右の人のカンが卓の下端に押しつけられて見えない、と指摘があったときに詰めた。 */
#bottomArea {
  flex: 0 0 auto;
  position: relative;
  /* 卓と同じ布を敷く。真っ黒な帯が下に残ると、そこだけ画面の外のように見えて
     「卓のまわりに黒い余白がある」と感じられる。卓の続きとして見えるようにする。
     手牌が沈まないよう、布の上に薄い暗幕を重ねている(::before) */
  background: #05100b url('../img/table-bg.jpg') center bottom / cover no-repeat;
  padding: 1px 8px calc(1px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; align-items: center; gap: 0;
}
/* 布の上に薄く暗幕。手牌・名札・ボタンの文字が布の模様に埋もれないようにする。
   子に z-index を付けると下段が重ね合わせの単位になり、中のボタンが
   点数画面(z-index:60)より上に出られなくなる。暗幕側を 0 に下げて避ける */
#bottomArea::before {
  content: ''; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background: linear-gradient(to bottom, rgba(4,12,8,.55), rgba(4,12,8,.78));
}
#bottomArea > * { position: relative; }
/* 名札+持ち時間・操作ボタン・左右対称用の余白を1行に。手牌の行とは別の行なので手牌の幅を削らない */
#bottomRow { position: relative; display: flex; align-items: center; width: 100%; gap: 6px; }
/* 名札は縮めない。縮めると中身が折り返して下段が縦に伸び、卓が小さくなる */
/* 名札はふだんは縮めない(縮むと中身が折り返して下段が縦に伸び、卓が小さくなる)。
   ただし鳴きの選択肢が多くてボタンが入りきらないときだけは、名前を詰めて幅を譲る。
   ボタンが画面外に切れると押せなくなる(カンが押せない、と報告された) */
#bottomRow #nameBottom { flex: 0 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; }
/* 自分の顔は「誰だったか」を思い出すためのものではないので、相手の顔ほど大きくなくてよい。
   この行の高さは顔の大きさで決まり、その高さぶん卓が低くなるので、操作ボタンと同じ高さにそろえる */
#bottomRow #nameBottom .seatAvatar {
  width: calc(var(--u) * 1.35); height: calc(var(--u) * 1.35);
}
#bottomRow #actionBar { flex: 1 1 auto; min-width: 0; }
/* 局が終わって帯を出しているあいだは操作ボタンが無いので、
   その枠に余白を持たせず、帯が中央に寄れるようにする */
#bottomRow.endShown #actionBar { flex: 0 0 auto; }
/* 操作ボタンを中央に見せるための余白。ボタンが幅を必要とするときは縮めて譲る
   (固定幅のままだと鳴きの選択肢が入りきらず折り返して卓が潰れる) */
/* 名札と釣り合いを取るための右の枠。中に牌譜・音・遊び方のボタンを置く。
   ボタンぶんの幅は絶対に譲らない(譲ると画面外へ出て押せなくなる)。
   残りの余白だけが、操作ボタンに幅が要るときに縮む。 */
.bottomSide {
  flex: 0 500 var(--side-w, 0px); width: var(--side-w, 0px);
  /* ボタンぶんの幅だけは絶対に譲らない。
     min-width:0 のままだと、鳴きの選択肢が多い場面でこの枠が幅0まで潰れ、
     中のボタンが操作ボタンの上にはみ出して「スキップが押せない」状態になっていた。
     余っているぶん(名札と釣り合いを取るための余白)だけが縮む。 */
  min-width: max-content;
  display: flex; align-items: center; justify-content: flex-end; gap: 4px;
}
.toolbtn {
  flex: 0 0 auto;
  width: calc(var(--u) * 1.3); height: calc(var(--u) * 1.3);
  background: rgba(255,255,255,.08); border: none; color: #fff;
  border-radius: 50%; font-size: calc(var(--u) * .62); line-height: 1; cursor: pointer;
  padding: 0; display: flex; align-items: center; justify-content: center;
}
.toolbtn:active { background: rgba(255,255,255,.22); }

#handRow {
  position: relative;
  display: flex; align-items: flex-end; justify-content: center;
  gap: 6px; flex-wrap: nowrap;
}
/* リーチ宣言牌を選んでいる最中は、手牌の上に赤い帯を出して必ず気づくようにする。
   (以前はボタンが「リーチ取消」に変わるだけで、気づかないまま牌を押して
   意図せずリーチが成立してしまう事故が起きていた) */
#game.riichiArming #handRow::before {
  content: 'リーチする牌を選んでください';
  position: absolute; left: 50%; bottom: 100%; transform: translateX(-50%);
  margin-bottom: 4px;
  background: rgba(196,32,32,.94); color: #fff; font-weight: 800;
  padding: 3px 14px; border-radius: 999px; white-space: nowrap;
  font-size: .8em; letter-spacing: .04em;
  box-shadow: 0 0 12px rgba(255,80,80,.85);
  z-index: 6; pointer-events: none;
  animation: riichiNoticePulse 1.1s ease-in-out infinite;
}
#game.riichiArmingPicked #handRow::before { content: 'この牌でリーチ！ もう一度タップで確定'; }
@keyframes riichiNoticePulse {
  0%, 100% { box-shadow: 0 0 10px rgba(255,80,80,.7); }
  50% { box-shadow: 0 0 20px rgba(255,80,80,1); }
}
/* 候補の牌も赤で示す(通常の選択の金色と区別する) */
#game.riichiArming #myHand .tile.riichiCandidate { outline: 2px solid #ff6b6b; }

#myHand {
  display: flex; gap: 3px; justify-content: center; flex-wrap: wrap;
}
#myHand .tile {
  width: var(--hand-w, 33px); height: var(--hand-h, 50px); cursor: pointer;
  transition: transform .08s;
}
#myHand .tile:hover { transform: translateY(-4px); }
#myHand .tile.disabled { opacity: .45; cursor: default; }
#myHand .tile.disabled:hover { transform: none; }
#myHand .tile.riichiCandidate { outline: 2px solid var(--gold); }
/* 直前にツモってきた牌は手牌から少し離し、金色に光らせて分かるようにする */
#myHand .tile.drawnTile {
  margin-left: calc(var(--u) * .55);
  box-shadow: 0 0 0 2px #ffe9a8, 0 0 12px 3px rgba(232,196,107,.85);
  animation: drawnPulse 1.4s ease-in-out infinite;
}
@keyframes drawnPulse {
  0%, 100% { box-shadow: 0 0 0 2px #ffe9a8, 0 0 10px 2px rgba(232,196,107,.7); }
  50% { box-shadow: 0 0 0 2px #fff, 0 0 18px 6px rgba(232,196,107,1); }
}
/* 引いてきた牌でそのまま和了れるとき。ただのツモ牌(金)よりはっきり目立たせる */
#myHand .tile.drawnWinTile {
  margin-left: calc(var(--u) * .55);
  animation: drawnWinPulse .8s ease-in-out infinite;
  z-index: 6;
}
@keyframes drawnWinPulse {
  0%, 100% { box-shadow: 0 0 0 3px #fff, 0 0 14px 5px rgba(255,90,60,.9); transform: translateY(-3px); }
  50% { box-shadow: 0 0 0 3px #ffe9a8, 0 0 26px 11px rgba(255,120,60,1); transform: translateY(-6px); }
}
#myHand .tile.selected {
  transform: translateY(-14px);
  box-shadow: 0 0 0 3px #fff, 0 0 14px 2px rgba(232,196,107,.9), 0 8px 10px rgba(0,0,0,.5);
}
#myHand .tile.selected:hover { transform: translateY(-14px); }

#actionBar {
  /* 折り返さない。折り返すと下段が縦に伸びて卓が潰れる(実測で卓が302→216px、
     小さい画面では0pxまで潰れていた)。入りきらない場合だけ横スクロールさせる。
     高さは常に固定で、ボタンの有無で卓の高さが変わらないようにする。 */
  display: flex; justify-content: center; align-items: center;
  /* 高さは「鳴く牌を見せるボタン」で決まる。中の牌が --u*1.26、上下の余白が2pxずつ。
     ここを縮めすぎるとボタンの下が切れる(実測で2px切れていた)。
     1.65u だった頃の余りぶんだけ詰めてあり、そのぶん卓が高くなる */
  height: calc(var(--u) * 1.26 + 6px);
  overflow: hidden;
}
/* 実際にボタンを並べる箱。入りきらないときはこの箱ごと縮めて、必ず全部見えるようにする */
.actionBarInner {
  display: flex; gap: 5px; flex-wrap: nowrap; align-items: center;
  transform-origin: center center;
}
#actionBar button {
  padding: 4px 10px; border-radius: 8px; border: none; font-weight: 700; cursor: pointer;
  background: var(--gold); color: #2b1d05;
  /* 操作欄の高さは牌の大きさ(--u)で決まるのに、文字だけ固定だと
     小さい画面で欄からはみ出す(320pxの横画面では欄29pxに対し文字が27px分を占めていた)。
     文字も --u に連動させて、どの画面でも同じ詰まり具合にする。 */
  font-size: max(11px, calc(var(--u) * 0.6));
  white-space: nowrap; flex: 0 0 auto;
  max-height: 100%;
}
#actionBar button.secondary { background: #444; color: #eee; }
/* ツモ・ロンは見逃すと取り返しがつかない。ほかの選択肢より文字を大きくして目を引かせる。
   操作欄の高さ(--u*1.26+6px)に収まる範囲で大きくすること */
#actionBar button.winBtn {
  /* ほかのボタン(0.6u)より3割大きい。こちらも --u 連動にしないと小さい画面ではみ出す */
  font-size: max(13px, calc(var(--u) * 0.78)); font-weight: 800; letter-spacing: .04em;
  /* 横の余白は広げない。選択肢が多い場面(ロン+カン+ポン+チー2つ+スキップ)で
     操作欄が足りなくなり、全体が縮んで かえって小さくなる */
  padding: 2px 10px;
  /* 押しやすいように、行の高さいっぱいまで伸ばす。
     高さを固定すると、牌の絵が入るチーのボタン(背が高い)より小さくなってしまうので、
     align-self:stretch で「必ずいちばん背の高いボタンと同じ高さ」にする。
     min-height は、ツモだけが出る場面(伸びる相手がいない)の下限。 */
  box-sizing: border-box;
  align-self: stretch;
  min-height: calc(var(--u) * 1.3);
  /* ほかの選択肢はどれも金色なので、和了だけ地を赤・文字を白にして見分けられるようにする。
     「和了は金」という決めごと(カットインの色分け)は枠の金で残す。
     赤はこれ以上明るくしないこと。白文字との明暗差が4.5:1を切って読みにくくなる
     (#e8453f では3.9:1しか無かった)。 */
  background: linear-gradient(180deg, #c93b35, #8f1216);
  color: #fff;
  border: 1px solid var(--gold);
  text-shadow: 0 1px 2px rgba(0,0,0,.6);
  box-shadow: 0 0 10px rgba(255,95,95,.55);
}
#actionBar button.winBtn:active { background: linear-gradient(180deg, #a92f2a, #760e11); }
/* 鳴きの選択肢は「手牌のどの牌を使うか」を牌の絵で見せる。
   赤5と普通の5は同じ数字でもドラの数(=点数)が変わるので、文字だけでは選べない */
#actionBar button.tileBtn {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 7px 2px 6px;
}
.tileBtnLabel { font-weight: 800; }
.tileBtnTiles { display: inline-flex; gap: 2px; align-items: center; }
#actionBar .btnTile {
  width: calc(var(--u, 21px) * .92); height: calc(var(--u, 21px) * 1.26);
  border-radius: 2px; box-shadow: none; flex: 0 0 auto;
}
/* 鳴く牌を選ぶボタンも同じ。絵で見分けられるので枠は付けない */
#actionBar .btnTile.btnTileAka { }

.iconbtn {
  position: absolute; top: 8px; right: 8px;
  background: rgba(0,0,0,.4); border: none; color: #fff;
  width: 34px; height: 34px; border-radius: 50%; font-size: 1.1em; cursor: pointer;
  z-index: 5;
}
.iconbtn.iconbtn2 { top: 48px; }
.iconbtn.iconbtn3 { top: 88px; }

/* 持ち時間タイマー: 自分の番でだけ現れる。名札・鳴き牌・配牌などと絶対に重ならないよう、
   既に検証済みの中央パネル(#centerInfo .cp-core)の中に置く(卓の外に浮かせて重複させない)。 */
#turnTimer {
  display: flex; align-items: center; gap: 5px; margin-left: 6px;
  font-size: .8em; color: var(--gold); white-space: nowrap; line-height: 1.2;
  background: rgba(20,16,10,.32); border-radius: 10px; padding: 2px 8px;
}
#turnFreeCount {
  min-width: 1.6em; height: 1.6em; border-radius: 50%; text-align: center; line-height: 1.6em;
  background: var(--gold); color: #2b1d05; font-weight: 700; font-size: 1em;
}
#turnFreeCount:empty { display: none; }
#timeBankWrap { opacity: .9; }
#timeBankCount { font-weight: 700; margin-left: 2px; }
#turnTimer.urgent { color: #ff6b6b; animation: turnTimerPulse 900ms ease-in-out infinite; }
#turnTimer.urgent #turnFreeCount { background: #ff6b6b; }
@keyframes turnTimerPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .55; }
}

#logPanel {
  position: fixed; inset: 0; background: rgba(0,0,0,.9);
  display: flex; flex-direction: column; align-items: center;
  gap: 12px; z-index: 50;
  padding: calc(20px + var(--safe-t)) calc(20px + var(--safe-r))
           calc(20px + var(--safe-b)) calc(20px + var(--safe-l));
}
#logList {
  flex: 1; width: 100%; max-width: 480px; overflow-y: auto;
  background: rgba(255,255,255,.05); border-radius: 8px; padding: 10px;
  font-size: .82em; line-height: 1.6;
}

#helpPanel, #statsPanel, #onlinePanel {
  position: fixed; inset: 0; background: rgba(3,8,5,.97);
  display: flex; flex-direction: column; align-items: center;
  gap: 12px; z-index: 65;
  padding: calc(18px + var(--safe-t)) calc(18px + var(--safe-r))
           calc(18px + var(--safe-b)) calc(18px + var(--safe-l));
}
#helpScroll, #statsScroll, #onlineScroll {
  flex: 1; width: 100%; max-width: 560px; overflow-y: auto;
  background: rgba(255,255,255,.04); border: 1px solid rgba(232,196,107,.3);
  border-radius: 10px; padding: 16px 18px; text-align: left;
}
#helpScroll h2, #statsScroll h2, #onlineScroll h2 { color: var(--gold); margin: 0 0 8px; font-size: 1.2em; }
#helpScroll h3, #statsScroll h3 { color: var(--gold); margin: 16px 0 6px; font-size: 1em; }
#helpScroll p, #statsScroll p, #onlineScroll p { font-size: .85em; line-height: 1.7; opacity: .92; margin: 0 0 8px; }
#helpScroll .helpNote, #statsScroll .helpNote { font-size: .78em; opacity: .7; }
/* 話題のなかの小見出し。ひとつの話題が長くなったときに切れ目を作る */
#helpScroll .helpH {
  color: var(--gold); font-weight: 800; font-size: .92em;
  margin: 12px 0 4px; padding-top: 8px;
  border-top: 1px solid rgba(232,196,107,.22);
}

#onlineScroll { display: flex; flex-direction: column; align-items: stretch; gap: 10px; text-align: center; }
#onlineNameLabel { display: flex; flex-direction: column; gap: 4px; font-size: .85em; opacity: .9; }
#onlineName, #onlineRoomInput {
  padding: 9px 12px; border-radius: 8px; border: 1px solid rgba(232,196,107,.4);
  background: rgba(255,255,255,.06); color: var(--text); font-size: 1em; text-align: center;
}
#onlineRoomInput { text-transform: uppercase; letter-spacing: .12em; width: 130px; }
#onlineChoiceRow { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-top: 4px; }
.onlineOr { font-size: .8em; opacity: .6; }
#onlineJoinRow { display: flex; gap: 8px; align-items: center; justify-content: center; }
#onlineStatus { font-size: .88em; min-height: 1.4em; opacity: .9; }
#onlineRoomCode {
  font-size: 1.8em; font-weight: 700; letter-spacing: .18em; color: var(--gold);
  text-shadow: 0 0 12px rgba(232,196,107,.6);
}
.yakuTable { width: 100%; border-collapse: collapse; font-size: .84em; }
.yakuTable td { padding: 4px 6px; border-bottom: 1px solid rgba(255,255,255,.08); }
.yakuTable td:last-child { text-align: right; color: var(--gold); white-space: nowrap; }
/* 成績は項目が多い。横画面では横幅が余っているので2列に流して、
   背の低い端末でもスクロールせずに一覧できるようにする */
/* table の中身は自動で tbody に入るので、格子にするのは tbody のほう */
/* 成績は2列に流すので、ほかの画面より広げる */
#statsScroll { max-width: 760px; }
#statsTable { display: block; }
#statsTable tbody {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 18px;
}
#statsTable tr { display: flex; justify-content: space-between; gap: 10px; }
#statsTable td { border-bottom: 1px solid rgba(255,255,255,.08); flex: 0 1 auto; }
#statsTable td:first-child { white-space: nowrap; }
#statsTable td:last-child { flex: 1 1 auto; }
/* 1列ぶんの幅しか無い狭い画面では1列に戻す */
@media (max-width: 560px) {
  #statsTable tbody { grid-template-columns: 1fr; }
}

.titleLinks { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; justify-content: center; }

#rankCard {
  text-align: center; margin-bottom: 14px; padding: 12px;
  background: rgba(232,196,107,.08); border: 1px solid rgba(232,196,107,.35); border-radius: 10px;
}
#rankName { font-size: 1.5em; font-weight: 700; color: var(--gold); }
#rankBarOuter {
  margin: 8px auto 4px; width: 100%; max-width: 320px; height: 10px;
  background: rgba(255,255,255,.1); border-radius: 6px; overflow: hidden;
}
#rankBarInner { height: 100%; background: linear-gradient(90deg, #c79a3a, var(--gold)); width: 0%; }
#rankNext { font-size: .78em; opacity: .8; }

#resultOverlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.75);
  display: flex; align-items: center; justify-content: center; z-index: 60;
  padding: calc(8px + var(--safe-t)) calc(8px + var(--safe-r))
           calc(8px + var(--safe-b)) calc(8px + var(--safe-l));
}
#resultBox {
  position: relative; z-index: 1;
  background: linear-gradient(180deg, #123a26, #08201a);
  border: 1px solid var(--gold);
  border-radius: 12px;
  padding: 12px 18px;
  /* 役と点数を横に並べるぶん広げる。横は余っていたので、縦に伸びるより収まりがよい */
  max-width: 620px; width: 100%;
  max-height: 100%;
  display: flex; flex-direction: column;
  text-align: center;
  box-shadow: 0 0 0 rgba(232,196,107,0);
  animation: resultPop 420ms cubic-bezier(.2,1.4,.4,1) both, resultGlow 1.8s ease-in-out .3s infinite;
}
/* 役満達成時だけ結果ボックスの背後に金龍を出す(演出用、通常和了では非表示) */
#yakumanBurst {
  position: absolute; top: 50%; left: 50%; z-index: 0;
  width: min(88vw, 620px); height: auto;
  pointer-events: none;
  animation: yakumanBurstIn 1.3s cubic-bezier(.2,1.3,.35,1) both;
}
@keyframes yakumanBurstIn {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(.4) rotate(-12deg); }
  55% { opacity: 1; transform: translate(-50%, -50%) scale(1.08) rotate(3deg); }
  100% { opacity: .92; transform: translate(-50%, -50%) scale(1) rotate(0deg); }
}
/* 総合1位で終えた時だけ最終結果の背後に鳳凰を出す */
#victoryBurst {
  position: absolute; top: 50%; left: 50%; z-index: 0;
  width: min(92vw, 680px); height: auto;
  pointer-events: none;
  animation: yakumanBurstIn 1.3s cubic-bezier(.2,1.3,.35,1) both;
}

/* CPUがリーチ/和了した瞬間に顔を大きく出すカットイン */
#cutin {
  /* 下端を画面の34%に置く。中央パネルの上端はどの画面でもほぼ35%なので、
     ここに収めておけば局・残り枚数・ドラを隠さない。
     top で置いていた頃は、卓を大きくして中央パネルが伸びたときに重なった。 */
  position: fixed; bottom: 66%; right: 0; z-index: 40;
  display: flex; align-items: center; gap: 12px;
  background: linear-gradient(90deg, rgba(10,10,10,0), rgba(8,8,8,.92) 35%);
  padding: 10px 20px 10px 46px;
  border-top: 2px solid var(--gold); border-bottom: 2px solid var(--gold);
  transform: translateX(100%);
  transition: transform .35s cubic-bezier(.2,1,.3,1);
  pointer-events: none;
}
#cutin.show { transform: translateX(0); }
#cutin.cutinRiichi { border-color: #ff6b6b; }
#cutinImg {
  /* 画面の高さに合わせて大きくする。小さい端末でも卓を潰さない範囲で最大に */
  width: clamp(72px, calc(var(--u, 21px) * 5.2), 128px);
  height: clamp(72px, calc(var(--u, 21px) * 5.2), 128px);
  border-radius: 50%; object-fit: cover; object-position: center top;
  border: 3px solid var(--gold); box-shadow: 0 0 20px rgba(232,196,107,.75);
  flex: 0 0 auto;
}
/* ポン・チー・カンのカットインは青系にして、和了(金)・リーチ(赤)と一目で区別できるようにする */
#cutin.cutinCall { border-color: #7fd4ff; }
#cutin.cutinCall #cutinImg { border-color: #7fd4ff; box-shadow: 0 0 20px rgba(127,212,255,.7); }
#cutin.cutinCall #cutinAction { color: #7fd4ff; text-shadow: 0 0 10px rgba(127,212,255,.8); }
#cutin.cutinRiichi #cutinImg { border-color: #ff6b6b; box-shadow: 0 0 14px rgba(255,107,107,.6); }
#cutinText { text-align: right; }
#cutinName { font-size: .78em; opacity: .85; }
#cutinAction { font-size: 1.9em; font-weight: 800; color: var(--gold); text-shadow: 0 0 10px rgba(232,196,107,.8); white-space: nowrap; }
#cutin.cutinRiichi #cutinAction { color: #ff6b6b; text-shadow: 0 0 10px rgba(255,107,107,.8); }
@keyframes resultPop {
  0% { transform: scale(.7); opacity: 0; }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes resultGlow {
  0%, 100% { box-shadow: 0 0 18px rgba(232,196,107,.25); }
  50% { box-shadow: 0 0 32px rgba(232,196,107,.55); }
}
#resultTitle {
  color: var(--gold); margin: 0 0 6px; font-size: 1.2em;
  text-shadow: 0 0 16px rgba(232,196,107,.6);
  animation: resultTitlePop 500ms 150ms cubic-bezier(.2,1.4,.4,1) both;
}
@keyframes resultTitlePop {
  0% { transform: scale(.5); opacity: 0; }
  60% { transform: scale(1.12); opacity: 1; }
  100% { transform: scale(1); }
}
/* 本文だけを伸び縮みさせる。min-height:0 が無いとflexの中で縮まずにボタンを押し出す */
#resultBody { font-size: .88em; margin-bottom: 10px; flex: 0 1 auto; min-height: 0; overflow-y: auto; }
/* 最終結果の順位表 */
.finalRow { padding: 3px 0; font-size: 1.05em; }
.finalRow.finalTop { color: var(--gold); font-weight: 700; font-size: 1.2em; }

/* ---------- 勝敗の画面(最終結果のあと) ----------
   順位表だけでは「誰に勝って誰に負けたのか」が点数の並びから読み取る話になってしまう。
   相手の顔を出し、勝った相手と負けた相手に分けて、上から順に出てくるようにする。 */
.vsMe {
  display: flex; align-items: center; gap: 7px;
  padding: 3px 7px; margin-bottom: 3px;
  background: rgba(232,196,107,.12);
  border: 1px solid rgba(232,196,107,.4); border-radius: 10px;
}
.vsFace {
  width: 28px; height: 28px; flex: 0 0 auto;
  border-radius: 8px; object-fit: cover;
  border: 1px solid rgba(232,196,107,.45); background: #0a1a12;
}
.vsFaceMe { width: 32px; height: 32px; border-color: var(--gold); }
/* 絵の無い相手(オンラインの人間)は席の数字で代わりにする */
.vsFaceNone {
  display: flex; align-items: center; justify-content: center;
  color: #cfc7b8; font-weight: 700; font-size: .85em;
}
.vsInfo { flex: 1 1 auto; min-width: 0; text-align: left; }
.vsName {
  font-weight: 700; font-size: .88em; color: #f2ead6;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.vsSub { font-size: .68em; color: #a8bfae; }
.vsSectionHead {
  margin: 4px 0 2px; font-size: .74em; font-weight: 700;
  text-align: left; letter-spacing: .04em;
}
.vsSectionHead.win { color: var(--gold); }
.vsSectionHead.lose { color: #e79a9a; }
.vsCard {
  display: flex; align-items: center; gap: 7px;
  padding: 2px 7px; margin-bottom: 3px; border-radius: 9px;
  border: 1px solid transparent;
  /* 上から順に出てくる。遅れは要素側の animation-delay で付ける */
  opacity: 0; animation: vsIn .34s ease-out forwards;
}
.vsCard:last-child { margin-bottom: 0; }
.vsCard.win { background: rgba(232,196,107,.12); border-color: rgba(232,196,107,.38); }
.vsCard.lose { background: rgba(255,120,120,.09); border-color: rgba(255,120,120,.28); }
.vsMark {
  flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: .78em; font-weight: 800;
}
.vsCard.win .vsMark { background: var(--gold); color: #10240f; }
.vsCard.lose .vsMark { background: #b85c5c; color: #ffeaea; }
.vsDiff { flex: 0 0 auto; font-size: .8em; font-weight: 700; min-width: 52px; text-align: right; }
.vsCard.win .vsDiff { color: #a8e0a8; }
.vsCard.lose .vsDiff { color: #e79a9a; }
.vsVerdict {
  margin: 3px 0; padding: 2px 6px; border-radius: 8px;
  font-weight: 800; font-size: .86em;
}
.vsVerdict.vsAll { color: #10240f; background: var(--gold); }
.vsVerdict.vsNone { color: #ffeaea; background: rgba(184,92,92,.55); }
@keyframes vsIn {
  from { opacity: 0; transform: translateX(-14px); }
  to { opacity: 1; transform: none; }
}
/* 動きを減らす設定の端末では、順番に出す演出をしない */
@media (prefers-reduced-motion: reduce) {
  .vsCard { opacity: 1; animation: none; }
}
/* 背の高い横画面(390pxなど)は縦に余裕があるので、顔を大きくする。
   小さいままだと右側の余白だけが目立ってしまう。 */
@media (min-height: 386px) {
  .vsFace { width: 36px; height: 36px; }
  .vsFaceMe { width: 40px; height: 40px; }
  .vsCard { padding: 4px 8px; margin-bottom: 4px; }
  .vsMe { padding: 5px 8px; margin-bottom: 5px; }
  .vsName { font-size: .95em; }
  .vsSub { font-size: .72em; }
  .vsMark { width: 22px; height: 22px; }
}
/* 背の低い横画面(iPhone SE の横=320pxなど)では、そのままだと本文が
   40px ほど溢れて3枚目の札が隠れてしまう。相手の顔は残したまま全体を詰める。 */
@media (max-height: 360px) {
  .vsMe {
    padding: 0 6px; margin-bottom: 2px;
    background: none; border: none; border-radius: 0;
  }
  .vsFace { width: 24px; height: 24px; border-radius: 6px; }
  .vsFaceMe { width: 24px; height: 24px; }
  .vsCard { padding: 1px 6px; margin-bottom: 2px; }
  .vsMark { width: 17px; height: 17px; font-size: .7em; }
  .vsName { font-size: .82em; }
  .vsSub { font-size: .62em; }
  .vsSectionHead { margin: 2px 0 1px; font-size: .68em; }
  .vsVerdict { margin: 0 0 1px; padding: 1px 5px; font-size: .78em; }
  .vsDiff { font-size: .74em; min-width: 46px; }
}

.win-block {
  background: rgba(232,196,107,.08);
  border: 1px solid rgba(232,196,107,.4);
  border-radius: 10px;
  padding: 6px 10px;
  margin-bottom: 6px;
  text-align: left;
}
.win-who { font-weight: 700; color: var(--gold); font-size: .95em; margin-bottom: 3px; }
/* 結果画面: 和了した瞬間の手牌をそのまま並べて見せる(なぜ和了ったか一目で分かるように) */
.win-hand { display: flex; flex-wrap: wrap; gap: 2px; margin-bottom: 5px; justify-content: center; }
/* 牌画像の縦横比(1.371)に合わせる。比が違うと上下が切れる */
.win-hand .tile { width: 24px; height: 33px; border-radius: 3px; }
.win-hand .tile.winTileMark { transform: translateY(-4px); }
.win-hand .meldGap { width: 6px; }
/* 面子の切れ目。ここが無いと「この牌はどこともつながっていない」と読めてしまう */
.win-hand .setGap { width: 5px; flex: 0 0 auto; }
.win-yaku { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 4px; }
.yaku-chip {
  background: rgba(255,255,255,.08); border-radius: 6px; padding: 2px 8px;
  font-size: .85em;
  opacity: 0;
  animation: chipPop 420ms cubic-bezier(.2,1.5,.4,1) both;
}
@keyframes chipPop {
  0% { transform: scale(.3) translateY(6px); opacity: 0; }
  70% { transform: scale(1.12) translateY(0); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
.yaku-chip b { color: var(--gold); margin-left: 3px; }
.win-score {
  font-size: .9em; opacity: 0;
  animation: scoreFadeIn 400ms ease-out both;
}
@keyframes scoreFadeIn { 0% { opacity: 0; transform: translateY(4px); } 100% { opacity: .9; transform: translateY(0); } }
.win-total {
  color: var(--gold); font-weight: 700; font-size: 1.3em;
  text-shadow: 0 0 12px rgba(232,196,107,.7);
  animation: totalPulse 900ms ease-in-out .6s 2;
}
.win-total-row { margin-top: 4px; opacity: .95; }
.win-bonus {
  font-size: .8em; opacity: .8; margin: 2px 0; line-height: 1.5;
}
/* 満貫・跳満などの格。翻符のすぐ横に出す */
.win-rank {
  margin-left: 6px; padding: 1px 8px; border-radius: 999px;
  background: var(--gold); color: #2b1d05; font-weight: 800; font-size: .92em;
}
/* 役の札(左)と点数の計算(右)を横に並べる。
   縦に積むと点数画面が伸びて、ドラ表示や持ち点の一覧まで入りきらなくなる。
   狭い画面では折り返して今までどおり縦に並ぶ */
.win-detail {
  display: flex; flex-wrap: wrap; justify-content: center;
  align-items: flex-start; gap: 6px 16px; margin-top: 4px;
}
.win-detail .win-yaku { flex: 1 1 190px; margin-bottom: 0; justify-content: center; }
.win-numbers { flex: 0 1 auto; min-width: 170px; }
/* 「和了点 ＋ 本場 ＋ 供託 ＝ 合計」の内訳。
   数字の桁を縦にそろえて、足し算として読めるようにする */
.win-calc {
  display: block; margin: 3px 0 0; text-align: left;
  font-size: .82em; opacity: .9;
}
.calc-row { display: flex; justify-content: space-between; gap: 12px; line-height: 1.35; }
.calc-name { opacity: .85; }
.calc-name small { opacity: .75; margin-left: 5px; font-size: .9em; }
.calc-val { font-variant-numeric: tabular-nums; white-space: nowrap; }
.calc-row.plus .calc-val { color: #9fe0a8; }
/* 合計の上に区切り線を引いて、ここまでの足し算だと分かるようにする */
.win-total-row::before {
  content: ''; display: block; width: 100%;
  height: 1px; margin: 3px 0; background: rgba(232,196,107,.4);
}
.honba-note {
  text-align: center; color: var(--gold); font-size: .85em; opacity: .85; margin-bottom: 6px;
}
@keyframes totalPulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.14); } }
/* 点数画面のドラ・裏ドラの山 */
.dora-block {
  display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 4px 14px;
  margin: 3px 0 2px; padding: 3px 6px;
  background: rgba(232,196,107,.08); border: 1px solid rgba(232,196,107,.35); border-radius: 8px;
}
.dora-row { display: flex; align-items: center; gap: 4px; }
.dora-label { font-size: .78em; opacity: .85; text-align: left; white-space: nowrap; }
.dora-chip img { width: 20px; height: 27px; border-radius: 2px; display: block; }
.dora-chip.dora-ura img { box-shadow: 0 0 0 2px rgba(255,107,107,.8); border-radius: 3px; }

/* 裏ドラをめくる演出(王牌の下段を返す) */
.tile.uraFlip { animation: uraFlipIn 520ms cubic-bezier(.2,1.2,.4,1) both; z-index: 2; }
@keyframes uraFlipIn {
  0% { transform: rotateX(90deg) scale(.8); filter: brightness(2); }
  60% { transform: rotateX(0deg) scale(1.12); filter: brightness(1.5); }
  100% { transform: rotateX(0deg) scale(1); filter: brightness(1); }
}

.score-table {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 2px 10px;
  font-size: .78em; opacity: .9; margin-top: 4px;
}


/* 判定の診断ログ(📜ログ末尾) */
.diagHead{margin-top:10px;color:#e6c46a;font-size:12px}
.diagLine{font-size:11px;color:#cfc7b8;word-break:break-all}

/* 横向きスマホでは画面が低いので、点数画面のボタンだけ控えめにして中身を1画面に収める */
#resultBox .bigbtn { font-size: 1.05em; padding: 10px 30px; flex: 0 0 auto; }

/* 局が終わったあと「タップすれば点数画面へ進む」ことを伝える案内。
   勝手に進まない仕様なので、これが無いと固まったように見える */
#tapHint {
  flex: 0 0 auto; pointer-events: none;
  background: rgba(20,16,10,.82); color: var(--gold);
  border: 1px solid rgba(232,196,107,.75); border-radius: 999px;
  padding: 3px 14px; font-size: max(10px, calc(var(--u) * .46)); font-weight: 700; white-space: nowrap;
  animation: tapHintPulse 1.4s ease-in-out infinite;
}
@keyframes tapHintPulse {
  0%, 100% { opacity: .65; }
  50% { opacity: 1; }
}

/* 流局の点数の振り分け(ノーテン罰符)。誰がいくら動いたか1人ずつ見せる */
.draw-note { font-size: .8em; opacity: .9; margin-top: 4px; }
.draw-pays { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 8px; margin-top: 4px; }
.draw-pay { font-weight: 700; font-size: .85em; padding: 1px 8px; border-radius: 999px; white-space: nowrap; }
.draw-pay.draw-get { background: rgba(60,120,60,.45); color: #cdf5cd; }
.draw-pay.draw-lose { background: rgba(140,40,40,.45); color: #ffd0d0; }

/* 裏ドラをめくる場面。王牌だけを大きくして、何がめくれたのか分かるようにする */
#cpDora.uraZoom {
  transform: scale(2.1);
  transform-origin: center center;
  z-index: 40;
  position: relative;
  filter: drop-shadow(0 0 10px rgba(255,215,110,.9));
  transition: transform .35s ease-out;
}
/* 拡大中は中央パネルの文字が邪魔になるので薄くする */
#centerInfo.uraZooming .cp-line,
#centerInfo.uraZooming .cp-score { opacity: .15; transition: opacity .3s; }
#centerInfo.uraZooming { overflow: visible; }

/* 局が終わった卓の上で「誰が誰からロンしたのか」を出す帯。
   点数画面を開く前に、何が起きたのかを1行で分かるようにする */
#endBanner {
  /* 名札とタップ案内のあいだの余白の真ん中に置く(重ならないまま中央に寄る) */
  flex: 0 1 auto; margin: 0 auto; pointer-events: none;
  background: linear-gradient(180deg, rgba(120,26,26,.95), rgba(72,14,14,.95));
  color: #ffe9b0; border: 1px solid rgba(232,196,107,.85); border-radius: 999px;
  padding: 3px 10px; font-size: max(10px, calc(var(--u) * .46)); font-weight: 800;
  white-space: nowrap; box-shadow: 0 2px 10px rgba(0,0,0,.45);
  /* 名前が長いときでも、左の名札や右の案内に乗り上げないように幅を抑える */
  max-width: 72%; overflow: hidden; text-overflow: ellipsis;
}

/* ロビーの顔ぶれ(誰が入っているか) */
#onlineRoster {
  margin-top: 6px; color: #ffe9b0; font-size: .92em; font-weight: 700;
  background: rgba(20,16,10,.6); border: 1px solid rgba(232,196,107,.5);
  border-radius: 10px; padding: 6px 12px;
}

/* 対局中ずっと出しておく部屋番号。通信が切れた人が入り直すのに要る */
/* 部屋番号と「CPUに任せる」を縦に並べる箱。重ならないようにここで位置を決める */
#roomBar {
  /* 点数画面(z-index:60)より上に置く。席を外したくなるのは
     結果を見ている最中のことが多く、そこで押せないと意味がない */
  /* 卓が大きくなって上家の配牌レーンが左上の角まで伸びたので、レーンの内側へ寄せる
     (以前は left:6px で、配牌の牌に重なっていた) */
  position: fixed; left: calc(8px + var(--lane, 34px)); top: 6px; z-index: 70;
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  pointer-events: none; max-width: 60vw;
}
#roomChip {
  pointer-events: none;
  background: rgba(20,16,10,.78); color: var(--gold);
  border: 1px solid rgba(232,196,107,.6); border-radius: 999px;
  padding: 2px 10px; font-size: max(10px, calc(var(--u, 21px) * .42));
  font-weight: 700; white-space: nowrap; letter-spacing: .04em;
}

/* 顔を持たない席(オンラインで見た目を選んでいない人)のカットイン。
   画像を隠したぶん、名前と「ポン！」を読めるだけの幅を確保する */
#cutin #cutinImg[hidden] { display: none; }
#cutin:has(#cutinImg[hidden]) { padding-left: 28px; }
#cutin #cutinName { max-width: 40vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 席を離れる/戻るボタン。部屋番号のすぐ下に置く(対局中ずっと押せる場所) */
#btnSitOut {
  pointer-events: auto;
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(20,16,10,.85); color: var(--gold);
  border: 1px solid rgba(232,196,107,.6); border-radius: 999px;
  padding: 3px 10px; font-size: max(10px, calc(var(--u, 21px) * .42));
  font-weight: 700; white-space: nowrap; cursor: pointer;
}
#btnSitOut .ic {
  width: 1.25em; height: 1.25em; border: 0; background: none;
  box-shadow: none; padding: 0; filter: none; flex: 0 0 auto;
}
#btnSitOut:active { transform: scale(.96); }
/* 下段の左端(自分の名札の手前)に置いたときの形。幅が足りないときは文字だけ削り、
   ボタン自体は絶対に消えない(押せなくなると席を外せなくなる) */
/* 点数画面(z-index:60)より上に出す。席を外したくなるのは結果を見ている最中が多く、
   そこで押せないと意味がない(オンラインで全員の進行が止まる) */
#bottomRow > #btnSitOut {
  /* このボタンは縮めない。縮むと「対局に戻る」が「対局に…」と切れて、
     何のボタンか分からなくなる。幅は名札やシャンテン表示のほうが譲る */
  flex: 0 0 auto; overflow: hidden;
  height: calc(var(--u) * 1.3);
  position: relative; z-index: 70;
}
#bottomRow > #btnSitOut span { overflow: hidden; text-overflow: ellipsis; }
#bottomRow > #btnSitOut.hidden { display: none; }
#btnSitOut.back { background: rgba(60,120,60,.9); color: #eaffea; border-color: rgba(180,240,180,.7); }

/* 入り直しの待ち受け中の案内 */
#onlineWait { margin-top: 6px; color: #ffd9a0; font-size: .9em; }

/* 操作欄に出す短い知らせ(「CPUが代わりに打っています」など)。
   そのまま文字を入れると折り返して手牌の上にかぶるので、1行に収める */
.barNote {
  display: block; width: 100%; text-align: center;
  color: var(--gold); font-weight: 700;
  font-size: max(10px, calc(var(--u) * .46));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ============ ロン・ツモの演出(一番強い場面) ============ */

/* 中央から広がる金色の衝撃波 */
.winRing {
  position: absolute; left: 50%; top: 50%;
  width: 40px; height: 40px; margin: -20px 0 0 -20px;
  border-radius: 50%;
  /* 太くすると画面が輪で埋まって卓が見えなくなる。細く速く通す */
  border: 3px solid rgba(255,225,150,.85);
  box-shadow: 0 0 26px rgba(255,210,110,.75);
  animation: winRingOut 1100ms cubic-bezier(.15,.7,.3,1) forwards;
  opacity: 0;
}
.winRing.yakuman { border-color: rgba(255,255,255,.9); border-width: 4px; }
@keyframes winRingOut {
  0% { transform: scale(.2); opacity: 0; }
  12% { opacity: 1; }
  100% { transform: scale(26); opacity: 0; }
}

/* 背後から差す光。和了の一撃を重く見せる */
.winRays {
  position: absolute; inset: -20%;
  /* 卓が見えなくならない濃さにとどめる。一瞬だけ差して消える */
  background:
    repeating-conic-gradient(from 0deg at 50% 50%,
      rgba(255,220,140,.16) 0deg 5deg, rgba(255,220,140,0) 5deg 20deg);
  mask-image: radial-gradient(circle at 50% 50%, transparent 8%, black 46%, transparent 86%);
  -webkit-mask-image: radial-gradient(circle at 50% 50%, transparent 8%, black 46%, transparent 86%);
  animation: winRaysSpin 900ms ease-out forwards;
  opacity: 0;
}
.winRays.yakuman { background:
    repeating-conic-gradient(from 0deg at 50% 50%,
      rgba(255,245,200,.26) 0deg 5deg, rgba(255,245,200,0) 5deg 16deg); }
@keyframes winRaysSpin {
  0% { opacity: 0; transform: rotate(0deg) scale(.6); }
  18% { opacity: 1; }
  100% { opacity: 0; transform: rotate(26deg) scale(1.2); }
}

/* 卓が短く揺れる。長く揺らすと酔うので、ごく短く */
#game.winShake { animation: winShake 480ms ease-out; }
#game.winShakeBig { animation: winShake 880ms ease-out; }
@keyframes winShake {
  0% { transform: translate(0, 0); }
  12% { transform: translate(-6px, 3px); }
  26% { transform: translate(5px, -4px); }
  40% { transform: translate(-4px, -2px); }
  55% { transform: translate(3px, 3px); }
  70% { transform: translate(-2px, -1px); }
  100% { transform: translate(0, 0); }
}

/* ロン・ツモのカットインは、鳴きの帯とは別物にする。
   画面の中央に大きく構え、名前と「ロン！」を大きく見せる */
#cutin.cutinWin {
  left: 50%; right: auto; top: 50%;
  /* 飛び出す瞬間に1.08倍まで膨らむので、その分を見込んだ幅にする
     (はみ出すと帯の端が切れて、名前や文字が欠ける) */
  box-sizing: border-box;
  width: min(84vw, 680px);
  justify-content: center; gap: 18px;
  padding: 6px 24px;
  background: linear-gradient(90deg,
    rgba(30,10,0,0) 0%, rgba(78,32,0,.90) 16%,
    rgba(140,92,12,.92) 50%, rgba(78,32,0,.90) 84%, rgba(30,10,0,0) 100%);
  border-top: 3px solid #ffe9a8; border-bottom: 3px solid #ffe9a8;
  box-shadow: 0 0 46px rgba(255,205,105,.55);
  transform: translate(-50%, -50%) scale(.5);
  opacity: 0;
  transition: none;
}
#cutin.cutinWin.show { animation: winCutinIn 560ms cubic-bezier(.2,1.5,.35,1) forwards; }
@keyframes winCutinIn {
  0% { transform: translate(-50%, -50%) scale(.5); opacity: 0; }
  55% { transform: translate(-50%, -50%) scale(1.08); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}
#cutin.cutinWin #cutinImg {
  width: clamp(86px, calc(var(--u, 21px) * 6.4), 150px);
  height: clamp(86px, calc(var(--u, 21px) * 6.4), 150px);
  border-width: 4px;
  box-shadow: 0 0 28px rgba(255,225,150,.95);
}
#cutin.cutinWin #cutinText { text-align: center; }
#cutin.cutinWin #cutinName { font-size: 1.05em; opacity: .95; }
#cutin.cutinWin #cutinAction {
  font-size: 2.7em; letter-spacing: .08em; color: #fff6d8;
  text-shadow: 0 0 18px rgba(255,210,110,1), 0 0 44px rgba(255,170,40,.9), 0 3px 0 rgba(90,40,0,.9);
  animation: winActionPop 620ms cubic-bezier(.2,1.7,.35,1) both;
}
@keyframes winActionPop {
  0% { transform: scale(.55); opacity: 0; }
  60% { transform: scale(1.2); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* 和了の呼び出し絵(ロン/ツモ)も一回り大きくする */
#callFlash.win:not(.hidden) {
  height: max(88px, calc(var(--u, 23px) * 7));
  filter: drop-shadow(0 0 26px rgba(255,215,120,.95)) drop-shadow(0 6px 14px rgba(0,0,0,.7));
}

/* ============ お店で買える見た目 ============ */
/* 牌は「裏の絵」だけを差し替える。表の絵柄は変えない(数字や字が読みにくくなるため)。
   色を回すのではなく、彫りの入った専用の絵を img/tiles/back_*.webp に用意してある。 */

/* 卓の色は「背景そのものを染める」やり方にする。
   上に膜を重ねると重なり順の調整が必要になり、河・手牌・名札の配置を壊した。
   background-blend-mode なら卓の絵だけが染まり、上に置くものには一切触れない。
   混ぜ方は luminosity。color だと絵の明暗が消えて真っ平らな灰色になる。 */
body[data-table-skin="midori"] #table { background-image: url('../img/tables/midori.jpg'); }
body[data-table-skin="shiraki"] #table { background-image: url('../img/tables/shiraki.jpg'); }
body[data-table-skin="enji"] #table { background-image: url('../img/tables/enji.jpg'); }
body[data-table-skin="ai"] #table { background-image: url('../img/tables/ai.jpg'); }
/* 最終章を突破した人だけが使える卓。ptでは買えない（2026-10-23） */
body[data-table-skin="tengen"] #table { background-image: url('../img/tables/tengen.jpg'); }

/* ============ お店の画面 ============ */
#shopPanel {
  position: fixed; inset: 0; z-index: 80;
  background: linear-gradient(180deg, #0a1410, #050b08);
  display: flex; flex-direction: column; gap: 8px;
  padding: calc(10px + var(--safe-t)) calc(10px + var(--safe-r))
           calc(10px + var(--safe-b)) calc(10px + var(--safe-l));
}
#shopScroll { flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; }
#shopHead { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
#shopHead h2 { margin: 0; color: var(--gold); }
#shopWallet {
  color: #ffe9b0; background: rgba(20,16,10,.7);
  border: 1px solid rgba(232,196,107,.6); border-radius: 999px;
  padding: 3px 14px; font-weight: 700; white-space: nowrap;
}
#shopWallet b { color: var(--gold); font-size: 1.15em; }
#shopTabs { display: flex; gap: 8px; margin: 5px 0; }
.shopTab {
  flex: 1 1 0; padding: 6px 4px; border-radius: 10px; cursor: pointer;
  background: #1d2a22; color: #cfc7b8; border: 1px solid rgba(232,196,107,.35);
  font-weight: 700; font-size: 1em;
}
.shopTab.selected { background: linear-gradient(180deg, #3a5c45, #21382b); color: #ffe9b0; border-color: var(--gold); }
#shopGrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 6px; }
.shopCard {
  background: rgba(18,32,24,.9); border: 1px solid rgba(232,196,107,.35);
  border-radius: 12px; padding: 6px; display: flex; flex-direction: column; gap: 4px;
}
.shopCard.equipped { border-color: var(--gold); box-shadow: 0 0 12px rgba(232,196,107,.35); }
.shopCardName { color: #ffe9b0; font-weight: 700; }
.shopCardNote {
  color: #a8bfae; font-size: .72em; line-height: 1.35;
  /* 2行で止める。伸びると「買う」ボタンが画面の外に出てしまう */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; min-height: 2.2em;
}
.shopPreview { display: flex; gap: 4px; align-items: center; justify-content: center;
  height: 34px; border-radius: 8px; overflow: hidden; }
.shopPreview img { width: 19px; height: 26px; border-radius: 3px; display: block; }
.shopPrice { color: var(--gold); font-weight: 700; font-size: .9em; }
.shopBtn {
  padding: 7px 4px; border-radius: 999px; border: 0; cursor: pointer;
  background: linear-gradient(180deg, #e8c46b, #b8923c); color: #2a1d06; font-weight: 800;
}
.shopBtn.own { background: linear-gradient(180deg, #4e8a5d, #2f5c3a); color: #eaffea; }
.shopBtn[disabled] { opacity: .5; cursor: default; }
#shopNote { margin-top: 10px; color: #ffd9a0; min-height: 1.4em; font-weight: 700; text-align: center; }

/* 卓の見本。実際の卓と同じ色の膜をかけて見せる */
.shopPreview.tablePrev { background: #05100b url('../img/table-bg.jpg') center / cover no-repeat; }
.shopPreview.tablePrev[data-t="midori"] { background-image: url('../img/tables/midori.jpg'); }
.shopPreview.tablePrev[data-t="shiraki"] { background-image: url('../img/tables/shiraki.jpg'); }
.shopPreview.tablePrev[data-t="enji"] { background-image: url('../img/tables/enji.jpg'); }
.shopPreview.tablePrev[data-t="ai"] { background-image: url('../img/tables/ai.jpg'); }

/* 見本の牌にも、その色を当てて見せる */
/* 見本の牌は、その牌の絵そのものを並べて見せる */

/* 最終結果に出す「今回もらった分」 */
.finalGain {
  margin-top: 10px; padding-top: 8px; border-top: 1px solid rgba(232,196,107,.4);
  color: #ffe9b0; font-size: .86em; line-height: 1.6;
}

/* お店の説明は1〜2行に収める。長いと「買う」ボタンが画面の外に出る */
.shopHelp { font-size: .78em; margin: 4px 0; line-height: 1.4; }
#shopScroll { padding-bottom: 6px; }

/* 対局を始める前に曲を選ぶ欄 */
#bgmPick {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  flex-wrap: wrap; margin-bottom: 6px; color: #cfc7b8; font-size: .9em;
}
#bgmPickLabel { color: var(--gold); font-weight: 700; }
#bgmSelect {
  background: #1d2a22; color: #ffe9b0; border: 1px solid rgba(232,196,107,.5);
  border-radius: 8px; padding: 5px 8px; font-size: 1em; max-width: 60vw;
}

/* お店の曲。見本の代わりに音符を出す */
.shopPreview.bgmPrev {
  background: linear-gradient(180deg, #1b2c22, #0e1a14);
  color: var(--gold); font-size: 1.5em; letter-spacing: .2em;
}

/* 選んだ相手だと段位ポイントが何倍になるか。選ぶ前に分かるように出す */
#foeReward {
  margin: 2px 0 0; color: #ffd9a0; font-size: .82em; font-weight: 700;
  text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* 毎日のログインボーナスの知らせ。
   押せない帯にしてあるので、下のボタンの操作を邪魔しない */
#loginBonus {
  /* 画面の上に浮かせる。タイトルの流れに入れると、狭い画面で下端が切れた */
  position: fixed; left: var(--safe-l); right: var(--safe-r);
  top: calc(8px + var(--safe-t)); margin: 0 auto; z-index: 90;
  width: -moz-fit-content; width: fit-content;
  pointer-events: none; max-width: 94vw;
  background: linear-gradient(180deg, rgba(120,90,10,.95), rgba(72,52,4,.95));
  color: #fff6d8; border: 1px solid rgba(232,196,107,.85); border-radius: 999px;
  padding: 5px 16px; font-weight: 800; font-size: .92em; text-align: center;
  box-shadow: 0 2px 12px rgba(0,0,0,.5);
  animation: loginPop 520ms cubic-bezier(.2,1.5,.35,1) both;
}
@keyframes loginPop {
  0% { transform: scale(.7) translateY(-6px); opacity: 0; }
  60% { transform: scale(1.06); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}


/* 少し見せたら静かに消す */
#loginBonus.fade { animation: loginFade 700ms ease-out forwards; }
@keyframes loginFade { to { opacity: 0; transform: translateY(-10px); } }

/* ============ 鳴き・リーチのカットインを、その人の側から出す ============
   自分から見て 下家=右 / 対面=上 / 上家=左 / 自分=下。
   どこから声がかかったのかが一目で分かる。和了だけは真ん中に大きく出す(別指定)。 */

/* 右から(下家)。これまでと同じ見た目 */
/* スマホの横持ちは、ノッチ側の帯(セーフエリア)に文字が潜って切れる。
   画面の端に貼り付く向き(左右)は、その端のぶんだけ内側へ寄せる（2026-10-11） */
#cutin.fromRight {
  right: 0; left: auto; top: 30%; bottom: auto; transform: translateX(100%);
  padding: 10px calc(20px + var(--safe-r, 0px)) 10px 46px;
}
#cutin.fromRight.show { transform: translateX(0); }

/* 左から(上家)。左右を鏡にする */
#cutin.fromLeft {
  left: 0; right: auto; top: 30%; bottom: auto;
  transform: translateX(-100%);
  flex-direction: row-reverse;
  background: linear-gradient(270deg, rgba(10,10,10,0), rgba(8,8,8,.92) 35%);
  padding: 10px 46px 10px calc(20px + var(--safe-l, 0px));
}
#cutin.fromLeft.show { transform: translateX(0); }
#cutin.fromLeft #cutinText { text-align: left; }

/* 上から(対面)。横長の帯を上端から下ろす */
#cutin.fromTop {
  left: 50%; right: auto; top: 0; bottom: auto;
  transform: translate(-50%, -100%);
  padding: 8px 28px;
  border-radius: 0 0 14px 14px;
  background: linear-gradient(90deg, rgba(10,10,10,0), rgba(8,8,8,.92) 22%,
    rgba(8,8,8,.92) 78%, rgba(10,10,10,0));
}
#cutin.fromTop.show { transform: translate(-50%, 0); }
/* 中央に出るものは、左右のノッチぶんを避けた幅に収める */
#cutin.fromTop, #cutin.fromBottom, #cutin.cutinWin {
  max-width: calc(100vw - var(--safe-l, 0px) - var(--safe-r, 0px) - 8px);
  box-sizing: border-box;
}

/* 下から(自分)。中央パネル(ドラ表示)と手牌のあいだに収める。
   以前は bottom:26% で手牌は避けていたが、上にある中央パネルに重なり、
   320pxの横画面ではドラ表示の牌が7枚隠れていた。 */
#cutin.fromBottom {
  left: 50%; right: auto; top: auto; bottom: 22.5%;
  transform: translate(-50%, 220%);
  padding: 8px 28px;
  border-radius: 14px;
  background: linear-gradient(90deg, rgba(10,10,10,0), rgba(8,8,8,.92) 22%,
    rgba(8,8,8,.92) 78%, rgba(10,10,10,0));
}
#cutin.fromBottom.show { transform: translate(-50%, 0); }
/* 背の低い横画面は、中央パネルと手牌のあいだが狭い。卓を大きくしたぶん中央パネルも
   伸びたので、320pxの横画面ではその隙間が72pxしかない。
   顔と文字と余白を詰めて、中央パネルにも手牌にも重ならない高さに収める。 */
@media (max-height: 380px) {
  #cutin.fromBottom { padding: 4px 24px; }
  #cutin.fromBottom #cutinImg { width: 42px; height: 42px; }
  #cutin.fromBottom #cutinName { font-size: .7em; }
  #cutin.fromBottom #cutinAction { font-size: 1.3em; }
}

/* 上下の帯は横長なので、名前と文字を横に並べて高さを抑える */
#cutin.fromTop #cutinText, #cutin.fromBottom #cutinText { text-align: left; }

/* ============ 物語(ストーリーモード) ============ */
/* 終幕で流す一枚絵。画面いっぱいに出し、下に題と一文を添える */
#endingSlide {
  position: fixed; inset: 0; z-index: 66; cursor: pointer;
  background: #040806;
  display: flex; align-items: center; justify-content: center;
}
#endingSlide.hidden { display: none; }
#endingSlideImg {
  max-width: 100%; max-height: 100%; object-fit: contain;
  opacity: 0; transition: opacity .55s ease;
}
#endingSlideImg.on { opacity: 1; }
#endingSlideCap {
  position: absolute; left: 0; right: 0; bottom: calc(env(safe-area-inset-bottom, 0px) + 26px);
  text-align: center; pointer-events: none;
  text-shadow: 0 2px 8px #000, 0 0 16px rgba(0,0,0,.9);
}
#endingSlideCap b { display: block; color: var(--gold); font-size: 1.05em; letter-spacing: .06em; }
#endingSlideCap span { display: block; color: #f2ead6; font-size: .8em; margin-top: 3px; }
#endingSlideDots {
  position: absolute; left: 0; right: 0; bottom: calc(env(safe-area-inset-bottom, 0px) + 10px);
  display: flex; justify-content: center; gap: 5px; pointer-events: none;
}
.slideDot { width: 5px; height: 5px; border-radius: 50%; background: rgba(255,255,255,.28); }
.slideDot.on { background: var(--gold); box-shadow: 0 0 6px rgba(232,196,107,.8); }
#endingSlide .talkSkip { z-index: 2; }

/* 人物録の「物語の絵」の棚 */
#galleryHead { margin-top: 18px; }
#galleryGrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.galleryCard {
  display: flex; flex-direction: column; gap: 4px; padding: 0;
  background: rgba(255,255,255,.04); border: 1px solid rgba(232,196,107,.3);
  border-radius: 8px; overflow: hidden; cursor: pointer; font-family: inherit;
}
.galleryCard img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block; }
.galleryTitle { color: #f2ead6; font-size: .72em; padding: 0 6px 6px; text-align: left; }
/* 1枚を大きく見る */
.picView {
  position: fixed; inset: 0; z-index: 68; background: rgba(3,8,5,.96);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  padding: calc(env(safe-area-inset-top, 0px) + 8px) 12px calc(env(safe-area-inset-bottom, 0px) + 8px);
}
/* 絵は「残りの高さ」で縮める。割合(68%)で決めると、320pxの横画面では
   題と閉じるボタンのぶんが足りずに下がはみ出す */
.picView img {
  max-width: 100%; min-height: 0; flex: 1 1 auto;
  object-fit: contain; border-radius: 8px;
}
.picView .picCap, .picView .picClose { flex: 0 0 auto; }
.picView .picClose { padding: 7px 26px; font-size: .92em; }
.picCap { text-align: center; }
.picCap b { display: block; color: var(--gold); }
.picCap span { display: block; color: #cbd7cc; font-size: .82em; margin-top: 2px; }

/* 最後の一戦。本編の章とは別枠なので、見出しも行も金で強く出す */
.storyChapterFinal { color: var(--gold); text-shadow: 0 0 10px rgba(232,196,107,.5); }
.storyRowFinal {
  border-color: rgba(232,196,107,.75);
  background: linear-gradient(90deg, rgba(232,196,107,.14), rgba(255,255,255,.04));
}
.storyRowFinal.locked { border-color: rgba(255,255,255,.12); background: rgba(255,255,255,.03); }
.storyRowFinal:not(.locked) .storyNo { color: var(--gold); font-weight: 800; }
/* 因縁の卓。打ち手たちが主人公になる話なので、最終章の金とは別に紅で分ける */
.storyChapterRival { color: #e8a08f; }
.storyRowRival {
  border-color: rgba(220,120,100,.55);
  background: linear-gradient(90deg, rgba(200,90,70,.13), rgba(255,255,255,.03));
}
.storyRowRival.locked { border-color: rgba(255,255,255,.12); background: rgba(255,255,255,.03); }
.storyRowRival:not(.locked) .storyNo { color: #e8a08f; font-weight: 800; }
/* 余話。戦わずに読むだけの行なので、金ではなく藍で静かに分ける */
.storyChapterSide { color: #a9c4e8; }
.storyRowSide {
  border-color: rgba(150,185,230,.5);
  background: linear-gradient(90deg, rgba(120,160,220,.12), rgba(255,255,255,.03));
}
.storyRowSide.locked { border-color: rgba(255,255,255,.12); background: rgba(255,255,255,.03); }
.storyRowSide:not(.locked) .storyNo { color: #a9c4e8; font-weight: 800; }
.dexUra .uraSide { display: block; margin-top: 4px; color: #a9c4e8; font-size: .85em; }
/* 終幕で、三人の顔だけ大きく出す */
.endingFacesBig img { width: 78px; height: 78px; border-width: 2px; }

/* 誰として物語を進めるか。3人は進み具合も台詞も別々なので、
   いまどの人で見ているのかが一覧の上で分かるようにする */
#storyWho { margin: 0 0 10px; }
.storyWhoLabel { font-size: .78em; color: #a8bfae; margin-bottom: 5px; }
#storyWhoRow { display: flex; gap: 8px; flex-wrap: wrap; }
.storyWhoCard {
  flex: 1 1 0; min-width: 92px;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 6px 8px; cursor: pointer;
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(232,196,107,.3); border-radius: 10px;
  color: #cbd7cc; font-family: inherit;
}
.storyWhoCard.on {
  background: rgba(232,196,107,.16); border-color: var(--gold);
  box-shadow: 0 0 10px rgba(232,196,107,.35);
}
.storyWhoFace {
  width: 44px; height: 44px; border-radius: 50%;
  background-size: cover; background-position: center top;
  border: 2px solid rgba(232,196,107,.5);
}
.storyWhoCard.on .storyWhoFace { border-color: var(--gold); }
.storyWhoName { font-weight: 700; font-size: .86em; color: #f2ead6; }
.storyWhoCard.on .storyWhoName { color: var(--gold); }
.storyWhoProg { font-size: .68em; opacity: .85; }

/* ステージえらび */
#storyPanel {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(3,8,5,.97);
  display: flex; flex-direction: column;
  padding: calc(env(safe-area-inset-top, 0px) + 8px) calc(env(safe-area-inset-right, 0px) + 10px)
    calc(env(safe-area-inset-bottom, 0px) + 8px) calc(env(safe-area-inset-left, 0px) + 10px);
}
#storyPanel.hidden { display: none; }
#storyScroll { flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; }
#storyScroll h2 { color: var(--gold); margin: 2px 0 4px; font-size: 1.05em; }
#storyCount { font-size: .7em; color: #a8bfae; font-weight: 400; }
.storyChapter {
  color: var(--gold); font-weight: 800; font-size: .82em;
  margin: 10px 0 4px; padding-top: 6px;
  border-top: 1px solid rgba(232,196,107,.22);
}
.storyRow {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 5px 8px; margin-bottom: 5px;
  background: rgba(10,26,18,.7); border: 1px solid rgba(232,196,107,.3);
  border-radius: 10px; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.storyRow:disabled, .storyRow.locked { opacity: .55; cursor: default; }
.storyRow.done { border-color: rgba(168,224,168,.5); background: rgba(14,34,22,.8); }
.storyRow img {
  width: 42px; height: 42px; flex: 0 0 auto; border-radius: 8px; object-fit: cover;
  object-position: center top; border: 1px solid rgba(232,196,107,.4);
}
.storyRowText { flex: 1 1 auto; min-width: 0; }
.storyNo { font-size: .64em; color: #a8bfae; }
.storyTitle { font-size: .92em; font-weight: 700; color: #f2ead6; }
.storyFoe { font-size: .68em; color: #cbbf9a; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.storyMark {
  flex: 0 0 auto; font-size: .7em; font-weight: 800;
  padding: 2px 9px; border-radius: 999px;
  background: var(--gold); color: #10240f;
}
.storyRow.done .storyMark { background: #a8e0a8; }
.storyRow.locked .storyMark { background: none; }

/* 会話 */
#storyTalk {
  position: fixed; inset: 0; z-index: 62;
  background: radial-gradient(120% 90% at 50% 20%, #12221a, #020604);
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: calc(env(safe-area-inset-top, 0px) + 6px) calc(env(safe-area-inset-right, 0px) + 10px)
    calc(env(safe-area-inset-bottom, 0px) + 8px) calc(env(safe-area-inset-left, 0px) + 10px);
}
#storyTalk.hidden { display: none; }
/* 場面の絵。話が進んで部屋が変わるとき、ふわりと入れ替える。
   絵が読み込めなくても下の暗い地色が残るので、話はそのまま進む */
#talkBg {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-position: center; background-size: cover; background-repeat: no-repeat;
  opacity: 0; transition: opacity .5s ease;
}
#talkBg.on { opacity: 1; }
/* 絵の上に台詞をのせるので、上下を暗く沈めて文字を立たせる */
#talkBg::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(to top, rgba(2,6,4,.88) 0%, rgba(2,6,4,.35) 34%, rgba(2,6,4,0) 56%),
    linear-gradient(to bottom, rgba(2,6,4,.72) 0%, rgba(2,6,4,0) 22%);
}
#talkTop { position: absolute; top: 8px; left: 12px; right: 12px; z-index: 1; pointer-events: none; }
/* 絵の上に直接のる文字なので、影を付けて明るい部分でも読めるようにする */
#talkStage { color: var(--gold); font-size: .78em; font-weight: 700; text-shadow: 0 1px 4px #000, 0 0 10px rgba(0,0,0,.9); }
#talkPlace { color: #cfe0d4; font-size: .66em; text-shadow: 0 1px 4px #000, 0 0 10px rgba(0,0,0,.9); }
#talkFace {
  position: absolute; right: 12px; bottom: 110px; z-index: 1; pointer-events: none;
  animation: talkFaceIn .3s ease-out;
}
#talkFace.hidden { display: none; }
/* アイコンを選んでいない人の札。絵と同じ大きさにして、枠が揺れないようにする */
.talkFaceNone {
  display: flex; align-items: center; justify-content: center;
  width: clamp(110px, 44vh, 240px); height: clamp(110px, 44vh, 240px);
  border-radius: 12px; border: 2px solid rgba(127,212,255,.5);
  background: linear-gradient(160deg, rgba(14,34,22,.95), rgba(6,16,11,.95));
  color: #9fd0ff; font-weight: 800; font-size: 1.05em; letter-spacing: .1em;
  box-shadow: 0 0 26px rgba(0,0,0,.7);
}
#talkFace img {
  width: clamp(110px, 44vh, 240px); height: clamp(110px, 44vh, 240px);
  border-radius: 12px; object-fit: cover; object-position: center top;
  border: 2px solid rgba(232,196,107,.55); box-shadow: 0 0 26px rgba(0,0,0,.7);
}
#talkBox {
  position: relative; z-index: 1;
  background: rgba(4,12,8,.92); border: 1px solid rgba(232,196,107,.45);
  border-radius: 12px; padding: 7px 12px 9px; min-height: 76px;
}
#talkName { color: var(--gold); font-weight: 800; font-size: .84em; }
#talkText { color: #f2ead6; font-size: .92em; line-height: 1.6; min-height: 2.9em; }
#talkBox.narration { background: rgba(2,6,4,.9); border-color: rgba(232,196,107,.2); }
#talkBox.narration #talkText { color: #cbd7cc; font-style: italic; }
#talkBox.meLine { border-color: rgba(127,212,255,.5); }
#talkBox.meLine #talkName { color: #9fd0ff; }
#talkHint {
  text-align: right; font-size: .64em; color: #cbbf9a;
  animation: callHintBlink 1.4s ease-in-out infinite;
}
.talkSkip {
  position: absolute; top: 6px; right: 10px; z-index: 2;
  background: rgba(10,26,18,.85); color: #cbbf9a;
  border: 1px solid rgba(232,196,107,.35); border-radius: 999px;
  padding: 3px 12px; font-size: .7em; cursor: pointer;
}
@keyframes talkFaceIn { from { opacity: 0; transform: translateX(18px); } to { opacity: 1; transform: none; } }

/* 終幕 */
/* 第3部の終わり方を選ぶ画面（2026-10-17）。
   終幕の手前に一度だけ出る。どちらも正解ではないので、片方を目立たせない
   (同じ大きさ・同じ色・同じ並び。おすすめの印も付けない) */
#part3Choice {
  position: fixed; inset: 0; z-index: 71;
  display: flex; align-items: center; justify-content: center;
  background: #020604; overflow-y: auto; padding: 12px;
}
#part3Choice.hidden { display: none; }
#part3ChoiceSky {
  position: absolute; inset: -20%;
  background:
    radial-gradient(circle at 50% 30%, rgba(232,196,107,.22), transparent 55%),
    radial-gradient(circle at 50% 80%, rgba(255,120,120,.14), transparent 55%);
}
#part3ChoiceBox {
  position: relative; width: min(680px, 100%);
  display: flex; flex-direction: column; gap: 10px; align-items: center;
  margin: auto; text-align: center;
}
#part3ChoiceQ { color: #e8c46b; font-size: 20px; margin: 0; }
#part3ChoiceList { display: flex; flex-direction: column; gap: 10px; width: 100%; }
.part3ChoiceBtn {
  display: flex; flex-direction: column; gap: 3px; align-items: center;
  width: 100%; padding: 10px 14px; height: auto; white-space: normal;
}
.part3ChoiceLabel { font-size: 17px; font-weight: 700; }
.part3ChoiceNote { font-size: 12px; opacity: .78; line-height: 1.5; }
#part3ChoiceNote { margin: 0; }
/* 画面が低いとき(スマホ横)は、2つとも見えることを優先して詰める */
@media (max-height: 420px) {
  #part3ChoiceQ { font-size: 17px; }
  .part3ChoiceBtn { padding: 7px 12px; }
  .part3ChoiceLabel { font-size: 15px; }
  .part3ChoiceNote { font-size: 11px; }
}

#storyEnding {
  position: fixed; inset: 0; z-index: 70;
  display: flex; align-items: center; justify-content: center;
  background: #020604; overflow: hidden;
}
#storyEnding.hidden { display: none; }
#endingSky {
  position: absolute; inset: -20%;
  background-size: cover; background-position: center;
  background:
    radial-gradient(circle at 30% 20%, rgba(232,196,107,.28), transparent 45%),
    radial-gradient(circle at 72% 70%, rgba(255,120,120,.2), transparent 45%),
    radial-gradient(circle at 50% 50%, rgba(127,212,255,.14), transparent 60%);
  animation: endingSway 12s ease-in-out infinite alternate;
}
@keyframes endingSway { from { transform: scale(1) rotate(0deg); } to { transform: scale(1.12) rotate(4deg); } }
/* 一枚絵を敷いたとき、文字が沈まないように暗い膜をかける */
#endingBox::before {
  content: ''; position: absolute; inset: -12px -18px; z-index: -1;
  background: radial-gradient(70% 70% at 50% 45%, rgba(2,6,4,.86), rgba(2,6,4,.55) 70%, transparent);
  border-radius: 20px;
}
#endingBox {
  position: relative; z-index: 1; text-align: center;
  max-width: min(92vw, 560px); max-height: 92vh; overflow-y: auto;
  padding: 10px 14px;
}
#endingTitle {
  font-size: clamp(1.6em, 7vh, 2.8em); font-weight: 900; color: var(--gold);
  letter-spacing: .18em; text-shadow: 0 0 22px rgba(232,196,107,.85);
  animation: endingTitleIn 1.1s cubic-bezier(.2,1.4,.3,1) both;
}
#endingSub { color: #cbbf9a; font-size: .74em; letter-spacing: .1em; margin-bottom: 6px; }
#endingBody { color: #f2ead6; font-size: .84em; line-height: 1.7; }
#endingBody p { margin: 3px 0; }
.endingFaces {
  display: flex; flex-wrap: wrap; gap: 3px; justify-content: center; margin: 8px 0 4px;
}
.endingFaces img {
  width: 34px; height: 34px; border-radius: 6px; object-fit: cover; object-position: center top;
  border: 1px solid rgba(232,196,107,.4);
  animation: endingFaceIn .5s ease-out both;
}
.endingFaces img:nth-child(n) { animation-delay: calc(var(--i, 0) * 40ms); }
.endingNote { color: #a8bfae; font-size: .72em; }
@keyframes endingTitleIn {
  from { opacity: 0; transform: scale(.7) translateY(14px); filter: blur(6px); }
  to { opacity: 1; transform: none; filter: none; }
}
@keyframes endingFaceIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  #endingSky, #endingTitle, .endingFaces img, #talkFace, #talkHint { animation: none; }
}

/* 最終結果のあとに出す「獲得ポイント」の画面 */
.gainBlock {
  background: rgba(10,26,18,.7); border: 1px solid rgba(232,196,107,.45);
  border-radius: 12px; padding: 8px 12px; margin: 8px 0;
}
.gainLabel { color: #a8bfae; font-size: .8em; }
.gainNum { color: var(--gold); font-size: 1.6em; font-weight: 800; line-height: 1.3; }
.gainDelta {
  margin-left: 10px; font-size: .62em; font-weight: 800;
  color: #9fe8a8; background: rgba(40,90,50,.5);
  border: 1px solid rgba(140,230,150,.55); border-radius: 999px; padding: 1px 10px;
  display: inline-block; vertical-align: middle;
}
.gainDelta.minus { color: #ffc0c0; background: rgba(120,40,40,.5); border-color: rgba(240,150,150,.55); }
.gainRank { color: #ffe9b0; font-size: .8em; margin-top: 2px; }

/* ============ タイトルのアイコン ============
   絵文字は端末ごとに絵柄も大きさも変わり、金色の画面から浮いてしまう。
   画面の中で描く形(SVG)にして、線の太さと色を卓の意匠にそろえる。 */
.ic {
  width: 1.25em; height: 1.25em; flex: 0 0 auto;
  vertical-align: -0.22em; color: inherit;
  filter: drop-shadow(0 0 4px rgba(232,196,107,.45));
}
/* タイトルの下段のアイコンは、金の円章に入れて「押せるもの」に見せる */
.linkbtn .ic, #btnOnline .ic {
  width: 1.95em; height: 1.95em; padding: 4px; box-sizing: border-box;
  border-radius: 50%;
  border: 1px solid rgba(232,196,107,.55);
  background: radial-gradient(circle at 50% 28%, rgba(232,196,107,.26), rgba(18,12,3,.55));
  box-shadow: 0 0 10px rgba(232,196,107,.28), inset 0 0 8px rgba(232,196,107,.14);
  vertical-align: middle;
  transition: box-shadow .2s, transform .2s;
}
.linkbtn:active .ic, #btnOnline:active .ic { transform: scale(.94); }
.linkbtn, #btnOnline, #loginBonus {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
}
.linkbtn { text-decoration: none; }
/* 下線はボタン全体ではなく文字だけに付ける(アイコンに線がかからないように) */
.linkbtn span { text-decoration: underline; text-underline-offset: 3px; }
.linkbtn:hover .ic, .linkbtn:active .ic { filter: drop-shadow(0 0 7px rgba(232,196,107,.9)); }
/* オンラインのボタンは押せる感じを出すため、少し大きめに */
/* オンラインのボタンは下地が明るいので、円章の色を濃いめにする */
#btnOnline .ic {
  border-color: rgba(232,196,107,.75);
  background: radial-gradient(circle at 50% 28%, rgba(40,28,6,.45), rgba(12,8,2,.72));
  color: var(--gold);
}

/* ============ 実績バッジ ============
   取ったものは金、まだのものは灰色。まだのものにも進み具合の帯を出して、
   「あと何回で取れるのか」がその場で分かるようにする。 */
.statsHead {
  color: var(--gold); font-size: 1.05em; margin: 14px 0 6px;
  border-bottom: 1px solid rgba(232,196,107,.35); padding-bottom: 4px;
}
.statsHead #badgeCount { color: #cfe0d4; font-size: .82em; font-weight: 600; margin-left: 6px; }
#badgeGrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 7px;
}
.badgeGroup {
  grid-column: 1 / -1; color: #a8bfae; font-size: .76em; font-weight: 700;
  margin: 6px 0 0; letter-spacing: .08em;
}
.badgeCard {
  background: rgba(10,26,18,.66); border: 1px solid rgba(160,170,160,.25);
  border-radius: 10px; padding: 7px 8px; text-align: center;
  color: #8b9a8e;
}
.badgeCard.got {
  color: var(--gold); border-color: rgba(232,196,107,.6);
  background: linear-gradient(180deg, rgba(60,46,10,.6), rgba(12,28,18,.7));
  box-shadow: 0 0 9px rgba(232,196,107,.2) inset;
}
.badgeIcon svg { width: 26px; height: 26px; color: inherit; }
.badgeCard.got .badgeIcon svg { filter: drop-shadow(0 0 5px rgba(232,196,107,.75)); }
.badgeName { font-weight: 800; font-size: .88em; line-height: 1.25; margin-top: 1px; }
.badgeNote { font-size: .68em; line-height: 1.3; opacity: .9; margin-top: 2px; }
.badgeBar {
  height: 3px; margin-top: 5px; border-radius: 999px;
  background: rgba(255,255,255,.12); overflow: hidden;
}
.badgeBar > div { height: 100%; background: linear-gradient(90deg, #7d6a2a, var(--gold)); }

/* 達成した瞬間の知らせ。ログインボーナスの帯とぶつからないよう少し下に出す */
#badgeToast {
  position: fixed; left: var(--safe-l); right: var(--safe-r);
  top: calc(52px + var(--safe-t)); margin: 0 auto; z-index: 92;
  width: -moz-fit-content; width: fit-content; max-width: 94vw;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(120,90,10,.96), rgba(60,42,4,.96));
  color: #fff6d8; border: 1px solid rgba(232,196,107,.9); border-radius: 999px;
  padding: 5px 16px; font-weight: 800; font-size: .92em; text-align: center;
  box-shadow: 0 2px 14px rgba(0,0,0,.55);
}
#badgeToast svg { width: 20px; height: 20px; color: var(--gold); flex: 0 0 auto; }
#badgeToast.pop { animation: badgePop 2400ms ease-out both; }
@keyframes badgePop {
  0% { opacity: 0; transform: translateY(-8px) scale(.85); }
  8% { opacity: 1; transform: translateY(0) scale(1.05); }
  14% { transform: scale(1); }
  86% { opacity: 1; transform: translateY(0) scale(1); }
  100% { opacity: 0; transform: translateY(-8px) scale(.96); }
}

/* ============ 隠し相手 ============
   条件を満たすまでは影だけを見せる。「まだ見ていない相手がいる」と分かることが
   段位を上げる理由になる。名前も★も伏せる。 */







.foeSelectCard.secret:not(.locked) {
  border-color: rgba(220,90,60,.8);
  box-shadow: 0 0 12px rgba(220,90,60,.35);
}
.foeSelectCard.secret:not(.locked) .foeSelectStars { color: #ff9a6b; }
#foeSelectHint.warn { color: #ffc98a; }

/* 解放したときの知らせ */
#unlockBanner {
  position: fixed; left: var(--safe-l); right: var(--safe-r);
  top: 14%; margin: 0 auto; z-index: 95;
  width: -moz-fit-content; width: fit-content; max-width: 92vw;
  display: flex; align-items: center; gap: 12px; pointer-events: none;
  background: linear-gradient(180deg, rgba(60,14,6,.96), rgba(22,8,3,.96));
  border: 2px solid rgba(232,120,70,.9); border-radius: 14px;
  padding: 10px 18px 10px 10px;
  box-shadow: 0 4px 26px rgba(0,0,0,.7), 0 0 22px rgba(232,120,70,.35);
  animation: unlockPop 620ms cubic-bezier(.2,1.4,.35,1) both;
}
#unlockBanner img {
  width: 64px; height: 64px; border-radius: 10px; object-fit: cover;
  border: 1px solid rgba(232,196,107,.7);
}
.unlockLead { color: #ffb289; font-size: .74em; font-weight: 700; letter-spacing: .08em; }
.unlockName { color: var(--gold); font-size: 1.25em; font-weight: 900; line-height: 1.2; }
.unlockNote { color: #e7d9c0; font-size: .7em; margin-top: 2px; }
@keyframes unlockPop {
  0% { opacity: 0; transform: scale(.8); }
  100% { opacity: 1; transform: scale(1); }
}

/* ============ 相手ごとの成績 ============ */
#foeStats { display: flex; flex-direction: column; gap: 5px; }
.foeStatRow {
  display: grid; grid-template-columns: 36px minmax(84px, auto) 1fr;
  align-items: center; gap: 8px;
  background: rgba(10,26,18,.66); border: 1px solid rgba(232,196,107,.25);
  border-radius: 10px; padding: 5px 9px;
}
.foeStatRow.none { opacity: .55; }
.foeStatRow img {
  width: 36px; height: 36px; border-radius: 8px; object-fit: cover;
  border: 1px solid rgba(232,196,107,.45);
}
.foeStatName { color: var(--gold); font-weight: 800; font-size: .86em; line-height: 1.2; }
.foeStatNums { display: flex; flex-wrap: wrap; gap: 4px 12px; }
.foeStatCell { color: #e7efe8; font-size: .76em; white-space: nowrap; }
.foeStatCell b { color: #a8bfae; font-weight: 600; margin-right: 5px; }
.foeStatNone { color: #8b9a8e; font-size: .76em; }

/* お店: 段位で解放する品 */
.shopPrice.locked { color: #8b9a8e; }
.shopRank {
  color: #ffc98a; font-size: .68em; font-weight: 700; margin-top: 1px;
}

/* ============ タイトルのコマンド一覧 ============
   「大きいボタン」と「小さな文字リンク」で見た目がばらばらだったので、
   全部を同じ形のコマンドにそろえる。どれも押せるものだと一目で分かる。
   横長の画面では2列、狭い画面では1列に落ちる。 */
#titleMenu {
  display: grid; gap: 6px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  width: min(620px, 94%);
  /* 入りきらないときは品書きの中だけを動かせるようにする。
     こうしておくと、下にある「なまえの札」が画面の外に出ない（2026-10-08） */
  min-height: 0;
  overflow-y: auto;
}
/* 一番上の「対局をはじめる」だけ横いっぱいに置いて、最初に目が行くようにする */
#titleMenu .cmdBtn.primary { grid-column: 1 / -1; }
/* 物語はメインの遊び方。横いっぱいに置き、アイコンと文字を大きくして目を引かせる */
#titleMenu .cmdBtn.featured { grid-column: 1 / -1; }
.cmdBtn.featured {
  padding: 8px 12px; gap: 12px;
  border-color: rgba(232,196,107,.85);
  box-shadow: 0 3px 14px rgba(232,196,107,.22);
}
.cmdBtn.featured .cmdIcon {
  width: 46px; height: 46px;
  border-color: rgba(232,196,107,.85);
  box-shadow: inset 0 0 10px rgba(232,196,107,.26), 0 0 12px rgba(232,196,107,.18);
}
.cmdBtn.featured .cmdIcon .ic { width: 30px; height: 30px; }
.cmdBtn.featured .cmdMain { font-size: 1.12em; }
.cmdBtn.featured .cmdSub { font-size: .74em; opacity: .85; }
.cmdBtn {
  display: flex; align-items: center; gap: 9px;
  width: 100%; text-align: left; cursor: pointer;
  padding: 6px 10px;
  border: 1px solid rgba(232,196,107,.55); border-radius: 11px;
  background: linear-gradient(180deg, rgba(24,38,28,.88), rgba(8,18,12,.92));
  color: #f3e7cb; font-family: inherit;
  box-shadow: 0 2px 10px rgba(0,0,0,.45);
  transition: border-color .15s, box-shadow .15s, transform .1s;
}
.cmdBtn.primary {
  border-color: rgba(232,196,107,.95);
  background: linear-gradient(180deg, rgba(232,196,107,.96), rgba(196,152,64,.96));
  color: #1b1405;
  box-shadow: 0 3px 16px rgba(232,196,107,.35);
}
.cmdBtn:hover { border-color: var(--gold); box-shadow: 0 3px 16px rgba(232,196,107,.4); }
.cmdBtn:active { transform: scale(.985); }
.cmdIcon {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 50%;
  border: 1px solid rgba(232,196,107,.6);
  background: radial-gradient(circle at 50% 28%, rgba(232,196,107,.26), rgba(18,12,3,.6));
  box-shadow: inset 0 0 8px rgba(232,196,107,.16);
}
.cmdBtn.primary .cmdIcon {
  border-color: rgba(60,42,8,.6);
  background: radial-gradient(circle at 50% 28%, rgba(60,44,10,.28), rgba(30,20,4,.55));
  color: #ffe9b0;
}
.cmdIcon .ic {
  width: 20px; height: 20px; border: 0; background: none; box-shadow: none;
  padding: 0; filter: none;
}
.cmdText { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.cmdMain { font-weight: 800; font-size: .96em; line-height: 1.25; }
.cmdSub { font-size: .68em; opacity: .78; line-height: 1.2; }
.cmdBtn.primary .cmdSub { opacity: .68; }
.cmdArrow { flex: 0 0 auto; opacity: .5; font-size: .9em; }

/* 幅ではなく「高さ」で決める。横持ちの端末は幅が狭くても高さがもっと狭いので、
   1列にすると縦にあふれて下のコマンドが押せなくなる。
   背が低いときは2列のまま小さくし、縦に長いときだけ1列に落とす。 */
@media (max-height: 420px) {
  #titleMenu { gap: 4px; width: min(560px, 96%); }
  .cmdBtn { padding: 4px 8px; gap: 6px; }
  .cmdIcon { width: 26px; height: 26px; }
  .cmdIcon .ic { width: 16px; height: 16px; }
  .cmdBtn.featured { padding: 5px 10px; gap: 9px; }
  .cmdBtn.featured .cmdIcon { width: 36px; height: 36px; }
  .cmdBtn.featured .cmdIcon .ic { width: 23px; height: 23px; }
  .cmdBtn.featured .cmdMain { font-size: 1em; }
  .cmdBtn.featured .cmdSub { font-size: .66em; }
  .cmdMain { font-size: .86em; }
  .cmdSub { font-size: .62em; }
  #titleArt { max-height: 22vh; }
}
/* 320pxの横画面に「前回の対局を再開」が増えると、コマンドが11pxはみ出して
   一番下の「腕だめし」が押せなくなる。この高さではさらに詰める。 */
@media (max-height: 340px) {
  #titleMenu { gap: 3px; }
  .cmdBtn { padding: 3px 8px; }
  .cmdIcon { width: 24px; height: 24px; }
  .cmdIcon .ic { width: 15px; height: 15px; }
  .cmdBtn.featured { padding: 3px 10px; }
  .cmdBtn.featured .cmdIcon { width: 32px; height: 32px; }
  .cmdBtn.featured .cmdIcon .ic { width: 20px; height: 20px; }
  #titleArt { max-height: 18vh; }
}
@media (max-width: 620px) and (min-height: 560px) {
  #titleMenu { grid-template-columns: 1fr; gap: 4px; width: min(420px, 96%); }
  .cmdBtn { padding: 5px 9px; gap: 7px; }
  .cmdIcon { width: 27px; height: 27px; }
  .cmdIcon .ic { width: 17px; height: 17px; }
}

/* ============ まだ出していない相手(伏せ札) ============
   真っ黒にすると「空のカード」に見えてしまうので、姿が分かるだけの影にする。
   色を抜いて暗く落とし、明暗の差だけ強く残すと、誰なのかは分からないまま
   「人がいる」ことだけが伝わる。名前と強さは伏せ、代わりに出す条件を書く。 */
.foeSelectCard.locked {
  position: relative;
  border-color: rgba(200,90,60,.55);
  box-shadow: 0 0 10px rgba(200,70,50,.18) inset;
}
/* 画像そのものが影絵なので、ここでは暗くしない
   (二重に暗くすると、また真っ黒に潰れる) */
.foeSelectCard.locked img { filter: none; }
/* 影の上に薄い墨をかけて、下に書く条件を読みやすくする */
.foeSelectCard.locked::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(4,8,6,.93) 40%, rgba(4,8,6,.35) 68%, rgba(4,8,6,0));
}
/* 強さは伏せるので出さない。そのぶん条件に行を使う */
.foeSelectCard.locked .foeSelectStars { display: none; }
.foeSelectCard.locked .cardLabel {
  padding: 10px 4px 4px; background: none;
}
.foeSelectCard.locked .foeSelectName {
  color: #cfd8d0; letter-spacing: .16em; font-size: .78em;
  text-shadow: 0 1px 4px #000;
}
.foeLockNote {
  /* 相手が増えるとカードは小さくなる。文字を固定にすると、
     狭い画面で条件がカードからあふれて読めなくなる */
  font-size: max(7px, calc(var(--card, 110px) * .092));
  line-height: 1.28; color: #ffcf96; text-align: center;
  margin-top: 1px; text-shadow: 0 1px 4px #000, 0 0 8px #000;
  white-space: normal; word-break: break-word;
}
/* 相手が増えるとカードは小さくなる。名前も強さもカードの大きさに合わせる。
   固定にすると、人数が増えた日に名前が「…」で切れ、★が2行に折り返す */
#table ~ * .foeSelectName, #foeGrid .foeSelectName {
  font-size: max(8px, calc(var(--card, 110px) * .105));
}
#foeGrid .foeSelectStars {
  font-size: max(8px, calc(var(--card, 110px) * .098));
  white-space: nowrap;
}
.foeSelectCard.locked .cardLabel { padding: 6px 3px 3px; }

/* 名札は枠をはみ出さない範囲でできるだけ広く取る。
   名前の長い相手(「雀鬼の虎次郎」など)でも最後まで読めるようにする。 */
#table .cornerRight .seatLabel,
#table .cornerLeft .seatLabel,
#table .nameTop .seatLabel {
  padding: 1px 6px;
}

/* ============ 人物録 ============
   倒した相手だけが載る。まだの相手は影絵のまま。
   一覧 → 名前を押す → その人の素性、の2画面で切り替える。 */
#dexPanel {
  position: fixed; inset: 0; z-index: 80;
  background: linear-gradient(180deg, #0a1410, #050b08);
  display: flex; flex-direction: column; gap: 8px;
  padding: calc(10px + var(--safe-t)) calc(10px + var(--safe-r))
           calc(10px + var(--safe-b)) calc(10px + var(--safe-l));
}
#dexPanel h2 { margin: 0; color: var(--gold); }
#dexCount { color: #cfe0d4; font-size: .7em; font-weight: 600; margin-left: 6px; }
#dexScroll { flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; min-height: 0; }
#dexGrid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 6px; margin-top: 6px;
}
.dexCard {
  position: relative; overflow: hidden; cursor: pointer;
  background: rgba(18,32,24,.9); border: 1px solid rgba(232,196,107,.45);
  border-radius: 10px; padding: 5px; text-align: center;
  transition: border-color .15s, box-shadow .15s, transform .1s;
}
.dexCard:hover { border-color: var(--gold); box-shadow: 0 0 10px rgba(232,196,107,.3); }
.dexCard:active { transform: scale(.98); }
.dexCard img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover; object-position: center top;
  border-radius: 8px; display: block;
}
.dexName { color: var(--gold); font-weight: 800; font-size: .78em; margin-top: 3px; line-height: 1.2; }
.dexStars { color: var(--gold); font-size: .7em; letter-spacing: .02em; }
/* まだ倒していない相手 */
.dexCard.locked { cursor: default; border-color: rgba(160,170,160,.3); }
.dexCard.locked:hover { border-color: rgba(160,170,160,.3); box-shadow: none; }
.dexCard.locked .dexName { color: #8b9a8e; letter-spacing: .14em; }
.dexCard.locked .dexStars { color: #6d7a70; letter-spacing: .1em; }
.dexLockNote { color: #ffc98a; font-size: .64em; margin-top: 1px; }

/* 1人ぶんの紹介。左に大きな顔、右に文章。狭い画面では上下に積む */
#dexDetail {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  display: flex; gap: 14px; align-items: center;
}
/* 顔は「画面の高さ」で決める。横幅だけで決めると、背の低い横持ちでは
   上に寄って下が大きく余り、顔も小さいままになる */
.dexFace { flex: 0 0 auto; width: min(36vw, 62vh); }
.dexFace img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover; object-position: center top;
  border-radius: 14px; border: 2px solid rgba(232,196,107,.75); display: block;
  box-shadow: 0 4px 22px rgba(0,0,0,.6), 0 0 18px rgba(232,196,107,.2);
}
.dexBody { flex: 1 1 auto; min-width: 0; }
.dexTitle { color: #ffc98a; font-size: .78em; font-weight: 700; letter-spacing: .06em; }
.dexBigName { color: var(--gold); font-size: 1.5em; font-weight: 900; line-height: 1.15; }
.dexBigStars { color: var(--gold); font-size: .95em; letter-spacing: .04em; margin-bottom: 4px; }
.dexStory { color: #e7efe8; font-size: .8em; line-height: 1.55; margin: 4px 0; }
.dexSec {
  color: #e7efe8; font-size: .78em; line-height: 1.5; margin-top: 5px;
  background: rgba(10,26,18,.66); border: 1px solid rgba(232,196,107,.3);
  border-radius: 9px; padding: 5px 9px;
}
.dexSec b { color: #a8bfae; font-weight: 600; margin-right: 7px; }
.dexLine {
  color: #ffe9b0; font-size: .92em; font-weight: 700; font-style: italic;
  margin-top: 7px; text-shadow: 0 1px 4px #000;
}
.dexRec { display: flex; flex-wrap: wrap; gap: 3px 12px; margin-top: 7px; }
.dexRec span { color: #e7efe8; font-size: .74em; white-space: nowrap; }
.dexRec b { color: #a8bfae; font-weight: 600; margin-right: 5px; }

/* 背の低い横持ちでは顔を小さくして、文章が読める幅を確保する */
@media (max-height: 420px) {
  .dexBigName { font-size: 1.3em; }
  .dexStory { font-size: .76em; line-height: 1.5; }
}
/* とても背の低い画面では、二つ名と余白を削って本文を収める */
@media (max-height: 340px) {
  .dexFace { width: min(32vw, 54vh); }
  .dexBigName { font-size: 1.1em; }
  .dexStory { font-size: .7em; line-height: 1.4; margin: 2px 0; }
  .dexSec { font-size: .7em; line-height: 1.3; padding: 3px 7px; margin-top: 3px; }
  /* 裏の顔の欄が増えたぶん、背の低い画面ではもう少し詰める（2026-10-08）。
     紹介は1画面に収まるのが決まりなので、行を足したら必ずどこかを削る */
  .dexSec { margin-top: 2px; padding: 2px 7px; }
  .dexTitle { font-size: .72em; }
  .dexBigStars { font-size: .8em; letter-spacing: 0; line-height: 1.25; }
  /* まだ開いていない人の案内は、背の低い画面では枠を外して1行の添え書きにする。
     紹介を1画面に収める決まりを守りつつ、存在だけは必ず伝える */
  .dexUra.locked, .dexSugao.locked { border: none; background: none; padding: 0 0 0 2px; margin-top: 3px; }
  .dexLine { font-size: .82em; margin-top: 3px; }
  .dexRec { margin-top: 3px; gap: 2px 10px; }
  .dexRec span { font-size: .68em; }
  #dexPanel h2 { font-size: 1.1em; }
}

/* ============ 遊び方・ルール ============
   話題ごとのコマンド一覧 → 選んだ話題だけを大きく読む、の2段。 */
#helpPanel h2 { margin: 0; color: var(--gold); flex: 0 0 auto; }
#helpMenu {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
  width: 100%; max-width: 900px;
  display: grid; gap: 6px; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  align-content: start; padding: 2px;
}
.helpCmd { text-align: left; }
#helpBody {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
  width: 100%; max-width: 760px; color: #e7efe8;
}
#helpBody p { margin: 6px 0; font-size: .86em; line-height: 1.65; }
#helpBody b { color: var(--gold); }
#helpBody .yakuTable { margin: 8px 0; }
.helpList { margin: 6px 0 6px 1.2em; padding: 0; font-size: .86em; line-height: 1.7; }
.helpList li { margin: 2px 0; }
.helpOk {
  background: rgba(10,26,18,.72); border: 1px solid rgba(140,220,160,.4);
  border-radius: 10px; padding: 7px 10px; color: #cfe8d4;
}
@media (max-height: 420px) {
  #helpMenu { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
  #helpBody p, .helpList { font-size: .8em; line-height: 1.55; }
}

/* ============ ルール説明の図 ============
   対局で使っているのと同じ牌の絵を並べる。別に図を描かないので、
   役を足しても図が古くならないし、説明の牌と卓の牌が食い違わない。 */
.figBox { margin: 8px 0; display: flex; flex-direction: column; gap: 7px; }
.figRow {
  background: rgba(10,26,18,.6); border: 1px solid rgba(232,196,107,.28);
  border-radius: 10px; padding: 6px 9px;
}
.figName { color: var(--gold); font-weight: 800; font-size: .8em; margin-bottom: 3px; }
.figNote { color: #a8bfae; font-size: .7em; line-height: 1.4; margin-top: 3px; }

/* ---------- 相手が鳴いたときのタップ待ちの帯 ----------
   画面のいちばん下、操作ボタンの行にぴったり重ねて出す(相手が鳴いている間は
   自分の操作ボタンが無いので、その行はまるごと空いている)。
   高さをその行ぴったりに縛ってあるのが大事で、これより高いと上の手牌を隠してしまう。 */
#callPause {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 45;
  height: calc(var(--u) * 1.26 + 6px + env(safe-area-inset-bottom, 0px));
  box-sizing: border-box; overflow: hidden;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  padding: 2px calc(env(safe-area-inset-right, 0px) + 10px) calc(env(safe-area-inset-bottom, 0px) + 2px)
    calc(env(safe-area-inset-left, 0px) + 10px);
  background: #071711;
  border-top: 1px solid rgba(232,196,107,.45);
  box-shadow: 0 -6px 14px rgba(0,0,0,.5);
  animation: callPauseIn .22s ease-out;
  pointer-events: none;
}
#callPause.hidden { display: none; }

/* これから鳴かれる牌。タップ待ちの間だけ河に残して、赤枠と明滅で示す。
   「どの牌でポンなのか」が分からないまま卓が動いてしまう、という指摘への対応。 */
.tile.calledNowMark {
  outline: 2px solid #ff5f5f;
  outline-offset: -1px;
  border-radius: 3px;
  box-shadow: 0 0 10px rgba(255,95,95,.95), 0 0 20px rgba(255,95,95,.5);
  animation: calledNowPulse .85s ease-in-out infinite;
  position: relative; z-index: 2;
}
@keyframes calledNowPulse {
  0%, 100% { box-shadow: 0 0 8px rgba(255,95,95,.8), 0 0 16px rgba(255,95,95,.35); }
  50% { box-shadow: 0 0 16px rgba(255,95,95,1), 0 0 28px rgba(255,95,95,.65); }
}
@media (prefers-reduced-motion: reduce) {
  .tile.calledNowMark { animation: none; }
}
#callPauseInner {
  display: flex; align-items: center; gap: 5px;
  font-size: .86em; color: #f2ead6; white-space: nowrap;
}
#callPauseInner .cpWho { display: flex; align-items: center; gap: 5px; }
#callPauseInner .cpWho img {
  width: calc(var(--u) * .9); height: calc(var(--u) * .9); border-radius: 6px; object-fit: cover;
  border: 1px solid rgba(232,196,107,.5);
}
#callPauseInner b { color: var(--gold); }
#callPauseInner .cpFromName { color: #9fd0ff; }
#callPauseInner .cpFrom { color: #a8bfae; font-size: .9em; }
#callPauseInner .cpKind {
  color: #10240f; background: var(--gold); font-weight: 800;
  padding: 1px 8px; border-radius: 999px; font-size: .95em;
}
/* 鳴かれた牌。卓の牌より少し大きくして、どれを鳴いたのかを一目で分かるようにする */
/* 帯は操作ボタンの行ぴったりの高さしかないので、中身もその中に収める */
#callPauseInner .cpTile { width: calc(var(--u) * .78); height: calc(var(--u) * 1.07); flex: 0 0 auto; }
#callPauseInner .cpTile img { width: 100%; height: 100%; display: block; }
#callPauseHint {
  font-size: .68em; color: #cbbf9a; opacity: .85; white-space: nowrap;
  animation: callHintBlink 1.4s ease-in-out infinite;
}
@keyframes callPauseIn { from { transform: translateY(100%); } to { transform: none; } }
@keyframes callHintBlink { 0%, 100% { opacity: .35; } 50% { opacity: .95; } }
/* 背の低い横画面では1行に収める */
@media (max-height: 360px) {
  #callPauseInner { font-size: .76em; gap: 4px; }
  #callPauseInner .cpWho img { width: 20px; height: 20px; }
  #callPauseInner .cpTile { width: 18px; height: 25px; }
  #callPauseHint { font-size: .62em; }
}
@media (prefers-reduced-motion: reduce) {
  #callPause { animation: none; }
  #callPauseHint { animation: none; opacity: .85; }
}
/* 役の成立条件。図の上に置く。牌の形が同じで状況だけ違う役はここでしか区別できないので、
   注記(figNote)より読みやすい明るさ・大きさにする */
.figYakuDesc {
  color: #dbe8dd; font-size: .76em; line-height: 1.55;
  margin: 2px 0 5px; padding-left: 7px;
  border-left: 2px solid rgba(232,196,107,.45);
}
.figTiles { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 2px; }
/* 説明の牌は卓の牌より小さくてよい。1行に14枚入る大きさにする */
.figTiles .tile { width: 22px; height: 30px; flex: 0 0 auto; }
.figTiles .tile img { width: 100%; height: 100%; display: block; }
/* 横向き(鳴いた牌)。場所を取らないよう、幅と高さを入れ替える */
.figTiles .tile.figSide { width: 30px; height: 22px; align-self: flex-end; }
.figTiles .tile.figSide img { transform: rotate(90deg) scale(1.363); }
/* 和了牌は光らせる */
.figTiles .tile.figWin {
  outline: 2px solid var(--gold); outline-offset: 1px; border-radius: 3px;
  box-shadow: 0 0 8px rgba(232,196,107,.65);
}
.figGap { width: 10px; flex: 0 0 auto; }
.figArrow { color: var(--gold); font-size: .74em; font-weight: 700; margin: 0 5px; align-self: center; }
/* 役の行は名前と翻数を横に並べる */
.figYakuHead { display: flex; align-items: baseline; gap: 8px; margin-bottom: 3px; }
.figYakuHead b { color: var(--gold); font-size: .88em; }
.figYakuHead span { color: #cfe0d4; font-size: .7em; }
@media (max-height: 420px) {
  .figTiles .tile { width: 19px; height: 26px; }
  .figTiles .tile.figSide { width: 26px; height: 19px; }
}

/* ============ 「端末を横にしてください」 ============
   横向きで遊ぶゲームなので、縦持ちのあいだはこれだけを出す。
   中身を90度回して見せる作りもあるが、文字が体の向きと合わず読みにくい。 */
#rotateGate {
  position: fixed; inset: 0; z-index: 200;
  background: linear-gradient(180deg, #0a1410, #04100a);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; text-align: center;
  padding: calc(24px + var(--safe-t)) calc(24px + var(--safe-r))
           calc(24px + var(--safe-b)) calc(24px + var(--safe-l));
}
#rotateIcon {
  width: min(38vw, 150px); height: auto; color: var(--gold);
  filter: drop-shadow(0 0 14px rgba(232,196,107,.4));
  animation: rotateHint 2.4s ease-in-out infinite;
}
@keyframes rotateHint {
  0%, 55% { transform: rotate(0deg); }
  75%, 92% { transform: rotate(-90deg); }
  100% { transform: rotate(0deg); }
}
#rotateMain { color: var(--gold); font-size: 1.35em; font-weight: 900; line-height: 1.3; }
#rotateSub { color: #e7efe8; font-size: .92em; line-height: 1.7; }
#rotateLock { color: #a8bfae; font-size: .78em; line-height: 1.6; }
/* 案内を出しているあいだは、うしろを触れないようにする */
body.waitingRotate #title, body.waitingRotate #game { pointer-events: none; }

/* ============ 腕だめし(5問クイズ) ============ */
#quizPanel {
  position: fixed; inset: 0; z-index: 80;
  background: linear-gradient(180deg, #0a1410, #050b08);
  display: flex; flex-direction: column; gap: 6px;
  padding: calc(10px + var(--safe-t)) calc(10px + var(--safe-r))
           calc(10px + var(--safe-b)) calc(10px + var(--safe-l));
}
#quizHead { display: flex; align-items: baseline; gap: 12px; flex: 0 0 auto; }
#quizHead h2 { margin: 0; color: var(--gold); }
#quizCount { color: #cfe0d4; font-size: .8em; }
#btnQuizClose { margin-left: auto; color: #a8bfae; font-size: .82em; }
#quizBody {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch;
  width: 100%; max-width: 760px; margin: 0 auto; color: #e7efe8;
}
.quizLead { font-size: .88em; line-height: 1.7; margin: 6px 0; }
.quizSmall { font-size: .76em; color: #a8bfae; }
.quizPrompt { color: var(--gold); font-weight: 800; font-size: 1em; margin: 4px 0 7px; }
.quizTiles { justify-content: center; margin-bottom: 3px; }
/* 問題の牌は説明の図より大きく。ここは読み取りが本題なので */
.quizTiles .tile { width: 30px; height: 41px; }
.quizNote { color: #a8bfae; font-size: .7em; text-align: center; margin-bottom: 6px; }
.quizChoices {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; margin-top: 8px;
}
.quizChoice {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 10px; cursor: pointer; font-family: inherit;
  background: linear-gradient(180deg, rgba(24,38,28,.9), rgba(8,18,12,.94));
  border: 1px solid rgba(232,196,107,.5); border-radius: 11px;
  color: #f3e7cb; font-weight: 700; font-size: .92em;
  transition: border-color .15s, transform .1s;
}
.quizChoice .tile { width: 24px; height: 33px; flex: 0 0 auto; }
.quizChoice:hover:not(:disabled) { border-color: var(--gold); }
.quizChoice:active:not(:disabled) { transform: scale(.98); }
.quizChoice:disabled { cursor: default; opacity: .75; }
.quizChoice.right {
  border-color: rgba(140,230,150,.9); background: rgba(30,70,38,.9);
  color: #d8ffdd; opacity: 1;
}
.quizChoice.wrong {
  border-color: rgba(240,140,140,.9); background: rgba(80,26,26,.9); color: #ffd8d8; opacity: 1;
}
.quizFeedback {
  margin-top: 9px; padding: 8px 11px; border-radius: 10px;
  font-size: .82em; line-height: 1.6;
}
.quizFeedback b { display: block; font-size: 1.1em; margin-bottom: 2px; }
.quizFeedback.ok { background: rgba(20,54,28,.8); border: 1px solid rgba(140,230,150,.5); color: #d8ffdd; }
.quizFeedback.ok b { color: #9fe8a8; }
.quizFeedback.no { background: rgba(60,20,20,.8); border: 1px solid rgba(240,150,150,.5); color: #ffe0e0; }
.quizFeedback.no b { color: #ffb0b0; }
.quizScore { color: #e7efe8; font-size: 1.15em; text-align: center; margin: 14px 0 6px; }
.quizScore b { color: var(--gold); font-size: 1.7em; }
.quizGain {
  text-align: center; color: #9fe8a8; font-weight: 800; font-size: 1.05em;
}
@media (max-height: 420px) {
  .quizTiles .tile { width: 25px; height: 34px; }
  .quizChoice { padding: 6px 8px; font-size: .84em; }
  .quizChoice .tile { width: 20px; height: 27px; }
  .quizLead, .quizFeedback { font-size: .76em; }
}

/* ============ 回転ロック中の逃げ道 ============
   Android は端末に横向きを頼めるが、iPhone(Safari)はその仕組みが無い。
   そこで、自分で選んだときだけ画面の中身を90度回して見せる。
   既定では回さない(文字が体の向きと合わず読みにくいため)。 */
body.cssRotate {
  position: fixed;
  top: 0; left: 0;
  width: 100vh;
  height: 100vw;
  transform: rotate(90deg) translateY(-100%);
  transform-origin: top left;
}
/* 回して見せているあいだは、端末の上下左右が中身の左右上下に入れ替わる */
body.cssRotate {
  --safe-l: env(safe-area-inset-top, 0px);
  --safe-r: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-right, 0px);
  --safe-b: env(safe-area-inset-left, 0px);
}
body.cssRotate #foeSelectPanel, body.cssRotate #myAvatarPanel { padding: 4px 8px; }

#btnRotateAnyway {
  margin-top: 4px; padding: 9px 22px; font-size: .92em;
  max-width: 80vw;
}
#rotateHint { color: #9fe8a8; font-size: .78em; line-height: 1.5; min-height: 1em; }


/* ---------- ネットで対戦(自動マッチング)の待機画面 ---------- */
/* 横向きの狭い画面でも全部入るように、縦に積んで中央に寄せるだけにしてある */
#autoMatchPanel {
  position: fixed;
  inset: 0;
  /* ログインボーナスの帯(z-index 90)より上に置く。下だと帯が画面にかぶる */
  z-index: 94;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(circle at 50% 35%, #1b3326, #0b1710 70%);
  padding: 10px calc(10px + env(safe-area-inset-right)) calc(10px + env(safe-area-inset-bottom)) calc(10px + env(safe-area-inset-left));
  box-sizing: border-box;
}
#autoMatchPanel.hidden { display: none; }
#autoMatchBox {
  width: min(560px, 100%);
  max-height: 100%;
  overflow: auto;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: center;
}
#autoMatchBox h2 {
  margin: 0;
  font-size: clamp(15px, 4.2vh, 22px);
  color: var(--gold);
  letter-spacing: 0.08em;
}
#autoMatchCount {
  font-size: clamp(26px, 9vh, 52px);
  font-weight: 800;
  color: #fff;
  line-height: 1.1;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.6);
}
#autoMatchDots { display: flex; gap: 8px; justify-content: center; }
#autoMatchDots .amDot {
  width: clamp(10px, 2.4vh, 16px);
  height: clamp(10px, 2.4vh, 16px);
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.35);
  background: rgba(255, 255, 255, 0.08);
}
#autoMatchDots .amDot.on {
  background: var(--gold);
  border-color: var(--gold);
  box-shadow: 0 0 8px rgba(226, 184, 94, 0.7);
}
#autoMatchNote {
  font-size: clamp(11px, 2.8vh, 15px);
  color: #e9e3d2;
  min-height: 1.4em;
}
/* 探しているあいだ、文字がゆっくり明滅して「止まっていない」ことを見せる */
#autoMatchNote.searching { animation: amPulse 1.8s ease-in-out infinite; }
@keyframes amPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
#autoMatchNames {
  font-size: clamp(10px, 2.4vh, 13px);
  color: #bfe6c9;
  min-height: 1.2em;
}
#autoMatchSub {
  font-size: clamp(10px, 2.2vh, 12px);
  color: #9fb3a5;
}
#btnAutoMatchLeave { margin-top: 4px; min-width: 180px; }
@media (max-height: 340px) {
  #autoMatchBox { gap: 3px; }
  #autoMatchSub { display: none; }
}

/* 点数画面に添える一言(アガリやめなど)。結果の数字より控えめに出す */
.win-note {
  margin: 4px 0 2px;
  font-size: max(10px, calc(var(--u) * 0.46));
  color: var(--gold);
  text-align: center;
}


/* ---------- なまえとID ---------- */
#titleFoot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;
}
.nameChip {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 2px 10px;
  border-radius: 999px;
  border: 1px solid rgba(226, 184, 94, 0.45);
  background: rgba(0, 0, 0, 0.3);
  color: #efe7d4;
  font-size: max(10px, 1.6vh);
  cursor: pointer;
}
.nameChip:active { background: rgba(226, 184, 94, 0.18); }
#nameChipName { font-weight: 700; }
#nameChipId { opacity: 0.7; font-size: 0.85em; letter-spacing: 0.04em; }

#namePanel {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(circle at 50% 35%, #1b3326, #0b1710 70%);
  padding: 10px calc(10px + env(safe-area-inset-right)) calc(10px + env(safe-area-inset-bottom)) calc(10px + env(safe-area-inset-left));
  box-sizing: border-box;
}
#namePanel.hidden { display: none; }
#nameBox {
  width: min(520px, 100%);
  max-height: 100%;
  overflow: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
}
#nameBox h2 { margin: 0; color: var(--gold); font-size: clamp(15px, 4vh, 21px); }
#nameLead, #nameIdNote {
  margin: 0;
  font-size: clamp(10px, 2.3vh, 13px);
  color: #cfd9d0;
  line-height: 1.5;
}
#nameIdNote { color: #9fb3a5; }
#nameInput {
  width: min(320px, 90%);
  font-size: clamp(15px, 3.6vh, 20px);
  text-align: center;
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid rgba(226, 184, 94, 0.5);
  background: rgba(0, 0, 0, 0.35);
  color: #fff;
  box-sizing: border-box;
}
/* 二つ名。物語を突破すると増える（2026-10-23）。
   数が増えても縦に伸びるだけで、名前を決める画面がはみ出さないように折り返す */
#nameTitlesRow { width: 100%; display: flex; flex-direction: column; gap: 5px; align-items: center; }
#nameTitlesLead { font-size: 12px; color: #e8c46b; opacity: .85; }
#nameTitlesList { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }
.nameTitleBtn {
  font-size: 12px; padding: 4px 10px; border-radius: 999px;
  border: 1px solid rgba(232,196,107,.45); background: rgba(255,255,255,.04);
  color: #f0e6cf; cursor: pointer;
}
.nameTitleBtn.on { background: rgba(232,196,107,.22); border-color: #e8c46b; font-weight: 700; }
@media (max-height: 420px) {
  #nameTitlesLead { font-size: 11px; }
  .nameTitleBtn { font-size: 11px; padding: 3px 8px; }
}
#nameIdRow {
  font-size: clamp(11px, 2.6vh, 14px);
  color: #e9e3d2;
  letter-spacing: 0.06em;
}
#nameIdRow b { color: var(--gold); }
#nameBtnRow { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
#nameBtnRow .bigbtn { min-width: 160px; }
@media (max-height: 340px) {
  #nameBox { gap: 3px; }
  #nameIdNote { display: none; }
}

/* オンライン画面の「あなた」の行 */
#onlineWho {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: max(11px, 1.8vh);
  color: #e9e3d2;
}
#onlineWhoId { opacity: 0.7; font-size: 0.85em; }
.smallbtn {
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid rgba(226, 184, 94, 0.5);
  background: rgba(0, 0, 0, 0.3);
  color: #efe7d4;
  font-size: 0.9em;
  cursor: pointer;
}


/* ---------- 人物録の「裏の顔」 ---------- */
/* 素性・信条より一段奥なので、金の縁取りで別格に見せる。
   まだ開いていない人には、open条件だけを出して中身は渡さない */
.dexUra {
  border-left: 2px solid var(--gold);
  padding-left: 8px;
  background: linear-gradient(90deg, rgba(226, 184, 94, 0.09), rgba(226, 184, 94, 0));
}
.dexUra .uraTitle {
  display: block;
  color: var(--gold);
  font-weight: 700;
  margin: 2px 0 1px;
}
.dexUra .uraText { display: block; }
.dexUra.locked {
  border-left-color: rgba(226, 184, 94, 0.35);
  background: none;
}
/* まだ開いていない人の案内は、見出しと同じ行に置く。
   行を増やすと、狭い画面で紹介が1画面に収まらなくなる */
.dexUra .uraLock {
  opacity: 0.65;
  font-size: 0.95em;
}
.dexUra.locked { padding-left: 8px; }
/* 素顔。裏の顔より奥なので、因縁の卓と同じ紅で分ける */
.dexSugao {
  border-left: 2px solid #e8a08f;
  padding-left: 8px;
  background: linear-gradient(90deg, rgba(200, 90, 70, 0.11), rgba(200, 90, 70, 0));
}
.dexSugao .uraTitle { display: block; color: #e8a08f; font-weight: 700; margin: 2px 0 1px; }
.dexSugao .uraText { display: block; }
.dexSugao.locked { border-left-color: rgba(232, 160, 143, 0.35); background: none; }
.dexSugao .uraLock { opacity: 0.65; font-size: 0.95em; }
.dexUraCount { font-size: .72em; color: var(--gold); opacity: .85; margin-left: 4px; }


/* ---------- その局のドラ ---------- */
/* 自分の手にあるあいだだけ、黄色い枠で示す。
   outline は場所を取らないので、牌の並びがずれない(border だと1枚ぶん太る)。
   内側に寄せているのは、3pxしか離れていない隣の牌と枠がくっついて見えないようにするため。
   リーチの候補(赤や金の枠)が出ているときは、そちらのほうが急ぎの情報なので上書きさせる */
.tile.doraTile {
  outline: 2px solid #ffd93b;
  outline-offset: -2px;
  border-radius: 3px;
}
#myHand .tile.doraTile { outline-width: 2px; }


/* ---------- お店の二つ名・和了演出・カットイン（2026-10-28） ---------- */
/* タブが6つになったので、狭い画面では字を詰める */
#shopTabs .shopTab { white-space: nowrap; min-width: 0; }
@media (max-width: 700px) { #shopTabs { gap: 4px; } #shopTabs .shopTab { font-size: .82em; padding: 6px 2px; } }

.shopPreview.namePrev {
  flex-direction: column; gap: 0; line-height: 1.1;
  background: linear-gradient(180deg, #1b2c22, #0e1a14);
}
.shopPreview.namePrev span { font-size: .72em; color: var(--gold); min-height: 1em; }
.shopPreview.namePrev b { font-size: .9em; color: #f3ead6; }

/* 和了演出の粒。形と色だけで描く */
.fxBit { position: absolute; display: block; pointer-events: none; }
.fxBit.fxFall {
  top: -24px;
  animation-name: fxFall; animation-timing-function: linear; animation-fill-mode: forwards;
}
.fxBit.fxRise { top: auto; bottom: -24px; animation-name: fxRise; animation-timing-function: ease-out; }
@keyframes fxFall {
  0% { transform: translate(0, 0) rotate(0deg); opacity: 1; }
  100% { transform: translate(var(--sway, 0), 112vh) rotate(var(--spin, 540deg)); opacity: .8; }
}
@keyframes fxRise {
  0% { transform: translate(0, 0); opacity: 0; }
  15% { opacity: 1; }
  100% { transform: translate(var(--sway, 0), -90vh); opacity: 0; }
}
.fxBit.fx_sakura { background: radial-gradient(circle at 30% 30%, #fff0f5, #f7a8c4 60%, #e77fa6); border-radius: 0 100% 0 100%; }
.fxBit.fx_yuki { background: radial-gradient(circle, #fff 35%, rgba(255,255,255,.55) 60%, rgba(255,255,255,0) 72%); border-radius: 50%; }
.fxBit.fx_hibana { background: radial-gradient(circle, #fff6c2 20%, #ffb43a 50%, rgba(255,80,20,0) 72%); border-radius: 50%; }
.fxBit.fx_hotaru { background: radial-gradient(circle, #f6ffc8 18%, rgba(190,255,120,.75) 40%, rgba(150,255,100,0) 70%); border-radius: 50%; }
.fxBit.fx_hoshi {
  background: linear-gradient(135deg, #fff7d1, #e8c46b 55%, #c9d3e6);
  clip-path: polygon(50% 0, 61% 38%, 100% 38%, 68% 61%, 79% 100%, 50% 76%, 21% 100%, 32% 61%, 0 38%, 39% 38%);
}
.fxBit.fx_std { background: linear-gradient(135deg, #fff2b8, #e8c46b 60%, #a67c2a); border-radius: 2px; }
/* お店の見本: 枠の中で小さくくり返す */
.shopPreview.fxPrev { position: relative; background: linear-gradient(180deg, #0f1c15, #08110c); }
.shopPreview.fxPrev .fxBit { top: -10px; width: 9px; height: 9px; animation: fxPrevFall 1.6s linear infinite; }
.shopPreview.fxPrev .fxBit.fx_hibana { width: 6px; height: 6px; }
.shopPreview.fxPrev .fxBit.fx_hotaru { top: auto; bottom: -10px; animation-name: fxPrevRise; }
@keyframes fxPrevFall { from { transform: translateY(0) rotate(0); } to { transform: translateY(48px) rotate(300deg); } }
@keyframes fxPrevRise { 0% { transform: translateY(0); opacity: 0; } 30% { opacity: 1; } 100% { transform: translateY(-46px); opacity: 0; } }

/* カットインの帯。自分の席のカットインだけに当てる(.mine)。
   リーチ=赤・鳴き=青・和了=金の色分けは文字と顔の縁に残し、帯の地だけを変える */
body[data-cutin-skin="sakura"] #cutin.mine { background: linear-gradient(90deg, rgba(60,20,35,0), rgba(110,40,70,.92) 35%); }
body[data-cutin-skin="ai"] #cutin.mine {
  background: repeating-linear-gradient(0deg, rgba(200,215,235,.12) 0 1px, transparent 1px 9px),
    linear-gradient(90deg, rgba(10,20,50,0), rgba(16,32,78,.94) 35%);
}
body[data-cutin-skin="shu"] #cutin.mine {
  background: linear-gradient(90deg, rgba(90,10,0,0), rgba(160,30,20,.93) 35%);
  border-top-color: #e8c46b; border-bottom-color: #e8c46b;
}
body[data-cutin-skin="kinran"] #cutin.mine {
  background: linear-gradient(100deg, transparent 40%, rgba(255,255,255,.35) 50%, transparent 60%) 0 0 / 300% 100%,
    linear-gradient(90deg, rgba(90,60,10,0), rgba(140,100,30,.94) 35%);
  animation: cutinShine 1.6s linear infinite;
}
body[data-cutin-skin="niji"] #cutin.mine {
  background: linear-gradient(90deg, rgba(0,0,0,0) 0%, rgba(120,60,160,.9) 30%, rgba(40,110,170,.9) 55%, rgba(40,150,110,.9) 78%, rgba(190,140,40,.92) 100%) 0 0 / 200% 100%;
  animation: cutinShine 3s linear infinite;
}
@keyframes cutinShine { from { background-position: 100% 0, 0 0; } to { background-position: -100% 0, 0 0; } }
/* お店の見本 */
.shopPreview.cutinPrev { justify-content: flex-end; background: #0b120e; }
.cutinPrevBand {
  display: flex; align-items: center; justify-content: flex-end; width: 100%; height: 100%;
  padding-right: 10px; border-top: 2px solid var(--gold); border-bottom: 2px solid var(--gold);
  background: linear-gradient(90deg, rgba(10,10,10,0), rgba(8,8,8,.92) 35%);
}
.cutinPrevBand b { color: var(--gold); font-size: 1.05em; text-shadow: 0 0 8px rgba(232,196,107,.8); }
.cutinPrev[data-c="sakura"] .cutinPrevBand { background: linear-gradient(90deg, rgba(60,20,35,0), rgba(110,40,70,.92) 35%); }
.cutinPrev[data-c="ai"] .cutinPrevBand { background: repeating-linear-gradient(0deg, rgba(200,215,235,.12) 0 1px, transparent 1px 7px), linear-gradient(90deg, rgba(10,20,50,0), rgba(16,32,78,.94) 35%); }
.cutinPrev[data-c="shu"] .cutinPrevBand { background: linear-gradient(90deg, rgba(90,10,0,0), rgba(160,30,20,.93) 35%); }
.cutinPrev[data-c="kinran"] .cutinPrevBand {
  background: linear-gradient(100deg, transparent 40%, rgba(255,255,255,.35) 50%, transparent 60%) 0 0 / 300% 100%, linear-gradient(90deg, rgba(90,60,10,0), rgba(140,100,30,.94) 35%);
  animation: cutinShine 1.6s linear infinite;
}
.cutinPrev[data-c="niji"] .cutinPrevBand {
  background: linear-gradient(90deg, rgba(0,0,0,0) 0%, rgba(120,60,160,.9) 30%, rgba(40,110,170,.9) 55%, rgba(40,150,110,.9) 78%, rgba(190,140,40,.92) 100%) 0 0 / 200% 100%;
  animation: cutinShine 3s linear infinite;
}

/* 因縁の卓の行: ①前哨 → ②因縁（2026-10-29） */
.storyRowRival .storyFoe span + span { margin-left: .9em; }
.storyRowRival .rivalGateStep { color: #a9c7a0; }
.storyRowRival.gatePassed .rivalGateStep { color: #7f9a78; }
.storyRowRival.gatePassed .storyMark { background: #8a3b2c; color: #ffe9c9; }
