/*
 * ============================================================================
 *  밀리AI 토큰 — 별칭 · 파생값 · Bootstrap 재바인딩
 * ============================================================================
 *
 *  정본은 theme/tokens.css(디자인 참고 저장소 1:1 이식본)다. 이 파일은 세 가지만 한다.
 *
 *    1) 우리 프로젝트가 예전부터 쓰던 이름 → 참고 토큰 이름 별칭
 *    2) 참고에 없어서 우리가 직접 정하는 파생값(-rgb 짝 · 그림자 · 히트맵 · 코드 팔레트 …)
 *    3) Bootstrap 루트 변수 재바인딩
 *
 *  ⚠️ 이 블록들은 "시맨틱을 재선언하는 모든 스코프"에 함께 걸어야 한다 — 즉 :root 와 .mili-light 양쪽.
 *     커스텀 프로퍼티는 선언된 요소에서 var() 가 치환되고 자손은 치환이 끝난 값을 상속하므로
 *     (css-variables-1 §2.1), :root 에만 --mili-bg: var(--mili-app-bg) 를 두면
 *     .mili-light 가 --mili-app-bg 를 바꿔도 따라오지 않는다.
 *
 *  스코프: :root = 다크(기본) / .mili-light = 라이트.
 *  화면 JSP 의 <body> 가 mili-dark(+레거시 mili-theme-dark) 또는 mili-light 를 붙인다.
 * ============================================================================
 */

/* ============================================================
   1) 원시 팔레트 — 테마 무관 raw 값
   ------------------------------------------------------------
   참고 토큰으로 대체되지 않은 것만 남았다. 참조처가 사라지는 대로 함께 지운다.
   ============================================================ */
:root {
    /* ---------- 라임(레거시) ----------
       참고의 --mili-primary 로 수렴 중이다. 아직 화면 CSS 가 참조한다.
       2026-09-18 재개편 — 브랜드색이 라임(#B4FF39)에서 민트그린(#85F686)으로 바뀌어 같이 갱신.
       -300 은 옛값과 정확히 같던 --mili-primary(Primary/500)를 그대로 옮기고, -400 은 옛값이
       어느 스텝과도 정확히 안 맞던 "더 밝은 강조색"이라 상대적 밝기를 유지해 Primary/400으로 뗀다.
       2026-09-18 2차 수정(사용자 확인) — "테마 무관 고정값"이 아니라 실제로는 테마를 타야
       맞는 값으로 바로잡는다. var() 로 참조하고 아래 .mili-light 블록에서 라이트 스텝으로
       재선언한다. -400 만 쓰이는 vod/learn.css(항상 mili-theme-dark 고정 화면)는 영향 없다. */
    --mili-lime-300: var(--mili-primary-500);
    --mili-lime-400: var(--mili-primary-400);

    /* ---------- 다크 표면 계조(레거시) ----------
       참고의 --mili-app-bg / --mili-surface / --mili-surface-raised 로 수렴 중이다. */
    --mili-slate-950: #0b0d10;
    --mili-slate-900: #0c0c0d;
    --mili-slate-800: #0d1014;
    --mili-slate-700: #14171b;
    --mili-slate-600: #1a1d21;

    /* ---------- 홈 스탯 4색 ---------- */
    --mili-stat-streak: #ff8904;    /* 연속 학습 */
    /* 위 색의 rgb 성분. 마이페이지 개요 시안(8qAqeXw50F8GKDGkeW0Pua, node 2224:89140)이
       보상 이력 아이콘 배경으로 rgba(255,137,4,0.12) 를 쓴다 — 알파를 섞어야 하는 곳에서
       리터럴을 박지 않도록 --mili-brand-rgb 와 같은 관례로 짝 토큰을 둔다.
       이 4색은 테마 무관 고정값이라 라이트 블록에 재정의가 없다. */
    --mili-stat-streak-rgb: 255, 137, 4;
    --mili-stat-badge: #fdc700;     /* 배지 */
    /* 완료 미션(2026-09-18 재개편 — 라임 #aaff19 → 민트그린 Primary/400). 2차 수정(사용자 확인) —
       "테마 무관"이 아니라 테마를 타야 맞는 값으로 바로잡는다. 아래 .mili-light 에서 재선언. */
    --mili-stat-mission: var(--mili-primary-400);
    --mili-stat-time: #51a2ff;      /* 누적 학습 */
    /* 2026-09-04 마이페이지 대시보드 상단 스탯 4색(Figma node 3249:63731 라이트 재확인) —
       XP 아이콘은 --mili-brand(테마 따라 뮤트 올리브로 바뀜)가 아니라 이 4색 세트와 같은
       값을 쓴다. --mili-stat-mission 과 결이 같지만 실측값이 달라(옛 #B4FF39) 별도 토큰으로
       둔다. 2026-09-18 재개편 — Primary/500 다크로 갱신. 2차 수정(사용자 확인) — 이것도
       "테마 무관"이 아니라 바로잡아 테마를 타게 한다(아래 .mili-light 재선언). */
    --mili-stat-xp: var(--mili-primary-500);        /* XP */

    /* 포인트 강조(노랑) — 진도 게이지·NEW 뱃지. 참고에 대응 토큰이 없다. */
    --mili-accent: #ffc53d;

    /* ---------- 스킬 배지 레벨 5색 ----------
       Figma "배지 디자인"(node 1381:149) 실측값. 이전에는 .reference/miliai-hddn
       AccountViews.tsx badgeLevels(컴포넌트 내부 JS 배열)를 그대로 옮겨 썼으나, 2026-08-12
       정식 배지 디자인이 나오면서 이 값으로 교체했다. */
    --mili-badge-lv1: #d4a84b;    /* 입문 */
    --mili-badge-lv2: #78d97c;    /* 기초 */
    --mili-badge-lv3: #5bc8f5;    /* 실전 */
    --mili-badge-lv4: #a78bfa;    /* 심화 */
    --mili-badge-lv5: #f4845f;    /* 전문 */

    /* 로그인 화면 좌측 비주얼 — 블랙 베이스 + 네온그린 글로우(PBL 히어로 배너와 같은 조합, pbl/project-list.css 참고).
       사진을 쓰려면 이 값만 url("../../images/login-visual.jpg") 처럼 바꾸면 된다(마크업 수정 불필요). */
    --mili-login-visual: linear-gradient(160deg, #060706 0%, #0c0f0a 55%, #142010 100%);

    /* ---------- 팔레트 원시값은 primitives.css 가 단일 출처다 ----------
       예전에 여기서 Secondary 램프 일부(sky/green/orange/purple/blue/mint/yellow/pink)를 hex 로
       다시 선언했으나, 그 사본이 primitives.css 를 덮어써 Figma 변경이 반영되지 않았다(2026-09-21 제거).
       색을 바꿀 땐 primitives.css 한 곳만 고친다. 아래 mint-400 만은 라이트에서도 다크 값을 쓰는
       의도된 테마 무관 고정값이라 남긴다. */
    --mili-mint-400: #5FB8A9;

    /* ---------- 검색창 placeholder 전용 고정 회색 ----------
       Figma "Search" 컴포넌트(8qAqeXw50F8GKDGkeW0Pua, node 2042:217006, 2026-08-26 사용자 확인)
       실측 — Neutral/600, 다크·라이트 공통 고정값(테마별로 안 바뀐다). 기존 placeholder 는
       rgba(--mili-fg-rgb, .35)로 테마별 반투명이었으나 시안대로 고정 회색으로 교체한다. */
    --mili-search-placeholder: var(--mili-neutral-600);

    /* tokens.css(참고 이식본)에는 regular/medium/bold 3단만 있다. Figma 실측(8qAqeXw50F8GKDGkeW0Pua,
       QA28 "GNB button case" node 1692:4205 selected 상태 — Pretendard SemiBold)으로 600 이
       실제로 쓰이는 걸 확인해 여기서 보강한다(버튼 라벨은 500 이 맞다 — 승인 D, 별개 값). */
    --mili-font-weight-semibold: 600;

    /* ---------- 폰트: tokens.css 값을 덮어쓴다 ----------
       참고는 폐쇄망 한글 폴백을 고려하지 않아 스택이 짧다(Pretendard 뒤가 바로 sans-serif).
       우리는 폰트 파일을 받지 못하는 환경에서도 한글이 깨지지 않도록 시스템 스택을 유지한다.

       맨 앞의 "Pretendard Variable" 은 base-layout.jsp 가 싣는 가변폰트 dynamic-subset 의
       글꼴 이름이다. 그 뒤 Pretendard 는 사용자 PC 에 정식 설치돼 있을 때 쓰는 로컬 폴백이라
       둘 다 남겨 둔다(웹폰트를 못 받는 폐쇄망에서 특히 의미가 있다). */
    --mili-font-sans: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, "Segoe UI", "Malgun Gothic", "Apple SD Gothic Neo", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
    /* 같은 이유로 Orbitron 뒤를 sans-serif 가 아니라 위 스택으로 받는다(Orbitron 에는 한글이 없다).
       스킬 배지 코드·Lv 필 라벨도 이 토큰을 쓴다 — 2026-08-28 Figma 실측 재확인 결과 배지
       전용 서체가 Rajdhani Bold 에서 Orbitron 으로 바뀌어(node 2261:43660 Numeric/N1),
       기존 --mili-font-rajdhani(Google Fonts CDN 별도 로드) 대신 이미 자체 호스팅 중인
       이 토큰으로 통일했다. */
    --mili-font-metric: "Orbitron Variable", Orbitron, var(--mili-font-sans);

    /* ---------- 형태(레거시 반경 스케일) ----------
       참고는 --mili-radius-none/-filter/-card/-pill 4종이고 우리 CSS 는 sm/base/lg 를 49곳에서 참조한다.
       각진 시안이라 전부 0 이다. 참조처를 --mili-radius-none 으로 옮기는 대로 지운다.

       ⚠️ 새 CSS 는 아래 3개(sm/base/lg)를 쓰지 않는다. "각져야 해서 0"인지 "아직 안 옮겨서 0"인지
          구분이 안 되기 때문이다. 모서리는 tokens.css 의 **모양별** 스케일만 참조한다:

            --mili-radius-none       0    표·구분 블록처럼 의도적으로 각진 곳
            --mili-radius-button   5px    일반 버튼
            --mili-radius-filter   8px    탭 · 필터칩 · 정렬 드롭다운
            --mili-radius-control 10px    아이콘 버튼 · 프로필 칩 · 입력 컨트롤
            --mili-radius-card    12px    카드 · 패널
            --mili-radius-badge   99px    배지
            --mili-radius-pill  9999px    검색 필드 · 알약형 칩

          Figma 시안(8qAqeXw50F8GKDGkeW0Pua)의 반경 실측이 이 스케일과 값까지 정확히 일치한다
          — 탭/드롭다운 8px, 아이콘버튼·프로필칩 10px, 검색창 9999px. 따라서 999px·9999px·8px·
          12px·5px 같은 리터럴을 새로 쓰지 말고 위 토큰을 참조한다(규칙 정본은 CLAUDE.md). */
    --mili-radius-sm: 0;
    --mili-radius: 0;
    --mili-radius-lg: 0;

    /* 사이드바 셸(카드) 전용 — 위 스케일에 없는 값이라 새로 추가했다.
       Figma 실측(8qAqeXw50F8GKDGkeW0Pua, node 1638:2827 · 1553:1099) 20px.
       카드(12px)보다 한 단 크다 — 앱 셸 최상위 컨테이너 전용이라 카드 스케일에 끼워 넣지 않는다. */
    --mili-radius-shell: 20px;

    /* 마이페이지 개요 상단 "요약 카드"(아바타·이름·레벨바) 전용 — QA 16(8qAqeXw50F8GKDGkeW0Pua,
       node 1659:18674) 실측 30px. shell(20px)보다도 한 단 더 크다 — 대시보드에서 다른 카드보다
       강조되게 두라는 명시적 요청(마이페이지 요약 카드 단독 용도, 카드 스케일에 끼워 넣지 않는다). */
    --mili-radius-profile-summary: 30px;

    /* ---------- 공통 페이지 헤더(hero) ----------
       Figma "PC 공통_타이틀/설명/검색" 정본. node 1354-232(컴포넌트 스펙) + 1497-3009(커뮤니티 실화면).
       세로 간격은 **실화면(1497)** 을 따른다 — 스펙 프레임은 상단 간격만 32px 로 달라서 쓰지 않는다.

           상단바 아래 → 제목   40px   (.app-page 의 padding-top 8px + 아래 --mili-hero-top-gap 32px)
           제목 → 설명          12px   (Figma Space/Padding/paddingSM)
           설명 → 검색창        32px
           hero → 본문          32px

       제목 36px 은 tokens.css 의 t1~t11 에 없는 값이라(t8=28/36, t9=32/42) 여기서 만든다.
       설명 14px/20px 은 t3 그대로라 --mili-text-sm / --mili-line-tight 을 쓴다.

       2026-08-25 정정 — line-height 는 원래 40px(111%, 근거 불명)이었는데, Figma Typography
       공통 요소 시트(8qAqeXw50F8GKDGkeW0Pua, node 2051:217181)의 H1 행이 "line-height 140%"로
       고정돼 있음을 확인해 36×1.4=50.4px 로 교체한다(docs/design/figma-common/02-typography.md
       질문1 반영, 사용자 확인). letter-spacing -2% 는 components.css 의 .page-hero__title 에서
       직접 건다(같은 시트, 전 Heading/Body 행 공통값). */
    --mili-hero-top-gap: 32px;
    --mili-hero-title-size: 2.25rem;      /* 36px */
    --mili-hero-title-line: 3.15rem;      /* 50.4px = 36px × 140% */
    --mili-hero-lead-gap: 0.75rem;      /* 12px */
    --mili-hero-search-gap: 2rem;       /* 32px */
    --mili-hero-block-gap: 2rem;        /* 32px — hero 와 본문 사이 */
    /* 2026-09-11 — 회원가입·아이디/비밀번호 찾기(fileKey 8qAqeXw50F8GKDGkeW0Pua, node
       4038:312569/312585/312601/312633) 실측. Title 컴포넌트 바닥에서 본문 첫 블록까지 60px 로,
       목록형 9개 화면이 쓰는 --mili-hero-block-gap(32px)보다 넓다. 전역 토큰을 바꾸면 그 9개 화면이
       다 벌어지므로 새 토큰을 두고 .page-hero--form-intro 로만 오버라이드한다. */
    --mili-hero-block-gap-lg: 3.75rem;  /* 60px */

    /* ---------- 타이포그래피 — Figma 실측 8단계 (2026-08-25) ----------
       위 hero(H1=36px)에 이어, 나머지 실제 존재하는 Figma 텍스트 스타일 7개를 여기서 토큰화한다.
       Figma MCP get_variable_defs(fileKey 8qAqeXw50F8GKDGkeW0Pua, node 2051:217181)로 "디자이너가
       실제로 고르는 스타일 이름"을 직접 조회한 결과다 — 아래 §Body B5 주석이 근거로 삼았던
       "H1~H5/B1~B5 10단계, 전 행 -2%" 표(같은 노드를 사람이 눈으로 읽고 옮긴 것)는 이 조회로
       상위 대체됐다: 실제로는 8단계뿐이고(H1~H4, B1~B3, Caption — B4/B5는 존재하지 않는다),
       B1은 16px가 아니라 18px, H3의 letter-spacing은 -2%가 아니라 0%다. 대조·정정 기록은
       docs/design-tokens.md 참고.

       tokens.css 의 t1~t11 스케일과 겹치는 이름은 7개뿐이다(t1=Caption, t3=B3, t4=B2, t5=B1,
       t6=H4, t7=H3, t9=H2) — 나머지(t2=13px·t8=28px·t10=40px·t11=48px)는 Figma에 대응 사이즈가
       없는 "고아 토큰"이라 이번엔 손대지 않는다(tokens.css 자체도 참고 저장소 이식본이라 값을
       바꾸지 않는다). line-height 는 Heading 140%/Body·Caption 130% 비율로 재계산했고, t6(H4)만
       기존 t-스케일 값과 우연히 정확히 일치한다.

       letter-spacing 은 H2만 토큰화했다 — H1 은 이미 .page-hero__title 에 리터럴로 걸려있고
       (선례 유지), H3 은 0%라 토큰이 불필요하며, H4·B3 는 굵기별로 값이 갈려서(H4: Bold만 -2%,
       B3: Tag 칩 전용 Medium만 -2%) 토큰 하나로 못 담는다 — 실제 적용 시점에 그 굵기 셀렉터에
       H1 선례처럼 리터럴로 직접 건다. */
    --mili-caption-size: 0.75rem;        /* 12px, = t1 */
    --mili-caption-line: 0.975rem;       /* 15.6px = 12px × 130% (구 t1 16px 대비 -0.4px) */
    --mili-body-b3-size: 0.875rem;       /* 14px, = t3 */
    --mili-body-b3-line: 1.1375rem;      /* 18.2px = 14px × 130% (구 t3 20px 대비 -1.8px) */
    --mili-body-b2-size: 1rem;           /* 16px, = t4 */
    /* 2026-09-18 Figma 재실측(get_design_context 다수 노드, Body/B2 스타일 메타 직접 확인) —
       130%(20.8px)가 아니라 160%(25.6px)다. 전역 토큰이라 본문 텍스트를 쓰는 모든 화면에
       영향 — 사용자 확인 후 반영. */
    --mili-body-b2-line: 1.6rem;         /* 25.6px = 16px × 160% */
    --mili-body-b1-size: 1.125rem;       /* 18px, = t5 */
    --mili-body-b1-line: 1.575rem;       /* 25.2px = 18px × 140% (구 t5 26px 대비 -0.8px) */
    --mili-heading-h4-size: 1.25rem;     /* 20px, = t6 */
    --mili-heading-h4-line: 1.75rem;     /* 28px = 20px × 140% — 구 t6 28px 와 이미 정확히 일치 */
    --mili-heading-h3-size: 1.5rem;      /* 24px, = t7 */
    --mili-heading-h3-line: 2.1rem;      /* 33.6px = 24px × 140% (구 t7 32px 대비 +1.6px) */
    --mili-heading-h2-size: 2rem;        /* 32px, = t9 */
    --mili-heading-h2-line: 2.8rem;      /* 44.8px = 32px × 140% (구 t9 42px 대비 +2.8px) */
    --mili-heading-h2-letter-spacing: -0.02em;

    /* ---------- Body B5(11px) — 2026-08-25 정정: 실재하지 않음 ----------
       위 블록에서 밝혔듯 Figma get_variable_defs 실측 결과 B4/B5 라는 스타일 자체가 없다(Body는
       B1~B3, 12px 아래는 바로 Caption). 이 토큰은 그 사실을 몰랐을 때(사람이 표를 옮겨 적은
       구버전 자료 기준) 만든 것이라 근거가 사라졌다 — 아직 실사용처가 없어 지우는 게 맞지만,
       이번 마이그레이션 1단계 범위가 아니라 정정 코멘트만 남기고 값은 그대로 둔다. */
    --mili-font-size-b5: 0.6875rem;     /* 11px */
    --mili-line-height-b5: 0.89375rem;  /* 14.3px = 11px × 130% */
    --mili-letter-spacing-b5: -0.02em;

    /* 검색 필드 실측(Figma Label 1354:352). 폭은 min() 상한으로만 쓴다.
       테두리색은 시안이 #1E2227(= --mili-surface-raised)이지만 그 토큰은 라이트에서 #FFFFFF 라
       테두리가 사라진다 — 두 테마 모두 성립하는 --mili-line 을 쓴다. */
    --mili-search-field-width: 576px;
    --mili-search-field-height: 52px;

    /* ---------- 레이아웃(참고에 없는 것) ---------- */
    --mili-navbar-height: 64px;      /* .detail-shell__aside 의 sticky top 계산용 */
    --mili-section-gap: 3rem;

    /* ---------- 레이아웃 그리드 — 디자인 규칙표 정합 ----------
       정본 규칙은 mydocs/ss02/design-system.md §7 이다. 여기 4줄이 그 표의 수치를 만든다.

       tokens.css 는 참고 저장소 1:1 이식본이라 손대지 않고, 값이 다른 것만 여기서 덮는다.
       로드 순서가 tokens → variables → reference 이므로, reference.css §페이지 그리드의
       미디어쿼리(:root 재정의)가 태블릿·모바일 구간을 뒤에서 다시 덮는다 — 즉 아래 4줄만으로
       ≥1280 / 1024–1279 / 768–1023 / ≤767 네 구간이 전부 규칙대로 맞는다.
       **여기에 새 미디어쿼리를 추가하지 말 것.** 구간 정의는 reference.css 한 곳이 정본이다. */

    /* 데스크톱 좌우 여백. 참고는 32px 이지만 우리 규칙표는 48px 이다
       (1440 화면 → 1440 - 240(사이드바) - 48×2 = 1104px 컨테이너). */
    --mili-page-padding: 48px;

    /* 모바일 거터. 참고는 12px 이지만 우리 규칙표는 16px 이다
       (390 화면 → (350 - 16×3) / 4 = 75.5 ≈ 76px 컬럼). */
    --mili-mobile-grid-gutter: 16px;

    /* 모바일 좌우 여백은 "20px 고정"이다. 참고의 16px 을 20px 로 올려서 390px 미만
       (구형 소형폰)에서도 20px 이 되게 한다 — reference.css 의
       @media (min-width: 390px) and (max-width: 767px) 블록은 그래서 중복이 되지만 무해하다. */
    --mili-mobile-page-padding: 20px;

    /* 본문 컨테이너 최대폭 3종.
         --mili-content-max      1440px  Wide     — 홈 · 미션 여정 (tokens.css 정의)
         --mili-content-standard 1200px  Standard — 그 외 전 화면 기본값
         --mili-content-narrow    960px  Narrow   — 읽기·폼 전용(역량진단 · 온보딩 등) */
    --mili-content-standard: 1200px;
    --mili-content-narrow: 960px;

    /* 푸터 전용 콘텐츠 최대폭. Figma 4857:194123(2026-09-23 재실측, 이전 4857:194122 대비
       콘텐츠 폭이 1518px 로 넓어짐)를 반영한다. 사용자가 "전역 --mili-page-padding 은
       건드리지 말고 푸터만 넓힌다"를 선택했으므로 --mili-content-standard 는 그대로 두고
       푸터 전용 값을 따로 둔다. */
    --mili-footer-content-max: 1518px;

    /* 본문 영역 최소 높이와 푸터 앞 간격.
       Figma QA 시안 1699:3983("공통- footer", 2026-08-12) 이 정한 두 값이다.
         · 콘텐츠 영역(상단바 포함)은 내용이 적어도 최소 1080px 을 유지한다.
           시안의 Container 가 1680×1080 이고 그 안에 72px Header 가 들어 있다 —
           그래서 .app-page 에 거는 값은 1080 이 아니라 1080 - 상단바 높이다.
         · 콘텐츠 영역이 끝난 뒤 푸터까지 200px 을 띄운다.
       둘 다 1920 데스크톱 시안에만 있는 값이라, 사이드바가 드로어로 바뀌는 1024px
       미만에서는 components.css 가 최소 높이를 풀고 간격을 줄인다(내용 없는 화면이
       폰에서 1080px 스크롤이 되는 것을 막는다). */
    --mili-content-min-height: 1080px;
    --mili-footer-gap: 200px;

    /* 실행 결과 정/오답 색. 에디터·콘솔은 어느 테마에서도 다크라 테마를 타지 않는다. */
    --mili-code-success: #48c78e;
    --mili-code-danger: #ff6b6b;

    /* ---------- 검색창 전용 배경·보더 ----------
       Figma "Search" 컴포넌트(8qAqeXw50F8GKDGkeW0Pua, node 2051:217068 "Property 1=Dark" 인스턴스
       직접 실측, 2026-08-26 재확인) — Neutral/870·750. 이전엔 Neutral/850(#1C1F23)로 잘못
       측정했었다(색상표를 손으로 옮기며 인접 단계와 혼동). 기존 --mili-surface/--mili-border
       (범용 패널 토큰)와 값이 달라 검색창(.search-box, vod/course-list·pbl/project-list·
       search/index 등 다수 화면 공용) 전용 토큰으로 유지한다. */
    --mili-search-bg: var(--mili-neutral-870);
    --mili-search-border: var(--mili-neutral-750);

    /* ---------- 드롭다운 메뉴 "선택됨"/"호버" 항목 배경 ----------
       2026-09-22 재실측(강의/프로젝트 목록 실제 화면 node 4038:312653/4038:312771의 정렬
       드롭다운 인스턴스, get_design_context — Selected 버튼 bg 직접 대조) — 2026-08-25
       라운드(node 2224:106600, 별도 "드롭다운" 컴포넌트 시트)는 재설계 이전 값이었다.
       실제 화면 노드는 Selected 배경이 Primary/800/100 이 아니라 Primary/500 그대로다
       (다크 #85f686·라이트 #1a987f — 둘 다 --mili-primary-500 자체와 정확히 일치).
       유일한 소비처는 .mili-sort-dropdown__menu .dropdown-item.active 뿐이다(로드맵 패널은
       이 토큰을 실제로 쓰지 않는다, 2026-09-22 재확인). */
    --mili-dropdown-selected-bg: var(--mili-primary-500);

    /* 2026-09-22 2차 재실측(node 4839:188481 "강의" 목록 정렬 드롭다운 인스턴스, 사용자 제공
       링크 — Hover/Default 상태 각각 get_design_context 로 확인) — 이전 라운드(node
       4038:312653/4038:312771)는 항목이 하나만 열린 상태를 봐서 "최신순"(호버 안 된 기본
       항목)을 hover 색으로 잘못 짚었다. 실제로는 기본(미호버) 항목이 Neutral/850(#1c1f23,
       메뉴 패널 --mili-bg 의 Neutral/900 #0e1013 보다 한 단 밝다 — 그래서 전용 토큰이 필요),
       호버 항목(마우스 커서가 얹힌 "가나다순")이 Neutral/800(#2b2e33)이다. */
    --mili-dropdown-bg: var(--mili-neutral-850);

    /* 범용 --mili-surface-hover(다크 Neutral/800 #2b2e33)와 값 자체는 같아졌지만, 다른
       화면(로드맵·PBL work 등)까지 같이 바뀌는 걸 막기 위해 컴포넌트 전용 토큰은 유지한다. */
    --mili-dropdown-hover-bg: var(--mili-neutral-800);

    /* ---------- 페이지네이션 전용 글자색·hover·active 배경/테두리 ----------
       Figma "Pagination" 컴포넌트(8qAqeXw50F8GKDGkeW0Pua) 실측.

       2026-08-27 개정 — 시안이 node 2051:218395 → 2051:218398 로 바뀌면서 hover·active 가
       <b>라임 브랜드에서 중성(Neutral) 팔레트로</b> 교체됐다(사용자 확인). 이전 값은
       hover Neutral/800 · active bg Primary/900 + border Primary/500 이었다.
       바뀐 것은 색뿐이고 40×40 · 반경 5px · 간격 12px · 16px 라는 기하값은 그대로다.

       새 값은 전부 primitives.css 의 Neutral 램프에 그대로 있어 새 hex 를 만들지 않는다.
       글자색을 --mili-ink 로 두지 않고 전용 토큰을 신설한 이유 — 시안의 기본 숫자는 다크
       Neutral/50(#ffffff)로 --mili-ink 다크(#F8F9FA)보다 한 단계 밝고, 라이트는
       Neutral/900(#0E1013)로 --mili-ink 라이트(#1E2227)와 아예 다르다. */
    --mili-pagination-fg: var(--mili-neutral-50);          /* 기본 숫자 */
    --mili-pagination-on: var(--mili-neutral-100);         /* hover·active 숫자 */
    --mili-pagination-hover-bg: var(--mili-neutral-850);
    --mili-pagination-active-bg: var(--mili-neutral-850);
    --mili-pagination-active-border: var(--mili-neutral-500);

    /* ---------- 리스트(게시판) 메타 정보(작성자·댓글·날짜) 전용 색 ----------
       Figma "List" 컴포넌트(8qAqeXw50F8GKDGkeW0Pua, node 2058:219171 등, 2026-08-26 사용자
       확인) 실측 — Neutral/500. 기존 --mili-fg-faint(전역 공유 토큰, 다크 #737373)와 값이 달라
       .post-row__date 전용 토큰으로 신설한다(전역 --mili-fg-faint 는 그대로 둔다). */
    --mili-list-meta: var(--mili-neutral-500);

    /* ---------- 홈 CTA 버튼 색(중성 팔레트) ----------
       Figma 재실측(8qAqeXw50F8GKDGkeW0Pua, node 2224:105165, 2026-08-24): 홈 로그인/이어서 학습
       버튼이 라임 브랜드색이 아니라 이 흑백 계열을 쓴다(get_variable_defs 실측: Neutral/50·300·950·500).
       2026-08-31: 홈도 라이트 모드를 지원하게 되어 라이트 값은 아래 2') 블록에 짝으로 둔다.
       적용 범위는 home.css 가 지목한 버튼(로그인·회원가입·이어서 학습)으로 한정한다 — 다른 accent
       버튼(강의 둘러보기 등)은 기존 라임(--mili-brand)을 그대로 쓴다. */
    --mili-btn-light-bg: var(--mili-neutral-50);
    --mili-btn-light-border: var(--mili-neutral-300);
    --mili-btn-light-on: var(--mili-neutral-950);
    --mili-btn-dark-border: var(--mili-neutral-500);
    --mili-btn-dark-on: var(--mili-neutral-500);
}

/* 1') 위 "테마 무관" 절 중 실제로는 테마를 타야 하는 4개 재선언 — 2026-09-18 2차 수정(사용자 확인).
   --mili-lime-300/-400·--mili-stat-mission/-xp 는 위 :root 에서 var(--mili-primary-NNN)을
   참조하므로, primitives.css 가 :root/.mili-light 양쪽에 그 스텝을 따로 갖고 있어도 이
   4개 프로퍼티 자체를 .mili-light 에서 다시 선언해 둬야 라이트 캔버스에서도 정확히 라이트
   스텝으로 치환된다(§2/2' 상단의 커스텀 프로퍼티 치환 시점 주석과 같은 이유 — 안전하게
   양쪽 스코프에 명시적으로 선언). */
.mili-light {
    --mili-lime-300: var(--mili-primary-500);
    --mili-lime-400: var(--mili-primary-400);
    --mili-stat-mission: var(--mili-primary-400);
    --mili-stat-xp: var(--mili-primary-500);
}

/* ============================================================
   2) 파생값 + 별칭 — 다크(기본)
   ============================================================ */
:root {
    /* 기본 스크롤바가 다크를 따라오게 한다(color-scheme 은 tokens.css 가 :root 에 건다). */
    scrollbar-color: var(--mili-border-strong) var(--mili-app-bg);

    /* ---------- 표면 별칭 ---------- */
    --mili-canvas: var(--mili-app-bg);
    --mili-bg: var(--mili-app-bg);
    --mili-panel: var(--mili-surface);
    --mili-panel-raised: var(--mili-surface-raised);
    --mili-panel-sunken: var(--mili-app-bg);   /* 패널 안에 파인 영역 — 판보다 어둡다 */
    /* 게시글 목록 줄(.post-row, components.css 23-2절) hover 배경.
       Figma "List" 컴포넌트(8qAqeXw50F8GKDGkeW0Pua, node 2058:219171) 실측 Neutral/800. */
    --mili-surface-hover: var(--mili-neutral-800);

    /* ---------- 전경 별칭 ---------- */
    --mili-fg: var(--mili-text);
    --mili-ink: var(--mili-text);
    --mili-fg-body: var(--mili-text-secondary);
    --mili-body: var(--mili-text-secondary);
    --mili-fg-muted: var(--mili-text-muted);
    --mili-muted: var(--mili-text-muted);
    --mili-fg-faint: #737373;                  /* 참고에 4단계가 없어 우리가 유지한다 */

    /* ---------- 경계 별칭 ---------- */
    --mili-line: var(--mili-border);
    --mili-line-strong: var(--mili-border-strong);

    /* ---------- 브랜드색 오버라이드(다크) ----------
       tokens.css(참고 이식본)의 다크 --mili-primary(#B4FF39)는 2026-09-18 Figma Color
       노드(8qAqeXw50F8GKDGkeW0Pua, 2107:269442) 전면 재개편으로 더 이상 정본이 아니다 —
       라임에서 민트그린으로 색상군 자체가 바뀌었다(Primary-Dark/500 실측 #85F686).
       tokens.css 는 손대지 않는 관행이라 여기서 덮는다.

       -strong/-bg/-border/-on 파생값은 이 Color 스펙시트에 정확히 대응하는 스와치가 없다
       (Default/Hover1/Hover2 서브스와치가 옛 리터럴 그대로 남아 있어 참고 불가) — 대신 옛
       tokens.css 리터럴이 옛 스케일의 어느 스텝에 가장 가까웠는지 유클리드 거리로 역산해
       같은 스텝의 새 값으로 옮긴다(옛 #C7FF68≈옛 400 → 새 400 #98F998, 옛 #2D4511≈옛 900 →
       새 900 #2B9350, 옛 #79AB25≈옛 700 → 새 700 #62CD6F). -on 은 스케일에 대응이 없는
       순수 잉크색이라 --mili-neutral-900 을 그대로 쓴다. 실제 버튼 컴포넌트 노드를 재실측한
       값이 아닌 근사치다(docs/design/figma-common/01-color.md 참고).
       값 전부가 primitives.css 스케일의 정확한 스텝과 일치해 리터럴 대신 var() 로 참조한다
       (로드 순서 tokens→primitives→variables→components 라 여기서 참조 가능, 2026-09-18). */
    --mili-primary: var(--mili-primary-500);
    --mili-primary-strong: var(--mili-primary-400);
    --mili-primary-bg: var(--mili-primary-900);
    --mili-primary-border: var(--mili-primary-700);
    --mili-primary-on: var(--mili-neutral-900);
    --mili-focus: var(--mili-primary-400);     /* tokens.css 의 다크 --mili-focus(#C7FF68)와 같은 스텝(400) */

    /* ---------- 브랜드 별칭 ---------- */
    --mili-brand: var(--mili-primary);
    --mili-brand-strong: var(--mili-primary-strong);
    --mili-brand-bg: var(--mili-primary-bg);
    --mili-brand-border: var(--mili-primary-border);
    --mili-brand-on: var(--mili-primary-on);
    --mili-brand-soft: rgba(133, 246, 134, 0.08);   /* = --mili-primary #85F686 의 8%(2026-09-18 재개편) */
    --mili-radar-fill: rgba(133, 246, 134, 0.08);   /* 스킬 스파이더 차트(js/common/multi-radar.js) 채우기 전용 — --mili-brand-soft 와 값은 같지만 배지·hover 등과 분리해 독립 조정 */
    /* 2026-09-04 Figma 재확인(8qAqeXw50F8GKDGkeW0Pua, node 3249:63731 마이페이지 대시보드
       라이트) — 스파이더 차트 선·포인트는 라이트에서도 --mili-primary(뮤트 올리브)로 바뀌지
       않고 다크와 같은 선명한 브랜드색 그대로다. --mili-brand 를 직접 바꾸면 버튼·배지 등 다른
       요소까지 전부 뒤집히므로, 차트 전용 토큰을 신설해 두 테마 모두 같은 값을 준다
       (multi-radar.js 가 --mili-brand 대신 이 토큰을 읽도록 변경). 2026-09-18 재개편으로
       라임(#B4FF39) → 민트그린(#85F686, Primary-Dark/500)으로 갱신. */
    --mili-radar-line: #85F686;
    /* 격자·축선 전용 — 기본(다크)은 전역 --mili-border 와 같다. 라이트는 아래 .mili-light
       블록에서 별도 값으로 덮는다(2026-09-04, 사용자 지적 — 라이트에서 격자선이 카드 배경과
       거의 안 갈릴 만큼 옅었다. 전역 --mili-border(#DEE2E6)는 일반 테두리용으로는 적절하지만
       차트 격자에는 너무 옅다). */
    --mili-radar-grid: var(--mili-border);

    /* ---------- 상태 별칭 ----------
       참고는 -bg 로, 우리는 -soft 로 불러 왔다. 값을 두 벌로 두면 한쪽만 고치는 사고가 난다. */
    --mili-danger: var(--mili-error);
    --mili-success-soft: var(--mili-success-bg);
    --mili-danger-soft: var(--mili-error-bg);

    /* ---------- -rgb 짝 ----------
       Bootstrap 과 글래스 표면이 rgba(var(--x-rgb), .5) 형태로 쓴다.
       color-mix() 는 정부망 구형 브라우저 호환 리스크가 있어 hex 와 손으로 맞춘다.
       ⚠️ tokens.css 의 대응 hex 를 바꾸면 여기도 함께 고쳐야 한다. */
    --mili-canvas-rgb: 14, 16, 19;             /* --mili-app-bg        #0E1013 */
    --mili-fg-rgb: 248, 249, 250;              /* --mili-text          #F8F9FA */
    --mili-fg-body-rgb: 173, 181, 189;         /* --mili-text-secondary #ADB5BD */
    --mili-line-rgb: 43, 48, 54;               /* --mili-border        #2B3036 */
    --mili-brand-rgb: 133, 246, 134;           /* --mili-primary       #85F686(2026-09-18 재개편, 위 오버라이드) */
    --mili-brand-strong-rgb: 152, 249, 152;    /* --mili-primary-strong #98F998(2026-09-18 재개편, 위 오버라이드) */
    --mili-brand-on-rgb: 24, 33, 14;           /* --mili-primary-on    #18210E */
    --mili-text-muted-rgb: 134, 142, 150;      /* --mili-text-muted    #868E96 */
    --mili-focus-rgb: 152, 249, 152;           /* --mili-focus         #98F998(2026-09-18 재개편, 위 오버라이드) */

    /* ---------- 오버레이 · 그림자 ----------
       검정 배경에서는 옅은 그림자가 보이지 않으므로 더 깊게 준다. */
    --mili-overlay: rgba(0, 0, 0, 0.6);
    --mili-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --mili-shadow: 0 12px 32px rgba(0, 0, 0, 0.38);
    --mili-shadow-lg: 0 28px 90px rgba(0, 0, 0, 0.45);

    /* ---------- 학습 활동 잔디 히트맵 5단계 ---------- */
    --mili-heat-0: rgba(255, 255, 255, 0.06);
    --mili-heat-1: #274d0a;
    --mili-heat-2: #4c8a12;
    --mili-heat-3: #7fc617;
    --mili-heat-4: var(--mili-primary);

    /* ---------- 코드 에디터·콘솔 팔레트(학습 플레이어) ----------
       다크 셸에서는 셸 자체가 검정이라 같은 계조를 쓰지 않으면 에디터만 다른 재질로 떠 보인다. */
    --mili-code-bg: var(--mili-app-bg);
    --mili-code-surface: var(--mili-surface-raised);
    --mili-code-border: var(--mili-border-strong);
    --mili-code-text: var(--mili-text);
    --mili-code-muted: var(--mili-text-muted);
    --mili-code-accent: var(--mili-primary);
}

/* ============================================================
   2') 파생값 + 별칭 — 라이트
   ------------------------------------------------------------
   ⚠️ 위 블록과 항목이 1:1 로 대응해야 한다. 한쪽에만 추가하면 그 토큰은 테마를 타지 않는다.
   ============================================================ */
.mili-light {
    /* 참고 globals.css:248 이 .mili-light 에 거는 값. tokens.css 는 원본 그대로 두려고 여기에 둔다. */
    color-scheme: light;
    scrollbar-color: var(--mili-border-strong) var(--mili-app-bg);

    /* ---------- 라이트 브랜드색 오버라이드 ----------
       tokens.css(참고 이식본)의 라이트 --mili-primary 는 #618F20 인데, Figma 정본
       (8qAqeXw50F8GKDGkeW0Pua, QA28 node 1743:2611 Light/Large/Primary 버튼) 원본 에셋을
       픽셀 단위로 대조하면 #9FE970 이다(Main_LightMode 변수와도 일치). tokens.css 는 손대지
       않는 관행이라 여기서 덮는다(2026-08-13 사용자 확인).
       secondary 테두리 등 파생 상태(hover 포함)는 아직 실측 전이라 3단계(컴포넌트 재정립)에서
       마저 확인한다 — 지금은 --mili-primary 와 그 -rgb 짝만 바꾼다.
       --mili-primary-on 도 함께 덮는다 — tokens.css 의 흰색은 옛 어두운 초록(#618F20) 배경 기준값이라
       밝은 연두(#9FE970) 위에서는 대비가 낮다. Figma 실측(QA28 Light/Primary 버튼 글자)은 검정이다
       (2026-08-15 QA28 재확인).
       2026-08-24 재정정: VOD 목록 시안(node 2178:36322, get_variable_defs)의 레벨탭·분야칩
       활성색은 `Primary/600 #91cc5c`다 — 위 QA28 버튼 실측(#9FE970)과 다른 값이다. 버튼 전용
       실측이 아니라 시안 변수 정의(Primary/600)가 더 정본에 가깝다고 보고 이걸로 맞춘다
       (사용자 확인). hover/strong 파생값은 이번엔 재실측하지 않아 기존 값을 유지한다 —
       버튼 hover(#8bd85c 리터럴, catalog-list.css)가 새 기본색과 잘 어울리는지는 미검증.

       2026-09-18 재개편 — Figma Color 노드가 라임→민트그린으로 전면 교체되며 "Primary_Light"
       램프도 완전히 다른 색(민트→딥그린 티일, #e0f2ef~#064f3a)이 됐다. 옛 관례처럼 같은
       "600번" 스텝(#178B73)을 그대로 옮기면 명도가 급격히 어두워져(라이트 텍스트/블랙 온컬러
       버튼 전제가 깨짐 — 대비 계산상 흰 글자가 필요해진다) 기존 버튼·탭 컴포넌트의 검정 글자
       전제와 충돌한다. 옛 #91CC5C(WCAG 상대휘도 0.50)와 명도가 가장 가까운 스텝은 "Primary/200"
       (#83CCBE, 상대휘도 0.52)이라 이걸 임시로 쓴다 — 실제 버튼·탭 컴포넌트 노드를 다시 실측하기
       전까지의 명도-매칭 근사치다(대응 컴포넌트 노드 재확인 필요).

       -strong/-bg/-border 는 다크와 같은 방식(옛 tokens.css 리터럴이 옛 라이트 스케일의 어느
       스텝에 가장 가까웠는지 역산 후 같은 스텝의 새 값으로 교체)으로 같이 갱신한다 — 옛
       #4D731B≈옛 900 → 새 900 #064F3A, 옛 #E8F8C8≈옛 200 → 새 200 #83CCBE(공교롭게 위
       --mili-primary 와 같은 스텝), 옛 #94C83A≈옛 600 → 새 600 #178B73. 전부 실제 컴포넌트
       노드 재실측 전 근사치다.
       값 전부가 primitives.css 라이트 스케일의 정확한 스텝과 일치해 리터럴 대신 var() 로
       참조한다(2026-09-18). */
    --mili-primary: var(--mili-primary-200);
    --mili-primary-strong: var(--mili-primary-900);
    --mili-primary-bg: var(--mili-primary-200);
    --mili-primary-border: var(--mili-primary-600);
    --mili-primary-on: var(--mili-neutral-950);
    --mili-focus: var(--mili-primary-700);     /* tokens.css 의 라이트 --mili-focus(#78AE28, 옛 700)와 같은 스텝(700) */

    /* 검색창 전용 배경·보더 라이트 값(Neutral/100·400) — 위 다크 정의와 짝. */
    --mili-search-bg: var(--mili-neutral-100);
    --mili-search-border: var(--mili-neutral-400);

    /* 로그인 화면 좌측 비주얼 라이트 값 — 2026-09-08, 라이트 시안이 아직 없어 다크(블랙+네온그린)를
       대칭 반전한 1차 추정치다(연한 라임 톤). 실제 Figma 라이트 시안이 나오면
       docs/dev-notes 원칙대로 노드 단위 재실측이 필요하다.
       2026-09-18 재개편 — 브랜드색이 라임→민트그린으로 바뀌어 톤도 같이 옮긴다. 새 라이트
       Primary/500(#1A987F)를 흰색에 3/10/15% 로 블렌드해 같은 방식으로 재유도(정식 실측 아님). */
    --mili-login-visual: linear-gradient(160deg, #F8FCFB 0%, #E8F5F2 55%, #DDF0EC 100%);

    /* 드롭다운 메뉴 "선택됨"/"호버" 항목 배경 라이트 값 — 위 다크 정의와 짝, 같은 2026-09-22
       재실측(node 4038:312667 정렬 드롭다운 인스턴스). Selected 배경은 Primary/100 이 아니라
       Primary/500(#1a987f) 그대로다. */
    --mili-dropdown-selected-bg: var(--mili-primary-500);

    /* 2026-09-22 2차 재실측(node 4839:188289 "강의" 목록 정렬 드롭다운 인스턴스) — 기본
       항목은 Neutral/50(#ffffff, 메뉴 패널 --mili-bg 의 라이트 값과 정확히 같아 위 다크와
       달리 전용 토큰 없이도 맞지만, 다크와 짝을 맞추려 --mili-dropdown-bg 로 명시한다),
       호버 항목("가나다순")은 Neutral/200(#f3f3f3)이다. */
    --mili-dropdown-bg: var(--mili-neutral-50);

    /* 범용 --mili-surface-hover(라이트 Neutral/300 #f0f0f0)와 한 단 어긋나 이 컴포넌트
       전용 토큰을 따로 둔다. */
    --mili-dropdown-hover-bg: var(--mili-neutral-200);

    /* 페이지네이션 라이트 값 — 위 다크 정의와 짝(node 2051:218398, 2026-08-27 개정).
       라이트는 기본·hover·active 글자가 전부 Neutral/900 한 가지다(다크만 기본 Neutral/50 ·
       hover/active Neutral/100 로 갈린다). active 는 hover 와 같은 배경에 Neutral/900 테두리만
       더해 구분한다 — 이전의 라임 배경(#EDF8E1)+라임 테두리(#AFE57E)를 대체한다. */
    --mili-pagination-fg: var(--mili-neutral-900);
    --mili-pagination-on: var(--mili-neutral-900);
    --mili-pagination-hover-bg: var(--mili-neutral-100);
    --mili-pagination-active-bg: var(--mili-neutral-100);
    --mili-pagination-active-border: var(--mili-neutral-900);

    /* 리스트 메타 정보 색 라이트 값(Neutral/750) — 위 다크 정의와 짝. */
    --mili-list-meta: var(--mili-neutral-750);

    --mili-canvas: var(--mili-app-bg);
    --mili-bg: var(--mili-app-bg);
    --mili-panel: var(--mili-surface);
    --mili-panel-raised: var(--mili-surface-raised);
    --mili-panel-sunken: var(--mili-surface-interactive);
    /* Figma "List" 컴포넌트(8qAqeXw50F8GKDGkeW0Pua, node 2058:219171) 실측 Neutral/300. */
    --mili-surface-hover: var(--mili-neutral-300);

    --mili-fg: var(--mili-text);
    --mili-ink: var(--mili-text);
    --mili-fg-body: var(--mili-text-secondary);
    --mili-body: var(--mili-text-secondary);
    --mili-fg-muted: var(--mili-text-muted);
    --mili-muted: var(--mili-text-muted);
    --mili-fg-faint: #9aa1ad;

    --mili-line: var(--mili-border);
    --mili-line-strong: var(--mili-border-strong);

    --mili-brand: var(--mili-primary);
    --mili-brand-strong: var(--mili-primary-strong);
    --mili-brand-bg: var(--mili-primary-bg);
    --mili-brand-border: var(--mili-primary-border);
    --mili-brand-on: var(--mili-primary-on);
    --mili-brand-soft: var(--mili-primary-bg);
    --mili-radar-fill: rgba(131, 204, 190, 0.12);  /* = --mili-primary #83CCBE 의 12%(2026-09-18 재개편) — --mili-primary-bg(불투명, 미재측정)를 쓰면 격자선이 안 비쳐 답답해 보였다 */
    /* 2026-09-04 Figma 재확인(node 3249:63731) — 격자·축선 실측이 Neutral/700(#66686C) 대다.
       전역 --mili-border(#DEE2E6)를 그대로 쓰면 카드 배경과 거의 안 갈렸다(사용자 지적). */
    --mili-radar-grid: var(--mili-neutral-700);

    --mili-danger: var(--mili-error);
    --mili-success-soft: var(--mili-success-bg);
    --mili-danger-soft: var(--mili-error-bg);

    --mili-canvas-rgb: 255, 255, 255;          /* --mili-app-bg        #FFFFFF (2026-08-24 bg/GNB 스왑 수정) */
    --mili-fg-rgb: 30, 34, 39;                 /* --mili-text          #1E2227 */
    --mili-fg-body-rgb: 92, 99, 107;           /* --mili-text-secondary #5C636B */
    --mili-line-rgb: 222, 226, 230;            /* --mili-border        #DEE2E6 */
    --mili-brand-rgb: 131, 204, 190;           /* --mili-primary       #83CCBE(2026-09-18 재개편, 위 오버라이드) */
    --mili-brand-strong-rgb: 6, 79, 58;        /* --mili-primary-strong #064F3A(2026-09-18 재개편, 위 오버라이드) */
    --mili-brand-on-rgb: 0, 0, 0;              /* --mili-primary-on    #000000 */
    --mili-text-muted-rgb: 134, 142, 150;      /* --mili-text-muted    #868E96 */
    --mili-focus-rgb: 19, 123, 99;             /* --mili-focus         #137B63(2026-09-18 재개편, 위 오버라이드) */

    --mili-overlay: rgba(30, 34, 39, 0.5);
    --mili-shadow-sm: 0 1px 2px rgba(30, 34, 39, 0.06);
    --mili-shadow: 0 8px 24px rgba(30, 34, 39, 0.08);
    --mili-shadow-lg: 0 16px 40px rgba(30, 34, 39, 0.12);

    /* 2026-08-13 정정: 라이트에서 중성 파랑 계조를 쓰던 이전 판단(Figma 노드 인용 없이 "브랜드가
       아니라 데이터 램프"라는 추정만으로 정한 값 — 참고 저장소에도 같은 값이 있었지만 그쪽도
       근거가 같다) 이 다크(브랜드 그린)와 테마마다 색상 자체가 달라 보인다는 지적을 받았다.
       기존 라이트 브랜드 그린 토큰만으로 자연스러운 농도 단계가 이미 있어 새 리터럴 없이
       구성한다 — 흰 배경에서는 진할수록 강조가 커지므로 dark 와 반대로 어두운 쪽이 4단계다. */
    --mili-heat-0: #eef1f6;
    --mili-heat-1: var(--mili-primary-bg);
    --mili-heat-2: var(--mili-primary);
    --mili-heat-3: var(--mili-primary-border);
    --mili-heat-4: var(--mili-primary-strong);

    /*
     * 라이트 셸에서 에디터·콘솔은 "흰 판 위에 얹힌 다크 섬"이라 셸과 무관한 독자 계조를 쓴다.
     * ⚠️ 이 토큰은 PBL 코딩 화면(work.css .work-code)뿐 아니라 .mili-rich/.mili-editor__surface
     * pre(게시글·문제 지시문 등에 박힌 코드 블록, components.css)도 함께 쓴다 — 여기서 라이트를
     * 따르게 바꾸면 그 코드 블록들도 전부 바뀐다. PBL 코딩 화면만 라이트를 따르게 하려면
     * work.css 의 .work-code 스코프에서 이 토큰들을 새로 별칭한다(2026-08-14).
     */
    --mili-code-bg: #10131a;
    --mili-code-surface: #171b24;
    --mili-code-border: #2a3040;
    --mili-code-text: #e6e9f0;
    --mili-code-muted: #8b93a7;
    --mili-code-accent: #6ea8ff;

    /* ---------- 홈 CTA 버튼 색(중성 팔레트) 라이트 값 ----------
       ⚠️ 2026-09-01 재정정(get_design_context, node 3397:61445/61446/61447 "로그인"/"회원가입"
       버튼 실측) — 2026-08-31 최초 값은 시안 없이 다크를 대칭 반전한 추정치였다.
       로그인(accent): bg Neutral/950(#000000) · border Neutral/870(#15181c) · 글자 흰색.
       회원가입(ghost): bg Neutral/50(흰색, 기존 --mili-sidebar-bg 로 이미 근사) ·
       border Neutral/550(#bfc0c2) · 글자 Neutral/800(#2b2e33). */
    --mili-btn-light-bg: var(--mili-neutral-950);
    --mili-btn-light-border: var(--mili-neutral-870);
    --mili-btn-light-on: var(--mili-neutral-50);
    --mili-btn-dark-border: var(--mili-neutral-550);
    --mili-btn-dark-on: var(--mili-neutral-800);
}

/* ============================================================
   3) Bootstrap 루트 변수 재바인딩
   ------------------------------------------------------------
   bootstrap.css 의 body/.btn/.card/.form-control 등은 아래 --bs-* 를 var() 로 그대로 참조하므로
   스코프마다 한 번씩 걸면 전역에 반영된다.
   ⚠️ 여기도 :root 와 .mili-light 양쪽에 걸어야 한다(파일 상단 주석 참고).
   ============================================================ */
:root,
.mili-light {
    --bs-body-font-family: var(--mili-font-sans);
    --bs-body-color: var(--mili-text-secondary);
    --bs-body-color-rgb: var(--mili-fg-body-rgb);
    --bs-body-bg: var(--mili-app-bg);
    --bs-emphasis-color: var(--mili-text);
    --bs-emphasis-color-rgb: var(--mili-fg-rgb);
    --bs-secondary-color: var(--mili-text-muted);
    --bs-border-color: var(--mili-border);

    /* Bootstrap 컴포넌트(.btn/.card/.form-control/.alert/.modal…)는 자기 반경을 이 변수로 읽는다.
       참고는 [class*="rounded-"] 를 전역 0 으로 눕히는데, 우리 쪽 등가물이 이 다섯 줄이다.
       --bs-border-radius-pill 은 건드리지 않는다(검색 입력·뱃지가 쓴다). */
    --bs-border-radius: 0;
    --bs-border-radius-lg: 0;
    --bs-border-radius-sm: 0;
    --bs-border-radius-xl: 0;
    --bs-border-radius-xxl: 0;

    --bs-link-color: var(--mili-primary);
    --bs-link-color-rgb: var(--mili-brand-rgb);
    --bs-link-hover-color: var(--mili-primary-strong);
    --bs-link-hover-color-rgb: var(--mili-brand-strong-rgb);
}
