/*
 * nous-bill-global.css
 * - 2026-09-05: v7.50 — **`[hidden] { display:none !important }` 전역 규칙 신설.** 🔴 209-1 실기기(기획자)에서 변경·취소·노쇼 패널이
 *   한꺼번에 그려져 「매너점수 규칙 확인」이 두 개 떴다 — 작성자 규칙 `.reply-row{display:grid}` 가 UA 의 `[hidden]` 을 이긴 것.
 *   ⚠ 목업 209-1 도 같은 결함(2026-08-12 «display !important 편법 제거 → hidden 전환» 때 생긴 구멍) → 목업 v8 에도 같은 줄.
 *   보이게 하려면 hidden 을 떼라 — 클래스로 display 를 켜지 마라. 본코딩 실물과 함께 정본화(전수조사 2026-09-05).
 * - 2026-09-05: v7.49 — **`.toast` z-index 50 → 600.** 🔴 206 실기기(기획자)에서 모달(오버레이 320)을 연 채 뜨는 검증 안내가
 *   뒤에 깔려 «[대기]가 안 눌린다»로 보였다. 토스트는 «지금 이 순간의 알림»이라 무엇보다 위에 있어야 한다.
 *   600 = 화면 오버레이 최댓값(501-1 intro 500)보다 위 · 오프라인 배너(999)보다 아래.
 *   ⚠ 화면 CSS 에서 `.toast` 의 z-index 를 다시 선언하지 마라 — 여기 하나로 정한다(`tools/nb_port_check.rb` ⑪ 이 지켜본다).
 *   목업 8화면이 갖고 있던 `.toast{z-index:400}` 인라인 복사본도 이 값으로 갈음한다.
 * - 2026-08-31: v7.48 — **시간·날짜 선택칸 `.time-select` 정본 신설** (기획자 지시
 *   *"이걸 시간입력을 사용하는 모든곳에 적용해줘"*). 🔴🔴 **종전에는 정본이 아예 없었다** —
 *   이 파일에도 쿡북에도 0건인 채로 **9화면이 각자 인라인 복사본**을 들었고 **이미 6가지로 갈려 있었다**
 *   (글자 크기·글자색·padding·transition). 모양은 정본 `.btn-inline`(+`.lg`) 계열을 따르고
 *   **여기서 색을 새로 만들지 않는다**. 고름 표시 `.chosen`(=511 업종 버튼의 `aria-pressed="true"`와 같은 값).
 *   ⚠ 글자 `--text-xs` — 월·일·시·분 **네 칸이 한 줄**에 들어가야 한다(§3 하한 13px).
 *   ⚠ `<select>`를 버튼으로 바꾸지 않는다 — 시(時)가 24개다. **모양만 맞춘다.**
 *   ⚠⚠ **`.selected`는 「상태」가 아니다** — 208-1·208-2·210이 마크업에 **고정**으로 달아 늘 켜져 있다.
 *   같은 값으로 두어 현재 모양을 바꾸지 않되, **새 화면은 `.chosen` + JS 토글**을 쓴다.
 *   ⚠ **프로토타입=스냅샷이라 자동 전파되지 않는다**(`.toast.multi` v7.39와 같은 경고) —
 *   이 값을 고치면 쓰는 화면을 함께 고친다. 복붙 코드·금지 사항 = 쿡북 **§AA**.
 * - 2026-08-21: v7.43 — `--color-text-bright: #90EEBC` 신설 (기획자 지시).
 *   `#A7F3D0`(--color-text-muted)과 `#78E8A8`(--color-text)의 **산술 중간값**이다.
 *   발단: 220 표 헤더·206 [이 당구장에서 대기] 모달의 `--color-text-muted` 글자가 **흰색으로 읽혔고**,
 *   `--color-text`로 낮추자 이번에는 어두웠다 — *"원래 흰색과 지금 초록색의 중간 정도"*.
 *   ⚠ `#A7F3D0`보다 **어둡다** — 「가장 밝은 글자색은 #A7F3D0」(design-system §7 v7.20 ④) 규칙에 위배되지 않는다.
 *   ⚠ 이 색을 쓸 자리는 **`--color-text-muted`가 흰색으로 읽히는 자리**다. muted를 대체하지 않는다
 *   (비활성 메뉴·부가 설명·보조 라벨은 그대로 muted). 첫 소비 = 206 v1.12 · 220 v1.11.
 *   design-system **v7.47**(§11-1 메인 :root · §5 색상 사용 원칙 표 · §11-6 Tailwind 매핑)과 동기화.
 * - 2026-07-31: v7.42 — 101 class 기반 인증 모달이 초기 화면부터 노출될 수 있던 결함 수정.
 *   `.verify-modal:not([hidden])` 선택자를 제거하고 `.verify-modal.visible`일 때만 표시한다.
 *   `[hidden]` 명시 숨김 규칙은 유지한다. 101 prototype_75 / SKILL v2.14와 동기화.
 * - 2026-07-31: v7.41 — 101 회원 선택 카드의 회원유형·표시명을 동일한 버튼 표준으로 통일.
 *   `.member-choice-btn`은 왼쪽 정렬·줄 배치만 담당하고, 두 줄 모두 `.btn-primary`의
 *   16px·`--color-text`·700을 상속한다. 101 prototype_72~73 / SKILL v2.11~v2.12와 동기화.
 * - 2026-07-31: v7.40 — 101 회원 선택 카드 버튼을 §11-5 단일 버튼 표준으로 통일.
 *   `.member-choice-btn`의 별도 청록 그라데이션·테두리·패딩·min-height를 폐지하고,
 *   마크업에서 `.btn-primary member-choice-btn`을 함께 사용한다. 이 클래스는 왼쪽 정렬과
 *   회원명/표시명 두 줄 배치만 담당한다. 글자: 회원유형 16px `--color-text`, 표시명 13px `--color-text-muted`.
 * - 2026-07-28: v7.39 — .toast.multi 폭 시정 (기획자 지시). left:16px/right:16px/max-width:none 폐지 →
 *   width:calc(100% - 32px) · max-width:448px · transform 에 translateX(-50%) 부활(.show 도 동일).
 *   사유: position:fixed 기준이 앱 틀이 아니라 브라우저 창이라 넓은 창에서 앱 폭(480px)을 넘었다.
 *   ⚠ 502(v4)·511(v1.8)이 이미 이 값으로 각자 이탈해 있었다 — 본 시정으로 정본이 두 화면을 따라간다.
 *   ⚠ .toast.multi 를 인라인 복사본으로 품은 다른 화면은 자동 전파되지 않는다(프로토타입=스냅샷).
 *      구 값은 폐지 리터럴 목록 v1.14에 등재해 grep 으로 잡는다. 기본형 .toast 는 불변.
 * - 2026-07-25: v7.38 — 충전금 원장 표시 CSS 신설(쿡북 §Y 대응). 214·508·311이 각자 인라인으로 품고 있던
 *   같은 값을 여기 한 곳으로 모은다. 4xx(할인가맹점)·6xx(영업조직)도 같은 화면을 쓴다.
 *   ⚠ 현황 4칸 행은 `.chg-*`다 — `.band-*`(§T 라벨띠 2칸)와 **이름이 비슷한 다른 물건**.
 *   ⚠ 본 절은 design-system ★ "어느 문서를 고칠 것인가"(v7.30) *"CSS 값을 바꾸라는 지시를 받으면
 *      global.css를 고친다"*에 따라 여기에 직접 적는다(아래 옛 경고문보다 v7.30이 나중이다).
 * - 2026-07-24: v7.37 — 숫자패드 오버레이 정본 추가, 구 인라인/하단 패드는 호환 전용으로 격하. 101 복수 회원 선택·신뢰 기기 모달 공통 CSS 추가.
 * 누빌(nous-bill) 앱 전체 공통 CSS
 * 출처: nous-bill-design-system.md 섹션 11 확정 코드
 *
 * ⚠️  이 파일을 직접 수정하지 말 것.
 *     nous-bill-design-system.md 를 먼저 업데이트한 후 이 파일에 반영할 것.
 *
 * 사용법: 모든 HTML 파일 <head>에 아래 한 줄 추가
 *   <link rel="stylesheet" href="nous-bill-global.css">
 *   (Pretendard는 외부 CDN에서 받지 않는다 — 2026-08-30 정본 통일 · design-system §3 참조.
 *    본코딩은 번들/로컬 자산으로 제공한다. 프로토타입은 --font-base fallback으로 그린다)
 *
 * [수정 이력]
 * - 2026-07-17: design-system v7.33 동기화 — .btn-inline 에 큰 변형(.lg) 신설 (기획자 판단 위임)
 *   배경: 줄 안 버튼이 **한 크기뿐**이라, 동의 행(201)처럼 줄 자체가 큰 곳에 28px 버튼이 놓였다.
 *   기획자 지적: *"배경 박스가 크기 때문에 디자인상 큰 버튼이 맞다. 작은 버튼이 어울리지 않잖아."*
 *   ⚠ 자동화(줄 높이를 재서 따라가기)는 **채택하지 않았다** — 줄 높이는 그 안의 글이 몇 줄이냐로 정해져서,
 *      문구를 고치거나 기기 폭이 바뀌면 버튼 크기가 따라 변한다(201 필수행 28px vs 선택행 44px로 갈림).
 *      v7.25에서 광고 틀을 25vh → aspect-ratio:2/1 로 바꾼 것과 **같은 이유**다(기기 종속 크기 폐기).
 *   내용: .btn-inline.lg = padding 6px 12px · min-height 44px · font-size var(--text-sm). **크기 3개만.**
 *   ⚠ 기본형 .btn-inline 값 불변 — 214([요청하기] 30px·[복사] 28px) 등 기존 화면 영향 0.
 *   동반: .view-btn 폐지(정본에 CSS가 없어 화면마다 각자 만들던 클래스) → <button class="btn-inline lg">.
 * - v7.27 동기화 (2026-07-15, 기획자 지시 — F-48 "3개 다 등재")
 *   .toast.multi / .toast.multi.show 신설 (design-system §11-11 여러 줄 토스트).
 *     메시지에 \n 이 있을 때만 적용되는 변형 — 기본형 .toast(한 줄·알약형) 불변, 기존 호출부 영향 없음.
 *     showToast() 가 \n 유무로 클래스 자동 토글 (§11-11 표준 코드).
 *   ※ 도식 인라인 SVG 표준(§11-25)·가이드 아코디언(쿡북 §P)은 화면별 마크업이라 본 파일 대상 아님.
 * - v7.26 동기화 (2026-07-15, 기획자 지시)
 *   .btn-primary color: var(--color-text-muted) → var(--color-text) (#A7F3D0 → #78E8A8)
 *   .btn-primary:hover 의 color: var(--color-text) 선언 삭제 — 기본색과 같아져 의미 상실.
 *     hover 색 변화 없음(기획자 2번안). transform·box-shadow 피드백만 유지.
 *   대상은 .btn-primary 만. .btn-primary.active(--color-primary)·:disabled·.nkey·verify-btn 은 대상 아님.
 * - 색상 변수 HTML + 디자인 시스템 기준으로 통일
 *   --color-bg:       #022C22 → #0f3d20
 *   --color-surface:  #064E3B → #1a5c2e
 *   --color-surface2: #065F46 → #236835
 *   btn-primary color: #022C22 → #0f3d20
 *   numpad-panel background, nkey 색상 동일 기준으로 수정
 *   tbody tr:hover 색상 동일 기준으로 수정
 * - 2026-05-03: design-system v7.1 동기화
 *   .input-field::placeholder color: var(--color-text-muted) → rgba(74,222,128,0.35)
 *   --color-text-muted 주석에서 "플레이스홀더" 단어 제거
 * - 2026-05-03: design-system v7.3 동기화 — 광고 영역 고정 결함 수정
 *   body: min-height: 100vh → height: 100vh + overflow: hidden
 *   .content-area: min-height: 0 추가
 * - 2026-05-08: design-system v7.4~v7.8 누적 동기화 (이전 동기화 누락분 일괄 반영)
 *   v7.4 (파일명 정리): global.css 영향 없음. 이력 기록만.
 *   v7.5 (§11-18~§11-23 신규): global.css는 §11-1~§11-17 범위만 담당. 본 css 영향 없음.
 *   v7.6 (11건 정리):
 *     - :root에 --radius-xl: 16px, --radius-full: 9999px 추가 (v7.2 동기화 누락분)
 *     - .toast border-radius: 9999px → var(--radius-full)
 *     - .ad-banner-small에 position: relative 명시 (design-system §11-3과 일치)
 *   v7.7 (자격 정리): 글로벌 자격 명문화. 본 css는 시각 표준만이므로 자격 적합.
 *   v7.8 (정합성 점검):
 *     - :root에 --text-xs/sm/base/lg/xl/2xl 폰트 사이즈 변수 추가 (design-system §3 정의분)
 *     - .input-field font-size: 16px → var(--text-base)
 *     - .input-field::placeholder font-size: 14px → var(--text-sm)
 *     - .error-message font-size: 12px → var(--text-xs)
 *     - .btn-primary:hover translateY(-1px) → translateY(-4px) (design-system §11-5 통일)
 *     - .btn-secondary:hover translateY(-1px) → translateY(-4px) (동상)
 *     - 숫자패드 케이스 A(#numpad·.middle-area) 추가 — design-system §11-10 v7.6 동기화
 *     - .score-display·.win-rate-display 사용처 주석 강화 (점수판 화면 전용 명시)
 * - 2026-05-24: btn-secondary 색상 변경 (v7.12)
 * - 2026-05-24: 버튼 전체 상태 정의 추가 (v7.15)
 *   210 fbtn 기준: 기본 color=text-muted, hover color=text, active=#2d7a42→#236835→#1a5228+color=primary, transition:all 0.15s
 * - 2026-05-24: 버튼 단일 표준 통합 (v7.13)
 *   btn-primary: surface 그라디언트, color=var(--color-primary), border-top rgba(74,222,128,0.45), box-shadow 축소
 *   btn-secondary 폐지 — btn-primary 단일 사용으로 통일
 *   background: #22B880→#085540 그라데이션 → rgba(255,255,255,0.06)→surface→rgba(0,0,0,0.15) (fbtn 비활성 스타일)
 *   color: #7EFFA8 → var(--color-primary)
 *   border-top: rgba(74,222,128,0.6) → rgba(74,222,128,0.45)
 *   border-bottom: 3px rgba(0,0,0,0.6) → 2px rgba(0,0,0,0.5)
 *   box-shadow: 0 8px 18px → 0 4px 10px
 *   body: height: 100vh; height: 100dvh; (폴백 + 우선 적용 두 줄 박는 방식)
 *   사유: 모바일 브라우저 진입 시 주소창·하단바가 표시되어 100vh 영역의 콘텐츠가 가려짐.
 *         100dvh는 브라우저 UI를 자동 제외한 실제 사용 가능 높이.
 *         iOS Safari 15.4+, Chrome Mobile 108+, Samsung Internet 21+ 지원.
 *         구형 브라우저는 dvh를 무시하고 vh 사용 (자연 폴백).
 *   영향 없음: 광고 고정 4규칙(쿡북 §H), 콘텐츠 영역(§11-4), 다른 표준 그대로.
 * - 2026-06-05: design-system v7.19 동기화 — 광고 위치 정책(고정 vs 스크롤)
 *   .content-area > .ad-zone 음수 마진 유틸 추가 (스크롤 화면 전체 폭 유지).
 *   kwang777 = 고정(.ad-zone를 body 직속 — 현 .ad-zone{flex-shrink:0} 그대로),
 * - 2026-06-05: design-system v7.20 동기화 — 글자 크기·색상 규칙 4건
 *   --text-xs: 12px → 13px (최소 글자 크기 13px 규칙). .field-label 11px → 13px.
 *   금색(--color-highlight): 경고·주의 문구 전용 (점수판 예외 삭제). .score-display 금색→녹색(--color-primary)+녹색 글로우. 그 외 금색은 기획자 특별 지시.
 *   흰색 계열 글자 기본 금지 — 필요 시 #A7F3D0(=--color-text-muted) 사용, 이 색이 가장 밝은 글자색 (주석 갱신).
 *   글자색은 녹색 계열(#A7F3D0 ~ 진한 녹색)만 — 예외는 경고문(금색)·에러(붉은색).
 * - 2026-06-05: design-system v7.21 동기화 — 점수판 기본 방향(휴대폰 세로 / 태블릿 가로). 점수판 주석에서 "(가로모드)" 표현 제거.
 * - 2026-06-14: design-system v7.22 동기화 — 버튼 글자 크기 18px → 16px (화면 타이틀과 동일)
 *   .btn-primary font-size: var(--text-lg) → var(--text-base). 회원유형 버튼·숫자패드 키는 대상 아님.
 * - 2026-06-21: design-system v7.23 동기화 — 광고 위치 정책 '기획자 고정 지정제'
 *   kwang777은 항상 고정 + 그 외 kwang{N}은 기본 스크롤이되 기획자가 화면별로 '고정' 지정 가능.
 *   CSS 자체는 불변(고정=.ad-zone body 직속 / 스크롤=.content-area 첫 자식 + 음수 마진). 정책 주석만 갱신.
 * - 2026-07-01: design-system v7.24 — 광고 업로드 권장 규격 신설(문서 전용). CSS 무관.
 * - 2026-07-16: design-system v7.30 동기화 — 문서 역할 분담 + 어긋난 중복 5건 시정
 *   ★ **CSS 값의 정본은 이 파일 한 곳뿐이다.** 디자인 시스템은 규칙·판단 기준만 적고,
 *      쿡북은 마크업·조립법만 적는다. 값을 바꾸라는 지시를 받으면 **여기를 고친다**.
 *   시정: .ad-fallback-label(13px vs 14px 어긋남 → 토큰 통일 + **프로토타입 전용** 명시 —
 *         실서버는 loadAd()가 광고 없으면 .ad-zone 숨김. v7.12 확정. 본 코딩 시 삭제 대상) /
 *         .numpad-panel → **.numpad-sheet 개명**(쿡북 §M의 가운데 오버레이 패널과 이름 충돌 —
 *         같은 이름 다른 물건이라 한 화면에 둘 다 오면 패드가 깨진다).
 *   ⚠ CSS 값 자체는 불변(.btn-primary padding:13px·min-height:44px 등 전부 그대로).
 * - 2026-07-16: design-system v7.29 동기화 — §11-5에 "줄 안에 얹히는 버튼" .btn-inline 신설
 *   버튼은 두 종류다: 혼자 한 줄 차지(.btn-primary, 폭 100%·50px) / 줄 안에 얹힘(.btn-inline, 폭=글자만큼·13px).
 *   예) .btn-primary = 저장·수정하기·탈퇴하기 / .btn-inline = 표 칸 안 [요청하기]·글자 옆 [복사]
 *   가르는 질문: "[저장] 버튼 옆에 나란히 뒀을 때 같은 크기여야 자연스러운가?"
 *   ⚠ 줄 안 버튼도 화면이 새로 만들지 않는다(.btn-dissolve·.btn-copy-code 같은 이름 신설 금지).
 *   ⚠ 13px 미만 금지(v7.20)는 그대로. 44px 탭 타깃은 못 맞추므로 얹히는 줄이 충분한 높이를 갖게 한다.
 *   ⚠ 기존 .btn-primary 값 불변 — 신규 클래스 추가일 뿐 기존 버튼 영향 없음.
 * - 2026-07-16: design-system v7.28 동기화 — §11-5 적용 범위 확장 (기획자 지시)
 *   "버튼처럼 생긴 것"은 전부 .btn-primary / .btn-primary.active 이다.
 *   눌리는 버튼뿐 아니라 **섹션 제목띠·아코디언 헤더·정보 행 라벨 띠**가 포함된다.
 *   화면이 같은 모양의 클래스를 새로 만드는 것 금지(.section-header·.sec-title·.rec-count-label 등 신설 금지).
 *   안 눌리는 요소는 <div class="btn-primary active">로 모양만 빌린다(<button> 금지 — 낭독기 §11-12).
 *   화면이 정하는 것은 배치뿐(화살표 자리·숫자 칸 폭). 색·그라데이션·글자·패딩·min-height는 여기서만 정한다.
 *   ⚠ CSS 값 자체는 불변 — padding:13px · min-height:44px · 색 · 글자 전부 v7.27 그대로.
 *      이번 동기화는 **범위·금지 규칙**만 반영(주석). 쿡북 v2.12(§T 신규 · §P 헤더 흡수) 동반.
 * - 2026-07-01: design-system v7.25 동기화 — 광고 표시 틀 개정(잘림 없이 전체 표시)
 *   .ad-banner-small: height:25vh(유동 비율) → aspect-ratio:2/1(비율 고정), 폭은 width:100% 유지.
 *   .ad-banner-small img: object-fit:cover(잘림) → contain(전체 표시·여백 허용). 소재는 2:1 권장.
 *   대가: '광고=화면 높이 1/4(25vh)' 보장 폐지(세로 비중이 폭에 종속). 위치 정책(v7.23)·미등록 숨김은 불변.
 */

/* ── 스크롤바 숨김 (기능 유지, 표시만 제거) ── */
* { scrollbar-width: none; }            /* Firefox */
*::-webkit-scrollbar { display: none; } /* Chrome / Safari / 모바일 */

/* ── 공통 초기화 ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ── CSS 변수 (색상·반경·폰트 사이즈·폰트) ── */
:root {
  --color-bg:        #0f3d20;  /* 최하단 배경 (당구대 녹색) */
  --color-surface:   #1a5c2e;  /* 카드, 테이블, 패널 등 표면 */
  --color-surface2:  #236835;  /* 테이블 헤더 전용 */
  --color-primary:   #4ADE80;  /* 버튼(활성), 현재 상태, 링크 */
  --color-highlight: #F59E0B;  /* 경고·주의 문구 전용. 점수·KPI 숫자 포함 그 외 모든 용도는 기획자 특별 지시 필요. 배경·버튼 금지 (v7.20) */
  --color-text:      #78E8A8;  /* 기본 텍스트 */
  --color-text-bright:#90EEBC; /* 본문보다 한 단계 밝은 글자. #A7F3D0과 #78E8A8의 산술 중간값 (v7.43, 기획자 지시 2026-08-21) */
  --color-text-muted:#A7F3D0;  /* 보조 텍스트 + 흰색 대체색(가장 밝은 글자색). placeholder는 rgba(74,222,128,0.35) 직접 사용 (v7.20) */
  --color-error:     #EF4444;  /* 에러 메시지 전용 */
  --glow-primary: 0 0 8px rgba(74,222,128,0.6), 0 0 20px rgba(74,222,128,0.3);
  /* 모서리 반경 */
  --radius-sm:   4px;
  --radius-md:   8px;
  --radius-lg:   12px;
  --radius-xl:   16px;        /* v7.6 추가 */
  --radius-full: 9999px;      /* v7.6 추가 */
  /* 폰트 사이즈 — design-system §3 폰트 체계 (v7.8 추가) */
  --text-xs:    13px;        /* 최소 글자 크기 (v7.20) */
  --text-sm:    14px;
  --text-base:  16px;
  --text-lg:    18px;
  --text-xl:    22px;
  --text-2xl:   28px;
  /* 폰트 패밀리 */
  --font-base: 'Pretendard', -apple-system, BlinkMacSystemFont,
               'Apple SD Gothic Neo', 'Noto Sans KR', sans-serif;
}

/* ── body 기본 설정 ── */
/* ⚠️ height: 100vh + overflow: hidden 은 광고 고정을 보장하기 위함이다.
   min-height: 100vh 로 두면 콘텐츠가 길어질 때 페이지 전체가 스크롤되어
   .ad-zone 의 flex-shrink: 0 이 무력화된다. 내부 스크롤은 .content-area 가 담당한다.
   ⚠️ height: 100vh; height: 100dvh; (v7.4) — 두 줄 모두 박는 방식.
   100vh는 모바일 브라우저 주소창·하단바를 제외하지 않은 전체 화면 높이라
   콘텐츠가 브라우저 UI에 가려질 수 있음. 100dvh는 브라우저 UI를 제외한 실제 영역.
   구형 브라우저는 dvh를 무시하고 vh 사용 (자연 폴백). */
body {
  font-family: var(--font-base);
  font-feature-settings: "tnum";
  -webkit-font-smoothing: antialiased;
  background-color: var(--color-bg);
  color: var(--color-text);
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-width: 480px;
  margin: 0 auto;
}

/* ── 페이지 헤더 ── */
.page-header {
  position: sticky; top: 0; z-index: 10;
  background-color: var(--color-bg); padding: 10px 14px;
  border-bottom: 1px solid rgba(74,222,128,0.1);
  display: flex; align-items: center; gap: 8px;
  flex-shrink: 0;
}
.btn-back, .btn-header-act {
  width: 34px; height: 34px; border-radius: var(--radius-md); flex-shrink: 0;
  background: rgba(4,46,34,0.7);
  border: 1px solid rgba(74,222,128,0.18);
  display: flex; align-items: center; justify-content: center;
  color: var(--color-text-muted); font-size: 16px; cursor: pointer;
  transition: color 0.15s, background 0.15s;
}
.btn-back:hover, .btn-header-act:hover { color: var(--color-primary); background: rgba(74,222,128,0.1); }
.page-header h1 {
  flex: 1;
  background: linear-gradient(180deg, #2d7a42 0%, #236835 50%, #1a5228 100%);
  border-top: 1.5px solid rgba(74,222,128,0.5);
  border-bottom: 2px solid rgba(0,0,0,0.5);
  border-left: none; border-right: none;
  border-radius: var(--radius-md);
  box-shadow: 0 4px 10px rgba(0,0,0,0.5);
  padding: 8px 0; text-align: center;
  font-size: 16px; font-weight: 700;
  color: var(--color-primary); letter-spacing: -0.01em;
}
.header-right { width: 34px; flex-shrink: 0; }

/* ── 광고 영역 (kwang100 계열 — 폭 100%·비율 2:1 고정) ── */
.ad-zone { flex-shrink: 0; }
/* 광고 위치 정책 (design-system §11-3 v7.23 — 기획자 고정 지정제):
   · kwang777(대회 광고) = 항상 고정 / 그 외 kwang{N} = 기본 스크롤이되 기획자가 화면별로 '고정' 지정 가능.
     (어느 화면이 고정인지는 각 화면 SKILL ⑳·연결 인덱스 광고 표기 '고정(기획자 지정)'으로 확인)
   · 고정 = .ad-zone를 body 직속 flex 자식으로(헤더와 .content-area 사이). 광고 고정 4규칙(쿡북 §H) 적용.
   · 스크롤(기본) = .ad-zone를 .content-area 첫 자식으로 두면 아래 음수 마진으로
     콘텐츠 영역 패딩(20px 16px 32px)을 상쇄해 전체 폭·상단 밀착 유지. 마지막 16px = 첫 콘텐츠와의 간격.
     (콘텐츠 영역 패딩값이 다른 화면은 음수 마진도 그 값에 맞춘다.) */
.content-area > .ad-zone { margin: -20px -16px 16px; }
.ad-banner-small {
  width: 100%; aspect-ratio: 2 / 1; border-radius: 0;  /* v7.25 — 비율 2:1 고정(높이는 폭에 종속). border-radius:0 고정 */
  background-color: var(--color-surface);
  overflow: hidden; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  position: relative;  /* v7.6 추가 — fallback absolute 위치 기준 */
}
.ad-banner-small img { width: 100%; height: 100%; object-fit: contain; display: block; }  /* v7.25 — contain: 잘림 없이 전체 표시(2:1 아니면 여백) */
.ad-fallback {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 10px;
  width: 100%; height: 100%; position: absolute; inset: 0;
}
/* ⚠ 프로토타입 전용 자리표시(design-system v7.12) — 실서버는 loadAd()가 광고 없으면
   .ad-zone 전체를 display:none 으로 숨긴다. 광고가 없으면 아무것도 표시하지 않는다.
   본 코딩 시 .ad-fallback 계열 CSS·마크업은 삭제한다. */
.ad-fallback-label {
  font-size: var(--text-sm); color: var(--color-text-muted);
  letter-spacing: 0.08em; font-weight: 500;
}
.ad-divider {
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(74,222,128,0.2), transparent);
}

/* ── 콘텐츠 영역 A — 스크롤 있는 일반 화면 ── */
/* ⚠️ min-height: 0 필수 — flex 컨테이너(body) 안에서 자식의 내부 스크롤이 작동하려면 이 속성이 있어야 한다. */
.content-area {
  flex: 1; min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 20px 16px 32px;
}

/* ── 콘텐츠 영역 B — 스크롤 없이 꽉 채우는 화면 ── */
.content-area-fixed {
  flex: 1; overflow: hidden;
  padding: 10px 18px 10px;
  display: flex; flex-direction: column;
  gap: 8px; min-height: 0;
}

/* ── 하단 고정 액션 버튼 영역 ── */
.action-footer {
  position: sticky; bottom: 0;
  background-color: var(--color-bg);
  padding: 12px 16px;
  border-top: 1px solid rgba(74,222,128,0.1);
}

/* ── 테이블 ── */
table {
  border-radius: var(--radius-md); overflow: hidden;
  border-collapse: collapse; width: 100%;
}
thead tr {
  background-color: var(--color-surface2);
  color: var(--color-text); font-weight: 600; font-size: var(--text-sm);
}
tbody tr {
  background-color: var(--color-surface);
  border-bottom: 1px solid rgba(4,120,87,0.4);
}
tbody tr:hover {
  background-color: rgba(10,95,45,0.8);
  transition: background-color 0.15s ease;
}

/* ── 버튼 표준 (단일) — v7.15: 210 fbtn 기준으로 전체 상태 정의 ── */
/* btn-secondary 폐지 — 기존 사용처는 btn-primary로 교체할 것 */
.btn-primary {
  width: 100%; padding: 13px;
  background: linear-gradient(180deg, rgba(255,255,255,0.06) 0%, var(--color-surface) 40%, rgba(0,0,0,0.15) 100%);
  color: var(--color-text); border: none;
  border-top: 1.5px solid rgba(74,222,128,0.45);
  border-bottom: 2px solid rgba(0,0,0,0.5);
  border-radius: var(--radius-md); box-shadow: 0 4px 10px rgba(0,0,0,0.5);
  font-size: var(--text-base); font-weight: 700; font-family: var(--font-base);
  cursor: pointer; transition: all 0.15s;
  min-height: 44px;
}
.btn-primary:hover { transform: translateY(-4px); box-shadow: 0 8px 16px rgba(0,0,0,0.6); }
.btn-primary:active { transform: translateY(2px); box-shadow: 0 1px 3px rgba(0,0,0,0.4); }
.btn-primary.active { background: linear-gradient(180deg, #2d7a42 0%, #236835 50%, #1a5228 100%); border-top-color: rgba(74,222,128,0.5); border-bottom-color: rgba(0,0,0,0.5); color: var(--color-primary); }
.btn-primary:disabled {
  background: rgba(74,222,128,0.2); color: rgba(236,253,245,0.4);
  border-top-color: transparent; border-bottom-color: transparent;
  box-shadow: none; cursor: not-allowed; transform: none;
}

/* ── 줄 안에 얹히는 버튼 (design-system §11-5 v7.29) ──
   표 칸 안·글자 옆에 얹히는 작은 버튼. 혼자 한 줄 차지하는 버튼(.btn-primary)과 다른 종류다.
   예) 복식팀 표의 [요청하기] · 추천인 코드 옆 [복사]
   화면이 같은 모양의 클래스를 새로 만들지 않는다(.btn-dissolve·.btn-copy-code 등 신설 금지). */
.btn-inline {
  width: auto; padding: 5px 10px; min-height: 0;
  background: linear-gradient(180deg, rgba(74,222,128,0.15) 0%, rgba(74,222,128,0.07) 100%);
  border: 1px solid rgba(74,222,128,0.3); border-radius: var(--radius-sm);
  color: var(--color-text-muted); font-size: var(--text-xs); font-weight: 700;
  font-family: var(--font-base); cursor: pointer; white-space: nowrap;
  transition: all 0.15s; flex-shrink: 0;
}
.btn-inline:hover {
  background: linear-gradient(180deg, rgba(74,222,128,0.25) 0%, rgba(74,222,128,0.12) 100%);
  border-color: rgba(74,222,128,0.55); color: var(--color-primary); transform: translateY(-1px);
}
.btn-inline:active { transform: translateY(1px); }
.btn-inline:disabled { opacity: 0.4; cursor: not-allowed; transform: none; }

/* 큰 줄 안 버튼 (v7.33 · design-system §11-5) — 동의 행처럼 **줄 자체가 큰** 경우.
   기본형(.btn-inline)을 덮어쓰는 **변형**이다(§11-11 .toast.multi 와 같은 방식) —
   기본형은 그대로 두므로 기존 화면(214 등)에 영향이 0이다.
   ⚠ **크기 3개만 바꾼다.** 배경·테두리·색·굵기는 기본형 그대로 — 두 벌이 되면 또 갈라진다.
   가르는 질문: "이 버튼이 얹힌 줄이, 버튼을 44px로 키워도 두꺼워지지 않을 만큼 큰가?"
     그렇다 → .lg  /  아니다(표 칸·글자 옆) → 기본형
   ⚠ **한 화면 안에서는 하나로만 쓴다.** 줄마다 골라 쓰면 한 화면에서 크기가 갈린다(214에서 실제 발생). */
.btn-inline.lg {
  padding: 6px 12px; min-height: 44px; font-size: var(--text-sm);
}

/* ── 입력 필드 ── */
.input-field {
  background-color: var(--color-surface);
  border: 1px solid rgba(74,222,128,0.2);
  border-radius: var(--radius-md); color: var(--color-text);
  font-family: var(--font-base); font-size: var(--text-base);  /* v7.8 변수화 */
  padding: 10px 14px; width: 100%;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.input-field::placeholder { color: rgba(74,222,128,0.35); font-size: var(--text-sm); }  /* v7.8 변수화 */
.input-field:focus {
  outline: none; border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(74,222,128,0.15);
}
.input-field.error {
  border-color: var(--color-error);
  box-shadow: 0 0 0 3px rgba(239,68,68,0.15);
}
.error-message { color: var(--color-error); font-size: var(--text-xs); margin-top: 4px; }  /* v7.8 변수화 */

/* ── 카드 ── */
.card {
  background-color: var(--color-surface);
  border-radius: var(--radius-lg);
  border: 1px solid rgba(74,222,128,0.08);
  padding: 16px 20px;
}

/* ── 구획 돋움 효과 (Emboss) ── */
.emboss {
  background: linear-gradient(180deg, rgba(255,255,255,0.08) 0%, var(--color-surface) 40%, rgba(0,0,0,0.2) 100%);
  border-top: 1.5px solid rgba(74,222,128,0.7);
  border-bottom: 3px solid rgba(0,0,0,0.65);
  border-left: 1px solid rgba(74,222,128,0.2);
  border-right: 1px solid rgba(74,222,128,0.2);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 20px rgba(0,0,0,0.7);
}
.emboss:active { transform: translateY(2px); box-shadow: 0 2px 4px rgba(0,0,0,0.5); }

/* ── 글로우 효과 ── */
.active-value, .score-live, .tab-active, .menu-active {
  color: var(--color-primary); text-shadow: var(--glow-primary);
}
tr.selected { background-color: rgba(74,222,128,0.1); outline: 1px solid rgba(74,222,128,0.4); }
tr.selected td { color: var(--color-primary); text-shadow: 0 0 6px rgba(74,222,128,0.4); }

/* ── 레이블 ── */
.field-label {
  font-size: 13px; color: var(--color-text-muted);
  font-weight: 500; letter-spacing: 0.05em; margin-bottom: 6px;
}

/* ── [hidden] 은 무조건 숨긴다 (v7.50 · 2026-09-05) ──
   🔴 209-1에서 데었다(기획자 실기기): 변경·취소·노쇼 패널을 `hidden` 속성으로 갈아 끼우는데, `.reply-row{display:grid}` 같은
   작성자 규칙이 UA 의 `[hidden]{display:none}` 을 이긴다 → 세 패널이 한꺼번에 그려져 「매너점수 규칙 확인」이 두 개 떴다.
   ⚠ 목업 209-1 도 같은 결함을 갖고 있다(2026-08-12 «display !important 편법 제거 → hidden 전환» 때 생긴 구멍) — 목업도 고쳐야 한다.
   ⇒ 정본에서 한 줄로 못 박는다. 보이게 하려면 hidden 을 떼라(클래스로 display 를 켜지 마라). */
[hidden] { display: none !important; }

/* ── 토스트 메시지 ── */
.toast {
  position: fixed; bottom: 28px; left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: rgba(6,78,59,0.95); border: 1px solid rgba(74,222,128,0.3);
  border-radius: var(--radius-full);  /* v7.6 — 9999px → var(--radius-full) */
  padding: 10px 20px;
  font-size: var(--text-sm); color: var(--color-primary); font-weight: 600;
  white-space: nowrap; opacity: 0;
  transition: opacity 0.2s ease, transform 0.2s ease;
  /* v7.49(2026-09-05) — 50 → 600. 🔴 206에서 데었다(기획자 실기기 실측): 모달을 연 채 뜨는 검증 안내가
     오버레이(320) 뒤에 깔려 «버튼이 안 눌린다»로 보였다. 토스트는 «지금 이 순간의 알림»이라 무엇보다 위여야 한다.
     600 = 화면 오버레이 최댓값(501-1 intro 500)보다 위 · 오프라인 배너(999)보다 아래.
     ⚠ 화면 CSS에서 .toast의 z-index를 다시 선언하지 마라 — 여기 하나로 정한다(nb_port_check ⑪이 지켜본다). */
  pointer-events: none; z-index: 600;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* 여러 줄 토스트 변형 (v7.27 신설 · v7.39 폭 시정 · design-system §11-11) — 메시지에 \n 이 있을 때만 적용.
   기본형(.toast)은 알약형·nowrap 이라 긴 문구가 화면 밖으로 밀림 → 폭을 넓히고 줄바꿈을 허용한다.
   ⚠ v7.39 이전에는 left:16px/right:16px 였는데, position:fixed 의 기준은 앱 틀(body max-width:480px)이
      아니라 브라우저 창이다. PC처럼 창이 넓으면 토스트만 앱 좌우 폭을 넘어 화면 전체로 퍼졌다
      (1200px 창 실측 — 토스트 1168px vs 앱 480px).
   → 기본형의 left:50% 가운데 정렬을 그대로 물려받고 폭만 제한한다.
      448px = 앱 폭 480 − 콘텐츠 좌우 여백 16×2. 480px 이하 기기에서는 종전과 결과가 같다. */
.toast.multi {
  width: calc(100% - 32px); max-width: 448px;
  white-space: pre-line; text-align: center; line-height: 1.6;
  border-radius: var(--radius-lg); padding: 12px 16px;
  transform: translateX(-50%) translateY(20px);
}
.toast.multi.show { transform: translateX(-50%) translateY(0); }

/* ── 숫자패드 — 오버레이 단일 정본 (design-system §11-10 v7.37 / 쿡북 §M) ── */

.numpad-overlay {
  display: none; position: fixed; inset: 0; z-index: 200;
  background: rgba(0,0,0,0.6); align-items: center; justify-content: center;
}
.numpad-overlay.visible { display: flex; }
.numpad-panel {
  width: calc(100% - 48px); max-width: 360px;
  background: var(--color-bg); border: 1px solid rgba(74,222,128,0.25);
  border-top: 2px solid rgba(74,222,128,0.4); border-radius: var(--radius-xl);
  box-shadow: 0 12px 40px rgba(0,0,0,0.7); padding: 18px 16px 20px;
}
.numpad-title {
  min-height: 18px; margin-bottom: 12px; text-align: center;
  color: var(--color-text); font-size: var(--text-sm); font-weight: 700;
}
.numpad-dots { display: flex; justify-content: center; gap: 8px; margin-bottom: 14px; }
.num-slot {
  width: 34px; height: 44px; display: flex; align-items: center; justify-content: center;
  border: 1.5px solid rgba(74,222,128,0.35); border-radius: var(--radius-md);
  background: rgba(0,0,0,0.18); color: var(--color-text);
  font-size: var(--text-xl); font-weight: 700; font-family: var(--font-base);
  font-feature-settings: "tnum"; transition: all 0.12s;
}
.num-slot.filled { border-color: var(--color-primary); box-shadow: 0 0 6px rgba(74,222,128,0.4); }

/* ⚠ 구 인라인/하단 패드 호환 전용 — 신규 본코딩 사용 금지. 폐지값 점검표 v1.11이 신규 사용을 검출한다. */
/* 케이스 A: 패턴 자리 대체 (구 프로토타입 호환) */
/* .middle-area 안에 #pattern·#numpad가 같은 자리에 absolute 배치됨 */
.middle-area { flex: 1; min-height: 0; position: relative; }
#numpad {
  position: absolute; inset: 0;
  background: var(--color-surface);
  border-top: 1.5px solid rgba(74,222,128,0.3);
  border-bottom: 3px solid rgba(0,0,0,0.6);
  border-left: 1px solid rgba(74,222,128,0.15);
  border-right: 1px solid rgba(74,222,128,0.15);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 20px rgba(0,0,0,0.7);
  padding: 14px;
  display: none;
  flex-direction: column; justify-content: center; gap: 8px;
}
#numpad.visible { display: flex; }
#numpad .nkey { padding: 0; height: 52px; }
#numpad .nkey.confirm { font-size: var(--text-sm); }

/* 케이스 B: 하단 슬라이드업 (관리자 로그인 등)
   ⚠ v7.30 개명: .numpad-panel → **.numpad-sheet**.
      쿡북 §M의 가운데 오버레이 패널(.numpad-panel)과 **이름이 같은데 다른 물건**이었다.
      한 화면에 둘 다 들어오면 뒤에 선언된 쪽이 앞을 덮어 패드가 깨진다. */
.numpad-sheet {
  background: var(--color-surface);
  border-top: 1.5px solid rgba(74,222,128,0.2);
  padding: 10px 14px 16px;
  flex-shrink: 0; display: none;
}
.numpad-sheet.visible { display: block; }

/* 공통 */
.numpad-grid { display: grid; grid-template-columns: repeat(4,1fr); gap: 7px; }
.nkey {
  background: linear-gradient(180deg, #1a9a6a 0%, #1a5c2e 55%, #0a3d20 100%);
  border: none; border-top: 1.5px solid rgba(74,222,128,0.5);
  border-bottom: 3px solid rgba(0,0,0,0.6);
  border-radius: var(--radius-md); box-shadow: 0 5px 10px rgba(0,0,0,0.6);
  color: var(--color-text); font-size: var(--text-xl); font-weight: 600;   /* v7.30: 22px 직박음 → 토큰(=22px, 값 동일) */
  font-family: var(--font-base); font-feature-settings: "tnum";
  padding: 12px 0; cursor: pointer; text-align: center;
  transition: transform 0.08s, box-shadow 0.08s;
  -webkit-tap-highlight-color: transparent;
  min-height: 44px;
}
.nkey:active { transform: translateY(2px); box-shadow: 0 1px 3px rgba(0,0,0,0.5); }
.nkey.del { font-size: var(--text-base); color: var(--color-text-muted); }   /* v7.30: 15px 직박음 → 토큰(16px — 1px 커짐) */
.nkey.confirm {
  font-size: 13px; color: var(--color-primary);
  background: linear-gradient(180deg, #1aaa6e 0%, #1a5c2e 100%);
}

/* ── 인증 모달·회원 선택·신뢰 기기 (design-system §11-26 / 쿡북 §V) ── */
.verify-modal {
  position: fixed; inset: 0; z-index: 210; display: none;
  align-items: center; justify-content: center; padding: 16px;
  background: rgba(0,0,0,0.75);
}
.verify-modal.visible { display: flex; }
.verify-modal[hidden] { display: none; }
.verify-modal-box {
  width: 100%; max-width: 360px; max-height: 90dvh; overflow-y: auto;
  display: flex; flex-direction: column; gap: 14px; padding: 20px 18px 18px;
  background: linear-gradient(180deg,var(--color-surface) 0%,var(--color-bg) 100%);
  border-top: 1.5px solid rgba(74,222,128,0.6);
  border-right: 1px solid rgba(74,222,128,0.25);
  border-bottom: 3px solid rgba(0,0,0,0.7);
  border-left: 1px solid rgba(74,222,128,0.25);
  border-radius: var(--radius-lg); box-shadow: 0 12px 32px rgba(0,0,0,0.8);
}
.verify-title { font-size: 15px; font-weight: 700; color: var(--color-text); text-align: center; line-height: 1.4; }
.verify-sub { margin-top: -8px; white-space: pre-line; font-size: var(--text-xs); color: var(--color-text-muted); text-align: center; line-height: 1.4; }
.verify-field { display: flex; flex-direction: column; gap: 5px; }
.verify-label { font-size: var(--text-xs); color: var(--color-text-muted); font-weight: 500; }
.verify-input {
  width: 100%; padding: 10px 12px; background: rgba(0,0,0,0.3);
  border: 1px solid rgba(74,222,128,0.3); border-radius: var(--radius-md);
  color: var(--color-text); font-size: var(--text-sm); font-family: var(--font-base);
}
.verify-input:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 2px rgba(74,222,128,0.25); }
.verify-msg { min-height: 14px; font-size: var(--text-xs); line-height: 1.3; text-align: center; }
.verify-msg.error { color: var(--color-error); }
.verify-msg.info { color: var(--color-text-muted); }
.verify-msg.ok { color: var(--color-primary); }
.verify-btn-row { display: flex; gap: 8px; margin-top: 4px; }

.member-choice-list { display: flex; flex-direction: column; gap: 8px; }
.member-choice-btn { text-align: left; line-height: 1.4; }
.member-choice-btn strong,
.member-choice-btn span {
  display: block; font: inherit; color: inherit;
}
.member-choice-btn span { margin-top: 2px; }

.device-stage { display: none; flex-direction: column; gap: 12px; }
.device-stage.visible { display: flex; }
.device-code { padding: 14px; text-align: center; background: rgba(0,0,0,0.28); border: 1px solid rgba(74,222,128,0.3); border-radius: var(--radius-md); }
.device-code-label, .device-help { color: var(--color-text-muted); font-size: var(--text-xs); }
.device-help { line-height: 1.6; text-align: center; }
.device-code-value { margin-top: 4px; color: var(--color-primary); font-size: var(--text-2xl); font-weight: 800; letter-spacing: 0.08em; font-feature-settings: "tnum"; }
.device-number-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 8px; }
.device-number-btn {
  min-height: 44px; cursor: pointer; border: 1px solid rgba(74,222,128,0.3);
  border-radius: var(--radius-md); background: linear-gradient(180deg,rgba(74,222,128,0.15),rgba(74,222,128,0.07));
  color: var(--color-text); font-family: var(--font-base); font-size: var(--text-lg); font-weight: 700;
  font-feature-settings: "tnum";
}
.device-number-btn:active { transform: translateY(1px); }

/* ── 점수판 전용 (기본 방향: 휴대폰 세로 / 태블릿 가로 — design-system §8 v7.21) ── */
/* ⚠️ 본 두 클래스는 점수판 화면 전용. 다른 화면에서 .score-display·.win-rate-display 사용 금지.
   점수 숫자 색은 녹색 계열이 기본 (v7.20). 금색이 필요하면 기획자 특별 지시 시에만 변경. */
.score-display {
  font-size: clamp(48px,10vw,96px); font-weight: 800;
  font-feature-settings: "tnum"; color: var(--color-primary);
  text-shadow: var(--glow-primary);
  line-height: 1; letter-spacing: -0.02em;
}
.win-rate-display {
  font-size: clamp(20px,4vw,36px); font-weight: 700;
  font-feature-settings: "tnum"; color: var(--color-primary);
  text-shadow: var(--glow-primary);
}

/* ═════════════════════════════════════════════════════════════════════
   충전금 원장 표시 (v7.38 신설) — 조립법·마크업·JS 계약은 쿡북 §Y
   ----------------------------------------------------------------------------------
   쓰는 화면: 214(회원)·508(당구장)·311(대회 개최자) + 4xx(할인가맹점)·6xx(영업조직) 예정
   ⚠ **주체마다 표(DB)는 다르지만 화면은 같다**(F-47 — `balance_transactions`·`jang_charge_transactions` …).
     그래서 값을 여기 한 곳에만 둔다. 화면마다 복사본을 품으면 한 곳을 고쳐도 나머지가 조용히 낡는다.
   ⚠ **`.chg-*`는 `.band-*`(§T 라벨띠)와 다른 물건이다** — `.numpad-panel`과 같은 함정.
     §T = 2칸(라벨 `flex:1` + 값 고정폭 96px) / 여기 = 4칸(라벨 고정 64px + 값 + 평균 + 건수).
     214가 이 충돌을 피하려고 `.chg-*`로 분리한 것이 올바르다(214 prototype_20).
   ⚠ 그래프 CSS는 여기 적지 않는다 — 범례·축 표준은 **billiards-ui §6**가 정본이다.
   ═════════════════════════════════════════════════════════════════════ */

/* ── 당월 입출금 표 — 5행만 보이고 나머지는 안쪽 스크롤 ──
   ⚠ **`overscroll-behavior`를 걸지 않는다**(기획자 지적 2026-07-25) — 걸면 표 끝에 닿아도
     스크롤이 페이지로 넘어가지 않아, **표 위에 손가락이 있으면 화면이 내려가지 않는다.**
     빼도 표 안쪽 스크롤은 그대로 동작한다. (모달의 `overscroll-behavior:contain`은 정당 — 뒷장이 밀리면 안 된다.) */
.flow-scroll {
  max-height: 245px; overflow-y: auto; border-radius: var(--radius-md);
  -webkit-overflow-scrolling: touch; touch-action: pan-y;
}
.flow-input-wrap { margin-top: 8px; }

/* 열 너비 — ⚠ **고정하지 않으면 내용이 열 폭을 정한다.**
   금액 열을 하나로 합치고(입출 구분 1글자 + 입출금 1열) 남는 폭을 전부 사유에 준다.
   ⚠ **%가 아니라 px로 고정한다** — %는 320px에서 반올림 1~2px이 모자라 그대로 접힌다(508 실측).
   실측 근거(13px tnum · 숫자 0.55em · 콤마 0.28em · 한글 1em):
     날짜 46('07.09' 41px) · 입출 28(1글자) · 입출금 66('9,999,999' 백만) · 잔액 66
   ⚠ **사유 열(.th-detail)에는 width를 주지 않는다** — 남는 폭을 혼자 가져가게 하려는 것이다(지우지 말 것).
   ⚠ **잔액 상한과 사유 폭은 맞바꾸는 관계다** — 상한을 바꿀 때는 사유 폭을 다시 계산할 것. */
.charge-table { table-layout: fixed; }
.charge-table th, .charge-table td { padding: 9px 2px; text-align: center; font-size: var(--text-xs); }
.charge-table .th-date { width: 46px; }
.charge-table .th-io   { width: 28px; }
.charge-table .th-amt  { width: 66px; }
.charge-table .th-bal  { width: 66px; }
.charge-table td.td-detail, .charge-table th.th-detail { text-align: left; padding-left: 6px; overflow-wrap: anywhere; }
.charge-table td.td-num { text-align: right; padding-right: 6px; font-feature-settings: "tnum"; }
/* ⚠ 날짜·구분만 접지 않는다. **숫자 칸에는 nowrap을 걸지 않는다** — 폭이 이미 한 줄을 보장하므로
   정상 범위에서는 접힐 일이 없는데, nowrap을 걸어두면 **상한을 넘는 순간 칸을 뚫거나 잘린다.**
   빼두면 두 줄로 접힐 뿐 숫자는 다 보인다 — 잘리는 것보다 낫다. */
.charge-table td.td-date, .charge-table td.td-io { white-space: nowrap; }
/* 입/출 구분 — '출'에만 볼드. 금액이 한 칸이라 이 글자가 유일한 구분 표시다.
   ⚠ 700이 아니라 800이다 — 13px 한 글자에서는 400과 700의 차이가 눈에 안 보인다(508 실측). */
.charge-table td.td-io { font-weight: 400; }
.charge-table td.td-io.out { font-weight: 800; }
.charge-table td.td-bal { color: var(--color-primary); }
/* 전월 이월 행 — 당월 표의 시작점. 데이터 행이 아니라 '이어받은 값'이라 흐리게.
   ⚠ 이 줄이 없으면 당월 표의 **잔액 첫 값이 어디서 왔는지 설명이 안 된다.** */
.charge-table tr.carry-row { border-top: 1px solid rgba(74,222,128,0.25); }
.charge-table tr.carry-row td { color: var(--color-text-muted); }
/* 머리 고정 — 스크롤해도 잔액 칸을 잃지 않게(th에 배경 재부여) */
.charge-table thead th { position: sticky; top: 0; z-index: 1; background-color: var(--color-surface2); }
.empty-cell { color: var(--color-text-muted); padding: 18px 8px !important; font-size: var(--text-xs); text-align: center; }

/* ── 입금·출금 토글 ──
   고른 것을 표시하는 자리라 `.active`가 정당하다(§11-5 v7.35 "색은 둘뿐: 기본 / 클릭(선택)"). */
.io-toggle { display: flex; gap: 8px; margin-bottom: 10px; }
.io-toggle .btn-primary { flex: 1; }

/* ── 현황 행 — 라벨띠 + 금액 + 평균 + 건수 (4칸) ──
   ⚠ **`.band-*`가 아니다** — 위 머리말 참조. §T는 2칸이라 이 구조를 담지 못한다.
   ⚠ `.chg-row`에 **테두리를 두르지 않는다** — 상·하 1px씩이 더해져 띠 높이가 버튼과 2px 어긋난다(214 실측).
     모서리는 `overflow:hidden`으로 처리한다. */
.chg-row { display: flex; align-items: stretch; border-radius: var(--radius-md); overflow: hidden; margin-bottom: 8px; }
/* ⚠ `text-align` 필수 — `<button>`은 브라우저 기본이 center인데 `<div>`는 left다.
   당일 라벨만 `<div>`(안 눌림 · §T 원칙 3)라, 이 줄이 없으면 **당일만 왼쪽으로 치우친다.** */
.chg-label { flex: 0 0 64px; border-radius: 0; padding-left: 4px; padding-right: 4px; text-align: center; }
.chg-value {
  flex: 1 1 0; min-width: 0;
  display: flex; align-items: center; justify-content: flex-end;
  background: var(--color-surface); padding: 0 8px;
  font-size: var(--text-base); font-weight: 400; color: var(--color-primary);
  font-feature-settings: "tnum";
}
.chg-avg {
  flex: 0 0 92px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: var(--color-surface2); padding: 4px; gap: 2px;
}
.chg-avg .avg-name { font-size: var(--text-xs); color: var(--color-text-muted); font-weight: 600; text-align: center; line-height: 1.35; }
.chg-avg .avg-val  { font-size: var(--text-xs); color: var(--color-text); font-weight: 700; font-feature-settings: "tnum"; }
.chg-avg.avg-head .avg-name { color: var(--color-text); font-weight: 700; font-size: var(--text-sm); }
/* 건수 열 — 평균 오른쪽. 배경만 surface로 번갈아 칸이 구분되게 한다. */
.chg-count {
  flex: 0 0 52px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  background: var(--color-surface); padding: 4px; gap: 2px;
}
.chg-count .count-name { font-size: var(--text-xs); color: var(--color-text-muted); font-weight: 600; text-align: center; line-height: 1.35; }
.chg-count .count-val  { font-size: var(--text-xs); color: var(--color-text); font-weight: 700; font-feature-settings: "tnum"; }
.chg-count.count-head .count-name { color: var(--color-text); font-weight: 700; font-size: var(--text-sm); }

/* ── 상세 리스트 모달의 표(일별·월별·년도별 공용) ──
   ⚠ **모달을 두 벌 만들지 않는다** — 입금·출금은 모양이 같고 데이터만 다르다. */
.charge-list-table th, .charge-list-table td { padding: 8px 4px; text-align: center; font-size: var(--text-sm); }
.charge-list-table td.td-num { text-align: right; padding-right: 8px; font-feature-settings: "tnum"; }
.charge-list-table td.td-cum { color: var(--color-text-muted); }
.charge-list-table tr.list-today td { color: var(--color-primary); font-weight: 700; }
.list-sum { margin-top: 10px; text-align: right; font-size: var(--text-sm); color: var(--color-text); font-weight: 600; }
.list-sum b { color: var(--color-primary); font-weight: 800; font-feature-settings: "tnum"; }
.list-note { margin-top: 8px; font-size: var(--text-xs); color: var(--color-text-muted); line-height: 1.6; }

/* ── 시간·날짜 선택칸 (.time-select) — 정본 (v7.48 · 2026-08-31 신설) ─────────────
   기획자 지시: *"이걸 시간입력을 사용하는 모든곳에 적용해줘"* (511 업종 버튼과 모양 통일)
   ⚠⚠ **종전에는 정본이 없었다** — 9화면이 각자 인라인 복사본을 들었고 **이미 6가지로 갈려 있었다.**
      (글자 크기·글자색·padding·transition이 화면마다 달랐다.) 그래서 여기에 만든다.
   ⭐ 모양은 정본 `.btn-inline`(+`.lg`) 계열을 따른다 — 여기서 색을 새로 만들지 않는다.
   ⚠ 글자는 `--text-xs`다 — 월·일·시·분 **네 칸이 한 줄**에 들어가야 한다(§3 최소 글자 13px 하한).
   ⚠ `<select>`를 버튼으로 바꾸지 않는다 — 시(時)가 24개라 펼치면 화면이 그것만으로 찬다.
   ⚠ **프로토타입은 스냅샷이라 이 값이 자동 전파되지 않는다** — 화면마다 인라인 복사본을 갖고 있다.
      본코딩(Rails)에서 전역 CSS 한 곳이 되면 그때 복사본이 사라진다. */
.time-row  { display:flex; align-items:center; gap:6px; }
.time-sep  { color:var(--color-text-muted); font-size:var(--text-base); font-weight:700; flex-shrink:0; }
/* ⚠ 자리 기준 변형(기획자 확인 2026-09-05 «들어갈 장소에 맞춰라 — 여유가 있으면 큰 쪽»):
   «라벨 열 + 네 칸»이 한 줄에 드는 답장·요청 화면(208-1·208-2·209-1·209-2·210-2·206 모달)은 375px에서 위 값이 21px 넘친다(실측 2026-09-05).
   그 화면들은 목업이 정한 **gap 3px · 글자 --text-xs** 를 화면 CSS에 둔다. 라벨 없이 한 줄을 다 쓰는 자리만 이 정본 값을 그대로 쓴다. */
.time-select {
  flex:1; min-width:0; min-height:44px; padding:6px 8px;
  font-family:var(--font-base); font-size:var(--text-xs); font-weight:700;
  text-align:center; cursor:pointer;
  -webkit-appearance:none; appearance:none;
  background:linear-gradient(180deg, rgba(74,222,128,0.15) 0%, rgba(74,222,128,0.07) 100%);
  border:1px solid rgba(74,222,128,0.3); border-radius:var(--radius-sm);
  color:var(--color-text-muted);
  transition:all 0.15s;
  -webkit-tap-highlight-color:transparent;
}
.time-select:hover {
  background:linear-gradient(180deg, rgba(74,222,128,0.25) 0%, rgba(74,222,128,0.12) 100%);
  border-color:rgba(74,222,128,0.55); color:var(--color-primary); transform:translateY(-1px);
}
.time-select:active { transform:translateY(1px); }
.time-select:focus  { outline:none; box-shadow:0 0 0 2px rgba(74,222,128,0.4); }
/* 고른 상태 — 511 업종 버튼의 aria-pressed="true"와 같은 값. JS가 켜고 끈다. */
.time-select.chosen { background:var(--color-primary); color:var(--color-bg); font-weight:700; }
/* ⚠⚠ `.selected`를 `.chosen`과 **같은 값으로 합치지 않는다.**
   208-1·208-2·210은 `.selected`를 마크업에 **고정**으로 달아 **모든 칸에 늘 켜져 있다** —
   합치면 그 세 화면의 시간칸이 **통째로 초록 블록**이 된다(고른 것이 하나도 없는데도).
   ⇒ `.selected`는 **구 거동 그대로 글자색만** 바꾼다. 「고름」은 `.chosen`뿐이다. */
.time-select.selected { color:var(--color-primary); }
.time-select option { background:var(--color-bg); color:var(--color-text); font-weight:400; }

/* ── 알림 허용 문맥 안내 (.nb-push-optin) — 정본 (2026-09-09 신설) ────────────────
   기획자 확정 2026-09-09: 푸시는 앱 밖에서 받는 것이라 첫화면 본문에서 상시로 조를 이유가 없다.
   알림이 필요해지는 순간(208 요청 열람 · 210 요청 발송 직후)에만 한 줄로 묻는다.
   ⭐ 새 색·새 버튼 모양을 만들지 않는다 — 글자는 `.list-note`, 버튼은 `.btn-inline` 정본 그대로다.
      여기서 정하는 것은 «두 개를 한 줄에 놓는 배치»뿐이다.
   ⚠ 205·505의 상시 「알림 받기」 버튼을 대신한다. 그 버튼은 목업에 없이 T2-w에서 들어왔던 것이다. */
.nb-push-optin {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap;
  margin-top: 8px; padding: 10px 12px;
  background: var(--color-surface);
  border: 1px solid rgba(74, 222, 128, 0.2);
  border-radius: var(--radius-md);
}
.nb-push-optin .list-note { margin-top: 0; flex: 1 1 200px; }
.nb-push-optin-actions { display: flex; gap: 8px; flex-shrink: 0; }
