/* lib/css/style.css — 공통 CSS 단일 파일
 *
 * 로드: lib/php/function.php common() (filemtime 캐시버스트) — **전 페이지**
 * 구성: ① 글로벌/폰트/토큰(:root) ② 공통 bi-* 컴포넌트
 *       ③ [구 list.css 이관분] ④ [구 write.css 이관분]   ← 2026-08-07 일원화
 *
 * ⚠ 페이지타입별 CSS 분리(list.css/write.css) 는 **폐지**됐다. 새 공통 규칙은
 *   페이지타입을 따지지 말고 이 파일 하나에 추가한다(sg2 = 단일 규격).
 *   과거 분리 구조가 "이 페이지엔 안 실림" → 모듈별 재발명을 낳았다.
 * 모듈 전용은 template/page/{module}/style.css (이 파일 뒤에 로드 → override 가능).
 */

/*////////////////////////////////////////////*/
/* 터치모니터 더블클릭 확대방지 */
html {
    -ms-touch-action: none;
    -ms-content-zooming: none;

	/* 21.09.09 ios에서 폰트사이즈자동조절되는것 막기위해서 추가 ( Prevent font scaling in landscape ) */
	-webkit-text-size-adjust: none; /*Chrome, Safari, newer versions of Opera*/
	-moz-text-size-adjust: none; /*Firefox*/
	-ms-text-size-adjust: none;  /*Ie*/
	-o-text-size-adjust: none; /*old versions of Opera*/
}

/* ============================================================
   CSS 변수 토큰 — docs/71 Phase 2: renewal.css :root → style.css 이전 (단일 소스)
   style.css 는 common() 으로 전 페이지(팝업·로그인 포함) 로드 → 토큰 전역 보장
   ============================================================ */
:root {
    /* 팔레트 원색 — 오버레이/딤 전용 앵커. 2026-08-07 추가.
       rgba(0,0,0,x) / rgba(255,255,255,x) 가 49곳에서 리터럴로 쓰였다. 투명도만 다른 같은 색이라
       색 자체를 토큰으로 잡고 투명도는 color-mix 로 준다:
         color-mix(in srgb, var(--black) 55%, transparent)
       ⚠ --bg-card(#FFFFFF)와 값은 같지만 역할이 다르다(카드 배경 ≠ 흰색 오버레이). 섞어 쓰지 않는다. */
    --black: #000000;
    --white: #FFFFFF;

    /* 브랜드 색상 */
    --brand-navy:    #00156E;
    --brand-blue:    #0023B7;
    --brand-purple:  #5E1E7B;
    --brand-lavender:#DEDBF0;

    /* 브랜드 hover/focus 변형 */
    --brand-blue-hover: #0018A0;
    --brand-navy-hover: #000F55;
    --brand-blue-light: rgba(0, 35, 183, 0.08);

    /* TryOn 브랜드 — 헤더의 TryOn 단추 전용 (2026-09-29 사용자 지시).
       값은 짐작이 아니라 tryon 사이트 캡처(renew_crm/try1.png)에서 **재서** 가져온 것이다
       (tools/qc/_tryon_ink.mjs — 로고 «Try» 글자 · «On» 글자 · AI 배지 · 칩을 각각 셈).
       ⚠ 우리 브랜드색(--brand-navy #00156E)이 아니다. 밖으로 나가는 서비스의 색이라
          일부러 갈라 둔다 — 우리 파랑으로 바꾸면 «그 사이트» 라는 표가 사라진다. */
    --tryon-ink:     #0F172A;   /* 로고 «Try» · AI 배지 바탕 · 그 사이트 주 단추 */
    --tryon-pink:    #EC4899;   /* 로고 «On» · 강조 */
    --tryon-pink-dk: #DB2777;   /* 칩 글자 (pink-600) */
    --tryon-surface: #FDF2F8;   /* 칩 바탕 (pink-50) */
    --tryon-line:    #FBCFE8;   /* 테두리 (pink-100) — 옆 날짜 pill 이 «--color-warning-100» 을
                                   쓰는 것과 같은 자리·같은 세기다(§ .hbar-pill--date). */

    /* 텍스트 팔레트 */
    --txt-primary:   #111827;
    --txt-secondary: #374151;
    --txt-muted:     #6B7280;
    --txt-disabled:  #9CA3AF;

    /* 배경 */
    --bg-page:    #F8F9FC;   /* index.html body background */
    --bg-card:    #FFFFFF;
    --bg-input:   #F9FAFB;
    --bg-section: #FAFAFA;
    /* 선택된 행의 옅은 바탕. 스타일보드 원칙 02 «선택 상태는 indigo 하나로» 의 짝 —
     * 강조 막대·체크박스는 --color-indigo-600, 바탕은 이 색이다(2026-08-21 신설). */
    --bg-selected: #F8FAFF;
    /* 판(카드) 안에서 «다른 성격의 열» 을 아주 옅게 갈라 주는 바탕 —
     * 매출등록의 결제 대기 열이 이 색이다. 규격안 그림에서 뽑았다(pick_spec_color: #FCFCFD).
     * 우리 팔레트에 없던 색이라 «규격안에 있고 우리에게 없으면 더한다» 는 원칙대로 신설(2026-09-07). */
    --bg-column: #FCFCFD;

    /* ── 팝업 규격 눈금 (2026-08-25 신설) ──────────────────────────────
     * **styleboard4.html 이 팝업의 유일한 규격이다**(사용자 확정). 옛 §38 은 폐기.
     * 보드 값 중 앱 눈금(--fs-*·--space-*·--radius-*)에 **없는 것이 많다**
     *   글자 15 · 여백 18 · 라운드 9 · 높이 34/37/38/30 …
     * 사용자 지시: «토큰이 없으면 추가하자» → 팝업 전용 눈금을 여기서 선언한다.
     * ⚠ 팝업은 앱의 다른 화면과 **다른 눈금**을 쓴다. 팝업 CSS 는 이 토큰만 부른다 —
     *   그래야 «보드와 다른가» 를 이 한 곳에서 볼 수 있다.
     * 검사: node renew_crm/tools/qc/probe_popspec.mjs (보드를 열어 기대값을 읽는다) */
    --pop-w:          423px;  /* 일반 팝업 (보드 §07) */
    --pop-w-form:     720px;
    /* §72 (2026-09-14) 시안 실측 — 눈대중이 아니라 pd1·pd2·pd3·p1 을 픽셀로 잰 값이다.
       사용자: 「디자이너검색·고객검색이 시안과 규격안이 달라 **넓이부터** 다른데」 */
    --pop-w-srch:     480px;  /* 사람 검색 — pd1 디자이너 · pd2 고객 (둘 다 480) */
    --pop-w-pick:     540px;  /* 하나 고르는 검색창 — pd3 상품 검색 · pd2 고객 검색(2026-09-17) */  /* 폼형 팝업 (사용자 확정 2026-08-25) */
    --pop-w-wide:    1000px;  /* 넓은 폼 — 예약일시처럼 3분할에 시간칩이 여럿인 것(사용자 확정 2026-08-28) */
    --pop-w-prod:     880px;  /* §72 시안 p1 실측 880 (전 860) */  /* 상품 추가 — 두 쪽(목록 | 담은상품 300). 1000 은 넓다는 사용자 지적 2026-09-14 §70-2.
                                 줄어드는 쪽은 «목록» 이다 — 오른쪽 칸은 300 으로 못박혀 있다 */
    --pop-radius:      12px;
    --pop-line:     #E5E7EB;  /* 셸 테두리 · 리스트 상단 */
    --pop-line-soft:#F3F4F6;  /* 그리드 행 구분선 · 폼 섹션 구분 */
    --pop-head-pad-y:  14px;
    --pop-head-pad-x:  18px;
    --pop-head-gap:    10px;
    --pop-title-fs:    15px;
    --pop-cnt-fs:      12px;
    --pop-close:       26px;
    /* ⚠ 2026-09-21 — 13/12 → **14/14**. 바닥줄 키를 시안에 맞춘다.
       시안 넷을 1px 자로 재니(tools/qc/_pd4_ruler.mjs · 선 y → 창 아래 y)
         pd1 69 · pd2 67 · **pd3 63 · pd4 63** · 우리 61
       시안끼리 63~69 로 갈려 «하나의 참값» 이 없다 — **다수인 63** 을 따른다.
       14 + 단추 34 + 14 = 62 · 윗선 1 → **63**. pd3·pd4 가 정확해지고 pd1·pd2 는 8 → 5 로 준다.
       ⚠ 팝업마다 가르지 않는다 — 이 바닥줄은 write 팝업 열일곱이 함께 쓰는 **하나의 규격**이다
         (사용자 2026-08-31: 「catalog도 푸터는 가로 넓이가 다른거지 같아」).
         가르면 «규격이 하나» 라는 전제가 깨지고, 다음에도 또 가르게 된다. */
    --pop-foot-pad-t:  14px;
    --pop-foot-pad-b:  14px;
    --pop-foot-gap:     8px;
    --pop-btn-h:       34px;
    --pop-btn-sm-h:    30px;
    --pop-btn-r:        8px;
    --pop-btn-fs:      13px;
    --pop-btn-sm-fs:   12px;
    --pop-search-h:    38px;
    --pop-search-r:     9px;
    --pop-field-h:     36px;
    --pop-field-r:      8px;
    --pop-sel:      #4F46E5;  /* 선택 강조 — 주 액션(파랑)과 구분 */
    --pop-ico:      #9CA3AF;  /* 헤더 아이콘 — 색을 넣지 않는다 */
    --pop-close-col:#6B7280;
    /* 보드 §04 — 팝업 그림자 1종. 앱 --shadow-* 눈금에 없는 값이라 팝업 토큰으로 둔다. */
    --pop-shadow: 0 10px 40px rgba(20, 30, 60, .16), 0 2px 8px rgba(20, 30, 60, .08);
    --pop-btn-nav-h:   37px;  /* 검색 버튼 — 보드 §06 */
    --pop-btn-nav-w:   57px;
    --pop-f-fs:      13px;  /* 폼 입력·셀렉트 글자 — 보드 §08 */
  --pop-f-gap:      5px;  /* 라벨↔입력 — 보드 §08 */
  --pop-tab-gap:    7px;  /* 탭 사이 — 보드 §08 */
  --pop-pill-pad-x:13px;  /* 칩 좌우 */
  /* ⚠ 2026-09-16 — 상품추가(p1) 시안의 분류 칩은 48·36·36·48·60·60·48 이다.
     13 이면 칩마다 4 넓다(52·40·…). 시안 실측 여백은 11 — 간격 눈금(2·4·6·8·10·12) 밖이라
     기존 --pop-pill-pad-x 와 같은 방식으로 «이름» 을 준다(literal 을 규칙에 쓰지 않는다). */
  --pop-pill-pad-sm:11px; /* 칩 좌우 — 시안 p1 실측(분류 칩) */
  --pop-row-gap:   21px;  /* 행 이름↔금액 사이 */
  --pop-tab-line:  #4C44D5;  /* 활성 탭 테두리 — 보드 §08 */
  --pop-pill-bg:   #EEF2FF;  /* 활성 칩 배경 */
  --pop-pill-line: #BFD0FF;  /* 활성 칩 테두리 */
  --pop-row-min-h:   62px;  /* 2줄 카드행 최소 높이 — 보조줄이 없어도 같은 높이 */
  --pop-row-pad-y:   12px;  /* 2줄 카드행 여백 — 보드 §08 */
    --pop-row-pad-x:   14px;
    --pop-sel-bar:      4px;  /* 선택 행 좌측 막대 — 테두리를 «대신» 한다 */
    --pop-check:       17px;  /* 체크 · 라디오 */
    --pop-check-r:      2px;
    --pop-label-fs:    13px;  /* 선택 라벨 */
    --pop-search-pad-l: 12px; /* 돋보기 들여쓰기 — 보드 §07-2 «인풋 안쪽 좌측 12px» */
    --pop-search-pad-r: 13px;

    /* 보더 */
    --border-base:  #E5E7EB;
    --border-light: #F3F4F6;

    /* 상태 색상 */
    --color-success: #059669;
    --color-danger:  #EF4444;
    --color-warning: #F59E0B;
    --color-npay:    #03C75A;
    --color-kakao:      #FAE102;   /* 카카오 브랜드 노랑 — 말풍선 머리 */
    --color-kakao-txt:  #25262A;   /* 카카오 말풍선 글자 */
    --radius-talk:      10px;      /* 말풍선 모서리 — 브랜드 형태 */

    /* 레이아웃 토큰 */
    --header-height: 50px;   /* 헤더 바 높이 (logo 와 분리) */
    --logo-height:   64px;   /* 사이드바 상단 브랜드(logo) 높이 */
    --sidebar-width: 256px;

    /* 그림자 스케일 (erp-design 기준 — 2026-06-11)
       2026-08-07: xs/sm/md 3단뿐이라 **오버레이(드로어·풀모달)급이 규격 밖**이었다 → --shadow-lg 추가.
       그림자는 blur 로 단계를 고른다: ≤1px=xs · 2~3px=sm · 4~8px=md · 12px↑=lg.
       ⚠ **색 있는 그림자 금지**(구 brand blue/rose 틴트 10곳은 중립 단계로 통일) — 강조는 색·보더로. */
    --shadow-xs: 0 1px 1px 0 rgba(0, 0, 0, 0.04);   /* 컴팩트 버튼/위젯 */
    --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);   /* 카드 기본 */
    --shadow-md: 0 4px 8px 0 rgba(0, 0, 0, 0.08);   /* 부각 카드/모달 */
    --shadow-lg: 0 12px 32px 0 rgba(0, 0, 0, 0.18); /* 오버레이(드로어·풀모달·팝오버 최상단) */
    --shadow-inset: inset 0 1px 2px 0 rgba(0, 0, 0, 0.04); /* 눌린 느낌 — 입력/트랙 안쪽 */

    /* 포커스 링 — 2026-08-07 신설. 구현이 폭 1·2·3px × 투명도 .07~.25 로 42곳 제각각이었다.
       입력·버튼 포커스는 **이 하나만** 쓴다(색 변형 금지 — 상태색은 border 로). */
    --ring-focus: 0 0 0 3px rgba(0, 35, 183, 0.12);

    /* 둥글기 스케일 (erp-design 기준) */
    --radius-xs: 3px;    /* 미세 배지/칩 */
    --radius-sm: 4px;    /* 작은 배지/태그 */
    --radius-md: 6px;    /* bi-btn--sm */
    --radius-lg: 8px;    /* 버튼/입력 기본 (rounded-lg) */
    --radius-xl: 12px;   /* 카드 기본 (rounded-xl) */
    --radius-2xl: 16px;  /* 큰 카드/서브바 */
    --radius-full: 9999px; /* pill/완전둥근 (999px 포함 스냅) */

    /* 인터랙션 (erp-design: hover-lift 대신 press-down) */
    --press-scale: 0.98;                 /* active:scale-98 */
    --transition-base: all 0.15s ease;   /* transition-all */

    /* ============================================================
       여백·타이포·z-index 토큰 (2026-07-27 추가, CSS_ARCHITECTURE_REVIEW P1)
       ※ 순수 추가 — 기존 화면 무변화. 모듈은 하드코딩 대신 이 토큰 참조.
       ============================================================ */

    /* 여백 스케일 — 16px 까지 2px 그리드, 그 위는 4px 그리드.
       2026-08-07: 구 스케일(4의 배수만)은 **너무 성겨서** 배지 패딩·아이콘 간격 같은 미세 여백을
       담지 못했다. 그 결과 1·2·3·5·6·7·9·10·11·13·14·15px 가 700곳 넘게 리터럴로 쓰였다.
       반쪽 단계 4개(2·6·10·14)만 추가해 스케일을 규칙적으로 만들고, 나머지는 최근접 스냅했다.
       ⚠ 새 여백이 필요하면 토큰을 늘리지 말고 **이 스케일에서 고른다.** */
    --space-0_5: 2px;
    --space-1:   4px;
    --space-1_5: 6px;
    --space-2:   8px;
    --space-2_5: 10px;
    --space-3:  12px;
    --space-3_5: 14px;
    --space-4:  16px;
    --space-5:  20px;
    --space-6:  24px;
    --space-8:  32px;
    --space-10: 40px;   /* 그리드 마지막 행 잘림 방지 여백 */
    --space-11: 44px;   /* 계산대 합계바 칸 간격 */
    --space-18: 72px;   /* 하단 고정 닫기바 높이만큼의 자리 */

    /* 콘텐츠/카드 공통 여백 */
    --content-pad: 16px;   /* bi-page 등 콘텐츠 영역 안쪽 여백 */
    --card-pad:    16px;   /* 카드 내부 padding */
    --card-gap:    12px;   /* 카드/요소 간 gap */

    /* 팝업 콘텐츠(iframe 본문) 영역 공통 여백 — 헤더(.bi-pop-head) 아래 본문 표준 padding.
       모든 팝업 콘텐츠 루트가 이 토큰을 불러써 헤더↔본문·본문↔가장자리 여백을 일관 유지(개별 하드코딩 금지). */
    --pop-pad-y:   22px;   /* 팝업 본문 상하 여백 */
    --pop-pad-x:   22px;   /* 팝업 본문 좌우 여백 */

    /* 글자 크기 스케일 */
    --fs-2xs:  10px;   /* 미세 캡션/뱃지 (실사용 다수) */
    --fs-xs:   11px;
    --fs-sm:   12px;
    --fs-base: 13px;   /* 본문 기본 */
    --fs-md:   14px;
    --fs-lg:   16px;
    /* 페이지 타이틀(.bi-erp-title)이 쓰던 값. 문서 §4 는 «역할 이름으로 정의» 하라고 하는데
     * 이 역할만 리터럴 18px 로 적혀 있었다 — 픽셀을 바꾸지 않고 토큰으로 등재한다(2026-08-14).
     * 제목을 16 이나 20 으로 «가장 가까운 토큰» 이라며 옮기면 전 화면 제목이 조용히 달라진다. */
    --fs-2lg:  18px;
    --fs-xl:   20px;
    /* 표시용 큰 숫자 — 대시보드 KPI·POS 최종금액처럼 «읽는 글자» 가 아니라 «보는 수» 다.
     * 값이 이미 화면에 있었는데 토큰이 없어 리터럴로 적혀 있었다(2026-08-14 등재). */
    --fs-2xl:  24px;
    --fs-3xl:  30px;

    /* 아이콘 크기 — 규격 문서 §11 (2026-08-14 등재)
     * 전 화면 3,160개를 실측했더니 10·11·12·13·14·16px 이 2,815개였다. 그건 «정한 값» 이 아니라
     * **옆 글자 크기를 물려받은 것**이다(타이포 스케일과 정확히 일치). 그래서 규칙은 이렇다:
     *   기본 — 아이콘은 제 크기를 정하지 않는다. 글자를 따라간다.
     *   홀로 쓰는 것(빈 상태·배너·강조)만 이 셋에서 고른다. */
    --icon-sm: 16px;
    --icon-md: 24px;
    --icon-lg: 32px;

    /* 글자 굵기 / 행간 */
    --fw-normal:   400;
    --fw-medium:   500;
    --fw-semibold: 600;
    --fw-bold:     700;
    --fw-extrabold: 800;   /* 실사용 다수 */
    --fw-black:     900;   /* 실사용 다수 */
    --lh-tight: 1.3;
    --lh-base:  1.5;

    /* 등폭(숫자·시각·코드) — 2026-08-07 신설. 이전엔 같은 용도를 5가지로 제각각 적고 있었다:
       `monospace` / `ui-monospace, Menlo, monospace` / `ui-monospace, SFMono-Regular, Menlo, monospace`
       / `…Monaco, Consolas, "Liberation Mono", "Courier New", monospace` / `'Inter', monospace`.
       등폭이 필요한 곳은 전부 이 토큰만 쓴다(본문 서체는 body 상속 — §폰트 규격). */
    /* 본문 서체 — 값은 여기 한 곳에만 적는다. 쓰는 쪽은 전부 var(--font-sans).
     * (2026-08-24 신설: 벤더 CSS 를 덮어야 하는 자리가 생겨 «상속만으로는 안 되는» 곳이 있다.
     *  그 자리에 'Pretendard' 를 다시 손으로 적으면 값이 두 군데가 된다 → 토큰으로 한 곳에.) */
    --font-sans: 'Pretendard', sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;

    /* z-index 스케일 (임의값 방지) */
    --z-dropdown: 1000;
    --z-sticky:   1020;
    --z-header:   1030;
    --z-modal:    1050;
    --z-popover:  1060;
    --z-toast:    1080;

    /* ============================================================
       색 팔레트 스케일 (2026-07-27 추가, CSS_PALETTE_PROPOSAL / P1-b)
       ※ 순수 추가 — 기존 화면 무변화. 실사용 색(Tailwind 계열) → 시맨틱 스케일.
       ※ 값-동일 단계는 기존 토큰 alias 로 연결(단일 출처). 신규 단계만 리터럴.
       ※ 모듈은 하드코딩 hex 대신 이 토큰을 참조(값-동일 치환).
       ============================================================ */

    /* 중립(Gray) — 기존 txt/border 를 하나의 스케일로 편입(alias) */
    --gray-50:  var(--bg-input);      /* #F9FAFB */
    --gray-100: var(--border-light);  /* #F3F4F6 */
    --gray-200: var(--border-base);   /* #E5E7EB */
    --gray-300: #D1D5DB;

    /* §58-3 예약 상태 색 — 시안 d1·d2 실측. 판·상세·바닥 색표가 «모두 여기서만» 나온다.
       ⚠ 처음엔 «비슷한 기존 토큰»(--brand-purple 등)으로 대신했다가 색이 시안과 달라졌다.
          --brand-purple 은 #5E1E7B 로 시안의 #5B45E0 이 아니다(2026-09-11 사용자 지적:
          「디자인 색 모양이 중요하다니까 기존 css 가 아니라 규격안, 시안 이 중요하다고」). */
    --bk-req:     #F59E0B;   /* 신청 */
    --bk-fix:     #1D4ED8;   /* 확정 */
    --bk-run:     #5B45E0;   /* 진행중 · 지금 시각 선 */
    --bk-done:    #9CA3AF;   /* 완료 */
    --bk-off:     #EF4444;   /* 취소·노쇼(바닥 색표의 점) */
    --bk-off-line:#FECACA;   /* 취소 블록 점선 — 시안 실측(2026-09-16) */
    --bk-req-bg:  #FFF6E5;
    --bk-fix-bg:  #EEF2FF;
    --bk-run-bg:  #EFEEFF;
    --bk-done-bg: #F6F7F9;

    /* §60-0 이름만 쓰고 «선언은 없던» 넷 (2026-09-11)
       var() 가 빈 값으로 떨어져 바탕이 투명해지고 테두리가 사라졌다(좌 패널이 그 영향을 받고 있었다).
       새 색을 만들지 않는다 — 이미 있는 회색 사다리·흰색에 «이름만» 붙인다. */
    --bg-subtle:     var(--gray-50);    /* #F9FAFB — 칩·배지의 옅은 바탕 */
    --bg-hover:      var(--gray-100);   /* #F3F4F6 — 눌리기 전 얹힘 */
    --border-strong: var(--gray-300);   /* #D1D5DB — 점선 안내처럼 «보여야 하는» 테두리 */
    --txt-inverse:   var(--bg-card);    /* #FFFFFF — 색 바탕 위의 글자 */
    --gray-400: var(--txt-disabled);  /* #9CA3AF */
    --gray-500: var(--txt-muted);     /* #6B7280 */
    --gray-600: #4B5563;
    --gray-700: var(--txt-secondary); /* #374151 */
    --gray-800: #1F2937;
    --gray-900: var(--txt-primary);   /* #111827 */

    /* Danger(빨강) */
    --color-danger-50:  #FEF2F2;
    --color-danger-100: #FEE2E2;
    --color-danger-200: #FECACA;
    --color-danger-500: var(--color-danger);  /* #EF4444 */
    --color-danger-600: #DC2626;
    --color-danger-700: #B91C1C;

    /* Warning(앰버) */
    --color-warning-50:  #FFFBEB;
    --color-warning-100: #FEF3C7;
    --color-warning-200: #FDE68A;
    --color-warning-300: #FCD34D; /* 2026-08 스케일 갭 보완(amber-300) — 사이드 즐겨찾기 hover 등 */
    --color-warning-500: var(--color-warning); /* #F59E0B */
    --color-warning-600: #D97706;
    --color-warning-700: #B45309;

    /* Success(그린) — 기본 성공색(--color-success #059669)=600. 밝은 emerald=500 */
    --color-success-50:  #ECFDF5;
    --color-success-100: #D1FAE5;
    --color-success-200: #A7F3D0;
    --color-success-500: #10B981;
    --color-success-600: var(--color-success); /* #059669 */
    --color-success-700: #047857;

    /* Green(시안 실측) — emerald 계열인 --color-success(#059669)와 «다른 초록» 이다.
       매출등록 시안(buysell.png)의 미결제액 값이 #16A34A(green-600)다 — 화소로 실측했다
       (2026-09-18 _pick_4.mjs: 시안 #16A34A ↔ 우리 #059669). 가까운 색으로 깎지 않고 더한다. */
    --color-green-600: #16A34A;

    /* Info(밝은 정보/링크 블루 — brand-blue 와 별개) */
    --color-info-50:  #EFF6FF;
    --color-info-100: #DBEAFE;
    --color-info-200: #BFDBFE;
    --color-info-500: #3B82F6;
    --color-info-600: #2563EB;
    --color-info-700: #1D4ED8;

    /* Indigo(강조 보조) */
    --color-indigo-50:  #EEF2FF;
    --color-indigo-100: #E0E7FF;
    --color-indigo-500: #6366F1;
    --color-indigo-700: #4338CA;

    /* Purple/Pink(브랜드 보조) — brand-purple(#5E1E7B) 과 별개의 밝은 보라 */
    --color-purple-50:  #FAF5FF;
    --color-purple-200: #E9D5FF;
    --color-purple-600: #9333EA;
    --color-purple-700: #7E22CE;
    --color-pink-500:   #EC4899;

    /* Rose(핑크빨강) — danger(정통 빨강)와 별개의 '의도적 액센트'(로즈 카테고리·신규등록 등). 실사용 값 그대로 */
    --color-rose-50:  #FFF1F2;
    --color-rose-100: #FFE4E6;
    --color-rose-200: #FECDD3;
    --color-rose-500: #F43F5E;
    --color-rose-600: #E11D48;
    --color-rose-700: #BE123C;

    /* 스케일 확장 단계 (2026-07-27) — 실사용 중인 exact-Tailwind 값을 기존 스케일에 편입(값-동일) */
    --gray-950:          #030712;
    --color-danger-300:  #FCA5A5;
    --color-danger-400:  #F87171;
    --color-warning-800: #92400E;
    --color-warning-900: #78350F;
    --color-success-300: #6EE7B7;
    --color-success-400: #34D399;
    --color-success-800: #065F46;
    --color-info-300:    #93C5FD;
    --color-info-900:    #1E3A8A;
    --color-indigo-200:  #C7D2FE;
    --color-indigo-600:  #4F46E5;
    --color-indigo-800:  #3730A3;
    --color-indigo-900:  #312E81;
    --color-purple-500:  #A855F7;
    --color-purple-800:  #6B21A8;
}

body {
    margin: 0;
    background: var(--bg-page);
    /* ▣ 폰트 규격 — 값은 :root 의 --font-sans 한 곳에만 있다. 쓰는 쪽은 전부 그 토큰을 참조한다.
         예외는 아이콘(i.fa/fas/far/fal → 'Font Awesome 5 Pro')과 등폭(var(--font-mono))뿐.
       Pretendard: 본문 서체(header.php 가 CDN static dynamic-subset 로드) · sans-serif: 로드 실패 시 시스템 폴백
       ⚠ 2026-08-07 정정: 옛 주석은 Inter/Noto Sans KR/Nanum Gothic/dotum 폴백 스택을 설명했지만
         실제 선언에는 그 어느 것도 없었다(주석↔코드 불일치). 렌더링 실태에 맞춰 주석을 고쳤다.
       ⚠ 2026-08-24 정정: 옛 주석은 "이 한 줄이 전부. 나머지는 상속"이라고 했는데 **사실이 아니었다** —
         dhx 그리드는 벤더 CSS 가 제 서체(Roboto)를 직접 박고, 폼 컨트롤(input·select·button)은
         브라우저 기본값이라 애초에 상속을 안 받는다. 그 두 자리는 아래에서 **명시적으로** 되돌린다.
       ⚠ 2026-08-24 추가 — 세 번째 자리: dhx **차트**(plugin/chart_gpl)도 벤더 CSS 가 제 서체를
         박는다(이번엔 'Nanum Gothic'). 축·범례·툴팁 글자가 본문과 다르게 나왔다(사용자 지적).
         차트 CSS 가 style.css 보다 뒤에 로드돼(모듈 view 에서 개별 link) 특이도가 같으면 진다 —
         아래서 선택자를 더 구체적으로 잡아 이긴다(§24-4 그리드 폰트 고정과 같은 원리). */
    font-family: var(--font-sans);
}
/* dhx 차트(plugin/chart_gpl/chart.css) 축·범례·툴팁·도넛 글자 — 위 body 주석 세 번째 항목.
   벤더가 .dhx_chart .scale-text 등에 (0,2,0) 으로 'Nanum Gothic' 을 박고 스타일시트가 뒤에
   로드돼 이긴다. .bi-page 로 한 단 더 감싸 (0,3,0) 으로 이긴다. */
.bi-page .dhx_chart .legend-text,
.bi-page .dhx_chart .scale-text,
.bi-page .dhx_chart .scale-title,
.bi-page .dhx_chart .tooltip-text,
.bi-page .dhx_chart .donut-value-title,
.bi-page .dhx_chart .donut-value { font-family: var(--font-sans); }

/* form 은 UA 스타일시트가 `margin-block-end: 1em` 을 준다 — 폼을 감싸기만 해도 아래에
 * 빈 줄이 생긴다. 그래서 12개 팝업이 `style="margin:0px; padding:0px"` 을 달고 있었다.
 * 리셋은 리셋 자리에 둔다(2026-08-11). */
form { margin: 0; padding: 0; }

input {
    /*input 입력시, 한글우선 // ie만 적용됨*/
    ime-mode: active;
}

/* 241108 로고 css*/

.h_log_box {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2_5);
    padding-right: var(--space-6);
}

.h_shooting_star {
    align-self: flex-end;
    margin-bottom: var(--space-1);
    width: 34px;
    height: 34px;
}

.h_log_wirte_div {
    margin-left: var(--space-1);
}

.h_logo_wirte_top {
    font-size: var(--fs-2xl);
    font-weight: var(--fw-semibold);
    margin-bottom: calc(var(--space-1) * -1);
    letter-spacing: -0.01em;
    text-align: left;
    text-underline-position: from-font;
    text-decoration-skip-ink: none;    
    color: var(--white);

}

.h_logo_wirte_bottom {
    font-size: var(--fs-2xs);   /* docs/71 Phase 4: renewal 9px 병합 */
    font-weight: var(--fw-medium);
    letter-spacing: -0.02em;
    text-align: left;
    text-underline-position: from-font;
    text-decoration-skip-ink: none;
    color: color-mix(in srgb, var(--white) 50%, transparent);
    
}

/* .menu_open / .login_info — docs/71 Phase 4: renewal 병합본으로 통합, 원본 중복 제거 */

.sub_menu_open {
    /*헤더 상단우측 img 왼쪽 위치한 : */
    float: right;
    width: 10px;
    height: 24px;
    background-image: radial-gradient(circle at center, white 2px, transparent 1px);
    background-size: 12px 8px;
    background-color: var(--color-info-600);
    margin: var(--space-5) var(--space-1_5) var(--space-1_5) var(--space-1_5);
}

.helpu {
    text-decoration: none;
    color: white;
    font-size: var(--fs-md);
    margin: var(--space-5) var(--space-1_5) 0px var(--space-1);
}

.login_user {
    float: right;
    margin: var(--space-2) var(--space-4) 0px var(--space-1);
}

.search_div {
    padding: var(--space-3) 0px var(--space-1_5) 0px;
    margin-left: var(--space-5);
    width: 250px;
    border-bottom: 1px solid var(--gray-100);
}

.search_input {
    /*10-19 130->260px;*/
    width: 220px;
    /* height: 20px;*/
    background-color: var(--gray-50);
    /* margin: 0px 3px 0px 3px;*/
    border: 0px;
    /* border-bottom: 2px solid var(--gray-100);*/
    color: var(--gray-900);
    padding: var(--space-1_5) 0px var(--space-1) var(--space-2);
    font-size: var(--fs-md);
}
.sch_ninput {
    width: 220px;
    background-color: var(--gray-50);
    border: 0px;
    color: var(--gray-900);
    padding: var(--space-1_5) 0px var(--space-1) var(--space-2);
    font-size: var(--fs-md);
}

.sch_nbtn {
    text-decoration: none;
    width: 20px;
    position: absolute;
    height: 30px;
}

#sch_but {
    text-decoration: none;
    width: 20px;
    position: absolute;
    height: 30px;
}

.body_all {
    width: 100%;
    height: 100%;

    background: var(--gray-50);
}

.body-header {
    height: 45px;
    /*    display: -webkit-flex;
    display: flex;*/
    -webkit-flex-shrink: 0;
    flex-shrink: 0;
    background: var(--bg-card);
    -webkit-justify-content: space-between;
    justify-content: space-between;
    -webkit-align-items: center;
    align-items: center;
    position: relative;
    width: 100% z-index: 101;
}

.body-main {

    height: 100%;

}

.body-main-sch {
    height: 50px;
    border-bottom: 2px solid var(--gray-100);
}

/* ================ 2018-10-19 상단 헤더부분 수정 ============================*/
.body-title {
    /* 매출등록은 직접 적용함*/
    /*padding: 13px 30px 9px 40px;
    width: 70px;*/
	width: auto;
    float: left;
    font-size: var(--fs-lg);
    font-weight: bold;
    color: var(--gray-500);
    margin-right: var(--space-1_5);
	text-align: center;
    padding: var(--space-3_5) 40px;
    height: 45px;
    box-sizing: border-box;

	border-bottom: solid 3px var(--brand-blue);
}

.body-title-sub {
    /* 매출등록은 직접 적용함*/
	/*
    padding: 13px 30px 9px 40px;
	width: 70px;*/
	width: auto;
    float: left;
    font-size: var(--fs-lg);
    font-weight: bold;
    color: var(--gray-500);
    margin-right: var(--space-1_5);
	text-align: center;
    padding: var(--space-3_5) 40px;
    height: 45px;
    box-sizing: border-box;

	border-bottom: solid 3px var(--gray-300);
	cursor: pointer;

}

.body-menu {
    float: right;
    /*1019 상단메뉴수정: 10 ->13px */
    padding: var(--space-3_5) var(--space-2_5) var(--space-1_5) var(--space-1_5);
    color: var(--gray-500);
}

.body-menu-sub {
    padding: 0px var(--space-5) 0px var(--space-3);
    font-size: var(--fs-md);
}

/*========================== [등록수정페이지 UI변경] =================================*/
/* 등록수정페이지 그룹*/

/* 부가설명 */
.sub_description {
    color: var(--gray-400);
    font-size: var(--fs-xs);
    font-weight: 300;
    padding-top: var(--space-1_5);
    display: inline-block;
}

/*===========================================================================*/
select {
    padding: var(--space-0_5) var(--space-0_5);

}

textarea, select {
    border: 1px solid var(--gray-300);
    -webkit-border-radius: 1px;
    -moz-border-radius: 1px;
    border-radius: var(--radius-xs);
    border-top: 1px solid var(--gray-300);
    -webkit-box-shadow: none;
    -moz-box-shadow: none;
    box-shadow: none;
    color: var(--gray-700);
    font-size: var(--fs-base);
    height: 25px;
    line-height: 25px;
    padding: var(--space-0_5) var(--space-2);
}

button {
    cursor: pointer;
}

.sub_menu_button {
    cursor: pointer;
}

input[type="checkbox"]+label {
    display: inline-block;
    background-image: url("/img/page/checkbox_none.png");
    width: 18px;
    height: 18px;
    cursor: pointer;
    position: relative;
    top: 3px;
}

input[type="checkbox"]:checked+label {
    /*background-color: var(--gray-500);*/
    width: 18px;
    height: 18px;
    /*	border: 0px;     12/31 정지은 권한정보 체크시 row 높이 달라지는 문제로 주석처리    */
    background-image: url("/img/page/checkbox.png");
}

input[type="checkbox"] {
    visibility: hidden;
    display: none;
    position: relative;
}

input[type="radio"]+label {
    display: inline-block;
    background-image: url("/img/page/radio.png");
    width: 18px;
    height: 18px;
    cursor: pointer;
    position: relative;
    top: 3px;
}

input[type="radio"]:checked+label {
    /*background-color: var(--gray-500);*/
    width: 18px;
    height: 18px;
    border: 0px;
    background-image: url("/img/page/radio_checked.png");
}

input[type="radio"] {
    visibility: hidden;
    display: none;
    /* position: relative; */
    /* 2024.05.31 radio 버튼 poisition 주석 처리 문소연 */
}

/* ===== sg2 §17 라디오/체크박스 — 공통(전역) 통합 (2026-08)
   위 전역 규칙이 native input 을 sprite(+label) 용으로 숨김. 래퍼 패턴
   (.bi-radio-label / .bi-checkbox-label = input 이 label 안 + <span>텍스트)은
   +label 형제가 없어 sprite 도 안 뜨고 input 도 숨겨져 깨졌음.
   → 래퍼 스코프에서만 native input 을 재활성(accent-color=브랜드블루). 컨테이너
   (filter-card/write-page)에 의존하지 않아 list/write/styleguide 어디서든 self-contained.
   특이도 0,1,1 > 전역 0,0,1 이라 !important 불필요. layout 은 list.css/write.css 에서 이관. */
.bi-radio-group { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
/* sg2 §17 체크박스 그룹 — 여러 체크박스 세로 나열(라디오 그룹 대응). 다중행 라벨은 상단 정렬 */
.bi-checkbox-group .bi-checkbox-label { align-items: flex-start; }
.bi-radio-label {
    display: inline-flex; align-items: center; gap: var(--space-1_5);
    font-size: var(--fs-base); color: var(--txt-secondary);
    cursor: pointer; user-select: none;
}
.bi-checkbox-label {
    display: inline-flex; align-items: center; gap: var(--space-2);
    font-size: var(--fs-md); color: var(--txt-secondary);
    font-weight: var(--fw-normal); cursor: pointer;
}
.bi-radio-label input[type="radio"] {
    visibility: visible; display: inline-block;
    accent-color: var(--brand-blue);
    width: 14px; height: 14px; margin: 0; cursor: pointer; flex-shrink: 0;
}
.bi-checkbox-label input[type="checkbox"] {
    visibility: visible; display: inline-block;
    accent-color: var(--brand-blue);
    width: 16px; height: 16px; margin: 0; cursor: pointer; flex-shrink: 0;
}
/* ⚠ 규격 래퍼 안에서는 옆에 오는 <label> 이 **글자**다.
 *   전역 레거시 규칙 `input[type=checkbox]+label` 이 그 label 을 18px 스프라이트 상자로
 *   바꿔버려, 로그인 화면의 "로그인 정보 저장" 이 한 글자씩 세로로 흘렀다(2026-08-12).
 *   래퍼 스코프(0,1,2)가 전역(0,1,1)을 이기므로 는 필요 없다. */
.bi-checkbox-label input[type="checkbox"] + label,
.bi-radio-label input[type="radio"] + label {
    width: auto; height: auto;
    background: none;
    text-indent: 0; overflow: visible;
    display: inline; cursor: pointer;
}

.bcolor2 {
    cursor: pointer;
    border: 0px;
    line-height: 20px;
    font-weight: bold;
    background: var(--color-info-900);
    -webkit-border-radius: 2px;
    border-radius: var(--radius-xs);
}

.bcolor3 {
    cursor: pointer;
    border: 0px;
    line-height: 20px;
    font-weight: bold;
    background: var(--gray-700);
    -webkit-border-radius: 2px;
    border-radius: var(--radius-xs);
}

.bcolor4 {
    cursor: pointer;
    border: 0px;
    line-height: 20px;
    font-weight: bold;
    background: var(--color-info-600);   /* 2026-08-07 팔레트 밖 #0087a9(청록) → info 계열로 통일. .bcolor* 는 npay 팝업 전용 레거시 세트 */
    padding: 0 var(--space-2);
    -webkit-border-radius: 2px;
    border-radius: var(--radius-xs);
}

.bcolor5 {
    cursor: pointer;
    border: 0px;
    line-height: 20px;
    font-weight: bold;
    background: var(--color-success-500);
    -webkit-border-radius: 2px;
    border-radius: var(--radius-xs);
}

.ft12 {
    font-size: var(--fs-sm);
}

.ft11 {
    font-size: var(--fs-xs);
}

.ft13 {
    font-size: var(--fs-base);
}

.ft14 {
    font-size: var(--fs-md);
}

.ft15 {
    font-size: var(--fs-md);
}

.ft16 {
    font-size: var(--fs-lg);
}

.cursor-p {
    cursor: pointer;
}

.br2_gray {
    border-bottom: 2px solid color-mix(in srgb, var(--black) 10%, transparent);
}

.pop_price {
    color: color-mix(in srgb, var(--black) 80%, transparent);
    padding-right: var(--space-4);
    font-weight: bold;
}

.bt_div {
    width: 100%;
    float: left;
    text-align: right;
    padding-top: var(--space-4);
    border-top: 1px solid color-mix(in srgb, var(--black) 10%, transparent);
}

.pop_desc {
    font-size: var(--fs-sm);
    color: color-mix(in srgb, var(--black) 60%, transparent);
}

/*============ DatePicker ===============*/
/* ⚠ 2026-08-24 «매출기간 캘린더가 깨진다»(사용자 지적 ⑨) — 원인은 이 고정폭이었다.
 *   width:184px 에 아래 select.ui-datepicker-year{width:62px} 가 겹쳐 **네 자리 연도가 «202» 로 잘렸다.**
 *   월 선택 달력(.bi-monthpicker)은 select 가 둘이라 더 좁아 겹쳐 보였다.
 *   → 폭은 내용이 정한다. 최소폭만 준다.
 *   달력은 화면 위에 뜨는 레이어인데 z-index 가 jQuery UI 기본(1)이라 가려질 수 있었다 → 규격 층으로. */
#ui-datepicker-div {
    padding: 0;
    width: auto;
    min-width: 200px;
    font-family: var(--font-sans);
    font-size: var(--fs-base);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    background: var(--bg-card);
    z-index: var(--z-dropdown, 1000);
    overflow: hidden;
}
/* 월 선택은 select 두 개가 나란히 선다 — 더 넓게 */
#ui-datepicker-div.bi-monthpicker { min-width: 232px; }

.ui-datepicker table {
    /* width: 150px; */
    font-size: var(--fs-sm) !important;
    border-collapse: unset;
}

.ui-datepicker .ui-datepicker-header {
    position: relative;
    font-size: var(--fs-md) !important;
    padding: .2em 0;
    background: var(--gray-100);
    ;
    border: none;
    border-bottom: 1px solid var(--gray-300);
}

/* 연도는 네 자리다 — 62px 에 맞추려다 «202» 로 잘렸다(2026-08-24).
 * 폭은 내용이 정하게 두고, 최소폭만 준다.
 * ⚠ 2026-08-24 — 아래 font-family 가 «먹지 않고 있었다». jquery-ui CDN 테마(smoothness)의
 *   `.ui-widget select { font-family: Verdana,Arial,sans-serif }` 가 특이도(0,2,1)로 완전히
 *   같고, style.css 보다 뒤에 로드돼 동점에서 이긴다. #ui-datepicker-div 로 스코프를 좁혀 이긴다. */
#ui-datepicker-div select.ui-datepicker-month,
#ui-datepicker-div select.ui-datepicker-year {
    width: auto;
    min-width: 72px;
    height: 28px;
    padding: 0 var(--space-1_5);
    font-family: var(--font-sans);
    font-size: var(--fs-base);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-md);
    background: var(--bg-card);
    color: var(--txt-primary);
}

.ui-datepicker td span,
.ui-datepicker td a {
    text-align: center !important;
}

.ui-state-highlight,
.ui-widget-content .ui-state-highlight,
.ui-widget-header .ui-state-highlight {
    border: 1px solid var(--gray-300);
    /* 2026-08-11 중복 정리(B0-2): background·color 를 여기서 지웠다.
       아래(L1029 부근) 같은 셀렉터가 `!important` 로 재선언하고 있어 이 두 선언은
       **한 번도 적용된 적이 없다**. 값이 다르니 남겨두면 "여기 고쳤는데 안 바뀐다"가 된다. */
}

.ui-corner-all,
.ui-corner-bottom,
.ui-corner-right,
.ui-corner-br {

    border-radius: 0;
}

.ui-datepicker .ui-datepicker-title {
    background: var(--gray-100);
    ;
}

.ui-widget-content .ui-state-default {
    /* border: 1px solid var(--gray-300); */
    background: white;
    border: none !important;
    /*    background:#fffff; */
    font-weight: normal;
    color: var(--gray-600);

}

.ui-state-highlight,
.ui-widget-content .ui-state-highlight,
.ui-widget-header .ui-state-highlight {
    /*오늘*/
    /* border: 1px solid var(--gray-300); */
    background: var(--color-info-600) !important;
    /* 구글색*/
    border-radius: 50%;
    color: var(--bg-card) !important;
    /*폰트*/
}

/* ⚠ 2026-08-24 스코프 교정 — 이 규칙은 «날짜 칸» 용인데 셀렉터가 너무 넓어
 *   달력 아래 버튼(오늘·닫기)까지 동그랗게 만들고 흰 배경을 씌우고 있었다.
 *   td 안으로 좁힌다. */
/* ⚠ 2026-09-10 «오늘 날짜가 표시되지 않는다»(사용자 지적 A14-1) — 여기가 원인이었다.
 *   오늘 칸의 링크는 클래스가 `ui-state-default ui-state-highlight` 로 **둘 다** 붙는데,
 *   이 규칙이 위(L903)의 `.ui-widget-content .ui-state-highlight` 와 특이도가 같고(0,2,0)
 *   **뒤에 있으면서 !important 도 같아** 오늘 강조(파란 원)를 흰색으로 덮었다.
 *   → 오늘 칸(:not(.ui-state-highlight))만 빼고 적용한다. 버튼줄 스코프 교정(2026-08-24)은 유지. */
.ui-datepicker td .ui-state-default:not(.ui-state-highlight) {
    border-radius: 50%;
    background: white !important;
    font-weight: normal;
    color: var(--gray-600) !important;
}
/* 오늘 칸 — 2026-09-11 사용자 지시: **배경은 달력 배경과 같은 색**으로 두고 글자로 구분한다.
 *   그 전에는 오늘이 «선택» 상태를 겸할 때(입력값이 오늘 = 기본값) `.ui-state-active` 가 겹쳐
 *   배경 연회색(#E5E7EB) + 글자 흰색이 되어 **거의 보이지 않았다**(실측).
 *   ui-state-active·hover 가 뒤에서 덮지 못하도록 셀렉터를 한 단계 더 좁히고 !important 로 고정한다. */
/* 선택된 날짜(오늘이 아닌 날) — 2026-09-11 사용자 지시: **진한 회색 테두리**로 표시.
 *   위(L925) `.ui-state-active` 는 배경을 연회색으로 칠하는데, 그러면 오늘(파랑)과 구분이 흐리고
 *   달력 배경과도 어긋난다. 달력 안에서만 배경을 달력색으로 두고 테두리로 구분한다.
 *   `:not(.ui-state-highlight)` — 오늘이 선택된 경우는 «오늘(파랑)» 이 이긴다. */
.ui-datepicker td .ui-state-active:not(.ui-state-highlight) {
    background: var(--bg-card) !important;
    color: var(--txt-primary) !important;
    border: 1px solid var(--gray-600) !important;
    border-radius: 50%;
    font-weight: var(--fw-medium);
}

.ui-datepicker td .ui-state-highlight,
.ui-datepicker td .ui-state-highlight.ui-state-active,
.ui-datepicker td .ui-state-highlight.ui-state-hover {
    background: var(--bg-card) !important;   /* 달력 배경과 동일 */
    color: var(--color-info-600) !important; /* 글자로 «오늘» 을 구분 */
    border: 1px solid var(--color-info-600) !important;
    border-radius: 50%;
    font-weight: var(--fw-medium);
}

.ui-state-active,
.ui-widget-content .ui-state-active,
.ui-button.ui-state-active:hover {
    border: 1px solid var(--gray-200);
    background: var(--gray-200) !important;
    font-weight: normal;
    color: var(--gray-900);
}

.ui-icon .ui-icon-circle-triangle-w {
    background-image: url(img/ui-icons_44444_256x240.png);

    background-position: -96px 0;
}

.ui-icon .ui-icon-circle-triangle-e {
    background-image: url(images/ui-icons_222222_256x240.png);
    background-position: -32px 0;
}

/*===기본 스크롤바 (얇고 숨김) =====*/
.scroll {
    border-bottom: 2px solid var(--gray-100);
    height: 408px;
    overflow: scroll;
    overflow-x: hidden;
    -ms-scrollbar-face-color: var(--border-light);
    -ms-scrollbar-arrow-color: var(--border-base);
    -ms-scrollbar-shadow-color: var(--white);
}

/*=====================*/
/* tree */
/*=====================*/

.txt_span_high {
    color: color-mix(in srgb, var(--black) 90%, transparent);
    font-size: var(--fs-md);
    font-weight: bold;
}

.txt_span_middle {
    color: color-mix(in srgb, var(--black) 60%, transparent);
    font-size: var(--fs-md);
}

.sch_mtxt {
    font-size: var(--fs-base);
    width: 120px;
    float: left;
    text-align: right;
    padding-top: var(--space-1_5);
    padding-right: var(--space-1_5);
}

.list_sch {
    /*list 검색 돋보기*/

    float: left;
    position: relative;
    height: 27px;
}

/* 검색조건 rowWrap (한줄) //매출관리,매입관리,홈 사용  */
.sch_rowWrap {
    float: left;
    /* width: 70%; */
	width: 100%; /*창크기 조절시 input깨지는 문제로 px로 변경  드래그 생격서 다시 수정(강무성, 2021-08-03*/
    padding: var(--space-0_5) 0px;
}

/* 검색버튼 왼쪽input */
.sch_left {
    margin-right: var(--space-1);
    width: 216px;
    text-align: right;
}

.sch_icon {
    position: absolute;
    margin-left: var(--space-2);
    margin-top: var(--space-2);
}

/* 20.11.11 크기고정 */
textarea {
	resize: none;
}

/*2021-02-08 보고서 : 와이드화면에서 검색부UI 깨지는 오류수정 */
 .sch_wrap{
	max-width: 1000px; /*2021-08-31 보고서 : 모바일에서 여백스크롤되는 문제 수정 (대표님작업) */
	margin-left: var(--space-5);
}

/* 2024.08.09 list_page 기존 style에서 추가 */
#list_page{
    display: flex;
    justify-content: center;
    align-items: center;
}
.div_select {
    position: relative;
    display: inline-block;
    padding-left: var(--space-2_5);
}

.div_select select {
    width: 60px;
    height: 31px;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    border: 1px solid var(--gray-200);
    border-radius: var(--radius-xs);
    font-weight: var(--fw-bold);
    font-size: var(--fs-md);
    line-height: 14px;
    padding-left: var(--space-2_5);
}

.div_select::after {
    content: "\f107";
    font-family: 'Font Awesome 5 Pro';   /* 2026-08-07 표기 통일(구 'Font Awesome 5 pro' — CSS 패밀리명은 대소문자 무시라 동작은 같았음) */
    font-weight: var(--fw-black);
    position: absolute;
    pointer-events: none;
    transform: translate(-160%,60%);
    color: var(--gray-300);
}

.div_select option {
    font-weight: var(--fw-bold);
    font-size: var(--fs-md);
    line-height: 14px;
}

/* 책갈피 컨테이너 (접혀진 상태) */
.bookmark-container {
    position: fixed;
    bottom: 30px;
    right: 0;
    width: 25px;
    height: 100px; /* 접힌 상태 높이 */
    background: var(--color-danger-50);
    border-radius: var(--radius-xl) 0 0 var(--radius-xl);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    transition: width 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55),
                height 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55) 0.25s; /* height는 0.25초 지연 */
    z-index: 1000;
    overflow: hidden;
    animation: pulse 2s infinite;
}

.bookmark-container.expanded {
    width: 500px;
    min-height: 250px;
    height: auto;
    border-radius: var(--radius-2xl) 0 0 var(--radius-2xl);
    animation: none;
    background: white;
    box-shadow: var(--shadow-lg);
    overflow: visible;
    transition: width 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55),
                height 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); /* 펼칠 때는 지연 없음 */
}

.bookmark-container:hover:not(.expanded):not(.collapsing) {
    width: 55px;
    box-shadow: var(--shadow-lg);
    cursor: pointer;
}

/* 접혀진 상태 아이콘 */
.bookmark-icon {
    width: 10px;
    height: 10px;
    position: relative;
    transition: opacity 0.3s ease 0.1s;
    z-index: 2;
    color: var(--txt-disabled);
}

.bookmark-icon::before {
    font-size: var(--icon-md);   /* §11 아이콘 사다리 */
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.bookmark-container.expanded .bookmark-icon {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.2s ease 0s;
}

/* 펼쳐진 상태 컨텐츠 */
.bookmark-content {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.3s ease 0s, visibility 0s linear 0.3s;
    padding: var(--space-5);
    box-sizing: border-box;
}

.bookmark-container.expanded .bookmark-content {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition: opacity 0.4s ease 0.2s, visibility 0s linear 0s;
}

/* 펼쳐진 상태 컨텐츠 */
.bookmark-title {
    font-size: var(--fs-lg);
    font-weight: var(--fw-semibold);
    color: var(--gray-700);
    margin-bottom: var(--space-2);
    border-bottom: 1px solid var(--gray-200);
    padding: var(--space-2_5) 0px;
}

.bookmark-message {
    font-size: var(--fs-md);
    color: var(--gray-500);
    line-height: 1.6;
    margin-bottom: var(--space-5);
    padding: var(--space-2_5) 0px;
    min-height: 80px;
}

.bookmark-message .highlight-date {
    color: var(--color-indigo-700);
}

/* 버튼 그룹 */
.bookmark-container .button-group {
    display: flex;
    gap: var(--space-2_5);
    cursor: pointer;
}

.bookmark-container .btn-tooltip {
    padding: var(--space-3) var(--space-4);
    border: none;
    border-radius: var(--radius-lg);
    font-size: var(--fs-md);
    font-weight: var(--fw-medium);
    cursor: pointer;
    transition: all 0.3s ease;
    text-align: center;
}

.bookmark-container .btn-close {
    flex: 0.5;
    background: var(--gray-100);
    color: var(--gray-500);
}

.bookmark-container .btn-close:hover {
    background: var(--gray-100);
}

.bookmark-container .btn-send {
    flex: 1;
    background: linear-gradient(135deg, var(--color-indigo-500) 0%, var(--color-purple-800) 100%);
    color: white;
}

.bookmark-container .btn-send:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-lg);
}

/* ============================================================
   레거시 공통 레이아웃 클래스 (write 폼 공통 — 복수 모듈 사용)
   ============================================================ */
.last  { border-left: 0px; padding: 0px 0px var(--space-4) var(--space-4); }

.circle {
    background: url(/img/page/circle_gray.png) no-repeat;
    width: 25px; height: 25px;
    position: relative; left: -26px; top: 24px;
    margin-top: calc(var(--space-6) * -1); line-height: 20px;
    padding: 1.3px 0px 0px var(--space-2);
    font-size: var(--fs-sm); color: var(--bg-card); font-weight: bold;
}

.edit_one   { width: 100%; float: left; padding: var(--space-1) 0px; }

/* .main_title_sub → popup.css 로 일원화(팝업 전용 · 2026-07-29) */
/* ⚠ .main_more 는 «더보기» **텍스트 링크의 스타일이자 동시에 JS 훅**이다
 *   (buysell/script.js 가 `$('.main_more').click` 으로 잡고 id 로 분기한다 — 지우면 «시술/상품 추가» 가 죽는다).
 *   그런데 이 규칙이 버튼에도 걸려 `float:right · width:10%(POS 30%) · 밑줄` 을 씌웠다 —
 *   §12-4 «버튼 크기를 제 이름으로 다시 정하지 않는다» 가 지목한 바로 그 클래스다(2026-08-21 사용자 지적).
 *   훅은 남기고 **스타일이 버튼을 잡지 않게** 범위를 좁힌다. */
.main_more:not(.bi-btn) { float: right; color: var(--color-info-600); font-size: var(--fs-base); text-decoration: underline; width: 10%; text-align: right; cursor: pointer; }

.text-form  { float: left; width: 100%; margin-top: var(--space-2_5); }
.text-head  { float: left; padding: 0px 0px 0px var(--space-3_5); font-size: var(--fs-base); color: var(--gray-400); }
.text-body  { float: left; }

.ul-style        { font-size: var(--fs-base); padding: 0px; margin: var(--space-2_5) 0px 50px 0px; }
.li-style        { list-style: none; padding: var(--space-1_5); float: left; width: 98%; }
.li-style-span-p { padding-left: var(--space-2_5); }
.li-style-span-r { float: right; }

textarea: :placeholder { color: var(--gray-500); font-weight: lighter; font-size: var(--fs-base); border: none; }

/* 애니메이션 */
@keyframes pulse {
    0%, 100% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.1);
    }
}

@keyframes blink {
    0%, 100% {
        opacity: 1;
    }
    50% {
        opacity: 0.5;
    }
}

/* ============================================================
   2. 전역 베이스
   ============================================================ */

/* docs/71 Phase 2: body(Inter+bg-page) 정의를 style.css 로 통합 (중복 제거) */

input[type="text"],
input[type="password"],
textarea,
select,
button {
    font-family: var(--font-sans);
}

/* ── 이미지 기본 규격 (§40-22) ──────────────────────────────────────
 * 사용자 2026-08-12: "이미지 등 크기 규격이 없어서 그런 거야?? 화면에 이미지로 꽉 차서 다 깨져"
 * 그동안 이미지에 대한 규격이 **하나도 없었다**. 원본 픽셀 크기 그대로 그려지니
 * 큰 사진 하나가 칸을 밀어내고 레이아웃을 깨뜨린다.
 * 규격: 이미지는 **담긴 칸을 넘지 않는다**. 비율은 유지한다.
 *   담는 방식이 필요하면 .bi-img-cover(칸을 채우고 잘라냄) / .bi-img-fit(다 보이게 맞춤).
 * ──────────────────────────────────────────────────────────────── */
/* ⚠ `height: auto` 는 **<img> 에만** 준다.
 *   svg 에 주면 크기를 안 정한 인라인 svg(로그인 로고)가 viewBox 비율대로 부풀어
 *   화면을 통째로 덮는다 — 실제로 그렇게 깨졌다(2026-08-12 사용자 보고).
 *   svg 는 "칸을 넘지 않는다" 까지만. 크기는 그 자리의 규격이 정한다. */
img, video, canvas {
    max-width: 100%;
    height: auto;
}
svg { max-width: 100%; }
img { vertical-align: middle; }
/* 로고 마크 — 크기를 안 정한 인라인 svg 가 기대는 규격 */
.bi-logo-mark { width: 44px; height: 44px; flex-shrink: 0; }
.bi-img-cover { width: 100%; height: 100%; object-fit: cover; display: block; }
.bi-img-fit   { width: 100%; height: 100%; object-fit: contain; display: block; }
.bi-img-round { border-radius: var(--radius-lg); }

/* bare h1~h5 — dhtmlx samples/common/index.css 제거(docs/71 Phase 1) 시 무회귀 보존.
   클래스 지정 제목(.bi-*-title 등)은 특이도로 우선하므로 영향 없음. */
h1, h2, h3, h4, h5 {
    color: color-mix(in srgb, var(--black) 70%, transparent);
    font-weight: var(--fw-medium);
}

/* ============================================================
   3. 레이아웃 보정 (레거시 override)
   ============================================================ */

/* 헤더 색상·높이 — erp: 로고는 사이드바로 이동 → 헤더는 사이드바 우측(left:256)부터 */
.header {
    /* docs/71 Phase 4: 원본 .header 병합 (computed 동일, !important 제거). position/top/float 는 원본 고유 */
    background: var(--bg-card);
    border-bottom: 1px solid var(--border-base);
    height: var(--header-height);
    left: var(--sidebar-width);
    width: auto;
    right: 0;
    display: flex;
    align-items: center;
    position: fixed;
    top: 0;
    float: left;
}
/* 기존 헤더 내 로고 숨김 (로고는 #menu1 상단으로 이동) */
.header .logo { display: none; }

/* 로고 영역 = 사이드바 상단 브랜드 (260702 리뉴얼: 화이트 배경 + 네이비 브랜드) */
.logo {
    /* docs/71 Phase 4: 원본 .logo 병합 (computed 동일, 제거). float/text-align 는 원본 고유 */
    background: var(--brand-navy);
    height: var(--logo-height);
    width: var(--sidebar-width);
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: 0 var(--space-3);
    box-sizing: border-box;
    overflow: hidden;
    transition: width .2s ease;
    float: left;
    text-align: center;
}
.logo-brand { display: flex; align-items: center; min-width: 0; overflow: hidden; }

/* 2026-08 sg2 §40-9: 테넌트 PNG 로고(hesol365 등) 이미지 규격 — 인라인 style 대체 */

/* 접기/펼치기 토글 버튼 (erp PanelLeftClose) — 260702: 화이트 로고 배경에 맞춰 회색 아이콘 */
/* 규격 문서 §12-4 사다리: 아이콘 버튼 = 32. 34 는 근거가 없다
 * (.bi-btn--icon 은 2026-08-13 에 같은 이유로 34→32 로 고쳤는데 셸 버튼이 남아 있었다). */
.menu1-collapse {
    position: relative;
    width: 32px; height: 32px;
    flex-shrink: 0;
    border: none;
    background: transparent;
    color: var(--txt-disabled);   /* 흰 배경 위 gray-400 (mockup 11.png) */
    border-radius: var(--radius-lg);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-md);
    transition: background .15s, color .15s, transform .15s;
}
/* 펼침: 패널 아이콘만 (별/툴팁 숨김) — hover 시 진한 회색 + 연한 배경 */
.menu1-collapse-star { display: none; }
.menu1-collapse-panel { display: flex; align-items: center; justify-content: center; }
.menu1-collapse-tip { display: none; }
.menu1-collapse:hover  { background: var(--border-light); color: var(--txt-muted); transform: scale(1.05); }
.menu1-collapse:active { transform: scale(0.95); }
.menu1-collapse svg { width: 22px; height: 22px; transition: transform .2s ease; display: block; }
.menu1-collapse-star svg { width: 22px; height: 22px; }

/* ── 접힌 상태(sidebar-collapsed): 레이아웃 보정 ── */
#menu1 { transition: width .2s ease; }
.header, .main-form { transition: left .2s ease; }
body.sidebar-collapsed #menu1     { width: 64px; }
body.sidebar-collapsed .logo      { width: 64px; justify-content: center; padding: 0; }
body.sidebar-collapsed .logo-brand { display: none; }
/* 260702: 접힘 기본 = 배지 없이 네이비 별(브랜드 마크, 펼침 로고와 동일 색). hover 시에만 gray-100 배지 + 패널 아이콘 + 툴팁 (22.png / 22_hover.png) */
body.sidebar-collapsed .menu1-collapse {
    width: 40px; height: 40px;
    background: transparent;
    box-shadow: none;
}
body.sidebar-collapsed .menu1-collapse-star  { display: flex; align-items: center; justify-content: center; }
body.sidebar-collapsed .menu1-collapse-star svg .fa-primary   { fill: var(--brand-navy); }
body.sidebar-collapsed .menu1-collapse-star svg .fa-secondary { fill: var(--brand-blue); }
body.sidebar-collapsed .menu1-collapse-panel { display: none; }
/* hover: 배지 밝게 + 패널(펼치기) 아이콘 노출
   ⚠ transform 금지: transform 은 자식 position:fixed 툴팁의 containing block 을 이 버튼으로 만들어
   #menu1/.logo 의 overflow:hidden 에 툴팁이 갇혀 잘림 → scale 대신 배경색 변화로만 hover 강조 */
body.sidebar-collapsed .menu1-collapse:hover {
    background: var(--border-light);
    color: var(--txt-muted);
    box-shadow: none;
}
body.sidebar-collapsed .menu1-collapse:hover .menu1-collapse-star  { display: none; }
body.sidebar-collapsed .menu1-collapse:hover .menu1-collapse-panel { display: flex; }
body.sidebar-collapsed .menu1-collapse:hover .menu1-collapse-panel svg { transform: rotate(180deg); }  /* PanelLeftClose → 펼치기 방향 */
/* :active 의 transform:scale 도 위와 동일 사유(툴팁 clip)로 생략 — 클릭 즉시 펼쳐지므로 불필요 */
/* 접힘 hover 툴팁 "메뉴 펼치기" — 배지 우측 (22_hover.png)
   #menu1/.logo overflow:hidden 에 잘리지 않도록 position:fixed 로 사이드바 밖 배치.
   #menu1 top:0 · logo 높이 64px → 배지(40px) 세로중심 ≈ 32px, 접힘 폭 64px → 우측 약 60px */
body.sidebar-collapsed .menu1-collapse:hover .menu1-collapse-tip {
    display: block;
    position: fixed;
    left: 60px;
    top: 32px;
    transform: translateY(-50%);
    white-space: nowrap;
    background: var(--bg-card);
    color: var(--txt-secondary);
    font-size: var(--fs-sm);
    font-weight: var(--fw-semibold);
    padding: var(--space-1_5) var(--space-2_5);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    z-index: 30;
    pointer-events: none;
}
body.sidebar-collapsed .header    { left: 64px; }
body.sidebar-collapsed .main-form { left: 64px; }

/* 로그인 정보 텍스트 (흰 배경 위) */
.login_info {
    /* docs/71 Phase 4: 원본 .login_info 병합 (computed 동일, !important 제거). float 는 원본 고유 */
    float: left;
    color: var(--txt-secondary);
    font-size: var(--fs-sm);
    padding: 0 0 0 var(--space-3);
    line-height: 1.4;
    white-space: nowrap;
}

/* DB/도메인 표시 (흰 배경 위 — 연하게) */
.pr_domain {
    color: var(--txt-disabled) !important;
    line-height: var(--header-height) !important;
    padding: 0 0 0 var(--space-4) !important;
}

/* 헤더 토글 버튼 (menu_open) — 공간 차지 방지 */
.menu_open {
    /* docs/71 Phase 4: 원본 .menu_open 병합 (float 원본 고유, 0 크기라 사실상 무효) */
    float: left;
    width: 0;
    height: 0;
}

/* 사이드바(메인메뉴) — erp Sidebar: top:0 풀하이트, 상단 브랜드 포함 flex 컬럼 */
#menu1 {
    width: var(--sidebar-width);
    top: 0;
    height: 100vh;
    background: var(--bg-card, var(--bg-card)) !important;
    border-right: 1px solid var(--border-base);
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
    z-index: 20;
}

/* 사이드바(서브메뉴) = erp '전체 메뉴보기' 모달
   ※ 오버레이/컨테이너 위치·크기는 menu.css 의 #menu2.open / .close 가 제어 */
#menu2 { top: 0; }
#menu2_sub { background-color: var(--bg-card, var(--bg-card)); }

/* 메인 콘텐츠 영역 */
.main-form {
    /* docs/71 Phase 4 수정: menu.css .main-form(left:205px/top:65px, position:fixed, 나중 로드)를
       이기려면 필요. position 은 menu.css 가 제공. (겹침 회귀 수정 2026-07-01) */
    left: var(--sidebar-width);
    top: var(--header-height);
}

/* #rectangle 토글 버튼 — 사이드바 우측 끝, 로고 영역 위 */
#rectangle {
    background: var(--brand-navy);
    z-index: 22;
    left: calc(var(--sidebar-width) - 24px);
    height: var(--header-height);
}

/* 드롭다운 메뉴 위치 보정 */
#user_menu     { top: var(--header-height); }
#question_menu { top: var(--header-height); }

/* ── 좌측: 브레드크럼 영역 ───────────────────────── */
.header-bar__left {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding-left: var(--space-4);
    min-width: 0;
    flex-shrink: 1;
}

/* 브레드크럼 선두 레이어 아이콘 (erp: Layers) */
.hbar-crumb-ico {
    color: var(--txt-disabled);
    font-size: var(--fs-md);
    flex-shrink: 0;
}

/* 브레드크럼 텍스트 그룹 */
.hbar-crumb {
    display: flex;
    align-items: center;
    gap: var(--space-1_5);
    font-size: var(--fs-base);
    font-weight: var(--fw-bold);
    min-width: 0;
}
.hbar-crumb-root { color: var(--txt-disabled); font-weight: var(--fw-semibold); white-space: nowrap; }
.hbar-crumb-cat  { color: var(--txt-disabled); font-weight: var(--fw-medium); white-space: nowrap; }   /* 페이지분류(카테고리) */
.hbar-crumb-sep  { color: var(--gray-300); font-size: var(--fs-2xs); flex-shrink: 0; }
.hbar-crumb-cur  {
    color: var(--txt-primary); font-weight: var(--fw-extrabold);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── 정보 pill (사용자 / 날짜 / DB) — erp desc·clock pill 톤 ── */
.hbar-pill {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1_5);
    height: 27px;   /* §12-4 사다리 sm. 26 은 사다리에 없는 값이었다 */
    padding: 0 var(--space-2_5);
    border-radius: var(--radius-full);
    font-size: var(--fs-xs);
    font-weight: var(--fw-bold);
    white-space: nowrap;
    flex-shrink: 0;
    line-height: 1;
}
.hbar-pill i { font-size: var(--fs-xs); }

/* 페이지 설명 pill (자동 문구) — erp desc pill: 작은 회색 + 말줄임 */
.hbar-pill--desc {
    display: inline-block;
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    background: var(--bg-input);
    color: var(--txt-muted);
    border: 1px solid var(--gray-100);
    font-weight: var(--fw-bold);
    font-size: var(--fs-2xs);
    height: 27px;   /* §12-4 사다리 sm. 26 은 사다리에 없는 값이었다 */
    line-height: 24px;
    padding: 0 var(--space-2_5);
    box-sizing: border-box;
    margin-left: var(--space-1_5);
    vertical-align: middle;
}

/* 오늘 날짜 pill (amber — erp clock pill 색감) */
.hbar-pill--date {
    background: color-mix(in srgb, var(--color-warning) 10%, transparent);
    color: var(--color-warning-700);
    border: 1px solid var(--color-warning-100);
}
.hbar-pill--date i { color: var(--color-warning); }

/* ⚠ 2026-10-06 — 긴 «페이지 설명 알약» 이 가운데 통합검색창 밑으로 들어가 글자가 잘렸다(눈 검수에서 발견 · DOM 으로 확인:
   report_employee_pcategory 알약 오른쪽 끝 726 ↔ 검색창 왼쪽 668 = 58px 겹침, report_buysell_method 18px).
   검색창은 헤더 가운데에 «절대배치» 라 레이아웃에 자리를 차지하지 않는다 — 왼쪽 묶음이 검색창 왼쪽 끝까지만 가도록 한도를 둔다.
   .hbar-pill 은 flex-shrink:0 이라 기존 max-width:260 만으로는 줄지 않는다 → 알약이 남는 만큼 줄고 말줄임(…)이 되게 한다.
   짧은 알약·검색창이 숨는 1200px 이하에서는 달라지는 것이 없다. */
.header-bar__left--fit { box-sizing: border-box; max-width: calc(50% - min(180px, 16vw) - var(--space-3)); }
.hbar-pill--fit { flex-shrink: 1; min-width: 0; }

/* erp 통합 검색 pill (헤더 중앙 절대배치) — 클릭/Ctrl+K → 전체메뉴 모달 */
.hbar-search {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 360px;
    max-width: 32vw;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: 0 var(--space-2) 0 var(--space-3);
    background: var(--bg-input);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-lg);
    cursor: pointer;
    color: var(--txt-disabled);
    font-size: var(--fs-sm);
    font-weight: var(--fw-semibold);
    transition: background .15s, border-color .15s, color .15s;
}
.hbar-search:hover { background: var(--border-light); border-color: var(--gray-300); color: var(--txt-muted); }
.hbar-search-left { display: flex; align-items: center; gap: var(--space-2); min-width: 0; overflow: hidden; }
.hbar-search-left i { font-size: var(--fs-sm); flex-shrink: 0; }
.hbar-search-left span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hbar-search-kbd {
    flex-shrink: 0;
    background: var(--bg-card);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-sm);
    padding: var(--space-0_5) var(--space-1_5);
    font-size: var(--fs-xs);
    font-family: var(--font-mono);
    color: var(--txt-disabled);
}
/* 좁은 화면에선 숨김 (브레드크럼/우측과 겹침 방지) */
@media (max-width: 1200px) { .hbar-search { display: none; } }

/* 지점 뱃지 (erp branch indicator) */
.hbar-branch {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1_5);
    height: 27px;   /* §12-4 사다리 sm. 26 은 사다리에 없는 값이었다 */
    padding: 0 var(--space-2_5);
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--color-indigo-500) 10%, transparent);
    border: 1px solid var(--color-indigo-100);
    color: var(--color-indigo-700);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-extrabold);
    letter-spacing: 0.02em;
    white-space: nowrap;
    flex-shrink: 0;
}
.hbar-branch-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--color-indigo-500);
    flex-shrink: 0;
    animation: hbar-branch-pulse 1.6s ease-in-out infinite;
}
@keyframes hbar-branch-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }

/* 동기화(새로고침) 버튼 (erp sync) */
.hbar-sync {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1_5);
    height: 27px;   /* §12-4 사다리 sm. 26 은 사다리에 없는 값이었다 */
    padding: 0 var(--space-2_5);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    color: var(--txt-muted);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-extrabold);
    cursor: pointer;
    white-space: nowrap;
    flex-shrink: 0;
    transition: background .15s, border-color .15s;
}
/* ⚠ 2026-09-29 — 이 자리가 <button>(동기화)에서 <a>(Try on)로 바뀜다.
   그러자 전역 링크 스타일의 밑줄이 붙어 옆 배지들과 모양이 갈렸다.
   기존 .hbar-sync 규칙은 고치지 않고(§4) <a> 일 때만 밑줄을 눠낸다. */
a.hbar-sync, a.hbar-sync:hover { text-decoration: none; }
.hbar-sync:hover { background: var(--gray-50); border-color: var(--gray-300); }
.hbar-sync i { font-size: var(--fs-xs); color: var(--txt-disabled); }
.hbar-sync.is-syncing i { animation: hbar-spin .7s linear infinite; }
@keyframes hbar-spin { to { transform: rotate(360deg); } }

/* ══ 헤더 TryOn 단추 (2026-09-29 사용자 지시) ══
   「TryOn 으로 버튼명 변경하고 … 사이트 로고에 맞게 버튼 및 글자 색 변경해줘」

   tryon 사이트 로고는 «Try» 가 먹빛(#0F172A) · «On» 이 분홍(#EC4899) 두 색이다.
   그래서 글자를 두 토막으로 나눠 각각 입힌다.
   바탕·테두리도 그 사이트에서 가져왔다 — 칩 바탕(pink-50) + 분홍 테두리라
   헤더의 흰 배지들 사이에서 «다른 서비스로 나가는 길» 임이 한눈에 보인다.
   ⚠ «On» 글자만 --tryon-pink 가 아니라 --tryon-pink-dk(#DB2777)를 쓴다.
      로고의 #EC4899 는 «흰 바탕» 위의 값이다. 연분홍(#FDF2F8) 위에 그대로 얹으면
      대비가 3.2:1 로 떨어져 작은 글자가 흐려진다. 그 사이트도 같은 자리
      (분홍 칩 = pink-50 바탕)에서는 글자를 #DB2777 로 쓴다 — 재서 확인한 값이다.
   ⚠ 기존 .hbar-sync 규칙은 고치지 않는다(§4) — 뒤에 덧입히는 클래스를 따로 둔다. */
.hbar-tryon {
    border-color: var(--tryon-line);
    background: var(--tryon-surface);
    color: var(--tryon-ink);
}
.hbar-tryon:hover {
    background: color-mix(in srgb, var(--tryon-pink) 14%, transparent);
    border-color: var(--tryon-pink);
}
.hbar-tryon i                    { color: var(--tryon-pink-dk); }
.hbar-tryon .hbar-tryon__try     { color: var(--tryon-ink); }
.hbar-tryon .hbar-tryon__on      { color: var(--tryon-pink-dk); }
/* 덮였을 때는 글자색을 바꾸지 않는다 — 바탕이 한 톤 짙어지고 테두리만 또렷해진다.
   ⚠ 2026-09-29 사용자 지적 「테두리가 너무 튀어」. 처음엔 테두리를 로고 분홍(#EC4899)
      원색으로, 덮으면 분홍을 꽉 채웠다 — 헤더의 흰 배지들 사이에서 혼자 소리쳤다.
      옆 날짜 pill 이 «10% 바탕 + X-100 테두리 + X-700 글자» 인 것과 **같은 세기**로 맞춘다. */
/* 좁은 화면에서 .hbar-sync span 이 숨는다 — 글자 두 토막도 같이 숨어 아이콘만 남는다 */

/* ── §101 구 사이트 이동 (2026-10-01 사용자 지시) ──────────────────────────
   「crm 로그인인지 shop 로그인인지에 따라 구 사이트이동 버튼을 추가 … 지점명 좌측」
   ⚠ 기존 .hbar-sync 규칙은 고치지 않는다(§4) — 뒤에 덧입히는 클래스를 따로 둔다.
      TryOn(.hbar-tryon)과 **같은 방식**이다.
   ⚠ 색은 일부러 수수하게 둔다. TryOn 은 «새로 쓰라고 권하는 길» 이라 분홍으로 부르지만,
      구 사이트는 «가끔 되돌아가는 길» 이다. 둘이 같은 세기로 서면 어느 쪽이 지금 길인지
      헷갈린다 — 회색 계열로 한 걸음 물러서게 한다. */
.hbar-oldsite {
    border-color: var(--border-base);
    background: var(--bg-card);
    color: var(--txt-secondary);
}
.hbar-oldsite:hover {
    background: var(--gray-50);
    border-color: var(--gray-400);
    color: var(--txt-primary);
}
/* ⚠ 2026-10-01 — 여기 `.hbar-oldsite i { color: var(--txt-tertiary) }` 를 적었다가 **걷었다.**
   ① `--txt-tertiary` 는 **없는 토큰**이다(있는 것은 primary·secondary·muted·disabled·inverse).
      폴백도 없어 **선언이 통째로 무효**였다 — L1 정적 검사(TK-UNDEF)가 잡아 주었다.
   ② 그리고 **있을 필요도 없었다.** `.hbar-sync i`(:1750)가 이미 `--txt-disabled` 를 준다.
      무효라서 그쪽으로 떨어져 있었고, 그래서 화면은 «멀쩡해 보였다» — 눈으로는 못 잡는 꼴이다.
   → 덧쓸 까닭이 없으면 **줄을 더하지 않는다.** 옆 TryOn 도 아이콘 색은 밑바탕을 그대로 쓴다. */

/* 좁은 화면 보조 정리 */
@media (max-width: 1440px) { .hbar-sync span { display: none; } .hbar-sync { padding: 0 var(--space-2); } }
@media (max-width: 1280px) { .hbar-branch { display: none; } }

/* 지점선택 (level 99) — 인라인 float/padding 중화 + 정렬
   ※ display 는 인라인/JS 가 제어하므로 건드리지 않음 */
#s_br.search_div_add {
    float: none !important;
    padding: 0 !important;
    width: auto !important;
    margin: 0 0 0 var(--space-2) !important;
    align-items: center;
}
#s_br.search_div_add select {
    height: 32px;
    border: 1px solid var(--border-base);
    border-radius: var(--radius-lg);
    font-size: var(--fs-sm);
    color: var(--txt-secondary);
    padding: 0 var(--space-2);
    background: var(--bg-card);
}

/* ── 우측: 기능 아이콘 그룹 ─────────────────────── */
.header-actions {
    display: flex;
    align-items: center;
    gap: var(--space-1_5);
    margin-left: auto;
    flex-shrink: 0;
    padding-right: var(--space-4);
}

/* 그룹 구분선 (pill 묶음 ↔ 아이콘 묶음) */
.header-actions__sep {
    width: 1px;
    height: 22px;
    background: var(--border-base);
    margin: 0 var(--space-0_5);
    flex-shrink: 0;
}

/* 아이콘 버튼 — erp: rounded-lg + subtle border + gray-400, hover:bg-slate-50 + press-down */
/* 아이콘 버튼 = 32 (§12-4 사다리). 헤더도 같은 사다리를 쓴다 — 셸만 예외일 이유가 없다. */
/* ⚠ 이 프로젝트엔 «*{box-sizing:border-box}» 같은 전역 규칙이 없다 — 규칙마다 따로 적는다.
 * 그래서 여기 height:32px 은 **테두리 1px×2 가 밖에 붙어 실측 34** 였다(§12-4 사다리 --icon 은 32).
 * 눈에 안 띄는 2px 이지만 사다리에 없는 값이라 검사가 매번 잡는다(2026-08-21). */
.header-icon-btn {
    box-sizing: border-box;
    width: 32px;
    height: 32px;
    border-radius: var(--radius-lg);
    border: 1px solid color-mix(in srgb, var(--border-base) 70%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    color: var(--txt-disabled);
    font-size: var(--fs-md);
    background: var(--bg-card);
    position: relative;
    transition: background .15s, color .15s, border-color .15s, transform .15s;
    flex-shrink: 0;
}
.header-icon-btn:hover {
    background: var(--gray-50);
    color: var(--gray-600);
    border-color: var(--border-base);
}
.header-icon-btn:active { transform: scale(0.94); }

/* ── 반응형: 좁은 화면에서 보조 pill 숨김 ── */
@media (max-width: 1280px) { .hbar-pill--desc { display: none; } }
@media (max-width: 1100px) { .hbar-pill--date { display: none; } }

/* ============================================================
   5. 스크롤바 (enterprise 스타일)
   ============================================================ */
::-webkit-scrollbar       { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--gray-300); border-radius: var(--radius-sm); }
::-webkit-scrollbar-thumb:hover { background: var(--txt-disabled); }

/* ============================================================
   6. 모듈 공통 — 리뉴얼 페이지 래퍼
   ============================================================ */
/* 리뉴얼된 list 페이지 최상위 래퍼
 * padding+gap 으로 내부 섹션 간 16px 여백 제공 (bi-card margin 불필요)
 */
.bi-page {
    display: flex;
    flex-direction: column;
    height: calc(100vh - var(--header-height));
    box-sizing: border-box;        /* padding(상하 32px)이 height 안에 포함 — 하단 패딩 화면 밖 이탈 방지 */
    overflow: hidden;
    background: var(--bg-page);
    padding: var(--content-pad);
    gap: var(--space-4);
}
/* 리뉴얼된 write 페이지 최상위 래퍼
 * bi-page 와 동일하게 padding:16px — 흰 bi-card 주변에 gray var(--bg-page) 프레임 노출 */
.bi-write-page {
    display: flex;
    flex-direction: column;
    height: calc(100vh - var(--header-height));
    box-sizing: border-box;        /* padding 포함 — 하단 패딩 화면 밖 이탈 방지 */
    overflow: hidden;
    background: var(--bg-page);
    padding: var(--content-pad);
}

/* ============================================================
   §40-10 레이아웃 프리미티브 (2026-08-07 신설)
   ------------------------------------------------------------
   왜: 규격에 "가로 한 줄" 프리미티브가 없어서 모듈마다 새 이름으로 다시 만들고 있었다.
       QC SG-RELOCATED 43건 중 22건이 아래 6가지 선언의 재발명이었다
       (`display:flex; align-items:center; justify-content:space-between` 하나만 10개 모듈·클래스).
   원칙: **역할 이름이 필요하면 모듈 클래스를 남기되(JS 훅·가독성), 레이아웃은 이 프리미티브를 쓴다.**
         `<div class="bi-row-between bi-row-between">` 처럼 병기하고,
         모듈 style.css 에서 레이아웃 선언은 지운다.
   ============================================================ */

/* 가로 한 줄 — 세로 가운데 정렬 + 간격. 간격은 --bi-row-gap 으로 조절(기본 8px). */
.bi-row            { display: flex; align-items: center; gap: var(--bi-row-gap, 8px); }
.bi-row--gap-4     { --bi-row-gap: 4px; }
.bi-row--gap-6     { --bi-row-gap: 6px; }
.bi-row--gap-12    { --bi-row-gap: 12px; }
.bi-row--wrap      { flex-wrap: wrap; }

/* 양끝 배치(라벨 ↔ 값, 제목 ↔ 액션) — 간격 없음. 가장 많이 재발명되던 형태. */
.bi-row-between    { display: flex; align-items: center; justify-content: space-between; }
/* 가운데 배치 */

.bi-row--gap-0     { --bi-row-gap: 0; }
/* 2026-08-11 추가 — SPEC-DUP 이 드러낸 재발명을 흡수하려니 척도에 구멍이 있었다.
 * 토큰 간격(--space-2_5=10 · --space-4=16)에 대응하는 row/col 변형이 없어서
 * 컴포넌트마다 display:flex;gap:… 를 다시 쓰고 있었다. */
/* 세로 정렬 변형 — .bi-row 는 center 고정이라 baseline/stretch 가 필요하면 재발명됐다 */
.bi-row--align-baseline { align-items: baseline; }
.bi-row--align-stretch  { align-items: stretch; }
/* flex 자식이 내용 때문에 안 줄어드는 것 방지. .bi-fill 과 달리 **늘리지는 않는다**. */
.bi-minw-0         { min-width: 0; }

/* 초기 숨김 — 2026-08-07 신설. `style="display:none"` 인라인이 128곳이었다(절대규칙 §4 위반).
 * ⚠ `` 를 **쓰지 않는다** — jQuery `.show()` 가 인라인 display 로 덮어써야 열린다.
 *   (스코프판 `#counter_portal .is-hidden` 은 라 show() 가 안 먹는다. 그 전철 금지.)
 * ⚠ 이름이 `.is-hidden` 이 아닌 이유: `.bi-ra-col-list__item.is-hidden` 이 '숨김'이 아니라
 *   '흐리게+취소선' 의미로 이미 쓰고 있어, 전역화하면 그 항목들이 사라진다. */
/* .bi-hidden 정의는 파일 맨 끝으로 이동(2026-08-11) — 아래 §HIDDEN 참조 */

/* 세로 쌓기 — 간격은 --bi-col-gap(기본 8px) */
.bi-col            { display: flex; flex-direction: column; gap: var(--bi-col-gap, 8px); }
.bi-col--gap-0     { --bi-col-gap: 0; }
/* 2026-08-11 — row 에는 --gap-4 가 있는데 col 에는 없었다. 그 비대칭을 못 보고
 * .bi-col--gap-4 를 쓰는 바람에 필드 간격이 4px→8px 로 벌어졌다(CLASS-ORPHAN 이 잡았다). */
.bi-col--gap-4     { --bi-col-gap: 4px; }
.bi-col--gap-6     { --bi-col-gap: 6px; }
.bi-col--gap-12    { --bi-col-gap: 12px; }
.bi-col--gap-16    { --bi-col-gap: 16px; }   /* 2026-08-11 — --space-4 대응이 없어 재발명됐다 */
.bi-col--grow      { flex: 1; min-height: 0; }

/* 가로 남는 공간 채우기 — flex 자식이 넘치지 않게(min-width:0 필수) */
.bi-fill           { flex: 1; min-width: 0; }
/* 상태 점(색은 쓰는 쪽에서) */
.bi-dot            { width: 6px; height: 6px; border-radius: var(--radius-full); display: inline-block; }

/* ============================================================
   8. 공통 버튼 (list + write 페이지 공용)
   ============================================================ */
.bi-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1_5);
    padding: var(--space-2) var(--space-4);
    font-size: var(--fs-md);
    font-weight: var(--fw-semibold);
    font-family: var(--font-sans);
    border-radius: var(--radius-lg);
    border: 1px solid transparent;
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s, box-shadow .15s, transform .15s;
    line-height: 1;
    white-space: nowrap;
    background: none;
}
/* 2026-09-02 — <a class="bi-btn"> 는 «링크» 라서 브라우저가 밑줄을 긋는다.
   사용자가 「지급율 찾기」 에서 봤지만, 글자 있는 a 버튼이면 어디서나 같은 일이 난다
   (돋보기처럼 아이콘만 있는 것은 밑줄이 안 보여 지금까지 드러나지 않았을 뿐이다).
   기존 .bi-btn 선언은 그대로 두고 뒤에서 못박는다 — 버튼 모양에 밑줄이 있으면 링크로 읽힌다. */
a.bi-btn, a.bi-btn:hover, a.bi-btn:focus{ text-decoration: none; }
/* erp-design 인터랙션: hover-lift 대신 press-down (active:scale-98) + disabled 상태 (2026-06-11) */
.bi-btn:active:not(:disabled):not(.is-disabled) { transform: scale(var(--press-scale, 0.98)); }.bi-btn--sm  { padding: var(--space-1_5) var(--space-3); font-size: var(--fs-base); border-radius: var(--radius-md); }
/* ── 크기 사다리 (2026-08-13 역전 교정) ───────────────────────────────
 * 사다리는 **한 방향**이어야 한다. 고치기 전 실측은 base 32 · sm 27 · **xs 30** 이었다 —
 * xs 의 세로 여백(8px)이 sm(6px)보다 커서 «가장 작은 것»이 sm 보다 컸다.
 * 같은 툴바에 sm 과 xs 가 같이 놓이면 작아야 할 쪽이 커 보였다(사용자 지적 2026-08-13).
 *   base 32px(14px) · sm 27px(13px) · xs 22px(12px) · lg 48px(15px)
 *
 * ⚠ 2026-08-21 «목록 버튼이 너무 작다»(사용자 지적, 고객관리 엑셀다운·정보등록·정보수정 …).
 *   실측: xs 22px / 글자 12 / 아이콘 12. 같은 화면의 그리드 한 행이 **37px**, 입력칸 36,
 *   검색 버튼 32, 옆의 「표시항목」이 27 — 즉 **행보다 작고, 부수 버튼보다도 작았다.**
 *   클릭 표적도 22px 로 최소치(24) 미만.
 *   전수조사 결과 .bi-btn--xs 는 **목록 list.php 156곳 + write.php 저장/취소 10곳** 이 전부고
 *   **그리드 셀·팝업·JS 템플릿에는 한 번도 쓰이지 않는다** — «작은 버튼» 이 아니라
 *   사실상 «목록 툴바 버튼» 이었다. → 정의를 base(32) 로 올린다. 63모듈이 동시에 맞는다.
 *   같은 줄에 서는 「표시항목」·퀵기간·상태탭도 32 로 맞춰 «한 줄엔 한 크기» 를 지킨다.
 *   이름은 남긴다(마크업 156곳). 새 코드는 그냥 .bi-btn 을 쓴다.
 * ─────────────────────────────────────────────────────────────────── */
.bi-btn--xs  {
    height: 32px;
    padding: 0 var(--space-3);
    font-size: var(--fs-base);
    border-radius: var(--radius-lg);
    font-weight: var(--fw-medium);
}
/* 아이콘은 글자보다 1px 커야 «아이콘» 으로 읽힌다 — 12/12 는 얼룩처럼 보였다 */
.bi-btn--xs > i { font-size: 14px; }

/* erp-design: bg-brand-blue hover:bg-blue-600 active:bg-blue-700 rounded-lg shadow-sm active:scale-98 (hover-lift 폐지) */
.bi-btn--primary            { background: var(--brand-blue); color: var(--bg-card); border-color: var(--brand-blue); font-weight: var(--fw-bold); }
.bi-btn--primary:hover      { background: var(--color-info-600); border-color: var(--color-info-600); }
.bi-btn--primary:active     { background: var(--color-info-700); border-color: var(--color-info-700); }

.bi-btn--ghost              { background: var(--bg-card); color: var(--gray-600); border-color: var(--border-base); font-weight: var(--fw-medium); }
.bi-btn--ghost:hover        { background: var(--bg-input); border-color: var(--border-base); }

.bi-btn--danger             { background: var(--color-danger); color: var(--bg-card); border-color: var(--color-danger); }
.bi-btn--danger:hover       { background: var(--color-danger-600); border-color: var(--color-danger-600); }
.bi-btn--danger-soft        { background: var(--color-danger-50); color: var(--color-danger-600); border-color: var(--color-danger-100); font-weight: var(--fw-medium); }
.bi-btn--danger-soft:hover  { background: var(--color-danger-100); border-color: var(--color-danger-200); }

/* 2026-07-30 bespoke 워크플로우 화면(reception/designer_chart/booking/main 등) 반복 버튼 패턴 공통 변형 */
.bi-btn--navy               { background: var(--brand-navy); color: var(--bg-card); border-color: var(--brand-navy); }
.bi-btn--navy:hover         { background: var(--brand-blue-hover); border-color: var(--brand-blue-hover); }
.bi-btn--navy:active        { background: var(--brand-blue); }
/* 신규 등록(soft rose) — reception/designer_chart 신규등록 버튼 동일 패턴 */
.bi-btn--register           { background: var(--color-rose-50); color: var(--color-rose-700); border-color: var(--color-rose-200); font-weight: var(--fw-extrabold); }
.bi-btn--register:hover     { background: var(--color-rose-100); border-color: var(--color-rose-200); }
.bi-btn--block              { width: 100%; justify-content: center; }
/* 2026-07-31 아이콘 전용 정사각 버튼(예약추가·검색추가 등 반복 패턴) — .bi-btn + 색상변형과 조합. 크기/라운드는 모듈 델타 */
.bi-btn--icon               { width: 32px; height: 32px; padding: 0; justify-content: center; }  /* 2026-08-13 기본 사다리(32px)와 맞춤 — 34 는 근거가 없었다 */

/* 세그먼트 컨트롤(탭형 토글) — reception rtab/seg · designer_chart statseg/rtab · booking viewseg 공통
 * ⚠ 2026-08-14 — 이 블록은 «자리·정렬» 만 맡는다. 색·크기·트랙은 **아래 §pickgrid 옆의 한 곳**이
 *   규격이다(문서 §29: 활성 = brand-blue 배경 + 흰글자, 트랙은 연회색).
 *   여기서 배경·글자색을 또 정하면 두 정의가 싸운다 — 실제로 그랬고, 뒤엣것이 이기고 있었다. */
.bi-segment__btn            { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1); transition: all .15s; }
/* 활성 칸은 배경이 brand-blue 다 — 아이콘까지 brand-blue 로 칠하면 파랑 위 파랑이 되어 사라진다.
 * 글자와 같은 색을 물려받게 둔다. */
.bi-segment__btn.is-active i{ color: inherit; }

/* ============================================================
   11. 페이지 레벨 통합 카드
   ============================================================ */
/*
 * toolbar + search + grid + pagination 전체를 하나의 카드로 묶는다.
 *
 * ⚠ 2026-08-11 B0-2: 아래 예시의 .bi-card / .bi-toolbar / .bi-table-card 는 **폐기 이름**이다.
 *   현행 규격은 §40-3 표준 레이아웃:
 *     <div class="bi-page">
 *       <div class="bi-erp-toolbar">          (변형 없음 — 모든 화면이 같은 헤더, 2026-08-21)
 *       <div class="bi-erp-filter">
 *       <div class="bi-erp-card"> <div class="bi-grid-area"> + <div class="bi-pg-wrap">
 *     </div>
 *
 * margin:16px 이 bi-page 의 gray 배경(var(--bg-page))을 카드 주변에 노출.
 */
/*
 * bi-page { padding: 16px } 가 외부 여백을 제공하므로 margin: 0
 */
/* elevated 카드 셸(자기완결 — flex:1 미강제) : bespoke 화면(reception/main/booking 등) 흰 카드 공통. radius-2xl + 강조 그림자. 성장/폭은 모듈 모디파이어(flex/width)로. (2026-07-30) */
.bi-card--box {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--bg-card);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-2xl);
}

/* ── 인페이지 모달 쉘 (공용) — 모듈들이 각자 오버레이+패널을 재구현하던 것 통합(2026-07-31).
   모듈은 .bi-modal-ov(백드롭) + .bi-modal(패널) + .bi-modal__body 를 쓰고, 헤더는 공용 .bi-pop-head,
   푸터/버튼은 .bi-pop-foot-btns/.bi-pop-btn. 크기·내용만 모듈 modifier. JS 는 id 로 .is-open 토글. ── */
.bi-modal-ov { display: none; position: fixed; inset: 0; z-index: 1000; background: color-mix(in srgb, var(--black) 60%, transparent); backdrop-filter: blur(2px); align-items: center; justify-content: center; padding: var(--space-4); }
.bi-modal-ov.is-open { display: flex; }
.bi-modal { background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-xl); width: 100%; max-width: 440px; box-shadow: var(--shadow-lg); overflow: hidden; display: flex; flex-direction: column; max-height: 90vh; text-align: left; }

/* ============================================================
 * bi-log-* — 관리자 로그 7개 모듈 공통 (2026-06-09)
 * 사용: log_login / log_buysell / log_buysell_products / log_buysell_package
 *      log_bk_buysell / log_bk_buysell_products / log_bk_payments
 * ============================================================ */

/* 7탭 nav */
.bi-log-tabs {
    display: flex; flex-wrap: wrap; gap: var(--space-1);
    background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-xl);
    padding: var(--space-1_5);
}
/* 로그 화면 탭 — 규격 문서에 «이름» 은 등재돼 있었지만 **크기가 없어** 35px 로 그려지고 있었다.
 * 탭도 버튼이다 → §12-4 사다리 base 32(2026-08-14). 가로로 늘어나는 성격(flex)만 제 것이다. */
.bi-log-tab {
    flex: 1 1 auto; min-width: 110px;
    height: 32px;
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0 var(--space-3_5);
    background: transparent; border: 0; border-radius: var(--radius-lg);
    font-size: var(--fs-base); font-weight: var(--fw-medium); color: var(--txt-muted);
    cursor: pointer;
    transition: background .15s, color .15s;
}
.bi-log-tab:hover { background: var(--border-light); color: var(--txt-primary); }
.bi-log-tab.is-active { background: var(--brand-navy); color: var(--bg-card); font-weight: var(--fw-semibold); cursor: default; }

/* 검색 row 추가 요소 */
.bi-log-date-input    { width: 130px; }
.bi-log-date-sep      { color: var(--txt-muted); margin: 0 var(--space-1); }

/* 결과 테이블 (ul/li grid) */
.bi-log-table-body { overflow: auto; flex: 1; min-height: 0; }
.bi-log-row {
    display: grid;
    align-items: center;
    text-align: center;
    border-bottom: 1px solid var(--border-light);
    list-style: none; margin: 0; padding: 0;
    grid-template-columns: repeat(7, minmax(80px, 1fr));   /* default */
}
.bi-log-row li { font-size: var(--fs-base); padding: var(--space-3) var(--space-1_5); word-break: break-all; }
.bi-log-row--head {
    background: var(--bg-input);
    font-weight: var(--fw-semibold); color: var(--txt-secondary);
    border-bottom: 1px solid var(--border-base);
    position: sticky; top: 0; z-index: 2;
}
.bi-log-row--head li { padding: var(--space-3_5) var(--space-1_5); font-size: var(--fs-base); }

/* 컬럼 수 modifier (원본 style.css grid-template-columns 보존) */
.bi-log-row--w15  { grid-template-columns: repeat(15, minmax(80px, 1fr)); }
.bi-log-row--w21  { grid-template-columns: repeat(21, minmax(80px, 1fr)); }

/* 컬럼 다수 → 가로 스크롤 (좁은 화면) */
.bi-log-table-wrap--w15 .bi-log-row, .bi-log-table-wrap--w21 .bi-log-row {
    min-width: max(100%, calc(80px * var(--cols, 18)));
}
.bi-log-table-wrap--w15 .bi-log-table-body, .bi-log-table-wrap--w21 .bi-log-table-body { overflow-x: auto; }

.bi-log-empty {
    padding: 80px var(--space-5);
    text-align: center;
    color: var(--txt-disabled);
    font-size: var(--fs-md);
}

@media (max-width: 1280px) {
    .bi-log-tab { min-width: 90px; font-size: var(--fs-sm); padding: var(--space-2) var(--space-2_5); }
    .bi-log-row li { font-size: var(--fs-sm); padding: var(--space-2_5) var(--space-1); }
}

/* ============================================================
 * bi-bm-* — AI 마케팅 제안 책갈피 (footer.php) — 2026-06-30 리뉴얼
 * 우하단 FAB(접힘) + 둥근 카드(펼침). 구 .bookmark-* (style.css) 위에 덮어쓰기.
 * JS 훅(#bookmarkContainer / .expanded / .bookmark-content / #bookmarkMessage) 불변.
 * ============================================================ */

/* FAB 알림 점 + 펄스 링 */
@keyframes bi-bm-pulse {
    0%   { transform: scale(0.8); opacity: 0.8; }
    100% { transform: scale(1.9); opacity: 0; }
}
@keyframes bi-bm-fab-float {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-4px); }
}

/* ── 펼침: 카드 ── */
@keyframes bi-bm-card-in {
    from { opacity: 0; transform: translateY(10px) scale(0.98); }
    to   { opacity: 1; transform: none; }
}

/* 좁은 화면: 카드 폭 축소 */
@media (max-width: 480px) {
}

/* ── 로딩 오버레이 (구 ai_marketing/booking_renew/employee_dayoff 중복) ── */
/* §36 로딩 오버레이 — "로딩은 기존 화면을 지우지 않는다. 겹쳐 표시한다"(규격 §36).
   2026-08-11: 구 `#load_img`(id 셀렉터) → 규격 클래스. id 는 JS 훅이라 마크업에 유지.
   ⚠ `display:block` 을 뺐다 — div 는 원래 block 이고, 이게 있으면 특이도 100(id)으로
     `.bi-hidden`(10)을 이겨 **초기 렌더에서 로딩막이 걷히지 않았다**(2026-08-07 158fe27 이후 실제 발생). */
.bi-loading {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: var(--bg-card);
    opacity: 0.8;
    text-align: center;
    z-index: 99;
}
.bi-loading > img {
    position: absolute;
    top: 45%;
    left: 50%;
    width: 30px;
    height: 30px;
    z-index: 100;
}

/* ── 마케팅 검색 필드 (구 marketing/marketing2/marketing_point 중복) ── */
.bi-marketing-range-group {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1_5);
    font-size: var(--fs-base);
    color: var(--txt-secondary);
}
/* 숫자 입력(우측 정렬 고정폭) — 이름의 marketing 은 처음 쓴 곳일 뿐 범용이다.
 * 2026-08-11 팝업에서도 같은 것이 필요해 .bi-pop-amt-in 을 만들 뻔했다 → 이걸 쓴다. */
/* 구 .bi-num-input — §21-3 입력 눈금으로 흡수(2026-08-11) */
/* 구 .bi-marketing-num-input — 마크업을 .bi-num-input 으로 옮기고 제거(2026-08-11) */
.bi-marketing-money-input { width: 110px; text-align: right; }
.bi-marketing-date-input  { width: 135px; }  /* marketing_point 은 110px 로 모듈 오버라이드 */

/* ── 급여 수당/과세 항목 행 (구 pay_edit/pay_init 중복) ── */
.bi-payinit-add-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
}
.bi-payinit-add-row {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1_5);
    font-size: var(--fs-base);
    color: var(--txt-secondary);
}
.bi-payinit-add-label {
    min-width: 100px;
    font-weight: var(--fw-semibold);
    color: var(--gray-600);
}

/* ============================================================
   docs/71: ERP list/write 공통 컴포넌트 — list.css·write.css 중복(완전동일) 통합
   (list XOR write 로 동시로드 안 되던 것 → style.css 단일화, 2026-07-01)
   ============================================================ */

.bi-erp-card {
    flex: 1;
    /* ⚠ 가로도 0 까지 줄 수 있어야 한다. min-width 를 안 풀면 안쪽 3열 워크스페이스가
     *   내용 최소폭에 걸려 열이 눌린다 — 디자이너 차팅 좌측 열이 세로 글자로 뭉갰다
     *   (2026-08-13, 공통 셸을 씌우며 드러남). 카드는 «담는 것» 이지 폭을 정하는 것이 아니다. */
    min-height: 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    background: var(--bg-card);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-xl);
    overflow: hidden;
}

.bi-erp-title { font-size: var(--fs-2lg); font-weight: var(--fw-bold); color: var(--txt-primary); margin: 0; }

/* §40-2 페이지 스크롤 변형 (2026-08-11) — .bi-page 는 overflow:hidden 이라
   내부 카드가 스크롤을 맡는다(표준 목록). 대시보드처럼 **페이지 전체가 세로로 긴** 화면은
   페이지 자체가 스크롤해야 한다. main 이 .bi-main-page 로 따로 정의하던 것을 규격으로 회수. */
.bi-page--scroll { overflow-y: auto; overflow-x: hidden; }

/* §21 폼 · §40-10 레이아웃 보완 (2026-08-11) — 모듈들이 반복해서 다시 만들던 한 줄짜리.
   main 의 .bi-main-modal-input(width:100%) · -submit(width:100%) · -row(margin) 처럼
   화면마다 이름만 다르고 값은 같았다. 규격 유틸로 회수한다. */
.bi-input--block { width: 100%; }
/* ⚠ .bi-btn--block 은 여기 넣지 않는다 — §12 버튼 변형 묶음(위쪽 .bi-btn--icon 옆)에 이미 있다.
   2026-08-11 중복 정리(B0-2): 같은 선언을 두 번 두면 나중에 값을 고칠 때 한쪽만 고친다. */
/* §40-3 카드형 헤더 (2026-08-11) — 워크플로 화면(예약일정표·예약일정표(시간)·휴무설정·AI메시지
   ·대기상담·디자이너차트)이 쓰는 변형. 값은 **§23 카드(.bi-erp-card)에서 그대로** 가져왔다 —
   세 모듈(.bi-aim-header/.bi-dayoff-header/.bi-bk-subbar)이 이미 같은 값을 쓰고 있었다.
   새 디자인이 아니라 기존 규격 조합("카드 안의 툴바")에 이름을 준 것이다. */
/* .bi-erp-toolbar--card 삭제(2026-08-21 · 사용자 지적) — **헤더는 하나다.**
 *
 * 규격 §40-3-1 은 「워크플로 화면은 카드형」이라 적고 예약일정표·대기상담·디자이너차트 등 6개를
 * 나열하고 있었다. 그런데 실물은 **정반대**였다 — 그 6개는 전부 플랫이고,
 * `--card` 를 쓰는 건 문구에 없던 POS 3개(+팝업 1)뿐이었다.
 *
 * POS 가 카드형이었던 이유는 «카드가 없어서» 다. 표준 셸은 프레임 → **카드** → 툴바인데
 * POS 는 프레임(.bi-counter-wrap) 바로 밑에 툴바가 있어, 툴바가 스스로 카드 흉내를 냈다.
 * 예약일정표처럼 플랫로 맞추면 프레임 위에 제목 + 아래 구분선 — 그게 §40-4 의 「타이틀은 유지」다.
 *
 * 남은 규격: .bi-erp-toolbar 하나. 변형 없음. */
/* §40-3 헤더 부속 (2026-08-11 추가) — 6개 워크플로 화면이 각자 다른 헤더를 쓰고 있었다.
   .bi-bk-subbar(예약일정표·예약일정표(시간)) · .bi-dayoff-header(휴무설정) · .bi-aim-header(AI메시지)
   · 헤더 자체가 없던 화면(대기/상담·디자이너차트). 전부 .bi-erp-toolbar 로 통일하고,
   그 화면들이 쓰던 부제·구분점·구분선만 규격 부속으로 올린다(모듈 클래스 신설 금지). */
.bi-erp-title__dot { width: 6px; height: 6px; border-radius: var(--radius-full); background: var(--brand-blue); flex-shrink: 0; }
.bi-erp-title__sub { font-size: var(--fs-sm); color: var(--txt-muted); font-weight: var(--fw-normal); white-space: nowrap; }
.bi-erp-toolbar__div { width: 1px; height: 14px; background: var(--border-base); flex-shrink: 0; }
.bi-erp-toolbar {
    height: 64px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 var(--space-6);
    border-bottom: 1px solid var(--border-base);
}

.bi-res-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0;
}

.bi-res-header__left  { display: flex; align-items: center; gap: var(--space-6); }

.bi-res-title {
    font-size: var(--fs-2xl);
    font-weight: var(--fw-bold);
    color: var(--txt-primary);
    margin: 0;
}

/* ============================================================
   팝업 공통 헤더 (.bi-pop-head*) — 2026-07-03 popup.css 에서 이전.
   popup_layer.js 가 '<div class="layer_header bi-pop-head">' 를 호스트 페이지 DOM 에 렌더하므로,
   전 페이지 공통 로드되는 이 파일(style.css)에 있어야 모든 모듈 팝업 헤더가 정상 적용됨.
   (docs/76: 밝은 헤더 + 브랜드블루 아이콘배지 + 둥근 닫기버튼 · menu2 스타일 통일)
   ============================================================ */
.bi-pop-head {
    display: flex; align-items: center; justify-content: space-between;
    width: 100%; height: auto; padding: var(--space-4) var(--space-5); box-sizing: border-box;   /* menu2-modal-head 와 동일 간격 (헤더 높이 ≈ 64px) */
    /* 스타일보드 §01 원칙 «헤더는 조용하게» — 흰 배경 · 구분선 없음 · 아이콘은 회색(2026-08-21 A단계).
     * 색은 «사용자가 눌러야 할 곳»(검색 navy · 주 액션 blue · 선택 indigo)에만 쓴다.
     * 선은 리스트 상단과 푸터 상단 두 곳에만 둔다 — 헤더에는 두지 않는다. */
    background: var(--bg-card);
    flex-shrink: 0;
}
/* 헤더 아이콘 = fal(light) 고정 — 모듈 wrap(예: .bi-page--scroll i.fal{font-weight:var(--fw-black)})이 헤더 아이콘까지 solid 로 바꿔 모듈 간 굵기(색감) 달라 보이던 것 통일. 특이도 0,3,1 로 wrap(0,2,1) override */
/* 스타일보드 §03 — 팝업 제목 15px. sg2 스케일(…14·16…)엔 15 가 없어 **16 으로 스냅**한다
 * (반픽셀·비스케일 값을 그대로 옮기면 스케일이 무너진다 — 2026-08-21 에 정한 원칙). */
.bi-pop-head-title {
    font-size: var(--pop-title-fs); font-weight: var(--fw-extrabold); color: var(--txt-primary);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ============================================================
   공통 컴포넌트 규격 (Phase 0 공통화, 2026-07-28)
   재사용 패턴을 모듈 프리픽스 중복 대신 공통 클래스로 정의(아직 모듈 미적용).
   상세: renew_crm/docs/design/CSS_CONSOLIDATION_PLAN.md
   ============================================================ */

/* 빈 상태 — 간단 텍스트형(기본) */
.bi-empty {
    text-align: center;
    color: var(--txt-disabled);
    font-size: var(--fs-sm);
    font-weight: var(--fw-semibold);
    padding: var(--space-6) 0;
}

/* ── 상태 배지 — 색 스케일 기반 modifier (success/danger/warning/info/neutral) ──────────
 * ⚠ 2026-08-21 «변형이 죽어 있었다». 기본 스킨(.bi-badge)이 파일 뒤쪽에 다섯 벌 더 복사돼
 *   있었고, 마지막 사본이 변형과 «같은 특이도로 더 뒤» 라 색·배경을 되돌렸다 —
 *   danger/warning/info/success/neutral 다섯이 렌더에서 전부 회색 하나로 나왔다(구분 1/6).
 *   테두리 색만 살아남아서 «변형이 있긴 한데 안 먹는» 상태로 오래 갔고,
 *   그래서 모듈들이 인라인 style='color:#ef5350' 으로 상태색을 직접 칠하기 시작했다.
 *   → 정의는 여기 한 곳. 뒤쪽 사본 5개 제거. 변형은 반드시 기본 «뒤» 에 온다.
 *   기본값은 «지금 화면에 나오던 그 값»(뒤 사본의 값)을 그대로 승격했다 — 맨 배지를 쓰는
 *   화면(reception 「실시간 수정 가능」·styleguide2 칩)이 변하지 않게 하려는 것이다. */
.bi-badge {
    display: inline-flex; align-items: center;
    font-size: var(--fs-xs); font-weight: var(--fw-semibold);
    color: var(--txt-muted); background: var(--border-light);
    padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm);
    border: 1px solid transparent; white-space: nowrap;
}
/* ↓ 변형은 기본 바로 뒤 — 순서가 규격이다. 다른 곳에 흩어 놓지 않는다. */
.bi-badge--danger  { background: var(--color-danger-50);  color: var(--color-danger-600);  border-color: var(--color-danger-200); }
.bi-badge--warning { background: var(--color-warning-50); color: var(--color-warning-700); border-color: var(--color-warning-200); }
.bi-badge--info    { background: var(--color-info-50);    color: var(--color-info-700);    border-color: var(--color-info-200); }
.bi-badge--success { background: var(--color-success-50); color: var(--color-success-700); border-color: var(--color-success-200); }
.bi-badge--neutral { background: var(--gray-100);         color: var(--txt-muted);         border-color: var(--border-base); }

/* sg2 §34 텍스트 링크 — 공통 shipped 클래스(2026-08 신설, 규격 있으나 배포 클래스 부재였음).
   브랜드블루 · 기본 밑줄 없음 · hover 밑줄 */
.bi-link { color: var(--brand-blue); text-decoration: none; cursor: pointer; }
.bi-link:hover { text-decoration: underline; }

/* ── §32 토스트 — 결과 알림(필드 단위 에러는 .bi-write-error) ── */
.bi-toast {
    display: inline-flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2) var(--space-3); border-radius: var(--radius-lg);
    font-size: var(--fs-base); font-weight: var(--fw-medium); box-shadow: var(--shadow-md);
}
/* ⚠ 2026-10-02 — 화면 아래에 «떴다 사라지는» 토스트(.bi-toast--float).
   .bi-toast 규격에는 «숨김» 상태가 없다 — 화면에 놓는 순간 늘 보인다(booking_time 이 2026-09-02 에 겪고 뺐다).
   접수(reception)·디자이너차트가 마크업을 상시로 두어 «빈 토스트(체크 아이콘만)» 가 화면 아래에 떠 있었다(L3 캡처에서 발견).
   기존 .bi-toast 를 고치지 않고 이 수식 클래스만 얹는다 — 보이는 쪽은 기존 .bi-toast.is-show 가 맡는다. */
.bi-toast--float {
    position: fixed; left: 50%; bottom: var(--space-6); z-index: var(--z-popover);
    background: var(--gray-900); color: var(--white);
    opacity: 0; visibility: hidden; transform: translateX(-50%) translateY(8px);
    transition: opacity .15s, transform .15s, visibility .15s; pointer-events: none;
}

/* ── §35 스피너 — 로딩 ── */
@keyframes bi-spin { to { transform: rotate(360deg); } }
.bi-spinner {
    width: 28px;
    height: 28px;
    border: 3px solid var(--border-light);
    border-top-color: var(--brand-blue);
    border-radius: 50%;
    animation: bi-spin .7s linear infinite;
}
@media (prefers-reduced-motion: reduce) { .bi-spinner { animation-duration: 1.4s; } }
/* 그리드 검색 로딩 — 2026-08-24 사용자 지적("일마감이 눌러도 반응이 없어 보인다") + §36
 * "로딩은 기존 화면을 지우지 않고 겹쳐 표시한다". 대상은 검색 그리드 AJAX
 * (/src/api/{모듈}/list.php) 전체 — function.js 가 공용 ajaxSend/ajaxComplete 하나로 붙인다.
 * 모듈 뷰를 하나도 고치지 않는다(§5-7 "동작 추가" 패턴) — .bi-grid-area 는 이미 position:relative. */
.bi-grid-loading {
    position: absolute;
    inset: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    background: color-mix(in srgb, var(--bg-card) 75%, transparent);
}

/* ── §28 드롭다운 메뉴 — 행 액션(⋯). 이름이 .bi-menu 가 아닌 이유:
      사이드바가 .bi-menu-shopmall* 네임스페이스를 쓰고 있어 혼동된다(template/side/menu.css). ── */
.bi-dropdown {
    display: inline-flex; flex-direction: column; min-width: 150px;
    background: var(--bg-card); border: 1px solid var(--border-base);
    border-radius: var(--radius-lg); box-shadow: var(--shadow-md); padding: var(--space-1);
}

/* ── §14 빈 상태 박스 — 점선 테두리 + 아이콘 + 제목/보조.
      그리드 셀 안의 짧은 "없음" 문구는 .bi-cell-empty, 패널 여백형은 .bi-empty--panel. ── */
.bi-emptybox {
    display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
    width: 100%; padding: var(--space-8) var(--space-4);
    background: var(--bg-card); border: 1px dashed var(--border-base); border-radius: var(--radius-lg);
}

/* ── §8 타이포 역할 클래스 — 카드제목/본문/보조. 모듈이 fs+fw+color 세 줄을 매번 다시 쓰던 조합 ── */
/* 카드 타이틀 역할 — 한 이름으로 모은다. .bi-write-card__title · .bi-carousel__stat-val 이
 * 같은 선언을 따로 갖고 있었다(2026-08-14 글자 토큰화가 드러냈다). 규격은 하나다. */
.bi-text-title,
.bi-write-card__title,
.bi-carousel__stat-val { font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--txt-primary); }
.bi-text-sub   { font-size: var(--fs-sm);   font-weight: var(--fw-normal);   color: var(--txt-muted); }
/* 숫자 — 자릿수가 흔들리지 않도록 tabular-nums 고정 */
.bi-num        { font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-primary); font-variant-numeric: tabular-nums; }

/* ============================================================
   헤더 셸 — 고객센터 패널(qmenu)·유저메뉴·pr_domain·helpu
   header.php 인라인 <style> 이관 (웨이브0, 2026-08-05)
   ============================================================ */
		.question_close {
			width: 30px; height: 30px;
			display: flex; align-items: center; justify-content: center;
			border-radius: var(--radius-lg);
			color: var(--txt-muted, var(--txt-muted)); cursor: pointer; font-size: var(--fs-lg);
			transition: background .15s, color .15s;
		}
		.question_close:hover { background: var(--border-light, var(--border-light)); color: var(--txt-primary, var(--txt-primary)); }

		#user_menu {
			border: 0;
			border-radius: var(--radius-xs);
			box-shadow: var(--ring-focus);
			font-size: var(--fs-md);
			padding: var(--space-2_5);
			width: 230px;
			height: 170px;
			position: fixed;
			right: 48px;
			z-index: 50;
			background-color: var(--bg-card, var(--bg-card));
			text-align: center;
			overflow: hidden;
		}

		#question_menu {
			width: 300px;
			height: calc(100vh - 50px);
			position: fixed;
			right: -320px;
			z-index: 50;
			background: var(--bg-card, var(--bg-card));
			border-left: 1px solid var(--border-base, var(--border-base));
			box-shadow: var(--shadow-lg);
			text-align: left;
			transition: right 0.25s ease;
			overflow-y: auto;
			overflow-x: hidden;
		}
		#question_menu.open { right: 0; }

		/* 리뉴얼: 고객센터 패널 내부 */
		.qmenu-head {
			display: flex; align-items: center; justify-content: space-between;
			padding: var(--space-4) var(--space-5);
			border-bottom: 1px solid var(--border-light);
		}
		.qmenu-title { font-size: var(--fs-md); font-weight: 800; color: var(--txt-primary, var(--txt-primary)); }
		.qmenu-body { padding: var(--space-2_5) var(--space-3); }
		.qmenu-link {
			display: flex; align-items: center; gap: var(--space-3);
			padding: var(--space-2_5);
			border-radius: var(--radius-xl);
			color: var(--txt-secondary, var(--txt-secondary)); font-size: var(--fs-base); font-weight: 600;
			text-decoration: none;
			transition: background .15s, color .15s;
		}
		.qmenu-link:hover { background: var(--color-info-50, var(--color-info-50)); color: var(--brand-blue, var(--brand-blue)); }
		.qmenu-link-ico {
			width: 34px; height: 34px; flex-shrink: 0;
			display: flex; align-items: center; justify-content: center;
			background: color-mix(in srgb, var(--brand-blue) 5%, transparent); color: var(--brand-blue, var(--brand-blue));
			border-radius: var(--radius-lg); font-size: var(--fs-md);
		}
		.qmenu-sublinks {
			margin-top: var(--space-2); padding: var(--space-3) var(--space-3_5);
			border-top: 1px solid var(--border-light);
			display: flex; flex-direction: column; gap: var(--space-2_5);
		}
		.qmenu-sublinks a {
			color: var(--txt-muted, var(--txt-muted)); font-size: var(--fs-sm); font-weight: 600; text-decoration: none;
			transition: color .15s;
		}
		.qmenu-sublinks a:hover { color: var(--brand-blue, var(--brand-blue)); }

		.pr_domain {
			float: left;
			font-size: var(--fs-2xs);
		}

		.helpu {
			float: right;
			margin-top: var(--space-5);
			position: relative;
			left: -158px;
		}

/* ── 헤더 유저메뉴 드롭다운 행 · CID 상태 (header.php 인라인 → 클래스, 웨이브0 2026-08-05) ── */
#user_menu .um-row { display: flex; align-items: center; justify-content: space-between; height: 45px; border-bottom: 1px solid var(--border-base); font-size: var(--fs-base); color: var(--txt-secondary); }
#user_menu .um-row--head { height: 38px; }
#user_menu .um-logout { cursor: pointer; color: var(--txt-muted); }
#user_menu .um-logout:hover { color: var(--brand-blue); }
#user_menu .um-foot { padding-top: var(--space-2_5); text-align: right; }
.header-icon-btn.header-cid-on { color: var(--color-success); }

/* sg2 §31 팝오버 — 트리거 옆에 뜨는 도움말/목록 패널. display 토글은 JS/hover */
/* 2026-09-11 A21-1 — «변수 도움말» 패널이 위로 솟아 윗줄이 잘려 나갔다(실측 top −80px).
   원인: .bi-popover-wrap 이 inline-flex + align-items:center 라, 절대배치 자식의 «정적 위치» 가
   플렉스 정렬을 따라 **세로 가운데**로 잡힌다(패널이 높을수록 위로 더 솟는다 —
   399px 패널이 15px 트리거 기준 −192px 만큼 올라갔다). 기준점을 못 박아 트리거 «아래» 에 건다. */
.bi-popover { top: calc(100% + var(--space-1_5)); display: none; position: absolute; min-width: 230px; padding: var(--space-2); background: var(--bg-card); border-radius: var(--radius-lg); z-index: var(--z-popover); box-shadow: var(--shadow-md); }
/* §31 보완(2026-08-11) — .bi-popover 가 position:absolute 인데 기준 요소가 규격에 없었다.
   모듈들이 각자 position:relative 를 얹던 자리(booking_buysell #arrow_pop · setting_sms .bi-ssms-help)를
   규격으로 회수한다. 새 절이 아니라 §31 의 빠진 조각을 채우는 것이다. */
.bi-popover-wrap { position: relative; display: inline-flex; align-items: center; gap: var(--space-1); }
.bi-popover-trigger { cursor: pointer; color: var(--brand-blue); font-style: normal; }
.bi-popover-trigger:hover + .bi-popover { display: block; }
/* sg2 비활성 상태 유틸 */
.bi-disabled { color: var(--txt-disabled); cursor: not-allowed; pointer-events: none; }

/* ── 건수 뱃지 — 2026-09-10 폐기(사용자 지시) ────────────────────────
 *   페이지명 오른쪽의 «총 N건» 표시. 세 화면에서 개별 삭제 요청이 반복돼
 *   (마케팅 문자·수신전화 CID·디자이너별 상품매출현황) **컴포넌트 자체를 걷어냈다.**
 *   마크업은 26개 list.php 에서 제거했고, 여기 있던 `.bi-count-badge`·`__dot`
 *   규칙도 함께 지운다 — 남겨두면 «쓰지 않는 규격» 으로 오해된다.
 *   건수는 그리드 하단 페이지네이션의 «총 N건» 이 이미 보여준다(중복 표시였다).
 *   ⚠ `#list_count` 를 채우는 각 모듈 JS 는 그대로 뒀다 — jQuery 라 대상이 없으면
 *      아무 일도 하지 않는다(무해). 다른 위치에서 같은 id 를 쓰는 화면이 있어 일괄 제거는 안 한다. */

/* ── 팝업 검색 input (클릭 아이콘 + readonly input 조합) ────────────── */
/* 고객·직원 등 팝업 검색 트리거가 있는 input 에 사용 */
.bi-search-trigger-wrap {
    position: relative;
    display: flex;
    align-items: center;
}
/* ⚠ 2026-08-21 «돋보기 위에 커서가 있었다» — 39화면 63칸.
 *   아이콘(.bi-search-trigger)은 left:10px 에 서는데 입력의 글자는 12px 에서 시작했다.
 *   아이콘 폭이 13px 이라 **글자와 커서가 돋보기 위에 10px 겹쳐** 앉았다.
 *   .bi-search-wrap 쪽은 아이콘 자리로 padding-left:36px 를 주는데 이 래퍼에는 그 짝이 없었다 —
 *   «아이콘을 놓는 래퍼는 여백도 같이 준다» 는 규칙이 한쪽에만 적용돼 있었던 것.
 *   ⚠ 이 칸들은 대부분 접히는 「상세조건」(.bi-erp-filter__more) 안에 있어서
 *     펼치지 않고 재는 도구에는 **통째로 안 잡혔다**(probe_caret.mjs 가 그래서 0 을 보고했다).
 *     → 접힌 것을 펼치고 재도록 도구를 고쳤다. */
.bi-search-trigger-wrap input[type="text"].bi-input,
.bi-search-trigger-wrap input[type="search"].bi-input,
.bi-search-trigger-wrap input[type="tel"].bi-input {
    padding-left: var(--space-9, 36px);   /* 아이콘 자리 — .bi-search-wrap 과 같은 값 */
}
.bi-search-trigger {
    position: absolute;
    left: 10px;
    display: flex;
    align-items: center;
    color: var(--txt-muted);
    font-size: var(--fs-base);
    text-decoration: none;
    z-index: 1;
    cursor: pointer;
    transition: color .15s;
}
.bi-search-trigger:hover { color: var(--brand-blue); }

/* ── 검색 인풋 ───────────────────────────────────────────────────────── */
/* ⚠ 2026-08-12: 베이스가 **아이콘 여백(padding-left:36px)을 기본으로** 갖고 있었다.
 * 그래서 아이콘 없는 입력(POS·팝업 등)마다 padding 을 다시 쓰는 사본이 생겼고,
 * 그 사본이 김에 border·radius·background 까지 다시 써서 **두 번째 스킨**이 됐다
 * (.bi-input--strong 이 그것이었다 — 선언 11개 중 9개가 베이스와 겹쳤다).
 * → 베이스는 아이콘을 가정하지 않는다. 여백은 **아이콘을 가진 쪽**(.bi-search-wrap)이 준다. */
.bi-input {
    height: 36px;
    border: 1px solid var(--border-base);
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    padding: 0 var(--space-3);
    font-size: var(--fs-md);
    font-family: var(--font-sans);
    color: var(--txt-primary);
    outline: none;
    transition: border-color .15s, box-shadow .15s;
    box-sizing: border-box;
}
.bi-input:focus {
    border-color: var(--brand-blue);
    box-shadow: var(--ring-focus);
    background: var(--bg-card);
}

/* ── 입력 폭 규격(필터·검색·그리드 공통) — 디자인은 이 규격 중 선택해서 사용. 모듈별 커스텀 폭 지양 ── */
.bi-page .bi-fw-sm { width: 90px; }   /* 년·월·짧은 코드 */
.bi-page .bi-fw-md { width: 130px; }   /* 전표·금액·승인·키인덱스 */
.bi-page .bi-fw-lg { width: 200px; }   /* 전화·이름·지점 */
.bi-page .bi-fw-xl { width: 340px; }   /* 키워드·제목 */
.bi-page .bi-fw-full { width: 100%; }  /* 컬럼/폼 폭 채움 */
.bi-page .bi-fw-r  { text-align: right; }

/* ── 소량 잔여 공통 패턴 ── */
/* 소형 입력 그룹(년월·금액 등 여러 리포트 공통) */
/* 한 칸짜리 가로 묶음 — 필드 묶음 · 전체선택 · 예약 상태 색표가 같은 모양이다 */
.bi-fld-group,
.bi-bk2-vfoot__sw { display: inline-flex; align-items: center; gap: var(--space-1_5); }
/* 그리드 셀 강조 텍스트(위험=빨강 굵게) — low-stock·point-use·출고 등 여러 리포트 공통 */
.bi-page .bi-cell-danger, .bi-erp-card #gridbox .bi-cell-danger { color: var(--color-danger); font-weight: var(--fw-black); }

/* ── 그리드 셀 강조 사다리 (2026-08-21 신설) ──────────────────────────────
 * 「어떤 항목을 강조해야 하나」에 답하려면 먼저 **강조할 수단**이 있어야 한다.
 * 실측: 64개 그리드 중 값을 강조하는 모듈은 **3개**(재고·입출금·포인트)뿐이고,
 *       나머지는 고객명도 메모도 전표번호도 전부 같은 무게(rgba(0,0,0,.7))였다.
 *       그래서 **무엇을 굵게 해도 덜 도드라졌다** — 올리기 전에 «바닥을 낮추는» 게 절반이다.
 *
 *   E1  bi-cell-key   무엇인가   행의 주어(고객명·상품명·직원명). **행당 하나**
 *   E2  bi-cell-amt   얼마인가   그 화면의 주 금액 하나. 자릿수 고정
 *   E!  bi-cell-danger 손대야 할 값 (이미 있음 — 재고부족·출금이 쓰고 있다)
 *   E−  bi-cell-mute  없는 값    0원·빈칸·끝난 행
 *
 * 규칙: 한 행에 강조는 **최대 셋**(무엇 · 얼마 · 상태). 넷을 넘으면 강조가 사라진다.
 * ──────────────────────────────────────────────────────────────────────── */
.bi-page .bi-cell-key  { color: var(--txt-primary); font-weight: var(--fw-semibold); }
.bi-page .bi-cell-amt  { color: var(--txt-primary); font-weight: var(--fw-semibold); font-variant-numeric: tabular-nums; }
.bi-page .bi-cell-mute { color: var(--txt-disabled); }
/* 끝난 행(취소·환불·미사용) — 행 전체를 물린다. 지우지 않고 «비켜 두는» 표시다 */
.bi-page .dhx_grid-row.bi-row-off .dhx_grid-cell { color: var(--txt-disabled); }

/* 숫자는 자릿수가 흔들리면 열이 삐뚤어 보인다. 우측정렬 셀 = 숫자 칸이므로 일괄 고정.
 * ⚠ 실측에서 tabular-nums 를 쓰는 그리드가 **64개 중 0개**였다 —
 *   규격(.bi-num)에는 있는데 그리드가 한 번도 안 쓰고 있었다. */
.bi-page .dhx_grid-cell.dhx_align-right,
.bi-page .dhx_grid-header-cell--align_right { font-variant-numeric: tabular-nums; }
/* 필터 select(패딩·배경) — 여러 리포트가 개별 정의하던 것 공통화 */
.bi-erp-filter select.bi-input { padding: 0 var(--space-2); background: var(--bg-input); }
/* 만료 라벨 + 체크박스(선불/패키지 잔여 공통) */
.bi-fw-expire-label { margin-left: var(--space-2); color: var(--color-danger); font-weight: var(--fw-medium); }
.bi-fw-expire-label input[type="checkbox"] { visibility: visible; display: inline-block; accent-color: var(--brand-blue); width: 14px; height: 14px; margin-right: var(--space-1); vertical-align: middle; }

/* ── 그리드 셀 인라인 입력(편집 표시) 공통 — 여러 모듈 공용. 폭/정렬만 모듈별(width, --right).
   글로벌 .bi-input(36px·검색아이콘 좌패딩)과 달리 셀용 컴팩트(30px). .bi-page 스코프+ 로 글로벌 input 강제규칙 우선. ── */

.bi-search-wrap {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    max-width: 480px;
    position: relative;
}
/* 세로 스택(패널) 안에 놓이는 검색칸 — 폭 제한 해제 + 아래 간격.
 * 2026-08-21: 접수·디자이너차트의 «분류 안 상품명 검색» 이 이 자리를 사설 스킨
 * (.bi-desk__psearch — 테두리·라운드·높이 34 를 따로 갖고 있었다)으로 메우고 있었다.
 * 규격에 «스택형» 이 없어서 생긴 사본이라 변형으로 승격하고 사설 스킨은 제거했다. */
.bi-search-wrap--stack { max-width: none; margin-bottom: var(--space-2_5); }
/* ⚠ 2026-08-21 «돋보기가 칸 밖에 서 있었다».
 *   래퍼(.bi-search-wrap)만 쓰고 아이콘에 이 클래스를 안 붙인 화면이 넷 있었다
 *   (접수 고객조회·상품검색, 디자이너차트 고객검색·상품검색).
 *   클래스가 없으면 아이콘이 absolute 가 아니라 **flex 아이템**이 되어 입력 테두리 «왼쪽 바깥» 에 서고,
 *   입력에는 아이콘용 padding-left:36px 만 빈 채로 남는다 → 돋보기 밖 + 글자 44px 안쪽.
 *   ① top/transform 을 명시한다 — 파일 안 다른 검색아이콘(.bi-bksch-search-icon 등)과 같은 형태로.
 *      (없을 때는 flex 의 static position 에 기대고 있었다 — 래퍼가 늘어나면 같이 끌려간다)
 *   ② 래퍼 안 <i class="fa-search"> 는 클래스를 잊어도 같은 자리에 서게 셀렉터에 함께 태운다. */
.bi-search-icon,
.bi-search-wrap > i.fa-search {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--txt-disabled);
    font-size: var(--fs-md);
    pointer-events: none;
    z-index: 1;
}

/* ── 검색 셀렉트 ─────────────────────────────────────────────────────── */
.bi-search-select {
    height: 36px;
    border: 1px solid var(--border-base);
    border-radius: var(--radius-lg);
    font-size: var(--fs-base);
    font-weight: var(--fw-medium);
    padding: 0 var(--space-8) 0 var(--space-3_5);   /* style.css 글로벌 select{padding:1px} 덮어쓰기 */
    background-color: var(--bg-card);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239CA3AF' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    color: var(--txt-primary);
    outline: none;
    min-width: 120px;
    text-indent: 1px;
    cursor: pointer;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    transition: border-color .15s, box-shadow .15s;
}
.bi-search-select:hover { border-color: var(--gray-300); }
.bi-search-select:focus {
    border-color: var(--brand-blue);
    box-shadow: var(--ring-focus);
}

/* ── 검색 영역 ───────────────────────────────────────────────────────── */
/* lib/css/style.css 글로벌 강제 규칙 override */
/* 검색 래퍼 안의 입력 — 래퍼가 아이콘을 갖고 있으므로 **왼쪽 여백은 여기서** 준다.
 * ⚠ 2026-08-12 정리: 같은 셀렉터가 한 목록에 **네 번** 반복돼 있었고,
 *   radius·height·background·box-shadow 를 `` 로 베이스와 똑같이 다시 쓰고 있었다.
 *   베이스가 이미 주는 값이라 전부 뺀다. 여기 남는 건 '이 래퍼라서 필요한 것' 뿐이다. */
/* ⚠ 2026-08-13: 이 규칙이 [type="text"] 만 잡아서 **비밀번호 칸에 아이콘 자리가 안 생겼다** —
 *   로그인 화면에서 자물쇠 아이콘이 «패스워드» 글자를 덮었다(padding-left 36 vs 12).
 *   아이콘을 놓는 래퍼 안이면 **글자를 받는 칸은 종류를 가리지 않는다**. */
.bi-search-wrap input[type="text"].bi-input,
.bi-search-wrap input[type="password"].bi-input,
.bi-search-wrap input[type="search"].bi-input,
.bi-search-wrap input[type="tel"].bi-input,
.bi-search-wrap input[type="email"].bi-input,
.bi-search-wrap input[type="number"].bi-input {
    width: 100%;                 /* 래퍼(아이콘+검색박스) 폭 채움 — 모듈별 width 하드코딩 대신 공통에서 */
    box-sizing: border-box;
    padding-left: var(--space-9, 36px);   /* 아이콘 자리 — 스케일 밖 값이라 폴백 표기 */          /* 아이콘 자리 */
}
/* 우측 clear(X) 버튼 있는 검색 인풋 — 텍스트가 X 아래로 안 깔리게 우패딩 확보 */
.bi-input.bi-input--clearable { padding-right: var(--space-8); }
/* 지우기 단추 — --clearable 입력의 짝. 규격에 짝이 없어 화면이 민무늬 <button> 을 쓰고 있었다
 * (레거시 전역 버튼 스킨이 가려주다가 2026-08-12 그 스킨 제거로 드러남). 값이 있을 때만 보인다. */
.bi-input-clear {
    position: absolute; right: var(--space-2); top: 50%; transform: translateY(-50%);
    width: 20px; height: 20px; display: none; align-items: center; justify-content: center;
    padding: 0; border: 0; background: transparent; cursor: pointer;
    color: var(--txt-disabled); font-size: var(--fs-xs); border-radius: 50%;
    transition: color .15s, background .15s;
}
.bi-input-clear.is-show { display: flex; }
.bi-input-clear:hover { color: var(--txt-secondary); background: var(--border-light); }
.bi-search-wrap input[type="text"].bi-input:focus,
.bi-search-wrap input[type="password"].bi-input:focus,
.bi-search-wrap input[type="search"].bi-input:focus,
.bi-search-wrap input[type="tel"].bi-input:focus,
.bi-search-wrap input[type="email"].bi-input:focus,
.bi-search-wrap input[type="number"].bi-input:focus {
    border-color: var(--brand-blue);
    box-shadow: var(--ring-focus);
    background: var(--bg-card);
}
.bi-sch-input { flex: 1; }

/* ── 검색 영역 멀티 row 유틸리티 · 예약 바닥 색표 묶음 ─────────────────── */
.bi-search-row,
.bi-bk2-vfoot__l {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}
/* 두 번째 이후 검색 row 상단 간격 */
.bi-search-row--top { margin-top: var(--space-2); }

/* ──────────────────────────────────────────────────────────────
 *  검색 상세조건 접기 (전 모듈 공통 규칙)
 *    · 주요(첫 번째) 검색조건은 항상 보임
 *    · 나머지 검색조건은 .bi-erp-filter__more 로 묶어 기본 숨김
 *    · 주요 row 우측 .bi-filter-tools(상세조건 토글 + 검색버튼) 고정
 *    · 토글 클릭 시 lib/js/function.js 의 위임 핸들러가 .is-open 부착
 * ────────────────────────────────────────────────────────────── */
.bi-filter-tools {            /* 주요 검색조건 바로 옆: 검색 + 상세조건 토글 */
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    flex-shrink: 0;
}
/* 필터바의 «상세조건» — 옆의 검색 버튼(.bi-btn 32)과 같은 줄에 선다.
 * 36 은 사다리에 없는 값이라 검색 버튼보다 커 보였다 → base 32(§12-4, 2026-08-14). */
.bi-erp-filter-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1_5);
    height: 32px;
    padding: 0 var(--space-3_5);
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    color: var(--txt-secondary);
    font-size: var(--fs-base);
    font-weight: var(--fw-medium);
    line-height: 1;
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s;
}
.bi-erp-filter-toggle:hover { background: var(--border-light); border-color: var(--txt-disabled); }
.bi-erp-filter-toggle__chev { font-size: var(--fs-xs); transition: transform .2s; }
.bi-erp-filter-toggle.is-open { background: var(--color-indigo-50); border-color: var(--color-indigo-200); color: var(--brand-navy); }
.bi-erp-filter-toggle.is-open .bi-erp-filter-toggle__chev { transform: rotate(180deg); }

.bi-erp-filter__more { display: none; }
.bi-erp-filter__more.is-open {
    display: flex;
    flex-direction: column;
    gap: var(--space-2_5);
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: 1px dashed var(--border-base);
}
/* __more 안의 첫 row 는 토글 분리선과 중복되므로 상단 간격 제거 */
.bi-erp-filter__more > .bi-search-row:first-child { margin-top: 0; }

.bi-search-label {
    font-size: var(--fs-sm);
    font-weight: var(--fw-semibold);
    color: var(--gray-600);
    min-width: 44px;
    flex-shrink: 0;
    white-space: nowrap;
    letter-spacing: -0.01em;
    /* 2026-08-24 사용자 지적 — 라벨-입력폼 간격이 화면마다 달라 보였다(상품별 재고현황
       「상품분류」4자 vs 「상품명」3자). 원인은 min-width:44px + 왼쪽 정렬 — 글자가 짧을수록
       칸 안에 남는 빈칸이 커져 입력폼까지의 눈에 보이는 거리가 늘어난다(3px 대 13px 차이 실측).
       오른쪽 정렬로 바꿔 «라벨 끝 → 입력폼» 간격을 flex gap 하나로 고정한다(전 화면 공통). */
    text-align: right;
}

/* ── 기간 그룹 ───────────────────────────────────────────────────────── */
/* bi-input 기본 padding(0 12px 0 36px)은 아이콘용 — 날짜 input 은 아이콘 없으므로 override */
.bi-date-group input[type="text"].bi-input { padding: 0 var(--space-3); }input[type="text"].bi-date-input { padding: 0 var(--space-3); width: 130px; }

.bi-date-sep {
    font-size: var(--fs-md);
    color: var(--txt-muted);
}
/* 날짜 picker input 고정 폭 — 모든 리뉴얼 모듈 공통 ID */
#start_date_input,
#end_date_input { width: 110px; }

/* ── 퀵 기간 버튼 그룹 ───────────────────────────────────────────────── */
.bi-quick-btns {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    background: var(--border-light);
    padding: var(--space-1);
    border-radius: var(--radius-md);
}/* ── sg2 §29-1 가로 스크롤 pill 필터바 — 공통(2026-08 승격, 구 member .bi-mem-emp-*).
   항목이 가변·다수인 동적 필터(디자이너/직원). 화살표 네비 + 가로스크롤 + navy 활성.
   ※ 화살표 enabled/disabled 색은 모듈 script.js 가 제어(현행 유지). ── */
.bi-pillbar__arrow {
    flex-shrink: 0; width: 24px; height: 24px;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer; color: var(--txt-secondary); font-size: var(--fs-xs);
    border-radius: 50%; transition: color .15s, background .15s;
}
.bi-pillbar__arrow:hover { color: var(--txt-primary); background: var(--border-light); }
/* 더 갈 곳이 없는 화살표. JS 가 인라인으로 'black' / rgb(159,159,159) 를 찍던 자리 —
 * 기본색이 --txt-disabled 라 «켜진» 상태를 JS 가 검정으로 덮어써야 했다. 뒤집는다:
 * 기본은 켜진 색, 꺼진 것만 상태 클래스로(2026-08-14). */
.bi-pillbar__arrow.is-disabled { color: var(--txt-disabled); cursor: default; }
.bi-pillbar__arrow.is-disabled:hover { color: var(--txt-disabled); background: none; }

/* ── 그리드 영역 + dhx (§5-5 패턴, .bi-grid-area 스코프) ──────────── */
/* .bi-grid-area 로 스코프 — 미갱신 모듈의 #gridbox 에 영향 없음 */
.bi-grid-area {
    flex: 1;
    position: relative;
    overflow: hidden;
    /* ⚠ min-height 금지 — CLAUDE.md §5-6 클립 함정 */
}
.bi-grid-area #gridbox {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}
.bi-grid-area #gridbox > * { background: var(--bg-card); }/* 2026-07-24 유령 가로 스크롤바 제거 — 세로 스크롤바가 유발한 ~15px 가짜 넘침.
 *   그리드가 `autoWidth:true` 로 컬럼을 컨테이너 폭에 꽉 맞추는데, 목록이 길어 세로
 *   스크롤바(~15px)가 나타나면 그만큼 사용 가능 폭이 줄어 컬럼이 살짝 넘친다(dhx v7 는
 *   세로 스크롤바 폭을 미리 확보하지 않음) → 불필요한 가로 스크롤바가 뜬다.
 *
 * ⚠ 2026-08-24 «그 처방이 진짜 넘침까지 잘라내고 있었다»(사용자 지적 ⑩ ⑪).
 *   overflow-x:hidden 은 15px 유령만 자르는 게 아니라 **846px 짜리 진짜 넘침도 자른다.**
 *   일마감(846px)·직원별매출(1216px)은 오른쪽 컬럼이 통째로 화면 밖에 있었고,
 *   사용자에게는 «검색이 안 된다» 로 보였다 — 실제로는 결과가 화면 밖에 있었을 뿐이다.
 *
 *   → 자르지 않고, **유령의 원인을 없앤다.**
 *     scrollbar-gutter:stable 로 세로 스크롤바 자리를 처음부터 확보하면
 *     dhx 가 재는 clientWidth 가 흔들리지 않아 15px 넘침 자체가 생기지 않는다.
 *     그러면 overflow-x:auto 로 둬도 «맞는 그리드에는 가로바가 안 뜨고,
 *     진짜 넘치는 그리드는 스크롤된다».
 *   ⚠ 세로(overflow-y)는 건드리지 않는다 — dhx 내부 스크롤 유지. */

/* 넘치는 그리드의 가로 스크롤바는 «보여야» 한다 (2026-08-24).
 * 전역 스크롤바는 6px + 옅은 회색이라 긴 목록 아래에서 찾기도 잡기도 어려웠다
 * ("우측으로 이동이 어려워"). 그리드 안에서만 굵고 또렷하게 — 다른 곳은 그대로 6px. */
.bi-grid-area #gridbox ::-webkit-scrollbar,
.bi-grid-area #gridbox::-webkit-scrollbar { width: 10px; height: 10px; }
.bi-grid-area #gridbox ::-webkit-scrollbar-track,
.bi-grid-area #gridbox::-webkit-scrollbar-track { background: var(--border-light); }
.bi-grid-area #gridbox ::-webkit-scrollbar-thumb,
.bi-grid-area #gridbox::-webkit-scrollbar-thumb {
    background: var(--txt-disabled);
    border-radius: var(--radius-full);
    border: 2px solid var(--border-light);   /* 트랙과 붙지 않게 — 손잡이로 읽힌다 */
}
.bi-grid-area #gridbox ::-webkit-scrollbar-thumb:hover,
.bi-grid-area #gridbox::-webkit-scrollbar-thumb:hover { background: var(--txt-muted); }

/* ── 헤더 행 (floating, no card) ─────────────────────────────────── */

/* 엑셀 버튼 파란 텍스트 — bi-btn--ghost 기반 + 강조 */
/* 아이콘-텍스트 간격을 styleguide 4.버튼 엑셀다운 기준(6px)으로 고정 → 전 모듈 엑셀다운 버튼 동일 간격 보장 */
.bi-excel-btn { color: var(--color-info-600); gap: var(--space-1_5); }
.bi-excel-btn:hover { color: var(--brand-blue); }

/* ── bi-erp-card 내 input — lib/css/style.css 전역 숨김 override ─── */
/* dhx boolean 컬럼, 그리드 내 체크박스 공통 (CLAUDE.md §5-1) */
.bi-erp-card input[type="checkbox"] {
    visibility: visible;
    display: inline-block;
    accent-color: var(--brand-blue);
}
/* dhx v7 boolean 그리드 체크박스(.dhx_checkbox) — 체크/포커스 색을 dhx 기본 #0288d1 → 디자인 블루 var(--brand-blue)(진한 var(--brand-blue) 은 너무 진해 완화) */
.bi-page .dhx_checkbox__input:checked + .dhx_checkbox__visual-input {
    background-color: var(--brand-blue);
    border-color: var(--brand-blue);
}
.bi-page .dhx_checkbox__input:focus + .dhx_checkbox__visual-input {
    border-color: var(--brand-blue);
}

/* ── bi-erp-card 내부 그리드 영역 ────────────────────────────────── */
.bi-erp-card .bi-grid-area {
    flex: 1;
    position: relative;
    overflow: hidden;
}
.bi-erp-card .bi-grid-area #gridbox {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}
.bi-erp-card .bi-grid-area #gridbox > * { background: var(--bg-card); }
/* sg2 §24-4 — 2026-08-24 사용자 지적: ".dhx_grid-content 에 테두리가 1px 들어가서 굵게 나온다".
 * 벤더(dhtmlxGrid v7 grid.css)가 그리드 콘텐츠 통째에 자체 테두리를 하나 더 그린다
 * (border:1px solid #dfdfdf, 하드코딩 색) — 그런데 바로 밖 .bi-erp-card 가 이미 카드 테두리를
 * 그리고 있고 그 안쪽 여백이 사실상 0(카드 테두리 두께만큼)이라 두 선이 거의 겹쳐 «상자 안 상자»
 * 로 두꺼워 보였다. 바깥 카드가 이미 프레임을 주므로 벤더 것은 지운다. */
.bi-page .dhx_grid-content { border: none; }
.bi-page .dhx_grid-header-cell {
    background: var(--bg-input);
    color: var(--txt-muted);
    font-weight: 600;
    font-size: var(--fs-base);
    border-top: none;
    border-bottom: 1px solid var(--border-base);
    border-left: none;
}/* ── 정렬 표시 리뉴얼 (asc/desc) — FA5 Pro 셰브론 + 브랜드블루 (2026-07-01) ──
   dhx 기본: 머티리얼 글리프 + 하늘색(#0288d1) → 리뉴얼 톤 통일. .bi-page 스코프 전 그리드 일괄.
   근거: docs/modules/74_part_grid_정렬표시_디자인리뉴얼.md */
/* ⚠ 2026-08-25 사용자 지적 — 「정렬 표시가 잘 안 보인다. 마우스를 올려야 흐린 회색으로
 *   보이기도 하고 모양도 잘 모르겠다. 오름차순 위 세모 · 내림차순 아래 세모로,
 *   위치는 항목명 좌측 고정으로.」 셋 다 고친다.
 *   ① 모양 — 얇은 셰브론(\f078/\f077) → **속 찬 세모**(fa-caret, \f0d7/\f0d8).
 *      가는 선은 13px 에서 방향이 안 읽힌다. 세모는 채워져 있어 작아도 방향이 보인다.
 *   ② 보임 — hover 에서만 보이던 것을 **늘 보이게**. 정렬 가능한 열임을 미리 알려야
 *      «눌러 볼 생각» 이 든다. 대신 미정렬은 아주 연하게(연회색), 정렬된 것만 브랜드블루. */
/* ⚠ 아이콘 폰트를 쓰지 않고 **CSS 삼각형**으로 그린다.
 *   벤더가 `.dxi:before { font-family: dhxicons !important }` 로 박아 둬서
 *   FA 글리프로는 이길 수 없다(특이도로는 !important 를 못 이긴다).
 *   `!important` 를 맞불로 놓는 대신 — 그러면 AB-IMPORTANT 가 는다 —
 *   **테두리로 세모를 만든다.** 폰트에 기대지 않으니 로드 실패·글리프 누락이 없고,
 *   13px 에서도 가장자리가 또렷하다.
 *   벤더 글리프(\F14C = 가로줄 3개)는 content 를 비워 지운다 — .dxi 를 함께 태워 (0,3,1) 로 이긴다. */
.bi-page .dhx_grid-sort-icon.dxi:before { content: ""; }
/* 세모 6px(좌우 3+3) × 높이 5px — 좌측정렬이 쓸 수 있는 자리가 8px 뿐이라 그 안에
   «세모 6 + 글자와의 틈 2» 로 맞춘다. 다른 정렬도 같은 값을 써서 **간격이 들쭉날쭉하지 않게**. */
.bi-page .dhx_grid-sort-icon:after {
    content: "";
    display: block;
    width: 0;
    height: 0;
    border-left: 3px solid transparent;
    border-right: 3px solid transparent;
    border-top: 5px solid currentColor;      /* ▼ 내림차순 */
}
/* ▲ 오름차순 — 위로 뾰족하게 */
.bi-page .dhx_grid-sort-icon--asc:after {
    border-top: none;
    border-bottom: 5px solid currentColor;
}
/* 정렬 가능하지만 미정렬 — «늘» 연하게 보인다(hover 조건 없음). hover 면 조금 진해진다. */
.bi-page .dhx_grid-header-cell--sortable .dhx_grid-sort-icon:not(.dhx_grid-sort-icon--asc):not(.dhx_grid-sort-icon--desc) {
    opacity: 1;
    color: var(--gray-300);
}
.bi-page .dhx_grid-header-cell--sortable:hover .dhx_grid-sort-icon:not(.dhx_grid-sort-icon--asc):not(.dhx_grid-sort-icon--desc) {
    color: var(--txt-disabled);
}

/* ── 정렬 아이콘 위치: 셀 가장자리(리사이즈 경계와 겹침) → 항목명 바로 옆 inline (2026-07-01) ──
   dhx 기본은 아이콘을 absolute(right/left:4px)로 셀 끝에 둠 → 리사이즈 핸들과 충돌.
   static 으로 흐름에 편입 + 예약 24px 패딩 제거 → 라벨 우측(우측정렬 컬럼은 좌측)에 밀착.

   ⚠ 2026-08-21 «이 규칙이 6주 동안 지고 있었다».
   아래 한 줄짜리 형태(.bi-page .…--sortable .…-text)는 특이도 (0,3,0) 인데,
   벤더가 **정렬 변형을 붙인 복합 셀렉터**로 같은 (0,3,0) 을 쓴다:
       .dhx_grid-header-cell--align_center.dhx_grid-header-cell--sortable .dhx_grid-header-cell-text
         → padding-right: 24px   (grid.css 7.1.5) / 16px (dhtmlxgrid.css)
       .dhx_grid-header-cell--align_center.dhx_grid-header-cell--sortable .dhx_grid-header-cell-text_content
         → padding-left: 24px
   동점이면 **나중에 로드되는 쪽**이 이긴다. 벤더 시트가 style.css 뒤에 붙으므로 벤더가 이겼다.
   결과: 헤더가 정렬아이콘 자리로 좌 24 + 우 16~24 = **40~48px 를 잃고**,
   넘친 글자는 말줄임 없이 «글자 중간에서» 잘렸다(「예약번3」「디자이니」「|술금액」).
   실측 10개 그리드에서 118컬럼 중 34개가 그렇게 잘려 있었다.
   → 벤더와 **같은 복합 형태 + .bi-page** 로 (0,4,0) 을 만들어 확실히 이긴다.
   ⚠ 벤더 셀렉터가 바뀌면 여기도 바뀌어야 한다 → 회귀는 verify_sec1.mjs 의 G-1 이 잡는다. */
.bi-page .dhx_grid-header-cell--sortable .dhx_grid-header-cell-text { width: auto; }/* 벤더의 «정렬변형 + sortable» 복합 셀렉터를 그대로 맞받는다 (0,4,0) */
.bi-page .dhx_grid-header-cell--align_left.dhx_grid-header-cell--sortable   .dhx_grid-header-cell-text,
.bi-page .dhx_grid-header-cell--align_center.dhx_grid-header-cell--sortable .dhx_grid-header-cell-text,
.bi-page .dhx_grid-header-cell--align_right.dhx_grid-header-cell--sortable  .dhx_grid-header-cell-text,
.bi-page .dhx_grid-header-cell--align_left.dhx_grid-header-cell--sortable   .dhx_grid-header-cell-text_content,
.bi-page .dhx_grid-header-cell--align_center.dhx_grid-header-cell--sortable .dhx_grid-header-cell-text_content,
.bi-page .dhx_grid-header-cell--align_right.dhx_grid-header-cell--sortable  .dhx_grid-header-cell-text_content {
    padding-left: 0;
    padding-right: 0;
}
/* ⚠ 2026-08-25 — 자리를 «항목명 좌측» 으로 고정한다(사용자 지시).
 *   전에는 좌·가운데정렬은 오른쪽, 우측정렬만 왼쪽이라 **열마다 자리가 달랐다.**
 *   눈이 세모를 찾아 좌우로 옮겨다녀야 했다 — 한 자리에 고정한다.
 *
 *   ⚠⚠ 그런데 아이콘이 «자리를 차지한 채» 왼쪽에 서면 좌측정렬 헤더가 그만큼 오른쪽으로
 *   밀린다 — 실측 14px. 그러면 2026-08-21·24 에 두 번에 걸쳐 맞춰 놓은
 *   «헤더 글자 = 데이터 글자» 라인이 도로 어긋난다(22/33 컬럼에서 -14px 확인).
 *   좌측정렬은 글자가 이미 칸 왼쪽 끝이라 **왼쪽에 내줄 자리가 없다.**
 *
 *   → 아이콘을 **레이아웃에서 뺀다**(폭 0 + overflow:visible). 가운데정렬에서 쓰던 방법을
 *     전 정렬로 넓혔다. 상자는 글자 바로 앞에 폭 0 으로 서고, 세모는 음수 마진으로
 *     그 왼쪽(헤더 좌패딩 16px 안)에 그려진다. 글자 위치는 **바뀌지 않는다.** */
.bi-page .dhx_grid-sort-icon {
    position: static;
    transform: none;
    top: auto;
    left: auto;
    right: auto;
    order: -1;                        /* 항상 항목명 앞(왼쪽) */
    width: 0;                         /* 레이아웃을 넓히지 않는다 */
    margin: 0;
    overflow: visible;
    flex: 0 0 auto;
}
/* 폭 0 상자 «안» 의 일이라 정렬 계산에 영향이 없다 — 세모만 글자 왼쪽으로 빼낸다.
   가운데·우측정렬은 글자 왼쪽에 빈자리가 있어 이걸로 충분하다. -8 = 세모 6 + 틈 2. */
.bi-page .dhx_grid-sort-icon:after { margin-left: calc(-1 * var(--space-2)); }

/* ⚠ 좌측정렬만 다르다 — 글자가 칸 왼쪽 «끝» 이라 왼쪽에 내줄 자리가 없다.
 *   헤더 칸은 overflow:hidden 이고 좌패딩이 8px 뿐이라, 위 -14px 로 빼내면 세모가 **잘린다**
 *   (실측 — 칸 바깥 x312 에 그려져 조각만 보였다).
 *   → 그 8px 패딩을 아이콘에게 그대로 넘긴다. 패딩이 줄어든 만큼 아이콘이 자리를 차지하므로
 *     **글자 위치는 1px 도 바뀌지 않는다**(라인 어긋남 0 유지). 세모는 칸 안에 온전히 들어간다. */
.bi-page .dhx_grid-header-cell--align_left.dhx_grid-header-cell--sortable { padding-left: 0; }
/* space-2(8px) 안에 «세모 6 + 틈 2» — 가운데·우측정렬의 -space-2 와 같은 리듬이 된다 */
.bi-page .dhx_grid-header-cell--align_left .dhx_grid-sort-icon { width: var(--space-2); }
.bi-page .dhx_grid-header-cell--align_left .dhx_grid-sort-icon:after { margin-left: 0; }
/* ⚠ 2026-08-24 «매출 결제현황은 헤더가 34~50px 왼쪽»(사용자 지적 ⑧) — 위 8~9px 과 다른 원인이다.
 *   헤더 글자는 flex 컨테이너(.dhx_grid-header-cell-text_content) 안에 있는데,
 *   벤더는 justify-content 를 **«정렬 가능(sortable)» 헤더에만** 건다.
 *   정렬을 끈 그리드(headerSort:false)는 justify-content 가 normal(=왼쪽)이라
 *   text-align:center 를 줘도 **flex 컨테이너에는 안 먹어** 글자가 왼쪽에 붙었다.
 *   → 정렬 클래스대로 flex 정렬을 준다. 정렬 가능 여부와 무관하게. */
.bi-page .dhx_grid-header-cell--align_left   .dhx_grid-header-cell-text_content { justify-content: flex-start; }
.bi-page .dhx_grid-header-cell--align_center .dhx_grid-header-cell-text_content { justify-content: center; }
.bi-page .dhx_grid-header-cell--align_right  .dhx_grid-header-cell-text_content { justify-content: flex-end; }

/* ⚠ 2026-08-21 «항목명은 왼쪽에 붙고 데이터는 가운데라 라인이 안 맞는다»(사용자 지적).
 *   가운데정렬 컬럼만 그랬다 — 헤더는 «라벨 + 정렬아이콘» 을 **한 덩어리로** 가운데 두는데
 *   셀은 값만 가운데 둔다. 그래서 라벨이 아이콘 폭의 절반(실측 8~9px)만큼 왼쪽으로 밀렸다.
 *   (좌·우 정렬은 기준 모서리가 아이콘 반대쪽이라 영향이 없다 — 실측 0px)
 *   ⚠ 벤더는 이걸 text_content 의 padding-left:24px 로 «반대편에 같은 폭을 둬서» 상쇄하고 있었다.
 *     그 여백이 항목명을 잘라먹던 범인이라 걷어냈고(G-1), 그러자 이 어긋남이 드러났다.
 *     여백으로 되돌리면 잘림이 돌아온다 → **아이콘이 자리를 안 먹게** 한다.
 *     폭 0 + overflow:visible 이면 글리프는 그대로 보이면서 가운데 계산에서 빠진다. */
/* (구 «가운데정렬만 폭 0» 규칙 — 2026-08-25 부터 위에서 **전 정렬**에 같은 처리를 하므로
   따로 둘 이유가 없어졌다. 가운데정렬이 겪던 8~9px 어긋남도 그 규칙이 그대로 막아 준다.) */
/* 멀티행(colspan) 그룹 헤더 셀 — dhx 기본 .dhx_span-cell(var(--gray-50)) 을 일반 헤더 톤·보더와 통일
   (패키지/선불권 판매현황 등 2행 헤더의 'X월' 그룹 셀이 본문 헤더와 어긋나 보이는 문제) */
.bi-page .dhx_span-cell {
    background: var(--bg-input);
    color: var(--txt-muted);
    font-weight: 600;
    font-size: var(--fs-base);
    border-top: none;
    border-bottom: 1px solid var(--border-base);
}/* ═══════════════════════════════════════════════════════════════════
   분석 리포트 공통 — 섹션 카드 / 타이틀 / 차트 (bi-anl-*)
   (월별매출현황 / 고객매출분석 / 재방률분석 / 상품매출분석 통일)
   ═══════════════════════════════════════════════════════════════════ */
.bi-anl-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: var(--space-4) var(--space-5);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    background: var(--bg-card);
}
.bi-anl-card {
    background: var(--bg-card);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-xl);
    padding: var(--space-4) var(--space-5);
    flex-shrink: 0;
}
/* 2026-08-24 사용자 지시 — 4페이지 디자인은 지금대로 두고, 월별 매출현황만 그래프 카드의
   라운드를 뺀다(월별 매출현황 <b>1건</b>). 바로 아래 그리드 카드(.bi-erp-gridwrap)는 이미
   각짐(border-radius:0) — 라운드를 빼면 위아래 카드가 이어져 보인다. 다른 3개 분석 페이지의
   .bi-anl-card 는 건드리지 않는다(신규 클래스로 이 화면만 opt-in).
   ⚠ 같은 지시 이어서 — 라운드를 빼니 .bi-anl-card 의 4면 테두리 중 위·좌·우가 바로 밖
   .bi-erp-card 테두리와 겹쳐 이중선으로 보였다(사용자 지적). 아래 그리드 카드와 맞닿는
   면(아래)만 남기고 나머진 뺀다 — 바깥 카드가 이미 그 3면의 프레임을 준다. */
.bi-anl-card--square {
    border-radius: 0;
    border: none;
    border-bottom: 1px solid var(--border-base);
}
.bi-anl-title {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--fs-md);
    font-weight: var(--fw-bold);
    color: var(--txt-primary);
    letter-spacing: -0.01em;
    margin: 0 0 var(--space-3_5);
}
.bi-anl-title::before {
    content: "";
    width: 3px;
    height: 14px;
    background: var(--brand-blue, var(--brand-blue));
    border-radius: var(--radius-xs);
    flex-shrink: 0;
}
.bi-anl-charts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: var(--space-4);
}
.bi-anl-chart-title {
    font-size: var(--fs-base);
    font-weight: var(--fw-semibold);
    color: var(--txt-secondary);
    text-align: center;
    margin-bottom: var(--space-2);
}/* sg2 §24 그리드 빈 셀 값 — '-' 등 없음 표시(muted). 공통(2026-08, 구 module .bi-*-memo-empty) */
.bi-cell-empty { color: var(--txt-disabled); }
/* sg2 §24 넓은 그리드 가로 스크롤 — 컬럼 총합 > 컨테이너인 리포트(고정폭 컬럼+autoWidth:false).
   공통 '유령 가로스크롤 방지'(overflow-x:hidden)를 명시 opt-in 으로 되돌림. */
.bi-grid-area--xscroll { overflow-x: auto; }/* sg2 §40-5 차트/그리드 캔버스 박스 — 고정높이 필요(chart.js·고정높이 그리드). .bi-anl-chart-cell 내부 */
.bi-anl-chart-box { width: 100%; height: 240px; }
@media (max-width: 1280px) { .bi-anl-chart-box { height: 200px; } }
/* sg2 §16 월 선택 datepicker 변형 — 일(날짜) 표 숨기고 월·년만 */
.bi-monthpicker .ui-datepicker-calendar { display: none; }
/* (구 «월 달력엔 오늘/닫기 줄을 보인다» 규칙은 뺐다 — 2026-08-24 부터 월은
   12칸 판에서 고르면 바로 닫히므로 그 줄 자체를 만들지 않는다. showButtonPanel:false) */
/* sg2 §16-2 월 판(1~12월) — 2026-08-24 사용자 지적 ③, 재작업(같은 날 ②차) —
 * 「캘린더가 완전히 바뀌었다. 기존 년월일 캘린더와 디자인이 너무 다르다」.
 * 첫 판은 머리줄에 <select> 를 그대로 노출해 일 달력(화살표+가운데 제목)과 다른 위젯처럼 보였다.
 * 화살표·제목 자리를 일 달력과 «같은 마크업» 으로 채운다 — 새 스킨을 만들지 않는다.
 *   · 월·연 <select> 는 지우지 않고 **둘 다** «숨김 보관함»(기존 <code>.bi-hidden</code> 재사용)으로
 *     옮긴다(jQuery UI 상태·data-handler 바인딩 유지, 그림은 안 그린다). select 만 display:none
 *     하면 jQuery UI 가 그 옆에 끼워 넣는 «년»(yearSuffix) 맨텍스트가 안 가려져 "2026년년" 으로
 *     겹쳐 보였다 — 텍스트 노드는 CSS 로 못 가리므로 통째로 옮긴다(function.js biMonthGrid).
 *   · 화살표(.ui-datepicker-prev/next)는 **그대로 보인다** — 일 달력과 똑같은 버튼이다.
 *     다만 여기선 «달» 이 아니라 **연도** 를 옮긴다(12칸을 다 깔았으니 달 이동은 뜻이 없다).
 *     클릭을 가로채는 코드는 function.js — 캡처 단계에서 jQuery UI 자체 핸들러보다 먼저 잡는다.
 *   · 제목 자리(.ui-datepicker-title)에 우리가 만든 «2026년» 글자만 얹는다 — 굵기·배경·정렬은
 *     이미 있는 .ui-datepicker-header/.ui-datepicker-title 규칙을 그대로 물려받는다(별도 지정 없음). */
.bi-monthgrid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-1);
    padding: var(--space-2);
}
.bi-monthgrid__cell {
    height: 34px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--txt-primary);
    font-size: var(--fs-base);
    font-weight: var(--fw-medium);
    line-height: 1;
    cursor: pointer;
    transition: background .12s ease, color .12s ease, border-color .12s ease;
}
/* font-family 만 따로 — .ui-widget button 이 Verdana 로 덮는다(jquery-ui CDN 테마, style.css 보다
   뒤에 로드돼 특이도 동점(0,2,1)에서 이긴다). #ui-datepicker-div 로 스코프를 좁혀 이긴다.
   배경·테두리 등 나머지는 이 문제가 없어(브라우저 기본 button 은 항상 저순위) 스코프가 필요 없다
   — 스코프를 걸면 styleguide2 정적 목업(진짜 #ui-datepicker-div 밖)에 회색 버튼 배경이 샜다. */
#ui-datepicker-div .bi-monthgrid__cell { font-family: var(--font-sans); }
.bi-monthgrid__cell:hover { background: var(--border-light); }
.bi-monthgrid__cell:focus-visible { outline: none; box-shadow: var(--ring-focus); }
.bi-monthgrid__cell.is-on {
    background: var(--brand-navy);
    border-color: var(--brand-navy);
    color: var(--bg-card);
    font-weight: var(--fw-semibold);
}
/* 제목 자리("2026년") — 일 달력 제목과 같은 칸(.ui-datepicker-title)에 얹혀 배경·굵기·정렬은
   이미 상속받는다. 폭이 좁아져도 "2026" 과 "년" 사이가 줄바꿈되지 않게만 한다. */
.bi-monthgrid__yr { white-space: nowrap; }
/* 달력 버튼줄(오늘·닫기) — jQuery UI 기본 스킨이 그대로였다(영문·Verdana·회색 테두리).
 * 글자는 function.js 의 currentText/closeText 가 한글로 바꾸고, 모양은 여기서 규격으로. */
.ui-datepicker .ui-datepicker-buttonpane {
    padding: var(--space-2) var(--space-3);
    border-top: 1px solid var(--border-light);
    background: var(--bg-input);
    margin: 0;
}
.ui-datepicker .ui-datepicker-buttonpane button {
    font-family: var(--font-sans);
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
    color: var(--txt-secondary);
    background: var(--bg-card);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-md);
    padding: var(--space-1) var(--space-3);
    cursor: pointer;
}
.ui-datepicker .ui-datepicker-buttonpane button:hover { background: var(--bg-input); border-color: var(--gray-300); }
.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-close {
    background: var(--brand-blue); border-color: var(--brand-blue); color: var(--bg-card); font-weight: var(--fw-bold);
}

/* ═══════════════════════════════════════════════════════════════════
   칼럼 표시/순서 커스터마이즈 톱니 (lib/js/grid_colcfg.js 자동 부착)
   참고: renew_crm/docs/modules/66_part_grid_컬럼순서표시_커스터마이즈.md
   ═══════════════════════════════════════════════════════════════════ */
.bi-grid-area .bi-ra-grid-tools {
    position: absolute;
    top: 6px;
    right: 12px;
    z-index: 6;
}

/* ── 결제탭 높이 보정 modifier ─────────────────────────────────────── */
/* 결제/리포트 탭(42px) + 헤더(--header-height, 50px) — 구 64px 하드코딩 정렬 (2026-06-15) */
.bi-page--payment { height: calc(100vh - var(--header-height) - 42px); }

/* ── 결제구분 컬럼 강조 (dhx template 내 span 적용) ────────────────── */
.bi-pay-approved { color: var(--color-info-600); font-weight: var(--fw-black); }
.bi-pay-canceled { color: var(--color-danger); font-weight: var(--fw-black); }/* ── 1. 툴바 ───────────────────────────────────────────── */
@keyframes bi-erp-pulse { 0%,100% { opacity: 1; } 50% { opacity: .3; } }

/* ── 2. 필터 영역 ──────────────────────────────────────── */
.bi-erp-filter {
    flex-shrink: 0;
    padding: var(--space-3_5) var(--space-6);
    background: var(--gray-50);
    border-bottom: 1px solid var(--gray-100);
    display: flex;
    flex-direction: column;
    gap: var(--space-2_5);
}

/* ── 상태 탭 ─────────────────────────────────────────────
 * 규격(2026-08-21 확정): ① 자리는 **필터카드의 마지막 줄** — 접히는 .bi-erp-filter__more 안에
 *   넣지 않는다(매출관리가 거기 있어서 0x0 으로 «한 번도 보이지 않았다»).
 *   ② 다른 검색조건과 같이 **왼쪽 .bi-search-label** 을 붙인다(「예약상태」「전표상태」).
 *   ③ 0건 탭도 숨기지 않는다 — 검색결과가 0 이라는 것도 답이다. */
.bi-erp-tabs { display: flex; align-items: center; gap: var(--space-1_5); flex-wrap: wrap; margin-top: var(--space-2_5); }
/* 라벨과 한 줄에 설 때는 줄 자체가 간격을 갖는다 → 탭의 위 여백은 뺀다 */
.bi-search-row > .bi-erp-tabs { margin-top: 0; }

/* ── 탭형 단일선택 필터 (2026-08-24, 사용자 지시 ⑤) ──────────────────────────
 * 「전체 + 몇 가지 중 하나」를 고르는 필터가 화면마다 라디오 / 탭으로 갈려 있었다
 * (실측: 라디오 84개 · 16화면). 용도가 같으니 매출관리 전표상태 탭으로 통일한다.
 *
 * ⚠ 라디오를 «지우지» 않는다 — 겉모습만 탭으로 바꾼다.
 *   목록 검색은 폼을 serializeArray() 로 통째로 보낸다. 라디오를 hidden input 으로 바꾸면
 *   16개 모듈의 읽는 쪽을 전부 손봐야 하고, 그 중 하나만 놓쳐도 «검색이 안 되는» 화면이 생긴다.
 *   라디오를 그대로 두면 전송·복원·접근성이 전부 그대로다.
 *   활성 표시는 :has(:checked) 가 맡는다 — JS 없이 «지금 무엇이 골라졌는가» 가 따라온다. */
.bi-erp-tabs .bi-erp-tab input[type="radio"] {
    position: absolute;
    opacity: 0;
    width: 1px; height: 1px;
    margin: 0;
    pointer-events: none;
}
/* label 은 button 과 달리 기본이 content-box 라 테두리 2px 이 더해져 34px 가 된다 —
 * 같은 줄의 버튼(32)과 어긋난다. 높이는 사다리 값 그대로 유지한다. */
.bi-erp-tabs label.bi-erp-tab { position: relative; user-select: none; box-sizing: border-box; }
.bi-erp-tabs label.bi-erp-tab:has(input[type="radio"]:checked) {
    background: var(--brand-navy);
    border-color: var(--brand-navy);
    color: var(--bg-card);
}
/* 키보드로 옮겨 다닐 때도 어디에 있는지 보여야 한다 */
.bi-erp-tabs label.bi-erp-tab:has(input[type="radio"]:focus-visible) {
    box-shadow: var(--ring-focus);
}
/* 2026-08-21: 높이를 사다리 값(32)으로 고정. 여백으로 정하면 카운트 칩이 있는 탭(30)과
 * 없는 탭(28)이 갈린다 — 실제로 예약관리 30 · 매출관리 28 로 갈려 있었다. */
.bi-erp-tab {
    display: inline-flex; align-items: center; gap: var(--space-1_5);
    height: 32px;
    padding: 0 var(--space-3_5); border-radius: var(--radius-full);
    border: 1px solid var(--border-base); background: var(--bg-card);
    color: var(--gray-600); font-size: var(--fs-sm); font-weight: var(--fw-medium);
    cursor: pointer; transition: background .15s, border-color .15s, color .15s;
}
.bi-erp-tab:hover { background: var(--bg-input); border-color: var(--gray-300); }
.bi-erp-tab.is-active { background: var(--brand-navy); border-color: var(--brand-navy); color: var(--bg-card);  }

/* ── 3. 그리드 액션바 ──────────────────────────────────── */
.bi-erp-actionbar {
    flex-shrink: 0;
    display: flex; align-items: center; justify-content: space-between;
    padding: var(--space-2_5) var(--space-6);
    border-bottom: 1px solid var(--border-base);
    background: var(--bg-card);
}
.bi-erp-actionbar__right { display: flex; align-items: center; }
.bi-erp-result { display: inline-flex; align-items: center; gap: var(--space-1_5); font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--gray-600); }
/* ⚠ §100 의 .bi-erp-sum__dot 은 선언이 같다 — 두 번 적지 않는다(SPEC-DUP).
     (번호를 §97 로 적었다가 다른 세션과 격쳐 §100 으로 옮겨졌다 — 자리는 그대로다.) */
.bi-erp-result__dot,
.bi-erp-sum__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--brand-blue); }
.bi-erp-result__val,
.bi-erp-sum__val { color: var(--brand-blue); font-weight: var(--fw-extrabold); font-size: var(--fs-md); }

/* ── 조회결과 전역 제거(공통 기본사양) — 표시항목 ⚙ 가 이 자리를 대체 ── */
.bi-erp-actionbar__right .bi-erp-result { display: none; }

/* ── 표시항목(칼럼 표시설정) = 기존 grid_colcfg.js ⚙ 을 툴바 오른쪽(조회결과 자리)에 라벨버튼으로 ── */
/* ⚠ 이 버튼은 lib/js/grid_colcfg.js 가 **전 목록 화면에 주입**한다. 아래 베이스가 없으면
 *   51개 화면에서 브라우저 기본 버튼(회색·2px 둥글기)으로 나온다 — 실제로 그렇게 됐었다.
 *   (2026-08-12 복구. 지우기 전에 lib/js 가 쓰는지 본다) */
.bi-ra-grid-cog {
    width: 32px; height: 32px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--border-base);
    background: var(--bg-card);
    color: var(--gray-600);
    border-radius: var(--radius-lg);
    cursor: pointer;
    font-size: var(--fs-md);
    transition: background .15s, border-color .15s, color .15s;
}
.bi-ra-grid-cog:hover { background: var(--bg-input); border-color: var(--gray-300); color: var(--txt-primary); }
.bi-ra-grid-cog[aria-expanded="true"] { background: var(--border-light); border-color: var(--gray-300); color: var(--brand-navy); }
.bi-ra-grid-cog__t { display: none; }
.bi-erp-actionbar__right .bi-ra-grid-tools { position: relative; }
/* 액션바에서는 글자가 붙어 가로로 길어진다. ⚠ 그래도 **높이는 사다리 값**이어야 한다 —
 * `height:auto` 로 두면 padding 이 높이를 정해 28px 이 되고, 옆 버튼(sm 27)과 어긋난다.
 * 문서 §12-4: "버튼 크기는 오직 이 표의 변형으로. 모듈 이름이 맡을 수 있는 건 배치뿐"(2026-08-14). */
/* 2026-08-21: 27 → 32. 같은 줄의 행 액션(.bi-btn--xs)이 32 가 되면서
 * 부수 버튼이 주 액션보다 커 보이던 역전이 사라진다 — «한 줄엔 한 크기». */
.bi-erp-actionbar__right .bi-ra-grid-cog {
    width: auto; height: 32px; padding: 0 var(--space-3); gap: var(--space-1_5);
    font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-secondary);
}
.bi-erp-actionbar__right .bi-ra-grid-cog__t { display: inline; }

/* ── 4. 그리드 래퍼 (카드 chrome 제거, dhx 테마는 위 .bi-erp-card 재사용) ── */
.bi-erp-gridwrap.bi-erp-card {
    border: none;
    border-radius: 0;
    box-shadow: none;
    flex: 1;
    min-height: 0;
}

/* ── 5. 페이지네이션 풋터 ──────────────────────────────── */
.bi-erp-foot {
    flex-shrink: 0;
    height: 52px;
    display: flex; align-items: center; justify-content: space-between;
    padding: 0 var(--space-6);
    border-top: 1px solid var(--border-base);
    background: var(--bg-card);
    font-size: var(--fs-base); color: var(--txt-muted);
}
.bi-erp-foot__size { display: inline-flex; align-items: center; gap: var(--space-1_5); color: var(--txt-muted); }
.bi-erp-size-select {
    height: 30px; border: 1px solid var(--border-base); border-radius: var(--radius-md);
    padding: 0 var(--space-1_5); background: var(--bg-card); color: var(--txt-secondary);
    font-size: var(--fs-base); font-weight: var(--fw-semibold); cursor: pointer; outline: none;
}
.bi-erp-size-select:focus { border-color: var(--brand-blue); box-shadow: var(--ring-focus); }
.bi-erp-foot__sep { color: var(--gray-300); }
.bi-erp-foot__range { color: var(--txt-muted); }
.bi-erp-foot__range b { color: var(--txt-primary); font-weight: var(--fw-bold); }

/* bi-erp-filter 내 입력 — lib/css/style.css 전역 강제 override (bi-filter-card 와 동일, CLAUDE.md §5-1) */
.bi-erp-filter input[type="text"].bi-input {
    background: var(--bg-card); height: 36px; border-radius: var(--radius-lg);
    border: 1px solid var(--border-base);
    font-size: var(--fs-base);
    transition: border-color .15s, box-shadow .15s;
}
.bi-erp-filter input[type="text"].bi-input:hover { border-color: var(--gray-300); }
.bi-erp-filter input[type="text"].bi-input:focus {
    border-color: var(--brand-blue); box-shadow: var(--ring-focus);
}
.bi-erp-filter input[type="text"].bi-input::placeholder { color: var(--txt-disabled); }
/* 검색영역 모든 select 일관 룩 (모듈별 select 포함) — 흰 배경 + 커스텀 화살표 + hover/focus 링 */
.bi-erp-filter select {
    height: 36px;
    border: 1px solid var(--border-base);
    border-radius: var(--radius-lg);
    background-color: var(--bg-card);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239CA3AF' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    padding: 0 var(--space-8) 0 var(--space-3_5) !important;   /* style.css 글로벌 select{padding:1px!important} 덮어쓰기 */
    font-size: var(--fs-base);
    font-weight: var(--fw-medium);
    color: var(--txt-primary);
    cursor: pointer;
    text-indent: 1px;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    transition: border-color .15s, box-shadow .15s;
}
.bi-erp-filter select:hover { border-color: var(--gray-300); }
.bi-erp-filter select:focus { outline: none; border-color: var(--brand-blue); box-shadow: var(--ring-focus); }
.bi-erp-filter input[type="radio"] {
    visibility: visible; display: inline-block;
    accent-color: var(--brand-blue); width: 14px; height: 14px; cursor: pointer; flex-shrink: 0;
}
.bi-erp-filter input[type="checkbox"] {
    visibility: visible; display: inline-block; accent-color: var(--brand-blue);
}
/* 날짜 input 아이콘용 좌패딩 해제 (bi-date-group 과 동일) */
.bi-erp-filter .bi-date-group input[type="text"].bi-input { padding: 0 var(--space-3); }/* ===== sg2 §26-4 권한/설정 매트릭스 — 공통 (2026-08 승격, 구 authority .bi-aut-*).
   메뉴×권한 격자 + 카테고리 헤더 + 셀 체크박스. 컬럼 구성은 매트릭스 표준(이름+5권한). ===== */
.bi-permmatrix-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 92px 92px 92px 92px 92px;
    align-items: center;
    border-bottom: 1px solid var(--border-light);
    transition: background .12s;
}
.bi-permmatrix-row:last-child { border-bottom: none; }
.bi-permmatrix-row input[type="checkbox"] + label { display: none; }
@media (max-width: 1280px) {
    .bi-permmatrix-row { grid-template-columns: minmax(0, 1fr) 80px 80px 80px 80px 80px; }
}

/* ── write 본문 래퍼 ─────────────────────────────────────────────────── */
.bi-write-body {
    flex: 1;
    overflow-y: auto;
    padding: var(--space-4) var(--space-6) var(--space-8);
}

/* ── lib/css/style.css writeinput height:25px 무력화 / password 동일 스타일 ──
   2026-06-09: .bi-write-body 스코프 → .bi-write-page 스코프로 확장
               (pay_ref/pay_init/pay_edit 처럼 .bi-write-body 없이 직접 .bi-write-card 만 사용하는 모듈 대응) */
.bi-write-page input[type="password"].bi-input, .bi-write-page input[type="text"].bi-input, .bi-write-body input[type="password"].bi-input, .bi-write-body input[type="text"].bi-input, .bi-pop-reg input[type="text"].bi-input, .bi-pop-reg input[type="date"].bi-input {
    height: 36px;
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-base);
    background: var(--bg-card);
    padding: 0 var(--space-3);
    font-size: var(--fs-md);
    color: var(--txt-primary);
    outline: none;
    box-sizing: border-box;
    transition: border-color .15s, box-shadow .15s;
}
.bi-write-page input[type="password"].bi-input:focus, .bi-write-page input[type="text"].bi-input:focus, .bi-write-body input[type="password"].bi-input:focus, .bi-write-body input[type="text"].bi-input:focus, .bi-pop-reg input[type="text"].bi-input:focus, .bi-pop-reg input[type="date"].bi-input:focus {
    border-color: var(--brand-blue);
    box-shadow: var(--ring-focus);
    background: var(--bg-card);
}.bi-form select.bi-input { cursor: pointer; }
/* 날짜 입력 = 표준 .bi-input.bi-date-input(§16). 아이콘 affix 특수케이스 제거(2026-08). */
.bi-form textarea.bi-input { height: auto; min-height: 60px; padding: var(--space-2) var(--space-3); resize: vertical; line-height: 1.5; }/* ── 카드 ────────────────────────────────────────────────────────────── */
.bi-write-card {
    background: var(--bg-card);
    border-radius: var(--radius-xl);
    border: 1px solid var(--border-base);
    margin-bottom: var(--space-4);
}
.bi-write-card__header {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-6);
    border-bottom: 1px solid var(--border-base);
    background: var(--bg-input);
}
.bi-write-card__header--required { border-bottom: 2px solid var(--color-info-500); }
.bi-write-card__header--required .bi-write-card__title { color: var(--color-info-700); }
.bi-write-card__hint { font-size: var(--fs-sm); color: var(--color-danger); display: none; }
/* sg2 §21 폼 필드 안내문 — 입력 아래 보조 설명(*안내). 표시/숨김 토글은 JS(인라인 display 허용) */
/* sg2 §21 폼 읽기전용 값 — 라벨 옆/아래 계산·표시 값(입력 아님) */
.bi-write-value { display: inline-block; font-size: var(--fs-md); color: var(--txt-secondary); padding: var(--space-2) 0; }
/* sg2 §19 입력 단위 접미(%, 원, 개 등) — 숫자입력 뒤 붙는 단위 라벨 */
/* sg2 §21 필수 표시 · 필드 에러 (2026-08-10 승격)
   규격(styleguide2 §21)은 필수 별표와 에러 메시지를 정의하고 있었는데 공통 구현이 없어,
   규격 페이지가 .sg2doc-req/.sg2doc-errmsg 로 자기 안에 그려두고 있었다 → 여기로 올린다.
   에러 상태는 §40-11 상태 모디파이어 규약대로 .is-error 를 필드 클래스에 결합해 쓴다. */
.bi-write-error { font-size: var(--fs-sm); color: var(--color-danger); }/* input-group 내 narrow(--sm) 입력은 늘어나지 않음(단위·버튼 자리 확보) */
.bi-fld-group .bi-write-input--sm { flex: none; }
/* sg2 §22 폼 정보 안내 박스 — 아이콘+문구, info 톤. 폼 상단/필드 위 설명 배너 */
.bi-write-notice {
    display: flex; align-items: center; gap: var(--space-2);
    margin-bottom: var(--space-4); padding: var(--space-3) var(--space-4);
    border: 1px solid var(--color-info-100); border-radius: var(--radius-lg);
    background: var(--color-info-50); color: var(--color-info-700); font-size: var(--fs-base);
}
.bi-write-notice i { font-size: var(--fs-md); }
.bi-write-card__body { padding: var(--space-5) var(--space-6); }

/* ── write 폼 레이아웃 ───────────────────────────────────────────────── */
.bi-write-row {
    display: flex;
    gap: var(--space-5);
    margin-bottom: var(--space-4);
    flex-wrap: wrap;
    align-items: flex-start;
}
/* 카드바디 '직계' 마지막 행만 여백 0 (2026-08). 구 `.bi-write-row:last-child`는
   조건부 서브섹션(.emp-id-section·#naver_section·#block_* 등)의 마지막 행까지 과잉 매칭해
   섹션 간 여백이 사라졌음 → 모듈별 복원 override 필요했음. 직계 스코프로 그 부작용 제거. */
.bi-write-card__body > .bi-write-row:last-child { margin-bottom: 0; }

.bi-write-field {
    flex: 1;
    min-width: 200px;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}
.bi-write-field--full { flex: 0 0 100%; }

.bi-write-label {
    font-size: var(--fs-sm);
    font-weight: var(--fw-semibold);
    color: var(--txt-muted);
    display: flex;
    align-items: center;
    gap: var(--space-2);
}
.bi-write-label-sub {
    font-size: var(--fs-xs);
    font-weight: var(--fw-normal);
    color: var(--txt-disabled);
}

/* ── 세로 정렬 변형(.bi-write-stack) ─────────────────────────────────────
 * 레이블을 행 전체 폭으로 올려(→ 자체 줄) 입력을 다음 줄에 가로 배치.
 * label↔input 세로 간격(row-gap)을 모든 행에 일정하게 부여. (pay_init·pay_edit 등)
 * 기존 .bi-write-row(가로 라벨) 는 그대로 두고, 이 변형이 붙은 폼/영역에서만 세로화. */
.bi-write-stack .bi-write-row {
    row-gap: var(--space-1_5);      /* label ↔ input 세로 간격 (일정) */
    column-gap: var(--space-3);  /* 같은 줄 입력들 사이 가로 간격 */
}
.bi-write-stack .bi-write-row > .bi-write-label {
    flex: 0 0 100%;    /* 레이블을 한 줄 전체로 → 입력은 다음 줄 */
    width: 100%;
}

/* ── 인풋 보조 클래스 ─────────────────────────────────────────────────── */
.bi-write-input--readonly {
    background: var(--border-light);
    color: var(--txt-muted);
    cursor: not-allowed;
}
.bi-write-input--zip { max-width: 200px; }

/* ── 인풋 그룹 (인풋 + 버튼 나란히) ─────────────────────────────────── */
.bi-fld-group input { flex: 1; }

/* ── 주소 래퍼 ───────────────────────────────────────────────────────── */
.bi-write-addr-wrap input { flex: 1; }

/* ── 텍스트에어리어 ───────────────────────────────────────────────────── */
.bi-write-textarea {
    width: 100%;
    height: 100px;
    border: 1px solid var(--border-base);
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    padding: var(--space-2) var(--space-3);
    font-size: var(--fs-md);
    color: var(--txt-primary);
    resize: vertical;
    font-family: var(--font-sans);
    outline: none;
    transition: border-color .15s, box-shadow .15s;
    box-sizing: border-box;
}
.bi-write-textarea:focus {
    border-color: var(--brand-blue);
    box-shadow: var(--ring-focus);
    background: var(--bg-card);
}

/* ── 라디오 그룹 ─────────────────────────────────────────────────────── */
.bi-write-radio-group {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    flex-wrap: wrap;
    /* 라디오는 인풋 박스(테두리)가 없어 .bi-write-field gap(4px)만으론 레이블과 붙어 보임 → 윗 간격 보정 */
    margin-top: var(--space-2);
}
.bi-write-radio-label {
    display: flex;
    align-items: center;
    gap: var(--space-1_5);
    cursor: pointer;
    font-size: var(--fs-md);
    color: var(--txt-secondary);
}
.bi-write-radio-label input[type="radio"] {
    visibility: visible;
    display: inline-block;
    accent-color: var(--brand-blue);
    width: 16px;
    height: 16px;
    cursor: pointer;
}

/* flat input+label 패턴 — JS 동적 생성 시 bi-write-radio-label 래퍼 없음 */
.bi-write-radio-group input[type="radio"] {
    visibility: visible;
    display: inline-block;
    accent-color: var(--brand-blue);
    cursor: pointer;
    width: 14px;
    height: 14px;
}
.bi-write-radio-group label {
    font-size: var(--fs-base);
    color: var(--txt-secondary);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
}

/* lib/css/style.css "input[type=radio]+label { background-image:radio.png; width:18px }" 초기화
 * 특이도 (0,2,2) > style.css (0,1,2) — !important 불필요 */
.bi-write-radio-group input[type="radio"] + label {
    display: inline-flex;
    align-items: center;
    background-image: none;
    width: auto;
    height: auto;
    position: static;
    top: auto;
}

/* ── 레이블 힌트 텍스트 ──────────────────────────────────────────────── */
/* 레이블 옆에 병렬로 오는 보조 안내문 (예: *미입력시 자동 부여, 숫자만 입력해주세요) */
.bi-label-hint {
    font-size: var(--fs-sm);
    font-weight: var(--fw-normal);
    color: var(--txt-disabled);
}

/* ── 숫자 인풋 — 우측 정렬 ─────────────────────────────────────────── */
.bi-input--num { text-align: right; }

/* ── select ─────────────────────────────────────────────────────────── */
.bi-write-select {
    height: 36px;
    border: 1px solid var(--border-base);
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    padding: 0 var(--space-3);
    font-size: var(--fs-md);
    color: var(--txt-primary);
    outline: none;
    cursor: pointer;
    min-width: 200px;
}
.bi-write-select:focus {
    border-color: var(--brand-blue);
    box-shadow: var(--ring-focus);
    background: var(--bg-card);
}/* ── 필드 헤더 (레이블 + 버튼 인라인) ───────────────────────────────── */
.bi-field-header {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-1_5);
    flex-wrap: wrap;
}

/* ── 아이콘 전용 버튼 (a·button 공용, 32px 회색 원) ─────────────────── */
.bi-write-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--radius-md);
    background: var(--border-light);
    color: var(--txt-secondary);
    text-decoration: none;
    flex-shrink: 0;
    cursor: pointer;
}
.bi-write-icon-btn:hover { background: var(--border-base); }

/* ── 인풋 너비 modifier ──────────────────────────────────────────────── */
.bi-write-input--sm   { width: 140px; }
.bi-write-input--md   { width: 200px; }
.bi-write-input--date { width: 160px; }
.bi-write-input--lg   { width: 240px; }
/* sg2 §21 2단 폼 그리드 — 필드 2개 가로(1fr 1fr) */
.bi-write-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
.bi-write-input--xs   { width: 60px; }
/* 메모 textarea 공용(.bi-input 위) — pay_edit/pay_init 등 정산 메모. 모듈별 재구현 대신 이걸 사용 */
.bi-write-memo { width: 80%; min-height: 100px; padding: var(--space-2) var(--space-3); resize: vertical; }

/* ── 필드 폭 modifier (그리드 폼 반/1/4 칸) — 공통 ──
 * ⚠ `min-width` 를 0 으로 풀어야 한다. 베이스 `.bi-write-field { min-width: 200px }` 가
 *   남아 있으면 **min-width 가 max-width 를 이겨** 3칸이 200px 씩 잡힌다.
 *   470px 팝업(회원등록)에서 600px 이 되어 가로로 넘쳤다(2026-08-13 실측).
 *   폭을 지정한 칸은 «지정한 만큼» 이어야 한다 — 그게 규격이다. */
.bi-write-field--half    { flex: 0 0 calc(50% - 10px); max-width: calc(50% - 10px); min-width: 0; }
.bi-write-field--third   { flex: 0 0 calc(33.333% - 14px); max-width: calc(33.333% - 14px); min-width: 0; }

/* ── 구간/설정 리스트(정산 등) — 여러 write 모듈 공통 ── */
.bi-write-type-row  { display: flex; align-items: center; gap: var(--space-2); font-size: var(--fs-base); color: var(--txt-secondary); }/* ── select 래퍼 / compact variant ──────────────────────────────────── */
.bi-write-select--compact {
    padding: 0 var(--space-2);
    min-width: unset;
}

/* ── 주소 분할 그룹 (우편번호 + 주소 + 상세주소) ─────────────────────── */
.bi-write-addr-zip   { width: 140px; padding-left: var(--space-3); }
.bi-write-addr-addr1 { flex: 1; min-width: 180px; }

/* ── 날짜 피커 팝업 컨테이너 (Daum/SuperCal) ─────────────────────────── */
#testdiv1 {
    position: absolute;
    visibility: hidden;
    background-color: white;
}/* bi-res-header 패턴으로 변환된 레거시 body-header (그룹 D) */
.bi-res-header.body-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-3_5) var(--space-8);
    border-bottom: 1px solid var(--border-base);
    box-sizing: border-box;
    width: 100%;
    float: none;
}
.bi-res-header.body-header .bi-res-header__left {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}
.bi-res-header.body-header .bi-erp-toolbar__right.body-menu {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    /* 레거시 body-menu 의 float right 등 무력화 */
    width: auto;
}

/* ============================================================
 * write 본문의 erp 카드 프레임 (2026-06-17)
 *   구조: .bi-write-page(회색 프레임) > .bi-erp-card(흰 카드) > .bi-erp-toolbar + 폼본문
 *   ※ .bi-res-header / .bi-erp-card / -toolbar / -title 본체는 위 [구 list.css] 블록에 있고
 *      2026-08-07 일원화로 write 페이지에도 그대로 실린다. 여기엔 write 전용 보정만 둔다.
 * ============================================================ */
.bi-erp-card > form { flex: 1; min-height: 0; overflow-y: auto; padding: var(--space-4) var(--space-6) var(--space-8); }

/* ============================================================
 * 2026-06-09 그룹 D 추가 무력화 — style.css 글로벌 .body-* 잔여 스타일
 *   style.css L239-317 의 .body-header height/box-shadow/.body-title float/border-bottom/padding/color
 *   .body-menu float/padding 을 bi-res-header 구조와 호환되도록 무력화
 * ============================================================ */

/* 헤더 박스 — body-header 의 45px 고정 / box-shadow 무력화 */
.bi-res-header.body-header {
    height: auto;
    box-shadow: none;
    background: var(--bg-card);
}

/* 타이틀 — body-title 의 float/border/padding/color 잔여 무력화 */
.bi-res-header.body-header .bi-res-title.body-title {
    float: none;
    border-bottom: none;
    padding: 0;
    height: auto;
    margin: 0;
    color: var(--txt-primary);
    text-align: left;
    box-sizing: content-box;
}

/* 우측 메뉴 — body-menu 의 float/padding 잔여 무력화 */
.bi-res-header.body-header .bi-erp-toolbar__right.body-menu {
    float: none;
    padding: 0;
}

/* sub-link (body-title-sub) — bi-btn--ghost 모양으로 통일 */
.bi-res-header.body-header .bi-res-header__left .body-title-sub {
    float: none;
    border-bottom: none;
    padding: var(--space-2) var(--space-3_5);
    height: auto;
    margin: 0;
    color: var(--txt-secondary);
    font-size: var(--fs-base);
    font-weight: 500;
    border: 1px solid var(--border-base);
    background: var(--bg-card);
    border-radius: var(--radius-lg);
    cursor: pointer;
}
.bi-res-header.body-header .bi-res-header__left .body-title-sub:hover {
    background: var(--bg-input);
    border-color: var(--gray-300);
}

/* sg2 §21 2패널 폼 — 사이드(고정폭) + 메인(flex). 미리보기|설정 등 */
.bi-write-split { display: flex; gap: var(--space-4); align-items: stretch; flex-wrap: wrap; }

/* ═══════════════════════════════════════════════════════════════════════════
 * [일원화 2026-08-07] 구 lib/css/pos_console.css
 *   reception·designer_chart POS 콘솔 공통. 원래도 common() 에서 전역 로드 — 로드 조건이 style.css 와 동일했다.
 *   ※ 여기까지가 이 파일의 출처 경계다 — 재구성(sg2 프리미티브화) 시 이 배너를 기준으로 찾는다.
 * ═══════════════════════════════════════════════════════════════════════════ */
/* ============================================================
 * 구 lib/css/pos_console.css (2026-08-07 이 파일로 이관)
 * reception · designer_chart 공유 POS 콘솔 컴포넌트 (2026-07-01)
 * 두 모듈 style.css 에 본문 동일하던 규칙만 그룹 셀렉터로 통합.
 * 근거: docs/modules/73_part_reception_designer_chart_정리.md
 * ============================================================ */

.bi-desk__crm-open:hover, .bi-desk__crm-open:hover { background: color-mix(in srgb, var(--brand-blue) 20%, transparent); }.bi-desk__prepaid-info,
.bi-desk__prepaid-info { display: flex; flex-direction: column; min-width: 0; }.bi-desk__ticket-sub, .bi-desk__ticket-sub { display: flex; flex-direction: column; gap: var(--space-1); }/* ⚠ 2026-08-14 — .bi-segment 가 **두 곳에 정의**돼 있었다(위 §29 블록 + 여기).
 *   뒤엣것이 이겨 실제로는 이 값이 그려졌는데, 둘의 활성색이 서로 달랐다
 *   (§29 블록: 흰 배경+검정 글자 / 여기: brand-blue+흰 글자).
 *   **규격 문서 §29 가 기준이다** — "활성 = brand-blue 배경 + 흰글자, 트랙은 연회색".
 *   그래서 이쪽을 남기고 값만 규격에 맞춘다:
 *     · font-size 10.5px → --fs-2xs(10). 10.5 는 글자 크기 스케일에 없는 값이다.
 *     · grid 4열 고정 → 항목 수만큼. 2개짜리(reception 시술상품/보유패키지)가 4열에 끼어 눌렸다. */
.bi-segment { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--space-0_5); background: var(--border-base); padding: var(--space-0_5); border-radius: var(--radius-xl); border: 1px solid color-mix(in srgb, var(--gray-300) 30%, transparent); }
.bi-segment__btn { border: 0; background: transparent; padding: var(--space-2) var(--space-0_5); border-radius: var(--radius-lg); cursor: pointer; font-size: var(--fs-2xs); font-weight: var(--fw-black); color: var(--txt-muted); letter-spacing: -.02em; line-height: 1.2; }
.bi-segment__btn.is-active { background: var(--brand-blue); color: var(--bg-card); }
.bi-desk__subgrp { display: flex; flex-direction: column; gap: var(--space-1_5); background: var(--gray-50); padding: var(--space-2); margin-bottom: var(--space-3); }
.bi-desk__subgrp .bi-desk__rpanel-lbl { margin-bottom: 0; }.bi-desk__catbtn.is-active,
.bi-desk__catbtn.is-active { color: var(--brand-blue); border-color: color-mix(in srgb, var(--brand-blue) 30%, transparent);  }
.bi-cell-empty,
.bi-cell-empty { font-size: var(--fs-xs); color: var(--txt-disabled); font-style: italic; padding: var(--space-1); }.bi-pick__badge { font-size: var(--fs-2xs); font-weight: var(--fw-black); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm); margin-left: var(--space-1_5); vertical-align: middle; border: 1px solid; }
/* ⚠ 이름은 JS 가 잇는다: `'bi-pick__badge--' + bk` (designer_chart·reception).
 *   마크업에 글자로 안 보여 "안 쓰는 규격"으로 몰려 지워졌다 → 되살린다. */

/* 상태색 fill/tone (reception=designer_chart 동일 패턴 통합 · 2026-07-30). fill=바 채움( 오버라이드), tone=뱃지(테두리 포함). */
.bi-lifecycle__fill--blue,    .bi-lifecycle__fill--blue    { background: var(--color-info-500); }
.bi-lifecycle__fill--emerald, .bi-lifecycle__fill--emerald { background: var(--color-success-500); }
.bi-lifecycle__fill--amber,   .bi-lifecycle__fill--amber   { background: var(--color-warning); }
.bi-lifecycle__fill--red,     .bi-lifecycle__fill--red     { background: var(--color-danger); }
.bi-lifecycle__tone--mute,    .bi-lifecycle__tone--mute    { color: var(--txt-muted); background: var(--border-light); border: 1px solid var(--border-base); }

/* 선불권/패키지 행 + CRM 빈상태 (reception=designer_chart 동일, 토큰 전역화 · 2026-07-30) */
.bi-desk__prepaid, .bi-desk__prepaid { display: flex; justify-content: space-between; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-2_5); background: var(--bg-input); border: 1px solid var(--border-base); border-radius: var(--radius-lg); }
.bi-desk__prepaid-list, .bi-desk__prepaid-list { display: flex; flex-direction: column; gap: var(--space-1_5); }
.bi-desk__prepaid-bal, .bi-desk__prepaid-bal { font-size: var(--fs-base); font-weight: var(--fw-extrabold); color: var(--brand-blue); flex-shrink: 0; }
.bi-desk__prepaid-expire, .bi-desk__prepaid-expire { font-size: var(--fs-2xs); color: var(--txt-disabled); font-weight: var(--fw-semibold); margin-top: var(--space-0_5); }
.bi-desk__crm-none, .bi-desk__crm-none { font-size: var(--fs-xs); color: var(--txt-disabled); text-align: center; padding: var(--space-1_5); background: color-mix(in srgb, var(--bg-input) 50%, transparent); border: 1px dashed var(--gray-100); border-radius: var(--radius-xl); font-style: italic; }

/* T6 컴포넌트 정규화 통합 (reception=canonical · designer_chart 값 수렴 · 클래스명 유지=JS무관 · 2026-07-30) */
.bi-lifecycle__bar, .bi-lifecycle__bar { display: flex; gap: var(--space-0_5); height: 6px; }
.bi-lifecycle__seg, .bi-lifecycle__seg { flex: 1; background: var(--border-base); }
.bi-lifecycle__seg--l, .bi-lifecycle__seg--l { border-radius: var(--radius-full) 0 0 var(--radius-full); }
.bi-lifecycle__seg--r, .bi-lifecycle__seg--r { border-radius: 0 var(--radius-full) var(--radius-full) 0; }
.bi-desk__chart-title, .bi-desk__chart-title { font-size: var(--fs-lg); color: var(--txt-primary); font-weight: var(--fw-extrabold); letter-spacing: -.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-desk__crm-open, .bi-desk__crm-open { font-size: var(--fs-2xs); background: color-mix(in srgb, var(--brand-blue) 10%, transparent); color: var(--brand-blue); border: 1px solid color-mix(in srgb, var(--brand-blue) 15%, transparent); font-weight: var(--fw-extrabold); padding: var(--space-1) var(--space-2); border-radius: var(--radius-md); cursor: pointer; display: inline-flex; align-items: center; gap: var(--space-1); }
.bi-cell-empty, .bi-cell-empty { padding: var(--space-8) var(--space-3); text-align: center; font-size: var(--fs-base); color: var(--txt-disabled); font-style: italic; }
.bi-emptybox, .bi-emptybox { background: var(--bg-card); border: 1px dashed var(--border-base); border-radius: var(--radius-xl); }
.bi-lifecycle, .bi-lifecycle { background: color-mix(in srgb, var(--bg-input) 40%, transparent); border: 1px solid var(--gray-100); border-radius: var(--radius-lg); padding: var(--space-2_5); display: flex; flex-direction: column; gap: var(--space-2); }
.bi-write-card__header, .bi-write-card__header { display: flex; justify-content: space-between; align-items: center; font-size: var(--fs-sm); }
.bi-desk__ok, .bi-desk__ok { margin-left: auto; color: var(--color-success); display: inline-flex; align-items: center; gap: var(--space-0_5); font-weight: var(--fw-extrabold); }
.bi-desk__prepaid-name, .bi-desk__prepaid-name { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-pick, .bi-pick { padding: var(--space-3); background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-xl); cursor: pointer; display: flex; justify-content: space-between; align-items: center; transition: all .15s; }
.bi-pick__r, .bi-pick__r { display: flex; align-items: center; gap: var(--space-1_5); font-weight: var(--fw-extrabold); color: var(--txt-primary); flex-shrink: 0; }
.bi-pulse, .bi-pulse { animation: bi-pulse 1.6s infinite; }
.bi-lifecycle__stages, .bi-lifecycle__stages { display: flex; justify-content: space-between; font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); color: var(--txt-disabled); }
.bi-desk__status, .bi-desk__status { font-size: var(--fs-xs); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm); font-weight: var(--fw-extrabold); margin-top: var(--space-1_5); align-self: flex-start; }
.bi-desk__ticket, .bi-desk__ticket { background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-xl); padding: var(--space-3);  display: flex; flex-direction: column; gap: var(--space-2_5); }
.bi-desk__ticket-bar, .bi-desk__ticket-bar { width: 100%; background: var(--gray-100); border-radius: var(--radius-full); height: 6px; overflow: hidden; }
/* ⚠ 셀렉터가 제 이름을 두 번 썼다(합치기 잔재). 높이도 안 정해 padding 이 20px 을 만들었다 →
 * §12-4 사다리 xs 22(2026-08-14). */
.bi-desk__ticket-btn { background: var(--brand-navy); color: var(--bg-card); border: 0; font-size: var(--fs-2xs); height: 22px; display: inline-flex; align-items: center; justify-content: center; padding: 0 var(--space-2_5); border-radius: var(--radius-lg); font-weight: var(--fw-extrabold); cursor: pointer; flex-shrink: 0; }
.bi-desk__ticket-sub-name, .bi-desk__ticket-sub-name { font-size: var(--fs-sm); font-weight: var(--fw-extrabold); color: var(--txt-primary); flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-desk__ticket-sub-rem, .bi-desk__ticket-sub-rem { font-size: var(--fs-sm); color: var(--brand-blue); font-weight: var(--fw-extrabold); flex-shrink: 0; }
.bi-desk__ticket-subs, .bi-desk__ticket-subs { display: flex; flex-direction: column; gap: var(--space-2); }
.bi-desk__ticket-top, .bi-desk__ticket-top { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-2); }

/* ═══════════════════════════════════════════════════════════════
   CRM 요약 카드 (공용) — Step1 대기(reception)·Step2 시술(designer_chart) 공유.
   두 모듈이 .bi-desk__crm / .bi-desk__crm 로 각자 구현하던 drift 를
   단일 공용 클래스 .bi-crmcard 로 통합(2026-07-31). 두 모듈 JS 가 이 클래스를 사용.
   ═══════════════════════════════════════════════════════════════ */
.bi-crmcard { background: var(--bg-input); border: 1px solid var(--gray-100); border-radius: var(--radius-xl); padding: var(--space-2_5); display: flex; flex-direction: column; gap: var(--space-1_5); }
.bi-crmcard__top { display: flex; justify-content: space-between; align-items: center; font-size: var(--fs-xs); }
.bi-crmcard__top span:first-child { color: var(--txt-primary); font-weight: var(--fw-black); }
.bi-crmcard__top span:last-child, .bi-crmcard__top .bi-num { color: var(--txt-disabled); }
.bi-crmcard__msg { font-size: var(--fs-xs); color: var(--txt-muted); line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.bi-crmcard__msg.is-clampable { cursor: pointer; }
.bi-crmcard__msg.is-expanded { display: block; -webkit-line-clamp: unset; overflow: visible; }
.bi-crmcard__more { padding: 0; border: 0; background: none; color: var(--txt-disabled); font-size: var(--fs-2xs); font-weight: var(--fw-semibold); cursor: pointer; display: inline-flex; align-items: center; gap: var(--space-1); }
.bi-crmcard__more i { font-size: var(--fs-2xs); }
.bi-crmcard__foot { display: flex; align-items: center; font-size: var(--fs-2xs); padding-top: var(--space-1_5); border-top: 1px solid var(--border-light); }

/* ── 재방주기 박스 (공용) — reception cycle-box / dchart cyclebox 통합(2026-07-31). 단일 .bi-cyclebox 사용 ── */
/* 규격 §40-2 «안쪽 구획은 둘레가 아니라 구분선으로» — 셸 카드가 이미 테두리·둥글기를 갖는다.
 * .bi-cyclebox 둘은 .bi-write-grid-2 안에 **가로로 나란히** 놓이므로 **둘째 칸에 왼쪽 세로선**을 긋는다.
 * (2026-08-21 — 178×85 라 옛 검사 문턱 220×90 에 걸리지 않아 «상자 안 상자 0» 으로 읽혔다.) */
.bi-cyclebox { background: transparent; border: 0; border-radius: 0; padding: var(--space-2_5) 0; display: flex; flex-direction: column; gap: var(--space-1); }
.bi-write-grid-2 > .bi-cyclebox + .bi-cyclebox { border-left: 1px solid var(--border-base); padding-left: var(--space-4); }
.bi-cyclebox__lbl { font-size: var(--fs-xs); color: var(--txt-disabled); font-weight: var(--fw-black); }
.bi-cyclebox__val { font-size: var(--fs-md); font-weight: var(--fw-black); color: var(--txt-primary); }
.bi-cyclebox__unit { font-size: var(--fs-xs); color: var(--txt-disabled); font-weight: var(--fw-bold); }
.bi-cyclebox__hint { font-size: var(--fs-2xs); color: var(--txt-muted); font-weight: var(--fw-extrabold); }

/* ── 티켓 진행바 fill (공용) — reception/dchart 동일(rc-blue=dc-blue=brand-blue) → 그룹 통합(2026-07-31). is-crit 등 상태는 모듈 유지 ── */
.bi-desk__ticket-bar > div, .bi-desk__ticket-bar > div { height: 100%; background: var(--brand-blue); border-radius: var(--radius-full); transition: width .3s; }

/* ── 디자이너 이름 뱃지 + Col2 헤더 타이틀 (공용) — reception/dchart 동일 → 그룹 통합 (2026-08-03) ── */
.bi-queue__emp, .bi-queue__emp { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-secondary); flex-shrink: 0; }
.bi-row { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
 * [일원화 2026-08-07] 구 lib/css/booking_schedule.css
 *   booking_renew·booking_time 예약일정 공통 크롬. 원래도 common() 전역 로드.
 *   ※ 여기까지가 이 파일의 출처 경계다 — 재구성(sg2 프리미티브화) 시 이 배너를 기준으로 찾는다.
 * ═══════════════════════════════════════════════════════════════════════════ */
/* 구 lib/css/booking_schedule.css (2026-08-07 이 파일로 이관) — 예약일정표 공통 크롬(booking_renew · booking_time)
 * 두 모듈(일별/시간별)이 스코프(.bi-page)만 다르게 100% 복제하던 규칙을 통합.
 *   .bi-bki-*  예약 상세 패널  ·  .bi-bksch-* 사이드 필터/통계  ·  .bi-bk-* 범례/서브바/빈패널
 * 접두어가 두 모듈 전용(bki/bksch) 또는 타 모듈과 무충돌(bk 범례·서브바)이라 전역 로드 무해.
 *   ⚠ 모듈 고유·반응형(@media)·분기 규칙은 각 style.css 에 유지(나중 로드로 override 승).
 *   (구: function.php head 에서 개별 <link> 전역 로드 → 2026-08-07 style.css 로 통합)
 */

.bi-bk-legend-item {
    display: flex;
    align-items: center;
    gap: var(--space-1_5);
    font-size: var(--fs-sm);
    color: var(--txt-muted);
}
.bi-bk-legend-dot {
    width: 12px;
    height: 12px;
    border-radius: var(--radius-xs);
    flex-shrink: 0;
}
.bi-bk-legend-dot--request   { background: var(--color-success-500); }
.bi-bk-legend-dot--confirmed { background: var(--color-info-500); }
.bi-bk-legend-dot--completed { background: var(--txt-disabled); }
.bi-bk-legend-dot--cancelled { background: var(--color-danger-50); border: 1px solid var(--color-danger-300); }
.bi-bk-legend--subbar { display: flex; align-items: center; gap: var(--space-3); flex-shrink: 0; }
.bi-bk-legend--subbar .bi-bk-legend-item { font-size: var(--fs-xs); white-space: nowrap; }
.bi-bk-panel-title {
    font-weight: var(--fw-bold);
    font-size: var(--fs-lg);
    color: var(--txt-primary);
}
.bi-bk-panel-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 280px;
    padding: var(--space-6);
    color: var(--txt-disabled);
}
.bi-bk-panel-empty-icon {
    width: 64px;
    height: 64px;
    background: var(--bg-input);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: var(--space-4);
    font-size: var(--icon-md);   /* §11 아이콘 사다리 */
    color: var(--gray-300);
}
.bi-bk-panel-empty-title {
    font-size: var(--fs-md);
    font-weight: var(--fw-bold);
    color: var(--txt-muted);
    margin: 0 0 var(--space-2);
}
.bi-bk-panel-empty-desc {
    font-size: var(--fs-sm);
    color: var(--txt-disabled);
    text-align: center;
    margin: 0;
    line-height: 1.6;
}
.bi-bki-head .bi-bk-panel-title { display: flex; align-items: center; gap: var(--space-2); }
.bi-bki-head .bi-bk-panel-title i { color: var(--brand-navy); font-size: var(--fs-md); }
.bi-bki-profile {
    position: relative; display: flex; align-items: center; gap: var(--space-3);
    background: color-mix(in srgb, var(--bg-input) 50%, transparent); border: 1px solid var(--border-light); border-radius: var(--radius-xl); padding: var(--space-2);
}
/* ⚠ 2026-09-28 사용자 지시 — 「예약상세정보에는 **네모로** 고객명 옆에 그대로 나오는데
     **동그라미 아이콘으로 똑같이** 해줘」. --radius-xl(12) 은 «둥근 네모» 라 동그라미가 아니었다.
   ⚠ 크기(40)·색은 그대로 둔다 — 바뀐 것은 모양과 «안에 들어가는 것»(이니셜 → ★/👑) 뿐이다.
     안쪽 아이콘은 .bi-grade 가 함께 입혀져 색을 정한다(§90). */
.bi-bki-avatar {
    width: 40px; height: 40px; flex-shrink: 0; border-radius: var(--radius-full);
    background: var(--brand-navy); color: var(--bg-card); font-weight: var(--fw-extrabold); font-size: var(--fs-md);
    display: flex; align-items: center; justify-content: center;
}
.bi-bki-profile-info { flex: 1; min-width: 0; padding-right: var(--space-4); }
.bi-bki-profile-nameline { display: flex; align-items: center; gap: var(--space-1_5); }
.bi-bki-profile-name { font-size: var(--fs-md); font-weight: var(--fw-black); color: var(--gray-950); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-bki-gender { flex-shrink: 0; font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--color-indigo-700); background: var(--color-indigo-50); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm); line-height: 1.5; }
.bi-bki-profile-phone { font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--txt-disabled); margin-top: var(--space-0_5); font-family: var(--font-mono); }
.bi-bki-profile-phone:empty::before { content: '전화번호 미등록'; color: var(--gray-300); }
.bi-bki-close {
    position: absolute; top: 8px; right: 8px;
    width: 22px; height: 22px; padding: 0; border: 0; background: transparent;
    color: var(--txt-disabled); font-size: var(--fs-md); line-height: 1; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius-md);
    transition: background .12s, color .12s;
}
.bi-bki-close:hover { background: var(--border-light); color: var(--gray-600); }
.bi-bki-status.status_round {
    flex-shrink: 0;
    padding: var(--space-1) var(--space-2_5); border-radius: var(--radius-full);
    font-size: var(--fs-xs); font-weight: var(--fw-extrabold); color: var(--bg-card);
}
.bi-bki-table {
    border: 1px solid var(--border-base); border-radius: var(--radius-xl); padding: var(--space-3);
    display: flex; flex-direction: column; gap: var(--space-2_5);
}
.bi-bki-row { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); }
.bi-bki-row--top { align-items: flex-start; }
.bi-bki-k { font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--txt-disabled); flex-shrink: 0; }
.bi-bki-v { font-size: var(--fs-xs); font-weight: var(--fw-extrabold); color: var(--txt-primary); text-align: right; min-width: 0; word-break: break-all; display: inline-flex; align-items: center; gap: var(--space-1_5); justify-content: flex-end; }
.bi-bki-vi { font-size: var(--fs-xs); color: var(--color-indigo-500); }
.bi-bki-mono { font-family: var(--font-mono); }
.bi-bki-goods {
    max-width: 175px;
    background: color-mix(in srgb, var(--bg-input) 70%, transparent); border: 1px solid var(--gray-100); border-radius: var(--radius-lg); padding: var(--space-1) var(--space-2);
}
.bi-bki-memo { background: color-mix(in srgb, var(--color-warning-50) 60%, transparent); border: 1px solid var(--color-warning-200); border-radius: var(--radius-xl); padding: var(--space-2_5) var(--space-3); }
.bi-bki-memo-label { display: flex; align-items: center; gap: var(--space-1_5); font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); color: var(--color-warning-800); text-transform: uppercase; letter-spacing: .02em; }
.bi-bki-memo-label i { font-size: var(--fs-xs); color: var(--color-warning-600); }
.bi-bki-memo-text { margin-top: var(--space-1_5); font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--color-warning-900); line-height: 1.55; white-space: pre-line; max-height: 84px; overflow-y: auto; }
.bi-bki-actsec { display: flex; flex-direction: column; gap: var(--space-2_5); padding-top: var(--space-3); border-top: 1px solid var(--gray-100); }
.bi-seclabel { font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); color: var(--txt-disabled); text-transform: uppercase; letter-spacing: .04em; }
/* 인스펙터 컨테이너 + 상태처리 버튼 base — 전역 input[type=button] 강제스타일(gradient·content-box·line-height27·min-width54) 무력화. booking_renew·booking_time 공통 (2026-07-31 모듈 중복 이관) */
.bi-bki { display: flex; flex-direction: column; padding: var(--space-4); }
.bi-bki > * + * { margin-top: var(--space-3_5); }
.bi-write-grid-2 input[type="button"].bi-bki-btn {
    height: 40px; min-width: 0; padding: 0 var(--space-3);
    box-sizing: border-box; line-height: 1; vertical-align: middle;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: var(--radius-xl); font-size: var(--fs-base); font-weight: var(--fw-extrabold); cursor: pointer;
    border: 1px solid transparent; background-image: none;
    transition: background .15s, color .15s, border-color .15s;
}
.bi-write-grid-2 input[type="button"].bi-bki-btn--sales { background: var(--color-success); color: var(--bg-card); text-align: center; }
.bi-bki-sublinks { display: flex; justify-content: flex-end; gap: var(--space-1); min-height: 0; }
.bi-bki-sublinks input[type="button"].bi-bki-link {
    height: 28px; min-width: 0; padding: 0 var(--space-2_5);
    box-sizing: border-box; line-height: 1; vertical-align: middle;
    background: transparent; background-image: none; border: 0; border-radius: var(--radius-lg);
    color: var(--txt-muted); font-size: var(--fs-xs); font-weight: var(--fw-bold); cursor: pointer;
    transition: background .12s, color .12s;
}
.bi-write-grid-2 input[type="button"].bi-bki-btn--primary { background: var(--brand-blue); color: var(--bg-card); }
.bi-write-grid-2 input[type="button"].bi-bki-btn--primary:hover { background: var(--brand-navy); }
.bi-write-grid-2 input[type="button"].bi-bki-btn--sales:hover { background: var(--color-success-700); }
.bi-bki-sublinks input[type="button"].bi-bki-link:hover { background: var(--border-light); color: var(--txt-secondary); }
.bi-bki-sublinks input[type="button"].bi-bki-link--danger { color: var(--color-danger-600); }
.bi-bki-sublinks input[type="button"].bi-bki-link--danger:hover { background: var(--color-danger-50); color: var(--color-danger-700); }
.bi-bksch-sec-head {
    display: flex; align-items: center; justify-content: space-between;
    padding-bottom: var(--space-1_5); border-bottom: 1px solid var(--gray-100);
}
.bi-seclabel span { color: var(--txt-muted); }
.bi-bksch-sec-toggle {
    border: 0; background: transparent; padding: 0; cursor: pointer;
    font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); color: var(--brand-blue);
}
.bi-bksch-sec-toggle:hover { text-decoration: underline; }
.bi-bksch-emp-list { display: flex; flex-direction: column; gap: var(--space-0_5); height: 210px; overflow-y: auto; }
/* 위젯 카드 + 체크박스 전역 스프라이트 무력화(CLAUDE §5-1) — booking_renew·booking_time 공통 (2026-07-31 모듈 중복 이관) */
.bi-bksch-side-sec { padding: var(--space-4); background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-2xl);  display: flex; flex-direction: column; gap: var(--space-2_5); }.bi-bksch-emp-row {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-1_5) var(--space-2); border-radius: var(--radius-xl);
    border: 1px solid transparent; cursor: pointer; user-select: none;
    transition: background .12s, border-color .12s;
}.bi-bksch-emp-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.bi-bksch-emp-info { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.2; }
.bi-bksch-emp-name { font-size: var(--fs-sm); font-weight: var(--fw-extrabold); color: var(--gray-800); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-bksch-emp-role { font-size: var(--fs-2xs); font-weight: var(--fw-semibold); color: var(--txt-disabled); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: var(--space-0_5); }
.bi-bksch-emp-cnt {
    flex-shrink: 0; font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); color: var(--txt-muted);
    background: var(--border-light); border: 1px solid var(--gray-200); border-radius: var(--radius-md); padding: var(--space-0_5) var(--space-1_5);
}
.bi-bksch-status-chip {
    flex: 1 1 28%; min-width: 0; height: 30px; padding: 0 var(--space-2_5);
    border: 1px solid var(--border-base); border-radius: var(--radius-lg); background: var(--bg-card);
    color: var(--gray-600); font-size: var(--fs-sm); font-weight: var(--fw-semibold); cursor: pointer;
    transition: background .15s, border-color .15s, color .15s;
}
.bi-bksch-status-chip:hover { background: var(--bg-input); border-color: var(--gray-300); }
.bi-bksch-status-chip.is-active { background: var(--brand-navy); border-color: var(--brand-navy); color: var(--bg-card); }
.bi-bksch-stat { display: flex; flex-direction: column; gap: var(--space-0_5); padding: var(--space-2) var(--space-2_5); border-radius: var(--radius-xl); border: 1px solid transparent; }
.bi-bksch-stat-k { font-size: var(--fs-2xs); font-weight: var(--fw-bold); }
.bi-bksch-stat-v { font-size: var(--fs-md); font-weight: var(--fw-black); }
.bi-bksch-stat--book { background: color-mix(in srgb, var(--color-info-50) 60%, transparent); border-color: var(--color-info-100); }
.bi-bksch-stat--book .bi-bksch-stat-k { color: var(--color-info-500); }
.bi-bksch-stat--book .bi-bksch-stat-v { color: var(--color-info-700); }
.bi-bksch-stat--done { background: color-mix(in srgb, var(--color-success-50) 60%, transparent); border-color: var(--color-success-100); }
.bi-bksch-stat--done .bi-bksch-stat-k { color: var(--color-success-500); }
.bi-bksch-stat--done .bi-bksch-stat-v { color: var(--color-success-700); }
.bi-bksch-typefilter { display: flex; flex-direction: column; gap: var(--space-0_5); }
.bi-bksch-emp-row:hover { background: var(--bg-input); border-color: var(--gray-100); }
.bi-bksch-emp-dot.is-naver  { background: var(--color-success-500); }
.bi-bksch-emp-dot.is-walkin { background: var(--color-info-500); }
.bi-bksch-type-name { flex: 1; min-width: 0; font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--gray-800); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ============================================================
   우측열: 예약상세 인스펙터 패널 + 실시간 플랜 일지
   (booking_renew·booking_time 공통 — 2026-07-31 booking_renew/style.css 에서 이관)
   ============================================================ */
.bi-bk-rightcol {
    width: 340px; flex-shrink: 0; align-self: flex-start;
    display: flex; flex-direction: column; gap: var(--space-3); min-height: 0;
    overflow: visible;
}
.bi-bk-rightcol .bi-bk-info-panel { width: 100%; flex: 0 0 auto; overflow: visible; }
.bi-bk-info-panel {
    width: 340px;
    display: flex; flex-direction: column; overflow: hidden;
    background: var(--bg-card); border-radius: var(--radius-xl); border: 1px solid var(--border-base);
}
.bi-bk-panel-header {
    padding: var(--space-3_5) var(--space-5); border-bottom: 1px solid var(--border-light);
    background: color-mix(in srgb, var(--bg-input) 50%, transparent); flex-shrink: 0;
}
.bi-bk-panel-body { overflow: visible; position: relative; }/* 실시간 최근 플랜 일지 */
.bi-bka {
    flex: 0 0 auto; display: flex; flex-direction: column; overflow: hidden;
    background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-xl);
}
.bi-bka-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border-light); flex-shrink: 0;
}
.bi-bka-live { position: relative; width: 8px; height: 8px; border-radius: 50%; background: var(--color-danger); flex-shrink: 0; }
.bi-bka-live::before {
    content: ''; position: absolute; inset: 0; border-radius: 50%;
    background: var(--color-danger-400); opacity: .75; animation: sdpBkaPing 1.3s cubic-bezier(0,0,.2,1) infinite;
}
@keyframes sdpBkaPing { 0% { transform: scale(1); opacity: .7; } 75%, 100% { transform: scale(2.4); opacity: 0; } }
.bi-bka-list { height: 195px; overflow-y: auto; padding: var(--space-2_5) var(--space-3); display: flex; flex-direction: column; gap: var(--space-1_5); }
.bi-bka-item {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
    padding: var(--space-2) var(--space-2_5); border: 1px solid var(--border-light); border-radius: var(--radius-xl); background: color-mix(in srgb, var(--bg-page) 40%, transparent);
    transition: background .12s;
}
.bi-bka-item:hover { background: var(--gray-50); }
.bi-bka-badge {
    flex-shrink: 0; min-width: 34px; text-align: center;
    font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-md); border: 1px solid transparent;
}
.bi-bka-badge.is-emerald { background: var(--color-success-50); color: var(--color-success-700); border-color: var(--color-success-100); }
.bi-bka-badge.is-blue    { background: var(--color-info-50); color: var(--color-info-600); border-color: var(--color-info-100); }
.bi-bka-badge.is-purple  { background: var(--color-purple-50); color: var(--color-purple-700); border-color: var(--color-purple-50); }
.bi-bka-badge.is-red     { background: var(--color-danger-50); color: var(--color-danger-600); border-color: var(--color-danger-100); }
.bi-bka-badge.is-gray    { background: var(--border-light); color: var(--txt-muted); border-color: var(--border-base); }
.bi-bka-name { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--gray-800); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-bka-emp  { font-size: var(--fs-2xs); font-weight: var(--fw-semibold); color: var(--txt-disabled); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-bka-time { flex-shrink: 0; font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--txt-disabled); font-family: var(--font-mono); }

/* ═══════════════════════════════════════════════════════════════════════════
 * [일원화 2026-08-07] 구 lib/css/popup_layer.css
 *   레이어 팝업 셸(호스트측 .write_layout 등). 원래도 common() 전역 로드.
 *   ※ 여기까지가 이 파일의 출처 경계다 — 재구성(sg2 프리미티브화) 시 이 배너를 기준으로 찾는다.
 * ═══════════════════════════════════════════════════════════════════════════ */
.write_layout{
	width: 100%;
       position: absolute;
    top: 0px;
    left: 10px;
    height: 100%;
    float: left;
    display: none;
    z-index: 2000;   /* 셸(사이드바·헤더 1000 대) 위 — 팝업은 화면을 덮는다(2026-08-28) */
}
.write_layout_pop{
	/* ⚠ 화면마다 달랐다 — designer_chart 에서는 content-box 로 잡혀 테두리 2px 이 더해졌고,
	   JS 가 맞춘 높이보다 상자가 2px 커져 버튼 아래에 틈이 남았다(2026-08-27 실측).
	   상자 크기의 셈법은 상자가 스스로 정한다 — 여는 화면에 맡기지 않는다. */
	box-sizing: border-box;
	position: relative;
        top: -10%;
    left: -250px;
    height: 300px;
	width: 600px;

/*팝업박스 보더 — 라운드 + 연한 테두리 + 그림자 (디자인 정합)*/
/* 스타일보드 §04 형태 — 팝업 박스는 라운드 12 + 2겹 그림자(떠 있는 것에만 그림자, 2026-08-25) */
border: 1px solid var(--border-base);
border-radius: var(--pop-radius);
box-shadow: var(--pop-shadow);
overflow: hidden;
background: var(--bg-card);
color: var(--gray-800);
    display: none;
}

/* 결제 팝업 박스 고정 높이 — JS 인라인/auto-resize 보다 우선() */
/* 2026-07-31 #card_pay 고정높이(513/iframe449) 제거.
 *   pop_name 'card_pay' 는 **6개 팝업이 공유**한다 — 카드결제(구/신)·카드승인취소(구/신)·리포트 취소 2종.
 * 라 호출부가 넘긴 높이를 전부 덮어써, 디자이너 결제(비사업자·PayUp) 선택 시 펼쳐지는
 *   카드정보 입력 블록만큼 아래(결제일자·카드종류·승인번호·버튼)가 잘렸다.
 *   도입 사유는 "JS 인라인/캐시보다 우선"(2026-06-23)이었으나 card_pay 는 popup_layer.js:92 _noFit 이라
 *   auto-resize 가 애초에 돌지 않고, 각 호출부가 이미 적정 높이를 넘긴다 → 호출부 값을 그대로 쓴다.
 *   본서버(shop)에도 이 규칙은 없다(전수 확인). 2026-08-27 에 #prepay·#n_pay 도 같은 이유로 제거했다. */
/* 2026-08-27 제거 — 이 네 줄이 «버튼 아래 빈 띠» 의 진짜 원인이었다(사용자 캡처 pop2·pop3).
 *   ① `!important` 라 JS 자동맞춤이 계산한 옳은 높이(선불권 354)를 **덮어썼다**.
 *      인라인은 354 인데 그려진 건 548 이었다 — 인라인만 보면 «맞았다» 로 읽힌다.
 *   ② iframe 높이가 **헤더 64px 가정**으로 계산돼 있었다. 실제 헤더는 규격상 56 이다.
 *      548 − 484 = 64 가 그 흔적이다(2026-08-26 에 고친 그 가정이 CSS 에 한 벌 더 있었다).
 *   높이는 이제 내용이 정한다 — popup_layer.js 의 _fit 이 재서 맞춘다. */

/* 스타일 카탈로그 팝업(style_catalog) — 박스 크기 확정(넓게·86vh), iframe 풀, 라운드 20
   ⚠ 2026-08-31 — 여기 있던  를 지웠다.
   이 팝업이 헤더를 **제 안에 하나 더** 그리고 있어서 껍데기 헤더를 숨겨 놨던 것인데,
   그 때문에 상자(760)와 iframe(676)이 84 만큼 어긋나 푸터 아래 흰 띠가 남았다
   (사용자 지적). 안쪽 헤더를 없앴으므로 이제 껍데기 헤더가 유일한 헤더다 — 숨기지 않는다. */
#style_catalog{ width: 1120px; max-width: 96vw; height: 86vh; max-height: 860px; border-radius: var(--radius-2xl); }
#style_catalog > iframe{ width: 100%; }
/* ⚠ 2026-08-21 — 여기 있던 «화면 중앙 재정렬»(left/top 50% + translate(-50%,-50%)) 을 **삭제**했다.
 *   popup_layer.js 가 이미 top/left 를 계산해 인라인으로 중앙에 놓는다(실측: 1440×900 에서 900×600 팝업이 270,150 = 정확히 중앙).
 *   그 위에 transform: translate(-50%,-50%) 가 더해지면 **제 크기의 절반만큼 더 밀린다** — 카탈로그만 가운데가 아니었던 이유다.
 *   중앙 정렬은 한 곳에서만 한다. */

/* ================= [1] counter (bi-counter-*) — 구 counter.css ================= */
/*
 * lib/css/counter.css  (구 template/page/counter/style.css)
 * 2026-06-26: counter 모듈 삭제 시, 이 bi-counter-* 디자인 시스템을 buy_write(매출/예약/매입등록)가
 *   @import 로 공유하고 있어 lib/css 로 이전. buysell/style.css 가 @import url('/lib/css/counter.css').
 * 공용 POS/카운터 룩 — 전 셀렉터 .bi-counter- 스코프 격리. FA Pro 5.13.
 * §8-5 레거시 전역 CSS 함정 방어: textarea/input/select/checkbox 명시 override.
 */

/* ===== 토큰 (wrapper 로컬) ===== */
.bi-counter-wrap {
    --cc-navy: var(--brand-navy);
    --cc-blue: var(--brand-blue);
    --cc-blue-2: var(--color-info-600);
    --cc-ink: var(--txt-primary);
    --cc-ink-2: var(--txt-secondary);
    --cc-gray: var(--txt-muted);
    --cc-gray-l: var(--txt-disabled);
    --cc-line: var(--border-base);
    --cc-line-l: var(--border-light);
    --cc-bg: var(--bg-page);
    --cc-rose: var(--color-rose-600);
    --cc-emerald: var(--color-success);
    --cc-amber: var(--color-warning-600);
    color: var(--cc-ink-2);
    padding: var(--space-4);
    box-sizing: border-box;
    height: calc(100vh - 64px);   /* stack/짧은 뷰포트에서 콘텐츠가 넘치면 하단 잘림 → wrap 을 스크롤 컨테이너로(너비 무관, 전역) */
    overflow-y: auto;
    background: var(--cc-bg);
}#counter_portal {
    --cc-navy:var(--brand-navy); --cc-blue:var(--brand-blue); --cc-blue-2:var(--color-info-600); --cc-ink:var(--txt-primary); --cc-ink-2:var(--txt-secondary); --cc-gray:var(--txt-muted); --cc-gray-l:var(--txt-disabled); --cc-line:var(--border-base); --cc-line-l:var(--border-light); --cc-bg:var(--bg-page); --cc-rose:var(--color-rose-600); --cc-emerald:var(--color-success); --cc-amber:var(--color-warning-600);
}
#counter_portal *, #counter_portal *::before, #counter_portal *::after { box-sizing: border-box; }
#counter_portal i.fa, #counter_portal i.fas, #counter_portal i.far, #counter_portal i.fal { font-family: 'Font Awesome 5 Pro'; }
.bi-counter-wrap .is-hidden { display: none; }
.bi-counter-pulse { animation: bi-counter-pulse 1.6s infinite; }
@keyframes bi-counter-pulse { 0%,100% { opacity: 1; } 50% { opacity: .4; } }

/* ===== 2컬럼 그리드 (8/4, xl=1280 이하 stack) ===== */
.bi-counter-grid {
    display: grid;
    grid-template-columns: minmax(0, 8fr) minmax(0, 4fr);
    gap: var(--space-3);
    align-items: start;
}
.bi-counter-col { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }

/* ── POS 를 §40-3 표준 셸로 (2026-08-21 · 사용자 지시 «예약일정표처럼») ──────────────
 * 예약일정표는 프레임 → **카드 하나** → 툴바 + 3열이고, 열은 §40-2 대로 **구분선**으로 나뉜다.
 * POS 는 카드가 없어 툴바가 카드 흉내를 내고 안쪽 구획이 각자 둘레를 그렸다 — 상자 안 상자.
 * 이제 .bi-erp-card 로 감쌌으므로, 그 안에서는 둘레를 걷고 선으로 나눈다.
 *   가로로 나란한 것(좌/우 열) = 왼쪽 세로선 · 세로로 쌓인 것 = 위쪽 가로선 · 첫 칸에는 안 긋는다. */
/* align-items: start 면 짧은 열의 높이만큼만 선이 그려져 **구분줄이 끝까지 안 간다**(사용자 지적).
 * 카드 안에서는 두 열이 같은 높이를 갖게 해서 세로선이 아래까지 내려가게 한다. */
.bi-erp-card > .bi-counter-grid { gap: 0; align-items: stretch; }
.bi-erp-card .bi-counter-col { gap: 0; }
.bi-erp-card .bi-counter-card,
.bi-erp-card .bi-counter-datebar {
    border: 0; border-radius: 0; box-shadow: none; background: transparent;
}
.bi-erp-card > .bi-counter-grid > .bi-counter-col + .bi-counter-col { border-left: 1px solid var(--border-base); }
.bi-erp-card .bi-counter-col > * + * { border-top: 1px solid var(--border-base); }

/* ===== 카드 공통 ===== */
.bi-counter-card {
    background: var(--bg-card);
    border: 1px solid var(--cc-line);
    border-radius: var(--radius-2xl);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.bi-counter-card__head {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-3_5) var(--space-5);
    background: var(--gray-50);
    border-bottom: 1px solid var(--cc-line-l);
    flex-shrink: 0;
}
.bi-counter-card__title {
    font-size: var(--fs-md); font-weight: var(--fw-black); color: var(--gray-950);
    display: inline-flex; align-items: center; gap: var(--space-1_5);
    text-transform: uppercase; letter-spacing: .03em;
}
.bi-counter-card__title--lg { font-size: var(--fs-md); }
.bi-counter-card__title i { color: var(--cc-blue); }

/* §8-5 전역 checkbox visibility:hidden override */
.bi-counter-wrap input[type="checkbox"] {
    visibility: visible; display: inline-block;
    width: 14px; height: 14px; accent-color: var(--cc-blue); margin: 0; cursor: pointer;
}

.bi-counter-cust-body { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-4); }

/* ===== 수납 대기 결제 큐 ===== */
/* 규격 §40-2 «안쪽 구획은 둘레가 아니라 구분선으로» — 셸 카드(.bi-counter-card) 안이다.
 * 둘레(테두리+둥글기)는 빼고, 세로로 쌓인 구획이므로 **아래 가로선**으로 다음 구획과 나눈다.
 * 틴트는 남긴다 — 이 구획은 **누를 수 있는 대기열**이라 배경이 그 신호를 맡는다(색은 둘레가 아니다).
 * (2026-08-21 — 프레임이 .bi-counter-wrap 이라 옛 검사 범위(.bi-erp-card 안)에서 통째로 빠져 있었다.) */
.bi-counter-queue-box {
    padding: var(--space-3); border-radius: 0; border: 0;
    border-bottom: 1px solid var(--border-base);
    background: color-mix(in srgb, var(--brand-navy) 5%, transparent);
    display: flex; flex-direction: column; gap: var(--space-1_5);
}
.bi-counter-queue-title {
    font-size: var(--fs-sm); font-weight: var(--fw-black); color: var(--cc-navy);
    text-transform: uppercase; letter-spacing: .04em;
    display: inline-flex; align-items: center; gap: var(--space-1_5);
}
.bi-counter-queue-title i { color: var(--cc-rose); }
.bi-counter-queue-meta { font-size: var(--fs-xs); color: var(--cc-gray-l); font-weight: var(--fw-bold); }
.bi-counter-queue { display: flex; gap: var(--space-2); overflow-x: auto; padding-bottom: var(--space-1); }
/* ⚠ 함정 — <button> 에 글자 크기를 안 주면 상속이 아니라 **브라우저 기본 13.333px** 이 된다.
 * 이 카드가 그랬다: 규격 스케일(10·11·12·13·14·16·…) 어디에도 없는 «13.3» 이 실측에 찍혔고,
 * style.css 를 아무리 grep 해도 그 값이 안 나온다 — 아무도 안 적었기 때문이다(2026-08-21).
 * 버튼은 글자 크기를 **반드시 적는다.** */
.bi-counter-qcard {
    flex-shrink: 0; text-align: left; cursor: pointer; font-size: var(--fs-base);
    padding: var(--space-2_5); border-radius: var(--radius-xl);
    background: var(--bg-card); border: 1px solid var(--cc-line); color: var(--txt-secondary);
    transition: all .15s; min-width: 0;
}
.bi-counter-qcard:hover { background: var(--bg-input); }
.bi-counter-qcard.is-active {
    background: color-mix(in srgb, var(--color-info-50) 70%, transparent); border-color: var(--cc-blue); color: var(--cc-navy);
}
.bi-counter-qcard__top { display: flex; align-items: center; gap: var(--space-1_5); line-height: 1; }
.bi-counter-qgrade {
    font-size: var(--fs-2xs); font-weight: var(--fw-black); padding: var(--space-0_5) var(--space-1); border-radius: var(--radius-xs);
    background: var(--border-base); color: var(--txt-muted); flex-shrink: 0;
}
.bi-counter-qgrade.is-hi { background: var(--color-warning-100); color: var(--color-warning-700); }
.bi-counter-qname { font-weight: var(--fw-extrabold); font-size: var(--fs-xs); color: var(--txt-primary); white-space: nowrap; }
.bi-counter-qpaid { color: var(--color-success-500); font-size: var(--fs-sm); flex-shrink: 0; }
.bi-counter-qdot { width: 6px; height: 6px; background: var(--color-rose-500); border-radius: 50%; flex-shrink: 0; animation: bi-counter-pulse 1.2s infinite; }
.bi-counter-qsub { font-size: var(--fs-2xs); color: var(--cc-gray-l); font-weight: var(--fw-medium); margin: var(--space-1_5) 0 0; line-height: 1; white-space: nowrap; }
.bi-counter-qpaid-txt { color: var(--color-success); font-weight: var(--fw-extrabold); }
.bi-counter-qempty { font-size: var(--fs-sm); color: var(--cc-gray-l); font-style: italic; padding: var(--space-2); }

/* 구 .bi-counter-field/-row/--2 와 그 > label — §21 .bi-write-row/.bi-write-field/.bi-write-label,
 * 단독은 §40-10 .bi-col --gap-4 + .bi-minw-0 으로 흡수(2026-08-11).
 * ⚠ .bi-write-field 는 flex:1;min-width:200px 라 **행 안에서만** 안전하다.
 *   세로 스택 안에 단독으로 쓰면 세로로 늘어난다 → 단독은 .bi-col 조합. */
/* §8-5 전역 input[type=text]/select/textarea border-radius·height override */
/* ⚠ 2026-08-12: 여기 있던 블록은 **변형이 아니라 입력의 두 번째 스킨**이었다.
 * 선언 11개 중 9개가 베이스와 겹쳤고(width·height·padding·background·border·radius·
 * font-size·color·outline·transition), 스코프 접두(.bi-counter-wrap input[type=…])는
 * 그 사본이 베이스를 이기게 하려는 특이도 우회였다. 그대로 두면 §21-3 '입력은 하나다' 가 무너진다.
 *   width  → .bi-input--block    height → .bi-input--md
 *   padding·border·radius·font-size·color·outline·transition → 베이스
 * **여기 남는 것은 '강조' 뿐이다.** (POS 마크업은 이미 네 변형을 함께 붙이고 있다) */
/* * ⚠ **배경·테두리·포커스도 빼야 한다.** 규격은 입력을 하나로 정했고 배경색은 거기에 없다.
 *   강조가 배경을 바꾸면 그건 강조가 아니라 **두 번째 입력**이다(사용자 지적 2026-08-12).
 *   여기 남는 것은 글자 굵기 하나뿐이다. */
.bi-input--strong { font-weight: var(--fw-extrabold); }
/* 아이콘 여백 — 베이스(.bi-input--strong padding:0 12px)와 동급 특이도로 올려 이기게 함 (§5-1) */
.bi-counter-wrap input[type="text"].bi-input--icon { padding-left: var(--space-10); }
/* 디자이너 input — 클릭 시 popup_layer_emp 오픈 (readonly 이지만 클릭 가능 표시) */
.bi-input--clickable { cursor: pointer; }
.bi-input--clickable:hover { border-color: var(--cc-blue); background: var(--bg-card); }

.bi-counter-search-wrap { position: relative; flex: 1; min-width: 0; }
.bi-counter-search-wrap > i {
    position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
    color: var(--cc-gray-l); font-size: var(--fs-md); pointer-events: none; z-index: 1;
}
.bi-counter-search-wrap > i.fa-user-check { color: var(--cc-blue); }
.bi-counter-search-btn {
    flex-shrink: 0; width: 40px; height: 32px;   /* §12-4 사다리 base 32. 40 은 사다리에 없다(2026-08-14) */
    background: var(--border-light); border: 1px solid var(--cc-line); border-radius: var(--radius-xl);
    color: var(--gray-600); cursor: pointer; transition: background .15s;
    display: inline-flex; align-items: center; justify-content: center;
}
.bi-counter-search-btn:hover { background: var(--border-base); }.bi-counter-consult:focus { border-color: color-mix(in srgb, var(--color-warning-300) 90%, transparent); }

/* ============================================================
   빌링 테이블
   ============================================================ */
.bi-counter-bill-card { min-height: 360px; }

.bi-counter-bill-scroll { flex: 1; overflow-x: auto; }

/* §8-5 전역 input[type=text].writeinput height override */

.bi-counter-bill-foot {
    background: var(--gray-50); border-top: 1px solid var(--cc-line);
    padding: var(--space-3_5) var(--space-6); display: flex; justify-content: flex-end; align-items: center; gap: var(--space-8);
    flex-wrap: wrap;
}
.bi-counter-foot-label {
    display: block; font-size: var(--fs-xs); font-weight: var(--fw-extrabold); color: var(--cc-gray-l);
    text-transform: uppercase; letter-spacing: .03em; line-height: 1; margin-bottom: var(--space-1);
}
.bi-counter-foot-val { font-size: var(--fs-md); color: var(--txt-secondary); }
.bi-counter-foot-val--mono { color: var(--txt-primary); font-variant-numeric: tabular-nums; }

/* ============================================================
   우측 컬럼
   ============================================================ */
.bi-counter-datebar {
    display: flex; align-items: center; justify-content: space-between;
    background: var(--bg-card); padding: var(--space-3) var(--space-4); border-radius: var(--radius-2xl);
    border: 1px solid var(--cc-line); 
}
.bi-counter-datebar__l { position: relative; display: flex; align-items: center; gap: var(--space-2); cursor: pointer; }
.bi-counter-datebar__l i { color: var(--cc-blue); font-size: var(--fs-2lg); }
.bi-counter-datebar__caption { font-weight: var(--fw-extrabold); color: var(--txt-secondary); font-size: var(--fs-base); }
/* 네이티브 datepicker 트리거용 — 시각적으로 숨기되 showPicker() 호출 가능하도록 DOM 유지 */
.bi-counter-datebar__close {
    font-size: var(--fs-sm); background: var(--border-light); border: 1px solid var(--cc-line); color: var(--txt-secondary);
    font-weight: var(--fw-black); padding: var(--space-2) var(--space-2_5); border-radius: var(--radius-lg); cursor: pointer; transition: background .15s;
}
.bi-counter-datebar__close:hover { background: var(--border-base); }.bi-counter-memo-ta:focus { border-color: var(--cc-blue); }

/* ============================================================
   POS 정산 도크
   ============================================================ */
.bi-counter-dock { padding: var(--space-5); gap: var(--space-4); }

/* 선불권/포인트 사용 입력 */

.bi-counter-final {
    border-top: 1px dashed var(--cc-line-l); padding-top: var(--space-3); margin-top: var(--space-1);
    display: flex; justify-content: space-between; align-items: baseline;
}
.bi-counter-final-label { font-size: var(--fs-md); font-weight: var(--fw-black); color: var(--gray-950); text-transform: uppercase; }
.bi-counter-final-amt {
    display: block; font-size: var(--fs-3xl); font-weight: var(--fw-black); color: var(--cc-blue);
    font-variant-numeric: tabular-nums; letter-spacing: -.02em; line-height: 1;
}
.bi-counter-final-amt small { font-size: var(--fs-md); font-weight: var(--fw-bold); }

/* 결제 버튼 */
.bi-counter-pay-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); }
/* ⚠ 기본 배경이 없으면 변형(--npay·--done)을 안 붙인 버튼이 **브라우저 기본 회색**으로 나온다.
 *   레거시 전역 버튼 스킨이 가려주고 있었을 뿐이다(2026-08-12 그 스킨을 없애며 드러남).
 *   §12 기준: 색없음 = 흰 배경 + 테두리. */
/* 규격 §12-5 크기 — POS 결제수단 타일. 사다리(48·32·27·22) 밖이지만 **위반이 아니라 별도 규격**이다.
 * 아이콘 위·글자 아래로 쌓는 **손가락 타깃**이라 사다리의 «글자 한 줄» 전제가 성립하지 않는다.
 * 값을 안 적어두면 padding·아이콘 크기가 대신 정하고, 검사는 «사다리 밖» 으로만 읽는다 →
 * §12-5 는 색만 정하고 크기를 안 정해서 실제로 그렇게 됐다(2026-08-21). 높이를 규격으로 못 박는다. */
.bi-counter-pay-btn {
    height: 78px;
    padding: var(--space-4) var(--space-1); border: 1px solid var(--border-base); border-radius: var(--radius-xl); cursor: pointer;
    background: var(--bg-card); color: var(--txt-primary); font-size: var(--fs-md); font-weight: var(--fw-black);
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2);
}
.bi-counter-pay-btn i { font-size: var(--fs-xl); }
.bi-counter-pay-btn:active { transform: scale(.97); }
.bi-counter-pay-btn:disabled { opacity: .45; cursor: not-allowed; }
/* 2026-08-11 §12-5 규격 적용 — **색은 둘만**(N Pay 네이버 초록 · 결제완료 브랜드블루).
   구 구현: 현금=초록 · 카드=네이비 · N Pay=로즈. 수단마다 색이 달라
   "지금 눌러야 할 것"을 색으로 구분할 수 없었다 — styleguide2 §12-5 가 "교정 대상"으로
   지목해두고 미뤄져 있던 마지막 항목이다. 색은 강조의 도구라 아껴 쓴다. */
.bi-counter-pay-btn--cash,
.bi-counter-pay-btn--card {
    background: var(--bg-card); border: 1px solid var(--gray-300); color: var(--txt-secondary);
}/* N Pay — 네이버 브랜드 초록. 결제수단 중 유일하게 색을 갖는다(브랜드 식별)
   ⚠ 이 규칙이 사라져 있었다(2026-08-12 복구). 마크업에 변형이 안 붙어 "아무도 안 쓰는
     규격" 으로 보였고, 레거시 전역 버튼 스킨이 회색으로 가려 눈에 띄지 않았다. */
.bi-counter-pay-btn--npay { background: var(--color-npay); border-color: var(--color-npay); color: var(--bg-card); }
.bi-counter-pay-btn--npay:hover:not(:disabled) { background: color-mix(in srgb, var(--color-npay) 88%, var(--black)); }
/* 비활성(N Pay 미계약 등) — JS 토글 */
.bi-counter-pay-btn--inactive { opacity: .4; pointer-events: none; }

/* ============================================================
   모달 공통
   ============================================================ */
@keyframes bi-counter-zoom { from { transform: scale(.95); opacity: .5; } to { transform: scale(1); opacity: 1; } }

/* ----- 할인 모달 ----- */
#counter_disc_presets { display: flex; flex-direction: column; gap: var(--space-1_5); max-height: 170px; overflow-y: auto; padding-right: var(--space-1); }

/* ============================================================
   반응형 (1920 → 1440 → 1280 → 1024)
   ============================================================ */
@media (max-width: 1280px) {
    .bi-counter-grid { grid-template-columns: 1fr; }
}
@media (max-width: 1024px) {
    .bi-write-grid-2 { grid-template-columns: 1fr; }
    .bi-counter-bill-foot { gap: var(--space-5); }
}

/* ===================================================================
   § 2-1. 페이지 레이아웃
   =================================================================== */

/* 전표번호 배지 */
.bi-bs-keyindex-badge {
    font-size: var(--fs-base);
    color: var(--txt-muted);
    background: var(--border-light);
    border-radius: var(--radius-sm);
    padding: var(--space-1) var(--space-2_5);
    font-variant-numeric: tabular-nums;
}

/* ===================================================================
   § 2-2. 2컬럼 그리드
   =================================================================== */

/* 컬럼 안 카드: write.css margin-bottom:16px 대신 gap만 사용 */

@media (max-width: 1280px) {
}
@media (max-width: 1024px) {
}

/* ===================================================================
   § 2-3. 카드 헤더 내부 요소
   =================================================================== */

/* 포인트 배지 */
.bi-bs-point-badge {
    font-size: var(--fs-sm);
    color: var(--brand-blue);
    font-weight: var(--fw-semibold);
    white-space: nowrap;
}

/* 더보기 / 추가 링크 */
.bi-bs-link {
    font-size: var(--fs-base);
    color: var(--color-info-500);
    text-decoration: underline;
}

/* ===================================================================
   § 2-4. 고객 폼 레이아웃 오버라이드
   =================================================================== */

/* 성별 세그먼트 컨트롤 */
.bi-bs-sex-group {
    display: flex;
    background: var(--bg-input);
    padding: var(--space-1);
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-base);
    gap: var(--space-0_5);
}
.bi-bs-sex-r {
    display: none;
    position: absolute;
}
/* lib/css/style.css  input[type=radio]+label { background-image:...; width:18px } 초기화 */
.bi-bs-sex-group .bi-bs-sex-r + .bi-bs-sex-lbl {
    background-image: none;
    width: auto;
    height: auto;
    position: static;
    top: auto;
}
.bi-bs-sex-lbl {
    flex: 1;
    text-align: center;
    padding: var(--space-1_5) var(--space-2);
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
    border-radius: var(--radius-md);
    color: var(--txt-muted);
    cursor: pointer;
    white-space: nowrap;
    transition: background .15s, color .15s, box-shadow .15s;
    user-select: none;
}
.bi-bs-sex-lbl:hover {
    background: color-mix(in srgb, var(--border-base) 50%, transparent);
}
.bi-bs-sex-r:checked + .bi-bs-sex-lbl {
    background: var(--bg-card);
    color: var(--brand-blue);
    font-weight: var(--fw-bold);
}

/* ── 고객 검색 — icon inside input + 검색 버튼 ─────────────────── */

/* 메모 노란 배경 */

@media (max-width: 1024px) {
}

/* ===================================================================
   § 2-5. 상품 카드
   =================================================================== */

/* 시술 추가 버튼 */

.bi-bs-pro-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-base);
    text-align: left;
    table-layout: fixed;
}
/* thead */
.bi-bs-pro-th {
    background: var(--bg-input);
    color: var(--txt-muted);
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
    padding: var(--space-2_5) var(--space-3_5);
    border-bottom: 1px solid var(--border-base);
    white-space: nowrap;
}
.bi-bs-pro-th--no    { width: 44px;  text-align: center; }
.bi-bs-pro-th--proc  { width: 130px; }
.bi-bs-pro-th--pro   { /* auto — table-layout:fixed 에서 나머지 너비 차지 */ }
.bi-bs-pro-th--price { width: 90px;  text-align: right; }
.bi-bs-pro-th--qty   { width: 68px;  text-align: center; }
/* 구 .bi-bs-pro-th--disc — .bi-bs-pro-th--price 와 같아 합침(2026-08-12) */
.bi-bs-pro-th--total { width: 160px; text-align: right; font-weight: var(--fw-bold); color: var(--txt-secondary); }
.bi-bs-pro-th--del   { width: 32px;  padding-left: 0; padding-right: 0; }
/* tbody rows */
.bi-bs-pro-row {
    border-bottom: 1px solid var(--border-light);
    transition: background .15s;
}
.bi-bs-pro-row:hover { background: color-mix(in srgb, var(--color-info-50) 30%, transparent); }
/* td */
.bi-bs-pro-td {
    padding: var(--space-2_5) var(--space-3_5);
    vertical-align: middle;
}
.bi-bs-pro-td--no    { text-align: center; }
/* (구 «.bi-bs-pro-td--proc { display:flex }» — td 를 표에서 빼내 행을 깨뜨리던 규칙.
   2026-08-26 제거. 대신 아래쪽(§POS 전표)에서 table-cell 인 채로 안쪽만 세운다.) */
.bi-bs-pro-td--del   { text-align: center; padding-left: 0; padding-right: 0; }
/* row number */
.bi-bs-pro-rownum {
    color: var(--txt-disabled);
    font-size: var(--fs-xs);
    font-family: var(--font-mono);
}
/* inputs inside td */
.bi-bs-pro-input {
    width: 100%;
    background: transparent;
    border: none;
    border-bottom: 1px solid transparent;
    border-radius: 0;
    outline: none;
    padding: var(--space-1) var(--space-0_5);
    height: auto;
    font-size: var(--fs-base);
    color: var(--txt-primary);
    box-shadow: none;
    box-sizing: border-box;
    transition: border-color .15s;
}
.bi-bs-pro-input:focus {
    border-bottom-color: var(--brand-blue);
    background: transparent;
    box-shadow: none;
}
.bi-bs-pro-input[readonly] { color: var(--txt-secondary); }
.bi-bs-pro-input--r { text-align: right; font-family: var(--font-mono); }
.bi-bs-pro-input--c { text-align: center; }
/* 수량 입력 */
/* ⚠ 2026-09-28 사용자 지적 — 「**시술 및 상품 내역에 수량 입력칸은 왜 안늘려줘**」.
     맞다. ‒/+ 단추를 걷으면서 접수전표·팝업 칸만 넓히고 이 표의 칸을 빠뜨렸다.
     단추가 있을 때는 «보여 주는» 자리라 48 이면 됐지만 이제는 «치는» 자리다.
     단추 둘(27+27)이 빠진 만큼 상자에 여유가 있으니 그 폭을 칸에 준다. */
.bi-bs-pro-input--qty {
    display: inline-block;
    width: 84px;
    background: var(--bg-input);
    border: 1px solid var(--border-base);
    border-bottom: 1px solid var(--border-base);
    border-radius: var(--radius-md);
    padding: var(--space-1) var(--space-1_5);
    height: 28px;
    font-size: var(--fs-sm);
    box-sizing: border-box;
}
.bi-bs-pro-input--qty:focus {
    border-color: var(--brand-blue, var(--brand-blue));
    box-shadow: var(--ring-focus);
}
.bi-bs-pro-input--pro { font-weight: var(--fw-medium); }
.bi-bs-pro-input--total { font-weight: 700; color: var(--txt-primary); font-family: var(--font-mono); }
/* search btn inside proc/disc td */
/* delete btn */
.bi-bs-pro-del-btn {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--gray-300);
    padding: var(--space-1);
    border-radius: var(--radius-sm);
    transition: color .15s;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.bi-bs-pro-del-btn:hover { color: var(--color-danger); }

/* ===================================================================
   § 2-6. 정보 탭 (CSS-only tab system)
   =================================================================== */

/* 탭 라디오 인풋 숨김 */
.bi-bs-tab-r {
    display: none;
    position: absolute;
    pointer-events: none;
}

/* 정보 탭 카드 */
.bi-bs-info-card {
    height: 340px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* 탭 헤더 바 */
.bi-bs-tab-hdr {
    display: flex;
    background: var(--bg-card);
    border-bottom: 1px solid var(--border-light);
    flex-shrink: 0;
}

/* 탭 레이블 */
.bi-bs-tab-lbl {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-1_5);
    padding: var(--space-3) var(--space-2);
    font-size: var(--fs-base);
    font-weight: var(--fw-medium);
    color: var(--txt-disabled);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: calc(var(--space-0_5) * -1);
    white-space: nowrap;
    transition: color .15s, border-color .15s, background .15s;
}
.bi-bs-tab-lbl:hover { color: var(--txt-secondary); }

/* 탭 패널 컨테이너 */
.bi-bs-tab-panels {
    flex: 1;
    overflow-y: auto;
    background: color-mix(in srgb, var(--bg-input) 30%, transparent);
    padding: var(--space-5);
    min-height: 0;
}/* 개별 패널 — 기본 숨김 */
.bi-bs-tab-pnl { display: none; }/* 메모: flex column — textarea h-full */
#itab_memo:checked ~ .bi-bs-tab-panels #pnl_memo {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}

/* 패널 내부 — 스크롤 리스트 — flex:1 으로 더보기를 하단으로 밀어냄 */
.bi-bs-info-list {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    list-style: none;
}

/* 더보기 — 하단 고정 (flex-shrink:0 + 패널 flex column 덕분에 항상 최하단) */
/* 탭을 바꿔도 이 줄의 높이는 같아야 한다 — «최근 내역» 은 링크만, «보유 정액권» 은 버튼+링크라
 * 내용이 높이를 정하게 두면 탭 전환 때 아래가 들썩인다(2026-08-21 사용자 지적).
 * 가장 큰 내용(버튼 27=--sm)에 맞춰 **줄 높이를 규격으로 고정**한다. */
.bi-bs-pnl-more {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    min-height: 27px;
    padding: var(--space-2) 0 0;
    border-top: 1px solid var(--border-light);
    margin-top: var(--space-1);
}
.bi-bs-pnl-more .bi-bs-link {
    font-size: var(--fs-sm);
    color: var(--color-info-500);
    text-decoration: underline;
    cursor: pointer;
}

/* ── 공통 빈 상태 ── */
.bi-bs-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-6) var(--space-3);
    list-style: none;
    color: var(--txt-disabled);
    text-align: center;
}
.bi-bs-empty-state i { font-size: var(--icon-md); opacity: 0.2; color: var(--txt-disabled); }
.bi-bs-empty-state p { font-size: var(--fs-base); margin: 0; }

/* ===================================================================
   § 2-9. 로딩 레이어
   =================================================================== */

.bi-bs-panel-layer {
    display: none;
    position: fixed;
    inset: 0;
    background: color-mix(in srgb, var(--black) 30%, transparent);
    z-index: 9000;
    justify-content: center;
    align-items: center;
}
.bi-bs-panel-loader {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

/* ===================================================================
   § 3. 레거시 클래스 보존 (JS 호환 — 수정 금지)
   =================================================================== */

.ad_style {
    padding: var(--space-5) var(--space-5);
    float: left;
    width: 100%;
    font-size: var(--fs-base);
    box-sizing: border-box;
}

/* 2026-08-07 공통 일원화: .ul-style(margin 5px↔10px)·.li-style(width 100%↔98%) 사본 제거.
   차이가 무의미한데 전역 클래스를 모듈군마다 다르게 덮고 있었다(같은 클래스가 products 에선 다른 값).
   → 공통 style.css 단일 정의 사용. span-r 90px 는 #package_olist 스코프라 유지. */

#package_olist .li-style-span-r {
    float: right;
    width: 90px;
    text-align: right;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* 상품 목록 컬럼 너비 */
.product_list2 { width: 300px; text-align: left; }
.product_list3 { width: 80px; text-align: right; }
.product_list4 { width: 150px; text-align: right; }

.bi-counter-wrap .main_more:not(.bi-btn) { width: 30%; }

@media (max-width: 981px) {
    .product_list2 { width: 250px; }
    .product_list3 { width: 73px; }
}

/* ===== buysell/style.css 이관(2026-08, §40-6-2: 모듈 @import 제거·POS 공통 일원화) =====
 *  - 아래는 매출등록 전용 보강(.bi-bs-counter 스코프): 동적 테이블/리스트를 counter 카드 안에 맞춤
 *
 * ⚠ 2026-08-07 결함 수정: 이 자리에 ① 여는 `/*` 없이 `*  - …` + ` *​/` 로 끝나는 **깨진 주석**과
 *   ② `@import url('/lib/css/buy_write.css')` — buy_write.css 가 **자기 자신을 import** 하는 줄이
 *   있었다(구 buysell/style.css 헤더를 이관하며 통째로 딸려 옴, 커밋 914ac03).
 *   깨진 주석은 파서를 어긋나게 하고, 자기 @import 는 파일 삭제 후 404 가 된다. 둘 다 제거.
 * ===================================================================================== */

/* ── 래퍼: write 페이지 높이 정렬(헤더 변수) ── */
.bi-counter-wrap.bi-bs-counter { height: calc(100vh - var(--header-height, 64px)); }/* 보조/액션 버튼 톤 통일 */
.bi-bs-counter .bi-counter-pay .bi-bs-dock-btn { border-radius: var(--radius-xl); font-weight: var(--fw-extrabold); height: 40px; }
.bi-bs-counter .bi-counter-pay .bi-bs-dock-actions { gap: var(--space-2_5); }
/* 보조행: flex 균등분배 → 포인트 숨김 시 남은 버튼이 자리 채움(3개=33%, 2개=50%) */
.bi-bs-counter .bi-counter-pay > .bi-bs-dock-btns { display: flex; gap: var(--space-2); }
.bi-bs-counter .bi-counter-pay > .bi-bs-dock-btns > .bi-bs-dock-btn { flex: 1 1 0; min-width: 0; }

/* ── 신규 고객 등록 모달 (designer_chart 신규회원등록 패턴) ── */
/* 신규회원 모달 = 공용 .bi-modal-ov(백드롭)+.bi-modal(패널) 사용(2026-07-31). 토글은 JS .css('display','flex')/.hide() 그대로(인라인 display가 공용 위 적용). 아래는 bs 전용 크기/여백 modifier */
/* 구 .bi-bs-reg-row/--2/--3/-field — §21 .bi-write-row/.bi-write-field(--third)/.bi-write-label 로 흡수(2026-08-11).
 * 가이드가 이미 같은 폼(고객명·연락처·성별·생년월일)을 그 규격으로 전시하고 있었다.
 * 새 격자 규격을 만들 뻔했으나 대응물이 있으면 만들지 않는다. */
/* 폼 필드 = 공통 .bi-form .bi-input (buy_write.php form 에 .bi-form 추가). 개별 재정의 제거 (2026-07-31) */
/* 취소/확인 = 공통 .bi-btn--ghost/--primary. 델타: 2:3 비율·큰 라운드·굵기·padding·그림자 (2026-07-31) */

/* ── 시술/상품 내역 테이블(JS bi-bs-pro-*) — counter bill 디자인 정합 ── */
.bi-bs-counter .bi-bs-pro-table { width: 100%; border-collapse: collapse; font-size: var(--fs-md); color: var(--gray-800); }

/* 헤더: counter thead (컬럼별 정렬은 buysell.css 유지 → 전역 center 강제 안 함) */
.bi-bs-counter .bi-bs-pro-th {
    background: var(--gray-50); color: var(--txt-muted); font-weight: var(--fw-extrabold);
    font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .04em;
    padding: var(--space-3_5) var(--space-2_5); border-bottom: 1px solid var(--border-base); white-space: nowrap;
}
.bi-bs-counter .bi-bs-pro-th--total { color: var(--txt-secondary); font-weight: var(--fw-black); }

/* 행 — counter row (여백 + hover) */
.bi-bs-counter .bi-bs-pro-table tbody tr.bi-bs-pro-row { border-bottom: 1px solid var(--border-light); transition: background .12s; }
.bi-bs-counter .bi-bs-pro-table tbody tr.bi-bs-pro-row:hover { background: color-mix(in srgb, var(--color-info-50) 30%, transparent); }
.bi-bs-counter .bi-bs-pro-td { padding: var(--space-2_5) var(--space-2_5); vertical-align: middle; }

/* No. — counter td--no (회색 tabular) */
.bi-bs-counter .bi-bs-pro-rownum {
    display: inline-block; text-align: center; color: var(--txt-disabled);
    font-weight: var(--fw-extrabold); font-size: var(--fs-base); font-variant-numeric: tabular-nums;
}.bi-bs-counter .bi-bs-pro-input--r { text-align: right; font-variant-numeric: tabular-nums; font-family: inherit; }/* 읽기전용 계산값(단가/할인/매출액) → counter 처럼 텍스트화(테두리 제거) */
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-pro-input[readonly] {
    background: transparent; border-color: transparent; box-shadow: none;
    padding-left: var(--space-1); padding-right: var(--space-1); cursor: default;
}.bi-bs-counter .bi-bs-pro-input--pro:hover { color: var(--brand-blue); }

/* 분류 input(2차 분류명) — 테두리 없는 텍스트형, 클릭 */
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-pro-input[name='input_proc[]'] {
    background: transparent; border-color: transparent; box-shadow: none;
    padding-left: var(--space-1); cursor: pointer; color: var(--gray-600); font-weight: 600;
}/* 합계: 매출인정(input_tdesiner) + 구분자 숨김 → 매출액(--total)만 표시 (값은 DOM 유지·제출됨) */
.bi-bs-counter input[name='input_tdesiner[]'] { display: none; }/* 삭제 버튼 — counter delbtn */
.bi-bs-counter .bi-bs-pro-del-btn {
    width: 30px; height: 30px; border: none; background: none; color: var(--txt-disabled);
    border-radius: var(--radius-lg); cursor: pointer; transition: all .12s;
    display: inline-flex; align-items: center; justify-content: center;
}
.bi-bs-counter .bi-bs-pro-del-btn:hover { color: var(--color-danger); background: var(--color-danger-50); }/* ── 컬럼 폭 보정: 분류(배지+명) / 수량(스테퍼) / 할인(버튼) ── */
.bi-bs-counter .bi-bs-pro-th--proc { width: 150px; }
.bi-bs-counter .bi-bs-pro-th--qty  { width: 112px; }

/* ── 분류 td: 1차 배지 + 2차 분류명 배지 가로 나란히 ──
   2026-08-26 — td 가 다시 table-cell 이라 flex 속성(flex-direction·gap·flex:1)은 안 먹는다.
   간격은 인접 형제 마진으로, 인풋은 폭 100% 로. */
.bi-bs-counter .bi-bs-pro-td--proc { white-space: nowrap; }
.bi-bs-counter .bi-bs-pro-td--proc > * + * { margin-left: var(--space-1_5); }
.bi-bs-counter .bi-bs-pro-td--proc .bi-bs-pro-input { width: 100%; min-width: 0; }

/* ── 분류 1차 상품구분 배지 (counter catbadge) — 코드별 결정적 색상 ── */
.bi-bs-counter .bi-bs-pro-cat-badge {
    display: none; align-self: center; flex-shrink: 0; max-width: 70px;
    padding: var(--space-0_5) var(--space-2_5); border-radius: var(--radius-md); font-size: var(--fs-xs); font-weight: var(--fw-black);
    border: 1px solid; white-space: nowrap; line-height: 1.6; cursor: pointer;
    overflow: hidden; text-overflow: ellipsis; margin: var(--space-2) 0px;
}
.bi-bs-counter .bi-bs-pro-cat-badge.is-on { display: inline-block; }

/* ── 분류 2차 분류명 배지 (1차와 유사 디자인, 중립 회색) ── */
.bi-bs-counter .bi-bs-pro-cat-badge2 {
    display: none; align-self: center; flex-shrink: 1; min-width: 0; max-width: 100%;
    padding: var(--space-0_5) var(--space-2_5); border-radius: var(--radius-md); font-size: var(--fs-xs); font-weight: var(--fw-extrabold);
    border: 1px solid var(--border-base); background: var(--border-light); color: var(--gray-600);
    white-space: nowrap; line-height: 1.6; cursor: pointer;
    overflow: hidden; text-overflow: ellipsis;
}
.bi-bs-counter .bi-bs-pro-cat-badge2.is-on { display: inline-block; }
.bi-bs-counter .bi-bs-pro-cat-badge.is-cat-blue   { background: var(--color-info-50); color: var(--brand-blue); border-color: var(--color-info-100); }
.bi-bs-counter .bi-bs-pro-cat-badge.is-cat-rose   { background: var(--color-rose-50); color: var(--color-rose-600); border-color: var(--color-rose-200); }
.bi-bs-counter .bi-bs-pro-cat-badge.is-cat-green  { background: var(--color-success-50); color: var(--color-success); border-color: var(--color-success-100); }
.bi-bs-counter .bi-bs-pro-cat-badge.is-cat-amber  { background: var(--color-warning-50); color: var(--color-warning-600); border-color: var(--color-warning-200); }
.bi-bs-counter .bi-bs-pro-cat-badge.is-cat-violet { background: var(--color-purple-50); color: var(--color-purple-600); border-color: var(--color-purple-200); }

/* ── 시술/상품 내역 푸터 — 글자 크게 (디자인 정합, counter 모듈 미영향) ── */
.bi-bs-counter .bi-counter-bill-foot { padding: var(--space-5) var(--space-6); gap: var(--space-11); }
.bi-bs-counter .bi-counter-foot-label { font-size: var(--fs-base); margin-bottom: var(--space-2); letter-spacing: 0; }
.bi-bs-counter .bi-counter-foot-val { font-size: var(--fs-lg); font-weight: var(--fw-extrabold); }
.bi-bs-counter #bs_foot_total { font-size: var(--fs-xl); font-weight: var(--fw-black); color: var(--brand-blue); }

/* ── 정산 dock 맨 위 '총 합계' 행 강조 ── */
.bi-bs-counter .bi-bs-dock-row--grand > span:first-child { color: var(--gray-800); font-weight: 800; font-size: var(--fs-md); }
.bi-bs-counter .bi-bs-dock-row--grand > span:last-child { color: var(--txt-primary); font-weight: 900; font-size: var(--fs-lg); font-variant-numeric: tabular-nums; }

/* ── 상품 없을 때 빈 상태 (counter empty-row) ── */
.bi-bs-counter .bi-bs-pro-empty { display: none; padding: 52px var(--space-4); text-align: center; color: var(--txt-disabled); }
.bi-bs-counter .bi-bs-pro-empty.is-on { display: block; }
.bi-bs-counter .bi-bs-pro-empty i { font-size: var(--fs-3xl); display: block; margin-bottom: var(--space-3); opacity: .45; }
.bi-bs-counter .bi-bs-pro-empty p { margin: 0; font-size: var(--fs-base); line-height: 1.7; font-weight: var(--fw-medium); }
.bi-bs-counter .bi-bs-pro-empty b { color: var(--brand-blue); font-weight: var(--fw-extrabold); }

/* ── 수량 +/- 스테퍼 (counter qty) ── */
.bi-bs-counter .bi-bs-pro-qty { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1_5); }
.bi-bs-counter .bi-bs-pro-qty-btn {
    width: 24px; height: 24px; flex-shrink: 0; padding: 0; border: none; border-radius: var(--radius-lg);
    background: var(--border-light); color: var(--gray-600); cursor: pointer; font-size: var(--fs-2xs);
    display: inline-flex; align-items: center; justify-content: center;
}
.bi-bs-counter .bi-bs-pro-qty-btn:hover { background: var(--border-base); color: var(--brand-blue); }

/* ── 할인 버튼 (counter discbtn: 없으면 '할인추가' 회색 / 있으면 '금액 / 율' 빨강) ── */
.bi-bs-counter .bi-bs-pro-disc-btn {
    min-width: 88px; padding: var(--space-2_5) var(--space-3_5); border-radius: var(--radius-lg); border: 1px solid var(--border-base);
    background: var(--bg-input); color: var(--txt-muted); font-size: var(--fs-base); font-weight: var(--fw-extrabold); cursor: pointer;
    white-space: nowrap; transition: all .12s; 
    font-variant-numeric: tabular-nums;
}
.bi-bs-counter .bi-bs-pro-disc-btn:hover { background: var(--border-light); color: var(--txt-secondary); }
.bi-bs-counter .bi-bs-pro-disc-btn.is-active { background: var(--color-danger-50); color: var(--color-danger-600); border-color: var(--color-danger-200); }
.bi-bs-counter .bi-bs-pro-disc-btn.is-active:hover { background: var(--color-danger-100); }

/* ── 최근내역 / 정액권 리스트(JS) — counter 톤 ── */
.bi-bs-counter .bi-bs-info-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.bi-bs-counter .bi-bs-empty-state {
    list-style: none; text-align: center; color: var(--txt-disabled); font-size: var(--fs-base); padding: var(--space-8) var(--space-2);
}
.bi-bs-counter .bi-bs-empty-state i { font-size: var(--icon-md); display: block; margin-bottom: var(--space-1_5); opacity: .6; }

/* ── 성별 라디오(전역 스프라이트 무력화 → 세그 느낌) ── */
.bi-counter-wrap.bi-bs-counter input[type="radio"].bi-bs-sex-r { position: absolute; opacity: 0; pointer-events: none; }
.bi-bs-counter .bi-bs-sex-group { display: inline-flex; gap: 0; background: var(--border-light); border-radius: var(--radius-xl); padding: var(--space-1); }
.bi-counter-wrap.bi-bs-counter input[type="radio"].bi-bs-sex-r + label.bi-bs-sex-lbl {
    background-image: none; width: auto; height: 33px; position: static; top: auto;
    display: inline-flex; align-items: center; justify-content: center;
    padding: var(--space-1_5) var(--space-4); border-radius: var(--radius-lg); font-size: var(--fs-base); font-weight: var(--fw-extrabold); color: var(--txt-muted); cursor: pointer; border: none;
}
.bi-bs-counter input[type="radio"].bi-bs-sex-r:checked + label.bi-bs-sex-lbl {
    background: var(--bg-card); color: var(--brand-blue); 
}

/* ── 정산 도크 보강: 매출/결제 요약 라인 ── */
.bi-bs-counter .bi-bs-dock-sum { display: flex; flex-direction: column; gap: var(--space-2); font-size: var(--fs-base); }
.bi-bs-counter .bi-bs-dock-row { display: flex; justify-content: space-between; align-items: center; }
.bi-bs-counter .bi-bs-dock-row > span:first-child { color: var(--txt-muted); font-weight: var(--fw-semibold); }
.bi-bs-counter .bi-bs-dock-row > span:last-child { color: var(--gray-800); font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; }
.bi-bs-counter .bi-bs-dock-row--remain > span { color: var(--color-rose-600); font-weight: 900; }
.bi-bs-counter .bi-bs-dock-divider { height: 1px; background: var(--border-light); margin: var(--space-0_5) 0; }

/* 결제 버튼 그리드(보조: 선불권/포인트/접수/취소 등) */
.bi-bs-counter .bi-bs-dock-btns { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2); }
/* 규격 §12-5 크기 — 보조 결제(선불권·포인트·접수). 타일 78 과 최종액션 48 사이의 **한 칸**. */
.bi-bs-counter .bi-bs-dock-btn {
    height: 40px;
    padding: 0 var(--space-1_5); border-radius: var(--radius-xl); border: 1px solid var(--border-base); background: var(--bg-card); color: var(--txt-secondary);
    font-size: var(--fs-base); font-weight: var(--fw-extrabold); cursor: pointer; transition: all .15s;
    display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-0_5); line-height: 1.25;
}
.bi-bs-counter .bi-bs-dock-btn:hover { background: var(--bg-input); border-color: var(--gray-300); }

/* 액션 (닫기 / 결제완료) */
/* 두 액션은 §12-5-1 에서 **같은 등급(48)** 이다. 폭도 같아야 한다 —
 * 1fr 1.4fr 이라 결제완료만 1.4배 넓었고, 글자도 16 vs 브라우저 기본(13.3)이라 «왜 큰지 모르겠다» 는
 * 지적이 나왔다(2026-08-21). 크기는 §12-4 --lg 와 같은 글자(--fs-md 14)로 통일한다. */
.bi-bs-counter .bi-bs-dock-actions { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2_5); }
/* 규격 §12-5 크기 — 최종 액션 두 개는 사다리 --lg(48)에 맞춘다.
 * 실측 47 이었다(padding 14 로 «거의» 48). 1px 차이는 안 보이지만 **사다리에 있는 값과 없는 값은 다르다** —
 * 없는 값이면 검사가 «사다리 밖» 으로 잡고, 다음 사람이 또 판정해야 한다(2026-08-21). */
.bi-bs-counter .bi-bs-dock-close {
    height: 48px; padding: 0 var(--space-3_5); border-radius: var(--radius-xl); border: 1px solid var(--border-base); background: var(--bg-card); color: var(--txt-secondary);
    font-size: var(--fs-md); font-weight: var(--fw-extrabold); cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
}
.bi-bs-counter .bi-bs-dock-close:hover { background: var(--bg-input); }
/* 결제완료 = 화면의 **최종 주 액션**. 규격 문서 §12-5: "색은 둘만 — N Pay 와 결제완료(브랜드블루)".
 * 2026-08-14: 실물이 검정(--txt-primary)이라 문구와 달랐다. **문서가 기준**이므로 실물을 문서에 맞춘다. */
.bi-bs-counter .bi-bs-dock-pay {
    height: 48px; padding: 0 var(--space-3_5); border-radius: var(--radius-xl); border: none; background: var(--brand-blue); color: var(--bg-card);
    font-size: var(--fs-md); font-weight: var(--fw-black); cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
}
.bi-bs-counter .bi-bs-dock-pay:hover { background: var(--brand-blue-hover); }/* keyindex 배지 */
.bi-bs-counter .bi-bs-keyindex-badge:empty { display: none; }
.bi-bs-counter .bi-bs-keyindex-badge {
    font-size: var(--fs-xs); font-weight: var(--fw-extrabold); color: var(--brand-blue); background: var(--color-info-50);
    border: 1px solid var(--color-info-100); border-radius: var(--radius-lg); padding: var(--space-1) var(--space-2);
}

/* 로딩 레이어 */
.bi-bs-counter .bi-bs-panel-layer {
    position: fixed; inset: 0; background: color-mix(in srgb, var(--white) 60%, transparent); z-index: 1500;
    display: none; align-items: center; justify-content: center;
}

/* ============================================================
 * booking_buysell · report_buy_appear 공통 (2026-07-01)
 * 두 모듈이 이 파일을 @import 하므로 여기서 단일 정의 → 각 모듈 중복 제거.
 * 근거: docs/modules/66_part_common_css_공통화_디자인리뉴얼.md
 * ============================================================ */

/* write: 안내문 바 (counter 톤) — .ad_style(float:left) 무력화: 상단 전체폭 */
.bi-bs-counter .bi-bk-info-bar {
    float: none; clear: both; width: 100%; box-sizing: border-box;
    margin: 0 0 var(--space-3); padding: var(--space-3) var(--space-4); border-radius: var(--radius-xl);
    background: var(--color-warning-50); border: 1px solid var(--color-warning-200); color: var(--color-warning-800);
    font-size: var(--fs-base); font-weight: var(--fw-semibold); display: flex; align-items: center; gap: var(--space-2);
}
.bi-bs-counter .bi-bk-info-bar i { color: var(--color-warning-600); }

/* write: 주 동작 2분할 결제버튼 그리드 (매출/선결제, 현금/카드 등) */
.bi-bs-counter .bi-counter-pay-grid--bk2 { grid-template-columns: 1fr 1fr; }

/*member popup*/
.pop_m_p_h{
    width: 100%;
    float: left;
    border-bottom: 2px solid var(--gray-100);
}
.pop_m_p_b{
    width: 100%;
    float: left;
}
.pop_m_h_sub{
    float: left;
    padding: 0px 0px 0px var(--space-4);
}
.pop_m_b{
    width: 100%;
    float: left;
    font-size: var(--fs-base);
}
.pop_m_b_ul{
    list-style: none;
    padding: 0px;
    margin: 0px;
}
.pop_m_b_li_div{
    float: left;
    padding: 0px 0px 0px var(--space-2);
    min-height: 1px;
}

/* 검색 팝업 헤더 부제목 — 13px 통일 (products 의 11px drift 정정) */
.main_title_sub{
    font-size: var(--fs-base);
    color: var(--gray-300);
    padding-left: var(--space-2_5);
    letter-spacing: -1px;
}

/* 검색 돋보기 버튼 (input 옆 절대위치) */
.sch_but_pop{
    text-decoration: none;
    width: 20px;
    position: absolute;
    height: 30px;
}

/* 팝업 본문 — 상품찾기/담당자/거래처 등 좌측 박스 */
.pop_body{
    padding: 0px var(--space-2_5);
    width: 250px;
    float: left;
    margin: var(--space-2_5) 0px;
}

/* 팝업 본문 분할선 */
.pop_border_l{
    border-left: 1px solid var(--gray-100);
}

/* ============================================================
   매출상품 선택 팝업 (popup_layer_product.php) — counter 카탈로그 모달(2단) 스코프
   - 레거시 .pop_body float 3열 → 상단 필터존(구분 세그먼트 + 분류 칩 + 검색) / 하단 상품 리스트
   - JS emit/참조 id/class(pop_*_ul, pop_m_b_li, pop_m_b_li_div, *_select_val,
     search_input_*, sch_but_*, ck_fill/ck_plus, product_save_but*) 보존, 룩만 재정의
   - 선택 하이라이트: 인라인 background → .is-sel 클래스 (JS/PHP 동기화)
   - 2026-06-22 신규 / 2026-06-22 2단(카탈로그) 재구성
   ============================================================ */
.bi-pop-catalog{
    box-sizing: border-box;
    display: flex; flex-direction: column;
    height: 100vh; padding: var(--space-5);
    font-family: var(--font-sans);
    background: var(--bg-page); color: var(--gray-800);
}
.bi-pop-catalog *{ box-sizing: border-box; }
.bi-pop-catalog ul{ list-style: none; margin: 0; padding: 0; }

/* 푸터 */
/* 예약 상품팝업 푸터 안내(체크박스 대신 안내문) */
/* 전역 input[type=checkbox]{visibility:hidden;display:none} 무력화 (CLAUDE.md §5-1) */
/* 공용 팝업 footer(취소+주버튼) — styleguide §13 톤: 우측정렬 + 상단 구분선 + 배경. 여기 한 곳에서 관리. */
/* 스타일보드 §07 해부도 — 「선은 리스트 상단(--border-base)과 **푸터 상단(--border-light)** 두 곳에만」.
 * 푸터 선은 헤더보다 연하다(구획을 나누되 눈길을 끌지 않는다). 배경도 흰색으로 — 회색 띠를 두지 않는다(2026-08-21 A단계). */
.bi-pop-foot-btns{ display: flex; gap: var(--space-2); flex-shrink: 0; justify-content: flex-end; padding: var(--pop-foot-pad-t) var(--pop-head-pad-x) var(--pop-foot-pad-b); border-top: 1px solid var(--pop-line); background: var(--bg-card); gap: var(--pop-foot-gap); }
/* footer 를 팝업 가장자리까지(bg·줄 풀블리드): body 하단 padding 제거(footer 가 바닥) + 좌우 padding 은 음수 margin 으로 상쇄. 팝업별로 다른 건 좌우 값뿐.
 — 뒤에 선언되는 body padding 단축속성(.bi-pop-reg{padding:22px} 등)이 padding-bottom 을 되돌리는 것 방지. */
/* 푸터가 바닥에 붙는 팝업은 body 아래 여백을 두지 않는다.
   ⚠ 채움형(--fill)은 «옛 fixed 푸터 자리»로 비워 둔 72px 때문에 남는 공간이 0 이 되어
     목록이 자라지 못하고 마지막 줄이 잘렸다(discount_list, 2026-08-25). 같은 이유·같은 선언이라 함께 묶는다. */
.bi-pop-reg{ padding-bottom: 0; }   /* 아래 간격은 푸터가 갖는다(2026-08-27) */
/* 버튼바는 좌우 여백을 뚫고 팝업 전폭을 쓴다(바닥에 붙는 띠).
 * ⚠ 음수 여백만 주면 **폭이 부모보다 커져** 폼이 가로로 넘친다(448 > 426, 2026-08-13 실측).
 *   넓히는 만큼 폭도 함께 정해 준다 — «뚫고 나가되 넘치지는 않게». */
.bi-pop-reg .bi-pop-foot-btns{
    margin: 0 calc(-1 * var(--pop-pad-x)) 0;
    width: calc(100% + var(--pop-pad-x) * 2);
    box-sizing: border-box;
}

/* ============================================================
   결제 팝업 공통 스킨 (.bi-pop-pay) — 현금/카드/선불권/포인트/N페이
   레거시 마크업(.bt_div/.but_blue/.btn_size/.writeinput/.pop_desc)을
   리뉴얼 토큰으로 재스타일 (id/구조/핸들러 무변경, 래퍼 div 만 추가)
   - 2026-06-22 추가
   ============================================================ */
/* ⚠ 2026-08-28 — 여기 값을 규격으로 바꿨다가 되돌렸다.
   공통 규칙을 고치면 그 규칙을 쓰는 «모든 팝업» 이 함께 움직인다(상품추가 팝업이 깨졌다).
   규격값은 아래 `.bi-pop-board` 로 **덧붙여** 준다 — 프로젝트 규칙 §4(기존 클래스 수정 금지). */
.bi-pop-pay{
    box-sizing: border-box; min-height: auto; padding: var(--space-5) var(--space-6) var(--space-6);
    font-family: var(--font-sans);
    background: var(--bg-card); color: var(--gray-800);
    display: flow-root;   /* 레거시 float 본문을 BFC 로 포함 → auto-height 가 콘텐츠 높이를 정확히 측정(스크롤 방지) */
}
/* 채움형 — 옛 규격은 푸터를 바닥에 «고정» 하고 그 높이(72px)만큼 아래를 비워 뒀다.
   푸터가 흐름 안으로 들어온 지금은 그 자리가 두 번 잡혀 «남는 공간 0» 이 되고,
   목록이 자라지 못해 마지막 줄이 잘렸다(discount_list 실측 2026-08-25).
   ⚠ 반드시 .bi-pop-pay 선언 «뒤» 에 있어야 한다 — 같은 특이도는 순서로 갈린다. */
.bi-pop-pay--fill,
.bi-pop-pay--list.bi-pop-pay--fill{ padding-top: 0; padding-bottom: 0; }   /* 보드: 헤더 바로 아래가 검색칸(간격 0) */   /* --list 가 비워 둔 72px(옛 fixed 푸터 자리)를 되돌린다 */
.bi-pop-pay *{ box-sizing: border-box; }
/* 레거시 팝업 float 본문 포함(clearfix) — popup_layer.js auto-height 가 콘텐츠 높이를 정확히 측정해
   팝업이 콘텐츠에 맞춰 리사이즈됨(불필요한 스크롤 방지). 버튼 영역은 float 본문 아래로 정렬. */
.bi-pop-pay::after{ content: ''; display: table; clear: both; }
.bi-pop-pay .bt_div{ clear: both; }

/* 안내문 — 회색 작은 텍스트(박스 아님) */
.bi-pop-pay .pop_desc{
    background: transparent; border: none; border-radius: 0;
    padding: 0 0 var(--space-1); color: var(--txt-disabled); float: none; width: auto;
    font-size: var(--fs-sm); line-height: 1.6; margin-bottom: var(--space-5);
}

/* 입력/셀렉트 — 모서리·테두리만 토큰화(높이는 인라인 유지해 레이아웃 보존) */
.bi-pop-pay input[type="text"], .bi-pop-pay select, .bi-pop-pay input[type="number"] {
    border: 1px solid var(--gray-300); border-radius: var(--radius-lg);
    background: var(--bg-card); color: var(--gray-800); box-shadow: none; outline: none;
}
.bi-pop-pay input[type="text"]:focus, .bi-pop-pay select:focus {
    border-color: var(--brand-blue); box-shadow: var(--ring-focus);
}

/* 금액 강조 입력(인라인 font-size 큰 것) */
.bi-pop-pay input#pay_amount, .bi-pop-pay input[id*="amount"]{
    font-weight: 700; color: var(--txt-primary); background: var(--bg-card);
}

/* ── 검색 리스트형 팝업(고객/디자이너 검색) — 공통 스킨 + 하단 고정 닫기바 ── */

.bi-pop-pay--list{ padding-bottom: var(--space-18); } /* 하단 고정 닫기바 공간 확보 */
.bi-pop-pay--list .pop_m_b{ height: auto; max-height: calc(100vh - 210px); overflow-y: auto; }
.bi-pop-pay--list [style*="position: fixed"]{
    left: 0; right: 0; bottom: 0; top: auto;
    width: 100%; padding: var(--space-3_5) var(--space-6); margin: 0;
    background: var(--bg-card); border-top: 1px solid var(--gray-100); box-sizing: border-box;
}
.bi-pop-pay--list [style*="position: fixed"] .bt_div{ width: auto; padding: 0; margin: 0; border: none; justify-content: flex-end; }
/* 검색 입력 행 — 디자인 정합(큰 검색바) */
.bi-pop-pay--list .body-main-sch{ display: flex; align-items: center; gap: var(--space-3); padding: var(--space-1) 0 var(--space-4); }
.bi-pop-pay--list .body-main-sch > div{ float: none; padding: 0; }
.bi-pop-pay--list .body-main-sch > div:first-child{ position: relative; }
.bi-pop-pay--list .body-main-sch .fa-search{ position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--txt-disabled); font-size: var(--fs-md); pointer-events: none; z-index: 1; }
.bi-pop-pay--list .sch_but_pop{ position: absolute; left: 8px; top: 0; width: 34px; height: 46px; z-index: 2; }
.bi-pop-pay--list .main_title_sub{ color: var(--txt-disabled); font-size: var(--fs-base); padding-left: 0; }
/* 안내문구 줄바꿈은 어절(공백) 단위로 — 옆 배치 유지, 2줄로 감싸지되 단어 중간에서 끊기던 것("필수입력"→"필/수입력") 방지 */
.bi-pop-pay--list .main_title_sub{ word-break: keep-all; }

/* inout_item 검색 입력창 = member 톤(46px 라운드). inout 은 --list(고정높이 → footer 잘림) 대신 자동높이 유지라 .pop_i_p_h 스코프로 개별 적용. */
.pop_i_p_h{ display: flex !important; align-items: center; gap: var(--space-3); padding: var(--space-1) 0 var(--space-4); }   /* member 검색행(.bi-pop-pay--list .body-main-sch)과 동일 간격 */
.pop_i_p_h > div{ float: none !important; padding: 0 !important; }
.pop_i_p_h > div:first-child{ position: relative; }
.pop_i_p_h .sch_but_pop{ position: absolute !important; left: 8px; top: 0; width: 34px !important; height: 46px !important; z-index: 2; }
.pop_i_p_h .fa-search{ position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--txt-disabled); font-size: var(--fs-md); pointer-events: none; z-index: 1; }
.pop_i_p_h .main_title_sub{ color: var(--txt-disabled) !important; font-size: var(--fs-base) !important; padding-left: 0 !important; }

/* 신규회원/거래처 등록 모달(popup_layer_reg · office_reg) = 공통 write 폼 디자인(.bi-write-row/field/label · .bi-input · .bi-write-select) 100% 재사용. 입력 박스 스타일은 style.css(구 write.css) 가 .bi-pop-reg 스코프로 제공. 아래는 좁은 모달(430px)에 맞춘 폭·간격 조정만. (2026-07-30 폼 디자인 write 통일) */
.bi-pop-reg .bi-write-row { gap: var(--space-3); margin-bottom: var(--space-3); }
.bi-pop-reg .bi-write-row:last-of-type { margin-bottom: 0; }
.bi-pop-reg .bi-write-field { min-width: 0; }
.bi-pop-reg .bi-write-field--half  { flex: 0 0 calc(50% - 6px); max-width: calc(50% - 6px); }
.bi-pop-reg .bi-write-field--third { flex: 0 0 calc(33.333% - 8px); max-width: calc(33.333% - 8px); }
.bi-pop-reg .bi-write-select { width: 100%; min-width: 0; }
.bi-pop-reg .bi-input--block { width: 100%; }

/* 팝업별 검색필드 폭 */
/* 검색결과 테이블 — 헤더/행을 flex 동일 컬럼으로 정렬(등록지점 줄바꿈 방지 + 위치 정렬, 휴대폰 폭 자동 축소) */
/* 2026-07-23 정산 지급율 관리(popup_layer_pay_ref) — 팝업 폭 790px 기준 검색필드 */
/* 지급율 표는 12컬럼으로 팝업 폭(790px)을 넘는다 → 표 영역만 가로 스크롤.
   ⚠ 가로 스크롤바는 **바깥(.pop_m_p_b) 한 곳에만** 둔다. 헤더(.pop_m_h)와 행(.pop_m_b)이
      함께 밀려야 컬럼 정렬이 유지되기 때문. 안쪽에도 스크롤이 생기면 헤더만 남고 행이
      따로 움직여 정렬이 깨진다.
   ⚠ .bi-pop-pay--list .pop_m_b 는 `overflow-y:auto`(위 §검색리스트 공통) 인데,
      CSS Overflow 규칙상 한 축이 non-visible 이면 나머지 축의 `visible` 이 `auto` 로 승격된다
      → 지정하지 않으면 안쪽에도 가로 스크롤바가 자동 생성(스크롤바 2개). 명시적으로 hidden 고정.
      단 hidden 이 잘라내지 않도록 .pop_m_b 폭을 표 전체 폭으로 넓혀 준다. */
/* 빈 상태 행 — 행 폭은 표와 같은 1650px(위 그룹 규칙) 이므로 기존처럼 가운데 정렬하면
   문구가 825px 지점에 놓여 화면 밖으로 밀린다. 좌측 정렬 + sticky 로 가시영역에 고정한다.
   (부모 .pop_m_b 가 1650px 라 `width:100%` 로는 못 줄인다 — 좌측 고정이 정답) */
/* 하단 고정 닫기바 — 버튼 우측 정렬(단일 자식 flex:1 무력화) */
.bi-pop-pay--list [style*="position: fixed"] .bt_div > div{ flex: 0 0 auto; }

/* 선불권 리스트(.pop_m_p_b float:left) 를 .div_wrap 가 감싸 해제 — 금액블록이 옆에 붙지 않고 세로로 쌓이게 */
.bi-pop-pay .div_wrap::after{ content: ""; display: table; clear: both; }

/* ── 선불권 결제 팝업(.bi-pop-pay--prepay) 컨텐츠 영역 간격 정돈 — 2026-07-27 ──
   레거시 인라인 값이 남긴 세 가지 어긋남을 스코프 안에서만 교정한다(인라인 자체는 보존).
     ① .div_wrap 의 좌우 10px 인덴트 → 리스트만 안쪽으로 밀려 하단 금액행과 좌우가 어긋났다.
     ② .pop_m_b 의 height:130px 고정 → 선불권 1~2건이면 아래가 텅 비고, 3건 이상이면 스크롤.
     ③ 헤더 열 폭 합(635px) ≠ 행 열 폭 합(570px) → '사용금액'부터 헤더와 값이 어긋났다. */
/* ③ 열 폭 — 헤더(.pop_m_h_sub)와 행(.pop_m_b_li_div)의 인라인 폭이 서로 달라(합계 635 vs 570)
      '사용금액'부터 어긋났고, 구매일 칸(80px − 좌패딩 15px = 65px)이 좁아 `2026-07-27` 이 두 줄로 밀렸다.
      → 양쪽에 같은 폭을 주고 날짜는 nowrap. 팝업 내부 가용폭 682px(730 − 좌우패딩 48) 안에 들어간다(합계 629).
      ⚠ 행의 li 는 hidden input 3개로 시작하므로 nth-child 가 아니라 **nth-of-type**(div 기준)으로 센다. */

/* 2026-07-31 네이버 디자이너 목록 팝업(popup_layer_employee_naver) 헤더 열 폭 보정.
   증상: 컬럼명 '네이버디자이너코드' 가 두 줄로 밀림(캡처 확인).
   원인: 헤더 2번째 열만 인라인 120px 인데 행은 150px — 폭이 어긋난 데다 좌패딩 15px 을 빼면
         가용폭 105px 이라 9글자(13px 폰트, 약 117px)가 안 들어간다.
   조치: 헤더 2번째 열을 행과 같은 150px 로 맞추고, 컬럼명은 전부 nowrap.
   ⚠ 행의 li 는 hidden input 으로 시작하므로 nth-child 가 아니라 **nth-of-type**(div 기준). */

/* 2026-07-31 카드승인취소 팝업 — 결제 주체(디자이너/사업장) 표시행(읽기전용).
   shop 원본은 인라인 style 이었으나 절대규칙(신규 인라인 style ❌)에 따라 클래스로 이식. */
/* 결제 주체(사업장/디자이너) 선택 — 카드결제 팝업은 선택형, 취소 팝업은 표시전용(disabled).
   여백: 위 안내문(.pop_desc)과 아래 '결제금액' 라벨(.bi-pop-card-label, margin-top:14px) 사이.
   아래는 6px 만 두고 나머지는 라벨 margin 이 담당 → 합계 20px 로 다른 섹션 간격과 같은 리듬. */
.bi-pop-card-payer{ display: flex; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-4); font-size: var(--fs-md); color: var(--txt-secondary); }
/* 2026-09-29 — 글이 <span> 에서 <label> 안으로 들어왔다(라벨 누락 고침).
   자리를 벌리던 규칙을 라벨에도 걸어 준다. span 규칙은 남겨 둔다 —
   같은 클래스를 쓰는 다른 취소 팝업이 아직 span 을 쓴다. */
.bi-pop-card-payer span,
.bi-pop-card-payer label{ margin-right: var(--space-3_5); }
.bi-pop-card-payer label{ cursor: pointer; }
.bi-pop-card-payer input[type="radio"]:disabled + label{ opacity: .7; cursor: default; }

/* 신용카드 팝업 — 안내문 하단여백 제거 */
.bi-pop-pay--card .pop_desc{ margin-bottom: 0; }
/* 안내문 긴 문장 넘침 시 문자단위로 다음 줄로 줄바꿈 */
.bi-pop-pay--card .pop_desc{ word-break: break-all; overflow-wrap: anywhere; }

/* ── 카드승인취소(다중결제) 선택 리스트 오버레이 — 2026-07-28 ──────────────────
   증상: 목록과 하단 버튼줄이 팝업 밖으로 넘치고(닫기 버튼 잘림), 헤더와 값의 열이 어긋나며,
         목록 아래로 큰 빈 공간이 남았다.
   원인: `.selectWrap` 이 `position:absolute; width:100%; height:510px`(팝업 인라인 style) 인데
         **기준이 되는 positioned 조상이 없어** body 기준으로 잡혔다 → 팝업 좌우 패딩(24px)만큼
         오른쪽으로 밀려 넘치고, 고정 높이 510px 이 콘텐츠와 무관하게 빈 공간을 만들었다.
         열 폭도 헤더(130/140/100)와 JS 가 그리는 행(150/150/100)이 서로 달랐다.
   대응: 팝업 래퍼에 `--cardcancel` 를 부여해 기준 컨테이너로 만들고, 오버레이를 그 안쪽에 맞춘다.
         인라인 style 은 그대로 두고 스코프 규칙으로만 덮는다. */
/* 열 폭 — 헤더(.pop_m_h_sub)와 행(.pop_m_b_li_div)에 같은 값. 행은 hidden input 으로 시작하므로 nth-of-type(div 기준) */
/* '검색결과가 존재하지 않습니다' 빈 행은 div 가 하나뿐 → 1번 열 규칙(170px)에서 제외 */
/* 하단 줄 — 안내문 좌측 / 버튼 우측, float 대신 flex (좁은 폭에서 겹치고 두 줄로 밀리던 것) */

/* 버튼 행 — 상단 구분선 + 우측 정렬 */
.bi-pop-pay .bt_div{ display: flex; justify-content: flex-end; align-items: center; gap: var(--space-2); border-top: 1px solid var(--gray-100); padding-top: var(--space-4); margin-top: var(--space-4); }
.bi-pop-pay .bt_div > div{ display: flex; gap: var(--space-2); align-items: center; }
.bi-pop-pay .bt_div > div:first-child:not(:last-child){ flex: 1; } /* 좌측 요소가 있을 때만 늘림 — 버튼 단독이면 우측 정렬 유지 */
/* 하단 고정 버튼바(선불권 등 position:fixed) — 팝업 폭에 맞춤(고정폭 넘침 방지) */
.bi-pop-pay .bt_div[style*="fixed"]{ left: 0; right: 0; width: auto; margin: 0; padding: var(--space-3) var(--space-5); background: var(--bg-card); }

/* 팝업 전역 버튼 베이스라인 — popup.css 는 팝업에서만 로드되므로 스킨(.bi-pop-pay) 없는
   레거시 팝업의 버튼에도 모던 룩 적용. 미사용 → 인라인 style 가진 버튼(결제팝업 등)은
   원본 유지(레이아웃 보호). 스킨 적용 팝업은 아래 .bi-pop-pay 규칙()이 우선. 2026-06-25 */
.bt_div input[type="button"], .bt_div input[type="submit"], .bt_div button,
input.btn_size, input.but_blue{
    height: 36px; padding: 0 var(--space-4); border-radius: var(--radius-lg); border: 1px solid var(--border-base);
    background: var(--border-light); color: var(--txt-secondary); font-size: var(--fs-base); font-weight: var(--fw-bold); cursor: pointer;
    vertical-align: middle; transition: background .12s;
}
.bt_div input[type="button"]:hover, .bt_div input[type="submit"]:hover, .bt_div button:hover{ background: var(--border-base); }/* N페이 팝업 상태 버튼(bcolor*) — 라운드/그림자 적용(색은 유지) */
.bi-pop-pay button[class*="bcolor"]{ border-radius: var(--radius-xl); font-weight: 800; border: none;  transition: filter .12s; }
.bi-pop-pay button[class*="bcolor"]:hover{ filter: brightness(.95); }
.bi-pop-pay button[class*="bcolor"] p{ margin: 0; }

/* ── N페이 스타일태그 카테고리 — 아코디언 카드(인라인 <style> 오버라이드) ── */
/* 헤어길이 라디오(FEMALE/MALE) → styleguide §5 네이티브 + brand accent (전역 input[type=radio]{visibility:hidden} + '+label' PNG 박스 무력화) */

/* ── 카드결제 팝업 ── */
/* 결제금액 행 — 할부 select(고정폭) + 금액 input(가변, 팝업 폭 채움) */
.bi-pop-pay select#txtPeriod { flex: 0 0 auto; }   /* 크기는 규격·격자가 정한다(2026-08-26) */
/* 수기 등록 체크 (우측 정렬) */
/* styleguide §5 체크박스(네이티브 accent-color)로 통일 — 전역 input[type=checkbox]{visibility:hidden} + '+label' PNG 박스 무력화 */
/* 레거시 PNG 커스텀 박스용 빈 label 제거 */
/* 결제팝업 옵션(체크박스·라디오) — styleguide §5 네이티브 + brand accent, label>input+span 패턴 (현금팝업 계좌이체/현금영수증/소득공제·지출증빙 등) */
/* 승인 정보 그리드 (결제일자 full + 카드종류/승인번호 2열) */
/* 2026-07-31 카드정보 입력(비사업자 디자이너/PayUp) — 승인정보 그리드와 동일 리듬.
   display 는 draw_payUi() 가 토글하므로 기본은 none(인라인 style 제거 대체). */
.bi-pop-pay .bi-pop-card-pg{ display: none; grid-template-columns: 1fr 1fr; gap: var(--space-3) var(--space-3_5); margin-top: var(--space-3_5); }
.bi-pop-pay .bi-pop-card-info{ display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3) var(--space-3_5); margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--gray-100); }

/* ── 선결제(예약금) 팝업(popup_layer_bk_deposit) — 금액·결제기한·방식·확인체크 리디자인 ── */
/* 결제기한 + 결제방식 2열 */
/* 결제내역 확인 체크박스 — 전역 input[type=checkbox]{visibility:hidden} 무력화(§5-1) */

/* designer_chart 모달 스타일이 의존하는 --dc-* 변수 재선언(팝업은 .bi-page--scroll 밖) */
.bi-pop-reg {
    --dc-blue:var(--brand-blue); --dc-blue-soft:rgba(0,35,183,.05); --dc-navy:var(--brand-navy);
    --dc-ink:var(--txt-primary); --dc-sub:var(--txt-muted); --dc-mut:var(--txt-disabled); --dc-line:var(--border-base);
    font-family: var(--font-sans);
}

/* ════════════════════════════════════════════════════════════
   예약일시 팝업(popup_layer_bk_datetime) — 캘린더 + 시작/종료시간 3컬럼 리디자인
   · supercal CSS 는 booking/style.css 에만 있고 이 팝업엔 미로딩 → 여기서 스코프 재정의
   · 인라인 width/height/float 무력화() 후 카드형 3컬럼 + 시간칩 그리드
   ════════════════════════════════════════════════════════════ */
.bi-pop-pay.bi-pop-pay--dt{
    padding: var(--space-4) var(--space-5);
    display: flex; flex-wrap: wrap; align-items: stretch; gap: var(--space-3_5);
}
/* 3개 컬럼(.pop_body) — 인라인 width:280/height 무력화 → 균등 카드 */
.bi-pop-pay--dt .pop_body{
    width: auto; height: auto; flex: 1 1 0; min-width: 250px;
    background: var(--bg-card); border: 1px solid var(--gray-100); border-radius: var(--radius-2xl);
    padding: var(--space-3_5) var(--space-4); margin: 0; box-sizing: border-box;
}
.bi-pop-pay--dt .pop_body.pop_border_l{ border-left: 1px solid var(--gray-100); }
.bi-pop-pay--dt .pop_m_p_b{ width: auto; }/* 섹션 헤더(예약 날짜 / 예약시작시간 / 예약종료시간) — 구분선 없음 */
.bi-pop-pay--dt .pop_m_h_sub{
    width: auto; padding: 0;
    font-size: var(--fs-base); font-weight: var(--fw-extrabold); color: var(--brand-blue); white-space: nowrap;
}/* .pop_m_b 공통 — 인라인 width/height 무력화(블록 유지). ⚠ 캘린더 컬럼의 .pop_m_b(.cal 포함)도 이 규칙만 받게 함 */
.bi-pop-pay--dt .pop_m_b{
    width: auto; height: auto; margin: 0 0 var(--space-3);
}
/* 오전/오후 행은 시간 컬럼(.pop_border_l)에만 flex 적용 — 캘린더 컬럼(.cal)이 32px 로 오므라드는 버그 방지 */
.bi-pop-pay--dt .pop_border_l .pop_m_b{
    display: flex; align-items: flex-start; gap: var(--space-2_5);
}
.bi-pop-pay--dt .pop_border_l .pop_m_b > div:first-child{ /* 오전/오후 라벨 */
    float: none; width: 32px; height: auto; margin: 0;
    flex: 0 0 32px; padding-top: var(--space-1_5); font-size: var(--fs-sm); font-weight: var(--fw-extrabold); color: var(--txt-muted);
}
.bi-pop-pay--dt .time_block{
    width: auto; float: none; flex: 1; min-width: 0;
    display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-1_5);
}
/* 캘린더 컨테이너 — 컬럼 전체폭 채움(.pop_m_b > div:first-child 류 영향 차단) */
.bi-pop-pay--dt .cal{ width: 100%; float: none; flex: none; }/* 고를 수 없는 시간(첫 칸·마지막 칸). JS 가 인라인으로 #efefef/#b9b9b9 를 찍던 자리 —
 * 상태는 클래스로, 색은 토큰으로(2026-08-14).
 * ⚠ :hover 도 같이 눌러야 «고를 수 없는데 손을 대면 반응하는» 칸이 되지 않는다. */
.bi-pop-pay--dt .t_butn.is-disabled,
.bi-pop-pay--dt .t_butn2.is-disabled{ background: var(--gray-100); color: var(--gray-400); cursor: default; }
.bi-pop-pay--dt .t_butn.is-disabled:hover,
.bi-pop-pay--dt .t_butn2.is-disabled:hover{ background: var(--gray-100); color: var(--gray-400); border-color: var(--border-base); }

/* ── supercal 캘린더 (브랜드 블루 톤 재디자인 — 자체완결: bootstrap 미로딩) ──
   · 플러그인이 nav 버튼/셀에 .css()(인라인 font-size:30px·color)로 직접 박으므로 로 제압
   · transition='carousel-vertical' 은 월전환 시 table 을 position:absolute 로 슬라이드 → .supercal-month overflow:hidden 필수 */
.bi-pop-pay--dt .supercal{ width: 100%; }
.bi-pop-pay--dt .supercal-header{
    width: 100%; margin: 0 0 var(--space-2_5); line-height: 1;
    display: flex; align-items: center; justify-content: space-between;
}
/* ⚠ 2026-08-31 — 캘린더를 규격안(popup_spec2 §1 `.cal`) 값으로 다시 짰다.
   그동안 「고쳤다」고 했지만 화면은 옛 모양 그대로였다. 이유는 CSS 가 아니라 **플러그인의 인라인 style**
   (jquery.supercal.js 가 .css('color','red') · .css('font-size','30px') 로 직접 박음)이 이겼기 때문이다.
   플러그인 쪽 인라인을 걷어내고(그 파일은 이 팝업만 쓴다) 여기서 모양을 정한다.
   규격안 값: 월표시 12.5/800 · 요일 10.5 회색 · 날짜 12/600 · 칸 radius 7 · 고른 날 navy · 다른 달 #D1D5DB */
.bi-pop-pay--dt .supercal-header .month{
    order: 1; flex: 1; text-align: center;
    font-size: 12.5px; font-weight: var(--fw-extrabold); color: var(--txt-primary);
}
.bi-pop-pay--dt .supercal-header .month div{ display: inline; }.bi-pop-pay--dt .supercal-header button.prev-month{ order: 0; }
.bi-pop-pay--dt .supercal-header button.next-month{ order: 2; }.bi-pop-pay--dt .supercal-month{ margin: 0; overflow: hidden; position: relative; }
.bi-pop-pay--dt .supercal table{
    width: 100%; margin: 0; background: transparent;
    border-collapse: separate; border-spacing: 2px; table-layout: fixed;
    box-sizing: border-box;   /* width:100% 에 border-spacing 포함 → 카드 영역 밖으로 안 넘침 */
}.bi-pop-pay--dt .cal{ max-width: 100%; overflow: hidden; }
/* 요일 머리 — 규격안은 주말도 «회색 한 톤» 이다(옛 화면의 빨강·파랑은 플러그인 인라인이었다) */
.bi-pop-pay--dt .supercal th{
    font-size: 10.5px; font-weight: var(--fw-semibold); color: var(--txt-muted);
    text-align: center; padding: var(--space-0_5) 0 var(--space-1_5);
    border: none; background: transparent;
}
/* 날짜 칸 — 배경 없이, 고른 날만 채운다 */
.bi-pop-pay--dt .supercal td{
    text-align: center; cursor: pointer; height: 30px; padding: var(--space-1) 0; color: var(--txt-secondary);
    /* 규격안 값은 7 이지만 토큰에 7 이 없다 → 가장 가까운 --radius-md(6). 새 토큰을 만들지 않는다. */
    border: none; border-radius: var(--radius-md); font-size: var(--pop-cnt-fs); font-weight: var(--fw-semibold);
    background: transparent; transition: background .12s, color .12s;
}
.bi-pop-pay--dt .supercal td:hover{ background: var(--bg-selected); color: var(--brand-blue); }
/* 지난 날·다른 달만 흐리다 — 그 밖의 날은 한 톤 */
.bi-pop-pay--dt .supercal td.before{ color: var(--gray-300); cursor: default; }
.bi-pop-pay--dt .supercal td.today{ box-shadow: inset 0 0 0 1.5px var(--color-info-200); font-weight: var(--fw-extrabold); }
.bi-pop-pay--dt .supercal td.selected{ background: var(--brand-navy); color: var(--bg-card); font-weight: var(--fw-extrabold); }
.bi-pop-pay--dt .supercal-footer{ display: none; } /* 하단 입력행 숨김(헤더로 충분) */

/* 하단 안내문 + 완료/닫기 버튼 영역 — 전체폭 차지 */
.bi-pop-pay--dt > div:last-child{ flex: 1 1 100%; }

/* ── 신규 회원/거래처 등록 팝업(popup_layer_reg · office_reg) — 공통 write 폼(.bi-write-* · .bi-input) 사용 + 팝업 본문 패딩 ──
   ⚠ 2026-08-07 결함 수정: 원문이 `.bi-write-*​/.bi-input` 이라 그 `*` + `/` 가 **주석을 조기 종료**시켰다.
   뒤 문구가 CSS 로 파싱되며 파서가 어긋나고 짝 없는 종료자가 남았다. 와일드카드 뒤 `/` 금지. ── */
/* 팝업 콘텐츠 영역 공통 여백은 --pop-pad-y/x 토큰(style.css :root)에서 불러씀 — 개별 하드코딩 대신 공통 규격 사용 */
.bi-pop-reg{ padding: 0 var(--pop-head-pad-x); color: var(--txt-primary); box-sizing: border-box; }   /* 보드 .pop-body 좌우값(2026-08-27) */
.bi-pop-reg *{ box-sizing: border-box; }

/* ── 스타일 카탈로그 팝업(popup_layer_catalog) — 본문 cat 스타일은 아래로 이관됨(팝업 공통). 모달 박스 → 팝업 전체폭 채움 ── */
/* 콘솔(좌) + 갤러리(우) 가로 배치 확정 */
/* ⚠ designer_chart/style.css @media(max-width:1024) 가 콘솔 display:none/view 220 처리 — 팝업 iframe(~980px)은 항상 ≤1024 라 무력화 필요 */

/* 카탈로그 팝업 본문 스타일 — designer_chart/style.css 에서 이관(팝업 공통 · 2026-07-30). --dc-* → 전역 토큰. */
/* 헤더를 공용 .bi-pop-head 로 통일 — 컨테이너 padding:20 상쇄해 헤더바를 박스 상단 가장자리까지(라운드 20 매칭).
   width:auto — 공용 .bi-pop-head{width:100%}(=content 폭)이면 음수 margin 상쇄 후 우측 40px 빔 → auto 로 flex stretch 가 margin 까지 채워 박스 폭 꽉 참. */
/* 공용 .bi-pop-head-title 은 overflow:hidden(긴 제목 말줄임)이라 __who 배지에 padding 크게 주면 상하가 잘림.
   카탈로그 제목은 짧으므로 넘침 허용 + inline-flex 로 배지 높이만큼 타이틀/헤더가 커지도록(잘림 방지·수직 중앙). */

.bi-catalog__tab { flex: 1; border: 0; background: transparent; color: var(--txt-muted); font-size: var(--fs-sm); font-weight: var(--fw-extrabold); padding: var(--space-2) var(--space-1_5); border-radius: var(--radius-lg); cursor: pointer; }
.bi-catalog__tab:hover { color: var(--txt-primary); }
.bi-catalog__tab.is-active { background: var(--bg-card); color: var(--gray-950);  }
.bi-catalog__thumb { position: relative; aspect-ratio: 1/1; border: 2px solid var(--border-base); border-radius: var(--radius-xl); overflow: hidden; background: var(--bg-card); cursor: pointer; padding: 0; }
.bi-catalog__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bi-catalog__thumb:hover { border-color: var(--color-indigo-200); }
.bi-catalog__thumb.is-selected { border-color: var(--brand-blue);  }
/* 2026-06-26 카탈로그 썸네일 삭제 버튼(hover) — 갤러리(.bi-gallery__del) 패턴 재사용. 시술 후 사진만 표시 */
.bi-catalog__del { position: absolute; top: 5px; right: 5px; width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%; background: color-mix(in srgb, var(--black) 60%, transparent); color: var(--bg-card); font-size: var(--fs-xs); line-height: 1; display: none; align-items: center; justify-content: center; cursor: pointer; z-index: 3; }
.bi-catalog__thumb:hover .bi-catalog__del { display: inline-flex; }
.bi-catalog__del:hover { background: var(--color-danger-600); }
/* 사진 고유 비율 유지 — 정사각형 강제·크롭 제거. 폭에 맞추되 높이는 원본 비율대로(세로 길면 컬럼 스크롤). */
.bi-catalog__swatch { width: 18px; height: 18px; border-radius: var(--radius-full); border: 1px solid var(--border-base); display: inline-block; }
@media (max-width: 1024px) {
}

/* ════════════════════════════════════════════════════════════
   제휴/할인 팝업(popup_layer_discount) — 할인 모달 디자인 (2026-06-25)
   ════════════════════════════════════════════════════════════ */

/* 프리셋(쿠폰) 영역 */

/* 직접 수동 조율 */
/* ── booking_renew 간편예약 팝업 (popup_layer_bk_quick) — 인라인 모달에서 이전. 오버레이/모달/헤더는 플러그인이 제공하므로 제외 ── */
.bi-bq-field label { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-secondary); }

/* 결제 요약 팝업 본문(popup_layer_dchart_pay) — designer_chart/style.css 에서 이관(팝업 공통 · 2026-07-30). --dc-* → 전역 토큰. */
.bi-paypop__custsub { font-size: var(--fs-lg); color: var(--txt-muted); font-weight: var(--fw-bold); }
.bi-paypop__divider { border-bottom: 1px solid var(--border-light); }
.bi-paypop__item { display: flex; justify-content: space-between; align-items: center; font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--gray-600); padding: var(--space-2) 0; border-top: 1px solid var(--gray-50); }
.bi-paypop__item:first-child { border-top: 0; }
.bi-paypop__pkg { font-size: var(--fs-sm); font-weight: var(--fw-extrabold); color: var(--color-purple-700); background: color-mix(in srgb, var(--color-purple-700) 10%, transparent); padding: var(--space-0_5) var(--space-2); border-radius: var(--radius-sm); }
/* 2026-08-28 — 아래 16 은 보드에서 «본문» 의 것이다(.pop-body padding-bottom).
   이 팝업들은 본문이 .bi-pop-pad 가 아니라 제 스크롤 상자라 규격 여백을 못 받는다 → 여기서 준다. */
.bi-paypop__scroll { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: var(--space-3_5); padding-bottom: var(--space-4); }
.bi-paypop__qty { font-size: var(--fs-xs); color: var(--brand-blue); font-weight: var(--fw-extrabold); }
#dchart_pay_split_body .bi-paypop__item { width: 100%; }
.bi-paypop__chip { font-size: var(--fs-2xs); border-radius: var(--radius-lg); padding: var(--space-1_5) var(--space-2_5); font-weight: var(--fw-black); cursor: pointer; border: 1px solid; }
.bi-paypop__chip.is-on { background: var(--color-danger-600); color: var(--bg-card); border-color: var(--color-danger-600);  }
.bi-paypop__disc-none { font-size: var(--fs-xs); color: var(--txt-disabled); font-style: italic; padding: var(--space-0_5) 0; }
.bi-paypop__method { padding: var(--space-2) var(--space-0_5); border-radius: var(--radius-xl); border: 1px solid var(--gray-300); background: var(--bg-card); font-size: var(--fs-sm); font-weight: var(--fw-black); color: var(--txt-secondary); cursor: pointer; }
.bi-paypop__method:hover { background: var(--bg-input); }
.bi-paypop__method.is-active { background: color-mix(in srgb, var(--brand-blue) 10%, transparent); border-color: var(--brand-blue); color: var(--brand-blue); }
.bi-paypop__method.is-npay.is-active { background: color-mix(in srgb, var(--color-npay) 10%, transparent); border-color: var(--color-npay); color: var(--color-npay); }
.bi-paypop__method.is-disabled, .bi-paypop__method.is-disabled:hover { opacity: .45; cursor: not-allowed; background: var(--border-light); color: var(--txt-disabled); border-color: var(--border-base); }

/* AI 메시지(CRM 컴포저) 팝업 본문(popup_layer_ai_msg) — designer_chart/style.css 에서 이관(팝업 공통 · 2026-07-30). --dc-* → 전역 토큰. */
.bi-msgpop__mode { border: 1px solid var(--border-base); border-radius: var(--radius-xl); padding: var(--space-2_5); text-align: center; display: flex; flex-direction: column; align-items: center; gap: var(--space-0_5); cursor: pointer; transition: all .12s; }
.bi-msgpop__mode i { color: var(--txt-disabled); }
.bi-msgpop__mode:hover { border-color: var(--brand-blue); background: var(--dc-blue-soft); }
.bi-msgpop__mode.is-active { border-color: var(--brand-blue); background: var(--dc-blue-soft); }
.bi-msgpop__mode.is-active i { color: var(--brand-blue); }
.bi-msgpop__mode.is-disabled { opacity: .45; cursor: not-allowed; pointer-events: none; }

/* 2026-07-31 AI 메시지 팝업(popup_layer_ai_msg) 높이 구조 — **콘텐츠 높이에 맞춤**(스크롤 없음).
   래퍼에 고정 높이를 주지 않아 자연 높이가 나오고, 팝업의 fitPopup 이 그 값을 재서
   박스=콘텐츠+헤더(64), iframe=콘텐츠 로 맞춘다 → 내부 스크롤바가 생기지 않는다.
   화면이 너무 작아 다 못 담을 때만 iframe 자체 스크롤(scrolling="auto")이 폴백으로 동작.
   ⚠ 기존 .bi-pop-pay--aim(popup.css) 규칙은 그대로 두고 신규 클래스로 분리. */
/* ⚠ 래퍼(.bi-pop-pay--aim)에는 gap 을 주지 말 것 — 자식이 [본문]+[버튼바] 둘뿐이라
   **버튼 아래 흰 여백**으로 나타난다(실측 확인). popup.css:272 에서 해당 gap 규칙을 제거했다.
   본문↔버튼바 간격은 __scroll 의 padding-bottom 으로 준다. */
.bi-pop-pay--aim-fit { height: auto; }

/* 2026-07-31 SMS/LMS 선택 카드 — 팝업 톤 정렬.
   기존 `.bi-msgpop__mode*`(위 419~) 는 designer_chart 본문도 쓰므로 건드리지 않고,
   **팝업 스코프(.bi-pop-pay--aim-fit) 안에서만** 덮는다.
   맞춘 기준: 수신인 카드(.bi-msgpop__recv) 의 radius 14 / 발송 버튼의 --brand-blue.
   기존 --dc-blue-soft 는 alpha .05 라 선택 상태가 거의 안 보였다 → 테두리·틴트·그림자로 강화. */
/* ⚠ 2026-08-28 — SMS·LMS 가 **세로로 쌓여** 있었다.
   `.bi-write-grid-2` 는 1024px 이하에서 1열로 접히는데(본문 화면용 반응형),
   팝업 iframe 은 폭이 423 이라 **언제나** 그 조건에 걸린다. 팝업은 화면 축소가 아니라
   제 폭을 가진 상자이므로 여기서는 2열을 되돌린다. */
.bi-pop-pay--aim-fit .bi-write-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2_5); }
.bi-pop-pay--aim-fit .bi-msgpop__mode {
    position: relative; padding: var(--space-3) var(--space-2_5); gap: var(--space-1_5);
    background: var(--bg-card); border: 1px solid var(--dc-line); border-radius: var(--radius-2xl);
    transition: border-color .12s, background .12s, box-shadow .12s, color .12s;
}
.bi-pop-pay--aim-fit .bi-msgpop__mode i { font-size: var(--fs-md); color: var(--dc-mut); transition: color .12s; }
.bi-pop-pay--aim-fit .bi-msgpop__mode:hover { border-color: var(--brand-blue); background: var(--bg-input); }
/* 선택 상태 — 테두리 + 옅은 틴트 + 인셋 링(1px 이중선 효과) */
.bi-pop-pay--aim-fit .bi-msgpop__mode.is-active {
    border-color: var(--brand-blue); background: color-mix(in srgb, var(--brand-blue) 5%, transparent);
    box-shadow: inset 0 0 0 1px var(--brand-blue), 0 2px 6px color-mix(in srgb, var(--brand-blue) 12%, transparent);
}
.bi-pop-pay--aim-fit .bi-msgpop__mode.is-active i { color: var(--brand-blue); }
/* 선택 체크 — FA5 Pro solid(f00c). 아이콘 폰트는 팝업이 이미 로드(fas fa-paper-plane 등) */
.bi-pop-pay--aim-fit .bi-msgpop__mode.is-active::after {
    content: '\f00c'; font-family: 'Font Awesome 5 Pro'; font-weight: 900;
    position: absolute; top: 7px; right: 9px; font-size: var(--fs-2xs); color: var(--brand-blue);
}
/* 비활성(90바이트 초과 시 SMS) — 점선으로 '선택 불가'를 명시 */
.bi-pop-pay--aim-fit .bi-msgpop__mode.is-disabled {
    opacity: .45; background: var(--bg-input); border-style: dashed; box-shadow: none;
}

/* ── 시술이미지 팝업(popup_layer_img · member·buysell 공용) 본문 — member/style.css 에서 이관,
 *   전부 #popup_layer_img 스코프(전역 누출 차단) · 2026-07-30
 *   ⚠ 무스코프 선택자(.container/.pop_desc/.img-box 등) — 다른 모듈 누출 위험.
 *   Phase 2 에서 .bi-mem-pop-* wrapper 스코프로 격리한다.
 *   (2026-08-07 결함 수정: 위 2줄이 주석 밖으로 나와 CSS 로 파싱되고 있었다) ── */

/* 시술이미지 팝업 */
/* 2026-07-28 스코프 누출 차단: bare .container(Bootstrap 등과 충돌 위험) → 시술이미지 팝업 컨테이너(#popup_layer_img) 하위로 격리. popup_layer_img.php 에서만 사용(확인). */
#popup_layer_img .container {
    max-width: 600px;
    margin: 0 auto;
    padding: var(--space-2_5) var(--space-5);
    position: relative;
}

#popup_layer_img .form-setting {
    padding: 0px;
    margin: 0px;
}

#popup_layer_img .dp-none {
    display: none;
}

#popup_layer_img .cursor {
    cursor: pointer;
}

#popup_layer_img .box-prev {
    position: absolute;
    left: 6px;
    top: -10px;
}

#popup_layer_img .box-next {
    position: absolute;
    right: 6px;
    top: -10px;
}

#popup_layer_img .pop_desc {
    line-height: 40px;
    display: flex;
    justify-content: space-between;
    margin-bottom: var(--space-1_5);
    font-size: var(--fs-md);
    color: var(--txt-muted);
    font-weight: var(--fw-medium);
}

#popup_layer_img .thumbnail-slider-wrapper {
    overflow: hidden;
    position: relative;
    width: 100%;
}

#bx-pager {
    display: flex;
    margin-bottom: var(--space-5);
    transition: transform 0.3s ease;
}

#popup_layer_img .box-nav {
    position: absolute;
    top: 16%;
    left: 0%;
    width: 100%;
    transform: translateY(-50%);
}

#popup_layer_img .box-nav span {
    cursor: pointer;
    font-size: var(--fs-sm);
    font-weight: bold;
    color: var(--bg-card);
    background: var(--gray-300);
    padding: var(--space-1_5) var(--space-2_5);
    border-radius: 50%;
}

#bx-pager .img-box {
    flex: 0 0 calc((100% - 40px) / 5);
    width: calc((100% - 40px) / 5);
    max-width: calc((100% - 40px) / 5);
    height: 100px;
    display: inline-block;
    position: relative;
    border: 1px solid var(--gray-300);
    text-align: center;
    overflow: hidden;
    border-radius: var(--radius-sm);
    margin-right: var(--space-2);
    cursor: pointer;
}

#popup_layer_img .img-box img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

#popup_layer_img .img-box .upload-btn {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
    cursor: pointer;
    font-size: var(--fs-2xl);
    color: var(--gray-600);
    background-color: var(--gray-50);
    transition: background-color 0.3s;
}

#popup_layer_img .img-box .upload-btn:hover {
    background-color: var(--gray-200);
}

#popup_layer_img .img-box .tag {
    position: absolute;
    top: 5px;
    left: 5px;
    background: color-mix(in srgb, var(--color-indigo-500) 80%, transparent);
    color: var(--bg-card);
    font-size: var(--fs-sm);
    padding: var(--space-0_5) var(--space-1_5);
    border-radius: var(--radius-xs);
    line-height: 15px;
}

#popup_layer_img .img-box .delete {
    position: absolute;
    top: 5px;
    right: 5px;
    background: color-mix(in srgb, var(--color-indigo-500) 80%, transparent);
    color: var(--bg-card);
    font-size: var(--fs-sm);
    padding: var(--space-0_5) var(--space-1_5);
    border-radius: var(--radius-xs);
    cursor: pointer;
    line-height: 15px;
    transition: background-color 0.3s;
}

#popup_layer_img .img-box .delete:hover {
    background: color-mix(in srgb, var(--color-indigo-500) 80%, transparent);
}

#popup_layer_img .slider-container {
    width: 100%;
    max-width: 600px;
    margin: 0 auto;
    position: relative;
}

/* ul-slider 클래스 추가 - 이미지 너비 깨짐 방지 */
#popup_layer_img .ul-slider {
    list-style: none;
    margin: 0;
    padding: 0;
    width: 100%;
}

#popup_layer_img .ul-slider li {
    /* width: 100%; */
    height: 400px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--gray-50);
    overflow: hidden;
}

/* 기존 slider 스타일 제거하고 ul-slider로 통합 */
#popup_layer_img .slider_img {
    max-height: 400px;
    max-width: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    display: block;
}

#popup_layer_img .bx-pager {
    text-align: center;
    margin-top: var(--space-4);
}

#popup_layer_img .bx-pager-link {
    display: block;
    width: 60px;
    height: 60px;
    border: 2px solid var(--gray-300);
    border-radius: var(--radius-sm);
    overflow: hidden;
    transition: border-color 0.3s;
}

#popup_layer_img .bx-pager-link.active {
    border-color: var(--brand-blue);
}

#popup_layer_img .bx-pager-link img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

#popup_layer_img .loading {
    display: none;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: color-mix(in srgb, var(--white) 90%, transparent);
    padding: var(--space-5);
    border-radius: var(--radius-lg);
    z-index: 1000;
}

#popup_layer_img .spinner {
    width: 40px;
    height: 40px;
    border: 4px solid var(--gray-100);
    border-top: 4px solid var(--brand-blue);
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin: 0 auto;
}

@keyframes spin {
    0% {
        transform: rotate(0deg);
    }

    100% {
        transform: rotate(360deg);
    }
}

#popup_layer_img .empty-slider {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 400px;
    background-color: var(--gray-50);
    color: var(--txt-disabled);
    font-size: var(--fs-2lg);
    border: 2px dashed var(--gray-300);
    border-radius: var(--radius-lg);
}

/* ============================================================
   sg2 §38-3 팝업 헤더(컴팩트) · §38-4 리스트형 콘텐츠 — 2026-08-10 확정
   근거: 사용자 확정 — A "컴팩트 + 아이콘(fa-user)" · B-1 "표형·단일선택" · B-4 "카드행형·다중선택"
        (팝업 규격 추천안 검토 → styleguide2 §38 반영)
   ⚠ 기존 .bi-pop-head / .bi-pop-list--member 등은 손대지 않는다(§4 절대규칙).
     신규 modifier·클래스만 추가하고, 실제 팝업 57개 적용은 모듈별 마이그레이션으로 별도 진행.
   ============================================================ */

/* ── 38-4-A. 표형 리스트(정형 다컬럼 · 단일선택) ──
   체크박스 없음. 행 클릭 → 좌측 3px 브랜드블루 바 + 연파랑 하이라이트. */
.bi-pop-tbl-row{
    display: grid; gap: var(--space-2); align-items: center;
    /* ⚠ box-sizing 필수 — 이 파일엔 전역 `* { box-sizing }` 이 없다.
     * 없으면 좌우 패딩 24px 이 폭에 더해져 목록이 넘친다(2026-08-12, 13개 팝업에서 실측). */
    box-sizing: border-box;
    padding: var(--space-2_5) var(--space-3); border-bottom: 1px solid var(--border-light);
    font-size: var(--fs-base); color: var(--txt-primary); cursor: pointer;
}
.bi-pop-tbl-row:last-child{ border-bottom: 0; }
.bi-pop-tbl-row:hover{ background: var(--color-info-50); }
/* 스타일보드 원칙 02 «선택 상태는 indigo 하나로» (2026-08-21 A단계) —
 * 주 액션(--brand-blue)과 **다른 색**이어야 «누를 곳» 과 «고른 것» 이 구분된다.
 * 단일선택 = 좌측 4px 막대 + 옅은 바탕 · 다중선택 = indigo 체크박스. 보드 Don't: 선택 강조에 brand-blue 금지. */
.bi-pop-tbl-row.is-sel{ background: var(--bg-selected); box-shadow: inset 4px 0 0 var(--color-indigo-600); }
/* 팝업 문서 바탕 — iframe 팝업은 **자기 document** 라 페이지 body 규칙이 미치지 않는다.
 * 그래서 14개 팝업이 `<body style='background:#fff'>` 를 각자 달고 있었다(2026-08-11).
 * ⚠ 흰색 리터럴이 아니라 토큰이다 — 카드 배경과 같은 값을 써야 테마가 갈리지 않는다. */

/* 팝업 콘텐츠 좌우 여백 — iframe 팝업은 페이지 셸 밖이라 자기 여백을 스스로 준다.
 * 2026-08-11: 26개 팝업이 이걸 `style="padding: 0px 10px"` 인라인으로 39번 반복하고 있었다. */
/* ⚠ box-sizing 필수 — 이 파일에는 전역 `* { box-sizing }` 이 없다. 안 주면 패딩이
 * 폭에 더해져 부모를 넘친다(slip_2022 에서 599 > 580 으로 실제 발생, 2026-08-11). */
/* 하단 닫기/확인 바 — 본문과 떨어뜨리는 윗여백. 구 `style="padding-top:11px"` 18회. */
/* 팝업 안 블록 사이 간격 — 안내문·구획을 앞 블록과 떼어 놓는다.
 * 구 `style="padding-top:15px"` 이 13개 팝업에서 17번 반복됐다(2026-08-11).
 * ⚠ 이건 **여백 유틸리티가 아니다.** 팝업 블록 간격 하나만을 위한 이름이고,
 *   다른 간격이 필요하면 그때 규격을 다시 본다. 여백 utility 를 열지 않는다. */
/* 명세 행의 항목명 칸 강조 — 결제 팝업이 `color:#4285f4` 리터럴로 쓰던 것.
 * 규격색(--brand-blue)으로 바꾼다. 리터럴은 테마가 갈릴 때 혼자 남는다. */
/* 결제 금액 입력 — 팝업에서 가장 눈에 띄어야 하는 한 칸. 높이는 §21-3 --md(40px)와 같아
 * 그걸 병기하고, **폭과 글자 크기만** 여기서 준다(구 인라인 width:300px·font-size:20px ×4파일). */
/* 구 .bi-pop-pay__amt — §21-3 입력 눈금으로 흡수(2026-08-11) */
/* 결제 팝업의 좁은 셀렉트(할부개월 등) — 구 인라인 font-size:16px;width:120px;height:30px ×3파일 */
/* 구 .bi-pop-pay__sel — §21-3 입력 눈금으로 흡수(2026-08-11) */
/* 필드 묶음 안쪽 여백 — 구 인라인 padding:7px 11px ×5파일 */
.bi-pop-field{ padding: var(--space-1_5) var(--space-3); box-sizing: border-box; }
/* 팝업 검색 입력 — 검색바(.bi-row)에 들어가는 한 칸. 구 인라인 width:250px ×7파일.
 * ⚠ --block(100%)이 아니다. 옆에 검색 버튼·안내문이 서므로 고정폭이 맞다. */
/* ⚠ .bi-msgprev-phone(폰 목업 250px)과 값이 같지만 **다른 것**이다 —
 * 하나는 검색 입력, 하나는 브랜드 자산 목업 폭. 우연 일치라 합치지 않는다. */
/* 구 .bi-pop-search-input(250px) — §21-3 .bi-input--w250 으로 흡수(2026-08-11).
 * ⚠ 이 이름은 7008행에 **다른 의미로 이미 있었다**(카탈로그 검색의 테두리 없는 입력).
 *   모르고 같은 이름을 또 정의해 그 입력의 폭을 250px 로 바꿔 놓고 있었다. */
/* 결제 정보 조회칸 — 읽기전용으로 승인일자·카드사·승인번호를 보여주는 작은 입력.
 * 구 인라인 `height:25px; width:110px; margin-top:4px` ×8회(card·card_cancel 계열). */
/* 구 .bi-pop-input-sm — §21-3 입력 눈금으로 흡수(2026-08-11) */
/* 네이버페이 결제 버튼 — 색은 기존 .bcolor2~5 가 상태별로 준다. 여기서는 **크기와 글자만**.
 * 구 인라인 `height:60px; font-size:14px; color:#FFFFFF` ×10회(npay_btn).
 * 폭은 인라인 %·px 대신 부모 .bi-row 와 .bi-fill 이 나눈다. */
/* 결제 버튼 행 — 한 줄에 1~2개. 버튼이 폭을 **균등하게 나눈다**(구 인라인 49%/32%/230px).
 * 아래 여백은 행이 준다(구 인라인 margin-bottom:10px ×5회). */

/* ── 38-6. 예약 일시 선택기 (2026-08-11) ──
 * 날짜 · 시간 · 담당자를 고정폭 패널로 나란히 놓는 예약 팝업 전용 구조.
 * 구 인라인 `width:280px; height:350px` / `width:280px; height:50%; margin:15px 0`
 * / `width:230px; float:right` 가 bk_datetime 에서 12번 반복됐다.
 * ⚠ float 를 flex 로 바꾸지 않았다 — 이 팝업은 기존에 가로넘침 4건이 있어
 *   배치를 손대면 원인이 섞인다. **규격으로 옮기기만** 하고 넘침은 따로 본다. */
/* 폭은 변수로 — 선택기마다 열 폭이 다르다(bk_datetime 280 · bk_p 150/220/350 · setpoint 430).
 * 값을 인라인으로 흩뿌리는 대신 **정해진 눈금**만 둔다. 새 폭이 필요하면 여기에 추가한다. */
/* 높이가 내용에 맞아야 하는 열 */
/* 구 .bi-pop-picker__col--auto — .bi-pop-pay--aim-fit 와 같아 합침(2026-08-12) */

/* ── 38-7. 예약 선택 패널 (2026-08-11) — booking_renew 팝업 ──
 * 디자이너 가로 스크롤 띠 + 우측 예약정보 패널. 인라인 30건이 이 구조를 그리고 있었다. */
.bi-pop-bk__track    { width: 100%; font-size: var(--fs-base); line-height: 3.2; }
.bi-pop-bk__strip    { display: -webkit-inline-box; overflow-x: hidden; }
.bi-pop-bk__emp-pad  { padding-left: var(--space-6); }   /* 디자이너 띠 항목 좌여백 */

/* ── 팝업 잔여 반복 (2026-08-11) — 한 파일에만 있어도 인라인보다 규격이 낫다 ── */
/* 합계 블록(우측 정렬 · 굵게) — npay·edit_pkg 공통 */
.bi-pop-total{ width: 50%; font-size: var(--fs-md); float: right; padding-top: var(--space-8); font-weight: var(--fw-bold); }
/* 어두운 머리띠 — npay 결과 안내 */

/* 발송 팝업 좌측 수신자 칸(273px) 과 가운데 세로 구분선 */
/* 금액 입력(우측 정렬 고정폭) — prepay */
/* 구 .bi-pop-amt-in — .bi-num-input 과 같아 제거(2026-08-11) */
/* 하단 고정 바 — prepay 처럼 스크롤되는 팝업의 버튼줄 */

/* ── 잔여 반복 2차 (2026-08-11) ── */
/* 선택기 좌우 이동 버튼(40px 세로 막대) — 높이만 두 가지 */
/* 읽기전용 표시 입력(테두리 없이 값만 보여준다) */
/* 구 .bi-pop-readonly-in — §21-3 입력 눈금으로 흡수(2026-08-11) */
/* 우하단에 고정되는 작은 입력 */
/* 아주 작은 숫자 입력(횟수 등) */
/* 구 .bi-pop-tiny-in — §21-3 입력 눈금으로 흡수(2026-08-11) */
/* 구 .bi-pop-date-in — §21-3 입력 눈금으로 흡수(2026-08-11) */
/* 오른쪽 절반 블록 */

/* ── 잔여 반복 3차 (2026-08-11) ── */
/* ⚠ position:relative 하나뿐이라 .bi-dropdown-anchor 등과 선언이 겹친다. **우연 일치다** —
 * 배치 기준점은 컴포넌트마다 따로 잡는 것이라 합치면 의미가 무너진다. */
/* ── 자리 기준점 — «절대배치 자식을 담는 통» 이라는 뜻이 전부 같다.
      흩어 두면 같은 선언이 다섯 벌이 된다(QC SPEC-DUP). 한 규칙이 맡는다. (2026-09-11) */
.bi-pop-pad--rel,        /* .bi-pop-pad 위에 병기 */
.bi-dropdown-anchor,
.bi-pop-pay--cardcancel,
.bi-schmx__body,
.bi-bk2-search           /* 돋보기가 칸 «안» 에 앉는다 */
{ position: relative; }
.bi-pop-pad--wide  { padding: 44px var(--space-3); box-sizing: border-box; } /* 넓은 상하 여백 블록 */
.bi-pop-cover{ position: absolute; inset: 0; display: flex; flex-direction: column; background: var(--bg-card); color: var(--txt-primary); box-sizing: border-box; }
.bi-pop-cover .bi-pop-pad{ flex: 1 1 auto; }
/* 구 .bi-pop-amt-wide — §21-3 입력 눈금으로 흡수(2026-08-11) */
/* 구 .bi-pop-count-in — §21-3 입력 눈금으로 흡수(2026-08-11) */
/* 구 .bi-pop-divider — .bi-paypop__divider 와 같아 제거(2026-08-11) */
.bi-pop-selected   { background: var(--color-info-50); }                     /* 선택된 행(구 #e4e4ff) */

/* 표 본문 — 목록이 길어지면 여기서만 스크롤한다. 레거시 팝업이 이걸
 * `style="height:245px; overflow-y:scroll"` 인라인으로 하고 있었다(2026-08-11).
 * ⚠ height 가 아니라 max-height 다 — 결과가 적을 때 빈 공간이 남지 않게. */
.bi-pop-tbl-body{ max-height: 245px; overflow-y: auto; }   /* 본문 밖의 목록도 같은 리셋 */

/* ── 38-4-C. 금액 명세 행 — 항목명 ↔ 금액 (2026-08-11 신설) ──
 * §38-4-B(선택 리스트)와 다르다: **고를 수 없는 내역**이라 hover·cursor 가 없어야 한다.
 * 결제 팝업들이 이 형태를 `float:left; width:40%` / `width:60%` 로 각자 만들고 있었다
 * (npay·card·cash·slip·pay_ref 등 32개 팝업에 float 149건).
 * 위 §38-4 주석이 "불균등이 필요하면 sg2 에 조합 modifier 를 추가한다" 고 정해 둔 그 경우다.
 * 금액칸은 기존 .bi-pop-tbl-cell--amt 를 그대로 쓴다(우측·굵게·자릿수 정렬). */
/* 항목 3열(항목명 · 단가 · 수량) — 전표 명세. 구 float 60%/20%/20% */
/* 굵게만 — 구 인라인 `padding-top:10px; font-weight:bold` 의 padding 은
 * .bi-pop-spec 이 이미 준다(10px). 굵기만 남는다(npay ×7). */
/* 구 .bi-pop-spec--bold — .bi-strong 과 같아 제거. 굵기는 .bi-strong 병기(2026-08-11) */
/* 전표 점선 구분선 — 인쇄 전표의 톱니선. 이미지가 두 종류다(위/아래) */
/* 정보 한 줄 — 라벨 ↔ 값. 구 인라인 `float:left; height:30px; padding-top:4px` +
 * 안쪽 float:left/right 조합(edit_pkg ×4). 높이만 고정하고 배치는 프리미티브가 한다. */
/* 라벨 폭 고정 정보 행 — 라벨이 130px 로 맞춰지고 값이 이어진다.
 * 구 인라인 `height:30px; padding-bottom:12px` + 안쪽 `float:left; width:130px` ×3(npay_ref). */
/* 안내 문단 — 팝업 하단의 여러 줄 주의사항. 구 인라인 `width:93%; line-height:19px; margin-top:0` ×3파일 */
.bi-pop-note{ margin: 0 0 var(--space-4); font-size: var(--pop-cnt-fs); color: var(--txt-muted); line-height: 1.6; }   /* 보드 §08 안내문 (2026-08-26) */

/* ── 38-4-B. 카드행 리스트(다중선택) ──
   행 좌측 체크박스 + 주정보/보조 2줄 + 우측 메타(금액·담당). 상품추가형. */
/* ⚠ 전역 `input[type=checkbox]{visibility:hidden;display:none}`(sprite +label 용) 때문에
   행 안의 native 체크박스가 사라진다 → §17 래퍼(.bi-checkbox-label)와 같은 방식으로 스코프 재활성.
   특이도 0,1,1 > 전역 0,0,1 이라 !important 불필요. */
.bi-pop-tbl-row input[type="checkbox"] {
    visibility: visible; display: inline-block;
    accent-color: var(--color-indigo-600);
    width: 16px; height: 16px; margin: 0; cursor: pointer; flex-shrink: 0;
}

/* ── 38-4 견본용(styleguide2 §38) ──
   styleguide2 는 자체 CSS 를 갖지 않는다 → 견본 클래스도 이 파일에 둔다.
   실제 팝업은 .bi-pop-pay 가 좌우 패딩을 주지만 견본은 셸 없이 그리므로
   본문·푸터가 자기 가로 패딩을 갖는다(.sg2doc-popfoot 의 음수마진 무효화).
   ⚠ 모듈 CSS 는 page_header() 가 common() **뒤에** 로드한다 → 같은 0,1,0 으로는
     styleguide2 쪽 .sg2doc-popbody/.sg2doc-popfoot 에 진다. 부모를 붙여 0,2,0 으로 이긴다. */
.sg2doc-popsample .sg2doc-popbody--list{
    display: flex; flex-direction: column; gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
}
.sg2doc-popsample .sg2doc-popfoot--inset{ margin: 0; padding: var(--space-3) var(--space-5); }

/* =========================================================
   §40-7 위젯 컴포넌트 — 프로모 배너 · 통계 타일 · 단순 표 · 캐러셀 (2026-08-11 편입)
   ---------------------------------------------------------
   출처: main(대시보드)이 bi-dash-* · bi-ai-banner-* · bi-perf-* 세 접두로 갖고 있던 것.
   §40-7 은 "위젯 = 카드+KPI+미니차트 조합, 재발명 금지"라고 정했고 그 조합분(카드·배지·
   아이콘버튼·카드머리·KPI)은 이미 규격 이름으로 회수했다.
   여기 남은 넷은 **조합으로 안 되는 실체**라 규격에 정식 추가한다(원칙 ⓑ):
     .bi-promo      프로모 배너 — 브랜드블루 바탕, 화면당 1개
     .bi-stat*      통계 타일 — KPI 숫자를 담는 선택 가능한 타일(.bi-statgrid 로 배치)
     .bi-simpletbl  단순 표 — 조회·정렬·페이징 없는 읽기전용 소량. 그 외는 §24 그리드
     .bi-carousel   가로 카드 캐러셀
   모듈 접두를 떼고 범용 이름으로 올린다 — reception·designer_chart 도 같은 모양을 갖고 있다.
   ⚠ 규격에 넣은 이상 styleguide2 에 전시해야 한다(QC SPEC-UNSHOWN).
   ========================================================= */
/* 프레임 = 공통 .bi-page (padding·gap·box-sizing:border-box·height 담당). 루트에서 body_all 제거로
   더 이상 padding·box-sizing 보정 불필요. 대시보드 델타 = 전체 세로 스크롤만 (2026-07-31) */
.bi-page.bi-page--scroll {
    overflow-y: auto;
    overflow-x: hidden;
}

/* ============================================================
   대시보드 (AI배너 + 2위젯 + Performance, 2026-06-15)
   토큰: gap-3=12, p-8=32, p-6=24, p-4=16, rounded-2xl=16, rounded-xl=12
         gray-200=var(--border-base), gray-100=var(--border-light), gray-50=var(--bg-input), gray-400=var(--txt-disabled)
         brand navy=var(--brand-navy) blue=var(--brand-blue) purple=var(--brand-purple), green=#00C853
   ============================================================ */

/* ---------- AI 마케팅 상단 배너 ---------- */
.bi-promo {
    position: relative;
    background: var(--brand-blue);                       /* bg-[var(--brand-blue)] */
    border-radius: var(--radius-2xl);                       /* rounded-2xl */
    padding: var(--space-8);                             /* p-8 */
    color: var(--bg-card);
    overflow: hidden;
    flex-shrink: 0;
}

/* ---------- 2 위젯 그리드 ---------- */
.bi-dashgrid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);   /* xl:grid-cols-2 */
    gap: var(--space-3);                                /* gap-3 */
}
@media (max-width: 1279px) { .bi-dashgrid { grid-template-columns: 1fr; } }

/* 2026-08-07 §40-10 프리미티브로 대체 — .bi-row: 마크업에 .bi-row 병기 */
/* 2026-08-07 공통 대체 — .bi-erp-title: 선언이 공통 .bi-erp-title 과 동일 → 마크업에 .bi-erp-title 병기 */
/* text-xs font-bold px-2 py-0.5 */
/* bg-blue-50 text-brand-blue */
/* bg-purple-50 text-brand-purple */

/* 스탯 카드 — grid-cols-3 gap-4 mb-6 */
.bi-statgrid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-4);                                 /* gap-4 */
    margin-bottom: var(--space-6);                       /* mb-6 */
}
.bi-stat {
    position: relative;
    display: flex; flex-direction: column;
    padding: var(--space-4);                             /* p-4 */
    background: var(--bg-card);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-xl);                       /* rounded-xl */
    text-align: left;
    cursor: pointer;
    overflow: hidden;
    transition: border-color .15s, box-shadow .15s;
}
.bi-stat:hover { border-color: var(--border-base); }
.bi-stat.is-active { border-color: var(--brand-blue);  }

/* 테이블 — text-sm, thead 무배경 text-xs gray-400, td py-4 */

.bi-simpletbl { width: 100%; border-collapse: collapse; font-size: var(--fs-md); text-align: left; }
.bi-simpletbl thead th {
    color: var(--txt-disabled); font-weight: var(--fw-normal); font-size: var(--fs-sm);   /* text-xs text-gray-400 font-normal */
    text-align: left; padding: var(--space-2) 0; border-bottom: 1px solid var(--border-light); white-space: nowrap;
}
.bi-simpletbl tbody td { padding: var(--space-4) 0; border-bottom: 1px solid var(--bg-input); color: var(--txt-muted); }  /* py-4 divide-gray-50 */
.bi-simpletbl tbody tr:last-child td { border-bottom: none; }
.bi-simpletbl tbody tr:hover { background: color-mix(in srgb, var(--bg-input) 50%, transparent); }
/* 구 .bi-simpletbl__r — 규격으로 흡수(2026-08-11) */
/* 보조 셀 — 구 main 의 td-svc / td-desg / td-no 셋이 같은 색 하나였다. 하나로 합친다.
   우측 정렬은 셀 종류가 아니라 배치라서 .bi-simpletbl__r 로 따로 붙인다(§40-11 방식). */
/* 빈 상태 — 구 main 은 40px 과 를 썼다. 는 모듈 CSS 와 싸우려던 흔적이라
   공통으로 올라온 지금은 필요 없고, 40px 은 여백 스케일 밖이라 --space-8(32px)로 스냅한다. */

/* ---------- Performance (디자이너 슬라이더) ---------- */
.bi-carousel {
    background: var(--bg-card);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-2xl);
    padding: var(--space-6);                             /* p-6 */
}

/* 2026-08-07 공통 대체 — .bi-erp-title: 선언이 공통 .bi-erp-title 과 동일 → 마크업에 .bi-erp-title 병기 */
.bi-carousel__viewport { overflow: hidden; }
.bi-carousel__card {
    flex: 0 0 calc((100% - 64px) / 5);         /* 5장 노출, gap 16px*4 */
    box-sizing: border-box;
    border: 1px solid var(--border-light); border-radius: var(--radius-xl); padding: var(--space-5);
    display: flex; flex-direction: column; align-items: center;
    background: var(--bg-card); cursor: pointer;
    transition: border-color .15s, box-shadow .15s;
}
.bi-carousel__card:hover { border-color: color-mix(in srgb, var(--brand-blue) 30%, transparent);  }
/* 2026-08-07 SG-RELOCATED 예외(의도적 유지)
   QC 가 공통 .bi-bs-sum-lbl--bold(POS 합계 라벨)와 같은 선언이라 지적하지만 **병합 금지** —
   대시보드 실적 수치와 POS 전표 합계는 무관하다. 굵은 본문 텍스트라 값이 겹쳤을 뿐. */

@media (max-width: 1279px) { .bi-carousel__card { flex-basis: calc((100% - 32px) / 3); } }   /* md:grid-cols-3 */
@media (max-width: 767px)  { .bi-carousel__card { flex-basis: calc((100% - 16px) / 2); } }   /* sm:grid-cols-2 */

/* =========================================================
   §21 보완 — 입력 크기·아이콘 래퍼 변형 (2026-08-11)
   ---------------------------------------------------------
   .bi-input 은 이미 좌측 36px 을 아이콘 자리로 비워두고 있고,
   그 아이콘을 놓는 기준은 .bi-search-wrap/.bi-search-icon 이다.
   검색 말고 다른 폼에서도 같은 조합이 필요해 변형 셋만 채운다(새 컴포넌트 아님).
   ========================================================= */
/* 크기 — 16(표 안 미세 입력) · 25(조회 표시칸) · 30(좁은 셀렉트) · 36(기본)
 *        · 40(터치 대상이 큰 POS) · 46(주 액션 하나뿐인 인증 화면)
 * 2026-08-11: 팝업 정리 중 .bi-pop-input-sm / __sel / -tiny-in / -count-in 처럼
 * **입력 클래스를 팝업마다 새로 만들고 있었다.** 입력은 하나이고 크기는 변형이다(§21-3 원칙).
 * 아래 눈금으로 흡수한다. 새 크기가 필요하면 여기에 추가한다. */
.bi-input--md        { height: 40px; }
/* 폭 눈금 — 고정폭이 의미 있는 자리만(표 열·조회칸·검색). 그 외는 --block 이 맞다. */
.bi-input--w80       { width: 80px; }
.bi-input--w120      { width: 120px; }
/* 테두리 없이 값만 보여주는 표시용 입력(읽기 전용) */
.bi-input--w100      { width: 100px; }
.bi-input--w220      { width: 220px; }

/* 상품 하위항목 표 — 머리와 JS 가 만드는 본문이 **같은 열 폭**을 써야 어긋나지 않는다.
 * 2026-08-11: 머리는 인라인 226/100/116/117px, 본문은 JS 인라인 220px 이었다.
 * 열 폭을 규격 한 곳에 두고 둘 다 여기서 읽는다. */
.bi-input--w70       { width: 70px; }

/* ── 잔여 반복 4차 (2026-08-11) ── */
/* ⚠ 1px 은 간격 눈금 밖이다 — 값을 맞추려는 미세 보정이라 토큰이 없다.
 * 눈금에 1px 을 추가하면 그게 간격처럼 쓰이기 시작한다. 여기만 예외로 둔다. */
/* 전표(접수증) — 인쇄를 흉내내는 좁은 문서. 글자·여백이 화면 규격과 다르다 */
/* 발송 팝업 — 좌(수신자) · 가운데(이동버튼) · 우(폰) 3단 */
/* 강조 — POS 금액칸처럼 값 자체가 주인공인 자리 */
/* 구 .bi-input--strong 2차 정의 — **배경을 더하고 있었다.** 규격에 입력 배경은 없다.
 * 강조가 배경을 바꾸면 강조가 아니라 두 번째 입력이 된다(사용자 지적 2026-08-12).
 * 굵기는 §5-1 의 정의 하나로 충분하다. */
/* 아이콘 자리 넓힘 — 기본 36px 보다 큰 아이콘을 쓸 때 */
.bi-input--icon      { padding-left: var(--space-10); }
/* §12 보완 — 큰 버튼. 인증·확인처럼 화면에 주 액션이 하나뿐인 자리에서 쓴다 */
.bi-btn--lg          { height: 48px; font-size: var(--fs-md); }

/* =========================================================
   §40-13 인증 화면 (2026-08-11 신설)
   ---------------------------------------------------------
   왜 새 절인가: 로그인은 **셸(헤더·사이드) 밖 단독 페이지**다. §40-3 표준 레이아웃
   (.bi-page > 툴바 + 필터 + 목록카드)이 성립하지 않는다 — 툴바도 그리드도 없다.
   기존 규격 어디에도 "뷰포트 한가운데 카드 하나" 형태가 없어 원칙 ⓑ 로 추가한다.

   구성은 전부 기존 규격 조합이다:
     화면  .bi-auth (뷰포트 중앙)  →  .bi-auth__wrap (폭 420)  →  .bi-erp-card (§23)
     입력  .bi-search-wrap.--full + .bi-search-icon + .bi-input.--block.--lg (§21)
     버튼  .bi-btn.bi-btn--primary.bi-btn--block (§12)
     에러  .bi-write-error (§21) · 폼 전역 에러는 .bi-auth__alert
     체크  .bi-checkbox-group / .bi-checkbox-label (§17)
   고유는 "중앙 정렬 + 브랜드 로크업 + 폼 에러 배너" 셋뿐이다.
   ⚠ 구 set_up/style.css 상단 절반은 PNG 스프라이트 체크박스·절대좌표 토글 같은 레거시를
 로 덮어쓰는 코드였다. 마크업에서 옛 클래스를 떼며 통째로 사라졌다.
   ========================================================= */
/* 화면 전체를 차지하는 건 이 클래스가 <body> 에 붙었을 때만이다.
   styleguide2 가 견본을 보여줄 때 100vh 를 먹지 않게 분리해 둔다. */

/* 폼 전역 에러 — 필드를 특정할 수 없는 서버 응답(아이디/PW 불일치 등) */
.bi-write-error.is-show { display: block; }

/* =========================================================
   §28 보완 — 드롭다운 앵커·라벨·구분선 (2026-08-11)
   규격에 목록(.bi-dropdown)과 항목만 있어서 "어디에 붙어 뜨는가"가 없었다.
   ========================================================= */

/* =========================================================
   §17-2 선택 타일 (2026-08-11 신설)
   ---------------------------------------------------------
   체크박스를 숨기고 **타일 전체를 누르는** 다중선택. 휴무설정의 디자이너 고르기와
   휴무유형 고르기가 같은 것이었고, 대기상담·디자이너차트의 프리셋도 같은 모양이다.
   상태는 §40-11 규약대로 .is-on 이 아니라 --on 이 아닌 .is-active … 로 통일하지 않고
   기존 JS 훅(.--on)을 유지한다: 마크업이 아니라 JS 가 토글하는 자리라 이름을 바꾸면 끊긴다.
   ========================================================= */
.bi-pickgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: var(--space-2_5); }
.bi-pick {
    position: relative;
    display: flex; flex-direction: column; align-items: center; gap: var(--space-1_5);
    padding: var(--space-3) var(--space-2);
    border: 1px solid var(--border-base); border-radius: var(--radius-xl);
    background: var(--bg-card); color: var(--txt-muted);
    font-size: var(--fs-sm); font-weight: var(--fw-semibold);
    cursor: pointer; text-align: center; transition: all 0.12s;
}
.bi-pick:hover { border-color: var(--gray-300); background: var(--bg-input); }
.bi-pick i { font-size: var(--fs-lg); }
.bi-pick__cb { display: none; }
/* 타일 안 아바타 — 크기·색은 §30 .bi-avatar 가 준다. 사진이 원 밖으로 나가지 않게만 덧붙인다 */
.bi-pick__nm {
    font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--txt-secondary);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
.bi-pick--on { border-color: var(--brand-blue); background: var(--color-info-50); box-shadow: 0 0 0 1px var(--brand-blue) inset; }
.bi-pick--on .bi-pick__nm { color: var(--brand-blue); }
.bi-pick--on::after {
    content: "\f00c"; font-family: "Font Awesome 5 Pro"; font-weight: var(--fw-black);
    position: absolute; top: 6px; right: 6px; width: 16px; height: 16px;
    background: var(--brand-blue); color: var(--bg-card); border-radius: var(--radius-full);
    font-size: 8px; display: flex; align-items: center; justify-content: center;
}

/* =========================================================
   §29 안내 박스 (2026-08-11 신설) — 아이콘 + 설명 한 덩어리.
   경고(§26 배지)도 에러(§21)도 아닌 "그냥 알려주는" 회색 박스. 여러 모달이 각자 만들고 있었다.
   ========================================================= */
.bi-note {
    display: flex; align-items: flex-start; gap: var(--space-2);
    background: var(--bg-input); border-radius: var(--radius-lg); padding: var(--space-3);
    font-size: var(--fs-sm); color: var(--txt-muted); line-height: 1.5;
}
.bi-note i { color: var(--txt-disabled); margin-top: var(--space-0_5); flex-shrink: 0; }

/* =========================================================
   §21-2 날짜 내비게이터 (2026-08-11 신설)
   ---------------------------------------------------------
   "◀ [날짜입력] ▶" 한 덩어리. 휴무설정·예약일정표·예약일정표(시간)가 각각
   .bi-dayoff-date-nav / .bi-datenav / .bi-bkt-daynav 로 같은 것을 만들고 있었다.
   가운데 입력은 §21 .bi-input 이 아니라 **테두리 없는 날짜 버튼**이라 별도 규격이 맞다.
   ========================================================= */
.bi-datenav {
    display: flex; align-items: center; flex-shrink: 0;
    border: 1px solid var(--border-base); border-radius: var(--radius-lg);
    background: var(--bg-card); padding: var(--space-0_5); gap: var(--space-0_5);
}
.bi-datenav__btn {
    display: flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; border-radius: var(--radius-md);
    border: none; background: transparent; color: var(--txt-muted);
    cursor: pointer; font-size: var(--fs-sm); user-select: none;
    transition: background 0.12s, color 0.12s;
}
.bi-datenav__btn:hover { background: var(--border-light); color: var(--txt-secondary); }
.bi-datenav__input {
    width: auto; min-width: 115px; height: 28px;
    border: none; border-radius: 0; background: transparent; box-shadow: none; outline: none;
    padding: 0; text-align: center; cursor: pointer;
    font-weight: var(--fw-bold); font-size: var(--fs-base); color: var(--txt-primary);
}

/* =========================================================
   §40-14 스케줄 매트릭스 (2026-08-11 신설)
   ---------------------------------------------------------
   왜 새 절인가: "열 = 사람 / 행 = 시간" 격자는 §24 그리드(dhx)로도 §40-5 차트로도
   표현되지 않는다. 휴무설정·예약일정표·예약일정표(시간) 세 화면이 각각
   .bi-dayoff-matrix-* / .bi-bk-dhead-* / .bi-bkt-grid-* 로 **같은 것을 세 번** 만들고 있었다.

   구조:
     .bi-schmx                가로 스크롤 판 (열이 inline-block 이라 nowrap)
       .bi-schmx__col           열 하나 = 사람 하나 (184)
       .bi-schmx__col--time     첫 열 = 시간 라벨 (90, 좌측 고정)
         .bi-schmx__head        열 머리 (152, 상단 고정) — 아바타·이름·직책·⋯
         .bi-schmx__row         시간 행 (48)
           .bi-schmx__slot      행 안의 색 블록 (상태별)
             .bi-schmx__count   그 칸의 예약 수

   ⚠ 슬롯 상태를 :has(아이콘)으로 읽는다. 레거시 JS 가 체크박스 아이콘으로 상태를 그리기
     때문이며, CLAUDE.md §7 "input 값 신뢰 ❌ → 렌더된 DOM 에서 상태 파싱"과 같은 이유다.
     JS 를 고쳐 --open/--closed 를 직접 붙이게 되면 이 :has 규칙은 지운다.
   ========================================================= */

.bi-schmx__col {
    display: inline-block; vertical-align: top; width: 184px;
    box-sizing: border-box; border-right: 1px dashed var(--border-light);
}
.bi-schmx__name {
    display: block; font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-primary);
    line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 172px;
}
.bi-schmx__role {
    display: block; font-size: var(--fs-2xs); font-weight: var(--fw-medium); color: var(--txt-muted);
    line-height: 1.2; margin-top: calc(var(--space-0_5) * -1);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 172px;
}

.bi-schmx__slot {
    height: 100%; border-radius: var(--radius-md);
    display: flex; align-items: center; justify-content: center; gap: var(--space-1);
    cursor: pointer; transition: all 0.12s; border: 1px solid transparent;
}
.bi-schmx__count { font-size: var(--fs-2xs); font-family: var(--font-mono, monospace); font-weight: var(--fw-bold); margin: 0; line-height: 1; }
.bi-schmx__mark  { display: none; }

/* 열림 */
.bi-schmx__slot:has(i.fa-check-square) {
    background: color-mix(in srgb, var(--brand-blue) 5%, transparent);
    border-color: color-mix(in srgb, var(--brand-blue) 25%, transparent);
}
.bi-schmx__slot:has(i.fa-check-square):hover { background: color-mix(in srgb, var(--brand-blue) 15%, transparent); }
.bi-schmx__slot:has(i.fa-check-square) .bi-schmx__count { color: var(--txt-disabled); }
/* 닫힘(휴무) — X 표시 */
.bi-schmx__slot:has(i.fa-square) { background: var(--border-light); border-color: var(--border-base); }
.bi-schmx__slot:has(i.fa-square):hover { background: var(--gray-200); }
.bi-schmx__slot:has(i.fa-square) .bi-schmx__count { color: var(--txt-disabled); }
.bi-schmx__slot:has(i.fa-square):not(.bi-schmx__slot--booked)::before {
    content: "\f00d"; font-family: "Font Awesome 5 Pro"; font-weight: var(--fw-black);
    font-size: var(--fs-xs); color: var(--txt-disabled); line-height: 1;
}

/* =========================================================
   §26-2 칩 — 고른 값을 되짚어 보여주는 조각 (2026-08-11 신설)
   ---------------------------------------------------------
   "선택된 조건", "적용된 필터"처럼 **고른 값을 나열**하는 조각.
   §26 배지(.bi-badge)는 상태를 알리는 읽기 전용이고, 칩은 **누를 수 있고 지울 수 있다** — 다른 것이다.
   AI 메시지 발송(.bi-aim-filter-chip) · 팝업(.bi-pop-chip) · 대기상담(tag/qchip)이
   각자 만들고 있던 것을 하나로 회수한다.
   ========================================================= */
.bi-chip {
    display: inline-flex; align-items: center;
    padding: var(--space-1_5) var(--space-3);
    border-radius: var(--radius-full);
    background: var(--bg-card); border: 1px solid var(--color-indigo-200);
    color: var(--brand-blue);
    font-size: var(--fs-sm); font-weight: var(--fw-medium);
    cursor: pointer; user-select: none; transition: all .15s;
}
.bi-chip:hover { border-color: var(--brand-blue); }
/* 아직 고르지 않은 후보 — 네모난 태그형. 고르면 .is-selected */
.bi-chip--opt {
    border-radius: var(--radius-lg); border-color: var(--border-base); color: var(--gray-600);
    box-shadow: none; text-align: center; white-space: nowrap;
}
.bi-chip--opt:hover { background: var(--bg-input); border-color: var(--gray-300); }
.bi-chip--opt.is-selected {
    background: var(--brand-blue-light); border-color: var(--brand-blue); color: var(--brand-blue);
}

/* =========================================================
   §26-3 카운트 필 — "선택 12 · 전체 340" (2026-08-11 신설)
   ⚠ §40-7-1 .bi-stat(KPI 타일)과 합치지 않는다. 저건 대시보드 위젯 안의 큰 숫자이고
     이건 표 머리 옆에 붙는 작은 필이다 — 크기도 역할도 다르다.
   ========================================================= */
.bi-countpill {
    display: inline-flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    background: var(--gray-50); border-radius: var(--radius-2xl);
    font-size: var(--fs-md); font-weight: var(--fw-semibold);
}

/* =========================================================
   §24-2 선택형 데이터 표 (2026-08-11 신설)
   ---------------------------------------------------------
   dhx 그리드(§24)가 아닌 순수 <table> 인데 **체크박스 열 · 행 hover · 행 선택**이 있는 표.
   §40-7-1 .bi-simpletbl(읽기전용 소량)로는 부족해서 별도 규격으로 둔다.
   행 사이를 띄우고 모서리를 둥글리는 "카드형 행" 방식.
   ⚠ 구 ai_marketing 은 "td: nth-child(3)" "tr: hover" 처럼 **콜론 뒤에 공백**이 들어가
     6개 셀렉터가 무효였다(브라우저가 파싱을 포기). 옮기면서 바로잡았다.
   ========================================================= */
.bi-datatbl { width: 100%; border-collapse: separate; border-spacing: 0 8px; }
.bi-datatbl thead th {
    text-align: left; font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--txt-muted);
    padding: var(--space-3) var(--space-4); background: var(--bg-input);
    border-top: 1px solid var(--border-light); border-bottom: 1px solid var(--border-light);
    white-space: nowrap;
}
.bi-datatbl tbody tr { transition: background .2s; cursor: pointer; }
.bi-datatbl tbody tr:hover { background: color-mix(in srgb, var(--brand-blue) 5%, transparent); }
.bi-datatbl tbody tr.is-active { background: color-mix(in srgb, var(--brand-blue) 5%, transparent); }
.bi-datatbl tbody td {
    padding: var(--space-1_5) var(--space-4); font-size: var(--fs-md);
    vertical-align: middle; background: var(--gray-50);
}
.bi-datatbl tbody tr td:first-child { text-align: center; border-top-left-radius: var(--radius-xl); border-bottom-left-radius: var(--radius-xl); }
.bi-datatbl tbody tr td:last-child  { border-top-right-radius: var(--radius-xl); border-bottom-right-radius: var(--radius-xl); }
/* 행을 펼쳐 상세를 보여주는 줄 */
.bi-datatbl__more { display: none; }
.bi-datatbl__more.is-shown { display: table-row; }

/* =========================================================
   §40-16 캠페인 발송 화면 (2026-08-11 신설)
   ---------------------------------------------------------
   왜 새 절인가: "조건을 좁혀 대상을 고르고 → 메시지를 만들어 → 보낸다"는 흐름은
   §40-3 표준 목록(툴바+필터+그리드)도 §40-4 예외 레이아웃도 아니다.
   좌측 조건 패널 · 우측 대상 표 · 메시지 미리보기 세 덩어리가 한 화면에 있다.

   안쪽은 전부 기존 규격 조합이다 — 카드 §23 · 버튼 §12 · 체크박스 §17 · 칩 §26-2
   · 카운트 필 §26-3 · 표 §24-2 · 레이아웃 §40-10.
   고유는 **접이식 조건 패널**과 **메시지 미리보기** 둘뿐이다.
   ⚠ 상태 이름은 규격 관례대로 .is-open 을 쓴다(구 .is-collapsed 는 뒤집힌 의미라 헷갈렸다).
   ========================================================= */

/* 접이식 조건 패널 */
.bi-fpanel            { border-radius: var(--radius-lg); overflow: hidden; transition: all .3s; }
.bi-fpanel__title {
    display: flex; align-items: center; cursor: pointer;
    font-size: var(--fs-md); font-weight: var(--fw-semibold); color: var(--gray-800);
    padding-bottom: var(--space-4); padding-right: var(--space-4);
}
.bi-fpanel__title.is-disabled { cursor: not-allowed; }
.bi-fpanel__title i   { margin-left: var(--space-1); font-size: var(--fs-base); vertical-align: middle; }
.bi-fpanel__body      { display: none; flex-direction: column; gap: var(--space-4); padding: 0 var(--space-5); }
.bi-fpanel__body.is-open { display: flex; }
.bi-fpanel__body.is-disabled { cursor: not-allowed; }

/* 조건 묶음 한 줄 */
.bi-fcat        { transition: border-color .3s; }

/* 메시지 미리보기 — setting_sms 의 폰 목업과 한 쌍(그 배치에서 합류) */
.bi-msgprev--empty     { color: var(--color-danger-600); font-weight: var(--fw-semibold); }

/* §17 보완 — 전역 PNG 체크박스를 끄고 네이티브로 (2026-08-11)
   lib/css/style.css 전역이 "input[type=checkbox]{visibility:hidden;display:none}" + "+label" PNG 박스라,
   네이티브 체크박스를 쓰려는 화면마다 그걸 무력화하는 코드를 각자 갖고 있었다. 규격으로 회수한다.
   ⚠ "+label" 은 PNG 박스 전용이라 숨긴다 — 숨기지 않으면 박스가 두 개로 보인다.
     label 자체는 JS 가 for 재지정에 쓰므로 DOM 에서 빼지 않는다. */

/* §12 보완 — 재생성 계열 액센트(indigo) · 비활성 */
.bi-btn.is-disabled   { opacity: .6; background: var(--gray-200); color: var(--gray-950); cursor: not-allowed; }
.bi-btn--primary.is-disabled { background: var(--txt-disabled); color: var(--bg-card); opacity: 1; }

/* ── 발송대상 체크박스 — styleguide §5 네이티브 체크박스로 통일 (2026-07-23) ──────────
   lib/css/style.css 의 전역 `input[type=checkbox]{visibility:hidden;display:none}` +
   `+label` PNG 박스(checkbox_none.png/checkbox.png)가 적용돼 구형 이미지 체크박스로 보이던 문제.
   전역 규칙을 무력화하고 accent-color 네이티브 체크박스로 표시한다.
   (동일 패턴: lib/css/style.css(구 popup.css) §결제팝업 `.bi-pop-pay .bi-pop-opt input[type=checkbox]`)
   ⚠ `+label` 은 PNG 박스 전용이라 숨긴다 — 숨기지 않으면 박스가 2개로 보인다.
      label 자체는 script.js 의 clone/for 재지정 로직이 참조하므로 DOM 에서 제거하지 않는다. */

/* 2026-08-07 §40-10 프리미티브로 대체 — .bi-datatbl__more-head: 마크업 사용처 0 — 죽은 CSS */

.bi-datatbl__name {
    font-weight: var(--fw-semibold);
}

/* ── 타겟팅 조건 카드 ───────────────────────────── */

/* 카테고리 그리드 */
/* 기본 조건(항상 표시) / 선택칩 / 상세 토글 간격 */

/* 기본(빠른) 조건 — 카테고리를 한 줄(가로 일렬)로 나란히 */

/* ── 반응형: 1100px 이하 1단 ───────────────────── */
@media (max-width: 1100px) {

}

/* =========================================================
   §40-17 작업 데스크 (2026-08-11 신설)
   ---------------------------------------------------------
   왜 새 절인가: "왼쪽에서 사람을 고르고 → 가운데서 내용을 채우고 → 오른쪽에서 담아 넘긴다"는
   3열 작업 화면은 §40-3 표준 목록도 §40-4 예외 레이아웃도 아니다.
   Step1 대기/상담(reception)과 Step2 디자이너 차트(designer_chart)가 **같은 구조**라,
   모듈 이름이 아니라 역할 이름(desk)으로 올린다 — B4 에서 Step2 가 그대로 쓴다.

   안쪽은 기존 규격 조합이다 — 카드 §23 · 버튼/세그먼트 §12 · 선택 타일 §17-2 · 배지 §26
   · 칩 §26-2 · 아바타 §30 · 토스트 §32 · 레이아웃 §40-10 · 빈 상태 §14.
   고유는 셋 — 3열 격자(.bi-desk) · 대기 큐 행(.bi-queue) · 장바구니(.bi-basket).
   ⚠ 구 reception 은 --rc-navy 같은 **로컬 토큰 별칭**을 두고 있었다(전역 토큰을 그대로 가리킴).
     이름만 하나 더 만드는 셈이라 전부 전역 토큰으로 되돌렸다.
   ========================================================= */
/* style.css(구 pos_console.css)(공통 스킨)는 function.php 가 filemtime ?v 로 전역 로드 (docs/73) */
/* ===== 토큰 (wrapper 로컬) ===== */
/* 프레임 = 공통 .bi-page (list.php 루트에 bi-page 추가). display/flex/height/box-sizing/padding/gap/background 공통 담당.
   여기선 rc 토큰·폰트·색 + 전체 세로 스크롤(공통 overflow:hidden 델타)만 (2026-07-31) */

/* FA 보호는 위 §.bi-page 스코프 규칙이 이미 한다(.bi-page i.fa/fas/fal/far/fab).
   구 reception 이 갖고 있던 wrap-스코프 사본은 제거 — 같은 일을 두 번 하지 않는다.
   ⚠ 2026-08-11: 이관 중 다중 셀렉터 규칙의 **마지막 줄만** 지워져 선택자 목록이 다음 규칙과
     붙어버린 사고가 있었다(brace 는 균형이라 검출 안 됨). 다중 셀렉터는 통째로 다룬다. */

/* 모달 portal 컨테이너 — body 직속, 상위 stacking context 탈출(오버레이가 사이드까지 전체 덮음).
   레이아웃(height/overflow/padding)은 재선언하지 않는다. */
#reception_portal { font-family: var(--font-sans); }
#reception_portal *, #reception_portal *::before, #reception_portal *::after { box-sizing: border-box; }
#reception_portal i.fa, #reception_portal i.fas, #reception_portal i.far, #reception_portal i.fal { font-family: 'Font Awesome 5 Pro' !important; }
@keyframes bi-pulse { 0%,100% { opacity: 1; } 50% { opacity: .45; } }

/* ===== 3컬럼 그리드 ===== */
.bi-desk {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-4);   /* 패널 간격 공통 16px 통일 (구 12px) (2026-07-31) */
    /* 2026-07-23 Step2(designer_chart) 와 컨텐츠(카드) 높이 통일 — wrap(calc(100vh-64px)) 을 채우도록 height:100%.
       기존 calc(100vh-150px)+min 760px 이라 Step2 보다 짧았음. */
    height: 100%;
    min-height: 0;
    align-items: stretch;
}

/* 과거 방문 이력 라벨 — 14px / font-weight 900 / uppercase / letter-spacing .1em */
#reception_hist_title { font-size: var(--fs-md); font-weight: var(--fw-black); color: var(--txt-disabled); letter-spacing: .1em; }

/* ===== COL1 : 검색 카드 ===== */
/* 탭+검색 영역 — 회색 박스 제거, 흰 배경 + 요소 분리 */
.bi-desk__panel-body { display: flex; flex-direction: column; background: var(--bg-card); flex-shrink: 0; }

/* ===== 목록 / 행 ===== */
.bi-queue__list { flex: 1; overflow-y: auto; }

.bi-queue__row { padding: var(--space-3); cursor: pointer; display: flex; flex-direction: column; gap: var(--space-1_5); border-left: 4px solid transparent; border-bottom: 1px solid var(--border-light); transition: background .15s; }
.bi-queue__row:hover { background: var(--bg-input); }
.bi-queue__row.is-active { background: color-mix(in srgb, var(--brand-blue) 5%, transparent); border-left-color: var(--brand-blue); }
/* 2026-08-07 §40-10 프리미티브로 대체 — .bi-queue__r1: 마크업에 .bi-row-between 병기 */
.bi-queue__name { font-weight: var(--fw-extrabold); color: var(--txt-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: var(--fs-base); }
.bi-queue__row.is-active .bi-queue__name { color: var(--brand-blue); }
.bi-queue__sub { font-size: var(--fs-xs); color: var(--txt-disabled); font-weight: var(--fw-semibold); white-space: nowrap; }
.bi-queue__r2 { display: flex; justify-content: space-between; align-items: center; padding-top: var(--space-1); border-top: 1px dashed var(--border-light); }
.bi-queue__badges { display: flex; flex-wrap: wrap; gap: var(--space-1); align-items: center; min-width: 0; }
/* .bi-queue__emp → 공통 style.css(구 pos_console.css) 그룹 이관 (dchart 동일) (2026-08-03) */
.bi-queue__r3 { display: flex; justify-content: space-between; align-items: center; padding-top: var(--space-1); border-top: 1px dashed var(--border-light); }
.bi-queue__chart { font-size: var(--fs-xs); color: var(--txt-disabled); font-family: monospace; font-weight: var(--fw-semibold); }

/* tone 매핑 */

.bi-desk__sec { padding-top: var(--space-3); border-top: 1px dashed var(--gray-100); display: flex; flex-direction: column; gap: var(--space-2); }
/* 2026-08-07 §40-10 프리미티브로 대체 — .bi-write-card__header: 마크업에 .bi-row-between 병기 */

/* ===== COL2 : 방문이력 / 상담 ===== */
/* ⚠ 한 이름에 규격이 둘이었다 — COL1(스크롤·여백 14)과 COL2(여백 0·hidden)가 같은 이름을 써서
 *   뒤엣것이 이기고 COL1 패널(#reception_guide)이 **잘려** 있었다(안 313 > 칸 293, 2026-08-14).
 *   규격은 하나다 — 여백 0 은 그대로 두고, 넘치면 **잘리지 말고 스크롤**하게 한다. */
.bi-desk__panel-body { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 0; padding: 0; overflow-y: auto; }

/* 2026-08-07 §40-10 프리미티브로 대체 — .bi-write-card__header: 마크업에 .bi-row-between 병기 */
/* height: 전역 textarea{height:25px}(style.css:377) 무력화 — rows=4 / text-sm / leading-relaxed 기준 4행 높이 */

/* ===== COL3 : 선택판 ===== */
/* 캡슐형 세그먼트 — 트랙(컨테이너)을 흰 카드보다 한 단계 어둡게(gray-200) → 비활성 탭이 회색 버튼으로 보임 */
/* 간격: 트랙 p-0.5(2px) + gap-1(4px) + rounded-lg(8px), 버튼 py-1.5(6px) + rounded-md(6px) */
/* 배치만 — 룩은 공통 .bi-segment--fill */
.bi-desk__rpanel { flex: 1; overflow-y: auto; padding: var(--space-4); background: color-mix(in srgb, var(--bg-input) 40%, transparent); display: flex; flex-direction: column; gap: var(--space-2); min-height: 0; }

.bi-pick__l p { font-weight: var(--fw-extrabold); color: var(--txt-primary); margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: var(--fs-base); }
.bi-pick__l span { font-size: var(--fs-xs); color: var(--txt-disabled); font-family: monospace; font-weight: var(--fw-bold); text-transform: uppercase; }
.bi-pick__r i { color: var(--brand-blue); }

/* 보유 패키지/선불권 탭: 두 섹션(선불권·패키지 정보) 공통 구조 — subtitle 라벨 + 내용 카드 */
/* 2026-08-07 §40-10: .bi-desk__membersec — 마크업에 .bi-col 병기 */
/* 보유 선불권별 목록 */
.bi-desk__ticket-exp { font-size: var(--fs-xs); background: var(--color-indigo-50); color: var(--color-indigo-700); border: 1px solid var(--color-indigo-100); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm); font-family: monospace; display: inline-block; margin-bottom: var(--space-1); font-weight: var(--fw-bold); }
.bi-desk__ticket-btn:hover { background: var(--gray-900); }

/* ===== 바스켓 / 접수 ===== */
.bi-basket__area { padding: var(--space-4); background: color-mix(in srgb, var(--color-indigo-50) 20%, transparent); border-top: 1px solid var(--color-indigo-100); display: flex; flex-direction: column; gap: var(--space-3); flex-shrink: 0; }
.bi-basket__head { display: flex; justify-content: space-between; align-items: center; padding-bottom: var(--space-1); border-bottom: 1px solid var(--color-indigo-50); }
.bi-basket__total { font-size: var(--fs-lg); font-weight: var(--fw-extrabold); color: var(--color-indigo-800); }
.bi-basket { display: flex; flex-direction: column; gap: var(--space-1_5); max-height: 140px; overflow-y: auto; padding-right: var(--space-1); }
.bi-basket__empty { padding: var(--space-4); text-align: center; font-size: var(--fs-base); color: var(--txt-disabled); font-weight: var(--fw-bold); font-style: italic; }
.bi-basket__row { display: flex; justify-content: space-between; align-items: center; background: var(--bg-card); border: 1px solid var(--color-indigo-100); padding: var(--space-2); border-radius: var(--radius-xl);  }
.bi-basket__row p { font-weight: var(--fw-bold); color: var(--gray-800); margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-right: var(--space-2); font-size: var(--fs-base); }
/* 2026-08-07 §40-10: .bi-basket__row-r — 마크업에 .bi-row .bi-row--shrink-0 병기 */
/* 높이를 안 정하면 padding+아이콘이 높이를 만든다(24px) — 사다리 xs 22 로 고정(§12-4, 2026-08-14) */
.bi-basket__del { width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; border: 0; background: none; color: var(--txt-disabled); cursor: pointer; padding: 0; border-radius: var(--radius-lg); }
.bi-basket__del:hover { color: var(--color-rose-500); background: var(--border-light); }

/* ===== 접수 완료 배너 ===== */
/* 2026-07-23 빈 배너가 wrap 의 flex-gap(12px) 슬롯을 차지해 그리드가 12px 밀려내려가던 문제 — 비었을 때 숨김(헤더~카드 간격을 buysell 등과 동일하게) */
#reception_banner:empty { display: none; }
/* 2026-08-07 §40-10: .bi-deskbar__txt — 마크업에 .bi-col .bi-col--gap-6 병기 */

/* ===== 반응형 (1280 / 1024) ===== */
@media (max-width: 1280px) {

    .bi-desk { gap: var(--space-2_5); height: calc(100vh - 140px); }

}
@media (max-width: 1024px) {
    .bi-desk { min-height: 700px; }
    .bi-queue__name { font-size: var(--fs-sm); }
    .bi-pick__l p { font-size: var(--fs-sm); }
}

/* =========================================================
   §40-17-1 차팅 데스크 부속 — 갤러리 · 라이트박스 · 시술 타임라인 (2026-08-11)
   ---------------------------------------------------------
   Step2 디자이너 차트(designer_chart)를 §40-17 작업 데스크에 합류시키며 남은 것.
   모듈 CSS 주석이 스스로 "reception 동일 패턴"이라 적고 있었고 실제로 대기 큐·장바구니
   ·프리셋·티켓·회원섹션이 선언까지 같았다 → 한 벌만 남기고 나머지는 지웠다.
   여기 남은 셋은 Step2 에만 있는 것이라 데스크 부속으로 올린다.
   ⚠ 구 designer_chart 도 --dc-navy 같은 로컬 토큰 별칭을 두고 있었다(reception 의 --rc-* 와 같은 문제).
     전부 전역 토큰으로 되돌렸다.
   ========================================================= */
/* style.css(구 pos_console.css)(공통 스킨)는 function.php 가 filemtime ?v 로 전역 로드 (docs/73) */

.bi-page--scroll i.fa, .bi-page--scroll i.fas, .bi-page--scroll i.far, .bi-page--scroll i.fal {
    font-family: 'Font Awesome 5 Pro'; font-weight: var(--fw-black);
}

/* ===== 그리드 3컬럼 ===== */

/* ⚠ .bi-desk__col 도 정의가 둘이었다(게다가 셀렉터가 제 이름을 두 번 썼다).
 *   뒤엣것이 gap·height 를 지우고 overflow:hidden 을 줘서, designer_chart 3열의 내용이
 *   **잘려 닿을 수 없었다**(안 1185 > 칸 749, 2026-08-14). 하나로 합치고 넘치면 스크롤한다.
 *   테두리·둥글기는 셸 안에서 §40-2 규칙이 다시 걷어낸다(상자 안 상자 금지). */
.bi-desk__col { display: flex; flex-direction: column; gap: var(--space-3); height: 100%; min-height: 0; background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-xl); overflow-y: auto; }

/* 2026-08-07 §40-10 프리미티브로 대체 — .bi-row-between: 마크업에 .bi-row-between 병기 */

/* 색/모양 = 공통 .bi-badge--success/--warning/--info/--neutral (JS 지정). 델타: 줄어들지 않게 + 원래 폰트크기 (2026-07-31) */

.bi-queue__r2, .bi-queue__r3 { display: flex; justify-content: space-between; align-items: center; gap: var(--space-1_5); padding-top: var(--space-1); border-top: 1px dashed var(--gray-100); }

/* 재방주기 박스 → 공용 .bi-cyclebox/.bi-write-grid-2 (style.css(구 pos_console.css)) 통합, JS 도 사용(2026-07-31). */

@keyframes sdpDchartPulse { 0%,100% { opacity: 1; } 50% { opacity: .55; } }/* .bi-row → 공통 style.css(구 pos_console.css) 그룹 이관 (reception charting 동일) (2026-08-03) */
.bi-desk__chart-title i { color: var(--brand-blue); margin-right: var(--space-0_5); }

/* ===== Col2 Left: 기록 ===== */
/* 2026-08-07 §40-10 프리미티브로 대체 — .bi-desk__field: 마크업에 .bi-col .bi-col--gap-5 병기 */
/* 2026-08-07 §40-10: .bi-dot — 마크업에 공통 .bi-dot 병기 */
/* ⚠️ 전역 textarea{height:25px} 차단 */

/* 2026-08-07 §40-10 프리미티브로 대체 — .bi-gallery__head: 마크업에 .bi-row-between 병기 */
/* 2026-08-07 §40-10 프리미티브로 대체 — .bi-gallery__boxhead: 마크업에 .bi-row-between 병기 */
.bi-gallery__thumb { position: relative; aspect-ratio: 1/1; border-radius: var(--radius-md); overflow: hidden; border: 1px solid var(--border-base); background: var(--bg-card); cursor: pointer; transition: border-color .15s, box-shadow .15s; }
.bi-gallery__thumb:hover {  }
.bi-gallery__del { position: absolute; top: 3px; right: 3px; width: 18px; height: 18px; padding: 0; border: 0; border-radius: 50%; background: color-mix(in srgb, var(--black) 60%, transparent); color: var(--bg-card); font-size: var(--fs-2xs); line-height: 1; display: none; align-items: center; justify-content: center; cursor: pointer; }
.bi-gallery__thumb:hover .bi-gallery__del { display: inline-flex; }
.bi-gallery__del:hover { background: var(--color-danger-600); }
/* 2026-08-07 §40-10: .bi-gallery__thumb img — 마크업에 공통 .bi-img-cover 부여 */

/* ===== Col2 Right: 타임라인 ===== */
.bi-timeline__tl { position: relative; padding-left: var(--space-5); cursor: pointer; }

/* 상위/하위 2단 분류 스킨(rpanel__lbl·presetgrp·maintabs·maintab·subgrp·cats·catbtn·cats__empty·presetlist) → lib/css/style.css(구 pos_console.css) 통합(reception 공통) */
/* 과거 전표 클릭 시 이동 대상 카드/티켓 강조(약 1.6초) */
/* 프리셋 카드 — reception 컴팩트 톤(좌:상품명+카테고리 / 우:가격+아이콘). 선택 시 ✓ 표시 */

.bi-pick__r i { font-size: var(--fs-sm); }

/* 보유 패키지/선불권 탭: 두 섹션(선불권·패키지) 공통 — rpanel__lbl 라벨 + 카드 목록 (reception 동일 패턴) */

.bi-desk__ticket-exp { font-size: var(--fs-xs); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm); border: 1px solid color-mix(in srgb, var(--brand-blue) 20%, transparent); background: color-mix(in srgb, var(--brand-blue) 5%, transparent); color: var(--brand-blue); font-weight: var(--fw-bold); }
/* 2026-08-07 SG-RELOCATED 예외(의도적 유지)
   QC 가 공통 .bi-counter-catbadge.is-retail 과 같은 선언이라 지적하지만 **병합 금지** —
   '만료임박 경고'와 '소매 분류 배지'는 역할이 다르다. rose 색 조합이 우연히 같을 뿐. */
.bi-desk__ticket-exp.is-crit { background: var(--color-rose-50); color: var(--color-rose-600); border-color: var(--color-rose-200); }
.bi-desk__ticket-exp.is-done { background: var(--color-danger-100); color: var(--color-danger-600); border-color: var(--color-danger-200); font-weight: var(--fw-black); }
/* 티켓 진행바 fill 기본 → 공용 그룹(style.css(구 pos_console.css)). is-crit 상태만 dchart 유지 */
.bi-desk__ticket-bar > div.is-crit { background: var(--color-danger); }
.bi-desk__ticket-btn:hover { background: var(--brand-blue-hover); }
.bi-desk__ticket-btn:disabled { background: var(--border-light); color: var(--txt-muted); cursor: not-allowed; }

/* 결제 모달 */
/*   (팝업 CSS 는 style.css(구 popup.css) 로 일원화 — styleguide2 §38). 나머지 .bi-paypop__* 는 여기 유지. */
/* 바스켓 수량 스텝퍼 (하이브리드: 프리셋 클릭 +1, 여기서 ± 직접 조정) */
/* 수량 스테퍼 */
.bi-basket__qbtn { width: 22px; height: 22px;   /* §12-4 사다리 xs 22 */ line-height: 1; padding: 0; border: 1px solid transparent; background: transparent; color: var(--txt-secondary); border-radius: var(--radius-md); font-size: var(--fs-sm); font-weight: var(--fw-black); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: background .12s, color .12s, border-color .12s; }
.bi-basket__qbtn:hover { background: var(--bg-card); color: var(--gray-800); border-color: color-mix(in srgb, var(--border-base) 50%, transparent);  }
/* 카운트 = 키보드 직접수정 input(유지). 평소엔 보더 없이 mono 텍스트처럼, 포커스 시에만 보더 */
input[type="text"].bi-basket__qn { width: 26px; height: 20px; text-align: center; font-size: var(--fs-xs); font-weight: var(--fw-black); font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; color: var(--gray-950); border: 1px solid transparent; border-radius: var(--radius-md); padding: 0 var(--space-0_5); box-sizing: border-box; outline: none; background: transparent; }
input[type="text"].bi-basket__qn:focus { border-color: var(--brand-blue); background: var(--bg-card); }

/* ===== 반응형 ===== */

@media (max-width: 1280px) {
    .bi-desk__chart-title { font-size: var(--fs-base); }
}
@media (max-width: 1024px) {

}

/* 카탈로그 모달 portal 컨테이너 — body 직속, 상위 stacking context 탈출용(미디어쿼리 사이드메뉴 가림 방지).
   wrap-스코프 의존(변수·폰트·FA)만 재선언, height/overflow/padding 은 제외(레이아웃 영향 0) */
#dchart_portal {
      
}
#dchart_portal i.fa, #dchart_portal i.fas, #dchart_portal i.far, #dchart_portal i.fal {
    font-family: 'Font Awesome 5 Pro'; font-weight: var(--fw-black);
}

/* =========================================================
   §40-18 미니 캘린더 · §40-19 예약 카드와 상태 (2026-08-11 신설)
   ---------------------------------------------------------
   예약일정표(booking_renew)와 예약일정표(시간)(booking_time)이 **같은 캘린더·같은 예약 카드**를
   각각 bi-bk-cal-* / bi-bt-cal-* 로 만들고 있었다. 역할 이름으로 한 벌만 남긴다.

   .bi-cal*      좌측 사이드의 월 달력(28px 칸 · 일/토 색 · 예약 있는 날 점)
   .bi-resv*     시간표 위에 얹히는 예약 블록. 상태 6종은 §3 상태색을 쓴다
                  (요청·확정·체크인·완료·취소·블록). **색만으로 구분하지 않는다** —
                  좌측 점(.bi-resv-dot--*)과 범례 스위치(.bi-resv-sw--*)가 함께 붙는다.
   .bi-bksplit*  좌(사이드) + 우(시간표) 2단 프레임. 시간표 자체는 §40-14 스케줄 매트릭스.
   ⚠ 새 색을 만들지 않는다. 상태색은 §3 팔레트에서 고른다.
   ========================================================= */
/* 둥근 아이콘 버튼(등록 +) — §12 .bi-btn--icon 에 라운드만 얹는다 */
/* 예약 상태 6종 중 취소·범례 힌트·시간표 본문 — 마크업만 있고 규격에 빠져 있던 조각 */
/* 검색어 지우기 × — §21 .bi-search-wrap 안 우측 */
/* ── 페이지 컨테이너 ─────────────────────────────────────────────── */

/* ── 상단 서브바 — booking_renew 와 동일(bi-bk-subbar / bi-bk-legend) ── */

@media (max-width: 1280px) { .bi-page .bi-bk-legend--subbar { gap: var(--space-2_5); } .bi-page .bi-bk-legend--subbar .bi-bk-legend-item { font-size: var(--fs-2xs); } }

/* ── 본문 레이아웃 ───────────────────────────────────────────────── */
.bi-bksplit { flex: 1; display: flex; gap: var(--space-4); min-height: 0; }
/* 우측열 = 공통 .bi-bk-rightcol(style.css(구 booking_schedule.css), booking_renew 와 공유). booking_time 은 본문 높이 채우고 넘치면 내부 스크롤(booking_renew 는 JS 로 height 지정) (2026-07-31) */
.bi-bksplit > .bi-bk-rightcol { align-self: stretch; overflow-y: auto; overflow-x: hidden; padding-right: var(--space-0_5); }

/* ── 좌 1B: 캘린더 ─────────────────────────────────────────────── */
/* .bi-cal__head · __label · __today 제거(2026-09-11)
   — 두 예약 화면이 .bi-bk2-cal__hd / __ym / __today 로 옮겼다. 쓰는 곳이 없다. */
/* §29-2 칩 = 28. 실측 18 이라 캘린더 헤더(46) 안에서 혼자 작았다(2026-08-21). */
.bi-cal__nav { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-2_5); padding: 0 var(--space-1); }
.bi-cal__navbtn { border: none; background: none; color: var(--txt-disabled); cursor: pointer; padding: var(--space-1); border-radius: var(--radius-lg); font-size: var(--fs-base); }
.bi-cal__navbtn:hover { background: var(--border-light); color: var(--txt-secondary); }
.bi-cal__title { font-size: var(--fs-sm); font-weight: var(--fw-black); color: var(--gray-800); }
.bi-cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--space-1); }
.bi-cal__day {
    position: relative; height: 28px; border: none; background: none; border-radius: var(--radius-lg);
    font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--txt-secondary); cursor: pointer;
    display: flex; align-items: center; justify-content: center; transition: all .12s;
}
.bi-cal__day:hover { background: var(--border-light); }.bi-cal__day.is-sel { background: var(--brand-blue, var(--brand-blue)); color: var(--bg-card); font-weight: var(--fw-extrabold);  }

/* 2026-08-07 §40-10 프리미티브로 대체 — .bi-bt-main-head-left: 마크업에 .bi-row .bi-row--gap-12 병기 */
/* 2026-08-07 §40-10 프리미티브로 대체 — .bi-bt-daynav: 마크업에 .bi-row 병기 */

.bi-datenav__input { min-width: 90px; text-align: center; font-size: var(--fs-sm); font-weight: var(--fw-black); color: var(--gray-800); background: var(--bg-input); border: 1px solid var(--gray-100); border-radius: var(--radius-lg); padding: var(--space-1) var(--space-2_5); }

/* ── 타임라인 그리드 (디자이너 행 세로 × 시간 열 가로) ───────────────
   열 고정폭: 디자이너 150px + 시간 104px (script.js BT_DNAME_W/BT_COL_W 와 일치) */

.bi-schmx__thcell { flex: 0 0 104px; width: 104px; display: flex; align-items: center; justify-content: center; border-right: 1px solid var(--gray-100); border-bottom: 1px solid var(--gray-100); font-family: ui-monospace, monospace; font-size: var(--fs-xs); font-weight: var(--fw-extrabold); color: var(--txt-muted); background: color-mix(in srgb, var(--bg-input) 50%, transparent); }

.bi-schmx__name { font-size: var(--fs-sm); font-weight: var(--fw-black); color: var(--txt-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-schmx__role { font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--txt-disabled); margin-top: var(--space-0_5); }

/* 빈 슬롯 (클릭 시 신규 등록 팝업) — booking_renew 일간처럼 '+' 항상 흐리게, hover 시 '예약 추가' */
.bi-schmx__slot--free { flex: 1; min-height: 44px; width: 100%; border: 1px dashed var(--border-base); border-radius: var(--radius-lg); background: var(--bg-card); cursor: pointer; display: flex; align-items: center; justify-content: center; gap: var(--space-1); font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--gray-300); transition: background .12s, border-color .12s, color .12s; }
/* 2026-08-07 SG-RELOCATED 예외(의도적 유지)
   QC 가 공통 .hbar-search:hover 와 같은 선언이라 지적하지만 **병합 금지** — 헤더 검색버튼과
   캘린더 빈 슬롯은 무관한 컴포넌트다. 값(회색 hover)이 같을 뿐 한쪽이 바뀌면 다른 쪽도 끌려간다. */
.bi-schmx__slot--free:hover { background: var(--border-light); border-color: var(--gray-300); color: var(--txt-muted); }

/* ── 예약 카드 (셀 내 세로 스택) ─────────────────────────────────── */
.bi-resv { display: block; width: 100%; border-radius: var(--radius-xl); padding: var(--space-2); cursor: pointer; overflow: hidden;  transition: box-shadow .15s, transform .1s; text-align: left; }
.bi-resv:hover {  }
.bi-resv:active { transform: scale(.98); }
.bi-resv.is-sel {  }
/* 구 .bi-resv__top — 배치를 §40-10 으로 옮기자 margin 하나만 남았고 사용처가 0이 됐다(2026-08-11) */
/* 2026-08-07 §40-10 프리미티브로 대체 — .bi-bt-card-tl: 마크업에 .bi-row .bi-row--gap-4 병기 */

/* 상태 뱃지 (카드/상세 공통) */
.bi-resv-dot { font-size: var(--fs-2xs); font-weight: var(--fw-black); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm); border: 1px solid transparent; }

/* ── 모달 공통 ───────────────────────────────────────────────────── */
/* 예약상세 모달 = 공용 .bi-modal-ov/.bi-modal/.bi-modal--sm/.bi-modal__body 사용(2026-07-31).
   bt 전용: 상세 body 는 bi-bki 가 자체 padding(16px) 제공 → 이중 패딩 방지(공용 __body padding 무력화) */
#bt_detail_body { padding: 0; }

/* ── 반응형: 1280 이하 좌패널 축소, 1024 세로 분리 ─────────────── */
@media (max-width: 1280px) {
    .bi-schmx__thcell { flex-basis: 96px; width: 96px; }
    .bi-bksplit > .bi-bk-rightcol, .bi-bksplit > .bi-bk-rightcol .bi-bk-info-panel { width: 300px; }
}
@media (max-width: 1024px) {
    .bi-bksplit { flex-direction: column; }
    .bi-bksplit > .bi-bk-rightcol, .bi-bksplit > .bi-bk-rightcol .bi-bk-info-panel { width: 100%; align-self: auto; overflow: visible; }
}

/* =========================================================
   §40-18-1 주·월 보기 · 예약 화면 사이드 (2026-08-11)
   ---------------------------------------------------------
   예약일정표(booking_renew)를 §40-18 캘린더 · §40-19 예약 카드 · §40-14 매트릭스에
   합류시키고 남은 것. 이 화면에만 있는 **주 단위 행 선택**(.bi-cal__wrow)과
   **월 그리드**(.bi-cal__mgrid), 그리고 좌측 사이드의 필터 행이다.
   ⚠ 상태 배지 번호(구 .bi-bk-badge1~6)는 §40-19 상태 이름으로 바꿨다 —
     숫자는 무엇을 뜻하는지 코드를 읽어야 알 수 있었다.
   ========================================================= */
/* 월간 캘린더 요일 머리줄 — 2026-08-14 규격 신설.
 * 사용자: "예약일정표 월간일때 날짜 캘린더 깨저 규격이 빠진거같아"
 * 실제로 **CSS 가 하나도 없었다.** JS 가 만들고(#div_top_yoil), 스크롤할 때만 position:fixed 를
 * 걸어 두는 식이라 머리줄이 제자리를 잃고 첫 주 날짜가 위로 잘려 나갔다(실측 top -137, 머리줄 222).
 * 규격으로 정한다 — 그리드 위에 붙는 머리줄(sticky) · 흰 바탕 · 아래 구분선.
 * ⚠ 머리칸은 날짜칸(170px)과 같은 이름을 쓰므로 높이·아래선을 여기서 되돌린다. */
.bi-page #div_top_yoil {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--bg-card);
  border-bottom: 1px solid var(--border-base);
  font-size: 0;                      /* inline-block 칸 사이 공백 제거 */
}
.bi-page #div_top_yoil .bi-bk-calendar--month {
  height: auto;
  border-bottom: 0;
  text-align: center;
}

.bi-page .bi-bk-calendar--month {
  display: inline-block;
  vertical-align: bottom;
  width: calc(100% / 7);
  /*height: calc(98% / 5);*/
  height: 170px;
  box-sizing: border-box;
  /*border-radius: 5px;*/
  border-right: 1px solid var(--gray-200);
  border-bottom: 1px solid var(--gray-200);
  padding: var(--space-1);
}

.bi-page .bi-bk-calendar--week {
  display: inline-block;
  vertical-align: bottom;
  width: calc((100% - 82px) / 7);
  /*height: calc(98% / 5);*/
  /*height: 170px;*/
  box-sizing: border-box;
  /*border-radius: 5px;*/
  border-right: 1px solid var(--gray-200);
  border-top: none;
  padding: 0px;
}

.bi-page .bi-bk-calendar--days {
  display: inline-block;
  vertical-align: bottom;
  /*width: 140px;*/
  /* 적으면 채우고(calc), 많으면 220px 고정 후 가로 스크롤(min-width). 시간열은 :first-child 에서 80px 로 리셋 */
  width: calc((100% - 82px) / var(--dcols, 8));
  min-width: 220px;
  max-width: 400px;          /* 1~2명일 때 과도하게 넓어지지 않도록 */
  white-space: normal;       /* #calendar_days nowrap 상속 해제(내용은 정상 줄바꿈) */
  /*height: calc(98% / 5);*/
  /*height: 170px;*/
  box-sizing: border-box;
  /*border-radius: 5px;*/
  /*border-left: 1px solid var(--gray-200);*/
  border-right: 1px solid var(--gray-200);
  border-top: none;
  padding: 0px;
}

#div_type{
    overflow-y: auto;
    overflow-x: auto;       /* 디자이너 열이 많으면 가로 스크롤 */
    cursor: grab;           /* 마우스 드래그 패닝 */
    scrollbar-width: thin;                      /* Firefox */
    scrollbar-color: var(--gray-300) transparent;
}

.bi-page .bi-bk-ht45{
    height: 45px;
    font-size: var(--fs-lg);
    padding: var(--space-1) var(--space-3);
    line-height: 2.4;
    font-weight: var(--fw-bold);
    background: white;
}
.bi-page .bi-bk-ht45-line{
    height: 45px;
    /*line-height: 2.8;*/
    display: flex;
    align-items: center;
    text-align: center;
    background: white;
    border-bottom: 1px solid var(--gray-200);
    /*width:138px;*/
}

.bi-page .bi-bk-txt-center{
    text-align: center;
    /*width:139px;*/
    /*border-right: 1px solid var(--gray-200);*/
}

.bi-page .bi-bk-inner{
    border-radius: var(--radius-xs);
    height: 22px;
    background: var(--color-info-600);
    text-align: left;
    padding: var(--space-1) var(--space-2);
    color: white;
    line-height: 2;
    margin-bottom: 0;
    font-size: var(--fs-xs);
    font-weight: var(--fw-bold);
    cursor: pointer;
    text-align-last: justify;
}

.bi-page .bi-bk-sp17{
    font-size: var(--fs-lg);
    padding: var(--space-1) var(--space-3);
    font-weight: var(--fw-bold);
    color: var(--gray-500);
}

.bi-page .bi-bk-calendar--week .bi-bk-sp17{
    color: var(--gray-500);
    font-weight: var(--fw-bold);
}

.bi-page .bi-bk-sp14{
    font-size: var(--fs-md);
    padding: var(--space-1) var(--space-2_5);
    font-weight: var(--fw-normal);
    color: var(--gray-700);
    width: 100%;
}

.bi-page .bi-bk-today{
    background: var(--color-npay);
    border-radius: var(--radius-2xl);
    color: white;
}

.bi-page .bi-bk-div5{
    margin-bottom: var(--space-1_5);
    margin-top: var(--space-1_5);
}

.bi-page .bi-bk-emp-active{
    border-bottom: 3px solid var(--brand-blue);
    color: var(--brand-blue);
    padding-bottom: var(--space-1);
}

.bi-page .bi-bk-number-grey{
    color: var(--gray-400);
}

.bi-page .bi-bk-btn-status{
    padding: var(--space-3_5) var(--space-3);
    text-align-last: center;
}

.bi-page .bi-bk-commend{
    /*padding:5px;*/
    /*background: var(--brand-blue);*/
    color: white;
    border-radius: var(--radius-xs);
    line-height: 0.8;
    font-size: var(--fs-base);
    cursor: pointer;
    width: 27px;
}
.bi-page .bi-bk-slot180{
    /* 고정 높이 — 좌측 시간열과 디자이너 열의 행 정렬(디자인 단일 시간축) */
    height: 84px;
    font-size: var(--fs-2xs);
    /*color:var(--gray-400);*/
    text-align: center;
    border-bottom: 1px solid var(--gray-200);
    padding: var(--space-1);
}
.bi-page .bi-bk-time-color{
    color: var(--gray-400);
}
.bi-page .bi-bk-mg10{
    margin-top: var(--space-2_5);
}

.bi-page .act_date{
    border-color: var(--brand-blue);
    color: var(--bg-card);
    cursor: pointer;
    background-image: -webkit-linear-gradient(top, var(--brand-blue), var(--brand-blue));
    background-color: var(--brand-blue);
}
.bi-page .act_status{
    border-color: var(--brand-blue);
    color: var(--bg-card);
    cursor: pointer;
    background-image: -webkit-linear-gradient(top, var(--brand-blue), var(--brand-blue));
    background-color: var(--brand-blue);
}

/* 40px 은 여백 스케일 밖 — 토큰을 늘리지 않고 스케일 조합으로 같은 값을 만든다(§1) */
.bi-page .bi-bk-emp{
    padding-left: calc(var(--space-8) + var(--space-2));
    font-weight: var(--fw-bold);
    cursor: pointer;
}
.bi-page .bi-bk-emp:first-child{
    padding-left: var(--space-2_5);
}
.bi-page .bi-bk-emp span{
    padding: var(--space-2_5) 0px;
}

.bi-page .bi-bk-ten-up{
    padding: var(--space-1) var(--space-1_5);
}

#calendar_days{
    white-space: nowrap;    /* 디자이너 열을 한 줄로 유지(가로 스크롤) */
}

/* 2026-08-21 제거 — 고객관리 디자이너 필터 아래에 «회색 판» 이 하나 더 있었다(사용자 지적).
 * 정체는 이 id 셀렉터의 border-bottom: 2px 였다. 밑줄 탭 시절의 잔재인데
 * 지금은 알약(pill)이라 밑줄이 필요 없고, 바로 아래 필터카드의 구분선과 겹쳐 두 줄로 보였다.
 * display:flex 는 .bi-pillbar 가 이미 준다 → 규칙 자체를 없앤다.
 * (id 셀렉터는 특이도가 높아 클래스로는 못 이긴다 — 그래서 오래 살아남았다) */

.bi-page .bi-bk-status1{
    background: var(--color-success-400);    
}

.bi-page .bi-bk-status2{
    background: var(--color-info-600);    
}

.bi-page .bi-bk-status3{
    background: var(--gray-300);    
}

.bi-page .bi-bk-status4{
    background: var(--color-purple-500);    
}

.bi-page .bi-bk-status5{
    background: var(--gray-300);    
}

.bi-page .bi-bk-status6{
    /* 2024.09.20 예약마감 css 추가  */
    background: var(--gray-300);     
}

/* 선결제 배지 안 원화 아이콘 — 배지 색 상속, 또렷하게 */

.bi-page .bi-bk-scroll{
    cursor: pointer;
}
.bi-page .bi-bk-days-scroll{
    cursor: pointer;
}
/* 더 갈 곳이 없는 화살표. JS 가 인라인으로 rgb(159,159,159) / 'black' 을 찍던 자리 —
 * 켜진 쪽은 아무 색도 주지 않는다(글자색을 물려받는 게 규격이다). 꺼진 쪽만 상태로 표시한다. */
.bi-page .bi-bk-scroll.is-disabled,
.bi-page .bi-bk-days-scroll.is-disabled{ color: var(--gray-400); cursor: default; }

.bi-page .inp_date{
    width: 100%;
    text-align: center;
    border: none;
    height: 20px;
    font-weight: 900;
    font-size: var(--fs-md);
}

/* 달력 컨테이너 스크롤바 — 얇고 은은한 회색 (디자인 scrollbar-thin) */
#div_type::-webkit-scrollbar { width: 9px; height: 9px; }
#div_type::-webkit-scrollbar-track { background: transparent; }
#div_type::-webkit-scrollbar-thumb {
    background: var(--gray-300);
    border-radius: var(--radius-full);
    border: 2px solid transparent;
    background-clip: padding-box;
}
#div_type::-webkit-scrollbar-thumb:hover {
    background: var(--txt-disabled);
    background-clip: padding-box;
}
#div_type::-webkit-scrollbar-corner { background: transparent; }

/* 고객명 옆에 디자이너명 출력 툴팁*/
#tooltip-re {
    display: none;
    position: relative;
    transform: translateX(8%);
    z-index: 90;
}
.bi-page .tooltip {
    position: absolute;
    width: 200px;
    height: 32px;
    background-color: var(--color-warning-300);
    line-height: 32px;
    text-align: center;
    padding: var(--space-0_5) var(--space-2);
    color: var(--gray-800);
    font-size: var(--fs-xs);
    font-weight: var(--fw-extrabold);
    left: -29px;
    bottom: 44px;
    z-index: 2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
#tooltip-container:hover+#tooltip-re{
    display: block;
}

/* 날짜 네비게이션 */
/* 2026-08-07 §40-10 프리미티브로 대체 — .bi-datenav: 마크업에 .bi-row .bi-row--gap-4 병기 */
.bi-datenav .bi-bk-commend {
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background .15s;
    flex-shrink: 0;
    background: var(--brand-blue);
}
.bi-datenav .bi-bk-commend:hover { background: var(--brand-blue-hover); }
.bi-datenav .bi-bk-commend svg { width: 12px; height: 12px; }
.bi-datenav .bi-bk-commend svg path { fill: var(--bg-card); }
.bi-datenav .inp_date {
    /* legacy .inp_date { width:100%; border:none; height:20px; } 덮어쓰기 */
    width: auto;
    min-width: 160px;
    border: 1px solid var(--border-base);
    border-radius: var(--radius-lg);
    padding: var(--space-1) var(--space-3_5);
    height: 32px;
    text-align: center;
    font-size: var(--fs-base);
    font-weight: 600;
    color: var(--txt-primary);
    background: var(--bg-card);
    line-height: normal;
}

/* 서브바 좌측 예약상태 범례 (검색필드에서 이동) */

@media (max-width: 1280px) { .bi-bk-legend--subbar { gap: var(--space-2_5); } .bi-bk-legend--subbar .bi-bk-legend-item { font-size: var(--fs-2xs); } }

/* ⚠ 배경·테두리가 없으면 브라우저 기본 회색 버튼이 된다. 레거시 전역 버튼 스킨이
 *   가려주고 있었을 뿐이다(2026-08-12 그 스킨 제거로 드러남).
 *   세그먼트 항목은 **바탕 없음**, 활성만 색(.act_date) — 그게 §12 세그먼트 규격이다. */
/* .bi-segment input[type="button"] 삭제(2026-08-21) — 세그먼트 구현이 **셋**이었다.
 *   ① .bi-segment__btn (§29 규격 · 특이도 0,1,0)
 *   ② .bi-seg-wrap input[type="button"] (레거시 래퍼 · 삭제됨)
 *   ③ .bi-segment input[type="button"] ← 이것 (특이도 0,1,1)
 * ③ 이 ① 을 **조용히 이긴다**(요소+속성 선택자가 클래스보다 높다). 그래서 마크업에
 * .bi-segment__btn 을 붙여도 화면이 그대로였다 — 규격을 고쳐도 안 바뀌는 상태였다.
 * 마크업의 <input> 전부에 규격 클래스를 달았으므로 ③ 을 없앤다. ① 하나만 남는다. */
.bi-segment__btn:hover:not(.is-active) { background: color-mix(in srgb, var(--black) 5%, transparent); color: var(--txt-secondary); }

/* ============================================================
   예약정보 인스펙터 (2026-06-16)
   기존 hook 클래스(.bk_status/.bk_top_name/.bk_phone/.bk_emp/.bk_date/.bk_type/
   .bk_num/.bk_goods/.bk_price/.bk_first_price/.bk_memo/.bk_avatar/.div_group/버튼) 보존
   ============================================================ */

/* 프로필 헤더 */

.bi-bki-gender:empty { display: none; }/* 인스펙터 버튼 base(.bi-bki-btn/--sales/-sublinks/-link) → 공통 style.css(구 booking_schedule.css) 이관 (2026-07-31).
   아래는 booking_renew 전용 델타: 부모 .div_group 의 text-align-last:right(JS) 상속 보정 */
.bi-write-grid-2 input[type="button"].bi-bki-btn--sales { text-align-last: center; }

/* ============================================================
   Stage 1 — 스케줄러 토큰 정렬 (2026-06-15)
   ⚠ JS 슬롯 수학에 영향 주는 치수(.bi-bk-slot180 170px·.bi-bk-inner 22px·열너비)는 불변.
      색·라운드·테두리·폰트·sticky 등 코스메틱만 조정.
   ============================================================ */

/* 디자이너 열 헤더 (Dashboard: 굵은 이름 + 연한 헤더 배경) — sticky 는 기존 JS 가 담당하므로 CSS sticky 미사용(충돌 방지) */
.bi-page .bi-bk-ht45-line {
    background: var(--bg-card);                /* 디자인 th 흰색 */
    border-bottom: 1px solid var(--border-base);
}
/* 디자이너 열 헤더 고정 — sticky(스크롤 컨테이너 #div_type 내에서만, 인스펙터 안 가림) */
.bi-page #calendar_days .bi-bk-calendar--days .bi-bk-ht45-line { position: sticky; top: 0; z-index: 5; }
/* 가로 스크롤 시 좌측 시간열 고정 (sticky left) — 흰 배경으로 카드가 비치지 않게 */
.bi-page #calendar_days .bi-bk-calendar--days:first-child {
    position: sticky; left: 0; z-index: 6;
    background: var(--bg-card);
    border-right: 1px solid var(--gray-200);
}
/* 좌상단 코너(시간열 헤더)는 가로·세로 모두 위로 */
.bi-page #calendar_days .bi-bk-calendar--days:first-child .bi-bk-ht45-line { z-index: 7; }
.bi-page .bi-bk-calendar--days .bi-bk-ht45-line .bi-bk-sp14 {
    color: var(--txt-primary);
    font-weight: var(--fw-bold);
    font-size: var(--fs-base);
}
/* 첫 열(시간 라벨열) 헤더도 디자이너 헤더와 동일하게 흰색 */
.bi-page .bi-bk-calendar--days:first-child .bi-bk-ht45-line { background: var(--bg-card); }
/* 시간 라벨열은 80px 고정 (디자이너 열의 min-width:220 적용 제외) */
.bi-page .bi-bk-calendar--days:first-child { width: 80px; min-width: 80px; max-width: 80px; }/* 예약 카드 (innerDiv) — Dashboard 카드 톤: 라운드 + 그림자 + 폰트 */
.bi-page .bi-bk-inner {
    border-radius: var(--radius-md);
    font-weight: var(--fw-semibold);
    letter-spacing: -0.01em;
}
/* 예약 가능(빈) 셀 — Dashboard 빈 셀: 점선 박스, 평소 '+' 흐림 / hover 시 '+ 예약 추가' */
.bi-page .bi-bk-innerPossible {
    background: var(--bg-card);
    color: var(--txt-disabled);
    border: 1px dashed var(--border-base);
    box-shadow: none;
    font-weight: var(--fw-bold);
    transition: background .12s, border-color .12s, color .12s;
}
.bi-page .bi-bk-innerPossible:hover {
    background: var(--bg-input);
    border-color: var(--gray-300);
    color: var(--gray-600);
}
.bi-page .bi-bk-innerPossible .bi-bk-sp-remain-cnt { display: none; }   /* 잔여수는 로직용 — 화면 숨김 */

/* 상태색 — Dashboard 팔레트로 정렬 (1신청 emerald / 2확정 blue / 4완료 gray / 3·5·6 취소·노쇼·마감 gray) */
.bi-page .bi-bk-inner.bi-bk-status1 { background: var(--color-success-500); }   /* 신청 = emerald */
.bi-page .bi-bk-inner.bi-bk-status2 { background: var(--color-info-600); }   /* 확정 = blue */
.bi-page .bi-bk-inner.bi-bk-status4 { background: var(--txt-muted); }/* 시간 슬롯 행 hover (인터랙션 힌트) */
.bi-page .bi-bk-time:hover { background: color-mix(in srgb, var(--bg-input) 60%, transparent); }

/* 디자이너 슬라이더 활성 — Dashboard 브랜드 블루 언더라인 */
.bi-page .bi-bk-emp-active { color: var(--color-info-600); }

/* ============================================================
   Stage 2 — 카드형 예약 + 디자이너 헤더 아바타 (2026-06-15)
   .bi-bk-inner · bi-bk-status · data-속성 · onclick · 툴팁 보존, 마크업만 카드화.
   슬롯(.bi-bk-slot180 170px) 안에서 카드 높이 auto(min 40px) — max_num(4) collapse 로 한도.
   ============================================================ */

/* 예약 카드 (Dashboard 카드: 시간 + 네이버 + 고객명) */
.bi-page .bi-bk-inner.bi-bksch-card {
    height: auto;
    min-height: 50px;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    padding: var(--space-2) var(--space-2_5);
    line-height: 1.25;
    text-align: left;
    text-align-last: left;
    border-radius: var(--radius-xl);     /* rounded-xl (디자인) */
    color: var(--gray-800);          /* 연한 배경 카드 → 진한 글자 */
    white-space: normal;
}
/* 카드 상태색 — Dashboard: 연한 배경 + 색상 좌측보더 + 진한 색 글자 (solid override) */
.bi-page .bi-bk-inner.bi-bksch-card.bi-bk-status1 { background: var(--color-success-50); border: 1px dashed var(--color-success-300); color: var(--color-success-800); }
.bi-page .bi-bk-inner.bi-bksch-card.bi-bk-status2 { background: var(--color-info-50); border-left: 3px solid var(--color-info-600); color: var(--brand-blue); }
.bi-page .bi-bk-inner.bi-bksch-card.bi-bk-status4 { background: var(--bg-input); border-left: 3px solid var(--txt-disabled); color: var(--txt-muted); }/* 모든 시간 슬롯 — flex column: 내용(카드/예약가능)이 칸을 꽉 채움 */
.bi-page .bi-bk-time { display: flex; flex-direction: column; gap: var(--space-0_5); padding: var(--space-1) var(--space-1); }
.bi-page .bi-bk-time > br { display: none; }
.bi-page .bi-bk-time > .bi-bk-inner { flex: 1 1 auto; }
/* 예약가능(빈) 셀 — 점선 placeholder 가 칸을 채우고 가운데 정렬 */
/* 2026-08-07 §40-10: .bi-page .bi-bk-time .bi-bk-innerPossible — 마크업에 .bi-row-center 병기 */
/* 주간: 예약 카드를 빈슬롯보다 먼저(위) 표시 — 빈슬롯을 맨 아래로 */
.bi-page .bi-bk-calendar--week .bi-bk-time .bi-bk-innerPossible { order: 10; }

/* 주간/월간 집계 칩 + hover 상세(고객명·디자이너) */
.bi-page .bi-agg { position: relative; min-width: 0; }
/* 집계 요약: 주간=단일 '예약 N건' 칩 / 월간=상태별 건수 칩(wrap) */
/* 2026-08-07 §40-10: .bi-agg-summary — 마크업에 .bi-row .bi-row--wrap .bi-row--gap-4 병기 */
.bi-page .bi-agg[data-mode="week"] .bi-agg-summary { display: block; }
/* 주간 예약 요약 = 슬롯형(빈슬롯과 구분되는 파란 톤) · 좌 '예약' · 우 건수 */
/* 월간 예약 요약 = 셀 가로 100% · 상태별 풀폭 행(좌 상태 · 우 건수) */
.bi-page .bi-agg[data-mode="month"] { width: 100%; }
.bi-page .bi-agg[data-mode="month"] .bi-agg-summary { flex-direction: column; flex-wrap: nowrap; width: 100%; gap: var(--space-1); }
.bi-page .bi-agg-stat {
    display: flex; align-items: center; justify-content: space-between;
    width: 100%; box-sizing: border-box; white-space: nowrap;
    font-size: var(--fs-xs); font-weight: var(--fw-extrabold); line-height: 1.5;
    padding: var(--space-0_5) var(--space-2); border-radius: var(--radius-md); border: 1px solid transparent;
}
.bi-page .bi-agg-stat.bi-bk-status1 { background: var(--color-success-100); color: var(--color-success-700); border-color: var(--color-success-300); }
.bi-page .bi-agg-stat.bi-bk-status2 { background: var(--color-info-100); color: var(--color-info-700); border-color: var(--color-info-300); }
.bi-page .bi-agg-stat.bi-bk-status4 { background: var(--border-base); color: var(--txt-muted); }.bi-page .bi-agg-list {
    display: none; position: absolute; left: 0; top: 100%; z-index: 50;
    min-width: 220px; max-width: 300px; overflow-y: auto;
    margin-top: var(--space-1); padding: var(--space-1_5);
    background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-xl);
    white-space: normal; text-align: left;
}
.bi-page .bi-agg[data-mode="week"]:hover .bi-agg-list { display: block; }/* 일간 취소 칩 — 슬롯 안에서 늘어나지 않고 컴팩트하게(활성 카드 아래) */
.bi-page .bi-bk-time > .bi-agg--daycancel { flex: 0 0 auto; width: 100%; margin-top: var(--space-0_5); }
/* hover 항목 = 슬롯 카드와 동일 룩의 블럭(시간·고객명·디자이너·시술) — 펼친 리스트, 높이 고정 80px */
.bi-page .bi-agg-item.bi-bksch-card {
    width: 100%; box-sizing: border-box; margin: 0 0 var(--space-1_5); cursor: pointer;
    height: 80px; min-height: 80px; overflow: hidden; justify-content: center;
}
.bi-page .bi-agg-item.bi-bksch-card:last-child { margin-bottom: 0; }
/* 일간 활성 과밀 ②: 3건+ 집계 칩(취소 칩과 동일 컴팩트·hover 펼침) */
/* 일간 활성 과밀 ①: 2건 컴팩트 — min-height 해제로 둘이 슬롯(84px)을 나눠 갖고, 서비스줄 숨김·이름 축소로 잘림 방지 */
.bi-page #calendar_days .bi-bk-time.is-dense .bi-bksch-card { min-height: 0; padding: var(--space-1) var(--space-2); gap: var(--space-0_5); }
.bi-page #calendar_days .bi-bk-time.is-dense .bi-bksch-card .bi-bksch-card-name { font-size: var(--fs-xs); }
/* 주간: 예약 요약 + 빈슬롯. 빈슬롯만이면 100%, 둘 다면 50:50 (flex 1 1 0). box-sizing 으로 침범 방지 */
.bi-page #calendar_week .bi-bk-time { flex-direction: column; gap: var(--space-1); align-items: stretch; box-sizing: border-box; }.bi-page #calendar_week .bi-bk-time > .bi-agg { display: flex; order: 1; }
.bi-page #calendar_week .bi-bk-time > .bi-bk-innerPossible { order: 2; }
.bi-page #calendar_week .bi-bk-time > .bi-agg > .bi-agg-summary { flex: 1; min-width: 0; display: flex; }

/* 시간은 좌측 시간열에만 표시 (디자인 단일 시간축) — 디자이너 열의 슬롯 시간 라벨 숨김 */
.bi-page .bi-bk-calendar--days:not(:first-child) .bi-bk-time > .bi-bk-mg10 { display: none; }
/* 좌측 시간열 — 시간 가운데, mono */
.bi-page .bi-bk-calendar--days:first-child .bi-bk-time { align-items: center; justify-content: center; }
.bi-page .bi-bk-calendar--days:first-child .bi-bk-time > .bi-bk-mg10 {
    flex: 0 0 auto; text-align: center; font-size: var(--fs-xs); font-weight: var(--fw-extrabold); color: var(--txt-muted);
    font-family: ui-monospace, Menlo, monospace;
}

/* 2026-08-07 §40-10: .bi-bksch-card-top — 마크업에 .bi-row .bi-row--gap-6 병기 */
/* 카드 상태 배지 */
.bi-bksch-card-badge { flex-shrink: 0; font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-md); border: 1px solid transparent; line-height: 1.5; }
.bi-bksch-card-time {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: var(--fs-2xs); font-weight: var(--fw-bold); opacity: .8;
}
.bi-bksch-card-name {
    font-size: var(--fs-base); font-weight: var(--fw-extrabold);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 2026-06-26 예약 카드 이름/상품명이 부모 .bi-bk-inner 의 text-align-last:justify 를 상속해
   공백 있는 상품명("남성 드라이" 등)의 공백이 카드 폭만큼 과하게 벌어지던 문제 → 좌측 정렬 고정 */
.bi-page .bi-bksch-card-name, .bi-bksch-card-name { text-align-last: left; }

/* 디자이너 열 헤더 — 아바타 이니셜 + 이름 (Dashboard 헤더) */
/* 직책 — 디자이너명 아래, 좌측 정렬 (부모 text-align:center 상속 차단) */
.bi-bksch-dhead-cnt {
    flex-shrink: 0; min-width: 18px; text-align: center;
    font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); color: var(--color-indigo-700);
    background: var(--color-indigo-50); border: 1px solid var(--color-indigo-100); border-radius: var(--radius-full); padding: var(--space-0_5) var(--space-2);
}

/* ── Stage 3 — 현재시각 빨간선 (일간 뷰 오버레이, 09:00~21:30, 슬롯 170px) ── */
#calendar_days { position: relative; }

/* 검색 영역 (Dashboard Section 1A — 아이콘 내장 입력 + navy + 버튼) */
/* 2026-08-07 §40-10: 레이아웃(flex:1;min-width:0)은 .bi-fill 병기 */
/* 기본형 → 공용 .bi-btn.bi-btn--navy.bi-btn--icon (HTML). 델타: 라운드·그림자 (hover/active 는 공용) (2026-07-31) */

/* 미니 월 달력 (Dashboard Section 1B — Calendar Picker) */
.bi-cal__nav:hover { background: var(--border-light); color: var(--txt-secondary); }
.bi-cal__day:hover { background: color-mix(in srgb, var(--border-light) 80%, transparent); }
.bi-cal__day.is-sun { color: var(--color-danger); }
.bi-cal__day.is-sat { color: var(--color-info-500); }
.bi-cal__day.is-empty { background: transparent; cursor: default; pointer-events: none; }
.bi-cal__day.is-today { box-shadow: inset 0 0 0 1.5px var(--color-info-200); color: var(--brand-blue); font-weight: var(--fw-extrabold); }
.bi-cal__day.is-sel { background: var(--brand-blue); color: var(--bg-card); font-weight: var(--fw-extrabold);  }
.bi-cal__day.is-out { color: var(--gray-300); }   /* 앞뒤 달 날짜 흐리게 (booking_time 캘린더와 동일) */

/* 주간 모드 — 주(row) 단위 선택/hover 하이라이트. 그리드를 세로 스택(각 주=7칸 가로) */
.bi-cal__grid.is-weekmode { display: block; }

/* 전역 input[type=checkbox]{visibility:hidden;display:none} 강제 규칙 회피 (CLAUDE §5-1) */
/* 체크박스 스프라이트 무력화 → 공통 style.css(구 booking_schedule.css) 이관 (2026-07-31) */

/* 스케줄 상태 통계 (예약/완료 건수) */

.bi-bksch-stat-v b { font-weight: var(--fw-black); }

/* ============================================================
   간편예약 팝업 (신규 — 예약 등록 모달, 2026-06-16)
   ============================================================ */
/* .bi-bq-overlay/-modal/-head/-close = 구 인페이지 모달 크롬. 레이어팝업(popup_layer_bk_quick)으로 전환돼 dead → 제거(2026-07-31). bq-body/row/field 는 폼 내용으로 live 유지. */
/* 2026-08-07 공통 일원화: `#popup_layer_member .write_layout{z-index:2000}` 은 style.css(구 popup.css) 에 동일 정의가
   있어 제거(팝업 CSS 는 style.css(구 popup.css) 로 일원화 — styleguide2 §38). */
/* 간편예약 레이어 팝업(popup_layer_bk_quick)을 스케줄(헤더 z:99·100, 집계 z:50, 현재시간줄 z:40) 위로 올림.
   .write_layout 기본 z-index:10 은 스케줄 요소들보다 낮아 가려지므로 상향(위치는 그대로, z-index 만). */
#popup_layer_bk_quick .write_layout { z-index: 1000; }
/* 2026-08-27 제거 — 여기 `#popup_layer_bk_quick .write_layout_pop{width:460px;height:660px}` 가 있었다.
 *   도입 사유는 「다른 팝업이 열리면 popup_layer.js 가 **전역** .write_layout_pop 크기를 덮어쓴다」였는데,
 *   그 전역 덮어쓰기는 2026-08-26 에 **원인을 고쳤다**(지금 여는 팝업의 상자만 고른다).
 *   증상을 막으려고 id 로 박아둔 크기가 남아 규격 폭(423)을 이기고 있었다 — #prepay·#n_pay 와 같은 함정.
 *   ⚠ **원인을 고친 뒤에는 그때 세운 방어막도 걷어야 한다.** 안 걷으면 다음 규격을 그게 막는다. */

.bi-page .div_grada_left, .div_grada_right { width: 50px; text-align: center; font-size: var(--fs-2xl); line-height: 1.75; }

/* §40-10 보완 — 인라인 style 을 걷어내며 필요해진 배치 유틸 (2026-08-11).
   팝업 마크업이 `style="text-align:right"` 처럼 한 줄짜리 인라인을 400여 곳에서 쓰고 있었다.
   뜻이 하나뿐인 것만 여기로 회수한다 — 여러 선언이 얽힌 float 레이아웃은
   마크업 구조를 바꿔야 해서 L2(브라우저) 확인 뒤에 한다. */
.bi-tr          { text-align: right; }
.bi-tc          { text-align: center; }
.bi-strong      { font-weight: var(--fw-bold); }
.bi-nounderline { text-decoration: none; }

/* 눌러서 팝업을 여는 읽기전용 입력 — 커서를 손모양으로, 깜빡이는 캐럿은 숨긴다.
   담당자·상품 선택처럼 "입력칸처럼 보이지만 실제로는 버튼"인 자리(§21 보완). */
/* 눌러서 팝업을 여는 읽기전용 입력 — 커서는 §40-10 .bi-clickable 이 맡고,
   여기서는 "타이핑할 수 없다"는 표시(캐럿 숨김)만 더한다. 마크업에 둘을 병기한다. */
.bi-input--clickable { caret-color: transparent; }
/* 범례에 쓰는 상태 아이콘 — 매트릭스 슬롯의 마커와 같은 뜻을 설명용으로 보여준다 */
/* §8 보완 — 작은 대문자 섹션 라벨. 예약 상세·예약 스케줄·예약 집계가 각자 만들고 있었다 */
/* =========================================================
   §40-2-1 발송 미리보기 — 문자 · 알림톡 (2026-08-11 신설)
   ---------------------------------------------------------
   **콘텐츠 고유**다. 실제 발송 화면을 흉내내는 그림이라 규격 컴포넌트로 대체할 수 없고,
   카카오 노랑(#FAE102)·말풍선 모서리는 **브랜드 자산**이라 규격색으로 바꾸면 오히려 틀린다.
   그래서 규격에 "고유"로 명시하고 전시한다 — 예외를 숨기지 않고 드러낸다.
   ⚠ 이 색·모양을 다른 화면에서 재사용하지 않는다. 알림톡 미리보기 한 곳 전용이다.
   ========================================================= */
.bi-msgprev-phone__top { height: 53px; }
.bi-msgprev-phone__ta  { width: 184px; height: 280px; overflow-y: scroll; line-height: 15px; letter-spacing: -0.5pt; word-wrap: break-word; font-family: 돋움체; background: transparent; border: 0; }
.bi-msgprev-phone__size{ width: 85%; text-align: right; padding-top: var(--space-3); }
.bi-msgprev-phone__foot{ height: 56px; }
/* 발송 팝업 변형 — 설정 화면은 본문 하나지만 발송 팝업(sms·lms)은 **본문 + 추가** 2단이다.
 * 배경 gif 가 단마다 다르다(A / Add / PhoneBody). 브랜드 자산이라 값 그대로 유지한다.
 * 2026-08-11: 이걸 팝업 두 곳이 긴 인라인 style 로 각자 갖고 있었다. */
/* 발송 팝업의 입력칸은 설정 화면보다 작다(2단으로 나뉘므로) */
/* 폰 목업 바깥 — 발송 팝업은 폼 옆에 나란히 놓는다 */
/* 발송 팝업 입력 열 — 폰 목업(250px) 옆에 서는 폼 기둥. 폭이 목업과 짝이라 규격에 둔다.
 * 안쪽 항목 간격은 §40-10 .bi-col --gap-16 이 준다(구 padding-top:16px 반복). */
/* 알림톡 — 카카오 브랜드 */
/* §40-10 보완 — 인라인 style 을 걷어내며 필요해진 한 줄짜리 (2026-08-11 2차) */
.bi-clickable { cursor: pointer; }
/* 잠깐 짚어 보여주는 강조 — 목록에서 방금 바뀐 행을 알릴 때(§40-11 상태).
 * 2026-08-12: 한 화면 전용 .bi-hl 을 걷어내며 규격 상태로 올렸다. */
.bi-row.is-highlight, .bi-pop-tbl-row.is-highlight, .bi-erp-card.is-highlight,
.is-highlight {  border-radius: var(--radius-lg); }

/* ── 40-20. 수신 전화 알림 (2026-08-11) — footer.php 의 CID 팝업 ──
 * 전화가 오면 화면 구석에 뜨는 파란 카드. 인라인 8건이 이 하나를 그리고 있었다.
 * ⚠ 파랑 두 가지(#4dabf7 머리/본문 · #2d87e2 수신줄)는 토큰에 없다.
 *   sg2 색과 다른 계열이라 억지로 맞추면 알림의 '눈에 띔' 이 무너진다 →
 *   §40-2-1(브랜드 자산)과 같은 취급으로 **값을 그대로 두고 규격에 명시**한다. */
/* 구 .bi-btn--cid-w70 — .bi-input--w70 와 같아 합침(2026-08-12) */
/* 구 .bi-btn--cid-w100 — .bi-input--w100 와 같아 합침(2026-08-12) */

/* ── 잔여 마무리 (2026-08-12) ── */
/* 예약 달력 위 요일 표시 — 절대배치로 셀 위에 겹친다 */
/* LMS 본문(장문) — SMS 보다 길어 배경 gif 와 높이가 다르다 */
/* =========================================================
   §HIDDEN — 숨김 유틸리티 (파일 맨 끝 · 위치가 곧 규칙)
   ---------------------------------------------------------
   `.bi-hidden` 은 "무조건 숨긴다"가 계약이다. 그런데 특이도가 0,1,0 뿐이라
   같은 특이도의 컴포넌트 규칙이 뒤에 오면 진다 — 실제로 `.bi-bki{display:flex}`(L5218)가
   `.bi-hidden`(L2169)을 이겨 숨겨야 할 요소가 보이고 있었다.

   ⚠ `` 는 쓰지 않는다 — jQuery `.show()` 가 안 먹는다(구 `#counter_portal .is-hidden` 의 전철).
   → 대신 **정의를 파일 맨 끝에 둔다.** 같은 특이도면 나중이 이기므로 공통 안에서는 항상 이긴다.
   이 블록 아래에 다른 규칙을 추가하지 말 것.

   모듈 CSS 는 공통 뒤에 로드되므로 여전히 이길 수 있다.
   그 자리는 QC `CASCADE-LOSS` 가 잡는다(2026-08-07 158fe27 사고의 재발 방지).
   ========================================================= */
.bi-hidden { display: none; }

/* =========================================================
   §38-8 팝업 파일에서 이관한 전용 규칙 (2026-08-11)
   ---------------------------------------------------------
   세 팝업이 각자 <style> 블록을 갖고 있었다(§4 절대규칙 위반).
   ⚠ 값은 **그대로** 옮긴다. 여기서 값까지 바꾸면 이관 실패와 디자인 변경이
     한 커밋에 섞여 원인을 가릴 수 없다. 토큰화는 별도로 한다.
   ========================================================= */
/* ── npay_btn 팝업 전용 (2026-08-11: 파일 내 <style> 블록에서 이관 — §4 절대규칙) ── */
/* 20.09.17 tag */
.pop_cate_wrap{
	border:1px solid var(--border-base);
	margin: var(--space-4) 0;
}

.pop_cate_div{
	width:450px;
	height:auto;
	margin: var(--space-2_5);
	/*border:1px solid var(--border-base);*/
	cursor:pointer;
}

.pop_cate_title{
	width:450px;
	height:35px;
	line-height:35px;
}

.tags_name{
	margin-left: var(--space-2_5);color: var(--brand-blue);font-size: var(--fs-md);
}

.pop_cate_title_right{
	float:right;
	width:100px;
	overflow:auto;
}

.onoff{
	float:left;width:20px;font-size: var(--fs-xl);cursor:pointer;postion:fixed;right:20px;display:none;
}
.onoff.off{
	display:block;
}

.pop_tag_ul{
	width:450px;
	padding:0px;
	margin:0px;
	overflow:hidden;
	border-top:1px solid var(--border-base);
	/*border:1px solid var(--border-base);*/
	display:none;
	cursor:default;
}

.pop_tag_li{
	width:150px;
	list-style:none;
	float:left;
	/*margin:5px 0px;*/
	margin-top: var(--space-2_5);
}

.ch_label{
	cursor:pointer;
}

/* ── sch_mem 팝업 전용 (2026-08-11: 파일 내 <style> 블록에서 이관 — §4 절대규칙) ── */
.write_layout {     /* 1012 wi/hei 100%-> 80% 변경 // top 0->5px sch_mem실행시 좌우스크롤 생성방지  */
    width: 80%;
    position: absolute;
/*    top: 0px;*/
   top: -37px;
	left: 10px;
    height: 70%;
    float: left;
    /*  display: none;*/
    /* display: block;*/

}

/* ── slip_2022 팝업 전용 (2026-08-11: 파일 내 <style> 블록에서 이관 — §4 절대규칙) ── */
.signature-pad--body canvas {
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-xs) inset;
	border:1px solid var(--border-base);
	width: 100%;
    height: 100%;
}
.signature-pad--body {
	height: 150px;
    width: 250px;
    margin: 0 auto;
}
.signature-pad--footer {
    width: 100%;
    text-align: right;
	padding-top: var(--space-3_5);
}

/* ── popup_layer_prepay (2026-08-12: 파일 내 <style> 에서 이관 — §4) ── */
  
  		.pop_m_b_li_div{
  			padding-left: var(--space-4);
  			line-height: 21px;
  		}

  		.pop_desc p {
  			margin: var(--space-0_5) 0;
  		}
  input[type="tel"] { /*태블릿용 - input type변경 시 계산이벤트 안먹는 문제로 보류*/
  	border: 1px solid var(--border-base);
  	-webkit-border-radius: var(--radius-sm);
  	-moz-border-radius: var(--radius-sm);
  	border-radius: var(--radius-sm);
  	border-top: 1px solid var(--border-base);
  	-webkit-box-shadow: none;
  	-moz-box-shadow: none;
  	box-shadow: none;
  	color: var(--txt-primary);
  	font-size: var(--fs-base);
  	height: 20px;
  	line-height: 25px;
  	padding: var(--space-0_5) var(--space-1);
  }  .selectWrap{
  	/* display:none; */
  	width: 100%;
      height: 428px;
      background: #fff;
      position: absolute;
      z-index: 999;
  }/* ── popup_layer_card_cancel_2022 (2026-08-12: 파일 내 <style> 에서 이관 — §4) ── */
  #kisPosOcx{
  	display:none; 
  }
  .selectWrap{
  	/* display:none; */
  	width: 100%;
      height: 510px;
      background: #fff;
      position: absolute;
      z-index: 999;
  }

  .selectWrap p{
  	 padding: 0 var(--space-2_5); 
  	color:rgba(0, 0, 0, 0.6);
  }

/* =========================================================
   가이드 데모 무대 (2026-08-12)
   ---------------------------------------------------------
   position:absolute/fixed 인 규격(.bi-cid · .bi-pop-cover ·
   .bi-pop-bk__daylbl · .bi-pop-corner-in)을 가이드에 그대로 놓으면 **문서를 덮는다**.
   실제로 styleguide2 가 반투명 흰 판에 가려졌다(사용자 발견 2026-08-12).
   → 데모는 이 무대 안에서만 띄운다. 무대가 배치 기준(relative)과 크기를 준다.
   ⚠ 규격 자체는 손대지 않는다 — 문제는 전시 방법이었다. */
/* ⚠ `overflow:hidden` 만으로는 **position:fixed 자식을 못 가둔다** — fixed 는 뷰포트 기준이라
 *   무대를 뚫고 나와 가이드 위를 덮는다(2026-08-12 실제로 스타일가이드2 가 그렇게 깨졌다).
 *   `contain: layout paint` 가 이 요소를 **고정·절대 요소의 기준 상자**로 만들어 가둔다.
 *   ⚠ `transform: translateZ(0)` 로도 되지만 그건 **합성 레이어를 만든다** — 무대가 260개면
 *     레이어도 260개라 스크롤·이동이 멈춘다(2026-08-13 사용자 보고). contain 만 쓴다. */
.sg2doc-stage{ position: relative; height: 220px; overflow: hidden;
               contain: layout paint;
               border: 1px dashed var(--border-base); border-radius: var(--radius-lg);
               background: var(--bg-input); }
/* 이름 나열 목록 안에서 쓰는 작은 무대 — .bi-loading·.bi-modal-ov 처럼
 * width/height 100% 로 부모를 덮는 규격을 여기 가둔다. */
/* ⚠ 고정 140×34 로 가두면 **견본이 안 보인다** — 117개가 그렇게 눌려 있었다(2026-08-13).
 *   무대는 «넘치는 것을 막는» 울타리지 «크기를 정하는» 상자가 아니다.
 *   자기 크기대로 보여주되 위·아래로만 한도를 둔다. */
.sg2doc-stage--mini{
    display: inline-block; vertical-align: top;
    width: auto; height: auto;
    min-width: 40px; min-height: 28px;
    max-width: 320px; max-height: 120px;
}

/* =========================================================
   §40-2-1 발송 팝업 3단 — 되살림 (2026-08-12)
   ---------------------------------------------------------
   SPEC-SINGLE-USE 가 이걸 '한 곳 전용' 으로 봤다. 판정이 **팝업 전체를 한 덩어리**로
   묶어 세기 때문이다 — 실제로는 popup_layer_sms 와 _lms 둘이 공유하는 규격이다.
   빼고 나니 두 팝업에서 가로넘침 56건이 났다(L2-P 실측).
   ⚠ 사용처 판정을 '팝업' 하나로 뭉개면 팝업끼리 공유하는 규격이 전용으로 보인다.
   ========================================================= */
/* 발송 팝업 바깥 감싸개 — 폰 목업(.bi-msgprev-phone--aside, 250px)과 **다른 것**이다.
 * 2026-08-12: 인라인 정리 때 이 자리에 --aside 를 잘못 붙여 840px 안내 박스가
 * 250px 기둥 안에 갇혔고 가로넘침 56건이 났다(L2-P 실측). */
/* ⚠ 2026-08-12: float + 고정폭(534+58+250)이라 870px 창을 구조적으로 넘쳤다.
 *   규격 입력(§21)이 옛 25px 입력보다 커지자 넘침이 더 늘었다 — 값을 되돌릴 게 아니라
 *   배치를 §40-10 프리미티브 방식으로 바꾼다. 폰 목업만 고정폭, 본문은 남는 폭을 쓴다. */
.bi-msgsend__wrap  { background: var(--bg-card); display: flex; flex-wrap: wrap; align-items: flex-start;
                     gap: var(--space-4); padding: var(--space-4); box-sizing: border-box; width: 100%; }
.bi-msgsend__form  { width: 200px; }
.bi-msgsend__left  { font-size: var(--fs-sm); flex: 1 1 320px; min-width: 0; }
.bi-msgsend__mid   { flex: 0 0 58px; }
.bi-msgprev-phone--aside { flex: 0 0 250px; width: 250px; }

/* §40-2-1 발송 팝업 — sms·lms **둘이 공유**하는 규격. SPEC-SINGLE-USE 가 팝업을
 * 한 덩어리로 세는 바람에 전용으로 보여 빠졌다가 되살렸다(2026-08-12). */
.bi-msgsend__recv{ padding: var(--space-4_5, 18px); flex: 1 1 240px; min-width: 0; height: 400px; box-sizing: border-box; }
.bi-msgsend__vline{ margin: auto; height: 460px; width: 1px; border-left: 1px solid var(--border-base); }
.bi-msgsend__notice{ box-sizing: border-box; padding: var(--space-2_5); border: 1px solid var(--border-base);
                      height: auto; background: var(--bg-input); box-sizing: border-box; }
.bi-msgsend__list{ width: 96%; height: 368px; }
.bi-msgsend__dot{ margin: auto; height: 10px; width: 10px; background-image: url('/img/page/line-cicle.gif'); }
.bi-msgsend__caption{ font-size: var(--fs-sm); background-color: var(--bg-input); font-weight: var(--fw-bold);
                       color: var(--txt-muted); padding: var(--space-1_5) 0; }
.bi-msgprev-phone__body--a  { height: 188px; padding-top: var(--space-10, 40px); text-align: center; background-image: url("/img/page/bgSmsInputA.gif"); }
.bi-msgprev-phone__body--ph { height: 176px; text-align: center; background-image: url("/img/page/bgPhoneBody.gif"); }
.bi-msgprev-phone__body--add{ width: 210px; margin: auto; height: 176px; padding-top: var(--space-6); text-align: center; background-image: url("/img/page/bgSmsInputAdd.gif"); }
.bi-msgprev-phone__ta--sm   { width: 185px; height: 120px; overflow: hidden; line-height: 16px; letter-spacing: -0.5pt; word-wrap: break-word; font-family: 돋움체; background-color: transparent; border: 0; cursor: pointer; }
.bi-msgprev-phone__size--sm { width: 85%; text-align: right; padding-top: var(--space-1); }
.bi-msgprev-phone__body--lms2{ height: 363px; padding-top: var(--space-10); text-align: center;
                                background-image: url('/img/page/bgSmsInputB.gif'); }

/* ── lib/js·src 가 찍어내는 마크업의 규격 (2026-08-12 복구) ─────────
 * list_pages()·행 체크·컬럼배치 드롭다운·팝업 헤더는 **공통 JS 가 문자열로**
 * 만든다. 규격 사용처 계산이 template/ 만 보던 때 "한 화면 전용"으로 오인돼
 * 지워졌다 → 되살린다. **지우기 전에 lib/js·src 도 사용처로 세라.**
 * ──────────────────────────────────────────────────────────────── */
.bi-log-row--w7   { grid-template-columns: repeat(7,  minmax(80px, 1fr)); }
.bi-log-row--w12  { grid-template-columns: repeat(12, minmax(80px, 1fr)); }
.bi-log-row--w19  { grid-template-columns: repeat(19, minmax(80px, 1fr)); }
.bi-pop-head-left { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.bi-pop-head-ico {
    width: 32px; height: 32px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: var(--brand-blue-light); color: var(--brand-blue);
    border-radius: var(--radius-md); font-size: var(--fs-md);
}
.bi-pop-head .bi-pop-head-ico i.fal { font-weight: 300; }
/* 스타일보드 §06 — 닫기 26×26(2026-08-25). 32 는 헤더에서 과하게 컸다. */
.bi-pop-head-close {
    width: var(--pop-close); height: var(--pop-close); flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    border: 0; background: none;                 /* <button> 로도 쓰이므로 리셋 */
    border-radius: var(--radius-md); color: var(--txt-muted); font-size: var(--fs-lg);
    cursor: pointer; transition: var(--transition-base);
}
.bi-pop-head-close:hover { background: var(--border-light); color: var(--txt-primary); }
/* 페이징 줄 — 이전·숫자·다음이 서로 붙지 않게 (사용자 2026-08-12).
 * 감싸개에 배치 규격이 없어 버튼들이 맞붙어 있었다. 간격은 눈금(--space-1_5=6px).
 * §40-10 .bi-row 로도 되지만, 이 줄은 **공통 JS 가 찍는 고정 구조**라 이름을 준다. */
.bi-pg-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--space-1_5);
    padding: var(--space-2_5) 0;
}
.bi-pg-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-1_5);
    min-width: 32px;
    height: 32px;
    padding: 0 var(--space-2_5);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-md);
    background: var(--bg-card);
    font-size: var(--fs-base);
    font-weight: var(--fw-medium);
    color: var(--txt-secondary);
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s;
    line-height: 1;
    white-space: nowrap;
    box-sizing: border-box;
    user-select: none;
}
.bi-pg-btn:hover {
    background: var(--bg-input);
    border-color: var(--gray-300);
}
.bi-pg-btn--active {
    background: var(--brand-blue);
    border-color: var(--brand-blue);
    color: var(--bg-card);
    cursor: default;
}
.bi-pg-btn--disabled {
    color: var(--gray-300);
    cursor: default;
    pointer-events: none;
}
.bi-ra-col-dropdown {
    position: absolute;
    top: 42px; right: 0;
    min-width: 240px; max-height: 380px;
    display: flex; flex-direction: column;
    background: var(--bg-card);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-lg);
    padding: var(--space-2) 0;
    z-index: 30;
    overflow: hidden;
}
.bi-ra-col-dropdown[hidden] { display: none; }
.bi-ra-col-dropdown__header {
    padding: var(--space-1_5) var(--space-3_5) var(--space-2);
    font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--txt-muted);
    border-bottom: 1px solid var(--border-light);
    margin-bottom: var(--space-1);
}
.bi-ra-col-list {
    list-style: none; margin: 0; padding: 0;
    flex: 1 1 auto; overflow-y: auto; max-height: 280px;
}
.bi-ra-col-list::-webkit-scrollbar { width: 8px; }
.bi-ra-col-list::-webkit-scrollbar-thumb { background: var(--gray-300); border-radius: var(--radius-sm); }
.bi-ra-col-list::-webkit-scrollbar-thumb:hover { background: var(--txt-disabled); }
.bi-ra-col-list::-webkit-scrollbar-track { background: transparent; }
.bi-ra-col-list__row {
    display: flex; align-items: center; justify-content: space-between;
    transition: background .12s;
}
.bi-ra-col-list__row:hover { background: var(--bg-input); }
.bi-ra-col-list__item {
    display: flex; align-items: center; gap: var(--space-2_5);
    padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3_5);
    font-size: var(--fs-base); color: var(--txt-primary); cursor: pointer;
    flex: 1 1 auto; min-width: 0;
    transition: color .12s;
}
.bi-ra-col-list__item input[type=checkbox] {
    width: 14px; height: 14px;
    accent-color: var(--brand-blue, var(--brand-blue));
    margin: 0; cursor: pointer; flex-shrink: 0;
    visibility: visible; display: inline-block; /* style.css 글로벌 체크박스 숨김 무력화 */
}
.bi-ra-col-list__item > span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bi-ra-col-list__item.is-hidden { color: var(--txt-disabled); }
.bi-ra-col-list__item.is-hidden > span { text-decoration: line-through; text-decoration-color: var(--gray-300); }
.bi-ra-col-list__moves { display: inline-flex; align-items: center; gap: var(--space-0_5); padding-right: var(--space-2); flex-shrink: 0; }
.bi-ra-col-move {
    width: 22px; height: 22px;
    display: inline-flex; align-items: center; justify-content: center;
    background: transparent; border: 1px solid transparent; border-radius: var(--radius-md);
    color: var(--txt-muted); cursor: pointer; font-size: var(--fs-xs); padding: 0;
    transition: background .12s, color .12s, border-color .12s;
}
.bi-ra-col-move:hover { background: var(--bg-card); border-color: var(--border-base); color: var(--brand-blue, var(--brand-blue)); }
.bi-ra-col-dropdown__divider { height: 1px; background: var(--border-light); margin: var(--space-1_5) 0; }
.bi-ra-col-dropdown__reset {
    width: calc(100% - 12px); margin: 0 var(--space-1_5); padding: var(--space-2) var(--space-2_5);
    background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-lg);
    color: var(--color-danger); font-size: var(--fs-sm); font-weight: var(--fw-semibold); text-align: center; cursor: pointer;
    transition: background .15s, border-color .15s;
}
.bi-ra-col-dropdown__reset:hover { background: var(--color-danger-50); border-color: var(--color-danger-200); }
.bi-ra-col-dropdown__reset i { margin-right: var(--space-1); }
.bi-erp-selected {
    display: inline-flex; align-items: center; gap: var(--space-1);
    font-size: var(--fs-base); font-weight: var(--fw-semibold);
    color: var(--txt-muted); margin-right: var(--space-1); white-space: nowrap;
}
.bi-erp-selected b { color: var(--brand-blue); font-weight: var(--fw-extrabold); }
.bi-erp-selected.is-on { color: var(--txt-primary); }
.bi-rowchk { width: 16px; height: 16px; margin: 0; cursor: pointer; accent-color: var(--brand-blue); vertical-align: middle; }
/* 스타일보드 §07 해부도 — 헤더 여백 14·18(2026-08-25). 전 10·16 이라 헤더가 4px 얕았다. */
.bi-pop-head--compact{ padding: var(--pop-head-pad-y) var(--pop-head-pad-x); }   /* 보드 §07 — 14·18 */
.bi-pop-head--compact .bi-pop-head-left{ gap: var(--pop-head-gap); }
/* 스타일보드 Don't 첫 줄 «아이콘에 색을 넣지 않는다 — 헤더 #9CA3AF, 닫기 #6B7280 고정».
 * 파란 아이콘은 «눌러야 할 곳» 으로 읽힌다 — 헤더는 조용해야 한다(2026-08-25). */
.bi-pop-head--compact .bi-pop-head-ico{
    /* 보드 §07 «아이콘(28box · 회색)» — 상자 크기가 헤더 높이(56)를 만든다.
       auto 로 두면 글자 높이(16)만큼만 차지해 헤더가 54 로 얕아졌다(2026-08-25). */
    width: 28px; height: 28px; border-radius: 0;
    display: inline-flex; align-items: center; justify-content: center;
    background: none; color: var(--pop-ico); font-size: var(--fs-lg);
}

/* ── §40-13 인증 화면 — 로그인은 셸 밖 단독 페이지 (2026-08-12 복구) ──────
 * ⚠ 한 화면에서만 쓴다. 그래서 "한 곳 전용" 판정에 걸려 걷혔고 로그인이 무너졌다.
 *   단독 페이지의 규격은 **그 화면 전체가 그 규격**이라 사용처가 하나인 게 정상이다.
 *   지우기 전에 물어야 할 것은 "몇 곳에서 쓰나" 가 아니라 "지우면 무엇이 남나" 다.
 * ──────────────────────────────────────────────────────────────── */
.bi-auth {
    background: var(--bg-page);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-6);
    box-sizing: border-box;
}
body.bi-auth { min-height: 100vh; margin: 0; }
.bi-auth__wrap  { width: 100%; max-width: 420px; }
.bi-auth__logo  { display: flex; justify-content: center; margin-bottom: var(--space-5); }
.bi-auth__logo img { max-width: 100%; height: auto; }
.bi-auth__head  { text-align: center; margin-bottom: var(--space-6); }
/* ⚠ 로그인 카드는 **write 폼이 아니다**. §21 의 .bi-erp-card > form 여백(16·24·32)을 물려받아
 *   로고·제목은 카드 모서리에 붙고 폼만 안쪽으로 들어가 있었다 — 위 0 / 아래 32 로 비대칭이었고,
 *   제목과 첫 입력칸 사이만 40px(24 margin + 16 padding)로 혼자 벌어졌다(사용자 지적 2026-08-13).
 *   여백은 **카드가 사방 균일하게** 맡고, 폼은 자기 여백을 갖지 않는다.
 *   세로 리듬: 카드 32 → 로고 20 → 제목·부제 24 → 칸 12 → 버튼 12 → 옵션 16 → 카드 32 */
.bi-auth__wrap .bi-erp-card { padding: var(--space-8); }
.bi-auth__wrap .bi-erp-card > form { padding: 0; overflow-y: visible; }
.bi-auth__form  { margin: 0; }
.bi-auth__head > * { margin: 0; }
.bi-auth__head { display: flex; flex-direction: column; gap: var(--space-2); }
.bi-auth__field { margin-bottom: var(--space-3); }
/* 2026-08-13 로그인 버튼과 체크박스가 **간격 0** 으로 맞붙어 있었다(버튼 아래 616 = 그룹 위 616).
 *   확정 액션과 옵션은 다른 묶음이다 — 칸 사이(12px)보다 한 칸 넓게 띄운다. */
.bi-auth__form .bi-checkbox-group { margin-top: var(--space-4); }
.bi-auth__alert {
    display: none;
    margin-bottom: var(--space-3_5);
    padding: var(--space-2_5) var(--space-3);
    background: var(--color-danger-50);
    border: 1px solid var(--color-danger-200);
    border-radius: var(--radius-xl);
    font-size: var(--fs-sm);
    line-height: 1.4;
    color: var(--color-danger);
}
.bi-auth__alert.is-show { display: block; }
.bi-auth__brand      { display: flex; justify-content: center; align-items: flex-end; }
.bi-auth__brand-star { align-self: flex-end; margin-bottom: var(--space-1); width: 54px; height: 54px; }
.bi-auth__brand-txt  { margin-left: var(--space-1_5); }
.bi-auth__brand-name {
    display: flex;
    font-size: var(--fs-3xl);
    font-weight: var(--fw-semibold);
    line-height: 35px;
    letter-spacing: -0.01em;
}
.bi-auth__brand-a   { color: var(--color-info-600); }
.bi-auth__brand-dot { color: var(--txt-muted); }
.bi-auth__brand-b   { color: var(--color-info-500); }   /* 구 var(--color-cyan-500, --color-info-400) — 둘 다 정의 없어 무효였다(2026-08-25) */
.bi-auth__brand-sub {
    font-size: var(--fs-base);
    font-weight: var(--fw-medium);
    margin-left: var(--space-0_5);
    letter-spacing: -0.02em;
    color: color-mix(in srgb, var(--black) 50%, transparent);
}

/* ════════════════════════════════════════════════════════════
   되살린 규격 — "한 곳 전용" 판정으로 걷혔던 것들 (2026-08-12)

   ⚠ 지우기 전에 물어야 할 것은 «몇 곳에서 쓰나» 가 아니라 «지우면 무엇이 남나» 다.
     로그인·디자이너 탭·예약 일정표·AI 메시지 발송은 사용처가 하나지만
     그 화면의 **구조 자체**였다. 걷어내니 화면이 통째로 무너졌다.
   규격화는 다시 한다 — 기준은 «같은 것이 둘 이상 있는가»(SPEC-DUP) 다.
   ════════════════════════════════════════════════════════════ */
.bi-logo-img { width: 70%; height: auto; margin-top: var(--space-2); }
.logo.bi-logo-light {
    background: var(--bg-card);
    border-bottom: 1px solid var(--border-light);   /* 헤더와의 경계 (mockup) */
}
.bi-logo-light .h_log_box { padding-right: 0; gap: var(--space-2); }
.bi-logo-light .h_shooting_star { width: 26px; height: 26px; margin-bottom: 0; align-self: center; }
.bi-logo-light .h_shooting_star svg .fa-primary   { fill: var(--brand-navy); }
.bi-logo-light .h_shooting_star svg .fa-secondary { fill: var(--brand-blue); }
.bi-logo-light .h_logo_wirte_top {
    color: var(--brand-navy);
    font-size: var(--fs-xl);
    font-weight: var(--fw-extrabold);
    margin-bottom: 0;
}
.bi-row-center     { display: flex; align-items: center; justify-content: center; }
.bi-row--shrink-0  { flex-shrink: 0; }
.bi-row--gap-10    { --bi-row-gap: 10px; }
.bi-col--gap-5     { --bi-col-gap: 5px; }
.bi-col--gap-14    { --bi-col-gap: 14px; }.bi-segment--fill           { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--space-1); }   /* 버튼 균등폭(2등분 등) */
.bi-modal__body { padding: var(--space-5) var(--space-5); overflow-y: auto; }.bookmark-container.bi-bm {
    position: fixed;
    right: 24px;
    bottom: 24px;
    left: auto;
    width: auto;
    height: auto;
    min-height: 0;
    background: transparent;
    box-shadow: none;
    border: none;
    border-radius: 0;
    overflow: visible;
    transition: none;
    z-index: 60;
}
.bookmark-container.bi-bm.expanded { width: auto; min-height: 0; }
.bookmark-container.bi-bm:hover:not(.expanded):not(.collapsing) {
    width: auto;
    box-shadow: none;
}
.bi-bm-fab {
    position: relative;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--brand-navy) 0%, var(--brand-blue) 100%);
    color: var(--bg-card);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-xl);
    cursor: pointer;
    box-shadow: var(--shadow-lg);
    opacity: 1;
    visibility: visible;
    transition: transform .15s ease, box-shadow .15s ease;
    animation: bi-bm-fab-float 3s ease-in-out infinite;
}
.bookmark-container.bi-bm:hover .bi-bm-fab { transform: scale(1.06); box-shadow: var(--shadow-lg); }
.bi-bm-fab::before { content: none; }   /* 구 .bookmark-icon::before(28px) 제거 */
.bookmark-container.bi-bm.expanded .bi-bm-fab { display: none; }
.bi-bm-fab-dot {
    position: absolute;
    top: 9px;
    right: 9px;
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: var(--color-danger);
    border: 2px solid var(--white);
}
.bi-bm-fab-dot::after {
    content: '';
    position: absolute;
    inset: -3px;
    border-radius: 50%;
    border: 2px solid color-mix(in srgb, var(--color-danger) 60%, transparent);
    animation: bi-bm-pulse 1.8s ease-out infinite;
}
.bi-bm-card {
    /* 구 .bookmark-content(absolute inset, opacity 토글) 무력화 */
    position: static;
    top: auto; left: auto;
    display: none;
    width: 360px;
    max-width: calc(100vw - 48px);
    padding: 0;   /* 구 .bookmark-content padding:20px 제거 (내부에서 패딩) */
    background: var(--bg-card);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-2xl);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    flex-direction: column;
}
.bookmark-container.bi-bm.expanded .bi-bm-card {
    display: flex;
    animation: bi-bm-card-in .18s ease;
}
.bi-bm-card-head {
    display: flex;
    align-items: center;
    gap: var(--space-2_5);
    padding: var(--space-3_5) var(--space-4);
    background: var(--gray-50);
    border-bottom: 1px solid var(--gray-100);
}
.bi-bm-card-head-ico {
    width: 30px; height: 30px;
    flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--brand-blue) 10%, transparent);
    color: var(--brand-blue);
    border-radius: var(--radius-lg);
    font-size: var(--fs-md);
}
.bi-bm-card-title {
    font-size: var(--fs-md);
    font-weight: var(--fw-extrabold);
    color: var(--txt-primary);
    margin: 0;
    padding: 0;            /* 구 .bookmark-title padding:10px 0 제거 */
    border-bottom: none;   /* 구 .bookmark-title 밑줄 제거 */
}
.bi-bm-card-msg {
    padding: var(--space-3_5) var(--space-4);
    margin: 0;             /* 구 .bookmark-message margin-bottom:20px 제거 */
    font-size: var(--fs-base);
    line-height: 1.65;
    color: var(--gray-600);
    max-height: 240px;
    overflow-y: auto;
}
.bi-bm-card-msg .highlight-date {
    color: var(--brand-blue);
    font-weight: var(--fw-bold);
}
.bi-bm-card-actions {
    display: flex;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border-top: 1px solid var(--gray-100);
}
.bi-bm-btn {
    padding: var(--space-2_5) var(--space-3_5);
    border: 1px solid transparent;
    border-radius: var(--radius-xl);
    font-size: var(--fs-base);
    font-weight: var(--fw-bold);
    cursor: pointer;
    transition: background .15s, color .15s, border-color .15s;
}
.bi-bm-btn--ghost {
    flex: 0 0 84px;   /* 구 .btn-close flex:0.5 무력화 */
    background: var(--bg-card);
    color: var(--txt-muted);
    border-color: var(--border-base);
}
.bi-bm-btn--ghost:hover { background: var(--border-light); color: var(--txt-secondary); }
.bi-bm-btn--send {
    flex: 1;
    background: var(--brand-blue);
    color: var(--bg-card);
}
.bi-bm-btn--send:hover { background: var(--brand-blue-hover); transform: none; box-shadow: none; }
.bi-marketing-select {
    width: 140px;
    padding: 0 var(--space-2);
    background: var(--bg-input);
}
.bi-marketing-branch-select {
    width: 200px;
    padding: 0 var(--space-2);
    background: var(--bg-input);
}.bi-table-wrap  { width: 100%; overflow-x: auto; }
.bi-field-row    { margin: var(--space-2) 0; }
.bi-avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 36px; height: 36px; border-radius: var(--radius-full);
    background: var(--brand-lavender); color: var(--brand-blue);
    font-size: var(--fs-sm); font-weight: var(--fw-bold); flex-shrink: 0;
}
.bi-dropdown__item {
    padding: var(--space-1_5) var(--space-3); font-size: var(--fs-base);
    color: var(--txt-secondary); border-radius: var(--radius-md); cursor: pointer;
}
.bi-dropdown__item:hover { background: var(--bg-input); color: var(--txt-primary); }
.bi-dropdown__item--danger { color: var(--color-danger-600); }
.bi-emptybox__sub   { margin: 0; font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-popover--right { right: 0; left: auto; }
.bi-popover-list { list-style: none; padding: var(--space-1_5); margin: 0; }
.bi-popover-item { padding-bottom: var(--space-2_5); border-bottom: 1px solid var(--border-light); }
.bi-popover-item:last-child { border-bottom: none; padding-bottom: 0; }
.bi-popover-name { display: inline-block; background: var(--color-info-100); color: var(--brand-blue); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm); font-weight: var(--fw-bold); }
.bi-popover-desc { margin-top: var(--space-1); font-size: var(--fs-sm); color: var(--txt-muted); }
/* 2026-09-11 — 팝오버 닫기 버튼. 규격에 없어서 <button> 이 브라우저 기본꼴(회색 네모)로
   패널 아래에 덩그러니 놓여 있었다(자동문자 설정 «변수 도움말»).
   같은 자리·같은 크기 규약을 쓰는 팝업 헤더 닫기(.bi-pop-head-close)와 결을 맞추되,
   패널 오른쪽 위에 겹쳐 세운다 — 목록 줄을 밀어내지 않는다.
   styleguide2 §팝오버에 전시해 등록한다. */
.bi-popover-close {
    position: absolute; top: var(--space-1_5); right: var(--space-1_5);
    width: 22px; height: 22px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    border: 0; background: none; padding: 0;
    border-radius: var(--radius-md); color: var(--txt-muted); font-size: var(--fs-sm);
    cursor: pointer; transition: var(--transition-base);
}
.bi-popover-close:hover { background: var(--border-light); color: var(--txt-primary); }
.bi-filter-card select.bi-input, .bi-erp-filter select.bi-input { padding: 0 var(--space-2); background: var(--bg-input); }
.bi-page .bi-grid-input {
    width: 100%;          /* 컬럼(셀) 폭에 맞춤 — 모듈별 폭 하드코딩 대신 컬럼 width 가 기준 */
    height: 30px;
    text-align: center;
    border: 1px solid var(--gray-300);
    border-radius: var(--radius-md);
    background: var(--bg-card);
    font-size: var(--fs-base);
    color: var(--txt-primary);
    padding: 0 var(--space-1_5);
    outline: none;
    box-sizing: border-box;
    cursor: text;
    transition: border-color .15s, box-shadow .15s;
}
.bi-page .bi-grid-input:hover  { border-color: var(--txt-disabled); }
.bi-page .bi-grid-input:focus  { border-color: var(--brand-blue); box-shadow: var(--ring-focus); }
.bi-page .bi-grid-input--right { text-align: right; }
/* (구 .bi-date-notice — 고객메모내역의 「* 데이터 수집 기간… 」 안내문 전용이었다.
   2026-08-25 사용자 지시로 그 문구를 빼자 **사용처가 0** 이 되어 같이 지웠다.
   같은 자리가 다시 필요하면 규격으로 새로 등록한다 — 죽은 채로 두지 않는다.) */

/* ── 디자이너 필터 필바 ──────────────────────────────────────────
 * ⚠ 2026-08-21 두 가지를 고쳤다(사용자 지적).
 *   ① 아래 2px 밑줄 — 밑줄 탭(underline tab)의 잔재였다. 이건 **알약(pill)** 이라
 *      밑줄이 필요 없고, 바로 아래 필터카드의 구분선과 겹쳐 **두 줄로** 보였다.
 *   ② 좌우 화살표 — 디자이너가 적어 넘치지 않는데도 항상 떠 있었다.
 *      화살표는 «넘쳐서 못 보는 게 있다» 는 신호다. 안 넘치면 신호가 아니라 잡음이다.
 *      → 넘칠 때만 .is-scrollable 이 붙고, 그때만 보인다. */
.bi-pillbar { display: flex; align-items: center; gap: var(--space-1); height: 36px; overflow: hidden; }
.bi-pillbar:not(.is-scrollable) .bi-pillbar__arrow { display: none; }
.bi-pillbar__scroll { flex: 1; overflow-x: auto; display: flex; align-items: center; gap: var(--space-1_5); scrollbar-width: none; }
.bi-pillbar__scroll::-webkit-scrollbar { display: none; }
.bi-pillbar__pill { padding: 0; font-weight: var(--fw-normal); cursor: pointer; flex-shrink: 0; }
.bi-pillbar__pill:first-child { padding: 0; }
/* 2026-08-24 — 상태 탭(.bi-erp-tab)과 같은 크기로 맞췄다(사용자 지시).
 * 둘 다 «필터 줄에 서는 알약» 이라 같은 것이어야 한다. 실측은 23px vs 32px 로 갈려 있었다.
 * 높이는 여백이 아니라 height 로 고정한다 — 여백으로 정하면 글자 길이·자식 유무에 따라 흔들린다. */
.bi-pillbar__pill span {
    display: inline-flex; align-items: center;
    height: 32px; padding: 0 var(--space-3_5);
    font-size: var(--fs-sm); font-weight: var(--fw-medium);
    border-radius: var(--radius-full); border: 1px solid var(--border-base);
    background: var(--bg-card); color: var(--txt-muted);
    white-space: nowrap; transition: all .15s;
}
.bi-pillbar__pill span:hover { background: var(--bg-input); border-color: var(--gray-300); }
.bi-pillbar__pill span.bi-pillbar__pill-active {
    background: var(--brand-navy); color: var(--bg-card);
    border-color: var(--brand-navy); border-bottom: none;
    box-shadow: var(--shadow-md);
}.bi-filter-card {
    background: var(--bg-card);
    padding: var(--space-5);
    border-radius: var(--radius-xl);
    border: 1px solid var(--border-base);
    box-shadow: var(--shadow-sm);
    flex-shrink: 0;
}
.bi-filter-card--compact { padding: var(--space-3) var(--space-5); }   /* 밀집 레이아웃(캘린더·매트릭스 컨트롤 행) */
.bi-filter-card--hidden  { display: none; }          /* 필터카드 숨김(DOM 유지, JS 토글) */
.bi-filter-card input[type="text"].bi-input {
    background: var(--bg-card);
    height: 36px;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}
.bi-filter-card input[type="text"].bi-input:focus {
    border-color: var(--brand-blue);
    box-shadow: var(--ring-focus);
    background: var(--bg-card);
}
.bi-res-pagination {
    flex-shrink: 0;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-top: 1px solid var(--border-base);
    background: var(--bg-card);
}.bi-page .scale-title {
    fill: var(--txt-muted);
    font-weight: 600;
}
.bi-page .bar-text {
    fill: var(--txt-muted);
}.bi-page .main-scale {
    stroke: var(--border-base);
}.bi-anl-chart-box--tall  { height: 320px; }
.bi-anl-chart-box--xtall { height: 420px; }
.bi-anl-grid { width: 100%; overflow: hidden; }
.bi-anl-grid--sm { min-height: 79px; }
.bi-anl-grid--md { min-height: 153px; }
.bi-anl-matrix { border: 1px solid var(--border-base); border-radius: var(--radius-lg); overflow: hidden; background: var(--bg-card); max-width: 720px; }
.bi-anl-matrix-row { display: flex; border-bottom: 1px solid var(--border-light); }
.bi-anl-matrix-row:last-child { border-bottom: none; }
.bi-anl-matrix-row--head { background: var(--bg-input); font-weight: var(--fw-semibold); color: var(--txt-primary); }
.bi-anl-matrix-cell { flex: 1; padding: var(--space-2_5) var(--space-4); text-align: right; font-size: var(--fs-base); color: var(--txt-secondary); box-sizing: border-box; border-left: 1px solid var(--border-light); }
.bi-anl-matrix-cell:first-child { border-left: none; }
.bi-anl-matrix-cell--label { background: var(--bg-input); }.bi-erp-divider { border-top: 1px solid var(--gray-100); padding-top: var(--space-3); margin-top: 0; }
.bi-erp-tab-count {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 18px; height: 16px; padding: 0 var(--space-1_5);
    border-radius: var(--radius-full); background: var(--border-light); color: var(--txt-muted);
    font-size: var(--fs-2xs); font-weight: var(--fw-bold); line-height: 1;
}
.bi-erp-tab.is-active .bi-erp-tab-count { background: color-mix(in srgb, var(--white) 20%, transparent); color: var(--bg-card); }
   17개 모듈의 .bi-{x}-total/-summary 중복 → 이 공통 클래스로 대체 예정.
/* ⚠ 2026-08-21 — 합계 클래스는 dhx `mark` 훅으로 «셀» 에 붙는다(행이 아니다).
 * 행 셀렉터만 있으면 배경만 먹고 굵기가 안 먹는다 → 셀 자신도 잡는다.
 * (그 전에는 `cellCss` 로 걸어 두어 **아무 데도 안 붙고 있었다** — 12개 리포트가 그랬다) */
.bi-grid-total,
.bi-grid-total .dhx_grid-cell,
.dhx_grid-cell.bi-grid-total {
    background: var(--border-light);
    font-weight: var(--fw-bold);
    color: var(--txt-primary);
}
.bi-permmatrix-group-select { max-width: 340px; }
.bi-permmatrix-matrix-body { padding: 0; }
.bi-permmatrix-matrix { background: var(--bg-card); overflow: hidden; }
.bi-permmatrix-row:not(.bi-permmatrix-row--head):hover { background: var(--color-info-50); }
.bi-permmatrix-row--head {
    background: var(--bg-input); border-bottom: 1px solid var(--border-base);
    font-weight: var(--fw-semibold); font-size: var(--fs-sm);
}
.bi-permmatrix-row--head .bi-permmatrix-cell {
    padding: var(--space-3) var(--space-2); text-align: center; color: var(--txt-muted); font-weight: var(--fw-semibold);
    display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1_5);
}
.bi-permmatrix-row--head .bi-permmatrix-cell--name { justify-content: flex-start; text-align: left; padding-left: var(--space-5); color: var(--txt-secondary); }
.bi-permmatrix-row--head .bi-permmatrix-cell i { font-size: var(--fs-xs); color: var(--txt-disabled); }
.bi-permmatrix-row--head .bi-permmatrix-cell + .bi-permmatrix-cell { box-shadow: inset 1px 0 0 var(--gray-100); }
.bi-permmatrix-cell { padding: var(--space-3) var(--space-2); text-align: center; font-size: var(--fs-base); color: var(--txt-secondary); }
.bi-permmatrix-cell--name { text-align: left; padding-left: var(--space-5); font-weight: var(--fw-semibold); color: var(--gray-800); }
.bi-permmatrix-row:not(.bi-permmatrix-row--head) .bi-permmatrix-cell--all { background: color-mix(in srgb, var(--brand-navy) 5%, transparent); }
.bi-permmatrix-category {
    display: flex; align-items: center; gap: var(--space-2);
    background: var(--color-indigo-50); color: var(--brand-blue); font-weight: var(--fw-extrabold); font-size: var(--fs-xs);
    padding: var(--space-2_5) var(--space-5); border-bottom: 1px solid var(--border-base);
    text-transform: uppercase; letter-spacing: .04em;
}
.bi-permmatrix-category::before {
    content: '\f0c9'; font-family: 'Font Awesome 5 Pro'; font-weight: var(--fw-black);
    font-size: var(--fs-xs); opacity: .65;
}
.bi-permmatrix-check {
    display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1_5);
    cursor: pointer; margin: 0;
}
.bi-permmatrix-check input[type="checkbox"] {
    visibility: visible; display: inline-block;
    width: 17px; height: 17px;
    accent-color: var(--brand-blue); cursor: pointer; margin: 0;
    position: static;
}
.bi-permmatrix-check input[type="checkbox"] + span { font-size: var(--fs-base); color: var(--txt-secondary); }
.bi-permmatrix-row--head .bi-permmatrix-check input[type="checkbox"] + span { color: var(--txt-muted); font-weight: var(--fw-semibold); }.bi-write-note { font-size: var(--fs-xs); color: var(--txt-muted); }
.bi-write-unit { font-size: var(--fs-base); color: var(--txt-muted); flex-shrink: 0; }
.bi-write-req { color: var(--color-danger); margin-left: var(--space-0_5); }.bi-write-field--quarter { flex: 0 0 calc(25% - 10px); max-width: calc(25% - 10px); }
.bi-write-type-label { min-width: 120px; font-weight: var(--fw-semibold); color: var(--gray-600); }
.bi-write-divider   { border-top: 1px solid var(--border-base); padding-top: var(--space-3); margin-top: var(--space-3); }.bi-write-notice--block { display: block; line-height: 1.8; align-items: initial; }
.bi-write-split__side { flex: 0 0 300px; }
/* 2026-09-02 — 미리보기(폰·알림톡)는 둘 다 250 인데 칸이 300 이라 오른쪽에 50px 이 죽어 있었다.
   그 죽은 공간이 gap 16 과 겹쳐 「간격이 너무 넓다」 로 보였다(사용자 지적).
   기존 규칙은 그대로 두고 «내용 폭에 맞춘 칸» 을 modifier 로 더한다. */
.bi-write-split__side--fit { flex: 0 0 250px; }
.bi-write-split__main { flex: 1; min-width: 360px; }.bi-desk__chart, .bi-row { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.bi-bk-subbar {
    height: 44px; flex-shrink: 0; box-sizing: border-box;
    display: flex; align-items: center; justify-content: space-between;
    padding: 0 var(--space-4);
    background: var(--bg-card);
    border: 1px solid color-mix(in srgb, var(--border-base) 90%, transparent); border-radius: var(--radius-2xl);
    box-shadow: var(--shadow-sm);
}
.bi-bki-status.sp_status1 { background: var(--color-success-500); }
.bi-bki-status.sp_status2 { background: var(--color-info-600); }
.bi-bki-status.sp_status4 { background: var(--txt-muted); }.bi-bksch-emp-dot.dot-c0 { background: var(--color-indigo-500); }
.bi-bksch-emp-dot.dot-c1 { background: var(--color-purple-500); }
.bi-bksch-emp-dot.dot-c2 { background: var(--color-pink-500); }
.bi-bksch-emp-dot.dot-c3 { background: var(--color-success-500); }
.bi-bksch-emp-dot.dot-c4 { background: var(--color-warning); }
.bi-bksch-emp-dot.dot-c5 { background: var(--color-info-500); }
.bi-bksch-emp-dot.dot-c6 { background: var(--color-success-500); }
.bi-bksch-emp-dot.dot-c7 { background: var(--color-rose-500); }.bi-counter-select {
    height: 40px; padding: 0 var(--space-2_5); background: var(--bg-card);
    border: 1px solid var(--cc-line); border-radius: var(--radius-xl);
    font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--gray-800); outline: none; cursor: pointer;
}
.bi-counter-select:focus { border-color: var(--cc-blue); }
.bi-counter-wrap input[type="text"].bi-counter-input--search { padding-left: var(--space-10); }.bi-counter-foot-val--rose { color: var(--color-rose-500); font-weight: var(--fw-extrabold); }
.bi-counter-hcard {
    background: var(--bg-card); padding: var(--space-3); border-radius: var(--radius-xl); border: 1px solid var(--cc-line);
    box-shadow: var(--shadow-xs);
}
.bi-counter-hcard.is-dim { opacity: .8; border-color: var(--cc-line-l); }
.bi-counter-hcard__top {
    display: flex; justify-content: space-between; font-size: var(--fs-sm);
    padding-bottom: var(--space-1_5); border-bottom: 1px solid var(--cc-line-l); margin-bottom: var(--space-1_5);
}
.bi-counter-hcard__top strong { color: var(--gray-800); font-variant-numeric: tabular-nums; }
.bi-counter-hcard.is-dim .bi-counter-hcard__top strong { color: var(--cc-gray-l); }
.bi-counter-hcard__top span { color: var(--cc-gray-l); font-weight: var(--fw-bold); }
.bi-counter-hcard__name { font-weight: var(--fw-extrabold); color: var(--gray-800); font-size: var(--fs-md); margin: 0; }
.bi-counter-hcard.is-dim .bi-counter-hcard__name { color: var(--txt-muted); }
.bi-counter-hcard__amt { text-align: right; font-size: var(--fs-sm); color: var(--txt-muted); font-variant-numeric: tabular-nums; margin: var(--space-1) 0 0; font-weight: var(--fw-bold); }.bi-counter-pay-btn--pay { background: var(--color-npay); }
.bi-counter-pay-btn--pay:hover:not(:disabled) { filter: brightness(1.05); }.bi-bs-pro-td--disc  { text-align: right; }.bi-bs-pro-total-wrap .bi-bs-pro-input {
    flex: 1;
    width: 0;
    min-width: 0;
}
.bi-bs-pro-total-sep {
    color: var(--gray-300);
    font-size: var(--fs-xs);
    flex-shrink: 0;
    user-select: none;
}.bi-bs-bank-badge {
    font-size: var(--fs-xs);
    color: var(--txt-muted);
    background: var(--border-light);
    border-radius: var(--radius-xs);
    padding: var(--space-0_5) var(--space-1);
    margin-left: var(--space-1);
}
.bi-bs-pay-grid-2 .bi-bs-pay-btn {
    height: auto;
    min-height: 80px;
    font-size: var(--fs-md);
    font-weight: var(--fw-bold);
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    border-radius: var(--radius-xl);
    padding: var(--space-4) var(--space-2);
    box-shadow: var(--shadow-sm);
}
.bi-bs-pay-grid-2 .bi-bs-pay-btn:active { transform: scale(.97); }
.bi-bs-pay-grid-3 .bi-bs-pay-btn {
    height: 44px;
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
}
.bi-bs-counter .bi-bs-hidden-btn { display: none; }.bi-bs-counter .bi-counter-pay-btn.bi-bs-pay-btn--inactive { opacity: .4; pointer-events: none; }
.bi-bs-reg-box { width: 460px; max-width: 92vw; padding: var(--space-6); border-radius: var(--radius-2xl);   /* 2026-08-07 스케일 밖 24px → 16px 스냅 */ gap: var(--space-4); color: var(--txt-primary); }
.bi-bs-reg-head { display: flex; justify-content: space-between; align-items: center; padding-bottom: var(--space-2); border-bottom: 1px solid var(--border-light); }
.bi-bs-reg-icon { width: 34px; height: 34px; border-radius: 50%; background: var(--color-info-50); border: 1px solid var(--color-info-100); color: var(--brand-blue); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.bi-bs-reg-title { font-size: var(--fs-lg); font-weight: var(--fw-extrabold); color: var(--txt-primary); margin: 0; }
.bi-bs-reg-desc { font-size: var(--fs-sm); color: var(--txt-disabled); margin: var(--space-0_5) 0 0; }
.bi-bs-reg-close { width: 28px; height: 28px; border: 0; background: none; color: var(--txt-disabled); cursor: pointer; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
.bi-bs-reg-close:hover { color: var(--gray-600); background: var(--border-light); }
.bi-bs-reg-footer { display: flex; gap: var(--space-2_5); padding-top: var(--space-3_5); border-top: 1px solid var(--border-light); }
.bi-bs-reg-cancel  { flex: 1;   padding: var(--space-3); border-radius: var(--radius-xl); font-weight: var(--fw-extrabold); }
.bi-bs-reg-confirm { flex: 1.5; padding: var(--space-3); border-radius: var(--radius-xl); font-weight: var(--fw-extrabold); box-shadow: var(--shadow-md); }
.bi-bs-counter .bi-bs-pnl-more--split { display: flex; align-items: center; justify-content: space-between; }
.bi-bs-counter .bi-bs-pkg-sms-btn {
    display: inline-flex; align-items: center; gap: var(--space-1_5);
    padding: var(--space-1_5) var(--space-3); border-radius: var(--radius-lg); border: 1px solid var(--color-info-100);
    background: var(--color-info-50); color: var(--brand-blue); font-size: var(--fs-sm); font-weight: var(--fw-extrabold); cursor: pointer;
    transition: background .12s;
}
.bi-bs-counter .bi-bs-pkg-sms-btn:hover { background: var(--color-info-100); }.bi-bs-counter .bi-bs-pro-th--disc { width: 124px; text-align: center; }
/* 2026-08-26 — justify-content 는 flex 전용이라 table-cell 에선 안 먹는다 → text-align */
.bi-bs-counter .bi-bs-pro-td--disc { text-align: center; }
.bi-bs-counter .bi-counter-foot-val--rose { font-weight: var(--fw-black); }
.bi-bs-counter .bi-bs-vcard-cnt {
    font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--brand-blue);
    background: var(--color-info-50); border: 1px solid var(--color-info-100); border-radius: var(--radius-full);
    padding: var(--space-0_5) var(--space-2_5); white-space: nowrap; font-variant-numeric: tabular-nums;
}
.bi-bs-counter .bi-bs-vcard-cnt b { font-weight: var(--fw-black); font-size: var(--fs-sm); }
.bi-bs-counter .bi-bs-vcard-cnt--inf { color: var(--color-success); background: var(--color-success-50); border-color: var(--color-success-100); }
.bi-bs-counter .bi-bs-vcard-date { margin: var(--space-1_5) 0 0; font-size: var(--fs-xs); color: var(--txt-disabled); }
.bi-bs-counter .bi-bs-dock-btns--2 { grid-template-columns: 1fr 1fr; }
/* 선불권·포인트·접수 = **보조 결제/액션**. 규격 문서 §12-5: "현금·신용카드·선불권·접수증출력은
 * 색없음(일반형)". 2026-08-14: 실물이 연파랑 틴트라 문구와 달랐다 → **문서가 기준**이므로 색을 뺀다.
 * 색은 강조의 도구다 — 수단마다 색을 달리하면 "지금 눌러야 할 것"을 색으로 알 수 없다. */
.bi-bs-counter .bi-bs-dock-btn--recv  { background: var(--bg-card); color: var(--txt-secondary); border-color: var(--border-base); }
.bi-bs-counter .bi-bs-dock-btn--recv:hover  { background: var(--bg-input); }.bi-pop-hidden{ display: none; }
.bi-pop-cat-tools{ flex-shrink: 0; display: flex; flex-direction: column; gap: var(--space-2_5); margin-bottom: var(--space-3); }
/* ── 카탈로그 상단 — 보드 §08 «상품 추가» (2026-08-26 재정의) ─────────
 * 탭 그룹은 회색 카드 안에 가로로 놓인다. 칩은 그 아래 한 줄.
 * 예전 규칙은 레거시 li 클래스를 겨냥해 실물에 하나도 안 걸렸다. */
.bi-pop-catalog .bi-pop-seg{
    display: flex; gap: var(--pop-tab-gap); flex-wrap: wrap; margin: 0; list-style: none;
    background: var(--pop-line-soft); border: 1px solid var(--pop-line);
    border-radius: var(--radius-sm); padding: var(--space-2_5);
}
.bi-pop-catalog .bi-pop-seg > li{
    height: 32px; padding: 0 var(--space-4); display: inline-flex; align-items: center;
    border-radius: var(--pop-btn-r); background: var(--bg-card); border: 1px solid var(--pop-line);
    /* §71 12.5 는 토큰 밖 값이었다 — 눈에 안 띄지만 사다리 밖이다(단추 검사가 잡음) */
    font-size: var(--fs-sm); font-weight: var(--fw-extrabold); color: var(--txt-muted); cursor: pointer;
}
/* 2026-10-07 상품 없는 갈래 탭 감추기 — 위 li 의 display:inline-flex(0,2,1)가 .bi-pop-hidden(0,1,0)을 이긴다. pcTabPrune() 이 붙인다. */
.bi-pop-catalog .bi-pop-seg > li.bi-pop-hidden{ display: none; }
.bi-pop-catalog .bi-pop-seg > li:hover{ border-color: var(--gray-300); color: var(--txt-secondary); }
.bi-pop-catalog .bi-pop-seg > li.is-sel{ background: var(--brand-navy); border-color: var(--pop-tab-line); color: var(--bg-card); }
.bi-pop-seg > li > div{ float: none; padding: 0; }

.bi-pop-catalog .bi-pop-chip-ul{ display: flex; gap: var(--space-1_5); flex-wrap: wrap; margin: 0; padding: 9px 0 0 var(--space-2_5); list-style: none; }
.bi-pop-catalog .bi-pop-chip-ul > li{
    height: 28px; padding: 0 var(--pop-pill-pad-x); display: inline-flex; align-items: center;
    border-radius: var(--radius-full); background: var(--bg-card); border: 1px solid var(--pop-line);
    font-size: var(--pop-cnt-fs); font-weight: var(--fw-semibold); color: var(--txt-muted);
    cursor: pointer; white-space: nowrap;
}
.bi-pop-catalog .bi-pop-chip-ul > li:hover{ background: var(--pop-line-soft); }
.bi-pop-catalog .bi-pop-chip-ul > li.is-sel{ background: var(--pop-pill-bg); border-color: var(--pop-pill-line); color: var(--brand-blue); }
.bi-pop-chip-ul > li > div{ float: none; padding: 0; }

/* 상품 행 — 한 줄 그리드(이름 좌 · 금액 우). 보드는 체크박스 열을 더 두지만
   다중선택은 매출등록 행 추가 구조를 바꿔야 해 다음 단계로 미뤘다(2026-08-26). */
.bi-pop-catalog .bi-pop-prod-ul{ margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--pop-line); }
.bi-pop-catalog .bi-pop-prod-ul > li{
    display: grid; grid-template-columns: var(--pop-check) 1fr auto; column-gap: var(--pop-row-gap); align-items: center;
    padding: var(--space-2_5) var(--space-3) 11px; background: var(--bg-card);
    border-bottom: 1px solid var(--pop-line-soft); cursor: pointer;
}
.bi-pop-prod-ul > li:hover{ background: var(--bg-selected); }
.bi-pop-prod-ul > li.is-sel{ background: var(--bg-selected); }
.bi-pop-prod-ul > li > div:first-of-type{ font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--txt-primary); line-height: 19.5px; }
.bi-pop-prod-ul > li > div:last-of-type{ font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--txt-primary); line-height: 19.5px; text-align: right; font-variant-numeric: tabular-nums; }
.bi-pop-cat-list{ flex: 1 1 auto; min-height: 0; overflow-y: auto; background: var(--bg-card); }   /* 카드 테두리 제거 — 목록은 위 1px 선으로 시작(보드 §08) */
.bi-pop-prod-ul .pop_m_b_li{
    width: 100%; float: none; display: flow-root;
    padding: var(--space-3_5) var(--space-3_5); margin-bottom: var(--space-1_5);
    border: 1px solid var(--gray-100); border-radius: var(--radius-xl); background: var(--bg-card);
    cursor: pointer; font-size: var(--fs-md); font-weight: var(--fw-semibold); color: var(--gray-800); transition: all .12s;
}
.bi-pop-prod-ul .pop_m_b_li:hover{ background: var(--bg-input); border-color: var(--color-info-100); }
.bi-pop-prod-ul .pop_m_b_li.is-sel{ background: var(--bg-selected); border-color: var(--color-indigo-600); box-shadow: inset 4px 0 0 var(--color-indigo-600); }
.bi-pop-prod-ul .pop_m_b_li_div{ padding: 0; min-height: 0; color: var(--txt-secondary); font-weight: var(--fw-extrabold); }
/* 보드 §07 — 푸터는 «좌 보조 → 여백 → 주 액션 → 닫기» 이고 **상단 선이 있다.**
 * 2026-08-10 요청으로 선·배경을 없앴었는데, styleboard4 가 규격이 되면서 보드를 따른다(2026-08-25).
 * 안쪽 .bi-pop-foot-btns 는 버튼 묶음일 뿐이라 선을 갖지 않는다 — 바깥이 푸터다. */
.bi-pop-check{
    display: flex; align-items: flex-start; gap: var(--space-2); cursor: pointer;
    font-size: var(--fs-sm); color: var(--txt-muted); line-height: 1.5; max-width: 470px;
}
.bi-pop-check input[type="checkbox"]{
    visibility: visible; display: inline-block;
    -webkit-appearance: auto; appearance: auto;
    width: 16px; height: 16px; margin: var(--space-0_5) 0 0; flex-shrink: 0;
    accent-color: var(--brand-blue); cursor: pointer;
}
/* — 뒤에 선언되는 body padding 단축속성(.bi-pop-reg{padding:22px} 등)이 padding-bottom 을 되돌리는 것 방지. */
.bi-pop-pay--dchart, .bi-pop-pay--aim{ padding-bottom: 0; }
.bi-pop-pay--dchart .bi-pop-foot-btns, .bi-pop-pay--aim .bi-pop-foot-btns{ margin-left: calc(var(--space-6) * -1); margin-right: calc(var(--space-6) * -1); }
.bi-pop-btn{
    height: 40px; padding: 0 var(--space-5); border-radius: var(--radius-xl); border: 1px solid var(--border-base);
    background: var(--bg-card); color: var(--txt-secondary); font-size: var(--fs-md); font-weight: var(--fw-extrabold); cursor: pointer;
}
.bi-pop-btn:hover{ background: var(--bg-input); }
.bi-pop-btn--ghost{ background: var(--color-info-50); color: var(--brand-blue); border-color: var(--color-info-100); }
.bi-pop-btn--ghost:hover{ background: var(--color-info-100); }
.bi-pop-btn--primary{ background: var(--brand-blue); color: var(--bg-card); border: none; }   /* docs/76: 구글블루 var(--brand-blue) → 앱 브랜드블루 통일 */
.bi-pop-btn--primary:hover{ background: var(--brand-blue-hover); }
.bi-pop-pay--dchart, .bi-pop-pay--aim { display: flex; flex-direction: column; }
.bi-pop-pay--dchart { height: 100vh; }
.bi-pop-pay input[type="text"], .bi-pop-pay input.writeinput, .bi-pop-pay select, .bi-pop-pay input[type="number"]{
    border: 1px solid var(--gray-300); border-radius: var(--radius-lg);
    background: var(--bg-card); color: var(--gray-800); box-shadow: none; outline: none;
}
.bi-pop-pay input[type="text"]:focus, .bi-pop-pay input.writeinput:focus, .bi-pop-pay select:focus{
    border-color: var(--brand-blue); box-shadow: var(--ring-focus);
}
.bi-pop-pay--list .text_input{
    width: 340px; height: 46px; font-size: var(--fs-md); line-height: 46px;
    border: 1px solid var(--gray-300); border-bottom: 1px solid var(--gray-300); border-radius: var(--radius-xl);
    padding: 0 var(--space-3_5) 0 40px; margin: 0; background: var(--bg-card); color: var(--gray-800);
}
.bi-pop-pay--list .text_input:focus{ border-color: var(--brand-blue); box-shadow: var(--ring-focus); }
.bi-pop-pay--list.bi-pop-list--member .text_input{ width: 320px; }.bi-pop-list--member .pop_m_h{ border-left: 2px solid transparent; }.bi-pop-pay--list.bi-pop-list--emp .text_input{ width: 230px; }
.bi-pop-pay--list .bi-pop-list-foot{
    position: fixed; left: 0; right: 0; bottom: 0; width: 100%;
    display: flex; justify-content: flex-end; align-items: center;
    padding: var(--pop-foot-pad-t) var(--pop-head-pad-x) var(--pop-foot-pad-b); gap: var(--pop-foot-gap);
    background: var(--bg-card); border-top: 1px solid var(--pop-line); box-sizing: border-box; z-index: 5;
}
.bi-pop-pay .bi-pop-prepay-amt{ clear: both; margin-top: var(--space-3_5); padding-top: var(--space-3_5); border-top: 1px solid var(--gray-100); }

.bi-pop-pay input.writeinput.bi-pop-prepay-amount{ flex: 0 0 240px; width: 240px; height: 44px; margin: 0; border: 1px solid var(--gray-300); border-radius: var(--radius-lg); background: var(--bg-card); font-size: var(--fs-2lg); font-weight: 700; color: var(--txt-primary); text-align: right; padding: 0 var(--space-3); box-sizing: border-box; }

.bi-pop-pay--prepay .div_wrap{ padding-left: 0; padding-right: 0; }
.bi-pop-pay--prepay .pop_desc{ margin-bottom: var(--space-3); }

.bi-pop-list--nvemp .pop_m_h_sub{ white-space: nowrap; }
.bi-pop-list--nvemp .pop_m_h_sub:nth-of-type(2){ width: 150px; }  /* 초기화 버튼 */

.bi-pop-pay--prepay .bi-pop-prepay-amt{ margin-top: var(--space-4); padding-top: var(--space-4); }
.bi-pop-pay--cash .pop_desc{ margin-bottom: 0; }
.bi-pop-pay--cash .pop_desc{ word-break: break-all; overflow-wrap: anywhere; }
.bi-pop-pay--cash .bi-pop-card-label{ margin: var(--space-1_5) 0 var(--space-2); }
.bi-pop-pay--cardcancel .selectWrap{
    position: absolute; top: 0; left: 0; right: 0; bottom: 0;
    width: auto; height: auto;
    padding: var(--space-5) var(--space-6) var(--space-6); box-sizing: border-box;
    display: flex; flex-direction: column; background: var(--bg-card);
}
.bi-pop-pay--cardcancel .selectWrap > div{ padding: 0; }          /* 인라인 padding:10px 제거(팝업 패딩과 이중 적용) */
.bi-pop-pay--cardcancel .selectWrap .pop_m_p_b{ flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.bi-pop-pay--cardcancel .selectWrap .pop_m_h{ padding: var(--space-3) 0; }
.bi-pop-pay--cardcancel .selectWrap .pop_m_b{ flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.bi-pop-pay--cardcancel .selectWrap .pop_m_b_li{ width: 100%; padding: 0; }.bi-pop-pay--cardcancel .selectWrap .pop_m_b_li_div:only-of-type{ width: 100%; padding-left: 0; }
.bi-pop-pay--cardcancel .selectWrap .bt_div{
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
    margin-top: auto; padding-top: var(--space-4); float: none;
}
.bi-pop-pay--cardcancel .selectWrap .bt_div > div{ float: none; padding-top: 0; }
.bi-pop-pay--cardcancel .selectWrap .pop_desc{ margin: 0; padding: 0; text-align: left; }
.bi-pop-pay.bi-pop-pay--slip{ padding: 0; }
.bi-pop-pay .bi-pop-slip-foot{ display: flex; align-items: center; justify-content: flex-end; gap: var(--space-2); float: none; width: 100%; box-sizing: border-box; padding-top: var(--space-3); }
.bi-pop-pay--slip .bi-pop-slip-foot .btn_size{ min-width: 65px; }
.bi-pop-pay--slip #signature-pad, .bi-pop-pay--slip .signature-pad{ width: 100%; box-sizing: border-box; }
.bi-pop-pay--slip .signature-pad--body{ width: 100%; overflow: hidden; }
.bi-pop-pay--slip .signature-pad--body canvas{ width: 100%; height: auto; max-width: 100%; display: block; }.bi-pop-pay--npay{ overflow: hidden; }
.bi-pop-pay--npay .pop_desc{ margin-bottom: 0px; }
.bi-pop-pay--npay .pop_cate_wrap{ border: 1px solid var(--border-base); border-radius: var(--radius-xl); margin: var(--space-2_5) 0; background: var(--bg-card); overflow: hidden; }
.bi-pop-pay--npay .pop_cate_div{ width: auto; height: auto; margin: 0; }
.bi-pop-pay--npay .pop_cate_title{ width: auto; height: auto; line-height: 1.2; display: flex; align-items: center; gap: var(--space-2); padding: var(--space-3_5) var(--space-4); }
.bi-pop-pay--npay .pop_cate_title > b{ font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--gray-800); flex: 0 0 auto; }
.bi-pop-pay--npay .pop_cate_title .tags_name{ flex: 1 1 auto; margin: 0; color: var(--brand-blue); font-size: var(--fs-base); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bi-pop-pay--npay .pop_cate_title_right{ float: none; width: auto; overflow: visible; display: flex; align-items: center; gap: var(--space-3); margin-left: auto; flex: 0 0 auto; }
.bi-pop-pay--npay .pop_cate_title_right .pop_desc{ float: none; width: auto; margin: 0; padding: 0; font-size: var(--fs-sm); color: var(--txt-disabled); line-height: 1; white-space: nowrap; }
.bi-pop-pay--npay .onoff{ float: none; width: 18px; height: 18px; right: auto; font-size: var(--fs-lg); color: var(--txt-disabled); line-height: 18px; text-align: center; }
.bi-pop-pay--npay .pop_tag_ul{ width: auto; padding: var(--space-1) var(--space-4) var(--space-3); margin: 0; border-top: 1px solid var(--gray-100); overflow: hidden; }
.bi-pop-pay--npay .pop_tag_li{ width: 33.33%; min-width: 0; box-sizing: border-box; float: left; margin: var(--space-2) 0; padding-right: var(--space-1_5); font-size: var(--fs-base); }
.bi-pop-pay--npay .pop_tag_li .ch_label{ color: var(--txt-secondary); }
.bi-pop-pay--npay .radio_div input[type="radio"]{
    visibility: visible; display: inline-block;
    -webkit-appearance: auto; appearance: auto;
    width: 16px; height: 16px; margin: 0 var(--space-0_5) 0 0; vertical-align: middle;
    accent-color: var(--brand-blue); cursor: pointer;
}
.bi-pop-pay--npay .radio_div input[type="radio"]+label{ display: none; }
/* 성별 셀렉트 ↔ 길이 라디오 — 붙어 있어 한 덩어리로 보였다(사용자 지적 2026-08-27).
   폼 칸 사이 간격(12)과 같은 리듬을 준다. 라디오 줄 자체도 위아래로 숨을 준다. */
.bi-pop-pay--npay .bi-pop-f{ margin-bottom: var(--space-3); }
.bi-pop-pay--npay .radio_div:not(.bi-hidden){ display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4); margin-bottom: var(--space-3); }
.bi-pop-pay--npay .radio_div .bi-pop-opt{ margin: 0; }
/* 2026-10-02 사용자 지시 — 「기장 라벨명 아래 radio 버튼 세로 중앙에 위치하도록」.
   옆 칸 성별 select 는 키 36(--pop-field-h)인데 라디오 줄은 제 키(17)만큼만 서서 9px 위로 떠 보였다.
   → 기장 칸 안의 라디오 줄을 입력 칸과 같은 키로 세우고(align-items:center 는 위 규칙), 아래 여백을 뺀다. */
.bi-pop-pay--npay .bi-pop-f .radio_div.bi-pop-opt-row:not(.bi-hidden){ min-height: var(--pop-field-h); margin-bottom: 0; }
.bi-pop-pay .bi-pop-card-label{ display: block; font-size: var(--fs-md); font-weight: var(--fw-extrabold); color: var(--gray-800); margin: var(--space-3_5) 0 var(--space-2); padding-left: var(--space-0_5); }
.bi-pop-pay .bi-pop-card-body{ width: 100%; }
.bi-pop-pay .bi-pop-card-amount-row{ display: flex; gap: var(--space-2); align-items: stretch; }
.bi-pop-pay select.bi-pop-card-period, .bi-pop-pay select#txtPeriod{ flex: 0 0 auto; }   /* 크기는 규격·격자가 정한다(2026-08-26) */
.bi-pop-pay input.writeinput.bi-pop-card-amount{ flex: 1 1 auto; width: auto; min-width: 0; }
.bi-pop-pay input#pay_amount.writeinput{ font-weight: var(--fw-bold); color: var(--txt-primary); font-variant-numeric: tabular-nums; }   /* 크기는 규격을 따른다(2026-08-26) */
.bi-pop-pay .bi-pop-card-manual{ display: flex; align-items: center; justify-content: flex-end; gap: var(--space-1_5); margin: var(--space-3) var(--space-0_5) var(--space-1); font-size: var(--fs-base); color: var(--txt-secondary); }
.bi-pop-pay .bi-pop-card-manual span{ user-select: none; }
.bi-pop-pay .bi-pop-card-manual input[type="checkbox"]{
    visibility: visible; display: inline-block;
    -webkit-appearance: auto; appearance: auto;
    width: 16px; height: 16px; margin: 0; flex-shrink: 0;
    accent-color: var(--brand-blue); cursor: pointer;
}
.bi-pop-pay .bi-pop-card-manual > label[for]{ display: none; }
.bi-pop-pay .bi-pop-opts{ display: flex; flex-direction: column; gap: var(--space-2_5); margin: var(--space-3) var(--space-0_5) var(--space-1); }
.bi-pop-pay .bi-pop-opt-row{ display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap; }
.bi-pop-pay .bi-pop-opt{ display: inline-flex; align-items: center; gap: var(--space-1_5); margin: 0; font-size: var(--fs-base); color: var(--txt-secondary); cursor: pointer; }.bi-pop-pay .bi-pop-opt input:disabled{ cursor: not-allowed; opacity: .6; }
.bi-pop-pay .bi-pop-opt span{ user-select: none; }
.bi-pop-pay .bi-pop-card-pg input.bi-pop-card-pg-no{ height: 46px; font-size: var(--fs-2lg); letter-spacing: .5px; }
.bi-pop-pay .bi-pop-card-field--full{ grid-column: 1 / -1; }
.bi-pop-pay .bi-pop-card-field label{ display: block; font-size: var(--fs-base); color: var(--txt-muted); margin: 0 0 var(--space-1_5); padding: 0; float: none; }
.bi-pop-pay .bi-pop-card-field input.writeinput{ width: 100%; height: 40px; margin: 0; background: var(--bg-input); }
/* 2026-08-27 제거 — 선결제 팝업 전용 폼 규칙 묶음. 보드 §08/§09 로 옮겨 대상이 사라졌고,
   .bi-pop-dep-body 의 좌우 2px 여백이 규격 여백 18 을 이겨 내용이 벽에 붙었다. */
.bi-pop-pay input.writeinput.bi-pop-cash-amount{ width: 100%; height: 48px; font-size: var(--fs-xl); font-weight: 700; color: var(--txt-primary); }
.bi-pop-pay .bi-pop-card-body .ft13{ font-size: var(--fs-base); color: var(--txt-secondary); }
.bi-pop-pay .bi-pop-card-body .br2_gray{ margin-top: var(--space-4); padding-top: var(--space-3_5); border: none; border-top: 1px solid var(--gray-100); }
/* ⚠ 2026-08-28 — `.bi-pop-pay` 를 빠뜨려 **테두리가 통째로 사라져** 있었다.
   ai_msg 는 뿌리가 `.bi-pop-pay--aim` 인데 --dc-* 는 여기 둘에만 선언돼 있었다.
   정의 안 된 변수를 쓴 `border:1px solid var(--dc-line)` 은 **선언 전체가 무효**가 되어
   border-style 이 none 으로 떨어진다 — 미선택 LMS 카드가 허공의 글자로 보인 이유다.
   색이 틀린 게 아니라 «규칙이 죽은» 것이라 눈으로만 잡혔다. */
.bi-pop-reg, .bi-pop-cat-wrap, .bi-pop-pay{
    --dc-blue:var(--brand-blue); --dc-blue-soft:rgba(0,35,183,.05); --dc-navy:var(--brand-navy);
    --dc-ink:var(--txt-primary); --dc-sub:var(--txt-muted); --dc-mut:var(--txt-disabled); --dc-line:var(--border-base);
    font-family: var(--font-sans);
}.bi-pop-pay--dt .pop_m_h{
    margin: 0 0 var(--space-3); padding: 0;
    display: flex; align-items: center; gap: var(--space-2); border: none;
}.bi-pop-cat-wrap{ height: 100vh; box-sizing: border-box; color: var(--txt-primary); }
.bi-pop-cat-wrap *{ box-sizing: border-box; }
.bi-pop-cat.bi-catalog{
    width: 100%; max-width: none; height: 100%;
    border-radius: 0; box-shadow: none; padding: var(--space-5);
    display: flex; flex-direction: column;
}
/* 2026-08-28 — 규격 푸터를 달았더니 이 상자의 아래 여백 20 이 «푸터 밑» 에 깔려
   푸터가 바닥에서 20 떠 보였다(실측). 푸터는 제 여백(13/18/12)을 가지므로 여기선 0 이다. */
.bi-pop-cat.bi-catalog:has(> .bi-pop-list-foot){ padding-bottom: 0; }
/* 예약일시 선택은 «자동맞춤 제외»(내부 스크롤 의도)라 상자가 내용보다 클 수 있다.
   그럴 때도 푸터는 바닥에 붙어야 한다 — 남는 자리를 본문이 먹는다(실측 푸터아래 17 → 0). */
/* 아래 여백은 0 — 푸터가 제 여백(13/18/12)을 갖는다. 뿌리 여백이 남으면 푸터 밑에 깔린다. */
/* ⚠ 2026-08-31 — 세로 정렬이 남는 자리를 «위아래로 나눠» 푸터가 바닥에서 14 떠 있었다
   (실측: 본문 위 34 · 푸터 아래 14). 위에서부터 쌓고, 남는 자리는 푸터의 margin-top:auto 가 먹는다. */
.bi-pop-pay--dt{ min-height: 100vh; display: flex; flex-direction: column; justify-content: flex-start; padding-bottom: 0; }
/* ⚠ 전폭 규칙의 margin-top:16 이 뒤에 오며 auto 를 이겨, 푸터가 바닥까지 못 갔다(실측 14 남음).
   특이도를 올려 «바닥으로 민다» 를 확정한다. */
.bi-pop-page .bi-pop-pay--dt > .bi-pop-list-foot,
.bi-pop-page .bi-pop-pay--dt > .bi-pop-foot-btns{ margin-top: auto; }
.bi-pop-cat .bi-catalog__body{ flex: 1; display: flex; flex-direction: row; gap: var(--space-5); min-height: 0; }
.bi-pop-cat .bi-catalog__console{ display: flex; flex-direction: column; width: 220px; flex-shrink: 0; }
.bi-pop-cat .bi-catalog__main{ flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.bi-pop-cat .bi-catalog__content{ flex: 1; display: flex; flex-direction: row; min-height: 0; }
.bi-pop-cat .bi-catalog__grid{ flex: 1 1 auto; min-width: 0; }
.bi-pop-cat .bi-catalog__view{ flex-shrink: 0; width: 280px; }
.bi-catalog { background: var(--bg-card); border-radius: var(--radius-2xl); padding: var(--space-5); width: 980px; max-width: 94vw; height: 86vh; display: flex; flex-direction: column; gap: var(--space-3_5); box-shadow: var(--shadow-lg); }
/*   width:auto — 공용 .bi-pop-head{width:100%}(=content 폭)이면 음수 margin 상쇄 후 우측 40px 빔 → auto 로 flex stretch 가 margin 까지 채워 박스 폭 꽉 참. */
.bi-catalog > .bi-pop-head { margin: calc(var(--space-5) * -1) calc(var(--space-5) * -1) 0; border-radius: var(--radius-2xl) var(--radius-2xl) 0 0; width: auto; }
.bi-catalog > .bi-pop-head .bi-pop-head-title { overflow: visible; display: inline-flex; align-items: center; gap: var(--space-1_5); }
.bi-catalog__who { font-size: var(--fs-sm); font-weight: var(--fw-extrabold); color: var(--color-purple-700); background: var(--color-purple-50); border: 1px solid var(--color-purple-200); padding: var(--space-0_5) var(--space-2_5); border-radius: var(--radius-full); }
.bi-catalog__body { flex: 1; display: flex; gap: var(--space-5); min-height: 0; }
.bi-catalog__console { width: 220px; flex-shrink: 0; background: var(--bg-input); border: 1px solid var(--border-base); border-radius: var(--radius-2xl); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3_5); }
.bi-catalog__console-t { font-size: var(--fs-xs); font-weight: var(--fw-black); color: var(--txt-disabled); letter-spacing: .15em; font-family: var(--font-mono); }
.bi-catalog__console-d { font-size: var(--fs-2xs); color: var(--txt-muted); font-weight: var(--fw-medium); line-height: 1.5; margin: var(--space-1) 0 0; word-break: keep-all; }
.bi-catalog__card { border-radius: var(--radius-2xl); padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2_5); }
.bi-catalog__card--ai { background: color-mix(in srgb, var(--color-purple-600) 5%, transparent); border: 1px solid var(--color-purple-200); }
.bi-catalog__card--up { background: color-mix(in srgb, var(--brand-blue) 5%, transparent); border: 1px solid var(--color-indigo-200); }
.bi-catalog__card-h { font-size: var(--fs-xs); font-weight: var(--fw-black); color: var(--gray-800); display: flex; align-items: center; gap: var(--space-1_5); }
.bi-catalog__dot--ai { background: var(--color-purple-600); }
.bi-catalog__dot--up { background: var(--brand-blue); }
.bi-catalog__cbtn { width: 100%; border: 0; color: var(--bg-card); font-size: var(--fs-sm); font-weight: var(--fw-black); padding: var(--space-2_5); border-radius: var(--radius-xl); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1_5); box-shadow: var(--shadow-md); }
.bi-catalog__cbtn i { color: var(--bg-card); }
.bi-catalog__cbtn--ai { background: var(--color-purple-600); }
.bi-catalog__cbtn--ai:hover { background: var(--color-purple-700); }
.bi-catalog__cbtn--up { background: var(--brand-blue); }
.bi-catalog__cbtn--up:hover { background: var(--brand-blue); }
.bi-catalog__main { flex: 1; display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.bi-catalog__tabs { display: flex; gap: var(--space-1); background: var(--border-light); padding: var(--space-1); border-radius: var(--radius-xl); flex-shrink: 0; }
.bi-catalog__content { flex: 1; display: flex; gap: var(--space-3_5); min-height: 0; }
.bi-catalog__grid { flex: 1; display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: min-content; gap: var(--space-2_5); overflow-y: auto; align-content: start; padding-right: var(--space-1); }
.bi-catalog__thumb--vt { border-color: var(--color-purple-200); }
.bi-catalog__thumb--vt.is-selected { border-color: var(--color-purple-600); box-shadow: var(--ring-focus); }
.bi-catalog__tag { position: absolute; left: 5px; bottom: 5px; font-size: var(--fs-2xs); font-weight: var(--fw-black); color: var(--bg-card); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-md); }
.bi-catalog__empty { grid-column: 1 / -1; padding: 40px var(--space-3); text-align: center; color: var(--txt-disabled); font-size: var(--fs-sm); font-style: italic; }
.bi-catalog__view { width: 280px; flex-shrink: 0; border-left: 1px solid var(--border-base); padding-left: var(--space-3_5); display: flex; flex-direction: column; gap: var(--space-3); overflow-y: auto; }
.bi-catalog__viewempty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2); color: var(--txt-disabled); font-size: var(--fs-xs); font-weight: var(--fw-semibold); text-align: center; }
.bi-catalog__viewempty i { font-size: var(--fs-xl); color: var(--gray-300); }
.bi-catalog__viewimg { border-radius: var(--radius-2xl); overflow: hidden; border: 1px solid var(--border-base); background: var(--bg-input); text-align: center; }
.bi-catalog__viewimg img { display: block; width: 100%; height: auto; }
.bi-catalog__meta-tags { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.bi-catalog__meta-tags span { font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--gray-600); background: var(--border-light); padding: var(--space-0_5) var(--space-2); border-radius: var(--radius-full); }
.bi-catalog__meta-at { font-size: var(--fs-xs); color: var(--txt-disabled); font-weight: var(--fw-semibold); }
.bi-catalog__meta-link { font-size: var(--fs-xs); font-weight: var(--fw-extrabold); color: var(--brand-blue); text-decoration: none; display: inline-flex; align-items: center; gap: var(--space-1_5); }
.bi-catalog__meta-link:hover { text-decoration: underline; }
.bi-pop-pay--form{ display: block; }
.bi-pop-pay--form form{ display: block; }
.bi-pop-pay .bi-pop-form-row{
    float: none; width: auto; clear: both;
    margin: 0 0 var(--space-4); padding: 0;
}
.bi-pop-pay .bi-pop-form-row:last-of-type{ margin-bottom: var(--space-1); }
.bi-pop-pay .bi-pop-form-label{
    display: block; float: none; width: auto; padding: 0;
    margin: 0 0 var(--space-2); font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-secondary); line-height: 1.4;
}
.bi-pop-pay .bi-pop-form-label b{ font-size: var(--fs-base); font-weight: 600; color: var(--txt-secondary); }
.bi-pop-pay .bi-pop-form-label .sub_description{
    display: inline; padding: 0; margin-left: var(--space-1_5);
    font-size: var(--fs-sm); font-weight: var(--fw-normal); color: var(--txt-disabled);
}.bi-pop-pay .bi-pop-form-row input.bi-pop-form-full{ width: 100%; }
.bi-pop-pay .bi-pop-form-range{ display: flex; align-items: center; gap: var(--space-2); }
.bi-pop-pay .bi-pop-form-range input.writeinput{ flex: 1 1 0; width: auto; }
.bi-pop-pay .bi-pop-form-range .bi-pop-form-tilde{ flex: 0 0 auto; color: var(--txt-disabled); font-size: var(--fs-md); }
.bi-pop-pay .bi-pop-point-amount-row{ display: flex; align-items: center; gap: var(--space-3_5); }
.bi-pop-pay--form input#use_point.writeinput{
    flex: 1 1 0; width: auto; height: 44px;
    text-align: right; font-size: var(--fs-2lg); font-weight: 700; color: var(--txt-primary);
}
.bi-pop-pay .bi-pop-point-radio{
    flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-3_5);
    font-size: var(--fs-base); color: var(--txt-secondary); white-space: nowrap; padding: 0; height: auto; float: none;
}
.bi-pop-pay .bi-pop-point-radio label{ margin: 0; }
.bi-pop-pay--msg{ padding: var(--space-4) var(--space-5) var(--space-3); }
.bi-pop-pay--msg > div:first-of-type{ float: none; margin: 0; width: auto; }
.bi-pop-pay--msg form{ margin: 0; padding: 0; }
.bi-pop-pay--msg .ft12{
    width: auto; float: none; height: auto; box-sizing: border-box;
    background: var(--bg-input); border: 1px solid var(--gray-100); border-radius: var(--radius-xl);
    padding: var(--space-3) var(--space-3_5); margin-bottom: var(--space-3_5);
    font-size: var(--fs-sm); line-height: 1.7; color: var(--txt-muted);
}
.bi-pop-pay--msg .bi-msg-rpanel{
    border: 1px solid var(--gray-100); box-shadow: none;
    border-radius: var(--radius-2xl); background: var(--bg-card); box-sizing: border-box;
    width: 480px; height: auto; min-height: 482px;
    float: left; padding: var(--space-5);
}
.bi-pop-pay--msg .bi-msg-rpanel > div{
    width: 100%; float: none; height: auto;
    padding: 0; margin: 0;
}
.bi-pop-pay--msg .bi-msg-rpanel > div + div{ margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--border-light); }
.bi-pop-pay--msg .bi-msg-rpanel input.writeinput{ width: 100%; }
.bi-pop-pay--msg .bi-msg-rpanel select[multiple]{ width: 100%; height: 150px; }
.bi-pop-pay--msg .bi-msg-rpanel .edit_one{ margin-bottom: var(--space-1_5); }
.bi-pop-pay--msg .bi-msg-rpanel > div > div[style*="padding-top"]{ padding-top: var(--space-3); }
.bi-pop-pay--msg .edit_one b{ font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-secondary); }
.bi-pop-pay--msg .edit_one[style*="font-weight"]{ font-size: var(--fs-base); font-weight: 700; color: var(--txt-secondary); }
.bi-pop-pay--msg .ft11{ color: var(--txt-muted); }
.bi-pop-pay--msg .txt_span_middle{ font-weight: var(--fw-semibold); color: var(--txt-disabled); }
.bi-pop-pay--msg input.writeinput{
    height: 36px; border: 1px solid var(--border-base); border-radius: var(--radius-lg);
    background: var(--bg-card); color: var(--gray-800); padding: 0 var(--space-3);
    font-size: var(--fs-base); box-shadow: none;
}
.bi-pop-pay--msg input.writeinput:focus{ border-color: var(--brand-blue); box-shadow: var(--ring-focus); }
.bi-pop-pay--msg select{
    height: 36px; border: 1px solid var(--border-base); border-radius: var(--radius-lg);
    background: var(--bg-card); color: var(--gray-800); font-size: var(--fs-base); padding: 0 var(--space-2); box-shadow: none;
}
.bi-pop-pay--msg select[multiple]{ padding: var(--space-1); }
.bi-pop-pay--msg select:focus{ border-color: var(--brand-blue); box-shadow: var(--ring-focus); }
.bi-pop-pay--msg select[multiple] option{ padding: var(--space-1_5) var(--space-2); font-size: var(--fs-base); }
.bi-pop-pay--msg input[type="button"][value="입력"]{
    width: auto; height: 36px; padding: 0 var(--space-3_5);
    border: 1px solid var(--gray-300); border-radius: var(--radius-lg);
    background: var(--border-light); color: var(--txt-secondary); font-size: var(--fs-base); font-weight: 600; cursor: pointer;
}
.bi-pop-pay--msg input[type="button"][value="입력"]:hover{ background: var(--border-base); }
.bi-pop-pay--msg .edit_one{ margin-bottom: var(--space-1); }
/* 2026-08-27 제거 — 할인 팝업 전용 폼 규칙 묶음. 보드 §08 로 옮겨 대상이 사라졌고,
   남은 .bi-pop-disc-search 테두리가 규격 입력칸을 두 겹으로 감쌌다. */
.bi-pop-pay--prodpick .bi-pop-prodpick-col{
    width: auto; flex: 1 1 0; min-width: 200px; margin: 0; padding: 0;
    display: flex; flex-direction: column;
    background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-xl); overflow: hidden;
}
.bi-pop-pay--prodpick .bi-pop-prodpick-head{
    width: auto; height: auto; float: none;
    padding: var(--space-3) var(--space-3_5); border-bottom: 1px solid var(--gray-100);
    font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-secondary);
}
.bi-pop-pay--prodpick .bi-pop-prodpick-search{
    position: relative; display: flex; align-items: center;
    height: 36px; padding: 0 var(--space-2_5) 0 34px; background: var(--bg-input); border: 1px solid var(--border-base); border-radius: var(--radius-lg);
}
.bi-pop-pay--prodpick .bi-pop-prodpick-search:focus-within{ border-color: var(--brand-blue); box-shadow: var(--ring-focus); background: var(--bg-card); }
.bi-pop-pay--prodpick .bi-pop-prodpick-search > i.fas{ position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--txt-disabled); font-size: var(--fs-sm); pointer-events: none; }
.bi-pop-pay--prodpick .bi-pop-prodpick-search .sch_but_pop{ left: 4px; top: 0; height: 36px; width: 28px; z-index: 2; }
.bi-pop-pay--prodpick .bi-pop-prodpick-search input.search_input_pop{
    width: 100%; height: 100%; border: none; box-shadow: none;
    background: transparent; padding: 0; margin: 0; font-size: var(--fs-base); color: var(--gray-800);
}
.bi-pop-pay--msg .bi-msg-direct{ margin-bottom: var(--space-2_5); }
.bi-pop-pay--msg .bi-msg-direct-label{ display: block; float: none; padding: 0 0 var(--space-1_5); font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-muted); }
.bi-pop-pay--msg .bi-msg-direct-row{ display: flex; gap: var(--space-2); align-items: center; }
.bi-pop-pay--msg .bi-msg-direct-row input[type="text"].writeinput{ flex: 1 1 auto; width: auto; }
.bi-pop-pay--msg .bi-msg-direct-row input[type="button"]{
    flex: 0 0 auto; width: auto; height: 36px; padding: 0 var(--space-4);
    border: 1px solid var(--gray-300); border-radius: var(--radius-lg);
    background: var(--border-light); color: var(--txt-secondary); font-size: var(--fs-base); font-weight: 600; cursor: pointer;
}
.bi-pop-pay--msg select[multiple]{ height: 300px; }
.bi-pop-pay--paylist .pop_desc{ margin-bottom: var(--space-3_5); padding-top: 0; font-size: var(--fs-base); color: var(--txt-muted); }
.bi-pop-pay--paylist .pop_m_p_b{ width: 100%; border: 1px solid var(--border-base); border-radius: var(--radius-xl); overflow: hidden; box-sizing: border-box; }
.bi-pop-pay--paylist .pop_m_h{
    width: 100%; display: flex; margin: 0; border: none;
    background: var(--bg-input); border-bottom: 1px solid var(--gray-100);
}
.bi-pop-pay--paylist .pop_m_h_sub{
    flex: 0 0 110px; width: auto; padding: var(--space-3) var(--space-1_5); text-align: center;
    font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--txt-muted); border-left: 1px solid var(--gray-100);
}
.bi-pop-pay--paylist .pop_m_h_sub:first-child{ flex: 1 1 auto; text-align: left; padding-left: var(--space-3_5); border-left: none; }
.bi-pop-pay--paylist .pop_m_b{ width: 100%; height: 300px; overflow-y: auto; }
.bi-pop-pay--paylist .pop_m_b_ul{ margin: 0; padding: 0; list-style: none; }
.bi-pop-pay--paylist .pop_m_b_li{
    display: flex; align-items: center; border-bottom: 1px solid var(--border-light); cursor: pointer; background: var(--bg-card);
}
.bi-pop-pay--paylist .pop_m_b_li:hover{ background: var(--border-light); }
.bi-pop-pay--paylist .pop_m_b_li_div{
    flex: 0 0 110px; width: auto; padding: var(--space-3) var(--space-1_5); text-align: center;
    font-size: var(--fs-base); color: var(--txt-secondary); border-left: 1px solid var(--border-light);
}
.bi-pop-pay--paylist .pop_m_b_li_div:first-child{ flex: 1 1 auto; text-align: left; padding-left: var(--space-3_5); border-left: none; font-weight: var(--fw-semibold); }
.bi-bq-pop { display: flex; flex-direction: column; min-height: 100%; box-sizing: border-box; }
/* ⚠ 2026-09-02 — 좌우 여백이 «두 겹» 이었다(실측 36px, 규격 18px).
 *   뿌리 .bi-pop-reg 가 padding: 0 18 (보드 .pop-body 좌우값)을 갖는데
 *   그 안의 .bi-pop-pad--form 이 또 padding: 0 18 을 가져 첫 블록이 36 에서 시작했다.
 *   .bi-pop-pad--form 은 다른 팝업(뿌리 여백이 없는 것)이 쓰므로 공통 규칙은 두고,
 *   «뿌리가 이미 좌우를 가진» 이 조합에서만 안쪽 좌우를 0 으로 돌린다.
 *   아래 여백 16 은 규격(.pop-body padding 0 18 16)대로 여기서 준다. */
.bi-pop-reg .bi-pop-pad--form{ padding-left: 0; padding-right: 0; padding-bottom: var(--space-4); }
/* ⚠ 2026-09-02 — 위 padding-bottom 16 과 푸터의 margin-top 16 이 겹쳐 «메모 아래 32» 가 됐다.
 *   규격은 «본문 아래 16 + 푸터 윗선» 이다. 이 조합에서만 푸터 위 여백을 뺀다. */
.bi-pop-reg .bi-pop-pad--form + .bi-pop-list-foot{ margin-top: 0; }
.bi-bq-body { padding: var(--space-5) var(--space-5); display: flex; flex-direction: column; gap: var(--space-3_5); flex: 1; }
.bi-bq-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3_5); }
.bi-bq-textarea { height: auto; padding: var(--space-2_5) var(--space-3); resize: vertical; line-height: 1.4; }
.bi-bq-cust .bi-bq-cust-input { flex: 1; min-width: 0; }
/* ⚠ 2026-09-02 — 규격 검색행 안의 인풋은 «투명» 이어야 하는데
 *   .bi-pop-reg input[type=text].bi-input (0,3,1) 이 .bi-pop-page .bi-pop-search__box input (0,2,1) 을 이겨
 *   테두리가 두 겹으로 보였다. 마크업에서 bi-input 을 떼는 것이 맞지만,
 *   혹시 다시 붙어도 상자 안에서는 투명하도록 못박는다. */
.bi-bq-cust-btn { flex-shrink: 0; width: 38px; height: 38px; padding: 0; display: inline-flex; align-items: center; justify-content: center; background: var(--brand-blue); color: var(--bg-card); font-size: var(--fs-md); border: 0; border-radius: var(--radius-xl); cursor: pointer; transition: background .15s, transform .1s; }
.bi-bq-cust-btn:hover { background: var(--brand-navy); }
.bi-bq-cust-btn:active { transform: scale(.95); }
/* 2026-09-02 — 라벨 «위» 로 올렸다(사용자 지시). 라벨과 붙지 않게 아래 여백을 준다.
   ⚠ 글자는 규격 보조문(.bi-pop-note = 12/400 --txt-muted)과 같아야 한다 —
      전엔 11/600 --txt-disabled 라 «다른 글» 처럼 보였다(실측). */
.bi-bq-cust-state { display: flex; align-items: center; gap: var(--space-1_5); margin-bottom: var(--space-1_5);
    font-size: var(--pop-cnt-fs); font-weight: var(--fw-normal); color: var(--txt-muted); }
.bi-bq-cust-state.is-linked { color: var(--color-success); }
/* 2026-09-02 — 2글자 미만일 때 «왜 안 되는지» 를 그 자리에서 알린다(전엔 조용히 아무 일도 없었다) */
/* ⚠ 검색행이 .bi-pop-f 안에 들어가면 «아래 여백이 두 겹» 이 된다 —
   .bi-pop-search{margin-bottom:12} + .bi-pop-f{margin-bottom:12} = 24.
   다른 줄은 12 인데 고객명 줄만 24 라 «간격이 안 맞아» 보였다(2026-09-02 실측). */
.bi-pop-page .bi-pop-f > .bi-pop-search{ margin-bottom: 0; }

/* 검색 안내 토스트 — 줄로 끼우면 팝업이 밀린다. 검색칸 아래에 «겹쳐» 뜬다.
   ⚠ 2026-09-02 — 처음엔 간편예약 전용(.bi-bq-toast)이었는데, 2글자 제한은
      고객검색·거래처검색 등 «여러 팝업» 에 있다 → 공용 이름(.bi-pop-toast)으로 올린다. */
/* 붙을 자리는 «이미 있는» 기준점을 쓴다 — .bi-pop-search · .bi-counter-search-wrap 둘 다 relative 다.
   ⚠ 전용 앵커 클래스(.bi-toast-host)를 새로 만들려다 SPEC-DUP 에 걸렸다(2026-09-02).
      position:relative 한 줄짜리 규격이 이미 다섯이라 여섯째를 보태는 꼴이었다.
      기준점이 안 잡힌 자리에서는 biPopToast 가 alert 로 물러선다 — 엉뚱한 데 뜨느니 낫다. */
.bi-pop-toast, .bi-bq-toast{
    position: absolute; left: 0; top: calc(100% + 6px); z-index: 5;
    max-width: 100%; padding: var(--space-1_5) var(--space-2_5);
    border-radius: var(--radius-lg); background: var(--gray-900); color: var(--white);
    font-size: var(--fs-xs); font-weight: var(--fw-semibold); white-space: nowrap;
    opacity: 0; visibility: hidden; transform: translateY(-3px);
    transition: opacity .15s, transform .15s, visibility .15s;
    box-shadow: var(--shadow-lg); pointer-events: none;
}
.bi-pop-toast.is-on, .bi-bq-toast.is-on{ opacity: 1; visibility: visible; transform: translateY(0); }
.bi-pop-page .bi-pop-search{ position: relative; }

.bi-bq-cust-state i { font-size: var(--fs-sm); }
.bi-bq-note { display: flex; align-items: center; gap: var(--space-1_5); background: var(--color-info-50); border: 1px solid var(--color-info-100); color: var(--color-info-700); font-size: var(--fs-sm); font-weight: var(--fw-semibold); padding: var(--space-2) var(--space-3); border-radius: var(--radius-xl); }
.bi-bq-foot { display: flex; justify-content: flex-end; gap: var(--space-2_5); padding: var(--space-3_5) var(--space-5); background: var(--bg-input); border-top: 1px solid var(--gray-100); }
.bi-bq-btn { height: 38px; padding: 0 var(--space-5); border-radius: var(--radius-xl); font-size: var(--fs-base); font-weight: var(--fw-bold); cursor: pointer; display: inline-flex; align-items: center; gap: var(--space-1_5); border: 1px solid transparent; transition: background .15s, border-color .15s, color .15s; }
.bi-bq-btn--ghost { background: var(--bg-card); border-color: var(--border-base); color: var(--gray-600); }
.bi-bq-btn--ghost:hover { background: var(--border-light); }
.bi-bq-btn--primary { background: var(--brand-blue); color: var(--bg-card); }
.bi-bq-btn--primary:hover { background: var(--brand-navy); }.bi-pg-choice {
  float: left;
  width: 100%;
  padding: var(--space-3) var(--space-3) 0;
  display: flex;
  gap: var(--space-5);
  align-items: center;
}
.bi-pg-choice__item {
  display: flex;
  align-items: center;
  gap: var(--space-1_5);
  font-size: var(--fs-md);
  cursor: pointer;
}
.bi-pg-fields {
  float: left;
  width: 100%;
  padding: var(--space-2_5) var(--space-3) 0;
  display: none; /* draw_payUi() 가 켠다 */
}
.bi-pg-fields__row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding-bottom: var(--space-1_5);
}
.bi-pg-fields__row label {
  width: 92px;
  font-size: var(--fs-base);
  color: var(--gray-600);
}
.bi-pg-fields__row input {
  flex: 1;
  height: 32px;
  padding: 0 var(--space-2);
  border: 1px solid var(--gray-300);
  border-radius: var(--radius-sm);
  font-size: var(--fs-md);
}
.bi-paypop__cust { font-size: var(--fs-xl); font-weight: var(--fw-black); color: var(--txt-primary); }
.bi-paypop__totallbl { font-size: var(--fs-base); font-weight: var(--fw-black); color: var(--txt-muted); }
.bi-paypop__totalval { font-size: var(--fs-3xl); font-weight: var(--fw-black); color: var(--txt-primary); }
.bi-paypop__items { display: flex; flex-direction: column; max-height: 140px; overflow-y: auto; }
.bi-paypop__collapse { border-bottom: 1px solid var(--border-light); padding-bottom: var(--space-2); }
.bi-paypop__collapse-btn { width: 100%; display: flex; justify-content: space-between; align-items: center; background: transparent; border: 0; cursor: pointer; font-size: var(--fs-sm); font-weight: var(--fw-black); color: var(--gray-600); padding: var(--space-1) 0; }
.bi-paypop__collapse-btn span { display: inline-flex; align-items: center; gap: var(--space-1_5); }
.bi-paypop__collapse-btn i { color: var(--txt-disabled); }
.bi-paypop__collapse-body { display: flex; flex-wrap: wrap; align-content: flex-start; gap: var(--space-1_5); margin-top: var(--space-2); max-height: 120px; overflow-y: auto; }
.bi-paypop__collapse-body.is-hidden { display: none; }
.bi-paypop__hint { font-size: var(--fs-xs); color: var(--txt-muted); text-align: center; padding: var(--space-0_5) 0 var(--space-1_5); display: flex; align-items: center; justify-content: center; gap: var(--space-1_5); }
.bi-paypop__hint i { color: var(--txt-disabled); }
.bi-paypop__methods-lbl { font-size: var(--fs-sm); color: var(--txt-muted); font-weight: var(--fw-black); }
.bi-paypop__methods-grid { display: grid; grid-template-columns: repeat(4,1fr); gap: var(--space-1_5); }
.bi-msgpop__recv { background: var(--bg-input); border: 1px solid var(--border-base); border-radius: var(--radius-2xl); padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-1_5); }
.bi-msgpop__recv-top h4 { font-size: var(--fs-md); font-weight: var(--fw-black); color: var(--txt-primary); margin: 0; }
.bi-msgpop__recv-top span { font-size: var(--fs-sm); color: var(--txt-disabled); }
.bi-msgpop__tag { font-size: var(--fs-xs); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm); font-weight: var(--fw-extrabold); }
.bi-msgpop__tag.tag-indigo { background: var(--color-indigo-50); color: var(--color-indigo-700); }
.bi-msgpop__tag.tag-amber { background: var(--color-warning-50); color: var(--color-warning-700); }
.bi-msgpop__tag.tag-rose { background: var(--color-rose-50); color: var(--color-rose-700); font-weight: var(--fw-black); }
.bi-msgpop__meta { display: flex; justify-content: space-between; font-size: var(--fs-xs); color: var(--txt-disabled); font-weight: var(--fw-bold); padding: 0 var(--space-0_5); }
.bi-msgpop__mode-name { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-secondary); }
.bi-msgpop__mode-price { font-size: var(--fs-2xs); color: var(--txt-disabled); }
.bi-msgpop__mode.is-active i, .bi-msgpop__mode.is-active .bi-msgpop__mode-name { color: var(--brand-blue); }
.bi-msgpop__scroll { display: flex; flex-direction: column; gap: var(--space-3_5); padding-bottom: var(--space-4); }   /* 보드 .pop-body 의 아래 16 */
.bi-pop-pay--aim-fit .bi-msgpop__mode-name  { font-size: var(--fs-base); font-weight: 800; color: var(--txt-secondary); }
.bi-pop-pay--aim-fit .bi-msgpop__mode-price { font-size: var(--fs-xs); font-weight: 700; color: var(--dc-mut); }.bi-pop-pay--aim-fit .bi-msgpop__mode.is-active .bi-msgpop__mode-price { color: var(--brand-blue); opacity: .75; }
/* 테두리 상자 — 팝업 표 · 시술·상품 목록이 같다 */
.bi-pop-tbl,
.bi-bq-items{ border: 1px solid var(--border-base); border-radius: var(--radius-lg); overflow: hidden; }
.bi-pop-tbl-head{
    display: grid; gap: var(--space-2); padding: var(--space-2) var(--space-3);
    background: var(--bg-input); border-bottom: 1px solid var(--border-base);
    font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--txt-muted);
}
.bi-pop-tbl-cell--amt{ text-align: right; font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; }
.bi-pop-page{ background: var(--bg-card); }
/* 팝업은 별도 문서라 .bi-page 스코프가 안 닿는다 — 폼 컨트롤 글꼴을 여기서도 물려받게 한다
 * (브라우저 기본은 Arial 이라 본문 글꼴을 안 따라온다, 2026-08-21) */
.bi-pop-page input,
.bi-pop-page select,
.bi-pop-page textarea,
.bi-pop-page button { font-family: var(--font-sans); }
.bi-pop-pad{ padding: 0 var(--space-2_5); box-sizing: border-box; }   /* 규격값은 .bi-pop-board 에서 덧붙인다(2026-08-28 되돌림) */
.bi-pop-btnbar{ padding-top: var(--space-3); }
.bi-pop-block{ padding-top: var(--space-4); }
.bi-pop-spec__lbl{ color: var(--brand-blue); font-size: var(--fs-sm); text-align: left; }
.bi-pop-paybtn{ height: 60px; font-size: var(--fs-base); color: var(--white); box-sizing: border-box; }
.bi-pop-paybtn-row{ display: flex; gap: var(--space-2); margin-bottom: var(--space-2_5); }
.bi-pop-paybtn-row > .bi-pop-paybtn{ flex: 1; min-width: 0; }
.bi-pop-picker__col { width: var(--bi-picker-w, 280px); height: 350px; box-sizing: border-box; }
.bi-pop-picker__col--w430{ --bi-picker-w: 430px; width: 430px; }   /* 단독으로도 쓸 수 있게 */
/* ⚠ 폭은 부모가 정한다. 여기 `width:280px` 는 부모 .bi-pop-picker__col 의 **바깥 폭**을 그대로
 *   다시 적은 것이라, 칼럼의 좌우 안쪽 여백(17px)만큼 그대로 넘쳤다(280 > 263, 2026-08-14 실측).
 *   .bi-timeline 이 `width:40%` 로 눌렸던 것과 같은 계열이다. */
.bi-pop-picker__sec { width: 100%; height: 50%; margin: var(--space-4) 0; box-sizing: border-box; }
.bi-pop-picker__list{ width: 230px; float: right; }
.bi-pop-picker__head{ padding: 0 0 var(--space-1_5) 0; margin-top: var(--space-3); }
.bi-pop-bk__scroller { display: none; height: 45px; color: var(--txt-muted); }
.bi-pop-bk__arrow    { width: 50px; font-size: var(--fs-2xl, 25px); margin-top: var(--space-2_5); text-align: center; }
.bi-pop-bk__info     { min-width: 335px; border: 1px solid var(--border-light); border-top: none;
                        overflow-y: auto; position: relative; background: var(--bg-card); box-sizing: border-box; }
.bi-pop-bk__info-pad { padding: var(--space-4) var(--space-4_5, 18px); }
.bi-pop-bk__title    { font-weight: var(--fw-bold); font-size: var(--fs-xl); color: var(--txt-secondary); }
.bi-pop-bk__searchbox{ display: flex; border: 1px solid var(--border-light); width: 258px;
                        padding: var(--space-1_5); background: var(--bg-card); height: 21px; box-sizing: border-box; }
.bi-pop-bk__schhead  { height: auto; padding-bottom: var(--space-2_5); border-bottom: 5px solid var(--border-light); }
.bi-pop-bk__schtitle { font-size: var(--fs-sm); padding: 11px 0 var(--space-2_5) var(--space-2_5); width: 95%; box-sizing: border-box; }
.bi-pop-bk__row      { display: flex; width: 100%; background: var(--bg-card); }
.bi-pop-bk__sec      { margin-top: var(--space-6); font-size: var(--fs-lg); margin-bottom: var(--space-5); font-weight: var(--fw-bold); }
.bi-pop-bk__sec--sub { margin-top: var(--space-2_5); font-size: var(--fs-lg); margin-bottom: var(--space-1_5); font-weight: var(--fw-normal); }
.bi-pop-bk__name     { margin-left: var(--space-4); color: var(--txt-secondary); }
.bi-pop-bk__hr       { margin: var(--space-0_5) 0; }
.bi-pop-bk__group    { text-align-last: justify; padding: var(--space-4) var(--space-2_5); }
.bi-pop-bk__copy     { border-bottom: 1px solid var(--border-base); margin-bottom: var(--space-10); display: none; }
.bi-pop-picker__nav    { height: 60px; width: 40px; font-size: var(--fs-base); margin-left: var(--space-2_5); }
.bi-pop-picker__nav--tall{ height: 85px; }
.bi-pop-corner-in{ width: 155px; position: absolute; bottom: 7px; right: 18px; }
.bi-pop-lbl60{ width: 60px; margin-right: var(--space-5); text-align: right; }
.bi-pop-scrollbox  { height: 130px; overflow: auto; }
.bi-pop-tbl-empty{ grid-column: 1 / -1; color: var(--txt-muted); padding: var(--space-4) 0; font-size: var(--pop-cnt-fs); }
.bi-pop-tbl--c1{ grid-template-columns: 1fr; }
.bi-pop-tbl--c2.bi-pop-tbl-head, .bi-pop-tbl--c2.bi-pop-tbl-row{ grid-template-columns: repeat(2, 1fr); }
.bi-pop-tbl--c3.bi-pop-tbl-head, .bi-pop-tbl--c3.bi-pop-tbl-row{ grid-template-columns: repeat(3, 1fr); }
.bi-pop-tbl--c4.bi-pop-tbl-head, .bi-pop-tbl--c4.bi-pop-tbl-row{ grid-template-columns: repeat(4, 1fr); }
.bi-pop-tbl--c5.bi-pop-tbl-head, .bi-pop-tbl--c5.bi-pop-tbl-row{ grid-template-columns: repeat(5, 1fr); }
.bi-pop-tbl--c6.bi-pop-tbl-head, .bi-pop-tbl--c6.bi-pop-tbl-row{ grid-template-columns: repeat(6, 1fr); }
.bi-pop-tbl--c12.bi-pop-tbl-head, .bi-pop-tbl--c12.bi-pop-tbl-row{ grid-template-columns: repeat(12, 1fr); }
.bi-pop-tbl--c2 .bi-pop-tbl-head, .bi-pop-tbl--c2 .bi-pop-tbl-row{ grid-template-columns: repeat(2, 1fr); }
.bi-pop-tbl--c3 .bi-pop-tbl-head, .bi-pop-tbl--c3 .bi-pop-tbl-row{ grid-template-columns: repeat(3, 1fr); }
.bi-pop-tbl--c4 .bi-pop-tbl-head, .bi-pop-tbl--c4 .bi-pop-tbl-row{ grid-template-columns: repeat(4, 1fr); }
.bi-pop-tbl--c5 .bi-pop-tbl-head, .bi-pop-tbl--c5 .bi-pop-tbl-row{ grid-template-columns: repeat(5, 1fr); }
.bi-pop-tbl--c6 .bi-pop-tbl-head, .bi-pop-tbl--c6 .bi-pop-tbl-row{ grid-template-columns: repeat(6, 1fr); }
.bi-pop-tbl--c12 .bi-pop-tbl-head, .bi-pop-tbl--c12 .bi-pop-tbl-row{ grid-template-columns: repeat(12, 1fr); }
.bi-pop-spec{
    display: grid; grid-template-columns: 2fr 3fr; gap: var(--space-2);
    align-items: center; padding: var(--space-2_5) 0;
    /* ⚠ float 형제 사이에 놓이면 폭이 0 이 된다(slip_2022 에서 clientWidth 0 으로 실측).
     * 레거시 팝업은 아직 float 흐름이 남아 있어 width·clear 를 함께 준다. */
    box-sizing: border-box; width: 100%; clear: both;
}
.bi-pop-spec--half{ grid-template-columns: 1fr 1fr; }   /* 균등 2열 — 구 float 50%/50% */
.bi-pop-spec--3{ grid-template-columns: 3fr 1fr 1fr; }
.bi-pop-slip-sep{ margin: var(--space-2_5) 0; height: 0; border-top: 1px dashed var(--pop-line); background: none; }
.bi-pop-slip-sep--b{ border-top-style: solid; }
.bi-pop-inforow{ display: flex; align-items: center; justify-content: space-between; min-height: 30px; }
.bi-pop-inforow--lbl130{ justify-content: flex-start; gap: var(--space-2); padding-bottom: var(--space-3); }
.bi-pop-inforow--lbl130 > :first-child{ flex: 0 0 130px; }
.bi-pop-spec--total{ font-weight: var(--fw-bold); border-top: 1px solid var(--border-base); }
.bi-pop-clist-item.is-sel .bi-pop-clist-meta{ color: var(--color-indigo-600); }.bi-promo__deco { position: absolute; right: 0; top: 0; height: 100%; width: 33%; opacity: 0.1; pointer-events: none; }
.bi-promo__deco svg { height: 100%; width: 100%; }
.bi-promo__body { position: relative; z-index: 10; }   /* 본문은 폭 제한 없음 → 닫기 버튼 우측 끝 정렬 */
.bi-promo__top { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: var(--space-4); }
.bi-promo__badge {
    padding: var(--space-1) var(--space-3); border-radius: var(--radius-full);
    background: color-mix(in srgb, var(--white) 20%, transparent);
    border: 1px solid color-mix(in srgb, var(--white) 10%, transparent);
    font-size: var(--fs-sm); font-weight: var(--fw-semibold);
    color: var(--bg-card);                    /* 흰 글자 (상속 의존 X) */
}
/* 배너 닫기 — 높이를 안 정해 글자 높이(16px)가 그대로 버튼 높이가 됐다.
 * 누르는 것은 사다리를 따른다 → xs 22(§12-4, 2026-08-14). */
.bi-promo__close {
    display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1);
    height: 22px; padding: 0 var(--space-1_5);
    background: none; border: none; cursor: pointer;
    font-size: var(--fs-sm); opacity: 0.8; transition: opacity .15s;
    color: var(--bg-card);
}
.bi-promo__close:hover { opacity: 1; }
.bi-promo__title { font-size: var(--fs-2xl); font-weight: var(--fw-bold); line-height: 1.25; margin: 0 0 var(--space-3); color: var(--bg-card); }   /* text-2xl, white */
.bi-promo__desc { font-size: var(--fs-md); line-height: 1.625; margin: 0 0 var(--space-8); max-width: 42rem; color: color-mix(in srgb, var(--white) 80%, transparent); }   /* text-white/80 */
/* 배너의 주 액션 — 높이를 안 정해 padding 이 높이를 만들었다(40·42, 테두리 유무로 갈림).
 * 눌러야 하는 것은 사다리를 따른다 → lg 48(§12-4, 2026-08-14). */
.bi-promo__btn { height: 48px; display: inline-flex; align-items: center; justify-content: center; padding: 0 var(--space-6); box-sizing: border-box; border-radius: var(--radius-lg); font-size: var(--fs-md); font-weight: var(--fw-bold); cursor: pointer; transition: background .15s; border: none; }
.bi-promo__btn--light { background: var(--bg-card); color: var(--brand-blue); }   /* 파란 글자 */
.bi-promo__btn--light:hover { background: var(--border-light); }
.bi-promo__btn--navy { background: var(--brand-navy); color: var(--bg-card); border: 1px solid color-mix(in srgb, var(--white) 20%, transparent); }   /* 흰 글자 */
.bi-promo__btn--navy:hover { background: var(--brand-navy-hover); }
.bi-promo__mockup {
    position: absolute; right: 48px; top: 48px; bottom: 0; width: 320px;
    background: color-mix(in srgb, var(--white) 10%, transparent);
    border: 1px solid color-mix(in srgb, var(--white) 20%, transparent); border-bottom: none;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0; padding: var(--space-4);
}
.bi-promo__tags { display: flex; gap: var(--space-2); margin-bottom: var(--space-4); }
.bi-promo__tags span { padding: var(--space-0_5) var(--space-2); border-radius: var(--radius-full); background: color-mix(in srgb, var(--white) 20%, transparent); font-size: var(--fs-2xs); }
.bi-promo__lines { display: flex; flex-direction: column; gap: var(--space-2); opacity: 0.5; }
.bi-promo__line { height: 8px; background: var(--bg-card); border-radius: var(--radius-sm); width: 100%; }
.bi-promo__line--3q { width: 75%; }
.bi-promo__line--5q { width: 83%; }
.bi-promo__spark { position: absolute; bottom: 16px; right: 16px; font-size: var(--icon-md); color: var(--bg-card); opacity: 0.8; }
.bi-statgrid--2 { grid-template-columns: repeat(2, 1fr); }
.bi-dash-kpi-lb { font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--txt-disabled); margin-bottom: var(--space-1); white-space: nowrap; }  /* text-xs font-medium text-gray-400 */
.bi-dash-kpi { font-size: var(--fs-3xl); font-weight: var(--fw-bold); color: var(--txt-primary); line-height: 1.1; }  /* text-3xl font-bold */
.bi-stat--navy { background: var(--brand-navy); border-color: var(--brand-navy); box-shadow: var(--shadow-md); }
.bi-stat--navy .bi-dash-kpi-lb { color: color-mix(in srgb, var(--white) 70%, transparent); }   /* text-white/70 */
.bi-stat--navy .bi-dash-kpi { color: var(--bg-card); }
.bi-stat--navy:hover { border-color: var(--brand-navy); }
.bi-stat--navy.is-active { box-shadow: var(--shadow-md); }
.bi-stat--purple { background: var(--brand-purple); border-color: var(--brand-purple); box-shadow: var(--shadow-md); }
.bi-stat--purple .bi-dash-kpi-lb { color: color-mix(in srgb, var(--white) 70%, transparent); }
.bi-stat--purple .bi-dash-kpi { color: var(--bg-card); }
.bi-stat--purple:hover { border-color: var(--brand-purple); }
.bi-stat--purple .bi-stat__ico { color: color-mix(in srgb, var(--white) 30%, transparent); }   /* ArrowUpRight text-white/30 */
.bi-stat--purple.is-active { box-shadow: var(--shadow-md); }   /* 강조 카드 활성 시 파란 링 대신 고유 그림자 (navy 와 동일) */
.bi-simpletbl tbody tr: last-child td { border-bottom: none; }
.bi-simpletbl tbody tr: hover { background: color-mix(in srgb, var(--bg-input) 50%, transparent); }
.bi-simpletbl__time { color: var(--gray-600); font-weight: var(--fw-medium); white-space: nowrap; }   /* text-gray-600 font-medium */
.bi-simpletbl__name { font-weight: var(--fw-bold); color: var(--txt-primary); }   /* font-bold text-gray-900 */
.bi-simpletbl__cell { color: var(--txt-muted); }
.bi-simpletbl__cell--ok { color: var(--color-success-500); }           /* 미지정 = green */
.bi-simpletbl__memo { text-align: right; color: var(--txt-disabled); font-size: var(--fs-sm); max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }  /* text-gray-400 text-xs truncate */
.bi-simpletbl-empty { text-align: center; color: var(--txt-disabled); padding: var(--space-8) 0; }
.bi-simpletbl-more {
    width: 100%; margin-top: var(--space-4); padding: var(--space-2); border: none; cursor: pointer;
    background: none; border-radius: var(--radius-lg);
    font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--brand-blue);
    transition: background .15s;
}
.bi-simpletbl-more:hover { background: var(--color-info-50); }   /* hover:bg-blue-50 */
.bi-carousel__btn {
    width: 32px; height: 32px; border: none; background: none; cursor: pointer;
    border-radius: var(--radius-full); color: var(--txt-disabled); font-size: var(--fs-md);
    display: flex; align-items: center; justify-content: center;
    transition: background .15s, color .15s;
}
.bi-carousel__btn:hover { background: var(--border-light); color: var(--txt-muted); }
.bi-carousel__track { display: flex; gap: var(--space-4); transition: transform .3s ease; }
.bi-carousel__avatar { position: relative; margin-bottom: var(--space-3); }.bi-carousel__card:hover .bi-carousel__avatar img { transform: scale(1.05); }
.bi-carousel__avatar-ph { display: flex; align-items: center; justify-content: center; background: var(--border-light); color: var(--txt-disabled); font-size: var(--fs-2xl); }
.bi-carousel__name { font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--txt-primary); margin: 0; }
.bi-carousel__role { font-size: var(--fs-sm); color: var(--txt-disabled); margin: 0 0 var(--space-4); }
.bi-carousel__stats { display: flex; justify-content: space-between; width: 100%; text-align: center; padding: 0 var(--space-2); }
.bi-carousel__stat { display: flex; flex-direction: column; align-items: center; }
.bi-carousel__stat-lb { font-size: var(--fs-2xs); color: var(--txt-disabled); margin-bottom: var(--space-1); display: flex; align-items: center; gap: var(--space-1); }
.bi-carousel__divider { width: 1px; background: var(--border-light); align-self: stretch; }
.bi-carousel__empty { color: var(--txt-disabled); padding: var(--space-6); text-align: center; width: 100%; }
.bi-input--xs        { height: 16px; }
.bi-input--xs2       { height: 19px; }
.bi-input--sm        { height: 25px; }
.bi-input--sm2       { height: 30px; }
.bi-input--lg        { height: 46px; font-size: var(--fs-md); }
.bi-input--xl        { font-size: var(--fs-xl); }   /* 글자만 키운다 — 금액칸 */
.bi-input--w30       { width: 30px; }
.bi-input--w65       { width: 65px; }
.bi-input--w110      { width: 110px; }
.bi-input--w155      { width: 155px; }
.bi-input--w250      { width: 250px; }
.bi-input--w300      { width: 300px; }
.bi-input--plain     { border: none; margin-top: 0; pointer-events: none; font-weight: var(--fw-bold); }
.bi-proditem-row{ display: grid; grid-template-columns: 226px 100px 116px 117px; align-items: center; }
/* 구성상품 표 — 머리와 줄이 «같은 격자» 를 쓰게 한다 (2026-09-04 사용자 지시).
   전에는 머리만 격자(226+100+116+117=559)였고 줄은 float + 인라인 width 였다.
   그래서 720 팝업 안에서 오른쪽 125px 이 통째로 비었다. 상품명 칸을 1fr 로 늘려 폭을 다 쓴다. */
.bi-proditem-row--fluid{ grid-template-columns: 1fr 92px 124px 124px; gap: var(--space-2); }
.bi-proditem-cell{ display: flex; align-items: center; gap: var(--space-1_5); min-width: 0; }
.bi-proditem-cell > input[type="text"]{ flex: 1 1 auto; min-width: 0; width: auto; }
/* ⚠ 전역 .li-style 이 `float:left · width:98% · padding:6px` 을 준다 — 격자와 싸운다.
   실측: 머리는 18~700 인데 줄은 18~686 으로 «14px 짧았다». 눈으로는 안 보이는 어긋남이다.
   그리고 .ul-style 의 `margin-bottom:50px` 이 표 아래 빈 띠를 만들었다. 둘 다 여기서 되돌린다. */
#pro_list_ul{ margin: var(--space-2_5) 0 0; }
#pro_list_ul > li.bi-proditem-row--fluid{ float: none; width: auto; padding: var(--space-1) 0; }
/* 상품 고르기 돋보기 — 인라인 style(색·밑줄)로 그리던 것을 클래스로 옮겼다(2026-09-04) */
.bi-proditem-pick{ flex: 0 0 auto; color: var(--txt-primary); text-decoration: none; }
.bi-input--w90       { width: 90px; }
.bi-pop-lbl-pad    { padding-top: var(--space-0_5); }   /* 읽기전용 값 옆 라벨 미세 정렬 */
.bi-pop-picker__col--h300{ height: 300px; }
.bi-pop-slip-body  { padding: var(--space-2_5) 0; font-size: var(--fs-sm); }
.bi-pop-slip-title { font-size: var(--fs-lg); font-weight: var(--fw-bold); padding: var(--space-2_5) 0; }
.bi-pop-slip-sign{ position: relative; border: 1px solid var(--pop-line); border-radius: var(--radius-lg); background: var(--bg-card); overflow: hidden; }
.bi-pop-slip-sign::after{ content: '이 칸에 서명해 주세요'; position: absolute; left: var(--space-3_5); right: var(--space-3_5); bottom: var(--space-3);
    border-top: 1px dashed var(--pop-line); padding-top: var(--space-1_5); text-align: center;
    font-size: var(--pop-cnt-fs); color: var(--txt-disabled); pointer-events: none; }
.bi-pop-slip-sign canvas{ position: relative; z-index: 1; }
.bi-pop-slip-sign img{ display: block; position: absolute; left: 0; top: 0;
                        border-radius: var(--radius-sm); box-shadow: var(--shadow-xs) inset;
                        border: 1px solid var(--border-base); width: 250px; height: 150px; }
.bi-pop-slip-canvas{ touch-action: none; user-select: none; width: 100%; height: 150px; display: block; }
/* ⚠ 2026-10-06 사용자 지적 — 「서명 파일 저장까지 확인했는데 서명 사진을 불러오는 게 안 되고 있어」.
   그림은 불러와졌다(실측 naturalWidth > 0) — **가려져 있었다.** 위 canvas 가 z-index:1 이고 SignaturePad 가
   backgroundColor '#eee' 로 칠해 불투명이라 그 밑의 .signimg 를 덮는다. 구 사이트는 canvas 에 위치 지정이 없어
   그림(absolute)이 위에 섰다 → 같은 차례로 되돌린다. 「서명 지우기」 가 그림을 숨기고 새로 그리게 하는 흐름은 그대로.
   폭도 칸 전체(canvas 와 같은 100% × 150)로 — 저장된 그림이 canvas 통째(배경 포함)라 칸을 꼭 맞게 덮는다. */
.bi-pop-slip-sign img.signimg{ z-index: 2; width: 100%; height: 150px; border: 0; border-radius: 0; box-shadow: none; }
.bi-search-wrap--full{ max-width: none; width: 100%; }
.bi-search-icon--right { left: auto; right: 12px; pointer-events: auto; cursor: pointer; z-index: 5; }
/* 2026-10-01 로그인 비밀번호 보기/숨기기 — 오른쪽 눈 아이콘 자리만큼 입력 오른쪽을 비운다
   (긴 비밀번호가 아이콘 밑으로 들어가지 않게). 보기 상태에서는 type=text 가 되므로 둘 다 잡는다. */
.bi-search-wrap.bi-search-wrap--pw input[type="password"].bi-input,
.bi-search-wrap.bi-search-wrap--pw input[type="text"].bi-input { padding-right: var(--space-10); }
.bi-modal--lg { max-width: 640px; }
.bi-modal__head {
    display: flex; align-items: center; justify-content: space-between;
    padding: var(--space-5) var(--space-6);
    border-bottom: 1px solid var(--border-light);
}
.bi-modal__head-ico {
    width: 38px; height: 38px; border-radius: var(--radius-xl);
    background: var(--color-info-50); color: var(--brand-blue);
    display: flex; align-items: center; justify-content: center;
    font-size: var(--fs-lg); flex-shrink: 0;
}
.bi-modal__head-txt h3 { margin: 0; font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--txt-primary); }
.bi-modal__head-txt p  { margin: var(--space-0_5) 0 0; font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-modal__close {
    width: 32px; height: 32px; border: none; background: transparent;
    color: var(--txt-disabled); border-radius: var(--radius-lg);
    cursor: pointer; font-size: var(--fs-lg);
}
.bi-modal__close:hover { background: var(--border-light); color: var(--txt-secondary); }
.bi-modal__foot {
    display: flex; justify-content: flex-end; gap: var(--space-2);
    padding: var(--space-4) var(--space-6);
    background: var(--bg-input); border-top: 1px solid var(--border-light);
}
.bi-modal__divider { height: 1px; background: var(--border-light); }
.bi-modal__body--sections { display: flex; flex-direction: column; gap: var(--space-5); }
.bi-modal__label {
    display: flex; align-items: center; justify-content: space-between;
    font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-secondary);
    margin-bottom: var(--space-2_5);
}
.bi-linkbtn {
    border: none; background: transparent; cursor: pointer;
    color: var(--brand-blue); font-size: var(--fs-sm); font-weight: var(--fw-semibold);
}
.bi-linkbtn:hover { text-decoration: underline; }
.bi-avatar--lg { width: 40px; height: 40px; font-size: var(--fs-md); }
.bi-avatar      { position: relative; overflow: visible; }
.bi-avatar__img {
    position: absolute; inset: 0; width: 100%; height: 100%;
    border-radius: var(--radius-full); object-fit: cover;
    background: var(--bg-card); z-index: 1;
}
.bi-avatar__initial { line-height: 1; }
.bi-avatar__dot {
    position: absolute; bottom: -1px; right: -1px; width: 11px; height: 11px;
    border-radius: var(--radius-full); background: var(--color-success-500);
    border: 2px solid var(--white); z-index: 2;
}
.bi-dropdown--below {
    position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
    margin-top: var(--space-1); min-width: 188px; z-index: 50;
    padding: 0 0 var(--space-1); overflow: hidden; text-align: left;
    border-radius: var(--radius-xl); box-shadow: var(--shadow-lg);
}
.bi-dropdown__label {
    padding: var(--space-2) var(--space-3) var(--space-1_5);
    font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--txt-disabled);
    letter-spacing: 0.04em; background: var(--bg-input); text-transform: uppercase;
}
.bi-dropdown__divider { height: 1px; background: var(--border-light); margin: var(--space-1) 0; }
.bi-dropdown__item   { display: flex; align-items: center; gap: var(--space-2); width: 100%; border: none; background: transparent; text-align: left; }
.bi-dropdown__item i { width: 14px; text-align: center; font-size: var(--fs-sm); color: var(--txt-disabled); }
.bi-dropdown__item:hover i { color: var(--brand-blue); }
.bi-dropdown__item--danger:hover { background: var(--color-danger-50); color: var(--color-danger-600); }
.bi-dropdown__item--danger:hover i { color: var(--color-danger-600); }
.bi-pickgrid--4 { grid-template-columns: repeat(4, 1fr); }
.bi-pick__av { overflow: hidden; }
.bi-pick--danger.bi-pick--on { background: var(--color-danger-50); border-color: var(--color-danger-200); color: var(--color-danger-600); box-shadow: none; }
.bi-pick--danger.bi-pick--on::after { background: var(--color-danger-600); }
.bi-datenav__mid { display: flex; align-items: center; gap: var(--space-1_5); padding: 0 var(--space-2); }
.bi-datenav__ico { color: var(--brand-blue); font-size: var(--fs-base); flex-shrink: 0; }
.bi-schmx { width: 100%; flex: 1; min-height: 0; overflow: auto; white-space: nowrap; }
.bi-schmx::-webkit-scrollbar { width: 8px; height: 8px; }
.bi-schmx::-webkit-scrollbar-thumb { background: var(--gray-300); border-radius: var(--radius-sm); }
.bi-schmx::-webkit-scrollbar-track { background: var(--bg-input); }
.bi-schmx__head {
    height: 152px; display: flex; flex-direction: column;
    align-items: center; justify-content: center; text-align: center;
    background: var(--bg-card); border-bottom: 1px solid var(--border-light);
    position: sticky; top: 0; z-index: 5; box-sizing: border-box;
    padding: var(--space-3_5) var(--space-2); transition: background 0.12s;
}
.bi-schmx__col:not(.bi-schmx__col--time) .bi-schmx__head:hover { background: var(--bg-input); }
.bi-schmx__col--time .bi-schmx__head { width: auto; }
.bi-schmx__head-in { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); width: 100%; text-align: center; }
.bi-schmx__timelb { font-size: var(--fs-xs); font-weight: var(--fw-semibold); color: var(--txt-disabled); letter-spacing: 0.02em; }
.bi-schmx__row { height: 48px; padding: var(--space-1_5); border-bottom: 1px solid var(--bg-input); box-sizing: border-box; }
.bi-schmx__col--time .bi-schmx__row {
    display: flex; align-items: center; justify-content: center;
    font-size: var(--fs-xs); font-weight: var(--fw-medium); color: var(--txt-muted);
    font-family: var(--font-mono, monospace);
    border-bottom: 1px solid var(--border-light); background: var(--bg-card);
    cursor: pointer; padding: 0; text-align: center;
    transition: background 0.12s, color 0.12s;
}
.bi-schmx__col--time .bi-schmx__row:hover { color: var(--brand-blue); background: var(--color-info-50); }
.bi-schmx__col--time .bi-schmx__row br { display: none; }
.bi-schmx__timetxt,
/* 2026-09-30 — .bi-bk2-empty(«빈 시간 · 칸을 클릭하여 예약» 안내)를 사용자 지시로 걷었다. 규칙 셋을 같이 지웠다. */
.bi-schmx__row .bi-schmx__slot--booked { background: var(--color-danger-50); border-color: var(--color-danger-200); }
.bi-schmx__row .bi-schmx__slot--booked:hover { background: var(--color-danger-100); }
.bi-schmx__row .bi-schmx__slot--booked .bi-schmx__count { color: var(--color-danger-600); }
.bi-erp-card--flush { padding: 0; overflow: hidden; display: flex; flex-direction: column; flex: 1; min-height: 0; }
.bi-chip__x { margin-left: var(--space-1_5); font-weight: var(--fw-bold); font-size: var(--fs-md); line-height: 1; color: var(--txt-disabled); transition: color .15s; }
.bi-chip:hover .bi-chip__x { color: var(--brand-blue); }
.bi-chipbox {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
    border: 1px solid var(--color-info-100);
    background: color-mix(in srgb, var(--color-info-50) 40%, transparent);
    padding: var(--space-3) var(--space-3_5);
    border-radius: var(--radius-xl); min-height: 50px;
}
.bi-chipbox--tight { padding: var(--space-2_5) var(--space-3); min-height: 25px; }
.bi-chipbox__lb { flex-shrink: 0; font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--brand-blue); letter-spacing: 0.03em; }
.bi-countpill__n { color: var(--brand-blue); font-size: var(--fs-lg); }
.bi-countpill--sel   { background: color-mix(in srgb, var(--brand-blue) 10%, transparent); color: var(--brand-blue); }
.bi-countpill--total { background: var(--border-light); color: var(--gray-600); }
.bi-datatbl thead th.bi-datatbl__cb { width: 50px; text-align: center; }
.bi-datatbl td.bi-datatbl__nowrap { white-space: nowrap; }
.bi-datatbl__loading { text-align: center; padding: var(--space-8) var(--space-5); background: var(--bg-page); }
.bi-fpanel__title-txt { font-size: var(--fs-md); font-weight: var(--fw-semibold); color: var(--gray-800); }
.bi-fpanel__chev      { width: 20px; height: 20px; color: var(--txt-muted); transition: transform .3s; }
.bi-fpanel.is-open .bi-fpanel__chev { transform: rotate(180deg); }
.bi-fcat__title {
    display: flex; align-items: center; gap: var(--space-1_5);
    font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-primary);
    margin-bottom: var(--space-2_5); letter-spacing: -0.01em;
}
.bi-fcat__title i { color: var(--brand-blue); font-size: var(--fs-base); width: 14px; text-align: center; }
.bi-msgprev {
    background: var(--border-light); border: 1px solid var(--border-base);
    border-radius: var(--radius-2xl); padding: var(--space-5);
    font-size: var(--fs-md); line-height: 1.7; color: var(--txt-secondary);
}
.bi-msgprev.is-editing { border-color: var(--brand-blue); box-shadow: var(--ring-focus); outline: none; }
.bi-msgprev__var       { color: var(--txt-disabled); font-weight: var(--fw-semibold); font-size: var(--fs-md); }
.bi-checkbox-native[type="checkbox"] {
    visibility: visible; display: inline-block;
    width: 16px; height: 16px; margin: 0;
    accent-color: var(--brand-blue); cursor: pointer;
}
.bi-checkbox-native + label { display: none; }
.bi-datatbl__more-body {
    max-width: 100%;
}
.bi-datatbl__more-text {
    background: white;
    border: 1px solid var(--color-warning-300);
    border-radius: var(--radius-xl);
    padding: var(--space-5);
    color: var(--txt-muted);
    font-size: var(--fs-md);
    margin: var(--space-2_5) 0;
    text-align: left;
}
.bi-queue__time { font-size: var(--fs-xs); font-weight: var(--fw-extrabold); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-xs); background: var(--color-info-50); color: var(--color-info-600); border: 1px solid var(--color-info-100); flex-shrink: 0; }
.bi-queue__time.is-none { background: var(--bg-input); color: var(--txt-disabled); border-color: var(--border-base); }
.bi-queue__phone { font-size: var(--fs-sm); color: var(--txt-muted); font-family: monospace; }
.bi-desk__hist-sec { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-4); }
.bi-desk__hist-list { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-3_5); padding-right: var(--space-1); }
.bi-desk__hist-item { position: relative; padding-left: var(--space-4); border-left: 1px solid var(--gray-100); }
.bi-desk__hist-box { background: color-mix(in srgb, var(--bg-input) 60%, transparent); border: 1px solid var(--border-base); border-radius: var(--radius-xl); padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); }
.bi-desk__hist-box-top span: first-child { font-family: monospace; font-weight: var(--fw-extrabold); color: var(--txt-primary); }
.bi-desk__hist-emp { font-size: var(--fs-xs); color: var(--txt-muted); background: var(--border-light); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm); font-weight: var(--fw-bold); }
.bi-desk__hist-sum { font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-secondary); line-height: 1.5; margin: 0; }
.bi-desk__hist-memo { padding-top: var(--space-2); border-top: 1px dashed var(--border-base); font-size: var(--fs-2xs); color: var(--gray-500); line-height: 1.5; }
.bi-desk__hist-memo span { font-weight: var(--fw-extrabold); color: var(--txt-secondary); display: block; margin-bottom: var(--space-0_5); }
.bi-desk__hist-memo p { background: color-mix(in srgb, var(--white) 80%, transparent); padding: var(--space-1_5); border-radius: var(--radius-sm); border: 1px solid color-mix(in srgb, var(--border-base) 50%, transparent); font-family: monospace; margin: 0; }
.bi-desk__consult { border-top: 1px solid var(--gray-100); padding-top: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); flex-shrink: 0; }
.bi-desk__consult--top { border-top: 0; border-bottom: 1px solid var(--gray-100); padding: var(--space-4); }
.bi-desk__consult-ta { width: 100%; height: auto; min-height: 112px; font-size: var(--fs-md); padding: var(--space-2_5); background: color-mix(in srgb, var(--color-warning-50) 20%, transparent); border: 1px solid var(--color-warning-200); border-radius: var(--radius-xl); outline: none; resize: none; line-height: 1.625; color: var(--gray-800); box-shadow: var(--shadow-inset); }
/* ⚠ 2026-10-02 — .bi-desk__consult-ta 는 width:100% + padding 인데 box-sizing 이 content-box 라 부모 밖으로 22px 넘쳤다(오른쪽 테두리가 잘림, L3 캡처에서 발견). 기존 규칙을 고치지 않고 수식 클래스로 맞춘다. */
.bi-desk__consult-ta--fit { box-sizing: border-box; max-width: 100%; }
.bi-desk__consult-ta:focus { background: var(--bg-card); border-color: var(--brand-blue); }
.bi-desk__bal { background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-xl); padding: var(--space-3); box-shadow: var(--shadow-sm); display: flex; flex-direction: column; gap: var(--space-2); }
.bi-desk__ticket-info h5 { font-size: var(--fs-base); font-weight: var(--fw-extrabold); color: var(--txt-primary); margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-basket__title { font-size: var(--fs-md); font-weight: var(--fw-extrabold); color: var(--color-indigo-900); display: inline-flex; align-items: center; gap: var(--space-1_5); }
.bi-basket__title i { color: var(--color-indigo-700); }
.bi-basket__row-r span { font-family: monospace; color: var(--gray-600); font-weight: var(--fw-bold); }
.bi-deskbar { background: var(--color-success-50); border: 2px solid var(--color-success-200); border-radius: var(--radius-2xl); padding: var(--space-4); display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); }
.bi-deskbar__ic { width: 40px; height: 40px; border-radius: 50%; background: var(--color-success-100); color: var(--color-success); display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-size: var(--fs-xl); }
.bi-deskbar__txt h4 { font-size: var(--fs-lg); font-weight: var(--fw-extrabold); color: var(--color-success-800); margin: 0; }
.bi-deskbar__txt p { font-size: var(--fs-base); color: var(--color-success-700); line-height: 1.5; margin: 0; }
.bi-deskbar__meta { display: flex; flex-wrap: wrap; gap: var(--space-1); align-items: center; font-size: var(--fs-base); }
.bi-deskbar__time { background: var(--color-success-200); color: var(--color-success-800); padding: var(--space-0_5) var(--space-2); border-radius: var(--radius-sm); font-weight: var(--fw-extrabold); }
.bi-deskbar__sep { color: var(--txt-disabled); }
.bi-deskbar__lbl { color: var(--color-success-700); font-weight: var(--fw-bold); }
.bi-deskbar__close { border: 0; background: none; color: var(--color-success-400); cursor: pointer; padding: var(--space-1); border-radius: 50%; }
.bi-deskbar__close:hover { color: var(--color-success-700); background: var(--color-success-100); }
.bi-segment__btn-nm { font-size: var(--fs-sm); font-weight: var(--fw-black); }
.bi-segment__btn-cnt { font-size: var(--fs-xs); font-family: monospace; opacity: .75; }
.bi-qchip { font-size: var(--fs-xs); padding: var(--space-0_5) var(--space-1); border-radius: var(--radius-xs); font-weight: var(--fw-bold); }
.bi-qchip--grade { color: var(--color-indigo-600); background: color-mix(in srgb, var(--color-indigo-500) 10%, transparent); }
.bi-qchip--danger { color: var(--color-danger-600); background: color-mix(in srgb, var(--color-danger) 10%, transparent); font-weight: var(--fw-black); }
.bi-qchip--scalp { color: var(--color-warning-700); background: color-mix(in srgb, var(--color-warning) 10%, transparent); max-width: 130px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }.bi-desk__chart-info { display: inline-flex; align-items: center; gap: var(--space-2); min-width: 0; }
.bi-desk__chart-key { font-size: var(--fs-sm); background: color-mix(in srgb, var(--brand-blue) 5%, transparent); color: var(--brand-blue); padding: var(--space-1_5) var(--space-2_5); border-radius: var(--radius-lg); font-weight: var(--fw-bold); display: inline-flex; align-items: center; gap: var(--space-1); white-space: nowrap; }
.bi-desk__chart-key b { color: var(--brand-navy); font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; font-weight: var(--fw-extrabold); font-size: var(--fs-base); }
.bi-desk__chart-key.is-new { background: var(--color-warning-50); color: var(--color-warning-700); }
.bi-desk__chart-key.is-new b { color: var(--color-warning-600); font-family: var(--font-sans); }
.bi-desk__records { width: 60%; overflow-y: auto; padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-4); border-right: 1px solid var(--border-base); }
.bi-desk__field--treat { background: color-mix(in srgb, var(--color-purple-50) 40%, transparent); border: 1px solid var(--color-purple-200); padding: var(--space-3); border-radius: var(--radius-xl); }
.bi-desk__field-lbl { font-size: var(--fs-base); font-weight: var(--fw-black); color: var(--gray-800); display: inline-flex; align-items: center; gap: var(--space-1_5); }
.bi-desk__field-lbl--alt { color: var(--color-purple-800); }
.bi-dot--info { background: var(--brand-blue); }
.bi-dot--alt { background: var(--color-purple-600); }
.bi-desk__ta { width: 100%; box-sizing: border-box; font-size: var(--fs-base); padding: var(--space-2_5); background: var(--bg-input); border: 1px solid var(--border-base); border-radius: var(--radius-lg); outline: none; line-height: 1.6; height: auto; min-height: 90px; color: var(--gray-800); resize: vertical; box-shadow: var(--shadow-inset); }
.bi-desk__ta:focus { background: var(--bg-card); border-color: var(--brand-blue); }
.bi-desk__ta--treat { background: var(--bg-card); border-color: var(--color-purple-200); min-height: 110px; color: var(--color-purple-800); }
.bi-desk__ta--treat:focus { border-color: var(--color-purple-600); }
.bi-gallery { display: flex; flex-direction: column; gap: var(--space-3); padding-top: var(--space-3); border-top: 1px solid var(--gray-100); }
/* ⚠ 2026-08-21: 여기 white-space:nowrap 을 줬다가 되돌렸다. 좁은 가운데 열에서 접히길래
 * 한 줄로 묶었더니 이번엔 옆 버튼(카탈로그 더보기)에 가려 **잘렸다**. 접히는 게 잘리는 것보다 낫다.
 * 근본 원인은 제목과 버튼이 좁은 한 줄을 나눠 쓰는 것 — 레이아웃 판단이 필요하다. */
/* 갤러리 구역 머리 — 제목과 버튼을 **세로로 쌓는다** (2026-08-21)
 *
 * 원래 .bi-row-between(가로 space-between)이었다. 그런데 이 열이 좁아서 가로 배치가 성립하지 않는다:
 *   1440 — 행 201 · 버튼 108 → 제목에 93 남는데 한 줄에 220 필요 (2~3줄로 접힘)
 *   1280 — 제목 폭 47 · 높이 92
 *   1024 — 제목 폭 **18** · 높이 **152** ← 글자가 세로로 한 자씩 흐른다
 * 버튼이 행을 통째로 먹는다. 폭을 나눠 쓸 수가 없다.
 *
 * ⚠ 제목에 white-space:nowrap 을 준 적이 있는데(2026-08-14), 접힘이 **잘림**으로 바뀌었다 —
 *   옆 버튼에 가려 글자가 사라졌다. **접히는 게 잘리는 것보다 낫고, 안 접히는 게 가장 낫다.**
 *   가로를 나눠 쓰는 걸 포기하면 셋 다 사라진다. */
.bi-gallery__head { display: flex; flex-direction: column; align-items: stretch; gap: var(--space-2); }
.bi-gallery__head > :last-child { align-self: flex-end; }
.bi-gallery__title { font-size: var(--fs-base); font-weight: var(--fw-black); color: var(--txt-primary); }
.bi-gallery__box { background: var(--bg-input); border: 1px solid var(--gray-100); border-radius: var(--radius-lg); padding: var(--space-2_5); display: flex; flex-direction: column; gap: var(--space-1_5); }
.bi-gallery__box--vt { background: color-mix(in srgb, var(--color-purple-50) 40%, transparent); border-color: var(--color-purple-200); }
.bi-gallery__boxtitle { font-size: var(--fs-base); font-weight: var(--fw-extrabold); color: var(--gray-800); }
.bi-gallery__boxtitle--vt { color: var(--color-purple-800); }
.bi-gallery__vt { color: var(--color-purple-700); border-color: var(--color-purple-200); }
.bi-gallery__grid { display: grid; grid-template-columns: repeat(3,1fr); gap: var(--space-2); }
.bi-gallery__thumb--vt { border-color: var(--color-purple-200); }
.bi-gallery__empty { border: 1px dashed var(--border-base); border-radius: var(--radius-md); padding: var(--space-3); text-align: center; color: var(--txt-muted); font-size: var(--fs-sm); }
/* ⚠ flex:1 + min-height:0 은 «필요하면 0 까지 줄어라» 는 뜻이다. 열이 스크롤하게 된 뒤로는
 *   그 말이 목록을 0 으로 만들어 머리(47px)만 남았다(안 102 > 칸 47, 2026-08-14).
 *   늘어나되 **줄어들지는 않는다** — 넘치면 열이 스크롤한다. */
.bi-timeline { width: 100%; flex: 1 0 auto; display: flex; flex-direction: column; overflow: hidden; min-height: 0; }
.bi-timeline__head { padding: var(--space-3); border-bottom: 1px solid var(--gray-100); background: color-mix(in srgb, var(--bg-input) 30%, transparent); display: flex; justify-content: space-between; align-items: center; flex-shrink: 0; }
.bi-timeline__title { font-size: var(--fs-base); font-weight: var(--fw-black); color: var(--gray-900); display: inline-flex; align-items: center; gap: var(--space-1_5); }
.bi-timeline__title i { color: var(--brand-blue); }
.bi-timeline__count { font-size: var(--fs-xs); font-weight: var(--fw-bold); background: var(--border-base); color: var(--txt-secondary); padding: var(--space-0_5) var(--space-2); border-radius: var(--radius-full); font-family: monospace; }
.bi-timeline__list { flex: 1; overflow-y: auto; padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-3); background: color-mix(in srgb, var(--bg-input) 20%, transparent); }
.bi-timeline__tip { padding: var(--space-2); background: color-mix(in srgb, var(--color-info-50) 50%, transparent); border-top: 1px solid var(--gray-100); font-size: var(--fs-xs); color: var(--brand-blue); line-height: 1.5; font-weight: var(--fw-medium); flex-shrink: 0; }
.bi-timeline__dot { position: absolute; left: 0; top: 6px; width: 10px; height: 10px; border-radius: var(--radius-full); border: 2px solid var(--gray-300); background: var(--bg-card); z-index: 1; }
.bi-timeline__tl.is-selected .bi-timeline__dot { background: var(--brand-blue); border-color: var(--brand-blue); transform: scale(1.1); }
.bi-timeline__card { padding: var(--space-2); border: 1px solid var(--gray-100); border-radius: var(--radius-lg); background: var(--bg-card); }
.bi-timeline__tl.is-selected .bi-timeline__card { background: var(--dc-blue-soft); border-color: color-mix(in srgb, var(--brand-blue) 20%, transparent); }
.bi-timeline__card:hover { background: var(--bg-input); }
.bi-timeline__top { margin-bottom: var(--space-1); }   /* 배치는 §40-10 프리미티브가 맡는다(2026-08-11) */
.bi-timeline__topl { display: inline-flex; align-items: center; gap: var(--space-1_5); min-width: 0; }
.bi-timeline__top strong { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--gray-900); }
.bi-timeline__key { font-size: var(--fs-xs); font-family: monospace; font-weight: var(--fw-bold); color: var(--txt-muted); background: var(--border-light); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-xs); }
.bi-timeline__latest { font-size: var(--fs-xs); background: color-mix(in srgb, var(--brand-blue) 10%, transparent); color: var(--brand-blue); font-weight: var(--fw-bold); padding: 0 var(--space-1); border-radius: var(--radius-xs); }
.bi-timeline__emp { font-size: var(--fs-xs); color: var(--txt-muted); }
.bi-timeline__sum { font-size: var(--fs-xs); color: var(--txt-secondary); line-height: 1.5; background: color-mix(in srgb, var(--bg-input) 60%, transparent); padding: var(--space-1_5); border-radius: var(--radius-sm); margin-top: var(--space-1_5); border: 1px solid var(--border-light); }
.bi-pick__cat { font-size: var(--fs-xs); color: var(--txt-muted); font-family: monospace; font-weight: var(--fw-bold); text-transform: uppercase; }
.bi-desk__ticket-kind { font-size: var(--fs-xs); background: color-mix(in srgb, var(--brand-navy) 5%, transparent); color: var(--brand-navy); border: 1px solid var(--border-base); padding: 0 var(--space-1); border-radius: var(--radius-xs); font-weight: var(--fw-black); text-transform: uppercase; letter-spacing: .04em; }
.bi-desk__ticket-name { font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-primary); line-height: 1.5; }
.bi-desk__ticket-btn--sm { width: auto; padding: var(--space-1) var(--space-2); font-size: var(--fs-2xs); flex-shrink: 0; }
.bi-basket__name { color: var(--gray-800); font-size: var(--fs-sm); font-weight: var(--fw-black); line-height: 1.25; word-break: break-all; }
.bi-basket__pricebox { display: flex; flex-direction: column; align-items: flex-end; }
.bi-basket__unit { font-size: var(--fs-2xs); color: var(--txt-muted); font-weight: var(--fw-bold); line-height: 1; margin-bottom: var(--space-0_5); }
.bi-basket__pkgtag { font-size: var(--fs-2xs); font-weight: var(--fw-black); color: var(--color-purple-700); background: color-mix(in srgb, var(--color-purple-700) 10%, transparent); border: 1px solid var(--color-purple-200); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-md); }
.bi-basket__price { color: var(--brand-blue); font-size: var(--fs-sm); background: color-mix(in srgb, var(--brand-blue) 5%, transparent); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm); font-weight: var(--fw-black); }
.bi-basket__price--pkg { color: var(--color-purple-700); background: color-mix(in srgb, var(--color-purple-700) 10%, transparent); }
.bi-desk__sum { padding-top: var(--space-2); border-top: 1px solid var(--border-base); display: flex; flex-direction: column; gap: var(--space-2_5); }
.bi-desk__sum-lbl { font-weight: var(--fw-extrabold); color: var(--txt-secondary); font-size: var(--fs-base); }
.bi-desk__sum-lbl .bi-num { color: var(--brand-blue); }
.bi-desk__sum-val { font-size: var(--fs-lg); font-weight: var(--fw-black); color: var(--txt-primary); }
.bi-lightbox { position: relative; display: flex; align-items: center; justify-content: center; max-width: 92vw; max-height: 90vh; }
.bi-lightbox img { max-width: 92vw; max-height: 90vh; object-fit: contain; border-radius: var(--radius-lg); background: var(--bg-card); box-shadow: var(--shadow-lg); }
.bi-lightbox__btn { position: absolute; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: 0; border-radius: 50%;   /* §12-4 아이콘 32 */ background: color-mix(in srgb, var(--black) 60%, transparent); color: var(--bg-card); font-size: var(--fs-lg); cursor: pointer; transition: background .15s; }
.bi-lightbox__btn:hover { background: color-mix(in srgb, var(--black) 80%, transparent); }
.bi-lightbox__close { top: 10px; right: 10px; }
.bi-lightbox__nav { top: 50%; transform: translateY(-50%); }
.bi-lightbox__nav--prev { left: 10px; }
.bi-lightbox__nav--next { right: 10px; }
.bi-lightbox__count { position: absolute; bottom: 10px; left: 50%; transform: translateX(-50%); background: color-mix(in srgb, var(--black) 60%, transparent); color: var(--bg-card); font-size: var(--fs-sm); font-weight: var(--fw-bold); padding: var(--space-1) var(--space-2_5); border-radius: var(--radius-full); }
.bi-basket__qty { display: inline-flex; align-items: center; gap: var(--space-1); background: var(--bg-input); border: 1px solid var(--gray-100); padding: var(--space-0_5); border-radius: var(--radius-lg); }
.bi-gallery__more:hover { background: var(--brand-blue-hover); }
.bi-gallery__more i { color: var(--bg-card); }
.bi-resv-sw--cancel { background: var(--gray-300); }
/* §72-2 예약일정표(시간)의 바닥 안내가 «10px · 흐린 회색» 이었다 — 규격안은 12 · --txt-muted 다.
   같은 자리인 예약 일정표(.bi-bk2-vfoot__hint)와도 값이 달랐다. 둘을 맞춘다. */
.bi-bksplit__foot-hint { font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-search-clear { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); border: none; background: none; color: var(--txt-disabled); cursor: pointer; font-size: var(--fs-base); }
.bi-search-clear:hover { color: var(--gray-600); }
.bi-bksplit__side { width: 280px; flex-shrink: 0; display: flex; flex-direction: column; gap: var(--space-3); overflow-y: auto; }
.bi-bksplit__main { flex: 1; min-width: 0; display: flex; flex-direction: column; background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-2xl); overflow: hidden; min-height: 500px; }
.bi-cal__dow { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); color: var(--txt-disabled); margin-bottom: var(--space-1_5); }
.bi-cal__dow .is-sun { color: var(--color-danger); }
.bi-cal__dow .is-sat { color: var(--color-info-500); }
.bi-cal__dot { position: absolute; bottom: 3px; left: 50%; transform: translateX(-50%); width: 4px; height: 4px; border-radius: var(--radius-full); background: var(--color-indigo-500); }
.bi-schmx.is-grabbing, .bi-schmx.is-grabbing * { cursor: grabbing; }
/* 배지는 한 줄이다 — 좁은 가운데 열에서 «실시간 / 대기열» 로 접혔다(2026-08-21) */
.bi-bksplit__live { white-space: nowrap; font-size: var(--fs-xs); font-weight: var(--fw-black); background: var(--color-danger-400); color: var(--bg-card); border-radius: var(--radius-sm); padding: var(--space-0_5) var(--space-2); }
.bi-bksplit__date { color: var(--txt-primary); font-weight: var(--fw-extrabold); font-size: var(--fs-sm); }
.bi-bksplit__sep { color: var(--gray-300); }
/* 라벨도 한 줄 — «16개 시술 진 / 행중» 으로 접혔다 */
.bi-bksplit__progress { white-space: nowrap; color: var(--brand-blue, var(--brand-blue)); font-weight: var(--fw-bold); font-size: var(--fs-sm); text-decoration: underline; }
.bi-schmx__inner { width: max-content; min-width: 100%; position: relative; }
.bi-schmx__headrow { display: flex; position: sticky; top: 0; z-index: 6; background: var(--white); box-shadow: var(--shadow-sm); }
.bi-schmx__corner { flex: 0 0 150px; width: 150px; position: sticky; left: 0; z-index: 8; display: flex; align-items: center; justify-content: center; border-right: 1px solid var(--border-base); border-bottom: 1px solid var(--gray-100); background: var(--bg-input); font-size: var(--fs-xs); font-weight: var(--fw-black); color: var(--txt-muted); }
.bi-schmx__drow { display: flex; min-height: 78px; align-items: stretch; }
.bi-schmx__dname { flex: 0 0 150px; width: 150px; position: sticky; left: 0; z-index: 4; display: flex; align-items: center; justify-content: space-between; gap: var(--space-1_5); padding: var(--space-2) var(--space-2_5); border-right: 1px solid var(--border-base); border-bottom: 1px solid var(--gray-100); border-left: 4px solid var(--color-indigo-500); background: var(--bg-card); }
.bi-schmx__cnt { flex-shrink: 0; font-size: var(--fs-2xs); font-weight: var(--fw-black); color: var(--color-indigo-700); background: var(--color-indigo-50); border: 1px solid var(--color-indigo-100); border-radius: var(--radius-full); padding: var(--space-0_5) var(--space-2); }
.bi-schmx__cell { flex: 0 0 104px; width: 104px; border-right: 1px solid var(--border-light); border-bottom: 1px solid var(--border-light); padding: var(--space-1_5); display: flex; flex-direction: column; gap: var(--space-1); }
.bi-schmx__slot-ico { font-size: var(--fs-sm); opacity: .6; }
.bi-schmx__slot-lbl { display: none; }
.bi-schmx__slot--free:hover .bi-schmx__slot-ico { display: none; }
.bi-schmx__slot--free:hover .bi-schmx__slot-lbl { display: inline; }
.bi-schmx__inner.is-loading, #bt_timeline.is-loading { opacity: .5; pointer-events: none; }
.bi-schmx__empty { padding: 60px var(--space-5); text-align: center; color: var(--txt-disabled); font-size: var(--fs-base); font-weight: var(--fw-bold); }
.bi-resv__time { font-family: ui-monospace, monospace; font-size: var(--fs-2xs); color: var(--txt-muted); }
.bi-resv__tr { display: flex; gap: var(--space-0_5); }
.bi-resv__name { font-size: var(--fs-xs); font-weight: var(--fw-black); color: var(--gray-900); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-resv__sub { font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--txt-disabled); }
.bi-resv__detail { font-size: var(--fs-2xs); font-weight: var(--fw-semibold); color: var(--txt-muted); margin-top: var(--space-0_5); line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-resv__memo { font-size: var(--fs-2xs); color: var(--txt-disabled); font-style: italic; margin-top: var(--space-1); padding-top: var(--space-1); border-top: 1px solid color-mix(in srgb, var(--black) 5%, transparent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-resv--cancel .bi-resv__name { text-decoration: line-through; }
.bi-resv-dot--request { background: color-mix(in srgb, var(--color-success-100) 70%, transparent); color: var(--color-success-700); border-color: var(--color-success-200); }
.bi-resv-dot--confirmed { background: color-mix(in srgb, var(--color-info-100) 70%, transparent); color: var(--color-info-700); border-color: var(--color-info-200); }
.bi-resv-dot--checkin { background: color-mix(in srgb, var(--color-warning-100) 70%, transparent); color: var(--color-warning-700); border-color: var(--color-warning-200); }
.bi-resv-dot--done { background: var(--border-base); color: var(--txt-muted); }
.bi-resv-dot--cancel { background: var(--color-danger-100); color: var(--color-danger-600); border-color: var(--color-danger-200); }
.bi-resv-dot--block { background: var(--color-danger-100); color: var(--color-danger-700); border-color: var(--color-danger-200); }
.bi-resv-naver { width: 14px; height: 14px; border-radius: var(--radius-sm); background: var(--color-npay); color: var(--bg-card); font-weight: var(--fw-black); font-size: var(--fs-2xs); display: inline-flex; align-items: center; justify-content: center; }
.bi-schmx__now { position: absolute; top: 0; bottom: 0; width: 2px; background: color-mix(in srgb, var(--color-danger) 80%, transparent); z-index: 7; pointer-events: none; }
.bi-schmx__now-lbl { position: absolute; top: 3px; left: 50%; transform: translateX(-50%); font-family: ui-monospace, monospace; font-size: var(--fs-2xs); font-weight: var(--fw-black); color: var(--bg-card); background: var(--color-danger); border-radius: var(--radius-sm); padding: var(--space-0_5) var(--space-1_5); white-space: nowrap; }
.bi-schmx__now::before { content: ''; position: absolute; top: 0; left: -4px; width: 10px; height: 10px; border-radius: var(--radius-full); background: var(--color-danger); border: 2px solid var(--white); box-shadow: var(--shadow-sm); }
.bi-bksplit__foot { height: 40px; border-top: 1px solid var(--gray-100); padding: 0 var(--space-4); background: color-mix(in srgb, var(--bg-input) 70%, transparent); display: flex; align-items: center; gap: var(--space-4); flex-shrink: 0; }
/* 2026-08-13 범례가 좁아질 때 «신 청 / 확 정» 처럼 한 글자씩 세로로 흘렀다 — 줄바꿈 금지 + 넘치면 접는다 */
.bi-bksplit__foot { flex-wrap: wrap; height: auto; min-height: 40px; padding-top: var(--space-1_5); padding-bottom: var(--space-1_5); }
.bi-bksplit__foot-lb, .bi-bksplit__foot-item { white-space: nowrap; flex-shrink: 0; }
.bi-bksplit__foot-lb { font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); text-transform: uppercase; letter-spacing: .06em; color: var(--txt-disabled); }
.bi-bksplit__foot-item { display: flex; align-items: center; gap: var(--space-1_5); font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--txt-muted); }
.bi-resv-sw { width: 10px; height: 10px; border-radius: var(--radius-xs); }
.bi-resv-sw--request { background: var(--color-warning-100); border: 1px solid var(--color-warning-200); }
.bi-resv-sw--confirmed { background: var(--color-info-50); border: 1px solid var(--color-info-200); }
.bi-resv-sw--done { background: var(--color-success-50); border: 1px solid var(--border-base); }
.bi-page .bi-bk-status-round{
    border-radius: var(--radius-2xl);
    color: white;
    padding: var(--space-2_5) var(--space-1_5);
}
.bi-page .bi-bk-sp-red{
    color: red;
}
.bi-page .bi-bk-yoil-font{
    font-size: var(--fs-sm);
    font-weight: var(--fw-normal);
}
.bi-page .bi-bk-sp-today-check{
    float: right;
    font-size: var(--fs-sm);
    color: var(--color-npay);
    line-height: 2;
    margin-right: var(--space-2_5);
}
.bi-page .bi-bk-div-status345{
    background: var(--color-purple-500);    
}
.bi-page .bi-bk-sp-deposit0{
    background: var(--color-danger); color: var(--bg-card); font-size: var(--fs-xs); font-weight: var(--fw-extrabold);
    border-radius: var(--radius-xs); padding: var(--space-0_5) var(--space-1_5); line-height: 1.4;
    display: inline-flex; align-items: center;
}
.bi-page .bi-bk-sp-deposit1{
    background: var(--gray-300); color: var(--gray-600); font-size: var(--fs-xs); font-weight: var(--fw-extrabold);
    border-radius: var(--radius-xs); padding: var(--space-0_5) var(--space-1_5); line-height: 1.4;
    display: inline-flex; align-items: center;
}
.bi-page .bi-bk-sp-deposit0 i.fas, .bi-bk-sp-deposit1 i.fas { font-size: var(--fs-xs); line-height: 1; }
.bi-bksplit__fc-title {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--fs-base);
    font-weight: var(--fw-bold);
    color: var(--txt-primary);
    border-bottom: 1px solid var(--border-light);
    padding-bottom: var(--space-2_5);
    margin-bottom: var(--space-2_5);
}
.bi-bksplit__fc-ico { color: var(--brand-blue); font-size: var(--fs-base); }
.bi-bksplit__fc-row {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    flex-wrap: wrap;
    font-size: var(--fs-base);
    margin-bottom: var(--space-2);
}
.bi-bksplit__fc-row:last-child { margin-bottom: 0; }
.bi-bksplit__fc-label {
    color: var(--txt-muted);
    font-weight: var(--fw-medium);
    white-space: nowrap;
    font-size: var(--fs-sm);
}
/* .bi-seg-wrap 계열 삭제(2026-08-21) — 세그먼트 구현이 둘이었다.
 * §29 .bi-segment/__btn 과 이 레거시(.bi-seg-wrap + input[type="button"] 요소 선택자)가
 * booking_renew 한 요소에 **동시에** 붙어 있었고, 실제로 그리는 건 레거시였다.
 * 규격 문서가 기준이므로 §29 쪽으로 통일하고 레거시를 없앤다.
 * 바뀌는 것: 글자 12→10(--fs-2xs) · 활성색 네이비/흰색 → brand-blue (§29 «활성=brand-blue+흰글자»). */
.bi-bksplit__fc-row--nav {
    border-top: 1px solid var(--border-light);
    padding-top: var(--space-3);
    margin-top: 0;
}
.bi-bksplit__calcol {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
    overflow: hidden;
    background: var(--bg-card);
    border-radius: var(--radius-xl);
    border: 1px solid var(--border-base);
    box-shadow: var(--shadow-sm);
}
.bi-cal__header {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-2_5);
    height: 46px; box-sizing: border-box; padding: 0 var(--space-4);
    border-bottom: 1px solid var(--border-base); background: var(--bg-card); flex-shrink: 0;
    white-space: nowrap; overflow: hidden;
}
.bi-cal__hleft { display: flex; align-items: center; gap: var(--space-2_5); min-width: 0; overflow: hidden; }
.bi-cal__navdate {
    display: inline-flex; align-items: center; justify-content: center;
    height: 28px; padding: 0 var(--space-3); min-width: 110px;
    background: var(--bg-input); border: 1px solid var(--border-base); border-radius: var(--radius-lg);
    color: var(--txt-primary); font-size: var(--fs-sm); font-weight: var(--fw-extrabold); white-space: nowrap;
}
.bi-cal__badge {
    display: inline-flex; align-items: center; gap: var(--space-1); flex-shrink: 0;
    font-size: var(--fs-xs); font-weight: var(--fw-extrabold); color: var(--bg-card); background: var(--color-danger-400);
    border-radius: var(--radius-md); padding: var(--space-1) var(--space-2);
}
.bi-cal__badge i { font-size: var(--fs-2xs); }
.bi-cal__date { font-size: var(--fs-base); font-weight: var(--fw-extrabold); color: var(--txt-primary); }
.bi-cal__sep { width: 1px; height: 12px; background: var(--border-base); flex-shrink: 0; }
.bi-cal__prog { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-muted); }
.bi-cal__prog b { color: var(--brand-blue); font-weight: var(--fw-extrabold); }
.bi-bksplit__empslide {
    display: none;
}.bi-bksplit__calcol {
    background: var(--bg-card);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-2xl);                       /* rounded-2xl */
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}.bi-page .bi-bk-innerPossible .bi-pos-ico { font-size: var(--fs-sm); opacity: .5; }
.bi-page .bi-bk-innerPossible .bi-pos-label { display: none; font-size: var(--fs-xs); font-weight: var(--fw-extrabold); }
.bi-page .bi-bk-innerPossible:hover .bi-pos-ico { display: none; }
.bi-page .bi-bk-innerPossible:hover .bi-pos-label { display: inline; }.bi-page .bi-agg-count {
    display: flex; align-items: center; justify-content: space-between;
    width: 100%; height: 100%; box-sizing: border-box; cursor: default;
    background: var(--color-info-50); border: 1px solid var(--color-info-200); border-radius: var(--radius-lg);
    color: var(--color-info-700); padding: var(--space-1) var(--space-2_5); white-space: nowrap;
    overflow: hidden;
}
.bi-page .bi-agg:hover .bi-agg-count { background: var(--color-info-100); border-color: var(--color-info-300); }
.bi-page .bi-agg-count-lb { font-size: var(--fs-xs); font-weight: var(--fw-bold); }
.bi-page .bi-agg-count-n { font-size: var(--fs-base); font-weight: var(--fw-extrabold); }
.bi-page .bi-agg-stat-n { font-weight: var(--fw-extrabold); }.bi-page .bi-agg-emp-line { font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--txt-muted); }
.bi-page .bi-bk-time > .bi-agg--dayactive { flex: 0 0 auto; width: 100%; margin-top: var(--space-0_5); }
.bi-page #calendar_days .bi-bk-time.is-dense .bi-bksch-card .bi-bksch-card-svc { display: none; }.bi-page #calendar_week .bi-bk-time > .bi-agg .bi-agg-count { flex: 1; height: 100%; box-sizing: border-box; }
.bi-bksch-card-badge.bi-resv-dot--request { background: var(--color-success-100); color: var(--color-success-700); border-color: var(--color-success-300); }
.bi-bksch-card-badge.bi-resv-dot--confirmed { background: var(--color-info-100); color: var(--color-info-700); border-color: var(--color-info-300); }
.bi-bksch-card-badge.bi-resv-dot--done { background: var(--border-base); color: var(--txt-muted); }.bi-bksch-card-nv {
    background: var(--color-npay); color: var(--bg-card); font-size: var(--fs-2xs); font-weight: var(--fw-extrabold);
    border-radius: var(--radius-xs); padding: 0 var(--space-1); line-height: 1.5; margin-left: auto;
}
.bi-bksch-card-sex { font-size: var(--fs-2xs); font-weight: var(--fw-bold); opacity: .6; }
.bi-bksch-card-svc {
    font-size: var(--fs-2xs); font-weight: var(--fw-semibold); opacity: .85;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}.bi-bksch-dhead {
    display: flex; align-items: center; gap: var(--space-2);
    padding: 0 var(--space-2) 0 var(--space-2);
    border-left: 4px solid transparent;     /* 디자이너 색상 (bi-bk-dhead-c0~7) */
}
.bi-bksch-dhead-info { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; min-width: 0; flex: 1; line-height: 1.2; text-align: left; }
.bi-bksch-dhead .bi-bk-sp14 { width: auto; padding: 0; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-bksch-dhead-name { font-size: var(--fs-sm); font-weight: var(--fw-black); color: var(--txt-primary); text-align: left; }
.bi-page .bi-bk-calendar--days .bi-bk-ht45-line .bi-bksch-dhead-name.bi-bk-sp14 { font-size: var(--fs-sm); font-weight: var(--fw-black); color: var(--txt-primary); text-align: left; }
.bi-page .bi-bk-calendar--days .bi-bk-ht45-line .bi-bksch-dhead-role { display: block; font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--txt-disabled); text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: var(--space-0_5); width: 100%; }
.bi-bksch-dhead.bi-bk-dhead-c0 { border-left-color: var(--color-indigo-500); }
.bi-bksch-dhead.bi-bk-dhead-c1 { border-left-color: var(--color-purple-500); }
.bi-bksch-dhead.bi-bk-dhead-c2 { border-left-color: var(--color-pink-500); }
.bi-bksch-dhead.bi-bk-dhead-c3 { border-left-color: var(--color-success-500); }
.bi-bksch-dhead.bi-bk-dhead-c4 { border-left-color: var(--color-warning); }
.bi-bksch-dhead.bi-bk-dhead-c5 { border-left-color: var(--color-info-500); }
.bi-bksch-dhead.bi-bk-dhead-c6 { border-left-color: var(--color-success-500); }
.bi-bksch-dhead.bi-bk-dhead-c7 { border-left-color: var(--color-rose-500); }
.bi-bksch-side {
    width: 280px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);                 /* 위젯 카드 간 간격 */
    background: transparent;    /* 컨테이너는 투명 — 각 섹션이 개별 위젯 */
    overflow-y: auto;
    overflow-x: hidden;
}
.bi-bksch-side-sec--search { padding: var(--space-3); }
.bi-bksch-search { display: flex; flex-direction: row; align-items: center; gap: var(--space-2); }
/* .bi-bksch-search-box 제거(2026-09-11) — .bi-bk2-search 로 옮겼다 */
.bi-bksch-search-icon {
    position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
    font-size: var(--fs-base); color: var(--txt-disabled); pointer-events: none;
}
.bi-bksch-search-clear {
    display: none;
    position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
    width: 20px; height: 20px; padding: 0;
    border: 0; background: transparent; cursor: pointer;
    color: var(--txt-disabled); font-size: var(--fs-base); line-height: 1;
    align-items: center; justify-content: center;
}
.bi-bksch-search-clear.is-show { display: inline-flex; }
.bi-bksch-search-clear:hover { color: var(--gray-600); }
.bi-cal__wdrow { display: grid; grid-template-columns: repeat(7, 1fr); margin-bottom: var(--space-1_5); }
.bi-cal__wd { text-align: center; font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); color: var(--txt-disabled); }
.bi-cal__wd.is-sun { color: var(--color-danger); }
.bi-cal__wd.is-sat { color: var(--color-info-500); }
.bi-cal__wrow {
    display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--space-1);
    padding: var(--space-0_5); border-radius: var(--radius-lg); cursor: pointer;
    transition: background .12s, box-shadow .12s;
}
.bi-cal__wrow + .bi-cal__wrow { margin-top: var(--space-1); }
.bi-cal__wrow:hover { background: color-mix(in srgb, var(--color-info-100) 60%, transparent); }
.bi-cal__wrow:hover .bi-cal__day:hover { background: transparent; }   /* 셀 개별 hover 억제(주 전체 강조) */
/* §68-3 고른 주는 «옅게» 알린다 — 통째로 네이비를 칠하면 달력만 딴 얼굴이 된다(사용자 3번).
   일 빨강·토 파랑 같은 날짜 색이 흰 글자에 먹히지 않도록, 바탕만 바꾸고 글자는 건드리지 않는다. */
.bi-cal__wrow.is-wsel {
    background: var(--bk-fix-bg);
    box-shadow: inset 0 0 0 1.5px var(--brand-navy);
    border-radius: var(--radius-md);
}
/* §68-3 12달 고르개(.bi-cal__mgrid / .bi-cal__mon)는 없앴다 — 월간도 «같은 달력» 을 쓴다. */
.bi-schmx__mark-legend { font-size: var(--fs-base); color: var(--txt-muted); }
.bi-msgprev-phone      { width: 250px; }
.bi-msgprev-phone__body{ height: 323px; padding-top: var(--space-10, 40px); width: 100%; text-align: center; background-image: url("/img/page/bgSmsInputB.gif"); }
.bi-msgprev-talk       { width: 250px; }
.bi-msgprev-talk__box  { border-radius: var(--radius-talk); }
.bi-msgprev-talk__head { padding: var(--space-3); background: var(--color-kakao); text-align: left; border-radius: var(--radius-talk) var(--radius-talk) 0 0; font-size: var(--fs-sm); font-weight: 600; }
.bi-msgprev-talk__body { padding: var(--space-2_5) var(--space-1); color: var(--color-kakao-txt); border-radius: 0 0 var(--radius-talk) var(--radius-talk); font-weight: 500; letter-spacing: -0.2px; line-height: 1.2; font-size: var(--fs-sm); background: var(--bg-card); border: 1px solid var(--border-light); }
.bi-msgprev-talk__ta   { width: 100%; line-height: 1.5; border: 0; box-sizing: border-box; resize: none; }
.bi-txt-secondary { color: var(--txt-secondary); }
.bi-txt-muted     { color: var(--txt-muted); }
.bi-txt-disabled,
.bi-bk2-cal__d--out { color: var(--txt-disabled); }   /* 달력의 «지난달 날짜» 도 같은 회색 */
.bi-txt-primary   { color: var(--txt-primary); }
.bi-txt-white     { color: var(--white); }
.bi-cid{ position: fixed; bottom: 0; right: 0; display: none; background-color: var(--bg-card);
          border: 1px solid var(--color-info-600); font-weight: var(--fw-bold); box-sizing: border-box; }
.bi-cid__date  { padding: var(--space-2_5); font-size: var(--fs-base); background-color: var(--color-info-500);
                  font-weight: var(--fw-bold); height: 19px; width: 445px; box-sizing: border-box; }
.bi-cid__close { padding: var(--space-2_5); float: right; width: 15px; cursor: pointer; }
.bi-cid__icon  { background-color: var(--color-info-500); text-align: center; font-size: var(--icon-lg); }
.bi-cid__name  { background-color: var(--color-info-500); text-align: center; font-size: var(--fs-3xl);
                  padding: var(--space-2_5) 0 var(--space-5) 0; font-weight: var(--fw-bold); cursor: pointer; }
.bi-cid__callee{ background-color: var(--color-info-600); padding: var(--space-2_5); font-size: var(--fs-xl);
                  color: var(--color-info-200); font-weight: var(--fw-bold); }
.bi-cid__btns  { text-align: center; float: left; width: 300px; padding: var(--space-2_5); box-sizing: border-box; }
.bi-cid__btns--r{ float: right; padding: var(--space-2_5) 34px var(--space-2_5) 0; }
.bi-btn--cid   { height: 50px; font-size: var(--fs-lg); }        /* 알림 안의 큰 버튼 */

.bi-pop-btnbar--w330{ width: 330px; }
.bi-pop-note--sm  { font-size: var(--fs-xs); margin-left: var(--space-1); color: var(--txt-muted); }
.bi-pop-inline-btn{ font-size: var(--fs-xs); margin-left: var(--space-3_5); }
.bi-input--borderless{ border: none; }                   /* 래퍼가 테두리를 가진 검색칸 */
.bi-pop-tbl-empty--tall{ padding-bottom: var(--space-6); }          /* 결과없음 줄에 여백을 더 준다 */
.bi-pop-note--sm-strong{ font-size: var(--fs-xs); margin-left: var(--space-1); color: var(--txt-muted); font-weight: var(--fw-semibold); }
.bi-pop-note--xs  { font-size: var(--fs-2xs); color: var(--txt-muted); margin: var(--space-0_5); }
.bi-pop-field--w450{ width: 450px; }
.bi-pop-bk__daylbl{ text-align-last: justify; position: absolute; margin-top: var(--space-1_5);
                     margin-left: var(--space-1_5); color: var(--txt-muted); font-size: var(--fs-2xl); z-index: 9999; }
.bi-indent    { padding-left: var(--space-12, 50px); }
   같은 특이도의 컴포넌트 규칙이 뒤에 오면 진다 — 실제로 `.bi-bki{display:flex}`(L5218)가
.sg2doc-stage > .bi-cid{ position: absolute; }/* ════════════════════════════════════════════════════════════
   되살린 규격 — "한 곳 전용" 판정으로 걷혔던 것들 (2026-08-12)

   ⚠ 지우기 전에 물어야 할 것은 «몇 곳에서 쓰나» 가 아니라 «지우면 무엇이 남나» 다.
     로그인·디자이너 탭·예약 일정표·AI 메시지 발송은 사용처가 하나지만
     그 화면의 **구조 자체**였다. 걷어내니 화면이 통째로 무너졌다.
   규격화는 다시 한다 — 기준은 «같은 것이 둘 이상 있는가»(SPEC-DUP) 다.
   ════════════════════════════════════════════════════════════ */
.bi-btn:disabled,
.bi-btn.is-disabled {
    background: var(--border-light);
    color: var(--txt-disabled, var(--txt-disabled));
    border-color: var(--border-light);
    transform: none;
    cursor: not-allowed;
}
.bi-log-table-wrap--w15 .bi-log-row,
.bi-log-table-wrap--w19 .bi-log-row,
.bi-log-table-wrap--w21 .bi-log-row {
    min-width: max(100%, calc(80px * var(--cols, 18)));
}
.bi-log-table-wrap--w15 .bi-log-table-body,
.bi-log-table-wrap--w19 .bi-log-table-body,
.bi-log-table-wrap--w21 .bi-log-table-body { overflow-x: auto; }
/* ⚠ 2026-10-02 — 로그 표(w15·w19·w21)의 머리줄이 «잘리기만» 했다.
   머리줄(ul.bi-log-row--head)은 래퍼 카드(.bi-erp-card, overflow:hidden) 안에, 몸통은 .bi-log-table-body(overflow-x:auto)에 따로 있어
   몸통만 가로로 움직이고 머리는 못 움직였다 — 1440px 에서 열 머리가 오른쪽에서 끊기고 스크롤하면 머리·값이 어긋났다(L3 캡처에서 발견).
   → 가로 스크롤을 «래퍼» 한 곳으로 올려 머리·몸통이 같이 움직이게 한다. 기존 규칙은 고치지 않고 뒤에서 덮는다. */
.bi-erp-card.bi-log-table-wrap--w15,
.bi-erp-card.bi-log-table-wrap--w19,
.bi-erp-card.bi-log-table-wrap--w21 { overflow-x: auto; }
.bi-log-table-wrap--w15 .bi-log-table-body,
.bi-log-table-wrap--w19 .bi-log-table-body,
.bi-log-table-wrap--w21 .bi-log-table-body { overflow-x: visible; }
.bi-search-wrap input[type="text"].bi-input,
.bi-bksch-search-box input[type="text"].bi-input {
    width: 100%;                 /* 래퍼(아이콘+검색박스) 폭 채움 — 모듈별 width 하드코딩 대신 공통에서 */
    box-sizing: border-box;
    padding-left: var(--space-9, 36px);   /* 아이콘 자리 — 스케일 밖 값이라 폴백 표기 */          /* 아이콘 자리 */
}
.bi-search-wrap input[type="text"].bi-input:focus,
.bi-search-wrap input[type="text"].bi-input:focus,
.bi-search-wrap input[type="text"].bi-input:focus,
.bi-bksch-search-box input[type="text"].bi-input:focus,
.bi-search-wrap input[type="text"].bi-input:focus {
    border-color: var(--brand-blue);
    box-shadow: var(--ring-focus);
    background: var(--bg-card);
}
.bi-grid-total--center,
.bi-grid-total--center .dhx_grid-cell { text-align: center; }
/* 2026-08-21: 퀵기간도 32. 같은 줄에 검색(32)·상세조건(32)이 서는데 혼자 27 이라
 * 필터 줄에 버튼 높이가 둘 섞여 있었다 — «한 줄엔 한 크기». */
.bi-quick-btns .bi-btn,
.bi-quick-btns input[type="button"].bi-btn {
    background: transparent;
    border-color: transparent;
    color: var(--txt-secondary);
    height: 32px;
    padding: 0 var(--space-3);
    font-size: var(--fs-base);
}
.bi-quick-btns .bi-btn:hover,
.bi-quick-btns input[type="button"].bi-btn:hover {
    background: var(--bg-card);
    border-color: var(--border-base);
}
.bi-quick-btns .bi-btn.is-active,
.bi-quick-btns input[type="button"].bi-btn.is-active {
    background: var(--bg-card);
    border-color: var(--border-base);
    color: var(--color-info-600);
    font-weight: var(--fw-semibold);
}
/* 2026-09-11 A17-1 — 활성표시가 .bi-quick-btns 안에서만 보였다.
 * log_* 7화면은 이 버튼들을 래토 없이 검색줄(.bi-search-row)에 바로 둔다
 * — 래토 셀렉튰로는 닿지 않는다. 여섯 id 는 화면당 하나뿐인 «그 프로셋 버튼» 이니
 * 스코프로 쓰개 도 새는 곳이 없다. 높이·여백은 건들지 않는다 — --xs/--sm 이 화면마다 다르다. */
#btn_today.is-active,
#btn_yesterday.is-active,
#btn_week.is-active,
#btn_month.is-active,
#btn_lastmonth.is-active,
#btn_thisMonth.is-active {
    background: var(--bg-card);
    border-color: var(--border-base);
    color: var(--color-info-600);
    font-weight: var(--fw-semibold);
}
.bi-search-area input[type="radio"],
.bi-filter-card input[type="radio"] {
    visibility: visible;
    display: inline-block;
    accent-color: var(--brand-blue);
    width: 14px;
    height: 14px;
    cursor: pointer;
    flex-shrink: 0;
}
.bi-grid-area #gridbox .dhx_grid-body,
.bi-grid-area #gridbox [class*="dhx_grid-body"] {
    padding-bottom: var(--space-10);
    /* 2026-08-11 중복 정리(B0-2): `box-sizing:content-box` 를 지웠다.
       바로 아래 규칙이 같은 셀렉터에 `border-box !important` 를 주며 그 이유를 적어두었다
       — 즉 이 선언은 적용된 적이 없고, 남겨두면 아래 교정을 되돌리려는 사람을 오도한다. */
}
.bi-grid-area #gridbox .dhx_grid-body,
.bi-grid-area #gridbox [class*="dhx_grid-body"] {
    box-sizing: border-box;
}
.bi-erp-card:not(:has(.bi-erp-foot)) .bi-grid-area #gridbox .dhx_grid-body,
.bi-erp-card:not(:has(.bi-erp-foot)) .bi-grid-area #gridbox [class*="dhx_grid-body"] {
    padding-bottom: 0;
}
/* 기본은 «자르기» — 유령 15px 넘침을 막는다(2026-07-24 사유는 위 블록 참고).
 * 진짜로 넓은 그리드는 아래 .is-xscroll 이 열어 준다 — 그 판단은 CSS 가 못 한다(픽셀 수를 세야 한다). */
/* ⚠ 2026-08-24 스코프를 «푸터 없는 카드» → **전 그리드** 로 넓혔다.
 *   원래 이 규칙은 푸터 없는 리포트만 잡았고, 푸터 있는 목록(고객관리 등)은
 *   유령 10px 넘침에도 가로바가 뜰 수 있었다. 다만 본문이 컨테이너를 넘어 있어서
 *   그 바가 «잘려» 안 보였을 뿐이다 — 높이를 바로잡자 유령 바가 드러났다.
 *   → 기본은 전부 자르고, 진짜 넘침(24px 초과)만 아래 .is-xscroll 이 연다. */
.bi-erp-card .bi-grid-area #gridbox .dhx_grid-body,
.bi-erp-card .bi-grid-area #gridbox [class*="dhx_grid-body"] {
    overflow-x: hidden;
}

/* ⚠ 2026-08-24 «가로 스크롤바가 푸터 뒤에 그려지고 있었다» — 사용자 지적 ⑪ 의 진짜 원인.
 *   실측(패키지 사용내역): .bi-grid-area 는 y788 에서 끝나는데 .dhx_grid-body 는 y827 까지 그려졌고,
 *   가로 스크롤바 띠(y817~827)가 페이지네이션 푸터(y788~841) **안쪽**에 깔렸다 → 잡을 수가 없다.
 *   원인은 «마지막 행 잘림» 을 막으려고 준 padding-bottom:40px 이다. 본문 높이가 내용으로 정해지는데
 *   거기에 40px 이 더해져 컨테이너보다 커졌고, 스크롤바는 늘 «패딩 박스 맨 아래» 에 붙는다.
 *   본문은 box-sizing:content-box 라 height 532 + padding 40 = **572** 가 되어
 *   컨테이너(534)를 38px 넘었고, 넘친 부분에 스크롤바가 있어 .bi-grid-area(overflow:hidden)에 잘렸다.
 *   → 여백은 그대로 두고(잘림 방지 유지) **여백을 높이 «안» 으로** 넣는다(border-box).
 *     그러면 본문이 컨테이너에 들어가고 스크롤바가 화면 안에 남는다. */
/* box-sizing 은 벤더가 이긴다(실측: 우리 규칙을 넣어도 content-box 그대로) →
 * 높이 자체를 여백만큼 줄여 «패딩 포함 총 높이 = 컨테이너» 가 되게 한다.
 * ⚠ dhx 가 height 를 **인라인으로** 박으므로 여기서는 !important 가 유일한 수단이다.
 *   푸터가 있는 카드(=패딩 40px 를 받는 쪽)에만 건다 — 푸터 없는 리포트는 패딩이 0이라 대상이 아니다.
 *   스크롤 가능한 «내용» 총량은 그대로다(줄인 40px 를 패딩이 되돌려 준다) → 마지막 행도 그대로 보인다. */
/* ⚠ 2026-08-27 제거 — 여기 있던 `height: calc(100% - var(--space-10)) !important` 는
 *   위 진단이 틀려서 생긴 우회였다. box-sizing 이 content-box 로 남은 «진짜 이유» 는
 *   벤더가 아니라 우리 규칙(아래 블록)이었고, 그걸 border-box 로 돌리자 높이를 깎을 이유가 없어졌다.
 *
 *   깎아 두면 오히려 «리스트가 화면에 차지 않는» 새 문제가 된다 — 카드가 중첩된 화면
 *   (.bi-erp-card 안 .bi-erp-gridwrap)에서는 두 규칙이 **서로 다른 조상** 을 보기 때문이다.
 *   실측(예약관리) — 여백 규칙은 :not(:has(.bi-erp-foot)) 이 «안쪽» 카드에 맞아 padding 0,
 *   높이 규칙은 :has(.bi-erp-foot) 가 «바깥» 카드에 맞아 -40px → 되돌려 줄 여백이 없어
 *   본문이 컨테이너보다 40px 짧아졌다(content 581 · body 541). 15줄 중 12줄만 보이고
 *   나머지는 세로 스크롤 안으로 밀렸다.
 *
 *   ⚠ !important 로 우회하기 전에 «왜 지고 있나» 를 끝까지 본다. 그때 벤더를 탓하고 멈춘 탓에
 *     한 줄짜리 고침(content-box→border-box)이 석 달 뒤에야 나왔다. */

/* «진짜로» 넘치는 그리드만 가로 스크롤을 연다.
 * 판정은 JS(lib/js/grid_colcfg.js)가 그린 뒤 실제 픽셀로 한다 — 15px 유령과 800px 진짜를
 * CSS 로는 구별할 수 없다. 임계값(24px)을 넘으면 .bi-grid-area 에 .is-xscroll 이 붙는다.
 * ⚠ 위 «자르기» 규칙과 **같은 특이도(1,4,0)** 로 맞추고 **바로 뒤에** 둔다 —
 *   앞에 두거나 특이도가 낮으면 조용히 진다(2026-08-24 실제로 그랬다). */
.bi-erp-card .bi-grid-area.is-xscroll #gridbox .dhx_grid-body,
.bi-erp-card .bi-grid-area.is-xscroll #gridbox [class*="dhx_grid-body"] {
    overflow-x: auto;
}
/* 잡아끌어 미는 그리드 — 2026-08-24 사용자 지적 ⑤.
 * 가로 스크롤바는 그리드 맨 아래에 하나뿐이라, 윗줄을 보다 옆을 보려면 매번 아래로 내려가야 했다.
 * 동작은 function.js 가 붙인다(6px 넘게 끌어야 «민 것» — 행 선택을 뺏지 않는다). 여기선 손모양만. */
.bi-erp-card .bi-grid-area.is-xscroll #gridbox .dhx_grid-body,
.bi-erp-card .bi-grid-area.is-xscroll #gridbox [class*="dhx_grid-body"] {
    cursor: grab;
}
.bi-erp-card .bi-grid-area.is-xscroll #gridbox .dhx_grid-body.is-panning,
.bi-erp-card .bi-grid-area.is-xscroll #gridbox [class*="dhx_grid-body"].is-panning {
    cursor: grabbing;
    user-select: none;
}
.bi-erp-card .bi-grid-area #gridbox .dhx_grid-body,
.bi-erp-card .bi-grid-area #gridbox [class*="dhx_grid-body"] {
    padding-bottom: var(--space-10);
    /* ⚠ 2026-08-27 «리스트가 화면에 차지 않고 세로 스크롤이 생긴다»(사용자 지적) —
     *   여기 있던 `box-sizing: content-box` 가 범인이었다.
     *   위(9949)에 이미 `border-box` 규칙이 있는데 이쪽이 특이도 (1,3,0) > (1,2,0) 로 이겨
     *   **우리 규칙이 우리 규칙을 덮고** 있었다.
     *   2026-08-24 주석은 이걸 «벤더가 이긴다» 고 잘못 읽고, 진 이유를 못 찾아
     *   높이를 40px 깎는 !important 로 우회했다(아래 블록에서 함께 제거).
     *   border-box 면 여백이 높이 «안» 에 들어가 총 높이 = 컨테이너가 된다 —
     *   깎을 필요도, 죽는 40px 도 없다. */
}
.bi-page .dhx_grid-header,
.bi-page [class*="dhx_header-row"] {
    background: var(--bg-input);
}
.bi-page .dhx_grid-header-cell--sortable:hover:after,
.bi-page .dhx_grid-header-cell--sorted:after {
    display: none;
}
.bi-page .dhx_grid-sort-icon--asc,
.bi-page .dhx_grid-sort-icon--desc {
    color: var(--brand-blue);
}
.bi-page .dhx_grid-header-cell--sortable .dhx_grid-header-cell-text,
.bi-page .dhx_grid-header-cell--sortable .dhx_grid-header-cell-text_content {
    padding-left: 0;
    padding-right: 0;
}
.bi-page .dhx_grid-header-cell.bi-grid-msep,
.bi-page .dhx_grid-cell.bi-grid-msep {
    border-left: 2px solid var(--gray-300);
}
.bi-page .scale-text,
.bi-page .start-text,
.bi-page .end-text {
    fill: var(--txt-disabled);
    font-size: var(--fs-xs);
}
.bi-page .grid-line,
.bi-page .dash-line {
    stroke: var(--border-light);
}
.bi-erp-card #gridbox .dhx_grid-body .dhx_cell,
.bi-erp-card #gridbox .dhx_grid-body [class*="dhx_cell"],
.bi-erp-card #gridbox [class*="dhx_grid-body"] [class*="dhx_cell"] {
    padding: 0 var(--space-4);
    border-bottom: 1px solid var(--border-light);
    color: var(--txt-secondary);
    font-size: var(--fs-base);
}
#gridbox .dhx_grid-row:hover .dhx_grid-cell,
.bi-erp-card #gridbox .dhx_grid-row:hover .dhx_grid-cell {
    background: color-mix(in srgb, var(--color-info-50) 40%, transparent);
    cursor: pointer;
}
#gridbox .dhx_grid-selected-row,
.bi-erp-card #gridbox .dhx_grid-selected-row {
    background: color-mix(in srgb, var(--brand-blue) 10%, transparent);
    box-shadow: none;   /* dhx v7 기본 선택행 좌측 inset 액센트(세로 바) 제거 */
    border-left: 0;
}
#gridbox .dhx_grid-selected-cell,
.bi-erp-card #gridbox .dhx_grid-selected-cell,
#gridbox .dhx_grid-selected-focus-cell,
.bi-erp-card #gridbox .dhx_grid-selected-focus-cell {
    /* 2026-08 sg2 §24-3: 선택 시 파랑 테두리(→ 첫 셀 왼쪽이 세로 파란선으로 보임) 제거.
       일반 그리드선(border-base)으로 되돌리고 배경 틴트만 남긴다. box-shadow(포커스 아웃라인)도 차단. */
    border-color: var(--border-base);
    background-color: color-mix(in srgb, var(--brand-blue) 5%, transparent);
    box-shadow: none;
}
.bi-grid-area--xscroll #gridbox .dhx_grid-body,
.bi-grid-area--xscroll #gridbox [class*="dhx_grid-body"] { overflow-x: auto; }
/* ── 글꼴은 한 벌이다 (2026-08-21, 사용자 지적) ──────────────────────────
 * 실측: 화면 안에 **Pretendard 가 아닌 요소가 1,525개** 있었다.
 *   ① dhx 그리드 — 벤더 grid.css 가 `.dhx_widget`·`.dhx_grid`·`.dhx_grid-cell` 에
 *      `Roboto, Arial, Tahoma, Verdana` 를 직접 박는다. 목록 화면의 «본문» 이 통째로 다른 글꼴이었다.
 *      배지·강조 같은 우리 클래스도 그 안에 있으니 같이 끌려갔다.
 *   ② 폼 컨트롤(input·select·textarea·button) — 브라우저 기본값이라 글꼴을 물려받지 않는다(Arial).
 * → 둘 다 `inherit` 로 되돌린다. .bi-page 를 앞에 붙여 벤더보다 특이도가 높다.
 * ⚠ 아이콘은 예외다 — 아래 FA 규칙이 (0,2,1) 로 더 높아 안 끌려간다(CLAUDE.md §7 함정).
 * ⚠ 2026-08-24 `inherit` → `var(--font-sans)` 로 바꿨다(사용자 지적).
 *   `inherit` 는 «바로 위 부모의 값» 이라, 벤더가 중간 조상에 서체를 박으면 **그걸 물려받는다**.
 *   지금은 조상까지 다 덮어서 결과가 맞았지만, 벤더가 규칙을 하나 더 늘리면 조용히 되돌아간다.
 *   보는 쪽에서도 계산값이 `inherit` 로만 보여 «무슨 서체인지» 를 알 수 없었다.
 *   → 값은 :root 의 --font-sans 한 곳, 쓰는 쪽은 그 토큰을 «명시» 한다. */
.bi-page .dhx_widget,
.bi-page .dhx_grid,
.bi-page .dhx_grid-row,
.bi-page .dhx_grid-cell,
.bi-page .dhx_grid-cell__content,
.bi-page .dhx_grid-header,
.bi-page .dhx_grid-header-cell,
.bi-page .dhx_grid-header-cell-text,
.bi-page .dhx_grid-header-cell-text_content,
.bi-page input,
.bi-page select,
.bi-page textarea,
.bi-page button { font-family: var(--font-sans); }

.bi-page i.fa,
.bi-page i.fas,
.bi-page i.fal,
.bi-page i.far,
.bi-page i.fab { font-family: 'Font Awesome 5 Pro'; }
/* ⚠ 2026-08-21 — 합계 클래스는 dhx `mark` 훅으로 «셀» 에 붙는다(행이 아니다).
 * 행 셀렉터만 있으면 배경만 먹고 굵기가 안 먹는다 → 셀 자신도 잡는다.
 * (그 전에는 `cellCss` 로 걸어 두어 **아무 데도 안 붙고 있었다** — 12개 리포트가 그랬다) */
.bi-grid-total,
.bi-grid-total .dhx_grid-cell,
.dhx_grid-cell.bi-grid-total {
    background: var(--border-light);
    font-weight: var(--fw-bold);
    color: var(--txt-primary);
}
.bi-permmatrix-check input[type="checkbox"] + label,
.bi-permmatrix-row input[type="checkbox"] + label { display: none; }
.bi-write-page input[type="password"].bi-input,
.bi-write-page input[type="text"].writeinput,
.bi-write-page input[type="text"].bi-input,
.bi-write-body input[type="password"].bi-input,
.bi-write-body input[type="text"].writeinput,
.bi-write-body input[type="text"].bi-input,
.bi-pop-reg input[type="text"].bi-input,
.bi-pop-reg input[type="date"].bi-input {
    height: 36px;
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-base);
    background: var(--bg-card);
    padding: 0 var(--space-3);
    font-size: var(--fs-md);
    color: var(--txt-primary);
    outline: none;
    box-sizing: border-box;
    transition: border-color .15s, box-shadow .15s;
}
.bi-write-page input[type="password"].bi-input:focus,
.bi-write-page input[type="text"].writeinput:focus,
.bi-write-page input[type="text"].bi-input:focus,
.bi-write-body input[type="password"].bi-input:focus,
.bi-write-body input[type="text"].writeinput:focus,
.bi-write-body input[type="text"].bi-input:focus,
.bi-pop-reg input[type="text"].bi-input:focus,
.bi-pop-reg input[type="date"].bi-input:focus {
    border-color: var(--brand-blue);
    box-shadow: var(--ring-focus);
    background: var(--bg-card);
}
.bi-form input[type="text"].bi-input,
.bi-form input[type="tel"].bi-input,
.bi-form input[type="date"].bi-input,
.bi-form input[type="number"].bi-input,
.bi-form input[type="password"].bi-input,
.bi-form select.bi-input,
.bi-form textarea.bi-input {
    width: 100%;
    box-sizing: border-box;
    height: 36px;
    border: 1px solid var(--border-base);
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    padding: 0 var(--space-3);
    font-size: var(--fs-md);
    color: var(--txt-primary);
    outline: none;
    font-family: var(--font-sans);
    transition: border-color .15s, box-shadow .15s;
}
.bi-form input.bi-input:focus,
.bi-form select.bi-input:focus,
.bi-form textarea.bi-input:focus {
    border-color: var(--brand-blue);
    box-shadow: var(--ring-focus);
    background: var(--bg-card);
}
.bi-form .bi-input.is-error,
.bi-write-page .bi-input.is-error,
.bi-write-body .bi-input.is-error,
.bi-write-textarea.is-error {
    border-color: var(--color-danger);
    box-shadow: 0 0 0 2px var(--color-danger-100);
}
.bi-write-page input[type="checkbox"],
.bi-write-body input[type="checkbox"] {
    visibility: visible;
    display: inline-block;
    accent-color: var(--brand-blue);
    width: 16px;
    height: 16px;
    cursor: pointer;
    flex-shrink: 0;
}
.bi-write-page input: :placeholder,
.bi-write-page textarea::placeholder,
.bi-write-body input::placeholder,
.bi-write-body textarea::placeholder {
    color: var(--txt-disabled);
    font-weight: var(--fw-normal);
    font-size: var(--fs-sm);
}
.bi-write-page .bi-erp-title,
.body-header .body-title {
    font-size: var(--fs-2xl);
    font-weight: 700;
    color: var(--txt-primary);
    margin: 0;
    line-height: 1.4;
    /* 레거시 인라인 style="width:..px" / float 무력화 */
    width: auto;
    float: none;
    padding: 0;
}
.bi-desk__cardbtn:hover,
.bi-desk__crm-open:hover,
.bi-desk__crm-open:hover { background: color-mix(in srgb, var(--brand-blue) 20%, transparent); }
/* ⚠ 2026-09-08 — .bi-num 에 «등폭 서체» 가 덧씌워져 있었다(선택자가 두 번 겹쳐 적힌 찌꺼기).
   §10 규격(2312줄)은 font-family 를 정하지 않는다 — 본문 서체(--font-sans)를 상속하고
   숫자 폭만 font-variant-numeric: tabular-nums 로 맞춘다. 그것으로 자릿수는 이미 선다.
   사용자 지적: 「.bi-num 에 알 수 없는 font-family 가 들어갔어. var(--font-sans) 로 통일인데」 */
.bi-desk__newbtn:hover,
.bi-desk__prepaid-info,
.bi-desk__prepaid-info { display: flex; flex-direction: column; min-width: 0; }
.bi-pick__l,
.bi-pick__l { min-width: 0; padding-right: var(--space-2); }
.bi-lifecycle__stage--amber,
.bi-lifecycle__stage--amber { color: var(--color-warning-600); }
.bi-lifecycle__stage--blue,
.bi-lifecycle__stage--blue { color: var(--color-info-600); }
.bi-lifecycle__stage--emerald,
.bi-lifecycle__stage--emerald { color: var(--color-success); }
.bi-lifecycle__stage--red,
.bi-lifecycle__stage--red { color: var(--color-danger); }
.bi-desk__ticket-meter,
.bi-desk__ticket-sub,
.bi-desk__ticket-sub { display: flex; flex-direction: column; gap: var(--space-1); }
.bi-desk__ticket-sub-head,
.bi-desk__ticket-sub-head { display: flex; align-items: center; gap: var(--space-2); }
.bi-desk__tickets,
.bi-desk__tickets { display: flex; flex-direction: column; gap: var(--space-2); }
.bi-toast i,
.bi-toast i { font-size: var(--fs-lg); }
.bi-toast.is-show,
.bi-toast.is-show { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); }
.bi-desk__rpanel-lbl,
.bi-desk__rpanel-lbl { font-size: var(--fs-xs); color: var(--txt-muted); font-weight: var(--fw-black); display: block; text-transform: uppercase; letter-spacing: .06em; margin-bottom: var(--space-2); }
.bi-pickgrid__grp,
.bi-pickgrid__grp { display: flex; flex-direction: column; gap: var(--space-1_5); margin-bottom: var(--space-3); }
.bi-pickgrid__grp .bi-desk__rpanel-lbl,
.bi-pickgrid__grp .bi-desk__rpanel-lbl { margin-bottom: 0; }
.bi-segment,
.bi-segment { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-0_5); background: var(--border-base); padding: var(--space-0_5); border-radius: var(--radius-xl); border: 1px solid color-mix(in srgb, var(--gray-300) 30%, transparent); }
.bi-segment__btn,
.bi-segment__btn { border: 0; background: transparent; padding: var(--space-2) var(--space-0_5); border-radius: var(--radius-lg); cursor: pointer; font-size: var(--fs-2xs); font-weight: var(--fw-black); color: var(--txt-muted); letter-spacing: -.02em; line-height: 1.2; }
.bi-segment__btn.is-active,
.bi-segment__btn.is-active { background: var(--brand-blue); color: var(--bg-card); box-shadow: var(--shadow-sm); }
.bi-desk__subcats,
.bi-desk__subcats { display: flex; flex-wrap: wrap; gap: var(--space-1_5); max-height: 140px; overflow-y: auto; }
.bi-desk__catbtn,
.bi-desk__catbtn { border: 1px solid var(--border-base); background: var(--bg-card); padding: var(--space-1) var(--space-2); border-radius: var(--radius-lg); cursor: pointer; font-size: var(--fs-2xs); font-weight: var(--fw-black); color: var(--txt-muted); }
.bi-desk__catbtn.is-active,
.bi-desk__catbtn.is-active { color: var(--brand-blue); border-color: color-mix(in srgb, var(--brand-blue) 30%, transparent); box-shadow: var(--shadow-xs); }
.bi-pickgrid__list,
.bi-pickgrid__list { display: flex; flex-direction: column; gap: var(--space-2); }
.bi-pick.is-sel,
.bi-pick.is-sel { border-color: var(--brand-blue); background: color-mix(in srgb, var(--brand-blue) 5%, transparent); }
.bi-pick__badge,
.bi-pick__badge { font-size: var(--fs-2xs); font-weight: var(--fw-black); padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm); margin-left: var(--space-1_5); vertical-align: middle; border: 1px solid; }
.bi-bksch-emp-list input[type="checkbox"].bi-bksch-emp-chk,
.bi-bksch-typefilter input[type="checkbox"].bi-bksch-type-chk {
    visibility: visible; display: inline-block;
    width: 14px; height: 14px; margin: 0; flex-shrink: 0;
    accent-color: var(--brand-blue); cursor: pointer;
    -webkit-appearance: auto; appearance: auto; background-image: none;
}
.bi-bk-panel-body:has(#div_reserve .mb_reserve) .bi-bk-panel-empty,
.bi-bk-panel-body:has(.bi-bki:not([style*="display:none"])) .bi-bk-panel-empty { display: none; }
.bi-counter-wrap *,
.bi-counter-wrap *::before,
.bi-counter-wrap *::after { box-sizing: border-box; }
.bi-counter-wrap i.fa,
.bi-counter-wrap i.fas,
.bi-counter-wrap i.far,
.bi-counter-wrap i.fal { font-family: 'Font Awesome 5 Pro'; }
.bi-counter-wrap textarea.bi-counter-consult,
.bi-counter-consult {
    width: 100%; height: auto; min-height: 60px; line-height: 1.6;
    padding: var(--space-2_5) var(--space-3_5); resize: none;
    background: color-mix(in srgb, var(--color-warning-50) 20%, transparent); border: 1px solid color-mix(in srgb, var(--color-warning-300) 60%, transparent);
    border-radius: var(--radius-xl); font-size: var(--fs-md); color: var(--color-warning-900); outline: none;
}
.bi-counter-wrap textarea.bi-counter-memo-ta,
.bi-counter-memo-ta {
    width: 100%; flex: 1; height: auto; min-height: 120px; line-height: 1.6;
    padding: var(--space-2_5); resize: none; background: var(--bg-card); border: 1px solid var(--cc-line);
    border-radius: var(--radius-xl); font-size: var(--fs-md); color: var(--txt-secondary); outline: none; font-weight: var(--fw-medium);
}
.bi-counter-pay-btn--cash,
.bi-counter-pay-btn--card {
    background: var(--bg-card); border: 1px solid var(--gray-300); color: var(--txt-secondary);
    box-shadow: var(--shadow-xs);
}
.bi-counter-pay-btn--cash:hover:not(:disabled),
.bi-counter-pay-btn--card:hover:not(:disabled) { background: var(--bg-input); }
/* ⚠ 2026-08-26 «상품을 추가하면 표가 깨진다»(사용자 지적) — 원인은 여기였다.
 *   `<td>` 에 display:flex 를 주면 그 칸은 **표 레이아웃에서 빠져나온다.**
 *   실측 — 분류·상품명 두 칸이 **둘 다 x=273** 에 겹쳐 상품명이 아래로 밀리고,
 *   그 뒤 칸이 통째로 한 칸씩 왼쪽으로 밀렸다(삭제 버튼이 합계 자리에, 폭도 160px).
 *   td 는 table-cell 로 두고, 안쪽 내용만 가로로 세운다. */
.bi-bs-pro-td--proc,
.bi-bs-pro-td--disc  { white-space: nowrap; }
.bi-bs-pro-td--proc > *,
.bi-bs-pro-td--disc  > * { vertical-align: middle; }
/* 배지 둘 사이 간격 — flex 의 gap 을 대신한다(표 칸에는 gap 이 안 먹는다) */
.bi-bs-pro-td--proc > * + * { margin-left: var(--space-1); }
.bi-bs-pro-td--price,
.bi-bs-pro-td--total { text-align: right; }
/* flex:1 대신 폭 100% — 칸이 다시 table-cell 이라 인풋이 칸을 채우면 된다 */
.bi-bs-pro-td--proc .bi-bs-pro-input,
.bi-bs-pro-td--disc .bi-bs-pro-input,
.bi-bs-pro-td--pro  .bi-bs-pro-input {
    width: 100%;
    min-width: 0;
}
#itab_hist:checked ~ .bi-bs-tab-panels,
#itab_pkg:checked  ~ .bi-bs-tab-panels,
#itab_memo:checked ~ .bi-bs-tab-panels {
    overflow-y: hidden;
    display: flex;
    flex-direction: column;
}
#itab_hist:checked ~ .bi-bs-tab-hdr .bi-bs-tab-lbl[for="itab_hist"],
#itab_pkg:checked  ~ .bi-bs-tab-hdr .bi-bs-tab-lbl[for="itab_pkg"],
#itab_memo:checked ~ .bi-bs-tab-hdr .bi-bs-tab-lbl[for="itab_memo"] {
    color: var(--brand-blue);
    border-bottom-color: var(--brand-blue);
    font-weight: var(--fw-bold);
    background: color-mix(in srgb, var(--color-info-50) 50%, transparent);
}
#itab_hist:checked ~ .bi-bs-tab-panels #pnl_history,
#itab_pkg:checked  ~ .bi-bs-tab-panels #pnl_package {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}
.bi-bs-counter .bi-counter-pay > .bi-counter-pay-grid,
.bi-bs-counter .bi-counter-pay > .bi-bs-dock-btns { margin-bottom: var(--space-2); }
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-pro-input,
.bi-bs-counter .bi-bs-pro-input {
    height: 36px; border-radius: var(--radius-lg);
    background: var(--bg-input); border: 1px solid var(--border-base);
    font-weight: 700; font-size: var(--fs-base); color: var(--gray-800);
    transition: border-color .12s, background .12s, box-shadow .12s;
}
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-pro-input:focus,
.bi-bs-counter .bi-bs-pro-input:focus {
    border-color: var(--brand-blue); background: var(--bg-card); box-shadow: var(--ring-focus);
}
.bi-bs-counter .bi-bs-pro-input--c,
.bi-bs-counter .bi-bs-pro-input--qty { text-align: center; }
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-pro-input[name='input_price[]'],
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-pro-input[name='input_disc[]'] {
    color: var(--txt-muted); font-weight: 600;
}
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-pro-input--pro,
.bi-bs-counter .bi-bs-pro-input--pro {
    font-weight: 800; font-size: var(--fs-md); color: var(--txt-primary);
    background: transparent; border-color: transparent; box-shadow: none;
    padding-left: var(--space-1); cursor: pointer;
}
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-pro-input--pro:focus,
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-pro-input[name='input_proc[]']:focus {
    background: transparent; border-color: transparent; box-shadow: none;
}
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-pro-input--qty,
.bi-bs-counter .bi-bs-pro-input--qty {
    width: 44px; height: 32px; font-weight: 900;
    background: var(--bg-input); border-radius: var(--radius-lg);
}
.bi-bs-counter input[name='input_tdesiner[]'],
.bi-bs-counter .bi-bs-pro-total-sep { display: none; }
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-pro-input--total,
.bi-bs-counter .bi-bs-pro-input--total { color: var(--txt-primary); font-weight: 900; }
.bi-bs-counter .bi-bs-pro-th--no,
.bi-bs-counter .bi-bs-pro-td--no { display: none; }
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-datebar-date,
.bi-bs-counter .bi-bs-datebar-date {
    border: none; background: transparent; box-shadow: none;
    width: 110px; height: auto; padding: 0;
    font-weight: 800; font-size: var(--fs-lg); color: var(--brand-navy);
    font-variant-numeric: tabular-nums; cursor: pointer; outline: none;
}
.bi-pop-list--member .pop_m_h,
.bi-pop-list--member .pop_m_b_li{
    display: flex; align-items: center; width: 100%; box-sizing: border-box;
}
.bi-pop-list--member .pop_m_h_sub,
.bi-pop-list--member .pop_m_b_li_div{
    flex: 1 1 0; width: auto; min-width: 0;
    padding: 0 var(--space-2_5); float: none; box-sizing: border-box;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bi-pop-pay--cardcancel .selectWrap .pop_m_h_sub:nth-of-type(1),
.bi-pop-pay--cardcancel .selectWrap .pop_m_b_li_div:nth-of-type(1){ width: 170px; padding-left: var(--space-5); }
.bi-pop-pay--cardcancel .selectWrap .pop_m_h_sub:nth-of-type(2),
.bi-pop-pay--cardcancel .selectWrap .pop_m_b_li_div:nth-of-type(2){ width: 140px; }
.bi-pop-pay--cardcancel .selectWrap .pop_m_h_sub:nth-of-type(3),
.bi-pop-pay--cardcancel .selectWrap .pop_m_b_li_div:nth-of-type(3){ width: 110px; text-align: right; }
.bi-pop-pay input.btn_size, .bi-pop-pay .btn_size, .bi-pop-pay input[type="button"].btn_size,
.bi-pop-pay .bt_div input[type="button"],
.bi-pop-pay .bt_div input[type="submit"],
.bi-pop-pay .bt_div button{
    height: 40px; min-width: 76px; padding: 0 var(--space-5);
    border-radius: var(--radius-lg); border: 1px solid var(--border-base);
    background: var(--border-light); color: var(--txt-secondary);
    font-size: var(--fs-md); font-weight: 700; cursor: pointer; width: auto;
    transition: background .12s, border-color .12s;
}
.bi-pop-pay input.btn_size:hover,
.bi-pop-pay .bt_div input[type="button"]:hover,
.bi-pop-pay .bt_div input[type="submit"]:hover,
.bi-pop-pay .bt_div button:hover{ background: var(--border-base); }
.bi-pop-pay input.btn_size.but_blue,
.bi-pop-pay input.but_blue, .bi-pop-pay .but_blue,
.bi-pop-pay .bt_div input.but_blue,
.bi-pop-pay .bt_div button.but_blue{
    background: var(--brand-blue); color: var(--bg-card); border: none; font-weight: 800;
    box-shadow: var(--shadow-md);
}
.bi-pop-pay input.btn_size.but_blue:hover,
.bi-pop-pay input.but_blue:hover, .bi-pop-pay .but_blue:hover{ background: var(--brand-blue-hover); }
.bi-pop-pay .bi-pop-opt input[type="checkbox"],
.bi-pop-pay .bi-pop-opt input[type="radio"]{
    visibility: visible; display: inline-block;
    -webkit-appearance: auto; appearance: auto;
    width: 16px; height: 16px; margin: 0; flex-shrink: 0;
    accent-color: var(--brand-blue); cursor: pointer;
}
.bi-pop-pay--dep .bi-pop-dep-info input.writeinput,
.bi-pop-pay--dep .bi-pop-dep-info select{
    width: 100%; height: 42px; margin: 0;
    border: 1px solid var(--gray-300); border-radius: var(--radius-lg); background: var(--bg-input);
    font-size: var(--fs-md); color: var(--gray-800); padding: 0 var(--space-2_5); box-sizing: border-box;
}
.bi-pop-pay--dep .bi-pop-dep-info input.writeinput:focus,
.bi-pop-pay--dep .bi-pop-dep-info select:focus{ border-color: var(--brand-blue); background: var(--bg-card); }
.bi-pop-pay--dt .pop_body:not(.pop_border_l) .pop_m_p_b,
.bi-pop-pay--dt .pop_body:not(.pop_border_l) .pop_m_b{ float: none; width: 100%; display: block; }
.bi-pop-pay--dt #selected_date,
.bi-pop-pay--dt #selected_time,
.bi-pop-pay--dt #selected_etime{
    width: auto; flex: 1; min-width: 0;
    border: none; background: transparent;
    font-weight: 800; font-size: var(--fs-md); color: var(--txt-primary); margin: 0;
}
.bi-pop-pay--dt .t_butn,
.bi-pop-pay--dt .t_butn2{
    width: 100%; margin: 0; padding: var(--space-2) var(--space-1); float: none;
    border: 1px solid var(--border-base); border-radius: var(--radius-lg);
    font-size: var(--fs-base); font-weight: var(--fw-semibold); text-align: center; cursor: pointer; line-height: 1.2;
    background: var(--bg-card); color: var(--txt-secondary);
    transition: background .12s, color .12s, border-color .12s;
}
.bi-pop-pay--dt .t_butn:hover,
.bi-pop-pay--dt .t_butn2:hover{ background: var(--color-info-50); color: var(--brand-blue); border-color: var(--color-info-200); }
.bi-pop-pay--dt .t_butn.active,
.bi-pop-pay--dt .t_butn2.active{ background: var(--brand-blue); color: var(--bg-card); border-color: var(--brand-blue); }
/* 월 이동 화살표 — 규격안은 «파란 알약 버튼» 이 아니라 글자만 놓인 홑화살표다(2026-08-31).
   30px 짜리 파란 원은 플러그인 인라인(font-size:30px)을 덮으려다 커진 것이었다. */
.bi-pop-pay--dt .supercal-header button.prev-month,
.bi-pop-pay--dt .supercal-header button.next-month{
    float: none; cursor: pointer; width: 22px; height: 22px;
    padding: 0; margin: 0; border: none; border-radius: var(--radius-md);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: var(--fs-md); line-height: 1; color: var(--txt-secondary);
    background: none; box-shadow: none; flex: 0 0 22px;
}
.bi-pop-pay--dt .supercal-header button.prev-month:hover,
.bi-pop-pay--dt .supercal-header button.next-month:hover{ background: var(--bg-selected); color: var(--brand-blue); }
.bi-pop-pay--dt .cal,
.bi-pop-pay--dt .supercal,
.bi-pop-pay--dt .supercal *{ box-sizing: border-box; }
.bi-pop-pay--dt .supercal td.month-prev,
.bi-pop-pay--dt .supercal td.month-next{ background: transparent; color: var(--gray-300); cursor: default; }
.bi-pop-pay--form input.writeinput,
.bi-pop-pay--form input[type="text"]{
    height: 36px; padding: 0 var(--space-2_5); margin: 0;
    border: 1px solid var(--border-base); border-radius: var(--radius-lg);
    background: var(--bg-card); color: var(--gray-800); font-size: var(--fs-md);
    box-sizing: border-box; vertical-align: middle;
}
.bi-pop-pay--form input.writeinput:focus,
.bi-pop-pay--form input[type="text"]:focus{
    border-color: var(--brand-blue); box-shadow: var(--ring-focus);
}
.bi-bq-pop #popup_layer_member .write_layout,
#popup_layer_member .write_layout { z-index: 2000; }
.bi-pop-pay--aim-fit .bi-msgpop__mode.is-active i,
.bi-pop-pay--aim-fit .bi-msgpop__mode.is-active .bi-msgpop__mode-name { color: var(--brand-blue); }
.bi-pop-tbl-body ul,
.bi-pop-tbl-list{ list-style: none; margin: 0; padding: 0; }   /* 본문 밖의 목록도 같은 리셋 */
.bi-pop-clist-item input[type="checkbox"],
.bi-pop-tbl-row input[type="checkbox"]{
    visibility: visible; display: inline-block;
    accent-color: var(--color-indigo-600);
    width: 16px; height: 16px; margin: 0; cursor: pointer; flex-shrink: 0;
}
.bi-carousel__avatar img,
.bi-carousel__avatar .bi-carousel__avatar-ph {
    width: 64px; height: 64px; border-radius: var(--radius-full); object-fit: cover;
    border: 2px solid var(--white); box-shadow: var(--shadow-sm);
    transition: transform .15s;
}
.bi-desk__crm-open.is-disabled,
.bi-desk__crm-open:disabled { background: var(--border-light); color: var(--txt-disabled); border-color: var(--border-base); cursor: not-allowed; opacity: .7; }
.bi-desk__crm-open.is-disabled:hover,
.bi-desk__crm-open:disabled:hover { background: var(--border-light); }
.bi-bki-status.bi-bk-status3,
.bi-bki-status.bi-bk-status5,
.bi-bki-status.bi-bk-status6 { background: var(--color-danger-50); color: var(--color-danger-700); }
.bi-page .bi-bk-slot180 .bi-bk-time-color,
.bi-page .bi-bk-slot180.bi-bk-time-color {
    color: var(--txt-disabled);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-weight: var(--fw-semibold);
}
.bi-page .bi-bk-inner.bi-bk-status3,
.bi-page .bi-bk-inner.bi-bk-status5,
.bi-page .bi-bk-inner.bi-bk-status6 { background: var(--gray-300); color: var(--txt-muted); }
.bi-page .bi-bk-inner.bi-bksch-card.bi-bk-status3,
.bi-page .bi-bk-inner.bi-bksch-card.bi-bk-status5,
.bi-page .bi-bk-inner.bi-bksch-card.bi-bk-status6 { background: var(--color-danger-50); border-left: 3px solid var(--color-danger-300); color: var(--color-danger-700); opacity: .9; }
.bi-page .bi-agg-stat.bi-bk-status3,
.bi-page .bi-agg-stat.bi-bk-status5,
.bi-page .bi-agg-stat.bi-bk-status6 { background: var(--color-danger-50); color: var(--color-danger-700); border-color: var(--color-danger-300); }
.bi-page .bi-agg-item.is-filtered,
.bi-page .bi-agg-item.is-status-hidden { display: none; }
.bi-page #calendar_week .bi-bk-time > .bi-agg,
.bi-page #calendar_week .bi-bk-time > .bi-bk-innerPossible {
    flex: 1 1 0; min-height: 0; box-sizing: border-box; margin: 0;
}
.bi-bksch-card-badge.bi-resv-dot--checkin,
.bi-bksch-card-badge.bi-resv-dot--cancel,
.bi-bksch-card-badge.bi-resv-dot--block { background: var(--color-danger-100); color: var(--color-danger-600); }
.bi-page .bi-bksch-card-name,
.bi-bksch-card-name,
.bi-page .bi-bksch-card-svc,
.bi-bksch-card-svc { text-align-last: left; }
.sg2doc-stage > .bi-cid{ position: absolute; }

/* ── @media 껍데기 복구 (2026-08-12) ─────────────────────────────────
 * 규칙 블록만 되살리면 이 껍데기가 안 온다 → 좁은 화면용 규칙이 모든 폭에 걸린다.
 * ──────────────────────────────────────────────────────────────── */
@media (max-width: 480px) {
    .bookmark-container.bi-bm { right: 16px; bottom: 16px; }
    .bi-bm-card { width: calc(100vw - 32px); }
}

@media (max-width: 1024px) {
    .bi-catalog { width: 96vw; height: 90vh; }
    .bi-catalog__console { display: none; }
    .bi-catalog__view { width: 220px; }
    .bi-desk__records, .bi-timeline { width: 100%; border-right: 0; }
    .bi-desk__records { border-bottom: 1px solid var(--border-base); }
    .bi-bksplit__side { width: 100%; flex-direction: row; flex-wrap: wrap; }
    .bi-bksplit__side > .bi-erp-card, .bi-bksplit__side > .bi-bksch-side-sec { flex: 1 1 240px; }
    .bi-bksplit__main { min-height: 560px; }
}

@media (max-width: 1100px) {
}

@media (max-width: 1280px) {
    .bi-desk__records { width: 55%; }
    .bi-timeline { width: 45%; }
    .bi-bksplit__side { width: 240px; }
    .bi-schmx__thcell, .bi-schmx__cell { flex-basis: 96px; width: 96px; }
    .bi-schmx__corner, .bi-schmx__dname { flex-basis: 132px; width: 132px; }
}

/* ── 워크플로 화면 안쪽 구획은 «카드» 가 아니다 (2026-08-13) ─────────────
 * 사용자: "기존 B형의 경우 각 컨텐츠 카드에 라운드 테두리가 있는데 빼줘"
 * 셸 카드(.bi-erp-card)가 이미 테두리·둥글기를 갖는다. 그 안에서 열·패널이 또 그리면
 * 상자 안 상자가 된다. 안쪽은 구분선으로 나누고 둘레는 두지 않는다.
 * ⚠ 배경은 남긴다 — 흰 바탕까지 지우면 구획이 안 보인다.
 * ⚠ 칩·뱃지·버튼·입력칸은 대상이 아니다. 그 둥글기는 규격이다.
 * ──────────────────────────────────────────────────────────────────── */
/* ⚠ 2026-08-14 — 이 규칙이 «이름을 열거해서» 걸리고 있었다. 그래서 목록에 없는 이름은
 *   계속 둥근 채로 남았다 — 사용자 지적: "ai메시지발송의 경우 컨텐츠 라운드 빼달라는게 그대로 있어".
 *   이름 목록은 사람이 관리하면 반드시 샌다. **구조로 거는 규칙을 먼저 둔다.**
 *
 *   ① 카드 안에 또 카드는 없다 — 셸이 이미 카드다.
 *      (ai_marketing 의 .bi-camp__target/__editor/__audience, 로그 화면의 표 래퍼가 전부 이 경우였다.
 *       실측: probe_nestbox.mjs 가 105화면에서 «상자 안 상자» 를 위치로 찾는다) */
.bi-erp-card .bi-erp-card {
    border: 0;
    border-radius: 0;
    box-shadow: none;
}

/*   ② 카드가 아닌 이름으로 둘레를 그리던 안쪽 패널들.
 *      ⚠ 입력칸(textarea·input)·문서가 카드로 정한 것(§23 카드 · §40-5 차트 카드 · §29 안내 박스)은
 *        대상이 아니다 — 그 둥글기는 규격이다. */
.bi-erp-card .bi-desk__col,
.bi-erp-card .bi-card--box,
.bi-erp-card .bi-bksch-side-sec,
.bi-erp-card .bi-bksplit__main,
.bi-erp-card .bi-bksplit__calcol,
.bi-erp-card .bi-bk-info-panel,
.bi-erp-card .bi-bka,
.bi-erp-card .bi-msgprev,
.bi-erp-card .bi-lifecycle,
.bi-erp-card .bi-desk__hist-box,
.bi-erp-card .bi-desk__field--treat,
.bi-erp-card .bi-desk__ticket,
.bi-erp-card .bi-crmcard {
    border: 0;
    border-radius: 0;
}

/* ⚠ 2026-08-14 — 위에서 둘레를 지우며 **구분선까지 지웠다.**
 *   사용자: "라운드를 없앴지만 컨텐츠별 구분 border 까지 지워버려서 컨텐츠 영역 구분이 어려워"
 *   바로 위 주석이 «안쪽은 구분선으로 나누고» 라고 적어 놓고 `border: 0` 으로 다 지운 것이다.
 *   구분선을 되돌린다 — 다만 **둘레가 아니라 선 하나**로.
 *
 *   어느 변에 긋는가는 형제가 어떻게 놓였나로 정한다(probe_partition.mjs 로 실측):
 *     · 가로로 나란한 것(.bi-desk__col 3열, split 의 본문)  → 왼쪽 세로선
 *     · 세로로 쌓인 것(.bi-card--box, .bi-bksch-side-sec)   → 위쪽 가로선
 *   첫 칸에는 긋지 않는다(`+` 로 «앞에 형제가 있을 때만»). 그래서 바깥 둘레는 생기지 않는다.
 *   선 옆에 부모 gap 과 같은 여백을 줘 선이 글자에 붙지 않게 한다. */
/* ⚠ 선 옆에 여백을 더하면 **열이 그만큼 좁아진다.** designer_chart 가운데 열이 눌려
 *   «간편결제요청» 이 잘리고 제목이 두 줄로 접혔다(2026-08-14). 부모 gap(16)이 이미 사이를 벌려 놓았으니
 *   선만 긋고 여백은 더하지 않는다 — 폭은 한 픽셀도 뺏지 않는다. */
.bi-erp-card .bi-desk__col + .bi-desk__col,
.bi-erp-card .bi-bksplit__side + .bi-bksplit__main,
.bi-erp-card .bi-bksplit__side + .bi-bksplit__calcol {
    border-left: 1px solid var(--border-base);
}
.bi-erp-card .bi-card--box + .bi-card--box,
.bi-erp-card .bi-bksch-side-sec + .bi-bksch-side-sec,
.bi-erp-card .bi-bk-info-panel + .bi-bka,
.bi-erp-card .bi-bka + .bi-bk-info-panel {
    border-top: 1px solid var(--border-light);
    padding-top: var(--space-3);
}

/* ── 팝업 버튼 — 보드 §06 (2026-08-25) ─────────────────────────────────
 * 보드: 주 액션 #0023B7 h34 r8 13Bold · 검색 navy h37 w57 · ghost h34(작은 h30·12)
 * ⚠ 앱 전체 버튼 사다리(§12-4 48·32·27·22)는 **그대로 둔다.** 팝업만 다른 눈금이다.
 *   스코프: .bi-pop-page(팝업 문서 body) 안에서만. */
.bi-pop-page .bi-btn{ height: var(--pop-btn-h); border-radius: var(--pop-btn-r); font-size: var(--pop-btn-fs); }
.bi-pop-page .bi-btn--sm{ height: var(--pop-btn-sm-h); font-size: var(--pop-btn-sm-fs); }
.bi-pop-page .bi-btn--ghost{ background: var(--bg-card); border: 1px solid var(--pop-line); color: var(--txt-secondary); }
.bi-pop-page .bi-btn--primary{ background: var(--brand-blue); color: var(--bg-card); }

/* 팝업 폭 = 규격 (styleboard4 §07 · 2026-08-25).
 * popup_layer.js 가 인라인 px 대신 이 클래스를 붙인다 — 폭은 토큰 한 곳에서 바뀐다.
 * 보드에 본문이 없는 13개는 클래스가 안 붙어 기존 호출 인자를 그대로 쓴다(5단계에서 결정). */
.write_layout_pop--list{ width: var(--pop-w); }
/* 2026-08-28 — 세 번째 폭. 720 에 3분할을 넣으니 시간칩이 좁아 «갑갑하다» 는 지적(사용자). */
.write_layout_pop--form{ width: var(--pop-w-form); }
.write_layout_pop--wide{ width: var(--pop-w-wide); }
.write_layout_pop--prod{ width: var(--pop-w-prod); }
/* ⚠ (2026-09-15) 팝업은 «.bi-pop-page input[type=radio]» 로 네이티브 라디오를 되살린다(§05).
   그런데 .bi-bs-tab-r 은 보이라고 만든 입력이 아니라 «탭 상태만 나르는» 숨은 스위치다 —
   되살아나 정보카드 머리 옆에 **빈 동그라미**가 떴다(실측 17×17 @ #itab_memo).
   원래 규칙(.bi-bs-tab-r{display:none})은 건드리지 않고, 팝업 안에서 다시 숨긴다. */
.bi-pop-page input[type="radio"].bi-bs-tab-r { display: none; visibility: hidden; }
/* §72 시안 실측 폭 — 사람 검색 480 · 하나 고르는 카탈로그 540 */
.write_layout_pop--srch{ width: var(--pop-w-srch); }
.write_layout_pop--pick{ width: var(--pop-w-pick); }
/* §76 결제 팝업 — bs1·bs2·bs3 실측 480 (2026-09-15) */
.write_layout_pop--pay{ width: var(--pop-w-pay); }

/* ══ 2단계 컨트롤 — styleboard4 §06 (2026-08-25) ═══════════════════════
 * 팝업 안에서만 적용한다. 앱 전체 버튼 사다리(§12-4)·입력 규격은 그대로 둔다.
 * 보드: 주 액션 blue h34 · 검색 navy h37·w57 · ghost h34(작은 h30)
 *       검색칸 h38/r9 · 필드 h36/r8 · 셀렉트만 회색바탕 · 체크/라디오 17 */

/* 푸터 버튼은 --sm 이어도 h34 다 — 보드 푸터에는 «작은 닫기» 가 없다.
 * (디자이너 검색의 닫기가 --sm 이라 h30 으로 그려지고 있었다) */
.bi-pop-page .bi-pop-list-foot .bi-btn,
.bi-pop-page .bi-pop-foot-btns .bi-btn{ height: var(--pop-btn-h); font-size: var(--pop-btn-fs); }
.bi-pop-page .bi-pop-list-foot .bi-btn--sm,
.bi-pop-page .bi-pop-foot-btns .bi-btn--sm{ height: var(--pop-btn-sm-h); font-size: var(--pop-btn-sm-fs); }

/* 검색 버튼 — 색으로 주 액션과 구분한다(보드: 검색만 navy) */
/* ⚠ .sch_but_pop 은 **글자 없는 <a> 트리거**다(내용이 &nbsp; 하나).
 *   보드의 «검색» 버튼(navy·글자 있음)을 여기 씌웠더니 화면에 **글자 없는 네이비 덩어리**가 생겼다
 *   (2026-08-25 눈으로 잡힘 — 대조 검사기는 «다른 항목 1개» 라고 했다).
 *   보드 구조의 검색행은 3단계에서 마크업과 함께 만든다. 그때 .bi-btn--search 를 붙인다. */
.bi-pop-page .bi-btn--search{
    height: var(--pop-btn-nav-h); min-width: var(--pop-btn-nav-w);
    background: var(--brand-navy); color: var(--bg-input);
    border: 0; border-radius: var(--pop-btn-r);
    font-size: var(--pop-btn-sm-fs); font-weight: var(--fw-bold); cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
}

/* 입력 — 검색칸과 폼 필드는 높이가 다르다(보드 §06) */
.bi-pop-page .bi-input,
.bi-pop-page input[type="text"],
.bi-pop-page input[type="password"],
.bi-pop-page input[type="number"],
.bi-pop-page .text_input{
    height: var(--pop-field-h); border-radius: var(--pop-field-r);
    font-size: var(--pop-btn-fs); background: var(--bg-card);
    border: 1px solid var(--pop-line); box-sizing: border-box;
}
/* 셀렉트만 회색 바탕 — 보드 §06 «셀렉트만 #F9FAFB · 인풋은 흰 배경» */
.bi-pop-page select,
.bi-pop-page .bi-write-select{
    height: var(--pop-field-h); border-radius: var(--pop-field-r);
    font-size: var(--pop-btn-fs); background: var(--bg-input);
    border: 1px solid var(--pop-line); box-sizing: border-box;
}
/* 검색행 인풋은 더 크다(h38) — 검색은 팝업의 주 동작이다 */
.bi-pop-page .bi-pop-search input,
.bi-pop-page .body-main-sch input[type="text"]{
    height: var(--pop-search-h); border-radius: var(--pop-search-r);
    background: var(--bg-input);
}

/* 선택 컨트롤 — 체크 17·r2 · 라디오 17 · 라벨 13 (보드 §06) */
.bi-pop-page input[type="checkbox"]{
    width: var(--pop-check); height: var(--pop-check);
    accent-color: var(--pop-sel); border-radius: var(--pop-check-r);
}
.bi-pop-page input[type="radio"]{
    /* ⚠ 전역 레거시 `input[type=radio]{visibility:hidden;display:none}` 이 살아 있다.
       옛 화면은 <label> 로 동그라미를 «그려» 썼지만, 보드는 **네이티브 라디오**를 쓴다(§05).
       그래서 팝업 안에서는 되살린다 — 안 그러면 글자만 남고 동그라미가 사라진다(2026-08-26 실측). */
    display: inline-block; visibility: visible;
    width: var(--pop-check); height: var(--pop-check);
    accent-color: var(--brand-navy);
    margin: 0; vertical-align: middle;
}
/* ⚠ 보드는 «라디오 링 navy · 점 blue» 라고 적었지만 네이티브 입력은 링과 점을 **따로 못 칠한다.**
 *   직접 그리면 2026-08-25 에 되돌린 «깨져 보이는 체크박스» 로 돌아간다 → 한 색(navy)으로 둔다.
 *   보드에 반영이 필요하면 그때 함께 고친다. */
.bi-pop-page .bi-checkbox-label,
.bi-pop-page .bi-radio-label{ font-size: var(--pop-label-fs); font-weight: var(--fw-normal); }

/* ══ 3단계 리스트 본문 — styleboard4 §07 해부도 (2026-08-25) ═══════════
 * 보드 구조:
 *   검색행  .bi-pop-search > .bi-pop-search__box(아이콘+인풋) + navy 검색 버튼
 *           인풋 상자 h38·r9·#F9FAFB · 돋보기는 **상자 안쪽 좌측 12px**
 *   리스트  상단 1px --pop-line 으로 시작 · 선택은 좌측 4px indigo
 *
 * ⚠ 2단계에서 배운 것: 스타일을 **글자 없는 트리거**(.sch_but_pop)에 씌우면
 *   화면에 네이비 덩어리가 생긴다. 그래서 구조를 먼저 만들고 클래스를 붙인다. */

.bi-pop-page .bi-pop-search{
    display: flex; align-items: center; gap: var(--space-2);
    margin-bottom: var(--space-3);
}
/* 인풋 «상자» 가 배경·테두리·라운드를 갖고, 안쪽 <input> 은 투명하다 —
 * 돋보기를 상자 안에 두려면 이 구조여야 한다(보드와 같은 방식). */
.bi-pop-page .bi-pop-search__box{
    flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--space-2_5);
    height: var(--pop-search-h); padding: 0 var(--pop-search-pad-r) 0 var(--pop-search-pad-l);
    background: var(--bg-input); border: 1px solid var(--pop-line);
    border-radius: var(--pop-search-r); box-sizing: border-box;
    /* 안내 토스트가 «입력 상자» 를 기준으로 뜬다 — 검색행에 붙이면 버튼까지 포함한
       행 왼쪽 끝(본문 여백 밖)에 걸려, 리스트형 팝업에서 목록 위에 여백 없이 얹혔다
       (2026-09-02 사용자 지적). 기준을 상자로 내리면 왼쪽이 입력칸과 맞는다. */
    position: relative;
}
.bi-pop-page .bi-pop-search__box i{
    color: var(--pop-ico); font-size: var(--pop-btn-fs); width: 16px;
    text-align: center; flex: 0 0 auto;
}
/* 상자가 이미 테두리를 가졌다 — 안쪽 인풋은 배경도 테두리도 없다.
 * (2단계에서 넣은 .bi-pop-page input 규칙을 이 자리에서만 되돌린다) */
.bi-pop-page .bi-pop-search__box input{
    flex: 1; min-width: 0; height: auto;
    border: 0; padding: 0; background: transparent;
    font-size: var(--pop-btn-fs); color: var(--txt-primary); outline: none;
}
/* 포커스 표시는 «상자» 가 한다 — 안쪽 인풋이 따로 테를 그리면 링이 두 겹으로 보인다.
   레거시 .text_input:focus 가 box-shadow 를 얹는 팝업이 있어 그림자까지 끈다(2026-08-25). */
.bi-pop-page .bi-pop-search__box input:focus{ border: 0; box-shadow: none; background: transparent; }
.bi-pop-page .bi-pop-search__box:focus-within{ border-color: var(--brand-blue); box-shadow: var(--ring-focus); }
.bi-pop-page .bi-pop-search__box input::placeholder{ color: var(--txt-disabled); font-weight: var(--fw-semibold); }

/* 리스트는 상단 선으로 시작한다(보드 §07-3) */
.bi-pop-page .bi-pop-tbl,
.bi-pop-page .bi-pop-clist{ border-top: 1px solid var(--pop-line); }

/* iframe 은 width 속성(HTML)으로 폭을 받는다 — 규격 폭 팝업에서는 상자를 꽉 채우게 한다.
 * 안 그러면 박스만 423 이 되고 안쪽 문서는 500 인 채라 내용이 넘친다(2026-08-25 실측). */
/* §72 — --srch·--pick·--prod 를 «여기 적는 걸 빠뜨려» 같은 함정에 또 걸렸다:
     상자는 480 인데 안쪽 문서는 500 이라 줄 오른쪽 «고름 동그라미» 가 잘렸다(2026-09-14 실측).
   폭 등급을 새로 만들면 이 목록에도 «반드시» 더한다. */
.write_layout_pop--list > iframe,
.write_layout_pop--form > iframe,
.write_layout_pop--srch > iframe,
.write_layout_pop--pick > iframe,
.write_layout_pop--prod > iframe,
.write_layout_pop--wide > iframe,
.write_layout_pop--pay > iframe{ width: 100%; box-sizing: border-box; }

/* 보드 구조(.bi-pop-search)로 옮긴 검색행에서는 옛 절대배치를 푼다.
 * .sch_but_pop 은 원래 **인풋 위에 겹쳐 놓는 돋보기 오버레이**였다(position:absolute).
 * 보드는 인풋 오른쪽에 **글자 있는 navy 버튼**이다 — 겹치면 안 된다(2026-08-25 눈으로 잡음).
 * 훅(.sch_but_pop)은 JS 가 쓰므로 지우지 않고, 이 구조 안에서만 배치를 되돌린다. */
.bi-pop-page .bi-pop-srch .sch_but_pop,
.bi-pop-page .bi-pop-search .sch_but_pop{
    position: static; width: auto; height: var(--pop-btn-nav-h); min-width: var(--pop-btn-nav-w);
    flex: 0 0 auto; padding: 0 var(--space-3);
    background: var(--brand-navy); color: var(--bg-input);
    border-radius: var(--pop-btn-r); font-size: var(--pop-btn-sm-fs); font-weight: var(--fw-bold);
    display: inline-flex; align-items: center; justify-content: center; text-decoration: none;
}

/* 옛 검색 돋보기는 **인풋 위에 절대배치로 얹는** 방식이었다(.bi-pop-pay--list .body-main-sch .fa-search).
 * 보드 구조에서는 돋보기가 **상자 안 첫 자식**이라 흐름 배치여야 한다 —
 * 절대배치가 남아 있으면 상자 밖으로 떨어진다(2026-08-25 눈으로 잡음: 목록 위에 떠 있었다). */
.bi-pop-page .bi-pop-search .bi-pop-search__box i{ position: static; transform: none; left: auto; top: auto; }
/* ⚠ 옛 규칙 .bi-pop-pay--list .body-main-sch .fa-search 가 클래스 3개(0,3,0)라
 *   내 0,2,1 로는 못 이겼다. !important 대신 **선택자를 한 단계 더** 적어 이긴다. */

/* ══ 2줄 카드행 — styleboard4 §07-3 / §08 (2026-08-25) ═════════════════
 * 보드: 「2줄 행(고객)이면 행마다 테두리, 그리드 행(상품)이면 구분선」
 *       선택 = 좌측 4px indigo + 옅은 바탕, **테두리는 없앤다**(막대가 대신한다)
 *
 * ⚠ .bi-pop-clist 는 2026-08-10 에 규격만 만들고 **쓰는 팝업이 0개** 였다
 *   (그때 문서에도 「실제 팝업 적용은 미착수」로 적혀 있다).
 *   이제 고객 검색이 처음 쓴다 — 규격은 «쓰여야» 규격이다. */

/* 보드: 행은 «맞붙어» 있다 — 간격 0 · 라운드 0 · 목록 위 1px 선으로 시작하고
 * 팝업 좌우 끝까지 간다(본문 좌우 여백을 음수로 상쇄). 라운드 행(.r10)은 보드에서
 * «아직 안 정한 대안» 으로 그려둔 것이라 규격이 아니다. */
.bi-pop-page .bi-pop-clist{
    list-style: none; margin: 0; padding: 0;
    border-top: 1px solid var(--pop-line);
    overflow-y: auto; flex: 1 1 auto; min-height: 0;
}
.bi-pop-page .bi-pop-clist-item{
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--pop-row-pad-y) var(--pop-row-pad-x); box-sizing: border-box;
    background: var(--bg-card); cursor: pointer;
    border: 0; border-bottom: 1px solid var(--pop-line);   /* 한 줄만 — 겹쳐 2px 되던 것 (2026-08-26) */
    min-height: var(--pop-row-min-h);   /* 보조줄 유무와 무관하게 같은 높이(2026-08-26) */
}
.bi-pop-page .bi-pop-clist-item:hover{ background: var(--bg-selected); }
/* 선택 — 보드: 테두리를 없애고 좌측 4px 막대. 여백은 막대 두께만큼 보정한다. */
.bi-pop-page .bi-pop-clist-item.is-sel{
    background: var(--bg-selected);
    border-left: var(--pop-sel-bar) solid var(--pop-sel);
    padding: var(--pop-row-pad-y) var(--pop-row-pad-x) var(--pop-row-pad-y)
             calc(var(--pop-row-pad-x) + var(--pop-sel-bar));
}
.bi-pop-page .bi-pop-clist-main{ flex: 1; min-width: 0; }
.bi-pop-page .bi-pop-clist-nm{
    font-size: 13.5px; font-weight: var(--fw-bold); color: var(--txt-primary); line-height: 1.5;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 이름 옆 연락처 — 보드는 같은 줄에 흐린 글자로 둔다 */
.bi-pop-page .bi-pop-clist-nm span{ font-size: var(--pop-cnt-fs); font-weight: var(--fw-medium); color: var(--txt-muted); }
.bi-pop-page .bi-pop-clist-sub{
    font-size: var(--pop-cnt-fs); color: var(--txt-muted); line-height: 1.5;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bi-pop-page .bi-pop-clist-meta{
    flex: 0 0 auto; font-size: var(--pop-cnt-fs); font-weight: var(--fw-bold);
    color: var(--txt-secondary); text-align: right;
}
.bi-pop-page .bi-pop-clist-item.is-sel .bi-pop-clist-meta{ color: var(--pop-sel); }

/* 카드행 목록에는 표 헤더가 없다 — 각 행이 스스로 설명한다(보드 §08) */
.bi-pop-page .bi-pop-clist + .bi-pop-tbl-head,
.bi-pop-page .bi-pop-tbl-head.is-hidden{ display: none; }

/* ══ 목록형 팝업 «채움» — styleboard4 §08 (2026-08-25) ═══════════════════
 * 보드에서 목록은 팝업 본문을 «끝까지» 채우고, 넘치면 목록만 스크롤한다.
 * 실물은 .bi-pop-tbl-body{max-height:245px} 라 창 높이 600 에서 4행만 보이고
 * 아래가 텅 비었다 — 창 높이와 목록 높이가 서로를 모른다.
 * 높이를 새로 계산하지 않고 flex 사슬로 «남는 만큼» 준다.
 * body 에 absolute inset 을 쓰는 이유: html{height:100%} 를 전역에 심지 않기 위해서다. */
/* 기준점은 body 가 아니라 래퍼다 — 팝업 문서는 <body> 가 두 번 나오고(header + 개별 파일)
 * 파서가 «먼저 나온» body 의 class 만 살리기 때문에 개별 팝업의 body class 는 절대 안 먹는다. */
.bi-pop-pay--fill{ position: absolute; inset: 0; display: flex; flex-direction: column; overflow: hidden; }
/* ⚠ .bi-pop-pad 는 본문에도, 하단 버튼바에도 쓰인다(같은 이름 두 용도).
   통째로 늘리면 푸터까지 늘어나 버튼이 허공에 뜬다 — naver 에서 실제로 그랬다.
   늘어나는 것은 «목록을 품은» 본문 하나뿐이다. */
.bi-pop-pay--fill .bi-pop-pad--fill,
.bi-pop-pay--fill .bi-pop-listwrap{ display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.bi-pop-pay--fill > .bi-pop-pad:not(.bi-pop-pad--fill){ flex: 0 0 auto; }   /* 하단 버튼바 */
.bi-pop-pay--fill .bi-pop-search{ flex: 0 0 auto; }
.bi-pop-pay--fill .bi-pop-tbl-body{ flex: 1 1 auto; max-height: none; min-height: 0; display: flex; flex-direction: column; }
.bi-pop-pay--fill .bi-pop-list-foot{ flex: 0 0 auto; }

/* 좌우 여백은 «검색행과 푸터에만» 준다 — 보드에서 목록은 팝업 벽까지 닿고,
 * 행 안쪽 14px 이 글자를 세운다. 음수 마진으로 여백을 상쇄하던 방식은
 * 껍데기(.bi-pop-pay 24px)와 본문(.bi-pop-pad 10px)이 각각 밀어 두 겹으로 어긋났다. */
.bi-pop-pay--fill,
.bi-pop-pay--fill .bi-pop-pad--fill{ padding-left: 0; padding-right: 0; }
.bi-pop-pay--fill .bi-pop-search{ padding: 0 var(--pop-head-pad-x) var(--pop-head-pad-x); margin-bottom: 0; }
.bi-pop-pay--fill .bi-pop-list-foot{ padding: var(--pop-foot-pad-t) var(--pop-head-pad-x) var(--pop-foot-pad-b); }

/* 헤더 건수 — 보드: 제목 뒤 12px SemiBold 회색 (2026-08-25) */
.bi-pop-head-cnt{ font-size: var(--pop-cnt-fs); font-weight: var(--fw-semibold); color: var(--txt-muted); margin-left: var(--space-0_5); }
.bi-pop-head-cnt:empty{ display: none; }

/* 빈 상태 줄 — «결과 없음» 은 행이 아니다. 카드행 규격(테두리·선택·2줄)을 입히면
   검사기가 이걸 행으로 재고, 사용자도 누를 수 있는 줄로 오해한다. (2026-08-25) */
/* 2026-08-28 — 스코프를 풀었다. 「비어 있음」은 팝업만의 것이 아니다.
   designer_chart 본문이 같은 뜻으로 `.bi-paypop__item-empty` 를 따로 갖고 있었다 —
   같은 것을 두 이름으로 두면 둘이 서서히 달라진다. 빈 상태는 제품 전체에서 하나다. */
.bi-pop-clist-none{
    list-style: none; padding: var(--pop-row-pad-y) var(--pop-row-pad-x);
    color: var(--txt-muted); text-align: center; font-size: var(--pop-cnt-fs);
}

/* 채움형 팝업의 푸터는 흐름 안에 둔다 — 옛 position:fixed 는 목록 마지막 줄을 덮는다 (2026-08-25) */
.bi-pop-pay--fill .bi-pop-list-foot{ position: static; }

/* 푸터 좌우 가르기 — 보드 §푸터: 선택 초기화(좌) … 확인·닫기(우) (2026-08-26) */
.bi-pop-foot-sp{ flex: 1 1 auto; }

/* 팝업 iframe 은 블록으로 — inline 줄상자 여백이 팝업 바닥에 빈 띠를 만든다 (2026-08-26) */
.write_layout_pop > iframe{ display: block; }

/* 규격 푸터 안의 버튼 묶음은 «배치» 만 한다 — 여백·선은 바깥 푸터가 이미 그렸다 (2026-08-26) */
.bi-pop-list-foot .bi-pop-foot-btns{ padding: 0; border-top: 0; background: transparent; }
/* 2026-08-28 — 전폭(100vw) 규칙이 «푸터 안에 든 푸터» 에도 걸렸다.
   버튼 묶음이 팝업 폭을 통째로 차지해 왼쪽 체크 라벨을 상자 밖(-90px)으로 밀어냈고,
   그래서 「내부소진·샘플」이 왼쪽 가장자리에 한 글자씩 세로로 눌려 보였다(사용자 캡처 poc1).
   전폭은 «바깥 푸터» 의 성질이다 — 안쪽 묶음은 제 내용만큼만 차지한다. */
.bi-pop-page .bi-pop-list-foot .bi-pop-foot-btns{
    width: auto; margin-left: 0; margin-right: 0; flex: 0 1 auto;
    /* 위 여백(16)도 «바깥 푸터» 의 것이다 — 안쪽 묶음이 받으면 푸터가 그만큼 두꺼워진다.
       실측: 상품추가 76 vs 고객검색·디자이너검색 60. 같은 형식이어야 한다(사용자 지적). */
    margin-top: 0;
}

/* 상품 추가형 간격 — 보드 §08 (2026-08-26) */
.bi-pop-catalog .bi-pop-search{ padding-bottom: var(--space-2_5); }
.bi-pop-catalog .bi-pop-cat-tools{ gap: 0; margin-bottom: var(--space-4); }

/* 상품 행 체크박스 — 보드 §08 (2026-08-26) */
.bi-pop-catalog .bi-pop-prod-ul input[type="checkbox"]{ width: var(--pop-check); height: var(--pop-check); margin: 0; accent-color: var(--pop-sel); cursor: pointer; }
/* 푸터 좌측 옵션은 왼쪽 끝에 — 규격 푸터가 오른쪽 정렬이라 그냥 두면 버튼 쪽으로 밀린다 */
.bi-pop-list-foot .bi-pop-check{ margin-right: auto; }
/* 2026-08-28 — 푸터의 체크 라벨이 «세로로 눌려» 글자가 한 자씩 쪼개졌다(사용자 캡처 poc1·상품추가).
   .bi-pop-check 는 flex 항목인데 flex-shrink 기본값이 1 이라, 옆 버튼들이 자리를 다 가져가면
   라벨이 0 에 가깝게 줄어든다. 보드 견본(§07 상품 추가)의 푸터는 «한 줄» 이다 — 줄지 않게 못박는다.
   ⚠ 기존 선언은 그대로 두고 «새 규칙» 으로 더한다(§4). */
.bi-pop-list-foot .bi-pop-check,
.bi-pop-foot-btns .bi-pop-check{ flex: 0 0 auto; white-space: nowrap; }

/* ══════════════════════════════════════════════════════════════════════
   .bi-pop-board — «규격안(styleboard4) 값을 그대로 쓰는 팝업» 표시 (2026-08-28)

   왜 새 클래스인가
     팝업 하나를 규격에 맞추려고 .bi-pop-pay / .bi-pop-pad / 푸터 같은 **공통 규칙의 값**을
     고쳤더니, 그 규칙을 쓰는 다른 팝업이 함께 움직여 상품추가 팝업이 깨졌다(사용자 지적).
     프로젝트 규칙 §4 — 기존 클래스는 고치지 않고 **새 클래스를 더한다**.
     그래서 규격값은 전부 여기 모으고, 옮긴 팝업의 뿌리에만 이 클래스를 붙인다.
     붙이지 않은 팝업은 예전 그대로 — 회귀가 원천적으로 생기지 않는다.

   값의 출처는 보드뿐이다(probe_vs_board.mjs 가 보드에서 읽어 대조한다).
   ══════════════════════════════════════════════════════════════════════ */
.bi-pop-board{                                   /* 보드 .pop-body */
    padding: 0 var(--pop-head-pad-x) var(--space-4);
    color: var(--txt-primary); line-height: 1.5;
}
/* 본문 아래 16 은 «본문» 의 것 — 푸터는 그 아래 바닥에 붙는다(보드 .pop-body) */
.bi-pop-board .bi-pop-pad{ padding: 0 0 var(--space-4); }
.bi-pop-board .bi-pop-pad--form{ padding: 0 0 var(--space-4); }
/* 목록이 본문의 마지막이면 «마지막 행의 아래선이 곧 푸터 윗선» — 사이 여백 0(보드 .pp-b.flush) */
.bi-pop-board:has(> .bi-pop-pad > .bi-pop-clist:last-child),
.bi-pop-board:has(> .bi-pop-pad > .bi-pop-tbl-body:last-child),
.bi-pop-board:has(> .bi-pop-pad--form > .bi-pop-clist:last-child){ padding-bottom: 0; }
/* 본문↔푸터선 16 은 «본문의 아래 여백» 이다 — 푸터에 얹으면 자리가 어긋난다 */
.bi-pop-page .bi-pop-board .bi-pop-list-foot,
.bi-pop-page .bi-pop-board .bi-pop-foot-btns{ margin-top: 0; }
/* 헤더는 부모 DOM 이라 여기 닿지 않는다 — 헤더용 규격은 .bi-pop-head--board 로 따로 준다 */

/* 2026-08-28 — 팝업 푸터 버튼을 보드 `.b`/`.b-pri`/`.b-ghost` 값 그대로 맞춘다.
   전역 `.bi-btn` 은 제품 전체가 쓰므로 건드리지 않고, **팝업 푸터 안에서만** 규격을 준다.
   어긋나 있던 것: 높이(패딩 8 로 대신) · 줄간격 1(=13px, 보드 19.5) · 보조버튼 굵기 500(보드 700)
   · 좌우 16(보조버튼 보드 13) · 아이콘 간격 6(보드에는 없다) · 모서리 --radius-lg(보드 8). */
.bi-pop-list-foot .bi-btn,
.bi-pop-foot-btns .bi-btn{
    height: 34px; padding: 0 var(--space-4); border-radius: var(--radius-lg);
    font-size: var(--pop-f-fs); font-weight: var(--fw-bold); line-height: 19.5px;
    justify-content: center; gap: normal; border: 1px solid transparent;
}
.bi-pop-list-foot .bi-btn > i,
.bi-pop-foot-btns .bi-btn > i{ margin-right: var(--space-1_5); }   /* 아이콘은 gap 대신 제 여백으로 */
.bi-pop-list-foot .bi-btn--primary,
.bi-pop-foot-btns .bi-btn--primary{ background: var(--brand-blue); color: var(--bg-card); border-color: transparent; }
.bi-pop-list-foot .bi-btn--ghost,
.bi-pop-foot-btns .bi-btn--ghost{ background: var(--bg-card); color: var(--txt-secondary); border-color: var(--pop-line); }
/* 옵션 줄 오른쪽 금액 — 「생일할인 … 0」처럼 체크와 값이 한 줄에 서는 곳(2026-08-27) */
.bi-pop-page .bi-pop-opt-row{ display: flex; align-items: center; gap: var(--space-4); }
.bi-pop-page .bi-pop-opt-amt{ margin-left: auto; font-size: var(--pop-f-fs); font-weight: var(--fw-bold); color: var(--txt-primary); }
/* 금액 요약 줄 — 「이름 : 값」 몇 줄짜리 팝업(네이버페이 환불 등)의 공통 짜임.
   보드에 별도 원형이 없어 폼 라벨·본문 글자를 그대로 쓴다(2026-08-27). */
.bi-pop-page .bi-pop-sumlist{ display: flex; flex-direction: column; gap: var(--space-2_5); margin-bottom: var(--space-4); }
.bi-pop-page .bi-pop-sumrow{ display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); font-size: var(--pop-cnt-fs); color: var(--txt-secondary); }
.bi-pop-page .bi-pop-sumrow > span:last-child{ font-weight: var(--fw-bold); color: var(--txt-primary); }
.bi-pop-page .bi-pop-sumrow--strong{ font-size: var(--pop-f-fs); }
.bi-pop-page .bi-pop-sumrow--strong > span:last-child{ font-size: var(--fs-lg); font-weight: var(--fw-extrabold); }

/* 라벨 옆 보조설명 — 붙어 보이던 것(2026-08-27). 라벨은 굵고 보조는 흐리게, 사이를 띄운다. */
.bi-pop-page .bi-pop-f > label .sub_description{ margin-left: var(--space-1_5); font-weight: var(--fw-medium); color: var(--txt-disabled); }

/* 푸터 왼쪽 보조 링크(모듈설치확인 등) — 버튼과 같은 줄에 두되 왼쪽 끝에 붙인다. */
.bi-pop-list-foot .bi-pop-foot-link{ margin-right: auto; font-size: var(--pop-cnt-fs); color: var(--txt-muted); }

/* ══ 팝업 폼 격자 — 보드 §08·§09 (2026-08-26) ═══════════════════════
 * 라벨(12 ExtraBold) 위 · 입력 아래 · 두 칸씩. 한 칸짜리는 --one 으로 폭을 다 쓴다. */
.bi-pop-form2{ display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3) var(--space-3); margin-bottom: var(--space-3); }
.bi-pop-f{ display: flex; flex-direction: column; gap: var(--pop-f-gap); min-width: 0; }
.bi-pop-f > label{ font-size: var(--pop-cnt-fs); font-weight: var(--fw-bold); color: var(--txt-secondary); line-height: 18px; }
.bi-pop-f > label .bi-req{ color: var(--color-danger); margin-left: var(--space-0_5); }
/* 2026-08-28 — `number`·`tel` 이 빠져 있었다. 타입 하나가 빠지면 그 칸만 규격 밖이 되는데
   생김새가 비슷해 눈으로는 안 잡힌다(discount 의 «직접 입력» 이 그랬다). 타입을 다 적는다. */
.bi-pop-page .bi-pop-f input[type="text"], .bi-pop-page .bi-pop-f input[type="password"],
.bi-pop-page .bi-pop-f input[type="number"], .bi-pop-page .bi-pop-f input[type="tel"],
.bi-pop-page .bi-pop-f select{
    width: 100%; height: var(--pop-field-h); border-radius: var(--pop-field-r);
    padding: 0 var(--space-3); font-size: var(--pop-f-fs); border: 1px solid var(--pop-line);
    background: var(--bg-card); color: var(--txt-primary); box-sizing: border-box;
}
/* ⚠ 위 규칙과 특이도가 같아(0,3,1) «뒤» 에 있어야 이긴다 —
   검색 상자 «안» 의 인풋은 투명해야 테두리가 두 겹으로 안 보인다(2026-09-02). */
.bi-pop-page .bi-pop-search__box input,
.bi-pop-page .bi-pop-f .bi-pop-search__box input,
.bi-pop-page .bi-pop-search__box input.bi-input{
    border: 0; background: transparent; box-shadow: none; height: auto; padding: 0; border-radius: 0;
}
.bi-pop-page .bi-pop-f select{ background: var(--bg-input); }   /* 보드: 셀렉트는 바탕이 옅다 */
/* 2026-08-28 — 보드 §09 에는 «여러 줄 입력»(.pp-f .tx)이 있는데 CSS 에 옮겨져 있지 않았다.
   그래서 팝업마다 제 방언(.bi-msgpop__ta 등)으로 따로 만들고 있었다. 보드 값 그대로 여기 둔다. */
.bi-pop-page .bi-pop-f textarea{
    width: 100%; min-height: 96px; resize: vertical;
    border-radius: var(--pop-field-r); padding: var(--space-2_5) var(--space-3);
    font-size: var(--pop-f-fs); line-height: 1.6; border: 1px solid var(--pop-line);
    background: var(--bg-card); color: var(--txt-primary); box-sizing: border-box; font-family: var(--font-sans);
}
/* 결제구분↔결제금액 줄 — 보드는 구분이 좁고 금액이 넓다 */
.bi-pop-form2--amt{ grid-template-columns: 110px 1fr; }
/* 3열·4열 — 보드 §09 의 .fgrid 를 열 수만 달리한 것. 짧은 칸(성별·생년월일·등급 / 적립률 넷)이 한 줄에 든다. */
/* 폼 칸 안의 «입력 + 검색 버튼» 한 줄 — 보드 .fwrap. 여러 팝업이 같은 모양을 각자 그리고 있었다. */
.bi-pop-page .bi-pop-srch{ display: flex; align-items: center; gap: var(--space-2); }
.bi-pop-page .bi-pop-srch > input[type=text]{ flex: 1 1 auto; min-width: 0; }
/* 2026-09-02 — 「직책·은행」 처럼 «셀렉트 + 옆 버튼» 이 생겼다(사용자 지시로 버튼을 라벨 줄에서 내렸다).
   위 규칙이 input[type=text] 만 늘려서 select 는 제 폭에 머물고 버튼이 가운데 떠 있었다. */
.bi-pop-page .bi-pop-srch > select{ flex: 1 1 auto; min-width: 0; }
.bi-pop-page .bi-pop-srch > .bi-btn{ flex: 0 0 auto; height: var(--pop-field-h); }
.bi-pop-form3{ display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-3); margin-bottom: var(--space-3); }
.bi-pop-form4{ display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-2) var(--space-2); margin-bottom: var(--space-3); }
/* 폼 섹션 구분 — 새 색 없이 --group 선 + 흐린 소제목(보드 .fsec) */
.bi-pop-fsec{ display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-1_5); padding-top: var(--space-3_5); border-top: 1px solid var(--gray-100); }
.bi-pop-fsec--first{ margin-top: 0; padding-top: 0; border-top: 0; }
.bi-pop-fsec > span{ font-size: var(--fs-xs); font-weight: var(--fw-extrabold); letter-spacing: .08em; color: var(--txt-disabled); }

/* 폼 본문은 좌우 여백을 지킨다 — 목록형만 벽까지 간다 (2026-08-26) */
.bi-pop-pad--form{ padding: 0 var(--pop-head-pad-x); }   /* 규격값은 .bi-pop-board 에서(2026-08-28 되돌림) */

/* 폼 셀렉트 — 전역 select 규칙(44)이 이겨 칸 높이가 어긋났다(2026-08-26) */
.bi-pop-page .bi-pop-f select{ height: var(--pop-field-h); font-size: var(--pop-f-fs); background: var(--bg-input); }

/* 팝업 푸터 — 원형과 무관한 공통 규격 (2026-08-26) */
.bi-pop-page .bi-pop-list-foot{
    display: flex; align-items: center; justify-content: flex-end; gap: var(--pop-foot-gap);
    padding: var(--pop-foot-pad-t) var(--pop-head-pad-x) var(--pop-foot-pad-b);
    border-top: 1px solid var(--pop-line); background: var(--bg-card); box-sizing: border-box;
}

/* 폼 안의 체크 줄도 다음 줄과 12 를 띄운다 — 보드 §08 (2026-08-26) */
.bi-pop-pad--form .bi-pop-check{ margin-bottom: var(--space-3); }

/* 폼 본문은 헤더 바로 아래에서 시작한다 — 보드 §08 (2026-08-26) */
.bi-pop-pad--form{ padding-top: 0; }   /* 위 선언과 같은 뜻 — 뒤에 오는 단축속성이 되돌리지 않게 한 번 더 */

/* 여백이 두 겹으로 잡히던 것 — `.bi-pop-pay`(자체 padding)가 `.bi-pop-pad--form`(18)을 감싸면
   본문이 42 만큼 밀려 헤더 타이틀보다 안쪽에서 시작했다(cash 실측 2026-08-27). 여백은 안쪽 한 곳만 잡는다. */
.bi-pop-pay:has(.bi-pop-pad){ padding: 0; }
/* ⚠ 2026-08-28 — 위 `:has()` 규칙이 «뒤에 오고 특이도도 높아» .bi-pop-board 의 본문 여백을 지웠다.
   그래서 안내문·검색줄이 팝업 벽에 붙어 버렸다(규격안은 좌우 18 들여쓰기).
   규격 여백은 여기서 다시 못박는다 — 클래스를 더하는 것만으로는 «뒤에 오는 규칙» 을 못 이긴다. */
/* ⚠ 아래 16 을 «껍데기» 에 주면 그 여백이 **푸터 밑** 에 깔려 푸터가 떠 보인다
   (실측 푸터아래여유 paylist_cash 17 · setpoint 16 — 사용자 지적).
   보드에서 그 16 은 본문(.pop-body)의 것이다. 껍데기는 좌우만 갖는다. */
.bi-pop-pay.bi-pop-board{ padding: 0 var(--pop-head-pad-x) 0; }
/* 보드: **목록은 팝업 벽까지 닿는다** — 구분선이 벽에서 벽까지 그어지고,
   글자는 행 안쪽 여백(14)이 세운다. 안내문·검색줄만 18 들여쓴다.
   목록까지 18 을 먹으면 구분선이 짧아져 «떠 있는» 선으로 보인다(사용자 지적). */
.bi-pop-pay.bi-pop-board .bi-pop-clist,
.bi-pop-pay.bi-pop-board .bi-pop-tbl-body{
    margin-left: calc(var(--pop-head-pad-x) * -1);
    margin-right: calc(var(--pop-head-pad-x) * -1);
}
/* ⚠ 목록이 «상자 안에 또» 들어 있는 팝업이 있다(.bi-pop-tbl-body > .bi-pop-clist — pay_ref).
   둘 다 −18 을 받으면 −36 이 되어 행이 좌우로 잘린다("60%" 가 "0%" 로 보였다).
   전폭은 바깥 상자 한 번만 준다. */
.bi-pop-pay.bi-pop-board .bi-pop-tbl-body .bi-pop-clist{ margin-left: 0; margin-right: 0; }
/* 안내문 아래 16 — 보드 `.pop-note{margin:0 0 12~16}`.
   `.bi-pop-note:last-of-type:not(:only-child){margin-bottom:0}` 이 이걸 지워
   setpoint 에서 안내문과 「시술」이 맞붙어 있었다(사용자 지적). 특이도를 맞춰 되돌린다. */
/* ⚠ `.bi-pop-note:last-of-type:not(:only-child){margin-bottom:0}` 이 **뒤에 있고 특이도도 같아**
   계속 이겼다(실측 안내문↔본문 0, 규격안 12). :last-of-type 을 함께 걸어 특이도를 올린다. */
.bi-pop-page .bi-pop-pay.bi-pop-board .bi-pop-note,
.bi-pop-page .bi-pop-pay.bi-pop-board .bi-pop-note:last-of-type{ margin-bottom: var(--space-3); }
/* 본문 아래 16 도 `:has(.bi-pop-pad){padding:0}` 에 밀려 0 이 되곤 했다 — 특이도를 올려 못박는다.
   (--disc 와 «목록이 마지막» 인 경우는 아래 규칙이 더 높은 특이도로 다시 덮는다) */
.bi-pop-page .bi-pop-pay.bi-pop-board{ padding-bottom: 0; }
/* ⚠ 제휴/할인은 푸터가 «하단 고정» 이라 그 높이만큼 아래를 비워 둬야 한다.
   바로 위 board 여백(아래 16)이 그 예약을 덮어써서 단위·직접입력 폼이 푸터에 가려졌다.
   푸터를 이루는 값으로 다시 계산해 준다(버튼 높이가 바뀌면 함께 따라간다). */
/* ⚠ 뿌리 padding 으로 푸터 자리를 잡으려 했으나, 뿌리를 노리는 규칙이 여럿이라
   특이도 싸움이 반복됐다(실측 padding-bottom 이 계속 0). 그래서 **마지막 블록 자신** 이
   푸터 높이만큼 아래를 밀어 두게 한다 — 뿌리 여백이 어떻게 되든 폼이 가려지지 않는다. */
.bi-pop-pay--disc > .bi-pop-pad--form{
    margin-bottom: calc(var(--pop-foot-pad-t) + 34px + var(--pop-foot-pad-b));
}
/* 이 둘은 푸터가 본문의 «마지막 요소» 다 — 뿌리 아래 여백이 남으면 푸터 밑에 빈 띠가 생긴다
   (실측 푸터아래여유 16). 보드는 0 이다. */
.bi-pop-page .bi-pop-pay.bi-pop-board.bi-pop-pay--dchart,
.bi-pop-page .bi-pop-pay.bi-pop-board.bi-pop-pay--aim{ padding-bottom: 0; }
/* 결제수단 고르개 — 보드에 이 부품은 없지만, «여럿 중 하나를 고르는 칩» 은 보드 §06 의 필터 pill 이다.
   그 값(높이 28~38 · radius 999 · 활성 #EEF2FF/#BFD0FF/#0023B7)을 그대로 가져다 쓴다.
   ⚠ 기존 `.bi-paypop__method` 선언은 그대로 두고, 규격 팝업 안에서만 덮는다(§4). */
.bi-pop-board .bi-paypop__method{
    height: 38px; padding: 0 var(--space-3_5); border-radius: var(--radius-full);
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--pop-line); background: var(--bg-card);
    font-size: var(--pop-f-fs); font-weight: var(--fw-bold); color: var(--txt-secondary);
}
.bi-pop-board .bi-paypop__method.is-active{
    background: var(--color-indigo-50); border-color: var(--pop-pill-line, #BFD0FF); color: var(--brand-blue);
}
/* ── AI 메시지: 규격안대로 «군더더기» 를 걷는다 (2026-08-28 사용자 지시) ──
   규격안의 선택지는 «이름 + 단가» 두 줄이 전부다. 실제에는 체크표시(::after)와
   inset 이중 테두리·그림자가 들어가 있어 다른 물건처럼 보였다. */
.bi-pop-board .bi-msgpop__mode{
    border: 1px solid var(--pop-line); border-radius: var(--radius-2xl);
    background: var(--bg-card); box-shadow: none; padding: var(--space-3) var(--space-2_5);
}
.bi-pop-board .bi-msgpop__mode.is-active{
    border-color: var(--brand-blue); background: var(--color-indigo-50); box-shadow: none;
}
.bi-pop-board .bi-msgpop__mode.is-active::after{ content: none; }   /* 체크표시 제거 */
/* 수신인 태그 — 글자가 흐려 보였다. 규격안과 같은 «대비» 를 토큰으로 낸다.
   ⚠ 날색(#EEF2FF 등)을 그대로 쓰면 게이트가 막는다 — 같은 값의 토큰이 이미 있다. */
.bi-pop-board .bi-msgpop__tag.tag-indigo{ background: var(--color-indigo-50); color: var(--color-indigo-700); }
.bi-pop-board .bi-msgpop__tag.tag-amber { background: var(--color-warning-100); color: var(--color-warning-800); }
.bi-pop-board .bi-msgpop__tag.tag-rose  { background: var(--color-rose-100); color: var(--color-rose-700); }
/* ⚠ 하단 «고정» 푸터를 쓰는 팝업(--disc)은 제외한다 — 여기서 아래를 0 으로 만들면
   푸터가 흐름 밖이라 본문 마지막 블록을 그대로 덮는다(실측: 폼이 통째로 가려졌다). */
.bi-pop-page .bi-pop-board .bi-pop-pad:has(> .bi-pop-clist:last-child),
.bi-pop-page .bi-pop-board .bi-pop-pad:has(> .bi-pop-tbl-body:last-child),
.bi-pop-page .bi-pop-board .bi-pop-pad--form:has(> .bi-pop-clist:last-child){ padding-bottom: 0; }

/* 2026-08-28 — 검색·목록형인데 «목록 아래에 폼이 하나 더» 붙는 유일한 팝업(제휴/할인).
   푸터는 이 원형답게 하단 고정(position:fixed)이라 흐름에서 빠진다. 그래서 두 가지가 필요하다:
     ① 목록이 남는 자리를 먹어야 폼이 푸터 «바로 위» 에 선다(안 그러면 폼이 허공 가운데 뜬다 — 실측 빈 띠 165)
     ② 푸터 높이만큼 아래를 비워 둬야 푸터가 폼을 «덮지» 않는다
   ⚠ ②를 --list 의 padding-bottom 에 기대면 안 된다. 바로 위 `:has(.bi-pop-pad){padding:0}` 이 그걸 지운다
     (실측 padding-bottom 0 → 고정 푸터가 폼 위에 겹쳐 폼이 통째로 안 보였다).
     그래서 그 규칙 **뒤에서** 같은 특이도로 다시 준다.
   ⚠ box-sizing 을 빼면 100vh 에 아래 여백이 더해져 폼이 상자 밖으로 밀려난다. */
.bi-pop-pay--list.bi-pop-pay--disc{
    box-sizing: border-box; display: flex; flex-direction: column;
    height: 100vh; padding-bottom: calc(var(--pop-foot-pad-t) + 34px + var(--pop-foot-pad-b));
}
.bi-pop-pay--disc > .bi-pop-pad:not(.bi-pop-pad--form){ display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
.bi-pop-pay--disc .bi-pop-clist{ flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.bi-pop-pay--disc > .bi-pop-pad--form{ flex: 0 0 auto; }
/* 푸터 윗선은 «팝업 전폭» 이다 — 보드 §08.
   ⚠ 감싼 상자마다 음수 여백을 주는 방식은 새 상자가 생길 때마다 빠진다(2026-08-27 네 팝업에서 확인).
     iframe 뷰포트 폭 = 팝업 안폭이라, 그 기준으로 한 번에 뚫는다. 버튼 여백(18)은 푸터 자신의 패딩이 지킨다. */
.bi-pop-page .bi-pop-list-foot,
.bi-pop-page .bi-pop-foot-btns{
    width: 100vw; margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw); box-sizing: border-box;
    margin-top: var(--space-4);   /* 본문 ↔ 푸터선 16. 규격 배치는 .bi-pop-board 가 덮는다(2026-08-28 되돌림) */
}
/* 2026-08-28 — 보드 `.pp-b.flush` 규칙을 제대로 옮긴다.
   실측(probe_gaps): 마지막블록↔푸터선이 **규격안 0 · 실제 16~24** 였다.
   목록이 본문의 마지막이면 «마지막 행의 아래선이 곧 푸터 윗선» 이라 사이에 여백이 없다.
   내가 본문 아래 16 을 모든 팝업에 준 것이 목록형에서는 규격을 깨뜨렸다(사용자 지적).
   ⚠ 폼형은 반대다 — 마지막 칸의 margin-bottom 12 + 본문 16 = 28 이 규격이다. 그래서
     아래에 있던 `:last-child{margin-bottom:0}` 도 걷는다(그게 폼형을 16 으로 눌러 놨다). */
.bi-pop-page .bi-pop-pad:has(> .bi-pop-clist:last-child),
.bi-pop-page .bi-pop-pad:has(> .bi-pop-tbl-body:last-child),
.bi-pop-page .bi-pop-pad--form:has(> .bi-pop-clist:last-child),
.bi-pop-page .bi-pop-pad--form:has(> .bi-pop-tbl-body:last-child){ padding-bottom: 0; }
.bi-pop-page .bi-pop-list-foot ~ *:last-child{ margin-bottom: 0; }
.bi-pop-page .bi-pop-note:last-of-type:not(:only-child){ margin-bottom: 0; }
.bi-pop-page .bi-pop-clist ~ .bi-pop-list-foot,
.bi-pop-page .bi-pop-tbl-body ~ .bi-pop-list-foot,
.bi-pop-page .bi-pop-clist ~ .bi-pop-foot-btns,
.bi-pop-page .bi-pop-prod-ul ~ .bi-pop-foot-btns,
.bi-pop-pay--fill .bi-pop-list-foot,
.bi-pop-pay--list .bi-pop-list-foot{ margin-top: 0; }

/* 셀렉트 화살표 — 보드는 옅은 홑화살표다. 브라우저 기본 화살표는 굵고 색이 진해 규격과 다르게 보인다. */
.bi-pop-page .bi-pop-f select{
    appearance: none; -webkit-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'><path d='M2.5 4.5L6 8l3.5-3.5' fill='none' stroke='%239CA3AF' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>");
    background-repeat: no-repeat; background-position: right var(--space-3) center;
    padding-right: var(--space-8);   /* 화살표 자리 */
}

/* 결제 팝업 레거시 라벨/본문 → 보드 §08 값 (2026-08-26) */
.bi-pop-page .bi-pop-card-label{ display: block; margin: 0 0 var(--pop-f-gap); font-size: var(--pop-cnt-fs); font-weight: var(--fw-bold); color: var(--txt-secondary); line-height: 18px; }
.bi-pop-page .bi-pop-card-body{ margin-bottom: var(--space-3); }
.bi-pop-page .bi-pop-card-body input[type="text"], .bi-pop-page .bi-pop-card-body select{
    height: var(--pop-field-h); border-radius: var(--pop-field-r); font-size: var(--pop-f-fs);
}
/* 홀로 놓인 폼 칸도 줄 간격을 지킨다 */
.bi-pop-pad--form > .bi-pop-f{ margin-bottom: var(--space-3); }
/* ⚠ 2026-10-02 — 위 규칙은 .bi-pop-pad--form 의 «직계» 자식만 잡는다. <form> 이 사이에 끼면(신규고객·거래처등록·정산) 항목 사이가 0 이라
   라벨이 앞 입력칸에 붙었다(L3 캡처에서 발견). <form class="bi-pop-stack"> 의 직계 .bi-pop-f 에 같은 12px 를 준다. 마지막 항목은 제 여백을 따른다. */
.bi-pop-stack > .bi-pop-f:not(:last-of-type){ margin-bottom: var(--space-3); }
.bi-pop-stack > .bi-pop-f:has(+ .bi-pop-list-foot){ margin-bottom: 0; }
/* ⚠ 2026-10-06 — 체크 줄(.bi-pop-check)·옵션 줄(.bi-pop-opts) 바로 뒤의 입력 항목이 앞 줄에 붙었다
   (카드 승인취소: «카드취소 정보를 수기로 등록합니다» ↔ «결제일자» 간격 0 · 현금 승인취소: 라디오 줄 ↔ «결제일자» ~0).
   눈 검수에서 두 번 지적됐고 DOM 으로 0px 를 확인했다. 형제 선택자로 12px 만 더한다 — 기존 규칙은 고치지 않는다. */
.bi-pop-check + .bi-pop-f, .bi-pop-check + .bi-pop-form2, .bi-pop-opts + .bi-pop-f, .bi-pop-opts + .bi-pop-form2 { margin-top: var(--space-3); }   /* 푸터 바로 앞 항목은 푸터가 제 여백을 준다 */
/* ══ 선불권 결제 — 카드행 2줄로 옮긴 뒤의 정돈 (2026-08-27) ═══════════════
 * 목록이 6열 표에서 카드행으로 바뀌면서 표 시절의 선·폭 규칙이 남아 겹쳐 보였다. */
/* 목록을 감싼 divider 의 아래선 + 마지막 행의 아래선 = 두 줄. 목록이 스스로 긋는다. */
.bi-pop-pay--prepay .bi-paypop__divider{ border-bottom: 0; }
/* 선불권 행은 «고르는» 행이 아니다 — 만료일 순으로 전부 자동 차감된다. 손가락 커서·hover 를 끈다. */
.bi-pop-pay--prepay .bi-pop-clist-item{ cursor: default; }
.bi-pop-pay--prepay .bi-pop-clist-item:hover{ background: var(--bg-card); }
/* 오른쪽 금액 두 줄(남은금액 / 충전금액) — 아래줄은 본문 보조줄과 같은 리듬 */
.bi-pop-pay--prepay .bi-pop-clist-meta > div + div{ font-weight: var(--fw-medium); color: var(--txt-muted); line-height: 1.5; }
/* 카드행은 팝업 좌우 끝까지 간다 — 본문 여백만큼 되돌린다(보드 §08). */
.bi-pop-pay--prepay .bi-pop-clist{
    margin-left: calc(var(--pop-head-pad-x) * -1); margin-right: calc(var(--pop-head-pad-x) * -1);
}
/* 금액 두 줄은 라벨·값 규격을 따른다 — 옛 15px/18px 은 카드행 13px 옆에서 혼자 컸다. */

/* 본문 좌우 여백은 폼과 같은 18 — .bi-pop-pad 기본값(10)이 헤더와 어긋났다. */
.bi-pop-pay--prepay .bi-pop-pad{ padding-left: var(--pop-head-pad-x); padding-right: var(--pop-head-pad-x); padding-top: 0; }
.bi-pop-pay--prepay .pop_desc{ padding-top: var(--space-3); }
/* 금액 두 줄은 .bi-pop-pad 밖(form 직속)이라 좌우 여백이 없어 벽에 붙었다(2026-08-27). */
.bi-pop-pay--prepay .bi-pop-prepay-amt{ padding-left: var(--pop-head-pad-x); padding-right: var(--pop-head-pad-x); }
/* 목록 끝과 금액줄 사이 — 목록 마지막 행 선 + 금액줄 윗선이 나란히 두 줄로 보였다. 위쪽 하나만 남긴다. */
.bi-pop-pay--prepay .bi-pop-clist-item:last-child{ border-bottom: 0; }

/* ══ 예약일시 선택(bk_datetime) — 넓은 폼 3분할 (2026-08-27) ═══════════
 * 규격안대로: 폭은 폼형(720)을 쓰고, 날짜·시작시간·종료시간을 **한 줄에 셋**.
 * 고정 폭(280×3=840)이 720 을 넘겨 마지막 칸이 밀려 나가 있었다. */
/* 세로로 쌓는 묶음 — 결제 일시 · 디자이너 이름/직급 */
.bi-pop-pay--dt,
.bi-bk2-emp__l{ display: flex; flex-direction: column; }
/* ⚠ 푸터 아래 «14px» 의 정체 (2026-08-31) — 자유공간이 아니었다.
 * 공통 `.bi-pop-pay::after{content:'';display:table}` 는 float 시절의 클리어픽스인데,
 * 뿌리가 flex 가 되면서 **높이 0 짜리 flex 항목**이 됐다. 그 앞의 `gap:14px` 가
 * 푸터 뒤에 그대로 찍힌 것. 그래서 margin-top:auto 를 줘도(57px 로 먹고 있었다) 14 가 남았다.
 * 공통 규칙은 다른 팝업이 쓰므로 건드리지 않고 이 팝업에서만 항목에서 뺀다. */
.bi-pop-pay--dt::after{ display: none; }
.bi-pop-pay--dt .bi-pop-pad--dtgrid{
    display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--space-3);
    align-items: start; min-height: 0;
}
/* ⚠ 2026-08-31 — 여기 `max-height:352px; overflow-y:auto` 가 있었다.
 * 그래서 팝업 높이를 550→620 으로 키워도 칸은 350 에 머물고 «넘침 53» 이 그대로였다
 * (사용자: "스크롤이 생기는데 스크롤 안생기게 팝업 크기를 키워줘").
 * 칸은 격자 줄을 채우고, 팝업 높이가 가장 긴 칸을 담는다 — 자르는 쪽이 아니라 담는 쪽. */
.bi-pop-pay--dt .bi-pop-picker__col{
    width: auto; min-width: 0; height: auto; max-height: none; overflow: visible;
    border: 1px solid var(--pop-line); border-radius: var(--radius-xl); padding: var(--space-3);
}
/* 회색 머리띠 → 규격 라벨(12/700) — 보드에 «색 띠 머리» 는 없다 */
.bi-pop-pay--dt .bi-pop-picker__head{
    display: flex; flex-direction: column; gap: var(--pop-f-gap);
    margin: 0 0 var(--space-3); padding: 0; background: none; border: 0;
}
.bi-pop-pay--dt .bi-pop-picker__head > div:first-child{
    width: auto; padding: 0; white-space: nowrap;          /* 「예약 날짜」가 두 줄로 깨지던 것 */
    font-size: var(--pop-cnt-fs); font-weight: var(--fw-bold); color: var(--txt-secondary); line-height: 18px;
}
/* 오전·오후 = 섹션 소제목 (보드 .fsec) */
.bi-pop-pay--dt .bi-pop-picker__nav,
.bi-pop-pay--dt .bi-pop-picker__nav--tall{
    height: auto; margin: var(--space-3) 0 var(--space-2); padding: 0;
    font-size: var(--fs-xs); font-weight: var(--fw-extrabold); letter-spacing: .08em; color: var(--txt-disabled);
    background: none; border: 0; writing-mode: horizontal-tb;
}
.bi-pop-pay--dt .bi-pop-picker__sec:first-of-type .bi-pop-picker__nav{ margin-top: 0; }
/* 필수표시 * — 규격안은 빨강. 공통 `.bi-req` 는 `.bi-pop-f > label` 안에서만 색이 붙어
   여기(칸 머리의 평범한 div)에서는 검정으로 나왔다(2026-08-31). */
.bi-pop-pay--dt .bi-pop-picker__head .bi-req{ color: var(--color-danger); margin-left: var(--space-0_5); }
/* 안내문은 격자 위에 한 줄 — 규격안에 있던 것이 빠져 있었다(2026-08-28) */
.bi-pop-pay--dt .bi-pop-note--dt{ padding: 0 var(--pop-head-pad-x); margin: 0 0 var(--space-3); }
/* 고른 시간칩은 navy — 규격안대로. 지난 시간은 흐리게. */
/* ⚠ 2026-08-31 — 여기에 `.t_butn2.active` 가 빠져 있었다.
   시작시간은 .t_butn, 종료시간은 .t_butn2 다. 그래서 시작은 navy, 종료는 앞 규칙의 파랑으로
   «둘의 색이 서로 달랐다»(사용자 지적). 규격안은 고른 시간칩이 둘 다 navy 다. */
.bi-pop-pay--dt .t_butn.active,
.bi-pop-pay--dt .t_butn2.active{ background: var(--brand-navy); border-color: var(--brand-navy); color: var(--white); font-weight: var(--fw-extrabold); }
.bi-pop-pay--dt .t_butn:disabled,
.bi-pop-pay--dt .t_butn.is-past{ color: var(--gray-300); background: var(--bg-input); cursor: not-allowed; }
/* 시간칩 — 폭을 1000 으로 넓혔으니 한 줄에 5개(2026-08-28 규격안 확정).
   720 에서 4열일 때 «갑갑하다» 는 지적이었다. */
.bi-pop-pay--dt .bi-pop-picker__list{
    display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--space-1_5); width: auto; height: auto;
}
.bi-pop-pay--dt .bi-pop-picker__list > *{ width: auto; margin: 0; }

/* ══ 문자·장문 전송(sms · lms) — 폰 미리보기 + 입력폼 2단 (2026-08-27) ══════
 * 사용자 지시: «기존처럼 휴대폰 미리보기와 입력 폼 내용이 일단 다 들어가게».
 * 지금은 폰 그림이 본문의 절반을 차지하고 폭 870 에 세로도 넘쳤다.
 * → 폰은 **왼쪽 고정 폭**으로 줄이고, 오른쪽에 폼을 규격 라벨·입력으로 세운다. */
.bi-pop-pay--msg .bi-pop-pad--msggrid{
    display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: var(--space-4); align-items: start;
}
/* ⚠ 옛 폰 목업은 배경 이미지 폭(gif)에 기대 «고정 폭» 이었다 — 격자 칸을 넘겨 가로 스크롤이 났다.
   칸 안으로 들어오게 하고, 이미지도 칸 폭을 따르게 한다(2026-08-27). */
.bi-pop-pay--msg .bi-pop-pad--msggrid img{ max-width: 100%; height: auto; display: block; }
.bi-pop-pay--msg .bi-pop-pad--msggrid *{ max-width: 100%; box-sizing: border-box; }
.bi-pop-pay--msg .bi-msgsend__list,
.bi-pop-pay--msg input[type="text"],
.bi-pop-pay--msg textarea{ width: 100%; }
.bi-pop-pay--msg .bi-msgsend__wrap{ display: contents; }   /* 옛 가로 배치 래퍼는 격자에 자리를 안 차지한다 */
/* ⚠ 래퍼만 contents 로 풀면 그 안의 <form> 이 블록이라 **격자가 통하지 않는다** —
   폼이 폰 아래로 흘러 한 줄이 됐다(2026-08-27 실측). form 도 함께 태운다. */
.bi-pop-pay--msg .bi-pop-pad--msggrid > form,
.bi-pop-pay--msg .bi-msgsend__wrap > form{ display: contents; }
/* 안내문은 두 칸에 걸친다 */
.bi-pop-pay--msg .bi-msgsend__notice{ grid-column: 1 / -1; margin-bottom: var(--space-3); }
.bi-pop-pay--msg .bi-msgprev-phone--aside{ width: auto; min-width: 0; }
.bi-pop-pay--msg .bi-msgprev-phone__body--a,
.bi-pop-pay--msg .bi-msgprev-phone__body--ph{ width: auto; min-width: 0; }
.bi-pop-pay--msg .bi-msgprev-phone__ta--sm{ width: 100%; box-sizing: border-box; }
.bi-pop-pay--msg .bi-msgprev-phone__top,
.bi-pop-pay--msg .bi-msgprev-phone__foot{ width: 100%; overflow: hidden; }
.bi-pop-pay--msg .bi-msgprev-phone__body--a,
.bi-pop-pay--msg .bi-msgprev-phone__body--ph,
.bi-pop-pay--msg .bi-msgprev-phone__body--add{ width: 100%; padding-left: 0; padding-right: 0; }
/* 폰과 폼 사이의 옛 «점선 연결선» — 격자에서는 자리만 먹는다 */
.bi-pop-pay--msg .bi-msgsend__mid{ display: none; }
.bi-pop-pay--msg .bi-msg-rpanel{ width: auto; min-width: 0; float: none; }
.bi-pop-pay--msg .bi-msgsend__recv,
.bi-pop-pay--msg .bi-msgsend__form{ width: auto; min-width: 0; }
/* 오른쪽 폼 — 규격 라벨(12/700)·입력(h36 r8) */
.bi-pop-pay--msg .edit_one.bi-strong,
.bi-pop-pay--msg .bi-msg-direct-label{
    font-size: var(--pop-cnt-fs); font-weight: var(--fw-bold); color: var(--txt-secondary);
    line-height: 18px; margin: 0 0 var(--pop-f-gap);
}
.bi-pop-pay--msg .bi-msgsend__list{ width: 100%; min-height: 92px; box-sizing: border-box; }
.bi-pop-pay--msg .bi-msg-direct-row{ display: flex; gap: var(--space-2); }
.bi-pop-pay--msg .bi-msg-direct-row > input[type=text]{ flex: 1 1 auto; min-width: 0; }
.bi-pop-pay--msg .bi-msg-direct-row > .bi-btn{ flex: 0 0 auto; height: var(--pop-field-h); }
/* 옛 «라벨로 그린 동그라미» — 네이티브 라디오/체크와 겹쳐 보인다 */
.bi-pop-pay--msg input[type=radio] + label[for],
.bi-pop-pay--msg input[type=checkbox] + label[for]{ display: none; }
.bi-pop-pay--msg input[type=radio],
.bi-pop-pay--msg input[type=checkbox]{
    appearance: auto; visibility: visible; display: inline-block;
    width: var(--pop-check); height: var(--pop-check); margin: 0 var(--space-1_5) 0 0; vertical-align: middle;
    accent-color: var(--brand-navy);
}

/* ══ 스타일 카탈로그(catalog) — 3단 유지 · 우측 미리보기+설명 (2026-08-27) ══
 * 사용자 지시: «기존처럼 3단이여야 하고 우측엔 미리보기와 설명이 나와야 한다».
 * 폭은 사진 콘솔이라 예외로 두되, **헤더 왼쪽이 화면 밖으로 잘려 제목이 안 보이던 것**을 고친다
 *   — 팝업 상자가 중앙에 안 잡혀 왼쪽으로 밀려 있었다(실측 2026-08-27). */
#style_catalog{ max-width: calc(100vw - 24px); }
.bi-pop-cat-wrap{ width: 100%; max-width: 100%; box-sizing: border-box; }
.bi-pop-cat .bi-catalog__body{ padding: 0 var(--pop-head-pad-x) var(--space-4); }
/* 우측 미리보기 — «사진을 고르면 크게» 자리에 설명이 함께 서게 */
.bi-pop-cat .bi-catalog__view{
    flex: 0 0 300px; min-width: 0; display: flex; flex-direction: column; gap: var(--space-3);
    border-left: 1px solid var(--pop-line); padding-left: var(--space-4); margin-left: var(--space-4);
}
/* 콘솔 카드의 보라·파랑 그라데이션은 규격에 없는 색이다 — 규격 카드로 */
.bi-pop-cat .bi-catalog__card{
    background: var(--bg-card); border: 1px solid var(--pop-line); border-radius: var(--radius-xl);
    padding: var(--space-3_5); margin-bottom: var(--space-2_5);
}
.bi-pop-cat .bi-catalog__card-h{
    font-size: var(--pop-cnt-fs); font-weight: var(--fw-bold); color: var(--txt-secondary);
    margin-bottom: var(--space-2);
}
/* 탭 — 보드 §08 탭 규격(회색 카드 안 흰 알약, 활성은 navy) */
.bi-pop-cat .bi-catalog__tabs{
    background: var(--gray-100); border: 1px solid var(--pop-line); border-radius: var(--radius-sm);
    padding: var(--space-2_5); gap: var(--space-1_5); margin-bottom: var(--space-3);
}
.bi-pop-cat .bi-catalog__tab{
    height: 32px; padding: 0 var(--space-4); border-radius: var(--radius-lg);
    background: var(--bg-card); border: 1px solid var(--pop-line); color: var(--txt-secondary);
    font-size: 12.5px; font-weight: var(--fw-extrabold);
}
.bi-pop-cat .bi-catalog__tab.is-active{ background: var(--brand-navy); border-color: var(--pop-tab-line); color: var(--white); }

/* ══════════════════════════════════════════════════════════════════════
   .bi-cat3 — 스타일 카탈로그 «규격안 3단» (2026-08-28)

   사용자 지시: 규격안대로 고친다. 기존 팝업 CSS 를 살리려 애쓰지 않는다.
   단 **공통 규칙은 손대지 않고 여기 새로 더한다** — 이미 끝낸 팝업이 함께 움직이면 안 된다.
   그래서 기존 `.bi-catalog__*` 선언은 그대로 두고, 이 클래스가 붙은 팝업 안에서만 덮는다.

   규격안: 좌 콘솔 220 · 중 갤러리 1fr · 우 미리보기 300
   ══════════════════════════════════════════════════════════════════════ */
/* ⚠ align-items:start 였다 — 세 칸이 «내용만큼만» 서서, 미리보기의 세로 구분선이
   본문 중간에서 끊겨 있었다(2026-08-31 캡처). 칸은 본문 높이를 채운다. */
.bi-cat3 .bi-catalog__body{
    display: grid; grid-template-columns: 220px minmax(0, 1fr) 300px;
    gap: var(--space-4); align-items: stretch; min-height: 0; flex: 1 1 auto;
}
/* 왼쪽 콘솔만 위에 붙인다 — 격자의 직계 자식이라 align-self 는 «세로» 로 작동한다.
   ⚠ .bi-catalog__content 에는 주면 안 된다. 그 부모(.bi-catalog__main)는 세로 flex 라
   같은 속성이 «가로» 로 작동해 사진 격자가 87px 로 눌렸다(2026-08-31 실측). */
.bi-cat3 > .bi-catalog__body > .bi-catalog__console{ align-self: start; }
/* 콘솔 카드 — 강조는 «테두리 색만». 좌측 굵은 막대는 보드에 없는 표현이라 쓰지 않는다(사용자 지적) */
.bi-cat3 .bi-catalog__console{ display: block; }
.bi-cat3 .bi-catalog__card{
    border: 1px solid var(--pop-line); border-radius: var(--radius-xl);
    background: var(--bg-card); padding: var(--space-3_5); box-shadow: none;
}
.bi-cat3 .bi-catalog__card + .bi-catalog__card{ margin-top: var(--space-2_5); }
.bi-cat3 .bi-catalog__card--ai{ border-color: var(--pop-sel); }
.bi-cat3 .bi-catalog__card--ai .bi-catalog__card-h{ color: var(--pop-sel); }
.bi-cat3 .bi-catalog__card-h{ font-size: var(--pop-cnt-fs); font-weight: var(--fw-bold); color: var(--txt-secondary); margin-bottom: var(--space-2); }
.bi-cat3 .bi-catalog__cbtn{ width: 100%; }
/* 갤러리 — 3열. 사진은 세로 3:4 */
.bi-cat3 .bi-catalog__content{ display: block; min-height: 0; }
.bi-cat3 .bi-catalog__grid{
    display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-2_5);
}
.bi-cat3 .bi-catalog__grid > *{ aspect-ratio: 3 / 4; }
/* 사진 추가 — 가운데 + 한 글자, 점선으로 «빈 자리» 를 알린다(규격안) */
.bi-cat3 .bi-cat3__add{
    display: flex; align-items: center; justify-content: center;
    border: 1px dashed var(--pop-line); border-radius: var(--radius-lg);
    background: var(--bg-card); color: var(--txt-disabled); font-size: 26px; font-weight: 300;
    line-height: 1; cursor: pointer;
}
.bi-cat3 .bi-cat3__add:hover{ border-color: var(--pop-sel); color: var(--pop-sel); }
/* 미리보기 — 세 번째 단. 경계선으로 나눈다 */
.bi-cat3 .bi-cat3__prev{
    border-left: 1px solid var(--pop-line); padding-left: var(--space-4);
    display: flex; flex-direction: column; gap: var(--space-2_5); min-height: 0;
}
.bi-cat3 .bi-cat3__prev-t{
    font-size: var(--fs-xs); font-weight: var(--fw-extrabold); letter-spacing: .08em; color: var(--txt-disabled);
}
.bi-cat3 .bi-catalog__view{ width: auto; min-height: 0; flex: 1 1 auto; overflow-y: auto; }
/* 빈 안내는 «격자 한 칸» 이 아니라 줄 전체를 쓴다 — 안 그러면 + 옆에 끼어 격자가 흐트러진다 */
.bi-cat3 .bi-catalog__grid > .bi-catalog__empty{ grid-column: 1 / -1; aspect-ratio: auto; padding: var(--space-6) 0; }
/* 미리보기 세로선은 이 단이 하나만 긋는다 — 안쪽 뷰의 테두리는 지운다(선이 두 겹으로 보였다) */
.bi-cat3 .bi-cat3__prev .bi-catalog__view{ border: 0; padding: 0; }

/* ══════════════════════════════════════════════════════════════════════
   .bi-msgspec — 문자·장문 전송 «규격안» (2026-08-28)

   사용자 지시: 규격안대로 고친다. 기존 팝업 CSS 를 살리려 애쓰지 않는다.
   단 공통 규칙은 손대지 않고 여기 새로 더한다 — 이미 끝낸 팝업이 함께 움직이면 안 된다.

   ⚠ 앞선 시도에서 «격자를 새로 얹어» 실패했다. 바깥 격자(.bi-pop-pad--msggrid)는
     이미 2단(210 / 나머지)이다. 여기서는 **격자를 만들지 않고** 안쪽 모양만 규격에 맞춘다.

   ⚠ textarea 가 둘인 것은 «남은 것» 이 아니다 — 90바이트를 넘으면 두 번째 칸으로 이어 쓴다
     (popup_layer_sms.1.js:196). 그래서 지우지 않고, 폰 안에서 **하나의 글상자처럼** 보이게 한다.
   ══════════════════════════════════════════════════════════════════════ */
/* 상자 = 헤더 + 본문(스크롤) + 푸터 — 푸터가 화면 밖으로 밀리지 않는다 */
.bi-msgspec{ display: flex; flex-direction: column; height: 100vh; box-sizing: border-box; padding-bottom: 0; }
.bi-msgspec > .bi-pop-pad{ flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.bi-msgspec > .bi-pop-list-foot{ flex: 0 0 auto; margin-top: 0; }

/* 안내문 — 규격 안내문 모양(옛 회색 상자 대신) */
.bi-msgspec .bi-msgsend__notice{
    background: none; border: 0; padding: 0; margin: 0 0 var(--space-3);
    font-size: var(--pop-cnt-fs); color: var(--txt-muted); line-height: 1.6;
}
/* 폰 — 둥근 카드 하나. 두 글상자는 이어진 하나처럼 보이게 한다. */
.bi-msgspec .bi-msgprev-phone--aside{ width: auto; max-width: 100%; }
.bi-msgspec .bi-msgprev-phone__body--a,
.bi-msgspec .bi-msgprev-phone__body--ph{
    width: auto; background: none; border: 0; padding: 0; margin: 0;
}
.bi-msgspec .bi-msgprev-phone__body--add{ width: auto; padding: 0; }
.bi-msgspec .bi-msgprev-phone__ta--sm{
    width: 100%; box-sizing: border-box; min-height: 132px; resize: vertical;
    border: 1px solid var(--pop-line); border-radius: var(--radius-xl); background: var(--bg-card);
    padding: var(--space-2_5) var(--space-3); margin: 0;
    font-size: var(--pop-f-fs); line-height: 1.6; color: var(--txt-primary); font-family: var(--font-sans);
}
.bi-msgspec .bi-msgprev-phone__body--ph .bi-msgprev-phone__ta--sm{ min-height: 92px; margin-top: var(--space-2); }
/* 글자수 — 글상자 오른쪽 아래에 작게 */
.bi-msgspec .bi-msgprev-phone__size--sm{
    display: block; width: auto; text-align: right; margin: var(--space-1) 0 0;
    font-size: var(--fs-2xs); color: var(--txt-muted); background: none; border: 0; padding: 0;
}
/* ══ 폰 미리보기 — 규격안 .ph2 (2026-08-31) ════════════════════════════
 * 사용자: "sms, lms 는 휴대폰 이미지 부분이 규격안대로 안됬어".
 * 지금까지는 «GIF 를 뺀 밋밋한 글상자» 였다. 규격안은 폰 카드다 —
 * 이어피스 · 브랜드 라벨 · 흰 화면 · 화면 안 말풍선 · 바닥에 글자수 한 번.
 * ⚠ 이름을 새로 판다(.bi-msgphone*). 기존 .bi-msgprev-phone* 는 다른 화면도 쓰므로 그대로 둔다. */
.bi-msgspec .bi-msgphone{
    border: 1px solid var(--pop-line); border-radius: var(--radius-2xl);
    background: var(--bg-input); padding: var(--space-2_5) var(--space-2_5) var(--space-3_5);
    box-sizing: border-box;
}
.bi-msgspec .bi-msgphone__ear{
    width: 52px; height: 5px; border-radius: var(--radius-full);
    background: var(--gray-300); margin: 0 auto var(--space-2);
}
.bi-msgspec .bi-msgphone__brand{
    text-align: center; font-size: var(--fs-2xs); font-weight: var(--fw-extrabold);
    color: var(--txt-muted); margin-bottom: var(--space-2);
}
/* ⚠ 폰 화면 높이는 sms·lms 가 «같다» (2026-08-31 사용자 지시: "sms 휴대폰 이미지 크기를 lms와 같게").
   전에는 lms 의 textarea rows=19 가 높이를 정해 sms(270) 와 lms(403) 가 달랐다.
   → 화면 높이를 여기서 못박고, 글상자는 그 안을 채운다. rows 는 더 이상 크기를 정하지 않는다. */
.bi-msgspec .bi-msgphone__scr{
    background: var(--bg-card); border: 1px solid var(--pop-line); border-radius: var(--radius-xl);
    height: 343px; padding: var(--space-2_5);
    display: flex; flex-direction: column; gap: var(--space-2);
}
/* 말풍선이 화면을 채운다 — 이어쓰기 칸이 드러나면 둘이 나눠 갖는다(화면 높이는 그대로) */
.bi-msgspec .bi-msgphone__bub{ display: flex; flex: 1 1 auto; min-height: 0; }
.bi-msgspec .bi-msgphone__ta{ flex: 1 1 auto; height: 100%; }
/* 말풍선 — 왼쪽 아래 모서리만 각지게(규격 12/12/12/3) */
.bi-msgspec .bi-msgphone__bub{
    background: var(--bg-input); border-radius: var(--radius-xl) var(--radius-xl) var(--radius-xl) 3px;
    padding: var(--space-2) var(--space-2_5); max-width: 88%;
}
/* 말풍선 «안» 의 입력칸 — 테두리·배경 없이 글만 (말풍선이 곧 상자다) */
.bi-msgspec .bi-msgphone__ta{
    width: 100%; box-sizing: border-box; min-height: 0; resize: none;
    border: 0; border-radius: 0; background: none; padding: 0; margin: 0;
    font-size: var(--pop-cnt-fs); line-height: 1.6; color: var(--txt-secondary);
    font-family: var(--font-sans); outline: none;
}
/* 글자수 — 화면 바닥 오른쪽에 한 번 */
.bi-msgspec .bi-msgphone__cnt{
    margin-top: auto; text-align: right;
    font-size: var(--fs-2xs); color: var(--txt-muted);
}
.bi-msgspec .bi-msgphone__cnt2{ margin-left: var(--space-2); }
/* 이어쓰기 칸은 «쓰였을 때만» 보인다 — 비어 있으면 말풍선도 글자수도 접는다.
   (빈 칸일 때 placeholder 가 보이는 것을 신호로 쓴다) */
.bi-msgspec .bi-msgphone__scr:has(#inputsms2:placeholder-shown) .bi-msgphone__bub--cont,
.bi-msgspec .bi-msgphone__scr:has(#inputsms2:placeholder-shown) .bi-msgphone__cnt2{ display: none; }
/* 가운데 점·세로선 장식은 규격에 없다 */
.bi-msgspec .bi-msgsend__mid{ display: none; }
/* 오른쪽 폼 — 칸을 꽉 쓴다 */
.bi-msgspec .bi-msg-rpanel{ width: auto; min-width: 0; }
.bi-msgspec .bi-msgsend__recv,
.bi-msgspec .bi-msgsend__form{ width: auto; min-width: 0; }
/* 폼 줄간격 16 → 12 (2026-08-31). 팝업은 창 높이에 잘리므로 내용을 줄여야 스크롤이 없어진다.
   .bi-col--gap-16 은 공통이라 값을 고치지 않고, 이 팝업 안에서만 덮는다. */
.bi-msgspec .bi-msgsend__form.bi-col--gap-16{ gap: var(--space-2_5); }
/* 전송시각 — 날짜·시·분 한 줄. 날짜가 남는 폭을 갖고 시·분은 제 폭만 쓴다. */
.bi-msgspec .bi-msgsend__when{ align-items: center; flex-wrap: nowrap; font-size: var(--pop-cnt-fs); color: var(--txt-secondary); }
.bi-msgspec .bi-msgsend__when > input[type=text]{ flex: 1 1 auto; min-width: 0; }
.bi-msgspec .bi-msgsend__when > select{ flex: 0 0 auto; }

/* 2026-09-11 A19-5 — 「내용 입력란 width 수정」(사용자).
 * 폰 칸이 210px 이라 말풍선(max-width 88%) 안 글상자가 **126px** 까지 줄어들었다(실측).
 * 폰 칸을 260 으로 넓히고 말풍선도 칸을 거의 다 쓰게 한다 — 오른쪽 폼은 minmax(0,1fr) 이라 같이 줄어도 안 깨진다.
 * 폭만 바꿈 — 폰 화면 높이(343)는 sms·lms 가 같아야 하므로(2026-08-31 지시) 건들지 않는다. */
.bi-pop-pay--msg .bi-pop-pad--msggrid{ grid-template-columns: 260px minmax(0, 1fr); }
.bi-msgspec .bi-msgphone__bub{ max-width: 96%; }

/* 2026-09-11 A19-6 — 「시·분」 세로 위치는 CSS 없이 마크업에서 끝냈다.
 * 맨문자 단위가 뒤따르는 `&nbsp;` 공백과 한 덩어리(익명 flex 항목)로 묶여 두 줄로 접혀
 * 글자가 첫 줄에 앚았던 것 — 그 공백만 없앱다(popup_layer_{sms,lms}.php).
 * 새 클래스를 두지 않는다 — 규격(styleguide2)에 전시할 것이 아니고, QC SPEC-REWORK 가 미등록을 막는다. */
/* 라벨 — 규격 12/700 */
.bi-msgspec .edit_one > b,
.bi-msgspec .edit_one.bi-strong,
.bi-msgspec .bi-msg-direct-label{
    font-size: var(--pop-cnt-fs); font-weight: var(--fw-bold); color: var(--txt-secondary); line-height: 18px;
}
/* 수신자 목록 — 최대 1,000명. 목록 «안에서» 스크롤해 팝업이 길어지지 않게 한다(규격안) */
.bi-msgspec .bi-msgsend__list{
    /* 최대높이 132 → 104 (2026-08-31): 목록은 어차피 «안에서» 스크롤한다.
       바깥(.bi-pop-pad)에 스크롤이 생기지 않게 하는 쪽이 우선이다. */
    width: 100%; box-sizing: border-box; height: auto; min-height: 80px; max-height: 96px; overflow-y: auto;
    border: 1px solid var(--pop-line); border-radius: var(--radius-lg); background: var(--bg-card);
    font-size: var(--pop-cnt-fs); padding: var(--space-1);
}
/* 옛 폰 목업의 «배경 이미지»(bgPhoneBody.gif·bgSmsInputAdd.gif)가 검은 테두리로 남아 있었다.
   규격안의 폰은 그림이 아니라 둥근 카드다 — 배경과 고정 높이를 걷는다. */
.bi-msgspec .bi-msgprev-phone__body--ph,
.bi-msgspec .bi-msgprev-phone__body--add{
    background-image: none; height: auto; padding-top: 0; text-align: left;
}

/* ══════════════════════════════════════════════════════════════════════
 * §41  write 팝업 — 입력화면을 팝업으로 (2026-08-28)
 * ══════════════════════════════════════════════════════════════════════
 * 규격: renew_crm/write_pop.html.  나머지는 §40 팝업 규격(.bi-pop-form2 ·
 * .bi-pop-f · .bi-pop-fsec · .bi-pop-foot-btns)을 **그대로** 쓴다.
 * 여기 있는 것은 그 규격에 «없어서» 옮길 수 없던 것 8가지뿐 — 새 색·새 토큰 0.
 * ⚠ 기존 클래스를 고치지 않는다(CLAUDE.md §4). 전부 신규 이름이다. */

/* ① 2열 격자에서 한 줄을 다 쓰는 칸 — 메모·주소·이메일처럼 값이 긴 것.
 *    (기존 .bi-pop-form-full 은 .bi-pop-pay 스코프 전용이라 폼 격자에서 안 먹는다) */
.bi-pop-f--full{ grid-column: 1 / -1; }

/* ② 주소 3열 — 우편번호 / 주소 / 상세주소.
 *    .bi-pop-form3 는 «균등» 3열이라 우편번호가 주소만큼 넓어진다. */
.bi-pop-page .bi-pop-faddr{ display: grid; grid-template-columns: 150px 1fr 200px; gap: var(--space-2); }
@media (max-width: 640px){ .bi-pop-page .bi-pop-faddr{ grid-template-columns: 1fr; } }

/* ③ 라벨 옆에 버튼이 붙는 줄 — 주소검색.
 *    버튼을 «필드» 옆에 두면 3열이 4열이 되어 주소칸이 좁아진다. */
.bi-pop-page .bi-pop-flabel-row{ display: flex; align-items: center; gap: var(--space-2); }
.bi-pop-page .bi-pop-flabel-row > label{ flex: 0 0 auto; }
.bi-pop-page .bi-pop-flabel-row > .bi-btn{ height: var(--pop-btn-sm-h); font-size: var(--pop-btn-sm-fs); padding: 0 var(--pop-pill-pad-x); }

/* ④ 라벨 옆 힌트 — 별도 줄로 내리면 칸 높이가 줄마다 달라진다. */
.bi-pop-page .bi-pop-fhint{ margin-left: var(--space-1_5); font-size: var(--fs-xs); font-weight: var(--fw-semibold); color: var(--txt-muted); }

/* ⑤ 팝업 안 여러 줄 입력 — 팝업은 페이지보다 낮다.
 *    .bi-write-textarea 는 «고정» h100, 폼 공통 textarea 는 min 96. 팝업 규격은 74. */
.bi-pop-page .bi-pop-f textarea.bi-pop-ftx{ min-height: 74px; height: auto; }

/* ⑥ 파일 선택 — 브라우저 기본 모양은 높이·글꼴이 규격 밖이라 그 줄만 튄다. */
.bi-pop-page .bi-pop-ffile{ display: flex; align-items: center; gap: var(--space-2); height: var(--pop-field-h); }
.bi-pop-page .bi-pop-ffile > input[type="file"]{ position: absolute; width: 0; height: 0; padding: 0; opacity: 0; overflow: hidden; border: 0; }
.bi-pop-page .bi-pop-ffile > label.bi-btn{ flex: 0 0 auto; height: var(--pop-btn-sm-h); font-size: var(--pop-btn-sm-fs); padding: 0 var(--pop-pill-pad-x); cursor: pointer; }
.bi-pop-page .bi-pop-ffile > .bi-pop-ffile__name{ font-size: var(--pop-cnt-fs); color: var(--txt-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

/* ⑦ 라디오·체크 한 줄 — 입력칸과 «같은 높이» 라야 옆 칸과 밑선이 맞는다. */
.bi-pop-page .bi-pop-finline{ display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-1) var(--space-4); min-height: var(--pop-field-h); }
.bi-pop-page .bi-pop-finline > label{ display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--pop-f-fs); color: var(--txt-secondary); cursor: pointer; margin: 0; font-weight: var(--fw-normal); }
.bi-pop-page .bi-pop-finline input[type="radio"], .bi-pop-page .bi-pop-finline input[type="checkbox"]{
    width: var(--pop-check); height: var(--pop-check); margin: 0; flex: 0 0 auto; }
.bi-pop-page .bi-pop-finline input[type="radio"]{ accent-color: var(--brand-navy); }
.bi-pop-page .bi-pop-finline input[type="checkbox"]{ accent-color: var(--pop-sel); }

/* ⑧ 폼 본문 — 긴 폼은 **본문만** 스크롤한다. 머리·발은 붙어 있어야
 *    26항목짜리(상품)에서도 저장 버튼을 찾으러 스크롤할 일이 없다. */
.bi-pop-page .bi-pop-wbody{ padding-bottom: var(--space-4); }
/* ⚠ 어느 폼이 넘칠지는 «화면 높이» 가 정한다 — 모듈을 보고 미리 고를 수 없다.
 *   (실측: pay_init 19항목 = 1026px 로 화면 밖 106px. 같은 폼도 낮은 화면에선 더 넘친다)
 *   max-height 는 짧은 폼을 늘리지 않으므로 규격이 늘 갖는다. 머리·발은 밖에 있어 고정된다.
 * ⚠ vh 를 쓰면 «안 된다» — 팝업은 iframe 이라 iframe 안에서 1vh 는 «팝업 높이» 다.
 *   팝업 높이는 다시 내용 높이로 정해지므로 되먹임이 생겨 모든 팝업이 268px 로 오그라들었다
 *   (2026-08-28 실측). 화면이 아니라 «상자» 를 기준으로 재는 값이어야 한다 → 고정 560px.
 *   56(머리)+560+59(발) = 675 → 700px 화면까지 저장 버튼이 보인다. */
/* 560 은 «부모 창을 못 읽을 때» 의 안전값이다. 실제 값은 popup_layer_write.js 가
   부모 창 높이에서 머리·발·여백을 빼 --pop-wbody-max 로 넘긴다(브릿지 변수, §4).
   ⚠ 여기에 vh 를 쓰면 안 된다 — iframe 안에서 1vh 는 «팝업 높이» 라 되먹임이 생긴다. */
.bi-pop-page .bi-pop-wbody{ max-height: var(--pop-wbody-max, 560px); overflow-y: auto; overscroll-behavior: contain; }
/* 스크롤바가 생기면 오른쪽 칸이 눌린다 — 그만큼만 비운다 */
.bi-pop-page .bi-pop-wbody{ padding-right: var(--space-1); margin-right: calc(var(--space-1) * -1); }

/* 푸터 — 팝업 벽까지 닿는 띠. 기존 `.bi-pop-reg .bi-pop-foot-btns` 는 --pop-pad-x(22)로
   뚫는데 본문 여백은 --pop-head-pad-x(18)라 좌우로 4px 씩 넘친다.
   기존 규칙을 고치는 대신(§4) write 폼에서만 여백과 같은 값으로 다시 못박는다. */
.bi-pop-page .bi-popwrite .bi-pop-foot-btns{
    margin: 0 calc(-1 * var(--pop-head-pad-x)) 0;
    width: calc(100% + var(--pop-head-pad-x) * 2);
}
/* 페이지 셸(메뉴로 직접 여는 환경설정·내정보관리)에서는 뚫지 않는다 — 벽이 없다 */
.bi-write-page .bi-popwrite .bi-pop-foot-btns{ margin: 0; width: 100%; }
/* 규격 §04 — 구획이 하나뿐이면 소제목을 쓰지 않는다. 첫 격자는 위 여백이 없다. */
.bi-pop-page .bi-popwrite .bi-pop-wbody > .bi-pop-form2:first-child{ margin-top: 0; }
.bi-pop-page .bi-popwrite .bi-pop-form2:last-child{ margin-bottom: 0; }

/* 단위 표기(원 · % · 회) — 입력칸 옆에 붙는 짧은 글. 규격 §05 «숫자는 오른쪽» 과 한 벌이다. */
.bi-pop-page .bi-pop-funit{ font-size: var(--pop-cnt-fs); color: var(--txt-muted); flex: 0 0 auto; white-space: nowrap; }
/* 한 줄 안의 짧은 입력 — 폼 공통 규칙이 width:100% 를 주므로 여기서만 되돌린다.
   («기본적용 비율 [30] %» 처럼 칸이 값보다 커지면 무엇을 넣는 칸인지 흐려진다) */
.bi-pop-page .bi-pop-finline input[type="text"], .bi-pop-page .bi-pop-finline input[type="number"]{ width: auto; min-width: 0; }
.bi-pop-page .bi-pop-finline input.bi-write-input--xs{ width: 68px; }
.bi-pop-page .bi-pop-finline input.bi-write-input--sm{ width: 118px; }
.bi-pop-page .bi-pop-finline input.bi-write-input--md{ width: 160px; }
/* 구획선은 격자 한 줄을 «다» 쓴다 — 한 칸만 차지하면 옆 칸이 소제목 오른쪽으로 올라붙는다
   (pay_ref 실측 2026-08-28: 「구간별 지급율」 옆에 «가.구간» 이 붙어 있었다). */
.bi-pop-page .bi-popwrite .bi-pop-form2 > .bi-pop-fsec,
.bi-pop-page .bi-popwrite .bi-pop-form3 > .bi-pop-fsec,
.bi-pop-page .bi-popwrite .bi-pop-form4 > .bi-pop-fsec{ grid-column: 1 / -1; }
/* 줄 끊기 — 「이 항목은 반 칸 크기 그대로 «혼자» 둔다」 (2026-09-01 고객등록 휴대폰번호).
   빈 칸이 옆자리를 차지해 다음 항목이 새 줄에서 시작한다. --full 로 늘리면 입력칸까지 넓어져
   «크기는 그대로, 줄만 끊는다» 가 안 된다. 높이 0 이라 줄 간격에 영향을 주지 않는다. */
.bi-pop-page .bi-popwrite .bi-pop-f--spacer{ min-height: 0; padding: 0; border: 0; }
/* ⚠ 전역 `input[type=checkbox]{visibility:hidden;display:none}`(옛 스프라이트 +label 방식) 때문에
   폼 안 체크박스가 «보이지 않는다». 라디오는 살아 있어 눈으로 대조하기 전에는 못 잡는다
   (product_category 실측 2026-08-28: 「하위 일괄 적용」 앞이 비어 있었다). 여기서 되살린다. */
.bi-pop-page .bi-pop-finline input[type="checkbox"],
.bi-pop-page .bi-pop-finline input[type="radio"]{
    visibility: visible; display: inline-block;
    -webkit-appearance: auto; -moz-appearance: auto; appearance: auto;
}

/* ⚠ 팝업 안에서는 `.bi-pop-reg *{box-sizing:border-box}` 가 걸리는데, 같은 폼이 **페이지 셸**로
   뜰 때는 그 조상이 없어 옛 content-box 규칙이 이긴다. 그러면 height:36 인 버튼이 테두리 2를
   더해 **38** 로 그려진다(page=write 실측 2026-08-28) — 같은 마크업인데 화면마다 값이 달라진다.
   폼 스코프에서 한 번 못박아 두 셸의 눈금을 맞춘다. */
.bi-popwrite, .bi-popwrite *{ box-sizing: border-box; }

/* ── 문자 미리보기 폰 목업 — 그림 대신 규격으로 (2026-08-31) ──────────────
 * 규격: renew_crm/write_pop.html §06 «미리보기»
 * 왜 GIF 를 걷어내나:
 *   ① 이미지의 색·라운드는 토큰 밖이고 확대하면 흐려진다(bgPhoneTops/Bottoms/bgSmsInputB 3장).
 *   ② 「SMS」 글자가 **그림에 박혀 있다.** 이 화면의 최대 길이는 2000바이트(LMS)인데
 *      캡션은 언제나 SMS 였다 — 화면이 거짓말을 하고 있었다.
 *   ③ 3장을 이어 붙인 상자라 높이가 53+323+56 로 고정이고 팝업 안에서 줄일 수 없다.
 * ⚠ 카카오 알림톡 말풍선(.bi-msgprev-talk*)은 **건드리지 않는다** — 그건 카카오 규격이다. */
.bi-pop-page .bi-pop-phone{
    width: 250px; max-width: 100%; box-sizing: border-box;
    border: 1px solid var(--border-base); border-radius: var(--radius-2xl, 16px);
    background: var(--bg-card); padding: var(--space-3_5) var(--space-3_5) var(--space-5);
    display: flex; flex-direction: column;
}
/* 스피커 슬릿 — 그림에 있던 것을 그대로 옮긴 형태다 */
.bi-pop-page .bi-pop-phone__bar{
    width: 56px; height: 5px; border-radius: var(--radius-full); background: var(--gray-300); margin: 0 auto;
}
/* 캡션은 **바이트 수가 정한다** — 90 이하 SMS · 넘으면 LMS */
.bi-pop-page .bi-pop-phone__cap{
    margin-top: var(--space-2); text-align: center;
    font-size: var(--fs-sm); font-weight: var(--fw-bold); letter-spacing: .08em; color: var(--txt-muted);
}
.bi-pop-page .bi-pop-phone__screen{
    margin-top: var(--space-3); padding-top: var(--space-2_5);
    border-top: 1px solid var(--border-light); display: flex; flex-direction: column;
}
.bi-pop-page .bi-pop-phone__ta{
    width: 100%; height: 280px; border: 0; outline: none; resize: none; background: transparent;
    padding: 0; font-family: var(--font-sans); font-size: var(--fs-sm); line-height: 1.6;
    color: var(--txt-primary); box-sizing: border-box;
}
.bi-pop-page .bi-pop-phone__size{
    margin-top: var(--space-2); text-align: right; font-size: var(--fs-xs); color: var(--txt-disabled);
    font-variant-numeric: tabular-nums;
}

/* ⚠ 감춤이 새고 있었다 — 실측 2026-08-31, 18화면 중 **6화면**.
 *   `.bi-hidden{display:none}` 은 (0,1,0) 이고 7393줄에 있다.
 *   규격 컴포넌트가 `.bi-pop-f{display:flex}`(10905줄, 같은 (0,1,0) 이지만 **뒤**) 나
 *   `.bi-pop-page .bi-pop-finline{display:flex}`((0,2,0)) 로 display 를 잡으면 감춤이 진다.
 *   증상: pay_edit 은 정산타입이 고정급인데도 구간 10줄이 다 보이고,
 *         branch 는 «환경설정 복사 대상 지점» 이 늘 보였다.
 *   («클래스를 붙였는데 안 감춰진다» 는 눈으로는 원래 보이는 칸과 구별이 안 된다 — 재야 안다)
 *   감춤은 무엇이든 이겨야 한다. !important 대신 폼 스코프로 특이도를 올려 못박는다. */
.bi-pop-page .bi-popwrite .bi-hidden,
.bi-pop-page .bi-popwrite.bi-hidden,
.bi-write-page .bi-popwrite .bi-hidden{ display: none; }
/* 카탈로그 푸터 — 「사진 삭제」는 왼쪽, 나머지는 오른쪽(규격안). .sp 가 밀어야 하는데
   이 팝업의 푸터는 flex 인데도 왼쪽 버튼이 붙지 않았다 — 첫 버튼을 직접 민다. */
.bi-cat3 > .bi-pop-list-foot{ justify-content: flex-start; }
.bi-cat3 > .bi-pop-list-foot > .sp{ flex: 1 1 auto; }

/* ① 라벨줄 안의 라벨도 «같은 글자» 여야 한다 — 실측 2026-08-31, 5화면 8개가 규격 밖이었다.
 *   공통 규칙 `.bi-pop-f > label` 은 **직계 자식만** 잡는다. 라벨 옆에 버튼을 붙이려고
 *   한 겹 감싼 순간(.bi-pop-flabel-row) 그 규칙이 빗나가 브라우저 기본값(16px/400)으로 떨어졌다.
 *   «주소» 만 글자가 크고 굵기가 다른데, 눈으로는 «좀 크네» 정도라 지나치기 쉽다.
 *   힌트·별표도 라벨의 자손이라 같이 놓쳤으므로 함께 못박는다. */
.bi-pop-page .bi-pop-flabel-row > label{
    font-size: var(--pop-cnt-fs); font-weight: var(--fw-bold);
    color: var(--txt-secondary); line-height: 18px;
}
.bi-pop-page .bi-pop-flabel-row > label .bi-req{ color: var(--color-danger); margin-left: var(--space-0_5); }

/* ③ 알림톡 미리보기를 **SMS/LMS 미리보기와 같은 크기**로 (2026-08-31 사용자 지적).
 *   말풍선은 내용만큼 자라던 터라, 긴 템플릿에서는 옆의 폰 목업보다 훨씬 길어져
 *   두 미리보기의 «키» 가 달랐다. 내용이 길면 **말풍선 안에서 스크롤**한다.
 * ⚠ 노란 머리·흰 말풍선(브랜드 형태)은 건드리지 않는다 — 크기만 맞춘다.
 *   그래서 .bi-msgprev-talk* 를 고치지 않고 write 폼 스코프에서만 덮는다(§4). */
.bi-pop-page .bi-popwrite .bi-msgprev-talk__ta{
    height: 327px;                    /* 폰 목업 전체 높이(391)에서 말풍선 머리·여백(64)을 뺀 값 — 실측으로 맞췄다 */
    overflow-y: auto; resize: none; box-sizing: border-box;
}

/* ── 예약일시 팝업 푸터 — 규격(높이 60) (2026-08-31) ──
   실측 79 였다. 왼쪽 안내문이 제 줄높이로 푸터를 키우고 있었다.
   규격 푸터는 «버튼 34 + 여백 13/12 = 60» 이다 — 안내문은 그 안에 한 줄로 앉는다.
   ⚠ 이 팝업에서만 쓰는 이름(.bi-dtfoot)으로 더한다 — 공통 푸터 규칙은 건드리지 않는다. */
/* ⚠ 뿌리가 세로 flex 라 푸터가 «늘어나고» 있었다(계산 높이 78.8 — 규격 60).
   푸터는 제 내용만큼만 차지한다. */
.bi-dtfoot{ align-items: center; flex: 0 0 auto;
    /* 규격 푸터 = 여백 13 + 버튼 34 + 여백 12 + 윗선 1 = 60.
       ⚠ 높이를 못박았더니 59 가 나왔다 — border-box 라 못박은 값 안에 윗선 1px 이 먹혔다.
       flex:0 0 auto 로 «늘어나지 않음» 은 이미 보장되니, 높이는 내용이 정하게 둔다(2026-08-31). */
    height: auto; }
.bi-dtfoot > .sp{ flex: 1 1 auto; }
.bi-dtfoot .bi-pop-foot-link{
    flex: 0 1 auto; min-width: 0; line-height: 18px; font-size: var(--pop-cnt-fs);
    color: var(--txt-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    padding: 0; margin: 0; text-decoration: none;
}
/* ⚠ 2026-08-31 — 위 `.bi-pop-pay--dt > div:last-child{flex:1 1 100%}` 는 «막내를 늘리는» 규칙이다.
   규격 푸터를 달면서 막내가 푸터가 되어, 푸터가 79 로 늘어났다(규격 60).
   기존 규칙은 그대로 두고(다른 자리에서 쓸 수 있다) 푸터만 예외로 못박는다. */
.bi-pop-pay--dt > .bi-pop-list-foot.bi-dtfoot{
    flex: 0 0 auto;
    height: auto;       /* 위와 같은 이유 — 못박으면 윗선 1px 만큼 59 가 된다 */
    margin-top: auto;   /* 남는 자리는 위로 — 푸터는 바닥에 붙는다(실측 14 남던 것) */
}
/* ⚠ 2026-08-31 — 문자·장문의 푸터는 본문(.bi-pop-pad) «안» 에 있다.
   옛 마크업의 <div> 짝이 맞지 않아 밖으로 옮기면 구조가 더 흐트러진다(실제로 시도했다).
   구조를 건드리는 대신 **스크롤 상자 바닥에 붙여** 항상 보이게 한다 —
   사용자 지적 「푸터 버튼영역이 없어 안 나와」의 해결이다. */
.bi-msgspec .bi-pop-pad > .bi-pop-list-foot{
    position: sticky; bottom: 0; z-index: 2;
    margin-top: var(--space-4); background: var(--bg-card);
}

/* ⚠ 한 줄 안의 «라벨 아닌 글자» 가 규격을 안 타고 있었다 — 실측 2026-08-31.
 *   `.bi-pop-finline > label` 만 13px 로 잡아 두어, 같은 줄에 있는
 *   포인트 값(`span.upoint_val`)과 약관 링크(`a.bi-link`)가 **브라우저 기본 16px** 로 떴다.
 *   한 줄 안에서 글자 크기가 갈리면 «항목 글자가 들쭉날쭉» 해 보인다.
 *   → 줄 자체에 크기를 준다. 안에 무엇이 들어와도 같은 글자다. */
.bi-pop-page .bi-popwrite .bi-pop-finline{ font-size: var(--pop-f-fs); color: var(--txt-secondary); }
.bi-pop-page .bi-popwrite .bi-pop-finline a,
.bi-pop-page .bi-popwrite .bi-pop-finline span:not(.bi-pop-funit):not(.bi-pop-fhint),
.bi-pop-page .bi-popwrite .bi-pop-finline .bi-write-value{ font-size: var(--pop-f-fs); }
/* 값 표시(포인트·마지막 거래일 등)도 폼 글자와 같은 눈금을 쓴다 — --fs-md(14)가 아니다 */
.bi-pop-page .bi-popwrite .bi-write-value{ font-size: var(--pop-f-fs); padding: 0; }

/* ⚠ 폼 안 버튼 글자가 **세 종류**였다 — 실측 2026-08-31.
 *   푸터 13/700 · 검색줄 13/500 · 라벨옆 12/500.
 *   규격(styleboard4 §09)은 «주 버튼 13 · 보조 버튼 12, 굵기는 둘 다 700» 이다.
 *   보조 버튼은 자리에 따라 **높이만** 다르고(라벨 옆 30 · 검색줄 36) 글자는 같아야 한다 —
 *   한 폼 안에서 같은 성격의 버튼이 크기·굵기가 갈리면 «항목 글자가 들쭉날쭉» 해 보인다. */
.bi-pop-page .bi-popwrite .bi-pop-srch > .bi-btn,
.bi-pop-page .bi-popwrite .bi-pop-flabel-row > .bi-btn,
.bi-pop-page .bi-popwrite .bi-pop-ffile > .bi-btn,
.bi-pop-page .bi-popwrite .bi-pop-f > .bi-btn,
.bi-pop-page .bi-popwrite .bi-pop-finline > .bi-btn{
    font-size: var(--pop-btn-sm-fs); font-weight: var(--fw-bold);
}
.bi-pop-page .bi-popwrite .bi-pop-foot-btns .bi-btn{ font-weight: var(--fw-bold); }

/* ═══════════════════════════════════════════════════════════════════════════
 * §42 예약 상세 = «자리» 가 아니라 «덮개»  (2026-09-02 · 규격 renew_crm/booking_spec.html)
 *   booking_renew · booking_time 공통. 사용자 요구 셋:
 *     ① 예약을 «고를 때» 우측에서 밀려 나오고 닫을 수 있게
 *     ② 중앙(디자이너 × 시간)이 상세가 물고 있던 자리까지 넓어지게
 *     ③ 펼쳐질 때 중앙을 «덮게» — 밀지 않는다
 *   근거(실측): 타임라인 실제 폭 3217px 인데 보이는 창은 976px = 30%.
 *   그 옆에서 340px 가 «예약을 선택하세요» 빈 상태로 늘 자리를 물고 있었다.
 *   덮개로 바꾸면 1920 에서 중앙 976 → 1318, 보이는 시간칸 7.7 → 10.9 칸.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* 좌 사이드와 중앙을 붙인다 — 사용자 지시(2026-09-02) 「붙여달라」.
   구획 구분선이 중앙 세로선까지 닿는다. 좌 구획이 이미 오른쪽 여백 16px 을 갖고 있어
   글자와 세로선 사이는 그대로다 — 폭은 뺏지 않고 «선이 못 미치던 빈 자리» 만 없앤다. */
.bi-bksplit.bi-bksplit--tight { gap: 0; }

/* 덮개가 «중앙 위» 에 얹히려면 기준이 필요하다 */
/* ⚠ 닫힌 덮개는 translateX(100%) 로 오른쪽에 «나가 있다» — 그대로 두면 부모의 scrollWidth 가
   360 늘어 카드에 **가로 넘침**이 생긴다(1630 → 1990 실측). 넘친 만큼을 여기서 자른다. */
.bi-bksplit.bi-bksplit--drawer { position: relative; overflow: hidden; }

/* ⚠ 덮개일 때만 자리를 뺀다 — 기존 .bi-bk-rightcol(340px 고정 열)은 그대로 두고
   두 클래스가 함께 붙었을 때만 덮개가 된다(특이도 0,2,0 로 위 규칙을 이긴다). */
.bi-bksplit > .bi-bk-rightcol.bi-bk-drawer {
    position: absolute; top: 0; right: 0; bottom: 0;
    width: 360px; align-self: auto; box-sizing: border-box;   /* 폭 360 은 여백을 포함한 값이다 */
    background: var(--bg-card);
    border-left: 1px solid var(--border-base);   /* 그림자·스크림은 쓰지 않는다 — 지금 화면에 없는 것이다 */
    /* ⚠ 여백을 주면 안쪽 패널(.bi-bk-panel-header 14/20 · .bi-bki 자체 여백)과 **겹쳐 이중**이 된다.
       덮개는 «자리» 만 잡고 여백은 안쪽 것을 그대로 쓴다. */
    overflow-y: auto; overflow-x: hidden;
    transform: translateX(100%);                  /* 폭이 아니라 «위치» 를 옮긴다 — 타임라인을 다시 그리지 않는다 */
    transition: transform .22s ease;
    /* z 는 «둘 사이» 여야 한다 — 실측으로 정한 값이다.
         .bi-bksch-nowline (현재시각 빨간선) z:40  → 덮개가 이보다 **위**여야 선이 상세를 가로지르지 않는다
         .bi-agg-list (주간·월간 요약에 마우스를 올리면 펼쳐지는 목록) z:50
                                                 → 덮개가 이보다 **아래**여야 그 목록에서 예약을 고를 수 있다
       60 으로 뒀다가 ③ 「마우스오버 설명에서 예약 선택이 안 된다」 를 만들었다. */
    z-index: 45;
}
.bi-bksplit > .bi-bk-rightcol.bi-bk-drawer.is-open { transform: translateX(0); }
/* 닫혀 있는 동안은 «없는 것» 이다 — 탭 이동·읽기 프로그램에서도 빠진다 */
.bi-bksplit > .bi-bk-rightcol.bi-bk-drawer:not(.is-open) { visibility: hidden; }
.bi-bksplit > .bi-bk-rightcol.bi-bk-drawer.is-open { visibility: visible; }
@media (prefers-reduced-motion: reduce) { .bi-bksplit > .bi-bk-rightcol.bi-bk-drawer { transition: none; } }
/* 덮개 안에서는 «상세 → 선 → 플랜 일지» 순서를 그대로 쓴다(지금 우측열과 같다) */
.bi-bksplit > .bi-bk-drawer .bi-bk-info-panel { width: 100%; }
/* 덮개 머리의 닫기 — 자리를 오른쪽 끝으로 */
/* ⚠ .bi-bk-panel-header 는 display:block 이라 margin-left:auto 가 안 먹고
   × 가 **제목 다음 줄로** 떨어졌다(제목 위 162 · 닫기 위 181 실측). 덮개 안에서만 한 줄로 세운다. */
.bi-bk-drawer .bi-bk-panel-header { display: flex; align-items: center; gap: var(--space-2); }
.bi-bk-panel-header .bi-bk-panel-close {
    margin-left: auto; width: 26px; height: 26px; border: 0; border-radius: var(--radius-md);
    background: var(--bg-input); color: var(--txt-muted); cursor: pointer;
    display: flex; align-items: center; justify-content: center;
}
.bi-bk-panel-header .bi-bk-panel-close:hover { background: var(--border-light); color: var(--txt-primary); }
/* 덮개에서는 닫기가 «머리에 하나» 다 — 상세 안 .bi-bki-close 는 같은 일을 두 번 한다 */
.bi-bksplit > .bi-bk-drawer .bi-bki-close { display: none; }
/* 빈 상태 「예약을 선택하세요」 는 덮개에서 쓰이지 않는다 — 안 고르면 덮개 자체가 없다 */
.bi-bksplit > .bi-bk-drawer .bi-bk-panel-empty { display: none; }

/* 예약 상태 배지 — 「실시간 최근 플랜 일지」 배지(.bi-bka-badge) 와 같은 모양.
   ⚠ 지금 것은 bg #2563EB · 흰 글자 · 라운드 0 «각진 사각» 인데 이 형태가 화면 어디에도 없다(사용자 지적).
   색은 «확정 = 파랑» 으로 — 타임라인 카드 배지(.bi-resv-dot--confirmed)와 같은 계열이라 눈이 헷갈리지 않는다. */
/* ⚠ 기존 .bi-bki-status.status_round (0,2,0) 가 r9999 를 준다 — 특이도를 맞춰야 이긴다 */
/* ── 예약 카드 — 두 화면 «한 형태» (2026-09-02) ──────────────────────────
 * 지적 ⑥⑦: 예약일정표 카드에는 **왼쪽 3px 굵은 선**이 있고(디자인에 없던 형태),
 *   예약일정표(시간) 카드는 **배경이 아예 없다**(.bi-bt-card-res--* 는 **정의가 없는 죽은 클래스**였다).
 *   같은 «예약 카드» 가 두 화면에서 다르게 생겼다.
 * → 한 형태로 맞춘다: **연한 배경 + 1px 옅은 테두리 + r12**. 굵은 선은 쓰지 않는다.
 *   색은 상태 배지(.bi-resv-dot--*)와 같은 계열이라 카드와 배지가 따로 놀지 않는다.
 * ⚠ 기존 규칙을 고치지 않는다 — .bi-bksplit--drawer 스코프에서 덮는다(두 화면에만 닿는다). */
.bi-bksplit--drawer .bi-bk-inner.bi-bksch-card,
/* ⚠ .bi-resv 는 content-box 였다. 테두리 1px 을 더하니 width:100% 위에 2px 이 얹혀
   칸(117 · 안쪽 105)을 **11px 넘겼다**(실측). 테두리를 폭 안에 넣는다. */
.bi-bksplit--drawer .bi-resv { border-style: solid; border-width: 1px; border-radius: var(--radius-xl); box-sizing: border-box; }

/* 좌↔중앙 세로 구분선 — 붙이고 나니 «사라졌다».
   ⚠ 원래 규칙은 .bi-bksplit__side + .bi-bksplit__calcol 인데
   booking_renew 의 좌측은 .bi-bksch-side 라 형제 선택자에 걸리지 않았다(실측 border-left 0px).
   두 이름을 다 건다. */
.bi-bksplit--tight > .bi-bksch-side + .bi-bksplit__calcol,
.bi-bksplit--tight > .bi-bksch-side + .bi-bksplit__main,
.bi-bksplit--tight > .bi-bksplit__side + .bi-bksplit__calcol,
.bi-bksplit--tight > .bi-bksplit__side + .bi-bksplit__main {
    border-left: 1px solid var(--border-base);
}

/* ⚠ 여기서 .bi-bka-badge.is-emerald 를 파랑으로 덮었다가 **되돌렸다.**
   같은 클래스가 두 화면에서 «다른 상태» 를 뜻하고 있었기 때문이다 —
   시간표는 확정=emerald, 일정표는 신청=emerald. CSS 로 덮으면 한쪽은 맞고 한쪽은 틀린다.
   → 색이 아니라 **뜻을 통일**했다: booking_time/script.js 의 badgeCls 를 일정표 기준으로 맞췄다.
   기준은 카드 안 배지 .bi-resv-dot--* — 신청 초록 · 확정 파랑 · 완료 회색 · 취소 빨강. */

/* 헤더 일간·주간·월간이 눌려 글자가 깨졌다 — 버튼 21×28 실측, 「일간」 두 글자가 안 들어간다.
   범례가 커지면서 세그먼트를 짓눌렀다. 줄어들지 않게 못박는다. */
.bi-erp-toolbar__right .bi-segment { flex-shrink: 0; }
.bi-erp-toolbar__right .bi-segment .bi-segment__btn { flex-shrink: 0; white-space: nowrap; }
/* ⚠ 진짜 원인은 좌우 여백이 --space-0_5(**2px**) 라 「일간」 두 글자가 버튼에 꽉 찬 것이다(21×28 실측).
   공통 .bi-segment__btn 은 건드리지 않고 이 툴바에서만 숨통을 튼다. */
.bi-erp-toolbar__right .bi-segment .bi-segment__btn { padding-left: var(--space-3); padding-right: var(--space-3); }
/* 카드 고객명 — 시간표만 11/900 이고 일정표는 13/800 이었다(실측). 두 화면을 맞춘다. */
.bi-bksplit--drawer .bi-resv__name { font-size: var(--fs-xs); font-weight: var(--fw-extrabold); }
/* ⚠ 원래 규칙 .bi-page .bi-bk-inner.bi-bksch-card.bi-bk-statusN 은 클래스 **넷**(0,4,0) 이다.
   셋으로는 못 이긴다 — 상태 클래스를 속성으로 한 번 더 걸어 무게를 맞추고 뒤에 둔다. */
.bi-bksplit--drawer .bi-bk-inner.bi-bksch-card[class*="bi-bk-status"] { border-left-width: 1px; }
/* 신청 */
.bi-bksplit--drawer .bi-bk-inner.bi-bksch-card.bi-bk-status1 {
    background: color-mix(in srgb, var(--color-success-100) 45%, transparent);
    border-color: var(--color-success-200); color: var(--color-success-700);
}
/* 확정 */
.bi-bksplit--drawer .bi-bk-inner.bi-bksch-card.bi-bk-status2 {
    background: color-mix(in srgb, var(--color-info-100) 45%, transparent);
    border-color: var(--color-info-200); color: var(--color-info-700);
}
/* 취소 · 노쇼 */
.bi-bksplit--drawer .bi-bk-inner.bi-bksch-card.bi-bk-status3,
.bi-bksplit--drawer .bi-bk-inner.bi-bksch-card.bi-bk-status5,
.bi-bksplit--drawer .bi-bk-inner.bi-bksch-card.bi-bk-status6 {
    background: color-mix(in srgb, var(--color-danger-100) 45%, transparent);
    border-color: var(--color-danger-200); color: var(--color-danger-600);
}
/* 완료 */
.bi-bksplit--drawer .bi-bk-inner.bi-bksch-card.bi-bk-status4 {
    background: var(--bg-input); border-color: var(--border-base); color: var(--txt-muted);
}

.bi-bki-status.bi-bki-status--chip {
    display: inline-block; min-width: 34px; text-align: center;
    font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); line-height: 1.5;
    padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-md);
    background: var(--color-info-50); color: var(--color-info-600); border: 1px solid var(--color-info-100);
}

/* ─────────────────────────────────────────────────────────────────────────
   §43 · 예약 두 화면을 «한 벌» 로 (사용자 지적 6건, 2026-09-02)
   ───────────────────────────────────────────────────────────────────────── */

/* ① 카드 안 상태 글자 — 주간·월간의 묶음 칩(.bi-agg-stat)과 «크기·모양·색» 을 같게.
   일간·시간표는 10/900 · r4 · 2/6 이었고 주간·월간은 11/800 · r6 · 2/8 이었다.
   같은 낱말이 자리마다 다른 옷을 입으면 한 화면으로 안 읽힌다. */
.bi-page .bi-resv-dot {
    font-size: var(--fs-xs); font-weight: var(--fw-extrabold); line-height: 1.5;
    padding: var(--space-0_5) var(--space-2); border-radius: var(--radius-md);
    border: 1px solid transparent; white-space: nowrap;
}
/* 색도 .bi-agg-stat 과 같은 값으로 — 신청 초록 · 확정 파랑 · 완료 회색 · 취소·노쇼·마감 빨강 */
.bi-page .bi-resv-dot--request   { background: var(--color-success-100); color: var(--color-success-700); border-color: var(--color-success-300); }
.bi-page .bi-resv-dot--confirmed { background: var(--color-info-100);    color: var(--color-info-700);    border-color: var(--color-info-300); }
.bi-page .bi-resv-dot--done      { background: var(--border-base);       color: var(--txt-muted);         border-color: transparent; }
.bi-page .bi-resv-dot--cancel,
.bi-page .bi-resv-dot--block     { background: var(--color-danger-50);   color: var(--color-danger-700);  border-color: var(--color-danger-300); }
.bi-page .bi-resv-dot--checkin   { background: var(--color-warning-100); color: var(--color-warning-700); border-color: var(--color-warning-300); }

/* ③ 헤더 세그먼트 — 4칸 «고정» 격자였다. 버튼이 셋이면 네 번째 빈 칸이
   「월간」 옆 회색 여백으로 남고, 다섯이면 두 줄로 접힌다.
   → 칸 수를 버튼 수에 맡긴다. 버튼이 넷이면 지금과 똑같다. */
.bi-page .bi-segment { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 1fr; }

/* ④ 검색 칸 아래 여백 — 칸 자체의 아래 padding 12 + 칸 사이 12 + 다음 칸 위 12 = 36 이었다.
   칸의 아래 여백을 덜어 24 로. 좌우도 다른 칸(16)에 맞춰 입력폼이 캘린더와 같은 선에서 시작하게 한다. */
.bi-page .bi-bksch-side-sec--search { padding: var(--space-3) var(--space-4) 0; }

/* ⑦ 시간표 아래 「상태 가이드」 스위치 — 위 서브바 범례(.bi-bk-legend-dot--*)와 같은 색으로.
   신청 초록 · 확정 파랑 · 완료 회색 · 취소 빨강 테두리 — 카드 칩과도 한 벌이다. */
.bi-page .bi-resv-sw--request   { background: var(--color-success-500); border: 0; }
.bi-page .bi-resv-sw--confirmed { background: var(--color-info-500);    border: 0; }
.bi-page .bi-resv-sw--done      { background: var(--txt-disabled);      border: 0; }
.bi-page .bi-resv-sw--cancel    { background: var(--color-danger-50);   border: 1px solid var(--color-danger-300); }

/* ④ 중앙의 디자이너 알약 필터바는 **뺐다**(2026-09-04 사용자 지시) —
   같은 필터가 좌측 사이드에 체크박스로 있고, script.js 주석도 중앙 칩을
   「(구) 단일선택 … 현재 미사용(체크박스 필터로 대체)」 이라 적어 두고 있었다.
   규격 부품 .bi-pillbar 자체는 member 화면이 쓰므로 그대로 둔다. */

/* ⑧ 좌측 사이드에서 «고르는 것» 은 네이비다 — 규격안(booking_spec)이 그렇게 그려져 있다
   (.bkm-cn.is-on · .bkm-chip.is-on 둘 다 --navy). 셋 다 --brand-blue 로 칠해져 「튄다」 는 지적을 받았다.
   ⚠ 중앙 상단의 «보기 전환»(.bi-segment 일간·주간·월간)만 brand-blue 로 남는다 —
      「사이드에서 고른다」 와 「보기를 바꾼다」 는 다른 일이고, 규격안도 그렇게 그려져 있다. */
.bi-page .bi-cal__day.is-sel     { background: var(--brand-navy); }
/* §68-3 네이비 판은 §61 에서 걷었다. 12달 고르개(.bi-cal__mon)는 화면에서 사라졌다 — 세 모드가 같은 달력을 쓴다. */
.bi-page .bi-bksch-status-chip.is-active {
    background: var(--brand-navy); border-color: var(--brand-navy); color: var(--bg-card);
}

/* ⑨ 보기 탭(일간·주간·월간) 활성색을 «캘린더와 같은 색» 으로 (2026-09-04 사용자 지시).
   §29 는 세그먼트 활성을 brand-blue 로 두지만, 이 화면에서는 좌측 달력·상태 칩이 네이비라
   가운데 탭만 파랑이면 그 하나가 튄다. 예약 두 화면 안에서 «고르는 것» 의 색을 하나로 맞춘다. */
.bi-page .bi-erp-toolbar__right .bi-segment__btn.is-active {
    background: var(--brand-navy); color: var(--bg-card);
}

/* ⑩ 달력에 색 테두리 — 「box-shadow: inset 0 0 0 1.5px 이렇게 색테두리 들어갔으면」 (사용자).
   달을 담은 격자를 한 상자로 두른다. 색은 이미 쓰던 값(오늘 표시 링과 같은 --color-info-200) —
   새 색을 만들지 않는다(styleguide2 §40-19 「상태색은 §3 팔레트에서 고른다」와 같은 생각). */
.bi-page .bi-cal__grid {
    box-shadow: inset 0 0 0 1.5px var(--color-info-200);
    border-radius: var(--radius-lg); padding: var(--space-1_5);
}

/* ─────────────────────────────────────────────────────────────────────────
   §44 · POS 결제·매출등록 — 규격안(pos_spec2.html) 적용 · 1단계
   ───────────────────────────────────────────────────────────────────────── */

/* 결제 대기는 «자리» 가 둘이다 — 넓으면 오른쪽 열, 좁으면 본문 맨 위 띠.
   다른 화면이 아니라 같은 화면의 두 모습이다(사용자 정정 2026-09-07). 기준선 1600. */
@media (min-width: 1600px) {
    .bi-erp-card > .bi-counter-grid { grid-template-columns: minmax(0, 8fr) minmax(0, 4fr) 268px; }
    /* 세로로 쌓아 대기 손님이 여럿 보이게 — 가로 스크롤이 아니라 세로 목록이다 */
    .bi-counter-col--queue .bi-counter-queue {
        flex-direction: column; overflow-x: visible; overflow-y: auto; max-height: 620px;
    }
    .bi-counter-col--queue .bi-counter-qcard { width: 100%; }
}
@media (max-width: 1599px) {
    /* 좁으면 셋을 나란히 못 둔다 — 대기열만 맨 위로 올리고 두 칸 폭을 다 쓴다.
       ⚠ 왼쪽 세로선(.bi-counter-col + .bi-counter-col)이 따라오므로 그쪽을 끄고 아래선으로 바꾼다. */
    .bi-erp-card > .bi-counter-grid > .bi-counter-col--queue {
        order: -1; grid-column: 1 / -1;
        border-left: 0; border-bottom: 1px solid var(--border-base);
    }
}
/* 대기열 칸은 카드 안이라 둘레를 갖지 않는다(§40-2 — 카드 안에서는 선으로 나눈다).
   구 위치에서 갖고 있던 아래선은 이제 열 자신이 긋는다. */
.bi-erp-card .bi-counter-col--queue .bi-counter-queue-box { border-bottom: 0; }

/* 268 열에서 제목이 두 줄로 접혔다 — 「결제 대기」 한 줄 + 건수는 «배지» 로.
   규격안(pos_spec2 §1)의 «🕐 결제 대기 3» 과 같은 모양. */
.bi-counter-queue-box .bi-counter-queue-title { white-space: nowrap; text-transform: none; letter-spacing: 0; }
.bi-counter-queue-box .bi-counter-queue-meta {
    background: var(--color-danger-100); color: var(--color-danger-700);
    border-radius: var(--radius-full); padding: var(--space-0_5) var(--space-2);
    font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); line-height: 1.5;
}

/* §44 · 2단계 — 우측 패널 (pos_spec2 §2·§6) */

/* 목록 칸은 «3줄» 을 기준으로 높이를 고정한다(사용자 지시 2026-09-07).
   실측 한 줄 47 × 3 = 141 + 줄마다 아래 구분선 3 = 144.
   왜 고정인가 — 아래가 «합계 → 결제수단 → 결제완료» 다. 목록이 늘었다 줄었다 하면
   버튼 자리가 움직이고, 계산대에서 버튼이 움직이면 잘못 누른다. */
/* ⚠ 이 목록은 flex:1 이라 «칸을 채우는» 쪽이었다 — height 를 줘도 flex 가 이긴다.
   높이를 못박으려면 flex 를 꺼야 한다. 그리고 패널도 늘어나지 않게 한다. */
.bi-bs-info-card .bi-bs-tab-panels { flex: none; }
.bi-bs-info-card .bi-bs-info-list { flex: 0 0 144px; height: 144px; overflow-y: auto; }
/* ⚠ 형제 선택자(li + li)로 그으면 «1개일 때 줄이 없다».
   줄마다 «아래» 선을 그어 한 줄만 있어도 칸이 목록으로 읽히게 한다(사용자 지시). */
.bi-bs-info-card .bi-bs-info-list > li { border-bottom: 1px solid var(--border-light); }
.bi-bs-info-card .bi-bs-info-list > li.bi-bs-empty-state { border-bottom: 0; height: 100%; }

/* 매출 메모 — 탭에서 내려온 고정 칸 */
/* ⚠ 새 클래스를 만들려다 SPEC-UNSHOWN 에 걸렸다 — 이미 있는 규격으로 쓴다.
   .bi-counter-cust-body = 여백 20 + 세로 스택. 딱 그 모양이다. */
.bi-bs-info-card > .bi-counter-cust-body { gap: var(--space-1_5); padding: var(--space-3) var(--space-5) var(--space-5); }
.bi-bs-info-card .bi-counter-memo-ta { min-height: 62px; }

/* §44 · 3~6단계 (pos_spec2 §5·§8) */

/* 6 · 진행 표시 — 지나온 칸은 파랑 배지, 지금 칸은 회색 배지. 사이는 화살표 없이 간격으로. */
.bi-bs-counter .bi-erp-title__sub { display: inline-flex; align-items: center; gap: var(--space-1_5); }
.bi-bs-counter .bi-erp-title__sub .bi-badge i { font-size: var(--fs-2xs); margin-right: var(--space-0_5); }

/* 5 · 「＋시술/상품 추가」 — §12 축1: primary(브랜드블루)는 화면에 1개 = 결제완료.
   이 버튼은 «워크플로 반복 액션» 이라 네이비다(pos_spec2 §4). */
.bi-bs-counter #product_add.bi-btn--primary {
    background: var(--brand-navy); border-color: var(--brand-navy); color: var(--bg-card);
}
.bi-bs-counter #product_add.bi-btn--primary:hover { background: var(--brand-navy-hover); border-color: var(--brand-navy-hover); }

/* 5 · 「못 쓰는」 상태 — opacity 로 흐리면 «색이 옅은 것» 과 구분이 안 된다(N Pay 초록이 특히).
   회색으로 갈아입혀 «지금은 아니다» 를 분명히 한다(pos_spec2 §5). */
.bi-bs-counter .bi-counter-pay-btn:disabled,
.bi-bs-counter .bi-counter-pay-btn--inactive {
    opacity: 1; background: var(--bg-input); border-color: var(--border-base);
    color: var(--txt-disabled); cursor: not-allowed;
}
.bi-bs-counter .bi-counter-pay-btn:disabled i,
.bi-bs-counter .bi-counter-pay-btn--inactive i { color: var(--txt-disabled); }
.bi-bs-counter .bi-bs-dock-pay:disabled {
    opacity: 1; background: var(--txt-disabled); border-color: var(--txt-disabled); color: var(--bg-card); cursor: not-allowed;
}
.bi-bs-counter .bi-bs-dock-close:disabled {
    opacity: 1; background: var(--bg-input); border-color: var(--border-base); color: var(--txt-disabled); cursor: not-allowed;
}

/* 4 · 내역 행 — 마크업은 이미 규격 모양이다(분류 배지·수량 스테퍼·할인 버튼).
   어긋난 것은 «칩 모양» 뿐이라 그것만 맞춘다. */
.bi-bs-counter .bi-bs-pro-qty {
    border: 1px solid var(--border-base); border-radius: var(--radius-lg); overflow: hidden; gap: 0; height: 32px;
}
.bi-bs-counter .bi-bs-pro-qty .bi-bs-pro-qty-btn { width: 30px; border: 0; background: var(--bg-input); color: var(--txt-muted); }
.bi-bs-counter .bi-bs-pro-qty .bi-bs-pro-input--qty {
    width: 36px; border: 0; border-left: 1px solid var(--border-light); border-right: 1px solid var(--border-light);
    border-radius: 0; text-align: center;
}
/* 할인 — 없으면 흰 칩(할인추가), 값이 있으면 빨강 칩. 값 유무는 JS 가 is-on 으로 표시한다. */
.bi-bs-counter .bi-bs-pro-disc-btn {
    min-width: 88px; height: 32px; border-radius: var(--radius-lg);
    border: 1px solid var(--border-base); background: var(--bg-card); color: var(--txt-secondary);
    font-size: var(--fs-sm); font-weight: var(--fw-bold);
}
.bi-bs-counter .bi-bs-pro-disc-btn.is-on {
    background: var(--color-danger-50); border-color: var(--color-danger-200); color: var(--color-danger-600);
    font-weight: var(--fw-extrabold);
}

/* ⚠ 카드가 «내용보다 작아» 잘렸다 — 레이아웃 검사가 「깨짐 427 > 340」 으로 잡았다.
   목록을 144 로 못박고 매출 메모를 아래로 내리면서 카드가 필요한 높이가 늘었는데,
   카드는 열이 남겨 준 만큼만 갖고 overflow:hidden 이라 아래가 잘렸다.
   → 이 카드는 «내용만큼» 갖게 한다(열은 세로로 늘어나도 된다). 메모 칸 여백도 조금 줄인다. */
.bi-bs-counter .bi-bs-info-card { flex: 0 0 auto; overflow: visible; }
.bi-bs-info-card > .bi-counter-cust-body { padding: var(--space-2_5) var(--space-5) var(--space-4); }

/* §44 · 고객 정보 세 줄 (pos_spec2 §1) — 기존 2단 배치를 규격안 배치로 덮는다. */
.bi-bs-counter .bi-counter-cust-body .bi-write-row { gap: var(--space-4); margin-bottom: 0; }
.bi-bs-counter .bi-counter-cust-body .bi-write-field { flex: 1 1 0; min-width: 0; }
.bi-bs-counter .bi-counter-cust-body .bi-write-field--wide { flex: 2 1 0; }
.bi-bs-counter .bi-bs-field--sex { flex: 0 0 168px; }
/* 검색 버튼은 입력 오른쪽에 붙는 «네모» 다(규격안). 입력의 오른쪽 모서리를 펴서 한 덩어리로. */
.bi-bs-counter .bi-counter-cust-body .bi-row--gap-0 { gap: var(--space-2); }
/* ⚠ 규격안 그림은 42 였지만 §12-4 버튼 사다리(48·32·27·22)에 42 는 없다 —
   검사가 「커짐」 으로 잡았다. 입력(.bi-input--md = 40)에 가장 가까운 «사다리 안» 값은 32 지만
   그러면 입력보다 작아 어긋나 보인다. → 입력을 48 로 올려 버튼과 같은 칸에 세운다. */
.bi-bs-counter .bi-counter-cust-body .bi-input--md,
.bi-bs-counter .bi-counter-cust-body .bi-counter-select { height: 48px; }
.bi-bs-counter .bi-counter-cust-body .bi-counter-search-btn {
    flex: 0 0 48px; width: 48px; height: 48px; border-radius: var(--radius-lg);
    border: 1px solid var(--border-base); background: var(--bg-card); color: var(--txt-muted);
}
.bi-bs-counter .bi-bs-sex-group { height: 48px; }

/* §44 · 마무리 — 규격안과 남아 있던 두 곳 */
/* 성별 — 규격안은 고른 쪽이 «네이비 채움 + 흰 글자» 다(연회색 + 파란 글자였다). */
.bi-bs-counter input[type="radio"].bi-bs-sex-r:checked + label.bi-bs-sex-lbl {
    background: var(--brand-navy); color: var(--bg-card); border-color: var(--brand-navy);
}
/* 매출 메모 — 최근 내역 바로 밑에 «붙어» 경계가 겹쳐 보였다. 위에 선 하나로 가르고 아래 숨을 준다. */
.bi-bs-info-card > .bi-counter-cust-body {
    border-top: 1px solid var(--border-base); padding: var(--space-4) var(--space-5) var(--space-5);
}

/* §44 · 규격안 «모양» (pos_spec2 §1) — bs1.png 대조로 남아 있던 다섯 */

/* ⚠ 「전체 영역 구분하는 틀부터 다르다」(사용자 2026-09-07). 내가 열마다 테두리를 주고
   사이를 벌려 «떨어진 카드 셋» 으로 만들었는데, 규격안은 그 반대다 —
   «흰 판 하나» 를 세로 실선으로 나누고, 테두리 카드는 «좌측 열 안» 의 둘뿐이다.
   → 판을 하나로 되돌리고(§40-2 대로 선으로 나눔), 테두리는 좌측 두 블록에만 남긴다. */
.bi-bs-counter .bi-erp-card > .bi-counter-grid { gap: 0; padding: 0; align-items: stretch; }
.bi-bs-counter .bi-erp-card > .bi-counter-grid > .bi-counter-col + .bi-counter-col {
    border-left: 1px solid var(--border-base);
}
/* 좌측 열만 «카드 둘» — 열 안쪽에 숨을 주고 블록마다 테두리를 준다 */
.bi-bs-counter .bi-erp-card > .bi-counter-grid > .bi-counter-col:first-child {
    padding: var(--space-4); gap: var(--space-4);
}
.bi-bs-counter .bi-erp-card > .bi-counter-grid > .bi-counter-col:first-child > .bi-counter-card {
    border: 1px solid var(--border-base); border-radius: var(--radius-xl);
    background: var(--bg-card); box-shadow: none;
}
.bi-bs-counter .bi-erp-card > .bi-counter-grid > .bi-counter-col:first-child > * + * { border-top: 0; }
/* 우측 결제 열·대기 열은 카드가 아니라 «판의 한 칸» 이다 — 둘레 없음 */
.bi-bs-counter .bi-erp-card > .bi-counter-grid > .bi-counter-col:not(:first-child) > * + * {
    border-top: 1px solid var(--border-light);
}
.bi-bs-counter .bi-counter-card__head { background: var(--bg-card); }

/* ③ 진행 표시 — 동그란 배지 + 사이 연결선 */
.bi-bs-counter .bi-erp-title__sub .bi-badge {
    width: 20px; height: 20px; padding: 0; border-radius: var(--radius-full);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: var(--fs-2xs); font-weight: var(--fw-extrabold);
}
.bi-bs-counter .bi-erp-title__sub .bi-erp-toolbar__div { width: 22px; height: 1px; background: var(--border-base); margin: 0 var(--space-1); }
/* ⚠ 단계 이름에 새 클래스를 만들려다 SPEC-UNSHOWN 에 걸렸다 — 글자는 클래스 없이 두고
   지금 단계만 <b> 로 굵게 한다. 색은 이 줄 안에서만 준다. */
.bi-bs-counter .bi-erp-title__sub { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-muted); }
.bi-bs-counter .bi-erp-title__sub b { color: var(--txt-primary); font-weight: var(--fw-extrabold); }

/* ⑤ 매출일자 칩 — 툴바 오른쪽으로 옮겼다. 카드 둘레는 벗고 한 줄로. */
.bi-bs-counter .bi-erp-toolbar__right .bi-counter-datebar {
    border: 0; background: transparent; padding: 0; gap: var(--space-2);
}

/* §44 · 내역 표 — 규격안은 «No.» 열이 보인다(지금은 폭이 0 이라 안 보였다) */
.bi-bs-counter .bi-bs-pro-th--no { width: 46px; }
.bi-bs-counter .bi-bs-pro-td--no { text-align: center; }
.bi-bs-counter .bi-bs-pro-rownum { color: var(--txt-disabled); font-size: var(--fs-sm); }

/* §44 · 「규격안대로인가」 검사(qc.mjs spec · spec_match/buysell.mjs)가 짚은 자리들 */

/* 1 · No. 열은 10371줄에서 display:none 이었다 — 규격안에는 있다. 되살린다. */
.bi-bs-counter .bi-bs-pro-table .bi-bs-pro-th--no,
.bi-bs-counter .bi-bs-pro-table .bi-bs-pro-td--no { display: table-cell; width: 46px; text-align: center; }

/* 2 · 할인은 «직접 입력» 이 되어야 한다(규격안 칩 안 숫자). 값이 있으면 빨강. */
.bi-bs-counter .bi-bs-pro-disc-in {
    width: 92px; height: 32px; text-align: center; border-radius: var(--radius-lg);
    border: 1px solid var(--border-base); background: var(--bg-card);
    font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-secondary);
}
.bi-bs-counter .bi-bs-pro-disc-in.is-on {
    background: var(--color-danger-50); border-color: var(--color-danger-200);
    color: var(--color-danger-600); font-weight: var(--fw-extrabold);
}

/* 3 · 매출 메모가 아래 합계와 겹쳤다 — 카드 안에서 자기 자리를 갖게 한다. */
.bi-bs-info-card > .bi-counter-cust-body { flex: 0 0 auto; }

/* 4 · 수단별 «×» 취소 — 값이 있는 줄에만 보인다(JS 가 is-on 을 붙인다). */
.bi-bs-counter .bi-bs-dock-x {
    width: 17px; height: 17px; margin-left: var(--space-2); border: 1px solid var(--border-base);
    border-radius: var(--radius-xs); background: var(--bg-card); color: var(--txt-disabled);
    font-size: var(--fs-3xs, 10px); line-height: 1; display: none; align-items: center; justify-content: center;
}
.bi-bs-counter .bi-bs-dock-row.is-on .bi-bs-dock-x { display: inline-flex; }
.bi-bs-counter .bi-bs-dock-x:hover { color: var(--color-danger-600); border-color: var(--color-danger-200); }

/* 5 · 총 결제 금액 */
/* ⚠ 규격안 그림은 31 이었지만 sg2 글자 사다리에 31 은 없다(11·12·13·14·16·18·20·24·30).
   sg2 가 유일 규격이고 규격안은 그 파생이다 → 가장 가까운 30 으로 내린다(probe_break 「커짐」). */
.bi-bs-counter .bi-counter-final-amt { font-size: 30px; }

/* 6 · 결제수단 «고른 표시» — 금액이 잡힌 수단에 테두리 네이비 + 초록 체크 */
.bi-bs-counter .bi-counter-pay-btn.is-on { border-color: var(--brand-navy); color: var(--brand-navy); }
.bi-bs-counter .bi-counter-pay-btn.is-on::after {
    content: '\f00c'; font-family: 'Font Awesome 5 Pro'; font-weight: 900;
    position: absolute; right: 8px; top: 6px; font-size: var(--fs-2xs); color: var(--color-npay);
}
.bi-bs-counter .bi-counter-pay-btn { position: relative; }

/* ⚠ 카드가 flex:0 0 auto 인데도 340 이었다 — 어딘가 «높이» 가 정해져 있어 매출 메모가
   카드 밖으로 삐져나와 도크와 겹쳤다(규격 일치 검사 「매출 메모 겹침」). 높이를 내용에 맡긴다. */
.bi-bs-counter .bi-bs-info-card { height: auto; min-height: 0; }

/* 규격안(buysell1.png) — 고객메모는 «흰 상자» 다. 공통 .bi-counter-consult 는 노란 상자이고
   booking_buysell·report_buy_appear 도 함께 쓰므로 정의를 고치지 않고 이 화면에서만 덮는다(§4). */
.bi-bs-counter textarea.bi-counter-consult {
    background: var(--bg-card); border-color: var(--cc-line); color: var(--txt-secondary);
    min-height: 52px;
}
.bi-bs-counter textarea.bi-counter-consult:focus { border-color: var(--brand-navy); }
/* 규격안 — 「결제수단」 라벨은 총액과 버튼 사이에서 숨을 준다 */
.bi-bs-counter .bi-counter-pay > .bi-write-label { margin-bottom: calc(-1 * var(--space-1)); }

/* ─────────────────────────────────────────────────────────────────────────
   §44-2 · 규격안(buysell1.png)과 «잘라 나란히» 대조해 잰 열 자리 (2026-09-07)
   ───────────────────────────────────────────────────────────────────────── */

/* 10 · 뿌리 원인 — 가운데 열이 454 였다. 규격안은 350(대기 250). 열이 넓으니 버튼이 다 커 보였다. */
@media (min-width: 1600px) {
    .bi-bs-counter .bi-erp-card > .bi-counter-grid { grid-template-columns: minmax(0, 1fr) 350px 250px; }
}

/* 1 · 진행 표시 — 규격안은 «채운 원». 지나온 칸은 파랑, 지금 칸은 네이비. */
.bi-bs-counter .bi-erp-title__sub { color: var(--txt-secondary); font-size: var(--fs-sm); }
.bi-bs-counter .bi-erp-title__sub .bi-badge {
    background: var(--brand-blue); color: var(--bg-card); border-color: transparent;
    width: 18px; height: 18px; padding: 0; font-size: var(--fs-2xs); font-weight: var(--fw-bold);
}
.bi-bs-counter .bi-erp-title__sub .bi-badge:nth-of-type(3) { background: var(--brand-navy); }
.bi-bs-counter .bi-erp-title__sub b { color: var(--txt-primary); }

/* 2 · 매출일자 — 달력 아이콘 + 날짜, 옅은 파란 칩 하나 */
.bi-bs-counter .bi-erp-toolbar__right .bi-counter-datebar {
    background: var(--color-info-50); border: 0; border-radius: var(--radius-lg);
    padding: 0 var(--space-3); height: 32px; width: auto;
}
.bi-bs-counter .bi-counter-datebar__l { gap: var(--space-2); height: 32px; }
.bi-bs-counter .bi-counter-datebar__close {
    background: none; border: 0; padding: 0; height: auto; color: var(--brand-navy);
}
.bi-bs-counter .bi-bs-datebar-date {
    font-size: var(--fs-md); font-weight: var(--fw-extrabold); color: var(--brand-navy);
    background: none; border: 0; width: 96px; padding: 0;
}

/* 3 · 새 전표 — 매출일자 왼쪽, 같은 높이 */
.bi-bs-counter .bi-erp-toolbar__right #bs_new_slip { height: 32px; border-radius: var(--radius-lg); }

/* 4 · 성별 — 규격안은 «네모 두 칸». 회색 트랙 알약이 아니다. */
.bi-bs-counter .bi-bs-sex-group {
    width: 200px; background: var(--bg-card); border: 1px solid var(--border-base);
    border-radius: var(--radius-md); padding: 0; overflow: hidden;
}
.bi-bs-counter .bi-bs-sex-lbl {
    flex: 1; height: 46px; border-radius: 0; font-size: var(--fs-md); font-weight: var(--fw-bold);
}
.bi-bs-counter .bi-bs-sex-r:checked + .bi-bs-sex-lbl { box-shadow: none; }

/* 8 · 탭 — 규격안은 «카드 탭»(옅은 트랙 위 흰 카드), 밑줄 탭이 아니다 */
.bi-bs-counter .bi-bs-tab-hdr {
    background: var(--bg-section); border-bottom: 1px solid var(--border-light);
    padding: var(--space-2); gap: var(--space-2);
}
.bi-bs-counter .bi-bs-tab-lbl {
    height: 40px; border-radius: var(--radius-lg); border: 1px solid transparent;
    background: none; color: var(--txt-disabled); font-weight: var(--fw-bold);
}
/* ⚠ 라디오는 헤더의 «형제» 이지 바로 앞이 아니다 — + 로는 절대 안 걸린다.
   기존 규칙(10318줄)이 쓰는 ~ + [for] 짝을 그대로 따른다. */
.bi-bs-counter #itab_hist:checked ~ .bi-bs-tab-hdr .bi-bs-tab-lbl[for="itab_hist"],
.bi-bs-counter #itab_pkg:checked  ~ .bi-bs-tab-hdr .bi-bs-tab-lbl[for="itab_pkg"] {
    background: var(--bg-card); border-color: var(--border-base); color: var(--brand-navy);
}
/* 8-b · 목록 줄 — 규격안은 «작은 회색 날짜 / 굵은 이름 … 오른쪽 금액» */
.bi-bs-counter .bi-counter-hcard { padding: var(--space-3) var(--space-4); }
.bi-bs-counter .bi-counter-hcard__top {
    font-size: var(--fs-xs); color: var(--txt-disabled); font-weight: var(--fw-medium);
    margin-bottom: var(--space-1);
}
.bi-bs-counter .bi-counter-hcard__line { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.bi-bs-counter .bi-counter-hcard__name { font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--txt-primary); margin: 0; }
.bi-bs-counter .bi-counter-hcard__amt { font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--txt-secondary); margin: 0; white-space: nowrap; }

/* 9 · 합계 — 규격안은 수단마다 아이콘이 있고 줄이 촘촘하며 값이 굵다 */
.bi-bs-counter .bi-bs-dock-row { min-height: 28px; font-size: var(--fs-md); }
.bi-bs-counter .bi-bs-dock-row > span:first-child { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--txt-secondary); }
.bi-bs-counter .bi-bs-dock-row > span:first-child > i { width: 15px; text-align: center; color: var(--txt-disabled); }
.bi-bs-counter .bi-bs-dock-row > span:last-of-type { font-weight: var(--fw-extrabold); color: var(--txt-primary); }
.bi-bs-counter .bi-bs-dock-row--grand { font-size: var(--fs-lg); }
.bi-bs-counter .bi-bs-dock-row--grand > span:first-child { color: var(--txt-primary); font-weight: var(--fw-extrabold); }

/* 5 · 매출액 / 합계 — 규격안은 «회색 매출액 / 굵은 합계». 폭을 못 받아 10px 로 눌려 있었다. */
.bi-bs-counter .bi-bs-pro-td--total { text-align: right; }
.bi-bs-counter .bi-bs-pro-total-wrap {
    display: flex; align-items: baseline; justify-content: flex-end; gap: var(--space-1_5);
}
.bi-bs-counter .bi-bs-pro-total-wrap .bi-bs-pro-input {
    flex: 0 1 auto; width: 66px; min-width: 0; text-align: right; padding: 0;
    background: none; border: 0;
}
.bi-bs-counter .bi-bs-pro-total-wrap input[name='input_tdesiner[]'] {
    color: var(--txt-disabled); font-size: var(--fs-sm); font-weight: var(--fw-medium);
}
.bi-bs-counter .bi-bs-pro-total-wrap .bi-bs-pro-input--total {
    color: var(--txt-primary); font-size: var(--fs-md); font-weight: var(--fw-extrabold); width: 76px;
}

/* 6 · 세부 분류 — 규격안은 배지가 아니라 상품명 아래 작은 회색 글 */
.bi-bs-counter .bi-bs-pro-td--pro .bi-bs-pro-cat-badge2 {
    display: block; background: none; border: 0; padding: 0; margin-top: var(--space-0_5);
    font-size: var(--fs-xs); font-weight: var(--fw-medium); color: var(--txt-disabled);
    cursor: pointer;
}
.bi-bs-counter .bi-bs-pro-td--pro .bi-bs-pro-cat-badge2:empty { display: none; }
.bi-bs-counter .bi-bs-pro-input--pro { font-weight: var(--fw-bold); }
/* 6-b · 규격안은 분류·상품명이 «왼쪽» 붙임이다. 지금은 가운데라 이름이 안쪽으로 밀려 있었다. */
.bi-bs-counter .bi-bs-pro-th--proc, .bi-bs-counter .bi-bs-pro-td--proc,
.bi-bs-counter .bi-bs-pro-th--pro,  .bi-bs-counter .bi-bs-pro-td--pro { text-align: left; }
.bi-bs-counter .bi-bs-pro-td--pro .bi-bs-pro-input--pro { text-align: left; padding-left: 0; }

/* 6-c · 분류 칸이 150 이라 상품명이 안쪽으로 밀렸다 — 규격안은 배지 하나 폭(70) 이면 된다 */
.bi-bs-counter .bi-bs-pro-th--proc { width: 70px; }
/* 밑줄은 카드 탭에 없다 — 기존 규칙(10318)이 그어 둔 것을 이 화면에서만 끈다 */
.bi-bs-counter .bi-bs-tab-hdr .bi-bs-tab-lbl { border-bottom-color: transparent; box-shadow: none; }
.bi-bs-counter #itab_hist:checked ~ .bi-bs-tab-hdr .bi-bs-tab-lbl[for="itab_hist"],
.bi-bs-counter #itab_pkg:checked  ~ .bi-bs-tab-hdr .bi-bs-tab-lbl[for="itab_pkg"] {
    border-color: var(--border-base); box-shadow: var(--shadow-xs);
}
/* 5-b · «매출액» 과 «/» 를 10367줄에서 display:none 으로 숨겨 두고 있었다 — No. 열과 같은 꼴이다.
   규격안은 「54,000 / 162,000」 둘 다 보여 준다(사용자 5번). 정의는 두고 이 화면에서만 되살린다. */
.bi-bs-counter .bi-bs-pro-total-wrap input[name='input_tdesiner[]'],
.bi-bs-counter .bi-bs-pro-total-wrap .bi-bs-pro-total-sep { display: inline-block; }
/* 5-c · 매출액/합계는 «칸» 이 아니라 «글» 이다(규격안). 공통 입력 스킨이 더 세서 상자로 보였다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-pro-total-wrap input[type="text"].bi-bs-pro-input {
    background: none; border-color: transparent; box-shadow: none; padding: 0; height: auto;
}

/* ═════════════════════════════════════════════════════════════════════════
   §44-3 · 규격안대로 «다시 쓴» 조각들 (2026-09-07)
   ─────────────────────────────────────────────────────────────────────────
   사용자: 「기존 css 디자인 무시좀해 왜 계속 남기는거야 …
            규격안과 실제화면 디자인이 다른데 기존 css 를 그대로 쓰면 당연히 차이가 나지」
   맞다. 여기부터는 «덧칠» 하지 않는다 — 조각마다 필요한 값을 **전부** 다시 적는다.
   (여백·둘레·둥글기·그림자·색을 명시적으로 0/none 으로 되돌린 뒤 규격안 값을 넣는다)
   색은 눈으로 고르지 않고 규격안 그림에서 **뽑아** 썼다 — pick_spec_color.mjs.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── 성별 세그먼트 ── 규격안: 200×48 흰 상자, 고른 쪽이 «절반을 꽉 채운» 네이비.
   전에는 옛 규칙(4964줄)의 height 33 · padding · radius-lg 가 살아 있어
   네이비 알약이 상자 밖으로 삐져나왔다(사용자 2번 「성별 깨지잔아」). */
.bi-counter-wrap.bi-bs-counter .bi-bs-sex-group {
    display: inline-flex; width: 200px; height: 48px; padding: 0; gap: 0;
    background: var(--bg-card); border: 1px solid var(--border-base);
    border-radius: var(--radius-md); overflow: hidden; box-shadow: none;
}
.bi-counter-wrap.bi-bs-counter input[type="radio"].bi-bs-sex-r + label.bi-bs-sex-lbl {
    flex: 1 1 0; width: auto; height: 100%; margin: 0; padding: 0;
    border: 0; border-radius: 0; box-shadow: none; background: var(--bg-card);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--txt-muted);
}
.bi-counter-wrap.bi-bs-counter input[type="radio"].bi-bs-sex-r:checked + label.bi-bs-sex-lbl {
    background: var(--brand-navy); color: var(--bg-card); box-shadow: none;
}

/* ── 매출일자 칩 ── 규격안에서 뽑은 배경 #F8FAFF(= --bg-selected). 32 높이, 날짜만. */
.bi-counter-wrap.bi-bs-counter .bi-erp-toolbar__right .bi-counter-datebar {
    display: inline-flex; align-items: center; gap: var(--space-2);
    height: 32px; width: auto; padding: 0 var(--space-3); margin: 0;
    background: var(--bg-selected); border: 0; border-radius: var(--radius-lg); box-shadow: none;
}
.bi-counter-wrap.bi-bs-counter .bi-counter-datebar__l {
    display: inline-flex; align-items: center; gap: var(--space-2); height: 32px; padding: 0; margin: 0;
}
.bi-counter-wrap.bi-bs-counter .bi-counter-datebar__close {
    display: inline-flex; align-items: center; height: auto; padding: 0; margin: 0;
    background: none; border: 0; border-radius: 0; color: var(--brand-navy); font-size: var(--fs-base);
}
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-datebar-date {
    width: 92px; height: auto; padding: 0; margin: 0; border: 0; background: none; box-shadow: none;
    font-size: var(--fs-md); font-weight: var(--fw-extrabold); color: var(--brand-navy); text-align: left;
}

/* ── 정보 탭 ── 규격안에서 뽑은 트랙 #F3F4F6(= --border-light). 아래 목록 칸은 «흰색». */
.bi-counter-wrap.bi-bs-counter .bi-bs-tab-hdr {
    display: flex; gap: var(--space-1_5); padding: var(--space-1_5);
    background: var(--border-light); border: 0; border-bottom: 1px solid var(--border-base);
}
.bi-counter-wrap.bi-bs-counter .bi-bs-tab-hdr .bi-bs-tab-lbl {
    flex: 1 1 0; height: 40px; margin: 0; padding: 0;
    display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
    background: none; border: 1px solid transparent; border-radius: var(--radius-lg); box-shadow: none;
    font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-muted);
}
.bi-counter-wrap.bi-bs-counter #itab_hist:checked ~ .bi-bs-tab-hdr .bi-bs-tab-lbl[for="itab_hist"],
.bi-counter-wrap.bi-bs-counter #itab_pkg:checked  ~ .bi-bs-tab-hdr .bi-bs-tab-lbl[for="itab_pkg"] {
    background: var(--bg-card); border-color: var(--border-base); color: var(--brand-navy);
    box-shadow: var(--shadow-xs);
}
.bi-counter-wrap.bi-bs-counter .bi-bs-tab-panels { background: var(--bg-card); }

/* ── 결제 대기 열 ── 규격안에서 뽑은 바탕 #FCFCFD. 흰 카드가 그 위에 선다. */
.bi-bs-counter .bi-erp-card > .bi-counter-grid > .bi-counter-col--queue { background: var(--bg-column); }
.bi-bs-counter .bi-counter-queue { gap: var(--space-2_5); padding: var(--space-3); }
.bi-counter-wrap.bi-bs-counter .bi-counter-qcard {
    display: block; width: 100%; margin: 0; padding: var(--space-3) var(--space-3_5);
    background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-lg);
    box-shadow: none; text-align: left; cursor: pointer;
}
.bi-counter-wrap.bi-bs-counter .bi-counter-qcard.is-active {
    border-color: var(--brand-navy); box-shadow: var(--shadow-xs);
}
.bi-bs-counter .bi-counter-qcard__top {
    display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-1);
}
/* 이름 다음의 «상태 점·체크» 는 오른쪽 끝으로 민다(규격안) */
.bi-bs-counter .bi-counter-qcard__top .bi-counter-qname { flex: 1 1 auto; }
.bi-bs-counter .bi-counter-qsub { margin: 0; font-size: var(--fs-xs); color: var(--txt-muted); }

/* ── 시술 및 상품 내역 표 머리 ── 규격안에서 뽑은 바탕 #F9FAFB(= --bg-input) */
.bi-bs-counter .bi-bs-pro-table thead th,
.bi-bs-counter .bi-bs-pro-th { background: var(--bg-input); }

/* ── 접수 · 결제완료 ── 규격안은 «접수 1 : 결제완료 2». 금액이 붙으면 두 줄로 깨졌다(사용자 6번). */
.bi-bs-counter .bi-bs-dock-actions { display: grid; grid-template-columns: 1fr 2fr; gap: var(--space-2_5); }
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-close,
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-pay {
    height: 48px; margin: 0; padding: 0 var(--space-3); white-space: nowrap;
    display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
    border-radius: var(--radius-lg); font-size: var(--fs-md); font-weight: var(--fw-extrabold);
}
.bi-bs-counter .bi-bs-dock-pay #bs_pay_btn_amt { font-weight: var(--fw-extrabold); white-space: nowrap; }

/* ── 판 높이 ── 규격안의 판은 «내용만큼» 이다. 우리는 .bi-erp-card 가 flex:1 1 0 이라
   화면 끝까지 늘어나 내역 아래에 큰 빈 자리가 생겼다(규격안 530 ↔ 실제 942).
   이 화면에서만 내용에 맡긴다. */
.bi-counter-wrap.bi-bs-counter > form > .bi-erp-card,
.bi-bs-counter .bi-erp-card { flex: 0 0 auto; }

/* ── 합계 영역 ── 규격안대로 다시 쓴다(사용자 9번).
   줄은 촘촘하게, 선은 «포인트 적립 뒤» 와 «총 결제 금액 앞» 두 곳만, 총액은 검정. */
.bi-counter-wrap.bi-bs-counter .bi-counter-dock { padding: var(--space-5); gap: var(--space-4); }
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-sum { gap: var(--space-1); }
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-row { min-height: 30px; padding: 0; }
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-divider {
    height: 1px; margin: var(--space-2) 0; background: var(--border-light);
}
.bi-counter-wrap.bi-bs-counter .bi-counter-final {
    border-top: 1px solid var(--border-light); border-bottom: 0;
    padding-top: var(--space-4); margin-top: var(--space-1);
}
.bi-counter-wrap.bi-bs-counter .bi-counter-final-label {
    font-size: var(--fs-lg); font-weight: var(--fw-extrabold); color: var(--txt-primary); text-transform: none;
}
/* 규격안의 총액은 «검정» 이다 — 파랑은 이 화면에서 primary(결제완료) 하나로 족하다(§12 축1) */
.bi-counter-wrap.bi-bs-counter .bi-counter-final-amt { color: var(--txt-primary); }

/* ═════════════════════════════════════════════════════════════════════════
   §44-4 · 규격안 대조 4차 — 사용자가 짚은 아홉 자리 (2026-09-07, bs4.png)
   ═════════════════════════════════════════════════════════════════════════ */

/* 1 · 입력폼이 컸다. 다른 화면과 같은 눈금(.bi-input--md = 40)으로 되돌린다.
   검색 버튼도 40 — §12-5-1 이 POS 에서 40 을 규격으로 두고 있다(사다리 밖이 아니다). */
.bi-bs-counter .bi-counter-cust-body .bi-input--md,
.bi-bs-counter .bi-counter-cust-body .bi-counter-select { height: 40px; }
.bi-bs-counter .bi-counter-cust-body .bi-counter-search-btn {
    flex: 0 0 40px; width: 40px; height: 40px;
}
.bi-counter-wrap.bi-bs-counter .bi-bs-sex-group { height: 40px; }
.bi-bs-counter .bi-counter-cust-body .bi-counter-consult { min-height: 44px; }

/* 2 · 표가 8px 넘쳐 «가로 스크롤» 이 생겼다. 상품명을 줄이고,
   분류와 상품명 사이 여백을 좁히고, 합계와 휴지통을 붙인다. */
.bi-bs-counter .bi-bs-pro-table { table-layout: fixed; width: 100%; }
.bi-bs-counter .bi-bs-pro-th--pro { width: auto; }
.bi-bs-counter .bi-bs-pro-th--proc, .bi-bs-counter .bi-bs-pro-td--proc { padding-right: 0; }
.bi-bs-counter .bi-bs-pro-th--pro, .bi-bs-counter .bi-bs-pro-td--pro { padding-left: var(--space-2); }
.bi-bs-counter .bi-bs-pro-th--total, .bi-bs-counter .bi-bs-pro-td--total { padding-right: var(--space-2); }
.bi-bs-counter .bi-bs-pro-th--del, .bi-bs-counter .bi-bs-pro-td--del { width: 34px; padding: 0; text-align: left; }
.bi-bs-counter .bi-bs-pro-row .bi-bs-pro-del-btn { margin: 0; }

/* 3 · 수단별 금액이 가운데 떠 있었다 — 규격안은 «× 바로 왼쪽» 에 붙는다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-row { justify-content: flex-start; gap: var(--space-2); }
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-row > span:first-child { flex: 1 1 auto; }
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-row > span:last-of-type { margin-left: auto; text-align: right; }

/* 4·5 · 네 버튼은 «같은 높이 48». 결제완료는 금액이 붙어도 안 깨지게 길게. */
.bi-bs-counter .bi-bs-dock-actions { grid-template-columns: 96px 1fr; }
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-btn,
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-btn--recv { height: 48px; }
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-pay { padding: 0 var(--space-2); font-size: var(--fs-base); }

/* 6·7 · 최근 내역 · 보유 정액권 — 규격안은 «카드» 가 아니라 선으로 나눈 줄이다.
   줄 높이를 48 로 맞춰 144 칸에 «세 줄» 이 보인다(규격안과 같은 개수). */
.bi-counter-wrap.bi-bs-counter .bi-bs-info-list { gap: 0; }
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard {
    background: none; border: 0; border-radius: 0; box-shadow: none;
    padding: var(--space-2) var(--space-4); min-height: 48px;
}
.bi-counter-wrap.bi-bs-counter .bi-bs-info-list > li + li { border-top: 1px solid var(--border-light); border-bottom: 0; }
.bi-counter-wrap.bi-bs-counter .bi-bs-info-list > li:first-child { border-bottom: 0; }
.bi-counter-wrap.bi-bs-counter .bi-bs-info-list > li:last-child { border-bottom: 0; }
/* 두 탭의 «더보기 줄» 을 같은 높이·같은 여백으로 — 탭을 바꿔도 아래가 들썩이지 않는다 */
.bi-counter-wrap.bi-bs-counter .bi-bs-pnl-more {
    min-height: 40px; padding: var(--space-2) var(--space-4);
    border-top: 1px solid var(--border-light); margin: 0;
}
.bi-counter-wrap.bi-bs-counter .bi-bs-pkg-sms-btn { height: 27px; }

/* 8 · 최근 내역 ↔ 매출 메모 ↔ 합계 사이의 선 — 굵기·색을 하나로 */
.bi-counter-wrap.bi-bs-counter .bi-bs-info-card > .bi-counter-cust-body {
    border-top: 1px solid var(--border-light); padding: var(--space-3) var(--space-4) var(--space-4);
}

/* 9 · 결제 대기 카드 — 규격안은 두 줄이 넉넉한 72 짜리다(우리는 55 였다) */
.bi-counter-wrap.bi-bs-counter .bi-counter-qcard { min-height: 72px; padding: var(--space-3) var(--space-3_5); }
.bi-bs-counter .bi-counter-qcard__top { margin-bottom: var(--space-1_5); }
/* 3-b · 숫자는 «한 줄로» 오른쪽 끝을 맞춰야 한다. × 는 그 바깥 고정 자리에 둔다
   (값에 padding 을 주는 방식은 × 없는 줄과 8px 어긋났다). */
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-row { position: relative; padding-right: var(--space-6); }
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-row > span:last-of-type { padding-right: 0; }
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-row .bi-bs-dock-x {
    position: absolute; right: 0; top: 50%; transform: translateY(-50%); margin: 0;
}
/* 6·7·8-b · 탭 아래 목록은 규격안에서 «칸 끝까지» 닿는다. .bi-bs-tab-panels 의 padding:20 이
   목록 위·옆·아래에 빈 띠를 만들어 첫 줄이 한참 내려와 있었다. 여백은 «줄» 이 갖는다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-tab-panels { padding: 0; }
.bi-counter-wrap.bi-bs-counter .bi-bs-empty-state { padding: var(--space-6) var(--space-4); }
/* 7-b · 규격안은 144 칸에 «세 줄» 이 보인다(줄 48). 우리 줄은 57 이라 두 줄 반만 보였다. */
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard {
    min-height: 48px; padding: var(--space-1_5) var(--space-4);
    display: flex; flex-direction: column; justify-content: center; gap: 0;
}
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard__top { margin: 0; font-size: var(--fs-2xs); line-height: 1.5; }
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard__name,
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard__amt { font-size: var(--fs-base); line-height: 1.5; }

/* §44-5 · 4차 재확인에서 «수치로» 남아 있던 것 (2026-09-08)
   6 · 「더보기」 줄이 최근 내역 40 · 보유 정액권 44 로 4px 어긋나 있었다.
       패키지문자 버튼(27) + 위아래 여백 8 = 43~44 가 칸을 밀어낸 것.
       여백을 6 으로 줄여 27+6+6 = 39 → 최근 내역과 같은 40 에 들어간다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-pnl-more {
    height: 40px; min-height: 40px; padding: var(--space-1_5) var(--space-4);
}
/* 결제완료 버튼의 금액 — 버튼이 gap 을 갖는데 글에도 ' · ' 를 넣어 사이가 두 배로 벌어져 있었다 */
.bi-bs-counter .bi-bs-dock-pay #bs_pay_btn_amt { margin-left: calc(-1 * var(--space-1)); }
/* 7-c · 이름이 길면 줄이 접혀 48 → 54 로 커졌다(실제 자료: 「펌 > < (실장)컷+다운펌 >」).
   규격안의 줄은 이름이 길어도 한 줄이다 — 말줄임으로 끊고 금액 자리를 지킨다. */
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard__line { gap: var(--space-3); min-width: 0; }
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard__name {
    flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard__amt { flex: 0 0 auto; }
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard__top {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 7-d · 줄이 54 였다 — 머리 22 + 본문 20 + 여백 12. 규격안의 줄은 48 이다.
   내용 높이를 «정해» 둔다: 머리 16 + 본문 20 + 여백 12 = 48. */
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard__top {
    margin: 0; padding: 0; font-size: var(--fs-2xs); line-height: 16px; min-height: 16px;
}
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard__line { line-height: 20px; }
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard__name,
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard__amt { line-height: 20px; }
/* 7-e · 머리가 line-height 16 인데도 17 로 잡혔다(flex 아이템 baseline). 높이를 못박는다. */
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard__top { height: 16px; }

/* §44-6 · 결제 대기 카드를 규격안에 맞춘다 (2026-09-08, 9번 재확인)
   · 상태점이 «맥동» 해서 캡처마다 흐리게 찍혔다 — 규격안은 정지한 진한 빨강이다.
   · 「결제완료」 는 규격안에서 «회색 글 + 초록 체크» 다(초록 굵은 글 + 채운 원이었다).
   · 고른 카드는 옅은 파랑 바탕 + 네이비 테두리(규격안 첫 카드). */
.bi-counter-wrap.bi-bs-counter .bi-counter-qdot {
    width: 7px; height: 7px; background: var(--color-rose-500); animation: none;
}
.bi-counter-wrap.bi-bs-counter .bi-counter-qpaid { color: var(--color-success); font-size: var(--fs-base); }
.bi-counter-wrap.bi-bs-counter .bi-counter-qpaid-txt { color: var(--txt-muted); font-weight: var(--fw-medium); }
.bi-counter-wrap.bi-bs-counter .bi-counter-qcard.is-active {
    background: var(--bg-selected); border-color: var(--brand-navy);
}

/* ═════════════════════════════════════════════════════════════════════════
   §44-7 · 규격안 대조 5차 — 관리자지점(A0000)에서 다시 재서 (2026-09-08)
   ─────────────────────────────────────────────────────────────────────────
   ⚠ 4차까지는 «실서비스 지점» 을 열어 캡처하고 있었다(사용자 지적). 계정 기본값을
      byhwamiju/_admin(관리자지점)으로 바꾸고, 색은 규격안 그림에서 뽑아 옮겼다.
   ═════════════════════════════════════════════════════════════════════════ */

/* 1 · 진행 표시 — 색이 뒤집혀 있었다.
   규격안: 지나온 칸은 «옅은 청회색»(#B5BBD5), 지금 칸만 네이비.
   우리: 지나온 칸이 진한 파랑(#0023B7)이라 지금 칸보다 더 눈에 띄었다. */
.bi-counter-wrap.bi-bs-counter .bi-erp-title__sub .bi-badge {
    width: 20px; height: 20px; min-width: 20px; padding: 0; border: 0; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--brand-navy) 30%, #FFFFFF);
    color: var(--bg-card); font-size: var(--fs-2xs); font-weight: var(--fw-bold);
}
.bi-counter-wrap.bi-bs-counter .bi-erp-title__sub .bi-badge:nth-of-type(3) {
    background: var(--brand-navy);
}
.bi-counter-wrap.bi-bs-counter .bi-erp-title__sub .bi-erp-toolbar__div {
    background: color-mix(in srgb, var(--brand-navy) 25%, #FFFFFF);
}

/* 2 · 연락처는 «더 길게», 성별은 «오른쪽에 붙는다»(규격안). 셋이 균등이었다. */
.bi-bs-counter .bi-counter-cust-body .bi-write-row > .bi-write-field { flex: 1 1 0; min-width: 0; }
.bi-bs-counter .bi-counter-cust-body .bi-write-row > .bi-write-field:nth-child(2) { flex: 1.35 1 0; }
.bi-bs-counter .bi-bs-field--sex { flex: 0 0 200px; margin-left: auto; }

/* 3 · 최근 내역 · 보유 정액권 — 규격안은 탭과 목록이 «둥근 테두리 상자» 하나다.
   우리는 테두리가 없어 판에 그대로 얹혀 있었다(사용자: 「테두리가 있는 형태와 완전히 다르다」). */
.bi-counter-wrap.bi-bs-counter .bi-bs-tab-hdr {
    margin: var(--space-4) var(--space-4) 0; padding: var(--space-1_5);
    border: 1px solid var(--border-base); border-bottom: 0;
    border-radius: var(--radius-xl) var(--radius-xl) 0 0;
}
.bi-counter-wrap.bi-bs-counter .bi-bs-info-list {
    margin: 0 var(--space-4); background: var(--bg-card);
    border: 1px solid var(--border-base); border-top: 0;
    border-radius: 0 0 var(--radius-xl) var(--radius-xl);
}
.bi-counter-wrap.bi-bs-counter .bi-counter-hcard { padding: var(--space-1_5) var(--space-3_5); }
/* 더보기는 상자 «밖» 이다 — 상자가 선을 그으므로 제 선은 지운다 */
.bi-counter-wrap.bi-bs-counter .bi-bs-pnl-more { border-top: 0; }

/* 5 · 결제 대기 카드 — 규격안 카드는 열 안에서 좌우 12 를 두고 선다(우리는 24 라 좁았다) */
.bi-counter-wrap.bi-bs-counter .bi-counter-queue { padding: var(--space-3) var(--space-3); }

/* 6 · 매출일자 — 규격안은 글이 «작고 옅은 남색», 아이콘도 옅다. 우리는 굵고 진해 튀었다. */
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-datebar-date {
    font-size: var(--fs-md); font-weight: var(--fw-bold);
    color: color-mix(in srgb, var(--brand-navy) 78%, #FFFFFF);
}
.bi-counter-wrap.bi-bs-counter .bi-counter-datebar__close {
    color: color-mix(in srgb, var(--brand-navy) 55%, #FFFFFF); font-size: var(--fs-base);
}
/* 5-b · 대기 카드가 201 이었다 — 열(250) 안에서 좌우 25 를 먹고 있었다. 규격안은 12 안팎이다. */
.bi-counter-wrap.bi-bs-counter .bi-counter-col--queue > .bi-counter-queue-box,
.bi-counter-wrap.bi-bs-counter .bi-counter-col--queue .bi-counter-queue { padding-left: var(--space-3); padding-right: var(--space-3); }
.bi-counter-wrap.bi-bs-counter .bi-counter-col--queue .bi-counter-queue-box { padding-left: 0; padding-right: 0; }

/* 4 · 시술 및 상품 내역 — 규격안보다 «줄이 크게» 나왔다(사용자 4번·2번).
   행 57 → 규격안 ~50. 분류 칸이 70 이라 상품명이 배지에서 멀어졌다(규격안은 배지 바로 옆).
   ⚠ 머리는 규격안이 「No.」 — uppercase 로 「NO.」 가 되어 있었다. */
.bi-bs-counter .bi-bs-pro-th { text-transform: none; }
.bi-bs-counter .bi-bs-pro-th--proc, .bi-bs-counter .bi-bs-pro-td--proc { width: 56px; }
.bi-bs-counter .bi-bs-pro-th--pro, .bi-bs-counter .bi-bs-pro-td--pro { padding-left: var(--space-1); }
.bi-counter-wrap.bi-bs-counter .bi-bs-pro-row > .bi-bs-pro-td { padding-top: var(--space-2); padding-bottom: var(--space-2); }

/* ═════════════════════════════════════════════════════════════════════════
   §44-8 · 규격안과 «나란히 놓고» 다시 본 것 (2026-09-08)
   규격안 그림에서 칸 경계를 «가로줄 훑기»(_edge)로 재서 옮겼다.
   ═════════════════════════════════════════════════════════════════════════ */

/* 고객 정보 칸 배분 — 규격안 실측
     첫 줄  고객명그룹 390 : 연락처 376 : 성별 206   (실제는 308 : 372 : 200 이었다)
     둘째 줄 담당디자이너 476 : 방문동향 478 — «반반» (실제는 340 : 480)
   ⚠ 전에 nth-child(2) 로 «둘째 칸» 을 늘렸더니 둘째 줄의 방문 동향까지 늘어났다. */
.bi-bs-counter .bi-counter-cust-body .bi-write-row > .bi-write-field { flex: 1 1 0; min-width: 0; }
.bi-bs-counter .bi-counter-cust-body .bi-write-row:first-of-type > .bi-write-field:first-child { flex: 1.05 1 0; }
.bi-bs-counter .bi-counter-cust-body .bi-write-row:first-of-type > .bi-write-field:nth-child(2) { flex: 1 1 0; }
.bi-bs-counter .bi-bs-field--sex { flex: 0 0 206px; margin-left: auto; }
.bi-counter-wrap.bi-bs-counter .bi-bs-sex-group { width: 206px; }

/* 매출 메모 — 규격안은 칸이 «절반 높이»(56)이고, 라벨 옆에 표시점이 있다.
   우리는 120 이라 아래 합계를 밀어내고 있었다. */
.bi-counter-wrap.bi-bs-counter .bi-counter-memo-ta {
    min-height: 56px; height: 56px; color: var(--txt-muted);
}
.bi-bs-counter .bi-bs-memo-dot {
    display: inline-block; width: 6px; height: 6px; border-radius: 50%;
    background: var(--brand-blue); vertical-align: middle; margin-left: var(--space-1);
}
/* ⚠ 바로 위 규칙이 «특이도에 졌다» — `.bi-bs-counter .bi-counter-cust-body .bi-write-row > .bi-write-field`(0,4,0)
   가 `.bi-bs-counter .bi-bs-field--sex`(0,2,0)를 이겨 성별 칸이 303 으로 늘어났다.
   사용자가 여러 번 말한 «기존 css 에 막히는» 바로 그 꼴이다 → 같은 자리에서 같은 무게로 다시 쓴다. */
.bi-bs-counter .bi-counter-cust-body .bi-write-row > .bi-write-field.bi-bs-field--sex {
    flex: 0 0 206px; margin-left: auto;
}
.bi-bs-counter .bi-counter-cust-body .bi-write-row:first-of-type > .bi-write-field:first-child { flex: 1.04 1 0; }
/* 메모 칸이 56 을 줘도 67 이었다 — 공통 입력 스킨의 padding(2.5)+테두리가 더해진다.
   규격안은 «바깥 높이» 가 56 이다 → box-sizing 기준으로 못박는다. */
.bi-counter-wrap.bi-bs-counter textarea.bi-counter-memo-ta {
    box-sizing: border-box; height: 56px; min-height: 56px; padding: var(--space-2) var(--space-2_5);
}
/* 원래 정의(10279줄)의 `flex: 1` 이 남아 있어 height 56 을 줘도 62.8 로 늘어났다. */
.bi-counter-wrap.bi-bs-counter textarea.bi-counter-memo-ta { flex: 0 0 56px; }

/* ═════════════════════════════════════════════════════════════════════════
   §45 · 매출등록 POS 전용 컴포넌트 — «덧칠» 이 아니라 새로 세운 것 (2026-09-08)
   ─────────────────────────────────────────────────────────────────────────
   사용자 지시: 「기존 css 에 덧칠만 하는 게 아니고 **다르다면 새로 만드는 게 맞아**.
                이건 무조건 이 프로젝트에서 받아들여야 해」

   왜 필요했나: 진행 표시는 `.bi-badge`, 매출일자는 예약 크롬의 `.bi-counter-datebar`,
   결제 대기는 `.bi-counter-qcard`, 목록은 `.bi-counter-hcard` 를 «빌려 쓰고» 있었다.
   그러면 그쪽 규격(색·크기·여백)이 따라와, 덮으려 할 때마다 특이도 싸움이 나고
   한 곳을 맞추면 다른 곳이 어긋났다. 규격안이 요구하는 모습이 다르면 **새 컴포넌트**다.

   색·치수는 규격안 그림(buysell1.png)에서 뽑고 재서 옮겼다 —
   pick_spec_color.mjs(색) · _edge.mjs(칸 경계) · _zoom.mjs(눈으로 확인).
   ═════════════════════════════════════════════════════════════════════════ */

/* ── 진행 표시 ─────────────────────────────────────────────────
   규격안: 지나온 칸 = «옅은 라벤더 원 + 파랑 체크», 지금 칸 = «네이비 원 + 흰 숫자».
   전에는 지나온 칸을 진한 파랑으로 채우고 체크를 흰색으로 둬서 지금 칸보다 튀었고,
   옅게 바꾸자 이번엔 «회색처럼» 보였다 — 체크가 흰색이라 색이 사라진 탓이다. */
.bi-bs-steps {
    display: flex; align-items: center; gap: var(--space-4);
    list-style: none; margin: 0; padding: 0;
}
.bi-bs-step {
    display: inline-flex; align-items: center; gap: var(--space-2);
    font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-muted);
}
.bi-bs-step + .bi-bs-step::before {
    content: ''; width: 22px; height: 1px; margin-right: var(--space-2);
    background: var(--border-base);
}
.bi-bs-step__mark {
    width: 20px; height: 20px; flex: 0 0 20px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: var(--fs-2xs); font-weight: var(--fw-extrabold); line-height: 1;
}
.bi-bs-step.is-done .bi-bs-step__mark {
    background: color-mix(in srgb, var(--brand-blue) 18%, #FFFFFF);
    color: var(--brand-blue);
}
.bi-bs-step.is-done { color: var(--txt-secondary); }
.bi-bs-step.is-now .bi-bs-step__mark { background: var(--brand-navy); color: var(--bg-card); }
.bi-bs-step.is-now { color: var(--txt-primary); font-weight: var(--fw-extrabold); }

/* ── 매출일자 칩 ───────────────────────────────────────────────
   규격안: 옅은 파랑 알약 + 네이비 달력 + 네이비 굵은 날짜. 예약 크롬 datebar 와 다른 물건이다. */
.bi-bs-datechip {
    display: inline-flex; align-items: center; gap: var(--space-2);
    height: 32px; padding: 0 var(--space-3_5);
    background: var(--bg-selected); border-radius: var(--radius-full);
}
.bi-bs-datechip__ico { display: inline-flex; color: var(--brand-navy); font-size: var(--fs-base); }
.bi-counter-wrap input[type="text"].bi-bs-datechip__val {
    width: 92px; height: auto; padding: 0; margin: 0; border: 0; background: none; box-shadow: none;
    font-size: var(--fs-md); font-weight: var(--fw-extrabold); color: var(--brand-navy);
    text-align: left; letter-spacing: -.01em;
}

/* ── 정보 탭바 ─────────────────────────────────────────────────
   규격안: «탭 상자» 와 «목록 상자» 의 테두리가 **나뉘어** 있다(사용자 8번).
   전에는 둘을 이어 붙여 한 상자로 보이게 했는데 규격안과 달랐다. */
.bi-bs-tabbar {
    display: flex; gap: var(--space-1_5);
    margin: var(--space-4) var(--space-4) var(--space-2_5);
    padding: var(--space-1_5);
    background: var(--border-light);
    border: 1px solid var(--border-base); border-radius: var(--radius-xl);
}
.bi-bs-tabbar__t {
    flex: 1 1 0; height: 38px; margin: 0; padding: 0;
    display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
    border: 1px solid transparent; border-radius: var(--radius-lg);
    font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-muted); cursor: pointer;
}
#itab_hist:checked ~ .bi-bs-tabbar .bi-bs-tabbar__t[for="itab_hist"],
#itab_pkg:checked  ~ .bi-bs-tabbar .bi-bs-tabbar__t[for="itab_pkg"] {
    background: var(--bg-card); border-color: var(--border-base); color: var(--brand-navy);
    box-shadow: var(--shadow-xs);
}

/* ── 최근 내역 · 보유 정액권 줄 ────────────────────────────────
   규격안: 「날짜(작은 회색)」 아래 「이름(굵은 검정) … 금액(회색)」. 줄 사이에만 선이 하나.
   전에는 옛 규칙의 border-bottom 과 내가 넣은 border-top 이 겹쳐 «선이 둘» 이었다(사용자 2번). */
.bi-bs-hitem {
    display: flex; flex-direction: column; justify-content: center;
    min-height: 48px; padding: var(--space-1_5) var(--space-4);
    background: none; border: 0; border-radius: 0; box-shadow: none;
}
.bi-bs-hitem + .bi-bs-hitem { border-top: 1px solid var(--border-light); }
.bi-bs-hitem__when {
    height: 16px; font-size: var(--fs-2xs); line-height: 16px; color: var(--txt-disabled);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bi-bs-hitem__row { display: flex; align-items: baseline; gap: var(--space-3); line-height: 20px; }
.bi-bs-hitem__name {
    flex: 1 1 auto; min-width: 0; margin: 0; line-height: 20px;
    font-size: var(--fs-base); font-weight: var(--fw-extrabold); color: var(--txt-primary);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bi-bs-hitem__amt {
    flex: 0 0 auto; margin: 0; line-height: 20px;
    font-size: var(--fs-base); font-weight: var(--fw-medium); color: var(--txt-muted);
    font-variant-numeric: tabular-nums;
}

/* ── 결제 대기 ─────────────────────────────────────────────────
   규격안: 바탕은 «흰색»(사용자 5번), 머리와 카드에 좌우 여백(사용자 6번),
   고른 카드는 «옅은 파랑 + 네이비 테두리». */
.bi-bs-queuecol { background: var(--bg-card); display: flex; flex-direction: column; }
.bi-bs-queue { display: flex; flex-direction: column; height: 100%; }
.bi-bs-queue__head {
    display: flex; align-items: center; justify-content: space-between;
    padding: var(--space-4) var(--space-4) var(--space-3);
}
.bi-bs-queue__title {
    display: inline-flex; align-items: center; gap: var(--space-2);
    font-size: var(--fs-base); font-weight: var(--fw-extrabold); color: var(--txt-primary);
}
.bi-bs-queue__title i { color: var(--color-danger-600); }
.bi-bs-queue__cnt {
    min-width: 22px; height: 22px; padding: 0 var(--space-1_5); border-radius: var(--radius-full);
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--color-danger-50); color: var(--color-danger-600);
    font-size: var(--fs-2xs); font-weight: var(--fw-extrabold);
}
.bi-bs-queue__list {
    display: flex; flex-direction: column; gap: var(--space-2_5);
    padding: 0 var(--space-4) var(--space-4); overflow-y: auto;
}
.bi-bs-qitem {
    display: block; width: 100%; margin: 0; padding: var(--space-3) var(--space-3_5);
    background: var(--bg-card); border: 1px solid var(--border-base); border-radius: var(--radius-lg);
    box-shadow: none; text-align: left; cursor: pointer;
}
.bi-bs-qitem.is-active { background: var(--bg-selected); border-color: var(--brand-navy); box-shadow: var(--shadow-xs); }
.bi-bs-qitem__top { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-1_5); }
.bi-bs-qgrade {
    padding: var(--space-0_5) var(--space-2); border-radius: var(--radius-xs);
    background: var(--border-light); color: var(--txt-muted);
    font-size: var(--fs-2xs); font-weight: var(--fw-extrabold);
}
.bi-bs-qgrade.is-hi { background: var(--color-warning-50); color: var(--color-warning-700); }
.bi-bs-qname { flex: 1 1 auto; font-size: var(--fs-base); font-weight: var(--fw-extrabold); color: var(--txt-primary); }
.bi-bs-qdot { width: 7px; height: 7px; flex: 0 0 7px; border-radius: 50%; background: var(--color-rose-500); }
.bi-bs-qpaid { color: var(--color-success); font-size: var(--fs-base); flex: 0 0 auto; }
.bi-bs-qsub { margin: 0; font-size: var(--fs-xs); color: var(--txt-muted); }
.bi-bs-qpaid-txt { color: var(--txt-muted); font-weight: var(--fw-medium); }
.bi-bs-qempty { padding: var(--space-6) var(--space-4); text-align: center; color: var(--txt-disabled); font-size: var(--fs-sm); }

/* ── 결제 대기의 «두 자리» ──────────────────────────────────────
   같은 화면의 두 모습이다(규격안 A/B). 기준선 1600.
   ⚠ 2026-09-08 — 전용 클래스로 새로 세우면서 옛 이름(.bi-counter-col--queue)에 걸려 있던
      반응형 규칙이 **끊겼다**. 좁은 화면에서 대기열이 맨 아래로 내려가고 카드가 100% 로 늘어났다
      (사용자: 「대기열이 2개인데 가로스크롤이 생기고 길게 늘어졌어」).
      새 컴포넌트를 만들 때는 **옛 이름에 걸려 있던 규칙을 함께 옮겨야** 한다. */
@media (min-width: 1600px) {
    /* 넓은 화면 — 오른쪽 셋째 열. 세로로 쌓아 대기 손님이 여럿 보인다. */
    .bi-bs-counter .bi-erp-card > .bi-counter-grid > .bi-bs-queuecol {
        border-left: 1px solid var(--border-base);
    }
    .bi-bs-queue__list { flex-direction: column; max-height: 620px; }
    .bi-bs-queue__list .bi-bs-qitem { width: 100%; }
}
@media (max-width: 1599px) {
    /* 좁은 화면 — 본문 «맨 위» 가로 띠(규격안 B). 카드는 폭을 고정해 옆으로 늘어선다.
       100% 로 두면 두 장짜리가 화면을 가로질러 길게 늘어난다. */
    .bi-bs-counter .bi-erp-card > .bi-counter-grid > .bi-bs-queuecol {
        order: -1; grid-column: 1 / -1;
        border-left: 0; border-bottom: 1px solid var(--border-base);
    }
    .bi-bs-queue__head {
        justify-content: flex-start; gap: var(--space-2_5);
        padding: var(--space-4) var(--space-5) var(--space-2_5);
    }
    .bi-bs-queue__list {
        flex-direction: row; flex-wrap: nowrap;
        padding: 0 var(--space-5) var(--space-4);
        overflow-x: auto; overflow-y: hidden;
    }
    .bi-bs-queue__list .bi-bs-qitem { flex: 0 0 232px; width: 232px; }
    .bi-bs-qempty { flex: 1 1 auto; padding: var(--space-4); text-align: left; }
}

/* ── 상품 행 : 상품명 · 2차분류 · 수량 ─────────────────────────
   요청 3·4. 규격안(zoom_prow 로 확대해 확인):
     · 상품명은 굵은 검정, **바로 아래** 작은 회색 2차분류(간격 거의 없음)
     · 수량은 «옅은 회색 알약 트랙 + 가운데 흰 칸» — 테두리 있는 흰 상자가 아니다
     · 단가는 굵지 않은 중간 굵기 */
.bi-bs-counter .bi-bs-proname {
    font-size: var(--fs-md); font-weight: var(--fw-extrabold); color: var(--txt-primary);
    line-height: 20px; height: 20px; padding: 0; margin: 0;
}
.bi-bs-counter .bi-bs-prosub {
    display: block; margin: 0; padding: 0;
    font-size: var(--fs-2xs); line-height: 16px; color: var(--txt-disabled); font-weight: var(--fw-medium);
    background: none; border: 0; cursor: pointer;
}
.bi-bs-counter .bi-bs-prosub:empty { display: none; }

.bi-bs-counter .bi-bs-qtybox {
    display: inline-flex; align-items: center; gap: 0;
    height: 30px; padding: var(--space-0_5);
    background: var(--bg-input); border: 0; border-radius: var(--radius-full); box-shadow: none;
}
.bi-counter-wrap.bi-bs-counter .bi-bs-qtybox .bi-bs-pro-qty-btn {
    width: 26px; height: 26px; border: 0; background: none; border-radius: var(--radius-full);
    color: var(--txt-muted); font-size: var(--fs-xs);
}
.bi-counter-wrap.bi-bs-counter .bi-bs-qtybox .bi-bs-pro-qty-btn:hover { background: var(--border-light); color: var(--txt-primary); }
.bi-counter-wrap.bi-bs-counter .bi-bs-qtybox input[type="text"].bi-bs-pro-input--qty {
    width: 32px; height: 26px; padding: 0; text-align: center;
    background: var(--bg-card); border: 0; border-radius: var(--radius-sm); box-shadow: none;
    font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-primary);
}
/* 단가는 규격안에서 «진한 검정» 이다 — 회색으로 낮췄던 것을 되돌린다 */
.bi-counter-wrap.bi-bs-counter .bi-bs-pro-td--price input[type="text"].bi-bs-pro-input {
    font-weight: var(--fw-medium); color: var(--txt-primary);
}
/* 진행 표시가 규격안(213)보다 286 으로 넓었다 — 칸 사이와 연결선이 길었다. */
.bi-bs-steps { gap: var(--space-2_5); }
.bi-bs-step { font-size: var(--fs-sm); gap: var(--space-1_5); }
.bi-bs-step + .bi-bs-step::before { width: 14px; margin-right: var(--space-2_5); }
.bi-bs-step__mark { width: 18px; height: 18px; flex: 0 0 18px; }
/* 상품명 입력이 공통 입력 스킨의 높이(36)를 물고 있어 2차분류가 아래로 밀렸다 —
   규격안은 이름 20 + 분류 16 = 36 이 «두 줄» 로 붙는다. */
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-proname { height: 20px; min-height: 0; }

/* ═════════════════════════════════════════════════════════════════════════
   §45-2 · 요청 열 자리 (2026-09-08) — 번호 순서대로
   ═════════════════════════════════════════════════════════════════════════ */

/* 1 · 매출일자 글자가 «크고 색이 진했다». 규격안은 13 · 조금 옅은 남색이다. */
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-datechip__val {
    font-size: var(--fs-base); font-weight: var(--fw-bold); width: 84px;
    color: color-mix(in srgb, var(--brand-navy) 85%, #FFFFFF);
}
.bi-bs-datechip__ico { font-size: var(--fs-sm); color: color-mix(in srgb, var(--brand-navy) 70%, #FFFFFF); }
.bi-bs-datechip { height: 30px; padding: 0 var(--space-3); }

/* 2 · 전표번호 — 새 전표 «왼쪽» 에 선다(마크업에서 옮겼다) */
.bi-bs-counter .bi-erp-toolbar__right .bi-bs-keyindex-badge:empty { display: none; }

/* 3 · 카드 제목이 «너무 진했다»(fw 900). 규격안은 한 단 아래다 — 글꼴은 그대로 두고 굵기만. */
.bi-counter-wrap.bi-bs-counter .bi-counter-card__title { font-weight: var(--fw-extrabold); color: var(--txt-primary); }
.bi-counter-wrap.bi-bs-counter .bi-counter-card__title--lg { font-size: var(--fs-md); }

/* 4 · 표 머리 글자가 11 로 작았다 — 규격안은 본문과 같은 눈금(12)이다. */
.bi-bs-counter .bi-bs-pro-th { font-size: var(--fs-sm); font-weight: var(--fw-bold); }

/* 5 · «매출액 / 합계» 칸이 좁아 숫자가 붙어 보였다 — 규격안 실측 폭에 맞춘다. */
.bi-bs-counter .bi-bs-pro-th--total, .bi-bs-counter .bi-bs-pro-td--total { width: 196px; }
.bi-bs-counter .bi-bs-pro-total-wrap { gap: var(--space-2_5); }
.bi-bs-counter .bi-bs-pro-total-wrap .bi-bs-pro-input { width: 76px; }
.bi-bs-counter .bi-bs-pro-total-wrap .bi-bs-pro-input--total { width: 86px; }

/* 6 · 목록 상자 «위쪽 테두리가 끊겨» 보였다 — 탭 상자와 목록 상자 사이가 벌어져
   목록의 border-top 을 0 으로 둔 것이 그대로 드러났다. 목록도 «닫힌 상자» 로 만든다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-info-list {
    border-top: 1px solid var(--border-base);
    border-radius: var(--radius-xl);
}

/* 7 · 매출 메모 «위» 구분선은 규격안에 없다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-memobox { border-top: 0; }

/* 8 · 합계 금액이 오른쪽 끝에서 «안쪽으로» 들어와 있었다 — × 자리만큼 줄을 좁혀 둔 탓.
   × 는 줄 위에 겹쳐 놓고, 숫자는 오른쪽 끝에 붙인다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-row { padding-right: 0; }
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-row .bi-bs-dock-x { right: calc(-1 * var(--space-5)); }

/* 10 · 매출 메모 아래(= 합계 위) 구분선이 «전체 줄» 이었다. 규격안은 좌우가 떨어져 있다. */
.bi-counter-wrap.bi-bs-counter .bi-counter-dock { border-top: 0; }
.bi-counter-wrap.bi-bs-counter .bi-counter-dock::before {
    content: ''; display: block; height: 1px; margin: 0 var(--space-5) var(--space-4);
    background: var(--border-light);
}

/* 9 · 좁은 화면에서 대기열 왼쪽에 «세로선이 하나 더» 그어져 굵어 보였다.
   공통 규칙(.bi-counter-col + .bi-counter-col)이 여전히 걸리고, 내가 또 그었다. 하나만 남긴다. */
@media (max-width: 1599px) {
    .bi-bs-counter .bi-erp-card > .bi-counter-grid > .bi-bs-queuecol,
    .bi-bs-counter .bi-erp-card > .bi-counter-grid > .bi-counter-col + .bi-bs-queuecol {
        border-left: 0;
    }
}

/* 11 · 보유 정액권 — 「회수권」 과 「잔여 7회 / 10회」 가 붙어 있었다. 사이를 벌린다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-hitem__when {
    display: flex; align-items: center; gap: var(--space-2_5);
}
.bi-counter-wrap.bi-bs-counter .bi-bs-hitem__when > strong { font-weight: var(--fw-extrabold); color: var(--txt-muted); }

/* 12 · 줄이 하나든 둘이든 «아래 구분줄» 이 있어야 한다(사용자 요청).
   전에는 줄 «사이» 에만 그어 마지막 줄 아래가 비어 있었다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-info-list > .bi-bs-hitem { border-bottom: 1px solid var(--border-light); }
/* 사용자 요청 12: «1개든 2개든 아래 구분줄» — 마지막 줄에도 긋는다 */
.bi-counter-wrap.bi-bs-counter .bi-bs-hitem + .bi-bs-hitem { border-top: 0; }
/* 8-b · × 를 줄 «바깥» 으로 밀었더니 열 경계에 걸렸다. 규격안은 × 가 «줄 안 오른쪽 끝» 이고
   금액은 그 왼쪽이다 — × 없는 줄의 금액만 끝까지 간다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-row .bi-bs-dock-x { right: 0; }
/* × 폭 17 + 숨 7 = 24(--space-6) — 25 는 여백 눈금 밖이다 */
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-row.is-on > span:last-of-type { margin-right: var(--space-6); }

/* ═════════════════════════════════════════════════════════════════════════
   §45-3 · 요청 여섯 자리 (2026-09-08) — 번호 순서대로
   ⚠ 3·4 는 «또 특이도에 졌다» — `.bi-bs-info-card > .bi-counter-cust-body`(0,3,0)와
     `.bi-counter-card`(카드 계열)가 내 `.bi-bs-memobox`(0,2,0)·`.bi-counter-dock`(0,2,0)를 이겨
     지웠다고 한 선이 그대로 남아 «선이 둘» 이었다. 같은 무게로 다시 쓴다.
   ═════════════════════════════════════════════════════════════════════════ */

/* 1 · 매출일자 글자색 — 규격안에서 뽑으니 #00156E(네이비)였다. 옅게 만든 것이 틀렸다. */
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-datechip__val { color: var(--brand-navy); }
.bi-counter-wrap.bi-bs-counter .bi-bs-datechip__ico { color: var(--brand-navy); }

/* 2 · 분류 칸이 56 이라 «3글자만 넘어도» 상품명과 겹쳤다. */
.bi-bs-counter .bi-bs-pro-th--proc, .bi-bs-counter .bi-bs-pro-td--proc { width: 84px; }
.bi-bs-counter .bi-bs-pro-cat-badge { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 3 · 매출 메모 위·아래 선이 «영역 전체» 였다. 규격안은 총 결제 금액 위 선처럼 «좌우가 떨어진» 선이다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-info-card > .bi-counter-cust-body.bi-bs-memobox {
    border-top: 0; position: relative;
}
.bi-counter-wrap.bi-bs-counter .bi-bs-memobox::before {
    content: ''; position: absolute; left: var(--space-5); right: var(--space-5); top: 0;
    height: 1px; background: var(--border-light);
}

/* 4 · 총 합계 위에 «선이 하나 더» 있었다 — 도크 자신의 border-top 과 내가 넣은 ::before 가 겹쳤다. */
.bi-counter-wrap.bi-bs-counter .bi-counter-card.bi-counter-dock { border-top: 0; }

/* 5 · 목록은 «줄마다» 구분선이고, 1개든 2개든 마지막 줄 아래에도 긋는다(사용자 요청).
   앞서 border-top 을 0 으로 돌리면서 줄 사이가 비어 버렸다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-info-list > li.bi-bs-hitem {
    border-top: 0; border-bottom: 1px solid var(--border-light);
}

/* 6 · × 가 네모 테두리 «가운데» 에 있지 않았다 — 글자 기준선 때문이다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-x {
    display: none; line-height: 1; padding: 0; font-size: var(--fs-2xs);
}
.bi-counter-wrap.bi-bs-counter .bi-bs-dock-row.is-on .bi-bs-dock-x {
    display: inline-flex; align-items: center; justify-content: center;
}
/* 4-b · 도크의 선을 그리던 것은 «우측 열의 형제 사이 선»(12175줄, 0,4,0)이었다.
   같은 무게로 되돌린다 — 규격안의 선은 도크 안쪽 ::before 하나뿐이다. */
.bi-bs-counter .bi-erp-card > .bi-counter-grid > .bi-counter-col:not(:first-child) > .bi-counter-dock {
    border-top: 0;
}
/* 3-b · 두 구분선의 «길이와 여백» 이 달랐다(사용자 재지적).
   메모 선은 상자 안 좌우 20, 도크 선은 padding 20 + margin 20 = 40 이라 40px 짧았고,
   선 아래 여백도 12 / 16 으로 갈렸다. 둘을 «같은 방식» 으로 놓는다 —
   상자 맨 위에 붙이고, 좌우 20, 아래 16. */
.bi-counter-wrap.bi-bs-counter .bi-bs-memobox { padding-top: var(--space-4); }
.bi-counter-wrap.bi-bs-counter .bi-counter-dock {
    position: relative; padding-top: var(--space-4);
}
.bi-counter-wrap.bi-bs-counter .bi-counter-dock::before {
    position: absolute; top: 0; left: var(--space-5); right: var(--space-5);
    margin: 0; height: 1px; background: var(--border-light);
}
/* 3-c · 선 아래 여백이 메모 12 / 도크 16 으로 갈렸다(라벨 글자상자 차이). 메모 쪽을 4 더한다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-memobox { padding-top: var(--space-5); }
/* 2-b · 상품명이 2차분류보다 «오른쪽으로 들여쓰기» 되어 있었다 —
   상품명은 input(좌우 padding 있음), 2차분류는 span(없음)이라 왼쪽 끝이 어긋났다. */
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-proname { padding-left: 0; padding-right: 0; }
/* 3-d · 또 특이도에 졌다 — `.bi-bs-info-card > .bi-counter-cust-body`(0,4,0) 의 padding 이
   내 `.bi-bs-memobox`(0,3,0) 를 이겨 선 아래 여백이 12 로 남았다. 같은 무게로 다시. */
.bi-counter-wrap.bi-bs-counter .bi-bs-info-card > .bi-counter-cust-body.bi-bs-memobox {
    padding: var(--space-5) var(--space-5) var(--space-4);
}

/* ── 추가 요청 (2026-09-08) ──
   · 매출일자 글자색: 규격안 그림에서 뽑으면 #00156E(네이비)지만, 사용자가 두 번
     「계속 네이비색이야 / 왜 파랑색이야」 라고 했다. **사용자 지시가 규격안 그림보다 앞선다** —
     색을 빼고 기본 글자색으로 둔다(칩 배경이 이미 «날짜 자리» 를 말해 준다).
   · 최근 내역·보유 정액권 목록 칸을 «조금 더 길게» — 3줄(144) → 4줄(192). */
.bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-datechip__val { color: var(--txt-primary); }
.bi-counter-wrap.bi-bs-counter .bi-bs-datechip__ico { color: var(--txt-muted); }
.bi-bs-info-card .bi-bs-info-list { flex: 0 0 192px; height: 192px; }
/* 목록 칸을 192 로 늘리자 줄이 48 → 49 가 됐다(4줄 + 마지막 구분선 1px 을 나눠 가짐).
   줄 높이는 규격안 값이므로 고정한다 — 늘어난 칸은 남는 자리로 둔다. */
.bi-counter-wrap.bi-bs-counter .bi-bs-info-list > li.bi-bs-hitem { flex: 0 0 auto; height: 48px; }
/* 보유 정액권 줄은 «세 줄» 이다(분류/잔여 · 상품명 · 유효기간).
   최근 내역(두 줄)에 맞춰 높이를 48 로 못박았더니 세 번째 줄이 넘쳐 상품명을 가렸다.
   → 정액권 목록만 내용에 맡긴다. */
.bi-counter-wrap.bi-bs-counter #package_olist > li.bi-bs-hitem {
    height: auto; min-height: 48px; padding: var(--space-2_5) var(--space-4);
}
.bi-counter-wrap.bi-bs-counter #package_olist .bi-bs-hitem__name { line-height: 20px; }
.bi-counter-wrap.bi-bs-counter .bi-bs-vcard-date {
    margin: 0; font-size: var(--fs-2xs); line-height: 16px; color: var(--txt-disabled);
}

/* ═════════════════════════════════════════════════════════════════════════
   §45-4 · POS 계열 세 화면을 «한 규격» 으로 (2026-09-08)
   매출등록(buysell) · 예약등록(booking_buysell) · 입고등록(report_buy_appear)
   셋 다 `.bi-counter-wrap.bi-bs-counter` 를 쓰므로 §45 컴포넌트가 그대로 걸린다.
   다른 것은 «대기 열이 있느냐» 뿐이다 — 입고등록에는 대기가 없다(사용자 확인).
   ═════════════════════════════════════════════════════════════════════════ */

/* 대기 열이 «없는» 화면은 두 칸으로 — 250 자리를 비워 두면 본문이 그만큼 좁아진다. */
@media (min-width: 1600px) {
    .bi-bs-counter .bi-erp-card > .bi-counter-grid { grid-template-columns: minmax(0, 1fr) 350px; }
    .bi-bs-counter .bi-erp-card > .bi-counter-grid:has(> .bi-bs-queuecol) {
        grid-template-columns: minmax(0, 1fr) 350px 250px;
    }
}
/* 예약·입고의 메모 상자는 «탭 카드 밖» 이라 매출등록용 규칙(.bi-bs-info-card > …)이 안 걸렸다.
   세 화면을 한 규격으로 두려면 상자 자신을 기준으로 써야 한다. */
.bi-counter-wrap.bi-bs-counter .bi-counter-cust-body.bi-bs-memobox {
    border-top: 0; position: relative;
    padding: var(--space-5) var(--space-5) var(--space-4);
}
/* 메모 상자가 열의 «직접 자식» 인 화면(예약·입고)에서는
   `.bi-counter-col:not(:first-child) > * + *`(0,5,0 — :not 이 무게를 올린다)가 이긴다.
   매출등록의 도크에 했던 것과 같은 모양으로 되돌린다. */
.bi-bs-counter .bi-erp-card > .bi-counter-grid > .bi-counter-col:not(:first-child) > .bi-bs-memobox {
    border-top: 0;
}
/* 예약 메모만 라벨↔칸 사이가 16 이었다(매출·입고는 6) — 예약 화면의 다른 gap 규칙이 걸린 탓.
   메모 상자는 세 화면이 같아야 한다. */
.bi-counter-wrap.bi-bs-counter .bi-counter-cust-body.bi-bs-memobox { gap: var(--space-1_5); }

/* 예약등록 «자동계산» 칸 — 고객 정보 셋째 자리(매출등록의 성별 자리와 같은 줄).
   체크 + 계산된 시간 + 도움말이 한 줄에 선다. */
.bi-bs-counter .bi-bs-field--auto { flex: 0 0 206px; }
.bi-bs-counter .bi-bs-autocalc {
    display: flex; align-items: center; gap: var(--space-2); height: 40px;
}
.bi-bs-counter .bi-bs-autocalc #action_p_time { font-size: var(--fs-base); color: var(--txt-secondary); }
/* .bi-row--gap-* 는 «토큰» 방식이다(1791줄 --bi-row-gap) — 그 규격을 따른다 */
.bi-row--gap-8 { --bi-row-gap: 8px; }

/* 예약등록 둘째 줄 — 담당 디자이너가 228 로 좁았다(셋이 균등 분배).
   매출등록의 첫 줄과 같은 비율로: 디자이너그룹 366 : 예약시간 352 : 자동계산 206. */
.bi-bs-counter .bi-counter-cust-body .bi-write-row:nth-of-type(2) > .bi-write-field:first-child { flex: 1.04 1 0; }
.bi-bs-counter .bi-counter-cust-body .bi-write-row:nth-of-type(2) > .bi-write-field:nth-child(2) { flex: 1 1 0; }
.bi-bs-counter .bi-counter-cust-body .bi-write-row > .bi-write-field.bi-bs-field--auto { flex: 0 0 206px; }
/* 입고등록 «주소» 칸 — 둘째 줄에서 연락처보다 넓다(주소는 길다). */
.bi-bs-counter .bi-counter-cust-body .bi-write-row > .bi-write-field.bi-bs-field--addr { flex: 2 1 0; }

/* =========================================================
   §46 AI 메시지 발송 (ai_marketing) — 2026-09-08 신설
   ---------------------------------------------------------
   왜 새 절인가: 이 화면은 «조건을 골라 → 문구를 만들고 → 대상에게 보낸다» 는
   3단 작업 화면이라 §40-3 표준 목록도 §40-4 예외 레이아웃도 아니다.
   규격안은 renew_crm/ai_spec.html · 목업은 tools/qc/spec_ai/ 에 있다.

   ⚠ 기존 클래스를 고치지 않았다(§4). 겉껍데기만 새로 만들고
     조건 칩은 기존 .bi-chip--opt 에 .bi-ai-ch 를 «덧입힌다» —
     script.js 가 .bi-chip--opt 와 .is-selected 로 잡기 때문이다.

   ⚠ 규격안에 없는 것은 여기에도 없다: 두피/손상도 열, 치환 태그 #두피상태.
     현행 DB 부재 확정(60_part §6-1).
   ========================================================= */

/* ── §46-1 카드 머리 — 아이콘 · 제목 · 부제가 «한 줄» ──────────
   왜 새 조각인가: 지금 화면은 제목과 부제가 두 줄로 쌓여 머리가 두껍다.
   규격안은 「아이콘 | 제목 · 부제」 가 한 줄이고, 오른쪽 끝에 버튼이 붙는다. */
.bi-ai-hd__ico {
    width: 30px; height: 30px; flex: 0 0 30px;
    display: flex; align-items: center; justify-content: center;
    border-radius: var(--radius-md);
    /* ⚠ 첨부 규격안의 아이콘은 «색이 없다» — 연회색 상자에 회색 획이다(2026-09-09 확대해 확인).
       파랑을 칠하면 제목보다 아이콘이 먼저 눈에 들어와 머리가 시끄러워진다. */
    background: var(--gray-100);
    color: var(--txt-secondary);
    font-size: var(--fs-md);
}
/* 부제는 제목 오른쪽에 «· » 를 달고 붙는다 — 줄을 새로 먹지 않는다 */

/* ── §46-2 일반 조건 검색 — 한 줄 세 칸 ───────────────────── */

/* ── §46-3 스마트 타겟검색 — 네 상자를 «가로 한 줄» 로 ────────
   ⚠ 2×2 가 아니다. 첨부 규격안은 네 상자가 한 줄에 나란히 서고,
     상자 «안» 에서 칩이 두 줄로 접힌다. */

/* 조건 칩 — 고르면 네이비로 «칠한다»(테두리만 바뀌면 눈에 안 띈다) */
/* 조건마다 대상 인원 — 조회를 더해야 채워진다(자리는 규격이 먼저 잡는다) */

/* ── §46-5 AI 메시지 카드 ─────────────────────────────────
   ⚠ 버튼 셋은 머리 오른쪽이 아니라 «머리 아래 왼쪽» 이다(첨부 규격안).
     치환 태그는 «석 장» 뿐 — #두피상태 는 값이 없어 규격안에서 뺐다. */
/* ⚠ 2026-09-09 — 여기서 .bi-ai-acts 를 «뺐다».
   치환 태그 줄과 한 묶음으로 두었더니 padding:12px 0 이 버튼 줄에도 딸려가
   머리가 계속 넓어 보였다(사용자가 세 번 지적했다). 버튼 줄은 아래 §46-16 에서 따로 정한다. */   /* LMS 배지를 오른쪽 끝으로 */
.bi-ai-tag {
    display: inline-flex; align-items: center; gap: var(--space-1);
    height: 24px; padding: 0 var(--space-2);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-sm);
    background: var(--bg-input);
    font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--txt-secondary);
}
.bi-ai-tag i { font-size: var(--fs-2xs); color: var(--txt-muted); }
.bi-ai-lms {
    display: inline-flex; align-items: center; height: 24px; padding: 0 var(--space-2_5);
    border-radius: var(--radius-sm);
    background: var(--brand-blue-light); color: var(--brand-blue);
    font-size: var(--fs-sm); font-weight: var(--fw-semibold);
}
.bi-ai-len {
    display: inline-flex; align-items: center; height: 24px; padding: 0 var(--space-2_5);
    border: 1px solid var(--border-base); border-radius: var(--radius-sm);
    background: var(--bg-input);
    font-size: var(--fs-sm); color: var(--txt-muted);
    font-variant-numeric: tabular-nums;
}
.bi-ai-len b { color: var(--txt-primary); font-weight: var(--fw-semibold); }

/* ── §46-6 발송 대상 목록 ─────────────────────────────────
   ⚠ 두피/손상도 열은 없다 — 현행 DB 부재 확정(60_part §6-1). */
/* 고른 줄을 칠한다 — 체크박스 상태로 잡으면 script.js 에 손댈 일이 없다 */
.bi-ai-cust__top { display: flex; align-items: center; gap: var(--space-1_5); }
/* ⚠ 차트번호와 시술일자를 «한 줄로 묶으려다» 이 배지 규칙에 붙어버렸다(2026-09-08).
   차트번호가 등급 배지 옷(10px 알약)을 먹어 답안지가 잡았다 — 묶지 않고 따로 둔다. */
.bi-ai-grade {
    display: inline-flex; align-items: center; height: 18px; padding: 0 var(--space-1_5);
    border-radius: var(--radius-sm);
    font-size: var(--fs-2xs); font-weight: var(--fw-bold);
    background: var(--gray-100); color: var(--gray-600);
}
.bi-ai-grade--vvip { background: var(--color-purple-50); color: var(--color-purple-600); }
.bi-ai-grade--vip  { background: var(--brand-blue-light); color: var(--brand-blue); }
/* ⚠ 「우수」 등급과 「발송가능」 상태는 «같은 초록» 이다 — 아래 한 곳에서 함께 정한다(SPEC-DUP) */
.bi-ai-tel       { font-size: var(--fs-md); font-weight: var(--fw-semibold); font-variant-numeric: tabular-nums; }
.bi-ai-last__nm  { font-size: var(--fs-md); font-weight: var(--fw-semibold);
                   overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 차트번호와 시술일자는 같은 옷이다 — 따로 적으면 한쪽만 바뀌어 어긋난다.
   ⚠ 등급 배지 규칙 «바로 앞» 에 붙이지 않는다. 전에 그랬다가 차트번호가 배지 옷을 먹었다. */
.bi-ai-cust__no,
.bi-ai-last__dt  { font-size: var(--fs-sm); color: var(--txt-muted); font-variant-numeric: tabular-nums; }
.bi-ai-state {
    display: inline-flex; align-items: center; height: 24px; padding: 0 var(--space-2_5);
    border-radius: var(--radius-full);
    font-size: var(--fs-sm); font-weight: var(--fw-semibold);
}
/* 「우수」 등급 배지와 「발송가능」 상태 배지는 같은 초록을 쓴다 — 따로 적으면 한쪽만 바뀌어 어긋난다 */
.bi-ai-grade--good,
.bi-ai-state--ok   { background: var(--color-success-50); color: var(--color-success-700); }

/* 보내기 줄 — 목록 아래 한 줄(지금은 버튼만 왼쪽 아래에 덩그러니 있다) */

/* ⚠ 좌우 배치는 기존 .bi-camp__cols 가 이미 하고 있다 —
   새로 만들면 «쓰이지 않는 규격» 이 된다(SPEC-DEAD). 목업에만 남긴다. */

/* ── §46-7 실물에서 잡은 것 (2026-09-08 캡처를 눈으로 보고) ──────────────
   ⚠ .bi-hidden 은 «.bi-hidden { display:none }» 한 줄(0,1,0)이라
     .bi-ai-basic / .bi-ai-segs 의 display:grid(같은 0,1,0, 뒤에 옴)에 진다.
     같은 «모양» 으로 다시 적어 이긴다 — 짧게 적으면 또 진다(4번 겪은 함정). */

/* 「전체 선택」 네모가 둘로 보이던 것 — 전역 PNG 체크박스의 +label 이 남아서다.
   label 은 script.js 가 for 재지정에 쓰므로 DOM 에서 빼지 않고 «가리기만» 한다.
   (§17 보완과 같은 손질) */
/* ⚠ 이름을 .bi-ai-selall 로 바꿨다 — 옛 .bi-camp__selectall 규칙은 더 이상 매치되지 않는다.
   전역 «input[type=checkbox] + label» PNG 박스가 되살아나 네모가 둘로 보였다.
   label 은 script.js 가 for 재지정에 쓰므로 DOM 에서 빼지 않고 가리기만 한다(§17 보완과 같은 손질). */
.bi-ai-selall label { display: none; }

/* 표가 카드 벽에 닿지 않게 — 목록 카드는 머리·표·보내기 줄이 한 몸이다 */

/* ── §46-8 목록 표 손질 (2026-09-08 채워진 화면을 눈으로 보고) ──────────
   ⚠ 행마다 네모가 «두 개» 로 보였다 — 전역 PNG 체크박스의 +label 이 남아서다.
     label 은 script.js 가 for 재지정에 쓰므로 DOM 에서 빼지 않고 가리기만 한다(§17 보완과 같은 손질). */

/* 보내기 줄이 표에 밀려 카드 밖으로 나가던 것 — 카드를 세로 flex 로 세워 맨 아래에 붙인다.
   ⚠ 기존 .bi-camp__audience 를 덧칠하지 않는다(§4) — 뷰에 새 이름을 «덧입힌다». */

/* 조건 칩 높이 28 은 «상자 전체» 기준이다 — 테두리가 밖으로 붙어 30 이 되던 것(2026-09-08 답안지가 잡았다) */

/* ── §46-0 페이지 골격 ─────────────────────────────────────
   ⚠ 규격안에는 «바깥 카드» 가 없다. 조건 카드 / AI 카드 / 목록 카드 셋이 나란히 설 뿐이다.
     지금 화면은 .bi-page > .bi-erp-card 안에 카드 셋을 또 넣어 «상자 안 상자» 였다. */
/* ⚠ .bi-erp-card 는 flex:1 이라 «남는 자리를 다 먹는다» — 조건 카드 아래에 225px 빈 공간이 생겼다.
   여기서는 내용만큼만 서야 한다(2026-09-08 실물을 재서 잡았다). */

/* 좌우 배치 — 왼쪽 AI 메시지 : 오른쪽 대상 목록 (규격안 ≈ 41 : 59) */
/* 좌우 두 카드는 서로 키를 맞춘다 — 한쪽이 길면 다른 쪽도 따라 선다 */

/* AI 메시지 사용 방법 — 카드 맨 아래 도움말 */

/* 「전체 선택」 묶음 — 옛 .bi-camp__selectall 을 대신한다(§4: 기존 클래스를 고치지 않는다) */
/* 가로 한 줄 묶음 — 전체선택 · 미리보기 바닥 */
.bi-ai-selall,
.bi-ai2-mfoot__l { display: flex; align-items: center; gap: var(--space-2); }
.bi-ai-selall label { display: none; }   /* 전역 PNG 체크박스의 +label — 네모가 둘로 보인다 */

/* styleguide2 전시용 — §46-0 골격을 «보이게» 하는 문서 전용 상자(화면 규격이 아니다) */
.sg2doc-aiframe { gap: var(--space-2); }
.sg2doc-aibox   { padding: var(--space-3); font-size: var(--fs-sm); color: var(--txt-secondary); }

/* ── §46-9 화면 높이에 맞춘다 (2026-09-09) ────────────────────────────
   사용자: 「AI 메시지 생성, 발송대상 고객목록이 화면 해상도를 벗어나 길게 되어
            AI 메시지 사용방법이나 리스트가 길경우 화면에서 짤려 안보여.
            발송대상고객목록은 스크롤이 생기는게 맞아」
   .bi-page 가 이미 height:calc(100vh - 헤더) + overflow:hidden 이다.
   그런데 아래 두 카드가 «내용만큼» 커져 판 밖으로 밀려 나갔다 —
   그래서 사용 방법과 마지막 줄이 잘렸다. 남은 높이를 채우고 «안에서» 스크롤한다. */

/* AI 메시지 카드 — 본문이 길면 카드 안에서 스크롤(사용 방법이 잘리지 않게) */

/* 발송 대상 목록 — 표만 스크롤한다. 머리와 보내기 줄은 늘 보인다. */

/* ── §46-10 발송 대상 목록 바탕 (2026-09-09) ──────────────────────────
   사용자: 「발송대상고객목록 리스트도 바탕색등 변경해줘」
   .bi-datatbl(공용 표)의 옛 배경·줄무늬가 함께 묻어 첨부와 달랐다.
   .bi-ai-tbl 안에서만 다시 정한다 — 공용 .bi-datatbl 은 건드리지 않는다(§4). */
/* 표 자체 배경은 적지 않는다 — 카드가 이미 흰색이다(적으면 다른 규격과 «같은 선언» 이 된다) */
/* 고른 줄만 옅은 파랑 — 첨부에서 선택 행이 눈에 띈다 */
/* 공용 표의 줄무늬·안쪽 배경이 새어 들어오지 않게 — 같은 «모양» 으로 다시 적는다 */

/* ── §46-11 배경 층 (2026-09-09) ──────────────────────────────────────
   사용자: 「첨부이미지는 배경색이 있는부분이 규격안에선 다빠젔어. 밋밋해 구분도 안되고」
   첨부를 재 보니 «머리에만» 옅은 층이 있었다(머리 #F9FBFD · 본문 #FBFCFD · 판 #F3F4F6).
   층이 없으면 제목·버튼 영역과 내용 영역이 한 덩어리로 보인다. */

/* 머리가 두 줄인 경우(AI 메시지 생성) — 제목 줄 아래에 버튼 줄이 «같은 층» 안에 온다.
   첨부에서 버튼 셋은 흰 본문이 아니라 머리 영역에 얹혀 있다. */

/* 표 머리줄도 한 겹 옅게 — 행(흰색)과 갈린다 */

/* 조건 상자는 흰색으로 두되, 상자 «바깥»(카드 본문)이 머리와 이어지지 않게 흰색을 명시한다 */

/* ── §46-12 첨부와 색·여백 맞춤 (2026-09-09) ──────────────────────────
   사용자: 「배경색 들어간거 첨부이미지와 같게 해줘 너무 칙칙해」
   --bg-input(#F9FAFB)은 «회색조» 라 눌려 보였다. 첨부의 머리는 #F9FBFD — 파랑기가 돈다.
   같은 계열인 --bg-selected(#F8FAFF)로 바꾼다(실재 토큰). */

/* 표 머리줄은 «흰 배경 + 진한 굵은 글씨» 다(첨부를 3배로 확대해 확인).
   회색 배경에 흐린 글씨를 쓰면 표 전체가 눌려 보인다 — 그게 「고객목록도 다르다」 의 정체였다. */

/* AI 머리 — 제목 줄과 버튼 줄 사이를 넉넉히(첨부는 12px 이 아니라 20px 쯤) */

/* 메시지 상자 — 스크롤이 생길 만큼 길 필요가 없다(사용자).
   카드가 늘어나도 상자는 «적당한 키» 로 멈추고, 남는 자리는 도움말이 가져간다. */

/* ── §46-13 조건 상자의 층 · 머리 여백 (2026-09-09) ────────────────────
   사용자: 「스마트 타겟검색 안에도 배경색 들어가잔아 — 발송목적, 날씨환경조건, 고객등급, 방문이탈주기 에」
   재 보니 층은 «상자 안» 에 있고 바깥은 흰색이다. 나는 거꾸로 두어 층이 아예 없었다. */

/* 사용자: 「타이틀과 버튼 사이 간격이 너무 멀어 아래 여백도 맞지 않고」
   20px 는 과했다 — 첨부는 제목 줄과 버튼 줄이 거의 붙어 있다(8px). */

/* 「전체 해제」 — 첨부는 체크박스가 아니라 «버튼» 이다.
   ⚠ #selectAll 체크박스는 script.js 가 change 로 쓰므로 지우지 않고 감춘다. 버튼이 대신 누른다. */
.bi-ai-selall input[type="checkbox"] { display: none; }

/* 머리와 본문 사이가 떠 보였다 — 첨부는 머리 바로 아래 치환 태그 줄이 온다(2026-09-09) */

/* ── §46-14 사용자 지적 8건 (2026-09-09) ──────────────────────────────
   ⓪ 「배경색은 background: var(--bg-input) 그대로 가자」 —
      첨부에서 잰 #FBFCFD 로 새 토큰을 들였는데 «디자인이랑 안 맞는 색» 이라는 판단.
      머리도 상자도 --bg-input 하나로 통일한다(색을 늘리지 않는다). */

/* ② 조건 상자 넷의 키를 맞춘다 — 칩 수가 달라 제각각이면 줄이 어긋나 보인다 */

/* ③ AI 머리 — 첨부를 재니 위아래 패딩 ~9px, 제목↔버튼 ~8px 였다(내 14px 는 과했다) */

/* ⑤ 「적용 중인 필터」 를 감싼 파란 테두리 — 기존 .bi-chipbox 의 것이 묻어 있었다.
   ⚠ .bi-chipbox 자체는 고치지 않는다(다른 화면이 쓴다) — 이 안에서만 지운다. */

/* ⑧ 메시지 상자 — 「영역에 맞게 다시 늘려줘. AI메시지 사용방법이 안잘리도록」
   본문을 세로 flex 로 세우고, «상자만» 남는 자리를 먹는다.
   태그 줄·글자수·사용 방법은 고정이라 잘리지 않는다. */

/* ── §46-15 사용자 지적 7건 (2026-09-09) ──────────────────────────────
   ② 「각 항목 카드 높이를 적용중인 필터 위까지 — 지금 겹처」
      height:100% 가 범인이었다. 격자에서 stretch 면 이미 같은 키가 되는데,
      거기에 100% 를 더하면 «부모 높이만큼» 다시 늘어 아래 줄(필터)과 겹친다. */

/* ③⑥ 「버튼에도 padding 이 있고 헤더 영역에도 있어서 이중이라 넓게 보여」 — 맞다.
   머리는 버튼의 여백을 «믿고» 자기 여백을 줄인다. 치환 태그 줄도 같다. */

/* 발송 목적 / 발송 날짜를 나눠 상자가 다섯이 되었다(2026-09-09 사용자 지적 ①) */

/* ── §46-16 (걷어냄, 2026-09-09) ────────────────────────────────────
   .bi-ai-mhd / __l / __acts 는 §47 에서 .bi-ai2-mhd 로 다시 세우며 쓸 곳이 없어졌다.
   쓰이지 않는 규격을 남겨 두면 다음 사람이 «둘 중 어느 것인가» 를 고민한다. 지운다. */

/* ── §46-17 조건 상자 배치 (2026-09-09) ────────────────────────────────
   사용자: 「발송목적과 발송날짜는 위 아래로 오게 카드 크기 맞추고 ·
            product_cate 는 상품 분류로 고객등급 아래 위치하게」
   네 «열» 로 세우되, 어떤 열은 카드를 위아래로 둘 담는다.
     ① 발송 목적 / 발송 날짜   ② 날씨·환경   ③ 고객 구분 / 상품 분류   ④ 방문·이탈 주기 */
/* 위아래로 담긴 두 카드가 옆 열의 한 카드와 «같은 키» 가 되게 나눠 갖는다 */

/* ⚠ 열마다 카드 수가 달라 키가 어긋났다 — 격자 아이템을 «행 높이만큼» 늘린다.
   §46-15 에서 height:auto 로 되돌린 뒤 stretch 가 확실히 먹도록 여기서 한 번 더 못박는다(2026-09-09). */

/* =========================================================
   §47 AI 메시지 발송 — 3열 규격안 (2026-09-09 신설)
   ---------------------------------------------------------
   받은 시안 newai1.png 를 우리 토큰·bi-* 로 다시 그린 것이 규격이다.
   규격안 목업: tools/qc/spec_ai/new.html · 비교 문서: renew_crm/ai_spec.html 0장

   ⚠ 앞선 §46 과 «틀» 이 다르다:
     §46  위에 조건(가로) · 아래 좌우 2열
     §47  한 줄 머리 + 3열 — 좌 조건(세로 그룹) · 가운데 목록 · 우 AI 메시지
   §46 의 조각 중 계속 쓰는 것: .bi-ai-ch · .bi-ai-tbl · .bi-ai-cust · .bi-ai-grade
     · .bi-ai-state · .bi-ai-fchip · .bi-ai-tag · .bi-ai-len · .bi-ai-lms · .bi-ai-hd__ico
   ========================================================= */

/* ── §47-1 머리 줄 — 제목 · 진행 단계 · 오른쪽 도구 ─────────────
   새 규격안은 화면 이름과 «지금 어디까지 왔는지» 를 한 줄에 놓는다. */
.bi-ai2-top {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-4);
    padding: 0 var(--space-1) var(--space-4);
}
.bi-ai2-top__l { display: flex; align-items: center; gap: var(--space-5); min-width: 0; }
.bi-ai2-top__t { font-size: var(--fs-xl); font-weight: var(--fw-bold); letter-spacing: -.02em; }
.bi-ai2-top__r { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }

/* 진행 단계 — 조건 → 대상 → 메시지·전송 */
/* 가로 한 줄 가운데 묶음 — 진행 칸 · 시간(시작–끝) */
.bi-ai2-steps,
.bi-bq-time { display: flex; align-items: center; gap: var(--space-2); }
.bi-ai2-step  { display: flex; align-items: center; gap: var(--space-1_5);
                font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-muted); }
.bi-ai2-step__mk {
    width: 18px; height: 18px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: var(--fs-2xs); font-weight: var(--fw-bold);
    background: var(--gray-200); color: var(--bg-card);
}
.bi-ai2-step.is-done .bi-ai2-step__mk { background: var(--brand-blue); }
.bi-ai2-step.is-done { color: var(--txt-primary); }
.bi-ai2-step.is-now  .bi-ai2-step__mk { background: var(--brand-blue); }
.bi-ai2-step.is-now  { color: var(--brand-blue); }
.bi-ai2-steps__bar { width: 26px; height: 1px; background: var(--border-base); }

/* 날짜 칩 — 오른쪽 도구 줄 */
.bi-ai2-date {
    display: inline-flex; align-items: center; gap: var(--space-2);
    height: 32px; padding: 0 var(--space-3);
    border: 1px solid var(--border-base); border-radius: var(--radius-md);
    background: var(--bg-card);
    font-size: var(--fs-base); font-weight: var(--fw-semibold);
}
.bi-ai2-date i { color: var(--txt-muted); }

/* ── §47-2 3열 골격 ────────────────────────────────────────────
   좌 조건(고정 폭) · 가운데 목록(남는 자리) · 우 AI 메시지(고정 폭) */
.bi-ai2-cols {
    display: grid;
    grid-template-columns: 320px minmax(0, 1fr) 430px;
    gap: var(--space-4);
    align-items: stretch;
}
.bi-ai2-cols > .bi-erp-card { display: flex; flex-direction: column; padding: 0; overflow: hidden; }

/* ── §47-3 좌측 조건 패널 — 그룹이 «세로로» 쌓인다 ───────────────
   앞 규격안은 상자를 가로로 늘어놓았지만, 새 규격안은 좁은 열에 세로로 쌓고
   그룹 사이를 «선» 으로 나눈다(상자를 겹치지 않는다). */
.bi-ai2-side__hd {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
    padding: var(--space-3_5) var(--space-4);
    border-bottom: 1px solid var(--border-base);
}
.bi-ai2-side__t { display: flex; align-items: center; gap: var(--space-2);
                  font-size: var(--fs-md); font-weight: var(--fw-bold); }
.bi-ai2-side__t i { color: var(--txt-muted); font-size: var(--fs-base); }
.bi-ai2-cnt {
    display: inline-flex; align-items: center; height: 20px; padding: 0 var(--space-2);
    border-radius: var(--radius-full);
    background: var(--brand-blue-light); color: var(--brand-blue);
    font-size: var(--fs-xs); font-weight: var(--fw-bold);
}
.bi-ai2-side__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 0 var(--space-4); }

.bi-ai2-grp { padding: var(--space-4) 0; border-bottom: 1px solid var(--border-light); }
.bi-ai2-grp:last-child { border-bottom: 0; }
.bi-ai2-grp__t {
    display: flex; align-items: baseline; gap: var(--space-2);
    margin-bottom: var(--space-2_5);
    font-size: var(--fs-base); font-weight: var(--fw-bold);
}
.bi-ai2-grp__note { font-size: var(--fs-sm); font-weight: var(--fw-normal); color: var(--txt-muted); }
.bi-ai2-grp__ch { display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* 좌측 바닥 — 모드 전환과 검색 */
.bi-ai2-side__foot {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border-top: 1px solid var(--border-base);
}
/* 합계 숫자 — 시안 실측 15px. 사다리엔 15 가 없다(13 · 14 · 16) 여서 실측값을 적는다.
   ⚠ 어떻게 알았나: 시안의 띠 «속» 이 35px 이고 안여백이 8+8 이므로 줄상자는 19px 이다.
     --fs-lg(16)는 19px 줄상자에 안 들어가 20px 로 밀어 올린다(실측 37 ↔ 규격안 36).
     15px 이라야 19 에 앉는다. 이 팝업엔 이미 12.5 · 13.5 같은 시안 실측값 선례가 있다. */
.bi-bq-pop .bi-bq-items__sum b { font-size: 15px; }
.bi-ai2-side__foot .bi-btn--primary { flex: 1 1 auto; justify-content: center; }

/* ── §47-4 가운데 — 발송 대상 목록 ───────────────────────────── */
.bi-ai2-lhd {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
    padding: var(--space-3_5) var(--space-4);
    border-bottom: 1px solid var(--border-base);
}
.bi-ai2-lhd__l { display: flex; align-items: center; gap: var(--space-2_5); min-width: 0; }
/* 열 제목 한 자 — 좌·가운데 */
/* §72-2 색을 안 정하면 «순검정»(#000)을 물려받는다 — 토큰이 아니다. 규격안은 --txt-primary 다.
   예약 두 화면에서도 같은 곳에 물렸다(글자 검사가 세 화면에서 한꺼번에 잡았다). */
.bi-ai2-lhd__t,
.bi-ai2-mhd__t { font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--txt-primary); }
.bi-ai2-lhd__n { font-size: var(--fs-base); color: var(--txt-muted); }
.bi-ai2-lhd__n b { color: var(--brand-blue); }
.bi-ai2-lhd__r { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }
/* 「수신거부 1 · 번호오류 1 제외」 — 왜 대상에서 빠졌는지 한 줄로 알린다 */
.bi-ai2-except {
    display: inline-flex; align-items: center; height: 26px; padding: 0 var(--space-2_5);
    border-radius: var(--radius-full);
    background: var(--bg-input); color: var(--txt-muted);
    font-size: var(--fs-sm);
}

.bi-ai2-filters {
    display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border-light);
}

/* 세로로 구르는 통 — AI 고객목록 · 상품 목록 */
.bi-ai2-listwrap { flex: 1 1 auto; min-height: 0; overflow-y: auto; }

/* 보낼 수 없는 줄은 «흐리게» — 왜 체크가 꺼져 있는지 눈으로 보인다 */
.bi-ai-state--off { background: var(--gray-100); color: var(--gray-600); }
.bi-ai-state--err { background: var(--color-danger-50); color: var(--color-danger-600); }

.bi-ai2-lfoot {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-top: 1px solid var(--border-base);
}
/* 작은 회색 글 — 안내 문구 · 디자이너 직급 · 섹션 힌트가 같은 자다 */
/* 작은 회색 글 — 안내 문구 · 디자이너 직급 · 섹션 힌트 · 줄 속 부연 · 월간 건수.
   아홉 군데가 «같은 자» 였다. 한 규칙이 맡는다(2026-09-11 §65-9). */
.bi-ai2-hint,
.bi-ai2-filters__lb,
.bi-ai2-tags__lb,
.bi-bk2-emp__p,
.bi-bk2-mcell__n,
.bi-bq-sec__hint,
.bi-bq-item__m,
.bi-bp2__rm { font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-ai2-pg { display: flex; align-items: center; gap: var(--space-1_5); font-size: var(--fs-sm); color: var(--txt-muted); }
/* §65-10 (2026-09-15) 바닥 한 줄에서 쪽 번호가 안내 글을 «폭 0» 으로 눌러
   글자가 한 글자씩 세로로 쌓였다(실제 캡처). 안내는 한 줄로 두고 모자라면 … 로 줄인다.
   ⚠ .bi-ai2-hint 는 아홉 군데가 함께 쓰는 이름이라 «이 바닥 줄 안에서만» 건다. */
.bi-ai2-lfoot .bi-ai2-hint { flex: 0 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-ai2-lfoot .bi-ai2-pg   { flex: 0 0 auto; }
.bi-ai2-pg__el { padding: 0 var(--space-1); color: var(--txt-muted); }
.bi-ai2-pg__b {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 26px; height: 26px; padding: 0 var(--space-1_5);
    border: 1px solid var(--border-base); border-radius: var(--radius-sm);
    background: var(--bg-card); font-size: var(--fs-sm); color: var(--txt-secondary);
}
.bi-ai2-pg__b.is-on { background: var(--txt-primary); border-color: var(--txt-primary); color: var(--bg-card); font-weight: var(--fw-bold); }

/* ── §47-5 우측 — AI 메시지 ───────────────────────────────────── */
.bi-ai2-mhd {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
    padding: var(--space-3_5) var(--space-4) var(--space-1);
}
.bi-ai2-mhd__l { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
/* §69 아이콘 색은 «머리마다 다르면» 안 된다 (2026-09-14 사용자 지적).
   전에는 파랑(--brand-blue)이라 좌 열의 「스마트 타겟검색」 깔때기(회색)와 짝이 안 맞았다.
   두 카드 머리는 같은 자리·같은 뜻이다 → .bi-ai2-side__t i 와 «같은 색» 을 쓴다. */
.bi-ai2-mhd__t i { color: var(--txt-muted); margin-right: var(--space-1_5); }
.bi-ai2-done {
    display: inline-flex; align-items: center; height: 22px; padding: 0 var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--color-success-50); color: var(--color-success-700);
    font-size: var(--fs-xs); font-weight: var(--fw-bold);
}
.bi-ai2-msub { padding: 0 var(--space-4) var(--space-3); font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-ai2-mbody { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 0 var(--space-4); }

.bi-ai2-tags { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); padding-bottom: var(--space-3); }

.bi-ai2-msg {
    border: 1px solid var(--border-base); border-radius: var(--radius-md);
    background: var(--bg-card); padding: var(--space-4);
    font-size: var(--fs-base); line-height: 1.9; white-space: pre-wrap;
}
/* 치환 태그가 문구 «안» 에서 드러난다 — 어디가 사람마다 바뀌는지 한눈에 */
.bi-ai2-var {
    display: inline-block; padding: 0 var(--space-1_5); border-radius: var(--radius-sm);
    background: var(--brand-blue-light); color: var(--brand-blue); font-weight: var(--fw-bold);
}
.bi-ai2-mfoot {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
    padding: var(--space-3) 0;
}

/* 미리보기 — 목록에서 고른 고객으로 «그 사람의 문구» 를 보여준다 */
.bi-ai2-prev {
    margin: 0 calc(var(--space-4) * -1);
    padding: var(--space-3) var(--space-4);
    background: var(--bg-input);
    border-top: 1px solid var(--border-base);
}
.bi-ai2-prev__hd {
    display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2);
    margin-bottom: var(--space-2);
}
/* 작은 굵은 글 — 미리보기 제목 · 월간 날짜 */
.bi-ai2-prev__t,
.bi-bk2-mcell__d { font-size: var(--fs-sm); font-weight: var(--fw-bold); }
.bi-ai2-prev__note { font-size: var(--fs-xs); color: var(--txt-muted); }
.bi-ai2-prev__line { margin: 0 0 var(--space-1); font-size: var(--fs-sm); color: var(--txt-secondary); line-height: 1.7; }

.bi-ai2-mfooter {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border-top: 1px solid var(--border-base);
}

/* ── §47-6 판을 꽉 채운다 (2026-09-09) ────────────────────────────────
   .bi-page 는 flex column 이라 자식 폭이 «내용만큼» 이 된다 — 3열이 화면 왼쪽에만 서 있었다.
   폭을 채우고, 3열이 남은 «높이» 를 가져가게 한다(카드 안에서만 스크롤). */
.bi-ai2-top  { width: 100%; flex: 0 0 auto; }
.bi-ai2-cols { width: 100%; flex: 1 1 auto; min-height: 0; }
.bi-ai2-cols > .bi-erp-card { min-height: 0; }

/* 목록 표가 카드 벽에 닿지 않게 — 좌우 여백은 카드가 준다 */

/* 날짜 칩 32 는 «상자 전체» 기준이다 — 테두리가 밖으로 붙어 34 가 되던 것 */
.bi-ai2-date { box-sizing: border-box; }

/* ── §47-7 규격안과 «틀» 을 맞춘다 (2026-09-09) ────────────────────────
   사용자: 「아니 똑같이 수정해줘 틀이 달라」 — 나란히 놓고 보니 그랬다.
   ① 카드가 남은 높이를 다 먹어 아래가 거대한 빈 공간이 됐다.
      규격안은 «내용만큼» 이다 — 목록이 길면 그때 스크롤이 생긴다. */
.bi-ai2-cols { flex: 0 1 auto; }
/* ⚠ 규격안은 세 카드의 아래끝이 «같다» — start 로 두면 우측이 짧아 층이 진다.
   판은 내용만큼(위 flex:0 1 auto), 그 안에서 셋은 서로 키를 맞춘다. */
.bi-ai2-cols > .bi-erp-card { align-self: stretch; max-height: 100%; }

/* ④ 「전체 선택」 왼쪽에 빈 네모가 남아 있었다 — 규격안은 버튼 하나다.
   전역 PNG 체크박스의 +label 까지 확실히 가린다(같은 모양으로 다시 적어 특이도를 맞춘다). */
.bi-ai2-lhd__r .bi-ai-selall input[type="checkbox"],
.bi-ai2-lhd__r .bi-ai-selall label { display: none; }

/* ── §47-8 공용 조각을 «쓰지 않는다» (2026-09-09) ──────────────────────
   사용자: 「기존 css 무시하고 새로 만들라니까 너 기존 css때문에 계속 똑같이 만들잔아」
   맞다. 규격안(목업)과 실제가 계속 달랐던 «진짜» 이유가 이것이었다:
       목업  <span class="bi-ai-ch">                        ← 규격만
       실제  <span class="bi-chip bi-chip--opt bi-ai-ch">   ← 공용 칩이 «섞였다»
   공용 .bi-chip · .bi-datatbl 이 자기 패딩·높이·글자를 얹어 규격보다 크고 넓어졌고,
   나는 그 위에 덧칠하며 특이도 싸움을 반복했다. 이 화면은 자기 조각으로 선다.

   ⚠ 공용을 «고치지 않았다» — 다른 화면이 그대로 쓴다. 여기서만 안 쓸 뿐이다. */

/* 카드 — .bi-erp-card 의 flex:1·여백과 싸우지 않는다 */
.bi-ai2-card {
    display: flex; flex-direction: column; min-width: 0; min-height: 0;
    background: var(--bg-card);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-xl);
    overflow: hidden;
}

/* 조건 칩 — 규격안 그대로. 공용 .bi-chip 을 상속하지 않는다 */
.bi-ai2-ch {
    display: inline-flex; align-items: center; gap: var(--space-1_5);
    box-sizing: border-box;
    height: 28px; padding: 0 var(--space-2_5);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-md);
    background: var(--bg-card);
    font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--txt-secondary);
    white-space: nowrap; cursor: pointer;
}
.bi-ai2-ch:hover     { border-color: var(--brand-blue-light); }
.bi-ai2-ch.is-selected {
    background: var(--brand-blue); border-color: var(--brand-blue);
    color: var(--bg-card); font-weight: var(--fw-semibold);
}

/* 적용 중인 필터 칩 */
/* 칩 묶음 — AI 조건칩 · 예약 스케줄 상태칩 */
.bi-ai2-fchips,
.bi-bk2-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.bi-ai2-fchip {
    display: inline-flex; align-items: center; gap: var(--space-1_5);
    box-sizing: border-box;
    height: 26px; padding: 0 var(--space-2) 0 var(--space-2_5);
    border: 1px solid var(--color-info-200);
    border-radius: var(--radius-full);
    background: var(--bg-card); color: var(--brand-blue);
    font-size: var(--fs-sm); font-weight: var(--fw-semibold);
}
.bi-ai2-fchip__x { font-size: var(--fs-sm); opacity: .7; cursor: pointer; }
.bi-ai2-fchip__x:hover { opacity: 1; }

/* 발송 대상 표 — 공용 .bi-datatbl 의 줄무늬·패딩을 쓰지 않는다 */
.bi-ai2-tbl { width: 100%; border-collapse: collapse; background: var(--bg-card); }
.bi-ai2-tbl th {
    padding: var(--space-3);
    border-bottom: 1px solid var(--border-base);
    background: var(--bg-card);
    font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-primary);
    text-align: left; white-space: nowrap;
    position: sticky; top: 0; z-index: 1;
}
.bi-ai2-tbl td { padding: var(--space-2_5) var(--space-3); border-bottom: 1px solid var(--border-light); }
.bi-ai2-tbl tbody tr:hover { background: var(--bg-input); }
.bi-ai2-tbl th:first-child, .bi-ai2-tbl td:first-child { width: 40px; padding-left: var(--space-4); text-align: center; }
.bi-ai2-tbl th:last-child,  .bi-ai2-tbl td:last-child  { padding-right: var(--space-4); text-align: right; }
.bi-ai2-tbl td label { display: none; }   /* 전역 PNG 체크박스의 +label */
.bi-ai2-tbl__loading { padding: var(--space-6); text-align: center; }
/* 작은 제목 한 자 — AI 고객명 · 달력 연월 */
.bi-ai2-name,
.bi-bk2-cal__ym { font-size: var(--fs-md); font-weight: var(--fw-bold); }
/* 개인화 문구 줄 — 규격안에서는 우측 미리보기가 대신한다(행 아래를 펼치지 않는다) */
.bi-ai2-more { display: none; }

/* 보낼 수 없는 줄 */
.bi-ai2-tbl tr.is-off { color: var(--txt-disabled); }
.bi-ai2-tbl tr.is-off .bi-ai2-name,
.bi-ai2-tbl tr.is-off .bi-ai-tel,
.bi-ai2-tbl tr.is-off .bi-ai-last__nm { color: var(--txt-disabled); font-weight: var(--fw-medium); }

/* ── §47-9 조건 그룹은 «각각 카드» 다 (2026-09-09) ─────────────────────
   사용자: 「검색부분 발송목적, 날짜, 날씨/환경, 고객, 상품분류, 방문/이탈 등 각 카드형이잔아」
   구분선으로만 나눴더니 여섯 묶음이 한 덩어리로 읽혔다. 묶음마다 상자를 준다. */
.bi-ai2-side__body { padding: var(--space-3) var(--space-3); display: flex; flex-direction: column; gap: var(--space-2_5); }
.bi-ai2-grp {
    padding: var(--space-3);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    background: var(--bg-input);
}
.bi-ai2-grp:last-child { border-bottom: 1px solid var(--border-light); }
.bi-ai2-grp__t { margin-bottom: var(--space-2); }

/* ⚠ 반복된 함정 — .bi-hidden{display:none}(0,1,0) 이 이 절의 display 선언에 «졌다».
   0건인데 「제외」 배지가 보였다. 같은 모양으로 다시 적어 특이도를 맞춘다(짧게 적으면 또 진다). */
.bi-ai2-except.bi-hidden,
.bi-ai2-done.bi-hidden,
.bi-ai2-prev.bi-hidden,
.bi-ai2-msg.bi-hidden,
.bi-ai2-filters.bi-hidden,
.bi-ai2-grp.bi-hidden,
.bi-ai2-ch.bi-hidden { display: none; }

/* ── §47-13 표가 «접혔다» (2026-09-09) ────────────────────────────────
   실제 화면에서 한 줄이 「C- / 34648 / 김시 / 우 / 일반」 처럼 네 줄로 눌렸다.
   열 폭을 안 정하면 브라우저가 글자 수로 나눈다 — 차트번호·이름·등급이 각자 접힌다.
   규격안은 «한 행 한 줄» 이다. 접히면 24명이 화면 밖으로 밀린다. */
.bi-ai2-tbl { table-layout: fixed; }
.bi-ai2-tbl th:nth-child(1), .bi-ai2-tbl td:nth-child(1) { width: 6%; }
.bi-ai2-tbl th:nth-child(2), .bi-ai2-tbl td:nth-child(2) { width: 23%; }
.bi-ai2-tbl th:nth-child(3), .bi-ai2-tbl td:nth-child(3) { width: 16%; }
.bi-ai2-tbl th:nth-child(4), .bi-ai2-tbl td:nth-child(4) { width: 13%; }
.bi-ai2-tbl th:nth-child(5), .bi-ai2-tbl td:nth-child(5) { width: 30%; }
.bi-ai2-tbl th:nth-child(6), .bi-ai2-tbl td:nth-child(6) { width: 12%; }  /* 여섯 열 합 100% — 하나라도 비우면 그 열이 0 이 된다 */
.bi-ai2-tbl td:nth-child(2), .bi-ai2-tbl td:nth-child(3),
.bi-ai2-tbl td:nth-child(4), .bi-ai2-tbl td:nth-child(6) { white-space: nowrap; }
.bi-ai2-tbl td:nth-child(5) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bi-ai-cust__top { display: flex; align-items: center; gap: var(--space-1_5); white-space: nowrap; }
.bi-ai-state { white-space: nowrap; }

/* ── §47-14 「전체 선택」 은 «버튼 하나» 다 (2026-09-09 → 2026-09-10 §47-19 로 고침)
   어제는 머리띠에도 파란 네모를 되살렸다. ao1.png(새 시안)에는 그 네모가 «없다» —
   「전체 선택」 글자 버튼 하나뿐이다. 네모를 되살리던 규칙을 걷어낸다.
   #selectAll 자체는 남는다(스크립트가 상태로 읽고 버튼이 그것을 뒤집는다) — 눈에서만 뺀다. */
.bi-ai-selall { display: inline-flex; align-items: center; gap: var(--space-1_5); }
.bi-ai-selall label { display: none; }

/* ── §47-15 이름만 있고 «규격이 없던» 넷 (2026-09-09) ─────────────────
   지문(CLASS-ORPHAN)이 넷을 짚었다 — 표시에 붙어 있으나 어디에도 규격이 없다.
   이름이 규격을 뜻하지 않으면 다음 사람이 「어딘가 있겠지」 하고 찾다 만다. 여기서 정한다. */
.bi-ai2-tbl__cb   { text-align: center; }              /* 고르는 칸 — 머리는 비운다 */
.bi-ai2-ch__x     { margin-left: var(--space-1); opacity: .6; cursor: pointer; }
.bi-ai2-ch__x:hover { opacity: 1; }
.bi-ai2-more__body { padding: var(--space-3) var(--space-4); background: var(--bg-input); }
.bi-ai2-more__text { font-size: var(--fs-sm); color: var(--txt-secondary); white-space: pre-wrap; }

/* ── §47-17 판 자체의 규격 — 이름을 가른 뒤의 마무리 (2026-09-09) ────
   전에는 «판 전체» 와 «페이지 번호 줄» 이 둘 다 .bi-ai2-page 였다.
   그래서 판이 display:flex · 13px 회색 글자를 번호 줄에서 물려받고 있었다.
   번호 줄을 .bi-ai2-pg 로 가른 지금, 판은 판대로 적는다. */
.bi-ai2-page {
    display: flex; flex-direction: column; gap: var(--space-3);
    min-height: 0;                      /* 3열이 자기 안에서만 스크롤하도록 */
}

/* ── §47-18 키가 큰 견본용 무대 (2026-09-09) ─────────────────────────
   .sg2doc-stage 는 «넘치는 것을 막는 울타리» 로 220px 고정 + overflow:hidden 이다.
   AI 메시지 발송 견본(좌 조건 300 · 목록 366 · 메시지 419)은 그 안에서 «잘렸다» —
   무대의 옛 교훈(2026-08-13 「고정 140×34 로 가두면 견본이 안 보인다」)이 그대로 되풀이됐다.
   ⚠ .sg2doc-stage 는 건드리지 않는다 — 260개가 그대로 쓴다. 변형을 하나 더 만든다. */
.sg2doc-stage--tall { height: auto; min-height: 60px; overflow: visible; contain: none; padding: var(--space-3); }

/* ══ §48 틀부터 다시 — 시안 newai1.png 실측 (2026-09-10) ═══════════════════
   사용자: 「기본 페이지 틀부터 다르잔아 **헤더와 본문을 감싸는 테두리도 없고** 내부 본문도 다르고
            기존 css 다 무시하고 새로 만들어야한다니까」 · 「newai1.png가 새시안이야」

   시안을 픽셀로 재니 내 화면과 «틀» 자체가 달랐다 — 값이 아니라 구조다.

     잰 값(newai1.png 1699×899 · 바깥 매트 제외 1615×825)      내가 만든 것
     ─────────────────────────────────────────────────────────────────────
     머리 줄 + 3열을 «한 상자» 가 감싼다                        감싸는 것이 없었다
       테두리 #E5E7EB · 모서리 14px · 페이지 바탕 #F5F6F9
     3열은 카드가 아니다 — 세로 구분선 1px 로만 나뉜다           카드 셋이 간격을 두고 떨어져 있었다
       간격 0 · 카드 테두리 0 · 모서리 0
     좌(330) 회색 #F5F6F9 · 가운데(1fr) 흰색 · 우(424) 회색      셋 다 흰색이었다
     머리 줄에 «진행 스텝이 없다»                                조건→대상→메시지 스텝이 있었다
     조건 그룹은 회색 판 위의 «흰 카드»                          회색 카드였다
     고른 칩은 보라 #5B45E0 채움 + 흰 글씨 · 알약                네이비 채움 · 모서리 6px

   ⚠ 이 블록은 «덧칠» 이 아니라 앞 규칙을 대신한다. 되돌리려 규칙을 또 얹지 않는다.
   ⚠ 이 화면은 사용자가 정한 «예외 페이지» 다 — 공용 .bi-erp-card / .bi-chip 을 섞지 않는다. */

.bi-ai2-page { background: var(--bg-page); }

/* ⚠ 이 화면은 예외 페이지다 — «전역이 해 주겠지» 에 기대지 않는다.
   box-sizing 이 안 걸려 있어 머리 줄의 padding 40px 이 폭에 «더해져» 오른쪽이 38px 잘렸다
   (frame 1632 인데 .bi-ai2-top 이 1670). 스스로 선언한다. */
.bi-ai2-frame,
.bi-ai2-frame * { box-sizing: border-box; }

/* 바깥 틀 — 머리 줄과 3열을 한 상자가 감싼다 */
.bi-ai2-frame {
    display: flex; flex-direction: column; min-height: 0;
    background: var(--bg-card);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-xl);   /* 시안 실측 ~14px · 토큰 12px 로 맞춘다(하드코딩 금지 §4) */
    overflow: hidden;
}

/* 머리 줄 — 흰 바탕 · 아래 구분선 · 높이 56 */
.bi-ai2-top {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
    height: 56px; padding: 0 var(--space-5);
    border-bottom: 1px solid var(--border-base);
    background: var(--bg-card);
}

/* 3열 — 카드가 아니라 «구분선» 이다 */
.bi-ai2-cols {
    display: grid;
    grid-template-columns: 330px minmax(0, 1fr) 424px;
    gap: 0;
    align-items: stretch;
}
.bi-ai2-card {
    display: flex; flex-direction: column; min-width: 0; min-height: 0;
    border: 0; border-radius: 0; background: transparent; overflow: hidden;
}
.bi-ai2-card--l { background: var(--bg-page); }
.bi-ai2-card--c { background: var(--bg-card); border-left: 1px solid var(--border-base); border-right: 1px solid var(--border-base); }
/* ⚠ 우 열은 «흰색» 이다 — 크롭으로 확인. 좌 열만 회색 판 위에 흰 카드가 놓인다 */
.bi-ai2-card--r { background: var(--bg-card); }
/* 「생성 완료」 배지도 보라 채움(시안) — 「LMS 장문」 은 연파랑 그대로 */
.bi-ai2-done { background: var(--ai-pick); border-color: var(--ai-pick); color: var(--bg-card); }

/* 좌 열 — 회색 판 위에 «흰 카드» 그룹이 쌓인다 */
.bi-ai2-side__hd,
.bi-ai2-lhd { height: 56px; padding: 0 var(--space-4); border-bottom: 1px solid var(--border-base); }
.bi-ai2-side__body { padding: var(--space-3); gap: var(--space-2_5); display: flex; flex-direction: column; }
.bi-ai2-grp {
    padding: var(--space-3) var(--space-3_5);
    background: var(--bg-card);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
}
.bi-ai2-grp:last-child { border-bottom: 1px solid var(--border-light); }
.bi-ai2-side__foot { border-top: 1px solid var(--border-base); background: var(--bg-page); }

/* 조건 칩 — 알약 · 고르면 보라 채움
   ⚠ #5B45E0 은 팔레트에 없던 색이다. 시안이 이 색이고 이 화면은 예외 페이지라,
     하드코딩 대신 이 화면 전용 토큰으로 한 번만 선언하고 그것만 쓴다. */
.bi-ai2-frame { --ai-pick: #5B45E0; }
.bi-ai2-ch {
    height: 30px; padding: 0 var(--space-3);
    border-radius: var(--radius-full);
    font-size: var(--fs-base);
}
.bi-ai2-ch.is-selected {
    background: var(--ai-pick); border-color: var(--ai-pick);
    color: var(--bg-card); font-weight: var(--fw-bold);
}

/* 가운데 · 우 열 머리 — 바깥 틀이 이미 감싸므로 카드 머리 장식을 덜어낸다 */
.bi-ai2-filters { border-bottom: 1px solid var(--border-light); }
.bi-ai2-lfoot { border-top: 1px solid var(--border-base); }
.bi-ai2-mhd { height: 56px; padding: 0 var(--space-4); }

/* 표의 체크박스 — 전역 input[type=checkbox]{display:none} 이 이긴다.
   이 표는 «고르는» 표다. 체크가 안 보이면 누구에게 가는지 알 수 없다(시안도 파란 네모가 있다). */
.bi-ai2-tbl input[type="checkbox"] {
    display: inline-block; visibility: visible;
    width: 16px; height: 16px; margin: 0;
    accent-color: var(--brand-blue); cursor: pointer;
}
.bi-ai2-tbl tr.is-off input[type="checkbox"] { cursor: not-allowed; }

/* 「전체 선택」 — 시안에는 앞에 «파란 네모» 가 있다 */
.bi-ai2-lhd .bi-ai-selall input[type="checkbox"] {
    display: inline-block; visibility: visible;
    width: 16px; height: 16px; margin: 0;
    accent-color: var(--brand-blue); cursor: pointer;
}
.bi-ai2-lhd .bi-ai-selall label { display: none; }

/* ══ §49 눌러 보고 나온 여덟 (2026-09-11) ══════════════════════════════
   사용자 지적을 하나씩. 모두 «규격안(newai1.png)이 어떻게 생겼나» 로 판정했다. */

/* ① 일반 조건 검색으로 바꾸면 판이 통째로 줄었다 — 조건 세 칸뿐이라 좌 열이 짧아지고
      그 키에 3열 전체가 맞춰졌다. 「안 줄어들었으면 해」 →  판의 키를 «화면» 에 맞춘다.
   ② AI 메시지 칸도 내용이 없으면 쪼그라들었다 — 같은 이유다. 최소 키를 준다. */
/* ⚠ 2026-09-11 §50 — 고정 뺄셈(calc(100vh - 150px))은 «틀렸다».
   .bi-page 가 이미 height: calc(100vh - 헤더) · overflow:hidden · padding 으로
   화면을 «정확히» 채우고 있다. 거기서 또 150px 을 빼니 판이 화면보다 작아졌고,
   조건 여섯 묶음이 다 안 들어가 «좌 열 안쪽»에 스크롤이 생겼다.
   사용자: 「화면 해상도는 충분한데 AI메시지발송 영역의 높이는 그렇지 않아서 생긴 문제」 — 맞다.
   → 빼지 말고 «남는 만큼 채운다». 해상도가 바뀌어도 따라온다. */
/* ⚠ .bi-page 의 gap(12px)이 «보이지 않는 형제» 사이마다 소비돼 36px 을 먹고 있었다
   (script.js 가 참조하는 옛 자리 div 셋 — 키는 0 이지만 display:none 은 아니라 gap 은 먹는다).
   이 판에는 틀 하나뿐이다. gap 을 둘 이유가 없다. */
.bi-ai2-page { gap: 0; }
.bi-ai2-frame { flex: 1 1 auto; min-height: 0; }
.bi-ai2-cols  { flex: 1 1 auto; min-height: 0; }
.bi-ai2-msg   { min-height: 168px; }

/* ③ 「199자 / LMS 최대 2,000자」 가 상자 안에서 두 줄로 접혔다.
      규격안은 «테두리도 바탕도 없는 글자» 다 — 상자를 없애면 접힐 일이 없다. */
.bi-ai2-mfoot .bi-ai-len {
    height: auto; padding: 0; border: 0; background: none;
    white-space: nowrap; flex-shrink: 0;
}

/* ⑥ 적용 중인 필터 칩 — 규격안은 «연파랑 바탕» 이다(흰 바탕이 아니다). 실측 #EEF2FF */
.bi-ai2-fchip { background: var(--color-info-50); }

/* ⑦ 「차트」 열을 뺐다(사용자 지시). 여섯 열 → 남는 폭을 담당 디자이너·최근 시술내역에 준다.
      전에는 담당 디자이너가 13% 라 «최유리 / 모근 밀착…» 이 서로 겹쳐 읽혔다. */
.bi-ai2-tbl th:nth-child(1), .bi-ai2-tbl td:nth-child(1) { width: 5%; }
.bi-ai2-tbl th:nth-child(2), .bi-ai2-tbl td:nth-child(2) { width: 20%; }
.bi-ai2-tbl th:nth-child(3), .bi-ai2-tbl td:nth-child(3) { width: 16%; }
.bi-ai2-tbl th:nth-child(4), .bi-ai2-tbl td:nth-child(4) { width: 18%; }
.bi-ai2-tbl th:nth-child(5), .bi-ai2-tbl td:nth-child(5) { width: 30%; }
.bi-ai2-tbl th:nth-child(6), .bi-ai2-tbl td:nth-child(6) { width: 11%; }
/* 차트번호는 화면에서 뺀다 — script.js 가 계속 값을 넣으므로 «지우지» 않는다.
   ⚠ 2026-09-16 — 시안(newai1.png)에는 차트번호가 있어 한때 되살렸다가 되돌렸다.
      **§49(2026-09-11) 사용자 결정** 「표 첫 글자 열은 «고객명»」 이 시안보다 나중이다.
      시안이 낡았다 — 여기를 다시 열려면 그 결정부터 확인할 것. */
.bi-ai2-tbl .bi-ai-cust__no { display: none; }
/* 담당 디자이너·최근 시술내역은 칸을 넘기지 않는다 — 넘치면 … 로 끊는다(겹쳐 읽히지 않게) */
.bi-ai2-tbl td:nth-child(4) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ⑧ 일반 조건 검색 — 입력칸 옆 돋보기 */
.bi-ai2-seek { display: flex; align-items: center; gap: var(--space-1_5); }
.bi-ai2-seek .bi-input { flex: 1 1 auto; min-width: 0; }
.bi-ai2-seek__b {
    flex-shrink: 0;
    width: 32px; height: 32px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--border-base); border-radius: var(--radius-md);
    background: var(--bg-card); color: var(--txt-secondary); cursor: pointer;
}
.bi-ai2-seek__b:hover { border-color: var(--ai-pick); color: var(--ai-pick); }

/* §54 「전체 선택」 앞 네모는 «감춘다»(2026-09-11 사용자 지시).
   §49 에서 시안에 네모가 있어 되살렸으나, 버튼 하나로 쓰기로 했다.
   #selectAll 자체는 남긴다 — script.js 가 상태로 읽고 버튼이 그것을 뒤집는다. */
.bi-ai2-lhd .bi-ai-selall input[type="checkbox"],
.bi-ai2-lhd .bi-ai-selall label { display: none; }

/* ③ 「조회 중」 은 표 한가운데에 선다 — 가로뿐 아니라 «세로» 도 가운데다.
   colspan 셀 하나가 목록 자리를 통째로 차지하므로, 그 안에서 flex 로 세운다. */
.bi-ai2-tbl__loading .bi-emptybox__sub {
    display: flex; align-items: center; justify-content: center;
    gap: var(--space-2);
    min-height: 220px;
    text-align: center; word-break: keep-all;
    color: var(--txt-secondary);
}
.bi-ai2-tbl__loading .fa-spinner { color: var(--ai-pick); }

/* ⑤ 테스트 발송 — «어디로» 가 버튼 옆에 늘 보인다 */
.bi-ai2-test { display: inline-flex; align-items: center; gap: var(--space-1_5); min-width: 0; }
.bi-ai2-test__lb { font-size: var(--fs-sm); color: var(--txt-muted); flex-shrink: 0; }
/* §50 라벨을 뺐다 — 칸 스스로 「테스트번호 입력」 을 말한다. 그만큼 넓힌다 */
.bi-ai2-test__in { width: 140px; height: 30px; flex-shrink: 0; font-variant-numeric: tabular-nums; }

/* ══ §51 「생성중」 문구가 가운데에 안 섰다 (2026-09-11) ═══════════════
   사용자: 「메시지 생성중일때 … 문구가 가운데에 있지않아」 (m1.png)

   범인은 부모의 white-space: pre-wrap 이었다 — 마크업의 «줄바꿈 + 들여쓰기 공백» 이
   그대로 찍혀 스피너가 한 줄 위로 가고, 문구가 어정쩡하게 들여써진 뒤
   「습니다.」 만 다음 줄로 밀렸다. (CLAUDE.md 학습된 함정 그대로다 —
    「부모에 white-space:pre-wrap → 들여쓰기 노출 → 텍스트 컨테이너에만 준다」)

   → 마크업은 <span> 한 덩어리로 붙이고(태그 사이를 띄우지 않는다),
     이 상자만 «가로·세로 가운데» 로 세운다. 생성중은 «읽는 글» 이 아니라 «기다리는 표시» 다. */
/* ⚠ 상자 자신에게 flex 를 줘 봤자 소용없다 — jQuery .show() 가 «인라인 display:block» 을
   박아 넣어 이긴다(실측: style="display: block;"). !important 로 싸우지 않는다(학습된 함정).
   → 가운데 정렬은 «안쪽 래퍼» 가 한다. 부모가 block 이든 flex 든 상관없어진다. */
#aiMsgLoading { padding: 0; white-space: normal; }
.bi-ai2-wait {
    min-height: inherit;            /* 부모의 min-height(168) 를 그대로 물려받는다 */
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: var(--space-2_5);
    padding: var(--space-4);
    text-align: center;
    color: var(--txt-secondary);
}
.bi-ai2-wait .fa-spinner { font-size: var(--fs-lg); color: var(--ai-pick); }
/* ⚠ 한국어는 기본값이면 «있습니 / 다.» 처럼 어절 한가운데서 끊긴다 — keep-all 로 어절을 지킨다.
   폭은 두 문장이 한 줄씩 서도록 잡는다. */
.bi-ai2-msg__wait { max-width: 240px; line-height: 1.7; word-break: keep-all; }

/* ══ §53 조건 카드가 서로 붙어 있었다 · 「생성중」 문구 두 줄 (2026-09-11) ═════
   사용자: 「각 항목별 카드가 모두 붙어있어 규격에는 떨어저있는데 aimodeSmart 에
            display:flex; flex-direction:column; gap:5px 이렇게 들어가야 하지않나」

   진단이 맞았다. .bi-ai2-side__body 가 flex·gap 을 갖고 있었지만 그 «직접 자식» 은
   #aimodeSmart / #aimodeNormal 둘뿐이다 — 조건 카드는 그 «안» 에 있어 gap 이 닿지 않았다.
   #aimodeSmart · #aimodeNormal 에 규칙이 하나도 없었다(확인함).

   간격은 시안을 재서 정했다 — newai1.png 의 좌 열을 x=80 에서 세로로 훑으니
   흰 카드 여섯의 사이가 «12px 균일» 이었다(5px 이 아니다). --space-3 이 그 값이다. */
#aimodeSmart,
#aimodeNormal {
    display: flex;
    flex-direction: column;
    /* 2026-09-11 사용자 지시로 «반» 으로 — 시안 실측은 12px(--space-3) 이었다.
       곁가지로 좌 열이 덜 넘친다(1600×900 실측: 12px 일 때보다 스크롤이 줄었다). */
    gap: var(--space-1_5);
}
/* ⚠ 아이디에 display 를 주면 .bi-hidden(클래스)을 «이긴다» — §51 에서 겪은 그 함정이다.
   여기서는 실제로 회귀를 냈다: #aimodeNormal 이 숨지 않아
   aimodeCnt() 의 $('#aimodeNormal').is(':visible') 분기가 참이 되고,
   조건을 다섯 개 골라도 배지가 «적용 0» 으로 나왔다(필터 칩은 5개인데).
   → 같은 모양(아이디+클래스)으로 숨김을 다시 선언한다. */
#aimodeSmart.bi-hidden,
#aimodeNormal.bi-hidden { display: none; }

/* 「생성중」 문구는 «두 줄» 로 — 무엇을 하는 중인지 / 무엇을 조심할지 를 나눠 읽는다.
   폭에 기대어 접히게 두면 창 크기에 따라 끊기는 자리가 달라진다. 줄을 우리가 정한다. */
.bi-ai2-msg__wait { max-width: none; }

/* ══ §56 미리보기는 «전문» 이다 (2026-09-11) ═══════════════════════════
   사용자: 「미리보기 내용이 이상해 … 내용이 짤리는데??」
   맞다 — 이 자리는 «그 사람에게 실제로 나갈 문자» 를 확인하는 곳이다.
   규격안 그림이 두 줄이라 두 줄만 보여줬는데, 잘라 놓으면 확인할 수가 없다.
   전문을 그대로 두고, 줄바꿈을 살리고, 길면 우측 열이 스크롤한다. */
.bi-ai2-prev__line {
    white-space: pre-wrap;          /* 문구의 줄바꿈을 그대로 */
    word-break: keep-all;           /* 한국어를 어절 한가운데서 끊지 않는다 */
    margin: 0;
}
/* 미리보기 머리는 «붙어 있게» — 문구가 길어도 누구 것인지 잃지 않는다 */
.bi-ai2-prev__hd { position: sticky; top: 0; background: var(--bg-card); z-index: 1; }

/* ══ §58 예약일정표 — «규격안 조각» 으로 다시 세운다 (2026-09-11) ═════
   사용자: 「좌측 날짜 디자이너 스케줄상태 등과 중간 시간 선택 영역도 다 달라
            기존 css때문에 덮어쓴거같은데 기존css 사용하는게 아니고 규격안대로 다시 만드는거야」

   맞다. §57 은 기존 .bi-bksch-* · .bi-cal__* 에 «겉만» 얹은 것이었다 —
   달력이 두 줄로 서고, 칩이 사각이고, 카드 경계가 안 보이는 것은 전부 기존 규격이 살아 있어서다.
   여기서는 규격안(tools/qc/spec_bk/)의 조각을 그대로 가져와 이 화면이 «자기 이름» 으로 선다.
   ⚠ 기존 클래스에 얹지 않는다 — 마크업이 새 이름을 쓰고, 옛 이름은 그 자리에서 사라진다. */

/* ── 좌 패널 — 회색 판 위 흰 카드 ────────────────────────────── */
.bi-bk2-side {
    width: 330px; flex-shrink: 0;
    background: var(--bg-page);
    border-right: 1px solid var(--border-base);
    padding: var(--space-3);
    display: flex; flex-direction: column; gap: var(--space-3);
    overflow-y: auto;
}
.bi-bk2-card {
    background: var(--bg-card);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-lg);
    /* 안여백 12 = 시안 실측 (2026-09-21 · 전엔 14 = --space-3_5)
       시안(reimg/d2.png)의 사이드 카드를 띠로 읽으면 카드 위 ~ 첫 글이 12 다:
         달력   카드 y136 -> 제목 글 y152   ·  상태 카드 y619 -> 제목 글 y631
       카드 키도 그만큼 다르다: 달력 252 -> 시안 242 · 상태 246 -> 시안 217.
       ⚠ 휴무설정은 .bi-do2-wrap .bi-bk2-card 로 이미 12 를 따로 쓰고 있다(16472줄) —
         공용 값을 내려도 그 화면은 안 움직인다(employee-dayoff 세션과 맞춤). */
    padding: var(--space-3);
}
.bi-bk2-card__t {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: var(--space-2_5);
    font-size: var(--fs-base); font-weight: var(--fw-bold);
}
.bi-bk2-card__t small { font-size: var(--fs-sm); font-weight: var(--fw-normal); color: var(--txt-muted); }
.bi-bk2-card__act {
    font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--brand-blue);
    background: none; border: 0; cursor: pointer; padding: 0;
}

/* 검색칸 — 돋보기는 «칸 안» 이다(옆 버튼이 아니다) */
.bi-bk2-search > i { position: absolute; left: var(--space-3); top: 50%; transform: translateY(-50%); color: var(--txt-muted); font-size: var(--fs-sm); }
.bi-bk2-search > input {
    width: 100%; height: 40px; padding: 0 var(--space-3) 0 34px;
    border: 1px solid var(--border-base); border-radius: var(--radius-lg);
    background: var(--bg-card); font-size: var(--fs-base); color: var(--txt-primary);
}
.bi-bk2-search > input::placeholder { color: var(--txt-muted); }

/* 달력 — 머리가 «한 줄» 이다(‹ 2026년 9월 › + [오늘 9/9]) */
.bi-bk2-cal__hd { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-3); }
.bi-bk2-cal__nav { display: inline-flex; align-items: center; gap: var(--space-2_5); }
.bi-bk2-cal__arw {
    width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--border-base); border-radius: var(--radius-md);
    background: var(--bg-card); color: var(--txt-secondary); font-size: var(--fs-sm); cursor: pointer;
}
.bi-bk2-cal__today {
    /* §68-6 26px 는 사다리 밖이었다 — 27 은 §12-4 의 칸이다(스윕이 「기준선에 없는 신규」로 잡음) */
    height: 27px; padding: 0 var(--space-2_5);
    display: inline-flex; align-items: center;
    border: 1px solid var(--color-info-200); border-radius: var(--radius-full);
    background: var(--color-info-50); color: var(--brand-blue);
    font-size: var(--fs-sm); font-weight: var(--fw-semibold); cursor: pointer;
}
/* 격자는 «상자 없이» — 기존 달력은 회색 테두리 상자였다 */
/* 요일 줄과 날짜 격자는 «같은 7칸» 이다 */
.bi-bk2-cal__grid,
.bi-bk2-cal__dowrow { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--space-0_5); text-align: center; }
.bi-bk2-cal__dow { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-muted); padding: var(--space-1) 0; }
/* 요일 머리와 날짜 칸은 같은 색을 쓴다 */
.bi-bk2-cal__dow--sun,
.bi-bk2-cal__d--sun { color: var(--color-danger-500); }
.bi-bk2-cal__dow--sat,
.bi-bk2-cal__d--sat { color: var(--brand-blue); }
.bi-bk2-cal__d {
    position: relative;
    height: 30px; display: inline-flex; align-items: center; justify-content: center;
    border: 0; background: none;
    border-radius: 50%;
    font-size: var(--fs-base); color: var(--txt-primary); cursor: pointer;
}
.bi-bk2-cal__d.is-today { background: var(--txt-primary); color: var(--bg-card); font-weight: var(--fw-bold); }
.bi-bk2-cal__d.has-dot::after {
    content: ''; position: absolute; bottom: 1px; left: 50%; transform: translateX(-50%);
    width: 4px; height: 4px; border-radius: 50%; background: var(--bk-run);
}

/* 디자이너 — 행마다 구분선, 아바타 34 */
/* ⚠ 2026-09-21 — 줄 키가 시안과 달랐다. 시안(reimg/d2.png)의 디자이너 카드 안
   나눔선 사이를 픽셀로 재니 **43px** 이다(_emp_rows.mjs · 43 · 43).
     시안 43  ·  규격안·실제 55  — 안여백 10 이 아니라 4 다(아바타 34 + 4+4 + 테두리 1). */
.bi-bk2-emp { display: flex; align-items: center; gap: var(--space-2_5); padding: var(--space-1) 0; border-bottom: 1px solid var(--border-light); cursor: pointer; }
.bi-bk2-emp:last-child { border-bottom: 0; }
.bi-bk2-emp > input[type="checkbox"] {
    display: inline-block; visibility: visible; flex-shrink: 0;
    width: 16px; height: 16px; margin: 0; accent-color: var(--brand-blue); cursor: pointer;
}
.bi-bk2-ava {
    width: 34px; height: 34px; flex-shrink: 0; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--ava, var(--brand-navy)); color: var(--bg-card);
    font-size: var(--fs-sm); font-weight: var(--fw-bold);
}
/* 디자이너 아바타 여덟 색 — «무슨 색인지» 만 정하고 칠하기는 .bi-bk2-ava 가 한 곳에서 한다.
   배경을 낱개로 적으면 팔레트 별명(.bi-dot--info 등)과 똑같은 규칙이 여덟 개 생긴다.
   ⚠ c5 는 --brand-purple(#5E1E7B)이 아니라 시안의 --bk-run(#5B45E0)이다. */
.bi-bk2-ava--c0 { --ava: var(--brand-navy); }
.bi-bk2-ava--c1 { --ava: var(--brand-blue); }
.bi-bk2-ava--c2 { --ava: var(--txt-secondary); }
.bi-bk2-ava--c3 { --ava: var(--gray-400); }
.bi-bk2-ava--c4 { --ava: var(--color-info-500); }
.bi-bk2-ava--c5 { --ava: var(--bk-run); }
.bi-bk2-ava--c6 { --ava: var(--color-success-600); }
.bi-bk2-ava--c7 { --ava: var(--color-warning-600); }
.bi-bk2-emp__l { flex: 1 1 auto; min-width: 0; }
/* §72-2 색을 안 정하면 «순검정»(#000)을 물려받는다 — 토큰이 아니다. 규격안은 --txt-primary 다 */
.bi-bk2-emp__n { font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-primary); }
.bi-bk2-cnt {
    flex-shrink: 0; height: 24px; padding: 0 var(--space-2_5);
    display: inline-flex; align-items: center; border-radius: var(--radius-full);
    background: var(--bg-input); color: var(--txt-secondary);
    font-size: var(--fs-sm); font-weight: var(--fw-semibold);
}
.bi-bk2-cnt--on { background: var(--bk-run-bg); color: var(--bk-run); }

/* 스케줄 상태 — 칩은 «알약» 이다(사각이 아니다) */
.bi-bk2-chip {
    height: 30px; padding: 0 var(--space-3);
    display: inline-flex; align-items: center; gap: var(--space-1_5);
    border: 1px solid var(--bk-run-bg); border-radius: var(--radius-full);
    background: var(--bg-card); color: var(--bk-run);
    font-size: var(--fs-sm); font-weight: var(--fw-semibold); cursor: pointer;
}
.bi-bk2-chip > b { font-weight: var(--fw-normal); }
.bi-bk2-chip.is-on { background: var(--bk-run); border-color: var(--bk-run); color: var(--bg-card); }
.bi-bk2-chip.is-on > b { color: var(--bg-card); }

/* 예약 유형 — 색 점이 아니라 «배지» 다 */
.bi-bk2-src { display: flex; align-items: center; gap: var(--space-2_5); padding: var(--space-2) 0; cursor: pointer; }
.bi-bk2-src > input[type="checkbox"] {
    display: inline-block; visibility: visible; width: 16px; height: 16px; margin: 0;
    accent-color: var(--brand-blue); cursor: pointer;
}
.bi-bk2-src__ico {
    width: 20px; height: 20px; flex-shrink: 0; border-radius: var(--radius-sm);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: var(--fs-2xs); font-weight: var(--fw-bold);
}
/* 네이버 표식 — 좌 패널 유형 아이콘과 블록의 작은 배지가 같은 것이다 */
.bi-bk2-src__ico--n,
.bi-bk2-tag--n { background: var(--color-success-500); color: var(--bg-card); }
.bi-bk2-src__ico--tel { background: var(--bg-input); color: var(--txt-secondary); }
.bi-bk2-src__l { flex: 1 1 auto; font-size: var(--fs-base); }

/* ── 툴바 — 날짜 버튼 · [오늘] · 실시간 배지 ─────────────────── */
.bi-bk2-daybtn {
    height: 32px; padding: 0 var(--space-3);
    display: inline-flex; align-items: center; gap: var(--space-2);
    border: 1px solid var(--border-base); border-radius: var(--radius-md);
    background: var(--bg-card); color: var(--txt-primary);
    font-size: var(--fs-md); font-weight: var(--fw-bold); cursor: pointer; white-space: nowrap;
}
.bi-bk2-live {
    height: 28px; padding: 0 var(--space-3);
    display: inline-flex; align-items: center; gap: var(--space-1_5);
    border-radius: var(--radius-full);
    background: var(--bk-run-bg); color: var(--bk-run);
    font-size: var(--fs-sm); font-weight: var(--fw-bold); white-space: nowrap;
}
.bi-bk2-live::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--bk-run); }
.bi-bk2-biz { font-size: var(--fs-sm); color: var(--txt-muted); white-space: nowrap; }

/* ── §58-2 본문 타임라인(가로) — 규격안 조각으로 다시 (2026-09-11) ────
   사용자: 「본문에 시간 영역이 완전히 다른데 규격안과 다르게 색이 들어간것도있고 크기도 다르고」

   기존 .bi-schmx* 는 «30분 칸마다 점선 상자 + 좌측 색 띠» 였다. 시안은 다르다:
     · 눈금은 «1시간» · 칸은 «얇은 세로선» 뿐(상자가 아니다)
     · 디자이너 열은 «아바타 + 이름 + 직급·N건» — 색 띠가 아니다
     · 빈 칸 안내는 «모든 칸» 이 아니라 필요한 곳에만
     · 예약 블록은 시간 폭만큼 «절대 위치» 로 눕는다(칸에 갇히지 않는다) */
.bi-bk2-hgrid { flex: 1 1 auto; min-height: 0; overflow: auto; background: var(--bg-card); }
.bi-bk2-hgrid__in { min-width: 100%; }

.bi-bk2-hhead { display: flex; border-bottom: 1px solid var(--border-base); background: var(--bg-card); position: sticky; top: 0; z-index: 2; }
.bi-bk2-hhead__c {
    width: 180px; flex-shrink: 0;
    padding: var(--space-2) var(--space-4);
    font-size: var(--fs-sm); color: var(--txt-muted);
    border-right: 1px solid var(--border-base);
}
.bi-bk2-hhead__t { flex: 1 1 auto; display: flex; min-width: 0; }
.bi-bk2-hhead__h {
    flex: 1 1 0; min-width: 0;
    padding: var(--space-2) 0 var(--space-2) var(--space-2);
    font-size: var(--fs-sm); color: var(--txt-muted);
    border-left: 1px solid var(--border-light);
}
.bi-bk2-hhead__h:first-child { border-left: 0; }

.bi-bk2-hrow { display: flex; border-bottom: 1px solid var(--border-light); min-height: 124px; }
.bi-bk2-hrow:last-child { border-bottom: 0; }
.bi-bk2-hrow__c {
    width: 180px; flex-shrink: 0;
    display: flex; align-items: center; gap: var(--space-2_5);
    padding: var(--space-3) var(--space-4);
    border-right: 1px solid var(--border-base);
}
/* 가로 판의 «시간 트랙» 과 세로 판의 «열 묶음» 은 하는 일이 같다 */
.bi-bk2-hrow__t,
.bi-bk2-vcols { flex: 1 1 auto; min-width: 0; position: relative; display: flex; }
.bi-bk2-hslot { flex: 1 1 0; min-width: 0; border-left: 1px solid var(--border-light); }
.bi-bk2-hslot:first-child { border-left: 0; }

/* 예약 블록 — 시간 폭만큼 누운다(칸에 갇히지 않는다) */
.bi-bk2-hrow__t .bi-bk2-ev {
    position: absolute; top: 8px; bottom: 8px;
    padding: var(--space-2);
    display: flex; flex-direction: column;
    cursor: pointer;
}
.bi-bk2-ev__hd { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); margin-bottom: var(--space-1); }
.bi-bk2-ev__time { font-size: var(--fs-sm); color: var(--txt-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-bk2-ev__nm { display: flex; align-items: center; gap: var(--space-1_5); font-size: var(--fs-base); font-weight: var(--fw-bold); white-space: nowrap; overflow: hidden; }
.bi-bk2-ev__pro { margin-top: var(--space-1); font-size: var(--fs-sm); color: var(--txt-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-bk2-tag {
    height: 20px; padding: 0 var(--space-2); flex-shrink: 0;
    display: inline-flex; align-items: center; border-radius: var(--radius-full);
    font-size: var(--fs-xs); font-weight: var(--fw-bold); white-space: nowrap;
}
/* 상태 배지 — 색은 «월간 알약과 한 규칙» 으로 §64 아래에 모아 두었다.
   ⚠ 여기에 두면 안 된다: .bi-bk2-mpill 기본 규칙이 §64(뒤)에 있어 같은 특이도로 덮어 버린다. */
.bi-bk2-tag--n    { background: var(--color-success-500); color: var(--bg-card); }

/* 빈 시간 — 필요한 곳에만 하나 */

/* 지금 시각 — 본문 전체를 가로지르는 세로선 */
.bi-bk2-now { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--bk-run); z-index: 3; }
.bi-bk2-now__b {
    position: absolute; top: -11px; left: 50%; transform: translateX(-50%);
    height: 22px; padding: 0 var(--space-2);
    display: inline-flex; align-items: center; border-radius: var(--radius-md);
    background: var(--bk-run); color: var(--bg-card);
    font-size: var(--fs-xs); font-weight: var(--fw-bold); white-space: nowrap;
}
.bi-bk2-hgrid__empty { padding: var(--space-6); text-align: center; color: var(--txt-muted); }

/* ══ §59 규격안과 «딴판» 이던 것 셋 (2026-09-11) ═══════════════════════
   사용자: 「실제화면이랑 규격안이랑 같다고 생각해?? … 완전히 잘못하고있잔아」
   전체를 나란히 놓고서야 보였다 — 부분만 보고 있어서 놓쳤다.

   ① 칸선이 «톱니» 로 보였다
      .bi-bk2-hslot 을 <button> 으로 바꾸면서 높이를 못 채웠다.
      버튼은 flex 자식이어도 늘어나지 않는다 — align-self 로 늘려야 한다.
   ② 빈 시간 안내가 모든 행에 가로로 길게 걸쳐 규격안과 딴판이었다.
      규격안은 «한 행에 한 곳», 그것도 블록 크기의 상자다.
   ③ 바닥 상태 가이드가 아직 옛 색(신청=초록)이었다. 시안은 주황이다. */

/* ① 칸은 행 높이를 «꽉» 채운다 — 버튼 기본 스타일을 눌러 둔다 */
.bi-bk2-hrow__t > .bi-bk2-hslot {
    align-self: stretch;
    height: auto; min-height: 0;
    margin: 0; padding: 0;
    font: inherit; color: inherit;
    /* ⚠ 2026-09-14 판이 통째로 «회색» 이었다 — <button> 의 기본 바탕(buttonface, #F0F0F0)이 남아 있었다.
       appearance:none 만으로는 바탕이 지워지지 않는다. 반드시 함께 비운다. */
    background: transparent;
    cursor: pointer;
    -webkit-appearance: none; appearance: none;
    border-top: 0; border-right: 0; border-bottom: 0;
}
.bi-bk2-hslot:hover::after { line-height: inherit; display: flex; align-items: center; justify-content: center; height: 100%; }

/* ② 빈 시간 안내 — 규격안은 «블록 하나 크기» 다. 행을 가로지르지 않는다.
      칸이 잘면(30분 눈금·긴 영업시간) 글자가 겹치니, 좁을 때는 아예 감춘다. */

/* ③ 바닥 상태 가이드 — 시안 색으로(신청은 주황이다) */
.bi-page .bi-bksplit__foot .bi-resv-sw--request   { background: var(--bk-req);  border: 0; }
.bi-page .bi-bksplit__foot .bi-resv-sw--confirmed { background: var(--bk-fix);  border: 0; }
.bi-page .bi-bksplit__foot .bi-resv-sw--done      { background: var(--bk-done); border: 0; }
.bi-page .bi-bksplit__foot .bi-resv-sw--cancel    { background: var(--bg-card); border: 1px solid var(--bk-off); }

/* ══ §60 예약 일정표(booking_renew) 본문 — 규격안 d2 의 «세로 타임라인» (2026-09-11) ═══════
   사용자: 「예약일정표 도 고처줘 좌측 날짜 디자이너 스케줄 상태 부터 일간주간월간 선택 탭 까지 전부」

   옛 본문은 30분 칸에 카드를 «칸마다» 넣어 한 예약이 여러 줄에 반복됐고,
   축 라벨이 12시간제라 13:00 예약이 「02:00」 줄에 있었다. 규격안은 시간 비례 절대 위치다.
   자리값은 데이터마다 달라 CSS 로 못 적는다 → 브릿지 변수 --t(위치) · --h(길이) · --l/--w(겹칠 때 폭). */

.bi-bk2-vgrid { --vh: 1000px; display: flex; flex-direction: column; min-width: 100%; }
.bi-bk2-vgrid, .bi-bk2-vgrid * { box-sizing: border-box; }

/* ── 열 머리(디자이너) — 좌측 시간축 폭(64px)만큼 비우고 시작한다 ── */
.bi-bk2-vhead {
    display: flex; position: sticky; top: 0; z-index: 6;
    background: var(--bg-card); border-bottom: 1px solid var(--border-base);
}
.bi-bk2-vhead__x { flex: 0 0 64px; }
.bi-bk2-vhead__d {
    flex: 1 1 0; min-width: 168px;
    display: flex; align-items: center; gap: var(--space-2_5);
    padding: var(--space-2_5) var(--space-3);
    border-left: 1px solid var(--border-light);
}
.bi-bk2-vhead__i b    { font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-primary);
                        white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-bk2-vhead__i span { font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-bk2-vhead__n {
    flex: 0 0 auto; padding: 1px var(--space-2);
    border-radius: var(--radius-full); background: var(--bg-subtle);
    font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-secondary);
}

/* ── 본문 ── */
/* ⚠ 2026-09-30 사용자 지적 — 「일간일 때 현재 시간 타임라인 위치가 맞지 않아」. 맞았다.
   .bi-bk2-vnow 는 position:absolute 인데 이 상자에 position 이 없어,
   «가장 가까운 자리 잡힌 조상» 을 기준으로 top:N% 를 쟀다 — 그 상자는 머리까지 포함해
   더 길어서 선이 **위로 밀렸다**(실측: 09:45 선이 09:30 라벨보다 20px 위. 48px ≈ 33분 어긋남).
   ⚠ 축(.bi-bk2-vaxis)과 열(.bi-bk2-vcols)은 제각기 relative 라 제대로 있었다 —
      그래서 «축은 맞는데 선만 틀린» 모양이 되어 알아채기 어려웠다. */
.bi-bk2-vbody { display: flex; height: var(--vh); position: relative; }

/* 시간축 — 라벨은 «선 위» 에 걸터앉는다(시안 그대로) */
.bi-bk2-vaxis { flex: 0 0 64px; position: relative; }
.bi-bk2-vaxis__t {
    position: absolute; top: var(--t); right: var(--space-2_5);
    transform: translateY(-50%);
    font-size: var(--fs-sm); color: var(--txt-muted); white-space: nowrap;
}
/* ⚠ 2026-09-30 사용자 지적 — 「시작시간이 09:00일때 시간이 짤려보여」.
   가운데 맞춤(translateY(-50%))이라 **첫 라벨이 판 위로 반쯤 나갔다**
   (실측: 눈금 top 226 · 몸통 top 233 → 7px 잘림).
   예약일정표(시간)은 라벨을 칸 «시작» 에 놓아 잘리지 않는다 — 양 끝만 그 방식으로 붙인다.
   ⚠ 가운데 것들은 그대로 둔다 — 눈금선과 글이 어긋나면 시각을 잘못 읽는다. */
.bi-bk2-vaxis__t.is-first { transform: translateY(0); }
.bi-bk2-vaxis__t.is-last  { transform: translateY(-100%); }
/* 30분 눈금 라벨 — 정시보다 한 톤 작고 옅게(정시가 먼저 읽혀야 한다) */
.bi-bk2-vaxis__t.is-half {
    font-size: var(--fs-2xs);
    color: var(--txt-disabled);
}

.bi-bk2-vcol  { flex: 1 1 0; min-width: 168px; position: relative; border-left: 1px solid var(--border-light); }

/* 눈금선 — 정시는 진하게, 30분은 옅게 */
.bi-bk2-vline      { position: absolute; left: 0; right: 0; top: var(--t); height: 0;
                     border-top: 1px dashed var(--border-light); }
.bi-bk2-vline.is-hour { border-top: 1px solid var(--border-light); border-top-style: solid; }

/* 빈 칸 — 눈금마다 «따로» 다. 눌러야 그 시각으로 새 예약이 된다 */
.bi-bk2-vslot {
    position: absolute; left: 0; right: 0; top: var(--t); height: var(--h);
    margin: 0; padding: 0; border: 0; background: transparent;
    -webkit-appearance: none; appearance: none; cursor: pointer;
    font: inherit; color: inherit;
}
.bi-bk2-vslot:hover { background: var(--bg-hover); }
.bi-bk2-vslot:hover::after {
    content: '+ 빈 시간 · 클릭하여 예약';
    position: absolute; inset: 2px 4px;
    display: flex; align-items: center; justify-content: center;
    border: 1px dashed var(--border-strong); border-radius: var(--radius-md);
    font-size: var(--fs-sm); color: var(--txt-muted); white-space: nowrap; overflow: hidden;
}

/* 예약 블록 — 시작 선에서 길이만큼 눕는다. 색·모서리·좌측 바는 .bi-bk2-ev 공용 */
.bi-bk2-vev {
    position: absolute; z-index: 2;
    left: var(--l, 0%); width: var(--w, 100%);
    padding: var(--space-2) var(--space-2_5);
    cursor: pointer;
}
.bi-bk2-vev:hover { box-shadow: var(--shadow-sm); }
.bi-bk2-vev__st {
    flex: 0 0 auto; padding: 0 var(--space-1_5);
    border-radius: var(--radius-sm); background: var(--bg-card);
    font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--txt-secondary);
}
.bi-bk2-ev--req  .bi-bk2-vev__st { color: var(--bk-req); }
.bi-bk2-ev--fix  .bi-bk2-vev__st { color: var(--bk-fix); }
.bi-bk2-ev--done .bi-bk2-vev__st { color: var(--txt-muted); }
.bi-bk2-ev--off  .bi-bk2-vev__st { color: var(--bk-off); }

/* 짧은 예약(30분)은 두 줄이 안 들어간다 — 시술명부터 접는다 */
.bi-bk2-vev .bi-bk2-ev__pro { margin-top: 0; }

/* 지금 시각 — 보라 가로선 + 좌측 시각 배지 */
.bi-bk2-vnow {
    position: absolute; left: 0; right: 0; top: var(--t); height: 0; z-index: 5;
    border-top: 2px solid var(--bk-run); pointer-events: none;
}
.bi-bk2-vnow span {
    position: absolute; top: 0; left: 0; transform: translate(-100%, -50%);
    padding: 1px var(--space-2); border-radius: var(--radius-sm);
    background: var(--bk-run); color: var(--txt-inverse);
    font-size: var(--fs-xs); font-weight: var(--fw-bold); white-space: nowrap;
}

/* ── §60-2 [일간][주간][월간] — 시안은 «연회색 알약 안의 흰 활성 탭» 이다.
      지금은 네이비로 꽉 찬 알약이라 시안과 딴판이었다. 이 화면 안에서만 다시 칠한다. */
.bi-page .bi-erp-toolbar .bi-segment {
    padding: var(--space-0_5); border-radius: var(--radius-lg);
    background: var(--bg-subtle); border: 1px solid var(--border-light);
}
.bi-page .bi-erp-toolbar .bi-segment__btn {
    border: 0; background: transparent; border-radius: var(--radius-md);
    padding: var(--space-1) var(--space-3_5);
    font-size: var(--fs-base); font-weight: var(--fw-medium); color: var(--txt-secondary);
}
.bi-page .bi-erp-toolbar .bi-segment__btn.is-active {
    background: var(--bg-card); color: var(--txt-primary);
    font-weight: var(--fw-bold); box-shadow: var(--shadow-xs);
}

/* ── §60-3 달력 헤더 우측 — 시안은 「영업 09:00 – 19:00」 과 [30분][1시간] 을 둔다 ── */
/* .bi-bk2-vmeta 제거(2026-09-11) — .bi-bk2-biz 와 같은 선언이고 쓰는 곳이 없다 */

/* ── §60-4 바닥 안내 — 시안은 상태 가이드 왼쪽 · 사용법 오른쪽 ── */
.bi-bk2-vfoot {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
    padding: var(--space-2_5) var(--space-4);
    border-top: 1px solid var(--border-base); background: var(--bg-card);
    font-size: var(--fs-sm); color: var(--txt-muted);
}
.bi-bk2-vfoot__sw i { width: 10px; height: 10px; border-radius: var(--radius-xs); display: inline-block; }
.bi-bk2-vfoot__sw--req  i { background: var(--bk-req); }
.bi-bk2-vfoot__sw--fix  i { background: var(--bk-fix); }
.bi-bk2-vfoot__sw--done i { background: var(--bk-done); }
.bi-bk2-vfoot__sw--off  i { background: var(--bg-card); border: 1px dashed var(--bk-off); }

/* ══ §65 예약등록 · 상품추가 팝업 — 규격안 spec_bk/reg.html · prod.html ═══════════
   시안: renew_crm/db1.png · p1.png (2026-09-11 사용자 요청 7 · 8)
   두 화면(예약일정표(시간)·예약 일정표)이 «같은 창» 을 쓴다. */

/* ── §65-1 예약등록: 고객 칸 안의 칩·고객번호 ── */
.bi-bq-chip {
    display: inline-flex; align-items: center; flex: 0 0 auto;
    padding: 1px var(--space-2); border-radius: var(--radius-full);
    background: var(--bk-fix-bg); color: var(--bk-fix);
    font-size: var(--fs-xs); font-weight: var(--fw-bold); white-space: nowrap;
}
.bi-bq-code { margin-left: auto; flex: 0 0 auto; font-size: var(--fs-sm); color: var(--txt-disabled); }

/* ── §65-2 시간: 시작 옆에 «끝» 이 붙는다(사람이 고르지 않는다) ── */
.bi-bq-time > select { flex: 1 1 auto; min-width: 0; }
.bi-bq-time > b { flex: 0 0 auto; font-size: var(--fs-base); color: var(--txt-secondary); white-space: nowrap; }

/* ── §65-3 시술 · 상품 ── */
.bi-bq-sec { margin-top: var(--space-4); }
.bi-bq-sec__hd { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-2); }
/* 팝업 속 작은 제목 — 「시술 · 상품」 · 「담은 상품」 */
.bi-bq-sec__t,
.bi-bq-sec__t b { color: var(--bk-fix); }
.bi-bq-sec__hd .bi-btn { margin-left: auto; }

.bi-bq-items__none {
    padding: var(--space-4); text-align: center;
    font-size: var(--fs-sm); color: var(--txt-disabled);
}
.bi-bq-item {
    display: flex; align-items: center; gap: var(--space-2_5);
    padding: var(--space-2_5) var(--space-3); border-bottom: 1px solid var(--border-light);
}
/* 줄 속 세로 묶음 — 예약등록 줄 · 상품 줄 · 디자이너 머리 */
.bi-bq-item__b,
.bi-bk2-vhead__i { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.bi-bq-item__t {
    display: flex; align-items: center; gap: var(--space-1_5);
    font-size: var(--fs-base); font-weight: var(--fw-bold);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bi-bq-item__m b { color: var(--txt-primary); }
/* ⚠ 2026-09-29 (2) 사용자 지적 1 — 「입고수정 팝업에 매입상품 상품추가했을때
     단가 및 계산부분이 상품명 아래로 내려가있어 **같은 열에 나오게** 해줘」.
   .bi-bq-item__b 는 예약등록 줄을 위해 «세로 묶음»(flex-direction:column)이다 —
   거기서는 이름 아래에 시간·금액이 오는 것이 맞다.
   입고 줄은 이름 옆에 «단가 × 수량 = 소계» 가 서야 한다(칸이라 더 그렇다).
   ⚠ 공용 규칙을 고치지 않는다 — 입고 팝업의 담긴 줄(#rb_items) 안에서만 가로로 눕힌다. */
#rb_items .bi-bq-item__b {
    flex-direction: row;
    align-items: center;
    gap: var(--space-2_5);
}
#rb_items .bi-bq-item__t { flex: 1 1 auto; min-width: 0; }
#rb_items .bi-bq-item__m {
    flex: 0 0 auto;
    display: flex; align-items: center; gap: var(--space-1);
    white-space: nowrap;
    /* ⚠ 2026-09-30 — .bi-bq-pop .bi-bq-item__m 의 margin-top:2px 를 여기서만 0 으로 되돌린다.
       그 2px 는 «이름 위 / 시간·금액 아래» 두 줄인 **예약등록** 줄의 값이다.
       입고 줄은 사용자 지시로 «한 줄» 이 되었고, .bi-bq-item__b 가 align-items:center 라
       2px 이 남아 있으면 단가·수량 묶음만 이름보다 2px 아래로 내려앉는다.
       cmp_box 가 「줄 · 아래글 위여백 규격 0 → 실제 2」 로 잡아 주었다.
       id 선택자라 (1,1,0) — .bi-bq-pop .bi-bq-item__m (0,2,0) 을 이긴다. */
    margin-top: 0;
}
/* 좁아지면 줄바꿈을 허용한다 — 억지로 한 줄에 두면 이름이 한 글자씩 눌린다.
   ⚠⚠ 2026-09-29 (3) — 여기 경계가 **720px** 이었다. 그런데 이 팝업의 iframe 폭이 바로 720 이다.
      미디어쿼리는 «그 문서의 창» 을 재므로 늘 걸렸고, 가로로 눕힌 규칙이 **곧바로 되돌려졌다.**
      사용자가 두 번 「단가가 아래로 내려가 있다」 고 말한 까닭이다 — 고쳤다고 적어 놓고
      화면은 그대로였다. 캡처해서 재고서야 보였다(flexDirection: column).
   → 팝업 폭보다 «확실히 좁을 때» 만 걸리게 520 으로 내린다.
      ⚠ 팝업 안에서 쓰는 규칙에 미디어쿼리를 걸 때는 **그 팝업의 폭** 을 먼저 본다.
        화면 폭이 아니다. */
@media (max-width: 520px) {
    #rb_items .bi-bq-item__b { flex-direction: column; align-items: stretch; gap: var(--space-1); }
    #rb_items .bi-bq-item__m { justify-content: flex-end; }
}
.bi-bq-tag {
    flex: 0 0 auto; padding: 1px var(--space-1_5); border-radius: var(--radius-sm);
    background: var(--bk-fix-bg); color: var(--bk-fix);
    font-size: var(--fs-xs); font-weight: var(--fw-bold);
}
/* 수량 단추 묶음 — 예약등록·상품추가가 같은 조각이다 */
/* §68 수량 상자는 예약등록·담은상품이 «한 규격» 이다 — 아래 .bi-bq-qty,.bi-bp2__qty 로 합쳤다 */
.bi-bq-qty button {
    width: 28px; height: 28px; border: 0; background: var(--bg-card);
    color: var(--txt-muted); cursor: pointer; font-size: var(--fs-md);
}
.bi-bq-qty button:hover { background: var(--bg-hover); color: var(--txt-primary); }
.bi-bq-qty > span { width: 30px; text-align: center; font-size: var(--fs-base); font-weight: var(--fw-bold); }
.bi-bq-del {
    width: 28px; height: 28px; flex: 0 0 auto;
    border: 1px solid var(--border-base); border-radius: var(--radius-md);
    background: var(--bg-card); color: var(--txt-disabled); cursor: pointer;
}
.bi-bq-del:hover { color: var(--bk-off); border-color: var(--bk-off); }
.bi-bq-items__ft {
    display: flex; align-items: center;
    padding: var(--space-2_5) var(--space-3); background: var(--bg-input);
    font-size: var(--fs-sm); color: var(--txt-muted);
}
.bi-bq-items__ft b { color: var(--txt-primary); }
.bi-bq-items__sum { margin-left: auto; font-size: var(--fs-base); color: var(--txt-primary); }
.bi-bq-items__sum b { color: var(--bk-fix); font-size: var(--fs-lg); }

/* ── §65-4 바닥: 예약 가능 안내는 왼쪽, 단추는 오른쪽 ── */
/* 팝업 바닥 — 안내는 왼쪽, 단추는 오른쪽 */
.bi-bq-foot { display: flex; align-items: center; gap: var(--space-3); }
.bi-bq-ok {
    display: inline-flex; align-items: center; gap: var(--space-1_5);
    font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--color-success);
}
/* 팝업 바닥 단추 묶음 — 두 창이 같다 */
.bi-bq-foot__btns { margin-left: auto; display: flex; gap: var(--space-2); }

/* §65-5 제거(2026-09-14) — 내가 따로 만든 상품 팝업(.bi-bp__*)을 걷어냈다.
   매출등록의 «기존» 팝업을 규격안에 맞춰 두 화면이 같이 쓴다(§66-3). */

/* ══════════════════════════════════════════════════════════════════════════
   §59-2 ~ §65 재구성 (2026-09-11)
   ⚠ 이 묶음은 «되살린» 것이다 — 작업 중 style.css 를 실수로 되돌려(git checkout) 날렸고,
      대화에 남은 각 절을 순서대로 다시 적었다. 내용은 같고, 이미 합쳐 둔 중복은 합친 채로 적었다.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── §59-2 30분 눈금일 때 칸이 너무 좁았다 ─────────────────────────────
   사용자: 「30분 단위일때 간격이 너무 좁아 더 넓혀줘」 → §61-7 에서 104px 로 다시 올렸다.
   칸을 flex:1 로만 두면 영업시간이 긴 지점(09:00~21:30 = 26칸)에서 한 칸이 41px 이 된다. */
.bi-bk2-hslot, .bi-bk2-hhead__h { min-width: 104px; }
.bi-bk2-hgrid.is-hourstep .bi-bk2-hslot,
.bi-bk2-hgrid.is-hourstep .bi-bk2-hhead__h { min-width: 208px; }

/* ── §59-3 칸을 넓히자 «판» 이 안 늘어나 머리와 본문이 어긋났다 ─────────
   26칸 × 104 인데 판 속은 1275px 그대로라 칸들이 «넘쳐 흐르고»,
   머리칸(86) ↔ 행칸(78) 이 어긋나고, 블록은 좁아진 트랙 기준 %로 앉아
   시각이 「11:00…」 처럼 잘렸다. 판 속을 내용 폭으로 늘리고 가로로 구르게 한다. */
.bi-bk2-hgrid__in { width: max-content; min-width: 100%; }
.bi-bk2-hhead, .bi-bk2-hrow { width: 100%; }
.bi-bk2-hhead__t, .bi-bk2-hrow__t { flex: 1 1 auto; min-width: 0; }
/* 디자이너 칸은 가로로 굴러도 «붙어» 있어야 누구 줄인지 안다 */
.bi-bk2-hhead__c, .bi-bk2-hrow__c { position: sticky; left: 0; z-index: 3; background: var(--bg-card); }
.bi-bk2-hhead__c { z-index: 4; }

/* ── §59-4 겹치는 예약을 한 줄 «안» 에서 위아래로 나눠 세운다 ───────────
   진짜 끝 시각이 오면서(13:00~20:30) 긴 예약과 짧은 예약이 한 줄에서 겹쳤다.
   ⚠ 갈래는 «비율(0~1)» 로 넘긴다 — calc 는 길이×숫자만 곱할 수 있다.
      백분율로 넘기면 height 가 무효가 되어 블록이 «내용 높이» 로 커진다(줄 밖으로 삐져나온다). */
.bi-bk2-hrow__t .bi-bk2-ev {
    top:    calc(8px + (100% - 16px) * var(--lt, 0));
    bottom: calc(8px + (100% - 16px) * (1 - var(--lt, 0) - var(--lh, 1)));
    height: auto;
}

/* ── §59-5 규격안은 180, 화면은 213 이었다 (답안지가 잡았다) ────────────
   .bi-bk2-* 에 box-sizing 이 안 걸려 width:180 에 안쪽 여백 32 + 테두리 1 이 «더해지고» 있었다.
   규격안 쪽(spec_bk.css)에는 * { box-sizing: border-box } 가 있어 두 그림이 어긋났다. */
.bi-bk2-side, .bi-bk2-side *,
.bi-bk2-hgrid, .bi-bk2-hgrid *,
.bi-bk2-vgrid, .bi-bk2-vgrid *,
.bi-cal__header, .bi-cal__header * { box-sizing: border-box; }

/* ── §60-5 지금 시각선은 «열 밖» 에 둔다 ──────────────────────────────
   열 안에 두면 모든 열과 겹쳐 「열이 겹치지 않는가」 를 잴 수 없다(답안지가 잡았다).
   시간축 폭만큼 비켜 앉는다. */
.bi-bk2-vbody > .bi-bk2-vnow { left: 64px; }

/* ── §60-9 styleguide2 12-5-5 견본 전용 ───────────────────────────────
   브릿지 변수(--t/--h)는 «데이터» 라 견본엔 없다. 견본만 보기 좋게 자리를 못박는다(§4: 클래스로). */
.sg2doc-vdemo { --vh: 340px; border: 1px solid var(--border-base); border-radius: var(--radius-lg); overflow: hidden; background: var(--bg-card); }
.sg2doc-t0 { --t: 0%; }
.sg2doc-t1 { --t: 28%; }
.sg2doc-t2 { --t: 56%; }
.sg2doc-t3 { --t: 84%; }
.sg2doc-ev1 { --t: 28%; --h: 42%; }
.sg2doc-ev2 { --t: 14%; --h: 28%; }
.sg2doc-ev3 { --t: 56%; --h: 14%; }
.sg2doc-now { --t: 37%; }
.sg2doc-slot { --t: 84%; --h: 16%; }

/* ── §61 2026-09-11 사용자 지적 넷 ────────────────────────────────────
   「30분단위가 너무 좁아서 예약 카드가 짤리는데 예약일정표(시간)처럼 늘려야지」
   「중앙 시간선택 영역에 예약 카드가 시간 영역을 벗어나 서로 겹처서 글자가 가려저」 */

/* §61-1 세로 타임라인도 «시간당 높이» 를 넉넉히 — 1시간 112px(30분 56px).
   80px 로는 「시각 / 이름 / 시술명」 석 줄이 안 들어간다. */
.bi-bk2-vgrid { --hr: 112px; }

/* §61-5 요일 줄 — 예약일정표(시간)은 요일을 달력 격자 «안» 에 넣지만,
   예약 일정표는 주간 모드에서 주(週)를 줄로 감싸야 해서 격자를 나눠 쓴다.
   그래서 요일 줄에도 같은 7칸 격자를 준다(안 주면 「일월화수목금토」 가 한 칸에 붙는다). */
.bi-bk2-cal__grid.is-weekmode { display: block; }
.bi-bk2-cal__grid.is-weekmode .bi-cal__wrow { display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--space-0_5); }
/* §69-4 주간 달력만 «컸다» — 주 래퍼가 줄마다 안여백 2+2 와 줄사이 4 를 더 얹어 28px 이 불었다.
   세 모드가 같은 크기여야 한다(2026-09-14 사용자 6번): 줄 높이 30 · 줄 사이 2 — 일간·월간의 격자 gap 과 같은 값. */
.bi-bk2-cal__grid.is-weekmode .bi-cal__wrow { padding: 0; }
.bi-bk2-cal__grid.is-weekmode .bi-cal__wrow + .bi-cal__wrow { margin-top: var(--space-0_5); }
/* §68-3 월간은 «보고 있는 달» 이 통째로 고른 범위다 — 날짜마다 칠하지 않고 그 달만 옅게 깐다(사용자 6번) */
.bi-bk2-cal__grid.is-monthmode .bi-bk2-cal__d:not(.bi-bk2-cal__d--out) { background: var(--bk-fix-bg); }
.bi-bk2-cal__grid.is-monthmode .bi-bk2-cal__d.is-today { background: var(--txt-primary); }   /* 오늘은 오늘대로 */

/* §61-7 바닥 색표에 «진행중» — 시안은 다섯이다 */

/* ── §62 예약 상세 — 규격안(spec_bk/detail.html)에 맞춘다 ───────────────
   사용자: 「예약상세도 규격안에 맞게」 · 「색도 다르게 적용되어있어」
   나란히 놓고 보니 색이 넷 어긋나 있었다 —
     · 「예약 일시」 가 초록이었다(판에 없는 색이다)
     · 「완료」 상태 칩이 «파랑» 이었다 — 판에서 완료는 회색이다. 같은 예약이 두 색으로 읽힌다
     · 「매출등록」 이 초록이었다 — 이 화면의 강조는 보라(--bk-run)다
     · 「예약 상품」 이 파란 칩이었다 — 규격안은 글이다
   상태 색은 §58-3 토큰 하나에서만 나오게 한다. */
.bi-page .bi-bki-status--chip {
    background: var(--bk-done-bg); color: var(--txt-muted);
    border: 0; box-shadow: none; font-weight: var(--fw-bold);
}
.bi-page .bi-bki-status--chip.bi-bk-status1 { background: var(--bk-req-bg); color: var(--bk-req); }
.bi-page .bi-bki-status--chip.bi-bk-status2 { background: var(--bk-fix-bg); color: var(--bk-fix); }
.bi-page .bi-bki-status--chip.bi-bk-status6 { background: var(--bk-run);    color: var(--txt-inverse); }
.bi-page .bi-bki-status--chip.bi-bk-status4 { background: var(--bk-done-bg); color: var(--txt-muted); }
.bi-page .bi-bki-status--chip.bi-bk-status3,
.bi-page .bi-bki-status--chip.bi-bk-status5 {
    background: var(--bg-card); color: var(--bk-off); box-shadow: inset 0 0 0 1px var(--bk-off);
}
/* 값은 «글» 이다 — 칩·색 글씨로 꾸미지 않는다(일시가 초록, 상품이 파란 칩이었다) */
.bi-page .bi-bki-v,
.bi-page .bi-bki-mono { color: var(--txt-primary); font-weight: var(--fw-semibold); }
.bi-page .bi-bki-mono { font-variant-numeric: tabular-nums; }
.bi-page .bi-bki-goods {
    background: transparent; border: 0; padding: 0;
    color: var(--txt-primary); font-weight: var(--fw-semibold);
}
/* ⚠ 옛 규칙이 .bi-write-grid-2 input[type=button].bi-bki-btn--sales (0,3,1) 이라
   특이도를 맞춰야 이긴다. `!important` 대신 «같은 모양의 선택자» 로 이긴다(§7 학습된 함정). */
.bi-page .bi-write-grid-2 input[type="button"].bi-bki-btn--sales,
.bi-page .bi-write-grid-2 input[type="button"].bi-bki-btn--sales:hover {
    background: var(--bk-run); border-color: var(--bk-run); color: var(--txt-inverse);
}
.bi-page .bi-write-grid-2 input[type="button"].bi-bki-btn--primary {
    background: var(--bk-fix); border-color: var(--bk-fix); color: var(--txt-inverse);
}
.bi-page .bi-write-grid-2 input[type="button"].bi-bki-btn--primary:hover { background: var(--brand-navy); }
/* 성별은 «작은 회색 글» — 노란 칩이 아니다 */
.bi-page .bi-bki-gender {
    background: transparent; border: 0; padding: 0;
    font-size: var(--fs-sm); font-weight: var(--fw-normal); color: var(--txt-muted);
}

/* ══ §63 2026-09-11 사용자 요청 묶음 ═══════════════════════════════════ */

/* §63-1 좌 패널 디자이너 목록 — 「4명까지 보이고 그 위는 스크롤」
   한 줄 50px(아바타 34 + 위아래 여백 8) × 4 = 200px.
   다섯째 줄이 «반쯤» 보여야 더 있다는 것이 읽힌다 — 그래서 딱 200 이 아니라 조금 더 준다. */
.bi-bk2-side #bksch_emp_list {
    max-height: 214px; overflow-y: auto;
    padding-right: var(--space-1);   /* 스크롤 막대가 오른쪽 건수를 가리지 않게 */
}

/* §63-2 겹쳐 반 높이가 된 블록은 «고객명만» (dn1.png)
   사용자: 「고객명이 상품명이랑 겹처 짤리는 경우가 있어 이런경우 고객명만 표시해」 */
.bi-bk2-ev.is-tight .bi-bk2-ev__pro { display: none; }
.bi-bk2-ev.is-tight .bi-bk2-ev__nm  { margin-top: 0; }

/* §63-3 예약 일정표 본문 — 디자이너 열은 «넷» 까지 보이고 옆으로 구른다
   사용자: 「디자이너 수에따라 줄어들게 되어있는데 기본 4명 나오고 가로로 이동해서 선택가능하게」
   열을 1/n 로 나누면 사람이 늘수록 글자가 먼저 죽는다. 폭을 못박고 넘치면 굴린다. */
.bi-bk2-vgrid { --vcol: 232px; min-width: calc(64px + var(--vcol) * 4); }
/* 디자이너 열 — 머리와 본문이 «같은 폭» 이어야 줄이 맞는다 */
.bi-bk2-vhead__d,
.bi-bk2-vcol { flex: 0 0 var(--vcol); min-width: var(--vcol); }

/* ══ §64 주간 · 월간 — 규격안(spec_bk/week.html · month.html) ═══════════
   주간은 일간의 세로 타임라인을 «그대로» 쓴다 — 열만 디자이너에서 요일로 바뀐다. */

/* §64-3 의 «주간 타임라인»(.bi-bk2-vgrid--week · -vhead__d--day · -vmore) 제거(2026-09-14)
   — 한 요일에 온 지점의 예약이 들어와 겹쳐서 못 읽었다(사용자 지적).
   §67 에서 월간과 같은 «집계 격자»(.bi-bk2-wgrid)로 바꿨다. 쓰는 곳이 없다. */

/* §64-4 좁은 블록은 «상태 배지» 를 접는다 — 시각이 「1…」 으로 잘리느니 이편이 낫다.
   상태는 좌측 색 바와 바탕색이 이미 말하고 있다(바닥 색표가 그 뜻을 적어 둔다). */
.bi-bk2-vev.is-tight .bi-bk2-vev__st { display: none; }
.bi-bk2-vev.is-tight .bi-bk2-ev__time { font-size: var(--fs-xs); }

/* ── 월간: 시간 축이 없다. 칸마다 «상태별 건수» ── */
/* 집계 판 골격 — 주간·월간이 같은 모양이다 */
/* §69-6 판을 늘려 본문을 채우던 것(§68-5)을 «되돌린다».
   2026-09-14 사용자: 「월간일때 중앙 영역 디자인 규격과 완전히 달라」 —
   칸이 112 → 163 으로 불면서 「예약 N」과 알약 사이가 텅 비어 규격안과 딴판이 됐다.
   규격안은 112·96 «고정» 이다. 아래가 남는 것은 규격안이 정한 모습이다. */
.bi-bk2-mgrid,
.bi-bk2-wgrid { display: flex; flex-direction: column; min-height: 0; }
.bi-bk2-mgrid, .bi-bk2-mgrid * { box-sizing: border-box; }
.bi-bk2-mhead {
    display: grid; grid-template-columns: repeat(7, 1fr);
    border-bottom: 1px solid var(--border-base); background: var(--bg-card);
}
.bi-bk2-mhead span {
    padding: var(--space-2) 0; text-align: center;
    font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-muted);
}
.bi-bk2-mhead .is-sun { color: var(--color-danger-500); }
.bi-bk2-mhead .is-sat { color: var(--brand-blue); }

.bi-bk2-mbody { display: grid; grid-template-columns: repeat(7, 1fr); grid-auto-rows: 112px; }
.bi-bk2-mcell {
    display: flex; flex-direction: column; gap: var(--space-1);
    padding: var(--space-2); text-align: left;
    /* ⚠ §70-3 «굵은 선» 의 정체 — <button> 의 기본 테두리(2px outset)다.
       왼·위만 지정하면 오른·아래에 그 2px 이 «그대로 남는다». appearance:none 도 지우지 못한다.
       (§9 에서 바탕(buttonface)에 똑같이 물렸다 — 테두리도 같다.)
       2026-09-14 사용자: 「예약 선택하는곳 … 굵은선으로 그려져있고 규격안이랑 달라」.
       → 먼저 «0 으로 비우고», 그 위에 규격안의 선을 «새로» 긋는다. */
    border: 0;
    border-left: 1px solid var(--border-light);
    border-top: 1px solid var(--border-light);
    background: var(--bg-card); cursor: pointer;
    -webkit-appearance: none; appearance: none; font: inherit; color: inherit;
    overflow: hidden;
}
.bi-bk2-mcell:nth-child(7n+1) { border-left: 0; }
.bi-bk2-mcell:hover { background: var(--bg-hover); }
.bi-bk2-mcell.is-out { background: var(--bg-column); cursor: default; }
/* §68-5 날짜 숫자는 «중립» 이다 — 색은 요일 머리(.bi-bk2-mhead .is-sun/.is-sat)에만 준다(규격안).
   ⚠ 옛 규칙은 is-sun/is-sat 이 is-out «뒤» 에 있어 지난달 날짜까지 빨강·파랑으로 칠했다
      (2026-09-14 사용자 7번 「중앙 달력부분 규격안 디자인과 완전히 달라」의 한 갈래). */
.bi-bk2-mcell.is-out .bi-bk2-mcell__d { color: var(--txt-disabled); }
.bi-bk2-mcell.is-today .bi-bk2-mcell__d {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; border-radius: 50%;
    background: var(--txt-primary); color: var(--txt-inverse);
}
/* §72-2 규격안은 숫자를 «한 치수 크게» 둔다 — 어미(12)를 그대로 물려받아 작아 보였다
   (2026-09-14 사용자: 「주간,월간에 중앙영역 등 글자크기등이 시안이나 규격안에 비해 작은거 같아」) */
.bi-bk2-mcell__n b { font-size: var(--fs-base); color: var(--txt-primary); }
.bi-bk2-mpills { display: flex; flex-wrap: wrap; gap: var(--space-1); margin-top: auto; }
.bi-bk2-mpill {
    display: inline-flex; align-items: center; height: 19px; padding: 0 var(--space-2);
    border-radius: var(--radius-full); font-size: var(--fs-xs); font-weight: var(--fw-bold);
    /* §72-2 규격안은 «완료» 알약 글자를 --txt-muted 로 둔다 — 바탕(회색)에 견줘 한 단 옅다.
       --txt-secondary 는 너무 진해 다른 상태 알약과 무게가 엉킨다. */
    background: var(--bk-done-bg); color: var(--txt-muted); white-space: nowrap;
}
/* 상태 배지 — 블록의 작은 배지와 월간 칸의 알약이 «같은 색» 이다 */
/* 상태 색 — 블록의 작은 배지(.bi-bk2-tag--*)와 월간 칸의 알약(.bi-bk2-mpill--*)이 «같은 색» 이다.
   ⚠ 두 기본 규칙(.bi-bk2-tag · .bi-bk2-mpill)보다 «뒤» 에 있어야 한다 — 같은 특이도면 뒤가 이긴다. */
.bi-bk2-tag--req,
.bi-bk2-mpill--req  { background: var(--bk-req-bg);  color: var(--bk-req); }
.bi-bk2-tag--fix,
.bi-bk2-mpill--fix  { background: var(--bk-fix-bg);  color: var(--bk-fix); }
.bi-bk2-tag--done,
.bi-bk2-mpill--done { background: var(--bk-done-bg); color: var(--txt-muted); }   /* §72-2 규격안 값 */
.bi-bk2-mpill--off  { background: var(--bg-card);    color: var(--bk-off); box-shadow: inset 0 0 0 1px var(--bk-off); }

/* 월간에는 눈금이 없다 — [30분][1시간] 을 감춘다 */
.bi-page.is-monthview #bk_step_seg { display: none; }

/* 바닥 오른쪽 안내 — 보기에 따라 글이 바뀐다(§64) */
.bi-bk2-vfoot__hint { margin-left: auto; }

/* ── §65-6 시술·상품 바닥 요약 ────────────────────────────────────────
   태그 사이 빈칸에 기대지 않고 «제 간격» 을 갖는다(§7 함정: 태그 경계의 빈칸이 붙어 버린다). */
.bi-bq-items__est { display: inline-flex; align-items: baseline; gap: var(--space-1); }
.bi-bq-items__end { margin-left: var(--space-2_5); position: relative; padding-left: var(--space-3); }
.bi-bq-items__end::before { content: '·'; position: absolute; left: 0; color: var(--txt-disabled); }

/* ── §65-7 예약등록과 상품추가는 «같은 조각» 을 쓴다 ────────────────────
   태그·수량·삭제·줄 속 묶음은 두 창에서 똑같이 생겼다. 담은 목록 안에서만 한 치수 작게. */

/* ══════════════════════════════════════════════════════════════════════════
   되살리기 ④ — 조각 파일에 없던 규격들 (툴바 · 예약 블록 색 · 디자이너 줄)
   ══════════════════════════════════════════════════════════════════════════ */

/* ── §57-2 예약 블록 — 좌측 3px 색 바 + 연한 바탕 + 모서리 6px (시안 d1·d2) ──
   가로 판·세로 판·주간이 «같은 이름» 을 쓴다. 색은 :root 의 --bk-* 아홉에서만 나온다. */
.bi-bk2-ev {
    border: 1px solid var(--border-light);
    border-left: 3px solid var(--bk-done);
    border-radius: var(--radius-md);
    background: var(--bk-done-bg);
    overflow: hidden;
}
.bi-bk2-ev--req  { border-left-color: var(--bk-req);  background: var(--bk-req-bg); }
.bi-bk2-ev--fix  { border-left-color: var(--bk-fix);  background: var(--bk-fix-bg); }
.bi-bk2-ev--done { border-left-color: var(--bk-done); background: var(--bk-done-bg); }
/* 2026-09-16 시안 대조 — 취소 블록의 점선은 «옅은 분홍»(#FECACA)이고, 고객명에 취소선이 있다.
   진한 빨강(--bk-off)은 바닥 색표의 점이고 블록 테두리가 아니다(시안 d1.png 4배 확대 실측). */
.bi-bk2-ev--off  { border: 1px dashed var(--bk-off-line); background: var(--bg-card); color: var(--txt-disabled); }
.bi-bk2-ev--off .bi-bk2-ev__nm { text-decoration: line-through; text-decoration-color: var(--txt-disabled); }
/* ⚠ 2026-09-29 (2) — 휴무 전표의 «예약마감» 칸 (사용자 지적 4).
   .bi-bk2-ev--off 는 «취소·노쇼» 를 위한 꼴이라 이름에 줄이 그어진다 —
   마감은 지워진 예약이 아니라 «받지 않는 시간» 이다. 줄을 지우고 회색으로 채운다. */
.bi-bk2-ev--off.is-closed {
    border-style: solid;
    border-color: var(--border-base);
    background: repeating-linear-gradient(135deg,
        var(--gray-100) 0, var(--gray-100) 6px, var(--bg-input) 6px, var(--bg-input) 12px);
    color: var(--txt-muted);
    cursor: pointer;
}
.bi-bk2-ev--off.is-closed .bi-bk2-ev__nm {
    text-decoration: none;
    font-weight: var(--fw-bold);
    color: var(--txt-muted);
}
.bi-bk2-ev--off.is-closed .bi-bk2-vev__st { color: var(--txt-muted); }

/* ══ 2026-09-29 (3) 휴무·휴게 «예약마감» 칸 (사용자 지시) ══════════════════════
   사용자: 「예약마감일 경우 해당 중앙영역 선택같이 선택 안 되고 **회색 배경색**으로 나오면 좋겠어」
   ⚠ 빈 칸(.bi-bk2-vslot) «위» 에 덮는다 — 아래 빈 칸이 클릭을 먹으면 마감인 시간에
      새 예약이 열린다. z-index 를 예약 카드보다는 낮게 두어 카드는 위에 보이게 한다. */
.bi-bk2-voff {
    /* ⚠ --t·--h 에 «되돌림 값» 을 준다 — 그래야 styleguide2 전시에서 인라인 style 없이
       그대로 보여 줄 수 있다(§4 신규 인라인 style 금지). 실제 판은 늘 값을 준다. */
    position: absolute; left: 0; right: 0;
    top: var(--t, 0); height: var(--h, 100%);
    z-index: 1;
    display: flex; align-items: center; justify-content: center;
    /* ⚠ 2026-09-30 사용자 지적 — 「빗금이 있는 모양인데 너무 눈에 띄어 조금 더 연한 색으로」.
       gray-200/gray-100 은 예약 카드보다 진해 «판이 마감투성이» 로 보였다.
       한 단계 내려 gray-100 / bg-card 로 — 무늬는 남기되 뒤로 물러나게. */
    background: repeating-linear-gradient(135deg,
        var(--gray-100) 0, var(--gray-100) 5px, var(--bg-card) 5px, var(--bg-card) 10px);
    border-top: 1px solid var(--border-light);
    border-bottom: 1px solid var(--border-light);
    cursor: not-allowed;
}
.bi-bk2-voff__t {
    font-size: var(--fs-2xs); font-weight: var(--fw-bold);
    color: var(--txt-disabled);
    background: var(--bg-card);
    /* 1px 은 스케일에 없다(L1 TK-SPACE) — 가장 작은 칸 2px 로. 작은 알약이라 눈에 안 띈다 */
    padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm);
    opacity: .9;
}
/* 칸이 짧으면 글자가 넘친다 — 30분짜리는 글자를 숨기고 무늬만 남긴다 */
.bi-bk2-voff[style*="--h:1."] .bi-bk2-voff__t,
.bi-bk2-voff[style*="--h:2."] .bi-bk2-voff__t { display: none; }
/* 예약일정표(시간)의 «예약마감» 칸 — 일간과 같은 결. 가로 판이라 left/width 로 놓는다. */
.bi-bk2-hoff {
    /* 되돌림 값 — 전시에서 인라인 style 없이 보이게(위 .bi-bk2-voff 와 같은 까닭) */
    position: absolute; top: 0; bottom: 0;
    left: var(--l, 0); width: var(--w, 100%);
    z-index: 1;
    display: flex; align-items: center; justify-content: center;
    /* 일간과 같은 연한 무늬 (2026-09-30 사용자 지적) */
    background: repeating-linear-gradient(135deg,
        var(--gray-100) 0, var(--gray-100) 5px, var(--bg-card) 5px, var(--bg-card) 10px);
    border-left: 1px solid var(--border-light);
    border-right: 1px solid var(--border-light);
    cursor: not-allowed;
    pointer-events: auto;
}
.bi-bk2-hoff__t {
    font-size: var(--fs-2xs); font-weight: var(--fw-bold);
    color: var(--txt-disabled); background: var(--bg-card);
    /* 1px 은 스케일에 없다(L1 TK-SPACE) — 가장 작은 칸 2px 로. 작은 알약이라 눈에 안 띈다 */
    padding: var(--space-0_5) var(--space-1_5); border-radius: var(--radius-sm); opacity: .9;
    white-space: nowrap;
}
.bi-bk2-hrow__t .bi-bk2-ev { z-index: 2; }

/* 상태 가이드의 «예약마감» 표시 — 판의 마감 무늬와 같은 결 */
.bi-bk2-vfoot__sw--closed i,
.bi-resv-sw--closed {
    background: repeating-linear-gradient(135deg,
        var(--gray-300) 0, var(--gray-300) 3px, var(--gray-100) 3px, var(--gray-100) 6px);
    border: 1px solid var(--border-base);
}

/* 예약 카드는 마감 위에 선다 */
.bi-bk2-vev { z-index: 2; }

.bi-bk2-ev__hd   { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); margin-bottom: var(--space-1); }
.bi-bk2-ev__time { font-size: var(--fs-sm); color: var(--txt-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-bk2-ev__nm   { display: flex; align-items: center; gap: var(--space-1_5); font-size: var(--fs-base); font-weight: var(--fw-bold); white-space: nowrap; overflow: hidden; }
.bi-bk2-ev__pro  { margin-top: var(--space-1); font-size: var(--fs-sm); color: var(--txt-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 블록의 작은 상태 배지(.bi-bk2-tag)는 위에 이미 있다 — 두 벌로 적지 않는다 */

/* ── 디자이너 줄 — 이름 위, 직급 아래 (한 줄로 붙어 「원장 윤희원장」 이 됐다) ── */

/* ── §58 툴바 — 시안: ‹ [날짜] › [오늘] · 실시간 배지 · 「예약 N건 …」 ─────── */
.bi-bk2-tool__l { display: inline-flex; align-items: center; gap: var(--space-2); flex: 1 1 auto; min-width: 0; }
.bi-bk2-cal__arw {
    width: 28px; height: 28px; flex: 0 0 auto;
    border: 1px solid var(--border-base); border-radius: var(--radius-md);
    background: var(--bg-card); color: var(--txt-muted); cursor: pointer;
}
.bi-bk2-cal__arw:hover { background: var(--bg-hover); color: var(--txt-primary); }
.bi-bk2-daybtn {
    height: 32px; padding: 0 var(--space-3); flex: 0 0 auto;
    border: 1px solid var(--border-base); border-radius: var(--radius-md);
    background: var(--bg-card); color: var(--txt-primary);
    font-size: var(--fs-base); font-weight: var(--fw-bold); cursor: pointer; white-space: nowrap;
}
.bi-bk2-daybtn:hover { background: var(--bg-hover); }
.bi-bk2-live {
    display: inline-flex; align-items: center; gap: var(--space-1_5); flex: 0 0 auto;
    height: 26px; padding: 0 var(--space-2_5); border-radius: var(--radius-full);
    background: var(--bk-run-bg); color: var(--bk-run);
    font-size: var(--fs-sm); font-weight: var(--fw-bold); white-space: nowrap;
}
.bi-bk2-live::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--bk-run); }
/* 한 줄 회색 부연 — 머리 줄 집계 · 담은 상품 줄 */
/* §68 한 줄 요약(말줄임)은 아래 .bi-bk2-stat,.bi-bp2__cm 로 합쳤다 */
.bi-bk2-stat b { color: var(--txt-primary); }

/* 머리 줄 오른쪽 도구 묶음 · 달력 앞뒤 이동 — 같은 «가로 한 줄 묶음» 이다 */
.bi-bk2-tools,
.bi-bk2-cal__nav { display: inline-flex; align-items: center; gap: var(--space-2_5); }
.bi-bk2-biz { font-size: var(--fs-sm); color: var(--txt-muted); white-space: nowrap; }

/* 눈금 알약 — [30분][1시간] */
.bi-bk2-seg {
    display: inline-flex; padding: var(--space-0_5);
    border: 1px solid var(--border-base); border-radius: var(--radius-md); background: var(--bg-subtle);
}
.bi-bk2-seg__b {
    /* §68-6 키를 사다리(§12-4)의 22 로 못박는다 — 안쪽 여백에 맡겼더니 20 이 나왔다 */
    height: 22px; padding: 0 var(--space-2_5); border: 0; border-radius: var(--radius-sm);
    display: inline-flex; align-items: center;
    background: transparent; color: var(--txt-secondary);
    font-size: var(--fs-sm); font-weight: var(--fw-medium); cursor: pointer; white-space: nowrap;
}
.bi-bk2-seg__b.is-on {
    background: var(--bg-card); color: var(--txt-primary);
    font-weight: var(--fw-bold); box-shadow: var(--shadow-xs);
}

/* ── 머리 줄의 도구·날짜 칩 (예약 관리 · 새 예약 · 날짜) ── */
.bi-bk2-head-acts { display: inline-flex; align-items: center; gap: var(--space-2); }
.bi-bk2-headdate {
    display: inline-flex; align-items: center; gap: var(--space-1_5);
    height: 32px; padding: 0 var(--space-3); border-radius: var(--radius-md);
    background: var(--bg-selected); color: var(--txt-primary);
    font-size: var(--fs-base); font-weight: var(--fw-bold); white-space: nowrap;
}

/* 좌 패널 카드 안 «두 묶음» 사이 간격 (스케줄 상태 ↔ 예약 유형) */
.bi-bk2-card__t--gap { margin-top: var(--space-3_5); }

/* ── §59-2·§60 브릿지 변수에 폴백 — 없으면 선언 «전체» 가 무효가 된다(QC TK-UNDEF) ──
   값을 못 받은 조각이 0 자리에 얌전히 앉는 편이, 위치가 통째로 날아가는 것보다 낫다. */
/* 브릿지 변수 폴백 — 값이 없으면 선언 «전체» 가 무효가 된다(QC TK-UNDEF) */
.bi-bk2-vaxis__t,
.bi-bk2-vline,
.bi-bk2-vnow { top: var(--t, 0); }
.bi-bk2-vslot    { top: var(--t, 0); height: var(--h, 0); }
.bi-bk2-vev {
    top: var(--t, 0); height: var(--h, 0);
    /* 1px 은 «맞닿은 두 블록을 떼는 실금» 이다 — 간격 사다리의 칸이 아니다 */
    margin: 1px var(--space-1) 1px 0;
    display: flex; flex-direction: column;
    max-width: calc(100% - var(--space-1));
}
.bi-bk2-vev .bi-bk2-ev__hd { flex: 0 0 auto; }

/* §64-5 · §65-8 styleguide2 12-5-6 견본 전용 — 실제 화면은 판이 화면을 채우지만
   견본은 «조각» 만 보여 준다. 자리를 못박는다(§4: 인라인 style 금지 → 클래스로). */
.sg2doc-mdemo   { border: 1px solid var(--border-base); border-radius: var(--radius-lg); overflow: hidden; }
.sg2doc-wdemo   { --vh: 150px; min-width: 0; border: 1px solid var(--border-base);
                  border-radius: var(--radius-lg) var(--radius-lg) 0 0; overflow: hidden; }
.sg2doc-wdemo .bi-bk2-vhead__d, .sg2doc-wdemo .bi-bk2-vcol { min-width: 0; }
.sg2doc-regdemo { display: flex; flex-direction: column; gap: var(--space-3); max-width: 560px;
                  border: 1px solid var(--border-base); border-radius: var(--radius-lg); padding: var(--space-4); background: var(--bg-card); }
.sg2doc-bpdemo  { height: 380px; border: 1px solid var(--border-base); border-radius: var(--radius-lg); overflow: hidden; background: var(--bg-card); }

/* §61-5b 주간 모드에서 «고른 주» 가 네이비로 덮여 날짜가 안 보였다 (2026-09-14)
   옛 규칙은 .bi-cal__wrow.is-wsel .bi-cal__day 를 흰 글자로 만들고 있었는데,
   §61-5 에서 날짜 칸 이름을 .bi-bk2-cal__d 로 바꾸면서 그 규칙이 «빈 선택자» 가 됐다
   — 바탕만 네이비로 남고 글자는 검은 채라 통째로 안 읽혔다(§7: 이름 바꾸면 그 이름을 찾는 규칙까지 본다). */
/* §68-3 흰 글자는 걷었다 — 고른 주도 «날짜 색» 을 그대로 지킨다. 글씨만 굵게. */
.bi-cal__wrow.is-wsel .bi-bk2-cal__d { font-weight: var(--fw-extrabold); }

/* ══ §66-3 상품 추가 팝업 — 규격안 p1.png / spec_bk/prod.html (2026-09-14) ═══════
   2026-09-14 사용자: 「기존 매출등록에 시술/상품 추가 팝업 ui 변경한게 아닌가??」
   맞다 — 새로 만들 것이 아니라 «있는 것» 을 규격안에 맞추는 일이었다.
   왼쪽(검색·갈래·분류·목록)은 있던 것을 그대로 두고 오른쪽 «담은 상품» 만 얹는다. */

/* ⚠ 두 쪽(격자) 배치는 접었다(2026-09-14) — .bi-pop-catalog 는 display:flex + height:100vh 를
   전제로 짜여 있어 격자로 바꾸면 폭 계산이 무너진다(상품명이 한 글자씩 세로로 쌓였다).
   이 창은 매출등록·입고등록·AI 메시지도 쓴다 — 구조를 흔들지 않는다.
   규격안에서 남긴 것: 줄의 «분류 · 소요분» 과 바닥 단추의 「N건 담기 · ₩합계」. */

/* 오른쪽 «담은 상품» 칸 규격(.bi-bp2__rhd ~ __sumrow)은 접었다(2026-09-14) —
   두 쪽 배치를 되돌리면서 쓰는 곳이 없어졌다. 남은 것은 목록 줄의 부연(.bi-bp2__rm) 뿐이다. */

/* 목록 줄의 «분류 · 소요분» — 이름 아래 작은 회색 글(규격안 p1) */

/* §66-3b styleguide2 견본 전용 — 실제 팝업은 화면을 채우지만 견본은 «조각» 만 보여 준다 */

/* ══ §67 주간 — «집계 격자»(규격안 spec_bk/week.html) 2026-09-14 ═══════════
   사용자: 「한 요일에 여러 디자이너 자료가 겹처서 보기가 어려워 … 월간과 비슷하게」
   타임라인을 버리고 월간과 «같은 언어» 로 센다 — 행 두 시간 · 열 요일 · 칸 건수 알약.
   ⚠ 칸 모양·알약은 월간(.bi-bk2-mcell / -mpill)과 한 벌을 나눠 쓴다. 두 벌로 만들지 않는다. */
.bi-bk2-wgrid, .bi-bk2-wgrid * { box-sizing: border-box; }

/* 왼쪽 첫 칸은 «시간 열» 자리다 — 비어 있지만 격자를 맞춘다 */
.bi-bk2-whead__x { border-right: 0; }
.bi-bk2-whead {
    display: grid; grid-template-columns: 92px repeat(7, 1fr);
    border-bottom: 1px solid var(--border-base); background: var(--bg-card);
    position: sticky; top: 0; z-index: 2;
}
.bi-bk2-whead__d {
    padding: var(--space-2_5) var(--space-2); text-align: center; cursor: pointer;
    border-left: 1px solid var(--border-light);
    background: var(--bg-card); border-top: 0; border-right: 0; border-bottom: 0;
    font: inherit; color: inherit;
}
.bi-bk2-whead__d:hover { background: var(--bg-hover); }
.bi-bk2-whead__d b    { display: block; font-size: var(--fs-base); font-weight: var(--fw-bold); }
.bi-bk2-whead__d span { font-size: var(--fs-sm); color: var(--txt-disabled); }
/* 건수는 날짜 옆 괄호로 — 세 줄이면 머리가 너무 높다(§68-2) */
.bi-bk2-whead__d.is-sun b   { color: var(--color-danger-500); }
.bi-bk2-whead__d.is-sat b   { color: var(--brand-blue); }
.bi-bk2-whead__d.is-today b { color: var(--bk-run); }

.bi-bk2-wbody { display: grid; grid-template-columns: 92px repeat(7, 1fr); grid-auto-rows: 96px; }
.bi-bk2-wtime {
    display: flex; align-items: center; justify-content: flex-end;
    padding: 0 var(--space-2_5); border-top: 1px solid var(--border-light);
    font-size: var(--fs-sm); color: var(--txt-disabled); white-space: nowrap;
}
.bi-bk2-wcell {
    display: flex; flex-direction: column; gap: var(--space-1);
    padding: var(--space-2); text-align: left; overflow: hidden;
    border-top: 1px solid var(--border-light); border-left: 1px solid var(--border-light);
    border-right: 0; border-bottom: 0;
    background: var(--bg-card); cursor: pointer;
    -webkit-appearance: none; appearance: none; font: inherit; color: inherit;
}
.bi-bk2-wcell:hover { background: var(--bg-hover); }

/* §67-2 styleguide2 견본 전용 — 실제 판은 요일 일곱이지만 견본은 셋만 세운다 */
.sg2doc-wgdemo { border: 1px solid var(--border-base); border-radius: var(--radius-lg); overflow: hidden; }
.sg2doc-wgdemo .bi-bk2-whead,
.sg2doc-wgdemo .bi-bk2-wbody { grid-template-columns: 92px repeat(3, 1fr); }

/* §67-3 «진행중» 배지는 하루를 볼 때 뜻이 있다 — 월간엔 규격안에도 없다.
   ⚠ .bi-hidden 이 먼저 선언돼 있어 뒤에 온 .bi-bk2-live 의 display 가 이긴다(§7 학습된 함정).
      숨김을 «같이» 선언해야 진짜 숨는다. */
.bi-bk2-live.bi-hidden { display: none; }

/* §66-3b 목록 줄의 «분류 · 소요분» 은 이름 «아래» 줄이다(규격안 p1) — 옆에 붙으면 이름과 엉킨다 */
.bi-pop-prod-ul .bi-bp2__rm { display: block; font-weight: var(--fw-normal); }

/* ══ §68 상품 추가 팝업 — 규격안 p1.png / spec_bk/prod.html 의 «두 쪽» (2026-09-14) ═══
   ⚠ .bi-pop-catalog 는 flex column + height:100vh 다. 세로 흐름을 깨지 않으려면
     «목록 한 덩이» 만 오른쪽 칸과 나란히 묶는다(검색·갈래·분류·푸터는 건드리지 않는다).
     지난번 통째로 감쌌다가 상품명이 «한 글자씩» 세로로 쌓였다. */
.bi-bp2__mid {
    flex: 1 1 auto; min-height: 0;
    display: flex; gap: 0;
}
/* 목록은 이 줄 안에서 남는 폭을 쓴다 */
.bi-bp2__mid > .bi-pop-cat-list { flex: 1 1 auto; min-width: 0; }

.bi-bp2__r {
    flex: 0 0 300px; min-width: 0;
    display: flex; flex-direction: column;
    border-left: 1px solid var(--border-light); background: var(--bg-card);
}
.bi-bp2__rhd { display: flex; align-items: center; padding: var(--space-3) var(--space-3_5) var(--space-2); }
.bi-bp2__rt { font-size: var(--fs-base); font-weight: var(--fw-extrabold); }
.bi-bp2__rt b { color: var(--bk-fix); }
.bi-bp2__reset { margin-left: auto; border: 0; background: none; cursor: pointer; font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-bp2__reset:hover { color: var(--txt-primary); }

.bi-bp2__cart {
    flex: 1 1 auto; min-height: 0; overflow-y: auto;
    padding: 0 var(--space-3_5); display: flex; flex-direction: column; gap: var(--space-2);
}
.bi-bp2__ci {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2_5); border: 1px solid var(--border-base); border-radius: var(--radius-lg);
}
.bi-bp2__cb { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.bi-bp2__ct { font-size: var(--fs-base); font-weight: var(--fw-bold); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-bp2__cm { font-size: var(--fs-sm); color: var(--txt-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* §72-2 머리 요약은 규격안(staff·time)이 13 이다 — 담은상품 줄(12)과 한 규격으로 묶었더니 작아졌다 */
.bi-bk2-stat { font-size: var(--fs-base); color: var(--txt-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-bq-qty,
.bi-bp2__qty { display: inline-flex; align-items: center; flex: 0 0 auto; border: 1px solid var(--border-base); border-radius: var(--radius-md); overflow: hidden; }
.bi-bp2__qty button { width: 24px; height: 24px; border: 0; background: var(--bg-card); color: var(--txt-muted); cursor: pointer; }
.bi-bp2__qty button:hover { background: var(--bg-hover); color: var(--txt-primary); }
.bi-bp2__qty > span { width: 24px; text-align: center; font-size: var(--fs-sm); font-weight: var(--fw-bold); }
.bi-bp2__del {
    width: 24px; height: 24px; flex: 0 0 auto;
    border: 1px solid var(--border-base); border-radius: var(--radius-md);
    background: var(--bg-card); color: var(--txt-disabled); cursor: pointer;
}
.bi-bp2__del:hover { color: var(--bk-off); border-color: var(--bk-off); }
/* 비어 있어도 «어디에 담기는지» 자리를 지킨다(규격안) */
.bi-bp2__empty {
    padding: var(--space-4); border: 1px dashed var(--border-base); border-radius: var(--radius-lg);
    text-align: center; font-size: var(--fs-sm); color: var(--txt-disabled);
}
.bi-bp2__sum { padding: var(--space-3) var(--space-3_5); border-top: 1px solid var(--border-light); background: var(--bg-input); }
.bi-bp2__sumrow { display: flex; align-items: baseline; font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-bp2__sumrow b { margin-left: auto; color: var(--txt-primary); font-size: var(--fs-base); }
.bi-bp2__sumrow--big b { color: var(--bk-fix); font-size: var(--fs-2xl); font-weight: var(--fw-extrabold); }

/* ══ §68-4 주간·월간 «엿보기» 쪽지 ═════════════════════════════════════════
   2026-09-14 사용자 5·8번: 「마우스 오버시 간략하게 예약들이 나오고 선택시 바로 상세보기가
   나왔었는데 다 없어젔어」. 집계 칸으로 바꾸면서 옛 .bi-agg 뭉치가 함께 사라졌다.
   쪽지는 문서에 «하나» 뿐이다 — 칸마다 목록을 심으면 월간 42칸이 통째로 DOM 이 된다.
   ⚠ .bi-hidden 은 «클래스» 다. 아래에서 display 를 정하므로 둘을 «같이» 선언해야 숨는다(§7). */
.bi-bk2-peek {
    position: fixed; z-index: 9500;
    width: 268px; max-height: 320px;
    display: flex; flex-direction: column;
    background: var(--bg-card);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}
.bi-bk2-peek.bi-hidden { display: none; }

.bi-bk2-peek__hd {
    flex: 0 0 auto;
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--border-light);
    background: var(--bg-subtle);
    font-size: var(--fs-xs); color: var(--txt-secondary);
}
.bi-bk2-peek__hd b { color: var(--txt-primary); font-weight: var(--fw-bold); }

.bi-bk2-peek__list { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: var(--space-1); }

.bi-bk2-peek__i {
    /* ⚠ <button> 의 기본 바탕(buttonface)은 appearance:none 으로 지워지지 않는다 — 함께 비운다(§9) */
    appearance: none; background: transparent; cursor: pointer;
    display: flex; align-items: center; gap: var(--space-2);
    width: 100%; padding: var(--space-1_5) var(--space-2);
    border: 0; border-left: 3px solid var(--border-light);
    border-radius: var(--radius-sm);
    text-align: left;
}
.bi-bk2-peek__i:hover { background: var(--bg-hover); }
.bi-bk2-peek__t  { flex: 0 0 38px; font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--txt-secondary); }
.bi-bk2-peek__nm { flex: 1 1 auto; min-width: 0; font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--txt-primary);
                   overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bi-bk2-peek__e  { flex: 0 0 auto; font-size: var(--fs-xs); color: var(--txt-muted); }

/* 왼쪽 띠로 상태를 알린다 — 알약 색(§58-3)을 그대로 쓴다. 두 벌로 만들지 않는다 */
.bi-bk2-peek__i.bi-bk-status1 { border-left-color: var(--bk-req); }
.bi-bk2-peek__i.bi-bk-status2 { border-left-color: var(--bk-fix); }
.bi-bk2-peek__i.bi-bk-status3 { border-left-color: var(--bk-off); }
.bi-bk2-peek__i.bi-bk-status4 { border-left-color: var(--bk-done); }
.bi-bk2-peek__i.bi-bk-status5 { border-left-color: var(--bk-off); }
.bi-bk2-peek__i.bi-bk-status6 { border-left-color: var(--bk-done); }

/* §69-6 두 판은 제 키대로 선다 — 규격안이 정한 112·96 고정 줄높이 그대로. */
#calendar_month,
#calendar_week { display: flex; flex-direction: column; }

/* §68 styleguide2 견본 — 쪽지는 실제로 «떠 있는» 것이라 전시할 땐 자리에 앉힌다.
   담은상품 칸도 팝업에선 높이를 물려받지만 여기선 제 키를 스스로 말한다. */
.sg2doc-peekdemo { position: static; max-height: none; }
.sg2doc-bp2demo  { display: block; max-width: 300px; height: 320px; border: 1px solid var(--border-base);
                   border-radius: var(--radius-lg); overflow: hidden; }
.sg2doc-bp2demo .bi-bp2__r { flex: 1 1 auto; height: 100%; border-left: 0; }

/* ══ §69 AI 메시지 발송 — 머리 아이콘·하단 단추 (2026-09-14) ═══════════════
   사용자: 「발송대상고객목록에 헤더 아이콘에 배경이 들어가있어 «배경없는 아이콘»이여야해」

   ⚠ 공용 .bi-ai-hd__ico(§46-1, styleguide2 전시) 는 건드리지 않는다 — 회색 상자가 그 규격이다.
     이 화면의 목록 머리에서만 되받는다(«같은 모양으로 되받는다» — §47 에서 세 번 배운 것).
     상자를 걷으면 30px 칸도 뜻이 없다 → 폭·키를 글자에 맡겨 제목에 바로 붙인다(시안 newai1). */
.bi-ai2-lhd .bi-ai-hd__ico {
    width: auto; height: auto; flex: 0 0 auto;
    background: none; border-radius: 0;
    font-size: var(--fs-lg);
}

/* ══ §69-2 상품 «검색» 팝업(popup_layer_p) — 규격안 p1.png 의 왼쪽 목록 칸 (2026-09-14) ══
   사용자: 「상품별매출현황의 상품검색 팝업과 매출등록의 상품추가 팝업이 달라 …
            상품 검색용 팝업은 규격이 p1.png · 담은 상품 부분이 없고 상품이 1개만 선택되면 돼」

   ⚠ 이 창은 .bi-pop-catalog 스킨을 «그대로» 쓴다 — 새 스킨을 만들지 않는다.
     줄 격자(--pop-check | 1fr | auto)도 그대로다. 전에 이 창이 깨져 보인 이유는
     줄에 «첫 칸(고름 표시)» 이 없어 이름이 18px 칸에 들어가 한 글자씩 쌓였기 때문이다. */

/* ⚠ 마지막 줄이 잘려 있었다 — 푸터는 position:fixed 라 흐름에서 빠져 있는데
     .bi-pop-catalog 는 height:100vh 를 그대로 쓴다. 그만큼을 아래에 비워 둔다.
     («padding-t + 단추 34 + padding-b» 는 이 파일이 이미 쓰는 셈법 — 새 수를 만들지 않는다)
     검색 팝업과 상품 추가 팝업이 같은 스킨이라 둘 다 함께 고쳐진다. */
.bi-pop-catalog{ padding-bottom: calc(var(--pop-foot-pad-t) + 34px + var(--pop-foot-pad-b)); }

/* 몇 개인지 한 줄 — 목록 바로 위 */
.bi-pop-catalog .bi-pop-cat-cnt{
    flex: 0 0 auto;
    padding: 0 var(--space-3) var(--space-2);
    font-size: var(--fs-sm); color: var(--txt-muted);
}

/* 고름 표시 — 한 개만 고르는 창이라 «동그라미» 다(체크 네모는 여럿 고르는 창의 것).
   진짜 input 을 두지 않는다: 전역 input[type=checkbox]{display:none} 과 싸우게 되고,
   고름 상태는 공통 핸들러가 .is-sel 로만 말한다(lib/js/popup_layer.js). */
.bi-pop-catalog .bi-pop-pick{
    width: var(--pop-check); height: var(--pop-check);
    border: 1px solid var(--border-base); border-radius: var(--radius-full);
    background: var(--bg-card); box-sizing: border-box;
}
.bi-pop-catalog .bi-pop-prod-ul > li.is-sel .bi-pop-pick{
    border-color: var(--pop-sel); border-width: 5px; background: var(--bg-card);
}

/* styleguide2 견본 전용 — 실제 창은 height:100vh 로 화면을 채우지만 견본은 «조각» 만 보여 준다.
   폭은 실제(720)의 절반쯤으로 줄여도 세 칸 격자가 그대로 보인다 — 눌리는지 여기서도 드러난다. */
.sg2doc-catdemo{
    height: auto; padding: 0; max-width: 520px;
    border: 1px solid var(--border-base); border-radius: var(--radius-lg); overflow: hidden;
}
.sg2doc-catdemo .bi-pop-cat-cnt{ padding-top: var(--space-2_5); }

/* 푸터 왼쪽 안내 — 규격 푸터가 오른쪽 정렬이라 그냥 두면 버튼 쪽으로 밀린다(.bi-pop-check 와 같은 손질) */
.bi-pop-list-foot .bi-pop-foot-note{
    margin-right: auto; flex: 0 1 auto; min-width: 0;
    font-size: var(--fs-sm); color: var(--txt-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ══ §70 테스트 «발송» 은 번호 칸에 붙는다 (2026-09-14) ═══════════════════
   사용자: 「테스트발송 버튼 발송 으로 바꿔줘 **테스트번호 입력 우측에 붙여주고**」
   두 조각이 떨어져 있으면 「이 버튼이 저 칸의 것인가」 가 매번 물음이 된다 —
   붙여서 «한 덩어리»(입력 그룹)로 만든다. 맞물리는 자리는 테두리가 «한 줄» 이어야 한다. */
.bi-ai2-test { gap: 0; }
.bi-ai2-test__in {
    height: 32px;                                    /* 옆 단추(base 32)와 키를 맞춘다 — 어긋나면 계단이 진다 */
    border-top-right-radius: 0; border-bottom-right-radius: 0;
}
.bi-ai2-test .bi-btn {
    border-top-left-radius: 0; border-bottom-left-radius: 0;
    margin-left: -1px;                               /* 두 테두리가 겹쳐 «두 줄» 로 보이는 것을 막는다 */
}
.bi-ai2-test .bi-btn:hover, .bi-ai2-test .bi-btn:focus { position: relative; z-index: 1; }

/* ══════════════════════════════════════════════════════════════════════
   §71 팝업 다섯 — 규격안 (2026-09-14)
   시안 pd1(디자이너 검색) · pd2(고객 검색) · pd3(상품 검색) · pd4(스타일 카탈로그) · p1(상품 추가)
   규격안 목업: renew_crm/tools/qc/spec_pop/*.html  (시안을 «우리 토큰으로 다시 그린 것»)
   ⚠ 사용자 2026-09-14: 「시안과 규격안은 별개로 규격안을 시안 참고로 그려줘야지」
     — 시안의 색·치수를 그대로 옮기지 않는다. 우리 팔레트·사다리로 «번역» 한 값이 여기 있다.
   ══════════════════════════════════════════════════════════════════════ */
/* ── §71-1 머리 — 시안은 아이콘이 «네이비 채운 둥근 사각» 이고 제목 옆에 부제가 붙는다 ──
   지금 우리 머리는 회색 외곽선 아이콘 + 제목뿐이다. */
/* ⚠ .bi-pop-head--compact .bi-pop-head-ico(0,2,0)가 이미 «회색·둥글기 0» 을 못박고 있다.
     한 클래스로 적으면 진다 — «같은 모양으로 되받는다»(§47·§69 에서 네 번 겪은 함정).
   ⚠ 크기는 28 그대로다. 30 으로 키우면 머리 높이(56)가 바뀌고,
     popup_layer.js 가 그 높이로 iframe 을 잘라 팝업 바닥에 흰 띠가 남는다. */
.bi-pop-head--compact .bi-pop-head-ico--fill{
    background: var(--brand-navy); color: var(--bg-card);
    border-radius: var(--radius-md);
}
.bi-pop-head-sub{
    font-size: var(--fs-sm); font-weight: var(--fw-normal); color: var(--txt-muted);
    margin-left: var(--space-1_5); min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 부제가 없는 팝업이 훨씬 많다 — 비면 자리도 갖지 않는다(빈 요소도 gap 을 먹는다, §7) */
.bi-pop-head-sub:empty{ display: none; }
/* 건수는 «괄호» 가 아니라 옅은 알약 — 시안 pd1「4명」 pd2「1명」 */
.bi-pop-head-cnt--pill{
    display: inline-flex; align-items: center; height: 20px; padding: 0 var(--space-2);
    border-radius: var(--radius-full);
    background: var(--bg-input); color: var(--txt-secondary);
    font-size: var(--fs-xs); font-weight: var(--fw-bold);
    margin-left: var(--space-1_5);
}

/* ── §71-2 거르개 칩 줄 — 시안 pd1(직급) · pd2(범위) · pd3/p1(분류) 이 같은 모양이다 ──
   고른 칩은 «보라 채움». 지금 .bi-pop-chip-ul 의 연파랑 테두리는 눈에 잘 안 띈다. */
.bi-pop-filters{
    display: flex; align-items: center; gap: var(--space-1_5); flex-wrap: wrap;
    padding: 0 var(--pop-head-pad-x) var(--space-2_5);
}
.bi-pop-filters__hint{
    margin-left: auto; font-size: var(--fs-sm); color: var(--txt-muted); white-space: nowrap;
}
.bi-pop-fchip{
    display: inline-flex; align-items: center; height: 28px; padding: 0 var(--space-3);
    border: 1px solid var(--border-base); border-radius: var(--radius-full);
    background: var(--bg-card); color: var(--txt-secondary);
    font-size: var(--fs-base); font-weight: var(--fw-semibold);
    cursor: pointer; box-sizing: border-box; white-space: nowrap;
}
.bi-pop-fchip:hover{ border-color: var(--gray-300); color: var(--txt-primary); }
/* §73 시안 pd4 — 칩 안의 수는 «옅은 알약» 이다. 그냥 두면 「전체0」 으로 붙어 보인다 */
.bi-pop-fchip b{
    display: inline-block; margin-left: var(--space-1_5); padding: 0 var(--space-1_5);
    border-radius: var(--radius-full); background: var(--bg-input); color: var(--txt-secondary);
    font-size: var(--fs-xs); font-weight: var(--fw-bold);
}
.bi-pop-fchip.is-sel b{ background: var(--bg-card); color: var(--bk-run); }
.bi-pop-fchip.is-sel{
    background: var(--pop-sel); border-color: var(--pop-sel); color: var(--bg-card);
}

/* ── §71-3 사람 줄 — 아바타 · 이름+배지 · 보조줄 (시안 pd1·pd2) ─────────── */
.bi-pop-avt{
    width: 34px; height: 34px; flex: 0 0 34px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: var(--radius-full);
    background: var(--gray-200); color: var(--txt-secondary);
    font-size: var(--fs-sm); font-weight: var(--fw-bold);
}
/* 고른 줄의 아바타는 강조색으로 — 어느 사람이 골라졌는지 줄 전체가 말한다 */
.bi-pop-clist-item.is-sel .bi-pop-avt{ background: var(--pop-sel); color: var(--bg-card); }
.bi-pop-tag{
    display: inline-flex; align-items: center; height: 19px; padding: 0 var(--space-1_5);
    border-radius: var(--radius-sm);
    background: var(--bg-input); color: var(--txt-secondary);
    font-size: var(--fs-xs); font-weight: var(--fw-bold);
    flex: 0 0 auto;
}
/* §75-5 파란 배지 — 시안 실측 바탕 #EEF2FF(--pop-pill-bg) · 글자 #1D4ED8(--color-info-700).
   pd1 「원장」 · pd2 차트번호 · p1 담은 상품 갈래 배지가 모두 이 색이다. */
.bi-pop-tag--top{ background: var(--pop-pill-bg); color: var(--color-info-700); }
/* 오른쪽 끝 «골랐다» 동그라미 — 좌측 막대만으로는 약하다(시안 pd1·pd2) */
.bi-pop-pick2{
    width: 20px; height: 20px; flex: 0 0 20px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--border-base); border-radius: var(--radius-full);
    background: var(--bg-card); color: transparent; font-size: 11px;
}
.bi-pop-clist-item.is-sel .bi-pop-pick2{
    background: var(--pop-sel); border-color: var(--pop-sel); color: var(--bg-card);
}
/* 담당 디자이너를 줄 오른쪽에 «작은 사람» 으로 (시안 pd2) */
.bi-pop-owner{ display: flex; align-items: center; gap: var(--space-2); flex: 0 0 auto; }
.bi-pop-owner__b{ min-width: 0; text-align: left; }
.bi-pop-owner__lb{ display: block; font-size: var(--fs-xs); color: var(--txt-muted); line-height: 1.4; }
/* ⚠ 2026-09-21 — 색 선언이 «없어서» 물려받고 있었다. 실제 화면에서는 #1F2937 로 내려오는데
   규격안 목업에서는 브라우저 기본 **검정(#000000)** 으로 떨어져 글자 검사가 어긋났다.
   형제인 .bi-pop-owner__lb 는 토큰(--txt-muted)을 쓰는데 이 줄만 빠져 있었다.
   지금 보이는 값을 그대로 토큰으로 못 박는다 — 화면은 안 바뀌고 더는 흐르지 않는다. */
.bi-pop-owner__nm{ display: block; font-size: var(--fs-sm); font-weight: var(--fw-bold); line-height: 1.4; color: var(--gray-800); }
.bi-pop-owner .bi-pop-avt{ width: 28px; height: 28px; flex: 0 0 28px; font-size: var(--fs-xs); }
/* ⚠ 2026-09-17 §81-3 — 시안 pd2 는 담당 디자이너 아바타가 «이름 왼쪽» 이다. 우리는 오른쪽이었다.
   마크업(JS 가 만드는 문자열)을 건드리지 않고 flex order 로 앞세운다 — id·name 을 안 바꾼다(§4). */
.bi-pop-owner .bi-pop-avt{ order: -1; }

/* ── §71-4 결과 줄 — 「검색 결과 N명」 · 오른쪽에 정렬 이름 (시안 pd2·pd3·p1) ── */
.bi-pop-resline{
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
    padding: var(--space-2) var(--pop-head-pad-x);
    font-size: var(--fs-sm); color: var(--txt-muted);
    border-top: 1px solid var(--pop-line);
}
.bi-pop-resline b{ color: var(--txt-primary); }

/* ── §71-5 「찾는 고객이 없나요?」 줄 (시안 pd2) ─────────────────────────
   빈 목록에 «그럼 어떻게 하나» 를 남긴다 — 지금은 빈 화면만 남는다. */
.bi-pop-askrow{
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
    padding: var(--space-3) var(--pop-head-pad-x);
    font-size: var(--fs-sm); color: var(--txt-muted);
}

/* §71-6·§71-7 은 §69-2 가 이미 정한 것과 같은 규격이다 — 위에서 한 번만 적는다 */

/* §71-6·§71-7 은 §69-2 가 이미 정한 것과 같은 규격이다 — 위에서 한 번만 적는다 */

/* ── §71-8 카탈로그 — 사진이 주인공 (시안 pd4) ───────────────────────
   좌측 콘솔 상자를 걷고 «탭 줄 + 격자 | 미리보기» 두 단으로. */
/* ⚠ 2026-09-17 — 여기 있던 .bi-cat4__* 한 벌을 **걷어냈다**.
   스타일 카탈로그가 시안대로 다시 서면서 §87 .bi-cat5 로 옮겨 갔다 —
   팝업 · 규격안 목업 · styleguide2 전시가 모두 새 이름을 쓴다. 그 뒤로 이 한 벌은 아무도 안 쓴다.
   남겨 두자 검사 셋이 모두 신규 위반으로 찍었다:
     SPEC-DEAD 22(쓰이지 않는 규격) · SPEC-UNSHOWN 21(전시 안 됨) · SPEC-DUP 16(cat5 와 같은 선언)
   ⚠ «기존 규칙은 지우지 않는다»(§4)는 **살아 있는 규칙**을 지키자는 말이다.
     옮기다 만 껍데기를 남겨 두는 것은 그 규칙이 지키려는 바가 아니다 — 옮겼으면 마저 옮긴다.
     되돌릴 근거는 git 과 §87 문서에 있다. 새 규칙은 §87 에 붙인다. */

/* ── §71-2b 분류 칩도 «고르면 보라 채움» — 거르개는 어디서나 같은 모양이어야 한다 ──
   지금 .bi-pop-chip-ul > li.is-sel 은 연파랑 배경 + 파란 글씨라 «골랐다» 가 약하다.
   시안 pd3·p1 의 「전체」 는 채워져 있다. .bi-pop-fchip 과 같은 값으로 맞춘다. */
.bi-pop-catalog .bi-pop-chip-ul > li.is-sel{
    background: var(--pop-sel); border-color: var(--pop-sel); color: var(--bg-card);
}

/* §71-6b 푸터 왼쪽 «묶음» — 안내와 보조 체크가 함께 왼쪽에 선다 (규격안 p1).
   ⚠ 둘에게 각각 margin-right:auto 를 주면 «남는 자리를 나눠 가져» 사이가 벌어진다.
     하나로 묶고 그 묶음만 밀어낸다. */
.bi-pop-list-foot .bi-pop-foot-l{
    margin-right: auto; min-width: 0;
    display: flex; align-items: center; gap: var(--space-3);
}
.bi-pop-list-foot .bi-pop-foot-l .bi-pop-foot-note,
.bi-pop-list-foot .bi-pop-foot-l .bi-pop-check{ margin-right: 0; }

/* §71-7b 건수 줄과 목록을 «한 덩이» 로 — 목록만 스크롤하고 건수 줄은 붙어 있는다.
   (담은 상품 칸과 나란히 서는 .bi-bp2__mid 안에서 세로로 쌓인다) */
.bi-bp2__cnt{ flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; min-height: 0; }
.bi-bp2__cnt > .bi-pop-cat-list{ flex: 1 1 auto; min-height: 0; }

/* §71-1b 검색 «단추» 를 감출 때 — `.bi-pop-hidden`(0,1,0) 만으로는 안 숨는다.
   `.bi-pop-page .bi-pop-search .sch_but_pop`(0,3,0)이 display:inline-flex 를 못박고 있다.
   ⚠ 특이도는 «나중» 이 아니라 «더 긴 선택자» 가 이긴다 — 같은 모양으로 되받는다(§47·§69 에서 다섯 번째).
   ⚠ .sch_but_pop 자체는 지우지 않는다. 팝업 JS 들이 이 훅을 click 으로 부른다(입력 즉시 검색이 그것을 쏜다). */
.bi-pop-page .bi-pop-srch .sch_but_pop.bi-pop-hidden,
.bi-pop-page .bi-pop-search .sch_but_pop.bi-pop-hidden{ display: none; }

/* §71-3b 사람 줄의 «이름 / 번호» 는 두 줄이다 — 규격안 pd1·pd2.
   .bi-pop-clist-nm·-sub 는 <span> 이라 그대로 두면 한 줄로 이어 붙는다. */
.bi-pop-page .bi-pop-clist-main{ display: flex; flex-direction: column; }
.bi-pop-page .bi-pop-clist-nm,
.bi-pop-page .bi-pop-clist-sub{ display: block; }

/* §71-3c 거르개로 줄을 감출 때 — .bi-pop-hidden(0,1,0) 은
   .bi-pop-page .bi-pop-clist-item{display:flex}(0,2,0) 에 진다. 같은 모양으로 되받는다(여섯 번째). */
.bi-pop-page .bi-pop-clist-item.bi-pop-hidden{ display: none; }

/* §71 styleguide2 견본 — 건수 줄은 팝업에선 목록과 한 덩이지만, 전시할 땐 제 키로 선다 */
.sg2doc-bp2cnt { flex: 0 0 auto; }

/* §71-5b 「찾는 고객이 없나요?」 줄은 결과가 있으면 접는다.
   ⚠ .bi-hidden(0,1,0) 이 .bi-pop-askrow{display:flex}(0,1,0) 보다 «앞» 에 선언돼 있어 진다.
     같은 모양으로 되받는다 — 이번 회차에서만 일곱 번째다. */
.bi-pop-askrow.bi-hidden{ display: none; }

/* §71-9 styleguide2 견본 전용 — 실제 팝업은 창을 채우지만 견본은 «조각» 만 보여 준다 */
.sg2doc-popbits{
    max-width: 620px; border: 1px solid var(--border-base); border-radius: var(--radius-lg);
    overflow: hidden; background: var(--bg-card);
}
.sg2doc-popbits .bi-pop-list-foot{ position: static; width: auto; margin-left: 0; margin-right: 0; }
.sg2doc-popbits .bi-pop-clist{ flex: 0 1 auto; overflow: visible; }
.sg2doc-catgrid{ grid-template-columns: repeat(3, 1fr); max-height: 260px; }
.sg2doc-cat4demo{ height: 300px; }
/* §87 — 전시에서는 .bi-cat5-wrap 의 100vh 를 쓰지 않는다(문서 페이지가 늘어난다) */
.sg2doc-cat5wrap{ height: auto; }

/* §71-1c 검색칸 «지우기» ✕ — 규격안 pd2. 친 글자가 있을 때만 뜬다.
   검색 단추를 걷어냈으니(입력 즉시) 「지우고 처음부터」 가 갈 곳이 없었다. */
.bi-pop-search__box{ position: relative; }
.bi-pop-search__x{
    position: absolute; right: 8px; top: 50%; transform: translateY(-50%);
    width: 22px; height: 22px; padding: 0;
    display: inline-flex; align-items: center; justify-content: center;
    border: 0; border-radius: var(--radius-full);
    background: none; color: var(--txt-disabled); cursor: pointer; font-size: 14px;
}
.bi-pop-search__x:hover{ color: var(--txt-secondary); background: var(--bg-input); }
.bi-pop-search__x.bi-pop-hidden{ display: none; }

/* ══ §72-2 예약 두 화면의 «기본 글자색» ═══════════════════════════════════
   2026-09-14 사용자: 「제일 중요한건 시안에있는 글자크기, 색, 버튼크기」 —
   재 보니 디자이너 이름·블록 이름·시간 머리가 «순검정(#000)» 이었다. 토큰이 아니다.
   색을 안 정한 곳이 문서 기본값을 물려받은 것이다. 판에 한 번 정해 두면
   안에서 따로 정하지 않은 글자는 모두 --txt-primary 가 된다(규격안과 같은 값). */
.bi-bk2-vgrid,
.bi-bk2-hgrid,
.bi-bk2-mgrid,
.bi-bk2-wgrid { color: var(--txt-primary); }

/* 시간 머리는 규격안이 13 이다 — 16 은 어디선가 물려받은 값이었다 */
.bi-bk2-hhead__t { font-size: var(--fs-base); }

/* ══════════════════════════════════════════════════════════════════════
   §72 시안 실측 — 색 · 크기 (2026-09-14)
   사용자: 「중요한건 시안에 나오는 **색, 버튼 크기, 글자크기, 아이콘 색** 이야
            이부분 다시 체크해서 규격안, 실제화면 적용해줘」

   pd1·pd2·pd3·pd4·p1 을 픽셀로 잰 값(tools/qc/_measure_pd*.mjs) — 다섯이 «모두 같았다»:
     주 단추   #1D4ED8 · 키 33      (우리 --brand-blue #0023B7 · 32)
     고른 칩   #5B45E0 · 키 28      (우리 --pop-sel #4F46E5 · 28)
     고른 줄   #EEF3FF              (우리 --bg-selected #F8FAFF)
     아바타    38 / 작은 26         (우리 34 / 28)
     건수 알약 21                    (우리 20)
     머리      55~56 · 아이콘 28    (우리 56 / 28 — 맞음)
   ⚠ 단추 키 33 은 «테두리까지» 다 — 사다리 base(32 + 테두리)와 같은 값이라 사다리를 건드리지 않는다.
   ══════════════════════════════════════════════════════════════════════ */
:root{
    /* 시안의 «고른 줄» 바탕. --bg-selected(#F8FAFF)는 거의 흰색이라 고른 줄이 안 보였다 */
    --pop-row-sel: #EEF3FF;
}

/* ⚠ 주 단추 색은 «팝업 안에서만» 바꾼다.
   --brand-blue(#0023B7)는 온 제품의 주 액션 색이다 — 여기서 토큰을 갈면 화면 전부가 따라 바뀐다.
   시안 다섯은 «팝업» 규격이므로 그 범위에만 댄다. 제품 전체로 옮길지는 사용자 결정 몫. */
.bi-pop-page .bi-btn--primary{
    background: var(--color-info-700); border-color: var(--color-info-700);
}
/* 눌렀을 때는 «있는» 다음 단계로 — 없는 토큰에 폴백 색을 박으면 그 색이 팔레트 밖이 된다 */
.bi-pop-page .bi-btn--primary:hover{ background: var(--color-info-900); border-color: var(--color-info-900); }

/* 고른 칩 — 시안은 #5B45E0 이다(우리 토큰 --bk-run 과 같은 값). --pop-sel(#4F46E5)보다 붉다 */
.bi-pop-fchip.is-sel,
.bi-pop-catalog .bi-pop-chip-ul > li.is-sel{
    background: var(--bk-run); border-color: var(--bk-run); color: var(--bg-card);
}

/* 고른 줄 — 시안 #EEF3FF. 좌측 막대·아바타·체크는 그대로 --pop-sel 계열을 쓴다 */
.bi-pop-page .bi-pop-clist-item.is-sel,
.bi-pop-catalog .bi-pop-prod-ul > li.is-sel{ background: var(--pop-row-sel); }

/* 아바타 — 시안 38(줄) / 26(담당 디자이너) */
.bi-pop-avt{ width: 38px; height: 38px; flex: 0 0 38px; }
.bi-pop-owner .bi-pop-avt{ width: 26px; height: 26px; flex: 0 0 26px; }

/* 건수 알약 — 시안 21 */
.bi-pop-head-cnt--pill{ height: 21px; }

/* §72-2 «고른 것» 강조색 — 시안 다섯 어디에도 #4F46E5 는 없다 (2026-09-14 실측).
   시안의 고름 표시(체크 동그라미 · 좌측 막대 · 고른 아바타)는 주 단추와 «같은» #1D4ED8 이다.
   ⚠ 토큰 자체(--pop-sel)를 갈지 않고 «팝업 문서 안에서만» 다시 정한다 —
     그러면 다섯 팝업뿐 아니라 다른 팝업도 강조색이 한 가지로 모인다(색을 늘리지 않는 쪽).
     화면(페이지) 쪽 --pop-sel 은 그대로다. */
.bi-pop-page{ --pop-sel: var(--color-info-700); }

/* ══ §73 상품 추가 팝업 — p1.png 를 «캡처로 대조해» 나온 자리들 (2026-09-14) ══
   ⚠ 앞선 두 번은 «담은 상품 0건» 상태를 찍어 «2건 담긴» 시안과 견줬다 —
     상태를 맞추지 않으면 대조가 아니다(사용자가 세 번 짚었다). */
/* 담은 상품 칸 — 시안 p1 은 창 880 에 오른쪽 343 이다(우리 300 이라 곱셈식이 더 잘렸다) */
.bi-bp2__r{ flex: 0 0 340px; }
/* 줄의 «단가 × 수량 = 합계» — 합계만 진하게 */
.bi-bp2__cm b{ color: var(--txt-primary); font-weight: var(--fw-bold); }
/* 이름 앞 갈래 배지 */
.bi-bp2__ct .bi-pop-tag{ margin-right: var(--space-1); }
/* 「내부소진 · 샘플로 담기」 — 담은 상품 칸의 합계 «위» 줄 */
.bi-bp2__fill{
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2_5) var(--space-3_5);
    border-top: 1px solid var(--border-light);
    font-size: var(--fs-sm); color: var(--txt-secondary);
}
.bi-bp2__fill small{ color: var(--txt-muted); }

/* ══ §74 AI 메시지 발송 하단 단추 — 규격을 «자리» 로 못박는다 (2026-09-14) ══
   §57·§69 에서 「하단 넷은 본문 단추보다 크다(base 32)」 로 정하고 마크업에서 --sm 을 뗐는데,
   **두 번이나 다시 붙어서 돌아왔다**(다른 세션 작업분 — 바로 위 주석은 「--sm 을 뗀다」 인데 값이 반대였다).
   마크업을 지키는 대신 «그 자리의 단추는 base 다» 를 규격으로 적는다 —
   누가 --sm 을 붙여도 키가 유지된다. 답안지(§69 키 32)도 그대로 통과한다. */
.bi-ai2-side__foot .bi-btn,
.bi-ai2-mfooter .bi-btn{
    padding: var(--space-2) var(--space-4);
    font-size: var(--fs-md);
    border-radius: var(--radius-lg);
}
/* 붙어 있는 «발송» 은 왼쪽 모서리를 그대로 둔다(§70 입력 그룹) */
.bi-ai2-test .bi-btn{ border-top-left-radius: 0; border-bottom-left-radius: 0; }

/* ══ §74 시안을 «셋을 한 장에 붙여» 보고서야 나온 것들 (2026-09-14) ══════════
   사용자(세 번째): 「실제 화면 캡처해서 **비교**해서 처리 내용을 브라우저에 보여달라는데
   그것도 안 되고 있어」 — 맞다. 수치표만 만들고 «그림 셋을 나란히 놓고 보는» 일을 안 했다.
   붙여 놓으니 아래 넷이 한 번에 보였다(tools/qc/pop_strip.mjs 가 그 한 장을 만든다). */

/* ── §74-1 줄 높이 — 시안은 사람 줄 56 · 상품 줄 50 이다(우리 65 · 61) ──────
   시안 pd1 의 목록 구분선 214·270·326 = 56 · pd3 의 234·284·334 = 50.
   ⚠ --pop-row-min-h(62) 는 «2줄 카드행» 규격이라 팝업 목록 전부가 쓴다.
     시안 여섯이 모두 56 이므로 토큰을 시안 값으로 내린다 — 자리마다 다르게 두지 않는다. */
:root{ --pop-row-min-h: 56px; }
.bi-pop-page .bi-pop-clist-item{ padding-top: var(--space-2); padding-bottom: var(--space-2); }
.bi-pop-page .bi-pop-clist-item.is-sel{
    padding-top: var(--space-2); padding-bottom: var(--space-2);
}
/* 상품 줄 — 시안 50 */
.bi-pop-catalog .bi-pop-prod-ul > li{ padding-top: var(--space-2); padding-bottom: var(--space-2); min-height: 50px; }

/* ── §74-2 «고른 것» 은 체크가 정한다 (시안 p1) ────────────────────────────
   시안은 체크된 줄 «둘 다» 연파랑이다. 우리는 마지막에 누른 줄에만 .is-sel 이 붙어
   먼저 체크한 줄이 흰 채로 남았다 — 「무엇을 담았는지」 가 줄에서 안 보였다. */
.bi-pop-catalog .bi-pop-prod-ul > li:has(input[type="checkbox"]:checked){
    background: var(--pop-row-sel);
}

/* ── §74-3 pd2 — 등급 아바타는 «고른 줄에서도 회색» 이고, 담당 디자이너가 네이비다 ──
   우리는 반대로 하고 있었다(고른 줄 등급 아바타를 파랗게 칠했다).
   시안 pd2 실측: 등급 #D1D5DB(38) · 담당 디자이너 #1E3A8A(26). */
.bi-pop-clist-item.is-sel .bi-pop-clist-main ~ .bi-pop-owner .bi-pop-avt,
.bi-pop-owner .bi-pop-avt{ background: var(--color-info-900); color: var(--bg-card); }
.bi-pop-list--member .bi-pop-clist-item.is-sel > .bi-pop-avt{
    background: var(--gray-200); color: var(--txt-secondary);
}

/* ══════════════════════════════════════════════════════════════════════
   §75 시안을 «위아래로 붙여» 보고서야 나온 색·모양 (2026-09-14)
   사용자: 「p1 에 시안과 규격안이 다르잔아 … pd4 도 마찬가지야
            **아이콘 색 버튼 등 전체적인 색**도 다 달라 다시 확인해줘」

   가로로 나란히 놓으면 «비슷해 보인다». 같은 자리를 **위아래로** 붙여야 어긋남이 드러난다
   (§47 3-1 에서 이미 배운 것을 또 어겼다). tools/qc/pop_zoom.mjs 가 그 한 장을 만든다.

   시안 실측(p1·pd3·pd4 공통):
     짙은 네이비  #121D3F   ← 머리 아이콘 · 고른 갈래 탭 · pd4 고른 탭 «셋 다 같은 색»
                            (우리는 --brand-navy #00156E — 훨씬 파랗다)
     갈래 줄 배경 #FFFFFF   ← 우리는 회색 띠(--pop-line-soft)를 깔고 있었다
     고른 탭 상자 56×32 · pd4 69×31 — «알약» 이 아니라 «둥근 사각»
   ══════════════════════════════════════════════════════════════════════ */
:root{
    /* 팝업의 짙은 네이비 — 시안 실측값. --brand-navy(#00156E)는 화면(페이지)의 브랜드색이라 건드리지 않는다 */
    --pop-navy: #121D3F;
}

/* ── §75-1 머리 아이콘 ─────────────────────────────────────────────── */
.bi-pop-head--compact .bi-pop-head-ico--fill{ background: var(--pop-navy); }

/* ── §75-2 갈래 세그먼트 — 줄 배경은 «흰색», 고른 탭은 짙은 네이비 ──────
   지금은 회색 띠 + 테두리로 «상자 안 상자» 처럼 보였다. 시안엔 그 띠가 없다. */
.bi-pop-catalog .bi-pop-seg{
    background: none; border: 0; padding: 0;
}
.bi-pop-catalog .bi-pop-seg > li.is-sel{
    background: var(--pop-navy); border-color: var(--pop-navy);
}

/* ── §75-3 배지는 «기울지 않는다» ───────────────────────────────────
   <em> 으로 적어 브라우저 기본 이탤릭이 걸려 있었다 — 시안의 배지는 곧게 서 있다.
   pd1 직급 · pd2 등급/차트번호 · p1 담은 상품 갈래 배지가 모두 기울어 보였다. */
.bi-pop-tag{ font-style: normal; }

/* ── §75-4 pd4 탭은 «알약» 이 아니라 갈래 세그먼트와 «같은 모양» ────────
   시안 pd4 의 「전체 3」 은 #121D3F 로 채운 둥근 사각(69×31)이다.
   수는 알약이 아니라 «옅은 글자» 로 이름 옆에 붙는다. */

/* §75-6 팝업 안의 «짙은 네이비» 는 하나다 — 머리 아이콘 · 고른 갈래 탭 · 검색 단추.
   검색 단추만 --brand-navy(#00156E) 로 남아 있어 같은 창 안에서 두 네이비가 부딪혔다.
   ⚠ .bi-pop-page .bi-btn--search 로 «같은 모양» 되받는다(0,2,0 → 뒤에 와서 이긴다). */
.bi-pop-page .bi-btn--search{ background: var(--pop-navy); border-color: var(--pop-navy); }
/* 2026-09-16 — 예약등록(db1.png)·입고등록 팝업의 검색 단추는 «시안이 파랑» 이다(#1D4ED8 실측).
   공통 검색 단추(--pop-navy)는 다른 팝업 열 곳이 함께 쓰므로 건드리지 않고 이 두 팝업 안에서만 맞춘다. */
.bi-pop-page .bi-bq-pop .bi-btn--search{ background: var(--color-info-700); border-color: var(--color-info-700); }

/* ══════════════════════════════════════════════════════════════════════
   §76 결제 팝업 셋 — 시안 bs1(카드) · bs2(선불권) · bs3(현금)  (2026-09-15)

   사용자: 「bs1.png, bs2.png, bs3.png 팝업 시안이 추가되었어 해당 3개 팝업에 대해서
            추가적으로 작업이 필요해 · 시안대로 규격안을 만들어주고 … 바로 작업 진행해줘」

   시안 실측(tools/qc/_measure_bs.mjs — 눈대중 금지):
     창 폭        480 (셋 다) · 키 552~558
     머리         55~56                       ← §38-3 컴팩트 머리 그대로
     안내 띠      #F5F6F9 · 키 35(bs1·bs3) · 56(bs2 두 줄)
     주 단추      #1D4ED8 · 440×48 · 좌우 여백 20   ← «전폭 CTA». 사다리의 32/34 가 아니다
     섹션 머리 띠 #F5F6F9 · 438×43
     고른 줄      #EEF3FF (bs2 선불권) · 키 55
     배지         #EEF2FF 바탕 / #1D4ED8 글자 · 「만료 임박」만 #FFF6E5(--bk-req-bg)
     짙은 네이비  #121D3F  ← 머리 아이콘 (§75 와 같다)

   ⚠ 색 다섯이 «이미 우리 토큰» 이다 — 새 색을 들이지 않는다.
     #1D4ED8=--color-info-700 · #121D3F=--pop-navy · #EEF2FF=--pop-pill-bg
     #EEF3FF=--pop-row-sel · #FFF6E5=--bk-req-bg

   ⚠ 전폭 CTA 48 은 «사다리 밖» 이 아니라 새 등급이다 — 시안 셋이 모두 48 이고
     한 창에 하나뿐인 «확정» 단추다. .bi-btn--cta 로 이름을 주어 사다리에 올린다.
   ══════════════════════════════════════════════════════════════════════ */
:root{
    --pop-w-pay:      480px;  /* §76 결제 팝업 — bs1·bs2·bs3 실측 480 */
    --pay2-cta-h:      48px;  /* 전폭 확정 단추 키 — 시안 실측 */
    --pay2-note-h:     35px;  /* 상단 안내 띠 한 줄 */
    --pay2-chd-h:      43px;  /* 섹션 카드 머리 띠 */
    --pay2-row-h:      55px;  /* 고르는 줄(선불권) */
    --pay2-in-h:       36px;
    /* ⚠ 2026-09-16 — 28 이 아니라 26 이다. 시안의 칩 테두리(윗선 y245 · 아랫선 y270)를
       화소로 직접 읽어 확정했다. 28 은 «사다리(§29-2)» 값이라 맞다고 넘겼던 것이다. */
    --pay2-chip-h:     26px;
    /* ⚠ 칩 테두리만 --border-base(#E5E7EB) 가 아니다. 같은 시안에서 안내 띠 아랫선·섹션 카드
       윗선은 #E5E7EB 로 우리와 같은데, **칩만 #D9DFE9**(살짝 푸른 회색)다 — 시안의 뜻이다. */
    --pay2-chip-bd:  #D9DFE9;
    /* ⚠ 2026-09-16 — 「시안과 규격안이 다른가 하나하나 확인해봐」 에서 나온 두 색.
       --bg-page(#F8F9FC) 를 쓰고 있었는데 시안은 #F5F6F9 다(세 채널 모두 3 씩 어둡다).
       눈으로는 거의 같아 넘어갔고, 폭·키·단추만 재던 qc.mjs pop 도 «칠한 면의 색» 은
       안 봤다 — 그래서 _palette.mjs(색을 색으로 센다)를 새로 만들어 잡았다. */
    /* ⚠ 2026-09-16 — 이 «회색 판» 은 결제 팝업만의 것이 아니다. 시안 p1(상품추가)의
       검색·칩 판도 같은 #F5F6F9 다. 이름을 공통으로 두고 --pay2-band 는 별칭으로 남긴다. */
    --pop-band:    #F5F6F9;  /* 시안의 회색 판 — 결제 안내 띠 · 섹션 카드 머리 띠 · 상품추가 검색판 */
    --pay2-band:   var(--pop-band);
    --pay2-track:  #EEF1F6;  /* 수령 방식 세그먼트 트랙 — 시안 실측(8,113 화소). 띠보다 진하다 */
}

/* ── §76-1 골격 — 창을 세로로 채운다(고정 뺄셈 금지, flex:1) ───────────── */
.bi-pay2{
    display: flex; flex-direction: column;
    /* ⚠ 2026-09-15 — 여기가 100vh 였다. 그러면 popup_layer.js 의 «내용 높이 맞춤» 이
       내용 대신 **창 높이**를 재서 상자가 화면만큼 커졌다(푸터 아래 400px 빈 띄).
       시안 셋은 내용만큼(552~558)이다 — 높이는 내용이 정한다. */
    min-height: 0;
    box-sizing: border-box;
    background: var(--bg-card);
    font-size: var(--fs-base); color: var(--txt-secondary);
}
.bi-pay2__body{
    flex: 1 1 auto; min-height: 0;
    /* 시안 실측 — 상하 16 · 좌우 20 (사방 20 이어서 위아래로 8 길었다) */
    padding: var(--space-4) var(--space-5); box-sizing: border-box;
}

/* ── §76-2 상단 안내 띠 — 회색 판에 ⓘ 글리프 ─────────────────────────── */
.bi-pay2__note{
    flex: 0 0 auto;
    display: flex; align-items: center; gap: var(--space-2);
    min-height: var(--pay2-note-h);
    padding: var(--space-2) var(--space-5);
    box-sizing: border-box;
    background: var(--pay2-band);
    border-bottom: 1px solid var(--border-base);
    color: var(--txt-muted); font-size: var(--fs-sm); line-height: 1.5;
}
.bi-pay2__note i{ color: var(--txt-disabled); font-size: var(--fs-md); }
/* ══ 2026-09-29 (2) 카드 승인취소 규격안 (사용자 지시 12-2) ═══════════════════
   결제(bi-pay2)와 «같은 일의 반대쪽» 이라 같은 규격을 쓰되, 두 가지를 더한다 —
     ① 되돌릴 수 없는 일이므로 안내 띠를 «주의» 색으로
     ② «무엇을 취소하는가» 를 한 덩이로 못박는다(금액이 가장 크다)
   색·크기는 새로 들이지 않는다 — 전부 기존 토큰이다.
   규격안: renew_crm/tools/qc/spec_pop/card_cancel.html */
.bi-pay2__note--warn{
    background: var(--color-danger-50);
    border-bottom-color: var(--color-danger-100);
    color: var(--color-danger-700);
}
.bi-pay2__note--warn i{ color: var(--color-danger); }

.bi-pay2__sum{
    border: 1px solid var(--border-base); border-radius: var(--radius-lg);
    background: var(--bg-card); overflow: hidden;
}
.bi-pay2__sumtop{
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border-light);
    background: var(--pay2-band);
}
.bi-pay2__sumlb{ font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-muted); }
.bi-pay2__sumamt{
    font-size: var(--fs-2xl); font-weight: var(--fw-extrabold); color: var(--txt-primary);
    letter-spacing: -.01em;
}
.bi-pay2__sumamt small{ margin-left: var(--space-0_5); font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-muted); }
.bi-pay2__sumgrid{
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-1) var(--space-4);
    padding: var(--space-3) var(--space-4);
}
.bi-pay2__sumgrid > div{ display: flex; align-items: center; gap: var(--space-2); min-width: 0; font-size: var(--fs-sm); }
.bi-pay2__sumgrid span{ flex: 0 0 68px; color: var(--txt-muted); }
.bi-pay2__sumgrid b{
    flex: 1 1 auto; min-width: 0;
    display: flex; align-items: center; gap: var(--space-1_5);
    color: var(--txt-primary); font-weight: var(--fw-bold);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* ⚠ 2026-09-29 (3) 사용자 지적 — 「수기등록 란이 위에 내용과 딱 붙어있어 별로야 떨어뜨려줘」.
   .bi-pay2__card 는 «아래» 여백만 갖고 있어(margin-bottom) 요약 덩이 바로 밑에 붙었다.
   요약 다음에 오는 카드에만 위 여백을 준다 — 공용 규칙은 건드리지 않는다. */
.bi-pay2__sum + .bi-pay2__card{ margin-top: var(--space-4); }
@media (max-width: 560px){ .bi-pay2__sumgrid{ grid-template-columns: 1fr; } }
.bi-pay2__note b{ display: block; font-weight: var(--fw-normal); }
/* ⚠ 2026-09-16 — 두 줄짜리 안내 띠(bs2)는 시안이 56 인데 52 로 서 있었다.
   한 줄(35)은 min-height 가 잡아 주지만 두 줄은 «내용 높이» 라 위아래 여백이 그대로 8 이었다.
   줄 수는 CSS 로 알 수 없으므로 이름을 따로 준다 — :has() 에 기대지 않는다. */
.bi-pay2__note--2{
    min-height: 57px;
    padding-top: var(--space-2_5); padding-bottom: var(--space-2_5);
}

/* ── §76-3 칸 제목 줄 — 왼쪽 라벨 · 오른쪽 «남은 금액» ────────────────── */
/* 시안 — 라벨 줄은 15 (13px × 1.15). 1.3 이면 17 이 돼 아래가 모두 밀린다 */
.bi-pay2__lbrow{
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--space-2); margin-bottom: var(--space-1); line-height: 1.15;
}
.bi-pay2__lb{ font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-secondary); }
/* ⚠ 2026-09-16 — 「*」 가 **검정**으로 찍히고 있었다. 전역 `.bi-req` 에는 색이 없고
   `.bi-pop-f > label .bi-req` · `.bi-pop-flabel-row > label .bi-req` 처럼 «자리마다» 색을 주는데,
   .bi-pay2 의 라벨은 그 어느 선택자에도 안 걸렸다. 시안 bs1 의 「결제일자*」 는 빨강이다.
   ⚠ 요소를 하나하나 대 보고서야 나왔다 — 폭·키·띠 색만 재는 자에는 6×15 짜리 글리프가 안 걸린다. */
.bi-pay2 .bi-req{ color: var(--color-danger); }
.bi-pay2__lb .bi-req{ margin-left: var(--space-0_5); }
.bi-pay2__rest{ font-size: var(--fs-sm); color: var(--txt-muted); white-space: nowrap; }
.bi-pay2__rest b{ color: var(--txt-secondary); font-weight: var(--fw-semibold); }

/* ── §76-4 큰 금액 칸 — 시안은 «파란 테두리 + 크고 굵은 우측 숫자» ────── */
/* ⚠ 2026-09-16 — 여기서 «중복 규격 묶기» 를 하다 **감싸개(.bi-pay2__amt)가 입력칸 규칙에 붙어**
   감싸개에 파란 테두리·높이 36 이 걸렸고, 안의 라벨줄과 칩이 겹쳐 보였다.
   «같은 선언» 이라고 묶을 때는 **역할이 같은가**를 먼저 본다 — 감싸개와 칸은 다른 것이다.
   (매출등록 세션이 같은 사고를 세 번 겪었다고 알려 주었다) */
.bi-pay2__amt{ margin-bottom: var(--space-2); }
.bi-pay2 input.bi-pay2__in[type="text"]{
    display: block; width: 100%; height: var(--pay2-in-h);
    box-sizing: border-box;
    padding: 0 var(--space-3_5);
    border: 2px solid var(--color-info-700);
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    text-align: right;
    font-size: var(--fs-xl); font-weight: var(--fw-bold); color: var(--txt-primary);
}
.bi-pay2 input.bi-pay2__in[type="text"]:focus{ outline: none; box-shadow: 0 0 0 3px var(--brand-blue-light); }

/* ── §76-5 빠른 입력 칩 줄 ───────────────────────────────────────────── */
/* 시안 — 입력칸/2열 바로 다음에 칩이 오면 사이가 8 이다 */
/* ⚠ 사이에 «숨은 경고 줄»(.bi-pay2__over)이 끼어도 맞게 — 인접(+)은 display 를 안 본다 */
.bi-pay2__f2 + .bi-pay2__quick,
.bi-pay2__f2 + .bi-pay2__over + .bi-pay2__quick{ margin-top: var(--space-2); }
.bi-pay2__quick{
    display: flex; align-items: center; flex-wrap: wrap;
    gap: var(--space-2); margin-bottom: var(--space-3);
}
.bi-pay2__quick > span{ font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-pay2__qb{
    height: var(--pay2-chip-h); padding: 0 var(--space-3);
    border: 1px solid var(--pay2-chip-bd); border-radius: var(--radius-full);
    background: var(--bg-card);
    font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--txt-secondary);
    cursor: pointer;
}
.bi-pay2__qb:hover{ border-color: var(--color-info-700); color: var(--color-info-700); }
/* 카드 안에서 마지막 줄이면 아래 여백을 주지 않는다 */
.bi-pay2__quick--tight{ margin-bottom: 0; }
/* ⚠ 2026-09-16 — 시안에서 «칩 줄 → 섹션 카드» 사이는 16 인데 12 로 서 있었다(bs1·bs3 모두).
   그만큼 카드가 위로 올라붙어, 카드 안쪽이 그만큼 길어져 총 높이만 우연히 맞고 있었다.
   ⚠ 실제 카드결제 팝업은 카드가 `.bi-pop-card-body` 로 한 겹 더 싸여 있다 — 둘 다 적는다.
   ⚠ bs2(선불권)에는 카드가 없어 인접 선택자가 안 걸린다. 그래서 칩의 여백 자체는 건드리지 않는다.
   ⚠ 여백은 «겹친다»(margin collapsing) — 칩의 아래 12 와 카드의 위 4 는 더해지지 않고
     큰 쪽 12 만 남는다. 그래서 «더 크게»(16) 준다. */
.bi-pay2__quick + .bi-pay2__card,
.bi-pay2__quick + .bi-pop-card-body{ margin-top: var(--space-4); }

/* ── §76-6 섹션 카드 — 머리 띠(체크 + 배지) + 본문 ──────────────────── */
.bi-pay2__card{
    border: 1px solid var(--border-base); border-radius: var(--radius-xl);
    overflow: hidden; margin-bottom: var(--space-4);
}
/* 시안 — 카드가 본문의 마지막이면 아래 여백이 없다(본문 여백만 남는다) */
/* ⚠ 실제 팝업은 카드가 .bi-pop-card-body 안에 있어 «직계» 선택자가 안 맞는다 */
.bi-pay2__card:last-child{ margin-bottom: 0; }
.bi-pay2__chd{
    display: flex; align-items: center; gap: var(--space-2);
    min-height: var(--pay2-chd-h);
    padding: 0 var(--space-3_5);
    box-sizing: border-box;
    background: var(--pay2-band);
    border-bottom: 1px solid var(--border-base);
}
.bi-pay2__chd .bi-pay2__ctitle{ flex: 1 1 auto; font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-primary); }
/* 시안 — 카드 본문 여백은 12 (좌우도 12). 라벨 먹이 왼쪽 33 에서 시작한다(카드 안쪽 21 + 12).
   ⚠ 2026-09-16 — 14 로 두고 있었다(라벨이 37 에서 시작해 4 밀려 있었다). */
.bi-pay2__cbd{ padding: var(--space-3) var(--space-3) var(--space-2_5); }
/* ⚠ 2026-09-16 — 카드 «안» 라벨만 굵기 400 · 13px 로 서 있었다.
   굵게·12px 로 만드는 규칙이 `.bi-pay2__body > .bi-pay2__f2 > .bi-pay2__f > label` 이라
   **직계 자식** 만 잡고, 카드 안(`.bi-pay2__cbd`)의 라벨에는 하나도 안 걸렸다.
   시안은 카드 안팎이 같다 — 먹 키가 둘 다 11 이고 굵다. */
.bi-pay2__cbd .bi-pay2__f > label{
    font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-secondary);
}
/* 시안 — 카드 안 라벨 줄은 15 (밖의 맞춤용 17 과 다르다) */
.bi-pay2__cbd .bi-pay2__f > label{ line-height: 15px; }
/* 카드가 꺼져 있으면 본문은 흐리게(지우지 않는다 — 켜면 그 자리 그대로) */
.bi-pay2__card.is-off .bi-pay2__cbd{ opacity: .45; pointer-events: none; }

/* ⚠ 전역 input[type=checkbox]{display:none}(스프라이트 방식) 때문에 카드 머리의
   네이티브 체크가 사라진다 — §38-6 과 같은 처리로 스코프에서 되살린다(0,1,1 > 0,0,1). */
.bi-pay2__chd input[type="checkbox"],
.bi-pay2__tix input[type="checkbox"]{
    display: inline-block; visibility: visible;
    width: 18px; height: 18px; margin: 0; accent-color: var(--color-info-700); cursor: pointer;
}
/* ⚠ 2026-09-16 — 「사업장 결제」 라디오 점이 시안 #1D4ED8 인데 규격안은 #00156E 였다.
   `.bi-pop-check input[type=checkbox]{accent-color:var(--brand-blue)}`(전역)를 그대로 물려받아
   팝업 안에서만 파랑을 쓰기로 한 결정(2026-09-15)과 어긋나 있었다.
   화소가 424개뿐이라 팔레트 대조에도 안 걸렸다 — 자리를 찍어 재고서야 나왔다. */
.bi-pay2 input[type="radio"],
.bi-pay2 .bi-pop-check input[type="radio"],
.bi-pay2 .bi-pop-check input[type="checkbox"]{ accent-color: var(--color-info-700); }

/* ── §76-7 두 칸 폼 ─────────────────────────────────────────────────── */
/* ⚠ 1fr 은 minmax(auto,1fr) 라 **안의 최소폭이 칸을 밀어낸다**. minmax(0,1fr) 로 막는다 */
.bi-pay2__f2{ display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-3); }
/* 시안 — 라벨과 칸 사이는 4 (6 이었다) */
.bi-pay2__f{ display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
/* ⚠ 2열에서 왼쪽은 <label> 한 줄, 오른쪽은 .bi-pay2__lbrow(라벨+남은금액) 라
   두 칸의 입력이 12px 어긋났다. 시안은 둘이 같은 y 에서 시작한다 — 줄 키를 맞춘다. */
.bi-pay2__body > .bi-pay2__f2 > .bi-pay2__f > label,
.bi-pay2__body > .bi-pay2__f2 > .bi-pay2__f > .bi-pay2__lbrow{
    min-height: 17px; margin-bottom: 0;
    font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-secondary);
}
.bi-pay2__f > label small{ margin-left: var(--space-1); font-size: var(--fs-xs); font-weight: var(--fw-normal); color: var(--txt-muted); }
/* ⚠ 2026-09-22 — .bi-pay2__hint 를 지웠다. 현금결제 팝업의 「휴대폰 번호」 칸이 사라지면서
   (발행 번호는 단말기에서 받는다) 그 칸 아래 안내글도 함께 사라져 쓰는 곳이 없어졌다. */
/* ⚠ 2026-09-16 — 「단말기 영수증의 승인번호 8자리」 같은 안내 글씨가 브라우저 기본색(#757575)
   으로 찍혀 시안(#9CA3AF = --txt-disabled)보다 진했다. 팔레트 대조(_palette.mjs)가 잡았다 —
   글자 크기·자리만 재던 검사로는 안 걸리는 종류다. */
.bi-pay2 input::placeholder,
.bi-pay2 textarea::placeholder{ color: var(--txt-disabled); opacity: 1; }

/* ── §76-8 수령 방식 세그먼트 (bs3) ─────────────────────────────────── */
.bi-pay2__seg{
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
    gap: var(--space-1);
    /* 시안 실측 — 띄 전체가 36 이다(안쪽 단추 30 + 여백 4 + 테두리 2) */
    padding: var(--space-0_5);
    background: var(--pay2-track);
    border: 1px solid var(--border-base); border-radius: var(--radius-lg);
    margin-bottom: var(--space-4);
}
.bi-pay2__sg{
    display: flex; align-items: center; justify-content: center; gap: var(--space-1_5);
    /* ⚠ 36 은 사다리 밖이다(§12-4 48·40·32·30·28·27·22). 시안 실측은 안쪽 단추 ≈ 34,
       띄 전체 ≈ 38 — 사다리의 32 로 내리면 띄가 42 로 시안과 거의 같다.
       새 등급을 만들 까닭이 없으면 사다리를 따른다(2026-09-15 btn 검사가 잡았다).
       ⚠ 2026-09-16 — 30 이면 띄 전체가 36 이다. 시안을 «색으로» 재니 띄가 38(칠 36 + 테두리 2) —
          사다리의 32 로 올리면 32+4+2 = 38 로 딱 맞는다. 위 주석의 «42» 는 셈이 틀렸다. */
    height: 32px; border: 0; border-radius: var(--radius-md);
    background: transparent;
    font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-muted);
    cursor: pointer;
}
.bi-pay2__sg.is-sel{ background: var(--bg-card); color: var(--color-info-700); box-shadow: var(--shadow-sm); }

/* ── §76-9 고르는 줄 (bs2 선불권) ──────────────────────────────────── */
.bi-pay2__tixhd{
    display: flex; align-items: baseline; justify-content: space-between;
    padding: 0 0 var(--space-1_5); font-size: var(--fs-sm); color: var(--txt-muted);
}
.bi-pay2__tixhd b{ color: var(--txt-secondary); font-weight: var(--fw-semibold); }
/* 시안 — 안내 띠 아래 목록 머리는 본문 여백 16 보다 조금 위에서 시작한다.
   ⚠ 2026-09-16 — 처음엔 -6 으로 잡았는데, 그때 목업이 **Pretendard 를 안 싣고** 있었다.
     폴백 글꼴은 줄 키가 달라, 그 위에서 잰 값이었다. 진짜 글꼴로 다시 재니 -2 다. */
.bi-pay2__body > .bi-pay2__tixhd:first-child{ margin-top: calc(var(--space-0_5) * -1); }
/* ⚠ 2026-09-16 — 시안에서 선불권 목록은 «전폭» 이다. 줄 배경(#EEF3FF)과 왼쪽 표시 막대가
   창 끝(x=0)에서 시작하고, 들여쓰기는 «줄 안쪽»(padding 20)이 갖는다.
   규격안은 본문 좌우 여백(20) 안에 갇혀 폭 437 짜리 카드로 서 있었다 — 시안은 477 이다.
   본문 여백을 음수 margin 으로 되물린다. */
.bi-pay2__tixul{
    list-style: none; padding: 0;
    margin: 0 calc(var(--space-5) * -1) var(--space-4);
    /* ⚠ 2026-09-16 — 목록이 길면 **창이 통째로 늘어나고 있었다**(3줄 610 → 40줄 976, +366).
       조상에 스크롤 상자가 하나도 없었다. 매출등록 세션이 알려 온 「스크롤이 생겨야지
       왜 화면을 길게 늘어뜨려」 와 같은 부류다 — 목록이 있는 화면은 예외 없이 이 함정에 있다.
       ⚠ 275 는 «다섯 줄»(55×5)이다. 호출부가 이 창을 730 으로 여는데,
         시안(2줄 552)에서 목록만 275 로 늘면 552-110+275 = 717 로 730 안에 든다.
         눈금이 아니라 «줄 수» 로 정한 값이라 여기에 적어 둔다. */
    max-height: 275px; overflow-y: auto;
}
.bi-pay2__tix{
    display: flex; align-items: center; gap: var(--space-2_5);
    min-height: var(--pay2-row-h);
    padding: var(--space-2) var(--space-5);
    box-sizing: border-box;
    border-bottom: 1px solid var(--border-light);
    cursor: pointer;
}
.bi-pay2__tix.is-sel{ background: var(--pop-row-sel); box-shadow: inset 3px 0 0 var(--color-info-700); }
.bi-pay2__tixmain{ flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--space-0_5); }
.bi-pay2__tixnm{ font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--txt-primary); }
.bi-pay2__tixsub{ font-size: var(--fs-sm); color: var(--txt-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bi-pay2__tixamt{ text-align: right; white-space: nowrap; }
.bi-pay2__tixamt b{ display: block; font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--txt-primary); }
.bi-pay2__tixamt small{ display: block; font-size: var(--fs-xs); color: var(--txt-muted); }
/* 「만료 임박」 — 이미 있는 주의색(--bk-req-bg). 새 색이 아니다 */
.bi-pop-tag--warn{ background: var(--bk-req-bg); color: var(--color-warning-700); }

/* ── §76-10 차감·미결제액 요약 (bs2) ──────────────────────────────── */
/* 시안 — 요약 줄은 위아래 4 (8 이면 두 줄이 16 길어진다) */
.bi-pay2__sumrow{
    display: flex; align-items: baseline; justify-content: space-between;
    padding: var(--space-1) 0;
    font-size: var(--fs-base); color: var(--txt-muted);
}
.bi-pay2__sumrow b{ color: var(--txt-secondary); font-weight: var(--fw-semibold); }
.bi-pay2__sumrow--big{ border-top: 1px solid var(--border-light); font-size: var(--fs-md); color: var(--txt-primary); font-weight: var(--fw-bold); }
.bi-pay2__sumrow--big b{ font-size: var(--fs-xl); color: var(--color-info-700); font-weight: var(--fw-bold); }

/* ── §76-11 푸터 — 안내 한 줄 + «전폭» 확정 단추 ────────────────────── */
.bi-pay2__foot{
    flex: 0 0 auto;
    /* 시안 실측 — 위 14 · 좌우 20 · 아래 14 (위아래가 같다)
       ⚠ 2026-09-16 — 아래를 10 으로 잡고 있었다. CTA 의 «자리» 는 맞는데 창 총 키만
         4 모자란 것으로 나타나, 푸터 아래 여백에서만 생긴 차이임을 알 수 있었다
         (시안은 CTA 아래로 14~15, 우리는 11~12 였다). */
    padding: var(--space-3_5) var(--space-5);
    box-sizing: border-box;
    background: var(--bg-card);
    border-top: 1px solid var(--border-base);
}
.bi-pay2__fnote{
    display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2);
    line-height: 1;
    margin-bottom: var(--space-3);
    font-size: var(--fs-sm); color: var(--txt-muted);
}
.bi-pay2__fnote b{ color: var(--txt-secondary); font-weight: var(--fw-semibold); }
/* «등록 후 남은 금액» 자리 — pay2_common.js 가 이 이름으로 숫자를 다시 쓴다.
   늘어나는 것은 이미 있는 프리미티브 `.bi-fill` 을 같이 붙여 쓴다(새로 만들지 않는다). */
/* 전폭 CTA 의 «이름» 조각 — 수기 등록 여부에 따라 글자가 바뀜다 */
/* 긴 이름이 들어와도 단추가 불지 않게 — 금액은 살리고 이름만 줄인다 */
.bi-btn--cta-lb{ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-pay2__cancel{ color: var(--color-danger-600); font-weight: var(--fw-semibold); cursor: pointer; }

/* 전폭 확정 단추 — 사다리의 새 등급(§76). 한 창에 하나뿐이다.
   ⚠ 이름을 `.bi-pop-page .bi-btn--cta` 로 적는다 — §38 의
     `.bi-pop-page .bi-btn{height:var(--pop-btn-h)}`(0,2,0)이 있어
     `.bi-btn--cta`(0,1,0) 만으로는 **진다** — 실측 34px 로 찍혔다(2026-09-15).
     «뒤에 오면 이긴다» 가 아니라 «더 긴 선택자가 이긴다» (§75-6 에 적어 둔 그것). */
.bi-pop-page .bi-btn--cta,
.bi-btn--cta{
    display: flex; align-items: center; justify-content: center; gap: var(--space-2);
    /* ⚠ 팝업 문서는 전역 box-sizing 을 믿지 않는다 — 스스로 선언한다(CLAUDE §7).
       안 적으면 키 48 에 패딩·테두리가 더해져 58 로 찍힌다. */
    box-sizing: border-box;
    width: 100%; height: var(--pay2-cta-h);
    border-radius: var(--radius-lg);
    font-size: var(--fs-lg); font-weight: var(--fw-bold);
}
.bi-btn--cta i{ font-size: var(--fs-lg); }

/* ── §76-12 시안을 «확대해» 보고서야 나온 셋 (2026-09-15) ────────────────
   수치 검사(pop/btn/type)는 색과 크기만 잰다 — 모양은 그림을 봐야 나온다(§75 의 교훈). */

/* ① 「수기 등록」·「국세청 전송」 배지는 «테두리 알약» 이다 — 채운 배지가 아니다.
      시안 실측: 옅은 파랑 바탕(#EEF2FF) + 파란 테두리 + 파란 글자 + 완전둥근. */
.bi-pop-tag--out{
    background: var(--pop-pill-bg);
    border: 1px solid var(--color-info-200);
    border-radius: var(--radius-full);
    padding: 0 var(--space-2_5);
    color: var(--color-info-700);
}

/* ② 「고객 정보에서 자동 입력」 은 칸 «안» 오른쪽에 선다 — 칸 아래가 아니다. */
/* ⚠ <span> 그대로둔 inline 이라 폭이 글자만큼만 되고,
   안에 넣은 힌트가 칸 밖으로 빠져나왔다(2026-09-15 캐프처에서 보였다). */
.bi-pay2__inrow{ position: relative; display: block; }
/* 시안 bs1 — 결제일자 칸 오른쪽에 달력 글리프가 있다 */
.bi-pay2__inico{
    position: absolute; right: var(--space-3); top: 50%; transform: translateY(-50%);
    color: var(--txt-disabled); font-size: var(--fs-md); pointer-events: none;
}
/* ⚠ 2026-09-22 — 여기 있던 .bi-pay2__inhint(「고객 정보에서 자동 입력」 안내 글)와
   그 글이 설 자리를 비우던 --hint 변형을 지웠다. 사용자 지시로 현금영수증 번호를
   «손으로 넣는» 칸으로 바꾸면서 그 안내가 사라졌고, 쓰는 곳이 하나도 남지 않았다.
   (되살릴 일이 생기면 --pay2-inhint-w 변수와 함께 되돌린다.) */
/* ⚠ 2026-09-16 — 칸에 «폭» 규칙이 없었다. <input> 은 size 속성만큼만 서기 때문에
   줄(414)보다 좁거나(현금 휴대폰 칸 331 — 시안은 카드 폭 전체 413) 넓게(카드결제 줄 201 에 칸 223)
   제멋대로 섰다. 시안은 칸이 줄을 꽉 채운다. 큰 금액칸(.bi-pay2__in)에만 width:100% 를 주고
   여기는 빠뜨린 것이다. */
.bi-pay2__inrow input.bi-input{ display: block; width: 100%; box-sizing: border-box; }
.bi-pay2__inrow input.bi-input{ padding-right: var(--space-8); }

/* ③ 「사업장 결제」 줄은 다음 칸과 붙지 않는다 */
.bi-pay2__payer{ margin-bottom: var(--space-4); }
.bi-pay2__payer small{ margin-left: var(--space-1_5); color: var(--txt-muted); font-weight: var(--fw-normal); }
/* 라디오 줄과 그 아래 칸 사이 */
.bi-pay2__cbd .bi-pay2__quick--tight{ margin-bottom: var(--space-3); }
/* 남은 금액보다 많이 치면 알려만 준다 — 막지는 않는다(분리 결제·거스름이 있다) */
.bi-pay2__over{ margin-top: var(--space-1_5); font-size: var(--fs-sm); color: var(--color-danger-600); font-weight: var(--fw-semibold); }

/* ── §76-13 눈으로 보고서야 나온 넷 (2026-09-15) ──────────────────────
   수치 검사(pop/btn/type)는 「전폭 단추 48 ✔」 를 냈는데, 캡처를 열어 보니
   체크 글자 위에 스프라이트 네모가 줄줄이 찍혀 있었다. 그림을 봐야 하는 이유가 이것이다. */

/* ① 섹션 카드 머리의 <label> 은 «글자» 다 — 전역 레거시 `input[type=checkbox]+label`
      (18px PNG 상자)이 그 글자를 스프라이트로 바꿔 체크 네모가 줄줄이 찍혔다.
      §17 `.bi-checkbox-label` 과 같은 처리(0,1,2 > 0,1,1 이라 !important 불필요). */
.bi-pay2__chd input[type="checkbox"] + label,
.bi-pay2__tix input[type="checkbox"] + label,
.bi-pay2 .bi-pop-check input[type="checkbox"] + label,
.bi-pay2 .bi-pop-check input[type="radio"] + label{
    width: auto; height: auto; top: 0;
    background: none;
    text-indent: 0; overflow: visible;
    display: inline; cursor: pointer;
}

/* ② `.bi-hidden`(0,1,0) 만으로는 `.bi-pop-check{display:flex}` 를 못 이긴다 —
      숨겼다고 믿은 「계좌이체」 체크가 세그먼트 아래 그대로 남아 있었다(§F2 그대로 다시 물렸다).
      ⚠ !important 로 누르지 않는다 — «더 긴 선택자» 로 이긴다.
      `.bi-pay2 .bi-hidden`(0,2,0) > `.bi-pop-check`(0,1,0). §75-6 에 적어 둔 그 방법이다. */
.bi-pay2 .bi-pop-check.bi-hidden,
.bi-pay2 .bi-hidden{ display: none; }

/* ③ 「보유 선불권이 없습니다」 줄 — 목록이 0장일 때의 자리 */
.bi-pay2__none{
    padding: var(--space-6) var(--space-2_5);
    text-align: center;
    color: var(--txt-disabled); font-size: var(--fs-base);
    border-bottom: 1px solid var(--border-light);
}

/* ④ 「사업장 결제」 갈래 줄 — 라디오와 글자가 한 줄에 선다 */
.bi-pop-card-payer{ display: flex; flex-wrap: wrap; gap: var(--space-4); margin-bottom: 0; }

/* ⚠ §76 결제 팝업은 골격(.bi-pay2)이 제 여백을 갖는다 — 안내 띄와 푸터는
   시안처럼 «창 끝까지» 닿아야 한다. 그런데 감싸개 `.bi-pop-pay` 가
   `padding: 20 24 24` 를 더해 여백이 **두 번** 걸렸고, 실제 창이 규격안보다 46px 길었다
   (2026-09-16 사용자 지적 — 「규격안과 실제가 다르다」). 쓰는 쪽이 끔다. */
.bi-pop-pay--pay2{ padding: 0; }
/* 같은 까닭 — 카드 팝업의 레거시 감싸개도 아래 여백을 더해 본문이 12 길었다 */
.bi-pop-pay--pay2 .bi-pop-card-body{ margin-bottom: 0; }

/* ══════════════════════════════════════════════════════════════════════
   §61 휴무설정 — «행=사람 · 열=시간» 전치 매트릭스 (2026-09-15 신설)
   ──────────────────────────────────────────────────────────────────────
   시안: renew_crm/reimg/dayoff.png(본 화면) · dayoff2.png(기간 휴무 팝업)
        · dayoff3.png(⋯ 일괄 설정 메뉴)
   규격안: renew_crm/tools/qc/spec_do/{day,period,bulk}.html
   비교 문서: renew_crm/dayoff_spec.html (시안 | 규격안 | 실제 3단)

   사용자 지시(2026-09-15): 「시안과 지금 실제화면이 달라 그건 기존 css에 덮으란게
   아니야 … 물어보지말고 다르면 새로 만들어서 추가해」
   → 옛 §40-14 .bi-schmx__*(열=사람 · 행=시간)는 **그대로 남기고** 여기에 새 이름으로 더한다.
     styleguide2 §40-14 데모가 아직 그 이름을 쓰기 때문이다.

   ⚠ 색·치수는 전부 시안을 «픽셀로 재서» 넣었다(_do_measure*.mjs). 눈대중·근사 금지 —
     2026-09-11 에 --brand-purple(#5E1E7B)로 시안 #5B45E0 을 대신했다가 지적받았다.
   ⚠ 이 절은 기존 클래스를 «비틀지» 않는다. 공용 원자(.bi-btn·.bi-bk2-cal__*·.bi-bk2-side·
     .bi-bk2-card·.bi-bk2-search·.bi-modal·.bi-dropdown-anchor·.bi-note)는 불러쓴다.
   ══════════════════════════════════════════════════════════════════════ */

:root {
    /* 시안에 있고 우리 팔레트에 «없던» 색만 등재한다. 있는 것은 아래에서 그 이름을 부른다:
         근무 칸 바탕/테두리/글자 = --color-indigo-50 / --color-indigo-200 / --color-info-700
         휴무 칸 바탕 = --border-light · 정기휴무 줄 = --bk-done-bg
         반차·미저장 배지 바탕 = --bk-req-bg · 겹침 배지 = --color-danger-50 / -700
         고른 줄 = --pop-row-sel · 짙은 네이비(⋯ 활성) = --pop-navy · 고른 칩 = --bk-run */
    --do-line:          #EEF0F3;   /* 행 구분선 · 드롭다운 구분선 (실측) */
    --do-cell-booked:   #D6DEFF;   /* 예약이 있는 칸 (0/1 → 1/1) */
    --do-cell-rest:     #E6E9EE;   /* 휴게 칸 */
    --do-cell-off-line: #C9CED8;   /* 휴무(×) 칸 테두리 — --gray-300 보다 살짝 푸르다 */
    --do-cell-clash:    #E4E0FF;   /* 휴게·휴무와 «겹친» 예약 칸 */
    --do-ok-bg:         #ECFDF3;   /* 상태 꼬리표 «근무» 바탕 */
    --do-ok-txt:        #15803D;   /* 상태 꼬리표 «근무» 글자 */
    --do-warn-txt:      #8A5A0B;   /* «저장되지 않은 변경»·«반차» 글자 */
    /* 눈금 — 시안 실측. 사다리에 없으면 등급을 더한다(§71 판례, 2026-09-14) */
    --do-cell-w:          48px;    /* 30분 칸 폭 — 시안 실측 48 (47 이었다) */
    --do-cell-gap:         2px;    /* 칸 사이 — 시안 실측 2 (3 이었다). 칸 pitch 50 은 그대로 */
    --do-cell-h:          46px;    /* 칸 높이 */
    --do-rowhd-w:        256px;    /* 행머리(디자이너) 열 폭 */
    --do-modal-w:        560px;    /* 기간 휴무 팝업 — 시안 정확히 560 */
    --do-menu-w:         220px;    /* ⋯ 일괄 설정 메뉴 — 시안 219 */
    /* 2026-09-16 간격 실측 — 시안↔규격안을 같은 자로 견주어 잡았다(_do_gap2.mjs).
       칸(46)만 세고 «줄이 얼마나 높은지» 를 안 쟀더니 행 pitch 가 63 이었다(시안 84). */
    --do-row-h:           84px;   /* 줄 높이 — 시안 행 pitch 84 */
    --do-hd-h:            36px;   /* 판 머리행(시간 눈금) 높이 — 시안 36 */
}

/* 이 화면은 전역(box-sizing)에 기대지 않고 «스스로» 선언한다 —
   예외 페이지가 전역에 기대어 width 180 이 213 으로 벌어진 전례가 있다(§48 §5). */
/* 좌패널 카드 사이 틈 — 시안 실측 14 (--space-3_5).
   ⚠ 2026-09-16 «9» 로 적었던 앞선 실측은 원점을 툴바 아래로 잡아 틀렸다.
   카드 테두리로 원점을 다시 잡아 재니 14 다(_do_side.mjs). */
.bi-do2-wrap .bi-bk2-side { gap: var(--space-3_5); }

.bi-do2-wrap, .bi-do2-wrap * { box-sizing: border-box; }

/* 판 안에서 «색을 따로 정하지 않은 글자» 는 모두 토큰이 된다.
   안 정하면 순검정 #000000 이 된다 — 그건 토큰이 아니다(_SPEC_CHECKLIST §2-1). */
.bi-do2-wrap { color: var(--txt-primary); font-family: var(--font-sans); }

/* ── 골격 — 좌 패널(공용 .bi-bk2-side) + 본문 ───────────────────── */
.bi-do2-wrap { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.bi-do2-wrap .bi-do2-body { display: flex; flex: 1; min-height: 0; }
.bi-do2-wrap .bi-do2-main {
    flex: 1; min-width: 0; display: flex; flex-direction: column;
    background: var(--bg-card);
    position: relative;        /* ⋯ 메뉴가 여기에 얹힌다 */
}
/* 판 안에 두면 overflow 가 자르고 아랫줄이 덮는다 — 하나를 판 밖에 두고 자리만 옮긴다.
   자리는 브릿지 변수로 받는다(§4 «인라인 style 금지» 의 허용 예외 — 폴백 필수). */
.bi-do2-wrap .bi-do2-menu--float {
    position: absolute; z-index: var(--z-dropdown);
    top: var(--do-menu-top, 0px); left: var(--do-menu-left, 0px);
}

/* ── 머리 줄 — ‹ 날짜 › [오늘] · 배지 · 안내 · 일괄 ───────────────── */
.bi-do2-wrap .bi-do2-tool {
    display: flex; align-items: center; gap: var(--space-2_5);
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border-base);
    flex-wrap: wrap;
}
.bi-do2-wrap .bi-do2-tool__hint {
    flex: 1 1 60px; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    font-size: var(--fs-xs); color: var(--txt-muted);
}
.bi-do2-wrap .bi-do2-tool__sp { margin-left: auto; }
.bi-do2-wrap .bi-do2-tool__lb { font-size: var(--fs-xs); color: var(--txt-disabled); }

/* 배지 — 상태를 알리는 읽기 전용 알약 */
.bi-do2-wrap .bi-do2-pill {
    display: inline-flex; align-items: center; gap: var(--space-1_5);
    height: 28px; padding: 0 var(--space-2_5);
    border-radius: var(--radius-full);
    font-size: var(--fs-xs); font-weight: var(--fw-semibold);
    white-space: nowrap;
}
/* ⚠ F2 — .bi-hidden 을 «같은 모양» 으로 되받는다. 안 하면 0건 배지가 떠 있는다. */
.bi-do2-wrap .bi-do2-pill.bi-hidden,
.bi-do2-cnt.bi-hidden { display: none; }
.bi-do2-wrap .bi-do2-pill__dot {
    width: 5px; height: 5px; border-radius: var(--radius-full); background: currentColor;
}
.bi-do2-wrap .bi-do2-pill--dirty { background: var(--bk-req-bg);       color: var(--do-warn-txt); }
.bi-do2-wrap .bi-do2-pill--clash { background: var(--color-danger-50); color: var(--color-danger-700); }

/* ── 판 — 행=사람 · 열=시간 ──────────────────────────────────────
   ⚠ 가로로만 구른다. 세로는 부모가 이미 화면을 채우므로 flex 로 받는다
     (고정 뺄셈 calc(100vh - N) 은 부모가 채워진 순간 틀어진다). */
.bi-do2-wrap .bi-do2-grid { flex: 1; min-height: 0; overflow: auto; background: var(--bg-card); isolation: isolate; }
.bi-do2-wrap .bi-do2-grid__in { width: max-content; min-width: 100%; }

/* 머리행 — 시간 눈금. 위로 붙어 따라온다 */
.bi-do2-wrap .bi-do2-hd {
    height: var(--do-hd-h);           /* 시안 36 */
    display: flex; align-items: stretch;
    position: sticky; top: 0; z-index: 3;   /* 판 안에서만 위다 — 전역 --z-sticky 는 모달을 뚫는다 */
    background: var(--bg-card);
    border-bottom: 1px solid var(--border-base);
}
.bi-do2-wrap .bi-do2-hd__lb {
    width: var(--do-rowhd-w); flex-shrink: 0;
    display: flex; align-items: center;
    padding: 0 var(--space-3_5);
    font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-primary);
    background: var(--bg-column);
    border-right: 1px solid var(--border-base);
    position: sticky; left: 0; z-index: 4;
}
.bi-do2-wrap .bi-do2-hd__lb small {
    margin-left: var(--space-1_5);
    font-size: var(--fs-sm); font-weight: var(--fw-normal); color: var(--txt-muted);
}
.bi-do2-wrap .bi-do2-hd__ts { display: flex; align-items: center; padding: 0; }
.bi-do2-wrap .bi-do2-hh {
    width: calc(var(--do-cell-w) * 2 + var(--do-cell-gap) * 2);
    flex-shrink: 0;
    font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--txt-muted);
    padding-left: var(--space-0_5);
}

/* 줄 — 행머리 + 칸들 */
.bi-do2-wrap .bi-do2-row {
    display: flex; align-items: stretch;
    min-height: var(--do-row-h);      /* 시안 84 — 칸(46)만 세면 63 이 된다 */
    border-bottom: 1px solid var(--do-line);
}
.bi-do2-wrap .bi-do2-row--off { background: var(--bk-done-bg); }
.bi-do2-wrap .bi-do2-row.is-sel .bi-do2-rowhd { box-shadow: inset 3px 0 0 0 var(--color-danger-600); }

.bi-do2-wrap .bi-do2-rowhd {
    width: var(--do-rowhd-w); flex-shrink: 0;
    display: flex; align-items: center; gap: var(--space-2_5);
    padding: var(--space-3) var(--space-3);
    background: var(--bg-column);
    border-right: 1px solid var(--border-base);
    position: sticky; left: 0; z-index: 1;
}
.bi-do2-wrap .bi-do2-row--off .bi-do2-rowhd { background: var(--bk-done-bg); }
.bi-do2-wrap .bi-do2-rowhd__tx { min-width: 0; flex: 1; display: block; }
.bi-do2-wrap .bi-do2-rowhd__n {
    display: block;
    font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-primary);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bi-do2-wrap .bi-do2-rowhd__s {
    display: block; margin-top: var(--space-0_5);
    font-size: var(--fs-xs); color: var(--txt-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* 상태 꼬리표 — 색만으로 구분하지 않는다(글자가 함께 있다) */
.bi-do2-wrap .bi-do2-tag {
    flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    height: 22px; padding: 0 var(--space-2);
    border-radius: var(--radius-full);
    font-size: var(--fs-xs); font-weight: var(--fw-semibold);
}
.bi-do2-wrap .bi-do2-tag--work  { background: var(--do-ok-bg);         color: var(--do-ok-txt); }
.bi-do2-wrap .bi-do2-tag--half  { background: var(--bk-req-bg);        color: var(--do-warn-txt); }
.bi-do2-wrap .bi-do2-tag--off   { background: var(--border-light);     color: var(--txt-muted); }
.bi-do2-wrap .bi-do2-tag--clash { background: var(--color-danger-50);  color: var(--color-danger-700); }

/* 칸 줄 */
.bi-do2-wrap .bi-do2-cells { display: flex; align-items: center; gap: var(--do-cell-gap); padding: 0; }

/* ── 칸 — button 이다. 기본 테두리·바탕을 «먼저 비운다» ──────────────
   ⚠ appearance:none 으로는 buttonface(#F0F0F0)와 2px outset 이 안 지워진다.
     판이 통째로 회색이 되고 칸마다 굵은 선이 그려진 전례가 두 번 있다(F7). */
.bi-do2-wrap .bi-do2-cell {
    -webkit-appearance: none; appearance: none;
    margin: 0; border: 0; background: transparent; box-shadow: none;
    font: inherit; color: inherit; text-align: center;
    width: var(--do-cell-w); height: var(--do-cell-h); flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: var(--radius-md);
    font-size: var(--fs-xs); font-weight: var(--fw-bold);
    cursor: pointer; transition: var(--transition-base); user-select: none;
}
.bi-do2-wrap .bi-do2-cell--none { background: transparent; cursor: default; }

/* 근무 — 파란 옅은 블록 */
.bi-do2-wrap .bi-do2-cell--work {
    background: var(--color-indigo-50);
    border: 1px solid var(--color-indigo-200);
    color: var(--color-info-700);
}
/* 예약 있음 — 같은 계열의 «짙은» 바탕 + 카운트가 함께 뜬다 */
.bi-do2-wrap .bi-do2-cell--booked {
    background: var(--do-cell-booked);
    border: 1px solid var(--color-indigo-200);
    color: var(--color-info-700);
}
/* 휴게 — 회색. 글자로 «휴게» 를 말한다 */
.bi-do2-wrap .bi-do2-cell--rest {
    background: var(--do-cell-rest);
    border: 1px solid var(--do-cell-off-line);
    color: var(--txt-secondary);
    font-weight: var(--fw-medium);
}
/* 휴무 — 회색 + × (색만으로 구분하지 않는다) */
.bi-do2-wrap .bi-do2-cell--off {
    background: var(--border-light);
    border: 1px solid var(--do-cell-off-line);
    color: var(--txt-disabled);
    font-weight: var(--fw-normal);
}
/* ══ §61-48 예약으로 «마감된» 칸 (2026-09-22 신설) ═════════════════════
   사용자 지적: 「겹침 상태값이 이해가 안 돼 — 매장관리자는 예약 3개가 있고 **시간이 겹치지
     않았는데** 겹침으로 나와」. hourbit 의 0 은 「휴무」 가 아니라 「그 시간 예약 불가」 이고,
   `set_bk_hourbit()` 이 **정원이 찬 칸을 0 으로 저장**한다 — 즉 예약을 받으면 0 이 된다.
   그 칸은 «겹침»(경고)이 아니라 «마감»(정상)이다. 그래서 색을 가른다:
     · 마감 = 예약 있음(--booked)과 같은 계열이되 테두리를 굵게 해 «닫혔음» 을 말한다
     · 겹침 = 보라 그대로(아래) — 사람이 봐야 하는 칸만 눈에 띈다
   ⚠ 기존 --clash 선언은 고치지 않는다(뜻이 좁아졌을 뿐 그대로 쓴다). */
.bi-do2-wrap .bi-do2-cell--full {
    background: var(--do-cell-booked);
    border: 1px solid var(--color-info-700);
    color: var(--color-info-700);
    font-weight: var(--fw-semibold);
}
.bi-do2-wrap .bi-do2-cell--full:hover { background: var(--color-indigo-100); }
.bi-do2-wrap .bi-do2-legend__sw--full {
    background: var(--do-cell-booked); border-color: var(--color-info-700);
}

/* 휴게·휴무와 «겹친» 예약 — 보라. 저장 전에 알려야 하는 칸 */
.bi-do2-wrap .bi-do2-cell--clash {
    background: var(--do-cell-clash);
    border: 1px solid var(--color-indigo-200);
    color: var(--bk-run);
}
.bi-do2-wrap .bi-do2-cell--work:hover,
.bi-do2-wrap .bi-do2-cell--booked:hover { background: var(--color-indigo-100); }
.bi-do2-wrap .bi-do2-cell--off:hover,
.bi-do2-wrap .bi-do2-cell--rest:hover { background: var(--gray-200); }
.bi-do2-wrap .bi-do2-cell:focus-visible { outline: 0; box-shadow: var(--ring-focus); }
/* 끌어서 고르는 중 — 손이 지나간 칸 */
.bi-do2-wrap .bi-do2-cell.is-dragging { box-shadow: var(--ring-focus); }
.bi-do2-wrap .bi-do2-grid.is-dragging { cursor: crosshair; }

/* ── 바닥 범례 — 상자 바닥에 «붙는다». 판이 flex:1 로 받아 허공에 뜨지 않는다 */
.bi-do2-wrap .bi-do2-foot {
    display: flex; align-items: center; gap: var(--space-4);
    padding: var(--space-2_5) var(--space-4);
    border-top: 1px solid var(--border-base);
    background: var(--bg-card);
    flex-wrap: wrap;
}
.bi-do2-wrap .bi-do2-legend { display: flex; align-items: center; gap: var(--space-3_5); flex-wrap: wrap; }
.bi-do2-wrap .bi-do2-legend__i {
    display: inline-flex; align-items: center; gap: var(--space-1_5);
    font-size: var(--fs-xs); color: var(--txt-muted);
}
.bi-do2-wrap .bi-do2-legend__sw {
    display: inline-block;
    width: 10px; height: 10px; border-radius: var(--radius-xs);
    border: 1px solid var(--color-indigo-200); background: var(--color-indigo-50);
}
.bi-do2-wrap .bi-do2-legend__sw--rest   { background: var(--do-cell-rest);   border-color: var(--do-cell-off-line); }
.bi-do2-wrap .bi-do2-legend__sw--off    { background: var(--border-light);   border-color: var(--do-cell-off-line); }
.bi-do2-wrap .bi-do2-legend__sw--booked { background: var(--do-cell-booked); }
.bi-do2-wrap .bi-do2-legend__sw--clash  { background: var(--do-cell-clash); }
.bi-do2-wrap .bi-do2-foot__hint { margin-left: auto; font-size: var(--fs-xs); color: var(--txt-disabled); }

/* ── 좌 패널 — 근무 현황 ─────────────────────────────────────── */
.bi-do2-wrap .bi-do2-chips { display: flex; align-items: center; gap: var(--space-1_5); flex-wrap: wrap; margin-bottom: var(--space-2_5); }
.bi-do2-wrap .bi-do2-chip {
    -webkit-appearance: none; appearance: none;
    border: 1px solid var(--border-base); background: var(--bg-card);
    height: 28px; padding: 0 var(--space-2_5);
    border-radius: var(--radius-full);
    font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--txt-secondary);
    cursor: pointer; display: inline-flex; align-items: center; gap: var(--space-1);
}
.bi-do2-wrap .bi-do2-chip b { font-weight: var(--fw-bold); }
.bi-do2-wrap .bi-do2-chip.is-on { background: var(--bk-run); border-color: var(--bk-run); color: var(--txt-inverse); }
.bi-do2-wrap .bi-do2-chip:hover:not(.is-on) { background: var(--bg-hover); }

.bi-do2-wrap .bi-bk2-side { overflow-y: auto; }
.bi-do2-wrap .bi-bk2-side > .bi-bk2-card.bi-do2-flex { flex: 0 0 auto; }
.bi-do2-wrap .bi-do2-stat { display: flex; flex-direction: column; }
.bi-do2-wrap .bi-do2-stat__r {
    display: flex; align-items: center; gap: var(--space-2_5);
    padding: var(--space-2) 0;
    border-top: 1px solid var(--do-line);
}
.bi-do2-wrap .bi-do2-stat__r:first-child { border-top: 0; }
.bi-do2-wrap .bi-do2-stat__tx { min-width: 0; flex: 1; display: block; }
.bi-do2-wrap .bi-do2-stat__n {
    display: block;
    font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-primary);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bi-do2-wrap .bi-do2-stat__s {
    display: block;
    font-size: var(--fs-xs); color: var(--txt-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── 좌 패널 — 기본 근무 규칙 ────────────────────────────────── */
.bi-do2-wrap .bi-do2-rule__r {
    display: flex; align-items: center; justify-content: space-between;
    padding: var(--space-2) 0;
    font-size: var(--fs-sm);
}
.bi-do2-wrap .bi-do2-rule__r + .bi-do2-rule__r { border-top: 1px solid var(--do-line); }
.bi-do2-wrap .bi-do2-rule__k { color: var(--txt-muted); }
.bi-do2-wrap .bi-do2-rule__v { font-weight: var(--fw-bold); color: var(--txt-primary); }
/* 2026-09-29 — 규칙 값 아래에 붙는 «곁말» 한 줄.
   「예약단위 설정없음 판은 30분」 이 한 줄에 붙어 있어 무엇이 30분인지 안 보였다(사용자 지적).
   지점 설정과 «이 판의 칸» 을 갈라 적는다. */
/* 2026-09-29 — 담긴 줄에서 «바로 고치는» 작은 칸 (입고 팝업의 단가·수량).
   사용자 지시로 단가는 읽기전용 글자, 수량은 ∓ 단추뿐이던 것을 둘 다 칸으로 바꿨다.
   줄 안에 들어가는 칸이라 사다리의 가장 작은 키를 쓰고 폭은 글자 수에 맞춘다. */
/* ══ 2026-09-29 (2) 예약 선결제(예약금) 덩이 — 규격안 spec_pop/bk_deposit.html ══
   담긴 시술 덩이(.bi-bq-item)와 «같은 꼴» 을 쓰고 금액 자리만 더한다. */
.bi-bq-dep__amt {
    flex: 0 0 auto;
    font-size: var(--fs-base); font-weight: var(--fw-extrabold); color: var(--txt-primary);
    white-space: nowrap;
}
/* ⚠ 2026-09-30 — 1px 은 스케일에 없는 값이었다(L1 TK-SPACE. 동료 세션이 짚었다).
   같은 꼴이 이미 있다 — 카드 승인취소의 «105,000원» (.bi-pay2__sumamt small, 15835줄)이
   var(--space-0_5)(2px)를 쓴다. 같은 «금액 + 단위» 이므로 같은 값으로 맞춘다.
   ⚠ 0 으로 붙이면 숫자와 «원» 이 한 덩이로 읽혀 금액이 한눈에 안 들어온다 — 재어 보고 2 를 골랐다. */
.bi-bq-dep__amt small { margin-left: var(--space-0_5); font-size: var(--fs-2xs); font-weight: var(--fw-bold); color: var(--txt-muted); }
.bi-bq-dep__ok { color: var(--color-success-700); }
.bi-bq-dep__no { color: var(--color-warning-700); }

/* 2026-09-29 (2) — 네이버 예약이라 «시작 시각을 못 바꾼다» 는 안내 한 줄.
   ⚠ 처음엔 JS 가 .bi-pop-note--top 을 append 로 끼워 넣었다 — 체크박스 아래로 밀려 붙고
      글자도 깨져 보였다(사용자 지적). 자리를 뷰에 두고 여기서 모양을 준다. */
.bi-bq-lock {
    display: flex;
    align-items: center;
    gap: var(--space-1_5);
    margin-top: var(--space-1_5);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--bg-input);
    color: var(--txt-muted);
    font-size: var(--fs-2xs);
    line-height: 1.5;
}
.bi-bq-lock i { color: var(--txt-disabled); font-size: var(--fs-2xs); }
/* ⚠⚠ 2026-09-30 사용자 지적 — 「네이버예약이 아닌데 «네이버예약이라 시작시간을 바꿀 수 없다»
     안내문구가 나오고 시간 선택이 안 되」. 내가 만든 흠이다.
   .bi-hidden 은 7528줄, 이 규칙은 16542줄 — **뒤에 오는 이것이 이긴다.**
   그래서 감춰 둔 안내가 **늘 보였고**, 시각 칸을 누르는 코드가 「보이면 잠김」 으로 보아
   crm 예약에서도 시간 팝업이 안 열렸다.
   CLAUDE.md 의 학습된 함정 그대로다 — 「display 를 뒤에서 지정하면 .bi-hidden 을 이긴다 →
   `#id.bi-hidden { display:none }` 을 **같이** 선언한다」. 여기서는 클래스끼리라 같은 방식으로 못박는다. */
.bi-bq-lock.bi-hidden { display: none; }   /* 클래스 둘(0,2,0) 이라 .bi-hidden(0,1,0)·.bi-bq-lock(0,1,0) 을 모두 이긴다 — 강제 우선순위를 쓰지 않는다 */

/* 2026-09-29 — 예약등록 팝업 «시술 소요시간으로 끝 시각 계산» 체크 (8-1)
   시간 칸 바로 아래 붙는 작은 줄이다. 칸 사이를 벌리지 않게 위 여백만 조금. */
.bi-bq-autoend {
    display: flex;
    align-items: center;
    gap: var(--space-1_5);
    margin-top: var(--space-1_5);
    font-size: var(--fs-2xs);
    color: var(--txt-muted);
    cursor: pointer;
}
/* 2026-09-29 — 네이버 예약이라 잠근 칸 (8-6). 눌러도 안 열리는 것이 «고장» 으로
   보이지 않게 «잠김» 으로 보이게 한다. 까닭은 칸 아래 한 줄로 따로 적는다. */
.bi-input.is-locked,
.bi-counter-search-btn.is-locked {
    background: var(--bg-input);
    color: var(--txt-disabled);
    cursor: not-allowed;
}

.bi-bq-inp {
    width: 72px;
    height: 22px;
    padding: 0 var(--space-1_5);
    border: 1px solid var(--border-base);
    border-radius: var(--radius-sm);
    background: var(--bg-card);
    color: var(--txt-primary);
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    text-align: right;
    vertical-align: middle;
}
.bi-bq-inp:focus { border-color: var(--brand-blue); outline: none; }
.bi-bq-inp--qty { width: 48px; text-align: center; }
/* ⚠ 2026-09-30 — 위 두 줄은 (0,1,0) 이라 전역 팝업 규칙
     `.bi-pop-page input[type="text"]{height:var(--pop-field-h)}`(0,2,1 · 10669줄)에 **졌다**.
     뜻은 22 인데 실제는 **36** 으로 그려져, 54 이어야 할 담긴 줄이 **59** 로 부풀었다
     (2026-09-30 실측 · _do_rbrow.mjs · cmp_box 가 「규격 61 → 실제 59」 로 알렸다).
   ⚠ 예약등록의 .bi-bq-qin 이 **같은 함정에 먼저 물렸다**(§91 · 2026-09-29).
     팝업 안 입력칸은 항상 .bi-pop-page 를 앞에 두고 **재본 뒤에** 고쳐야 한다(_SPEC_CHECKLIST §2-24 ②).
   ⚠ 값은 그대로 22 다 — 높이만 되찾는다. 폭은 위 줄이 정한다. */
.bi-pop-page .bi-bq-item .bi-bq-inp { height: 22px; }

.bi-do2-wrap .bi-do2-rule__sub {
    display: block;
    /* ⚠ 2026-09-29 — `--fw-regular` 로 적었다가 고쳤다. **그 이름은 없다**(400 은 --fw-normal).
         없는 변수를 폴백 없이 쓰면 «그 선언 하나» 가 아니라 통째로 무효다(TK-UNDEF).
         결과로 이 곁말은 굵기가 아니라 **물려받은 굵기** 로 보이고 있었다. */
    font-weight: var(--fw-normal);
    font-size: var(--fs-2xs);
    color: var(--txt-muted);
}
.bi-do2-wrap .bi-do2-rule__sw {
    display: flex; align-items: center; justify-content: space-between;
    padding: var(--space-2_5) 0 var(--space-1_5);
    font-size: var(--fs-sm); color: var(--txt-secondary);
    border-top: 1px solid var(--do-line);
}

/* 켜고 끄는 단추 — 규격에 스위치가 없어 여기서 정한다(§61) */
.bi-do2-wrap .bi-do2-sw {
    -webkit-appearance: none; appearance: none; border: 0;
    width: 40px; height: 22px; flex-shrink: 0;
    border-radius: var(--radius-full); background: var(--gray-300);
    position: relative; cursor: pointer; transition: var(--transition-base);
    /* ⚠ font 를 안 정하면 <button> 기본값 13.3333px 을 물려받는다 — 글자 눈금 밖이다.
       글자가 없어 눈에는 안 보이지만 검사에는 걸린다. */
    font: inherit;
}
.bi-do2-wrap .bi-do2-sw__k {
    position: absolute; top: 2px; left: 2px;
    width: 18px; height: 18px; border-radius: var(--radius-full);
    background: var(--bg-card); box-shadow: var(--shadow-xs);
    transition: var(--transition-base);
}
.bi-do2-wrap .bi-do2-sw.is-on { background: var(--color-info-700); }
.bi-do2-wrap .bi-do2-sw.is-on .bi-do2-sw__k { left: 20px; }

/* ── 아바타 — 이니셜이 기본, 사진이 덮는다(§40-8 폴백) ───────────── */
.bi-do2-wrap .bi-do2-av,
.bi-do2-pop .bi-do2-av {
    width: 32px; height: 32px; flex-shrink: 0;
    border-radius: var(--radius-full);
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--brand-navy); color: var(--txt-inverse);
    font-size: var(--fs-xs); font-weight: var(--fw-bold);
    position: relative; overflow: hidden;
}
.bi-do2-wrap .bi-do2-av > img,
.bi-do2-pop .bi-do2-av > img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; }

/* ══ ⋯ 일괄 설정 메뉴 — 공용 .bi-dropdown 안의 «보조설명 있는 항목» ══ */
.bi-do2-menu { width: var(--do-menu-w); }
.bi-do2-menu .bi-do2-menu__lb {
    padding: var(--space-2_5) var(--space-3) var(--space-1_5);
    font-size: var(--fs-xs); font-weight: var(--fw-semibold); color: var(--txt-disabled);
}
.bi-do2-menu .bi-do2-menu__i {
    -webkit-appearance: none; appearance: none; border: 0; background: transparent;
    width: 100%; display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    font-size: var(--fs-base); color: var(--txt-secondary);
    cursor: pointer; text-align: left;
}
.bi-do2-menu .bi-do2-menu__i:hover { background: var(--bg-hover); }
.bi-do2-menu .bi-do2-menu__i > i { width: 16px; text-align: center; color: var(--txt-muted); }
.bi-do2-menu .bi-do2-menu__i > small { margin-left: auto; font-size: var(--fs-sm); color: var(--txt-disabled); }
.bi-do2-menu .bi-do2-menu__i--danger { color: var(--color-danger-600); }
.bi-do2-menu .bi-do2-menu__i--danger > i { color: var(--color-danger-600); }
.bi-do2-menu .bi-do2-menu__div { height: 1px; margin: var(--space-1) 0; background: var(--do-line); }

/* ══ 기간 휴무 설정 팝업 — 시안 폭 560 ════════════════════════════ */
.bi-modal--do { box-sizing: border-box; width: var(--do-modal-w); max-width: calc(100vw - var(--space-8)); }
.bi-modal--do .bi-modal__head-ico { background: var(--pop-navy); color: var(--txt-inverse); border-radius: var(--radius-lg); }
.bi-modal--do .bi-modal__head-txt h3 { font-size: var(--pop-title-fs); }

.bi-do2-pop { display: flex; flex-direction: column; min-height: 0; }
.bi-do2-pop, .bi-do2-pop * { box-sizing: border-box; }
/* 검색 띠 — 머리와 목록 사이의 «다른 성격의 줄» */
.bi-do2-pop .bi-do2-pop__srch {
    padding: var(--space-3) var(--space-4);
    background: var(--bg-page);
    border-bottom: 1px solid var(--border-base);
}
.bi-do2-pop .bi-do2-roles { display: flex; align-items: center; gap: var(--space-1_5); margin-top: var(--space-2_5); flex-wrap: wrap; }
.bi-do2-pop .bi-do2-role {
    -webkit-appearance: none; appearance: none;
    border: 1px solid var(--border-base); background: var(--bg-card);
    height: 28px; padding: 0 var(--space-3);
    border-radius: var(--radius-full);
    font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--txt-secondary);
    cursor: pointer;
}
.bi-do2-pop .bi-do2-role.is-on { background: var(--bk-run); border-color: var(--bk-run); color: var(--txt-inverse); }
.bi-do2-pop .bi-do2-role:hover:not(.is-on) { background: var(--bg-hover); }

.bi-do2-pop .bi-do2-pop__cnt {
    display: flex; align-items: center; justify-content: space-between;
    padding: var(--space-3) var(--space-4) var(--space-2);
    font-size: var(--fs-sm); color: var(--txt-muted);
}
.bi-do2-pop .bi-do2-pop__cnt b { color: var(--txt-primary); font-weight: var(--fw-bold); }

/* 대상 목록 — «줄» 이다(타일이 아니다). 고른 줄은 옅은 파랑 바탕 */
.bi-do2-pop .bi-do2-plist { max-height: 230px; overflow-y: auto; }
.bi-do2-pop .bi-do2-pitem {
    display: flex; align-items: center; gap: var(--space-2_5);
    padding: var(--space-2) var(--space-4);
    cursor: pointer;
}
.bi-do2-pop .bi-do2-pitem:hover { background: var(--bg-hover); }
.bi-do2-pop .bi-do2-pitem.is-on { background: var(--pop-row-sel); }
.bi-do2-pop .bi-do2-pitem > input[type=checkbox] {
    /* ⚠ 전역 input[type=checkbox]{visibility:hidden;display:none}(§글로벌, 스프라이트 +label 용)
       을 «되받아» 켠다. 특이도로 이겨도 선언이 없으면 안 보인다(CLAUDE §7 «체크박스 안 먹힘»). */
    visibility: visible; display: inline-block; -webkit-appearance: checkbox; appearance: auto;
    width: var(--pop-check); height: var(--pop-check); flex-shrink: 0;
    accent-color: var(--color-info-700); margin: 0; cursor: pointer;
}
.bi-do2-pop .bi-do2-pitem__n { font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-primary); }
.bi-do2-pop .bi-do2-pitem__p {
    font-size: var(--fs-sm); color: var(--txt-muted);
    background: var(--bg-subtle); border-radius: var(--radius-sm);
    padding: 1px var(--space-1_5);
}

.bi-do2-pop .bi-do2-pop__sec { padding: var(--space-3_5) var(--space-4) 0; border-top: 1px solid var(--border-base); }
.bi-do2-pop .bi-do2-pop__st {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: var(--space-2);
    font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-primary);
}
.bi-do2-pop .bi-do2-pop__st small { font-weight: var(--fw-normal); color: var(--txt-muted); }
.bi-do2-pop .bi-do2-pop__lb { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-secondary); margin-bottom: var(--pop-f-gap); }
.bi-do2-pop .bi-do2-pop__dates { display: flex; align-items: flex-end; gap: var(--space-2_5); }
.bi-do2-pop .bi-do2-pop__dates > div { flex: 1; min-width: 0; }
.bi-do2-pop .bi-do2-pop__dash { color: var(--txt-disabled); padding-bottom: var(--space-2_5); }

/* 설정 내용 — 아이콘 없는 알약 넷 (시안 dayoff2) */
.bi-do2-pop .bi-do2-kinds { display: flex; align-items: center; gap: var(--space-2); }
.bi-do2-pop .bi-do2-kind {
    -webkit-appearance: none; appearance: none;
    flex: 1; height: 38px;
    border: 1px solid var(--border-base); background: var(--bg-card);
    border-radius: var(--radius-full);
    font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-secondary);
    cursor: pointer; white-space: nowrap;
}
.bi-do2-pop .bi-do2-kind.is-on { background: var(--bk-run); border-color: var(--bk-run); color: var(--txt-inverse); }
.bi-do2-pop .bi-do2-kind:hover:not(.is-on) { background: var(--bg-hover); }

/* 바닥 — 좌 선택요약 · 우 단추 둘 */
.bi-do2-pop .bi-do2-pop__foot {
    display: flex; align-items: center; gap: var(--space-2_5);
    padding: var(--pop-foot-pad-t) var(--space-4) var(--pop-foot-pad-b);
    border-top: 1px solid var(--border-base);
}
.bi-do2-pop .bi-do2-pop__sum {
    flex: 1; min-width: 0;
    font-size: var(--fs-sm); color: var(--txt-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bi-do2-pop .bi-do2-pop__sum b { color: var(--txt-primary); font-weight: var(--fw-bold); }
/* 규격을 «자리» 로 못박는다 — 누가 --sm 을 붙여도 이 자리는 팝업 푸터 키(34)다 */
.bi-do2-pop .bi-do2-pop__foot .bi-btn {
    height: var(--pop-btn-h); font-size: var(--pop-btn-fs); font-weight: var(--fw-bold);
    border-radius: var(--pop-btn-r);
}

/* 저장 단추 안의 «변경 N» 조각 — 시안 dayoff.png 머리줄 */
.bi-do2-cnt {
    display: inline-flex; align-items: center;
    margin-left: var(--space-1_5); padding: 1px var(--space-1_5);
    border-radius: var(--radius-full);
    background: color-mix(in srgb, var(--white) 24%, transparent);
    font-size: var(--fs-2xs); font-weight: var(--fw-bold);
    /* ⚠ line-height 1 — 1.6 이면 칩 상자가 18 이 되어 --sm 단추(27)를 32 로 늘린다.
       칩은 «단추 사다리를 바꾸지 않는다»(2026-09-15 결제팝업 세션이 qc.mjs btn 으로 잡아 줬다). */
    line-height: 1;
}

/* ⚠ 2026-09-17 — 미니달력 머리의 «• 휴무 • 반차» 범례 선언을 걷었다.
     점 자체를 없애면서(사용자 지시) 범례도 함께 걷었다 — 가리킬 것이 없는 범례는
     «있는데 안 맞는 설명» 이 되어 없는 것보다 나쁘다. 마크업도 지웠다. */

/* «기본 규칙으로 되돌리기» — 카드 폭을 꽉 채우는 보조 단추 */
.bi-do2-wrap .bi-do2-reset { width: 100%; margin-top: var(--space-2_5); justify-content: center; }
/* 「설정 내용」 절은 위쪽 구분선 없이 바로 이어진다(시안) */
.bi-do2-pop .bi-do2-pop__sec--tight { border-top: 0; }
/* 안내 박스 — 알약 줄과 푸터 사이 (인라인 style 금지 §4) */
.bi-do2-pop .bi-do2-pop__note { margin: var(--space-3_5) 0; }

/* ── §61-2 시안 실측 반영 — «버튼 키 · 글자 크기» (2026-09-16) ──────────
 * 사용자 지적: 「시안에서 중요하게 말한 버튼 크기, 글 크기, 색등 다 무시하고 규격안을 만들었네」.
 * 맞다. 색은 픽셀로 쟀지만 **키와 글자 크기는 사다리에서 «역할로» 골랐다.**
 *
 * 다시 잰 방법 (눈대중 없음)
 *   키   — 시안에서 «테두리·채움색이 길게 이어지는 줄» 의 위·아래를 찾았다(_do_btn.mjs · _do_edge.mjs).
 *   글자 — 같은 서체(Pretendard)로 직접 그려 만든 «높이↔크기» 눈금표에 대고 되짚었다
 *          (_do_cal2.mjs → out/_do_glyph_cal.json). 0.72 같은 상수로 나누지 않는다.
 *          ⚠ 폭은 쓰지 않는다 — 캔버스 자간이 달라 처음엔 제목을 16 으로 잘못 되짚었다(실제 18).
 *
 * 실측값 ↔ 적용값
 *   머리 툴바 단추/날짜칸  35·34 → 34   (사다리 예외 34 = 이미 있는 등급)
 *   본문 줄 단추(오늘·일괄) 31    → 32   (사다리 base 32 · 1px 차)
 *   머리 배지               21    → 22   (사다리 22)
 *   근무현황 칩             22    → 22   ✔
 *   상태 꼬리표             21    → 22   ✔(그대로)
 *   칸                     46    → 46   ✔(그대로)
 *   팝업 직급칩             26    → 26
 *   팝업 설정내용 알약       36    → 36
 *   팝업 검색칸             38    → 38   (--pop-search-h)
 *   팝업 머리 아이콘 네모     29    → 28
 *   팝업 푸터 단추           33·35 → 34   ✔(그대로)
 *   글자: 칸 11→12 · 디자이너 이름 13→14 · 규칙 13 · 단추 14 · 메뉴 12 · 팝업 제목 16
 *   글자(그대로 맞았던 것): 페이지 제목 18 · 시간 눈금 12 · 휴게 11
 * ──────────────────────────────────────────────────────────────────── */

/* 머리 툴바 — 시안 34. 공용 .bi-btn--sm(27) 을 고치지 않고 «이 자리» 에서 다시 정한다 */
.bi-do2-tb .bi-btn {
    height: 34px;
    font-size: var(--fs-md);          /* 시안 14 */
    font-weight: var(--fw-semibold);
}
/* ⚠ 머리 툴바는 .bi-do2-wrap «밖» 이라 전역 border-box 가 안 걸린다 —
   content-box 에서는 height 34 가 «속» 34 라 겉이 40 이 된다(실측으로 잡았다). */
.bi-do2-tb .bi-datenav,
.bi-do2-tb .bi-datenav * { box-sizing: border-box; }
.bi-do2-tb .bi-datenav { height: 34px; }
.bi-do2-tb .bi-datenav__input { height: 26px; padding: 0 var(--space-2_5); }
.bi-do2-tb .bi-datenav__input { font-size: var(--fs-md); }

/* 본문 줄 — 시안 31 → 사다리 32 */
.bi-do2-wrap .bi-do2-tool .bi-btn {
    height: 32px;
    font-size: var(--fs-md);          /* 시안 14 */
    font-weight: var(--fw-semibold);
}
.bi-do2-wrap .bi-do2-tool .bi-datenav { height: 32px; }
.bi-do2-wrap .bi-do2-tool .bi-datenav__input { font-size: var(--fs-md); }

/* 머리 배지 — 시안 21 → 22 */
.bi-do2-wrap .bi-do2-pill { height: 22px; }

/* 근무현황 칩 — 시안 22 */
.bi-do2-wrap .bi-do2-chip { height: 22px; }

/* 칸 글자 — 시안 12 (11 이었다) */
.bi-do2-wrap .bi-do2-cell { font-size: var(--fs-sm); }
/* 「휴게」 는 시안 11 — 칸 안에서만 한 단 작다 */
.bi-do2-wrap .bi-do2-cell--rest { font-size: var(--fs-xs); }

/* 디자이너 이름 — 시안 14 (13 이었다) */
.bi-do2-wrap .bi-do2-rowhd__n { font-size: var(--fs-md); }

/* 기본 근무 규칙 줄 — 시안 13 (12 이었다) */
.bi-do2-wrap .bi-do2-rule__r,
.bi-do2-wrap .bi-do2-rule__sw { font-size: var(--fs-base); }

/* ⋯ 메뉴 항목 — 시안 12 (13 이었다) */
.bi-do2-menu .bi-do2-menu__i { font-size: var(--fs-sm); }

/* ══ 기간 휴무 팝업 — 시안 실측 ════════════════════════════════════ */
/* 머리 아이콘 네모 — 시안 29 (38 이었다). 공용 .bi-modal__head-ico 는 고치지 않는다 */
.bi-modal--do .bi-modal__head-ico { width: 28px; height: 28px; font-size: var(--fs-base); }
/* 팝업 제목 — 시안 16 (15 였다) */
.bi-modal--do .bi-modal__head-txt h3 { font-size: var(--fs-lg); }

/* 검색칸 — 시안 38. 공용 .bi-bk2-search(40) 를 이 두 자리에서만 다시 정한다 */
.bi-do2-pop .bi-bk2-search > input,
.bi-do2-wrap .bi-bk2-search > input { height: 38px; }

/* 직급 칩 — 시안 26 */
.bi-do2-pop .bi-do2-role { height: 26px; }

/* 설정 내용 알약 — 시안 36 · 글자 14 */
.bi-do2-pop .bi-do2-kind { height: 36px; font-size: var(--fs-md); }

/* 푸터 단추 글자 — 시안 14 (13 이었다). 키 34 는 그대로 */
.bi-do2-pop .bi-do2-pop__foot .bi-btn { font-size: var(--fs-md); }

/* ── 좌패널 세로 리듬 — 시안 실측 (2026-09-16) ──────────────────────
 * 시안 좌패널: 검색 38 → 달력카드 237 → (틈 9) → 근무현황 246 → (틈 9) → 규칙카드 206.
 * 그 안에서 근무현황 «목록» 은 168 이다. 내 것은 달력·규칙 카드가 각각 14 씩 커서
 * 목록이 110 으로 눌려 두 줄만 보였다(시안은 네 줄). 카드 안쪽 여백을 한 단 줄여 되찾는다. */
.bi-do2-wrap .bi-bk2-card { padding: var(--space-3); }         /* 14 → 12 (카드 셋 × 위아래) */
/* ⚠ min-height:168(시안 목록 높이)로 밀었더니 남는 자리를 넘어 «기본 근무 규칙» 카드와 겹쳤다.
   자리가 없으면 «겹치는» 대신 «구르게» 한다 — 겹침은 규격 위반이고 스크롤은 아니다. */

/* ── §61-3 글자 크기 2차 실측 (2026-09-16) ─────────────────────────
 * 1차에서 «내가 고른 11자리» 만 봤다. 사용자: 「간격 글 크기 등 다른게 보이는데」 —
 * 남은 자리를 같은 눈금표로 다시 재서 아홉 곳을 한 단 올리거나 내렸다(_do_txt2.mjs).
 * ⚠ 아래 값은 시안 글자 «높이» 로 되짚은 것이다. 10 ↔ 11 처럼 한 단 안에서
 *   후보가 둘인 자리는 옆 글자와의 관계로 골랐고, 그 자리는 주석에 «후보» 를 남겼다. */

/* 좌패널 카드 제목 — 시안 14 (공용 .bi-bk2-card__t 는 13) */
.bi-do2-wrap .bi-bk2-card__t { font-size: var(--fs-md); }

/* 머리 배지 글자 — 시안 12 (11 이었다) */
.bi-do2-wrap .bi-do2-pill { font-size: var(--fs-sm); }

/* 판 머리행 라벨 — 시안 12 (13 이었다) */
.bi-do2-wrap .bi-do2-hd__lb { font-size: var(--fs-sm); }

/* 머리줄 안내 — 시안 13 (11 이었다) */
.bi-do2-wrap .bi-do2-tool__hint { font-size: var(--fs-base); }

/* 바닥 범례 — 시안 12 (11 이었다) */
.bi-do2-wrap .bi-do2-legend__i { font-size: var(--fs-sm); }

/* 팝업 대상 목록 — 이름 시안 14(13 이었다) · 직급 꼬리표 시안 11(12 였다, 후보 10·11) */
.bi-do2-pop .bi-do2-pitem__n { font-size: var(--fs-md); }
.bi-do2-pop .bi-do2-pitem__p { font-size: var(--fs-xs); }

/* 팝업 바닥 선택 요약 — 시안 14 (12 였다) */
.bi-do2-pop .bi-do2-pop__sum { font-size: var(--fs-md); }

/* 팝업 «총 N일» — 시안 11 (12 였다, 후보 10·11) */
.bi-do2-pop .bi-do2-pop__st small { font-size: var(--fs-xs); }
/* §61-2 끝 ────────────────────────────────────────────────────────── */

/* §61 끝 ─────────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §78 · 매출등록 — 새 시안 정합 (bi-bs2-*)           신설 2026-09-15
   ──────────────────────────────────────────────────────────────────────
   규격안  renew_crm/tools/qc/spec_pos/main.html
   시안    renew_crm/reimg/buysell.png   (1917x1103 = 1920 뷰포트 1:1)
   문서    renew_crm/docs/design/sg2/49_매출등록_시안정합.md
   대조    renew_crm/pos_spec3.html
   답안지  renew_crm/tools/qc/spec_match/buysell.mjs

   ⚠ 사용자 지시(2026-09-15): 「시안과 달라도 기존 css 에 덮으란게 아니야 —
      다르면 새로 만들어서 추가해」. 그래서 접두를 bi-bs2-* 로 **새로 그렸다.**
      옛 .bi-counter-*(4178~4465) · .bi-bs-*(4466~5048) · POS 절(§44·§45)은
      **한 줄도 고치지 않았다.** 되돌릴 것이 없다.

   시안 색 ↔ 토큰 (2026-09-15 실측 · 같은 날 정정):
        #121D3F → var(--pop-navy)         **정확히 일치**
        #EEF2FF → var(--color-indigo-50)  **정확히 일치** (--pop-pill-bg · --bk-fix-bg 와 같은 값)
        #1D4ED8 → var(--color-info-700)   토큰에 **있다** (--bk-fix 와 같은 값)
      ⚠ 그런데 «강조 파랑» 은 --color-info-700 이 아니라 **var(--brand-blue) #0023B7** 을 쓴다.
        까닭: styleguide2 §12-5 가 POS 에 「색은 둘만 — N Pay 초록 · **결제완료 브랜드블루**」
        로 못박았다. 시안 값과 규격이 부딪히면 **규격을 따른다**(§47 12-1 전례).
        → «토큰이 아니라서» 가 아니라 «규격이 다른 토큰을 지정해서» 다. (앞선 주석을 정정한다)
      ⚠ 날색(생 hex)을 그대로 쓰면 게이트가 막는다 — 같은 값의 토큰을 쓴다(style.css:10995).

   실측 수치(node _bs2_measure.mjs): 세 열 330/860/425 (구분선 x=602·1462)
     · 대기 카드 65 / 간격 8 · 탭 트랙 54(칩 32) · 바닥 요약 45
     · 결제수단 타일 **1행 4개** 92x56 · 푸터 단추 34 → 사다리 32
   ══════════════════════════════════════════════════════════════════════ */

/* 예외 페이지는 전역에 기대지 않고 스스로 선언한다(CLAUDE §7) */
.bi-bs2, .bi-bs2 * { box-sizing: border-box; }
.bi-bs2 { padding: var(--content-pad); background: var(--bg-page); }

.bi-bs2-card,
.bi-rs-card { background: var(--bg-card); border: 1px solid var(--border-base);
  border-radius: var(--radius-lg); overflow: hidden; }

/* ── 툴바 ───────────────────────────────────────────────────────── */
.bi-bs2-top { display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-base); }
/* ⚠ .bi-bq-foot(예약등록 팝업) 과 우연히 같았다 — 제목+진행표시가 좁을 때 줄로 내려간다 */
.bi-bs2-top__l,
.bi-rs-top__l { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
/* ⚠ .bi-erp-title 과 선언이 «우연히» 같았다. 합치지 않는다 — 다른 모듈의 제목 규격에 묶인다.
   대신 이 제목이 정말 필요한 것을 적는다: 「결제 · 매출등록」은 줄바꿈하지 않는다. */
.bi-bs2-top__t,
.bi-rs-top__t { font-size: var(--fs-2lg); font-weight: var(--fw-bold); margin: 0;
  color: var(--txt-primary); white-space: nowrap; }
.bi-bs2-top__r,
.bi-rs-top__r,
.bi-rs-hrow__t { display: flex; align-items: center; gap: var(--space-2); }

.bi-bs2-steps,
.bi-rs-steps { display: flex; align-items: center; gap: var(--space-2_5);
  margin: 0; padding: 0; list-style: none; }
.bi-bs2-step { display: flex; align-items: center; gap: var(--space-1_5);
  font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-bs2-step__mk { width: 18px; height: 18px; border-radius: var(--radius-full);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--fs-2xs); font-weight: var(--fw-bold); }
/* 시안 실측: 끝난 단계는 «남색 채움 + 흰 ✓» · 지금 단계는 «#1D4ED8 채움 + 흰 숫자» 다.
   앞서 둘이 뒤바뀌어 있었다(끝난=연파랑+파란✓ · 지금=--brand-navy). */
.bi-bs2-step.is-done .bi-bs2-step__mk { background: var(--pop-navy); color: var(--bg-card); }
.bi-bs2-step.is-now  .bi-bs2-step__mk { background: var(--color-info-700); color: var(--bg-card); }
.bi-bs2-step.is-now { color: var(--txt-primary); font-weight: var(--fw-bold); }

/* ⚠ 2026-09-22 — 접수/시술전표(.bi-rs-newslip)를 여기에 «같이» 적는다.
     사용자 지시: 「접수 전표 새전표 버튼 매출등록 새전표 버튼과 CSS 동일하게 적용」.
     실측 차이는 셋이었다 — 여백 10↔12 · 글자 12↔13 · 아이콘 10↔13(rs 가 작았다).
     따로 적으면 선언이 한 글자도 안 달라 SPEC-DUP 으로 잡힌다(라벨 .bi-bs2-lb 와 같은 판단). */
.bi-bs2-newslip,
.bi-rs-newslip { height: 27px; padding: 0 var(--space-3); font-size: var(--fs-base);
  font-weight: var(--fw-semibold); border: 1px solid var(--border-base);
  /* 시안 실측: 단추 글자색 #111827 — --txt-secondary 였다 */
  background: var(--bg-card); color: var(--txt-primary); border-radius: var(--radius-md); }
.bi-bs2-datechip,
.bi-rs-datechip { display: inline-flex; align-items: center; gap: var(--space-1_5); height: 27px;
  /* 시안 실측: 날짜칩 바탕은 «흰색» 이다(--color-indigo-50 이 아니다) */
  padding: 0 var(--space-2_5); background: var(--bg-card);
  border: 1px solid var(--border-base); border-radius: var(--radius-md); }
/* 시안 실측: 달력 아이콘도 값과 같은 #121D3F 다 */
.bi-bs2-datechip__ico { color: var(--pop-navy); font-size: var(--fs-sm); }
.bi-bs2-datechip__val { border: 0; background: transparent; width: 104px;
  /* 시안 실측: 날짜 글자색 #121D3F = --pop-navy */
  font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--pop-navy); }

/* ── 세 열 ──────────────────────────────────────────────────────── */
.bi-bs2-cols { display: grid; grid-template-columns: 330px minmax(0, 1fr) 425px; align-items: stretch; }
.bi-bs2-cols > * + * { border-left: 1px solid var(--border-base); }

/* ══ 좌 · 결제 대기 ══════════════════════════════════════════════ */
/* ⚠ 2026-09-15 복구 — SPEC-DUP 합치기가 어긋나 .bi-bs2-q(열)가 «머리줄» 규칙에 붙어
   flex-direction 이 row 가 됐고, 그 탓에 대기 카드가 26px 로 눌렸다.
   열과 머리줄은 «다른 것» 이다 — 합치지 않는다. */
/* 좌·우 열은 «같은 것» 이다(세로로 쌓는 판) — 하나로 적는다 */
.bi-bs2-q, .bi-bs2-slip { display: flex; flex-direction: column; padding: var(--space-4);
  gap: var(--space-2_5); background: var(--bg-card); }
.bi-bs2-q__hd, .bi-bs2-slip__hd { display: flex; align-items: center;
  justify-content: space-between; gap: var(--space-2); }
/* ⚠ 머리글과 건수 배지는 «다른 것» 이다 — 합쳐져 머리글이 11px 파란 배지가 돼 있었다.
   (2026-09-15 «합치고 삭제» 치환의 세 번째 사고. 이 방식은 더 쓰지 않는다.) */
/* 시안 실측: 글자 16(잉크 15 · 폭환산 16.5) — 14 였다 */
.bi-bs2-q__t,
.bi-bs2-bill__t,
.bi-rs-q__t,
.bi-rs-hist__t { display: inline-flex; align-items: center; gap: var(--space-1_5);
  font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--txt-primary); }
/* 시안: 연라벤더 알약 + 보라 숫자 (bk-run-bg / bk-run). 전에는 연파랑+브랜드블루였다 */
.bi-bs2-q__n { display: inline-flex; align-items: center; justify-content: center;
  min-width: 26px; height: 22px; padding: 0 var(--space-2); border-radius: var(--radius-full);
  /* 시안 실측: 건수 글자색 #4338CA = --color-indigo-700 (--bk-run 보라가 아니다) */
  background: var(--bk-run-bg); color: var(--color-indigo-700);
  font-size: var(--fs-sm); font-weight: var(--fw-bold); }
/* 2026-09-23 사용자 지시 ⑭ — 숫자 태그는 안 보인다. 셈은 script.js 가 그대로 넣는다.
   ⚠ `.bi-hidden`(0,1,0)은 위 규칙과 셈이 같은데 «앞» 에 있어 진다 — 트랩 F2 그대로다.
      같이 적어야 숨는다. */
.bi-bs2-q__n.bi-hidden { display: none; }
.bi-bs2-q__new { height: 27px; padding: 0 var(--space-2_5); font-size: var(--fs-sm);
  font-weight: var(--fw-semibold); border-radius: var(--radius-md);
  border: 1px solid var(--border-base); background: var(--bg-card); color: var(--txt-primary); }

/* 탭 — 고른 칩은 --pop-navy (시안 #121D3F 와 정확히 일치) */
.bi-bs2-qtabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-1);
  /* 시안 실측: 트랙 여백 10 (4 였다) · 바탕은 시안 #F5F6F9 → 가장 가까운 --border-light */
  padding: var(--space-2_5); background: var(--border-light); border-radius: var(--radius-lg);
  /* 시안 실측: 트랙에 1px 테두리가 있다(y 185·240 이 #E5E7EB) → 트랙 55 */
  border: 1px solid var(--border-base); }
/* 시안 실측: 칩 30 · 미선택은 «흰 카드 + 테두리»(투명이 아니다) · 글자 14 */
/* 시안 실측(세 장 나란히 보고 다시 쟀다): 칩 «32» · 트랙 여백 «10» → 트랙 54(시안 y 185..240).
   ⚠ 앞 회차에 내가 32 를 30 으로 «고쳤다» — 그때는 트랙까지 보지 않았다. 32 는 사다리 값이다. */
.bi-bs2-qtab,
.bi-rs-qtab { height: 32px; border: 1px solid var(--border-base); background: var(--bg-card);
  border-radius: var(--radius-md); font-size: var(--fs-md); font-weight: var(--fw-semibold);
  color: var(--txt-primary); display: inline-flex; align-items: center;
  justify-content: center; gap: var(--space-1); }
.bi-bs2-qtab.is-on { background: var(--pop-navy); color: var(--bg-card); border-color: var(--pop-navy); }
/* 시안: 숫자는 라벨보다 작고 연하다 */
/* 시안 실측: 안 고른 탭의 건수는 흐리지 않다(#111827) — 고른 탭(남색) 건수만 흐린 흰색이다 */
/* 시안 실측: 안 고른 탭의 «건수» 는 #9CA3AF 다(라벨은 #111827) */
.bi-bs2-qtab__n,
.bi-rs-qtab__n { font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--txt-disabled); }
.bi-bs2-qtab.is-on .bi-bs2-qtab__n { color: inherit; opacity: .75; }

/* 시안 실측: 높이 36(241~276) · 바탕 «흰색»(--bg-input 이 아니다) */
.bi-bs2-qsearch { display: flex; align-items: center; gap: var(--space-1_5); height: 36px;
  padding: 0 var(--space-2_5); border: 1px solid var(--border-base);
  border-radius: var(--radius-lg); background: var(--bg-card); }
.bi-bs2-qsearch__ico { color: var(--txt-disabled); font-size: var(--fs-sm); }
.bi-bs2-qsearch__in,
.bi-rs-qsearch__in { flex: 1; min-width: 0; border: 0; background: transparent;
  font-size: var(--fs-md); color: var(--txt-primary); }
.bi-bs2-qsearch__in::placeholder { color: var(--txt-disabled); }

/* 카드 — 실측 65 / 간격 8. ⚠ button 기본값(buttonface·outset)을 먼저 비운다(_SPEC_CHECKLIST §2-4) */
.bi-bs2-qlist { display: flex; flex-direction: column; gap: var(--space-2); overflow-y: auto; }
.bi-bs2-qcard { border: 1px solid var(--border-base); background: var(--bg-card);
  /* ⚠ 2026-09-23 ⑯ 로 줄이 둘 → 셋이 되었다. 65 를 그대로 두면 셋째 줄이 눌린다.
     담당줄 17 + 줄간격 2 만큼만 키운다(65 → 84). 규격안 목업·답안지도 같이 고쳤다. */
  height: 84px; padding: 0 var(--space-3); border-radius: var(--radius-lg);
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-content: center;
  align-items: center; gap: var(--space-0_5) var(--space-2_5); text-align: left; width: 100%; }
/* 등급 아바타 — 시안: 원형. 두 줄을 가로지른다(이름줄 + 시각줄). */
.bi-bs2-qav { grid-row: 1 / 4; width: 40px; height: 40px; border-radius: var(--radius-full);
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  /* 시안 실측: «일반» 아바타 바탕 #D1D5DB = --gray-300 · 글자 #4B5563 = --gray-600 */
  background: var(--gray-300); color: var(--gray-600);
  font-size: var(--fs-2xs); font-weight: var(--fw-bold); }
/* 시안 실측: 아바타 바탕 #1E3A8A = --color-info-900 (브랜드네이비가 아니다) */
.bi-bs2-qcard.is-hi .bi-bs2-qav { background: var(--color-info-900); color: var(--bg-card); }
/* VVIP — 시안 실측 #C8891A. 토큰에 그 값이 없어 «가장 가까운» --color-warning-600 #D97706 을 쓴다
   (거리 55. --color-warning #F59E0B 는 77 이었다). 새 토큰을 만들지 않는다 — §4 절대규칙. */
.bi-bs2-qcard.is-vv .bi-bs2-qav { background: var(--color-warning-600); color: var(--bg-card); }
/* 시안 실측: 고른 카드 바탕 #EEF3FF = --pop-row-sel (내가 쓴 #EEF2FF 와 다르다) */
.bi-bs2-qcard.is-active { border-color: var(--color-info-700); background: var(--pop-row-sel); }
.bi-bs2-qcard__top { display: flex; align-items: center; gap: var(--space-1_5);
  min-width: 0; overflow: hidden; }   /* 이름+전화가 길면 상자를 넘었다(실측) — 잘라 낸다 */
/* 시안 실측(--전부): 잉크 16→14 · 폭 46→37 — 두 자가 같은 쪽을 가리킨다 → 14 */
/* ⚠⚠ 2026-09-28 사용자 지적 — 「매출등록 고객대기열이 접수전표와 **다르게 깨저** 나와」.
     긴 이름이 «줄바꿈» 되어 카드가 늘어나고 줄이 어긋났다(실측: 「박브이아이 / 피」 로 갈라짐).
     접수전표(.bi-rs-qcard__nm)는 `white-space: nowrap` 이라 한 줄로 두고 전화가 먼저 줄어든다 —
     같은 규칙을 준다. 이름이 잘릴지언정 «줄이 어긋나지는» 않는다.
   ⚠ 말줄임은 __top 이 이미 overflow:hidden 이라 그것으로 잘린다. */
.bi-bs2-qcard__nm { font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--txt-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 0 1 auto; }
.bi-bs2-qcard__tel { font-size: var(--fs-sm); color: var(--txt-muted); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; min-width: 0; }   /* flex 안에서 줄어들어야 잘린다 */
/* 시안 실측: 배지는 알약이고, «고른 카드» 는 보라 채움(#5B45E0=--bk-run) + 흰 글자다.
   전에는 연파랑 바탕 + 파란 글자였다(사용자 지적 「색이 전혀 지켜지지 않았다」의 한 자리). */
/* ⚠ 카드가 <button> 이다 — 글자크기를 안 주면 브라우저 기본 13.3333px 이 새어 «토큰 밖» 이 된다 */
.bi-bs2-qcard { font-size: var(--fs-base); }
.bi-bs2-qcard__tag { font-size: var(--fs-sm); font-weight: var(--fw-bold);
  border-radius: var(--radius-full); padding: var(--space-0_5) var(--space-2); justify-self: end;
  background: var(--bk-run-bg); color: var(--bk-run); white-space: nowrap; }
/* 시안 실측(--전부): 안 고른 카드의 꼬리표 글자는 #4338CA(--color-indigo-700) — --bk-run 보다 짙다 */
/* ⚠ 2026-09-23 사용자 지적 ⑪ — 아래 「미결제」 규칙이 안 먹고 이 규칙이 이기고 있었다.
   셈이 (0,4,0: qcard·is-active·tag·--done) 대 (0,3,0: qcard·is-active·--unpaid) 이라
   뒤에 와도 진다. 뒤에 쓰면 이긴다는 것은 «셈이 같을 때» 뿐이다.
   → 남보라는 «완료도 미결제도 아닌» 자리에만 준다. 빼는 쪽을 한 줄 더 적는다. */
.bi-bs2-qcard:not(.is-active) .bi-bs2-qcard__tag:not(.bi-bs2-qcard__tag--done):not(.bi-bs2-qcard__tag--unpaid):not(.bi-bs2-qcard__tag--book) { color: var(--color-indigo-700); }
.bi-bs2-qcard.is-active .bi-bs2-qcard__tag { background: var(--bk-run); color: var(--bg-card); }
.bi-bs2-qcard__tag--done,
.bi-rs-qtag--done { background: var(--border-light); color: var(--txt-muted); }
/* ⚠ 2026-09-22 사용자 지시 ⑧ — 「결제완료로 저장됐는데 실 결제금액이 0」 인 전표.
   «완료» 와 헷갈리면 안 되므로 경고 결(호박)로 가른다 — 돈이 아직 안 들어왔다는 뜻이다.
   ⚠ 위의 `:not(--done)` 규칙이 글자색을 남보라로 주므로 여기서 다시 적는다(더 뒤에 온다). */
/* ⚠ 바탕만 여기 둔다 — 글자색까지 적으면 선언이 `.bi-rs-qtag--book`(예약 호박)과
   한 글자도 안 달라져 SPEC-DUP 으로 잡힌다. 뜻이 다른 둘을 한 규칙으로 묶을 수는 없다.
   글자색은 아래 «더 긴 선택자» 가 준다(위의 :not(--done) 규칙을 이겨야 하기도 한다). */
.bi-bs2-qcard__tag--unpaid,
.bi-bs2-qcard__tag--book,
.bi-bs2-slip__st--unpaid { background: var(--bk-req-bg); }
.bi-bs2-qcard:not(.is-active) .bi-bs2-qcard__tag--unpaid,
.bi-bs2-qcard:not(.is-active) .bi-bs2-qcard__tag--book,
.bi-bs2-slip__st--unpaid { color: var(--color-warning-800); }
/* ⚠ 2026-10-07 — 결제/매출등록 대기열에 «예약» 탭이 더해져 탭이 넷이다(전체·예약·접수·완료 — 접수/시술전표 .bi-rs-qtabs 와 같은 4칸).
   예약 꼬리표(--book)는 접수/시술전표의 .bi-rs-qtag--book 과 같은 호박 결이라 위 규칙에 «묶었다». */
.bi-bs2-qtabs--4 { grid-template-columns: repeat(4, 1fr); }
.bi-bs2-qcard__sub,
.bi-rs-hrow__emp { font-size: var(--fs-base); color: var(--txt-muted); }
/* 2026-09-23 사용자 지시 ⑯ — 담당명은 «셋째 줄» 이다(시각 오른쪽이 아니라 아래).
   꼬리표·금액은 오른쪽 칸에 그대로 있고, 셋째 줄 오른쪽은 빈다. */
.bi-bs2-qcard__emp { grid-column: 2; font-size: var(--fs-sm); color: var(--txt-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.bi-bs2-qcard__amt { font-size: var(--fs-base); font-weight: var(--fw-bold);
  color: var(--txt-primary); justify-self: end; }
/* 시안: 고른 카드의 금액은 보라 계열이다 */
/* 시안 실측(--전부 · 카드 넷이 같은 값): 안 고른 카드의 금액은 #6B7280 이다 */
.bi-bs2-qcard:not(.is-active) .bi-bs2-qcard__amt { color: var(--txt-muted); }
.bi-bs2-qcard.is-active .bi-bs2-qcard__amt { color: var(--color-indigo-700); }
.bi-bs2-qempty { padding: var(--space-8) var(--space-3); text-align: center;
  font-size: var(--fs-sm); color: var(--txt-muted); }

/* 바닥 요약 — 실측 45 */
.bi-bs2-qfoot { margin-top: auto; height: 45px; display: flex; align-items: center;
  justify-content: space-between; border-top: 1px solid var(--border-base);
  /* 시안 실측: 바닥 라벨 잉크 13 · 글자색 #374151 (12 · --txt-muted 였다) */
  font-size: var(--fs-base); color: var(--txt-secondary); }
/* ⚠ 2026-09-22 사용자 지시 — 여기 있던 .bi-bs2-qfoot__v(대기열 바닥 정액권 금액)를 지웠다.
   접수전표의 .bi-rs-qfoot__v 도 같은 지시로 먼저 빠졌다 — 이제 두 화면의 이 띠에는
   「선택: 이름」 하나뿐이다. 선언이 같아 한 규칙으로 묶어 두었던 짝(.bi-bs2-final__unit)만 남는다. */
/* ⚠ 2026-09-22 — 이 둘은 «전부터» 선언이 한 글자도 다르지 않았다. 접수전표의 .bi-rs-qfoot__v 가
   같은 무리에 끼어 있어 SPEC-DUP 이 세 짝으로 묶여 있었고, 그것을 사용자 지시로 지우자
   둘만 남아 «새 위반» 으로 드러났다. 선언이 같으니 한 규칙으로 합친다 — 그리는 결과는 같다. */
/* ⚠ 2026-09-22 — 합쳐 두었던 .bi-bs2-qfoot__v 를 뺐다(대기 바닥 정액권 표시 삭제). */
.bi-bs2-final__unit { font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--color-info-700); }

/* ══ 중 · 본문 ══════════════════════════════════════════════════ */
.bi-bs2-mid { display: flex; flex-direction: column; padding: var(--space-4);
  gap: var(--space-3); min-width: 0; }

/* 고객 — 두 상태. .is-picked 하나로 갈린다. */
.bi-bs2-cust { border: 1px solid var(--border-base); border-radius: var(--radius-lg);
  padding: var(--space-3) var(--space-3_5); }
.bi-bs2-cust__pick { display: grid; grid-template-columns: 1fr 1fr auto; gap: var(--space-3); align-items: end; }
.bi-bs2-cust__card { display: none; align-items: center; gap: var(--space-3); }
.bi-bs2-cust.is-picked .bi-bs2-cust__pick { display: none; }
.bi-bs2-cust.is-picked .bi-bs2-cust__card { display: flex; }
.bi-bs2-inrow { display: flex; align-items: stretch; gap: 0; }
.bi-bs2-inrow .bi-bs2-in { border-top-right-radius: 0; border-bottom-right-radius: 0; }
/* 검색 단추 — 사다리가 아니라 «붙어 있는 입력칸» 의 키를 따른다(btn_audit 사다리예외 37 과 같은 까닭) */
.bi-bs2-schbtn { width: 40px; height: 40px; flex: 0 0 auto; border: 1px solid var(--border-base);
  border-left: 0; border-radius: 0 var(--radius-md) var(--radius-md) 0;
  background: var(--bg-input); color: var(--txt-muted); font-size: var(--fs-base); }
/* ⚠ 2026-09-22 — 여기 있던 .bi-bs2-f--btn 을 지웠다. 그 클래스가 감싸던 것은
   고객 영역의 «신규회원등록» 단추 하나뿐이었고, 그 단추를 사용자 지시로 뺐다
   (같은 단추가 대기열 머리에도 있어 한 화면에 둘이었다). 쓰는 곳 없는 규칙은 남기지 않는다. */

.bi-bs2-ava { width: 44px; height: 44px; border-radius: var(--radius-full); flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  /* 시안 실측: 등급 아바타 바탕 #1E3A8A = --color-info-900 (--brand-navy 가 아니다) */
  background: var(--color-info-900); color: var(--bg-card);
  font-size: var(--fs-xs); font-weight: var(--fw-bold); }
/* flex:1 + min-width:0 은 공통 유틸 .bi-fill 이 이미 한다 — 마크업에서 쓴다 */
.bi-bs2-cust__nm { margin: 0; display: flex; align-items: baseline; gap: var(--space-2); }
/* 시안 실측: 고객 이름 24(ink 22) — 20 이었다 */
.bi-bs2-cust__nm b { font-size: var(--fs-2xl); font-weight: var(--fw-extrabold); color: var(--txt-primary); }
.bi-bs2-cust__sub,
.bi-bs2-prow__t,
.bi-rs-cust__sub { font-size: var(--fs-md); color: var(--txt-muted); }
/* 포인트 배지와 카탈로그·메모 건수는 «같은 것» 이다(작은 파란 숫자) */
/* 포인트 배지는 파랑이 맞다(시안에 없는 자리 — 실제 화면 것) */
.bi-bs2-cust__pt { font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--brand-blue); }
/* 시안 실측: 카탈로그·고객메모의 «건수» 는 파랑이 아니라 #111827 이다 */
.bi-bs2-cust__cnt { font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--txt-primary); }
.bi-bs2-cust__meta { margin: var(--space-1) 0 0; display: flex; flex-wrap: wrap; gap: var(--space-3_5);
  font-size: var(--fs-base); color: var(--txt-muted); }
.bi-bs2-cust__meta b { color: var(--txt-secondary); font-weight: var(--fw-bold); }
.bi-bs2-cust__acts { display: flex; gap: var(--space-2); flex: 0 0 auto; }
.bi-bs2-cust__btn { height: 32px; padding: 0 var(--space-3); font-size: var(--fs-sm);
  font-weight: var(--fw-semibold); border-radius: var(--radius-md);
  /* 시안 실측: 단추 글자 #111827 */
  border: 1px solid var(--border-base); background: var(--bg-card); color: var(--txt-primary);
  display: inline-flex; align-items: center; gap: var(--space-1_5); white-space: nowrap; }
.bi-bs2-cust__chg { width: 32px; height: 32px; border-radius: var(--radius-md);
  border: 1px solid var(--border-base); background: var(--bg-card); color: var(--txt-muted);
  font-size: var(--fs-sm); }
/* 고객메모 — 접이칸. 기본은 닫혀 있다. */
.bi-bs2-cmemo { display: none; margin-top: var(--space-3); }
.bi-bs2-cmemo.is-open { display: block; }
.bi-bs2-cmemo__ta { width: 100%; height: 56px; padding: var(--space-2_5);
  font-size: var(--fs-base); resize: none; font-family: inherit;
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); color: var(--txt-primary); }

/* 필드 3열 */
/* 시안 실측: 필드 3열은 폭이 박혀 있다 — 220 / 180 / 180 · 간격 10 · 오른쪽 243 은 빈 자리.
   1fr×3(273씩)으로 열을 꽉 채우고 있었다(2026-09-16 · 세 장 나란히 보고 드러났다). */
.bi-bs2-frow { display: grid; grid-template-columns: 220px 180px 180px;
  gap: var(--space-2_5); justify-content: start; }
/* 칸 — 격자 칸이 줄어들 수 있게 min-width:0. display:block 은 div 기본값이라 보임은 그대로다.
   (styleguide2 가 전시하는데 CSS 규칙이 없어 SPEC-REWORK 「빈 규격」 으로 잡혔다) */
.bi-bs2-f, .bi-bs2-memo { display: block; min-width: 0; }
/* min-width:0 은 공통 유틸 .bi-minw-0 이 이미 한다 — 마크업에서 그 유틸을 쓴다(중복 선언 금지) */
/* 시안 실측: 라벨 글자색 #374151 = --txt-secondary (muted 가 아니다)
   ⚠ 2026-09-22 — 접수/시술전표(.bi-rs-lb)를 여기에 «같이» 적는다.
     사용자 지시가 「해당 영역 각 label font style 결제 매출전표와 **동일하게**」 였다 —
     즉 두 화면이 같이 움직이는 것이 **바라는 바**다(§79 의 「나눠 쓰지 않는다」 는
     «우연히» 얽히는 것을 막으려는 규약이고, 여기 얽힘은 지시된 것이다).
     따로 적으면 선언이 한 글자도 안 달라 SPEC-DUP 으로도 잡힌다. */
.bi-bs2-lb,
.bi-rs-lb { display: block; font-size: var(--fs-sm); font-weight: var(--fw-semibold);
  color: var(--txt-secondary); margin: 0 0 var(--space-1); }
/* ⚠ 전역 .bi-input 강제 규칙과 싸우지 않도록 «타입 셀렉터» 로 특이도를 올린다(CLAUDE §7) */
.bi-bs2 input.bi-bs2-in, .bi-bs2 select.bi-bs2-in, .bi-bs2-in {
  width: 100%; height: 40px; padding: 0 var(--space-2_5);
  font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-primary);
  border: 1px solid var(--border-base); border-radius: var(--radius-md); background: var(--bg-card); }
.bi-bs2 input.bi-bs2-in::placeholder { color: var(--txt-disabled); font-weight: var(--fw-normal); }
.bi-bs2-selbox { position: relative; display: flex; }
.bi-bs2-selbox__ico { position: absolute; right: 0; top: 0; width: 40px; height: 40px;
  border: 0; background: transparent; color: var(--txt-muted); font-size: var(--fs-base); }

/* 성별 세그먼트 */
.bi-bs2-seg { display: grid; grid-template-columns: 1fr 1fr; height: 40px;
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  overflow: hidden; background: var(--bg-card); }
/* 성별·내역탭 라디오는 «같은 것» 이다(숨은 채 :checked 만 쓴다) */
/* ⚠ 라디오와 라벨은 «다른 것» 이다 — 합치면 라디오가 보인다.
   2026-09-15 에 두 번 이 상태가 됐다(치환 패턴이 합친 규칙의 «일부» 와 일치해 잘려 나갔다).
   라디오는 숨고, :checked 만 쓴다. 숨김 선언은 §78-5 의 .bi-bs2-tabr 와 함께 둔다. */
.bi-bs2-seg__lb { display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--fs-md); font-weight: var(--fw-semibold); color: var(--txt-secondary); cursor: pointer; }
/* 시안 실측: 고른 성별 바탕 #121D3F = --pop-navy (브랜드네이비가 아니다) */
.bi-bs2-seg__r:checked + .bi-bs2-seg__lb { background: var(--pop-navy); color: var(--bg-card); }

/* 매출 메모 — 시안: 한 줄 높이. textarea 로 남긴다(script.js:207 위임). */
.bi-bs2-memo__ta { width: 100%; height: 40px; padding: var(--space-2_5);
  font-size: var(--fs-base); resize: none; font-family: inherit;
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); color: var(--txt-primary); }
.bi-bs2-memo__ta::placeholder { color: var(--txt-disabled); }
.bi-bs2-memo__dot { display: none; width: 6px; height: 6px; border-radius: var(--radius-full);
  background: var(--brand-blue); }
.bi-bs2-memo__dot.is-on { display: inline-block; }

/* ── 내역 표 ────────────────────────────────────────────────────── */
.bi-bs2-bill, .bi-bs2-info { border: 1px solid var(--border-base);
  border-radius: var(--radius-lg); overflow: hidden; }
.bi-bs2-bill__hd { display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-2_5) var(--space-3_5); border-bottom: 1px solid var(--border-base); }
/* 시안 실측: 표 제목 잉크 15 · 폭환산 16.5 → 16 (14 였다) */
/* 시안 실측: 「3건」 배지는 보라가 아니라 «연회색» 이다 — 바탕 #F3F4F6 · 글자 #6B7280 */
.bi-bs2-bill__n { font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-muted);
  background: var(--border-light); border-radius: var(--radius-full); padding: var(--space-0_5) var(--space-2); }
/* 시안 실측: 단추 글자 14 (잉크 13) — 13 이었다 */
.bi-bs2-bill__add { height: 32px; padding: 0 var(--space-3); font-size: var(--fs-md);
  font-weight: var(--fw-semibold); border-radius: var(--radius-md); border: 0;
  background: var(--color-info-700); color: var(--bg-card);
  display: inline-flex; align-items: center; gap: var(--space-1_5); }
/* 가로 스크롤은 공통 .bi-grid-area--xscroll 과 같은 선언이다 — 그 유틸을 마크업에서 쓴다 */
.bi-bs2 .bi-bs2-tbl { width: 100%; border-collapse: collapse; }
/* 여백 8 — 10 이면 여덟 칸이 합쳐 가운데 열을 6px 넘겼다(실측 846/840, 2026-09-15) */
.bi-bs2 .bi-bs2-th { padding: var(--space-2); font-size: var(--fs-sm);
  font-weight: var(--fw-semibold); color: var(--txt-muted); background: var(--bg-input);
  border-bottom: 1px solid var(--border-base); text-align: right; white-space: nowrap; }
.bi-bs2 .bi-bs2-th--no, .bi-bs2 .bi-bs2-th--cat, .bi-bs2 .bi-bs2-th--pro { text-align: left; }

/* 행 내부 — ⚠ .bi-bs-pro-* 는 **JS 훅**이다(script.js:639·1926·1941·2004).
   이름을 바꾸지 않고 .bi-bs2 스코프에서 «새 선택자» 로 모양만 얹는다.
   옛 규칙(4466~5048)은 건드리지 않았다. 스코프가 더 길어 특이도로 이긴다. */
.bi-bs2 .bi-bs-pro-row > .bi-bs-pro-td,
.bi-bs2 #pro_list_ul > tr > td { padding: var(--space-2);
  font-size: var(--fs-base); color: var(--txt-primary);
  border-bottom: 1px solid var(--border-light); text-align: right; height: auto; }
.bi-bs2 #pro_list_ul > tr > td:nth-child(1),
.bi-bs2 #pro_list_ul > tr > td:nth-child(2),
.bi-bs2 #pro_list_ul > tr > td:nth-child(3) { text-align: left; }
/* 시안 실측: 분류 꼬리표는 회색이 아니라 «파랑» 이다 — 바탕 #EEF2FF · 글자 #1D4ED8 */
.bi-bs2 .bi-bs-pro-cat-badge, .bi-bs2 .bi-bs-pro-cat-badge2 { font-size: var(--fs-2xs);
  font-weight: var(--fw-bold); color: var(--color-info-700); background: var(--color-indigo-50);
  border-radius: var(--radius-sm); padding: var(--space-0_5) var(--space-1_5); border: 0; }
.bi-bs2 .bi-bs-prosub { font-size: var(--fs-sm); color: var(--txt-muted);
  background: transparent; padding: 0; font-weight: var(--fw-normal); }
/* 시안 실측: 잉크 14 · 폭환산 14.1 · 굵게 → 14/800.
   ⚠ 이 자리는 .bi-counter-wrap.bi-bs-counter input[type="text"].bi-bs-pro-input(:10179 · 0,3,1)과
     .bi-bs-counter .bi-bs-proname(:12767)이 이긴다 — 옛 규칙을 고치지 않고 «같은 값» 을 적어 뜻을 맞춘다. */
.bi-bs2 .bi-bs-proname { font-size: var(--fs-md); font-weight: var(--fw-extrabold); color: var(--txt-primary); }
.bi-bs2 .bi-bs-qtybox { height: 30px; background: var(--bg-input);
  border-radius: var(--radius-md); padding: var(--space-0_5); }
.bi-bs2 .bi-bs-pro-qty-btn { border: 0; background: transparent; color: var(--txt-muted);
  width: 24px; height: 26px; font-size: var(--fs-base); }
.bi-bs2 .bi-bs-pro-disc-in { height: 30px; padding: 0 var(--space-2_5); font-size: var(--fs-sm);
  font-weight: var(--fw-semibold); border-radius: var(--radius-md);
  border: 1px solid var(--border-base); background: var(--bg-card);
  color: var(--txt-muted); text-align: center; }
.bi-bs2 .bi-bs-pro-disc-in.is-on { border-color: var(--color-danger); color: var(--color-danger);
  font-weight: var(--fw-bold); }

.bi-bs2-bill__empty { padding: var(--space-10) var(--space-4); text-align: center;
  color: var(--txt-muted); font-size: var(--fs-sm); }
.bi-bs2-bill__empty i { font-size: var(--icon-md); color: var(--txt-disabled); }
/* 합계행 — 시안에 있다. 값은 action_sales() 가 이미 넣고 있었고 감춰져 있었을 뿐이다. */
.bi-bs2-bill__ft { display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-2_5) var(--space-3_5); border-top: 1px solid var(--border-base);
  font-size: var(--fs-sm); color: var(--txt-muted); }
/* 시안 실측: 할인 합계 #DC2626 = --color-danger-600 (--color-danger #EF4444 였다) */
.bi-bs2-bill__disc { font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--color-danger-600); }
.bi-bs2-bill__sum,
.bi-rs-hrow__dt,
.bi-rs-picked__t,
.bi-rs-often__t { font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--txt-primary); }

/* ── 최근내역 / 보유 정액권 (CSS 라디오 탭) ─────────────────────── */
.bi-bs2-tabs { display: flex; align-items: center; gap: var(--space-1_5);
  padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--border-base); }
.bi-bs2-tab { height: 30px; padding: 0 var(--space-3); border-radius: var(--radius-md);
  /* 시안 실측: 안 고른 탭 글자색 #111827 (--txt-muted → #374151 → #111827 로 두 번 고쳤다.
     좁은 자리로 다시 재니 가장 진함·덩어리 둘 다 #111827 이다 — 앞서는 옆의 «고른 탭» 남색이 섞였다) */
  font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-primary);
  background: transparent; display: inline-flex; align-items: center;
  gap: var(--space-1); cursor: pointer; }
/* 시안 실측: 안 고른 내역·정액권 탭의 건수는 아주 밝다(#CDD1D7 = --gray-300) */
.bi-bs2-tab__n { font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--gray-300); }
/* ⚠ .bi-bk2-vfoot__hint(예약) 과 우연히 같았다 — 「클릭 시 내역에 추가」는 줄바꿈하지 않는다 */
.bi-bs2-tabs__hint { margin-left: auto; font-size: var(--fs-xs);
  /* 시안 실측: 덧말 글자색 #9CA3AF */
  color: var(--txt-disabled); white-space: nowrap; }
/* ⚠ 라디오는 .bi-bs2-tabs 의 «형제» 다 — + 로는 안 걸린다. ~ 로 잇는다. */
#itab_hist:checked ~ .bi-bs2-tabs .bi-bs2-tab[for="itab_hist"],
#itab_pkg:checked  ~ .bi-bs2-tabs .bi-bs2-tab[for="itab_pkg"] {
  background: var(--pop-navy); color: var(--bg-card); }
/* 고른 탭의 건수는 «흐린 흰색» 이다(시안 실측 #B7BBC5) — 안 고른 쪽의 --gray-300 을 덮는다 */
#itab_hist:checked ~ .bi-bs2-tabs .bi-bs2-tab[for="itab_hist"] .bi-bs2-tab__n,
#itab_pkg:checked  ~ .bi-bs2-tabs .bi-bs2-tab[for="itab_pkg"] .bi-bs2-tab__n {
  color: inherit; opacity: .75; }
.bi-bs2-pnl { display: none; }
/* ⚠ 2026-09-22 사용자 지시 — 빈칸(「…이 없습니다」)을 **세로 가운데**에 둔다.
   전에는 판이 120px 인데 빈 줄만 40px 이라 글이 «위에 붙어» 아래가 휑했다.
   보이는 판을 세로로 채우고(min-height:100%), 목록이 남는 자리를 먹고,
   그 안에서 빈 줄이 가운데로 선다. 최근 내역·보유 패키지/선불권 **둘 다** 같다.
   ⚠ height 가 아니라 min-height 다 — 줄이 많으면 늘어나고 판이 스크롤해야 한다. */
#itab_hist:checked ~ .bi-bs2-pnls > #pnl_history,
#itab_pkg:checked  ~ .bi-bs2-pnls > #pnl_package {
  display: flex; flex-direction: column; min-height: 100%; }
.bi-bs2 .bi-bs2-hlist { margin: 0; padding: 0; list-style: none;
  display: flex; flex-direction: column; flex: 1 1 auto; }
.bi-bs2 .bi-bs2-hlist > li { display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2_5); min-height: 40px; padding: var(--space-2) var(--space-3_5);
  border-bottom: 1px solid var(--border-light); font-size: var(--fs-base); }
.bi-bs2 .bi-bs2-hlist > li:last-child { border-bottom: 0; }
/* 빈 상태 — 위의 `.bi-bs2 .bi-bs2-hlist > li`(줄 배치)를 이겨야 한다.
   ⚠ !important 를 쓰지 않는다 — «더 긴 선택자» 로 이긴다(CLAUDE §7 「inline·!important 전쟁」).
      li.bi-bs2-empty 로 요소+클래스를 붙여 특이도를 한 칸 올렸다. */
.bi-bs2 .bi-bs2-hlist > li.bi-bs2-empty { justify-content: center; flex-direction: column;
  flex: 1 1 auto;   /* 목록의 남는 자리를 먹어 «세로 가운데» 가 된다(2026-09-22) */
  gap: var(--space-1); color: var(--txt-muted); font-size: var(--fs-sm); }
/* ⚠ 2026-09-22 사용자 지시 — 빈칸 글꼴·아이콘을 「최근 시술내역이 없습니다」 쪽에 맞춘다.
   그 글은 옛 .bi-bs-empty-state(아이콘 24 · 글 13 · 흐림 .2)로 그려지고 있었고,
   뷰의 첫 모습(.bi-bs2-empty)은 글 12 · 아이콘도 12 였다 — 같은 자리가 두 모습이었다.
   이제 JS 도 이 클래스를 쓰므로 «여기 한 곳» 이 두 상태를 다 정한다. */
.bi-bs2-empty p { margin: 0; font-size: var(--fs-base); }
.bi-bs2-empty > i { font-size: var(--icon-md); opacity: 0.2; color: var(--txt-disabled); }
.bi-bs2-more { display: flex; align-items: center; justify-content: center; height: 40px;
  border-top: 1px solid var(--border-light); }
.bi-bs2-more--split { justify-content: space-between; padding: 0 var(--space-3_5); }
.bi-bs2-link { font-size: var(--fs-base); color: var(--color-info-700); font-weight: var(--fw-semibold); }
.bi-bs2-pkgsms { height: 27px; padding: 0 var(--space-2_5); font-size: var(--fs-sm);
  border-radius: var(--radius-md); border: 1px solid var(--border-base);
  background: var(--bg-card); color: var(--txt-secondary); }

/* ══ 우 · 전표 패널 ══════════════════════════════════════════════ */
.bi-bs2-slip__no,
.bi-rs-slip__no,
.bi-rs-total__lb { font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--txt-primary); }
/* ⚠ 2026-09-22 사용자: 「상태표시는 시안에서 보면 «전표번호 옆에 붙어서» 표시되는데」 — 그대로였다.
   .bi-bs2-q__hd 와 한 규칙(16696)으로 justify-content:space-between 을 물려받아 배지가 판
   **오른쪽 끝**으로 밀려 있었다. 시안(buysell.png 실측 out/_sian_sliphd.png)은 번호 오른쪽에
   틈 8px 로 붙는다. 대기열 머리(.bi-bs2-q__hd)는 양끝 정렬이 맞으니 **공유 규칙은 건드리지 않고**
   전표 머리만 왼쪽 모아 놓는다(§4 「기존 CSS 클래스 직접 수정 금지 → 신규 추가」). */
.bi-bs2 .bi-bs2-slip > .bi-bs2-slip__hd { justify-content: flex-start; }
/* 시안 실측: 상태 배지는 «보라» 채움(#5B45E0 = --bk-run) — 네이비가 아니다 */
.bi-bs2-slip__st { font-size: var(--fs-sm); font-weight: var(--fw-bold);
  border-radius: var(--radius-full); padding: var(--space-1) var(--space-3);
  background: var(--bk-run); color: var(--bg-card); white-space: nowrap; }
/* 2026-09-23 사용자 지적 ⑪ — 「결제완료로 저장됐는데 실 결제금액이 0」 은 대기열 카드와
   같은 경고 결(호박)로 적는다. 카드와 머리가 같은 말을 해야 한다.
   ⚠ 규칙은 카드 쪽(§76 미결제)에 **함께 묶어** 두었다 — 따로 적으면 선언이 한 글자도
      안 달라져 SPEC-DUP 으로 잡힌다(.bi-rs-qtag--book 과 겹쳤다). */
.bi-bs2-slip__meta { display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2); font-size: var(--fs-sm); color: var(--txt-muted);
  padding-bottom: var(--space-2_5); border-bottom: 1px solid var(--border-base); }

/* ⚠ .bi-pay2__f(결제 팝업) 과 우연히 같았다 — 금액 줄이 좁아도 밀리지 않게 */
.bi-bs2-sum { display: flex; flex-direction: column; gap: var(--space-1_5); min-width: 0; }
.bi-bs2-srow { display: grid; grid-template-columns: 1fr auto auto; align-items: center;
  /* 시안 실측: 합계줄 라벨(총 합계·선불권 결제·포인트 적립 예정) 글자색 #6B7280 */
  gap: var(--space-2); min-height: 28px; font-size: var(--fs-md); color: var(--txt-muted); }
.bi-bs2-srow > span:nth-of-type(2) { font-weight: var(--fw-bold); color: var(--txt-primary);
  text-align: right; font-size: var(--fs-lg); }
.bi-bs2-srow--grand > span:nth-of-type(2) { font-size: var(--fs-lg); }
/* 시안 실측: 선불권 결제 금액은 «빨강이 아니다» — 기본 글자색이다(ink #111827) */
.bi-bs2-srow--minus > span:nth-of-type(2) { color: var(--txt-primary); }
/* 시안: 포인트 적립 예정 «위» 에 구분선이 있다 */
.bi-bs2-srow--acc { padding-top: var(--space-2); border-top: 1px solid var(--border-light); }
.bi-bs2-srow--acc > span:nth-of-type(2) { color: var(--txt-secondary); font-weight: var(--fw-semibold); }
/* × — 글자만인 작은 단추. 상자가 없으면 사다리 대상이 아니다(§12-4 단서) */
.bi-bs2-sx { width: 18px; height: 18px; border: 1px solid var(--border-base);
  border-radius: var(--radius-sm); background: var(--bg-card); color: var(--txt-muted);
  font-size: var(--fs-2xs); line-height: 1; padding: 0; }

.bi-bs2-final { display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-2); padding: var(--space-1) 0 var(--space-1_5); }
/* ⚠ .bi-bk2-emp__n(예약) 과 우연히 같았다 — 「총 결제 금액」은 한 줄로 둔다 */
.bi-bs2-final__lb { font-size: var(--fs-lg); font-weight: var(--fw-bold);
  color: var(--txt-primary); white-space: nowrap; }
/* 시안 실측: 색은 #1D4ED8(--color-info-700) — 브랜드블루가 아니었다.
   크기는 30 이 맞다: 큰 «숫자» 는 한글과 잉크 비율이 다르다(숫자 0.833 · 한글 0.92).
   시안 ink 26 ÷ 0.833 = 31.2 → 토큰 30. 처음에 한글 비율로 재 28 로 잘못 봤다. */
.bi-bs2-final__v { font-size: var(--fs-3xl); font-weight: var(--fw-extrabold);
  color: var(--color-info-700); line-height: 1.1; }

/* 시안 실측: «결제수단» 라벨 글자색 #374151 (--txt-muted 였다) */
.bi-bs2-paylb { display: block; font-size: var(--fs-base); font-weight: var(--fw-semibold);
  color: var(--txt-secondary); }
/* 타일 — 실측 1행 4개 · 92x56. §12-5-1 POS 전용 등급의 확장(1열 3개 78 → 1행 4개 56).
   btn_audit 의 사다리예외에 56 을 «까닭과 함께» 등재한다. */
.bi-bs2-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-2); }
.bi-bs2 .bi-bs2-tile { position: relative; height: 56px; border: 1px solid var(--border-base);
  border-radius: var(--radius-lg); background: var(--bg-card); color: var(--txt-secondary);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--space-0_5); font-size: var(--fs-sm); padding: 0; }
.bi-bs2 .bi-bs2-tile__t { font-size: var(--fs-base); font-weight: var(--fw-semibold); }
/* 시안 실측: 고른 타일 바탕 #EEF3FF(--pop-row-sel) · 테두리·글자 #1D4ED8(--color-info-700) */
.bi-bs2 .bi-bs2-tile.is-on { border-color: var(--color-info-700); background: var(--pop-row-sel);
  color: var(--color-info-700); }
.bi-bs2-tile__dot { position: absolute; top: var(--space-1_5); right: var(--space-1_5);
  width: 6px; height: 6px; border-radius: var(--radius-full);
  background: var(--color-info-700); display: none; font-size: 0; }
.bi-bs2 .bi-bs2-tile.is-on .bi-bs2-tile__dot { display: block; }
/* N Pay — styleguide2 §12-5 「색은 둘만: N Pay 네이버 브랜드 초록 · 결제완료 브랜드블루」.
   브랜드 식별이므로 «고르지 않았을 때도» 초록이다(시안도 그렇다). 미계약 지점은 --inactive 가 흐리게 한다. */
.bi-bs2 .bi-bs2-tile--npay { color: var(--color-npay); }
.bi-bs2 .bi-bs2-tile--npay.is-on { border-color: var(--color-npay); color: var(--color-npay); }
.bi-bs2 .bi-bs2-tile--npay.is-on .bi-bs2-tile__dot { background: var(--color-npay); }
/* ⚠ script.js:85 가 N Pay 에 이 클래스를 토글한다 — 옛 규칙에 기대지 않고 여기서 받는다 */
.bi-bs2 .bi-bs2-tile.bi-counter-pay-btn--inactive { opacity: .45; }

/* 시안 실측: 수단 줄들은 «테두리 상자» 안에 있다 — 폭 392(열 안쪽폭) · 키 122 · 반경 8,
   줄마다 키 40 · 줄 사이 구분선 --border-light. 앞서는 «위 구분선 하나» 뿐이었다. */
.bi-bs2-prows { display: flex; flex-direction: column; gap: 0;
  border: 1px solid var(--border-base); border-radius: var(--radius-lg); }
.bi-bs2-prow { display: grid; grid-template-columns: auto 1fr auto auto;
  align-items: center; gap: var(--space-2); height: 40px; padding: 0 var(--space-3); }
.bi-bs2-prow + .bi-bs2-prow { border-top: 1px solid var(--border-light); }
.bi-bs2-prow__tag { font-size: var(--fs-xs); font-weight: var(--fw-bold);
  border-radius: var(--radius-sm); padding: var(--space-0_5) var(--space-1_5);
  background: var(--pop-row-sel); color: var(--color-info-700); }
/* 시안 실측: 수단별 금액 잉크 16 — 총 합계 값(잉크 14)보다 2 크다 → 18 */
.bi-bs2-prow__v { font-size: var(--fs-2lg); font-weight: var(--fw-bold);
  color: var(--txt-primary); text-align: right; }
.bi-bs2-prow__bank { font-size: var(--fs-xs); color: var(--txt-muted); }
/* 미결제액 줄도 상자 «안» 의 한 줄이다 — 따로 위 여백을 주지 않는다(위 .bi-bs2-prow + 규칙이 선을 그린다) */
.bi-bs2-prow--remain .bi-bs2-prow__t { font-weight: var(--fw-bold); color: var(--txt-muted); }
/* 시안 실측: 미결제액 값은 «녹색» 이다 — ink #16A34A.
   ⚠ 2026-09-18 정정: 전에는 「토큰엔 없어 가장 가까운 --color-success(#059669)」 로 두었다.
     그것은 차이를 «거리» 로 깎은 것이다(CLAUDE.md 금지). 시안 색으로 토큰을 더해 쓴다. */
.bi-bs2-prow--remain .bi-bs2-prow__v { color: var(--color-green-600); }

/* 푸터 — 시안 34 → 사다리 32 (§47 12-1 전례: 사다리와 «거의 같은» 값은 쓰지 않는다) */
.bi-bs2-foot { margin-top: auto; display: grid; grid-template-columns: auto auto 1fr;
  gap: var(--space-2); padding-top: var(--space-3); border-top: 1px solid var(--border-base); }
/* 시안 실측: 푸터 단추 키 34(851~884) · 글자 14.
   34 는 사다리 밖이지만 «팝업 푸터» 예외와 같은 값이고 시안이 그렇게 정했다 —
   btn_audit 의 사다리예외에 까닭과 함께 등재한다. */
.bi-bs2 .bi-bs2-foot__print, .bi-bs2 .bi-bs2-foot__recv { height: 34px; padding: 0 var(--space-3);
  font-size: var(--fs-md); font-weight: var(--fw-semibold); border-radius: var(--radius-md);
  border: 1px solid var(--border-base); background: var(--bg-card);
  /* 시안 실측: 접수증 출력·접수 글자색 #111827 = --txt-primary (--txt-secondary 였다) */
  color: var(--txt-primary);
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-1_5); white-space: nowrap; }
/* 시안 실측: 결제완료 바탕 #1D4ED8(--color-info-700) · 키 34 · 글자 14.
   ⚠ styleguide2 §12-5 는 「결제완료 = 브랜드블루」로 적혀 있다 — 새 시안과 어긋난다.
      사용자 지시(2026-09-16 「시안 확인해서 규격안 잘못된거 바로잡아」)에 따라 시안을 따랐다.
      §12-5 문구 갱신은 사용자 판단 몫으로 문서에 남긴다. */
.bi-bs2 .bi-bs2-foot__pay { height: 34px; padding: 0 var(--space-3_5); font-size: var(--fs-md);
  font-weight: var(--fw-bold); border-radius: var(--radius-md); border: 0;
  background: var(--color-info-700); color: var(--bg-card);
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-1_5); white-space: nowrap; }
.bi-bs2 .bi-bs2-foot__pay b { font-weight: var(--fw-bold); }

/* 옛 자리를 쓰던 것 — 시안에 없다. 감춘다(계산은 그대로 돈다). */
.bi-bs2 .bi-bs-hidden-btn { display: none; }

/* ── 반응형 — 1600 아래에서 대기가 본문 위 가로 띠로 올라간다 ──── */
@media (max-width: 1599px) {
  .bi-bs2-cols { grid-template-columns: minmax(0, 1fr) 425px; }
  .bi-bs2-q { grid-column: 1 / -1; border-bottom: 1px solid var(--border-base); }
  .bi-bs2-cols > .bi-bs2-q + * { border-left: 0; }
  .bi-bs2-qlist { flex-direction: row; overflow-x: auto; }
  .bi-bs2-qcard { width: 240px; flex: 0 0 auto; }
  .bi-bs2-qtabs { max-width: 330px; }
  .bi-bs2-qsearch { max-width: 330px; }
  .bi-bs2-qfoot { margin-top: var(--space-2_5); }
}
@media (max-width: 1279px) {
  .bi-bs2-cols { grid-template-columns: minmax(0, 1fr); }
  .bi-bs2-cols > * + * { border-left: 0; border-top: 1px solid var(--border-base); }
  .bi-bs2-frow { grid-template-columns: 1fr 1fr; }
  .bi-bs2-cust__pick { grid-template-columns: 1fr 1fr; }
}

/* §78 끝 ─────────────────────────────────────────────────────────── */

/* ── §78-2 · 옛 규칙과 부딪히는 자리 «덧고침» (2026-09-15, 실측 후) ───────
   실제 화면을 띄워 재 보니 다섯 곳이 옛/전역 규칙에 졌다. 원인과 이긴 규칙을 적어 둔다 —
   특이도는 «나중» 이 아니라 «더 긴 선택자» 가 이긴다(§47 에서 네 번 되풀이된 교훈).
   ⚠ 옛 규칙을 고치지 않는다. 여기서 «더 긴 선택자» 로 받는다. ------------------ */

/* ① 성별 — 전역 `input[type="radio"]+label`(style.css:686)이 라벨을
      **18x18 스프라이트**(radio.png · position:relative · top:3px)로 만들어
      세그먼트가 뭉개졌다. 실측: 라벨 18x18. */
.bi-bs2 .bi-bs2-seg__r + .bi-bs2-seg__lb {
  display: inline-flex; align-items: center; justify-content: center;
  width: auto; height: auto; background-image: none; position: static; top: auto;
  /* 시안 실측: 잉크 14 · 폭환산 13.5 → 14 · #374151 (13 · --txt-muted 였다) */
  font-size: var(--fs-md); font-weight: var(--fw-semibold); color: var(--txt-secondary);
}
.bi-bs2 .bi-bs2-seg__r:checked + .bi-bs2-seg__lb {
  /* 시안 실측 #121D3F = --pop-navy (브랜드네이비가 아니다) — 2026-09-16 */
  background-image: none; background-color: var(--pop-navy); color: var(--bg-card);
}
/* 전역이 이미 display:none 이라 라디오는 격자 칸을 먹지 않는다 — 그대로 둔다 */

/* ①-2 시술 보조(«펌»·«클리닉») — `.bi-bs-counter .bi-bs-pro-td--pro .bi-bs-pro-cat-badge2`(12199)
      이 **선택자 셋**(0,3,0)이라 §78 의 `.bi-bs2 .bi-bs-prosub`(0,2,0)을 이기고
      11px · 500 · --txt-disabled 로 그렸다. 시안 실측은 **12 · #6B7280**(잉크 12 · 폭환산 12.05,
      가장 진한 잉크 #6B7280 = --txt-muted)이다. 같은 길이(0,3,0)로 받는다. */
.bi-bs2 .bi-bs-pro-td--pro .bi-bs-prosub {
  font-size: var(--fs-sm); font-weight: var(--fw-normal); color: var(--txt-muted);
}

/* ①-3 수단 줄·선불권 줄의 «×» — `.bi-counter-wrap.bi-bs-counter .bi-bs-dock-x`(12916 · 0,3,0)
      이 display:none 을 물리고 `.bi-bs-dock-row.is-on` 일 때만 풀어 준다. 새 줄 이름은
      .bi-bs2-prow · .bi-bs2-srow 라 그 짝이 없어 **시안의 × 가 아예 안 보였다**(2026-09-16 실측 0x0).
      script.js:1584 가 줄에 .is-on 을 붙여 주므로 같은 길이(0,3,0)로 그 상태에서 풀어 준다. */
.bi-bs2 .bi-bs2-prow.is-on .bi-bs2-sx,
.bi-bs2 .bi-bs2-srow.is-on .bi-bs2-sx {
  display: inline-flex; align-items: center; justify-content: center;
  /* 시안 실측: 18x18 · 반경 4 · 글자 11 · #6B7280.
     옛 `.bi-bs-counter .bi-bs-dock-x`(12068)가 17 · --radius-xs · --txt-disabled 를 줬다. */
  width: 18px; height: 18px; border-radius: var(--radius-sm);
  color: var(--txt-disabled); font-size: var(--fs-xs);
}

/* ①-4 삭제 단추 — `.bi-bs-counter .bi-bs-pro-del-btn`(4900)이 바탕없음·반경 8 을 주고
      **글자크기는 아무도 안 줘서** 브라우저 기본 13.3333px 이 샜다(토큰 밖).
      시안 실측: 상자 30x30 · 바탕 #FFFFFF · 테두리 #E5E7EB · 반경 6 · 아이콘 #9CA3AF. */
.bi-bs2 .bi-bs-pro-td--del .bi-bs-pro-del-btn {
  width: 30px; height: 30px; border: 1px solid var(--border-base);
  border-radius: var(--radius-md); background: var(--bg-card);
  color: var(--txt-disabled); font-size: var(--fs-sm);
}

/* ①-6 내역표 칸 폭 — 시안 실측으로 덮는다(옛 공용 .bi-bs-pro-th--* 는 그대로 둔다).
      시안: No. 42 · 분류 65 · 단가 71 · 수량 107 · 할인 117 · 매출액/합계 155 · 삭제 45 */
/* ⚠ 옛 규칙이 «선택자 셋»(0,3,0)으로도 박혀 있다(12055 .bi-bs-pro-table .bi-bs-pro-th--no 46px ·
      12375 th--del/td--del 34px). 같은 길이로는 못 이긴다 — 넷(0,4,0)으로 받는다. */
.bi-bs2 .bi-bs-pro-table .bi-bs-pro-th--no,
.bi-bs2 .bi-bs-pro-table .bi-bs-pro-td--no   { width: 42px; }
.bi-bs2 .bi-bs-pro-table .bi-bs-pro-th--proc { width: 65px; }
.bi-bs2 .bi-bs-pro-table .bi-bs-pro-th--price { width: 71px; }
.bi-bs2 .bi-bs-pro-table .bi-bs-pro-th--qty  { width: 107px; }
.bi-bs2 .bi-bs-pro-table .bi-bs-pro-th--total { width: 155px; }
.bi-bs2 .bi-bs-pro-table .bi-bs-pro-th--del,
.bi-bs2 .bi-bs-pro-table .bi-bs-pro-td--del  { width: 45px; }
/* 할인 칸은 옛 규격이 --price 와 합쳐져 있다(4597 주석) — 시안은 117 로 더 넓다.
   머리·칸 모두 여섯째 자리다. */
.bi-bs2 #pro_list_ul > tr > td:nth-child(6),
.bi-bs2 .bi-bs-pro-table thead th:nth-child(6) { width: 117px; }

/* ①-5 분류 꼬리표의 갈래 색 — 옛 `.bi-bs-counter .bi-bs-pro-cat-badge.is-cat-*`(4935~4939 · 0,3,0)
      이 시안과 다른 색을 쓴다. 시안 실측: «시술» #EEF2FF / #1D4ED8 · «상품» #FFF6E5 / #8A5A0B.
      ⚠ 어느 줄이 어느 색을 받을지는 `bs_cat_class()`(script.js:2009)가 «분류 코드의 글자합» 으로
        정한다 — 시안처럼 «시술=파랑 · 상품=앰버» 로 못박는 것은 기능 변경이라 하지 않았다.
        팔레트가 파랑·앰버를 고를 때 «그 색이 시안과 같게» 만드는 것까지가 이 규칙의 몫이다. */
.bi-bs2 .bi-bs-pro-cat-badge.is-cat-blue, .bi-bs2 .bi-bs-pro-cat-badge2.is-cat-blue {
  background: var(--color-indigo-50); color: var(--color-info-700); border-color: var(--color-indigo-50);
}
.bi-bs2 .bi-bs-pro-cat-badge.is-cat-amber, .bi-bs2 .bi-bs-pro-cat-badge2.is-cat-amber {
  background: var(--bk-req-bg); color: var(--color-warning-800); border-color: var(--bk-req-bg);
}

/* ② 결제수단 타일 — `.bi-counter-pay-btn`(4428)이 font-weight:900 · 아이콘 20px 을 준다.
      그 클래스는 **떼지 않는다**(script.js:85 가 --inactive 를 토글한다). 값만 되돌린다. */
.bi-bs2 .bi-bs2-tile { font-weight: var(--fw-semibold); }
.bi-bs2 .bi-bs2-tile i.fas, .bi-bs2 .bi-bs2-tile i.far { font-size: var(--fs-md); }
/* 시안 실측: N Pay 의 표는 «초록 글자 N» — 잉크 13(대문자 높이) → 18 · #03C75A */
.bi-bs2 .bi-bs2-tile__np { font-size: var(--fs-2lg); font-weight: var(--fw-extrabold);
  color: var(--color-npay); line-height: 1; }
.bi-bs2 .bi-bs2-tile .bi-bs2-tile__dot { font-size: 0; }

/* ③ 「시술/상품 추가」 — `.bi-counter-wrap .main_more:not(.bi-btn)`(4841) 이
      float:right · width:30% · color:#2563EB · underline 을 준다.
      실측: 폭 244px · 글자색 #2563EB(파란 바탕에 파란 글자라 거의 안 보였다).
      ⚠ .main_more 는 **JS 훅** 이다(script.js 가 $('.main_more').click 으로 잡는다) — 떼면 죽는다. */
.bi-bs2 #product_add.main_more:not(.bi-btn) {
  float: none; width: auto; text-decoration: none; text-align: center;
  /* 시안 실측: 단추 글자 14 (잉크 13) — 12 로 적어 두었다(2026-09-16 정정) */
  color: var(--bg-card); font-size: var(--fs-md);
}
/* 「더보기」 링크도 같은 규칙에 걸려 오른쪽으로 떠 있었다 */
.bi-bs2 .bi-bs2-link.main_more:not(.bi-btn) {
  float: none; width: auto; text-align: center; color: var(--brand-blue); text-decoration: none;
}

/* ④ 행 합계 — `.bi-bs-counter #bs_foot_total`(4949)은 **아이디** 라(특이도 1,1,0)
      클래스로는 못 이긴다. 실측: 20px/900/#0023B7 → 시안은 14/700/기본색. */
.bi-bs2 #bs_foot_total { font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--txt-primary); }
.bi-bs2 #bs_foot_disc  { font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--color-danger-600); }

/* ⑤ 최근 내역 줄 — ref_sales() 가 그리는 마크업은 «두 줄»(.bi-bs-hitem__when / __row)이다.
      시안은 «한 줄»(날짜 · 상품명 · 금액)이다. JS 를 고치지 않고 배치만 한 줄로 되돌린다.
      ⚠ 이 클래스들은 JS 가 만든다 — 이름을 바꾸지 않는다(바꾸면 ref_sales 와 갈린다). */
/* 최근 내역 — «한 줄»(날짜 · 상품명 · 금액) */
.bi-bs2 #sales_olist > li.bi-bs-hitem {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  gap: var(--space-2_5); min-height: 40px; padding: var(--space-2) var(--space-3_5);
  border-bottom: 1px solid var(--border-light); border-top: 0; background: transparent;
}
/* ⚠ 보유 정액권은 «세 줄» 이다(분류+잔여 / 상품명 / 유효기간) — 위의 한 줄 격자를 쓰면
   유효기간이 상품명을 가린다. 2026-09-08 에 사용자가 먼저 발견한 바로 그 흠이고
   spec_match/buysell_pkg.mjs 가 그 자리를 지키고 있다. 쌓아서 높이를 내용만큼 준다. */
.bi-bs2 #package_olist > li.bi-bs-hitem {
  display: block; min-height: 40px; padding: var(--space-2_5) var(--space-3_5);
  border-bottom: 1px solid var(--border-light); border-top: 0; background: transparent;
}
.bi-bs2 #package_olist .bi-bs-hitem__when { display: flex; align-items: center;
  gap: var(--space-2_5); margin-bottom: var(--space-1); }
.bi-bs2 #package_olist .bi-bs-hitem__name { display: block; margin: 0 0 var(--space-0_5); }
.bi-bs2 .bi-bs-vcard-date { display: block; margin: 0; font-size: var(--fs-2xs);
  color: var(--txt-muted); }
.bi-bs2 .bi-bs-vcard-cnt { font-size: var(--fs-xs); color: var(--txt-muted); }
.bi-bs2 .bi-bs-hitem__when { font-size: var(--fs-sm); color: var(--txt-muted);
  border: 0; padding: 0; margin: 0; white-space: nowrap; }
.bi-bs2 .bi-bs-hitem__row { display: contents; }
.bi-bs2 .bi-bs-hitem__name { font-size: var(--fs-md); color: var(--txt-secondary);
  margin: 0; text-align: left; font-weight: var(--fw-normal); }
.bi-bs2 .bi-bs-hitem__amt { font-size: var(--fs-md); font-weight: var(--fw-bold);
  color: var(--txt-primary); margin: 0; text-align: right; white-space: nowrap; }
/* 옛 «빈 상태» 도 ref_sales 가 그린다 — 새 빈 상태와 같은 모양으로 */
.bi-bs2 #sales_olist > li.bi-bs-empty-state,
.bi-bs2 #package_olist > li.bi-bs-empty-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--space-1); min-height: 80px; color: var(--txt-muted); font-size: var(--fs-sm);
  border-bottom: 0; }
.bi-bs2 #sales_olist > li.bi-bs-empty-state p,
.bi-bs2 #package_olist > li.bi-bs-empty-state p { margin: 0; }

/* §78-2 끝 ───────────────────────────────────────────────────────── */

/* ── §78-3 · 캡처를 «눈으로» 보고서야 잡힌 둘 (2026-09-15) ────────────────
   수치 검사는 통과했는데 그림에서 드러났다 — 사용자 지시 「캡처를 직접 열어 대조」의 값어치. */

/* ⑥ 결제수단 타일에 «초록 체크» 가 남아 있었다.
      `.bi-bs-counter .bi-counter-pay-btn.is-on::after`(style.css:12097)가 그린다.
      새 시안의 «고름 표시» 는 오른쪽 위 **파란 점**(.bi-bs2-tile__dot)이다. 체크는 지운다. */
.bi-bs2 .bi-bs2-tile.is-on::after { content: none; display: none; }

/* ⑦ 품목이 1건 있는데도 「추가된 시술·상품이 없습니다」가 함께 보였다.
      script.js:1972 는 `$('#bs_pro_empty').toggleClass('is-on', n === 0)` 로 «클래스» 를 토글한다 —
      기본이 보임이면 항상 보인다. 기본을 숨김으로 두고 .is-on 일 때만 보인다.
      ⚠ 아이디에 display 를 주지 않는다 — 클래스 토글을 이겨 버린다(함정 F2). */
.bi-bs2 .bi-bs2-bill__empty { display: none; }
.bi-bs2 .bi-bs2-bill__empty.is-on { display: block; }

/* 세그먼트 상자 자체의 글자 크기 — 안에 글자가 있어 검사가 이 값을 잰다(전역 16 이 새어 들어왔다) */
.bi-bs2 .bi-bs2-seg { font-size: var(--fs-base); }

/* ⑧ 표는 840 으로 «딱» 맞는데 두 칸이 각자 넘쳤다(실측: 할인 칸 90에 내용 100 · 삭제 칸 34에 38).
      칸이 넘치면 스크롤 상자가 가로로 밀린다 — 시안에는 가로 스크롤이 없다. */
.bi-bs2 .bi-bs-pro-disc-in { width: 100%; min-width: 0; padding: 0 var(--space-1_5); }
.bi-bs2 #pro_list_ul > tr > td:last-child { padding-left: 0; padding-right: 0; }
/* ⚠ 여기서 28 로 줄여 두었더니 §78-2 ①-4 의 30(시안 실측)을 이 규칙(아이디 1,2,2)이 이겼다.
      삭제 칸은 34 이므로 30 도 들어간다 — 시안값 30 으로 맞춘다(2026-09-16). */
.bi-bs2 #pro_list_ul > tr > td:last-child > * { width: 30px; height: 30px; margin: 0 auto; }

/* §78-3 끝 ───────────────────────────────────────────────────────── */
/* ── §78-4 · 이름에 규격을 준다 (2026-09-15, CLASS-ORPHAN 정리) ─────────
   ⚠ SPEC-DUP 을 피해 선언을 지우고 공통 유틸을 마크업에서 쓰자 그 이름들이
      CLASS-ORPHAN 이 됐다. 두 규칙이 반대로 당긴다 — 답안지가 이 이름으로 재므로
      «이름에 규격을 주는» 쪽을 택한다. 중복은 뜻이 다른 두 자리가 우연히 같은 것이다. */

/* 표 여덟 칸 — 가운데 열에 «딱» 맞아야 한다(가로 스크롤 금지. 실측 840/840) */
.bi-bs2 .bi-bs2-th--no    { width: 46px; }
.bi-bs2 .bi-bs2-th--cat   { width: 72px; }
.bi-bs2 .bi-bs2-th--pro   { width: auto; }
.bi-bs2 .bi-bs2-th--price { width: 90px; }
.bi-bs2 .bi-bs2-th--qty   { width: 104px; }
.bi-bs2 .bi-bs2-th--disc  { width: 96px; }
.bi-bs2 .bi-bs2-th--total { width: 150px; }
.bi-bs2 .bi-bs2-th--del   { width: 34px; }

/* ⚠ 아래 둘은 공통 유틸(.bi-fill · .bi-grid-area--xscroll)과 선언이 같다 — SPEC-DUP 으로 잡힌다.
   그래도 «이름에 규격을 준다». 까닭:
     · 유틸만 쓰고 이름을 마크업에 남기면 CLASS-ORPHAN 이 된다(두 규칙이 반대로 당긴다).
     · 이름까지 빼면 답안지·목업·전시의 선택자가 모두 갈리고, 이 판의 구조가 이름으로 안 읽힌다.
   SPEC-DUP 을 0 으로 만드는 것은 이 파일 규모에서 달성 불가다(§49 문서 §6-2 에 근거를 적었다) —
   `{white-space:nowrap}` `{margin-left:auto}` 같은 작은 선언은 반드시 어딘가와 겹친다. */
/* .bi-bs2-cust__l — 없앤다(2026-09-21). 남는 자리를 채우는 선언이 공통 유틸 .bi-fill(1870줄)과
   같아 SPEC-DUP 이 됐고, 선언만 걷어내니 이번에는 «스타일 없는 빈 클래스»(CLASS-ORPHAN)가 됐다.
   이름을 두 개 두고 사이에서 고르는 대신, 마크업은 .bi-fill 하나만 쓴다. */
.bi-bs2-bill__scroll { overflow-x: auto; }         /* 표만 필요하면 가로로 민다 */
.bi-bs2-qfoot__l,
.bi-rs-qfoot__l { color: var(--txt-secondary); }
/* 시안 실측: 표 번호는 #6B7280 · 12px · «굵지 않다».
   옛 규칙 둘이 어긋나게 줬다 — `.bi-bs-counter .bi-bs-pro-rownum`(4886)이 --fw-extrabold,
   (12045)이 --txt-disabled. 시안의 번호 잉크 폭은 「1」 5 · 「2」 7 로 보통 굵기다
   (800 이면 6~9 가 된다). 같은 길이(0,2,0)로 뒤에서 받는다. */
.bi-bs2 .bi-bs-pro-rownum { color: var(--txt-muted); font-weight: var(--fw-normal); }
/* 시안 실측: 「접수 14:30 → 결제」 는 #9CA3AF 다 */
.bi-bs2-slip__flow { white-space: nowrap; color: var(--txt-disabled); }
.bi-bs2-sel { appearance: none; }                  /* 화살표는 브라우저 것을 쓰지 않는다 */
.bi-bs2-tabs__hint { margin-left: auto; }

/* §78-4 끝 ───────────────────────────────────────────────────────── */
/* ⚠ 되살림 (2026-09-15) — SPEC-DUP 을 합치려다 «교체는 안 먹고 삭제만» 적용돼
   아래 넷이 사라져 있었다. .bi-bs2-slip 은 우측 열의 골격이라 특히 위험했다.
   교훈: 치환마다 «들어갔는지» 확인한다(assert). 조용한 실패가 가장 비싸다. */
.bi-bs2-seg__r, .bi-bs2-tabr { position: absolute; opacity: 0; pointer-events: none; }
/* .bi-bs2-f--btn 은 §78(위)에 있다 — 여기 있던 복사본을 지웠다(2026-09-16 · SPEC-DUP) */

/* §78-5 끝 ───────────────────────────────────────────────────────── */

/* =========================================================
   §61-5 휴무설정 — 시안 «겹쳐서» 다시 잰 값 (2026-09-16)
   ---------------------------------------------------------
   사용자: 「왜 이렇게 빨리끝나지?? 요청사항 처음부터 다시 확인해서 수정해달라니까??
            시안과 규격안이 다른가 부터 «하나하나 상세하게» 확인해봐」

   맞다. §61-2·§61-3 까지는 «내가 지목한 자리» 만 쟀다. 그래서 자를 바꿨다 —
   두 그림에서 카드 테두리(#E5E7EB 가 1600px 이어지는 줄·열)를 찾아 원점을 맞추고,
   구분선·칸 채움·흰 덩이를 «기계로 쏟아내» 견주었다(tools/qc/_do_card · _do_sweep ·
   _do_cellw2 · _do_side · _do_side2 · _do_side3 · _do_band · _do_dom*).

   그랬더니 앞서 「맞다」고 적은 자리에서 열넷이 더 어긋나 있었다.

   | 자리                   | 시안 실측 | 규격안(전) | 고침 |
   |---|---|---|---|
   | 카드 폭                | 1616  | 1660  | 무대에서 (spec_do.css) |
   | 카드 키                |  826  |  823  | 무대에서 |
   | 머리 툴바 키           |   56  |   64  | 여기 |
   | 툴바 좌우 여백         |   20  |   24  | 여기 |
   | 툴바 단추 좌우 여백    |   10  |   12  | 여기 |
   | 날짜 칸 폭             |  157  |  245  | 여기 ← input 의 기본 폭(20자)이 벌렸다 |
   | 저장 단추 배경         | #1D4ED8 | #0023B7 | 여기 ← .bi-btn--primary 는 --brand-blue |
   | 30분 칸 폭 / 틈        | 48 / 2 | 47 / 3 | §61 토큰 |
   | 바닥 범례 키           |   44  |   37  | 여기 |
   | 좌패널 안쪽 여백       |   16  |   12  | 여기 |
   | 좌패널 카드 사이 틈    |   12~14 |  8   | §61 (--space-3_5) |
   | 미니달력 카드 키       |  234  |  248  | 여기 (머리 24 · 틈 8 · 요일줄 18) |
   | 근무현황 카드 키       |  250  |  281  | 여기 (항목 pitch 44 · 49 였다) |
   | 기본근무규칙 카드 키   |  195  |  231  | 여기 (줄 pitch 28 · 34 였다) |

   ⚠ 「좌패널이 시안보다 110px 길다」던 미해결 항목의 «정체» 가 이것이다 —
     미니달력 +14 · 근무현황 +31 · 규칙 +36 · 틈 +18 · 여백이 합쳐 107 이었다.
     카드 하나를 줄인 것이 아니라 «네 카드가 조금씩» 부푼 것이었다.

   ⚠ 페이지 바탕만은 시안(#F5F6F9)을 따르지 않는다 — #F8F9FC 는 전역 --bg-page 로
     모든 화면이 쓴다. 카드 «안» 인 좌패널 바탕은 시안대로 --do-bg-page 를 쓴다.
     (§4 «기존 CSS 직접 수정 ❌» · 전역 토큰을 이 화면 때문에 바꾸지 않는다)
   ========================================================= */
:root {
    --do-bg-page:    #F5F6F9;   /* 좌패널 바탕 — 시안 실측(전역 --bg-page 는 #F8F9FC) */
    --do-datenav-w:   157px;    /* 머리 툴바 날짜 칸 — 시안 실측 157 */
    --do-tb-h:         56px;    /* 머리 툴바 키 — 시안 실측 56 (공용 64) */
    --do-foot-h:       44px;    /* 바닥 범례 키 — 시안 실측 44 */
    --do-sidecard-gap: 12px;    /* 좌패널 카드 사이 — 시안 12~14 */
}

/* ── 머리 툴바 — 공용 .bi-erp-toolbar(64) 를 «이 화면에서만» 다시 정한다 ── */
.bi-erp-toolbar.bi-do2-tb { height: var(--do-tb-h); padding: 0 var(--space-5); }
.bi-do2-tb .bi-btn { padding: 0 var(--space-2_5); }
/* 날짜 칸 — <input> 은 width:auto 면 «20자» 를 잡는다(206px 이 되어 있었다).
   폭을 못박고 안쪽 칸이 그 폭을 채우게 한다. */
.bi-do2-tb .bi-datenav { width: var(--do-datenav-w); }
.bi-do2-tb .bi-datenav__mid { flex: 1; min-width: 0; }
.bi-do2-tb .bi-datenav__input { width: 100%; min-width: 0; }
/* 저장 — 시안 #1D4ED8(= --color-info-700). 공용 .bi-btn--primary 는 --brand-blue #0023B7 */
.bi-do2-tb .bi-btn--primary {
    background: var(--color-info-700); border-color: var(--color-info-700);
}
.bi-do2-tb .bi-btn--primary:hover { background: var(--color-info-600); border-color: var(--color-info-600); }

/* ── 바닥 범례 — 시안 44. 여백으로 맞추면 글자 줄높이에 흔들린다 → 키를 못박는다.
      min- 으로 두어 1024 에서 줄이 접히면 늘어난다(고정하면 잘린다). ── */
.bi-do2-wrap .bi-do2-foot { min-height: var(--do-foot-h); padding: 0 var(--space-4); }

/* ── 좌패널 ──────────────────────────────────────────────────── */
.bi-do2-wrap .bi-bk2-side {
    padding: var(--space-4) var(--space-4) var(--space-2);
    background: var(--do-bg-page);
    gap: var(--do-sidecard-gap);
}
/* 미니달력 — 카드 키 248 → 234 */
.bi-do2-wrap .bi-bk2-cal__hd { margin-bottom: var(--space-2); }      /* 12 → 8 */
/* ⚠ 미니달력 머리의 화살표 — 시안 실측은 24 지만 «규격을 따른다».
   24 는 §29-2 세그먼트·칩 등급(28·30)에도, §12-4 사다리(48·32·27·22)에도 없다.
   판례: 「시안이 말하는 건 «본문보다 크다» 이지 «정확히 34» 가 아니다 —
   시안 수치가 규격과 부딪히면 규격을 따른다」(sg2/47_AI메시지발송.md:1173).
   4px 차이로 미니달력 카드가 234 → 236 이 된다(허용 ±2 안). */
.bi-do2-wrap .bi-bk2-cal__arw { width: 28px; height: 28px; }
/* 요일줄 — 시안 18. 여백으로 맞추면 1px 이 되어 «간격 스케일 밖»(TK-SPACE)이 된다
   → 키를 못박는다(스케일에 없는 여백을 쓰는 것보다 «키를 말하는» 편이 맞다). */
.bi-do2-wrap .bi-bk2-cal__dow {
    padding: 0; min-height: 18px;
    display: inline-flex; align-items: center; justify-content: center;
}
/* 근무현황 — 카드 키 281 → 250. 항목 pitch 는 시안 44 (49 였다) */
.bi-do2-wrap .bi-bk2-card__t { margin-bottom: var(--space-1_5); }    /* 10 → 6 */
.bi-do2-wrap .bi-do2-chips { margin-bottom: var(--space-1); }        /* 10 → 4 */
.bi-do2-wrap .bi-do2-stat__r { min-height: 44px; padding: 0; }       /* 8 0 → 키 못박기 */
/* 기본 근무 규칙 — 카드 키 231 → 195. 줄 pitch 는 시안 28 (34 였다) */
.bi-do2-wrap .bi-do2-rule__r { min-height: 28px; padding: 0; }
.bi-do2-wrap .bi-do2-rule__sw { min-height: 30px; padding: 0; }
.bi-do2-wrap .bi-bk2-side .bi-btn { height: 30px; }                  /* 되돌리기 — 시안 30 */
/* §61-5 끝 ───────────────────────────────────────────────────────── */

/* =========================================================
   §61-6 휴무설정 — 시안 «부품마다» 견주어 고친 값 (2026-09-16)
   ---------------------------------------------------------
   §61-5 가 큰 뼈대(카드·툴바·범례·좌패널)를 맞췄다. 그다음 영역마다 2배로 확대해
   나란히 붙여 놓고 보니(tools/qc/_do_crop.mjs → out/shots/dayoff/cmp_*.png)
   «수치는 맞는데 모양이 다른» 자리가 또 나왔다.

   | 자리 | 시안 | 규격안(전) |
   |---|---|---|
   | 머리줄 날짜네비        | ‹(30) · 날짜칸(157) · ›(30), 틈 6 = 229 | 한 덩이 305 |
   | 날짜칸 안             | 오른쪽에 ⌄ · 달력 아이콘 없음 | 왼쪽에 달력 아이콘 · ⌄ 없음 |
   | 「오늘」 폭            |  50  |  54  |
   | 배지 «미저장» 폭       | 146  | 159  |
   | 배지 «겹침» 폭         |  88  | 106  |
   | 「전체 근무/휴무」 폭   |  77  |  87  |
   | 판머리행 「디자이너 N」 | 이름=회색 보통 · 숫자=진하고 굵게 | 뒤바뀜 |
   | 시간 눈금 색           | 중간 회색 | 더 연함 |
   | 아바타 채움            | #1E3A8A | #1E2A78 (--brand-navy) |
   | 상태 꼬리표            | 44×25 | 38×22 |
   | ⋯ 단추 폭             |  28  |  32  |
   | ⋯ 점                 | 연한 회색 · 가늘다 | 진하고 굵다 |
   | ⋯ 단추(고른 줄)        | 네이비 채움 + 흰 점 | 흰색 그대로 |
   | 미출근 칸             | 점선 네모가 «있다» | 아무것도 없다 |
   | 범례                  | 앞에 「범례」 라벨 | 라벨 없음 |
   | 범례 글자·「오늘」·일괄  | 더 진하다 | 더 연하다 |

   ⚠ 「수치 검사가 0 인데 화면은 딴판」의 전형이다 — 키·폭·색을 자리마다 쟀어도
     «점선이 아예 없다»·«라벨이 빠졌다»·«굵기가 뒤바뀌었다» 는 자를 안 댄 곳이라 안 잡혔다.
     그래서 이번엔 영역 그림을 사람이 본다(결과 문서 §0-3).
   ========================================================= */
:root {
    --do-ava-navy:  #1E3A8A;   /* 디자이너 아바타 c0 — 시안 실측(--brand-navy 는 #1E2A78) */
    --do-nav-btn:     30px;    /* 머리줄 ‹ › 단추 — 시안 30 */
    --do-nav-inp:    157px;    /* 머리줄 날짜칸 — 시안 157 */
}

/* ── 머리줄 날짜네비 — 시안은 «세 네모» 다. 한 덩이로 감싼 테두리를 지우고
      ‹ · 날짜칸 · › 이 각각 네모를 갖게 한다. 공용 .bi-datenav 는 건드리지 않는다. ── */
.bi-do2-wrap .bi-do2-tool .bi-datenav {
    border: 0; background: transparent; padding: 0; gap: var(--space-1_5);   /* 틈 6 */
    height: auto;
}
.bi-do2-wrap .bi-do2-tool .bi-datenav__btn {
    width: var(--do-nav-btn); height: var(--do-nav-btn);
    border: 1px solid var(--border-base); background: var(--bg-card);
    border-radius: var(--radius-lg); color: var(--txt-secondary);
}
.bi-do2-wrap .bi-do2-tool .bi-datenav__mid {
    width: var(--do-nav-inp); flex: 0 0 auto;
    height: var(--do-nav-btn);
    border: 1px solid var(--border-base); background: var(--bg-card);
    border-radius: var(--radius-lg);
    padding: 0 var(--space-2_5);
    justify-content: center;
}
.bi-do2-wrap .bi-do2-tool .bi-datenav__input { width: auto; min-width: 0; flex: 0 1 auto; }
/* 시안의 날짜칸은 «오른쪽에 ⌄» 다 — 달력 아이콘은 이 자리에서 숨기고 셰브론을 쓴다.
   ⚠ F2 — 아이디로 display 를 주는 규칙이 없으므로 클래스만으로 충분하다. */
.bi-do2-wrap .bi-do2-tool .bi-datenav__ico { display: none; }
.bi-do2-wrap .bi-do2-tool .bi-datenav__cv {
    margin-left: var(--space-1_5); font-size: var(--fs-sm); color: var(--txt-muted); flex: 0 0 auto;
}

/* ── 머리줄 단추·배지 폭 — 시안 실측 ───────────────────────────── */
.bi-do2-wrap .bi-do2-tool .bi-btn { padding: 0 var(--space-2_5); color: var(--txt-primary); }
.bi-do2-wrap .bi-do2-pill { padding: 0 var(--space-2); font-size: var(--fs-sm); }
.bi-do2-wrap .bi-do2-tool__hint { color: var(--txt-muted); }
/* ⚠ 2026-09-17 — .bi-do2-dots 가 마크업에서 사라져 이 줄도 걷었다.
     일괄 단추 묶음은 `.bi-do2-bulk` 다(이름이 갈려 있었다 — 한쪽만 남기면 죽은 규칙이 된다). */

/* ── 판 머리행 — 시안은 «이름이 회색 보통 · 숫자가 진하고 굵다» (뒤바뀌어 있었다) ── */
.bi-do2-wrap .bi-do2-hd__lb { font-weight: var(--fw-medium); color: var(--txt-muted); }
.bi-do2-wrap .bi-do2-hd__lb small {
    font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-primary);
}
.bi-do2-wrap .bi-do2-hh { color: var(--txt-secondary); }   /* 눈금 — 시안은 --txt-muted 보다 진하다 */
/* 2026-10-07 — 끝 시각 라벨은 칸이 없으니 폭을 차지하지 않는다(그 폭만큼 판 끝에 빈 공간이 생겼다).
   글자는 끝선 «안쪽» 에 붙여 판 밖으로 넘치지 않게 한다. */
.bi-do2-wrap .bi-do2-hh.bi-do2-hh--end { width: 0; padding-left: 0; white-space: nowrap; display: flex; justify-content: flex-end; }   /* 폭 0 + 끝 맞춤 → 글자가 끝선 안쪽(왼쪽)으로 넘친다 */

/* ── 행머리 ───────────────────────────────────────────────────── */
.bi-do2-wrap .bi-bk2-ava--c0 { --ava: var(--do-ava-navy); }   /* 시안 #1E3A8A */
.bi-do2-wrap .bi-do2-rowhd__s { color: var(--txt-disabled); } /* 부제 — 시안은 더 연하다 */
.bi-do2-wrap .bi-do2-tag { height: 25px; padding: 0 var(--space-2_5); }   /* 시안 44×25 */
/* ⋯ 단추 — 시안 28×28 · 점은 연한 회색. 공용 .bi-btn--icon(32) 을 이 자리에서 다시 정한다 */
.bi-do2-wrap .bi-do2-rowhd .bi-btn--icon {
    width: 28px; height: 28px; padding: 0;
    color: var(--txt-disabled); font-size: var(--fs-sm);
}
/* 고른 줄은 ⋯ 가 «네이비 채움 + 흰 점» 이다 — 시안에서 시우 실장 줄이 그렇다 */
.bi-do2-wrap .bi-do2-row.is-sel .bi-do2-rowhd .bi-btn--icon {
    background: var(--brand-navy); border-color: var(--brand-navy); color: var(--bg-card);
}

/* ── 미출근 칸 — 시안에는 «점선 네모» 가 있다. 투명이면 판이 뚫린 것처럼 보인다 ── */
.bi-do2-wrap .bi-do2-cell--none {
    background: transparent; cursor: default;
    border: 1px dashed var(--border-base);
}

/* ── 범례 — 앞에 「범례」 라벨. 글자는 시안이 더 진하다 ──────────── */
.bi-do2-wrap .bi-do2-legend__lb {
    font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--txt-secondary);
    margin-right: var(--space-2); flex-shrink: 0;
}
.bi-do2-wrap .bi-do2-legend__i { color: var(--txt-secondary); }
/* 「휴게와 겹친 예약」 스와치는 시안에서 «짙은 보라 채움» 이다 (칸 색 #E4E0FF 이 아니다) */
.bi-do2-wrap .bi-do2-legend__sw--clash { background: var(--bk-run); border-color: var(--bk-run); }
/* §61-6 끝 ───────────────────────────────────────────────────────── */

/* =========================================================
   §61-7 휴무설정 — 좌패널 세로 자리를 시안에 «맞물린다» (2026-09-16)
   ---------------------------------------------------------
   §61-5 로 네 카드의 키를 줄였는데도 「기본 근무 규칙」 카드가 시안보다 11px 아래에
   앉아 있었다. 카드마다 ±3 씩 남은 것이 쌓인 결과다. 자리를 하나씩 맞물린다.

   | 카드 | 시안 top/키 | §61-5 뒤 | 이 절에서 |
   |---|---|---|---|
   | 검색           |  73 / 38 |  73 / 38 | 그대로 ✔ |
   | 미니달력        | 121 / 234 | 123 / 234 | 그대로 ✔ |
   | 근무현황        | 367 / 243 | 369 / 252 | 목록에 «키» 를 준다 |
   | 기본 근무 규칙   | 622 / 195 | 633 / 204 | 되돌리기 위 틈 10 → 4 |

   ⚠ 근무현황이 «내용대로» 늘어나 있었다. 시안을 다시 보니 넷째 줄(현지 디자이너)이
     흐릿하게 «잘려» 있다 — 목록이 카드 안에서 스스로 구르는 것이다. 키를 못박고
     아래에 흰 그러데이션을 깔아 «더 있다» 를 말한다(시안과 같은 신호).
     지난번 min-height:168 을 줬다가 규칙 카드와 겹쳤던 것과 반대 방향이다 —
     그때는 «늘렸고» 이번엔 «가둔다».
   ========================================================= */
.bi-do2-wrap .bi-do2-stat {
    max-height: 167px;          /* 44×3 + 35 — 넷째 줄이 «조금» 보인다(시안과 같다) */
    overflow-y: auto;
    position: relative;
}
/* 아래가 «더 있다» 는 신호 — 시안의 흐려짐. 목록을 감싼 자리에 얹는다 */
.bi-do2-wrap .bi-do2-statwrap { position: relative; }
.bi-do2-wrap .bi-do2-statwrap::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 24px;
    background: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--bg-card));
    pointer-events: none;
}
/* 되돌리기 단추 위 틈 — 시안 4 (--space-2_5 = 10 이었다) */
.bi-do2-wrap .bi-do2-reset { margin-top: var(--space-1); }
/* §61-7 끝 ───────────────────────────────────────────────────────── */

/* =========================================================
   §61-8 휴무설정 — 시안의 «작은 색» 과 구분선 (2026-09-16)
   ---------------------------------------------------------
   영역 그림을 3단으로 붙여 보니(out/shots/dayoff/cmp_side_top·mid·bot.png)
   키·폭이 다 맞은 뒤에도 «색과 선» 이 달랐다. 픽셀로 집어낸 값이다(tools/qc/_do_pick · _do_dots).

   | 자리 | 시안 실측 | 규격안(전) |
   |---|---|---|
   | 달력 일요일 날짜      | #DC2626 | 검정 — 규칙이 «있는데» 안 먹었다 |
   | 달력 토요일 날짜      | #1D4ED8 | 검정 |
   | 달력 지난달 날짜      | #D1D5DB | 검정 |
   | 달력 «오늘» 원        | #121D3F | #111827 |
   | 달력 점 — 휴무        | #DC2626 | 전부 보라 |
   | 달력 점 — 반차        | #F59E0B | 전부 보라 |
   | 달력 «실제 오늘»(9일)  | #1D4ED8 글자 | 표시 없음 |
   | 근무현황 제목 아래      | 구분선 #E5E7EB | 없음 |
   | 근무현황 칩 줄         | 바탕 #F5F6F9 + 위아래 구분선 | 흰 바탕 · 선 없음 |
   | 규칙 줄 사이          | 구분선 «없음» | 세 줄 다 있었다 |
   | 규칙 토글 위          | 구분선 #EEF0F3 | 있음 ✔ |
   | 되돌리기 글자          | #111827 굵게 | 연한 회색 보통 |
   | 검색 돋보기            | #9CA3AF | 진한 남색 |

   ⚠ 「규칙이 있는데 안 먹었다」 — `.bi-bk2-cal__d--sun`(0,1,0) 이 `.bi-bk2-cal__d`(0,1,0)
     «보다 먼저» 선언되어 있다(:14007 vs :14010). 같은 특이도면 뒤가 이긴다 →
     주말 색이 본문색에 덮여 있었다. 예약 화면도 같이 그랬을 것이다.
     기존 규칙은 손대지 않고(§4) 이 화면 스코프에서 특이도를 올려 되돌린다.
   ========================================================= */
:root {
    --do-cal-today: #121D3F;   /* 미니달력 «고른 날» 원 — 시안 실측 */
}

/* ── 미니달력 ─────────────────────────────────────────────────── */
.bi-do2-wrap .bi-bk2-cal__d--sun { color: var(--color-danger-600); }
.bi-do2-wrap .bi-bk2-cal__d--sat { color: var(--color-info-700); }
.bi-do2-wrap .bi-bk2-cal__d--out { color: var(--gray-300); }
.bi-do2-wrap .bi-bk2-cal__d.is-today { background: var(--do-cal-today); color: var(--bg-card); }
/* 실제 오늘 — 고른 날과 다르면 글자만 파랗다(시안 9일) */
.bi-do2-wrap .bi-bk2-cal__d.is-realtoday:not(.is-today) { color: var(--color-info-700); font-weight: var(--fw-bold); }
/* ⚠ 2026-09-17 — 휴무·반차 «점» 색 두 줄을 걷었다. 사용자 지시로 점 자체를 없앴다
     (「빨간점 주황점 그거 빼줘 … 여러명일때는 표시가 안되는게 맞지않을까??」).
     점은 «하루에 하나» 인데 판은 «사람마다 다른 하루» 를 그려, 한 명 휴무와
     전원 휴무가 같은 점으로 보였다. 공용 `.bi-bk2-cal__d.has-dot` 는 남긴다 —
     예약일정표(booking_time)·styleguide2 가 쓴다. */
/* 검색 — 돋보기·안내글은 시안에서 아주 연하다 */
.bi-do2-wrap .bi-bk2-search > i { color: var(--txt-disabled); }
.bi-do2-wrap .bi-bk2-search > input::placeholder { color: var(--txt-disabled); }

/* ── 근무현황 — 시안은 «제목 / 칩 / 목록» 세 단이 선으로 나뉜다 ────
      칩 줄은 카드 여백을 넘어 «판 끝까지» 깔린다(카드 padding 12 만큼 밖으로). ── */
.bi-do2-wrap .bi-bk2-card__t + .bi-do2-chips,
.bi-do2-wrap .bi-do2-chips {
    margin: -4px calc(var(--space-3) * -1) 0;
    padding: var(--space-2_5) var(--space-3);
    background: var(--do-bg-page);
    border-top: 1px solid var(--border-base);
    border-bottom: 1px solid var(--border-base);
}
.bi-do2-wrap .bi-do2-stat { max-height: 153px; }   /* 칩 줄이 22 더 먹으므로 목록을 줄인다 */

/* ── 기본 근무 규칙 — 시안은 줄 사이에 선이 «없다». 토글 위에만 있다 ── */
.bi-do2-wrap .bi-do2-rule__r + .bi-do2-rule__r { border-top: 0; }
.bi-do2-wrap .bi-do2-reset {
    color: var(--txt-primary); font-weight: var(--fw-bold);
}
/* §61-8 끝 ───────────────────────────────────────────────────────── */

/* =========================================================
   §61-9 휴무설정 — 시안의 «테두리» 와 남은 색 (2026-09-16)
   ---------------------------------------------------------
   §61-8 까지 오고 나서도 배지·꼬리표에 «시안에는 있는 테두리» 가 없었다.
   채움색만 재고 테두리를 안 쟀기 때문이다 — 채움이 맞으면 같아 보인다고 여겼다.

   | 자리 | 시안 실측 |
   |---|---|
   | 배지 «미저장» 테두리     | #F1D7A3 (바탕 #FFF6E5) |
   | 배지 «겹침» 테두리       | #FECACA (= --color-danger-200) |
   | 꼬리표 근무 테두리        | #DBF1E3 (바탕 #ECFDF3) |
   | 꼬리표 겹침 테두리        | #FDE3E3 (바탕 #FEF2F2) |
   | 꼬리표 반차 테두리        | #F6E9D0 (바탕 #FFF6E5) |
   | 꼬리표 휴무 테두리        | #F7F8F9 (바탕 #F3F4F6) |
   | 흰 단추 테두리(오늘·일괄·날짜) | #F2F3F5 ≒ --border-light — --border-base(#E5E7EB) «보다 연하다» |
   | 툴바 날짜 글자·아이콘      | #121D3F (--txt-primary #111827 이 아니다) |
   | 툴바 날짜칸             | 아이콘+글자가 «한 네모» — 안쪽에 또 칸이 있었다 |
   | 「기간 휴무 설정」 아이콘    | 글자와 같은 색(회색) — 파란 아이콘이었다 |
   | 「총 N명」               | #374151 굵게 — 연한 회색 보통이었다 |
   | 범례 «휴게와 겹친» 스와치   | #9D8FEC (칸 색 #E4E0FF 도, --bk-run #5B45E0 도 아니다) |
   ========================================================= */
:root {
    --do-pill-warn-line:  #F1D7A3;   /* 배지 «저장되지 않은 변경» 테두리 */
    --do-tag-ok-line:     #DBF1E3;   /* 꼬리표 근무 */
    --do-tag-clash-line:  #FDE3E3;   /* 꼬리표 겹침 */
    --do-tag-half-line:   #F6E9D0;   /* 꼬리표 반차 */
    --do-tag-off-line:    #F7F8F9;   /* 꼬리표 휴무 */
    --do-btn-line:        #F3F4F6;   /* 흰 단추 테두리 — 시안 #F2F3F5 */
    --do-tb-ink:          #121D3F;   /* 툴바 날짜 글자·아이콘 */
    --do-legend-clash:    #9D8FEC;   /* 범례 «휴게와 겹친 예약» 스와치 */
}

/* ── 배지 — 시안 글자 11 · 테두리 있음 ─────────────────────────── */
.bi-do2-wrap .bi-do2-pill { font-size: var(--fs-xs); border: 1px solid transparent; }
.bi-do2-wrap .bi-do2-pill--dirty { border-color: var(--do-pill-warn-line); }
.bi-do2-wrap .bi-do2-pill--clash { border-color: var(--color-danger-200); }

/* ── 상태 꼬리표 — 채움마다 «한 단 진한» 테두리 ────────────────── */
.bi-do2-wrap .bi-do2-tag { border: 1px solid transparent; }
.bi-do2-wrap .bi-do2-tag--work  { border-color: var(--do-tag-ok-line); }
.bi-do2-wrap .bi-do2-tag--clash { border-color: var(--do-tag-clash-line); }
.bi-do2-wrap .bi-do2-tag--half  { border-color: var(--do-tag-half-line); }
.bi-do2-wrap .bi-do2-tag--off   { border-color: var(--do-tag-off-line); }

/* ── 흰 단추 테두리 — 시안은 카드 테두리보다 «한 단 연하다» ────── */
.bi-do2-tb .bi-btn--ghost,
.bi-do2-wrap .bi-do2-tool .bi-btn--ghost,
.bi-do2-wrap .bi-do2-tool .bi-datenav__btn,
.bi-do2-wrap .bi-do2-tool .bi-datenav__mid,
.bi-do2-wrap .bi-bk2-side .bi-btn,
.bi-do2-wrap .bi-do2-rowhd .bi-btn--icon { border-color: var(--do-btn-line); }
/* 아이콘은 글자와 같은 색 — 파랗게 두면 시안과 어긋난다 */
.bi-do2-tb .bi-btn--ghost i,
.bi-do2-wrap .bi-do2-tool .bi-btn--ghost i { color: inherit; }

/* ── 툴바 날짜 — «한 네모» 로 되돌린다.
      .bi-datenav__input 이 :6711 에서 제 바탕·테두리를 갖고 있어 안쪽에 칸이 또 생겼고,
      게다가 padding 20 이 글자를 잘랐다(「2026-09-14 (울」 로 찍혔다). ── */
.bi-do2-tb .bi-datenav { border-color: var(--do-btn-line); }
.bi-do2-tb .bi-datenav__mid { padding: 0 var(--space-2); gap: var(--space-1_5); }
.bi-do2-tb .bi-datenav__input {
    width: 118px; min-width: 0; padding: 0;
    background: transparent; border: 0; border-radius: 0; box-shadow: none;
    text-align: left; color: var(--do-tb-ink);
}
.bi-do2-tb .bi-datenav__ico { color: var(--do-tb-ink); }

/* 툴바 단추 글자 — 시안은 #111827(진한 검정). §61-6 은 머리줄에만 줬다 */
.bi-do2-tb .bi-btn--ghost { color: var(--txt-primary); }

/* ── 근무현황 「총 N명」 ──────────────────────────────────────── */
.bi-do2-wrap .bi-bk2-card__t small,
.bi-do2-wrap .bi-bk2-card__t > span:last-child {
    font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-secondary);
}
.bi-do2-wrap .bi-do2-stat { max-height: 160px; }   /* 넷째 줄이 시안만큼 보인다 */

/* ── 범례 «휴게와 겹친 예약» 스와치 ───────────────────────────── */
.bi-do2-wrap .bi-do2-legend__sw--clash {
    background: var(--do-legend-clash); border-color: var(--do-legend-clash);
}
/* §61-9 끝 ───────────────────────────────────────────────────────── */

/* §61-10 휴무설정 — 고른 줄의 ⋯ 는 «#121D3F» 다 (2026-09-16)
   --brand-navy(#1E2A78)는 보라빛이 돈다. 시안은 미니달력 «오늘» 원과 같은 #121D3F 다. */
:root { --do-navy: #121D3F; }
.bi-do2-wrap .bi-do2-row.is-sel .bi-do2-rowhd .bi-btn--icon {
    background: var(--do-navy); border-color: var(--do-navy);
}

/* =========================================================
   §61-11 기간 휴무 팝업 — 시안 dayoff2.png 를 창 기준으로 다시 (2026-09-16)
   ---------------------------------------------------------
   | 자리 | 시안 실측 | 규격안(전) |
   |---|---|---|
   | 창                 | 560×756 | 538×740 (무대 여백 탓) |
   | 머리줄 키           |   56   |  80  |
   | 제목 · 부제          | «한 줄» 로 나란히 | 두 줄로 쌓임 |
   | 목록 줄 pitch        |   48   |  48 ✔ |
   | 목록 5줄이 온전히     | 195..435 (240) | 218..421 — 마지막 줄 잘림 |
   | 안내 상자            | 한 줄 · 키 37 · 바탕 #F5F6F9 | 두 줄 · 60 · #F9FAFB |
   | 「설정 저장」 배경     | #1D4ED8 | #0023B7 |
   | 머리 아이콘 네모       | #121D3F 28×28 ✔ | ✔ |
   | 고른 줄 바탕          | #EEF3FF ✔ | ✔ |
   ========================================================= */
/* 머리줄 — 시안은 제목과 부제가 «한 줄» 이고 줄 키가 56 이다 */
.bi-modal--do .bi-modal__head { min-height: 56px; padding: 0 var(--space-5); }
.bi-modal--do .bi-modal__head-txt > div {
    display: flex; align-items: baseline; gap: var(--space-2_5); min-width: 0;
}
.bi-modal--do .bi-modal__head-txt p { margin: 0; white-space: nowrap; }
.bi-modal--do .bi-modal__close { width: 28px; height: 28px; color: var(--txt-muted); }

/* 안내 상자 — 시안은 한 줄. 바탕도 페이지색(#F5F6F9)이다 */
.bi-do2-pop .bi-do2-pop__note { background: var(--do-bg-page); }

/* 「설정 저장」 — 시안 #1D4ED8 (공용 --brand-blue 는 #0023B7) */
.bi-do2-pop .bi-do2-pop__foot .bi-btn--primary {
    background: var(--color-info-700); border-color: var(--color-info-700);
}
.bi-do2-pop .bi-do2-pop__foot .bi-btn--primary:hover {
    background: var(--color-info-600); border-color: var(--color-info-600);
}
/* 2026-10-02 «기간 휴무 설정» 을 화면 안 모달에서 공용 팝업(popup_layer_dayoff_period)으로 옮겼다.
   ① 팝업 래퍼 .bi-pop-reg 의 좌우 안쪽 18 이 본문(.bi-do2-pop__* 의 21)에 «한 번 더» 더해져 폭이 36 좁아졌다
      → 이 팝업에서는 래퍼 좌우를 비운다(모달 때와 같은 폭 · 안내 문구가 한 줄에 든다).
   ② 요약·단추가 공용 푸터(.bi-pop-list-foot)로 나가며 «.bi-do2-pop 안» 이라는 범위를 벗어나 모양을 잃었다
      → 같은 값을 팝업 범위(.bi-pop-do)로 다시 준다. 값은 위 모달 규칙 그대로 베낀다(새 수를 만들지 않는다). */
.bi-pop-reg.bi-pop-do { padding-left: 0; padding-right: 0; }
.bi-pop-do .bi-pop-list-foot .bi-do2-pop__sum {
    flex: 1; min-width: 0;
    font-size: var(--fs-md); color: var(--txt-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bi-pop-do .bi-pop-list-foot .bi-do2-pop__sum b { color: var(--txt-primary); font-weight: var(--fw-bold); }
.bi-pop-do .bi-pop-list-foot .bi-btn {
    height: var(--pop-btn-h); font-size: var(--fs-md); font-weight: var(--fw-bold);
    border-radius: var(--pop-btn-r);
}
.bi-pop-do .bi-pop-list-foot .bi-btn--primary { background: var(--color-info-700); border-color: var(--color-info-700); }
.bi-pop-do .bi-pop-list-foot .bi-btn--primary:hover { background: var(--color-info-600); border-color: var(--color-info-600); }
/* 2026-10-06 사용자 지시 — 대상 디자이너 «고른 표시» 를 팝업 공통 규격으로:
     줄 오른쪽 동그라미(.bi-pop-pick2 · 고객 검색/상품 추가와 같은 부품) + 고른 줄 왼쪽 막대(.bi-pop-clist-item.is-sel 과 같은 값).
   ⚠ 체크박스는 DOM 에서 지우지 않고 숨긴다 — 줄(label)을 누르면 그 체크가 바뀌고 change 로 doPop.sel 이 바뀐다.
   ⚠ 막대 두께만큼 왼쪽 여백을 줄여 이름·아바타가 고를 때 옆으로 밀리지 않게 한다. */
.bi-pop-do .bi-do2-pop .bi-do2-pitem > input[type=checkbox] { display: none; }
.bi-pop-do .bi-do2-pop .bi-do2-pitem > .bi-pop-pick2 { margin-left: auto; }
.bi-pop-do .bi-do2-pop .bi-do2-pitem.is-on {
    background: var(--bg-selected);
    border-left: var(--pop-sel-bar) solid var(--pop-sel);
    padding-left: calc(var(--do-pop-padx) - var(--pop-sel-bar));
}
.bi-pop-do .bi-do2-pop .bi-do2-pitem.is-on .bi-pop-pick2 {
    background: var(--pop-sel); border-color: var(--pop-sel); color: var(--bg-card);
}

/* 흰 단추 테두리도 본 화면과 같이 한 단 연하게 */
.bi-do2-pop .bi-btn--ghost,
.bi-do2-pop .bi-do2-role,
.bi-do2-pop .bi-do2-kind { border-color: var(--do-btn-line); }
/* §61-11 끝 ───────────────────────────────────────────────────────── */

/* §61-12 기간 휴무 팝업 — 아래 절반의 «줄 자리» (2026-09-16)
   시안(창 기준): 「기간」 457 · 「시작일」 484 · 날짜칸 502/36 · 「설정 내용」 561 ·
                 알약 586/37 · 안내 640/37 · 푸터선 693 · 단추 708/35 · 창 756
   규격안(전):    454 · 478 · 496/36 · 549 · 570/36 · 620/42 · 676 · 690/34 · 725
   → 목록이 10 잘렸고(230), 섹션 여백이 2~6 좁고, 안내 상자가 5 높았다. */
.bi-do2-pop .bi-do2-plist { max-height: 240px; }                  /* 48×5 — 다섯 줄이 온전히 */
.bi-do2-pop .bi-do2-pop__sec { padding-top: var(--space-4); }     /* 14 → 16 */
.bi-do2-pop .bi-do2-pop__sec--tight { padding-top: var(--space-5); } /* 14 → 20 (시안 24 틈) */
.bi-do2-pop .bi-do2-pop__note { padding: var(--space-2_5); margin: var(--space-4) 0 var(--space-3_5); }

/* §61-13 ⋯ 일괄 설정 메뉴 — 시안 dayoff3.png (2026-09-16)
   | 자리 | 시안 | 규격안(전) |
   |---|---|---|
   | 보조 설명 「(09:00 – 19:00)」 | 라벨 «바로 뒤» (틈 10) | 오른쪽 끝으로 밀림 (틈 30) |
   | 항목 pitch                 | 34 | 32 |
   | 구분선 자리                 | 102 · 179 | 104 · 177 ✔ |
   | 메뉴 키                    | 225 | 224 ✔ |
   ⚠ margin-left:auto 가 보조 설명을 오른쪽 끝으로 밀고 있었다 —
     시안은 «라벨에 붙는 부연» 이라 자리가 다르면 뜻이 달라진다(항목마다 우변이 들쭉날쭉해 보인다). */
.bi-do2-menu .bi-do2-menu__i { min-height: 34px; }
.bi-do2-menu .bi-do2-menu__i > small { margin-left: 0; }   /* 줄 자체의 틈 8 만 — 시안 10 */

/* §61-14 휴무설정 — 규격안↔실제가 갈라진 셋 (2026-09-16)
   답안지를 «시안 실측» 으로 갱신하고 나니 실제화면 쪽에서 셋이 걸렸다.

   ① 머리 툴바 키 56 인데 실제는 57 — 툴바는 .bi-do2-wrap «밖» 이라
      전역 box-sizing 이 안 걸린다. 목업에는 * { box-sizing:border-box } 가 있어
      두 쪽이 갈라졌다. §61-2 에서 .bi-datenav 만 못박고 툴바 자신은 빠뜨렸다.
   ② 아바타 색을 .bi-bk2-ava--c0 에 줬는데 이 화면은 «.bi-do2-av» 를 쓴다 —
      규칙이 아무 데도 닿지 않았다(§7 F6 «이름만 바꾸고 찾는 쪽을 안 고침» 의 거울상).
   ③ 아바타 지름 32 인데 시안은 34. */
.bi-erp-toolbar.bi-do2-tb,
.bi-erp-toolbar.bi-do2-tb * { box-sizing: border-box; }
/* 아바타 지름 — 본 화면 34 · 팝업 32 (시안 실측: dayoff.png 34 · dayoff2.png 31~32).
   팝업까지 34 로 키우면 목록 줄이 48 → 50 이 되어 시안 pitch 가 깨진다. */
.bi-do2-wrap .bi-do2-av { width: 34px; height: 34px; }
.bi-do2-wrap .bi-do2-av,
.bi-do2-pop .bi-do2-av { background: var(--do-ava-navy); }

/* §61-15 기간 휴무 팝업 — 목록의 «선» 과 «원장» (2026-09-16)
   확대 대조에서 셋이 더 나왔다(out/shots/dayoff/cmp_pop_list.png).
   | 자리 | 시안 실측 | 전 |
   |---|---|---|
   | 목록 줄 사이 | 구분선 #EEF0F3 | 선이 없었다 |
   | 직급 꼬리표 «원장» | 바탕 #EEF2FF · 글자 #1D4ED8 | 다른 직급과 같은 회색 |
   | 직급 꼬리표 그 밖 | 바탕 #F3F4F6 · 글자 #6B7280 ✔ | ✔ |
   | 「전체 선택」 글자 | 회색 (네모만 파랑) | 글자까지 파랑 |
   | 닫기 × | 얇은 선(fal) | 굵은 선(fas) |  ← 마크업 */
.bi-do2-pop .bi-do2-pitem + .bi-do2-pitem { border-top: 1px solid var(--do-line); }
.bi-do2-pop .bi-do2-pitem__p--own {
    background: var(--color-indigo-50); color: var(--color-info-700);
}
.bi-do2-pop .bi-do2-pop__cnt .bi-linkbtn { color: var(--txt-muted); }
.bi-do2-pop .bi-do2-pop__cnt .bi-linkbtn > i { color: var(--color-info-700); }

/* §61-16 기간 휴무 팝업 — 날짜 입력칸 (2026-09-16)
   시안 dayoff2.png: 입력칸 «오른쪽 안» 에 달력 아이콘(#6B7280)이 있고 글자는 #111827 이다.
   규격안에는 아이콘이 아예 없었고 글자는 회색이었다. 「날짜를 고를 수 있다」 는 신호가 빠져 있었다. */
.bi-do2-pop .bi-do2-dt { position: relative; }
.bi-do2-pop .bi-do2-dt > input { padding-right: var(--space-8); color: var(--txt-primary); }
.bi-do2-pop .bi-do2-dt__ico {
    position: absolute; top: 50%; right: var(--space-3); transform: translateY(-50%);
    font-size: var(--fs-md); color: var(--txt-muted); pointer-events: none;
}
/* 「총 N일」 — 시안은 아주 연하다 */
.bi-do2-pop .bi-do2-pop__st small { color: var(--txt-disabled); }

/* §61-17 휴무설정 — 칩이 «하나 더» 있으면 좌패널이 넘친다 (2026-09-16)
   시안 dayoff.png 의 근무현황 칩은 넷이다(전체·근무·반차·휴무). 실제화면에는 «겹침» 이 더 있어
   다섯이 되고, 그러면 칩 줄이 «두 줄로 접혀» 근무현황 카드가 26px 커진다 →
   「기본 근무 규칙」 카드의 되돌리기 단추가 다시 스크롤 밖으로 밀렸다.

   ⚠ CLAUDE §7 F3 의 사촌 — «자식이 하나 늘면 접힌다» 는 것을 세로 리듬이 못 버틴다.
     칩을 지우는 것은 기능을 줄이는 것이라 하지 않는다. 대신 «접히지 않게» 하고
     자리가 모자라면 가로로 구르게 한다 — 세로 리듬은 시안 그대로 지킨다.
     줄이 22px 이라 막대는 숨긴다(손가락·바퀴로는 여전히 구른다). */
.bi-do2-wrap .bi-do2-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
}
.bi-do2-wrap .bi-do2-chips::-webkit-scrollbar { height: 0; display: none; }
.bi-do2-wrap .bi-do2-chip { flex: 0 0 auto; }

/* §61-18 styleguide2 §40-14-2 전시용 자리잡기 (2026-09-16)
   전시판에 새 부품을 올릴 때 인라인 style 로 자리를 잡으면 §4 절대규칙 위반이고
   `qc_static` 의 AB-INLINE 이 잡는다(실제로 12건이 났다). 자리는 클래스가 잡는다. */
/* ⚠ .bi-do2-demo 자신에게 {display:block} 을 주지 않는다 — <div> 는 이미 block 이고
   같은 선언을 가진 규격(.bi-pop-pay--form)과 겹쳐 SPEC-DUP 이 뜬다. */
.bi-do2-demo .bi-do2-demo__row { display: flex; align-items: flex-start; flex-wrap: wrap; gap: var(--space-3); }
.bi-do2-demo .bi-do2-demo__row + .bi-do2-demo__row { margin-top: var(--space-3); }
.bi-do2-demo .bi-do2-demo__c--cal { width: 212px; }
.bi-do2-demo .bi-do2-demo__c--w300 { width: 300px; }
.bi-do2-demo .bi-do2-demo__tool { display: inline-flex; padding: 0; }
.bi-do2-demo .bi-do2-demo__list { margin-top: var(--space-2); }

/* =========================================================
   §61-19 휴무설정 — 글자 크기를 «폭» 으로 다시 되짚었다 (2026-09-16)
   ---------------------------------------------------------
   §61-2·§61-3 의 글자 크기는 «잉크 높이» 로 되짚은 값이다. 그게 약한 자였다 —
   12px 과 11px 의 잉크 높이 차는 1px 뿐이라 안티에일리어싱에 묻힌다.
   같은 서체로 렌더된 두 그림을 견줄 때 «잉크 폭» 은 글자 수만큼 증폭된다 → 훨씬 민감하다.
   (⚠ _SPEC_CHECKLIST §2-9 의 「폭은 쓰지 않는다」 는 «캔버스에 직접 그린 눈금표» 와
     견줄 때의 이야기다 — 자간이 실제와 다르다. 실제 렌더 두 장을 서로 견줄 때는 폭이 맞다.)

   | 자리 | 시안 | 전 | 근거 |
   |---|---|---|---|
   | 바닥 범례 글자 | **11** | 12 | 「근무 (예약 가능)」 잉크폭 77/86 = 0.895 → 12×0.895 = 10.7.
   |  |  |  | 원시 덩이로도 세 항목이 모두 0.88~0.89 (79/88 · 73/82 · 82/93) |
   | 머리줄 단추 글자 | **12** | 14 | 아래 셈 |
   | 머리줄 단추 좌우 여백 | **12** | 10 | 아래 셈 |

   ⚠ 머리줄 단추는 «두 값을 같이» 봐야 풀린다. 하나만 보면 답이 둘 나온다:
       「오늘」 겉폭은 시안·규격안 모두 **50** — 14/여백10 도 50, 12/여백12 도 50 이다.
       「전체 근무」 겉폭이 가른다 — 시안 **77** · 규격안 83.
         14/10 → 61+2+20 = 83  (규격안)
         12/12 → 51+2+24 = 77  (시안) ✔
       잉크폭도 같은 말을 한다: 오늘 23/26 · 전체 근무 49/59.
     →  «한 자리만 재면 두 답이 다 맞아 보인다» 는 것을 여기서 배웠다.

   ⚠ 머리 툴바 단추는 그대로 14 다 — 「기간 휴무 설정」 겉폭이 134 로 «정확히 같다».
     머리줄과 툴바는 같은 .bi-btn 이지만 시안이 다르게 말한다.
   ========================================================= */
/* ⚠⚠ 2026-09-16 되돌림 — 이 절의 판정은 «틀렸다».
   규격안 목업이 Pretendard 를 «싣지 않아» 시스템 폴백으로 렌더되고 있었다
   (style.css 의 --font-sans 는 서체를 가리키기만 하고, 로드는 template/header.php 가 한다.
    목업은 셸을 안 쓰니 아무도 싣지 않았다). 폴백 서체가 넓어서
      같은 글·같은 크기인데  목업 96 · 실제 86  으로 벌어졌고,
      나는 그 차이를 「시안 글자가 한 단 작다」 로 읽어 범례 12→11, 머리줄 단추 14→12 로 줄였다.
   목업에 서체를 실으니 목업 86 = 실제 86 이 되었다 → 줄일 이유가 없었다.

   교훈: «두 그림을 견주기 전에 둘이 같은 서체로 렌더되는지 확인한다.»
        폭은 민감한 자다 — 그래서 서체가 다르면 가장 크게 틀린다.
   (같은 결함이 spec_bk·spec_ai 목업 전부에 있다 → KNOWN_ISSUES D12) */
/* §61-19 끝 — 규칙은 되돌렸고 기록만 남긴다 ───────────────────────── */

/* §61-20 휴무설정 — 머리줄이 «자기 칸» 과 나란해야 한다 (2026-09-16)
   시안: 머리줄 「전체 휴무」 우 끝 1584 · 마지막 칸 우 끝 1586 → 나란하다.
   규격안: 머리줄 1599 · 칸 1584 → 머리줄이 15 더 나갔다.
   까닭 — 판은 구르는 상자라 세로 막대(≈15)만큼 안으로 들어오는데 머리줄은 밖이라 그대로다.
   시안이 둘을 맞춰 두었으니 머리줄 오른쪽 여백에 그만큼을 더한다. */
.bi-do2-wrap .bi-do2-tool { padding-right: var(--do-tool-padr); }   /* 30px — 토큰은 §61-36 */

/* §61-21 휴무설정 — 「일괄」 단추 둘의 틈은 6 이다 (2026-09-16)
   머리줄의 다른 틈은 10 인데(오늘↔배지 등, 시안과 일치) 「전체 근무」↔「전체 휴무」 만 6 이다.
   머리줄 gap 을 줄이면 나머지가 다 어긋나므로 둘만 묶어 그 안에서 6 을 쓴다. */
.bi-do2-wrap .bi-do2-bulk { display: inline-flex; align-items: center; gap: var(--space-1_5); }

/* §61-22 휴무설정 — 바닥 범례의 항목 사이 틈은 8 이다 (2026-09-16)
   규격안 14 로 두었더니 항목이 하나씩 7px 밀려 다섯째 스와치가 29 어긋났다(누적).
   시안에서 «세 가지가 동시에» 8 을 가리킨다:
     「범례」 라벨 → 첫 스와치 틈 18  (라벨 여백 8 + 틈 8 + 잉크 여유 2)
     항목1 폭 96 + 틈 → 스와치 간격 103  (96+8 = 104, 시안 103)
     항목4 폭 91 + 틈 → 간격 98         (91+8 = 99,  시안 98)
   ⚠ 누적으로 벌어지는 어긋남은 «마지막 것» 만 보면 원인을 못 찾는다 —
     항목마다의 차(+7)로 나눠 봐야 «틈» 이라는 답이 나온다. */
/* ⚠ 2026-09-16 다시 — 처음엔 8 로 잡았는데 그건 «목업이 폴백 서체로 렌더될 때» 의 값이었다.
   목업에 Pretendard 를 실은 뒤 다시 재니 항목 넷이 «모두» 틈 12 를 가리킨다:
     항목 폭 92·37·67·86 (두 그림 같다) → 시안 스와치 간격 104·49·79·98 = 폭 + 12
   네 항목이 한 값을 가리키면 그게 답이다. */
.bi-do2-wrap .bi-do2-legend { gap: var(--space-3); }

/* =========================================================
   §61-23 팝업·메뉴 — 창을 «머리줄 아래 선» 기준으로 다시 재서 나온 둘 (2026-09-16)
   ---------------------------------------------------------
   ⚠ 창 «위 테두리» 를 원점으로 삼으면 안 된다 — 창 그림자가 여백을 물들여
     위 끝이 그림마다 3~8px 다르게 읽히고, 그 위에 세운 모든 y 비교가 통째로 어긋난다
     (팝업 머리줄 키가 55 ↔ 78 로 나왔다). 안쪽 1px 구분선은 선명하다 → 그것을 원점으로.
     그렇게 하니 두 그림의 공유 선이 «70 · 107 · 157 · 435» 로 정확히 맞았다.

   | 자리 | 시안 | 규격안(전) |
   |---|---|---|
   | 팝업 검색·직급칩 구역 바탕 | #F5F6F9 | #F8F9FC (전역 --bg-page) |
   | ⋯ 메뉴 안쪽 위아래 여백 | ~10 | ~14 → 창 키 225 vs 233 |

   본 화면의 좌패널 바탕을 --do-bg-page 로 잡은 것과 «같은 까닭» 이다 —
   시안은 이 화면에서 옅은 바탕을 #F5F6F9 로 말한다. 전역 --bg-page 는 #F8F9FC 다. */
.bi-do2-pop .bi-do2-pop__srch { background: var(--do-bg-page); }
/* ⋯ 메뉴 — 시안 창 키 225. 공용 .bi-dropdown 의 여백 4 에 라벨/항목 여백이 더해져 8 이 컸다 */
.bi-do2-menu .bi-do2-menu__lb { padding: var(--space-1_5) var(--space-3) var(--space-1); }
/* §61-23 끝 ───────────────────────────────────────────────────────── */

/* §61-24 기간 휴무 팝업 — 머리줄 아래 선은 #E5E7EB 다 (2026-09-16)
   공용 .bi-modal__head 의 border-bottom 은 --border-light(#F3F4F6) 인데
   시안 dayoff2.png 는 그 자리를 --border-base(#E5E7EB)로 말한다(y=55 에서 실측).
   ⚠ 이 1px 을 못 찾고 있었던 까닭 — 선을 «#E5E7EB» 만 찾는 자로 훑었더니
     규격안에서는 그 선이 «아예 없는 것» 으로 나와 머리줄 키가 55↔70 으로 갈렸다.
     찾는 색이 틀리면 «없다» 와 «다르다» 를 구별할 수 없다. */
.bi-modal--do .bi-modal__head { border-bottom-color: var(--border-base); }

/* §61-25 기간 휴무 팝업 — 목록 구역의 선 둘 (2026-09-16)
   머리줄 아래 선을 원점으로 삼아 재니 목록 구역이 정확히 견주어졌다.

   | 자리 | 시안 | 규격안(전) |
   |---|---|---|
   | 「대상 디자이너 N명 중 …」 줄 아래 | 구분선 #EEF0F3 있음 | 없음 |
   | 목록 줄 pitch | 48 | 49 (줄 48 + 테두리 1) |

   ⚠ pitch 1px 은 한 줄에서는 안 보이지만 다섯 줄이면 5px 이 밀린다.
     «누적되는 어긋남» 은 마지막 줄에서야 눈에 띈다 — pitch 로 재야 잡힌다.
   ⚠ 팝업은 .bi-do2-wrap «밖» 이라(모달은 형제다) 전역 box-sizing 이 안 걸린다 → 스스로 못박는다. */
.bi-do2-pop .bi-do2-pop__cnt { border-bottom: 1px solid var(--do-line); }
.bi-do2-pop .bi-do2-pitem { box-sizing: border-box; height: 48px; }

/* §61-26 휴무설정 — 머리줄 단추 좌우 여백 12 (2026-09-16 · 서체를 맞춘 뒤 다시 잰 값)
   §61-19 에서 「글자 14→12 · 여백 10→12」 로 잡았던 것을 되돌리고 다시 쟀다.
   목업이 Pretendard 로 렌더되자 답이 하나로 모였다 — 글자는 **14 그대로**, 여백만 10 → 12:
     「전체 근무」 겉폭  시안 77 · 규격안 73(여백10) → 여백 12 면 77 ✔
   ⚠ 서체가 다르면 폭으로 잰 모든 값이 틀린다. 견주기 전에 «같은 서체인가» 를 먼저 본다. */
.bi-do2-wrap .bi-do2-tool .bi-btn { padding: 0 var(--space-3); }

/* =========================================================
   §61-27 휴무설정 — 서체를 맞춘 뒤 «다시» 되짚은 글자 크기 (2026-09-16)
   ---------------------------------------------------------
   §61-2·§61-3·§61-19 의 글자 크기는 모두 «목업이 폴백 서체로 렌더되던 때» 의 값이다.
   목업에 Pretendard 를 실은 뒤 자동 폭 비교기(_do_fs4.mjs)를 다시 돌리니 답이 수렴했다.

   | 자리 | 되짚기 | 전 | 근거 |
   |---|---|---|---|
   | 행머리 부제 · 근무현황 부제 | **12** | 11 | 네 자리가 모두 12.4~12.5 (잉크폭 91/81 · 93/82 · 134/122) |
   | 머리줄 배지 글자 | **13** | 11 | 배지1 겉폭 146: fs13 → 148 · fs11 → 130. 배지2 88: fs13 → 85 |
   | 머리 툴바 단추 글자 | **16** | 14 | 「기간 휴무 설정」 134: fs16 → 131 · fs14 → 120.
   |  |  |  | 「저장」 119: fs16 → 118 · fs14 → 114. 둘이 같은 답을 낸다 |
   | 디자이너 이름 · 범례 · 눈금 · 칸 · 판머리 라벨 | 그대로 | — | 14.5 · 12.3~12.7 · 12.4 · 12.0 → 맞았다 |

   ⚠ 「한 자리만 맞으면 답이 둘 나온다」 를 또 배웠다 — 툴바 단추는 «폭이 다른 단추 둘» 이
     같은 값(16)을 가리켜야 비로소 답이다. 하나만 보면 여백으로도 맞출 수 있다.
   ========================================================= */
.bi-do2-wrap .bi-do2-rowhd__s,
.bi-do2-wrap .bi-do2-stat__s { font-size: var(--fs-sm); }      /* 11 → 12 */
.bi-do2-wrap .bi-do2-pill { font-size: var(--fs-base); }       /* 11 → 13 */
.bi-do2-tb .bi-btn { font-size: var(--fs-lg); }                /* 14 → 16 */

/* §61-28 휴무설정 — 상태 꼬리표와 ⋯ 사이 틈 (2026-09-16)
   시안 행머리의 틈이 «자리마다 다르다»: 아바타↔이름 11 · 꼬리표↔⋯ 16.
   .bi-do2-rowhd 의 gap 을 16 으로 올리면 아바타 쪽이 5 벌어진다 →
   꼬리표에만 오른쪽 여백을 준다(⋯ 자리는 이미 맞다 — 546 vs 시안 544). */
.bi-do2-wrap .bi-do2-tag { margin-right: var(--space-1_5); }

/* §61-29 휴무설정 — 머리 툴바의 «물려받는 글자색» 이 순검정이었다 (2026-09-16)
   규격안↔실제를 DOM 값으로 견주니(tools/qc/_do_specreal.mjs) 실제화면 툴바의
   color 가 **rgb(0,0,0)** 이었다. §61 은 `.bi-do2-wrap { color: var(--txt-primary) }` 로
   판 안쪽만 못박았고, 머리 툴바는 그 «밖» 이라 아무도 정하지 않았다.
   목업은 무대가 color 를 정해 두어 #111827 로 보였다 → 두 쪽이 갈렸다.
   ⚠ 「순검정 #000000 은 토큰이 아니다」(_SPEC_CHECKLIST §2-1). 스코프 밖은 스스로 못박는다 —
     §61-14 의 box-sizing 과 «같은 갈래» 의 함정이다. */
.bi-erp-toolbar.bi-do2-tb { color: var(--txt-primary); }

/* =========================================================
   §61-30 휴무설정 — 사용자 지적 넷 (2026-09-16)
   ---------------------------------------------------------
   ① 「중앙영역 헤더에 날짜가 2026-09-16 ( 이런식으로 요일표시가 짤려」
      실측: 머리줄 날짜칸 안쪽 111 인데 글자가 132 → **21px 잘림**.
      시안의 그 글자는 14 가 아니라 **12** 다 — 잉크폭 108 (14 라면 132).
      게다가 네모(157)가 이미 좌우 여백을 갖는데 안쪽 칸이 «또» 여백 10 을 가져 좁아졌다.
   ========================================================= */
.bi-do2-wrap .bi-do2-tool .bi-datenav__input {
    font-size: var(--fs-sm);        /* 14 → 12 (시안 잉크폭 108) */
    padding: 0;                     /* 네모가 이미 여백을 갖는다 — 두 번 주면 글자가 잘린다 */
    min-width: 0;
    flex: 1 1 auto;
    text-overflow: clip;            /* 잘릴 일이 없어야 한다 — 잘리면 «…» 로 숨기지 않고 드러낸다 */
}
.bi-do2-wrap .bi-do2-tool .bi-datenav__cv { flex: 0 0 auto; }

/* ⚠ 2026-09-30 사용자 지시 — 「**«오늘» 버튼 좌측 날짜의 배경색 빼기**」.
   찾아보니 배경을 가진 것은 .bi-datenav(그것은 17914 에서 이미 transparent 다)가 아니라
   **안쪽 상자 .bi-datenav__mid** 였다(17919: background var(--bg-card) + 테두리).
   ⚠ 전역 .bi-datenav__mid(9284)는 배경이 없다 — 이 판이 제 규칙으로 «더한» 것이라
     여기서 되돌리는 것이 맞다. 다른 화면엔 닿지 않는다.
   ⚠ 배경만 지우면 «테두리만 남은 빈 상자» 가 되어 더 어색하다 — 테두리도 같이 지운다.
     키·폭·안여백은 남긴다(지우면 ‹ › 화살표와 글자가 붙는다).
   ⚠ 이 줄은 17919 보다 **뒤** 에 있어야 이긴다 — 같은 특이도(0,3,0)라 차례가 가른다. */
/* ⚠⚠ 2026-09-30 (2) 사용자 지시 — 「휴무설정에 오늘 버튼 좌측에 날짜,
     **예약일정표에 똑같은 부분있는데 참고해서 똑같이** 해줘」.
   예약일정표의 그 자리는 ‹ [날짜] › [오늘] 이고 날짜도 **오늘과 같은 단추 꼴**이다
     (.bi-bk2-daybtn — 테두리 --border-base · 바탕 --bg-card · 반경 --radius-md · 키 32 · 굵게).
   휴무설정은 그 자리를 «달력 아이콘 + 칸 + ∨» 로 그려 두어 **다른 모양**이었다.
   ⚠ 앞선 지시(「배경색 빼줘」)로 바탕·테두리를 지웠는데, 이번 지시가 그것을 덮는다 —
     예약일정표와 «같게» 가 기준이다. 지웠다 되살린 자취를 남긴다.
   ⚠ 칸(input)은 **지우지 않는다** — datetimepicker 가 그 칸에 붙는다(script.js:1009).
     보이는 꼴만 단추처럼 만들고, 아이콘과 ∨ 는 걷는다(예약일정표엔 없다). */
.bi-do2-wrap .bi-do2-tool .bi-datenav__mid {
    height: 32px; padding: 0 var(--space-3); gap: 0;
    border: 1px solid var(--border-base); background: var(--bg-card);
    border-radius: var(--radius-md);
}
.bi-do2-wrap .bi-do2-tool .bi-datenav__ico,
.bi-do2-wrap .bi-do2-tool .bi-datenav__cv { display: none; }
/* ⚠ 2026-09-30 (3) — 날짜칸이 «눌리는 것» 으로 보이게 한다.
   ∨ 를 걷고 칸 자체를 누르게 바꿨는데(예약일정표와 같은 꼴), 그 칸은 readonly input 이라
   기본 커서가 text 다 — 누를 수 있는 자리인데 **누를 수 있어 보이지 않았다.**
   probe_dayoff 가 「커서 auto」 로 잡아 주었다. 예약일정표의 .bi-bk2-daybtn 도 pointer 다. */
.bi-do2-wrap .bi-do2-tool .bi-datenav__mid,
.bi-do2-wrap .bi-do2-tool .bi-datenav__input { cursor: pointer; }
.bi-do2-wrap .bi-do2-tool .bi-datenav__input {
    font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-primary);
    text-align: center; cursor: pointer;
}

/* ② 「가로로 긴데 마우스로 끌면 가게 해줘」 — 판을 끌어 옮기는 중에는 손 모양으로 알린다.
      ⚠ 칸 위 드래그는 이미 «여러 칸 고르기» 다. 그래서 «칸이 아닌 곳» 을 끌 때만 판이 따라온다
        (행머리 · 판 머리행 · 칸 사이 빈 자리). 칸 고르기와 섞이지 않는다. */
.bi-do2-wrap .bi-do2-grid { cursor: grab; }
.bi-do2-wrap .bi-do2-grid.is-panning { cursor: grabbing; user-select: none; }
.bi-do2-wrap .bi-do2-grid.is-panning .bi-do2-cell { pointer-events: none; }
/* §61-30 끝 ───────────────────────────────────────────────────────── */

/* =========================================================
   §61-31 기본 근무 규칙 — 값이 «어디서 왔는지» 를 말한다 (2026-09-16)
   ---------------------------------------------------------
   사용자 지시: 「기본근무규칙 a안으로 해봐 그런데 설정이 안되어있으면 어떻게 해??
                이런거 고려해줘야하지」

   A안 = 지점 설정(Setting_config_shop) 을 읽어 시간축을 세운다. 그런데 «없는 것이 정상» 이다
   (아직 아무 지점도 넣지 않았다). 그럴 때 조용히 기본값으로 돌아가면
   「설정했는데 안 먹네」 를 아무도 모른다 → 카드 제목 옆에 출처를 적는다.

   | 꼬리말 | 뜻 |
   |---|---|
   | `지점 설정` | 환경설정에서 온 값으로 축을 세웠다 |
   | `지점 설정(일부) · 영업시간 값이 이상해 기본값` | 일부만 쓸 수 있었다 — **이상한 항목을 이름으로 말한다** |
   | `기본값` | 설정이 없다(또는 전부 이상하다) → script.js 의 기본값 |
   | `… · 자료가 있어 축을 넓혔다` | 설정이 좁아 축 밖이 된 hourbit 비트가 있어 넓혔다 |

   ⚠ 「기본값」·「이상해서 버렸다」 는 **눈에 띄어야** 한다 — 그래야 고친다. 주의색을 준다. */
.bi-do2-wrap .bi-bk2-card__t { display: flex; align-items: baseline; gap: var(--space-2); }
/* ⚠ 2026-09-17 — 꼬리말(.bi-do2-rule__src) 선언을 걷었다. 사용자 지시로 요소를 없앴다
     (「기본 근무규칙 타이틀 우측에 '지점설정 축 넓힘' 머야 빼줘」).
     위의 표는 그때의 설계 기록으로 남긴다 — 왜 있었는지를 모르면 또 만든다. */
/* §61-31 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-32 · 규칙 출처 꼬리말의 «특이도» — 2026-09-16
   ──────────────────────────────────────────────────────────────────────
   §61-31 의 `.bi-do2-wrap .bi-do2-rule__src` 는 (0,2,0) 이고,
   §61-27 근처의 `.bi-do2-wrap .bi-bk2-card__t small` 은 (0,2,1) 이다 →
   «총 N명» 을 위해 만든 굵은 13px 이 출처 꼬리말까지 덮어썼다(13/#374151).

   ⚠ 기존 선언을 고치지 않는다 — 「총 N명」 이 그 규칙을 쓰고 있다.
     자리로 못박아 «같은 자리에서 더 구체적인» 쪽으로 이긴다. `!important` 는 쓰지 않는다.
     (이 프로젝트에서 특이도로 일곱 번 물렸다 — 38_popup_규격.md:1538) */
/* ⚠ 2026-09-17 — 꼬리말이 없어져 이 특이도 싸움도 끝났다(선언 걷음).
     기록은 남긴다 — «같은 자리에서 더 구체적인 쪽으로 이긴다» 는 처방은 계속 쓴다. */
/* §61-32 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-33 · 기간 휴무 팝업의 «세로 틈» — 시안 756 에 맞춘다 (2026-09-16)
   ──────────────────────────────────────────────────────────────────────
   사용자 상시 요구: 「시안에 있는 글자크기, 색, 버튼크기 … **간격도**」

   ⚠ 어긋남이 «아래로 갈수록 커졌다» — 누적이다. 픽셀 자(_do_verify2.mjs)가 이렇게 찍었다:

   | 자리 | 시안 | 규격안 | 차 |
   |---|---|---|---|
   | 기간 라벨 top | 457 | 452 | −5 |
   | 날짜 라벨 top | 484 | 474 | −10 |
   | 내용 라벨 top | 561 | 549 | −12 |
   | 알약 top | 586 | 570 | −16 |
   | 안내 top | 640 | 622 | −18 |
   | 푸터 위 선 | 693 | 673 | −20 |
   | 창 키 | 756 | 734 | **−22** |

   누적이면 원인은 «어느 한 틈» 이 아니라 «여러 틈» 이다 → 이웃한 차를 «나누어» 보면
   어느 틈이 몇 px 좁은지 그대로 나온다(−5 · −5 · 0 · −2 · −4 · −2 · −2 · −2).
   그 일곱이 아래 일곱 줄이다. 한 줄씩 더하니 여덟 자리가 «모두» 시안과 맞았다.

   ⚠ `--pop-foot-pad-t/b` 는 **모든 팝업이 쓰는 전역 토큰**이다(§38). 건드리지 않고
     `.bi-do2-pop` 안에서만 여백을 다시 준다. 같은 자리의 옛 선언(16416·17778~17780)은
     지우지 않는다 — 뒤에 오는 이 절이 «같은 특이도에서 나중» 이라 이긴다. */
:root {
    --do-pop-sec-pad:  22px;   /* 시안: 구역 위 여백 (옛 16·20) */
    --do-pop-note-mt:  18px;   /* 시안: 안내 위 틈 (옛 16) */
    --do-pop-foot-pb:  13px;   /* 시안: 푸터 아래 여백 (옛 --pop-foot-pad-b 12) */
}
.bi-do2-pop .bi-do2-pop__sec        { padding-top: var(--do-pop-sec-pad); }   /* 16 → 22 */
.bi-do2-pop .bi-do2-pop__sec--tight { padding-top: var(--do-pop-sec-pad); }   /* 20 → 22 */
.bi-do2-pop .bi-do2-pop__st         { margin-bottom: var(--space-3); }        /*  8 → 12 */
.bi-do2-pop .bi-do2-pop__note       { margin: var(--do-pop-note-mt) 0 var(--space-4); } /* 16·14 → 18·16 */
.bi-do2-pop .bi-do2-pop__foot {
    padding: var(--space-3_5) var(--space-4) var(--do-pop-foot-pb);           /* 13·12 → 14·13 */
}
/* §61-33 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-34 · 기간 휴무 팝업의 «좌우 여백» — 시안 22 (2026-09-16)
   ──────────────────────────────────────────────────────────────────────
   verify2 가 「알약1 좌 22 / 17」 을 냈다. 알약은 둥근 모서리라 잉크 왼쪽 끝이
   여백과 다르다 → 둥글지 않은 «글자» 의 왼쪽 끝으로 다시 쟀다(`_do_popx.mjs`):

   |            | 「기간」 | 「시작일」 | 날짜칸 | 「설정 내용」 | 알약줄 | 안내상자 |
   |---|---|---|---|---|---|---|
   | 시안       | 22 | 24 | 22 | 22 | 22 | 22 |
   | 규격안     | 17 | 19 | 17 | 17 | 17 | 17 |

   여섯 자리가 «모두 정확히 5» 다 → 한 자리의 흠이 아니라 **안쪽 여백 자체**가 5 좁다.
   ⚠ 한 자리만 보고 고치면 나머지 다섯이 그대로 남는다. 「전부 같은 차」 면 뿌리를 고친다.
     (모달 테두리 1px + 여백 21 = 잉크 22) */
:root { --do-pop-padx: 21px; }   /* 시안 실측 22 − 모달 테두리 1 */
.bi-do2-pop .bi-do2-pop__srch,
.bi-do2-pop .bi-do2-pop__cnt,
.bi-do2-pop .bi-do2-pitem,
.bi-do2-pop .bi-do2-pop__sec,
.bi-do2-pop .bi-do2-pop__foot {
    padding-left: var(--do-pop-padx); padding-right: var(--do-pop-padx);   /* 16 → 21 */
}
/* §61-34 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-35 · 카드 제목이 «두 줄로 밀리지» 않게 — 2026-09-16
   ──────────────────────────────────────────────────────────────────────
   실제 캡처를 «눈으로 보고» 잡았다: 「기본 근무 규칙」 이 「기본 근무 / 규칙」 두 줄이 되어
   카드가 16px 길어지고 좌패널이 넘쳤다. 원인은 꼬리말(#do_rule_src)이다 —
   `white-space: nowrap` 인 플렉스 자식은 **`min-width: 0` 이 없으면 줄어들지 않는다**
   (기본 `min-width: auto`). 줄지 않는 꼬리말이 제목을 밀고, 제목은 줄바꿈이 되니 접혔다.

   ⚠ 수치 검사는 이것을 못 잡는다 — 「줄 수」 를 세는 잣대가 없다. 캡처를 열어 봐야 보인다
     (CLAUDE.md §5-1 「턴 종료 전 ②: 캡처를 직접 열어 대조한다 — 수치만 보면 놓친다」). */
.bi-do2-wrap .bi-bk2-card__t > span:first-child { white-space: nowrap; flex: 0 0 auto; }
/* ⚠ 2026-09-17 — 꼬리말이 없어져 이 줄도 걷었다. 제목이 두 줄로 밀릴 까닭이 사라졌다.
     설명은 남긴다 — «nowrap 인 플렉스 자식은 min-width:0 이 없으면 줄지 않는다» 는
     그대로 유효한 함정이다. */
/* §61-35 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-36 · 머리줄 오른쪽 여백을 «토큰» 으로 (2026-09-16)
   ──────────────────────────────────────────────────────────────────────
   §61-20 이 `padding-right: 30px` 을 날값으로 썼다 → L1 정적 검사가 `TK-SPACE`
   (「스케일 밖」)로 짚는다. 30 은 사다리(`--space-*`)에 없는 값이고, **없는 것이 맞다** —
   여백 16 + 세로 막대 ≈14 를 합한 «자리에서 나온 수» 이기 때문이다(§61-20 의 셈).
   사다리에 없다고 «가까운 것» 으로 바꾸면 머리줄이 다시 칸과 어긋난다 →
   근거를 적고 토큰으로 신설한다(§61-33·34 의 22·18·13·21 과 같은 처방). */
:root { --do-tool-padr: 30px; }   /* 여백 16 + 판의 세로 막대 ≈14 */
/* ⚠ 규칙을 여기 다시 쓰지 않는다 — §61-20 의 그 선언이 이 토큰을 쓰도록 바꿨다.
     같은 선택자를 두 번 쓰면 SPEC-DUP 가 되고, 나중에 «어느 쪽이 먹는지» 를 또 따져야 한다.
     값은 30px 그대로다 — 화면은 1px 도 바뀌지 않는다. */
/* §61-36 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-37 · 전시판 칸의 «빈 규격» 을 없앤다 (2026-09-16)
   ──────────────────────────────────────────────────────────────────────
   `qc_static` 의 `SPEC-REWORK` 가 「빈 규격 1개 — .bi-do2-demo__c」 를 짚었다 —
   전시판 마크업이 그 이름을 쓰는데 선언이 «아무 데도 없다»(폭을 주는 --cal·--w300 만 있었다).
   이름만 있고 규칙이 없으면 다음 사람이 「어디서 먹는 거지」 를 찾아 헤맨다.

   채우는 값은 «있으나 마나» 한 것이 아니라 실제로 필요한 것이다 —
   `.bi-do2-demo__row` 가 flex 인데 자식 기본값이 `min-width: auto` 라
   안의 넓은 부품(판·팝업)이 칸을 밀어 줄을 넘긴다. §61-35 에서 겪은 것과 같은 갈래다. */
.bi-do2-demo .bi-do2-demo__c { min-width: 0; }
/* §61-37 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-38 · 「기본 근무 규칙」 카드가 시안보다 6px 길다 (2026-09-17)
   ──────────────────────────────────────────────────────────────────────
   픽셀 표가 「규칙 카드 키 165 / 171」 을 계속 내고 있었다. 어제는 «6px 이라 쫓지 않겠다» 고
   적고 넘겼는데, 사용자 지시(「처음부터 다시 검수 … 문제있으면 바로 수정」)로 다시 재서
   카드 «안» 의 띠를 하나씩 나누어 봤다(`_do_rulebands.mjs`):

   | 자리 | 시안 | 규격안 |
   |---|---|---|
   | 제목 잉크 top (= 카드 위 여백) | 11 | 13 |
   | 줄 셋의 자리 | 41 · 69 · 97 | 42 · 70 · 98  ← 같다 |
   | 스위치 줄 | 124 | 123  ← 같다 |
   | 되돌리기 단추 위 틈 | **0** | **4** |
   | 안쪽 잉크 span | **165** | **171** |

   줄 셋과 스위치는 이미 같았다 — 어긋난 곳은 **둘**이고 합이 정확히 6 이다:
     ① 카드 위 여백 12 → **10**   ② 단추 위 틈 4 → **0** (시안은 스위치 줄에 붙어 있다)

   ⚠ 여백은 `.bi-do2-wrap` 안에서만 바꾼다 — `.bi-bk2-card` 는 예약일정표와 공유하는 부품이다.
   ⚠ 「6px 쯤은」 이라고 넘기지 않는다. 카드가 길어지면 좌패널 넷이 아래로 밀리고,
     낮은 창(900px)에서 마지막 단추가 접힌다 — 어제 실제로 그랬다(§61-35 참조). */
/* ⚠⚠ 2026-09-17 되돌림 — 이 두 줄의 판정이 «틀렸다».
     근거로 삼은 「규칙 카드 키 165 / 171」 은 카드를 «흰 덩이» 로 세던 자가 낸 수이고,
     그 자는 칩 줄 때문에 카드를 조각으로 쪼개고 있었다(§61-39 머리말 · KNOWN_ISSUES D18).
     카드 «박스» 를 제대로 재 보니 시안 **195** · 규격안 **196** — 이미 1px 안쪽이었다.
     그런데 6 을 줄여 **190** 으로 만들어 오히려 5px 틀리게 했다. 값을 돌려놓는다.
     (선언을 지우지 않고 무효화한다 — 왜 되돌렸는지가 여기 남아야 다음에 또 안 줄인다) */
/* .bi-do2-wrap .bi-bk2-side > .bi-bk2-card:last-child { padding-top: var(--space-2_5); } */
/* .bi-do2-wrap .bi-do2-reset { margin-top: 0; } */
/* §61-38 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-39 · 「근무 현황」 카드 — 시안의 세 수치 (2026-09-17)
   ──────────────────────────────────────────────────────────────────────
   사용자 지시(「처음부터 다시 검수 … 문제있으면 바로 수정」)로 좌패널을 다시 쟀다.
   자를 세 번 바꾼 뒤에야 제대로 읽혔다 —
     ① 흰 덩이로 «카드» 를 세면 카드 «안» 의 선(칩 줄·단추 테두리)에 쪼개진다
        → `_do_verify1` 이 «조각» 에 카드 이름을 붙이고 있었다(현황 카드 키를 29 로 읽었다. 실제 248).
     ② 테두리 훑기는 두 그림에서 줄 개수가 달라(10 대 5) 짝이 안 맞는다.
     ③ 좌패널 바탕 `#F5F6F9` 는 «흰색» 문턱(250) 아래다 → 패널 여백까지 «칠» 로 잡혀 띠 번호가 밀린다.
   그래서 «규격안은 DOM · 시안은 픽셀» 로 이름을 붙여 견줬다(`_do_sidemap.mjs` · `_do_sidebands.mjs`).

   | 자리 | 시안 | 옛 규격안 |
   |---|---|---|
   | 현황 목록 아바타 지름 | **30** | 34 |
   | 제목 → 칩 줄 틈 | **9** | 2 |
   | 칩 줄 → 첫 목록 줄 틈 | **11** | 5 |

   ⚠ 아바타는 «두 자리» 에 있고 시안은 둘을 다르게 준다 — 판 행머리 **34** · 현황 목록 **30**.
     한 규칙(`.bi-do2-wrap .bi-do2-av`)으로 34 를 주고 있어 현황 목록이 4px 컸다.
     답안지는 행머리만 못박아 두어(`.bi-do2-rowhd .bi-do2-av` 폭 34) 이쪽은 아무도 안 봤다.
   ⚠ 키 셈이 맞는다 — 아바타 4줄 × −4 = −16, 틈 +7 +6 = +13 → 카드가 3 줄어든다.
     좌패널이 낮은 창에서 접히지 않게 «합» 을 보고 고친다(§61-35 에서 배운 것). */
.bi-do2-wrap .bi-do2-stat .bi-do2-av { width: 30px; height: 30px; }   /* 34 → 30 (시안) */
/* ⚠ 칩 줄은 «자리로» 못박는다 — 17664 의 `.bi-do2-wrap .bi-bk2-card__t + .bi-do2-chips`
     가 (0,3,0) 이라 (0,2,0) 으로는 진다(처음에 그래서 안 먹었다).
     옆 여백은 그 규칙의 «판 끝까지 깔기»(음수 여백)를 건드리지 않게 top 만 준다. */
/* ⚠ 이웃한 형제의 여백은 «상쇄» 된다 — 제목의 margin-bottom(6)과 칩의 margin-top 이
     겹쳐 max() 만 남는다. 처음에 5 를 줬더니 6 이 그대로 나와 «안 먹는다» 고 헤맸다.

   ⚠⚠ 2026-09-17 «9 → 6» 으로 고쳤다. 잉크 틈과 박스 틈이 서로 다른 답을 낸다:
     · «잉크» 로 재면 시안의 제목 글 끝 391 → 칩 줄 400 = **9**
     · «박스» 로 재면 시안 흰조각 34 = 카드여백 12 + 제목 16 + **6**
     카드 키를 정하는 것은 **박스 틈**이다. 9 를 주면 카드가 245 → 252 로 커져
     좌패널이 넘치고(실제로 12px 넘쳤다) 목록 창을 시안보다 좁혀야 한다.
     잉크 틈이 9 로 보이는 것은 제목 글이 16px 상자 안에서 위로 붙어 앉기 때문이다.
     → 박스 6 을 준다. 잉크는 7~8 로 나오고 시안과 1~2px 안쪽이다. */
:root { --do-chips-mt: 6px; }   /* 시안 흰조각 셈 — 제목 16 + 틈 6 = 34 */
.bi-do2-wrap .bi-bk2-card__t + .bi-do2-chips { margin-top: var(--do-chips-mt); }   /* -4 → 5 (제목 틈 9) */
/* ⚠ 2026-09-17 «4 → 0». 시안의 목록 조각은 167 = 목록창 155 + 카드 아래여백 12 이고
     칩 줄과 목록 사이에 «박스 틈이 없다». 4 를 주면 카드가 그만큼 커진다. */
.bi-do2-wrap .bi-do2-statwrap { margin-top: 0; }                      /*  4 → 0  (시안: 칩에 붙는다) */
/* ⚠ 다만 «목록 자체» 에는 위 여백 4 가 있다 — 시안의 첫 줄 잉크가 칩 줄에서 11 떨어져 있고
     줄(44) 안에서 아바타(30)가 가운데면 7 이므로 4 가 남는다. 카드는 커지지 않는다
     (max-height 는 border-box 라 여백을 창 «안» 에서 먹는다). */
.bi-do2-wrap .bi-do2-stat { padding-top: var(--space-1); }            /* 시안: 목록 위 4 */
/* §61-39 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-40 · 현황 목록 창을 좌패널이 «담을 수 있는 만큼» 으로 (2026-09-17)
   ──────────────────────────────────────────────────────────────────────
   §61-39 로 현황 카드가 13px 길어졌다(시안의 두 틈). 아바타를 4 줄이는 것으로는
   카드가 줄지 않는다 — 목록에 `max-height` 가 걸려 «창» 이 고정이기 때문이다.
   그래서 좌패널이 17px 넘쳐(목업 clientH 768 · scrollH 785) 낮은 창에서
   「기본 규칙으로 되돌리기」 가 다시 접혔다 — §61-35 에서 고친 그 증상이다.

   ⚠ «한 자리만 보고 고치면 다른 자리가 깨진다.» 세로는 «합» 으로 본다:
       카드 넷 38 + 238 + 259 + 190 = 725 · 틈 3×12 + 패널 여백 32 = 68 → 793 > 768
     목록 창을 17 줄이면 정확히 담긴다(160 → 143).
   ⚠ 시안도 목록을 «넷째 줄이 반쯤 보이는» 창으로 쓴다 — 줄 키 44 이므로
     143 = 세 줄(132) + 넷째 줄 11px. 흐려지는 덧칠(`.bi-do2-statwrap::after`)이 그 위를 덮는다. */
/* ⚠ 2026-09-17 — 143 은 «위 카드들이 더 먹고 있던 상태» 에서 남은 자리였다.
     §61-43 으로 검색칸·달력·패널여백을 시안대로 되돌리자 자리가 생겼다.
     시안의 목록 조각은 167(= 창 155 + 카드 아래여백 12) 이다 → 창을 155 로. */
.bi-do2-wrap .bi-do2-stat { max-height: 155px; }   /* 160 → 143 → 155 (시안 조각 167 − 여백 12) */
/* §61-40 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-41 · 칩 줄이 구른다는 것을 «보이게» 한다 (2026-09-17)
   ──────────────────────────────────────────────────────────────────────
   실제 캡처를 눈으로 보고 잡았다 — 칩 줄이 좌패널(295)보다 **26px 넘쳐**
   마지막 칩이 글자 중간에서 잘려 있었다. 구르게 만든 것은 의도지만(§61 D10 —
   칩이 하나 더 있으면 세로 리듬이 무너진다) **구른다는 표시가 없어 «깨진 것» 처럼 보인다.**

   ⚠ 칩 여백을 줄여 다섯을 억지로 끼우지 않는다 — 칩 크기는 시안 실측이다(키 22 · 여백 10).
     칸을 줄이는 대신 «더 있다» 를 알린다.
   ⚠ 구르는 상자에 `::after` 를 얹으면 내용과 함께 밀려 끝에서도 그늘이 남는다.
     그래서 background-attachment 를 «local + scroll» 로 겹친다 —
     끝까지 구르면 local 층(바탕색)이 scroll 층(그늘)을 덮어 그늘이 스스로 사라진다.
   ⚠ 바탕«색» 은 17664 의 선언을 그대로 쓴다(여기서는 image·position·size 만 준다). */
.bi-do2-wrap .bi-bk2-card__t + .bi-do2-chips {
    background-image:
        linear-gradient(to left, var(--do-bg-page) 45%, rgba(245, 246, 249, 0)),
        linear-gradient(to left, rgba(17, 24, 39, .22), rgba(17, 24, 39, 0));
    background-position: right center, right center;
    background-size: 30px 100%, 18px 100%;
    background-repeat: no-repeat;
    background-attachment: local, scroll;
}
/* §61-41 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-42 · 미니달력 날짜 글자색 — 시안을 칸마다 재서 둘을 고쳤다 (2026-09-17)
   ──────────────────────────────────────────────────────────────────────
   크롭을 눈으로 보다 지난달 「30」 에 **붉은 기** 가 남은 것을 발견하고, 35칸 전부를
   두 그림에서 재 봤다(`_do_caldays.mjs` — 칸 자리는 목업 DOM, 색은 «칸에서 가장 진한 픽셀»):

   | 갈래 | 시안 | 옛 규격안 | 무엇이었나 |
   |---|---|---|---|
   | 평일 날짜 (20칸) | **#374151** | #111827 | 시안은 한 단 **연하다**(`--txt-secondary`) |
   | 지난달 «일요일» 30 | **#EF9D9D** | #D1D5DB | 시안은 주말 색을 **옅게 유지**한다 |
   | 다음달 «토요일» 3 | **#99AFED** | #D1D5DB | 같다 |

   ⚠⚠ **어느 검사도 이것을 보지 않았다.** 답안지는 일요일·토요일·「지난달 회색」 세 색만 못박았고,
     그 「지난달 회색」 은 **우리 동작을 그대로 적은 것**이라 목업과도 맞아 `spec_mock_check` 가
     «다름 0» 을 냈다. 평일 색은 아예 항목이 없었다 —
     **답안지가 «내가 적어 둔 것» 만 잰다는 한계가 여기서 드러났다.**
   ⚠ 옅은 주말색은 «섞은 값» 이다 — 빨강/파랑을 흰 바탕에 45% 로 얹은 색이다:
       #DC2626 45% + #FFF 55% = (239,157,157) = #EF9D9D
       #1D4ED8 45% + #FFF 55% = (153,175,238) = #99AFED
     `color-mix()` 대신 값을 박는다 — QC 의 색 읽기가 `color(srgb …)` 를 한 번 물었던 자리다.
   ⚠ 달력은 예약일정표와 «공유하는 부품» 이지만, 이 절은 `.bi-do2-wrap` 안에서만 바꾼다 —
     예약 화면은 자기 시안(d1·d2.png)이 따로 있다. 이미 §61-10 이 같은 방식으로
     일요일·토요일 색을 이 화면에만 주고 있다. */
:root {
    --do-sidecard-gap2: 11px;    /* 시안 실측 — 카드 사이 11 (옛 --do-sidecard-gap 12) */
    --do-cal-out-sun: #EF9D9D;   /* 시안 실측 — 일요일 빨강 45% */
    --do-cal-out-sat: #99AFED;   /* 시안 실측 — 토요일 파랑 45% */
}
/* ⚠⚠ 순서까지 맞춰 쓴다 — 처음에 «기본 색» 한 줄만 더했더니 앞(17652~17654)의
     일요일·토요일·지난달 규칙이 **같은 특이도(0,2,0)에 더 앞** 이라 내 줄이 이겨
     주말이 회색이 되고 지난달이 진해졌다(35칸 중 12칸이 어긋났다).
     그래서 갈래 넷을 이 절 안에서 «다시» 선언한다 — 여기서는 순서가 규칙이다.
     (is-today·is-realtoday 는 (0,3,0) 이라 안 밀린다) */
.bi-do2-wrap .bi-bk2-cal__d { color: var(--txt-secondary); }                 /* #111827 → #374151 */
.bi-do2-wrap .bi-bk2-cal__d--sun { color: var(--color-danger-600); }         /* 다시 (내 줄에 밀리지 않게) */
.bi-do2-wrap .bi-bk2-cal__d--sat { color: var(--color-info-700); }
.bi-do2-wrap .bi-bk2-cal__d--out { color: var(--gray-300); }
.bi-do2-wrap .bi-bk2-cal__d--out.bi-bk2-cal__d--sun { color: var(--do-cal-out-sun); }
.bi-do2-wrap .bi-bk2-cal__d--out.bi-bk2-cal__d--sat { color: var(--do-cal-out-sat); }
/* §61-42 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-43 · 좌패널 네 카드의 «키 배분» 을 시안대로 (2026-09-17)
   ──────────────────────────────────────────────────────────────────────
   좌패널 세로 합은 768 로 정해져 있다(카드 826 − 툴바 59). 그 합을 네 카드가 어떻게
   나누는지를 시안에서 재려면 카드 경계를 알아야 하는데, 그 자가 두 판 내내 흔들렸다.
   달력 카드는 «안에 깔린 띠» 가 없어 흰 덩이로 잡힌다는 것을 알고 나서 전부 읽혔다
   (`_do_calbox.mjs` — 근무현황만 칩 줄 때문에 두 조각으로 나뉘므로 둘을 더한다):

   | 카드 | 시안 | 옛 규격안 |
   |---|---|---|
   | 검색칸 | **36** | 38 |
   | 미니달력 | **236** | 238 |
   | 근무현황 | **245** (윗조각 34 + 칩 44 + 목록조각 167) | 242 |
   | 기본 근무 규칙 | **195** | 196 → (내가 190 으로 줄였다가 되돌림) |
   | 패널 위여백 | **13** | 16 |

   ⚠ 목록 창이 시안보다 좁았던 것(143 vs ≈155)은 목록 자체의 흠이 아니라
     **위의 카드들이 2~3px 씩 더 먹고 있었기 때문**이다. 한 자리만 보고 목록을 줄이면
     4번째 줄이 시안보다 덜 보이고(실제로 그랬다), 늘리면 패널이 넘친다.
     **합을 보고 배분을 고친다.**
   ⚠ 검색칸·달력은 예약일정표와 공유하는 부품이라 `.bi-do2-wrap` 안에서만 바꾼다. */
/* 시안 실측 — 패널 위여백 13 · 카드 사이 틈 13/11/11(고르지 않다) → 11 로 두고
   첫 틈만 2 더한다. 합이 시안과 맞아야 마지막 카드가 접히지 않는다. */
.bi-do2-wrap .bi-bk2-side { padding-top: var(--space-3); gap: var(--do-sidecard-gap2); }
.bi-do2-wrap .bi-bk2-side > .bi-bk2-search + .bi-bk2-card { margin-top: var(--space-0_5); }   /* 첫 틈 11 → 13 */
/* ⚠ 검색칸의 키는 «감싸개» 가 아니라 input 이 정한다 —
     16585 의 `.bi-do2-wrap .bi-bk2-search > input { height: 38px }` 가 (0,2,1) 이므로
     감싸개에 36 을 줘도 안쪽 input 38 이 삐져나온다(처음에 그래서 안 먹었다). */
.bi-do2-wrap .bi-bk2-side .bi-bk2-search,
.bi-do2-wrap .bi-bk2-side .bi-bk2-search > input { height: 36px; }        /* 38 → 36 (시안) */
/* ⚠ 요일줄의 이름은 «dowrow» 다 — `.bi-bk2-cal__dow` 는 «칸 하나» 다(처음에 헷갈렸다).
     그리고 줄 키를 정하는 것은 여백이 아니라 17465 의 `min-height: 18px` 다 —
     `padding: 3px 0` 을 줬더니 그 위에 더해져 줄이 **20 으로 커졌다**(2026-09-17).
     고칠 자리는 min-height 다. */
.bi-do2-wrap .bi-bk2-cal__dowrow .bi-bk2-cal__dow { min-height: 16px; }   /* 18 → 16 → 달력 카드 −2 */
/* §61-43 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-44 · 기간 팝업 직급칩 — 칩 사이 틈 (2026-09-17)
   ──────────────────────────────────────────────────────────────────────
   직급칩 다섯은 **두 판 내내 재지 않고 있었다.** 픽셀 표가 「칩 개수 0 / 0 ✔」 로
   «양쪽 다 못 찾은 것» 을 같다고 통과시켰기 때문이다(내가 체크리스트에 적어 둔 그 함정).
   자를 «고른 칩의 보라 네모» 로 바꾸고 나서야 일곱 자리가 읽혔다:

   | 자리 | 시안 | 규격안 |
   |---|---|---|
   | 칩 줄 top | 118 | 118 ✔ |
   | 칩 키 | 28 | 26 ✔ |
   | 개수 | 5 | 5 ✔ |
   | 첫 칩 좌 / 폭 | 22 / 48 | 22 / 47 ✔ |
   | **칩 사이 틈** | **12** | 11 ← 고침 |
   | 줄 오른쪽 끝 | 303 | 294 (틈 4 + 글자 폭 5) |

   ⚠⚠ 「칩 사이 틈 12」 를 그대로 믿어 gap 을 12 로 줬더니 측정값이 **17** 이 됐다.
     자가 알약 «위쪽»(글자 위)에서 재기 때문이다 — 둥근 모서리(반경 13)의 들여쓰기 ≈4 와
     테두리 1 이 더해져 **측정값 = CSS 틈 + 5** 다. 시안의 12 도 같은 자로 잰 값이니
     시안의 CSS 틈은 ≈7 이고, 우리 6 과는 **1px 차이**였다 — 고칠 일이 아니었다.
     → gap 은 6 그대로 두고, **자를 고쳤다**(틈은 알약 «가운데 줄» 에서 잰다. 그 높이엔
       모서리 들여쓰기가 없다. 개수는 글자에 쪼개지므로 위쪽에서 센다 — 둘을 따로 잰다).
   ⚠ 남는 5px(줄 오른쪽 끝)은 «글자 폭» 이다 — 라벨이 각 1px 씩 좁다(자간·힌팅).
     여백을 늘려 맞추면 칩 하나하나가 시안보다 커진다. 그 자리는 틈을 넓혀 둔다. */
/* gap 은 옛 선언(16390 · --space-1_5 = 6)을 그대로 쓴다 — 여기서 덮지 않는다 */
/* §61-44 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-45 · 아바타는 «사람마다 다른 색» 이다 (2026-09-17)
   ──────────────────────────────────────────────────────────────────────
   기간 팝업 목록 크롭을 눈으로 보다 세 번째 아바타가 밝은 것을 발견하고 자리마다 쟀다
   (`_do_avacolor.mjs` · `_do_ava2.mjs` — 자리는 목업 DOM, 색은 그림의 채움):

   | 줄 | 시안 | 우리(옛) |
   |---|---|---|
   | 1 리나 | **#1E3A8A** 남색 | #1E3A8A |
   | 2 시우 | **#3B4A7A** 슬레이트 | #1E3A8A |
   | 3 은서 | **#5B6B8F** 밝은 슬레이트 | #1E3A8A |

   우리는 `.bi-do2-av` 한 색으로 여덟 줄을 다 칠하고 있었다 —
   **아바타로 사람을 가리는 시안의 뜻이 사라진다.**
   ⚠⚠ 어느 검사도 이것을 보지 않았다. 답안지는 「행 · 아바타 채움 #1E3A8A」 를 못박았는데
     그 «첫 줄» 만 맞으면 통과다. 픽셀 표도 「아바타 좌」(자리)만 봤다.
   ⚠ 장치를 새로 만들지 않는다 — 예약일정표가 이미 `--ava` + `.bi-bk2-ava--c0…c7` 로 돌린다
     (`:14044`). 같은 방식으로 `--c0/c1/c2` 만 둔다. 색은 이 화면 시안 실측값이고
     예약 쪽(§82-1, 같은 날 다른 세션이 손보는 중)과 «따로» 둔다 — 세 번째 색이 다르다
     (휴무설정 #5B6B8F · 예약 #6B7280). */
:root {
    --do-ava-c0: #1E3A8A;   /* 시안 실측 — 남색 */
    --do-ava-c1: #3B4A7A;   /* 시안 실측 — 슬레이트 */
    --do-ava-c2: #5B6B8F;   /* 시안 실측 — 밝은 슬레이트 */
}
.bi-do2-wrap .bi-do2-av,
.bi-do2-pop .bi-do2-av { background: var(--ava, var(--do-ava-c0)); }
.bi-do2-wrap .bi-do2-av--c0, .bi-do2-pop .bi-do2-av--c0 { --ava: var(--do-ava-c0); }
.bi-do2-wrap .bi-do2-av--c1, .bi-do2-pop .bi-do2-av--c1 { --ava: var(--do-ava-c1); }
.bi-do2-wrap .bi-do2-av--c2, .bi-do2-pop .bi-do2-av--c2 { --ava: var(--do-ava-c2); }
/* §61-45 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §78-6 · 매출등록 — 자료가 늘어도 «판» 은 늘어나지 않는다 (2026-09-16 · 2차 교정)

   사용자 지적 ①: 「결제 대기가 많은 경우 계속 길어지는데 화면 이상이면 **스크롤이 생겨야지**
     왜 계속 화면을 길게 늘어뜨려. 시술 및 상품 내역도 마찬가지 — 전표에 상품 선택한게 없을때
     에서 상품을 추가하면 왜 상품리스트 크기가 달라져. 스크롤이 생기든지 하고 크기는 그대로야지.
     최근내역/보유정액권도 마찬가지고」
   사용자 지적 ②: 「**시안과 규격안이 달라 그래서 실제도 안되었어**」

   ⚠ 1차 교정이 틀렸다 — 카드를 «화면 전체» 로 늘렸다(래퍼의 키를 flex 로 내려보냄).
     자료가 늘어도 판이 안 늘어나긴 했지만, **시안의 카드는 화면을 채우지 않는다.**
     실측: 시안 카드 826(그림 키 1103 — 아래로 200 남는다) vs 1차 교정한 실제 1218.
     시안은 «내용 높이» 이고, 늘어날 수 있는 두 목록에 **키가 박혀** 있다.

   시안 실측 (색 바뀜 훑기 · 판 원점 x272 y72)
     대기 목록 영역      y 291..853 → **562**   (카드 5장 365 + 빈 자리 198 · 바닥요약은 아래 붙음)
     내역표 줄 영역      y 428..595 → **168**   (3줄 × 56)
     최근내역 흰 카드    y 701..821 → **120**   (3줄 × 40)
     최근내역 연회색 판  y 652..897            (카드 바닥까지 · 그 안에 흰 카드)

   그래서 이렇게 한다
     · 카드는 «내용 높이» — 늘리지 않는다(1차 교정의 flex 사슬을 걷어냈다)
     · 늘어나는 두 목록(내역표 줄·최근내역 목록)에 **키를 박고** 스크롤 → 카드 키가 자료와 무관해진다
     · 대기 목록은 «열이 격자 줄 키만큼 늘어나므로» flex:1 + min-height:0 로 남은 키를 먹는다
   ⚠ `min-height:0` 을 빠뜨리면 flex 자식이 내용보다 작아지지 않아 overflow 가 «먹은 척» 한다.
   ------------------------------------------------------------------ */

/* 열 — 격자 줄 키만큼 늘어난다(.bi-bs2-cols 는 이미 align-items:stretch) */
.bi-bs2 .bi-bs2-cols { min-height: 0; }
.bi-bs2 .bi-bs2-q, .bi-bs2 .bi-bs2-mid, .bi-bs2 .bi-bs2-slip { min-height: 0; }

/* ① 결제 대기 — 머리·탭·검색·바닥요약은 붙어 있고 «카드 목록» 만 스크롤한다.
      ⚠ 이 목록의 키(시안 562)가 **카드 키 826 을 정한다** — 세 열 중 대기 열이 가장 높고,
        가운데 열은 거기까지 늘어나며 최근내역 판이 남는 키를 먹는다(시안 그대로).
        그래서 여기에 키를 «박는다» — flex:1 로 두면 카드가 773 이 되어 시안보다 53 짧았다. */
.bi-bs2 .bi-bs2-q__hd, .bi-bs2 .bi-bs2-qtabs,
.bi-bs2 .bi-bs2-qsearch, .bi-bs2 .bi-bs2-qfoot { flex: 0 0 auto; }
.bi-bs2 .bi-bs2-qlist { flex: 0 0 auto; height: 562px; min-height: 0; overflow-y: auto; }

/* ② 시술·상품 내역 — 줄 영역의 키를 박는다(시안 168 = 3줄 × 56).
      0줄이든 20줄이든 이 상자는 168 이고, 넘으면 스크롤한다. */
.bi-bs2 .bi-bs2-bill { flex: 0 0 auto; display: flex; flex-direction: column; }
.bi-bs2 .bi-bs2-bill__hd, .bi-bs2 .bi-bs2-bill__ft { flex: 0 0 auto; }
.bi-bs2 .bi-bs2-bill__scroll { height: 168px; flex: 0 0 auto; overflow-y: auto; overflow-x: auto; }

/* ③ 최근내역 · 보유 정액권 — 시안은 «연회색 판 안에 흰 목록 카드» 다.
      판  : 가운데 열 전폭(시안 x 603..1461 — 열 여백을 음수 마진으로 뚫는다) · 바탕 #F5F6F9 ·
            여백 16 · 카드 바닥까지 늘어난다(y 652..897)
      탭줄: 그 연회색 위에 칩만 — 판 자체의 바탕·테두리는 없다
      목록: 흰 카드(테두리 #E5E7EB · 반경 8) · 키 120 = 3줄 × 40 · 넘으면 스크롤 */
.bi-bs2 .bi-bs2-info {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
  margin: 0 calc(-1 * var(--space-4)) calc(-1 * var(--space-4));
  padding: var(--space-4);
  /* ⚠ 2026-09-17 정정 — 「토큰에 없다」 가 «틀렸다». --pop-band(#F5F6F9)가 이미 있다
     (결제 팝업 작업에서 같은 함정에 걸려 만든 토큰 · style.css :root). 색 팔레트 검사가
     「시안 #F5F6F9 117,060 화소 ↔ 규격안 #F3F4F6」 로 큰 소리로 알렸는데도 «거리 7» 이라며
     넘겼다. 눈에 안 보이는 3채널 차이가 «화면에서 가장 넓은 면» 에 깔려 있었다. */
  background: var(--pop-band);
  border: 0; border-top: 1px solid var(--border-base); border-radius: 0;
}
.bi-bs2 .bi-bs2-info .bi-bs2-tabs {
  flex: 0 0 auto; background: transparent; border-bottom: 0;
  padding: 0 0 var(--space-2);
}
.bi-bs2 .bi-bs2-pnls {
  flex: 0 0 auto; height: 120px; overflow-y: auto;
  background: var(--bg-card); border: 1px solid var(--border-base);
  border-radius: var(--radius-lg);
}

/* 고객카드·필드행·매출메모는 내용만큼 — 줄지도 늘지도 않는다 */
.bi-bs2 .bi-bs2-cust, .bi-bs2 .bi-bs2-frow, .bi-bs2 .bi-bs2-memo { flex: 0 0 auto; }

/* 전표 열 — 수단 줄이 늘어도(최대 5) 푸터는 바닥에 붙어 있다 */
.bi-bs2 .bi-bs2-slip__hd, .bi-bs2 .bi-bs2-sum, .bi-bs2 .bi-bs2-final,
.bi-bs2 .bi-bs2-paylb, .bi-bs2 .bi-bs2-tiles, .bi-bs2 .bi-bs2-prows { flex: 0 0 auto; }
.bi-bs2 .bi-bs2-foot { flex: 0 0 auto; margin-top: auto; }

/* §78-6 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §77 상품 추가(p1) — 검색·칩을 «왼쪽 칸 안» 으로 (2026-09-16)

   사용자: 「상품추가 팝업에 경우 … **담은상품 영역이 시안과 다르다**는거야
            상품명 검색하는부분과 담은상품이 나눠저야하는데 **하나로 되어있잖아**」
           「상품추가에 카데고리도 **간격이 안맞잖아**」

   시안 p1.png 실측 —
     좌우 분할 : 왼쪽 0~538 · 세로 구분선 x=539(#E5E7EB) · 오른쪽 540~880(폭 340)
     왼쪽 머리 : 회색 판 #F5F6F9 · y 56~197(키 142) · 안 여백 위12 좌우16 아래8
                 검색칸 36 → 사이 14 → 갈래칩 32 → 사이 8 → 분류칩 32
     분류 칩   : 왼16 폭 48·36·36·48·60·60·48 · 사이 6   (우리는 칩마다 4 넓었다)
     목록 줄   : 키 50                                   (우리는 55)

   ⚠ 전에는 검색·칩이 «전폭 머리» 였다. 그래서 오른쪽 「담은 상품」 이 그 아래에서
     시작해, 두 영역이 나뉘어 보이지 않았다.
   ⚠ 옛 주석이 「검색·갈래·분류까지 묶으면 세로 흐름이 깨진다(상품명이 한 글자씩 쌓였다)」
     고 경고했는데, 그 까닭은 **묶어서** 가 아니라 flex 자식에 `min-width:0` 이 없어서였다.
     여기서는 왼쪽 칸(.bi-bp2__cnt)이 이미 `min-width:0` 을 갖는다.
   ══════════════════════════════════════════════════════════════════════ */

/* ── §77-1 왼쪽 칸의 «회색 판» — 검색 + 갈래 + 분류 ─────────────────── */
.bi-bp2__lhd{
    flex: 0 0 auto;
    background: var(--pop-band);
    border-bottom: 1px solid var(--border-base);
    padding: var(--space-3) var(--space-4) var(--space-2);
    box-sizing: border-box;
}
/* 판 안에서는 조각들이 제 여백을 갖지 않는다 — 판의 여백만 쓴다.
   ⚠ `.bi-pop-cat-tools` 는 **margin-bottom:16** 도 갖는다. padding 만 0 으로 두면
     판이 16 길어진다(시안 142 → 우리 158 이었다). */
/* ⚠ 2026-09-17 — 판 안 «검색칸 → 칩 줄» 사이가 시안 8 인데 규격안 13 · 실제 1 로 서로도 달랐다
   (판 키가 시안 102 · 규격안 106 · 실제 94 로 셋 다 어긋난 까닭). 판 안에서는 값을 못 박는다. */
.bi-bp2__lhd > .bi-pop-search{ padding: 0; margin-bottom: var(--space-2); }
.bi-bp2__lhd > .bi-pop-cat-tools{ padding: var(--space-3_5) 0 0; margin-bottom: 0; }
/* ⚠ 2026-09-17 — pd1·pd2 의 칩 줄(.bi-pop-filters)은 좌우 18 을 제 안에 갖고 있어
   판 여백(16) 위에 더해져 칩이 35 에서 시작했다(시안 20). 판 안에서는 판의 여백만 쓴다. */
.bi-bp2__lhd > .bi-pop-filters{ padding-left: 0; padding-right: 0; }
/* 시안 — 검색칸 36 (우리는 38 이었다) */
.bi-bp2__lhd .bi-pop-search__box{ height: 36px; }
/* 시안 — 분류 칩 줄은 갈래 칩과 «같은 왼쪽»(16)에서 시작한다.
   기본 규칙이 왼쪽 10 을 더 주어 27 에서 시작하고 있었다. */
.bi-bp2__lhd .bi-pop-catalog .bi-pop-chip-ul,
.bi-pop-catalog .bi-bp2__lhd .bi-pop-chip-ul{ padding-left: 0; }

/* ── §77-2 시안 치수 — 칩이 4 넓었다(좌우 여백 2씩) ────────────────── */
/* 시안 「전체」 48 · 「컷」 36 · 「드라이」 60 — 우리는 52 · 40 · 64 였다.
   ⚠ 여백은 «안쪽 div» 가 아니라 **li** 가 갖는다(`> li > div{padding:0}`).
     처음에 div 에 넣었더니 20 이 **더해져** 72 로 되레 넓어졌다 — 「기타」 가 줄바꿈됐다. */
.bi-bp2__lhd .bi-pop-catalog .bi-pop-chip-ul > li,
.bi-pop-catalog .bi-bp2__lhd .bi-pop-chip-ul > li{ padding-left: var(--pop-pill-pad-sm); padding-right: var(--pop-pill-pad-sm); }
/* 시안 pd1 칩 48·48·48·72 · pd2 75·75·63 — 우리는 52·52·52·78 / 83·82·70 로 칩마다 4~8 넓었다.
   거르개 칩(.bi-pop-fchip)도 같은 여백을 쓴다. */
.bi-bp2__lhd .bi-pop-fchip{ padding-left: var(--pop-pill-pad-sm); padding-right: var(--pop-pill-pad-sm); }

/* ── §77-2-2 회색 판 위의 검색칸은 «흰색» ──────────────────────────── */
/* 시안 pd1·pd2·pd3·p1 모두 검색칸 바탕이 #FFFFFF 다. 우리는 --bg-input(#F9FAFB)이라
   회색 판(#F5F6F9) 위에서 칸이 묻혔다 — 판을 넣고 나서야 드러났다. */
/* ⚠ 2026-09-17 — 처음엔 input 까지 흰색으로 칠했다. input 은 둥근 모서리가 없고 상자보다 커서
   **흰 사각형이 둥근 검색칸을 뚫고 나왔다**(사용자: 「검색창이 깨졌잖아」).
   칠하는 것은 «상자» 뿐이고 input 은 비운다. */
.bi-bp2__lhd .bi-pop-search__box{ background: var(--bg-card); }
.bi-bp2__lhd .bi-pop-search__box input.bi-input{ background: transparent; }

/* ── §77-3 목록 줄 — 시안 50(우리는 55) ────────────────────────────── */
.bi-pop-catalog .bi-pop-prod-ul > li.bi-pop-tbl-row{ min-height: 50px; }

/* ══ §82 시안의 파랑은 «--color-info-700 #1D4ED8» 이다 (2026-09-17) ══════════════
   사용자: 「시안과 규격안 비교부터 … 기능 및 디자인이 다른지 처음부터 다시 검수」

   픽셀로 세어 보니 시안 넷(db1·newai1·d1·d2)에 --brand-blue(#0023B7)와
   --brand-navy(#00156E)는 «0픽셀» 이다. 파랑은 전부 #1D4ED8, 남색은 #1E3A8A —
   둘 다 이미 등록된 값이다(--color-info-700 / 휴무설정의 --do-ava-navy 와 같은 색).

   | 시안 | 픽셀 | 실제가 쓰던 것 |
   |---|---:|---|
   | #1D4ED8 | db1 4,582 · newai1 11,428 · d1 4,945 · d2 5,026 | --brand-blue #0023B7 |
   | #1E3A8A | d1 1,224 · d2 1,224 (디자이너 아바타) | --brand-navy #00156E |

   ⚠ --brand-blue 자체는 건드리지 않는다 — 앱 전체(차트·체크박스·링크 수십 곳)가 쓴다.
     «이 화면 안에서만» 토큰을 갈아 끼운다. 휴무설정이 이미 같은 방식이다(§61 --do-ava-navy).
     규격안 목업도 이 style.css 를 불러 쓰므로 같은 클래스를 달면 함께 움직인다. */
.bi-bk2-wrap,
.bi-ai2-frame {
    --brand-blue: var(--color-info-700);   /* #1D4ED8 — 시안 실측 */
}
.bi-bk2-wrap {
    --brand-navy: #1E3A8A;                 /* 디자이너 아바타 c0 — 시안 실측(휴무설정 --do-ava-navy 와 같다) */
}

/* ── §82-1 시안 실측 — 아바타 둘째 색 · 네이버 표식 (2026-09-17) ──────────────
   시안 d2.png 을 잘라 보면 디자이너 아바타는 «남색 #1E3A8A · 슬레이트 #3B4A7A» 두 톤이다.
   실제는 c1 이 --brand-blue(밝은 파랑)라 시안보다 튀었다. 시안 값으로 맞춘다.

   네이버 표식은 시안이 «네이버 초록 #03C75A»(886px) 인데 규격안·실제 둘 다
   --color-success-500(에메랄드 #10B981) 을 쓰고 있었다. 쓸 토큰이 이미 있다 — --color-npay. */
.bi-bk2-wrap .bi-bk2-ava--c1 { --ava: #3B4A7A; }          /* 시안 실측 — 슬레이트 */
.bi-bk2-wrap .bi-bk2-src__ico--n,
.bi-bk2-wrap .bi-bk2-tag--n { background: var(--color-npay); }   /* 시안 실측 #03C75A */
/* 아바타 셋째 색 — 시안·규격안 모두 #6B7280(--gray-500) 인데 실제만 --txt-secondary(#374151) 였다.
   «이번엔 실제가 틀렸다» — 규격안이 맞았다(2026-09-17 픽셀 실측 1,053px). */
.bi-bk2-wrap .bi-bk2-ava--c2 { --ava: var(--gray-500); }

/* ══════════════════════════════════════════════════════════════════════
   §78-7 · 매출등록 — «판 키 826» 을 되찾는 골격 교정 (2026-09-17 · 5차)

   사용자: 「시안과 규격안 비교부터 qc가 잘못된건 없는지 기능 및 디자인이 다른지
     처음부터 다시 검수 시작하고 문제있으면 바로 수정하고 결과 브라우저에 띄워줘」

   ⚠ 앞 네 회차가 못 잡은 까닭 — «판 키» 를 아무도 시안과 견주지 않았다.
     _bs2_full3.mjs 는 세 장을 폭 1616 으로 «다시 그려» 붙이므로 규격안 850 이 842 로
     찍혀 있었다. 실제 값은 **시안 1616×826 · 규격안 1632×850 · 실제 1632×850** 이다.
     (폭 16 은 쉘의 페이지 여백이라 이 화면 것이 아니다. 키 24 는 이 화면 것이다.)

   시안 그림에서 다시 잰 값 (_bs2_ruler.mjs · 판 원점 x272 y72 · 세로선 x280=열 여백)
     판 제목 줄        판y   1..55   → 56 (55 + 아래선)        우리 52
     대기 머리         판y  57..112  → 57 (56 + 아래선)        우리 27 + 열여백
     대기 탭·검색 판   판y 114..217  → 105 (104 + 아래선)      우리 둥근 트랙 54 + 흰 검색 36
       └ 여백 12 · 칩 32 · 틈 10 · 검색 38 · 여백 12 · **바탕 #F5F6F9 · 전폭**
     대기 목록         판y 219..780  → 562                     우리 562 ✓
     대기 바닥요약     판y 782..823  → 43 (42 + 위선) · **전폭 · 카드 바닥에 붙는다**
                                                               우리 45 · 여백 안쪽 · 아래 16 남김
     고객 줄           판y  73..117  → 48 · **테두리·바탕·여백 없다**   우리 85 테두리 카드
   합 56 + (57+105+562+43) + 테두리 2 = **826** ✓

   왜 «열 여백» 을 걷어내고 띠마다 주나 — 시안의 구분선이 **열 전폭**이다(x 272..602).
     열에 padding:16 을 두면 선이 여백 안쪽으로 들어가 시안과 달라진다.
   ------------------------------------------------------------------ */

/* 판 제목 줄 — 시안 55(+아래선) · 여백 14 (12 였다) */
.bi-bs2 .bi-bs2-top { padding: var(--space-3_5) var(--space-4); }

/* 대기 열 — 여백을 걷고 띠마다 준다(구분선이 전폭이어야 한다) */
.bi-bs2 .bi-bs2-cols > .bi-bs2-q { padding: 0; gap: 0; }
.bi-bs2 .bi-bs2-q > .bi-bs2-q__hd { height: 57px; padding: 0 var(--space-4);
  border-bottom: 1px solid var(--border-base); }

/* 탭 + 검색은 시안에서 «하나의 연회색 판» 이다 — 마크업에 .bi-bs2-qpanel 을 더했다 */
.bi-bs2 .bi-bs2-qpanel { flex: 0 0 auto; display: flex; flex-direction: column;
  gap: var(--space-2_5); padding: var(--space-3) var(--space-4);
  background: var(--pop-band); border-bottom: 1px solid var(--border-base); }
/* 판 안에서는 트랙 자체의 테두리·바탕·둥근 모서리를 지운다 — 판이 그 몫을 한다 */
.bi-bs2 .bi-bs2-qpanel > .bi-bs2-qtabs { padding: 0; background: transparent;
  border: 0; border-radius: 0; }

/* 목록 — 키는 그대로 562, 여백만 스스로 갖는다 */
.bi-bs2 .bi-bs2-q > .bi-bs2-qlist { height: 562px; padding: var(--space-3) var(--space-4); }

/* 바닥요약 — 카드 바닥에 붙는다(아래 여백 0) · 키 43 */
.bi-bs2 .bi-bs2-q > .bi-bs2-qfoot { height: 43px; margin: auto 0 0;
  padding: 0 var(--space-4); }

/* 고객 줄 — 시안은 테두리·바탕·여백이 없다(48px 짜리 «줄» 이다).
   ⚠ 미선택 상태(고객명·연락처 입력칸)도 같이 테두리를 잃는다 — 시안이 보여 주는 것은
     선택됨 상태뿐이고, 아래 필드행도 테두리가 없어 둘이 한 결이 된다. */
.bi-bs2 .bi-bs2-mid > .bi-bs2-cust { border: 0; border-radius: 0; padding: 0;
  background: transparent; }

/* 검색칸 — 시안 판y 168..205 → 38 (36 이었다) */
.bi-bs2 .bi-bs2-qpanel > .bi-bs2-qsearch { height: 38px; }

/* ── 가운데 열의 «줄 키» — 시안 실측 (판 원점 x272 y72) ──────────────
   고객 줄        판y  73..120 → 48   (아바타 원이 48 · 두 줄 글이 48)      우리 59
   필드 select    판y 152..185 → 35~36 (테두리가 반픽셀에 걸려 34~36 으로 읽힌다)  우리 40
   성별 세그      판y 151..186 → 36                                        우리 40
   매출메모       판y 217..252 → 36                                        우리 40
   내역표 위선    판y 267                                                  우리 297
   최근내역 판    판y 580..824 → 245                                       우리 208
   ⚠ 답안지가 「필드 입력칸 40 · 세그 40 · 메모 40」 을 «맞다» 고 축복하고 있었다 —
     시안을 재지 않고 적은 값이다. 36 으로 고치고 답안지도 같이 고쳤다. */
.bi-bs2 .bi-bs2-cols > .bi-bs2-mid { gap: var(--space-2_5); }
.bi-bs2 .bi-bs2-mid .bi-bs2-ava { width: 48px; height: 48px; }
.bi-bs2 .bi-bs2-mid .bi-bs2-cust__nm { line-height: 1.15; }
.bi-bs2 .bi-bs2-mid .bi-bs2-cust__meta { margin-top: var(--space-0_5); }
.bi-bs2 .bi-bs2-frow input.bi-bs2-in, .bi-bs2 .bi-bs2-frow select.bi-bs2-in { height: 36px; }
.bi-bs2 .bi-bs2-frow .bi-bs2-seg { height: 36px; }
/* 매출 메모 — 한 줄(rows=1) textarea 다.
   사용자 지적 2026-09-17: 「매출 메모 입력칸이 위아래로 가운데가 아니라서 **입력 전부터
   스크롤이 생겨있어**」 — 키 36 에 위아래 여백 10+10 이라 글줄(13px · 줄높이 ≈20)이
   내용상자(36−20−2=14)에 안 들어가 곧바로 스크롤이 났고 글이 위로 붙었다.
   → 위아래 여백을 0 으로 두고 «줄높이» 로 가운데 맞춘다(34 = 36 − 테두리 2). */
.bi-bs2 .bi-bs2-memo .bi-bs2-memo__ta {
  height: 36px; padding: 0 var(--space-2_5); line-height: 34px; overflow: hidden; }
/* 붙어 있는 검색 단추는 입력칸의 키를 따른다(사다리 예외와 같은 까닭) */
.bi-bs2 .bi-bs2-frow .bi-bs2-selbox__ico { width: 36px; height: 36px; }
.bi-bs2 .bi-bs2-cust .bi-bs2-schbtn { width: 36px; height: 36px; }
.bi-bs2 .bi-bs2-cust input.bi-bs2-in { height: 36px; }

/* ── 수량 스테퍼 · 할인 칩 — 시안 실측 (판 1줄을 가로로 훑어 테두리 좌표를 읽었다) ──
   수량 : abs x 1033·1060·1089·1116 에 #E5E7EB 1px → «칸 셋이 구분선으로 나뉜 한 상자» 다.
          84×28 · 흰 바탕 · 칸 27/29/27.  우리는 «연회색 알약 + 테두리 없음» 이었다.
   할인 : abs x 1144..1231 → 88×30 · 흰 바탕 · 테두리 #E5E7EB · **글자만 빨강**.
          우리는 «테두리까지 빨강» 이었다(.is-on 이 border-color 를 --color-danger 로 준다).
   ⚠ .bi-bs-* 는 옛 POS 와 같이 쓰는 이름이다 — 한 줄도 고치지 않고 «더 긴 선택자» 로 받는다.
     기존: .bi-bs-counter .bi-bs-pro-qty .bi-bs-pro-qty-btn (0,3,0) · 뿌리에 세 이름이 같이 있다
     (.bi-counter-wrap.bi-bs-counter.bi-bs2) 므로 .bi-bs2 는 «자손» 선택자로만 쓴다. */
.bi-bs2 .bi-bs-pro-td .bi-bs-pro-qty {
  height: 28px; gap: 0; background: var(--bg-card);
  border: 1px solid var(--border-base); border-radius: var(--radius-md); overflow: hidden; }
.bi-bs2 .bi-bs-pro-td .bi-bs-pro-qty .bi-bs-pro-qty-btn {
  width: 27px; height: 26px; background: var(--bg-card); color: var(--txt-muted);
  border: 0; border-radius: 0; font-size: var(--fs-xs); }
.bi-bs2 .bi-bs-pro-td .bi-bs-pro-qty .js-bs-pro-qty-minus { border-right: 1px solid var(--border-base); }
.bi-bs2 .bi-bs-pro-td .bi-bs-pro-qty .js-bs-pro-qty-plus { border-left: 1px solid var(--border-base); }
/* ⚠⚠ 2026-09-28 사용자 지시 — 「시술 및 상품 내역에 **상품선택했을때 수량 입력칸 늘려줘**」.
     ‒/+ 단추를 걷었으니 이 칸이 «치는» 자리다. 29 는 단추 사이에 끼어 «보여 주기만» 하던 폭이다.
   ⚠ 앞서 §4692 의 `.bi-bs-pro-input--qty { width: 84px }` 만 고쳤더니 안 먹었다 —
     이 규칙(0,4,1)이 그것(0,1,0)을 이긴다. **이기는 자리에서 고쳐야 바뀐다.**
     실측으로 확인했다: 고치기 전 29px · 고친 뒤 84px. 칸(td)이 107 이라 들어간다. */
.bi-bs2.bi-bs-counter .bi-bs-pro-qty input[type="text"].bi-bs-pro-input--qty {
  width: 84px; height: 26px; border: 0; background: transparent; text-align: center; }
/* 할인 칩 — 테두리는 연회색으로 두고 «글자만» 빨강 */
.bi-bs2 .bi-bs-pro-td--disc .bi-bs-pro-disc-in { width: 88px; }
.bi-bs2 .bi-bs-pro-td--disc .bi-bs-pro-disc-in.is-on {
  /* ⚠ 앞서 테두리·글자색만 받아 «빨강 채움» 이 남아 있었다 —
     .bi-bs-counter .bi-bs-pro-disc-in.is-on(12064 · 0,2,0) 이 background 를
     --color-danger-50 으로 준다. 시안은 «흰 바탕 + 연회색 테두리 + 빨간 글자» 다. */
  background: var(--bg-card); border-color: var(--border-base);
  color: var(--color-danger-600); font-weight: var(--fw-bold); }

/* 최근내역·정액권 탭 — 시안의 «안 고른» 칩은 연회색 판 위의 «흰 알약 + 연회색 테두리» 다
   (시안 abs x 711 에 #E5E7EB · 712 부터 #FFFFFF). 우리는 background:transparent 였다. */
.bi-bs2 .bi-bs2-info .bi-bs2-tab:not(.is-on) {
  background: var(--bg-card); border: 1px solid var(--border-base); }

/* ── 아이콘 크기 — 시안이 «글자보다 작게» 쓴다 (전부열거 대조로 드러났다) ──
   규격안에 Font Awesome 을 실은 뒤 비로소 잴 수 있게 된 자리다. 같은 글리프를 양쪽에서
   재므로 «글리프 대 em 비율» 이 상쇄되고, 잉크 차이가 곧 크기 차이다.
     대기 머리 시계   잉크 16 → 시안 14  (라벨 16 을 그대로 물려받고 있었다)
     신규회원등록 ＋   잉크 11 → 시안  8  (단추 글자 12 를 물려받았다)
     검색 확대경      잉크 12 → 시안 10
     수량 ＋/−        잉크 10 → 시안  7  (9 는 토큰이 아니다 → 10) */
.bi-bs2 .bi-bs2-q__t > i { font-size: var(--fs-md); }                       /* 16 → 14 */
.bi-bs2 .bi-bs2-q__new > i { font-size: var(--fs-2xs); }                    /* 12 → 10 */
.bi-bs2 .bi-bs2-qsearch .bi-bs2-qsearch__ico { font-size: var(--fs-xs); }   /* 12 → 11 */
.bi-bs2 .bi-bs-pro-td .bi-bs-pro-qty .bi-bs-pro-qty-btn > i { font-size: var(--fs-2xs); } /* 11 → 10 */
.bi-bs2 .bi-bs2-sum .bi-bs2-srow > span > i { font-size: var(--fs-2xs); }   /* 14 → 10 */

/* §78-7 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════
   §78-8 · 가운데·우측 열도 «전폭 구분줄로 나뉜 띠» 다 (2026-09-17 · 6차)

   사용자: 「야 시안이랑 규격안이 다르니까 실제가 다르잔아 **이거 기존 css가 문제인거같은데
     왜 계속 그대로 두는거야**. 중앙영역에 고객정보랑 시술상품리스트 영역도 그렇고
     **우측에 구분줄**도 시안과 다른데 수정안해줄거야??」 — 맞다. 재 보니 그대로였다.

   ⚠ 내가 놓친 까닭 — 대기(좌) 열만 «띠» 로 고치고 나머지 둘은 «테두리 카드» 로 두었다.
     자리별 색·글자 대조는 통과하고 판 키도 맞았다. 열의 «여백선» 을 훑어야 드러난다.

   시안 실측 — 열의 «여백선»(열 왼테두리에서 8px 안쪽)을 위에서 아래로 훑은 값
     가운데 열 (판x 338)   판y  57..266 흰색 · **267 전폭선** · 268..579 흰색 · 580..824 연회색
     우측 열   (판x 1198)  판y  57..128 흰색 · **129 전폭선** · 130..765 흰색 · **766 전폭선** · 767..824
     푸터 선은 열 전폭이다 — abs x 1462..1887(426 = 전표 열 폭 그대로)
   우리 것 (고치기 전)
     가운데 열  선이 «하나도» 안 보인다 — 내역표가 여백(16) 안쪽의 «둥근 테두리 카드»(r8)라
                여백선에 걸리지 않는다. 연회색 판은 533 에서 시작(시안 580)
     우측 열    푸터 선은 «있었지만» 여백 안쪽(판x 1222~)이라 시안의 전폭선과 다르다.
                전표 머리 아래 선(판y 129)은 **아예 없었다**

   그래서 좌 열과 «같은 방식» 으로 바꾼다 — 열 여백을 걷고 띠마다 여백·선을 준다.
   ⚠ .bi-bs2-info 는 §78-6 에서 음수 마진으로 여백을 뚫고 있었다 — 열 여백이 0 이 되었으니
     음수 마진을 걷어야 한다(안 걷으면 카드 밖으로 16 삐져나간다).
   ------------------------------------------------------------------ */

/* ── 가운데 열 ── */
.bi-bs2 .bi-bs2-cols > .bi-bs2-mid { padding: 0; gap: var(--space-1_5); }
.bi-bs2 .bi-bs2-mid > .bi-bs2-cust  { padding: var(--space-4) var(--space-4) 0; }
.bi-bs2 .bi-bs2-mid > .bi-bs2-frow  { padding: 0 var(--space-4); }
.bi-bs2 .bi-bs2-mid > .bi-bs2-memo  { padding: 0 var(--space-4) var(--space-2); }
/* 내역표 — 카드가 아니라 «띠» 다: 위에 전폭선 하나, 테두리·둥근 모서리 없음 */
.bi-bs2 .bi-bs2-mid > .bi-bs2-bill {
  border: 0; border-top: 1px solid var(--border-base); border-radius: 0;
  /* 사용자 지적 2026-09-17 ⑨: 「각 영역 들간에 간격들이 시안과 달라보여」 — 재 보니
     내역표 띠가 시안보다 **13 크고** 그만큼 최근내역 판이 **15 작았다**(가운데 열 여백선 실측).
     안쪽을 쪼개 보니 «머리+표머리» 가 +17, «합계줄» 이 −13 이었다 → 여백을 시안 치수로. */
  padding: var(--space-2) var(--space-4) 0; background: transparent; }
.bi-bs2 .bi-bs2-mid > .bi-bs2-bill .bi-bs2-bill__hd { padding: var(--space-1_5) var(--space-3_5); }
.bi-bs2 .bi-bs2-mid > .bi-bs2-bill .bi-bs2-bill__ft { padding: var(--space-4) var(--space-3_5); }
/* 연회색 판 — 열 여백이 0 이 되었으니 음수 마진을 걷는다 */
.bi-bs2 .bi-bs2-mid > .bi-bs2-info { margin: 0; }

/* ── 우측(전표) 열 ── */
.bi-bs2 .bi-bs2-cols > .bi-bs2-slip { padding: 0; gap: var(--space-1_5); }
.bi-bs2 .bi-bs2-slip > .bi-bs2-slip__hd { padding: var(--space-4) var(--space-4) 0; }
/* 전표 머리 아래 전폭선 (시안 판y 129) — 없던 선이다 */
.bi-bs2 .bi-bs2-slip > .bi-bs2-slip__meta {
  padding: 0 var(--space-4) var(--space-1_5);
  border-bottom: 1px solid var(--border-base); }
.bi-bs2 .bi-bs2-slip > .bi-bs2-sum,
.bi-bs2 .bi-bs2-slip > .bi-bs2-final,
.bi-bs2 .bi-bs2-slip > .bi-bs2-paylb,
.bi-bs2 .bi-bs2-slip > .bi-bs2-tiles,
.bi-bs2 .bi-bs2-slip > .bi-bs2-prows { margin-left: var(--space-4); margin-right: var(--space-4); }
/* 푸터 — 선이 «열 전폭» 이고 카드 바닥에 붙는다(시안 판y 766..824 = 59) */
.bi-bs2 .bi-bs2-slip > .bi-bs2-foot {
  margin-top: auto; padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border-base); }

/* 전표 열의 «안쪽» 구분줄 둘 — 열 전폭이 아니라 내용 폭이다.
   시안 실측(판x 1207 을 훑음): 판y **210**(포인트 적립 예정 «위») · 판y **303**(총 결제 금액 «아래»).
   ⚠ 선을 «선불권 결제 줄 아래» 에 달면 선불권이 없는 전표에서 사라진다 —
     그래서 «포인트 적립 예정 위» 에 단다(같은 자리인데 늘 있다). */
.bi-bs2 .bi-bs2-sum > .bi-bs2-srow--acc {
  border-top: 1px solid var(--border-base); padding-top: var(--space-2); }
.bi-bs2 .bi-bs2-slip > .bi-bs2-final {
  border-bottom: 1px solid var(--border-base); padding-bottom: var(--space-2_5); }

/* §78-8 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════
   §78-9 · 최근내역·보유정액권 — 목록은 «늘 3줄 키» · 더보기는 그 아래 (2026-09-17 · 7차)

   사용자: 「① 최근내역, 보유정액권은 **리스트상 3개 나오게 높이를 맞춰줘**.
     2개라고 줄어드는게 아니야. **그 아래 더보기** 넣어줘.
     ② 보유정액권이 상품카테고리/금액, 상품명, 기간 순으로 아래로 나오는데
     **상품 카테고리, 상품명, 금액/잔여, 기간 순으로 가로로** 나오게 해줘」

   ⚠ 전(§78-6)에는 흰 카드(.bi-bs2-pnls)에 키 120 을 박고 그 «안에» 더보기까지 넣었다 —
     그래서 줄이 2개면 목록이 쪼그라들고 더보기가 올라붙었고, 3줄이면 더보기가 밖으로 밀려
     스크롤해야 보였다. 키는 «목록(ul)» 이 갖고, 더보기는 그 아래 «바닥줄» 로 둔다.
   ------------------------------------------------------------------ */

/* 흰 카드는 내용만큼 — 키는 목록이 갖는다 */
.bi-bs2 .bi-bs2-mid .bi-bs2-pnls { height: auto; overflow: visible; }
/* 목록 — 언제나 3줄(40×3) · 넘으면 목록만 스크롤 · 줄이 적어도 줄지 않는다 */
.bi-bs2 .bi-bs2-pnls .bi-bs2-hlist {
  height: 120px; min-height: 120px; overflow-y: auto; overflow-x: hidden; }
/* 더보기 — 목록 «아래» 바닥줄(스크롤 밖) */
.bi-bs2 .bi-bs2-pnls .bi-bs2-more { flex: 0 0 auto; height: 38px; }

/* ── 보유 정액권 줄 — 한 줄 네 칸(분류 · 상품명 · 금액/잔여 · 기간) ── */
.bi-bs2 .bi-bs2-hlist > li.bi-bs2-pkrow { gap: var(--space-2_5); }
.bi-bs2 .bi-bs2-pkcat {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  min-width: 52px; height: 20px; padding: 0 var(--space-1_5);
  border-radius: var(--radius-sm); background: var(--color-indigo-50);
  color: var(--color-info-700); font-size: var(--fs-2xs); font-weight: var(--fw-bold); }
.bi-bs2 .bi-bs2-pknm {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-primary); }
.bi-bs2 .bi-bs2-pkamt {
  flex: 0 0 auto; font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-bs2 .bi-bs2-pkamt b { font-weight: var(--fw-bold); color: var(--txt-primary); }
/* ⚠ 2026-09-22 사용자 지시 — 「이용기간 글자크기를 «잔여» 글자 크기에 맞출 것」.
   잔여(.bi-bs2-pkamt)는 --fs-sm 인데 여기만 --fs-2xs 라 한 줄 안에서 글자가 두 크기였다. */
.bi-bs2 .bi-bs2-pkdt {
  flex: 0 0 auto; font-size: var(--fs-sm); color: var(--txt-disabled); }

/* ── 카탈로그 단추의 «겹친 사진 석 장» · 개수 배지 — 시안 실측 ──
   시안: 카탈로그 왼쪽에 색 있는 네모 석 장이 «겹쳐» 있고, 그 뒤에 개수(3)가 «맨 글자» 로 온다.
     고객메모는 아이콘이 «외곽선»(far)이고 개수는 «호박색 동그라미» 다.
   사용자 지적 2026-09-17: 「시안에는 3개 이상일때 겹친 네모 아이콘 3개가 뜨고
     이미지 개수도 표시하는데 안되고있어」 */
/* 시안 실측(_pick_cat.mjs): 잉크 16×22 · 흰 테 2 · 물림 pitch 18 · 보라 점 8×8.
   ⚠ 16×16 정사각에 테 1 · 물림 6 으로 두었더니 시안의 «세로로 긴 사진 석 장» 과
     전혀 다른 모습이었다. 눈대중으로 정한 값이 두 회차를 지났다 — 그림에서 잰다. */
.bi-bs2 .bi-bs2-cat3 { position: relative; display: inline-flex; align-items: center; flex: 0 0 auto; }
.bi-bs2 .bi-bs2-cat3 > img {
  width: 20px; height: 26px; flex: 0 0 auto; object-fit: cover;
  border: 2px solid var(--bg-card); border-radius: var(--radius-md);
  background: var(--gray-300); }
/* 둘째·셋째 장은 «겹친다» — 흰 테가 2 이므로 −2 면 시안의 pitch 18 이 된다 */
.bi-bs2 .bi-bs2-cat3 > img + img { margin-left: calc(var(--space-0_5) * -1); }
/* 마지막 장 오른쪽 위 보라 점 — 시안 8×8, 오른쪽으로 4 삐져나온다 */
.bi-bs2 .bi-bs2-cat3__ai {
  position: absolute; top: 0; right: -4px; width: 8px; height: 8px;
  border-radius: var(--radius-full); background: var(--bk-run);
  border: 1px solid var(--bg-card); box-sizing: content-box; }
/* AI 알약 — 시안 30×16 · 바탕 #EFEEFF · 글자 #4A37CF 에 가장 가까운 토큰 */
.bi-bs2 .bi-bs2-cust__ai {
  display: inline-flex; align-items: center; height: 16px; padding: 0 var(--space-1_5);
  border-radius: var(--radius-full); background: var(--bk-run-bg);
  font-size: var(--fs-2xs); font-weight: var(--fw-bold); font-style: normal;
  color: var(--color-indigo-700); }
/* ⚠ 두 겹 선택자가 .bi-hidden(한 겹)을 이긴다 — 숨김을 «같이» 선언해야 숨는다(함정 F2).
   2026-09-17: 값 출처가 없어 숨겨 둔 알약이 「AI 0」 으로 화면에 그대로 보였다. */
.bi-bs2 .bi-bs2-cust__ai.bi-hidden { display: none; }
/* 개수 동그라미 — 고객메모는 호박색(시안), 카탈로그는 맨 글자 */
.bi-bs2 .bi-bs2-cust__cnt--warn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: var(--radius-full);
  background: var(--bk-req-bg); color: var(--color-warning-800);
  /* ⚠ --fs-2xs(10) 로 두었더니 「실제가 규격안보다 작다」 로 걸렸다 —
     이 화면 규격안(spec_pos)의 개수 배지는 11 이다(카탈로그 개수와 같은 결). */
  font-size: var(--fs-xs); font-weight: var(--fw-bold); }

/* ── 날짜칩 요일 — 값과 같은 결로 붙인다(시안 「2026-09-01 (화)」) ── */
.bi-bs2 .bi-bs2-datechip .bi-bs2-datechip__dow {
  flex: 0 0 auto; font-size: var(--fs-md); font-weight: var(--fw-bold);
  color: var(--pop-navy); }
.bi-bs2 .bi-bs2-datechip .bi-bs2-datechip__dow:empty { display: none; }
/* 입력칸이 104 라 남는 26 만큼 요일이 오른쪽 끝으로 밀렸다 — 글자 폭에 맞춘다.
   시안은 「2026-09-01 (화)」 가 붙어 있다. */
/* 2026-09-23 사용자 지시 ⑬ — 78 은 「2026-09-23」 마지막 글자가 잘렸다. 82 로 넓힌다
   (접수/시술전표 #rs_date 와 같은 값 — 같은 모양의 날짜칸은 같은 폭이어야 한다). */
.bi-bs2 .bi-bs2-datechip .bi-bs2-datechip__val { width: 82px; flex: 0 0 auto; }
/* 시안은 ＋ 와 글자 사이가 벌어져 있다 */
.bi-bs2 .bi-bs2-newslip { gap: var(--space-1_5); }

/* §78-9 끝 ───────────────────────────────────────────────────────── */

/* ── §82-2 AI 메시지 발송 — 시안 실측 둘 (2026-09-17) ─────────────────────────
   ① VVIP 등급 배지: 시안은 «크림 #FFF6E5 바탕 + 앰버 #8A5A0B 글자» 인데 실제는 보라였다.
      같은 짝이 매출등록 시안에도 쓰였다(§76 «상품» 배지) — 이 프로젝트의 등록된 값이다.
   ② 쪽번호 «지금 쪽»: 시안은 짙은 네이비 #121D3F(--pop-navy) 인데 실제는 --txt-primary(#111827) 였다. */
.bi-ai2-frame { --ai-vvip-tx: #8A5A0B; }                  /* 시안 실측 — 앰버 글자(--do-warn-txt 와 같은 값) */
.bi-ai2-frame .bi-ai-grade--vvip { background: var(--bk-req-bg); color: var(--ai-vvip-tx); }
.bi-ai2-frame .bi-ai2-pg__b.is-on { background: var(--pop-navy); border-color: var(--pop-navy); }

/* ══════════════════════════════════════════════════════════════════════
   §81 검색 팝업의 «아바타» 색 — 시안과 넷이 달랐다 (2026-09-17)

   사용자: 「처음부터 하나하나 확인하는데」 — 요소 전수 대조의 «바탕 차이» 아홉을
   눈으로 갈라 보니 셋이 진짜였고, 그중 둘이 아바타였다.

   시안 실측 —
     pd1 디자이너 검색 · 안 고른 줄 : 바탕 #3B4A7A · 글자 흰색   (우리는 #E5E7EB + 진회색)
     pd1 디자이너 검색 · 고른 줄     : 바탕 #1E3A8A            (우리는 #1D4ED8)
     pd2 고객 검색  · 등급          : 바탕 #D1D5DB · 글자 #4B5563 (우리는 #1D4ED8 + 흰색)

   ⚠ §74-3 에 이미 「등급 아바타는 고른 줄에서도 회색」 규칙이 있었는데 두 가지로 빗나갔다 —
     ① 규격안 목업에 `.bi-pop-list--member` 가 없어 **규칙이 아예 안 걸렸다**(그래서 파랗게 보였다)
     ② 걸리는 실제에서도 색이 `--gray-200`(#E5E7EB)이라 시안(#D1D5DB = --gray-300)과 달랐다
     «규칙이 있다» 가 «그 규칙이 먹는다» 는 뜻이 아니다.
   ══════════════════════════════════════════════════════════════════════ */

/* ⚠ 이름표는 «감싸개 div» 에 붙는다(실제 팝업이 그렇게 한다) — 자식 결합자(>)로 쓰면 안 걸린다.
   `<div class="… bi-pop-list--member"> <ul class="bi-pop-clist"> <li class="bi-pop-clist-item">` */

/* ── §81-1 디자이너 검색(pd1) — 사람 아바타는 짙은 남색이다 ─────────── */
/* ⚠⚠ 2026-09-21 — 리터럴 #3B4A7A 를 토큰으로 뺀다(TK-COLOR).
     검사는 `--do-ava-c1` 을 권하지만 그것은 «휴무설정» 아바타 토큰이라 **값만 같고 뜻이 다르다** —
     팝업이 휴무설정 토큰에 매달리면 한쪽 시안이 바뀔 때 다른 쪽이 조용히 끌려간다.
     그래서 결제 팝업 세션이 스스로 정한 이름 `--pop-avt-emp` 로 «제 이름의» 토큰을 둔다.
   ⚠ 값은 그대로라 화면은 한 픽셀도 바뀌지 않는다. 이름이 마음에 안 들면 그 세션이 바꾸면 된다. */
:root { --pop-avt-emp: #3B4A7A; }   /* pd1 디자이너 아바타 — 시안 실측 */
.bi-pop-list--emp .bi-pop-clist-item .bi-pop-avt{ background: var(--pop-avt-emp); color: var(--bg-card); }
.bi-pop-list--emp .bi-pop-clist-item.is-sel .bi-pop-avt{ background: var(--color-info-900); color: var(--bg-card); }

/* ── §81-2 고객 검색(pd2) — «등급» 아바타는 회색이다(고른 줄에서도) ──── */
/* 시안 #D1D5DB = --gray-300 · 글자 #4B5563 = --gray-600. §74-3 은 --gray-200 을 쓰고 있었다 */
.bi-pop-list--member .bi-pop-clist-item > .bi-pop-avt,
.bi-pop-list--member .bi-pop-clist-item.is-sel > .bi-pop-avt{
    background: var(--gray-300); color: var(--gray-600);
}

/* ── §81-4 카탈로그(pd4) 미리보기 머리의 배지 ────────────────────────
   시안 실측: 바탕 #EEF2FF(= --pop-pill-bg) · 글자 파랑. 우리는 기본 회색 배지였다
   (바탕 #F9FAFB · 글자 #374151). 같은 `.bi-pop-tag` 라도 자리에 따라 다르다 —
   pd1 의 직급 배지는 시안에서도 회색이므로 «미리보기 머리» 안에서만 바꾼다. */

/* ── §81-5 고객 검색(pd2)의 줄은 «60» 이다 — pd1(56)과 다르다 (2026-09-17) ──
   사용자: 「고객검색만 봐도 **실제가 깨져 보이는게** 있잖아」 — 3칸을 눈으로 보고서 나왔다.
   시안 실측: pd1 고른 줄 159~213(56) · **pd2 고른 줄 193~252(60)**.
   pd2 줄에는 «담당 디자이너»(라벨+이름+아바타)가 한 덩이 더 들어가 그만큼 높다.
   ⚠ `--pop-row-min-h:56` 은 「시안 여섯이 모두 56」 이라는 앞선 실측으로 정해진 값인데,
     그 여섯에 pd2 가 빠져 있었다. 토큰은 그대로 두고 **pd2 만** 제 값을 갖는다. */
.bi-pop-page .bi-pop-list--member .bi-pop-clist-item{ min-height: 60px; }

/* ══ §83 담은 목록은 «네 줄까지» 보이고 그 위는 스크롤한다 (2026-09-17) ═══════════
   사용자: 「입고등록 팝업에 상품리스트가 상품선택에 따라 계속 길어지는데 최대 4개까지
            보이는 크기로 하고 그이상 상품이 선택되면 스크롤있게 해줘. 예약등록 팝업도 마찬가지로」

   ⚠ 같은 요청을 2026-09-16 매출등록에서 이미 받았고 _SPEC_CHECKLIST §2-12 로 적어 두었는데
     「새 화면에 목록이 있으면 이 검사도 같이 만든다」 를 이 팝업 둘에 안 해서 또 묻게 했다.
     이제 probe_pop_grow2.mjs 가 막는다(qc.mjs layout).

   실측(고치기 전) — 줄 키 54px:
     예약등록  목록 97 → 259 → 583 · 판 664 → 826 → 1056 (1 · 4 · 10줄)
     입고등록  목록 97 → 259 → 583 · 판 735 → 897 → 1056
   10줄이면 창에 세로 스크롤까지 생겼다.

   ⚠ 합계 바(.bi-bq-items__ft)는 스크롤 «밖» 이다 — 같이 감싸면 줄이 늘 때 밀려 사라진다.
   ⚠ max-height 는 «정해진 키» 라 overflow 가 바로 먹는다(§2-12 의 첫 함정 — flex 사슬이 아니다). */
.bi-bq-items { --bq-item-h: 54px; --bq-rows: 4; }
/* ⚠ 2026-09-30 — 입고 줄은 «한 줄» 이다(사용자 지시로 단가·수량을 이름 옆으로 옮겼다).
     예약등록 줄은 «이름 위 / 시간·금액 아래» 두 줄이라 54 가 맞지만, 한 줄짜리는 그보다 낮다.
     같은 변수를 억지로 나눠 쓰면 «네 줄까지 보인다» 가 한쪽에서 어긋난다
     (54×4=216 인데 실제 줄이 49 라 4.4줄이 보였다 — 동료 세션이 cmp_box 로 잡아냈다).
   → 입고 줄만 제 키를 갖는다. 값은 «잰 것» 이다(실측 49px: 이름 17 + 위아래 여백 + 테두리).
   ⚠ 규격안 목업(spec_pop/buy_appear.html)은 아직 «두 줄» 판이라 61px 이다 —
      구조가 바뀌었으니 목업도 한 줄로 고쳐야 한다(§「전시=등록」). */
#rb_items { --bq-item-h: 49px; }
.bi-bq-items__scroll {
    max-height: calc(var(--bq-item-h) * var(--bq-rows));
    overflow-y: auto; overflow-x: hidden;
    /* ⚠ 스크롤바는 이 프로젝트 전체가 «오버레이 6px» 이다(::-webkit-scrollbar, 1776줄) —
       폭을 안 차지하고 굴릴 때만 보인다. scrollbar-gutter:stable 로 자리를 잡아 보았으나
       «엄지는 여전히 안 그려지고 6px 만 비어» 서 되돌렸다(2026-09-17 실측).
       «더 있다» 는 제목·합계 바가 두 번 말해 준다 — 「매입 상품 (9건)」·「담은 상품 9건」. */
}

/* ══════════════════════════════════════════════════════════════════════
   §61-46 휴무설정 — 단추 글자·키를 «다른 페이지와 같게» 내린다 (2026-09-17)
   ──────────────────────────────────────────────────────────────────────
   사용자 지적 2026-09-17:
     「기간휴무설정, 저장 버튼이 조금 이상해 글자크기때문인지 모르겠는데
      **다른 페이지들과 상이해 보여**. 시안에는 괜찬았는데 말이지.
      전체근무, 전체휴무 버튼도. **전체적 글자크기 등 확인이 필요해보여**」

   재 보니 이랬다 (`_do_btncmp.mjs` — 같은 자로 다섯 화면):

   | 자리 | 휴무설정(전) | 지점·직원·회원 | 예약일정표 |
   |---|---|---|---|
   | 머리 툴바 단추 | 키 34 · **글자 16** · 600 | 키 32 · **13** · 500/700 | 키 27 · **13** |
   | 본문 툴바 단추 | 키 32 · **글자 14** · 600 | — | — |

   **이 화면만 앱 전체보다 크다.** 그것이 「상이해 보여」 의 정체다.

   ⚠ 시안을 «다시» 확인했다 — 시안이 틀린 것이 아니다.
     후보를 실제로 렌더해 시안 잉크와 견주니(`_do_btnfit.mjs`, 크기 4 × 굵기 3 = 12 조합)
     시안은 **15px / 700** 이었다(잉크 상자 키 13 · 밀도 0.372 가 정확히 일치).
     지금의 16/600 은 시안에 이미 가깝다(키차 +1 · 밀도차 −0.02).
     즉 사용자가 본 것은 «시안과의 차이» 가 아니라 **«다른 페이지와의 차이»** 다.

   ⚠ 그래서 시안(15)이 아니라 규격(13)을 따른다 — 이 프로젝트의 판례다:
     「시안이 말하는 건 «본문보다 크다» 이지 «정확히 34» 가 아니다.
      **시안 수치가 규격과 부딪히면 규격을 따른다**」(47_AI메시지발송.md:1173)
     사다리에 15 는 없고(11·12·13·14·16·18·20), 15 를 만들면 «등급에 없는 새 수» 가 된다.

   ⚠ 굵기는 **다시 정하지 않는다** — 공용 `.bi-btn--ghost`(500)·`.bi-btn--primary`(700)에
     맡긴다. 600 으로 못박아 둔 것이 ghost 를 무겁게, primary 를 가볍게 만들고 있었다
     (다른 페이지는 둘이 다르다). `font-weight` 를 여기서 «되돌려» 준다.

   ⚠ 키도 34 → 32 로 내린다 — 다른 페이지 툴바가 32 고, `probe_break` 의 사다리
     (48·32·27·22)에 34 가 없어 이 화면만 «커짐 2» 로 찍히고 있었다(KNOWN_ISSUES D5·D11).
     이걸 내리면 그 둘도 함께 사라진다.
   ⚠ 여백은 10 → 12(--space-3) — 다른 페이지와 같다. 글자가 3px 작아진 만큼
     여백으로 메워 단추가 헐렁해 보이지 않게 한다.
   ══════════════════════════════════════════════════════════════════════ */
.bi-erp-toolbar.bi-do2-tb .bi-btn {
    height: 32px;
    font-size: var(--fs-base);              /* 16 → 13 (다른 페이지와 같다) */
    font-weight: inherit;                   /* 600 못박기 해제 → 공용 클래스가 정한다 */
    padding: 0 var(--space-3);              /* 10 → 12 */
}
.bi-erp-toolbar.bi-do2-tb .bi-btn--ghost   { font-weight: var(--fw-medium); }   /* 500 */
.bi-erp-toolbar.bi-do2-tb .bi-btn--primary { font-weight: var(--fw-bold); }     /* 700 */

.bi-do2-wrap .bi-do2-main .bi-do2-tool .bi-btn {
    font-size: var(--fs-base);              /* 14 → 13 */
    font-weight: inherit;
}
.bi-do2-wrap .bi-do2-main .bi-do2-tool .bi-btn--ghost   { font-weight: var(--fw-medium); }
.bi-do2-wrap .bi-do2-main .bi-do2-tool .bi-btn--primary { font-weight: var(--fw-bold); }

/* 날짜칸도 같은 줄에 있다 — 단추가 32 로 내려갔으니 상자도 32 여야 한 줄이 고르다.
   ⚠ .bi-do2-tb 는 .bi-do2-wrap «밖» 이라 전역 border-box 가 안 걸린다(§61-2 주석).
     box-sizing 은 이미 그 블록이 선언해 두었으므로 키만 고친다. */
.bi-erp-toolbar.bi-do2-tb .bi-datenav { height: 32px; }

/* 날짜의 «아래 화살표» 와 달력 아이콘은 이제 눌린다 — 손가락 커서로 알린다
   (사용자 지적: 「화살표는 기능도 없는데 왜있어 화살표누르면 달력나오게 해주던가」) */
/* ⚠ 본문 툴바의 달력 «아이콘» 은 시안대로 숨어 있다(:17494 display:none) —
     시안의 본문 내비에는 아이콘이 없고 화살표만 있다. 커서를 줄 자리가 아니다. */
.bi-do2-wrap .bi-do2-tool .bi-datenav__cv,
.bi-erp-toolbar.bi-do2-tb .bi-datenav__ico { cursor: pointer; }
/* §61-46 끝 ──────────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §61-47 휴무설정 — 「근무 안 함」 을 고를 수 있게 (2026-09-17)
   ──────────────────────────────────────────────────────────────────────
   사용자 질문:
     「휴무설정할때 시간에 한번클릭하면 휴무고 다시 클릭하면 활성이 되는데
      그럼 **휴무가아니고 근무를 안한다고 표시하려하면 어떻게해?**
      지금은 전체휴무,반차 뿐이잔아」

   ⚠⚠ 저장 모델은 바꿀 수 없다 — `hourbit` 의 0/1 은 이 화면만 쓰는 것이 아니다:
     · 예약 화면    `booking_renew/script.js:1596` 이 '0' 을 **예약 마감**으로 그린다
     · 모바일       `mobile/page/employee_dayoff/*` · `mobile_beauty/*`
     · 네이버 연동  `json/lib/function_naver.php` 가 그대로 올린다
   즉 **저장되는 뜻은 「그 시각에 예약을 받는가」 하나뿐**이고, 세 번째 글자를 넣으면
   그 셋이 «조용히» 깨진다(칼럼 변경도 사전 승인 대상 — CLAUDE.md §5).

   그래서 0 이 «무엇으로 읽히는가» 를 **자리**가 정하게 두고(이미 그랬다),
   그 자리를 **고를 수 있게** 만들었다:
     근무 구간 «안» 의 0  → 휴게        (앞뒤에 근무가 있다 = 나왔다가 쉰다)
     근무 구간 «밖» 의 0  → 근무 안 함  (미출근 · 마감)
     온종일 0            → 휴무
   → 「근무 안 함」 을 만드는 정식 길 = **근무 시간을 줄이는 것**. ⋯ 메뉴의 「근무 시간」 이다.

   ⚠ 미출근 칸이 `<span>` 이라 **죽어 있었다** — 근무 시간을 줄이면 다시 늘릴 길이 없었다.
     `<button>` 으로 바꿨으니 커서도 손가락이어야 한다.
   ══════════════════════════════════════════════════════════════════════ */
.bi-do2-wrap .bi-do2-cell--none { cursor: pointer; }
.bi-do2-wrap .bi-do2-cell--none:hover { border-color: var(--do-cell-line, #C7D2FE); background: var(--bg-page); }

/* ⋯ 메뉴의 「근무 시간」 줄 — 셀렉트 둘 + 적용 */
/* ⚠ 메뉴 폭은 **시안 219 (--do-menu-w 220)** 그대로 둔다 — 넓히면 시안과 어긋난다.
     대신 줄을 나눈다: 1줄 «셀렉트 – 셀렉트» · 2줄 «적용»(꽉 찬 폭).
     한 줄에 넷을 넣었더니 셀렉트가 «09:0» 으로 잘렸다(2026-09-17 캡처로 확인). */
.bi-do2-wrap .bi-do2-menu .bi-do2-menu__span {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1_5);
    padding: var(--space-1_5) var(--space-3) var(--space-2_5);
}
.bi-do2-wrap .bi-do2-menu .bi-do2-menu__sel {
    flex: 1 1 40%; min-width: 0; height: 28px; padding: 0 var(--space-1_5);
    font-size: var(--fs-sm);
}
.bi-do2-wrap .bi-do2-menu .bi-do2-menu__dash { flex: 0 0 auto; color: var(--txt-muted); }
.bi-do2-wrap .bi-do2-menu .bi-do2-menu__span .bi-btn {
    flex: 1 1 100%; height: 28px; margin-top: var(--space-0_5);
}
/* 「근무 시간」 라벨의 보조설명 — 한 줄에 붙는다 */
.bi-do2-wrap .bi-do2-menu .bi-do2-menu__lb small {
    margin-left: var(--space-1_5); font-weight: var(--fw-normal); color: var(--txt-disabled);
}

/* 범례 — «근무 시간 밖» 스와치는 칸과 같은 «점선 빈 네모» 다 (색이 아니라 모양으로 말한다) */
.bi-do2-wrap .bi-do2-legend__sw--none {
    background: transparent; border: 1px dashed var(--border-base);
}
/* 범례 «예약 마감» 스와치 = 판의 마감 칸과 같은 색 (2026-10-07).
   위쪽 --full 선언(16515)이 뒤에 오는 기본 .bi-do2-legend__sw 에 져서 «근무» 견본과 똑같이 보였다 — 특이도를 올려 새로 선언 */
.bi-do2-wrap .bi-do2-legend__sw.bi-do2-legend__sw--full {
    background: var(--do-cell-booked); border-color: var(--color-info-700);
}
/* §61-47 끝──────────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   §84 · 지점수정 팝업의 «지점 환경설정» 줄 (2026-09-17 신설)
   ──────────────────────────────────────────────────────────────────────
   사용자 지시 2026-09-17:
     「사업장 환경설정의 경우 일반 페이지일 필요도 없어보이고 지점수정 팝업에서
      지점 설정 버튼 및 설정값 표시해주면서 지점 환경설정 버튼을 누르면
      팝업으로 설정할수있게 하는게 좋겠어」

   왜 옮겼나 — 「환경설정」 페이지는 **어느 레벨의 사이드 메뉴에도 없다**
   (2026-09-17 네 계정으로 띄워 전수 확인 · `_do_menucheck.mjs`).
   기능은 살아 있는데 들어갈 길이 없었다. 지점수정 팝업이 그 지점을 다루는 자리다.

   ⚠ 요약 줄은 «길다» — 영업·휴게·단위·자동휴게 넷을 한 줄에 적는다.
     팝업 폭이 720 이라 그냥 두면 단추를 밀어낸다 → 요약이 줄고(min-width:0) 넘치면 … 로 자른다.
     단추는 줄지 않게 못박는다(flex:0 0 auto). 「버튼이 밀려 잘린다」 를 막는 자리다.
   ⚠ 값이 하나도 없으면(=기본값) 흐리게 적는다 — «설정이 없다» 와 «못 불러왔다» 를
     빈칸으로 두면 구별할 수 없다. 글자로 말한다. */
.bi-br-cfg { align-items: center; gap: var(--space-2_5); }
.bi-br-cfg .bi-br-cfg__sum {
    flex: 1 1 auto; min-width: 0;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    font-size: var(--fs-sm); color: var(--txt-secondary);
}
.bi-br-cfg .bi-br-cfg__sum.is-muted { color: var(--txt-disabled); }
.bi-br-cfg .bi-btn { flex: 0 0 auto; }

/* 팝업 안 도움말 — 규격 보조문(.bi-pop-note)과 같은 글자다 */
.bi-pop-help {
    margin: var(--space-3) 0 0;
    font-size: var(--fs-sm); color: var(--txt-muted); line-height: 1.6;
    /* 낱말 중간에서 끊기지 않게 — 「(근/무 자료가」 로 갈라졌다(2026-09-17 캡처) */
    word-break: keep-all; overflow-wrap: break-word;
}
/* 안내문이 «낱말 중간» 에서 끊기지 않게 — 한국어는 기본값(break-word 성향)으로
   「휴무설/정·예약」 처럼 갈라진다(2026-09-17 캡처로 확인).
   ⚠ 기존 `.bi-pop-note` 를 고치지 않는다 — 다른 팝업 30여 곳이 쓴다.
     새 이름을 «더해서» 이 팝업만 바꾼다(사용자 상시 지시: 다르면 새로 만들어 추가).
   ⚠ keep-all 은 긴 영문·URL 을 넘치게 만든다 → overflow-wrap 으로 그것만 예외를 둔다. */
.bi-pop-note.bi-pop-note--keep { word-break: keep-all; overflow-wrap: break-word; }
.bi-pop-note.bi-pop-note--keep span { word-break: keep-all; }

/* §84 끝 ───────────────────────────────────────────────────────────── */

/* ══ §84 담는 덩이 — 규격안(시안 db1.png)과 어긋난 자리 (2026-09-17) ═══════════════
   사용자: 「두 팝업 보면 상품리스트 부분 타이틀 글자색, 글자 크기 등 규격안과 달라
            그리고 각 항목 간격도 다르고 … 왜 계속 그대로지? qc에 문제가 있는거 같은데?」

   ⚠ 맞는 지적이었다. 검사의 구멍:
     · 답안지는 «내가 적어 둔 자리» 만 본다 · 단추 검사는 단추만 · 글자 검사는 «짝» 에 적은 글자만.
     · padding·gap·margin·line-height 를 재는 검사는 **하나도 없었다.**
     → cmp_box.mjs 를 새로 만들어 자리마다 열둘을 견줬더니 **22곳**이 어긋나 있었다.

   시안 실측(db1.png 확대) — 「시술 · 상품 (2건) 수량 변경 · 삭제 가능」:
     «시술 · 상품» 은 **검정 굵게**, «(2건)» 만 **파랑**, 덧말은 연한 회색.
     실제는 제목 전체가 파랑 16px/400 이었다 — 규격안(reg.html 13px/800)이 맞고 실제가 틀렸다.

   ⚠ 두 목업끼리도 갈라져 있었다(buy_appear.html 이 옛 값을 들고 있었다) —
     예약등록·입고등록은 «같은 규격» 이므로 목업도 reg.html 값으로 맞췄다. */
.bi-bq-pop .bi-bq-sec__t {
    font-size: var(--fs-base); font-weight: var(--fw-extrabold); color: var(--txt-primary);
}
.bi-bq-pop .bi-bq-sec__t b { color: var(--bk-fix); font-weight: var(--fw-extrabold); }

/* 줄 — 이름 13.5 / 아래글 12, 줄높이를 못박아 줄 키가 흔들리지 않게 한다 */
.bi-bq-pop .bi-bq-item__t { font-size: 13.5px; line-height: 15px; }
.bi-bq-pop .bi-bq-item__m { line-height: 14px; margin-top: var(--space-0_5); }   /* 2px */

/* 꼬리표 · 수량 · 빼기 — 규격안(reg.html) 실측.
   ⚠ 목업의 반경 이름과 집 토큰의 이름이 «같은 숫자가 아니다» — 숫자로 맞춘다:
     목업 --r-sm 6 · --r-md 8 · --r-lg 10   /   집 --radius-sm 4 · --radius-md 6 · --radius-lg 8 */
.bi-bq-pop .bi-bq-tag { border-radius: var(--radius-md); }   /* 6 — 목업 --r-sm */
.bi-bq-pop .bi-bq-qty { font-size: var(--fs-md); }
.bi-bq-pop .bi-bq-qty button { font-size: var(--fs-md); }
.bi-bq-pop .bi-bq-del { border-radius: var(--radius-lg); }   /* 8 — 목업 --r-md */
/* 휴지통 아이콘 11 = --fs-xs.
   ⚠ 2026-09-21 — §83-2 에 「휴지통 아이콘은 --fs-xs(11) 로 준다」 고 적어 두고 **규칙을 안 만들었다**.
     그래서 <button> 의 브라우저 기본값 13.3333px 이 그대로 서 있었다(우리 값이 아니다).
     목업은 font-size:0 + CSS 도형이라 «0 ↔ 13.3333» 인데도 아무도 못 봤다 —
     목업이 FontAwesome 을 안 싣고 있어 아이콘으로 짝지을 수가 없었기 때문이다. */
.bi-bq-pop .bi-bq-del { font-size: var(--fs-xs); }
.bi-bq-pop .bi-bq-del i { font-size: inherit; }

/* 합계 바 — 12.5px (반올림이 흠을 숨긴다: 12 로 적어 두면 12.5 가 통과한다)
   ⚠ 2026-09-21 — 시안·규격안·실제가 «셋 다 달랐다». 시안(db1.png)을 글자 없는 세로선으로
     읽으니 이렇다:  y480 = 1px 경계선 #E5E7EB · y481~515 = 띠 속 35px.
       시안 36(경계 1 + 속 35)  ↔  규격안 41  ↔  실제 42(줄높이 선언 전엔 44)
     규격안이 적어 둔 41 은 시안이 아니라 «2026-09-16 의 실제» 를 베낀 값이었다(reg.html:97 주석).
     규격안과 실제가 같이 틀려 있으면 검사가 통과한다 — 시안을 자로 삼아 셋을 맞춘다.
     8 + 8 + 19 = 35, 경계 1 을 더해 36.
   ⚠ 시안에 있는 «띠 위 1px 경계선» 이 실제에는 아예 없었다(앞형제 border-bottom 0). */
.bi-bq-pop .bi-bq-items__ft {
    font-size: 12.5px; line-height: 19px;
    padding: var(--space-2) var(--space-3);
    border-top: 1px solid var(--border-base);
}
/* 목록 상자 반경 10 — 목업 --r-lg.
   ⚠ 2026-09-21 정정: 「집 토큰엔 10 이 없다」 고 적어 두었는데 틀렸다.
     --radius-talk 가 정확히 10px 이다(155줄). 실측값 대신 토큰을 쓴다. */
.bi-bq-pop .bi-bq-items { border-radius: var(--radius-talk); }

/* ══ §83-2 담은 상품의 «수량 −/+» 와 «휴지통» 에 글자 크기가 없었다 (2026-09-17) ══
   `qc.mjs btn` 이 규격안·실제 «양쪽» 에서 13.3333px 을 찍었다 — 이것은 우리 값이 아니라
   브라우저가 <button> 에 주는 기본값이다(UA 스타일시트). 규칙이 «없어서» 나온 수다.
   ⚠ 양쪽이 같아서 «어긋남» 으로는 안 잡혔다 — 「토큰 밖」 칸이 아니었으면 영영 안 나왔다.
   −/+ 는 24px 칸 안의 글리프라 --fs-sm(13), 휴지통 아이콘은 --fs-xs(11) 로 준다. */
.bi-bp2__qty button { font-size: var(--fs-sm); }
.bi-bp2__del { font-size: var(--fs-xs); }

/* ══ §84 칩 줄 ~ 목록 사이를 «반» 으로 (2026-09-17 사용자 지시) ══════════════
   사용자: 「고객검색 팝업에 … 카테고리 나오는데 … 아래 리스트와 여백 반으로 줄여줘」
          「디자이너 검색 팝업에 디자이너 카테고리 아래 리스트와 여백도 반으로 줄여줘」
   잰 값(tools/qc/_gap_chip.mjs) — 칩 아래 84 → 목록 위 104 = **20px**.
     10(.bi-pop-filters 의 padding-bottom) + 8(판 .bi-bp2__lhd 의 padding-bottom) + 1(판 아랫선) + 1(반올림)
   칩 줄이 판 안에서 제 아래 여백을 갖는 것이 겹침이다 — 판의 여백만 쓰게 하면 **20 → 10**.
   ⚠ 판 자체의 아래 여백(8)은 건드리지 않는다. 그것까지 줄이면 칩이 아랫선에 붙는다. */
.bi-bp2__lhd > .bi-pop-filters { padding-bottom: 0; }

/* ⚠ 2026-09-17 — 여기 있던 §85 · §85-2 를 **걷어냈다**.
   `.bi-cat4__grid{grid-auto-rows}` · `.bi-cat4__card{aspect-ratio}` 로 **같은 이름을 파일 끝에서
   다시 선언해 덮어쓰고** 있었다 — 사용자: 「기존 css에 덮어서 하지말라니까 수정이 안되잔아」.
   그 두 값은 §87 의 새 조각 `.bi-cat5` 에 시안 실측값(줄 키 250 · 카드 203×250)으로 들어 있다.
   ⚠ 덮어쓰기는 «되던 것처럼» 보이지만 규칙이 두 곳으로 갈라져 다음 사람이 둘 다 고쳐야 한다. */

/* ══ §85 담는 덩이 — 아래 틈 · 추가 단추 색 (2026-09-17) ═══════════════════════
   사용자: 「상품리스트 영역 아래 항목이 리스트 영역에 붙어있잔아 상품추가 버튼색도 다르고」

   ① 아래 틈 — 실측 규격안 16 ↔ 실제 **0**. 시안에도 합계 바 아래 뚜렷한 틈이 있다.
   ② 추가 단추 — 시안 실측은 «흰 바탕 · 파란 글자 #1D4ED8 · 연한 파란 테두리 #C7D2FE» 다.
      실제는 .bi-btn--ghost(회색)였다. ⚠ 09-16 에 검사가 어긋났을 때 «실제에 맞춰 규격안을
      회색으로» 바꿨는데, 시안을 안 보고 고친 것이 잘못이었다 — 시안은 처음부터 파랑이다. */
.bi-bq-pop .bi-bq-sec { margin-bottom: var(--space-4); }   /* 16 — 시안·규격안 실측 */
.bi-bq-pop .bi-bq-sec__hd .bi-btn {
    color: var(--color-info-700);                          /* #1D4ED8 — 시안 실측 */
    border-color: var(--color-indigo-200);                 /* #C7D2FE — 시안 실측 */
    font-weight: var(--fw-bold);
}
.bi-bq-pop .bi-bq-sec__hd .bi-btn i { color: inherit; }
/* 규격안은 height 30 + padding 0 12 로 놓는다 — 키는 같았지만 안여백이 달라 검사가 잡음리를 냈다 */
.bi-bq-pop .bi-bq-sec__hd .bi-btn { padding: 0 var(--space-3); }

/* ══════════════════════════════════════════════════════════════════════
   §79 · 접수 · 시술전표 (신규 모듈 · 2026-09-17)

   시안       : renew_crm/reimg/buysell2.png
   규격안 목업 : renew_crm/tools/qc/spec_rs/main.html
   뷰         : template/page/reception_slip/slip_write.php
   답안지      : renew_crm/tools/qc/spec_match/reception_slip.mjs
   비교 문서   : renew_crm/rs_spec.html

   사용자 지시: 「buysell2.png 로 새로운 페이지… 메뉴에 기본업무에 접수/시술전표 로 추가해줘.
     해당 신규건은 매출등록과 비슷하므로 매출등록 작업내용을 참고해서 진행해줘」

   ⚠ 매출등록(§76~§78-9)의 bi-bs2-* 를 «나눠 쓰지 않는다» — 새 접두 bi-rs-* 다.
     시안이 닮았다고 클래스를 공유하면 한쪽을 고칠 때 다른 쪽이 따라 움직인다
     (§4 절대규칙 「기존 CSS 클래스 직접 수정 ❌ → 항상 신규 클래스 추가」의 같은 취지).

   ⚠ 매출등록에서 배운 것을 처음부터 적용한다
     · 세 열은 «전폭 구분줄로 나뉜 띠» 다 — 열에 padding 을 두지 않고 띠마다 준다(§78-8)
     · 자료가 늘어도 판은 늘어나지 않는다 — 늘어나는 목록에 키를 박고 스크롤 (§78-6)
     · 연회색 판은 --pop-band(#F5F6F9) 다 — --border-light 가 아니다 (§14-1)
   ------------------------------------------------------------------ */

/* ⚠ box-sizing 을 «스스로» 선언한다 — 전역에 기대지 않는다(CLAUDE.md §7).
   처음엔 빠뜨려 content-box 로 계산돼 박아 둔 키마다 여백이 더해졌다(판 826 → 920). */
.bi-rs, .bi-rs * { box-sizing: border-box; }
.bi-rs { display: flex; flex-direction: column; padding: var(--space-4);
  background: var(--bg-page); min-height: 0; }
/* ── 툴바 ── */
.bi-rs-top { display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); padding: var(--space-3_5) var(--space-4);
  border-bottom: 1px solid var(--border-base); }
.bi-rs-step { display: inline-flex; align-items: center; gap: var(--space-1_5);
  font-size: var(--fs-sm); color: var(--txt-disabled); }
.bi-rs-step__mk { display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: var(--radius-full);
  background: var(--border-light); color: var(--txt-disabled);
  font-size: var(--fs-2xs); font-weight: var(--fw-bold); }
.bi-rs-step.is-done { color: var(--txt-secondary); }
.bi-rs-step.is-done .bi-rs-step__mk { background: var(--pop-navy); color: var(--bg-card); }
.bi-rs-step.is-now { color: var(--txt-primary); font-weight: var(--fw-bold); }
.bi-rs-step.is-now .bi-rs-step__mk { background: var(--color-info-700); color: var(--bg-card); }
/* ⚠ 「새 전표」 단추 규칙은 매출등록과 «한 규칙» 으로 합쳐 두었다(위 .bi-bs2-newslip 자리).
     아이콘 크기를 따로 줄이던 `.bi-rs-newslip > i` 도 뺐다 — 매출등록은 글자 크기를 그대로 쓴다. */
.bi-rs-datechip__ico { font-size: var(--fs-xs); color: var(--pop-navy); }
/* ⚠ 2026-09-22 사용자 지시 — 78 → 82. 「2026-09-22」 열 글자가 78 에 빠듯해
   글꼴에 따라 끝이 잘려 보였다. 요일은 옆의 .bi-rs-datechip__dow 가 따로 들고 있다. */
.bi-rs-datechip__val { width: 82px; flex: 0 0 auto; border: 0; background: transparent;
  font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--pop-navy); }
.bi-rs-datechip__dow { flex: 0 0 auto; font-size: var(--fs-md); font-weight: var(--fw-bold);
  color: var(--pop-navy); }
.bi-rs-datechip__dow:empty { display: none; }

/* ── 세 열 — 시안 330 / 1fr / 425 ── */
.bi-rs-cols { display: grid; grid-template-columns: 330px minmax(0, 1fr) 425px;
  align-items: stretch; min-height: 0; }
.bi-rs-q, .bi-rs-mid, .bi-rs-slip { display: flex; flex-direction: column;
  min-width: 0; min-height: 0; }
.bi-rs-mid, .bi-rs-slip { border-left: 1px solid var(--border-base); }

/* ══ 좌 · 고객 대기열 — 띠 넷 (머리 · 탭검색판 · 목록 · 바닥요약) ══ */
.bi-rs-q__hd { flex: 0 0 auto; height: 57px; padding: 0 var(--space-4);
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  border-bottom: 1px solid var(--border-base); }
.bi-rs-q__t > i { font-size: var(--fs-md); color: var(--txt-muted); }
/* ⚠ 2026-09-23 — 결제/매출등록의 같은 단추(.bi-bs2-q__new)는 flex 가 «아니다» —
   아이콘과 글자 사이가 HTML 의 «빈칸 한 칸»(약 3px)뿐이다. 여기는 inline-flex + gap 6 이라
   빈칸이 지워지고 6px 이 들어가 «더 벌어져» 보였다(실측 폭 99 ↔ 96).
   → 같은 모습이 되도록 flex 를 걷는다. 높이는 line-height 로 맞춘다. */
.bi-rs-q__new { height: 27px; padding: 0 var(--space-2_5); line-height: 25px;
  font-size: var(--fs-sm); font-weight: var(--fw-semibold);
  /* 2026-09-23 사용자 지시 — 결제/매출등록의 같은 단추(.bi-bs2-q__new)와 «같은 바탕» 이다.
     전에는 파랑 채움이라 한 제품에서 같은 뜻의 단추가 두 모습이었다. */
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); color: var(--txt-primary); }
.bi-rs-q__new > i { font-size: var(--fs-2xs); }

/* 탭 + 검색 = 하나의 연회색 판 */
.bi-rs-qpanel { flex: 0 0 auto; display: flex; flex-direction: column; gap: var(--space-2_5);
  padding: var(--space-3) var(--space-4);
  background: var(--pop-band); border-bottom: 1px solid var(--border-base); }
.bi-rs-qtabs { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-1); }
.bi-rs-qtab.is-on { background: var(--pop-navy); color: var(--bg-card); border-color: var(--pop-navy); }
.bi-rs-qtab.is-on .bi-rs-qtab__n { color: inherit; opacity: .75; }
.bi-rs-qsearch { display: flex; align-items: center; gap: var(--space-1_5); height: 38px;
  padding: 0 var(--space-2_5); border: 1px solid var(--border-base);
  border-radius: var(--radius-md); background: var(--bg-card); }
/* 돋보기는 «단추» 다 — 누르면 공용 고객검색 팝업이 열린다(2026-09-17).
   시안의 자리·크기는 그대로 두고 단추의 기본 테두리·바탕만 지운다. */
.bi-rs-qsearch__ico { font-size: var(--fs-xs); color: var(--txt-disabled);
  border: 0; background: transparent; padding: 0; line-height: 1; }
.bi-rs-qsearch__ico:hover { color: var(--color-info-700); }
.bi-rs-qsearch__in::placeholder { color: var(--txt-disabled); }

/* 목록 — 키를 박는다(자료가 늘어도 판이 늘지 않는다 · §78-6) */
.bi-rs-qlist { flex: 0 0 auto; height: 562px; min-height: 0; overflow-y: auto; overflow-x: hidden;
  padding: var(--space-3) var(--space-4);
  display: flex; flex-direction: column; gap: var(--space-2); }
.bi-rs-qcard { flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-2_5);
  padding: var(--space-2_5); cursor: pointer;
  border: 1px solid var(--border-base); border-radius: var(--radius-lg); background: var(--bg-card); }
.bi-rs-qcard.is-active { border-color: var(--color-info-700); background: var(--pop-row-sel); }
.bi-rs-qav { flex: 0 0 auto; width: 40px; height: 40px; border-radius: var(--radius-full);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--fs-2xs); font-weight: var(--fw-bold); }
.bi-rs-qav--std  { background: var(--gray-300); color: var(--gray-600); }
/* 시안 실측 2026-09-22(_rs_vs_sian + 그림 확인 out/_sian_queue.png): «우수» 는 연보라가 아니라
   **짙은 회색 채움 + 흰 글자** 다 — 시안 바탕 #9CA3AF(--gray-400) · 잉크 흰색.
   «일반»(--std, 바탕 #D1D5DB + 글 #4B5563)보다 한 단 진해 두 등급이 눈으로 갈린다. */
.bi-rs-qav--good { background: var(--gray-400); color: var(--bg-card); }
/* ⚠ 2026-09-28 — 이 줄의 선언은 §90 .bi-grade--vip 와 **글자 또라도 같다**(SPEC-DUP).
     값은 하나도 바꾸지 않고 선언 자리만 §90 으로 옮겼다 — 그 줄에 이 이름이 함께 적혀 있다. */
.bi-rs-qav--vvip { background: var(--color-warning-600); color: var(--bg-card); }
/* 대기 카드 — 2026-09-22 사용자 지시로 배치를 바꿨다:
     첫 줄  고객명(성별)  휴대폰번호            [상태]
     둘째 줄 시간 · 디자이너명
   전에는 오른쪽 칸이 «꼬리표 + 담당명» 세로 두 줄이었고 그 칸이 줄어들지 않아
   (flex:0 0 auto) 담당명이 길수록 왼쪽을 밀어 이름·전화가 줄바꿈됐다.
   ⚠ 이제 오른쪽에는 짧은 꼬리표만 남는다 — 그래도 «넘치면 잘라 내는» 방어를 함께 둔다.
     매출등록이 같은 흠을 겪고 .bi-bs2-qcard__top 에 적어 둔 것과 같은 판단이다
     (「이름+전화가 길면 상자를 넘었다(실측) — 잘라 낸다」). */
/* ⚠ overflow 를 여기 주지 않는다 — 자식(__nm 의 nowrap · __sub 의 말줄임)이 이미 잘라 낸다.
   주면 선언이 `.bi-bk2-emp__l` 무리에서 빠져나와 SPEC-DUP 의 키가 바뀐다(없어도 되는 선언이다). */
.bi-rs-qcard__l,
.bi-rs-cust__l { flex: 1 1 auto; min-width: 0; }
.bi-rs-qcard__nm { margin: 0; display: flex; align-items: baseline; gap: var(--space-1_5);
  min-width: 0; white-space: nowrap;
  font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--txt-primary); }
/* 전화가 먼저 자리를 내준다 — 이름이 잘리면 누구인지 알 수 없다 */
.bi-rs-qcard__tel { min-width: 0; overflow: hidden; text-overflow: ellipsis;
  font-size: var(--fs-base); font-weight: var(--fw-normal); color: var(--txt-muted); }
.bi-rs-qcard__sub { margin: var(--space-0_5) 0 0; min-width: 0; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  font-size: var(--fs-base); color: var(--txt-muted); }
/* 오른쪽 — 위에 꼬리표, 아래에 그 전표의 금액(2026-09-22 사용자 지시).
   ⚠ 담당명이 여기 있을 때와는 다르다 — 금액은 «짧고 길이가 예측되는» 값이라
     왼쪽을 밀지 않는다(담당명은 사람 이름이라 얼마든지 길어졌다).
     그래도 nowrap 을 둔다 — 「₩1,299,600」 이 쪼개지면 카드 키가 흔들린다. */
.bi-rs-qcard__r,
.bi-bs2-qcard__r { flex: 0 0 auto; display: flex; flex-direction: column;
  align-items: flex-end; justify-content: center; gap: var(--space-1); }
/* 금액 — 매출등록과 같은 결(안 고른 카드는 흐리게, 고른 카드는 보라) */
/* ⚠ 글자 대조가 잡았다 — 규격안 13 ↔ 실제 12. 매출등록(.bi-bs2-qcard__amt)도 --fs-base 다.
   짝을 새로 올린 덕에 드러났다(안 올렸으면 «아무도 안 잰 것» 으로 지나갔다). */
.bi-rs-qcard__amt { white-space: nowrap; font-size: var(--fs-base); font-weight: var(--fw-bold); }
.bi-rs-qcard:not(.is-active) .bi-rs-qcard__amt { color: var(--txt-muted); }
.bi-rs-qcard.is-active .bi-rs-qcard__amt { color: var(--color-indigo-700); }
/* 담당명 — 둘째 줄로 옮겼지만 «글꼴 값은 그대로» 둔다.
   ⚠ color 하나만 남기면 공통 유틸 `.bi-txt-muted` 와 선언이 같아져 SPEC-DUP 으로 잡힌다. */
.bi-rs-qcard__emp,
.bi-rs-item__calc { font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-rs-qtag { display: inline-flex; align-items: center; height: 21px; padding: 0 var(--space-2);
  white-space: nowrap;   /* 「예약」·「완료」 가 쪼개지지 않게 */
  border-radius: var(--radius-sm); font-size: var(--fs-sm); font-weight: var(--fw-bold); }
.bi-rs-qtag--recv { background: var(--color-indigo-50); color: var(--color-indigo-700); }
/* 바닥요약 — 카드 바닥에 붙는다(§78-7) */
.bi-rs-qfoot { flex: 0 0 auto; margin-top: auto; height: 43px; padding: 0 var(--space-4);
  display: flex; align-items: center; justify-content: space-between;
  border-top: 1px solid var(--border-base);
  font-size: var(--fs-base); color: var(--txt-secondary); }
.bi-rs-qfoot__l b { font-weight: var(--fw-bold); color: var(--txt-primary); }
/* ⚠ 2026-09-22 사용자 지시 — 여기 있던 .bi-rs-qfoot__v(선불권 잔액 · 패키지 잔여)를 지웠다.
   그 값을 넣으며 붙였던 nowrap·말줄임 규칙도 함께 뺀다 — 이제 이 띠에는 「선택: 이름」 하나뿐이다. */

/* ══ 중 · 고객 · AI · 전표 이력 ══ */
.bi-rs-cust { flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-4) var(--space-4) 0; }
.bi-rs-ava { flex: 0 0 auto; width: 48px; height: 48px; border-radius: var(--radius-full);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-info-900); color: var(--bg-card);
  font-size: var(--fs-xs); font-weight: var(--fw-bold); }
.bi-rs-cust__nm { margin: 0; display: flex; align-items: baseline; gap: var(--space-2);
  line-height: 1.15; }
.bi-rs-cust__nm b { font-size: var(--fs-2xl); font-weight: var(--fw-extrabold); color: var(--txt-primary); }
.bi-rs-cust__meta { margin: var(--space-0_5) 0 0; display: flex; gap: var(--space-3_5);
  font-size: var(--fs-base); color: var(--txt-muted); }
.bi-rs-cust__meta b { color: var(--txt-secondary); font-weight: var(--fw-bold); }
.bi-rs-cust__acts { flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-2); }
.bi-rs-cust__btn { height: 32px; padding: 0 var(--space-3); gap: var(--space-1_5);
  display: inline-flex; align-items: center;
  font-size: var(--fs-sm); font-weight: var(--fw-semibold);
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); color: var(--txt-primary); }
/* 시안 실측(2026-09-21): 카탈로그 개수 배지는 «보라» 다(#4A37CF ≒ --color-indigo-700) */
.bi-rs-cust__cnt { font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--color-indigo-700); }
/* ⚠ 2026-09-22 — 여기 있던 .bi-rs-cust__cnt--warn(고객메모 옆 호박색 배지)을 지웠다.
   사용자 지시로 그 배지를 화면에서 뺐다 — 쓰는 곳 없는 규칙을 남기면 다음 사람이
   「어디에 쓰는 것인가」 를 다시 찾는다. 규격안·답안지·글자짝도 함께 걷었다. */

/* 시안 실측(_pick_cat.mjs · buysell2.png 도 같은 단추다):
   사진 잉크 16×22 · 흰 테 2 · 물림 pitch 18 · 마지막 장 오른쪽 위 보라 점 8×8(#5B45E0) */
.bi-rs-cat3 { position: relative; display: inline-flex; align-items: center; flex: 0 0 auto; }
.bi-rs-cat3 > img { width: 20px; height: 26px; flex: 0 0 auto; object-fit: cover;
  border: 2px solid var(--bg-card); border-radius: var(--radius-md); background: var(--gray-300); }
.bi-rs-cat3 > img + img { margin-left: calc(var(--space-0_5) * -1); }
.bi-rs-cat3__ai { position: absolute; top: 0; right: -4px; width: 8px; height: 8px;
  border-radius: var(--radius-full); background: var(--bk-run);
  border: 1px solid var(--bg-card); box-sizing: content-box; }
/* AI 알약 — 시안 30×16 · 바탕 #EFEEFF · 글자 #4A37CF 에 가장 가까운 토큰 */
.bi-rs-cust__ai { display: inline-flex; align-items: center; height: 16px; padding: 0 var(--space-1_5);
  border-radius: var(--radius-full); background: var(--bk-run-bg);
  font-size: var(--fs-2xs); font-weight: var(--fw-bold); font-style: normal;
  color: var(--color-indigo-700); }
.bi-rs-cust__ai.bi-hidden { display: none; }   /* 함정 F2 — 숨김을 «같이» 선언한다 */

/* AI 고객분석 — 칩 줄 */
.bi-rs-ai { flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-2_5);
  padding: var(--space-2_5) var(--space-4) var(--space-3); flex-wrap: wrap; }
.bi-rs-ai__t { display: inline-flex; align-items: center; gap: var(--space-1_5);
  font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--txt-primary); }
.bi-rs-ai__t > i { font-size: var(--fs-2xs); color: var(--txt-muted); }
.bi-rs-chips { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.bi-rs-chip { display: inline-flex; align-items: center; gap: var(--space-1);
  height: 27px; padding: 0 var(--space-2_5);
  border: 1px solid var(--border-base); border-radius: var(--radius-full);
  background: var(--bg-card); font-size: var(--fs-base); color: var(--txt-secondary); }
.bi-rs-chip b { font-weight: var(--fw-bold); color: var(--txt-primary); }
.bi-rs-chip em { font-style: normal; color: var(--txt-disabled); }
.bi-rs-chip > i { font-size: var(--fs-xs); color: var(--txt-muted); }
.bi-rs-chip--ok { background: var(--color-indigo-50); border-color: var(--color-indigo-50);
  color: var(--color-indigo-700); font-weight: var(--fw-bold); }

/* 전표 이력 — 위에 전폭선 하나(§78-8 의 «띠») */
.bi-rs-hist { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
  border-top: 1px solid var(--border-base);
  padding: var(--space-3) var(--space-4) 0; }
.bi-rs-hist__hd { flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-2);
  padding-bottom: var(--space-2_5); }
.bi-rs-hist__t > i { font-size: var(--fs-md); color: var(--txt-muted); }
/* 시안 실측 2026-09-21: 보조줄은 #9CA3AF(--txt-disabled) — #6B7280 보다 옷다 */
.bi-rs-hist__sub { font-size: var(--fs-base); color: var(--txt-disabled); }
.bi-rs-hist__n { margin-left: auto; display: inline-flex; align-items: center; height: 22px;
  padding: 0 var(--space-2); border-radius: var(--radius-full);
  background: var(--border-light); color: var(--txt-muted);
  font-size: var(--fs-sm); font-weight: var(--fw-bold); }
/* 목록 — 키를 박는다 */
.bi-rs-hlist { flex: 0 0 auto; height: 468px; min-height: 0; overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column; gap: var(--space-2_5); padding-bottom: var(--space-4); }
.bi-rs-hrow { flex: 0 0 auto; padding: var(--space-3);
  border: 1px solid var(--border-base); border-radius: var(--radius-lg);
  background: var(--bg-card); cursor: pointer; }
.bi-rs-hrow.is-active { border-color: var(--bk-run); background: var(--bk-run-bg); }
.bi-rs-hrow__pick { margin-left: auto; display: inline-flex; align-items: center; gap: var(--space-1);
  height: 22px; padding: 0 var(--space-2); border-radius: var(--radius-full);
  background: var(--bg-card); border: 1px solid var(--bk-run);
  color: var(--bk-run); font-size: var(--fs-sm); font-weight: var(--fw-bold); }
.bi-rs-hrow__b { display: flex; align-items: center; gap: var(--space-2_5);
  margin-top: var(--space-2); }
.bi-rs-hrow__cnt { display: inline-flex; align-items: center; height: 20px; padding: 0 var(--space-1_5);
  border-radius: var(--radius-sm); background: var(--color-indigo-50);
  color: var(--color-info-700); font-size: var(--fs-2xs); font-weight: var(--fw-bold); }
/* 시안 실측 2026-09-21: «고른» 이력 줄의 건수 칩만 보라(#4A37CF ≒ --color-indigo-700)다 */
.bi-rs-hrow.is-active .bi-rs-hrow__cnt { color: var(--color-indigo-700); }
/* 시안 실측(2026-09-21): 이력 줄 시술명은 #374151 이다(화소 482개) — #111827 이 아니다 */
.bi-rs-hrow__nm { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-size: var(--fs-md); font-weight: var(--fw-semibold); color: var(--txt-secondary); }
.bi-rs-hrow__nm em { font-style: normal; font-weight: var(--fw-normal); color: var(--txt-muted); }
.bi-rs-hrow__amt { flex: 0 0 auto; font-size: var(--fs-lg); font-weight: var(--fw-bold);
  color: var(--txt-primary); }
.bi-rs-hrow__memo { margin-top: var(--space-2); display: inline-flex; align-items: center;
  gap: var(--space-1_5); font-size: var(--fs-base); color: var(--txt-muted); }

/* ══ 우 · 시술전표 작성 ══ */
.bi-rs-slip__hd { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2); padding: var(--space-4) var(--space-4) 0; }
.bi-rs-slip__st { display: inline-flex; align-items: center; height: 24px; padding: 0 var(--space-2_5);
  border-radius: var(--radius-full); background: var(--bk-run); color: var(--bg-card);
  font-size: var(--fs-sm); font-weight: var(--fw-bold); }
/* ⚠ 2026-09-23 — 이 묶음은 «여기» 에 있어야 한다. 셈이 모두 (0,1,0) 이라
   `.bi-rs-qtag--recv` 와 `.bi-rs-slip__st` 보다 **뒤** 에 와야 이긴다.
   앞(§예약 꼬리표 자리)에 두었더니 미결제가 남보라·보라로 찍혔다(실측으로 잡았다). */
/* 2026-09-23 사용자 지시 — 「미결제」(결제완료 저장인데 돈이 0)는 예약과 같은 경고 결이다.
   ⚠ 따로 적으면 선언이 한 글자도 안 달라져 SPEC-DUP 이 된다 — 한 규칙에 «묶어» 적는다.
      전표 머리 배지(.bi-rs-slip__st--unpaid)도 같은 결이라 여기 같이 둔다. */
.bi-rs-qtag--book,
.bi-rs-qtag--unpaid,
.bi-rs-slip__st--unpaid { background: var(--bk-req-bg); color: var(--color-warning-800); }
.bi-rs-slip__meta { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2); padding: var(--space-1_5) var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--border-base);
  font-size: var(--fs-base); color: var(--txt-muted); }
.bi-rs-additem { height: 32px; padding: 0 var(--space-3); gap: var(--space-1_5);
  display: inline-flex; align-items: center;
  font-size: var(--fs-sm); font-weight: var(--fw-semibold);
  border: 1px solid var(--color-info-700); border-radius: var(--radius-md);
  background: var(--color-info-700); color: var(--bg-card); }
.bi-rs-additem > i { font-size: var(--fs-2xs); }

/* 선택된 시술 목록 */
.bi-rs-picked { flex: 0 0 auto; padding: var(--space-3) var(--space-4) 0; }
.bi-rs-picked__hd { display: flex; align-items: baseline; gap: var(--space-2);
  padding-bottom: var(--space-2); }
/* 시안 실측(2026-09-21): 「선택된 시술 목록」 제목은 검정(#111827)이다 — 파랑이 아니다 */
.bi-rs-picked__hint { margin-left: auto; font-size: var(--fs-sm); color: var(--txt-disabled); }
.bi-rs-items { margin: 0; padding: 0; list-style: none;
  height: 132px; overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column; gap: var(--space-2); }
.bi-rs-item { flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-2_5);
  border: 1px solid var(--border-base); border-radius: var(--radius-md); background: var(--bg-card); }
.bi-rs-item__cat { flex: 0 0 auto; display: inline-flex; align-items: center; height: 20px;
  padding: 0 var(--space-1_5); border-radius: var(--radius-sm);
  /* 시안 실측(2026-09-21): 갈래 칩 글자는 «보라» 다(#4A37CF ≒ --color-indigo-700) — 파랑이 아니다 */
  background: var(--color-indigo-50); color: var(--color-indigo-700);
  font-size: var(--fs-2xs); font-weight: var(--fw-bold); }
.bi-rs-item__l { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.bi-rs-item__nm { font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bi-rs-item__del { flex: 0 0 auto; width: 30px; height: 30px;
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); color: var(--txt-disabled); font-size: var(--fs-sm); }
/* 수량 — 시안은 «칸 셋이 구분선으로 나뉜 한 상자» 다(§78-7 에서 배운 것) */
.bi-rs-qty { flex: 0 0 auto; display: inline-flex; align-items: center; height: 28px;
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); overflow: hidden; }
.bi-rs-qty__b { width: 27px; height: 26px; border: 0; border-radius: 0;
  background: var(--bg-card); color: var(--txt-muted); font-size: var(--fs-xs); }
/* 아이콘만 있는 단추다 — 크기는 아이콘에 준다(단추 글자를 10 으로 두면 사다리 밖이다) */
.bi-rs-qty__b > i { font-size: var(--fs-2xs); }
.bi-rs-qty__b:first-child { border-right: 1px solid var(--border-base); }
.bi-rs-qty__b:last-child { border-left: 1px solid var(--border-base); }
.bi-rs-qty__v { width: 29px; text-align: center;
  font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-primary); }

/* 자주 쓰는 시술 — 2열 카드 */
.bi-rs-often { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
  margin-top: var(--space-3); padding: var(--space-3) var(--space-4) var(--space-4);
  border-top: 1px solid var(--border-base); }
.bi-rs-often__hd { flex: 0 0 auto; display: flex; align-items: baseline; gap: var(--space-2);
  padding-bottom: var(--space-2_5); }
.bi-rs-often__all { margin-left: auto; border: 0; background: transparent;
  font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--color-info-700); }
.bi-rs-grid { flex: 0 0 auto; height: 396px; min-height: 0; overflow-y: auto; overflow-x: hidden;
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); align-content: start; }
/* ⚠ <button> 은 글자를 물려받지 않는다 — 안 적으면 UA 기본(13.3333px · 순검정)이 들어온다 */
.bi-rs-pcard { min-height: 52px; padding: var(--space-2) var(--space-2_5);
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-0_5);
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); text-align: left;
  font-size: var(--fs-base); color: var(--txt-primary); }
.bi-rs-pcard.is-on { border-color: var(--pop-navy); border-width: 2px; }
/* 시안 실측 2026-09-21: 보통 카드 이름은 #374151, «고른 카드» 만 #111827 이다(화소 328) */
.bi-rs-pcard__nm { width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--txt-secondary); }
.bi-rs-pcard.is-on .bi-rs-pcard__nm { color: var(--txt-primary); }
.bi-rs-pcard__pr { font-size: var(--fs-base); font-weight: var(--fw-bold); color: var(--txt-secondary); }

/* 바닥 — 합계 + 저장 */
.bi-rs-foot { flex: 0 0 auto; margin-top: auto; padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border-base); }
.bi-rs-total { display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-2); padding-bottom: var(--space-2_5); }
.bi-rs-total__v { font-size: var(--fs-3xl); font-weight: var(--fw-extrabold); color: var(--color-info-700); }
/* ⚠ 2026-09-18 — 시안 실측(_pick_foot.mjs): 단추 392 × **40** · #1D4ED8.
   48 로 두어 시안보다 8 높았다(사용자 지적 ⑭: 「전표저장 부분 디자인이 시안과 달라」). */
/* 바닥 — 확정 단추를 한 줄로 묶는 감싸개.
   ⚠ .bi-rs-save 는 고치지 않는다(width:100% 그대로) — 감싸개를 두어 한 줄로 묶는다.
   ⚠ 2026-09-22 — 여기 있던 .bi-rs-foot__date 를 **지웠다**(사용자 지적 ⑤로 날짜가
     머리로 갔다). 쓰는 곳이 한 군데도 남지 않은 규칙을 두면 다음 사람이 «둘 중 어느
     자리가 맞나» 를 다시 고민한다 — 그래서 남기지 않는다.
     감싸개 자체는 남긴다: 단추 하나만 있어도 이 줄이 필요하다. */
.bi-rs-foot__act { display: flex; align-items: center; gap: var(--space-2_5); }
.bi-rs-foot__act > .bi-rs-save { flex: 1 1 auto; }

/* ⚠ 2026-09-22 — 상태 배지가 판 «오른쪽 끝» 으로 밀려 있었다(실측 틈 252).
   .bi-rs-slip__hd 가 space-between 이라 아이 둘(번호·배지)이 양끝으로 갈라진다.
   매출등록이 같은 흠을 먼저 고쳤다(9a65e4dd · 사용자: 「상태표시는 전표번호 옆에 붙어서」) —
   시안 실측 틈 **8**. 같은 기준으로 맞춘다.
   ⚠ 공유 규칙(.bi-rs-q__hd 와 한 줄로 선언된 것)은 건드리지 않는다 — 전표 머리만 왼쪽으로 모은다
     (§4 「기존 CSS 클래스 직접 수정 금지 → 신규 추가」 · 매출등록과 같은 방식). */
.bi-rs .bi-rs-slip > .bi-rs-slip__hd { justify-content: flex-start; gap: var(--space-2); }

/* 전표 날짜 — 머리 «둘째 줄 왼쪽» (2026-09-22 사용자 지시).
   결제/매출등록과 같은 배치다: 첫 줄 번호·태그 / 둘째 줄 날짜·시술상품추가.
   ⚠ .bi-rs-slip__meta 는 이미 space-between 이라 날짜는 왼쪽, 단추는 오른쪽으로 간다 —
     margin-left:auto 를 주면 «둘 다 오른쪽» 으로 몰린다(머리에 있을 때 쓰던 값이다).
   ⚠ 기존 .bi-rs-slip__hd / .bi-rs-slip__meta 는 고치지 않는다(§4 절대규칙). */
.bi-rs-slip__date { flex: 0 0 auto;
  font-size: var(--fs-sm); color: var(--txt-muted); white-space: nowrap; }

.bi-rs-save { width: 100%; height: 40px; gap: var(--space-2);
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: var(--radius-md);
  background: var(--color-info-700); color: var(--bg-card);
  font-size: var(--fs-lg); font-weight: var(--fw-bold); }

/* 빈 상태 — 목록이 비어도 자리를 지킨다 */
.bi-rs-empty { display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--space-1); padding: var(--space-8) var(--space-3);
  color: var(--txt-muted); font-size: var(--fs-sm); }
/* ⚠ 2026-09-22 — 빈칸 안내가 «두 줄» 이 됐다(사용자 지시로 «혹은» 뒤에서 줄을 바꾼다).
   .bi-rs-empty 의 align-items:center 는 «상자» 를 가운데 놓을 뿐이라, 글줄 자체는
   왼쪽에 붙는다 — 둘째 줄이 삐뚤어 보인다. 글도 가운데로 맞춘다. */
.bi-rs-empty p { margin: 0; text-align: center; }
.bi-rs-empty > i { font-size: var(--fs-xl); color: var(--txt-disabled); }

/* §79 끝 ───────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════════
   §87 스타일 카탈로그 «새 조각» — .bi-cat5 (2026-09-17)

   사용자: 「스타일 카탈로그가 시안과 규격안이 달라 **간격이라던지 전부**」
           「**기존 css에 덮어서 하지말라니까** 수정이 안되잔아」

   맞는 지적이다. 앞서 나는 `.bi-cat4__card{aspect-ratio}` 처럼 **같은 이름을 파일 끝에서
   다시 선언해 덮어쓰고** 있었다. 그것은 §4 「기존 CSS 클래스 직접 수정 ❌ → 항상 신규 클래스 추가」
   와 자동 메모리(new-component-not-overlay)의 「시안이 다르면 새로 만든다」 에 어긋난다.
   → **.bi-cat4 는 한 줄도 건드리지 않는다.** 시안대로 잰 값으로 새 조각을 세우고, 팝업과
     규격안 목업이 그 새 이름을 쓴다. cat3 → cat4 때와 같은 방식이다(집의 방식).

   ── 시안 pd4.png 실측 (tools/qc/_pd4_ruler.mjs · 1배 그림) ────────────────
     창           x  24..1143  = 1120      ·  y 9..728 = 720
     머리         y   9.. 64   =   56      (팝업 껍데기가 부모 문서에 그린다 — 여기 없음)
     본문         y  65..664   =  600
     바닥         y 665..728   =   64      (.bi-pop-list-foot — 이미 규격이라 그대로 쓴다)
     왼칸(띠)     x  24..686   =  663      ·  오른칸 x 688..1143 = 456  (가른 선 x 687)
     칩 띠        y  65..119   =   55      바탕 #F5F6F9 (--pop-band)
     칩           y  76..107   =   32      (.bi-pop-fchip — 이미 규격)
     격자 여백            16               (창 왼 24 → 카드 왼 40 · 띠 아래 120 → 카드 위 136)
     카드         203 × 250    사이 12     (x 40..242 · y 136..385 · 다음 줄 397)
     미리보기 사진 424 × 300               (x 703..1126 · y 135..434)
     미리보기 머리·바닥   55               (셋 다 같은 55 띠다)

   ⚠ «간격» 이 어긋나 있던 까닭 두 가지 —
     ① 오른칸이 **420** 이었다(시안 456). 그 36 이 왼칸으로 가서 카드가 203 이 아니라 213 이 됐다.
     ② 실제만 `.bi-catalog` 의 좌우 여백 **20** 을 쓰고 있었다(시안은 0 — 띠가 창 끝에서 시작한다).
        그래서 규격안 1120 · 실제 1078 로 **둘이 서로도 달랐다**.
        새 조각은 그 껍데기 밖에 선다 — 덮어쓸 일이 없다.

   ⚠ 줄 키를 «내용» 에 맡기지 않는다. aspect-ratio 로 정한 카드 키를 격자의 줄이 모른 채
     내용 키(25)로 잡아 **사진이 여러 장이면 카드가 겹쳤다**(사용자 지적 · 13칸에서 겹침 12).
     줄 키를 250 으로 못 박으면 그 흠이 **생길 수가 없다**.
   ══════════════════════════════════════════════════════════════════════════ */

.bi-cat5-wrap{
    height: 100vh; box-sizing: border-box;
    font-family: var(--font-sans); color: var(--txt-primary); background: var(--bg-card);
}
.bi-cat5-wrap *{ box-sizing: border-box; }
/* ⚠ 전역 box-sizing 에 기대지 않는다(CLAUDE.md §7 「예외 페이지는 스스로 선언한다」).
   규격안 목업은 .bi-cat5-wrap 없이 .specpop 안에 들어가므로, 거기서도 같은 셈이 되게 «조각이» 선언한다.
   기대지 않았을 때 띠 키가 56 이 아니라 57 로 잡혀 선이 1px 씩 밀렸다(2026-09-17 실측). */
.bi-cat5, .bi-cat5 *{ box-sizing: border-box; }
/* 껍데기 안쪽 — 본문과 바닥(.bi-pop-list-foot)이 세로로 선다. 좌우 여백은 0 이다(시안). */
.bi-cat5-shell{ height: 100%; display: flex; flex-direction: column; min-height: 0; }
/* ⚠ 공용 바닥줄(.bi-pop-list-foot)은 제 «윗여백 16» 을 갖는다. 시안 pd4 는 본문과 바닥이 **붙어** 있다
   (본문 바닥 664 · 선 665). 그 16 만큼 미리보기 바닥 줄이 위로 떠 있었다(실측 535 · 시안 548).
   ⚠ 공용 규칙은 건드리지 않는다 — 이 껍데기 «안에서만» 0 으로 둔다. */
.bi-cat5 > .bi-pop-list-foot,
.bi-cat5-shell > .bi-pop-list-foot{ margin-top: 0; }

/* ⚠ 2026-09-17 — «머리 ↔ 본문» 구분선. 시안 pd4 는 y 64 에 전폭 #E5E7EB 선이 있다.
   공용 머리(.bi-pop-head)는 «선 없음» 이 규격이고(「헤더에는 두지 않는다」) 게다가 그 머리는
   팝업 껍데기가 **부모 문서**에 그린다 — 여기서 손댈 수도, 손대서도 안 된다.
   → 본문의 **윗선**으로 긋는다. 껍데기가 무엇을 하든 이 창에는 선이 선다.
   (사용자: 「헤더랑 내용사이 구분선등 없잔아」) */
.bi-cat5{ height: 100%; display: flex; flex-direction: column; min-height: 0;
          border-top: 1px solid var(--pop-line); }
.bi-cat5__body{ flex: 1 1 auto; min-height: 0; display: flex; }
.bi-cat5__main{ flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; min-height: 0; }

/* ── 칩 띠 55 — 시안 y 65..119 ── */
.bi-cat5__bar{
    /* 채움 55 + 아랫선 1 = 56. 시안: 띠 y 65..119(55) · 선 y 120 */
    flex: 0 0 auto; height: 56px;
    display: flex; align-items: center; gap: var(--space-2);
    padding: 0 var(--card-pad);
    background: var(--pop-band); border-bottom: 1px solid var(--pop-line);
}
.bi-cat5__ai{ margin-left: auto; }

/* 시안 pd4 의 「전체 3」 은 #121D3F 로 채운 둥근 사각이고 키가 **32** 다.
   pd1·pd2·pd3 의 거르개 칩은 28 이 맞으므로 «공용 .bi-pop-fchip 은 건드리지 않고»
   이 띠 안에서만 32 로 선다 — 집이 .bi-cat4__bar 에서 쓰던 것과 같은 방식이다.
   수는 알약이 아니라 «옅은 글자» 로 이름 옆에 붙는다. */
.bi-cat5__bar .bi-pop-fchip{
    height: 32px; border-radius: var(--radius-md);
    font-weight: var(--fw-bold);
}
.bi-cat5__bar .bi-pop-fchip.is-sel{
    background: var(--pop-navy); border-color: var(--pop-navy); color: var(--bg-card);
}
.bi-cat5__bar .bi-pop-fchip b{
    background: none; padding: 0; margin-left: var(--space-1_5);
    color: var(--txt-disabled); font-size: var(--fs-base); font-weight: var(--fw-semibold);
}
.bi-cat5__bar .bi-pop-fchip.is-sel b{ background: none; color: rgba(255, 255, 255, .72); }

/* ── 격자 — 줄 키를 못 박는다(겹침이 생길 수 없다) ── */
.bi-cat5__grid{
    flex: 1 1 auto; min-height: 0; overflow-y: auto;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: 250px;
    /* 시안: 띠 아랫선 120 → 카드 위 136. 16 이면 137 로 1 아래인데, 15 는 눈금 밖이라 쓰지 않는다
       (검사 허용 ±2 안이고, 눈금을 깨면 다음 사람이 또 깬다). */
    gap: var(--card-gap); padding: var(--card-pad);
    align-content: start;
}
/* 창이 좁아지면(1280 이하 등) 3열이 203 을 밑돌 수 있다 — 그때만 두 열로 접는다.
   줄 키는 그대로 250 이라 겹치지 않는다. */
@media (max-width: 900px){
    .bi-cat5__grid{ grid-template-columns: repeat(2, 1fr); }
}

.bi-cat5__up{
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-1);
    border: 1px dashed var(--border-base); border-radius: var(--radius-lg);
    background: var(--bg-input); color: var(--txt-muted); cursor: pointer; text-align: center;
}
.bi-cat5__up i{ font-size: 18px; }
.bi-cat5__up b{ font-size: var(--fs-base); color: var(--txt-secondary); }
.bi-cat5__up span{ font-size: var(--fs-xs); }

/* 드래그하여 사진 올리기 — 놓을 자리를 «보여 준다» (2026-09-22 사용자 지적 ④)
   칸에 「드래그하여 추가」 라고 적어 두고도 놓을 자리가 없었다. 동작을 붙이면서
   «여기 놓으면 된다» 를 눈으로도 알려 준다 — 표시가 없으면 되는지 모른 채 놓게 된다.
   ⚠ 기존 .bi-cat5__grid / .bi-cat5__up 규칙은 고치지 않는다(§4) — 상태 클래스만 더한다. */
.bi-cat5__grid.is-dragover{ outline: 2px dashed var(--brand-blue); outline-offset: -4px;
  background: var(--bg-hover); }
.bi-cat5__grid.is-dragover .bi-cat5__up{ border-color: var(--brand-blue); color: var(--brand-blue); }
.bi-cat5__grid.is-dragover .bi-cat5__up b{ color: var(--brand-blue); }
/* 놓는 동안에는 카드가 «마우스를 먹지» 않게 한다 — 자식 위에서 dragleave 가 튀는 것을 줄인다 */
.bi-cat5__grid.is-dragover .bi-cat5__card{ pointer-events: none; }

.bi-cat5__card{
    position: relative; overflow: hidden; cursor: pointer;
    border: 2px solid transparent; border-radius: var(--radius-lg);
    background: var(--gray-200);
}
.bi-cat5__card.is-sel{ border-color: var(--brand-blue); }
.bi-cat5__card img{ width: 100%; height: 100%; object-fit: cover; display: block; }

.bi-cat5__badge{
    position: absolute; left: 8px; top: 8px;
    display: inline-flex; align-items: center; height: 22px; padding: 0 var(--space-2);
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, .92); color: var(--txt-secondary);
    font-size: var(--fs-xs); font-weight: var(--fw-bold);
}
.bi-cat5__badge--ai{ background: var(--bk-run); color: var(--bg-card); }

/* 오른쪽 위 표시는 «고른 것» 하나만 뜻한다 — ★(대표)는 넣지 않는다(§86-2 ⓔ) */
.bi-cat5__mark{
    position: absolute; right: 8px; top: 8px;
    width: 22px; height: 22px; border-radius: var(--radius-full);
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--bg-card); color: var(--txt-disabled); font-size: 11px;
}
.bi-cat5__card.is-sel .bi-cat5__mark{ background: var(--brand-blue); color: var(--bg-card); }

.bi-cat5__cap{
    position: absolute; left: 0; right: 0; bottom: 0;
    padding: 22px var(--space-2_5) var(--space-2_5);
    background: linear-gradient(to top, rgba(17, 24, 39, .78), rgba(17, 24, 39, 0));
    color: var(--bg-card);
}
.bi-cat5__cap small{ display: block; font-size: var(--fs-xs); opacity: .85; }
.bi-cat5__cap b{ display: block; font-size: var(--fs-base); }

/* ── 오른칸 456 — 시안 x 688..1143 ── */
.bi-cat5__prev{
    flex: 0 0 456px; min-width: 0; display: flex; flex-direction: column; min-height: 0;
    border-left: 1px solid var(--pop-line); background: var(--bg-card);
}
/* ⚠ 시안의 y 120 선은 **전폭**이다 — 왼쪽은 칩 띠의 아랫선, 오른쪽은 이 머리의 아랫선.
   둘이 이어져 한 줄로 보인다. 오른쪽만 빠져 있어 선이 왼칸에서 끊겨 있었다. */
.bi-cat5__prevhd{
    flex: 0 0 auto; height: 56px;
    display: flex; align-items: center; gap: var(--space-2); padding: 0 var(--card-pad);
    font-size: var(--fs-base); font-weight: var(--fw-bold);
    border-bottom: 1px solid var(--pop-line);
}
.bi-cat5__prevhd .bi-pop-tag{ background: var(--pop-pill-bg); color: var(--color-info-700); }
.bi-cat5__n{ margin-left: auto; font-size: var(--fs-sm); font-weight: var(--fw-normal); color: var(--txt-muted); }

.bi-cat5__stage{
    /* 시안 — 머리 아랫선 120 → 사진 위 135. 선 아래로 14 를 띄운다 */
    flex: 0 0 auto; position: relative; margin: var(--space-3_5) var(--card-pad) 0; height: 300px;
    border-radius: var(--radius-lg); overflow: hidden; background: var(--gray-200);
}
.bi-cat5__stage img{ width: 100%; height: 100%; object-fit: cover; display: block; }
.bi-cat5__tools{ position: absolute; right: 8px; bottom: 8px; display: flex; gap: var(--space-1_5); }
.bi-cat5__tool{
    width: 26px; height: 26px; border-radius: var(--radius-md);
    border: 1px solid var(--border-base); background: var(--bg-card); color: var(--txt-secondary);
    display: inline-flex; align-items: center; justify-content: center; cursor: pointer; font-size: var(--fs-xs);
}

.bi-cat5__meta{
    flex: 1 1 auto; min-height: 0; margin: 0;
    display: grid; grid-template-columns: 1fr 1fr; align-content: start;
    gap: var(--space-3) var(--space-4); padding: var(--card-pad);
}
.bi-cat5__meta dt{ font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-cat5__meta dd{ margin: 2px 0 0; font-size: var(--fs-base); font-weight: var(--fw-bold); }

/* ⚠ 시안 y 612 에 **오른칸에만** 있는 선이다(왼칸 2% · 오른칸 100%).
   본문 바닥 664 에서 거슬러 612 → 이 줄은 선을 포함해 **53** 이다. */
.bi-cat5__prevfoot{
    flex: 0 0 auto; height: 53px;
    display: flex; align-items: center; gap: var(--space-2); padding: 0 var(--card-pad);
    border-top: 1px solid var(--pop-line);
}
.bi-cat5__prevfoot .bi-btn--danger-soft{ margin-left: auto; }

.bi-cat5__none{
    flex: 1 1 auto; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: var(--space-2); color: var(--txt-muted); font-size: var(--fs-sm);
}

/* ══════════════════════════════════════════════════════════════════════
   §79-2 · 접수 · 시술전표 — 시안 실측으로 «판 826» 맞추기 (2026-09-17)

   시안 buysell2.png 실측 — 판 x 285..1900(1616) · y 86..911(**826**) · 열 330/860/425
     («여백선 훑기» — 열 왼테두리에서 8px 안쪽을 위에서 아래로 훑은 값. §_SPEC_CHECKLIST §2-14)

     좌 · 고객 대기열   판y  57 머리 ·  105 탭검색판(연회색) ·  562 목록 ·  43 바닥요약   합 767
     중 · 고객·AI·이력  판y 116 (고객 줄 + AI 칩 줄) · **173 전폭선** · 651 전표 이력
     우 · 시술전표      판y  86 머리 · **143 선** · 163 선택된 시술 · **306 선**
                        · 415 «자주 쓰는 시술»(연회색 #F5F6F9) · **721 선** · 103 합계+저장

   처음 만들 때 판이 **902** 였다(76 큼) — 우측의 목록 키를 눈대중으로 잡았기 때문이다.
   매출등록에서 배운 대로 «띠마다 키를 박는다» (§78-6·§78-7).
   ------------------------------------------------------------------ */

/* 우 열 — 띠 넷의 합이 767 이 되게 못 박는다(86 + 163 + 415 + 103 = 767) */
.bi-rs .bi-rs-slip > .bi-rs-slip__hd { height: 48px; padding: var(--space-4) var(--space-4) 0; }
.bi-rs .bi-rs-slip > .bi-rs-slip__meta {
  height: 38px; padding: 0 var(--space-4) var(--space-2);
  border-bottom: 1px solid var(--border-base); }

.bi-rs .bi-rs-slip > .bi-rs-picked {
  flex: 0 0 auto; height: 163px; display: flex; flex-direction: column;
  padding: var(--space-3) var(--space-4) var(--space-2_5);
  border-bottom: 1px solid var(--border-base); }
.bi-rs .bi-rs-picked > .bi-rs-items { flex: 1 1 auto; height: auto; min-height: 0; }

/* 자주 쓰는 시술 — 시안은 «연회색 판» 이다(판y 307..720 · #F5F6F9 = --pop-band) */
.bi-rs .bi-rs-slip > .bi-rs-often {
  flex: 0 0 auto; height: 415px; margin-top: 0;
  padding: var(--space-3) var(--space-4);
  background: var(--pop-band); border-top: 0;
  border-bottom: 1px solid var(--border-base); }
.bi-rs .bi-rs-often > .bi-rs-grid { flex: 1 1 auto; height: auto; min-height: 0; }

.bi-rs .bi-rs-slip > .bi-rs-foot {
  flex: 0 0 auto; height: 103px; margin-top: 0;
  padding: var(--space-2_5) var(--space-4); border-top: 0; }

/* 중 열 — 고객 줄 + AI 줄이 116, 그 아래 전폭선, 이력이 남는 키를 먹는다 */
/* 가운데 열 — 칸 사이 틈은 매출등록과 같은 값(§78-9 `.bi-bs2-cols > .bi-bs2-mid`) */
.bi-rs .bi-rs-mid { gap: var(--space-1_5); }
.bi-rs .bi-rs-mid > .bi-rs-cust { height: 64px; padding: var(--space-4) var(--space-4) 0; }
.bi-rs .bi-rs-mid > .bi-rs-ai { height: 52px; padding: 0 var(--space-4) var(--space-3); }
/* ⚠ 2026-09-17 검수에서 잡힘 — 여기에 «키» 가 없으면 목록이 내용만큼 늘고 판이 따라 늘어난다
   (전표 이력 12줄 → 판 825 → **1549**). 「남는 키를 먹는다」 는 말은 부모가 묶여 있을 때만
   참이다. 좌 열(대기 562)·우 열(담김 163·자주 415)처럼 시안 실측 키를 준다.
   64(고객) + 52(AI) + 651(이력) = 767 → 세 열이 같은 키가 되고 판은 825 로 고정된다. */
.bi-rs .bi-rs-mid > .bi-rs-hist {
  flex: 0 0 auto; height: 651px; min-height: 0; display: flex; flex-direction: column;
  border-top: 1px solid var(--border-base); padding: var(--space-3) var(--space-4) var(--space-4); }
/* 목록은 «묶인» 이력 덩이 안에서 남는 키를 먹고 스크롤한다 — 이제 위가 651 로 묶였다 */
.bi-rs .bi-rs-hist > .bi-rs-hlist { flex: 1 1 auto; height: auto; min-height: 0; overflow-y: auto; }

/* §79-2 끝 ───────────────────────────────────────────────────────── */

/* ══ §86 팝업 폼 — 덩이 사이 간격을 «일정하게» (2026-09-17) ═══════════════════
   사용자: 「항목간 간격 … 고객명, 디자이너, 시간, 시술상품, 메모 간에
            **사이 간격이 일정하지 않다**는거야」

   실측(고치기 전) — 덩이 사이 틈:
     예약등록  note→고객명 0 · 고객명→디자이너 12 · 디자이너→시간 12 · 시간→시술상품 16 · 시술상품→메모 16
     입고등록  0 · 12 · 12 · 16 · 16 · 12
   덩이마다 제 margin 을 들고 있어 «더해지고 무너지고» 했다. 규격안의 주된 값은 16 이다.

   ⚠ margin 으로 맞추면 또 어긋난다(위·아래가 겹치고 collapse 한다) —
     세로 flex + gap 으로 **한 곳에서** 정한다. 자식의 세로 margin 은 0 으로 눕힌다.
     §85 의 .bi-bq-sec margin-bottom 도 여기서 대신한다(아래 틈 16 그대로). */
.bi-bq-pop .bi-pop-pad--form {
    display: flex; flex-direction: column; gap: var(--space-4);   /* 16 */
}
.bi-bq-pop .bi-pop-pad--form > * { margin-top: 0; margin-bottom: 0; }

/* ══ §78-10 · 매출등록 — 화면 높이 채우기 · 좁은 화면 대기 띠 (2026-09-18) ══════
   사용자 지적 ⑮: 「페이지 길이가 825px 인가 까지만 되어있어서 화면해상도가 클경우
                   다른페이지들과 다르게 비어 보여. 해상도에 맞게 나오게 해줘」
   사용자 지적 ⑯: 「해상도를 줄였을때 대기(좌측)영역이 위로 가는데 … 길게 늘어저있어」(bs1.png)

   ⚠ «창» 에는 맞춰 늘리고 «내용» 에는 늘리지 않는다 — 내용이 늘면 목록이 스크롤한다.
     (probe_bs2_grow · probe_rs_grow 가 그것을 지킨다)
   ⚠ 시안 판 키 826 은 «최소» 로 남긴다 — 짧은 화면에서 시안보다 작아지지 않게. */
.bi-bs2,
.bi-rs { min-height: calc(100vh - var(--header-height, 64px)); }
.bi-bs2 .bi-bs2-card {
  display: flex; flex-direction: column;
  min-height: 826px;
  height: calc(100vh - var(--header-height, 64px) - var(--content-pad, 16px) * 2); }
.bi-bs2 .bi-bs2-card > .bi-bs2-cols { flex: 1 1 auto; min-height: 0; }
/* 남는 키를 먹는 것은 «목록» 뿐이다 — 판이 아니라 */
.bi-bs2 .bi-bs2-q > .bi-bs2-qlist { flex: 1 1 auto; height: auto; min-height: 120px; }
/* ⚠ 최근내역·보유정액권은 «3줄 고정 + 더보기» 다(2026-09-17 사용자 요청) —
   여기서 flex:1 을 주면 30줄일 때 1200 으로 늘어 스크롤이 사라진다. 늘리지 않는다.
   가운데 열의 남는 키는 내역표가 먹는다(§78-7 에서 이미 그렇게 세워 두었다). */

@media (max-width: 1599px) {
  /* 대기 열이 «위 띠» 로 올라간다 — 그러면 목록 키 562 는 말이 안 된다.
     한 줄짜리 가로 띠로 눕히고 키를 카드 한 장 높이로 줄인다(사용자 지적 ⑯). */
  .bi-bs2 .bi-bs2-card { height: auto; min-height: 0; }
  .bi-bs2 .bi-bs2-q > .bi-bs2-qlist { height: 132px; min-height: 0; flex: 0 0 auto;
    flex-direction: row; overflow-x: auto; overflow-y: hidden; }
  .bi-bs2 .bi-bs2-q > .bi-bs2-qfoot { height: 43px; }
  .bi-bs2 .bi-bs2-mid > .bi-bs2-pnls { min-height: 220px; }
}

/* §78-10 끝 ─────────────────────────────────────────────────────── */

/* ══ §79-3 · 접수·시술전표 — 기능이 붙으면서 생긴 자리들 (2026-09-18) ══════════
   ① 고객 «고르기 / 고른 뒤» 두 모습  ② 고객메모 접이  ③ 시술 메모 펼침
   ④ 전표 이력 더보기  ⑤ 담당 디자이너 칸  ⑥ 화면 높이 채우기·좁은 화면 */

/* ── ① 고객 줄 — 두 모습을 «클래스 하나» 로 바꾼다(아이디에 display 를 주지 않는다) ── */
.bi-rs .bi-rs-cust > .bi-rs-pickedrow { display: none; }
.bi-rs .bi-rs-cust.is-picked > .bi-rs-pickrow { display: none; }
.bi-rs .bi-rs-cust.is-picked > .bi-rs-pickedrow { display: flex; align-items: center; gap: var(--space-3); width: 100%; }
/* ⚠ 2026-09-22 사용자 지시 — 「고객명 연락처 영역 매출등록과 동일하게 … 현재 고객명이 2/3 영역을 차지함」.
   까닭: flex 로 `1 1 260px` / `0 1 200px` 를 주어 고객명이 남는 자리를 다 먹었다.
   매출등록(.bi-bs2-cust__pick)은 **격자 1fr 1fr** 이라 둘이 «반반» 이다. 같게 맞춘다.
   ⚠ 간편고객등록 단추는 여기서 이미 뺐으므로(지적 ⑪) 세 번째 auto 칸은 두지 않는다. */
.bi-rs-pickrow { display: grid; grid-template-columns: 1fr 1fr;
  gap: var(--space-3); align-items: end; width: 100%; }
.bi-rs-ava--none { background: var(--bg-input); color: var(--txt-disabled); }
/* 칸 — 매출등록 .bi-bs2-f 와 같이 «블록» 이다(라벨이 제 아래여백을 갖는다) */
.bi-rs-pf { display: block; min-width: 0; }
/* ⚠ 라벨 글꼴은 매출등록과 «한 규칙» 으로 합쳐 두었다(위 .bi-bs2-lb 자리 · 사용자 지시).
     전에는 여기서 따로 12px/bold 를 주고 있었다 — 매출등록은 13px/semibold 다. */
.bi-rs-lb > em { font-style: normal; color: var(--color-danger-600); }
/* ⚠ 2026-09-22 사용자 지시 — 「고객명 INPUT 태그와 돋보기 버튼 UI 결제/매출등록과 동일하게」.
   매출등록(.bi-bs2-inrow / .bi-bs2-schbtn)은 «붙어 있는» 모양이다 —
     · 사이 틈 0 · 입력칸의 오른쪽 모서리는 각지게
     · 단추는 왼쪽 테두리를 없애고 오른쪽만 둥글게 · 바탕은 --bg-input
   전에는 틈 6px 에 단추가 «따로 뜬 네모» 였다.
   ⚠ bi-rs-* 는 이 화면만 쓴다(L1 SPEC-SINGLE-USE 로 확인) — 고쳐도 다른 화면이 따라 움직이지 않는다. */
/* ⚠ gap 을 «적지 않는다» — 0 이 기본값이라 적으면 .bi-bs2-inrow 와 선언이 한 글자도
     안 달라져 SPEC-DUP 으로 잡힌다. 없는 선언이 가장 깨끗하다. */
.bi-rs-inrow { display: flex; align-items: stretch; }
.bi-rs-inrow .bi-rs-in { border-top-right-radius: 0; border-bottom-right-radius: 0; }
/* ⚠ 2026-09-22 사용자 지시 — 「연락처 input 태그 width … 매출등록과 동일하게」.
   까닭: 폭을 «flex» 로만 주고 있었다. 고객명은 .bi-rs-inrow(flex) 안이라 늘어났지만,
     연락처는 칸(.bi-rs-pf)이 block 이 되면서 flex 가 안 먹어 **브라우저 기본 폭**으로 쪼그라들었다.
     매출등록(.bi-bs2-in)은 width:100% 를 갖는다 — 같게 둔다. flex 값은 그대로 두어
     .bi-rs-inrow 안에서의 늘어남도 유지한다. */
.bi-rs-in { width: 100%; flex: 1 1 auto; min-width: 0; height: 36px; padding: 0 var(--space-2_5);
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); font-size: var(--fs-base); color: var(--txt-primary); }
.bi-rs-in::placeholder { color: var(--txt-disabled); }
/* 검색 단추 — 사다리가 아니라 «붙어 있는 입력칸» 의 키를 따른다(btn_ladder 사다리예외 36) */
.bi-rs-schbtn { flex: 0 0 auto; width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-base); border-left: 0;
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  background: var(--bg-input); color: var(--txt-muted); font-size: var(--fs-base); }
.bi-rs-schbtn:hover { background: var(--bg-hover); }
.bi-rs-cust__btn--reg { flex: 0 0 auto; height: 36px; }
/* ⚠ 「고객 다시 고르기」 ⇄ — 이 단추에 아무 규칙도 없어 브라우저 기본 모양이었다
   (L1 CLASS-ORPHAN 으로 드러났다). 매출등록의 짝(.bi-bs2-cust__chg)과 같은 결로 맞춘다. */
.bi-rs-cust__chg { flex: 0 0 auto; width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); color: var(--txt-muted); font-size: var(--fs-sm); }
.bi-rs-cust__chg:hover { background: var(--bg-input); }
/* ⚠ ‘고객 다시 고르기’ ⇄ — 이 단추에 아무 규칙도 없어 및라우저 기본 모양이었다
   (L1 CLASS-ORPHAN 으로 드러났다). 매출등록의 짝(.bi-bs2-cust__chg)과 같은 결로 맞춘다. */
.bi-rs-cust__chg { flex: 0 0 auto; width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); color: var(--txt-muted); font-size: var(--fs-sm); }
.bi-rs-cust__chg:hover { background: var(--bg-input); }

/* ── ② 고객메모 접이 — 닫힌 것이 기본 ── */
.bi-rs-cmemo { display: none; flex-direction: column; gap: var(--space-1_5);
  padding: 0 var(--space-4) var(--space-3); }
.bi-rs-cmemo.is-open { display: flex; }
.bi-rs-cmemo__ta { width: 100%; min-height: 56px; padding: var(--space-2) var(--space-2_5);
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); font-size: var(--fs-base); color: var(--txt-primary); resize: vertical; }
.bi-rs-cmemo__save { align-self: flex-end; height: 32px; padding: 0 var(--space-3);
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-primary); }

/* ── ③ 시술 메모 — 그 줄만 펼친다 ── */
.bi-rs-hrow__memobody { display: none; margin-top: var(--space-2);
  padding: var(--space-2_5); border-radius: var(--radius-md);
  background: var(--bg-input); font-size: var(--fs-sm); color: var(--txt-secondary);
  white-space: pre-wrap; }
.bi-rs-hrow.is-memo > .bi-rs-hrow__memobody { display: block; }
.bi-rs-hrow.is-memo > .bi-rs-hrow__memo > .fa-chevron-down { transform: rotate(180deg); }

/* ── ④ 전표 이력 더보기 — 매출등록의 «더보기» 와 같은 키(38) ── */
.bi-rs-more { flex: 0 0 auto; width: 100%; height: 38px;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1_5);
  margin-top: var(--space-2); border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--txt-secondary); }
.bi-rs-more:hover { background: var(--bg-input); }
.bi-rs-more.bi-hidden { display: none; }

/* ── ⑤ 담당 디자이너 칸 — 전표 머리줄에 앉는다 ── */
.bi-rs-empbox { flex: 0 0 auto; display: inline-flex; align-items: center; gap: var(--space-1);
  height: 32px; padding: 0 var(--space-1_5) 0 var(--space-2_5);
  border: 1px solid var(--border-base); border-radius: var(--radius-md); background: var(--bg-card); }
.bi-rs-empbox__in { width: 118px; border: 0; background: transparent;
  font-size: var(--fs-sm); color: var(--txt-primary); }
.bi-rs-empbox__ico { width: 24px; height: 24px; border: 0; background: transparent;
  color: var(--txt-muted); font-size: var(--fs-xs); }

/* ── ⑥ 판이 화면 높이를 채운다(⑮) · 좁은 화면에서 대기 띠(⑯) ── */
.bi-rs .bi-rs-card {
  display: flex; flex-direction: column;
  min-height: 826px;
  height: calc(100vh - var(--header-height, 64px) - var(--space-4) * 2); }
.bi-rs .bi-rs-card > .bi-rs-cols { flex: 1 1 auto; min-height: 0; }
/* 남는 키를 먹는 것은 «목록» 뿐이다 — 판이 아니라(2026-09-17 검수 교훈) */
.bi-rs .bi-rs-q > .bi-rs-qlist { flex: 1 1 auto; height: auto; min-height: 120px; }
.bi-rs .bi-rs-mid > .bi-rs-hist { flex: 1 1 auto; height: auto; min-height: 200px; }
.bi-rs .bi-rs-slip > .bi-rs-often { flex: 1 1 auto; height: auto; min-height: 160px; }

@media (max-width: 1599px) {
  /* 대기 열이 «위 띠» 로 올라간다 — 목록을 가로로 눕히고 키를 카드 한 장으로 줄인다.
     사용자 지적 ⑯: 「영역이 위로가는건 좋아 그에 맞게 디자인 잡아줘야해」 */
  .bi-rs-cols { grid-template-columns: minmax(0, 1fr) 425px; }
  .bi-rs-cols > .bi-rs-q { grid-column: 1 / -1; border-bottom: 1px solid var(--border-base); }
  .bi-rs-cols > .bi-rs-q + * { border-left: 0; }
  .bi-rs .bi-rs-card { height: auto; min-height: 0; }
  .bi-rs .bi-rs-q > .bi-rs-qlist { height: 132px; min-height: 0; flex: 0 0 auto;
    flex-direction: row; overflow-x: auto; overflow-y: hidden; }
  .bi-rs .bi-rs-q .bi-rs-qcard { width: 240px; flex: 0 0 auto; }
  .bi-rs .bi-rs-qtabs, .bi-rs .bi-rs-qsearch { max-width: 330px; }
  .bi-rs .bi-rs-mid > .bi-rs-hist { min-height: 320px; }
}
@media (max-width: 1279px) {
  .bi-rs-cols { grid-template-columns: minmax(0, 1fr); }
  .bi-rs-cols > * + * { border-left: 0; border-top: 1px solid var(--border-base); }
  .bi-rs-pickrow { flex-wrap: wrap; }
}

/* ══ §79-4 · 접수·시술전표 — 고객 영역을 결제/매출등록과 같은 구성으로 (2026-09-22) ══
   사용자 지시: 「담당디자이너, 방문동향 성별 매출메모를 결제매출등록 페이지와 동일하게 표시」
              「고객선택시에만 AI 고객분석 영역이 나타나도록」
              「고객명 왼쪽 아이콘은 … 선택시에만 결제매출등록처럼 표시」
   ⚠ 매출등록의 .bi-bs2-* 규칙을 «나눠 쓰지 않는다» — 한쪽을 고치면 다른 쪽이 따라 움직인다.
     값은 같게 두되 이름은 이 화면 것(bi-rs-*)으로 새로 둔다(§79 머리말과 같은 판단). */

/* 세 칸 — 담당 디자이너 220 · 방문 동향 180 · 성별 180 (매출등록 .bi-bs2-frow 와 같은 치수) */
/* 세 칸 — 매출등록 .bi-bs2-frow 와 같은 치수(220 / 180 / 180 · 간격 10)와 같은 여백.
   ⚠ 여백도 매출등록을 따른다(§78-9 실측): frow 는 `0 16`, 매출메모는 `0 16 8`.
     전에는 둘 다 `12 16 0` 이라 매출메모 «아래» 가 붙어 있었다
     (사용자: 「매출메모 아래 간격도 결제/매출전표와 동일하게」). */
.bi-rs-frow { display: grid; grid-template-columns: 220px 180px 180px;
  gap: var(--space-2_5); justify-content: start;
  padding: 0 var(--space-4); }
.bi-rs-frow > .bi-rs-pf { min-width: 0; }
/* 담당 디자이너 칸이 세 칸 격자 안에서 제 폭·키를 갖게 한다(전에는 전표 판의 인라인 자리였다).
   ⚠ 원래 키가 32 였다 — 옆의 방문 동향(36)·성별(36)과 4px 어긋나 아랫선이 안 맞는다.
     세 칸은 한 줄이므로 키를 맞춘다. 안쪽 입력칸도 폭을 칸에 맡긴다(118px 고정이었다). */
.bi-rs-frow .bi-rs-empbox { width: 100%; height: 36px; }
.bi-rs-frow .bi-rs-empbox__in { width: auto; flex: 1 1 auto; min-width: 0; font-size: var(--fs-base); }

/* 방문 동향 — 화살표는 브라우저 것을 쓰지 않는다(매출등록과 같다).
   ⚠ 별도의 .bi-rs-sel 규칙을 두지 않는다 — 선언이 .bi-bs2-sel 과 한 글자도 안 달라
     SPEC-DUP 으로 잡힌다. 이미 있는 이 규칙 안에 넣는다(클래스는 마크업에서도 뺐다). */
.bi-rs select.bi-rs-in { width: 100%; height: 36px; appearance: none; }

/* 성별 — 라디오는 숨고 :checked 만 쓴다(매출등록 .bi-bs2-seg 와 같은 방식).
   ⚠ 라디오와 라벨을 한 규칙으로 합치지 않는다 — 합치면 라디오가 보인다(§78-5 교훈). */
.bi-rs-seg { display: grid; grid-template-columns: 1fr 1fr; height: 36px;
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  overflow: hidden; background: var(--bg-card); }
.bi-rs-seg__r { position: absolute; opacity: 0; pointer-events: none; }

/* ⚠⚠ 전역 `input[type="radio"]+label`(style.css:697)이 라벨을 **18×18 스프라이트**
   (radio.png · position:relative · top:3px)로 만든다 — 그대로 두면 세그먼트가 뭉개진다.
   실측으로 확인했다: 칸은 89×36 인데 라벨이 **18×18** 이라 「여 / 남 성」 으로 깨졌다.
   매출등록이 §78-6 에서 이미 겪고 적어 둔 함정이다 — 같은 방식으로 받는다.
   ⚠ 옛 전역 규칙은 **고치지 않는다**(§4). 특이도는 «나중» 이 아니라 «더 긴 선택자» 가 이긴다. */
.bi-rs .bi-rs-seg__r + .bi-rs-seg__lb {
  display: inline-flex; align-items: center; justify-content: center;
  width: auto; height: auto; background-image: none; position: static; top: auto;
  /* 2026-09-23 사용자 지시 — 글자 크기는 결제/매출등록의 같은 세그먼트와 같다(--fs-md 14).
     여기만 13 이라 같은 성별 칸이 두 화면에서 다르게 읽혔다. */
  font-size: var(--fs-md); font-weight: var(--fw-semibold); color: var(--txt-secondary); cursor: pointer; }
.bi-rs .bi-rs-seg__r:checked + .bi-rs-seg__lb {
  background-image: none; background-color: var(--pop-navy); color: var(--bg-card); }

/* 매출 메모 — 전폭 한 줄(매출등록 .bi-bs2-memo 와 같다). 고객메모와 «다른 것» 이다. */
.bi-rs-memo { display: block; min-width: 0; padding: 0 var(--space-4) var(--space-2); }
/* ⚠ 2026-09-22 사용자 지시 — 「매출메모 placeholder 내부 scroll 속성 매출등록과 동일하게」.
   매출등록이 §78-7 에 똑같은 흠을 적어 두었다(사용자 지적 2026-09-17):
     「매출 메모 입력칸이 위아래로 가운데가 아니라서 **입력 전부터 스크롤이 생겨있어**」
   키 36 에 위아래 여백을 주면 글줄(줄높이 ≈20)이 내용상자(36−여백−테두리)에 안 들어가
   곧바로 스크롤이 나고 글이 위로 붙는다.
   → 위아래 여백 0 · 줄높이 34(=36−테두리2)로 가운데 맞추고 overflow:hidden. */
.bi-rs-memo__ta { width: 100%; height: 36px; padding: 0 var(--space-2_5); line-height: 34px;
  overflow: hidden; font-size: var(--fs-base); resize: none; font-family: inherit;
  border: 1px solid var(--border-base); border-radius: var(--radius-md);
  background: var(--bg-card); color: var(--txt-primary); }
.bi-rs-memo__ta::placeholder { color: var(--txt-disabled); }

/* 고객을 «고르기 전» 에 감추는 것은 **AI 고객분석 줄 하나뿐** 이다(2026-09-22 사용자 지시).
   ⚠ 처음엔 세 칸(담당/방문동향/성별)과 매출 메모도 같이 감췄다 — 사용자가 바로잡았다:
     「고객명연락처 담당디자이너 방문동향성별 매출메모가 **상시로** 보여야해」.
     그것들은 «채워 넣는 칸» 이라 고르기 전에도 자리가 있어야 한다.
     AI 분석만 «고객이 있어야 값이 있는» 것이다.
   ⚠ 아이디에 display 를 주지 않는다(함정 F2) — 부모 #rs_mid 의 클래스 하나로만 가른다. */
.bi-rs .bi-rs-mid:not(.is-picked) > .bi-rs-ai { display: none; }

/* §79-4 끝 ─────────────────────────────────────────────────────── */

/* §79-3 끝 ─────────────────────────────────────────────────────── */

/* ══ §88 검색칸은 «카드에 안 싸인다» — 시안 정합 (2026-09-21) ══════════════════
   시안(reimg/d2.png)의 왼쪽 사이드를 세로선으로 읽으면 이렇다:
       y71~84  회색 바탕  ·  y87~122  흰 판(= 입력칸 그 자체, 36px)  ·  y125~133  회색 바탕
   즉 검색칸 둘레에 «흰 카드» 가 없다. 카드로 감싸면 14+40+14+테두리 = 70 이 되어
   시안보다 32px 높고, 그만큼 사이드 전체가 길어진다.
   ⚠ 감싸개 .bi-bk2-card 는 지우지 않는다 — 답안지가 「흰 카드 넷」 을 세고 JS 가 자리를 잡는다.
     보이는 것만 걷는다. */
.bi-bk2-card--bare {
    background: transparent; border: 0; padding: 0; box-shadow: none;
}
/* 입력칸 키 36 = 시안 실측 (전엔 40) */
.bi-bk2-card--bare .bi-bk2-search > input { height: 36px; }

/* ══ §89 · 메인 대시보드 — 사용자 지시 2026-09-28 ═══════════════════════════════
   「예약현황, 매출현황 에서 예약/완료/취소, 접수/완료 … 탭 같은 건데 눌러서 선택하는 건지
     잘 모르겠어. 디자인상 탭을 선택 가능하다는 임팩트가 필요해」
   지금도 누를 수 있고 .is-active 도 붙지만, 켜진 표시가 «테두리 색» 하나뿐이라
   어두운 타일(navy·purple)에서는 거의 보이지 않는다. 그래서 «고를 수 있다» 도,
   «지금 이게 켜졌다» 도 읽히지 않았다.
   ⚠ 기존 .bi-stat 규칙은 한 줄도 고치지 않는다(§4) — 새 규칙만 더한다.
   세 가지로 말한다: ① 얹으면 뜬다(누를 수 있다) ② 켜진 것은 «아래 밑줄» 로 못박는다
   ③ 켜진 것만 또렷하고 꺼진 것은 한 단 옅다(탭 줄에서 고른 하나가 드러나게).            */
.bi-statgrid .bi-stat { transition: border-color .15s, box-shadow .15s, transform .12s, opacity .15s; }
.bi-statgrid .bi-stat:not(.is-active) { opacity: .72; }
.bi-statgrid .bi-stat:hover { transform: translateY(-1px); box-shadow: var(--shadow-md); opacity: 1; }
.bi-statgrid .bi-stat:focus-visible { outline: 2px solid var(--brand-blue); outline-offset: 2px; }
/* ⚠ 2026-09-28 사용자 지시 — 「탭부분 아래에 줄표시 이상해. 차라리 선택된 탭이 그림자로
   살짝 떠보이는게 좋겠어」. 밑줄(::after)을 걷고 «떠오름» 으로 바꾼다.
   떠오름은 세 가지가 함께 말한다: 살짝 올라가고(-2px) · 그림자가 짙고 · 또렷하다(opacity 1).
   어두운 타일(navy·purple)은 그림자가 묻히므로 한 단 더 짙게 준다. */
.bi-statgrid .bi-stat.is-active {
  opacity: 1;
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}
.bi-statgrid .bi-stat--navy.is-active,
.bi-statgrid .bi-stat--purple.is-active { box-shadow: var(--shadow-xl, var(--shadow-lg)); }
/* 2026-09-28 사용자 지시 — 「선택되었을때 파란색 테두리가 이상해. 텝 안쪽 배경색과 맞는
   테두리색으로 해줘」. 기본 규칙(6105)이 켜진 칸에 --brand-blue 를 주는데, 네이비·보라 타일
   위에서는 그 파랑이 겉돈다. 칸마다 «제 배경과 같은 색» 으로 덮는다.
   ⚠ 6105 는 다른 화면도 쓰는 공통 규칙이라 고치지 않는다 — 대시보드 안에서만 덮어쓴다.
   흰 타일은 테두리를 배경색(흰색)에 맞추므로 사실상 사라진다 — 켜짐은 «떠오름»(그림자)이 말한다. */
.bi-statgrid .bi-stat.is-active        { border-color: var(--bg-card); }
.bi-statgrid .bi-stat--navy.is-active  { border-color: var(--brand-navy); }
.bi-statgrid .bi-stat--purple.is-active { border-color: var(--brand-purple); }
/* 얹었을 때는 «더» 뜨지 않는다 — 켜진 것과 헷갈린다. 얹음은 그림자만 살짝. */
.bi-statgrid .bi-stat:hover:not(.is-active) { transform: none; box-shadow: var(--shadow-md); }

/* 표 — 예약·매출 두 판의 칸 수와 정렬을 같게(사용자: 「데이터 정렬 맞춰줘야함」).
   시간은 고정폭으로 왼쪽에 세워 두 표의 첫 칸이 같은 자리에서 시작하게 한다. */
.bi-simpletbl .bi-dash-col-time { width: 84px; white-space: nowrap; text-align: left; }
/* ⚠ 2026-09-28 사용자 지시 — 「고객명이 조금더 우측으로 가고, 이름이 길면 ...으로 나오는데
   칸이 넓은데 더 길게 표기해도 되」. 칸을 오른쪽으로 물리고 «줄임» 이 늦게 오게 넓힌다.
   (글자 수 상한은 script.js 에서 10 → 24 로 함께 올렸다 — 둘 중 하나만 고치면 그대로다.) */
.bi-simpletbl th:nth-child(2), .bi-simpletbl td.bi-simpletbl__name { padding-left: var(--space-6); }
.bi-simpletbl td.bi-simpletbl__name { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bi-simpletbl th:nth-child(3), .bi-simpletbl td.bi-simpletbl__cell { width: 34%; }

/* ⚠ 2026-09-28 사용자 지시 — 「디자이너에 헤더와 아래 각 디자이너 설명 부분이 딱붙어있는데
   헤더는 오늘 예약현황처럼 해줘」. 예약현황 머리(.bi-write-card__header)는 바탕·아래선·여백을
   갖는데, 캐러셀은 판 안에 머리를 그냥 얹어 두어 카드와 맞붙어 있었다.
   ⚠ .bi-write-card__header 규칙 자체는 고치지 않는다 — 캐러셀 안에서만 같은 모습이 되게 한다.
      (.bi-carousel 은 padding 24 를 갖고 있어 머리를 그 밖으로 물려야 예약현황과 같은 꼴이 된다) */
.bi-carousel > .bi-write-card__header {
  margin: calc(var(--space-6) * -1) calc(var(--space-6) * -1) var(--space-6);
  border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
}

/* 디자이너 카드 아래 예약·접수·완료 — 누를 수 있는 것으로 보이게(사용자 지시 2026-09-28).
   ⚠ .bi-carousel__stat 규칙은 고치지 않는다 — 누를 수 있는 것에만 덧입힌다. */
.bi-carousel__stat--go {
  border: 0; background: transparent; padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-md); cursor: pointer;
  transition: background .15s, transform .12s;
}
.bi-carousel__stat--go:hover { background: var(--bg-input); transform: translateY(-1px); }
.bi-carousel__stat--go:focus-visible { outline: 2px solid var(--brand-blue); outline-offset: 2px; }

/* 디자이너 사진이 «없거나 못 찾을 때» — 사용자: 「밝은 톤 이미지로 다시 했으면 해」.
   전에는 --border-light 바탕에 --txt-disabled 아이콘이라 어둡고 칙칙했다. */
.bi-carousel__avatar .bi-carousel__avatar-ph {
  background: var(--bg-input);
  color: var(--color-info-300, var(--brand-blue));
  border: 2px solid var(--white);
}
.bi-carousel__avatar .bi-carousel__avatar-ph > i { opacity: .55; }

/* ══ §90 · 고객 등급 표식 + 「도는 중」 표시 — 공통 부품 (2026-09-28) ═══════════
   사용자 지시 둘:
     ① 「고객등급이 **일반일때는 별모양 아이콘, VIP 일때는 왕관 모양** 아이콘으로 변경해줘
        그리고 **네모로 된건 동그라미로 통일**해줘」
     ③ 「전 페이지 스크립트 동작시 **시간이 걸리는경우 로딩이미지가 나오든지** 했으면 해」

   ⚠ 기존 아바타 규칙(.bi-bs2-ava · .bi-rs-ava · .bi-pop-avt · .bi-bk2-ava)을 **고치지 않는다.**
     그 넷은 이미 --radius-full 이고 크기·색이 화면마다 다르다. 여기서는 «안에 무엇이 들어가나»
     만 정하고, 크기는 그 화면 클래스가 그대로 정하게 둔다(같이 입힌다).
   ⚠ 색만으로 등급을 말하지 않는다 — 모양(별/왕관)이 먼저이고 `title`·`aria-label` 이 글자를 남긴다.
   값을 만드는 자리는 `lib/js/function.js` 의 `biGradeIcon()` 하나다. */
.bi-grade {
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: var(--radius-full);          /* 네모로 된 자리를 동그라미로 통일한다 */
    /* ⚠ 2026-09-28 사용자 지시 — 「고객등급이 일반일때 **회색이 너무 안좋아보여** 다른 색으로」.
         회색(--gray-200)은 «꺼진 것·막힌 것» 의 색이라 등급이 아예 없는 것처럼 보였다.
         별(★)에 어울리는 앰버로 바꾼다 — 이미 있는 토큰이고 VIP 의 네이비와도 또렷이 갈린다. */
    background: var(--color-warning-100); color: var(--color-warning-700);
    line-height: 1;
}
/* 크기를 스스로 정하지 않는다 — 함께 입힌 화면 클래스(.bi-bs2-ava 등)가 정한다.
   홀로 쓸 때만 쓰는 기본값 */
/* ⚠ 2026-09-28 — 이 줄의 :not() 둘이 특이도를 (0,3,0) 으로 올려 «화면 클래스를 이겼다».
     대기열 아바타 이름은 -qav(.bi-bs2-qav · .bi-rs-qav) 라 무늘에 안 걸렸고,
     40 이어야 할 자리가 조용히 34 로 줄었다(답안지가 잡았다 — 없었으면 못 봤다).
     무늬에 -qav 를 더한다. 새 아바타 이름을 만들 때 **여기도 같이** 본다. */
.bi-grade:not([class*="-ava"]):not([class*="-avt"]):not([class*="-qav"]) { width: 34px; height: 34px; flex: 0 0 34px; }
.bi-grade > i { font-size: var(--fs-md); }
/* VIP — 왕관. 시안의 등급 강조색을 그대로 쓴다(새 색을 만들지 않는다) */
.bi-grade--vip,
.bi-rs-qav--vip { background: var(--color-info-900); color: var(--bg-card); }

/* ── 「도는 중」 — 화면 위에 겹친다. 기존 #load_img(.bi-loading)와 다른 자리다 ──
   .bi-loading 은 «그 판 안»(position:absolute)을 덮고, 이것은 «창 전체»(fixed)를 덮는다.
   둘이 같이 뜨지 않게 function.js 가 #load_img 가 보이면 이쪽을 띄우지 않는다. */
.bi-busy {
    position: fixed; inset: 0; z-index: 9998;
    display: flex; align-items: center; justify-content: center;
    /* 막 색은 모달 막(.bi-modal-ov)과 같은 만드는 법을 쓴다 — 리터럴 hex 를 새로 만들지 않는다.
       다만 이것은 «잠깐» 뜨는 것이라 훨씬 옅게(12%) 둔다. */
    background: color-mix(in srgb, var(--black) 12%, transparent);
}
.bi-busy__box {
    display: inline-flex; align-items: center; gap: var(--space-2_5);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-lg);
    background: var(--bg-card); box-shadow: var(--shadow-md);
    font-size: var(--fs-base); color: var(--txt-secondary);
}
.bi-busy__box > i { font-size: var(--fs-lg); color: var(--color-info-700); }
/* ⚠ `#bi_busy.bi-hidden` 을 «함께» 선언한다 — id 는 특이도 100 이라 클래스(10)를 이긴다.
   이 한 줄이 없어 로딩막이 안 걷힌 전례가 있다(§36 주석 · 2026-08-07 · 함정 F2).
   ⚠ `!important` 는 쓰지 않는다 — 특이도로 이미 이긴다(§4 절대규칙·AB-IMPORTANT). */
#bi_busy.bi-hidden { display: none; }

/* ══ §91 · 수량은 «직접 입력» 이다 — ‒/+ 단추를 걷은 자리 (2026-09-28) ══════════
   사용자 지시: 「수량등에 - + 로 조정되게 되어있는 경우에는 **- + 기능을 빼고 숫자 기입**하도록」
                「+ - 들어있는거 빼달라니까 **그냥 입력폼으로** 해줘」

   걷은 곳 다섯 — 매출등록·예약등록 전표(원래 input 이 있어 단추만 걷음) ·
   접수/시술전표(.bi-rs-qty__v) · 상품추가 팝업(.bi-bp2__qty) · 예약등록 팝업(.bi-bq-qty).
   뒤 셋은 값이 <span> 이라 **칸을 새로 만들었다.**

   ⚠ 감싸개(.bi-rs-qty · .bi-bp2__qty · .bi-bq-qty)와 옛 단추 규칙은 **고치지 않는다.**
     단추가 사라졌을 뿐 상자의 키·테두리·반경은 그대로 쓴다(§4 「기존 CSS 직접 수정 ❌」).
   ⚠ 값이 있던 자리의 «폭·글자» 를 그대로 물려받는다 — 칸이 좁아지면 표가 흔들린다.
     .bi-rs-qty__v 29 / .bi-bq-qty>span 30 / .bi-bp2__qty>span 30 을 각각 따랐다. */
.bi-rs-qty__in,
.bi-bp2__qin,
.bi-bq-qin {
    border: 0; background: transparent; text-align: center;
    color: var(--txt-primary); font-size: var(--fs-base);
    padding: 0; min-width: 0;
}
/* ⚠ 2026-09-28 사용자 지시 — 「수량 입력폼이 **너무 좁아**」.
     ‒/+ 단추가 있을 때는 «보여 주기만» 하는 자리라 29·30 이면 됐는데, 이제는 «치는» 자리다.
     두 자리 수를 넉넉히 치고 지울 수 있게 넓힌다(상자 폭은 단추가 빠진 만큼 여유가 있다). */
.bi-rs-qty__in { width: 62px; height: 26px; font-weight: var(--fw-semibold); }
.bi-bp2__qin,
.bi-bq-qin { width: 64px; height: 28px; font-weight: var(--fw-bold); }
/* ⚠ 2026-09-29 — 이 줄은 (0,1,0) 이라 전역 팝업 규칙
     `.bi-pop-page input[type="text"]{height:var(--pop-field-h)}`(0,2,1 · style.css:10616)에
     **졌다** — 예약등록 팝업의 수량칸이 28 이 아니라 **36** 으로 그려졌고,
     그 탓에 담긴 줄이 규격 54 → 실제 **59** 로 부풀어 «4줄까지 보인다» 가 깨졌다
     (2026-09-29 실측 · _do_bqrow.mjs). 한 겹 올려 이긴다 — 값은 그대로 28 이다.
   ⚠ 같은 함정을 상품추가 팝업(.bi-bp2__qin)이 먼저 물렸다(§91-7) — 팝업 안 입력칸은
     **항상** .bi-pop-page 를 앞에 두고 재눈다. */
.bi-pop-page .bi-bq-qty .bi-bq-qin { height: 28px; }
/* 고른 칸임을 알린다 — 테두리가 없으니 바탕으로 말한다 */
.bi-rs-qty__in:focus,
.bi-bp2__qin:focus,
.bi-bq-qin:focus { outline: 0; background: var(--bg-input); box-shadow: var(--ring-focus); }
/* 숫자 칸의 위·아래 화살표(스피너)를 없앤다 — 그것도 «− / +» 다 */
.bi-rs-qty__in::-webkit-outer-spin-button, .bi-rs-qty__in::-webkit-inner-spin-button,
.bi-bp2__qin::-webkit-outer-spin-button, .bi-bp2__qin::-webkit-inner-spin-button,
.bi-bq-qin::-webkit-outer-spin-button, .bi-bq-qin::-webkit-inner-spin-button {
    -webkit-appearance: none; margin: 0;
}

/* ── §91-2 「고객변경」 — 전화번호 바로 옆 (2026-09-28 사용자 지시) ──────────────
   사용자: 「고객변경은 **전화번호 우측에 붙여줘**」
   이름·성별·전화가 한 줄이고 그 줄 끝에 붙는다. 카탈로그·메모 단추(.bi-*-cust__btn)와
   같은 크기로 두면 이름줄이 두꺼워지므로 «글자 단추» 로 작게 둔다.
   ⚠ 옛 아이콘 단추 규칙(.bi-bs2-cust__chg · .bi-rs-cust__chg)은 고치지 않는다 — 안 쓸 뿐이다. */
.bi-bs2-cust__chg2,
.bi-rs-cust__chg2 {
    flex: 0 0 auto; margin-left: var(--space-2);
    height: 22px; padding: 0 var(--space-2);
    border: 1px solid var(--border-base); border-radius: var(--radius-sm);
    background: var(--bg-card); color: var(--txt-secondary);
    font-size: var(--fs-xs); cursor: pointer; white-space: nowrap;
}
.bi-bs2-cust__chg2:hover,
.bi-rs-cust__chg2:hover { background: var(--bg-hover); color: var(--txt-primary); }
/* ⚠ 2026-09-29 사용자 지시 — 「고객변경 버튼에 에디터 모양 아이콘(연필)이 추가되었으면 해」.
     글자만 있던 단추라 «글 한 덩어리» 였다 — 아이콘이 붙으면 둘 사이가 붙어 읽히므로 간격을 준다.
     ⚠ 인라인 style 을 쓰지 않는다(§4). 키(22)·글자(--fs-xs)는 그대로 둔다 — 이름줄이 두꺼워지면 안 된다.
     ⚠ 아이콘은 fa-pencil-alt 다 — 이 저장소가 «고쳐 쓰기» 에 쓰는 이름이다(24곳). FA5(fal)로 적는다. */
.bi-bs2-cust__chg2,
.bi-rs-cust__chg2 { display: inline-flex; align-items: center; gap: var(--space-1); line-height: 1; }
.bi-bs2-cust__chg2 i,
.bi-rs-cust__chg2 i { font-size: var(--fs-2xs); }

/* ── §91-3 카드 제목 + 개수는 «한 덩어리» 다 (2026-09-28 사용자 지시) ─────────────
   「(5/5) 같은 명수 표시가 가운데에 있어 디자이너 타이틀 우측에 붙여줘」
   .bi-bk2-card__t 가 space-between 이라 글자와 <small> 이 따로 밀려났다.
   ⚠ .bi-bk2-card__t 는 고치지 않는다 — 감싸개를 하나 두어 «한 항목» 으로 만든다. */
.bi-bk2-card__tl { display: inline-flex; align-items: baseline; gap: var(--space-1_5); min-width: 0; }

/* ── §91-4 스케줄 상태 «탭» 은 상태 가이드와 같은 색이다 (2026-09-28 사용자 지시) ──────
   사용자: 「예약일정표·예약일정표(시간)에 스케줄상태에 **탭 색상을 상태가이드 참고해서
           같은색으로** 가는게 좋을거같아」
   지금은 넷 다 보라(--bk-run) 한 색이라, 바로 아래 가이드(확정 파랑 · 완료 회색 · 취소 빨강)와
   말이 달랐다. 같은 것을 두 색으로 말하면 읽는 사람이 둘을 잇지 못한다.
   ⚠ .bi-bk2-chip 기본 규칙은 고치지 않는다 — data-type 별로 «색만» 덧입힌다(§4 · 새 클래스 추가).
   ⚠ 「전체」(data-type="")는 그대로 보라다 — 가이드에 없는 갈래이고 «고른 것» 을 뜻한다. */
.bi-bk2-chip[data-type="2"] { border-color: var(--color-info-200); color: var(--color-info-700); }
.bi-bk2-chip[data-type="4"] { border-color: var(--border-base);    color: var(--txt-secondary); }
.bi-bk2-chip[data-type="3,5"] { border-color: var(--color-danger-300); color: var(--color-danger-600); }
/* 고른 탭은 그 색으로 «채운다» — 흰 글자로 또렷이 */
.bi-bk2-chip.is-on[data-type="2"] { background: var(--color-info-500);  border-color: var(--color-info-500);  color: var(--bg-card); }
.bi-bk2-chip.is-on[data-type="4"] { background: var(--txt-disabled);    border-color: var(--txt-disabled);    color: var(--bg-card); }
.bi-bk2-chip.is-on[data-type="3,5"] { background: var(--color-danger-500); border-color: var(--color-danger-500); color: var(--bg-card); }

/* ── §91-5 매출등록 고객대기열 = 접수/시술전표와 «같은 판» (2026-09-28 사용자 지시) ──────
   사용자: 「결제/매출등록 고객대기열 **데이터 리스트** 고처달라는 요청 처리안되고 있어
           **접수/시술전표와 같게** 해줘」
   접수전표(.bi-rs-qcard)는 [아바타][왼칸][오른칸] 세 덩이의 flex 다.
   매출등록은 여섯 조각을 감싸개 없이 격자에 흩어 놓아 줄이 셋이 되고 어긋났다.
   ⚠ 옛 .bi-bs2-qcard 의 grid 선언은 **고치지 않는다** — 아래에서 flex 로 덮어쓴다.
     (같은 특이도이고 뒤에 오므로 이긴다. 옛 규칙은 규격안 목업이 아직 쓴다.)
   ⚠ 키를 84 → 62 로 내린다. 줄이 둘이 되었으니 84 를 두면 카드가 헐겁다.
     2026-09-23 의 「담당명은 시각 아래」 는 «접수전표와 같게» 라는 이번 지시가 대신한다 —
     접수전표는 시각과 담당을 한 줄에 «가운뎃점» 으로 잇는다. */
.bi-bs2-q .bi-bs2-qcard {
    display: flex; align-items: center; gap: var(--space-2_5);
    height: 62px; padding: 0 var(--space-2_5);
}
.bi-bs2-qcard__l { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column;
    justify-content: center; gap: var(--space-0_5); }
/* ⚠ 오른칸은 접수전표와 **선언이 같다** — 둘로 적으면 SPEC-DUP 이다.
     선언은 .bi-rs-qcard__r 자리 하나에 두고, 이 이름을 그 줄에 붙였다(19524줄).
     — 기존 클래스의 값은 한 글자도 바꾸지 않는다(§4 절대규칙). */
/* 아바타는 두 줄을 가로지르지 않는다 — flex 에서는 그냥 첫 항목이다 */
.bi-bs2-q .bi-bs2-qav { grid-row: auto; }
/* 시각 · 담당이 한 줄이다 — 담당명이 길면 그것부터 줄어든다 */
.bi-bs2-q .bi-bs2-qcard__sub { display: flex; align-items: baseline; gap: var(--space-1);
    min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bi-bs2-q .bi-bs2-qcard__emp { grid-column: auto; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; }

/* ══ §91-6 빈 칸 안내는 «네 보기 모두» 같다 (2026-09-28 사용자 지시) ═══════════════
   사용자: 「일간일때 빈 시간 «클릭하여 예약» 뜨는데 **주간·월간도 똑같이** 해줘」
           「예약일정표(시간)은 **깨져서 제대로 안 나와**」

   재 보니(_do_slot_hover.mjs):
     · 일간   .bi-bk2-vslot  → ::after content 「+ 빈 시간 · 클릭하여 예약」  ✔ 나온다
     · 주간   .bi-bk2-wcell  → content 없음                                  ✘
     · 월간   .bi-bk2-mcell  → content 없음 · cursor default                 ✘
     · 시간표 .bi-bk2-hslot  → **모양 규칙만 있고 content 가 없다**(14294줄)  ✘  ← 「깨져서」 의 정체
   즉 안내가 일간에만 있었고, 시간표는 «껍데기만» 있어 빈 네모조차 안 그려졌다.

   ⚠ 칸 폭이 제각각이다 — 일간 231 · 주간 173 · 월간 186 · **시간표 104**.
     일간 규칙은 `white-space: nowrap` 이라 104 짜리 칸에서는 글이 잘린다.
     그래서 여기서는 **줄바꿈을 허용**한다(칸이 좁으면 두 줄로 눕는다). 키는 넉넉하다(96~123).
   ⚠ 기존 .bi-bk2-vslot 규칙은 고치지 않는다 — 일간은 지금 모습이 맞다. */
.bi-bk2-wcell,
.bi-bk2-mcell,
.bi-bk2-hslot { position: relative; cursor: pointer; }
.bi-bk2-wcell:hover::after,
.bi-bk2-mcell:hover::after,
.bi-bk2-hslot:hover::after {
    content: '+ 빈 시간 · 클릭하여 예약';
    position: absolute; inset: 4px;
    display: flex; align-items: center; justify-content: center;
    border: 1px dashed var(--border-strong); border-radius: var(--radius-md);
    background: var(--bg-card);
    font-size: var(--fs-sm); color: var(--txt-muted);
    white-space: normal; text-align: center; line-height: 1.35;
    /* ⚠ 한글은 기본으로 «글자 단위» 로 끊긴다 — 104px 칸에서 「클릭하 / 여 예약」 이 되었다.
         keep-all 을 주어 «낱말 단위» 로만 끊는다(§7 함정 · .bi-pop-note--keep 과 같은 판단). */
    word-break: keep-all;
    overflow: hidden; pointer-events: none; z-index: 3;
}
/* 월간은 «날짜 숫자» 가 이미 칸에 있다 — 안내가 그 위를 덮지 않게 아래쪽만 쓴다 */
.bi-bk2-mcell:hover::after { inset: auto 4px 4px; height: 46px; }
/* 예약이 들어 있는 칸에는 안내를 띄우지 않는다 — 거기는 «빈 칸» 이 아니다 */
.bi-bk2-wcell:has(.bi-bk2-ev):hover::after,
.bi-bk2-mcell:has(.bi-bk2-mcell__n):hover::after,
.bi-bk2-hslot:has(.bi-bk2-ev):hover::after { content: none; }
/* ⚠ 지난달·다음달 칸(.is-out)은 «이 달의 빈 칸» 이 아니다 — 커서도 이미 default 다(14728줄).
     안내만 남으면 «누를 수 있다» 고 말해 놓고 커서는 아니라고 말하는 꼴이 된다. */
.bi-bk2-mcell.is-out:hover::after { content: none; }

/* ── §91-7 담은 상품 «수량 칸» — 상자 안 상자를 푼다 (2026-09-28 사용자 지시) ──────
   사용자: 「상품추가 팝업에 담은상품 **수량 입력폼이 디자인 처음보는 형태**야 수정이 필요해」

   ⚠ 실측(_do_bp2_qty.mjs): 감싸개 .bi-bp2__qty 66×38(테두리 1 · 반경 6) **안에**
     칸 .bi-bp2__qin 64×36(테두리 1 · 반경 8) 이 들어 있었다 —
     테두리가 **두 겹**이고 반경도 6/8 로 달라, 프로젝트 어디에도 없는 모양이 되었다.
     («상자 안 상자» 는 이 프로젝트가 여러 번 지적받은 바로 그 흠이다.)

   감싸개는 ‒/+ 단추 시절의 «테를 두른 상자» 였다. 단추가 빠진 지금은 칸 하나뿐이니
   **테는 칸이 가진다.** 옛 규칙(.bi-bp2__qty · .bi-bp2__qin)은 고치지 않고,
   마크업이 덧입는 새 이름으로 «두 클래스»(0,2,0) 특이도를 세워 덮는다. */
.bi-bp2__qty.bi-bp2__qty--in {
    border: 0; border-radius: 0; overflow: visible; background: transparent;
}
/* 프로젝트의 보통 입력칸과 «같은 자» — .bi-input 의 테·반경·바탕을 그대로 따른다.
   폭은 두 자리 수를 넉넉히 치도록 64.
   ⚠ 2026-09-29 사용자 지시 — 「상품추가 팝업에 수량 입력칸 높이가 **기존과 다르게 커져서**
     줄여달라」. 36 은 «곁의 빼기 단추에 맞춘다» 며 넣은 값이었는데, 그 단추는 실제로 **24**다
     (.bi-bp2__del 24×24 · style.css:15011). 칸이 단추보다 반 넘게 커서 담은 줄이 칸 하나로
     독보였다. §91 이 정했던 **28** 로 되돌린다. */
/* ⚠ 셀렍터에 .bi-pop-page 를 더한 것은 멋 때문이 아니다 — 전역 입력칸 규칙
   `.bi-pop-page input[type="text"]{height:var(--pop-field-h)}`(0,2,1 · style.css:10609)가
   (0,2,0) 을 이겨 키가 **36 으로 남아 있었다**(실측 2026-09-29). 한 겹 올려 이긴다. */
.bi-pop-page .bi-bp2__qty--in .bi-bp2__qin {
    width: 64px; height: 28px;
    border: 1px solid var(--border-base);
    border-radius: var(--radius-md);
    background: var(--bg-card);
    color: var(--txt-primary);
    font-size: var(--fs-md); font-weight: var(--fw-bold);
    text-align: center; padding: 0; box-sizing: border-box;
    transition: border-color .15s, box-shadow .15s;
}
.bi-bp2__qty--in .bi-bp2__qin:hover { border-color: var(--gray-300); }
.bi-bp2__qty--in .bi-bp2__qin:focus {
    outline: 0; border-color: var(--brand-blue);
    box-shadow: var(--ring-focus); background: var(--bg-card);
}

/* ── §91-8 예약 상세정보를 «규격안대로» (2026-09-28 사용자 지시) ────────────────
   사용자: 「예약일정표, 예약일정표(시간)에 **예약 상세정보 규격안 대로 수정**해줘」
   규격안: renew_crm/tools/qc/spec_bk/detail.html · 대조문서 renew_crm/bkdetail_spec.html

   규격안↔실제를 나란히 찍어 다른 곳 여섯을 골랐다(_do_bk_detail.mjs):
     ① 이름줄에 **등급 칩**(일반/VIP)이 없다          → .bi-bki-grade 신설
     ② 표의 값이 «오른쪽 정렬» 이다                   → 규격안은 이름칸 86 + 값 왼쪽
     ③ 담당 디자이너 앞에 «사람 아이콘» 이 있다        → 규격안에 없다
     ④ 프로필이 «회색 테두리 상자» 다                 → 규격안은 테 없이 얹힌다
     ⑤ 노쇼·예약취소가 «오른쪽» 에 붙어 있다          → 규격안은 가운데
     ⑥ 예약 상품 값이 «회색 알약» 이다                → 규격안은 그냥 글이다

   ⚠ 옛 .bi-bki-* 선언은 **하나도 고치지 않는다**(§4 절대규칙 · 다른 화면이 아직 쓴다).
     상세 뿌리에 bi-bki--spec 을 덧입혀 «두 클래스»(0,3,0) 로 이긴다.
     .bi-page .bi-bki-v (0,2,0) 도 있으므로 세 마디가 필요하다. */
.bi-bki.bi-bki--spec .bi-bki-profile {
    background: transparent; border-color: transparent; padding: 0;
}
/* ① 등급 칩 — 아바타(★/👑)와 «같은 색» 을 쓴다. 색만으로 말하지 않게 글자를 담는다. */
.bi-bki-grade {
    flex-shrink: 0; font-size: var(--fs-2xs); font-weight: var(--fw-extrabold);
    line-height: 1.5; padding: var(--space-0_5) var(--space-2);
    border-radius: var(--radius-full);
}
/* ⚠ 색은 «일반» 에만 적는다 — VIP 는 §90 의 .bi-grade--vip 가 칠한다.
     둘 다 (0,1,0) 인데 이 줄이 뒤에 서서 네이비를 덮어버렸다(칩이 앵버로 찍혔다).
     :not() 로 «서로 닿지 않게» 갈라 둔다 — !important 로 싸우지 않는다. */
.bi-bki-grade:not(.bi-grade--vip) {
    background: var(--color-warning-100); color: var(--color-warning-700);
}
/* ⚠ VIP 색은 §90 의 .bi-grade--vip 하나다 — 같은 선언을 두 번 적지 않는다(SPEC-DUP).
     칩은 모양만 .bi-bki-grade 가 정하고, 색은 bi-grade--vip 를 «함께 입혀» 받는다. */
.bi-bki-grade:empty { display: none; }
/* ② 이름칸은 고정폭, 값은 왼쪽 — 규격안의 읽는 차례(이름 → 값)를 그대로 둔다 */
.bi-bki.bi-bki--spec .bi-bki-row { justify-content: flex-start; }
.bi-bki.bi-bki--spec .bi-bki-k { flex: 0 0 86px; }
.bi-page .bi-bki.bi-bki--spec .bi-bki-v {
    flex: 1 1 auto; text-align: left; justify-content: flex-start; word-break: keep-all;
}
/* ③ 사람 아이콘은 규격안에 없다 — 이름칸이 이미 「담당 디자이너」 라고 적고 있다 */
.bi-bki.bi-bki--spec .bi-bki-vi { display: none; }
/* ⑥ 예약 상품은 «글» 이다(답안지 booking_renew.mjs 의 「값은 글이다」 와 같은 판단) */
.bi-page .bi-bki.bi-bki--spec .bi-bki-goods {
    max-width: none; background: transparent; border-color: transparent; padding: 0;
}
/* ⑤ 되돌리기 어려운 둘은 가운데에 낮춰 둔다 */
.bi-bki.bi-bki--spec .bi-bki-sublinks { justify-content: center; gap: var(--space-4); }

/* ══ §93 · 팝업 최소 크기 · 직접 입력 칸 (2026-09-28 사용자 지시) ═══════════════
   사용자: 「팝업 창 **최소크기 min-width : 550px, min-height : 450px** 로 조정필요」
           「제휴/할인정보 팝업창 직접입력 수량인경우 **위아래 버튼 없이 입력창으로** 수정」

   ⚠ 폭 등급(423·480·540)은 토큰을 그대로 둔다 — 등급의 «뜻» 은 바뀌지 않았고,
     상자가 최소치를 지키면 결과가 같다. 토큰을 550 으로 덮어쓰면 문서·목업·시안 메모에
     적힌 수가 전부 거짓이 된다(423 이라 적힌 곳이 550 으로 그려진다).
   ⚠ 이 규칙으로 실제로 넓어지는 것 — 일반 423 · 사람검색 480 · 고르기 540 · 결제 480.
     720·880·1000 은 그대로다. 규격안 목업도 같이 올렸다(spec_pop/build.mjs).
   ⚠ 높이: popup_layer.js 가 iframe 키를 `상자.height() - 머리` 로 맞춘다.
     min-height 는 그 `상자.height()` 에 반영되므로 iframe 도 따라 커진다 — 흰 띠가 안 남는다. */
.write_layout_pop { min-width: var(--pop-min-w); min-height: var(--pop-min-h); }

/* 직접 입력 칸의 «위아래 화살표»(브라우저 기본 스피너)를 걷는다.
   ⚠ type=number 는 그대로 둔다 — JS 가 값을 숫자로 읽고, 휴대폰 자판이 숫자판으로 뜬다.
     보이는 화살표만 없앤다(§91 이 .bi-rs-qty__in 등에 쓴 것과 같은 방법). */
.bi-pop-page input[type="number"]::-webkit-outer-spin-button,
.bi-pop-page input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.bi-pop-page input[type="number"] { -moz-appearance: textfield; appearance: textfield; }

/* 머리의 «팝업이 채우는 단추 자리» — 비었으면 없는 것처럼 (2026-09-28)
   ⚠ 이 자리는 모든 팝업의 머리에 생긴다. 채우는 팝업만 보이게 해야
     나머지 예순 몇 창의 머리 간격이 흔들리지 않는다. */
.bi-pop-head-act { display: flex; align-items: center; gap: var(--space-2); margin-left: auto; }
.bi-pop-head-act:empty { display: none; }

/* ══ §94 · 2차 분류 칩이 많으면 «한 줄만» 두고 접는다 (2026-09-28 사용자 지시) ═══════
   사용자: 「상품추가, 상품검색 팝업 **2차 카테고리가 많을경우 1줄만 남기고 접히는 형태**로」

   왜 필요한가 — 분류는 지점이 만든다. 많은 지점은 열 개가 넘어 칩 줄이 세 줄까지 늘고,
   그만큼 목록이 아래로 밀려 «상품을 고르는 자리» 가 좁아진다. 줄 수가 자료에 따라
   들쭉날쭉하면 창 안의 자리 배분도 흔들린다.

   짜임 —  .bi-pop-chips ( ul.bi-pop-chip-ul )  ·  접고 펴는 단추는 §98 의 «제 줄» 이 맡는다
   접힘은 ul 에 .is-fold, 펼침은 그 클래스를 뗀다. 넘치지 않으면 단추 자체를 감춘다.
   ⚠ 단추를 ul «안» 에 두면 접혔을 때 같이 잘린다 — 그래서 밖에 둔다.
   ⚠ 한 줄 키 = 위 여백 9 + 칩 28 = 37. 칩 키(28)는 기존 규칙 그대로 쓴다(§4). */
.bi-pop-chips { display: flex; align-items: flex-start; gap: var(--space-1_5); }
.bi-pop-chips > .bi-pop-chip-ul { flex: 1 1 auto; min-width: 0; }
.bi-pop-catalog .bi-pop-chip-ul.is-fold { max-height: 37px; overflow: hidden; }

/* ⚠ 2026-09-29 — 여기 있던 `.bi-pop-chip-more`(칩 옆 「+N」 단추)를 **걷었다.**
   사용자가 접기를 «제 줄»(§98 .bi-pop-cat-fold)로 옮기라고 정해, 그 단추를 만들던
   pop_search.js §④ 도 그 줄을 쓰도록 바뀌었다 — 이제 이 이름을 달는 마크업이 하나도 없다.
   안 쓰는 규칙을 남겨 두면 styleguide2 가 «쓰지 도 않는 부품» 을 규격이라고 전시한다.
   ⚠ 규칙과 전시는 **같이** 걷는다 — 한쪽만 지우면 다른 쪽이 CLASS-ORPHAN 으로 뜨거나
     쓰는 곳 없는 규칙으로 남는다. */

/* ══ §95 · 최소 키(§93) 가 내용보다 크면 «푸터를 바닥에» (2026-09-28) ═══════════════
   §93 으로 팝업에 min-height:450 을 걸자, 내용이 짧은 창은 그 차이가 **푸터 아래 빈 띠**로
   남았다(보유패키지 수정 — 내용 316, 상자 450, 빈 자리 78). 껍데기(popup_layer.js)가
   iframe 을 상자 키에 맞추도록 고쳤으므로 빈 자리는 이제 **팝업 문서 안**에 있다.
   → 문서를 세로로 채우고, 푸터를 바닥으로 내린다. 내용은 위에 그대로 붙는다.

   ⚠ 범위를 좁힌다 — 「푸터를 **제 직계 자식으로** 가진 팝업」 에만 건다.
     팝업 예순 몇 개가 저마다 다른 짜임이라, body 를 통째로 flex 로 바꾸면 남의 창이 흔들린다.
   ⚠ 내용이 길면 min-height 가 지지 않는다(min- 이라서) — 긴 창은 예전 그대로다.
   ⚠ 전례: §38 의 `.bi-pop-pay--dt > .bi-pop-list-foot{margin-top:auto}` 와 같은 수법이다. */
/* ⚠ `:has()` 안에 `:has()` 를 넣으면 **선택자 전체가 무효**가 된다(규격상 금지).
   처음에 `html:has(> body:has(> foot))` 로 적었다가 조용히 안 먹었다 — 넣지 말고 이어 쓴다. */
html:has(> body.bi-pop-page > .bi-pop-list-foot) { height: 100%; }
body.bi-pop-page:has(> .bi-pop-list-foot) {
    min-height: 100%; display: flex; flex-direction: column;
}
body.bi-pop-page:has(> .bi-pop-list-foot) > .bi-pop-list-foot { margin-top: auto; }

/* ══ §96 · 보유패키지 수정 팝업 규격 (2026-09-28 사용자 지시) ═══════════════════
   사용자: 「**패키지 잔존현황** 팝업 디자인에 맞게 규격안 만들어줘」
          → 「패키지 잔존현황 **페이지의 «보유패키지 수정» 팝업**을 말하는 거야.
             **시안은 없고** 규격안 새로 만들어주면 되」

   시안이 없으므로 «우리 팝업 규격» 에서 뽑는다 — 보드 §08·§09 의 폼 골격(.bi-pop-board /
   .bi-pop-form2 / .bi-pop-f)과 결제 팝업의 «요약 줄»(.bi-pop-sumrow)을 그대로 쓴다.
   새로 만드는 것은 둘뿐이다 — 요약을 담는 «회색 판» 과 입력 오른쪽의 «단위» 글자.

   ⚠ 왜 회색 판인가 — 이 창은 «고칠 수 없는 것(패키지명·상품명·지금 남은 횟수)» 과
     «고치는 것(수정후 횟수·만료일)» 이 한 화면에 섞인다. 판으로 갈라야 어느 쪽이
     읽기만 하는 값인지 한눈에 보인다. 색은 이미 있는 --pop-band 다(새 색 없음).
   ⚠ 왜 두 칸 폼인가 — §93 으로 창이 550 이 되었다. 한 칸씩 쌓으면 550 폭에 36 짜리
     입력이 홀로 늘어져 빈 자리가 커진다(실측: 내용 312 · 창 450). */
.bi-pop-page .bi-pop-infobox{
    background: var(--pop-band); border: 1px solid var(--pop-line);
    border-radius: var(--radius-lg); padding: var(--space-3_5) var(--space-4);
    margin-bottom: var(--space-4);
}
.bi-pop-page .bi-pop-infobox .bi-pop-sumlist{ margin-bottom: 0; }

/* 보드 골격에서도 «칸 제목» 이 보이게 — 지금 규칙은 .bi-pop-pay 안에서만 산다(8579행) */
.bi-pop-page .bi-pop-board .bi-pop-card-label{
    display: block; font-size: var(--fs-md); font-weight: var(--fw-extrabold);
    color: var(--gray-800); margin: 0 0 var(--space-2); padding-left: var(--space-0_5);
}

/* 입력 오른쪽의 단위(「회」) — 값과 단위가 떨어져 있으면 무엇의 수인지 되묻게 된다 */
.bi-pop-page .bi-pop-inwrap{ position: relative; }
.bi-pop-page .bi-pop-inwrap > .bi-pop-unit{
    position: absolute; right: var(--space-3); top: 0; height: var(--pop-field-h);
    display: flex; align-items: center; pointer-events: none;
    font-size: var(--pop-f-fs); color: var(--txt-muted);
}
.bi-pop-page .bi-pop-inwrap > input{ padding-right: var(--space-8); }   /* 32 — 단위 글자가 앉을 자리(새 토큰 없이 스케일에서 고른다) */

/* ── §95-2 · 푸터가 «막 안» 에 있는 팝업 (2026-09-28) ───────────────
   §95 는 푸터가 몸통의 «직계» 일 때만 닿는다. 실제로 재 보니 그런 팝업은 넷뿐이고,
   나머지는 푸터를 여러 겹 안에 두고 있었다(_pop_band.mjs 실측 2026-09-28):
     할인      body > .bi-pop-pay > .bi-pop-pad--form > foot                    — 빈 띄 156
     예약금    body > .bi-pop-pay--dep > .bi-pop-pad--form > foot               — 137
     현금취소  body > .bi-pop-pay--cash > .bi-pop-pad--form > form > foot       — 145
     지점등록  body > .bi-pop-reg > form > foot                                —  55
     카드취소  body > .bi-pop-pay--card > .selectWrap > .bi-pop-field > .bi-pop-pad > foot
   겹을 이름으로 적으면 다음 팝업이 한 겹 더 감을 때 또 빠진다.
   «푸터를 품고 있는 상자» 를 그대로 고른다 — 그것이 곳 몸통에서 푸터까지의 «길» 이다.

   ⚠ `.bi-pop-pay` 의 `display:flow-root` 는 레거시 float 본문을 BFC 로 품기 위한 것이다.
     그래서 모든 `.bi-pop-pay` 를 바꾸지 않고, **푸터를 안에 둔 길** 만 바꾼다.
     이 바꿈은 내용이 창보다 길면 아무 일도 하지 않는다(flex:1 도 margin-top:auto 도).
   ⚠ `margin-top:auto` 를 넓게 걸지 않는다. 블록 흐름에서 auto 는 **0** 이라,
     푸터 위 16 여백을 가진 다른 팝업에서 그 여백이 사라진다. 된 flex 의 직계에만 건다.
   ⚠ 카탈로그증 같이 제가 이미 100vh 골격을 가진 창은 `.bi-pop-cat` 을 건드리지 않았다. */
/* ⚠ 여기를 `min-height:100%` 로 적으면 **되먹임**이 생긴다.
   껍데기의 높이 맞춤은 «내용 키» 로 상자를 정하는데, 100% 는 그 상자가 정한
   iframe 키를 다시 가리키므로 «내용» 이 항상 iframe 만큼이 된다 — 창이 내용에
   맞게 줄지 못하고 부른다(실측: 지점등록 450 → 540, 제휴할인 환점 496 → 590).
   → 창의 최소 키(§93)에서 머리를 밀 **고정 px** 을 쓴다. 그러면
   내용 = max(제 키, 394) · 상자 = max(제 키+56, 450) 로 둘이 같은 답에 멈췄다. */
body.bi-pop-page:has(.bi-pop-list-foot) {
    min-height: calc(var(--pop-min-h) - var(--pop-head-h));
    display: flex; flex-direction: column;
}

/* «푸터를 품고 있는» 상자 전부 = 몸통에서 푸터까지의 길 */
body.bi-pop-page *:has(.bi-pop-list-foot) {
    flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
}
/* ⚠ 2026-10-02 — 위 «길» 규칙(0,2,1)이 `.bi-hidden`(0,1,0)을 **이겨** 숨겨 둔 상자를 드러냈다.
   네이버페이 결제요청 창(popup_layer_npay.php)의 «결제요청 진행 중» 판(#req_after.bi-hidden)이 푸터를 품고 있어
   상태와 무관하게 늘 떠 있었고, 그 밑의 「결제요청」 단추를 가렸다 — 사용자 보고
   「결제버튼 클릭 시 결제요청 진행중이 뜨는데, 고객은 결제요청 메세지를 받지 못함」.
   → 숨긴 상자는 푸터를 품어도 숨긴다(0,3,1). JS 가 보일 때는 bi-hidden 을 떼므로 영향 없다. */
body.bi-pop-page .bi-hidden:has(.bi-pop-list-foot) { display: none; }

/* 그 길의 끝 — 푸터를 바닥으로 */
body.bi-pop-page *:has(> .bi-pop-list-foot) > .bi-pop-list-foot,
body.bi-pop-page > .bi-pop-list-foot { margin-top: auto; }


/* ── §93·§95 가 쓰는 토큰 (2026-09-28) ───────────────────────────
   값이 두 곳(상자의 최소 키 · 팝업 문서의 최소 키)에 나뉘어 있어 한 곳에 모은다.
   --pop-head-h 는 «재서 넣은 값» 이다 — 머리(.bi-pop-head--compact)는 패딩으로 키가 정해져
   고정 토큰이 없었다. 팝업 24개를 두 계정에서 재보니 전부 56 이었다(_pop_band.mjs).
   ⚠ 머리 키를 바꾸면 이 값도 같이 바꾼다 — 안 바꾸면 푸터 아래에 그만큼 빈 띄가 생긴다. */
:root {
    --pop-min-w: 550px;   /* 사용자 지시 2026-09-28 — 팝업 창 최소 폭 */
    --pop-min-h: 450px;   /* 같은 지시 — 팝업 창 최소 키 */
    --pop-head-h: 56px;   /* 머리의 그려진 키(재서 넣은 값) */
}

/* ══ §97 · 공통 검색 조각의 «폭» 과 타이틀 아래 «안내 띠» (2026-09-29 사용자 지시) ═══

   ── §97-1 검색 판이 여백 있는 상자 안에 들어가면 좁아진다 ────────────────────
   사용자: 「제휴/할인 정보 팝업의 경우 **고객검색 팝업처럼 검색창을 수정해 달라니까 다르잖아**」
   재 보니 색·테·반경·글자는 고객검색과 **한 군데도 다르지 않았다**(tools/qc/_srch_cmp.mjs).
   다른 것은 «폭» 이었다 —
     고객검색  body > .bi-pop-pay--list > .bi-pop-pad--fill > 판   왼 0  · 548 (가장자리까지)
     제휴/할인 body > .bi-pop-pay.bi-pop-board > .bi-pop-pad  > 판   왼 18 · 512 (양옆 흰 띠)
   `.bi-pop-pad` 의 좌우 여백 18 이 회색 판을 안쪽으로 밀어 «다른 창» 처럼 보였다.
   ⚠ 판을 넓히려고 .bi-pop-pad 의 여백을 건드리지 않는다 — 그 안의 폼·목록이 같이 움직인다.
     푸터가 쓰는 수법(음수 마진)을 그대로 쓴다: 제 부모의 여백만큼 도로 밀어낸다. */
.bi-pop-page .bi-pop-pad > .bi-bp2__lhd,
.bi-pop-page .bi-pop-pad--form > .bi-bp2__lhd,
.bi-pop-page .bi-pop-pad > .bi-pop-resline[data-popsrch="1"],
.bi-pop-page .bi-pop-pad--form > .bi-pop-resline[data-popsrch="1"] {
    width: 100vw; margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw);
    box-sizing: border-box;
}

/* ── §97-2 타이틀 아래 안내문은 «회색 띠» 하나로 ──────────────────────────────
   사용자: 「어떤 팝업은 타이틀아래 안내문구가 **배경색이 있고** 어떤 팝업은 안내문구에
           **배경색이없어 통일**해줘」
   갈라져 있던 둘 —
     결제 팝업 셋(.bi-pay2__note) : 회색 띠 --pop-band · 아래선 · 최소 키 35  ← 시안(bs1~bs3)이 그렇다
     그 밖(.bi-pop-note)          : 배경 없는 맨 글줄
   시안이 말한 쪽(회색 띠)으로 맞춘다. 새 색은 없다 — 이미 있는 --pop-band 다.

   ⚠ «타이틀 아래» 만이다. .bi-pop-note 는 폼 한가운데·맨 아래에도 쓰인다
     (보유패키지 수정의 마지막 줄이 그렇다) — 거기까지 띠를 두르면 폼이 끊겨 보인다.
     그래서 «본문의 첫 덩이» 일 때만 건다(:first-child).
   ⚠ 여백 있는 상자 안에 있으면 §97-1 과 같은 이유로 좁아진다 — 같은 수법으로 넓힌다. */
/* «타이틀 아래» 를 **글자로 적는다** — `:first-child` 로 고르려다 놓쳤다.
   팝업 여럿이 안내문 앞에 **숨은 input** 을 줄줄이 두고 있어(현금취소·날짜시간 등)
   그들은 «첫 자식» 이 아니었다 — 눈으로는 맨 위인데도.
   :first-of-type 으로 바꾸면 이번엔 폼 한가운데·맨 아래 안내(보유패키지 수정)까지 잡힌다.
   그래서 **쓰는 쪽이 뜻을 밝힌다** — .bi-pop-note--top. 어디에 놀아도 같은 꼴이 된다.
   ⚠ 숨김은 건드리지 않는다 — display 를 주므로 .bi-hidden 을 이기지 않게 :not() 을 달았다
     (제휴/할인의 #disc_sub 가 실제로 빈 회색 띄로 드러났다 · CLAUDE.md §7 의 둘째 함정). */
.bi-pop-page .bi-pop-note--top:not(.bi-hidden):not(.bi-pop-hidden) {
    display: flex; align-items: center; gap: var(--space-2);
    min-height: var(--pay2-note-h);
    /* ⚠ 여백만큼 음수 마진(-18)으로 밀어내다가 **가로로 넘쳤다**(카드취소 실측 2026-09-29).
       팝업마다 감싸개가 달라 «부모의 여백이 18» 이 항상 맞지 않기 때문이다.
       푸터(.bi-pop-list-foot)가 쓰는 수법을 그대로 쓴다 — «창 폭 그대로» 로 잡고
       가운데 정렬한다. 감싸개의 여백이 얼마건 결과가 같다. */
    width: 100vw; margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw);
    margin-top: 0; margin-bottom: var(--space-4);
    padding: var(--space-2) var(--pop-head-pad-x);
    background: var(--pop-band);
    border-bottom: 1px solid var(--border-base);
    box-sizing: border-box;
}
/* 감싸개(.pop_desc.bi-pop-block)가 있는 팝업은 그 감싸개가 위 여백을 갖고 있다 —
   띠가 제목에 붙게 그 여백을 거둔다(네이버페이 셋). */
.bi-pop-page .bi-pop-block:has(> .bi-pop-note--top) { padding-top: 0; }
/* ⚠ 위에서 display:flex 를 주었으므로 **숨김을 다시 못박는다** — 아니면 .bi-hidden 을 이겨
   숨어 있어야 할 안내가 빈 회색 띄로 드러난다(제휴/할인의 #disc_sub 가 실제로 그랬다).
   CLAUDE.md §7 «조용히 실패하는 여섯» 의 둘째가 바로 이것이다. */
.bi-pop-page .bi-pop-note.bi-hidden,
.bi-pop-page .bi-pop-note.bi-pop-hidden { display: none; }

/* ⚠ 2026-09-29 — 부모가 **gap 으로** 틈을 정하는 곳에서는 안내가 제 아래 여백을 갖지 않는다.
   §78-9 가 `.bi-bq-pop .bi-pop-pad--form` 을 세로 flex + gap:16 으로 두고
   `> * { margin-top:0; margin-bottom:0 }` 로 자식 여백을 누어 둔다 — flex 에서는 여백이
   **무너지지 않고 더해지기** 때문이다. 그런데 위 §97-2 가 (0,4,0) 으로 그 규칙을 이겨
   아래 여백 16 을 되살렸고, gap 16 과 더해져 첫 틈이 **32** 가 됐다
   (입고등록 팝업 실측 2026-09-29 · 규격안 16 ↔ 실제 32 · cmp_gap.mjs).
   ⚠ 한 곹 더 올려 되돌린다 — «틈을 정하는 주인» 은 부모의 gap 하나여야 한다. */
.bi-pop-page .bi-bq-pop .bi-pop-pad--form > .bi-pop-note--top { margin-bottom: 0; }

/* ── §100 액션바의 «매출건수 · 합계» (2026-09-29 사용자 지시) ──────────────
   ⚠ 번호를 §97 로 적었다가 고쳤다 — 공용 style.css 는 네 세션이 나눠 쓴다.
     20849줄에 이미 «§97 공통 검색 조각» 이 있었고, §98 · §99 도 임자가 있다.
     자리는 그대로 두고 번호만 비운 곳으로 옮긴다(자리 ≠ 번호).
   사용자: 「카드/네이버페이/현금영수증 승인관리 — **표시항목 버튼 좌측에 매출건수/합계 표시**」
           (뒤에 「**총 건수 , 총 합계**로 해줘」 로 문구가 바뀜다 — 값을 적는 자리는 function.js 하나다)
           「이거 요청사항 안됬어 … 표시항목 좌측에 건수 합계 표시 부분」

   ⚠ 왜 «안 된 것처럼» 보였나 — 값은 들어가 있었다. 처음엔 `.bi-erp-result` 를 빌려 썼는데
     바로 위 §에 「조회결과 전역 제거」 규칙이 있어
       `.bi-erp-actionbar__right .bi-erp-result { display: none }`
     가 **같이 지웠다.** DOM 에는 「매출건수 4건 · 합계 30,000원」 이 그대로 있었고
     수치 검사도 통과했다 — **캡처를 눈으로 보고서야** 빈 자리인 것을 알았다.
   ⚠ 그 규칙은 고치지 않는다(§4). 「조회 결과」 는 표시항목이 대신한다는 판단이 살아 있고,
     이것은 «다른 것»(매출 합계)이므로 이름을 갈라 둔다.
   값·색은 .bi-erp-result 와 같은 자를 쓴다 — 한 줄에 나란히 서는 배지라 달라 보이면 안 된다. */
.bi-erp-sum {
    display: inline-flex; align-items: center; gap: var(--space-1_5);
    margin-right: var(--space-3);
    font-size: var(--fs-base); font-weight: var(--fw-semibold); color: var(--gray-600);
    white-space: nowrap;
}
/* 점·값의 생김새는 .bi-erp-result__dot / __val 줄에 같이 적어 둔다 — 선언은 한 자리다. */

/* ══ §99 · 예약 상세정보의 글자 — §91-8 의 이음 (사용자 지시 2026-09-29) ══
   ⚠ 이 절은 «파일 끝» 에 서야 한다 — §91-8(20659줄)이 같은 이름들에 크기를 이미 적어 둔다.
   번호를 §91-9 로 달아 그 옆에 두면 캐스케이드에서 지고, 그렇다고 !important 로 싸우지 않는다.
   「규격안 만든거 봤을땐 괜찮은거 같았는데 실제로 적용했을땐 전체 디자인과 좀 안맞는거 같아.
     글자 크기도 너무 작고」

   재 보니 그럴 만했다 — 이 판만 본문이 11px(--fs-xs)·10px(--fs-2xs) 였다.
   이 프로젝트의 본문 기본은 13px(--fs-base)이고, 바로 옆 «실시간 플랜 일지» 도
   이름이 12px 다. 같은 열에 있는 두 판이 한 두 단씩 달랐으니 «전체와 안 맞는다» 가 된다.

   고친 방식 — 한 단씩 올려 규격(§12 글자 사다리)에 얹는다:
     항목 이름·값 11 → 13(--fs-base)  ·  전화 10 → 12(--fs-sm)
     고객명 14 → 16(--fs-lg)            ·  성별·상태 배지 10·11 → 11·12
     메모 라벨 10 → 11              ·  줄간격도 그만큼 룰게 한다
   ⚠ 기존 .bi-bki-* 규칙은 한 줄도 고치지 않는다(§4) — 여기서 덮어쓴다.
   ⚠ 규격안 목업(spec_bk/detail.html)은 이 style.css 를 그대로 읽는다 —
      따로 고칠 것이 없고, 그래서 목업·실제가 갈라지지 않는다. */
.bi-bki .bi-bki-profile-name { font-size: var(--fs-lg); }
.bi-bki .bi-bki-profile-phone { font-size: var(--fs-sm); }
.bi-bki .bi-bki-gender { font-size: var(--fs-xs); }
.bi-bki .bi-bki-k,
.bi-bki .bi-bki-v,
.bi-bki .bi-bki-vi { font-size: var(--fs-base); }
/* ⚠ 상태 칩은 예약일정표에만 옛 클래스 status_round 가 더 붙는다 —
     그걸 잡으면 두 화면이 10px·12px 로 갈라진다(실측 2026-09-29).
     칩 자체를 잡아 규격안·두 화면을 한 값으로 묶는다. */
.bi-bki .bi-bki-status { font-size: var(--fs-sm); }
/* 등급 칩은 10px 이라 읽힐 크기가 아니었다 — 한 단 올린다 */
.bi-bki .bi-bki-grade { font-size: var(--fs-xs); }
.bi-bki .bi-bki-memo-label { font-size: var(--fs-xs); }
.bi-bki .bi-bki-memo-label i { font-size: var(--fs-sm); }
.bi-bki .bi-bki-memo-text { font-size: var(--fs-base); }
.bi-bki .bi-seclabel { font-size: var(--fs-xs); }
/* 글자가 커진 만큼 줄도 널래진다 — 빽빽해 보이지 않게 틈을 한 단 늘린다 */
.bi-bki .bi-bki-table { gap: var(--space-3); padding: var(--space-3_5, var(--space-4)); }
.bi-bki .bi-bki-goods { max-width: 210px; }

/* ── §99-2 「노쇼 · 예약취소」 는 «오른쪽 끝» 이다 (사용자 지시 2026-09-29) ──────────
   「노쇼,예약취소 버튼이 가운데 정렬이라 보기 안좋아」
   §91-8 이 .bi-bki--spec 에 justify-content:center 를 걸어 두었다(20705줄).
   기본 규칙(.bi-bki-sublinks, 4056줄)은 본디 flex-end 다 — 그 자리로 되돌린다.
   ⚠ 옛 규칙을 고치지 않는다(§4). 같은 특이도로 «뒤에» 서서 이긴다. */
.bi-bki.bi-bki--spec .bi-bki-sublinks { justify-content: flex-end; gap: var(--space-2); }

/* ── §99-3 「실시간 최근 플랜 일지」 도 «같은 판» 이다 (사용자 지시 2026-09-29) ───────
   「정보영역 외 실시간최근플랜일지도 같이 규격안 해줘야지」
   이 판은 상세 패널 바로 아래에 붙어 한 열을 이룬다. 그런데 이름 12 · 담당·때 10 이라
   위 판(13/12/11)과 두 단 어긋나 있었다 — 같은 열에서 글자가 층층이 작아 보였다.
   위와 «같은 사다리» 로 맞춘다. 11px 보다 작은 글자를 남기지 않는다. */
.bi-bka .bi-bka-name { font-size: var(--fs-base); }
.bi-bka .bi-bka-emp,
.bi-bka .bi-bka-time { font-size: var(--fs-xs); }
.bi-bka .bi-bka-badge { font-size: var(--fs-xs); }

/* ── §99-4 일지 판이 «열 끝까지» 내려온다 (2026-09-29) ──────────────────────────
   재 보니 우측 열 931 인데 상세판 383 + 일지판 265 = 648 — **바닥에 283px 빈 띠**가
   남아 있었다. 사용자가 앞서 지적한 「그리드가 화면 끝까지 이어지지않고 잘리는 현상」 과
   같은 모양이다. 목록 상자가 height:195 로 못박혀 있는 것이 까닭이다.

   ⚠ 고정 뺄셈(calc(100vh - N))으로 풀지 않는다 — 부모(.bi-bk-rightcol)가 이미 세로 flex 로
     화면을 채우고 있어, 빼는 순간 틀어진다(학습된 함정). 남은 자리를 «받게» 한다.
   ⚠ 옛 규칙(4138·4152줄)을 고치지 않는다(§4) — 같은 특이도로 뒤에 서서 덮는다.
   ⚠ min-height:0 이 없으면 flex 자식은 내용만큼 «늘어나» 스크롤이 안 생긴다. */
.bi-bk-rightcol > .bi-bka { flex: 1 1 auto; min-height: 220px; }
.bi-bk-rightcol > .bi-bka > .bi-bka-list { height: auto; flex: 1 1 auto; min-height: 0; }

/* ══ §98 · 2차 분류 «접기» 는 제 줄을 가진다 (2026-09-29 사용자 지시) ═══════════
   사용자 ①: 「상품 검색 상품추가에 접고 펼수있는 부분을 「시술 24개」 라인에 적용해야지」
   사용자 ②: 「시술 갯수는 사실 **필요없는 요소**라 「시술 24개」 라인 **자체를 접고 피는 용**으로
             하고싶은거고 **기본은 2차 카테고리가 펼처저 있는 거**고」

   그래서 그 줄은 이제 «건수» 가 아니라 **접기 단추 한 줄**이다.
   회색 판 밖에 홀로 있는 줄이라 칩이 늘어도 자리가 흔들리지 않고, 줄 전체가 누르는 자리다.
   ⚠ 기본은 **펼침** — 칩 ul 에 .is-fold 가 없는 상태가 기본이고, 누르면 붙는다.
   ⚠ 지금은 규격안에만 쓴다. 실제 마크업에 이 클래스를 달면 그때 화면이 바뀐다. */
.bi-pop-cat-fold {
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
    width: 100%; box-sizing: border-box;
    padding: var(--space-2) var(--pop-head-pad-x);
    border: 0; border-bottom: 1px solid var(--pop-line);
    background: var(--bg-card); cursor: pointer;
    font-size: var(--pop-cnt-fs); font-weight: var(--fw-semibold); color: var(--txt-muted);
    text-align: left;
}
.bi-pop-cat-fold:hover { background: var(--pop-line-soft); color: var(--txt-secondary); }
/* 글자 칸 — 남는 자리를 먹어 꾫은 항상 줄 끝에 선다 */
.bi-pop-cat-fold__t { flex: 1 1 auto; min-width: 0; }
.bi-pop-cat-fold > i { flex: 0 0 auto; font-size: var(--fs-sm); }
/* ⚠ display 를 주었으니 숨김을 다시 못박는다 — 아니면 접을 것이 없는데도
   줄이 남아 «누를 수 있는데 아무 일도 안 하는» 단추가 된다(실측 2026-09-29).
   CLAUDE.md §7 «조용히 실패하는 여섯» 의 둘째 — 이번 회차에만 세 번째다. */
.bi-pop-cat-fold.bi-pop-hidden,
.bi-pop-cat-fold.bi-hidden { display: none; }


/* ── §98-2 신규고객등록 — 마지막 칸이 푸터에 붙지 않게 (2026-09-29 사용자 지시) ──────
   사용자: 「**고객메모가 푸터랑 너무 붙어있게** 규격안에 되어있어 수정하고 실제에 바로 적용해줘」
   `.bi-pop-reg{padding-bottom:0}` 은 «아래 간격은 푸터가 갖는다»(2026-08-27)는 뜻이었는데,
   푸터의 그 간격은 «푸터 선 위» 가 아니라 «푸터 안» 이라 마지막 칸과 선 사이가 0 이 된다.
   여러 줄 입력(메모)은 테두리가 커서 그 0 이 더 도드라진다 — 마지막 칸에만 아래 여백을 준다. */
/* ⚠ 직계(>)로 적었다가 안 먹었다 — 칸들은 <form> 안에 있다(실측 사이 0). */
.bi-pop-page .bi-pop-reg .bi-pop-reg__last { margin-bottom: var(--space-4); }
/* 2026-10-06 사용자 지시 — 신규고객등록 「담당 디자이너」 칸과 「고객 메모」 라벨 사이가 0 이었다.
   위 줄들(.bi-pop-form2 · .bi-pop-form3)은 margin-bottom var(--space-3)(12) 로 떨어져 있다 → 같은 값 */
.bi-pop-page .bi-pop-reg .bi-pop-reg__designer { margin-bottom: var(--space-3); }
/* 2026-10-07 — 팝업 칸(.bi-pop-f)을 숨길 때. .bi-pop-f 의 display 규칙이 .bi-hidden(0,1,0)을 이긴다(F2 함정) → 짝을 둔다 */
.bi-pop-page .bi-pop-f.bi-hidden { display: none; }
/* 2026-10-06 사용자 지시 — 패키지/선불권 메시지전송 「전송방법」 라벨과 아래 세그먼트 사이 세로 간격(실측 8 → 입력 줄 간격과 같은 12) */
.bi-pop-page .bi-pop-card-label.bi-pop-card-label--gap { margin-bottom: var(--space-3); }
/* 2026-10-06 사용자 지적 — 「285번 전표에서 … 전송방법 라벨 윗 간격이 딱 붙어」. 보유 패키지가 차면 목록 마지막 줄 바로 밑에
   라벨이 붙었다(실측 0px · 빈 목록일 때는 «없습니다» 줄 여백에 가려 안 보였다). 위 «안내띠↔패키지/선불권» 과 같은 12 를 준다. */
.bi-pop-page .bi-pop-pad--form.bi-pop-pad--chan { padding-top: var(--space-3); }

/* ── §99 · «칸 제목만 든 상자» 는 아래 여백을 갖지 않는다 (2026-09-29) ─────
   `.bi-pop-pad--form` 은 아래 여백 16 을 든다 — 안에 폼이 있을 때는 맞는 값이지만,
   칸 제목(.bi-pop-card-label) 하나만 들어 있으면 제목과 목록 사이가 벌어져
   «까닭 없는 빈 줄» 처럼 보인다(패키지/선불권 메시지전송 실측 2026-09-29).
   ⚠ 공통 값을 고치지 않고 «그런 상자» 에만 이름을 준다(§4). */
.bi-pop-page .bi-pop-pad--form.bi-pop-pad--lbl { padding-bottom: 0; }

/* ── §99-2 · 고를 수 없는 칸은 «고를 수 없게 보여야» 한다 (2026-09-29) ────
   TryOn 메시지전송의 「알림톡」 은 아직 보내는 길이 없어 disabled 다.
   그런데 세그먼트는 고른 것만 밝게 하므로, 끈 칸과 «그저 안 고른 칸» 이 똑같아 보인다 —
   누를 수 있어 보이는데 아무 일도 안 하는 자리가 된다(카탈로그 ★ 와 같은 갈래).
   ⚠ 새 색을 만들지 않는다 — 엷게 하고 커서 모양만 바꾼다. */
.bi-pop-page .bi-pay2__sg[disabled] { opacity: .45; cursor: not-allowed; }

/* ══ §100 · 2026-09-30 사용자 추가 오류건 ═════════════════════════════════

   §100-1 대기열 카드가 «줄어든다» — 아홉 줄이 넘으면 키가 깎인다
     사용자: 「대기열에 9개 이상 있을 경우 대기열 목록 버튼의 height가 줄어듬」.
     그대로였다. .bi-bs2-qcard 는 height:84px 를 갖지만 부모(.bi-bs2-qlist)가
     flex-direction:column 이라 **자식은 기본으로 줄어든다**(flex-shrink:1).
     여덟 줄까지는 자리가 남아 84 를 지키고, 아홉째부터 남는 자리가 없어 전부 깎였다.
     ⚠ height 만 못박아도 안 된다 — flex 에서 height 는 «바라는 크기» 일 뿐이다.
     목록은 이미 overflow-y:auto 다 — 줄어들지 않게만 하면 넘치는 만큼 스크롤한다.
     §2-12 「자료가 늘어도 판이 안 늘어난다」 의 짝: «자료가 늘어도 줄이 안 눌린다».

     ⚠⚠ 2026-09-30 정정 — 처음엔 `flex: 0 0 84px` 로 적었다. **그것이 값을 바꿔 버렸다.**
       이 클래스의 키는 두 곳에서 말한다: :17090 의 84(2026-09-23 ⑯ 에 65→84) 와
       :20876 의 **62**(그 뒤 사용자 「고객대기열을 접수·시술전표와 같은 꼴로」).
       뒤에 오는 62 가 이기므로 **지금 규격은 62** 이고, 답안지(spec_match/buysell.mjs)와
       verify_wave3 도 62 를 잰다. 84 를 flex 밑변으로 박으니 카드가 62 → 84 로 커졌다
       (동료 세션이 「대기 · 카드 62 기대 → 실제 84」 로 잡아 주었다).
     → **값을 다시 적지 않는다.** 줄어들지만 않게 한다 — 키는 위 규칙들이 정한 그대로 둔다.
       이것이 「같은 값을 두 곳에 적지 않는다」 의 실제 모습이다. */
.bi-bs2-qcard { flex: 0 0 auto; }
/* 목록이 부모 안에서 줄어들 수 있어야 스크롤이 생긴다 — min-height:auto 면 내용만큼 늘어난다 */
.bi-bs2-qlist { min-height: 0; }

/* §100-2 주간 머리 — 토·일 색이 «요일» 에만 있었다
     사용자: 「토/일 요일에만 color적용되어있음 동일하게 날짜에도 색깔 적용 필요」.
     .bi-bk2-whead__d 는 <b>요일</b> + <span>날짜 (건수)</span> 두 줄인데
     is-sun/is-sat 이 b 에만 걸려 있었다(15130~15131). 날짜는 --txt-disabled 회색 그대로였다.
     ⚠ 새 색을 들이지 않는다 — b 가 쓰는 그 색을 span 에도 준다. */
.bi-bk2-whead__d.is-sun span { color: var(--color-danger-500); }
.bi-bk2-whead__d.is-sat span { color: var(--brand-blue); }

/* §100-3 월간 셀 — 날짜 숫자에도 토·일 색
     §68-5 에 「날짜 숫자는 «중립» 이다 — 색은 요일 머리에만 준다(규격안)」 고 적어 두었는데,
     2026-09-30 사용자 지시가 그 결정을 뒤집었다. 요일 머리와 날짜가 같은 말을 해야 한다.
     ⚠ 지난달·다음달 칸(is-out)은 그대로 흐리게 둔다 — 그 달이 아니라는 뜻이 먼저다. */
.bi-bk2-mcell.is-sun:not(.is-out) .bi-bk2-mcell__d { color: var(--color-danger-500); }
.bi-bk2-mcell.is-sat:not(.is-out) .bi-bk2-mcell__d { color: var(--brand-blue); }

/* §100-4 대시보드 위젯 표 — 가운데 정렬
     사용자: 「오늘 예약/매출현황 - 표 데이터 가운데정렬」.
     ⚠ .bi-simpletbl 을 고치지 않는다 — 다른 화면도 쓴다. 그 두 표에만 이름을 준다(§4). */
.bi-simpletbl--c th,
.bi-simpletbl--c td { text-align: center; }
/* ⚠ 2026-09-30 — 위 두 줄만으로는 **머리줄이 안 따라온다.** 실측: td 는 center 인데 th 는 left 였다.
     .bi-simpletbl thead th 가 (0,1,2) 이고 위 규칙은 (0,1,1) 이라 **저쪽이 이긴다** —
     뒤에 적는다고 이기는 것이 아니다(차례는 «같은 무게» 일 때만 가른다).
     .bi-dash-col-time(예약시간 칸)은 (0,2,0) 이라 더 무겁다 — 그것도 같이 짚는다.
   ⚠ 「표 데이터 가운데」 지시에 머리줄도 맞춘다 — 머리만 왼쪽이면 칸과 어긋나 보인다. */
.bi-simpletbl--c thead th,
.bi-simpletbl--c tbody td,
.bi-simpletbl--c .bi-dash-col-time { text-align: center; }

/* §100-5 상품 추가 팝업 — 고른 표시를 «줄 오른쪽 동그라미» 로 (2026-09-30 사용자 지시)
     「고객정보 팝업창과 동일하게 행의 우측에 동그라미 체크표시」.
     고객 검색 팝업의 규격(.bi-pop-pick2 · style.css:15421)을 그대로 쓴다 — 새로 만들지 않는다.
     ⚠ 왼쪽 첫 칸(.bi-pop-pick)은 **지우지 않고 숨긴다.** 격자가 `--pop-check | 1fr | auto` 라
       그 칸을 없애면 이름이 18px 칸에 들어가 «한 글자씩 세로로» 쌓인다(2026-09-14 실측).
       칸 자체를 걷고 격자를 다시 짠다 — 그래야 빈 자리가 남지 않는다. */
.bi-pop-catalog .bi-pop-prod-ul > li{ grid-template-columns: minmax(0, 1fr) auto auto; }
.bi-pop-catalog .bi-pop-prod-ul > li > .bi-pop-pick{ display: none; }
/* 고른 줄에만 동그라미가 채워진다 — 고객 검색의 .bi-pop-clist-item.is-sel 과 같은 규칙 */
.bi-pop-catalog .bi-pop-prod-ul > li.is-sel .bi-pop-pick2{
    background: var(--pop-sel); border-color: var(--pop-sel); color: var(--bg-card);
}

/* §100-6 예약등록 팝업 — 네이버 «미연동 상품» 줄 (2026-09-30 사용자 지시)
     「네이버예약 건 미연동 상품 아예표시안되고 있음, 미연동 상품이라고 표시해줄것」.
     전에는 상품번호가 없으면 줄을 통째로 버려서 «무엇이 빠졌는지» 조차 알 수 없었다.
     ⚠ 새 색을 들이지 않는다 — «아직 이어지지 않았다» 는 경고색(warning)을 그대로 쓴다.
       빨강(danger)은 «잘못» 이라는 뜻이라 과하다. 이것은 고칠 수 있는 «미완» 이다. */
.bi-bq-tag--nolink{ background: var(--color-warning-50); color: var(--color-warning-600); }
.bi-bq-item.is-nolink .bi-bq-item__t{ color: var(--color-warning-600); }

/* §100-7 시술·상품 추가 팝업(popup_layer_product) — 고른 표시를 «줄 오른쪽 동그라미» 로
     2026-09-30 사용자 지시 11-1: 「고객정보 팝업창과 동일하게 행의 우측에 동그라미 체크표시」.
     §100-5(상품 «검색» 팝업)와 **같은 규격**이다 — 어느 창을 열었는지에 따라 달라 보이면 안 된다.
   ⚠ 앞의 <input type=checkbox> 는 **DOM 에서 지우지 않는다** — 「N건 담기」 가 그 체크 상태를
     세어 고른 줄을 만든다(popup_layer_product.js:149). **보이는 것만** 바꾼다.
   ⚠ 이 목록은 여럿을 고를 수 있다(고객 검색은 하나다). 그래도 표시는 같은 부품을 쓴다 —
     「같은 뜻에 두 가지 모양을 만들지 않는다」. */
.bi-pop-catalog #pop_pro_ul > .bi-pop-tbl-row { grid-template-columns: minmax(0, 1fr) auto auto; }
.bi-pop-catalog #pop_pro_ul > .bi-pop-tbl-row > input[type="checkbox"] { display: none; }
.bi-pop-catalog #pop_pro_ul > .bi-pop-tbl-row.is-sel .bi-pop-pick2 {
    background: var(--pop-sel); border-color: var(--pop-sel); color: var(--bg-card);
}

/* ══ §101 · 입력 오른쪽 «단위» 글자가 값 위에 겹치던 것 (2026-09-30) ═══════════
   §98-2 에서 `.bi-pop-page .bi-pop-inwrap > input{padding-right:32}` 을 넣었는데
   **한 번도 먹은 적이 없었다**. `.bi-pop-page .bi-pop-f input[type=text]`(0,3,1 · 10985행)이
   `padding: 0 var(--space-3)` 로 덮는데 내 선택자는 (0,2,1) 이라 **순서와 무관하게** 진다.
   그리고 `.bi-pop-unit` 은 오직 `.bi-pop-f` 안에서만 쓰인다 — 즉 늘 지고 있었다.
   「뒤에 뒀으니 이긴다」 는 **특이도가 같을 때만** 참이다.

   왜 아무도 못 봤나 — 규격안(spec_pop/pkg.html)의 입력에 `bi-input--num` 이 빠져 값이
   **왼쪽**에 섰고, `type_audit` 의 그 화면 자리 다섯에 `.bi-pop-unit` 이 **아예 없었다**.
   규격안이 흠을 가리고 아무도 그 자리를 안 재서 spec·btn·type 이 모두 0 이었다(§2-16 의 그 꼴).

   실측 — 값 «1,200»: 규격안 사이 **−13** · 실제 사이 **−13** → 고친 뒤 **+9**.
   ⚠ 값(32 = --space-8)은 그대로다. 새 수치를 만들지 않고 **특이도만** 맞춘다.
   ⚠ 재발 막이: `probe_unit_gap.mjs` — 글자의 크기·색이 아니라 **둘 사이의 거리**를 잰다. */
.bi-pop-page .bi-pop-f .bi-pop-inwrap > input[type="text"],
.bi-pop-page .bi-pop-f .bi-pop-inwrap > input[type="number"]{ padding-right: var(--space-8); }

/* ══ §102 · 네이버페이 결제 팝업 — 남성 기장 줄이 «숨김» 을 이기고 남던 것 (2026-10-01) ═══
   사용자: 「N Pay 네이버페이 결제 팝업 **성별에 따른 카테고리** 성별선택안했을때 깨저」

   실측(test9180 · 전표 262): 성별이 «여성» 인데 남성 라디오 줄이 **함께** 보였다 —
   「롱·미디움·단발·숏」(여성) 바로 밑에 「롱·미디움·숏」(남성)이 겹쳐 떴다.

   까닭 — 마크업은 `<div class="radio_div bi-pop-opt-row male bi-hidden">` 로 감추는데
     `.bi-pop-page .bi-pop-opt-row{display:flex}`(0,2,0 · §97)가
     `.bi-hidden{display:none}`(0,1,0 · 7552행)을 **이긴다.**
     팝업 JS 는 성별을 «바꿀 때» 만 .hide()(인라인)를 걸어서, 바꾸기 전 첫 화면에서만 샌다.
     ⚠ 이 저장소가 같은 함정에 물린 것이 이번이 넷째다(KNOWN_ISSUES F2 · F12).
       **display 를 주는 규칙을 새로 쓸 때는 `.bi-hidden` 짝을 같이 적는다.**
   ⚠ `!important` 를 쓰지 않는다 — 특이도로 이미 이긴다(§4 절대규칙·AB-IMPORTANT). */
.bi-pop-page .bi-pop-opt-row.bi-hidden,
.bi-pop-page .bi-pop-opt-row.bi-pop-hidden { display: none; }

/* ══ §103 · 네이버페이 결제 팝업 — 카테고리를 «규격 이름» 으로 (2026-10-01) ════════
   사용자: 「네이버페이 결제 팝업 **규격안 디자인에 맞게 새로 만들어주고 수정해줘**」
   규격안: renew_crm/tools/qc/spec_pop/npay.html

   고친 까닭 — 이 팝업의 카테고리는 `.pop_cate_wrap` · `.pop_cate_div` · `.pop_cate_title` ·
     `.pop_tag_ul` · `.pop_tag_li` 로 그려져 있었다. 셋 다 **`bi-` 접두가 아니고 styleguide2 에
     전시도 없다** — 즉 규격 밖 이름이라, 다른 팝업과 모양이 따로 놀았다(SPEC 밖 · MOD-CSS-RULE).

   ⚠⚠ 옛 이름을 **지우지 않는다.** 팝업 JS 가 `.onoff` · `.pop_cate_div` · `.ch_label` 을
     **동작 손잡이**로 쓴다(popup_layer_npay_btn.js:183·195·207·231). 이름을 바꾸면
     선택자가 빈 결과를 내고 핸들러가 **조용히 return** 한다(CLAUDE.md §7 여섯째 함정).
     → 마크업에 옛 이름과 새 이름을 **나란히** 두고, 보이는 모양만 새 이름이 정한다.

   ⚠ 태그는 «칩» 으로 보이되 알맹이는 체크박스 그대로다 — name·value·id 를 바꾸지 않는다(§4).
     JS 가 `input:checkbox[name=CUT_FEMALE]:checked` 로 읽는다. */
.bi-pop-page .bi-pop-acc{
    border: 1px solid var(--border-base); border-radius: var(--radius-xl);
    background: var(--bg-card); margin-bottom: var(--space-2_5); overflow: hidden;
}
.bi-pop-page .bi-pop-acc__hd{
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-3) var(--space-4); cursor: pointer;
}
.bi-pop-page .bi-pop-acc__t{ flex: 0 0 auto; font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--gray-800); }
/* 고른 태그를 머리에 적는다 — **접은 채로도** 무엇을 골랐는지 보이게. 길면 … 로 자른다 */
.bi-pop-page .bi-pop-acc__sel{
    flex: 1 1 auto; min-width: 0; font-size: var(--pop-cnt-fs); color: var(--color-info-700);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bi-pop-page .bi-pop-acc__max{ flex: 0 0 auto; font-size: var(--fs-sm); color: var(--txt-muted); }
.bi-pop-page .bi-pop-acc__ar{ flex: 0 0 auto; color: var(--txt-muted); }
/* ⚠⚠ 2026-10-01 — 여기 처음에 `display:flex` 를 줬다가 **접힘을 깨뜨렸다.**
     접는 장치는 `.pop_tag_ul{display:none}`(0,1,0 · 7599행)인데
     `.bi-pop-page .bi-pop-acc__bd`(0,2,0)가 그걸 이겨 **다섯 덩이가 모두 펼쳐진 채**로 떴다
     (실측: 본문 높이 595 → 2794). 오늘 이 저장소에서 같은 함정이 네 번째다.
   → **display 를 아예 주지 않는다.** 여닫이는 옛 규칙과 JS(.show()/.hide())에 맡기고,
     칩은 제 자신이 inline-flex 로 서서 줄바꿈한다. 모양만 바꾸고 «보이고 숨기는 일» 은 안 건드린다. */
.bi-pop-page .bi-pop-acc__bd{
    width: auto; margin: 0; padding: var(--space-1) var(--space-4) var(--space-3);
    list-style: none; border-top: 0; overflow: visible;
}
/* 태그 한 알 — 보이는 것은 칩, 알맹이는 **체크박스 그대로**다.
   실제 마크업(popup_layer_npay_btn.php)이 이렇다 — 규격안도 **같은 꼴**로 그린다:
     <li class="pop_tag_li bi-pop-tag">
       <input type="checkbox" name="CUT_FEMALE" value="…" id="13_FEMALE">
       <label for="13_FEMALE"><span></span></label>     ← 옛 스프라이트. 눕힌다
       <span class="ch_label">레이어드컷</span>          ← JS 가 누르는 자리
     </li> */
.bi-pop-page .bi-pop-tag{
    position: relative; display: inline-flex; align-items: center; height: 28px;
    border: 1px solid var(--pop-line); border-radius: var(--radius-full); background: var(--bg-card);
    cursor: pointer; user-select: none; list-style: none; padding: 0;
    /* 옛 `.pop_tag_li` 는 float:left · width:150px 로 «표» 처럼 깔렸다 — 칩은 글자만큼만 선다 */
    float: none; width: auto; margin: var(--space-2) var(--space-2) 0 0;
}
/* ⚠ 전역 `input[type=checkbox]{display:none}` 에 기대지 않는다 — 팝업 스코프가 되살려 놓은 곳이 있어
     그대로 두면 칩 안에 네모가 비친다. 옛 스프라이트 label 과 함께 **여기서** 눕힌다. */
.bi-pop-page .bi-pop-tag > input[type="checkbox"],
.bi-pop-page .bi-pop-tag > label{
    position: absolute; width: 0; height: 0; opacity: 0; overflow: hidden;
    margin: 0; padding: 0; border: 0;
}
/* 글자가 칩을 가득 채운다 — JS 가 .ch_label 에 걸려 있어 **칩 어디를 눌러도** 골라지게 */
.bi-pop-page .bi-pop-tag .ch_label{
    display: block; padding: 0 var(--space-3); line-height: 26px;
    font-size: var(--fs-sm); color: var(--txt-secondary); white-space: nowrap;
}
/* ⚠ 고른 표시는 **체크박스 상태**가 정한다 — JS 가 클래스를 달아 주지 않기 때문이다.
     `:has()` 로 읽으면 팝업 JS 를 한 줄도 안 고치고 모양만 바꿀 수 있다. */
.bi-pop-page .bi-pop-tag:has(> input:checked){ border-color: var(--pop-sel); background: var(--pop-row-sel); }
.bi-pop-page .bi-pop-tag:has(> input:checked) .ch_label{ color: var(--pop-sel); font-weight: var(--fw-semibold); }
/* ⚠ 2026-10-02 사용자 지시 — 「bi-pop-tag bi-pop-tag--out UI CSS 기존과 다른 것 같은데」 → 「원래 알약 모양으로 되돌려줘」.
   바로 위 칩 규칙(.bi-pop-page .bi-pop-tag, 5675603f · 네이버페이 스타일 태그용)이 «팝업 안 모든 .bi-pop-tag» 에 걸려
   현금·카드 팝업의 「국세청 전송」·「수기 등록」·「읽기 전용」 배지(.bi-pop-tag--out, 9ac5cc87 시안 실측)를
   흰 바탕·회색 테두리·키 28·안쪽 여백 0·바깥 여백 8 의 «누를 수 있어 보이는 칩» 으로 바꿔 놓았다.
   → 배지는 원래 값(.bi-pop-tag + .bi-pop-tag--out)으로 되돌린다. 칩 규칙은 그대로 둔다. */
.bi-pop-page .bi-pop-tag.bi-pop-tag--out{
    height: 19px; padding: 0 var(--space-2_5); margin: 0;
    background: var(--pop-pill-bg); border: 1px solid var(--color-info-200); border-radius: var(--radius-full);
    color: var(--color-info-700); cursor: default; float: none;
}
/* ⚠ 2026-10-06 사용자 지시 — 「디자이너 검색 팝업창 직급 chip css 깨짐 확인 수정」.
   원인은 위와 같다: 사람 줄(.bi-pop-clist — 디자이너 검색·고객 검색)의 직급·차트번호 배지(.bi-pop-tag · --top)에
   네이버페이 칩 규칙이 걸려 키 28 · 흰 바탕 · 테두리 · 위/오른쪽 여백 8 의 칩이 됐다(실측).
   → 사람 줄 안에서는 배지 원래 값(.bi-pop-tag · .bi-pop-tag--top, §75-5)으로 되돌린다. 칩 규칙은 그대로 둔다. */
.bi-pop-page .bi-pop-clist .bi-pop-tag{
    height: 19px; padding: 0 var(--space-1_5); margin: 0; width: auto;
    border: 0; border-radius: var(--radius-sm);
    background: var(--bg-input); color: var(--txt-secondary);
    cursor: inherit; float: none; position: static; user-select: auto;
}
.bi-pop-page .bi-pop-clist .bi-pop-tag--top{ background: var(--pop-pill-bg); color: var(--color-info-700); }

/* §103-2 «체크/라디오 한 알» 을 팝업 어디서나 (2026-10-01)
   `.bi-pop-opt` 는 지금까지 `.bi-pop-pay` **안에서만** 살았다(8675행). 그래서 결제 스킨이 아닌
   팝업이나 규격안 목업에 그대로 쓰면 **라디오와 글자가 붙어** 버린다(gap 이 안 와서).
   규격 이름이 특정 스킨에 묶여 있으면 그건 아직 규격이 아니다 — `.bi-pop-page` 로 올린다.
   ⚠ 값은 그대로 베낀다. 새 수를 만들지 않는다 — 두 곳이 달라지면 같은 이름이 두 모양이 된다. */
.bi-pop-page .bi-pop-opt{
    display: inline-flex; align-items: center; gap: var(--space-1_5); margin: 0;
    font-size: var(--fs-base); color: var(--txt-secondary); cursor: pointer;
}
.bi-pop-page .bi-pop-opt input:disabled{ cursor: not-allowed; opacity: .6; }
.bi-pop-page .bi-pop-opt span{ user-select: none; }


/* ═══════════════════════════════════════════════════════════════════
   고객분석(Customer 360) — report_customer360 (2026-10-07)
   규격안: renew_crm/tools/qc/spec_c360/ · 문서: docs/design/sg2/report_customer360.md
   공통(.bi-erp-* · .bi-anl-* · .bi-btn · .bi-search-* · .bi-erp-tab)은 불러쓴다. 여기는 이 화면 고유(KPI·등급 배지·위험도·연락 목록)만.
   ═══════════════════════════════════════════════════════════════════ */
.bi-c360-meta b { color: var(--txt-secondary); font-weight: var(--fw-semibold); }

.bi-c360-state { font-size: var(--fs-base); color: var(--txt-muted); line-height: 1.6; }
.bi-c360-state:empty { display: none; }
.bi-c360-state.is-err { color: var(--color-danger-700); font-weight: var(--fw-semibold); }

.bi-c360-pane { display: none; flex-direction: column; gap: var(--space-4); }
.bi-c360-pane.is-on { display: flex; }

/* KPI */
.bi-c360-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-4); }
.bi-c360-kpi { border: 1px solid var(--border-base); border-radius: var(--radius-xl); padding: var(--space-4) var(--space-5); background: var(--bg-card); min-height: 96px; }
.bi-c360-kpi__v { font-size: var(--fs-2xl); font-weight: var(--fw-bold); line-height: 1.3; margin-top: var(--space-0_5); }
.bi-c360-kpi__v small { font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--txt-muted); margin-left: var(--space-0_5); }
.bi-c360-kpi__n { font-size: var(--fs-sm); color: var(--txt-muted); margin-top: var(--space-0_5); }
.bi-c360-tone--danger { color: var(--color-danger-700); font-weight: var(--fw-semibold); }
.bi-c360-tone--warn { color: var(--color-warning-700); font-weight: var(--fw-semibold); }
.bi-c360-tone--good { color: var(--color-success-700); font-weight: var(--fw-semibold); }
.bi-c360-tone--brand { color: var(--brand-blue); font-weight: var(--fw-semibold); }

/* 등급 배지 5종 · 위험도 · 채널 칩 */
.bi-c360-grade { display: inline-flex; align-items: center; height: 22px; padding: 0 var(--space-2); border-radius: var(--radius-full); font-size: var(--fs-sm); font-weight: var(--fw-semibold); white-space: nowrap; }
.bi-c360-grade--new  { background: var(--color-indigo-100);  color: var(--color-indigo-500); }
.bi-c360-grade--grow { background: var(--color-info-100);    color: var(--color-info-500); }
.bi-c360-grade--vip  { background: var(--color-success-100); color: var(--color-success-700); }
.bi-c360-grade--risk { background: var(--color-warning-100); color: var(--color-warning-700); }
.bi-c360-grade--dorm { background: var(--color-danger-100);  color: var(--color-danger-700); }
.bi-c360-lane { display: inline-flex; align-items: center; gap: var(--space-1); height: 22px; padding: 0 var(--space-2); border-radius: var(--radius-md); background: var(--bg-input); border: 1px solid var(--border-base); font-size: var(--fs-sm); color: var(--txt-secondary); font-weight: var(--fw-normal); }

/* 등급 5칸 */
.bi-c360-g5 { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--space-3); }
.bi-c360-seg { border: 1px solid var(--border-base); border-radius: var(--radius-lg); padding: var(--space-3) var(--space-4); background: var(--bg-card); }
.bi-c360-seg b { display: block; font-size: var(--fs-2lg); margin-top: var(--space-1_5); }

/* 우선 과제 */
.bi-c360-ins { display: flex; gap: var(--space-3); padding: var(--space-3) 0; border-bottom: 1px solid var(--border-light); }
.bi-c360-ins:last-child { border-bottom: 0; }
.bi-c360-ins__sev { flex-shrink: 0; width: 48px; height: 22px; border-radius: var(--radius-md); font-size: var(--fs-xs); font-weight: var(--fw-bold); display: flex; align-items: center; justify-content: center; }
.bi-c360-ins p { margin: 0; font-size: var(--fs-base); color: var(--txt-secondary); line-height: 1.55; }
.bi-c360-ins p b { color: var(--txt-primary); }
.bi-c360-note { font-size: var(--fs-base); color: var(--txt-secondary); line-height: 1.6; margin: var(--space-2) 0 var(--space-3); }

/* 컨트롤 줄 */
.bi-c360-ctrl { display: flex; align-items: flex-end; gap: var(--space-6); flex-wrap: wrap; margin-bottom: var(--space-3); }
.bi-c360-ctrl__item label { display: block; font-size: var(--fs-sm); font-weight: var(--fw-semibold); color: var(--txt-secondary); margin-bottom: var(--space-1_5); }
.bi-c360-ctrl__item label b { color: var(--brand-blue); }
.bi-c360-range { width: 300px; accent-color: var(--brand-blue); }
.bi-c360-chk { display: inline-flex; align-items: center; gap: var(--space-1_5); font-size: var(--fs-md); cursor: pointer; }

/* 목록 — 높이 고정 + 내부 스크롤: 자료가 늘어도 판 키가 변하지 않는다 */
.bi-c360-list { border-radius: 0; }
.bi-c360-list__scroll { height: 264px; overflow: auto; }
.bi-c360-list__scroll--short { height: 232px; }
.bi-c360-tbl { width: 100%; border-collapse: collapse; font-size: var(--fs-base); color: var(--txt-primary); }
.bi-c360-tbl th { box-sizing: border-box; position: sticky; top: 0; background: var(--bg-input); color: var(--txt-muted); font-weight: var(--fw-semibold); font-size: var(--fs-base); text-align: left; padding: 0 var(--space-3); height: 40px; border-bottom: 1px solid var(--border-base); white-space: nowrap; }
.bi-c360-tbl td { box-sizing: border-box; padding: 0 var(--space-3); height: 37px; border-bottom: 1px solid var(--border-light); white-space: nowrap; }
.bi-c360-tbl td.bi-c360-wrap { white-space: normal; line-height: 1.4; min-width: 240px; }
.bi-c360-tbl .bi-c360-mono { font-family: Consolas, monospace; font-size: var(--fs-sm); }
.bi-c360-tbl .bi-c360-num { text-align: right; }
.bi-c360-tbl td.bi-c360-empty { text-align: center; color: var(--txt-muted); height: 80px; }
.bi-c360-pick:hover { background: var(--bg-input); }
.bi-c360-pick.is-sel { background: var(--color-info-100); }

.bi-c360-chip { height: 26px; padding: 0 var(--space-3); border-radius: var(--radius-full); background: var(--color-indigo-100); color: var(--brand-blue); font-size: var(--fs-sm); font-weight: var(--fw-semibold); display: inline-flex; align-items: center; }

@media (max-width: 1280px) {
  .bi-c360-kpis { grid-template-columns: repeat(2, 1fr); }
  .bi-c360-g5 { grid-template-columns: repeat(3, 1fr); }
}

/* 고객분석 — 참조 프로그램 기능 대조 후 보강(2026-10-07): 고객 상세 두 칸 · 위험도 큰 숫자·게이지 · 상세 항목 · 처리 체크 · 판정 박스 */
.bi-c360-go { color: var(--brand-blue); font-weight: var(--fw-semibold); text-decoration: none; margin-left: var(--space-1); }
.bi-c360-go:hover { text-decoration: underline; }
.bi-c360-g2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: var(--space-4); align-items: start; }
.bi-c360-seg__hd { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.bi-c360-riskbig { display: flex; align-items: flex-end; gap: var(--space-2); margin-top: var(--space-2); }
.bi-c360-riskbig__n { font-size: var(--fs-3xl); line-height: 1; font-weight: var(--fw-bold); }
.bi-c360-gauge { height: 8px; border-radius: var(--radius-full); background: var(--border-base); overflow: hidden; margin: var(--space-2) 0 var(--space-3); }
.bi-c360-gauge__fill { height: 100%; border-radius: var(--radius-full); }
.bi-c360-gauge--danger { background: var(--color-danger); }
.bi-c360-gauge--warn { background: var(--color-warning); }
.bi-c360-gauge--good { background: var(--color-success); }
.bi-c360-dl { display: grid; grid-template-columns: 110px minmax(0, 1fr); gap: var(--space-2) var(--space-3); font-size: var(--fs-base); margin: var(--space-3) 0; }
.bi-c360-tags { display: flex; flex-wrap: wrap; gap: var(--space-1_5); margin-bottom: var(--space-3); }
.bi-c360-act { border: 1px solid var(--border-base); border-radius: var(--radius-lg); background: var(--bg-input); padding: var(--space-3) var(--space-4); }
.bi-c360-act__main { color: var(--txt-primary); font-size: var(--fs-md); font-weight: var(--fw-bold); margin: var(--space-1) 0; }
.bi-c360-done { width: 16px; height: 16px; accent-color: var(--brand-blue); cursor: pointer; vertical-align: middle; }
.bi-c360-verdict { border-left: 3px solid var(--brand-blue); background: var(--color-info-100); border-radius: var(--radius-md); padding: var(--space-3) var(--space-4); font-size: var(--fs-base); line-height: 1.6; margin-bottom: var(--space-2); }
@media (max-width: 1280px) { .bi-c360-g2 { grid-template-columns: minmax(0, 1fr); } }

/* 고객분석 — 차트 막대 위 값 표시(참조 프로그램의 barValue 와 같은 역할). SVG <text> 에 JS 가 클래스를 붙인다 (2026-10-08) */
.bi-c360-barval { font-size: var(--fs-sm); font-weight: var(--fw-bold); text-anchor: middle; fill: var(--txt-secondary); color: var(--txt-secondary); pointer-events: none; }   /* SVG 는 fill 이 색이지만 검사 도구가 color 를 읽으므로 같이 둔다 */
.bi-c360-barval--danger { fill: var(--color-danger-700); color: var(--color-danger-700); }
.bi-c360-barval--warn { fill: var(--color-warning-700); color: var(--color-warning-700); }
.bi-c360-barval--good { fill: var(--color-success-700); color: var(--color-success-700); }
.bi-c360-barval--brand { fill: var(--brand-blue); color: var(--brand-blue); }

/* 2026-10-12 일본어화 — 일본어 글리프용 폴백 폰트의 «줄 상자» 를 Pretendard 와 맞춘다.
   Pretendard 에는 가나·한자가 없어 시스템 CJK 폰트로 그려지는데, 그 폰트는 ascent+descent 가 커서
   line-height:normal 인 모든 줄이 한국어보다 2px 가량 커졌다(규격 키가 줄마다 어긋남).
   → 일본어 문자 범위에만 걸리는 @font-face 로 ascent/descent 를 고정한다(Chrome 87+). 한글에는 영향 없음.
   :root 토큰은 «뒤에서 덮어쓴다» — 위쪽 기존 선언은 건드리지 않는다. */
@font-face {
  font-family: 'JP Fallback';
  src: local('Yu Gothic UI'), local('Meiryo UI'), local('Yu Gothic'), local('Hiragino Kaku Gothic ProN'), local('Noto Sans JP'), local('Noto Sans CJK JP'), local('MS PGothic'), local('MS Gothic'), local('Malgun Gothic');
  unicode-range: U+3000-303F, U+3040-309F, U+30A0-30FF, U+31F0-31FF, U+4E00-9FFF, U+FF00-FFEF;
  ascent-override: 95%;
  descent-override: 25%;
  line-gap-override: 0%;
}
:root { --font-sans: 'Pretendard', 'JP Fallback', sans-serif; }

/* 2026-10-13 일본어화 — 브레드크럼 «현재 페이지명» 이 «페이지 설명 알약» 과 함께 줄어 «ダッシュボ…» 처럼 잘렸다.
   일본어 페이지명(예: 대시보드 4자 → ダッシュボード 7자)이 한글보다 길어 알약과 같은 비율로 깎인 것.
   → 페이지명은 줄지 않게(flex-shrink:0) 하고, 줄어드는 몫은 알약(.hbar-pill--fit, 이미 말줄임)이 전부 진다. */
.hbar-crumb-cur { flex-shrink: 0; overflow: visible; text-overflow: clip; }
/* 2026-10-13 일본어화 — 위 규칙으로 페이지명이 줄지 않게 했더니 브레드크럼 묶음(.hbar-crumb)이 자기 상자보다 커져
   «넘침» 으로 잡혔다(qc layout: div.hbar-crumb 152→169 등 19화면). 묶음도 줄지 않게 하고, 줄어드는 몫은 설명 알약만 진다. */
.hbar-crumb { flex-shrink: 0; }

/* 2026-10-15 월별 매출현황 — 간이 수요 예측 한 줄(신규 클래스, 사업계획서 31쪽). 차트 카드 아래 얇은 안내 줄이라 키는 글자 한 줄. */
.bi-anl-forecast { padding: var(--space-3) var(--space-4); font-size: var(--fs-base); line-height: 18px; color: var(--txt-secondary); border-top: 1px solid var(--border-light); }
.bi-anl-forecast b { color: var(--txt-primary); font-weight: 700; }

/* 일본 배포 — 한국 전용 항목(NAVER 예약 줄·현금영수증 카드) 숨김 (2026-10-21). 위 규칙의 display 가 .bi-hidden 을 이기므로 같은 특이도로 뒤에서 다시 선언 */
.bi-bk2-src.bi-hidden,
.bi-pay2__card.bi-hidden { display: none; }
.bi-bs2 .bi-bs2-tile.bi-hidden,
.bi-bs2 .bi-bs2-prow.bi-hidden { display: none; }
/* 일본 배포 — N Pay 타일을 숨긴 뒤 남은 타일이 줄 전체를 채운다(3칸·4칸 모두) */
.bi-bs2 .bi-bs2-tiles { grid-template-columns: repeat(auto-fit, minmax(72px, 1fr)); }

/* 일본 배포 — 현금영수증 카드를 뺀 현금 결제 팝업은 내용이 최소 키(§93, 450)보다 짧다.
   §95 와 같은 수법으로 푸터(결제 버튼)를 창 바닥에 붙여, 버튼 아래 빈 띠를 없앤다. 범위는 현금 팝업뿐. */
html:has(> body .bi-pop-pay--cash) { height: 100%; }
body:has(.bi-pop-pay--cash) { min-height: 100%; display: flex; flex-direction: column; }
.bi-pop-pay--cash { flex: 1 1 auto; display: flex; flex-direction: column; }
.bi-pop-pay--cash > .bi-pay2 { flex: 1 1 auto; display: flex; flex-direction: column; }
.bi-pop-pay--cash > .bi-pay2 > form { flex: 1 1 auto; display: flex; flex-direction: column; }
.bi-pop-pay--cash .bi-pay2__foot { margin-top: auto; }
