@hubpav/hwio-brand 0.6.5 → 0.7.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,217 @@
1
+ ---
2
+ name: "ENEROOO"
3
+ description: "Teal and green on white with graphite footer, Poppins, pill fields, 24 px card radius. Generated from @hubpav/hwio-brand; the source of truth is brand.json."
4
+ colors:
5
+ primary: "#14A0C0"
6
+ primary-content: "#ffffff"
7
+ secondary: "#01CC9B"
8
+ secondary-content: "#061920"
9
+ accent: "#0C6678"
10
+ accent-content: "#ffffff"
11
+ neutral: "#404040"
12
+ neutral-content: "#ffffff"
13
+ base-100: "#ffffff"
14
+ base-200: "#f9fafb"
15
+ base-300: "#f3f4f6"
16
+ base-content: "#333333"
17
+ info: "#19768B"
18
+ info-content: "#ffffff"
19
+ success: "#15803d"
20
+ success-content: "#ffffff"
21
+ warning: "#b45309"
22
+ warning-content: "#ffffff"
23
+ error: "#dc2626"
24
+ error-content: "#ffffff"
25
+ typography:
26
+ display:
27
+ fontFamily: "'Poppins', 'Poppins Fallback', ui-sans-serif, system-ui, sans-serif"
28
+ fontSize: "3.5rem"
29
+ fontWeight: 700
30
+ lineHeight: 1.05
31
+ letterSpacing: "-0.03em"
32
+ heading:
33
+ fontFamily: "'Poppins', 'Poppins Fallback', ui-sans-serif, system-ui, sans-serif"
34
+ fontSize: "2.5rem"
35
+ fontWeight: 700
36
+ lineHeight: 1.1
37
+ letterSpacing: "-0.025em"
38
+ subheading:
39
+ fontFamily: "'Poppins', 'Poppins Fallback', ui-sans-serif, system-ui, sans-serif"
40
+ fontSize: "1.375rem"
41
+ fontWeight: 700
42
+ lineHeight: 1.2
43
+ letterSpacing: "-0.01em"
44
+ title:
45
+ fontFamily: "'Poppins', 'Poppins Fallback', ui-sans-serif, system-ui, sans-serif"
46
+ fontSize: "1.125rem"
47
+ fontWeight: 700
48
+ lineHeight: 1.3
49
+ letterSpacing: "-0.005em"
50
+ lead:
51
+ fontFamily: "'Poppins', 'Poppins Fallback', ui-sans-serif, system-ui, sans-serif"
52
+ fontSize: "1.1875rem"
53
+ fontWeight: 400
54
+ lineHeight: 1.55
55
+ letterSpacing: "0"
56
+ body:
57
+ fontFamily: "'Poppins', 'Poppins Fallback', ui-sans-serif, system-ui, sans-serif"
58
+ fontSize: "1.0625rem"
59
+ fontWeight: 400
60
+ lineHeight: 1.6
61
+ letterSpacing: "0"
62
+ kicker:
63
+ fontFamily: "'Poppins', 'Poppins Fallback', ui-sans-serif, system-ui, sans-serif"
64
+ fontSize: "0.875rem"
65
+ fontWeight: 600
66
+ lineHeight: 1.4
67
+ letterSpacing: "0"
68
+ button:
69
+ fontFamily: "'Poppins', 'Poppins Fallback', ui-sans-serif, system-ui, sans-serif"
70
+ fontSize: "0.9375rem"
71
+ fontWeight: 600
72
+ lineHeight: 1
73
+ letterSpacing: "0"
74
+ rounded:
75
+ selector: "2rem"
76
+ field: "2rem"
77
+ box: "1.5rem"
78
+ spacing:
79
+ unit: "8px"
80
+ section: "80px"
81
+ section-lg: "112px"
82
+ section-compact: "40px"
83
+ section-compact-lg: "48px"
84
+ container-hub: "1275px"
85
+ container-landing: "1640px"
86
+ container-pad: "27px"
87
+ control: "48px"
88
+ card-padding: "32px"
89
+ components:
90
+ button-primary:
91
+ backgroundColor: "{colors.primary}"
92
+ textColor: "{colors.primary-content}"
93
+ typography: "{typography.button}"
94
+ rounded: "{rounded.field}"
95
+ height: "48px"
96
+ button-secondary:
97
+ backgroundColor: "{colors.base-100}"
98
+ textColor: "{colors.primary}"
99
+ typography: "{typography.button}"
100
+ rounded: "{rounded.field}"
101
+ height: "48px"
102
+ button-inverse:
103
+ backgroundColor: "{colors.neutral-content}"
104
+ textColor: "{colors.neutral}"
105
+ typography: "{typography.button}"
106
+ rounded: "{rounded.field}"
107
+ height: "48px"
108
+ card:
109
+ backgroundColor: "{colors.base-100}"
110
+ textColor: "{colors.base-content}"
111
+ rounded: "{rounded.box}"
112
+ padding: "32px"
113
+ input:
114
+ backgroundColor: "{colors.base-100}"
115
+ textColor: "{colors.base-content}"
116
+ typography: "{typography.body}"
117
+ rounded: "{rounded.field}"
118
+ height: "48px"
119
+ kicker:
120
+ textColor: "{colors.accent}"
121
+ typography: "{typography.kicker}"
122
+ chip:
123
+ backgroundColor: "{colors.base-200}"
124
+ textColor: "{colors.base-content}"
125
+ typography: "{typography.kicker}"
126
+ rounded: "{rounded.selector}"
127
+ ---
128
+ <!-- Generated from @hubpav/hwio-brand (theme er3o) by packages/brand/scripts/build-design-md.mjs. Do not edit in a site: change packages/brand/src in hardwario/website-ui, publish, then run scripts/design-sync.sh in website-admin. -->
129
+
130
+ # ENEROOO design system
131
+
132
+ ## Overview
133
+
134
+ **Creative North Star: "The energy dashboard"**
135
+
136
+ ENEROOO is a separate brand on the shared component system: its palette and Poppins are preserved by owner ruling R7 and its footer graphite by R12. It is not part of the 2026 HARDWARIO redesign (R13); this file records the theme as built.
137
+
138
+ Key characteristics:
139
+
140
+ - One type family (Poppins), one accent, hairline structure, flat surfaces.
141
+ - Sentence-case labels and buttons everywhere ([R4](https://github.com/hardwario/website-admin/blob/main/DESIGN-SYSTEM.md)); kickers instead of uppercase eyebrows.
142
+ - Light is the default theme on every site; dark is a visitor's choice remembered without a consent gate (R11).
143
+ - Copy is the product: components carry the site's own words, never placeholder text.
144
+
145
+ **The Own-Brand Rule.** ENEROOO keeps its palette and Poppins (R7) and its footer graphite (R12). Changes need a screenshot sign-off by the owner.
146
+
147
+ ## Colors
148
+
149
+ Roles follow the DaisyUI 5 vocabulary so every `@hubpav/hwio-ui` component and every site utility resolves the same slot. Values below are the `er3o` light theme; the source of truth is `packages/brand/src/brand.json` in `hardwario/website-ui`.
150
+
151
+ | Role | Value | Use |
152
+ |---|---|---|
153
+ | `primary` / `primary-content` | `#14A0C0` on `#ffffff` | buttons, active states, links in navigation |
154
+ | `secondary` / `secondary-content` | `#01CC9B` on `#061920` | focus ring, secondary emphasis |
155
+ | `accent` / `accent-content` | `#0C6678` on `#ffffff` | kicker, current-page marker, inline links; never large fills |
156
+ | `neutral` / `neutral-content` | `#404040` on `#ffffff` | ink panels and the footer |
157
+ | `base-100` / `base-100-content` | `#ffffff` on `undefined` | page ground |
158
+ | `base-200` / `base-200-content` | `#f9fafb` on `undefined` | alternate section surface |
159
+ | `base-300` / `base-300-content` | `#f3f4f6` on `undefined` | hairline borders |
160
+ | `info` / `info-content` | `#19768B` on `#ffffff` | informational badges |
161
+ | `success` / `success-content` | `#15803d` on `#ffffff` | form success |
162
+ | `warning` / `warning-content` | `#b45309` on `#ffffff` | warnings |
163
+ | `error` / `error-content` | `#dc2626` on `#ffffff` | form errors |
164
+
165
+ **The Token Rule.** A colour, radius or type change is a `brand.json` edit and a `website-ui` pull request, never site-local CSS. Sites consume roles (`bg-primary`, `text-base-content`), not hex values.
166
+
167
+ **The One Accent Rule.** The accent carries the kicker, the current-page marker and inline links; it never fills large surfaces and never sets small body text (R5).
168
+
169
+
170
+
171
+ ## Typography
172
+
173
+ Poppins for everything: display, body, labels and numerals (tabular numerals in stats). The fallback face is metric-matched to Arial so the pre-paint gate (`font-display: block`, R3) never repaints a layout. The ramp tightens tracking as size grows.
174
+
175
+ | Role | Element | Size (large screens) | Weight | Line height | Tracking |
176
+ |---|---|---|---|---|---|
177
+ | display | `h1` | 3.5rem | 700 | 1.05 | -0.03em |
178
+ | heading | `h2` | 2.5rem | 700 | 1.1 | -0.025em |
179
+ | subheading | `h3` | 1.375rem | 700 | 1.2 | -0.01em |
180
+ | title | `h4` | 1.125rem | 700 | 1.3 | -0.005em |
181
+ | lead | `.hwio-lead` | 1.1875rem | 400 | 1.55 | 0 |
182
+ | body | `body` | 1.0625rem | 400 | 1.6 | 0 |
183
+ | kicker | `.hwio-kicker` | 0.875rem | 600 | 1.4 | 0 |
184
+ | button | `.btn` | 0.9375rem | 600 | 1 | 0 |
185
+
186
+ Smaller screens step the display and heading roles down (display: 2.5rem at base, 3rem at md, 3.5rem from 64rem; heading: 2rem at base, 2.5rem from 64rem). Headings use `text-wrap: balance`.
187
+
188
+ ## Layout
189
+
190
+ Two container presets from the theme: the hub width (1275px) for content-rich sites and the landing width (1640px) for the single-page marketing sites, both with 27px side padding. Sections stack on an 8 px rhythm: 80px (112px from 64rem) of vertical padding, compact bands 40px (48px from 64rem). Section content opens with a `HWioSectionHeader` in `stack` (centred) or `split` (5/7 grid, aligned to the baseline) layout; stats bands and choice cards divide with hairlines, not boxes.
191
+
192
+ ## Elevation & Depth
193
+
194
+ The system is flat. DaisyUI `depth` and `noise` are `0`; there are no shadow tokens. Structure comes from hairline borders (`base-300`) and surface shifts (`base-100` on `base-200`, ink panels on `neutral`). A dark-surface panel uses the `neutral` pair and the inverse button; nothing floats.
195
+
196
+ ## Shapes
197
+
198
+ Corner radii from the theme: fields 2rem, boxes 1.5rem, selectors 2rem. Borders are 1 px hairlines. Media inside cards is clipped to the box radius; hero media keeps its natural edges.
199
+
200
+ ## Components
201
+
202
+ - **Buttons.** `button-primary` (primary fill, primary-content text), `button-secondary` (primary outline on base-100), `button-inverse` for ink panels (neutral-content fill), `ghost` and `link`. All 48px tall, 0.9375rem at weight 600, sentence case, 2rem radius; large buttons widen padding at the same height.
203
+ - **Cards.** `card card-border` on base-100 with a hairline, 32px padding; the lead choice card carries a 3 px accent top border. Cards never nest.
204
+ - **Kicker and lead.** The kicker is the accent-coloured 0.875rem label above a heading; the lead is 1.1875rem muted text below it.
205
+ - **Inputs.** Field radius, hairline border, 48px tall; focus ring 2 px `secondary`.
206
+ - **Navigation.** `HWioHeader` with mega panels on wide screens (`desktopFrom="xl"` on sites with five or more items); the current page is marked by a 2 px bar on the header's bottom edge.
207
+ - **Bands.** `HWioStatsBand` (hairline top and bottom, vertical dividers, count-up with tabular numerals), `HWioCtaBand`, `HWioLogoStrip`.
208
+
209
+ ## Do's and Don'ts
210
+
211
+ - Do keep Poppins as the only text face; the detector's `overused-font` finding for Inter is waived by owner ruling R14 in `.impeccable/config.json`.
212
+ - Do use the theme roles for every colour; don't hard-code hex values in a site.
213
+ - Do keep buttons sentence case and 48px tall; don't uppercase labels or shrink touch targets below 44 px.
214
+ - Do keep dark mode a visitor's choice with the `hwio_theme` memory; don't follow the OS scheme by default (R11).
215
+ - Don't add inline styles, `style=` attributes or template-literal class names; `policy-lint` fails them.
216
+ - Don't nest cards, add glass or gradient effects, or animate anything above the fold.
217
+ - Don't set small body text in the accent colour (R5).
@@ -0,0 +1,233 @@
1
+ ---
2
+ name: "HARDWARIO (forestry.report)"
3
+ description: "The HARDWARIO system with the forestry green as primary and accent; Inter, hairline borders, 8 px rhythm, 48 px controls. Generated from @hubpav/hwio-brand; the source of truth is brand.json."
4
+ colors:
5
+ primary: "#2B7036"
6
+ primary-content: "#ffffff"
7
+ secondary: "#016ad4"
8
+ secondary-content: "#ffffff"
9
+ accent: "#2B7036"
10
+ accent-content: "#ffffff"
11
+ neutral: "#252532"
12
+ neutral-content: "#f3f4f6"
13
+ base-100: "#ffffff"
14
+ base-200: "#F1FAFF"
15
+ base-300: "#e5e7eb"
16
+ base-content: "#252532"
17
+ info: "#009cfa"
18
+ info-content: "#06367a"
19
+ success: "#15803d"
20
+ success-content: "#ffffff"
21
+ warning: "#b45309"
22
+ warning-content: "#ffffff"
23
+ error: "#dc2626"
24
+ error-content: "#ffffff"
25
+ typography:
26
+ display:
27
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
28
+ fontSize: "3.5rem"
29
+ fontWeight: 700
30
+ lineHeight: 1.05
31
+ letterSpacing: "-0.03em"
32
+ heading:
33
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
34
+ fontSize: "2.5rem"
35
+ fontWeight: 700
36
+ lineHeight: 1.1
37
+ letterSpacing: "-0.025em"
38
+ subheading:
39
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
40
+ fontSize: "1.375rem"
41
+ fontWeight: 700
42
+ lineHeight: 1.2
43
+ letterSpacing: "-0.01em"
44
+ title:
45
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
46
+ fontSize: "1.125rem"
47
+ fontWeight: 700
48
+ lineHeight: 1.3
49
+ letterSpacing: "-0.005em"
50
+ lead:
51
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
52
+ fontSize: "1.1875rem"
53
+ fontWeight: 400
54
+ lineHeight: 1.55
55
+ letterSpacing: "0"
56
+ body:
57
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
58
+ fontSize: "1.0625rem"
59
+ fontWeight: 400
60
+ lineHeight: 1.6
61
+ letterSpacing: "0"
62
+ kicker:
63
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
64
+ fontSize: "0.875rem"
65
+ fontWeight: 600
66
+ lineHeight: 1.4
67
+ letterSpacing: "0"
68
+ button:
69
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
70
+ fontSize: "0.9375rem"
71
+ fontWeight: 600
72
+ lineHeight: 1
73
+ letterSpacing: "0"
74
+ rounded:
75
+ selector: "2rem"
76
+ field: "0.5rem"
77
+ box: "1rem"
78
+ spacing:
79
+ unit: "8px"
80
+ section: "80px"
81
+ section-lg: "112px"
82
+ section-compact: "40px"
83
+ section-compact-lg: "48px"
84
+ container-hub: "1275px"
85
+ container-landing: "1640px"
86
+ container-pad: "27px"
87
+ control: "48px"
88
+ card-padding: "32px"
89
+ components:
90
+ button-primary:
91
+ backgroundColor: "{colors.primary}"
92
+ textColor: "{colors.primary-content}"
93
+ typography: "{typography.button}"
94
+ rounded: "{rounded.field}"
95
+ height: "48px"
96
+ button-secondary:
97
+ backgroundColor: "{colors.base-100}"
98
+ textColor: "{colors.primary}"
99
+ typography: "{typography.button}"
100
+ rounded: "{rounded.field}"
101
+ height: "48px"
102
+ button-inverse:
103
+ backgroundColor: "{colors.neutral-content}"
104
+ textColor: "{colors.neutral}"
105
+ typography: "{typography.button}"
106
+ rounded: "{rounded.field}"
107
+ height: "48px"
108
+ card:
109
+ backgroundColor: "{colors.base-100}"
110
+ textColor: "{colors.base-content}"
111
+ rounded: "{rounded.box}"
112
+ padding: "32px"
113
+ input:
114
+ backgroundColor: "{colors.base-100}"
115
+ textColor: "{colors.base-content}"
116
+ typography: "{typography.body}"
117
+ rounded: "{rounded.field}"
118
+ height: "48px"
119
+ kicker:
120
+ textColor: "{colors.accent}"
121
+ typography: "{typography.kicker}"
122
+ chip:
123
+ backgroundColor: "{colors.base-200}"
124
+ textColor: "{colors.base-content}"
125
+ typography: "{typography.kicker}"
126
+ rounded: "{rounded.selector}"
127
+ ---
128
+ <!-- Generated from @hubpav/hwio-brand (theme hwio-forestry) by packages/brand/scripts/build-design-md.mjs. Do not edit in a site: change packages/brand/src in hardwario/website-ui, publish, then run scripts/design-sync.sh in website-admin. -->
129
+
130
+ # HARDWARIO (forestry.report) design system
131
+
132
+ ## Overview
133
+
134
+ **Creative North Star: "The instrument panel, in the forest"**
135
+
136
+ forestry.report is a HARDWARIO landing page for forestry managers. It shares every component and rule with the family and swaps the primary and accent roles to the forestry green so the vertical is recognisable at a glance. This file documents the system as built on 2026-09-07; the 2026 redesign evolves everything but the fixed constraints below.
137
+
138
+ Key characteristics:
139
+
140
+ - One type family (Inter), one accent, hairline structure, flat surfaces.
141
+ - Sentence-case labels and buttons everywhere ([R4](https://github.com/hardwario/website-admin/blob/main/DESIGN-SYSTEM.md)); kickers instead of uppercase eyebrows.
142
+ - Light is the default theme on every site; dark is a visitor's choice remembered without a consent gate (R11).
143
+ - Copy is the product: components carry the site's own words, never placeholder text.
144
+
145
+ **The Fixed Four Rule.** The HARDWARIO logo, red `#e30427` (kept in the brand mark), navy `#06367a` and Inter do not change (owner ruling R14, 2026-09-07). The forestry green is a theme role, not a brand colour, and may be re-weighted by the redesign.
146
+
147
+ ## Colors
148
+
149
+ Roles follow the DaisyUI 5 vocabulary so every `@hubpav/hwio-ui` component and every site utility resolves the same slot. Values below are the `hwio-forestry` light theme; the source of truth is `packages/brand/src/brand.json` in `hardwario/website-ui`.
150
+
151
+ | Role | Value | Use |
152
+ |---|---|---|
153
+ | `primary` / `primary-content` | `#2B7036` on `#ffffff` | buttons, active states, links in navigation |
154
+ | `secondary` / `secondary-content` | `#016ad4` on `#ffffff` | focus ring, secondary emphasis |
155
+ | `accent` / `accent-content` | `#2B7036` on `#ffffff` | kicker, current-page marker, inline links; never large fills |
156
+ | `neutral` / `neutral-content` | `#252532` on `#f3f4f6` | ink panels and the footer |
157
+ | `base-100` / `base-100-content` | `#ffffff` on `undefined` | page ground |
158
+ | `base-200` / `base-200-content` | `#F1FAFF` on `undefined` | alternate section surface |
159
+ | `base-300` / `base-300-content` | `#e5e7eb` on `undefined` | hairline borders |
160
+ | `info` / `info-content` | `#009cfa` on `#06367a` | informational badges |
161
+ | `success` / `success-content` | `#15803d` on `#ffffff` | form success |
162
+ | `warning` / `warning-content` | `#b45309` on `#ffffff` | warnings |
163
+ | `error` / `error-content` | `#dc2626` on `#ffffff` | form errors |
164
+
165
+ **The Token Rule.** A colour, radius or type change is a `brand.json` edit and a `website-ui` pull request, never site-local CSS. Sites consume roles (`bg-primary`, `text-base-content`), not hex values.
166
+
167
+ **The One Accent Rule.** The accent carries the kicker, the current-page marker and inline links; it never fills large surfaces and never sets small body text (R5).
168
+
169
+ ### Dark theme (`hwio-forestry-dark`)
170
+
171
+ The dark pair keeps the same roles; visitors choose it with the theme toggle and the choice is remembered (R11). The primary lifts to the light brand blue with dark content so filled and outline buttons stay legible (R10).
172
+
173
+ | Role | Value |
174
+ |---|---|
175
+ | `primary` / `primary-content` | `#5aa864` on `#0f0f14` |
176
+ | `secondary` / `secondary-content` | `#009cfa` on `#0f0f14` |
177
+ | `accent` / `accent-content` | `#5aa864` on `#0f0f14` |
178
+ | `neutral` / `neutral-content` | `#23232f` on `#e7e7ee` |
179
+ | `base-100` / `base-100-content` | `#0f0f14` on `undefined` |
180
+ | `base-200` / `base-200-content` | `#1a1a22` on `undefined` |
181
+ | `base-300` / `base-300-content` | `#23232f` on `undefined` |
182
+ | `info` / `info-content` | `#009cfa` on `#06367a` |
183
+ | `success` / `success-content` | `#15803d` on `#ffffff` |
184
+ | `warning` / `warning-content` | `#b45309` on `#ffffff` |
185
+ | `error` / `error-content` | `#dc2626` on `#ffffff` |
186
+
187
+ ## Typography
188
+
189
+ Inter for everything: display, body, labels and numerals (tabular numerals in stats). The fallback face is metric-matched to Arial so the pre-paint gate (`font-display: block`, R3) never repaints a layout. The ramp tightens tracking as size grows.
190
+
191
+ | Role | Element | Size (large screens) | Weight | Line height | Tracking |
192
+ |---|---|---|---|---|---|
193
+ | display | `h1` | 3.5rem | 700 | 1.05 | -0.03em |
194
+ | heading | `h2` | 2.5rem | 700 | 1.1 | -0.025em |
195
+ | subheading | `h3` | 1.375rem | 700 | 1.2 | -0.01em |
196
+ | title | `h4` | 1.125rem | 700 | 1.3 | -0.005em |
197
+ | lead | `.hwio-lead` | 1.1875rem | 400 | 1.55 | 0 |
198
+ | body | `body` | 1.0625rem | 400 | 1.6 | 0 |
199
+ | kicker | `.hwio-kicker` | 0.875rem | 600 | 1.4 | 0 |
200
+ | button | `.btn` | 0.9375rem | 600 | 1 | 0 |
201
+
202
+ Smaller screens step the display and heading roles down (display: 2.5rem at base, 3rem at md, 3.5rem from 64rem; heading: 2rem at base, 2.5rem from 64rem). Headings use `text-wrap: balance`.
203
+
204
+ ## Layout
205
+
206
+ Two container presets from the theme: the hub width (1275px) for content-rich sites and the landing width (1640px) for the single-page marketing sites, both with 27px side padding. Sections stack on an 8 px rhythm: 80px (112px from 64rem) of vertical padding, compact bands 40px (48px from 64rem). Section content opens with a `HWioSectionHeader` in `stack` (centred) or `split` (5/7 grid, aligned to the baseline) layout; stats bands and choice cards divide with hairlines, not boxes.
207
+
208
+ ## Elevation & Depth
209
+
210
+ The system is flat. DaisyUI `depth` and `noise` are `0`; there are no shadow tokens. Structure comes from hairline borders (`base-300`) and surface shifts (`base-100` on `base-200`, ink panels on `neutral`). A dark-surface panel uses the `neutral` pair and the inverse button; nothing floats.
211
+
212
+ ## Shapes
213
+
214
+ Corner radii from the theme: fields 0.5rem, boxes 1rem, selectors 2rem. Borders are 1 px hairlines. Media inside cards is clipped to the box radius; hero media keeps its natural edges.
215
+
216
+ ## Components
217
+
218
+ - **Buttons.** `button-primary` (primary fill, primary-content text), `button-secondary` (primary outline on base-100), `button-inverse` for ink panels (neutral-content fill), `ghost` and `link`. All 48px tall, 0.9375rem at weight 600, sentence case, 0.5rem radius; large buttons widen padding at the same height.
219
+ - **Cards.** `card card-border` on base-100 with a hairline, 32px padding; the lead choice card carries a 3 px accent top border. Cards never nest.
220
+ - **Kicker and lead.** The kicker is the accent-coloured 0.875rem label above a heading; the lead is 1.1875rem muted text below it.
221
+ - **Inputs.** Field radius, hairline border, 48px tall; focus ring 2 px `secondary`.
222
+ - **Navigation.** `HWioHeader` with mega panels on wide screens (`desktopFrom="xl"` on sites with five or more items); the current page is marked by a 2 px bar on the header's bottom edge.
223
+ - **Bands.** `HWioStatsBand` (hairline top and bottom, vertical dividers, count-up with tabular numerals), `HWioCtaBand`, `HWioLogoStrip`.
224
+
225
+ ## Do's and Don'ts
226
+
227
+ - Do keep Inter as the only text face; the detector's `overused-font` finding for Inter is waived by owner ruling R14 in `.impeccable/config.json`.
228
+ - Do use the theme roles for every colour; don't hard-code hex values in a site.
229
+ - Do keep buttons sentence case and 48px tall; don't uppercase labels or shrink touch targets below 44 px.
230
+ - Do keep dark mode a visitor's choice with the `hwio_theme` memory; don't follow the OS scheme by default (R11).
231
+ - Don't add inline styles, `style=` attributes or template-literal class names; `policy-lint` fails them.
232
+ - Don't nest cards, add glass or gradient effects, or animate anything above the fold.
233
+ - Don't set small body text in the accent colour (R5).
@@ -0,0 +1,233 @@
1
+ ---
2
+ name: "HARDWARIO"
3
+ description: "Navy and red on white with sky panels, Inter, hairline borders, 8 px rhythm, 48 px controls, sentence-case red kickers. Generated from @hubpav/hwio-brand; the source of truth is brand.json."
4
+ colors:
5
+ primary: "#06367a"
6
+ primary-content: "#ffffff"
7
+ secondary: "#016ad4"
8
+ secondary-content: "#ffffff"
9
+ accent: "#e30427"
10
+ accent-content: "#ffffff"
11
+ neutral: "#252532"
12
+ neutral-content: "#f3f4f6"
13
+ base-100: "#ffffff"
14
+ base-200: "#F1FAFF"
15
+ base-300: "#e5e7eb"
16
+ base-content: "#252532"
17
+ info: "#009cfa"
18
+ info-content: "#06367a"
19
+ success: "#15803d"
20
+ success-content: "#ffffff"
21
+ warning: "#b45309"
22
+ warning-content: "#ffffff"
23
+ error: "#dc2626"
24
+ error-content: "#ffffff"
25
+ typography:
26
+ display:
27
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
28
+ fontSize: "3.5rem"
29
+ fontWeight: 700
30
+ lineHeight: 1.05
31
+ letterSpacing: "-0.03em"
32
+ heading:
33
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
34
+ fontSize: "2.5rem"
35
+ fontWeight: 700
36
+ lineHeight: 1.1
37
+ letterSpacing: "-0.025em"
38
+ subheading:
39
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
40
+ fontSize: "1.375rem"
41
+ fontWeight: 700
42
+ lineHeight: 1.2
43
+ letterSpacing: "-0.01em"
44
+ title:
45
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
46
+ fontSize: "1.125rem"
47
+ fontWeight: 700
48
+ lineHeight: 1.3
49
+ letterSpacing: "-0.005em"
50
+ lead:
51
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
52
+ fontSize: "1.1875rem"
53
+ fontWeight: 400
54
+ lineHeight: 1.55
55
+ letterSpacing: "0"
56
+ body:
57
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
58
+ fontSize: "1.0625rem"
59
+ fontWeight: 400
60
+ lineHeight: 1.6
61
+ letterSpacing: "0"
62
+ kicker:
63
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
64
+ fontSize: "0.875rem"
65
+ fontWeight: 600
66
+ lineHeight: 1.4
67
+ letterSpacing: "0"
68
+ button:
69
+ fontFamily: "'Inter', 'Inter Fallback', ui-sans-serif, system-ui, sans-serif"
70
+ fontSize: "0.9375rem"
71
+ fontWeight: 600
72
+ lineHeight: 1
73
+ letterSpacing: "0"
74
+ rounded:
75
+ selector: "2rem"
76
+ field: "0.5rem"
77
+ box: "1rem"
78
+ spacing:
79
+ unit: "8px"
80
+ section: "80px"
81
+ section-lg: "112px"
82
+ section-compact: "40px"
83
+ section-compact-lg: "48px"
84
+ container-hub: "1275px"
85
+ container-landing: "1640px"
86
+ container-pad: "27px"
87
+ control: "48px"
88
+ card-padding: "32px"
89
+ components:
90
+ button-primary:
91
+ backgroundColor: "{colors.primary}"
92
+ textColor: "{colors.primary-content}"
93
+ typography: "{typography.button}"
94
+ rounded: "{rounded.field}"
95
+ height: "48px"
96
+ button-secondary:
97
+ backgroundColor: "{colors.base-100}"
98
+ textColor: "{colors.primary}"
99
+ typography: "{typography.button}"
100
+ rounded: "{rounded.field}"
101
+ height: "48px"
102
+ button-inverse:
103
+ backgroundColor: "{colors.neutral-content}"
104
+ textColor: "{colors.neutral}"
105
+ typography: "{typography.button}"
106
+ rounded: "{rounded.field}"
107
+ height: "48px"
108
+ card:
109
+ backgroundColor: "{colors.base-100}"
110
+ textColor: "{colors.base-content}"
111
+ rounded: "{rounded.box}"
112
+ padding: "32px"
113
+ input:
114
+ backgroundColor: "{colors.base-100}"
115
+ textColor: "{colors.base-content}"
116
+ typography: "{typography.body}"
117
+ rounded: "{rounded.field}"
118
+ height: "48px"
119
+ kicker:
120
+ textColor: "{colors.accent}"
121
+ typography: "{typography.kicker}"
122
+ chip:
123
+ backgroundColor: "{colors.base-200}"
124
+ textColor: "{colors.base-content}"
125
+ typography: "{typography.kicker}"
126
+ rounded: "{rounded.selector}"
127
+ ---
128
+ <!-- Generated from @hubpav/hwio-brand (theme hwio) by packages/brand/scripts/build-design-md.mjs. Do not edit in a site: change packages/brand/src in hardwario/website-ui, publish, then run scripts/design-sync.sh in website-admin. -->
129
+
130
+ # HARDWARIO design system
131
+
132
+ ## Overview
133
+
134
+ **Creative North Star: "The instrument panel"**
135
+
136
+ HARDWARIO sells industrial IoT hardware to system integrators, engineers, schools and plant operators. The web family reads like a well-made instrument: calm white ground, navy for what acts, one red mark for what matters, generous measure and no decoration that does not carry information. This file documents the system as built on 2026-09-07 (direction A, "www systematised"); the 2026 redesign evolves everything but the fixed constraints below and rewrites this file from the built world.
137
+
138
+ Key characteristics:
139
+
140
+ - One type family (Inter), one accent, hairline structure, flat surfaces.
141
+ - Sentence-case labels and buttons everywhere ([R4](https://github.com/hardwario/website-admin/blob/main/DESIGN-SYSTEM.md)); kickers instead of uppercase eyebrows.
142
+ - Light is the default theme on every site; dark is a visitor's choice remembered without a consent gate (R11).
143
+ - Copy is the product: components carry the site's own words, never placeholder text.
144
+
145
+ **The Fixed Four Rule.** The HARDWARIO logo, red `#e30427`, navy `#06367a` and Inter do not change (owner ruling R14, 2026-09-07). Every other token, surface, composition and motion decision is open to the redesign.
146
+
147
+ ## Colors
148
+
149
+ Roles follow the DaisyUI 5 vocabulary so every `@hubpav/hwio-ui` component and every site utility resolves the same slot. Values below are the `hwio` light theme; the source of truth is `packages/brand/src/brand.json` in `hardwario/website-ui`.
150
+
151
+ | Role | Value | Use |
152
+ |---|---|---|
153
+ | `primary` / `primary-content` | `#06367a` on `#ffffff` | buttons, active states, links in navigation |
154
+ | `secondary` / `secondary-content` | `#016ad4` on `#ffffff` | focus ring, secondary emphasis |
155
+ | `accent` / `accent-content` | `#e30427` on `#ffffff` | kicker, current-page marker, inline links; never large fills |
156
+ | `neutral` / `neutral-content` | `#252532` on `#f3f4f6` | ink panels and the footer |
157
+ | `base-100` / `base-100-content` | `#ffffff` on `undefined` | page ground |
158
+ | `base-200` / `base-200-content` | `#F1FAFF` on `undefined` | alternate section surface |
159
+ | `base-300` / `base-300-content` | `#e5e7eb` on `undefined` | hairline borders |
160
+ | `info` / `info-content` | `#009cfa` on `#06367a` | informational badges |
161
+ | `success` / `success-content` | `#15803d` on `#ffffff` | form success |
162
+ | `warning` / `warning-content` | `#b45309` on `#ffffff` | warnings |
163
+ | `error` / `error-content` | `#dc2626` on `#ffffff` | form errors |
164
+
165
+ **The Token Rule.** A colour, radius or type change is a `brand.json` edit and a `website-ui` pull request, never site-local CSS. Sites consume roles (`bg-primary`, `text-base-content`), not hex values.
166
+
167
+ **The One Accent Rule.** The accent carries the kicker, the current-page marker and inline links; it never fills large surfaces and never sets small body text (R5).
168
+
169
+ ### Dark theme (`hwio-dark`)
170
+
171
+ The dark pair keeps the same roles; visitors choose it with the theme toggle and the choice is remembered (R11). The primary lifts to the light brand blue with dark content so filled and outline buttons stay legible (R10).
172
+
173
+ | Role | Value |
174
+ |---|---|
175
+ | `primary` / `primary-content` | `#009cfa` on `#0f0f14` |
176
+ | `secondary` / `secondary-content` | `#009cfa` on `#0f0f14` |
177
+ | `accent` / `accent-content` | `#f43f5e` on `#0f0f14` |
178
+ | `neutral` / `neutral-content` | `#23232f` on `#e7e7ee` |
179
+ | `base-100` / `base-100-content` | `#0f0f14` on `undefined` |
180
+ | `base-200` / `base-200-content` | `#1a1a22` on `undefined` |
181
+ | `base-300` / `base-300-content` | `#23232f` on `undefined` |
182
+ | `info` / `info-content` | `#009cfa` on `#06367a` |
183
+ | `success` / `success-content` | `#15803d` on `#ffffff` |
184
+ | `warning` / `warning-content` | `#b45309` on `#ffffff` |
185
+ | `error` / `error-content` | `#dc2626` on `#ffffff` |
186
+
187
+ ## Typography
188
+
189
+ Inter for everything: display, body, labels and numerals (tabular numerals in stats). The fallback face is metric-matched to Arial so the pre-paint gate (`font-display: block`, R3) never repaints a layout. The ramp tightens tracking as size grows.
190
+
191
+ | Role | Element | Size (large screens) | Weight | Line height | Tracking |
192
+ |---|---|---|---|---|---|
193
+ | display | `h1` | 3.5rem | 700 | 1.05 | -0.03em |
194
+ | heading | `h2` | 2.5rem | 700 | 1.1 | -0.025em |
195
+ | subheading | `h3` | 1.375rem | 700 | 1.2 | -0.01em |
196
+ | title | `h4` | 1.125rem | 700 | 1.3 | -0.005em |
197
+ | lead | `.hwio-lead` | 1.1875rem | 400 | 1.55 | 0 |
198
+ | body | `body` | 1.0625rem | 400 | 1.6 | 0 |
199
+ | kicker | `.hwio-kicker` | 0.875rem | 600 | 1.4 | 0 |
200
+ | button | `.btn` | 0.9375rem | 600 | 1 | 0 |
201
+
202
+ Smaller screens step the display and heading roles down (display: 2.5rem at base, 3rem at md, 3.5rem from 64rem; heading: 2rem at base, 2.5rem from 64rem). Headings use `text-wrap: balance`.
203
+
204
+ ## Layout
205
+
206
+ Two container presets from the theme: the hub width (1275px) for content-rich sites and the landing width (1640px) for the single-page marketing sites, both with 27px side padding. Sections stack on an 8 px rhythm: 80px (112px from 64rem) of vertical padding, compact bands 40px (48px from 64rem). Section content opens with a `HWioSectionHeader` in `stack` (centred) or `split` (5/7 grid, aligned to the baseline) layout; stats bands and choice cards divide with hairlines, not boxes.
207
+
208
+ ## Elevation & Depth
209
+
210
+ The system is flat. DaisyUI `depth` and `noise` are `0`; there are no shadow tokens. Structure comes from hairline borders (`base-300`) and surface shifts (`base-100` on `base-200`, ink panels on `neutral`). A dark-surface panel uses the `neutral` pair and the inverse button; nothing floats.
211
+
212
+ ## Shapes
213
+
214
+ Corner radii from the theme: fields 0.5rem, boxes 1rem, selectors 2rem. Borders are 1 px hairlines. Media inside cards is clipped to the box radius; hero media keeps its natural edges.
215
+
216
+ ## Components
217
+
218
+ - **Buttons.** `button-primary` (primary fill, primary-content text), `button-secondary` (primary outline on base-100), `button-inverse` for ink panels (neutral-content fill), `ghost` and `link`. All 48px tall, 0.9375rem at weight 600, sentence case, 0.5rem radius; large buttons widen padding at the same height.
219
+ - **Cards.** `card card-border` on base-100 with a hairline, 32px padding; the lead choice card carries a 3 px accent top border. Cards never nest.
220
+ - **Kicker and lead.** The kicker is the accent-coloured 0.875rem label above a heading; the lead is 1.1875rem muted text below it.
221
+ - **Inputs.** Field radius, hairline border, 48px tall; focus ring 2 px `secondary`.
222
+ - **Navigation.** `HWioHeader` with mega panels on wide screens (`desktopFrom="xl"` on sites with five or more items); the current page is marked by a 2 px bar on the header's bottom edge.
223
+ - **Bands.** `HWioStatsBand` (hairline top and bottom, vertical dividers, count-up with tabular numerals), `HWioCtaBand`, `HWioLogoStrip`.
224
+
225
+ ## Do's and Don'ts
226
+
227
+ - Do keep Inter as the only text face; the detector's `overused-font` finding for Inter is waived by owner ruling R14 in `.impeccable/config.json`.
228
+ - Do use the theme roles for every colour; don't hard-code hex values in a site.
229
+ - Do keep buttons sentence case and 48px tall; don't uppercase labels or shrink touch targets below 44 px.
230
+ - Do keep dark mode a visitor's choice with the `hwio_theme` memory; don't follow the OS scheme by default (R11).
231
+ - Don't add inline styles, `style=` attributes or template-literal class names; `policy-lint` fails them.
232
+ - Don't nest cards, add glass or gradient effects, or animate anything above the fold.
233
+ - Don't set small body text in the accent colour (R5).
package/dist/tokens.json CHANGED
@@ -99,8 +99,8 @@
99
99
  "base-content": "#e7e7ee",
100
100
  "primary": "#009cfa",
101
101
  "primary-content": "#0f0f14",
102
- "secondary": "#016ad4",
103
- "secondary-content": "#ffffff",
102
+ "secondary": "#009cfa",
103
+ "secondary-content": "#0f0f14",
104
104
  "accent": "#f43f5e",
105
105
  "accent-content": "#0f0f14",
106
106
  "neutral": "#23232f",
@@ -185,8 +185,8 @@
185
185
  "base-content": "#e7e7ee",
186
186
  "primary": "#5aa864",
187
187
  "primary-content": "#0f0f14",
188
- "secondary": "#016ad4",
189
- "secondary-content": "#ffffff",
188
+ "secondary": "#009cfa",
189
+ "secondary-content": "#0f0f14",
190
190
  "accent": "#5aa864",
191
191
  "accent-content": "#0f0f14",
192
192
  "neutral": "#23232f",
@@ -247,7 +247,9 @@
247
247
  "--er3o-gradient-from": "#01CC9B",
248
248
  "--er3o-gradient-to": "#14A0C0",
249
249
  "--hwio-footer-hover": "#ffffff",
250
- "--hwio-nav-active": "#296ea7"
250
+ "--hwio-nav-active": "#296ea7",
251
+ "--hwio-kicker-on-neutral": "#01CC9B",
252
+ "--hwio-link": "#0C6678"
251
253
  }
252
254
  }
253
255
  },
@@ -261,6 +263,88 @@
261
263
  "pad": "27px"
262
264
  }
263
265
  },
266
+ "typography": {
267
+ "$comment": "Type ramp and rhythm as implemented in @hubpav/hwio-ui/styles.css today (direction A, R9). A test in packages/brand/test/design-md.test.mjs fails when the two drift. fontSize is the large-screen value; responsive lists the smaller breakpoints (base, md = 48rem). The 2026 redesign (R13-R16) evolves these blocks; the fixed constraints are the logo, red, navy and Inter (R14).",
268
+ "roles": {
269
+ "display": {
270
+ "element": "h1",
271
+ "fontSize": "3.5rem",
272
+ "responsive": {
273
+ "base": "2.5rem",
274
+ "md": "3rem"
275
+ },
276
+ "fontWeight": 700,
277
+ "lineHeight": 1.05,
278
+ "letterSpacing": "-0.03em"
279
+ },
280
+ "heading": {
281
+ "element": "h2",
282
+ "fontSize": "2.5rem",
283
+ "responsive": {
284
+ "base": "2rem"
285
+ },
286
+ "fontWeight": 700,
287
+ "lineHeight": 1.1,
288
+ "letterSpacing": "-0.025em"
289
+ },
290
+ "subheading": {
291
+ "element": "h3",
292
+ "fontSize": "1.375rem",
293
+ "fontWeight": 700,
294
+ "lineHeight": 1.2,
295
+ "letterSpacing": "-0.01em"
296
+ },
297
+ "title": {
298
+ "element": "h4",
299
+ "fontSize": "1.125rem",
300
+ "fontWeight": 700,
301
+ "lineHeight": 1.3,
302
+ "letterSpacing": "-0.005em"
303
+ },
304
+ "lead": {
305
+ "selector": ".hwio-lead",
306
+ "fontSize": "1.1875rem",
307
+ "fontWeight": 400,
308
+ "lineHeight": 1.55,
309
+ "letterSpacing": "0"
310
+ },
311
+ "body": {
312
+ "element": "body",
313
+ "fontSize": "1.0625rem",
314
+ "fontWeight": 400,
315
+ "lineHeight": 1.6,
316
+ "letterSpacing": "0"
317
+ },
318
+ "kicker": {
319
+ "selector": ".hwio-kicker",
320
+ "fontSize": "0.875rem",
321
+ "fontWeight": 600,
322
+ "lineHeight": 1.4,
323
+ "letterSpacing": "0"
324
+ },
325
+ "button": {
326
+ "selector": ".btn",
327
+ "fontSize": "0.9375rem",
328
+ "fontWeight": 600,
329
+ "lineHeight": 1,
330
+ "letterSpacing": "0"
331
+ }
332
+ }
333
+ },
334
+ "rhythm": {
335
+ "$comment": "Spacing rhythm as implemented in styles.css: Tailwind --spacing is 4px; .hwio-section is 20/28 units, compact 10/12 units; controls are 48px tall; card padding 32px.",
336
+ "unit": "8px",
337
+ "section": {
338
+ "base": "80px",
339
+ "lg": "112px"
340
+ },
341
+ "sectionCompact": {
342
+ "base": "40px",
343
+ "lg": "48px"
344
+ },
345
+ "control": "48px",
346
+ "cardPadding": "32px"
347
+ },
264
348
  "fonts": {
265
349
  "display": "block",
266
350
  "families": {
package/dist/vars.css CHANGED
@@ -40,8 +40,8 @@
40
40
  --hwio-color-base-content: #e7e7ee;
41
41
  --hwio-color-primary: #009cfa;
42
42
  --hwio-color-primary-content: #0f0f14;
43
- --hwio-color-secondary: #016ad4;
44
- --hwio-color-secondary-content: #ffffff;
43
+ --hwio-color-secondary: #009cfa;
44
+ --hwio-color-secondary-content: #0f0f14;
45
45
  --hwio-color-accent: #f43f5e;
46
46
  --hwio-color-accent-content: #0f0f14;
47
47
  --hwio-color-neutral: #23232f;
@@ -106,8 +106,8 @@
106
106
  --hwio-color-base-content: #e7e7ee;
107
107
  --hwio-color-primary: #5aa864;
108
108
  --hwio-color-primary-content: #0f0f14;
109
- --hwio-color-secondary: #016ad4;
110
- --hwio-color-secondary-content: #ffffff;
109
+ --hwio-color-secondary: #009cfa;
110
+ --hwio-color-secondary-content: #0f0f14;
111
111
  --hwio-color-accent: #5aa864;
112
112
  --hwio-color-accent-content: #0f0f14;
113
113
  --hwio-color-neutral: #23232f;
@@ -166,4 +166,6 @@
166
166
  --er3o-gradient-to: #14A0C0;
167
167
  --hwio-footer-hover: #ffffff;
168
168
  --hwio-nav-active: #296ea7;
169
+ --hwio-kicker-on-neutral: #01CC9B;
170
+ --hwio-link: #0C6678;
169
171
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubpav/hwio-brand",
3
- "version": "0.6.5",
3
+ "version": "0.7.0",
4
4
  "description": "HARDWARIO brand source of truth: palette, theme roles, fonts, logos and the sites registry, generated into CSS and JSON for any stack.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -26,6 +26,7 @@
26
26
  "./vars.css": "./dist/vars.css",
27
27
  "./docusaurus.css": "./dist/docusaurus.css",
28
28
  "./fonts/*": "./dist/fonts/*",
29
+ "./design/*": "./dist/design/*",
29
30
  "./logos/*": "./logos/*",
30
31
  "./package.json": "./package.json"
31
32
  },
package/src/brand.json CHANGED
@@ -102,7 +102,9 @@
102
102
  "neutral": "night-300",
103
103
  "neutral-content": "night-content",
104
104
  "primary": "blue-light",
105
- "primary-content": "night-100"
105
+ "primary-content": "night-100",
106
+ "secondary": "blue-light",
107
+ "secondary-content": "night-100"
106
108
  }
107
109
  },
108
110
  "hwio-forestry": {
@@ -153,7 +155,9 @@
153
155
  "--er3o-gradient-from": "#01CC9B",
154
156
  "--er3o-gradient-to": "#14A0C0",
155
157
  "--hwio-footer-hover": "#ffffff",
156
- "--hwio-nav-active": "#296ea7"
158
+ "--hwio-nav-active": "#296ea7",
159
+ "--hwio-kicker-on-neutral": "#01CC9B",
160
+ "--hwio-link": "#0C6678"
157
161
  }
158
162
  }
159
163
  },
@@ -167,6 +171,88 @@
167
171
  "pad": "27px"
168
172
  }
169
173
  },
174
+ "typography": {
175
+ "$comment": "Type ramp and rhythm as implemented in @hubpav/hwio-ui/styles.css today (direction A, R9). A test in packages/brand/test/design-md.test.mjs fails when the two drift. fontSize is the large-screen value; responsive lists the smaller breakpoints (base, md = 48rem). The 2026 redesign (R13-R16) evolves these blocks; the fixed constraints are the logo, red, navy and Inter (R14).",
176
+ "roles": {
177
+ "display": {
178
+ "element": "h1",
179
+ "fontSize": "3.5rem",
180
+ "responsive": {
181
+ "base": "2.5rem",
182
+ "md": "3rem"
183
+ },
184
+ "fontWeight": 700,
185
+ "lineHeight": 1.05,
186
+ "letterSpacing": "-0.03em"
187
+ },
188
+ "heading": {
189
+ "element": "h2",
190
+ "fontSize": "2.5rem",
191
+ "responsive": {
192
+ "base": "2rem"
193
+ },
194
+ "fontWeight": 700,
195
+ "lineHeight": 1.1,
196
+ "letterSpacing": "-0.025em"
197
+ },
198
+ "subheading": {
199
+ "element": "h3",
200
+ "fontSize": "1.375rem",
201
+ "fontWeight": 700,
202
+ "lineHeight": 1.2,
203
+ "letterSpacing": "-0.01em"
204
+ },
205
+ "title": {
206
+ "element": "h4",
207
+ "fontSize": "1.125rem",
208
+ "fontWeight": 700,
209
+ "lineHeight": 1.3,
210
+ "letterSpacing": "-0.005em"
211
+ },
212
+ "lead": {
213
+ "selector": ".hwio-lead",
214
+ "fontSize": "1.1875rem",
215
+ "fontWeight": 400,
216
+ "lineHeight": 1.55,
217
+ "letterSpacing": "0"
218
+ },
219
+ "body": {
220
+ "element": "body",
221
+ "fontSize": "1.0625rem",
222
+ "fontWeight": 400,
223
+ "lineHeight": 1.6,
224
+ "letterSpacing": "0"
225
+ },
226
+ "kicker": {
227
+ "selector": ".hwio-kicker",
228
+ "fontSize": "0.875rem",
229
+ "fontWeight": 600,
230
+ "lineHeight": 1.4,
231
+ "letterSpacing": "0"
232
+ },
233
+ "button": {
234
+ "selector": ".btn",
235
+ "fontSize": "0.9375rem",
236
+ "fontWeight": 600,
237
+ "lineHeight": 1,
238
+ "letterSpacing": "0"
239
+ }
240
+ }
241
+ },
242
+ "rhythm": {
243
+ "$comment": "Spacing rhythm as implemented in styles.css: Tailwind --spacing is 4px; .hwio-section is 20/28 units, compact 10/12 units; controls are 48px tall; card padding 32px.",
244
+ "unit": "8px",
245
+ "section": {
246
+ "base": "80px",
247
+ "lg": "112px"
248
+ },
249
+ "sectionCompact": {
250
+ "base": "40px",
251
+ "lg": "48px"
252
+ },
253
+ "control": "48px",
254
+ "cardPadding": "32px"
255
+ },
170
256
  "fonts": {
171
257
  "display": "block",
172
258
  "families": {
@@ -0,0 +1,67 @@
1
+ ## Overview
2
+
3
+ **Creative North Star: "{{northStar}}"**
4
+
5
+ {{overview}}
6
+
7
+ Key characteristics:
8
+
9
+ - One type family ({{fontFamily}}), one accent, hairline structure, flat surfaces.
10
+ - Sentence-case labels and buttons everywhere ([R4](https://github.com/hardwario/website-admin/blob/main/DESIGN-SYSTEM.md)); kickers instead of uppercase eyebrows.
11
+ - Light is the default theme on every site; dark is a visitor's choice remembered without a consent gate (R11).
12
+ - Copy is the product: components carry the site's own words, never placeholder text.
13
+
14
+ {{brandRules}}
15
+
16
+ ## Colors
17
+
18
+ Roles follow the DaisyUI 5 vocabulary so every `@hubpav/hwio-ui` component and every site utility resolves the same slot. Values below are the `{{themeName}}` light theme; the source of truth is `packages/brand/src/brand.json` in `hardwario/website-ui`.
19
+
20
+ {{colorsTable}}
21
+
22
+ **The Token Rule.** A colour, radius or type change is a `brand.json` edit and a `website-ui` pull request, never site-local CSS. Sites consume roles (`bg-primary`, `text-base-content`), not hex values.
23
+
24
+ **The One Accent Rule.** The accent carries the kicker, the current-page marker and inline links; it never fills large surfaces and never sets small body text (R5).
25
+
26
+ {{darkSection}}
27
+
28
+ ## Typography
29
+
30
+ {{fontFamily}} for everything: display, body, labels and numerals (tabular numerals in stats). The fallback face is metric-matched to Arial so the pre-paint gate (`font-display: block`, R3) never repaints a layout. The ramp tightens tracking as size grows.
31
+
32
+ | Role | Element | Size (large screens) | Weight | Line height | Tracking |
33
+ |---|---|---|---|---|---|
34
+ {{typeTable}}
35
+
36
+ Smaller screens step the display and heading roles down ({{responsiveNote}}). Headings use `text-wrap: balance`.
37
+
38
+ ## Layout
39
+
40
+ Two container presets from the theme: the hub width ({{containerHub}}) for content-rich sites and the landing width ({{containerLanding}}) for the single-page marketing sites, both with {{containerPad}} side padding. Sections stack on an 8 px rhythm: {{sectionRhythm}} of vertical padding, compact bands {{sectionCompact}}. Section content opens with a `HWioSectionHeader` in `stack` (centred) or `split` (5/7 grid, aligned to the baseline) layout; stats bands and choice cards divide with hairlines, not boxes.
41
+
42
+ ## Elevation & Depth
43
+
44
+ The system is flat. DaisyUI `depth` and `noise` are `0`; there are no shadow tokens. Structure comes from hairline borders (`base-300`) and surface shifts (`base-100` on `base-200`, ink panels on `neutral`). A dark-surface panel uses the `neutral` pair and the inverse button; nothing floats.
45
+
46
+ ## Shapes
47
+
48
+ Corner radii from the theme: fields {{radiusField}}, boxes {{radiusBox}}, selectors {{radiusSelector}}. Borders are 1 px hairlines. Media inside cards is clipped to the box radius; hero media keeps its natural edges.
49
+
50
+ ## Components
51
+
52
+ - **Buttons.** `button-primary` (primary fill, primary-content text), `button-secondary` (primary outline on base-100), `button-inverse` for ink panels (neutral-content fill), `ghost` and `link`. All {{control}} tall, {{buttonSize}} at weight {{buttonWeight}}, sentence case, {{radiusField}} radius; large buttons widen padding at the same height.
53
+ - **Cards.** `card card-border` on base-100 with a hairline, {{cardPadding}} padding; the lead choice card carries a 3 px accent top border. Cards never nest.
54
+ - **Kicker and lead.** The kicker is the accent-coloured {{kickerSize}} label above a heading; the lead is {{leadSize}} muted text below it.
55
+ - **Inputs.** Field radius, hairline border, {{control}} tall; focus ring 2 px `secondary`.
56
+ - **Navigation.** `HWioHeader` with mega panels on wide screens (`desktopFrom="xl"` on sites with five or more items); the current page is marked by a 2 px bar on the header's bottom edge.
57
+ - **Bands.** `HWioStatsBand` (hairline top and bottom, vertical dividers, count-up with tabular numerals), `HWioCtaBand`, `HWioLogoStrip`.
58
+
59
+ ## Do's and Don'ts
60
+
61
+ - Do keep {{fontFamily}} as the only text face; the detector's `overused-font` finding for Inter is waived by owner ruling R14 in `.impeccable/config.json`.
62
+ - Do use the theme roles for every colour; don't hard-code hex values in a site.
63
+ - Do keep buttons sentence case and {{control}} tall; don't uppercase labels or shrink touch targets below 44 px.
64
+ - Do keep dark mode a visitor's choice with the `hwio_theme` memory; don't follow the OS scheme by default (R11).
65
+ - Don't add inline styles, `style=` attributes or template-literal class names; `policy-lint` fails them.
66
+ - Don't nest cards, add glass or gradient effects, or animate anything above the fold.
67
+ - Don't set small body text in the accent colour (R5).