:root {
  --bg: #f4f6f9;
  --fg: #2c3542;
  --muted: #7b8698;
  --line: #cdd5e0;
  --check: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 12.5 L9.5 18 L20 6.5'/></svg>");
  --card-bg: #ffffff;
  --btn-bg: #55637a;
  --btn-fg: #f2f5f9;
  --sheet-bg: #ffffff;
  --key-bg: #dfe5ee;
  --good: #4f8f45;
  --bad: #c1503f;
  --hint: #c9962f;

  /* 판은 나무색을 유지한다. 다른 색으로 바꾸면 체스판으로 안 읽힌다. 대신
     테마에 따라 밝기만 조금 낮춘다. */
  --light-square: #e9dbbb;
  --dark-square: #b08159;
  --board-edge: #6d492d;
  --last-move: #d8bb4a;

  /* 판 크기 계산이 이 값들을 다시 읽어야 해서 변수로 둔다. */
  --pad-x: clamp(10px, 4vmin, 28px);
  --app-max: 480px;
  /* 판은 정사각형이라 폭만 보면 세로가 짧은 화면에서 아래가 잘린다. 쓸 수 있는
     가로와 세로를 함께 보고 작은 쪽을 쓴다. 말 크기도 여기서 나눠 쓰므로,
     칸에 비해 말이 작아지는 일이 생기지 않는다. */
  --board: min(100vw - 2 * var(--pad-x), var(--app-max), 70vh);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #171b21;
    --fg: #dfe5ee;
    --muted: #8892a3;
    --line: #333c49;
    --card-bg: #212832;
    --btn-bg: #4a5568;
    --sheet-bg: #212832;
    --key-bg: #333c49;
    --good: #6f9e63;
    --bad: #e0705c;
    --hint: #d8a13a;

    --light-square: #c2ad8b;
    --dark-square: #7d5a3d;
    --board-edge: #4a3220;
    --last-move: #b8992f;
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; min-height: 100%; }

body {
  background: var(--bg);
  color: var(--fg);
  font-family: "Pretendard", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
  display: flex;
  justify-content: center;
  padding: clamp(10px, 3vmin, 24px) var(--pad-x);
}

.app {
  width: min(100%, var(--app-max));
  display: flex;
  flex-direction: column;
  gap: clamp(8px, 2vmin, 14px);
}

/* 게임마다 헤더가 제각각이면 게임을 옮겨 다닐 때 목록으로 돌아가는 길을 매번
   다시 찾게 된다. 네 게임과 같은 배치를 쓴다: 목록은 왼쪽 위, 이름은 가운데.
   양옆을 1fr로 묶으면 좌우 내용의 폭이 달라도 이름이 화면 한가운데에 온다. */
.title-row {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 10px;
}

.title-row h1 { text-align: center; }
.title-row .head-nav { justify-self: start; }
.head-nav { display: flex; align-items: center; gap: 14px; }
.title-row .head-actions { justify-self: end; }
.head-actions { display: flex; align-items: center; gap: 8px; }

h1 {
  margin: 0;
  font-size: clamp(24px, 6vmin, 34px);
  letter-spacing: -0.02em;
}

.back {
  color: inherit;
  text-decoration: none;
  opacity: 0.75;
  font-size: 14px;
  font-weight: 600;
}
.back:hover { opacity: 1; }

.toggle {
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  color: inherit;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 10px;
  cursor: pointer;
}

/* 취소선은 소리 토글에만 준다. 도움말 토글의 꺼짐은 "안 열림"이라 뜻이 다르다. */
.toggle.sound[aria-pressed="false"] { opacity: 0.38; text-decoration: line-through; }

.sub-row {
  display: flex;
  align-items: center;
  gap: 8px 12px;
  flex-wrap: wrap;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
}
.sub-row .side { margin-inline-start: auto; color: var(--fg); }
.sub-row .rating:empty { display: none; }

/* 난이도 고르개. 다른 게임의 것과 같은 모양을 쓴다. */
.picker { display: flex; gap: 4px; }
.pick {
  border: 1px solid var(--line);
  border-radius: 999px;
  background: none;
  color: inherit;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 3px 9px;
  cursor: pointer;
}
.pick[aria-pressed="true"] {
  background: var(--btn-bg);
  border-color: var(--btn-bg);
  color: var(--btn-fg);
}
/* 이미 푼 문제. 다시 눌러 봐도 되는 곳인지 번호만 보고 알 수 있게 한다. */
.sub-row .count.solved { color: var(--good); }
/* 체크는 글자가 아니라 도형이다. `content`에는 SVG를 넣을 수 없으므로 마스크로
   찍고 색은 `currentColor`가 준다 — 그래야 위 줄의 색 규칙을 그대로 탄다. */
.sub-row .count.solved::after {
  content: '';
  display: inline-block;
  width: 0.8em;
  height: 0.8em;
  margin-left: 0.25em;
  vertical-align: -0.05em;
  background: currentColor;
  -webkit-mask: var(--check) center / contain no-repeat;
  mask: var(--check) center / contain no-repeat;
}

.brief { text-align: center; }
.brief h2 { margin: 0; font-size: 18px; }
.brief .themes { margin: 3px 0 0; font-size: 12px; color: var(--muted); }

.board-wrap { position: relative; }

.board {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  /* 행도 못박아야 한다. 없으면 행 높이가 내용을 따라가서, 말이 하나도 없는
     가로줄만 납작해진다. 시작 위치에서는 어느 줄에나 말이 있어 드러나지 않고,
     3번 문제를 다 푼 뒤처럼 한 줄이 통째로 비어야 나타난다. */
  grid-template-rows: repeat(8, 1fr);
  width: var(--board);
  margin-inline: auto;
  aspect-ratio: 1;
  border: 6px solid var(--board-edge);
  border-radius: 6px;
  overflow: hidden;
  user-select: none;
}

.square {
  position: relative;
  display: grid;
  place-items: center;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
  line-height: 1;
}
.square.light { background: var(--light-square); }
.square.dark { background: var(--dark-square); }

/* 말은 pieces.js가 그리는 SVG다. 채우기와 테두리를 반대색으로 두면 밝은 칸에서도
   어두운 칸에서도 윤곽이 살아, 흑백을 한눈에 가를 수 있다. */
.piece {
  display: block;
  width: 88%;
  pointer-events: none;
  filter: drop-shadow(0 1px 1px #00000038);
}
.piece svg { display: block; width: 100%; height: auto; }
.piece svg * {
  fill: var(--piece-fill);
  stroke: var(--piece-stroke);
  stroke-width: 1.5;
  stroke-linejoin: round;
}
/* 속을 비우고 선만 그리는 도형. 인라인 fill="none"은 위 규칙에 덮어써지므로
   클래스로 되돌려야 한다 — 처음엔 그걸 몰라 비숍의 트인 자리가 칠해져 나왔다. */
.piece svg .line { fill: none; stroke: var(--piece-stroke); }
.piece.white { --piece-fill: #f7f2e7; --piece-stroke: #23201a; }
.piece.black { --piece-fill: #2a251d; --piece-stroke: #e9e1d2; }

/* 직전 수는 두 칸을 함께 물들인다. 화면을 잠깐 벗어났다 돌아와도 무슨 일이
   있었는지 판만 보고 알 수 있어야 한다. */
.square.last::after {
  content: '';
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 0 3px var(--last-move);
  pointer-events: none;
}

.square.selected::after {
  content: '';
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 0 4px var(--hint);
  pointer-events: none;
}

/* 갈 수 있는 빈 칸은 점, 잡을 수 있는 칸은 테두리. 점을 말 위에 겹치면 말이
   가려져서 무엇을 잡는지 안 보인다. */
.square.target::before {
  content: '';
  position: absolute;
  width: 28%;
  height: 28%;
  border-radius: 50%;
  background: #1c1c1c44;
  pointer-events: none;
}
.square.capture::before {
  content: '';
  position: absolute;
  inset: 6%;
  border-radius: 50%;
  border: 4px solid #1c1c1c44;
  pointer-events: none;
}

.square.checked { background: var(--bad); }

.promotion {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
}
.promotion[hidden] { display: none; }
.promotion-title { margin: 0; font-weight: 700; }
.promotion-keys { display: flex; gap: 8px; }
.promotion-key {
  width: clamp(48px, 13vw, 64px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--light-square);
  cursor: pointer;
}
.promotion-key .piece { width: 80%; }

.toast {
  margin: 0;
  min-height: 3em;
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--muted);
}
.toast[data-kind="wrong"] { color: var(--bad); }
.toast[data-kind="solved"] { color: var(--good); }
.toast[data-kind="hint"] { color: var(--hint); }

/* 다 푼 뒤에만 나오는 줄. 왜 이겼는지 한 줄로 적고, 이어지는 수순을 판 위에서
   되짚어 볼 수 있게 한다. */
.after {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card-bg);
}
.after[hidden] { display: none; }
.why { margin: 0; flex: 1; font-size: 13px; line-height: 1.5; }
.btn.ghost {
  flex: none;
  border: 1px solid var(--line);
  background: none;
  color: inherit;
  font-size: 12px;
  padding: 6px 10px;
}
.btn.ghost:disabled { opacity: 0.5; cursor: default; }

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

.tool {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 8px 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: none;
  color: inherit;
  font-family: inherit;
  cursor: pointer;
}
.tool:active { background: var(--key-bg); }
/* 도구 아이콘은 글자가 아니라 도형이다(`shared/icons.js`). 기호 문자로 두었더니
   글꼴마다 크기와 두께가 달랐고, 아예 안 그리는 글꼴도 있었다. */
.tool-icon { display: inline-flex; line-height: 0; }
.tool-icon svg { width: 19px; height: 19px; }
.tool-label { font-size: 11px; font-weight: 600; }

.source { margin: 0; text-align: center; font-size: 11px; color: var(--muted); }

.sheet {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--sheet-bg);
  padding: 14px 16px;
}
.sheet[hidden] { display: none; }
.sheet-title { margin: 0 0 8px; font-weight: 700; }
.help-list { margin: 0; padding-inline-start: 18px; font-size: 13px; line-height: 1.7; }
.help-list li { margin-bottom: 6px; }
.sheet-actions { display: flex; justify-content: flex-end; margin-top: 10px; }

.btn {
  border: 0;
  border-radius: 8px;
  padding: 8px 16px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: inherit;
  font-weight: 700;
  cursor: pointer;
}
