@iyulab/house-style 0.1.1 → 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/CHANGELOG.md +30 -0
- package/README.md +18 -0
- package/package.json +11 -7
- package/styles/components.css +13 -3
- package/styles/patterns.css +24 -20
- package/styles/tokens.css +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.3] - 2026-10-06
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **A sidebar group holding the current page keeps a readable header.** `@iyulab/modern-app` derived that header's
|
|
8
|
+
text from the active background, which this theme makes light (`--hs-brand-soft`), so the text sank into the
|
|
9
|
+
panel (about 1.6:1 light, 1.1:1 dark). The theme now sets `--app-sidebar-group-active-fg` to `--hs-brand-ink`, the
|
|
10
|
+
color it already uses for text on that background (`@iyulab/modern-app` 0.39 reads it).
|
|
11
|
+
- **Patterns follow the type ladder.** `patterns.css` set font sizes in px (11, 12, 13, 28 — 19 places) and flex-table
|
|
12
|
+
cells and headers did too, so a consumer who rescaled `--u-text-*-size` saw components and body text change while
|
|
13
|
+
tables, pagers, definition lists and stats stayed put. They now read the steps — label, caption and overline, plus
|
|
14
|
+
two house steps derived from the ladder: `--hs-text-dense-size` (between body and label — the 13px of table cells,
|
|
15
|
+
definition lists, callouts) and `--hs-text-hero-size` (display + 6px — the 28px headline figure). Each read keeps
|
|
16
|
+
the current px as its fallback, so nothing changes at the house ladder. Button and field font sizes stay literal:
|
|
17
|
+
they are terms of the 28/32/40 control-height formula.
|
|
18
|
+
|
|
19
|
+
## [0.1.2] - 2026-10-06
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- **Plain links take the house link colour.** The theme defined `--u-link-txt-color` but only
|
|
24
|
+
`hs-*` classes read it, so a link without a class kept the browser's blue (`#0000EE`, and a
|
|
25
|
+
different blue again in dark mode). A zero-specificity `:where(a:any-link)` default now applies the
|
|
26
|
+
token; a class on the link and any application rule still win. The underline stays.
|
|
27
|
+
- **A table's totals get one separating line, not one per row.** `.hs-table tfoot td` drew a top
|
|
28
|
+
border on every totals row, so subtotal · tax · total read as stripes. The line is now on the first
|
|
29
|
+
totals row only.
|
|
30
|
+
- A whole card as a link (`a.hs-card`) keeps ink text and no underline, and a `.hs-views__tab`
|
|
31
|
+
rendered as a link has no underline — both used to take the browser's link styling.
|
|
32
|
+
|
|
3
33
|
## [0.1.1] - 2026-10-05
|
|
4
34
|
|
|
5
35
|
### Fixed
|
package/README.md
CHANGED
|
@@ -77,6 +77,11 @@ Everything else — warm-grey neutrals, the ink primary action, blue for links a
|
|
|
77
77
|
tints, the 22/18/15/14/13/12/11 type ladder, 28/32/40 controls, 40px table rows — comes from the
|
|
78
78
|
theme and can be overridden token by token.
|
|
79
79
|
|
|
80
|
+
The type ladder is the `--u-text-*-size` steps plus two house steps derived from them —
|
|
81
|
+
`--hs-text-dense-size` (between body and label: table cells, definition lists, callouts) and
|
|
82
|
+
`--hs-text-hero-size` (display + 6px: a headline figure). Every pattern reads a step, so rescaling the
|
|
83
|
+
ladder (a larger mode, a product system) carries the patterns along.
|
|
84
|
+
|
|
80
85
|
## The guide
|
|
81
86
|
|
|
82
87
|
**Live**: https://iyulab.github.io/house-style/ — this is the guide. There is no
|
|
@@ -126,6 +131,19 @@ site; run it locally with (needs network and Playwright's Chromium):
|
|
|
126
131
|
npm run check:start-here -w @iyulab/house-style
|
|
127
132
|
```
|
|
128
133
|
|
|
134
|
+
`check:start-here:local` walks the same path with this working tree's `@iyulab/house-style`
|
|
135
|
+
packed in place of the registry's — run it before tagging a release. The deploy workflow runs
|
|
136
|
+
both on every push to `main`.
|
|
137
|
+
|
|
138
|
+
The guide itself is checked too: after a build, every page (the landing page and each category)
|
|
139
|
+
must draw its section in a browser, with no page errors — a build can drop the section modules and
|
|
140
|
+
still succeed. The deploy workflow runs it before uploading the site:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
npm run build -w @iyulab/house-style
|
|
144
|
+
npm run check:guide -w @iyulab/house-style
|
|
145
|
+
```
|
|
146
|
+
|
|
129
147
|
## License
|
|
130
148
|
|
|
131
149
|
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/house-style",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "The iyulab house theme: a CSS-only theme for @iyulab components — tokens, component recipes, line-of-business layout patterns and a Tailwind CSS v4 preset — plus the guide site that documents it.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -25,7 +25,9 @@
|
|
|
25
25
|
"LICENSE"
|
|
26
26
|
],
|
|
27
27
|
"sideEffects": [
|
|
28
|
-
"**/*.css"
|
|
28
|
+
"**/*.css",
|
|
29
|
+
"./src/**",
|
|
30
|
+
"./src-app/**"
|
|
29
31
|
],
|
|
30
32
|
"scripts": {
|
|
31
33
|
"preversion": "node -e \"if(require('fs').existsSync('../../scripts/preversion-check.mjs'))require('child_process').execFileSync('node',['../../scripts/preversion-check.mjs'],{stdio:'inherit'})\"",
|
|
@@ -33,8 +35,10 @@
|
|
|
33
35
|
"build": "npm run typecheck && vite build",
|
|
34
36
|
"preview": "vite preview",
|
|
35
37
|
"typecheck": "tsc --noEmit",
|
|
38
|
+
"check:guide": "node scripts/check-guide.mjs",
|
|
36
39
|
"check:start-here": "node scripts/check-start-here.mjs",
|
|
37
40
|
"check:start-here:local": "node scripts/check-start-here.mjs --local",
|
|
41
|
+
"pretest": "node -e \"if(require('fs').existsSync('../../scripts/sibling-dist-check.js'))require('child_process').execFileSync('node',['../../scripts/sibling-dist-check.js'],{stdio:'inherit'})\"",
|
|
38
42
|
"test": "node --test \"tests/*.test.mjs\""
|
|
39
43
|
},
|
|
40
44
|
"engines": {
|
|
@@ -58,11 +62,11 @@
|
|
|
58
62
|
},
|
|
59
63
|
"devDependencies": {
|
|
60
64
|
"@iyulab/components": "^2.0.0",
|
|
61
|
-
"@iyulab/data-components": "^0.
|
|
62
|
-
"@iyulab/enterprise": "^0.
|
|
63
|
-
"@iyulab/modern-app": "^0.
|
|
64
|
-
"@iyulab/router": "^0.
|
|
65
|
-
"@iyulab/u-widgets": "^0.
|
|
65
|
+
"@iyulab/data-components": "^0.39.0",
|
|
66
|
+
"@iyulab/enterprise": "^0.25.0",
|
|
67
|
+
"@iyulab/modern-app": "^0.39.0",
|
|
68
|
+
"@iyulab/router": "^0.20.0",
|
|
69
|
+
"@iyulab/u-widgets": "^0.25.0",
|
|
66
70
|
"@lit/react": "^1.0.8",
|
|
67
71
|
"@types/node": "^26.1.1",
|
|
68
72
|
"@types/react": "^19.2.14",
|
package/styles/components.css
CHANGED
|
@@ -21,10 +21,20 @@
|
|
|
21
21
|
color: var(--u-txt-color);
|
|
22
22
|
-webkit-font-smoothing: antialiased;
|
|
23
23
|
}
|
|
24
|
+
/* A plain link takes the house link colour instead of the browser's — in light and dark alike.
|
|
25
|
+
* Zero specificity: a class on the link (`hs-*`, an app's own) and any application rule win.
|
|
26
|
+
* Visited links keep the same colour (an application, not a document); the underline stays,
|
|
27
|
+
* so a link in running text is not told apart by colour alone. */
|
|
28
|
+
:where(a:any-link) {
|
|
29
|
+
color: var(--u-link-txt-color);
|
|
30
|
+
}
|
|
24
31
|
|
|
25
32
|
/* ── Button — 28 / 32 / 40, medium weight ─────────────────────────────── *
|
|
26
33
|
* Height follows the components' own formula (1.5em line + 2 × padding + 2px border), so
|
|
27
|
-
* these are padding values, not fixed heights: text and icon-only buttons stay equal.
|
|
34
|
+
* these are padding values, not fixed heights: text and icon-only buttons stay equal.
|
|
35
|
+
* The font sizes here are literal on purpose: they are terms of that height formula (the
|
|
36
|
+
* control ladder 28/32/40), not steps of the text ladder — tying them to `--u-text-*` would
|
|
37
|
+
* change control heights whenever the text ladder is rescaled. */
|
|
28
38
|
u-button:not([size]),
|
|
29
39
|
u-button[size='md'] {
|
|
30
40
|
font-size: 13px;
|
|
@@ -83,10 +93,10 @@ u-drawer::part(body) {
|
|
|
83
93
|
* no zebra (hover and selection carry the row), tabular figures. ──────── */
|
|
84
94
|
flex-table {
|
|
85
95
|
--ft-font-family: var(--u-font-base);
|
|
86
|
-
--ft-font-size: 13px;
|
|
96
|
+
--ft-font-size: var(--hs-text-dense-size, 13px);
|
|
87
97
|
--ft-row-height: var(--hs-row);
|
|
88
98
|
--ft-cell-padding-inline: 12px;
|
|
89
|
-
--ft-header-font-size: 12px;
|
|
99
|
+
--ft-header-font-size: var(--u-text-label-size, 12px);
|
|
90
100
|
--ft-header-font-weight: 500;
|
|
91
101
|
--ft-header-text-color: var(--u-txt-color-weak);
|
|
92
102
|
--ft-header-bg: var(--u-bg-color-raised);
|
package/styles/patterns.css
CHANGED
|
@@ -87,9 +87,10 @@
|
|
|
87
87
|
border-bottom: 2px solid transparent;
|
|
88
88
|
background: none;
|
|
89
89
|
font: inherit;
|
|
90
|
-
font-size: 13px;
|
|
90
|
+
font-size: var(--hs-text-dense-size, 13px);
|
|
91
91
|
line-height: 20px;
|
|
92
92
|
color: var(--u-txt-color-weak);
|
|
93
|
+
text-decoration: none; /* a tab may be a link (`aria-current="page"`) */
|
|
93
94
|
white-space: nowrap;
|
|
94
95
|
cursor: pointer;
|
|
95
96
|
}
|
|
@@ -113,7 +114,7 @@
|
|
|
113
114
|
border-radius: var(--u-radius-pill, 9999px);
|
|
114
115
|
background: var(--u-bg-color-raised);
|
|
115
116
|
color: var(--u-txt-color-weak);
|
|
116
|
-
font-size: 11px;
|
|
117
|
+
font-size: var(--u-text-overline-size, 11px);
|
|
117
118
|
line-height: 16px;
|
|
118
119
|
font-weight: 500;
|
|
119
120
|
text-align: center;
|
|
@@ -181,17 +182,17 @@
|
|
|
181
182
|
}
|
|
182
183
|
.hs-stat__unit {
|
|
183
184
|
margin-inline-start: 2px;
|
|
184
|
-
font-size: 12px;
|
|
185
|
+
font-size: var(--u-text-caption-size, 12px);
|
|
185
186
|
font-weight: 500;
|
|
186
187
|
color: var(--u-txt-color-weak);
|
|
187
188
|
}
|
|
188
189
|
.hs-stat__sub {
|
|
189
|
-
font-size: 12px;
|
|
190
|
+
font-size: var(--u-text-caption-size, 12px);
|
|
190
191
|
line-height: 18px;
|
|
191
192
|
color: var(--u-txt-color-weaker);
|
|
192
193
|
}
|
|
193
194
|
.hs-stat--hero .hs-stat__value {
|
|
194
|
-
font-size: 28px;
|
|
195
|
+
font-size: var(--hs-text-hero-size, 28px);
|
|
195
196
|
line-height: 34px;
|
|
196
197
|
letter-spacing: -0.01em;
|
|
197
198
|
}
|
|
@@ -231,7 +232,7 @@
|
|
|
231
232
|
background: var(--u-primary-bg-color);
|
|
232
233
|
}
|
|
233
234
|
.hs-table-toolbar__title {
|
|
234
|
-
font-size: 13px;
|
|
235
|
+
font-size: var(--hs-text-dense-size, 13px);
|
|
235
236
|
font-weight: 600;
|
|
236
237
|
}
|
|
237
238
|
.hs-pager {
|
|
@@ -241,7 +242,7 @@
|
|
|
241
242
|
gap: var(--u-space-sm, 8px);
|
|
242
243
|
padding: var(--u-space-sm, 8px) var(--u-space-md, 12px);
|
|
243
244
|
border-top: 1px solid var(--u-border-color);
|
|
244
|
-
font-size: 12px;
|
|
245
|
+
font-size: var(--u-text-label-size, 12px);
|
|
245
246
|
color: var(--u-txt-color-weak);
|
|
246
247
|
font-variant-numeric: tabular-nums;
|
|
247
248
|
}
|
|
@@ -250,7 +251,7 @@
|
|
|
250
251
|
.hs-table {
|
|
251
252
|
width: 100%;
|
|
252
253
|
border-collapse: collapse;
|
|
253
|
-
font-size: 13px;
|
|
254
|
+
font-size: var(--hs-text-dense-size, 13px);
|
|
254
255
|
line-height: 20px;
|
|
255
256
|
color: var(--u-txt-color);
|
|
256
257
|
}
|
|
@@ -258,7 +259,7 @@
|
|
|
258
259
|
padding: var(--u-space-sm, 8px) var(--u-space-md, 12px);
|
|
259
260
|
text-align: start;
|
|
260
261
|
white-space: nowrap;
|
|
261
|
-
font-size: 12px;
|
|
262
|
+
font-size: var(--u-text-label-size, 12px);
|
|
262
263
|
line-height: 16px;
|
|
263
264
|
font-weight: 500;
|
|
264
265
|
color: var(--u-txt-color-weak);
|
|
@@ -276,9 +277,10 @@
|
|
|
276
277
|
.hs-table tr[aria-selected='true'] td { background: var(--u-primary-bg-color); }
|
|
277
278
|
.hs-table tfoot td {
|
|
278
279
|
height: var(--hs-row, 40px);
|
|
279
|
-
border-top: 1px solid var(--u-border-color);
|
|
280
280
|
font-weight: 600;
|
|
281
281
|
}
|
|
282
|
+
/* One line separates the totals from the body — not one per totals row (subtotal · tax · total). */
|
|
283
|
+
.hs-table tfoot tr:first-child td { border-top: 1px solid var(--u-border-color); }
|
|
282
284
|
.hs-table--compact td { height: var(--hs-row-compact, 32px); }
|
|
283
285
|
.hs-table--top td { vertical-align: top; padding-block: var(--u-space-sm, 8px); height: auto; }
|
|
284
286
|
/* Cells (`th` too — header text aligns with its values) */
|
|
@@ -307,7 +309,7 @@ a.hs-id:hover,
|
|
|
307
309
|
.hs-table .hs-group td {
|
|
308
310
|
height: 32px;
|
|
309
311
|
background: var(--u-bg-color-raised);
|
|
310
|
-
font-size: 12px;
|
|
312
|
+
font-size: var(--u-text-label-size, 12px);
|
|
311
313
|
font-weight: 600;
|
|
312
314
|
color: var(--u-txt-color-weak);
|
|
313
315
|
}
|
|
@@ -351,7 +353,7 @@ tr[aria-selected='true'] .hs-row-actions {
|
|
|
351
353
|
font-weight: 600;
|
|
352
354
|
}
|
|
353
355
|
.hs-card__link {
|
|
354
|
-
font-size: 12px;
|
|
356
|
+
font-size: var(--u-text-label-size, 12px);
|
|
355
357
|
font-weight: 500;
|
|
356
358
|
color: var(--u-link-txt-color);
|
|
357
359
|
text-decoration: none;
|
|
@@ -359,6 +361,8 @@ tr[aria-selected='true'] .hs-row-actions {
|
|
|
359
361
|
.hs-card__link:hover { text-decoration: underline; }
|
|
360
362
|
a.hs-card,
|
|
361
363
|
.hs-card--link { cursor: pointer; transition: border-color 0.12s ease-out; }
|
|
364
|
+
/* A whole card as a link reads as a card: ink text, no underline — the border carries hover. */
|
|
365
|
+
a.hs-card { color: inherit; text-decoration: none; }
|
|
362
366
|
a.hs-card:hover,
|
|
363
367
|
.hs-card--link:hover { border-color: var(--u-border-color-strong); }
|
|
364
368
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -371,7 +375,7 @@ a.hs-card:hover,
|
|
|
371
375
|
grid-template-columns: max-content minmax(0, 1fr);
|
|
372
376
|
gap: 6px var(--u-space-lg, 16px);
|
|
373
377
|
margin: 0;
|
|
374
|
-
font-size: 13px;
|
|
378
|
+
font-size: var(--hs-text-dense-size, 13px);
|
|
375
379
|
line-height: 20px;
|
|
376
380
|
}
|
|
377
381
|
.hs-dl > dt { color: var(--u-txt-color-weak); }
|
|
@@ -408,7 +412,7 @@ a.hs-card:hover,
|
|
|
408
412
|
padding: var(--u-space-md, 12px) var(--u-space-lg, 16px);
|
|
409
413
|
border-radius: var(--u-radius-xl, 10px);
|
|
410
414
|
background: var(--u-bg-color-raised);
|
|
411
|
-
font-size: 13px;
|
|
415
|
+
font-size: var(--hs-text-dense-size, 13px);
|
|
412
416
|
line-height: 20px;
|
|
413
417
|
}
|
|
414
418
|
.hs-callout__icon { color: var(--u-txt-color-weak); line-height: 20px; }
|
|
@@ -446,7 +450,7 @@ a.hs-card:hover,
|
|
|
446
450
|
width: 100%;
|
|
447
451
|
margin: 0 0 var(--u-space-md, 12px);
|
|
448
452
|
padding: 0;
|
|
449
|
-
font-size: 13px;
|
|
453
|
+
font-size: var(--hs-text-dense-size, 13px);
|
|
450
454
|
font-weight: 600;
|
|
451
455
|
color: var(--u-txt-color);
|
|
452
456
|
}
|
|
@@ -471,12 +475,12 @@ a.hs-card:hover,
|
|
|
471
475
|
color: var(--u-danger-color-strong);
|
|
472
476
|
}
|
|
473
477
|
.hs-field__help {
|
|
474
|
-
font-size: 12px;
|
|
478
|
+
font-size: var(--u-text-caption-size, 12px);
|
|
475
479
|
line-height: 18px;
|
|
476
480
|
color: var(--u-txt-color-weaker);
|
|
477
481
|
}
|
|
478
482
|
.hs-field__error {
|
|
479
|
-
font-size: 12px;
|
|
483
|
+
font-size: var(--u-text-caption-size, 12px);
|
|
480
484
|
line-height: 18px;
|
|
481
485
|
color: var(--u-danger-color-strong);
|
|
482
486
|
}
|
|
@@ -513,7 +517,7 @@ a.hs-card:hover,
|
|
|
513
517
|
background: var(--u-bg-color);
|
|
514
518
|
}
|
|
515
519
|
.hs-sheet-footer__summary {
|
|
516
|
-
font-size: 12px;
|
|
520
|
+
font-size: var(--u-text-caption-size, 12px);
|
|
517
521
|
color: var(--u-txt-color-weak);
|
|
518
522
|
}
|
|
519
523
|
.hs-sheet-footer__actions {
|
|
@@ -530,7 +534,7 @@ a.hs-card:hover,
|
|
|
530
534
|
padding: 0 5px;
|
|
531
535
|
border: 1px solid var(--u-border-color);
|
|
532
536
|
border-radius: var(--u-radius-md, 4px);
|
|
533
|
-
font-size: 11px;
|
|
537
|
+
font-size: var(--u-text-overline-size, 11px);
|
|
534
538
|
line-height: 16px;
|
|
535
539
|
font-weight: 500;
|
|
536
540
|
color: var(--u-txt-color-weak);
|
|
@@ -544,7 +548,7 @@ a.hs-card:hover,
|
|
|
544
548
|
height: 18px;
|
|
545
549
|
padding: 0 6px;
|
|
546
550
|
border-radius: var(--u-radius-pill, 9999px);
|
|
547
|
-
font-size: 11px;
|
|
551
|
+
font-size: var(--u-text-overline-size, 11px);
|
|
548
552
|
font-weight: 600;
|
|
549
553
|
font-variant-numeric: tabular-nums;
|
|
550
554
|
background: var(--u-bg-color-raised);
|
package/styles/tokens.css
CHANGED
|
@@ -140,6 +140,7 @@
|
|
|
140
140
|
--app-sidebar-width: 232px;
|
|
141
141
|
--app-sidebar-active-bg: var(--hs-brand-soft);
|
|
142
142
|
--app-sidebar-active-fg: var(--hs-brand-ink);
|
|
143
|
+
--app-sidebar-group-active-fg: var(--hs-brand-ink);
|
|
143
144
|
|
|
144
145
|
/* Brand — the application's identity colour. The house default is neutral, so an
|
|
145
146
|
unbranded app looks finished; an application sets these three and nothing else. */
|
|
@@ -304,6 +305,12 @@
|
|
|
304
305
|
--hs-row-compact: 32px;
|
|
305
306
|
--hs-page-padding: 24px;
|
|
306
307
|
|
|
308
|
+
/* House type steps beyond the shared ladder — derived from it, so a rescaled ladder (density, a product system)
|
|
309
|
+
carries them along. Dense = the step between body and label (13 at 14/12): table cells, definition lists,
|
|
310
|
+
callouts. Hero = a headline figure, display + 6 (28 at 22). */
|
|
311
|
+
--hs-text-dense-size: calc((var(--u-text-body-size) + var(--u-text-label-size)) / 2);
|
|
312
|
+
--hs-text-hero-size: calc(var(--u-text-display-size) + 6px);
|
|
313
|
+
|
|
307
314
|
/* Field box (`@iyulab/components`) — 32px fields beside 32px buttons; 40px inside form sections */
|
|
308
315
|
--u-field-padding-block: 4.5px;
|
|
309
316
|
--u-field-padding-inline: 12px;
|