/* web/static/tokens.css -- 디자인 토큰 단일 정의 (R7A, 2026-07-18)
   시스템: 검증 원장(ledger of evidence). 순뉴트럴(zinc) 지면 + 흰 카드 서피스 +
   인디고 브랜드색(행동·정보 공용). 지면·텍스트는 뉴트럴, 색은 상태·액션·
   브랜드 포인트에만 쓴다.
   [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). 청색기 제거 */
  --bg: #f7f7f8;            /* 캔버스 */
  --surface: #ffffff;       /* 카드 서피스 */
  --panel: #f1f1f3;         /* 인셋 패널·행 hover */
  --paper: #ffffff;         /* 차트 지면 -- 다크에서도 밝게 (SVG 고정색 가독) */

  /* 텍스트 */
  --ink: #111113;           /* 18.86:1 on surface, 17.62:1 on bg, 16.72:1 on panel */
  --sub: #52525b;           /* 7.73:1 on surface, 7.22:1 on bg, 6.85:1 on panel */

  /* 보더 */
  --line: #e4e4e7;
  --line-strong: #d4d4d8;

  /* 액센트 (인디고 -- DIRECTION 적/청과 충돌하지 않는 제3색). 브랜드색이자
     인터랙션 색이다: 주 CTA·활성 탭·링크 hover·데이터 하이라이트·포커스 링.
     OG 이미지·브랜드 마크와 같은 계열이라 제품 밖 표면과도 정합.
     [v2] "정보 전용" 축소는 철회 — 행동도 인디고가 진다. */
  --accent: #4f46e5;        /* 6.29:1 on surface, 5.87:1 on bg, 5.57:1 on panel */
  --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 */

  /* 노출 주목 세기 램프 (조용→조명, P-explore-redesign) — 판정/방향색 아님, 서수 인코딩.
     앰버 = 주목받는 중(월상 원반 은유). 색은 보조, 텍스트 라벨이 정본. */
  /* [재파생 대상 — W-PR2 지면 온도 시프트] --lit-quiet 만은 의미 hue 가 아니라 중립
     회색이다. 지면이 웜 스톤으로 옮겨가면 zinc 계열 회색은 그 위에서 푸른 기로 읽히므로
     램프의 서수 역할은 그대로 두고 **값만** 웜 뉴트럴로 재파생해야 한다(설계 §2.2 W-1).
     --lit-mid/--lit-lit 는 의미 hue(인디고·앰버)라 재파생 대상이 아니다. */
  --lit-quiet: #cfd4dc;   /* 주목 전 — 중립 회색 */
  --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-*)는 의미 채널이므로 역할 불변,
     값만 새 뉴트럴 위 대비 재실측". 아래가 그 재실측이다. */
  --color-direction-plus:  #c0392b;  /* 수혜 — 5.44:1 on surface, 5.08:1 on bg, 4.82:1 on panel */
  --color-direction-minus: #2563a8;  /* 피해 — 6.12:1 on surface, 5.72:1 on bg, 5.43: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 17.69:1, --sub 7.25:1 on this fill */
  --color-warn-line: #eadfae;
  --color-danger:    #d92d20;  /* 4.83:1 on surface, 4.51:1 on bg */

  /* 그림자 -- 층은 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(17, 17, 19, 0.14);  /* 표 가로 스크롤 섀도 -- --ink #111113 파생 */

  /* 글래스 (R7B) -- 떠 있는 크롬 전용: sticky 내비 바 / Ask Sayo 런처 / 홈 가치 바.
     본문·카드 서피스에 사용 금지. 적용은 @supports (backdrop-filter) 안에서만 --
     미지원 브라우저는 불투명 기본값이 그대로 남는다 (fail-open).
     prefers-reduced-transparency 오버라이드는 style.css 크롬 블록이 담당. */
  --glass-bg: rgba(255, 255, 255, 0.72);    /* --surface #ffffff 파생 (손파생, 위 주석) */
  --glass-border: rgba(17, 17, 19, 0.08);   /* --ink #111113 파생 (손파생, 위 주석) */
  --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 {
    /* 네이비 틴트 다크 폐기 -> 무채 심연 (DESIGN.md §3.2) */
    --bg: #09090b;
    --surface: #131316;
    --panel: #1b1b1f;
    --lit-quiet: #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.86:1 on bg, 6.79:1 on panel */
    --color-direction-minus: #7fb3e8;  /* 피해 — 8.40:1 on surface, 9.02:1 on bg, 7.78:1 on panel */
    /* 판정·상태색 다크 — style.css/panel.css 다크 리터럴을 값 보존 승격(W-PR1).
       면은 알파 틴트라 지면 위에서 합성된다. 아래 실측은 합성 후 텍스트 대비다. */
    --color-verified:        #81c784;  /* 7.44:1 on surface, 8.30:1 on bg, 6.76: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.07:1 on surface, 7.85:1 on bg, 6.43: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.58:1, --sub 6.03:1 on this fill */
    --color-warn-line: #4a3f14;
    --color-danger:    #f97066;  /* 6.66:1 on surface, 7.14:1 on bg */
    /* --paper 는 재정의하지 않음 (차트 지면은 다크에서도 흰색 유지) */
    --ink: #f0f0f2;          /* 16.29:1 on surface, 17.48:1 on bg */
    --sub: #a1a1aa;          /* 6.70:1 on panel, 7.24:1 on surface */
    --line: #26262b;
    --line-strong: #3f3f46;
    --accent: #a5b4fc;       /* 9.98:1 on bg, 9.30:1 on surface */
    --accent-strong: #c7d2fe;
    --accent-soft: #26264a;  /* accent 텍스트 7.22:1 위에서 통과 */
    --accent-ink: #09090b;   /* on accent, 9.98: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 파생이라 무채 지면 위에 파란 크롬이 떴다.) */
    --scroll-shade: rgba(240, 240, 242, 0.16);  /* --ink 파생 */
    --glass-bg: rgba(9, 9, 11, 0.66);           /* --bg 파생 */
    --glass-border: rgba(240, 240, 242, 0.10);  /* --ink 파생 */
  }
}

/* 인쇄 = 라이트 고정 (구 style.css @media print :root 이관) */
@media print {
  :root {
    color-scheme: light;
    --bg: #f7f7f8; --surface: #ffffff; --panel: #f1f1f3; --paper: #ffffff;
    --ink: #111113; --sub: #52525b;
    --line: #e4e4e7; --line-strong: #d4d4d8;
    --accent: #4f46e5; --accent-strong: #4338ca;
    --accent-soft: #eef0fe; --accent-ink: #ffffff;
    /* --primary 3종은 재정의 금지 (:root 별칭이 위 --accent 를 따라간다). */
    /* [W-PR1] 판정·상태색(--color-verified/-unverified/-warn/-danger)은 **일부러**
       여기 안 적는다. 승격 전 style.css 리터럴도 print 오버라이드가 없어서
       "다크모드로 인쇄" 시 다크 배지가 그대로 나갔다. 여기에 라이트 값을 적으면
       그 동작이 바뀐다 — 이 PR 은 값 보존 리팩터라 인쇄 동작도 보존한다.
       인쇄 팔레트 정합은 별도 판단거리로 남긴다(승격 이전과 동일 상태). */
  }
}
