@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 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.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.33.0",
62
- "@iyulab/enterprise": "^0.22.0",
63
- "@iyulab/modern-app": "^0.34.0",
64
- "@iyulab/router": "^0.19.0",
65
- "@iyulab/u-widgets": "^0.24.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",
@@ -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);
@@ -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;