:root {
  --bg: #f8f5f0;
  --fg: #332e28;
  --muted: #8b8276;
  --line: #ded5c8;
  --board-bg: #e6ded1;
  --cell-bg: #fffdf9;
  --wall: #b8ad9c;
  --edge: #4a443c;
  --grid: #ded5c8;
  --ink: #332e28;
  --bad: #c9503a;
  --btn-bg: #5c5347;
  --btn-fg: #f8f5f0;
  --sheet-bg: #fffdf9;
  /* 찾은 성어마다 색을 돌려 쓴다. 길이 서로 감기므로 색이 갈리지 않으면 어느 길이
     어느 성어인지 눈으로 따라갈 수 없다. **아홉 색을 색상환에 고르게 벌려 놓고
     밝기는 비슷하게 맞춘다** — 몰아 놓으면 이웃한 두 색이 같아 보인다.
     **마지막 셋은 색상이 아니라 밝기로 가른다.** 8×8에는 성어가 열두 개까지
     오는데 색상환을 열둘로 쪼개면 서로 닮은 색이 생긴다. 앞의 세 색을 어둡게(어두운
     테마에서는 밝게) 눕혀 두면 같은 계열이라도 한눈에 갈린다. */
  --w0: #a8524e;
  --w1: #a4703c;
  --w2: #77863c;
  --w3: #4f8a6d;
  --w4: #3f8a93;
  --w5: #4a6fa5;
  --w6: #6a5fa8;
  --w7: #8b5e9c;
  --w8: #a8557f;
  --w9: #6d3a35;
  --w10: #6b4a25;
  --w11: #4b5525;
  --pad-x: clamp(10px, 4vmin, 28px);
  --app-max: 440px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #1a1714;
    --fg: #e7e0d6;
    --muted: #94897b;
    --line: #3a342d;
    --board-bg: #2d2822;
    --cell-bg: #241f1a;
    --wall: #4a423a;
    --edge: #cfc7b9;
    --grid: rgba(255, 255, 255, 0.1);
    --ink: #e7e0d6;
    --bad: #de6a52;
    --btn-bg: #4c453b;
    --sheet-bg: #241f1a;
    --w0: #c2665f;
    --w1: #bd8548;
    --w2: #92a24e;
    --w3: #5d9d7e;
    --w4: #56a3ac;
    --w5: #5f85bd;
    --w6: #8079c4;
    --w7: #a172b4;
    --w8: #c06a95;
    --w9: #e8a49d;
    --w10: #e3c08a;
    --w11: #c8d492;
  }
}

* { 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);
  overscroll-behavior: none;
}

.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; }

h1 {
  margin: 0;
  font-size: clamp(20px, 5.4vmin, 30px);
  font-weight: 800;
  letter-spacing: -0.02em;
}

.head-actions { display: flex; align-items: baseline; gap: 14px; }

.toggle {
  border: 0; background: none; padding: 0;
  color: inherit; font-family: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer; opacity: 0.6;
}
.toggle:hover { opacity: 1; }
.toggle.sound { font-size: 12px; }
/* 취소선은 소리 토글에만 준다. 도움말의 꺼짐은 "안 열림"이라 뜻이 다르다. */
.toggle.sound[aria-pressed="false"] { opacity: 0.38; text-decoration: line-through; }

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

.picker-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.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: 4px 10px;
  cursor: pointer;
}

.pick[aria-pressed="true"] {
  background: var(--btn-bg);
  border-color: var(--btn-bg);
  color: var(--btn-fg);
}

.best {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.timer {
  margin-inline-start: auto;
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.board-wrap { position: relative; min-height: 200px; }

.board {
  position: relative;
  user-select: none;
  /* **칸 너비를 정수 픽셀로 끊는다.** 소수점으로 두면 브라우저가 열마다 다르게
     반올림해 어떤 칸이 1픽셀 넓어지고, 그만큼 글자도 열마다 다른 자리에 놓인다.
     끊는 것은 아래 @supports가 맡는다. --cols는 buildBoard가 넣는다. */
  --cell-raw: min(clamp(44px, 18vmin, 82px),
    calc((min(100vw - 2 * var(--pad-x), var(--app-max))) / var(--cols)));
  --cell: var(--cell-raw);
  display: grid;
  width: max-content;
  margin-inline: auto;
  background: var(--board-bg);
  border-radius: 0;
  gap: 0;
  --board-pad: 2px;
  padding: var(--board-pad);
  /* 끌어서 길을 긋는 판이라 브라우저가 스크롤을 가져가면 안 된다. `none`이면
     `shared/base.js`가 그 안의 touchend를 모두 취소해 확대도 걸리지 않는다. */
  touch-action: none;
}

/* `round()`를 아는 브라우저에서만 끊는다. **커스텀 속성은 값이 이상해도 파싱에서
   버려지지 않아**, 모르는 브라우저에 그냥 두면 `--cell`이 통째로 무효가 되어 판이
   무너진다. */
@supports (width: round(down, 3px, 2px)) {
  .board { --cell: round(down, var(--cell-raw), 1px); }
}

.cell {
  position: relative;
  width: var(--cell);
  height: var(--cell);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--cell-bg);
  color: var(--ink);
  font-size: calc(var(--cell) * 0.46);
  font-weight: 700;
  line-height: 1;
}

/* **글자는 길 위에 남는다.** 길을 칸 배경 위에 겹쳐 그려야 어느 순서로 이어지는지
   보이는데, 그러면 글자가 그 밑에 깔린다. 글자만 따로 싸서 올린다 — 칸 자체를
   올리면 칸 배경이 같이 올라와 길을 통째로 덮는다. */
.cell .ch { position: relative; z-index: 2; }

/* 벽. 글자가 없으므로 색만으로 "여기는 쓰지 않는다"를 말해야 한다. */
.cell.wall { background: var(--wall); }

/* 찾은 성어에 든 칸. **색을 옅게 깐다** — 진하게 칠하면 그 위에 같은 색으로 긋는
   길이 배경에 묻혀 사라지고, 글자도 흰색으로 바꿔야 해서 판이 시끄러워진다. */
.cell.w0 { background: color-mix(in srgb, var(--w0) 22%, var(--cell-bg)); }
.cell.w1 { background: color-mix(in srgb, var(--w1) 22%, var(--cell-bg)); }
.cell.w2 { background: color-mix(in srgb, var(--w2) 22%, var(--cell-bg)); }
.cell.w3 { background: color-mix(in srgb, var(--w3) 22%, var(--cell-bg)); }
.cell.w4 { background: color-mix(in srgb, var(--w4) 22%, var(--cell-bg)); }
.cell.w5 { background: color-mix(in srgb, var(--w5) 22%, var(--cell-bg)); }
.cell.w6 { background: color-mix(in srgb, var(--w6) 22%, var(--cell-bg)); }
.cell.w7 { background: color-mix(in srgb, var(--w7) 22%, var(--cell-bg)); }
.cell.w8 { background: color-mix(in srgb, var(--w8) 22%, var(--cell-bg)); }
.cell.w9 { background: color-mix(in srgb, var(--w9) 22%, var(--cell-bg)); }
.cell.w10 { background: color-mix(in srgb, var(--w10) 22%, var(--cell-bg)); }
.cell.w11 { background: color-mix(in srgb, var(--w11) 22%, var(--cell-bg)); }

/* 긋는 중인 길. 아직 성어가 아니므로 색을 주지 않고 테두리로만 표시한다. */
.cell.draft { box-shadow: inset 0 0 0 3px var(--edge); z-index: 2; }
.cell.bad { animation: shake 0.3s ease-in-out; }

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

@media (prefers-reduced-motion: reduce) {
  .cell.bad { animation-duration: 1ms; }
}

.ink {
  position: absolute;
  inset: var(--board-pad);
  /* **크기를 인셋에 맡기지 않고 직접 준다.** `<svg>`는 대체 요소라 너비가 auto면
     사파리가 오른쪽·아래 인셋을 버리고 제 본래 크기(패딩 상자)를 쓴다. 그러면 칸
     영역보다 패딩 두 몫만큼 큰 상자에 그려져 길이 칸에서 어긋난다. */
  width: calc(100% - 2 * var(--board-pad));
  height: calc(100% - 2 * var(--board-pad));
  pointer-events: none;
  z-index: 1;
}

/* 칸 구분선. 칸이 아니라 여기서 긋는 이유는 길과 같은 좌표계에 있어야 서로 밀려
   보이지 않기 때문이다. 가로세로로만 긋는 선이라 픽셀 격자에 맞춰 끊는다. */
.ink .grid {
  fill: none;
  stroke: var(--grid);
  stroke-width: 0.04;
  shape-rendering: crispEdges;
}

/* 길. 칸 색만으로는 네 글자가 어느 순서로 이어지는지 알 수 없어 선을 겹쳐 긋는다.
   둥글게 마감해야 꺾이는 자리가 매끄럽다. */
.ink .trail {
  fill: none;
  stroke-width: 0.13;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.85;
}

.ink .trail.t0 { stroke: var(--w0); }
.ink .trail.t1 { stroke: var(--w1); }
.ink .trail.t2 { stroke: var(--w2); }
.ink .trail.t3 { stroke: var(--w3); }
.ink .trail.t4 { stroke: var(--w4); }
.ink .trail.t5 { stroke: var(--w5); }
.ink .trail.t6 { stroke: var(--w6); }
.ink .trail.t7 { stroke: var(--w7); }
.ink .trail.t8 { stroke: var(--w8); }
.ink .trail.t9 { stroke: var(--w9); }
.ink .trail.t10 { stroke: var(--w10); }
.ink .trail.t11 { stroke: var(--w11); }
.ink .trail.draft { stroke: var(--edge); opacity: 0.55; }

/* 길이 시작하는 칸. 네 글자를 어느 쪽에서부터 읽는지 이것으로 안다. **점이 아니라
   고리다** — 칸 한가운데에 점을 찍으면 그 위에 오는 글자에 가려 보이지 않는다. */
.ink .head {
  fill: none;
  stroke-width: 0.05;
  opacity: 0.85;
}
.ink .head.t0 { stroke: var(--w0); }
.ink .head.t1 { stroke: var(--w1); }
.ink .head.t2 { stroke: var(--w2); }
.ink .head.t3 { stroke: var(--w3); }
.ink .head.t4 { stroke: var(--w4); }
.ink .head.t5 { stroke: var(--w5); }
.ink .head.t6 { stroke: var(--w6); }
.ink .head.t7 { stroke: var(--w7); }
.ink .head.t8 { stroke: var(--w8); }
.ink .head.t9 { stroke: var(--w9); }
.ink .head.t10 { stroke: var(--w10); }
.ink .head.t11 { stroke: var(--w11); }

.veil {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--bg) 75%, transparent);
  font-weight: 700;
  color: var(--muted);
}
.veil[hidden] { display: none; }

.toast {
  margin: 0;
  min-height: 20px;
  text-align: center;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.5;
  color: var(--muted);
}

.tools { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; }

.tool {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 7px 0;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: none;
  color: inherit;
  font-family: inherit;
  cursor: pointer;
}
/* 도구 아이콘은 글자가 아니라 도형이다(`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; opacity: 0.8; }
.tool:disabled { opacity: 0.35; cursor: default; }

/* 찾은 성어와 뜻. **결과 카드에 넣지 않고 판 아래에 쌓는다** — 판을 푸는 동안
   하나씩 늘어나는 것이 진행 표시가 되고, 다 푼 뒤에도 그대로 남아 읽힌다. */
.found {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-height: 20px;
}

.found li {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 13px;
  line-height: 1.4;
}

.found .word { font-weight: 800; flex: none; }
.found .word.f0 { color: var(--w0); }
.found .word.f1 { color: var(--w1); }
.found .word.f2 { color: var(--w2); }
.found .word.f3 { color: var(--w3); }
.found .word.f4 { color: var(--w4); }
.found .word.f5 { color: var(--w5); }
.found .word.f6 { color: var(--w6); }
.found .word.f7 { color: var(--w7); }
.found .word.f8 { color: var(--w8); }
.found .word.f9 { color: var(--w9); }
.found .word.f10 { color: var(--w10); }
.found .word.f11 { color: var(--w11); }
.found .mean { color: var(--muted); }

.sheet {
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--sheet-bg);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.sheet[hidden] { display: none; }

.sheet-title { margin: 0; font-size: 19px; font-weight: 800; }
.sheet-note { margin: 0; font-size: 14px; color: var(--muted); }
.sheet-actions { display: flex; gap: 8px; }

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

.help-list {
  margin: 0;
  padding-left: 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 14px;
  line-height: 1.55;
}
