/* 사본 — snapholo-web 9917f0b5b docs/design/styles/tokens.css sha256=8f811000de2be8968b0dbf7a785bf4adbda1918efe0eb995a97f43232593ea52 (scripts/sync_tokens.py) */
/* ============================================================================
   SnapHolo 디자인 토큰
   ----------------------------------------------------------------------------
   생성물 — 정본은 docs/design/tokens/snapholo.tokens.json, 손으로 고치지 마라.
   다시 만들기: python scripts/build_tokens.py
   (docs/design/styles/tokens.css 와 docs/design/ds-bundle/tokens.css 는 같은 바이트다.)

   다른 CSS 파일에 hex 리터럴을 적지 마라 — 그게 v3 가 죽은 경로다.
   프레임워크 중립: 순수 CSS 커스텀 프로퍼티다. 빌드 없는 정적 HTML 은 <link> 로 읽는다.
   대비 실측은 정본 JSON 의 contrast 표에 있고 tests/test_design_tokens.py 가 다시 잰다.
   ========================================================================== */

:root {
  /* ══════════════════════════════════════════════════════════════════════════
     1층 · PRIMITIVE — 값 그 자체. 의미를 담지 않는다.
     ══════════════════════════════════════════════════════════════════════════ */

  /* 브랜드 홀로 4색 — logo.ai 마스터에서 나온 값. 새로 만들지 않는다. */
  --holo-aqua: #5bc9d5;
  --holo-iris: #8c77da;
  --holo-blossom: #ef94b8;
  --holo-amber: #ffd88e;
  --ink: #17232c; /* 브랜드 잉크 — brand/master/*.svg 의 fill 값과 동일 */

  /* 중성 램프 (hue 220) — 흰 지면 대비 실측은 contrast 표 */
  --slate-950: #1e2534;
  --slate-800: #333b4c;
  --slate-700: #4d576a;
  --slate-600: #65718b; /* 본문 최소선 */
  --slate-400: #9ca4b4; /* 비텍스트 전용 */
  --slate-300: #cacfd8;
  --slate-200: #e1e4ea;
  --slate-100: #eef0f4;
  --slate-50: #f7f8fa;
  --white: #ffffff;

  /* 아이리스 — 브랜드 보라(옛). v0 시안에 흩어져 있던 7종을 이 넷으로 수렴했다
     (#7174d4 #7c79dc #7476d3 #6e73d1 #8081dc #7777d6 #4f55b5) */
  --iris-700: #5f62cf; /* 글자로 쓸 수 있는 유일한 보라
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */
  --iris-500: #7174d4; /* 텍스트로 쓰지 마라. 채움 전용
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */
  --iris-300: #8b8ddc; /* 보더·밑줄 전용
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */
  --iris-50: #f0f0ff; /* legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */

  /* 상태색 — 지면·카드 양쪽에서 4.5:1 을 넘도록 낮춘 값 */
  --green-600: #3a7e63;
  --amber-700: #9f6432;

  /* 알파 — 그림자·오버레이. 색상 토큰과 섞지 않는다 */
  --alpha-card-shadow: rgba(116, 118, 216, 0.2);
  --alpha-art-shadow: rgba(41, 55, 90, 0.33);
  --alpha-text-shadow: rgba(0, 0, 0, 0.2);
  --alpha-white-strong: rgba(255, 255, 255, 0.7);
  --alpha-white-soft: rgba(255, 255, 255, 0.33);

  /* ══════════════════════════════════════════════════════════════════════════
     2층 · SEMANTIC — 화면은 이것만 쓴다.
     다크 모드를 얹을 때 재정의하는 것도 이 층뿐이다(1층은 그대로).
     ══════════════════════════════════════════════════════════════════════════ */

  /* 지면 */
  --color-bg: var(--slate-50);
  --color-surface: var(--white);
  --color-surface-sunken: var(--slate-50);

  /* 글자 — 세 단. 그 아래는 없다 */
  --color-text: var(--slate-950); /* 제목·값 */
  --color-text-secondary: var(--slate-700); /* 본문·설명 */
  --color-text-muted: var(--slate-600); /* 라벨·보조 */

  /* 선 */
  --color-border: var(--slate-200);
  --color-border-strong: var(--slate-300);
  --color-border-dashed: var(--slate-200);

  /* 강조 — legacy(옛 보라). 옛 화면 9개 전용 — 새 화면은 아래 브랜드 강조(민트)만 쓴다 */
  --color-accent: var(--iris-700); /* 링크·강조 텍스트 — 세 지면 모두 통과
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */
  --color-accent-fill: var(--iris-500); /* 채움(아바타·칩) — 텍스트 아님
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */
  --color-accent-line: var(--iris-300); /* 보더·활성 밑줄 — 텍스트 아님
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */
  --color-accent-soft: var(--iris-50); /* 배지·노트 지면
       legacy — 2026-10-02 대표 결정 d2 — 2단계에서 민트로 */

  /* 브랜드 강조 — 민트 (2026-10-02 대표 결정 d2). 액션 채움과 텍스트 링크를 구분한다 */
  --color-brand-action-fill: #1bd3ce; /* 액션 채움 — 에메랄드 바탕. 텍스트·아이콘은 brand.action.on(흰색). */
  --color-brand-action-on: #ffffff; /* 에메랄드 액션 버튼의 텍스트·아이콘 — 흰색(2026-10-07 사용자 지시) */
  --color-brand-link-text: #007f85; /* 텍스트 링크 — 민트 글자로 작은 링크를 만들지 않고 이 진한 색을 쓴다(UI-GUIDE 03). 아이스 지면 미달 — contrast 예외 */
  --color-brand-symbol-mint: #24d5cb; /* 심볼 민트 — 심볼 위쪽 그라디언트 시작색 · 홈 강조 */

  /* 상태 */
  --color-state-known: var(--green-600);
  --color-state-uncollected: var(--amber-700);
  --color-state-live: var(--green-600);

  /* 홀로 그라디언트 — 정의는 여기 하나뿐이다.
     허용 자리 세 곳 (README 로고 규칙 4, 2026-08-21 개정):
       ① 어두운 지면의 워드마크  ② 실제 포일 판본의 카드 표면
       ③ 상단 3px 브랜드 밴드
     그 외에 쓰지 마라. */
  --gradient-holo: linear-gradient(
    57deg,
    var(--holo-aqua),
    var(--holo-iris) 33.3%,
    var(--holo-blossom) 66.7%,
    var(--holo-amber)
  );
  --on-gradient: var(--ink); /* 그라디언트 위 글자는 잉크다. 흰 글자는 금지 — 대비 실측은 contrast 표 */

  /* 그림자 */
  --shadow-card: 0 24px 50px var(--alpha-card-shadow);
  --shadow-art-text: 0 15px 22px var(--alpha-art-shadow);

  /* ── 차트 계열색 — 마감 3종. 순서 고정, 순환 금지 ──
     색은 마감(엔티티)을 따라간다. 필터로 계열이 줄어도 남은 것의 색은 안 바뀐다.
     dataviz 검증기 실측(지면 #ffffff):
       명도대역 PASS · 채도하한 PASS · 정상시각 ΔE 20.3 PASS · 지면대비 PASS
       CVD 최악쌍 리버스↔홀로 ΔE 7.7(deutan) — 6~8 구간이라
       **선 끝 직접 라벨이 필수**다. 범례만으로는 안 된다.
     다크(지면 #191e2a): 명도대역·채도·정상시각 ΔE 17.4·지면대비 PASS / CVD 최악쌍 7.7(deutan)
       → 라이트와 같은 이유로 직접 라벨 필수 */
  --chart-finish-base: #6f5bd8;
  --chart-finish-holo: #0a97a6;
  --chart-finish-reverse: #d62a76;
  --chart-grid: var(--slate-100);
  --chart-axis: var(--slate-300);

  /* ══════════════════════════════════════════════════════════════════════════
     활자 — 서체 · 크기 · 행간 · 자간 · 굵기
     ══════════════════════════════════════════════════════════════════════════ */

  /* 서체 — IBM Plex 한 가족으로 Latin·한글·일본어·태국어를 덮는다.
     중국어(TC/SC)만 IBM Plex 에 없어 Noto 로 보충한다.
     ⚠️ 스크립트별 스택은 아래 :lang() 이 갈아 끼운다 — 한 줄로 다 나열하면
        한자가 겹쳐서 중국어가 일본어 글리프로 나온다. */
  --font-sans: "IBM Plex Sans", "IBM Plex Sans KR", "IBM Plex Sans JP", sans-serif;
  --font-display: var(--font-sans);
  --font-mono: "IBM Plex Mono", "IBM Plex Sans KR", ui-monospace, SFMono-Regular, monospace;

  /* Shared service scale: body 16, supporting text 14, captions 12; desktop/mobile headings use the same roles in every language. */
  --text-display: 3.5rem; /* 3.5rem desktop / 2rem mobile */
  --text-hero: 2rem; /* 2rem desktop / 1.625rem mobile */
  --text-h2: 1.5rem; /* 24.0px */
  --text-h3: 1.125rem; /* 18.0px */
  --text-body: 1rem; /* 16px */
  --text-data: 0.875rem; /* 14.0px */
  --text-label: 0.75rem; /* 12 — 절대 하한 */
  --text-price: 2.25rem; /* 36.0px */
  --text-price-sub: 1.25rem; /* 20.0px */
  --leading-tight: 1.25;
  --leading-snug: 1.4;
  --leading-normal: 1.6;
  --tracking-display: -0.02em;
  --tracking-kicker: 0.04em;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-bold: 700;
  --weight-black: 800;
  --weight-semibold: 600;

  /* ══════════════════════════════════════════════════════════════════════════
     간격 — 4px 기반 12단. v0 시안의 padding 24종 · gap 20종을 여기 스냅했다.
     ══════════════════════════════════════════════════════════════════════════ */
  --space-1: 0.25rem; /* 4px */
  --space-2: 0.5rem; /* 8px */
  --space-3: 0.75rem; /* 12px */
  --space-4: 1rem; /* 16px */
  --space-5: 1.25rem; /* 20px */
  --space-6: 1.5rem; /* 24px */
  --space-7: 2rem; /* 32px */
  --space-8: 2.5rem; /* 40px */
  --space-9: 3rem; /* 48px */
  --space-10: 4rem; /* 64px */
  --space-11: 5rem; /* 80px */
  --space-12: 6rem; /* 96px */

  /* 반경 — v0 의 5·8·9·10·12·17·26·999 를 다섯 단으로 */
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-xl: 16px;
  --radius-full: 999px;

  /* 레이아웃 */
  --layout-max: 1184px;
  --layout-pad: var(--space-7); /* 모바일(≤760px)에서 space-5 */
  --layout-pad-sm: var(--space-5);
  --topbar-height: 74px;

  /* 모션 — 150~300ms. 의미 없는 장식 애니메이션은 두지 않는다.
     들어올 때는 ease-out(빠르게 시작해 부드럽게 안착), 나갈 때는 ease-in 으로 더 짧게.
     transform 과 opacity 만 애니메이션한다 — width/height/top/left 는 매 프레임 레이아웃을 다시 계산한다. */
  --motion-fast: 0.15s; /* 줄이기 설정에서 0.01ms */
  --motion-base: 0.25s; /* 줄이기 설정에서 0.01ms */
  --motion-ease: cubic-bezier(0.4, 0, 0.2, 1); /* 표준 */
  --motion-enter: 0.2s; /* 손에 잡히는 순간 */
  --motion-leave: 0.14s; /* 놓는 건 더 빨라야 미련이 없다 */
  --ease-out: cubic-bezier(0.22, 0.9, 0.3, 1); /* 들어올 때 */
  --ease-in: cubic-bezier(0.4, 0, 1, 1); /* 나갈 때 */

  /* 카드를 집어 올리는 눈금. 이 셋이 「손으로 집었다」의 전부다 —
     더 올리면 카드가 화면에서 뜯겨 나가고, 더 틀면 그리드가 흔들려 보인다. */
  --lift-y: -10px; /* 뜨는 높이 */
  --lift-tilt: -2.5deg; /* 왼쪽이 들린다(반대각). 기존 기울기에 더해진다.
       ⚠️ 음수 = 반시계 = 왼쪽 들림.
       +2.5 로 되돌리지 마라 (2026-08-23 대표) */
  --lift-scale: 1.03; /* 눈에 가까워진 만큼 */
  --press-scale: 0.97; /* 손가락 아래서 눌리는 정도 */
  --shadow-rest: 0 6px 16px var(--alpha-card-shadow);
  --shadow-lift: 0 22px 40px var(--alpha-card-shadow);

  /* 나머지 모션의 눈금. 전부 짧다 — 이 화면은 표와 그리드라 오래 끌면 읽을 수가 없다 */
  --motion-tint: 0.12s; /* 색만 바뀌는 것(행·버튼·테두리) */
  --motion-press: 0.08s; /* 누름 */
  --motion-drop: 0.16s; /* 메뉴 열림 (닫힘은 --motion-press) */
  --motion-reveal: 0.32s; /* 스크롤 진입 — 한 번만 */
  --reveal-y: 12px; /* 진입할 때 아래에서 올라오는 거리 */
  --reveal-step: 0.04s; /* 줄줄이 들어올 때 한 칸 간격 */
  --set-bg: #f3f7f9; /* 아이스 */
  --set-line: #dee8ee;
  --set-panel: #eaf1f5;
  --set-focus: #6e66d7;
  --set-fan-duration: 400ms;
  --brand-foil-cyan: #32dce8;
  --brand-foil-violet: #8374f3;
  --brand-foil-pink: #ef8fda;
  --brand-foil-gold: #ffe9a1;
  --brand-foil-green: #7ae1c0;
  --brand-foil-blue: #57c9ee;
  --brand-foil-mask-solid: #000;
  --brand-foil-mask-soft: #000c;
  --brand-foil-light-cyan: #b7eeff55;
  --brand-foil-light-white: #fff;
  --brand-foil-light-soft: #fff9;
  --brand-foil-light-pink: #fcd9ff66;
  --brand-foil-glow-soft: #fff5;
  --brand-foil-pin: #718d98;
  --motion-foil-sweep: 8s;

  /* Service UI typography roles. Hero and cinematic card prices retain their own scale. */
  --ui-page-size: var(--text-h2);
  --ui-page-line: var(--space-7);
  --ui-section-size: var(--text-h3);
  --ui-group-size: var(--text-body);
  --ui-body-size: var(--text-body);
  --ui-body-line: var(--space-6);
  --ui-support-size: var(--text-data);
  --ui-support-line: var(--space-5);
  --ui-label-size: var(--text-label);
  --ui-label-line: var(--space-4);
  --ui-summary-size: var(--text-h2);
  --ui-summary-line: var(--space-7);
  --ui-section-line: 1.625rem;

  /* Shared service components: compact/descriptive rows, groups, summary, FAQ and contact form. */
  --ui-gutter: var(--space-4);
  --ui-group-radius: var(--radius-lg);
  --ui-group-padding: var(--space-5);
  --ui-group-gap: var(--space-3);
  --ui-section-gap: var(--space-6);
  --ui-label-gap: var(--space-3);
  --ui-row-compact: var(--space-9);
  --ui-row-descriptive: var(--space-10);
  --ui-row-pad-y: var(--space-2);
  --ui-icon-slot: var(--space-7);
  --ui-icon-size: var(--space-6);
  --ui-icon-gap: var(--space-3);
  --ui-trailing-size: var(--space-4);
  --ui-text-gap: var(--space-1);
  --ui-control-height: 2.75rem;
  --ui-control-radius: var(--radius-sm);
  --ui-field-gap: var(--space-6);
  --ui-chart-width: var(--space-12);
  --ui-page-max: 40rem;
  --ui-touch-min: 2.75rem;
  --ui-submit-height: 3.25rem;

  /* 2026-10-18 user decision: one dominant hue per purpose, tonal light/shadow only. Replaces rainbow-per-icon rule. */
  --icon-discovery: var(--color-brand-symbol-mint);
  --icon-market: var(--color-brand-symbol-mint);
  --icon-library: var(--color-brand-symbol-violet);
  --icon-interest: var(--color-brand-symbol-pink);
  --icon-premium: var(--color-brand-symbol-gold);
  --icon-support: var(--holo-aqua);
  --icon-account: #4c8fe6; /* Account/settings blue. Replaces gray after user feedback 2026-10-18. */
  --color-brand-symbol-violet: #7760f5;
  --color-brand-symbol-pink: #f08bda;
  --color-brand-symbol-gold: #ffd17c;
}

/* ══════════════════════════════════════════════════════════════════════════
   다크 — 2층(semantic)만 다시 정의한다. 1층 primitive 는 건드리지 않는다(예외: 알파 그림자 2개).
   대비는 **패널 지면(--color-surface) 기준**으로 맞췄다 — 실측과 미달 예외는 정본 JSON 의 contrast 표.

   세 갈래를 모두 받는다:
     ① 사용자가 다크를 명시   → :root[data-theme="dark"]
     ② 시스템 설정이 다크     → prefers-color-scheme (라이트 명시는 제외)
     ③ 클래스 토글            → .dark
   ══════════════════════════════════════════════════════════════════════════ */

:root[data-theme="dark"],
.dark {
  color-scheme: dark;
  --color-bg: #10151e;
  --color-surface: #191e2a;
  --color-surface-sunken: #0c1018;
  --color-text: #d8dbe1;
  --color-text-secondary: #a1a9b8;
  --color-text-muted: #7b869b;
  --color-border: #313949;
  --color-border-strong: #454f63;
  --color-border-dashed: #313949;
  --color-accent: #797cd6;
  --color-accent-fill: #7174d4;
  --color-accent-line: #585bcd;
  --color-accent-soft: #25264b;
  --color-state-known: #449373;
  --color-state-uncollected: #b9753a;
  --color-state-live: #449373;

  /* 그라디언트와 그 위 글자는 다크에서도 그대로다 — 대비는 contrast 표 */

  /* 차트 계열색 (다크) — 근거는 정본 JSON semantic.chart */
  --chart-finish-base: #8274e0;
  --chart-finish-holo: #0f9dad;
  --chart-finish-reverse: #e05f92;
  --chart-grid: #232b3a;
  --chart-axis: #3b4557;
  --on-gradient: var(--ink);

  /* 다크에서는 보라 그림자가 탁해 보인다. 검정 기반으로 바꾼다 */
  --alpha-card-shadow: rgba(0, 0, 0, 0.55);
  --alpha-art-shadow: rgba(0, 0, 0, 0.5);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --color-bg: #10151e;
    --color-surface: #191e2a;
    --color-surface-sunken: #0c1018;
    --color-text: #d8dbe1;
    --color-text-secondary: #a1a9b8;
    --color-text-muted: #7b869b;
    --color-border: #313949;
    --color-border-strong: #454f63;
    --color-border-dashed: #313949;
    --color-accent: #797cd6;
    --color-accent-fill: #7174d4;
    --color-accent-line: #585bcd;
    --color-accent-soft: #25264b;
    --color-state-known: #449373;
    --color-state-uncollected: #b9753a;
    --color-state-live: #449373;

    /* 그라디언트와 그 위 글자는 다크에서도 그대로다 — 대비는 contrast 표 */

    /* 차트 계열색 (다크) — 근거는 정본 JSON semantic.chart */
    --chart-finish-base: #8274e0;
    --chart-finish-holo: #0f9dad;
    --chart-finish-reverse: #e05f92;
    --chart-grid: #232b3a;
    --chart-axis: #3b4557;
    --on-gradient: var(--ink);

    /* 다크에서는 보라 그림자가 탁해 보인다. 검정 기반으로 바꾼다 */
    --alpha-card-shadow: rgba(0, 0, 0, 0.55);
    --alpha-art-shadow: rgba(0, 0, 0, 0.5);
  }
}

@media (max-width: 760px) {
  :root {
    --text-display: 2rem;
    --text-hero: 1.625rem;
    --text-body: 1rem;
    --text-price: 1.75rem;
    --layout-pad: var(--space-5);
  }
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-fast: 0.01ms;
    --motion-base: 0.01ms;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   언어별 서체 — 한자가 겹치므로 스크립트마다 스택을 갈아 끼운다.
   카드 이름처럼 본문 언어와 다른 조각에는 그 자리에 lang 속성을 준다:
     <span lang="ja">熱風のアリーナ</span>
   ══════════════════════════════════════════════════════════════════════════ */

:lang(ko) {
  --font-sans: "IBM Plex Sans", "IBM Plex Sans KR", "IBM Plex Sans JP", sans-serif;
}

:lang(ja) {
  --font-sans: "IBM Plex Sans", "IBM Plex Sans JP", "IBM Plex Sans KR", sans-serif;
}

:lang(th) {
  --font-sans: "IBM Plex Sans", "IBM Plex Sans Thai", system-ui, sans-serif;
}

:lang(zh-Hant),
:lang(zh-TW) {
  --font-sans: "IBM Plex Sans", "Noto Sans TC", system-ui, sans-serif;
}

:lang(zh-Hans),
:lang(zh-CN) {
  --font-sans: "IBM Plex Sans", "Noto Sans SC", system-ui, sans-serif;
}

:lang(en) {
  --font-sans: "IBM Plex Sans", "IBM Plex Sans KR", "IBM Plex Sans JP", sans-serif;
  font-family: var(--font-sans);
}

:lang(ko),
:lang(ja),
:lang(th),
:lang(zh-Hant),
:lang(zh-TW),
:lang(zh-Hans),
:lang(zh-CN) {
  font-family: var(--font-sans);
}
