@mizumi25/cli 0.1.0 → 0.1.3
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/docs-generator.js +1302 -536
- package/index.js +2557 -316
- package/package.json +1 -1
- package/watcher.js +153 -40
package/docs-generator.js
CHANGED
|
@@ -1,713 +1,1479 @@
|
|
|
1
1
|
// packages/cli/docs-generator.js
|
|
2
|
-
import fs
|
|
3
|
-
import path from 'path'
|
|
4
|
-
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
import path from 'path'
|
|
5
4
|
|
|
6
5
|
export class DocsGenerator {
|
|
7
6
|
constructor(config) {
|
|
8
|
-
this.config = config
|
|
9
|
-
this.tokens = config.tokens || {}
|
|
10
|
-
this.patterns = config.patterns || {}
|
|
11
|
-
this.animations = config.animations || {}
|
|
7
|
+
this.config = config
|
|
8
|
+
this.tokens = config.tokens || {}
|
|
9
|
+
this.patterns = config.patterns || {}
|
|
10
|
+
this.animations = config.animations || {}
|
|
11
|
+
this.rules = config.rules || {}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
generate(outputDir = '.mizumi/docs') {
|
|
15
|
+
if (!fs.existsSync(outputDir)) {
|
|
16
|
+
fs.mkdirSync(outputDir, { recursive: true })
|
|
17
|
+
}
|
|
18
|
+
const html = this._buildHTML()
|
|
19
|
+
const outPath = path.join(outputDir, 'index.html')
|
|
20
|
+
fs.writeFileSync(outPath, html, 'utf8')
|
|
21
|
+
console.log(`✅ Docs: ${outPath}`)
|
|
22
|
+
return outPath
|
|
12
23
|
}
|
|
13
24
|
|
|
14
|
-
|
|
25
|
+
// ── Token counts ──
|
|
26
|
+
countTokens() {
|
|
27
|
+
let count = 0
|
|
28
|
+
for (const [, v] of Object.entries(this.tokens)) {
|
|
29
|
+
if (typeof v === 'object') {
|
|
30
|
+
for (const [, val] of Object.entries(v)) {
|
|
31
|
+
if (typeof val === 'object') count += Object.keys(val).length
|
|
32
|
+
else count++
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return count
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ── Utility class examples per capability ──
|
|
40
|
+
getUtilityExamples() {
|
|
41
|
+
const T = this.tokens
|
|
42
|
+
const examples = []
|
|
43
|
+
|
|
44
|
+
// Colors
|
|
45
|
+
if (T.colors) {
|
|
46
|
+
const colorKeys = Object.entries(T.colors).slice(0, 3)
|
|
47
|
+
for (const [key, val] of colorKeys) {
|
|
48
|
+
const name = typeof val === 'object' ? key : key
|
|
49
|
+
examples.push({ cap: 'ink', value: name, css: 'color', preview: 'color' })
|
|
50
|
+
examples.push({ cap: 'paint', value: name, css: 'background-color', preview: 'bg' })
|
|
51
|
+
examples.push({ cap: 'stroke-color', value: name, css: 'border-color', preview: 'border' })
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Spacing
|
|
56
|
+
if (T.spacing) {
|
|
57
|
+
const keys = Object.keys(T.spacing).slice(0, 4)
|
|
58
|
+
for (const k of keys) {
|
|
59
|
+
examples.push({ cap: 'pad', value: k, css: 'padding', preview: 'spacing' })
|
|
60
|
+
examples.push({ cap: 'mar', value: k, css: 'margin', preview: 'spacing' })
|
|
61
|
+
examples.push({ cap: 'gap', value: k, css: 'gap', preview: 'spacing' })
|
|
62
|
+
examples.push({ cap: 'pad-x', value: k, css: 'padding-inline', preview: 'spacing' })
|
|
63
|
+
examples.push({ cap: 'pad-y', value: k, css: 'padding-block', preview: 'spacing' })
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Typography
|
|
68
|
+
if (T.typography) {
|
|
69
|
+
for (const k of Object.keys(T.typography)) {
|
|
70
|
+
examples.push({ cap: 'text', value: k, css: 'font-size + weight + line-height', preview: 'text' })
|
|
71
|
+
examples.push({ cap: 'type-size', value: k, css: 'font-size', preview: 'text' })
|
|
72
|
+
examples.push({ cap: 'type-weight', value: k, css: 'font-weight', preview: 'text' })
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Fonts
|
|
77
|
+
if (T.fonts) {
|
|
78
|
+
for (const k of Object.keys(T.fonts)) {
|
|
79
|
+
examples.push({ cap: 'type-face', value: k, css: 'font-family', preview: 'font' })
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Radius
|
|
84
|
+
if (T.radius) {
|
|
85
|
+
for (const k of Object.keys(T.radius)) {
|
|
86
|
+
examples.push({ cap: 'curve', value: k, css: 'border-radius', preview: 'radius' })
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Shadows
|
|
91
|
+
if (T.shadows) {
|
|
92
|
+
for (const k of Object.keys(T.shadows)) {
|
|
93
|
+
examples.push({ cap: 'cast', value: k, css: 'box-shadow', preview: 'shadow' })
|
|
94
|
+
examples.push({ cap: 'cast-inner', value: k, css: 'box-shadow (inset)', preview: 'shadow' })
|
|
95
|
+
examples.push({ cap: 'cast-text', value: k, css: 'text-shadow', preview: 'shadow' })
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Opacity
|
|
100
|
+
if (T.opacity) {
|
|
101
|
+
for (const k of Object.keys(T.opacity)) {
|
|
102
|
+
examples.push({ cap: 'canvas-fade', value: k, css: 'opacity', preview: 'opacity' })
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Blur
|
|
107
|
+
if (T.blur) {
|
|
108
|
+
for (const k of Object.keys(T.blur)) {
|
|
109
|
+
examples.push({ cap: 'glass-blur', value: k, css: 'backdrop-filter: blur()', preview: 'blur' })
|
|
110
|
+
examples.push({ cap: 'glow-blur', value: k, css: 'filter: blur()', preview: 'blur' })
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Leading
|
|
115
|
+
if (T.leading) {
|
|
116
|
+
for (const k of Object.keys(T.leading)) {
|
|
117
|
+
examples.push({ cap: 'leading', value: k, css: 'line-height', preview: 'text' })
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Tracking
|
|
122
|
+
if (T.tracking) {
|
|
123
|
+
for (const k of Object.keys(T.tracking)) {
|
|
124
|
+
examples.push({ cap: 'tracking', value: k, css: 'letter-spacing', preview: 'text' })
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Z-index
|
|
129
|
+
if (T.zIndex) {
|
|
130
|
+
for (const k of Object.keys(T.zIndex)) {
|
|
131
|
+
examples.push({ cap: 'layer', value: k, css: 'z-index', preview: 'layer' })
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Easing
|
|
136
|
+
if (T.easing) {
|
|
137
|
+
for (const k of Object.keys(T.easing)) {
|
|
138
|
+
examples.push({ cap: 'ease-curve', value: k, css: 'transition-timing-function', preview: 'ease' })
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Duration
|
|
143
|
+
if (T.duration) {
|
|
144
|
+
for (const k of Object.keys(T.duration)) {
|
|
145
|
+
examples.push({ cap: 'ease-speed', value: k, css: 'transition-duration', preview: 'ease' })
|
|
146
|
+
examples.push({ cap: 'ease-wait', value: k, css: 'transition-delay', preview: 'ease' })
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return examples
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ── Static utility categories ──
|
|
154
|
+
getStaticCategories() {
|
|
155
|
+
return [
|
|
156
|
+
{
|
|
157
|
+
name: 'Display', utilities: [
|
|
158
|
+
{ cls: 'display:flex', css: 'display: flex' },
|
|
159
|
+
{ cls: 'display:grid', css: 'display: grid' },
|
|
160
|
+
{ cls: 'display:block', css: 'display: block' },
|
|
161
|
+
{ cls: 'display:inline', css: 'display: inline' },
|
|
162
|
+
{ cls: 'display:none', css: 'display: none' },
|
|
163
|
+
{ cls: 'display:flex-inline', css: 'display: inline-flex' },
|
|
164
|
+
{ cls: 'display:grid-inline', css: 'display: inline-grid' },
|
|
165
|
+
{ cls: 'display:contents', css: 'display: contents' },
|
|
166
|
+
]
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: 'Flex', utilities: [
|
|
170
|
+
{ cls: 'flex-dir:row', css: 'flex-direction: row' },
|
|
171
|
+
{ cls: 'flex-dir:col', css: 'flex-direction: column' },
|
|
172
|
+
{ cls: 'flex-dir:row-rev', css: 'flex-direction: row-reverse' },
|
|
173
|
+
{ cls: 'flex-dir:col-rev', css: 'flex-direction: column-reverse' },
|
|
174
|
+
{ cls: 'flex-wrap:yes', css: 'flex-wrap: wrap' },
|
|
175
|
+
{ cls: 'flex-wrap:no', css: 'flex-wrap: nowrap' },
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
name: 'Alignment', utilities: [
|
|
180
|
+
{ cls: 'align-x:center', css: 'justify-content: center' },
|
|
181
|
+
{ cls: 'align-x:between', css: 'justify-content: space-between' },
|
|
182
|
+
{ cls: 'align-x:start', css: 'justify-content: flex-start' },
|
|
183
|
+
{ cls: 'align-x:end', css: 'justify-content: flex-end' },
|
|
184
|
+
{ cls: 'align-yi:center', css: 'align-items: center' },
|
|
185
|
+
{ cls: 'align-yi:start', css: 'align-items: flex-start' },
|
|
186
|
+
{ cls: 'align-yi:end', css: 'align-items: flex-end' },
|
|
187
|
+
{ cls: 'align-ys:center', css: 'align-self: center' },
|
|
188
|
+
{ cls: 'place:center', css: 'place-content: center' },
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: 'Position', utilities: [
|
|
193
|
+
{ cls: 'pos:relative', css: 'position: relative' },
|
|
194
|
+
{ cls: 'pos:absolute', css: 'position: absolute' },
|
|
195
|
+
{ cls: 'pos:fixed', css: 'position: fixed' },
|
|
196
|
+
{ cls: 'pos:sticky', css: 'position: sticky' },
|
|
197
|
+
{ cls: 'pos:static', css: 'position: static' },
|
|
198
|
+
]
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
name: 'Overflow', utilities: [
|
|
202
|
+
{ cls: 'overflow:hidden', css: 'overflow: hidden' },
|
|
203
|
+
{ cls: 'overflow:auto', css: 'overflow: auto' },
|
|
204
|
+
{ cls: 'overflow:scroll', css: 'overflow: scroll' },
|
|
205
|
+
{ cls: 'overflow:visible', css: 'overflow: visible' },
|
|
206
|
+
{ cls: 'overflow:clip', css: 'overflow: clip' },
|
|
207
|
+
]
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: 'Sizing', utilities: [
|
|
211
|
+
{ cls: 'canvas-w:full', css: 'width: 100%' },
|
|
212
|
+
{ cls: 'canvas-w:screen', css: 'width: 100vw' },
|
|
213
|
+
{ cls: 'canvas-w:auto', css: 'width: auto' },
|
|
214
|
+
{ cls: 'canvas-h:full', css: 'height: 100%' },
|
|
215
|
+
{ cls: 'canvas-h:screen', css: 'height: 100vh' },
|
|
216
|
+
{ cls: 'canvas-h:auto', css: 'height: auto' },
|
|
217
|
+
{ cls: 'mar-x:auto', css: 'margin-inline: auto' },
|
|
218
|
+
]
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
name: 'Typography', utilities: [
|
|
222
|
+
{ cls: 'text-align:center', css: 'text-align: center' },
|
|
223
|
+
{ cls: 'text-align:left', css: 'text-align: left' },
|
|
224
|
+
{ cls: 'text-align:right', css: 'text-align: right' },
|
|
225
|
+
{ cls: 'text-case:upper', css: 'text-transform: uppercase' },
|
|
226
|
+
{ cls: 'text-case:lower', css: 'text-transform: lowercase' },
|
|
227
|
+
{ cls: 'text-case:capital', css: 'text-transform: capitalize' },
|
|
228
|
+
{ cls: 'type-weight:bold', css: 'font-weight: bold' },
|
|
229
|
+
{ cls: 'type-weight:semi', css: 'font-weight: 600' },
|
|
230
|
+
{ cls: 'type-weight:medium',css: 'font-weight: 500' },
|
|
231
|
+
{ cls: 'type-style:italic', css: 'font-style: italic' },
|
|
232
|
+
]
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: 'Cursor & Interaction', utilities: [
|
|
236
|
+
{ cls: 'cursor:pointer', css: 'cursor: pointer' },
|
|
237
|
+
{ cls: 'cursor:default', css: 'cursor: default' },
|
|
238
|
+
{ cls: 'cursor:none', css: 'cursor: none' },
|
|
239
|
+
{ cls: 'cursor:grab', css: 'cursor: grab' },
|
|
240
|
+
{ cls: 'select:none', css: 'user-select: none' },
|
|
241
|
+
{ cls: 'events:none', css: 'pointer-events: none' },
|
|
242
|
+
{ cls: 'events:all', css: 'pointer-events: all' },
|
|
243
|
+
]
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
name: 'Border Style', utilities: [
|
|
247
|
+
{ cls: 'stroke-style:solid', css: 'border-style: solid' },
|
|
248
|
+
{ cls: 'stroke-style:dashed', css: 'border-style: dashed' },
|
|
249
|
+
{ cls: 'stroke-style:dotted', css: 'border-style: dotted' },
|
|
250
|
+
{ cls: 'stroke-style:none', css: 'border-style: none' },
|
|
251
|
+
]
|
|
252
|
+
},
|
|
253
|
+
]
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ── Animation type badge ──
|
|
257
|
+
getAnimType(config) {
|
|
258
|
+
if (config.hover) return { label: 'hover', color: '#a78bfa' }
|
|
259
|
+
if (config.active) return { label: 'click', color: '#f87171' }
|
|
260
|
+
if (config.targets === 'children') return { label: 'stagger', color: '#fbbf24' }
|
|
261
|
+
if (config.scrollTrigger) return { label: 'scroll', color: '#38bdf8' }
|
|
262
|
+
if (config.repeat === -1) return { label: 'loop', color: '#e879f9' }
|
|
263
|
+
return { label: 'entrance', color: '#34d399' }
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// ── Arbitrary value examples ──
|
|
267
|
+
getArbitraryExamples() {
|
|
268
|
+
return [
|
|
269
|
+
{ cls: 'pad:clamp(1rem,4vw,3rem)', desc: 'Fluid padding using CSS clamp()' },
|
|
270
|
+
{ cls: 'type-size:clamp(2rem,5vw,5rem)', desc: 'Fluid font size' },
|
|
271
|
+
{ cls: 'canvas-w:min(100%,1200px)', desc: 'Responsive max-width container' },
|
|
272
|
+
{ cls: 'curve:24px', desc: 'Arbitrary border radius' },
|
|
273
|
+
{ cls: 'cast:0_8px_32px_rgba(0,0,0,0.4)', desc: 'Custom box shadow (use _ for spaces)' },
|
|
274
|
+
{ cls: 'ink:#ff6b6b', desc: 'Arbitrary hex color' },
|
|
275
|
+
{ cls: 'paint:rgba(0,0,0,0.5)', desc: 'Arbitrary rgba background' },
|
|
276
|
+
{ cls: 'tracking:-0.04em', desc: 'Arbitrary letter spacing' },
|
|
277
|
+
{ cls: 'leading:0.9', desc: 'Arbitrary line height' },
|
|
278
|
+
{ cls: 'canvas-w:calc(100%-2rem)', desc: 'CSS calc() value' },
|
|
279
|
+
]
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
_buildHTML() {
|
|
283
|
+
const tokenCount = this.countTokens()
|
|
284
|
+
const patternCount = Object.keys(this.patterns).length
|
|
285
|
+
const animCount = Object.keys(this.animations).length
|
|
286
|
+
const utilExamples = this.getUtilityExamples()
|
|
287
|
+
const staticCats = this.getStaticCategories()
|
|
288
|
+
const arbitrary = this.getArbitraryExamples()
|
|
289
|
+
const bpCount = Object.keys(this.rules.breakpoints || {}).length
|
|
290
|
+
|
|
15
291
|
return `<!DOCTYPE html>
|
|
16
292
|
<html lang="en">
|
|
17
293
|
<head>
|
|
18
294
|
<meta charset="UTF-8">
|
|
19
295
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
20
|
-
<title>Mizumi Docs
|
|
296
|
+
<title>Mizumi Docs 💮</title>
|
|
21
297
|
<style>
|
|
22
|
-
|
|
298
|
+
@import url('https://fonts.googleapis.com/css2?family=IM+Fell+English:ital@0;1&family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300&display=swap');
|
|
299
|
+
|
|
300
|
+
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
301
|
+
|
|
302
|
+
:root {
|
|
303
|
+
--ink: #e8e4dc;
|
|
304
|
+
--ink-muted: #7a7568;
|
|
305
|
+
--ink-dim: #3d3a34;
|
|
306
|
+
--surface: #0e0d0b;
|
|
307
|
+
--surface-2: #141310;
|
|
308
|
+
--surface-3: #1a1916;
|
|
309
|
+
--border: #2a2823;
|
|
310
|
+
--accent: #c9a96e;
|
|
311
|
+
--accent-2: #8b6f47;
|
|
312
|
+
--serif: 'IM Fell English', Georgia, serif;
|
|
313
|
+
--mono: 'DM Mono', monospace;
|
|
314
|
+
--sans: system-ui, sans-serif;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
html { scroll-behavior: smooth; }
|
|
23
318
|
|
|
24
319
|
body {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
320
|
+
background: var(--surface);
|
|
321
|
+
color: var(--ink);
|
|
322
|
+
font-family: var(--sans);
|
|
323
|
+
font-size: 15px;
|
|
324
|
+
line-height: 1.6;
|
|
28
325
|
min-height: 100vh;
|
|
29
326
|
}
|
|
30
327
|
|
|
31
|
-
/*
|
|
328
|
+
/* ── LAYOUT ── */
|
|
32
329
|
.sidebar {
|
|
33
330
|
position: fixed;
|
|
34
331
|
top: 0; left: 0;
|
|
35
|
-
width:
|
|
332
|
+
width: 220px;
|
|
36
333
|
height: 100vh;
|
|
37
|
-
background:
|
|
38
|
-
border-right: 1px solid
|
|
334
|
+
background: var(--surface-2);
|
|
335
|
+
border-right: 1px solid var(--border);
|
|
39
336
|
overflow-y: auto;
|
|
40
|
-
padding:
|
|
337
|
+
padding: 0;
|
|
338
|
+
z-index: 100;
|
|
41
339
|
}
|
|
42
340
|
|
|
43
341
|
.main {
|
|
44
|
-
margin-left:
|
|
45
|
-
|
|
46
|
-
|
|
342
|
+
margin-left: 220px;
|
|
343
|
+
max-width: 1100px;
|
|
344
|
+
padding: 0 48px 120px;
|
|
47
345
|
}
|
|
48
346
|
|
|
49
|
-
/*
|
|
50
|
-
.sidebar-
|
|
51
|
-
padding:
|
|
52
|
-
border-bottom: 1px solid
|
|
53
|
-
margin-bottom: 16px;
|
|
347
|
+
/* ── SIDEBAR ── */
|
|
348
|
+
.sidebar-header {
|
|
349
|
+
padding: 32px 24px 24px;
|
|
350
|
+
border-bottom: 1px solid var(--border);
|
|
54
351
|
}
|
|
55
352
|
|
|
56
|
-
.sidebar-logo
|
|
57
|
-
font-
|
|
58
|
-
font-
|
|
59
|
-
color:
|
|
60
|
-
letter-spacing: -0.
|
|
353
|
+
.sidebar-logo {
|
|
354
|
+
font-family: var(--serif);
|
|
355
|
+
font-size: 22px;
|
|
356
|
+
color: var(--ink);
|
|
357
|
+
letter-spacing: -0.02em;
|
|
358
|
+
margin-bottom: 4px;
|
|
61
359
|
}
|
|
62
360
|
|
|
63
|
-
.sidebar-
|
|
64
|
-
font-
|
|
65
|
-
|
|
361
|
+
.sidebar-version {
|
|
362
|
+
font-family: var(--mono);
|
|
363
|
+
font-size: 11px;
|
|
364
|
+
color: var(--ink-muted);
|
|
365
|
+
letter-spacing: 0.1em;
|
|
66
366
|
}
|
|
67
367
|
|
|
68
|
-
.nav-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
368
|
+
.nav-group { padding: 20px 0 4px; }
|
|
369
|
+
|
|
370
|
+
.nav-label {
|
|
371
|
+
padding: 0 24px 8px;
|
|
372
|
+
font-family: var(--mono);
|
|
373
|
+
font-size: 10px;
|
|
374
|
+
letter-spacing: 0.15em;
|
|
72
375
|
text-transform: uppercase;
|
|
73
|
-
|
|
74
|
-
color: #475569;
|
|
376
|
+
color: var(--ink-dim);
|
|
75
377
|
}
|
|
76
378
|
|
|
77
379
|
.nav-link {
|
|
78
380
|
display: block;
|
|
79
|
-
padding:
|
|
80
|
-
|
|
381
|
+
padding: 7px 24px;
|
|
382
|
+
font-family: var(--mono);
|
|
383
|
+
font-size: 12px;
|
|
384
|
+
color: var(--ink-muted);
|
|
81
385
|
text-decoration: none;
|
|
82
|
-
|
|
386
|
+
border-left: 2px solid transparent;
|
|
83
387
|
transition: all 0.15s;
|
|
84
|
-
border-left: 3px solid transparent;
|
|
85
388
|
}
|
|
86
389
|
|
|
87
390
|
.nav-link:hover {
|
|
88
|
-
color:
|
|
89
|
-
|
|
90
|
-
|
|
391
|
+
color: var(--ink);
|
|
392
|
+
border-left-color: var(--accent);
|
|
393
|
+
background: rgba(201,169,110,0.04);
|
|
91
394
|
}
|
|
92
395
|
|
|
93
|
-
/*
|
|
94
|
-
.
|
|
95
|
-
|
|
396
|
+
/* ── SECTIONS ── */
|
|
397
|
+
.hero {
|
|
398
|
+
padding: 80px 0 64px;
|
|
399
|
+
border-bottom: 1px solid var(--border);
|
|
400
|
+
margin-bottom: 80px;
|
|
96
401
|
}
|
|
97
402
|
|
|
98
|
-
.
|
|
99
|
-
font-
|
|
100
|
-
font-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
letter-spacing: -0.5px;
|
|
403
|
+
.hero-eyebrow {
|
|
404
|
+
font-family: var(--mono);
|
|
405
|
+
font-size: 11px;
|
|
406
|
+
letter-spacing: 0.2em;
|
|
407
|
+
text-transform: uppercase;
|
|
408
|
+
color: var(--accent);
|
|
409
|
+
margin-bottom: 20px;
|
|
106
410
|
}
|
|
107
411
|
|
|
108
|
-
.
|
|
109
|
-
font-
|
|
110
|
-
font-
|
|
111
|
-
|
|
112
|
-
|
|
412
|
+
.hero-title {
|
|
413
|
+
font-family: var(--serif);
|
|
414
|
+
font-size: clamp(3rem, 6vw, 5.5rem);
|
|
415
|
+
line-height: 0.95;
|
|
416
|
+
letter-spacing: -0.03em;
|
|
417
|
+
color: var(--ink);
|
|
418
|
+
margin-bottom: 24px;
|
|
113
419
|
}
|
|
114
420
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
|
119
|
-
gap: 12px;
|
|
120
|
-
margin-bottom: 24px;
|
|
421
|
+
.hero-title em {
|
|
422
|
+
color: var(--ink-muted);
|
|
423
|
+
font-style: italic;
|
|
121
424
|
}
|
|
122
425
|
|
|
123
|
-
.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
426
|
+
.hero-sub {
|
|
427
|
+
font-family: var(--mono);
|
|
428
|
+
font-size: 13px;
|
|
429
|
+
color: var(--ink-muted);
|
|
430
|
+
max-width: 480px;
|
|
431
|
+
line-height: 1.7;
|
|
432
|
+
margin-bottom: 40px;
|
|
129
433
|
}
|
|
130
434
|
|
|
131
|
-
.
|
|
435
|
+
.stats {
|
|
436
|
+
display: flex;
|
|
437
|
+
gap: 40px;
|
|
438
|
+
flex-wrap: wrap;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.stat-item { display: flex; flex-direction: column; gap: 4px; }
|
|
442
|
+
|
|
443
|
+
.stat-num {
|
|
444
|
+
font-family: var(--serif);
|
|
445
|
+
font-size: 2.5rem;
|
|
446
|
+
line-height: 1;
|
|
447
|
+
color: var(--accent);
|
|
448
|
+
letter-spacing: -0.03em;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
.stat-label {
|
|
452
|
+
font-family: var(--mono);
|
|
453
|
+
font-size: 10px;
|
|
454
|
+
letter-spacing: 0.15em;
|
|
455
|
+
text-transform: uppercase;
|
|
456
|
+
color: var(--ink-muted);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/* ── SECTION HEADERS ── */
|
|
460
|
+
.section { margin-bottom: 80px; }
|
|
132
461
|
|
|
133
|
-
.
|
|
134
|
-
|
|
462
|
+
.section-header {
|
|
463
|
+
display: flex;
|
|
464
|
+
align-items: flex-end;
|
|
465
|
+
justify-content: space-between;
|
|
466
|
+
padding-bottom: 20px;
|
|
467
|
+
border-bottom: 1px solid var(--border);
|
|
468
|
+
margin-bottom: 40px;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.section-title {
|
|
472
|
+
font-family: var(--serif);
|
|
473
|
+
font-size: clamp(1.8rem, 3vw, 2.8rem);
|
|
474
|
+
line-height: 1;
|
|
475
|
+
letter-spacing: -0.03em;
|
|
476
|
+
color: var(--ink);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.section-count {
|
|
480
|
+
font-family: var(--mono);
|
|
481
|
+
font-size: 11px;
|
|
482
|
+
letter-spacing: 0.1em;
|
|
483
|
+
color: var(--ink-muted);
|
|
484
|
+
padding-bottom: 4px;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
.subsection-title {
|
|
488
|
+
font-family: var(--mono);
|
|
489
|
+
font-size: 11px;
|
|
490
|
+
letter-spacing: 0.15em;
|
|
491
|
+
text-transform: uppercase;
|
|
492
|
+
color: var(--ink-muted);
|
|
493
|
+
margin: 40px 0 16px;
|
|
494
|
+
padding-bottom: 8px;
|
|
495
|
+
border-bottom: 1px solid var(--border);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/* ── SEARCH ── */
|
|
499
|
+
.search-wrap {
|
|
500
|
+
position: relative;
|
|
501
|
+
margin-bottom: 48px;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.search {
|
|
505
|
+
width: 100%;
|
|
506
|
+
background: var(--surface-2);
|
|
507
|
+
border: 1px solid var(--border);
|
|
508
|
+
border-radius: 4px;
|
|
509
|
+
padding: 14px 20px;
|
|
510
|
+
color: var(--ink);
|
|
511
|
+
font-family: var(--mono);
|
|
135
512
|
font-size: 13px;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
513
|
+
outline: none;
|
|
514
|
+
transition: border-color 0.2s;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
.search:focus { border-color: var(--accent); }
|
|
518
|
+
.search::placeholder { color: var(--ink-dim); }
|
|
519
|
+
|
|
520
|
+
/* ── TOKEN TABLES ── */
|
|
521
|
+
.token-table { width: 100%; border-collapse: collapse; margin-bottom: 32px; }
|
|
522
|
+
|
|
523
|
+
.token-table th {
|
|
524
|
+
font-family: var(--mono);
|
|
525
|
+
font-size: 10px;
|
|
526
|
+
letter-spacing: 0.15em;
|
|
527
|
+
text-transform: uppercase;
|
|
528
|
+
color: var(--ink-muted);
|
|
529
|
+
text-align: left;
|
|
530
|
+
padding: 10px 16px;
|
|
531
|
+
border-bottom: 1px solid var(--border);
|
|
139
532
|
}
|
|
140
533
|
|
|
141
|
-
.
|
|
534
|
+
.token-table td {
|
|
535
|
+
padding: 12px 16px;
|
|
536
|
+
border-bottom: 1px solid var(--border);
|
|
537
|
+
font-family: var(--mono);
|
|
142
538
|
font-size: 12px;
|
|
143
|
-
|
|
144
|
-
word-break: break-all;
|
|
539
|
+
vertical-align: middle;
|
|
145
540
|
}
|
|
146
541
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
542
|
+
.token-table tr:hover td { background: var(--surface-2); }
|
|
543
|
+
|
|
544
|
+
.token-name { color: var(--accent); }
|
|
545
|
+
.token-var { color: var(--ink-muted); font-size: 11px; }
|
|
546
|
+
.token-val { color: var(--ink-dim); }
|
|
547
|
+
|
|
548
|
+
.color-chip {
|
|
549
|
+
width: 28px; height: 28px;
|
|
550
|
+
border-radius: 4px;
|
|
551
|
+
border: 1px solid rgba(255,255,255,0.08);
|
|
552
|
+
display: inline-block;
|
|
553
|
+
vertical-align: middle;
|
|
154
554
|
}
|
|
155
555
|
|
|
156
|
-
|
|
556
|
+
.radius-chip {
|
|
557
|
+
width: 28px; height: 28px;
|
|
558
|
+
background: var(--accent-2);
|
|
559
|
+
display: inline-block;
|
|
560
|
+
vertical-align: middle;
|
|
561
|
+
opacity: 0.7;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/* ── UTILITY ROWS ── */
|
|
565
|
+
.utility-row {
|
|
566
|
+
display: flex;
|
|
567
|
+
align-items: center;
|
|
568
|
+
gap: 16px;
|
|
569
|
+
padding: 10px 16px;
|
|
570
|
+
border-bottom: 1px solid var(--border);
|
|
571
|
+
transition: background 0.1s;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
.utility-row:hover { background: var(--surface-2); }
|
|
575
|
+
|
|
576
|
+
.utility-cls {
|
|
577
|
+
font-family: var(--mono);
|
|
578
|
+
font-size: 12px;
|
|
579
|
+
color: var(--accent);
|
|
580
|
+
min-width: 260px;
|
|
581
|
+
flex-shrink: 0;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
.utility-arrow {
|
|
585
|
+
color: var(--ink-dim);
|
|
586
|
+
font-size: 11px;
|
|
587
|
+
flex-shrink: 0;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.utility-css {
|
|
591
|
+
font-family: var(--mono);
|
|
592
|
+
font-size: 11px;
|
|
593
|
+
color: var(--ink-muted);
|
|
594
|
+
flex: 1;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/* ── PATTERN ROWS ── */
|
|
157
598
|
.pattern-row {
|
|
158
|
-
|
|
159
|
-
border:
|
|
160
|
-
border-radius: 10px;
|
|
161
|
-
padding: 16px 20px;
|
|
599
|
+
border: 1px solid var(--border);
|
|
600
|
+
border-radius: 4px;
|
|
162
601
|
margin-bottom: 8px;
|
|
602
|
+
overflow: hidden;
|
|
603
|
+
transition: border-color 0.15s;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
.pattern-row:hover { border-color: var(--accent-2); }
|
|
607
|
+
|
|
608
|
+
.pattern-header {
|
|
163
609
|
display: flex;
|
|
164
|
-
align-items:
|
|
165
|
-
|
|
166
|
-
|
|
610
|
+
align-items: center;
|
|
611
|
+
justify-content: space-between;
|
|
612
|
+
padding: 14px 20px;
|
|
613
|
+
background: var(--surface-2);
|
|
614
|
+
cursor: pointer;
|
|
167
615
|
}
|
|
168
616
|
|
|
169
617
|
.pattern-name {
|
|
170
|
-
font-family:
|
|
171
|
-
font-size:
|
|
172
|
-
color:
|
|
173
|
-
font-weight: 600;
|
|
174
|
-
min-width: 160px;
|
|
618
|
+
font-family: var(--mono);
|
|
619
|
+
font-size: 13px;
|
|
620
|
+
color: var(--accent);
|
|
175
621
|
}
|
|
176
622
|
|
|
177
|
-
.pattern-
|
|
178
|
-
|
|
179
|
-
font-size:
|
|
623
|
+
.pattern-toggle {
|
|
624
|
+
font-family: var(--mono);
|
|
625
|
+
font-size: 10px;
|
|
626
|
+
color: var(--ink-dim);
|
|
627
|
+
letter-spacing: 0.1em;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
.pattern-body {
|
|
631
|
+
padding: 16px 20px;
|
|
632
|
+
border-top: 1px solid var(--border);
|
|
633
|
+
display: none;
|
|
180
634
|
}
|
|
181
635
|
|
|
636
|
+
.pattern-body.open { display: block; }
|
|
637
|
+
|
|
182
638
|
.pattern-value {
|
|
183
|
-
font-family:
|
|
184
|
-
font-size:
|
|
185
|
-
color:
|
|
186
|
-
|
|
639
|
+
font-family: var(--mono);
|
|
640
|
+
font-size: 12px;
|
|
641
|
+
color: var(--ink-muted);
|
|
642
|
+
line-height: 1.8;
|
|
643
|
+
margin-bottom: 16px;
|
|
644
|
+
word-break: break-all;
|
|
187
645
|
}
|
|
188
646
|
|
|
189
|
-
|
|
647
|
+
.pattern-usage {
|
|
648
|
+
background: var(--surface);
|
|
649
|
+
border: 1px solid var(--border);
|
|
650
|
+
border-radius: 3px;
|
|
651
|
+
padding: 10px 14px;
|
|
652
|
+
font-family: var(--mono);
|
|
653
|
+
font-size: 12px;
|
|
654
|
+
color: #86efac;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/* ── ANIMATION ROWS ── */
|
|
190
658
|
.anim-row {
|
|
191
|
-
|
|
192
|
-
border:
|
|
193
|
-
border-radius: 10px;
|
|
194
|
-
padding: 16px 20px;
|
|
659
|
+
border: 1px solid var(--border);
|
|
660
|
+
border-radius: 4px;
|
|
195
661
|
margin-bottom: 8px;
|
|
662
|
+
overflow: hidden;
|
|
196
663
|
}
|
|
197
664
|
|
|
198
665
|
.anim-header {
|
|
199
666
|
display: flex;
|
|
200
667
|
align-items: center;
|
|
201
668
|
gap: 12px;
|
|
202
|
-
|
|
669
|
+
padding: 14px 20px;
|
|
670
|
+
background: var(--surface-2);
|
|
203
671
|
}
|
|
204
672
|
|
|
205
673
|
.anim-name {
|
|
206
|
-
font-family:
|
|
207
|
-
font-size:
|
|
208
|
-
color:
|
|
209
|
-
|
|
674
|
+
font-family: var(--mono);
|
|
675
|
+
font-size: 13px;
|
|
676
|
+
color: var(--accent);
|
|
677
|
+
flex: 1;
|
|
210
678
|
}
|
|
211
679
|
|
|
212
|
-
.anim-
|
|
213
|
-
font-
|
|
214
|
-
font-
|
|
215
|
-
|
|
680
|
+
.anim-badge {
|
|
681
|
+
font-family: var(--mono);
|
|
682
|
+
font-size: 10px;
|
|
683
|
+
font-weight: 500;
|
|
684
|
+
padding: 3px 10px;
|
|
216
685
|
border-radius: 999px;
|
|
686
|
+
letter-spacing: 0.1em;
|
|
217
687
|
text-transform: uppercase;
|
|
218
|
-
letter-spacing: 0.5px;
|
|
219
688
|
}
|
|
220
689
|
|
|
221
|
-
.
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
.type-stagger { background: #2e2a0d; color: #fbbf24; }
|
|
226
|
-
.type-loop { background: #2e1a3b; color: #e879f9; }
|
|
690
|
+
.anim-body {
|
|
691
|
+
padding: 16px 20px;
|
|
692
|
+
border-top: 1px solid var(--border);
|
|
693
|
+
}
|
|
227
694
|
|
|
228
695
|
.anim-config {
|
|
229
|
-
font-family:
|
|
230
|
-
font-size:
|
|
231
|
-
color:
|
|
232
|
-
line-height: 1.
|
|
696
|
+
font-family: var(--mono);
|
|
697
|
+
font-size: 11px;
|
|
698
|
+
color: var(--ink-muted);
|
|
699
|
+
line-height: 1.7;
|
|
700
|
+
white-space: pre-wrap;
|
|
701
|
+
margin-bottom: 12px;
|
|
233
702
|
}
|
|
234
703
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
border:
|
|
239
|
-
border-radius: 6px;
|
|
704
|
+
.anim-usage {
|
|
705
|
+
background: var(--surface);
|
|
706
|
+
border: 1px solid var(--border);
|
|
707
|
+
border-radius: 3px;
|
|
240
708
|
padding: 10px 14px;
|
|
241
|
-
|
|
242
|
-
font-family: monospace;
|
|
709
|
+
font-family: var(--mono);
|
|
243
710
|
font-size: 12px;
|
|
244
711
|
color: #86efac;
|
|
245
712
|
}
|
|
246
713
|
|
|
247
|
-
/*
|
|
248
|
-
.
|
|
714
|
+
/* ── ARBITRARY SECTION ── */
|
|
715
|
+
.arbitrary-row {
|
|
249
716
|
display: flex;
|
|
250
|
-
|
|
251
|
-
gap:
|
|
717
|
+
flex-direction: column;
|
|
718
|
+
gap: 6px;
|
|
719
|
+
padding: 14px 16px;
|
|
720
|
+
border-bottom: 1px solid var(--border);
|
|
721
|
+
transition: background 0.1s;
|
|
252
722
|
}
|
|
253
723
|
|
|
254
|
-
.
|
|
255
|
-
background: #38bdf8;
|
|
256
|
-
height: 16px;
|
|
257
|
-
border-radius: 3px;
|
|
258
|
-
opacity: 0.7;
|
|
259
|
-
}
|
|
724
|
+
.arbitrary-row:hover { background: var(--surface-2); }
|
|
260
725
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
border: 1px solid #334155;
|
|
266
|
-
border-radius: 10px;
|
|
267
|
-
padding: 12px 16px;
|
|
268
|
-
color: #e2e8f0;
|
|
269
|
-
font-size: 14px;
|
|
270
|
-
margin-bottom: 32px;
|
|
271
|
-
outline: none;
|
|
272
|
-
transition: border-color 0.15s;
|
|
726
|
+
.arbitrary-cls {
|
|
727
|
+
font-family: var(--mono);
|
|
728
|
+
font-size: 12px;
|
|
729
|
+
color: var(--accent);
|
|
273
730
|
}
|
|
274
731
|
|
|
275
|
-
.
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
.stats-bar {
|
|
280
|
-
display: flex;
|
|
281
|
-
gap: 24px;
|
|
282
|
-
margin-bottom: 48px;
|
|
283
|
-
flex-wrap: wrap;
|
|
732
|
+
.arbitrary-desc {
|
|
733
|
+
font-family: var(--mono);
|
|
734
|
+
font-size: 11px;
|
|
735
|
+
color: var(--ink-muted);
|
|
284
736
|
}
|
|
285
737
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
border
|
|
290
|
-
|
|
291
|
-
|
|
738
|
+
/* ── MIZU SYNTAX ── */
|
|
739
|
+
.code-block {
|
|
740
|
+
background: var(--surface-2);
|
|
741
|
+
border: 1px solid var(--border);
|
|
742
|
+
border-radius: 4px;
|
|
743
|
+
padding: 24px;
|
|
744
|
+
font-family: var(--mono);
|
|
745
|
+
font-size: 12px;
|
|
746
|
+
line-height: 1.8;
|
|
747
|
+
color: var(--ink-muted);
|
|
748
|
+
white-space: pre;
|
|
749
|
+
overflow-x: auto;
|
|
750
|
+
margin-bottom: 24px;
|
|
292
751
|
}
|
|
293
752
|
|
|
294
|
-
.
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
}
|
|
753
|
+
.code-keyword { color: #38bdf8; }
|
|
754
|
+
.code-name { color: var(--accent); }
|
|
755
|
+
.code-value { color: #86efac; }
|
|
756
|
+
.code-comment { color: var(--ink-dim); }
|
|
299
757
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
758
|
+
/* ── MODIFIER GRID ── */
|
|
759
|
+
.modifier-grid {
|
|
760
|
+
display: grid;
|
|
761
|
+
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
|
|
762
|
+
gap: 8px;
|
|
763
|
+
margin-bottom: 24px;
|
|
304
764
|
}
|
|
305
765
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
766
|
+
.modifier-card {
|
|
767
|
+
background: var(--surface-2);
|
|
768
|
+
border: 1px solid var(--border);
|
|
769
|
+
border-radius: 4px;
|
|
770
|
+
padding: 12px 14px;
|
|
309
771
|
}
|
|
310
772
|
|
|
311
|
-
.
|
|
312
|
-
font-
|
|
313
|
-
font-
|
|
314
|
-
color:
|
|
315
|
-
|
|
316
|
-
margin-bottom: 8px;
|
|
773
|
+
.modifier-cls {
|
|
774
|
+
font-family: var(--mono);
|
|
775
|
+
font-size: 11px;
|
|
776
|
+
color: var(--accent);
|
|
777
|
+
margin-bottom: 4px;
|
|
317
778
|
}
|
|
318
779
|
|
|
319
|
-
.
|
|
320
|
-
|
|
321
|
-
font-size:
|
|
780
|
+
.modifier-val {
|
|
781
|
+
font-family: var(--mono);
|
|
782
|
+
font-size: 10px;
|
|
783
|
+
color: var(--ink-muted);
|
|
322
784
|
}
|
|
323
785
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
786
|
+
/* ── SCROLLBAR ── */
|
|
787
|
+
::-webkit-scrollbar { width: 4px; height: 4px; }
|
|
788
|
+
::-webkit-scrollbar-track { background: var(--surface); }
|
|
789
|
+
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
|
|
790
|
+
|
|
791
|
+
/* ── COPY BUTTON ── */
|
|
792
|
+
.copy-btn {
|
|
793
|
+
background: none;
|
|
794
|
+
border: 1px solid var(--border);
|
|
795
|
+
border-radius: 3px;
|
|
329
796
|
padding: 3px 10px;
|
|
330
|
-
|
|
331
|
-
font-size:
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
797
|
+
font-family: var(--mono);
|
|
798
|
+
font-size: 10px;
|
|
799
|
+
color: var(--ink-muted);
|
|
800
|
+
cursor: pointer;
|
|
801
|
+
transition: all 0.15s;
|
|
802
|
+
letter-spacing: 0.05em;
|
|
335
803
|
}
|
|
336
804
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
805
|
+
.copy-btn:hover { border-color: var(--accent); color: var(--accent); }
|
|
806
|
+
|
|
807
|
+
/* ── RESPONSIVE ── */
|
|
808
|
+
@media (max-width: 768px) {
|
|
809
|
+
.sidebar { display: none; }
|
|
810
|
+
.main { margin-left: 0; padding: 0 20px 80px; }
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
/* ── HIDDEN ── */
|
|
814
|
+
.hidden { display: none !important; }
|
|
341
815
|
</style>
|
|
342
816
|
</head>
|
|
343
817
|
<body>
|
|
344
818
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
819
|
+
<!-- SIDEBAR -->
|
|
820
|
+
<nav class="sidebar">
|
|
821
|
+
<div class="sidebar-header">
|
|
822
|
+
<div class="sidebar-logo">Mizumi 💮</div>
|
|
823
|
+
<div class="sidebar-version">v0.1.0 — Auto-generated</div>
|
|
824
|
+
</div>
|
|
351
825
|
|
|
352
|
-
|
|
826
|
+
<div class="nav-group">
|
|
827
|
+
<div class="nav-label">Overview</div>
|
|
353
828
|
<a href="#overview" class="nav-link">Overview</a>
|
|
354
|
-
|
|
355
|
-
<
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
<
|
|
360
|
-
<a href="#
|
|
361
|
-
|
|
362
|
-
<
|
|
829
|
+
<a href="#arbitrary" class="nav-link">Arbitrary Values</a>
|
|
830
|
+
<a href="#mizu-syntax" class="nav-link">.mizu Syntax</a>
|
|
831
|
+
</div>
|
|
832
|
+
|
|
833
|
+
<div class="nav-group">
|
|
834
|
+
<div class="nav-label">Design Tokens</div>
|
|
835
|
+
${this.tokens.colors ? '<a href="#colors" class="nav-link">Colors</a>' : ''}
|
|
836
|
+
${this.tokens.spacing ? '<a href="#spacing" class="nav-link">Spacing</a>' : ''}
|
|
837
|
+
${this.tokens.typography ? '<a href="#typography" class="nav-link">Typography</a>' : ''}
|
|
838
|
+
${this.tokens.fonts ? '<a href="#fonts" class="nav-link">Fonts</a>' : ''}
|
|
839
|
+
${this.tokens.radius ? '<a href="#radius" class="nav-link">Radius</a>' : ''}
|
|
840
|
+
${this.tokens.shadows ? '<a href="#shadows" class="nav-link">Shadows</a>' : ''}
|
|
841
|
+
${this.tokens.easing ? '<a href="#easing" class="nav-link">Easing</a>' : ''}
|
|
842
|
+
${this.tokens.duration ? '<a href="#duration" class="nav-link">Duration</a>' : ''}
|
|
843
|
+
${this.tokens.blur ? '<a href="#blur" class="nav-link">Blur</a>' : ''}
|
|
844
|
+
${this.tokens.opacity ? '<a href="#opacity" class="nav-link">Opacity</a>' : ''}
|
|
845
|
+
${this.tokens.zIndex ? '<a href="#zindex" class="nav-link">Z-Index</a>' : ''}
|
|
846
|
+
${this.tokens.leading ? '<a href="#leading" class="nav-link">Leading</a>' : ''}
|
|
847
|
+
${this.tokens.tracking ? '<a href="#tracking" class="nav-link">Tracking</a>' : ''}
|
|
848
|
+
</div>
|
|
849
|
+
|
|
850
|
+
<div class="nav-group">
|
|
851
|
+
<div class="nav-label">Utilities</div>
|
|
852
|
+
<a href="#token-utilities" class="nav-link">Token Utilities</a>
|
|
853
|
+
<a href="#static-utilities" class="nav-link">Static Utilities</a>
|
|
854
|
+
</div>
|
|
855
|
+
|
|
856
|
+
${patternCount > 0 ? `
|
|
857
|
+
<div class="nav-group">
|
|
858
|
+
<div class="nav-label">Patterns</div>
|
|
363
859
|
<a href="#patterns" class="nav-link">All Patterns</a>
|
|
860
|
+
</div>` : ''}
|
|
364
861
|
|
|
365
|
-
|
|
862
|
+
${animCount > 0 ? `
|
|
863
|
+
<div class="nav-group">
|
|
864
|
+
<div class="nav-label">Animations</div>
|
|
366
865
|
<a href="#animations" class="nav-link">All Animations</a>
|
|
367
866
|
<a href="#modifiers" class="nav-link">Modifiers</a>
|
|
368
|
-
</
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
<div class="stats
|
|
389
|
-
<div class="stat">
|
|
390
|
-
<
|
|
391
|
-
<
|
|
867
|
+
</div>` : ''}
|
|
868
|
+
</nav>
|
|
869
|
+
|
|
870
|
+
<!-- MAIN -->
|
|
871
|
+
<main class="main">
|
|
872
|
+
|
|
873
|
+
<!-- SEARCH -->
|
|
874
|
+
<div class="search-wrap" style="padding-top: 40px;">
|
|
875
|
+
<input class="search" type="text" placeholder="Search tokens, utilities, patterns..." oninput="handleSearch(this.value)">
|
|
876
|
+
</div>
|
|
877
|
+
|
|
878
|
+
<!-- HERO -->
|
|
879
|
+
<section class="hero" id="overview">
|
|
880
|
+
<div class="hero-eyebrow">Documentation</div>
|
|
881
|
+
<h1 class="hero-title">Mizumi<br><em>Design System</em></h1>
|
|
882
|
+
<p class="hero-sub">
|
|
883
|
+
A designer-first CSS framework. Token-based. Colon-syntax.
|
|
884
|
+
Arbitrary values. GSAP animations — all from a single config.
|
|
885
|
+
Auto-generated from your <code style="color:var(--accent);font-family:var(--mono)">mizumi.config.js</code>.
|
|
886
|
+
</p>
|
|
887
|
+
<div class="stats">
|
|
888
|
+
<div class="stat-item">
|
|
889
|
+
<span class="stat-num">${tokenCount}</span>
|
|
890
|
+
<span class="stat-label">Tokens</span>
|
|
392
891
|
</div>
|
|
393
|
-
<div class="stat">
|
|
394
|
-
<
|
|
395
|
-
<
|
|
892
|
+
<div class="stat-item">
|
|
893
|
+
<span class="stat-num">${patternCount}</span>
|
|
894
|
+
<span class="stat-label">Patterns</span>
|
|
396
895
|
</div>
|
|
397
|
-
<div class="stat">
|
|
398
|
-
<
|
|
399
|
-
<
|
|
896
|
+
<div class="stat-item">
|
|
897
|
+
<span class="stat-num">${animCount}</span>
|
|
898
|
+
<span class="stat-label">Animations</span>
|
|
400
899
|
</div>
|
|
401
|
-
<div class="stat">
|
|
402
|
-
<
|
|
403
|
-
<
|
|
900
|
+
<div class="stat-item">
|
|
901
|
+
<span class="stat-num">${bpCount}</span>
|
|
902
|
+
<span class="stat-label">Breakpoints</span>
|
|
404
903
|
</div>
|
|
405
904
|
</div>
|
|
905
|
+
</section>
|
|
406
906
|
|
|
407
|
-
|
|
408
|
-
|
|
907
|
+
<!-- COLORS -->
|
|
908
|
+
${this.tokens.colors ? `
|
|
909
|
+
<section class="section" id="colors">
|
|
910
|
+
<div class="section-header">
|
|
409
911
|
<h2 class="section-title">Colors</h2>
|
|
410
|
-
<
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
912
|
+
<span class="section-count">${Object.keys(this.tokens.colors).length} defined</span>
|
|
913
|
+
</div>
|
|
914
|
+
<table class="token-table">
|
|
915
|
+
<thead>
|
|
916
|
+
<tr>
|
|
917
|
+
<th></th>
|
|
918
|
+
<th>Token</th>
|
|
919
|
+
<th>CSS Variable</th>
|
|
920
|
+
<th>Value</th>
|
|
921
|
+
<th>Utilities</th>
|
|
922
|
+
</tr>
|
|
923
|
+
</thead>
|
|
924
|
+
<tbody>
|
|
925
|
+
${this._colorRows()}
|
|
926
|
+
</tbody>
|
|
927
|
+
</table>
|
|
928
|
+
</section>` : ''}
|
|
929
|
+
|
|
930
|
+
<!-- SPACING -->
|
|
931
|
+
${this.tokens.spacing ? `
|
|
932
|
+
<section class="section" id="spacing">
|
|
933
|
+
<div class="section-header">
|
|
417
934
|
<h2 class="section-title">Spacing</h2>
|
|
418
|
-
<
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
935
|
+
<span class="section-count">${Object.keys(this.tokens.spacing).length} defined</span>
|
|
936
|
+
</div>
|
|
937
|
+
<table class="token-table">
|
|
938
|
+
<thead>
|
|
939
|
+
<tr><th>Token</th><th>Variable</th><th>Value</th><th>Preview</th></tr>
|
|
940
|
+
</thead>
|
|
941
|
+
<tbody>
|
|
942
|
+
${Object.entries(this.tokens.spacing).map(([k, v]) => `
|
|
943
|
+
<tr class="searchable">
|
|
944
|
+
<td class="token-name">pad:${k} · mar:${k} · gap:${k}</td>
|
|
945
|
+
<td class="token-var">--spacing-${k}</td>
|
|
946
|
+
<td class="token-val">${v}</td>
|
|
947
|
+
<td><div style="width:${Math.min(parseInt(v)*1.5, 200)}px;height:12px;background:var(--accent-2);border-radius:2px;opacity:0.6;"></div></td>
|
|
948
|
+
</tr>
|
|
949
|
+
`).join('')}
|
|
950
|
+
</tbody>
|
|
951
|
+
</table>
|
|
952
|
+
</section>` : ''}
|
|
953
|
+
|
|
954
|
+
<!-- TYPOGRAPHY -->
|
|
955
|
+
${this.tokens.typography ? `
|
|
956
|
+
<section class="section" id="typography">
|
|
957
|
+
<div class="section-header">
|
|
425
958
|
<h2 class="section-title">Typography</h2>
|
|
426
|
-
<
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
959
|
+
<span class="section-count">${Object.keys(this.tokens.typography).length} scales</span>
|
|
960
|
+
</div>
|
|
961
|
+
<table class="token-table">
|
|
962
|
+
<thead>
|
|
963
|
+
<tr><th>Token</th><th>Size</th><th>Weight</th><th>Line Height</th><th>Preview</th></tr>
|
|
964
|
+
</thead>
|
|
965
|
+
<tbody>
|
|
966
|
+
${Object.entries(this.tokens.typography).map(([k, v]) => `
|
|
967
|
+
<tr class="searchable">
|
|
968
|
+
<td class="token-name">text:${k}</td>
|
|
969
|
+
<td class="token-val">${v.size || '—'}</td>
|
|
970
|
+
<td class="token-val">${v.weight || '—'}</td>
|
|
971
|
+
<td class="token-val">${v.line || '—'}</td>
|
|
972
|
+
<td style="font-size:${v.size};font-weight:${v.weight};line-height:${v.line};color:var(--ink);max-width:200px;overflow:hidden;white-space:nowrap;">Aa</td>
|
|
973
|
+
</tr>
|
|
974
|
+
`).join('')}
|
|
975
|
+
</tbody>
|
|
976
|
+
</table>
|
|
977
|
+
</section>` : ''}
|
|
978
|
+
|
|
979
|
+
<!-- FONTS -->
|
|
980
|
+
${this.tokens.fonts ? `
|
|
981
|
+
<section class="section" id="fonts">
|
|
982
|
+
<div class="section-header">
|
|
983
|
+
<h2 class="section-title">Fonts</h2>
|
|
984
|
+
<span class="section-count">${Object.keys(this.tokens.fonts).length} faces</span>
|
|
985
|
+
</div>
|
|
986
|
+
<table class="token-table">
|
|
987
|
+
<thead><tr><th>Token</th><th>Variable</th><th>Stack</th><th>Preview</th></tr></thead>
|
|
988
|
+
<tbody>
|
|
989
|
+
${Object.entries(this.tokens.fonts).map(([k, v]) => `
|
|
990
|
+
<tr class="searchable">
|
|
991
|
+
<td class="token-name">type-face:${k}</td>
|
|
992
|
+
<td class="token-var">--font-${k}</td>
|
|
993
|
+
<td class="token-val" style="font-size:11px;">${v}</td>
|
|
994
|
+
<td style="font-family:${v};font-size:18px;color:var(--ink);">The quick brown fox</td>
|
|
995
|
+
</tr>
|
|
996
|
+
`).join('')}
|
|
997
|
+
</tbody>
|
|
998
|
+
</table>
|
|
999
|
+
</section>` : ''}
|
|
1000
|
+
|
|
1001
|
+
<!-- RADIUS -->
|
|
1002
|
+
${this.tokens.radius ? `
|
|
1003
|
+
<section class="section" id="radius">
|
|
1004
|
+
<div class="section-header">
|
|
433
1005
|
<h2 class="section-title">Border Radius</h2>
|
|
434
|
-
<
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
1006
|
+
<span class="section-count">${Object.keys(this.tokens.radius).length} values</span>
|
|
1007
|
+
</div>
|
|
1008
|
+
<table class="token-table">
|
|
1009
|
+
<thead><tr><th>Preview</th><th>Token</th><th>Variable</th><th>Value</th></tr></thead>
|
|
1010
|
+
<tbody>
|
|
1011
|
+
${Object.entries(this.tokens.radius).map(([k, v]) => `
|
|
1012
|
+
<tr class="searchable">
|
|
1013
|
+
<td><div style="width:36px;height:36px;background:var(--accent-2);border-radius:${v};opacity:0.7;"></div></td>
|
|
1014
|
+
<td class="token-name">curve:${k}</td>
|
|
1015
|
+
<td class="token-var">--radius-${k}</td>
|
|
1016
|
+
<td class="token-val">${v}</td>
|
|
1017
|
+
</tr>
|
|
1018
|
+
`).join('')}
|
|
1019
|
+
</tbody>
|
|
1020
|
+
</table>
|
|
1021
|
+
</section>` : ''}
|
|
1022
|
+
|
|
1023
|
+
<!-- SHADOWS -->
|
|
1024
|
+
${this.tokens.shadows ? `
|
|
1025
|
+
<section class="section" id="shadows">
|
|
1026
|
+
<div class="section-header">
|
|
441
1027
|
<h2 class="section-title">Shadows</h2>
|
|
442
|
-
<
|
|
443
|
-
|
|
1028
|
+
<span class="section-count">${Object.keys(this.tokens.shadows).length} levels</span>
|
|
1029
|
+
</div>
|
|
1030
|
+
<table class="token-table">
|
|
1031
|
+
<thead><tr><th>Preview</th><th>Token</th><th>Variable</th><th>Value</th></tr></thead>
|
|
1032
|
+
<tbody>
|
|
1033
|
+
${Object.entries(this.tokens.shadows).map(([k, v]) => `
|
|
1034
|
+
<tr class="searchable">
|
|
1035
|
+
<td><div style="width:40px;height:28px;background:var(--surface-3);border-radius:4px;box-shadow:${v};"></div></td>
|
|
1036
|
+
<td class="token-name">cast:${k}</td>
|
|
1037
|
+
<td class="token-var">--shadow-${k}</td>
|
|
1038
|
+
<td class="token-val" style="font-size:10px;">${v}</td>
|
|
1039
|
+
</tr>
|
|
1040
|
+
`).join('')}
|
|
1041
|
+
</tbody>
|
|
1042
|
+
</table>
|
|
1043
|
+
</section>` : ''}
|
|
1044
|
+
|
|
1045
|
+
<!-- EASING -->
|
|
1046
|
+
${this.tokens.easing ? `
|
|
1047
|
+
<section class="section" id="easing">
|
|
1048
|
+
<div class="section-header">
|
|
1049
|
+
<h2 class="section-title">Easing</h2>
|
|
1050
|
+
<span class="section-count">${Object.keys(this.tokens.easing).length} curves</span>
|
|
1051
|
+
</div>
|
|
1052
|
+
<table class="token-table">
|
|
1053
|
+
<thead><tr><th>Token</th><th>Variable</th><th>Value</th></tr></thead>
|
|
1054
|
+
<tbody>
|
|
1055
|
+
${Object.entries(this.tokens.easing).map(([k, v]) => `
|
|
1056
|
+
<tr class="searchable">
|
|
1057
|
+
<td class="token-name">ease-curve:${k}</td>
|
|
1058
|
+
<td class="token-var">--ease-${k}</td>
|
|
1059
|
+
<td class="token-val">${v}</td>
|
|
1060
|
+
</tr>
|
|
1061
|
+
`).join('')}
|
|
1062
|
+
</tbody>
|
|
1063
|
+
</table>
|
|
1064
|
+
</section>` : ''}
|
|
1065
|
+
|
|
1066
|
+
<!-- DURATION -->
|
|
1067
|
+
${this.tokens.duration ? `
|
|
1068
|
+
<section class="section" id="duration">
|
|
1069
|
+
<div class="section-header">
|
|
1070
|
+
<h2 class="section-title">Duration</h2>
|
|
1071
|
+
<span class="section-count">${Object.keys(this.tokens.duration).length} speeds</span>
|
|
1072
|
+
</div>
|
|
1073
|
+
<table class="token-table">
|
|
1074
|
+
<thead><tr><th>Token</th><th>Variable</th><th>Value</th></tr></thead>
|
|
1075
|
+
<tbody>
|
|
1076
|
+
${Object.entries(this.tokens.duration).map(([k, v]) => `
|
|
1077
|
+
<tr class="searchable">
|
|
1078
|
+
<td class="token-name">ease-speed:${k} · ease-wait:${k}</td>
|
|
1079
|
+
<td class="token-var">--duration-${k}</td>
|
|
1080
|
+
<td class="token-val">${v}</td>
|
|
1081
|
+
</tr>
|
|
1082
|
+
`).join('')}
|
|
1083
|
+
</tbody>
|
|
1084
|
+
</table>
|
|
1085
|
+
</section>` : ''}
|
|
1086
|
+
|
|
1087
|
+
<!-- BLUR -->
|
|
1088
|
+
${this.tokens.blur ? `
|
|
1089
|
+
<section class="section" id="blur">
|
|
1090
|
+
<div class="section-header">
|
|
1091
|
+
<h2 class="section-title">Blur</h2>
|
|
1092
|
+
<span class="section-count">${Object.keys(this.tokens.blur).length} levels</span>
|
|
1093
|
+
</div>
|
|
1094
|
+
<table class="token-table">
|
|
1095
|
+
<thead><tr><th>Token</th><th>Variable</th><th>Value</th></tr></thead>
|
|
1096
|
+
<tbody>
|
|
1097
|
+
${Object.entries(this.tokens.blur).map(([k, v]) => `
|
|
1098
|
+
<tr class="searchable">
|
|
1099
|
+
<td class="token-name">glass-blur:${k} · glow-blur:${k}</td>
|
|
1100
|
+
<td class="token-var">--blur-${k}</td>
|
|
1101
|
+
<td class="token-val">${v}</td>
|
|
1102
|
+
</tr>
|
|
1103
|
+
`).join('')}
|
|
1104
|
+
</tbody>
|
|
1105
|
+
</table>
|
|
1106
|
+
</section>` : ''}
|
|
1107
|
+
|
|
1108
|
+
<!-- OPACITY -->
|
|
1109
|
+
${this.tokens.opacity ? `
|
|
1110
|
+
<section class="section" id="opacity">
|
|
1111
|
+
<div class="section-header">
|
|
1112
|
+
<h2 class="section-title">Opacity</h2>
|
|
1113
|
+
<span class="section-count">${Object.keys(this.tokens.opacity).length} levels</span>
|
|
1114
|
+
</div>
|
|
1115
|
+
<table class="token-table">
|
|
1116
|
+
<thead><tr><th>Preview</th><th>Token</th><th>Variable</th><th>Value</th></tr></thead>
|
|
1117
|
+
<tbody>
|
|
1118
|
+
${Object.entries(this.tokens.opacity).map(([k, v]) => `
|
|
1119
|
+
<tr class="searchable">
|
|
1120
|
+
<td><div style="width:40px;height:20px;background:var(--accent);border-radius:3px;opacity:${v};"></div></td>
|
|
1121
|
+
<td class="token-name">canvas-fade:${k}</td>
|
|
1122
|
+
<td class="token-var">--opacity-${k}</td>
|
|
1123
|
+
<td class="token-val">${v}</td>
|
|
1124
|
+
</tr>
|
|
1125
|
+
`).join('')}
|
|
1126
|
+
</tbody>
|
|
1127
|
+
</table>
|
|
1128
|
+
</section>` : ''}
|
|
1129
|
+
|
|
1130
|
+
<!-- Z-INDEX -->
|
|
1131
|
+
${this.tokens.zIndex ? `
|
|
1132
|
+
<section class="section" id="zindex">
|
|
1133
|
+
<div class="section-header">
|
|
1134
|
+
<h2 class="section-title">Z-Index</h2>
|
|
1135
|
+
<span class="section-count">${Object.keys(this.tokens.zIndex).length} layers</span>
|
|
1136
|
+
</div>
|
|
1137
|
+
<table class="token-table">
|
|
1138
|
+
<thead><tr><th>Token</th><th>Variable</th><th>Value</th></tr></thead>
|
|
1139
|
+
<tbody>
|
|
1140
|
+
${Object.entries(this.tokens.zIndex).map(([k, v]) => `
|
|
1141
|
+
<tr class="searchable">
|
|
1142
|
+
<td class="token-name">layer:${k}</td>
|
|
1143
|
+
<td class="token-var">--z-${k}</td>
|
|
1144
|
+
<td class="token-val">${v}</td>
|
|
1145
|
+
</tr>
|
|
1146
|
+
`).join('')}
|
|
1147
|
+
</tbody>
|
|
1148
|
+
</table>
|
|
1149
|
+
</section>` : ''}
|
|
1150
|
+
|
|
1151
|
+
<!-- LEADING -->
|
|
1152
|
+
${this.tokens.leading ? `
|
|
1153
|
+
<section class="section" id="leading">
|
|
1154
|
+
<div class="section-header">
|
|
1155
|
+
<h2 class="section-title">Leading</h2>
|
|
1156
|
+
<span class="section-count">${Object.keys(this.tokens.leading).length} values</span>
|
|
1157
|
+
</div>
|
|
1158
|
+
<table class="token-table">
|
|
1159
|
+
<thead><tr><th>Token</th><th>Variable</th><th>Value</th><th>Preview</th></tr></thead>
|
|
1160
|
+
<tbody>
|
|
1161
|
+
${Object.entries(this.tokens.leading).map(([k, v]) => `
|
|
1162
|
+
<tr class="searchable">
|
|
1163
|
+
<td class="token-name">leading:${k}</td>
|
|
1164
|
+
<td class="token-var">--leading-${k}</td>
|
|
1165
|
+
<td class="token-val">${v}</td>
|
|
1166
|
+
<td style="font-size:13px;line-height:${v};color:var(--ink-muted);max-width:160px;">Line one<br>Line two<br>Line three</td>
|
|
1167
|
+
</tr>
|
|
1168
|
+
`).join('')}
|
|
1169
|
+
</tbody>
|
|
1170
|
+
</table>
|
|
1171
|
+
</section>` : ''}
|
|
1172
|
+
|
|
1173
|
+
<!-- TRACKING -->
|
|
1174
|
+
${this.tokens.tracking ? `
|
|
1175
|
+
<section class="section" id="tracking">
|
|
1176
|
+
<div class="section-header">
|
|
1177
|
+
<h2 class="section-title">Tracking</h2>
|
|
1178
|
+
<span class="section-count">${Object.keys(this.tokens.tracking).length} values</span>
|
|
1179
|
+
</div>
|
|
1180
|
+
<table class="token-table">
|
|
1181
|
+
<thead><tr><th>Token</th><th>Variable</th><th>Value</th><th>Preview</th></tr></thead>
|
|
1182
|
+
<tbody>
|
|
1183
|
+
${Object.entries(this.tokens.tracking).map(([k, v]) => `
|
|
1184
|
+
<tr class="searchable">
|
|
1185
|
+
<td class="token-name">tracking:${k}</td>
|
|
1186
|
+
<td class="token-var">--tracking-${k}</td>
|
|
1187
|
+
<td class="token-val">${v}</td>
|
|
1188
|
+
<td style="font-size:12px;letter-spacing:${v};color:var(--ink-muted);font-family:var(--mono);">MIZUMI</td>
|
|
1189
|
+
</tr>
|
|
1190
|
+
`).join('')}
|
|
1191
|
+
</tbody>
|
|
1192
|
+
</table>
|
|
1193
|
+
</section>` : ''}
|
|
1194
|
+
|
|
1195
|
+
<!-- TOKEN UTILITIES -->
|
|
1196
|
+
<section class="section" id="token-utilities">
|
|
1197
|
+
<div class="section-header">
|
|
1198
|
+
<h2 class="section-title">Token Utilities</h2>
|
|
1199
|
+
<span class="section-count">Generated from your tokens</span>
|
|
1200
|
+
</div>
|
|
1201
|
+
<p style="font-family:var(--mono);font-size:12px;color:var(--ink-muted);margin-bottom:24px;line-height:1.7;">
|
|
1202
|
+
Every token automatically generates utility classes. Syntax: <span style="color:var(--accent)">capability:token-name</span>
|
|
1203
|
+
</p>
|
|
1204
|
+
${utilExamples.slice(0, 40).map(u => `
|
|
1205
|
+
<div class="utility-row searchable">
|
|
1206
|
+
<span class="utility-cls">.${u.cap}:${u.value}</span>
|
|
1207
|
+
<span class="utility-arrow">→</span>
|
|
1208
|
+
<span class="utility-css">${u.css}: var(--...)</span>
|
|
1209
|
+
</div>
|
|
1210
|
+
`).join('')}
|
|
1211
|
+
</section>
|
|
1212
|
+
|
|
1213
|
+
<!-- STATIC UTILITIES -->
|
|
1214
|
+
<section class="section" id="static-utilities">
|
|
1215
|
+
<div class="section-header">
|
|
1216
|
+
<h2 class="section-title">Static Utilities</h2>
|
|
1217
|
+
<span class="section-count">Always available</span>
|
|
1218
|
+
</div>
|
|
1219
|
+
${staticCats.map(cat => `
|
|
1220
|
+
<div class="subsection-title">${cat.name}</div>
|
|
1221
|
+
${cat.utilities.map(u => `
|
|
1222
|
+
<div class="utility-row searchable">
|
|
1223
|
+
<span class="utility-cls">.${u.cls}</span>
|
|
1224
|
+
<span class="utility-arrow">→</span>
|
|
1225
|
+
<span class="utility-css">${u.css}</span>
|
|
1226
|
+
</div>
|
|
1227
|
+
`).join('')}
|
|
1228
|
+
`).join('')}
|
|
1229
|
+
</section>
|
|
1230
|
+
|
|
1231
|
+
<!-- ARBITRARY VALUES -->
|
|
1232
|
+
<section class="section" id="arbitrary">
|
|
1233
|
+
<div class="section-header">
|
|
1234
|
+
<h2 class="section-title">Arbitrary Values</h2>
|
|
1235
|
+
<span class="section-count">Any valid CSS value</span>
|
|
1236
|
+
</div>
|
|
1237
|
+
<p style="font-family:var(--mono);font-size:12px;color:var(--ink-muted);margin-bottom:24px;line-height:1.8;">
|
|
1238
|
+
Any capability accepts raw CSS values. Use <span style="color:var(--accent)">_</span> for spaces in values.
|
|
1239
|
+
The scanner picks these up at build time and generates the exact CSS rule needed.
|
|
1240
|
+
</p>
|
|
1241
|
+
${arbitrary.map(a => `
|
|
1242
|
+
<div class="arbitrary-row searchable">
|
|
1243
|
+
<span class="arbitrary-cls">.${a.cls}</span>
|
|
1244
|
+
<span class="arbitrary-desc">${a.desc}</span>
|
|
444
1245
|
</div>
|
|
445
|
-
|
|
1246
|
+
`).join('')}
|
|
1247
|
+
</section>
|
|
446
1248
|
|
|
447
|
-
|
|
448
|
-
|
|
1249
|
+
<!-- PATTERNS -->
|
|
1250
|
+
${patternCount > 0 ? `
|
|
1251
|
+
<section class="section" id="patterns">
|
|
1252
|
+
<div class="section-header">
|
|
449
1253
|
<h2 class="section-title">Patterns</h2>
|
|
450
|
-
<
|
|
451
|
-
|
|
1254
|
+
<span class="section-count">${patternCount} defined</span>
|
|
1255
|
+
</div>
|
|
1256
|
+
<p style="font-family:var(--mono);font-size:12px;color:var(--ink-muted);margin-bottom:24px;line-height:1.7;">
|
|
1257
|
+
Reusable utility compositions. Use them like any other class.
|
|
1258
|
+
</p>
|
|
1259
|
+
${Object.entries(this.patterns).map(([name, value]) => `
|
|
1260
|
+
<div class="pattern-row searchable" onclick="togglePattern(this)">
|
|
1261
|
+
<div class="pattern-header">
|
|
1262
|
+
<span class="pattern-name">.${name}</span>
|
|
1263
|
+
<span class="pattern-toggle">expand ↓</span>
|
|
1264
|
+
</div>
|
|
1265
|
+
<div class="pattern-body">
|
|
1266
|
+
<div class="pattern-value">${value}</div>
|
|
1267
|
+
<div class="pattern-usage"><div class="${name}">...</div></div>
|
|
1268
|
+
</div>
|
|
452
1269
|
</div>
|
|
453
|
-
|
|
1270
|
+
`).join('')}
|
|
1271
|
+
</section>` : ''}
|
|
454
1272
|
|
|
455
|
-
|
|
456
|
-
|
|
1273
|
+
<!-- ANIMATIONS -->
|
|
1274
|
+
${animCount > 0 ? `
|
|
1275
|
+
<section class="section" id="animations">
|
|
1276
|
+
<div class="section-header">
|
|
457
1277
|
<h2 class="section-title">Animations</h2>
|
|
458
|
-
<
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
1278
|
+
<span class="section-count">${animCount} defined</span>
|
|
1279
|
+
</div>
|
|
1280
|
+
<p style="font-family:var(--mono);font-size:12px;color:var(--ink-muted);margin-bottom:24px;line-height:1.7;">
|
|
1281
|
+
GSAP-powered animations. Add the class name to any element.
|
|
1282
|
+
Stack modifiers like <span style="color:var(--accent)">duration-300 ease-bouncy delay-200</span> to customize.
|
|
1283
|
+
</p>
|
|
1284
|
+
${Object.entries(this.animations).map(([name, config]) => {
|
|
1285
|
+
const type = this.getAnimType(config)
|
|
1286
|
+
return `
|
|
1287
|
+
<div class="anim-row searchable">
|
|
1288
|
+
<div class="anim-header">
|
|
1289
|
+
<span class="anim-name">.${name}</span>
|
|
1290
|
+
<span class="anim-badge" style="background:${type.color}18;color:${type.color};border:1px solid ${type.color}44;">${type.label}</span>
|
|
1291
|
+
</div>
|
|
1292
|
+
<div class="anim-body">
|
|
1293
|
+
<div class="anim-config">${JSON.stringify(config, null, 2)}</div>
|
|
1294
|
+
<div class="anim-usage"><div class="${name}">...</div></div>
|
|
1295
|
+
</div>
|
|
1296
|
+
</div>`
|
|
1297
|
+
}).join('')}
|
|
1298
|
+
</section>
|
|
462
1299
|
|
|
463
|
-
|
|
464
|
-
|
|
1300
|
+
<!-- MODIFIERS -->
|
|
1301
|
+
<section class="section" id="modifiers">
|
|
1302
|
+
<div class="section-header">
|
|
465
1303
|
<h2 class="section-title">Animation Modifiers</h2>
|
|
466
|
-
<
|
|
467
|
-
|
|
468
|
-
</p>
|
|
469
|
-
|
|
470
|
-
<h3 class="section-sub">Duration</h3>
|
|
471
|
-
<div class="card-grid">
|
|
472
|
-
${[100,150,200,300,500,800,1000].map(d => `
|
|
473
|
-
<div class="doc-card">
|
|
474
|
-
<div class="doc-card-name">duration-${d}</div>
|
|
475
|
-
<div class="doc-card-value">${d}ms → ${d/1000}s</div>
|
|
476
|
-
</div>
|
|
477
|
-
`).join('')}
|
|
478
|
-
${['fast','normal','slow','slower'].map(n => `
|
|
479
|
-
<div class="doc-card">
|
|
480
|
-
<div class="doc-card-name">duration-${n}</div>
|
|
481
|
-
<div class="doc-card-value">Token-based</div>
|
|
482
|
-
</div>
|
|
483
|
-
`).join('')}
|
|
484
|
-
</div>
|
|
485
|
-
|
|
486
|
-
<h3 class="section-sub">Delay</h3>
|
|
487
|
-
<div class="card-grid">
|
|
488
|
-
${[0,100,150,200,300,500,1000].map(d => `
|
|
489
|
-
<div class="doc-card">
|
|
490
|
-
<div class="doc-card-name">delay-${d}</div>
|
|
491
|
-
<div class="doc-card-value">${d}ms → ${d/1000}s</div>
|
|
492
|
-
</div>
|
|
493
|
-
`).join('')}
|
|
494
|
-
</div>
|
|
1304
|
+
<span class="section-count">Stack onto any animation</span>
|
|
1305
|
+
</div>
|
|
495
1306
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
1307
|
+
<div class="subsection-title">Duration</div>
|
|
1308
|
+
<div class="modifier-grid">
|
|
1309
|
+
${[100,150,200,300,500,800,1000].map(d => `
|
|
1310
|
+
<div class="modifier-card">
|
|
1311
|
+
<div class="modifier-cls">duration-${d}</div>
|
|
1312
|
+
<div class="modifier-val">${d}ms</div>
|
|
1313
|
+
</div>
|
|
1314
|
+
`).join('')}
|
|
1315
|
+
${['fast','normal','slow','slower'].map(n => `
|
|
1316
|
+
<div class="modifier-card">
|
|
1317
|
+
<div class="modifier-cls">duration-${n}</div>
|
|
1318
|
+
<div class="modifier-val">token-based</div>
|
|
1319
|
+
</div>
|
|
1320
|
+
`).join('')}
|
|
1321
|
+
</div>
|
|
505
1322
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
</section>
|
|
516
|
-
|
|
517
|
-
</main>
|
|
518
|
-
|
|
519
|
-
<script>
|
|
520
|
-
// Search functionality
|
|
521
|
-
function handleSearch(query) {
|
|
522
|
-
const q = query.toLowerCase().trim();
|
|
523
|
-
const allRows = document.querySelectorAll(
|
|
524
|
-
'.doc-card, .pattern-row, .anim-row'
|
|
525
|
-
);
|
|
526
|
-
|
|
527
|
-
allRows.forEach(row => {
|
|
528
|
-
const text = row.textContent.toLowerCase();
|
|
529
|
-
row.style.display = !q || text.includes(q) ? '' : 'none';
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
// Smooth scroll for nav links
|
|
534
|
-
document.querySelectorAll('.nav-link').forEach(link => {
|
|
535
|
-
link.addEventListener('click', e => {
|
|
536
|
-
e.preventDefault();
|
|
537
|
-
const target = document.querySelector(link.getAttribute('href'));
|
|
538
|
-
if (target) target.scrollIntoView({ behavior: 'smooth' });
|
|
539
|
-
});
|
|
540
|
-
});
|
|
541
|
-
</script>
|
|
1323
|
+
<div class="subsection-title">Delay</div>
|
|
1324
|
+
<div class="modifier-grid">
|
|
1325
|
+
${[0,100,150,200,300,500,1000].map(d => `
|
|
1326
|
+
<div class="modifier-card">
|
|
1327
|
+
<div class="modifier-cls">delay-${d}</div>
|
|
1328
|
+
<div class="modifier-val">${d}ms</div>
|
|
1329
|
+
</div>
|
|
1330
|
+
`).join('')}
|
|
1331
|
+
</div>
|
|
542
1332
|
|
|
543
|
-
</
|
|
544
|
-
|
|
545
|
-
|
|
1333
|
+
<div class="subsection-title">Easing</div>
|
|
1334
|
+
<div class="modifier-grid">
|
|
1335
|
+
${['smooth','bouncy','sharp','back','linear'].map(e => `
|
|
1336
|
+
<div class="modifier-card">
|
|
1337
|
+
<div class="modifier-cls">ease-${e}</div>
|
|
1338
|
+
<div class="modifier-val">GSAP curve</div>
|
|
1339
|
+
</div>
|
|
1340
|
+
`).join('')}
|
|
1341
|
+
</div>
|
|
546
1342
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
1343
|
+
<div class="subsection-title">Prop Overrides (inline)</div>
|
|
1344
|
+
<div class="modifier-grid">
|
|
1345
|
+
${['data-gsap-duration','data-gsap-delay','data-gsap-ease','data-gsap-y','data-gsap-x','data-gsap-scale','data-gsap-opacity'].map(a => `
|
|
1346
|
+
<div class="modifier-card">
|
|
1347
|
+
<div class="modifier-cls" style="font-size:9px;">${a}</div>
|
|
1348
|
+
<div class="modifier-val">highest priority</div>
|
|
1349
|
+
</div>
|
|
1350
|
+
`).join('')}
|
|
1351
|
+
</div>
|
|
1352
|
+
</section>` : ''}
|
|
550
1353
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
<div class="doc-card">
|
|
569
|
-
<div class="color-swatch" style="background:${v};"></div>
|
|
570
|
-
<div class="doc-card-name">${k}</div>
|
|
571
|
-
<div class="doc-card-value">${v}</div>
|
|
572
|
-
<div class="doc-card-value" style="margin-top:4px;">
|
|
573
|
-
bg-${k} · color-${k}
|
|
574
|
-
</div>
|
|
575
|
-
</div>
|
|
576
|
-
`);
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
return cards.join('');
|
|
1354
|
+
<!-- .MIZU SYNTAX -->
|
|
1355
|
+
<section class="section" id="mizu-syntax">
|
|
1356
|
+
<div class="section-header">
|
|
1357
|
+
<h2 class="section-title">.mizu Syntax</h2>
|
|
1358
|
+
<span class="section-count">CSS-style config</span>
|
|
1359
|
+
</div>
|
|
1360
|
+
<p style="font-family:var(--mono);font-size:12px;color:var(--ink-muted);margin-bottom:24px;line-height:1.7;">
|
|
1361
|
+
An alternative to <span style="color:var(--accent)">mizumi.config.js</span>.
|
|
1362
|
+
Create any <span style="color:var(--accent)">*.mizu</span> file in your project —
|
|
1363
|
+
it's auto-discovered and merged. No imports needed.
|
|
1364
|
+
</p>
|
|
1365
|
+
<div class="code-block"><span class="code-comment">/* styles.mizu — auto-discovered, no imports needed */</span>
|
|
1366
|
+
|
|
1367
|
+
<span class="code-keyword">@token</span> {
|
|
1368
|
+
colors {
|
|
1369
|
+
<span class="code-name">brand</span>: <span class="code-value">#ff6b6b</span>;
|
|
1370
|
+
<span class="code-name">ocean</span>: <span class="code-value">#006994</span>;
|
|
580
1371
|
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
return Object.entries(this.tokens.spacing).map(([k, v]) => {
|
|
585
|
-
const px = parseInt(v);
|
|
586
|
-
return `
|
|
587
|
-
<div class="pattern-row">
|
|
588
|
-
<div class="pattern-name">pad-${k} · mar-${k} · gap-${k}</div>
|
|
589
|
-
<div class="spacing-preview">
|
|
590
|
-
<div class="spacing-bar" style="width:${Math.min(px * 2, 200)}px;"></div>
|
|
591
|
-
<span style="color:#64748b; font-size:13px;">${v}</span>
|
|
592
|
-
</div>
|
|
593
|
-
</div>
|
|
594
|
-
`;
|
|
595
|
-
}).join('');
|
|
1372
|
+
spacing {
|
|
1373
|
+
<span class="code-name">hero</span>: <span class="code-value">120px</span>;
|
|
1374
|
+
<span class="code-name">section</span>: <span class="code-value">80px</span>;
|
|
596
1375
|
}
|
|
1376
|
+
}
|
|
597
1377
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
<div style="font-size:${v.size}; font-weight:${v.weight}; line-height:${v.line}; color:#e2e8f0; margin-bottom:4px;">
|
|
605
|
-
The quick brown fox
|
|
606
|
-
</div>
|
|
607
|
-
<div style="font-size:12px; color:#64748b;">
|
|
608
|
-
${v.size} · weight ${v.weight} · line ${v.line}
|
|
609
|
-
</div>
|
|
610
|
-
</div>
|
|
611
|
-
</div>
|
|
612
|
-
`).join('');
|
|
613
|
-
}
|
|
1378
|
+
<span class="code-keyword">@pattern</span> hero-box {
|
|
1379
|
+
<span class="code-name">pad</span>: <span class="code-value">hero</span>;
|
|
1380
|
+
<span class="code-name">paint</span>: <span class="code-value">brand</span>;
|
|
1381
|
+
<span class="code-name">ink</span>: <span class="code-value">white</span>;
|
|
1382
|
+
<span class="code-name">curve</span>: <span class="code-value">xl</span>;
|
|
1383
|
+
}
|
|
614
1384
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
<div style="
|
|
620
|
-
width:48px; height:48px;
|
|
621
|
-
background:#38bdf8;
|
|
622
|
-
border-radius:${v};
|
|
623
|
-
margin:0 auto 12px;
|
|
624
|
-
opacity:0.7;
|
|
625
|
-
"></div>
|
|
626
|
-
<div class="doc-card-name">rounded-${k}</div>
|
|
627
|
-
<div class="doc-card-value">${v}</div>
|
|
628
|
-
</div>
|
|
629
|
-
`).join('');
|
|
630
|
-
}
|
|
1385
|
+
<span class="code-keyword">@pattern</span> btn-brand <span class="code-keyword">extends</span> button {
|
|
1386
|
+
<span class="code-name">paint</span>: <span class="code-value">brand</span>;
|
|
1387
|
+
<span class="code-name">ink</span>: <span class="code-value">white</span>;
|
|
1388
|
+
}
|
|
631
1389
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
<div class="pattern-name">shadow-${k}</div>
|
|
637
|
-
<div style="
|
|
638
|
-
width:60px; height:32px;
|
|
639
|
-
background:#1e293b;
|
|
640
|
-
border-radius:6px;
|
|
641
|
-
box-shadow:${v};
|
|
642
|
-
flex-shrink:0;
|
|
643
|
-
"></div>
|
|
644
|
-
<div class="doc-card-value" style="font-family:monospace; font-size:12px;">${v}</div>
|
|
645
|
-
</div>
|
|
646
|
-
`).join('');
|
|
1390
|
+
<span class="code-keyword">@animate</span> hover-brand {
|
|
1391
|
+
hover {
|
|
1392
|
+
<span class="code-name">move-y</span>: <span class="code-value">-6px</span>;
|
|
1393
|
+
<span class="code-name">ease-speed</span>: <span class="code-value">fast</span>;
|
|
647
1394
|
}
|
|
1395
|
+
}
|
|
648
1396
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
1397
|
+
<span class="code-keyword">@rule</span> {
|
|
1398
|
+
<span class="code-name">responsive</span>: <span class="code-value">true</span>;
|
|
1399
|
+
<span class="code-name">darkMode</span>: <span class="code-value">class</span>;
|
|
1400
|
+
}</div>
|
|
1401
|
+
</section>
|
|
1402
|
+
|
|
1403
|
+
</main>
|
|
1404
|
+
|
|
1405
|
+
<script>
|
|
1406
|
+
// ── Search ──
|
|
1407
|
+
function handleSearch(query) {
|
|
1408
|
+
const q = query.toLowerCase().trim()
|
|
1409
|
+
document.querySelectorAll('.searchable').forEach(el => {
|
|
1410
|
+
const text = el.textContent.toLowerCase()
|
|
1411
|
+
el.classList.toggle('hidden', q !== '' && !text.includes(q))
|
|
1412
|
+
})
|
|
660
1413
|
}
|
|
661
1414
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
<div class="anim-name">.${name}</div>
|
|
669
|
-
<span class="anim-type type-${type}">${type}</span>
|
|
670
|
-
</div>
|
|
671
|
-
<div class="anim-config">${JSON.stringify(config, null, 2)}</div>
|
|
672
|
-
<div class="usage-box">
|
|
673
|
-
<div class="${name}">...</div>
|
|
674
|
-
</div>
|
|
675
|
-
</div>
|
|
676
|
-
`;
|
|
677
|
-
}).join('');
|
|
1415
|
+
// ── Pattern toggle ──
|
|
1416
|
+
function togglePattern(el) {
|
|
1417
|
+
const body = el.querySelector('.pattern-body')
|
|
1418
|
+
const toggle = el.querySelector('.pattern-toggle')
|
|
1419
|
+
const open = body.classList.toggle('open')
|
|
1420
|
+
toggle.textContent = open ? 'collapse ↑' : 'expand ↓'
|
|
678
1421
|
}
|
|
679
1422
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
}
|
|
1423
|
+
// ── Smooth scroll ──
|
|
1424
|
+
document.querySelectorAll('.nav-link').forEach(link => {
|
|
1425
|
+
link.addEventListener('click', e => {
|
|
1426
|
+
e.preventDefault()
|
|
1427
|
+
const target = document.querySelector(link.getAttribute('href'))
|
|
1428
|
+
if (target) target.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
1429
|
+
})
|
|
1430
|
+
})
|
|
1431
|
+
|
|
1432
|
+
// ── Copy on click ──
|
|
1433
|
+
document.querySelectorAll('.utility-cls, .arbitrary-cls, .pattern-name, .anim-name').forEach(el => {
|
|
1434
|
+
el.style.cursor = 'pointer'
|
|
1435
|
+
el.title = 'Click to copy'
|
|
1436
|
+
el.addEventListener('click', () => {
|
|
1437
|
+
const text = el.textContent.replace(/^\./, '')
|
|
1438
|
+
navigator.clipboard?.writeText(text)
|
|
1439
|
+
const orig = el.textContent
|
|
1440
|
+
el.textContent = '✓ copied'
|
|
1441
|
+
setTimeout(() => el.textContent = orig, 1000)
|
|
1442
|
+
})
|
|
1443
|
+
})
|
|
1444
|
+
</script>
|
|
688
1445
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
smooth: 'power2.out',
|
|
692
|
-
bouncy: 'elastic.out(1, 0.5)',
|
|
693
|
-
sharp: 'power4.inOut',
|
|
694
|
-
back: 'back.out(1.7)',
|
|
695
|
-
linear: 'none'
|
|
696
|
-
};
|
|
697
|
-
return map[name] || name;
|
|
1446
|
+
</body>
|
|
1447
|
+
</html>`
|
|
698
1448
|
}
|
|
699
1449
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
1450
|
+
// ── Color rows helper ──
|
|
1451
|
+
_colorRows() {
|
|
1452
|
+
const rows = []
|
|
1453
|
+
for (const [key, val] of Object.entries(this.tokens.colors)) {
|
|
1454
|
+
if (typeof val === 'object') {
|
|
1455
|
+
for (const [shade, color] of Object.entries(val)) {
|
|
1456
|
+
const name = shade === 'DEFAULT' ? key : `${key}-${shade}`
|
|
1457
|
+
rows.push(`
|
|
1458
|
+
<tr class="searchable">
|
|
1459
|
+
<td><div class="color-chip" style="background:${color};"></div></td>
|
|
1460
|
+
<td class="token-name">ink:${name} · paint:${name}</td>
|
|
1461
|
+
<td class="token-var">--color-${name}</td>
|
|
1462
|
+
<td class="token-val">${color}</td>
|
|
1463
|
+
<td class="token-val" style="font-size:10px;">ink · paint · stroke-color · ring-color</td>
|
|
1464
|
+
</tr>`)
|
|
707
1465
|
}
|
|
1466
|
+
} else {
|
|
1467
|
+
rows.push(`
|
|
1468
|
+
<tr class="searchable">
|
|
1469
|
+
<td><div class="color-chip" style="background:${val};"></div></td>
|
|
1470
|
+
<td class="token-name">ink:${key} · paint:${key}</td>
|
|
1471
|
+
<td class="token-var">--color-${key}</td>
|
|
1472
|
+
<td class="token-val">${val}</td>
|
|
1473
|
+
<td class="token-val" style="font-size:10px;">ink · paint · stroke-color · ring-color</td>
|
|
1474
|
+
</tr>`)
|
|
708
1475
|
}
|
|
709
1476
|
}
|
|
710
|
-
return
|
|
1477
|
+
return rows.join('')
|
|
711
1478
|
}
|
|
712
|
-
}
|
|
713
|
-
|
|
1479
|
+
}
|