:root {
  --bg: #1b1f2b;
  --panel: #262b3a;
  --panel-alt: #2f3548;
  --accent: #5b8def;
  --accent-hover: #4a78d6;
  --text: #eef1f8;
  --text-dim: #9aa3b8;
  --error: #ff6b6b;
  --border: #3a4054;
  /* One radius for every piece of shop chrome: the cut edge of paper or wood.
     Game surfaces (cards, cells, stones) keep their own, rounder shapes. */
  --radius: 3px;
  /* Where the bottom row of the floating tool stack sits. The start plaque
     holds the corner while a room waits to begin, and the stack stands on top
     of it; once play starts the plaque goes and the stack takes the corner. */
  --tool-stack-base: 20px;
  /* 将棋の盤は昼と夜の二面を持つ。既定は榧と漆 ―― 盤を静かにして駒を
     主役にし、後手は向きで見分ける本式。body.board-dark が行灯に
     差し替える(下)。値はすべてトークンで、盤の組み方そのものは共通。 */
  --shogi-frame-a: #4a3524;
  --shogi-frame-b: #241810;
  --shogi-frame-edge: var(--shop-brass);
  --shogi-frame-sheen: rgba(255, 255, 255, 0.1);
  --shogi-frame-drop: rgba(20, 12, 4, 0.38);
  --shogi-board-a: #eed3a4;
  --shogi-board-b: #dfbc82;
  /* 木目と照りは片方だけを使う。使わない側は透明のまま重ねる。 */
  --shogi-board-grain:
    repeating-linear-gradient(92deg,
      rgba(90, 62, 28, 0.055) 0 1px, transparent 1px 9px);
  --shogi-board-sheen: linear-gradient(transparent, transparent);
  --shogi-line: rgba(46, 29, 14, 0.6);
  --shogi-line-edge: #3a2612;
  --shogi-star: rgba(46, 29, 14, 0.72);
  --shogi-tray-a: #4a3524;
  --shogi-tray-b: #2b1d12;
  --shogi-tray-border: var(--shop-walnut-deep);
  --shogi-tray-sheen: rgba(255, 255, 255, 0.07);
  --shogi-piece-a: #fbf1d2;
  --shogi-piece-b: #e8cf9c;
  --shogi-piece-flip-a: #f7ecca;
  --shogi-piece-flip-b: #e2c891;
  --shogi-piece-edge: #6d4a22;
  --shogi-piece-shadow: 0 1px 2px rgba(40, 24, 10, 0.34);
  --shogi-piece-bevel:
    inset 0 -3px 5px rgba(122, 86, 40, 0.3),
    inset 0 2px 2px rgba(255, 248, 226, 0.75);
  --shogi-ink: #1d140b;
  --shogi-ink-flip: #1d140b;
  --shogi-ink-red: #9c2b26;
  --shogi-ink-red-flip: #9c2b26;
  --shogi-ink-weight: 900;
  --shogi-dot-gote-ring: 0 0 0 1px var(--shop-walnut-deep) inset;
  --shogi-selected: rgba(226, 168, 58, 0.42);
  --shogi-legal: rgba(52, 84, 66, 0.62);
  --shogi-legal-ring: rgba(52, 84, 66, 0.85);
  --shogi-check: rgba(163, 45, 38, 0.5);
  --shogi-last-move: rgba(226, 168, 58, 0.18);

  /* リバーシの盤も同じく二面。既定は蛤と那智黒 ―― 羅紗の色を落として
     将棋と同じ胡桃の枠に納め、石は厚みで盤から起き上がる。将棋と同じ札
     (body.board-dark)で行灯に切り替わる。 */
  --reversi-frame-a: #4a3524;
  --reversi-frame-b: #241810;
  --reversi-frame-edge: var(--shop-brass);
  --reversi-frame-sheen: rgba(255, 255, 255, 0.1);
  --reversi-frame-drop: rgba(20, 12, 4, 0.38);
  --reversi-line: rgba(16, 34, 26, 0.85);
  --reversi-felt-a: #2f5f4a;
  --reversi-felt-b: #27513f;
  /* 羅紗の毛並み。斜めに寝かせて、平らな緑に触感を一枚かける。 */
  --reversi-felt-nap:
    repeating-linear-gradient(98deg,
      rgba(0, 0, 0, 0.035) 0 1px, transparent 1px 6px);
  --reversi-felt-sheen:
    radial-gradient(115% 90% at 50% 0%, rgba(255, 255, 255, 0.05), transparent 62%);
  --reversi-felt-hover: rgba(255, 255, 255, 0.07);
  --reversi-star: rgba(6, 16, 11, 0.92);
  --reversi-coord: var(--shop-brass-light);
  --reversi-black: radial-gradient(circle at 36% 26%, #5a625c 0%, #232825 42%, #0c0e0d 100%);
  --reversi-black-bevel:
    inset 0 -4px 6px rgba(0, 0, 0, 0.55),
    inset 0 2px 3px rgba(255, 255, 255, 0.22);
  --reversi-black-shadow: 0 3px 4px rgba(0, 0, 0, 0.5), 0 1px 0 #05100b;
  --reversi-white: radial-gradient(circle at 36% 26%, #fffdf6 0%, #f4ecd9 45%, #d9cdb2 100%);
  --reversi-white-bevel:
    inset 0 -4px 6px rgba(120, 100, 68, 0.28),
    inset 0 2px 3px rgba(255, 255, 255, 0.9);
  --reversi-white-shadow: 0 3px 4px rgba(0, 0, 0, 0.38), 0 1px 0 #b3a68c;
  --reversi-legal: rgba(221, 192, 127, 0.85);
  --reversi-last: var(--shop-brass-light);

  /* チェスも二面。昼は木で挽いた卓 ―― 将棋・リバーシと同じ胡桃の枠に納め、
     マスは木口の差で分け、駒は黄楊と黒檀。夜は同じ札(body.board-dark)で
     盤の面だけ灯を落とす(下)。枠と金物は昼夜とも胡桃と真鍮のまま
     ―― 木も金物も灯りで材は変わらないので、灯を落とすだけにする。 */
  --chess-frame-a: #4a3524;
  --chess-frame-b: #241810;
  --chess-frame-edge: var(--shop-brass);
  --chess-frame-sheen: rgba(255, 255, 255, 0.1);
  --chess-frame-drop: rgba(20, 12, 4, 0.38);
  --chess-board-edge: #3a2612;
  /* 木口は92度に寝かせた筋。マスごとに同じ木口が来るが、48pxでは
     木目が繰り返しに見えるほど大きくないのでこれでいい。 */
  --chess-light:
    repeating-linear-gradient(92deg, rgba(90, 62, 28, 0.05) 0 1px, transparent 1px 9px),
    linear-gradient(160deg, #eed9ad, #e3c894);
  --chess-dark:
    repeating-linear-gradient(92deg, rgba(20, 10, 4, 0.1) 0 1px, transparent 1px 9px),
    linear-gradient(160deg, #8d6238, #6f4a29);
  --chess-hover: rgba(255, 255, 255, 0.1);
  --chess-coord: var(--shop-brass-light);
  --chess-selected: rgba(226, 168, 58, 0.85);
  --chess-last: rgba(226, 168, 58, 0.34);
  --chess-legal: rgba(58, 38, 18, 0.72);
  --chess-capture: rgba(163, 45, 38, 0.75);
  --chess-check: rgba(163, 45, 38, 0.45);
  --chess-white-face: #f4e3bd;
  --chess-white-edge: #6d4a22;
  --chess-white-line: #6d4a22;
  --chess-white-bevel: #fff8e2;
  --chess-white-bevel-alpha: 0.5;
  --chess-black-face: #33251a;
  --chess-black-edge: #150d07;
  --chess-black-line: #c9b189;
  --chess-black-bevel: #6b5540;
  --chess-black-bevel-alpha: 0.45;
  --chess-piece-shadow: 0 2px 2px rgba(40, 24, 10, 0.45);

  /* 〇✕の卓も二面。既定は帳面 ―― 店の伝票と同じ和紙に細い罫を刷り、手は
     藍印と朱印を捺す。判子なので欠けはいつも同じ位置に出る。同じ札
     (body.board-dark)で夜の半紙に替わり、そちらは筆で書く(下)。 */
  --ttt-paper-a: #f0e6cf;
  --ttt-paper-b: #e4d7b4;
  --ttt-paper-grain: var(--shop-paper-grain);
  --ttt-paper-sheen: linear-gradient(transparent, transparent);
  --ttt-board-edge:
    0 0 0 1px rgba(42, 36, 28, 0.5),
    0 0 0 4px var(--shop-paper),
    0 0 0 5px rgba(42, 36, 28, 0.28),
    0 10px 20px rgba(12, 8, 4, 0.34);
  --ttt-rule: rgba(42, 36, 28, 0.42);
  --ttt-rule-width: 1px;
  --ttt-ink-o: #2b4a78;
  --ttt-ink-x: #a8352b;
  --ttt-win: #a8352b;
  --ttt-cell-hover: rgba(42, 36, 28, 0.06);
  --ttt-cell-win: rgba(196, 150, 60, 0.16);
  --ttt-ghost: 0.28;

  /* 大富豪の卓。場に緋毛氈を敷き、将棋・リバーシ・チェスと同じ胡桃の枠に
     納める ―― 盤を持たない札の卓に、置き場という面を一枚与える。毛氈は
     かるたの席の緋色で、リバーシの羅紗(緑)とは別の布。 */
  --daifugo-frame-a: #4a3524;
  --daifugo-frame-b: #241810;
  --daifugo-frame-edge: var(--shop-brass);
  --daifugo-frame-sheen: rgba(255, 255, 255, 0.1);
  --daifugo-frame-drop: rgba(20, 12, 4, 0.38);
  --daifugo-mousen-a: #a8352b;
  --daifugo-mousen-b: #7d2119;
  /* 毛氈の毛並み。羅紗と同じ角度に寝かせて、平らな緋色に触感をかける。 */
  --daifugo-mousen-nap:
    repeating-linear-gradient(98deg,
      rgba(0, 0, 0, 0.045) 0 1px, transparent 1px 6px);
  --daifugo-mousen-sheen:
    radial-gradient(120% 100% at 50% -12%, rgba(255, 236, 214, 0.13), transparent 62%);
  --daifugo-mousen-well: inset 0 2px 5px rgba(60, 12, 8, 0.45);
  --daifugo-mousen-ink: rgba(255, 233, 208, 0.72);
  --daifugo-mousen-ink-soft: rgba(255, 233, 208, 0.6);
  --daifugo-plate-name: var(--shop-brass-light);
  --daifugo-plate-name-lit: #f4e7c4;
  --daifugo-plate-sub: rgba(221, 192, 127, 0.6);
  --daifugo-plate-sub-lit: rgba(244, 231, 196, 0.75);
  --daifugo-plate-edge: rgba(180, 144, 63, 0.55);
  --daifugo-plate-lit:
    0 0 0 1px var(--shop-brass),
    0 0 12px rgba(180, 144, 63, 0.45),
    0 2px 3px rgba(20, 12, 4, 0.38);
  /* ヨットの卓。賽は紺鉄の羅紗を張った盆に落とす ―― リバーシの羅紗(緑)、
     大富豪の毛氈(緋)とは別の布で、賽を転がすためだけの一枚。枠は将棋・
     リバーシ・チェス・大富豪と同じ胡桃。 */
  --yacht-frame-a: #4a3524;
  --yacht-frame-b: #241810;
  --yacht-frame-edge: var(--shop-brass);
  --yacht-frame-sheen: rgba(255, 255, 255, 0.1);
  --yacht-frame-drop: rgba(20, 12, 4, 0.38);
  --yacht-rasha-a: #2c4356;
  --yacht-rasha-b: #22354a;
  /* 羅紗の毛並みと照り。リバーシの盤と同じ角度に寝かせる。 */
  --yacht-rasha-nap:
    repeating-linear-gradient(98deg,
      rgba(0, 0, 0, 0.035) 0 1px, transparent 1px 6px);
  --yacht-rasha-sheen:
    radial-gradient(115% 90% at 50% 0%, rgba(255, 255, 255, 0.05), transparent 62%);
  --yacht-rasha-well:
    inset 0 0 0 1px rgba(0, 0, 0, 0.35),
    inset 0 2px 6px rgba(0, 0, 0, 0.3);
  --yacht-rail-ink: var(--shop-brass-light);
  /* 賽は店の一組(--die-*)。盆に落ちる56pxも点取帳の行頭の16pxも、挽き方は
     同じで大きさだけが違うので、ヨットは骨も目も自前では持たない。 */
  /* 点取帳。自分の列だけ地を落とし、小計の帯はその下に敷く。 */
  --yacht-self-tint: rgba(180, 144, 63, 0.1);
  /* 小計の帯。左端に留める役の名の升と同じ地でなければならないので、
     透かしではなく、紙(--shop-paper-light)に重ねた色をそのまま置く。 */
  --yacht-band-tint: #e9dfc3;

  /* 店の賽。地はリバーシの蛤と同じ挽き方、目は彫って下辺の照り返しで出す
     ―― 使うのはライアーズダイスとヨットなので、遊びの名は付けない。 */
  --die-bone: radial-gradient(circle at 36% 26%, #fffdf6 0%, #f4ecd9 45%, #d9cdb2 100%);
  --die-bevel:
    inset 0 -4px 6px rgba(120, 100, 68, 0.28),
    inset 0 2px 3px rgba(255, 255, 255, 0.9);
  --die-shadow: 0 3px 4px rgba(0, 0, 0, 0.38), 0 1px 0 #b3a68c;
  /* まだ振っていない賽。同じ地を一段落として、目が無いのは伏せているから
     ではなく、まだ出ていないからだと色で示す(ヨットの一投目より前)。 */
  --die-bone-idle: radial-gradient(circle at 36% 26%, #efe6d2 0%, #e2d6ba 45%, #cdbf9f 100%);
  --die-pip: radial-gradient(circle at 38% 32%, #4a4238, #241c12 72%);
  --die-pip-sheen: 0 1px 0 rgba(255, 255, 255, 0.65);

  /* ライアーズダイスの卓。賽を転がす面が要る ―― 胡桃の枠(将棋・リバーシ・
     チェス・大富豪と同じ)に鞣した革を張る。毛氈の緋・羅紗の緑・紫紺の布に
     対して、ここだけは布ではなく革。色は箱絵(public/cover-art.js の
     liarsdice)の地から起こしたが、箱絵の茶のままだと枠と明度が近すぎて
     枠が枠に見えないので、一段明るい飴色に振り、革の際に暗い立ち上がりを
     一本入れて分けている。 */
  --liarsdice-frame-a: #4a3524;
  --liarsdice-frame-b: #241810;
  --liarsdice-frame-edge: var(--shop-brass);
  --liarsdice-frame-sheen: rgba(255, 255, 255, 0.1);
  --liarsdice-frame-drop: rgba(20, 12, 4, 0.38);
  --liarsdice-hide-a: #9c5a34;
  --liarsdice-hide-b: #63321d;
  /* 革の肌理と照り。毛氈・羅紗と違って毛並みはないので、紙と同じ角度の
     細かい目を薄く敷くだけにする。 */
  --liarsdice-hide-nap:
    repeating-linear-gradient(115deg,
      rgba(42, 36, 28, 0.05) 0 1px, transparent 1px 5px);
  --liarsdice-hide-sheen:
    radial-gradient(120% 100% at 50% -10%, rgba(255, 236, 214, 0.15), transparent 60%);
  --liarsdice-hide-well:
    inset 0 0 0 1px rgba(20, 8, 2, 0.55),
    inset 0 2px 6px rgba(40, 14, 6, 0.5);
  --liarsdice-hide-rule: rgba(221, 192, 127, 0.3);
  --liarsdice-hide-ink: rgba(255, 233, 208, 0.72);
  /* 革に空押しした賽筒。入口の帳場(index.html の .entry-counter)と同じ
     描き方 ―― 胡桃色に沈めて、真鍮の細い線を一本だけ。 */
  --liarsdice-tooling-fill: rgba(40, 16, 6, 0.16);
  --liarsdice-tooling-line: rgba(255, 236, 214, 0.16);
  --liarsdice-tooling-pip: rgba(18, 7, 2, 0.14);
  /* 打ち手の木札。大富豪・ばば抜きと同じ組みで、手番だけ真鍮が灯る。 */
  --liarsdice-plate-name: var(--shop-brass-light);
  --liarsdice-plate-name-lit: #f4e7c4;
  --liarsdice-plate-sub: rgba(221, 192, 127, 0.6);
  --liarsdice-plate-sub-lit: rgba(244, 231, 196, 0.75);
  --liarsdice-plate-edge: rgba(180, 144, 63, 0.55);
  --liarsdice-plate-lit:
    0 0 0 1px var(--shop-brass),
    0 0 12px rgba(180, 144, 63, 0.45),
    0 2px 3px rgba(20, 12, 4, 0.38);

  /* 残り枚数の頭に付く札束の目印。色は置いた場所の文字色をそのまま拾う。
     大富豪とばば抜きの両方の木札が使うので、遊びの名は付けない。 */
  --card-stack-mark:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 13 13' fill='none' stroke='%23000' stroke-width='1' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='0.5' y='2.5' width='8' height='10' rx='1.5'/%3E%3Cpath d='M2.5 1.5H10.5V10'/%3E%3Cpath d='M4.5 0.5H12.5V8'/%3E%3C/svg%3E");
  /* 同じ組みで、こちらは銭の重なり ―― 手持ちのチップの頭に付く。
     枚数ではなく額を出す卓(ポーカー)が使うので、こちらも遊びの名は付けない。 */
  --chip-stack-mark:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 13 13' fill='none' stroke='%23000' stroke-width='1'%3E%3Cellipse cx='6.5' cy='9.6' rx='5.4' ry='2.2'/%3E%3Cellipse cx='6.5' cy='6.5' rx='5.4' ry='2.2'/%3E%3Cellipse cx='6.5' cy='3.4' rx='5.4' ry='2.2'/%3E%3C/svg%3E");
  /* 伏せ札の地。札の表(public/cards.js)が店に一組しかないのと同じで、裏も
     一枚 ―― ばば抜きは同じ裏に引く位置の番号を入れて使う。 */
  --card-back: #20143a;
  --card-back-ring: var(--shop-violet-deep);

  /* ばば抜きの卓。相手の手を番号ボタンではなく伏せ札の扇で差し出すための
     面を一枚与える ―― 布は箱の色(紫紺)から採り、枠は将棋・リバーシ・
     チェス・大富豪と同じ胡桃。伏せ札の地は箱絵(public/cover-art.js の
     babanuki)の伏せ札とそのまま同じ色で、布の上に置いても沈まない。 */
  --babanuki-frame-a: #4a3524;
  --babanuki-frame-b: #241810;
  --babanuki-frame-edge: var(--shop-brass);
  --babanuki-frame-sheen: rgba(255, 255, 255, 0.1);
  --babanuki-frame-drop: rgba(20, 12, 4, 0.38);
  --babanuki-cloth-a: var(--shop-violet);
  --babanuki-cloth-b: var(--shop-violet-deep);
  /* 布の織り目と照り。毛氈・羅紗と同じ角度に寝かせる。 */
  --babanuki-cloth-nap:
    repeating-linear-gradient(98deg,
      rgba(0, 0, 0, 0.05) 0 1px, transparent 1px 6px);
  --babanuki-cloth-sheen:
    radial-gradient(120% 100% at 50% -12%, rgba(236, 225, 200, 0.12), transparent 62%);
  --babanuki-cloth-well: inset 0 2px 5px rgba(10, 4, 20, 0.5);
  --babanuki-cloth-name: var(--shop-brass-light);
  --babanuki-cloth-sub: rgba(221, 192, 127, 0.6);
  --babanuki-cloth-ink: rgba(226, 214, 240, 0.72);
  --babanuki-back-lift: rgba(221, 192, 127, 0.95);
  --babanuki-card-drop: drop-shadow(0 3px 5px rgba(12, 6, 22, 0.5));
  --babanuki-card-drop-lift: drop-shadow(0 8px 12px rgba(12, 6, 22, 0.6));
  /* 木札。手番は真鍮が灯り、引かれる側には紫の小札が差さる。 */
  --babanuki-plate-name: var(--shop-brass-light);
  --babanuki-plate-name-lit: #f4e7c4;
  --babanuki-plate-sub: rgba(221, 192, 127, 0.6);
  --babanuki-plate-sub-lit: rgba(244, 231, 196, 0.75);
  --babanuki-plate-edge: rgba(180, 144, 63, 0.55);
  --babanuki-plate-lit:
    0 0 0 1px var(--shop-brass),
    0 0 12px rgba(180, 144, 63, 0.45),
    0 2px 3px rgba(20, 12, 4, 0.38);
  --babanuki-target-edge: rgba(122, 92, 168, 0.75);
  --babanuki-target-ink: #e2d6f0;
  /* 手札の並べ替え(左へ・右へ)。紙の札に真鍮の細い縁。 */
  --babanuki-rail-edge: rgba(180, 144, 63, 0.7);

  /* ポーカーの卓。出した札を置く場ではなく、賭けを置く卓 ―― 布は紺の羅紗で、
     枠は将棋・リバーシ・チェス・大富豪と同じ胡桃。緑(リバーシ)・緋(大富豪)・
     紫紺(ばば抜き)に続く四枚目の布。 */
  --poker-rasha-a: #31496a;
  --poker-rasha-b: #22334a;
  /* 羅紗の毛並みと照り。他の卓と同じ角度に寝かせる。 */
  --poker-rasha-nap:
    repeating-linear-gradient(98deg,
      rgba(0, 0, 0, 0.045) 0 1px, transparent 1px 6px);
  --poker-rasha-sheen:
    radial-gradient(120% 100% at 50% -12%, rgba(214, 232, 255, 0.12), transparent 62%);
  --poker-rasha-well: inset 0 2px 6px rgba(8, 16, 30, 0.5);
  --poker-rasha-ink: rgba(240, 232, 212, 0.8);
  --poker-rasha-ink-soft: rgba(240, 232, 212, 0.55);
  /* 銭 ―― 卓に出ているチップ。山の高さが額に比例する(games/poker.js)。 */
  --poker-coin: var(--shop-brass);
  --poker-coin-edge: var(--shop-brass-deep);
  --poker-coin-face: var(--shop-brass-light);
  --poker-coin-hole: var(--shop-walnut-deep);
  /* まだ配られていない場札の空枠。 */
  --poker-slot-edge: rgba(221, 192, 127, 0.42);

  --shop-paper: #ece1c8;
  --shop-paper-deep: #ded0aa;
  --shop-paper-line: rgba(42, 36, 28, 0.14);
  /* a sheet lighter than the surrounding stock, for fields meant to be written on */
  --shop-paper-light: #f7f1e1;
  --shop-ink: #2a241c;
  --shop-ink-soft: #55493a;
  --shop-pine: #2f4a3d;
  --shop-pine-deep: #203228;
  --shop-burgundy: #7c2e2e;
  --shop-burgundy-deep: #591f1f;
  --shop-walnut: #362519;
  --shop-walnut-deep: #241810;
  --shop-walnut-warm: #4a3524;
  --shop-seal: #a8352b;
  --shop-seal-deep: #7d2119;
  --shop-brass: #b4903f;
  --shop-brass-light: #ddc07f;
  --shop-brass-deep: #8a6a1a;
  --shop-slate: #45536a;
  --shop-crimson: #7a2230;
  --shop-crimson-deep: #3d1119;
  --shop-teal: #2c5a5a;
  --shop-teal-deep: #16302f;
  --shop-violet: #4a3768;
  --shop-violet-deep: #2a1d3d;
  --shop-gold: #8a6a1a;
  --shop-gold-deep: #4a3a0d;
  --shop-rust: #8a4a2f;
  --shop-rust-deep: #5c2f1c;
  --shop-font-display: 'Zen Old Mincho', 'Hiragino Mincho ProN', serif;
  --shop-font-body: 'Zen Kaku Gothic New', 'Hiragino Kaku Gothic ProN', sans-serif;
  --shop-font-stamp: 'Shippori Antique B1', 'Zen Old Mincho', serif;

  /* Faint laid-paper texture; layer over --shop-paper on anything that
     should read as a slip of washi rather than a flat panel. */
  --shop-paper-grain:
    repeating-linear-gradient(115deg,
      rgba(42, 36, 28, 0.03) 0px, rgba(42, 36, 28, 0.03) 1px,
      transparent 1px, transparent 5px);

  /* Layered grain lines for a walnut-plank feel on headers/buttons.
     Stack on top of the existing flat color or gradient background. */
  --wood-grain:
    repeating-linear-gradient(0.6deg,
      rgba(0, 0, 0, 0.16) 0px, rgba(0, 0, 0, 0.16) 1px,
      transparent 1px, transparent 3px,
      rgba(0, 0, 0, 0.08) 3px, transparent 4px, transparent 7px),
    repeating-linear-gradient(-0.3deg,
      rgba(255, 255, 255, 0.05) 0px, transparent 1px,
      transparent 12px, rgba(255, 255, 255, 0.05) 13px, transparent 24px),
    repeating-linear-gradient(0.2deg,
      rgba(0, 0, 0, 0.10) 0px, transparent 3px,
      transparent 55px, rgba(0, 0, 0, 0.10) 58px, transparent 130px);
  --wood-knots:
    radial-gradient(ellipse 70px 16px at 16% 28%, rgba(0, 0, 0, 0.22), transparent 70%),
    radial-gradient(ellipse 46px 12px at 74% 66%, rgba(0, 0, 0, 0.16), transparent 70%);

  /* Soft top-lit sheen + carved-edge shadow, layered on top of the grain
     so headers/buttons read as a raised wood panel rather than a flat print. */
  --wood-sheen: linear-gradient(180deg,
      rgba(255, 255, 255, 0.09) 0%,
      transparent 25%,
      transparent 70%,
      rgba(0, 0, 0, 0.2) 100%);
  --wood-shadow-panel:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    inset 0 -3px 6px rgba(0, 0, 0, 0.35),
    0 2px 6px rgba(0, 0, 0, 0.3);
  --wood-shadow-button:
    inset 0 1px 0 rgba(255, 255, 255, 0.16),
    inset 0 -2px 3px rgba(0, 0, 0, 0.4),
    0 1px 3px rgba(0, 0, 0, 0.35);
}

/* --- 行灯の盤 ---
   夜の対局。盤の灯を落とし、先手は象牙・後手は暗い木地にして、駒の向き
   ではなく色で手番が分かれる。将棋の器の中だけに掛けるので、同じトークン
   を読んでいるチェスの王手は昼のままでいる。 */
body.board-dark .shogi-container {
  --shogi-frame-a: #2f2118;
  --shogi-frame-b: #17100b;
  --shogi-frame-edge: var(--shop-brass-deep);
  --shogi-frame-sheen: rgba(221, 192, 127, 0.14);
  --shogi-frame-drop: rgba(0, 0, 0, 0.45);
  --shogi-board-a: #2c2018;
  --shogi-board-b: #211710;
  --shogi-board-grain: linear-gradient(transparent, transparent);
  --shogi-board-sheen:
    radial-gradient(120% 90% at 50% 0%, rgba(221, 192, 127, 0.1), transparent 62%);
  --shogi-line: rgba(221, 192, 127, 0.26);
  --shogi-line-edge: rgba(221, 192, 127, 0.45);
  --shogi-star: rgba(221, 192, 127, 0.55);
  --shogi-tray-a: #2f2118;
  --shogi-tray-b: #1b120c;
  --shogi-tray-border: rgba(221, 192, 127, 0.22);
  --shogi-tray-sheen: rgba(221, 192, 127, 0.1);
  --shogi-piece-a: #f6e8c4;
  --shogi-piece-b: #e9d5a6;
  --shogi-piece-flip-a: #6b4f34;
  --shogi-piece-flip-b: #4a3524;
  --shogi-piece-edge: #0f0a06;
  --shogi-piece-shadow: 0 2px 6px rgba(0, 0, 0, 0.55);
  --shogi-piece-bevel:
    inset 0 -3px 5px rgba(0, 0, 0, 0.18),
    inset 0 2px 2px rgba(255, 252, 240, 0.5);
  --shogi-ink: #241a10;
  --shogi-ink-flip: #f2e4c2;
  --shogi-ink-red: #9c2b26;
  --shogi-ink-red-flip: #e59a80;
  --shogi-ink-weight: 700;
  --shogi-dot-gote-ring: 0 0 0 1px rgba(221, 192, 127, 0.45);
  --shogi-selected: rgba(221, 192, 127, 0.3);
  --shogi-legal: rgba(221, 192, 127, 0.7);
  --shogi-legal-ring: rgba(221, 192, 127, 0.85);
  --shogi-check: rgba(190, 58, 48, 0.55);
  --shogi-last-move: rgba(221, 192, 127, 0.13);
}

/* 同じ行灯をリバーシの卓にも。羅紗の灯を落として墨緑にし、罫と星は真鍮の
   細い光。黒石は盤に沈みやすいので、縁の照りだけ残して形を拾わせる。 */
body.board-dark .reversi-container {
  --reversi-frame-a: #2f2118;
  --reversi-frame-b: #17100b;
  --reversi-frame-edge: var(--shop-brass-deep);
  --reversi-frame-sheen: rgba(221, 192, 127, 0.14);
  --reversi-frame-drop: rgba(0, 0, 0, 0.5);
  --reversi-line: rgba(221, 192, 127, 0.18);
  --reversi-felt-a: #1a2b23;
  --reversi-felt-b: #14211b;
  --reversi-felt-nap: linear-gradient(transparent, transparent);
  --reversi-felt-sheen:
    radial-gradient(120% 90% at 50% 0%, rgba(221, 192, 127, 0.07), transparent 62%);
  --reversi-felt-hover: rgba(221, 192, 127, 0.08);
  --reversi-star: rgba(221, 192, 127, 0.55);
  --reversi-black: radial-gradient(circle at 36% 26%, #3b423d 0%, #1b201d 45%, #0a0c0b 100%);
  --reversi-black-bevel:
    inset 0 -3px 5px rgba(0, 0, 0, 0.5),
    inset 0 2px 3px rgba(221, 192, 127, 0.3);
  --reversi-black-shadow: 0 2px 6px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(221, 192, 127, 0.35);
  --reversi-white: radial-gradient(circle at 36% 26%, #f8efd5 0%, #eadfbe 45%, #c9bb94 100%);
  --reversi-white-bevel:
    inset 0 -3px 5px rgba(90, 74, 46, 0.3),
    inset 0 2px 3px rgba(255, 252, 240, 0.85);
  --reversi-white-shadow: 0 2px 6px rgba(0, 0, 0, 0.55);
  --reversi-legal: rgba(221, 192, 127, 0.8);
}

/* チェスの夜。枠も金物も駒の材も昼のままで、灯を落として盤の面だけ無彩に
   する ―― 木は灯りで色が変わるが、材は変わらないので。黄楊だけが灯りを
   受けて残り、黒檀は縁を温かい鼠にして暗いマスから輪郭で起き上がらせる。 */
body.board-dark .chess-container {
  --chess-frame-a: #2c2017;
  --chess-frame-b: #17100a;
  --chess-frame-edge: var(--shop-brass-deep);
  --chess-frame-sheen: rgba(221, 192, 127, 0.12);
  --chess-frame-drop: rgba(0, 0, 0, 0.5);
  --chess-board-edge: #17100a;
  /* 夜のマスは無彩まで落とさず、枠の胡桃と同じ方向の茶を一滴だけ残す。
     明るさは無彩案と同じで、色味だけ木へ寄せてある ―― 無彩にすると、
     胡桃の枠と真鍮に囲まれた盤だけが石板を嵌め込んだように見えるため。 */
  --chess-light: linear-gradient(160deg, #443f36, #3b372f);
  --chess-dark: linear-gradient(160deg, #221e19, #1a1713);
  --chess-hover: rgba(221, 192, 127, 0.08);
  --chess-coord: var(--shop-brass);
  --chess-last: rgba(226, 168, 58, 0.3);
  --chess-legal: rgba(226, 168, 58, 0.8);
  --chess-capture: rgba(196, 74, 64, 0.85);
  --chess-check: rgba(190, 58, 48, 0.5);
  --chess-white-face: #ead9b3;
  --chess-white-edge: #4a3115;
  --chess-white-line: #4a3115;
  --chess-white-bevel: #fff4d8;
  --chess-white-bevel-alpha: 0.4;
  --chess-black-face: #191410;
  --chess-black-edge: #6d6459;
  --chess-black-line: #9a9083;
  --chess-black-bevel: #3d362c;
  --chess-black-bevel-alpha: 0.5;
  --chess-piece-shadow: 0 2px 3px rgba(0, 0, 0, 0.55);
}

/* 夜の〇✕は帳面をしまって半紙を出す。紙の灯を落とすと墨は乗らないので、
   罫は穂先で引いた真鍮の細い光、手は胡粉の白。字は色ではなく形で分かれる
   ―― 半紙の上には一つの墨壺しかないので。 */
body.board-dark .ttt-board {
  --ttt-paper-a: #2b2419;
  --ttt-paper-b: #211b12;
  --ttt-paper-grain: linear-gradient(transparent, transparent);
  --ttt-paper-sheen:
    radial-gradient(120% 90% at 50% 0%, rgba(221, 192, 127, 0.09), transparent 62%);
  --ttt-board-edge:
    0 0 0 1px rgba(221, 192, 127, 0.22),
    0 10px 20px rgba(0, 0, 0, 0.45);
  --ttt-rule: rgba(221, 192, 127, 0.42);
  --ttt-ink-o: #f4ecd8;
  --ttt-ink-x: #f4ecd8;
  --ttt-win: #f4ecd8;
  --ttt-cell-hover: rgba(221, 192, 127, 0.07);
  --ttt-cell-win: rgba(221, 192, 127, 0.13);
  --ttt-ghost: 0.26;
}

* {
  box-sizing: border-box;
}

.hidden {
  display: none;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--shop-paper);
  color: var(--shop-ink);
  font-family: "Hiragino Kaku Gothic ProN", "Yu Gothic", "Segoe UI", sans-serif;
}

#app {
  min-height: 100vh;
}

/* =========================================================
   FLOATING TOOL CONTROLS — SE volume / board scale / rules
   Styled as objects left on the shop's table: a turned walnut
   counter with a brass rim, opening a washi slip of options.
   The look is shared by all three (.rules-toggle-btn lives in
   room.css, which only positions it); only the anchors differ.
   ========================================================= */
/* The tools stack up the right-hand edge of the table, above the gear tab:
   ?  /  board scale  /  SE  /  gear. Each control is anchored on its own, and
   opens its slip sideways into the clear space at its left, so a popup never
   covers another button. Only the SE control lives outside the room screen -
   every screen has sound - so body.in-room lifts it to make room for the rest. */
.se-control {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 5;
}
/* In a room the gear is a tab on the bottom edge, so the stack it reveals
   starts from the edge itself. */
body.in-room { --tool-stack-base: 0px; }
.se-control { bottom: var(--tool-stack-base); }

/* --- in a room the three settings live behind the gear ---
   Outside a room the sound button stands in the corner on its own: the gear is
   part of the room, and hiding the volume behind it everywhere would leave no
   way to reach it from the entrance or the lobby. */
body.in-room .se-control,
body.in-room .board-scale-control,
body.in-room .board-theme-control,
body.in-room .rules-control { display: none; }
body.in-room.tools-open .se-control,
body.in-room.tools-open .board-scale-control:not(.hidden),
body.in-room.tools-open .board-theme-control:not(.hidden),
body.in-room.tools-open .rules-control:not(.hidden) { display: block; }

body.in-room .se-control { bottom: calc(var(--tool-stack-base) + 58px); }
body.in-room .board-scale-control { bottom: calc(var(--tool-stack-base) + 116px); }
/* help sits above the two settings, and closes the gap when a card or dice
   game leaves no board to scale */
body.in-room .board-theme-control { bottom: calc(var(--tool-stack-base) + 174px); }
body.in-room .rules-control { bottom: calc(var(--tool-stack-base) + 174px); }
body.in-room.has-board-theme .rules-control { bottom: calc(var(--tool-stack-base) + 232px); }
body.in-room.no-board-scale .rules-control { bottom: calc(var(--tool-stack-base) + 116px); }
/* max-content because an absolutely positioned box otherwise shrinks to fit
   its 48px-wide anchor and wraps the labels. */
.se-volume-menu {
  position: absolute;
  right: 58px;
  bottom: 0;
  width: max-content;
}

.board-scale-control {
  position: fixed;
  right: 20px;
  bottom: calc(var(--tool-stack-base) + 116px);
  z-index: 5;
}
.board-scale-control.hidden { display: none; }

.board-theme-control {
  position: fixed;
  right: 20px;
  bottom: calc(var(--tool-stack-base) + 174px);
  z-index: 5;
}
.board-theme-control.hidden { display: none; }
.board-scale-stepper {
  position: absolute;
  right: 58px;
  bottom: 0;
  width: max-content;
}

/* --- 木札: the round wooden buttons themselves --- */
.se-toggle-btn,
.board-scale-toggle-btn,
.board-theme-toggle-btn,
.rules-toggle-btn,
.tools-toggle-btn {
  width: 48px;
  height: 48px;
  flex: 0 0 48px;
  padding: 0;
  border-radius: 50%;
  background-color: var(--shop-walnut);
  background-image: var(--wood-sheen), var(--wood-grain);
  border: 1px solid var(--shop-brass);
  color: var(--shop-brass-light);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--wood-shadow-button), 0 4px 12px rgba(36, 24, 16, 0.32);
  transition: transform 0.18s ease, background-color 0.18s ease, box-shadow 0.18s ease;
}
.se-toggle-btn:hover,
.board-scale-toggle-btn:hover,
.board-theme-toggle-btn:hover,
.rules-toggle-btn:hover,
.tools-toggle-btn:hover {
  background-color: var(--shop-walnut-warm);
  transform: translateY(-2px);
  box-shadow: var(--wood-shadow-button), 0 7px 18px rgba(36, 24, 16, 0.36), 0 0 18px rgba(221, 192, 127, 0.3);
}
.se-toggle-btn svg,
.board-scale-toggle-btn svg,
.board-theme-toggle-btn svg,
.rules-toggle-btn svg,
.tools-toggle-btn svg {
  width: 22px;
  height: 22px;
}
/* 日輪と三日月は一枚の木札の表と裏。盤が夜に入ると彫りが入れ替わる。
   隣の歯車も輪と光条の形なので、こちらは輪を塗って見分けをつけている。 */
.board-theme-toggle-btn .board-theme-moon,
body.board-dark .board-theme-toggle-btn .board-theme-sun { display: none; }
body.board-dark .board-theme-toggle-btn .board-theme-moon { display: block; }
.tools-toggle-btn.open {
  background-color: var(--shop-walnut-warm);
  box-shadow: var(--wood-shadow-button), 0 0 16px rgba(221, 192, 127, 0.32);
}
.se-mute-slash {
  opacity: 0;
}
.se-toggle-btn.muted .se-mute-slash {
  opacity: 1;
}

/* --- 短冊: the washi slip a button opens --- */
.se-volume-menu,
.board-scale-stepper {
  display: flex;
  border-radius: 3px;
  background-color: var(--shop-paper);
  background-image: var(--shop-paper-grain);
  border: 1px solid var(--shop-brass);
  box-shadow: 0 10px 24px rgba(36, 24, 16, 0.3);
}
.se-volume-menu {
  flex-direction: row;
  gap: 2px;
  padding: 6px;
}
.se-volume-menu.hidden,
.board-scale-stepper.hidden {
  display: none;
}
.se-volume-btn {
  min-width: 68px;
  padding: 7px 14px;
  border: none;
  border-radius: 2px;
  background: transparent;
  color: var(--shop-ink);
  font-family: var(--shop-font-display);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  transition: background 0.15s ease, color 0.15s ease;
}
.se-volume-btn:hover {
  background: rgba(180, 144, 63, 0.18);
}

/* --- board scale stepper: one row of the same slip ---
   A dial rather than a list: minus / current zoom / plus, with 自動 kept
   apart by a hairline because it is a mode, not another rung. */
.board-scale-stepper {
  align-items: center;
  gap: 2px;
  padding: 5px 6px;
}
.board-scale-step-btn {
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  border-radius: 2px;
  background: transparent;
  color: var(--shop-ink);
  font-family: var(--shop-font-display);
  font-size: 1.05rem;
  line-height: 1;
  transition: background 0.15s ease;
}
.board-scale-step-btn:hover {
  background: rgba(180, 144, 63, 0.18);
}
.board-scale-step-btn:disabled {
  color: var(--shop-ink);
  opacity: 0.28;
  background: transparent;
  cursor: not-allowed;
}
.board-scale-value {
  min-width: 58px;
  text-align: center;
  font-family: var(--shop-font-display);
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--shop-ink);
}
/* while auto is following the window the number is a readout, not a setting */
.board-scale-value.auto {
  color: var(--shop-ink-soft);
  font-weight: 400;
}
.board-scale-sep {
  width: 1px;
  align-self: stretch;
  margin: 2px 5px;
  background: var(--shop-paper-line);
}
.board-scale-auto-btn {
  padding: 7px 11px;
  border: none;
  border-radius: 2px;
  background: transparent;
  color: var(--shop-ink-soft);
  font-family: var(--shop-font-display);
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  transition: background 0.15s ease, color 0.15s ease;
}
.board-scale-auto-btn:hover {
  background: rgba(180, 144, 63, 0.18);
  color: var(--shop-ink);
}
/* the setting in force reads as a 朱印 stamped onto the slip */
.se-volume-btn.active,
.board-scale-auto-btn.active {
  background: var(--shop-seal);
  color: var(--shop-paper);
}

.screen {
  display: none;
}
.screen.active {
  display: block;
}

button {
  cursor: pointer;
  font: inherit;
  border: none;
  border-radius: var(--radius);
  padding: 10px 18px;
}

.primary-btn {
  background: var(--accent);
  color: #fff;
  font-weight: 600;
}
.primary-btn:hover {
  background: var(--accent-hover);
}
.primary-btn:disabled {
  background: #4a5066;
  color: var(--text-dim);
  cursor: not-allowed;
}

.secondary-btn {
  background: var(--panel-alt);
  color: var(--text);
  border: 1px solid var(--border);
}
.secondary-btn:hover {
  background: var(--border);
}
.secondary-btn:disabled {
  background: transparent;
  color: var(--text-dim);
  border-color: transparent;
  cursor: not-allowed;
}

input, select {
  font: inherit;
  padding: 10px 12px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: var(--panel-alt);
  color: var(--text);
  width: 100%;
}
input:focus, select:focus {
  outline: 2px solid var(--shop-pine);
}

label {
  display: block;
  margin: 14px 0 6px;
  font-size: 0.9rem;
  color: var(--text-dim);
}

.required {
  color: var(--error);
}

.error-text {
  color: var(--error);
  min-height: 1.2em;
  font-size: 0.9rem;
  margin: 8px 0 0;
}

.modal-hint {
  color: var(--text-dim);
  font-size: 0.85rem;
  line-height: 1.6;
  margin: 0 0 14px;
}
.modal-hint.hidden { display: none; }

.status-text {
  color: var(--shop-ink-soft);
  min-height: 1.2em;
}


/* --- operator's banner (maintenance notices, wind-down countdown) ---
   A strip of paper pinned over the top of the shop. It takes part in the
   normal flow rather than floating, so it pushes the page down instead of
   covering the header - a notice that hides the way out is worse than none. */
.site-banner:empty { display: none; }

.banner-line {
  margin: 0;
  padding: 10px 24px;
  text-align: center;
  font-family: var(--shop-font-display);
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--shop-ink);
  background-color: var(--shop-paper-deep);
  border-bottom: 1px solid var(--shop-paper-line);
}
.banner-line.hidden { display: none; }

.banner-line.warning {
  color: var(--shop-paper-light);
  background-color: var(--shop-burgundy);
  border-bottom-color: var(--shop-burgundy-deep);
}

/* A small picture placed above the prose in "あそびかた" - one look before
   the reading, for whoever has never sat at this game before. Empty and
   invisible for a game whose diagram has not been drawn yet. */
.rules-diagram {
  margin: 0 0 18px;
  padding: 14px 16px 12px;
  background: var(--shop-paper-light);
  border: 1px solid var(--shop-paper-line);
  border-radius: 10px;
}
.rules-diagram-art {
  display: flex;
  justify-content: center;
}
.rules-diagram-art svg {
  width: 100%;
  max-width: 360px;
  height: auto;
  display: block;
}
.rules-diagram figcaption {
  margin-top: 10px;
  text-align: center;
  font-size: 0.85rem;
  line-height: 1.7;
  color: var(--shop-ink-soft);
}

/* =========================================================
   店の賽 — 三×三の升に目を彫る。地と彫りは --die-* が持つ。
   置く場所(卓の上・手控えの一行・目の選択)で大きさだけが変わるので、
   遊びの名は付けない。public/dice.js が組み立てる。
   升の大きさは --die-pip-size / --die-pip-gap で挽き直せる ―― 殻を自前で
   持つ側(ヨットの盆の賽は押せる木札、点取帳の行頭の賽は16px)は、彫りだけを
   借りて、大きさを自分のところで決める。
   ========================================================= */
.die {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 8px;
  background: var(--die-bone);
  box-shadow: var(--die-bevel), var(--die-shadow);
}
.die-pips {
  display: grid;
  grid-template-columns: repeat(3, var(--die-pip-size, 7px));
  grid-template-rows: repeat(3, var(--die-pip-size, 7px));
  gap: var(--die-pip-gap, 4px);
}
.die-pip { border-radius: 50%; }
.die-pip.on {
  background: var(--die-pip);
  box-shadow: var(--die-pip-sheen);
}
/* 手控えの賽。目が読める下限がこのあたり。 */
.die-small {
  width: 28px;
  height: 28px;
  border-radius: 5px;
  box-shadow:
    inset 0 -2px 4px rgba(120, 100, 68, 0.26),
    inset 0 1px 2px rgba(255, 255, 255, 0.9),
    0 2px 3px rgba(0, 0, 0, 0.32);
}
.die-small .die-pips {
  --die-pip-size: 4px;
  --die-pip-gap: 2.5px;
}
