@iyulab/house-style 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.
@@ -0,0 +1,78 @@
1
+ /*
2
+ * @iyulab/house-style โ€” Tailwind CSS v4 entry
3
+ * ==========================================================================
4
+ * A Tailwind v4 app imports this file โ€” and only this file โ€” from its Tailwind entry:
5
+ *
6
+ * @import 'tailwindcss';
7
+ * @import '@iyulab/house-style/styles/tailwind.css';
8
+ *
9
+ * ๐Ÿ”ดWhy not `import '@iyulab/house-style'` from JS in a Tailwind app: Tailwind declares
10
+ * `@layer theme, base, components, utilities` after `iyu.base, iyu.house`, so its preflight
11
+ * (`base` โ€” `* { padding: 0; border: 0 }`, `h1 { font-size: inherit }`, `a { color: inherit }`)
12
+ * would beat every house rule. Here the theme is imported into Tailwind's own `components`
13
+ * layer, the slot Tailwind defines for third-party component CSS: above preflight, below
14
+ * utilities (a utility on an element still wins), and still below your unlayered CSS.
15
+ *
16
+ * Also maps the house roles onto utilities that read the live `--u-*` tokens (`@theme inline`),
17
+ * so dark mode and brand overrides reach Tailwind classes with no rebuild:
18
+ *
19
+ * bg-canvas ยท bg-surface ยท bg-raised ยท bg-selected ยท border-line ยท border-line-strong
20
+ * text-ink ยท text-ink-weak ยท text-ink-weaker ยท text-link ยท ring-focus
21
+ * {text,bg,border}-{info,success,warning,danger} (text = readable step) ยท bg-{role}-soft
22
+ * rounded-control (6) ยท rounded-card (10) ยท shadow-raise ยท shadow-overlay ยท font-sans
23
+ *
24
+ * Existing markup full of `text-gray-*` / `bg-slate-*`: add `tailwind-neutrals.css` too.
25
+ * ========================================================================== */
26
+ @import './fonts.css';
27
+ @import './theme.css' layer(components);
28
+
29
+ @theme inline {
30
+ --color-canvas: var(--u-canvas-bg-color);
31
+ --color-surface: var(--u-bg-color);
32
+ --color-raised: var(--u-bg-color-raised);
33
+ --color-hover: var(--u-bg-color-hover);
34
+ --color-selected: var(--u-primary-bg-color);
35
+ --color-line: var(--u-border-color);
36
+ --color-line-strong: var(--u-border-color-strong);
37
+ --color-ink: var(--u-txt-color);
38
+ --color-ink-weak: var(--u-txt-color-weak);
39
+ --color-ink-weaker: var(--u-txt-color-weaker);
40
+ --color-ink-disabled: var(--u-txt-color-disabled);
41
+ --color-link: var(--u-link-txt-color);
42
+ --color-focus: var(--u-focus-ring-color);
43
+ --color-action: var(--u-primary-color);
44
+ --color-on-action: var(--u-primary-txt-color);
45
+ --color-brand: var(--hs-brand);
46
+ --color-brand-soft: var(--hs-brand-soft);
47
+ --color-brand-ink: var(--hs-brand-ink);
48
+
49
+ --color-info: var(--u-info-color-strong);
50
+ --color-info-soft: var(--u-info-bg-color);
51
+ --color-success: var(--u-success-color-strong);
52
+ --color-success-soft: var(--u-success-bg-color);
53
+ --color-warning: var(--u-warning-color-strong);
54
+ --color-warning-soft: var(--u-warning-bg-color);
55
+ --color-danger: var(--u-danger-color-strong);
56
+ --color-danger-soft: var(--u-danger-bg-color);
57
+
58
+ --radius-control: var(--u-radius-lg);
59
+ --radius-card: var(--u-radius-xl);
60
+ --radius-badge: var(--u-radius-md);
61
+
62
+ --shadow-raise: var(--u-shadow-sm);
63
+ --shadow-overlay: var(--u-shadow-lg);
64
+
65
+ --font-sans: var(--u-font-base);
66
+ --font-mono: var(--u-font-mono);
67
+ }
68
+
69
+ /* Tailwind v4 draws a bare `border` utility in `currentColor` (near-black); LOB screens draw many
70
+ hairlines, so a bare border is the house line instead. Scoped to elements that use a border
71
+ utility โ€” a `*` rule would also reach custom-element hosts and beat their shadow `:host`
72
+ borders (outer styles win over `:host`). An explicit colour utility still wins (same layer,
73
+ later utilities layer). */
74
+ @layer base {
75
+ :where([class*='border']) {
76
+ border-color: var(--u-border-color);
77
+ }
78
+ }
@@ -0,0 +1,7 @@
1
+ /*
2
+ * @iyulab/house-style โ€” the theme without fonts
3
+ * import '@iyulab/house-style/styles/theme.css';
4
+ */
5
+ @import './tokens.css';
6
+ @import './components.css';
7
+ @import './patterns.css';
@@ -0,0 +1,322 @@
1
+ /*
2
+ * @iyulab/house-style โ€” tokens
3
+ * ==========================================================================
4
+ * The house values for the token axes `@iyulab/components` opens. Axes (names, steps) belong
5
+ * to the libraries; this sheet only fills them in. Everything lives in `@layer iyu.house`, so:
6
+ *
7
+ * built-in defaults (iyu.base) < this theme (iyu.house) < your application (unlayered)
8
+ *
9
+ * An application brands the house by overriding a handful of tokens with plain `:root` rules โ€”
10
+ * see "Brand" below. No specificity tricks are needed.
11
+ *
12
+ * Character โ€” a quiet, dense line-of-business look:
13
+ * ยท neutral first: warm greys carry ~90% of the screen; colour is for status and brand only
14
+ * ยท one ink action per view (`--u-primary-*` is ink, not blue)
15
+ * ยท blue is reserved for interaction: links, focus, selection
16
+ * ยท depth by surface and a hairline, shadows only on things that float
17
+ * ยท numbers first: tabular figures everywhere
18
+ *
19
+ * Contrast (light, against the surface #FFFFFF unless noted): body ink 17.4 ยท secondary 6.5 ยท
20
+ * tertiary 5.6 ยท link 6.2 ยท status text on its own tint โ‰ฅ 5.5 ยท input border 3.2 (WCAG 1.4.11).
21
+ * The numbers are re-measured by `tests/contrast.test.mjs`.
22
+ * ========================================================================== */
23
+
24
+ @layer iyu.base, iyu.house;
25
+
26
+ @layer iyu.house {
27
+
28
+ /* โ”€โ”€ light (and no theme attribute) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */
29
+ :root {
30
+ /* Neutral ramp โ€” warm grey. Most role tokens derive from it. */
31
+ --u-neutral-0: #FFFFFF;
32
+ --u-neutral-50: #F6F6F4;
33
+ --u-neutral-100: #F1F1EF;
34
+ --u-neutral-200: #EAEAE7;
35
+ --u-neutral-300: #E3E3DF;
36
+ --u-neutral-400: #C8C9C5;
37
+ --u-neutral-500: #8F9296;
38
+ --u-neutral-600: #666970;
39
+ --u-neutral-700: #5B5E63;
40
+ --u-neutral-800: #34363A;
41
+ --u-neutral-900: #18191B;
42
+ --u-neutral-1000: #0E0F10;
43
+
44
+ /* Depth โ€” canvas (page) < surface (cards, tables, controls) < floating (shadow) */
45
+ --u-canvas-bg-color: #F6F6F4;
46
+ --u-bg-color: #FFFFFF;
47
+ --u-panel-bg-color: #FFFFFF;
48
+ --u-input-bg-color: #FFFFFF;
49
+ --u-bg-color-raised: #F1F1EF; /* table header, toolbar strip, read-only field */
50
+ --u-bg-color-raised-hover: #EAEAE7;
51
+ --u-bg-color-hover: #F1F1EF;
52
+ --u-bg-color-active: #EAEAE7;
53
+ --u-bg-color-disabled: #F1F1EF;
54
+ --u-overlay-bg-color: rgba(24, 25, 27, 0.32);
55
+
56
+ /* Lines */
57
+ --u-border-color: #E3E3DF;
58
+ --u-border-color-weak: #ECECE9;
59
+ --u-border-color-strong: #8F9296;
60
+ --u-border-color-hover: #8F9296;
61
+ --u-input-border-color: #8F9296;
62
+ --u-input-border-color-hover: #5B5E63;
63
+ --u-input-border-color-focus: #2F6FEB;
64
+
65
+ /* Ink */
66
+ --u-txt-color: #18191B;
67
+ --u-txt-color-strong: #0E0F10;
68
+ --u-txt-color-weak: #5B5E63;
69
+ --u-txt-color-weaker: #666970;
70
+ --u-txt-color-hover: #18191B;
71
+ --u-txt-color-active: #18191B;
72
+ --u-txt-color-disabled: #A3A5A9;
73
+ --u-icon-color: #5B5E63;
74
+ --u-icon-color-hover: #18191B;
75
+ --u-icon-color-active: #18191B;
76
+
77
+ /* Action โ€” ink. The primary button is near-black; selection stays blue. */
78
+ --u-primary-color-weakest: #E3E3DF;
79
+ --u-primary-color-weaker: #C8C9C5;
80
+ --u-primary-color-weak: #5B5E63;
81
+ --u-primary-color: #18191B;
82
+ --u-primary-color-strong: #18191B;
83
+ --u-primary-txt-color: #FFFFFF;
84
+ --u-primary-bg-color: #EEF3FD; /* selected rows, current item */
85
+
86
+ /* Interaction โ€” blue, for links and focus only */
87
+ --u-link-txt-color: #1F5FCC;
88
+ --u-focus-ring-color: #2F6FEB;
89
+
90
+ /* Status โ€” `-color-strong` is the text step (on surface and on its own tint), `-bg-color`
91
+ the tint, `-color` the solid fill (with `-txt-color` on top). */
92
+ --u-info-color-weakest: #D6E3FB;
93
+ --u-info-color-weaker: #A9C4F6;
94
+ --u-info-color-weak: #5B8DE8;
95
+ --u-info-color: #1F5FCC;
96
+ --u-info-color-strong: #1A55B8;
97
+ --u-info-bg-color: #E8F0FD;
98
+ --u-info-txt-color: #FFFFFF;
99
+
100
+ --u-success-color-weakest: #CDEBD9;
101
+ --u-success-color-weaker: #A3D8BA;
102
+ --u-success-color-weak: #4AA274;
103
+ --u-success-color: #1B7A44;
104
+ --u-success-color-strong: #1B6E3E;
105
+ --u-success-bg-color: #E6F4EC;
106
+ --u-success-txt-color: #FFFFFF;
107
+
108
+ --u-warning-color-weakest: #FBEBCF;
109
+ --u-warning-color-weaker: #F5D9A3;
110
+ --u-warning-color-weak: #E8B25A;
111
+ --u-warning-color: #E59A24;
112
+ --u-warning-color-strong: #8A5100;
113
+ --u-warning-bg-color: #FDF3E1;
114
+ --u-warning-txt-color: #18191B;
115
+
116
+ --u-danger-color-weakest: #F9D4D0;
117
+ --u-danger-color-weaker: #F2AAA2;
118
+ --u-danger-color-weak: #DE6A5D;
119
+ --u-danger-color: #B42318;
120
+ --u-danger-color-strong: #B42318;
121
+ --u-danger-bg-color: #FDECEA;
122
+ --u-danger-txt-color: #FFFFFF;
123
+
124
+ /* Elevation โ€” a hairline lift for surfaces, one real shadow for things that float */
125
+ --u-shadow-color-weaker: rgba(16, 17, 19, 0.04);
126
+ --u-shadow-color-weak: rgba(16, 17, 19, 0.06);
127
+ --u-shadow-color-normal: rgba(16, 17, 19, 0.10);
128
+ --u-shadow-color-strong: rgba(16, 17, 19, 0.14);
129
+ --u-shadow-color-stronger: rgba(16, 17, 19, 0.18);
130
+ --u-shadow-sm: 0 1px 2px rgba(16, 17, 19, 0.06);
131
+ --u-shadow-md: 0 1px 2px rgba(16, 17, 19, 0.06);
132
+ --u-shadow-lg: 0 12px 32px rgba(16, 17, 19, 0.14), 0 2px 6px rgba(16, 17, 19, 0.06);
133
+ --u-shadow-xl: 0 16px 40px rgba(16, 17, 19, 0.18), 0 2px 8px rgba(16, 17, 19, 0.08);
134
+
135
+ /* Shell (`@iyulab/modern-app`) */
136
+ --app-sidebar-bg: var(--u-bg-color);
137
+ --app-sidebar-fg: var(--u-txt-color-weak);
138
+ --app-header-bg: var(--u-bg-color);
139
+ --app-header-fg: var(--u-txt-color);
140
+ --app-sidebar-width: 232px;
141
+ --app-sidebar-active-bg: var(--hs-brand-soft);
142
+ --app-sidebar-active-fg: var(--hs-brand-ink);
143
+
144
+ /* Brand โ€” the application's identity colour. The house default is neutral, so an
145
+ unbranded app looks finished; an application sets these three and nothing else. */
146
+ --hs-brand: #18191B;
147
+ --hs-brand-soft: #EAEAE7;
148
+ --hs-brand-ink: #18191B;
149
+ }
150
+
151
+ /* โ”€โ”€ dark โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */
152
+ :root[theme="dark"] {
153
+ --u-neutral-0: #0E0F10;
154
+ --u-neutral-50: #121314;
155
+ --u-neutral-100: #1A1B1D;
156
+ --u-neutral-200: #222326;
157
+ --u-neutral-300: #2E3033;
158
+ --u-neutral-400: #45474B;
159
+ --u-neutral-500: #6A6D72;
160
+ --u-neutral-600: #8C8F95;
161
+ --u-neutral-700: #A3A6AB;
162
+ --u-neutral-800: #C4C6CA;
163
+ --u-neutral-900: #EDEDEC;
164
+ --u-neutral-1000: #FFFFFF;
165
+
166
+ --u-canvas-bg-color: #121314;
167
+ --u-bg-color: #1A1B1D;
168
+ --u-panel-bg-color: #1A1B1D;
169
+ --u-input-bg-color: #1A1B1D;
170
+ --u-bg-color-raised: #222326;
171
+ --u-bg-color-raised-hover: #2A2B2E;
172
+ --u-bg-color-hover: #222326;
173
+ --u-bg-color-active: #2A2B2E;
174
+ --u-bg-color-disabled: #1F2022;
175
+ --u-overlay-bg-color: rgba(0, 0, 0, 0.56);
176
+
177
+ --u-border-color: #2E3033;
178
+ --u-border-color-weak: #26282B;
179
+ --u-border-color-strong: #6A6D72;
180
+ --u-border-color-hover: #6A6D72;
181
+ --u-input-border-color: #6A6D72;
182
+ --u-input-border-color-hover: #A3A6AB;
183
+ --u-input-border-color-focus: #6E9CF7;
184
+
185
+ --u-txt-color: #EDEDEC;
186
+ --u-txt-color-strong: #FFFFFF;
187
+ --u-txt-color-weak: #A3A6AB;
188
+ --u-txt-color-weaker: #8C8F95;
189
+ --u-txt-color-hover: #EDEDEC;
190
+ --u-txt-color-active: #EDEDEC;
191
+ --u-txt-color-disabled: #5E6166;
192
+ --u-icon-color: #A3A6AB;
193
+ --u-icon-color-hover: #EDEDEC;
194
+ --u-icon-color-active: #EDEDEC;
195
+
196
+ --u-primary-color-weakest: #2E3033;
197
+ --u-primary-color-weaker: #45474B;
198
+ --u-primary-color-weak: #A3A6AB;
199
+ --u-primary-color: #EDEDEC;
200
+ --u-primary-color-strong: #EDEDEC;
201
+ --u-primary-txt-color: #18191B;
202
+ --u-primary-bg-color: #1C2638;
203
+
204
+ --u-link-txt-color: #8DB3F7;
205
+ --u-focus-ring-color: #6E9CF7;
206
+
207
+ --u-info-color-weakest: #1F3152;
208
+ --u-info-color-weaker: #2C4A7E;
209
+ --u-info-color-weak: #5E8BE0;
210
+ --u-info-color: #8DB3F7;
211
+ --u-info-color-strong: #8DB3F7;
212
+ --u-info-bg-color: #1B2A44;
213
+ --u-info-txt-color: #0E0F10;
214
+
215
+ --u-success-color-weakest: #1A3826;
216
+ --u-success-color-weaker: #2B5A3E;
217
+ --u-success-color-weak: #4FB07D;
218
+ --u-success-color: #7DD8A5;
219
+ --u-success-color-strong: #7DD8A5;
220
+ --u-success-bg-color: #16301F;
221
+ --u-success-txt-color: #0E0F10;
222
+
223
+ --u-warning-color-weakest: #3F2E12;
224
+ --u-warning-color-weaker: #5E451A;
225
+ --u-warning-color-weak: #C99140;
226
+ --u-warning-color: #F2B65A;
227
+ --u-warning-color-strong: #F2B65A;
228
+ --u-warning-bg-color: #3A2A10;
229
+ --u-warning-txt-color: #0E0F10;
230
+
231
+ --u-danger-color-weakest: #4A1F1B;
232
+ --u-danger-color-weaker: #6E2C26;
233
+ --u-danger-color-weak: #E0675C;
234
+ --u-danger-color: #FF8A80;
235
+ --u-danger-color-strong: #FF8A80;
236
+ --u-danger-bg-color: #3D1A17;
237
+ --u-danger-txt-color: #1A0D0B;
238
+
239
+ --u-shadow-color-weaker: rgba(0, 0, 0, 0.24);
240
+ --u-shadow-color-weak: rgba(0, 0, 0, 0.32);
241
+ --u-shadow-color-normal: rgba(0, 0, 0, 0.40);
242
+ --u-shadow-color-strong: rgba(0, 0, 0, 0.50);
243
+ --u-shadow-color-stronger: rgba(0, 0, 0, 0.60);
244
+ --u-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.40);
245
+ --u-shadow-md: 0 1px 2px rgba(0, 0, 0, 0.40);
246
+ --u-shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.55), 0 2px 6px rgba(0, 0, 0, 0.40);
247
+ --u-shadow-xl: 0 16px 40px rgba(0, 0, 0, 0.60), 0 2px 8px rgba(0, 0, 0, 0.45);
248
+
249
+ --hs-brand: #EDEDEC;
250
+ --hs-brand-soft: #2A2B2E;
251
+ --hs-brand-ink: #EDEDEC;
252
+ }
253
+
254
+ /* โ”€โ”€ mode-independent scale: shape, type, spacing โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */
255
+ :root {
256
+ /* Shape โ€” badge 4 ยท control 6 ยท card and table 10 */
257
+ --u-radius-sm: 3px;
258
+ --u-radius-md: 4px;
259
+ --u-radius-lg: 6px;
260
+ --u-radius-xl: 10px;
261
+ --u-radius-2xl: 12px;
262
+ --u-radius-3xl: 16px;
263
+
264
+ /* Type โ€” Pretendard; one ladder 22 / 18 / 15 / 14 / 13 / 12 / 11. Korean gets no positive
265
+ tracking, so only the largest step is tightened and the overline stays near zero. */
266
+ --u-font-base: 'Pretendard Variable', Pretendard, -apple-system, BlinkMacSystemFont, 'Apple SD Gothic Neo',
267
+ 'Noto Sans KR', 'Malgun Gothic', 'Segoe UI', system-ui, sans-serif;
268
+ --u-font-mono: 'JetBrains Mono', D2Coding, ui-monospace, 'Cascadia Code', Menlo, Consolas, monospace;
269
+
270
+ --u-text-display-size: 22px;
271
+ --u-text-display-weight: 700;
272
+ --u-text-display-leading: 1.364;
273
+ --u-text-display-tracking: -0.01em;
274
+ --u-text-title-size: 18px;
275
+ --u-text-title-weight: 700;
276
+ --u-text-title-leading: 1.444;
277
+ --u-text-title-tracking: 0;
278
+ --u-text-subtitle-size: 15px;
279
+ --u-text-subtitle-weight: 600;
280
+ --u-text-subtitle-leading: 1.467;
281
+ --u-text-subtitle-tracking: 0;
282
+ --u-text-body-size: 14px;
283
+ --u-text-body-weight: 400;
284
+ --u-text-body-leading: 1.571;
285
+ --u-text-body-tracking: 0;
286
+ --u-text-label-size: 12px;
287
+ --u-text-label-weight: 500;
288
+ --u-text-label-leading: 1.333;
289
+ --u-text-label-tracking: 0;
290
+ --u-text-caption-size: 12px;
291
+ --u-text-caption-weight: 400;
292
+ --u-text-caption-leading: 1.5;
293
+ --u-text-caption-tracking: 0;
294
+ --u-text-overline-size: 11px;
295
+ --u-text-overline-weight: 600;
296
+ --u-text-overline-leading: 1.455;
297
+ --u-text-overline-tracking: 0.02em;
298
+
299
+ /* House-only scale โ€” control heights and table rows (read by components.css ยท patterns.css) */
300
+ --hs-control-sm: 28px;
301
+ --hs-control-md: 32px;
302
+ --hs-control-lg: 40px;
303
+ --hs-row: 40px;
304
+ --hs-row-compact: 32px;
305
+ --hs-page-padding: 24px;
306
+
307
+ /* Field box (`@iyulab/components`) โ€” 32px fields beside 32px buttons; 40px inside form sections */
308
+ --u-field-padding-block: 4.5px;
309
+ --u-field-padding-inline: 12px;
310
+ --u-field-radius: 6px;
311
+
312
+ /* Shell (`@iyulab/modern-app`) โ€” 32px navigation rows, 16px icons, a flat current item */
313
+ --app-main-padding: var(--hs-page-padding);
314
+ --app-sidebar-item-radius: 6px;
315
+ --app-sidebar-item-gap: 8px;
316
+ --app-sidebar-item-padding: 6px 12px;
317
+ --app-sidebar-icon-size: 16px;
318
+ --app-sidebar-active-shadow: none;
319
+ --app-sidebar-active-shadow-hover: none;
320
+ }
321
+
322
+ } /* @layer iyu.house */