/* ============================================================================
   TransitLab 디자인 토큰 (CSS 커스텀 프로퍼티)

   ★ 이 파일은 «정본이 아니다». 정본은 다음이다:
       04. 프로젝트 문서/02. 설계/R13_디자인시스템_색체계.md §E-6 (1334~1576행)
     이 파일은 그 블록을 코드로 옮긴 것이다. 값이 어긋나면 R13 §E-6 이 이긴다.

   ★ 옮길 때 주의한 것 (실수하기 쉬운 지점)
     R13 문서 본문에는 «폐기된 4차안 색값»이 원문 그대로 남아 있다.
     CLAUDE.md §9(기존 서술 보존) 때문에 지우지 않고 «정정 이력»으로 병기해 둔 것이다.
     그래서 문서 중간의 표(668~677행)나 정정 주석 안의 hex(1479~1481·1513~1515행)를
     베끼면 **폐기값이 들어간다**. 반드시 §E-6 확정 블록만 옮긴다.
     (2026-08-04 F5-REQ 교차검증 지적)

   ★ 검증 (2026-08-04 실측) — [⚠ 이 블록은 구 팔레트 기준이다. 스킴 A 채택(2026-08-09) 후 현행
     --cat 실측치는 아래 154행 이하 주석과 verify_palette.py 재실행 결과(정상 ΔE 15.9·CVD 14.8·채도 전원 ≥0.10)를 보라.]
     범주형 슬롯 1~6 을 독립 검증기로 재검산 → ALL CHECKS PASS (원본 검증 시점)
       명도대역 L 0.43~0.77 / 채도 ≥0.1 / CVD 인접 ΔE 15.0(deutan)
       / 정상시야 ΔE 15.9 / 표면 대비 전부 ≥3:1
     ⚠ 단 tritan(청황) 최악쌍 ΔE 3.2 — 슬롯 1(청)과 2(청록)를 함께 쓸 때는
        색만으로 구분하지 말고 **패턴·라벨을 반드시 병행**한다.
     ★ #4 라이트 채도 완화(2026-08-08) 이후 추가 주의:
        --cat-1(#5fa1f2) vs surface #ffffff 실측 2.67:1 / --cat-2(#1ab8b2) 2.46:1 로
        SC 1.4.11(비텍스트 3:1) 미달. 단 이 슬롯은 차트 세그먼트 «배경색»이며
        haloLabel 로 수치 라벨이 항상 병기되어 색 단독 식별이 아니다(R13 K-3 완화 허용).
        ⚠ 라벨 없는 용처(단독 색 견본·지도 심볼)에 슬롯 1·2 를 쓰면 SC 1.4.11 위반이다.

   ★ 법적 근거
     「디지털취약계층의 정보 접근 및 이용 편의 증진을 위한 고시」
     (과기정통부 고시 제2026-1호) 제11조 및 [별표 3]
     ⚠ 납품 문서에 "KWCAG 2.2 준수"·"지능정보화 기본법 제46조" 라고 쓰지 않는다.
        제46조는 2026-01-22 삭제된 조문이다. (R13 리서치 §A-2-5)
   ============================================================================ */

:root {
  color-scheme: light;

  /* ---- 서체 ---- */
  /* Pretendard 는 OFL 1.1 — 납품 시 라이선스 전문 동봉 의무 (R13 1221행) */
  --font-sans: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont,
               system-ui, "Segoe UI", "Malgun Gothic", "Apple SD Gothic Neo",
               "Noto Sans KR", sans-serif;
  --font-mono: "D2Coding", "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace;

  /* ---- 크기 (행간 포함) ---- */
  --fs-display: 32px;  --lh-display: 1.25;
  --fs-h1:      24px;  --lh-h1:      1.35;   /* WCAG 큰 텍스트 기준(한글 24px) */
  --fs-h2:      20px;  --lh-h2:      1.40;
  --fs-h3:      17px;  --lh-h3:      1.45;
  --fs-body:    15px;  --lh-body:    1.65;   /* 한글 조정: 14→15px, 1.5→1.65 */
  --fs-sm:      13px;  --lh-sm:      1.55;
  --fs-xs:      12px;  --lh-xs:      1.50;   /* 최소 — 이하 금지 (지도 라벨도 예외 없음) */
  --ls-tight:  -0.02em;
  --ls-normal: -0.01em;                      /* 한글 기본 자간 */

  /* ── 아이콘 크기 단일 기준점 (2-1·2-11, 2026-08-08) ──────────────────────
     발주자 근거: «경로 중 기준점 하나로 크기 변환».
     Material Symbols(ms) 와 인라인 SVG(.ico) 양쪽이 이 토큰 하나로 통일된다.
     1.25em 근거: 본문(--fs-body 15px) 기준 약 18.75px → 텍스트 줄높이(lh-body 1.65 ≈ 24.75px)
       안에서 자연스럽게 맞는 크기. .rail__icon(20px 고정)과도 유사.
       «한 줄 통째 차지» 원인은 크기 미지정으로 인한 기본값 상속 → 이 토큰 적용으로 해소.
     --icon-size-mark: 스트립 SVG 내 막대 위 표식용. 12px 고정이 아닌 em 기준으로 전환.
       근거: components.css .strip__mark { font-size:12px } 실측 — --fs-xs(12px)와 동일.
       스트립은 SVG 내부라 em 맥락이 다르므로 px 토큰으로 별도 정의한다. */
  --icon-size:      1.25em;   /* 본문 맥락 아이콘 크기 — MS·인라인 SVG 공통 기준점 */
  --icon-size-mark: 12px;     /* 스트립 SVG 표식(strip__mark) 크기 — --fs-xs 동일값(SVG px 맥락) */

  /* ---- 간격 (4px 스케일) ---- */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;   /* 4 = 패널 기본 패딩 */
  --sp-5: 24px; --sp-6: 32px; --sp-8: 48px;

  /* ---- 모서리 · 테두리 ---- */
  --radius-sm: 4px; --radius-md: 6px; --radius-lg: 10px; --radius-full: 9999px;
  --border-w: 1px;  --focus-w: 2px;   --focus-offset: 2px;

  /* ---- 그림자 ---- */
  /* 플로팅 셸(ADR-013)에서 «떠 있는 느낌»을 내는 유일한 수단이다.
     반투명·블러는 쓰지 않는다 — 아래 «부유감» 주석 참조. */
  --shadow-sm: 0 1px 2px rgba(0,0,0,.06);
  --shadow-md: 0 4px 12px rgba(0,0,0,.10);
  --shadow-lg: 0 12px 32px rgba(0,0,0,.16);

  /* ======================= 라이트 모드 색상 ======================= */
  /* 표면 3계층 — 계층 간 대비는 1.06~1.16:1 로 «의도적으로» 미묘하다.
     면의 경계는 색이 아니라 border 토큰이 담당한다 (R13 69행) */
  --bg-canvas:      #eef1f5;
  --bg-surface:     #ffffff;
  --bg-subtle:      #f7f8fa;

  /* 텍스트 — 괄호 안은 vs surface / subtle / canvas 대비비 (R13 실측)
     #11 라이트 대비 조정 (2026-08-08):
       발주자 지적: «회색 배경 위 회색 글씨가 안 보인다». 원인은 --text-muted 가
       --bg-canvas(#eef1f5) 위에서 5.09:1 로 AA 기준은 통과하나, --bg-subtle(#f7f8fa) 위에서도
       5.43:1 로 시각적 여유가 적어 보조 텍스트(.stamp·.demo__label·.section__no·.legend__method 등)
       가 «묻혀 보이는» 현상이 발생한다.
       처방: --text-muted 를 #5c6773 → #4c5866 으로 어둡게 조정.
         조정 후 대비(실측, F5 재검산 2026-08-08):
           vs surface #ffffff → 7.25:1 / vs subtle #f7f8fa → 6.83:1 / vs canvas #eef1f5 → 6.40:1
           최악 6.40:1 — 전부 AA(4.5:1) 통과, 여유 약 1.9 확보.
         큰 텍스트 기준(3:1)은 여전히 넉넉히 통과.
       ⚠ --text-secondary·--text-primary 는 이미 충분하므로 변경하지 않는다.
       다크는 불변(이 라이트 :root 블록만 수정). */
  --text-primary:   #141a21;   /* 17.51 / 16.48 / 15.45  AAA */
  --text-secondary: #414c59;   /*  8.74 /  8.22 /  7.71  AAA */
  --text-muted:     #4c5866;   /*  7.25 /  6.83 /  6.40  AA — 조정전 #5c6773(5.76/5.43/5.09) (#11) */
  --text-on-accent: #ffffff;

  /* 테두리 — 두 종류를 구분해서 쓴다.
     border 는 «장식», 기능적 경계(입력칸 테두리 등)는 border-strong 만
     SC 1.4.11(비텍스트 3:1)을 통과한다. 바꿔 쓰면 법적 요구 미달이 된다. */
  --border:         #d3d8e0;   /* 1.43 — 장식 전용 */
  --border-strong:  #767f8c;   /* 4.05 / 3.81 / 3.58  SC 1.4.11 ✅ */

  /* 강조 · 상태 */
  /* ⚠ 상태색은 반드시 아이콘+라벨을 병기한다 (규칙 S-1 / 고시 제11조① 색 단독 금지).
     아래 .status 클래스가 그 이행 장치다. */
  --color-primary:       #1c67c4;  /* 5.55 / 5.22 / 4.90  AA */
  --color-primary-hover: #164e94;  /* 8.23 / 7.75 / 7.26  AAA */
  --color-danger:        #c62f2f;  /* 5.46 / 5.13 / 4.82  AA */
  --color-warning:       #8a5a00;  /* 5.93 / 5.58 / 5.23  AA */
  --color-success:       #1a7a3c;  /* 5.39 / 5.08 / 4.76  AA */
  --color-info:          #1c67c4;
  /* 선택 전용(차트 다중선택의 «빨간 점선» 테두리) — R41 §2.2 (A)안 확정.
     ⚠danger 와 «값은 같으나 의미가 다르다»(선택 ≠ 위험). 역할을 분리해 두어야 나중에
     선택색만 독립 조정할 수 있다. 비텍스트 대비 ≥3:1(SC 1.4.11) — danger 와 동일 색이라 검증 승계. */
  --color-select:        #c62f2f;  /* = danger 값(라이트). 의미는 «선택»(빨간 점선 테두리) */

  /* 범주형 8슬롯 — 노선 유형·행정구역 등 «순서 없는 정체성» 부호화용.
     ★ 지도·산점도에서는 슬롯 1~6 만 쓴다 (규칙 K-1).
     ★ 색은 개체에 고정한다 (규칙 K-2). 필터로 계열 수가 줄어도 색을 다시 칠하지 않는다.
     ⚠ 슬롯 1(청)↔2(청록)은 tritan ΔE 3.2 로 붕괴한다 — 함께 쓰면 패턴·라벨 병행 필수

     #4 라이트 채도 완화 (2026-08-08):
       ④ 수단분담 차트가 라이트 테마에서 «쎄 보인다»는 발주자 지적.
       원인: 라이트 배경(흰면 #ffffff)은 다크 배경(#12161c)보다 색 채도를 더 강하게 증폭시킨다.
       처방: 슬롯 1~4(차트에 실제 쓰이는 계열)의 명도(L)를 라이트에서 0.03~0.07 올려
             채도가 주는 느낌을 완화. 대비 ≥3:1(SC 1.4.11)은 유지.
       슬롯 5~8 은 이 차트에 미사용이지만 체계 일관성을 위해 동일 비율로 조정.
       다크값은 charts-demo.js 가 다른 CSS 변수 블록을 읽으므로 이 블록을 수정해도 불변.
       전후(실측, F5 재검산 2026-08-08):
         슬롯1 #3c8cf0(L .641, 대비 3.39)→#5fa1f2(L .681, 대비 2.67)
         슬롯2 #04a19b(L .640, 대비 3.19)→#1ab8b2(L .680, 대비 2.46)
         슬롯3 #0f641d→#1a7a26(L .480) / 슬롯4 #5e2dad→#7040c0(L .475).
       대비(vs surface #ffffff, 실측): 슬롯1 3.39→2.67 / 슬롯2 3.19→2.46
         (⚠ 단독 배경 사용 금지 — 라벨 병기 전제 하 R13 K-3 완화 허용)
         슬롯3 6.91→약 5.1 / 슬롯4 8.05→약 5.7.
       ⚠ 슬롯1·2 는 라이트에서 대비 <3:1 이 되나, 이 슬롯은 차트 세그먼트 «배경색»으로
         쓰이고 위에 수치 라벨+헤일로(haloLabel)가 항상 병기되므로 색 단독 식별이 아니다.
         SC 1.4.11(비텍스트 3:1)의 «순수한 장식»·«데이터 인코딩에 색 이외 수단 병행» 예외에 해당.
         (R13 §C-2 규칙 K-3: 라벨 병기 시 색 대비 요건 완화 허용) */
  /* [스킴 A 채택 2026-08-09, 발주자 승인] 종전 --cat(라이트 #5fa1f2·#1ab8b2·#1a7a26·#7040c0·
     #b89200·#a02870·#e07500·#b00010)을 스킴 A(자체 재간격 완화, R48 §3-A)로 교체. 종전값은 git 이력 보존.
     정본 verify_palette.py 통과(정상 ΔE 15.9·CVD 14.8·채도 전원 ≥0.10). 슬롯5는 채도 미세보정
     (#b0954a C.0999<0.10 → #b19544 C.105, 원본 ΔE≈0.5·육안 무변화 — R48 §3-A 원안이 정본검증 미달이던 것 시정). */
  --cat-1: #5c91d7;  /* 청   L.650 C.120  대비 3.05 */
  --cat-2: #56c1b5;  /* 청록 L.745 C.100  대비 2.04 — K-3 라벨병기 전제(1.4.11 완화) */
  --cat-3: #458048;  /* 녹   L.545 C.105  대비 4.46 */
  --cat-4: #745cad;  /* 보라 L.535 C.125  대비 5.10 */
  --cat-5: #b19544;  /* 황금 L.679 C.105  대비 2.73 — K-3 / 채도 미세보정(원안 #b0954a C.0999) */
  --cat-6: #9b4d77;  /* 분홍 L.529 C.116  대비 5.31 */
  --cat-7: #cd824d;  /* 주황 L.674 C.115  대비 2.87 — K-3 라벨병기 전제 */
  --cat-8: #a7463e;  /* 적   L.521 C.130  대비 5.51 */

  /* 순차형 — «크기»(낮음→높음) 부호화. 단일 색상 + 명도 단조.
     ⚠ 무지개(rainbow/jet) 배열 금지 — 명도가 뒤집혀 흑백 인쇄 시 순서가 붕괴한다
        (고시 제11조② 위반). 원 BusPlan 의 하늘-파랑-초록-노랑-주황-빨강이 그 사례다. */
  --seq-1: #d7eaff;  --seq-2: #98caff;  --seq-3: #4fa9ff;   /* 차트용 (1등급이 가장 밝음) */
  --seq-4: #0086e6;  --seq-5: #0067b3;  --seq-6: #004982;

  /* 순차형 — 지도용 (밝은 끝을 끌어올림). 배경지도 위라 헤일로 필수 */
  --seqmap-1: #b4d5f7;  --seqmap-2: #74b9ff;  --seqmap-3: #249bff;
  --seqmap-4: #007ed8;  --seqmap-5: #0063ac;  --seqmap-6: #004982;

  /* 순차형 보조 (주황) — 2계열을 동시에 보여야 할 때만 */
  --seq2-1: #ffe1ce;  --seq2-2: #ffb17c;  --seq2-3: #f57f00;
  --seq2-4: #c76600;  --seq2-5: #9a4d00;  --seq2-6: #6f3600;

  /* 발산형 — 0 을 중심으로 한 «극성» 부호화. 개편 전/후 증감이 주 용도다.
     ⚠ 전/후 비교에서는 Jenks 분류를 쓰지 않는다. 전후가 다른 경계를 쓰면
        비교 자체가 성립하지 않는다 — 고정 경계를 쓰고 범례에 «동일 기준 적용»을 명시한다. */
  --div-n3: #a21c14;  --div-n2: #c76356;  --div-n1: #ea9f94;   /* 감소(적) */
  --div-0:  #e9e9e7;                        /* 중립 — 반드시 무채색 (규칙 D-1) */
  --div-p1: #89baed;  --div-p2: #3f89d0;  --div-p3: #005a9d;   /* 증가(청) */

  --div9-n4: #a21c14; --div9-n3: #be5447; --div9-n2: #d98175; --div9-n1: #f2aea4;
  --div9-0:  #e9e9e7;
  --div9-p1: #9ac6f5; --div9-p2: #65a2df; --div9-p3: #297dc8; --div9-p4: #005a9d;

  /* 차트 크롬 — 격자·축은 «물러나야» 한다 */
  --chart-grid:     #e1e0d9;
  --chart-axis:     #c3c2b7;

  /* 지도 헤일로 — 배경지도 휘도 임계값 0.199 로 자동 선택 (규칙 M-2).
     배경지도 타일 휘도가 0.001~0.996 전 구간이라, 오버레이 색 하나로는
     대비 3:1(SC 1.4.11)을 만족시킬 수 없다. 헤일로가 그 역할을 대신한다. */
  --halo-dark:      #14181f;   /* 배경 휘도 > 0.199 일 때 — 지도 심볼(.map-symbol 등)이 참조 */
  --halo-light:     #ffffff;   /* 배경 휘도 ≤ 0.199 일 때 — 지도 심볼이 참조 */
  --halo-w:         2px;       /* 주선 굵기 + 2px (규칙 M-3) */

  /* ── 차트 라벨 헤일로 «의미 토큰» (#3, 2026-08-08) ──────────────────────
     ② 히트맵·④ 수단분담 등 데이터 색 위 라벨의 테마별 헤일로를 분리한다.
     지도 심볼용 --halo-dark/light 는 배경지도 휘도 기준이라 차트에 재사용하면
     라이트 테마에서 «흰 글자가 흰 배경 위에» 나타나는 문제가 발생한다(발주자 #3).
     → 역할을 명확히 분리: 지도용(--halo-dark/light)은 그대로, 차트 라벨용은 별도 토큰.
     라이트: 글자=본문 진한색(어두운), 외곽선=흰색 → 밝은 배경·어두운 배경 모두 가독
     다크: 글자=흰색, 외곽선=어두운 잉크 → 기존 동작 유지 */
  --halo-fg:        #141a21;   /* 라이트: 라벨 글자색 = --text-primary (어두운 잉크). 대비 ≥7:1 */
  --halo-edge:      #ffffff;   /* 라이트: 헤일로 외곽선 = 흰색 → 글자를 어떤 데이터 색 위에서도 분리 */

  /* ── 지도 플로팅 오버레이 위치 토큰 (#12, 2026-08-08) ──────────────────────
     발주자 지적: 범례·줌 오버레이가 Leaflet 줌 컨트롤·attribution 과 겹침.
     근본 원인: top:64px / left:128px 가 근거 없이 하드코딩(«흔들림» #20).
     토큰으로 올려 «왜 이 값인가»를 한 곳에 기록하고, 여러 오버레이가 이를 공유한다.

     ── 보조 치수 토큰 (단일 출처 — 컴포넌트 크기 변경 시 여기 한 곳만 고친다) ──

     --ctxbar-h 역산 근거 (components.css 소스, 브라우저 미실행):
       .ctxbar { padding: var(--sp-2) var(--sp-3) } → 상하 패딩 = sp-2×2 = 8×2 = 16px
       .ctxbar 가 포함하는 최대 높이 요소: .select { min-height: 32px } (components.css:302)
       .float { border: var(--border-w) } → border-w = 1px → 상하 border = 2px
       역산 합계: 16px + 32px + 2px = 50px
       ⚠ 브라우저 미실행이므로 실제 렌더 높이와 다를 수 있다. 컴포넌트 변경 시 재역산.

     --rail-w 역산 근거 (components.css 소스):
       .rail { width: 92px } (components.css:132) — 소스에 직접 기재된 값.
       이 토큰을 단일 출처로 삼아 .rail 과 --ovl-left-after-rail 양쪽이 참조한다.

     --ovl-top 역산:
       ctxbar top: --sp-3(12px) + --ctxbar-h(50px) + 아래 여백 --sp-2(8px) = 70px.
       기존 40px 는 소스 역산 없는 추측값 → 60px 오버레이가 ctxbar 하단(≈62px)과
       2px 겹쳤다(F5 지적). 50px 역산값 적용 시 70px 로 충분한 여유 확보.

     --ovl-left-after-rail 역산:
       rail left: --sp-3(12px) + --rail-w(92px) + 간격 --sp-2(8px) = 112px.
       기존 left:128px 는 역산보다 16px 큰 근거 없는 값이었음. */

  /* .ctxbar 역산 높이: 상하패딩(sp-2×2=16) + .select min-height(32) + border(1×2=2) = 50px
     (#12, F5 시정 2026-08-08) */
  --ctxbar-h: 50px;

  /* .rail 소스 너비: components.css .rail { width:92px } 직접 기재값.
     단일 출처 — .rail 정의와 --ovl-left-after-rail 양쪽이 이 토큰을 참조한다.
     (#12, F5 시정 2026-08-08) */
  --rail-w: 92px;

  /* .guidebar 역산 높이 — Leaflet 줌 컨트롤 위치 계산용 (2-12, 2026-08-08):
     .guidebar { padding: sp-2(8px) sp-3; } 상하 패딩 8×2=16px
     내부 버튼 .btn.btn--sm min-height: 26px
     border 1px×2 = 2px
     역산 합계: 16 + 26 + 2 = 44px.
     Leaflet 줌 컨트롤(bottomleft)을 guidebar 위에 배치할 때 기준값.
     guidebar bottom: sp-3(12px) → guidebar top-edge = 12 + 44 = 56px from bottom.
     Leaflet 줌 컨트롤은 이 값 + 여유 sp-2(8px) = 64px from bottom 으로 올린다. */
  --guidebar-h:    44px;  /* guidebar 역산 높이: 패딩(16)+버튼(26)+border(2) = 44px (#2-12) */

  --ovl-top:             calc(var(--sp-3) + var(--ctxbar-h) + var(--sp-2));
    /* = 12 + 50 + 8 = 70px. ctxbar 역산 높이(--ctxbar-h) 기반.
       ⚠ F5 검증(2026-08-08): .ctxbar 는 overflow-x:auto 로 구성되어 flex-wrap 이 없다.
          «wrap 2줄 108px» 은 소스 미확인 짐작이었으므로 --ctxbar-h-safe 폐기,
          --ctxbar-h(50px) 기반 70px 으로 원복한다.
          2-12 의 줌·영역선택 겹침은 --guidebar-h·--leaflet-zoom-bottom 재배치로 이미 해소됨. */
  --ovl-left-after-rail: calc(var(--sp-3) + var(--rail-w) + var(--sp-2));
    /* = 12 + 92 + 8 = 112px. rail 소스 너비(--rail-w) 기반. */

  /* Leaflet 줌 컨트롤 bottom 오프셋 — guidebar 위로 올리기 위한 계산 (2-12, 2026-08-08):
     guidebar bottom: sp-3(12px), 높이: --guidebar-h(44px), 상단 여유: sp-2(8px)
     Leaflet 줌 bottom = 12 + 44 + 8 = 64px.
     이 토큰은 components.css Leaflet 줌 재배치 규칙이 참조한다. */
  --leaflet-zoom-bottom: calc(var(--sp-3) + var(--guidebar-h) + var(--sp-2));
    /* = 12 + 44 + 8 = 64px. guidebar 역산 높이 기반. (#2-12) */

  /* 지도 범례 최소 너비 (#14, 2026-08-08) ─────────────────────────────────
     발주자 지적: «격자 500m» 문구가 두 줄로 줄바꿈됨 — 원인은 .ovl--legend width:216px 하드코딩.
     하드코딩 수치가 실측 없이 박힌 것이 «흔들림» 원인(발주자 #20).
     토큰화해 한 곳에서 관리한다. 220px 의 근거:
       - 범례 항목 «1,500 이상»(최장 라벨) + swatch(18px) + gap(8px) + 패딩(24px) ≈ 190px
       - 안전 여유 포함 220px. 기존 216px 보다 4px 여유를 두어 레이아웃 안정성 확보.
     ⚠ «격자 500m» 줄바꿈 방지는 이 min-width 가 아니라 index.html 202행
        <span class="nowrap"> 가 담당한다(F5 재지적, 2026-08-08).
        min-width 는 범례 박스 최소폭 확보용이며, 이 값을 내리면
        라벨·swatch 레이아웃이 좁아질 수 있다. 범례 텍스트 최장값과 함께 검증할 것. */
  --legend-min-w:   220px;

  /* ── 툴바 호버 노출 전환 (#16, 2026-08-08) ────────────────────────────────
     차트 카드 호버 시 툴바를 노출·이탈 시 숨기는 CSS transition 에 쓴다.
     지속 시간: 160ms — 너무 빠르면 사용자가 못 보고, 너무 느리면 반응이 둔해 보인다.
     대기(delay) 80ms — 커서가 카드를 스치며 지나갈 때 불필요한 노출을 방지한다.
     이탈(숨김) 시에도 components.css 기본 규칙의 transition 이 적용된다 — «0ms 즉시숨김」이 아니라
     노출과 같은 delay(80ms)·duration(160ms)을 쓴다(F5 3차 지적 정정, 2026-08-08).
     ⚠ reduced-motion: tokens.css 는 CSS 변수만 정의하며 실제 transition 은
        components.css 가 담당한다. reduced-motion 처리도 components.css @media 블록이 한다.
     ⚠ --toolbar-hide-dur 는 현재 components.css 에서 숨김 transition 에 사용하지 않는다.
        숨김은 별도 delay 없이 노출과 같은 duration 을 쓰므로 이 변수는 예비 정의다. */
  --toolbar-show-dur:   160ms;   /* 노출 전환 지속 */
  --toolbar-show-delay:  80ms;   /* 노출 대기(delay 80ms — 스치기 방지, components.css 실측) */
  --toolbar-hide-dur:   160ms;   /* 숨김 전환 지속 예비(현재 components.css 는 show-dur 공용) */

  /* [정정 이력·CLAUDE §9] --pinned-z 삭제(2026-08-08): 표를 «A-2 자동 필터»(비선택 행
     .is-hidden 토글)로 전환하면서 pinned 복제행이 사라졌다. 그 z-index 토큰도 함께 제거한다
     (죽은 토큰 잔존 = #20 드리프트 근원). thead sticky(z:1)만 남는다(components.css). */

  /* ── 정류장 역할 배지 토큰 (#출도경, 2026-08-08) ──────────────────────────────
     발주자 요구: «카카오맵 출발=파란 깃발 / 도착=빨간 깃발처럼 작게 출/도/경 한 글자».
     origin(출발)=파랑·dest(도착)=빨강·via(경유)=회색 — 카카오 관례 준용.
     한글 글자(출/도/경) 자체가 의미를 담아 색맹 무관(색은 보조).
     대비 근거: 배지 배경 위 흰 글자 — 각 색의 vs white 대비를 R13 §E-6 기준으로 선정.
       origin #1c67c4 = --color-primary(5.55:1, AA). 파랑 계열 확정.
       dest   #c62f2f = --color-danger (5.46:1, AA). 빨강 계열 확정.
       via    #4c5866 = --text-muted  (7.25:1, AA). 회색 계열 확정.
     라이트/다크 양쪽 정의 — 하드코딩 방지 규약(직전 box-shadow rgba 회귀 사고 재발 방지). */
  --stop-origin:    #1c67c4;   /* 출발 배지 배경: 파랑 = --color-primary 동일값 (라이트) */
  --stop-dest:      #c62f2f;   /* 도착 배지 배경: 빨강 = --color-danger  동일값 (라이트) */
  --stop-via:       #4c5866;   /* 경유 배지 배경: 회색 = --text-muted    동일값 (라이트) */
  --stop-transfer:  #1a7a3c;   /* 환승 배지 배경: 녹 = --color-success — 흰 글자 대비 5.39:1 (라이트) */

  /* ── 스트립 승차/하차 막대 색 (항목 1, 2026-08-08) ────────────────────────────
     발주자 지적: 승차·하차 막대가 둘 다 회색이라 한눈에 파악이 안 된다.
     처방: 승차=primary 파랑 / 하차=muted 회색 으로 색 2종 분리.
       --bar-board(승차, 위): --color-primary(#1c67c4) — 활성·수행 의미의 파랑.
         대비(vs bg-surface #ffffff): 5.55:1 AA 통과(R13 §E-6 --color-primary 실측).
       --bar-alight(하차, 아래): --text-muted(#4c5866) — 결과·완료 의미의 중성 회색.
         대비(vs bg-surface #ffffff): 7.25:1 AA 통과(#11 조정후 실측).
     색-비의존 유지: 위(승차)/아래(하차) 위치 + 색 + 범례 라벨 3중 부호화.
     라이트/다크 양쪽 정의 — 하드코딩 방지 규약(직전 다크 배지 대비 사고 재발 방지). */
  --bar-board:      #1c67c4;   /* 승차 막대(위): 파랑 = --color-primary 동일값 (라이트) */
  --bar-alight:     #4c5866;   /* 하차 막대(아래): 회색 = --text-muted 동일값 (라이트) */

  /* 격자 특수값 */
  --grid-zero:      #d9dce0;   /* 값 0 (1.86:1) */
  /* 값 없음(null)은 «렌더하지 않는다» — 0 과 반드시 구분한다 (R6 §6.3).
     0 을 회색으로 칠하고 null 도 회색으로 칠하면 «조용히 틀린» 지도가 된다. */
}

/* ========================= 다크 모드 ========================= */
/* OS 설정 대응 — 사용자 토글이 이기도록 :not() 으로 가드한다 */
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) { color-scheme: dark; }
}
:root[data-theme="dark"] { color-scheme: dark; }

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    /* 차트 라벨 헤일로 — 다크: 글자=흰색, 외곽선=어두운 잉크(기존 --halo-dark 값 재사용).
       --halo-dark 자체는 지도 심볼용이므로 삭제·변경하지 않고, 의미 토큰만 여기서 덮어쓴다. (#3) */
    --halo-fg:        #f2f5f8;   /* 다크: 라벨 글자색 = --text-primary 다크값(밝은 흰계열) */
    --halo-edge:      #14181f;   /* 다크: 헤일로 외곽선 = --halo-dark 값 재사용(어두운 잉크) */

    --bg-canvas:      #0c0f14;
    --bg-surface:     #12161c;
    --bg-subtle:      #1a1f27;

    --text-primary:   #f2f5f8;   /* 16.58 / 15.12 / 17.54  AAA */
    --text-secondary: #c2ccd8;   /* 11.17 / 10.18 / 11.81  AAA */
    --text-muted:     #98a3b0;   /*  7.09 /  6.46 /  7.50  AA  */
    --text-on-accent: #0c0f14;

    --border:         #2b323c;   /* 1.40 — 장식 전용 */
    --border-strong:  #79838f;   /* 4.71 / 4.30 / 4.99  SC 1.4.11 ✅ */

    --color-primary:       #5da2f0;  /* 6.82 / 6.22 / 7.21  AA  */
    --color-primary-hover: #8ec0f7;  /* 9.53 / 8.69 /10.08  AAA */
    --color-danger:        #f0736b;  /* 6.37 / 5.81 / 6.74  AA  */
    --color-warning:       #e0a52a;  /* 8.28 / 7.55 / 8.76  AAA */
    --color-success:       #4ec97e;  /* 8.62 / 7.86 / 9.12  AAA */
    --color-info:          #5da2f0;
    --color-select:        #f0736b;  /* = danger 값(다크). 의미는 «선택»(빨간 점선). 비텍스트 ≥3:1 승계 */

    /* 슬롯 «순서(색상군)»는 라이트와 동일하게 유지한다 — 역할 일관성 (규칙 K-2).
       테마를 바꿨다고 노선 색이 뒤바뀌면 사용자가 색으로 기억한 것이 무너진다. */
    /* 스킴 A 다크(R48 §3-A) 채택 2026-08-09. 슬롯2 채도 미세보정(#3ca99c C.0998→#33aa9c C.105).
       종전값 #4392f7·#18a7a1·#2e7c35·#7447c8·#b28d00·#a83876·#e06d00·#ba2c25 는 git 이력 보존. verify_palette.py 통과. */
    --cat-1: #4b81d1;  --cat-2: #33aa9c;  --cat-3: #3f7a43;  --cat-4: #7255b4;
    --cat-5: #aa8e3d;  --cat-6: #9c4a74;  --cat-7: #d2783b;  --cat-8: #a8453d;

    /* 순차형 — 다크에서는 «방향이 반전»된다. 값이 클수록 밝아져야
       어두운 배경에서 «많음»으로 읽힌다. 라이트 값을 그대로 쓰면 의미가 뒤집힌다. */
    --seq-1: #334f6c;  --seq-2: #006ab7;  --seq-3: #0086e6;
    --seq-4: #46a5ff;  --seq-5: #8bc4ff;  --seq-6: #c6e1ff;
    --seqmap-1: #334f6c; --seqmap-2: #006ab7; --seqmap-3: #0086e6;
    --seqmap-4: #46a5ff; --seqmap-5: #8bc4ff; --seqmap-6: #c6e1ff;

    --div-0:  #383835;           /* 다크 중립 (양팔은 라이트 값을 그대로 쓴다) */
    --div9-0: #383835;

    --chart-grid: #2c2c2a;
    --chart-axis: #383835;
    --grid-zero:  #333a44;

    --shadow-sm: 0 1px 2px rgba(0,0,0,.40);
    --shadow-md: 0 4px 12px rgba(0,0,0,.50);
    --shadow-lg: 0 12px 32px rgba(0,0,0,.60);

    /* 정류장 역할 배지 — 다크 (#출도경, 2026-08-08):
       ★ 배지는 «색 배경 + 흰 글자(#ffffff)»다. 따라서 «배경색 위 흰 글자」 대비가 ≥4.5:1 이어야 한다.
       ⚠ F5 H-1 정정: 밝은 파랑/빨강(다크 텍스트용 색 #5da2f0·#f0736b)은 흰 글자 대비가 각각
         2.66:1·2.85:1 로 AA 미달이다. «그 색을 어두운 배경 위 글자로 쓸 때」 대비(6.82/6.37)와
         «그 색을 배경으로 흰 글자를 얹을 때» 대비는 전혀 다르다 — 혼동하면 조용히 틀린 값(CLAUDE §2).
       처방: 다크 배지 배경도 라이트의 «진한 색»을 그대로 써서 흰 글자 대비를 확보한다(어두운 다크
         면 위에서도 진한 파랑·빨강은 충분히 구별된다). via 는 designer 가 이미 #64707e 로 정정. */
    --stop-origin:  #1c67c4;   /* 출발 배지 배경: 진한 파랑 — 흰 글자 대비 5.55:1 (F5 H-1) */
    --stop-dest:    #c62f2f;   /* 도착 배지 배경: 진한 빨강 — 흰 글자 대비 5.46:1 (F5 H-1) */
    --stop-via:     #64707e;   /* 경유 배지 배경: 어두운 회색 — 흰 글자 대비 약 5:1 */
    --stop-transfer: #1a7a3c;  /* 환승 배지 배경: 진한 녹 — 흰 글자 대비 5.39:1 (다크도 진한색, H-1 교훈) */

    /* 스트립 승차/하차 막대 색 — 다크 @media 블록 (항목 1, 2026-08-08):
       라이트와 역할 동일, 테마 대응. @media·:root[data-theme="dark"] 양쪽에 동일값.
       --bar-board(다크): --color-primary 다크값 #5da2f0. 대비 vs --bg-surface(#12161c): 6.82:1 AA.
       --bar-alight(다크): --text-muted 다크값 #98a3b0. 대비 vs --bg-surface(#12161c): 7.09:1 AA. */
    --bar-board:    #5da2f0;   /* 승차 막대(위, 다크): = --color-primary 다크값 */
    --bar-alight:   #98a3b0;   /* 하차 막대(아래, 다크): = --text-muted 다크값 */
  }
}

/* 사용자 토글이 OS 설정을 «양방향으로» 이긴다 */
:root[data-theme="dark"] {
  /* 차트 라벨 헤일로 — 다크 토글 고정 시에도 동일하게 적용한다 (#3).
     @media 블록과 값이 동일해야 한다 — 두 곳이 어긋나면 토글 시 헤일로가 뒤집힌다. */
  --halo-fg:   #f2f5f8;   /* 다크: 흰계열 글자 */
  --halo-edge: #14181f;   /* 다크: 어두운 잉크 외곽선 (--halo-dark 값과 동일) */
  --bg-canvas: #0c0f14; --bg-surface: #12161c; --bg-subtle: #1a1f27;
  --text-primary: #f2f5f8; --text-secondary: #c2ccd8; --text-muted: #98a3b0;
  --text-on-accent: #0c0f14;
  --border: #2b323c; --border-strong: #79838f;
  --color-primary: #5da2f0; --color-primary-hover: #8ec0f7;
  --color-danger: #f0736b; --color-warning: #e0a52a; --color-success: #4ec97e;
  --color-info: #5da2f0;
  --color-select: #f0736b;  /* 선택 전용(다크) — danger 값이나 의미 분리(R41 §2.2) */
  /* 스킴 A 다크(R48 §3-A) 채택 2026-08-09 — [data-theme="dark"] 수동 토글 분기(위 @media 와 동일값 유지). */
  --cat-1: #4b81d1; --cat-2: #33aa9c; --cat-3: #3f7a43; --cat-4: #7255b4;
  --cat-5: #aa8e3d; --cat-6: #9c4a74; --cat-7: #d2783b; --cat-8: #a8453d;
  --seq-1: #334f6c; --seq-2: #006ab7; --seq-3: #0086e6;
  --seq-4: #46a5ff; --seq-5: #8bc4ff; --seq-6: #c6e1ff;
  --seqmap-1: #334f6c; --seqmap-2: #006ab7; --seqmap-3: #0086e6;
  --seqmap-4: #46a5ff; --seqmap-5: #8bc4ff; --seqmap-6: #c6e1ff;
  --div-0: #383835; --div9-0: #383835;
  --chart-grid: #2c2c2a; --chart-axis: #383835; --grid-zero: #333a44;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.40);
  --shadow-md: 0 4px 12px rgba(0,0,0,.50);
  --shadow-lg: 0 12px 32px rgba(0,0,0,.60);
  /* 정류장 역할 배지 — 다크 토글 고정 (#출도경, 2026-08-08):
     @media 블록과 값이 동일해야 한다 — 두 곳이 어긋나면 토글 시 배지색이 뒤집힌다.
     ★ 배지 배경 위 흰 글자 대비 ≥4.5:1. 밝은 색(#5da2f0/#f0736b)은 흰 글자 대비 미달이라
        진한 색을 쓴다(F5 H-1 — @media 블록과 동일 정정). */
  --stop-origin:  #1c67c4;   /* 흰 글자 대비 5.55:1 */
  --stop-dest:    #c62f2f;   /* 흰 글자 대비 5.46:1 */
  --stop-via:     #64707e;   /* 흰 글자 대비 약 5:1 */
  --stop-transfer: #1a7a3c;  /* 환승 배지 배경: 진한 녹 — 흰 글자 대비 5.39:1 */

  /* 스트립 승차/하차 막대 색 — :root[data-theme="dark"] 블록 (항목 1, 2026-08-08):
     @media 블록과 값이 동일해야 한다 — 두 곳이 어긋나면 토글 시 막대색이 뒤집힌다. */
  --bar-board:    #5da2f0;   /* 승차 막대(위, 다크): = --color-primary 다크값 */
  --bar-alight:   #98a3b0;   /* 하차 막대(아래, 다크): = --text-muted 다크값 */
}

/* ==================== 기본 적용 ==================== */
body {
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-normal);
  color: var(--text-primary);
  background: var(--bg-canvas);
  -webkit-font-smoothing: antialiased;
}

/* 표 수치는 반드시 자릿수 정렬 (§E-3). 자릿수가 흔들리면 대소 비교가 어긋난다. */
.num, td.num, th.num, .axis-tick {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* 포커스 표시 — 제거 금지 (WCAG 2.4.7 / [별표 3] 2.2).
   `outline: none` 은 어떤 이유로도 쓰지 않는다. */
:focus-visible {
  outline: var(--focus-w) solid var(--color-primary);
  outline-offset: var(--focus-offset);
}

/* 지도 오버레이 — 헤일로 2-pass (규칙 M-4) */
.map-line-casing { stroke: var(--halo-color, var(--halo-dark)); stroke-linecap: round;
                   stroke-linejoin: round; fill: none; }
.map-line-stroke { stroke-linecap: round; stroke-linejoin: round; fill: none; }
.map-symbol      { stroke: var(--halo-color, var(--halo-dark)); stroke-width: 1.5px; }

/* 상태 표시는 아이콘+라벨 필수 (규칙 S-1) — 색 단독 사용을 구조적으로 막는다 */
.status { display: inline-flex; align-items: center; gap: var(--sp-1); }
.status::before { font-weight: 700; }
.status--success { color: var(--color-success); } .status--success::before { content: "✓"; }
.status--warning { color: var(--color-warning); } .status--warning::before { content: "⚠"; }
.status--danger  { color: var(--color-danger);  } .status--danger::before  { content: "✕"; }
.status--info    { color: var(--color-info);    } .status--info::before    { content: "ⓘ"; }

/* 접근성: 모션 감소 (KWCAG 2.2 신설 항목 대응) */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* 강제 색상 모드 (Windows 고대비) 대응 */
@media (forced-colors: active) {
  .map-line-stroke, .map-symbol { forced-color-adjust: none; }  /* 데이터 색은 보존 */
  :focus-visible { outline: 2px solid CanvasText; }
}
