/* web/static/tokens.css -- 디자인 토큰 단일 정의 (R7A, 2026-07-18)
   시스템: 검증 원장(ledger of evidence). 웜 스톤 틴트 뉴트럴 지면 + 흰 카드 서피스 +
   인디고 브랜드색(행동·정보 공용). 지면·텍스트는 뉴트럴, 색은 상태·액션·
   브랜드 포인트에만 쓴다.
   [W-PR2 웜 스톤 시프트 2026-09-09] 지면 뉴트럴을 순뉴트럴(zinc)에서 웜 스톤으로
   옮겼다. 사유는 장식이 아니라 원칙이다 — docs/design-principles.md 원칙 4
   "액센트 1색, 지면은 틴트 뉴트럴": 등간격 무채색(#nnn)은 라이브러리 기본값의
   지문이라 어느 SaaS와도 구분되지 않는다. 미색 캔버스가 "종이 원장" 은유를
   완성한다. **액센트·의미 채널(방향·판정·상태·주목 램프)은 값 불변**이고 새
   지면 위 대비만 재실측했다(아래 각 값 옆 주석이 그 실측이다).
   [v2 색복원 2026-09-05] PR-2 의 "잉크 프라이머리(행동) / 인디고 액센트(정보)"
   2색 분리는 **철회**됐다. 전면이 흑백으로 읽힌다는 Kevin 반려 — 잉크 CTA +
   사진 무채화가 겹쳐 브랜드색이 화면에서 사라졌다. --primary 는 다시 --accent
   별칭이고, 인디고가 CTA·활성 탭·링크를 함께 진다.
   SSOT 분담: 이 파일 = 지면·타이포·간격·라운딩·그림자 토큰.
             web/palette.py = 차트·의미색 (--color-*, dist/static/palette.css).
   로드 순서: tokens.css -> (palette.css, 어드민만) -> style.css/app.css/admin.css.
   구 계약 호환: --bg --panel --paper --ink --sub --line --accent
   --accent-soft --sans --mono 이름 유지. --serif 는 삭제 (참조 금지). */

/* -- 자체 호스팅 폰트 (OFL) -- 서브셋 woff2, CDN 아님 -- */
@font-face {
  font-family: "Pretendard Variable";
  src: url("/static/fonts/PretendardVariable-sub.ee12fffc042b.woff2") format("woff2");
  font-weight: 45 920;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("/static/fonts/JetBrainsMono-sub.588d538906ed.woff2") format("woff2");
  font-weight: 100 800;
  font-display: swap;
}

:root {
  color-scheme: light dark;

  /* 지면 -- 웜 스톤 틴트 뉴트럴 (구 zinc). R>G>B 로 미색을 유지한다 */
  --bg: #f8f7f4;            /* 캔버스 -- 미색, "종이 원장" */
  --surface: #ffffff;       /* 카드 서피스 -- 흰색 유지(대비 기준면 불변) */
  --panel: #f2f0ec;         /* 인셋 패널·행 hover */
  --paper: #ffffff;         /* 차트 지면 -- 다크에서도 밝게 (SVG 고정색 가독) */

  /* 텍스트 */
  --ink: #1a1815;           /* 웜 블랙. 17.72:1 on surface, 16.54:1 on bg, 15.56:1 on panel */
  --sub: #57534e;           /* 7.63:1 on surface, 7.12:1 on bg, 6.70:1 on panel */

  /* 보더 -- 웜 헤어라인 */
  --line: #e8e5df;
  --line-strong: #d8d3ca;

  /* 액센트 (인디고 -- DIRECTION 적/청과 충돌하지 않는 제3색). 브랜드색이자
     인터랙션 색이다: 주 CTA·활성 탭·링크 hover·데이터 하이라이트·포커스 링.
     OG 이미지·브랜드 마크와 같은 계열이라 제품 밖 표면과도 정합.
     [v2] "정보 전용" 축소는 철회 — 행동도 인디고가 진다. */
  --accent: #4f46e5;        /* 6.29:1 on surface, 5.87:1 on bg, 5.52:1 on panel (W-PR2 재실측) */
  --accent-strong: #4338ca; /* hover·active, 7.90:1 on surface */
  --accent-soft: #eef0fe;   /* 틴트 배경 -- accent 텍스트 5.55:1, accent-strong 6.97:1 */
  --accent-ink: #ffffff;    /* on accent, 6.29:1 */

  /* 구성 세그먼트 사다리 (기업 개요 "무엇으로 벌까요"·"번 돈은 어디로 갈까요"
     스택/절대금액 바 + 그 범례 스와치). 소비는 style.css `.mix-seg-N`.

     왜 색이 붙는가 — 구 구현은 `--ink` 불투명도 사다리(.82→.07)라 8단이 전부
     무채 회색이었고, 말단 두 단(.12/.07)은 --panel 위에서 사실상 안 보였다
     (Kevin 실사용 반려: "bar 색깔이 흑백이라 알아보기 힘들어"). 세그먼트 구분은
     **정보**이므로 색 사용이 정당하다(디자인 원칙 4 "색은 정보에만"). 다만 신규
     hue 는 0개다 — 전 단이 브랜드 인디고(--accent h≈302.6 in CIELab) 단일
     계열이고, 구분은 색상이 아니라 **명도**가 진다. 무지개 다색 금지 유지.

     방향·판정 의미 없음. index 는 원문 공시 순서(폭 순 아님)이고 순서 인코딩일
     뿐이다 — 색으로 좋고 나쁨을 말하지 않는다(앰버·방향색 금지 규율 그대로).

     색맹 대비 — 인접 단 ΔL* ≥ 7.5(최소 3→4 의 7.5), 인접 대비비 ≥ 1.26. 단일
     hue 사다리라 색상 정보를 전부 지워도(회색조 변환) 8단이 그대로 남는다.

     말단(8단)은 뉴트럴이다(웜 지면과 같은 계열의 저채도 C=4 — 무채 회색을 쓰면
     웜 지면 위에서 푸른 기로 뜬다. --lit-quiet 재파생과 같은 규율). "기타"류
     잔여 항목이 마지막에 오는 관례를 받되 **라벨로 분류하지 않는다** — 실측
     (forward/company_profiles 446개 mix) 상 '기타' 문자열 보유 240건 중 36건은
     마지막이 아니고, '기타자동차부품'·'감가상각비·기타상각비'처럼 실명 부문도
     substring 에 걸린다. 실명 부문을 잔여로 오표기하는 손해가 이득보다 크다.
     뉴트럴은 사다리의 L* 슬롯을 그대로 지키므로(라이트 81.1 / 다크 25.0) 명도
     단조성과 위 색맹 대비 주장은 깨지지 않는다.

     -fg = 그 단 위에 얹히는 온-바 % 오버레이(.seg-num) 글자색. 어두운 단은 흰
     글자, 밝은 단은 잉크. 전 단 ≥ 4.5:1 (아래 실측). 사다리가 L*≈50 부근을
     비켜 가는 것은 의도다 — 그 명도대는 흰 글자·검은 글자 어느 쪽도 4.5:1 에
     못 미치는 사각지대다(이론 최댓값 4.34:1).

     아래 실측은 라이트 지면 --panel(#f2f0ec) 기준이다. 바는 aria-hidden 장식이고
     정보 정본은 범례 텍스트라 세그먼트-지면 대비에 AA(3:1) 를 요구하지 않는다 —
     요구하면 8단이 3:1 안으로 압축돼 인접 ΔL 이 죽는다. 다만 말단이 지면에 녹아
     사라지던 구 결함은 재발 금지이고, 8단 vs panel 1.45:1 이 그 하한이다. */
  --mix-seg-1: #3b3084;     /* L*25.9 · on panel 9.50:1, surface 10.81:1 */
  --mix-seg-2: #4239bc;     /* L*33.4 · on panel 7.26:1 */
  --mix-seg-3: #5147e3;     /* L*40.9 · on panel 5.49:1 (--accent 와 동급 명도) */
  --mix-seg-4: #735fe5;     /* L*48.9 · on panel 4.10:1 */
  --mix-seg-5: #8e78e4;     /* L*56.9 · on panel 3.10:1 */
  --mix-seg-6: #a690e9;     /* L*64.9 · on panel 2.37:1 */
  --mix-seg-7: #bca8f1;     /* L*72.9 · on panel 1.84:1 */
  --mix-seg-8: #cdc9c2;     /* L*81.1 · on panel 1.45:1 — 말단 웜 뉴트럴(C=4) */
  --mix-seg-1-fg: #ffffff;  /* on seg-1, 10.81:1 */
  --mix-seg-2-fg: #ffffff;  /* on seg-2,  8.26:1 */
  --mix-seg-3-fg: #ffffff;  /* on seg-3,  6.25:1 */
  --mix-seg-4-fg: #ffffff;  /* on seg-4,  4.67:1 */
  --mix-seg-5-fg: #1a1815;  /* on seg-5,  5.03:1 */
  --mix-seg-6-fg: #1a1815;  /* on seg-6,  6.57:1 */
  --mix-seg-7-fg: #1a1815;  /* on seg-7,  8.44:1 */
  --mix-seg-8-fg: #1a1815;  /* on seg-8, 10.74:1 */

  /* 노출 주목 세기 램프 (조용→조명, P-explore-redesign) — 판정/방향색 아님, 서수 인코딩.
     앰버 = 주목받는 중(월상 원반 은유). 색은 보조, 텍스트 라벨이 정본. */
  /* [W-PR2 재파생 완료] --lit-quiet 만은 의미 hue 가 아니라 중립 회색이라 웜 지면
     위에서 푸른 기로 읽혔다. 램프의 **서수 역할을 보존하려고 상대 휘도를 고정**하고
     hue 만 옮겼다: 구 #cfd4dc 의 Y=0.6552 → 신 #d9d3c8 의 Y=0.6551(차 0.0001).
     밝기가 같으므로 quiet < mid < lit 순서가 값으로 흔들리지 않는다.
     --lit-mid/--lit-lit 는 의미 hue(인디고·앰버)라 재파생 대상이 아니다 — 불변. */
  --lit-quiet: #d9d3c8;   /* 주목 전 — 웜 뉴트럴. Y=0.6551 (구 zinc #cfd4dc Y=0.6552 동일) */
  --lit-mid:   #8ea0d8;   /* 보통 — 옅은 인디고 (accent 계열, 저채도) */
  --lit-lit:   #f79009;   /* 주목받는 중 — 앰버 */

  /* 파급 방향색 (수혜/피해) — style.css `.delta-benefit/.delta-harm .delta-num`.
     값의 단일 진실 원천은 web/palette.py 의 DIRECTION 이고 여기 라이트 2값은 그
     **사본**이다. 사본을 두는 이유: palette.css(=palette.py 산출물)는 어드민 전용
     링크라 공개면 <head> 에 없어서 공개 카드 34장에서 이 두 변수가 정의되지 않은
     채로 있었다(빈 var() -> 상속색으로 조용히 렌더. 실측: computed color 가 부모와
     동일). palette.css 를 공개면에 링크하는 대안은 다크를 못 푼다 — admin.css 는
     prefers-color-scheme 블록이 0개라 palette.py 는 애초에 라이트 전용이고,
     그 값을 다크 지면에 그대로 쓰면 2.80~3.66:1 로 AA 미달이다.
     그래서 라이트만 사본(정합)이고 **다크는 사본이 아니라 신규 값**이다.
     사본 잠금: tests/test_web_assets.py 가 palette.py DIRECTION 과 대조한다.
     --color-direction-neutral 은 공개면이 안 읽으므로 일부러 안 옮긴다(사본 최소화).
     DESIGN.md §2 "방향색(--color-direction-*)는 의미 채널이므로 역할 불변,
     값만 새 뉴트럴 위 대비 재실측". 아래가 그 재실측이다. */
  /* [W-PR2] 값 불변, 웜 지면 위 대비만 재실측(아래 수치가 새 --bg/--panel 기준이다). */
  --color-direction-plus:  #c0392b;  /* 수혜 — 5.44:1 on surface, 5.08:1 on bg, 4.78:1 on panel */
  --color-direction-minus: #2563a8;  /* 피해 — 6.12:1 on surface, 5.72:1 on bg, 5.38:1 on panel */

  /* 판정 상태색 (연결 확인 / 연결 기각) — style.css `.badge-confirmed/.badge-not-confirmed`.
     [W-PR1 2026-09-07] 종전에는 style.css 안 hex 리터럴이었다. 승격은 **값 보존**이다
     (온도 시프트는 W-PR2 소관 — 이 PR 은 시각 diff 0 이 목표).
     방향색·주목 램프와 값이 겹치지 않게 유지한다: 세 채널(파급 방향·서수 주목·판정)이
     한 색을 쓰면 같은 화면에서 서로를 못 가린다. 위 다크 방향색 주석과 같은 논리.
     실측 대비(라이트): 배지는 틴트 면 + 같은 계열 보더 + 텍스트라 텍스트 대비가 기준면이다. */
  --color-verified:        #2e7d32;  /* 4.52:1 on --color-verified-bg */
  --color-verified-bg:     #eaf3ea;
  --color-verified-line:   #cfe3cf;  /* 틴트 면의 보조선(1.35:1 on surface) — 정보 전달 보더가
                                        아니다. 판정은 배지 텍스트로 이중 인코딩된다. */
  --color-unverified:      #c62828;  /* 4.89:1 on --color-unverified-bg */
  --color-unverified-bg:   #faecec;
  --color-unverified-line: #f0d4d4;  /* 1.39:1 on surface — 위와 같은 보조선 */

  /* 상태색 (경고 / 위험). [W-PR1] 종전 panel.css `.sayo-panel` 스코프 전용 리터럴이라
     공개면에는 이 두 역할의 토큰이 아예 없었다(설계 §2.1 D2). 값 보존 승격.
     --color-warn-bg 는 --lit-lit(#f79009)과 **값을 분리한다**: 주목 램프는 서수 채널,
     경고는 상태 채널이라 한 색이면 두 의미가 한 색으로 뭉개진다.
     --color-danger 는 글자·테두리 전용이다 — 면을 채우면 액센트 CTA 와 경쟁한다. */
  --color-warn-bg:   #fff7e6;  /* --ink 16.62:1, --sub 7.16:1 on this fill (W-PR2 새 잉크 기준) */
  --color-warn-line: #eadfae;
  --color-danger:    #d92d20;  /* 4.83:1 on surface, 4.51:1 on bg, 4.24:1 on panel */

  /* 그림자 -- 층은 3개뿐: 지면(0) / 카드(1층) / 떠 있는 크롬(raised).
     카드 그림자는 장식이 아니라 보더의 보조라 1층으로 줄인다 (2층 -> 1층). */
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.04);
  --shadow-raised: 0 4px 6px -2px rgba(0, 0, 0, 0.05),
                   0 12px 16px -4px rgba(0, 0, 0, 0.10);
  /* [손파생 rgba — 팔레트 변경 때 반드시 손으로 재파생] 아래 --scroll-shade 와
     --glass-bg/--glass-border 는 rgba 리터럴이라 var() 로 팔레트를 못 따라간다.
     다크 블록에도 같은 3종이 있고(아래), 패널에는 --sp-ring 이 같은 클래스다
     (web/static/panel/panel.css). 지면·잉크 값을 바꾸는 PR(W-PR2)이 이 넷을
     빠뜨리면 새 지면 위에 옛 색조의 크롬이 남는다 — 증상이 조용하다. */
  --scroll-shade: rgba(26, 24, 21, 0.14);  /* 표 가로 스크롤 섀도 -- --ink #1a1815 파생 (W-PR2 재파생) */

  /* 글래스 (R7B) -- 떠 있는 크롬 전용: sticky 내비 바 / Ask Sayo 런처 / 홈 가치 바.
     본문·카드 서피스에 사용 금지. 적용은 @supports (backdrop-filter) 안에서만 --
     미지원 브라우저는 불투명 기본값이 그대로 남는다 (fail-open).
     prefers-reduced-transparency 오버라이드는 style.css 크롬 블록이 담당. */
  --glass-bg: rgba(255, 255, 255, 0.72);    /* --surface #ffffff 파생 (손파생, 위 주석) — surface 불변이라 값 유지 */
  --glass-border: rgba(26, 24, 21, 0.08);   /* --ink #1a1815 파생 (손파생, 위 주석 — W-PR2 재파생) */
  --glass-blur: 14px;
  --glass-saturate: 160%;

  /* 라운딩 -- shadcn --radius 10px 기준 재파생.
     --radius-pill 은 **인터랙티브 전용**(검색창·필터 버튼·헤더 pill).
     정보성 배지에 필 금지 (DESIGN.md §3.4). */
  --radius-xs: 4px;    /* 포커스 링·미니 요소 */
  --radius-sm: 6px;    /* 배지·인풋·인라인 블록 */
  --radius-md: 8px;    /* 버튼·패널·팝오버 */
  --radius-lg: 10px;   /* 카드 */
  --radius-pill: 999px;

  /* 간격 -- 4px 베이스 스케일 */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  /* 타이포 -- Pretendard 단일 패밀리 (명조 폐기) */
  --sans: "Pretendard Variable", "Apple SD Gothic Neo", "Noto Sans KR",
          "Malgun Gothic", -apple-system, "Segoe UI", sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* -- shadcn/ui semantic aliases (PR-1, render-invariant) --
     These are ALIASES over the sayo tokens above, not new values. Every one
     resolves through var() to the existing token, so the dark and print
     overrides further down keep working untouched: var() is resolved at use
     time, so redefining --bg in the dark block also moves --background.
     Do NOT restate these aliases inside the dark or print blocks -- that would
     duplicate the value and let the two copies drift apart.

     Naming note -- --accent is NOT introduced here. sayo already defines
     --accent (indigo, 170 call sites) and it carries what shadcn calls
     "primary", which is why --primary aliases it. shadcn's own --accent role
     (a subtle hover/active surface tint) has no counterpart yet; introducing
     it would mean redefining the existing --accent and repainting every one of
     those call sites, so it is deferred to the follow-up visual PR.
     --destructive is likewise omitted: the public stylesheets carry no
     dominant destructive value to derive it from, only two one-off literals.

     v2 note (2026-09-05) -- --primary / --primary-hover / --primary-foreground
     are back HERE as aliases. PR-2 had split them out into real ink values
     restated in the dark and print blocks ("indigo = information, ink =
     action"); Kevin reverted that call -- the whole product read monochrome.
     Aliasing is deliberately the safer shape: a restated value has to be kept
     in sync across three blocks (:root / dark / print) and the dark copy is
     exactly the one a screenshot pass forgets to look at. As aliases they
     resolve at use time, so the dark and print --accent overrides move them
     for free. Do NOT restate these three below. */
  --background: var(--bg);
  --foreground: var(--ink);
  --muted: var(--panel);
  --muted-foreground: var(--sub);
  --border: var(--line);
  --ring: var(--accent);
  --radius: var(--radius-sm);
  --primary: var(--accent);
  --primary-hover: var(--accent-strong);
  --primary-foreground: var(--accent-ink);
}

@media (prefers-color-scheme: dark) {
  :root {
    /* 네이비 틴트 다크 폐기 -> 무채 심연 -> [W-PR2] 웜 심연.
       라이트와 **같은 방향으로** 옮긴다 — 한쪽만 웜이면 테마 전환에서 온도가 튄다. */
    --bg: #0d0b09;
    --surface: #151310;
    --panel: #1d1a17;
    /* [W-PR2 재파생] 라이트 --lit-quiet 과 같은 규율: 서수 보존을 위해 상대 휘도 고정.
       구 #3a4358 Y=0.0562 → 신 #4b4232 Y=0.0562(동일). hue 만 웜으로. */
    --lit-quiet: #4b4232;   /* 주목 전 — 어두운 웜 뉴트럴. Y=0.0562 (구 #3a4358 과 동일) */
    --lit-mid:   #5a6bb0;   /* 보통 — 인디고 */
    --lit-lit:   #f5a623;   /* 주목받는 중 — 앰버(다크 대비 상향) */
    /* 방향색 다크 — palette.py 사본이 아니다(그쪽은 라이트 전용). 라이트 실값을
       그대로 쓰면 최악 2.80:1(minus on panel)로 AA 미달이라 색상(hue)은 지키고
       명도만 올려 재파생했다. .badge-confirmed/.rs-role-* 선례와 같은 톤대이되
       값은 겹치지 않게 뒀다 — #ef9a9a 는 이미 '미검증' 의미라 방향색이 같은 색을
       쓰면 두 의미 채널이 한 색이 된다. */
    --color-direction-plus:  #e8897c;  /* 수혜 — 7.33:1 on surface, 7.77:1 on bg, 6.85:1 on panel (W-PR2 재실측) */
    --color-direction-minus: #7fb3e8;  /* 피해 — 8.40:1 on surface, 8.90:1 on bg, 7.85:1 on panel (W-PR2 재실측) */
    /* 판정·상태색 다크 — style.css/panel.css 다크 리터럴을 값 보존 승격(W-PR1).
       면은 알파 틴트라 지면 위에서 합성된다. 아래 실측은 합성 후 텍스트 대비다. */
    --color-verified:        #81c784;  /* 7.43:1 on surface, 8.10:1 on bg, 6.84:1 on panel (새 지면 합성 후) */
    --color-verified-bg:     rgba(129, 199, 132, 0.12);
    --color-verified-line:   rgba(129, 199, 132, 0.28);
    --color-unverified:      #ef9a9a;  /* 7.06:1 on surface, 7.68:1 on bg, 6.49:1 on panel (새 지면 합성 후) */
    --color-unverified-bg:   rgba(239, 154, 154, 0.12);
    --color-unverified-line: rgba(239, 154, 154, 0.28);
    --color-warn-bg:   #2a2410;  /* --ink 13.59:1, --sub 6.13:1 on this fill (W-PR2 새 잉크 기준) */
    --color-warn-line: #4a3f14;
    --color-danger:    #f97066;  /* 6.66:1 on surface, 7.05:1 on bg, 6.22:1 on panel */
    /* --paper 는 재정의하지 않음 (차트 지면은 다크에서도 흰색 유지) */
    --ink: #f2f0ed;          /* 웜 화이트. 16.30:1 on surface, 17.27:1 on bg, 15.23:1 on panel */
    --sub: #a8a29e;          /* 7.35:1 on surface, 7.79:1 on bg, 6.87:1 on panel */
    --line: #29251f;
    --line-strong: #423d35;
    --accent: #a5b4fc;       /* 9.85:1 on bg, 9.30:1 on surface, 8.69:1 on panel (W-PR2 재실측) */
    --accent-strong: #c7d2fe;
    --accent-soft: #26264a;  /* accent 텍스트 7.22:1 위에서 통과 (틴트 면이라 지면 시프트 무관) */
    --accent-ink: #0d0b09;   /* on accent, 9.85:1 — --bg 파생이라 웜 시프트를 따라간다 */
    /* 구성 세그먼트 사다리 다크 — 라이트의 **반전**이다. 라이트는 어두운 인디고
       →밝은 쪽으로 가고, 다크는 밝은 인디고→어두운 쪽으로 간다: 두 모드 모두
       "1단이 지면에서 가장 멀고 말단이 지면에 가장 가깝다"는 같은 규칙이다.
       라이트 값을 그대로 흘리면 1단(L*25.9)이 웜 심연(--panel L*9.5) 위에서
       사실상 사라진다 — 그래서 이 블록의 존재 자체가 계약이고,
       tests/test_web_assets.py 가 다크 오버라이드 부재를 red 로 잡는다.
       실측 지면 = 웜 심연 --panel #1d1a17 / --surface #151310 / --bg #0d0b09.
       인접 단 ΔL* ≥ 7.9, 인접 대비비 ≥ 1.268 (라이트와 같은 하한). */
    --mix-seg-1: #d1c1f8;    /* L*81.0 · on panel 10.47:1, surface 11.21:1 */
    --mix-seg-2: #bca8f1;    /* L*72.9 · on panel 8.26:1 */
    --mix-seg-3: #a690ec;    /* L*65.0 · on panel 6.45:1 */
    --mix-seg-4: #8e77eb;    /* L*57.0 · on panel 4.94:1 */
    --mix-seg-5: #725fe8;    /* L*49.0 · on panel 3.73:1 */
    --mix-seg-6: #5147e3;    /* L*40.9 · on panel 2.77:1 */
    --mix-seg-7: #4038bb;    /* L*32.9 · on panel 2.06:1 */
    --mix-seg-8: #3e3b35;    /* L*25.0 · on panel 1.55:1 — 말단 웜 뉴트럴(C=4) */
    --mix-seg-1-fg: #0d0b09; /* on seg-1, 11.88:1 */
    --mix-seg-2-fg: #0d0b09; /* on seg-2,  9.36:1 */
    --mix-seg-3-fg: #0d0b09; /* on seg-3,  7.32:1 */
    --mix-seg-4-fg: #0d0b09; /* on seg-4,  5.60:1 */
    --mix-seg-5-fg: #ffffff; /* on seg-5,  4.65:1 */
    --mix-seg-6-fg: #ffffff; /* on seg-6,  6.25:1 */
    --mix-seg-7-fg: #ffffff; /* on seg-7,  8.40:1 */
    --mix-seg-8-fg: #ffffff; /* on seg-8, 11.16:1 */
    /* --primary 3종은 재정의하지 않는다 -- :root 에서 --accent 별칭이라
       위 --accent 재정의를 자동으로 따라간다(다크 CTA = 라이트 인디고 반전). */
    --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.45);
    --shadow-raised: 0 4px 6px -2px rgba(0, 0, 0, 0.4),
                     0 12px 16px -4px rgba(0, 0, 0, 0.5);
    /* 아래 셋은 rgba 라 var() 로 팔레트를 못 따라간다 -- 새 뉴트럴에서 손으로 재파생.
       (구 값은 네이비 #0d1220·#e6e9f0 파생이라 무채 지면 위에 파란 크롬이 떴다.
        W-PR2 에서 zinc 파생 → 웜 스톤 파생으로 한 번 더 옮겼다.) */
    --scroll-shade: rgba(242, 240, 237, 0.16);  /* --ink #f2f0ed 파생 (W-PR2 재파생) */
    --glass-bg: rgba(13, 11, 9, 0.66);          /* --bg #0d0b09 파생 (W-PR2 재파생) */
    --glass-border: rgba(242, 240, 237, 0.10);  /* --ink #f2f0ed 파생 (W-PR2 재파생) */
  }
}

/* 인쇄 = 라이트 고정 (구 style.css @media print :root 이관) */
@media print {
  :root {
    color-scheme: light;
    /* [W-PR2] 라이트 실값의 사본이다 — :root 를 옮기면 여기도 같이 옮겨야 한다.
       (사본을 안 옮기면 화면만 웜이고 인쇄물만 zinc 로 남는다.) */
    --bg: #f8f7f4; --surface: #ffffff; --panel: #f2f0ec; --paper: #ffffff;
    --ink: #1a1815; --sub: #57534e;
    --line: #e8e5df; --line-strong: #d8d3ca;
    --accent: #4f46e5; --accent-strong: #4338ca;
    --accent-soft: #eef0fe; --accent-ink: #ffffff;
    /* --primary 3종은 재정의 금지 (:root 별칭이 위 --accent 를 따라간다). */
    /* 구성 세그먼트 사다리 = 라이트 실값 사본. 지면·액센트와 **같은 이유**로
       여기 적는다: 위에서 --panel 을 라이트로 되돌리므로, 다크 사다리가 그대로
       남으면 "다크모드로 인쇄" 시 흰 지면 위에 다크 말단(#3e3b35)이 찍힌다.
       (판정·상태색을 일부러 안 적는 것과 갈리는 지점 — 그쪽은 승격 전 동작
       보존이 목적이었고, 이쪽은 신규라 보존할 구 동작이 없다.)
       사본 잠금: tests/test_web_assets.py 가 :root 값과 대조한다. */
    --mix-seg-1: #3b3084; --mix-seg-2: #4239bc;
    --mix-seg-3: #5147e3; --mix-seg-4: #735fe5;
    --mix-seg-5: #8e78e4; --mix-seg-6: #a690e9;
    --mix-seg-7: #bca8f1; --mix-seg-8: #cdc9c2;
    --mix-seg-1-fg: #ffffff; --mix-seg-2-fg: #ffffff;
    --mix-seg-3-fg: #ffffff; --mix-seg-4-fg: #ffffff;
    --mix-seg-5-fg: #1a1815; --mix-seg-6-fg: #1a1815;
    --mix-seg-7-fg: #1a1815; --mix-seg-8-fg: #1a1815;
    /* [W-PR1] 판정·상태색(--color-verified/-unverified/-warn/-danger)은 **일부러**
       여기 안 적는다. 승격 전 style.css 리터럴도 print 오버라이드가 없어서
       "다크모드로 인쇄" 시 다크 배지가 그대로 나갔다. 여기에 라이트 값을 적으면
       그 동작이 바뀐다 — 이 PR 은 값 보존 리팩터라 인쇄 동작도 보존한다.
       인쇄 팔레트 정합은 별도 판단거리로 남긴다(승격 이전과 동일 상태). */
  }
}
