@iyulab/components 1.20.0 → 1.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/dist/_virtual/_glob-assets_raw/dark.css.e8ac080d.js +1 -1
  3. package/dist/_virtual/_glob-assets_raw/light.css.637cb2f8.js +1 -1
  4. package/dist/components/UFloatingElement.styles.js +1 -1
  5. package/dist/components/UOverlayElement.styles.js +1 -1
  6. package/dist/components/alert/UAlert.styles.js +8 -6
  7. package/dist/components/breadcrumb-item/UBreadcrumbItem.styles.js +1 -1
  8. package/dist/components/button/UButton.styles.js +1 -1
  9. package/dist/components/card/UCard.styles.js +3 -3
  10. package/dist/components/carousel/UCarousel.styles.js +4 -4
  11. package/dist/components/checkbox/UCheckbox.styles.js +2 -2
  12. package/dist/components/dialog/UDialog.styles.js +2 -2
  13. package/dist/components/drawer/UDrawer.styles.js +2 -2
  14. package/dist/components/input/UInput.styles.js +3 -3
  15. package/dist/components/menu-item/UMenuItem.styles.js +4 -4
  16. package/dist/components/option/UOption.styles.js +3 -3
  17. package/dist/components/progress-bar/UProgressBar.styles.js +2 -2
  18. package/dist/components/progress-ring/UProgressRing.styles.js +1 -1
  19. package/dist/components/rating/URating.styles.js +1 -1
  20. package/dist/components/select/USelect.styles.js +3 -3
  21. package/dist/components/slider/USlider.styles.js +3 -3
  22. package/dist/components/split-panel/USplitPanel.styles.js +1 -1
  23. package/dist/components/switch/USwitch.styles.js +11 -8
  24. package/dist/components/tab/UTab.styles.js +1 -1
  25. package/dist/components/tab-panel/UTabPanel.styles.js +1 -1
  26. package/dist/components/tag/UTag.styles.js +1 -1
  27. package/dist/components/textarea/UTextarea.styles.js +1 -1
  28. package/dist/components/tooltip/UTooltip.styles.js +3 -3
  29. package/dist/components/tree-item/UTreeItem.styles.js +2 -2
  30. package/dist/styles/dark.css +99 -6
  31. package/dist/styles/light.css +117 -7
  32. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,94 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.21.0] - 2026-08-03
4
+
5
+ > **디자인 파운데이션 릴리스.** 이 패키지에는 **글자 크기·굵기·행간·자간 토큰이 하나도
6
+ > 없었다**(폰트 패밀리 6개가 전부였다). 그래서 소비자는 화면의 모든 글자 크기를 리터럴로
7
+ > 적었고, 한 앱 안에 12·12.5·13·13.5·14 가 섞였다. 위계가 없으면 화면이 평평해 보이고,
8
+ > 평평한 화면은 낡아 보인다. 이 릴리스는 **축을 연다** — 값의 취향은 상위 계층 몫이다.
9
+
10
+ ### Added
11
+
12
+ - **타입 스케일 축** — 7단 × 4속성. 단 이름은 크기가 아니라 **역할**이다.
13
+
14
+ ```
15
+ --u-text-{display,title,subtitle,body,label,caption,overline}-{size,weight,leading,tracking}
16
+ ```
17
+
18
+ ★**네 값을 단 단위로 묶어 낸다.** 크기만 주면 소비자가 굵기·행간을 각자 정해 결국
19
+ 제각각이 된다 — 스케일이 스케일로 동작하려면 한 단이 네 값을 모두 소유해야 한다.
20
+
21
+ 🔴**한글 기준으로 값을 골랐다**: ⑴행간 **전 단 1.4 이상**(라틴 관례 1.2 는 한글에서
22
+ 답답하다 — 받침 때문에 글자 상자가 세로로 꽉 차 있다) ⑵자간은 **0 이 기본**이고 큰
23
+ 제목만 음수(한글에 양수 자간은 가독성을 떨어뜨린다) ⑶양수 자간은 `overline` 하나뿐이고
24
+ 그 단은 **영문·숫자 라벨**을 전제한다.
25
+ ⚠**`text-transform` 은 토큰으로 내지 않는다** — 한글에 대문자가 없어 `uppercase` 가
26
+ 아무 효과가 없고, 영문이 섞이면 그것만 커져 오히려 어수선해진다.
27
+
28
+ ★**이 축의 1차 소비자는 컴포넌트가 아니라 소비 앱이다** — 화면의 제목·라벨·캡션을
29
+ 짓는 쪽이다. 컴포넌트는 대부분 자기 크기가 이미 정해져 있고(툴팁은 툴팁이다),
30
+ `u-button` 의 `size` 축 리터럴(12/14/16px)은 **결손이 아니라 설계**다(여백·최소높이가
31
+ 전부 `em` 이라 그 한 값으로 비례한다). ⇒ 컴포넌트 배선은 **값이 이미 단과 일치하는
32
+ 자리에만** 했다(시각 변경 0): `u-alert` 머리줄 → `subtitle` · `u-tooltip`·`u-tag` →
33
+ `caption`.
34
+
35
+ ⚠**남은 것 하나를 숨기지 않고 적는다**: `u-dialog`·`u-drawer` 의 제목은 **18px** 인데
36
+ **스케일에 18px 단이 없다**(title 20 / subtitle 16). 값이 어긋나므로 배선하지 않았다 —
37
+ 맞추려면 제목이 2px 작아지거나(시각 변경) 스케일에 단을 하나 더해야 한다(7 → 8단).
38
+ **사람 판단으로 올린다.**
39
+
40
+ - **모션 축** — `--u-duration-{instant,fast,normal,slow}` · `--u-ease-{standard,decelerate,accelerate}`.
41
+ ★**`prefers-reduced-motion: reduce` 존중을 라이브러리가 진다** — 지속시간을 0 으로 눌러
42
+ 이 축을 경유하는 모든 애니메이션이 함께 멈춘다. 소비자마다 각자 처리하게 두면 반드시
43
+ 빠뜨리는 앱이 나오고, 그 앱은 접근성 감사 전까지 아무도 모른다.
44
+
45
+ **컴포넌트 `transition` 37곳 · 24파일 배선.** ⚠**리터럴 지속시간이 남아 있으면 그 자리는
46
+ `prefers-reduced-motion` 을 비껴간다** — 축이 있어도 경유하지 않으면 아무것도 멈추지
47
+ 않기 때문이다. 회귀 테스트가 **컴포넌트 시트에 리터럴 지속시간 0건**을 지킨다(폴백은
48
+ 제외 — 시트 부재 시 렌더를 살리는 장치다). 컴포넌트-로컬 지속시간 토큰
49
+ (`--switch-duration`)의 **기본값도 공용 축에서 파생**시켰다. 그러지 않으면 그
50
+ 컴포넌트만 비껴간다.
51
+
52
+ ⚠**지속시간이 계단으로 접히면서 값이 움직인다**(최대 편차는 진행바 `0.4s → 0.32s`,
53
+ −20%). 나머지는 ±10% 이내다(`0.15s → 140ms` · `0.2s → 220ms` · `0.3/0.35s → 320ms`).
54
+ **값 보존 대신 계단을 고른 이유**: 7가지 지속시간을 그대로 토큰화하면 축이 아니라
55
+ 사전이 되고, 그러면 이 축의 존재 이유(전수 경유 → 한 번에 멈춤)가 성립하지 않는다.
56
+
57
+ - **여백 스케일 상단 4단** — `xl: 20px` · `2xl: 24px` · `3xl: 32px` · `4xl: 40px`.
58
+ 종전에는 `lg`(16px)에서 끊겨 **카드 안쪽 여백·섹션 간격·페이지 여백 구간이 통째로
59
+ 비어 있었다** — LOB 화면 여백의 대부분이 그 구간이다.
60
+ ⚠`xs: 6px` 는 4px 격자를 벗어나 있으나 **바꾸지 않는다**(배선된 컨트롤 여백이 전부
61
+ 움직인다). 신규 단은 전부 4의 배수이며 테스트가 지킨다.
62
+
63
+ - **반경 스케일 상단 2단** — `2xl: 12px` · `3xl: 16px`. **면(surface)용**이다.
64
+ 카드·패널·대화상자처럼 큰 사각형은 컨트롤과 같은 반경을 쓰면 각져 보인다.
65
+ ⚠**기존 5단(3/4/6/8px)의 값은 바꾸지 않았다** — 컨트롤용이고, 바꾸면 모든 소비자의
66
+ 버튼·입력이 동시에 움직인다.
67
+
68
+ ### Changed
69
+
70
+ - ⚠**그림자가 2겹이 된다** — 접촉 그림자가 추가됐다(예: `--u-shadow-md` 는
71
+ `0 2px 8px rgba(0,0,0,.12)` → `0 2px 8px rgba(0,0,0,.12), 0 1px 2px rgba(0,0,0,.05)`).
72
+ 1겹 그림자는 경계가 탁해 회색이 낀 것처럼 보인다. **기존 레이어의 값은 그대로**이므로
73
+ 기존 인상은 유지되고 접촉면만 또렷해진다.
74
+ ★배치 순서가 **지배 레이어 먼저**인 것은 의도다 — elevation 계약이 값의 첫 레이어로
75
+ 단의 세기를 읽으므로, 그 계약과 알파 짝(`--u-shadow-color-*`)이 단일 출처로 남는다.
76
+
77
+ - ⚠**`--u-font-base` 에 CJK 폴백이 들어간다** — 국제화이지 취향이 아니다.
78
+ 종전 스택(`-apple-system, Segoe UI, Noto Sans, Helvetica, Arial`)에는 **한중일 글립을
79
+ 가진 폰트가 하나도 없었다.** Windows 는 UA 가 임의로 맑은 고딕을 고르고 macOS 는
80
+ Apple SD Gothic Neo 를 줘서 **같은 앱이 OS 마다 다른 글꼴로 렌더**됐다.
81
+ 스택 맨 앞의 `Pretendard` 는 **소비자가 로드했을 때만** 잡히는 선택적 이름이다 —
82
+ 라이브러리는 웹폰트를 네트워크로 요청하지 않는다(소비자 CSP·오프라인 환경을 깬다).
83
+
84
+ - `u-alert` glass variant 의 반경 리터럴 `16px` 이 `--u-radius-3xl` 배선으로 바뀐다(값 동일).
85
+
86
+ ### 계약 테스트
87
+
88
+ `tests/build/type-scale.test.ts` 신설 — 단·속성 존재, 두 시트 동일, 인접 단 비율 1.05~1.35,
89
+ 크기 역전 없음, **행간 1.4 이상**, **양수 자간은 overline 하나뿐**, 굵기 100 단위,
90
+ `prefers-reduced-motion` 에서 지속시간 0.
91
+
3
92
  ## [1.20.0] - 2026-08-03
4
93
 
5
94
  > ⚠**이 릴리스는 시각이 바뀐다.** 아래 항목들은 값을 고르는 문제가 아니라 **관계가
@@ -1,4 +1,4 @@
1
1
  //#region \0glob-assets_raw/dark.css.e8ac080d
2
- var dark_css_default = ":root[theme=\"dark\"] {\n color-scheme: dark;\n\n /* Neutral Colors */\n --u-neutral-0: #000000;\n --u-neutral-50: #0A0A0A;\n --u-neutral-100: #121212;\n --u-neutral-200: #1E1E1E;\n --u-neutral-300: #2A2A2A;\n --u-neutral-400: #3D3D3D;\n --u-neutral-500: #525252;\n --u-neutral-600: #6E6E6E;\n --u-neutral-700: #8A8A8A;\n --u-neutral-800: #B0B0B0;\n --u-neutral-900: #D4D4D4;\n --u-neutral-1000: #FFFFFF;\n\n /* Blue Colors */\n --u-blue-0: #030D1A;\n --u-blue-100: #061629;\n --u-blue-200: #0A223B;\n --u-blue-300: #103150;\n --u-blue-400: #174167;\n --u-blue-500: #205281;\n --u-blue-600: #2A659D;\n --u-blue-700: #3678B8;\n --u-blue-800: #478DCE;\n --u-blue-900: #5DA2DF;\n --u-blue-1000: #79BBEA;\n\n /* Green Colors */\n --u-green-0: #06140C;\n --u-green-100: #0A2114;\n --u-green-200: #10301D;\n --u-green-300: #164228;\n --u-green-400: #1F5535;\n --u-green-500: #2A6942;\n --u-green-600: #367E50;\n --u-green-700: #4A9563;\n --u-green-800: #63AB7A;\n --u-green-900: #80BE97;\n --u-green-1000: #9BCFB1;\n\n /* Yellow Colors */\n --u-yellow-0: #1C1300;\n --u-yellow-100: #2D1E00;\n --u-yellow-200: #402B00;\n --u-yellow-300: #553900;\n --u-yellow-400: #6B4900;\n --u-yellow-500: #825A00;\n --u-yellow-600: #9A6C00;\n --u-yellow-700: #B08012;\n --u-yellow-800: #C69635;\n --u-yellow-900: #D9AD5A;\n --u-yellow-1000: #E8C57F;\n\n /* Red Colors */\n --u-red-0: #1C0707;\n --u-red-100: #2C0B0B;\n --u-red-200: #3E1111;\n --u-red-300: #541818;\n --u-red-400: #6C2020;\n --u-red-500: #852A2A;\n --u-red-600: #A13535;\n --u-red-700: #B94949;\n --u-red-800: #CB6262;\n --u-red-900: #D98383;\n --u-red-1000: #E7A2A2;\n\n /* Orange Colors */\n --u-orange-0: #1D0E00;\n --u-orange-100: #2F1700;\n --u-orange-200: #421F00;\n --u-orange-300: #582A00;\n --u-orange-400: #703600;\n --u-orange-500: #8A4500;\n --u-orange-600: #A55600;\n --u-orange-700: #BD6A18;\n --u-orange-800: #D1823C;\n --u-orange-900: #E19D67;\n --u-orange-1000: #EDB992;\n\n /* Teal Colors */\n --u-teal-0: #041411;\n --u-teal-100: #07201B;\n --u-teal-200: #0B2E28;\n --u-teal-300: #10403A;\n --u-teal-400: #16544D;\n --u-teal-500: #1E6860;\n --u-teal-600: #297D74;\n --u-teal-700: #3A9389;\n --u-teal-800: #54A89F;\n --u-teal-900: #73BBB3;\n --u-teal-1000: #93CBC5;\n\n /* Cyan Colors */\n --u-cyan-0: #041318;\n --u-cyan-100: #071F29;\n --u-cyan-200: #0B2D3A;\n --u-cyan-300: #104050;\n --u-cyan-400: #165469;\n --u-cyan-500: #1E6A82;\n --u-cyan-600: #287F9C;\n --u-cyan-700: #3995B5;\n --u-cyan-800: #53AACC;\n --u-cyan-900: #73BEDD;\n --u-cyan-1000: #95CFE8;\n\n /* Purple Colors */\n --u-purple-0: #150A22;\n --u-purple-100: #220F36;\n --u-purple-200: #31164B;\n --u-purple-300: #432064;\n --u-purple-400: #572B80;\n --u-purple-500: #6C379C;\n --u-purple-600: #8245B7;\n --u-purple-700: #975BCB;\n --u-purple-800: #AB79D9;\n --u-purple-900: #BD99E2;\n --u-purple-1000: #CEB8EA;\n\n /* Pink Colors */\n --u-pink-0: #1F0A14;\n --u-pink-100: #310F20;\n --u-pink-200: #451532;\n --u-pink-300: #5C1D45;\n --u-pink-400: #74285A;\n --u-pink-500: #8F336F;\n --u-pink-600: #AB4187;\n --u-pink-700: #C0569D;\n --u-pink-800: #D174B3;\n --u-pink-900: #E095C7;\n --u-pink-1000: #EBB5D9;\n\n /* ==========================================================================\n Role Colors — 의미 역할 층\n 컴포넌트는 팔레트 프리미티브가 아니라 이 층을 참조한다.\n 브랜드 색 교체는 아래 25개만 재정의하면 시맨틱 층까지 따라온다.\n\n 단은 '강도' 축이다 (weakest -> strong). 용도(배경/테두리/텍스트)는\n 소비처가 정한다 -- 단을 속성에 묶으면 primary 버튼의 배경이 어느\n 단인지 같은 모순이 생긴다.\n\n ★**다만 두 단은 용도가 확정돼 있다** — 대비 요구가 서로 다르기 때문이다.\n `-color` = **면**. `--u-*-txt-color` 가 그 위에 얹히므로 on-color 기준 4.5.\n `-strong` = **글자·아이콘**. `--u-bg-color` 위에 놓이므로 바탕 기준 4.5.\n 라이트에서는 바탕도 on-color 도 흰색이라 두 요구가 한 조건으로 합쳐지지만,\n **다크에서는 정반대 방향**이다(바탕 #121212 · on-color #FFFFFF). 바탕에서 읽히는\n 밝은 단은 흰 글자를 못 받고, 흰 글자를 받는 어두운 단은 바탕에서 안 읽힌다.\n ⇒ 다크에서 `-color` 와 `-strong` 이 두 단 벌어지는 것이 그 결과다.\n `tests/build/token-contrast.test.ts` 가 값을 지킨다.\n ========================================================================== */\n\n /* primary — 브랜드 · 강조 · 포커스 · 링크 */\n --u-primary-color-weakest: var(--u-blue-200);\n --u-primary-color-weaker: var(--u-blue-300);\n --u-primary-color-weak: var(--u-blue-500);\n --u-primary-color: var(--u-blue-600); /* 면: 흰 글자 6.09 ✓ */\n --u-primary-color-strong: var(--u-blue-800); /* 글자: 바탕 5.32 ✓ (700 은 4.05 ✗) */\n\n /* info — 정보 안내 (primary 와 기본값은 같으나 역할이 다르다 — 브랜딩은 primary 만 바꾼다) */\n --u-info-color-weakest: var(--u-blue-200);\n --u-info-color-weaker: var(--u-blue-300);\n --u-info-color-weak: var(--u-blue-500);\n --u-info-color: var(--u-blue-600);\n --u-info-color-strong: var(--u-blue-800);\n\n /* success — 성공 · 완료 */\n --u-success-color-weakest: var(--u-green-200);\n --u-success-color-weaker: var(--u-green-300);\n --u-success-color-weak: var(--u-green-500);\n --u-success-color: var(--u-green-600);\n --u-success-color-strong: var(--u-green-700);\n\n /* warning — 주의 */\n --u-warning-color-weakest: var(--u-yellow-200);\n --u-warning-color-weaker: var(--u-yellow-300);\n --u-warning-color-weak: var(--u-yellow-500);\n --u-warning-color: var(--u-yellow-600);\n --u-warning-color-strong: var(--u-yellow-700);\n\n /* danger — 오류 · 위험 · 유효성 실패 */\n --u-danger-color-weakest: var(--u-red-200);\n --u-danger-color-weaker: var(--u-red-300);\n --u-danger-color-weak: var(--u-red-500);\n --u-danger-color: var(--u-red-600); /* 면: 흰 글자 6.83 ✓ */\n --u-danger-color-strong: var(--u-red-800); /* 글자: 바탕 4.87 ✓ (700 은 3.67 ✗) */\n /* ==========================================================================\n Radius Scale — 모서리 반경\n 리터럴을 흩뿌리면 값이 갈린다(실제로 pill 이 999px/9999px 두 표기로 나뉘어 있었다).\n ========================================================================== */\n --u-radius-none: 0;\n --u-radius-sm: 3px;\n --u-radius-md: 4px;\n --u-radius-lg: 6px;\n --u-radius-xl: 8px;\n --u-radius-pill: 9999px;\n --u-radius-circle: 50%;\n\n /* ==========================================================================\n Space Scale — 컨테이너·오버레이의 절대 여백\n ⚠**여백은 하나의 축이 아니다.** 이 스케일은 컨테이너/오버레이의 **레이아웃 여백**만\n 담당한다. 폼·인라인 요소의 `em` 여백은 상속된 `font-size` 에 비례하는 것이 의도이므로\n **여기로 흡수하지 않는다.** 반경과 마찬가지로 테마와 무관하므로 두 시트가 같다.\n 축 구분과 근거는 docs/design-tokens.md 참조.\n ========================================================================== */\n --u-space-3xs: 2px;\n --u-space-2xs: 4px;\n --u-space-xs: 6px;\n --u-space-sm: 8px;\n --u-space-md: 12px;\n --u-space-lg: 16px;\n\n /* Text Colors */\n --u-txt-color: var(--u-neutral-900);\n --u-txt-color-inverse: var(--u-neutral-100);\n\n /* 유채색 배경 위의 글자 — warning 만 다르다(light.css 참조). */\n --u-primary-txt-color: #FFFFFF;\n --u-info-txt-color: #FFFFFF;\n --u-success-txt-color: #FFFFFF;\n --u-danger-txt-color: #FFFFFF;\n /* ★라이트 시트와 같은 이유로 중립 최상단을 쓴다 — 다크에서는 그 값이 #FFFFFF 라\n 결과가 종전과 같다(4.65 ✓). 리터럴 대신 토큰을 쓰는 이유는 라이트에서 뒤집히기\n 때문이다(#000000). 두 시트가 같은 선언이 되어 어긋날 자리가 없어진다. */\n --u-warning-txt-color: var(--u-neutral-1000);\n --u-txt-color-hover: var(--u-primary-color-strong);\n --u-txt-color-active: var(--u-primary-color-strong);\n --u-txt-color-disabled: var(--u-neutral-500);\n --u-txt-color-weak: var(--u-neutral-700);\n --u-txt-color-strong: var(--u-neutral-1000);\n\n --u-link-txt-color: var(--u-primary-color-strong);\n --u-tooltip-txt-color: var(--u-neutral-100);\n\n /* Icon Colors */\n --u-icon-color: var(--u-neutral-800);\n --u-icon-color-inverse: var(--u-neutral-100);\n --u-icon-color-hover: var(--u-primary-color-strong);\n --u-icon-color-active: var(--u-primary-color-strong);\n --u-icon-color-disabled: var(--u-neutral-500);\n\n /* Border Colors */\n --u-border-color: var(--u-neutral-400);\n --u-border-color-weak: var(--u-neutral-300);\n --u-border-color-strong: var(--u-neutral-500);\n --u-border-color-hover: var(--u-neutral-500);\n\n /* ★상태 테두리는 `-strong` 단이다 — light.css 의 같은 자리 주석 참조.\n 이 테마가 실제로 미달이었다: focus 2.74 · invalid 2.44 → 4.74 / 4.34. */\n --u-input-border-color: var(--u-neutral-400);\n --u-input-border-color-hover: var(--u-neutral-500);\n --u-input-border-color-focus: var(--u-primary-color-strong);\n --u-input-border-color-invalid: var(--u-danger-color-strong);\n\n /* Background Colors */\n --u-bg-color: var(--u-neutral-100);\n --u-bg-color-inverse: var(--u-neutral-0);\n --u-bg-color-hover: var(--u-neutral-300);\n --u-bg-color-active: var(--u-neutral-400);\n --u-bg-color-disabled: var(--u-neutral-100);\n\n /* 면 높이 — 상세는 light.css 참조. 다크는 **바탕보다 밝은 쪽**이 위다.\n neutral-300(#2A2A2A)은 바탕(#121212) 대비 1.42 로, 소비 측이 오버라이드로 쓰던\n neutral-200(1.15)보다 실제로 더 잘 구분된다 — 그 오버라이드가 해결하려던 증상이\n *\"툴바·헤더가 배경에 묻힌다\"* 였다. */\n --u-bg-color-raised: var(--u-neutral-300);\n \n /* 유채색 표면 — 라이트와 **같은 단이 아니라 같은 세기**로 짝지었다(light.css 참조).\n 팔레트 유채색 틴트가 다크에서 짓눌리므로 한 단 위를 쓴다. green 은 대칭이라 그대로. */\n --u-primary-bg-color: var(--u-blue-100);\n --u-info-bg-color: var(--u-blue-100);\n --u-success-bg-color: var(--u-green-0);\n --u-danger-bg-color: var(--u-red-100);\n /* warning 합류 — 라이트는 yellow-200 이다(단 이름이 다른 이유는 light.css 참조). */\n --u-warning-bg-color: var(--u-yellow-100);\n\n --u-input-bg-color: var(--u-neutral-200);\n --u-panel-bg-color: var(--u-neutral-200);\n --u-overlay-bg-color: rgba(0, 0, 0, 0.7);\n --u-tooltip-bg-color: rgba(255, 255, 255, 0.85);\n\n /* Shadow Colors */\n --u-shadow-color-weaker: rgba(0, 0, 0, 0.15);\n --u-shadow-color-weak: rgba(0, 0, 0, 0.25);\n --u-shadow-color-normal: rgba(0, 0, 0, 0.35);\n --u-shadow-color-strong: rgba(0, 0, 0, 0.45);\n --u-shadow-color-stronger: rgba(0, 0, 0, 0.60);\n\n /* Elevation Scale — 근거는 light.css 의 같은 자리 주석 참조.\n ★다크는 알파가 3배 가까이 진하다 — 리터럴로 흩어져 있던 종전에는 이 차이가\n 적용되지 않아 다크에서 그림자가 사실상 보이지 않았다. */\n --u-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.25); /* = shadow-color-weak */\n --u-shadow-md: 0 2px 8px rgba(0, 0, 0, 0.35); /* = shadow-color-normal */\n --u-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.45); /* = shadow-color-strong */\n --u-shadow-xl: 0 6px 18px rgba(0, 0, 0, 0.60); /* = shadow-color-stronger */\n\n /* Scrollbar Colors */\n --u-scrollbar-color: var(--u-neutral-500);\n --u-scrollbar-color-hover: var(--u-neutral-600);\n --u-scrollbar-track-color: transparent;\n\n /* Font Styles */\n --u-font-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';\n --u-font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Monaco, 'Courier New', monospace;\n --u-font-serif: 'Georgia', 'Times New Roman', Times, serif;\n --u-font-display: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;\n --u-font-modern: 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n --u-font-rounded: 'Nunito', 'Quicksand', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}";
2
+ var dark_css_default = ":root[theme=\"dark\"] {\n color-scheme: dark;\n\n /* Neutral Colors */\n --u-neutral-0: #000000;\n --u-neutral-50: #0A0A0A;\n --u-neutral-100: #121212;\n --u-neutral-200: #1E1E1E;\n --u-neutral-300: #2A2A2A;\n --u-neutral-400: #3D3D3D;\n --u-neutral-500: #525252;\n --u-neutral-600: #6E6E6E;\n --u-neutral-700: #8A8A8A;\n --u-neutral-800: #B0B0B0;\n --u-neutral-900: #D4D4D4;\n --u-neutral-1000: #FFFFFF;\n\n /* Blue Colors */\n --u-blue-0: #030D1A;\n --u-blue-100: #061629;\n --u-blue-200: #0A223B;\n --u-blue-300: #103150;\n --u-blue-400: #174167;\n --u-blue-500: #205281;\n --u-blue-600: #2A659D;\n --u-blue-700: #3678B8;\n --u-blue-800: #478DCE;\n --u-blue-900: #5DA2DF;\n --u-blue-1000: #79BBEA;\n\n /* Green Colors */\n --u-green-0: #06140C;\n --u-green-100: #0A2114;\n --u-green-200: #10301D;\n --u-green-300: #164228;\n --u-green-400: #1F5535;\n --u-green-500: #2A6942;\n --u-green-600: #367E50;\n --u-green-700: #4A9563;\n --u-green-800: #63AB7A;\n --u-green-900: #80BE97;\n --u-green-1000: #9BCFB1;\n\n /* Yellow Colors */\n --u-yellow-0: #1C1300;\n --u-yellow-100: #2D1E00;\n --u-yellow-200: #402B00;\n --u-yellow-300: #553900;\n --u-yellow-400: #6B4900;\n --u-yellow-500: #825A00;\n --u-yellow-600: #9A6C00;\n --u-yellow-700: #B08012;\n --u-yellow-800: #C69635;\n --u-yellow-900: #D9AD5A;\n --u-yellow-1000: #E8C57F;\n\n /* Red Colors */\n --u-red-0: #1C0707;\n --u-red-100: #2C0B0B;\n --u-red-200: #3E1111;\n --u-red-300: #541818;\n --u-red-400: #6C2020;\n --u-red-500: #852A2A;\n --u-red-600: #A13535;\n --u-red-700: #B94949;\n --u-red-800: #CB6262;\n --u-red-900: #D98383;\n --u-red-1000: #E7A2A2;\n\n /* Orange Colors */\n --u-orange-0: #1D0E00;\n --u-orange-100: #2F1700;\n --u-orange-200: #421F00;\n --u-orange-300: #582A00;\n --u-orange-400: #703600;\n --u-orange-500: #8A4500;\n --u-orange-600: #A55600;\n --u-orange-700: #BD6A18;\n --u-orange-800: #D1823C;\n --u-orange-900: #E19D67;\n --u-orange-1000: #EDB992;\n\n /* Teal Colors */\n --u-teal-0: #041411;\n --u-teal-100: #07201B;\n --u-teal-200: #0B2E28;\n --u-teal-300: #10403A;\n --u-teal-400: #16544D;\n --u-teal-500: #1E6860;\n --u-teal-600: #297D74;\n --u-teal-700: #3A9389;\n --u-teal-800: #54A89F;\n --u-teal-900: #73BBB3;\n --u-teal-1000: #93CBC5;\n\n /* Cyan Colors */\n --u-cyan-0: #041318;\n --u-cyan-100: #071F29;\n --u-cyan-200: #0B2D3A;\n --u-cyan-300: #104050;\n --u-cyan-400: #165469;\n --u-cyan-500: #1E6A82;\n --u-cyan-600: #287F9C;\n --u-cyan-700: #3995B5;\n --u-cyan-800: #53AACC;\n --u-cyan-900: #73BEDD;\n --u-cyan-1000: #95CFE8;\n\n /* Purple Colors */\n --u-purple-0: #150A22;\n --u-purple-100: #220F36;\n --u-purple-200: #31164B;\n --u-purple-300: #432064;\n --u-purple-400: #572B80;\n --u-purple-500: #6C379C;\n --u-purple-600: #8245B7;\n --u-purple-700: #975BCB;\n --u-purple-800: #AB79D9;\n --u-purple-900: #BD99E2;\n --u-purple-1000: #CEB8EA;\n\n /* Pink Colors */\n --u-pink-0: #1F0A14;\n --u-pink-100: #310F20;\n --u-pink-200: #451532;\n --u-pink-300: #5C1D45;\n --u-pink-400: #74285A;\n --u-pink-500: #8F336F;\n --u-pink-600: #AB4187;\n --u-pink-700: #C0569D;\n --u-pink-800: #D174B3;\n --u-pink-900: #E095C7;\n --u-pink-1000: #EBB5D9;\n\n /* ==========================================================================\n Role Colors — 의미 역할 층\n 컴포넌트는 팔레트 프리미티브가 아니라 이 층을 참조한다.\n 브랜드 색 교체는 아래 25개만 재정의하면 시맨틱 층까지 따라온다.\n\n 단은 '강도' 축이다 (weakest -> strong). 용도(배경/테두리/텍스트)는\n 소비처가 정한다 -- 단을 속성에 묶으면 primary 버튼의 배경이 어느\n 단인지 같은 모순이 생긴다.\n\n ★**다만 두 단은 용도가 확정돼 있다** — 대비 요구가 서로 다르기 때문이다.\n `-color` = **면**. `--u-*-txt-color` 가 그 위에 얹히므로 on-color 기준 4.5.\n `-strong` = **글자·아이콘**. `--u-bg-color` 위에 놓이므로 바탕 기준 4.5.\n 라이트에서는 바탕도 on-color 도 흰색이라 두 요구가 한 조건으로 합쳐지지만,\n **다크에서는 정반대 방향**이다(바탕 #121212 · on-color #FFFFFF). 바탕에서 읽히는\n 밝은 단은 흰 글자를 못 받고, 흰 글자를 받는 어두운 단은 바탕에서 안 읽힌다.\n ⇒ 다크에서 `-color` 와 `-strong` 이 두 단 벌어지는 것이 그 결과다.\n `tests/build/token-contrast.test.ts` 가 값을 지킨다.\n ========================================================================== */\n\n /* primary — 브랜드 · 강조 · 포커스 · 링크 */\n --u-primary-color-weakest: var(--u-blue-200);\n --u-primary-color-weaker: var(--u-blue-300);\n --u-primary-color-weak: var(--u-blue-500);\n --u-primary-color: var(--u-blue-600); /* 면: 흰 글자 6.09 ✓ */\n --u-primary-color-strong: var(--u-blue-800); /* 글자: 바탕 5.32 ✓ (700 은 4.05 ✗) */\n\n /* info — 정보 안내 (primary 와 기본값은 같으나 역할이 다르다 — 브랜딩은 primary 만 바꾼다) */\n --u-info-color-weakest: var(--u-blue-200);\n --u-info-color-weaker: var(--u-blue-300);\n --u-info-color-weak: var(--u-blue-500);\n --u-info-color: var(--u-blue-600);\n --u-info-color-strong: var(--u-blue-800);\n\n /* success — 성공 · 완료 */\n --u-success-color-weakest: var(--u-green-200);\n --u-success-color-weaker: var(--u-green-300);\n --u-success-color-weak: var(--u-green-500);\n --u-success-color: var(--u-green-600);\n --u-success-color-strong: var(--u-green-700);\n\n /* warning — 주의 */\n --u-warning-color-weakest: var(--u-yellow-200);\n --u-warning-color-weaker: var(--u-yellow-300);\n --u-warning-color-weak: var(--u-yellow-500);\n --u-warning-color: var(--u-yellow-600);\n --u-warning-color-strong: var(--u-yellow-700);\n\n /* danger — 오류 · 위험 · 유효성 실패 */\n --u-danger-color-weakest: var(--u-red-200);\n --u-danger-color-weaker: var(--u-red-300);\n --u-danger-color-weak: var(--u-red-500);\n --u-danger-color: var(--u-red-600); /* 면: 흰 글자 6.83 ✓ */\n --u-danger-color-strong: var(--u-red-800); /* 글자: 바탕 4.87 ✓ (700 은 3.67 ✗) */\n /* ==========================================================================\n Radius Scale — 모서리 반경\n 리터럴을 흩뿌리면 값이 갈린다(실제로 pill 이 999px/9999px 두 표기로 나뉘어 있었다).\n ========================================================================== */\n --u-radius-none: 0;\n --u-radius-sm: 3px;\n --u-radius-md: 4px;\n --u-radius-lg: 6px;\n --u-radius-xl: 8px;\n /* ★상단 2단은 **면(surface)용**이다 — 카드·패널·대화상자처럼 큰 사각형은 컨트롤과\n 같은 반경을 쓰면 각져 보인다. 기존 5단은 **컨트롤용**이고 값을 바꾸지 않는다\n (바꾸면 모든 소비자의 버튼·입력이 동시에 움직인다). */\n --u-radius-2xl: 12px;\n --u-radius-3xl: 16px;\n --u-radius-pill: 9999px;\n --u-radius-circle: 50%;\n\n /* ==========================================================================\n Space Scale — 컨테이너·오버레이의 절대 여백\n ⚠**여백은 하나의 축이 아니다.** 이 스케일은 컨테이너/오버레이의 **레이아웃 여백**만\n 담당한다. 폼·인라인 요소의 `em` 여백은 상속된 `font-size` 에 비례하는 것이 의도이므로\n **여기로 흡수하지 않는다.** 반경과 마찬가지로 테마와 무관하므로 두 시트가 같다.\n 축 구분과 근거는 docs/design-tokens.md 참조.\n ========================================================================== */\n --u-space-3xs: 2px;\n --u-space-2xs: 4px;\n --u-space-xs: 6px;\n --u-space-sm: 8px;\n --u-space-md: 12px;\n --u-space-lg: 16px;\n /* ★상단 4단은 **화면 리듬**이다 — 카드 안쪽 여백(20~24)·섹션 간격(24~32)·페이지 여백\n (32~40). 종전에는 이 구간이 통째로 비어 있어 소비자가 전부 리터럴로 적었고,\n 그래서 앱마다 화면 밀도가 달라졌다. `lg`(16px) 이하는 **요소 사이**, `xl` 이상은\n **영역 사이**로 나눠 쓴다.\n ⚠`xs: 6px` 는 4px 격자에서 벗어나 있으나 **바꾸지 않는다** — 이미 배선된 컨트롤\n 여백이 전부 움직인다. 신규 단은 전부 4의 배수로 둔다. */\n --u-space-xl: 20px;\n --u-space-2xl: 24px;\n --u-space-3xl: 32px;\n --u-space-4xl: 40px;\n\n /* Text Colors */\n --u-txt-color: var(--u-neutral-900);\n --u-txt-color-inverse: var(--u-neutral-100);\n\n /* 유채색 배경 위의 글자 — warning 만 다르다(light.css 참조). */\n --u-primary-txt-color: #FFFFFF;\n --u-info-txt-color: #FFFFFF;\n --u-success-txt-color: #FFFFFF;\n --u-danger-txt-color: #FFFFFF;\n /* ★라이트 시트와 같은 이유로 중립 최상단을 쓴다 — 다크에서는 그 값이 #FFFFFF 라\n 결과가 종전과 같다(4.65 ✓). 리터럴 대신 토큰을 쓰는 이유는 라이트에서 뒤집히기\n 때문이다(#000000). 두 시트가 같은 선언이 되어 어긋날 자리가 없어진다. */\n --u-warning-txt-color: var(--u-neutral-1000);\n --u-txt-color-hover: var(--u-primary-color-strong);\n --u-txt-color-active: var(--u-primary-color-strong);\n --u-txt-color-disabled: var(--u-neutral-500);\n --u-txt-color-weak: var(--u-neutral-700);\n --u-txt-color-strong: var(--u-neutral-1000);\n\n --u-link-txt-color: var(--u-primary-color-strong);\n --u-tooltip-txt-color: var(--u-neutral-100);\n\n /* Icon Colors */\n --u-icon-color: var(--u-neutral-800);\n --u-icon-color-inverse: var(--u-neutral-100);\n --u-icon-color-hover: var(--u-primary-color-strong);\n --u-icon-color-active: var(--u-primary-color-strong);\n --u-icon-color-disabled: var(--u-neutral-500);\n\n /* Border Colors */\n --u-border-color: var(--u-neutral-400);\n --u-border-color-weak: var(--u-neutral-300);\n --u-border-color-strong: var(--u-neutral-500);\n --u-border-color-hover: var(--u-neutral-500);\n\n /* ★상태 테두리는 `-strong` 단이다 — light.css 의 같은 자리 주석 참조.\n 이 테마가 실제로 미달이었다: focus 2.74 · invalid 2.44 → 4.74 / 4.34. */\n --u-input-border-color: var(--u-neutral-400);\n --u-input-border-color-hover: var(--u-neutral-500);\n --u-input-border-color-focus: var(--u-primary-color-strong);\n --u-input-border-color-invalid: var(--u-danger-color-strong);\n\n /* Background Colors */\n --u-bg-color: var(--u-neutral-100);\n --u-bg-color-inverse: var(--u-neutral-0);\n --u-bg-color-hover: var(--u-neutral-300);\n --u-bg-color-active: var(--u-neutral-400);\n --u-bg-color-disabled: var(--u-neutral-100);\n\n /* 면 높이 — 상세는 light.css 참조. 다크는 **바탕보다 밝은 쪽**이 위다.\n neutral-300(#2A2A2A)은 바탕(#121212) 대비 1.42 로, 소비 측이 오버라이드로 쓰던\n neutral-200(1.15)보다 실제로 더 잘 구분된다 — 그 오버라이드가 해결하려던 증상이\n *\"툴바·헤더가 배경에 묻힌다\"* 였다. */\n --u-bg-color-raised: var(--u-neutral-300);\n \n /* 유채색 표면 — 라이트와 **같은 단이 아니라 같은 세기**로 짝지었다(light.css 참조).\n 팔레트 유채색 틴트가 다크에서 짓눌리므로 한 단 위를 쓴다. green 은 대칭이라 그대로. */\n --u-primary-bg-color: var(--u-blue-100);\n --u-info-bg-color: var(--u-blue-100);\n --u-success-bg-color: var(--u-green-0);\n --u-danger-bg-color: var(--u-red-100);\n /* warning 합류 — 라이트는 yellow-200 이다(단 이름이 다른 이유는 light.css 참조). */\n --u-warning-bg-color: var(--u-yellow-100);\n\n --u-input-bg-color: var(--u-neutral-200);\n --u-panel-bg-color: var(--u-neutral-200);\n --u-overlay-bg-color: rgba(0, 0, 0, 0.7);\n --u-tooltip-bg-color: rgba(255, 255, 255, 0.85);\n\n /* Shadow Colors */\n --u-shadow-color-weaker: rgba(0, 0, 0, 0.15);\n --u-shadow-color-weak: rgba(0, 0, 0, 0.25);\n --u-shadow-color-normal: rgba(0, 0, 0, 0.35);\n --u-shadow-color-strong: rgba(0, 0, 0, 0.45);\n --u-shadow-color-stronger: rgba(0, 0, 0, 0.60);\n\n /* Elevation Scale — 근거는 light.css 의 같은 자리 주석 참조.\n ★다크는 알파가 3배 가까이 진하다 — 리터럴로 흩어져 있던 종전에는 이 차이가\n 적용되지 않아 다크에서 그림자가 사실상 보이지 않았다. */\n --u-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.25), 0 1px 1px rgba(0, 0, 0, 0.14); /* = shadow-color-weak */\n --u-shadow-md: 0 2px 8px rgba(0, 0, 0, 0.35), 0 1px 2px rgba(0, 0, 0, 0.18); /* = shadow-color-normal */\n --u-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.45), 0 2px 4px rgba(0, 0, 0, 0.22); /* = shadow-color-strong */\n --u-shadow-xl: 0 6px 18px rgba(0, 0, 0, 0.60), 0 2px 6px rgba(0, 0, 0, 0.30); /* = shadow-color-stronger */\n\n\n /* ==========================================================================\n Type Scale — 글자 크기·굵기·행간·자간의 **한 벌**\n ★**크기만 주면 스케일이 되지 않는다.** 소비자가 크기만 받고 굵기·행간을 각자 정하면\n 결국 화면마다 다른 위계가 생긴다 — 그래서 네 값을 **단 단위로 묶어** 낸다.\n\n 단 이름은 크기가 아니라 **역할**이다(`lg`/`xl` 이 아니라 `title`/`label`). 역할로 두면\n 소비자가 *\"어느 크기를 쓸까\"* 가 아니라 *\"이 글자는 무엇인가\"* 를 묻게 된다.\n\n ★**한글 기준으로 값을 골랐다**:\n ⑴ 행간은 **1.4 이상**. 라틴 관례(1.2)는 한글에서 답답하다 — 받침 때문에 글자 상자가\n 세로로 꽉 차 있어 라틴과 같은 행간이면 줄이 붙어 보인다.\n ⑵ 자간은 **0 이 기본**이고 큰 제목만 **음수**. 한글에 양수 자간(letter-spacing)을 주면\n 가독성이 떨어진다 — 라틴 소문자 조판 관례를 그대로 옮기면 안 되는 자리다.\n ⑶ `overline` 에만 양수 자간을 둔다. 그 단은 **영문·숫자 라벨**을 전제한 자리이고,\n 한글을 넣을 소비자는 자간을 0 으로 덮어야 한다(문서에 명시).\n\n ⚠**`text-transform` 은 토큰으로 내지 않는다.** 한글에는 대문자가 없어 `uppercase` 가\n 아무 효과가 없고, 영문이 섞이면 그것만 커져 오히려 어수선해진다.\n ========================================================================== */\n --u-text-display-size: 26px;\n --u-text-display-weight: 700;\n --u-text-display-leading: 1.4;\n --u-text-display-tracking: -0.02em;\n\n --u-text-title-size: 20px;\n --u-text-title-weight: 700;\n --u-text-title-leading: 1.45;\n --u-text-title-tracking: -0.01em;\n\n --u-text-subtitle-size: 16px;\n --u-text-subtitle-weight: 600;\n --u-text-subtitle-leading: 1.5;\n --u-text-subtitle-tracking: 0;\n\n --u-text-body-size: 14px;\n --u-text-body-weight: 400;\n --u-text-body-leading: 1.6;\n --u-text-body-tracking: 0;\n\n --u-text-label-size: 13px;\n --u-text-label-weight: 600;\n --u-text-label-leading: 1.5;\n --u-text-label-tracking: 0;\n\n --u-text-caption-size: 12px;\n --u-text-caption-weight: 400;\n --u-text-caption-leading: 1.5;\n --u-text-caption-tracking: 0;\n\n --u-text-overline-size: 11px;\n --u-text-overline-weight: 700;\n --u-text-overline-leading: 1.45;\n --u-text-overline-tracking: 0.06em;\n\n /* ==========================================================================\n Motion — 지속시간·이징\n ★값이 없으면 앱마다 다른 속도가 생기고, `prefers-reduced-motion` 은 **반드시**\n 빠뜨리는 앱이 나온다. 축을 여기 두고 존중 규칙은 아래 미디어 쿼리가 진다.\n ========================================================================== */\n --u-duration-instant: 80ms;\n --u-duration-fast: 140ms;\n --u-duration-normal: 220ms;\n --u-duration-slow: 320ms;\n --u-ease-standard: cubic-bezier(0.2, 0, 0, 1);\n --u-ease-decelerate: cubic-bezier(0, 0, 0, 1);\n --u-ease-accelerate: cubic-bezier(0.3, 0, 1, 1);\n\n /* Scrollbar Colors */\n --u-scrollbar-color: var(--u-neutral-500);\n --u-scrollbar-color-hover: var(--u-neutral-600);\n --u-scrollbar-track-color: transparent;\n\n /* ==========================================================================\n Font Styles\n ★**CJK 폴백을 스택에 포함한다 — 국제화이지 취향이 아니다.**\n 종전 스택(`-apple-system, Segoe UI, Noto Sans, Helvetica, Arial`)에는 **한중일 글립을\n 가진 폰트가 하나도 없었다.** Windows 에서 한글은 `Segoe UI` 에 없으므로 UA 가 임의로\n 맑은 고딕을 고르고, macOS 는 `-apple-system` 이 Apple SD Gothic Neo 를 준다 ⇒ **같은 앱이\n OS 마다 다른 글꼴로 렌더**됐다. 폴백을 명시하면 그 선택이 결정적이 된다.\n ⚠**웹폰트를 로드하지 않는다.** 라이브러리가 네트워크 요청을 만들면 소비자의 CSP·\n 오프라인 환경을 깬다. 스택 맨 앞의 `Pretendard` 는 **소비자가 로드했을 때만** 잡히는\n 선택적 이름이다(없으면 조용히 다음으로 넘어간다).\n ========================================================================== */\n --u-font-base: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans KR', 'Hiragino Sans', 'Yu Gothic UI', 'Microsoft YaHei', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';\n --u-font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Monaco, 'Courier New', monospace;\n --u-font-serif: 'Georgia', 'Times New Roman', Times, serif;\n --u-font-display: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;\n --u-font-modern: 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n --u-font-rounded: 'Nunito', 'Quicksand', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}";
3
3
  //#endregion
4
4
  export { dark_css_default as default };
@@ -1,4 +1,4 @@
1
1
  //#region \0glob-assets_raw/light.css.637cb2f8
2
- var light_css_default = ":root {\n color-scheme: light;\n\n /* Neutral Colors */\n --u-neutral-0: #FFFFFF;\n --u-neutral-50: #FAFAFA;\n --u-neutral-100: #F5F5F5;\n --u-neutral-200: #EEEEEE;\n --u-neutral-300: #E0E0E0;\n --u-neutral-400: #BDBDBD;\n --u-neutral-500: #9E9E9E;\n --u-neutral-600: #757575;\n --u-neutral-700: #616161;\n --u-neutral-800: #424242;\n --u-neutral-900: #212121;\n --u-neutral-1000: #000000;\n\n /* Blue Colors */\n --u-blue-0: #E3F2FD;\n --u-blue-100: #BBDEFB;\n --u-blue-200: #90CAF9;\n --u-blue-300: #64B5F6;\n --u-blue-400: #42A5F5;\n --u-blue-500: #2196F3;\n --u-blue-600: #1E88E5;\n --u-blue-700: #1976D2;\n --u-blue-800: #1565C0;\n --u-blue-900: #0D47A1;\n --u-blue-1000: #062A5E;\n\n /* Green Colors */\n --u-green-0: #E8F5E9;\n --u-green-100: #C8E6C9;\n --u-green-200: #A5D6A7;\n --u-green-300: #81C784;\n --u-green-400: #66BB6A;\n --u-green-500: #4CAF50;\n --u-green-600: #43A047;\n --u-green-700: #388E3C;\n --u-green-800: #2E7D32;\n --u-green-900: #1B5E20;\n --u-green-1000: #0F3A12;\n\n /* Yellow Colors */\n --u-yellow-0: #FFFDE7;\n --u-yellow-100: #FFF9C4;\n --u-yellow-200: #FFF59D;\n --u-yellow-300: #FFF176;\n --u-yellow-400: #FFEE58;\n --u-yellow-500: #FFEB3B;\n --u-yellow-600: #FDD835;\n --u-yellow-700: #FBC02D;\n --u-yellow-800: #F9A825;\n --u-yellow-900: #F57F17;\n --u-yellow-1000: #8A4A00;\n\n /* Red Colors */\n --u-red-0: #FFEBEE;\n --u-red-100: #FFCDD2;\n --u-red-200: #EF9A9A;\n --u-red-300: #E57373;\n --u-red-400: #EF5350;\n --u-red-500: #F44336;\n --u-red-600: #E53935;\n --u-red-700: #D32F2F;\n --u-red-800: #C62828;\n --u-red-900: #B71C1C;\n --u-red-1000: #6B0F0F;\n\n /* Orange Colors */\n --u-orange-0: #FFF3E0;\n --u-orange-100: #FFE0B2;\n --u-orange-200: #FFCC80;\n --u-orange-300: #FFB74D;\n --u-orange-400: #FFA726;\n --u-orange-500: #FF9800;\n --u-orange-600: #FB8C00;\n --u-orange-700: #F57C00;\n --u-orange-800: #EF6C00;\n --u-orange-900: #E65100;\n --u-orange-1000: #8C3100;\n\n /* Teal Colors */\n --u-teal-0: #E0F2F1;\n --u-teal-100: #B2DFDB;\n --u-teal-200: #80CBC4;\n --u-teal-300: #4DB6AC;\n --u-teal-400: #26A69A;\n --u-teal-500: #009688;\n --u-teal-600: #00897B;\n --u-teal-700: #00796B;\n --u-teal-800: #00695C;\n --u-teal-900: #004D40;\n --u-teal-1000: #002E26;\n\n /* Cyan Colors */\n --u-cyan-0: #E0F7FA;\n --u-cyan-100: #B2EBF2;\n --u-cyan-200: #80DEEA;\n --u-cyan-300: #4DD0E1;\n --u-cyan-400: #26C6DA;\n --u-cyan-500: #00BCD4;\n --u-cyan-600: #00ACC1;\n --u-cyan-700: #0097A7;\n --u-cyan-800: #00838F;\n --u-cyan-900: #006064;\n --u-cyan-1000: #003A3D;\n\n /* Purple Colors */\n --u-purple-0: #F3E5F5;\n --u-purple-100: #E1BEE7;\n --u-purple-200: #CE93D8;\n --u-purple-300: #BA68C8;\n --u-purple-400: #AB47BC;\n --u-purple-500: #9C27B0;\n --u-purple-600: #8E24AA;\n --u-purple-700: #7B1FA2;\n --u-purple-800: #6A1B9A;\n --u-purple-900: #4A148C;\n --u-purple-1000: #2C0B54;\n\n /* Pink Colors */\n --u-pink-0: #FCE4EC;\n --u-pink-100: #F8BBD0;\n --u-pink-200: #F48FB1;\n --u-pink-300: #F06292;\n --u-pink-400: #EC407A;\n --u-pink-500: #E91E63;\n --u-pink-600: #D81B60;\n --u-pink-700: #C2185B;\n --u-pink-800: #AD1457;\n --u-pink-900: #880E4F;\n --u-pink-1000: #520830;\n\n /* ==========================================================================\n Role Colors — 의미 역할 층\n 컴포넌트는 팔레트 프리미티브가 아니라 이 층을 참조한다.\n 브랜드 색 교체는 아래 25개만 재정의하면 시맨틱 층까지 따라온다.\n\n 단은 '강도' 축이다 (weakest -> strong). 용도(배경/테두리/텍스트)는\n 소비처가 정한다 -- 단을 속성에 묶으면 primary 버튼의 배경이 어느\n 단인지 같은 모순이 생긴다.\n ========================================================================== */\n\n /* ★단이 팔레트 shade 와 1:1 이 아니다 — **대비로 고른다.**\n `-color` 는 `--u-*-txt-color` 를 받는 면이고 `-strong` 은 바탕 위의 글자다.\n 라이트에서는 바탕도 on-color 도 흰색이라 두 요구가 `contrast(shade, #FFF) ≥ 4.5`\n 하나로 합쳐지고, 그 단이 계열마다 다르다(blue 700 · red 700 · green 800).\n Material 램프는 휘도가 아니라 색상 기준으로 만들어져 있어서 단 번호가 세기를\n 보장하지 않는다 — 값은 `tests/build/token-contrast.test.ts` 가 지킨다. */\n\n /* primary — 브랜드 · 강조 · 포커스 · 링크 */\n --u-primary-color-weakest: var(--u-blue-200);\n --u-primary-color-weaker: var(--u-blue-300);\n --u-primary-color-weak: var(--u-blue-500);\n --u-primary-color: var(--u-blue-700); /* 4.60 ✓ (600 은 3.68 ✗) */\n --u-primary-color-strong: var(--u-blue-800); /* 5.75 ✓ */\n\n /* info — 정보 안내 (primary 와 기본값은 같으나 역할이 다르다 — 브랜딩은 primary 만 바꾼다) */\n --u-info-color-weakest: var(--u-blue-200);\n --u-info-color-weaker: var(--u-blue-300);\n --u-info-color-weak: var(--u-blue-500);\n --u-info-color: var(--u-blue-700);\n --u-info-color-strong: var(--u-blue-800);\n\n /* success — 성공 · 완료\n ⚠green 은 700 도 4.12 로 미달이라 두 단을 건너뛴다. 계열마다 통과 단이 다른 것이\n 이 층의 정상 상태다(단 번호를 맞추면 대비가 어긋난다). */\n --u-success-color-weakest: var(--u-green-200);\n --u-success-color-weaker: var(--u-green-300);\n --u-success-color-weak: var(--u-green-500);\n --u-success-color: var(--u-green-800); /* 5.13 ✓ (600=3.30 · 700=4.12 ✗) */\n --u-success-color-strong: var(--u-green-900); /* 7.87 ✓ */\n\n /* warning — 주의 */\n --u-warning-color-weakest: var(--u-yellow-200);\n --u-warning-color-weaker: var(--u-yellow-300);\n --u-warning-color-weak: var(--u-yellow-500);\n --u-warning-color: var(--u-yellow-600);\n /* ★다른 계열은 -strong 이 shade-800~900 인데 warning 만 1000 이다 — 노랑 램프는\n 900 까지도 흰 바탕 2.65 로 미달이고, 1000(#8A4A00)에서 처음 6.86 이 된다.\n 그 값은 갈색에 가깝지만, 이 단의 용도는 **면이 아니라 글자·아이콘**이므로 색상보다\n 가독성이 먼저다(경고 문구를 어두운 호박색으로 쓰는 것은 보편 관행이다). */\n --u-warning-color-strong: var(--u-yellow-1000);\n\n /* danger — 오류 · 위험 · 유효성 실패 */\n --u-danger-color-weakest: var(--u-red-200);\n --u-danger-color-weaker: var(--u-red-300);\n --u-danger-color-weak: var(--u-red-500);\n --u-danger-color: var(--u-red-700); /* 4.98 ✓ (600 은 4.23 ✗ — 오류 문구가 이 단이었다) */\n --u-danger-color-strong: var(--u-red-800); /* 5.62 ✓ */\n /* ==========================================================================\n Radius Scale — 모서리 반경\n 리터럴을 흩뿌리면 값이 갈린다(실제로 pill 이 999px/9999px 두 표기로 나뉘어 있었다).\n ========================================================================== */\n --u-radius-none: 0;\n --u-radius-sm: 3px;\n --u-radius-md: 4px;\n --u-radius-lg: 6px;\n --u-radius-xl: 8px;\n --u-radius-pill: 9999px;\n --u-radius-circle: 50%;\n\n /* ==========================================================================\n Space Scale — 컨테이너·오버레이의 절대 여백\n ⚠**여백은 하나의 축이 아니다.** 이 스케일은 컨테이너/오버레이(카드·대화상자·드로어·\n 알림·메뉴·툴팁 등)의 **레이아웃 여백**만 담당한다. 폼·인라인 요소의 `em` 여백은\n 상속된 `font-size` 에 비례하는 것이 의도이므로 **여기로 흡수하지 않는다** —\n 흡수하면 타이포를 키운 소비자의 여백이 따라 커지지 않는다.\n 축 구분과 근거는 docs/design-tokens.md 참조.\n ========================================================================== */\n --u-space-3xs: 2px;\n --u-space-2xs: 4px;\n --u-space-xs: 6px;\n --u-space-sm: 8px;\n --u-space-md: 12px;\n --u-space-lg: 16px;\n\n /* Text Colors */\n --u-txt-color: var(--u-neutral-900);\n --u-txt-color-inverse: var(--u-neutral-0);\n /* 유채색 배경 위의 글자. --u-txt-color-inverse 는 다크에서 neutral-100(#121212)이라\n 유채색 버튼 위에서 읽히지 않는다. 브랜드 색을 바꾸는 소비자가 전경색도 함께\n 조절할 수 있도록 별도 이름을 준다.\n ⚠이 토큰이 흰색이라는 것과 그 위의 배경이 AA 를 받친다는 것은 별개다 —\n 라이트 팔레트의 shade-600 은 8색 중 6색이 흰 글자로 AA 에 미달한다(미해결). */\n --u-primary-txt-color: #FFFFFF;\n --u-info-txt-color: #FFFFFF;\n --u-success-txt-color: #FFFFFF;\n --u-danger-txt-color: #FFFFFF;\n /* ★warning 만 어둡다 — 취향이 아니라 측정이다. 노랑은 **어떤 단도** 흰 글자로 AA 를\n 받치지 못한다(라이트 최대 2.65 @900, 그마저 갈색). 다른 넷처럼 단을 옮기는 수단이\n 없으므로 전경을 뒤집는다. `--u-neutral-1000` 은 라이트 #000000 / 다크 #FFFFFF 이라\n 한 줄로 양 테마를 만족한다(라이트 15.05 · 다크 4.65). */\n --u-warning-txt-color: var(--u-neutral-1000);\n\n --u-txt-color-hover: var(--u-primary-color-strong);\n --u-txt-color-active: var(--u-primary-color-strong);\n --u-txt-color-disabled: var(--u-neutral-400);\n /* neutral-500(#9E9E9E)은 흰 배경 대비 2.68 로 WCAG AA(4.5) 미달이었다.\n neutral-600(#757575) = 4.61 로 통과한다. 다크 매핑(neutral-700 = 5.43)은\n 원래 정상이라 손대지 않는다 — 라이트 한쪽만의 결함이었다. */\n --u-txt-color-weak: var(--u-neutral-600);\n --u-txt-color-strong: var(--u-neutral-1000);\n\n --u-link-txt-color: var(--u-primary-color-strong);\n --u-tooltip-txt-color: var(--u-neutral-0);\n\n /* Icon Colors */\n --u-icon-color: var(--u-neutral-700);\n --u-icon-color-inverse: var(--u-neutral-0);\n --u-icon-color-hover: var(--u-primary-color-strong);\n --u-icon-color-active: var(--u-primary-color-strong);\n --u-icon-color-disabled: var(--u-neutral-400);\n\n /* Border Colors */\n --u-border-color: var(--u-neutral-300);\n --u-border-color-weak: var(--u-neutral-200);\n --u-border-color-strong: var(--u-neutral-400);\n --u-border-color-hover: var(--u-neutral-400);\n\n /* ★상태 테두리는 `-strong` 단이다 — 면이 아니라 **면 위에 그리는 선**이기 때문이다.\n 1.16.0 이 가른 용도(`-color` = 면 / `-strong` = 면·바탕 위)에 이 자리가 맞춰지지\n 않아 다크에서 미달이었다: focus 2.74 · invalid 2.44 (WCAG 1.4.11 기준 3.0).\n `-strong` 으로 옮기면 다크 4.74 / 4.34, 라이트 5.75 / 5.62 — 두 테마 모두 단조 상승. */\n --u-input-border-color: var(--u-neutral-300);\n --u-input-border-color-hover: var(--u-neutral-400);\n --u-input-border-color-focus: var(--u-primary-color-strong);\n --u-input-border-color-invalid: var(--u-danger-color-strong);\n\n /* Background Colors */\n --u-bg-color: var(--u-neutral-0);\n --u-bg-color-inverse: var(--u-neutral-900);\n --u-bg-color-hover: var(--u-neutral-100);\n --u-bg-color-active: var(--u-neutral-200);\n --u-bg-color-disabled: var(--u-neutral-50);\n\n /* ★면 높이 — 바탕에 인접해 있으면서 한 단 구분되는 크롬 면(툴바·표 헤더·푸터).\n 상호작용 상태(-hover/-active/-disabled)와 **다른 축**이다. 상태 이름에 높이를\n 얹으면 의미가 어긋난다(`DL-131-1`).\n `--u-panel-bg-color` 와도 다르다 — 그쪽은 **떠 있는 패널**(카드·대화상자·메뉴)이라\n 라이트에서 페이지와 같은 흰색이고 그림자가 높이를 나른다. 크롬 면은 그림자가 없어\n 라이트에서도 틴트가 필요하다.\n ⚠한 단만 정의한다. 두 단째의 실측 수요는 라이트 한쪽뿐이었다(다크에서는 소비 측\n 오버라이드가 두 값을 같은 단으로 합치고 있었다). */\n --u-bg-color-raised: var(--u-neutral-50);\n \n /* 유채색 표면 — 정보/성공/위험 상태의 '면'.\n 역할 층의 유채색은 전경 5단뿐이라, 상태 배경이 필요한 컴포넌트는 팔레트를 직접\n 읽고 다크를 손으로 보정해야 했다. 팔레트의 유채색 틴트는 다크에서 짓눌리므로\n (바탕 대비 델타의 다크/라이트 비 — 청색 0.38~0.54) 두 테마가 **같은 단이 아니라\n 같은 세기**가 되도록 짝지었다. 실측 비: blue 1.09 · red 1.12 · green 0.91.\n\n ★**warning 이 합류했다(1.16.0 → 1.17.0).** 종전에는 *\"세기를 맞출 단 짝이 없다\"* 며\n 빠져 있었는데, 그 판정은 **shade-0 짝만** 재고 있었다. 노랑만 한 단 내려 잡으면\n 라이트 쪽 세기가 맞는다 — 바탕 대비 휘도 델타 실측:\n blue-0 0.131 · red-0 0.132 · green-0 0.117 · **yellow-200 0.110** (yellow-0 은 0.027)\n ⚠단 이름이 계열마다 다른 것(yellow 만 200)은 이 층의 정상 상태다. 라이트 팔레트는\n 휘도 순이 아니므로 같은 단 번호가 같은 세기를 뜻하지 않는다. */\n --u-primary-bg-color: var(--u-blue-0);\n --u-info-bg-color: var(--u-blue-0);\n --u-success-bg-color: var(--u-green-0);\n --u-danger-bg-color: var(--u-red-0);\n --u-warning-bg-color: var(--u-yellow-200);\n\n --u-input-bg-color: var(--u-neutral-0);\n --u-panel-bg-color: var(--u-neutral-0);\n --u-overlay-bg-color: rgba(0, 0, 0, 0.5);\n --u-tooltip-bg-color: rgba(0, 0, 0, 0.75);\n\n /* Shadow Colors */\n --u-shadow-color-weaker: rgba(0, 0, 0, 0.04);\n --u-shadow-color-weak: rgba(0, 0, 0, 0.08);\n --u-shadow-color-normal: rgba(0, 0, 0, 0.12);\n --u-shadow-color-strong: rgba(0, 0, 0, 0.16);\n --u-shadow-color-stronger: rgba(0, 0, 0, 0.24);\n\n /* ==========================================================================\n Elevation Scale — 높이(그림자)\n\n ★색 축은 있었지만 **높이 축이 없었다.** 그 결과 컴포넌트가 그림자를 리터럴로\n 썼고, 같은 리듬을 의도한 자리에 서로 다른 값 11가지가 생겼다(카드 .1 vs 캐러셀\n .15 — 둘 다 \"표면에 얹힌 카드\"인데 알파가 다르다).\n\n ⚠**그리고 그 리터럴들은 테마를 몰랐다** — `rgba(0,0,0,.1)` 은 다크 바탕에서\n 거의 보이지 않는다. 이 축을 경유하면 다크의 진한 알파(.25~.60)를 자동으로 받는다.\n\n ⚠**알파를 `--u-shadow-color-*` 로 중첩하지 않고 인라인한다.** use-site 폴백\n 생성기는 합성 값을 리터럴로 다루므로, 중첩하면 `var(--u-shadow-md, 0 2px 8px\n var(--u-shadow-color-normal))` 처럼 **폴백 안에 또 토큰이 들어간다** — 시트가\n 없을 때 그 폴백도 함께 무효가 되어 그림자가 통째로 사라진다.\n 두 축의 알파가 어긋나지 않는지는 `tests/build/elevation-scale.test.ts` 가 지킨다.\n ========================================================================== */\n --u-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08); /* = shadow-color-weak — 표면에 얹힌 작은 컨트롤(탭·손잡이) */\n --u-shadow-md: 0 2px 8px rgba(0, 0, 0, 0.12); /* = shadow-color-normal — 카드·표면 */\n --u-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.16); /* = shadow-color-strong — 떠 있는 레이어(드롭다운·알림) */\n --u-shadow-xl: 0 6px 18px rgba(0, 0, 0, 0.24); /* = shadow-color-stronger — 모달·최상위(대화상자·툴팁) */\n\n /* Scrollbar Colors */\n --u-scrollbar-color: var(--u-neutral-400);\n --u-scrollbar-color-hover: var(--u-neutral-500);\n --u-scrollbar-track-color: transparent;\n\n /* Font Styles */\n --u-font-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';\n --u-font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Monaco, 'Courier New', monospace;\n --u-font-serif: 'Georgia', 'Times New Roman', Times, serif;\n --u-font-display: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;\n --u-font-modern: 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n --u-font-rounded: 'Nunito', 'Quicksand', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}";
2
+ var light_css_default = ":root {\n color-scheme: light;\n\n /* Neutral Colors */\n --u-neutral-0: #FFFFFF;\n --u-neutral-50: #FAFAFA;\n --u-neutral-100: #F5F5F5;\n --u-neutral-200: #EEEEEE;\n --u-neutral-300: #E0E0E0;\n --u-neutral-400: #BDBDBD;\n --u-neutral-500: #9E9E9E;\n --u-neutral-600: #757575;\n --u-neutral-700: #616161;\n --u-neutral-800: #424242;\n --u-neutral-900: #212121;\n --u-neutral-1000: #000000;\n\n /* Blue Colors */\n --u-blue-0: #E3F2FD;\n --u-blue-100: #BBDEFB;\n --u-blue-200: #90CAF9;\n --u-blue-300: #64B5F6;\n --u-blue-400: #42A5F5;\n --u-blue-500: #2196F3;\n --u-blue-600: #1E88E5;\n --u-blue-700: #1976D2;\n --u-blue-800: #1565C0;\n --u-blue-900: #0D47A1;\n --u-blue-1000: #062A5E;\n\n /* Green Colors */\n --u-green-0: #E8F5E9;\n --u-green-100: #C8E6C9;\n --u-green-200: #A5D6A7;\n --u-green-300: #81C784;\n --u-green-400: #66BB6A;\n --u-green-500: #4CAF50;\n --u-green-600: #43A047;\n --u-green-700: #388E3C;\n --u-green-800: #2E7D32;\n --u-green-900: #1B5E20;\n --u-green-1000: #0F3A12;\n\n /* Yellow Colors */\n --u-yellow-0: #FFFDE7;\n --u-yellow-100: #FFF9C4;\n --u-yellow-200: #FFF59D;\n --u-yellow-300: #FFF176;\n --u-yellow-400: #FFEE58;\n --u-yellow-500: #FFEB3B;\n --u-yellow-600: #FDD835;\n --u-yellow-700: #FBC02D;\n --u-yellow-800: #F9A825;\n --u-yellow-900: #F57F17;\n --u-yellow-1000: #8A4A00;\n\n /* Red Colors */\n --u-red-0: #FFEBEE;\n --u-red-100: #FFCDD2;\n --u-red-200: #EF9A9A;\n --u-red-300: #E57373;\n --u-red-400: #EF5350;\n --u-red-500: #F44336;\n --u-red-600: #E53935;\n --u-red-700: #D32F2F;\n --u-red-800: #C62828;\n --u-red-900: #B71C1C;\n --u-red-1000: #6B0F0F;\n\n /* Orange Colors */\n --u-orange-0: #FFF3E0;\n --u-orange-100: #FFE0B2;\n --u-orange-200: #FFCC80;\n --u-orange-300: #FFB74D;\n --u-orange-400: #FFA726;\n --u-orange-500: #FF9800;\n --u-orange-600: #FB8C00;\n --u-orange-700: #F57C00;\n --u-orange-800: #EF6C00;\n --u-orange-900: #E65100;\n --u-orange-1000: #8C3100;\n\n /* Teal Colors */\n --u-teal-0: #E0F2F1;\n --u-teal-100: #B2DFDB;\n --u-teal-200: #80CBC4;\n --u-teal-300: #4DB6AC;\n --u-teal-400: #26A69A;\n --u-teal-500: #009688;\n --u-teal-600: #00897B;\n --u-teal-700: #00796B;\n --u-teal-800: #00695C;\n --u-teal-900: #004D40;\n --u-teal-1000: #002E26;\n\n /* Cyan Colors */\n --u-cyan-0: #E0F7FA;\n --u-cyan-100: #B2EBF2;\n --u-cyan-200: #80DEEA;\n --u-cyan-300: #4DD0E1;\n --u-cyan-400: #26C6DA;\n --u-cyan-500: #00BCD4;\n --u-cyan-600: #00ACC1;\n --u-cyan-700: #0097A7;\n --u-cyan-800: #00838F;\n --u-cyan-900: #006064;\n --u-cyan-1000: #003A3D;\n\n /* Purple Colors */\n --u-purple-0: #F3E5F5;\n --u-purple-100: #E1BEE7;\n --u-purple-200: #CE93D8;\n --u-purple-300: #BA68C8;\n --u-purple-400: #AB47BC;\n --u-purple-500: #9C27B0;\n --u-purple-600: #8E24AA;\n --u-purple-700: #7B1FA2;\n --u-purple-800: #6A1B9A;\n --u-purple-900: #4A148C;\n --u-purple-1000: #2C0B54;\n\n /* Pink Colors */\n --u-pink-0: #FCE4EC;\n --u-pink-100: #F8BBD0;\n --u-pink-200: #F48FB1;\n --u-pink-300: #F06292;\n --u-pink-400: #EC407A;\n --u-pink-500: #E91E63;\n --u-pink-600: #D81B60;\n --u-pink-700: #C2185B;\n --u-pink-800: #AD1457;\n --u-pink-900: #880E4F;\n --u-pink-1000: #520830;\n\n /* ==========================================================================\n Role Colors — 의미 역할 층\n 컴포넌트는 팔레트 프리미티브가 아니라 이 층을 참조한다.\n 브랜드 색 교체는 아래 25개만 재정의하면 시맨틱 층까지 따라온다.\n\n 단은 '강도' 축이다 (weakest -> strong). 용도(배경/테두리/텍스트)는\n 소비처가 정한다 -- 단을 속성에 묶으면 primary 버튼의 배경이 어느\n 단인지 같은 모순이 생긴다.\n ========================================================================== */\n\n /* ★단이 팔레트 shade 와 1:1 이 아니다 — **대비로 고른다.**\n `-color` 는 `--u-*-txt-color` 를 받는 면이고 `-strong` 은 바탕 위의 글자다.\n 라이트에서는 바탕도 on-color 도 흰색이라 두 요구가 `contrast(shade, #FFF) ≥ 4.5`\n 하나로 합쳐지고, 그 단이 계열마다 다르다(blue 700 · red 700 · green 800).\n Material 램프는 휘도가 아니라 색상 기준으로 만들어져 있어서 단 번호가 세기를\n 보장하지 않는다 — 값은 `tests/build/token-contrast.test.ts` 가 지킨다. */\n\n /* primary — 브랜드 · 강조 · 포커스 · 링크 */\n --u-primary-color-weakest: var(--u-blue-200);\n --u-primary-color-weaker: var(--u-blue-300);\n --u-primary-color-weak: var(--u-blue-500);\n --u-primary-color: var(--u-blue-700); /* 4.60 ✓ (600 은 3.68 ✗) */\n --u-primary-color-strong: var(--u-blue-800); /* 5.75 ✓ */\n\n /* info — 정보 안내 (primary 와 기본값은 같으나 역할이 다르다 — 브랜딩은 primary 만 바꾼다) */\n --u-info-color-weakest: var(--u-blue-200);\n --u-info-color-weaker: var(--u-blue-300);\n --u-info-color-weak: var(--u-blue-500);\n --u-info-color: var(--u-blue-700);\n --u-info-color-strong: var(--u-blue-800);\n\n /* success — 성공 · 완료\n ⚠green 은 700 도 4.12 로 미달이라 두 단을 건너뛴다. 계열마다 통과 단이 다른 것이\n 이 층의 정상 상태다(단 번호를 맞추면 대비가 어긋난다). */\n --u-success-color-weakest: var(--u-green-200);\n --u-success-color-weaker: var(--u-green-300);\n --u-success-color-weak: var(--u-green-500);\n --u-success-color: var(--u-green-800); /* 5.13 ✓ (600=3.30 · 700=4.12 ✗) */\n --u-success-color-strong: var(--u-green-900); /* 7.87 ✓ */\n\n /* warning — 주의 */\n --u-warning-color-weakest: var(--u-yellow-200);\n --u-warning-color-weaker: var(--u-yellow-300);\n --u-warning-color-weak: var(--u-yellow-500);\n --u-warning-color: var(--u-yellow-600);\n /* ★다른 계열은 -strong 이 shade-800~900 인데 warning 만 1000 이다 — 노랑 램프는\n 900 까지도 흰 바탕 2.65 로 미달이고, 1000(#8A4A00)에서 처음 6.86 이 된다.\n 그 값은 갈색에 가깝지만, 이 단의 용도는 **면이 아니라 글자·아이콘**이므로 색상보다\n 가독성이 먼저다(경고 문구를 어두운 호박색으로 쓰는 것은 보편 관행이다). */\n --u-warning-color-strong: var(--u-yellow-1000);\n\n /* danger — 오류 · 위험 · 유효성 실패 */\n --u-danger-color-weakest: var(--u-red-200);\n --u-danger-color-weaker: var(--u-red-300);\n --u-danger-color-weak: var(--u-red-500);\n --u-danger-color: var(--u-red-700); /* 4.98 ✓ (600 은 4.23 ✗ — 오류 문구가 이 단이었다) */\n --u-danger-color-strong: var(--u-red-800); /* 5.62 ✓ */\n /* ==========================================================================\n Radius Scale — 모서리 반경\n 리터럴을 흩뿌리면 값이 갈린다(실제로 pill 이 999px/9999px 두 표기로 나뉘어 있었다).\n ========================================================================== */\n --u-radius-none: 0;\n --u-radius-sm: 3px;\n --u-radius-md: 4px;\n --u-radius-lg: 6px;\n --u-radius-xl: 8px;\n /* ★상단 2단은 **면(surface)용**이다 — 카드·패널·대화상자처럼 큰 사각형은 컨트롤과\n 같은 반경을 쓰면 각져 보인다. 기존 5단은 **컨트롤용**이고 값을 바꾸지 않는다\n (바꾸면 모든 소비자의 버튼·입력이 동시에 움직인다). */\n --u-radius-2xl: 12px;\n --u-radius-3xl: 16px;\n --u-radius-pill: 9999px;\n --u-radius-circle: 50%;\n\n /* ==========================================================================\n Space Scale — 컨테이너·오버레이의 절대 여백\n ⚠**여백은 하나의 축이 아니다.** 이 스케일은 컨테이너/오버레이(카드·대화상자·드로어·\n 알림·메뉴·툴팁 등)의 **레이아웃 여백**만 담당한다. 폼·인라인 요소의 `em` 여백은\n 상속된 `font-size` 에 비례하는 것이 의도이므로 **여기로 흡수하지 않는다** —\n 흡수하면 타이포를 키운 소비자의 여백이 따라 커지지 않는다.\n 축 구분과 근거는 docs/design-tokens.md 참조.\n ========================================================================== */\n --u-space-3xs: 2px;\n --u-space-2xs: 4px;\n --u-space-xs: 6px;\n --u-space-sm: 8px;\n --u-space-md: 12px;\n --u-space-lg: 16px;\n /* ★상단 4단은 **화면 리듬**이다 — 카드 안쪽 여백(20~24)·섹션 간격(24~32)·페이지 여백\n (32~40). 종전에는 이 구간이 통째로 비어 있어 소비자가 전부 리터럴로 적었고,\n 그래서 앱마다 화면 밀도가 달라졌다. `lg`(16px) 이하는 **요소 사이**, `xl` 이상은\n **영역 사이**로 나눠 쓴다.\n ⚠`xs: 6px` 는 4px 격자에서 벗어나 있으나 **바꾸지 않는다** — 이미 배선된 컨트롤\n 여백이 전부 움직인다. 신규 단은 전부 4의 배수로 둔다. */\n --u-space-xl: 20px;\n --u-space-2xl: 24px;\n --u-space-3xl: 32px;\n --u-space-4xl: 40px;\n\n /* Text Colors */\n --u-txt-color: var(--u-neutral-900);\n --u-txt-color-inverse: var(--u-neutral-0);\n /* 유채색 배경 위의 글자. --u-txt-color-inverse 는 다크에서 neutral-100(#121212)이라\n 유채색 버튼 위에서 읽히지 않는다. 브랜드 색을 바꾸는 소비자가 전경색도 함께\n 조절할 수 있도록 별도 이름을 준다.\n ⚠이 토큰이 흰색이라는 것과 그 위의 배경이 AA 를 받친다는 것은 별개다 —\n 라이트 팔레트의 shade-600 은 8색 중 6색이 흰 글자로 AA 에 미달한다(미해결). */\n --u-primary-txt-color: #FFFFFF;\n --u-info-txt-color: #FFFFFF;\n --u-success-txt-color: #FFFFFF;\n --u-danger-txt-color: #FFFFFF;\n /* ★warning 만 어둡다 — 취향이 아니라 측정이다. 노랑은 **어떤 단도** 흰 글자로 AA 를\n 받치지 못한다(라이트 최대 2.65 @900, 그마저 갈색). 다른 넷처럼 단을 옮기는 수단이\n 없으므로 전경을 뒤집는다. `--u-neutral-1000` 은 라이트 #000000 / 다크 #FFFFFF 이라\n 한 줄로 양 테마를 만족한다(라이트 15.05 · 다크 4.65). */\n --u-warning-txt-color: var(--u-neutral-1000);\n\n --u-txt-color-hover: var(--u-primary-color-strong);\n --u-txt-color-active: var(--u-primary-color-strong);\n --u-txt-color-disabled: var(--u-neutral-400);\n /* neutral-500(#9E9E9E)은 흰 배경 대비 2.68 로 WCAG AA(4.5) 미달이었다.\n neutral-600(#757575) = 4.61 로 통과한다. 다크 매핑(neutral-700 = 5.43)은\n 원래 정상이라 손대지 않는다 — 라이트 한쪽만의 결함이었다. */\n --u-txt-color-weak: var(--u-neutral-600);\n --u-txt-color-strong: var(--u-neutral-1000);\n\n --u-link-txt-color: var(--u-primary-color-strong);\n --u-tooltip-txt-color: var(--u-neutral-0);\n\n /* Icon Colors */\n --u-icon-color: var(--u-neutral-700);\n --u-icon-color-inverse: var(--u-neutral-0);\n --u-icon-color-hover: var(--u-primary-color-strong);\n --u-icon-color-active: var(--u-primary-color-strong);\n --u-icon-color-disabled: var(--u-neutral-400);\n\n /* Border Colors */\n --u-border-color: var(--u-neutral-300);\n --u-border-color-weak: var(--u-neutral-200);\n --u-border-color-strong: var(--u-neutral-400);\n --u-border-color-hover: var(--u-neutral-400);\n\n /* ★상태 테두리는 `-strong` 단이다 — 면이 아니라 **면 위에 그리는 선**이기 때문이다.\n 1.16.0 이 가른 용도(`-color` = 면 / `-strong` = 면·바탕 위)에 이 자리가 맞춰지지\n 않아 다크에서 미달이었다: focus 2.74 · invalid 2.44 (WCAG 1.4.11 기준 3.0).\n `-strong` 으로 옮기면 다크 4.74 / 4.34, 라이트 5.75 / 5.62 — 두 테마 모두 단조 상승. */\n --u-input-border-color: var(--u-neutral-300);\n --u-input-border-color-hover: var(--u-neutral-400);\n --u-input-border-color-focus: var(--u-primary-color-strong);\n --u-input-border-color-invalid: var(--u-danger-color-strong);\n\n /* Background Colors */\n --u-bg-color: var(--u-neutral-0);\n --u-bg-color-inverse: var(--u-neutral-900);\n --u-bg-color-hover: var(--u-neutral-100);\n --u-bg-color-active: var(--u-neutral-200);\n --u-bg-color-disabled: var(--u-neutral-50);\n\n /* ★면 높이 — 바탕에 인접해 있으면서 한 단 구분되는 크롬 면(툴바·표 헤더·푸터).\n 상호작용 상태(-hover/-active/-disabled)와 **다른 축**이다. 상태 이름에 높이를\n 얹으면 의미가 어긋난다(`DL-131-1`).\n `--u-panel-bg-color` 와도 다르다 — 그쪽은 **떠 있는 패널**(카드·대화상자·메뉴)이라\n 라이트에서 페이지와 같은 흰색이고 그림자가 높이를 나른다. 크롬 면은 그림자가 없어\n 라이트에서도 틴트가 필요하다.\n ⚠한 단만 정의한다. 두 단째의 실측 수요는 라이트 한쪽뿐이었다(다크에서는 소비 측\n 오버라이드가 두 값을 같은 단으로 합치고 있었다). */\n --u-bg-color-raised: var(--u-neutral-50);\n \n /* 유채색 표면 — 정보/성공/위험 상태의 '면'.\n 역할 층의 유채색은 전경 5단뿐이라, 상태 배경이 필요한 컴포넌트는 팔레트를 직접\n 읽고 다크를 손으로 보정해야 했다. 팔레트의 유채색 틴트는 다크에서 짓눌리므로\n (바탕 대비 델타의 다크/라이트 비 — 청색 0.38~0.54) 두 테마가 **같은 단이 아니라\n 같은 세기**가 되도록 짝지었다. 실측 비: blue 1.09 · red 1.12 · green 0.91.\n\n ★**warning 이 합류했다(1.16.0 → 1.17.0).** 종전에는 *\"세기를 맞출 단 짝이 없다\"* 며\n 빠져 있었는데, 그 판정은 **shade-0 짝만** 재고 있었다. 노랑만 한 단 내려 잡으면\n 라이트 쪽 세기가 맞는다 — 바탕 대비 휘도 델타 실측:\n blue-0 0.131 · red-0 0.132 · green-0 0.117 · **yellow-200 0.110** (yellow-0 은 0.027)\n ⚠단 이름이 계열마다 다른 것(yellow 만 200)은 이 층의 정상 상태다. 라이트 팔레트는\n 휘도 순이 아니므로 같은 단 번호가 같은 세기를 뜻하지 않는다. */\n --u-primary-bg-color: var(--u-blue-0);\n --u-info-bg-color: var(--u-blue-0);\n --u-success-bg-color: var(--u-green-0);\n --u-danger-bg-color: var(--u-red-0);\n --u-warning-bg-color: var(--u-yellow-200);\n\n --u-input-bg-color: var(--u-neutral-0);\n --u-panel-bg-color: var(--u-neutral-0);\n --u-overlay-bg-color: rgba(0, 0, 0, 0.5);\n --u-tooltip-bg-color: rgba(0, 0, 0, 0.75);\n\n /* Shadow Colors */\n --u-shadow-color-weaker: rgba(0, 0, 0, 0.04);\n --u-shadow-color-weak: rgba(0, 0, 0, 0.08);\n --u-shadow-color-normal: rgba(0, 0, 0, 0.12);\n --u-shadow-color-strong: rgba(0, 0, 0, 0.16);\n --u-shadow-color-stronger: rgba(0, 0, 0, 0.24);\n\n /* ==========================================================================\n Elevation Scale — 높이(그림자)\n\n ★색 축은 있었지만 **높이 축이 없었다.** 그 결과 컴포넌트가 그림자를 리터럴로\n 썼고, 같은 리듬을 의도한 자리에 서로 다른 값 11가지가 생겼다(카드 .1 vs 캐러셀\n .15 — 둘 다 \"표면에 얹힌 카드\"인데 알파가 다르다).\n\n ⚠**그리고 그 리터럴들은 테마를 몰랐다** — `rgba(0,0,0,.1)` 은 다크 바탕에서\n 거의 보이지 않는다. 이 축을 경유하면 다크의 진한 알파(.25~.60)를 자동으로 받는다.\n\n ⚠**알파를 `--u-shadow-color-*` 로 중첩하지 않고 인라인한다.** use-site 폴백\n 생성기는 합성 값을 리터럴로 다루므로, 중첩하면 `var(--u-shadow-md, 0 2px 8px\n var(--u-shadow-color-normal))` 처럼 **폴백 안에 또 토큰이 들어간다** — 시트가\n 없을 때 그 폴백도 함께 무효가 되어 그림자가 통째로 사라진다.\n 두 축의 알파가 어긋나지 않는지는 `tests/build/elevation-scale.test.ts` 가 지킨다.\n ========================================================================== */\n --u-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 1px rgba(0, 0, 0, 0.04); /* = shadow-color-weak — 표면에 얹힌 작은 컨트롤(탭·손잡이) */\n --u-shadow-md: 0 2px 8px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.05); /* = shadow-color-normal — 카드·표면 */\n --u-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.16), 0 2px 4px rgba(0, 0, 0, 0.06); /* = shadow-color-strong — 떠 있는 레이어(드롭다운·알림) */\n --u-shadow-xl: 0 6px 18px rgba(0, 0, 0, 0.24), 0 2px 6px rgba(0, 0, 0, 0.08); /* = shadow-color-stronger — 모달·최상위(대화상자·툴팁) */\n\n\n /* ==========================================================================\n Type Scale — 글자 크기·굵기·행간·자간의 **한 벌**\n ★**크기만 주면 스케일이 되지 않는다.** 소비자가 크기만 받고 굵기·행간을 각자 정하면\n 결국 화면마다 다른 위계가 생긴다 — 그래서 네 값을 **단 단위로 묶어** 낸다.\n\n 단 이름은 크기가 아니라 **역할**이다(`lg`/`xl` 이 아니라 `title`/`label`). 역할로 두면\n 소비자가 *\"어느 크기를 쓸까\"* 가 아니라 *\"이 글자는 무엇인가\"* 를 묻게 된다.\n\n ★**한글 기준으로 값을 골랐다**:\n ⑴ 행간은 **1.4 이상**. 라틴 관례(1.2)는 한글에서 답답하다 — 받침 때문에 글자 상자가\n 세로로 꽉 차 있어 라틴과 같은 행간이면 줄이 붙어 보인다.\n ⑵ 자간은 **0 이 기본**이고 큰 제목만 **음수**. 한글에 양수 자간(letter-spacing)을 주면\n 가독성이 떨어진다 — 라틴 소문자 조판 관례를 그대로 옮기면 안 되는 자리다.\n ⑶ `overline` 에만 양수 자간을 둔다. 그 단은 **영문·숫자 라벨**을 전제한 자리이고,\n 한글을 넣을 소비자는 자간을 0 으로 덮어야 한다(문서에 명시).\n\n ⚠**`text-transform` 은 토큰으로 내지 않는다.** 한글에는 대문자가 없어 `uppercase` 가\n 아무 효과가 없고, 영문이 섞이면 그것만 커져 오히려 어수선해진다.\n ========================================================================== */\n --u-text-display-size: 26px;\n --u-text-display-weight: 700;\n --u-text-display-leading: 1.4;\n --u-text-display-tracking: -0.02em;\n\n --u-text-title-size: 20px;\n --u-text-title-weight: 700;\n --u-text-title-leading: 1.45;\n --u-text-title-tracking: -0.01em;\n\n --u-text-subtitle-size: 16px;\n --u-text-subtitle-weight: 600;\n --u-text-subtitle-leading: 1.5;\n --u-text-subtitle-tracking: 0;\n\n --u-text-body-size: 14px;\n --u-text-body-weight: 400;\n --u-text-body-leading: 1.6;\n --u-text-body-tracking: 0;\n\n --u-text-label-size: 13px;\n --u-text-label-weight: 600;\n --u-text-label-leading: 1.5;\n --u-text-label-tracking: 0;\n\n --u-text-caption-size: 12px;\n --u-text-caption-weight: 400;\n --u-text-caption-leading: 1.5;\n --u-text-caption-tracking: 0;\n\n --u-text-overline-size: 11px;\n --u-text-overline-weight: 700;\n --u-text-overline-leading: 1.45;\n --u-text-overline-tracking: 0.06em;\n\n /* ==========================================================================\n Motion — 지속시간·이징\n ★값이 없으면 앱마다 다른 속도가 생기고, `prefers-reduced-motion` 은 **반드시**\n 빠뜨리는 앱이 나온다. 축을 여기 두고 존중 규칙은 아래 미디어 쿼리가 진다.\n ========================================================================== */\n --u-duration-instant: 80ms;\n --u-duration-fast: 140ms;\n --u-duration-normal: 220ms;\n --u-duration-slow: 320ms;\n --u-ease-standard: cubic-bezier(0.2, 0, 0, 1);\n --u-ease-decelerate: cubic-bezier(0, 0, 0, 1);\n --u-ease-accelerate: cubic-bezier(0.3, 0, 1, 1);\n\n /* Scrollbar Colors */\n --u-scrollbar-color: var(--u-neutral-400);\n --u-scrollbar-color-hover: var(--u-neutral-500);\n --u-scrollbar-track-color: transparent;\n\n /* ==========================================================================\n Font Styles\n ★**CJK 폴백을 스택에 포함한다 — 국제화이지 취향이 아니다.**\n 종전 스택(`-apple-system, Segoe UI, Noto Sans, Helvetica, Arial`)에는 **한중일 글립을\n 가진 폰트가 하나도 없었다.** Windows 에서 한글은 `Segoe UI` 에 없으므로 UA 가 임의로\n 맑은 고딕을 고르고, macOS 는 `-apple-system` 이 Apple SD Gothic Neo 를 준다 ⇒ **같은 앱이\n OS 마다 다른 글꼴로 렌더**됐다. 폴백을 명시하면 그 선택이 결정적이 된다.\n ⚠**웹폰트를 로드하지 않는다.** 라이브러리가 네트워크 요청을 만들면 소비자의 CSP·\n 오프라인 환경을 깬다. 스택 맨 앞의 `Pretendard` 는 **소비자가 로드했을 때만** 잡히는\n 선택적 이름이다(없으면 조용히 다음으로 넘어간다).\n ========================================================================== */\n --u-font-base: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans KR', 'Hiragino Sans', 'Yu Gothic UI', 'Microsoft YaHei', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';\n --u-font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Monaco, 'Courier New', monospace;\n --u-font-serif: 'Georgia', 'Times New Roman', Times, serif;\n --u-font-display: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;\n --u-font-modern: 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n --u-font-rounded: 'Nunito', 'Quicksand', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n}\n\n/* ==========================================================================\n ★`prefers-reduced-motion` 존중 — **라이브러리가 진다.**\n 소비자마다 각자 처리하게 두면 반드시 빠뜨리는 앱이 나온다(그리고 그 앱은\n 접근성 감사 전까지 아무도 모른다). 지속시간 축을 0 으로 눌러 두면 이 축을\n 경유하는 모든 애니메이션이 함께 멈춘다.\n ⚠`animation: none` 으로 강제하지 않는다 — 로딩 스피너처럼 **의미를 나르는**\n 움직임까지 죽이면 사용자가 진행 중인지 알 수 없게 된다.\n ========================================================================== */\n@media (prefers-reduced-motion: reduce) {\n :root {\n --u-duration-instant: 0ms;\n --u-duration-fast: 0ms;\n --u-duration-normal: 0ms;\n --u-duration-slow: 0ms;\n }\n}\n";
3
3
  //#endregion
4
4
  export { light_css_default as default };
@@ -19,7 +19,7 @@ var styles = css`
19
19
  opacity: 0;
20
20
  visibility: hidden;
21
21
  pointer-events: none;
22
- transition: opacity 0.2s ease, visibility 0s 0.2s;
22
+ transition: opacity var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), visibility 0s var(--u-duration-normal, 220ms);
23
23
  }
24
24
  :host([open]) {
25
25
  opacity: 1;
@@ -12,7 +12,7 @@ var styles = css`
12
12
  visibility: hidden;
13
13
  pointer-events: none;
14
14
  /* 패널 슬라이드와 동일 duration + easing으로 맞춰 '띠요옹' 느낌 제거 (타이밍 미스매치 방지) */
15
- transition: opacity 0.35s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s 0.35s;
15
+ transition: opacity var(--u-duration-slow, 320ms) var(--u-ease-decelerate, cubic-bezier(0, 0, 0, 1)), visibility 0s var(--u-duration-slow, 320ms);
16
16
  overflow: hidden;
17
17
  }
18
18
  :host([open]) {
@@ -47,16 +47,16 @@ var styles = css`
47
47
  max-width: 100%;
48
48
  max-height: 50vh;
49
49
  border-radius: var(--u-radius-xl, 8px);
50
- box-shadow: var(--u-shadow-lg, 0 4px 12px rgba(0, 0, 0, 0.16));
50
+ box-shadow: var(--u-shadow-lg, 0 4px 12px rgba(0, 0, 0, 0.16), 0 2px 4px rgba(0, 0, 0, 0.06));
51
51
 
52
52
  opacity: 0;
53
53
  transform: scale(0.8);
54
54
  visibility: hidden;
55
55
  pointer-events: none;
56
56
  transition:
57
- visibility 0s 0.2s,
58
- opacity 0.2s ease,
59
- transform 0.2s ease-out;
57
+ visibility 0s var(--u-duration-normal, 220ms),
58
+ opacity var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)),
59
+ transform var(--u-duration-normal, 220ms) ease-out;
60
60
  }
61
61
  :host([open]) {
62
62
  opacity: 1;
@@ -88,7 +88,9 @@ var styles = css`
88
88
  --alert-border-width: 1px;
89
89
  --alert-border-color: rgba(255, 255, 255, 0.3);
90
90
  background: rgba(255, 255, 255, 0.2);
91
- border-radius: 16px;
91
+ /* 유리 질감의 넉넉한 반경 — 반경 스케일에 면(surface)용 상단 단이 생기면서
92
+ 리터럴 16px 이 스케일 안으로 들어왔다. 값은 그대로이고 출처만 축으로 옮긴다. */
93
+ border-radius: var(--u-radius-3xl, 16px);
92
94
  /* ⚠**높이 축(--u-shadow-*)을 쓰지 않는다** — 이 값은 유리 질감 레시피의 일부이고
93
95
  (30px 번짐 + backdrop-filter), 높이를 뜻하지 않는다. 축으로 접으면 질감이 사라진다. */
94
96
  box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
@@ -115,7 +117,7 @@ var styles = css`
115
117
  align-items: center;
116
118
  gap: var(--u-space-md, 12px);
117
119
  margin-bottom: var(--u-space-2xs, 4px);
118
- font-size: 16px;
120
+ font-size: var(--u-text-subtitle-size, 16px);
119
121
  user-select: none;
120
122
  }
121
123
  .header .icon {
@@ -26,7 +26,7 @@ var styles = css`
26
26
  gap: 0.2em;
27
27
  color: inherit;
28
28
  text-decoration: none;
29
- transition: color 0.2s ease;
29
+ transition: color var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
30
30
  cursor: inherit;
31
31
  }
32
32
 
@@ -43,7 +43,7 @@ var styles = css`
43
43
  border-radius: var(--u-radius-lg, 6px);
44
44
  background-color: transparent;
45
45
 
46
- transition: all 0.2s ease;
46
+ transition: all var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
47
47
  overflow: hidden;
48
48
  user-select: none;
49
49
  cursor: pointer;
@@ -5,7 +5,7 @@ var styles = css`
5
5
  display: flex;
6
6
  border-radius: var(--u-radius-xl, 8px);
7
7
  background-color: var(--u-panel-bg-color, #FFFFFF);
8
- box-shadow: var(--u-shadow-md, 0 2px 8px rgba(0, 0, 0, 0.12));
8
+ box-shadow: var(--u-shadow-md, 0 2px 8px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.05));
9
9
  overflow: hidden;
10
10
 
11
11
  --card-border-width: 1px;
@@ -37,11 +37,11 @@ var styles = css`
37
37
  }
38
38
  :host([hoverable]) {
39
39
  cursor: pointer;
40
- transition: all 0.2s ease;
40
+ transition: all var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
41
41
  }
42
42
  :host([hoverable]:hover) {
43
43
  transform: translateY(-2px);
44
- box-shadow: var(--u-shadow-lg, 0 4px 12px rgba(0, 0, 0, 0.16));
44
+ box-shadow: var(--u-shadow-lg, 0 4px 12px rgba(0, 0, 0, 0.16), 0 2px 4px rgba(0, 0, 0, 0.06));
45
45
  }
46
46
 
47
47
  .media {
@@ -39,7 +39,7 @@ var styles = css`
39
39
  width: 100%;
40
40
  height: 100%;
41
41
  gap: var(--slide-gap, 0px);
42
- transition: transform 0.3s ease-in-out;
42
+ transition: transform var(--u-duration-slow, 320ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
43
43
  }
44
44
 
45
45
  ::slotted(*) {
@@ -60,11 +60,11 @@ var styles = css`
60
60
  font-size: 20px;
61
61
  color: var(--u-neutral-900, #212121);
62
62
  background-color: var(--u-neutral-100, #F5F5F5);
63
- box-shadow: var(--u-shadow-md, 0 2px 8px rgba(0, 0, 0, 0.12));
63
+ box-shadow: var(--u-shadow-md, 0 2px 8px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.05));
64
64
  }
65
65
  .nav-button:hover {
66
66
  background-color: var(--u-neutral-200, #EEEEEE);
67
- box-shadow: var(--u-shadow-lg, 0 4px 12px rgba(0, 0, 0, 0.16));
67
+ box-shadow: var(--u-shadow-lg, 0 4px 12px rgba(0, 0, 0, 0.16), 0 2px 4px rgba(0, 0, 0, 0.06));
68
68
  transform: translateY(-50%) scale(1.1);
69
69
  }
70
70
  .nav-button:active {
@@ -97,7 +97,7 @@ var styles = css`
97
97
  border-radius: var(--u-radius-circle, 50%);
98
98
  background-color: var(--u-neutral-400, #BDBDBD);
99
99
  cursor: pointer;
100
- transition: all 0.2s ease;
100
+ transition: all var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
101
101
  }
102
102
  .dot:hover {
103
103
  background-color: var(--u-neutral-200, #EEEEEE);
@@ -154,14 +154,14 @@ var styles = css`
154
154
  border: 2px solid var(--checkbox-border-color);
155
155
  border-radius: 0.2em;
156
156
  background-color: var(--checkbox-background-color);
157
- transition: border-color 0.2s ease, background-color 0.2s ease;
157
+ transition: border-color var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), background-color var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
158
158
  }
159
159
 
160
160
  /* 체크박스 아이콘 */
161
161
  .checkbox u-icon {
162
162
  font-size: 0.85em;
163
163
  transform: scale(0);
164
- transition: transform 0.15s ease;
164
+ transition: transform var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
165
165
  }
166
166
 
167
167
  .label {
@@ -70,11 +70,11 @@ var styles = css`
70
70
  border: 1px solid var(--u-border-color, color-mix(in srgb, CanvasText 20%, Canvas));
71
71
  border-radius: var(--u-radius-lg, 6px);
72
72
  background: var(--u-panel-bg-color, Canvas);
73
- box-shadow: var(--u-shadow-xl, 0 6px 18px rgba(0, 0, 0, 0.24));
73
+ box-shadow: var(--u-shadow-xl, 0 6px 18px rgba(0, 0, 0, 0.24), 0 2px 6px rgba(0, 0, 0, 0.08));
74
74
  pointer-events: auto;
75
75
  opacity: 0;
76
76
  transform: scale(0.92);
77
- transition: opacity 0.3s ease, transform 0.3s ease;
77
+ transition: opacity var(--u-duration-slow, 320ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), transform var(--u-duration-slow, 320ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
78
78
  }
79
79
  :host([open]) .panel {
80
80
  opacity: 1;
@@ -57,7 +57,7 @@ var styles = css`
57
57
  display: flex;
58
58
  flex-direction: column;
59
59
  background: var(--u-panel-bg-color, Canvas);
60
- box-shadow: var(--u-shadow-xl, 0 6px 18px rgba(0, 0, 0, 0.24));
60
+ box-shadow: var(--u-shadow-xl, 0 6px 18px rgba(0, 0, 0, 0.24), 0 2px 6px rgba(0, 0, 0, 0.08));
61
61
  pointer-events: auto;
62
62
  /*
63
63
  * easeOutQuart (cubic-bezier(0.22, 1, 0.36, 1)) — 빠르게 시작해서 부드럽게 정착.
@@ -66,7 +66,7 @@ var styles = css`
66
66
  * UOverlayElement의 backdrop opacity transition과 동일 duration/easing으로 맞춤.
67
67
  * 호스트 앱이 ::part(panel) { transition: ... }로 추가 override 가능.
68
68
  */
69
- transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
69
+ transition: transform var(--u-duration-slow, 320ms) var(--u-ease-decelerate, cubic-bezier(0, 0, 0, 1));
70
70
  }
71
71
 
72
72
  .header {
@@ -26,7 +26,7 @@ var styles = css`
26
26
  border: 1px solid var(--u-input-border-color, #E0E0E0);
27
27
  border-radius: 0.25em;
28
28
  background-color: var(--u-input-bg-color, #FFFFFF);
29
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
29
+ transition: border-color var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), box-shadow var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
30
30
  overflow: hidden;
31
31
  }
32
32
  :host([readonly]) .container,
@@ -157,7 +157,7 @@ var styles = css`
157
157
  margin-left: 0.25em;
158
158
  color: var(--u-icon-color, #616161);
159
159
  font-size: 1em;
160
- transition: color 0.2s ease;
160
+ transition: color var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
161
161
  cursor: pointer;
162
162
  }
163
163
  .suffix-item:hover {
@@ -175,7 +175,7 @@ var styles = css`
175
175
  border: 1px solid var(--u-border-color, #E0E0E0);
176
176
  border-radius: var(--u-radius-lg, 6px);
177
177
  background-color: var(--u-panel-bg-color, #FFFFFF);
178
- box-shadow: var(--u-shadow-lg, 0 4px 12px rgba(0, 0, 0, 0.16));
178
+ box-shadow: var(--u-shadow-lg, 0 4px 12px rgba(0, 0, 0, 0.16), 0 2px 4px rgba(0, 0, 0, 0.06));
179
179
  overflow-x: auto;
180
180
  overflow-y: auto;
181
181
  }
@@ -25,7 +25,7 @@ var styles = css`
25
25
  padding: 0.25em 0.5em;
26
26
  padding-left: calc(var(--menu-indent-size) * var(--menu-item-depth) + 0.5em);
27
27
  background-color: transparent;
28
- transition: background-color 0.15s ease, color 0.15s ease;
28
+ transition: background-color var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), color var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
29
29
  user-select: none;
30
30
  cursor: pointer;
31
31
  }
@@ -77,7 +77,7 @@ var styles = css`
77
77
  position: absolute;
78
78
  border-radius: 1px;
79
79
  background-color: currentColor;
80
- transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
80
+ transition: transform var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
81
81
  }
82
82
  /* 기본: 위 방향 chevron (∧) */
83
83
  .suffix-toggler::before {
@@ -139,9 +139,9 @@ var styles = css`
139
139
  border: 1px solid var(--u-border-color, #E0E0E0);
140
140
  border-radius: var(--u-radius-md, 4px);
141
141
  background-color: var(--u-panel-bg-color, #FFFFFF);
142
- box-shadow: var(--u-shadow-md, 0 2px 8px rgba(0, 0, 0, 0.12));
142
+ box-shadow: var(--u-shadow-md, 0 2px 8px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.05));
143
143
  transform: scale(0.8);
144
- transition: opacity 0.2s ease, visibility 0s 0.2s, transform 0.2s ease;
144
+ transition: opacity var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), visibility 0s var(--u-duration-normal, 220ms), transform var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
145
145
  }
146
146
  .popover[open] {
147
147
  transform: scale(1);
@@ -18,7 +18,7 @@ var styles = css`
18
18
 
19
19
  :host {
20
20
  display: flex;
21
- transition: background-color 0.15s ease, color 0.15s ease;
21
+ transition: background-color var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), color var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
22
22
  user-select: none;
23
23
  cursor: pointer;
24
24
 
@@ -102,7 +102,7 @@ var styles = css`
102
102
  border: 2px solid var(--u-neutral-400, #BDBDBD);
103
103
  border-radius: var(--u-radius-circle, 50%);
104
104
  background-color: var(--u-bg-color, #FFFFFF);
105
- transition: border-color 0.2s ease, background-color 0.2s ease;
105
+ transition: border-color var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), background-color var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
106
106
  }
107
107
  :host([marker="radio"]:not([disabled]):hover) .radio-marker,
108
108
  :host([marker="radio"]:not([disabled]):focus-visible) .radio-marker {
@@ -127,7 +127,7 @@ var styles = css`
127
127
  border-radius: var(--u-radius-circle, 50%);
128
128
  background-color: var(--option-color-active);
129
129
  transform: scale(0);
130
- transition: transform 0.15s ease;
130
+ transition: transform var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
131
131
  }
132
132
  :host([marker="radio"][selected]) .radio-marker::after {
133
133
  transform: scale(1);
@@ -77,7 +77,7 @@ var styles = css`
77
77
  background-color: var(--progress-bar-color);
78
78
  transform-origin: left center;
79
79
  transform: scaleX(0);
80
- transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
80
+ transition: transform var(--u-duration-slow, 320ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
81
81
  will-change: transform;
82
82
  }
83
83
 
@@ -89,7 +89,7 @@ var styles = css`
89
89
  background-color: var(--progress-bar-buffer-color);
90
90
  transform-origin: left center;
91
91
  transform: scaleX(0);
92
- transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
92
+ transition: transform var(--u-duration-slow, 320ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
93
93
  will-change: transform;
94
94
  }
95
95
 
@@ -60,7 +60,7 @@ var styles = css`
60
60
  /* === Mask === */
61
61
  .mask-progress,
62
62
  .mask-buffer {
63
- transition: stroke-dashoffset 0.4s cubic-bezier(0.4, 0, 0.2, 1);
63
+ transition: stroke-dashoffset var(--u-duration-slow, 320ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
64
64
  }
65
65
 
66
66
  /* === Track === */
@@ -29,7 +29,7 @@ var styles = css`
29
29
  outline: none;
30
30
  border-radius: 0.15em;
31
31
  color: var(--rating-symbol-off-color);
32
- transition: color 0.15s ease, transform 0.15s ease;
32
+ transition: color var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), transform var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
33
33
  }
34
34
  .symbol:focus-visible {
35
35
  outline: 2px solid var(--u-primary-color-strong, #1565C0);
@@ -24,7 +24,7 @@ var styles = css`
24
24
  border: 1px solid var(--u-input-border-color, #E0E0E0);
25
25
  border-radius: 0.25em;
26
26
  background-color: var(--u-input-bg-color, #FFFFFF);
27
- transition: border-color 0.2s ease, box-shadow 0.2s ease;
27
+ transition: border-color var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), box-shadow var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
28
28
  overflow: hidden;
29
29
  user-select: none;
30
30
  cursor: pointer;
@@ -155,7 +155,7 @@ var styles = css`
155
155
  margin-left: 0.25em;
156
156
  font-size: 1em;
157
157
  color: var(--u-icon-color, #616161);
158
- transition: color 0.2s ease;
158
+ transition: color var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
159
159
  cursor: pointer;
160
160
  }
161
161
  .suffix-item:hover {
@@ -175,7 +175,7 @@ var styles = css`
175
175
  border: 1px solid var(--u-border-color, #E0E0E0);
176
176
  border-radius: var(--u-radius-lg, 6px);
177
177
  background-color: var(--u-panel-bg-color, #FFFFFF);
178
- box-shadow: var(--u-shadow-lg, 0 4px 12px rgba(0, 0, 0, 0.16));
178
+ box-shadow: var(--u-shadow-lg, 0 4px 12px rgba(0, 0, 0, 0.16), 0 2px 4px rgba(0, 0, 0, 0.06));
179
179
  overflow-x: hidden;
180
180
  overflow-y: auto;
181
181
  }
@@ -75,14 +75,14 @@ var styles = css`
75
75
  border: 2px solid var(--slider-thumb-border-color);
76
76
  border-radius: var(--u-radius-circle, 50%);
77
77
  background: var(--slider-thumb-color);
78
- box-shadow: var(--u-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.08));
79
- transition: transform 0.15s ease, box-shadow 0.15s ease;
78
+ box-shadow: var(--u-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 1px rgba(0, 0, 0, 0.04));
79
+ transition: transform var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), box-shadow var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
80
80
  cursor: pointer;
81
81
  }
82
82
  .thumb:hover .thumb-content,
83
83
  .thumb:active .thumb-content {
84
84
  transform: scale(1.15);
85
- box-shadow: var(--u-shadow-md, 0 2px 8px rgba(0, 0, 0, 0.12));
85
+ box-shadow: var(--u-shadow-md, 0 2px 8px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.05));
86
86
  }
87
87
  .thumb:focus-visible .thumb-content {
88
88
  box-shadow: 0 0 0 1px var(--slider-fill-color);
@@ -36,7 +36,7 @@ var styles = css`
36
36
  align-items: center;
37
37
  justify-content: center;
38
38
  background-color: var(--splitter-color);
39
- transition: background-color 0.15s ease;
39
+ transition: background-color var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
40
40
  touch-action: none;
41
41
  }
42
42
  .splitter:hover {
@@ -11,7 +11,10 @@ var styles = css`
11
11
  --switch-thumb-color: #fff;
12
12
  --switch-thumb-color-checked: #fff;
13
13
  --switch-radius: 9999px;
14
- --switch-duration: 0.25s;
14
+ /* ★로컬 축이지만 **기본값은 공용 축에서 파생**한다 — 그러지 않으면
15
+ prefers-reduced-motion 이 이 컴포넌트만 비껴간다(축을 경유해야 함께 멈춘다).
16
+ 소비자가 --switch-duration 을 덮으면 그 값이 이긴다(로컬 축의 존재 이유). */
17
+ --switch-duration: var(--u-duration-normal, 220ms);
15
18
  --switch-move-width: calc(var(--switch-track-width) - var(--switch-thumb-size) - var(--switch-thumb-offset) * 2);
16
19
  }
17
20
 
@@ -70,7 +73,7 @@ var styles = css`
70
73
  height: var(--switch-track-height);
71
74
  border-radius: var(--switch-radius);
72
75
  background: var(--switch-track-color);
73
- transition: background var(--switch-duration) ease;
76
+ transition: background var(--switch-duration) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
74
77
  }
75
78
  :host([checked]) .track {
76
79
  background: var(--switch-track-color-checked);
@@ -92,7 +95,7 @@ var styles = css`
92
95
  line-height: 1;
93
96
  white-space: nowrap;
94
97
  pointer-events: none;
95
- transition: opacity var(--switch-duration) ease;
98
+ transition: opacity var(--switch-duration) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
96
99
  }
97
100
  .track-checked {
98
101
  opacity: 0;
@@ -123,11 +126,11 @@ var styles = css`
123
126
  height: var(--switch-thumb-size);
124
127
  border-radius: var(--switch-radius);
125
128
  background: var(--switch-thumb-color);
126
- box-shadow: var(--u-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.08));
129
+ box-shadow: var(--u-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 1px rgba(0, 0, 0, 0.04));
127
130
  overflow: hidden;
128
131
  transition:
129
- transform var(--switch-duration) cubic-bezier(0.4, 0, 0.2, 1),
130
- background var(--switch-duration) ease;
132
+ transform var(--switch-duration) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)),
133
+ background var(--switch-duration) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
131
134
  }
132
135
  :host([checked]) .thumb {
133
136
  transform: translateX(var(--switch-move-width));
@@ -148,8 +151,8 @@ var styles = css`
148
151
  line-height: 1;
149
152
  pointer-events: none;
150
153
  transition:
151
- opacity var(--switch-duration) ease,
152
- transform var(--switch-duration) ease;
154
+ opacity var(--switch-duration) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)),
155
+ transform var(--switch-duration) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
153
156
  }
154
157
  .thumb-checked {
155
158
  opacity: 0;
@@ -48,7 +48,7 @@ var styles = css`
48
48
  font-size: 0.75em;
49
49
  color: inherit;
50
50
  opacity: 0.5;
51
- transition: opacity 0.15s ease;
51
+ transition: opacity var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
52
52
  }
53
53
  .remove-btn:hover {
54
54
  opacity: 1;
@@ -188,7 +188,7 @@ var styles = css`
188
188
  :host([variant="pill"]) ::slotted(u-tab[active]) {
189
189
  border-color: var(--u-border-color, #E0E0E0);
190
190
  background-color: var(--u-neutral-0, #FFFFFF);
191
- box-shadow: var(--u-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.08));
191
+ box-shadow: var(--u-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 1px rgba(0, 0, 0, 0.04));
192
192
  }
193
193
 
194
194
  /* Variant: plain */
@@ -163,7 +163,7 @@ var styles = css`
163
163
 
164
164
  :host {
165
165
  display: inline-flex;
166
- font-size: 12px;
166
+ font-size: var(--u-text-caption-size, 12px);
167
167
  font-weight: 500;
168
168
  border-radius: var(--u-radius-md, 4px);
169
169
 
@@ -15,7 +15,7 @@ var styles = css`
15
15
  border: 1px solid var(--u-input-border-color, #E0E0E0);
16
16
  border-radius: 0.25em;
17
17
  background-color: var(--u-input-bg-color, #FFFFFF);
18
- transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
18
+ transition: border-color var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), box-shadow var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), background-color var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
19
19
  }
20
20
  :host([readonly]) .container,
21
21
  :host([disabled]) .container {
@@ -8,13 +8,13 @@ var styles = css`
8
8
  :host {
9
9
  color: var(--u-tooltip-txt-color, #FFFFFF);
10
10
  font-family: var(--u-font-display, inherit);
11
- font-size: 12px;
11
+ font-size: var(--u-text-caption-size, 12px);
12
12
  line-height: 1.25;
13
13
  border-radius: var(--u-radius-md, 4px);
14
14
  background-color: var(--u-tooltip-bg-color, rgba(0, 0, 0, 0.75));
15
- box-shadow: var(--u-shadow-xl, 0 6px 18px rgba(0, 0, 0, 0.24));
15
+ box-shadow: var(--u-shadow-xl, 0 6px 18px rgba(0, 0, 0, 0.24), 0 2px 6px rgba(0, 0, 0, 0.08));
16
16
  transform: scale(0.9);
17
- transition: opacity 0.2s ease, transform 0.2s ease, visibility 0s 0.2s;
17
+ transition: opacity var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), transform var(--u-duration-normal, 220ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), visibility 0s var(--u-duration-normal, 220ms);
18
18
 
19
19
  --tooltip-padding-block: var(--u-space-xs, 6px);
20
20
  --tooltip-padding-inline: var(--u-space-sm, 8px);
@@ -27,7 +27,7 @@ var styles = css`
27
27
  var(--tree-indent-size) * var(--tree-item-depth)
28
28
  + var(--tree-indent-guide-offset)
29
29
  );
30
- transition: background-color 0.15s ease, color 0.15s ease;
30
+ transition: background-color var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), color var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
31
31
  user-select: none;
32
32
  cursor: pointer;
33
33
  }
@@ -89,7 +89,7 @@ var styles = css`
89
89
  border-radius: var(--u-radius-sm, 3px);
90
90
  border: 1.5px solid var(--u-input-border-color, #E0E0E0);
91
91
  background-color: transparent;
92
- transition: background-color 0.15s ease, border-color 0.15s ease;
92
+ transition: background-color var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1)), border-color var(--u-duration-fast, 140ms) var(--u-ease-standard, cubic-bezier(0.2, 0, 0, 1));
93
93
  cursor: pointer;
94
94
  }
95
95
  .prefix-checkbox u-icon {
@@ -194,6 +194,11 @@
194
194
  --u-radius-md: 4px;
195
195
  --u-radius-lg: 6px;
196
196
  --u-radius-xl: 8px;
197
+ /* ★상단 2단은 **면(surface)용**이다 — 카드·패널·대화상자처럼 큰 사각형은 컨트롤과
198
+ 같은 반경을 쓰면 각져 보인다. 기존 5단은 **컨트롤용**이고 값을 바꾸지 않는다
199
+ (바꾸면 모든 소비자의 버튼·입력이 동시에 움직인다). */
200
+ --u-radius-2xl: 12px;
201
+ --u-radius-3xl: 16px;
197
202
  --u-radius-pill: 9999px;
198
203
  --u-radius-circle: 50%;
199
204
 
@@ -210,6 +215,16 @@
210
215
  --u-space-sm: 8px;
211
216
  --u-space-md: 12px;
212
217
  --u-space-lg: 16px;
218
+ /* ★상단 4단은 **화면 리듬**이다 — 카드 안쪽 여백(20~24)·섹션 간격(24~32)·페이지 여백
219
+ (32~40). 종전에는 이 구간이 통째로 비어 있어 소비자가 전부 리터럴로 적었고,
220
+ 그래서 앱마다 화면 밀도가 달라졌다. `lg`(16px) 이하는 **요소 사이**, `xl` 이상은
221
+ **영역 사이**로 나눠 쓴다.
222
+ ⚠`xs: 6px` 는 4px 격자에서 벗어나 있으나 **바꾸지 않는다** — 이미 배선된 컨트롤
223
+ 여백이 전부 움직인다. 신규 단은 전부 4의 배수로 둔다. */
224
+ --u-space-xl: 20px;
225
+ --u-space-2xl: 24px;
226
+ --u-space-3xl: 32px;
227
+ --u-space-4xl: 40px;
213
228
 
214
229
  /* Text Colors */
215
230
  --u-txt-color: var(--u-neutral-900);
@@ -290,18 +305,96 @@
290
305
  /* Elevation Scale — 근거는 light.css 의 같은 자리 주석 참조.
291
306
  ★다크는 알파가 3배 가까이 진하다 — 리터럴로 흩어져 있던 종전에는 이 차이가
292
307
  적용되지 않아 다크에서 그림자가 사실상 보이지 않았다. */
293
- --u-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.25); /* = shadow-color-weak */
294
- --u-shadow-md: 0 2px 8px rgba(0, 0, 0, 0.35); /* = shadow-color-normal */
295
- --u-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.45); /* = shadow-color-strong */
296
- --u-shadow-xl: 0 6px 18px rgba(0, 0, 0, 0.60); /* = shadow-color-stronger */
308
+ --u-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.25), 0 1px 1px rgba(0, 0, 0, 0.14); /* = shadow-color-weak */
309
+ --u-shadow-md: 0 2px 8px rgba(0, 0, 0, 0.35), 0 1px 2px rgba(0, 0, 0, 0.18); /* = shadow-color-normal */
310
+ --u-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.45), 0 2px 4px rgba(0, 0, 0, 0.22); /* = shadow-color-strong */
311
+ --u-shadow-xl: 0 6px 18px rgba(0, 0, 0, 0.60), 0 2px 6px rgba(0, 0, 0, 0.30); /* = shadow-color-stronger */
312
+
313
+
314
+ /* ==========================================================================
315
+ Type Scale — 글자 크기·굵기·행간·자간의 **한 벌**
316
+ ★**크기만 주면 스케일이 되지 않는다.** 소비자가 크기만 받고 굵기·행간을 각자 정하면
317
+ 결국 화면마다 다른 위계가 생긴다 — 그래서 네 값을 **단 단위로 묶어** 낸다.
318
+
319
+ 단 이름은 크기가 아니라 **역할**이다(`lg`/`xl` 이 아니라 `title`/`label`). 역할로 두면
320
+ 소비자가 *"어느 크기를 쓸까"* 가 아니라 *"이 글자는 무엇인가"* 를 묻게 된다.
321
+
322
+ ★**한글 기준으로 값을 골랐다**:
323
+ ⑴ 행간은 **1.4 이상**. 라틴 관례(1.2)는 한글에서 답답하다 — 받침 때문에 글자 상자가
324
+ 세로로 꽉 차 있어 라틴과 같은 행간이면 줄이 붙어 보인다.
325
+ ⑵ 자간은 **0 이 기본**이고 큰 제목만 **음수**. 한글에 양수 자간(letter-spacing)을 주면
326
+ 가독성이 떨어진다 — 라틴 소문자 조판 관례를 그대로 옮기면 안 되는 자리다.
327
+ ⑶ `overline` 에만 양수 자간을 둔다. 그 단은 **영문·숫자 라벨**을 전제한 자리이고,
328
+ 한글을 넣을 소비자는 자간을 0 으로 덮어야 한다(문서에 명시).
329
+
330
+ ⚠**`text-transform` 은 토큰으로 내지 않는다.** 한글에는 대문자가 없어 `uppercase` 가
331
+ 아무 효과가 없고, 영문이 섞이면 그것만 커져 오히려 어수선해진다.
332
+ ========================================================================== */
333
+ --u-text-display-size: 26px;
334
+ --u-text-display-weight: 700;
335
+ --u-text-display-leading: 1.4;
336
+ --u-text-display-tracking: -0.02em;
337
+
338
+ --u-text-title-size: 20px;
339
+ --u-text-title-weight: 700;
340
+ --u-text-title-leading: 1.45;
341
+ --u-text-title-tracking: -0.01em;
342
+
343
+ --u-text-subtitle-size: 16px;
344
+ --u-text-subtitle-weight: 600;
345
+ --u-text-subtitle-leading: 1.5;
346
+ --u-text-subtitle-tracking: 0;
347
+
348
+ --u-text-body-size: 14px;
349
+ --u-text-body-weight: 400;
350
+ --u-text-body-leading: 1.6;
351
+ --u-text-body-tracking: 0;
352
+
353
+ --u-text-label-size: 13px;
354
+ --u-text-label-weight: 600;
355
+ --u-text-label-leading: 1.5;
356
+ --u-text-label-tracking: 0;
357
+
358
+ --u-text-caption-size: 12px;
359
+ --u-text-caption-weight: 400;
360
+ --u-text-caption-leading: 1.5;
361
+ --u-text-caption-tracking: 0;
362
+
363
+ --u-text-overline-size: 11px;
364
+ --u-text-overline-weight: 700;
365
+ --u-text-overline-leading: 1.45;
366
+ --u-text-overline-tracking: 0.06em;
367
+
368
+ /* ==========================================================================
369
+ Motion — 지속시간·이징
370
+ ★값이 없으면 앱마다 다른 속도가 생기고, `prefers-reduced-motion` 은 **반드시**
371
+ 빠뜨리는 앱이 나온다. 축을 여기 두고 존중 규칙은 아래 미디어 쿼리가 진다.
372
+ ========================================================================== */
373
+ --u-duration-instant: 80ms;
374
+ --u-duration-fast: 140ms;
375
+ --u-duration-normal: 220ms;
376
+ --u-duration-slow: 320ms;
377
+ --u-ease-standard: cubic-bezier(0.2, 0, 0, 1);
378
+ --u-ease-decelerate: cubic-bezier(0, 0, 0, 1);
379
+ --u-ease-accelerate: cubic-bezier(0.3, 0, 1, 1);
297
380
 
298
381
  /* Scrollbar Colors */
299
382
  --u-scrollbar-color: var(--u-neutral-500);
300
383
  --u-scrollbar-color-hover: var(--u-neutral-600);
301
384
  --u-scrollbar-track-color: transparent;
302
385
 
303
- /* Font Styles */
304
- --u-font-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
386
+ /* ==========================================================================
387
+ Font Styles
388
+ ★**CJK 폴백을 스택에 포함한다 — 국제화이지 취향이 아니다.**
389
+ 종전 스택(`-apple-system, Segoe UI, Noto Sans, Helvetica, Arial`)에는 **한중일 글립을
390
+ 가진 폰트가 하나도 없었다.** Windows 에서 한글은 `Segoe UI` 에 없으므로 UA 가 임의로
391
+ 맑은 고딕을 고르고, macOS 는 `-apple-system` 이 Apple SD Gothic Neo 를 준다 ⇒ **같은 앱이
392
+ OS 마다 다른 글꼴로 렌더**됐다. 폴백을 명시하면 그 선택이 결정적이 된다.
393
+ ⚠**웹폰트를 로드하지 않는다.** 라이브러리가 네트워크 요청을 만들면 소비자의 CSP·
394
+ 오프라인 환경을 깬다. 스택 맨 앞의 `Pretendard` 는 **소비자가 로드했을 때만** 잡히는
395
+ 선택적 이름이다(없으면 조용히 다음으로 넘어간다).
396
+ ========================================================================== */
397
+ --u-font-base: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans KR', 'Hiragino Sans', 'Yu Gothic UI', 'Microsoft YaHei', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
305
398
  --u-font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Monaco, 'Courier New', monospace;
306
399
  --u-font-serif: 'Georgia', 'Times New Roman', Times, serif;
307
400
  --u-font-display: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
@@ -198,6 +198,11 @@
198
198
  --u-radius-md: 4px;
199
199
  --u-radius-lg: 6px;
200
200
  --u-radius-xl: 8px;
201
+ /* ★상단 2단은 **면(surface)용**이다 — 카드·패널·대화상자처럼 큰 사각형은 컨트롤과
202
+ 같은 반경을 쓰면 각져 보인다. 기존 5단은 **컨트롤용**이고 값을 바꾸지 않는다
203
+ (바꾸면 모든 소비자의 버튼·입력이 동시에 움직인다). */
204
+ --u-radius-2xl: 12px;
205
+ --u-radius-3xl: 16px;
201
206
  --u-radius-pill: 9999px;
202
207
  --u-radius-circle: 50%;
203
208
 
@@ -215,6 +220,16 @@
215
220
  --u-space-sm: 8px;
216
221
  --u-space-md: 12px;
217
222
  --u-space-lg: 16px;
223
+ /* ★상단 4단은 **화면 리듬**이다 — 카드 안쪽 여백(20~24)·섹션 간격(24~32)·페이지 여백
224
+ (32~40). 종전에는 이 구간이 통째로 비어 있어 소비자가 전부 리터럴로 적었고,
225
+ 그래서 앱마다 화면 밀도가 달라졌다. `lg`(16px) 이하는 **요소 사이**, `xl` 이상은
226
+ **영역 사이**로 나눠 쓴다.
227
+ ⚠`xs: 6px` 는 4px 격자에서 벗어나 있으나 **바꾸지 않는다** — 이미 배선된 컨트롤
228
+ 여백이 전부 움직인다. 신규 단은 전부 4의 배수로 둔다. */
229
+ --u-space-xl: 20px;
230
+ --u-space-2xl: 24px;
231
+ --u-space-3xl: 32px;
232
+ --u-space-4xl: 40px;
218
233
 
219
234
  /* Text Colors */
220
235
  --u-txt-color: var(--u-neutral-900);
@@ -331,21 +346,116 @@
331
346
  없을 때 그 폴백도 함께 무효가 되어 그림자가 통째로 사라진다.
332
347
  두 축의 알파가 어긋나지 않는지는 `tests/build/elevation-scale.test.ts` 가 지킨다.
333
348
  ========================================================================== */
334
- --u-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08); /* = shadow-color-weak — 표면에 얹힌 작은 컨트롤(탭·손잡이) */
335
- --u-shadow-md: 0 2px 8px rgba(0, 0, 0, 0.12); /* = shadow-color-normal — 카드·표면 */
336
- --u-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.16); /* = shadow-color-strong — 떠 있는 레이어(드롭다운·알림) */
337
- --u-shadow-xl: 0 6px 18px rgba(0, 0, 0, 0.24); /* = shadow-color-stronger — 모달·최상위(대화상자·툴팁) */
349
+ --u-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 1px rgba(0, 0, 0, 0.04); /* = shadow-color-weak — 표면에 얹힌 작은 컨트롤(탭·손잡이) */
350
+ --u-shadow-md: 0 2px 8px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.05); /* = shadow-color-normal — 카드·표면 */
351
+ --u-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.16), 0 2px 4px rgba(0, 0, 0, 0.06); /* = shadow-color-strong — 떠 있는 레이어(드롭다운·알림) */
352
+ --u-shadow-xl: 0 6px 18px rgba(0, 0, 0, 0.24), 0 2px 6px rgba(0, 0, 0, 0.08); /* = shadow-color-stronger — 모달·최상위(대화상자·툴팁) */
353
+
354
+
355
+ /* ==========================================================================
356
+ Type Scale — 글자 크기·굵기·행간·자간의 **한 벌**
357
+ ★**크기만 주면 스케일이 되지 않는다.** 소비자가 크기만 받고 굵기·행간을 각자 정하면
358
+ 결국 화면마다 다른 위계가 생긴다 — 그래서 네 값을 **단 단위로 묶어** 낸다.
359
+
360
+ 단 이름은 크기가 아니라 **역할**이다(`lg`/`xl` 이 아니라 `title`/`label`). 역할로 두면
361
+ 소비자가 *"어느 크기를 쓸까"* 가 아니라 *"이 글자는 무엇인가"* 를 묻게 된다.
362
+
363
+ ★**한글 기준으로 값을 골랐다**:
364
+ ⑴ 행간은 **1.4 이상**. 라틴 관례(1.2)는 한글에서 답답하다 — 받침 때문에 글자 상자가
365
+ 세로로 꽉 차 있어 라틴과 같은 행간이면 줄이 붙어 보인다.
366
+ ⑵ 자간은 **0 이 기본**이고 큰 제목만 **음수**. 한글에 양수 자간(letter-spacing)을 주면
367
+ 가독성이 떨어진다 — 라틴 소문자 조판 관례를 그대로 옮기면 안 되는 자리다.
368
+ ⑶ `overline` 에만 양수 자간을 둔다. 그 단은 **영문·숫자 라벨**을 전제한 자리이고,
369
+ 한글을 넣을 소비자는 자간을 0 으로 덮어야 한다(문서에 명시).
370
+
371
+ ⚠**`text-transform` 은 토큰으로 내지 않는다.** 한글에는 대문자가 없어 `uppercase` 가
372
+ 아무 효과가 없고, 영문이 섞이면 그것만 커져 오히려 어수선해진다.
373
+ ========================================================================== */
374
+ --u-text-display-size: 26px;
375
+ --u-text-display-weight: 700;
376
+ --u-text-display-leading: 1.4;
377
+ --u-text-display-tracking: -0.02em;
378
+
379
+ --u-text-title-size: 20px;
380
+ --u-text-title-weight: 700;
381
+ --u-text-title-leading: 1.45;
382
+ --u-text-title-tracking: -0.01em;
383
+
384
+ --u-text-subtitle-size: 16px;
385
+ --u-text-subtitle-weight: 600;
386
+ --u-text-subtitle-leading: 1.5;
387
+ --u-text-subtitle-tracking: 0;
388
+
389
+ --u-text-body-size: 14px;
390
+ --u-text-body-weight: 400;
391
+ --u-text-body-leading: 1.6;
392
+ --u-text-body-tracking: 0;
393
+
394
+ --u-text-label-size: 13px;
395
+ --u-text-label-weight: 600;
396
+ --u-text-label-leading: 1.5;
397
+ --u-text-label-tracking: 0;
398
+
399
+ --u-text-caption-size: 12px;
400
+ --u-text-caption-weight: 400;
401
+ --u-text-caption-leading: 1.5;
402
+ --u-text-caption-tracking: 0;
403
+
404
+ --u-text-overline-size: 11px;
405
+ --u-text-overline-weight: 700;
406
+ --u-text-overline-leading: 1.45;
407
+ --u-text-overline-tracking: 0.06em;
408
+
409
+ /* ==========================================================================
410
+ Motion — 지속시간·이징
411
+ ★값이 없으면 앱마다 다른 속도가 생기고, `prefers-reduced-motion` 은 **반드시**
412
+ 빠뜨리는 앱이 나온다. 축을 여기 두고 존중 규칙은 아래 미디어 쿼리가 진다.
413
+ ========================================================================== */
414
+ --u-duration-instant: 80ms;
415
+ --u-duration-fast: 140ms;
416
+ --u-duration-normal: 220ms;
417
+ --u-duration-slow: 320ms;
418
+ --u-ease-standard: cubic-bezier(0.2, 0, 0, 1);
419
+ --u-ease-decelerate: cubic-bezier(0, 0, 0, 1);
420
+ --u-ease-accelerate: cubic-bezier(0.3, 0, 1, 1);
338
421
 
339
422
  /* Scrollbar Colors */
340
423
  --u-scrollbar-color: var(--u-neutral-400);
341
424
  --u-scrollbar-color-hover: var(--u-neutral-500);
342
425
  --u-scrollbar-track-color: transparent;
343
426
 
344
- /* Font Styles */
345
- --u-font-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
427
+ /* ==========================================================================
428
+ Font Styles
429
+ ★**CJK 폴백을 스택에 포함한다 — 국제화이지 취향이 아니다.**
430
+ 종전 스택(`-apple-system, Segoe UI, Noto Sans, Helvetica, Arial`)에는 **한중일 글립을
431
+ 가진 폰트가 하나도 없었다.** Windows 에서 한글은 `Segoe UI` 에 없으므로 UA 가 임의로
432
+ 맑은 고딕을 고르고, macOS 는 `-apple-system` 이 Apple SD Gothic Neo 를 준다 ⇒ **같은 앱이
433
+ OS 마다 다른 글꼴로 렌더**됐다. 폴백을 명시하면 그 선택이 결정적이 된다.
434
+ ⚠**웹폰트를 로드하지 않는다.** 라이브러리가 네트워크 요청을 만들면 소비자의 CSP·
435
+ 오프라인 환경을 깬다. 스택 맨 앞의 `Pretendard` 는 **소비자가 로드했을 때만** 잡히는
436
+ 선택적 이름이다(없으면 조용히 다음으로 넘어간다).
437
+ ========================================================================== */
438
+ --u-font-base: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans KR', 'Hiragino Sans', 'Yu Gothic UI', 'Microsoft YaHei', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
346
439
  --u-font-mono: ui-monospace, 'Cascadia Code', 'Source Code Pro', Menlo, Monaco, 'Courier New', monospace;
347
440
  --u-font-serif: 'Georgia', 'Times New Roman', Times, serif;
348
441
  --u-font-display: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans', Helvetica, Arial, sans-serif;
349
442
  --u-font-modern: 'Inter', 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
350
443
  --u-font-rounded: 'Nunito', 'Quicksand', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
351
- }
444
+ }
445
+
446
+ /* ==========================================================================
447
+ ★`prefers-reduced-motion` 존중 — **라이브러리가 진다.**
448
+ 소비자마다 각자 처리하게 두면 반드시 빠뜨리는 앱이 나온다(그리고 그 앱은
449
+ 접근성 감사 전까지 아무도 모른다). 지속시간 축을 0 으로 눌러 두면 이 축을
450
+ 경유하는 모든 애니메이션이 함께 멈춘다.
451
+ ⚠`animation: none` 으로 강제하지 않는다 — 로딩 스피너처럼 **의미를 나르는**
452
+ 움직임까지 죽이면 사용자가 진행 중인지 알 수 없게 된다.
453
+ ========================================================================== */
454
+ @media (prefers-reduced-motion: reduce) {
455
+ :root {
456
+ --u-duration-instant: 0ms;
457
+ --u-duration-fast: 0ms;
458
+ --u-duration-normal: 0ms;
459
+ --u-duration-slow: 0ms;
460
+ }
461
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@iyulab/components",
3
3
  "description": "web-components library based on lit-element made by iyulab",
4
- "version": "1.20.0",
4
+ "version": "1.21.0",
5
5
  "keywords": [
6
6
  "iyulab",
7
7
  "components",