/*
 * 보석 테마, 미니멀.
 *
 * 규칙 세 개.
 * 1. 이모지 없음. 보석 모양이 필요하면 SVG 나 45도 돌린 사각형으로 만든다.
 * 2. 선을 아낀다. 상자를 겹겹이 두르면 오밀조밀해진다. 구분은 여백으로 먼저 하고,
 *    선은 정말 갈라야 할 때만 쓴다. 그라디언트도 표면마다 두지 않는다.
 * 3. 색은 강조 하나로 몰아준다. 빛나는 건 답 하나뿐이고 나머지는 조용하다.
 */
:root {
  --bg: #0c0a12;
  --panel: #17141f;
  --panel-2: #201c2c;
  --line: #292437;
  --edge: #3b3357;
  --fg: #ece9f5;
  --dim: #8f8aa3;
  --label: #b5afc6;
  /*
   * 읽기 전에는 색이 없다.
   *
   * 여기 있던 #a78bfa 는 어느 AI 도 기본으로 뱉는 보라(tailwind violet-400)였고,
   * 짝이던 시안과 함께 "AI 가 만든 화면" 의 첫 번째 표식이다. 그런데 이 화면에서
   * 색은 장식이 아니라 정보다 - 강조색이 곧 젬 계열이다. 그래서 젬을 읽기 전에는
   * 아무 색도 주지 않는다. 뼈색으로 있다가, 젬이 들어오면 그 젬의 색으로 켜진다.
   */
  --accent: #ddd8cf;
  --accent-2: #f2eee7;
  --glow: rgba(221, 216, 207, 0.07);
  --good: #4ade80;
  --warn: #fbbf24;
  --bad: #fb7185;
  --ink: #0c0a12;
}

/* 젬 계열에 따라 색이 바뀐다. 화면에 띄운 젬과 같은 색이어야 헷갈리지 않는다.
   질서가 빨강, 혼돈이 파랑이다. */
body[data-gem="order"] {
  --accent: #f2536b;
  --accent-2: #ffa3b1;
  --glow: rgba(242, 83, 107, 0.16);
  /* 강조색이 빨강이면 오류 표시가 묻힌다. 붉은 주황으로 밀어 갈라놓되
     경고(--warn 호박색)와도 갈려야 한다. */
  --bad: #ff6a33;
}
body[data-gem="chaos"] {
  --accent: #4d8dfa;
  --accent-2: #86c9ff;
  --glow: rgba(77, 141, 250, 0.18);
}

* { box-sizing: border-box; }

/* HTML 의 hidden 속성은 브라우저 기본 스타일(display:none)이라 우선순위가 가장 낮다.
   아래에서 .answer 에 display:grid, .note 에 display:flex 를 주는 순간 그대로 덮여서
   hidden=true 인데도 계속 보인다. gempago-poc 에서 같은 원인으로 오버레이가 안 사라지고
   드래그 이벤트를 전부 가로챈 적이 있다. */
[hidden] { display: none !important; }

body {
  margin: 0;
  padding: 30px 20px 80px;
  color: var(--fg);
  font: 14px/1.6 "Pretendard", "Malgun Gothic", system-ui, sans-serif;
  /* 조명 하나. 단색이면 패널이 종이처럼 보이는데, 두 개를 겹치면 그것대로 어수선하다. */
  background: radial-gradient(1100px 700px at 50% -20%, var(--glow), transparent 65%) var(--bg);
  background-attachment: fixed;
}

/*
 * 우리가 안 그린 표면도 이 디자인에 속한다. 스크롤바, 캐럿, 포커스 링은 손대지 않으면
 * 어느 디자인에도 속하지 않는 브라우저 기본값으로 남는다. 어두운 페이지에 밝은
 * 스크롤바가 붙는 순간 조립한 티가 난다.
 */
::selection { background: var(--accent); color: var(--ink); }

html {
  scrollbar-color: var(--line) transparent;
  scrollbar-width: thin;
}
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--line);
  border: 3px solid var(--bg);
  border-radius: 999px;
}
::-webkit-scrollbar-thumb:hover { background: var(--edge); }

input, select, textarea { caret-color: var(--accent); }

/*
 * 키보드로 옮겨 다닐 때만 링을 보여준다. 예전에는 select 에 outline: none 을 주고
 * 1px 테두리 색만 바꿨는데, 키보드 사용자에게는 지금 어디 있는지가 안 보였다.
 */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
:focus:not(:focus-visible) { outline: none; }

/* ---- 머리 ---------------------------------------------------------------- */

.top {
  max-width: 1340px;
  margin: 0 auto 22px;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  column-gap: 12px;
  align-items: center;
}
.logo { grid-row: 1 / 3; width: 26px; height: 26px; }
.top h1 { margin: 0; font-size: 19px; font-weight: 700; letter-spacing: -0.02em; }
.sub { margin: 0; color: var(--dim); font-size: 12px; }

/* ---- 판 ------------------------------------------------------------------ */

/*
 * 좌우 3단. 가운데가 답이고 양옆이 그 답을 정하는 두 입력이다.
 * 왼쪽 = 화면에서 읽어 온 것, 오른쪽 = 사람이 정하는 것.
 * 세로로 쌓으면 답이 접이식 패널 밑으로 밀린다.
 */
.cols {
  max-width: 1340px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 5fr) minmax(0, 4fr);
  gap: 16px;
  align-items: start;
}
/* 공유 조작은 세 단 위를 가로지른다. 어느 단에도 속하지 않는 시작 버튼이다. */
.span-all { grid-column: 1 / -1; }
.col {
  display: grid;
  gap: 14px;
  align-content: start;
  min-width: 0;
}
/*
 * 그리드 자식의 기본 min-width 는 auto(= min-content) 다. 접이식 제목의 요약줄이
 * white-space: nowrap 이라 젬 요약이 길어지면 그 길이가 곧 칸의 최소 폭이 되고,
 * 칸이 통째로 밀려 옆 칸을 덮는다 - 실제로 405px 칸에서 504px 이 나와 답 패널을
 * 가렸다. 요약줄은 이미 ellipsis 가 붙어 있으니 줄어들어도 된다.
 */
.cols > *,
.col > * { min-width: 0; }

.panel,
.live,
.note,
.answer {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
}

/* 젬을 읽으면 페이지 전체가 그 젬의 색으로 옮겨간다. 한 번에, 조용히. */
body { transition: background-color 600ms ease-out; }
.fold-title,
.panel h2,
.live button,
.presets button[aria-pressed="true"] {
  transition: color 500ms ease-out, background-color 500ms ease-out, border-color 500ms ease-out;
}

.panel { padding: 20px; }
.panel h2 {
  margin: 0 0 14px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--accent);
}
/* 음수 위쪽 여백은 h2 바로 밑에 붙으라고 준 것이다. 예전에 .hint 전체에 걸었더니
   제목이 없는 자리(접이식 본문, 목표 패널 맨 끝)에서 그 여백이 위 요소를 파고들었다.
   그래서 h2 다음에 오는 것만 당긴다. */
.hint { margin: 0 0 16px; color: var(--dim); font-size: 12px; }
h2 + .hint { margin-top: -8px; }
.hint:empty { display: none; }

/* ---- 답 ------------------------------------------------------------------ */

/* 알트탭으로 넘어왔을 때 스크롤 없이 이것만 눈에 들어와야 한다. */
.answer {
  display: grid;
  gap: 20px;
  padding: 24px;
}

.verdict {
  font-size: 30px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.03em;
}
.verdict small {
  display: block;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--dim);
  margin-top: 8px;
}
.verdict.commit { color: var(--good); }
.verdict.reroll { color: var(--warn); }

/* 상자를 두르지 않는다. 고른 쪽 위에만 선을 하나 긋는다 - 탭처럼 읽힌다. */
.compare { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.opt {
  padding-top: 11px;
  border-top: 2px solid var(--line);
}
.opt .k { display: block; color: var(--dim); font-size: 12px; }
.opt .v {
  display: block;
  margin-top: 2px;
  font-size: 27px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.opt.pick { border-top-color: var(--accent); }
.opt.pick .k { color: var(--accent); }

/* 줄마다 선을 그으면 표가 창살이 된다. 머리글 아래 하나면 충분하다. */
/* 표는 내용만큼만 넓힌다. 100% 로 늘리면 확률이 카드 오른쪽 끝까지 밀려나서
   항목과 그 확률이 한 줄로 안 읽히고 눈이 두 번 왔다 갔다 한다. */
.breakdown { width: max-content; max-width: 100%; border-collapse: collapse; font-size: 13px; }
.breakdown th {
  text-align: left;
  color: var(--dim);
  font-weight: 400;
  font-size: 12px;
  padding: 0 0 8px;
  border-bottom: 1px solid var(--line);
}
.breakdown td { padding: 7px 0; color: var(--label); }
.breakdown tr:first-child td { padding-top: 11px; }
.breakdown th:first-child,
.breakdown td:first-child { white-space: nowrap; padding-right: 28px; }
/* 숫자는 오른쪽 맞춤이라야 소수점이 한 줄로 선다. 칸 자체가 이미 좁아서
   오른쪽 맞춤을 해도 항목 바로 옆에 붙어 있다. */
.breakdown td:last-child {
  text-align: right;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}

.meta { margin: 0; color: var(--dim); font-size: 12px; }

/* ---- 공유 조작 줄 --------------------------------------------------------- */

.live {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  padding: 13px 16px;
}
.live button {
  background: var(--accent);
  color: var(--ink);
  border: 1px solid transparent;
  border-radius: 9px;
  padding: 8px 16px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.live button.ghost,
.live button.on {
  background: none;
  border-color: var(--line);
  color: var(--label);
  font-weight: 400;
}
.live button.ghost:hover:not(:disabled),
.live button.on:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.live button:disabled { opacity: 0.35; cursor: default; }

/* 상태 문구가 버튼 사이에서 자리를 잡는다. 길이가 계속 바뀌기 때문. */
.live-state { flex: 1 1 200px; color: var(--dim); font-size: 12px; }
.live-state.ok { color: var(--good); }
.live-state.warn { color: var(--warn); }
.live-state.bad { color: var(--bad); }

.toggle { display: flex; align-items: center; gap: 6px; color: var(--dim); font-size: 12px; }
.toggle input { accent-color: var(--accent); }

/* ---- 접이식 패널 ---------------------------------------------------------- */

.fold { padding: 0; }
.fold > summary {
  list-style: none;
  cursor: pointer;
  padding: 16px 20px;
  display: flex;
  align-items: baseline;
  gap: 10px;
  border-radius: 14px;
}
.fold > summary::-webkit-details-marker { display: none; }
.fold-title {
  color: var(--accent);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
}
/*
 * 제목마다 점을 찍으면 그건 장식이고, 장식은 아무 말도 안 한다. 읽기가 흔들린
 * 패널에만 찍는다 - 그때부터 이 점은 "여기 봐라" 라는 뜻이 된다.
 */
.fold.attention .fold-title::before,
.fold.bad .fold-title::before {
  content: "";
  width: 5px;
  height: 5px;
  transform: rotate(45deg);
}
.fold-sum {
  flex: 1 1 auto;
  color: var(--dim);
  font-size: 12px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 알약 테두리를 두르면 그것도 상자다. 글자만 남긴다. */
.fold > summary::after {
  content: "펼치기";
  flex: none;
  color: var(--dim);
  font-size: 11px;
}
.fold[open] > summary::after { content: "접기"; }
.fold > summary:hover::after { color: var(--accent); }
.fold-body { padding: 0 20px 20px; }
/* .hint 의 음수 위쪽 여백은 .panel h2 밑에 붙으라고 준 것이다. 접이식 본문에는 h2 가
   없어서 그 여백이 밖으로 새어 나가 제목 줄을 4px 파고든다(playwright 로 잡았다). */
.fold-body > :first-child { margin-top: 0; }

/* 읽기가 흔들린 패널만 눈에 띄게 한다. 평소에는 조용히 접혀 있는 게 정상. */
.fold.attention { border-color: var(--warn); }
.fold.attention .fold-sum { color: var(--warn); }
.fold.attention .fold-title::before { background: var(--warn); }
.fold.bad { border-color: var(--bad); }
.fold.bad .fold-sum { color: var(--bad); }
.fold.bad .fold-title::before { background: var(--bad); }

/* ---- 입력 ---------------------------------------------------------------- */

.row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 11px;
}
.row > span { color: var(--label); font-size: 13px; }

select,
input[type="text"] {
  /* background 단축을 쓰면 background-color 가 transparent 로 돌아가는데, 네이티브
     드롭다운 목록은 그 색으로 그려진다. 이걸 놓치면 펼쳤을 때 글씨가 안 보인다. */
  background-color: var(--panel-2);
  color: var(--fg);
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 7px 10px;
  font: inherit;
  min-width: 136px;
}
select:hover,
input[type="text"]:hover { border-color: var(--line); }
select:focus,
input[type="text"]:focus { border-color: var(--accent); }
input[type="text"]::placeholder { color: var(--dim); }

/* 드롭다운 목록은 브라우저가 그린다. 변수를 못 읽는 경우가 있어 값을 직접 적는다. */
option {
  background-color: #201c2c;
  color: #ece9f5;
}
option:checked { background-color: #292437; }

/* 목표는 현재 수치와 헷갈리면 안 되므로 초록을 쓰지 않는다. 다이아만 공유한다. */
#target .stat select { color: var(--accent-2); font-weight: 600; }

.stats { display: grid; gap: 12px; margin-bottom: 4px; }

/* ---- 수치 넷: 게임의 융합 완료 화면과 같은 모양 ---------------------------- */

/* 라벨이 남는 폭을 먹고 값은 오른쪽에 붙는다. 다이아 - 이름 - 숫자. */
.row.stat { gap: 11px; margin-bottom: 0; }
.row.stat > span { flex: 1 1 auto; }

/* 45도 돌린 사각형 = 젬 다이아. 수치마다 색이 다른 것도 게임과 같다. */
.dia {
  flex: none;
  width: 9px;
  height: 9px;
  transform: rotate(45deg);
  border-radius: 1px;
}
.stat[data-k="will"] .dia { background: #e2445e; }
.stat[data-k="point"] .dia { background: #eab447; }
.stat[data-k="opt1"] .dia { background: #5dc25b; }
.stat[data-k="opt2"] .dia { background: #4f8ef0; }

/*
 * 현재 수치는 게임처럼 초록 숫자로만 보인다. 그래도 select 그대로라 눌러서 고칠 수
 * 있다 - 인식이 흔들렸을 때 손댈 곳이 여기다. 그래서 텍스트로 바꾸지 않았다.
 */
#stats .stat select {
  width: 52px;
  min-width: 0;
  padding: 2px 4px;
  background-color: transparent;
  color: #a3e635;
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
  text-align-last: right;
  appearance: none;
  -webkit-appearance: none;
}
#stats .stat select:hover { background-color: var(--panel-2); }
/* 손가락으로는 30px 이 좁다. 인식이 틀렸을 때 고치러 오는 자리가 바로 여기다. */
@media (pointer: coarse) {
  #stats .stat select { padding: 9px 6px; }
}
#stats .stat select:focus { border-color: var(--accent); background-color: var(--panel-2); }

/* 게임 화면의 흐려지는 가로선. */
.sumline {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 16px 0 20px;
  padding-top: 16px;
}
.sumline::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line) 18%, var(--line) 82%, transparent);
}
.sumline span { color: var(--label); font-size: 13px; }
.sumline strong {
  color: #a3e635;
  font-size: 16px;
  font-variant-numeric: tabular-nums;
  padding-right: 4px;
}

/* ---- 목표 프리셋 ---------------------------------------------------------- */

.presets { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 18px; }
.presets button {
  background: none;
  color: var(--label);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 6px 13px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.presets button:hover { border-color: var(--accent); color: var(--accent); }
.presets button[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--ink);
  font-weight: 600;
}

.picks { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.picks select { min-width: 0; width: 100%; }

/* ---- 읽기 상세 ------------------------------------------------------------ */

.capture-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 14px; }
.capture-row button {
  background: none;
  color: var(--label);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 7px 13px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}
.capture-row button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.capture-row button:disabled { opacity: 0.35; cursor: default; }

.capture-status { margin: 0; color: var(--dim); font-size: 12px; white-space: pre-line; }
.capture-status:empty { display: none; }
.capture-status.ok { color: var(--good); }
.capture-status.warn { color: var(--warn); }
.capture-status.bad { color: var(--bad); }

#preview {
  width: 100%;
  max-height: 180px;
  object-fit: contain;
  margin-top: 14px;
  border-radius: 10px;
  background: #000;
}

/* 파일을 끌고 오는 동안에만 보이는 표시. */
body.dragging::after {
  content: "여기에 놓으면 읽는다";
  position: fixed;
  inset: 14px;
  border: 1px dashed var(--accent);
  border-radius: 16px;
  display: grid;
  place-items: center;
  font-size: 17px;
  color: var(--accent);
  background: rgba(12, 10, 18, 0.88);
  pointer-events: none;
  z-index: 10;
}

/* ---- 알림 ---------------------------------------------------------------- */

.note {
  padding: 16px 20px;
  color: var(--dim);
  font-size: 13px;
  display: flex;
  gap: 10px;
  align-items: baseline;
}
/* 읽기 전에는 여기가 답의 자리다. 작은 알림 줄로 두면 "뭘 해야 하지" 가 안 보인다. */
.note.empty {
  display: grid;
  gap: 8px;
  padding: 28px 24px 30px;
}
.note.empty strong { font-size: 16px; letter-spacing: -0.02em; }
.note.empty #noteText { line-height: 1.7; }

.note strong { color: var(--fg); flex: none; }
.note.error { border-color: var(--bad); }
.note.error strong { color: var(--bad); }

.spinner {
  flex: none;
  align-self: center;
  width: 13px;
  height: 13px;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/*
 * 이 화면에서 사람이 기다리는 순간은 하나다 - 판정이 바뀔 때. 거기에만 모션을 준다.
 * 이미 보이는 상태에서 출발해 지수 곡선으로 잦아든다(들어오는 애니메이션이 아니다).
 * 실제로 값이 달라졌을 때만 재생한다. 자동 갱신이 0.7초마다 도는데 매번 재생하면
 * 그건 모션이 아니라 깜빡임이다.
 */
.answer.changed .verdict,
.answer.changed .opt .v {
  animation: verdict 420ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
.answer.changed .opt .v { animation-delay: 40ms; }
@keyframes verdict {
  from { opacity: 0.55; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}

/* 색이 바뀌는 것들만 부드럽게. 레이아웃을 건드리는 전환은 두지 않는다. */
.opt,
.fold,
.presets button,
.capture-row button,
.live button,
select,
input[type="text"] {
  transition: border-color 140ms ease-out, color 140ms ease-out, background-color 140ms ease-out;
}

/* ---- 전체 로딩 ------------------------------------------------------------ */

/*
 * 첫 읽기는 배율을 찾느라 1~8초, 목표 첫 풀이는 2~10초 걸린다. 그동안 화면이 그대로면
 * 멈춘 것으로 읽힌다. 13px 짜리 테두리 스피너로는 눈에 안 들어와서 화면을 덮는다.
 * 배율을 잡은 뒤의 읽기는 60ms 라 여기 오지 않는다.
 */
.busy {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  background: rgba(12, 10, 18, 0.8);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.busy-card {
  display: grid;
  justify-items: center;
  gap: 16px;
  text-align: center;
  padding: 0 24px;
}
.busy-ring {
  position: relative;
  width: 62px;
  height: 62px;
  display: grid;
  place-items: center;
}
/* 고리 하나가 돈다. 마스크로 가운데를 뚫어 테두리만 남긴다. */
.busy-ring::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 0turn, transparent 0 58%, var(--accent) 100%);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
  animation: spin 1.1s linear infinite;
}
.busy-gem { width: 24px; height: 24px; }
#busyText { font-size: 15px; font-weight: 600; color: var(--fg); }
#busySub { font-size: 12px; color: var(--dim); min-height: 1em; }

@media (prefers-reduced-motion: reduce) {
  .busy-ring::before { animation-duration: 3s; }
  .spinner { animation-duration: 3s; }
  .answer.changed .verdict,
  .answer.changed .opt .v { animation: none; }
}

/* 마지막 줄 밑에 남는 여백을 지운다. 접이식 패널 안에서 특히 눈에 띈다. */
.row.last { margin-bottom: 0; }
.hint.last { margin-bottom: 0; }

/* 좁아지면 답이 먼저다. 매 턴 보는 게 그것뿐이다.
   공유 줄은 그보다 더 위에 둔다 - 답을 앞으로 당기다 보면 시작 버튼이
   화면 한가운데 파묻힌다(playwright 로 잡았다). */
@media (max-width: 1100px) {
  .cols { grid-template-columns: 1fr 1fr; }
  .live.span-all { order: -2; }
  .col-center { grid-column: 1 / -1; order: -1; }
}
@media (max-width: 700px) {
  .cols { grid-template-columns: 1fr; }
}

@media (max-width: 560px) {
  .compare { grid-template-columns: 1fr; gap: 16px; }
  .picks { grid-template-columns: 1fr; }
  .verdict { font-size: 25px; }
}
