/* ds.css — 품고 그라운드 통합 디자인 시스템 (단일 소스)
 * 설계 문서: docs/디자인시스템.md
 *
 * ⚠ 이 파일은 admin / index / carrier 3화면이 공유한다.
 *   한 줄 고치면 3화면이 동시에 바뀐다. 반드시 docs/디자인시스템.md §7-4 검증 체크포인트를 돌 것.
 *
 *   login / driver / privacy는 **의도적으로 제외**했다(2026-08-14 검증 결과).
 *   - privacy.html: 자체 *{box-sizing}만 있어 여기 *{margin:0;padding:0}이 새로 먹는다 → 문서 여백 붕괴
 *   - driver.html : 자체 .badge에 vertical-align·white-space가 없어 여기 값이 새로 먹는다
 *   - login.html  : .btn.g를 다른 의미로 쓴다(흰 배경 아웃라인 버튼)
 *   세 화면 모두 badge·dtable·toolbar·modal 같은 공용 컴포넌트를 쓰지 않아 얻는 것도 없다.
 *   나중에 각 화면의 스타일을 의도적으로 이관할 때 함께 붙일 것.
 *
 * ── 지켜야 할 규칙 4가지 (설계 문서 §6-4) ──────────────────────────────
 * 1. !important 금지.
 *    carrier-disp-shim.js가 admin-dispatch.js의 최상위 배선이 죽는 걸 막으려고 숨김 버튼 8개를
 *    인라인 display:none으로 심어둔다. 여기서 !important를 쓰면 그 스텁이 운송사 화면에 노출된다.
 * 2. 맨몸 요소 선택자(input / select / th / td / label / table) 추가 금지.
 *    공용 JS 모듈(onboard.js · arrange-view.js · account.js)이 그리는 요소를 무차별 타격한다.
 *    커밋 368fa11이 정확히 이걸로 터졌다(온보딩 체크박스가 거대 입력칸으로 렌더).
 * 3. 특이도를 페이지 대응 규칙보다 높이지 않는다. (.dtable thead th 를 .ds .dtable thead th 로 올리지 않기)
 * 4. <link>는 각 HTML의 기존 <style> "앞"에 둔다.
 *    뒤에 두면 이 파일이 이겨서 6화면이 한꺼번에 흔들린다. 앞에 두어야 페이지가 이기고,
 *    이관이 끝나지 않은 규칙은 기존 동작 그대로 남는다.
 *
 * ⚠ 참조 시 ?v= 쿼리스트링을 붙이지 말 것.
 *   build-pages.js의 역참조 검증 정규식이 ? 를 배제해 검증이 통째로 스킵되고,
 *   FILES 등록을 누락하면 6화면이 무스타일로 배포된다. 캐시는 _headers의 /*.css no-cache로 처리한다.
 *
 * ── 1단계 범위(2026-08-14) ────────────────────────────────────────────
 * admin.html / index.html / carrier.html 세 화면의 <style>에서 **선택자·선언이 완전히 동일한**
 * 53개 규칙만 원문 그대로 옮겼다. 값을 바꾸지 않았고, 페이지의 기존 <style>도 지우지 않았다.
 * 따라서 이 시점의 계산된 스타일은 정의상 이전과 같다(시각 변화 0).
 * 토큰(:root)·.btn 기본·.card·h1·.sub·.hint·.spin·.pgbtn 기본은 화면별 값이 달라 아직 제외한다.
 */

/* ═══ 1. 토큰 (5단계, 2026-08-14) ════════════════════════════════════
   이전에는 세 화면이 :root를 각자 복제해 갖고 있었고 이미 어긋나 있었다:
     admin   --st-ship 없음, --font 스택은 통일본
     index   --st-ship 있음  ← 여기만
     carrier --st-* 블록이 통째로 뒤쪽(109행)에 따로, --font 스택도 달랐음
   → 여기 한 곳으로 모으고 세 화면의 :root 선언을 지웠다. 이제 단일 소스다.

   상태 ↔ 색 매핑 표준은 docs/디자인시스템.md §5-1.
   픽업완료(주황) ≠ 입고완료(초록) ≠ 배송완료(틸) — 세 상태가 서로 다른 색이어야 한다. */
:root{
  --blue:#1C6FF2; --blue-d:#1457C6; --navy:#0b1f44;
  --ink:#15202e; --muted:#5b6675; --line:#e4e8ee; --bg:#f4f7fb; --pale:#eef4ff;
  --font:"Pretendard","Malgun Gothic","Apple SD Gothic Neo",system-ui,sans-serif;
  --tr:.14s ease;
  --sbw:222px;

  /* 모서리 스케일 — 이전엔 6/7/8/9/10/11/12/14~16/20px 9종이 뒤섞여 있었다(설계 문서 §3-3) */
  --radius-sm:6px; --radius-md:8px; --radius-lg:10px; --radius-xl:14px; --radius-pill:999px;

  --st-wait-bg:#fff3cd;   --st-wait-fg:#8a6d00;    /* 접수·대기 */
  --st-info-bg:#eaf1ff;   --st-info-fg:#1b6fd6;
  --st-info2-bg:#eef4ff;  --st-info2-fg:#1457C6;   /* 배차완료 */
  --st-prog-bg:#e6f7ee;   --st-prog-fg:#0c8a5a;    /* 진행중 */
  --st-prog2-bg:#e3f5ea;  --st-prog2-fg:#0b7a53;
  --st-done-bg:#e3f5ea;   --st-done-fg:#13854a;    /* 입고완료·정산완료 */
  --st-pick-bg:#fef3e2;   --st-pick-fg:#c07a1c;    /* 픽업완료 — 입고완료(초록)와 구분되는 주황 */
  --st-ship-bg:#d6f0ee;   --st-ship-fg:#0e857a;    /* 배송완료(주선) — 입고완료와 구분되는 틸. 이전엔 index에만 있었다 */
  --st-cancel-bg:#fdecea; --st-cancel-fg:#c2362d;  /* 취소·실패 */
  --st-neutral-bg:#f0f3f8;--st-neutral-fg:#7c8aa0;
  --st-purple-bg:#f3f0ff; --st-purple-fg:#6b4fd6;  /* 결제대기 등 — 이전엔 토큰이 없어 #6b3fb8/#7a5cc0/#6b4fd6 3종이 뒤섞여 있었다 */
}
/* ⚠ --brand 와 --gray-50 은 일부러 정의하지 않는다.
   admin.html·admin-dispatch.js가 var(--brand,#1C6FF2), var(--gray-50,#f6f7f9)처럼
   폴백을 달아 쓰고 있고, 이 토큰들은 원래부터 어디에도 정의된 적이 없다.
   여기에 정의를 추가하는 순간 그 자리 색이 폴백값에서 조용히 바뀐다.
   설계 문서 §3-1의 --gray-* 원시 스케일을 도입할 때는 --gray-50 값(#eef4ff 제안)이
   현재 폴백(#f6f7f9)과 다르다는 점을 먼저 확인할 것. */

/* ═══ 2. 리셋 · 기반 ═════════════════════════════════════════════════ */
*{box-sizing:border-box;margin:0;padding:0;}
body.sb-collapsed{--sbw:60px;}
@media(max-width:820px){ :root{--sbw:56px;} }

/* ═══ 3. 상태 표시 — 뱃지 · 상태필 ═══════════════════════════════════
   변형 순서는 admin.html 원문 그대로 유지한다(뒤 규칙이 이기므로 순서를 바꾸면 잠재적 차이가 생긴다).
   상태 ↔ 색 매핑 표준은 docs/디자인시스템.md §5-1. */
.badge{display:inline-flex;align-items:center;justify-content:center;height:24px;line-height:1;vertical-align:middle;background:var(--pale);color:var(--blue-d);font-weight:700;font-size:12px;border-radius:999px;padding:0 11px;white-space:nowrap;}
.badge.wait{background:var(--st-wait-bg);color:var(--st-wait-fg);}
.badge.info{background:var(--st-info-bg);color:var(--st-info-fg);}
.badge.info2{background:var(--st-info2-bg);color:var(--st-info2-fg);}
.badge.prog{background:var(--st-prog-bg);color:var(--st-prog-fg);}
.badge.prog2{background:var(--st-prog2-bg);color:var(--st-prog2-fg);}
.badge.done{background:var(--st-done-bg);color:var(--st-done-fg);}
.badge.cancel{background:var(--st-cancel-bg);color:var(--st-cancel-fg);}
.badge.neutral{background:var(--st-neutral-bg);color:var(--st-neutral-fg);}
.badge.pick{background:var(--st-pick-bg);color:var(--st-pick-fg);}
.badge.ship{background:var(--st-ship-bg);color:var(--st-ship-fg);}      /* 배송완료(주선) — 이전엔 index.html에만 정의돼 관리자·운송사에선 무색이었다 */
.badge.purple{background:var(--st-purple-bg);color:var(--st-purple-fg);} /* 결제대기 등 */
/* 컴팩트 변형 — 좁은 컬럼의 표(#ocList·#arrDispList 등)와 정산 뱃지용.
   기본 .badge(24px/0 11px/12px)를 그대로 쓰면 좁은 상태 컬럼에서 줄바꿈이 생긴다. */
.badge.sm{height:20px;padding:0 8px;font-size:11px;}

.stpill{display:inline-flex;align-items:center;gap:6px;padding:6px 13px;font-size:13px;font-weight:600;border:1px solid var(--line);background:#fff;color:var(--ink);border-radius:999px;cursor:pointer;transition:var(--tr);}
.stpill .n{font-size:11px;font-weight:700;padding:1px 7px;border-radius:10px;background:var(--pale);color:var(--muted);}
.stpill:hover:not(.on){border-color:#c7d3e6;background:#f7faff;}
.stpill.on{border-color:var(--c,var(--blue));background:var(--c,var(--blue));color:#fff;}
.stpill.on .n{background:rgba(255,255,255,.28);color:#fff;}

/* ═══ 4. 표 — dtable · 빈 상태 · 로딩 ════════════════════════════════ */
.dtable{width:100%;border-collapse:collapse;font-size:13px;}
.dtable thead th{position:sticky;top:0;z-index:2;background:var(--navy);color:#fff;font-weight:700;font-size:12.5px;padding:10px 12px;text-align:left;white-space:nowrap;}
.dtable thead th.r{text-align:right;}
.dtable thead th.sortable{cursor:pointer;user-select:none;}
.dtable thead th.sortable:hover{background:#16305e;}
.dtable tbody td{padding:9px 12px;border-bottom:1px solid var(--line);vertical-align:middle;}
.dtable tbody tr:nth-child(even){background:#fafbfd;}
.dtable tbody tr:hover{background:var(--pale);}
.dtable td.r,.dtable th.r{text-align:right;font-variant-numeric:tabular-nums;}
.dtable tfoot td{font-weight:800;background:#f7f9fc;border-top:2px solid var(--line);}

/* 우측정렬 셀 — .dtable이 아닌 표에서도 통하게 한다.
   ⚠ 이건 "맨몸 요소 선택자 금지" 규칙의 예외가 아니다. td.r / th.r은 .r 클래스를 명시적으로
     붙인 셀만 잡으므로, input/select처럼 무차별 타격하지 않는다.
   왜 필요한가: 전역 td.r,th.r 규칙이 index.html에만 있고 admin.html·carrier.html에는 없었다.
     그래서 관리자·운송사의 .dtable 아닌 표(admin-master.js·admin-dispatch.js의 나체 table 등)에서
     금액 셀에 붙인 class="r"이 아무 효과 없이 th,td{text-align:center} 기본값으로 떨어졌다.
     같은 클래스가 화면에 따라 동작하기도, 안 하기도 하던 상태 — 조용한 버그였다(2026-08-14 발견). */
td.r,th.r{text-align:right;font-variant-numeric:tabular-nums;}

.empty-state{text-align:center;padding:44px 20px;color:var(--muted);}
.empty-state .ico{font-size:26px;margin-bottom:8px;opacity:.6;display:block;}
.empty-state b{color:var(--ink);}
.loading-state{display:flex;align-items:center;justify-content:center;gap:8px;padding:40px 0;color:var(--muted);font-size:13.5px;}

/* ═══ 5. 도구모음 — 툴바 · 건수 ══════════════════════════════════════ */
.toolbar{display:flex;flex-direction:column;gap:10px;}
.toolbar-row{display:flex;gap:8px;flex-wrap:wrap;align-items:center;}
.toolbar-row+.toolbar-row{padding-top:10px;border-top:1px solid var(--line);}
.count-chip{margin-left:auto;font-size:12.5px;font-weight:700;color:var(--muted);white-space:nowrap;}
.count-chip b{color:var(--blue-d);}

/* ═══ 6. 페이저 ══════════════════════════════════════════════════════
   .hpg / .ahpg 는 고객사 전용 페이저 변형인데 같은 컴포넌트다(index.html·index-orders.js에서만 사용).
   함께 묶어 통일한다. index만 border가 #d8dee7이었던 것도 var(--line)으로 맞췄다. */
.pgbtn,.hpg,.ahpg{min-width:30px;height:30px;border:1px solid var(--line);background:#fff;border-radius:7px;font-size:12.5px;font-weight:700;cursor:pointer;color:#39424f;padding:0 8px;transition:var(--tr);}
.pgbtn:hover:not(.on):not(:disabled),.hpg:hover:not(.on):not(:disabled),.ahpg:hover:not(.on):not(:disabled){border-color:var(--blue);color:var(--blue-d);}
.pgbtn.on,.hpg.on,.ahpg.on{background:var(--blue);color:#fff;border-color:var(--blue);}
.pgbtn:disabled,.hpg:disabled,.ahpg:disabled{opacity:.4;cursor:default;}
.pager{display:flex;justify-content:center;align-items:center;gap:4px;margin-top:14px;flex-wrap:wrap;}

/* ═══ 7. 모달 ════════════════════════════════════════════════════════
   .modal 자체(max-width)는 화면별로 440 / 920 / 1480px으로 갈려 있어 아직 제외. */
.modal-bg{position:fixed;inset:0;background:rgba(11,31,68,.5);display:none;align-items:flex-start;justify-content:center;z-index:1100;padding:40px 16px;overflow-y:auto;}
.modal-bg.on{display:flex;}
.modal-head{display:flex;align-items:center;justify-content:space-between;padding:18px 22px;border-bottom:1px solid var(--line);font-size:16px;font-weight:800;flex:none;}
.modal-x{background:#eef2f7;border:none;border-radius:9px;width:40px;height:40px;flex:none;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;font-weight:800;font-size:17px;line-height:1;}
.modal-x:hover{background:#e2e8f1;}
.modal-body{padding:20px 22px 24px;overflow-y:auto;}

/* ═══ 8. 버튼 (5단계 값 통일, 2026-08-14) ════════════════════════════
   이전에는 3화면 3규격이었다:
     admin   14.5px / radius10 / 12·22 / 기본 파랑
     index   14px   / radius10 /  9·16 / 기본 배경 없음(.btn.p라야 파랑)
     carrier 13px   / radius9  /  8·14 / 기본 파랑
   → 관리자 기준으로 통일(사용자 결정). font·padding은 스케일 정렬(설계 문서 §3-3, §4-1).

   ⚠ 기본 배경을 파랑으로 두는 게 핵심이다. index 방식(.btn은 무색, .btn.p만 파랑)은
     .p를 빠뜨리면 조용히 회색 버튼이 나오는 사고 구조다. 실제로 고객사의 bare .btn 4곳
     (설정 저장 2 · 파렛 동의 · 홈 픽업요청 CTA)이 브라우저 기본 회색으로 렌더되고 있었다.
   ⚠ .btn.p는 지우지 않는다 — 고객사 마크업 9곳과 account.js가 아직 .p를 쓴다(하위 호환). */
.btn{font-family:inherit;font-weight:800;font-size:14px;border:none;border-radius:10px;padding:10px 20px;cursor:pointer;background:var(--blue);color:#fff;}
.btn:hover:not(:disabled){filter:brightness(.97);}   /* 변형(.g/.danger)에도 안전하게 먹는 방식 — carrier 기존 규칙 승계 */
.btn:disabled{background:#e5e9f0;color:#9aa4b2;cursor:not-allowed;box-shadow:none;}
.btn.p{background:var(--blue);color:#fff;}
.btn.g{background:#eef2f7;color:#39424f;}
.btn.sm{padding:8px 14px;font-size:13px;}
.btn.xs{padding:3px 9px;font-size:11px;border-radius:6px;font-weight:700;}
.btn.danger{background:#fdecea;color:#c2362d;}

/* ═══ 9. 카드 · 페이지 헤더 (5단계 값 통일, 2026-08-14) ══════════════
   .card  admin·carrier는 radius16/pad24/mt20으로 이미 같았고 index만 radius12/pad14·16/mt14였다.
          → 관리자 기준으로 통일. 조밀함이 필요한 곳은 .card.tight(= index 기존 값)를 쓴다.
   h1     admin·carrier 23px / index 20px → 23px
   .sub   admin 14px·mt6 / index 13px·mt4 / carrier 13.5px·mt5 → 관리자 값

   ※ .card h2는 통일하지 않았다 — 고객사는 flex + 번호 뱃지(.card h2 .n) 레이아웃을 쓰고
     관리자는 단순 제목이라, 합치면 신청 폼 스텝 헤더가 깨진다. 각 페이지에 그대로 둔다. */
h1{font-size:23px;font-weight:800;letter-spacing:-.02em;}
.sub{color:var(--muted);font-size:14px;margin-top:6px;}
.card{background:#fff;border:1px solid var(--line);border-radius:16px;padding:24px;box-shadow:0 8px 24px rgba(20,30,55,.05);margin-top:20px;}
.card.tight{border-radius:12px;padding:14px 16px;box-shadow:0 6px 18px rgba(20,30,55,.05);margin-top:14px;}

/* .hint — 이전 값: admin 12.5px·mt8 / index 12px·mt6 / carrier 12px·margin:4px 0 0·lh1.5
   → 고객사 값 기준으로 통일하고 carrier의 line-height만 살렸다.
   ⚠ 기본 margin-top은 그대로 둔다. 684곳 중 기본값에 의존하는 곳이 79곳 있고,
     margin:0으로 좁히면 그 79곳을 한 곳씩 판단해야 하는데 사용자가 체감하는 개선은 없다.
     인라인 style="margin:0" 196건은 중복이지만 정상 동작하므로 손대지 않는다. */
.hint{font-size:12px;color:var(--muted);margin-top:6px;line-height:1.5;}
.hint b{color:var(--blue-d);}

/* ═══ 11. 폼 컨트롤 (2026-08-14 사용자 요청) ═════════════════════════
   ⚠ 맨몸 요소 선택자(input / select / textarea)를 쓰지 않는다.
     공용 JS 모듈(onboard.js · arrange-view.js · account.js)이 그리는 요소를 무차별 타격한다.
     커밋 368fa11이 정확히 이걸로 터졌다 — 고객사 전역 input 규칙이 온보딩 체크박스에 먹어
     체크박스가 거대한 입력칸으로 렌더됐다. 그래서 전부 클래스 기반이다.

   이전 상태(실측):
     전역 input,select  admin 14.5px/11·13/r10/width:120px · index 14px/8·11/r9/width:100% · carrier 정의 없음
     type=date          5종 · type=month 8종 · type=search 5종으로 갈려 있었다

   높이 체계 — 툴바 안에서 버튼·칩과 나란히 서므로 32px로 맞춘다(.btn.sm과 같은 줄에 놓아도 어긋나지 않음). */
.ds-field{font-family:inherit;font-size:13px;height:32px;padding:0 10px;border:1px solid var(--line);border-radius:var(--radius-md);background:#fff;color:var(--ink);box-sizing:border-box;}
.ds-field:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(28,111,242,.12);}
.ds-field:disabled{background:#f4f7fb;color:#9aa4b2;cursor:not-allowed;}
.ds-field::placeholder{color:#9aa4b2;}

/* 폭 변형 — 툴바에서 쓰는 세 가지 패턴 */
.ds-field.date{width:150px;}                    /* type=date  — YYYY.MM.DD가 잘리지 않는 최소폭 */
.ds-field.month{width:130px;}                   /* type=month */
.ds-field.search{flex:1;min-width:200px;}       /* 검색 — 남는 폭을 채운다 */
.ds-field.full{width:100%;}                     /* 폼 안의 한 줄 입력 */

/* 폼(툴바가 아닌 입력 영역) — 세로로 쌓이는 라벨+입력 조합. 툴바보다 크게. */
.ds-field.lg{height:40px;font-size:14px;padding:0 12px;border-radius:var(--radius-lg);}
textarea.ds-field{height:auto;padding:9px 10px;line-height:1.5;resize:vertical;}

/* 기간 범위 픽커 — 「📅 픽업일 [from] ~ [to]」를 한 덩어리로 보이게 하는 조합.
   테두리는 바깥 래퍼가 갖고 안쪽 입력은 테두리를 없앤다(.bare).
   포커스 링도 래퍼가 대신 그린다 — 안쪽 두 입력이 각각 링을 그리면 조합이 깨져 보인다. */
.ds-daterange{display:inline-flex;align-items:center;gap:5px;background:#fff;border:1px solid var(--line);border-radius:var(--radius-md);padding:0 9px;height:32px;}
.ds-daterange:focus-within{border-color:var(--blue);box-shadow:0 0 0 3px rgba(28,111,242,.12);}
.ds-field.bare{border:none;background:transparent;height:auto;padding:2px 4px;width:auto;}
.ds-field.bare:focus{box-shadow:none;}

/* ═══ 10. 좌측 사이드바 (2026-08-14 사용자 요청) ═════════════════════
   설계 문서 §8-3은 사이드바를 "범위 외"로 뒀으나 사용자 지시로 해제했다.

   이전 상태: 관리자·고객사는 .sidebar + body{padding-left}, 운송사만 .sb + .main{margin-left}로
   구조 자체가 달랐다. 규격도 갈려 있었다 —
     운송사  컨테이너 padding:14px 0 + 탭 radius 없음 → 활성 탭이 좌우 끝까지 채워진 파란 띠
             (관리자·고객사는 안쪽 여백 + 9px 라운드 알약)
             아이콘 15px(vs 17px) · 탭 색 #c9d6ef(vs #c3cede) · 그룹헤더 #7f93c4(vs #8595ab)
             z-index 50(vs 60) · 토글 hover 없음
     고객사  탭 14px·padding 11px(vs 13.5px·10px)

   ⚠ .tab 클래스명은 절대 바꾸지 말 것.
     admin-orders.js:19 / index-core.js:93이 맨몸 .tab으로 배선하고 URL 라우팅도 이걸 통과한다.
     같은 이유로 본문에 class="tab"을 새로 만들면 사이드바 라우팅이 오작동한다
     (모든 .tab에서 .on이 제거되고 뷰가 전부 display:none 판정을 받는다).
     admin.html에 있던 유령 .tab CSS(흰 알약)를 함께 지운 이유가 이것이다 — 그 이름을 써도
     되는 것처럼 유도했다.

   그룹 헤더만 관리자 값(10.5px)이 아니라 11px을 쓴다 — §3-3 스케일에 10.5px이 없고
   고객사·운송사가 이미 11px이다. */
body{padding-left:var(--sbw);transition:padding-left .2s;}
/* 본문 컨테이너 여백 — 3화면 공통. 이 값이 곧 페이지 제목(h1)의 시작 위치다.
   이전엔 관리자·운송사 22/24/60px, 고객사만 14/20/20px이라 제목이 8px 위·4px 왼쪽에서 시작했다.
   max-width는 화면별로 다르게 둔다(고객사는 신청 폼 위주라 좁은 편이 읽기 좋다) — 각 페이지에서 지정. */
.wrap{margin:22px auto;padding:0 24px 60px;}
@media(max-width:820px){ .wrap{margin:16px auto;padding:0 14px 50px;} }
.sidebar{position:fixed;left:0;top:0;bottom:0;width:var(--sbw);background:var(--navy);color:#fff;display:flex;flex-direction:column;padding:14px 10px;gap:3px;z-index:60;transition:width .2s;overflow-x:hidden;overflow-y:auto;}
.sidebar .brand{font-weight:800;font-size:16px;display:flex;align-items:center;gap:9px;padding:6px 8px 4px;white-space:nowrap;}
.sidebar .brand .b{width:20px;height:20px;border-radius:4px;background:url(favicon-180.png) center/contain no-repeat;flex:none;}
.sidebar .sb-tag{font-size:11px;color:#aebbd0;padding:0 9px 10px;white-space:nowrap;}
.sidebar .tab{display:flex;align-items:center;gap:11px;width:100%;justify-content:flex-start;background:transparent;border:none;color:#c3cede;font-weight:700;font-size:13.5px;padding:10px;border-radius:9px;cursor:pointer;font-family:inherit;white-space:nowrap;text-decoration:none;}
.sidebar .tab:hover{background:rgba(255,255,255,.08);color:#fff;}
.sidebar .tab.on{background:var(--blue);color:#fff;}
.sidebar .tab .ico{font-size:17px;flex:none;width:22px;text-align:center;}
.sidebar .sb-sp{flex:1;min-height:10px;}
.sidebar .sb-div{height:1px;background:rgba(255,255,255,.12);margin:8px 6px;flex:none;}
.sidebar .sb-group{font-size:11px;font-weight:800;color:#8595ab;letter-spacing:.03em;padding:12px 9px 4px;white-space:nowrap;}
.sidebar .sb-group:first-of-type{padding-top:2px;}
.sidebar .brand .sbToggle{margin-left:auto;flex:none;width:26px;height:26px;padding:0;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.1);border:none;color:#fff;border-radius:8px;cursor:pointer;font-size:17px;font-weight:800;line-height:1;}
.sidebar .brand .sbToggle:hover{background:rgba(255,255,255,.2);}
/* 접힘(60px 레일) */
body.sb-collapsed .sidebar .sb-group{color:transparent;font-size:0;padding:7px 8px 6px;}
body.sb-collapsed .sidebar .sb-group::after{content:'';display:block;height:1px;background:rgba(255,255,255,.14);}
body.sb-collapsed .sidebar .brand{justify-content:center;padding-left:0;padding-right:0;}
body.sb-collapsed .sidebar .brand .b{display:none;}
body.sb-collapsed .sidebar .brand .sbToggle{margin-left:0;}
body.sb-collapsed .sidebar .tab .lbl,body.sb-collapsed .sidebar .brand .txt,body.sb-collapsed .sidebar .sb-tag{display:none;}
body.sb-collapsed .sidebar .tab{justify-content:center;gap:0;padding:10px 0;}
/* 좁은 화면 — 항상 레일. body:not(.sb-collapsed) 방어가 없으면 ds.css의 60px가 이겨 56px이 안 먹는다
   (고객사에만 이 방어가 빠져 있어 모바일 접힘 폭이 4px 달랐다) */
@media(max-width:820px){
  :root{--sbw:56px;} body:not(.sb-collapsed){--sbw:56px;}
  .sidebar .tab .lbl,.sidebar .brand .txt,.sidebar .sb-tag{display:none;}
  .sidebar .tab{justify-content:center;gap:0;padding:10px 0;}
  .sidebar .brand{justify-content:center;padding-left:0;padding-right:0;}
  .sidebar .brand .b{display:none;}
  .sidebar .brand .sbToggle{margin-left:0;}
  .sidebar .sb-group{color:transparent;font-size:0;padding:7px 8px 6px;}
  .sidebar .sb-group::after{content:'';display:block;height:1px;background:rgba(255,255,255,.14);}
}

/* ═══ 11-B. 액션 셀렉트 (2026-08-14 사용자 요청) ═════════════════════
   "고르면 즉시 실행"되는 표 안 처리 드롭다운. 조회·입력용 .ds-field와 반드시 구분돼야 한다.

   이전 상태: 액션 셀렉트 14곳이 8종 규격 / 6종 폭으로 갈려 있었다.
   그중 6곳(.ad-act .cs-act .acc-act .da-act .dd-act .tk-leg-act)은 **폭을 아무도 정한 적이 없고**
   호스트 페이지 전역 규칙에서 우발적으로 흘러든 값이었다:
     admin.html   input,select{width:120px}
     index.html   input,select{width:100%}
     carrier.html 전역 규칙 없음
   → 같은 .tk-leg-act(트럭픽업 상세 모달)가 관리자에선 120px, 운송사에선 auto로 렌더됐다.

   ⚠ 파란 테두리가 이번 통합의 핵심 판정이다.
     지금까지 대부분이 var(--line) 회색이라 조회용 필터 셀렉트와 눈으로 구분되지 않았다.
     "고르면 즉시 실행"되는 위험한 컨트롤이 조회 컨트롤과 같은 모습인 건 오조작 구조다.

   높이 26px: .dtable tbody td(9·12) + .badge(24px) = 행 42px을 흔들지 않는다.
              32px로 하면 50px로 8px 부푼다. 짝 버튼(admin-dispatch.js)이 이미 26px이다.
   폭 84px:   58px은 관리자가 실사용 중 84px로 늘린 이력이 있다(부족하다는 증거).
              width:auto는 못 쓴다 — select의 auto 폭은 가장 긴 option에 맞춰져 셀이 폭발한다. */
.ds-act{font-family:inherit;font-size:11px;font-weight:700;height:26px;width:84px;padding:0 4px 0 8px;border:1px solid var(--blue);border-radius:var(--radius-sm);background:#fff;color:var(--blue-d);cursor:pointer;box-sizing:border-box;}
.ds-act:hover:not(:disabled){background:var(--pale);}
.ds-act:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(28,111,242,.12);}
.ds-act:disabled{border-color:var(--line);color:#9aa4b2;background:#f4f7fb;cursor:not-allowed;}
/* ⚠ 컴팩트 변형(.sm)은 두지 않는다. 표 밀도에 맞춘다는 이유로 크기를 나누자,
   같은 "처리" 드롭다운이 픽업 배차·내역(26px)과 주선 배차·내역(22px)에서 다르게 보였다.
   한 종류로 못 박는다 — 좁은 컬럼은 셀 폭을 넓히거나 라벨을 줄여 대응한다(2026-08-14 사용자 지시). */

/* ═══ 12. 애니메이션 ═════════════════════════════════════════════════ */
@keyframes spin{to{transform:rotate(360deg);}}

/* ═══ 13. 운송사 사각지대 복구 (2단계, 2026-08-14) ═══════════════════
   carrier.html은 carrier-disp-shim.js를 통해 admin-dispatch.js의 렌더를 그대로 재사용하는데,
   아래 클래스들은 admin.html에만 정의돼 있고 carrier.html에는 한 줄도 없었다.
   그래서 운송사 화면에서만 조용히 깨져 있었다:
     .trans-row.on  → 목록 행을 클릭해도 선택 강조가 보이지 않음 (admin-dispatch.js:1508,1561,1594)
     (.selbtn은 2026-08-14 .ds-act로 흡수돼 정의를 제거했다)
     .calcbox       → 원가 계산 박스가 무스타일 (admin-dispatch.js:938)
     .arr-dd-2col   → 배차 상세 모달의 2단 그리드가 1단으로 흐름 (admin-dispatch.js:1380)
   값은 admin.html(106·111·218-220·237행) 원문 그대로다.
   → 관리자는 같은 규칙을 자기 <style>에도 갖고 있어 변화 없음. 운송사만 정상화된다. */
.calcbox{margin-top:12px;background:#f7f9fc;border:1px dashed #cfe0fb;border-radius:8px;padding:12px;text-align:center;color:#4a5568;font-size:13px;font-weight:600;}
.arr-dd-2col{display:grid;grid-template-columns:1.7fr 1fr;gap:8px 28px;align-items:start;}
.arr-dd-2col.eq{grid-template-columns:1fr 1fr;}
@media (max-width:820px){ .arr-dd-2col,.arr-dd-2col.eq{grid-template-columns:1fr;} }
#transList tr.trans-row.on{background:#eaf1ff;}
#transList tr.trans-row.on td{border-color:#cfe0fb;}
