@askewly/design 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Yusung Jun
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # @askewly/design
2
+
3
+ Query, inject, and verify the [Askewly Design](https://ui.askewly.com) system from your terminal or coding agent.
4
+
5
+ ```bash
6
+ npx @askewly/design verify src
7
+ ```
8
+
9
+ ## Commands
10
+
11
+ | Command | What it does |
12
+ |---|---|
13
+ | `verify [dir]` | Scan for color values that bypass the token system — hex literals and raw `rgb()`/`hsl()`/`oklch()`. Comments and SVG markup are exempt. |
14
+ | `terms search <query>` | Search the UI vocabulary (562 terms, Korean + English). |
15
+ | `terms show <id>` | Definition, aliases, visual anatomy, anti-use cases, prompt phrases. |
16
+ | `tokens` | Print the design token set. |
17
+ | `init [dir]` | Drop token CSS into a project. |
18
+ | `add <recipe>` | Add a component recipe. |
19
+ | `recipes list` / `recipes show <id>` | Agent-ready implementation contracts (45 recipes). |
20
+
21
+ ## Why `verify` exists
22
+
23
+ A screenshot cannot tell `#3B82F6` from `var(--color-accent)` — they render identically. Whether a screen actually uses the token system is a question for a machine, not an eye.
24
+
25
+ `verify` exits `1` on violations and prints `file:line [rule] excerpt`, so a coding agent can read the list, fix, and re-measure.
26
+
27
+ Exempt by design: generated token files (`tokens.css`, `askewly.css`), build directories, comments, and SVG markup.
28
+
29
+ ## License
30
+
31
+ MIT
package/data/DESIGN.md ADDED
@@ -0,0 +1,224 @@
1
+ ---
2
+ # GENERATED tokens/themes from tokens/askewly.tokens.json — edit the SSOT, then regenerate
3
+ name: "Askewly Design"
4
+ version: "0.2.0"
5
+
6
+ tokens:
7
+ color:
8
+ primitive:
9
+ white: { value: {"colorSpace":"oklch","components":[1,0,0]}, type: color }
10
+ gray:
11
+ "1": { value: {"colorSpace":"oklch","components":[0.985,0,0]}, type: color }
12
+ "2": { value: {"colorSpace":"oklch","components":[0.97,0.005,270]}, type: color }
13
+ "3": { value: {"colorSpace":"oklch","components":[0.95,0.015,270]}, type: color }
14
+ "4": { value: {"colorSpace":"oklch","components":[0.94,0.02,270]}, type: color }
15
+ "5": { value: {"colorSpace":"oklch","components":[0.91,0.015,270]}, type: color }
16
+ "6": { value: {"colorSpace":"oklch","components":[0.88,0.015,270]}, type: color }
17
+ "7": { value: {"colorSpace":"oklch","components":[0.72,0.02,270]}, type: color }
18
+ "8": { value: {"colorSpace":"oklch","components":[0.6,0.025,270]}, type: color }
19
+ "9": { value: {"colorSpace":"oklch","components":[0.46,0.03,270]}, type: color }
20
+ "10": { value: {"colorSpace":"oklch","components":[0.35,0.03,270]}, type: color }
21
+ "11": { value: {"colorSpace":"oklch","components":[0.25,0.03,270]}, type: color }
22
+ "12": { value: {"colorSpace":"oklch","components":[0.16,0.015,270]}, type: color }
23
+ askewly:
24
+ violet: { value: {"colorSpace":"srgb","components":[0.435294,0.176471,0.741176],"hex":"#6F2DBD"}, type: color }
25
+ orchid: { value: {"colorSpace":"srgb","components":[0.65098,0.388235,0.8],"hex":"#A663CC"}, type: color }
26
+ lavender: { value: {"colorSpace":"srgb","components":[0.698039,0.596078,0.862745],"hex":"#B298DC"}, type: color }
27
+ sky: { value: {"colorSpace":"srgb","components":[0.721569,0.815686,0.921569],"hex":"#B8D0EB"}, type: color }
28
+ mint: { value: {"colorSpace":"srgb","components":[0.72549,0.980392,0.972549],"hex":"#B9FAF8"}, type: color }
29
+ red:
30
+ "9": { value: {"colorSpace":"oklch","components":[0.58,0.22,27]}, type: color }
31
+ semantic:
32
+ surface:
33
+ base: { value: "{color.primitive.gray.1}", type: color }
34
+ raised: { value: "{color.primitive.white}", type: color }
35
+ overlay: { value: "{color.primitive.white}", type: color }
36
+ muted: { value: "{color.primitive.gray.3}", type: color }
37
+ secondary: { value: "{color.primitive.gray.4}", type: color }
38
+ tint: { value: "{color.primitive.askewly.mint}", type: color }
39
+ text:
40
+ default: { value: "{color.primitive.gray.12}", type: color }
41
+ muted: { value: "{color.primitive.gray.9}", type: color }
42
+ secondary: { value: "{color.primitive.gray.11}", type: color }
43
+ on-accent: { value: "{color.primitive.gray.1}", type: color }
44
+ action:
45
+ primary: { value: "{color.primitive.askewly.violet}", type: color }
46
+ secondary: { value: "{color.primitive.askewly.orchid}", type: color }
47
+ destructive: { value: "{color.primitive.red.9}", type: color }
48
+ accent:
49
+ base: { value: "{color.primitive.askewly.mint}", type: color }
50
+ foreground: { value: "{color.primitive.gray.12}", type: color }
51
+ border:
52
+ default: { value: "{color.primitive.gray.6}", type: color }
53
+ input: { value: "{color.primitive.gray.6}", type: color }
54
+ focus: { value: "{color.primitive.askewly.violet}", type: color }
55
+ accent: { value: "{color.primitive.askewly.lavender}", type: color }
56
+ component:
57
+ button:
58
+ bg: { value: "{color.semantic.action.primary}", type: color }
59
+ text: { value: "{color.semantic.text.on-accent}", type: color }
60
+
61
+ dimension:
62
+ space:
63
+ "1": { value: "4px", type: dimension }
64
+ "2": { value: "8px", type: dimension }
65
+ "4": { value: "16px", type: dimension }
66
+ "8": { value: "32px", type: dimension }
67
+ "12": { value: "48px", type: dimension }
68
+ "16": { value: "64px", type: dimension }
69
+ radius:
70
+ sm: { value: "4px", type: dimension }
71
+ md: { value: "6px", type: dimension }
72
+ lg: { value: "8px", type: dimension }
73
+ xl: { value: "12px", type: dimension }
74
+ 2xl: { value: "16px", type: dimension }
75
+
76
+ typography:
77
+ font:
78
+ sans: { value: "Geist, Noto Sans KR, ui-sans-serif, system-ui, sans-serif", type: fontFamily }
79
+ mono: { value: "Geist Mono, ui-monospace, monospace", type: fontFamily }
80
+ scale:
81
+ sm: { value: "14px", type: dimension }
82
+ base: { value: "16px", type: dimension }
83
+ lg: { value: "20px", type: dimension }
84
+ xl: { value: "28px", type: dimension }
85
+ 2xl: { value: "40px", type: dimension }
86
+ weight:
87
+ regular: { value: 400, type: fontWeight }
88
+ medium: { value: 500, type: fontWeight }
89
+
90
+ themes:
91
+ default: { base: true }
92
+ dark:
93
+ color.semantic.surface.base: { value: "{color.primitive.gray.12}", type: color }
94
+ color.semantic.surface.raised: { value: "{color.primitive.gray.11}", type: color }
95
+ color.semantic.surface.overlay: { value: "{color.primitive.gray.11}", type: color }
96
+ color.semantic.surface.muted: { value: "{color.primitive.gray.10}", type: color }
97
+ color.semantic.surface.secondary: { value: "{color.primitive.gray.10}", type: color }
98
+ color.semantic.surface.tint: { value: "{color.primitive.gray.10}", type: color }
99
+ color.semantic.text.default: { value: "{color.primitive.gray.1}", type: color }
100
+ color.semantic.text.muted: { value: "{color.primitive.gray.7}", type: color }
101
+ color.semantic.text.secondary: { value: "{color.primitive.gray.3}", type: color }
102
+ color.semantic.text.on-accent: { value: "{color.primitive.gray.12}", type: color }
103
+ color.semantic.action.primary: { value: "{color.primitive.gray.1}", type: color }
104
+ color.semantic.action.secondary: { value: "{color.primitive.askewly.mint}", type: color }
105
+ color.semantic.action.destructive: { value: "{color.primitive.red.9}", type: color }
106
+ color.semantic.accent.base: { value: "{color.primitive.gray.10}", type: color }
107
+ color.semantic.accent.foreground: { value: "{color.primitive.gray.1}", type: color }
108
+ color.semantic.border.default: { value: "{color.primitive.gray.10}", type: color }
109
+ color.semantic.border.input: { value: "{color.primitive.gray.10}", type: color }
110
+ color.semantic.border.focus: { value: "{color.primitive.askewly.lavender}", type: color }
111
+ color.semantic.border.accent: { value: "{color.primitive.askewly.orchid}", type: color }
112
+ ---
113
+
114
+ # Askewly Design — White System / Intentional Asymmetry
115
+
116
+ ## 1. Personality
117
+ 화이트 기반의 조용한 제품 디자인 시스템. 첫 화면은 중앙 hero 제목으로 시작하고, 색은 팔레트 전체를 뿌리는 장식이 아니라 제품 표면과 상태를 구분하는 신호로만 쓴다.
118
+
119
+ Askewly는 "살짝 비틀렸지만 의도적인" 브랜드다. 레이아웃은 정돈되어야 하지만, 작은 비대칭, 겹침, 단계적 색 전환으로 사람이 설계한 긴장을 남긴다.
120
+
121
+ ## 2. Color
122
+ 기본 테마는 white. 배경은 거의 흰색이고, 본문은 고대비 charcoal을 쓴다.
123
+
124
+ Extracted palette from landing planning reference image:
125
+
126
+ - Violet: `#6F2DBD` — primary action, selected state, strongest brand mark.
127
+ - Orchid: `#A663CC` — secondary accent, hover, active navigation underline.
128
+ - Lavender: `#B298DC` — soft border, muted badge, chart/pattern highlight.
129
+ - Sky: `#B8D0EB` — informational surface, preview panel wash.
130
+ - Mint: `#B9FAF8` — success/agent-ready signal, light hero glow.
131
+
132
+ Do not turn the whole page purple. Use the palette as a controlled five-step spectrum in the hero proof surface, selected chips, small gradients, and state indicators.
133
+
134
+ ## 3. Typography
135
+ Geist is the primary Latin UI face. Noto Sans KR is the Korean fallback in the same sans stack because Geist does not cover Korean reliably. Geist Mono is reserved for code, token names, keyboard shortcuts, and agent-facing technical labels.
136
+
137
+ - Hero title: 72-96px desktop, 44-56px mobile, line-height 0.95-1.05.
138
+ - Section heading: 32-44px.
139
+ - Body: 16-18px, relaxed but not editorial.
140
+ - Korean UI/body copy uses `Noto Sans KR` through the shared sans stack.
141
+ - Technical labels and code snippets use `Geist Mono`.
142
+ - Do not use negative letter spacing except where the existing type scale already requires optical tightening in the hero.
143
+
144
+ ## 4. Spacing & Layout
145
+ Landing first viewport:
146
+
147
+ - Top navigation stays compact and close to the current site shell: Askewly Design / Docs / Patterns / Showcase / Resources / Pro.
148
+ - Hero copy sits centered, not split left/right.
149
+ - Hero should show the product promise before scroll: a design-system website for humans plus an agent-usable system for Codex/Claude Code.
150
+ - Keep enough of the next section visible on desktop and mobile, so the page does not feel like a dead poster.
151
+
152
+ General layout:
153
+
154
+ - Container max 1120-1200px.
155
+ - Use `space.12` and `space.16` for major vertical rhythm.
156
+ - Use a single strong focal area per viewport.
157
+ - Below the hero, prefer full-width bands or unframed grids over nested cards.
158
+
159
+ ## 5. Radius & Borders
160
+ Small radius only. Cards and framed previews should stay at 4px or below unless a real browser/device mockup needs a slightly larger corner.
161
+
162
+ Use hairline borders for structure. Use `border.accent` only for selected/active states or subtle hero preview edges.
163
+
164
+ ## 6. Elevation & Motion
165
+ No heavy drop shadows. Use borders, spacing, tint surfaces, and subtle opacity/translate motion.
166
+
167
+ Motion rules:
168
+
169
+ - The still frame must work before animation.
170
+ - Motion should explain focus, state, or progression.
171
+ - Hero segmented preview changes can crossfade/slide 120-180ms.
172
+ - Respect reduced motion.
173
+
174
+ ## 7. Components
175
+ ### Landing Hero
176
+ - White background.
177
+ - Centered product name or direct product promise.
178
+ - Primary CTA: `Explore Patterns`.
179
+ - Secondary CTA: `Open Docs`.
180
+ - Supporting copy should mention both surfaces: public UI reference website and agent-facing design system.
181
+ - Below the centered title, show one restrained proof surface rather than many unrelated decorative cards.
182
+
183
+ ### Hero Proof Surface
184
+ - Show a compact design-system workspace: left nav, central preview, right inspector.
185
+ - The proof surface can include Docs, Patterns, Showcase, Resources, and Pro as visible labels.
186
+ - Use palette spectrum as tiny state chips or inspector accents.
187
+ - Must not look like a generic SaaS analytics dashboard unless the selected mode is Dashboard.
188
+
189
+ ### Top Navigation
190
+ - Keep the current compressed nav model.
191
+ - Use text labels: Docs, Patterns, Showcase, Resources, Pro.
192
+ - Active/hover state may use Violet/Orchid underline or text shift.
193
+
194
+ ### Button
195
+ - height 40 (hero CTA는 44), padding-x 24. radius `lg` (8px).
196
+ - primary: Violet background / white text. hover opacity 0.9.
197
+ - secondary: 투명 / 1px 보더.
198
+ - 완전한 pill(`rounded-full`)은 쓰지 않는다 — §8 anti-pattern. 8px 라운드가 Askewly의 "살짝 부드럽되 각이 남는" 기본값이다.
199
+
200
+ ### Input
201
+ - 보더 없음, bottom-border 1px. focus 시 2px.
202
+
203
+ ### Card
204
+ - 보더만. 패딩 32. 그림자 없음.
205
+
206
+ ## 8. Anti-patterns
207
+ - Purple-dominated page.
208
+ - Generic SaaS dashboard hero with fake metrics and no design-system meaning.
209
+ - Split hero with text on one side and card/mockup on the other.
210
+ - Decorative blob/orb backgrounds.
211
+ - Nested cards inside cards.
212
+ - Heavy shadows, oversized rounded pills, or one-note gradient surfaces.
213
+ - Motion that runs forever without communicating state.
214
+
215
+ ## 9. Changelog
216
+ ## 2026-07-07
217
+ - Button radius `sm`(4px) → `lg`(8px)로 확정 (Figma 배리에이션 A/B/C 중 B 픽, PSS2 Step 11a). hero CTA·탑바 Pro Plan `rounded-full` 제거. §8 pill anti-pattern과 코드가 이제 정합.
218
+
219
+ ## 2026-07-05
220
+ - Bootstrapped design-manual Minimal family and rewrote it as Askewly Design landing guidance.
221
+ - Extracted planning palette from user reference image: `#6F2DBD`, `#A663CC`, `#B298DC`, `#B8D0EB`, `#B9FAF8`.
222
+
223
+ ## 2026-05-14
224
+ - 초안.
@@ -0,0 +1,38 @@
1
+ /* GENERATED by @askewly/design — imports the token custom properties and binds
2
+ them to Tailwind v4 utilities. Usage in your global stylesheet:
3
+ @import "tailwindcss"; @import "./askewly.css"; */
4
+ @import "./tokens.css";
5
+
6
+ @custom-variant dark (&:is(.dark *));
7
+
8
+ @theme inline {
9
+ --font-sans: Geist, "Noto Sans KR", ui-sans-serif, system-ui, sans-serif;
10
+ --font-mono: "Geist Mono", ui-monospace, monospace;
11
+ --color-background: var(--background);
12
+ --color-foreground: var(--foreground);
13
+ --color-card: var(--card);
14
+ --color-card-foreground: var(--card-foreground);
15
+ --color-popover: var(--popover);
16
+ --color-popover-foreground: var(--popover-foreground);
17
+ --color-primary: var(--primary);
18
+ --color-primary-foreground: var(--primary-foreground);
19
+ --color-secondary: var(--secondary);
20
+ --color-secondary-foreground: var(--secondary-foreground);
21
+ --color-muted: var(--muted);
22
+ --color-muted-foreground: var(--muted-foreground);
23
+ --color-accent: var(--accent);
24
+ --color-accent-foreground: var(--accent-foreground);
25
+ --color-destructive: var(--destructive);
26
+ --color-border: var(--border);
27
+ --color-input: var(--input);
28
+ --color-ring: var(--ring);
29
+ --radius-sm: calc(var(--radius) - 4px);
30
+ --radius-md: calc(var(--radius) - 2px);
31
+ --radius-lg: var(--radius);
32
+ --radius-xl: calc(var(--radius) + 4px);
33
+ --color-askewly-violet: var(--askewly-violet);
34
+ --color-askewly-orchid: var(--askewly-orchid);
35
+ --color-askewly-lavender: var(--askewly-lavender);
36
+ --color-askewly-sky: var(--askewly-sky);
37
+ --color-askewly-mint: var(--askewly-mint);
38
+ }