/* 프로젝트 진행 상황 UI — 인덱스(폰)와 패널이 함께 쓴다.
 *
 * 두 페이지의 변수 이름이 다르다(인덱스는 --fg/--line/--panel, 패널은
 * --text/--border/--card). 그래서 var(A, var(B)) 로 둘 다 받는다.
 * 색을 새로 정의하지 않고 각 페이지의 색을 그대로 따라가게 하려는 것이다.
 *
 * 원칙
 *  - 문단이 아니라 항목. 제목(작고 흐림) + 내용(크고 또렷함) 을 짝으로 둔다.
 *  - 목록은 왼쪽에 붙이지 않는다. 글머리와 글 사이, 상자와 글 사이에 숨을 둔다.
 *  - 폰에서 읽히는 크기를 기준으로 잡는다.
 */

/* -------------------------------------------------------- 처음 뜰 때의 막 */
/* PIN 을 물을지는 호스트에 물어봐야 안다(/api/auth/info). 그 답이 오기까지
 * 잠깐이지만 **본 화면이 그대로 보였다** — 잠긴 화면인데 프로젝트 이름도
 * 대화 내용도 다 드러났다. 잠글 것인지 정할 때까지 덮어 둔다.
 *
 * 잠금 화면(#lock, z-index 40)보다 위에 있어야 한다. 정하고 나면 JS 가
 * 걷어내고, 그때 이미 #lock 이 펴져 있으므로 사이가 비지 않는다.
 * 두 페이지(인덱스·패널)가 같이 쓰므로 여기 둔다. */
#boot {
  position: fixed; inset: 0; z-index: 60;
  background: var(--bg, var(--bg0, #0e1117));
  display: grid; place-items: center;
}
#boot[hidden] { display: none; }
#boot > span {
  font-size: 12.5px; font-weight: 800; letter-spacing: .12em;
  text-transform: uppercase; color: var(--st-accent);
}

:root {
  --st-fg:     var(--text, var(--fg, #e6edf3));
  --st-muted:  var(--muted, #8b949e);
  --st-line:   var(--border, var(--line, #2d333b));
  --st-card:   var(--card2, #1c2128);
  --st-accent: var(--accent, #58a6ff);
  --st-ink:    var(--accent-ink, #06121f);
  --st-ok:     var(--ok, #3fb950);

  /* 점 색은 --accent 를 쓰지 않는다.
   *
   * 인덱스의 --accent 는 초록이라, 일하는 중과 그냥 기다리는 중이 둘 다
   * 초록으로 나왔다(깜빡이는 것만 달랐다). 상태마다 색을 따로 못 박는다.
   *   일하는 중  파랑 (깜빡임)
   *   방금 끝남  빨강 — 답이 와 있으니 봐 달라는 뜻
   *   기다리는 중 초록 — 지금 시켜도 되는 상태
   */
  --st-busy:  var(--busy, #3b82f6);
  --st-fresh: var(--rec, var(--err, #ef4444));

  /* 캔버스 바닥. 여기만은 반드시 불투명해야 한다 — 뒤가 비치면 판과 뒷화면이
     포개져 보인다. 인덱스와 패널 둘 다 --bg 를 쓴다. */
  --st-bg: var(--bg, #0e1117);

  /* 별표·일단락. 상태 색(초록·파랑·빨강) 어디와도 겹치지 않아야 한다 —
     저것들은 '지금 어떤가' 고 이것은 '내가 붙였다' 라서 뜻이 다르다.
     --warn 은 인덱스가 노랑(#d29922 계열)이라 그대로 빌린다. */
  --st-star: var(--warn, #e3b341);
}

/* ------------------------------------------------------------ 요약 덩어리 */
.sum { display: flex; flex-direction: column; gap: 6px; }

/* 제목은 작고 흐리게, 내용은 크고 또렷하게. 이 대비가 훑는 속도를 만든다. */
.sum-cap {
  font-size: 11.5px; font-weight: 800; letter-spacing: .03em;
  color: var(--st-muted); text-transform: none;
  margin-top: 4px;
}
.sum-cap:first-child { margin-top: 0; }
.sum-cap.next { color: var(--st-accent); }

/* 총정리 — 맨 위의 세 줄 (원래 / 문제 / 바뀜).
 *
 * 딱지와 글을 두 기둥으로 세운다. 딱지 폭을 고정해야 글머리가 세로로 딱
 * 맞아떨어져서, 눈이 딱지를 따라 내려가며 세 줄을 한 번에 잡는다. */
.sum-beats {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 5px 9px;
  align-items: baseline;
  padding: 9px 11px;
  border: 1px solid var(--st-line);
  border-radius: 9px;
  background: rgba(255, 255, 255, .03);
  margin-bottom: 4px;
}
/* 갈래 딱지 — 세 줄 위에 홀로. 두 칸을 다 쓴다.
 *
 * '이건 고친 것 / 이건 물어본 것' 이 색으로 먼저 온다. 딱지 글을 읽기 전에
 * 알아야, 아래 세 줄을 어떤 눈으로 읽을지가 정해진다. */
.sum-kind {
  grid-column: 1 / -1;
  justify-self: start;
  font-size: 11px; font-weight: 800; letter-spacing: .04em;
  padding: 2px 8px; border-radius: 999px;
  border: 1px solid currentColor;
  margin-bottom: 1px;
}
.sum-kind.fix  { color: var(--st-accent); }
.sum-kind.make { color: var(--st-ok); }
.sum-kind.tell { color: #9db4ff; }
.sum-kind.look { color: var(--st-star); }
.sum-kind.ask  { color: var(--rec, #ef4444); }
.sum-kind.mid  { color: var(--st-muted); }

/* 줄 딱지 — 작고 굵게. 셋의 색이 서로 다른 것은 구별을 위해서다.
   배경(흐림) → 핵심(노랑) → 결말(강조) 순으로 눈이 밝아진다. 갈래가
   무엇이든 자리의 뜻은 같아서, 색도 자리에 붙인다. */
.sum-beat-cap {
  font-size: 11px; font-weight: 800; letter-spacing: .02em;
  white-space: nowrap; text-align: center;
  min-width: 30px;
  padding: 1px 5px; border-radius: 5px;
  border: 1px solid currentColor;
  opacity: .95;
}
.sum-beat-cap.n0 { color: var(--st-muted); }
/* 가운데 자리는 노랑(--st-star 가 빌려 쓰는 --warn)이다. --st-busy 는 파랑이라
   바로 옆의 강조색(파랑)과 겹쳐서 두 딱지가 한 색으로 보였다. */
.sum-beat-cap.n1 { color: var(--st-star); }
.sum-beat-cap.n2 { color: var(--st-accent); }
.sum-beat-text {
  font-size: 14px; line-height: 1.5; color: var(--st-fg);
  word-break: break-word;
}

/* 눈에 걸 곳. 색만 바꾸고 배경은 아주 옅게 — 형광펜처럼 칠하면 글이 안 읽힌다. */
.sum-hi {
  color: var(--st-accent); font-weight: 800;
  background: color-mix(in srgb, var(--st-accent) 14%, transparent);
  border-radius: 4px; padding: 0 3px; margin: 0 -1px;
}
/* 색 섞기를 모르는 브라우저를 위한 바탕. 색만으로도 충분히 걸린다. */
@supports not (background: color-mix(in srgb, red 10%, transparent)) {
  .sum-hi { background: none; }
}

/* 옛 판 요약(줄글 하나). 새로 만들어지면 위의 세 줄로 바뀐다. */
.sum-gist {
  font-size: 15px; line-height: 1.7; color: var(--st-fg);
  padding: 2px 0 2px 11px;
  border-left: 3px solid var(--st-accent);
  word-break: break-word;
  margin-bottom: 2px;
}

.sum-text {
  display: block;
  font-size: 14.5px; line-height: 1.55; color: var(--st-fg);
  word-break: break-word;
}
.sum-text.next { color: var(--st-accent); }
/* 아직 답을 기다리는 중. 끝난 내용과 헷갈리지 않게 흐리게 둔다. */
.sum-text.pending { color: var(--st-muted, var(--muted)); font-style: italic; }

/* 목록 — 글머리와 글 사이를 벌리고, 상자 왼쪽에서도 띄운다 */
.sum-list {
  margin: 2px 0 0; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: 6px;
}
.sum-list li {
  position: relative;
  padding-left: 16px;
  font-size: 14px; line-height: 1.5; color: var(--st-fg);
  word-break: break-word;
}
.sum-list li::before {
  content: ""; position: absolute;
  left: 3px; top: .62em;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--st-accent); opacity: .75;
}

.sum-more { font-size: 12.5px; color: var(--st-muted); padding-left: 16px; }
.sum-wait { font-size: 13.5px; color: var(--st-muted); padding: 6px 0; }
/* 현황의 판(#now-board)만 좌우 여백이 없다 — 판이 화면을 통째로 쓰므로
   감싼 쪽도 padding 을 0 으로 둔다(styles.css 의 `#nowbox #now-body`).
   그 바람에 '불러오는 중…' 이 화면 왼쪽 끝에 딱 붙어 나왔다. 다른 자리는
   카드가 이미 여백을 주니 건드리지 않고, 여기서만 밀어 준다. */
#now-board > .sum-wait { padding: 10px 14px; }

/* --------------------------------------------------------- 전체 목록의 줄 */
.ov-row {
  display: flex; flex-direction: column; gap: 9px;
  padding: 15px 16px; border-radius: 14px;
  background: var(--st-card); border: 1px solid var(--st-line);
}
.ov-row.tappable { cursor: pointer; }
.ov-row.tappable:active { transform: translateY(1px); }
.ov-row.busy { border-color: color-mix(in srgb, var(--st-accent) 55%, transparent); }

.ov-head { display: flex; align-items: center; gap: 9px; }
.ov-head .led {
  width: 9px; height: 9px; border-radius: 50%; flex: none;
  background: var(--st-muted);
}
.ov-head .led.idle { background: var(--st-ok); }
.ov-head .led.busy { background: var(--st-busy); animation: st-pulse 1s infinite; }
@keyframes st-pulse { 50% { opacity: .25; } }

.ov-name {
  flex: 1; min-width: 0; font-size: 16px; font-weight: 800;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ov-age { flex: none; font-size: 12px; color: var(--st-muted); }
.ov-row.busy .ov-age { color: var(--st-accent); font-weight: 800; }

/* 최근에 답이 끝난 것 — 며칠 묵은 것과 섞이지 않게 표시를 단다 */
.ov-row.fresh { border-color: color-mix(in srgb, var(--st-ok) 45%, transparent); }
/* 방금 끝난 것의 점만 빨강. 답이 와 있으니 봐 달라는 표시다.
   `.ov-head .led.idle` (0,3,0) 를 이겨야 해서 한 단계 더 붙인다. */
.ov-row.fresh .ov-head .led.idle { background: var(--st-fresh); }
.ov-done {
  flex: none; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 800; white-space: nowrap;
  color: var(--st-ok);
  background: color-mix(in srgb, var(--st-ok) 16%, transparent);
}
.ov-row.fresh .ov-age { color: var(--st-ok); }

/* 아직 요약이 안 된 줄 — 원문이라 흐리게. 채워지면 또렷해진다. */
.ov-raw {
  font-size: 13.5px; line-height: 1.5; color: var(--st-muted);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* -------------------------------------------------- 5시간 외의 한도 알약들 */
/* 위쪽 띠에 들어가므로 아주 작고 낮아야 한다. 채워진 정도는 알약 안쪽을
   칠해서 보인다 — 막대를 따로 두면 줄이 하나 더 늘어난다. */
/* 위의 게이지와 붙지 않게 띄운다.
   게이지가 위쪽에 7px 을 갖고 있으니 그보다 조금 넉넉히 줘서, 게이지가
   '글자줄에 딸린 것' 이고 알약은 '그 아래 딴 줄' 로 읽히게 한다. */
.ulims { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 9px; }
.ulim {
  position: relative; overflow: hidden;
  padding: 2px 8px; border-radius: 999px;
  font-size: 10.5px; line-height: 1.5; font-weight: 600;
  color: var(--st-muted); background: var(--st-card);
  border: 1px solid var(--st-line);
  white-space: nowrap;
  --u: var(--st-ok);
}
.ulim[data-level="warning"]  { --u: #d29922; }
.ulim[data-level="critical"] { --u: var(--st-fresh); }
.ulim::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: var(--fill, 0%);
  background: color-mix(in srgb, var(--u) 28%, transparent);
}
/* 글자가 칠한 것에 묻히지 않게 위로 올린다 */
.ulim > .ulim-t { position: relative; }
.ulim > .ulim-t > b { color: var(--st-fg); font-weight: 800; }
/* 남은 기간은 곁가지다. 퍼센트보다 흐리게 둬야 숫자가 먼저 읽힌다. */
.ulim > .ulim-t > .ulim-left { font-weight: 500; opacity: .8; }

/* ------------------------------------------------------- 오늘 쓸 몫 한 줄 */
/* 위 알약들이 '얼마나 썼나' 라면 이건 '오늘 얼마나 써도 되나' 다. 성격이 다르니
   줄을 나누고, 알약 하나로 눕혀 둔다. 채워진 정도 = 오늘 몫 중 쓴 만큼.
   `hidden` 을 쓰므로 display 를 주는 규칙과 명시도를 맞춰 둔다 — 이 프로젝트에서
   포괄 규칙이 `hidden` 을 이겨 버린 일이 여러 번 있었다. */
.upace { display: flex; align-items: center; gap: 6px; margin-top: 5px; }
.upace[hidden] { display: none; }
.upace > .upace-pill {
  position: relative; overflow: hidden;
  padding: 2px 8px; border-radius: 999px;
  font-size: 10.5px; line-height: 1.5; font-weight: 600;
  color: var(--st-muted); background: var(--st-card);
  border: 1px dashed var(--st-line);      /* 실제 사용량이 아니라 '권고' 라서 점선 */
  white-space: nowrap;
  --u: var(--st-accent, #4c8dff);
}
.upace > .upace-pill[data-level="warn"] { --u: #d29922; }
.upace > .upace-pill[data-level="over"] { --u: var(--st-fresh); }
.upace > .upace-pill::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0;
  width: var(--fill, 0%);
  background: color-mix(in srgb, var(--u) 22%, transparent);
}
.upace > .upace-pill > .ulim-t { position: relative; }
.upace > .upace-pill > .ulim-t > .upace-tag {
  font-weight: 600; opacity: .7; margin-right: 3px;
}
/* 오늘 몫의 크기. 알약(진행 막대) 바깥에 곁들이는 글자라, 강조하지 않는다 —
   강조색은 진행률 몫이다. 알약과 같은 줄에 앉도록 .upace 를 flex 로 둔다. */
.upace > .upace-quota {
  font-size: 10px; font-weight: 500; color: var(--st-muted);
  opacity: .75; white-space: nowrap;
}
.upace > .upace-pill > .ulim-t > b { color: var(--u); font-weight: 800; }
.upace > .upace-pill > .ulim-t > .ulim-left { font-weight: 500; opacity: .8; }

/* ------------------------------------------------------------- 상태 배지 */
.now-state {
  display: inline-block; padding: 5px 12px; border-radius: 999px;
  font-size: 12.5px; font-weight: 800;
  background: var(--st-card); border: 1px solid var(--st-line); color: var(--st-muted);
}
.now-state.busy { color: var(--st-accent); border-color: color-mix(in srgb, var(--st-accent) 45%, transparent); }
.now-state.idle { color: var(--st-ok); border-color: color-mix(in srgb, var(--st-ok) 40%, transparent); }

/* ------------------------------------------------------------- 추천 명령 */
/* 여기 규칙은 일부러 한 단계 더 구체적으로 쓴다(.sug-row > X).
 *
 * 두 페이지 모두 자기 버튼을 크게 만드는 포괄 규칙을 갖고 있다
 * (인덱스: `.panel button { width:100%; min-height:60px }`).
 * `.panel button` 은 클래스1+요소1 이라 클래스 하나짜리 `.sug-go` 를 이긴다.
 * 그러면 ▶ 버튼이 width:100% 가 되어 줄을 통째로 먹고, 옆의 본문이 0폭으로
 * 눌려 **한 줄에 한 글자씩** 떨어진다. 자식 선택자로 한 단계 올려서 막는다.
 */
.sug { display: flex; flex-direction: column; gap: 10px; }
.sug-stage {
  padding: 12px 14px; border-radius: 12px;
  background: color-mix(in srgb, var(--st-accent) 13%, transparent);
  font-size: 14px; font-weight: 700; line-height: 1.5; color: var(--st-fg);
}

.sug-row { display: flex; gap: 8px; align-items: stretch; }
.sug .sug-row > .sug-pick {
  flex: 1 1 auto; width: auto; min-width: 0; min-height: 0;
  text-align: left; cursor: pointer;
  display: flex; flex-direction: column; gap: 5px;
  padding: 13px 15px; border-radius: 12px;
  font-family: inherit; font-size: 14px; font-weight: 400;
  color: var(--st-fg);
  background: var(--st-card); border: 1px solid var(--st-line);
}
.sug .sug-row > .sug-pick:active { transform: translateY(1px); }
.sug-label { font-size: 12.5px; font-weight: 800; color: var(--st-accent); }
.sug-body { font-size: 14px; line-height: 1.55; word-break: break-word; white-space: normal; }

.sug .sug-row > .sug-go {
  flex: 0 0 56px; width: 56px; min-width: 56px; min-height: 0;
  border-radius: 12px; cursor: pointer;
  font-family: inherit; font-size: 17px; font-weight: 800;
  color: var(--st-ink); background: var(--st-accent);
  border: 1px solid var(--st-accent);
}
.sug .sug-row > .sug-go:disabled { opacity: .45; }
.sug .sug-row > .sug-go:active:not(:disabled) { transform: translateY(1px); }

/* ------------------------------------------------------------- 직접 입력 */
/* 추천이 마음에 안 들 때 바로 쓸 수 있어야 한다. 프로젝트를 이미 고른
   상태이므로, 여기서 쓴 글은 그 프로젝트로 간다. */
.sug-own { display: flex; flex-direction: column; gap: 8px; margin-top: 2px; }
.sug-own-cap {
  font-size: 11.5px; font-weight: 800; letter-spacing: .03em;
  color: var(--st-muted);
}
.sug .sug-own > .sug-input {
  width: 100%; box-sizing: border-box; resize: vertical;
  min-height: 76px; padding: 12px 14px; border-radius: 12px;
  font-family: inherit; font-size: 14px; line-height: 1.55; font-weight: 400;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.sug .sug-own > .sug-input:focus {
  outline: none; border-color: var(--st-accent);
}
.sug-own-row { display: flex; gap: 8px; flex-wrap: wrap; }
/* 버튼이 셋이면 좁은 화면에서 글자가 눌린다. 최소 폭을 주고 넘치면 접는다. */
.sug .sug-own-row > button { flex: 1 1 30%; min-width: 92px; }
.sug .sug-own-row > button {
  flex: 1 1 0; width: auto; min-width: 0; min-height: 46px;
  border-radius: 12px; cursor: pointer;
  font-family: inherit; font-size: 14px; font-weight: 800;
}
.sug .sug-own-row > .sug-own-edit,
.sug .sug-own-row > .sug-own-mic {
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.sug .sug-own-row > .sug-own-mic.rec {
  color: #fff; background: #b3261e; border-color: #b3261e;
}
.sug .sug-own-row > .sug-own-send {
  color: var(--st-ink); background: var(--st-accent);
  border: 1px solid var(--st-accent);
}
.sug .sug-own-row > button:disabled { opacity: .45; }
.sug .sug-own-row > button:active:not(:disabled) { transform: translateY(1px); }

/* ------------------------------------------------------------- 프로젝트 */
.pj { display: flex; flex-direction: column; gap: 8px; }
.pj-cap {
  display: flex; align-items: center; gap: 7px;
  margin-top: 6px;
  font-size: 11.5px; font-weight: 800; letter-spacing: .03em; color: var(--st-muted);
}
.pj-cap:first-child { margin-top: 0; }
.pj-num {
  padding: 1px 7px; border-radius: 999px;
  background: var(--st-card); border: 1px solid var(--st-line);
}
.pj-rows { display: flex; flex-direction: column; gap: 7px; }
.pj-row { display: flex; gap: 7px; }
.pj-row.off { opacity: .55; }

.pj .pj-row > .pj-pick {
  flex: 1 1 auto; width: auto; min-width: 0; min-height: 0;
  display: flex; align-items: center; gap: 9px; text-align: left; cursor: pointer;
  padding: 11px 13px; border-radius: 11px;
  font-family: inherit; font-weight: 400;
  color: var(--st-fg); background: var(--st-card); border: 1px solid var(--st-line);
}
.pj .pj-row > .pj-pick:active { transform: translateY(1px); }
.pj-pick .led {
  flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--st-ok);
}
.pj-pick .led.busy { background: var(--st-busy); animation: st-pulse 1s infinite; }
.pj-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pj-name {
  font-size: 14.5px; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pj-note { font-size: 11.5px; color: var(--st-muted); }

.pj .pj-row > .pj-ex {
  flex: 0 0 auto; width: auto; min-width: 0; min-height: 0;
  padding: 0 12px; border-radius: 11px; cursor: pointer;
  font-family: inherit; font-size: 12.5px; font-weight: 700;
  color: var(--st-muted); background: var(--st-card); border: 1px solid var(--st-line);
}
.pj .pj-row > .pj-ex:active { transform: translateY(1px); }
.pj .pj-row > .pj-ex:disabled { opacity: .45; }
/* 한 번 더 눌러야 닫힌다는 것을 색으로 알린다 */
.pj .pj-row > .pj-shut.armed {
  color: #fff; background: #b3261e; border-color: #b3261e;
}
.pj-none { font-size: 13px; color: var(--st-muted); padding: 8px 0; }

/* ------------------------------------------------------------- 대기 목록의 버튼 */
/* 인덱스에서는 이 줄이 `.panel` 안에 들어간다. 거기 `.panel button` 이
   width:100%; min-height:60px 라서, 그냥 두면 버튼 두 개가 화면 폭짜리로
   위아래에 쌓인다. 추천 목록과 같은 이유로 한 단계 올려 쓴다. */
/* 보냈지만 그 프로젝트가 작업 중이라 도착 확인이 아직인 것.
   실패(빨강)와 섞이면 안 된다 — 글은 이미 들어가 있다. */
.q-row.waiting { border-color: color-mix(in srgb, var(--st-accent) 45%, transparent); }
.q-row.waiting .q-badge {
  color: var(--st-accent);
  background: color-mix(in srgb, var(--st-accent) 16%, transparent);
}
.q-note { font-size: 12px; line-height: 1.5; color: var(--st-muted); margin-top: 5px; }
/* 왜 아직 안 나갔는지. 오류(붉은색)가 아니라 '기다리는 중' 이므로 따로 둔다 —
   기다리는 것을 붉게 칠하면 고장으로 읽힌다. */
.q-why {
  font-size: 12px; line-height: 1.5; margin-top: 5px;
  padding: 5px 8px; border-radius: 8px;
  color: var(--st-busy, #3b82f6);
  background: color-mix(in srgb, var(--st-busy, #3b82f6) 12%, transparent);
}

.q-actions { display: flex; gap: 8px; margin-top: 9px; }
.q-row > .q-actions > button {
  flex: 1 1 0; width: auto; min-width: 0; min-height: 40px;
  padding: 0 12px; border-radius: 10px; cursor: pointer;
  font-family: inherit; font-size: 13.5px; font-weight: 700;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.q-row > .q-actions > .q-drop { color: var(--st-muted); }
/* 붙들어 두기 — 곁가지다. '지금 실행' 과 같은 무게로 두면 어느 쪽이 평소
   길인지 알 수 없다. 테두리만 노랗게 해서 있는 줄만 알린다. */
.q-row > .q-actions > .q-hold {
  flex: 0 0 auto; padding: 0 12px;
  color: var(--st-star);
  border-color: color-mix(in srgb, var(--st-star) 45%, transparent);
}
/* 보류한 줄. 기다리는 줄과 한눈에 갈려야 한다 — 하나는 저절로 나가고
   하나는 안 나간다. 점선으로 '줄에서 빠져 있다' 를 말한다. */
.q-row.s-held { border-style: dashed; }
.q-row.s-held .q-badge {
  color: var(--st-star);
  background: color-mix(in srgb, var(--st-star) 16%, transparent);
}
/* 고치기는 곁가지다 — 이 줄에서 자주 누르는 것은 '지금 실행' 이다. */
.q-row > .q-actions > .q-edit { flex: 0 0 auto; padding: 0 14px; color: var(--st-muted); }

/* 그 자리에서 고치는 칸.
 *
 * 다른 화면으로 넘어가지 않는다. 어느 줄을 고치는 중인지가 눈에서 사라지면
 * 엉뚱한 것을 고쳐 저장한다. 원래 글 자리에 그대로 열린다. */
.q-editbox { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.q-editbox > .q-editarea {
  width: 100%; box-sizing: border-box; resize: vertical;
  min-height: 64px; padding: 10px 12px; border-radius: 10px;
  font-family: inherit; font-size: 14px; line-height: 1.55;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-accent);
}
.q-editbar { display: flex; gap: 8px; }
/* 두 페이지의 포괄 버튼 규칙(width:100%, min-height:60px)을 이겨야 한 줄에 선다.
   .q-actions 쪽과 같은 명시도(0,3,1)로 맞춰 둔다. */
.q-row > .q-editbox > .q-editbar > button {
  flex: 1 1 0; width: auto; min-width: 0; min-height: 40px;
  padding: 0 12px; border-radius: 10px; cursor: pointer;
  font-family: inherit; font-size: 13.5px; font-weight: 700;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.q-row > .q-editbox > .q-editbar > .q-editsave {
  color: var(--st-ink); background: var(--st-accent); border-color: var(--st-accent);
}
.q-row > .q-editbox > .q-editbar > button:disabled { opacity: .45; }
/* 고친 줄임을 표시한다. 나중에 기록을 볼 때 원래 말과 다른 이유가 된다. */
.q-edited { color: var(--st-muted); font-weight: 700; font-size: 11px; }
.q-row > .q-actions > button:disabled { opacity: .45; }
.q-row > .q-actions > button:active:not(:disabled) { transform: translateY(1px); }

/* ------------------------------------------------------------- 원문 보기 */
/* 글이 많다. 작은 글씨 + 줄바꿈 유지 + 상자 안 스크롤로 한눈에 훑게 한다. */
.raw { display: flex; flex-direction: column; gap: 8px; margin-top: 2px; }
.raw-bar { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
/* 새로 받기 버튼도 이 목록에 **반드시** 넣는다. 두 페이지 모두 자기 버튼을
   크게 만드는 포괄 규칙을 갖고 있어(인덱스: `.panel button { width:100% }`)
   빠뜨리면 줄을 통째로 먹는다. */
.raw .raw-bar > .raw-btn,
.raw .raw-bar > .raw-full,
.raw .raw-bar > .raw-refresh {
  width: auto; min-width: 0; min-height: 34px;
  padding: 0 13px; border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: 12.5px; font-weight: 800;
  color: var(--st-muted); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.raw .raw-bar > .raw-btn.on {
  color: var(--st-accent);
  border-color: color-mix(in srgb, var(--st-accent) 45%, transparent);
}
/* ↻ 는 글자 하나뿐이라 원형으로 둔다 */
.raw .raw-bar > .raw-refresh {
  padding: 0; width: 34px; flex: 0 0 34px; font-size: 15px; font-weight: 400;
}
/* `[hidden]` 을 덮지 않게 되돌린다. display 를 주는 규칙이 [hidden] 보다 세다. */
.raw .raw-bar > .raw-full[hidden],
.raw .raw-bar > .raw-refresh[hidden] { display: none; }
.raw .raw-bar > .raw-btn:active,
.raw .raw-bar > .raw-full:active,
.raw .raw-bar > .raw-refresh:active:not(:disabled) { transform: translateY(1px); }
.raw .raw-bar > .raw-refresh:disabled { opacity: .5; }

.raw-note, .rawfs-note {
  font-size: 11.5px; font-weight: 700; color: var(--st-accent);
  white-space: nowrap;
}

/* 도는 동안 표시. 눌렀는지 안 눌렀는지가 보여야 한다. */
.raw-refresh.spin, .rawfs-refresh.spin { animation: st-spin .8s linear infinite; }
@keyframes st-spin { to { transform: rotate(360deg); } }

.raw-body { display: flex; flex-direction: column; gap: 6px; }
.raw-body[hidden] { display: none; }
.raw-cap {
  display: flex; align-items: center; gap: 8px;
  font-size: 11px; font-weight: 800; letter-spacing: .03em;
  color: var(--st-muted); margin-top: 2px;
}

/* 내가 쓴 말을 그대로 복사하는 단추.
 *
 * 머리줄(누가 언제)에 얹히는 곁가지라 작고 조용해야 한다 — 원문을 읽는 자리에
 * 색이 하나 더 늘면 글보다 단추가 먼저 보인다. 그래서 테두리만 두고,
 * 눌러서 복사된 순간에만 잠깐 초록으로 답한다.
 *
 * 두 페이지 모두 자기 버튼을 크게 만드는 포괄 규칙을 갖고 있어
 * (인덱스: `.panel button { width:100%; min-height:60px }`) 여기서 못 박는다.
 * 부모(.raw-cap/.ex-who)를 앞에 붙여 명시도를 한 단계 올린 것이 그 때문이다. */
.raw-cap > .raw-copy, .ex-who > .raw-copy {
  flex: 0 0 auto; width: auto; min-width: 0;
  min-height: 0; height: 22px; margin: 0 0 0 auto; padding: 0 8px;
  border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: 10.5px; font-weight: 800; line-height: 1;
  color: var(--st-muted); background: transparent;
  border: 1px solid var(--st-line);
  white-space: nowrap;
}
.raw-cap > .raw-copy:active, .ex-who > .raw-copy:active { transform: translateY(1px); }
.raw-cap > .raw-copy.done, .ex-who > .raw-copy.done {
  color: var(--st-ok); border-color: color-mix(in srgb, var(--st-ok) 55%, transparent);
}
.raw-cap > .raw-copy:disabled, .ex-who > .raw-copy:disabled { opacity: .5; }
.raw-text {
  margin: 0; padding: 10px 12px; border-radius: 10px;
  background: var(--st-card); border: 1px solid var(--st-line);
  color: var(--st-fg);
  /* 원문은 작게. 한 화면에 최대한 많이 들어와야 훑을 수 있다. */
  font-family: inherit;
  font-size: 11.5px; line-height: 1.5;
  word-break: break-word;
  max-height: 46vh; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  -webkit-user-select: text; user-select: text;
}
/* 표기랄 것이 없는 글(로그·코드 조각)은 줄바꿈을 그대로 지킨다 */
.raw-plain { margin: 0; font: inherit; white-space: pre-wrap; }

/* ------------------------------------------------------------- 마크다운 */
.md { display: flex; flex-direction: column; gap: 7px; }
.md-p { white-space: pre-wrap; }
.md-h { font-weight: 800; margin-top: 4px; }
.md-h1, .md-h2 { font-size: 1.25em; }
.md-h3, .md-h4 { font-size: 1.12em; }
.md-h5, .md-h6 { font-size: 1.04em; }
.md-hr { border: none; border-top: 1px solid var(--st-line); margin: 4px 0; }
.md-quote {
  padding-left: 9px; border-left: 3px solid var(--st-line);
  color: var(--st-muted); white-space: pre-wrap;
}
.md-list { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 3px; }
.md-code {
  padding: 1px 4px; border-radius: 4px;
  background: color-mix(in srgb, var(--st-fg) 12%, transparent);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .94em;
}
.md-pre {
  margin: 2px 0; padding: 9px 11px; border-radius: 8px;
  background: color-mix(in srgb, var(--st-fg) 8%, transparent);
  border: 1px solid var(--st-line);
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.md-pre code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .94em; line-height: 1.45; white-space: pre;
}
.md-link { color: var(--st-accent); }

/* 표 — 진짜 표로. 좁으면 표만 가로로 움직인다(바깥 화면은 그대로) */
.md-tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 2px 0; }
.md-table {
  border-collapse: collapse; width: max-content; min-width: 100%;
  font-size: .96em;
}
.md-table th, .md-table td {
  padding: 5px 9px; border: 1px solid var(--st-line);
  text-align: left; vertical-align: top; white-space: normal;
}
.md-table th {
  background: color-mix(in srgb, var(--st-fg) 8%, transparent);
  font-weight: 800; white-space: nowrap;
}
.md-table tbody tr:nth-child(even) td {
  background: color-mix(in srgb, var(--st-fg) 3%, transparent);
}
.raw-none { font-size: 12px; color: var(--st-muted); }

/* 폰에서는 조금 더 작게 — 원문은 '읽기' 보다 '찾기' 로 쓴다 */
@media (max-width: 480px) {
  .raw-text { font-size: 11px; line-height: 1.48; max-height: 42vh; }
}

/* ------------------------------------------ 대기 탭에서 바로 적어 넣는 칸 */
.qc {
  display: flex; flex-direction: column; gap: 8px;
  margin-top: 12px; padding-top: 14px;
  /* 바로 아래에 그 화면의 버튼 줄(새로 고침·닫기)이 이어진다.
     여백이 없으면 '대기시키기' 와 붙어 보여 어느 것을 누르는지 헷갈린다. */
  margin-bottom: 16px;
  border-top: 1px solid var(--st-line);
}
.qc-cap {
  font-size: 11.5px; font-weight: 800; letter-spacing: .03em;
  color: var(--st-muted);
}
.qc > .qc-proj {
  width: 100%; box-sizing: border-box; min-height: 44px;
  padding: 0 12px; border-radius: 10px;
  font-family: inherit; font-size: 14px; font-weight: 700;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.qc > .qc-input {
  width: 100%; box-sizing: border-box; resize: vertical;
  min-height: 72px; padding: 12px 14px; border-radius: 12px;
  font-family: inherit; font-size: 14px; line-height: 1.55; font-weight: 400;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.qc > .qc-input:focus, .qc > .qc-proj:focus {
  outline: none; border-color: var(--st-accent);
}
.qc-row { display: flex; gap: 8px; }
.qc .qc-row > button {
  flex: 1 1 0; width: auto; min-width: 0; min-height: 46px;
  border-radius: 12px; cursor: pointer;
  font-family: inherit; font-size: 14px; font-weight: 800;
}
.qc .qc-row > .qc-mic {
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.qc .qc-row > .qc-mic.rec {
  color: #fff; background: #b3261e; border-color: #b3261e;
}
.qc .qc-row > .qc-add {
  color: var(--st-ink); background: var(--st-accent);
  border: 1px solid var(--st-accent);
}
/* 보류로 넣기 — 평소 길이 아니므로 강조색을 주지 않는다.
   '있는 줄은 알되 먼저 손이 가지는 않게' (쪽지의 바로 보내기와 같은 규칙). */
.qc .qc-row > .qc-hold {
  flex: 0 0 auto; padding: 0 14px;
  color: var(--st-star); background: var(--st-card);
  border: 1px solid color-mix(in srgb, var(--st-star) 55%, transparent);
}
.qc .qc-row > button:disabled { opacity: .45; }
.qc .qc-row > button:active:not(:disabled) { transform: translateY(1px); }

/* ------------------------------------------- Claude 가 되묻는 질문 */
.ask {
  display: flex; flex-direction: column; gap: 12px;
  padding: 14px; border-radius: 14px;
  background: color-mix(in srgb, var(--st-accent) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--st-accent) 40%, transparent);
}
.ask-cap {
  font-size: 12px; font-weight: 800; letter-spacing: .03em;
  color: var(--st-accent);
}
.ask-q { display: flex; flex-direction: column; gap: 7px; }
.ask-head { font-size: 11.5px; font-weight: 800; color: var(--st-muted); }
.ask-text { font-size: 14px; line-height: 1.55; color: var(--st-fg); word-break: break-word; }

.ask .ask-q > .ask-opt {
  display: flex; gap: 10px; align-items: flex-start; text-align: left;
  width: 100%; box-sizing: border-box; min-height: 0;
  padding: 11px 13px; border-radius: 11px; cursor: pointer;
  font-family: inherit; font-weight: 400;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.ask .ask-q > .ask-opt.on {
  border-color: var(--st-accent);
  background: color-mix(in srgb, var(--st-accent) 18%, transparent);
}
.ask .ask-q > .ask-opt:active { transform: translateY(1px); }
.ask-num {
  flex: 0 0 22px; width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 12px; font-weight: 800;
  color: var(--st-ink); background: var(--st-accent);
}
.ask-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ask-label { font-size: 14px; font-weight: 700; line-height: 1.45; word-break: break-word; }
/* 고르는 것에 붙은 설명은 **끝까지 보인다.**
 *
 * 세 줄에서 잘라 두었었다. 목록이 짧아 보이라고 그랬는데, 잘린 자리에
 * 하필 고를 근거가 들어 있으면 무엇을 고르는지 모른 채 눌러야 한다 —
 * 실제로 263px 짜리 설명이 56px 만 보였다. 되돌릴 수 없는 선택도 있는
 * 자리라 짧게 보이는 것보다 다 보이는 것이 먼저다.
 *
 * 길어지면 상자가 스크롤한다(#ask-body 는 overflow-y:auto). */
.ask-desc {
  font-size: 12.5px; line-height: 1.5; color: var(--st-muted); word-break: break-word;
}

.ask .ask-q > .ask-other .ask-num {
  color: var(--st-fg); background: var(--st-line);
}
.ask .ask-q > .ask-other.on .ask-num {
  color: var(--st-ink); background: var(--st-accent);
}
.ask-own { display: flex; flex-direction: column; gap: 7px; }
.ask-own[hidden] { display: none; }
.ask .ask-own > .ask-input {
  width: 100%; box-sizing: border-box; resize: vertical;
  min-height: 64px; padding: 11px 13px; border-radius: 11px;
  font-family: inherit; font-size: 14px; line-height: 1.55; font-weight: 400;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-accent);
}
.ask .ask-own > .ask-input:focus { outline: none; }
.ask .ask-own > .ask-mic {
  width: 100%; box-sizing: border-box; min-height: 42px;
  border-radius: 11px; cursor: pointer;
  font-family: inherit; font-size: 13.5px; font-weight: 800;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.ask .ask-own > .ask-mic.rec { color: #fff; background: #b3261e; border-color: #b3261e; }
.ask .ask-own > .ask-mic:active { transform: translateY(1px); }

.ask > .ask-send {
  width: 100%; box-sizing: border-box; min-height: 48px;
  border-radius: 12px; cursor: pointer;
  font-family: inherit; font-size: 15px; font-weight: 800;
  color: var(--st-ink); background: var(--st-accent);
  border: 1px solid var(--st-accent);
}
.ask > .ask-send:disabled { opacity: .4; }

/* --------------------------------------------------------------- 폰 화면 */
@media (max-width: 480px) {
  .ov-row { padding: 13px 14px; border-radius: 12px; }
  .ov-name { font-size: 15px; }
  .sum-text { font-size: 14px; }
  .sum-list li { font-size: 13.5px; }
  .sug .sug-row > .sug-go { flex-basis: 48px; width: 48px; min-width: 48px; font-size: 15px; }
  .sug .sug-row > .sug-pick { padding: 12px 13px; }
  .sug .sug-own > .sug-input { min-height: 68px; }
}

/* --------------------------------------------------- 원문 전체화면 */
/* 모달 안은 좁다. 긴 원문을 훑을 때는 화면을 통째로 쓴다.
   현황·질문 모달(z-index 25~28) 위에 한 겹 더 올린다. */
.rawfs {
  position: fixed; inset: 0; z-index: 60;
  display: flex; flex-direction: column;
  background: var(--panel, #161b24);
}
.rawfs-bar {
  flex: none; display: flex; align-items: center; gap: 8px;
  padding: calc(12px + env(safe-area-inset-top, 0px)) 14px 12px;
  border-bottom: 1px solid var(--st-line);
  background: var(--panel, #161b24);
}
.rawfs-title {
  flex: 1; min-width: 0; font-size: 15px; font-weight: 800; color: var(--st-fg);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rawfs-bar > button {
  flex: 0 0 auto; width: auto; min-width: 0; min-height: 36px;
  padding: 0 13px; border-radius: 10px; cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 700;
  color: var(--st-fg); background: var(--st-card); border: 1px solid var(--st-line);
}
.rawfs-bar > button:active { transform: translateY(1px); }
/* ↻ 는 글자 하나뿐이라 정사각으로 */
.rawfs-bar > .rawfs-refresh {
  padding: 0; width: 36px; flex: 0 0 36px; font-size: 16px; font-weight: 400;
}
.rawfs-bar > .rawfs-refresh:disabled { opacity: .5; }

.rawfs-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  padding: 14px 14px calc(20px + env(safe-area-inset-bottom, 0px));
  display: flex; flex-direction: column; gap: 6px;
  -webkit-overflow-scrolling: touch;
}
/* 전체화면에서는 상자 높이 제한을 풀고 화면 끝까지 흐르게 둔다 */
.rawfs-body .raw-text { max-height: none; overflow: visible; }

/* --------------------------------------------------- 적용하는 동안 막기
 *
 * 원문 전체화면(.rawfs, z-index 60)보다 위에 와야 한다 — 원문을 보는 중에
 * 설정이 적용되는 경우가 실제로 문제였다. */
.blockwrap {
  position: fixed; inset: 0; z-index: 90;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: color-mix(in srgb, #000 62%, transparent);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.block-card {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  max-width: 320px; width: 100%;
  padding: 22px 20px; border-radius: 14px; text-align: center;
  background: var(--panel, #161b24); border: 1px solid var(--st-line);
  box-shadow: 0 10px 40px rgba(0, 0, 0, .45);
}
.block-spin {
  width: 26px; height: 26px; border-radius: 50%;
  border: 3px solid var(--st-line);
  border-top-color: var(--st-accent);
  animation: block-turn .8s linear infinite;
}
@keyframes block-turn { to { transform: rotate(360deg); } }
/* 움직임을 싫어하는 설정이면 돌리지 않는다 */
@media (prefers-reduced-motion: reduce) {
  .block-spin { animation: none; border-top-color: var(--st-accent); }
}
.block-msg { font-size: 14px; font-weight: 800; color: var(--st-fg); }
.block-sub {
  font-size: 12px; line-height: 1.5; color: var(--st-muted);
  word-break: keep-all;
}
.blockwrap > .block-card > .block-out {
  margin-top: 4px; width: auto; min-width: 0; min-height: 34px;
  padding: 0 14px; border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: 700;
  color: var(--st-muted); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.blockwrap > .block-card > .block-out[hidden] { display: none; }

/* ---------------------------------------------- 전체화면 글자 크기 6단계
 *
 * 크기는 **여기 한 곳**에서만 정한다. 안엣것(.raw-text, 마크다운, 머리말)은
 * 전부 em 이나 inherit 로 따라오게 두었다. 그래야 +를 누를 때 본문만 커지고
 * 표·코드·머리말은 그대로인 어긋난 화면이 되지 않는다.
 *
 * 다시 그리지 않고 이 값만 갈아 끼우므로 보고 있던 자리를 잃지 않는다.
 *
 * 기본은 z2 (status.js 의 RAWFS_Z_DEFAULT). 단계 수를 고치면 그쪽 상수도
 * 함께 고쳐야 한다. */
/* 글자 크기 단계. 원문이 보이는 자리는 어디든 같은 자를 쓴다 —
   원문 상자(.raw-body)와 전체화면(.rawfs-body)이 한 값을 나눠 쓴다.
   상자 쪽은 모달 안이라 한 단계 작게 잡는다(같은 12px 이 좁은 칸에서는
   더 크게 읽힌다). */
.rawfs-body { font-size: 14.5px; line-height: 1.6; }
.rawfs-body[data-z="0"] { font-size: 11.5px; line-height: 1.5; }
.rawfs-body[data-z="1"] { font-size: 13px;   line-height: 1.55; }
.rawfs-body[data-z="2"] { font-size: 14.5px; line-height: 1.6; }
.rawfs-body[data-z="3"] { font-size: 16.5px; line-height: 1.64; }
.rawfs-body[data-z="4"] { font-size: 18.5px; line-height: 1.68; }
.rawfs-body[data-z="5"] { font-size: 21px;   line-height: 1.72; }

.raw-body[data-z="0"] { font-size: 10.5px; line-height: 1.5; }
.raw-body[data-z="1"] { font-size: 11.5px; line-height: 1.55; }
.raw-body[data-z="2"] { font-size: 13px;   line-height: 1.6; }
.raw-body[data-z="3"] { font-size: 15px;   line-height: 1.64; }
.raw-body[data-z="4"] { font-size: 17px;   line-height: 1.68; }
.raw-body[data-z="5"] { font-size: 19.5px; line-height: 1.72; }
/* 안엣것은 크기를 스스로 정하지 않는다 — 위에서 내려온 것을 따른다. */
.raw-body[data-z] .raw-text,
.raw-body[data-z] .ex-body { font-size: inherit; line-height: inherit; }
.raw-body[data-z] .raw-cap,
.raw-body[data-z] .ex-who { font-size: .8em; }

.zoomset { display: inline-flex; gap: 4px; flex: none; }
.zoomset[hidden] { display: none; }
/* 원문 상자(모달 안)의 글자 크기 단추. 머리줄이 좁으므로 작게. */
.raw-bar > .zoomset > .raw-zoom {
  min-height: 26px; padding: 0 7px; border-radius: 8px; cursor: pointer;
  font-family: inherit; font-size: 11px; font-weight: 800;
  color: var(--st-muted); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.raw-bar > .zoomset > .raw-zoom:disabled { opacity: .35; }

/* ------------------------------------- 전체화면 원문 아래의 '적어서 보내기'
 * 읽던 자리를 잃지 않고 곧바로 시키려는 자리다. 화면 맨 아래에 붙는다 —
 * 키보드가 올라오면 그 위로 밀려 올라온다. */
.rawfs-say {
  flex: none; display: flex; align-items: flex-end; gap: 8px;
  padding: 10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--st-line);
  background: var(--panel, #161b24);
}
.rawfs-say-in {
  flex: 1 1 auto; min-width: 0; resize: none; overflow-y: auto;
  min-height: 40px; padding: 9px 11px; border-radius: 10px;
  font-family: inherit; font-size: 14px; line-height: 1.45;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.rawfs-say-in::placeholder { color: var(--st-muted); }
.rawfs-say-in:focus { outline: none; border-color: var(--st-accent); }
.rawfs-say-btns { flex: none; display: flex; gap: 6px; }
.rawfs-say-btns > button {
  width: 44px; min-height: 40px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  border-radius: 10px; color: var(--st-fg);
  background: var(--st-card); border: 1px solid var(--st-line);
  touch-action: manipulation;
}
.rawfs-say-btns > button > .bd-ico { width: 18px; height: 18px; }
.rawfs-say-btns > .rawfs-say-go {
  color: var(--st-ink); background: var(--st-accent); border-color: var(--st-accent);
}
.rawfs-say-btns > .rawfs-say-now {
  color: var(--warn, #d29922);
  border-color: color-mix(in srgb, var(--warn, #d29922) 55%, transparent);
}
.rawfs-say-btns > .rawfs-say-mic.rec {
  color: #fff; background: var(--rec, #ef4444); border-color: transparent;
}
.rawfs-say-btns > button:disabled { opacity: .5; }

/* 안엣것은 크기를 스스로 정하지 않는다 — 위에서 내려온 것을 따른다.
 * 머리말은 본문보다 조금 작게, 비율로만 잡는다. */
.rawfs-body .raw-text,
.rawfs-body .ex-body { font-size: inherit; line-height: inherit; }
.rawfs-body .raw-cap,
.rawfs-body .ex-who,
.rawfs-body .ex-cap { font-size: .78em; }
.rawfs-body .raw-none,
.rawfs-body .ex-none { font-size: .84em; }
.rawfs-body .ex-tag { font-size: .72em; }

/* 가− / 가＋ — 두 개가 나란히 붙으므로 좁게. 끝에 닿으면 흐리게. */
.rawfs-bar > .rawfs-zoom {
  padding: 0 9px; font-size: 12.5px; letter-spacing: -.02em;
}
.rawfs-bar > .rawfs-zoom:disabled { opacity: .35; }

/* ------------------------------------------------- 최근 주고받은 것 */
.ex { display: flex; flex-direction: column; gap: 7px; }
.ex-cap {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 11.5px; font-weight: 800; letter-spacing: .03em; color: var(--st-muted);
}
.ex-hint { margin-left: auto; font-weight: 400; }

/* 이 상자 안에서만 스크롤한다. 바깥 화면은 그대로 있어야
   위아래로 오가며 볼 때 자리를 잃지 않는다. */
.ex-list {
  display: flex; flex-direction: column; gap: 12px;
  max-height: 52vh; overflow-y: auto;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  padding: 11px 12px; border-radius: 12px;
  background: var(--st-card); border: 1px solid var(--st-line);
}
.ex-turn {
  display: flex; flex-direction: column; gap: 7px;
  padding-bottom: 11px; border-bottom: 1px dashed var(--st-line);
}
.ex-turn:last-child { padding-bottom: 0; border-bottom: none; }

.ex-who {
  display: flex; align-items: baseline; gap: 7px;
  font-size: 11px; font-weight: 800; color: var(--st-muted);
}
.ex-at { font-weight: 400; }
.ex-tag {
  padding: 1px 6px; border-radius: 999px; font-size: 10px;
  color: var(--st-accent);
  background: color-mix(in srgb, var(--st-accent) 15%, transparent);
}
.ex-me .ex-who span:first-child { color: var(--st-fg); }
.ex-claude .ex-who span:first-child { color: var(--st-accent); }

.ex-body {
  font-size: 12px; line-height: 1.55; color: var(--st-fg);
  word-break: break-word; -webkit-user-select: text; user-select: text;
}
/* 내가 한 말은 왼쪽에 선을 둘러 눈으로 갈라 놓는다 */
.ex-me .ex-body {
  padding-left: 9px; border-left: 2px solid var(--st-line);
}
.ex-claude .ex-body {
  padding-left: 9px;
  border-left: 2px solid color-mix(in srgb, var(--st-accent) 45%, transparent);
}
.ex-none { font-size: 11.5px; color: var(--st-muted); padding-left: 9px; }

.ex > .ex-full {
  align-self: flex-start;
  width: auto; min-width: 0; min-height: 32px;
  padding: 0 12px; border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: 800;
  color: var(--st-muted); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.ex > .ex-full:active { transform: translateY(1px); }

@media (max-width: 480px) {
  .ex-list { max-height: 46vh; }
  .ex-body { font-size: 11.5px; }
}

/* ------------------------------------------- 프로젝트별 모델 / 노력 */
.mp {
  display: flex; flex-direction: column; gap: 7px;
  padding: 10px 12px; border-radius: 12px;
  background: var(--st-card); border: 1px solid var(--st-line);
}
.mp-head { display: flex; align-items: baseline; gap: 8px; }
.mp-cap {
  font-size: 11.5px; font-weight: 800; letter-spacing: .03em; color: var(--st-muted);
}
.mp-where {
  margin-left: auto; font-size: 11.5px; font-weight: 700; color: var(--st-accent);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 55%;
}
.mp-row { display: flex; gap: 7px; }
/* 권한은 아래 줄에 혼자 둔다. 모델·노력과 성질이 다르고(잘못 고르면 되돌릴
   수 없다), 이름이 길어서 셋을 한 줄에 넣으면 전부 잘린다. */
.mp-row-perm > select { flex: 1 1 auto; }
.mp .mp-row-perm > select[data-danger="1"] {
  color: var(--warn, #d29922);
  border-color: color-mix(in srgb, var(--warn, #d29922) 55%, transparent);
}
/* '새 채팅' — 고르는 칸이 아니라 누르는 것이므로 폭을 글자에 맞춘다.
   select 는 flex:1 로 늘어나고 이것만 제 크기를 지킨다. */
.mp .mp-row > .mp-new {
  flex: 0 0 auto; width: auto; min-width: 0; min-height: 40px;
  padding: 0 12px; border-radius: 10px; cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 700;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
  white-space: nowrap;
}
.mp .mp-row > .mp-new:active { transform: translateY(1px); }
.mp .mp-row > .mp-new:disabled { opacity: .5; }
.mp .mp-row > select {
  flex: 1 1 0; min-width: 0; min-height: 40px;
  padding: 0 9px; border-radius: 10px;
  font-family: inherit; font-size: 13px; font-weight: 700;
  color: var(--st-fg); background: var(--st-bg, #0f141c);
  border: 1px solid var(--st-line);
}
.mp .mp-row > select:focus { outline: none; border-color: var(--st-accent); }
.mp .mp-row > select:disabled { opacity: .5; }
/* 고른 것을 모아 두었다가 한 번에 보내는 줄. 바꾼 것이 있을 때만 나온다.
   모델과 노력을 같이 고르고 '적용' 한 번이면 창이 한 번만 다시 뜬다. */
.mp-acts {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 7px; flex-wrap: wrap;
}
.mp-acts[hidden] { display: none; }
/* 무엇이 바뀌는지는 한 줄을 통째로 쓴다. 버튼 옆에 끼우면 폰 폭에서 두 줄로
   접히며 버튼을 밀어 올린다. */
.mp-pending {
  flex: 1 1 100%; min-width: 0;
  font-size: 11.5px; font-weight: 700; line-height: 1.4;
  color: var(--st-accent); overflow-wrap: anywhere;
}
.mp .mp-acts > button {
  flex: 0 0 auto; min-height: 36px; padding: 0 14px;
  border-radius: 10px; cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 700;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line); white-space: nowrap;
}
.mp .mp-acts > .mp-apply {
  color: #0b1220; background: var(--st-accent); border-color: var(--st-accent);
}
.mp .mp-acts > button:active { transform: translateY(1px); }
.mp .mp-acts > button:disabled { opacity: .5; }

/* 폴더 경로가 한 줄에 안 들어간다. 넘치게 두면 화면이 옆으로 밀린다. */
.mp-note {
  font-size: 11.5px; line-height: 1.55; color: var(--st-muted);
  white-space: pre-line; overflow-wrap: anywhere;
}

/* ------------------------------------------------------- 사이트 보기 */
.site {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 13px; border-radius: 12px;
  text-decoration: none;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid color-mix(in srgb, var(--st-accent) 40%, var(--st-line));
}
.site:active { transform: translateY(1px); }
.site-host {
  flex: 1; min-width: 0; font-size: 13.5px; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.site .site-go {
  flex: none; font-size: 12px; font-weight: 800; color: var(--st-accent);
  white-space: nowrap;
}

/* 공용 조각들도 글은 고를 수 있게. 누르는 것만 끈다. */
.sum, .sum-text, .sum-list, .ov-raw, .ex-body, .q-note, .q-err,
.md, .raw-plain, .ask-text, .ask-desc, .mp-note, .sug-stage {
  -webkit-user-select: text; user-select: text;
}
.sug .sug-row > .sug-go, .q-row > .q-actions > button,
.pj .pj-row > .pj-ex, .ex > .ex-full, .raw .raw-bar > button {
  -webkit-user-select: none; user-select: none;
}

/* ------------------------------------------------------------- 중지 */
.now-state-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.now-state-row > .now-state { flex: 0 1 auto; }
.now-state-row > .now-stop {
  flex: 0 0 auto; width: auto; min-width: 0; min-height: 34px;
  padding: 0 14px; border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: 12.5px; font-weight: 800;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
}
/* 한 번 더 눌러야 멈춘다는 것을 색으로 알린다 */
.now-state-row > .now-stop.armed {
  color: #fff; background: #b3261e; border-color: #b3261e;
}
.now-state-row > .now-stop:disabled { opacity: .5; }
.now-state-row > .now-stop:active:not(:disabled) { transform: translateY(1px); }

/* ------------------------------------------- 전체 목록 줄의 추천 */
.ov-tips {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-top: 2px; padding-top: 9px;
  border-top: 1px dashed var(--st-line);
}
.ov-row .ov-tips > .ov-tip {
  width: auto; min-width: 0; min-height: 32px;
  max-width: 100%;
  padding: 0 11px; border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: 700;
  color: var(--st-accent);
  background: color-mix(in srgb, var(--st-accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--st-accent) 35%, transparent);
}
.ov-tip-label {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ov-row .ov-tips > .ov-tip:disabled { opacity: .45; }
.ov-row .ov-tips > .ov-tip:active:not(:disabled) { transform: translateY(1px); }

/* 원문 여러 쌍을 담는 상자. 한 세트쯤 보이는 높이. */
.raw-scroll {
  display: flex; flex-direction: column; gap: 6px;
  max-height: 44vh; overflow-y: auto;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  padding: 10px 11px; border-radius: 11px;
  background: color-mix(in srgb, var(--st-fg) 4%, transparent);
  border: 1px solid var(--st-line);
}
/* 상자가 스크롤을 맡으므로 안쪽 조각은 제 키만큼만 차지한다 */
.raw-scroll .raw-text { max-height: none; overflow: visible; border: none;
  background: transparent; padding: 0; }
.raw-scroll .raw-cap { margin-top: 6px; }
.raw-scroll > .raw-cap:first-child { margin-top: 0; }

/* 전체화면에서는 화면 전체가 스크롤한다 — 상자 안에 또 상자를 두지 않는다 */
.rawfs-body .raw-scroll {
  max-height: none; overflow: visible;
  border: none; background: transparent; padding: 0;
}

@media (max-width: 480px) { .raw-scroll { max-height: 40vh; } }

/* ------------------------------------------- 원문 한 세트 (나 / Claude) */
.ex-set {
  display: flex; flex-direction: column; gap: 7px;
  padding-bottom: 14px; margin-bottom: 2px;
  border-bottom: 1px dashed var(--st-line);
}
.ex-set:last-child { padding-bottom: 0; border-bottom: none; }

/* 창이 갈린 자리.
 *
 * 쌍 사이의 점선(.ex-set 의 border-bottom)보다 세야 한다 — 같은 굵기로 두면
 * 그냥 다음 대화로 넘어가는 자리와 구별이 안 된다. 양옆으로 선을 뻗고 가운데
 * 글을 앉힌다. 위아래 여백도 넉넉히 줘서 눈이 한 번 쉬게 한다. */
.ex-newroom {
  display: flex; align-items: center; gap: 10px;
  margin: 18px 0 16px;
  font-size: 11.5px; font-weight: 800; letter-spacing: .08em;
  color: var(--st-muted);
  white-space: nowrap;
}
.ex-newroom::before, .ex-newroom::after {
  content: ''; flex: 1 1 auto; height: 0;
  border-top: 1px dashed var(--st-line);
}

/* 누가 한 말인지 — 색과 크기로 바로 갈린다 */
.raw-scroll .ex-who {
  display: flex; align-items: baseline; gap: 8px;
  font-size: 13px; font-weight: 800; letter-spacing: -.01em;
}
.raw-scroll .ex-who .ex-at {
  font-size: 11px; font-weight: 600; color: var(--st-muted);
}
.raw-scroll .ex-who.me .ex-name { color: var(--st-accent); }
.raw-scroll .ex-who.claude .ex-name { color: #9db4ff; }

/* 내가 한 말 — 초록 테두리로 감싼다 */
.ex-mine {
  display: flex; flex-direction: column; gap: 5px;
  padding: 10px 12px; border-radius: 11px;
  border: 1px solid color-mix(in srgb, var(--st-accent) 45%, transparent);
  background: color-mix(in srgb, var(--st-accent) 7%, transparent);
}

/* 답 끝의 요약 */
.ex-sum {
  display: flex; flex-direction: column; gap: 6px;
  margin-top: 4px; padding: 11px 13px; border-radius: 11px;
  border: 1px solid color-mix(in srgb, var(--st-accent) 45%, transparent);
  background: color-mix(in srgb, var(--st-accent) 7%, transparent);
}
.ex-sum-cap {
  font-size: 11px; font-weight: 800; letter-spacing: .04em;
  color: var(--st-accent);
}
.ex-sum .sum-text, .ex-sum .sum-list li { font-size: 12.5px; }

/* 목록에 없는 모델을 직접 적는 칸 */
.mp > .mp-typed {
  width: 100%; box-sizing: border-box; min-height: 40px;
  padding: 0 12px; border-radius: 10px;
  font-family: inherit; font-size: 13px;
  color: var(--st-fg); background: var(--st-bg, #0f141c);
  border: 1px solid var(--st-accent);
}
.mp > .mp-typed[hidden] { display: none; }
.mp > .mp-typed:focus { outline: none; }

/* ---------------------------------------------------------------- 창 맵
   화면을 그대로 축소한 그림. 인덱스와 패널이 같이 쓴다.
   패널에는 예전부터 같은 규칙이 #map 안에 있었는데, 인덱스에도 넣으면서
   여기로 옮겼다 — 두 곳에 두면 곧 서로 달라진다. */
.wmap { display: flex; flex-direction: column; gap: 12px; }
.wmap .screen-name {
  font-size: 13px; font-weight: 600;
  color: var(--st-muted); margin-bottom: 7px;
}
.wmap .screen-box {
  position: relative; width: 100%;
  background: #0a0d12;
  border: 1px solid var(--st-line);
  border-radius: 8px; overflow: hidden;
}
/* 지도 안의 창 하나. 자리와 크기는 인라인 스타일(%)로 들어온다. */
.wmap .win {
  position: absolute; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  padding: 2px; text-align: center;
  font-size: 12px; font-weight: 700; line-height: 1.2;
  color: var(--st-fg);
  background: color-mix(in srgb, var(--st-accent) 20%, transparent);
  border: 1px solid var(--st-accent);
  border-radius: 4px; cursor: pointer;
  /* 인덱스에는 '.panel button { width:100% }' 같은 포괄 규칙이 있다.
     그것이 이기면 창이 전부 가로 꽉 차서 지도가 뭉개진다. */
  min-height: 0; margin: 0;
}
.wmap .win.fg {
  background: rgba(63, 185, 80, .22);
  border-color: var(--st-ok);
}
.wmap .win.min { opacity: .4; border-style: dashed; }
.wmap .win:active { background: var(--st-accent); color: var(--st-ink); }
.wmap .win.working {
  border-color: var(--st-accent);
  box-shadow: inset 0 0 0 1px var(--st-accent);
}

/* 자동 배치 칸들. 좁은 화면에서는 한 줄에 하나. */
.win-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 12px; }
.win-grid label {
  display: flex; flex-direction: column; gap: 6px;
  font-size: 13px; color: var(--st-muted);
}
.win-grid select { width: 100%; }
@media (max-width: 420px) { .win-grid { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------ 받아쓰기
 *
 * 음성 파일을 얹는 자리와 보관된 글 목록. 인덱스와 패널이 같은 것을 쓴다.
 *
 * 끌어다 놓는 자리는 **끌어오기 전에도 보여야** 한다. 파일을 쥔 채로만
 * 나타나는 자리는 그런 기능이 있는 줄을 모른다. 그래서 늘 점선으로 두고,
 * 파일이 화면에 들어오면(.over) 색을 올린다.
 */
#tr-drop {
  display: flex; flex-direction: column; gap: 4px; align-items: center;
  padding: 22px 14px; margin-bottom: 12px;
  text-align: center; cursor: pointer;
  border: 2px dashed var(--st-line); border-radius: 12px;
  background: var(--st-card);
  color: var(--st-muted);
  transition: border-color .12s, background .12s;
}
#tr-drop b { color: var(--st-fg); font-size: 15px; }
#tr-drop span { font-size: 12px; line-height: 1.5; }
#tr-drop.over {
  border-color: var(--st-accent);
  background: color-mix(in srgb, var(--st-accent) 14%, var(--st-card));
}
/* 받아쓰는 동안. 누르면 또 올릴 것 같지 않게 흐려 둔다. */
#tr-drop.busy { opacity: .55; cursor: progress; border-style: solid; }
/* 폰 화면에서는 바깥(#stt-body)이 이미 12px 씩 띄운다. 여기 margin 을 그대로
   두면 상자와 목록 사이만 두 배로 벌어진다. */
#stt-body #tr-drop { margin-bottom: 0; }

.tr-row {
  padding: 10px 12px; margin-bottom: 8px;
  border: 1px solid var(--st-line); border-radius: 10px;
  background: var(--st-card);
}
.tr-head { display: flex; align-items: baseline; gap: 8px; }
.tr-title {
  flex: 1; min-width: 0; font-weight: 700; color: var(--st-fg);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tr-when { flex: none; font-size: 12px; color: var(--st-muted); }
.tr-meta { margin-top: 2px; font-size: 12px; color: var(--st-muted); }

/* 맛보기는 두 줄까지만. 전문은 눌러서 펼친다(.all) — 한 시간짜리 녹음이
   통째로 펼쳐져 있으면 다음 건을 찾을 수 없다. */
.tr-text {
  margin-top: 6px; font-size: 13px; line-height: 1.6; color: var(--st-fg);
  white-space: pre-wrap; word-break: break-word;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.tr-text.all {
  display: block; max-height: 40vh; overflow-y: auto;
  padding: 8px; margin-top: 8px;
  border: 1px solid var(--st-line); border-radius: 8px;
  -webkit-user-select: text; user-select: text;
}

.tr-acts { display: flex; gap: 8px; margin-top: 8px; }
/* 인덱스의 '.panel button' 은 세로 60px 짜리 초록 덩어리다(녹음 화면의 큰
   버튼을 위한 것). 한 줄에 셋이 서는 자리에 그대로 오면 목록이 버튼밭이 되고
   무엇이 중요한지 사라진다. 그래서 크기와 색을 여기서 다시 정한다.
   명시도를 id/속성까지 올려야 그쪽을 이긴다. */
#sttbox .tr-acts button, .tab[data-panel="stt"] .tr-acts button {
  flex: 1; min-width: 0; width: auto; margin: 0;
  min-height: 38px; padding: 0 12px; border-radius: 9px;
  font-family: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
  color: var(--st-fg); background: transparent;
  border: 1px solid var(--st-line);
}
/* 눌러야 할 것 하나만 채운다 — 여기 온 이유가 '전문 복사' 라서다. */
#sttbox .tr-acts button.primary, .tab[data-panel="stt"] .tr-acts button.primary {
  color: var(--st-ink); background: var(--st-accent); border-color: var(--st-accent);
}
#sttbox .tr-acts button:disabled, .tab[data-panel="stt"] .tr-acts button:disabled {
  opacity: .45;
}
/* 삭제는 좁게. 되돌릴 수 없는 것이 '전문 복사' 와 같은 크기로 나란히 서면
   잘못 누른다. 위의 포괄 규칙(#sttbox .tr-acts button)이 flex:1 로 이겨서
   셋이 같은 너비로 나왔던 자리다 — 같은 명시도로 맞춰 두어야 진다. */
#sttbox .tr-acts .danger, .tab[data-panel="stt"] .tr-acts .danger {
  flex: 0 0 auto; width: auto;
  color: var(--st-muted); background: transparent;
  border: 1px solid var(--st-line);
}

/* ---------------------------------------------------------------- 보드
 *
 * 프로젝트를 기둥으로 세우고, 그 안에 최근 몇 걸음을 위에서 아래로 쌓는다.
 * 인덱스와 패널이 같은 것을 쓴다.
 *
 * 글자는 일부러 작다. 여기서 읽는 것이 아니라 훑는 것이라, 한 화면에 몇 개가
 * 들어오느냐가 글자 크기보다 중요하다. 자세히 볼 것은 눌러서 들어간다.
 */
/* 판이 제 상자를 넘지 못하게 한다.
 *
 * 높이는 밖(상자)에서 정하고 안(무대)이 그것을 나눠 갖는다. 반대로 무대가
 * 제 높이를 우기면, 세로 flex 안에서 상자만 눌리고 무대는 그대로 남아 아래
 * 목록 위로 흘러넘친다 — 폰에서 상자 230px 에 무대 320px 이었다. 바닥이
 * 비치는 판이라 목록이 판 안에 겹쳐 보였다.
 */
/* 높이는 **바깥 상자**가 정하고 판은 그것을 100% 로 받는다.
 *
 * 쓰는 쪽이 `#now-board > .bd { height: 66vh }` 처럼 ID 를 끼워 판에 직접
 * 높이를 주면, 화면 가득(.bd-full)이 그것을 이길 수 없다 — ID 하나가 클래스
 * 셋보다 세다. 실제로 1280×860 화면에서 1280×602 까지만 덮였다. 판에는 아무도
 * 높이를 못 박지 않기로 하고, 상자에만 준다. */
/* 폭도 마찬가지다. 판은 overflow:hidden 이라 제 안엣것으로는 폭이 정해지지
   않는다 — 상자가 flex 면 2px 까지 쪼그라들어 아무것도 안 보였다. */
.bd {
  position: relative; display: flex; flex-direction: column;
  width: 100%; height: 100%; min-height: 320px; overflow: hidden;
}

/* 종이를 올려 둔 판. 여기서 손짓을 받는다.
   touch-action:none 이 있어야 두 손가락 확대가 브라우저 확대로 새지 않고,
   한 손가락 밀기가 페이지 스크롤로 가로채이지 않는다.
   바닥색을 반드시 깐다. 점무늬만 두면 뒤가 그대로 비쳐 두 화면이 포개진
   것처럼 보인다. */
.bd-stage {
  position: relative; flex: 1 1 auto; min-height: 0;
  overflow: hidden; touch-action: none; cursor: grab;
  border: 1px solid var(--st-line); border-radius: 12px;
  background-color: var(--st-bg);
  background-image:
    radial-gradient(circle at 1px 1px,
      color-mix(in srgb, var(--st-line) 90%, transparent) 1px, transparent 0);
  background-size: 22px 22px;
  background-position: 0 0;
  -webkit-user-select: none; user-select: none;
}
.bd.dragging .bd-stage { cursor: grabbing; }

/* 화면 가득. 상자 안에서는 기둥 하나도 다 안 들어오는 화면이 있다.
   바탕을 불투명하게 깔아 뒤가 비치지 않게 한다. */
/* 쓰는 쪽이 못박아 둔 높이(패널 66vh, 확인용 70vh)를 여기서 풀어야 한다.
   height 가 남아 있으면 inset:0 의 아래쪽이 지고 화면 중간까지만 덮는다 —
   1280×860 화면에서 1280×602 로 나왔던 자리다. */
.bd.bd-full {
  position: fixed; inset: 0; z-index: 60;
  width: auto; height: auto;
  min-width: 0; min-height: 0; max-height: none;
  padding: 0; margin: 0;
  background: var(--st-bg);
}
.bd.bd-full > .bd-stage { border: none; border-radius: 0; }
body.bd-locked { overflow: hidden; }

/* 눕힌 판.
 *
 * 가로세로를 바꿔 잡고(100dvh × 100dvw) 한가운데를 축으로 90도 돌린다. 세로로
 * 든 폰에서 화면을 가로로 쓰는 유일한 길이다 — 브라우저에 방향을 돌려 달라고
 * 하는 것은 iOS 에서 안 된다.
 *
 * 자리는 inset 이 아니라 top/left 50% + translate(-50%,-50%) 로 잡는다.
 * inset:0 은 폭·높이를 화면에 맞춰 버려서 바꿔 잡은 값이 죽는다. 축이 정확히
 * 한가운데여야 손짓 좌표를 되돌리는 셈(status.js 의 inside)이 맞는다. */
.bd.bd-full.bd-turn {
  inset: auto; top: 50%; left: 50%;
  width: 100dvh; height: 100dvw;
  transform: translate(-50%, -50%) rotate(90deg);
  transform-origin: 50% 50%;
}

/* 실제로 움직이는 것. 왼쪽 위를 기준으로 키워야 셈이 맞는다. */
.bd-sheet {
  position: absolute; top: 0; left: 0;
  display: flex; align-items: flex-start; gap: 10px;
  transform-origin: 0 0; will-change: transform;
}

.bd-col {
  flex: 0 0 auto; width: 250px;
  display: flex; flex-direction: column; gap: 6px;
  padding: 8px; border-radius: 12px;
  background: color-mix(in srgb, var(--st-card) 70%, transparent);
  border: 1px solid var(--st-line);
}

/* 기둥 머리 = 프로젝트. 누르면 그 프로젝트로 들어간다. */
.bd .bd-col > .bd-col-head {
  display: flex; align-items: center; gap: 6px;
  width: 100%; min-height: 0; margin: 0; padding: 6px 8px;
  border-radius: 9px; cursor: pointer; text-align: left;
  font-family: inherit; font-size: 12.5px; font-weight: 800;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.bd .bd-col > .bd-col-head:active { transform: translateY(1px); }
.bd-col-head > .led {
  flex: none; width: 7px; height: 7px; border-radius: 50%;
  background: var(--st-muted);
}
.bd-col-head > .led.idle { background: var(--st-ok); }
.bd-col-head > .led.busy { background: var(--st-busy); animation: st-pulse 1s infinite; }
.bd-name {
  flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.bd-age { flex: none; font-size: 10.5px; font-weight: 600; color: var(--st-muted); }

/* 한 걸음 = 물음 한 문단 + 답 한 문단. 누르면 원문이 뜬다. */
.bd .bd-step {
  display: block; width: 100%; margin: 0;
  padding: 7px 9px; border-radius: 9px; text-align: left; cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: 400;
  color: var(--st-fg);
  background: var(--st-card); border: 1px solid var(--st-line);
  min-height: 0;
}
.bd .bd-step.waiting { border-color: color-mix(in srgb, var(--st-accent) 55%, transparent); }
.bd .bd-step:active { transform: translateY(1px); }
/* 누를 수 있다는 것이 보여야 한다. 마우스에서만 — 손가락에는 hover 가 없다. */
@media (hover: hover) {
  .bd .bd-step:hover {
    border-color: color-mix(in srgb, var(--st-accent) 60%, var(--st-line));
  }
}

/* ------------------------------------------------------- 손으로 붙인 표시
 *
 * 별표 = 나중에 다시 볼 것. 노란 테두리로 멀리서도 찾아진다.
 *
 * 노랑을 고른 이유가 있다. 이 판에서 초록은 '기다리는 중', 파랑은 '일하는 중',
 * 빨강은 '방금 끝남' 으로 이미 뜻이 박혀 있다. 상태가 아니라 **사람이 붙인
 * 것**이라 그 셋과 섞이지 않는 색이어야 한다.
 *
 * 판을 확 줄여 놓으면 글자는 안 보이고 테두리만 남는다. 그래서 테두리를 두껍게
 * 하고 바깥으로 빛을 한 겹 두른다 — 줄여 놓고 별표만 찾는 것이 이 표시의 쓰임이다.
 */
.bd .bd-step.star {
  border-color: var(--st-star);
  border-width: 2px; padding: 6px 8px;      /* 테두리가 굵어진 만큼 안쪽을 줄인다 */
  background: color-mix(in srgb, var(--st-star) 9%, var(--st-card));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--st-star) 22%, transparent);
}
/* 하는 중이어도 별표가 이긴다 — 상태는 점(led)에도 있지만 별표는 여기뿐이다. */
.bd .bd-step.star.waiting { border-color: var(--st-star); }

/* 별표 단추. 손가락으로 누르는 것이라 넉넉해야 한다 — 22px 로 두었더니
   너무 작아 눌리지 않았다. 카드 머리줄 높이를 넘지 않는 선에서 최대한 키우고,
   보이는 것보다 넓게 눌리도록 바깥으로 여백을 뺀다(-6px). */
.bd .bd-star {
  flex: none; width: 34px; height: 34px; min-height: 0;
  margin: -6px -6px -6px 0; padding: 0;
  border-radius: 8px; cursor: pointer; line-height: 1;
  font-family: inherit; font-size: 19px;
  color: color-mix(in srgb, var(--st-muted) 55%, transparent);
  background: transparent; border: none;
  touch-action: manipulation;
}
.bd .bd-star[aria-pressed="true"] {
  color: var(--st-star);
  text-shadow: 0 0 10px color-mix(in srgb, var(--st-star) 60%, transparent);
}
.bd .bd-star:active { transform: scale(.86); }

/* 기둥 맨 아래의 '작업 일단락' — 프로젝트마다 하나.
   켜졌는지가 한눈에 보여야 하므로 눌린 채로 남는다. */
.bd .bd-done {
  display: block; width: 100%; margin: 2px 0 0; padding: 0 10px;
  min-height: 40px; border-radius: 9px; cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: 800;
  color: var(--st-muted);
  background: color-mix(in srgb, var(--st-card) 70%, transparent);
  border: 1px dashed var(--st-line);
  touch-action: manipulation;
}
.bd .bd-done[aria-pressed="true"] {
  color: var(--st-muted);
  background: transparent;
  border-style: solid;
  border-color: color-mix(in srgb, var(--st-muted) 45%, transparent);
}
.bd .bd-done:active { transform: translateY(1px); }

/* 지금 이 프로젝트가 무슨 상태인지 — 적는 칸 바로 위.
   기둥 머리에도 같은 것이 있지만, 밀어 내려 읽다 보면 머리는 화면 밖이다.
   불빛 색은 머리(.bd-col-head > .led)와 똑같이 맞춘다. */
.bd .bd-where-now {
  display: flex; align-items: center; gap: 6px; margin-top: 4px;
  padding: 4px 8px; border-radius: 8px;
  font-size: 11px; color: var(--st-muted);
  background: color-mix(in srgb, var(--st-card) 55%, transparent);
  border: 1px solid var(--st-line);
}
.bd .bd-where-now > .led {
  width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--st-muted);
}
.bd .bd-where-now.idle > .led { background: var(--st-ok); }
.bd .bd-where-now.busy > .led { background: var(--st-busy); animation: st-pulse 1s infinite; }
.bd .bd-where-now > b { font-weight: 800; color: var(--st-fg); }
/* 작업 중은 눈에 걸려야 한다 — 지금 시키면 줄을 서게 되는 상태다. */
.bd .bd-where-now.busy {
  color: var(--st-busy);
  border-color: color-mix(in srgb, var(--st-busy) 45%, transparent);
}
.bd .bd-where-now.busy > b { color: var(--st-busy); }
.bd .bd-where-now.idle > b { color: var(--st-ok); }
.bd-where-ago { margin-left: auto; flex: none; }

/* 기둥 끝의 '한마디 시키기'. 250px 기둥이라 칸과 단추를 한 줄에 나란히 두면
   둘 다 좁다 — 적는 칸이 한 줄을 다 쓰고 단추가 그 아래에 선다. */
.bd .bd-say { display: flex; flex-direction: column; gap: 4px; margin-top: 4px; }
/* 여러 줄을 적는 칸(textarea)이다. 한 줄일 때는 예전 높이 그대로 보이고,
   줄이 늘면 자란다(높이는 JS 가 scrollHeight 로 맞춘다 — 110px 에서 멈춘다).
   input 이던 때의 `padding: 0 9px` 를 그대로 두면 글이 위에 딱 붙는다. */
.bd .bd-say-in {
  width: 100%; min-width: 0; min-height: 34px;
  padding: 7px 9px; resize: none; overflow-y: auto;
  border-radius: 9px; font-family: inherit; font-size: 12px; line-height: 1.4;
  color: var(--st-fg); background: var(--st-bg, #0f141c);
  border: 1px solid var(--st-line);
}
.bd .bd-say-in::placeholder { color: var(--st-muted); }
.bd .bd-say-in:focus { outline: none; border-color: var(--st-accent); }
/* 적은 것이 없으면 조용히 있는다. 기둥마다 하나씩 서는 단추라, 늘 강조색이면
   판이 초록 줄로 뒤덮여 정작 봐야 할 카드와 별표가 뒤로 밀린다. */
/* 눕힌 판에서 적을 때 뜨는 쪽지.
 *
 * 판(.bd-full, z-index 60) **밖**에 붙는다 — 판 안에 두면 그것까지 같이
 * 90도 누워서, 세로로 올라오는 키보드와 다시 어긋난다. 그래서 여기 좌표는
 * 판이 아니라 화면을 따른다.
 *
 * 위쪽에 붙인다. 키보드는 아래에서 올라오므로 적는 칸이 가려지지 않는다. */
.bd-compose {
  position: fixed; inset: 0; z-index: 70;
  display: flex; align-items: flex-start; justify-content: center;
  padding: calc(12px + env(safe-area-inset-top, 0px)) 12px 12px;
  background: color-mix(in srgb, var(--st-bg) 72%, transparent);
  backdrop-filter: blur(3px);
}
.bd-compose-card {
  width: 100%; max-width: 520px;
  display: flex; flex-direction: column; gap: 8px;
  padding: 12px; border-radius: 14px;
  background: var(--st-bg); border: 1px solid var(--st-line);
  box-shadow: 0 18px 50px rgba(0, 0, 0, .55);
}
.bd-compose-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; font-weight: 800; color: var(--st-accent);
}
.bd-compose-head > b { flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bd-compose-x {
  flex: none; width: 32px; height: 32px; min-height: 0; margin: 0; padding: 0;
  border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: 14px; font-weight: 700;
  color: var(--st-muted); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.bd-compose-in {
  width: 100%; min-width: 0; resize: none;
  padding: 10px; border-radius: 10px;
  font-family: inherit; font-size: 15px; line-height: 1.5;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
}
.bd-compose-in:focus { outline: none; border-color: var(--st-accent); }
.bd-compose-btns { display: flex; gap: 8px; }
.bd-compose-btns > button {
  flex: 1 1 0; min-width: 0; min-height: 42px; padding: 0 12px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  border-radius: 10px; font-family: inherit; font-size: 14px; font-weight: 800;
  color: var(--st-fg); background: var(--st-card);
  border: 1px solid var(--st-line);
  touch-action: manipulation;
}
/* 쪽지는 넓다 — 모양도 그만큼 크게 둔다. */
.bd-compose-btns > button > .bd-ico { width: 20px; height: 20px; }
.bd-compose-btns > .bd-compose-go {
  color: var(--st-ink); background: var(--st-accent); border-color: var(--st-accent);
}
/* '바로 보내기' — 순차 전송을 건너뛴다. 평소 길이 아니므로 강조색을 주지
   않는다. 테두리만 도드라지게 해서 '있는 줄은 알되 먼저 손이 가지는 않게'. */
.bd-compose-btns > .bd-compose-now {
  color: var(--warn, #d29922);
  border-color: color-mix(in srgb, var(--warn, #d29922) 55%, transparent);
}
.bd-compose-btns > .bd-compose-mic.rec {
  color: #fff; background: var(--rec, #ef4444); border-color: transparent;
}

/* ------------------------------------------- 지금 녹음 중이라는 띠
 * 쪽지·전체화면은 본 화면을 덮는다. 거기 있던 초 세기와 소리 막대가 뒤로
 * 숨어서, 남는 신호가 작은 단추 색 하나뿐이었다 (status.js 의 micLive).
 *
 * `[hidden]` 을 이기지 않도록 :not([hidden]) 을 붙인다. 이 파일에는 포괄
 * 규칙이 여럿이라 개별 규칙이 지는 일이 반복됐다. */
.mic-live:not([hidden]) {
  display: flex; align-items: center; gap: 8px;
  margin: 8px 0 0;
  padding: 6px 10px;
  border-radius: 9px;
  border: 1px solid color-mix(in srgb, var(--rec, #ef4444) 45%, transparent);
  background: color-mix(in srgb, var(--rec, #ef4444) 12%, transparent);
  font-size: 12px; font-weight: 800; white-space: nowrap;
}
/* 깜빡이는 점 — 멈춘 화면과 도는 화면을 가르는 가장 빠른 신호다. */
.mic-live-dot {
  width: 9px; height: 9px; flex: none; border-radius: 50%;
  background: var(--rec, #ef4444);
  animation: mic-live-beat 1s infinite;
}
@keyframes mic-live-beat { 50% { opacity: .25; } }
.mic-live-cap { color: var(--rec, #ef4444); }
/* 초는 폭이 흔들리면 옆엣것이 따라 움직인다. 숫자 폭을 고정한다. */
.mic-live-sec {
  color: var(--st-fg); font-variant-numeric: tabular-nums;
  min-width: 44px;
}
/* 소리 크기 — '내 말이 들어가고 있나' 에 답하는 것은 이것뿐이다.
   초만 흘러가고 이것이 죽어 있으면 마이크가 안 잡히는 것이다. */
.mic-live-lane {
  flex: 1 1 auto; min-width: 24px; height: 5px;
  border-radius: 3px; overflow: hidden;
  background: color-mix(in srgb, var(--st-fg) 14%, transparent);
}
.mic-live-fill {
  display: block; height: 100%; width: 0;
  background: var(--rec, #ef4444);
  transition: width .08s linear;
}
.mic-live-hint { color: var(--st-muted); font-weight: 700; }
/* 좁은 폰에서는 안내 글을 접는다 — 점·초·막대가 먼저다. */
@media (max-width: 420px) {
  .mic-live-hint { display: none; }
}
.bd-compose-btns > button:disabled { opacity: .5; }

/* ------------------------------------------------------------- 아이콘
 * 글자 대신 모양. 색은 단추의 글자색을 따른다(currentColor)므로, 단추가
 * 강조색이 되면 그림도 함께 간다 — 색을 따로 적을 자리가 없다. */
.bd-ico { width: 16px; height: 16px; display: block; flex: none; }
/* 녹음 중에는 마이크가 '멈춤' 으로 바뀐다. 두 그림을 넣어 두고 갈아 끼운다 —
   CSS 로는 그림을 그릴 수 없으니 미리 넣고 감추는 편이 확실하다. */
.bd-ico-stop { display: none; }
button.rec > .bd-ico-mic { display: none; }
button.rec > .bd-ico-stop { display: block; }
/* 보내는 중. 글자를 갈아 끼울 수 없으니(그림이 지워진다) 깜빡임으로 알린다. */
@keyframes bd-sending { 50% { opacity: .35; } }
button.sending > .bd-ico { animation: bd-sending .8s infinite; }

/* 말하기 · 보내기는 한 줄에 나란히. 250px 기둥이라 둘까지가 한계다. */
.bd .bd-say-btns { display: flex; gap: 4px; }
.bd .bd-say-btns > button {
  flex: 1 1 0; min-width: 0; min-height: 32px; padding: 0 8px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  border-radius: 9px; font-family: inherit; font-size: 12px; font-weight: 800;
  white-space: nowrap;
  color: var(--st-muted);
  background: color-mix(in srgb, var(--st-card) 70%, transparent);
  border: 1px solid var(--st-line);
  touch-action: manipulation;
}
.bd .bd-say.ready > .bd-say-btns > .bd-say-go {
  color: var(--st-ink); background: var(--st-accent); border-color: var(--st-accent);
}
/* 녹음 중 — app.js·panel.js 의 askMic 이 이 표시를 붙인다. */
.bd .bd-say-btns > .bd-say-mic.rec {
  color: #fff; background: var(--rec, #ef4444); border-color: transparent;
}
.bd .bd-say-btns > button:active { transform: translateY(1px); }
.bd .bd-say-in:disabled, .bd .bd-say-btns > button:disabled { opacity: .5; }

/* 일단락한 기둥은 반대로 **물러난다.**
 *
 * 노랑은 별표의 색이다 — '자세히 들여다볼 것' 을 골라내는 표시. 끝났다는
 * 표시가 같은 색으로 빛나면 그 구분이 무너진다(실제로 그랬다). 끝난 것은
 * 흐려져서 훑는 눈이 자연스럽게 건너뛰고, 그만큼 별표가 더 도드라진다.
 *
 * 단추만은 또렷이 남긴다 — 되돌리는 자리인데 같이 흐려지면 못 찾는다. */
.bd .bd-col.done > :not(.bd-done) { opacity: .4; }
.bd .bd-col.done { border-style: dashed; }
/* 흐려진 기둥 안에서도 별표는 빛나야 한다 — 끝난 일 속의 '다시 볼 것' 이다. */
.bd .bd-col.done > .bd-step.star { opacity: .85; }
.bd-step-head { display: flex; align-items: center; gap: 6px; margin-bottom: 3px; }
.bd-no {
  flex: none; min-width: 15px; height: 15px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 9.5px; font-weight: 800;
  color: var(--st-muted); background: color-mix(in srgb, var(--st-line) 60%, transparent);
}
.bd-at { flex: 1; font-size: 10px; color: var(--st-muted); }
.bd-doing {
  flex: none; padding: 1px 6px; border-radius: 999px;
  font-size: 9.5px; font-weight: 800; color: var(--st-accent);
  background: color-mix(in srgb, var(--st-accent) 16%, transparent);
}
/* 중간에 끊긴 것. '하는 중' 과 같은 자리에 서지만 색이 달라야 한다 —
   같은 색이면 훑는 눈이 둘을 구별하지 못해서, 끊어 놓은 것까지 살아 있는
   것으로 읽힌다(그 착각이 바로 이 표시를 만든 이유다). */
.bd-stopped {
  flex: none; padding: 1px 6px; border-radius: 999px;
  font-size: 9.5px; font-weight: 800; color: var(--st-muted);
  background: color-mix(in srgb, var(--st-muted) 16%, transparent);
}
/* 아직 안 나간 것. '하는 중'(강조색)과도 '중지됨'(회색)과도 달라야 한다 —
   셋이 같은 자리에 서므로 색으로 갈린다. 기다리는 것은 노랑 계열. */
.bd-queued {
  flex: none; padding: 1px 6px; border-radius: 999px;
  font-size: 9.5px; font-weight: 800; color: var(--warn, #d29922);
  background: color-mix(in srgb, var(--warn, #d29922) 16%, transparent);
}
/* 대기 중인 카드는 기록이 아니다. 테두리를 점선으로 두어 '아직 일어나지
   않은 것' 임을 한눈에 가른다(눌러도 열 원문이 없다). */
.bd .bd-step.queued {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--warn, #d29922) 45%, transparent);
  cursor: default;
}

/* 물음이 또렷하고 답이 흐리다. 훑을 때 눈이 물음을 따라 내려가야
   '무엇을 시켰나' 가 먼저 읽힌다. */
.bd-asked {
  font-size: 11.5px; line-height: 1.45; font-weight: 700; color: var(--st-fg);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; word-break: break-word;
}
.bd-did {
  margin-top: 3px;
  font-size: 11px; line-height: 1.45; color: var(--st-muted);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; word-break: break-word;
}
/* 아직 요약 전이라 원문 앞머리를 쓴 자리. 같은 글로 보이면 안 된다. */
.bd-did.raw { font-style: italic; opacity: .75; }
.bd-next {
  margin-top: 3px; font-size: 10.5px; font-weight: 700; color: var(--st-accent);
  display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical;
  overflow: hidden;
}
.bd-empty { padding: 10px 8px; font-size: 11px; color: var(--st-muted); }

/* ---------------------------------------------------------- 지금 어디인가
 *
 * 넓은 판 위에서는 몇 번만 밀어도 어디에 있는지 모르게 된다. 폰은 더하다 —
 * 한 번에 기둥 하나밖에 안 보여서 앞뒤가 없다. 그래서 늘 두 가지를 띄운다.
 *   왼쪽 위 이름표 : 지금 한가운데 있는 프로젝트 (몇 번째인지까지)
 *   오른쪽 위 지도 : 전체 중 지금 보는 자리 (눌러서 건너뛴다)
 */
/* 이름표는 아래쪽 왼편에 둔다. 위에 두면 기둥 머리(프로젝트 이름)와 겹쳐
   같은 이름이 두 번 보인다. */
.bd-where {
  position: absolute; left: 10px; bottom: 10px; z-index: 3;
  display: flex; align-items: center; gap: 6px;
  max-width: calc(100% - 200px);
  padding: 5px 9px; border-radius: 999px;
  font-size: 11.5px; font-weight: 800; color: var(--st-fg);
  background: color-mix(in srgb, var(--st-card) 92%, transparent);
  border: 1px solid var(--st-line);
  pointer-events: none;
}
.bd-where > b {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bd-where-no { flex: none; font-weight: 700; color: var(--st-muted); }

.bd-map {
  position: absolute; right: 10px; top: 10px; z-index: 3;
  /* 지금 보는 네모가 판보다 클 때가 있다(다 들어오는 배율). 넘치는 만큼은
     잘라 낸다 — 지도 밖으로 테두리가 삐져나오면 지도로 안 읽힌다. */
  overflow: hidden;
  border-radius: 6px; touch-action: none; cursor: pointer;
  background: color-mix(in srgb, var(--st-card) 92%, transparent);
  border: 1px solid var(--st-line);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .35);
}
/* 기둥 하나 = 막대 하나. 색은 보드의 점과 같은 뜻이다. */
.bd-map-col {
  position: absolute; border-radius: 2px;
  background: color-mix(in srgb, var(--st-muted) 45%, transparent);
}
.bd-map-col.idle { background: color-mix(in srgb, var(--st-ok) 55%, transparent); }
.bd-map-col.busy { background: color-mix(in srgb, var(--st-busy) 70%, transparent); }
.bd-map-col.dim  { opacity: .3; }
.bd-map-col.on   { background: var(--st-fg); }
/* 지금 보고 있는 네모. 칠하지 않고 테두리만 — 아래 막대를 가리면 안 된다. */
.bd-map-view {
  position: absolute; border-radius: 3px;
  border: 1.5px solid var(--st-accent);
  background: color-mix(in srgb, var(--st-accent) 14%, transparent);
}

/* ------------------------------------------------------- 카드 원문 (모달)
 *
 * 판 안에 겹쳐 띄운다. 판이 눕혀져 있으면 이것도 함께 눕는다 — 바깥(body)에
 * 붙이면 이것만 똑바로 서서 따로 논다.
 *
 * 캔버스를 나가지 않고 원문을 보고 닫는 자리라, 판을 완전히 덮지 않는다.
 * 뒤로 판이 비쳐 보여야 '잠깐 열어 본 것' 으로 읽힌다.
 */
.bd-modal {
  position: absolute; inset: 0; z-index: 10;
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  background: color-mix(in srgb, var(--st-bg) 72%, transparent);
  backdrop-filter: blur(3px);
}
.bd-modal-card {
  display: flex; flex-direction: column;
  width: 100%; max-width: 620px; max-height: 100%;
  border-radius: 14px; overflow: hidden;
  background: var(--st-bg); border: 1px solid var(--st-line);
  box-shadow: 0 18px 50px rgba(0, 0, 0, .55);
}
.bd-modal-bar {
  display: flex; align-items: center; gap: 8px; flex: none;
  padding: 10px 12px;
  background: var(--st-card); border-bottom: 1px solid var(--st-line);
}
.bd-modal-title {
  flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 7px;
  font-size: 12.5px; font-weight: 800; color: var(--st-fg);
}
.bd-modal-title > b {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bd-modal-at { flex: none; font-size: 11px; font-weight: 400; color: var(--st-muted); }
.bd .bd-modal-x {
  flex: none; width: 34px; height: 34px; min-height: 0; margin: 0; padding: 0;
  border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: 15px; font-weight: 700;
  color: var(--st-muted);
  background: var(--st-bg); border: 1px solid var(--st-line);
}
.bd .bd-modal-x:active { color: var(--st-fg); }

/* 글은 여기서만 흐른다. 판은 손짓(touch-action:none)을 다 먹으므로, 읽는
   자리는 판 밖(모달)이어야 손가락으로 넘길 수 있다. */
.bd-modal-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  display: flex; flex-direction: column; gap: 12px;
  padding: 12px;
  touch-action: pan-y;
}
/* 눕힌 판에서는 넘기는 방향이 돌아간다.
 *
 * touch-action 은 **화면 축**으로 읽힌다. 요소가 어떻게 돌아가 있든 pan-y 는
 * '화면 세로로만 밀 수 있다' 는 뜻이다. 그런데 판을 90도 눕혀 놓았으므로 글의
 * 세로축은 화면의 가로축에 누워 있다 — 실제로 잰 것: 판은 화면에서 390×844
 * 인데 본문의 clientHeight 는 305 로 화면 '가로' 와 같다(scrollHeight 2272).
 *
 * 그래서 글을 넘기려면 손가락을 옆으로 밀어야 하는데, pan-y 가 그 방향을
 * 막아 버렸다. **폰에서 원문이 한 글자도 안 넘어가던 이유다.** 마우스 휠은
 * 축을 따지지 않아 데스크톱에서는 멀쩡했고, 그래서 늦게 드러났다.
 *
 * 눕혔을 때만 축을 바꾼다. 눕지 않은 판(가로로 든 폰·데스크톱)은 그대로 pan-y. */
.bd.bd-turn .bd-modal-body { touch-action: pan-x; }
.bd-modal-body > .ex-turn:last-child { padding-bottom: 0; border-bottom: none; }
.bd-modal-nosum { font-size: 11.5px; color: var(--st-muted); }
.bd .bd-modal-again {
  align-self: flex-start;
  width: auto; min-width: 0; min-height: 34px; margin: 0;
  padding: 0 14px; border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: 12.5px; font-weight: 800;
  color: var(--st-fg); background: var(--st-card); border: 1px solid var(--st-line);
}

/* 눕혔을 때도 카드가 화면(=눕힌 판)을 넘지 않게. 가로가 길어졌으니 그만큼
   넓게 쓴다 — 원문은 한 줄이 길수록 읽기 좋다. */
.bd.bd-turn > .bd-modal { padding: 14px 22px; }
.bd.bd-turn > .bd-modal > .bd-modal-card { max-width: 760px; }

/* 눕혔다고 알리는 쪽지. 몇 초 뒤 저절로 사라진다. */
.bd-hint {
  position: absolute; left: 50%; top: 14px; z-index: 4;
  transform: translateX(-50%);
  padding: 7px 14px; border-radius: 999px; white-space: nowrap;
  font-size: 12.5px; font-weight: 800; color: var(--st-fg);
  background: color-mix(in srgb, var(--st-card) 95%, transparent);
  border: 1px solid var(--st-line);
  box-shadow: 0 4px 16px rgba(0, 0, 0, .45);
  pointer-events: none;
  animation: bd-hint-out 4s ease forwards;
}
@keyframes bd-hint-out {
  0% { opacity: 0; }
  8%, 70% { opacity: 1; }
  100% { opacity: 0; }
}
/* 눕혔을 때는 쪽지만 도로 세운다.
   이 글은 '아직 폰을 안 돌린 사람' 이 읽어야 하는 글이다. 판과 함께 누워
   있으면 정작 읽을 수가 없어서, 돌리라는 말이 돌려야만 읽힌다. */
.bd.bd-turn > .bd-hint {
  left: 50%; top: 50%;
  transform: translate(-50%, -50%) rotate(-90deg);
}

/* 보드 위에 얹는 조작부 (크기·되돌리기). 판을 가리지 않게 구석에 둔다. */
.bd-tools {
  position: absolute; right: 10px; bottom: 10px; z-index: 3;
  display: flex; gap: 6px;
}
.bd .bd-tools > button {
  width: 34px; height: 34px; min-height: 0; margin: 0; padding: 0;
  border-radius: 999px; cursor: pointer;
  font-family: inherit; font-size: 14px; font-weight: 800;
  color: var(--st-fg);
  background: color-mix(in srgb, var(--st-card) 92%, transparent);
  border: 1px solid var(--st-line);
}
.bd .bd-tools > button.wide { width: auto; padding: 0 12px; font-size: 12px; }

/* 화면 가득일 때는 노치·홈바를 피해 앉는다.
   붙어 있는 쪽만 밀어야 한다. 아래에 붙은 것(.bd-where)에 top 까지 주면 위아래가
   둘 다 못박혀 상자가 화면 높이만큼 늘어난다 — 눕혔을 때 이름표가 화면을 가로질러
   길게 늘어나 있던 자리다(97 × 370px). */
.bd.bd-full > .bd-map { top: calc(10px + env(safe-area-inset-top, 0px)); }
.bd.bd-full > .bd-tools,
.bd.bd-full > .bd-where { bottom: calc(10px + env(safe-area-inset-bottom, 0px)); }

/* 눕히면 노치·홈바가 판의 좌우로 온다. 어느 쪽으로 눕히든(폰이 알아서 돌아가는
   경우까지) 걸리지 않게 위아래 중 큰 값을 양옆에 쓴다. */
.bd.bd-full.bd-turn {
  --bd-side: max(env(safe-area-inset-top, 0px), env(safe-area-inset-bottom, 0px));
}
.bd.bd-full.bd-turn > .bd-map { top: 10px; }
.bd.bd-full.bd-turn > .bd-tools,
.bd.bd-full.bd-turn > .bd-where { bottom: 10px; }
.bd.bd-full.bd-turn > .bd-map,
.bd.bd-full.bd-turn > .bd-tools { right: calc(10px + var(--bd-side)); }
.bd.bd-full.bd-turn > .bd-where { left: calc(10px + var(--bd-side)); }
