/* ============================================================
   v2 components (P0-d) — 클래스 계약은 계획서 P0-d "CSS 계약"
   .btn .btn-primary .btn-danger .btn-sm · .card · .section-card > .section-head + .section-body
   .chip.chip-{eq|lb|mt|ex|os|wk|rain|off} · .tbl .tbl-sticky · .num · .kpi · .badge-dd
   .modal-bg .modal .modal-head .modal-body .modal-foot · .sheet · .toast · .empty
   .banner[data-tone=info|warn|danger] · .pc-only · .m-only(→ mobile.css/desktop.css)
   + 재사용 JS가 내는 옛 클래스 최소 가독 스타일(.ui-dlg .form-input .btn-ghost .empty-state .u-*)
   ============================================================ */

/* ── 버튼 ─────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: var(--btn-h);
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  background: var(--card);
  color: var(--ink);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semi);
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.btn:hover { border-color: var(--border-strong); background: var(--surface-2); }
.btn:active { transform: translateY(.5px); }
.btn-primary { background: var(--navy); border-color: var(--navy); color: var(--on-navy); }
.btn-primary:hover { background: var(--navy-2); border-color: var(--navy-2); }
.btn-danger { background: var(--red); border-color: var(--red); color: var(--on-navy); }
.btn-danger:hover { background: var(--red); border-color: var(--red); opacity: .9; }
.btn-amber { background: var(--amber); border-color: var(--amber); color: var(--on-amber); }
.btn-ghost { background: transparent; }
.btn-sm { min-height: 26px; padding: 0 9px; font-size: var(--fs-xs); border-radius: var(--r-md); gap: 4px; }
.btn-icon { padding: 0; width: var(--btn-h); }
.btn-icon.btn-sm { width: 26px; }
.btn-block { display: flex; width: 100%; }
/* 옛 변형 (재사용 JS) */
.btn-success { background: transparent; color: var(--green); }
.btn-purple  { background: transparent; color: var(--blue); }

/* ── 입력 ─────────────────────────────────────────────── */
.input, .form-input, .select {
  width: 100%;
  min-height: 32px;
  padding: 6px 10px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  color: var(--ink);
  font-size: var(--fs-base);
}
.input:focus, .form-input:focus, .select:focus { border-color: var(--blue); box-shadow: var(--focus-ring); }
.input::placeholder, .form-input::placeholder { color: var(--mute); }
.field { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-sm); color: var(--mute); font-weight: var(--fw-semi); }

/* ── 카드 ─────────────────────────────────────────────── */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}
.card-pad { padding: var(--sp-3) var(--sp-4); }

.section-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  overflow: hidden;
}
.section-head {
  display: flex; align-items: center; gap: var(--sp-2);
  min-height: 44px;
  padding: 8px 14px;
  border-bottom: 1px solid var(--line);
}
.section-head h3, .section-head .section-title { font-size: var(--fs-md); font-weight: var(--fw-extra); }
.section-head .section-sub { color: var(--mute); font-size: var(--fs-xs); font-weight: var(--fw-semi); }
.section-head .section-tools { margin-left: auto; display: flex; align-items: center; gap: 6px; }
/* 카테고리 색 막대 (일보 섹션 헤더 등): <div class="section-head" data-cat="eq"> */
.section-head[data-cat] { box-shadow: inset 3px 0 0 var(--cat, var(--line)); }
.section-head[data-cat="eq"] { --cat: var(--cat-eq); }
.section-head[data-cat="lb"] { --cat: var(--cat-lb); }
.section-head[data-cat="mt"] { --cat: var(--cat-mt); }
.section-head[data-cat="ex"] { --cat: var(--cat-ex); }
.section-head[data-cat="os"] { --cat: var(--cat-os); }
.section-body { padding: var(--sp-3) 14px; }
.section-body.flush { padding: 0; }
.section-card[data-collapsed="1"] .section-body { display: none; }

/* ── 칩 (카테고리 색 고정) ───────────────────────────── */
.chip {
  display: inline-block;
  max-width: 100%;
  padding: 1px 6px;
  border-radius: var(--r-chip);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semi);
  line-height: 1.55;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  vertical-align: middle;
}
.chip-eq   { background: var(--navy-soft);  color: var(--navy-ink); }
.chip-lb   { background: var(--amber-soft); color: var(--amber-ink); }
.chip-mt   { background: var(--green-soft); color: var(--green-ink); }
.chip-ex   { background: var(--gray-soft);  color: var(--gray-ink); }
.chip-os   { background: var(--navy-soft);  color: var(--navy-ink); box-shadow: inset 2px 0 0 var(--cat-os); }
.chip-wk   { background: transparent; color: var(--ink); padding-left: 0; font-weight: var(--fw-bold); }
.chip-rain { background: var(--blue-soft);  color: var(--blue-ink); font-weight: var(--fw-extra); }
.chip-off  { background: var(--red-soft);   color: var(--red-ink);  font-weight: var(--fw-extra); }

/* 상태 배지 (확정·대기 등) */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 7px; border-radius: 5px;
  font-size: var(--fs-2xs); font-weight: var(--fw-extra);
  background: var(--gray-soft); color: var(--gray-ink);
}
.badge[data-tone="amber"]  { background: var(--amber-soft); color: var(--amber-ink); }
.badge[data-tone="green"]  { background: var(--green-soft); color: var(--green-ink); }
.badge[data-tone="red"]    { background: var(--red-soft);   color: var(--red-ink); }
.badge[data-tone="blue"]   { background: var(--blue-soft);  color: var(--blue-ink); }
.badge[data-tone="navy"]   { background: var(--navy-soft);  color: var(--navy-ink); }

/* 필터 칩 (달력 머리 등) */
.fchip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px; border-radius: var(--r-pill);
  border: 1px solid var(--line); background: var(--card);
  color: var(--mute); font-size: var(--fs-xs); font-weight: var(--fw-bold);
  cursor: pointer;
}
.fchip[aria-pressed="true"], .fchip.is-on { background: var(--navy); border-color: var(--navy); color: var(--on-navy); }

/* ── 표 ───────────────────────────────────────────────── */
.tbl-wrap { overflow: auto; max-width: 100%; }
.tbl {
  width: 100%;
  border-collapse: separate; border-spacing: 0;
  font-size: var(--fs-tbl);
  font-variant-numeric: tabular-nums;
}
.tbl th {
  padding: 7px 10px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  color: var(--mute);
  font-size: var(--fs-xs);
  font-weight: var(--fw-bold);
  white-space: nowrap;
}
.tbl td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--row-line);
  color: var(--ink);
  vertical-align: middle;
}
.tbl tbody tr:hover td { background: var(--surface-2); }
.tbl tfoot td { font-weight: var(--fw-extra); background: var(--surface-2); border-top: 1px solid var(--line); border-bottom: 0; }
.tbl .r, .tbl th.r { text-align: right; }
.tbl .c, .tbl th.c { text-align: center; }
.tbl td.empty-cell { padding: 0; }
.tbl-sticky th { position: sticky; top: 0; z-index: var(--z-sticky); }
.tbl input.cell, .tbl select.cell {
  width: 100%; min-height: 28px; padding: 3px 6px;
  border: 1px solid transparent; border-radius: var(--r-md); background: transparent;
}
.tbl input.cell:hover, .tbl select.cell:hover { border-color: var(--line); }
.tbl input.cell:focus, .tbl select.cell:focus { border-color: var(--blue); background: var(--card); box-shadow: var(--focus-ring); }
.tbl input.cell.r { text-align: right; }

/* ── KPI (숫자 띠 한 칸) ─────────────────────────────── */
.kpi-strip { display: grid; grid-template-columns: repeat(5, minmax(0,1fr)); gap: 10px; }
.kpi {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: 10px 12px;
  min-width: 0;
}
.kpi-label { display: block; font-size: var(--fs-xs); color: var(--mute); font-weight: var(--fw-semi); margin-bottom: 4px; }
.kpi-value { font-size: var(--fs-xl); font-weight: var(--fw-extra); letter-spacing: -.01em; white-space: nowrap; }
.kpi-value small { font-size: var(--fs-xs); color: var(--mute); font-weight: var(--fw-semi); margin-left: 3px; }
.kpi-delta { font-size: var(--fs-xs); font-weight: var(--fw-semi); margin-left: 6px; color: var(--green); }
.kpi-delta[data-tone="down"], .kpi-delta[data-tone="danger"] { color: var(--red); }

/* ── 배지 드롭다운 (자동완성·선택 목록 컨테이너) ─────── */
.badge-dd {
  position: absolute;
  z-index: var(--z-dropdown);
  min-width: 160px; max-width: 320px; max-height: 280px;
  overflow-y: auto;
  padding: 4px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  box-shadow: var(--sh-lg);
}
.badge-dd-item {
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 6px 8px; border-radius: var(--r-md);
  font-size: var(--fs-sm); text-align: left; color: var(--ink);
  cursor: pointer;
}
.badge-dd-item:hover, .badge-dd-item.is-active { background: var(--navy-soft); }
.badge-dd-sep { height: 1px; background: var(--line); margin: 4px 0; }

/* ── 모달 · 시트 ──────────────────────────────────────── */
.modal-bg {
  position: fixed; inset: 0;
  z-index: var(--z-modal);
  display: flex; align-items: center; justify-content: center;
  padding: 16px;
  background: var(--overlay-bg);
  animation: uiFadeIn var(--dur) var(--ease);
}
.modal {
  position: relative;
  display: flex; flex-direction: column;
  width: 520px; max-width: 100%;
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  background: var(--card);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--sh-modal);
  animation: uiSlideUp var(--dur-slow) var(--ease);
}
.modal[data-size="sm"] { width: 400px; }
.modal[data-size="md"] { width: 560px; }
.modal[data-size="lg"] { width: 860px; }
.modal-lg { width: 780px; }
.modal h3 { font-size: var(--fs-lg); font-weight: var(--fw-extra); }
.modal-head {
  position: sticky; top: 0; z-index: 1;
  display: flex; align-items: center; gap: var(--sp-2);
  padding: 12px 16px;
  background: var(--card);
  border-bottom: 1px solid var(--line);
}
.modal-head .modal-title { flex: 1; min-width: 0; font-size: var(--fs-lg); font-weight: var(--fw-extra); }
.modal-body { padding: 14px 16px; flex: 1 1 auto; min-height: 0; }
.modal-foot, .modal-footer {
  display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap;
  padding: 12px 16px;
  border-top: 1px solid var(--line);
}
.modal-x { border-color: transparent; color: var(--mute); }
.modal-x:hover { color: var(--ink); }

/* 바텀시트 — uiOpenModal이 모바일에서 자동으로 이 모양을 쓴다 */
.modal-bg.is-sheet { align-items: flex-end; padding: 0; }
.sheet, .modal.sheet {
  width: 100%; max-width: 100%;
  max-height: 88vh;
  border-radius: var(--r-2xl) var(--r-2xl) 0 0;
  border-left: 0; border-right: 0; border-bottom: 0;
  padding-bottom: env(safe-area-inset-bottom, 0px);
  animation: uiSheetUp var(--dur-slow) var(--ease);
}
.sheet-grip {
  flex: none;
  width: 40px; height: 4px; margin: 8px auto 0;
  border-radius: 2px; background: var(--line);
}
.sheet .modal-head { border-bottom: 0; padding-top: 6px; }

/* ui-dialog.js (uiAlert/uiConfirm/uiPrompt) */
.ui-dlg { width: 400px; padding: var(--sp-5); gap: var(--sp-3); }
.ui-dlg h3 { font-size: var(--fs-lg); font-weight: var(--fw-extra); }
.ui-dlg-msg { font-size: var(--fs-md); line-height: 1.55; white-space: pre-wrap; word-break: keep-all; overflow-wrap: anywhere; }
.ui-dlg[data-tone="danger"] h3 { color: var(--red); }
.ui-dlg[data-tone="success"] h3 { color: var(--green); }
.ui-dlg-input { margin-top: var(--sp-1); }
.ui-dlg .modal-footer { padding: var(--sp-2) 0 0; border-top: 0; }

@keyframes uiFadeIn  { from { opacity: 0; } to { opacity: 1; } }
@keyframes uiSlideUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes uiSheetUp { from { transform: translateY(40px); opacity: .6; } to { transform: none; opacity: 1; } }

/* ── 토스트 (ui-dialog.js toast()) ───────────────────── */
.toast {
  position: fixed; left: 50%; bottom: 24px;
  transform: translateX(-50%);
  z-index: var(--z-toast);
  display: flex; align-items: center; gap: var(--sp-3);
  max-width: min(90vw, 480px);
  padding: 10px 16px;
  background: var(--navy);
  color: var(--on-navy);
  border-radius: var(--r-xl);
  box-shadow: var(--sh-lg);
  font-size: var(--fs-base);
  font-weight: var(--fw-semi);
  animation: uiSlideUp var(--dur) var(--ease);
}
.toast-msg { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.toast-action {
  padding: 2px 6px; border-radius: var(--r-md);
  color: var(--amber); font-weight: var(--fw-extra); white-space: nowrap;
}

/* ── 빈 상태 ─────────────────────────────────────────── */
.empty, .empty-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px;
  padding: var(--sp-10) var(--sp-4);
  text-align: center;
  color: var(--mute);
}
.empty-ico, .empty-state-icon {
  display: grid; place-items: center;
  width: 52px; height: 52px; margin-bottom: 4px;
  border-radius: 16px;
  background: var(--gray-soft);
  color: var(--gray-ink);
  line-height: 0;
}
.empty-title { font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--ink); }
.empty-hint, .empty-state-text { font-size: var(--fs-sm); color: var(--mute); }
.empty .btn, .empty-state .btn { margin-top: var(--sp-2); }

/* ── 배너 ─────────────────────────────────────────────── */
.banner {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  background: var(--card);
  font-size: var(--fs-sm);
}
.banner[data-tone="info"]   { background: var(--blue-soft);  border-color: transparent; color: var(--blue-ink); }
.banner[data-tone="warn"]   { background: var(--amber-soft); border-color: transparent; color: var(--amber-ink); }
.banner[data-tone="danger"] { background: var(--red-soft);   border-color: transparent; color: var(--red-ink); }
.banner .banner-act { margin-left: auto; display: flex; gap: 6px; }

/* ── 세그먼트 (보기 전환) ─────────────────────────────── */
.seg { display: inline-flex; padding: 2px; gap: 2px; background: var(--gray-soft); border-radius: var(--r-btn); }
.seg button { padding: 4px 10px; border-radius: var(--r-md); font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--mute); }
.seg button[aria-pressed="true"], .seg button.is-on { background: var(--card); color: var(--ink); box-shadow: var(--sh-sm); }

/* ── 금액 숨김 (toggleMaskAmounts → html[data-mask-amounts]) ── */
html[data-mask-amounts="1"] .amt,
html[data-mask-amounts="1"] .kpi-value {
  color: transparent !important;
  text-shadow: 0 0 9px var(--mute);
  user-select: none;
}

/* ============================================================
   재사용 JS용 유틸리티 (옛 components.css와 같은 이름·의미)
   ============================================================ */
.u-flex { display: flex; }
.u-flex-col { display: flex; flex-direction: column; }
.u-flex-wrap { flex-wrap: wrap; }
.u-items-center { align-items: center; }
.u-items-start { align-items: flex-start; }
.u-justify-between { justify-content: space-between; }
.u-justify-center { justify-content: center; }
.u-justify-end { justify-content: flex-end; }
.u-gap-1 { gap: var(--sp-1); }
.u-gap-2 { gap: var(--sp-2); }
.u-gap-3 { gap: var(--sp-3); }
.u-gap-4 { gap: var(--sp-4); }
.u-mt-1 { margin-top: var(--sp-1); }
.u-mt-2 { margin-top: var(--sp-2); }
.u-mt-3 { margin-top: var(--sp-3); }
.u-mb-1 { margin-bottom: var(--sp-1); }
.u-mb-2 { margin-bottom: var(--sp-2); }
.u-mb-3 { margin-bottom: var(--sp-3); }
.u-ml-auto { margin-left: auto; }
.u-p-2 { padding: var(--sp-2); }
.u-p-3 { padding: var(--sp-3); }
.u-px-2 { padding-left: var(--sp-2); padding-right: var(--sp-2); }
.u-py-2 { padding-top: var(--sp-2); padding-bottom: var(--sp-2); }
.u-text-muted { color: var(--text-muted); }
.u-text-2 { color: var(--text-2); }
.u-text-accent { color: var(--accent); }
.u-text-success { color: var(--success); }
.u-text-warning { color: var(--amber-ink); }
.u-text-danger { color: var(--danger); }
.u-text-info { color: var(--info); }
.u-text-center { text-align: center; }
.u-text-right { text-align: right; }
.u-fs-xs { font-size: var(--fs-xs); }
.u-fs-sm { font-size: var(--fs-sm); }
.u-fs-base { font-size: var(--fs-base); }
.u-fs-md { font-size: var(--fs-md); }
.u-fs-lg { font-size: var(--fs-lg); }
.u-fw-bold { font-weight: var(--fw-bold); }
.u-font-mono { font-family: var(--ff-mono); }
.u-hidden { display: none !important; }
.u-w-full { width: 100%; }
.u-flex-1 { flex: 1; }
.u-flex-shrink-0 { flex-shrink: 0; }
.u-flex-dir-col { flex-direction: column; }
.u-block { display: block; }
.u-grid { display: grid; }
.u-cursor-pointer { cursor: pointer; }
.u-nowrap { white-space: nowrap; }
.u-overflow-hidden { overflow: hidden; }
.u-overflow-y-auto { overflow-y: auto; }
.u-text { color: var(--text); }
.u-bg-surface { background: var(--surface); }
.u-bg-surface-2 { background: var(--surface-2); }
.u-border { border: 1px solid var(--border); }
.u-border-t { border-top: 1px solid var(--border); }
.u-border-b { border-bottom: 1px solid var(--border); }
.u-rounded-md { border-radius: var(--r-md); }
.u-text-on-accent { color: var(--accent-text); }

/* ============================================================
   공사계획 · 사진 (카드 M4) — 사진은 photo.js(.photo-* .tag-btn). 공사계획 화면은 js/ui/gantt.js(.gantt-*).
   ============================================================ */
.plan-root, .photo-root { display: flex; flex-direction: column; gap: var(--sp-3); }
.plan-root, .gantt-host { min-width: 0; max-width: 100%; }
.gantt-host { display: flex; flex-direction: column; gap: var(--sp-3); }
#plan-palette-popup { border-radius: var(--r-xl) !important; box-shadow: var(--sh-md) !important; }

/* 공정표 — 트리 표 + 막대 (공정표 재구축 1단계). 색은 토큰만: 막대 = 일정색(--c, 없으면 navy) · 오늘선 amber · 지연 red.
   행 높이 32px. 왼쪽 열(.gantt-label)은 가로 스크롤해도 sticky left, 머리글(.gantt-head)은 sticky top.
   주말·공휴일 음영·달 경계선·오늘선은 .gantt-layer 한 겹(행 아래에 깔림). */
.gantt-tools { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.gantt-sp { flex: 1; }
.gantt-seg { display: inline-flex; border: 1px solid var(--line); border-radius: var(--r-btn); overflow: hidden; background: var(--card); }
.gantt-seg button { min-width: 40px; min-height: 30px; padding: 0 12px; border: 0; border-right: 1px solid var(--line); background: var(--card); color: var(--ink); font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-semi); cursor: pointer; }
.gantt-seg button:last-child { border-right: 0; }
.gantt-seg button[aria-pressed="true"] { background: var(--navy); color: var(--on-navy); }
.gantt-delay { border: 0; border-radius: var(--r-pill); padding: 4px 12px; background: var(--red-soft); color: var(--red); font-size: var(--fs-sm); font-weight: var(--fw-semi); cursor: pointer; }
.gantt-delay[hidden] { display: none; }
.gantt-fs { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--mute); }
.gantt-fs input[type="range"] { width: 88px; accent-color: var(--navy); }
.gantt-fs .num { min-width: 34px; color: var(--ink-2); }
.gantt-empty { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); padding-bottom: var(--sp-4); background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card); }

.gantt-scroll {
  --gantt-lw: 260px;
  position: relative; overflow: auto; -webkit-overflow-scrolling: touch;
  max-height: calc(100dvh - 210px); min-height: 220px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card);
  font-variant-numeric: tabular-nums;
}
.gantt { position: relative; width: calc(var(--gantt-lw) + var(--gantt-w)); min-width: 100%; }
.gantt-head { position: sticky; top: 0; z-index: 4; display: flex; background: var(--surface-2); border-bottom: 1px solid var(--line); }
.gantt-head .gantt-label { z-index: 5; background: var(--surface-2); color: var(--mute); font-size: var(--fs-xs); font-weight: var(--fw-bold); }
.gantt-ticks { position: relative; flex: none; width: var(--gantt-w); }
.gantt-tkrow { position: relative; height: 22px; }
.gantt-tkrow + .gantt-tkrow { border-top: 1px solid var(--line-soft); }
.gantt-tk {
  position: absolute; top: 0; height: 100%; padding: 0 4px; overflow: hidden; white-space: nowrap; box-sizing: border-box;
  border-left: 1px solid var(--line-soft); line-height: 22px; font-size: var(--fs-2xs); font-weight: var(--fw-semi); color: var(--ink-2);
}
.gantt-tkrow:first-child .gantt-tk { overflow: clip; font-weight: var(--fw-bold); color: var(--ink); }   /* clip: 안쪽 sticky 가 동작하도록(hidden 은 스크롤 박스가 된다) */
.gantt-tkrow:first-child .gantt-tk > span { position: sticky; left: calc(var(--gantt-lw) + 4px); }
.gantt-tkrow[data-zoom="day"] .gantt-tk { padding: 0; text-align: center; }
.gantt-tk[data-off="weekend"] { color: var(--mute); background: var(--bg); }
.gantt-tk[data-off="holiday"] { color: var(--red); background: var(--bg); }
.gantt-today-mk { position: absolute; bottom: 0; height: 3px; background: var(--amber); pointer-events: none; }

.gantt-body { position: relative; }
.gantt-layer { position: absolute; top: 0; bottom: 0; left: var(--gantt-lw); width: var(--gantt-w); pointer-events: none; }
.gantt-off { position: absolute; top: 0; bottom: 0; background: var(--bg); }
.gantt-vl { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--line); }
.gantt-today { position: absolute; top: 0; bottom: 0; width: 2px; margin-left: -1px; background: var(--amber); }

.gantt-row { display: flex; height: 32px; border-bottom: 1px solid var(--line-soft); }
.gantt-label {
  position: sticky; left: 0; z-index: 2; flex: none; box-sizing: border-box; width: var(--gantt-lw);
  display: flex; align-items: center; gap: 6px; padding: 0 10px 0 6px;
  background: var(--card); border-right: 1px solid var(--line);
  font-size: var(--plan-fs, 12px); color: var(--ink);
}
.gantt-hcell { padding-left: 12px; }
.gantt-row:hover .gantt-label { background: var(--surface-2); }
.gantt-row[data-group] .gantt-label { background: var(--surface-2); font-weight: var(--fw-bold); }
.gantt-row[data-depth="1"] .gantt-label { padding-left: 22px; }
.gantt-tg, .gantt-tg-sp { flex: none; width: 20px; }
.gantt-tg { height: 24px; padding: 0; border: 0; border-radius: var(--r-sm); background: transparent; color: var(--mute); font-size: 12px; cursor: pointer; }
.gantt-tg:hover { background: var(--line-soft); color: var(--ink); }
.gantt-dot { flex: none; width: 10px; height: 10px; border-radius: 3px; background: var(--c, var(--navy)); }
.gantt-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gantt-pct { flex: none; min-width: 38px; text-align: right; color: var(--mute); font-size: var(--fs-xs); }
.gantt-late { flex: none; padding: 1px 7px; border-radius: var(--r-pill); background: var(--red-soft); color: var(--red); font-size: var(--fs-2xs); font-weight: var(--fw-bold); white-space: nowrap; }
.gantt-late[data-tone="behind"] { background: transparent; box-shadow: inset 0 0 0 1px var(--red); font-weight: var(--fw-semi); }

.gantt-track { position: relative; flex: none; width: var(--gantt-w); }
.gantt-row:hover .gantt-track { background: color-mix(in srgb, var(--surface-2) 45%, transparent); }
.gantt-bar {
  position: absolute; top: 8px; height: 16px; overflow: hidden; box-sizing: border-box;
  border-radius: var(--r-sm); background: color-mix(in srgb, var(--c, var(--navy)) 30%, var(--card));
}
.gantt-bar > i { position: absolute; left: 0; top: 0; bottom: 0; background: var(--c, var(--navy)); pointer-events: none; }
.gantt-bar[data-status="late"] { background: color-mix(in srgb, var(--red) 25%, var(--card)); }
.gantt-bar[data-status="late"] > i { background: var(--red); }
.gantt-bar[data-status="behind"] { box-shadow: inset 0 0 0 1.5px var(--red); }
.gantt-bar.gantt-grp { top: 12px; height: 8px; border-radius: 2px; background: color-mix(in srgb, var(--navy) 35%, var(--card)); }
.gantt-bar.gantt-grp > i { background: var(--navy); }
.gantt-bar.gantt-grp[data-status="late"] { background: color-mix(in srgb, var(--red) 30%, var(--card)); }
.gantt-bar.gantt-grp[data-status="late"] > i { background: var(--red); }
.gantt-scroll[data-editable] .gantt-bar:not(.gantt-grp) { cursor: grab; }
.gantt-handle { position: absolute; top: 0; bottom: 0; width: clamp(3px, 25%, 8px); cursor: ew-resize; }   /* 짧은 막대도 가운데(이동)가 남게 막대 폭의 25%까지만 */
.gantt-handle[data-side="start"] { left: 0; }
.gantt-handle[data-side="end"] { right: 0; }
.gantt-handle:hover { background: color-mix(in srgb, var(--card) 45%, transparent); }
/* 편집(Task 6) — 이름 클릭 = 인라인 수정, 색 점 = 팔레트, [수정] = 모달(행에 마우스를 올리면 보임). 끌기 중 커서 고정 */
.gantt-name[data-action], .gantt-dot[data-action] { cursor: pointer; }
.gantt-name[data-action]:hover { text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 3px; }
.gantt-edit { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; padding: 0; border: 0; border-radius: var(--r-sm); background: transparent; color: var(--mute); cursor: pointer; opacity: 0; }
.gantt-row:hover .gantt-edit, .gantt-edit:focus-visible { opacity: 1; }
.gantt-edit:hover { background: var(--line-soft); color: var(--ink); }
.gantt-scroll[data-drag], .gantt-scroll[data-drag] * { user-select: none; }
.gantt-scroll[data-drag="move"], .gantt-scroll[data-drag="move"] * { cursor: grabbing !important; }
.gantt-scroll[data-drag="start"], .gantt-scroll[data-drag="start"] *,
.gantt-scroll[data-drag="end"], .gantt-scroll[data-drag="end"] * { cursor: ew-resize !important; }
.gantt-bar.is-drag { z-index: 1; outline: 2px solid var(--ink); outline-offset: 1px; }
.gantt-nodate { position: absolute; left: 8px; top: 0; line-height: 32px; font-size: var(--fs-2xs); color: var(--mute); }
.gantt-hl .gantt-label { background: var(--red-soft); box-shadow: inset 3px 0 0 var(--red); }
.gantt-hl .gantt-bar { outline: 2px solid var(--red); outline-offset: 1px; }
/* 2단계(Task 3) — 선택 행 · [⋯] 행 메뉴 · N일 밀기 창 (PC 편집 전용 — 모바일·공유 보기에는 그려지지 않는다) */
.gantt-more { font-size: 15px; font-weight: var(--fw-bold); line-height: 1; letter-spacing: -1px; }
.gantt-scroll[data-editable] .gantt-label { cursor: default; }
/* 편집 가능할 때 이름은 글자 폭만(누르면 이름 수정) — 남는 칸이 행 선택을 위한 빈 곳이 된다(배치는 그대로: 뒤 칩·버튼·진행률은 오른쪽) */
.gantt-scroll[data-editable] .gantt-name { flex: 0 1 auto; margin-right: auto; }
.gantt-row.is-sel .gantt-label, .gantt-row.is-sel:hover .gantt-label { background: var(--navy-soft); box-shadow: inset 3px 0 0 var(--navy); }
.gantt-row.is-sel .gantt-track { background: color-mix(in srgb, var(--navy-soft) 40%, transparent); }
.gantt-row.is-sel .gantt-edit { opacity: 1; }
.gantt-menu .menu-item { cursor: pointer; }
.gantt-menu-lb { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
.gantt-menu-lb small { color: var(--mute); font-size: var(--fs-2xs); font-weight: var(--fw-regular, 400); }
.gantt-menu .menu-item[aria-disabled="true"] { cursor: not-allowed; color: var(--mute); }
.gantt-menu .menu-item[aria-disabled="true"]:hover { background: transparent; }
.gantt-menu .menu-item.is-danger, .gantt-menu .menu-item.is-danger svg { color: var(--red); }
.gantt-kbd { flex: none; padding: 1px 6px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface-2); color: var(--mute); font: inherit; font-size: var(--fs-2xs); }
.gantt-shift { display: flex; flex-direction: column; gap: var(--sp-3); }
.gantt-shift-base { margin: 0; color: var(--ink-2); font-size: var(--fs-sm); line-height: 1.6; }
.gantt-shift-f { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-sm); font-weight: var(--fw-semi); }
.gantt-shift-f small { color: var(--mute); font-weight: var(--fw-regular, 400); }
.gantt-shift-f .input { width: 140px; }
.gantt-shift-pv { margin: 0; min-height: 1.5em; font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--navy-ink, var(--ink)); }
.gantt-shift-pv[data-tone="warn"] { color: var(--red); }
/* 2단계(Task 4) — 빠른 추가 줄(본문 맨 아래) · 빈 줄 끌기 유령 막대 (PC 편집 전용) */
.gantt-quick .gantt-label { gap: 4px; }
.gantt-quick-in { flex: 1; min-width: 0; min-height: 0; height: 24px; padding: 0 8px; font-size: var(--plan-fs, 12px); background: transparent; border-color: transparent; }
.gantt-quick-in:hover { border-color: var(--line); }
.gantt-quick-in:focus { background: var(--card); border-color: var(--navy); }
.gantt-quick-to { flex: none; max-width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--mute); font-size: var(--fs-2xs); font-weight: var(--fw-semi); }
.gantt-quick-to[hidden] { display: none; }
.gantt-quick .gantt-track { cursor: crosshair; }
.gantt-bar.is-new { background: color-mix(in srgb, var(--navy) 18%, transparent); border: 1.5px dashed var(--navy); pointer-events: none; }
.gantt-new-lb { position: absolute; top: 0; line-height: 32px; white-space: nowrap; pointer-events: none; color: var(--ink-2); font-size: var(--fs-2xs); font-weight: var(--fw-semi); }
.gantt-scroll[data-drag="new"], .gantt-scroll[data-drag="new"] * { cursor: crosshair !important; }
/* 2단계(Task 5) — 템플릿 창 (PC 편집 전용) · 빈 공정표의 [일정 추가]·[템플릿으로 시작] */
.gantt-empty-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-2); }
.gantt-tpl { display: flex; flex-direction: column; gap: var(--sp-4); }
.gantt-tpl-start { display: flex; align-items: center; gap: var(--sp-3); font-size: var(--fs-sm); font-weight: var(--fw-semi); }
.gantt-tpl-start small, .gantt-tpl-h small { color: var(--mute); font-weight: var(--fw-regular, 400); }
.gantt-tpl-start .input { width: 160px; }
.gantt-tpl-sec { display: flex; flex-direction: column; gap: var(--sp-2); }
.gantt-tpl-h { margin: 0; font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--ink); }
.gantt-tpl-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-2); }
.gantt-tpl-card { display: flex; flex-direction: column; gap: 4px; padding: var(--sp-3); border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface-2); }
.gantt-tpl-card .btn { align-self: flex-start; margin-top: auto; }
.gantt-tpl-card-h { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-2); }
.gantt-tpl-card-h b { font-size: var(--fs-md); color: var(--ink); }
.gantt-tpl-cnt, .gantt-tpl-meta { color: var(--mute); font-size: var(--fs-2xs); white-space: nowrap; }
.gantt-tpl-desc { margin: 0 0 4px; color: var(--ink-2); font-size: var(--fs-xs); line-height: 1.5; }
.gantt-tpl-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; max-height: 240px; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--r-lg); }
.gantt-tpl-item { display: flex; align-items: center; gap: var(--sp-2); padding: 6px var(--sp-3); border-top: 1px solid var(--line-soft); }
.gantt-tpl-item:first-child { border-top: 0; }
.gantt-tpl-item.is-cur .gantt-tpl-nm { color: var(--navy-ink, var(--ink)); }
.gantt-tpl-main { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.35; }
.gantt-tpl-nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-sm); }
.gantt-tpl-meta { overflow: hidden; text-overflow: ellipsis; }
.gantt-tpl-del { color: var(--mute); }
.gantt-tpl-del:hover { color: var(--red); }
.gantt-tpl-del-sp { flex: none; width: 28px; }
.gantt-tpl-none { margin: 0; padding: var(--sp-3); border: 1px dashed var(--line); border-radius: var(--r-lg); color: var(--mute); font-size: var(--fs-xs); line-height: 1.5; }
.gantt-tpl-save { padding-top: var(--sp-3); border-top: 1px solid var(--line); }
.gantt-tpl-save-row { display: flex; gap: var(--sp-2); }
.gantt-tpl-save-row .input { flex: 1; min-width: 0; }
.gantt-tpl-note { margin: 0; color: var(--mute); font-size: var(--fs-2xs); line-height: 1.5; }
/* 2단계(Task 6) — 엑셀에서 붙여넣기 창 (PC 편집 전용) · 미리보기·오류만 다시 그린다(textarea 는 그대로) */
.gantt-paste { display: flex; flex-direction: column; gap: var(--sp-2); }
.gantt-paste-guide { margin: 0; font-size: var(--fs-sm); color: var(--ink); line-height: 1.55; }
.gantt-paste-note, .gantt-paste-hint { margin: 0; color: var(--mute); font-size: var(--fs-2xs); line-height: 1.5; }
.gantt-paste-ta { min-height: 150px; max-height: 40vh; font-family: ui-monospace, Consolas, monospace; font-size: var(--fs-xs); line-height: 1.5; white-space: pre; overflow: auto; }
.gantt-paste-out { display: flex; flex-direction: column; gap: var(--sp-2); min-height: 1.5em; }
.gantt-paste-sum { margin: 0; font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--navy-ink, var(--ink)); }
.gantt-paste-sum[data-tone="warn"] { color: var(--red); }
.gantt-paste-pv { max-height: 240px; overflow: auto; border: 1px solid var(--line); border-radius: var(--r-lg); }
.gantt-paste-tbl { width: 100%; border-collapse: collapse; font-size: var(--fs-xs); }
.gantt-paste-tbl th { position: sticky; top: 0; background: var(--surface-2); color: var(--mute); font-weight: var(--fw-semi); text-align: left; padding: 4px 8px; border-bottom: 1px solid var(--line); }
.gantt-paste-tbl td { padding: 3px 8px; border-top: 1px solid var(--line-soft); white-space: nowrap; }
.gantt-paste-tbl .num { font-variant-numeric: tabular-nums; }
.gantt-paste-tbl th.num, .gantt-paste-tbl td:first-child { color: var(--mute); text-align: right; width: 1%; }
.gantt-paste-nm { max-width: 260px; overflow: hidden; text-overflow: ellipsis; }
.gantt-paste-none { color: var(--mute); }
.gantt-paste-tag { display: inline-block; margin-left: 6px; padding: 0 5px; border-radius: var(--r-chip, 4px); font-size: var(--fs-2xs); font-weight: var(--fw-semi); line-height: 1.6; }
.gantt-paste-tag[data-kind="old"] { background: var(--gray-soft); color: var(--ink-2); }
.gantt-paste-tag[data-kind="new"] { background: var(--navy-soft); color: var(--navy-ink, var(--navy)); }
.gantt-paste-more { margin: 0; padding: 4px 8px; color: var(--mute); font-size: var(--fs-2xs); }
.gantt-paste-errs { list-style: none; margin: 0; padding: 6px 10px; max-height: 160px; overflow-y: auto; border: 1px solid var(--red); border-radius: var(--r-lg); background: var(--red-soft); color: var(--red); font-size: var(--fs-xs); line-height: 1.6; }
.gantt-paste-errs b { font-weight: var(--fw-bold); margin-right: 2px; }
.gantt-paste-errs .is-limit { font-weight: var(--fw-semi); }
.gantt-paste-errs .gantt-paste-more { padding: 0; color: var(--red); }
/* 막대 일보 팝업(Task 8) — .plan-root 안 한 개, 위치는 JS(position:fixed, .gantt-scroll 보이는 영역 안) */
.gantt-pop {
  position: fixed; z-index: var(--z-dropdown); box-sizing: border-box; width: 240px; max-width: calc(100vw - 32px);
  display: flex; flex-direction: column; gap: 4px; padding: 10px 12px;
  background: var(--card); color: var(--ink); border: 1px solid var(--line); border-radius: var(--r-xl); box-shadow: var(--sh-lg);
  font-size: var(--fs-sm); line-height: 1.55;
}
.gantt-pop[hidden] { display: none; }
.gantt-pop-h { font-size: var(--fs-base); font-weight: var(--fw-bold); }
.gantt-pop-plan { color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gantt-pop-ph { display: block; width: 100%; height: 72px; margin: 2px 0; object-fit: cover; border-radius: var(--r-md); background: var(--surface-2); }
.gantt-pop-stat { font-weight: var(--fw-semi); font-variant-numeric: tabular-nums; }
.gantt-pop-memo { margin: 0; color: var(--ink-2); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; white-space: pre-line; }
.gantt-pop-none { color: var(--mute); }
.gantt-pop-go { margin-top: 4px; justify-content: center; }
@media (max-width: 767px) { .gantt-pop-go { min-height: var(--hit); } }

/* 일정 추가/수정 모달 */
.plan-form { display: flex; flex-direction: column; gap: var(--sp-3); }
.plan-form-dates { display: grid; grid-template-columns: 1fr 1fr 96px; gap: var(--sp-3); }   /* 시작일 · 종료일 · 작업일수 */
#planModal #pf-delete { margin-right: auto; }   /* 삭제는 왼쪽 끝 — 취소·저장과 떨어뜨린다 */
.plan-colors { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.plan-color-btn { width: 26px; height: 26px; padding: 0; border-radius: 50%; border: 2px solid var(--card); box-shadow: 0 0 0 1px var(--line); cursor: pointer; }
.plan-color-btn:hover { box-shadow: 0 0 0 1px var(--border-strong); }
.plan-color-btn.selected { border-color: var(--card); box-shadow: 0 0 0 2px var(--navy); }
.plan-color-custom { width: 30px; height: 30px; padding: 0; border: 1px solid var(--line); border-radius: 50%; background: none; cursor: pointer; }
.plan-holiday { display: flex; flex-direction: column; gap: 6px; }
.plan-radio { display: flex; align-items: center; gap: 8px; color: var(--ink); font-size: var(--fs-base); font-weight: var(--fw-regular); cursor: pointer; }
.plan-workdays { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; background: var(--bg); border-radius: var(--r-lg); color: var(--mute); font-size: var(--fs-base); font-weight: var(--fw-semi); }
.plan-workdays b { color: var(--ink); font-size: var(--fs-xl); font-weight: var(--fw-extra); }

.plan-hint { color: var(--mute); font-size: var(--fs-xs); font-weight: var(--fw-regular); }
.plan-boq-list { max-height: 170px; overflow: auto; border: 1px solid var(--line); border-radius: var(--r-lg); padding: 4px; background: var(--card); }
.plan-boq-row { display: flex; align-items: center; gap: 8px; padding: 4px 6px; border-radius: 6px; font-size: var(--fs-sm); font-weight: var(--fw-regular); color: var(--ink); cursor: pointer; }
.plan-boq-row:hover { background: var(--surface-2); }
.plan-boq-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-boq-qty { flex-shrink: 0; color: var(--mute); }
.plan-res-rows { display: flex; flex-direction: column; gap: 6px; margin-bottom: 6px; }
.plan-res-row { display: grid; grid-template-columns: 1fr 90px 32px; gap: 6px; align-items: center; }
.plan-res-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.plan-res-table th, .plan-res-table td { padding: 6px 8px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.plan-res-table tfoot td { font-weight: var(--fw-semi); }

/* 사진 */
.photo-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); }
.photo-filter { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.photo-filter-label { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--mute); }
.photo-add-m { margin-left: auto; }
.tag-filter-wrap { display: flex; flex-wrap: wrap; gap: 6px; }
.tag-btn {
  display: inline-flex; align-items: center;
  min-height: 26px; padding: 0 10px;
  border-radius: var(--r-chip);
  background: var(--gray-soft); color: var(--gray-ink);
  font-size: var(--fs-xs); font-weight: var(--fw-semi);
  cursor: pointer; user-select: none;
}
.tag-btn:hover { background: var(--navy-soft); color: var(--navy-ink); }
.tag-btn.active { background: var(--navy); color: var(--on-navy); }
.photo-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-3); }
.photo-grid > .empty-state { grid-column: 1 / -1; }
.photo-card { overflow: hidden; background: transparent; border: 0; border-radius: 8px; cursor: pointer; }
.photo-card img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 8px; background: var(--gray-soft); transition: filter var(--dur) var(--ease); }
.photo-card:hover img { filter: brightness(.93); }
.photo-card-info { padding: 6px 2px 0; }
.photo-card-date { font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--mute); }
.photo-card-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
/* 무료 계정 안내 — 사진은 유료 플랜 기능 */
.photo-lock, .photo-lock-note { grid-column: 1 / -1; }
.photo-lock { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2); padding: var(--sp-4); background: var(--card); border: 1px solid var(--line); border-radius: 12px; max-width: 560px; }
.photo-lock-title { font-size: var(--fs-lg, 16px); color: var(--ink); }
.photo-lock p { margin: 0; color: var(--mute); line-height: 1.6; }
.photo-lock-note { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2); padding: var(--sp-2) var(--sp-3); background: var(--amber-soft); border-radius: 8px; font-size: var(--fs-sm, 13px); color: var(--ink); }
/* 사진 저장 공간 사용량 막대 (js/photo-storage.js photoUsageHtml) — 80%부터 amber, 가득 차면 red */
.ph-usage { grid-column: 1 / -1; display: flex; flex-direction: column; gap: 4px; max-width: 360px; }
.ph-usage-bar { height: 6px; border-radius: 999px; background: var(--line); overflow: hidden; }
.ph-usage-bar > i { display: block; height: 100%; width: var(--ph-pct, 0%); background: var(--navy); border-radius: inherit; }
.ph-usage[data-level="warn"] .ph-usage-bar > i { background: var(--amber); }
.ph-usage[data-level="full"] .ph-usage-bar > i { background: var(--red); }
.ph-usage > small { font-size: var(--fs-xs); color: var(--mute); font-variant-numeric: tabular-nums; }
.photo-tag { padding: 1px 6px; border-radius: var(--r-chip); background: var(--navy-soft); color: var(--navy-ink); font-size: var(--fs-2xs); font-weight: var(--fw-semi); }
.photo-add-form { display: flex; flex-direction: column; gap: var(--sp-3); }

/* 사진 뷰어 */
.modal.photo-viewer[data-size="lg"] { width: min(920px, 100%); }
.photo-viewer-body { display: flex; flex-direction: column; align-items: center; gap: var(--sp-3); padding: var(--sp-4); text-align: center; }
.photo-viewer-body img { display: block; max-width: 100%; max-height: 65vh; object-fit: contain; border-radius: 8px; }
.photo-view-info { color: var(--ink-2); font-size: var(--fs-base); }
.photo-viewer-foot { justify-content: center; }

/* ============================================================
   게스트 모드 — 로그인·가입 시트, 환영 시트, 안내 띠 (js/ui/guest.js)
   로그인 오버레이는 없다(게스트로 바로 시작). 로그인 폼은 uiOpenModal 안에 그린다.
   ============================================================ */
.login-logo { display: grid; place-items: center; flex: none; width: 48px; height: 48px; border-radius: 12px; background: var(--amber); color: var(--on-amber); font-size: 22px; font-weight: var(--fw-extra); }
.login-form { display: flex; flex-direction: column; gap: var(--sp-3); width: 100%; max-width: 360px; }
.login-form .input { min-height: 40px; }
.login-btn { width: 100%; min-height: 40px; justify-content: center; font-size: var(--fs-md); font-weight: var(--fw-bold); }
.login-google { background: var(--card); border: 1px solid var(--border-strong); color: var(--ink); }
.login-google:hover { background: var(--surface-2); }
.login-google svg { flex: none; }
.login-or { display: flex; align-items: center; gap: 10px; color: var(--mute); font-size: var(--fs-xs); }
.login-or::before, .login-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.login-msg { min-height: 18px; margin: 0; color: var(--red); font-size: var(--fs-sm); font-weight: var(--fw-semi); }
.login-sub { margin: 0; color: var(--mute); font-size: var(--fs-base); }
.login-msg[data-tone="ok"] { color: var(--green); }
.login-links { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px 12px; }
.login-links button { padding: 4px 0; color: var(--mute); font-size: var(--fs-sm); text-decoration: underline; text-underline-offset: 3px; }
.login-links button:hover { color: var(--ink); }
.guest-welcome { display: flex; flex-direction: column; gap: var(--sp-3); align-items: stretch; }
.guest-welcome .login-logo { align-self: flex-start; }
.guest-welcome-title { margin: 0; color: var(--ink); font-size: var(--fs-xl); font-weight: var(--fw-extra); }
.guest-welcome-sub, .guest-welcome-hint, .guest-note { margin: 0; color: var(--mute); font-size: var(--fs-sm); line-height: 1.6; }
.guest-welcome-hint { margin-top: calc(var(--sp-2) * -1); }
.guest-welcome-login { align-self: center; padding: 6px 0; color: var(--mute); font-size: var(--fs-sm); text-decoration: underline; text-underline-offset: 3px; }
.guest-sites { margin: var(--sp-2) 0; padding-left: 18px; color: var(--ink); font-size: var(--fs-base); }
.guest-bar { border-radius: 0; border-width: 0 0 1px; padding: 8px 18px; font-size: var(--fs-sm); }
.guest-bar .banner-msg { min-width: 0; }
.sb-guest { max-width: 100%; padding: 4px 6px; border-radius: 6px; color: var(--amber); font-size: var(--fs-xs); font-weight: var(--fw-bold); text-align: left; }
.guest-welcome-warn { color: var(--amber-ink); font-weight: var(--fw-semi); }
.save-status[data-tone="warn"] { color: var(--amber); cursor: pointer; font-weight: var(--fw-bold); }
.save-status[data-tone="warn"]:hover { text-decoration: underline; }
.sb-guest:hover { background: var(--side-hover); }

/* ============================================================
   공유 모드 (?share=ID) — share.js가 <html data-readonly="1">을 붙인다. 쓰기 진입점을 숨기고 안내 배너를 둔다(shell.js uiApplyShareMode).
   저장은 share.js/db.js가 no-op으로 막는다. 이 규칙은 화면에서 쓰기 버튼을 치우는 것일 뿐이다.
   ============================================================ */
#uiShareBanner { margin: 10px 18px 0; }
[data-readonly] .btn-danger,
[data-readonly] [data-action$="-add"],
[data-readonly] [data-action="photo-cleanup"],
[data-readonly] .fab, [data-readonly] .tab-fab,
[data-readonly] #uiTopActions .btn:not([data-action="go-today-daily"]),
[data-readonly] .empty-state .btn,
[data-readonly] .sb-item[data-action="company"],
[data-readonly] .sb-tool[data-action="undo"], [data-readonly] .sb-tool-out,
[data-readonly] .sb-chev, [data-readonly] .m-site svg { display: none !important; }
/* 원가 가림 — 공유 데이터에는 단가·거래처·금액이 없다(share.js 화이트리스트). 0원으로 보이는 조각을 숨긴다.
   [data-cost]: 렌더러가 원가 조각(투입·손익·단가·거래처 금액·원가 카드)에 붙이는 표시. .col-cost: 일보 표의 단가·금액·누계·거래처 열(th·td·col).
   기성(내역서·오늘기성·공정률)은 남긴다. 숨기는 화면(탭) 목록은 shell.js UI_SHARE_TAB_HIDE. */
[data-readonly] [data-cost], [data-readonly] .col-cost,
[data-readonly] [data-banner="vendor-warn"], [data-readonly] #dash-banners, [data-readonly] [data-action="daily-print"] { display: none !important; }
[data-readonly] .m-cal-d[data-a]::after { content: none !important; }   /* 모바일 홈 달력 칸의 일 투입 금액 */
/* share.js가 html[data-readonly] * 에 pointer-events:auto !important 를 넣으므로 !important로 맞선다(특이도는 이쪽이 높다) */
[data-readonly] .sb-site, [data-readonly] .sb-org, [data-readonly] .m-site { pointer-events: none !important; }


/* ============================================================
   대시보드 달력 (D1) — .cal-* · 선택일 패널 .day-panel-*
   색은 토큰만. 카테고리 색은 data-cat(eq|lb|mt|ex|os|wk)로 --cat-* 를 받는다.
   ============================================================ */
.cal-wrap { display: flex; flex-direction: column; min-width: 0; overflow: hidden; }
.cal-head { padding: 10px 12px 8px; border-bottom: 1px solid var(--line); display: flex; flex-direction: column; gap: 8px; }
.cal-head-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cal-head h4 { font-size: var(--fs-md); font-weight: var(--fw-extra); margin-right: 4px; }
.cal-ym { margin-left: 6px; color: var(--mute); font-size: var(--fs-sm); font-weight: var(--fw-semi); }
.cal-settings-btn { margin-left: auto; }
.cal-flabel { font-size: var(--fs-xs); color: var(--mute); margin-right: 2px; }
.cal-flabel-sep { margin-left: 8px; padding-left: 10px; border-left: 1px solid var(--line); }
.cal-fchip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: var(--r-pill);
  border: 1px solid var(--line); background: var(--card); color: var(--mute);
  font-size: var(--fs-xs); font-weight: var(--fw-bold); cursor: pointer;
}
.cal-fchip[data-cat]::before { content: ""; width: 8px; height: 8px; border-radius: 3px; background: var(--c, var(--mute)); }
.cal-fchip[data-cat="eq"] { --c: var(--cat-eq); }
.cal-fchip[data-cat="lb"] { --c: var(--cat-lb); }
.cal-fchip[data-cat="mt"] { --c: var(--cat-mt); }
.cal-fchip[data-cat="ex"] { --c: var(--cat-ex); }
.cal-fchip[data-cat="wk"] { --c: var(--ink); }
.cal-fchip[aria-pressed="true"] { background: var(--navy); border-color: var(--navy); color: var(--on-navy); }
.cal-fchip[aria-pressed="true"][data-cat]::before { background: var(--c, var(--on-navy)); box-shadow: 0 0 0 1.5px var(--on-navy); }
.cal-fchip[data-empty="1"] { opacity: .6; }
.cal-slot { display: inline-flex; align-items: center; gap: 2px; }
.cal-slot-save {
  display: inline-grid; place-items: center; width: 24px; height: 24px;
  border-radius: var(--r-md); color: var(--mute); border: 1px solid transparent;
}
.cal-slot-save:hover { background: var(--gray-soft); color: var(--ink); }
.cal-settings { display: flex; flex-wrap: wrap; gap: 10px; padding: 10px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-lg); }
.cal-settings[hidden] { display: none; }
.cal-set-grp { display: flex; flex-direction: column; gap: 4px; min-width: 96px; font-size: var(--fs-sm); }
.cal-set-grp b { font-size: var(--fs-xs); color: var(--cat, var(--mute)); }
.cal-set-grp[data-cat="eq"] { --cat: var(--cat-eq); }
.cal-set-grp[data-cat="lb"] { --cat: var(--amber-ink); }
.cal-set-grp[data-cat="mt"] { --cat: var(--green-ink); }
.cal-set-grp[data-cat="ex"] { --cat: var(--gray-ink); }
.cal-set-grp label { display: flex; align-items: center; gap: 5px; cursor: pointer; }

.cal-dow { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); border-bottom: 1px solid var(--line); background: var(--surface-2); }
.cal-dow i { font-style: normal; font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--mute); text-align: center; padding: 5px 0; }
.cal-dow i.sun { color: var(--red); }
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); grid-auto-rows: minmax(104px, auto); }
.cal-day {
  position: relative; min-width: 0; overflow: hidden;
  display: flex; flex-direction: column; gap: 3px;
  padding: 5px 6px 4px;
  border-right: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft);
  cursor: pointer; outline-offset: -2px;
}
.cal-day:nth-child(7n) { border-right: 0; }
.cal-day:hover { background: var(--surface-2); }
.cal-day:focus-visible { outline: 2px solid var(--blue); }
.cal-day .n {
  width: 20px; height: 20px; line-height: 20px; text-align: center; flex: none;
  font-size: 11.5px; font-weight: var(--fw-bold); color: var(--ink-2); border-radius: var(--r-md);
}
.cal-day.sun .n { color: var(--red); }
.cal-day.o { background: var(--surface-2); }
.cal-day.o .n { color: var(--faint); }
.cal-day.today .n { background: var(--amber); color: var(--on-amber); }
.cal-day.sel { outline: 2px solid var(--navy); background: var(--surface-2); }
.cal-day .st { position: absolute; top: 5px; right: 6px; }
.cal-day .chip { display: block; }
.cal-day .more { font-size: var(--fs-2xs); color: var(--mute); }
.cal-day .tot { margin-top: auto; font-size: var(--fs-xs); font-weight: var(--fw-extra); color: var(--ink); text-align: right; }
.cal-day .ph { position: absolute; bottom: 5px; left: 6px; color: var(--mute); display: inline-flex; }

.day-panel { display: flex; flex-direction: column; min-width: 0; overflow: hidden; }
.day-panel-head { display: flex; align-items: center; gap: 8px; padding: 11px 14px; border-bottom: 1px solid var(--line); }
.day-panel-head > b { font-size: var(--fs-md); font-weight: var(--fw-extra); }
.day-panel-go { margin-left: auto; white-space: nowrap; }
.day-panel-total { display: flex; justify-content: space-between; align-items: center; padding: 10px 14px; background: var(--navy); color: var(--on-navy); }
.day-panel-total span { font-size: var(--fs-sm); color: var(--on-navy-mute); font-weight: var(--fw-semi); }
.day-panel-total strong { font-size: var(--fs-xl); font-weight: var(--fw-extra); }
.day-panel-total small { font-size: var(--fs-xs); margin-left: 2px; color: var(--on-navy-mute); font-weight: var(--fw-semi); }
.day-panel-sec {
  display: flex; justify-content: space-between; gap: 8px; padding: 9px 14px 4px;
  font-size: var(--fs-xs); font-weight: var(--fw-extra); color: var(--mute); letter-spacing: .04em;
  box-shadow: inset 3px 0 0 var(--cat, transparent);
}
.day-panel-sec[data-cat="eq"] { --cat: var(--cat-eq); }
.day-panel-sec[data-cat="lb"] { --cat: var(--cat-lb); }
.day-panel-sec[data-cat="mt"] { --cat: var(--cat-mt); }
.day-panel-sec[data-cat="ex"] { --cat: var(--cat-ex); }
.day-panel-sec[data-cat="os"] { --cat: var(--cat-os); }
.day-panel-sec[data-cat="wk"] { --cat: var(--ink); }
.day-panel-sec span:last-child { font-weight: var(--fw-bold); }
.day-panel-row { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; padding: 6px 14px; font-size: var(--fs-tbl); border-bottom: 1px solid var(--row-line); }
.day-panel-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.day-panel-name small { margin-left: 5px; color: var(--mute); font-size: var(--fs-xs); }
.day-panel-row b { font-weight: var(--fw-bold); white-space: nowrap; }
.day-panel-row .day-panel-out { color: var(--mute); font-weight: var(--fw-semi); font-size: var(--fs-xs); }
.day-panel-memo {
  margin: 10px 14px 0; padding: 8px 10px; white-space: pre-wrap;
  background: var(--surface-2); border: 1px dashed var(--line); border-radius: var(--r-lg);
  font-size: var(--fs-sm); color: var(--ink-2); line-height: 1.5;
}
.day-panel-thumbs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; padding: 10px 14px 4px; }
.day-panel-thumb { aspect-ratio: 4 / 3; border-radius: var(--r-md); overflow: hidden; background: var(--gray-soft); padding: 0; }
.day-panel-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.day-panel-more { align-self: center; color: var(--mute); font-size: var(--fs-xs); }
.day-panel-foot { display: flex; gap: 6px; flex-wrap: wrap; padding: 10px 14px 12px; margin-top: auto; }
.day-panel > .empty { padding: var(--sp-8) var(--sp-4); }
/* 선택일 패널 바로 입력 (js/ui/day-edit.js) */
.dpe-mode { display: inline-flex; gap: 4px; }
.day-panel-head { flex-wrap: wrap; }
.dpe { display: flex; flex-direction: column; min-width: 0; }
.dpe-sec { padding-bottom: 6px; box-shadow: inset 3px 0 0 var(--cat, transparent); }
.dpe-sec[data-cat="eq"] { --cat: var(--cat-eq); }
.dpe-sec[data-cat="lb"] { --cat: var(--cat-lb); }
.dpe-sec[data-cat="mt"] { --cat: var(--cat-mt); }
.dpe-sec[data-cat="ex"] { --cat: var(--cat-ex); }
.dpe-sec[data-cat="os"] { --cat: var(--cat-os); }
.dpe-sec[data-cat="wk"] { --cat: var(--ink); }
.dpe-sec-head { display: flex; justify-content: space-between; gap: 8px; padding: 9px 14px 4px; font-size: var(--fs-xs); font-weight: var(--fw-extra); color: var(--mute); letter-spacing: .04em; }
.dpe-row { display: flex; align-items: center; flex-wrap: wrap; gap: 4px; padding: 3px 14px; }
.dpe-in { height: 30px; padding: 0 7px; font-size: var(--fs-tbl); min-width: 0; }
.dpe-t { flex: 1 1 84px; }
.dpe-q { flex: 0 0 58px; text-align: right; }
.dpe-p { flex: 0 0 82px; text-align: right; }
.dpe-s { flex: 0 0 62px; }
.dpe-amt { flex: 0 0 76px; text-align: right; font-size: var(--fs-tbl); }
.dpe-name { flex: 1 1 110px; min-width: 0; overflow: hidden; text-overflow: ellipsis; font-size: var(--fs-tbl); }
.dpe-name small { margin-left: 5px; color: var(--mute); font-size: var(--fs-xs); }
.dpe-unit { flex: 0 0 auto; color: var(--mute); font-size: var(--fs-xs); }
.dpe-acc { flex: 0 0 auto; font-size: var(--fs-xs); }
.dpe-del { flex: 0 0 auto; margin-left: auto; }
.dpe-foot { padding: 3px 14px 0; }
.dpe-memo { display: block; width: calc(100% - 28px); margin: 4px 14px 0; font-size: var(--fs-tbl); resize: vertical; }
.day-panel-full { display: block; max-width: 100%; max-height: 70vh; margin: 0 auto; border-radius: var(--r-md); }
.day-panel-full-info { margin-top: var(--sp-2); text-align: center; color: var(--mute); font-size: var(--fs-sm); }

/* ── 대시보드 카드 (D2) — .dcards .dcard .dc-* ─────────────
   카드 틀은 .section-card. 폭: data-size="1"(반) | "2"(전체 폭). 모바일은 한 열. 색은 토큰만.
   막대의 width/height(%)만 데이터 값이라 인라인 style 로 둔다. */
#dash-banners { display: flex; flex-direction: column; gap: var(--sp-2); }
#dash-banners:empty { display: none; }
.banner small { color: var(--mute); font-size: var(--fs-xs); font-weight: var(--fw-semi); }
.banner[data-tone="info"] small { color: inherit; opacity: .75; }

.dcards-restore { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-bottom: var(--sp-2); font-size: var(--fs-xs); color: var(--mute); font-weight: var(--fw-semi); }
.dc-restore-chip {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 9px;
  border: 1px dashed var(--border-strong); border-radius: var(--r-pill); background: var(--card);
  color: var(--ink-2); font-size: var(--fs-xs); font-weight: var(--fw-bold);
}
.dc-restore-chip:hover { border-color: var(--navy); color: var(--navy-ink); }
.dcards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; align-items: start; }
.dcards-none { grid-column: 1 / -1; padding: var(--sp-6); text-align: center; color: var(--mute); font-size: var(--fs-sm); }
.dcard[data-size="2"] { grid-column: 1 / -1; }
.dcard.is-dragging { opacity: .55; outline: 2px dashed var(--navy); outline-offset: -2px; }
.dcards.is-sorting { user-select: none; cursor: grabbing; }
.card-grip {
  display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 28px;
  margin-left: -6px; color: var(--faint); cursor: grab; touch-action: none; border-radius: var(--r-md);
}
.card-grip:hover { color: var(--mute); background: var(--gray-soft); }
.dcard .section-head h3 { white-space: nowrap; }
.dcard .section-head .section-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dcard-body { min-width: 0; }
.dcard-body:has(> .tbl-wrap) { padding: 0; }

/* 막대 공통 */
.dc-track { height: 8px; background: var(--gray-soft); border-radius: 4px; overflow: hidden; }
.dc-track-lg { height: 12px; border-radius: 6px; }
.dc-track > i { display: block; height: 100%; border-radius: inherit; background: var(--gray); }
[data-tone="blue"] { --tone: var(--blue); }
[data-tone="navy"] { --tone: var(--navy); }
[data-tone="amber"] { --tone: var(--amber); }
[data-tone="green"] { --tone: var(--green); }
[data-tone="red"] { --tone: var(--red); }
.dc-track > i[data-tone], .dc-legend i[data-tone], .dc-col-bars > i[data-tone] { background: var(--tone); }
.amt[data-tone], .dc-cmp-head b[data-tone], .dc-line b[data-tone] { color: var(--tone, inherit); }
.dc-line b[data-tone="ink"] { color: var(--ink); }
/* 색 의미(T1-b): 기성 = navy · 투입/지출 = amber · 손익 +/− = green/red · blue = 우천 전용. 글자색은 다크에서도 읽히도록 -ink */
.amt[data-tone="navy"] { color: var(--navy-ink); }
.kpi[data-tone="navy"] .kpi-value { color: var(--navy-ink); }
.kpi[data-tone="amber"] .kpi-value { color: var(--amber-ink); }

.dc-meter { margin-bottom: var(--sp-3); }
.dc-meter-top { display: flex; justify-content: space-between; gap: 8px; margin-bottom: 4px; font-size: var(--fs-sm); color: var(--ink-2); }
.dc-meter-top b { color: var(--ink); font-weight: var(--fw-extra); }
.dc-meter-top small { color: var(--mute); font-weight: var(--fw-semi); }
.dc-line { display: flex; justify-content: space-between; gap: 8px; padding: 6px 0 0; font-size: var(--fs-sm); color: var(--mute); }
.dc-line + .dc-line { padding-top: 4px; }
.dc-line b { color: var(--ink); font-weight: var(--fw-extra); }
.dc-meter + .dc-line { border-top: 1px solid var(--line-soft); }
.dc-warn { display: flex; align-items: flex-start; gap: 6px; margin-top: var(--sp-2); padding: 7px 10px; background: var(--red-soft); color: var(--red-ink); border-radius: var(--r-lg); font-size: var(--fs-xs); font-weight: var(--fw-semi); }
.dc-warn svg { flex: none; margin-top: 1px; }

.dc-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; margin: 0 0 var(--sp-2); font-size: var(--fs-xs); color: var(--mute); }
.dc-cols + .dc-legend { margin: var(--sp-2) 0 0; }
.dc-legend i { display: inline-block; width: 9px; height: 9px; margin-right: 4px; border-radius: 2px; vertical-align: -1px; }
.dc-cmp { margin-bottom: var(--sp-3); }
.dc-cmp:last-child { margin-bottom: 0; }
.dc-cmp-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--ink-2); }
.dc-cmp-row { display: grid; grid-template-columns: 30px minmax(0, 1fr) 92px; align-items: center; gap: 8px; margin-top: 3px; font-size: var(--fs-xs); color: var(--mute); }
.dc-cmp-row b { text-align: right; color: var(--ink); font-weight: var(--fw-bold); }

/* 최근 7일 막대 */
.dc-cols { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.dc-col { display: flex; flex-direction: column; align-items: center; gap: 3px; min-width: 0; }
.dc-col-v { height: 13px; font-size: 10px; color: var(--mute); font-weight: var(--fw-semi); white-space: nowrap; }
.dc-col-bars { display: flex; align-items: flex-end; justify-content: center; gap: 3px; width: 100%; height: 92px; border-bottom: 1px solid var(--line); }
.dc-col-bars > i { width: min(18px, 40%); border-radius: 3px 3px 0 0; min-height: 0; transition: height .3s; }
.dc-col-bars[data-n="2"] > i { width: min(11px, 38%); }
.dc-col-l { font-size: var(--fs-2xs); color: var(--mute); }
.dc-col.is-today .dc-col-l { color: var(--ink); font-weight: var(--fw-extra); }

.dc-prog { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-2); }
.dc-prog > b { font-size: 26px; font-weight: var(--fw-extra); letter-spacing: -.02em; }
.dc-prog > b small { margin-left: 2px; font-size: var(--fs-md); color: var(--mute); }
.dc-prog .dc-track { flex: 1; }

/* 월별 손익 표 */
.dcard .tbl tr.is-cur td { background: var(--navy-soft); }

/* 할 일 */
.dc-todo-form { display: flex; gap: 6px; }
.dc-todo-form .input { flex: 1; min-width: 0; }
.dc-todo-form .select { width: 92px; }
.dc-todo-filter { margin: var(--sp-2) 0; }
.dc-todo { display: flex; align-items: center; gap: 6px; padding: 5px 0; border-bottom: 1px solid var(--row-line); font-size: var(--fs-base); }
.dc-todo:last-child { border-bottom: 0; }
.dc-todo-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.dc-todo.is-done .dc-todo-text { opacity: .5; text-decoration: line-through; color: var(--mute); }
.dc-todo-prio { width: 34px; padding: 0 2px; border: 0; background: transparent; font-weight: var(--fw-extra); cursor: pointer; font-size: var(--fs-sm); color: var(--mute); }
.dc-todo-prio[data-p="1"] { color: var(--red); }
.dc-todo-prio[data-p="2"] { color: var(--amber-ink); }
.dc-todo-empty { padding: var(--sp-4); text-align: center; color: var(--mute); font-size: var(--fs-xs); }
.dc-todo input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--navy); cursor: pointer; flex: none; }

/* 날씨 · D-Day */
.dc-wx { display: flex; align-items: center; gap: var(--sp-3); }
.dc-wx-ico { font-size: 30px; line-height: 1; min-width: 34px; text-align: center; color: var(--mute); }
.dc-wx-main { flex: 1; min-width: 0; }
.dc-wx-t { font-size: var(--fs-xl); font-weight: var(--fw-extra); }
.dc-wx-t small { margin-left: 4px; font-size: var(--fs-xs); color: var(--mute); font-weight: var(--fw-semi); }
.dc-wx-d { font-size: var(--fs-sm); color: var(--mute); }
.dc-wx-more { font-size: var(--fs-xs); color: var(--blue); font-weight: var(--fw-bold); white-space: nowrap; }
.dc-wloc { margin-top: var(--sp-2); max-height: 300px; overflow-y: auto; }
.dc-wloc-msg { padding: 10px; text-align: center; color: var(--mute); font-size: var(--fs-sm); }
.dc-wloc-msg[data-tone="red"] { color: var(--red); }
.dc-wloc-item { display: block; width: 100%; padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--row-line); }
.dc-wloc-item:hover { background: var(--surface-2); }
.dc-wloc-item b { display: block; font-weight: var(--fw-bold); }
.dc-wloc-item small { color: var(--mute); font-size: var(--fs-xs); }
.dc-dday { display: flex; align-items: baseline; gap: var(--sp-3); width: 100%; text-align: left; padding: 2px 0; }
.dc-dday > b { font-size: 28px; font-weight: var(--fw-extra); letter-spacing: -.02em; color: var(--navy-ink); }
.dc-dday > span { color: var(--mute); font-size: var(--fs-sm); font-weight: var(--fw-semi); }
.dc-dday.is-empty > b { font-size: var(--fs-lg); color: var(--blue); }

/* 온보딩 */
.dc-onboard { padding: 12px 16px; border-left: 4px solid var(--navy); }
.dc-onboard-head { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: 4px; }
.dc-onboard-head span { color: var(--mute); font-size: var(--fs-xs); }
.dc-onboard-head .btn { margin-left: auto; }
.dc-step { display: flex; align-items: center; gap: 10px; padding: 5px 0; font-size: var(--fs-base); }
.dc-step-n { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 22px; height: 22px; border-radius: 50%; background: var(--gray-soft); border: 1px solid var(--line); color: var(--ink-2); font-size: var(--fs-sm); font-weight: var(--fw-bold); }
.dc-step.is-done .dc-step-n { background: var(--green); border-color: var(--green); color: var(--on-navy); }
.dc-step-l { flex: 1; min-width: 0; }
.dc-step.is-done .dc-step-l { color: var(--mute); text-decoration: line-through; }

/* ============================================================
   일보 부속 모달 · 배너 (R2) — 내역 선택 · 전일 복사 · 템플릿 · 작업내용 칩
   ============================================================ */
/* 내역서 항목 선택 */
.bq-tools { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-2); }
.bq-tools .input { flex: 1; min-width: 0; }
.bq-count { flex: none; font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--mute); }
.bq-list { display: flex; flex-direction: column; max-height: 56vh; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--r-lg); }
.bq-none { padding: 24px; text-align: center; color: var(--mute); font-size: var(--fs-sm); }
.bq-head { padding: 6px 10px; background: var(--navy-soft); color: var(--navy-ink); font-weight: var(--fw-bold); font-size: var(--fs-base); }
.bq-head small { font-weight: var(--fw-regular); color: var(--mute); }
.bq-head[data-lv="2"] { padding-left: 24px; background: var(--gray-soft); }
.bq-head[data-lv="3"] { padding-left: 38px; background: var(--surface-2); }
.bq-head[data-lv="4"] { padding-left: 52px; background: var(--surface-2); }
.bq-item { display: flex; align-items: center; gap: 10px; padding: 7px 10px 7px 14px; border-top: 1px solid var(--row-line); cursor: pointer; }
.bq-item:hover { background: var(--surface-2); }
.bq-item.is-on { background: var(--green-soft); }
.bq-item.is-locked { opacity: .55; cursor: not-allowed; }
.bq-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.bq-main b { font-weight: var(--fw-semi); }
.bq-main small { color: var(--mute); font-size: var(--fs-xs); }
.bq-unit { flex: none; width: 36px; color: var(--mute); font-size: var(--fs-sm); text-align: center; }
.bq-price { flex: none; min-width: 150px; text-align: right; color: var(--ink-2); font-size: var(--fs-sm); }
.bq-tag { margin-left: 4px; padding: 1px 5px; border-radius: var(--r-sm); background: var(--navy); color: var(--on-navy); font-size: var(--fs-2xs); font-style: normal; }
.bq-tag.is-lock { background: var(--gray); }

/* 전일 복사 */
.cp-weekbar { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); padding: 4px 0 var(--sp-2); }
.cp-weeklabel { font-weight: var(--fw-bold); }
.cp-weeklabel small { color: var(--mute); font-weight: var(--fw-regular); }
.cp-days { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; }
.cp-day { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); width: 100%; padding: 10px 14px; text-align: left; border-top: 1px solid var(--row-line); }
.cp-day:first-child { border-top: 0; }
.cp-day:not(:disabled):hover { background: var(--navy-soft); }
.cp-day:disabled { opacity: .42; cursor: default; }
.cp-date { font-weight: var(--fw-bold); }
.cp-date small { margin-left: 2px; font-weight: var(--fw-regular); color: var(--mute); }
.cp-day.is-sat .cp-date { color: var(--blue); }
.cp-day.is-sun .cp-date { color: var(--red); }
.cp-cur { margin-left: 8px; font-size: var(--fs-2xs); font-style: normal; font-weight: var(--fw-bold); color: var(--amber-ink); }
.cp-counts { color: var(--mute); font-size: var(--fs-sm); }
.cp-sec { border: 1px solid var(--line); border-radius: var(--r-lg); margin-bottom: var(--sp-2); overflow: hidden; }
.cp-sec-head { display: flex; align-items: center; gap: 8px; padding: 8px 12px; background: var(--surface-2); cursor: pointer; }
.cp-sec-head small { color: var(--mute); }
.cp-rows { display: flex; flex-direction: column; padding: 4px 8px 6px 28px; }
.cp-row { display: flex; align-items: center; gap: 8px; padding: 3px 4px; border-radius: var(--r-sm); color: var(--ink-2); font-size: var(--fs-sm); cursor: pointer; }
.cp-row:hover { background: var(--surface-2); }
.cp-foot-l { display: flex; gap: 6px; margin-right: auto; }

/* 일보 템플릿 */
.tpl-save { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2); padding: 10px 12px; margin-bottom: var(--sp-3); background: var(--surface-2); border-radius: var(--r-lg); }
.tpl-cur { flex: 1 1 180px; display: flex; flex-direction: column; min-width: 0; }
.tpl-cur small { color: var(--mute); font-size: var(--fs-xs); }
.tpl-save .input { flex: 1 1 180px; min-width: 0; }
.tpl-list { display: flex; flex-direction: column; gap: 6px; max-height: 46vh; overflow-y: auto; }
.tpl-item { display: flex; align-items: center; gap: 6px; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--r-lg); }
.tpl-info { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.tpl-info small { color: var(--mute); font-size: var(--fs-xs); }

/* 일보 배너 (날짜 바 아래) */
.daily-banners { display: flex; flex-direction: column; gap: var(--sp-2); }
.daily-banners:empty { display: none; }
.banner svg { flex: none; }
.banner .banner-msg { flex: 1; min-width: 0; }
.banner .banner-msg small { font-weight: var(--fw-regular); }
.banner-date { font-weight: var(--fw-extra); text-decoration: underline; color: inherit; padding: 0; }
/* 접히는 한 줄 배너 (T1-b): 요지 한 줄 + 버튼 1개 + ▸, 상세는 펼칠 때만 */
.banner.banner-fold { flex-direction: column; align-items: stretch; gap: 0; padding: 4px 8px 4px 14px; }
.banner-fold .banner-row { display: flex; align-items: center; gap: var(--sp-2); min-height: 44px; }
.banner-fold .banner-msg { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.banner-fold .banner-act { align-items: center; flex: none; }
.banner-toggle { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: var(--r-btn); color: inherit; }
.banner-toggle svg { transition: transform .15s ease; }
.banner-fold[data-open="1"] .banner-toggle svg { transform: rotate(90deg); }
.banner-detail { display: flex; flex-direction: column; gap: 6px; padding: 2px 0 10px; }
.banner-detail[hidden] { display: none; }
.banner-dates { display: flex; flex-wrap: wrap; gap: 6px 10px; }
.banner-detail-act { display: flex; gap: 6px; flex-wrap: wrap; }

/* 작업내용 — 내역서 항목 칩 패널 */
.wc-boq-panel { display: flex; flex-direction: column; gap: var(--sp-2); padding: 8px; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface-2); }
.wc-chips { display: flex; flex-wrap: wrap; gap: 6px; max-height: 160px; overflow-y: auto; }
.wc-chip { padding: 3px 9px; border: 1px solid var(--border-strong); border-radius: var(--r-pill); background: var(--card); color: var(--ink-2); font-size: var(--fs-sm); }
.wc-chip:hover { border-color: var(--blue); color: var(--blue); }
.wc-chip.is-on { background: var(--green-soft); border-color: var(--green); color: var(--green-ink); font-weight: var(--fw-semi); }
.wc-chip-none { color: var(--mute); font-size: var(--fs-sm); }
.wc-chip.wc-group { padding: 6px 12px; font-weight: var(--fw-semi); color: var(--navy); border-color: var(--navy); }
.wc-chip.wc-group small { margin-left: 4px; color: var(--mute); font-weight: normal; }
/* 일보 사진 — 항목 사진 창·맨 아래 사진 카드 */
.ph-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.ph-item { margin: 0; display: flex; flex-direction: column; gap: 4px; }
.ph-item img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--r-sm, 8px); border: 1px solid var(--border); cursor: pointer; }
.ph-item .ph-cap { width: 100%; }
.ph-ctx { padding: 6px 10px; border-radius: 8px; background: var(--green-soft); color: var(--green-ink); font-size: var(--fs-sm); font-weight: var(--fw-semi); margin-bottom: 8px; }
.wk-photo { padding: 0 6px; vertical-align: middle; }
.wk-photo-n { margin-left: 2px; font-size: var(--fs-sm); color: var(--mute); }
.wc-group-bar { flex: 0 0 100%; display: flex; align-items: center; gap: 8px; }
.wc-chip-sub { flex: 0 0 100%; margin-top: 4px; color: var(--mute); font-size: var(--fs-sm); font-weight: var(--fw-semi); }

/* ── 빠른 추가 시트 · 일보 도구 시트 그리드 (R3) — .qa-* ───────────────
   js/ui/quick-add.js(.qa-tile) 와 daily-mobile.js dmMoreSheet(.qa-grid > button) 가 함께 쓴다. 카테고리 색은 data-cat. */
.qa-sub { margin: 0 0 10px; font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--mute); }
.qa-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.qa-grid > button {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  min-height: 84px; padding: 10px 4px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-2xl);
  color: var(--ink); font-size: var(--fs-base); font-weight: var(--fw-bold);
}
.qa-grid > button:active { background: var(--navy-soft); border-color: var(--navy); }
.qa-grid > button > span:first-child { font-size: 22px; line-height: 1; }
.qa-ic {
  display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: 14px;
  background: var(--gray-soft); color: var(--ink-2);
}
.qa-tile[data-cat="eq"] .qa-ic { background: var(--navy-soft);  color: var(--navy-ink); }
.qa-tile[data-cat="lb"] .qa-ic { background: var(--amber-soft); color: var(--amber-ink); }
.qa-tile[data-cat="mt"] .qa-ic { background: var(--green-soft); color: var(--green-ink); }
.qa-tile[data-cat="ex"] .qa-ic { background: var(--gray-soft);  color: var(--gray-ink); }
.qa-tile[data-cat="os"] .qa-ic { background: var(--navy-soft);  color: var(--cat-os); }
.qa-tile[data-cat="wk"] .qa-ic { background: var(--gray-soft);  color: var(--ink); }
.qa-voice { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 8px 0 4px; text-align: center; color: var(--ink-2); }
.qa-voice-ic { display: grid; place-items: center; width: 64px; height: 64px; border-radius: 50%; background: var(--red-soft); color: var(--red); }
.qa-voice .btn { min-width: 160px; min-height: 52px; }

/* ============================================================
   월별집계 (S1) — 기간 바 · KPI 색 의미 · 항목별 기성 표 · 진행률 게이지
   색 의미: 기성 navy · 투입 amber · 손익 양수 green / 음수 red
   ============================================================ */
.sum-root { display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0; }
.sum-bar { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card); padding: 8px 12px; }
.sum-base { display: inline-flex; align-items: center; gap: 6px; }
.sum-base-l { color: var(--mute); font-size: var(--fs-xs); font-weight: var(--fw-semi); }
.sum-bar .db-date { width: 148px; min-height: 30px; padding: 3px 8px; }
.sum-range { margin-left: auto; color: var(--ink-2); font-size: var(--fs-sm); font-weight: var(--fw-semi); }
.sum-kpis .kpi { box-shadow: inset 3px 0 0 var(--line); }
.sum-kpis .kpi[data-tone="navy"]  { box-shadow: inset 3px 0 0 var(--navy); }
.sum-kpis .kpi[data-tone="amber"] { box-shadow: inset 3px 0 0 var(--amber); }
.sum-kpis .kpi[data-tone="green"] { box-shadow: inset 3px 0 0 var(--green); }
.sum-kpis .kpi[data-tone="red"]   { box-shadow: inset 3px 0 0 var(--red); }
.sum-kpis .kpi[data-tone="navy"] .kpi-value  { color: var(--navy-ink); }
.sum-kpis .kpi[data-tone="amber"] .kpi-value { color: var(--amber-ink); }
.sum-kpis .kpi-value.is-pos { color: var(--green-ink); }
.sum-kpis .kpi-value.is-neg { color: var(--red); }
.sum-sec .section-sub { margin-left: 2px; }
.sum-navy  { color: var(--navy-ink); }
.sum-amber { color: var(--amber-ink); }
.sum-pos   { color: var(--green-ink); font-weight: var(--fw-bold); }
.sum-neg   { color: var(--red); font-weight: var(--fw-bold); }
.sum-dow[data-dow="0"] { color: var(--red); }
.sum-dow[data-dow="6"] { color: var(--blue); }
.sum-boq td.sum-spec { color: var(--mute); }
.sum-boq td.sum-amt { color: var(--navy-ink); font-weight: var(--fw-semi); }
.sum-boq tr.is-child td { color: var(--ink-2); }
.sum-boq tr.is-child td.sum-name { padding-left: 24px; }
.sum-boq tr.is-child td.sum-amt { color: var(--mute); font-weight: var(--fw-regular, 400); }
.sum-prop { color: var(--mute); font-size: var(--fs-2xs); }
.sum-boq tr.sum-hd td { background: var(--navy-soft); font-weight: var(--fw-bold); color: var(--ink); }
.sum-boq tr.sum-hd[data-lv="1"] td:first-child { padding-left: 10px; }
.sum-boq tr.sum-hd[data-lv="2"] td:first-child { padding-left: 24px; }
.sum-boq tr.sum-hd[data-lv="3"] td:first-child { padding-left: 38px; }
.sum-boq tr.sum-hd[data-lv="2"] td { background: color-mix(in srgb, var(--navy-soft) 65%, transparent); }
.sum-boq tr.sum-hd[data-lv="3"] td { background: color-mix(in srgb, var(--navy-soft) 35%, transparent); }
.sum-boq tr.sum-hd small { color: var(--mute); font-weight: var(--fw-regular, 400); }
.sum-boq tr.sum-bundle td.sum-amt { color: var(--navy-ink); font-weight: var(--fw-extra); }
.sum-gauge { display: flex; align-items: center; gap: 8px; min-width: 110px; }
.sum-gauge-bar { flex: 1; height: 6px; border-radius: 6px; background: var(--gray-soft); overflow: hidden; }
.sum-gauge-bar i { display: block; height: 100%; background: var(--navy); border-radius: 6px; }
.sum-gauge.is-done .sum-gauge-bar i { background: var(--green); }
.sum-gauge-t { min-width: 44px; text-align: right; font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sum-gauge.is-done .sum-gauge-t { color: var(--green-ink); }
.tbl tr.is-click { cursor: pointer; }

/* ============================================================
   노무대장 · 근로자명단 · 급여 요율 모달 (S2)
   색 의미: 금액 amber(노무) · 실지급 green · 경고 amber/red
   ============================================================ */
.ls-root { display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0; }
.ls-bar .seg { flex: none; }
.ls-mstep { align-items: center; gap: 6px; }
.ls-mtools { gap: 6px; margin-left: auto; }
.ls-banners { display: flex; flex-direction: column; gap: var(--sp-2); }
.ls-banners:empty { display: none; }
.ls-tbl td.ls-in { padding: 3px 6px; }
.ls-tbl td.ls-in input.cell { min-width: 0; }
.ls-tbl .ls-nm { font-weight: var(--fw-extra); white-space: nowrap; }
.ls-tbl td.ls-amt, .ls-tbl .ls-amt { color: var(--amber-ink); font-weight: var(--fw-semi); }
.ls-tbl td.ls-strong { font-weight: var(--fw-extra); }
.ls-tbl td.ls-ded.is-muted, .ls-dlist b.is-muted { color: var(--mute); opacity: .6; }
.ls-tbl td[data-dk="net"] { color: var(--green-ink); }
.ls-warn { display: inline-flex; vertical-align: middle; color: var(--amber-ink); }
.ls-warn[hidden] { display: none; }
.sign-chip {
  display: inline-flex; align-items: center; gap: 4px;
  min-height: 24px; padding: 2px 8px;
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: var(--card); color: var(--mute);
  font-size: var(--fs-xs); font-weight: var(--fw-bold); cursor: pointer;
}
.sign-chip:hover { border-color: var(--navy); color: var(--navy-ink); }
.sign-chip.is-signed { background: var(--green-soft); border-color: transparent; color: var(--green-ink); }
.sign-chip img { height: 18px; max-width: 48px; object-fit: contain; background: #fff; border-radius: 3px; }
.wl-add .input { flex: 0 1 220px; }
.wl-tbl td input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--navy); cursor: pointer; }
/* 급여 요율 관리 모달 — 머리글·푸터(미리보기 + 버튼)는 고정, 본문만 스크롤 (모바일에서 푸터가 입력칸을 가리지 않게) */
.prm-modal .modal { overflow: hidden; }
.prm-modal .modal-body { overflow-y: auto; overscroll-behavior: contain; }
.prm-modal .modal-foot { align-items: center; }
.prm-preview { flex: 1 1 100%; font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--navy-ink); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.prm-preview[data-tone="err"] { color: var(--red); }
.prm-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: var(--sp-3); }
.prm-src { padding: 8px 10px; margin-bottom: var(--sp-2); border-radius: var(--r-md); background: var(--surface-2); color: var(--mute); font-size: var(--fs-xs); line-height: 1.5; }
.prm-src[data-tone="warn"] { background: var(--amber-soft); color: var(--amber-ink); }
.prm-law { font-weight: var(--fw-bold); }
.prm-meta { display: flex; flex-direction: column; gap: 2px; margin-bottom: var(--sp-2); }
.prm-tools { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: var(--sp-3); }
.prm-set { border: 1px solid var(--line); border-radius: var(--r-md); padding: 8px 12px 10px; margin: 0 0 var(--sp-2); min-width: 0; }
.prm-set legend { padding: 0 6px; font-weight: var(--fw-extra); font-size: var(--fs-sm); }
.prm-hint { color: var(--mute); font-size: var(--fs-xs); margin-bottom: 2px; }
.prm-group + .prm-group { margin-top: var(--sp-2); }
.prm-gt { margin-top: 6px; font-weight: var(--fw-bold); font-size: var(--fs-xs); color: var(--navy-ink); }
.prm-item { margin-top: 6px; }
.prm-row { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); }
.prm-lab { flex: 0 0 150px; min-width: 0; }
.prm-row .input { flex: 0 1 130px; min-width: 0; text-align: right; font-variant-numeric: tabular-nums; }
.prm-item.is-wide .prm-row .input { flex: 1 1 auto; text-align: left; }
.prm-row input[type="date"] { text-align: left; }
.prm-row input[type="checkbox"] { width: 18px; height: 18px; accent-color: var(--navy); }
.prm-derived { flex: 0 1 130px; text-align: right; font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; }
.prm-unit { min-width: 54px; color: var(--mute); font-size: var(--fs-xs); }
.prm-note { margin: 2px 0 0 158px; color: var(--mute); font-size: var(--fs-xs); line-height: 1.4; }
.prm-err { margin: 2px 0 0 158px; color: var(--red); font-size: var(--fs-xs); font-weight: var(--fw-bold); }
.prm-err[hidden] { display: none; }
.prm-item.is-diff .input { border-color: var(--amber); background: var(--amber-soft); }
.prm-item.is-err .input { border-color: var(--red); background: var(--red-soft); }
.prm-hist { display: flex; flex-direction: column; gap: var(--sp-2); }
.prm-hrow { border: 1px solid var(--line); border-radius: var(--r-md); padding: 8px 12px; }
.prm-hat { font-weight: var(--fw-extra); font-size: var(--fs-sm); margin-bottom: 4px; }
.prm-hrow ul { margin: 0; padding-left: 18px; font-size: var(--fs-sm); line-height: 1.6; }
.prm-hpath { color: var(--mute); font-size: var(--fs-2xs); }
.ls-reasons { display: flex; flex-direction: column; gap: 2px; padding: 4px 0 2px; color: var(--amber-ink); font-size: var(--fs-xs); }
.ls-reasons[hidden] { display: none; }
@media (max-width: 767px) {
  .prm-row { flex-wrap: wrap; row-gap: 2px; }
  .prm-lab { flex: 1 1 100%; font-weight: var(--fw-bold); }
  .prm-row .input, .prm-derived { flex: 1 1 120px; font-size: 16px; }
  .prm-note, .prm-err { margin-left: 0; }
}
.ls-tbl td { white-space: nowrap; }

/* ── S3 거래처현황 · 청구서 · 월말 점검 · 이력조회 ───────────────── */
.vs-root, .hs-root { display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0; }
.vs-search { position: relative; display: inline-flex; align-items: center; gap: 6px; flex: 0 1 240px; min-width: 150px; color: var(--mute); }
.vs-search .input { min-height: 30px; padding: 3px 8px; }
.vs-chips, .hs-types, .hs-presets { display: flex; flex-wrap: wrap; gap: 6px; }
.vs-bar .sum-range { margin-left: auto; }
.vs-mtools, .hs-mtools { gap: 6px; flex-wrap: wrap; }
.vs-empty-act { display: flex; justify-content: center; padding: 0 0 var(--sp-4); }
.vs-tbl td.vs-name b { font-weight: var(--fw-extra); }
.vs-tbl td.vs-name small, .vs-hint { display: block; color: var(--mute); font-size: var(--fs-2xs); font-weight: var(--fw-regular, 400); }
.vs-tbl td.vs-role { min-width: 140px; }
.vs-tbl td.vs-role input.cell { min-width: 120px; font-size: var(--fs-xs); }
.vs-tbl td.vs-bank { color: var(--mute); font-size: var(--fs-xs); white-space: nowrap; }
.vs-tbl td.vs-cur { font-weight: var(--fw-extra); color: var(--amber-ink); }
.vs-tbl td.vs-acc { color: var(--green-ink); }
.vs-tbl td.vs-prev { color: var(--ink-2); }
.vs-tbl tr.vs-grp td { background: var(--gray-soft); font-weight: var(--fw-bold); }
.vs-tbl tr.vs-unreg td { background: color-mix(in srgb, var(--amber-soft) 55%, transparent); }
.vs-tbl tr.vs-unreg-hd td { background: var(--amber-soft); }
.vs-tbl tr.vs-total td { font-weight: var(--fw-extra); border-top: 2px solid var(--line); background: var(--card); }
.vs-acts { white-space: nowrap; text-align: center; }
.vs-acts .btn + .btn { margin-left: 4px; }
button.vs-biok { border: 0; cursor: pointer; font-family: inherit; }
button.vs-biok.is-empty { opacity: .65; }
.vs-pick { display: flex; flex-wrap: wrap; gap: 6px; }
.vs-pick-custom { display: flex; gap: 8px; margin-top: var(--sp-3); }
.vr-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); }
.vr-form .vr-cat { grid-column: 1 / -1; }
.vr-form .vr-memo { grid-column: 1 / -1; }
.vr-form em { color: var(--red); font-style: normal; }
.ha-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); }

/* 청구서 */
.claim-wrap { display: flex; flex-direction: column; gap: var(--sp-3); }
.claim-doc { background: var(--card); color: var(--ink); border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--sp-5); font-variant-numeric: tabular-nums; }
.claim-title { text-align: center; font-size: 22px; font-weight: var(--fw-extra); letter-spacing: 10px; border-bottom: 3px double var(--ink); padding-bottom: 10px; }
.claim-date { text-align: right; color: var(--mute); font-size: var(--fs-xs); margin: 4px 0 var(--sp-3); }
.claim-meta { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); margin-bottom: var(--sp-3); }
.claim-meta th, .claim-meta td { border: 1px solid var(--border-strong); padding: 6px 10px; }
.claim-meta th { background: var(--gray-soft); width: 84px; text-align: center; }
.claim-tbl td, .claim-tbl th { border: 1px solid var(--line); }
.claim-cat td { background: var(--gray-soft); font-weight: var(--fw-extra); }
.claim-vendor td { background: color-mix(in srgb, var(--gray-soft) 55%, transparent); font-weight: var(--fw-bold); }
.claim-vendor td:first-child { padding-left: 20px; }
.claim-row td.claim-name { padding-left: 24px; }
.claim-row td.claim-item { color: var(--mute); }
.claim-note { font-weight: var(--fw-regular, 400); color: var(--mute); font-size: var(--fs-2xs); }
.claim-tools { white-space: nowrap; text-align: center; width: 92px; }
.claim-tools .btn + .btn { margin-left: 2px; }
.claim-row.is-excluded td:not(.claim-tools) { opacity: .4; text-decoration: line-through; }
.claim-tbl tfoot td { font-weight: var(--fw-extra); border-top: 2px solid var(--ink); background: var(--card); }
.claim-final { display: flex; justify-content: space-between; align-items: center; border: 1.5px solid var(--ink); padding: 10px 16px; margin-top: var(--sp-3); }
.claim-final span { font-weight: var(--fw-extra); letter-spacing: 2px; }
.claim-final-amount { font-size: 20px; color: var(--red); }
.claim-vcard { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border: 1px solid var(--border-strong); margin-bottom: var(--sp-3); }
.claim-vc { display: flex; flex-direction: column; gap: 1px; padding: 6px 10px; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); min-width: 0; }
.claim-vc:nth-child(4n) { border-right: 0; }
.claim-vc span { color: var(--mute); font-size: var(--fs-2xs); }
.claim-vc b { font-size: var(--fs-sm); font-weight: var(--fw-bold); overflow-wrap: anywhere; }
.claim-vc-msg { grid-column: 1 / -1; padding: 6px 10px; font-size: var(--fs-xs); color: var(--red); background: var(--gray-soft); }
/* 청구서 모달 — 머리글(제목 + 요약 복사·인쇄 + ×)은 고정, 표는 본문 안에서만 스크롤한다.
   (예전엔 .modal-body가 min-height:0 + overflow:visible 이라 표가 길면 본문 밖으로 넘쳐 아래 푸터 버튼 위에 겹쳐 '표 중간에 버튼이 뜬' 것처럼 보였다) */
.claim-modal .modal { overflow: hidden; }
.claim-modal .modal-body { overflow-y: auto; overscroll-behavior: contain; }
.claim-modal .modal-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.modal-head-actions { display: flex; align-items: center; gap: var(--sp-2); flex: none; }
.claim-modal .modal-body { background: var(--bg); }
/* 청구서 — 월 이동·작성일 줄 / 근거(수량×단가) / 계좌 경고 / 숨김 칩 / 날짜 칩 */
.claim-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-4); }
.claim-ym-nav { display: inline-flex; align-items: center; gap: var(--sp-2); }
.claim-ym { min-width: 64px; text-align: center; font-weight: var(--fw-extra); }
.claim-date-in { display: inline-flex; align-items: center; gap: 6px; color: var(--mute); font-size: var(--fs-xs); }
.claim-date-in .input { min-height: 30px; padding: 3px 8px; width: auto; }
.claim-basis { color: var(--mute); font-size: var(--fs-2xs); font-variant-numeric: tabular-nums; }
.claim-warn { display: inline-block; margin-left: 6px; padding: 0 6px; border-radius: var(--r-chip, 4px); background: var(--red-soft); color: var(--red-ink); font-size: var(--fs-2xs); font-weight: var(--fw-bold); vertical-align: middle; }
.claim-datechips { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; font-size: var(--fs-xs); color: var(--mute); }
.claim-etc-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.claim-tools { width: auto; min-width: 92px; }
/* ⋯ 메뉴 (청구서 머리·모바일 카드·거래처현황 공용) */
.claim-menu { position: relative; display: inline-block; }
.claim-menu > summary { list-style: none; cursor: pointer; min-width: var(--hit, 44px); min-height: var(--hit, 44px); justify-content: center; font-weight: var(--fw-extra); }
.claim-menu > summary::-webkit-details-marker { display: none; }
.claim-menu-pop { position: absolute; right: 0; top: calc(100% + 2px); z-index: 20; display: flex; flex-direction: column; gap: 4px; min-width: 150px; padding: 6px; background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md); box-shadow: 0 6px 20px rgba(16,24,40,.14); }
.claim-menu-pop .btn { justify-content: flex-start; min-height: var(--hit, 44px); white-space: nowrap; }
/* 모바일 청구서 카드 */
.claim-cards, .vs-cards { display: flex; flex-direction: column; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.claim-chead, .vs-chead { display: flex; justify-content: space-between; align-items: center; margin-top: var(--sp-2); padding: 4px 2px; font-size: var(--fs-sm); }
.claim-card, .vs-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card, 16px); padding: var(--sp-3); display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.vs-card[data-hidden="1"] { opacity: .6; }
.claim-card-top, .vs-card-top { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-2); }
.claim-card-name, .vs-card-name { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; }
.claim-card-name b, .vs-card-name b { font-weight: var(--fw-extra); overflow-wrap: anywhere; }
.claim-card-name, .vs-card-name { flex: 1 1 0; }
.claim-card-name > *, .vs-card-name > * { min-width: 0; max-width: 100%; }
.claim-card-name .badge, .claim-card-name .chip, .vs-card-name .badge, .vs-card-name .chip { white-space: normal; overflow-wrap: anywhere; }
.claim-card-top > :last-child, .vs-card-top > :last-child { flex: 0 0 auto; }
.claim-card, .vs-card { overflow: hidden; }
.claim-card-note, .vs-card-sub { color: var(--mute); font-size: var(--fs-xs); overflow-wrap: anywhere; }
.claim-card-amts, .vs-card-amts, .claim-mtotal { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; font-variant-numeric: tabular-nums; }
.claim-card-amts span, .vs-card-amts span, .claim-mtotal span { display: flex; flex-direction: column; min-width: 0; }
.claim-card-amts i, .vs-card-amts i, .claim-mtotal i { font-style: normal; color: var(--mute); font-size: var(--fs-2xs); }
.claim-card-amts b, .vs-card-amts b, .claim-mtotal b { font-size: var(--fs-sm); font-weight: var(--fw-bold); text-align: right; }
.claim-card-amts span:nth-child(2) b, .vs-card-amts span:nth-child(2) b { color: var(--amber-ink); font-weight: var(--fw-extra); }
.claim-mtotal { grid-template-columns: auto repeat(3, minmax(0, 1fr)); align-items: end; padding: var(--sp-2) 2px; border-top: 2px solid var(--ink); font-weight: var(--fw-extra); }
.claim-card-items > summary { cursor: pointer; color: var(--mute); font-size: var(--fs-xs); padding: 4px 0; }
.claim-citems { display: flex; flex-direction: column; }
.claim-citem { display: flex; align-items: center; gap: var(--sp-2); padding: 6px 0; border-top: 1px solid var(--line); }
.claim-citem-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.claim-citem-main small { color: var(--mute); font-size: var(--fs-2xs); overflow-wrap: anywhere; }
.claim-citem.is-excluded > :not(button) { opacity: .4; text-decoration: line-through; }
.vs-ptools { display: inline-flex; gap: 4px; }

/* 월말 점검 */
.mc-list { display: flex; flex-direction: column; }
.mc-item { display: flex; align-items: flex-start; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.mc-ico { flex: none; width: 22px; height: 22px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: var(--amber-soft); color: var(--amber-ink); }
.mc-item[data-ok="1"] .mc-ico { background: var(--green-soft); color: var(--green-ink); }
.mc-main { flex: 1; min-width: 0; }
.mc-title { font-weight: var(--fw-bold); font-size: var(--fs-base); }
.mc-count { margin-left: 4px; padding: 1px 7px; border-radius: var(--r-pill); background: var(--amber-soft); color: var(--amber-ink); font-size: var(--fs-2xs); }
.mc-detail { color: var(--mute); font-size: var(--fs-xs); margin-top: 2px; word-break: break-all; }
.mc-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.mc-foot-note { align-self: center; color: var(--mute); font-size: var(--fs-xs); }

/* 이력조회 */
.hs-bar, .hs-filters { align-items: center; }
.hs-filters { gap: var(--sp-2) var(--sp-3); }
.hs-search { position: relative; display: inline-flex; align-items: center; gap: 8px; flex: 1 1 260px; min-width: 200px; }
.hs-search .vs-search { flex: 1 1 auto; }
.hs-opts { position: absolute; z-index: 40; top: calc(100% + 4px); left: 0; width: min(100%, 360px); max-height: 260px; overflow: auto; background: var(--card); border: 1px solid var(--line); border-radius: var(--r-md); box-shadow: 0 6px 20px rgba(16,24,40,.12); padding: 4px; }
.hs-opts[hidden] { display: none; }
.hs-opt { display: block; width: 100%; text-align: left; padding: 6px 10px; border-radius: var(--r-md); font-size: var(--fs-sm); }
.hs-opt:hover { background: var(--navy-soft); }
.hs-opt-empty { padding: 8px 10px; color: var(--mute); font-size: var(--fs-xs); }
.hs-sel { display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px 2px 10px; border-radius: var(--r-pill); background: var(--navy-soft); color: var(--navy-ink); font-size: var(--fs-xs); font-weight: var(--fw-bold); white-space: nowrap; }
.hs-sel-x { display: inline-flex; padding: 3px; border-radius: 50%; color: inherit; }
.hs-range, .hs-amtr { display: inline-flex; align-items: center; gap: 6px; color: var(--mute); }
.hs-range .input { width: 140px; min-height: 30px; padding: 3px 8px; }
.hs-amtr .input { width: 110px; min-height: 30px; padding: 3px 8px; }
.hs-kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.hs-kpis .kpi[data-tone="navy"]  { box-shadow: inset 3px 0 0 var(--navy); }
.hs-kpis .kpi[data-tone="amber"] { box-shadow: inset 3px 0 0 var(--amber); }
.hs-kpis .kpi[data-tone="green"] { box-shadow: inset 3px 0 0 var(--green); }
.hs-kpis .kpi-value b { font-weight: inherit; }
.hs-kpis .hs-k-note { display: block; margin-top: 2px; color: var(--mute); font-size: var(--fs-2xs); }
.hs-tbl .hs-date { color: var(--navy-ink); text-decoration: underline; font-size: inherit; cursor: pointer; padding: 0; }
.hs-tbl .hs-chdate { margin-left: 4px; vertical-align: middle; }
.hs-tbl td { white-space: nowrap; }
.hs-tbl .hs-nm { font-weight: var(--fw-extra); }
.hs-tbl .hs-spec { color: var(--mute); font-size: var(--fs-xs); }
.hs-tbl input.cell { min-width: 0; }
.hs-tbl .hs-out { display: block; color: var(--mute); font-size: var(--fs-2xs); }
.hs-tbl .hs-amt.is-out { color: var(--mute); }
.hs-tbl td:last-child { white-space: nowrap; text-align: center; }
.hs-tbl td:last-child .btn + .btn { margin-left: 4px; }
.hs-foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); padding: 10px 14px; border-top: 1px solid var(--line); background: var(--surface-2); font-size: var(--fs-sm); }
.hs-more-t { color: var(--mute); }
.hs-sumline { margin-left: auto; font-weight: var(--fw-bold); }
.hs-sumline .amt { color: var(--green-ink); }

/* ── M1 자재 — 재고 현황 · 입반출 이력 · 등록 모달 ───────────────── */
.mt-root { display: flex; flex-direction: column; gap: var(--sp-3); min-width: 0; }
.mt-tbl td { white-space: nowrap; }
.mt-tbl .mt-row { cursor: pointer; }
.mt-tbl .mt-row.is-unreg { opacity: .85; }
.mt-tbl input.cell { min-width: 0; }
.mt-tbl td:last-child { white-space: nowrap; text-align: center; }
.mt-tbl td:last-child .btn + .btn { margin-left: 4px; }
.mt-in { color: var(--green-ink); }
.mt-out { color: var(--amber-ink); }
.mt-stock { font-weight: var(--fw-extra); color: var(--green-ink); }
.mt-stock.is-neg { color: var(--red); }
.mt-stock.is-zero { color: var(--mute); }
.mt-warn { white-space: nowrap; }
.mt-warn[data-tone="gray"] { background: var(--gray-soft); color: var(--gray-ink); }
/* 이력 필터 · 행 추가 폼 */
.mh-bar { margin: var(--sp-3) 0 var(--sp-2); }
.mh-search { flex: 1 1 220px; max-width: 360px; }
.mh-add { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-2) var(--sp-3); padding: var(--sp-2) 0 var(--sp-3); }
.mh-add .field { min-width: 0; }
.mh-add .input, .mh-add .select { min-height: 32px; padding: 4px 8px; }
.mh-add [data-field="ma-date"] { width: 132px; }
.mh-add [data-field="ma-qty"] { width: 92px; }
.mh-add-spec { flex: 1 1 240px; }
.mh-add-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.mh-add-chips .input { width: 150px; }
.mh-tbl .mh-amtwrap { display: inline-block; text-align: right; }
.mh-tbl .item-tag { display: flex; }
/* 자재명·규격 선택 태그 (uiMatPicker를 여는 칸) */
.mt-tag {
  display: flex; align-items: center; min-height: 28px; padding: 3px 8px;
  border: 1px solid transparent; border-radius: var(--r-md);
  background: var(--green-soft); color: var(--green-ink);
  font-size: var(--fs-tbl); font-weight: var(--fw-semi);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;
}
.mt-tag:hover { border-color: var(--border-strong); }
.mt-tag:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.mt-tag.empty { background: transparent; border: 1px dashed var(--line); color: var(--mute); font-weight: var(--fw-regular); }
.field > .mt-tag { min-height: 32px; font-weight: var(--fw-semi); }
/* 선택창 */
.mp-q { width: 100%; margin-bottom: var(--sp-2); }
.mp-list { display: flex; flex-direction: column; gap: 2px; max-height: 320px; overflow: auto; }
.mp-item { display: block; width: 100%; text-align: left; padding: 8px 10px; border-radius: var(--r-md); font-size: var(--fs-sm); color: var(--ink); }
.mp-item:hover { background: var(--navy-soft); }
.mp-item.is-cur { background: var(--green-soft); color: var(--green-ink); font-weight: var(--fw-bold); }
.mp-item.is-clear { color: var(--mute); }
.mp-item.is-add { color: var(--blue-ink); font-weight: var(--fw-bold); }
.mp-empty { padding: var(--sp-3); color: var(--mute); font-size: var(--fs-xs); }
/* 등록 모달 */
#matRegModal .modal-body { display: flex; flex-direction: column; gap: var(--sp-3); }
#matRegModal .field small { font-weight: var(--fw-regular, 400); }
.maf-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.maf-tabs:empty { display: none; }
.maf-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.maf-wide { grid-column: 1 / -1; }
.maf-check { display: flex; align-items: center; gap: var(--sp-2); min-height: var(--hit, 36px); font-weight: var(--fw-regular, 400); }
.maf-check input { width: 18px; height: 18px; }
/* 자재 재고현황 — 구분 필터·잔여수량 */
.mt-supply-bar { padding: var(--sp-2) var(--sp-3); }
.mt-remain.is-neg { color: var(--red); font-weight: 600; }
.mt-remain.is-zero { color: var(--mute); }
/* 자재 재고현황 — 같은 이름·다른 규격 묶음(접기/펼치기) */
.mt-tbl tr[hidden], .mt-cards .mt-card[hidden] { display: none; }
.mt-tbl .mt-grp-row { cursor: pointer; background: var(--bg-soft, var(--bg)); }
.mt-tbl .mt-grp-row:hover { background: var(--navy-soft); }
.mt-tbl .mt-grp-row td { font-weight: 600; }
.mt-caret { display: inline-block; width: 1em; color: var(--mute); }
.mt-grp-n { margin-left: var(--sp-1); font-size: var(--fs-xs); font-weight: var(--fw-regular, 400); color: var(--mute); }
.mt-child-ind { margin-left: var(--sp-3); color: var(--mute); }
.mt-grp-tools { margin-left: auto; display: inline-flex; gap: var(--sp-2); }
.mt-grp-card { cursor: pointer; }
.mt-cards .mt-card.is-child { margin-left: var(--sp-3); }
/* 입출고 동시 짝 행 — 일보 자재 표에서 왼쪽에 가는 선으로 표시 */
tr.is-pair > td:first-child { box-shadow: inset 3px 0 0 var(--navy-2, var(--navy)); }

/* ── 내역서 (M2) — js/ui/boq.js ───────────────────────── */
.bq-root { display: flex; flex-direction: column; gap: var(--sp-3); }
.bq-tbl { min-width: 1000px; }
.bq-tbl th { padding: 7px 4px; }
.bq-tbl td { padding: 4px 4px; }
.bq-tbl input[type=number] { -moz-appearance: textfield; appearance: textfield; }
.bq-tbl input[type=number]::-webkit-inner-spin-button, .bq-tbl input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.bq-no { white-space: nowrap; }
.bq-grip { display: inline-flex; align-items: center; gap: 2px; padding: 4px 3px; border-radius: var(--r-sm); color: var(--mute); cursor: grab; user-select: none; touch-action: none; }
.bq-grip:hover { color: var(--ink); background: var(--gray-soft); }
.bq-grip i { min-width: 18px; text-align: right; font-style: normal; font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.bq-tbl td.bq-name { min-width: 180px; }
.bq-leaf td.bq-name { padding-left: 24px; }
.bq-tbl input.cell.c { text-align: center; }
.bq-tbl select.cell { padding: 3px 0 3px 2px; min-width: 46px; }
.bq-dash { color: var(--mute); }
/* 헤더 행 = 레벨별 배너 (S1 .sum-hd와 같은 면) */
.bq-tbl tbody tr.bq-hd td { background: var(--navy-soft); font-weight: var(--fw-bold); }
.bq-tbl tbody tr.bq-hd[data-lv="2"] td { background: color-mix(in srgb, var(--navy-soft) 65%, transparent); }
.bq-tbl tbody tr.bq-hd[data-lv="3"] td { background: color-mix(in srgb, var(--navy-soft) 35%, transparent); }
.bq-hd[data-lv="1"] td.bq-name { padding-left: 6px; }
.bq-hd[data-lv="2"] td.bq-name { padding-left: 20px; }
.bq-hd[data-lv="3"] td.bq-name { padding-left: 34px; }
.bq-hd input.cell { font-weight: var(--fw-bold); }
.bq-hd td.bq-sub { color: var(--green-ink); }
.bq-tbl td.bq-bundle { white-space: normal; font-size: var(--fs-xs); font-weight: var(--fw-regular, 400); }
.bq-bundle .btn { margin-top: 3px; }
.bq-chk { display: inline-flex; align-items: center; gap: 4px; cursor: pointer; color: var(--ink-2); white-space: nowrap; }
.bq-tbl tbody tr.is-last td { box-shadow: inset 0 1px 0 var(--blue), inset 0 -1px 0 var(--blue); }
.bq-tbl tbody tr.is-dragging td { opacity: .4; }
.bq-tbl tbody tr.bq-drop-before td { box-shadow: inset 0 2px 0 var(--blue); }
.bq-tbl tbody tr.bq-drop-after td { box-shadow: inset 0 -2px 0 var(--blue); }
.bq-tbl tfoot td { padding: 8px 6px; }
.bq-ghost { position: fixed; z-index: var(--z-modal); pointer-events: none; max-width: 320px; padding: 6px 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; background: var(--card); border: 1px solid var(--blue); border-radius: var(--r-md); box-shadow: var(--sh-modal); font-size: var(--fs-sm); font-weight: var(--fw-bold); opacity: .9; }
.bq-foot { display: flex; gap: 6px; padding: var(--sp-2) var(--sp-3); border-top: 1px solid var(--line); }
/* 게이지 — 100% 초과는 amber + 초과 표시 */
.bq-gauge { min-width: 92px; }
.sum-gauge.is-over .sum-gauge-bar i { background: var(--amber); }
.sum-gauge.is-over .sum-gauge-t { color: var(--amber-ink); }
.bq-over { text-align: right; font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--amber-ink); }
/* 모달 */
#boqAddModal .modal-body { display: flex; flex-direction: column; gap: var(--sp-3); }
.baf-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--sp-3); }
.bq-imp-lead { margin-bottom: var(--sp-3); color: var(--ink-2); line-height: 1.7; }
.bq-imp-lead small { color: var(--mute); font-size: var(--fs-xs); }
.bq-drop { display: flex; flex-direction: column; align-items: center; gap: 6px; width: 100%; padding: 28px 16px; border: 2px dashed var(--line); border-radius: var(--r-xl); color: var(--ink-2); cursor: pointer; }
.bq-drop:hover, .bq-drop:focus-visible { border-color: var(--blue); background: var(--blue-soft); }
.bq-drop small { color: var(--mute); font-size: var(--fs-xs); }
.bq-imp-sec { margin-bottom: var(--sp-3); }
.bq-imp-lbl { margin-bottom: 6px; color: var(--mute); font-size: var(--fs-sm); font-weight: var(--fw-bold); }
.bq-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.bq-tab { padding: 4px 12px; border: 1px solid transparent; border-radius: var(--r-chip); background: var(--navy-soft); color: var(--navy-ink); font-size: var(--fs-sm); font-weight: var(--fw-semi); cursor: pointer; }
.bq-tab.empty { background: transparent; border: 1px dashed var(--line); color: var(--mute); font-weight: var(--fw-regular, 400); }
.bq-map { padding: var(--sp-3); background: var(--surface-2); border-radius: var(--r-lg); }
.bq-map-grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; }
.bq-map-grid > div > div { margin-bottom: 3px; color: var(--ink-2); font-size: var(--fs-xs); }
.bq-map-grid select { width: 100%; min-height: 28px; padding: 3px 6px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--card); font-size: var(--fs-xs); }
.bq-imp-scroll { max-height: 340px; overflow: auto; border: 1px solid var(--line); border-radius: var(--r-lg); }
.bq-imp-tbl td, .bq-imp-tbl th { font-size: var(--fs-xs); white-space: nowrap; }
.bq-imp-tbl td { max-width: 200px; overflow: hidden; text-overflow: ellipsis; }
.bq-imp-info { margin-top: var(--sp-2); color: var(--ink-2); font-size: var(--fs-sm); }

/* ── M3 설정 화면 (js/ui/settings.js) — 마스터 4열 · 도구 목록 · 전체 메뉴 그룹 ── */
.mst-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-3); align-items: start; }
.mst-card .section-head { min-height: 40px; }
.mst-list { max-height: 60vh; overflow: auto; }
.mst-row { display: flex; align-items: center; gap: var(--sp-2); padding: 7px 12px; border-bottom: 1px solid var(--line); min-height: 40px; }
.mst-row:last-child { border-bottom: 0; }
.mst-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.mst-name { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mst-sub { font-size: var(--fs-xs); color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mst-biok { flex-shrink: 0; min-width: 64px; min-height: 26px; background: none; border: 0; padding: 0; cursor: pointer; }
.mst-biok-empty { display: inline-block; padding: 2px 8px; border: 1px dashed var(--line); border-radius: var(--r-chip); color: var(--mute); font-size: var(--fs-xs); }
.mst-del { flex-shrink: 0; }
.mst-biok-name { margin: 0 0 var(--sp-2); font-size: var(--fs-sm); color: var(--mute); }
.mst-biok-grid { display: flex; flex-wrap: wrap; gap: 6px; }
.mst-biok-custom { margin-top: var(--sp-3); }

.tools-card .tool-row { display: flex; align-items: center; gap: var(--sp-3); padding: 10px 14px; border-bottom: 1px solid var(--line); }
.tools-card .tool-row:last-child { border-bottom: 0; }
.tool-ico { width: 32px; height: 32px; flex-shrink: 0; display: grid; place-items: center; border-radius: var(--r-md); background: var(--navy-soft); color: var(--navy-ink); }
.tool-txt { flex: 1; min-width: 0; }
.tool-title { font-size: var(--fs-base); font-weight: var(--fw-semi); color: var(--ink); }
.tool-desc { font-size: var(--fs-xs); color: var(--mute); }

.more-root { display: flex; flex-direction: column; gap: var(--sp-3); }
.more-list { display: flex; flex-direction: column; }
.more-item { display: flex; align-items: center; gap: var(--sp-3); min-height: 44px; padding: 0 14px; border: 0; border-bottom: 1px solid var(--line); background: none; color: var(--ink); font-size: var(--fs-md); text-align: left; width: 100%; cursor: pointer; }
.more-item:last-child { border-bottom: 0; }
.more-label { flex: 1; }

@media (max-width: 1100px) and (min-width: 768px) {
  .mst-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 767px) {
  .mst-grid { grid-template-columns: minmax(0, 1fr); }
  .mst-list { max-height: none; }
}

/* ============================================================
   T1 — 옛 JS가 문자열로 만드는 동적 모달 통일 (옛 파일은 수정하지 않고 id 선택자로 붙인다)
   P = .modal 루트에 직접 쌓고 머리글 행만 가진 모달 (여백·구분선을 여기서 준다)
   C = 머리글·본문에 이미 인라인 padding이 있는 모달 (글자·닫기 버튼만 통일)
   새 옛 모달이 추가되면 아래 :is() 목록에 id를 더한다. 인라인 style(폭·max-height)은 !important로만 덮는다.
   ============================================================ */
:is(#photoCleanupModal, #signModal, #safetyModal, #claimLogModal, #equipReportModal, #priceHistModal,
    #siteCompareModal, #siteCopyModal, #integrityModal, #companyModal, #errLogModal, #shortcutHelpModal) > .modal {
  padding: var(--sp-4);
  gap: var(--sp-3);
}
:is(#photoCleanupModal, #signModal, #safetyModal, #claimLogModal, #equipReportModal, #priceHistModal,
    #siteCompareModal, #siteCopyModal, #integrityModal, #companyModal, #errLogModal, #shortcutHelpModal) > .modal > :first-child {
  padding-bottom: var(--sp-3) !important;
  border-bottom: 1px solid var(--line) !important;
}
/* 머리글 15px / 800 */
:is(#photoCleanupModal, #signModal, #safetyModal, #claimLogModal, #equipReportModal, #priceHistModal, #siteCompareModal,
    #siteCopyModal, #integrityModal, #companyModal, #errLogModal, #shortcutHelpModal, #contactModal, #inqModal, #shareModal, #csvExportModal) > .modal > strong:first-child,
:is(#photoCleanupModal, #signModal, #safetyModal, #claimLogModal, #equipReportModal, #priceHistModal, #siteCompareModal,
    #siteCopyModal, #integrityModal, #companyModal, #errLogModal, #shortcutHelpModal, #contactModal, #inqModal, #shareModal, #csvExportModal) > .modal > :first-child > strong:first-child {
  font-size: var(--fs-lg) !important;
  font-weight: var(--fw-extra);
  color: var(--ink);
}
/* 닫기 × — 머리글 끝의 ✕ ghost 버튼을 28px 정사각 아이콘 버튼으로 */
:is(#photoCleanupModal, #equipReportModal, #priceHistModal, #siteCompareModal, #siteCopyModal, #integrityModal, #companyModal,
    #shortcutHelpModal, #contactModal, #inqModal, #shareModal, #csvExportModal) > .modal > :first-child > .btn-ghost[onclick*=".remove()"] {
  width: 28px; min-height: 28px; height: 28px; padding: 0;
  border-color: transparent; border-radius: var(--r-md);
  color: var(--mute);
  font-size: var(--fs-md) !important; line-height: 1;
}
:is(#photoCleanupModal, #equipReportModal, #priceHistModal, #siteCompareModal, #siteCopyModal, #integrityModal, #companyModal,
    #shortcutHelpModal, #contactModal, #inqModal, #shareModal, #csvExportModal) > .modal > :first-child > .btn-ghost[onclick*=".remove()"]:hover {
  background: var(--gray-soft); color: var(--ink);
}
/* 서명 패드(#signCanvas)·서명 미리보기 img는 인쇄·PNG 저장과 같은 흰 종이라 sign.js의 인라인 #fff를 다크에서도 그대로 둔다 (의도된 예외) */

/* 사진 뷰어 이전/다음 화살표 (photo.js가 인라인 rgba(0,0,0,.45)로 만든다) */
#pv-prev, #pv-next {
  background: var(--overlay-bg) !important;
  color: var(--on-navy) !important;
  border: 1px solid rgba(255, 255, 255, .22) !important;
}
#pv-prev:hover, #pv-next:hover { background: var(--navy) !important; }

/* 다크 — 공정표 막대가 카드색에 묻히지 않도록 연한 테두리 */
:root[data-theme="dark"] .gantt-bar:not([data-status="behind"]) { box-shadow: 0 0 0 1px var(--navy-soft); }

/* 행 편집·작업량·도구 시트(.sheet)는 모바일 전용이지만, PC에서 열려도 화면 폭 전체로 깔리지 않고 중앙 모달처럼 보이게 한다 */
@media (min-width: 768px) {
  .modal-bg.is-sheet { align-items: center; padding: 16px; }
  .modal.sheet { width: 520px; max-width: 100%; border-radius: var(--r-card); border-left: 1px solid var(--line); border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); }
  .modal.sheet .sheet-grip { display: none; }
}

/* 노무대장 일자 보기 (T1-b) — 이름 오른쪽 1~말일 칸, 가로 스크롤 */
.ls-days { overflow-x: auto; }
.ls-days .ls-tbl { min-width: calc(1180px + var(--ls-n, 31) * 36px); }
.ls-tbl th.ls-d, .ls-tbl td.ls-d { width: 36px; min-width: 36px; padding: 4px 0; text-align: center; font-size: var(--fs-xs); }
.ls-tbl td.ls-d .ls-dq { width: 100%; height: 28px; border: 0; background: transparent; text-align: center; font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--navy); padding: 0; border-radius: 4px; }
.ls-tbl td.ls-d .ls-dq:hover { background: var(--navy-soft); }
.ls-tbl td.ls-d .ls-dq:focus { outline: 2px solid var(--navy); background: var(--card); }
.ls-tbl td.ls-d.is-sun .ls-dq { color: var(--red); }
.ls-tbl th.ls-d span { display: block; font-weight: var(--fw-bold); }
.ls-tbl th.ls-d small { display: block; font-weight: var(--fw-regular); color: var(--mute); }
.ls-tbl th.ls-d.is-sun, .ls-tbl td.ls-d.is-sun, .ls-tbl th.ls-d.is-sun small { color: var(--red); }
.ls-tbl td.ls-d { color: var(--navy); }
.ls-tbl td.ls-d.is-sun { background: var(--red-soft); }
.ls-dayview[aria-pressed="true"] { background: var(--navy-soft); border-color: var(--navy); color: var(--navy); }

/* 모바일 일보 작업내용 시트 (T1-b) */
.wc-sheet { display: flex; flex-direction: column; gap: var(--sp-2); }
.wc-sheet .wc-memo { min-height: 132px; }
.wc-sheet .wc-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.wc-sheet .wc-boq-panel[hidden] { display: none; }
.dm-wc-l { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 장비대장 — 노무대장의 .ls-days/.ls-tbl/.ls-dq 를 그대로 쓰고, 열이 적어 최소 폭만 줄인다 */
.eq-root .ls-days .ls-tbl { min-width: calc(640px + var(--ls-n, 31) * 36px); }
.eq-tbl td.eq-qty { font-weight: var(--fw-semi); }

/* 직원대장 — 이름·월급·출근일수·인건비 4열뿐이라 노무대장용 1180px 대신 작은 최소 폭을 쓴다(이름 열 고정은 desktop.css) */
.stf-root .ls-days .ls-tbl { min-width: calc(440px + var(--ls-n, 31) * 36px); }
.stf-tbl td input.cell[data-field="st-salary"] { width: 112px; max-width: 100%; }

/* 자재관리대장 (js/ui/mat-ledger.js) — 노무대장의 .ls-days/.ls-tbl 위에 품목 열과 입고/출고 두 줄 일자 칸을 얹는다. 색은 토큰만: 자재 green · 출고 amber-ink · 경고 red/amber/gray */
.ml-root .ls-days .ls-tbl { min-width: calc(1120px + var(--ls-n, 31) * 40px); }
.ml-bar-tools { display: inline-flex; gap: 6px; margin-left: auto; }
.ml-tbl .ls-nm { white-space: nowrap; }
.ml-tbl .ml-u, .ml-ins-tbl small { margin-left: 3px; color: var(--mute); font-weight: var(--fw-regular); }
.ml-tbl td.ml-warn { white-space: normal; min-width: 96px; }
.ml-tbl td.ml-warn .badge { margin: 1px 2px 1px 0; }
.ml-tbl tr.is-unnamed td { background: var(--gray-soft); }
.ml-tbl button.badge { border: 0; cursor: pointer; font: inherit; font-size: var(--fs-xs); }
.ml-na { color: var(--mute); }
.ml-pct { display: inline-flex; align-items: center; gap: 6px; justify-content: flex-end; }
.ml-bar { display: inline-block; width: 44px; height: 6px; border-radius: 3px; background: var(--gray-soft); overflow: hidden; }
.ml-bar i { display: block; height: 100%; width: calc(var(--p, 0) * 1%); background: var(--green); }
.ml-bar[data-tone="amber"] i { background: var(--amber); }
.ml-bar[data-tone="red"] i { background: var(--red); }
.ml-tbl th.ls-d, .ml-tbl td.ls-d { width: 40px; min-width: 40px; padding: 2px 0; }
.ml-dqw { position: relative; display: block; }
.ml-dqw .ml-dq { display: block; width: 100%; height: 22px; border: 0; background: transparent; text-align: center; font: inherit; font-size: var(--fs-xs); font-weight: var(--fw-bold); padding: 0 0 0 7px; border-radius: 4px; }
.ml-dqw.is-in .ml-dq { color: var(--green-ink); }
.ml-dqw.is-out .ml-dq { color: var(--amber-ink); }
.ml-dqw::before { display: none; position: absolute; left: 3px; top: 50%; transform: translateY(-50%); font-size: 10px; font-weight: var(--fw-bold); pointer-events: none; }
.ml-dqw.has-v::before { display: block; }
.ml-dqw.is-in::before { content: '+'; color: var(--green-ink); }
.ml-dqw.is-out::before { content: '\2212'; color: var(--amber-ink); }
.ml-dqw.is-in .ml-dq:hover { background: var(--green-soft); }
.ml-dqw.is-out .ml-dq:hover { background: var(--amber-soft); }
.ml-dqw .ml-dq:focus { outline: 2px solid var(--navy); background: var(--card); }
.ml-dqw.is-multi .ml-dq { cursor: pointer; text-decoration: underline dotted; }
.ml-tbl td.ls-d.is-sun .ml-dqw .ml-dq { background: transparent; }
.ml-ins-row { cursor: pointer; }
.ml-ins-row:hover td { background: var(--surface-2); }
.ml-ins-tbl td, .ml-ins-tbl th, .ml-vendor-tbl td, .ml-vendor-tbl th { white-space: nowrap; }
.ml-cnt-intro { margin: 0 0 var(--sp-3); font-size: var(--fs-sm); color: var(--mute); line-height: 1.5; }
.ml-cnt-tbl input.cell { width: 96px; }
.ml-cnt-diff { font-weight: var(--fw-semi); }
.ml-rs-row { display: flex; align-items: flex-end; gap: 8px; flex-wrap: wrap; padding: 8px 0; border-bottom: 1px solid var(--line); }
.ml-rs-row .field { flex: 1; min-width: 84px; margin: 0; }
.ml-rs-row .ml-rs-remark { flex: 2; min-width: 120px; }
.ml-rs-add { display: flex; gap: 8px; padding-top: var(--sp-3); }

/* 소장 PIN 가드 (js/ui/guard.js) */
.mst-intro { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-3); }
.mst-intro-txt { flex: 1; min-width: 240px; margin: 0; font-size: var(--fs-sm); color: var(--mute); }
.guard-chip { flex-shrink: 0; min-height: 32px; padding: 0 12px; border: 1px solid var(--line); border-radius: 999px; background: var(--card); color: var(--ink); font-size: var(--fs-xs); font-weight: var(--fw-semi); cursor: pointer; }
.guard-chip[data-state="locked"], .guard-chip[data-state="unset"] { background: var(--amber-soft); border-color: var(--amber); }
.guard-chip[data-state="open"] { background: var(--green-soft); border-color: var(--green); }
.guard-note { margin: 0 0 var(--sp-3); font-size: var(--fs-sm); color: var(--ink); line-height: 1.5; }
.guard-pin { text-align: center; }
.guard-pin:not(:placeholder-shown) { letter-spacing: 6px; font-size: var(--fs-lg, 16px); }
.guard-msg { min-height: 1.4em; margin: var(--sp-2) 0 0; font-size: var(--fs-xs); color: var(--red); }
.guard-btns { display: flex; gap: var(--sp-2); flex-wrap: wrap; justify-content: flex-end; }
.guard-card { margin-bottom: var(--sp-3); }
@media (max-width: 767px) {
  .guard-card .tool-row { flex-wrap: wrap; }
  .guard-btns { width: 100%; justify-content: flex-start; }
  .guard-chip { min-height: var(--hit, 44px); }
}

/* ── 청구서 숨김·순서 (거래처현황 · 통합 자금청구서) ── */
.vs-tbl .vs-grip { display: inline-flex; align-items: center; vertical-align: middle; margin-right: 6px; color: var(--mute); cursor: grab; touch-action: none; }
.vs-tbl .vs-grip:active { cursor: grabbing; }
.vs-tbl label.vs-hide { display: flex; align-items: center; gap: 4px; margin-top: 2px; color: var(--mute); font-size: var(--fs-2xs); cursor: pointer; }
.vs-tbl label.vs-hide input { margin: 0; }
.vs-tbl tr.vs-row[data-hidden="1"] td { opacity: .5; }
.vs-tbl tr.vs-row[data-hidden="1"] td.vs-name { opacity: 1; }
.vs-tbl tr.vs-row[data-hidden="1"] td.vs-name > :not(.vs-hide) { opacity: .5; }
.vs-tbl tr.vs-row[data-hidden="1"] td.vs-acts { opacity: 1; }
.vs-tbl tr.vs-row.is-dragging { opacity: .4; }
.vs-tbl tr.vs-row[data-drop="before"] td { box-shadow: inset 0 2px 0 var(--navy); }
.vs-tbl tr.vs-row[data-drop="after"] td { box-shadow: inset 0 -2px 0 var(--navy); }
.claim-etc td { background: var(--amber-soft); font-weight: var(--fw-bold); }
.claim-etc td:first-child { padding-left: 20px; }
.claim-etc-hide { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-2xs); font-weight: var(--fw-regular, 400); white-space: nowrap; cursor: pointer; }
.claim-etcbar { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; padding: 6px 10px; border: 1px dashed var(--line); border-radius: var(--r-sm, 8px); font-size: var(--fs-xs); }
.claim-etcbar label { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.claim-etcbar small { color: var(--mute); }
.vs-tbl td.vs-name { min-width: 150px; }
.vs-tbl td.vs-name b { white-space: nowrap; }
.vs-tbl label.vs-hide { white-space: nowrap; }
.vs-tbl td.vs-acts { min-width: 180px; }

/* ── 현장 기록 (js/ui/events.js) ─────────────────────────── */
.ev-root { display: flex; flex-direction: column; gap: var(--sp-3); }
.ev-bar { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.ev-sum { display: flex; gap: var(--sp-3); flex-wrap: wrap; color: var(--mute); font-size: var(--fs-sm); }
.ev-sum-item b { color: var(--ink); }
.ev-sum-item[data-tone="red"], .ev-sum-item[data-tone="red"] b { color: var(--red); }
.ev-bar-tools { display: inline-flex; gap: 6px; margin-left: auto; }
.ev-filters { display: flex; flex-direction: column; gap: 6px; }
.ev-frow { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.ev-search { display: inline-flex; align-items: center; gap: 6px; margin-left: auto; color: var(--mute); }
.ev-search .input { min-width: 200px; }
.ev-list { display: flex; flex-direction: column; }
.ev-row {
  display: grid; grid-template-columns: 74px auto minmax(0, 1fr) auto auto; align-items: center; gap: var(--sp-2);
  padding: 9px 12px; border-bottom: 1px solid var(--line); cursor: pointer; min-height: var(--hit, 44px);
}
.ev-row:last-child { border-bottom: 0; }
.ev-row:hover { background: var(--surface-2); }
.ev-row[data-overdue="1"] { box-shadow: inset 3px 0 0 var(--red); }
.ev-date { color: var(--mute); font-size: var(--fs-sm); }
.ev-main { display: flex; flex-direction: column; min-width: 0; }
.ev-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-main small { color: var(--mute); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-meta { display: inline-flex; gap: 4px; flex-wrap: wrap; justify-content: flex-end; }
.ev-status { border: 0; cursor: pointer; font-family: inherit; min-height: 26px; padding: 0 10px; }
.ev-status:hover { filter: brightness(0.95); }
@media (max-width: 767px) {
  .ev-row { grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "type date status" "main main main" "meta meta meta"; row-gap: 4px; padding: 12px 14px; }
  .ev-row .ev-type { grid-area: type; justify-self: start; }
  .ev-row .ev-date { grid-area: date; }
  .ev-row .ev-main { grid-area: main; }
  .ev-row .ev-main .ev-title { white-space: normal; }
  .ev-row .ev-meta { grid-area: meta; justify-content: flex-start; }
  .ev-row .ev-meta:empty { display: none; }
  .ev-row .ev-status { grid-area: status; min-height: var(--hit, 44px); min-width: 64px; }
  .ev-search { margin-left: 0; width: 100%; }
  .ev-search .input { flex: 1; min-width: 0; }
}
.ev-form { display: flex; flex-direction: column; gap: var(--sp-3); }
.ev-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-2); }
@media (min-width: 768px) { .ev-grid:not(.ev-grid-2) { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.ev-photo-head { display: flex; align-items: baseline; gap: var(--sp-2); margin-bottom: 6px; flex-wrap: wrap; }
.ev-photo-head small, .ev-photo-none { color: var(--mute); font-size: var(--fs-xs); }
.ev-photo-cnt { color: var(--navy-ink); font-weight: var(--fw-bold); font-size: var(--fs-sm); }
.ev-photos { display: grid; grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); gap: 6px; }
.ev-photo { position: relative; padding: 0; border: 2px solid var(--line); border-radius: var(--r-md, 8px); overflow: hidden; background: var(--surface-2); cursor: pointer; aspect-ratio: 1; }
.ev-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ev-photo-ck { position: absolute; top: 3px; right: 3px; width: 18px; height: 18px; border-radius: 50%; background: var(--navy); color: var(--on-navy); display: none; align-items: center; justify-content: center; }
.ev-photo[aria-pressed="true"] { border-color: var(--navy); }
.ev-photo[aria-pressed="true"] .ev-photo-ck { display: inline-flex; }
.ev-photo-more { margin-top: 8px; }
/* 대시보드 카드 · 홈 한 줄 */
.ev-kpis { display: flex; gap: var(--sp-4); margin-bottom: var(--sp-2); }
.ev-kpis div { display: flex; flex-direction: column; color: var(--mute); font-size: var(--fs-xs); }
.ev-kpis b { font-size: var(--fs-xl, 22px); color: var(--ink); }
.ev-kpis div[data-tone="red"] b { color: var(--red); }
.ev-minis { display: flex; flex-direction: column; }
.ev-mini { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); width: 100%; min-height: var(--hit, 44px); padding: 4px 0; border: 0; border-bottom: 1px solid var(--line); background: transparent; color: var(--ink); font-family: inherit; text-align: left; cursor: pointer; }
.ev-mini-main { display: flex; align-items: center; gap: 6px; min-width: 0; }
.ev-mini-main b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-mini-side { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.ev-mini-side small { color: var(--mute); }
.ev-none { color: var(--mute); font-size: var(--fs-sm); padding: var(--sp-2) 0; }
.ev-card-foot { display: flex; gap: 6px; margin-top: var(--sp-2); }
.ev-home { display: flex; align-items: center; gap: 8px; width: 100%; min-height: var(--hit, 44px); border: 0; background: transparent; color: var(--ink); font-family: inherit; font-size: var(--fs-md); text-align: left; cursor: pointer; }
.ev-home > span { flex: 1; }
.ev-home-over { color: var(--red); }
/* 달력 칸 현장 기록 점 */
.cal-day .evd { position: absolute; top: 11px; left: 30px; width: 7px; height: 7px; border-radius: 50%; background: var(--mute); }
.cal-day .evd[data-tone="red"] { background: var(--red); }
.cal-day .evd[data-tone="amber"] { background: var(--amber); }
.input[aria-invalid="true"] { border-color: var(--red); box-shadow: 0 0 0 2px var(--red-soft); }

/* 내역서 — 실행·원가 보기 (js/ui/boq.js _uiBqc*) */
.bqc-modebar { display: flex; }
.bqc-tools { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2); margin-bottom: var(--sp-2); }
.bqc-spacer { flex: 1; }
.bqc-range { display: inline-flex; align-items: center; gap: 6px; color: var(--mute); }
.bqc-range .input { width: 138px; }
.bqc-tbl { min-width: 760px; }
.bqc-tbl td { padding: 6px 8px; }
.bqc-name small { color: var(--mute); font-weight: var(--fw-regular, 400); }
.bqc-row[data-depth="1"] .bqc-name { padding-left: 22px; }
.bqc-row[data-depth="2"] .bqc-name { padding-left: 38px; }
.bqc-row[data-depth="3"] .bqc-name { padding-left: 54px; }
.bqc-grp td { background: var(--navy-soft); font-weight: var(--fw-bold); }
.bqc-row.is-over td { box-shadow: inset 0 0 0 9999px color-mix(in srgb, var(--red-soft) 55%, transparent); }
.bqc-un td { background: var(--amber-soft); }
.bqc-unbtn { text-align: left; color: var(--amber-ink); font-weight: var(--fw-bold); }
.bqc-unbtn small { color: var(--mute); font-weight: var(--fw-regular, 400); }
.bqc-bud { min-width: 72px; padding: 3px 8px; border: 1px dashed var(--line); border-radius: var(--r-md); background: transparent; color: var(--ink); font-variant-numeric: tabular-nums; text-align: right; cursor: pointer; }
.bqc-bud:hover { border-color: var(--navy); background: var(--surface-2); }
.bqc-bud.is-empty { color: var(--mute); }
.bqc-bud.is-derived { border-style: none; color: var(--mute); font-style: italic; }
.bqc-sub { display: block; color: var(--mute); font-size: var(--fs-2xs, 11px); font-weight: var(--fw-regular, 400); white-space: nowrap; }
.bqc-neg { color: var(--red); }
.bqc-gap[data-tone="amber"] { color: var(--amber-ink); font-weight: var(--fw-bold); }
.bqc-gap[data-tone="red"] { color: var(--red-ink); font-weight: var(--fw-bold); }
.bqc-gauge.is-red .sum-gauge-bar i { background: var(--red); }
.bqc-gauge.is-red .sum-gauge-t { color: var(--red-ink); }
.bqc-edit-note { margin: 0 0 var(--sp-3); color: var(--ink-2); }
.bqc-edit-note small { color: var(--mute); }
.bqc-edit-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2) var(--sp-3); }
.bqc-edit-grid label { display: flex; flex-direction: column; gap: 3px; font-size: var(--fs-sm); color: var(--mute); }
.bqc-edit-grid .input { text-align: right; }
.bqc-edit-sum { margin-top: var(--sp-3); text-align: right; color: var(--mute); }
.bqc-edit-sum b { color: var(--ink); font-size: var(--fs-lg, 16px); }
.bqc-un-list { display: flex; flex-direction: column; max-height: 50vh; overflow-y: auto; }
.bqc-un-row { display: flex; align-items: center; gap: var(--sp-3); padding: 8px 2px; border-top: 1px solid var(--line-soft, var(--line)); }
.bqc-un-row:first-child { border-top: 0; }
.bqc-un-row span { flex: 1; }
.bqc-note td { padding: 6px 8px; color: var(--mute); font-size: var(--fs-xs); font-weight: var(--fw-regular, 400); }
.bqc-note b { color: var(--ink); }

/* PWA 설치·계정 삭제·로그인 시트 하단 링크 */
.sb-install { display: flex; align-items: center; gap: 8px; width: 100%; padding: 7px 8px; border-radius: 7px; color: var(--amber); font-size: var(--fs-sm); font-weight: var(--fw-semi); }
.sb-install[hidden] { display: none; }
.sb-install:hover { background: var(--side-hover); }
.pwa-guide { margin: 0 0 10px; padding-left: 20px; display: grid; gap: 8px; line-height: 1.6; }
.pwa-guide-note { margin: 0; color: var(--mute); font-size: var(--fs-sm); }
.accdel { display: grid; gap: 10px; }
.accdel-warn { margin: 0; color: var(--red); }
.accdel-list { margin: 0; padding-left: 18px; display: grid; gap: 4px; line-height: 1.55; }
.accdel-sub { margin: 0; color: var(--mute); font-size: var(--fs-sm); line-height: 1.5; }
.accdel-sub b { color: var(--ink); word-break: break-all; }
.accdel-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
.login-legal { display: flex; justify-content: center; gap: 14px; margin: 4px 0 0; font-size: var(--fs-xs); }
.login-legal a { color: var(--mute); text-decoration: underline; text-underline-offset: 3px; }
.login-legal a:hover { color: var(--ink); }

/* ── 음성메모 (js/ui/voices.js) — 폰에만 저장되는 녹음 목록·녹음 시트 ── */
.voice-section:empty { display: none; }
.vc-head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); margin: var(--sp-4) 0 var(--sp-2); }
.vc-head h3 { margin: 0; font-size: var(--fs-md); }
.vc-list { display: flex; flex-direction: column; gap: var(--sp-2); }
.vc-item { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); padding: var(--sp-2) var(--sp-3); background: var(--card); border: 1px solid var(--line); border-radius: 8px; }
.vc-meta { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--sp-2); flex: 1 1 140px; min-width: 0; font-size: var(--fs-sm); color: var(--ink); }
.vc-meta span { color: var(--mute); }
.vc-item audio { flex: 1 1 220px; min-width: 0; height: 44px; }
.vc-item .btn { min-height: 44px; }
.vc-empty, .vc-else, .vc-loading { color: var(--mute); font-size: var(--fs-sm); }
.wc-voices:empty { display: none; }
.vc-rec { display: flex; flex-direction: column; gap: var(--sp-3); }
.vc-rec-timer { text-align: center; font-size: 32px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--red); }
.vc-rec-note { margin: 0; text-align: center; font-size: var(--fs-sm); color: var(--mute); }
.vc-rec-btns { display: flex; gap: var(--sp-2); }
.vc-rec-btns .btn { flex: 1; min-height: 44px; }

/* ── 작업내용 카드: 금일 작업 / 명일 작업 (PC 좌우 절반, 모바일 위아래) ── */
.wc-split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.wc-col { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.wc-col-lb { font-size: var(--fs-sm); font-weight: 600; color: var(--mute); }
@media (max-width: 767px) { .wc-split { grid-template-columns: 1fr; } }

/* 현장 기록 — 음성 연결 선택 */
.ev-voices { display: flex; flex-direction: column; gap: var(--sp-1); }
.ev-voice { display: flex; align-items: center; gap: var(--sp-2); min-height: 44px; padding: var(--sp-2) var(--sp-3); text-align: left; background: var(--card); border: 1px solid var(--line); border-radius: 8px; font-size: var(--fs-sm); color: var(--ink); }
.ev-voice .ev-photo-ck { position: static; display: inline-flex; flex: none; background: transparent; border: 1px solid var(--line); border-radius: 4px; color: transparent; }
.ev-voice[aria-pressed="true"] { border-color: var(--navy); }
.ev-voice[aria-pressed="true"] .ev-photo-ck { background: var(--navy); border-color: var(--navy); color: var(--on-navy); }
