gyeol 0.1.3 → 0.1.4
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.
- package/README.md +128 -128
- package/gyeol.css +151 -151
- package/index.mjs +21 -21
- package/package.json +1 -1
- package/tokens.json +21 -21
package/README.md
CHANGED
|
@@ -1,128 +1,128 @@
|
|
|
1
|
-
# 결 gyeol
|
|
2
|
-
|
|
3
|
-
한지를 겹겹이 올리듯 화면을 쌓는 디자인 시스템이에요. 다른 프로젝트나 도구에서 쓸 수 있게 세 가지 형식으로 나눠 두었어요.
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
npm install gyeol
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
소개 사이트: https://minjaek111.github.io/gyeol/
|
|
10
|
-
|
|
11
|
-
| 파일 | 쓰는 곳 |
|
|
12
|
-
| --- | --- |
|
|
13
|
-
| `gyeol.css` | 아무 웹 프로젝트(HTML, React, Vue, Svelte 등). 토큰, 팔레트, 테마, 겹 소재, 컴포넌트 클래스가 모두 들어 있어요. |
|
|
14
|
-
| `tailwind.preset.cjs` | Tailwind CSS 프로젝트. `gyeol.css`의 CSS 변수를 Tailwind 클래스로 연결해요. |
|
|
15
|
-
| `tokens.json` | 디자인 토큰 표준(DTCG) 형식. Figma Tokens Studio, Style Dictionary, iOS·Android 변환에 써요. |
|
|
16
|
-
|
|
17
|
-
## 1. 웹 (CSS)
|
|
18
|
-
|
|
19
|
-
```html
|
|
20
|
-
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Hahmlet:wght@300;500;700;800&family=IBM+Plex+Sans+KR:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap">
|
|
21
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gyeol@0.1.
|
|
22
|
-
<!-- 또는 unpkg: <link rel="stylesheet" href="https://unpkg.com/gyeol@0.1.
|
|
23
|
-
|
|
24
|
-
<html data-palette="meok" data-theme="dark">
|
|
25
|
-
<body class="gy">
|
|
26
|
-
<div class="gy-gyeop gy-du">
|
|
27
|
-
<button class="gy-btn">저장하기</button>
|
|
28
|
-
<button class="gy-btn gy-btn--paper">취소</button>
|
|
29
|
-
</div>
|
|
30
|
-
</body>
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
CDN은 jsDelivr와 unpkg 중 하나를 쓰면 돼요. 버전을 빼고 `gyeol/gyeol.css`로 쓰면 항상 최신 버전을 불러오지만, 실제 서비스에서는 버전을 고정하는 게 안전해요.
|
|
34
|
-
|
|
35
|
-
| CDN | 주소 |
|
|
36
|
-
| --- | --- |
|
|
37
|
-
| jsDelivr | `https://cdn.jsdelivr.net/npm/gyeol@0.1.
|
|
38
|
-
| unpkg | `https://unpkg.com/gyeol@0.1.
|
|
39
|
-
|
|
40
|
-
번들러(Vite, Next.js 등)를 쓰면 CSS를 이렇게 불러와요.
|
|
41
|
-
|
|
42
|
-
```js
|
|
43
|
-
import 'gyeol/gyeol.css';
|
|
44
|
-
import { setPalette, setTheme, color, tokens } from 'gyeol';
|
|
45
|
-
|
|
46
|
-
setPalette('cheongja');
|
|
47
|
-
setTheme('light');
|
|
48
|
-
color('meok', 'dark', 'accent'); // '#85aeff'
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
- `data-palette`: `meok`(기본) · `jjok` · `cheongja` · `songhwa` · `yeonji` · `jaju` · `chija` · `hwangto` · `oksaek` · `haneul` · `odi`
|
|
52
|
-
|
|
53
|
-
| 팔레트 | 키 | 팔레트 | 키 |
|
|
54
|
-
| --- | --- | --- | --- |
|
|
55
|
-
| 먹 | `meok` | 치자 | `chija` |
|
|
56
|
-
| 쪽빛 | `jjok` | 황토 | `hwangto` |
|
|
57
|
-
| 청자 | `cheongja` | 옥색 | `oksaek` |
|
|
58
|
-
| 송화 | `songhwa` | 하늘 | `haneul` |
|
|
59
|
-
| 연지 | `yeonji` | 오디 | `odi` |
|
|
60
|
-
| 자주 | `jaju` | | |
|
|
61
|
-
- `data-theme`: `dark`(기본) · `light` · `system`
|
|
62
|
-
- 컴포넌트 클래스는 모두 `gy-` 접두사를 써서 기존 CSS와 겹치지 않아요.
|
|
63
|
-
- 화면 일부만 다른 팔레트나 테마로 바꿀 수 있어요(0.1.2부터). 그 범위 안의 색과 글자색이 모두 다시 계산돼요.
|
|
64
|
-
|
|
65
|
-
```html
|
|
66
|
-
<html data-palette="meok" data-theme="dark">
|
|
67
|
-
<section data-palette="yeonji" data-theme="light">이 영역만 연지 · 라이트</section>
|
|
68
|
-
<section data-palette="cheongja">테마를 빼면 바깥 테마(다크)를 따라가요</section>
|
|
69
|
-
</html>
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
```js
|
|
73
|
-
setPalette('jaju', document.querySelector('#promo')); // 특정 요소에만 적용
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
| 컴포넌트 | 클래스 |
|
|
77
|
-
| --- | --- |
|
|
78
|
-
| 겹 소재 | `gy-gyeop` + `gy-hol` / `gy-du` / `gy-se` |
|
|
79
|
-
| 버튼 | `gy-btn` + `--ink` / `--paper` / `--ghost` / `--danger` / `--sm` |
|
|
80
|
-
| 스위치 | `<button class="gy-switch" role="switch" aria-checked="true">` |
|
|
81
|
-
| 세그먼트 | `gy-seg` 안에 `aria-pressed` 버튼 |
|
|
82
|
-
| 칩 | `gy-chip` + `aria-pressed` |
|
|
83
|
-
| 입력 필드 | `gy-field` (오류는 `gy-field--error`) |
|
|
84
|
-
| 체크박스 | `<label class="gy-check"><input type="checkbox"> 텍스트</label>` |
|
|
85
|
-
| 배지 | `gy-badge` + `--ok` / `--warn` / `--err` |
|
|
86
|
-
| 진행 막대 | `<div class="gy-progress" style="--p:60%"><i></i></div>` |
|
|
87
|
-
| 토스트·툴팁 | `gy-toast`(겹과 함께), `gy-tooltip` |
|
|
88
|
-
|
|
89
|
-
## 2. Tailwind
|
|
90
|
-
|
|
91
|
-
```js
|
|
92
|
-
// tailwind.config.js
|
|
93
|
-
module.exports = {
|
|
94
|
-
presets: [require('gyeol/tailwind')],
|
|
95
|
-
};
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
`gyeol.css`를 함께 불러와야 색이 정의돼요. 그다음 `bg-paper`, `text-ink-2`, `bg-accent`, `p-pun-4`, `rounded-r-3`, `font-display`, `gyeop gyeop-du`처럼 써요.
|
|
99
|
-
|
|
100
|
-
## 3. 디자인 토큰 JSON (Figma, iOS, Android)
|
|
101
|
-
|
|
102
|
-
`tokens.json`은 [DTCG](https://tr.designtokens.org/format/) 형식이고, 색은 팔레트·테마별로 계산된 HEX 값이에요.
|
|
103
|
-
|
|
104
|
-
```
|
|
105
|
-
gyeol.color.<팔레트>.<light|dark>.<역할> 예) gyeol.color.meok.dark.accent = #85aeff
|
|
106
|
-
gyeol.space.pun-4 = 16px
|
|
107
|
-
gyeol.radius.r-3 = 20px
|
|
108
|
-
gyeol.material.du.thickness = 0.72
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
- **JS에서 바로**: `import tokens from 'gyeol'` 또는 `import tokens from 'gyeol/tokens.json'`
|
|
112
|
-
- **Figma**: Tokens Studio 플러그인에서 `tokens.json`을 불러오세요.
|
|
113
|
-
- **iOS / Android**: Style Dictionary로 `tokens.json`을 Swift, Kotlin, XML 리소스로 변환하세요.
|
|
114
|
-
|
|
115
|
-
HEX 값은 화면용 sRGB로 변환한 근사치예요. 웹에서는 `gyeol.css`의 oklch 원본을 쓰는 게 더 정확해요.
|
|
116
|
-
|
|
117
|
-
## 패키지 경로
|
|
118
|
-
|
|
119
|
-
| 경로 | 내용 |
|
|
120
|
-
| --- | --- |
|
|
121
|
-
| `gyeol` | 토큰 객체와 `setPalette`, `setTheme`, `color` 함수 (ESM·CommonJS·TypeScript 타입 포함) |
|
|
122
|
-
| `gyeol/gyeol.css` (또는 `gyeol/css`) | 전체 CSS |
|
|
123
|
-
| `gyeol/tailwind` | Tailwind 프리셋 |
|
|
124
|
-
| `gyeol/tokens.json` | DTCG 토큰 원본 |
|
|
125
|
-
|
|
126
|
-
## 라이선스
|
|
127
|
-
|
|
128
|
-
MIT
|
|
1
|
+
# 결 gyeol
|
|
2
|
+
|
|
3
|
+
한지를 겹겹이 올리듯 화면을 쌓는 디자인 시스템이에요. 다른 프로젝트나 도구에서 쓸 수 있게 세 가지 형식으로 나눠 두었어요.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install gyeol
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
소개 사이트: https://minjaek111.github.io/gyeol/
|
|
10
|
+
|
|
11
|
+
| 파일 | 쓰는 곳 |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| `gyeol.css` | 아무 웹 프로젝트(HTML, React, Vue, Svelte 등). 토큰, 팔레트, 테마, 겹 소재, 컴포넌트 클래스가 모두 들어 있어요. |
|
|
14
|
+
| `tailwind.preset.cjs` | Tailwind CSS 프로젝트. `gyeol.css`의 CSS 변수를 Tailwind 클래스로 연결해요. |
|
|
15
|
+
| `tokens.json` | 디자인 토큰 표준(DTCG) 형식. Figma Tokens Studio, Style Dictionary, iOS·Android 변환에 써요. |
|
|
16
|
+
|
|
17
|
+
## 1. 웹 (CSS)
|
|
18
|
+
|
|
19
|
+
```html
|
|
20
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Hahmlet:wght@300;500;700;800&family=IBM+Plex+Sans+KR:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap">
|
|
21
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gyeol@0.1.3/gyeol.css">
|
|
22
|
+
<!-- 또는 unpkg: <link rel="stylesheet" href="https://unpkg.com/gyeol@0.1.3/gyeol.css"> -->
|
|
23
|
+
|
|
24
|
+
<html data-palette="meok" data-theme="dark">
|
|
25
|
+
<body class="gy">
|
|
26
|
+
<div class="gy-gyeop gy-du">
|
|
27
|
+
<button class="gy-btn">저장하기</button>
|
|
28
|
+
<button class="gy-btn gy-btn--paper">취소</button>
|
|
29
|
+
</div>
|
|
30
|
+
</body>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
CDN은 jsDelivr와 unpkg 중 하나를 쓰면 돼요. 버전을 빼고 `gyeol/gyeol.css`로 쓰면 항상 최신 버전을 불러오지만, 실제 서비스에서는 버전을 고정하는 게 안전해요.
|
|
34
|
+
|
|
35
|
+
| CDN | 주소 |
|
|
36
|
+
| --- | --- |
|
|
37
|
+
| jsDelivr | `https://cdn.jsdelivr.net/npm/gyeol@0.1.3/gyeol.css` |
|
|
38
|
+
| unpkg | `https://unpkg.com/gyeol@0.1.3/gyeol.css` |
|
|
39
|
+
|
|
40
|
+
번들러(Vite, Next.js 등)를 쓰면 CSS를 이렇게 불러와요.
|
|
41
|
+
|
|
42
|
+
```js
|
|
43
|
+
import 'gyeol/gyeol.css';
|
|
44
|
+
import { setPalette, setTheme, color, tokens } from 'gyeol';
|
|
45
|
+
|
|
46
|
+
setPalette('cheongja');
|
|
47
|
+
setTheme('light');
|
|
48
|
+
color('meok', 'dark', 'accent'); // '#85aeff'
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
- `data-palette`: `meok`(기본) · `jjok` · `cheongja` · `songhwa` · `yeonji` · `jaju` · `chija` · `hwangto` · `oksaek` · `haneul` · `odi`
|
|
52
|
+
|
|
53
|
+
| 팔레트 | 키 | 팔레트 | 키 |
|
|
54
|
+
| --- | --- | --- | --- |
|
|
55
|
+
| 먹 | `meok` | 치자 | `chija` |
|
|
56
|
+
| 쪽빛 | `jjok` | 황토 | `hwangto` |
|
|
57
|
+
| 청자 | `cheongja` | 옥색 | `oksaek` |
|
|
58
|
+
| 송화 | `songhwa` | 하늘 | `haneul` |
|
|
59
|
+
| 연지 | `yeonji` | 오디 | `odi` |
|
|
60
|
+
| 자주 | `jaju` | | |
|
|
61
|
+
- `data-theme`: `dark`(기본) · `light` · `system`
|
|
62
|
+
- 컴포넌트 클래스는 모두 `gy-` 접두사를 써서 기존 CSS와 겹치지 않아요.
|
|
63
|
+
- 화면 일부만 다른 팔레트나 테마로 바꿀 수 있어요(0.1.2부터). 그 범위 안의 색과 글자색이 모두 다시 계산돼요.
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<html data-palette="meok" data-theme="dark">
|
|
67
|
+
<section data-palette="yeonji" data-theme="light">이 영역만 연지 · 라이트</section>
|
|
68
|
+
<section data-palette="cheongja">테마를 빼면 바깥 테마(다크)를 따라가요</section>
|
|
69
|
+
</html>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
setPalette('jaju', document.querySelector('#promo')); // 특정 요소에만 적용
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
| 컴포넌트 | 클래스 |
|
|
77
|
+
| --- | --- |
|
|
78
|
+
| 겹 소재 | `gy-gyeop` + `gy-hol` / `gy-du` / `gy-se` |
|
|
79
|
+
| 버튼 | `gy-btn` + `--ink` / `--paper` / `--ghost` / `--danger` / `--sm` |
|
|
80
|
+
| 스위치 | `<button class="gy-switch" role="switch" aria-checked="true">` |
|
|
81
|
+
| 세그먼트 | `gy-seg` 안에 `aria-pressed` 버튼 |
|
|
82
|
+
| 칩 | `gy-chip` + `aria-pressed` |
|
|
83
|
+
| 입력 필드 | `gy-field` (오류는 `gy-field--error`) |
|
|
84
|
+
| 체크박스 | `<label class="gy-check"><input type="checkbox"> 텍스트</label>` |
|
|
85
|
+
| 배지 | `gy-badge` + `--ok` / `--warn` / `--err` |
|
|
86
|
+
| 진행 막대 | `<div class="gy-progress" style="--p:60%"><i></i></div>` |
|
|
87
|
+
| 토스트·툴팁 | `gy-toast`(겹과 함께), `gy-tooltip` |
|
|
88
|
+
|
|
89
|
+
## 2. Tailwind
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
// tailwind.config.js
|
|
93
|
+
module.exports = {
|
|
94
|
+
presets: [require('gyeol/tailwind')],
|
|
95
|
+
};
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
`gyeol.css`를 함께 불러와야 색이 정의돼요. 그다음 `bg-paper`, `text-ink-2`, `bg-accent`, `p-pun-4`, `rounded-r-3`, `font-display`, `gyeop gyeop-du`처럼 써요.
|
|
99
|
+
|
|
100
|
+
## 3. 디자인 토큰 JSON (Figma, iOS, Android)
|
|
101
|
+
|
|
102
|
+
`tokens.json`은 [DTCG](https://tr.designtokens.org/format/) 형식이고, 색은 팔레트·테마별로 계산된 HEX 값이에요.
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
gyeol.color.<팔레트>.<light|dark>.<역할> 예) gyeol.color.meok.dark.accent = #85aeff
|
|
106
|
+
gyeol.space.pun-4 = 16px
|
|
107
|
+
gyeol.radius.r-3 = 20px
|
|
108
|
+
gyeol.material.du.thickness = 0.72
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- **JS에서 바로**: `import tokens from 'gyeol'` 또는 `import tokens from 'gyeol/tokens.json'`
|
|
112
|
+
- **Figma**: Tokens Studio 플러그인에서 `tokens.json`을 불러오세요.
|
|
113
|
+
- **iOS / Android**: Style Dictionary로 `tokens.json`을 Swift, Kotlin, XML 리소스로 변환하세요.
|
|
114
|
+
|
|
115
|
+
HEX 값은 화면용 sRGB로 변환한 근사치예요. 웹에서는 `gyeol.css`의 oklch 원본을 쓰는 게 더 정확해요.
|
|
116
|
+
|
|
117
|
+
## 패키지 경로
|
|
118
|
+
|
|
119
|
+
| 경로 | 내용 |
|
|
120
|
+
| --- | --- |
|
|
121
|
+
| `gyeol` | 토큰 객체와 `setPalette`, `setTheme`, `color` 함수 (ESM·CommonJS·TypeScript 타입 포함) |
|
|
122
|
+
| `gyeol/gyeol.css` (또는 `gyeol/css`) | 전체 CSS |
|
|
123
|
+
| `gyeol/tailwind` | Tailwind 프리셋 |
|
|
124
|
+
| `gyeol/tokens.json` | DTCG 토큰 원본 |
|
|
125
|
+
|
|
126
|
+
## 라이선스
|
|
127
|
+
|
|
128
|
+
MIT
|
package/gyeol.css
CHANGED
|
@@ -1,151 +1,151 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* 결 gyeol — layered-paper design system
|
|
3
|
-
* 사용법: <html data-palette="meok" data-theme="dark">
|
|
4
|
-
* data-palette: meok | jjok | cheongja | songhwa | yeonji | jaju |
|
|
5
|
-
* chija | hwangto | oksaek | haneul | odi (기본 meok)
|
|
6
|
-
* data-theme: dark | light | system (기본 dark)
|
|
7
|
-
* 화면 일부만 다른 팔레트·테마로: <section data-palette="yeonji" data-theme="light"> (0.1.2+)
|
|
8
|
-
* 모든 컴포넌트 클래스는 gy- 접두사를 써서 다른 CSS와 충돌하지 않아요.
|
|
9
|
-
* 글꼴: https://fonts.googleapis.com/css2?family=Hahmlet:wght@300;500;700;800&family=IBM+Plex+Sans+KR:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
/* ---------- tokens ---------- */
|
|
13
|
-
:root{
|
|
14
|
-
--h:255; --c:.012; --ah:265; --ac:.14; /* 기본 팔레트: 먹 + 쪽빛 강조 */
|
|
15
|
-
--f-display: "Hahmlet", "Nanum Myeongjo", "Apple SD Gothic Neo", serif;
|
|
16
|
-
--f-body: "IBM Plex Sans KR", "Apple SD Gothic Neo", "Malgun Gothic", system-ui, sans-serif;
|
|
17
|
-
--f-mono: "IBM Plex Mono", ui-monospace, "Consolas", monospace;
|
|
18
|
-
|
|
19
|
-
--pun-1:4px; --pun-2:8px; --pun-3:12px; --pun-4:16px; --pun-6:24px; --pun-8:32px; --pun-12:48px; --pun-16:64px;
|
|
20
|
-
--r-1:6px; --r-2:12px; --r-3:20px; --r-4:28px; --r-pill:999px;
|
|
21
|
-
--ease-bleed: cubic-bezier(.2,.7,.2,1);
|
|
22
|
-
--t-1:120ms; --t-2:220ms; --t-3:420ms;
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
/* 색 토큰: 루트와, 팔레트·테마를 따로 지정한 모든 요소에서 다시 계산돼요 */
|
|
26
|
-
:root, [data-palette], [data-theme]{
|
|
27
|
-
--bg: oklch(96.5% calc(var(--c)*.12) var(--h));
|
|
28
|
-
--bg-2: oklch(92.5% calc(var(--c)*.22) var(--h));
|
|
29
|
-
--ink: oklch(23% calc(var(--c)*.35) var(--h));
|
|
30
|
-
--ink-2: oklch(43% calc(var(--c)*.25) var(--h));
|
|
31
|
-
--ink-3: oklch(50% calc(var(--c)*.18) var(--h));
|
|
32
|
-
--line: oklch(84% calc(var(--c)*.22) var(--h));
|
|
33
|
-
--paper: oklch(99.2% calc(var(--c)*.05) var(--h));
|
|
34
|
-
--accent: oklch(49% var(--ac) var(--ah));
|
|
35
|
-
--accent-soft: oklch(90% calc(var(--ac)*.45) var(--ah));
|
|
36
|
-
--on-accent: oklch(99% 0 0);
|
|
37
|
-
--stain: oklch(80% calc(var(--c)*.9 + .03) calc(var(--h) + 70));
|
|
38
|
-
--ok: oklch(50% .13 150); --warn: oklch(54% .13 65); --err: oklch(52% .19 25);
|
|
39
|
-
--shadow: 0 1px 0 oklch(100% 0 0 / .7) inset, 0 18px 40px -22px oklch(25% .06 var(--h) / .35), 0 2px 6px -2px oklch(25% .04 var(--h) / .12);
|
|
40
|
-
--grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='a'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .32 0'/></filter><filter id='b'><feTurbulence type='fractalNoise' baseFrequency='.012 .32' numOctaves='2' seed='4' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .7 -.42'/></filter><rect width='100%' height='100%' filter='url(%23a)'/><rect width='100%' height='100%' filter='url(%23b)'/></svg>");
|
|
41
|
-
--grain-o: .4;
|
|
42
|
-
|
|
43
|
-
color-scheme: light;
|
|
44
|
-
}
|
|
45
|
-
@media (prefers-color-scheme: dark){ :root[data-theme="system"], :root[data-theme="system"] [data-palette]:not([data-theme]):not([data-theme="light"] *){
|
|
46
|
-
--bg: oklch(17% calc(var(--c)*.22) var(--h)); --bg-2: oklch(21% calc(var(--c)*.3) var(--h));
|
|
47
|
-
--ink: oklch(95% calc(var(--c)*.08) var(--h)); --ink-2: oklch(79% calc(var(--c)*.15) var(--h)); --ink-3: oklch(70% calc(var(--c)*.15) var(--h));
|
|
48
|
-
--line: oklch(33% calc(var(--c)*.25) var(--h)); --paper: oklch(29% calc(var(--c)*.25) var(--h));
|
|
49
|
-
--accent: oklch(76% var(--ac) var(--ah)); --accent-soft: oklch(33% calc(var(--ac)*.55) var(--ah)); --on-accent: oklch(18% .03 var(--ah));
|
|
50
|
-
--stain: oklch(48% calc(var(--c)*.9 + .03) calc(var(--h) + 70));
|
|
51
|
-
--ok: oklch(74% .14 150); --warn: oklch(80% .13 75); --err: oklch(72% .16 25);
|
|
52
|
-
--shadow: 0 1px 0 oklch(100% 0 0 / .07) inset, 0 20px 44px -20px oklch(5% .02 var(--h) / .7), 0 2px 6px -2px oklch(5% 0 0 / .4);
|
|
53
|
-
--grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='a'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .22 0'/></filter><filter id='b'><feTurbulence type='fractalNoise' baseFrequency='.012 .32' numOctaves='2' seed='4' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .6 -.4'/></filter><rect width='100%' height='100%' filter='url(%23a)'/><rect width='100%' height='100%' filter='url(%23b)'/></svg>");
|
|
54
|
-
--grain-o: .35; color-scheme: dark;
|
|
55
|
-
}}
|
|
56
|
-
:root:not([data-theme="light"]):not([data-theme="system"]), [data-theme="dark"],
|
|
57
|
-
:root:not([data-theme="light"]):not([data-theme="system"]) [data-palette]:not([data-theme]):not([data-theme="light"] *){
|
|
58
|
-
--bg: oklch(17% calc(var(--c)*.22) var(--h)); --bg-2: oklch(21% calc(var(--c)*.3) var(--h));
|
|
59
|
-
--ink: oklch(95% calc(var(--c)*.08) var(--h)); --ink-2: oklch(79% calc(var(--c)*.15) var(--h)); --ink-3: oklch(70% calc(var(--c)*.15) var(--h));
|
|
60
|
-
--line: oklch(33% calc(var(--c)*.25) var(--h)); --paper: oklch(29% calc(var(--c)*.25) var(--h));
|
|
61
|
-
--accent: oklch(76% var(--ac) var(--ah)); --accent-soft: oklch(33% calc(var(--ac)*.55) var(--ah)); --on-accent: oklch(18% .03 var(--ah));
|
|
62
|
-
--stain: oklch(48% calc(var(--c)*.9 + .03) calc(var(--h) + 70));
|
|
63
|
-
--ok: oklch(74% .14 150); --warn: oklch(80% .13 75); --err: oklch(72% .16 25);
|
|
64
|
-
--shadow: 0 1px 0 oklch(100% 0 0 / .07) inset, 0 20px 44px -20px oklch(5% .02 var(--h) / .7), 0 2px 6px -2px oklch(5% 0 0 / .4);
|
|
65
|
-
--grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='a'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .22 0'/></filter><filter id='b'><feTurbulence type='fractalNoise' baseFrequency='.012 .32' numOctaves='2' seed='4' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .6 -.4'/></filter><rect width='100%' height='100%' filter='url(%23a)'/><rect width='100%' height='100%' filter='url(%23b)'/></svg>");
|
|
66
|
-
--grain-o: .35; color-scheme: dark;
|
|
67
|
-
}
|
|
68
|
-
[data-palette="meok"] {--h:255;--c:.012;--ah:265;--ac:.14}
|
|
69
|
-
[data-palette="jjok"] {--h:265;--c:.14; --ah:265;--ac:.14}
|
|
70
|
-
[data-palette="cheongja"]{--h:178;--c:.075;--ah:178;--ac:.075}
|
|
71
|
-
[data-palette="songhwa"] {--h:98; --c:.12; --ah:98; --ac:.12}
|
|
72
|
-
[data-palette="yeonji"] {--h:16; --c:.16; --ah:16; --ac:.16}
|
|
73
|
-
[data-palette="jaju"] {--h:330;--c:.13; --ah:330;--ac:.13}
|
|
74
|
-
[data-palette="chija"] {--h:70;--c:0.14;--ah:70;--ac:0.14}
|
|
75
|
-
[data-palette="hwangto"] {--h:
|
|
76
|
-
[data-palette="oksaek"] {--h:195;--c:0.08;--ah:195;--ac:0.08}
|
|
77
|
-
[data-palette="haneul"] {--h:235;--c:0.11;--ah:235;--ac:0.11}
|
|
78
|
-
[data-palette="odi"] {--h:300;--c:0.12;--ah:300;--ac:0.12}
|
|
79
|
-
/* 화면 일부에 팔레트·테마를 따로 지정하면 글자색도 그 범위의 먹색을 따라가요 */
|
|
80
|
-
:where([data-palette], [data-theme]):not(:root){color:var(--ink)}
|
|
81
|
-
|
|
82
|
-
/* ---------- base (opt-in: add class="gy" to <body>) ---------- */
|
|
83
|
-
.gy{margin:0;color:var(--ink);background:var(--bg);font:400 16px/1.65 var(--f-body);-webkit-font-smoothing:antialiased}
|
|
84
|
-
.gy :focus-visible{outline:2px solid var(--accent);outline-offset:3px;box-shadow:0 0 0 7px color-mix(in oklch, var(--accent) 22%, transparent)}
|
|
85
|
-
|
|
86
|
-
/* ---------- material: 겹 ---------- */
|
|
87
|
-
.gy-gyeop{position:relative;isolation:isolate;background:color-mix(in oklch, var(--paper) var(--thick,74%), transparent);-webkit-backdrop-filter:blur(var(--blur,14px)) saturate(1.2);backdrop-filter:blur(var(--blur,14px)) saturate(1.2);border:1px solid color-mix(in oklch, var(--paper) 50%, var(--line));border-radius:var(--r-3);box-shadow:var(--shadow)}
|
|
88
|
-
.gy-gyeop::before{content:"";position:absolute;inset:0;border-radius:inherit;background-image:var(--grain);opacity:var(--grain-o);pointer-events:none;z-index:-1}
|
|
89
|
-
.gy-hol{--thick:46%;--blur:6px}
|
|
90
|
-
.gy-du {--thick:72%;--blur:14px}
|
|
91
|
-
.gy-se {--thick:90%;--blur:24px}
|
|
92
|
-
|
|
93
|
-
/* ---------- button ---------- */
|
|
94
|
-
.gy-btn{--bg-b:var(--accent);--fg-b:var(--on-accent);appearance:none;border:0;cursor:pointer;font:600 15px/1 var(--f-body);color:var(--fg-b);background:var(--bg-b);padding:13px 20px;border-radius:var(--r-2);display:inline-flex;align-items:center;gap:8px;text-decoration:none;transition:transform var(--t-1) var(--ease-bleed), box-shadow var(--t-3) var(--ease-bleed)}
|
|
95
|
-
.gy-btn:hover{box-shadow:0 0 0 1px var(--bg-b), 0 6px 22px -4px color-mix(in oklch, var(--bg-b) 60%, transparent)}
|
|
96
|
-
.gy-btn:active{transform:translateY(1px) scale(.985)}
|
|
97
|
-
.gy-btn--ink{--bg-b:var(--ink);--fg-b:var(--bg)}
|
|
98
|
-
.gy-btn--paper{--fg-b:var(--ink);background:color-mix(in oklch, var(--paper) 74%, transparent);border:1px solid var(--line);backdrop-filter:blur(12px)}
|
|
99
|
-
.gy-btn--paper:hover{box-shadow:0 6px 22px -8px color-mix(in oklch, var(--ink) 40%, transparent)}
|
|
100
|
-
.gy-btn--ghost{--fg-b:var(--accent);background:transparent}
|
|
101
|
-
.gy-btn--ghost:hover{background:color-mix(in oklch, var(--accent) 10%, transparent);box-shadow:none}
|
|
102
|
-
.gy-btn--danger{--bg-b:var(--err);--fg-b:oklch(99% 0 0)}
|
|
103
|
-
.gy-btn--sm{padding:9px 14px;font-size:14px;border-radius:10px}
|
|
104
|
-
.gy-btn:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}
|
|
105
|
-
|
|
106
|
-
/* ---------- switch: <button class="gy-switch" role="switch" aria-checked="true"> ---------- */
|
|
107
|
-
.gy-switch{appearance:none;border:0;cursor:pointer;width:50px;height:30px;border-radius:var(--r-pill);background:var(--line);position:relative;transition:background var(--t-2) var(--ease-bleed);flex:none}
|
|
108
|
-
.gy-switch::after{content:"";position:absolute;top:3px;left:3px;width:24px;height:24px;border-radius:50%;background:var(--paper);box-shadow:0 2px 6px oklch(0% 0 0 / .25);transition:transform var(--t-2) var(--ease-bleed)}
|
|
109
|
-
.gy-switch[aria-checked="true"]{background:var(--accent)}
|
|
110
|
-
.gy-switch[aria-checked="true"]::after{transform:translateX(20px);background:oklch(99% 0 0)}
|
|
111
|
-
|
|
112
|
-
/* ---------- segmented: buttons with aria-pressed ---------- */
|
|
113
|
-
.gy-seg{display:inline-flex;padding:4px;border-radius:var(--r-pill);background:color-mix(in oklch, var(--ink) 7%, transparent);gap:2px}
|
|
114
|
-
.gy-seg button{appearance:none;border:0;background:transparent;color:var(--ink-2);font:500 14px/1 var(--f-body);padding:8px 14px;border-radius:var(--r-pill);cursor:pointer}
|
|
115
|
-
.gy-seg button[aria-pressed="true"]{background:var(--paper);color:var(--ink);box-shadow:0 1px 3px oklch(0% 0 0 / .14)}
|
|
116
|
-
|
|
117
|
-
/* ---------- chip ---------- */
|
|
118
|
-
.gy-chip{appearance:none;cursor:pointer;border:1px solid var(--line);background:transparent;color:var(--ink-2);font:500 14px/1 var(--f-body);padding:8px 13px;border-radius:var(--r-pill)}
|
|
119
|
-
.gy-chip[aria-pressed="true"]{background:var(--accent-soft);border-color:transparent;color:var(--ink)}
|
|
120
|
-
|
|
121
|
-
/* ---------- field ---------- */
|
|
122
|
-
.gy-field{display:flex;flex-direction:column;gap:6px}
|
|
123
|
-
.gy-field label{font-size:13px;font-weight:500;color:var(--ink-2)}
|
|
124
|
-
.gy-field input,.gy-field textarea,.gy-field select{font:400 15px var(--f-body);color:var(--ink);background:color-mix(in oklch, var(--paper) 80%, transparent);border:1px solid var(--line);border-radius:var(--r-2);padding:11px 13px;transition:border-color var(--t-2), box-shadow var(--t-3) var(--ease-bleed)}
|
|
125
|
-
.gy-field :is(input,textarea,select):focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 5px color-mix(in oklch, var(--accent) 18%, transparent), 0 0 18px 2px color-mix(in oklch, var(--accent) 22%, transparent)}
|
|
126
|
-
.gy-field small{font-size:13px;color:var(--ink-3)}
|
|
127
|
-
.gy-field--error :is(input,textarea,select){border-color:var(--err)}
|
|
128
|
-
.gy-field--error small{color:var(--err)}
|
|
129
|
-
|
|
130
|
-
/* ---------- checkbox: <label class="gy-check"><input type="checkbox"> 텍스트</label> ---------- */
|
|
131
|
-
.gy-check{display:flex;gap:10px;align-items:center;font-size:15px;cursor:pointer}
|
|
132
|
-
.gy-check input{appearance:none;width:20px;height:20px;border-radius:6px;border:1.5px solid var(--ink-3);display:grid;place-items:center;margin:0;cursor:pointer}
|
|
133
|
-
.gy-check input:checked{background:var(--accent);border-color:var(--accent)}
|
|
134
|
-
.gy-check input:checked::after{content:"";width:9px;height:5px;border:2px solid var(--on-accent);border-top:0;border-right:0;transform:rotate(-45deg) translate(1px,-1px)}
|
|
135
|
-
|
|
136
|
-
/* ---------- badge ---------- */
|
|
137
|
-
.gy-badge{font:600 12px/1 var(--f-body);padding:7px 11px;border-radius:var(--r-pill);display:inline-flex;align-items:center;gap:5px;color:var(--accent);background:color-mix(in oklch, var(--accent) 13%, transparent)}
|
|
138
|
-
.gy-badge::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}
|
|
139
|
-
.gy-badge--ok{color:var(--ok);background:color-mix(in oklch, var(--ok) 14%, transparent)}
|
|
140
|
-
.gy-badge--warn{color:var(--warn);background:color-mix(in oklch, var(--warn) 16%, transparent)}
|
|
141
|
-
.gy-badge--err{color:var(--err);background:color-mix(in oklch, var(--err) 14%, transparent)}
|
|
142
|
-
|
|
143
|
-
/* ---------- progress: <div class="gy-progress" style="--p:60%"><i></i></div> ---------- */
|
|
144
|
-
.gy-progress{height:8px;border-radius:var(--r-pill);background:color-mix(in oklch, var(--ink) 9%, transparent);overflow:hidden}
|
|
145
|
-
.gy-progress > i{display:block;height:100%;width:var(--p,0%);border-radius:inherit;background:linear-gradient(90deg, color-mix(in oklch, var(--accent) 50%, transparent), var(--accent))}
|
|
146
|
-
|
|
147
|
-
/* ---------- toast / tooltip ---------- */
|
|
148
|
-
.gy-toast{display:flex;align-items:center;gap:12px;padding:12px 16px;font-size:14.5px}
|
|
149
|
-
.gy-tooltip{font-size:13px;padding:7px 11px;border-radius:10px;background:var(--ink);color:var(--bg)}
|
|
150
|
-
|
|
151
|
-
@media (prefers-reduced-motion: reduce){.gy *,.gy *::before,.gy *::after{transition:none!important;animation:none!important}}
|
|
1
|
+
/*!
|
|
2
|
+
* 결 gyeol — layered-paper design system
|
|
3
|
+
* 사용법: <html data-palette="meok" data-theme="dark">
|
|
4
|
+
* data-palette: meok | jjok | cheongja | songhwa | yeonji | jaju |
|
|
5
|
+
* chija | hwangto | oksaek | haneul | odi (기본 meok)
|
|
6
|
+
* data-theme: dark | light | system (기본 dark)
|
|
7
|
+
* 화면 일부만 다른 팔레트·테마로: <section data-palette="yeonji" data-theme="light"> (0.1.2+)
|
|
8
|
+
* 모든 컴포넌트 클래스는 gy- 접두사를 써서 다른 CSS와 충돌하지 않아요.
|
|
9
|
+
* 글꼴: https://fonts.googleapis.com/css2?family=Hahmlet:wght@300;500;700;800&family=IBM+Plex+Sans+KR:wght@400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/* ---------- tokens ---------- */
|
|
13
|
+
:root{
|
|
14
|
+
--h:255; --c:.012; --ah:265; --ac:.14; /* 기본 팔레트: 먹 + 쪽빛 강조 */
|
|
15
|
+
--f-display: "Hahmlet", "Nanum Myeongjo", "Apple SD Gothic Neo", serif;
|
|
16
|
+
--f-body: "IBM Plex Sans KR", "Apple SD Gothic Neo", "Malgun Gothic", system-ui, sans-serif;
|
|
17
|
+
--f-mono: "IBM Plex Mono", ui-monospace, "Consolas", monospace;
|
|
18
|
+
|
|
19
|
+
--pun-1:4px; --pun-2:8px; --pun-3:12px; --pun-4:16px; --pun-6:24px; --pun-8:32px; --pun-12:48px; --pun-16:64px;
|
|
20
|
+
--r-1:6px; --r-2:12px; --r-3:20px; --r-4:28px; --r-pill:999px;
|
|
21
|
+
--ease-bleed: cubic-bezier(.2,.7,.2,1);
|
|
22
|
+
--t-1:120ms; --t-2:220ms; --t-3:420ms;
|
|
23
|
+
|
|
24
|
+
}
|
|
25
|
+
/* 색 토큰: 루트와, 팔레트·테마를 따로 지정한 모든 요소에서 다시 계산돼요 */
|
|
26
|
+
:root, [data-palette], [data-theme]{
|
|
27
|
+
--bg: oklch(96.5% calc(var(--c)*.12) var(--h));
|
|
28
|
+
--bg-2: oklch(92.5% calc(var(--c)*.22) var(--h));
|
|
29
|
+
--ink: oklch(23% calc(var(--c)*.35) var(--h));
|
|
30
|
+
--ink-2: oklch(43% calc(var(--c)*.25) var(--h));
|
|
31
|
+
--ink-3: oklch(50% calc(var(--c)*.18) var(--h));
|
|
32
|
+
--line: oklch(84% calc(var(--c)*.22) var(--h));
|
|
33
|
+
--paper: oklch(99.2% calc(var(--c)*.05) var(--h));
|
|
34
|
+
--accent: oklch(49% var(--ac) var(--ah));
|
|
35
|
+
--accent-soft: oklch(90% calc(var(--ac)*.45) var(--ah));
|
|
36
|
+
--on-accent: oklch(99% 0 0);
|
|
37
|
+
--stain: oklch(80% calc(var(--c)*.9 + .03) calc(var(--h) + 70));
|
|
38
|
+
--ok: oklch(50% .13 150); --warn: oklch(54% .13 65); --err: oklch(52% .19 25);
|
|
39
|
+
--shadow: 0 1px 0 oklch(100% 0 0 / .7) inset, 0 18px 40px -22px oklch(25% .06 var(--h) / .35), 0 2px 6px -2px oklch(25% .04 var(--h) / .12);
|
|
40
|
+
--grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='a'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .32 0'/></filter><filter id='b'><feTurbulence type='fractalNoise' baseFrequency='.012 .32' numOctaves='2' seed='4' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .7 -.42'/></filter><rect width='100%' height='100%' filter='url(%23a)'/><rect width='100%' height='100%' filter='url(%23b)'/></svg>");
|
|
41
|
+
--grain-o: .4;
|
|
42
|
+
|
|
43
|
+
color-scheme: light;
|
|
44
|
+
}
|
|
45
|
+
@media (prefers-color-scheme: dark){ :root[data-theme="system"], :root[data-theme="system"] [data-palette]:not([data-theme]):not([data-theme="light"] *){
|
|
46
|
+
--bg: oklch(17% calc(var(--c)*.22) var(--h)); --bg-2: oklch(21% calc(var(--c)*.3) var(--h));
|
|
47
|
+
--ink: oklch(95% calc(var(--c)*.08) var(--h)); --ink-2: oklch(79% calc(var(--c)*.15) var(--h)); --ink-3: oklch(70% calc(var(--c)*.15) var(--h));
|
|
48
|
+
--line: oklch(33% calc(var(--c)*.25) var(--h)); --paper: oklch(29% calc(var(--c)*.25) var(--h));
|
|
49
|
+
--accent: oklch(76% var(--ac) var(--ah)); --accent-soft: oklch(33% calc(var(--ac)*.55) var(--ah)); --on-accent: oklch(18% .03 var(--ah));
|
|
50
|
+
--stain: oklch(48% calc(var(--c)*.9 + .03) calc(var(--h) + 70));
|
|
51
|
+
--ok: oklch(74% .14 150); --warn: oklch(80% .13 75); --err: oklch(72% .16 25);
|
|
52
|
+
--shadow: 0 1px 0 oklch(100% 0 0 / .07) inset, 0 20px 44px -20px oklch(5% .02 var(--h) / .7), 0 2px 6px -2px oklch(5% 0 0 / .4);
|
|
53
|
+
--grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='a'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .22 0'/></filter><filter id='b'><feTurbulence type='fractalNoise' baseFrequency='.012 .32' numOctaves='2' seed='4' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .6 -.4'/></filter><rect width='100%' height='100%' filter='url(%23a)'/><rect width='100%' height='100%' filter='url(%23b)'/></svg>");
|
|
54
|
+
--grain-o: .35; color-scheme: dark;
|
|
55
|
+
}}
|
|
56
|
+
:root:not([data-theme="light"]):not([data-theme="system"]), [data-theme="dark"],
|
|
57
|
+
:root:not([data-theme="light"]):not([data-theme="system"]) [data-palette]:not([data-theme]):not([data-theme="light"] *){
|
|
58
|
+
--bg: oklch(17% calc(var(--c)*.22) var(--h)); --bg-2: oklch(21% calc(var(--c)*.3) var(--h));
|
|
59
|
+
--ink: oklch(95% calc(var(--c)*.08) var(--h)); --ink-2: oklch(79% calc(var(--c)*.15) var(--h)); --ink-3: oklch(70% calc(var(--c)*.15) var(--h));
|
|
60
|
+
--line: oklch(33% calc(var(--c)*.25) var(--h)); --paper: oklch(29% calc(var(--c)*.25) var(--h));
|
|
61
|
+
--accent: oklch(76% var(--ac) var(--ah)); --accent-soft: oklch(33% calc(var(--ac)*.55) var(--ah)); --on-accent: oklch(18% .03 var(--ah));
|
|
62
|
+
--stain: oklch(48% calc(var(--c)*.9 + .03) calc(var(--h) + 70));
|
|
63
|
+
--ok: oklch(74% .14 150); --warn: oklch(80% .13 75); --err: oklch(72% .16 25);
|
|
64
|
+
--shadow: 0 1px 0 oklch(100% 0 0 / .07) inset, 0 20px 44px -20px oklch(5% .02 var(--h) / .7), 0 2px 6px -2px oklch(5% 0 0 / .4);
|
|
65
|
+
--grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='a'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .22 0'/></filter><filter id='b'><feTurbulence type='fractalNoise' baseFrequency='.012 .32' numOctaves='2' seed='4' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .6 -.4'/></filter><rect width='100%' height='100%' filter='url(%23a)'/><rect width='100%' height='100%' filter='url(%23b)'/></svg>");
|
|
66
|
+
--grain-o: .35; color-scheme: dark;
|
|
67
|
+
}
|
|
68
|
+
[data-palette="meok"] {--h:255;--c:.012;--ah:265;--ac:.14}
|
|
69
|
+
[data-palette="jjok"] {--h:265;--c:.14; --ah:265;--ac:.14}
|
|
70
|
+
[data-palette="cheongja"]{--h:178;--c:.075;--ah:178;--ac:.075}
|
|
71
|
+
[data-palette="songhwa"] {--h:98; --c:.12; --ah:98; --ac:.12}
|
|
72
|
+
[data-palette="yeonji"] {--h:16; --c:.16; --ah:16; --ac:.16}
|
|
73
|
+
[data-palette="jaju"] {--h:330;--c:.13; --ah:330;--ac:.13}
|
|
74
|
+
[data-palette="chija"] {--h:70;--c:0.14;--ah:70;--ac:0.14}
|
|
75
|
+
[data-palette="hwangto"] {--h:48;--c:.065;--ah:48;--ac:.065}
|
|
76
|
+
[data-palette="oksaek"] {--h:195;--c:0.08;--ah:195;--ac:0.08}
|
|
77
|
+
[data-palette="haneul"] {--h:235;--c:0.11;--ah:235;--ac:0.11}
|
|
78
|
+
[data-palette="odi"] {--h:300;--c:0.12;--ah:300;--ac:0.12}
|
|
79
|
+
/* 화면 일부에 팔레트·테마를 따로 지정하면 글자색도 그 범위의 먹색을 따라가요 */
|
|
80
|
+
:where([data-palette], [data-theme]):not(:root){color:var(--ink)}
|
|
81
|
+
|
|
82
|
+
/* ---------- base (opt-in: add class="gy" to <body>) ---------- */
|
|
83
|
+
.gy{margin:0;color:var(--ink);background:var(--bg);font:400 16px/1.65 var(--f-body);-webkit-font-smoothing:antialiased}
|
|
84
|
+
.gy :focus-visible{outline:2px solid var(--accent);outline-offset:3px;box-shadow:0 0 0 7px color-mix(in oklch, var(--accent) 22%, transparent)}
|
|
85
|
+
|
|
86
|
+
/* ---------- material: 겹 ---------- */
|
|
87
|
+
.gy-gyeop{position:relative;isolation:isolate;background:color-mix(in oklch, var(--paper) var(--thick,74%), transparent);-webkit-backdrop-filter:blur(var(--blur,14px)) saturate(1.2);backdrop-filter:blur(var(--blur,14px)) saturate(1.2);border:1px solid color-mix(in oklch, var(--paper) 50%, var(--line));border-radius:var(--r-3);box-shadow:var(--shadow)}
|
|
88
|
+
.gy-gyeop::before{content:"";position:absolute;inset:0;border-radius:inherit;background-image:var(--grain);opacity:var(--grain-o);pointer-events:none;z-index:-1}
|
|
89
|
+
.gy-hol{--thick:46%;--blur:6px}
|
|
90
|
+
.gy-du {--thick:72%;--blur:14px}
|
|
91
|
+
.gy-se {--thick:90%;--blur:24px}
|
|
92
|
+
|
|
93
|
+
/* ---------- button ---------- */
|
|
94
|
+
.gy-btn{--bg-b:var(--accent);--fg-b:var(--on-accent);appearance:none;border:0;cursor:pointer;font:600 15px/1 var(--f-body);color:var(--fg-b);background:var(--bg-b);padding:13px 20px;border-radius:var(--r-2);display:inline-flex;align-items:center;gap:8px;text-decoration:none;transition:transform var(--t-1) var(--ease-bleed), box-shadow var(--t-3) var(--ease-bleed)}
|
|
95
|
+
.gy-btn:hover{box-shadow:0 0 0 1px var(--bg-b), 0 6px 22px -4px color-mix(in oklch, var(--bg-b) 60%, transparent)}
|
|
96
|
+
.gy-btn:active{transform:translateY(1px) scale(.985)}
|
|
97
|
+
.gy-btn--ink{--bg-b:var(--ink);--fg-b:var(--bg)}
|
|
98
|
+
.gy-btn--paper{--fg-b:var(--ink);background:color-mix(in oklch, var(--paper) 74%, transparent);border:1px solid var(--line);backdrop-filter:blur(12px)}
|
|
99
|
+
.gy-btn--paper:hover{box-shadow:0 6px 22px -8px color-mix(in oklch, var(--ink) 40%, transparent)}
|
|
100
|
+
.gy-btn--ghost{--fg-b:var(--accent);background:transparent}
|
|
101
|
+
.gy-btn--ghost:hover{background:color-mix(in oklch, var(--accent) 10%, transparent);box-shadow:none}
|
|
102
|
+
.gy-btn--danger{--bg-b:var(--err);--fg-b:oklch(99% 0 0)}
|
|
103
|
+
.gy-btn--sm{padding:9px 14px;font-size:14px;border-radius:10px}
|
|
104
|
+
.gy-btn:disabled{opacity:.45;cursor:not-allowed;box-shadow:none}
|
|
105
|
+
|
|
106
|
+
/* ---------- switch: <button class="gy-switch" role="switch" aria-checked="true"> ---------- */
|
|
107
|
+
.gy-switch{appearance:none;border:0;cursor:pointer;width:50px;height:30px;border-radius:var(--r-pill);background:var(--line);position:relative;transition:background var(--t-2) var(--ease-bleed);flex:none}
|
|
108
|
+
.gy-switch::after{content:"";position:absolute;top:3px;left:3px;width:24px;height:24px;border-radius:50%;background:var(--paper);box-shadow:0 2px 6px oklch(0% 0 0 / .25);transition:transform var(--t-2) var(--ease-bleed)}
|
|
109
|
+
.gy-switch[aria-checked="true"]{background:var(--accent)}
|
|
110
|
+
.gy-switch[aria-checked="true"]::after{transform:translateX(20px);background:oklch(99% 0 0)}
|
|
111
|
+
|
|
112
|
+
/* ---------- segmented: buttons with aria-pressed ---------- */
|
|
113
|
+
.gy-seg{display:inline-flex;padding:4px;border-radius:var(--r-pill);background:color-mix(in oklch, var(--ink) 7%, transparent);gap:2px}
|
|
114
|
+
.gy-seg button{appearance:none;border:0;background:transparent;color:var(--ink-2);font:500 14px/1 var(--f-body);padding:8px 14px;border-radius:var(--r-pill);cursor:pointer}
|
|
115
|
+
.gy-seg button[aria-pressed="true"]{background:var(--paper);color:var(--ink);box-shadow:0 1px 3px oklch(0% 0 0 / .14)}
|
|
116
|
+
|
|
117
|
+
/* ---------- chip ---------- */
|
|
118
|
+
.gy-chip{appearance:none;cursor:pointer;border:1px solid var(--line);background:transparent;color:var(--ink-2);font:500 14px/1 var(--f-body);padding:8px 13px;border-radius:var(--r-pill)}
|
|
119
|
+
.gy-chip[aria-pressed="true"]{background:var(--accent-soft);border-color:transparent;color:var(--ink)}
|
|
120
|
+
|
|
121
|
+
/* ---------- field ---------- */
|
|
122
|
+
.gy-field{display:flex;flex-direction:column;gap:6px}
|
|
123
|
+
.gy-field label{font-size:13px;font-weight:500;color:var(--ink-2)}
|
|
124
|
+
.gy-field input,.gy-field textarea,.gy-field select{font:400 15px var(--f-body);color:var(--ink);background:color-mix(in oklch, var(--paper) 80%, transparent);border:1px solid var(--line);border-radius:var(--r-2);padding:11px 13px;transition:border-color var(--t-2), box-shadow var(--t-3) var(--ease-bleed)}
|
|
125
|
+
.gy-field :is(input,textarea,select):focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 5px color-mix(in oklch, var(--accent) 18%, transparent), 0 0 18px 2px color-mix(in oklch, var(--accent) 22%, transparent)}
|
|
126
|
+
.gy-field small{font-size:13px;color:var(--ink-3)}
|
|
127
|
+
.gy-field--error :is(input,textarea,select){border-color:var(--err)}
|
|
128
|
+
.gy-field--error small{color:var(--err)}
|
|
129
|
+
|
|
130
|
+
/* ---------- checkbox: <label class="gy-check"><input type="checkbox"> 텍스트</label> ---------- */
|
|
131
|
+
.gy-check{display:flex;gap:10px;align-items:center;font-size:15px;cursor:pointer}
|
|
132
|
+
.gy-check input{appearance:none;width:20px;height:20px;border-radius:6px;border:1.5px solid var(--ink-3);display:grid;place-items:center;margin:0;cursor:pointer}
|
|
133
|
+
.gy-check input:checked{background:var(--accent);border-color:var(--accent)}
|
|
134
|
+
.gy-check input:checked::after{content:"";width:9px;height:5px;border:2px solid var(--on-accent);border-top:0;border-right:0;transform:rotate(-45deg) translate(1px,-1px)}
|
|
135
|
+
|
|
136
|
+
/* ---------- badge ---------- */
|
|
137
|
+
.gy-badge{font:600 12px/1 var(--f-body);padding:7px 11px;border-radius:var(--r-pill);display:inline-flex;align-items:center;gap:5px;color:var(--accent);background:color-mix(in oklch, var(--accent) 13%, transparent)}
|
|
138
|
+
.gy-badge::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor}
|
|
139
|
+
.gy-badge--ok{color:var(--ok);background:color-mix(in oklch, var(--ok) 14%, transparent)}
|
|
140
|
+
.gy-badge--warn{color:var(--warn);background:color-mix(in oklch, var(--warn) 16%, transparent)}
|
|
141
|
+
.gy-badge--err{color:var(--err);background:color-mix(in oklch, var(--err) 14%, transparent)}
|
|
142
|
+
|
|
143
|
+
/* ---------- progress: <div class="gy-progress" style="--p:60%"><i></i></div> ---------- */
|
|
144
|
+
.gy-progress{height:8px;border-radius:var(--r-pill);background:color-mix(in oklch, var(--ink) 9%, transparent);overflow:hidden}
|
|
145
|
+
.gy-progress > i{display:block;height:100%;width:var(--p,0%);border-radius:inherit;background:linear-gradient(90deg, color-mix(in oklch, var(--accent) 50%, transparent), var(--accent))}
|
|
146
|
+
|
|
147
|
+
/* ---------- toast / tooltip ---------- */
|
|
148
|
+
.gy-toast{display:flex;align-items:center;gap:12px;padding:12px 16px;font-size:14.5px}
|
|
149
|
+
.gy-tooltip{font-size:13px;padding:7px 11px;border-radius:10px;background:var(--ink);color:var(--bg)}
|
|
150
|
+
|
|
151
|
+
@media (prefers-reduced-motion: reduce){.gy *,.gy *::before,.gy *::after{transition:none!important;animation:none!important}}
|
package/index.mjs
CHANGED
|
@@ -841,39 +841,39 @@ const tokens = {
|
|
|
841
841
|
"light": {
|
|
842
842
|
"bg": {
|
|
843
843
|
"$type": "color",
|
|
844
|
-
"$value": "#
|
|
844
|
+
"$value": "#f8f2ef"
|
|
845
845
|
},
|
|
846
846
|
"bg-2": {
|
|
847
847
|
"$type": "color",
|
|
848
|
-
"$value": "#
|
|
848
|
+
"$value": "#efe4de"
|
|
849
849
|
},
|
|
850
850
|
"ink": {
|
|
851
851
|
"$type": "color",
|
|
852
|
-
"$value": "#
|
|
852
|
+
"$value": "#261a14"
|
|
853
853
|
},
|
|
854
854
|
"ink-2": {
|
|
855
855
|
"$type": "color",
|
|
856
|
-
"$value": "#
|
|
856
|
+
"$value": "#584d48"
|
|
857
857
|
},
|
|
858
858
|
"ink-3": {
|
|
859
859
|
"$type": "color",
|
|
860
|
-
"$value": "#
|
|
860
|
+
"$value": "#69615e"
|
|
861
861
|
},
|
|
862
862
|
"line": {
|
|
863
863
|
"$type": "color",
|
|
864
|
-
"$value": "#
|
|
864
|
+
"$value": "#d3c8c3"
|
|
865
865
|
},
|
|
866
866
|
"paper": {
|
|
867
867
|
"$type": "color",
|
|
868
|
-
"$value": "#
|
|
868
|
+
"$value": "#fefcfa"
|
|
869
869
|
},
|
|
870
870
|
"accent": {
|
|
871
871
|
"$type": "color",
|
|
872
|
-
"$value": "#
|
|
872
|
+
"$value": "#7f553f"
|
|
873
873
|
},
|
|
874
874
|
"accent-soft": {
|
|
875
875
|
"$type": "color",
|
|
876
|
-
"$value": "#
|
|
876
|
+
"$value": "#efd9ce"
|
|
877
877
|
},
|
|
878
878
|
"on-accent": {
|
|
879
879
|
"$type": "color",
|
|
@@ -881,7 +881,7 @@ const tokens = {
|
|
|
881
881
|
},
|
|
882
882
|
"stain": {
|
|
883
883
|
"$type": "color",
|
|
884
|
-
"$value": "#
|
|
884
|
+
"$value": "#b8c684"
|
|
885
885
|
},
|
|
886
886
|
"ok": {
|
|
887
887
|
"$type": "color",
|
|
@@ -899,47 +899,47 @@ const tokens = {
|
|
|
899
899
|
"dark": {
|
|
900
900
|
"bg": {
|
|
901
901
|
"$type": "color",
|
|
902
|
-
"$value": "#
|
|
902
|
+
"$value": "#150e0a"
|
|
903
903
|
},
|
|
904
904
|
"bg-2": {
|
|
905
905
|
"$type": "color",
|
|
906
|
-
"$value": "#
|
|
906
|
+
"$value": "#201610"
|
|
907
907
|
},
|
|
908
908
|
"ink": {
|
|
909
909
|
"$type": "color",
|
|
910
|
-
"$value": "#
|
|
910
|
+
"$value": "#f2edeb"
|
|
911
911
|
},
|
|
912
912
|
"ink-2": {
|
|
913
913
|
"$type": "color",
|
|
914
|
-
"$value": "#
|
|
914
|
+
"$value": "#c0b9b5"
|
|
915
915
|
},
|
|
916
916
|
"ink-3": {
|
|
917
917
|
"$type": "color",
|
|
918
|
-
"$value": "#
|
|
918
|
+
"$value": "#a49d99"
|
|
919
919
|
},
|
|
920
920
|
"line": {
|
|
921
921
|
"$type": "color",
|
|
922
|
-
"$value": "#
|
|
922
|
+
"$value": "#3d332e"
|
|
923
923
|
},
|
|
924
924
|
"paper": {
|
|
925
925
|
"$type": "color",
|
|
926
|
-
"$value": "#
|
|
926
|
+
"$value": "#322924"
|
|
927
927
|
},
|
|
928
928
|
"accent": {
|
|
929
929
|
"$type": "color",
|
|
930
|
-
"$value": "#
|
|
930
|
+
"$value": "#d4a58e"
|
|
931
931
|
},
|
|
932
932
|
"accent-soft": {
|
|
933
933
|
"$type": "color",
|
|
934
|
-
"$value": "#
|
|
934
|
+
"$value": "#453025"
|
|
935
935
|
},
|
|
936
936
|
"on-accent": {
|
|
937
937
|
"$type": "color",
|
|
938
|
-
"$value": "#
|
|
938
|
+
"$value": "#1c0d06"
|
|
939
939
|
},
|
|
940
940
|
"stain": {
|
|
941
941
|
"$type": "color",
|
|
942
|
-
"$value": "#
|
|
942
|
+
"$value": "#596424"
|
|
943
943
|
},
|
|
944
944
|
"ok": {
|
|
945
945
|
"$type": "color",
|
package/package.json
CHANGED
package/tokens.json
CHANGED
|
@@ -840,39 +840,39 @@
|
|
|
840
840
|
"light": {
|
|
841
841
|
"bg": {
|
|
842
842
|
"$type": "color",
|
|
843
|
-
"$value": "#
|
|
843
|
+
"$value": "#f8f2ef"
|
|
844
844
|
},
|
|
845
845
|
"bg-2": {
|
|
846
846
|
"$type": "color",
|
|
847
|
-
"$value": "#
|
|
847
|
+
"$value": "#efe4de"
|
|
848
848
|
},
|
|
849
849
|
"ink": {
|
|
850
850
|
"$type": "color",
|
|
851
|
-
"$value": "#
|
|
851
|
+
"$value": "#261a14"
|
|
852
852
|
},
|
|
853
853
|
"ink-2": {
|
|
854
854
|
"$type": "color",
|
|
855
|
-
"$value": "#
|
|
855
|
+
"$value": "#584d48"
|
|
856
856
|
},
|
|
857
857
|
"ink-3": {
|
|
858
858
|
"$type": "color",
|
|
859
|
-
"$value": "#
|
|
859
|
+
"$value": "#69615e"
|
|
860
860
|
},
|
|
861
861
|
"line": {
|
|
862
862
|
"$type": "color",
|
|
863
|
-
"$value": "#
|
|
863
|
+
"$value": "#d3c8c3"
|
|
864
864
|
},
|
|
865
865
|
"paper": {
|
|
866
866
|
"$type": "color",
|
|
867
|
-
"$value": "#
|
|
867
|
+
"$value": "#fefcfa"
|
|
868
868
|
},
|
|
869
869
|
"accent": {
|
|
870
870
|
"$type": "color",
|
|
871
|
-
"$value": "#
|
|
871
|
+
"$value": "#7f553f"
|
|
872
872
|
},
|
|
873
873
|
"accent-soft": {
|
|
874
874
|
"$type": "color",
|
|
875
|
-
"$value": "#
|
|
875
|
+
"$value": "#efd9ce"
|
|
876
876
|
},
|
|
877
877
|
"on-accent": {
|
|
878
878
|
"$type": "color",
|
|
@@ -880,7 +880,7 @@
|
|
|
880
880
|
},
|
|
881
881
|
"stain": {
|
|
882
882
|
"$type": "color",
|
|
883
|
-
"$value": "#
|
|
883
|
+
"$value": "#b8c684"
|
|
884
884
|
},
|
|
885
885
|
"ok": {
|
|
886
886
|
"$type": "color",
|
|
@@ -898,47 +898,47 @@
|
|
|
898
898
|
"dark": {
|
|
899
899
|
"bg": {
|
|
900
900
|
"$type": "color",
|
|
901
|
-
"$value": "#
|
|
901
|
+
"$value": "#150e0a"
|
|
902
902
|
},
|
|
903
903
|
"bg-2": {
|
|
904
904
|
"$type": "color",
|
|
905
|
-
"$value": "#
|
|
905
|
+
"$value": "#201610"
|
|
906
906
|
},
|
|
907
907
|
"ink": {
|
|
908
908
|
"$type": "color",
|
|
909
|
-
"$value": "#
|
|
909
|
+
"$value": "#f2edeb"
|
|
910
910
|
},
|
|
911
911
|
"ink-2": {
|
|
912
912
|
"$type": "color",
|
|
913
|
-
"$value": "#
|
|
913
|
+
"$value": "#c0b9b5"
|
|
914
914
|
},
|
|
915
915
|
"ink-3": {
|
|
916
916
|
"$type": "color",
|
|
917
|
-
"$value": "#
|
|
917
|
+
"$value": "#a49d99"
|
|
918
918
|
},
|
|
919
919
|
"line": {
|
|
920
920
|
"$type": "color",
|
|
921
|
-
"$value": "#
|
|
921
|
+
"$value": "#3d332e"
|
|
922
922
|
},
|
|
923
923
|
"paper": {
|
|
924
924
|
"$type": "color",
|
|
925
|
-
"$value": "#
|
|
925
|
+
"$value": "#322924"
|
|
926
926
|
},
|
|
927
927
|
"accent": {
|
|
928
928
|
"$type": "color",
|
|
929
|
-
"$value": "#
|
|
929
|
+
"$value": "#d4a58e"
|
|
930
930
|
},
|
|
931
931
|
"accent-soft": {
|
|
932
932
|
"$type": "color",
|
|
933
|
-
"$value": "#
|
|
933
|
+
"$value": "#453025"
|
|
934
934
|
},
|
|
935
935
|
"on-accent": {
|
|
936
936
|
"$type": "color",
|
|
937
|
-
"$value": "#
|
|
937
|
+
"$value": "#1c0d06"
|
|
938
938
|
},
|
|
939
939
|
"stain": {
|
|
940
940
|
"$type": "color",
|
|
941
|
-
"$value": "#
|
|
941
|
+
"$value": "#596424"
|
|
942
942
|
},
|
|
943
943
|
"ok": {
|
|
944
944
|
"$type": "color",
|