/* ================================================================
   style.css – 華容道（HUARONG DAO）
   ================================================================

   ■ 目指している見た目
     紫檀の枠に収めた、漆塗りの駒。
     箱入り娘（藍と檜）・KLOTSKI（クリーム色と積み木）と並べたときに、
     一目で別のオモチャだと分かるようにしている。
     画像は1枚も使っていない。

   ■ 駒の色は三國演義から取っている
     關羽は緑の衣、張飛は墨、趙雲は白銀、馬超は青、黃忠は土黄、
     曹操だけ朱に金文字。色で武将を覚えられるようにしているが、
     形（2×2・2×1・1×2・1×1）がすでに違うため、
     色が見分けにくい人でも駒の区別はつく。

   ■ Webフォントを1つも読み込んでいない
     画面に出るのは漢字と注音符號だけで、/fonts/ に置いてある
     ラテン文字のフォントは描画に関与しない。1バイトも読まずに済む。
     表示は OS に入っている楷書・明朝と黑體に任せ、
     どれも無い環境では serif / sans-serif に落ちる。

   ■ 注音符號が出ない環境について
     注音（ㄅㄆㄇㄈ）は台湾向けの書体には入っているが、
     日本語環境の書体には入っていないことがある。
     その場合ふりがなの位置に豆腐（□）が出るため、
     ruby の書体指定は繁体字中国語の書体を先に並べてある。
   ================================================================ */


/* ----------------------------------------------------------------
   01. 配色と書体
---------------------------------------------------------------- */
:root {
  /* color-scheme: dark … スクロールバーや選択範囲の色を暗い前提に揃える */
  color-scheme: dark;

  --ground:      #2a1a17;   /* 栗色：背景 */
  --ground-deep: #1d1210;   /* 濃い栗色：手数の台 */
  --ink:         #f3e7d3;   /* 生成り：文字 */
  --muted:       #b9a28c;   /* 枯茶：補助の文字 */
  --rim:         #5b3326;   /* 盤の枠（紫檀） */
  --rim-hi:      #7d4a36;   /* 枠の光が当たる側 */
  --recess:      #211311;   /* 盤の底 */
  --gold:        #e3bb6a;   /* 金：強調 */

  --zhu:         #b3302a;   /* 曹操（朱漆） */
  --green:       #3f7a52;   /* 關羽（緑の衣） */
  --black:       #3a3a3f;   /* 張飛（墨） */
  --silver:      #d9d9d4;   /* 趙雲（白銀） */
  --blue:        #5d7fa8;   /* 馬超（青） */
  --yellow:      #c89a3e;   /* 黃忠（土黄） */
  --wood:        #d8bb8c;   /* 兵（素木） */

  /* 見出しと駒は楷書・明朝系、本文は黑體系。
     繁体字中国語の書体を先に並べ、無ければ日本語の書体に落とす。 */
  --font-display: 'BiauKai', '標楷體', 'Kaiti TC', 'Songti TC', 'Noto Serif TC',
                  'Hiragino Mincho ProN', serif;
  --font-body:    'PingFang TC', 'Heiti TC', 'Microsoft JhengHei', 'Noto Sans TC',
                  'Hiragino Sans', sans-serif;

  /* 盤の枠の太さ。出口の幅もこの値から計算している */
  --rim-w: clamp(10px, 3.4vw, 16px);
}

* { box-sizing: border-box; }

html, body { height: 100%; }

/* 背景は漆を塗った板。
   斜めの細い線を2本重ねて、刷毛目のような質感を作っている。
   線は 1px 未満の濃さにしてあるため、模様としては認識されない。 */
body {
  margin: 0;
  background:
    repeating-linear-gradient(105deg, rgba(255,255,255,.016) 0 1px, transparent 1px 5px),
    radial-gradient(ellipse 80% 60% at 50% 0%, rgba(255, 200, 150, .07), transparent 70%),
    var(--ground);
  color: var(--ink);
  font-family: var(--font-body);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  /* 駒を押したときに青い矩形が出ないようにする */
  -webkit-tap-highlight-color: transparent;
}


/* ----------------------------------------------------------------
   02. レイアウト
---------------------------------------------------------------- */
.app {
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding-top: max(14px, env(safe-area-inset-top, 0px));
  padding-bottom: max(14px, env(safe-area-inset-bottom, 0px));
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
}


/* ----------------------------------------------------------------
   03. ヘッダー
---------------------------------------------------------------- */
.site-header { text-align: center; }

.site-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 7vw, 2.3rem);
  font-weight: 700;
  letter-spacing: .18em;
  line-height: 1.6;
  color: var(--gold);
}

/* 注音は本文書体の方が読みやすい。楷書のまま小さくすると線が消える */
.site-title rt {
  font-family: var(--font-body);
  font-size: .3em;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--muted);
}

.site-tagline { margin: 2px 0 0; color: var(--muted); font-size: .95rem; }


/* ----------------------------------------------------------------
   04. 步數
---------------------------------------------------------------- */
.stats {
  display: flex;
  justify-content: center;
  gap: 10px;
  /* 数字の幅を揃える。9步から10步で数字の中心が横へ動かないように */
  font-variant-numeric: tabular-nums;
}

.stat {
  min-width: 104px;
  display: grid;
  justify-items: center;
  padding: 4px 14px;
  background: var(--ground-deep);
  border-radius: 12px;
  line-height: 1.4;
}

/* クリアした回数の印。🏆 だけ、2回目からは 🏆 2 と数字が付く。
   「手数」の札と並べるので、同じ .stat の見た目を借りて中身だけ大きくする。 */
.stat-clears {
  align-content: center;
  font-size: 1.2rem;
  font-weight: 900;
}

.stat span   { font-size: .78rem; color: var(--muted); letter-spacing: .14em; }
.stat strong { font-size: 1.45rem; font-weight: 700; }


/* ----------------------------------------------------------------
   05. 盤
   ----------------------------------------------------------------
   幅の決め方は3本とも同じ。画面幅・380px・縦に収まる幅の最小値を取る。
   盤は 4:5（横:縦）なので、使える高さの 0.8 倍が盤の横幅になる。
   392px は盤以外（ヘッダー・步數・地名2つ・操作・フッターと余白）の
   高さの実測値。375×667（画面の短い iPhone）で縦に収まるところまで
   実測して決めた。他の2本より大きいのは、盤の上に地名を1行置いていて、
   その地名も他の2本の「出口 / EXIT」より大きいため
   （箱入り娘 356px / KLOTSKI 348px）。
   この数を直し忘れると、背の低い画面で盤が下へはみ出す。
   dvh を使っているのは、iOS でアドレスバーが隠れるときに
   vh が古い値のまま残り、盤が画面からはみ出すため。

   margin-top は、盤の上に出る「赤壁」の場所を空けるためのもの。
   .stage の padding ではなく margin にしているのは、過關の表示が
   inset: 0 で .stage に重なるため。padding にすると、
   その表示が盤より上へはみ出してしまう。
---------------------------------------------------------------- */
.stage {
  position: relative;
  width: min(100%, 380px, calc((100dvh - 392px) * .8 + 2 * var(--rim-w)));
  min-width: 240px;
  margin-top: 24px;
}

/* 紫檀の枠。木目と、上辺の光・下辺の影で面取りを作っている */
.frame {
  position: relative;
  padding: var(--rim-w);
  border-radius: 14px;
  background:
    repeating-linear-gradient(92deg, rgba(0,0,0,.07) 0 3px, transparent 3px 12px),
    linear-gradient(160deg, var(--rim-hi), var(--rim) 55%, #3f2219);
  box-shadow:
    0 18px 36px rgba(0,0,0,.5),
    inset 0 2px 0 rgba(255,255,255,.16),
    inset 0 -3px 0 rgba(0,0,0,.3);
}

.grid {
  position: relative;
  aspect-ratio: 4 / 5;
  background: var(--recess);
  border-radius: 5px;
  box-shadow: inset 0 3px 10px rgba(0,0,0,.65);
  /* touch-action: none … 駒をなぞったときに画面がスクロールしないように */
  touch-action: none;
}

/* 出口。下の枠を2マスぶん切り欠いて、盤の底の色で塗っている */
.gate {
  position: absolute;
  bottom: 0;
  left: calc(var(--rim-w) + (100% - 2 * var(--rim-w)) * .25);
  width: calc((100% - 2 * var(--rim-w)) * .5);
  height: var(--rim-w);
  background: var(--recess);
  box-shadow: inset 0 3px 6px rgba(0,0,0,.55);
}

/* 盤の上下に出る地名。上が赤壁（逃げてきた場所）、下が江陵（目的地）。
   2つを同じ見た目にして、盤を挟んで対に見えるようにしている。

   字間を広く取っているのは、2文字の地名を看板らしく見せるため。
   駒の文字と同じ大きさにすると盤の一部に見えてしまうので、
   大きさではなく字間で目立たせている。 */
.gate-label,
.wall-label {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: 1em;
  /* 字間を広げると、最後の1文字のうしろにも同じ隙間が入る。
     その隙間のぶんだけ中心が左へずれて見えるので、
     同じ幅を先頭にも足して釣り合わせる。 */
  text-indent: 1em;
  white-space: nowrap;
}

.gate-label { bottom: -1.8em; color: var(--gold); }

/* 赤壁は通ってきた場所なので、目的地の江陵より一段おさえた色にする */
.wall-label { top: -1.8em; color: var(--muted); }


/* ----------------------------------------------------------------
   06. 駒
---------------------------------------------------------------- */
.piece {
  position: absolute;
  margin: 0;
  border: 0;
  padding: calc(var(--cell, 70px) * .04);   /* 駒と駒の隙間 */
  background: none;
  font: inherit;
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  transition: left .16s cubic-bezier(.3,.7,.4,1), top .16s cubic-bezier(.3,.7,.4,1);
  z-index: 1;
}

/* 枠線は駒の面に出す。ボタンには隙間ぶんの padding があるため、
   そこに枠が出ると駒から浮いて見える。 */
.piece:focus { outline: none; }
.piece:focus-visible .face { outline: 3px solid var(--gold); outline-offset: 1px; }

.piece.lift { cursor: grabbing; transition: none; z-index: 3; }
.piece.lift .face {
  transform: translateY(-1px);
  box-shadow: 0 8px 14px rgba(0,0,0,.55), inset 0 2px 0 rgba(255,255,255,.3), inset 0 -4px 0 rgba(0,0,0,.2);
}

/* 漆の面。艶のかぶせと、下の木口の厚みで立体にしている */
.face {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: calc(var(--cell, 70px) * .1);
  background:
    linear-gradient(155deg, rgba(255,255,255,.22), transparent 50%),
    var(--lacquer);
  box-shadow:
    0 3px 0 rgba(0,0,0,.4),
    inset 0 2px 0 rgba(255,255,255,.22),
    inset 0 -4px 0 rgba(0,0,0,.2);
  /* 何があっても駒の外へは描かせない。
     文字の大きさの計算がどこかで狂っても、盤が壊れないようにする保険。 */
  overflow: hidden;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: calc(var(--cell, 70px) * .3);
  line-height: 1.15;
  color: var(--ink);
  transition: transform .12s, box-shadow .12s;
}

/* 注音は本文書体。楷書のまま小さくすると線が潰れる。
   writing-mode の中でも横に組みたいので、縦駒側で向きを戻している。 */
.face rt {
  font-family: var(--font-body);
  font-size: .34em;
  font-weight: 400;
  letter-spacing: 0;
  opacity: .72;
}

/* 文字を包む span。大きさは内容ぶんだけで、駒より大きくはならない。 */
.face .text { max-width: 100%; max-height: 100%; }

/* 縦に2マスの駒は、駒の形に沿って縦書きにする。
   writing-mode を掛けるのは .face ではなく、中の .text であること。
   .face は height: 100% を持つ flex 容器で、iOS Safari ではそこに
   縦書きを足すと、高さがボタンではなく画面いっぱいまで伸びる。
   駒が盤の外へ細長くはみ出し、下の文字やボタンを覆ってしまう。 */
.general .text { writing-mode: vertical-rl; letter-spacing: .1em; }

/* 横に2マスの駒は字間を開ける */
.guanyu .face { letter-spacing: .22em; }

/* 武将ごとの色。白銀の趙雲だけ、文字を黒にしないと読めない */
.caocao     .face { --lacquer: var(--zhu); }
.guanyu     .face { --lacquer: var(--green); }
.zhangfei   .face { --lacquer: var(--black); }
.zhaoyun    .face { --lacquer: var(--silver); color: #2b2b30; }
.machao     .face { --lacquer: var(--blue); }
.huangzhong .face { --lacquer: var(--yellow); color: #2b2008; }
.bing       .face { --lacquer: var(--wood); color: #3a2414; }

.zhaoyun .face rt,
.huangzhong .face rt,
.bing .face rt { opacity: .62; }

/* 曹操だけ金文字。内側に金の縁（4つめの inset）を回して別格にする */
.caocao .face {
  color: var(--gold);
  font-size: calc(var(--cell, 70px) * .46);
  box-shadow:
    0 3px 0 rgba(0,0,0,.45),
    inset 0 2px 0 rgba(255,220,190,.3),
    inset 0 -5px 0 rgba(0,0,0,.25),
    inset 0 0 0 calc(var(--cell, 70px) * .055) rgba(227,187,106,.35);
}

.caocao .face rt { color: var(--ink); opacity: .8; }

/* 出口から出ていく動き。盤の外へ落として消す。
   opacity の遅延（.6s）は、枠を抜けきってから薄くなるように合わせた値。 */
.caocao.escape {
  transition: top .9s cubic-bezier(.5,0,.7,.4), opacity .4s .6s;
  opacity: 0;
}


/* ----------------------------------------------------------------
   07. ボタン
---------------------------------------------------------------- */
/* margin-top は、盤の下に出る「江陵」の場所を空けるためのもの。
   地名を大きくしたぶん、他の2本（16px）より広く取っている。 */
.controls { display: flex; gap: 10px; margin-top: 22px; }

.btn {
  min-width: 128px;
  min-height: 48px;          /* 指で押す的の最小の大きさ */
  padding: 8px 18px;
  border: 0;
  border-radius: 12px;
  font: inherit;
  font-size: 1rem;
  font-weight: 700;
  color: var(--ink);
  background: var(--ground-deep);
  box-shadow: 0 3px 0 rgba(0,0,0,.45);
  cursor: pointer;
}

.btn:active { transform: translateY(2px); box-shadow: 0 1px 0 rgba(0,0,0,.45); }
.btn:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.btn:disabled { opacity: .4; cursor: default; transform: none; }
.btn.primary { background: var(--gold); color: #3a2414; }


/* ----------------------------------------------------------------
   08. 過關の表示
   ----------------------------------------------------------------
   盤の上に重ねる（inset: 0）。別の画面に切り替えないのは、
   解けた盤面を見せたまま結果を出したいため。

   hidden 属性が付いている間は出さない。.clear に display: grid を
   指定しているため、ブラウザ標準の [hidden] { display: none } が
   負けて、常に表示されてしまう。クラス付きで打ち消す必要がある。
---------------------------------------------------------------- */
.clear[hidden] { display: none; }

.clear {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 8px;
  padding: 20px;
  border-radius: 14px;
  background: rgba(29, 18, 16, .93);
  text-align: center;
  z-index: 10;
  animation: rise .4s ease-out;
}

.clear h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: .12em;
  color: var(--gold);
}

.clear .result { margin: 0; font-size: 1.3rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.clear .best   { margin: 0; font-size: .95rem; font-weight: 700; color: var(--gold); font-variant-numeric: tabular-nums; }
.clear .note   { margin: 0 0 4px; font-size: .9rem; line-height: 1.6; color: var(--muted); }

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


/* ----------------------------------------------------------------
   09. フッター
---------------------------------------------------------------- */
.site-footer { margin-top: auto; padding-top: 10px; text-align: center; }
.footer-copy { margin: 3px 0; font-size: .75rem; color: var(--muted); line-height: 1.6; }
.footer-link { color: var(--gold); font-weight: 700; text-decoration: none; }
.footer-link:hover { text-decoration: underline; }
.footer-link:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }


/* ----------------------------------------------------------------
   10. 動きを減らす設定
   ----------------------------------------------------------------
   OS で「視差効果を減らす」を選んでいる人には動きを出さない。
   駒は transition なしで即座に移動し、曹操は出口で消えずにその場に残る
   （共有エンジンが escape を付けない）。過關の表示も動かさずに出す。
---------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .piece, .face, .caocao.escape { transition: none !important; }
  .clear { animation: none; }
}
