@mitcsutt/kiln-ui 0.2.2 → 0.4.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/README.md +6 -6
- package/dist/assets/fonts/archivo-latin-ext-wdth-italic.woff2 +0 -0
- package/dist/assets/fonts/archivo-latin-ext-wdth-normal.woff2 +0 -0
- package/dist/assets/fonts/archivo-latin-wdth-italic.woff2 +0 -0
- package/dist/assets/fonts/archivo-latin-wdth-normal.woff2 +0 -0
- package/dist/assets/fonts/atkinson-hyperlegible-mono-latin-ext-wght-italic.woff2 +0 -0
- package/dist/assets/fonts/atkinson-hyperlegible-mono-latin-ext-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/atkinson-hyperlegible-mono-latin-wght-italic.woff2 +0 -0
- package/dist/assets/fonts/atkinson-hyperlegible-mono-latin-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/b612-latin-400-italic.woff2 +0 -0
- package/dist/assets/fonts/b612-latin-400-normal.woff2 +0 -0
- package/dist/assets/fonts/b612-latin-700-italic.woff2 +0 -0
- package/dist/assets/fonts/b612-latin-700-normal.woff2 +0 -0
- package/dist/assets/fonts/b612-mono-latin-400-italic.woff2 +0 -0
- package/dist/assets/fonts/b612-mono-latin-400-normal.woff2 +0 -0
- package/dist/assets/fonts/b612-mono-latin-700-italic.woff2 +0 -0
- package/dist/assets/fonts/b612-mono-latin-700-normal.woff2 +0 -0
- package/dist/assets/fonts/golos-text-latin-ext-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/golos-text-latin-wght-normal.woff2 +0 -0
- package/dist/assets/fonts/licenses/archivo.txt +93 -0
- package/dist/assets/fonts/licenses/atkinson-hyperlegible-mono.txt +93 -0
- package/dist/assets/fonts/licenses/b612-mono.txt +93 -0
- package/dist/assets/fonts/licenses/b612.txt +93 -0
- package/dist/assets/fonts/licenses/golos-text.txt +93 -0
- package/dist/assets/fonts/licenses/shantell-sans.txt +93 -0
- package/dist/assets/fonts/shantell-sans-latin-ext-full-italic.woff2 +0 -0
- package/dist/assets/fonts/shantell-sans-latin-ext-full-normal.woff2 +0 -0
- package/dist/assets/fonts/shantell-sans-latin-full-italic.woff2 +0 -0
- package/dist/assets/fonts/shantell-sans-latin-full-normal.woff2 +0 -0
- package/dist/components/actions/Button/Button.module.js.map +1 -1
- package/dist/components/actions/ToggleChip/ToggleChip.d.ts +5 -0
- package/dist/components/actions/ToggleChip/ToggleChip.js +10 -6
- package/dist/components/actions/ToggleChip/ToggleChip.js.map +1 -1
- package/dist/components/actions/ToggleChip/chip.module.js +4 -3
- package/dist/components/actions/ToggleChip/chip.module.js.map +1 -1
- package/dist/components/display/Avatar/Avatar.d.ts +3 -3
- package/dist/components/display/Avatar/Avatar.js.map +1 -1
- package/dist/components/display/AvatarGroup/AvatarGroup.d.ts +2 -2
- package/dist/components/display/AvatarGroup/AvatarGroup.js +1 -1
- package/dist/components/display/AvatarGroup/AvatarGroup.js.map +1 -1
- package/dist/components/display/Card/Card.d.ts +7 -4
- package/dist/components/display/Card/Card.js +8 -7
- package/dist/components/display/Card/Card.js.map +1 -1
- package/dist/components/display/Card/Card.module.js.map +1 -1
- package/dist/components/display/List/List.d.ts +10 -5
- package/dist/components/display/List/List.js +49 -40
- package/dist/components/display/List/List.js.map +1 -1
- package/dist/components/display/List/List.module.js.map +1 -1
- package/dist/components/display/Marquee/Marquee.js +1 -1
- package/dist/components/display/Marquee/Marquee.js.map +1 -1
- package/dist/components/display/Media/Media.d.ts +13 -0
- package/dist/components/display/Media/Media.js +23 -19
- package/dist/components/display/Media/Media.js.map +1 -1
- package/dist/components/display/Media/Media.module.js.map +1 -1
- package/dist/components/display/Media/index.d.ts +1 -1
- package/dist/components/display/Stat/Stat.module.js.map +1 -1
- package/dist/components/display/Table/Table.d.ts +6 -1
- package/dist/components/display/Table/Table.js +6 -4
- package/dist/components/display/Table/Table.js.map +1 -1
- package/dist/components/display/Table/Table.module.js.map +1 -1
- package/dist/components/display/Tag/Tag.d.ts +3 -0
- package/dist/components/display/Tag/Tag.js +11 -10
- package/dist/components/display/Tag/Tag.js.map +1 -1
- package/dist/components/display/Tag/Tag.module.js.map +1 -1
- package/dist/components/display/Tag/index.d.ts +1 -1
- package/dist/components/feedback/Flash/Flash.d.ts +47 -0
- package/dist/components/feedback/Flash/Flash.js +36 -0
- package/dist/components/feedback/Flash/Flash.js.map +1 -0
- package/dist/components/feedback/Flash/Flash.module.js +10 -0
- package/dist/components/feedback/Flash/Flash.module.js.map +1 -0
- package/dist/components/feedback/Flash/index.d.ts +2 -0
- package/dist/components/feedback/RelativeTime/RelativeTime.d.ts +7 -0
- package/dist/components/feedback/RelativeTime/RelativeTime.js +11 -11
- package/dist/components/feedback/RelativeTime/RelativeTime.js.map +1 -1
- package/dist/components/feedback/StatusDot/StatusDot.d.ts +1 -1
- package/dist/components/feedback/StatusDot/StatusDot.js.map +1 -1
- package/dist/components/inputs/ChoiceCards/ChoiceCards.js +9 -9
- package/dist/components/inputs/Combobox/Combobox.js +5 -5
- package/dist/components/inputs/PasswordInput/PasswordInput.js +4 -4
- package/dist/components/layout/AppShell/AppShell.d.ts +4 -1
- package/dist/components/layout/AppShell/AppShell.js +58 -44
- package/dist/components/layout/AppShell/AppShell.js.map +1 -1
- package/dist/components/layout/AppShell/AppShell.module.js.map +1 -1
- package/dist/components/layout/Box/Box.d.ts +6 -3
- package/dist/components/layout/Box/Box.js.map +1 -1
- package/dist/components/layout/Box/Box.module.js.map +1 -1
- package/dist/components/layout/Divider/Divider.d.ts +7 -1
- package/dist/components/layout/Divider/Divider.js +18 -20
- package/dist/components/layout/Divider/Divider.js.map +1 -1
- package/dist/components/layout/Section/Section.d.ts +8 -6
- package/dist/components/layout/Section/Section.js.map +1 -1
- package/dist/components/layout/Section/Section.module.js.map +1 -1
- package/dist/components/navigation/Accordion/Accordion.d.ts +6 -1
- package/dist/components/navigation/Accordion/Accordion.js +19 -11
- package/dist/components/navigation/Accordion/Accordion.js.map +1 -1
- package/dist/components/navigation/Accordion/Accordion.module.js +7 -6
- package/dist/components/navigation/Accordion/Accordion.module.js.map +1 -1
- package/dist/components/navigation/NavLinks/NavLinks.d.ts +4 -1
- package/dist/components/navigation/NavLinks/NavLinks.js.map +1 -1
- package/dist/components/navigation/NavLinks/NavLinks.module.js.map +1 -1
- package/dist/components/overlays/Tooltip/Tooltip.d.ts +23 -0
- package/dist/components/overlays/Tooltip/Tooltip.js +77 -31
- package/dist/components/overlays/Tooltip/Tooltip.js.map +1 -1
- package/dist/components/typography/Numeral/Numeral.d.ts +26 -2
- package/dist/components/typography/Numeral/Numeral.js +25 -21
- package/dist/components/typography/Numeral/Numeral.js.map +1 -1
- package/dist/components/typography/Numeral/Numeral.module.js +4 -3
- package/dist/components/typography/Numeral/Numeral.module.js.map +1 -1
- package/dist/components/typography/Text/Text.d.ts +5 -2
- package/dist/components/typography/Text/Text.js.map +1 -1
- package/dist/components/typography/Text/Text.module.js.map +1 -1
- package/dist/icons/Icon.d.ts +1 -1
- package/dist/icons/Icon.js +1 -0
- package/dist/icons/Icon.js.map +1 -1
- package/dist/icons/icons.d.ts +12 -0
- package/dist/icons/icons.js +63 -13
- package/dist/icons/icons.js.map +1 -1
- package/dist/index.d.ts +16 -23
- package/dist/index.js +113 -112
- package/dist/styles.css +1 -1
- package/dist/theme/ThemeProvider.d.ts +4 -4
- package/dist/theme/ThemeProvider.js.map +1 -1
- package/dist/theme/themes.d.ts +1 -1
- package/dist/theme/themes.js +15 -3
- package/dist/theme/themes.js.map +1 -1
- package/dist/themes/fiesta.css +1 -1
- package/dist/themes/flightdeck.css +1 -0
- package/dist/themes/ledger.css +1 -1
- package/dist/themes/monograph.css +1 -1
- package/dist/themes/riso.css +1 -0
- package/dist/utils/tokens.d.ts +2 -0
- package/dist/utils/tokens.js.map +1 -1
- package/package.json +5 -3
- package/skills/custom-theme/SKILL.md +45 -43
- package/skills/custom-theme/references/colour.md +1 -1
- package/skills/custom-theme/references/motion.md +2 -2
- package/skills/custom-theme/references/tokens.md +42 -42
- package/skills/custom-theme/references/type.md +13 -10
- package/skills/design-rules/SKILL.md +36 -5
- package/skills/layout-composition/references/app-shell.md +2 -2
- package/skills/layout-composition/references/box.md +1 -1
- package/skills/layout-composition/references/divider.md +30 -1
- package/skills/layout-composition/references/section.md +23 -2
- package/skills/setup-and-theming/SKILL.md +13 -9
- package/skills/setup-and-theming/references/fiesta.md +3 -1
- package/skills/setup-and-theming/references/flightdeck.md +39 -0
- package/skills/setup-and-theming/references/ledger.md +7 -7
- package/skills/setup-and-theming/references/monograph.md +4 -0
- package/skills/setup-and-theming/references/paper.md +7 -7
- package/skills/setup-and-theming/references/riso.md +32 -0
|
@@ -45,25 +45,25 @@ Type roles:
|
|
|
45
45
|
|
|
46
46
|
| Token | Paper |
|
|
47
47
|
| --- | --- |
|
|
48
|
-
| `--font-display` | `'
|
|
49
|
-
| `--font-text` | `'
|
|
50
|
-
| `--font-prose` | `'
|
|
51
|
-
| `--font-mono` | `'
|
|
52
|
-
| `--font-numeric` | `'
|
|
48
|
+
| `--font-display` | `'Golos Text', ui-sans-serif, system-ui, sans-serif` |
|
|
49
|
+
| `--font-text` | `'Golos Text', ui-sans-serif, system-ui, sans-serif` |
|
|
50
|
+
| `--font-prose` | `'Golos Text', ui-sans-serif, system-ui, sans-serif` |
|
|
51
|
+
| `--font-mono` | `'Atkinson Hyperlegible Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace` |
|
|
52
|
+
| `--font-numeric` | `'Golos Text', ui-sans-serif, system-ui, sans-serif` |
|
|
53
53
|
| `--type-base` | `1rem` |
|
|
54
54
|
| `--display-scale` | `1` |
|
|
55
55
|
| `--type-ratio` | `1.25` |
|
|
56
|
-
| `--display-weight` | `
|
|
56
|
+
| `--display-weight` | `740` |
|
|
57
57
|
| `--display-style` | `normal` |
|
|
58
58
|
| `--display-stretch` | `100%` |
|
|
59
59
|
| `--display-transform` | `none` |
|
|
60
|
-
| `--display-tracking` | `-0.
|
|
60
|
+
| `--display-tracking` | `-0.025em` |
|
|
61
61
|
| `--display-opsz` | `72` |
|
|
62
62
|
| `--heading-font` | `var(--font-display)` |
|
|
63
|
-
| `--heading-weight` | `
|
|
63
|
+
| `--heading-weight` | `650` |
|
|
64
64
|
| `--heading-tracking` | `-0.015em` |
|
|
65
65
|
| `--heading-transform` | `none` |
|
|
66
|
-
| `--label-weight` | `
|
|
66
|
+
| `--label-weight` | `600` |
|
|
67
67
|
| `--label-tracking` | `0` |
|
|
68
68
|
| `--label-transform` | `none` |
|
|
69
69
|
| `--numeric-stretch` | `100%` |
|
|
@@ -71,7 +71,7 @@ Type roles:
|
|
|
71
71
|
| `--leading-tight` | `1` |
|
|
72
72
|
| `--leading-snug` | `1.2` |
|
|
73
73
|
| `--leading-body` | `1.55` |
|
|
74
|
-
| `--prose-size` | `1.
|
|
74
|
+
| `--prose-size` | `1.0625rem` |
|
|
75
75
|
| `--prose-leading` | `1.6` |
|
|
76
76
|
|
|
77
77
|
Structure & temperament:
|
|
@@ -86,38 +86,38 @@ Structure & temperament:
|
|
|
86
86
|
| `--icon-stroke` | `1.5` |
|
|
87
87
|
| `--border-width` | `1px` |
|
|
88
88
|
| `--border-width-strong` | `2px` |
|
|
89
|
-
| `--radius-action` | `0.
|
|
90
|
-
| `--radius-field` | `0.
|
|
91
|
-
| `--radius-surface` | `0.
|
|
92
|
-
| `--radius-media` | `0.
|
|
93
|
-
| `--radius-chip` | `
|
|
89
|
+
| `--radius-action` | `0.25rem` |
|
|
90
|
+
| `--radius-field` | `0.25rem` |
|
|
91
|
+
| `--radius-surface` | `0.375rem` |
|
|
92
|
+
| `--radius-media` | `0.125rem` |
|
|
93
|
+
| `--radius-chip` | `999px` |
|
|
94
94
|
| `--radius-avatar` | `50%` |
|
|
95
95
|
|
|
96
96
|
Colour:
|
|
97
97
|
|
|
98
98
|
| Token | Paper |
|
|
99
99
|
| --- | --- |
|
|
100
|
-
| `--color-canvas` | `light-dark(oklch(0.
|
|
101
|
-
| `--color-surface` | `light-dark(oklch(0.
|
|
102
|
-
| `--color-surface-sunken` | `light-dark(oklch(0.
|
|
103
|
-
| `--color-surface-raised` | `light-dark(oklch(0.
|
|
104
|
-
| `--color-surface-inverse` | `light-dark(oklch(0.
|
|
105
|
-
| `--color-ink` | `light-dark(oklch(0.
|
|
106
|
-
| `--color-ink-muted` | `light-dark(oklch(0.
|
|
107
|
-
| `--color-ink-subtle` | `light-dark(oklch(0.
|
|
108
|
-
| `--color-ink-inverse` | `light-dark(oklch(0.
|
|
109
|
-
| `--color-line` | `light-dark(oklch(0.9 0.
|
|
110
|
-
| `--color-line-strong` | `light-dark(oklch(0.
|
|
111
|
-
| `--color-accent` | `light-dark(oklch(0.
|
|
112
|
-
| `--color-accent-hover` | `light-dark(oklch(0.
|
|
113
|
-
| `--color-accent-ink` | `light-dark(oklch(0.
|
|
114
|
-
| `--color-accent-text` | `light-dark(oklch(0.
|
|
115
|
-
| `--color-accent-soft` | `light-dark(oklch(0.
|
|
116
|
-
| `--color-highlight` | `light-dark(oklch(0.
|
|
100
|
+
| `--color-canvas` | `light-dark(oklch(0.952 0.006 250), oklch(0.17 0.008 250))` |
|
|
101
|
+
| `--color-surface` | `light-dark(oklch(0.995 0.002 250), oklch(0.215 0.009 250))` |
|
|
102
|
+
| `--color-surface-sunken` | `light-dark(oklch(0.935 0.006 250), oklch(0.14 0.008 250))` |
|
|
103
|
+
| `--color-surface-raised` | `light-dark(oklch(0.998 0.002 250), oklch(0.25 0.009 250))` |
|
|
104
|
+
| `--color-surface-inverse` | `light-dark(oklch(0.26 0.06 256), oklch(0.93 0.012 250))` |
|
|
105
|
+
| `--color-ink` | `light-dark(oklch(0.26 0.06 256), oklch(0.94 0.01 250))` |
|
|
106
|
+
| `--color-ink-muted` | `light-dark(oklch(0.42 0.06 256), oklch(0.77 0.015 250))` |
|
|
107
|
+
| `--color-ink-subtle` | `light-dark(oklch(0.47 0.06 256), oklch(0.66 0.015 250))` |
|
|
108
|
+
| `--color-ink-inverse` | `light-dark(oklch(0.96 0.006 250), oklch(0.2 0.05 256))` |
|
|
109
|
+
| `--color-line` | `light-dark(oklch(0.9 0.006 250), oklch(0.3 0.01 250))` |
|
|
110
|
+
| `--color-line-strong` | `light-dark(oklch(0.78 0.012 252), oklch(0.42 0.012 250))` |
|
|
111
|
+
| `--color-accent` | `light-dark(oklch(0.37 0.1 255), oklch(0.86 0.06 250))` |
|
|
112
|
+
| `--color-accent-hover` | `light-dark(oklch(0.31 0.095 255), oklch(0.92 0.045 250))` |
|
|
113
|
+
| `--color-accent-ink` | `light-dark(oklch(0.985 0.005 250), oklch(0.2 0.05 256))` |
|
|
114
|
+
| `--color-accent-text` | `light-dark(oklch(0.35 0.1 255), oklch(0.86 0.06 250))` |
|
|
115
|
+
| `--color-accent-soft` | `light-dark(oklch(0.93 0.025 252), oklch(0.285 0.03 252))` |
|
|
116
|
+
| `--color-highlight` | `light-dark(oklch(0.925 0.045 228), oklch(0.33 0.05 235))` |
|
|
117
117
|
| `--color-highlight-ink` | `var(--color-ink)` |
|
|
118
118
|
| `--color-focus` | `var(--color-ink)` |
|
|
119
119
|
| `--color-selection` | `light-dark(oklch(0.88 0.06 228), oklch(0.42 0.07 235))` |
|
|
120
|
-
| `--color-scrim` | `light-dark(oklch(0.22 0.
|
|
120
|
+
| `--color-scrim` | `light-dark(oklch(0.22 0.04 258 / 0.4), oklch(0.07 0.01 250 / 0.66))` |
|
|
121
121
|
| `--tone-positive` | `light-dark(oklch(0.52 0.11 155), oklch(0.72 0.12 158))` |
|
|
122
122
|
| `--tone-positive-soft` | `light-dark(oklch(0.94 0.035 155), oklch(0.28 0.045 158))` |
|
|
123
123
|
| `--tone-positive-text` | `light-dark(oklch(0.45 0.1 155), oklch(0.78 0.11 158))` |
|
|
@@ -141,8 +141,8 @@ Colour:
|
|
|
141
141
|
| `--color-cat-5` | `light-dark(oklch(0.8 0.05 300), oklch(0.7 0.06 300))` |
|
|
142
142
|
| `--color-cat-6` | `light-dark(oklch(0.82 0.06 125), oklch(0.72 0.07 125))` |
|
|
143
143
|
| `--color-cat-7` | `light-dark(oklch(0.8 0.05 195), oklch(0.7 0.06 195))` |
|
|
144
|
-
| `--color-cat-8` | `light-dark(oklch(0.8 0.01
|
|
145
|
-
| `--color-cat-ink` | `oklch(0.21 0.
|
|
144
|
+
| `--color-cat-8` | `light-dark(oklch(0.8 0.01 250), oklch(0.7 0.01 250))` |
|
|
145
|
+
| `--color-cat-ink` | `oklch(0.21 0.03 258)` |
|
|
146
146
|
|
|
147
147
|
Edges & depth:
|
|
148
148
|
|
|
@@ -151,13 +151,13 @@ Edges & depth:
|
|
|
151
151
|
| `--shadow-surface` | `none` |
|
|
152
152
|
| `--active-shift` | `0px` |
|
|
153
153
|
| `--shadow-active` | `none` |
|
|
154
|
-
| `--shadow-float` | `0 1px 2px oklch(0.2 0.
|
|
155
|
-
| `--shadow-overlay` | `0 2px 4px oklch(0.15 0.
|
|
154
|
+
| `--shadow-float` | `0 1px 2px oklch(0.2 0.04 258 / 0.1), 0 8px 24px -6px oklch(0.2 0.04 258 / 0.18)` |
|
|
155
|
+
| `--shadow-overlay` | `0 2px 4px oklch(0.15 0.04 258 / 0.12), 0 20px 56px -12px oklch(0.15 0.04 258 / 0.32)` |
|
|
156
156
|
| `--canvas-image` | `none` |
|
|
157
157
|
|
|
158
158
|
## Optional theme tokens
|
|
159
159
|
|
|
160
|
-
Some themes set a few more: Fiesta's inks for text on
|
|
160
|
+
Some themes set a few more: Fiesta's and Riso's inks for text on their tinted rows, Ledger's table rule. Every theme scope resets these first, so a theme nested inside another falls back to the component's default instead of inheriting its parent's value. Set them only when your theme's idea needs them:
|
|
161
161
|
|
|
162
162
|
`--canvas-image-size`, `--control-checked-border`, `--highlight-accent-text`, `--highlight-tone-caution-text`, `--highlight-tone-critical-text`, `--highlight-tone-info-text`, `--highlight-tone-positive-text`, `--marquee-edge`, `--numeral-scale`, `--numeral-weight`, `--section-divider-color`, `--stat-fit`, `--table-foot-rule`, `--table-head-font`
|
|
163
163
|
|
|
@@ -170,7 +170,7 @@ A component exposes a few tokens of its own where a theme might reasonably diffe
|
|
|
170
170
|
Radii are roles, not one global roundness. A theme can make actions pills and surfaces square.
|
|
171
171
|
|
|
172
172
|
|
|
173
|
-
One edge treatment per element: a border, a shadow or a change of fill, never all three. Static structure uses hairlines. Soft shadows are only for things that float, like popovers and dialogs. Fiesta
|
|
173
|
+
One edge treatment per element: a border, a shadow or a change of fill, never all three. Static structure uses hairlines. Soft shadows are only for things that float, like popovers and dialogs. Hard offsets never go on static surfaces in a new theme. Fiesta keeps its hard offset as a legacy preset: it's the print misregistration, and it _is_ the edge. Riso's misregistered offset, the second ink drum printing slightly off, is floating-only.
|
|
174
174
|
|
|
175
175
|
|
|
176
176
|
## Axes and scoping
|
|
@@ -178,13 +178,13 @@ One edge treatment per element: a border, a shadow or a change of fill, never al
|
|
|
178
178
|
Three attributes select tokens, and they're independent of each other.
|
|
179
179
|
|
|
180
180
|
```html
|
|
181
|
-
<html data-theme="
|
|
182
|
-
<div data-theme="
|
|
181
|
+
<html data-theme="flightdeck" data-mode="dark">
|
|
182
|
+
<div data-theme="riso">a Riso panel that keeps the page's dark mode</div>
|
|
183
183
|
<div data-density="compact">a denser table</div>
|
|
184
184
|
</html>
|
|
185
185
|
```
|
|
186
186
|
|
|
187
|
-
- `data-theme` is `paper`, `monograph`, `ledger`, `fiesta`, or the name of a theme you wrote. No attribute means Paper.
|
|
187
|
+
- `data-theme` is `paper`, `monograph`, `ledger`, `fiesta`, `flightdeck`, `riso`, or the name of a theme you wrote. No attribute means Paper.
|
|
188
188
|
- `data-mode` is `light`, `dark` or `system`. It drives `color-scheme`, which drives every `light-dark()` colour. Leave it off nested scopes and they inherit the page's mode.
|
|
189
189
|
- `data-density` is `compact` or `comfortable`, and multiplies the theme's own density.
|
|
190
190
|
|
|
@@ -20,7 +20,7 @@ A theme picks at most two families (plus a mono where it needs one) and assigns
|
|
|
20
20
|
| Numeric | `--font-numeric`, `--numeric-stretch` | `Numeral`, `Amount`, `Stat`, numeric cells |
|
|
21
21
|
| Mono | `--font-mono`, `--mono-stretch` | `Code`, `CodeBlock`, `Kbd` |
|
|
22
22
|
|
|
23
|
-
Fiesta sets `--heading-transform: uppercase` for poster headlines
|
|
23
|
+
Fiesta sets `--heading-transform: uppercase` for poster headlines. Ledger sets `--numeric-stretch` so its figures use a condensed width of the same family, and a column of money reads like receipt tape. Flightdeck keeps its numerals in B612, whose digits are already equal width, so columns align without a monospace. Neither needed a component change. Riso's Shantell Sans has no tabular figures, so its numerals don't line up in columns.
|
|
24
24
|
|
|
25
25
|
## The scale
|
|
26
26
|
|
|
@@ -50,12 +50,15 @@ Every number that aligns or updates uses tabular, lining figures: counts, money,
|
|
|
50
50
|
|
|
51
51
|
Kiln self-hosts every face its themes use, so there's nothing to set up:
|
|
52
52
|
|
|
53
|
-
| Face
|
|
54
|
-
|
|
|
55
|
-
|
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
| Face | Used by | Ships in |
|
|
54
|
+
| ---------------------------------- | ------------------------------- | ------------------------------------------- |
|
|
55
|
+
| Golos Text | Paper | `styles.css` |
|
|
56
|
+
| Atkinson Hyperlegible Mono | code in Paper, Ledger and Riso | `styles.css` |
|
|
57
|
+
| Newsreader, Schibsted Grotesk | Monograph | `themes/monograph.css` |
|
|
58
|
+
| Martian Mono | code in Monograph and Fiesta | `themes/monograph.css`, `themes/fiesta.css` |
|
|
59
|
+
| Archivo | Ledger | `themes/ledger.css` |
|
|
60
|
+
| Big Shoulders, Bricolage Grotesque | Fiesta | `themes/fiesta.css` |
|
|
61
|
+
| B612, B612 Mono | Flightdeck (B612 Mono for code) | `themes/flightdeck.css` |
|
|
62
|
+
| Shantell Sans | Riso | `themes/riso.css` |
|
|
63
|
+
|
|
64
|
+
Browsers download a face only when something renders in it, so a declared face you never use costs nothing. All of them are licensed under the SIL Open Font License 1.1, and the licences ship in the package at `dist/assets/fonts/licenses/`. A theme of your own loads its own fonts: see [Theming](../SKILL.md#5-load-its-fonts).
|
|
@@ -20,7 +20,7 @@ These rules come from [DESIGN.md](https://github.com/mitcsutt/kiln/blob/main/DES
|
|
|
20
20
|
## Principles
|
|
21
21
|
|
|
22
22
|
1. **Themes are data, components are structure.** A component never knows which theme it is in. Everything visual is a token; a new theme is one CSS file and zero component changes.
|
|
23
|
-
2. **One idea per theme, drawn from its subject.** Paper is
|
|
23
|
+
2. **One idea per theme, drawn from its subject.** Paper is an office that prints for everyone, on grey recycled stock in blue-black ink. Monograph is a scholar's monograph read under a desk lamp. Ledger is an accountant's columnar pad. Fiesta is a screen-printed festival poster. Flightdeck is a glass-cockpit display. Riso is a two-drum risograph zine. Monograph and Fiesta predate the second-order rules in §2 and keep their original design for compatibility (Fiesta's status and categorical inks have since been tuned apart for real use). Every choice in a theme designed since has a one-line reason traced to its subject, written in the stylesheet next to the value. If you can't write the reason, the choice is wrong and it doesn't ship.
|
|
24
24
|
3. **Props, not styles.** Consumers compose layout and intent through typed props (`gap={5}`, `tone="critical"`, `width="text"`). No utility classes, no inline style soup, no raw px/hex/ms at call sites. `className` exists as an escape hatch, not a workflow.
|
|
25
25
|
4. **Durable by default.** Every component forwards refs, spreads native props, works with React 18 and 19, is keyboard- and screen-reader-complete, respects `prefers-reduced-motion`, and renders on the server.
|
|
26
26
|
5. **Specific beats safe.** The median choice is the wrong choice (see [Not AI slop](#not-ai-slop)).
|
|
@@ -34,16 +34,45 @@ Generated UI converges on the statistical median: indigo buttons, Inter, gradien
|
|
|
34
34
|
- Authored in **OKLCH**. Neutrals are **tinted** (chroma 0.004–0.02 toward the theme's hue). Never `#000`/`#fff` surfaces, never stock slate/zinc.
|
|
35
35
|
- **One accent, ~5–10% of pixels**: the primary action, the current item, live state, key data. A second hue only when it carries meaning (`--color-highlight` = "you" / selected; tones = status).
|
|
36
36
|
- **No gradients** unless they encode data. No gradient text. No glow halos in dark mode.
|
|
37
|
-
- No indigo/violet as a primary. No cream `#F4F1EA`
|
|
37
|
+
- No indigo/violet as a primary. No warm cream canvas (such as `#F4F1EA`) and no terracotta or ember accent (such as `#D97757`). See _Second-order tells_ below.
|
|
38
38
|
|
|
39
39
|
### Type
|
|
40
40
|
|
|
41
41
|
- **Two families max per theme** (+ a mono for code/figures where the theme needs it), clearly distinct, one with real character.
|
|
42
42
|
- **Big contrast**: the largest display step is ≥ 5× body. Display tracking tightens with size (−0.02 to −0.04em); line-height drops to ~0.9–1.05.
|
|
43
43
|
- **`tabular-nums` on every number that aligns or updates**: counts, money, tables, dates. `<Numeral>`/`<Amount>` do this for you.
|
|
44
|
+
- **Navigation text stays off the caption steps.** Links, nav items and tabs are read and scanned like body copy: `NavLinks` is `--text-md` (`sm`: `--text-sm`), and no navigation label uses `--text-xs` or `--text-2xs`. Those steps are for captions, badges, keyboard hints and metadata. A label that must stay compact, like `BottomNav`'s under its icon, floors at `0.75rem`. The `Usage` stories of `NavLinks`, `Tabs` and `BottomNav` enforce this in the browser (`pnpm test:storybook`), checking each label's computed size in the current theme.
|
|
44
45
|
- Prose measure ≤ 70ch (`width="text"`). `text-wrap: balance` on headings, `pretty` on paragraphs (the reset does it).
|
|
45
46
|
- **Banned patterns:** accenting one word of a headline in italic/colour; a tracked ALL-CAPS eyebrow over every section; `01 / 02 / 03` numbering on things that aren't a sequence; monospace used as decoration for small labels.
|
|
46
47
|
|
|
48
|
+
### Second-order tells
|
|
49
|
+
|
|
50
|
+
Models that are told to avoid the tells above converge on a second set instead ([research](https://github.com/mitcsutt/kiln/blob/main/docs/research/ai-design-tells.md), [ADR 0030](https://github.com/mitcsutt/kiln/blob/main/docs/adr/0030-theme-family-without-ai-tells.md)). None of these ships in a new built-in theme:
|
|
51
|
+
|
|
52
|
+
- A **cream or warm-paper canvas** (hue 40 to 100, with any visible chroma), including apricot and beige.
|
|
53
|
+
- An **ember, terracotta or burnt-orange accent**.
|
|
54
|
+
- A **near-black canvas with one acid or ember accent**.
|
|
55
|
+
- A **mint or sage canvas with a forest-green accent**, which is the cream tell in another hue.
|
|
56
|
+
- **Hard-offset "neo-brutalist" shadows on static surfaces.** A hard offset is allowed only where the theme's subject explains it, and only on floating layers. Fiesta, the legacy preset, keeps its hard offset on static surfaces; no new theme may.
|
|
57
|
+
- **Grain, noise or halftone** on the canvas (`--canvas-image` stays `none`).
|
|
58
|
+
- **Monospace beyond code**: for labels, eyebrows or every figure as decoration. A mono is allowed for figures only when the subject really uses one.
|
|
59
|
+
- A **serif display with one italic accent word**.
|
|
60
|
+
- A font from the banned list below.
|
|
61
|
+
|
|
62
|
+
`packages/ui/src/themes/tells.test.ts` enforces the checkable part for Paper, Ledger, Flightdeck and Riso, reading the light half of each `light-dark()` pair:
|
|
63
|
+
|
|
64
|
+
- no banned font family in their stylesheets or in any font stylesheet under `tokens/` except the legacy ones;
|
|
65
|
+
- no warm-cream canvas: `--color-canvas` fails when its lightness is above 0.85, its chroma above 0.008 and its hue 40 to 100;
|
|
66
|
+
- no ember, terracotta or indigo accent: `--color-accent` fails when its chroma is above 0.08 and its hue is 25 to 60 (ember) or above 262 up to 300 (indigo).
|
|
67
|
+
|
|
68
|
+
The rest is review.
|
|
69
|
+
|
|
70
|
+
**Legacy exemption.** Monograph and Fiesta are listed as `LEGACY` in that test and are exempt, along with the font stylesheets only they use (`fonts-monograph.css`, `fonts-fiesta.css` and `fonts-martian-mono.css`), because they keep their design from before these rules ([ADR 0030](https://github.com/mitcsutt/kiln/blob/main/docs/adr/0030-theme-family-without-ai-tells.md)). Monograph still has its ember accent and serif display, and Fiesta its apricot canvas and halftone. Do not treat them as precedent: a new theme gets no exemption, and a redesigned Monograph or Fiesta loses its own.
|
|
71
|
+
|
|
72
|
+
The banned font families, from the research: the first-order defaults plus the faces models now reach for as "distinctive" escapes (several are on Anthropic's own recommended list): Inter, Roboto, Open Sans, Poppins, Montserrat, Space Grotesk, Space Mono, Geist, DM Sans, DM Serif, Manrope, Plus Jakarta Sans, Outfit, Sora, Syne, Satoshi, Cabinet Grotesk, Clash Display, General Sans, Instrument Sans, Instrument Serif, Fraunces, Playfair Display, Cormorant, Lora, EB Garamond, Newsreader, Bricolage Grotesque, IBM Plex, JetBrains Mono and Fira Code. The list goes stale as model defaults move: change the list in the test and here together.
|
|
73
|
+
|
|
74
|
+
Beyond the checks, a theme has a subject, and each colour, face, radius and easing has a one-line reason in the stylesheet that traces it to that subject. Each theme also mixes radii on purpose (for example square fields with pill chips), so no theme is one uniform roundness.
|
|
75
|
+
|
|
47
76
|
### Layout
|
|
48
77
|
|
|
49
78
|
- **Left-aligned by default.** Centre is an exception (empty states, a lone CTA).
|
|
@@ -55,15 +84,17 @@ Generated UI converges on the statistical median: indigo buttons, Inter, gradien
|
|
|
55
84
|
### Components & depth
|
|
56
85
|
|
|
57
86
|
- **Radii are roles**, not a global roundness: `--radius-action`, `--radius-field`, `--radius-surface`, `--radius-media`, `--radius-chip`, `--radius-avatar`. Nested radii shrink (inner = outer − padding).
|
|
58
|
-
- **One edge treatment per element**: a border _or_ a shadow _or_ a fill change. Static structure uses hairlines; soft shadows are only for things that float (popover, menu, dialog). Fiesta
|
|
59
|
-
- **Icons**: the library ships ~
|
|
87
|
+
- **One edge treatment per element**: a border _or_ a shadow _or_ a fill change. Static structure uses hairlines; soft shadows are only for things that float (popover, menu, dialog). Hard-offset shadows never go on static surfaces in a new theme. Fiesta keeps its hard offset as a legacy preset: it is the print misregistration, and it _is_ the edge. Riso's misregistered offset (the second ink drum slightly off) is floating-only.
|
|
88
|
+
- **Icons**: the library ships ~40 glyphs on a 20px grid with a themed stroke: the ones its components need, plus common navigation and page-furniture glyphs so apps don't mix in a second set. At most one icon per row; never an icon in a tinted chip; never emoji as UI.
|
|
60
89
|
- **No left-border-accent callouts.** Alerts are a neutral hairline frame; the tone lives only in the glyph and a short tab on the top edge (`variant="soft"` for a tinted box when it must shout).
|
|
61
|
-
- **
|
|
90
|
+
- **Categorical colour marks who, never how.** A row or card with `color` draws a thin rail or a top keyline in `--color-cat-N`, matching that person's or team's `Tag` and `Avatar`. It's identity, not status or emphasis, so it's not the accent callout above; tones stay in badges and figures.
|
|
91
|
+
- **Empty states** mark their frame with printer's crop marks, not a dashed box. So does a placeholder `Card`, a slot not yet decided.
|
|
62
92
|
- **Focus is neutral** (`--color-focus` = ink) and always visible on `:focus-visible`. Focus must never look like validation; only error/warning/success tint a field.
|
|
63
93
|
|
|
64
94
|
### Motion
|
|
65
95
|
|
|
66
96
|
- Motion answers an action or shows a state change (count updated, row expanded, panel opened). **No fade-up-on-scroll, no hover-scale on static cards, no parallax.**
|
|
97
|
+
- To point at something that just changed or that a link just opened on, wrap it in `Flash`: one primitive for any element, not a flash prop on each component. It's an outline that fades, so it never moves layout, and under reduced motion it holds and goes instead of fading.
|
|
67
98
|
- Durations and easings are tokens (`--dur-1/2/3`, `--ease-out`, `--ease-spring`) and collapse to ~0 under `prefers-reduced-motion`.
|
|
68
99
|
|
|
69
100
|
### Copy (for stories, docs and examples)
|
|
@@ -92,7 +92,7 @@ export function Usage() {
|
|
|
92
92
|
|
|
93
93
|
`AppShell.Header`, `AppShell.Sidebar`, `AppShell.Main`, `AppShell.Footer` and `AppShell.BottomBar` place themselves, so their order in JSX doesn't affect the layout. Keep it the same as the reading order anyway: header, sidebar, main, footer, bottom bar.
|
|
94
94
|
|
|
95
|
-
- **Header** is sticky by default (`sticky={false}` to scroll it away). Put a `Container` and an `Inline` inside.
|
|
95
|
+
- **Header** is sticky by default (`sticky={false}` to scroll it away). While it sticks, in-page links and `scrollIntoView` land just below it, whatever its height. Put a `Container` and an `Inline` inside.
|
|
96
96
|
- **Sidebar** appears from `navBreakpoint` up. It sits at the start of the main region (`side="end"` for the other side), scrolls on its own, and stays below the header.
|
|
97
97
|
- **Main** is the `<main>` landmark and the skip link's target.
|
|
98
98
|
- **BottomBar** is pinned to the bottom of the viewport below `navBreakpoint`, and pads for the phone's home indicator.
|
|
@@ -117,7 +117,7 @@ Also accepts every prop of `HTMLAttributes<HTMLDivElement>`.
|
|
|
117
117
|
|
|
118
118
|
| Prop | Type | Default | Description |
|
|
119
119
|
| --- | --- | --- | --- |
|
|
120
|
-
| `sticky` | `boolean` | `true` | Stick to the top of the viewport while scrolling. Default `true`. |
|
|
120
|
+
| `sticky` | `boolean` | `true` | Stick to the top of the viewport while scrolling. Default `true`. While it sticks, in-page links and `scrollIntoView` land below it, however tall it grows. |
|
|
121
121
|
|
|
122
122
|
Also accepts every prop of `HTMLAttributes<HTMLElement>`.
|
|
123
123
|
|
|
@@ -39,7 +39,7 @@ export function Usage() {
|
|
|
39
39
|
| `padding` | `Responsive<Space>` | | Padding on every side. Responsive. |
|
|
40
40
|
| `paddingX` | `Responsive<Space>` | | Inline (left/right) padding; overrides `padding` on that axis. Responsive. |
|
|
41
41
|
| `paddingY` | `Responsive<Space>` | | Block (top/bottom) padding; overrides `padding` on that axis. Responsive. |
|
|
42
|
-
| `surface` | `'none' \| 'surface' \| 'canvas' \| 'sunken' \| 'raised' \| 'inverse'` | `none` | Background fill. `inverse` also re-
|
|
42
|
+
| `surface` | `'none' \| 'surface' \| 'canvas' \| 'sunken' \| 'raised' \| 'inverse' \| 'cat-6' \| 'cat-3' \| 'cat-5' \| 'cat-1' \| 'cat-2' \| 'cat-4' \| 'cat-7' \| 'cat-8'` | `none` | Background fill. `inverse` and the categorical `cat-1` to `cat-8` (one person's or team's colour, matching their `Tag`) also re-point ink and line colours for its children. |
|
|
43
43
|
| `border` | `boolean` | `false` | Hairline border in `--color-line`. One edge treatment per element — a border *or* a fill. |
|
|
44
44
|
| `radius` | `'none' \| 'surface' \| 'field' \| 'media'` | `none` | Corner radius, by role. |
|
|
45
45
|
| `as` | `'div' \| 'section' \| 'article' \| 'aside' \| 'header' \| 'footer' \| 'li' \| 'span'` | `div` | |
|
|
@@ -8,6 +8,8 @@ Source: https://kiln.mitchellsutton.com/docs/ui/layout/divider
|
|
|
8
8
|
|
|
9
9
|
`Divider` separates groups. For a rule between every item of a list, use `Stack dividers` instead, which spaces the rules for you.
|
|
10
10
|
|
|
11
|
+
A labelled divider is a band rather than a separator: its label is content that screen readers read in place, and the rules either side of it are decorative.
|
|
12
|
+
|
|
11
13
|
A labelled divider names the group that follows. `spacing` adds space above and below from the space scale, `strong` uses the stronger line colour, and `decorative` hides the rule from assistive technology when it carries no meaning (it's a `separator` otherwise).
|
|
12
14
|
|
|
13
15
|
```tsx
|
|
@@ -32,6 +34,33 @@ export function Usage() {
|
|
|
32
34
|
}
|
|
33
35
|
```
|
|
34
36
|
|
|
37
|
+
## Block label
|
|
38
|
+
|
|
39
|
+
A label can be a block: a few lines set into the rule, like a verdict and a time between two halves of a timetable. It's read in place as ordinary content.
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { Divider, Stack, Text } from '@mitcsutt/kiln-ui'
|
|
43
|
+
|
|
44
|
+
export function BlockLabel() {
|
|
45
|
+
return (
|
|
46
|
+
<Divider
|
|
47
|
+
labelPosition="center"
|
|
48
|
+
spacing={4}
|
|
49
|
+
label={
|
|
50
|
+
<Stack gap={1} align="center">
|
|
51
|
+
<Text size="sm" weight="strong">
|
|
52
|
+
Change at Harbour Square
|
|
53
|
+
</Text>
|
|
54
|
+
<Text size="sm" tone="muted">
|
|
55
|
+
Connection 6 minutes
|
|
56
|
+
</Text>
|
|
57
|
+
</Stack>
|
|
58
|
+
}
|
|
59
|
+
/>
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
35
64
|
## API
|
|
36
65
|
|
|
37
66
|
`DividerProps`:
|
|
@@ -40,7 +69,7 @@ export function Usage() {
|
|
|
40
69
|
| --- | --- | --- | --- |
|
|
41
70
|
| `orientation` | `'horizontal' \| 'vertical'` | `horizontal` | Default `horizontal`. A vertical rule stretches to its flex/grid row. |
|
|
42
71
|
| `strong` | `boolean` | `false` | Heavier rule in `--color-line-strong` at `--border-width-strong`. |
|
|
43
|
-
| `label` | `ReactNode` | |
|
|
72
|
+
| `label` | `ReactNode` | | Content set into a horizontal rule, e.g. "Earlier this week". It's real content, read like any text, and may be a block (a `Stack` of lines); the rules either side are decorative. |
|
|
44
73
|
| `labelPosition` | `'start' \| 'center'` | `start` | Where the label sits. Default `start` (left-aligned by default); `center` for a lone break. |
|
|
45
74
|
| `spacing` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 \| 11 \| 12` | | Margin on both sides of the rule (block axis if horizontal, inline if vertical). |
|
|
46
75
|
| `decorative` | `boolean` | `false` | Purely visual: hide it from assistive tech. Use when the rule only repeats a boundary that headings or landmarks already convey. |
|
|
@@ -39,9 +39,30 @@ export function Usage() {
|
|
|
39
39
|
}
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
## Categorical band
|
|
43
|
+
|
|
44
|
+
`surface="cat-1"` to `"cat-8"` paints a band in a categorical colour, one person's or team's colour, matching their `Tag`. Ink and lines flip to stay legible on it.
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { Container, Heading, Section, Stack, Text } from '@mitcsutt/kiln-ui'
|
|
48
|
+
|
|
49
|
+
export function CategoricalBand() {
|
|
50
|
+
return (
|
|
51
|
+
<Section surface="cat-2" space={6}>
|
|
52
|
+
<Container>
|
|
53
|
+
<Stack gap={2}>
|
|
54
|
+
<Heading level={2}>Ada's crew</Heading>
|
|
55
|
+
<Text tone="muted">Three boats, eleven crossings this week.</Text>
|
|
56
|
+
</Stack>
|
|
57
|
+
</Container>
|
|
58
|
+
</Section>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
42
63
|
## Surfaces and bands
|
|
43
64
|
|
|
44
|
-
`surface` is `canvas`, `surface`, `sunken`, `inverse` or `
|
|
65
|
+
`surface` is `canvas`, `surface`, `sunken`, `inverse`, `accent`, or a categorical `cat-1` to `cat-8` (a band in one person's or team's colour, matching their `Tag`). On `inverse`, `accent` and the categorical bands, the colour roles flip for everything inside, so text, links, focus rings and buttons stay legible with no extra props. `divider` adds a rule at the `top`, `bottom` or `both`.
|
|
45
66
|
|
|
46
67
|
## API
|
|
47
68
|
|
|
@@ -50,7 +71,7 @@ export function Usage() {
|
|
|
50
71
|
| Prop | Type | Default | Description |
|
|
51
72
|
| --- | --- | --- | --- |
|
|
52
73
|
| `space` | `Responsive<Space>` | `8` | Block padding (top and bottom), as a step on the space scale. Responsive. Vary it: adjacent sections should not share the same step. Default `8`. |
|
|
53
|
-
| `surface` | `'accent' \| 'surface' \| 'canvas' \| 'sunken' \| 'inverse'` | | Full-bleed band colour. Omit to stay transparent on the canvas. `inverse` and `
|
|
74
|
+
| `surface` | `'accent' \| 'surface' \| 'canvas' \| 'sunken' \| 'inverse' \| 'cat-6' \| 'cat-3' \| 'cat-5' \| 'cat-1' \| 'cat-2' \| 'cat-4' \| 'cat-7' \| 'cat-8'` | | Full-bleed band colour. Omit to stay transparent on the canvas. `inverse`, `accent` and the categorical `cat-1` to `cat-8` re-point the ink, line and focus colours so children stay legible. |
|
|
54
75
|
| `divider` | `'top' \| 'bottom' \| 'both'` | | A hairline across the full bleed at the top, bottom or both edges. |
|
|
55
76
|
| `as` | `'div' \| 'section' \| 'article' \| 'aside' \| 'header' \| 'footer'` | `section` | |
|
|
56
77
|
| `hideBelow` | `'sm' \| 'md' \| 'lg' \| 'xl'` | | Hide below this breakpoint (e.g. `md` → hidden on phones, shown from 48em). |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: setup-and-theming
|
|
3
|
-
description: "Use when installing @mitcsutt/kiln-ui in a React app: loading its stylesheet, wrapping the app in ThemeProvider, choosing Paper or a preset theme (Monograph, Ledger, Fiesta) and a colour mode, setting the theme before first paint with themeScript under SSR or the Next.js App Router, and passing router links through asChild."
|
|
3
|
+
description: "Use when installing @mitcsutt/kiln-ui in a React app: loading its stylesheet, wrapping the app in ThemeProvider, choosing Paper or a preset theme (Monograph, Ledger, Fiesta, Flightdeck, Riso) and a colour mode, setting the theme before first paint with themeScript under SSR or the Next.js App Router, and passing router links through asChild."
|
|
4
4
|
metadata:
|
|
5
5
|
purpose: Install kiln-ui, load its CSS, and apply a built-in theme and colour mode correctly on the client and the server.
|
|
6
6
|
type: lifecycle
|
|
@@ -11,6 +11,8 @@ sources:
|
|
|
11
11
|
- mitcsutt/kiln:apps/docs/content/docs/ui/themes/monograph.mdx
|
|
12
12
|
- mitcsutt/kiln:apps/docs/content/docs/ui/themes/ledger.mdx
|
|
13
13
|
- mitcsutt/kiln:apps/docs/content/docs/ui/themes/fiesta.mdx
|
|
14
|
+
- mitcsutt/kiln:apps/docs/content/docs/ui/themes/flightdeck.mdx
|
|
15
|
+
- mitcsutt/kiln:apps/docs/content/docs/ui/themes/riso.mdx
|
|
14
16
|
---
|
|
15
17
|
|
|
16
18
|
<!-- Generated from the Kiln docs by apps/docs/src/skills. Edit the docs pages, then run `pnpm generate:skills`. -->
|
|
@@ -54,14 +56,14 @@ With no `theme`, you get **Paper**, the neutral default. `ThemeProvider` writes
|
|
|
54
56
|
|
|
55
57
|
```tsx
|
|
56
58
|
import '@mitcsutt/kiln-ui/styles.css'
|
|
57
|
-
import '@mitcsutt/kiln-ui/themes/
|
|
59
|
+
import '@mitcsutt/kiln-ui/themes/flightdeck.css'
|
|
58
60
|
|
|
59
|
-
;<ThemeProvider theme="
|
|
61
|
+
;<ThemeProvider theme="flightdeck" defaultMode="dark">
|
|
60
62
|
…
|
|
61
63
|
</ThemeProvider>
|
|
62
64
|
```
|
|
63
65
|
|
|
64
|
-
Presets are separate files, so an app pays only for the ones it imports. [Themes](references/paper.md) shows all
|
|
66
|
+
Presets are separate files, so an app pays only for the ones it imports. [Themes](references/paper.md) shows all six, and [Theming](https://kiln.mitchellsutton.com/docs/ui/foundations/theming) shows how to write your own.
|
|
65
67
|
|
|
66
68
|
## Compose a screen
|
|
67
69
|
|
|
@@ -126,11 +128,11 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
126
128
|
The reader's mode is stored in `localStorage` under `kiln-color-mode`. Every app on one origin shares that key, so a choice made in one carries into the next. Give each app its own key with `storageKey`, or keep a key the app already used so returning readers keep their choice. Pass the same key to `themeScript`:
|
|
127
129
|
|
|
128
130
|
```tsx
|
|
129
|
-
;<ThemeProvider theme="ledger" defaultMode="light" storageKey="
|
|
131
|
+
;<ThemeProvider theme="ledger" defaultMode="light" storageKey="acme:color-mode">
|
|
130
132
|
…
|
|
131
133
|
</ThemeProvider>
|
|
132
134
|
|
|
133
|
-
themeScript('ledger', 'light', { storageKey: '
|
|
135
|
+
themeScript('ledger', 'light', { storageKey: 'acme:color-mode' })
|
|
134
136
|
```
|
|
135
137
|
|
|
136
138
|
### Without server rendering
|
|
@@ -150,7 +152,7 @@ export default defineConfig({
|
|
|
150
152
|
transformIndexHtml: () => [
|
|
151
153
|
{
|
|
152
154
|
tag: 'script',
|
|
153
|
-
children: themeScript('ledger', 'light', { storageKey: '
|
|
155
|
+
children: themeScript('ledger', 'light', { storageKey: 'acme:color-mode' }),
|
|
154
156
|
injectTo: 'head-prepend',
|
|
155
157
|
},
|
|
156
158
|
],
|
|
@@ -229,7 +231,9 @@ Merges class names, filtering falsy values.
|
|
|
229
231
|
|
|
230
232
|
Read a reference when its description matches the task:
|
|
231
233
|
|
|
232
|
-
- [Paper](references/paper.md): The neutral default.
|
|
234
|
+
- [Paper](references/paper.md): The neutral default. An office that prints for everyone, with white sheets on grey stock, blue-black ink as the accent and Golos Text for type.
|
|
233
235
|
- [Monograph](references/monograph.md): A scholarly monograph read under a desk lamp at night. Blue slate, one ember accent, a big serif display. Dark-first.
|
|
234
|
-
- [Ledger](references/ledger.md): An accountant's
|
|
236
|
+
- [Ledger](references/ledger.md): An accountant's columnar pad. A white sheet ruled in green, banknote-green actions, accounting red, and figures set condensed instead of in a monospace.
|
|
235
237
|
- [Fiesta](references/fiesta.md): A screen-printed festival poster. Flat spot inks, hard offsets, condensed signage numerals and springy motion.
|
|
238
|
+
- [Flightdeck](references/flightdeck.md): A glass-cockpit flight display. Cyan for what you set, a reverse-video box for what you select, and green, amber and red for status, set in B612. Dark-first.
|
|
239
|
+
- [Riso](references/riso.md): A two-drum risograph zine. Fluorescent pink and blue on white stock, screen tints instead of borders, and Shantell Sans.
|
|
@@ -8,6 +8,8 @@ Source: https://kiln.mitchellsutton.com/docs/ui/themes/fiesta
|
|
|
8
8
|
|
|
9
9
|
_A screen-printed festival poster and sticker album._ Screen printing can't do gradients, so neither does Fiesta: flat spot inks on apricot poster stock, everything keylined in aubergine, and a hard misregistered offset where other themes have a soft shadow.
|
|
10
10
|
|
|
11
|
+
Fiesta predates Kiln's [second-order design rules](https://kiln.mitchellsutton.com/docs/ui/foundations/design-rules#second-order-tells) and keeps its original design for compatibility, so it isn't the model for a new theme. Its status inks are kept apart for real use: the gold is only the highlight ("you"), caution is marigold, and critical is a deep brick that never reads as the coral accent.
|
|
12
|
+
|
|
11
13
|
|
|
12
14
|
## Use it
|
|
13
15
|
|
|
@@ -21,7 +23,7 @@ import { ThemeProvider } from '@mitcsutt/kiln-ui'
|
|
|
21
23
|
</ThemeProvider>
|
|
22
24
|
```
|
|
23
25
|
|
|
24
|
-
Fiesta's
|
|
26
|
+
Fiesta's faces (Big Shoulders, Bricolage Grotesque and Martian Mono for code) are declared in its own stylesheet, so they cost nothing unless you import it. It's light-first (the daytime show); dark mode is the floodlit night show.
|
|
25
27
|
|
|
26
28
|
## The idea, applied
|
|
27
29
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<!-- Generated from the Kiln docs by apps/docs/src/skills. Edit the docs pages, then run `pnpm generate:skills`. -->
|
|
2
|
+
|
|
3
|
+
# Flightdeck
|
|
4
|
+
|
|
5
|
+
> A glass-cockpit flight display. Cyan for what you set, a reverse-video box for what you select, and green, amber and red for status, set in B612. Dark-first.
|
|
6
|
+
|
|
7
|
+
Source: https://kiln.mitchellsutton.com/docs/ui/themes/flightdeck
|
|
8
|
+
|
|
9
|
+
_A glass-cockpit flight display._ Flightdeck follows the colour convention of electronic flight instruments, where each colour has one fixed meaning, and sets everything in the typefaces designed for Airbus cockpit displays.
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## Use it
|
|
13
|
+
|
|
14
|
+
Flightdeck is a preset, so import its stylesheet. It's dark-first, so pair it with `defaultMode="dark"`, and give `themeScript` the same:
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import '@mitcsutt/kiln-ui/styles.css'
|
|
18
|
+
import '@mitcsutt/kiln-ui/themes/flightdeck.css'
|
|
19
|
+
import { ThemeProvider, themeScript } from '@mitcsutt/kiln-ui'
|
|
20
|
+
|
|
21
|
+
;<html lang="en">
|
|
22
|
+
<head>
|
|
23
|
+
<script dangerouslySetInnerHTML={{ __html: themeScript('flightdeck', 'dark') }} />
|
|
24
|
+
</head>
|
|
25
|
+
<body>
|
|
26
|
+
<ThemeProvider theme="flightdeck" defaultMode="dark">
|
|
27
|
+
…
|
|
28
|
+
</ThemeProvider>
|
|
29
|
+
</body>
|
|
30
|
+
</html>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## The idea, applied
|
|
34
|
+
|
|
35
|
+
- **Colour.** The cockpit convention, mapped onto Kiln's roles. Cyan is the accent: what the pilot sets and acts on. What you selected is a neutral reverse-video box, like the selected line of a flight-management display. Green, amber and red are the positive, caution and critical tones, and info is steel blue. Neutrals are dark blue-grey display glass, never black. Light mode is the day mode of an electronic flight bag: pale cool grey with the cyan darkened to pass contrast.
|
|
36
|
+
- **Type.** B612 for text, display and figures (its digits are already equal width), and B612 Mono for code. B612 ships static regular and bold weights and a Latin subset only, so Latin Extended text falls back to a system face. There are no uppercase transforms.
|
|
37
|
+
- **Shape.** Square instrument bezels: small radii on actions, fields and surfaces. Chips are pills, like annunciator capsules.
|
|
38
|
+
- **Depth.** Hairlines, with no shadow on static surfaces. Floating layers add a very subtle dark shadow, with no glow.
|
|
39
|
+
- **Motion.** Instruments move linearly and quickly: a gentle ease-out, a little faster than the default, and no bounce.
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
# Ledger
|
|
4
4
|
|
|
5
|
-
> An accountant's
|
|
5
|
+
> An accountant's columnar pad. A white sheet ruled in green, banknote-green actions, accounting red, and figures set condensed instead of in a monospace.
|
|
6
6
|
|
|
7
7
|
Source: https://kiln.mitchellsutton.com/docs/ui/themes/ledger
|
|
8
8
|
|
|
9
|
-
_An accountant's
|
|
9
|
+
_An accountant's columnar pad._ Quiet, dense and numeric. In Ledger the numbers are the content, so they get their own treatment: the same face set condensed, always tabular, so a column of money reads like receipt tape.
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
## Use it
|
|
@@ -25,8 +25,8 @@ Ledger is light-first. It suits screens that are mostly tables and totals: invoi
|
|
|
25
25
|
|
|
26
26
|
## The idea, applied
|
|
27
27
|
|
|
28
|
-
- **Colour.**
|
|
29
|
-
- **Type.**
|
|
30
|
-
- **Shape.**
|
|
31
|
-
- **Depth.** Hairlines, and a double rule above a table's footer (`--table-foot-rule`), as a ledger totals a column.
|
|
32
|
-
- **Motion.** Brief and flat (`--motion-scale: 0.8`).
|
|
28
|
+
- **Colour.** A white sheet, with the green carried by the rules rather than the paper. Banknote green for actions, accounting red for negatives and a flat highlighter yellow for the highlight. Dark mode is a blue-green carbon-copy night with dim green rules, not a green-screen terminal.
|
|
29
|
+
- **Type.** Archivo throughout. Figures use its width axis to set condensed (`--numeric-stretch`) with tabular numerals, so they get receipt-tape narrowness without a monospace. Atkinson Hyperlegible Mono is for code only. A 15px base on a 1.2 ratio.
|
|
30
|
+
- **Shape.** Tight radii on actions, fields and surfaces, squarer chips, and rounded-square avatars like ledger stamps. A compact density of 0.86, so every space step and control is smaller.
|
|
31
|
+
- **Depth.** Hairlines in the ledger green, with flat surfaces, and a double rule above a table's footer (`--table-foot-rule`), as a ledger totals a column.
|
|
32
|
+
- **Motion.** Brief and flat, with no bounce (`--motion-scale: 0.8`).
|
|
@@ -8,6 +8,8 @@ Source: https://kiln.mitchellsutton.com/docs/ui/themes/monograph
|
|
|
8
8
|
|
|
9
9
|
_A scholarly monograph read under a desk lamp at night._ Modern nostalgia: blue slate rather than black, a single ember accent that behaves like phosphor, and a serif display set big and tight over a newsroom grotesk.
|
|
10
10
|
|
|
11
|
+
Monograph predates Kiln's [second-order design rules](https://kiln.mitchellsutton.com/docs/ui/foundations/design-rules#second-order-tells) and ships unchanged for compatibility, so it isn't the model for a new theme.
|
|
12
|
+
|
|
11
13
|
|
|
12
14
|
## Use it
|
|
13
15
|
|
|
@@ -30,6 +32,8 @@ import { ThemeProvider, themeScript } from '@mitcsutt/kiln-ui'
|
|
|
30
32
|
</html>
|
|
31
33
|
```
|
|
32
34
|
|
|
35
|
+
Its faces (Newsreader, Schibsted Grotesk and Martian Mono) are declared in its own stylesheet, so they cost nothing unless you import it.
|
|
36
|
+
|
|
33
37
|
## The idea, applied
|
|
34
38
|
|
|
35
39
|
- **Colour.** Blue-slate neutrals (hue 255, never black). One ember accent (`oklch(0.72 0.15 52)` in dark, `oklch(0.565 0.158 44)` in light) that marks what's live and current, and never decorates. A cool slate highlight.
|