/* smallthang 디자인 시스템 — 색·모양 토큰 한 벌. **이 파일이 원본이다**: smallthang.com 아래에서 도는 화면
   (smallthang 로그인·홈 · 메모앱 · devboard · 각 프로젝트 작업대)이 같은 값을 쓰도록 여기서 복사해 간다.

   인상: 리넨 바탕 · 월넛 잉크 · 오크 헤어라인 · 더스티 레드 강조. **순검정 · 순백은 쓰지 않는다.**

   쓰는 법 — 화면 CSS 의 **맨 위**에 놓는다(@import 는 다른 규칙보다 앞에 있어야 브라우저가 읽는다).

       @import url("tokens.css");

   **글꼴은 이 파일에 없다.** Pretendard 를 함께 둔 프로젝트만 그 앞줄에 `@import url("fonts.css");` 를 더한다 —
   글꼴 없는 곳(smallthang, 회사 PC 로 가는 꾸러미)에서 없는 파일을 부르지 않게 하려는 것이다. 글꼴을 부르지 않아도
   `--font-sans` 는 시스템 글꼴로 서므로 화면은 그대로다.

   다크 모드는 기기 설정을 따르되, 화면이 `data-theme="light"|"dark"` 를 뿌리에 적어 두면 그쪽이 이긴다.
   대비는 `tests/contrast.py` 가 계산한다 — 값을 고치면 그 시험을 먼저 돌린다(WCAG AA: 글자 4.5:1, 큰 것 3:1). */

:root {
  color-scheme: light;

  /* 바탕과 글자 */
  --paper: #faf1e4;        /* linen-200 — 화면 바탕 */
  --card: #fdfbf6;         /* linen-000 — 카드 · 표 · 입력 칸 */
  --ink: #463a2d;          /* walnut-700 — 본문, 카드 위 10.7:1 */
  --dim: #6e5c4a;          /* walnut-500 — 흐린 글자, 6.2:1 */
  --rule: #ede4d3;         /* oak-200 — 헤어라인 */
  --soft: #f3ecdf;         /* 아주 연한 면 — 표 줄 사이 · 코드 조각 */
  --fill: #ede4d3;         /* 검색 칸 · 세그먼트 탭의 채움 */

  /* 머리 막대 */
  --head: #33291f;         /* walnut-900 */
  --head-2: #4a3c2c;       /* 눌린 단추 */
  --head-ink: #fdfbf6;     /* 머리 막대 위 글자, 13.7:1 */
  --head-dim: #b8ab9a;     /* 머리 막대 위 흐린 글자, 5.6:1 */
  --head-rule: #6e5233;    /* 머리 막대 위 테두리 */

  /* 강조 */
  --accent: #9c5047;       /* dusty red — 링크 · 아이콘 · 초점. red-500 보다 한 단계 어둡게(AA) */
  --accent-fg: #fdfbf6;
  --accent-tint: #f7e7e4;  /* red-100 — 눌린 토글 · 선택 */
  --highlight: #efc68c;    /* 5pm Light — 선·밑줄 전용, 면으로 깔지 않는다 */

  /* 뜻이 있는 색 — 서로 갈려야 한다. 넷 다 카드 위에서 글자로 쓰인다(AA) */
  --ok: #4f6138;           /* 정상 · 끝 · 최선 (짙은 올리브) */
  --exception: #8a5f38;    /* 주의 · 예외 · 부분 (oak-600) */
  --bad: #8b4a40;          /* 문제 · 멈춤 (red-600) */
  --search: #704a66;       /* 탐색 · 자유 변수 (plum) — 팔레트에 없는 색상이라 눈에 띈다 */
  --waiting: #6e5c4a;      /* 대기 · 미구현 (= --dim) */
  --ok-tint: #e9ecdf;
  --warn-tint: #f8e8cc;    /* light-200 을 살짝 밝힌 것 — 예외색 글자가 위에서 AA 를 넘도록 */
  --bad-tint: #f6e0dd;   /* --accent-tint 와 글자 그대로 같았다 — 눌린 토글과 「문제」 칩이 한 색이었다 */
  --search-tint: #f3edf4;

  /* 위험한 동작 — **위의 「뜻이 있는 색」과는 다른 갈래다.** 저것들은 무엇이 어떤 *상태*인지 말하는
     글자색(꺼짐 · 예외 · 대기)이고, 이것은 누르면 *일어날 일*을 말하는 **동작**의 색이다(지우기 ·
     되돌릴 수 없음). 그래서 상태 칩에 `--danger` 를 쓰지 않고, 지우기 단추에 `--bad` 를 쓰지 않는다.

     ■ 모양 규칙 — 위험한 동작은 **색이 아니라 모양으로** 가른다. 색은 거들 뿐이다.
       · 보통 동작(저장 · 확인) : 꽉 찬 단추 — 바탕 `--accent`, 글자 `--accent-fg`
       · 위험한 동작(지우기)    : **빈 단추** — 바탕은 놓인 면 그대로, `--danger-rule` 2px 테두리,
                                 글자 `--danger`. 가리키거나(:hover) 초점이 갔을 때(:focus-visible)만
                                 `--danger` 로 채우고 글자를 `--danger-fg` 로 뒤집는다.
       · `--danger-tint` 는 그 동작을 설명하는 안내 띠의 바탕이다(그 위 글자는 `--danger`).
       까닭: 이 팔레트는 따뜻한 쪽으로 모여 있어 강조 빨강과 위험 빨강이 **제1(protan)·제2(deutan)
       색각이상과 흑백에서 붙는다.** 채움 여부는 색을 못 보는 눈에도 남는다 — WCAG 1.4.1 이
       「색만을 유일한 수단으로 쓰지 말라」고 하는 것이 바로 이것이다. */
  --danger: #6f1114;       /* 지우기 · 되돌릴 수 없는 동작. 카드 위 11.5:1, --accent 와 색차 16.5 */
  --danger-fg: #fdfbf6;    /* 채워졌을 때의 글자 */
  --danger-tint: #f8e0e4;  /* 경고 띠의 바탕 */
  --danger-rule: #6f1114;  /* 빈 단추의 2px 테두리 */

  /* 그림 속 색 — 단면 SVG · 곡선처럼 **파이썬이 그려 페이지 안에 놓이는 것**이 따르는 토큰이다.
     밝은 벌은 본문 토큰과 같은 값이고, 어두울 때는 선이 묻히지 않게 밝은 쪽으로 옮긴다.
     혼자 서는 파일(내려받은 검도 HTML)에는 이 토큰이 없어 그림에 적힌 값으로 떨어진다. */
  --draw-outline: #463a2d;   /* 렌즈 윤곽 */
  --draw-mirror: #b8ab9a;    /* 렌즈 거울상 */
  --draw-part: #b08258;      /* 기구부 윤곽 · 치수선 */
  --draw-part-pale: #d9c4a6; /* 기구부 거울상 · 잔상 */
  --draw-part-deep: #6e5233; /* 기구부 이름 · 치수 글자 */
  --draw-axis: #cbb99d;      /* 광축 */
  --draw-faint: #a89b8a;     /* 배럴 밖 자리 · 견주는 곡선 */
  --draw-card: #fdfbf6;      /* 치수 글자 뒤 테두리 — 그림이 놓인 면의 색 */
  --draw-soft: #f3ecdf;      /* 곡선 격자 */
  --draw-rule: #ede4d3;      /* 틀 */
  --draw-dim: #6e5c4a;       /* 설명 글 */
  --draw-accent: #9c5047;   /* 모따기 · 평면부 — 강조와 같은 색 */
  --draw-ok: #4f6138;
  --draw-exception: #8a5f38;
  --draw-bad: #8b4a40;
  --draw-search: #704a66;

  /* 모양 */
  --kit-page-w: 1120px;    /* 화면 한 장의 폭 — 머리 · 몸통 · 허브 카드가 같은 자리에 선다(1280~1920 PC 기준) */
  --radius-s: 8px;
  --radius-l: 12px;
  --shadow-ink: 70 58 45;  /* 월넛 기반 저채도 그림자 — rgb(var(--shadow-ink) / .12) */
  --font-sans: -apple-system, BlinkMacSystemFont, "Pretendard Variable", Pretendard,
    "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
  --font-mono: ui-monospace, Consolas, "D2Coding", monospace;

  /* 부품의 모양 — 두 팔레트(리넨 · Primer)가 갈리는 자리. 화면 CSS 는 이 이름으로만 부른다. */
  --focus: #9c5047;        /* 키보드 초점 테두리 — 리넨은 강조색 */
  --focus-offset: 2px;     /* 초점 테두리를 단추 밖(+) · 안(-) 어디에 긋나 */
  --card-rule: var(--rule);  /* 카드 테두리 — Primer 는 없음(그림자만) */
  --card-shadow: none;
  --card-shadow-hover: none;
  --card-lift: 0px;        /* 가리킬 때 카드가 떠오르는 거리 */
  --font-size-body: 15px;
  --font-size-title: 13px; /* 카드 제목(「로드맵」 · 「마지막 배포」) */
  --title-weight: 700;
  --title-ink: var(--dim);
  --title-tracking: .06em;
  --num-figures: normal;   /* 시각 · 개수 — Primer 는 tabular-nums(숫자만 같은 폭) */
  --space-pad: 16px;       /* 카드 안쪽 여백 */
  --space-gap: 12px;       /* 줄 사이 */
  --motion-fast: 0s;       /* 펼치기 · 가리키기 — 리넨은 움직이지 않는다 */
}

/* 넓은 화면에서는 한 장을 더 넓게 쓴다 — 4K 모니터에서 화면의 절반만 쓰고 있다는 지적
   (사용자 2026-09-21 대시보드 피드백 #80). 1120px 은 1280~1920 기준이라 그보다 넓은 화면에서는
   양쪽 여백이 글보다 넓어진다. 두 단계로 올린다 — 실제로 쓰는 창이 1700px 이어서 한 단계만
   (1800px) 두었을 때는 아무 이득이 없었다. 차례가 중요하다: 뒤의 규칙이 앞을 덮는다. */
@media (min-width: 1500px) {
  :root { --kit-page-w: 1320px; }
}
@media (min-width: 1800px) {
  :root { --kit-page-w: 1480px; }
}

/* 다크 모드 — 디자인 원본에는 없어 파생했다: 깊은 월넛 바탕 + 월넛 카드 + 리넨 글자 + 밝힌 강조.
   뜻이 있는 색은 같은 계열을 밝은 쪽으로 옮겨, 어두운 카드 위에서 6:1 이상이 되게 했다. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --paper: #1f1913;
    --card: #33291f;
    --ink: #fdfbf6;
    --dim: #d3b58f;        /* oak-300, 7.3:1 */
    --rule: #4a3d30;
    --soft: #463a2d;
    --fill: #463a2d;
    --head: #33291f;
    --head-2: #4a3c2c;
    --head-ink: #fdfbf6;
    --head-dim: #d3b58f;
    --head-rule: #93683f;
    --accent: #e8a193;     /* red-soft, 6.7:1 */
    --focus: #e8a193;
    --accent-fg: #33291f;
    --accent-tint: #4a342c;
    --highlight: #efc68c;
    --ok: #b8c79a;         /* 7.9:1 */
    --exception: #efc68c;  /* 8.9:1 */
    --bad: #f2b8ad;        /* 8.3:1 */
    --search: #d9b4d0;     /* 7.7:1 */
    --waiting: #d3b58f;
    --ok-tint: #38412c;
    --warn-tint: #4d3a24;
    --bad-tint: #5a3a33;
    --search-tint: #453447;
    /* 위험한 동작 — 밝은 벌에 적은 주석(모양 규칙까지)이 그대로 적용된다. 어두운 카드 위에서는 짙은
       자두를 쓸 수 없어 연분홍 쪽으로 옮겼다: 카드 위 7.4:1, --accent 와 색차 12.0(제1 16.1 · 제2 12.5). */
    --danger: #e9aabb;
    --danger-fg: #33291f;
    --danger-tint: #4e2f37;
    --danger-rule: #e9aabb;
    --draw-outline: #f0e6d6;
    --draw-mirror: #9c8d79;
    --draw-part: #c89a6a;
    --draw-part-pale: #8a6f4f;
    --draw-part-deep: #d3b58f;
    --draw-axis: #7d6a4f;
    --draw-faint: #8a7b68;
    --draw-card: #33291f;
    --draw-soft: #463a2d;
    --draw-rule: #4a3d30;
    --draw-dim: #d3b58f;
    --draw-accent: #e8a193;
    --draw-accent: #e8a193;
  --draw-ok: #b8c79a;
    --draw-exception: #efc68c;
    --draw-bad: #f2b8ad;
    --draw-search: #d9b4d0;
    --shadow-ink: 0 0 0;
  }
}
/* 화면이 스스로 고른 값은 기기 설정을 이긴다 — 위 블록과 같은 값을 한 번 더 적는다(CSS 에는 변수 상속이 없다). */
:root[data-theme="dark"] {
  color-scheme: dark;
  --focus: #e8a193;
  --paper: #1f1913;
  --card: #33291f;
  --ink: #fdfbf6;
  --dim: #d3b58f;
  --rule: #4a3d30;
  --soft: #463a2d;
  --fill: #463a2d;
  --head: #33291f;
  --head-2: #4a3c2c;
  --head-ink: #fdfbf6;
  --head-dim: #d3b58f;
  --head-rule: #93683f;
  --accent: #e8a193;
  --accent-fg: #33291f;
  --accent-tint: #4a342c;
  --highlight: #efc68c;
  --ok: #b8c79a;
  --exception: #efc68c;
  --bad: #f2b8ad;
  --search: #d9b4d0;
  --waiting: #d3b58f;
  --ok-tint: #38412c;
  --warn-tint: #4d3a24;
  --bad-tint: #5a3a33;
  --search-tint: #453447;
  --danger: #e9aabb;
  --danger-fg: #33291f;
  --danger-tint: #4e2f37;
  --danger-rule: #e9aabb;
  --draw-outline: #f0e6d6;
  --draw-mirror: #9c8d79;
  --draw-part: #c89a6a;
  --draw-part-pale: #8a6f4f;
  --draw-part-deep: #d3b58f;
  --draw-axis: #7d6a4f;
  --draw-faint: #8a7b68;
  --draw-card: #33291f;
  --draw-soft: #463a2d;
  --draw-rule: #4a3d30;
  --draw-dim: #d3b58f;
  --draw-accent: #e8a193;
  --draw-ok: #b8c79a;
  --draw-exception: #efc68c;
  --draw-bad: #f2b8ad;
  --draw-search: #d9b4d0;
  --shadow-ink: 0 0 0;
}

/* ── 둘째 팔레트 「Primer」 — 사용자 2026-09-30 #247 · #252 ─────────────────────────────────────
   뿌리에 `data-palette="primer"` 를 적은 화면만 바뀐다(적지 않으면 위의 리넨 그대로). 고른 것:
   바탕 · 카드 · 강조는 리넨 그대로(1a 2a), 머리 띠는 Primer 먹색(3b), 모서리 2px(4c), 테두리 없이 그림자만(5c),
   본문 14 · 제목 16 굵게(6b), 숫자만 같은 폭(7c), 보통 간격(8b), 가리키면 카드가 떠오름(13c), 0.15초 스며듦(14b),
   Primer 파란 안쪽 초점(16b), 어두울 때는 Primer 흐린 어둠 #212830(17c).
   어두운 벌은 밝은 벌이 적은 색 토큰을 **모두** 다시 적는다 — 밝은 벌 블록이 리넨 어둠보다 뒤에 있어
   빠진 이름은 밝은 값으로 새기 때문이다(`tests/test_tokens.py` PrimerTests 가 잡는다). */
:root[data-palette="primer"] {
  --head: #25292e;         /* Primer 먹색 띠 */
  --head-2: #32383f;
  --head-ink: #f0f6fc;     /* 13.4:1 */
  --head-dim: #b7bdc8;     /* 7.8:1 */
  --head-rule: #3d444d;
  --focus: #0969da;        /* Primer 파랑 — 카드 위 5.0:1 */
  --focus-offset: -2px;
  --radius-s: 2px;
  --radius-l: 2px;
  --card-rule: transparent;
  --card-shadow: 0 1px 3px rgb(var(--shadow-ink) / .12), 0 4px 12px rgb(var(--shadow-ink) / .06);
  --card-shadow-hover: 0 6px 16px rgb(var(--shadow-ink) / .14);
  --card-lift: -2px;
  --font-size-body: 14px;
  --font-size-title: 16px;
  --title-weight: 600;
  --title-ink: var(--ink);
  --title-tracking: 0;
  --num-figures: tabular-nums;
  --space-pad: 12px;
  --space-gap: 8px;
  --motion-fast: .15s;
}
@media (prefers-color-scheme: dark) {
  :root[data-palette="primer"]:not([data-theme="light"]) {
    color-scheme: dark;
    --paper: #212830;
    --card: #262c36;
    --ink: #d1d7e0;          /* 9.7:1 */
    --dim: #9198a1;          /* 4.8:1 */
    --rule: #3d444d;
    --soft: #2a313c;
    --fill: #2a313c;
    --head: #151b23;
    --head-2: #262c36;
    --head-ink: #d1d7e0;
    --head-dim: #9198a1;
    --head-rule: #3d444d;
    --accent: #e8a193;       /* 리넨 어둠과 같은 밝힌 더스티 레드(2a) — 6.7:1 */
    --accent-fg: #262c36;
    --accent-tint: #4a3638;
    --highlight: #daaa3f;
    --focus: #478be6;        /* Primer dimmed 파랑 — 비텍스트 4.1:1 */
    --ok: #6bc46d;
    --exception: #daaa3f;
    --bad: #ff938a;
    --search: #dcbdfb;
    --waiting: #9198a1;
    --ok-tint: #283a2c;
    --warn-tint: #3d3421;
    --bad-tint: #4a2b2b;
    --search-tint: #362c4a;
    --danger: #e9aabb;
    --danger-fg: #262c36;
    --danger-tint: #4e2f37;
    --danger-rule: #e9aabb;
    --draw-card: #262c36;
    --draw-soft: #2a313c;
    --draw-rule: #3d444d;
    --draw-dim: #9198a1;
    --shadow-ink: 1 4 9;
  }
}
:root[data-palette="primer"][data-theme="dark"] {
  color-scheme: dark;
  --paper: #212830;
  --card: #262c36;
  --ink: #d1d7e0;          /* 9.7:1 */
  --dim: #9198a1;          /* 4.8:1 */
  --rule: #3d444d;
  --soft: #2a313c;
  --fill: #2a313c;
  --head: #151b23;
  --head-2: #262c36;
  --head-ink: #d1d7e0;
  --head-dim: #9198a1;
  --head-rule: #3d444d;
  --accent: #e8a193;       /* 리넨 어둠과 같은 밝힌 더스티 레드(2a) — 6.7:1 */
  --accent-fg: #262c36;
  --accent-tint: #4a3638;
  --highlight: #daaa3f;
  --focus: #478be6;        /* Primer dimmed 파랑 — 비텍스트 4.1:1 */
  --ok: #6bc46d;
  --exception: #daaa3f;
  --bad: #ff938a;
  --search: #dcbdfb;
  --waiting: #9198a1;
  --ok-tint: #283a2c;
  --warn-tint: #3d3421;
  --bad-tint: #4a2b2b;
  --search-tint: #362c4a;
  --danger: #e9aabb;
  --danger-fg: #262c36;
  --danger-tint: #4e2f37;
  --danger-rule: #e9aabb;
  --draw-card: #262c36;
  --draw-soft: #2a313c;
  --draw-rule: #3d444d;
  --draw-dim: #9198a1;
  --shadow-ink: 1 4 9;
}
/* 움직임 줄이기를 켠 기기에서는 어느 팔레트든 움직이지 않는다. */
@media (prefers-reduced-motion: reduce) {
  :root[data-palette="primer"] { --motion-fast: 0s; --card-lift: 0px; }
}

/* 선 아이콘 — Lucide 글리프(ISC)를 굵기 1.5 로. 이모지·채운 아이콘은 쓰지 않는다(기기마다 다르게 그려진다). */
.icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.22em;
}
.icon .dot { stroke-width: 2.6; }
/* 되풀이 아이콘 한 벌 — 자리를 차지하지 않게 크기만 0 으로 둔다(display:none 이면 <use> 를 못 그리는 브라우저가 있다). */
.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
/* 아이콘과 글자를 나란히 — 아이콘을 실제로 넣은 것에만 붙인다(자리를 바꾸는 규칙이다). */
.with-icon { display: inline-flex; align-items: center; gap: 6px; }

/* 머리띠 왼쪽의 프로젝트 이름 — 어느 화면에서든 마크가 같은 자리에 선다. */
.brand { display: inline-flex; align-items: center; gap: 6px; }
/* 마크 자체 — smallthang 의 네모 글리프를 현재 글자색으로 찍으므로 밝을 때나 어두울 때나 맞는다. */
.st-mark {
  display: inline-block;
  width: 22px;
  height: 22px;
  background-color: currentColor;
  -webkit-mask: var(--st-mark-url) no-repeat center / contain;
  mask: var(--st-mark-url) no-repeat center / contain;
}
