  :root {
    --blue: #2170a1;
    --orange: #d4702f;
    --teal: #29707f;
    /* アクセント色は1色だけ。「今押せるもの」(置けるマスの枠・選んだカード・配置後のターン終了) にだけ使う。
       青/橙はプレイヤーの識別専用なので、ここには使わない。 */
    --accent: #1c8e9b;
    --ink: #24303a;
    --paper: rgba(255,255,255,0.82);
    --paper-brd: rgba(255,255,255,0.7);
    --shadow-sm: 0 2px 8px rgba(20,50,60,0.10);
    --shadow-md: 0 6px 20px rgba(20,50,60,0.14);
    --shadow-lg: 0 14px 40px rgba(20,50,60,0.20);

    /* 手札ドックの高さ(216px)+下の余白8px。.dock2 の height と必ず揃えること。
       盤面の外にある #toast もこの値を見て避けるので :root に置く。
       540pxの論理キャンバスに対して 34%。以前は 214px (40%) あり、1920x1080 では
       盤面の取り分がそのぶん削られていた。札を2段組みにして詰めたぶんを設備列へ回す。 */
    --dockH: 224px;
    /* 実況バナー(#fx-stack)を出す高さ。上部の指示バーに重ねる。
       指示バーの下に出すと、盤面の縦が詰まる画面 (スマホ横 844x390 など) で便器に被るため。 */
    --fx-offset: 6px;
    /* 盤面 (.stage) の文書座標。ui.js の syncOverlayAnchors() が毎描画で入れる。
       #app の外にある #fx-stack / #toast を盤面に合わせるためのもの。 */
    --stage-top: 0px;
    --stage-bottom: 100dvh;
    --stage-mid: 50vw;
    /* 論理キャンバス。横向きでは、この寸法で組んだ固定pxのデザインを
       transform: scale(var(--fit)) で利用可能領域に合わせて引き伸ばす。
       960x540 は 16:9 のうち「盤面が成立する最小の高さ」。内訳は
       手札ドック 206px + 設備 208px + HUD/実況ピル 約80px + 余白 で、
       これより低いと設備列がHUDの下に潜る。小さいほど同じ画面での倍率が
       上がるので、成立する最小値を採っている。
       --fit は ui.js の syncStageFit() が入れる (上限1倍。それより広い画面では
       --canvas-w / --canvas-h のほうを広げる)。縦向きでは 1 のまま。 */
    --canvas-w: 960px;
    --canvas-h: 540px;
    --fit: 1;
  }
  * { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
  body {
    font-family: "M PLUS Rounded 1c", "Hiragino Maru Gothic ProN", "Hiragino Sans", "Noto Sans JP", system-ui, sans-serif;
    background: linear-gradient(165deg, #c8cfd2 0%, #eceff0 45%, #d6dbdd 100%);
    color: var(--ink);
    min-height: 100dvh;
    /* タップ操作で盤面や手札の文字が選択されないようにする。長押しで選択ハンドルが出ると
       設備をタップできなくなるため (CrazyGames Technical Requirements の Mobile CSS)。 */
    -webkit-user-select: none;
    user-select: none;
  }
  /* 名前と合言葉の入力だけは選択・編集できる必要がある */
  input, textarea { -webkit-user-select: text; user-select: text; }
  body::before {
    content: ""; position: fixed; inset: 0; z-index: -2;
    background: url("../restroom-background.webp") center / cover no-repeat;
    opacity: 0.35; filter: saturate(0.8) blur(1px);
  }
  /* ゲーム中は中央ステージと外周を同じ空のタイル壁に揃え、設備の縮尺を別室に見せない */
  body:has(.stage)::before {
    background-image: linear-gradient(180deg, #b8ced1 0%, #d7e4e2 58%, #c5d0c9 100%);
    opacity: 1;
    filter: none;
  }
  /* うっすらした光のムラで平面的にならないように */
  body::after {
    content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
    background:
      radial-gradient(60% 45% at 18% 8%, rgba(255,255,255,0.5), transparent 60%),
      radial-gradient(55% 40% at 88% 92%, rgba(120,160,170,0.28), transparent 60%);
  }
  #app { max-width: 640px; margin: 0 auto; padding: 12px; min-height: 100dvh; display: flex; flex-direction: column; justify-content: center; gap: 10px; }
  /* メニューはヒーロー1枚で画面全体を占める (周囲にゲームエリア外の背景を見せない) */
  #app.menu-mode { max-width: none; padding: 0; gap: 0; }
  .card {
    background: var(--paper);
    -webkit-backdrop-filter: blur(14px) saturate(1.3); backdrop-filter: blur(14px) saturate(1.3);
    border: 1px solid var(--paper-brd); border-radius: 20px; padding: 14px;
    box-shadow: var(--shadow-md), inset 0 1px 0 rgba(255,255,255,0.6);
  }
  button { font-family: inherit; border: none; cursor: pointer; }
  button:disabled { cursor: default; }

  /* オンラインのメニューだけは名前入力とボタンが増えて .online-actions が222pxあり、
     そのままでは中身が604pxになって540pxのキャンバスから64pxはみ出す
     (#app.menu-mode は overflow:hidden なので、言語切替と規約リンクが画面外で
     触れなくなる)。遊びに必要な導線は全部残し、飾りのバッジ行を落として
     ロゴを一段小さくすることで縮める。 */
  #app.menu-mode .hero.fullscreen:has(.online-actions) .badge-row { display: none; }
  /* ロゴは縮めない。.logo-copy の文字サイズは固定で一緒には縮まないため、
     枠だけ小さくするとタイトル文字がロゴ絵に重なる。 */
  #app.menu-mode .hero.fullscreen:has(.online-actions) .label { display: none; }
  /* 遊びの説明文 (menu.tagline) は既定のメニュー画面で読める。オンラインの欄では
     代わりに下の .foot がオンライン固有の説明を出すので、ここでは畳む。 */
  #app.menu-mode .hero.fullscreen:has(.online-actions) .menu-sub { display: none; }
  #app.menu-mode .hero.fullscreen:has(.online-actions) .online-actions { margin-top: 10px; gap: 6px; }
  #app.menu-mode .hero.fullscreen:has(.online-actions) .online-name-input { padding: 9px 12px; font-size: 14px; }
  #app.menu-mode .hero.fullscreen:has(.online-actions) .online-actions .start-btn { margin-top: 0; padding: 12px 16px; }
  #app.menu-mode .hero.fullscreen:has(.online-actions) .online-secondary { padding: 10px; }
  #app.menu-mode .hero.fullscreen:has(.online-actions) .howto-btn { padding: 8px; }

  /* menu */
  .hero {
    position: relative; overflow: hidden; margin-top: 16px; padding: 26px 22px;
    border: none; color: #fff;
    background: linear-gradient(150deg, #2c8093 0%, #1c5769 52%, #223f63 100%);
    box-shadow: var(--shadow-lg), inset 0 1px 0 rgba(255,255,255,0.25);
  }
  .hero::before {
    content: ""; position: absolute; inset: 0; opacity: 0.13; pointer-events: none;
    background-image:
      repeating-linear-gradient(0deg, transparent 0 33px, rgba(255,255,255,0.6) 33px 35px),
      repeating-linear-gradient(90deg, transparent 0 33px, rgba(255,255,255,0.6) 33px 35px);
  }
  .hero::after {
    content: ""; position: absolute; top: -50%; left: -25%; width: 70%; height: 150%;
    background: radial-gradient(closest-side, rgba(255,255,255,0.3), transparent 70%);
    transform: rotate(18deg); pointer-events: none;
  }
  /* 全画面ヒーロー: 角丸をなくして端まで敷き、中身は中央に寄せる */
  .hero.fullscreen {
    flex: 1; margin: 0; border-radius: 0;
    display: flex; flex-direction: column; justify-content: center; align-items: center;
    padding: 28px 22px calc(24px + env(safe-area-inset-bottom));
    background-image:
      linear-gradient(150deg, rgba(24,75,88,0.92) 0%, rgba(22,69,83,0.78) 54%, rgba(31,55,86,0.92) 100%),
      url("../room-clean.webp");
    background-size: cover;
    background-position: center;
  }
  .hero.fullscreen > *:not(.bub) { width: 100%; max-width: 520px; }
  .menu-title { position: relative; font-size: 39px; font-weight: 900; letter-spacing: -1px; line-height: 1.05; text-shadow: 0 3px 12px rgba(0,0,0,0.28); }
  .menu-title .emoji { display: inline-block; filter: drop-shadow(0 3px 5px rgba(0,0,0,0.3)); }
  .ui-icon { display: inline-block; width: 1.25em; height: 1.25em; object-fit: contain; vertical-align: -0.22em; pointer-events: none; }
  .badge .ui-icon, .howto-btn .ui-icon { width: 18px; height: 18px; vertical-align: -5px; }
  .hero .menu-sub { position: relative; color: rgba(255,255,255,0.92); }
  .menu-sub { color: #5b6b73; font-weight: 600; margin-top: 10px; line-height: 1.6; font-size: 14px; }
  .badge-row { position: relative; display: flex; flex-wrap: wrap; gap: 6px; margin-top: 16px; }
  .badge { background: rgba(255,255,255,0.18); border: 1px solid rgba(255,255,255,0.28); border-radius: 999px; padding: 5px 11px; font-size: 14px; font-weight: 800; -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
  .hint { display: flex; gap: 10px; align-items: baseline; font-size: 14px; font-weight: 600; color: #3d4c54; margin-top: 9px; }
  .hint .ico { flex-shrink: 0; width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center; border-radius: 8px; background: rgba(41,112,127,0.10); font-size: 14px; }
  .hint .ico .ui-icon { width: 22px; height: 22px; vertical-align: middle; }
  .seg { display: flex; background: #e4ecee; border-radius: 12px; padding: 3px; margin-top: 10px; }
  .seg button { flex: 1; padding: 9px 4px; border-radius: 10px; background: transparent; font-weight: 800; font-size: 14px; color: #55666e; }
  .seg button.on { background: #fff; color: var(--ink); box-shadow: 0 2px 6px rgba(0,0,0,0.12); }
  .online-actions { display: grid; gap: 9px; margin-top: 14px; }
  .online-secondary {
    width: 100%; padding: 13px; border-radius: 14px; background: #e6eef0;
    color: #34474f; font-size: 14px; font-weight: 900;
  }
  .online-name-input {
    width: 100%; padding: 12px 14px; border: 2px solid #c8d8dc; border-radius: 14px;
    background: #fff; color: var(--ink); font-size: 15px; font-weight: 800; text-align: center; outline: none;
  }
  .online-name-input:focus { border-color: var(--teal); box-shadow: 0 0 0 3px rgba(41,112,127,0.13); }
  .stat-line { margin-top: 10px; color: #52656d; font-size: 14px; font-weight: 800; }
  .online-error { margin-top: 10px; color: #a43f2e; font-size: 14px; font-weight: 800; line-height: 1.45; }
  .online-code-input {
    width: 100%; margin-top: 14px; padding: 15px 12px; border: 2px solid #c8d8dc;
    border-radius: 14px; background: #fff; color: var(--ink); text-align: center;
    font: 900 24px/1 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 2px;
    text-transform: uppercase; outline: none;
  }
  .online-code-input:focus { border-color: var(--teal); box-shadow: 0 0 0 3px rgba(41,112,127,0.13); }
  .online-lobby { max-width: 520px; margin: 18px auto; text-align: center; }
  .online-lobby h2 { margin: 0; font-size: 22px; font-weight: 900; }
  .room-code {
    margin: 18px 0 12px; padding: 17px 12px; border-radius: 18px; background: #edf4f5;
    color: var(--teal); font: 900 29px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
    letter-spacing: 2px; border: 2px dashed rgba(41,112,127,0.35);
  }
  .room-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .room-actions button { padding: 12px 8px; border-radius: 13px; background: #e5edef; font-size: 14px; font-weight: 900; color: #40545d; }
  .waiting-line, .connection-line {
    margin-top: 18px; padding: 12px; border-radius: 14px; background: rgba(41,112,127,0.09);
    color: #40545d; font-size: 14px; font-weight: 800;
  }
  .connection-line { background: #fff1d2; color: #7a5b19; }
  .wait-dot { display: inline-block; width: 9px; height: 9px; margin-right: 7px; border-radius: 50%; background: var(--teal); animation: waitpulse 1.2s ease-in-out infinite; }
  @keyframes waitpulse { 50% { opacity: 0.3; transform: scale(0.72); } }
  /* 高さは .dock2 と揃える。相手の手番との行き来で盤面がガタつかないようにするため */
  .opponent-dock {
    position: absolute; z-index: 9; left: 8px; right: 8px; bottom: 8px;
    display: flex; align-items: center; justify-content: center; height: 216px; padding: 16px;
    border: 1px solid var(--paper-brd); border-radius: 18px; background: rgba(255,255,255,0.93);
    color: #52656d; font-size: 14px; font-weight: 900; box-shadow: var(--shadow-md);
    -webkit-backdrop-filter: blur(14px) saturate(1.3); backdrop-filter: blur(14px) saturate(1.3);
  }
  .start-btn {
    position: relative; overflow: visible;
    width: 100%; margin-top: 16px; padding: 16px 18px; border-radius: 16px;
    background: linear-gradient(100deg, #17505f, #2f8a86); color: #fff;
    font-size: 16px; font-weight: 900; display: flex; align-items: center; justify-content: space-between;
    box-shadow: 0 8px 20px rgba(23,80,95,0.4), inset 0 1px 0 rgba(255,255,255,0.25);
    transition: transform 0.12s, box-shadow 0.12s;
  }
  .start-btn:active { transform: translateY(2px); box-shadow: 0 4px 12px rgba(23,80,95,0.4); }
  .start-btn .go {
    display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px;
    border-radius: 50%; background: rgba(255,255,255,0.22); font-size: 17px;
  }
  .label { font-weight: 800; font-size: 15px; margin-top: 4px; }
  .foot { font-size: 14px; color: #728088; margin-top: 10px; }
  /* プライバシーポリシー / 利用規約へのリンク。iframe内で開くとゲームが置き換わるので別タブへ。
     CrazyGamesのCross-Promotion禁止は、この2つのリンクだけ明示的に例外としている。 */
  .legal-links { display: flex; gap: 14px; justify-content: center; margin-top: 8px; }
  .legal-links a { font-size: 14px; font-weight: 700; color: #728088; text-decoration: underline; }
  .hero .legal-links { position: relative; }
  .hero .legal-links a { color: rgba(255,255,255,0.66); }
  .howto-btn {
    width: 100%; margin-top: 8px; padding: 12px; border-radius: 14px;
    background: #eef2f3; font-size: 14px; font-weight: 800; color: #46545c;
    transition: transform 0.12s;
  }
  .howto-btn:active { transform: scale(0.98); }
  /* 言語切替はメニューだけに出す小さなセグメント (ブラウザ言語の自動選択をその場で上書きする) */
  .lang-seg { width: 160px; margin: 8px auto 0; }
  .lang-seg button { padding: 6px 4px; font-size: 14px; }
  /* タイトルカード内の操作系: 暗い背景用の配色に */
  .hero .label { position: relative; color: rgba(255,255,255,0.92); margin-top: 18px; }
  .hero .seg { position: relative; background: rgba(9,38,48,0.45); box-shadow: inset 0 1px 3px rgba(0,0,0,0.25); }
  .hero .seg button { color: rgba(255,255,255,0.75); }
  .hero .seg button.on { background: #fff; color: var(--ink); }
  .hero .start-btn {
    position: relative;
    background: linear-gradient(100deg, #f5b93c, #ec8a2f); color: #4a2e08;
    box-shadow: 0 8px 20px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.45);
  }
  .hero .start-btn:active { box-shadow: 0 4px 12px rgba(0,0,0,0.35); }
  .hero .start-btn .go { background: rgba(74,46,8,0.18); }
  .hero .howto-btn { position: relative; background: rgba(255,255,255,0.16); color: rgba(255,255,255,0.92); border: 1px solid rgba(255,255,255,0.22); }
  .hero .foot { position: relative; color: rgba(255,255,255,0.7); }
  .hero .online-actions { position: relative; }
  .hero .online-secondary { background: rgba(255,255,255,0.16); color: rgba(255,255,255,0.92); border: 1px solid rgba(255,255,255,0.22); }
  .hero .online-name-input { position: relative; border-color: rgba(255,255,255,0.3); background: rgba(255,255,255,0.14); color: #fff; }
  .hero .online-name-input::placeholder { color: rgba(255,255,255,0.6); }
  .hero .online-error { position: relative; color: #ffd9cf; }
  .overlay .panel.rules { text-align: left; max-height: calc(84dvh / var(--fit)); overflow-y: auto; }
  .overlay .panel.rules h2 { text-align: center; margin-top: 0; }
  .overlay .panel.rules .hint { align-items: center; }
  .overlay .panel.rules .rules-detail-toggle { margin-top: 14px; padding: 9px; font-size: 14px; }
  .overlay .panel.rules .rules-detail { border-top: 1px dashed rgba(41,112,127,0.22); margin-top: 4px; padding-top: 2px; }

  /* header */
  .hrow { display: flex; align-items: center; gap: 8px; }
  .icon-btn {
    background: linear-gradient(180deg, #fff, #eef4f4); border-radius: 50%; width: 36px; height: 36px;
    font-size: 15px; font-weight: 900; color: #46545c;
    box-shadow: 0 2px 6px rgba(20,50,60,0.16), inset 0 1px 0 rgba(255,255,255,0.9);
    transition: transform 0.12s;
  }
  .icon-btn:active { transform: scale(0.92); }
  /* 格闘ゲーム風スコア: 白枠なしで、勝ち星と操作中プレイヤーのチップだけを部屋に直接重ねる */
  .side { display: flex; align-items: center; gap: 5px; min-width: 0; }
  .side.right { flex-direction: row-reverse; }
  .side .win-dot {
    width: 14px; height: 14px; border-radius: 50%; flex-shrink: 0;
    background: var(--pc); opacity: 0.3;
    box-shadow: inset 0 0 0 2px rgba(255,255,255,0.85), 0 1px 3px rgba(20,50,60,0.3);
    transition: opacity 0.3s, box-shadow 0.3s;
  }
  .side .win-dot.won { opacity: 1; box-shadow: inset 0 0 0 2px rgba(255,255,255,0.85), 0 0 9px var(--pc); }
  .side-name {
    color: #fff; background: var(--pc); font-size: 14px; font-weight: 900;
    padding: 3px 9px; border-radius: 999px; white-space: nowrap; opacity: 0.78;
    max-width: 88px; overflow: hidden; text-overflow: ellipsis;
    box-shadow: 0 2px 6px rgba(20,50,60,0.3), inset 0 1px 0 rgba(255,255,255,0.3);
  }
  .side.active .side-name { opacity: 1; box-shadow: 0 2px 8px rgba(20,50,60,0.38), 0 0 0 2px rgba(255,255,255,0.3), inset 0 1px 0 rgba(255,255,255,0.3); }
  /* 指示バー: 画面上部に1本だけ。1行目=今やること、2行目=カードの効果か通らなかった理由。
     2行ぶんの高さを常に取り、文言が変わっても盤面が上下しないようにする。 */
  .guide-bar {
    flex: 1; min-width: 0; min-height: 44px; display: flex; align-items: center; gap: 10px;
    padding: 4px 14px 4px 6px; border-radius: 14px;
    background: rgba(18,34,42,0.78); color: #fff;
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  }
  .guide-round {
    flex-shrink: 0; padding: 3px 7px; border-radius: 8px;
    background: rgba(255,255,255,0.14); color: rgba(255,255,255,0.8);
    font-size: 14px; font-weight: 900; letter-spacing: 0.04em;
  }
  .guide-text { min-width: 0; display: flex; flex-direction: column; line-height: 1.2; }
  .guide-main { font-size: 17px; font-weight: 900; white-space: nowrap; }
  .guide-sub { min-height: 1.2em; font-size: 14px; font-weight: 700; color: rgba(255,255,255,0.8); }
  .guide-sub.notice { color: #ffd479; }

  .panel .rematch-note { font-size: 14px; font-weight: 800; color: #46545c; margin-top: 4px; }

  /* board stage: 画面全体を1枚のトイレの部屋にして、HUD/手札を上に浮かべる。
     max-height を付けて背の高い画面での間延び(壁の空白)を抑え、余りは #app の
     justify-content:center で上下に均等配分する (板面・設備の縮尺はそのまま) */
  .stage {
    position: relative; flex: 1; min-height: 540px; max-height: min(660px, 84dvh);
    border-radius: 20px; overflow: hidden;
    box-shadow: var(--shadow-lg), inset 0 0 0 1px rgba(255,255,255,0.35);
  }
  /* 横向き (CrazyGames の 16:9 iframe) では、盤面を 960x540 の論理キャンバスとして
     組み、画面に合わせて等倍スケールする。以前は #app の max-width:640px と
     .stage の max-height で上限が掛かっていたため、1920x1080 では画面幅の32%しか
     使えず、本文が9pxのまま置かれていた (CrazyGames Gameplay requirements の
     "Text and images must be legible on devices with a devicePixelRatio:1")。
     中の固定px (--dockH / 設備の高さ / フォント) は触らず、倍率だけで読めるようにする。 */
  @media (orientation: landscape) {
    #app.board-mode {
      display: block; position: relative;
      width: 100%; height: 100dvh; max-width: none; padding: 0; gap: 0; overflow: hidden;
    }
    #app.board-mode > .stage {
      position: absolute; left: 50%; top: 50%; margin: 0;
      flex: none; width: var(--canvas-w); height: var(--canvas-h);
      min-height: 0; max-height: none;
      /* translate が先、scale が後。transform-origin は既定の中央のままで、
         キャンバスの中心が #app の中心に載る (余白は上下左右へ均等に配る)。 */
      transform: translate(-50%, -50%) scale(var(--fit));
    }
    /* 設備列だけは designed な密度を保って中央に置く。960px いっぱいに広げると
       小便器の間隔が絵の幅の倍近くになり、仕切り (.urinal .fin) が絵から離れて
       壁に浮いた板に見える。余った幅は左右の壁として残す。 */
    #app.board-mode .fixtures {
      max-width: 720px; margin-inline: auto;
      /* 広い画面では UI の拡大を止めたぶん、盤面だけを大きくする。transform: scale() だと
         Safari が再描画のたびに人物のレイヤーを隣の台の位置へ描き残した (タブ切替で直る) ので、
         合成レイヤーを作らない zoom で拡大する。zoom は bottom も拡大するので割り戻して接地位置を保つ。 */
      zoom: var(--board-scale, 1);
      bottom: calc((var(--dockH) + 20px) / var(--board-scale, 1));
    }
    /* 指示バーは広い画面でも読みやすい長さで止め、中央に置く */
    #app.board-mode .guide-bar { max-width: 760px; margin-inline: auto; }
    /* 拡大の上限 (ui.js の MAX_FIT) に当たる広い画面ではキャンバスが 960px より広がる。
       手札が横に間延びしないよう、ドックも中央に寄せて幅を止める。 */
    #app.board-mode .dock2, #app.board-mode .opponent-dock { max-width: 1040px; margin-inline: auto; }

    /* メニューも同じ 960x540 のキャンバスに載せる。流し込みのままだと中身の
       自然高が810pxあり、16:9 の短い画面 (800x450 / 844x390 / 1280x720) では
       ページが縦スクロールして「Enter the restroom」が画面外へ出ていた。
       キャンバスなら1回 540px に収めれば、どの画面幅でも倍率だけが変わる。 */
    #app.menu-mode {
      display: block; position: relative;
      width: 100%; height: 100dvh; max-width: none; padding: 0; gap: 0; overflow: hidden;
    }
    #app.menu-mode > .hero.fullscreen {
      position: absolute; left: 50%; top: 50%; margin: 0;
      flex: none; width: var(--canvas-w); height: var(--canvas-h);
      padding: 18px 20px;
      transform: translate(-50%, -50%) scale(var(--fit));
    }
    /* 540px に収めるための詰め。横幅は 960px 側に余裕があるので、行を削るのではなく
       「1行に収まる幅」を与えて行数を減らす (バッジ4つが2段->1段になる)。 */
    #app.menu-mode .hero.fullscreen > *:not(.bub) { max-width: 560px; }
    #app.menu-mode .logo-composite, #app.menu-mode .logo-svg, #app.menu-mode .logo-img {
      width: min(100%, 250px);
    }
    /* ロゴ絵 (logo.webp) は左の52%が余白で、便器は右53%から始まる。
       副題を 7px から 14px へ上げたぶん、文字の載る枠を余白の幅ちょうどに詰め、
       字間と横倍率で長さを吸収する (はみ出すと便器の水しぶきに重なって読めない)。 */
    #app.menu-mode .logo-copy { width: 52%; }
    #app.menu-mode .logo-copy .main { font-size: 15px; }
    #app.menu-mode .logo-copy .sub { font-size: 14px; margin-top: 2px; letter-spacing: 0; transform: scaleX(0.82); }
    #app.menu-mode .menu-sub { margin-top: 7px; font-size: 14px; line-height: 1.45; }
    #app.menu-mode .badge-row { margin-top: 8px; flex-wrap: nowrap; justify-content: center; }
    #app.menu-mode .badge { padding: 5px 9px; font-size: 14px; white-space: nowrap; }
    /* VSの2人はキャンバス左の余白へ逃がす。行送りを使わない飾りにすることで
       130px ぶんの高さが空き、メニューの中身が540pxに収まる。 */
    /* 960x540 では左下隅。キャンバスが広がる画面 (拡大の上限に当たるPC) でも、
       中央の中身から離れすぎないよう中心基準で置く (960x540 のときは従来と同じ位置)。 */
    #app.menu-mode .vs-scene {
      position: absolute; left: max(12px, calc(50% - 468px)); bottom: max(14px, calc(50% - 256px)); z-index: 0;
      width: 178px; height: 124px; margin: 0; gap: 22px; pointer-events: none;
    }
    #app.menu-mode .hero .label { margin-top: 10px; }
    #app.menu-mode .seg { margin-top: 6px; }
    #app.menu-mode .start-btn { margin-top: 12px; padding: 13px 16px; }
    #app.menu-mode .online-actions { margin-top: 12px; gap: 7px; }
    #app.menu-mode .howto-btn { margin-top: 7px; padding: 9px; }
    #app.menu-mode .lang-seg { margin-top: 6px; }
    #app.menu-mode .foot { margin-top: 6px; }
    #app.menu-mode .legal-links { margin-top: 5px; }

  }
  /* 天井照明のやわらかい光 */
  .stage::before {
    content: ""; position: absolute; inset: 0; z-index: 6; pointer-events: none;
    background:
      radial-gradient(130% 62% at 50% -12%, rgba(255,255,255,0.6), rgba(255,255,255,0) 55%),
      radial-gradient(50% 34% at 24% -4%, rgba(255,251,231,0.5), transparent 70%),
      radial-gradient(50% 34% at 76% -4%, rgba(255,251,231,0.5), transparent 70%);
    mix-blend-mode: screen;
  }
  /* 四隅の陰影で奥行きを出す */
  .stage::after {
    content: ""; position: absolute; inset: 0; z-index: 6; pointer-events: none; border-radius: 20px;
    box-shadow: inset 0 -26px 46px rgba(18,38,48,0.22), inset 0 30px 54px rgba(18,38,48,0.14),
                inset 34px 0 40px rgba(18,38,48,0.10), inset -34px 0 40px rgba(18,38,48,0.10);
  }
  .room {
    position: absolute; inset: 0;
    --tileW: 54px; --tileH: 36px; --grout: rgba(128,138,141,0.45);
    background-color: #d6dadb;
    background-image:
      /* 上からの光の減衰 */
      linear-gradient(180deg, rgba(255,255,255,0.55), rgba(255,255,255,0) 30%, rgba(80,90,94,0.14)),
      /* アクセントタイルの帯 (壁の余白を埋める) */
      linear-gradient(180deg, transparent 0 26%, rgba(84,98,104,0.16) 26% 33%, rgba(84,98,104,0.06) 33% 34.5%, transparent 34.5%),
      /* タイルの面取りハイライト(左上) */
      repeating-linear-gradient(0deg, rgba(255,255,255,0.28) 0 1.5px, transparent 1.5px var(--tileH)),
      repeating-linear-gradient(90deg, rgba(255,255,255,0.28) 0 1.5px, transparent 1.5px var(--tileW)),
      /* 目地(grout) */
      repeating-linear-gradient(0deg, transparent 0 calc(var(--tileH) - 2px), var(--grout) calc(var(--tileH) - 2px) var(--tileH)),
      repeating-linear-gradient(90deg, transparent 0 calc(var(--tileW) - 2px), var(--grout) calc(var(--tileW) - 2px) var(--tileW)),
      linear-gradient(#dfe2e3, #cbd0d1);
  }
  /* 床(奥行きのあるタイル)+ 巾木。手札ドックの裏まで続く */
  .floor {
    position: absolute; left: 0; right: 0; bottom: 0; height: calc(var(--dockH) + 62px); z-index: 1; pointer-events: none;
    background:
      linear-gradient(180deg, rgba(0,0,0,0.12), transparent 22%),
      linear-gradient(180deg, #ece2cf 0%, #ddd0b6 60%, #d2c4a6 100%);
    background-image:
      linear-gradient(180deg, rgba(0,0,0,0.12), transparent 22%),
      url("../floor-tiles.webp"),
      linear-gradient(180deg, #ece2cf 0%, #ddd0b6 60%, #d2c4a6 100%);
    background-size: auto, 220px 220px, auto;
    background-repeat: no-repeat, repeat, no-repeat;
    box-shadow: inset 0 4px 8px rgba(255,255,255,0.35);
    filter: saturate(0.45);
  }
  .floor::before {
    content: ""; position: absolute; inset: 0;
    background-image: repeating-linear-gradient(90deg, transparent 0 47px, rgba(150,128,90,0.32) 47px 49px);
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 55%);
            mask-image: linear-gradient(180deg, transparent, #000 55%);
  }
  /* 壁と床の境の巾木 */
  .floor::after {
    content: ""; position: absolute; left: 0; right: 0; top: -7px; height: 7px;
    background: linear-gradient(180deg, #b9c9ca, #9db0b2);
    box-shadow: 0 3px 5px rgba(0,0,0,0.20);
  }
  .fixtures {
    position: absolute; left: 0; right: 0; bottom: calc(var(--dockH) + 20px); z-index: 3;
    display: flex; align-items: flex-end; gap: 5px; padding: 0 12px;
    /* 手札の枚数/種類でドックの実高さ(--dockH)が変わるたびに設備列が瞬間移動して
       ガタつくのを防ぐ。位置の変化そのものはなくならないが、目に見えて滑らかになる。 */
    transition: bottom 0.22s ease;
  }
  /* 壁の装飾 (「一歩前へ！」ポスターのみ)。
     以前は不透明な白カード+濃い影で「操作できるUIパネル」のように見えてしまっていたため、
     半透明・薄い影の「壁に貼られた古い注意書き」に寄せ、盤面情報と誤読されない背景装飾にする (P3-2/P3-3) */
  .wall-decor {
    position: absolute; left: auto; right: 7%; top: 13%; z-index: 2;
    display: flex; justify-content: flex-end; align-items: flex-start; pointer-events: none;
    opacity: 0.72;
  }
  .wall-decor .poster {
    transform: rotate(1.6deg) scale(0.82); transform-origin: top right; text-align: center;
    background: rgba(255,254,245,0.55); border-radius: 4px; padding: 7px 11px 6px;
    color: rgba(61,76,84,0.8); box-shadow: 0 1px 3px rgba(20,50,60,0.10);
    border-bottom: 2px solid rgba(200,190,150,0.4);
  }
  .wall-decor .poster .big { font-size: 14px; font-weight: 900; letter-spacing: 3px; }
  .wall-decor .poster .small { font-size: 8.5px; font-weight: 700; color: rgba(116,131,139,0.85); margin-top: 3px; letter-spacing: 0.5px; }
  /* .fixtures (position:relative) の直近の子として bottom:100% で配置。
     盤面(.room)の実高さやブレークポイントに関わらず、常に設備の真上に密着する。 */
  /* 部屋の上に浮かぶHUD (紙パネルは手札ドックのみ。上部HUDは枠なし) */
  .dock2 {
    position: absolute; z-index: 8;
    background: var(--paper);
    -webkit-backdrop-filter: blur(14px) saturate(1.3); backdrop-filter: blur(14px) saturate(1.3);
    border: 1px solid var(--paper-brd);
    box-shadow: var(--shadow-sm), inset 0 1px 0 rgba(255,255,255,0.6);
  }
  .hud-top { position: absolute; z-index: 8; top: 10px; left: 10px; right: 10px; }
  /* 待機中CPU練習戦の検索帯。盤面の情報と混ざらないよう、HUD直下に細く敷く */
  .search-strip {
    position: absolute; top: 60px; left: 0; right: 0; z-index: 6;
    display: flex; align-items: center; gap: 8px; padding: 5px 10px;
    background: rgba(9,38,48,0.72); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
    color: rgba(255,255,255,0.92); font-size: 14px; font-weight: 700;
  }
  .search-strip .msg { flex: 1; min-width: 0; }
  .search-strip button {
    flex-shrink: 0; padding: 4px 9px; border-radius: 8px; font-size: 14px; font-weight: 800;
    background: rgba(255,255,255,0.18); color: #fff; border: 1px solid rgba(255,255,255,0.26);
  }
  .search-strip button:disabled { opacity: 0.5; }
  /* max-height + overflow は保険: カードが増えて収まらない画面でも、スクロールするのは
     このパネルの中だけにして、盤面を含む画面全体はスクロールさせない */
  /* 高さは固定する。手札の枚数 (配置前6枚 / 配置後2枚 / 相手の手番) でドックの高さが変わると、
     設備の接地位置 (--dockH) がそれに追従して盤面ごと上下にガタつくため。
     収まらない内容はドックの中だけをスクロールさせる。 */
  .dock2 {
    left: 8px; right: 8px; bottom: 8px; z-index: 9; border-radius: 18px; padding: 6px 10px 8px;
    box-shadow: var(--shadow-md), inset 0 1px 0 rgba(255,255,255,0.6);
    height: 216px; overflow-y: auto; overscroll-behavior: contain;
    display: flex; gap: 10px;
  }
  .wall-divider {
    width: 10px; height: 240px; margin: 0 6px; flex-shrink: 0; border-radius: 3px;
    background-color: #b7c6c5; background-image: url("../partition.webp"); background-size: 100% 100%; background-repeat: no-repeat;
    box-shadow: 2px 0 6px rgba(20,50,60,0.25), inset 1px 0 0 rgba(255,255,255,0.6);
  }
  .person-svg, .person-img, .sign-svg, .sign-wrap, .fixture-svg, .fixture-img, .ground-shadow, .fin { pointer-events: none; }
  /* 個室 */
  /* 個室は小便器(flex:1)に対する比率で幅を決める(固定pxではなく)。
     コンテナ幅が変わっても常に「小便器の1.4台分」の見た目比を保つ。 */
  .stallbox { flex: 1.4 0 0%; height: 240px; position: relative; }
  /* button は display:block でも親の幅に広がらず中身 (扉の画像) に縮むため、幅を明示する。
     無いと画像の読み込み前は幅0で、最初の手番に個室を押せない瞬間があった。 */
  .stallbox .door-btn { background: none; padding: 0; display: block; width: 100%; height: 100%; position: relative; border-radius: 6px; }
  /* 接地させるため object-position:bottom。contain だけだと上下中央に置かれて扉が宙に浮く */
  .stallbox .door-svg, .stallbox .door-art { height: 100%; width: 100%; object-fit: contain; object-position: bottom; display: block; margin: 0 auto; filter: drop-shadow(0 3px 5px rgba(0,0,0,0.22)); }
  .closed-tape { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
  .closed-tape i {
    position: absolute; left: 9%; right: 9%; top: 50%; height: 11%; margin-top: -5.5%;
    background: repeating-linear-gradient(115deg, #403a2a 0 7px, #f2c94c 7px 15px);
    border-top: 1.5px solid #a8871c; border-bottom: 1.5px solid #a8871c;
    box-shadow: 0 1px 3px rgba(0,0,0,0.25);
  }
  .closed-tape i:first-child { transform: rotate(11deg); }
  .closed-tape i:last-child { transform: rotate(-11deg); }
  .stallbox .door-btn.revealed { box-shadow: 0 0 0 3px rgba(217,95,77,0.85), 0 0 14px rgba(217,95,77,0.6); }
  .stall-badge {
    position: absolute; top: 42%; left: 50%; transform: translate(-50%, -50%); z-index: 4;
    width: 30px; height: 30px; border-radius: 50%; background: rgba(255,255,255,0.94);
    border: 2px solid rgba(0,0,0,0.18); display: flex; align-items: center; justify-content: center;
    box-shadow: 0 2px 5px rgba(0,0,0,0.18); font-size: 15px; font-weight: 900; color: rgba(0,0,0,0.55);
  }
  .stall-badge img { width: 20px; height: 20px; object-fit: contain; }
  /* 個室は盤面のいちばん左にあるので、中央寄せだと画面外へはみ出して先頭が切れる。
     個室の左端に合わせて右へ伸ばす (上は壁で、何とも重ならない)。 */
  .stallbox .stall-meta {
    position: absolute; top: -12px; left: 0; z-index: 6;
    display: flex; align-items: center; gap: 4px; white-space: nowrap;
    background: rgba(255,255,255,0.95); border-radius: 999px; padding: 3px 8px;
    font-size: 14px; font-weight: 900; color: #3d4c54; box-shadow: 0 2px 5px rgba(0,0,0,0.15);
  }
  .stall-meta .dot { width: 7px; height: 7px; border-radius: 50%; }
  /* 盤面の枠は3状態だけ (ui.js の seatFrameClass): hl 置ける / picked このターンに置いたマス / なし。
     置けないマスは枠を付けずに暗くするだけ (dim)。滞在・残り回数・閉鎖はマス内のアイコンと数字で出す。 */
  .stallbox.hl::after, .stallbox.picked::after {
    content: ""; position: absolute; inset: -3px; border-radius: 10px; pointer-events: none;
    border: 2px solid var(--accent);
  }
  /* 暗くする filter は位置指定された絵そのものに掛ける。入れ物 (.urinal のボタン) に掛けると
     Safari で中の人物 (left:50% + translateX(-50%)) の基準がずれ、隣の台に立って見えた
     (Docs/ui-improvement-progress.md の「filter は包含ブロックを作る」落とし穴と同じ)。 */
  .urinal.dim .fixture-img, .urinal.dim .fixture-svg, .urinal.dim .sign-svg, .urinal.dim .sign-wrap,
  .urinal.dim .flies, .stallbox.dim .door-btn { filter: brightness(0.62) saturate(0.5); }
  .urinal.dim .person-svg, .urinal.dim .person-img {
    filter: saturate(0.72) contrast(0.92) brightness(1.03) drop-shadow(0 5px 4px rgba(0,0,0,0.32)) brightness(0.62) saturate(0.5);
  }
  /* 小便器 */
  .urinal { flex: 1; background: none; padding: 0; position: relative; height: 240px; min-width: 0; }
  .urinal .fin { position: absolute; left: -4px; top: 56px; bottom: 46px; width: 5px; border-radius: 3px; background: linear-gradient(90deg, #eef5f6, #bfd2d5); }
  /* bottom は人物 (bottom:6px・height:128px = 頭が134px) より低く保つこと。
     便器の方が高いと「人が便器を見上げている」ように見えて接地感が壊れる。 */
  .urinal .fixture-svg, .urinal .fixture-img {
    position: absolute; left: 50%; transform: translateX(-50%); bottom: 30px; width: 86%; max-width: 69px; height: 111px;
    object-fit: contain; filter: drop-shadow(0 5px 4px rgba(20,35,40,0.22)); z-index: 1;
  }
  .urinal .fixture-img.closed { filter: grayscale(0.85) brightness(0.95); }
  /* 「あと1回」の見分けは専用のシミ画像 (urinal-used.webp) 側で表現する。
     CSSのフィルタで便器自体を黄色く染めるのは不採用 (設備の色が変わって見えるため)。 */
  .urinal .fixture-img.stained { filter: none; }
  /* 彩度/コントラストを少し落として設備側(淡色・柔らかい陰影)のトーンに寄せる (P1-1)。
     以前はここにオーナー色の縁取り+発光も足していたが、キャラが光っているようにしか見えず
     不要と判断して削除した。誰の駒かは足元の影の色で示す。
     別要素にfilterをかけるとposition:absoluteの子の包含ブロックがズレるため、必ずこの要素自身に付ける。 */
  /* 中央寄せは静的な translate プロパティで行い、transform (アニメーション) は揺れ・着地の縦移動だけに使う。
     translateX(-50%) をアニメーションの transform に含めていたとき、Safari で人物が隣の台へずれて描かれた。
     (人物の絵はマスより広いことがあるので、margin:auto の中央寄せは使えない)
     画像は絵ごとに幅が違う (184〜341/512) うえ、描画のたびに <img> を作り直すので読み込み前は幅0になる。
     iOS Safari はその幅0のときの -50% のまま描き続け、人物が絵の半幅ぶん右の台へずれた。
     そこで枠は一番広い絵が収まる固定比にして、絵は枠の中で下揃え・中央に置く。 */
  .urinal .person-svg, .urinal .person-img {
    position: absolute; left: 50%; translate: -50% 0; bottom: 6px; height: 148px; z-index: 2;
    filter: saturate(0.72) contrast(0.92) brightness(1.03)
      drop-shadow(0 5px 4px rgba(0,0,0,0.32));
  }
  .urinal .person-img { aspect-ratio: 0.7; object-fit: contain; object-position: 50% 100%; }
  .urinal .sign-svg, .urinal .sign-wrap { position: absolute; left: 50%; transform: translateX(-50%); bottom: 5px; height: 108px; z-index: 2; }
  .sign-wrap img { height: 100%; display: block; }
  .sign-wrap .sign-label {
    position: absolute; top: 42%; left: 50%; transform: translateX(-50%);
    font-size: 14px; font-weight: 900; color: #6b4e0e; white-space: nowrap;
    text-shadow: 0 0 3px rgba(255,255,255,0.9);
  }
  /* 人物の縁取りをやめたぶん、誰の駒かは足元の影の色で示す (--pc が無い設備側は無彩色のまま) */
  .urinal .ground-shadow {
    position: absolute; bottom: 8px; left: 50%; transform: translateX(-50%);
    width: 76%; height: 10px; border-radius: 50%; z-index: 1;
    background: radial-gradient(ellipse, var(--pc, rgba(20,35,40,0.32)), transparent 68%);
    opacity: 0.55;
  }
  /* 残り滞在のドット。1つ = 相手の手番1回ぶん (ふつう1・長小便2)。手札のカード左上と
     同じ形・同じ色で、相手の手番が1回終わるごとに1つ減る。顔にも隣の台にもかからないよう、
     足元に小さい白ピルで敷く (床の色に沈まないようにピルは残す)。 */
  .urinal .stay-meter {
    position: absolute; bottom: 1px; left: 50%; transform: translateX(-50%); z-index: 6;
    pointer-events: none; padding: 3px 5px; border-radius: 999px;
    background: rgba(255,255,255,0.93); box-shadow: 0 2px 5px rgba(0,0,0,0.2);
  }
  /* 滞在ドット本体。カード (.hcard) と盤面で共用する。色はプレイヤー色 (青/橙) にしない:
     橙にすると個室の持ち主の丸と同色で数が1つ多く見え、橙側のプレイヤーには自分の色になる。 */
  .stay-dots { display: inline-flex; align-items: center; gap: 3px; color: #3d4c54; }
  .stay-dots .hourglass { width: 10px; height: 13px; margin-right: 1px; }
  .stay-dots i {
    display: block; width: 8px; height: 8px; border-radius: 50%;
    background: #3d4c54; box-shadow: 0 0 0 1.5px rgba(255,255,255,0.92), 0 1px 2px rgba(20,50,60,0.3);
  }
  /* 人物が立っていても位置番号が読めるよう、透明文字ではなく不透明の小さなピルにする (P1-5) */
  .urinal .tag {
    position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); z-index: 3;
    font-size: 14px; font-weight: 900; color: #2c3a40; line-height: 1; white-space: nowrap;
    background: rgba(255,255,255,0.9); padding: 2px 6px; border-radius: 999px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.18);
  }
  .urinal.hl::after, .urinal.picked::after {
    content: ""; position: absolute; inset: 40px 2px 10px; border-radius: 16px; pointer-events: none;
    border: 2px solid var(--accent);
    background: rgba(28,142,155,0.10);
  }
  .stallbox.picked::after, .urinal.picked::after { border-width: 4px; border-color: #2c3a40; background: none; }
  /* キャラのゆらぎ(待機モーション) */
  /* NPC対戦の強さ。メニューは 960x540 のキャンバスで余白が11px、390x844 の縦画面で14pxしかない
     (はみ出すと規約リンクが画面外に出るか、ページが縦にスクロールする)。見出しと切替を1行に
     まとめ、増えた高さのぶん、オンラインの欄と同じく「対戦モード」の見出しを畳み、上のバッジ行と
     同じ内容を繰り返している .foot も畳む。下の3択ボタンだけで何を選ぶ欄かは分かる。 */
  .level-row { position: relative; display: flex; align-items: center; gap: 10px; margin-top: 8px; }
  .level-label { flex-shrink: 0; font-weight: 800; font-size: 15px; color: rgba(255,255,255,0.92); }
  .level-row .level-seg { flex: 1; margin-top: 0; }
  .level-row .level-seg button { padding: 6px 4px; }
  #app.menu-mode .hero.fullscreen:has(.level-row) .label { display: none; }
  #app.menu-mode .hero.fullscreen:has(.level-row) .foot { display: none; }

  @keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-2.5px); } }
  .urinal .person-img, .urinal .person-svg { animation: bob 3.6s ease-in-out infinite; }
  @media (max-width: 480px) {
    #app { padding: 8px; }
    #app.menu-mode { padding: 0; }
    .card { padding: 10px; border-radius: 16px; }
    /* バッジが14pxで3段に増えたぶん、余白を詰めて 844px の画面に収める
       (収まらないとページごと縦スクロールし、CrazyGames の iframe では下端が切れる) */
    .hero.fullscreen { padding: 16px 16px calc(9px + env(safe-area-inset-bottom)); border-radius: 0; }
    .badge-row { margin-top: 8px; gap: 3px; }
    .hero .label { margin-top: 12px; }
    .legal-links { margin-top: 7px; }
    .hrow { gap: 5px; }
    .icon-btn { width: 36px; height: 36px; }
    .side .win-dot { width: 12px; height: 12px; }
    .side-name { padding: 3px 7px; }
    /* 縦向きは横幅が足りないので、指示バーだけ2段目に下ろす */
    .hud-top { flex-wrap: wrap; }
    .guide-bar { order: 10; flex-basis: 100%; }
    .hcard { padding: 4px; min-height: 0; }
    /* 378px + 8px。6枚を3列x2段で見せつつ、カード下に不要な空白を残さない。 */
    /* 縦向きは指示バーが2段目に下りるので、実況もそこへ重ねる */
    :root { --dockH: 386px; --fx-offset: 51px; }
    .search-strip { top: 120px; }
    .stage { min-height: 500px; }
    .hud-top { top: 8px; left: 8px; right: 8px; }
    .dock2 { padding: 6px 8px 8px; height: 378px; flex-direction: column; }
    .end-control { flex-direction: row; justify-content: flex-end; }
    .opponent-dock { height: 378px; }
    .fixtures { gap: 2px; padding: 0 6px; }
    .stallbox { height: 156px; }
    .wall-divider { height: 148px; margin: 0 3px; }
    .urinal { height: 156px; }
    .urinal .person-svg, .urinal .person-img { height: 102px; }
    .urinal .sign-svg, .urinal .sign-wrap { height: 70px; }
    /* 人物 (bottom:6px・height:102px = 頭が108px) より低く保つ。
       縦向きは設備の幅 (画面幅 ÷ 7.4) が絵の大きさを決めるので、横向きキャンバス用に
       上げた height をここで戻す。伸ばしても絵は大きくならず、箱の中で浮くだけになる。 */
    .urinal .fixture-svg, .urinal .fixture-img { bottom: 18px; height: 96px; max-width: 60px; }
    .urinal .fin { top: 40px; bottom: 32px; }
    .urinal .tag { bottom: 16px; }
    .stallbox .stink { top: 34px; }
    .urinal.hl::after, .urinal.picked::after { inset: 28px 0 10px; }
    .pee-pop { bottom: 40px; }
    .wall-decor { top: 16%; right: 5%; }
    .wall-decor .poster .big { font-size: 13px; }
    .wall-decor .poster .small { font-size: 7.5px; }
  }
  /* 背の低い縦画面 (SafariのブラウザUI込みの実用領域など) でも、
     収まらないカードはドック内だけをスクロールする。 */
  @media (max-width: 480px) and (max-height: 760px) {
    :root { --dockH: 348px; }
    .dock2 { height: 340px; overflow-y: auto; }
    .opponent-dock { height: 340px; }
    .hcard { min-height: 0; }
  }

  /* ターン終了 (手札の右端 = 画面の右下)。配置前は枠線だけで押せず、配置後に塗りつぶしの主ボタンになる。 */
  .end-control { flex-shrink: 0; display: flex; flex-direction: column; justify-content: flex-end; gap: 6px; min-width: 96px; }
  .end-btn {
    padding: 10px 14px; border-radius: 12px; font-size: 16px; font-weight: 900; white-space: nowrap;
    background: transparent; color: var(--accent); border: 2px solid var(--accent); opacity: 0.45;
  }
  .end-btn.ready { background: var(--accent); color: #fff; opacity: 1; box-shadow: 0 4px 12px rgba(20,50,60,0.3); }
  .undo-btn {
    padding: 6px 10px; border-radius: 10px; font-size: 14px; font-weight: 900; white-space: nowrap;
    background: #fff; color: #46545c; border: 1.5px solid rgba(70,84,92,0.35);
  }
  /* 手札は6枚を常に同じ位置に1列で並べる (使えない札もグレーで残す)。 */
  .hand-cards { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 6px; flex: 1 1 auto; min-width: 0; min-height: 0; }
  .hcard {
    position: relative; text-align: left; padding: 4px; border-radius: 14px;
    border: 1px solid rgba(30,60,70,0.10);
    display: flex; flex-direction: column; gap: 3px; min-height: 0; background: #fff;
    min-width: 0; overflow: hidden;
    box-shadow: 0 2px 5px rgba(20,50,60,0.10), inset 0 1px 0 rgba(255,255,255,0.85);
    transition: none;
  }
  .hcard::before {
    content: ""; position: absolute; inset: 0 0 auto 0; height: 42%; border-radius: 14px 14px 40% 40%;
    background: linear-gradient(180deg, rgba(255,255,255,0.6), transparent); pointer-events: none;
  }
  /* カードの中身は人物画像1枚。ドックの余った高さはすべてここへ渡す (flex: 1)。 */
  .hcard .card-visual {
    display: block; position: relative; flex: 1 1 auto; width: 100%; min-height: 0;
    border-radius: 10px; overflow: hidden;
    background: rgba(255,255,255,0.42); box-shadow: inset 0 0 0 1px rgba(255,255,255,0.55);
  }
  .hcard .card-art {
    display: block; width: 100%; height: 100%; object-fit: contain; object-position: center bottom;
    filter: drop-shadow(0 2px 2px rgba(20,50,60,0.2));
  }
  .sr-only {
    position: absolute !important; width: 1px !important; height: 1px !important;
    padding: 0 !important; margin: -1px !important; overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important;
  }
  /* 全カード共通の上段: 対象アイコン (小便器 / 扉 / +)・名前。残数は画像の右上に固定。 */
  .hcard .card-head { display: flex; align-items: center; gap: 4px; min-width: 0; padding: 1px 2px 0; line-height: 1.1; }
  .card-target {
    flex-shrink: 0; width: 22px; height: 22px; padding: 2px; display: grid; place-items: center;
    border-radius: 6px; background: rgba(36,48,58,0.12);
  }
  .card-target img { width: 100%; height: 100%; object-fit: contain; }
  .card-target b { font-size: 17px; font-weight: 900; color: #46545c; line-height: 1; }
  .card-name { flex: 1; min-width: 0; font-size: 14px; font-weight: 900; color: #24303a; white-space: nowrap; }
  .hcard .card-stock {
    position: absolute; right: 4px; top: 4px; z-index: 3; padding: 2px 6px; border-radius: 999px;
    background: rgba(255,255,255,0.94); box-shadow: 0 1px 3px rgba(20,50,60,0.16);
    font-size: 14px; font-weight: 900; color: #38585f; line-height: 1.15; white-space: nowrap;
  }
  /* 滞在 (砂時計+ドット) は画像の左下。1ドット = 相手の手番1回ぶん居座る。 */
  .hcard .stay-dots {
    position: absolute; left: 4px; bottom: 4px; z-index: 3;
    padding: 3px 6px 3px 5px; border-radius: 999px;
    background: rgba(255,255,255,0.92); box-shadow: 0 1px 3px rgba(20,50,60,0.2);
  }
  /* 使えない札: 画像だけをグレーにして、その上に理由を重ねる。
     タップは塞がない (効果と理由の全文をドック上部の指示文の欄に出すため)。 */
  .hcard.dim .card-art, .hcard.dim .card-visual > svg { filter: grayscale(1) opacity(0.5); }
  .hcard .card-lock {
    position: absolute; inset: auto 3px 3px; z-index: 4;
    padding: 3px 4px; border-radius: 7px; background: rgba(255,255,255,0.93);
    color: #8a5a3f; font-size: 14px; font-weight: 900; line-height: 1.2;
    text-align: center; overflow-wrap: anywhere;
  }
  .hcard.sel {
    border: 3px solid var(--accent); transform: none;
    box-shadow: 0 0 0 2px rgba(28,142,155,0.26), inset 0 1px 0 rgba(255,255,255,0.85);
  }
  .hcard.sel::after {
    content: "✓"; position: absolute; right: 6px; bottom: 6px; z-index: 5;
    width: 18px; height: 18px; display: grid; place-items: center; border-radius: 50%;
    background: var(--accent); color: #fff; font-size: 12px; font-weight: 900; line-height: 1;
  }
  /* 無効な行動カード: 押せる札と混同しないよう影を外す (画像のグレー化は .card-art 側)。 */
  .hcard.dim { box-shadow: none; }

  /* overlay & toast */
  .overlay {
    position: fixed; inset: 0; background: rgba(10,25,30,0.55);
    -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
    display: flex; align-items: center; justify-content: center; padding: 24px; z-index: 20;
    animation: fade 0.3s ease;
  }
  @keyframes fade { from { opacity: 0; } }
  /* ラウンド結果・勝敗・遊び方のパネルも盤面と同じ倍率で出す。.overlay は #app の
     直下 (position:fixed) なので盤面の scale() が効かず、そのままだと 1920x1080 で
     2倍の盤面の上に等倍のダイアログが乗って、文字だけ急に小さくなる。 */
  .overlay .panel {
    position: relative; overflow: hidden;
    background: linear-gradient(180deg, #ffffff, #f4f8f9); border-radius: 26px; padding: 28px 26px;
    max-width: 350px; width: 100%; text-align: center;
    box-shadow: 0 24px 60px rgba(8,30,40,0.4), inset 0 1px 0 rgba(255,255,255,0.9);
    transform: scale(var(--fit));
    animation: pop 0.4s cubic-bezier(0.2,1.4,0.4,1);
  }
  @keyframes pop { from { opacity: 0; transform: scale(calc(var(--fit) * 0.9)) translateY(14px); } }
  /* パネル上部の色帯 */
  .overlay .panel::before {
    content: ""; position: absolute; top: 0; left: 0; right: 0; height: 6px;
    background: linear-gradient(90deg, var(--accent, var(--teal)), color-mix(in srgb, var(--accent, var(--teal)) 55%, #fff));
  }
  .overlay .emoji { font-size: 52px; filter: drop-shadow(0 4px 8px rgba(0,0,0,0.15)); animation: trophy 1.4s ease-in-out infinite; }
  .overlay .emoji .ui-icon { width: 52px; height: 52px; vertical-align: middle; }
  @keyframes trophy { 0%,100% { transform: rotate(-6deg); } 50% { transform: rotate(6deg); } }
  .overlay h2 { font-size: 23px; font-weight: 900; margin-top: 10px; letter-spacing: -0.5px; }
  .overlay p { font-size: 14px; font-weight: 600; color: #66757d; margin-top: 8px; line-height: 1.5; }
  .overlay .primary { width: 100%; margin-top: 18px; padding: 14px; border-radius: 14px; color: #fff; font-size: 14px; font-weight: 900; box-shadow: 0 6px 16px rgba(20,50,60,0.25); transition: transform 0.12s; }
  .overlay .primary:active { transform: scale(0.97); }
  .overlay .secondary { width: 100%; margin-top: 8px; padding: 12px; border-radius: 14px; background: #eef2f3; font-size: 14px; font-weight: 800; color: #46545c; }
  .overlay.handoff {
    z-index: 60; background: linear-gradient(155deg, #16333d, #10272f 58%, #1c3e48);
    -webkit-backdrop-filter: none; backdrop-filter: none;
  }
  .overlay.handoff .panel { max-width: 330px; }
  .handoff-mark {
    width: 74px; height: 74px; margin: 2px auto 12px; border-radius: 50%;
    display: grid; place-items: center; color: #fff; font-size: 34px;
    box-shadow: 0 10px 24px rgba(10,25,30,0.28), inset 0 0 0 4px rgba(255,255,255,0.28);
  }
  /* 紙吹雪 */
  #confetti { position: fixed; inset: 0; z-index: 21; pointer-events: none; overflow: hidden; }
  #confetti i {
    position: absolute; top: -6vh; width: 9px; height: 14px; border-radius: 2px;
    animation: fall linear forwards;
  }
  @keyframes fall {
    to { transform: translateY(112vh) rotate(720deg); opacity: 0.9; }
  }
  /* トーストは手札ドックの上端より上に出す。以前は viewport 基準の
     `fixed; bottom: 205px` だったため、盤面が上下中央寄せで動くとドックの
     ガイド行 (.coach) に重なって下の文字が透けていた。
     高さが変わっても下端が動かないよう、下端を指定して上へ伸ばす。 */
  /* --dockH は論理キャンバスの中の長さなので、盤面が拡大されている分だけ掛ける
     (そうしないと 1920x1080 では実際のドックの半分の高さしか避けられない)。
     文字も盤面と同じ倍率で拡大する。この2つは .stage の外にあるため、
     盤面の scale() が効かず、放っておくと相対的に小さい文字のまま残る。 */
  /* 盤面を覆う面積を減らすための3点。
     1. ドックの上端にぴったり付ける。以前は 12px 浮かせていたため、黒い箱が
        盤面の中ほどに浮いて人物と小便器を覆っていた。
     2. 幅は論理キャンバスに対する比で決める。実寸で 520px に絞っていたので、
        倍率の高い画面ほど「細くて背の高い箱」になり、いちばん余裕のある画面が
        いちばん邪魔になっていた (1920x1080 で 520x364、盤面の高さの34%)。
     3. 横に広げるほど行数が減り、同じ文でも盤面に食い込む高さが下がる。
     width は max-content で決める。既定の shrink-to-fit だと「包含ブロックの幅 -
     left」が上限になり、盤面の中央に置いている都合で常に画面の半分しか使えない
     (960x540 なら max-width を 820px にしても 480px で折り返していた)。 */
  #toast {
    position: absolute;
    top: calc(var(--stage-bottom) - (var(--dockH) + 4px) * var(--fit));
    left: var(--stage-mid);
    /* 下端を上の top に固定したまま拡大する (origin が下端中央) */
    transform-origin: bottom center;
    transform: translate(-50%, -100%) scale(var(--fit));
    width: max-content; max-width: min(calc(94vw / var(--fit)), 820px);
    text-align: center; line-height: 1.4;
    background: rgba(20,30,35,0.9); color: #fff; font-size: 14px; font-weight: 800;
    padding: 8px 16px; border-radius: 14px; z-index: 30; pointer-events: none;
    opacity: 0; transition: opacity 0.25s;
  }
  #toast.show { opacity: 1; }

  /* 演出バナー */
  /* 演出バナーは上部の指示バーに重ねて出す (位置は盤面基準。--fx-offset)。 */
  #fx-stack {
    position: absolute;
    top: calc(var(--stage-top) + var(--fx-offset) * var(--fit));
    left: var(--stage-mid);
    /* 上端を上の top に固定したまま拡大する (origin が上端中央) */
    transform-origin: top center;
    transform: translateX(-50%) scale(var(--fit)); z-index: 40;
    display: flex; flex-direction: column; gap: 8px; align-items: center;
    pointer-events: none; width: max-content; max-width: calc(92vw / var(--fit));
  }
  .fx-banner {
    display: flex; align-items: center; gap: 10px;
    background: rgba(255,255,255,0.97); border-radius: 999px; padding: 10px 20px;
    font-size: 15px; font-weight: 900; color: var(--ink);
    box-shadow: 0 8px 24px rgba(10,40,50,0.28);
    animation: fxin 0.3s cubic-bezier(0.2, 1.4, 0.4, 1);
    max-width: calc(92vw / var(--fit));
  }
  .fx-banner .fx-icon { font-size: 22px; }
  .fx-banner .fx-icon .ui-icon { width: 26px; height: 26px; vertical-align: middle; }
  .fx-banner.gold {
    background: linear-gradient(90deg, #fff6d8, #ffe9a8);
    box-shadow: 0 8px 26px rgba(220,160,20,0.5);
  }
  .fx-banner.red {
    background: linear-gradient(90deg, #ffe3dc, #ffc9bd);
    box-shadow: 0 8px 26px rgba(200,60,30,0.45);
  }
  .fx-banner.out { opacity: 0; transform: translateY(-10px); transition: all 0.3s; }
  @keyframes fxin { from { opacity: 0; transform: translateY(-16px) scale(0.85); } }

  .door-btn.shaking { animation: doorshake 0.13s linear infinite; }
  @keyframes doorshake {
    0% { transform: translateX(0); }
    25% { transform: translateX(-3px) rotate(-0.6deg); }
    75% { transform: translateX(3px) rotate(0.6deg); }
    100% { transform: translateX(0); }
  }

  @media (max-width: 480px) {
    .fx-banner { font-size: 14px; padding: 8px 14px; }
    .fx-banner .fx-icon { font-size: 17px; }
  }

  /* ===== ロゴ ===== */
  .logo-svg, .logo-img { display: block; width: min(100%, 330px); height: auto; position: relative; filter: drop-shadow(0 5px 12px rgba(0,0,0,0.35)); }
  .logo-composite { position: relative; width: min(100%, 330px); aspect-ratio: 16 / 9; filter: drop-shadow(0 5px 12px rgba(0,0,0,0.35)); }
  .logo-composite .logo-img { width: 100%; height: 100%; object-fit: contain; filter: none; }
  .logo-copy { position: absolute; left: 0; top: 31%; width: 57%; text-align: center; color: #fff; text-shadow: 0 3px 0 #14313d, 0 5px 10px rgba(0,0,0,0.35); }
  .logo-copy .main { display: block; font-size: 20px; font-weight: 900; letter-spacing: -1.3px; white-space: nowrap; transform: scaleX(0.88); }
  .logo-copy .sub { display: block; margin-top: 4px; color: #ffe28a; font-size: 14px; font-weight: 900; letter-spacing: 1px; white-space: nowrap; transform: scaleX(0.9); }

  /* ヒーローに立ちのぼる泡 */
  .hero .bub {
    position: absolute; bottom: -26px; border-radius: 50%; pointer-events: none;
    background: radial-gradient(circle at 32% 30%, rgba(255,255,255,0.95), rgba(255,255,255,0.25) 55%, rgba(255,255,255,0.06));
    animation: rise linear infinite;
  }
  .hero .bub:nth-of-type(1) { left: 10%; width: 13px; height: 13px; animation-duration: 6.5s; }
  .hero .bub:nth-of-type(2) { left: 32%; width: 8px; height: 8px; animation-duration: 5.2s; animation-delay: 1.4s; }
  .hero .bub:nth-of-type(3) { left: 68%; width: 16px; height: 16px; animation-duration: 7.4s; animation-delay: 0.6s; }
  .hero .bub:nth-of-type(4) { left: 87%; width: 10px; height: 10px; animation-duration: 5.8s; animation-delay: 2.4s; }
  @keyframes rise {
    0% { transform: translateY(0) translateX(0); opacity: 0; }
    12% { opacity: 0.9; }
    100% { transform: translateY(-150px) translateX(12px); opacity: 0; }
  }
  /* ===== ハンドカードのSVGアイコン (画像が未配信/未読込のときのフォールバック) ===== */
  .hcard .card-visual > svg {
    position: absolute; left: 50%; top: 50%; width: 52px; height: 52px;
    transform: translate(-50%, -50%); transform-origin: center;
  }
  /* カードは人物画像を主役にし、カード内の装飾は静止させる。 */
  .hcard .card-visual > svg, .hcard .card-art { animation: none !important; }
  .hcard .card-art { will-change: auto; }


  /* ===== 配置・モップ・ノックの演出 ===== */
  @keyframes arrive {
    0% { transform: translateY(-32px) scale(0.7); opacity: 0; }
    60% { transform: translateY(3px) scale(1.06); opacity: 1; }
    100% { transform: translateY(0) scale(1); }
  }
  .urinal .person-img.arrive, .urinal .person-svg.arrive {
    animation: arrive 0.5s cubic-bezier(0.25, 1.1, 0.4, 1), bob 3.6s ease-in-out 0.55s infinite;
  }
  @keyframes doorpop { 0% { transform: scale(0.92); } 55% { transform: scale(1.05); } 100% { transform: scale(1); } }
  .door-btn.arrive { animation: doorpop 0.42s ease; }
  .mop-spark { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
  .mop-spark i { position: absolute; font-style: normal; font-size: 15px; opacity: 0; animation: spark 0.95s ease forwards; }
  .mop-spark i .ui-icon { width: 1em; height: 1em; vertical-align: middle; }
  @keyframes spark {
    0% { transform: translateY(8px) scale(0.4) rotate(-15deg); opacity: 0; }
    30% { opacity: 1; }
    100% { transform: translateY(-30px) scale(1.2) rotate(15deg); opacity: 0; }
  }
  /* ===== 勝敗オーバーレイのキャラ ===== */
  .result-scene {
    position: relative; height: 138px; margin-top: 4px;
    display: flex; align-items: flex-end; justify-content: center; gap: 4px;
  }
  .result-scene .burst {
    position: absolute; left: 50%; top: 55%; width: 300px; height: 300px;
    transform: translate(-50%, -50%); border-radius: 50%; pointer-events: none;
    background: repeating-conic-gradient(color-mix(in srgb, var(--accent, var(--teal)) 15%, transparent) 0 11deg, transparent 11deg 26deg);
    -webkit-mask-image: radial-gradient(circle, #000 20%, transparent 68%);
            mask-image: radial-gradient(circle, #000 20%, transparent 68%);
    animation: spinslow 18s linear infinite;
  }
  @keyframes spinslow { to { transform: translate(-50%, -50%) rotate(360deg); } }
  .person-result { position: relative; height: 100%; width: auto; filter: drop-shadow(0 6px 8px rgba(0,0,0,0.18)); animation: winpop 0.55s cubic-bezier(0.2, 1.5, 0.4, 1); }
  img.person-result { height: 100%; }
  .person-result.lose-art { height: 76%; transform-origin: 50% 92%; animation: losewob 2.2s ease-in-out infinite; }
  @keyframes winpop { from { transform: translateY(24px) scale(0.5); opacity: 0; } }
  @keyframes losewob { 0%, 100% { transform: rotate(-2.5deg); } 50% { transform: rotate(2.5deg); } }

  /* ===== 楽しさポリッシュv3: VS対面 / 臭気 / 擬音 / 緊迫演出 / 洗面台 / 効果音UI ===== */
  /* メニューの VS 対面シーン */
  .vs-scene { position: relative; display: flex; justify-content: center; align-items: flex-end; gap: 38px; height: 112px; margin-top: 18px; }
  .vs-scene .mirror { display: block; height: 100%; transform: scaleX(-1); }
  .vs-scene .person-result { height: 100%; }
  .vs-badge {
    position: absolute; left: 50%; top: 36%; z-index: 2;
    font-size: 27px; font-weight: 900; font-style: italic; color: #ffd75e; letter-spacing: 1px;
    text-shadow: -2px 0 0 #14313d, 2px 0 0 #14313d, 0 -2px 0 #14313d, 0 2px 0 #14313d, 0 5px 12px rgba(0,0,0,0.45);
    transform: translate(-50%, -50%) rotate(-7deg);
    animation: vspulse 1.5s ease-in-out infinite;
  }
  @keyframes vspulse { 50% { transform: translate(-50%, -50%) rotate(-7deg) scale(1.16); } }

  /* 使用済み・閉鎖設備から立ちのぼる臭気 */
  .stink { position: absolute; left: 50%; transform: translateX(-50%); display: flex; gap: 8px; z-index: 3; pointer-events: none; }
  .stallbox .stink { top: 40px; z-index: 5; }
  .stink i {
    width: 4px; height: 17px; border-radius: 4px;
    background: linear-gradient(180deg, rgba(130,165,90,0), rgba(118,148,78,0.72));
    animation: stinkup 1.8s ease-in-out infinite;
  }
  .stink i:nth-child(2) { height: 21px; animation-delay: 0.6s; }
  .stink i:nth-child(3) { animation-delay: 1.2s; }
  @keyframes stinkup {
    0% { transform: translateY(9px) skewX(10deg) scaleY(0.5); opacity: 0; }
    35% { transform: translateY(0) skewX(-10deg) scaleY(1); opacity: 0.85; }
    100% { transform: translateY(-15px) skewX(10deg) scaleY(1.1); opacity: 0; }
  }

  /* 使用済み(閉鎖前)の小便器に集まるハエ。在室中でも空室でも出す (耐久は公開情報のため)。
     実際のハエは「等速の直線飛行」の合間に平均90°前後の方向転換をほぼ瞬時に行う
     ("サッケード"運動)。区間ごとの距離に応じて%幅を配分し、animation-timing-function は
     linear のままにすることで、各区間は等速・区間の切り替わりだけが一瞬で向きを変える。 */
  .urinal .flies { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
  .urinal .flies .bug { position: absolute; width: 4px; height: 3px; animation: flysaccade 2.2s linear infinite; }
  .urinal .flies .bug .body { position: absolute; inset: 0; background: #221b16; border-radius: 50%; }
  .urinal .flies .bug .wing {
    position: absolute; top: -1px; width: 3.5px; height: 2.5px;
    background: rgba(90,92,96,0.55); border-radius: 60% 60% 60% 10%;
    animation: wingflap 0.2s linear infinite alternate;
  }
  .urinal .flies .bug .wing.l { left: -4px; transform-origin: right center; }
  .urinal .flies .bug .wing.r { right: -4px; transform-origin: left center; border-radius: 60% 60% 10% 60%; }
  @keyframes wingflap {
    from { transform: scaleY(0.35) rotate(-10deg); }
    to   { transform: scaleY(1) rotate(10deg); }
  }
  @keyframes flysaccade {
    0%      { transform: translate(0, 0); }
    14.66%  { transform: translate(16px, -14px); }
    27.73%  { transform: translate(22px, 4px); }
    44.17%  { transform: translate(2px, 17px); }
    58.78%  { transform: translate(-18px, 10px); }
    77.10%  { transform: translate(-9px, -15px); }
    92.97%  { transform: translate(10px, -2px); }
    100%    { transform: translate(0, 0); }
  }

  /* コミック風の擬音ポップ */
  .comic-pop {
    position: absolute; z-index: 6; pointer-events: none; white-space: nowrap;
    font-size: 14px; font-weight: 900; color: var(--ink);
    background: #fff; border: 2px solid #24303a; border-radius: 10px; padding: 3px 8px;
    box-shadow: 0 3px 7px rgba(0,0,0,0.25);
  }
  .knock-pop { top: 22px; right: -12px; transform: rotate(7deg); animation: popin 0.4s cubic-bezier(0.2,1.6,0.4,1) both; }
  .door-pop { top: 34px; left: 50%; transform: translateX(-50%) rotate(-5deg); animation: peefade 1.7s ease both; }
  /* 顔に被らないよう、擬音は足元 (小便器の高さ) に出す */
  .pee-pop { top: auto; bottom: 60px; left: 50%; transform: translateX(-50%) rotate(-5deg); font-size: 14px; animation: peefade 1.9s ease both; }
  @keyframes popin { from { opacity: 0; transform: rotate(7deg) scale(0.4); } }
  @keyframes peefade {
    0% { opacity: 0; transform: translateX(-50%) rotate(-5deg) scale(0.55); }
    12% { opacity: 1; transform: translateX(-50%) rotate(-5deg) scale(1.06); }
    72% { opacity: 1; }
    100% { opacity: 0; transform: translateX(-50%) translateY(-9px) rotate(-5deg); }
  }


  /* NPC思考中のドット */
  .think-dots i { display: inline-block; font-style: normal; animation: thinkdot 1.2s infinite; }
  .think-dots i:nth-child(2) { animation-delay: 0.18s; }
  .think-dots i:nth-child(3) { animation-delay: 0.36s; }
  @keyframes thinkdot { 0%, 60%, 100% { opacity: 0.2; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-2px); } }

  /* 王手 (あと1ラウンドで勝利) の王冠 */
  .side .crown { font-size: 14px; filter: drop-shadow(0 1px 1px rgba(0,0,0,0.25)); }
  .side .crown .ui-icon { width: 16px; height: 16px; vertical-align: middle; }

  .hud-top .icon-btn .ui-icon { width: 20px; height: 20px; vertical-align: middle; }

  @media (max-width: 480px) {
    .vs-scene { height: 96px; gap: 24px; }
    .vs-badge { font-size: 21px; }
    .stink i { height: 13px; }
    .stink i:nth-child(2) { height: 16px; }
    .comic-pop { padding: 2px 6px; }
  }
  @media (max-width: 560px) {
    /* 6枚を1行に並べると1枚50pxしかなく、14pxの名前が入らないので 3列x2段にする。 */
    .hand-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); grid-auto-rows: 1fr; gap: 5px; }
    /* 人物シーンを縦いっぱいに伸ばし、カード上の文字はバッジと理由だけにする。 */
    .hcard { padding: 3px; min-height: 0; }
    .hcard .card-visual { border-radius: 8px; }
    .card-name, .hcard .card-stock { font-size: 13px; }
    .hcard .card-lock { font-size: 13px; padding: 2px 3px; }
    .hcard .stay-dots { padding: 2px 4px; }
    /* dockH は実測値 (syncDockHeight) なので、手札が2段になる分もすでに込み。
       以前はここに追加で+58pxのバッファを積んでいたが、実測と二重に空間を取ってしまい
       壁の空白を不必要に広げていたため、他の画面幅と同じ+20px相当まで削る */
    .fixtures { bottom: calc(var(--dockH) + 24px); }
  }
  @media (max-width: 360px) {
    .dock2 { padding-inline: 7px; }
    .hcard { padding: 3px; min-height: 0; }
    .hcard .card-visual { border-radius: 7px; }
    .side .win-dot { width: 10px; height: 10px; }
  }

  /* 上の共通カード定義より後に置き、背の低い画面の圧縮値を確実に適用する。 */
  @media (max-width: 480px) and (max-height: 760px) {
    :root { --dockH: 348px; }
    .dock2 { height: 340px; overflow-y: auto; }
    .opponent-dock { height: 340px; }
    .end-btn { padding: 6px 10px; font-size: 14px; }
    .hcard { min-height: 0; }
  }

  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      scroll-behavior: auto !important;
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
    }
    .hero .bub, #confetti, .result-scene .burst { display: none !important; }
  }
