/* book_publish 관리서버. 외부 CDN 을 쓰지 않는다 — 원고를 다루는 도구라
   바깥으로 나가는 요청을 두지 않는다. */
:root {
  --ink: #1b1b1d; --dim: #6b6b73; --line: #dcdce2; --bg: #f7f7f9;
  --card: #fff; --bad: #b3261e; --warn: #8a5a00; --good: #1c6b3c; --link: #2b5fb3;
}
* { box-sizing: border-box; }
body { margin: 0; background: var(--bg); color: var(--ink);
  font: 15px/1.6 system-ui, "Noto Sans KR", sans-serif; }
a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }
code { font-family: ui-monospace, monospace; font-size: .92em;
  background: #ececf1; padding: .1em .35em; border-radius: 3px; }

.bar { display: flex; align-items: center; gap: 1rem; padding: .7rem 1.2rem;
  background: var(--card); border-bottom: 1px solid var(--line); }
.brand { font-weight: 700; letter-spacing: -.01em; }
.bar nav { margin-left: auto; display: flex; align-items: center; gap: 1rem; }
.bar nav form { margin: 0; }
.who { color: var(--dim); }
button.link { background: none; border: 0; color: var(--link); cursor: pointer;
  font: inherit; padding: 0; }

.wrap { max-width: 1000px; margin: 0 auto; padding: 1.6rem 1.2rem 3rem; }
h1 { font-size: 1.35rem; margin: 0 0 1rem; }

.card { background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  padding: 1.2rem 1.4rem; }
.card.narrow { max-width: 26rem; margin: 2rem auto; }
.card h1 { margin-bottom: 1rem; }

label { display: block; margin: .8rem 0; }
label small { color: var(--dim); }
input { display: block; width: 100%; margin-top: .3rem; padding: .5rem .6rem;
  border: 1px solid var(--line); border-radius: 5px; font: inherit; background: #fff; }
input:focus { outline: 2px solid var(--link); outline-offset: -1px; }
button[type=submit] { margin-top: 1rem; padding: .55rem 1.1rem; border: 0;
  border-radius: 5px; background: var(--ink); color: #fff; font: inherit; cursor: pointer; }
button[type=submit]:disabled { background: var(--dim); cursor: not-allowed; }

.note { color: var(--dim); }
.bad  { color: var(--bad); }
.warn { color: var(--warn); }
.good { color: var(--good); }

.grid { width: 100%; border-collapse: collapse; background: var(--card);
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.grid th, .grid td { padding: .55rem .7rem; border-bottom: 1px solid var(--line);
  text-align: left; vertical-align: top; }
.grid th { background: #f0f0f4; font-weight: 600; font-size: .92em; }
.grid tr:last-child td { border-bottom: 0; }
.grid .num { text-align: right; }
.grid tr.dim { opacity: .55; }   /* 취소·폐기는 감추지 않고 흐리게만 */
.slug { display: block; color: var(--dim); font-family: ui-monospace, monospace; }

.foot { max-width: 1000px; margin: 0 auto; padding: 0 1.2rem 2rem;
  color: var(--dim); font-size: .88em; }

/* --- M1 ------------------------------------------------------------- */
.head { display: flex; align-items: center; gap: .8rem; margin-bottom: 1rem; }
.head h1 { margin: 0; }
h2 { font-size: 1.05rem; margin: 0 0 .7rem; }
h3 { font-size: .95rem; margin: 1.2rem 0 .4rem; }
.card + .card { margin-top: 1rem; }
.card h2 small { font-weight: 400; }

a.button, .button { display: inline-block; padding: .4rem .9rem; border-radius: 5px;
  background: var(--ink); color: #fff; font-size: .93em; }
a.button:hover { text-decoration: none; opacity: .88; }
button.danger { background: var(--bad); }
form.row { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
form.row label { margin: 0; }
form.row button[type=submit] { margin-top: 0; }
form.row input, form.row select { width: auto; margin-top: 0; }
select { padding: .45rem .5rem; border: 1px solid var(--line); border-radius: 5px;
  font: inherit; background: #fff; }
details { margin-top: .8rem; }
summary { cursor: pointer; color: var(--link); }

/* 작업물 배지. 색은 sha1(slug) 에서 뽑으므로 늘 같다 — 화면을 잘못 열었을 때
   글자를 읽기 전에 색으로 먼저 안다. */
.badge { display: inline-block; padding: .1rem .5rem; border: 1px solid;
  border-radius: 999px; font-size: .82em; font-family: ui-monospace, monospace; }
.badge.plain { color: var(--dim); background: #f0f0f4; border-color: var(--line); }
.dot { display: inline-block; width: .6rem; height: .6rem; border-radius: 50%;
  margin-right: .35rem; vertical-align: baseline; }
.tag { color: var(--dim); border: 1px solid var(--line); border-radius: 4px;
  padding: .05rem .4rem; font-size: .82em; }

.flash { background: #fff8e1; border: 1px solid #e6d28a; border-radius: 6px;
  padding: .6rem .8rem; }

/* 공정 띠 */
ol.stages { display: flex; flex-wrap: wrap; gap: .3rem; list-style: none;
  padding: 0; margin: 0 0 1rem; }
ol.stages li { padding: .25rem .6rem; border: 1px solid var(--line);
  border-radius: 999px; font-size: .85em; color: var(--dim); background: #fafafc; }
ol.stages li.past { color: var(--ink); background: #eef1f6; }
ol.stages li.now { color: #fff; background: var(--ink); border-color: var(--ink); }

/* 막힌 이유는 항목별로 적는다. 「할 수 없습니다」만 보이면 쓸모가 없다. */
ul.why { margin: .3rem 0 .8rem 1.1rem; }
ul.why li { margin: .15rem 0; }

pre.tree, pre.prompt { background: #f4f4f8; border: 1px solid var(--line);
  border-radius: 6px; padding: .7rem .9rem; overflow-x: auto; font-size: .88em;
  line-height: 1.5; margin: .4rem 0; }
pre.prompt { background: #f2f7f2; border-color: #cfe0cf; }
.grid th[scope], .grid tbody th { background: #f8f8fb; font-weight: 600;
  white-space: nowrap; }

/* --- M2 ------------------------------------------------------------- */
textarea { display: block; width: 100%; margin-top: .3rem; padding: .5rem .6rem;
  border: 1px solid var(--line); border-radius: 5px; font: inherit;
  font-family: ui-monospace, monospace; font-size: .9em; resize: vertical; }
input[type=file] { border: 0; padding: .3rem 0; }

.seg { border-top: 1px solid var(--line); padding: .7rem 0; }
.seg:first-of-type { border-top: 0; }
.seghead { color: var(--dim); font-size: .85em; font-family: ui-monospace, monospace;
  margin-bottom: .3rem; }
.seg .src { color: #45454e; background: #f6f6fa; border-left: 3px solid var(--line);
  padding: .4rem .6rem; margin-bottom: .35rem; white-space: pre-wrap; }
.seg .dst { padding: .4rem .6rem; white-space: pre-wrap; }
.seg .dst.empty { color: var(--dim); font-style: italic; }
dl.fn dt { font-family: ui-monospace, monospace; color: var(--dim); }
dl.fn dd { margin: 0 0 .5rem 1.2rem; }

/* --- M3 ------------------------------------------------------------- */
.toolbar { display: flex; gap: .5rem 1.2rem; align-items: center; flex-wrap: wrap;
  /* 위쪽 여백이 없어 앞 칸 테두리에 딱 붙어 있었다. 붙으면 그 칸의 일부처럼
     보여, 무엇을 고르는 단추인지가 흐려진다. */
  margin: 1.2rem 0; }
.toolbar .group { display: flex; gap: .4rem; flex-wrap: wrap; align-items: center; }
.toolbar .lead { color: var(--dim); font-size: .9em; }
.chip { display: inline-block; padding: .35rem .85rem; border: 1px solid var(--line);
  border-radius: 999px; font-size: .9em; background: #fff; color: var(--ink); }
.chip b { font-weight: 700; margin-left: .3em; }
.chip:hover { text-decoration: none; background: #f0f0f4; }
.chip.on { background: var(--ink); color: #fff; border-color: var(--ink); }
/* 갈 곳이 없는 쪽(처음·끝)은 단추처럼 보이면 안 된다 — 눌러도 안 되는
   것을 누르게 만들지 않는다. */
.chip.off { color: var(--dim); background: #fafafa; }
/* 아래쪽 쪽 이동. 「지금 어디」를 가운데 두고 앞뒤를 양옆에 둔다. */
.pager { border-top: 1px solid var(--line); padding-top: .9rem;
  margin-top: 1.6rem; }
.pager .note { color: var(--dim); font-size: .9em; }

h2.chtitle { font-size: 1.15rem; margin: 0 0 1rem; }
h2.chtitle small { font-weight: 400; color: var(--dim); }

.reader { background: var(--card); border: 1px solid var(--line); border-radius: 8px;
  padding: 1.4rem 1.6rem 1.4rem 5.2rem; line-height: 1.9; }
.reader .seg { position: relative; border: 0; padding: 0; margin: 0 0 1rem; }
.reader .addr { position: absolute; left: -4.4rem; top: .35em; width: 3.8rem;
  text-align: right; color: #b0b0bb; font-size: .72rem;
  font-family: ui-monospace, monospace; }
.reader .src { color: #45454e; background: transparent; border: 0; padding: 0;
  font-size: .93em; margin-bottom: .2rem; }
.reader.both .src { background: #f6f6fa; border-left: 3px solid var(--line);
  padding: .35rem .6rem; }
.reader .dst { padding: 0; }
.reader .seg.heading .dst { font-weight: 700; font-size: 1.05em; }
.reader .seg.verse .dst { margin-left: 1.5em; font-style: italic; }
sup.fn { font-size: .72em; }
sup.fn.missing { color: var(--bad); }
.footnotes ol { padding-left: 1.4em; }
.footnotes li { margin-bottom: .4rem; }

/* --- M4 ------------------------------------------------------------- */
.tally { display: flex; gap: .8rem; flex-wrap: wrap; margin-bottom: .6rem; }
.tally .t { display: flex; flex-direction: column; align-items: center;
  min-width: 7.5rem; padding: .6rem .9rem; border: 1px solid var(--line);
  border-radius: 8px; background: #fafafc; }
.tally .t:hover { text-decoration: none; background: #f2f2f7; }
.tally .t b { font-size: 1.5rem; line-height: 1.2; }
.tally .t span { font-size: .8rem; color: var(--dim); }
.tally .t.fail b { color: var(--bad); }
.tally .t.review b { color: var(--warn); }
.tally .t.on { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink); }

.lv { display: inline-block; padding: .05rem .45rem; border-radius: 4px;
  font-size: .78em; white-space: nowrap; }
.lv.fail { background: #fdeceb; color: var(--bad); }
.lv.review { background: #fdf3e0; color: var(--warn); }
.lv.info { background: #eef1f6; color: var(--dim); }

table.findings td { vertical-align: top; }
.q { font-size: .86em; padding: .2rem .45rem; border-radius: 4px;
  margin-top: .25rem; white-space: pre-wrap; }
.q.dst { background: #f3f6f3; }
.q.src { background: #f6f6fa; color: #45454e; }
.why { font-size: .84em; color: var(--dim); margin-top: .2rem; }

/* --- M5 ------------------------------------------------------------- */
.card.judge { border-left: 3px solid var(--line); }
.jhead { display: flex; align-items: center; gap: .55rem; flex-wrap: wrap;
  margin-bottom: .5rem; }
.jhead .detail { margin-left: auto; font-size: .86em; }
.tag.warn { color: var(--warn); border-color: #e6d28a; background: #fdf8ec; }
.msg { margin: .2rem 0 .4rem; }
.ctx { margin: .5rem 0 .7rem; }
.judgeform { margin-top: .6rem; }
.judgeform .reason { width: 100%; margin: 0 0 .5rem; }
.judgeform .btns { display: flex; gap: .5rem; flex-wrap: wrap; }
.judgeform button { margin: 0; padding: .45rem .9rem; border: 1px solid var(--line);
  border-radius: 5px; background: #fff; color: var(--ink); font: inherit;
  cursor: pointer; }
.judgeform button:hover { background: #f2f2f7; }
.judgeform .b-accept { border-color: #e0b48a; color: #8a5a00; }
.judgeform .b-reject { border-color: #a9c7ac; color: #1c6b3c; }
.judgeform .b-defer  { color: var(--dim); }
.promote { display: block; margin-top: .5rem; font-size: .9em; }
.promote input { display: inline; width: auto; margin: 0 .35rem 0 0; }
.tally .t:not(a) { cursor: default; }

/* --- M7 ------------------------------------------------------------- */
ul.files { list-style: none; padding: 0; }
ul.files li { padding: .3rem 0; border-bottom: 1px solid var(--line); }
ul.files li:last-child { border-bottom: 0; }
details summary.bad { color: var(--bad); }

/* --- M8 ------------------------------------------------------------- */
.segedit { margin: .2rem 0 0; }
.segedit textarea { margin: 0 0 .35rem; font-family: inherit; font-size: 1em; }
.segedit button { margin: 0; padding: .3rem .8rem; border: 1px solid var(--line);
  border-radius: 5px; background: #fff; color: var(--ink); font: inherit;
  font-size: .88em; cursor: pointer; }
.segedit button:hover { background: #f2f2f7; }
mark { background: #ffe9a8; padding: 0 .1em; }

/* 필수·선택 표시. **필수면 필수라고 적는다** — 눌러 보고 나서야 알게 하지 않는다. */
b.req { display: inline-block; margin-left: .3rem; padding: .05rem .4rem;
  border-radius: 4px; background: #fdeceb; color: var(--bad);
  font-size: .74rem; font-weight: 700; vertical-align: middle; }
.opt { display: inline-block; margin-left: .3rem; padding: .05rem .4rem;
  border-radius: 4px; background: #f0f0f4; color: var(--dim);
  font-size: .74rem; vertical-align: middle; }
label small { display: block; margin-top: .15rem; color: var(--dim);
  font-weight: 400; }
ul.made { margin: .3rem 0 .5rem 1.1rem; color: var(--ink); }
ul.made li { margin: .18rem 0; }
form.row label b.req, form.row label .opt { margin-left: .25rem; }
label small.note { display: block; margin-top: .2rem; font-weight: 400; }

/* --- 좁은 화면 ------------------------------------------------------- */
/* 브라우저로 재 보니 390px 폭에서 모든 화면이 79~210px 가로로 밀렸다.
   범인이 둘이다 — 머리띠가 줄바꿈을 안 했고, 표가 제 폭을 고집했다.
   가로 스크롤은 «넘쳤다» 는 사실을 숨기면서 읽기를 망친다. */
.bar { flex-wrap: wrap; row-gap: .4rem; }
.bar nav { flex-wrap: wrap; row-gap: .3rem; }

/* 표는 **제 안에서** 옆으로 넘긴다. 쪽 전체가 밀리면 본문까지 따라 나간다.
   이 규칙이 700px 아래에만 걸려 있어서, 태블릿 폭(768px)에서 감사 로그 표가
   쪽을 208px 밀어냈다. **표가 쪽을 미는 것은 어느 폭에서도 안 된다.** */
.grid-scroll, table.grid { display: block; max-width: 100%; overflow-x: auto; }
table.grid thead, table.grid tbody { display: table; width: 100%; }

@media (max-width: 700px) {
  .wrap { padding: 1rem .8rem 2.5rem; }
  .head { flex-wrap: wrap; row-gap: .4rem; }
  table.grid th, table.grid td { white-space: nowrap; }
  table.grid td:first-child, table.grid td:nth-child(4) { white-space: normal; }
  form.row { flex-direction: column; align-items: stretch; }
  form.row input, form.row select, form.row button { width: 100%; }
  .tally { gap: .5rem; }
  .tally .t { min-width: 6rem; flex: 1 1 6rem; }
  /* 읽기 화면의 구획번호는 여백 밖으로 나가면 안 된다 */
  .reader { padding: 1rem .9rem; }
  .reader .addr { position: static; display: block; width: auto; text-align: left;
    margin-bottom: .15rem; }
  pre.tree, pre.prompt { font-size: .8em; }
}

/* ── 「지금 할 일」과 누가 하는가 ───────────────────────────────────
   화면이 사람과 AI 의 일을 나눠 다루면 그 경계를 화면이 말해 줘야 한다. */
.card.now { border-left: 4px solid #2b6cb0; background: #f5f9ff; }
.card.now h2 { margin-top: 0; }
.now-what { font-size: 1.15em; line-height: 1.6; margin: .4em 0; }
.button.go { font-size: 1.05em; padding: .5em 1.1em; }

.who {
  display: inline-block; font-size: .8em; font-weight: 600;
  padding: .1em .5em; border-radius: 3px; border: 1px solid;
  white-space: nowrap; vertical-align: middle;
}
.who-me   { color: #1a4480; background: #e6effa; border-color: #b6cdea; }
.who-ai   { color: #6b3fa0; background: #f1e9fb; border-color: #cdb8e6; }
.who-auto { color: #55606a; background: #eef1f3; border-color: #ccd4da; }

table.acts { border-collapse: collapse; width: 100%; }
table.acts td { padding: .45em .6em; border-bottom: 1px solid #eceff1; vertical-align: middle; }
table.acts td:first-child { width: 1%; white-space: nowrap; }
table.acts td:nth-child(2) { white-space: nowrap; font-weight: 600; }
table.acts td.note { font-weight: 400; }

details.adv > summary { cursor: pointer; font-weight: 600; color: #55606a; }
details.adv > summary:hover { color: #1a4480; }
details.adv h3 { margin: 1.2em 0 .4em; font-size: .98em; }
details.adv > *:not(summary) { margin-left: .2em; }

@media (max-width: 700px) {
  table.acts td { display: block; border: 0; padding: .15em .3em; }
  table.acts td:nth-child(2) { white-space: normal; }
  table.acts tr { display: block; border-bottom: 1px solid #eceff1; padding: .5em 0; }
}

/* 화면 첫 줄의 「누가 하는 일인가」 안내 */
.intro {
  margin: .2em 0 1em; padding: .55em .8em; line-height: 1.6;
  background: #f7f9fb; border-left: 3px solid #ccd4da; border-radius: 0 3px 3px 0;
}

/* --- 화면 머리 (제목 / 이동+동작 / 안내) -----------------------------
   제목 줄에는 이동 링크를 섞지 않고, 이동과 동작은 **한 줄에 나란히** 둔다.
   따로 떼어 층을 쌓으면 화면이 길어지기만 하고 읽히지는 않는다. */
.head { gap: .6rem; margin-bottom: .6rem; }
.head .acts { margin-left: auto; }

.subbar {
  display: flex; align-items: center; flex-wrap: wrap; gap: .5rem;
  margin: 0 0 .9rem; padding-bottom: .5rem; border-bottom: 1px solid var(--line);
}
.crumbs { display: flex; flex-wrap: wrap; gap: .1rem; font-size: .93em; }
.crumbs a, .crumbs b {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .3rem .6rem; border-radius: 6px; font-weight: 400; white-space: nowrap;
}
.crumbs a { color: var(--dim); }
.crumbs a:hover { background: #eef1f3; color: var(--ink); text-decoration: none; }
.crumbs b.at { background: var(--ink); color: #fff; font-weight: 600; }

.acts, form.acts { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.subbar .acts { margin-left: auto; }
.acts form { margin: 0; }
.acts button, .acts .button { margin-top: 0; }

/* 아이콘 — 저장소에 넣은 Tabler 묶음을 쪽 안에서 쓴다 (CDN 없음). 글자 크기를
   따라가고 색을 물려받아, 어디에 놓아도 옆 글자와 같은 무게로 보인다. */
.ico {
  width: 1.05em; height: 1.05em; flex: none; vertical-align: -.16em;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.button .ico, button .ico { margin-right: .35em; }
.who .ico { width: .95em; height: .95em; margin-right: .2em; }

/* 딸린 동작은 채우지 않는다. 한 화면에 꽉 찬 검은 단추가 여럿이면 어느 것이
   본 동작인지 알 수 없다. */
a.button, .button, button { display: inline-flex; align-items: center; }
.button.ghost, button.ghost {
  background: #fff; color: var(--ink); border: 1px solid var(--line);
}
.button.ghost:hover, button.ghost:hover { background: #f2f4f6; opacity: 1; }

@media (max-width: 700px) {
  .crumbs { font-size: .88em; }
  .crumbs a, .crumbs b { padding: .3rem .45rem; }
  .subbar .acts, .head .acts { margin-left: 0; }
}

/* 퇴고 칸 — 이 화면에서 **원고를 실제로 바꾸는 유일한 자리**다. 눈에 띄어야 한다. */
.card.revise { border-left: 4px solid #6b3fa0; }
.card.revise h2 { display: flex; align-items: center; gap: .4rem; }
.who-ai_me { color: #6b3fa0; background: #f6f1fc; border-color: #ddcdf0; }

/* 「고쳤다 — 다시 봐 달라」. 판정이 아니라 **요청**이라 다른 색으로 둔다. */
button.b-recheck { border-color: #cdb8e6; color: #6b3fa0; background: #f6f1fc; }
button.b-recheck:hover { background: #efe6fa; }

/* 읽으며 남기는 메모. **읽는 데 지장을 주지 않는 것이 첫째다.**
   처음엔 테두리 친 상자에 단추를 아래로 달았더니 구획마다 세 줄씩 늘어나
   글이 끊겼다 — 사용자가 「그지 같자나 읽는데 엄청 지장 주자나」라고 했다.
   지금은 **밑줄 하나와 그 오른쪽 단추, 한 줄**이다. 글자는 #999999. */
.reader .cmt { display: flex; align-items: baseline; gap: .4rem;
  margin: .1rem 0 0; }
.reader .cmt .body { flex: 1 1 auto; width: auto; min-width: 0; margin: 0;
  border: 0; border-bottom: 1px solid #e8e8ee; border-radius: 0;
  background: transparent; color: #999999; font: inherit; font-size: .9em;
  line-height: 1.5; padding: 0 .1rem .1rem; }
.reader .cmt .body:hover { border-bottom-color: #d5d5dc; }
.reader .cmt .body:focus { outline: 0; border-bottom-color: #a9a9b2; }
.reader .cmt.has .body { border-bottom-color: #c9c9d0; }
.reader .cmt button { flex: 0 0 auto; margin: 0; border: 0; background: none;
  font: inherit; font-size: .95em; line-height: 1; padding: 0 .1rem;
  cursor: pointer; opacity: .35; filter: grayscale(1); }
.reader .cmt button:hover { opacity: 1; filter: none; }
.reader .cmt .body:focus ~ button { opacity: .8; filter: none; }
.reader .cmt .moved { flex: 0 0 auto; color: var(--warn); font-size: .75em; }

/* 토스트. 메모를 저장했다는 말을 **읽던 자리를 건드리지 않고** 전한다.
   쪽 맨 위의 flash 로 알리면 스크롤이 위로 튀어 읽던 데를 잃는다. */
#toast { position: fixed; right: 1rem; bottom: 1rem; z-index: 50;
  max-width: 28rem; padding: .5rem .8rem; border: 1px solid var(--line);
  border-radius: 6px; background: #fff; color: var(--dim); font-size: .88em;
  box-shadow: 0 2px 10px rgba(0,0,0,.08); }
#toast.bad { border-color: #e6cf9a; background: #fdf6e3; color: var(--warn); }
