/* =====================================================
   고피싱 — 디자인 토큰  (2026-09-08 · 개편 1단계)
   =====================================================

   🚨🚨**app.css 뒤에 링크한다.** index.html에 스타일시트가 둘뿐이고(app.css → tokens.css),
     app.css가 `:root`(5~32줄)와 다크 블록에서 `--primary`·`--text-sub`·`--radius`를 **직접 정의**하므로
     같은 특이도에서는 **뒤에 오는 쪽이 이긴다.** 앞에 두면 이 파일이 통째로 죽는다.

   ⭐**되돌리기 = index.html의 link 한 줄 삭제.** 이 파일은 값만 정의하고 선택자를 새로 만들지 않는다
     (아래 «지금 깨져 있는 것» 절만 예외 — 그건 별도 커밋이다).

   ⭐**기존 토큰은 지우지 않고 별칭으로 잇는다.** app.css·js의 `var(--bg)`·`var(--text)` 호출부가
     1,446곳이라 이름을 바꾸면 전부 손봐야 한다. 새 이름을 만들고 옛 이름을 그 위에 얹는다.

   📏**세는 법(진척 비교용 · 바꾸지 말 것)**
     · 색   = app.css에서 주석을 뺀 줄의 hex + rgb() → **2026-09-08 기준 763회 · 고유 223색**
     · 이모지 = js/·common/ 문자열 리터럴 안 → **2026-09-08 기준 729회 · 149종**
     정의를 바꾸면 이전 숫자와 비교가 안 된다(앞선 조사가 215/592/837로 제각각 세서 못 비교했다).
   ===================================================== */

/* ── 웹폰트 — Pretendard, **라틴·숫자만** ────────────────────
   ⭐한글은 시스템 폰트에 그대로 떨어뜨린다. `unicode-range`가 그 경계를 정하므로
     브라우저는 한글 자리에서 이 파일을 **아예 내려받지 않는다**.
     3벌 합쳐 21KB다(한글까지 넣으면 화면당 70~270KB — 그건 5단계에 실측하고 정한다).

   왜 라틴·숫자만이라도 넣는가 —
   ① **숫자가 이 앱의 본문이다.** 물때·조위·수온·풍속·거리·마릿수·cm·금액.
      기기마다 숫자 모양이 달라지면 «장비처럼» 안 보인다.
   ② **600이 진짜로 있다.** 시스템 한글 폰트에 600·800이 없으면 브라우저가 **가짜로 굵게**
      그린다 — 획이 뭉개지는 인상의 직접 원인이다. 굵기를 3단(400/600/700)으로 줄이는 것이
      의미가 있으려면 그 세 벌이 실제로 존재해야 한다.

   🚫**CDN 링크로 불러오지 않는다** — 외부 의존이 생기고 오프라인에서 깨진다. 파일은 fonts/에 둔다.
   📜라이선스 SIL Open Font License 1.1 — 상업적 사용 가능. **원문을 함께 배포해야 하므로**
     `fonts/OFL.txt`를 지우지 말 것(OFL의 의무다).
   🚨글자 모양을 바꿀 일이 생기면 **파일 이름을 바꾼다**(캐시가 30일이고 이름에 해시가 없다). */
@font-face {
  font-family: 'Pretendard Num';
  src: url('../fonts/pretendard-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0020-007E, U+00B0, U+2103, U+20A9;
}
@font-face {
  font-family: 'Pretendard Num';
  src: url('../fonts/pretendard-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0020-007E, U+00B0, U+2103, U+20A9;
}
@font-face {
  font-family: 'Pretendard Num';
  src: url('../fonts/pretendard-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0020-007E, U+00B0, U+2103, U+20A9;
}

/* app.css:114의 body 폰트 스택 **앞에** Pretendard를 세운다.
   ★app.css가 뒤가 아니라 앞에 있으므로 여기서 다시 선언해야 이긴다. 스택의 나머지는 그대로 둔다 —
     한글은 여전히 시스템 폰트(-apple-system / Noto Sans KR)가 그린다. */
body {
  font-family: 'Pretendard Num', -apple-system, BlinkMacSystemFont, 'Noto Sans KR', sans-serif;
  font-size: var(--fs-4);
}

/* ⭐**숫자가 흔들리지 않게.** 자릿수가 달라도 폭이 같아야 표·목록에서 세로가 맞는다.
   물때·조위·수온·기온·풍속·거리·마릿수·cm·금액에 붙인다.
   📌현행 `tabular-nums`가 걸린 8곳(레이더 시각·결제 금액·캘린더)이 이미 «정돈돼 보이는» 이유다. */
.num {
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}

:root {
  /* ── 중립 «잉크 램프» 8단 ─────────────────
     🚨--ink-4는 흰 위 3.48:1이라 **아이콘·비활성 전용이고 글자에 쓰지 않는다**(WCAG AA 4.5:1 미달).
       보조 글자는 --ink-5(7.35:1)를 쓴다. */
  --ink-0: #ffffff;   /* 표면(카드·시트) */
  /* 🚨🚨**주색 «위에 얹는» 글자색**(2026-09-10). --primary 하나가 «글자색»과 «배경색» 두 역할을
     하는데, 다크에서 AA를 맞추려고 밝게(#35C07B) 바꾼 순간 **배경으로 쓰인 자리에서 흰 글자와
     2.34:1**이 됐다(바다 #4FB0F0은 2.39:1). 밝히면 글자로는 좋아지고 배경으로는 나빠진다.
     ⭐그래서 «주색 배경 위 글자»를 따로 둔다 — 라이트는 흰색, 다크는 어두운 색(Material의
     on-primary와 같은 개념). 다크에서 7.90:1(민물)·7.74:1(바다).
     ⭐**새 색을 만들지 않는다** — 앱 다크 바탕(--ink-1 #10141a)을 그대로 쓴다.
     🚨`background: var(--primary)`와 짝인 자리에만 쓴다. --primary-light 배경에는 쓰지 않는다. */
  --on-primary: #ffffff;
  --ink-1: #f4f6f7;   /* 페이지 바탕 */
  --ink-2: #e9edf0;   /* 약한 구분면 */
  --ink-3: #d6dce1;   /* 테두리 */
  --ink-4: #7f8b96;   /* 아이콘·비활성 — 🚫글자 금지 */
  --ink-5: #4d5763;   /* 보조 글자 */
  --ink-6: #2b333c;   /* 본문 */
  --ink-7: #11161c;   /* 제목 */

  /* ── 데이터 램프 4단 + 미지 ────────────────
     ⭐**지표가 색을 갖지 않고 값이 색을 갖는다.** 임계치를 넘은 값에만 붙인다.
       (실제 배선은 3단계 — 여기서는 값만 정의한다) */
  --lv-good:    #046a38;  --lv-good-bg: #d8f0e3;  --lv-good-line: #b7e0c9;
  --lv-fair:    #8a5a00;  --lv-fair-bg: #fbedcb;  --lv-fair-line: #e8d3a2;
  --lv-poor:    #a03d08;  --lv-poor-bg: #fce3d2;  --lv-poor-line: #f0c9ab;
  --lv-bad:     #a4161a;  --lv-bad-bg:  #fbdddd;  --lv-bad-line:  #f0bcbc;
  /* 🚨--lv-none은 **색이 아니라 형태**다 — 점선 + 화면에 「확인 안 됨」 글자.
     «없음»(조회 성공·해당 없음)과 «못 받음»(응답 실패)은 다른 일이고, 둘 다 빈칸으로 두면 안 된다.
     2026-09-06 포털 장애 때 catch(()=>null)로 뭉개져 통째로 숨겨진 자리다.
     ⭐점선은 **보조 신호**이고 「확인 안 됨」은 **실제 텍스트**여야 한다 — 점선만으로는 화면을
       못 보는 사람에게 «값이 없다»와 «그냥 비었다»가 구별되지 않아 원칙 1이 거기서 무너진다. */
  --lv-none-fg:   var(--ink-5);
  --lv-none-line: var(--ink-3);

  /* ── 「내 것」 출처 표시 ────────────────────
     ⭐**같은 뜻을 세 자리가 서로 다른 보라로 칠하고 있었다**(3단계 · 2026-09-10):
       `.fish-src.gS`(자체 통계) #6b3fa0 · `.ai2-srcchips .sc-mine`(내 기록) #6247b0 ·
       `.tp-src.mine`(내 것) #7a4bd0. 뜻이 같으면 색도 같아야 한다 — 여기 한 벌로 모았다.
     🚨**«보라 폐기»에서 이 자리만 남긴 이유**: 「이 값이 내 기록에서 왔다」는 회원에게 실제로
       쓸모 있는 구분이고, 형제 칩(정부·학술 초록 / 전문지 파랑 / 경험담 베이지)이 전부 색을
       갖고 있어 여기만 무채색이면 «꺼진 칩»처럼 읽힌다. 출처 칩 전체를 무채색으로 갈지는
       더 큰 결정이라 4단계 아이콘 정리와 함께 본다.
     🚫`--primary`를 쓰면 안 된다 — 민물/바다 모드에 따라 갈아끼워져 «내 것»이 물 따라 바뀐다. */
  --src-mine:      #5f3d9e;   /* #f2ecfd 위 6.87:1 */
  --src-mine-bg:   #f2ecfd;
  --src-mine-line: #ddd0f5;

  /* ── 터치 영역 ──────────────────────────────
     ⭐**보이는 크기와 누르는 크기는 다른 값이다**(3단계 · 2026-09-10).
     30px짜리 동그란 닫기 버튼을 44px로 키우면 제목줄이 통째로 두꺼워진다 — 그래서 **보이는 것은
     그대로 두고 히트 영역만** 넓힌다(계획서의 «::after로 히트영역만»).
     🚨**옆에 이웃이 가까우면 쓰면 안 된다.** 6px 간격 칩 두 개를 각각 44px로 부풀리면 서로 겹쳐
       경계에서 엉뚱한 쪽이 눌린다 — 작은 표적보다 나쁘다. 이 장치는 **홀로 있는 아이콘 버튼**용이다.
     쓰는 법: 그 규칙에 `.tap-wide`를 함께 적거나 아래 확장 선택자에 추가한다. */
  --tap-min: 44px;

  /* ── 글자 스케일 8단 ──────────────────────
     현행 30종(9·9.5·10·10.5·11·11.5·12·12.5·13·13.5·14·14.5px…)을 여기로 접는다(2단계).
     스냅표: 9~11.5→fs-1 / 12·12.5→fs-2 / 13·13.5→fs-3 / 14~16→fs-4 / 17~19→fs-5
             20~24→fs-6 / 26~38→fs-7 / 42~56→fs-8
     🚨--fs-1(11px)이 **하한**이다. 야외·직사광선에서 9~10.5px는 «없는 정보»와 같다. */
  --fs-1: .6875rem;   /* 11px — 캡션·배지 */
  --fs-2: .75rem;     /* 12px — 메타·라벨 */
  --fs-3: .8125rem;   /* 13px — 보조 본문 */
  --fs-4: .9375rem;   /* 15px — 본문 */
  --fs-5: 1.0625rem;  /* 17px — 카드 제목 */
  --fs-6: 1.375rem;   /* 22px — 섹션 수치 */
  --fs-7: 2.125rem;   /* 34px — 주지표 */
  --fs-8: 3rem;       /* 48px — 히어로 수치(화면당 하나) */
  /* 🚨🚨**이모지·아이콘의 font-size는 «그림 치수»라 이 스케일 밖이다.**
     2026-09-08에 일괄 스냅을 돌렸다가 아바타 이모지가 40→34px로 줄어 **고정 원 안에 빈 자리가
     생겼고**, 도감 카드 아이콘 30→34 · 상세 56→48 · 주간 날씨 이모지 18→17로 함께 흔들렸다.
     실측 12곳을 되돌렸다. 판별 기준: **선택자 이름에 icon·emoji·avatar·glyph·ic가 들어가면 그림이다.**
     ⭐단 이름만으로 갈리지 않는다 — `#header-avatar .hdr-my`는 이름에 avatar가 있지만
       실제로는 「마이」라는 **글자**라 11px로 스케일에 넣었다. 자동 규칙 뒤에 눈으로 한 번 본다.
     📌`scripts/design-lint.js`의 «스케일 밖 font-size» 검사도 같은 예외를 쓴다. */

  /* 굵기 3단. 현행 800이 247곳·900이 1곳인데 **시스템 한글 폰트에 800이 없어** 브라우저가
     가짜 볼드로 그린다 — «뭉개져 보인다»는 인상의 직접 원인이다(2단계에 치환). */
  --fw-normal: 400;
  --fw-medium: 600;
  --fw-bold:   700;

  --lh-tight: 1.25;   /* 제목·수치 */
  --lh:       1.45;   /* UI 본문 */
  --lh-read:  1.65;   /* 리포트 본문 */

  /* ── 간격 7단 ─────────────────────────────
     현행 34종·1,654회 중 1,067회가 4의 배수가 아니다. 고정 규칙 셋:
     화면 좌우 --sp-4 · 카드 안쪽 --sp-3 · 섹션 사이 --sp-5
     🚨지도 오버레이처럼 «실기기 조정» 주석이 붙은 자리는 손대지 않는다. */
  --sp-0: 2px;   /* 미세 정렬 전용 — 실측 130회로 실제로 필요한 자리가 있다 */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;

  /* ── 모서리 4단 + 사진 ─────────────────────
     현행 30종. 기존 --radius(12) / --radius-sm(8)을 **그대로 잇는다**(아래 별칭). */
  --r-1: 8px;      /* 칩·배지·작은 버튼 */
  --r-2: 12px;     /* 카드·입력·버튼 */
  --r-3: 16px;     /* 시트·모달 */
  --r-pill: 999px;
  --r-photo: 10px; /* 카드보다 2px 작게 = «안에 든 것»으로 읽힌다 */

  /* ── 높이 3단 — 그림자보다 테두리를 먼저 ────
     ⭐기본 카드는 **그림자 없이 1px 테두리**다. 그림자는 테마 반전에서 안 살아남고 테두리는 살아남는다.
       현행 84선언·67종·알파 25종이 이 셋으로 접힌다(3단계). */
  --elev-0: none;
  --elev-1: 0 1px 2px rgba(16, 22, 28, .06);   /* FAB·드롭다운·sticky 헤더 */
  --elev-2: 0 8px 24px rgba(16, 22, 28, .14);  /* 시트·모달 */
  --elev-photo: inset 0 0 0 1px rgba(0, 0, 0, .06);  /* 🚫사진에 그림자 금지 — 가장자리만 */

  /* ── 모션 ────────────────────────────────
     현행 transition 26종·animation 17종. `all .12s` 같은 것은 속성을 명시하는 쪽으로. */
  --dur-1: 120ms;
  --dur-2: 180ms;
  --dur-3: 280ms;
  --ease: cubic-bezier(.2, .8, .2, 1);

  /* ── 터치 ────────────────────────────────
     🚨실측 현행: .chip ≈25px · .ai-quick-chip ≈26px · .fchip.sub ≈28px · .fchip ≈32px — **전부 미달**.
       전면 적용은 3단계(밀도를 올리기 «전»에 세워야 한다). */
  --tap: 44px;

  /* ── 옛 이름 잇기 (호출부를 안 건드린다) ──── */
  --bg:       var(--ink-1);
  --surface:  var(--ink-0);
  --text:     var(--ink-6);
  --text-sub: var(--ink-5);
  --border:   var(--ink-3);
  --radius:   var(--r-2);
  --radius-sm: var(--r-1);
  /* ⭐**--line은 정의된 적이 없었다** — `border: 1px dashed var(--line)` 단축이 통째로 무효가 되어
     출조 계획·포인트 고르기의 «더 보기» 점선 버튼에 테두리가 안 그려졌다.
     실측 4곳: css/app.css(.tp-pkmore · .sp-more) · js/tabs/map.js · js/tabs/my-admin.js. 이 한 줄로 넷이 산다. */
  --line: var(--border);
  --mute: var(--ink-5);
}

/* ── 다크 ──────────────────────────────────
   🚨app.css가 다크를 **두 벌**(`[data-theme="dark"]`과 `@media`)로 쓰므로 여기서도 두 벌이다.
     한쪽만 고치면 «시스템 설정을 따르는» 회원(속성 없음)과 «다크를 직접 고른» 회원이 갈린다. */
:root[data-theme="dark"] {
  --ink-0: #1b212c;
  --ink-1: #10141a;
  --ink-2: #232b37;
  --ink-3: #2e3644;
  --ink-4: #7d8794;   /* 🚫글자 금지 — 4.43:1(비텍스트 3:1만 통과) */
  --ink-5: #a7b1bd;   /* 보조 글자 7.43:1 */
  --ink-6: #d5dbe3;
  --ink-7: #eef1f5;

  /* 🚨**교체**. 현행 --primary #1f9257은 다크 표면(#1b212c) 위 **4.08:1로 AA 미달**인데
     `color: var(--primary)`가 app.css에 173회다 — 링크·활성 라벨·섹션 헤더가 전부 걸려 있다.
     ⭐--fresh-primary는 --primary와 **항상 같게** 유지한다(app.css:11~14 주석의 규약). */
  --primary:       #35C07B;   /* 6.90:1 */
  --on-primary:    #10141a;   /* 주색 배경 위 글자 — 민물 7.90:1 · 바다 7.74:1 */
  --fresh-primary: #35C07B;
  --sea-primary:   #4FB0F0;   /* 6.77:1 */

  --lv-good: #4ade80;  --lv-good-bg: #10301f;  --lv-good-line: #1e4a31;
  --lv-fair: #fbbf4a;  --lv-fair-bg: #33260b;  --lv-fair-line: #4c3a15;
  --lv-poor: #fb9a5c;  --lv-poor-bg: #38210f;  --lv-poor-line: #55341a;
  --lv-bad:  #ff8a8a;  --lv-bad-bg:  #3a1618;  --lv-bad-line:  #572527;

  --src-mine: #c4a9f5;  --src-mine-bg: #251d3a;  --src-mine-line: #3a2f57;   /* 7.86:1 */

  --elev-1: 0 1px 2px rgba(0, 0, 0, .5);
  --elev-2: 0 8px 24px rgba(0, 0, 0, .6);
  --elev-photo: inset 0 0 0 1px rgba(255, 255, 255, .08);
}
:root[data-theme="dark"] body.mode-sea { --primary: #4FB0F0; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink-0: #1b212c;
    --ink-1: #10141a;
    --ink-2: #232b37;
    --ink-3: #2e3644;
    --ink-4: #7d8794;
    --ink-5: #a7b1bd;
    --ink-6: #d5dbe3;
    --ink-7: #eef1f5;

    --primary:       #35C07B;
    --on-primary:    #10141a;
    --fresh-primary: #35C07B;
    --sea-primary:   #4FB0F0;

    --lv-good: #4ade80;  --lv-good-bg: #10301f;  --lv-good-line: #1e4a31;
    --lv-fair: #fbbf4a;  --lv-fair-bg: #33260b;  --lv-fair-line: #4c3a15;
    --lv-poor: #fb9a5c;  --lv-poor-bg: #38210f;  --lv-poor-line: #55341a;
    --lv-bad:  #ff8a8a;  --lv-bad-bg:  #3a1618;  --lv-bad-line:  #572527;

    --src-mine: #c4a9f5;  --src-mine-bg: #251d3a;  --src-mine-line: #3a2f57;

    --elev-1: 0 1px 2px rgba(0, 0, 0, .5);
    --elev-2: 0 8px 24px rgba(0, 0, 0, .6);
    --elev-photo: inset 0 0 0 1px rgba(255, 255, 255, .08);
  }
  :root:not([data-theme="light"]) body.mode-sea { --primary: #4FB0F0; }
}

/* ── 접근성 ────────────────────────────────
   현행 대응이 2줄뿐이라 @keyframes 16개 중 14개가 «동작 줄이기» 설정을 무시한다.
   스토어 심사에서 지적될 수 있는 항목이기도 하다. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
