:root { --gap:12px; --radius:14px; }
*{ box-sizing:border-box; }
body{
  font-family:system-ui,-apple-system,Segoe UI,Roboto,'Noto Sans KR',sans-serif;
  margin:0; padding:20px; color:#111; background:#fafafa;
  /* 페이지별 스크롤바 유무 차이로 인한 미세한 좌우 흔들림 방지 */
  scrollbar-gutter: stable;
}

/* 지도/대상처 화면은 ERP/엑셀처럼 "화면을 꽉 채우는" 형태가 더 적합해서,
   바깥 여백(특히 좌/우/하단)을 제거하고 데이터 영역을 최대한 확장한다. */
body.sites-page,
body.map-page{
  /* 상단(카테고리명/네비바)은 홈 화면과 동일한 여백 유지 */
  padding:20px 20px 0;
}

body.schedule-page{
  /* 상단(카테고리명/네비바)은 홈 화면과 동일한 여백 유지 */
  padding:20px 20px 0;
}

/* 대신 데이터(패널) 영역만 좌/우/하단을 최대한 확장 */
body.sites-page .panel,
body.map-page .panel,
body.schedule-page .panel{
  margin-left:-20px;
  margin-right:-20px;
  margin-bottom:0;
  border-radius:0;
}
header.top{
  margin-bottom:16px; display:flex; align-items:flex-start; justify-content:space-between; gap:12px;
}
.title-row{
  display:flex;
  align-items:baseline;
  gap:12px;
  min-width:0;
}
.sub-inline{
  /* 한 줄 유지해서 header 높이가 커지지 않게(=네비 버튼 위치 고정) */
  max-width: min(900px, 65vw);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#auth-area{
  display:flex;
  align-items:center;
  justify-content:flex-end;
  gap:8px;
  flex-wrap:wrap;
}
.auth-me{
  font-size:13px;
  color:#444;
  white-space:nowrap;
}
h1{ margin:0 0 6px 0; font-size:22px; }
.sub{ color:#666; font-size:13px; }

nav.nav{ display:flex; gap:var(--gap); margin:14px 0 20px; flex-wrap:wrap; }
a.btn,button.btn{
  display:inline-block; padding:10px 14px; border:1px solid #e3e3e3;
  background:#fff; border-radius:10px; text-decoration:none; color:#222; cursor:pointer;
}
.btn.with-shortcut{
  display:inline-flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:2px;
  line-height:1.05;
  min-height:38px;
  padding:6px 12px;
}
.btn.with-shortcut .lbl{
  font-size:13px;
  font-weight:400;
}
.btn.with-shortcut .sc{
  font-size:11px;
  color:#666;
  font-weight:500;
}
a.btn:hover,button.btn:hover{ background:#f2f2f2; }
a.btn.active{ border-color:#bbb; font-weight:700; }

.panel{
  background:#fff; border:1px solid #eee; border-radius:var(--radius);
  padding:14px; box-shadow:0 1px 0 rgba(0,0,0,.03);
}

.top-right{ display:flex; flex-direction:column; gap:8px; align-items:flex-end; }
.me{ font-size:13px; color:#444; }
.status{ display:flex; gap:8px; align-items:center; font-size:13px; color:#555; }
.dot{
  width:10px; height:10px; border-radius:50%;
  background:#2ecc71; display:inline-block;
}
.dot.dirty{ background:#f39c12; }
.dot.err{ background:#e74c3c; }

.tabs{
  display:flex; gap:8px; align-items:center; flex-wrap:wrap;
  /* 구분선 제거 + 표 영역을 더 위로 확장 */
  padding-bottom:0;
  border-bottom:none;
}
.tabs .count{
  font-size: 13px;
  color: #111;
  white-space: nowrap;
}
.tab{
  padding:10px 14px; border:1px solid #e3e3e3;
  background:#fff; border-radius:10px; cursor:pointer;
}
.tab.active{ border-color:#bbb; font-weight:800; }
.spacer{ flex:1; }

.q{
  padding:10px 12px; border:1px solid #ddd; border-radius:10px; font-size:14px; outline:none;
  min-width:260px;
}
.color-input{
  width: 34px;
  height: 34px;
  padding: 2px;
  border: 1px solid #ddd;
  border-radius: 8px;
  background: #fff;
  cursor: pointer;
}
.color-swatch-btn{
  display: inline-block;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  background-image: none !important;
  background-clip: padding-box;
  position: relative;
  overflow: hidden;
}
.color-swatch-btn .color-swatch-fill{
  position: absolute;
  left: 2px;
  right: 2px;
  top: 2px;
  bottom: 2px;
  border-radius: 6px;
  background: var(--swatch-color, #111111);
  pointer-events: none;
}
.color-palette{
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 6px;
  border: 1px solid #e3e3e3;
  border-radius: 10px;
  background: #fff;
  min-height: 34px;
}
.color-chip{
  width: 18px;
  height: 18px;
  border-radius: 6px;
  border: 1px solid rgba(0,0,0,0.2);
  cursor: pointer;
  padding: 0;
}
.color-chip:hover{
  transform: translateY(-1px);
}
.cell-color-menu{
  position: fixed;
  z-index: 3600;
  min-width: 188px;
  border: 1px solid rgba(0,0,0,0.18);
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 10px 28px rgba(0,0,0,0.18);
  padding: 6px;
}
.cell-color-menu .menu-btn{
  width: 100%;
  display: block;
  border: 0;
  background: transparent;
  text-align: left;
  font-size: 12px;
  padding: 8px 9px;
  border-radius: 8px;
  cursor: pointer;
}
.cell-color-menu .menu-btn:hover{
  background: rgba(37,99,235,0.1);
}
.cell-color-menu .menu-title{
  font-size: 11px;
  color: #666;
  padding: 4px 4px 6px;
}
.cell-color-menu .menu-palette{
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  padding: 2px 2px 6px;
}
.cell-color-menu .menu-palette-wide{
  max-width: 240px;
  max-height: 170px;
  overflow: auto;
  padding-right: 2px;
}
.btn.primary{ border-color:#cfd8ff; background:#eef2ff; }

.meta{
  display:flex; gap:12px; align-items:center; justify-content:space-between;
  padding:10px 2px;
}
.hint{ color:#888; font-size:12px; }

.err{ color:#c00; font-size:12px; margin-top:8px; white-space:pre-line; }

.grid-wrap{
  margin-top:6px;
  overflow:auto;
  border:1px solid #eee;
  border-radius:12px;
  --grid-font-size: 12px;
}

/* 스크롤바 톤 통일 (Chrome/Edge/Safari) */
.grid-wrap::-webkit-scrollbar{
  width: 10px;
  height: 10px;
}
.grid-wrap::-webkit-scrollbar-track{
  background: rgba(0,0,0,0.08);
  border-radius: 999px;
}
.grid-wrap::-webkit-scrollbar-thumb{
  background: rgba(0,0,0,0.25);
  border-radius: 999px;
  border: 2px solid rgba(0,0,0,0.08);
}
.grid-wrap::-webkit-scrollbar-thumb:hover{
  background: rgba(0,0,0,0.32);
}

/* Firefox */
.grid-wrap{
  scrollbar-width: thin;
  scrollbar-color: rgba(0,0,0,0.28) rgba(0,0,0,0.10);
}

/* sites.html: 표 영역만 스크롤 */
body.sites-page{
  height:100vh;
  overflow:hidden;
  display:flex;
  flex-direction:column;
}
body.sites-page header.top,
body.sites-page nav.nav{
  flex:0 0 auto;
}

/* sites.html은 body가 flex라 마진 겹침이 안 되어(header margin-bottom + nav margin-top이 합산됨)
   대쉬보드(index.html)와 동일한 위치감이 나도록 sites-page에서만 간격을 보정한다. */
body.sites-page header.top{ margin-bottom:2px; } /* 2 + nav(14) = 16(대쉬보드의 마진겹침 결과와 유사) */
body.sites-page nav.nav{ margin:14px 0 12px; }   /* 표 영역을 위로 더 확장 */
body.sites-page section.panel{
  flex:1 1 auto;
  min-height:0;
  display:flex;
  flex-direction:column;
}
body.sites-page section.panel .grid-wrap{
  flex:1 1 auto;
  min-height:0;
  margin-top:6px; /* 네비바에 더 바짝 붙여서 표 영역 확장 */
}

/* 계약해지 행 강조 */
table.sheet tr.row-terminated td{
  background:#ffe6e6;
}

/* grid2: transform 기반 틀고정(가로 스크롤 버벅임 완화) */
body.use-grid2 table.sheet th.frozen,
body.use-grid2 table.sheet td.frozen{
  position: relative; /* z-index 적용을 위해 */
  z-index: 30;
  transform: translateX(var(--scroll-x, 0px));
  will-change: transform;
  background: #fff;
}
body.use-grid2 table.sheet th.frozen{
  z-index: 40;
}
body.use-grid2 table.sheet th.frozen-edge,
body.use-grid2 table.sheet td.frozen-edge{
  box-shadow: 2px 0 0 rgba(0,0,0,0.18);
}

/* grid2 renderer layers */
body.use-grid2 .grid2-scroller{
  /* keep existing overflow:auto from .grid-wrap */
}

/* grid2 canvas overlay */
body.use-grid2 .grid2-spacer{
  width: 1px;
  height: 1px;
}
body.use-grid2 .grid2-overlay{
  /* overlay(canvas)는 scroller 내부에서 항상 화면을 덮는다.
     세로 스크롤 시에는 JS에서 translateY(scrollTop)로 보정한다. */
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  outline: none;
  background: transparent;
  overflow: hidden; /* scrollbars lane과 데이터 영역 분리 */
}
body.use-grid2 canvas.grid2-canvas{
  position: absolute;
  left: 0;
  top: 0;
  display: block;
}

/* grid2 cell editor (textarea overlay) */
body.use-grid2 .grid2-editor{
  position: absolute;
  z-index: 60;
  box-sizing: border-box;
  padding: 4px 6px;
  border: 2px solid #22c55e;
  border-radius: 6px;
  outline: none;
  background: #fff;
  color: #111;
  font-size: var(--grid-font-size);
  line-height: var(--grid-line-height, 1.35);
  font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
  overflow: auto;
  caret-color: #111;
}

/* grid2 column resize guide */
.grid2-col-resize-guide{
  position: fixed;
  top: 0;
  bottom: 0;
  width: 2px;
  background: rgba(37,99,235,0.55);
  z-index: 9999;
  pointer-events: none;
}

body.use-grid2 .grid2-hscroll{
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 16px;
  z-index: 45;
  pointer-events: auto;
  display: flex;
  align-items: center;
  padding: 0 0;
  background: #f7f7f7;
  border-top: 1px solid rgba(0,0,0,0.10);
}
body.use-grid2 .grid2-hscroll-range{
  width: 100%;
  height: 16px;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  margin: 0;
}

body.use-grid2 .grid2-hscroll-range::-webkit-slider-runnable-track{
  height: 6px;
  border-radius: 999px;
  background: rgba(0,0,0,0.08); /* .grid-wrap scrollbar track과 톤 맞춤 */
}
body.use-grid2 .grid2-hscroll-range::-webkit-slider-thumb{
  -webkit-appearance: none;
  width: 54px;
  height: 10px;
  margin-top: -2px;
  border-radius: 999px;
  background: rgba(0,0,0,0.25); /* .grid-wrap scrollbar thumb과 톤 맞춤 */
  border: 2px solid rgba(0,0,0,0.08);
}
body.use-grid2 .grid2-hscroll-range:focus-visible{
  outline: 2px solid rgba(37,99,235,0.55);
  outline-offset: 3px;
}

body.use-grid2 .grid2-sort-menu{
  position: fixed;
  z-index: 3100;
  min-width: 156px;
  border: 1px solid rgba(0,0,0,0.16);
  border-radius: 8px;
  background: #fff;
  box-shadow: 0 8px 24px rgba(0,0,0,0.16);
  padding: 4px;
}
body.use-grid2 .grid2-sort-menu button{
  width: 100%;
  border: 0;
  background: transparent;
  text-align: left;
  font-size: 12px;
  padding: 7px 8px;
  border-radius: 6px;
  cursor: pointer;
}
body.use-grid2 .grid2-sort-menu button:hover{
  background: rgba(37,99,235,0.10);
}
body.use-grid2 .grid2-sort-submenu{
  position: absolute;
  left: calc(100% + 4px);
  top: 0;
  min-width: 190px;
  border: 1px solid rgba(0,0,0,0.16);
  border-radius: 8px;
  background: #fff;
  box-shadow: 0 8px 24px rgba(0,0,0,0.16);
  padding: 4px;
}
body.use-grid2 .grid2-sort-subtitle{
  font-size: 11px;
  color: #666;
  padding: 6px 6px 4px;
}
body.use-grid2 .grid2-sort-color-item{
  width: 100%;
  border: 0;
  background: transparent;
  text-align: left;
  font-size: 12px;
  padding: 7px 8px;
  border-radius: 6px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
}
body.use-grid2 .grid2-sort-color-item:hover{
  background: rgba(37,99,235,0.10);
}
body.use-grid2 .grid2-sort-swatch{
  width: 24px;
  height: 12px;
  border: 1px solid rgba(0,0,0,0.25);
  border-radius: 2px;
  flex: 0 0 auto;
}
body.use-grid2 .grid2-sort-swatch-empty{
  background:
    linear-gradient(45deg, transparent 45%, #b91c1c 45%, #b91c1c 55%, transparent 55%),
    linear-gradient(-45deg, transparent 45%, #b91c1c 45%, #b91c1c 55%, transparent 55%);
}

/* grid2 perf overlay */
body.use-grid2 .grid2-perf{
  position: fixed;
  right: 10px;
  top: 10px;
  z-index: 50;
  padding: 8px 10px;
  border: 1px solid rgba(0,0,0,0.12);
  border-radius: 10px;
  background: rgba(255,255,255,0.92);
  font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  color: #111;
  pointer-events: auto;
  user-select: text;
}
body.use-grid2 .grid2-perf button{
  margin-top: 6px;
  font: inherit;
  padding: 4px 8px;
  border-radius: 8px;
  border: 1px solid rgba(0,0,0,0.2);
  background: #f8fafc;
}

/* grid2 banner (sites page) */
.grid2-banner{
  border: 1px solid rgba(0,0,0,0.12);
  background: #fffdf0;
  border-radius: 12px;
  padding: 10px 12px;
  margin-bottom: 10px;
}
.grid2-banner-title{
  font-weight: 700;
  margin-bottom: 4px;
}
.grid2-banner-desc{
  font-size: 12px;
  color: #333;
  margin-bottom: 6px;
}
.grid2-banner-link{
  display: inline-block;
  font-size: 12px;
  text-decoration: underline;
  color: #111;
}

/* ===== 엑셀형 그리드 ===== */
table.sheet{
  width:max-content;
  min-width:100%;
  border-collapse:collapse;
  table-layout:fixed;
  font-size: var(--grid-font-size);
}
table.sheet th, table.sheet td{
  border:1px solid #cfcfcf;
  padding:0;
  text-align:left;
  vertical-align:top;
  background:#fff;
  background-clip: padding-box; /* 행 배경이 테두리까지 번져 보이는 느낌 완화 */
}
/* 좌측 고정 컬럼(가로 스크롤 시) */
table.sheet th.frozen{
  z-index:50;
}
table.sheet td.frozen{
  z-index:30;
}
table.sheet th.frozen-edge,
table.sheet td.frozen-edge{
  box-shadow:none;
}
/* 틀고정 경계선을 항상 보이게(가로 스크롤 시에도) */
table.sheet th.frozen-edge::after,
table.sheet td.frozen-edge::after{
  content:"";
  position:absolute;
  top:-1px;
  bottom:-1px;
  right:-1px;
  width:2px;
  background:#b9b9b9;
  pointer-events:none;
}
table.sheet th{
  position:sticky;
  top:0;
  z-index:5;
  background:#f7f7f7;
  font-size: inherit;
  color:#333;
  padding:8px 4px;
  white-space:nowrap;
}
table.sheet th .th-inner{
  position:relative;
  display:block;
  /* ▼ 버튼이 레이아웃을 밀지 않도록 우측에 최소 공간만 확보 */
  padding-right:14px;
}
table.sheet th .th-label{
  min-width:0;
  overflow:hidden;
  text-overflow:ellipsis;
}
table.sheet th .th-menu-btn{
  position:absolute;
  right:6px; /* resizer(0..8px) 영역을 피해서 고정 */
  top:50%;
  transform:translateY(-50%);
  border:1px solid transparent;
  background:transparent;
  color:#555;
  width:16px;
  height:16px;
  line-height:14px;
  padding:0;
  border-radius:6px;
  cursor:pointer;
}

/* 선택모드에서 input/select는 커서가 보이지 않게(편집 진입 시에만 입력) */
.cell-input{
  caret-color: transparent;
}
.cell-input.editing{
  caret-color: auto;
}
table.sheet th .th-menu-btn:hover{
  background:#efefef;
  border-color:#e0e0e0;
}
table.sheet th .th-menu-btn.active{
  background:#e8f0ff;
  border-color:#cfe0ff;
  color:#1d4ed8;
}

.col-menu{
  width:260px;
  background:#fff;
  border:1px solid #ddd;
  border-radius:10px;
  box-shadow:0 12px 30px rgba(0,0,0,0.12);
  z-index:9999;
  padding:10px;
}
.col-menu-title{
  font-weight:600;
  font-size:12px;
  color:#222;
  margin:0 0 8px 0;
}
.col-menu hr{
  border:none;
  border-top:1px solid #eee;
  margin:8px 0;
}
.col-menu-item{
  width:100%;
  text-align:left;
  border:1px solid transparent;
  background:#fff;
  padding:8px 10px;
  border-radius:8px;
  cursor:pointer;
  font-size:12px;
}
.col-menu-item:hover{
  background:#f5f5f5;
  border-color:#eee;
}
table.sheet th .resizer{
  position:absolute;
  right:0;
  top:0;
  width:8px;
  height:100%;
  cursor:col-resize;
}

/* 컬럼 리사이즈 가이드(드래그 중 reflow를 피하기 위해 ghost line 사용) */
.col-resize-guide{
  position:fixed;
  top:0;
  bottom:0;
  width:2px;
  background:#3b82f6;
  opacity:0.65;
  z-index:9999;
  pointer-events:none;
}

/* ✅ 고정 높이 제거 (줄바꿈/자동높이) */
table.sheet td{
  height:auto;
}
table.sheet tr.vspacer td{
  border:0 !important;
  background:transparent !important;
}

/* col widths (기본) */
.c-no{ width:70px; }
.c-check{ width:90px; }
.c-approval{ width:120px; }
.c-phone{ width:150px; }

/* ✅ 셀: 기본은 선택모드(커서 깜빡임 제거) */
.cell{
  width:100%;
  padding:4px 8px;
  outline:none;
  white-space:pre-wrap;        /* 줄바꿈 표시 */
  word-break:break-word;       /* 긴 텍스트 줄바꿈 */
  overflow:visible;
  caret-color: transparent;    /* ✅ 선택모드에서 커서 숨김 */
}
.cell.readonly{
  color:#777;
  background:#fafafa;
}
.cell.sel,
.cell-input.sel,
.cell-select.sel{
  background:#eef6ff;
}
.cell.active{ box-shadow:none; }
.cell.editing{
  box-shadow:none;
  background:transparent;
  caret-color: auto;           /* ✅ 편집모드에서는 커서 보이기 */
  overflow:visible;
}

/* 선택/편집/활성 표시를 td에도 적용해서(빈 셀/줄바꿈 셀 포함) 셀 전체 높이에 정확히 표시 */
table.sheet td.sel{ background:#eef6ff; }
/* 파란 활성 테두리는 outline이 더 정확하게 td 경계에 맞는다(빈 셀/줄바꿈 셀 포함) */
table.sheet td.active{
  outline: 2px solid #3b82f6;
  outline-offset:-2px;
}
table.sheet td.editing{
  outline: 2px solid #10b981;
  outline-offset:-2px;
  background:#f0fdf4;
}

/* 행 강조(계약해지): 번호(첫번째 칸)는 제외해서 보기 좋게 */
table.sheet tr.row-terminated td:first-child{
  background:#fff;
}

.cell-select,
.cell-input{
  width:100%;
  padding:4px 8px;
  border:0;
  outline:none;
  background:transparent;
  font:inherit;
  overflow:visible;
}
/* input/select도 div 셀과 동일하게: 선택=파랑, 편집=초록 */
.cell-select.active,
.cell-input.active{
  box-shadow:none;
}
.cell-select.editing,
.cell-input.editing{
  box-shadow:none;
  background:transparent;
}
.cell-select.editing:focus,
.cell-input.editing:focus{
  box-shadow:none;
}
.cell-select:focus,
.cell-input:focus{
  box-shadow:none;
}

/* 컬럼폭 적용(마우스 업) 순간에, 브라우저가 화면 밖 셀 렌더링 부담을 줄이도록 힌트 */
@supports (content-visibility: auto){
  table.sheet.resizing-apply tbody td > .cell,
  table.sheet.resizing-apply tbody td > .cell-input,
  table.sheet.resizing-apply tbody td > .cell-select{
    content-visibility:auto;
    contain-intrinsic-size: 24px 140px;
  }
}
