/* ==========================================================================
   쩜오책방 납품 도구 — 도서관 서지카드에서 가져온 시각 언어
   따뜻한 종이색 바탕, 잉크색 글자, 도장 같은 벽돌빛 강조색.
   ========================================================================== */

/*
 * Pretendard (SIL OFL 1.1) — public/fonts/Pretendard-LICENSE.txt
 * 가변 폰트라 파일 하나로 모든 두께를 쓴다. 외부 CDN 없이 직접 담아
 * 인터넷이 끊겨도 글꼴이 깨지지 않는다.
 */
@font-face {
  font-family: 'Pretendard Variable';
  src: url('/fonts/PretendardVariable.woff2') format('woff2-variations');
  font-weight: 45 920;
  font-style: normal;
  font-display: swap;
}

/*
 * 고운바탕 (SIL OFL 1.1) — public/fonts/GowunBatang-LICENSE.txt
 * 제목에만 쓰는 명조체. 서지카드 같은 인쇄물의 질감을 준다.
 * 제목은 전부 굵게 쓰므로 Bold 한 벌만 담았다(한글 437KB).
 * unicode-range 를 나눠 두면 한글이 없는 화면에서는 한글 파일을 아예 받지 않는다.
 */
@font-face {
  font-family: 'Gowun Batang';
  src: url('/fonts/GowunBatang-latin-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F,
                 U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Gowun Batang';
  src: url('/fonts/GowunBatang-korean-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+1100-11FF, U+3130-318F, U+A960-A97F, U+AC00-D7A3, U+D7B0-D7FF;
}

:root {
  --paper:        oklch(0.972 0.009 88);
  --paper-deep:   oklch(0.945 0.012 86);
  --card:         oklch(0.995 0.004 90);
  --ink:          oklch(0.24 0.018 62);
  --ink-soft:     oklch(0.46 0.016 65);
  --ink-faint:    oklch(0.63 0.014 70);
  --rule:         oklch(0.874 0.013 80);
  --rule-soft:    oklch(0.925 0.010 82);

  --stamp:        oklch(0.505 0.152 28);   /* 강조 — 대출 도장 빨강 */
  --stamp-soft:   oklch(0.955 0.022 32);
  --amber:        oklch(0.700 0.125 72);   /* 확인 필요 */
  --amber-soft:   oklch(0.968 0.030 84);
  --slate:        oklch(0.60 0.010 250);   /* 못 찾음 */
  --slate-soft:   oklch(0.955 0.005 250);

  --sans: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont,
          'Apple SD Gothic Neo', 'Malgun Gothic', sans-serif;
  /* 제목에만 쓰는 명조체. 본문·표는 Pretendard 로 두어 가독성을 지킨다. */
  --serif: 'Gowun Batang', AppleMyungjo, 'Nanum Myeongjo', ui-serif, Georgia, serif;

  /*
   * 두께 체계 — 가변 폰트라 원하는 값을 그대로 쓸 수 있다.
   * 한글은 라틴보다 획이 많아 같은 두께라도 더 빽빽해 보인다.
   * 그래서 본문은 400, 작은 글씨는 450~500 으로 살짝 올려 읽기 편하게 잡았다.
   */
  --w-body:     400;  /* 표 데이터, 문단 */
  --w-small:    450;  /* 작은 보조 글씨 — 400 이면 흐릿해 보인다 */
  --w-medium:   500;  /* 라벨, 표 머리, 강조되지 않는 버튼 */
  --w-strong:   600;  /* 소제목, 확정된 책 제목, 기본 버튼 */
  --w-title:    700;  /* 화면 제목 */
  --w-display:  800;  /* 합계 금액처럼 한눈에 읽어야 하는 숫자 */

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
}

body {
  /* 머리말 높이를 숫자로 박아두면 로고나 글자 크기가 바뀔 때 어긋난다.
     세로 flex 로 두고 작업 영역이 남는 높이를 차지하게 한다. */
  display: flex;
  flex-direction: column;
  font-family: var(--sans);
  /* 사용자가 오래 들여다보는 도구다. 기본 글자를 넉넉하게 잡는다. */
  font-size: 15.5px;
  font-weight: var(--w-body);
  line-height: 1.55;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-synthesis: none; /* 없는 굵기를 브라우저가 억지로 만들지 않게 */
  /* Pretendard 의 한글 자간을 살짝 조여 표가 촘촘하게 읽히도록 */
  letter-spacing: -0.003em;
}

button, input, textarea { font: inherit; color: inherit; }

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

.masthead {
  flex: none;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.85rem clamp(1rem, 3vw, 2rem);
  border-bottom: 1px solid var(--rule);
  background: var(--card);
}

.wordmark {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0;
  font-size: 1.32rem;
  font-weight: inherit;
  flex: none; /* 좁은 화면에서 글자가 한 자씩 세로로 쪼개지지 않게 */
}

/* 책방 로고 */
.wordmark .logo {
  height: 1.7rem;
  width: auto;
  display: block;
}

/*
 * 앱 이름. 로고와의 사이에 얇은 구분선을 둔다.
 * 누르면 프로그램 정보 창이 뜨므로 단추이지만, 제목 글자 그대로 보여야 하므로
 * 단추의 기본 모양(테두리·배경·글꼴)은 지운다. 가리켰을 때만 진해진다.
 */
.wordmark .appname {
  font-family: var(--serif);
  font-weight: var(--w-title);
  font-size: inherit;
  letter-spacing: -0.01em;
  padding: 0 0 0 0.7rem;
  border: none;
  border-left: 1px solid var(--rule);
  border-radius: 0;
  background: none;
  color: var(--ink);
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.13s var(--ease);
}
.wordmark .appname:hover { color: var(--stamp); }
.wordmark .appname:focus-visible { outline: 2px solid var(--stamp); outline-offset: 2px; }

/*
 * 판 번호 도장. 화면에 늘 보이는 판 번호는 이것 하나뿐이다.
 * 제목 명조가 아니라 본문 글꼴로 작게 둬서 이름을 가리지 않는다.
 */
.wordmark .appver {
  margin-left: 0.45rem;
  padding: 0.05em 0.34em;
  border: 1px solid var(--rule);
  border-radius: 2px;
  font-family: var(--sans);
  font-weight: var(--w-small);
  font-size: 0.68rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  color: var(--ink-faint);
  vertical-align: middle;
  white-space: nowrap;
  transition: color 0.13s var(--ease), border-color 0.13s var(--ease);
}
.wordmark .appname:hover .appver { color: var(--stamp); border-color: var(--stamp); }

/*
 * 툴 탭. 목록은 /api/tools 로 받아 그리므로 툴이 늘어도 HTML 은 손대지 않는다.
 * 지금 보고 있는 탭만 진하게 두고 밑줄로 표시한다 — 버튼처럼 보이지 않게.
 * 이름이 모두 한글 네 글자라 그냥 두면 한 줄의 문장으로 뭉쳐 보인다.
 * 탭 사이에 짧은 세로선을 그어 항목 하나하나로 끊어 읽히게 한다.
 */
.tabs {
  display: flex;
  align-items: center;
  gap: 0;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
  padding-left: 0.3rem;
}
.tabs::-webkit-scrollbar { display: none; }

.tab {
  position: relative;
  flex: none;
  padding: 0.3rem 0.75rem 0.34rem;
  border-bottom: 2px solid transparent;
  font-size: 0.9rem;
  font-weight: var(--w-medium);
  color: var(--ink-faint);
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.12s var(--ease), border-color 0.12s var(--ease);
}

/* 항목 사이 칸막이 — 글자 높이만큼만 긋는다 */
.tab + .tab::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 1px;
  height: 0.95em;
  background: var(--rule);
}

.tab:hover { color: var(--ink); }

.tab.is-current {
  color: var(--ink);
  font-weight: var(--w-strong);
  border-bottom-color: var(--stamp);
}

.tab:focus-visible {
  outline: 2px solid var(--stamp);
  outline-offset: 1px;
  border-radius: 3px;
}

.masthead .spacer { margin-left: auto; }

/*
 * 계정 묶음 — 로그인한 사람 · 비밀번호 · 회원관리 · 로그아웃.
 * 머리말은 자식 사이를 1rem 씩 벌리는데 이 넷은 한 덩어리다. 따로 묶어 거의 붙여 두고,
 * 1rem 간격은 묶음 바깥(탭과의 사이)에만 남긴다. nav.js 가 이 상자를 만들어 넣는다.
 */
.masthead .account {
  flex: none;
  display: flex;
  align-items: center;
  gap: 0.12rem;
}

/* 이름은 단추가 아니라 표시일 뿐이라 단추들과만 조금 띄운다 */
.account .whoami { margin-right: 0.35rem; }

.account .btn {
  padding: 0.32rem 0.55rem;
  font-size: 0.8rem;
}

/* 그림 단추(비밀번호·회원관리)는 정사각형으로 — 글자 단추보다 눈에 덜 띄게 */
.account .btn-icon { width: 1.95rem; height: 1.95rem; padding: 0; }
.account .btn-icon svg { width: 1.05rem; height: 1.05rem; }

.whoami {
  font-weight: var(--w-small);
  color: var(--ink-soft);
  font-size: 0.8rem;
  white-space: nowrap;
}

.masthead #logout { white-space: nowrap; }

/*
 * 읽기 전용(일반) 계정.
 * 머리말에 딱지를 하나 달고, 값을 넣는 단추(data-write)를 감춘다.
 * 감추는 것은 친절일 뿐이고 진짜 방어는 서버가 한다 — 이 CSS 를 지워도 안전하다.
 */
.role-chip {
  margin-right: 0.35rem;
  padding: 0.08rem 0.4rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: var(--w-small);
  color: var(--ink-faint);
  white-space: nowrap;
}

body.is-readonly [data-write] { display: none !important; }

/* 잠긴 입력칸이 '고장난 것'이 아니라 '못 쓰는 것'으로 보이게 */
body.is-readonly input:disabled,
body.is-readonly textarea:disabled,
body.is-readonly select:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

/* 좁은 화면에서는 로고 글자를 접고 탭만 남긴다 — 탭이 있어야 툴을 옮겨다닐 수 있다 */
@media (max-width: 760px) {
  .masthead { gap: 0.4rem; padding-inline: 0.9rem; }
  .wordmark { font-size: 1.1rem; }
  .wordmark .logo { height: 1.45rem; }
  .wordmark .appname { display: none; }
  .whoami { display: none; }
  .tab { padding-inline: 0.55rem; font-size: 0.86rem; }
}

/* ------------------------------------------------------------------ 레이아웃 */

.workspace {
  display: grid;
  grid-template-columns: minmax(300px, 25rem) 1fr;
  flex: 1;
  min-height: 0; /* 안쪽 표가 스스로 스크롤하도록 */
}

@media (max-width: 900px) {
  html, body { height: auto; }

  .workspace {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto;
    flex: none;
  }
}

/* --------------------------------------------------------------- 입력 패널 */

.compose {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  padding: clamp(1rem, 2.2vw, 1.6rem);
  border-right: 1px solid var(--rule);
  background: var(--paper-deep);
  min-height: 0;
}

.compose h2 {
  font-family: var(--serif);
  font-weight: var(--w-title);
  font-size: 1.02rem;
  margin: 0;
}

.compose .hint {
  font-weight: var(--w-small);
  margin: -0.5rem 0 0;
  font-size: 0.83rem;
  color: var(--ink-faint);
  line-height: 1.5;
}

#inputs {
  flex: 1;
  min-height: 14rem;
  resize: none;
  padding: 0.85rem 0.9rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--card);
  /* 한 줄에 한 권 — 줄 간격을 넓혀 세는 것을 쉽게 */
  line-height: 1.95;
  tab-size: 2;
}

#inputs:focus-visible {
  outline: 2px solid var(--stamp);
  outline-offset: 1px;
  border-color: transparent;
}

#inputs::placeholder {
  color: var(--ink-faint);
  line-height: 1.95;
}

/* 목록 파일을 끌어다 놓는 곳 — 입력창 아래 작게 */
.dropzone {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: 3.6rem;
  padding: 0.6rem 0.9rem;
  border: 1.5px dashed var(--rule);
  border-radius: 4px;
  background: var(--paper);
  color: var(--ink-faint);
  font-size: 0.8rem;
  font-weight: var(--w-small);
  line-height: 1.5;
  cursor: pointer;
  transition: border-color 0.15s var(--ease), background 0.15s var(--ease), color 0.15s var(--ease);
}
.dropzone strong { font-weight: var(--w-medium); color: var(--ink-soft); }
.dropzone:hover { border-color: var(--ink-faint); color: var(--ink-soft); }

/* 파일을 끌고 들어왔을 때 */
.dropzone.is-drag {
  border-color: var(--stamp);
  background: var(--stamp-soft);
  color: var(--stamp);
}
.dropzone.is-drag strong { color: var(--stamp); }

/* 읽는 중 */
.dropzone.is-busy { opacity: 0.6; cursor: progress; }

/* 납품체크 — 바코드 스캔 입력 (크고 또렷하게) */
.scan-box { display: flex; flex-direction: column; gap: 0.35rem; }
.scan-box label {
  font-weight: var(--w-medium);
  font-size: 0.86rem;
  color: var(--ink-soft);
}
#scan {
  padding: 0.7rem 0.85rem;
  border: 2px solid var(--rule);
  border-radius: 5px;
  background: var(--card);
  font-size: 1.15rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
#scan:focus-visible {
  outline: none;
  border-color: var(--stamp);
  box-shadow: 0 0 0 3px var(--stamp-soft);
}
#scan:disabled { background: var(--paper-deep); color: var(--ink-faint); }

/* 납품체크는 아래 합계줄이 없으므로 여백 제거하고, 2단 표가 각자 스크롤한다 */
.table-scroll:has(.check-panes) { padding-bottom: 0; overflow: hidden; }

/* 납품체크 — 확인 / 미확인 2단 표 */
.check-panes {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  height: 100%;
  min-height: 0;
}
.check-panes[hidden] { display: none; }
.check-pane {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1 1 0;
}
.check-pane.is-muted { flex: 0 1 40%; }
.pane-title {
  flex: none;
  padding: 0.4rem 0.85rem;
  font-size: 0.82rem;
  font-weight: var(--w-medium);
  letter-spacing: 0.03em;
  color: var(--ink-soft);
  background: var(--paper-deep);
  border-bottom: 1px solid var(--rule);
}
.pane-title strong { color: var(--stamp); font-weight: var(--w-strong); }
.check-pane.is-muted .pane-title strong { color: var(--ink-soft); }
.pane-table { flex: 1 1 0; overflow: auto; min-height: 0; }
.pane-empty {
  padding: 0.9rem;
  font-size: 0.85rem;
  color: var(--ink-faint);
  font-weight: var(--w-small);
}
.check-pane.is-muted .pane-table table { color: var(--ink-soft); }
td.c-qty, th.c-qty { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* 한 줄이 두 줄로 접히지 않게(저자·제목은 app.js 에서 글자 수로 잘라 표시한다) */
.pane-table td, .pane-table th { white-space: nowrap; }

/*
 * 방금 찍은 책을 확인표 맨 윗줄에 1초간 반짝여 "스캔이 잘 됐다"를 눈으로 알린다.
 * 살짝 커졌다 돌아오고, 따뜻한 색이 번졌다 사라진다.
 */
@keyframes scan-flash {
  0%   { transform: scale(1.035); background-color: oklch(0.86 0.12 62); }
  30%  { background-color: oklch(0.80 0.15 33); }
  100% { transform: scale(1); background-color: transparent; }
}
.pane-table tr.just-scanned {
  animation: scan-flash 1s ease-out;
  transform-origin: center;
}

.compose footer {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.tally {
  font-weight: var(--w-medium);
  font-size: 0.84rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  margin-right: auto;
}

/* 입력 패널 안의 한 줄짜리 선택 칸 (복본검사의 도서관 고르기) */
.field-inline {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: -0.2rem 0 0;
}

.field-inline label {
  font-weight: var(--w-medium);
  font-size: 0.86rem;
  color: var(--ink-soft);
  white-space: nowrap;
}

.field-inline select {
  flex: 1;
  min-width: 0;
  padding: 0.42rem 0.55rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--card);
  font-size: 0.9rem;
  font-weight: var(--w-medium);
}

.field-inline select:focus-visible {
  outline: 2px solid var(--stamp);
  outline-offset: 1px;
  border-color: transparent;
}

/* --------------------------------------------------------------- 버튼 */

.btn {
  border: 1px solid var(--rule);
  background: var(--card);
  color: var(--ink);
  padding: 0.44rem 0.85rem;
  border-radius: 4px;
  cursor: pointer;
  font-size: 0.88rem;
  font-weight: var(--w-medium);
  white-space: nowrap; /* 좁은 화면에서 "전체 복사" 가 두 줄로 접히지 않게 */
  transition: background 0.15s var(--ease), border-color 0.15s var(--ease),
              transform 0.15s var(--ease);
}

.btn:hover:not(:disabled) { background: var(--paper); border-color: var(--ink-faint); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: 0.45; cursor: default; }

.btn:focus-visible {
  outline: 2px solid var(--stamp);
  outline-offset: 2px;
}

.btn-primary {
  background: var(--stamp);
  border-color: var(--stamp);
  color: oklch(0.99 0.01 60);
  font-weight: var(--w-strong);
  padding-inline: 1.3rem;
}
.btn-primary:hover:not(:disabled) {
  background: oklch(0.45 0.152 28);
  border-color: oklch(0.45 0.152 28);
}

.btn-quiet {
  border-color: transparent;
  background: transparent;
  color: var(--ink-soft);
}
.btn-quiet:hover:not(:disabled) { background: var(--paper); color: var(--ink); }

/* 주문서 버튼 — 이 화면의 실제 목적(북센·YES24 업로드)이라 살짝 강조한다 */
.btn-order {
  border-color: var(--stamp);
  color: var(--stamp);
  font-weight: var(--w-strong);
}
.btn-order:hover:not(:disabled) {
  background: var(--stamp-soft);
  border-color: var(--stamp);
  color: var(--stamp);
}

/* --------------------------------------------------------------- 결과 영역 */

.results {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

.toolbar {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.6rem clamp(0.75rem, 2vw, 1.25rem);
  border-bottom: 1px solid var(--rule);
  background: var(--card);
}

.summary {
  font-weight: var(--w-small);
  margin-right: auto;
  font-size: 0.86rem;
  color: var(--ink-soft);
  display: flex;
  align-items: center;
  gap: 0.9rem;
  flex-wrap: wrap;
}

.summary .chip {
  display: inline-flex;
  align-items: center;
  gap: 0.34rem;
  white-space: nowrap;
}

.summary .dot {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  flex: none;
}
.dot.is-amber { background: var(--amber); }
.dot.is-slate { background: var(--slate); }
.dot.is-stamp { background: var(--stamp); }

.table-scroll {
  flex: 1;
  overflow: auto;
  min-height: 0;
  padding-bottom: 6rem; /* 마지막 행이 합계 줄에 가려지지 않게 */
}

/* --------------------------------------------------------------- 합계 줄 */

/* 표가 길어져도 항상 아래에 붙어 있다 */
.totals {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.7rem clamp(0.75rem, 2vw, 1.25rem);
  border-top: 1px solid var(--rule);
  background: var(--card);
}
.totals[hidden] { display: none; }

.totals .count {
  font-weight: var(--w-medium);
  font-size: 0.92rem;
  font-variant-numeric: tabular-nums;
}

.totals .caveat {
  font-weight: var(--w-medium);
  font-size: 0.78rem;
  color: var(--stamp);
}

.totals .sum {
  margin-left: auto;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}

.totals .sum-label {
  font-weight: var(--w-medium);
  font-size: 0.8rem;
  color: var(--ink-faint);
  letter-spacing: 0.03em;
}

/* 구입 정산에 쓰는 숫자라 또렷하게 */
.totals .sum strong {
  font-size: 1.3rem;
  font-weight: var(--w-display);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.totals .won {
  font-size: 0.85rem;
  color: var(--ink-soft);
  margin-left: -0.25rem;
}

/* --------------------------------------------------------------- 표 */

table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.94rem;
}

thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--paper-deep);
  text-align: left;
  font-weight: var(--w-medium);
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
  padding: 0.5rem 0.8rem;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}

tbody td {
  padding: 0.52rem 0.8rem;
  border-bottom: 1px solid var(--rule-soft);
  vertical-align: top;
}

/*
 * 표의 바깥 여백은 위 툴바·아래 합계 줄과 같은 값으로 맞춘다.
 * 마지막 칸은 대개 권수라 오른쪽에 붙는데, 창 가장자리에 바짝 붙으면
 * 작은 숫자 단추를 누르기 어렵고 위아래 줄과 눈금도 어긋나 보인다.
 * 줄 눈금은 표 끝까지 그대로 이어지고 글자만 안으로 들어온다.
 */
thead th:last-child,
tbody td:last-child { padding-right: clamp(0.75rem, 2vw, 1.25rem); }

tbody tr:hover td { background: oklch(0.985 0.008 88); }

/* 상태 표식과 줄 지우기 단추를 첫 번째로 보이는 열에 겹쳐 놓는다(제목을 꺼도 깨지지 않게). */
td.c-flag {
  position: relative;
  padding-left: 3.95rem; /* 표식 + 지우기 두 칸. 글자와의 간격은 원래(0.4rem)를 지킨다 */
}

/*
 * 한 줄이 두 줄로 접히지 않게 내용 열은 nowrap 으로 둔다. 너비는 내용에 맞춰
 * 유동적으로 잡히고, 표가 넓어지면 가로로 스크롤한다(납품체크 표와 같은 방식).
 */
td.c-title {
  font-weight: var(--w-strong);
  white-space: nowrap;
}

td.c-isbn {
  font-weight: var(--w-small);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  white-space: nowrap;
  color: var(--ink-soft);
}

td.c-author, td.c-publisher { color: var(--ink-soft); white-space: nowrap; }

td.c-price {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/*
 * 값이 비어 있는 줄에 원래 입력이 무엇이었는지 흐리게 보여준다.
 * ::after 로 그린 글자라 DOM 텍스트가 아니고 user-select 도 막혀 있어서,
 * 표를 드래그해 엑셀에 붙여넣어도 이 글자는 들어가지 않는다.
 */
td.c-flag[data-input]::after {
  content: attr(data-input);
  color: var(--ink-faint);
  font-weight: 400;
  font-style: italic;
  user-select: none;
  -webkit-user-select: none;
}

/* 행 상태 — 배경 색조로만 알린다 */
tr.is-ambiguous td { background: var(--amber-soft); }
tr.is-ambiguous:hover td { background: oklch(0.955 0.036 84); }
tr.is-notfound td, tr.is-error td { background: var(--slate-soft); }

/* 아직 조회 중인 줄 — 자리는 잡혀 있고 값만 비어 있다 */
tr.is-pending td { color: var(--ink-faint); }
tr.is-pending .flag {
  cursor: default;
  animation: breathe 1.4s ease-in-out infinite;
}

@keyframes breathe {
  0%, 100% { opacity: 0.35; }
  50%      { opacity: 0.9; }
}

/*
 * 상태 표식.
 * 표 밖으로 삐져나온 절대 위치 버튼이라 열을 만들지 않고,
 * user-select:none 이라 표를 드래그 복사해도 엑셀에 딸려오지 않는다.
 */
.flag {
  position: absolute;
  left: 0.45rem;
  top: 0.5rem;
  width: 1.25rem;
  height: 1.25rem;
  padding: 0;
  border: none;
  border-radius: 3px;
  background: transparent;
  color: var(--ink-faint);
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  display: grid;
  place-items: center;
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
}

.flag:hover:not(:disabled) { background: oklch(0.90 0.02 80); color: var(--ink); }
.flag:focus-visible { outline: 2px solid var(--stamp); outline-offset: 1px; }
.flag svg { width: 0.95rem; height: 0.95rem; display: block; }

tr.is-ambiguous .flag { color: oklch(0.52 0.13 62); }
tr.is-notfound .flag, tr.is-error .flag { color: var(--slate); }

/*
 * 줄 지우기 단추 — 표식 바로 옆.
 * 평소엔 투명하고 클릭도 안 받는다. 그 줄에 마우스를 올렸을 때만 나타나므로
 * 줄마다 ✕ 가 늘어서지 않고, 표식(회색·호박색)과 달리 빨강으로만 반응해 역할이 헷갈리지 않는다.
 */
.rowdel {
  position: absolute;
  /*
   * 표식(0.45rem + 1.25rem)에서 한 칸 띄운 자리.
   * 표식은 '다시 검색', 이쪽은 '지우기' 라 하는 일이 아주 다르다 —
   * 손이 조금 빗나가도 엉뚱한 쪽이 눌리지 않게 사이를 벌려 둔다.
   */
  left: 2.3rem;
  top: 0.5rem;
  width: 1.25rem;
  height: 1.25rem;
  padding: 0;
  border: none;
  border-radius: 3px;
  background: transparent;
  color: var(--ink-faint);
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  display: grid;
  place-items: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s var(--ease), background 0.15s var(--ease), color 0.15s var(--ease);
}

tbody tr:hover .rowdel,
.rowdel:focus-visible {
  opacity: 1;
  pointer-events: auto;
}

.rowdel:hover { background: var(--stamp-soft); color: var(--stamp); }
.rowdel:focus-visible { outline: 2px solid var(--stamp); outline-offset: 1px; }
.rowdel svg { width: 0.9rem; height: 0.9rem; display: block; }

/*
 * 순번 열 — 여기 적힌 번호가 그대로 납품서류의 일련번호가 된다.
 * 내용만큼만 차지한다(width:1%). 숫자 자체가 순서 손잡이라 열이 더 늘지 않는다.
 *
 * 표식·지우기 단추와 같이 이 열은 통째로 복사에서 뺀다(머리글 # 까지).
 * 번호는 화면에서 자리를 알려 주는 표시일 뿐이고 책의 값이 아니다 —
 * 한쪽만 복사되면 엑셀에 붙였을 때 머리글과 값이 한 칸씩 어긋난다.
 */
thead th.c-seq,
tbody td.c-seq {
  width: 1%;
  padding-left: 0.7rem;
  padding-right: 0.4rem;
  text-align: right;
  white-space: nowrap;
  user-select: none;
  -webkit-user-select: none;
}

/*
 * 순서 손잡이 — 권수·제목과 같이 글자 자체가 단추다(열을 늘리지 않는다).
 * 한두 자리 숫자라 그냥 두면 잡을 자리가 좁아, 음수 여백으로 줄 높이는 그대로 두고
 * 누르고 잡는 자리만 넓힌다(권수 단추와 같은 방법).
 * 크롬은 draggable 요소에 user-select:none 을 스스로 걸지만 파이어폭스는 걸지 않는다 —
 * 브라우저마다 복사 결과가 달라지지 않게 여기서 못 박는다.
 */
.rowgrip {
  min-width: 1.6rem;
  padding: 0.25rem 0.35rem;
  margin: -0.25rem 0;
  border: none;
  border-radius: 3px;
  background: transparent;
  font: inherit;
  font-weight: var(--w-small);
  font-variant-numeric: tabular-nums;
  color: var(--ink-faint);
  text-align: right;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  transition: background 0.13s var(--ease), color 0.13s var(--ease);
}

/* 그 줄에 마우스를 올렸을 때만 잡을 수 있는 자리로 보인다 — 평소엔 그냥 번호다. */
tbody tr:hover .rowgrip { background: oklch(0.90 0.02 80); color: var(--ink); }
.rowgrip:focus-visible { outline: 2px solid var(--stamp); outline-offset: 1px; }
.rowgrip:active { cursor: grabbing; }

/* 끌고 있는 줄 — 출력 열 설정 드래그와 같은 표시(흐리게) */
tbody tr.dragging td { opacity: 0.4; }

/* ------------------------------------------------------- 복본검사 전용 표 */

/* 표식이 첫 칸에 겹쳐 놓인다 — 표는 정확히 3열을 유지한다 */
td.c-dbisbn {
  position: relative;
  padding-left: 2.1rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  white-space: nowrap;
  font-weight: var(--w-small);
}

td.c-status {
  white-space: nowrap;
  font-weight: var(--w-medium);
  color: var(--ink-soft);
}

td.c-book {
  min-width: 16rem;
  font-weight: var(--w-strong);
}

/* 복본이 있는 줄이 이 화면의 결론이다 — 가장 눈에 띄게 */
tr.is-duplicate td { background: var(--stamp-soft); }
tr.is-duplicate:hover td { background: oklch(0.945 0.030 32); }
tr.is-duplicate td.c-status { color: var(--stamp); font-weight: var(--w-strong); }
tr.is-duplicate .flag { color: var(--stamp); }

/* 복본 없음 — 좋은 소식이지만 조용히 둔다 */
tr.is-none td.c-status { color: var(--ink-faint); }

/* 결과 필터 — 고른 범위 말고는 줄을 감춘다 */
.table-scroll[data-filter="duplicate"] tbody tr:not(.is-duplicate) { display: none; }
.table-scroll[data-filter="none"] tbody tr:not(.is-none) { display: none; }

/* 전체 · 복본 · 복본 없음 을 고르는 세그먼트 버튼 */
.seg {
  display: inline-flex;
  border: 1px solid var(--rule);
  border-radius: 4px;
  overflow: hidden;
  flex: none;
}
.seg[hidden] { display: none; }
.seg-btn {
  border: 0;
  border-left: 1px solid var(--rule);
  background: var(--card);
  color: var(--ink-soft);
  padding: 0.38rem 0.7rem;
  font-size: 0.84rem;
  font-weight: var(--w-medium);
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
}
.seg-btn:first-child { border-left: 0; }
.seg-btn:hover:not(.is-active) { background: var(--paper); }
.seg-btn.is-active {
  background: var(--stamp);
  color: #fff;
}
.seg-btn:focus-visible {
  outline: 2px solid var(--stamp);
  outline-offset: -2px;
}

/* --------------------------------------------------------------- 빈 화면 */

.empty {
  display: grid;
  place-content: center;
  justify-items: start;
  gap: 0.55rem;
  height: 100%;
  padding: 2rem clamp(1.5rem, 6vw, 5rem);
  max-width: 34rem;
  color: var(--ink-soft);
}
/* display:grid 가 기본 [hidden](display:none)을 덮으므로 명시적으로 숨긴다 */
.empty[hidden] { display: none; }

.empty h3 {
  font-family: var(--serif);
  font-weight: var(--w-title);
  font-size: 1.22rem;
  margin: 0 0 0.15rem;
  color: var(--ink);
}

.empty p {
  font-weight: var(--w-body); margin: 0; font-size: 0.92rem; line-height: 1.65; }

.empty .sample {
  margin-top: 0.7rem;
  padding: 0.75rem 0.95rem;
  border-left: 2px solid var(--stamp);
  background: var(--card);
  font-size: 0.88rem;
  line-height: 1.85;
  color: var(--ink-soft);
  white-space: pre-line;
  border-radius: 0 4px 4px 0;
}

/* --------------------------------------------------------------- 진행 표시 */

.progress {
  height: 2px;
  background: var(--rule-soft);
  overflow: hidden;
}
.progress[hidden] { display: none; }

/* 몇 권까지 끝났는지 실제 비율로 보여준다 */
.progress::after {
  content: '';
  display: block;
  height: 100%;
  width: var(--done, 0%);
  background: var(--stamp);
  transition: width 0.35s var(--ease);
}

/* --------------------------------------------------------------- 확인 창 */

dialog.picker {
  border: 1px solid var(--rule);
  border-radius: 6px;
  padding: 0;
  width: min(46rem, 92vw);
  max-height: 84vh;
  background: var(--card);
  color: var(--ink);
  box-shadow: 0 18px 44px oklch(0.24 0.018 62 / 0.18);
}

dialog.picker::backdrop {
  background: oklch(0.24 0.018 62 / 0.34);
}

.picker-head {
  padding: 1rem 1.25rem 0.8rem;
  border-bottom: 1px solid var(--rule);
}

.picker-head .step {
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  color: var(--stamp);
  font-weight: var(--w-strong);
}

.picker-head h3 {
  font-family: var(--serif);
  font-weight: var(--w-title);
  font-size: 1.2rem;
  margin: 0.15rem 0 0.2rem;
}

.picker-head p {
  font-weight: var(--w-small);
  margin: 0;
  font-size: 0.85rem;
  color: var(--ink-faint);
}

.picker-list {
  overflow: auto;
  max-height: 52vh;
  padding: 0.4rem 0;
}

.pick {
  display: grid;
  grid-template-columns: 2.9rem 1fr;
  gap: 0.85rem;
  width: 100%;
  text-align: left;
  padding: 0.7rem 1.25rem;
  border: none;
  background: transparent;
  cursor: pointer;
  border-left: 3px solid transparent;
  transition: background 0.13s var(--ease), border-color 0.13s var(--ease);
}

.pick:hover, .pick:focus-visible {
  background: var(--stamp-soft);
  border-left-color: var(--stamp);
  outline: none;
}

.pick img {
  width: 2.9rem;
  height: 4.1rem;
  object-fit: cover;
  background: var(--paper-deep);
  border-radius: 2px;
}

.pick .t {
  display: block;
  font-weight: var(--w-strong);
  line-height: 1.4;
  margin-bottom: 0.15rem;
}

.pick .m {
  font-weight: var(--w-small);
  display: block;
  font-size: 0.85rem;
  color: var(--ink-soft);
  line-height: 1.5;
}

.pick .m .sep { color: var(--rule); margin: 0 0.4rem; }

.picker-foot {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  padding: 0.75rem 1.25rem;
  border-top: 1px solid var(--rule);
}

.picker-foot .note {
  font-weight: var(--w-small);
  margin-right: auto;
  font-size: 0.8rem;
  color: var(--ink-faint);
}

/* ------------------------------------------------------------- 확인 창 */

/*
 * 되돌릴 수 없는 일을 하기 전에 한 번 묻는 작은 창.
 * 여닫는 처리는 단추 클릭에서만 한다 — close 이벤트는 늦게 도착할 수 있어 믿지 않는다.
 */
dialog.askbox {
  border: 1px solid var(--rule);
  border-radius: 6px;
  padding: 0;
  width: min(24rem, 92vw);
  background: var(--card);
  color: var(--ink);
  box-shadow: 0 18px 44px oklch(0.24 0.018 62 / 0.18);
}
dialog.askbox::backdrop { background: oklch(0.24 0.018 62 / 0.34); }

.ask-head { padding: 1.1rem 1.25rem 0.9rem; }

.ask-head h3 {
  font-family: var(--serif);
  font-weight: var(--w-title);
  font-size: 1.15rem;
  margin: 0;
}

.ask-head p {
  margin: 0.4rem 0 0;
  font-size: 0.88rem;
  font-weight: var(--w-small);
  color: var(--ink-soft);
  line-height: 1.5;
}

.ask-foot {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.85rem 1.25rem;
  border-top: 1px solid var(--rule);
}

/* -------------------------------------------------- 책 정보 · 납품 권수 창 */

/*
 * 표의 권수 숫자 자체가 단추다 — 열을 늘리지 않는다.
 * 여기 글자는 실제 값이라 user-select 를 막지 않는다(표를 엑셀에 붙여넣으면 그대로 들어간다).
 * 점선 밑줄로만 "눌러서 고칠 수 있다"를 알린다.
 */
.qtybtn {
  /*
   * 한두 자리 숫자라 그냥 두면 누를 자리가 너무 좁다.
   * 위아래로도 넓히되 같은 크기의 음수 여백으로 되돌려, 누를 자리만 커지고
   * 줄 높이는 그대로 둔다(12×24 → 22×32).
   */
  padding: 0.25rem 0.4rem;
  margin: -0.25rem 0;
  border: none;
  border-bottom: 1px dashed var(--rule);
  border-radius: 2px;
  background: transparent;
  font: inherit;
  color: inherit;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background 0.13s var(--ease), color 0.13s var(--ease), border-color 0.13s var(--ease);
}

.qtybtn:hover {
  background: var(--stamp-soft);
  color: var(--stamp);
  border-bottom-color: var(--stamp);
}

.qtybtn:focus-visible { outline: 2px solid var(--stamp); outline-offset: 1px; }

/*
 * 제목도 눌러서 책 정보를 볼 수 있다. 권수와 같은 방식으로 글자 자체가 단추라
 * 열이 늘지 않고 엑셀 복사에도 값 그대로 들어간다.
 * 제목은 목록에서 가장 눈에 띄는 글자라 밑줄을 늘 깔면 표가 어수선해진다 —
 * 그 줄에 마우스를 올렸을 때만 밑줄이 비치고, 제목을 직접 가리키면 진해진다.
 */
.titlebtn {
  padding: 0;
  border: none;
  border-bottom: 1px dashed transparent;
  background: transparent;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: color 0.13s var(--ease), border-color 0.13s var(--ease);
}

tbody tr:hover .titlebtn { border-bottom-color: var(--rule); }
.titlebtn:hover { color: var(--stamp); border-bottom-color: var(--stamp); }
.titlebtn:focus-visible { outline: 2px solid var(--stamp); outline-offset: 2px; border-radius: 2px; }

dialog.bookbox {
  border: 1px solid var(--rule);
  border-radius: 6px;
  padding: 0;
  width: min(29rem, 92vw);
  background: var(--card);
  color: var(--ink);
  box-shadow: 0 18px 44px oklch(0.24 0.018 62 / 0.18);
}
dialog.bookbox::backdrop { background: oklch(0.24 0.018 62 / 0.34); }

.dlg-head {
  padding: 1rem 1.25rem 0.8rem;
  border-bottom: 1px solid var(--rule);
}

.dlg-head .step {
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  color: var(--stamp);
  font-weight: var(--w-strong);
}

.dlg-head h3 {
  font-family: var(--serif);
  font-weight: var(--w-title);
  font-size: 1.15rem;
  line-height: 1.4;
  margin: 0.15rem 0 0;
}

.dlg-body {
  display: flex;
  gap: 1rem;
  padding: 1rem 1.25rem;
}

.dlg-cover {
  flex: none;
  width: 3.6rem;
  height: 5.1rem;
  object-fit: cover;
  background: var(--paper-deep);
  border-radius: 2px;
}

.dlg-info {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.32rem 0.85rem;
  align-content: start;
  min-width: 0;
  margin: 0;
  font-size: 0.88rem;
}
.dlg-info dt { color: var(--ink-faint); font-weight: var(--w-small); white-space: nowrap; }
.dlg-info dd { margin: 0; color: var(--ink-soft); font-weight: var(--w-medium); overflow-wrap: anywhere; }
.dlg-info dd.is-num { font-variant-numeric: tabular-nums; }

.qty-edit {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.9rem 1.25rem;
  border-top: 1px solid var(--rule);
  background: var(--paper);
}

.qty-edit label {
  font-size: 0.86rem;
  font-weight: var(--w-medium);
  color: var(--ink-soft);
  white-space: nowrap;
}

.qty-edit input {
  appearance: textfield; /* 기본 화살표는 우리 ± 단추가 대신한다 */
  -moz-appearance: textfield;
  width: 4.2rem;
  padding: 0.42rem 0.55rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--card);
  text-align: right;
  font-size: 1rem;
  font-weight: var(--w-strong);
  font-variant-numeric: tabular-nums;
}
.qty-edit input:focus-visible { outline: 2px solid var(--stamp); outline-offset: 1px; border-color: transparent; }
.qty-edit input::-webkit-outer-spin-button,
.qty-edit input::-webkit-inner-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }

.qty-step {
  flex: none;
  width: 1.9rem;
  height: 1.9rem;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--card);
  color: var(--ink-soft);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.13s var(--ease), color 0.13s var(--ease), border-color 0.13s var(--ease);
}
.qty-step:hover { border-color: var(--stamp); color: var(--stamp); background: var(--stamp-soft); }
.qty-step:focus-visible { outline: 2px solid var(--stamp); outline-offset: 1px; }

.qty-sum {
  margin-left: auto;
  text-align: right;
  font-size: 0.84rem;
  font-weight: var(--w-small);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

.dlg-foot {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 1.25rem;
  border-top: 1px solid var(--rule);
}

.dlg-foot .note {
  margin-right: auto;
  font-size: 0.8rem;
  font-weight: var(--w-small);
  color: var(--ink-faint);
}

/* --------------------------------------------------------------- 환경설정 */

/* 툴바의 톱니 아이콘 버튼 — 툴바가 여러 줄로 늘어나도 항상 같은 크기의 정사각형.
   flex:none 로 늘어나지도 줄어들지도 않게 고정한다(옆 텍스트 버튼과 같은 높이). */
.btn-icon {
  flex: none;
  width: 2.36rem;
  height: 2.36rem;
  padding: 0;
  display: grid;
  place-items: center;
  color: var(--ink-soft);
}
.btn-icon svg { width: 1.2rem; height: 1.2rem; display: block; }
.btn-icon:hover:not(:disabled) { color: var(--ink); }

dialog.settings {
  border: 1px solid var(--rule);
  border-radius: 6px;
  padding: 0;
  width: min(30rem, 92vw);
  max-height: 88vh;
  /* 다이얼로그 자체는 스크롤하지 않는다 — 본문(.set-scroll)의 스크롤바 하나만 쓴다.
     (내용 88vh + 테두리 2px 가 최대 높이를 살짝 넘어 바깥 스크롤바가 겹쳐 생기던 문제) */
  overflow: hidden;
  background: var(--card);
  color: var(--ink);
  box-shadow: 0 18px 44px oklch(0.24 0.018 62 / 0.18);
}
dialog.settings::backdrop { background: oklch(0.24 0.018 62 / 0.34); }

.settings-form {
  display: flex;
  flex-direction: column;
  /* 다이얼로그 최대 높이(88vh)에서 테두리 2px 를 뺀다 — 넘치면 하단 버튼이 잘린다 */
  max-height: calc(88vh - 2px);
}
.settings-form h3 {
  margin: 0;
  padding: 1rem 1.25rem 0.85rem;
  border-bottom: 1px solid var(--rule);
  font-family: var(--serif);
  font-weight: var(--w-title);
  font-size: 1.05rem;
}

.set-group {
  padding: 1.1rem 1.25rem;
  border-bottom: 1px solid var(--rule-soft);
  flex-shrink: 0; /* 구역이 눌려 찌그러지지 않게 — 스크롤은 .set-scroll 이 맡는다 */
}

/* 설정 팝업의 본문 스크롤 영역 — 구역마다가 아니라 전체가 스크롤바 하나로 움직인다.
   (제목과 하단 취소·적용 버튼은 고정) */
.set-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.set-toggle {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  cursor: pointer;
}
.set-toggle input { width: 1.05rem; height: 1.05rem; accent-color: var(--stamp); margin: 0; }
.set-toggle strong { font-weight: var(--w-strong); }

.set-title {
  font-weight: var(--w-strong);
  margin-bottom: 0.15rem;
}

.set-help {
  margin: 0.45rem 0 0;
  font-size: 0.8rem;
  font-weight: var(--w-small);
  line-height: 1.55;
  color: var(--ink-faint);
}
.set-help a { color: var(--stamp); text-decoration: none; border-bottom: 1px solid var(--rule); }
.set-help a:hover { border-bottom-color: var(--stamp); }

.set-field {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.8rem;
}
.set-field label { font-size: 0.86rem; font-weight: var(--w-medium); color: var(--ink-soft); white-space: nowrap; }
.set-field input {
  flex: 1;
  min-width: 0;
  padding: 0.42rem 0.55rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper);
  font-size: 0.9rem;
}
.set-field input:focus-visible { outline: 2px solid var(--stamp); outline-offset: 1px; border-color: transparent; }

/* 알라딘 2차검색이 꺼져 있으면 키 입력을 흐리게 */
.set-group.is-off #setKeyRow,
.set-group.is-off #setKeyRow + .set-help { opacity: 0.45; }

/* 출력 열 목록 — 드래그로 순서 바꾸기 */
.col-list {
  list-style: none;
  margin: 0.7rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.col-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.6rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper);
  cursor: grab;
}
.col-item.dragging { opacity: 0.5; }
.col-item.drop-target { border-color: var(--stamp); background: var(--stamp-soft); }
.col-item input { width: 1rem; height: 1rem; accent-color: var(--stamp); margin: 0; }
.col-item .col-name { flex: 1; font-weight: var(--w-medium); }
.col-item .col-grip { color: var(--ink-faint); font-size: 1.1rem; line-height: 1; cursor: grab; user-select: none; }

.settings-foot {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.85rem 1.25rem;
  border-top: 1px solid var(--rule);
}

/* ------------------------------------------------------- 프로그램 정보 창 */

/*
 * 머리말의 앱 이름을 누르면 뜬다. 설정 창들과 달리 읽기만 하는 창이라
 * 가운데로 모으고 테두리 선을 두지 않는다 — 표지 한 장처럼 보이게.
 */
dialog.about {
  border: 1px solid var(--rule);
  border-radius: 6px;
  padding: 0;
  width: min(23.5rem, 92vw);
  background: var(--card);
  color: var(--ink);
  box-shadow: 0 18px 44px oklch(0.24 0.018 62 / 0.18);
}
dialog.about::backdrop { background: oklch(0.24 0.018 62 / 0.34); }

/*
 * 표지 한 장처럼 촘촘하게 짠다. 줄 간격이 조금만 벌어져도 글자가 흩어져 보인다 —
 * 특히 로고와 만든 이 이름은 거의 붙어 있어야 한 덩어리로 읽힌다.
 */
.about-body {
  padding: 1.8rem 1.4rem 1.3rem;
  text-align: center;
  line-height: 1.35;
}

/* 줄 사이 간격은 아래 여백 하나로만 준다 — 문단 기본 여백은 지운다 */
.about-body > * { margin: 0; }

.about-org {
  font-weight: var(--w-medium);
  font-size: 0.85rem;
  color: var(--ink-soft);
}

.about-name {
  margin-top: 0.3rem;
  font-family: var(--serif);
  font-weight: var(--w-title);
  font-size: 1.55rem;
  letter-spacing: -0.01em;
}

.about-ver {
  margin-top: 0.15rem;
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-soft);
}

.about-tagline {
  margin-top: 0.8rem;
  font-weight: var(--w-medium);
  font-size: 0.88rem;
}

.about-by {
  margin-top: 1rem;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

/*
 * 원본 로고는 500px 폭이다. 절반 아래로 줄여 걸어 고해상도 화면에서도 또렷하다.
 * 그림 파일 위아래에 투명 여백이 조금 들어 있어, 여기서 주는 여백은 아주 작아야 한다.
 */
.about-logo {
  display: block;
  width: 14.5rem;
  max-width: 100%;
  height: auto;
  margin: 0.15rem auto 0;
}

/* 로고 그림 자체에 아래 여백이 조금 있어, 여기서는 여백을 주지 않아야 붙어 보인다 */
.about-author {
  margin-top: 0;
  font-weight: var(--w-strong);
  font-size: 0.88rem;
}

/* 이름을 누르면 메일. 콜로폰 링크와 같이 밑줄만 두고 가리켰을 때만 진해진다. */
.about-author a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
}
.about-author a:hover { color: var(--stamp); border-bottom-color: var(--stamp); }
.about-author a:focus-visible { outline: 2px solid var(--stamp); outline-offset: 2px; }

.about-copy {
  margin-top: 0.15rem;
  font-size: 0.78rem;
  color: var(--ink-soft);
}

.about-foot {
  display: flex;
  justify-content: center;
  padding: 0 1.4rem 1.4rem;
}

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

.toast {
  font-weight: var(--w-medium);
  display: flex;
  align-items: center;
  gap: 0.85rem;
  position: fixed;
  left: 50%;
  bottom: 1.75rem;
  translate: -50% 0;
  background: var(--ink);
  color: var(--paper);
  padding: 0.55rem 1.1rem;
  border-radius: 4px;
  font-size: 0.88rem;
  box-shadow: 0 8px 24px oklch(0.24 0.018 62 / 0.25);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s var(--ease), translate 0.25s var(--ease);
}

.toast.show {
  opacity: 1;
  translate: -50% -0.4rem;
}

.toast.is-error { background: var(--stamp); }

/* 알림 안의 되돌리기 단추. .toast 는 클릭을 안 받으므로(pointer-events:none) 이 단추만 되돌려 준다. */
.toast-action {
  pointer-events: auto;
  flex: none;
  background: transparent;
  border: none;
  padding: 0.1rem 0.15rem;
  font: inherit;
  font-weight: var(--w-strong);
  color: var(--paper);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  opacity: 0.85;
  transition: opacity 0.15s var(--ease);
}

.toast-action:hover { opacity: 1; }
.toast-action:focus-visible { outline: 2px solid var(--paper); outline-offset: 2px; border-radius: 3px; }

/* --------------------------------------------------------------- 로그인 */

.gate {
  min-height: 100%;
  display: grid;
  justify-items: center;
  /* 카드와 제작 정보가 한 덩어리로 화면 가운데 오도록 */
  align-content: center;
  padding: 2rem 1.25rem;
}

.card-slip {
  width: min(23rem, 100%);
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: 5px;
  padding: 1.8rem 1.6rem 1.5rem;
  /* 서지카드의 상단 줄 */
  border-top: 3px solid var(--stamp);
  box-shadow: 0 10px 30px oklch(0.24 0.018 62 / 0.07);
}

.gate-logo {
  display: block;
  width: 10.5rem;
  height: auto;
  margin: 0 0 1.4rem;
}

.card-slip h1 {
  font-family: var(--serif);
  font-weight: var(--w-title);
  font-size: 1.3rem;
  margin: 0 0 0.2rem;
}

.card-slip .sub {
  font-weight: var(--w-small);
  margin: 0 0 1.5rem;
  font-size: 0.86rem;
  color: var(--ink-faint);
}

.field { margin-bottom: 0.9rem; }

.field label {
  font-weight: var(--w-medium);
  display: block;
  font-size: 0.8rem;
  color: var(--ink-soft);
  margin-bottom: 0.28rem;
  letter-spacing: 0.02em;
}

.field input {
  width: 100%;
  padding: 0.52rem 0.7rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper);
}

.field input:focus-visible {
  outline: 2px solid var(--stamp);
  outline-offset: 1px;
  border-color: transparent;
}

.card-slip .btn-primary { width: 100%; margin-top: 0.4rem; }

.gate-error {
  margin: 0.9rem 0 0;
  font-size: 0.85rem;
  color: var(--stamp);
  min-height: 1.2em;
}

/* --------------------------------------------------------------- 제작 정보 */

/*
 * 이제 로그인 화면 한 곳에서만 쓴다.
 * 도구 화면마다 제 판 번호를 적던 콜로폰은 걷어냈다 — 하나의 앱이 된 뒤로는
 * 화면마다 다른 번호를 말하는 꼴이 됐다. 판 번호는 머리말 도장(.appver) 하나,
 * 만든 이·저작권은 프로그램 정보 창(dialog.about) 한 곳에서만 말한다.
 */
.colophon {
  font-weight: var(--w-small);
  margin: 0;
  font-size: 0.74rem;
  line-height: 1.7;
  color: var(--ink-faint);
  letter-spacing: 0.01em;
}

.colophon .ver {
  font-variant-numeric: tabular-nums;
  padding: 0 0.32em;
  border: 1px solid var(--rule);
  border-radius: 2px;
  font-size: 0.94em;
}

.colophon .shop { color: var(--stamp); font-weight: var(--w-strong); }

.colophon a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
}
.colophon a:hover { color: var(--ink); border-bottom-color: var(--ink-faint); }

.gate-colophon {
  margin-top: 1.25rem;
  text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------------------------------------------------- 계정 · 회원관리 */

dialog.settings--wide { width: min(46rem, 94vw); }

.acct-msg { color: var(--stamp); font-weight: var(--w-medium); }
.acct-msg.is-ok { color: var(--ink-soft); }

.users-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}
.users-table th {
  text-align: left;
  font-size: 0.78rem;
  font-weight: var(--w-medium);
  color: var(--ink-faint);
  padding: 0.3rem 0.5rem;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
.users-table td {
  padding: 0.45rem 0.5rem;
  border-bottom: 1px solid var(--rule-soft);
  vertical-align: middle;
}
.users-table tr:hover td { background: var(--paper); }
.users-table .u-name { font-weight: var(--w-strong); }
.users-table .u-self { font-weight: var(--w-small); color: var(--ink-faint); }
.users-table .u-date { color: var(--ink-soft); white-space: nowrap; }
.users-table .u-actions { text-align: right; white-space: nowrap; }
.users-table .u-danger:hover:not(:disabled) { color: var(--stamp); }
.users-table button:disabled { opacity: 0.4; cursor: not-allowed; }

.users-table .u-role {
  padding: 0.25rem 0.4rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper);
  font-size: 0.85rem;
}
.users-table .u-role:disabled { opacity: 0.55; cursor: not-allowed; }

.u-reset { display: inline-flex; align-items: center; gap: 0.35rem; }
.u-reset input {
  width: 11rem;
  padding: 0.3rem 0.45rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper);
  font-size: 0.85rem;
}

/* ------------------------------------------------------------ 프로젝트 */

.projects-page {
  /* body 가 flex 세로 배치라 margin:auto 만으로는 내용 크기로 줄어든다 — 폭을 명시한다. */
  width: 100%;
  max-width: 56rem;
  margin: 0 auto;
  padding: 1.6rem 1.4rem 3rem;
}

.projects-head {
  display: flex;
  align-items: baseline;
  gap: 0.9rem;
  flex-wrap: wrap;
  margin-bottom: 1.2rem;
}
.projects-head h2 {
  margin: 0;
  font-family: var(--serif);
  font-weight: var(--w-title);
  font-size: 1.35rem;
}
.projects-head .hint { margin: 0; }
.projects-head .spacer { flex: 1; }

.projects-year {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.88rem;
  color: var(--ink-soft);
}
.projects-year select {
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--card);
  font-size: 0.9rem;
}

.projects-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.project-card {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--card);
}
.project-card:hover { border-color: var(--stamp); }

.project-main { flex: 1; min-width: 0; cursor: pointer; }
.project-name {
  margin: 0 0 0.2rem;
  font-size: 1.02rem;
  font-weight: var(--w-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.project-meta {
  margin: 0;
  font-size: 0.8rem;
  font-weight: var(--w-small);
  color: var(--ink-faint);
}
.project-vendor { color: var(--ink-soft); font-weight: var(--w-medium); }

.project-actions { display: flex; gap: 0.4rem; flex-shrink: 0; }
.project-actions .p-danger:hover:not(:disabled) { color: var(--stamp); }

.projects-empty {
  margin: 2.5rem 0;
  text-align: center;
  color: var(--ink-faint);
}

/* 마스트헤드의 현재 프로젝트 알약 (도구 화면) — [📁 이름 | ⚙] 한 덩어리.
   프로젝트 이름·설정이 캡슐 하나로 묶여, 오른쪽 도구 탭(텍스트 메뉴)과 확실히 구분된다. */
.project-pill {
  display: inline-flex;
  align-items: stretch;
  max-width: 19rem;
  margin-right: 0.6rem; /* 도구 탭과의 간격을 조금 더 벌린다 */
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--paper);
  overflow: hidden;
  white-space: nowrap;
}
.project-pill .pp-name,
.project-pill .pp-gear {
  border: none; /* 알약(캡슐) 테두리만 남기고 버튼 기본 테두리는 없앤다 */
  background: transparent;
}
.project-pill .pp-name {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
  padding: 0.25rem 0.55rem 0.25rem 0.7rem;
  font-size: 0.84rem;
  font-weight: var(--w-medium);
  color: var(--ink-soft);
  cursor: pointer;
}
.project-pill .p-name {
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 12rem;
}
.project-pill .pp-gear {
  display: inline-flex;
  align-items: center;
  padding: 0 0.6rem;
  border-left: 1px solid var(--rule); /* 이름과 설정 사이 얇은 칸막이 */
  color: var(--ink-faint);
  cursor: pointer;
}
.project-pill .pp-gear svg { width: 0.95rem; height: 0.95rem; }
.project-pill .pp-name:hover { color: var(--ink); }
.project-pill .pp-gear:hover { color: var(--stamp); background: var(--paper-deep); }
.project-pill:hover { border-color: var(--stamp); }

/* 라벨을 오른쪽 정렬로 나란히 — 필드 몇 개짜리 팝업(비밀번호 변경·프로젝트 설정)에서
   라벨 길이가 달라 입력칸 폭이 들쭉날쭉해지는 것을 막는다. */
dialog.settings--aligned .set-field label {
  width: 6.5rem;
  flex-shrink: 0;
  text-align: right;
  white-space: normal; /* '권당 용역비(원)' 처럼 길면 두 줄로 접힌다 */
}
dialog.settings--aligned .set-toggle { padding-left: 7.1rem; } /* 라벨 폭 + 간격만큼 들여쓰기 */

/* 설정 팝업·발주처 화면의 셀렉트 — 회원관리 권한 셀렉트(.u-role)와 같은 모양으로 통일한다.
   기본(OS 네이티브) 모양은 종이색 인터페이스와 어울리지 않는다. */
dialog.settings .set-field select,
.vendor-panel .set-field select {
  appearance: none;
  -webkit-appearance: none;
  padding: 0.42rem 1.9rem 0.42rem 0.55rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper);
  font-size: 0.9rem;
  color: var(--ink);
  /* 오른쪽에 작은 ∨ 화살표를 직접 그린다(네이티브 화살표 대신) */
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23847d72' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.6rem center;
}
dialog.settings .set-field select:focus-visible,
.vendor-panel .set-field select:focus-visible {
  outline: 2px solid var(--stamp);
  outline-offset: 1px;
  border-color: transparent;
}
dialog.settings .set-field select:disabled,
.vendor-panel .set-field select:disabled { opacity: 0.55; cursor: not-allowed; }

/* 정렬형 팝업의 설명·안내 문구는 입력칸 시작선(라벨 폭 + 간격)에 맞춘다 */
dialog.settings--aligned .set-help { padding-left: 7.1rem; }

/* ------------------------------------------------------------ 발주처 */

/* 카드 격자 — 기본 2열, 넓은 화면에서 3열 */
.vendor-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.7rem;
}
@media (min-width: 68rem) {
  .vendor-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 34rem) {
  .vendor-grid { grid-template-columns: 1fr; }
}

.vendor-card {
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--card);
  cursor: pointer;
}
.vendor-card:hover { border-color: var(--stamp); }

.vendor-card-head {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-bottom: 0.3rem;
}
.vendor-name {
  margin: 0;
  font-size: 1rem;
  font-weight: var(--w-strong);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vendor-chip {
  flex-shrink: 0;
  padding: 0.1rem 0.5rem;
  border: 1px solid var(--rule);
  border-radius: 999px;
  background: var(--paper);
  font-size: 0.74rem;
  font-weight: var(--w-medium);
  color: var(--ink-soft);
}
.vendor-line {
  margin: 0 0 0.15rem;
  font-size: 0.82rem;
  font-weight: var(--w-small);
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vendor-meta {
  margin: 0.35rem 0 0;
  font-size: 0.78rem;
  font-weight: var(--w-small);
  color: var(--ink-faint);
}

/* 상세 화면 — 발주처 정보(위) / 진행한 프로젝트(아래) 세로 배치.
   프로젝트 이름이 길어도 한 줄로 넉넉히 보이게 하기 위해서다. */
.vendor-detail {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.vendor-panel {
  padding: 1rem 1.2rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--card);
}
.vendor-panel h3 {
  margin: 0 0 0.7rem;
  font-size: 0.95rem;
  font-weight: var(--w-strong);
}
.vendor-panel h3 + .set-field { margin-top: 0; }
.vendor-panel .set-field { margin-top: 0.6rem; }
.vendor-panel .set-field label { width: 6.5rem; flex-shrink: 0; text-align: right; }
.vendor-panel h3:not(:first-child) { margin-top: 1.3rem; }

/* 발주처 노트 — 형식 없는 자유 메모라 라벨 없이 카드 폭을 다 쓴다.
   프로젝트 노트와 같은 모양이라 두 화면의 메모가 같은 물건으로 읽힌다. */
.vendor-note {
  display: block;
  width: 100%;
  min-height: 6.4rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--rule);
  border-radius: 5px;
  background: var(--paper);
  font-size: 0.95rem;
  line-height: 1.6;
  resize: vertical;
}
.vendor-note + .set-help { margin-top: 0.45rem; }

.hint-inline {
  font-size: 0.76rem;
  font-weight: var(--w-small);
  color: var(--ink-faint);
}

/* 담당자 목록 — 드래그로 순서 변경, 맨 위가 주담당자 */
.contact-list {
  list-style: none;
  margin: 0 0 0.6rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.contact-item {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper);
}
.contact-item.dragging { opacity: 0.5; }
.contact-item .col-grip { cursor: grab; }
.contact-item input {
  min-width: 0;
  padding: 0.32rem 0.45rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--card);
  font-size: 0.85rem;
}
.contact-item .c-name { flex: 2; }
.contact-item .c-phone { flex: 2; }
.contact-item .c-email { flex: 3; }
.contact-badge {
  display: none;
  flex-shrink: 0;
  padding: 0.08rem 0.45rem;
  border-radius: 999px;
  background: var(--stamp-soft);
  color: var(--stamp);
  font-size: 0.72rem;
  font-weight: var(--w-strong);
}
.contact-item:first-child .contact-badge { display: inline-block; }

/* 진행한 프로젝트 목록 */
.vendor-projects { display: flex; flex-direction: column; }
.vendor-project {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.1rem;
  border-bottom: 1px solid var(--rule-soft);
}
.vendor-project:last-child { border-bottom: none; }
.vp-name {
  flex: 1;
  min-width: 0;
  font-size: 0.88rem;
  font-weight: var(--w-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vp-date {
  flex-shrink: 0;
  font-size: 0.78rem;
  font-weight: var(--w-small);
  color: var(--ink-faint);
}

/* ------------------------------------------------------------ 납품노트 */

/* 프로젝트 관리 화면과 같은 가운데 한 단 — 노트는 읽는 화면이라 폭을 좁게 잡는다. */
.notes-page {
  width: 100%;
  max-width: 52rem;
  margin: 0 auto;
  padding: 1.6rem 1.4rem 4rem;
  overflow-y: auto;
}

/* 프로젝트 전반 노트 — 늘 맨 위에 펼쳐져 있다 */
.project-note {
  padding: 1rem 1.1rem 0.8rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--card);
}
.pn-head {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  margin-bottom: 0.6rem;
}
.pn-head h2 {
  margin: 0;
  font-family: var(--serif);
  font-weight: var(--w-title);
  font-size: 1.12rem;
}
.pn-status {
  font-size: 0.78rem;
  font-weight: var(--w-small);
  color: var(--ink-faint);
}
.project-note textarea {
  display: block;
  width: 100%;
  min-height: 5.6rem;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--rule);
  border-radius: 5px;
  background: var(--paper);
  font-size: 0.95rem;
  line-height: 1.6;
  resize: vertical;
}
.project-note textarea:focus-visible,
.vendor-note:focus-visible,
.note-editor textarea:focus-visible,
.note-editor .ne-when:focus-visible {
  outline: 2px solid var(--stamp);
  outline-offset: 1px;
  border-color: transparent;
}
.pn-help {
  margin: 0.45rem 0 0;
  font-size: 0.76rem;
  font-weight: var(--w-small);
  color: var(--ink-faint);
}

/* 진행 노트 머리 */
.notes-toolbar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 1.8rem 0 0.8rem;
}
.notes-toolbar h2 {
  margin: 0;
  font-family: var(--serif);
  font-weight: var(--w-title);
  font-size: 1.12rem;
}
.notes-toolbar .spacer { flex: 1; }
.note-count {
  display: inline-block;
  min-width: 1.4rem;
  padding: 0.02rem 0.4rem;
  border-radius: 999px;
  background: var(--paper-deep);
  color: var(--ink-soft);
  font-family: var(--sans);
  font-size: 0.78rem;
  font-weight: var(--w-medium);
  text-align: center;
}

/* 목록 — 왼쪽 세로선이 시간 흐름을 보여준다 */
.note-list {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding-left: 1.1rem;
  border-left: 2px solid var(--rule-soft);
}

.note-item {
  position: relative;
  padding: 0.75rem 1rem 0.85rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--card);
}
/* 세로선 위의 점 */
.note-item::before {
  content: '';
  position: absolute;
  left: -1.45rem;
  top: 1.05rem;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--rule);
}
.note-item:hover { border-color: var(--stamp); }
.note-item:hover::before { background: var(--stamp); }

.note-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.35rem;
}
.note-head .spacer { flex: 1; }
.note-when {
  font-size: 0.84rem;
  font-weight: var(--w-medium);
  color: var(--ink-soft);
  white-space: nowrap;
}
.note-kind {
  flex-shrink: 0;
  padding: 0.08rem 0.45rem;
  border-radius: 999px;
  background: var(--stamp-soft);
  color: var(--stamp);
  font-size: 0.72rem;
  font-weight: var(--w-strong);
}
.note-body {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.65;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* 수정·삭제는 평소엔 조용히 있다가 마우스를 올리거나 키보드로 짚으면 또렷해진다 */
.note-actions {
  display: flex;
  gap: 0.2rem;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity 0.15s var(--ease);
}
.note-item:hover .note-actions,
.note-actions:focus-within { opacity: 1; }
.note-actions .btn {
  padding: 0.12rem 0.45rem;
  font-size: 0.78rem;
}
.note-actions .n-del:hover { color: var(--stamp); }
@media (hover: none) {
  .note-actions { opacity: 1; } /* 터치 화면에는 늘 보여준다 */
}

/* 작성·수정 폼 — 목록 자리에서 그대로 펼쳐진다 */
.note-editor {
  padding: 0.75rem 1rem 0.85rem;
  border: 1px solid var(--stamp);
  border-radius: 6px;
  background: var(--card);
}
.ne-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
  flex-wrap: wrap;
}
.ne-row .spacer { flex: 1; }
.note-editor .ne-when,
.note-editor .ne-kind {
  padding: 0.3rem 0.45rem;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--paper);
  font-size: 0.85rem;
}
.note-editor .ne-kind {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 1.7rem;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23847d72' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.55rem center;
}
.note-editor textarea {
  display: block;
  width: 100%;
  min-height: 4.6rem;
  padding: 0.55rem 0.65rem;
  border: 1px solid var(--rule);
  border-radius: 5px;
  background: var(--paper);
  font-size: 0.95rem;
  line-height: 1.6;
  resize: vertical;
}

.notes-empty {
  margin: 1.6rem 0;
  text-align: center;
  color: var(--ink-faint);
}

@media (max-width: 34rem) {
  .note-list { padding-left: 0; border-left: none; }
  .note-item::before { display: none; }
}

/* ============================================================== 납품서류 서식
   관리 층의 세 번째 화면. 발주처가 준 샘플 엑셀과 지시서를 짝지어 등록한다. */

.form-card { cursor: default; }

.fc-actions {
  display: flex;
  gap: 0.35rem;
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--rule-soft);
}

/* 검사 결과 — 저장하기 전에 무엇이 확인됐는지 보여준다 */
.check-report {
  margin-top: 0.7rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--paper-deep);
}
.cr-ok {
  margin: 0 0 0.4rem;
  font-size: 0.86rem;
  font-weight: var(--w-medium);
  color: var(--stamp);
}
.cr-list {
  margin: 0;
  padding-left: 1.1rem;
  font-size: 0.82rem;
  font-weight: var(--w-small);
  color: var(--ink-soft);
}

/* 지시서 어휘집 */
.vocab { max-height: 60vh; overflow-y: auto; }
.vocab h4 {
  margin: 1rem 0 0.4rem;
  font-size: 0.9rem;
  font-weight: var(--w-strong);
}
.vocab h4:first-child { margin-top: 0; }
.vocab-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.82rem;
}
.vocab-table th,
.vocab-table td {
  padding: 0.3rem 0.5rem;
  border-bottom: 1px solid var(--rule-soft);
  text-align: left;
  vertical-align: top;
}
.vocab-table th { font-weight: var(--w-medium); color: var(--ink-soft); }
.vocab-table td:first-child {
  white-space: nowrap;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.78rem;
}

/* 발주처 화면의 '납품서류 서식' 고르기 */
.form-picks {
  list-style: none;
  margin: 0 0 0.3rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.form-pick {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}
.form-pick label {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  cursor: pointer;
}
.fp-name { font-size: 0.88rem; font-weight: var(--w-medium); }
.fp-note {
  font-size: 0.78rem;
  font-weight: var(--w-small);
  color: var(--ink-faint);
}

/* ================================================================ 납품서류
   서식을 골라 서류를 뽑는 도구. 왼쪽 고르기 / 오른쪽 요약·이력. */

.docs-page {
  display: grid;
  grid-template-columns: minmax(300px, 25rem) 1fr;
  flex: 1;
  min-height: 0;
}
@media (max-width: 900px) {
  .docs-page { grid-template-columns: 1fr; grid-template-rows: auto auto; flex: none; }
}

.docs-compose {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  padding: clamp(1rem, 2.2vw, 1.6rem);
  border-right: 1px solid var(--rule);
  background: var(--paper-deep);
  overflow-y: auto;
}
.docs-compose h2,
.docs-results h2 {
  margin: 0;
  font-family: var(--serif);
  font-weight: var(--w-title);
  font-size: 1.02rem;
}

.form-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.form-item > button {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  width: 100%;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--card);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.form-item > button:hover { border-color: var(--stamp); }
.form-item.is-current > button {
  border-color: var(--stamp);
  box-shadow: inset 3px 0 0 var(--stamp);
}
.fi-name { font-size: 0.9rem; font-weight: var(--w-medium); }
.fi-note {
  font-size: 0.78rem;
  font-weight: var(--w-small);
  color: var(--ink-faint);
}

.doc-params .set-field { margin-top: 0.5rem; }
.doc-params .set-field label { width: 6rem; flex-shrink: 0; text-align: right; }

.docs-actions { margin-top: 0.3rem; }
.docs-actions .btn { width: 100%; }

.docs-results {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  padding: clamp(1rem, 2.2vw, 1.6rem);
  overflow-y: auto;
}

.doc-summary {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--card);
}
.ds-row {
  display: flex;
  align-items: baseline;
  gap: 0.8rem;
  padding: 0.5rem 0.9rem;
  border-bottom: 1px solid var(--rule-soft);
}
.ds-row:last-child { border-bottom: none; }
.ds-key {
  width: 7rem;
  flex-shrink: 0;
  font-size: 0.82rem;
  font-weight: var(--w-small);
  color: var(--ink-soft);
}
.ds-val {
  font-size: 0.92rem;
  font-weight: var(--w-medium);
  font-variant-numeric: tabular-nums;
}

.docs-toolbar {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin-top: 0.6rem;
}

.issued-list {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.issued-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 0.9rem;
  border: 1px solid var(--rule);
  border-radius: 6px;
  background: var(--card);
}
.issued-item .spacer { flex: 1; }
.ii-main { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.ii-name { font-size: 0.9rem; font-weight: var(--w-medium); }
.ii-meta {
  font-size: 0.78rem;
  font-weight: var(--w-small);
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}

/* 파일 고르기 칸 — 기본 파일 단추는 브라우저마다 생김새가 달라서 쓰지 않는다.
   숨긴 input 을 앱의 .btn 으로 열고, 고른 파일 이름을 옆에 보여준다. */
.file-field {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex: 1;
  min-width: 0;
}
.file-name {
  font-size: 0.82rem;
  font-weight: var(--w-small);
  color: var(--ink-faint);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.file-name.is-set { color: var(--ink); font-weight: var(--w-medium); }
.fc-error { color: var(--stamp); white-space: normal; }
