/* erp2 공용 부품(24조 꼴) — 숫자 없이 토큰만. 옛 부품은 style.css 에서 차례로 옮겨 온다. 규약 knowledge/규약/디자인시스템.md 8절. */

/* 2-1. 그룹 상자 */
.groupbox {
  margin: 0 0 var(--sp-4) 0;
  border: 1px solid var(--c-line);
  border-radius: var(--r-0);
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
  background: var(--c-surface);
  box-sizing: border-box;
  min-width: 0;
}

.groupbox > legend {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  color: var(--c-text-2);
  padding: 0 var(--sp-2);
}

/* 2-1b. 안쪽 상자 — 상자 안의 작은 상자(box in box). 한 덩어리(첨부 하나 · 항목 하나)를 묶어 이웃과 가른다. */
.innerbox {
  border: var(--bw-hair) solid var(--c-line);
  border-radius: var(--r-2);
  padding: var(--sp-2);
  background: var(--c-sunken);
  box-sizing: border-box;
  min-width: 0;
}

.gb-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-2);
  min-height: var(--h-md);
}

.gb-row > label {
  width: var(--label-w);
  flex-shrink: 0;
  text-align: right;
  font-size: var(--fs-md);
  color: var(--c-text-2);
}

.gb-row > input,
.gb-row > select {
  flex: 1;
  min-width: 0;
  height: var(--h-md);
  border: 1px solid var(--c-line);
  border-radius: var(--r-1);
  padding: 0 var(--sp-3);
  font-size: var(--fs-md);
  box-sizing: border-box;
  font-family: inherit;
}

.gb-row > input[readonly] {
  background: var(--c-sunken);
}

.gb-cols {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-6);
}

/* 2-2. 상태줄 */
.statusbar {
  height: var(--h-md);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 0 var(--sp-4);
  background: var(--c-head);
  border-top: 1px solid var(--c-line);
  font-size: var(--fs-md);
  color: var(--c-text);
  white-space: nowrap;
  box-sizing: border-box;
}

.statusbar:not(.is-info):not(.is-ok):not(.is-warn):not(.is-error) {
  color: var(--c-text-2);
}

.sb-msg {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 기호는 글자 크기를 따른다 — 밀도가 바뀌어도 그대로(줄 높이만 커진다) */
.sb-ico {
  width: calc(var(--fs-md) + var(--sp-1) * 2);
  height: calc(var(--fs-md) + var(--sp-1) * 2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--c-on-dark);
  font-weight: var(--fw-bold);
  border-radius: var(--r-1);
  flex-shrink: 0;
  line-height: var(--lh-1);
  box-sizing: border-box;
}

.statusbar.is-info .sb-ico {
  background: var(--c-link);
}

.statusbar.is-ok .sb-ico {
  background: var(--c-ok);
}

.statusbar.is-warn .sb-ico {
  background: var(--c-warn);
}

.statusbar.is-error .sb-ico {
  background: var(--c-danger);
}

.sb-meta {
  margin-left: auto;
  font-size: var(--fs-sm);
  color: var(--c-text-3);
  flex-shrink: 0;
}

.statusbar.in-window {
  border-top: 1px solid var(--c-line);
  background: var(--c-sunken);
}

.modal.window .groupbox { padding: var(--sp-1) var(--sp-3) var(--sp-2); margin: 0 0 var(--sp-3); }
.modal.window .groupbox > legend { padding: 0 var(--sp-2); }
.modal.window .statusbar.in-window { margin: 0; }

/* 상태줄 · 단추 한 줄(대표님 2026-10-18) — 안내 글은 테두리 · 바탕 없이 왼쪽, 단추는 오른쪽. '안내 + 실행 단추' 자리의 표준 꼴 */
.sb-row { display: flex; align-items: center; gap: var(--sp-2); }
.sb-row > .statusbar { flex: 1 1 auto; min-width: 0; height: auto; padding: 0; border: 0; background: none; }
.sb-row > .btn { flex: none; margin-left: auto; }

/* 화면 머리줄 — SAP 제목줄 + 응용 도구줄을 한 줄로(24조 8-1). 제목 · 건수 · 찾는 칸 · Filter · 빈칸(.spacer) · 오른쪽 단추 차례 */
.page-head { position: relative; display: flex; align-items: center; gap: var(--sp-3); height: var(--h-md); margin: 0 0 var(--sp-2); min-width: 0; }   /* 줄 높이는 머리 줄이 정한다 — 제목 글자 · 단추가 줄을 키우지 않는다(대표님 2026-10-31 "텍스트 따위가 왜 공간을 점유하냐") */
.page-head > .win-id { display: none; }   /* 화면 이름표는 제목 툴팁으로(창-17 과 같은 꼴, 대표님 2026-10-31 "타이틀에 넣어라") — 마크업은 남김 */
.page-head > .page-lock { display: inline-flex; align-items: center; margin: 0; }
.page-title { margin: 0; font-size: var(--fs-2xl); line-height: var(--h-md); font-weight: var(--fw-semi); white-space: nowrap; }
@media (min-width: 701px) {   /* 폰은 손가락 크기(style.css --h-touch) 그대로 */
  .page-head :is(.search-input, .btn, .lock-btn), .page-head .btn.btn-toggle.filter-chip { height: var(--h-md); min-height: var(--h-md); box-sizing: border-box; }   /* 머리 줄 칸 · 단추 · 거르개 칩 높이 한 벌 */
  .page-head .btn-icon { width: var(--h-md); min-width: var(--h-md); }
}
.page-head :is(.btn-secondary, .lock-btn):not(.on):not(.held) { background: var(--c-surface); border: var(--bw-hair) solid var(--c-line); }   /* 머리 줄 바탕 단추 색 한 벌 = 찾는 칸과 같은 흰 바탕 · 옅은 테(대표님 2026-10-31 "색상차이 왜나는거냐") */
.page-count { color: var(--c-text-2); font-size: var(--fs-md); white-space: nowrap; }
:where(.search-frame) .search-input { width: calc(var(--label-w) * 10 / 3); max-width: 100%; }   /* 찾기칸 기본 폭 — 검색틀 안 폼 없이 든 칸만(폼 안 칸은 .search-frame > .search-form 이 정함). 검색틀 밖 · 모듈이 폭을 정한 칸엔 안 걸리게 :where 로 힘 0 조상(24-42z5c · 검수 B1 2026-10-29) */
.page-head .search-form { flex: 0 1 var(--search-w); min-width: 0; margin: 0; }
.page-head .search-input { width: 100%; max-width: none; }
.page-head .spacer { flex: 1 1 auto; }
.page-head .fn-list { right: 0; left: auto; }
.page-head .live-line { margin-left: var(--sp-2); }
.page-head > form { margin: 0; }
.page-sub { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-sm); color: var(--c-text-2); }   /* 제목 곁글은 제목 줄 안 한 줄(대표님 2026-10-31 "한줄로 되는걸 왜 두줄로") — 경로 · 출처는 tip 으로 툴팁에만 */
@media (max-width: 700px) {
  .page-head { flex-wrap: wrap; height: auto; min-height: var(--h-md); }
  .page-head .search-form { flex: 1 1 100%; order: 5; }
  .page-head .btn { white-space: nowrap; }
}

/* 칸 배치 — 상자 안 2칸 격자(24조 · 설계_칸배치). 기본은 한 줄, .fr-half 만 반 줄 */
.gb-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--sp-6); }
.gb-grid > * { grid-column: 1 / -1; min-width: 0; }
.gb-grid > .fr-half { grid-column: auto / span 1; }
@media (max-width: 700px) { .gb-grid > .fr-half { grid-column: 1 / -1; } }


/* ===== 규약 3-1 화면 꼴 규칙 일곱의 공용 부품 (대표님 2026-10-09 구매 화면 지적) =====
   바탕 규칙은 :where() 로 특이도 0 — 모듈 · 옛 규칙이 정한 것은 그대로 이기고, 아무도 안 정한 칸만 erp2 꼴을 받는다. */

/* ② 입력칸 한 꼴 — 표 안 칸도 브라우저 기본 꼴(검은 안쪽 테두리)이 남지 않게 */
:where(input:not([type=checkbox], [type=radio], [type=file], [type=hidden], [type=range], [type=color], [type=submit], [type=button], [type=image], [type=reset]), select, textarea) {
  box-sizing: border-box; height: var(--h-md); padding: 0 var(--sp-3);
  border: 1px solid var(--c-line); border-radius: var(--r-1);
  background: var(--c-surface); color: inherit; font: inherit; font-size: var(--fs-md);
}
:where(textarea) { height: auto; padding: var(--sp-2) var(--sp-3); }
:where(input, select, textarea):focus { outline: none; border-color: var(--c-link); }

/* ③ 보기 = 글자 — 보기 상태에서는 잠긴 입력칸 대신 이것으로 값을 그린다(높이는 입력칸과 같아 틀이 안 움직인다) */
.view-value { display: flex; align-items: center; min-height: var(--h-md); min-width: 0; font-size: var(--fs-md); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.view-value:empty::before { content: "—"; color: var(--c-text-3); }

/* ④ 단추 한 높이 — <a> · <button> · 폼 안 단추가 한 줄에서 같다. 높이는 style.css .btn(--h-md) · .btn-small(--h-sm) 그대로 */
:where(.btn) { display: inline-flex; align-items: center; justify-content: center; vertical-align: middle; text-decoration: none; white-space: nowrap; }
:where(.btn[hidden]) { display: none; }
.btn-form { display: inline-flex; align-items: center; margin: 0; }

/* ⑤ 숫자 칸 — 오른쪽 맞춤 · 자릿수 고정폭(표시는 |won · |qty 필터) */
.num, .grid .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }   /* 표 칸 규칙(.grid td)보다 앞서게 */

/* ① 층위는 선 굵기 · 진하기로 — 본보기 8116 전표 화면(대표님 "메인전표 '안에' 포함된 연결전표 & 첨부, 메인전표에 '부속'된 부속전표").
   **단일 전표는 상자 없이**(8129 꼴: .view-head + .kv-grid + 표) — 깔끔. **전표 안에 전표가 들 때만** 메인을 .sheet 로 감싼다(8116 꼴) — 겹치면 구분이 먼저.
   .sheet      메인 상자 — 진한 테두리. 안: 머리띠(.view-head) → 본문(groupbox) → 소제목(.view-sec) + 표
   .sheet-zone 메인 상자 **안의** 구역 — 점선 위 줄 뒤에 연결 전표 · 첨부(같은 상자 안)
   .sheet-sub  부속 상자 — 메인 아래, 연한 테두리 · 왼쪽 끝은 메인과 같거나 안쪽(바깥으로 나가지 않는다). 제목은 .view-sec */
/* 모서리는 직각 — 대표님 2026-10-09 "8116 은 너무 둥글둥글" */
.sheet { border: var(--bw-main) solid var(--c-line-strong); border-radius: var(--r-0); padding: var(--sp-3) var(--sp-4); background: var(--c-surface); min-width: 0; }
.sheet-zone { border-top: var(--bw-main) dotted var(--c-line); margin-top: var(--sp-4); padding-top: var(--sp-3); }
.sheet-sub { border: var(--bw-sub) solid var(--c-line); border-radius: var(--r-0); padding: var(--sp-3) var(--sp-4); margin-top: var(--sp-4); background: var(--c-surface); min-width: 0; }
.sheet-sub > .view-sec:first-child { margin-top: 0; }

/* ===== 한 건 보기 칸(오른쪽 보기 판 · 상세) 제목 두 단 — 대표님 2026-10-09 "메인 타이틀에 대한 층위가 약해보인다"
   차례: [메인 타이틀 줄] → 관련 본문 → [소제목 줄(첨부파일 …)] → 올리기 칸 → 관련 목록.
   층위는 글자 크기 · 굵기 · 선 굵기로(바탕색으로 가르지 않는다, 3-1 ①): 제목 16 굵게 + 아래 1.5 검정 선 / 소제목 13 굵게 + 아래 1 회색 선 / 본문 12 */
.view-head { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; min-height: var(--h-lg);
  padding-bottom: var(--sp-3); margin-bottom: var(--sp-4); border-bottom: var(--bw-head) solid var(--c-line-strong); }
.view-title { margin: 0; font-size: var(--fs-2xl); font-weight: var(--fw-bold); color: var(--c-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.view-meta { color: var(--c-text-2); font-size: var(--fs-md); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.view-head .spacer, .view-sec .spacer { flex: 1 1 auto; }
.view-sec { display: flex; align-items: center; gap: var(--sp-3); min-height: var(--h-md);
  margin: var(--sp-6) 0 var(--sp-3); padding-bottom: var(--sp-1); border-bottom: 1px solid var(--c-line); }
.view-sec-title { margin: 0; font-size: var(--fs-lg); font-weight: var(--fw-semi); color: var(--c-text); white-space: nowrap; }
.view-sec:first-child { margin-top: 0; }

/* 이름표 · 값 칸(보기 = 글자, 규약 3-1 ③) — 본보기 8129 견적서 보기 칸. 한 줄에 이름표 · 값 두 쌍, 폰은 한 쌍.
   <div class="kv-grid"><div class="kv-f"><label>견적일</label><span>2026-10-07</span></div> … </div> */
.kv-grid { display: grid; grid-template-columns: max-content minmax(0, 1fr) max-content minmax(0, 1fr);
  border-top: 1px solid var(--c-line); border-left: 1px solid var(--c-line); margin: var(--sp-2) 0 var(--sp-3); font-size: var(--fs-md); }
.kv-f { display: contents; }
.kv-f > label, .kv-f > span { display: flex; align-items: center; min-height: var(--h-lg); padding: 0 var(--sp-4); min-width: 0;
  border-right: 1px solid var(--c-line); border-bottom: 1px solid var(--c-line); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kv-f > label { background: var(--c-head); color: var(--c-text-2); font-weight: var(--fw-normal); }
.kv-f.kv-wide > label { grid-column: 1; }   /* 넓은 칸은 늘 새 줄 첫 칸부터 — 앞 칸 수가 홀수면 이름표만 오른쪽에 남고 값이 다음 줄로 떨어졌다 */
.kv-f.kv-wide > span { grid-column: span 3; }
@media (max-width: 700px) { .kv-grid { grid-template-columns: max-content minmax(0, 1fr); } .kv-f.kv-wide > span { grid-column: auto; } }

/* 상세 표(명세 줄) — 규약 목록과창 10절 · 동작은 app.js 상세 표. 번호 칸 · ⊕ 끼우기 · 줄을 누르면 단추줄([삭제][↑][↓]) */
.dg-bar { display: flex; align-items: center; gap: var(--sp-2); min-height: var(--h-md); margin: var(--sp-2) 0; visibility: hidden; }
.dg-bar.on { visibility: visible; }
.dg-btn { display: inline-flex; align-items: center; justify-content: center; width: var(--h-md); height: var(--h-md); padding: 0; border: 1px solid var(--c-line); border-radius: 0; background: var(--c-surface); color: var(--c-text); cursor: pointer; }
.dg-btn:hover { background: var(--c-hover); }
.dg-btn > svg { width: var(--fs-xl); height: var(--fs-xl); }
@media (max-width: 700px) { .dg-btn { width: var(--h-touch); height: var(--h-touch); } }  /* 폰은 단추 크게 — 줄 차례 [↑][↓] · [+] · [삭제] 같이 */
.dgrid .dg-no { display: inline-flex; align-items: center; justify-content: center; min-width: var(--h-sm); height: var(--h-sm); padding: 0 var(--sp-1); box-sizing: border-box; border: 1px solid var(--c-line); color: var(--c-text-2); font-size: var(--fs-sm); background: var(--c-surface); }
.dgrid tr.is-sel > td { background: var(--c-selected); }
.dgrid tr.is-sel .dg-no { border-color: var(--c-primary); color: var(--c-primary); }   /* 누른 줄 — 테두리만 */
.dgrid tr.is-chk .dg-no, .dgrid thead [data-dg="all"].is-chk { background: var(--c-primary); border-color: var(--c-primary); color: var(--c-on-dark); }   /* 체크한 줄 — 번호 칸을 칠한다(체크 칸 대신) */
.dgrid tr.is-del > td { opacity: .45; text-decoration: line-through; }
.dgrid tbody.fs-list tr.fs-item { cursor: pointer; }
.dgrid .dg-delbox { display: none; }
.dgrid .dg-c-ins { width: 3ch; text-align: center; }
.dgrid .dg-ins { display: inline-flex; align-items: center; justify-content: center; width: var(--h-sm); height: var(--h-sm); padding: 0; border: 0; border-radius: var(--r-round); background: var(--c-primary); color: var(--c-on-dark); font-size: var(--fs-lg); line-height: 1; cursor: pointer; }
.dgrid .dg-ins:hover { background: var(--c-primary-hover); }

/* 상세 표 — 고르기 체크 · 일괄변경(규약 목록과창 10절) */
.dgrid .dg-no, .dgrid thead [data-dg="all"] { cursor: pointer; user-select: none; }
.dg-bulk-on { display: inline-flex; align-items: center; gap: var(--sp-1); margin-left: var(--sp-4); font-size: var(--fs-md); color: var(--c-text); cursor: pointer; }
.dg-bulk { display: inline-flex; align-items: center; gap: var(--sp-2); }
.dg-bulk[hidden] { display: none; }
.dg-bulk-field { height: var(--h-md); border: 1px solid var(--c-primary); border-radius: 0; padding: 0 var(--sp-2); font-size: var(--fs-md); font-family: inherit; background: var(--c-surface); }
.dg-bulk-modes { display: inline-flex; }
.dg-bulk-modes[hidden] { display: none; }
.dg-mode { height: var(--h-md); padding: 0 var(--sp-3); border: 1px solid var(--c-line); margin-left: -1px; border-radius: 0; background: var(--c-surface); color: var(--c-text); font-size: var(--fs-md); font-family: inherit; cursor: pointer; }
.dg-mode.on { background: var(--c-head); font-weight: var(--fw-semi); }
.dg-bulk-val { width: 15em; height: var(--h-md); box-sizing: border-box; border: 1px solid var(--c-line); border-radius: 0; padding: 0 var(--sp-2); font-size: var(--fs-md); font-family: inherit; }
.dg-bulk-val.is-num { text-align: right; }
.dg-btn:disabled { opacity: .35; cursor: default; background: var(--c-surface); }   /* [+] — 여러 줄을 체크하면 잠김 */
table.dgrid tbody.fs-list tr.fs-item:not(.is-sel) input:not([type=checkbox]):not([type=hidden]),
table.dgrid tbody.fs-list tr.fs-item:not(.is-sel) select,
table.dgrid tbody.fs-list tr.fs-item:not(.is-sel) textarea { border-color: transparent; background: transparent; box-shadow: none; cursor: default; }
table.dgrid tbody.fs-list tr.fs-item:not(.is-sel) .lookup-find,
table.dgrid tbody.fs-list tr.fs-item:not(.is-sel) .datebox-btn { visibility: hidden; }
.dg-sum td { font-weight: var(--fw-bold); background: var(--c-head); border-top: var(--bw-head) solid var(--c-line-strong); }


/* 날짜 칸 달력 (필드값-013) */
.datebox { display: inline-flex; align-items: stretch; }
.datebox > input { border-top-right-radius: var(--r-0); border-bottom-right-radius: var(--r-0); }
.datebox-btn { display: inline-flex; align-items: center; justify-content: center; padding: 0 var(--sp-2); border: 1px solid var(--c-line); border-left: none; border-radius: var(--r-0); background: var(--c-head); color: var(--c-text-2); cursor: pointer; box-sizing: border-box; }
.datebox-btn:hover { background: var(--c-hover); }
.datebox-btn:disabled { opacity: .35; cursor: default; }
.datebox-btn > svg { display: block; }

.air-datepicker {
  --adp-font-family: var(--font-sans);
  --adp-font-size: var(--fs-md);
  /* 촘촘하게(대표님 2026-10-10 "크기도 너무 커 좀더 압축해") — 칸 26 × 7 + 여백 */
  --adp-width: calc(var(--h-xl) * 7 + var(--sp-2) * 2);
  --adp-padding: var(--sp-2);
  --adp-nav-height: var(--h-lg);
  --adp-nav-action-size: var(--h-lg);
  --adp-day-cell-width: var(--h-xl);
  --adp-day-cell-height: var(--h-md);
  --adp-month-cell-height: var(--h-xl);
  --adp-year-cell-height: var(--h-xl);
  --adp-btn-height: var(--h-lg);
  --adp-accent-color: var(--c-primary);
  --adp-border-radius: var(--r-0);
  --adp-cell-border-radius: var(--r-0);
  --adp-btn-border-radius: var(--r-0);
  --adp-border-color: var(--c-line-strong);
  --adp-border-color-inner: var(--c-line);
  --adp-day-name-color: var(--c-text-2);
  --adp-color: var(--c-text);
  --adp-color-secondary: var(--c-text-2);
  --adp-color-other-month: var(--c-text-3);
  --adp-background-color: var(--c-surface);
  --adp-cell-background-color-hover: var(--c-hover);
  --adp-cell-background-color-selected: var(--c-primary);
  --adp-cell-background-color-selected-hover: var(--c-primary-hover);
  --adp-color-current-date: var(--c-primary);
  --adp-background-color-hover: var(--c-hover);
  --adp-background-color-active: var(--c-selected);
  --adp-btn-color: var(--c-primary);
  --adp-btn-color-hover: var(--c-primary-hover);
  --adp-btn-background-color-hover: var(--c-hover);
  --adp-btn-background-color-active: var(--c-selected);
}

.air-datepicker-cell.-weekend- { color: var(--c-danger); }
/* 토요일 파랑(대표님 2026-10-14) — 한 주가 일요일부터(firstDay 0)라 일곱째 칸. 날짜 칸 달력과 조회범위 달력이 같이 쓴다. 고른 칸 · 다른 달 칸은 제 색 그대로 */
.air-datepicker-body--day-names .air-datepicker-body--day-name:nth-child(7n) { color: var(--c-primary); }
.air-datepicker-body--cells.-days- .air-datepicker-cell:nth-child(7n):not(.-selected-):not(.-other-month-) { color: var(--c-primary); }
.air-datepicker--pointer { display: none; }  /* 위 · 아래로 뒤집혀 펴지므로 꼭지는 두지 않는다 */
.datebox-today { font-weight: var(--fw-bold); }

/* 조회범위 (필드값-019) — common/period.py · templates/_period.html · app.js wirePeriods. 범위 + 달력 · 간편검색 한 줄, 안 들어가는 좁은 폭에서만 다음 줄로(대표님 2026-10-25) */
.prd { display: inline-flex; flex: none; flex-direction: row; flex-wrap: wrap; align-items: center; column-gap: var(--sp-3); row-gap: var(--sp-2); max-width: 100%; vertical-align: middle; }
.prd-row, .prd-end, .prd-quick { display: inline-flex; align-items: center; }
.prd-row { flex-wrap: wrap; gap: var(--sp-1); }   /* 좁은 판 · 큰 글자에선 끝 날짜가 다음 줄로(2026-10-25) */
.prd-end { gap: var(--sp-1); }
.prd-quick { flex-wrap: wrap; gap: var(--sp-2); }
.prd-mode { display: inline-flex; align-items: center; height: var(--h-sm); padding: 0 var(--sp-3); margin-right: var(--sp-2); background: var(--c-selected); color: var(--c-primary); font-size: var(--fs-sm); font-weight: var(--fw-semi); white-space: nowrap; }
.prd .prd-y, .prd .prd-m, .prd .prd-d, .prd-pop .prd-y, .prd-pop .prd-m { box-sizing: border-box; height: var(--h-md); padding: 0 var(--sp-1); border: 1px solid var(--c-line); border-radius: var(--r-1); background: var(--c-surface); color: var(--c-text); font-family: inherit; font-size: var(--fs-md); }
.prd .prd-y, .prd-pop .prd-y { width: auto; } /* 제 글자 폭 + 화살표 — 고정 ch 는 화살표를 못 세 "2026" 이 잘림(대표님 2026-10-25) */
.prd .prd-m, .prd-pop .prd-m { width: auto; }
.prd .prd-d { width: calc(2ch + 2 * var(--sp-1) + 2 * 1px); text-align: center; }
.prd-sep, .prd-tilde { color: var(--c-text-2); padding: 0 var(--sp-1); }
.prd .prd-cal { height: var(--h-md); margin-left: var(--sp-2); border-left: 1px solid var(--c-line); }
.prd-pop { position: fixed; z-index: 10000; display: flex; flex-wrap: wrap; max-width: 100vw; background: var(--c-surface); border: 1px solid var(--c-line-strong); }
.prd-pane { display: flex; flex-direction: column; }
.prd-pane + .prd-pane { border-left: 1px solid var(--c-line); }
.prd-nav { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-2) var(--sp-2) 0; }
.prd-nav .prd-y { flex: 1 1 auto; }
.prd-pop .btn.prd-arrow { justify-content: center; width: var(--h-md); padding: 0; font-size: var(--fs-xl); }
.prd-pop .air-datepicker { border: 0; --adp-cell-background-color-in-range: var(--c-selected); --adp-cell-background-color-in-range-hover: var(--c-hover); --adp-cell-border-color-in-range: var(--c-primary); }
.prd-foot { display: flex; padding: 0 var(--sp-2) var(--sp-2); }
.prd-foot .dbx-today { padding: 0 var(--sp-4); }

/* 표에서 바로 입력(common/inline.py) */
.inline-pane { display: flex; flex-direction: column; height: 100%; }
.inline-pane .view-head { padding: var(--sp-4) var(--sp-6); border-bottom: var(--bw-hair) solid var(--c-line); margin-bottom: 0; }
.inline-body { flex: 1 1 auto; overflow: auto; padding: var(--sp-6); }

.inline-group-box { margin-bottom: var(--sp-7); }
.inline-group-head { display: flex; align-items: center; gap: var(--sp-3); min-height: var(--h-md); }
.inline-group-head-form { display: flex; align-items: center; gap: var(--sp-3); }
.inline-group-input { max-width: calc(var(--sp-8) * 10); }

.inline-new-group { display: flex; gap: var(--sp-4); align-items: center; padding: var(--sp-4); border: var(--bw-hair) dashed var(--c-primary); margin-bottom: var(--sp-6); }
.inline-new-group-label { font-weight: var(--fw-semi); font-size: var(--fs-lg); }

.inline-table { width: 100%; border-collapse: collapse; margin: 0; }
.inline-table th, .inline-table td { padding: var(--sp-3) var(--sp-4); }
.inline-table thead tr { background: var(--c-head); border-bottom: var(--bw-hair) solid var(--c-line); text-align: left; }
.inline-table thead th { font-size: var(--fs-sm); color: var(--c-text-2); font-weight: var(--fw-semi); }
.inline-table tbody tr { border-bottom: var(--bw-hair) solid var(--c-line); }

.inline-col-grip { width: var(--h-xl); }
.inline-col-act { width: calc(var(--h-xl) * 8); }   /* 고치는 줄의 [그룹][저장][취소][삭제] 가 다 보이게 — 좁으면 [취소] 가 잘려 빈 줄을 [저장] 으로만 닫게 됐다(2026-10-11) */
.inline-table.has-check .inline-col-act { width: calc(var(--h-xl) * 10); }   /* 확인 칩 + [로그인확인] [수정] 이 한 줄에 */

.inline-cell-grip { text-align: center; }
.inline-cell-act { text-align: center; white-space: nowrap; }
.inline-table td.inline-cell-act { overflow: visible; }
/* 확인 칩(예: 로그인 확인 날짜) — 잠겨 있어도 보인다. [로그인확인] 단추는 lock-act 라 풀었을 때만(대표님 2026-10-11) */
/* [상태] 한 칸 = 칩이자 단추 — 잠겨 있으면 글자만(누를 수 없음), 풀면 [로그인 확인 / 날짜] 단추(대표님 2026-10-11) */
.btn.inline-check { display: inline-flex; flex-direction: column; align-items: flex-start; justify-content: center; vertical-align: middle;
  height: auto; min-height: var(--h-sm); line-height: var(--lh-1); gap: var(--sp-1); padding: var(--sp-1) var(--sp-3);
  font-size: var(--fs-sm); white-space: nowrap; margin-right: var(--sp-3);
  background: var(--c-surface); color: var(--c-primary); border: var(--bw-hair) solid var(--c-primary); }
@media (max-width: 700px) { .btn.inline-check { min-height: var(--h-touch); } }  /* 폰은 손가락 높이(폰-04) */
.btn.inline-check:hover { background: var(--c-hover); }
/* 줄 수정 칸의 그룹 고르기 — 고르고 [저장] 하면 그 그룹으로 옮겨진다 */
.inline-group-pick { height: var(--h-sm); max-width: calc(var(--h-xl) * 4); margin-right: var(--sp-2); font-size: var(--fs-sm); }
/* 비밀번호 칸 눈 단추(app.js · input[data-reveal]) */
.pw-wrap { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; width: 100%; }
.pw-wrap > input { flex: 1 1 auto; min-width: 0; }
.pw-reveal { flex: none; padding: 0 var(--sp-2); }
.btn.pw-reveal.on { background: var(--c-selected); color: var(--c-primary); border-color: var(--c-primary); }   /* 켜짐 = 연한 파랑 바탕 + 파란 눈(공용 .btn.on 의 진한 바탕이면 눈이 안 보임) */
.inline-pane:not(.is-edit) .btn.inline-check { background: transparent; border-color: transparent; color: var(--c-text-2); pointer-events: none; }
.inline-pane:not(.is-edit) .btn.inline-check .inline-check-date { color: var(--c-text); }
.inline-pane:not(.is-edit) .btn.inline-check.is-none .inline-check-date { color: var(--c-text-3); }

.inline-grip { cursor: grab; user-select: none; text-align: center; color: var(--c-text-3); }
.inline-grip:active { cursor: grabbing; }

.inline-row-edit { background: var(--c-note-bg); }
/* 고쳤는데 저장 안 한 칸 — 노랑 바탕 + 주황 테두리(대표님 2026-10-30), 표시는 assets/app/live.js markUnsaved */
:is(input, select, textarea).is-unsaved, .modal.window :is(input, select, textarea).is-unsaved { background: var(--c-note-bg); border-color: var(--c-warn); }
.inline-err { color: var(--c-danger); font-size: var(--fs-sm); margin-top: var(--sp-1); }

.sortable-ghost { opacity: .4; background: var(--c-selected); }
/* 끌기 손잡이 :: (디자인시스템 3-2 "끌어 옮기기") — 수정모드(.is-edit)에서만 보인다. 잠기면 숨고 끌기도 꺼진다(app.js ErpDrag) */
/* 트리 층위(디자인시스템 3-2 "트리 층위", 2026-10-11 "층위가 구분이 잘 안돼") — 분류 머리 = 회색 띠 · 굵은 진한 글씨 · 위아래 줄,
   그 아래 줄 = 들여쓰기 + 왼쪽 안내선(같은 분류 안이라는 표시). 고른 줄(.active · .on)은 파랑 채움 그대로. */
.tree-cap { display: flex; align-items: center; gap: var(--sp-2); min-height: var(--h-md); padding: 0 var(--sp-4); margin-top: var(--sp-3); background: var(--c-head); border-top: 1px solid var(--c-line); border-bottom: 1px solid var(--c-line); color: var(--c-text); font-size: var(--fs-md); font-weight: var(--fw-bold); }
.tree-cap:first-child { margin-top: 0; }
.tree-sub { margin-left: var(--sp-4); border-left: var(--bw-head) solid var(--c-line); border-radius: 0 var(--r-1) var(--r-1) 0; }
.tree-sub.active, .tree-sub.on { border-left-color: var(--c-primary); }
.tree-item { display: flex; justify-content: space-between; padding: var(--sp-2) var(--sp-4); border-radius: var(--r-2); color: inherit; text-decoration: none; font-size: var(--fs-lg); }
.tree-item:hover { background: var(--c-head); }
.tree-item.active { background: var(--c-primary); color: var(--c-on-dark); font-weight: var(--fw-semi); }
.drag-grip { display: none; align-items: center; justify-content: center; width: var(--h-sm); height: var(--h-sm); color: var(--c-text-3); cursor: grab; user-select: none; touch-action: none; flex: none; }
.is-edit .drag-grip { display: inline-flex; }
[data-edit-scope]:not(.is-edit) .lock-act { display: none !important; }   /* 자물쇠에 묶인 단추는 잠겨 있으면 숨김(디자인시스템 3-2) */
[data-lock-upload]:not(.is-edit) :is([data-upload-pick], .cards-add-btn, .card-del, .card-retry-btn, .veh-odo-save) { display: none !important; }   /* 차량정보 — 잠기면 올리기 · 추가 · 파일 삭제 · 다시 읽기 · 주행거리 저장 숨김(대표님 2026-10-24, 저장-01 · 06) */
[data-lock-upload]:not(.is-edit) .veh-odo-form .odo-widget { pointer-events: none; }   /* 잠기면 주행거리 숫자도 못 돌린다 */
/* 표에서 바로 입력의 줄 단추([로그인확인] [수정])는 잠겨 있어도 흐린 채 자리를 지킨다 — 풀면 살아난다(대표님 2026-10-11) */
.inline-pane[data-edit-scope]:not(.is-edit) .inline-cell-act .lock-act { display: inline-flex !important; opacity: .4; pointer-events: none; cursor: default; }
[data-edit-scope]:not(.is-edit) .scope-ro :is(input,select,textarea) { pointer-events: none; background: transparent; border-color: transparent; }
[data-edit-scope]:not(.is-edit) .scope-ro .dropzone, [data-edit-scope]:not(.is-edit) .scope-ro .file-x { display: none !important; }
.drag-grip:hover { color: var(--c-primary); }
.drag-grip:active { cursor: grabbing; }
@media (max-width: 700px) { .is-edit .drag-grip { width: var(--h-touch); height: var(--h-touch); } }

/* 트리 표(단 칸) 공용 꼴 */
tr.tt-sep > td { border-top: var(--bw-head) solid var(--c-line-strong); }
.tt-code-old { text-decoration: line-through; opacity: .5; }
.tt-code-arrow { color: var(--c-primary); font-weight: var(--fw-bold); }
.tt-code { white-space: nowrap; }
.sortable-chosen { background: var(--c-hover); }

/* 트리 표 가지 선 */
table td.tt-cell {
  position: relative;
  padding-left: var(--sp-3); /* 선 x 계산의 기준 — 표마다 다른 칸 여백을 한 값으로 */
  --tt-half: 0.45em; /* 한글 1글자 너비(≈0.9em)의 절반으로 부모 이름 글자 가운데 밑을 가리킨다 */
}
.tt-x-1 { --tt-n: 1; } .tt-x-2 { --tt-n: 2; } .tt-x-3 { --tt-n: 3; } .tt-x-4 { --tt-n: 4; } .tt-x-5 { --tt-n: 5; } .tt-x-6 { --tt-n: 6; } .tt-x-7 { --tt-n: 7; } .tt-x-8 { --tt-n: 8; } .tt-x-9 { --tt-n: 9; } .tt-x-10 { --tt-n: 10; } .tt-x-11 { --tt-n: 11; } .tt-x-12 { --tt-n: 12; }

td.tt-cell.tt-g-mid::before,
td.tt-cell.tt-g-pipe::before,
td.tt-cell.tt-g-end::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--sp-3) + var(--tt-n, 1) * var(--tt-half));
  border-left: var(--bw-hair) solid var(--c-line);
  pointer-events: none;
}
td.tt-cell.tt-g-end::before {
  bottom: auto;
  height: 50%;
}

td.tt-cell.tt-g-mid::after,
td.tt-cell.tt-g-end::after,
td.tt-cell.tt-g-dash::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0;
  border-top: var(--bw-hair) solid var(--c-line);
  pointer-events: none;
}
td.tt-cell.tt-g-mid::after,
td.tt-cell.tt-g-end::after {
  left: calc(var(--sp-3) + var(--tt-n, 1) * var(--tt-half));
}
td.tt-cell.tt-g-dash::after {
  left: 0;
}

/* 올려채운 줄 수평 가지 선 (대표님 2026-10-22) — 이름 끝에서 칸 오른쪽 끝까지, 칸 밖은 overflow 로 잘림 */
td.tt-cell.tt-g-up { overflow: hidden; }
td.tt-cell.tt-g-up .tt-up-name { position: relative; }
td.tt-cell.tt-g-up .tt-up-name::after {
  content: "";
  position: absolute;
  top: 50%;
  left: calc(100% + var(--sp-2));
  width: 100vw;
  border-top: var(--bw-hair) solid var(--c-line);
  pointer-events: none;
}
/* 칸 왼쪽 끝 → 이름 앞 */
td.tt-cell.tt-g-in::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: calc(var(--sp-3) - var(--sp-1));
  border-top: var(--bw-hair) solid var(--c-line);
  pointer-events: none;
}

.inline-pane .btn:disabled { opacity: .5; cursor: not-allowed; pointer-events: none; }
.inline-pane tr.is-pending { background: var(--c-selected); }
.inline-table td.inline-ellipsis { max-width: calc(var(--sp-9) * 7); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 달력 연 · 월 빠른 고르기 (대표님 2026-10-10) */
.air-datepicker--navigation { display: none; }  /* "< 2026년 10월 >" 줄은 칸 낭비 — 연 · 월 빠른 줄이 대신한다(대표님 2026-10-11) */
.dbx-quick { display: flex; gap: var(--sp-3); align-items: flex-start; padding: var(--sp-2) var(--sp-2) 0; }
.dbx-year { height: var(--h-md); font-size: var(--fs-md); padding: 0 var(--sp-2); }
.dbx-side { display: flex; flex-direction: column; gap: var(--sp-1); }
.dbx-today { height: var(--h-sm); padding: 0; border: 1px solid var(--c-primary); background: var(--c-surface); color: var(--c-primary); font-size: var(--fs-sm); border-radius: var(--r-0); cursor: pointer; }
.dbx-today:hover { background: var(--c-hover); }
.air-datepicker.-is-mobile- .dbx-today { height: var(--h-touch); font-size: var(--fs-lg); }
.dbx-months { display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--sp-1); flex: 1; }
.dbx-month { height: var(--h-sm); padding: 0; border: 1px solid var(--c-line); background: var(--c-surface); font-size: var(--fs-sm); border-radius: var(--r-0); cursor: pointer; }
.dbx-month:hover { background: var(--c-hover); }
.dbx-month.on { background: var(--c-primary); color: var(--c-on-dark); border-color: var(--c-primary); }
.air-datepicker.-is-mobile- .dbx-month { height: var(--h-touch); }
.air-datepicker.-is-mobile- .dbx-year { height: var(--h-touch); font-size: var(--fs-2xl); }

/* 폰(700px 아래) 달력 바텀시트 꼴 (조항 폰-05) */
@media (max-width: 700px) {
  .air-datepicker.-is-mobile- {
    position: fixed !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    top: auto !important;
    width: 100vw !important;
    max-width: 100vw !important;
    box-sizing: border-box;
    border-radius: var(--r-0);
    border-top: var(--bw-hair) solid var(--c-line);
    z-index: 1000;
  }
  .air-datepicker.-is-mobile-:not(.-custom-position-) {
    transform: translateY(100%) !important;
  }
  .air-datepicker.-is-mobile-.-active-:not(.-custom-position-) {
    transform: translateY(0) !important;
  }
}

/* 공용 잠금 부품 (디자인시스템 규약) */
.lock-btn { display: inline-flex; align-items: center; justify-content: center; }
.lock-btn .lock-icon { display: block; }
.lock-btn .lk-open { display: none; }
.lock-btn.on .lk-open { display: inline; }
.lock-btn.on .lk-shut { display: none; }
.lock-btn.on { background: var(--c-primary); border-color: var(--c-primary); color: var(--c-on-dark); }
.lock-btn.held { color: var(--c-danger); border-color: var(--c-danger); }

/* ---------------- 코드칸 (lookup) ---------------- */
/* 여러 명 코드칸 — 고른 사람만 칩으로 표시한다. */
.lookup-multi { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1); min-height: var(--h-md); max-width: 100%; padding: 0 var(--sp-1); border: var(--bw-hair) solid var(--c-line); border-radius: var(--r-1); background: var(--c-surface); }
.lookup-multi > input:not([name]) { flex: 1; width: var(--label-w); min-width: 6em; border: 0; background: transparent; }
.lookup-multi .chip { display: inline-flex; align-items: center; gap: var(--sp-1); padding: 0 var(--sp-1); border-radius: var(--r-1); background: var(--c-head); }
.lookup-multi .chip button { border: 0; padding: 0; min-height: 0; height: auto; background: transparent; color: inherit; cursor: pointer; }
.lookup-box { display: inline-flex; align-items: stretch; gap: 0; }   /* 돋보기 · 칸이 맞붙어 테두리가 이어지게 — style.css 의 gap 이 틈을 냈다(대표님 2026-10-10) */
.lookup-box > .lookup-name { margin-left: var(--sp-2); align-self: center; }
/* 맞춘 코드칸(대표님 2026-10-11 "룩업 매칭되면 사업자번호 / 표시방식 따로 표시하지말고 전체 필드박스에 표시방식만") —
   칸에는 출처의 보이는 꼴(거래처 `상호(사업자번호) 대표자` …)만 칸 가득, 코드는 숨은 값으로 남는다. 칸을 누르면(포커스) 코드가 보여 고칠 수 있다.
   딸린 칸이 있는 코드칸(품목코드 → 품목명 · 규격)은 이름을 딸린 칸이 보이므로 코드를 보이고 꼬리를 숨긴다 */
.lookup-box { position: relative; }
.lookup-box.is-matched:not(:focus-within):not(:has(input[data-lookup-fill])) input[data-lookup] { color: transparent; }
.lookup-box.is-matched:not(:focus-within):not(:has(input[data-lookup-fill])) > .lookup-name {
  position: absolute; top: 0; bottom: 0; left: var(--h-md); right: 0; margin: 0; padding: 0 var(--sp-2); max-width: none;
  display: flex; align-items: center; color: var(--c-text); overflow: hidden; white-space: nowrap; pointer-events: none; }
.lookup-box.is-matched:focus-within > .lookup-name, .lookup-box.is-matched:has(input[data-lookup-fill]) > .lookup-name { display: none; }
/* 공유 창 · 목록 실행 줄은 딸린 칸이 있어도 이름을 보인다 — 차량 코드는 속 번호(1 · 2 …)라 읽을 수 없다(24-29F) · 소방 서식 사람 칸(대표님 2026-11-01) */
:is(.fire-docform, [data-share-run-url], .sharetpl-run) .lookup-box.is-matched:not(:focus-within) input[data-lookup] { color: transparent; }
:is(.fire-docform, [data-share-run-url], .sharetpl-run) .lookup-box.is-matched:not(:focus-within) > .lookup-name {
  position: absolute; top: 0; bottom: 0; left: var(--h-md); right: 0; margin: 0; padding: 0 var(--sp-2); max-width: none;
  display: flex; align-items: center; color: var(--c-text); overflow: hidden; white-space: nowrap; pointer-events: none; }
.fire-docform .lookup-box:has(> input[name$="__free"][value="1"]) > .lookup-name { display: none; }   /* 소방 서식 좁은 칸 — [텍스트로 입력] 한 글자를 [Not matched] 꼬리가 밀어내 안 보였다(대표님 2026-11-01) */
.inplace.is-edit .kv-grid .lookup-box.is-matched > .lookup-name { padding-left: var(--sp-4); }   /* 이름표 칸 입력칸 안 여백과 같게 */
.lookup-box > .key-box, .lookup-box > input { flex: 1 1 auto; min-width: 0; }
.lookup-box input { border-top-left-radius: var(--r-0); border-bottom-left-radius: var(--r-0); }
.lookup-find {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: var(--h-md);
  height: auto;
  align-self: stretch;
  border: 1px solid var(--c-line);
  border-right: none;
  background: var(--c-surface);
  color: var(--c-text-3);
  border-radius: var(--r-0);
  cursor: pointer;
  padding: 0;
  box-sizing: border-box;
}
.lookup-find:hover {
  color: var(--c-primary);
}
.lookup-find > svg {
  display: block;
}

.lookup-bad input,
input.lookup-bad {
  border-color: var(--c-danger);
}

.lookup-win.small {
  width: calc(var(--label-w) * 5);   /* [수정] 칸 + [저장] [취소] 가 한 줄에 들어가게(대표님 2026-10-10) */
}
.lookup-win.big {
  width: calc(var(--label-w) * 8);
}
/* 폰 — 코드 고르기 창은 화면 가득 시트(app.js lookupPhone · 대표님 2026-10-11). 끌지 않고 목록만 스크롤, 찾는 칸 글자는 1rem(작으면 폰이 화면을 확대한다) */
@media (max-width: 700px) {
  .modal.window.lookup-win.lookup-sheet { position: fixed; left: 0; top: 0; right: 0; bottom: 0; width: auto; max-width: none; height: auto; max-height: none; transform: none; margin: 0; border: 0; box-shadow: none; display: flex; flex-direction: column; }
  .lookup-win.lookup-sheet .modal-header { cursor: default; }
  .lookup-win.lookup-sheet .modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }
  .lookup-win.lookup-sheet .lookup-q { font-size: 1rem; }
  .lookup-win.lookup-sheet .lookup-list { max-height: none; }
  .lookup-win.lookup-sheet .lookup-grid td { padding-top: var(--sp-3); padding-bottom: var(--sp-3); }
}
.lookup-win .modal-body {
  position: relative;
}
.lookup-win .lookup-bar {
  display: flex;
  gap: var(--sp-3);
  margin-bottom: var(--sp-2);
}
.lookup-bar .lookup-q {
  flex: 1;
  min-width: 0;
}
.lookup-win .lookup-filter-box {
  position: absolute;
  top: calc(var(--h-md) + var(--sp-4));
  left: var(--sp-4);
  right: var(--sp-4);
  z-index: 1;
}
.lookup-win .lookup-bar .lookup-manage-link {
  font-size: var(--fs-sm);
  color: var(--c-text-2);
  text-decoration: underline;
  white-space: nowrap;
  margin-left: auto;
}
.lookup-win .lookup-list {
  max-height: calc(var(--h-md) * 12);
  overflow-y: auto;
  border: 1px solid var(--c-line);
}
.lookup-win .lookup-grid {
  width: 100%;
  border-collapse: collapse;
}
.lookup-win .lookup-grid th[data-sort] {
  cursor: pointer;
  user-select: none;
}
.lookup-win .lookup-grid th[data-sort]:hover {
  background: var(--c-hover);
}
.lookup-win .lookup-grid tr.lookup-pick {
  cursor: pointer;
}
.lookup-win .lookup-grid tr.lookup-pick:hover {
  background: var(--c-hover);
}
.lookup-win .lookup-grid tr.lookup-pick.sel {
  background: var(--c-selected);
}
tr.lookup-pick.off td,
tr.lookup-pick.lookup-ctx td {
  color: var(--c-text-3);
}
.lookup-win .lookup-empty {
  text-align: center;
  color: var(--c-text-3);
  padding: var(--sp-4);
}
.lookup-win .lookup-pages {
  display: flex;
  justify-content: center;
  gap: var(--sp-1);
  padding: var(--sp-2) 0;
}
.lookup-win .lookup-page {
  min-width: var(--h-sm);
  height: var(--h-sm);
  padding: 0 var(--sp-2);
  border: 1px solid var(--c-line);
  background: var(--c-surface);
  color: var(--c-text);
  border-radius: var(--r-0);
  cursor: pointer;
  font-size: var(--fs-sm);
}
.lookup-win .lookup-page:hover {
  background: var(--c-hover);
}
.lookup-win .lookup-page.on {
  background: var(--c-primary);
  color: var(--c-on-dark);
  border-color: var(--c-primary);
}
.lookup-win .lookup-msg[hidden] { display: none; }
.lookup-win .lookup-msg {
  margin-top: var(--sp-2);
  color: var(--c-danger);
  font-size: var(--fs-sm);
}
.lookup-win .lookup-foot {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.lookup-win .lookup-spacer {
  flex: 1;
}

/* 서류 제자리 편집 (목록과창 9절) */
.inplace b.ip-ro, .inplace i.ip-rw, b.ip-ro, i.ip-rw { font-weight: inherit; font-style: normal; }
.inplace .ip-rw, .inplace .ip-rw-block, .inplace .ip-rw-rows, .inplace .ip-rw-cell { display: none; }
.inplace.is-edit .ip-ro, .inplace.is-edit .ip-ro-block, .inplace.is-edit .ip-ro-rows { display: none; }
.inplace.is-edit .ip-rw { display: inline-flex; align-items: center; gap: var(--sp-2); }
.inplace.is-edit .ip-rw-block { display: block; }
.inplace.is-edit .ip-rw-rows { display: table-row-group; }
.inplace.is-edit .ip-rw-cell { display: table-cell; }

body.ip-editing .top-level-tabs,
body.ip-editing .page-head,
body.ip-editing .ex3-tree,
body.ip-editing .ex3-list,
body.ip-editing [data-ip-lock],
body.inline-editing .top-level-tabs,
body.inline-editing .page-head,
body.inline-editing .ex3-tree,
body.inline-editing [data-ip-lock] {
  pointer-events: none;
  opacity: .45;
  user-select: none;
}

.inplace .kv-grid > .kv-f > span { background: var(--c-surface); }
.inplace.is-edit .kv-grid > .kv-f > span { padding: 0; overflow: visible; white-space: normal; }
.inplace.is-edit .kv-grid .ip-rw { display: flex; width: 100%; }
.inplace.is-edit .kv-grid input:not([type=checkbox]),
.inplace.is-edit .kv-grid select,
.inplace.is-edit .kv-grid textarea {
  width: 100%;
  box-sizing: border-box;
  border: 0;
  border-radius: 0;
  padding: 0 var(--sp-4);
  font-size: var(--fs-md);
  font-family: inherit;
  background: var(--c-surface);
}
.inplace.is-edit .kv-grid input:not([type=checkbox]),
.inplace.is-edit .kv-grid select {
  height: var(--h-lg);
}
.inplace.is-edit .kv-grid textarea {
  field-sizing: content;
  resize: none;
  min-height: var(--h-md);
  padding: var(--sp-1) var(--sp-4);
  line-height: 1.4;
}
.inplace.is-edit .kv-grid input:focus,
.inplace.is-edit .kv-grid select:focus,
.inplace.is-edit .kv-grid textarea:focus {
  outline: none;
  box-shadow: inset 0 0 0 var(--bw-head) var(--c-primary);
}
/* 칸 안 단추(코드칸 돋보기 · 날짜 [달력]) — 칸 경계선이 곧 테두리라 단추는 칸 쪽 한 줄만 긋는다(위 · 아래 · 바깥 테두리가 칸 선과 겹쳐 일그러지던 것, 대표님 2026-10-11) */
.inplace.is-edit .kv-grid .lookup-find { align-self: stretch; height: auto; border: 0; border-right: 1px solid var(--c-line); background: var(--c-head); }
.inplace.is-edit .kv-grid .datebox-btn { align-self: stretch; height: auto; border: 0; border-left: 1px solid var(--c-line); }
.inplace.is-edit .kv-grid .key-box,
.inplace.is-edit .kv-grid .lookup-box,
.inplace.is-edit .kv-grid .datebox {
  flex: 1;
  width: 100%;
}

.inplace .view-head .ip-rw,
.inplace .view-head .ip-ro {
  align-items: center;
  gap: var(--sp-2);
}
.inplace .view-head .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  height: var(--h-md);
  margin: 0;
  vertical-align: middle;
  line-height: 1;
}
.inplace:not(.is-edit) .view-head > .ip-ro,
.inplace:not(.is-edit) .view-head .ip-ro {
  display: inline-flex;
}

/* 곁판 없는 창(등록 창 new 등)도 몸통만 스크롤 · [저장] 줄은 늘 아래 — win-split 창 규칙(style.css)과 같은 꼴. 화면이 낮으면 관리 상자 · [저장] 이 창 밖으로 넘치던 것(대표님 2026-10-10 품목 장비 등록 창) */
.modal.window > form:not(:has(> .win-split)) { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.modal.window > form:not(:has(> .win-split)) > .modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.modal.window > form:not(:has(> .win-split)) > .modal-footer { flex: 0 0 auto; }
/* 창의 칸 줄 안 코드칸도 글자 칸처럼 줄 끝까지(170px 에서 멈추던 것) */
.field-row > .lookup-box, .field-row .lookup-box { flex: 1; min-width: 0; }

/* 연결 코드표 머리(디자인시스템 3-2) — 값이 다른 코드표에서 오는 칸 · 단의 제목: 사슬 그림 + 링크 색 · 누르면 그 코드표 코드창 */
.lookup-link-btn { display: inline-flex; align-items: center; gap: var(--sp-1); padding: 0; border: 0; background: none; color: var(--c-link); font: inherit; font-weight: inherit; cursor: pointer; }
.lookup-link-btn:hover { text-decoration: underline; }
.lookup-link-ic { flex: none; }
/* 곁판 액자(app.js data-side-open) — 창의 오른쪽 곁판(#winSide) 위를 덮는 상대 창. ✕ 는 이 액자만 닫고 밑의 판으로(대표님 2026-10-11) */
#winSide:has(> .side-layer) { position: relative; }
/* 액자가 떠 있는 동안 곁판 폭은 원래 창 폭 + 여백만 — 링크매치 판(922px)만큼 벌리지 않는다(대표님 2026-10-11 "확장패널이 큼"). ✕ 로 닫으면 다시 그 폭 */
.modal.window:has(#winSide > .side-layer) { --win-side: calc(var(--sp-9) * 16); }   /* 512px — 보기 화면은 폰 꼴(이름표 위 · 값 아래)로 접혀 좁아도 다 보인다 */
.side-layer { position: absolute; inset: 0; z-index: 60; background: var(--c-surface); }
.side-layer > iframe { width: 100%; height: 100%; border: 0; display: block; }
/* 액자 안의 창 = 곁판 안의 판 — 떠 있는 창 틀 없이 곁판을 꽉 채우고(창 자리 · 끌어 둔 자리 무시), 머리줄은 표준 창 머리,
   왼쪽 칸 고정 폭(--win-main)도 풀어 판 폭을 다 쓴다. 스크롤은 창 안 본문이 그대로 맡는다(대표님 2026-10-11 "이중창 · 스크롤 안 먹어") */
html.side-framed .modal-backdrop { display: none; }
html.side-framed .modal.window { position: fixed !important; inset: 0 !important; transform: none !important; margin: 0 !important;
  width: 100% !important; max-width: none !important; height: 100% !important; max-height: none !important;
  border: 0 !important; border-radius: 0 !important; box-shadow: none !important; }
/* 머리줄은 곁판 머리 꼴(.win-side > .panel-head) — 옅은 회색 띠 31px · 제목 · win-id · ✕. 떠 있는 창의 어두운 머리가 아니다(대표님 2026-10-11 "확장-내부창은 회색").
   폰 규칙은 base.html 머리 스크립트가 액자 안에서 끈다(폰-18) */
html.side-framed .modal.window > .modal-header { height: calc(var(--sp-9) - var(--bw-hair)); min-height: 0; padding: 0 var(--sp-4); box-sizing: border-box;
  background: var(--header-bg); border-bottom: var(--bw-hair) solid var(--border); cursor: default; touch-action: auto; }
html.side-framed .modal.window > .modal-header h2 { color: var(--text); font-size: var(--fs-md); font-weight: var(--fw-semi); }
html.side-framed .modal.window > .modal-header .win-id { color: var(--text-muted); }
html.side-framed .modal.window > .modal-header .titlebar-close { min-width: 0; min-height: 0; background: none; color: var(--text-muted); font-size: var(--fs-lg); }
html.side-framed .modal.window > .modal-header .titlebar-close:hover { background: none; color: var(--danger); }
html.side-framed .modal.window .win-split > .win-main { flex: 1 1 auto !important; width: auto !important; max-width: none !important; }
html.side-framed .modal.window .win-split > .win-side { display: none !important; }
html.side-framed .vm-text { font-size: var(--fs-md); line-height: var(--lh-text); padding: var(--sp-1) 0; }   /* 보기 모드 글자 — 폰 크기(16) 말고 PC 본문 크기 */
@media (min-width: 701px) { .modal.window[data-view-always] .vm-text { font-size: var(--fs-md); line-height: var(--lh-text); padding: var(--sp-1) 0; } }   /* PC 에서 보기 먼저 뜨는 창(data-view-always)도 PC 본문 크기 */
/* 곁판 액자 안의 Match connect 는 보기만 — 줄을 눌러 또 상대 창을 여는 고리를 끊는다(창 → 상대 → 창 … 무한, 대표님 2026-10-11) */
html.side-framed .link-view tr.row-link { pointer-events: none; cursor: default; }
html.side-framed .link-view tr.row-link button.fit-more { pointer-events: auto; cursor: pointer; }   /* 줄은 못 눌러도 표 맞춤 [+](숨긴 칸 보기)는 누른다(24-83) */
html.side-framed .link-view .link-view-find, html.side-framed .link-view .link-view-head .btn { display: none; }
/* 아이콘 단추(명함 · 거래처 · 사업자) — 아이콘만, 글자 높이에 맞춘다. 통화 · 문자 공용 */
.ref-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.ref-btn svg {
  width: var(--fs-xl);
  height: var(--fs-xl);
}

.ref-btns {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  flex: none;
}

.ref-btn span {
  margin-left: var(--sp-2);
}

/* 사업자 심볼 고르기(templates/_biz_pick.html, 24-49) — 단추는 원래 심볼 꼴 그대로, 펼친 목록 줄은 상호 · 거래처번호 한 줄 */
.biz-pick { vertical-align: middle; }
.icon-row > .biz-pick, .ref-btns > .biz-pick { display: inline-flex; }
.biz-pick > .biz-pick-btn.sym-link { font-style: normal; width: auto; min-width: 0; height: auto; min-height: 0; padding: 0; border: 0; background: none; color: var(--c-primary); font-size: inherit; line-height: inherit; cursor: pointer; }
.biz-pick > .biz-pick-btn.sym-link:hover { color: var(--c-dark); }
.biz-pick > .biz-pick-btn.sym-link svg { width: var(--sp-7); height: var(--sp-7); }
.biz-pick > .biz-pick-btn.ref-btn { font-style: normal; min-width: auto; }
.biz-pick-list { min-width: 14em; max-width: 24em; }
.biz-pick-list a { display: flex; gap: var(--sp-3); align-items: baseline; }
.biz-pick-list .biz-pick-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.biz-pick-list .biz-pick-code { flex: none; color: var(--c-text-3); font-size: var(--fs-sm); }

/* 일반 연결(_ref_panel) 칩 — 칩 하나가 두 줄로 안 갈라지게(24-13) */
.link-ref-chips { display: flex; flex-wrap: wrap; gap: var(--sp-1); }
.link-ref-chip { display: inline-flex; align-items: center; gap: var(--sp-1); }
html.side-framed .link-view .view-grid th, html.side-framed .link-view .view-grid td { font-size: var(--fs-md); padding: var(--sp-2); }
/* 곁판 Match connect 도 창과 같은 꼴 — 고정 열 · 판 폭 꽉 · 상호 한 줄 말줄임(…) + 올리면 title 로 전체, 좁으면 공용 표 맞춤(fit_table, th data-prio)이 오른쪽 열부터 [+] 로 접는다(대표님 2026-10-26 24-49, 10-11 열 숨김 · 줄바꿈 규칙 걷음) */
html.side-framed .link-view { margin-inline: 0; padding-inline: 0; }   /* 위 칸 묶음과 같은 너비 — 양옆 들여쓰기만큼 표가 넓어진다 */
/* 곁판 액자 안에서 밖으로 나가는 길은 모두 끊는다 — [수정] · [공유] · 전화 걸기 · 다른 창 고리(대표님 2026-10-11 "내부창에서 다른 외부로 연결되는것은 끊는게"). 첨부 이름(크게 보기)과 ✕ 만 남김 */
html.side-framed .modal.window .modal-footer .vm-share, html.side-framed .modal.window .modal-footer .vm-edit { display: none !important; }
html.side-framed .modal.window .modal-body a:not(.file-name), html.side-framed .modal.window .vm-text { pointer-events: none; }
html.side-framed .modal.window .vm-text[data-kind] { color: var(--c-text); text-decoration: none; cursor: default; }
/* 곁판이 넓어도 칸은 원래 창 폭(--win-main)만 — 값과 꼬리표(휴대폰 · 회사)가 멀리 벌어지지 않게(대표님 2026-10-11 "칸이 너무 넓다"). 보기라 꼬리표 자동생성도 뗀다 */
html.side-framed .modal.window .modal-body .groupbox { max-width: var(--win-main); }
html.side-framed .modal.window .auto-tag { display: none; }
/* 보기 모드엔 칸 풀이(예: 이름2 "사람 이름만 — 진우성")를 두지 않는다(대표님 2026-10-11) */
.modal.window.view-mode .modal-body .field-row > .hint { display: none; }
/* 차량사진 대표 고르기 — 동그라미와 글자 한 줄, 보기 모드는 고른 줄만 꼬리표로(24-29F) */
.file-main { display: inline-flex; align-items: center; gap: var(--sp-1); white-space: nowrap; cursor: pointer; }
.file-main > input { flex: none; width: 1em; height: 1em; min-width: 0; min-height: 0; margin: 0; }
.modal.window.view-mode .file-main { pointer-events: none; }
.modal.window.view-mode .file-main > input { display: none; }
.modal.window.view-mode .file-main:not(:has(input:checked)) { visibility: hidden; }
html.side-framed .modal.window.view-mode .modal-body .acct-item { padding: 0 !important; margin: 0 !important; gap: 0 var(--sp-4); align-items: flex-start; }
html.side-framed .modal.window.view-mode .modal-body .acct-item > .key-box, html.side-framed .modal.window.view-mode .modal-body .acct-item > .vm-text { flex: 1 1 auto; min-width: 0; }
html.side-framed .modal.window.view-mode .modal-body .acct-item > select { flex: none; width: auto; color: var(--c-text-2); }
/* 세 칸 트리 맨 위 일 단추 줄 — 회사관련서류 [폴더 추가] 가 [전체] 위(대표님 2026-10-11) */
.ex3-tree-act { flex: none; display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1); padding: var(--sp-1); border-bottom: var(--bw-hair) solid var(--border); }
.ex3-tree-act > .ex3-tree-act, .ex3-tree-act > form { display: contents; }
.ex3-tree-act .btn { flex: 1 1 auto; justify-content: center; }
/* 공용 뷰어 도구줄(PC) — 단추가 낱개로 줄을 바꿔 이 빠진 꼴이던 것(대표님 2026-10-11 "이빨빠진 모양"). IPC 본보기처럼 한 줄 오른쪽 정렬로 붙인다.
   펜 도구(색 · 굵기 · 지우개 …)는 꺼져 있을 때 빈자리를 지키지 않고, 켜면 펜 단추 아래 작은 판으로 겹쳐 뜬다(도구줄은 그대로 — 틀 고정).
   좁으면 찾기 묶음만 윗줄, 쪽 · 확대 · 도구는 아랫줄 한 덩어리 — 줄바꿈은 묶음 사이에서만. 새 창 전용(.vw-solo)은 제 규칙 그대로. */
.vw:not(.vw-solo) { container-type: inline-size; }
.vw:not(.vw-solo) .vw-tools { flex-wrap: nowrap; }
.vw:not(.vw-solo) .vw-slot[data-slot="ink"] { position: relative; }
.vw:not(.vw-solo) .vw-ink-tools { position: absolute; top: calc(100% + var(--sp-1)); right: 0; z-index: 7; margin: 0; padding: var(--sp-1);
  background: var(--card-bg); border: var(--bw-hair) solid var(--border); }
@container (max-width: 760px) {
  .vw:not(.vw-solo) .vw-tools { flex-wrap: wrap; }
  .vw:not(.vw-solo) .vw-tools > [data-slot="find"] { flex: 1 0 100%; justify-content: flex-end; }
}
/* 표 바로 입력 — 체크 칸은 칸 폭만큼 늘리지 않고 머리 · 값(Y/N)과 같은 왼쪽 줄에, 사업용 열은 좁게(대표님 2026-10-11 회사카드) */
.inline-row-edit input[type="checkbox"] { width: auto; margin: 0; }
.inline-table col.inline-col-business_use { width: calc(var(--h-xl) * 3); }

/* 목록 칸 둘째 줄 — 거래처 아래 사업자번호처럼 딸린 값(회계 세금계산서, 2026-10-12). 토큰만 */
.cell-sub { display: block; font-size: var(--fs-sm); color: var(--c-text-2); }


/* 문자 — SMS DB · MMS 공용. 토큰만 */
.sms-db .sms-c-at, .sms-db .sms-c-num { width: calc(var(--sp-9) * 4); }
.sms-db .sms-c-who, .sms-db .sms-c-why { width: calc(var(--sp-9) * 6); }
.sms-db .sms-c-acc, .sms-db .sms-c-state { width: calc(var(--sp-9) * 3); }   /* 문자DB(configuration) — 남는 폭은 내용 */
.sms-mms { color: var(--c-text-2); font-size: var(--fs-sm); }   /* 목록 내용 칸 앞 "MMS · 첨부 n" */
.sms-mms-pic { display: inline-block; margin: var(--sp-1) var(--sp-1) 0 0; vertical-align: top; }
.sms-mms-pic > img { display: block; width: var(--thumb-w); height: var(--thumb-h); object-fit: cover; object-position: top center; cursor: zoom-in; border: var(--bw-hair) solid var(--c-line); }   /* MMS 사진 — 누르면 새 창에 원본 */
.sms-mms-vid { position: relative; cursor: pointer; }
.sms-mms-vid > img { cursor: pointer; }
.sms-mms-vid::after { content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: var(--h-lg); height: var(--h-lg); border-radius: var(--r-round); background: var(--c-dark) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='9,7 18,12 9,17' fill='white'/%3E%3C/svg%3E") no-repeat center / var(--fs-sm); opacity: .8; pointer-events: none; }
.sms-mms-file { display: block; margin-top: var(--sp-2); white-space: normal; }
.sms-mms-media { display: block; max-width: 100%; max-height: calc(var(--thumb-h) * 5); margin-top: var(--sp-1); }
@media (max-width: 700px) {
  .sms-db .sms-c-who, .sms-db .sms-c-acc, .sms-db .sms-c-why,
  .sms-db .sms-c-line, .sms-db .sms-c-state { display: none; }   /* 폰 — 때 · 번호 · 내용만(이름은 대화 창 머리에) */
}
/* blk — 공용 블록 카드(대시보드2-3) */
.icon { width: 1em; height: 1em; vertical-align: middle; flex: none; }
.blk { border: var(--bw-sub) solid var(--c-line); border-radius: var(--r-1); box-shadow: none; background: var(--c-surface); display: flex; flex-direction: column; }
/* 대시보드 휠 — 커서가 올라간 블록 테두리를 강조해 휠이 어디에 먹는지 보이게 · 커서 아래 넘치는 스크롤 칸이 있으면 휠은 그 칸에서만(끝까지 내려도 대시보드 전체로 안 넘어감), 없으면 대시보드 전체 — 블록 몸은 dashboard.js 휠 듣기, 블록 액자 속은 app.js(대표님 2026-10-18) */
.grid-stack-item:hover > .grid-stack-item-content > .blk { border-color: var(--c-link); }
html.blk-framed, html.blk-framed * { overscroll-behavior: contain; }
.blk-head { display: flex; align-items: center; min-height: var(--h-lg); padding: var(--sp-2) var(--sp-3); background: var(--c-surface); border-bottom: var(--bw-sub) solid var(--c-line); container: blkhead / inline-size; }
.blk-title { margin: 0; font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--c-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.blk-tools { display: flex; align-items: center; gap: var(--sp-1); margin-left: auto; flex: none; }
.blk-tool { display: inline-flex; align-items: center; justify-content: center; width: var(--h-md); height: var(--h-md); padding: 0; border: 0; border-radius: var(--r-1); background: transparent; color: var(--c-text-2); cursor: pointer; text-decoration: none; box-sizing: border-box; }
.blk-tool:hover { background: var(--c-hover); color: var(--c-primary); }
.blk-tool:focus-visible { outline: var(--bw-head) solid var(--c-primary); }
summary.blk-tool { list-style: none; }
summary.blk-tool::-webkit-details-marker { display: none; }
.blk-body { overflow: auto; padding: var(--sp-3) var(--sp-4); flex: 1 1 auto; }
.blk-s .blk-body { max-height: calc(var(--lh-row) * 8); }
.blk-m .blk-body { max-height: calc(var(--lh-row) * 16); }
.blk-l .blk-body { max-height: calc(var(--lh-row) * 26); }
/* 화면 블록(Frame) — 모듈 화면을 iframe 으로, 몸 여백 · 높이 상한 없이 카드를 꽉 채운다 · 아래 띠는 크기조절 손잡이 자리(스크롤바와 겹치지 않게) */
.blk-body:has(> .blk-frame) { padding: 0 0 var(--sp-3); max-height: none; overflow: hidden; display: flex; }
.blk-frame { flex: 1 1 auto; width: 100%; min-height: calc(var(--lh-row) * 12); border: 0; display: block; background: var(--c-surface); }
/* 화면 블록 액자 안 — 두 칸 틀(.ex3-two)은 폭과 무관하게 위(목록) · 아래(보기)로 쌓고 블록 끝까지 채운다(대표님 2026-10-17 "대시보드에서는 좌우로 구분 안함") */
/* 액자 안(블록 · 고정 창 · 팝업 창)은 폭과 무관하게 끝까지 채운다 — base #page 감싸개(2026-10-18) 안 view-body 까지 */
html.blk-framed body:has(.ex3-wrap), html.keep-framed body:has(.ex3-wrap) { display: flex; flex-direction: column; height: 100vh; }
html.blk-framed body:has(.ex3-wrap) > *, html.keep-framed body:has(.ex3-wrap) > * { flex: none; }
html.blk-framed body:has(.ex3-wrap) > #page, html.keep-framed body:has(.ex3-wrap) > #page { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
html.blk-framed #page > *, html.keep-framed #page > * { flex: none; }
html.blk-framed #page > .view-body, html.keep-framed body:has(.ex3-wrap) #page > .view-body { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
html.blk-framed .view-body > .ex3-wrap, html.keep-framed .view-body > .ex3-wrap { flex: 1 1 0; height: auto; min-height: 0; }
html.blk-framed .ex3-wrap.ex3-two { flex-direction: column; }
html.blk-framed .ex3-wrap.ex3-two .ex3-list,
html.blk-framed .ex3-wrap.ex3-two .ex3-tree { flex: 0 0 40%; width: auto; min-width: 0; min-height: 0; border-right: 0; }
html.blk-framed .ex3-wrap.ex3-two .ex3-view { flex: 1 1 0; width: auto; min-width: 0; min-height: 0; }
/* 액자 안 스크롤은 칸마다 하나 — 문서 전체는 스크롤하지 않고 위(목록) · 아래(보기) 칸이 제 스크롤을 갖는다(대표님 2026-10-18). 액자 안이 폰 규칙을 안 받는 것은 base.html 머리 스크립트 */
html.blk-framed body:has(.ex3-wrap) { overflow: hidden; }
/* 블록 액자 안 쪽 넘김 — 얇은 띠로 접어 두고 커서를 대면 그 자리에서 아래로 떠서 펼친다(.is-open, app.js — 목록 · 아래 칸은 안 움직이고, 액자 바닥을 넘으면 블록이 아래 블록 위로 늘어남). 대표님 2026-10-18 */
html.blk-framed .pager { position: relative; margin: 0; padding: 0 var(--sp-1); height: var(--sp-3); overflow: hidden; border-top: var(--bw-hair) solid var(--c-line); background: var(--c-sunken); cursor: pointer; }
/* 접힌 띠에는 내용을 반쯤 비치지 않는다 — 가운데 손잡이 막대 하나만(대표님 "이런 표현방법이 어딨냐") */
html.blk-framed .pager > * { visibility: hidden; }
html.blk-framed .pager::before { content: ""; position: absolute; left: 50%; top: 50%; width: var(--h-lg); height: var(--bw-main); margin-left: calc(var(--h-lg) / -2); background: var(--c-text-3); border-radius: var(--r-1); }
html.blk-framed .pager.is-open { height: auto; padding: var(--sp-1); overflow: visible; background: var(--c-surface); border: var(--bw-hair) solid var(--c-line); }
html.blk-framed .pager.is-open > * { visibility: visible; }
html.blk-framed .pager.is-open::before { display: none; }
/* 블록 안 쪽 넘김은 촘촘하게 — 번호 줄 · 쪽 번호 칸과 건수 줄 두 줄로(앞 칸 사이 여백 없음) */
html.blk-framed .pager-jump { margin-left: 0; }
/* 블록 안에서는 "1–50 · 모두 N명" 같은 곁글을 빼 쪽 넘김을 한 줄로 — 곁글 때문에 칸이 늘지 않게(대표님 2026-10-18). 몇 쪽인지는 "/ 쪽수" 가 보인다 */
html.blk-framed .pager-count { display: none; }
html.blk-framed .pager-page, html.blk-framed .pager-step { min-width: var(--h-xs); padding: 0 var(--sp-1); }
/* 반복 실패 멈춤 띠(.alarm-band)는 메인 레이어(맨 위 화면) 몫 — 서브 레이어(블록 · 고정 창 · 팝업 창 · 겹친 창) 속에는 띄우지 않는다(대표님 "서브레이어에는 메인레이어 에러 띄우지마")(대표님 2026-10-18 "문자 메모내역에 uvis 에러가 왜뜬거냐") */
html.blk-framed .alarm-band, html.keep-framed .alarm-band, html.stacked .alarm-band { display: none; }
.blk-more { position: relative; }
.blk-menu { position: absolute; top: 100%; right: 0; z-index: 10; min-width: calc(var(--label-w) * 1.5); background: var(--c-surface); border: var(--bw-sub) solid var(--c-line); border-radius: var(--r-1); padding: var(--sp-1) 0; display: flex; flex-direction: column; }
.blk-menu a, .blk-menu button { display: flex; align-items: center; width: 100%; height: var(--h-md); padding: 0 var(--sp-3); border: 0; background: transparent; color: var(--c-text); font: inherit; font-size: var(--fs-md); text-decoration: none; white-space: nowrap; box-sizing: border-box; cursor: pointer; text-align: left; }
.blk-menu a:hover, .blk-menu button:hover { background: var(--c-hover); color: var(--c-primary); }
.blk-menu-phone { display: none; }
/* 블록이 좁아져도 제목은 다 보이게 — 말줄임 대신 글자 · 아이콘 칸을 줄인다(대표님 2026-10-18 "기능구분이 안되잖아") */
@container blkhead (max-width: 230px) { .blk-title { font-size: var(--fs-sm); } .blk-tools { gap: 0; } .blk-tool { width: var(--h-sm); } }
@container blkhead (max-width: 200px) { .blk-title { font-size: var(--fs-xs); white-space: normal; word-break: keep-all; line-height: 1.2; } .blk-tool { width: var(--h-xs); } }   /* 그래도 넘치면 두 줄 — 잘리지 않게 */
.blk-empty, .blk-error { color: var(--c-text-2); font-size: var(--fs-md); }
.blk.is-edit .drag-grip { display: inline-flex; }
.blk-size { height: var(--h-md); font-size: var(--fs-sm); padding: 0 var(--sp-2); }
/* 빼기 · 지우기 동그라미 — 빨간 동그라미 안 ×(공용 심볼 x). 블록 [빼기] · 바로가기 [×] 한 꼴(대표님 2026-10-18 "아이콘으로 통일") · 두 번 누름 깜빡은 data-arm(btn-reset-go) */
.del-dot { display: inline-flex; align-items: center; justify-content: center; flex: none; width: var(--sp-7); height: var(--sp-7); padding: 0; border: 0; border-radius: var(--r-round); background: var(--c-danger); color: var(--c-on-dark); font-size: var(--fs-xs); line-height: 1; cursor: pointer; }
.del-dot:hover { filter: brightness(0.85); }
.del-dot:focus-visible { outline: var(--bw-head) solid var(--c-primary); outline-offset: var(--sp-1); }
.blk-tools .del-dot { margin-left: var(--sp-2); }
@media (max-width: 700px) {
  .blk-tool { width: var(--h-touch); height: var(--h-touch); }
  .blk-menu a, .blk-menu button { height: var(--h-touch); }
  .blk-menu-phone { display: flex; flex-direction: column; border-top: var(--bw-hair) solid var(--c-line); margin-top: var(--sp-1); padding-top: var(--sp-1); }
}

/* 고정 창 — assets/keepwin.js (docs/문자내역-설계.md 2절) */
.modal.window.keep-win {
  position: fixed;
  transform: none;
  resize: both;
  overflow: hidden;
  min-width: calc(var(--label-w) * 4);
  min-height: calc(var(--h-lg) * 8);
  max-width: none;
  max-height: none;
  z-index: 101;
  display: flex;
  flex-direction: column;
}
/* 고정 창 표시 — 머리줄 맨 왼쪽 핀(대표님 2026-10-17) */
.keep-win .keep-pin { display: inline-flex; align-items: center; margin-right: var(--sp-2); color: var(--c-text-3); flex: none; }
/* 창 머리줄 — 제목 + 지금 한 건(.keep-sub) · 그 건의 단추는 ✕ 옆(.keep-tools). 창 이름은 제목 툴팁(대표님 2026-10-18) */
/* 머리줄 단추끼리는 공용 머리 단추 간격(.modal-header-actions 와 같은 sp-4) — 붙어서 경계가 안 보였다(대표님 2026-10-18) */
.keep-win .modal-header { gap: var(--sp-4); }
.keep-win .modal-header h2 { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.keep-win .keep-sub:not(:empty) { margin-left: var(--sp-3); font-weight: var(--fw-normal); }
.keep-win .keep-tools { display: inline-flex; align-items: center; gap: var(--sp-1); flex: none; }
.keep-win .keep-tools:empty { display: none; }
.keep-win .keep-tools .fn-list { left: auto; right: 0; }   /* 머리 펼침(사업자 고르기 등)은 ✕ 쪽에 붙여 창 안에서 펼친다 — 창이 overflow:hidden(24-59) */
/* 액자 속 — 머리줄로 올라간 "지금 한 건" 줄은 속에서 숨긴다(두 번 보이지 않게) */
html.keep-framed [data-win-head] { display: none; }

.keep-win .keep-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  position: relative;
  background: var(--c-surface);
}

.keep-win .keep-frame {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  flex: 1 1 auto;
}

.keep-win.is-dragging .keep-frame {
  pointer-events: none;
}

.keep-win.is-loading .keep-frame {
  visibility: hidden;
}

.keep-win .keep-wait {
  display: none;
  position: absolute;
  inset: 0;
  align-items: center;
  justify-content: center;
  margin: 0;
  background: var(--c-surface);
  color: var(--c-text-2);
  font-size: var(--fs-md);
}

.keep-win.is-loading .keep-wait {
  display: flex;
}

@media (max-width: 700px) {
  [data-keep-open], .keep-win {
    display: none;
  }
}

/* 공용 경고창 (6-7b) — erp-alert */
.modal.window.erp-alert {
  position: fixed;
  width: min(calc(var(--sp-9) * 16), calc(100vw - var(--sp-8)));
  max-width: calc(var(--sp-9) * 16);
  z-index: 10000;
  background: var(--c-surface);
  border: 1px solid var(--c-line-strong);
  box-shadow: var(--sp-1) var(--sp-1) 0 var(--c-line-strong);
  display: flex;
  flex-direction: column;
}

.modal.window.erp-alert .modal-header,
.newreg-pop > .modal-header {
  background: var(--c-dark);
  color: var(--c-on-dark);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--sp-2) 0 var(--sp-4);
  height: var(--h-lg);
  cursor: move;
  user-select: none;
}

/* ---- API 프로필 공동규칙 (knowledge/규약/API프로필.md) ----
   외부 API 를 쓰는 설정 화면은 섹터(탭)마다 같은 순서로 ① 프로필 ② 연결상태 ③ 수집옵션 ④ 디테일.
   ② 는 읽기 전용 신호등, 고치기 · 연결 끊기는 ① 에서만. 조각: templates/_api_status.html */
.api-tabs { display: flex; gap: var(--sp-1); border-bottom: var(--bw-hair) solid var(--c-line); margin-bottom: var(--sp-3); }
.api-tabs a { padding: var(--sp-2) var(--sp-4); color: var(--text-muted); text-decoration: none; border-bottom: var(--bw-head) solid transparent; margin-bottom: -1px; }
.api-tabs a.on { color: var(--c-primary); border-bottom-color: var(--c-primary); font-weight: var(--fw-semi); }
.api-tabs .lamp { margin-right: var(--sp-1); }
.api-sec { flex: 1 1 100%; min-width: 0; }
/* ①②③④ 는 한 줄에 나란히 두지 않고 줄마다 하나씩 아래로(대표님 2026-10-16 "1번 / 2번 / 3번 / 4번 … 한줄에 줄줄이 하지말고", 연결-09) */
.api-top { display: flex; flex-direction: column; gap: 0; }
.api-top > .cfg-box { flex: none; }   /* 세로로 쌓을 때 늘어나지 않게 — 폭은 cfg-box 기본(35rem 까지) */
.api-top > .cfg-box:has(table.grid), .api-top > .cfg-box-wide { max-width: none; }
.api-part { flex: none; }
.api-part > h3 .api-no,
.api-detail-head .api-no { display: inline-block; min-width: 1.4em; color: var(--text-muted); font-weight: var(--fw-normal); }
.api-sub { display: inline-block; min-width: 2em; color: var(--text-muted); font-weight: var(--fw-normal); font-size: inherit; }
.api-status { display: flex; align-items: center; gap: var(--sp-1); min-height: var(--h-md); }
.api-detail { margin-top: var(--sp-5); padding-top: var(--sp-4); border-top: var(--bw-hair) solid var(--c-line); display: flex; flex-direction: column; gap: 0; }   /* ④ 안 구획도 줄마다 하나씩 아래로 */
.api-detail-head { font-size: var(--fs-lg); margin: 0; }
.api-detail > .cfg-box { flex: none; margin: 0; }
.api-detail > .cfg-box:has(table.grid), .api-detail > .cfg-box-wide { max-width: none; }   /* 표가 든 구획만 넓게 */
.split-stack { display: flex; flex-direction: column; gap: 0; }
.split-stack > * + *,
.api-top > * + *,
.api-detail > * + * { border-top: var(--bw-hair) solid var(--c-line); padding-top: var(--sp-4); margin-top: var(--sp-4); }
.cfg-head-act { display: flex; align-items: center; gap: var(--sp-2); justify-content: flex-start; margin-bottom: var(--sp-3); }
.cfg-head-act h3, .cfg-head-act h4 { margin: 0; }
.cfg-box h4 { font-size: var(--fs-md); margin: 0 0 var(--sp-3); }
.api-detail .api-part > * { width: 100%; }
.api-detail .grid { width: 100%; }
@media (max-width: 700px) {
  .api-tabs a { flex: 1; text-align: center; padding: var(--sp-3) var(--sp-2); }
}
.api-log { margin-top: var(--sp-2); }
.api-log summary { cursor: pointer; color: var(--text-muted); font-size: var(--fs-sm); }
.api-log table { margin-top: var(--sp-1); }

/* lite viewer 창 — 첨부 판이 없는 화면의 첨부 보기(templates/_att_float.html, 대표님 2026-10-15). 차량정보 veh-att-view 를 공용으로 올림.
   다른 창(.modal.window 101) 위에 뜬다 — 창 안 첨부를 눌러도 그 창을 덮는다. 확대 보기(Viewer.js 3000)는 그 위 */
.modal.window.att-float { width: min(96vw, 62.5rem); height: min(88vh, 51rem); max-width: none; max-height: none; min-width: calc(var(--label-w) * 3); min-height: calc(var(--h-lg) * 6); resize: both; overflow: hidden; display: flex; flex-direction: column; padding: 0; z-index: 1101; }   /* 막 없는 떠 있는 창 · 귀퉁이로 크기 조절(keep-win 과 같은 resize, 대표님 2026-10-21) */
.modal.window.att-float > .att-panel { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.modal.window.att-float .att-stage { flex: 1 1 auto; min-height: 0; position: relative; }
.modal.window.att-float > .att-panel > .panel-head { cursor: move; touch-action: none; user-select: none; }   /* 머리줄로 끌어 옮긴다(app.js makeDraggable — 떠 있는 창은 모두 옮김) */
.att-tools { flex: 0 0 auto; padding: 0 var(--sp-2); }
.att-foot { padding: 0 var(--sp-3); }

/* 판 안에 바로 펴는 lite viewer(`{% att_inline %}` — 판독 원본 판의 PDF). 판 몸통을 다 쓴다 */
.att-panel.att-inline { display: flex; flex-direction: column; height: 100%; min-height: 20rem; }
.att-panel.att-inline .att-stage { flex: 1 1 auto; min-height: 0; position: relative; }

/* 지난 판 보기 = 편집 때와 같은 칸 상자([비교] 창과 같은 꼴, 대표님 2026-10-25 "viewer 모드일때 자꾸 칸 구분이 안되게 깨지고 있다" · 24-27).
   이력 [보기]는 칸을 잠가 그린다(common/history.py view_context). 10-15 공동규칙 A 의 "글자 꼴"(테두리 · 바탕을 걷음)은 칸 경계가 사라지고
   곁칸(라벨 · mobile · 대표)이 떠 보였으며, 그 선택자가 노랑보다 세서 바뀐 칸 노랑까지 지웠다 — 테두리 · 바탕은 그대로 두고 글자만 흐리지 않게, 지금과 다른 칸은 노랑 */
.modal.window:has(.hist-viewing) :is(input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=file]), select, textarea):disabled {
  color: var(--text); -webkit-text-fill-color: var(--text); opacity: 1; cursor: default; }
.modal.window:has(.hist-viewing) .field-row.hist-diff :is(input:not([type=checkbox]):not([type=radio]):not([type=hidden]):not([type=file]), select, textarea):disabled { background: var(--c-note-bg); }
/* 맞춘 코드 칸(관할세무서 등)은 코드 글자를 숨기고 이름표만 — 위 글자색이 숨김을 되살려 코드 · 이름이 겹쳤다 */
.modal.window:has(.hist-viewing) .lookup-box.is-matched:not(:has(input[data-lookup-fill])) input[data-lookup]:disabled { color: transparent; -webkit-text-fill-color: transparent; }

/* 설정 상자(cfg-wrap · cfg-box) — configuration 판 · 설정 화면 공용 한 벌(2026-10-15 공동규칙 — 알림 · 문자 · 서버 · 폰앱 · MAPS 가 각자 베끼거나
   아예 못 받아(MAPS KPI) 폰에서 단추가 화면 밖으로 나갔다). 모듈은 크기만 덮어쓴다. 폰은 한 줄에 하나 · 칸 줄은 접어 내린다 */
.cfg-wrap { display: flex; gap: var(--sp-6); align-items: flex-start; flex-wrap: wrap; }
.cfg-box { flex: 1 1 23.75rem; min-width: 0; max-width: 35rem; }
.cfg-box h3 { font-size: var(--fs-lg); margin: 0 0 var(--sp-3); }
.cfg-box .field-row { margin: 0 0 var(--sp-2); }
.cfg-box .field-row label { width: 7em; flex: none; }
.cfg-box .field-row input[type=text], .cfg-box .field-row input[type=password] { flex: 1; min-width: 0; }
.cfg-box .btn { min-height: var(--h-sm); padding: 0 var(--sp-5); }
@media (max-width: 700px) {
  .cfg-box { flex-basis: 100%; max-width: none; }
  .cfg-box .field-row { flex-wrap: wrap; }
}

.modal.window.erp-alert .modal-header h2,
.newreg-pop > .modal-header h2 {
  font-size: var(--fs-md);
  font-weight: var(--fw-semi);
  color: var(--c-on-dark);
  margin: 0;
}

.modal.window.erp-alert .modal-body {
  padding: var(--sp-4) var(--sp-5);
  font-size: var(--fs-md);
  line-height: var(--lh-text);
  color: var(--c-text);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  overflow-y: auto;
}

.modal.window.erp-alert .erp-alert-head {
  margin-bottom: var(--sp-1);
}

.modal.window.erp-alert .erp-alert-title {
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  color: var(--c-danger);
  margin: 0;
}

.modal.window.erp-alert .erp-alert-section {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.modal.window.erp-alert .erp-alert-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  color: var(--c-text-2);
}

.modal.window.erp-alert .erp-alert-text {
  font-size: var(--fs-md);
  color: var(--c-text);
}

.modal.window.erp-alert .erp-alert-meta {
  background: var(--c-sunken);
  border: 1px solid var(--c-line);
  border-radius: var(--r-1);
  padding: var(--sp-3);
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--c-text-2);
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}

.modal.window.erp-alert .erp-alert-footer,
.newreg-pop > .erp-alert-footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-5);
  background: var(--c-head);
  border-top: 1px solid var(--c-line);
}

/* 상단 [알림] — 경고 모음(대표님 2026-10-17) */
.erp-tray-n { display: inline-flex; align-items: center; justify-content: center; min-width: var(--h-xs); height: var(--h-xs); padding: 0 var(--sp-1); margin-left: var(--sp-1); border-radius: var(--r-round); background: var(--c-danger); color: var(--c-on-dark); font-size: var(--fs-xs); }
.erp-tray-n[hidden] { display: none; }
.erp-alert-tray .erp-tray-row { display: flex; gap: var(--sp-2); padding: var(--sp-2) 0; border-bottom: var(--bw-hair) solid var(--c-line); cursor: pointer; }
.erp-alert-tray .erp-tray-more { padding: var(--sp-2) var(--sp-3); background: var(--c-sunken); }
.erp-alert-tray .erp-alert-footer { padding: var(--sp-2) var(--sp-3); display: flex; justify-content: flex-end; gap: var(--sp-2); }
.erp-tray-cnt { color: var(--c-text-3); margin-left: var(--sp-1); }

/* ---- 사라지는 배너 · 창 아래 한 줄 (ErpSay, erp_alert.js say) ---- */
/* ---------------- 잘됐다는 화면 아래(잘됨) · 위(안 됨) 표시 ----------------

   수정 창은 저장해도 그 자리에 남으므로(규약 `목록과창.md` 3조), 위쪽 띠 한 줄만으로는
   창에 가려 안 보인다 (대표님 2026-10-03 "실제 저장이 됐는지 눈에 띄는 식별표시가
   없어서 좀 헷갈려").

   **지나가는 표시다** — 누를 수도 없고(`pointer-events:none`), 그 밑의 글자를 가리지도
   않게 반투명하다(안 됨은 빨강). 1.6초(안 됨 4초) 뒤 스스로 사라진다. */
.done-flash {
  position: fixed; left: 50%; bottom: var(--sp-8); transform: translateX(-50%);
  /* **무엇보다 위에 뜬다.** 창에 가려 안 보이는 띠를 대신하는 것이라, 창(101)
     보다 아래 두면 만든 뜻이 없어진다 — 60 으로 두어 창 뒤에 깔렸다 (2026-10-03). */
  z-index: 1300; max-width: min(40rem, calc(100vw - var(--sp-9)));
  padding: var(--sp-5) var(--sp-7); border-radius: var(--r-3);
  background: color-mix(in srgb, var(--c-dark) 88%, transparent); color: var(--c-on-dark);
  font-size: var(--fs-xl); font-weight: var(--fw-semi); text-align: center;
  pointer-events: none; animation: done-flash .2s ease-out;
}
@keyframes done-flash { from { opacity: 0; transform: translate(-50%, var(--sp-4)); } }
/* 안 된 것 = 화면 위 빨간 배너 (대표님 2026-10-28 "경고배너는 상단, 알림배너는 하단") */
.done-flash.bad { bottom: auto; top: var(--sp-8); background: var(--c-danger); animation-name: done-flash-bad; }
@keyframes done-flash-bad { from { opacity: 0; transform: translate(-50%, calc(-1 * var(--sp-4))); } }
.done-flash.off { opacity: 0; transition: opacity .35s ease-in; }

/* 창 맨 아래 한 줄 — 띠와 같은 생김새다 (대표님 2026-10-03 "팝업창에는 이런줄이
   가장 아래에 잠깐 떴으면"). 창 안에 앉으므로 보고 있던 칸을 가리지 않는다. */
.modal .done-line {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 5;
  background: var(--c-surface); border-top: var(--bw-hair) solid var(--c-line);
  border-left: var(--bw-main) solid var(--c-primary);
  padding: var(--sp-3) var(--sp-5); font-size: var(--fs-md); color: var(--c-text);
  pointer-events: none; animation: done-line .18s ease-out;
}
@keyframes done-line { from { opacity: 0; transform: translateY(var(--sp-3)); } }
.modal .done-line.off { opacity: 0; transition: opacity .4s ease-in; }
/* 안 된 것 — 빨간 선. 읽을 시간이 더 필요해 오래 머문다 (`erp_alert.js` 의 `say`) */
.modal .done-line.bad { border-left-color: var(--c-danger); }

/* 대시보드 문자 남음 블록 */
.smsl-blk-wrap {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.smsl-blk-head {
  font-size: var(--fs-sm);
  color: var(--c-text-2);
  font-weight: var(--fw-semi);
}
.smsl-blk-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
/* 줄 꼴은 공용 .comm-card.comm-card-line(아래 통신 카드) — E1-7 2026-10-31 */
.smsl-blk-empty {
  color: var(--c-text-2);
  font-size: var(--fs-sm);
  padding: var(--sp-2) 0;
}

/* 계좌 줄의 은행 = 공용 코드칸(codes:bank, 2026-10-15) — 옛 은행 글자 칸(.acct-bank)과 같은 몫(3)을 차지한다. 폰은 반 칸 */
.acct-row .acct-item > .lookup-box { flex: 3 1 0; min-width: 0; }
@media (max-width: 700px) {
  .acct-row .acct-item > .lookup-box { flex: 1 1 46%; box-sizing: border-box; }
  /* 공용 누를 것 44px 터치 높이 (전-111 · 폰-04) */
  button, a.btn, .btn, input:not([type=hidden]):not([type=checkbox]):not([type=radio]), select, textarea, [role=button] { min-height: var(--h-touch); }
  .air-datepicker *, .top-level-tabs * { min-height: auto; }
  /* 공용 표 칸 줄임표 해제 · 줄바꿈 (전-113 · 폰-11) */
  td, th { text-overflow: clip; white-space: normal; overflow-wrap: anywhere; }
  .num, .money { white-space: nowrap; }
}

/* 보기 모드(폰 · 곁판 액자)의 맞춘 코드칸 — 코드 숫자 · 돋보기는 감추고 보이는 꼴(이름)만 글자로(2026-10-15 은행 코드칸에서 "088신한은행" 으로 보임).
   style.css 보기 모드 입력칸 규칙(color: var(--text))이 맞춘 코드칸의 투명 글자를 덮어 코드가 드러났다 */
.modal.window.view-mode .lookup-box .lookup-find { display: none; }
.modal.window.view-mode .lookup-box.is-matched:not(:has(input[data-lookup-fill])) input[data-lookup] { color: transparent; }
.modal.window.view-mode .lookup-box.is-matched:not(:has(input[data-lookup-fill])) > .lookup-name { left: 0; padding-left: 0; }

/* 공용 첨부 줄의 비고 · 이력(`{% file_list … note_url_name= hist= %}`, 2026-10-15 — 구매 첨부가 쓴다). 비고 칸은 이름 줄을 짓누르지 않게 다음 줄로 내린다 */
.file-row:has(> form.att-note) { flex-wrap: wrap; row-gap: var(--sp-1); }
.file-row > .file-name { min-width: 6em; }
.file-row > .kind, .file-row > .by, .file-row > .stamp { flex: none; white-space: nowrap; font-size: var(--fs-sm); }
.file-row > form.att-note { order: 10; flex: 1 1 100%; display: flex; align-items: center; gap: var(--sp-2); min-width: 0; padding-left: calc(var(--h-xl) + var(--sp-3)); }
.file-row > form.att-note > input[name="note"] { flex: 1 1 auto; min-width: 0; }
.file-row > .att-note-text { order: 10; flex: 1 1 100%; padding-left: calc(var(--h-xl) + var(--sp-3)); color: var(--c-text-2); font-size: var(--fs-sm); }
.att-hist-box { margin: var(--sp-1) 0 var(--sp-3) calc(var(--h-xl) + var(--sp-3)); }
/* customers 조각 (전-21) */
.cust-clash-item { width: 26%; }
.cust-dup-check { width: var(--h-lg); }
.cust-dup-code { width: 22%; }
.cust-dup-date { width: 14%; }
.cust-dup-action { width: 10%; }
.cust-trail-seq { width: 5em; }
.cust-trail-code { width: 12em; }
.cust-trail-date { width: 14em; }
.cust-trail-name { width: 14em; }

/* contacts 조각 (전-21) */
.cont-dedupe-check { width: var(--h-lg); }
.cont-dedupe-phone { width: 16%; }
.cont-dedupe-org { width: 18%; }
.cont-dedupe-action { width: 10%; }
.cont-dedupe-name { width: 22%; }
.cont-dedupe-date { width: 14%; }
.cont-dedupe-gname { width: 28%; }
.cont-dedupe-gphone { width: 22%; }
.cont-dedupe-why { width: 16%; }
.cont-form-inline { display: inline; }
.cont-cell-actions { text-align: right; }
.cont-change-kind { width: 9%; }
.cont-change-name { width: 26%; }
.cont-change-date { width: 13%; }
.cont-change-act { width: 12%; }
.cont-bulk-seq { width: 8%; }
.cont-bulk-date { width: 16%; }
.cont-bulk-file { width: 26%; }
.cont-bulk-state { width: 10%; }
.cont-nofloat { float: none; }
.cont-cardlog-time { width: var(--h-touch); }
.cont-cardlog-pics { width: 10em; }
.cont-cardlog-name { width: 26%; }
.cont-cardlog-role { width: 16%; }
.cont-cardlog-phone { width: 8.5em; }

/* 공용 조각 (전-21) */
.listspec-col { width: auto; }
.formspec-col-grip { width: 6%; }
.formspec-col-name { width: 28%; }
.formspec-col-label { width: 24%; }
.formspec-col-kind { width: 14%; }
.formspec-col-box { width: 10%; }
.formspec-cell-actions { text-align: right; white-space: nowrap; }
.formspec-ret-hint { margin-top: var(--sp-2); }
.formspec-ret-key { width: 18%; }
.formspec-ret-label { width: 28%; }
.formspec-ret-name { width: 22%; }
.formspec-ret-kind { width: 14%; }

/* configuration 호스트 판 .cfg-* (전-22) */
.cfg-form-act { margin-top: var(--sp-2); }
.cfg-alarms td.cfg-cell-nowrap { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfg-alarms-sub { margin-bottom: var(--sp-3); }
.cfg-alarms-empty { text-align: center; padding: var(--sp-6); }
.cfg-col-dep-at { width: 13%; }
.cfg-col-dep-who { width: 11%; }
.cfg-col-dep-why { width: 37%; }
.cfg-col-dep-branch { width: 13%; }
.cfg-col-dep-commits { width: 9%; }
.cfg-col-dep-migr { width: 10%; }
.cfg-col-dep-act { width: 7%; }
.cfg-col-moves-h { width: 12%; }
.cfg-col-moves-at { width: 16%; }
.cfg-col-moves-subj { width: 72%; }
.cfg-col-migr-name { width: 70%; }
.cfg-col-migr-at { width: 30%; }
.cfg-col-job-what { width: 13%; }
.cfg-col-job-when { width: 12%; }
.cfg-col-job-role { width: 6%; }
.cfg-col-job-last { width: 9%; }
.cfg-col-job-res { width: 16%; }
.cfg-col-job-fails { width: 6%; }
.cfg-col-job-sig { width: 9%; }
.cfg-col-job-say { width: 22%; }
.cfg-col-job-act { width: 7%; }
.cfg-col-hist-at { width: 14%; }
.cfg-col-hist-res { width: 10%; }
.cfg-col-hist-why { width: 68%; }
.cfg-col-hist-sec { width: 8%; }

.cfg-wrap { display: flex; gap: var(--sp-6); align-items: flex-start; flex-wrap: wrap; }
.cfg-box { flex: 1 1 23.75rem; min-width: 0; max-width: 38.75rem; margin-bottom: var(--sp-4); }
.cfg-wide { flex: 1 1 100%; max-width: none; }
.cfg-box h3 { font-size: var(--fs-lg); margin: 0 0 var(--sp-3); }
.cfg-box .field-row { margin: 0 0 var(--sp-2); }
.cfg-box .field-row label { width: 7em; flex: none; }
.cfg-box .field-row input[type=text], .cfg-box .field-row input[type=password] { flex: 1; min-width: 0; }
.cfg-box .btn { min-height: var(--h-sm); padding: 0 var(--sp-5); }
.cfg-box .btn-small { height: var(--h-sm); padding: 0 var(--sp-3); }
.cfg-box form.inline { display: inline; margin: 0; }
.cfg-box .hint-line { font-size: var(--fs-md); color: var(--text-muted); margin: var(--sp-1) 0 0; }
.lamp.warn { background: var(--c-warn); box-shadow: 0 0 0 var(--sp-1) rgba(232,130,12,.22); }
.cfg-warn { color: var(--c-warn); font-size: var(--fs-md); margin: 0 0 var(--sp-1); }
.cfg-kv { width: 100%; border-collapse: collapse; font-size: var(--fs-md); table-layout: fixed; }
.cfg-kv th { width: 8.5em; text-align: left; font-weight: 500; color: var(--text-muted); padding: var(--sp-1) var(--sp-2); white-space: nowrap; }
.cfg-kv td { padding: var(--sp-1) var(--sp-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfg-kv td.warn { color: var(--c-warn); }
.cfg-alarms { width: 100%; border-collapse: collapse; font-size: var(--fs-md); table-layout: fixed; }
.cfg-alarms th, .cfg-alarms td { border-bottom: 1px solid var(--c-line); padding: var(--sp-1) var(--sp-2); text-align: left;
                                 overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cfg-alarms .st-open { color: var(--c-danger); font-weight: var(--fw-semi); }
.cfg-alarms tr.sub-row td { background: var(--c-page); white-space: normal; }
.cfg-alarms tr.sub-row[hidden] { display: none; }
.cfg-alarms.inner { font-size: var(--fs-sm); }
.cfg-box table, .hist-box table.hist { width: 100%; border-collapse: collapse; font-size: var(--fs-md); }
.cfg-box table { table-layout: fixed; }
.cfg-box th, .cfg-box td, .hist-box th, .hist-box td { border-bottom: 1px solid var(--c-line); padding: var(--sp-1) var(--sp-2); text-align: left; }
.cfg-box td, .h-what { word-break: break-all; }
.cfg-box .note, .app-note { display: block; font-size: var(--fs-sm); color: var(--c-text-2); margin-top: var(--sp-1); }
.win-id-badge, .app-win-id-badge { font-size: var(--fs-sm); color: var(--c-text-2); font-family: var(--font-mono); font-weight: normal; margin-left: var(--sp-4); }
.group-title, .app-group-title { font-size: var(--fs-lg); margin: var(--sp-6) 0 var(--sp-3); font-weight: var(--fw-bold); color: var(--c-text); }
.act-row, .app-act-row { margin-top: var(--sp-6); display: flex; gap: var(--sp-4); align-items: center; }
.hist-box { margin-top: var(--sp-5); background: var(--c-sunken); border: 1px solid var(--c-line); padding: var(--sp-4); border-radius: var(--r-2); }
.hist-title { font-weight: var(--fw-bold); font-size: var(--fs-md); margin-bottom: var(--sp-3); color: var(--c-text); }
.app-col-label { width: 28%; }
.app-col-val { width: 72%; }
.app-input-num { width: 6em; padding: var(--sp-1) var(--sp-2); }
.app-input-text { width: 65%; min-width: 8.75rem; padding: var(--sp-1) var(--sp-2); }
.app-guide-title { margin-top: var(--sp-7); }

/* 칸 견본 (전-22) */
.field-error { color: var(--c-danger); font-size: var(--fs-sm); margin-top: var(--sp-1); }
.field-guide-muted { color: var(--text-muted); font-size: var(--fs-sm); }
.field-guide-gap { color: var(--c-danger); font-weight: var(--fw-semi); }
.field-guide-actions { margin-top: var(--sp-3); display: flex; gap: var(--sp-2); align-items: center; }
.field-guide-list { margin: var(--sp-2) 0; padding-left: var(--sp-5); font-size: var(--fs-md); }
.field-guide-list li { margin-bottom: var(--sp-1); }
.field-guide-group th { background: var(--c-head); text-align: left; font-weight: var(--fw-bold); }
#guideLines { table-layout: fixed; width: 100%; }
#guideLines th:first-child { width: 5ch; text-align: center; }
#guideLines th[data-field="item_code"] { width: 14ch; }
#guideLines th[data-field="item_name"] { width: 30%; }
#guideLines th[data-field="spec"] { width: 18%; }
#guideLines th[data-field="unit"] { width: 8ch; }
#guideLines th[data-field="qty"] { width: 9ch; }
#guideLines th[data-field="price"] { width: 13ch; }
#guideLines th[data-field="amount"] { width: 14ch; }
#guideLines th[data-field="remarks"] { width: 14%; }
.lines-result-table { table-layout: fixed; width: 60ch; max-width: 100%; margin-top: var(--sp-2); }
.lines-result-table th:first-child { width: 6ch; text-align: center; }
.lines-result-table th:nth-child(2) { width: 14ch; }
.lines-result-table th:nth-child(3) { width: 10ch; }
.lines-result-table th:nth-child(4) { width: 14ch; }
.lines-result-table th:nth-child(5) { width: 16ch; }
.fg-sec { margin: 0 0 var(--sp-8); }
.fg-tree { list-style: none; margin: 0; padding-left: var(--sp-6); min-height: var(--h-sm); }
.fg-move > .fg-tree { padding-left: 0; }
.fg-node { display: flex; align-items: center; gap: var(--sp-2); min-height: var(--h-md); border-bottom: 1px solid var(--c-line); }
.fg-mt-3 { margin-top: var(--sp-3); }
.fg-mt-4 { margin-top: var(--sp-4); }
.fg-center { text-align: center; }

/* 폰 미리보기 (전-22) */
body.phone-preview { margin: 0; min-height: 100vh; background: var(--c-dark); color: var(--c-on-dark); font: var(--fs-xl)/1.4 system-ui, sans-serif;
       display: flex; flex-direction: column; align-items: center; gap: var(--sp-5); padding: 0.875rem 0; box-sizing: border-box; }
.phone-preview .bar { display: flex; align-items: center; gap: var(--sp-3); width: 24.375rem; }
.phone-preview .bar a, .phone-preview .bar button, .phone-preview .bar .btn.btn-icon { width: auto; color: var(--c-on-dark); background: var(--c-dark); border: 0; border-radius: var(--r-3); padding: var(--sp-3) var(--sp-5); text-decoration: none; font: inherit; cursor: pointer; }
.phone-preview .bar .path { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--c-text-3); font-size: var(--fs-md); }
.phone-preview .phone { width: 24.375rem; height: 52.75rem; max-height: calc(100vh - 5.625rem); border: var(--sp-5) solid var(--c-line-strong); border-radius: 1.75rem; overflow: hidden; background: var(--c-surface); box-shadow: 0 var(--sp-5) 2.5rem rgba(0,0,0,.5); }
.phone-preview .phone iframe { display: block; width: 100%; height: 100%; border: 0; }

/* 뷰어 시연 (전-22) */
.vw-demo-head { font-size: var(--fs-md); color: var(--text-muted); margin: 0 0 var(--sp-3); }
body:has(.vw-demo-head) { padding: var(--sp-4) var(--sp-6); }
body.vw-solo { padding: 0; height: 100vh; height: 100dvh; overflow: hidden; }

/* 오류 안내 페이지 (전-21 · 꼴-05) */
.alert-page-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 65vh;
  padding: var(--sp-6);
}
.alert-page-card {
  width: 100%;
  max-width: 36.25rem;
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--r-2);
  box-shadow: 0 var(--sp-1) var(--sp-5) rgba(0, 0, 0, 0.08);
  overflow: hidden;
}
.alert-page-header {
  background: var(--c-sunken);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--c-line);
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.alert-page-title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  color: var(--c-text);
}
.alert-page-badge {
  font-family: monospace;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-1);
  background: var(--c-danger-bg);
  color: var(--c-danger);
}
.alert-page-body {
  padding: var(--sp-5);
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--c-text);
}
.alert-page-section {
  margin-bottom: var(--sp-3);
}
.alert-page-section-last {
  margin-bottom: var(--sp-4);
}
.alert-page-label {
  display: block;
  font-weight: var(--fw-semi);
  color: var(--c-text-2);
  margin-bottom: var(--sp-1);
}
.alert-page-box {
  background: var(--c-sunken);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-1);
  font-weight: 500;
}
.alert-page-desc {
  color: var(--c-text);
}
.alert-page-meta {
  background: var(--c-sunken);
  border: 1px solid var(--c-line);
  border-radius: var(--r-1);
  padding: var(--sp-3);
  font-size: var(--fs-xs);
  color: var(--c-text-2);
  font-family: monospace;
  line-height: 1.7;
}
.alert-page-footer {
  background: var(--c-sunken);
  padding: var(--sp-3) var(--sp-5);
  border-top: 1px solid var(--c-line);
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
}

/* users (전-21) */
.user-col-id { width: 8%; }
.user-col-username { width: 14%; }
.user-col-pw { width: 14%; }
.user-col-groups { width: 12%; }
.user-col-status { width: 16%; }
.user-col-link { width: 8%; }
.user-group-col-stat { width: 14%; }
.user-first-pw-desc {
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--c-text-2);
  line-height: 1.5;
}
.user-first-pw-error {
  margin-bottom: var(--sp-3);
}
.user-field-error {
  color: var(--c-danger);
  font-size: var(--fs-xs);
  margin-top: var(--sp-1);
}
.user-first-pw-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: var(--sp-5);
}
.user-logout-btn {
  background: none;
  border: 1px solid var(--border);
  color: var(--text);
}
.user-submit-btn {
  margin: 0;
}


/* LLM adapter (전-21) */
.llm-hidden { display: none; }
.llm-tabs-spaced { margin-right: var(--sp-2); }
.llm-raw-box {
  margin: var(--sp-2) 0;
  background: var(--header-bg, var(--c-head));
  border: 1px solid var(--border, var(--c-line));
  color: var(--text, var(--c-text));
  min-height: calc(var(--h-touch) * 5);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--sp-4);
}
.llm-raw-text {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--text-muted, var(--c-text-2));
}
.llm-ap-lbl { margin-left: var(--sp-3); }
.llm-ap-schedule {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.llm-now-btn { white-space: nowrap; flex: none; }
.llm-cdx-input { padding: 0 var(--sp-1); height: var(--h-sm); }
.llm-full-select { width: 100%; }

.llm-col-conn-name { width: 17%; }
.llm-col-conn-kind { width: 15%; }
.llm-col-conn-acct { width: 23%; }
.llm-col-conn-state { width: 13%; }
.llm-col-conn-pii { width: 20%; }
.llm-col-conn-main { width: 12%; }

.llm-col-mon-conn { width: 14%; }
.llm-col-mon-state { width: 10%; }
.llm-col-mon-duties { width: 34%; }
.llm-col-mon-using { width: 22%; }
.llm-col-mon-calls { width: 10%; }
.llm-col-mon-act { width: 10%; }

.llm-col-rec-time { width: 14%; }
.llm-col-rec-task { width: 20%; }
.llm-col-rec-conn { width: 15%; }
.llm-col-rec-model { width: 17%; }
.llm-col-rec-res { width: 9%; }
.llm-col-rec-tok { width: 11%; }
.llm-col-rec-dur { width: 14%; }

.llm-col-task-feat { width: 17%; }
.llm-col-task-name { width: 18%; }
.llm-col-task-pii { width: 6%; }
.llm-col-task-needs { width: 10%; }
.llm-col-task-level { width: 7%; }
.llm-col-task-route { width: 32%; }
.llm-col-task-over { width: 10%; }

.llm-col-mod-id { width: 30%; }
.llm-col-mod-name { width: 22%; }
.llm-col-mod-cap { width: 16%; }
.llm-col-mod-st { width: 20%; }
.llm-col-mod-act { width: 12%; }

.llm-col-asg-pick { width: 8%; }
.llm-col-asg-task { width: 36%; }
.llm-col-asg-model { width: 56%; }

.llm-col-rt-pick { width: 7%; }
.llm-col-rt-ord { width: 9%; }
.llm-col-rt-conn { width: 26%; }
.llm-col-rt-model { width: 32%; }
.llm-col-rt-why { width: 26%; }

.llm-col-sm-id { width: 36%; }
.llm-col-sm-name { width: 28%; }
.llm-col-sm-cap { width: 20%; }
.llm-col-sm-st { width: 16%; }

.llm-col-call-time { width: 14%; }
.llm-col-call-task { width: 18%; }
.llm-col-call-conn { width: 14%; }
.llm-col-call-try { width: 5%; }
.llm-col-call-tok { width: 7%; }
.llm-col-call-dur { width: 8%; }
.llm-col-call-res { width: 8%; }
.llm-col-call-note { width: 18%; }
.llm-col-call-by { width: 8%; }

.llm-col-ap-lvl { width: 12%; }
.llm-col-ap-agy { width: 32%; }
.llm-col-ap-cdx { width: 28%; }
.llm-col-ap-eff { width: 14%; }
.llm-col-ap-upd { width: 14%; }

.llm-col-run-time { width: 14%; }
.llm-col-run-trig { width: 10%; }
.llm-col-run-who { width: 12%; }
.llm-col-run-dur { width: 8%; }
.llm-col-run-calls { width: 8%; }
.llm-col-run-res { width: 10%; }
.llm-col-run-sum { width: 38%; }

.llm-col-app-time { width: 14%; }
.llm-col-app-who { width: 12%; }
.llm-col-app-what { width: 18%; }
.llm-col-app-chg { width: 26%; }
.llm-col-app-rsn { width: 30%; }

.llm-col-reco-apply { width: 6%; }
.llm-col-reco-task { width: 18%; }
.llm-col-reco-now { width: 24%; }
.llm-col-reco-prop { width: 28%; }
.llm-col-reco-why { width: 24%; }

.llm-col-log-time { width: 15%; }
.llm-col-log-task { width: 19%; }
.llm-col-log-conn { width: 15%; }
.llm-col-log-try { width: 5%; }
.llm-col-log-dur { width: 8%; }
.llm-col-log-res { width: 9%; }
.llm-col-log-note { width: 20%; }
.llm-col-log-by { width: 9%; }
/* 공용 조각 style= 걷기 (전-21) */
.cards-up-form { display: none; }
.card-col-when { width: 14%; }
.card-col-by { width: 10%; }
.card-col-status { width: 12%; }
.card-col-actions { width: 8%; }
.card-hist-when { width: 24%; }
.card-hist-who { width: 16%; }
.card-hist-act { width: 16%; }
.card-hist-desc { width: 44%; }

.innerdoc-hint-empty { padding: var(--sp-4); }
.innerdoc-search-bar {
  display: flex;
  gap: var(--sp-2);
  align-items: center;
  margin-bottom: var(--sp-2);
}
.innerdoc-search-input { flex: 1; }

.pend-col-req { width: 4.75rem; }
.pend-col-date { width: 6.5rem; }
.pend-col-user { width: 5.25rem; }
.pend-col-path { width: 4.125rem; }
.pend-col-name { width: 30%; }
.pend-col-result { width: 6.875rem; }

.pend-trash-when { width: 16%; }
.pend-trash-actions {
  width: 14%;
  text-align: right;
}
.pend-trash-form { display: inline; }

.base-logout-form { display: inline; }

.col-star { width: var(--sp-9); }
.col-w22 { width: 22%; }
.col-w12 { width: 12%; }

/* 눌러서 복사 공용 칩(data-copy-text) · 대표님 2026-10-22 */
[data-copy-text] {
  cursor: pointer;
  border-radius: var(--r-1);
  padding: 0 var(--sp-1);
  transition: transform 0.15s ease-out, background-color 0.15s ease-out;
}

[data-copy-text]:hover {
  background: var(--c-hover);
}

[data-copy-text]:active,
[data-copy-text].is-copied {
  transform: scale(0.95);
  background: var(--c-selected);
}

/* 값은 줄이고 [복사]는 늘 보이게 — 연락처 리스트 2026-11-02 */
.copy-cell { display: flex; align-items: center; gap: var(--sp-1); min-width: 0; }
.copy-cell-val { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.copy-cell > .copy-btn, .copy-cell > .lamp { flex: none; }

/* ---- 단추 일곱 가지 · 크기 둘 (대표님 2026-10-23 "주의(주황)도 따로 두어 일곱 가지로", docs/설계_단추통일_결정_2026-10-23.md) ---- */
/* 주 btn-primary · 보통 btn-secondary · 위험 btn-danger 색은 btn_kinds.css — style.css 를 안 부르는 공유 화면도 같은 색 (2026-10-24) */
/* 크기: 보통 .btn, 작은 btn-small 두 가지뿐 */

.btn-warn {
  background: color-mix(in srgb, var(--c-warn) 14%, var(--c-surface));
  color: var(--c-warn);
  border-color: var(--c-warn);   /* 테두리를 그리는 판(공유 끝 줄)만 보인다 — 보통 .btn 은 테두리 없음 */
}
.btn-warn:hover {
  background: color-mix(in srgb, var(--c-warn) 24%, var(--c-surface));
}

.btn.btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  width: var(--h-md);
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  color: var(--c-text-2);
  font-size: var(--fs-lg);
  line-height: 1;
}
.btn.btn-icon.btn-small {
  width: var(--h-sm);
}
.btn.btn-icon svg {
  width: var(--fs-xl);
  height: var(--fs-xl);
}
.btn.btn-icon.btn-small svg {
  width: var(--fs-lg);
  height: var(--fs-lg);
}
.btn.btn-icon:hover,
.btn.btn-icon.on {
  color: var(--c-primary);
  border-color: var(--c-primary);
}

.btn.btn-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  color: var(--c-text-2);
  cursor: pointer;
  white-space: nowrap;
}
.btn.btn-toggle:hover {
  background: var(--c-hover);
}
.btn.btn-toggle.active,
.btn.btn-toggle.on,
.btn.btn-toggle:has(> input:checked) {
  background: var(--c-primary);
  border-color: var(--c-primary);
  color: var(--c-on-dark);
}
.btn.btn-toggle.btn-toggle-danger:has(> input:checked) {
  background: var(--c-danger);
  border-color: var(--c-danger);
  color: var(--c-on-dark);
}
.btn.btn-toggle > input[type=checkbox],
.btn.btn-toggle > input[type=radio] {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  pointer-events: none;
}
.btn.btn-toggle:has(> input:focus-visible) {
  outline: var(--bw-head) solid var(--c-primary);
  outline-offset: 1px;
}
.btn.btn-toggle:has(> input:disabled) {
  opacity: .5;
  cursor: not-allowed;
}
.btn.btn-toggle span,
.acct-item .btn.btn-toggle span {
  color: inherit;
  font-size: inherit;
}

/* 거르개 칩 = 켜고끄기 작은 단추 (대표님 2026-10-23 "거르개 칩(filter-chip)도 켜고끄기 단추로 합쳐줘")
   style.css .filter-chip 의 칩 꼴(덧칠 테두리 · 폰 32px)을 btn-small 크기로 되돌린다 */
.btn.btn-toggle.filter-chip {
  height: var(--h-sm);
  min-height: var(--h-sm);
  padding: 0 var(--sp-3);
  font-size: var(--fs-sm);
}
.btn.btn-toggle.filter-chip:not(.on):hover {
  border-color: var(--c-line);
}
.btn.btn-toggle > .filter-n {
  margin-left: 0;
  opacity: .65;
}
@media (max-width: 700px) {
  .btn.btn-toggle.filter-chip {
    min-height: var(--h-touch);
    padding: 0 var(--sp-4);
    font-size: var(--fs-xl);
  }
}

.btn.btn-link {
  background: none;
  border: 0;
  padding: 0 var(--sp-1);
  color: var(--c-primary);
}
.btn.btn-link:hover {
  text-decoration: underline;
  background: none;
}

/* 상대 뚜껑(이름 · 번호 · 심볼 줄) — 통화 상세 · 문자 대화가 같이 씀 */
.party-line {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  color: var(--c-text);
  flex-wrap: wrap;
}

.party-num {
  font-size: var(--fs-md);
  color: var(--c-text-2);
  font-weight: var(--fw-normal);
  cursor: pointer;
}

.party-sub {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--c-text-2);
  flex-wrap: wrap;
}
/* 통신 머리 줄(통화 상세 · 문자 한 줄) 한 벌 — 칸은 안 쪼개고, 모자라면 단추 칸이 아랫줄로(24-94). 좁은 창 셈은 여기 한 곳 */
.comm-meta > .comm-meta-item { white-space: nowrap; flex-shrink: 0; }
.comm-meta > .comm-meta-text { min-width: 0; overflow-wrap: anywhere; }
.comm-meta > .comm-meta-act { flex: none; margin-left: auto; }
.comm-meta .is-strong { font-weight: var(--fw-semi); color: var(--c-text-2); }
.comm-meta .is-bad { color: var(--c-danger); }
.comm-meta-sm { gap: var(--sp-1) var(--sp-3); font-size: var(--fs-xs); color: var(--c-text-3); }

/* 통신 카드 · 말풍선 · 수 띠 — 카드 꼴은 .comm-cards 안에서만 적용(기존 화면 보존) */
.comm-cards { display: flex; flex-direction: column; container-type: inline-size; container-name: comm; }
:where(.comm-cards) .comm-card { display: flex; align-items: flex-start; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3); border-bottom: var(--bw-hair) solid var(--c-line); background: var(--c-surface); color: var(--c-text); text-decoration: none; min-width: 0; box-sizing: border-box; }
:where(.comm-cards) .comm-card-main { display: flex; flex: 1 1 auto; min-width: 0; flex-direction: column; gap: var(--sp-1); }
:where(.comm-cards) .comm-card-l1 { display: flex; gap: var(--sp-2); align-items: baseline; min-width: 0; font-size: var(--fs-md); line-height: var(--lh-1); }
:where(.comm-cards) .comm-card-name { font-weight: var(--fw-semi); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 4em; flex: 0 1 auto; }
:where(.comm-cards) .comm-card-l2 { display: flex; gap: var(--sp-2); min-width: 0; font-size: var(--fs-sm); color: var(--c-text-2); }
:where(.comm-cards) .comm-card-text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
:where(.comm-cards) .comm-card-dur { flex: none; }
:where(.comm-cards) .comm-card-act { flex: none; display: flex; gap: var(--sp-1); align-items: center; }
:where(.comm-cards) .comm-card-side { display: flex; flex: 0 0 auto; flex-direction: column; align-items: flex-end; gap: var(--sp-1); max-width: 40%; min-width: 0; }
:where(.comm-cards) .comm-card-time { font-size: var(--fs-xs); color: var(--c-text-3); white-space: nowrap; font-variant-numeric: tabular-nums; }
:where(.comm-cards) .comm-card-time.is-today { font-weight: var(--fw-bold); color: var(--c-text); }
:where(.comm-cards) .comm-card-sub { font-size: var(--fs-xs); color: var(--c-text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
:where(.comm-cards) .comm-card.comm-card-line .comm-card-main { flex-direction: row; align-items: baseline; }
:where(.comm-cards) .comm-card.comm-card-line .comm-card-l2 { flex: 1 1 auto; }
/* 한 줄 꼴 이름 칸은 줄지 않고 반까지만 — 긴 글이 이름을 깎던 것(E1-7 2026-10-31) */
:where(.comm-cards) .comm-card.comm-card-line .comm-card-l1 { flex: 0 0 auto; max-width: 50%; }
:where(.comm-cards) .comm-card.way-in { background: var(--c-ok-bg); }
:where(.comm-cards) .comm-card.way-out { background: var(--c-violet-bg); }
:where(.comm-cards) .comm-card.way-miss { background: var(--c-danger-bg); color: var(--c-text-2); }
:where(.comm-cards) .comm-card:hover { background: var(--c-hover); }
:where(.comm-cards) .comm-card.on { background: var(--c-selected); font-weight: var(--fw-semi); box-shadow: inset 0 0 0 var(--bw-head) var(--c-primary); }
:where(.comm-cards) .comm-card:focus-visible { outline: none; box-shadow: inset 0 0 0 var(--bw-head) var(--c-primary); }
:where(.comm-cards) .comm-card.is-done > * { opacity: .5; }
:where(.comm-cards) .comm-card.is-done > .comm-card-act { opacity: 1; }
/* 할 일 메모 표시는 메모 칸 쪽 */
/* 대표님 2026-10-16 진한 남색 바탕 + 밝은 글자(마우스를 올렸을 때의 파란 강조와 헷갈리지 않게) */
:where(.comm-cards) .comm-card.is-unread { background: color-mix(in srgb, var(--c-primary-hover) 55%, var(--c-dark)); color: var(--c-on-dark); }
:where(.comm-cards) .comm-card.is-unread:hover { background: color-mix(in srgb, var(--c-primary-hover) 70%, var(--c-dark)); }
:where(.comm-cards) .comm-card.is-unread .comm-card-name,
:where(.comm-cards) .comm-card.is-unread .comm-card-text,
:where(.comm-cards) .comm-card.is-unread .comm-card-time,
:where(.comm-cards) .comm-card.is-unread .comm-card-sub,
:where(.comm-cards) .comm-card.is-unread .comm-card-dur { color: var(--c-on-dark); }
:where(.comm-cards) .comm-card.is-unread .comm-card-name,
:where(.comm-cards) .comm-card.is-unread .comm-card-text { font-weight: var(--fw-bold); }
:where(.comm-cards) .comm-card.is-unread.on { background: var(--c-selected); color: var(--c-text); }
:where(.comm-cards) .comm-card.is-unread.on .comm-card-name,
:where(.comm-cards) .comm-card.is-unread.on .comm-card-text,
:where(.comm-cards) .comm-card.is-unread.on .comm-card-dur { color: var(--c-text); }
:where(.comm-cards) .comm-card.is-unread.on .comm-card-time,
:where(.comm-cards) .comm-card.is-unread.on .comm-card-sub { color: var(--c-text-3); }
.comm-badge { display: inline-block; flex: none; border-radius: var(--r-3); background: var(--c-primary); color: var(--c-on-dark); font-size: var(--fs-xs); padding: 0 var(--sp-3); }
:where(.comm-cards) .comm-card.is-unread .comm-badge { background: var(--c-on-dark); color: var(--c-primary-hover); }
:where(.comm-cards) .comm-card.is-unread.on .comm-badge { background: var(--c-primary); color: var(--c-on-dark); }
@container comm (max-width: 22.5em) { :where(.comm-cards) .comm-card-sub { display: none; } }

.comm-bubbles { display: flex; flex-direction: column; gap: var(--sp-2); container-type: inline-size; container-name: bubbles; }
/* 칸 폭 = 머리 줄(날짜 · 단추)과 글 중 넓은 쪽, 풍선은 그 폭까지 채운다 — 칸만 넓고 풍선은 좁던 것(대표님 2026-10-31 "관련 버튼이나 기능들이 점유하는 폭까지는 맞춰서 넓혀라") */
.comm-bubble-wrap { display: flex; flex-direction: column; gap: var(--sp-1); max-width: 85%; }
.comm-bubble-wrap.in { align-self: flex-start; }
.comm-bubble-wrap.out { align-self: flex-end; align-items: flex-end; }
.comm-bubble-top { display: flex; flex-wrap: wrap; align-items: center; width: 100%; }
/* 단추는 날짜 바로 오른쪽 — 오른 끝으로 밀지 않음(대표님 2026-10-31 "왜 저렇게 멀리 떨어져있냐") */
.comm-bubble-top.comm-meta > .comm-meta-act { margin-left: 0; }
.comm-bubble { position: relative; display: flex; flex-direction: column; gap: var(--sp-1); padding: var(--sp-2) var(--sp-3); border-radius: var(--r-2); border: var(--bw-hair) solid var(--c-line); background: var(--c-surface); align-self: stretch; max-width: 100%; }
.comm-bubble.in { background: var(--c-sunken); }
.comm-bubble.out { background: var(--c-selected); }
.comm-bubble.is-hit { border-color: var(--c-primary); box-shadow: inset 0 0 0 var(--bw-hair) var(--c-primary); background: var(--c-note-bg); }
.comm-bubble-text { font-size: var(--fs-md); line-height: var(--lh-text); white-space: pre-wrap; overflow-wrap: anywhere; }
.comm-bubble-parts { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--sp-2); }
@container bubbles (max-width: 22.5em) {
  .comm-bubble-wrap { max-width: 100%; min-width: 0; align-self: stretch; }
  .comm-bubble { width: auto; }
}

/* 공용 조각 단추 일곱 가지(2026-10-23 대표님 "공용 조각(뷰어 · 블록 막대 · 카드)부터 일곱 가지로 바꿔줘")
   뷰어 도구줄 · 이력 판은 촘촘 꼴(--h-md) 그대로 — 폰 .btn 손가락 규칙(44px)이 뷰어 안까지 키우지 않게 */
.vw-tools .btn.btn-icon { width: var(--h-md); min-width: var(--h-md); padding: 0; }
.vw-tools .btn.btn-icon.vw-fit-btn, .vw-tools .btn.btn-icon.vw-full-btn { width: auto; padding: 0 var(--sp-2); }
.vw-tools .btn.btn-icon > svg { width: var(--fs-xl); height: var(--fs-xl); }
.vw-hist-head .btn.btn-icon.vw-hist-fold { width: var(--h-md); min-width: var(--h-md); }
.btn.btn-toggle[aria-pressed="true"] { background: var(--c-primary); border-color: var(--c-primary); color: var(--c-on-dark); }   /* [이력] · [비교] 켬 — aria-pressed 로 켜는 켜고끄기 */
@media (max-width: 700px) {
  .vw-tools .btn, .vw-hist .btn, .vw-ver .btn, .vw-foot .btn { min-width: 0; font-size: var(--fs-md); }
}
/* 블록 머리 [새로고침] 메뉴 줄은 메뉴 꼴 그대로(옆 a 와 같은 줄) */
.blk-menu .btn.btn-link { display: flex; align-items: center; justify-content: flex-start; width: 100%; height: var(--h-md); padding: 0 var(--sp-3); color: var(--c-text); font-weight: inherit; border-radius: 0; }
.blk-menu .btn.btn-link:hover { background: var(--c-hover); color: var(--c-primary); text-decoration: none; }
/* 블록 빼기 ✕ 점 · 표 [+][삭제][위][아래] 는 옛 꼴(빨간 점 · 테 네모)이 그대로 이긴다 */
.btn.btn-danger.del-dot { padding: 0; font-weight: var(--fw-normal); }
.btn.btn-icon.dg-btn { width: var(--h-md); }
@media (max-width: 700px) { .btn.btn-icon.dg-btn { width: var(--h-touch); height: var(--h-touch); } }
/* 옛 숨김 · 크기 규칙 지키기 — .btn.btn-icon(두 클래스 · inline-flex)이 style.css · 위 규칙의 같은 무게 숨김을 이기지 않게 */
.vw-tools > .btn.vw-exit, .vw-cmp .btn.vw-exit { display: none; }
.vw-solo .vw-tools > .btn, .vw-solo .btn.vw-hist-btn { display: none; }
.vw-solo .vw-tools > .btn.vw-full-btn, .vw-solo .vw-tools > .btn[data-act="rot"], .vw-solo .vw-tools > .btn[data-act="dl"], .vw-solo .vw-tools > .btn.vw-exit { display: inline-flex; }
.btn.btn-danger.del-dot { min-height: 0; min-width: 0; }
@container blkhead (max-width: 230px) { .btn.btn-icon.blk-tool { width: var(--h-sm); min-width: 0; } }
@container blkhead (max-width: 200px) { .btn.btn-icon.blk-tool { width: var(--h-xs); } }
@media (max-width: 700px) { .blk-tools .btn[data-keep-open] { display: none; } .btn.btn-danger.del-dot { min-height: var(--h-touch); } }


/* 메모 부품 (templates/_memo.html) */
.memo {
  font-size: var(--fs-xs);
  color: var(--c-text-3);
}

.memo-view {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}

.memo-meta {
  color: var(--c-text-3);
}

.memo-text {
  color: var(--c-text);
  word-break: break-word;
}

.memo-done {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-xs);
  color: var(--c-text-2);
  cursor: pointer;
  accent-color: var(--c-primary);
  margin: 0;
}

.memo-edit {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}

.memo-ipt,
.memo-edit textarea {
  width: 100%;
}

.memo-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.memo-hist,
.memo-share {
  margin-top: var(--sp-2);
}

.memo-hist .h-see,
.memo-hist .del {
  display: none;
}

.memo-snap-text {
  padding: var(--sp-2);
  white-space: pre-wrap;
}

.memo-view .memo-edit-btn.btn-secondary {
  height: auto;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
  color: var(--c-link);
}

.memo-view .memo-edit-btn.btn-secondary:hover {
  text-decoration: underline;
}

.memo-edit-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.memo-ctl {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  line-height: 1;
}

.memo-ctl input[type="checkbox"] {
  margin: 0;
}

.memo-ctl > button,
.memo-ctl > a {
  display: inline-flex;
  align-items: center;
  line-height: 1;
}

.memo.is-open {
  background: color-mix(in srgb, var(--c-warn) 16%, var(--c-surface));
  border-radius: var(--r-2);
}

.memo-edit-btn svg {
  width: var(--fs-sm);
  height: var(--fs-sm);
}

/* 남음 꼬리표 (문자 · 통화 공용) */
.todo-tag {
  display: inline-block;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semi);
  color: var(--c-warn);
}


/* 남은 공용 조각 단추 일곱 가지(2026-10-23 대표님 "남은 공용 조각도 일곱 가지로 바꿔줘")
   옛 꼴(숨은 기본 제출 · 첨부 줄 이름 · 뗌 ✕ · 기간 달력 · 공유 메뉴 줄 · [APP] · 셔터)을 .btn 이 덮지 않게 — 두 클래스 무게로 되돌린다 */
.btn.default-submit, .modal.window .btn.default-submit { position: absolute; width: 0; height: 0; min-width: 0; min-height: 0; padding: 0; border: 0; opacity: 0; overflow: hidden; }
.file-row .btn.file-name, .file-row .btn.file-x { height: auto; min-height: 0; min-width: 0; border: 0; border-radius: 0; background: none; font-family: var(--font-mono); font-size: var(--fs-md); font-weight: inherit; line-height: normal; }
.file-row .btn.file-name { padding: 0; color: var(--c-text); }
.file-row .btn.file-name:hover { color: var(--c-primary); }
.file-row .btn.file-x { padding: 0 var(--sp-1); color: var(--c-text-2); }
.file-row .btn.file-x:hover { color: var(--c-danger); text-decoration: none; }
.btn.btn-icon.datebox-btn { width: auto; min-width: 0; padding: 0 var(--sp-2); border-left: none; border-radius: var(--r-0); background: var(--c-head); font-size: var(--fs-md); font-weight: inherit; }
.btn.btn-icon.datebox-btn:hover { background: var(--c-hover); }
.btn.btn-icon.datebox-btn svg { width: var(--fs-xl); height: var(--fs-xl); }
.vm-share .fn-list .btn.btn-link { display: block; width: 100%; height: auto; min-height: var(--h-touch); min-width: 0; padding: 0 var(--sp-7); border: 0; border-radius: 0; background: none; text-align: left; color: var(--c-text); font: inherit; font-size: var(--fs-2xl); }
.vm-share .fn-list .btn.btn-link:hover { text-decoration: none; }
.vm-share .fn-list .btn.btn-link:active { background: var(--c-head); }
.btn.titlebar-app { height: auto; min-height: 0; border-radius: 0; }
@media (max-width: 700px) {
  .modal.window .file-row .btn.file-name { min-height: var(--h-touch); }
  .modal.window .file-row .btn.file-x { min-width: var(--h-touch); min-height: var(--h-touch); }
  .btn.titlebar-app { min-height: var(--h-touch); min-width: 0; padding: 0 var(--sp-4); font-size: var(--fs-sm); }
}

/* 사내(company) 단추 일곱 가지(2026-10-23 대표님 "사내(company) 단추부터 일곱 가지로 바꿔줘")
   옛 꼴(서류 줄 ✕ ✎ · 다시시도 ↻ · 정비표 칸 삭제 ✕ · 꺼진 폴더 삭제)을 .btn 이 덮지 않게 — 두 클래스 무게로 되돌린다 */
.btn.btn-icon.cdoc-tbtn, .btn.btn-icon.cdoc-retry, .btn.btn-icon.cdoc-tidy, .btn.btn-danger.vsm-del-btn, .btn.btn-danger.vsm-del-new-btn { width: auto; height: auto; min-width: 0; min-height: 0; border: 0; border-radius: 0; background: none; font-weight: inherit; line-height: normal; }
.btn.btn-icon.cdoc-tbtn { padding: 0 var(--sp-2); color: var(--c-text-2); font: inherit; font-size: var(--fs-lg); }
.btn.btn-icon.cdoc-tbtn:hover { background: none; color: var(--c-link); }
.cdoc-row .btn.btn-icon.cdoc-rename { width: var(--sp-7); padding: 0; font-size: var(--fs-md); }
.cdoc-grid .c-edit .btn.btn-icon.cdoc-rename { width: calc(var(--sp-7) + var(--sp-1)); }   /* 옛 18px */
.btn.btn-icon.cdoc-retry { padding: 0 var(--sp-1); color: var(--c-danger); font-size: var(--fs-xl); }
.btn.btn-icon.cdoc-retry:hover { background: none; }
.btn.btn-danger.vsm-del-btn, .btn.btn-danger.vsm-del-new-btn { margin-left: var(--sp-1); padding: 0 var(--sp-1); color: var(--c-text-3); font-size: var(--fs-md); }
.btn.btn-danger.vsm-del-btn:hover, .btn.btn-danger.vsm-del-new-btn:hover { background: none; color: var(--c-danger); }
.btn.btn-danger.btn-del-off, .btn.btn-danger.btn-del-off:hover { background: var(--c-line); color: var(--c-text-3); border-color: var(--c-line); cursor: not-allowed; }
@media (max-width: 700px) {
  .btn.btn-icon.cdoc-tbtn, .btn.btn-icon.cdoc-retry, .btn.btn-icon.cdoc-tidy, .btn.btn-danger.vsm-del-btn, .btn.btn-danger.vsm-del-new-btn { min-width: 0; min-height: var(--h-touch); height: auto; }   /* 옛 폰 꼴 = 공용 button 손가락 높이 */
}

/* 기술(tech) 단추 일곱 가지(2026-10-23) — 공구 목록 ★ 사내 목록 단추는 그림, 켜짐은 별색(주의 색) */
.btn.btn-icon.star-btn.on { color: var(--c-warn); }

/* 단추 일곱 가지(2026-10-23 대시보드) — .btn · .btn-icon(두 클래스)이 옛 꼴을 덮지 않게 세 클래스로 되돌린다.
   .btn 높이를 건드리므로 모듈 CSS 가 아닌 여기(꼴-14) */
.btn.btn-icon.dash-ic-preview { padding: 0; color: var(--c-text); font-weight: var(--fw-normal); }
.btn.btn-icon.dash-ic-preview svg, .btn.btn-icon.dash-ic-preview .icon { width: var(--fs-lg); height: var(--fs-lg); font-size: var(--fs-lg); }
.btn.btn-icon.dash-ic-opt { width: var(--h-lg); height: var(--h-lg); min-height: 0; padding: 0; font-weight: var(--fw-normal); border-color: transparent; background: transparent; color: var(--c-text); font-size: var(--fs-xs); }
.btn.btn-icon.dash-ic-opt:hover { border-color: transparent; background: var(--c-hover); color: var(--c-primary); }
.btn.btn-icon.dash-ic-opt.dash-ic-def { border-color: var(--c-line); }
.btn.btn-icon.dash-ic-opt.dash-ic-on { border-color: var(--c-primary); background: var(--c-selected); }
.btn.btn-icon.side-shut { width: auto; min-height: 0; font-weight: var(--fw-normal); border-radius: 0; }
@media (max-width: 700px) { .btn.btn-icon.dash-ic-opt { min-height: 0; min-width: 0; } }

/* MAPS 단추 일곱 가지(2026-10-23) — 지도 말풍선 ✕ 는 그림(btn-icon)이되 옛 꼴(테 · 바탕 없는 큰 ×) 그대로. .btn 높이를 건드리므로 모듈 CSS 가 아닌 여기(꼴-14) */
.btn.btn-icon.maps-popup-x { width: auto; height: auto; min-height: 0; min-width: 0; padding: var(--sp-1) var(--sp-3); border: 0; border-radius: 0; background: transparent; color: var(--c-text-2); font-size: var(--fs-2xl); font-weight: var(--fw-normal); line-height: var(--lh-1); }
.btn.btn-icon.maps-popup-x:hover { background: transparent; color: var(--c-text); }
@media (max-width: 700px) { .btn.btn-icon.maps-popup-x { min-height: var(--h-touch); } }   /* 폰은 옛 꼴처럼 터치 높이 */

/* 사용자(users) 단추 일곱 가지(2026-10-23) — 권한그룹 메뉴 트리 ▾ 는 그림(btn-icon)이되 옛 꼴(테 · 바탕 없는 2ch 글자) 그대로. .btn 높이를 건드리므로 여기(꼴-14) */
.btn.btn-icon.tree-toggle-btn { width: 2ch; height: auto; min-height: 0; min-width: 0; padding: 0; border: 0; border-radius: 0; background: transparent; color: var(--c-text-3); font-size: var(--fs-sm); font-weight: var(--fw-normal); line-height: normal; }
.btn.btn-icon.tree-toggle-btn:hover { background: transparent; color: var(--c-text-3); }
@media (max-width: 700px) { .btn.btn-icon.tree-toggle-btn { min-height: var(--h-touch); min-width: 0; } }

/* JS 가 만드는 단추 일곱 가지(2026-10-24 대표님 "자바스크립트가 만드는 단추도 일곱 가지로 맞추고")
   보기창 도구줄 · 목차 ✕ · 판 비교 ✕ 는 옛 꼴 그대로 — .btn · .btn-icon 이 덮지 않게 되돌린다(꼴-14 라 여기) */
.vw-tools .btn.btn-icon, .vw-tools .btn.btn-toggle:not(.vw-on) { color: var(--c-text); }
.vw-tools .btn.btn-icon { font-size: var(--fs-md); }
.vw-tools .btn.btn-toggle.vw-ink-color { background: transparent; }
.vw-tools .btn.btn-toggle.vw-ink-width { font-size: var(--fs-sm); }
.btn.btn-icon.vw-index-x, .btn.btn-icon.snap-cmp-x { width: auto; min-width: 0; height: auto; min-height: 0; border: 0; border-radius: 0; background: transparent; color: inherit; font-weight: inherit; line-height: 1; }
.btn.btn-icon.vw-index-x { padding: 0 var(--sp-4); font-size: var(--fs-2xl); }
.btn.btn-icon.vw-index-x:hover { background: transparent; }
.btn.btn-icon.snap-cmp-x { height: var(--h-sm); min-width: var(--h-sm); padding: 0 var(--sp-2); font-size: var(--fs-md); }
.btn.btn-icon.snap-cmp-x:hover { background: var(--c-dark); }
.btn.btn-icon.vw-cmp-x { width: var(--h-sm); min-width: 0; height: var(--h-xs); min-height: 0; color: inherit; font-size: inherit; }
@media (max-width: 700px) {
  .btn.btn-icon.vw-index-x, .btn.btn-icon.snap-cmp-x, .btn.btn-icon.vw-cmp-x { min-height: var(--h-touch); }   /* 옛 폰 꼴 = 공용 button 손가락 높이 */
}

/* 보낼 곳 고르기 부품(24-03 9번) */
.route-picker { display: flex; flex-direction: column; font-size: var(--fs-md); }
.route-picker-item { display: flex; align-items: center; justify-content: space-between; width: 100%; text-align: left; padding: var(--sp-1) var(--sp-4); cursor: pointer; color: var(--c-text); text-decoration: none; border: none; background: transparent; font-size: var(--fs-md); }
.route-picker-item.on { background: var(--c-head); color: var(--c-primary); }
.route-picker-sub { padding-left: var(--sp-7); }
/* 보내기 창 나무 줄 — .innerdoc-node · .innerdoc-fold · .innerdoc-give. base 없는 화면(공유 받기 다른 사용자 BOX)도 같은 꼴을 쓰게 style.css 에서 옮김(2026-10-25 24-04b) */
.innerdoc-node { display: flex; justify-content: space-between; padding: var(--sp-1) var(--sp-4) var(--sp-1) calc(var(--sp-7) + var(--sp-1)); cursor: pointer; color: var(--c-text); text-decoration: none; }
.innerdoc-node.on { background: var(--c-head); color: var(--c-primary); }
.innerdoc-node.is-inbox { background: color-mix(in srgb, var(--c-warn) 12%, transparent); }
.innerdoc-node.is-inbox.on { background: var(--c-head); color: var(--c-primary); }
.innerdoc-node-line.is-pick { background: var(--c-selected); }
.innerdoc-node-line { display: flex; align-items: center; gap: var(--sp-2); } .innerdoc-node-line > .innerdoc-node { flex: 1 1 auto; } .innerdoc-node-line > .route-tree-chk { margin: 0 0 0 var(--sp-2); flex: 0 0 auto; cursor: pointer; }
/* 보내기 창 나무 접기(24-03 5d) — 머리줄 앞 ▸ · ▾ 로 접고 폄(꼴-26 · 창-15 예외: 여는 단추). 부서 줄은 체크칸 = 고르기, 이름 · ▸ = 접기 */
.innerdoc-fold > summary { list-style: none; cursor: pointer; }
.innerdoc-node.innerdoc-solo { font-weight: var(--fw-semi); padding-left: calc(var(--sp-4) + 2ch); }   /* 칸 하나뿐인 갈래 — 접는 머리 없이 그 칸이 곧 갈래(▸ 자리만큼 들임) */
.innerdoc-fold > summary::-webkit-details-marker { display: none; }
.innerdoc-fold > summary::before { content: "▸"; display: inline-block; flex: 0 0 auto; width: 2ch; color: var(--c-text-3); }
.innerdoc-fold[open] > summary::before { content: "▾"; }
.innerdoc-fold-give > summary { display: flex; align-items: center; padding-left: var(--sp-4); }
.innerdoc-fold-give > summary > .innerdoc-node { flex: 1 1 auto; min-width: 0; padding-left: 0; }
.innerdoc-tree.route-tree { width: var(--route-tree-w); }   /* 3단 줄 이름이 접히지 않게 */
.innerdoc-fold.route-main > summary { display: flex; align-items: center; padding-left: 0; }
.innerdoc-fold.route-main > summary > .innerdoc-node-line { flex: 1 1 auto; min-width: 0; }
.innerdoc-fold.route-main-1 > :not(summary) { margin-left: var(--sp-3); }
.innerdoc-fold.route-main-2 > :not(summary) { margin-left: var(--sp-3); }
.innerdoc-fold.route-main > .innerdoc-node-line { margin-left: calc(var(--sp-3) + 2ch); }   /* 세모 없는 줄도 체크칸을 같은 단끼리 맞춘다 */
.innerdoc-fold.route-main .innerdoc-node.innerdoc-solo { padding-left: var(--sp-2); padding-right: var(--sp-2); }
.innerdoc-give { justify-content: flex-start; align-items: center; gap: var(--sp-2); }
/* 보낼 곳 나무 — 보내기 창 나무 꼴(바로 위 .innerdoc-* 줄)을 그대로 쓰고, 단추 줄만 맞춘다(2026-10-25 [내부문서로]) */
.route-tree { display: flex; flex-direction: column; font-size: var(--fs-md); }
.route-tree > .key-box { flex: none; }   /* 사유 칸 — 공용 .key-box 의 flex:1(가로 줄용)이 세로 나무에선 남는 높이를 먹어 [찾기] · 나무를 밑으로 밀었다(24-92b 나무 밀림) */
.route-tree-search { margin: 0 var(--sp-2) var(--sp-2); width: auto; min-width: 0; }
.route-tree-node[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }   /* 넣을 길 없는 칸(회사관련서류 — 그 화면에서 올림) */
.route-tree-node { width: 100%; box-sizing: border-box; border: none; background: transparent; text-align: left; font: inherit; }   /* style.css 없는 화면(공유 받기)도 덧살 없이(24-04e) */
.route-tree-node:hover, .route-tree .innerdoc-give:hover { background: var(--c-hover); }
.route-tree .innerdoc-node-line[hidden], .route-tree .route-tree-node[hidden], .route-tree .innerdoc-give[hidden], .route-tree details[hidden] { display: none; }   /* 찾기로 숨김 — .innerdoc-node 의 display:flex 가 hidden 을 이기지 않게 */


/* 첨부 내부문서로 넣기 (24-12) */
.todoc { display: inline-flex; align-items: center; flex-wrap: wrap; gap: var(--sp-1); }
.todoc-marks { display: inline-flex; align-items: center; flex-wrap: wrap; gap: var(--sp-1); }
.todoc-mark { color: var(--text-muted, var(--c-text-2)); }
.modal.window.todoc-win { display: flex; flex-direction: column; padding: 0; resize: both; overflow: hidden; max-width: none; max-height: none; }   /* 넣기 창 = 보내기 창 넣기 모드(_win_innerdoc.html put) — 보내기 창처럼 귀퉁이로 크기 조절 */
.todoc-win-content { flex: 1 1 auto; min-height: 0; }
.todoc-win-marks { font-size: var(--fs-sm); }
.todoc-put { display: flex; flex-direction: column; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4); overflow-y: auto; }
.todoc-put-card { display: flex; gap: var(--sp-3); align-items: flex-start; }
.todoc-put-thumb { flex: 0 0 auto; width: calc(var(--thumb-w) * 3); height: calc(var(--thumb-w) * 3); display: flex; align-items: center; justify-content: center; border: 1px solid var(--c-line); border-radius: var(--r-1); background: var(--c-sunken); overflow: hidden; }
.todoc-put-thumb img { max-width: 100%; max-height: 100%; object-fit: contain; }
.todoc-put-ext { font-weight: var(--fw-semi); color: var(--text-muted); }
.todoc-put-meta { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.todoc-put-name { overflow-wrap: anywhere; }
.todoc-put-reason { display: flex; flex-direction: column; gap: var(--sp-1); }
.modal.window .todoc-put-reason textarea { width: 100%; min-height: calc(var(--h-lg) * 4); resize: vertical; }   /* 사유 칸 크게(대표님 2026-10-25 "빈칸 많잖아") */

/* 사용자 화면 설정 창(24-10) */
.ups-sample { margin-top: var(--sp-1); padding: var(--sp-3); border: 1px solid var(--c-line); border-radius: var(--r-1); background: var(--c-sunken); display: flex; flex-direction: column; gap: var(--sp-2); width: 100%; }
.ups-sample-text { font-size: var(--fs-md); }
.ups-sample-row { display: flex; align-items: center; gap: var(--sp-2); }

/* 표 맞춤(fit_table, 대표님 2026-10-25) */
.fit-off { display: none !important; }
button.btn.fit-more { width: 1.3em; height: 1.3em; min-width: 0; min-height: 0; padding: 0; margin-right: var(--sp-1); font-size: inherit; line-height: 1; border: 1px solid var(--c-line); border-radius: var(--r-1); background: var(--c-surface); cursor: pointer; vertical-align: middle; }
tr.fit-child > td { background: var(--c-head); white-space: normal; }
tr.fit-child dl { display: grid; grid-template-columns: max-content 1fr; gap: var(--sp-1) var(--sp-3); margin: 0; }
tr.fit-child dt { color: var(--c-text-2); }
tr.fit-child dd { margin: 0; word-break: break-all; }

/* 외부공유2 (24-113) — 심볼은 아이콘 줄에 그대로, 링크 한 줄은 그 아래 온 너비 */
.extshare-btn { display: contents; }
.extshare-slot { flex-basis: 100%; font-size: var(--fs-md); font-weight: var(--fw-normal); }
.extshare-slot:empty { display: none; }
.extshare-list { display: flex; flex-direction: column; gap: var(--sp-2); }
.extshare-slot > button { margin-top: var(--sp-2); }
.extshare-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.extshare-row > input[readonly] { flex: 1 1 24em; min-width: 0; }
.extshare-row > form { display: contents; }
.extshare-staff { display: none; }
.extshare-row:has(select option[value="2"]:checked) .extshare-staff { display: inline-flex; }
.extshare-viewers { margin-top: var(--sp-4); font-size: var(--fs-md); }
.extshare-viewers > ul { margin: 0; padding: 0; list-style: none; }

/* 심볼 단추 한 줄 (2026-10-25) — 정사각 · 같은 svg 크기 · 한 꼴 */
.icon-row {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
}
.icon-row > .btn-icon,
.icon-row > a:has(> svg),
.icon-row > .sym-link,
.icon-row > .biz-pick > .biz-pick-btn.sym-link {
  width: var(--h-sm);
  height: var(--h-sm);
  min-width: var(--h-sm);
  min-height: var(--h-sm);
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  margin: 0;
  border: 1px solid var(--c-line);
  border-radius: var(--r-1);
  background: var(--c-surface);
  color: var(--c-text-2);
  text-decoration: none;
  font-size: var(--fs-md);
  line-height: 1;
  flex: 0 0 auto;
}
.icon-row > .btn-icon:hover,
.icon-row > a:has(> svg):hover,
.icon-row > .sym-link:hover,
.icon-row > .biz-pick > .biz-pick-btn.sym-link:hover {
  color: var(--c-primary);
  border-color: var(--c-primary);
  background: var(--c-hover);
}
.icon-row > .btn-icon svg,
.icon-row > a:has(> svg) svg,
.icon-row > .sym-link svg,
.icon-row > .biz-pick > .biz-pick-btn.sym-link svg {
  width: 1em;
  height: 1em;
  flex: none;
}

/* 로그 창 거르기 묶음 (2026-10-25) — 꺾일 때는 묶음 단위 */
.lf-grp {
  display: inline-flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--sp-2);
}
.lf-grp > :is(input, select, .btn, button) {
  height: var(--h-md);
  box-sizing: border-box;
  vertical-align: middle;
}


/* 새 등록 판단 알림 팝업 (24-36) — 뒤 화면을 막지 않는 작은 창 · [열기]로 연 창(.modal 101~)에 남은 줄이 가리지 않게 그 위, 겹친 창 막(.stack-layer 1250)보다는 아래(24-36c) · 꼴은 공용 경고창 머리 · 아래 띠(대표님 2026-10-28) */
.newreg-pop {
  position: fixed;
  right: var(--sp-7);
  bottom: var(--sp-7);
  z-index: 1240;
  width: min(21.25rem, calc(100vw - 2rem));
  box-sizing: border-box;
  background: var(--c-surface);
  border: 1px solid var(--c-line-strong);
  box-shadow: var(--sp-1) var(--sp-1) 0 var(--c-line-strong);
  overflow: hidden;
}
.newreg-pop > .modal-header { cursor: default; border-radius: 0; }   /* 몸통처럼 각진 모서리 — 공용 .modal-header 의 둥근 윗모서리가 남아 "원형도 직각도 아닌" 꼴(대표님 2026-10-29) */
.newreg-pop-body { display: flex; flex-direction: column; gap: var(--sp-2); padding: var(--sp-4) var(--sp-5); }
.newreg-pop-row { display: flex; align-items: center; justify-content: space-between; flex-wrap: nowrap; gap: var(--sp-2); }
.newreg-pop-group { font-weight: var(--fw-semi); color: var(--c-text-2); font-size: var(--fs-sm); }
.newreg-pop-row > .btn { flex: 0 0 auto; }
.newreg-pop-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.newreg-pop-actions { margin: 0; }
.newreg-pop-phone { display: none; }
html.stacked .newreg-pop-slot, html.blk-framed .newreg-pop-slot, html.keep-framed .newreg-pop-slot { display: none; }
@media (max-width: 700px) {
  .newreg-pop { right: 1rem; bottom: 1rem; }
  .newreg-pop .btn { min-height: 2.25rem; }
  .newreg-pop .newreg-pop-phone { display: inline-flex; }
}

/* 공유템플릿 펼침 단추 (24-29C) — 표준 fn-menu, 항목은 한 줄에 하나 */
.share-tpl-menu .fn-list { left: 0; right: auto; min-width: 12em; max-width: calc(100vw - var(--sp-7)); background: var(--c-surface); }
.share-tpl-menu.up .fn-list { top: auto; bottom: calc(100% + var(--sp-2)); left: 0; right: auto; min-width: 12em; max-width: calc(100vw - var(--sp-7)); background: var(--c-surface); }
.share-tpl-menu .fn-list .btn.share-tpl-item {
  display: block; width: 100%; padding: var(--sp-2) var(--sp-5); border: 0; border-radius: 0;
  background: var(--c-surface); text-align: left; white-space: nowrap; font: inherit; color: var(--c-text); cursor: pointer; height: auto; min-width: 0;
}
.share-tpl-menu .fn-list .btn.share-tpl-item:hover { background: var(--c-head); }
.share-tpl-menu.is-flip .fn-list { left: auto; right: 0; }

/* 채널 선택 표준 ch-pick (24-29E) — 채널 줄 · 채널별 보임 · 실행 단추 줄 */
.ch-pick { display: flex; flex-wrap: nowrap; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.ch-pick .on { background: var(--c-primary); border-color: var(--c-primary); color: var(--c-surface); }
.ch-send-row { display: flex; justify-content: flex-end; margin-bottom: var(--sp-3); }
[data-ch="sms"] [data-ch-only]:not([data-ch-only~="sms"]),
[data-ch="email"] [data-ch-only]:not([data-ch-only~="email"]),
[data-ch="insert"] [data-ch-only]:not([data-ch-only~="insert"]) { display: none; }

/* 공유 창 (24-29D) — 미리보기 · 첨부 */
.sharetpl-win .sharetpl-box .field-row { margin-bottom: var(--sp-3); }
.sharetpl-win .sharetpl-preview > * + * { margin-top: var(--sp-2); }
.sharetpl-win .sharetpl-files-box:has(#sharetplFiles[data-has-files="0"]) { display: none; }
.sharetpl-win .sharetpl-files { display: flex; flex-direction: column; gap: var(--sp-2); }
.sharetpl-win .sharetpl-files label { display: flex; align-items: center; gap: var(--sp-2); }
.sharetpl-win .sharetpl-files img { height: var(--thumb-h); width: auto; border: 1px solid var(--c-line); }

.sharetpl-win .field-row { display: flex; align-items: center; gap: var(--sp-3); }
.sharetpl-win .field-row > label { flex: 0 0 var(--label-w); text-align: left; }
.sharetpl-win .sharetpl-picks { margin-left: calc(var(--label-w) + var(--sp-3)); }
.sharetpl-pick { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.sharetpl-win .sharetpl-preview { padding-top: var(--sp-2); }
.sharetpl-chips { display: flex; flex-wrap: nowrap; gap: var(--sp-1); align-items: center; min-width: 0; white-space: nowrap; }
.sharetpl-chiprow .sharetpl-chips { flex: 1 1 0; min-width: 0; }
.sharetpl-chips .sharetpl-chip.btn-small { display: inline-flex; flex-direction: column; align-items: center; gap: var(--sp-1); height: auto; min-height: var(--h-sm); padding: var(--sp-1); line-height: var(--lh-1); font-size: inherit; white-space: nowrap; }
.sharetpl-attach-top { display: flex; gap: var(--sp-5); margin-bottom: var(--sp-3); }
.sharetpl-attach-setting { display: inline-flex; align-items: center; gap: var(--sp-2); }
.sharetpl-attach .sharetpl-innerbox { margin: var(--sp-3) 0; padding: var(--sp-3); border-color: var(--c-line); border-radius: var(--r-3); background: var(--c-head); }
.sharetpl-source-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(var(--label-w), 1fr)); gap: var(--sp-2); }
.sharetpl-source-card { padding: var(--sp-2); border: var(--bw-hair) solid var(--c-line); border-radius: var(--r-2); background: var(--c-surface); }
.sharetpl-source-top { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.sharetpl-source-options { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-1); }
.sharetpl-source-options .check-item { white-space: nowrap; }
.sharetpl-chip .chip-label { font-size: .92em; color: var(--c-text-2); }

/* 공유템플릿 목록 실행 (24-29E) */
.sharetpl-run { display: flex; align-items: center; gap: var(--sp-2); }
.sharetpl-run .ipt { width: 18em; }
.sharetpl-run-name { cursor: pointer; color: var(--c-link); }
.sharetpl-win .statusbar[hidden], .sharetpl-win [data-share-results][hidden] { display: none; }   /* 빈 상태 줄이 창 아래 회색 띠로 보였다 — display 가 hidden 을 이겼다 */

/* 공유 창 (24-29F) — 목록 실행 칸 · 메일로도 */
.sharetpl-run { flex-wrap: nowrap; gap: var(--sp-2); }
.sharetpl-also { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.sharetpl-win [data-ch="insert"]:not(.also-on) [data-share-to] { display: none; }

/* 저장 뒤 단추 곁 말풍선 ErpStay.tip (2026-10-26) */
.keep-tip {
  position: fixed;
  z-index: 100000;   /* 창 · 겹친 창(10000) · 띠(99999) 위 */
  max-width: 22em;
  font-size: 0.85em;
  line-height: var(--lh-text);
  padding: var(--sp-2) var(--sp-4);
  border-radius: var(--r-2);
  background: var(--c-ok-bg);
  color: var(--c-ok);
  border: 1px solid var(--c-ok);
  box-shadow: 0 var(--sp-1) var(--sp-2) rgba(0, 0, 0, 0.12);
  pointer-events: auto;
  cursor: default;
  word-break: break-all;
  box-sizing: border-box;
}
.keep-tip.off {
  opacity: 0;
  transition: opacity 0.4s ease;
}
.keep-tip.bad {
  background: var(--c-danger-bg);
  color: var(--c-danger);
  border-color: var(--c-danger);
  cursor: pointer;
}
.keep-tip.bad::after,
.keep-tip.keep::after {
  content: " ✕";
  font-weight: var(--fw-bold);
  margin-left: var(--sp-2);
}
.keep-tip.keep {
  cursor: pointer;
}


/* 목록 저절로 갱신 줄(24-63) */
.live-bar { display: inline-flex; align-items: center; gap: var(--sp-1); }
/* 단추 하나 · 색으로 상태(24-63 덧2) — 자동 켜짐: 파랑이 2.4초에 한 번 은은히 숨쉼 · 꺼짐: 보통 단추 · 끊김: 숨 멈추고 주황 */
.btn.btn-icon.live-refresh.is-auto { color: var(--c-primary); border-color: var(--c-primary); background: var(--c-selected); animation: live-breathe 2.4s ease-in-out infinite; }
.btn.btn-icon.live-refresh.is-lost { color: var(--c-warn); border-color: var(--c-warn); animation: none; }
@keyframes live-breathe { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .btn.btn-icon.live-refresh.is-auto { animation: none; } }
.live-new { font-size: var(--fs-xs); color: var(--c-primary); cursor: pointer; white-space: nowrap; }

/* 찾기칸이 있는 화면은 모두 이 검색틀 한 벌 — 꼴 · 폭은 여기만, 모듈 CSS 에 다시 쓰지 않음(대표님 2026-10-28 "전사적으로" · 통역자 위임) — 24-42z5 */
.search-frame            { flex: none; position: relative; display: grid; grid-template-columns: minmax(0, var(--search-w)) auto auto auto auto; justify-content: start; align-items: center; gap: var(--sp-1); padding: var(--sp-1) var(--sp-3); border-bottom: var(--bw-hair) solid var(--c-line); background: var(--c-head); }
.search-frame:has(> .search-period) { grid-template-columns: 1fr auto auto auto auto; }
/* justify-content: start — 기간 줄 없는 틀(Call DB · 짝맞춤 보기)은 남는 폭이 auto 칸으로 퍼져 [Filter] 261px · 새로고침 243px 로 늘어났다(대표님 2026-11-02 "필터모양 왜저래", 24-111) */
.search-frame > .search-form   { grid-column: 1; grid-row: 1; min-width: 0; max-width: var(--search-w); margin: 0; padding: 0; border-bottom: none; }
.search-frame:has(> .search-period) > .search-form { min-width: var(--label-w); max-width: none; }   /* 기간 줄이 있으면 남는 폭을 다 채움(대표님 2026-10-28) */
.search-frame > .search-form .search-input { width: 100%; max-width: none; min-width: 0; }
.search-frame > .live-bar, .search-frame > .filter-btn, .search-frame > .search-side, .search-frame > .chip { grid-row: 1; }
.search-side            { display: flex; gap: var(--sp-1); }
.search-frame > .search-period { grid-row: 2; grid-column: 1 / -1; display: flex; align-items: flex-start; min-width: 0; max-width: 100%; }   /* 둘째 줄: 기간 + 간편단추 */

/* 머리줄 안 검색틀(.page-head · .toolbar · .panel-head 등에 끼는 꼴) */
.search-frame.is-inline  { display: flex; flex: 0 1 auto; min-width: 0; padding: 0; border: none; background: transparent; }
.search-frame.is-inline > .search-form { flex: 0 1 var(--search-w); width: var(--search-w); max-width: var(--search-w); min-width: 0; }
.search-frame.is-inline > :is(.live-bar, .filter-btn, .search-side, .chip) { flex: none; }
.search-frame > .live-bar .live-refresh { width: var(--h-md); height: var(--h-md); min-height: var(--h-md); }   /* [새로고침]도 찾는 칸 · [Filter] 와 같은 높이 */
.search-frame > .filter-btn { height: var(--h-md); min-height: var(--h-md); padding: 0 var(--sp-3); font-size: var(--fs-sm); }   /* [Filter] 크기도 한 벌 — 화면마다 btn-small 이 있고 없어 높이가 달랐다(대표님 2026-10-31 "다른 탭들이랑 모양이 다르냐") */

/* 찾는 중 = 검색틀 윗띠, 0.3초 넘을 때만(통역자 2026-10-28 위임 결정 A) — 24-42z7 */
.search-frame:has(form.searching)::before,
.search-frame:has(.search-input.htmx-request)::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: var(--bw-head);
  background-image: linear-gradient(90deg, transparent 0%, var(--c-link) 50%, transparent 100%);
  background-repeat: no-repeat;
  background-size: 50% 100%;
  background-position: -100% 0;
  opacity: 0;
  animation: search-progress 1.2s ease-in-out infinite;
  animation-delay: .3s;
  pointer-events: none;
  z-index: 1;
}
@keyframes search-progress {
  0%   { background-position: -100% 0; opacity: 1; }
  100% { background-position: 200% 0; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .search-frame:has(form.searching)::before,
  .search-frame:has(.search-input.htmx-request)::before {
    animation: none;
    background: var(--c-link);
    opacity: 1;
  }
}

/* .fire-docform 종이 서식 꼴 표 — 이름 칸 고정 · 값 칸 입력(대표님 2026-10-31, 소방 1.1 첫 사용 · 다른 서식도 같이 씀) · 2026-11-01 원본 칸 배치 */
.fire-docform { width: 100%; max-width: calc(var(--sp-8) * 40); table-layout: fixed; border-collapse: collapse; border: var(--bw-main) solid var(--c-line-strong); font-size: var(--fs-md); }
.fire-docform col.c-grp { width: 5%; }
.fire-docform col.c-lab { width: 12%; }
.fire-docform th, .fire-docform td { border: var(--bw-hair) solid var(--c-line); padding: var(--sp-2); vertical-align: middle; }
.fire-docform th { background: var(--c-head); text-align: center; font-weight: var(--fw-semi); white-space: normal; word-break: keep-all; overflow-wrap: anywhere; }   /* 칸보다 긴 낱말만 쪼갬 — 머리 글자가 옆 칸에 잘리지 않게(대표님 2026-11-01 1.10.2) */
.fire-docform th.grp { writing-mode: vertical-rl; text-orientation: upright; letter-spacing: var(--sp-2); text-align: center; }
.fire-docform th.spread { text-align: justify; text-align-last: justify; }
.fire-docform caption { text-align: left; font-weight: var(--fw-bold); padding-bottom: var(--sp-2); }
.fire-docform td input, .fire-docform td select { width: 100%; min-width: 0; min-height: var(--sp-6); font-size: inherit; box-sizing: border-box; }
.fire-docform td.num { text-align: right; white-space: nowrap; }
.fire-docform td.num input { text-align: right; }
.fire-docform td.num > input { vertical-align: middle; width: calc(100% - 3em); max-width: calc(var(--sp-8) * 3); }
.fire-docform td.opt { white-space: normal; word-break: keep-all; }   /* 고름 글이 칸보다 길면 다음 줄로 — 옆 칸에 잘리지 않게(대표님 2026-11-01 1.10.2) */
.fire-docform td.opt .key-box { display: inline-flex; width: auto; flex: 0 0 auto; }
.fire-docform .pair, .fire-docform .range { display: flex; align-items: center; gap: var(--sp-1); white-space: nowrap; }
.fire-docform .pair + .pair { margin-top: var(--sp-1); }
.fire-docform td.num .pair input, .fire-docform .range input { flex: 1 1 0; width: auto; }
.fire-docform .range { flex-wrap: wrap; }
.fire-docform .shift { display: inline-flex; align-items: center; gap: var(--sp-1); white-space: nowrap; flex-wrap: wrap; max-width: 100%; }
.fire-docform .shift input[type="text"] { width: calc(var(--sp-8) * 1.5); }
.fire-docform .range input[type="time"] { width: auto; flex: 0 0 auto; }
.fire-docform .etc { display: inline-flex; align-items: center; gap: var(--sp-1); max-width: 100%; }
.fire-docform .etc label { margin-right: 0; }
.fire-docform .etc input { width: auto; flex: 1 1 auto; }
.fire-docform label { display: inline-flex; align-items: center; gap: var(--sp-1); }
.fire-docform input[type="checkbox"], .fire-docform input[type="radio"] { width: auto; min-height: 0; margin: 0; }
.fire-docform input:disabled, .fire-docform select:disabled { border-color: transparent; background: transparent; color: inherit; opacity: 1; -webkit-text-fill-color: currentColor; }
.fire-docform select:disabled { appearance: none; background-image: none; }
.fire-docform input[type="checkbox"]:disabled, .fire-docform input[type="radio"]:disabled { opacity: 1; }
.fire-docform .unit { white-space: nowrap; }
.fire-docform .hint { color: var(--c-text-3); font-size: var(--fs-sm); }
.fire-docform .hint.pulled { color: var(--c-link); opacity: 1; white-space: nowrap; cursor: help; }
.fire-docform .hint.pulled .icon { width: 1.1em; height: 1.1em; }
.inplace .fire-docform :is(input:not([type="checkbox"]):not([type="radio"]), select, textarea):has(+ .hint.pulled) { width: calc(100% - 1.6em); }   /* 칸 뒤 정보연결 심볼이 다음 줄로 내려가지 않게(대표님 2026-11-01) */
.fire-docform :is(input, textarea).fire-auto,
.inplace .fire-docform input[data-autofill-value].fire-auto:not([type="checkbox"]):not([type="radio"]),
.inplace .fire-docform textarea[data-autofill-value].fire-auto,
.inplace table.fire-docform.dgrid[data-autofill-rows] tbody.fs-list tr.fs-item input.fire-auto:not([type="checkbox"]):not([type="hidden"]) { color: var(--c-text-3); }   /* 연결 칸 파란 글자보다 앞서게 — 자동 값은 회색, 사람 값은 파랑 */
.fire-docform input[type="checkbox"].fire-auto, .fire-docform input[type="radio"].fire-auto { accent-color: var(--c-text-3); }
.inplace .fire-docform th:has(> .hint.pulled) { white-space: nowrap; }
.fire-docform .field-error { display: block; }

/* · 2026-11-01 1.3~1.9 */
.fire-docform col.c-half { width: 45%; }
.fire-docform col.c-dt { width: 20%; }
.fire-docform td.opts { white-space: normal; }
.fire-docform td.opts label { margin-right: var(--sp-3); }
.fire-docform td.opts .key-box { display: inline-flex; width: auto; flex: 0 0 auto; }
.fire-docform td.mark { white-space: nowrap; }
.fire-docform td.note { font-size: var(--fs-sm); color: var(--c-text-2); text-align: left; }
.fire-docform td.img { text-align: center; }
.fire-docform .docimgs { display: flex; flex-wrap: wrap; gap: var(--sp-2); justify-content: center; }
.fire-docform .docimg { margin: 0; }
.fire-docform .docimg img { max-width: 100%; max-height: calc(var(--sp-8) * 12); display: block; }
.fire-photos { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: flex-start; }
.fire-photos figure { margin: 0; }

.fire-docform th.sub { text-align: left; }
.fire-docform td.poster { text-align: center; }
.fire-docform td.poster div { padding: var(--sp-1) 0; }
.fire-docform td.poster input { vertical-align: middle; width: calc(var(--sp-8) * 7); max-width: 100%; }
.fire-docform td.opts input[inputmode="numeric"] { width: calc(var(--sp-8) * 1.5); }
.fire-docform tr.fs-add td { text-align: left; }
.fire-docform td.fs-sub { padding: 0; }   /* 한 항목(tr.fs-item) 안 여러 줄 — 칸 안 안쪽 표로 종이 서식 2열 × N줄을 지킨다(목록-52 · 소방 1.2.2) */
.fire-docform td.fs-sub > table { width: 100%; height: 100%; table-layout: fixed; border-collapse: collapse; border-style: hidden; }
.fire-docform + .fire-docform { margin-top: 0; border-top: 0; }
.fire-docform .docempty { padding: var(--sp-4) 0; text-align: center; color: var(--c-text-3); letter-spacing: var(--sp-1); }
.fire-docform td textarea { width: 100%; min-width: 0; box-sizing: border-box; font-size: inherit; resize: vertical; }

/* 지정일(월) 체크가 표 줄을 늘리지 않게 켜고끄기 칩으로 감싼다(대표님 2026-10-31). */
.chip-pick { display: flex; flex-wrap: wrap; gap: var(--sp-1); }
.chip-pick .btn.btn-toggle { min-width: 0; padding-inline: var(--sp-2); }

/* ---------------- 일정 달력(lib/calendar.js) ---------------- */
.fc-day-sun .fc-col-header-cell-cushion, .fc-day-sun .fc-daygrid-day-number { color: var(--c-danger); }
.fc-day-sat .fc-col-header-cell-cushion, .fc-day-sat .fc-daygrid-day-number { color: var(--c-primary); }
.erp-cal .fc-daygrid-day { cursor: pointer; }
.erp-cal .fc-daygrid-day:hover .fc-daygrid-day-frame::after { content: ""; position: absolute; inset: 0; border: var(--bw-head) solid var(--c-primary); pointer-events: none; z-index: 5; }   /* 커서 아래 날짜 칸 강조 */
.erp-cal .fc-daygrid-day:hover .fc-daygrid-day-number { font-weight: var(--fw-bold); }
/* 서류 이력(sheet_hist) — 이력-13 넷째 예외 */
.modal.window.sheet-hist {
  position: fixed; top: calc(var(--h-lg) * 2); right: var(--sp-4); bottom: auto; left: auto;
  transform: none; margin: 0; padding: 0; width: min(calc(100vw - var(--sp-4) * 2), calc(var(--sp-8) * 13));
  min-width: 0; height: auto; max-height: 70vh; display: flex; flex-direction: column; overflow: hidden;
}
.modal.window.sheet-hist > .modal-header { flex: 0 0 auto; }
.modal.window.sheet-hist > .modal-body { flex: 1 1 auto; min-height: 0; padding: 0; overflow-y: auto; }
.modal.window.sheet-hist .hist-panel { border-left: 0; max-height: none; overflow: visible; }
.modal.window.sheet-hist .side-shut { display: none; }   /* 닫기는 머리 [닫기] 하나 */
.sheet-hist-on td.hist-diff { background: var(--c-note-bg); }
.sheet-hist-on td.hist-diff :is(input:not([type=checkbox]):not([type=radio]), select, textarea):disabled { background: var(--c-note-bg); }

/* 고름 줄 · 제자리 제목 바꾸기 — 공용 부품(2026-11-02). */
.batch-pick-bar { display: flex; flex: 1 1 auto; align-items: center; gap: var(--sp-2); min-width: 0; }
.batch-pick-bar > form { display: none; }
.batch-pick-bar > .dropzone { flex: 1 1 auto; min-width: 0; padding: var(--sp-1) var(--sp-2); }
.batch-pick-bar .batch-pick-info { display: inline-flex; align-items: center; gap: var(--sp-2); white-space: nowrap; }
.batch-pick-bar .batch-pick-off { visibility: hidden; }
.rename-btn { display: inline-flex; align-items: center; gap: var(--sp-2); max-width: 100%; }
.rename-btn [data-rename-target="label"] { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rename-btn .rename-btn-pencil { visibility: hidden; flex: none; }
tr:hover .rename-btn .rename-btn-pencil, .rename-btn:hover .rename-btn-pencil, .rename-btn:focus-within .rename-btn-pencil { visibility: visible; }
.rename-btn .rename-btn-editor { display: inline-flex; align-items: center; gap: var(--sp-2); }
.rename-btn .rename-btn-hidden { display: none; }
.rename-btn .rename-btn-error { color: var(--c-danger); }
