/* grid_skin.css — 전역 Tabulator 스킨 정본(매물·고객·팝업 모든 그리드 공통 룩).
   로드: application·embed_modal 레이아웃 + Tabulator 있는 독립 팝업(register/consult) —
   properties_grid 보다 먼저. 매물 전용 그리드 규칙(#grid·dsv2-linked-grid·property-detail-expand)은
   properties_grid.css 잔류.

   ⚠️ 단일 소유(2026-07-29): 기본 스킨이 여기 + m3-components.css + tailwind/application.css
      3곳에 흩어져 승자가 로드 순서와 !important 로만 갈리던 것을 이 파일로 모았고(1차),
      이어서 파일 안에 세 번씩 재정의되던 같은 셀렉터를 **셀렉터당 규칙 1개**로 합쳤다(2차).
      그리드 룩을 바꾸려면 다른 파일 뒤지지 말고 여기서 그 셀렉터 하나만 고친다.
      (별개 관심사는 그대로 — 페이저=shared_pagination / 드롭다운·우클릭=shared_tabulator_popup /
       매물 #grid 스코프=properties_grid / 클릭 피드백=interaction_feedback.)

   ⚠️ 규칙의 순서는 계약이다. 여기엔 특이도가 같아 **순서로만 승부가 갈리는 짝**이 있다:
        .tabulator-row.tabulator-row-even (0,2,0) 과 .tabulator-row:hover (0,2,0)
        → hover 가 뒤에 있어야 마우스 올린 짝수행이 hover 색을 낸다.
      각 규칙은 병합 전 그 셀렉터가 **마지막으로 등장하던 자리**에 그대로 놓여 있다.
      규칙을 "보기 좋게" 재배열하지 말 것 — 배열이 곧 승자다.

   ⚠️ 선언 순서도 계약이다. 한 규칙 안에서 `font:` 숏핸드 뒤에 `font-size`/`font-weight` 가
      오는 곳이 있다(헤더 col·행). 순서를 뒤집으면 숏핸드가 롱핸드를 덮어쓴다.

   ⚠️ 남아 있는 `!important` 는 **선언 7개 · 규칙 5곳**이다. 전부 실측으로 필요성이 확인된 것이다.
      (세는 단위를 밝혀 둔다 — 종전 주석의 "8개"는 선언인지 규칙인지 불명확해 대조가 안 됐다.
       footer 규칙 하나가 선언 3개를 갖는다: background·border-top·color.)
      85개를 하나씩 빼보며 계산값을 대조해, 빼도 아무것도 안 변하는 것들을 지웠다(3·4차).
      2026-07-31 에 hover 선언 1개(셀렉터 3종)를 더 지웠다 — 아래 "지운 것" 참조.
      남은 5곳 — "정리" 삼아 지우지 말 것:
        .tabulator-footer (background·border-top·color)   라이브러리 .tabulator .tabulator-footer 가 더 깊다
        .tabulator-cell.tabulator-editing (outline)       빼면 #1e40af 2px solid → #0f1419 3px none
        .tabulator .tabulator-header .tabulator-col-content (padding)
        .tabulator .tabulator-col-title (text-overflow)
        .tabulator .tabulator-page.active (color)
      이 5개는 **특이도**로 막힌 자리다(라이브러리가 우리보다 깊은 셀렉터를 쓴다).
      더 줄이려면 !important 대신 **셀렉터 특이도를 올려야** 한다(별건).

      지운 것 — .tabulator .tabulator-row:hover 3종의 background 선언(아래 hover 블록):
        여기 적혀 있던 근거가 **사실이 아니었다**. 종전 문구:
          "properties_grid 의 `.dsv2-row-selected { background:#fff3bf !important }` 를 눌러
           선택행 hover 회색을 유지한다. 빼면 노란 선택색이 이긴다."
        두 가지가 틀렸다:
          ① 그 `!important` 는 **없다**. PR #71(2026-07-29, properties_grid !important 30→9)에서
             지워졌고 지금은 `background:#fff3bf;` 다(git log -S '#fff3bf !important' 로 확인).
          ② 있었더라도 이 규칙이 그걸 누를 수 없다. 이 3종은 `.tabulator-row`(행)에 칠하고
             선택행 규칙은 `.tabulator-row.dsv2-row-selected .tabulator-cell`(셀)에 칠한다 —
             **다른 요소**라 캐스케이드가 겨루지 않는다.
        그리고 라이브에서 직접 재 보니 **있으나 없으나 계산값이 같았다**(2026-07-31, dev):
          실마우스 hover 상태에서 CSSOM 으로 priority 만 떼고 getComputedStyle 대조.
          매물 그리드 짝수행·홀수행 × (hover만 / 선택+hover) 4조합, 상가2 우패널 홀수행 2조합
          → 6조합 전부 행 rgb(241,245,249) · 셀 동일. 차이 0.
          이유: 짝/홀 hover 변형(0,4,0)이 경쟁자(-even/-odd 0,3,0, 선택행 0,3,0)를 특이도로
          이미 이긴다. 렌더된 행 42/42 가 -even/-odd 를 가져 그 변형이 항상 적용된다.
        → 근거도 틀렸고 효과도 0이라 지웠다. 되살리려면 같은 방식으로 차이를 먼저 보일 것.

   ⚠️ 전제: **tabulator_simple(CDN) 이 grid_skin 보다 먼저 로드된다.**
      나머지를 걷어낼 수 있었던 근거가 이 순서다 — 동률이면 뒤에 오는 우리가 이긴다.
      application·embed_modal·register_window 세 문서 모두 이 순서다(2026-07-29 정정. 전엔
      register_window 만 반대였고, 그 문서 하나 때문에 !important 21개가 남아 있었다).
      → 새 문서에서 Tabulator 를 쓸 땐 **라이브러리 CSS 를 grid_skin 앞에** 둘 것.
         뒤에 두면 스킨이 통째로 라이브러리 기본 테마에 진다. */

/* 헤더 컬럼 타이틀(Tabulator 기본 마크업 전체 경로) — 대문자·자간 */
.tabulator
  .tabulator-header
  .tabulator-col
  .tabulator-col-content
  .tabulator-col-title {
  color: #1e293b;
  font-weight: 600;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* ── 행: .tabulator 스코프 없는 기본형(0,1,0~0,2,0) ── */
.tabulator-row {
  border-bottom: 1px solid #f0f2f5;
  min-height: 38px;
}
.tabulator-row.tabulator-row-even {
  background: var(--db-grid-row-base);
}
.tabulator-row.tabulator-row-odd {
  background: var(--db-grid-row-stripe);
}
/* ⚠️ even/odd 와 특이도 동률 — 반드시 뒤에 있어야 hover 가 이긴다. */
.tabulator-row:hover {
  background: var(--db-grid-row-hover);
  cursor: pointer;
}

.tabulator-cell {
  border-right: 1px solid #f0f2f5;
  color: #0f1419;
  padding: 8px 10px;
  font-weight: 500; /* 비볼드 기본 500 (c-price/c-unit 은 자체 600 유지) */
}
/* 컬럼별 텍스트 색 override — 위 기본 .tabulator-cell !important 보다 이겨야 하므로
   클래스 2개 조합(.tabulator-cell.text-gray-400)으로 specificity 를 올림(둘 다 !important
   면 specificity 가 타이브레이커). GridConfig column_overrides.cssClass 로 컬럼에 부여.
   dsv2-properties 접수일자(received_date) 연한 회색 처리에 최초 사용. */
.tabulator-cell.text-gray-400 {
  color: var(--db-color-text-muted);
}
.tabulator-footer {
  background: #f8f9fb !important;
  border-top: 1px solid #e5e8ed !important;
  color: #6b7a8d !important;
}

/* 편집중 셀은 파란 outline+border 로 이미 표시되므로 배경만 흰색으로.
   (짝이던 .cell-invalid/.cell-warning/.cell-focus 상태 규칙은 부착 코드가 없어 소각 — 2026-07-28) */
.tabulator .tabulator-cell.tabulator-editing {
  background: #ffffff;
}

/* 비고·메모 셀: 말줄임 금지, 전체 텍스트 표시 + 행 높이 자동 확장 */
.tabulator-cell[tabulator-field="REMARKS"],
.tabulator-cell[tabulator-field="MEMO"] {
  white-space: normal;
  word-break: break-word;
  line-height: 1.45;
  padding-top: 8px;
  padding-bottom: 8px;
}

/* 편집 그리드 컨테이너 — 가로 스크롤 차단 (responsive hide 로 조절) */
.tabulator[data-grid-mode="fit"] .tabulator-tableholder {
  overflow-x: hidden;
}
/* responsive collapse(숨겨진 컬럼 보기) 버튼 스타일 */
.tabulator .tabulator-responsive-collapse-toggle {
  background: #eef2ff;
  color: #4f6ef7;
  border-radius: 6px;
  width: 20px;
  height: 20px;
}
.tabulator .tabulator-responsive-collapse {
  padding: 10px 14px;
  background: #f8f9fb;
  border-top: 1px dashed #d1d6de;
  font-size: 12px;
}

/* 가격 컬럼은 기본 폰트와 통일 (매매가만 튀는 현상 방지) */
.tabulator-cell[tabulator-field="price"] {
  font-family: inherit;
}

/* ── 선택 행 / 원우회 엑셀식 인라인 편집 ── */
.tabulator .tabulator-row.tabulator-selected {
  background: color-mix(in srgb, var(--md-sys-color-primary) 8%, transparent);
}
.tabulator-cell.tabulator-cell-editable:hover {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: -2px;
  cursor: text;
}
.tabulator-cell.tabulator-editing {
  outline: 2px solid var(--md-sys-color-primary) !important;
  background: var(--md-sys-color-surface-container-lowest);
  padding: 0;
  /* 편집 중 셀을 형제 셀 «위»로 올린다. 안 올리면 cell_widen 이 넓힌 셀이 DOM 순서상 앞서
     있어 다음 칸 아래로 깔리고, 옆 칸 글자가 편집 입력칸 위에 그려진다 — 「뒤에가 투영돼
     보인다」(2026-08-11 양희). 배경색은 이미 흰색이었으므로 문제는 색이 아니라 **쌓임 순서**다.
     매물·상가2 그리드는 properties_grid.css 에서 같은 값(overflow:visible·z-index:60)을 이미
     쓰고 있다 — 원우회만 그 규칙의 스코프 밖이라 빠져 있었다. 여기(공용 skin)로 올려 통일한다.
     position 은 z-index 가 먹으려면 필요하다(Tabulator 기본 셀은 static 인 경우가 있다). */
  position: relative;
  z-index: 60;
  overflow: visible;
}
.tabulator-cell.tabulator-editing input {
  border: none;
  outline: none;
  background: transparent;
  width: 100%;
  height: 100%;
  padding: 0 8px;
  font-size: 13px;
}
/* background 숏핸드(구 tailwind 블록) → background-color(구 m3 블록) 순서 유지:
   뒤의 background-color 가 색을 확정한다. */
.tabulator-row.tabulator-selected {
  background: rgba(79, 110, 247, 0.08);
  background-color: color-mix(
    in srgb,
    var(--md-sys-color-primary) 8%,
    transparent
  );
}
.tabulator-row .tabulator-cell input[type="checkbox"] {
  accent-color: var(--md-sys-color-primary);
  width: 16px;
  height: 16px;
}
.tabulator .tabulator-cell {
  border-right: 1px solid var(--md-sys-color-outline-variant);
}

/* 로딩 오버레이 — Tabulator 5.6.1 은 .tabulator-alert / .tabulator-alert-msg 를 씀(.tabulator-loader 아님).
   기본 흰 박스 + 검정 4px 보더(.tabulator-alert-state-msg)를 제거하고 어두운 오버레이만 남긴다. */
.tabulator .tabulator-alert {
  background: rgba(15, 23, 42, 0.32);
  align-items: center;
  justify-content: center;
}
.tabulator .tabulator-alert .tabulator-alert-msg,
.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-msg,
.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-error {
  padding: 0;
  margin: 0;
  border: 0 none;
  border-radius: 0;
  background: none;
  background-color: transparent;
  box-shadow: none;
  color: #fff;
  font-weight: 600;
}

/* ── 헤더 ── */
.tabulator .tabulator-header {
  background: #f8fafc;
  border-bottom: 2px solid #e2e8f0;
}
/* ⚠️ `font:` 숏핸드 → `font-size`/`font-weight` 롱핸드 순서 필수(뒤집으면 숏핸드가 덮는다). */
.tabulator .tabulator-header .tabulator-col {
  background: #f8f9fb;
  font: var(--md-sys-typescale-label-medium);
  color: var(--md-sys-color-on-surface-variant);
  font-size: 12px;
  font-weight: 500;
  border-right: 1px solid #e2e8f0;
}
.tabulator .tabulator-header .tabulator-col-content {
  padding: 5px 6px !important;
}
/* 빈 목록 placeholder("데이터 없음") — 기본 bold(700) → 500 */
.tabulator .tabulator-placeholder .tabulator-placeholder-contents {
  font-weight: 500;
}

/* ── 행(.tabulator 스코프) ──
   행 최소높이는 `--db-grid-row-min-h` **한 값에서만** 나온다. 아래 셀 규칙의 min-height 가
   여기서 calc 로 파생되므로, 높이를 바꿀 땐 이 변수만 고친다(두 곳에 숫자를 박으면 한쪽만
   고쳐져 다시 선이 끊긴다 — 아래가 정확히 그 사고였다).

   ⚠️ **세로 구분선이 짧게 끊기던 버그**(조이 2026-08-20 라이브 실측):
   행은 `height:auto` + `min-height` 라 내용이 짧아도 최소높이를 유지하는데, Tabulator 는
   각 셀에 **콘텐츠 높이를 인라인 `height` 로 박는다**(normalizeHeight). 그래서 한 줄짜리 셀은
   24px, 행은 36px 이 되어 셀의 `border-right`(=세로 구분선)가 **12px 짧게 잘렸다.**
   상가2 좌패널 실측: 120셀 중 39셀(지번 없는 1줄 주소 행 13줄 × 3컬럼)이 이 상태였다.
   종전 처방(40→36 으로 min-height 낮추기)은 "콘텐츠가 마침 36px 인 행"만 맞춘 것이라
   두 줄이 아닌 행에서는 여전히 끊겼다. 근본은 **셀에도 같은 최소높이를 주는 것**이다(아래).
   행 스트레치(display:flex+align-items:stretch)로도 0 이 나오지만, Tabulator 의 행 레이아웃
   (가로 스크롤·고정컬럼)을 갈아끼우는 셈이라 쓰지 않는다 — 실측으로 셋 다 0 확인 후 최소 개입 선택.

   테두리 #f1f5f9(거의 안 보이는 연회색) → 진회색은 2026-07-23 요청.
   ⚠️ `font:` 숏핸드 → `font-size` 롱핸드 순서 필수. */
.tabulator {
  --db-grid-row-min-h: 36px;
}
.tabulator .tabulator-row {
  height: auto;
  font: var(--md-sys-typescale-body-medium);
  color: var(--md-sys-color-on-surface);
  font-size: 13px;
  border-bottom: 1px solid #47556985;
  min-height: var(--db-grid-row-min-h);
}
/* ⚠️ -even/-odd(0,3,0)가 아래에 있어 순수 :hover(0,3,0)를 이긴다 —
   그래서 짝/홀 전용 hover 변형(0,4,0)을 함께 둔다. 셋을 쪼개지 말 것.
   그 (0,4,0) 변형이 이미 이기므로 !important 는 필요 없다(2026-07-31 라이브 실측으로 제거).
   렌더된 행 42/42 가 -even/-odd 클래스를 가지므로 (0,4,0) 변형이 **항상** 적용된다 —
   순수 :hover(0,3,0) 하나만으로는 부족했던 게 !important 가 붙어 있던 이유였다. */
.tabulator .tabulator-row:hover,
.tabulator .tabulator-row.tabulator-row-even:hover,
.tabulator .tabulator-row.tabulator-row-odd:hover {
  background: var(--db-grid-row-hover);
}
.tabulator .tabulator-col-title {
  font-weight: 700;
  font-size: 12px;
  color: #0f172a;
  text-overflow: clip !important;
}
.tabulator .tabulator-row .tabulator-cell {
  padding: 4px 6px;
  border-right: 1px solid #47556985;
  font-size: 12px;
  line-height: 1.3;
  text-overflow: clip;
  /* 세로선을 행 끝까지 — 위 행 주석의 "짧게 끊기던 버그" 처방.
     `-1px` = 행의 border-bottom 몫(행 36px = 셀 35px + 아랫선 1px. 실측: 셀 39 / 행 40).
     min-height 는 Tabulator 가 박는 인라인 height 를 이긴다(used = max(min-height, height))
     — 그래서 !important 없이 짧은 셀만 늘어나고, 두 줄 셀(39px)은 그대로 간다.
     box-sizing:border-box 확인함(패딩·테두리 포함) — 행 높이는 그대로다(실측 전후 동일). */
  min-height: calc(var(--db-grid-row-min-h) - 1px);
}
.tabulator .tabulator-row.tabulator-row-even {
  background: var(--db-grid-row-base);
}
.tabulator .tabulator-row.tabulator-row-odd {
  background: var(--db-grid-row-stripe);
}
.tabulator .tabulator-footer {
  display: none;
}

/* ── 루트 ──
   background #f1f5f9 = 좌우 여백색. 행은 각자 배경(#fff/#fafbfc)을 가지므로 데이터 영역은
   유지되고, 마지막 행 아래 빈 띠만 여백색으로 blend 된다.
   box-shadow 만 토큰 기반(구 m3 블록 유산) — 나머지는 !important 로 확정. */
.tabulator {
  border-radius: 12px;
  box-shadow: var(--md-sys-elevation-1);
  border: none;
  font-family: var(--db-font-sans);
  font-size: 12px;
  background: #f1f5f9;
}
/* 타뷸레이터 내부 스크롤 유지 + 스크롤바 시각 숨김 (세로·가로 모두). */
.tabulator .tabulator-tableholder {
  background: #f1f5f9;
  overflow: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.tabulator .tabulator-tableholder::-webkit-scrollbar {
  width: 0;
  height: 0;
  display: none;
}

/* ── ds-grid-scroll — 스크롤바를 **되살리는** 표준 (정본 = v1 ds_grid_scrollbar.css) ──
   바로 위 규칙이 스크롤바를 시각적으로 숨긴다(overflow:auto 는 유지 = 기능은 살아있고
   "보이지만 않는" 상태). 매물 그리드처럼 숨겨야 하는 화면이 있어서 그게 기본값이다.
   되살릴 화면은 그리드 컨테이너에 클래스를 붙인다 — 가로·세로 `ds-grid-scroll`,
   세로만 `--v`, 가로만 `--h`.

   ⚠️ scrollbar-width 는 반드시 auto 여야 한다. thin/none 이면 표준 스펙상
      ::-webkit-scrollbar 커스터마이징이 통째로 무효화된다
      (v1 실측: thin → 세로바까지 되살아나고, none → 가로바까지 죽는다).
      이 함정에 v1·v2 합쳐 **네 번** 걸렸다 — 네 번째가 연결매물 그리드였고, 거기선
      `scrollbar-width: thin` 아래 webkit 규칙 4개가 **한 번도 적용된 적이 없었다**
      (그래서 화면엔 네이티브 스크롤바가 좌우 화살표 버튼을 달고 떴다).
      이제 `scrollbar_canon_test` 가 이 조합을 정적으로 막는다.

   ── 두께 ──────────────────────────────────────────────────────────────────
   `--ds-grid-scroll-size` 로 화면마다 조절한다(미지정이면 12px = 종전 그대로).
   폼 안에 끼는 좁은 그리드는 12px 가 두꺼워서 필요한 손잡이다 —
   되살리기 규칙을 화면별로 다시 쓰는 대신 **변수 한 줄만** 덮게 한다.
     .my-grid { --ds-grid-scroll-size: 8px; }

   왜 v1 것을 그대로 옮겼나 — v1 은 화면마다 각자 되살리다 "가로만 살리고 세로는 width:0 으로
   죽여놓은" 상태를 겪고(원우회가 정확히 그 화면이었다) 이 파일로 표준화했다. v2 이식은 그
   **표준화 이전 상태**(원우회 전용 가로만)를 옮겨와서 200행을 띄워도 세로바를 잡을 수 없었다.
   푸터 CSS 와 같은 부류의 누락이다 — v1 이 이미 푼 것을 안 가져온 자리. */
.ds-grid-scroll .tabulator-tableholder,
.ds-grid-scroll--v .tabulator-tableholder,
.ds-grid-scroll--h .tabulator-tableholder {
  scrollbar-width: auto !important; /* thin/none 금지 — 위 주석 참고 */
}

/* ⚠️ `scrollbar-color` 는 여기 두면 안 된다 — **아래 webkit 규칙을 전부 죽인다.**
   Chrome 은 scrollbar-color 가 auto 가 아니면 표준 스크롤바 경로로 전환하면서
   ::-webkit-scrollbar 커스터마이징을 통째로 무시한다. scrollbar-width 와 **같은 함정의
   다른 문**이다.

   실측(2026-08-13 라이브, 연결매물 그리드):
     정본 그대로(scrollbar-color 있음)      → 가로바 15px = 브라우저 기본. 두께 지정 무시
     scrollbar-color 만 auto 로 되돌림      → 가로바 8px  = 규칙이 그제서야 적용
     리터럴 8px 를 런타임 주입해도          → 15px. **var() 문제가 아니었다**

   즉 이 정본은 만들어진 이래 두께를 한 번도 못 정했고(색만 입힌 기본폭 바),
   중복본이던 상가2 우패널만 scrollbar-color 가 없어서 제대로 동작하고 있었다.
   → Firefox 등 webkit 의사요소가 **없는** 브라우저에만 표준 속성으로 준다. */
@supports not selector(::-webkit-scrollbar) {
  .ds-grid-scroll .tabulator-tableholder,
  .ds-grid-scroll--v .tabulator-tableholder,
  .ds-grid-scroll--h .tabulator-tableholder {
    /* Firefox 는 px 두께를 못 고른다(auto|thin|none) — 얇은 쪽을 준다. */
    scrollbar-width: thin !important;
    scrollbar-color: rgba(0, 0, 0, 0.32) rgba(0, 0, 0, 0.05);
  }
}
.ds-grid-scroll .tabulator-tableholder::-webkit-scrollbar:vertical,
.ds-grid-scroll--v .tabulator-tableholder::-webkit-scrollbar:vertical {
  width: var(--ds-grid-scroll-size, 12px) !important;
  display: block !important;
}
.ds-grid-scroll .tabulator-tableholder::-webkit-scrollbar:horizontal,
.ds-grid-scroll--h .tabulator-tableholder::-webkit-scrollbar:horizontal {
  height: var(--ds-grid-scroll-size, 12px) !important;
  display: block !important;
}
.ds-grid-scroll--v .tabulator-tableholder::-webkit-scrollbar:horizontal {
  height: 0 !important;
  display: none !important;
}
.ds-grid-scroll--h .tabulator-tableholder::-webkit-scrollbar:vertical {
  width: 0 !important;
  display: none !important;
}
.ds-grid-scroll .tabulator-tableholder::-webkit-scrollbar-track,
.ds-grid-scroll--v .tabulator-tableholder::-webkit-scrollbar-track,
.ds-grid-scroll--h .tabulator-tableholder::-webkit-scrollbar-track {
  background: rgba(0, 0, 0, 0.05);
}
.ds-grid-scroll .tabulator-tableholder::-webkit-scrollbar-thumb,
.ds-grid-scroll--v .tabulator-tableholder::-webkit-scrollbar-thumb,
.ds-grid-scroll--h .tabulator-tableholder::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.32);
  border-radius: 6px;
}
.ds-grid-scroll .tabulator-tableholder::-webkit-scrollbar-thumb:hover,
.ds-grid-scroll--v .tabulator-tableholder::-webkit-scrollbar-thumb:hover,
.ds-grid-scroll--h .tabulator-tableholder::-webkit-scrollbar-thumb:hover {
  background: rgba(0, 0, 0, 0.48);
}
.ds-grid-scroll .tabulator-tableholder::-webkit-scrollbar-corner {
  background: rgba(0, 0, 0, 0.05);
}

/* ── 헤더필터 입력칸 — **보이게** 되돌린다 ──────────────────────────────────
   증상: headerFilter 를 20개 달았는데 화면엔 아무 것도 없다. DOM 에는 input 20개가
   멀쩡히 있고 크기도 87×24 인데(실측 2026-08-10) `border: 0px` · `background: transparent`
   라 **투명한 빈칸**이었다. 사장님 눈엔 정렬화살표만 있는 컬럼 3개만 보였다.

   원인: 레이아웃이 tabulator_simple.min.css(line 42) 를 먼저 싣고 **tailwind(line 55) 를
   뒤에** 싣는다. tailwind preflight 가 `input { border-width:0; background-color:transparent }`
   로 전역 리셋하면서 Tabulator 테마의 입력칸 테두리를 지웠다.
   → 순서에 기대지 않고 canon(이 파일, line 61 로드)에서 **명시적으로** 그린다.
   체크박스는 제외한다(선택 컬럼·행 체크박스가 같은 셀렉터에 걸린다). */
.tabulator
  .tabulator-header
  .tabulator-header-filter
  input:not([type="checkbox"]),
.tabulator .tabulator-header .tabulator-header-filter select {
  box-sizing: border-box;
  width: 100%;
  height: 22px;
  padding: 1px 6px;
  border: 1px solid #cbd5e1;
  border-radius: 4px;
  background: #fff;
  color: #0f172a;
  font-size: 11px;
  font-weight: 400;
  line-height: 1.2;
}
.tabulator
  .tabulator-header
  .tabulator-header-filter
  input:not([type="checkbox"]):focus,
.tabulator .tabulator-header .tabulator-header-filter select:focus {
  outline: none;
  border-color: var(--db-color-primary, #2563eb);
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.15);
}

/* 헤더필터가 있는 그리드만 헤더 패딩을 줄인다 — 제목줄 + 필터줄 2단이라 기본 패딩이면
   헤더가 54px 까지 커진다(실측). 필터가 없는 그리드(매물 등)는 종전 5px 그대로. */
.tabulator:has(.tabulator-header-filter)
  .tabulator-header
  .tabulator-col-content {
  padding: 3px 6px !important;
}

/* ── 행 선택 체크박스 (.ds-row-select) — 두 번째 클릭이 안 먹던 자리 ─────────
   자세한 경위는 grid_table_preset.js 의 selectionCol 주석. 요약:
     · 내장 formatter 는 포맷 시점 RowComponent 를 가둬서 재렌더 후 토글이 죽는다
     · 예약 클래스 `tabulator-row-handle` 을 쓰면 셀 클릭을 라이브러리가 가져간다
   그래서 체크박스는 **표시 전용**(pointer-events:none)이고 클릭은 셀이 받는다.

   ⚠️ 체크 표시를 `checked` 속성으로 그리지 않는다. 헤더 전체선택처럼 JS 를 안 거치고
      행 클래스만 바뀌는 경로가 있어서, 표시를 행의 `.tabulator-selected` 에 묶어야
      **동기화 코드 없이 항상 맞는다**. */
.tabulator .tabulator-row .ds-row-select {
  cursor: pointer;
}
/* ⚠️ 셀렉터를 짧게 쓰면 위 183행 `.tabulator-row .tabulator-cell input[type="checkbox"]`
      (0,3,1) 에 진다 — 실측으로 16px 이 그대로 먹었다. `.tabulator-cell` + `input` 을
      끼워 (0,4,1) 로 올린다. */
/* ⚠️ pointer-events 를 끄지 않는다. 클릭을 셀에 맡기려고 껐다가 **선택이 통째로 죽었다** —
      Tabulator 는 이 컬럼의 cellClick 을 부르지 않는다(실측: cssClass 를 예약 클래스에서
      빼고 셀을 눌러도 sel 0). 클릭은 체크박스가 직접 받고, 핸들러는 formatter 가 단다.
      (주입 실험으로 확인: 체크박스 핸들러 경로는 0→1→0→1→0 정상) */
.tabulator .tabulator-row .tabulator-cell input.ds-row-select-cb {
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  box-sizing: border-box;
  width: 14px;
  height: 14px;
  margin: 0;
  border: 1.5px solid #94a3b8;
  border-radius: 3px;
  background: #fff;
  vertical-align: middle;
}
.tabulator
  .tabulator-row.tabulator-selected
  .tabulator-cell
  input.ds-row-select-cb {
  background: var(--db-color-primary, #2563eb);
  border-color: var(--db-color-primary, #2563eb);
}
.tabulator
  .tabulator-row.tabulator-selected
  .tabulator-cell
  input.ds-row-select-cb::after {
  content: "";
  display: block;
  width: 3px;
  height: 7px;
  margin: 0 auto;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) translate(-1px, -1px);
}

.tabulator .tabulator-page.active {
  background: var(--db-color-primary);
  color: #fff !important;
}
