@fracazo/design-system 0.2.0 → 0.2.1
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/DESIGN.md +361 -8
- package/README.md +3 -2
- package/package.json +1 -1
package/DESIGN.md
CHANGED
|
@@ -1,12 +1,365 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fracazo-design-system
|
|
3
|
+
description: The written authority for products built on @fracazo/design-system. Judgment, composition and the rejection list for surfaces a parent under pressure will read; the stylesheet and the guardrails do the visual work.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
applies_to: any product that imports @fracazo/design-system/roles.css and one brand file
|
|
6
|
+
enforced_by: css/roles.css (brand contract, held by ds-check-brand), @fracazo/design-system/eslint, each product's design snapshot harness
|
|
7
|
+
---
|
|
8
|
+
|
|
1
9
|
# DESIGN.md
|
|
2
10
|
|
|
3
|
-
|
|
4
|
-
the reader's job is, how a page is composed, what the system
|
|
5
|
-
ship
|
|
6
|
-
|
|
11
|
+
This file is for whoever builds a surface on the system, person or agent.
|
|
12
|
+
It says what the reader's job is, how a page is composed, what the system
|
|
13
|
+
refuses to ship, and where each brand differs. It is deliberately short.
|
|
14
|
+
The stylesheet carries the visual decisions; this file carries judgment,
|
|
15
|
+
and gains a rule only when the same correction has been made twice.
|
|
16
|
+
|
|
17
|
+
Read `css/roles.css` for the roles and the brand contract, the component
|
|
18
|
+
source in `src/ui/*` for each component's intent, and the product's own
|
|
19
|
+
CLAUDE.md for the rules that are local to it.
|
|
20
|
+
|
|
21
|
+
## Who the reader is
|
|
22
|
+
|
|
23
|
+
Every product on this system is used by people close to a birth: a parent
|
|
24
|
+
in the third trimester on a phone, a partner at a bedside on hospital
|
|
25
|
+
wifi, someone reading at 3am with one hand. They are tired, sometimes
|
|
26
|
+
frightened, and they came for one answer. The surface earns trust by being
|
|
27
|
+
fast, calm and exact, the way a good midwife is. It never earns it with
|
|
28
|
+
decoration, hype or novelty.
|
|
29
|
+
|
|
30
|
+
Two products run on it today: BirthGuide (Australia) and birthplans.app
|
|
31
|
+
(English-speaking markets, primarily the US). Their chapters are at the
|
|
32
|
+
end. Everything before them applies to both, and to the next product.
|
|
33
|
+
|
|
34
|
+
## Priority order
|
|
35
|
+
|
|
36
|
+
When rules conflict, the lower number wins.
|
|
37
|
+
|
|
38
|
+
1. **Performance is the brand.** A fast page feels more premium than any
|
|
39
|
+
palette. If a feature cannot meet its surface's budget, cut or simplify
|
|
40
|
+
it until it can.
|
|
41
|
+
2. **Preserve the reader's decision.** Facts, options and consequences stay
|
|
42
|
+
exact and complete. Copy claims only what the product delivers.
|
|
43
|
+
3. **Respect the host and the contract.** Work inside the product's
|
|
44
|
+
framework, its brand file and this package's roles. Never fork a
|
|
45
|
+
component or invent a token locally; raise it in the system.
|
|
46
|
+
4. **Keep the surface unmistakably the product's.** The brand file does
|
|
47
|
+
this. Do not add a second accent, a new typeface or a new radius to
|
|
48
|
+
make a page feel special.
|
|
49
|
+
5. **Choose a specific composition.** Let the material set the layout.
|
|
50
|
+
Reject the template reflex (centred hero, three cards, metric boxes).
|
|
51
|
+
|
|
52
|
+
## Two surface scopes
|
|
53
|
+
|
|
54
|
+
Name the scope before designing anything.
|
|
55
|
+
|
|
56
|
+
**Engagement surfaces** are the product itself: questionnaire, plan
|
|
57
|
+
editor, the published plan page, downloads, account. Failure mode: "it
|
|
58
|
+
did not load when I needed it." Strict budgets (cold start under 1.5s on
|
|
59
|
+
a three-year-old phone on slow 4G, first paint under 1s), no hero imagery,
|
|
60
|
+
no decorative motion, optimistic UI on every write, tap targets at least
|
|
61
|
+
44px, inputs at least 16px so iOS never zooms.
|
|
62
|
+
|
|
63
|
+
**Conversion surfaces** are the landing pages, guides and articles a
|
|
64
|
+
reader sees while deciding. Failure mode: "it looked cheap, or it was slow
|
|
65
|
+
and search buried it." Core Web Vitals "Good" thresholds apply (LCP under
|
|
66
|
+
2.5s, CLS under 0.1, INP under 200ms, first load under 1MB). Illustration,
|
|
67
|
+
one custom typeface and staged entrance motion are permitted within those
|
|
68
|
+
budgets. The hospital case still applies: a landing page opened on a ward
|
|
69
|
+
tour is still read under pressure.
|
|
70
|
+
|
|
71
|
+
## Work in four passes
|
|
72
|
+
|
|
73
|
+
**Frame the reader's job.** Who is reading, what they must decide or do
|
|
74
|
+
on this surface, what the one strongest piece of evidence or the one
|
|
75
|
+
primary action is. Support two reading speeds: the scan (headings, the
|
|
76
|
+
key value, the primary button) and the careful read (the detail, the
|
|
77
|
+
caveat, the "if necessary" path).
|
|
78
|
+
|
|
79
|
+
**Choose the composition.** One focal relationship per screen. Prose for
|
|
80
|
+
reasoning, a list for parallel items, a table for exact comparison, a
|
|
81
|
+
card only when the surface is genuinely a unit the reader picks up. Cards
|
|
82
|
+
do not nest. Emphasis is spent once: a surface that carries a tinted
|
|
83
|
+
border, a heavy shadow, an uppercase chip and an accent button at the
|
|
84
|
+
same time is shouting, and the fix is always to remove signals, not to
|
|
85
|
+
add a stronger one.
|
|
86
|
+
|
|
87
|
+
**Apply the system.** Semantic utilities first, primitives where no
|
|
88
|
+
semantic role fits, tokens for everything that varies by theme, named
|
|
89
|
+
roles for every size and radius. The sections below say how.
|
|
90
|
+
|
|
91
|
+
**Inspect privately, then verify with tooling.** Read the page aloud;
|
|
92
|
+
if the rhythm is wrong, rewrite. Check both themes and a 360px viewport.
|
|
93
|
+
Then run the product's snapshot compare: a refactor must compare
|
|
94
|
+
identical, and an intentional change must show only the keys you meant
|
|
95
|
+
to move, with the count stated in the handback.
|
|
96
|
+
|
|
97
|
+
## The visual system
|
|
98
|
+
|
|
99
|
+
### Tokens, two tiers
|
|
100
|
+
|
|
101
|
+
Primitives hold literals and live in the brand file: `--band`, `--ink`,
|
|
102
|
+
`--line`, `--brand`, `--dark` and their families. Semantics are the roles
|
|
103
|
+
components consume: `--primary`, `--border`, `--muted-foreground`. Eight
|
|
104
|
+
semantics alias a primitive with `var()` in `roles.css`, once, because
|
|
105
|
+
they are identical in light and dark: foreground, card, popover, primary,
|
|
106
|
+
accent, ring and the card and popover foregrounds. Six diverge in dark
|
|
107
|
+
and hold brand-tuned literals in the brand file: secondary, muted, border,
|
|
108
|
+
input, muted-foreground, accent-foreground. Dark border and input as
|
|
109
|
+
translucent white hairlines is a design decision. Never "fix" a divergent
|
|
110
|
+
semantic by aliasing it; the dark rendering changes.
|
|
111
|
+
|
|
112
|
+
Every token has a utility (`bg-band`, `text-ink-3`, `shadow-card`,
|
|
113
|
+
`rounded-20`, `text-display`, `py-band`). The utility is the only way a
|
|
114
|
+
value reaches a component.
|
|
115
|
+
|
|
116
|
+
### Colour
|
|
117
|
+
|
|
118
|
+
Semantic utilities first: `bg-background`, `bg-card`, `text-foreground`,
|
|
119
|
+
`text-muted-foreground`, `border-border`, `ring-ring`, `bg-primary`.
|
|
120
|
+
Primitives where no role fits:
|
|
121
|
+
|
|
122
|
+
- Alternating page bands: `bg-band`, then `bg-band-2` or `bg-surface-2`.
|
|
123
|
+
- Captions and hints on light surfaces: `text-ink-3`.
|
|
124
|
+
- Accent chips: `bg-chip-1-soft text-chip-1-ink`, `chip-2`, `chip-3`.
|
|
125
|
+
- The "new" or "note" pair: `bg-highlight text-highlight-ink`, with
|
|
126
|
+
`highlight-soft` and `highlight-deep` for two-tone stat pills.
|
|
127
|
+
- Preference state, and only preference state: `status-want`,
|
|
128
|
+
`status-ifnec`, `status-no`, each with a `-soft` wash. Colour carries
|
|
129
|
+
meaning here; it is never decoration.
|
|
130
|
+
|
|
131
|
+
Always-dark surfaces (footer, showcase bands) are `bg-dark` or `bg-dark-2`
|
|
132
|
+
and their text comes from the mode-constant on-dark ramp, `text-dark-ink`
|
|
133
|
+
down to `text-dark-faint-2`, with `text-dark-brand` for the one accent.
|
|
134
|
+
A theme-varying token such as `text-ink` on a dark band renders espresso
|
|
135
|
+
on espresso in light mode.
|
|
136
|
+
|
|
137
|
+
Design in the neutrals; the brand hue appears on the primary action,
|
|
138
|
+
links, the focus ring and small accents. Never use Tailwind's stock
|
|
139
|
+
palette (`amber-500`, `blue-600`) in product UI; it competes with the
|
|
140
|
+
brand and looks generic.
|
|
141
|
+
|
|
142
|
+
### Radius
|
|
143
|
+
|
|
144
|
+
The ramp derives from the brand's `--radius`: `rounded-sm` through
|
|
145
|
+
`rounded-4xl` are calc offsets. One absolute value sits off the ramp,
|
|
146
|
+
`rounded-20`. There are no other radii. Where a rounded child's corners
|
|
147
|
+
co-locate with a rounded parent's, the outer radius is the inner radius
|
|
148
|
+
plus the padding, and the result is always a named token (`rounded-lg`
|
|
149
|
+
plus `p-4` gives `rounded-4xl`; `rounded-md` plus `p-3` gives
|
|
150
|
+
`rounded-20`; `rounded-sm` plus `p-4` gives `rounded-3xl`). Concentric
|
|
151
|
+
corners read as one shape; equal radii at different depths read as a
|
|
152
|
+
mistake. The rule applies where corners meet, not to every nested corner.
|
|
153
|
+
|
|
154
|
+
Text buttons are rounded rectangles on a size-scaled ladder (xs `sm`,
|
|
155
|
+
sm `md`, default `lg`, lg `xl`); icon-only buttons are circles.
|
|
156
|
+
|
|
157
|
+
### Type
|
|
158
|
+
|
|
159
|
+
One sans family per product, set by the brand file's `@theme` block, and
|
|
160
|
+
one mono. Headings are weight 600, tracking -0.02em, `text-wrap: balance`;
|
|
161
|
+
paragraphs `text-wrap: pretty`. Numbers that line up in columns use
|
|
162
|
+
tabular numerals; headline figures stay proportional.
|
|
163
|
+
|
|
164
|
+
Fluid sizes are named roles, never `text-[clamp(...)]`: `text-display`
|
|
165
|
+
for the one display headline (line-height 0.9 travels with it),
|
|
166
|
+
`text-section-title` for section headings, `text-lede` for the lede
|
|
167
|
+
under them (leading is left to the use site). Landing sections keep their
|
|
168
|
+
vertical rhythm with `py-band` and `mt-band-gap`. A size the roles do not
|
|
169
|
+
cover is a token to add, not a literal to type; a deliberate one-off
|
|
170
|
+
carries an inline lint disable that states why.
|
|
171
|
+
|
|
172
|
+
Mono is for code, identifiers and the small uppercase kicker label with
|
|
173
|
+
wide tracking, and nothing else. All caps appears only on that label.
|
|
174
|
+
|
|
175
|
+
### Surfaces and shadows
|
|
176
|
+
|
|
177
|
+
Depth comes from the shadow-border system (`shadow-card`,
|
|
178
|
+
`shadow-card-hover`, `shadow-card-selected`, which embeds the primary as
|
|
179
|
+
a ring) rather than from flat borders, and from the warm soft shadows on
|
|
180
|
+
landing cards (`shadow-warm-sm` to `-lg`; the brand file swaps them for
|
|
181
|
+
black-based shadows in dark, where light shadows vanish). `shadow-bar` is
|
|
182
|
+
the upward shadow under a floating bottom bar. Spacing separates before a
|
|
183
|
+
border does. No glass, no decorative gradients, no dark rounded frames
|
|
184
|
+
around content.
|
|
185
|
+
|
|
186
|
+
### Motion
|
|
187
|
+
|
|
188
|
+
Default to stillness. Interactive state changes (hover, select, expand)
|
|
189
|
+
use CSS transitions, which retarget when interrupted mid-flight.
|
|
190
|
+
Keyframes are reserved for one-shot staged sequences such as a hero
|
|
191
|
+
entrance, gated to play once per visit so a reload does not replay them,
|
|
192
|
+
and collapsed to nothing under `prefers-reduced-motion`. Nothing the
|
|
193
|
+
reader needs is behind an animation. Ambient effects (glow blobs) must
|
|
194
|
+
not clip at a section edge; a hard horizontal seam where two sections
|
|
195
|
+
meet is a defect.
|
|
196
|
+
|
|
197
|
+
### Imagery and icons
|
|
198
|
+
|
|
199
|
+
Engagement surfaces carry no photography and no decorative illustration;
|
|
200
|
+
icons are SVG (lucide). Conversion surfaces may use illustration over
|
|
201
|
+
photography, custom, editorial and restrained, never stock, never
|
|
202
|
+
photographs of pregnant women and babies, never carousels or autoplay.
|
|
203
|
+
Icons label actions when they make the action faster to recognise; they
|
|
204
|
+
never decorate a heading.
|
|
205
|
+
|
|
206
|
+
### Accessibility
|
|
207
|
+
|
|
208
|
+
WCAG AA (4.5:1 for body text, 3:1 for large text and controls). Rose or
|
|
209
|
+
periwinkle text on a light surface uses the brand ink, not the brand.
|
|
210
|
+
Native controls where they exist; the date picker is the OS one. Focus is
|
|
211
|
+
shown with `focus-visible`, so a modal opened with the mouse does not
|
|
212
|
+
paint a ring on its close button while keyboard users still get one.
|
|
213
|
+
Source order is reading order; landmarks and heading levels are real;
|
|
214
|
+
44px targets on coarse pointers.
|
|
215
|
+
|
|
216
|
+
## Components
|
|
217
|
+
|
|
218
|
+
The package ships seventeen shadcn-based components under
|
|
219
|
+
`@fracazo/design-system/ui/*`. Each carries an intent block at the top of
|
|
220
|
+
its source (one line, then Use for, Avoid when, Variants); that block is
|
|
221
|
+
the contract and is updated whenever variants change. In brief:
|
|
222
|
+
|
|
223
|
+
- **Button** is the tappable action primitive. Default carries the one
|
|
224
|
+
primary action of a step; outline is the standard secondary; ghost is
|
|
225
|
+
back, cancel and edit-in-place; destructive is reserved for irreversible
|
|
226
|
+
acts. Default height 48px; sm in compact rows; lg only for
|
|
227
|
+
money-adjacent hero actions.
|
|
228
|
+
- **Input**, **Textarea**, **Label** and the **Form** glue serve
|
|
229
|
+
react-hook-form fields. Textarea auto-grows. A field outside RHF uses
|
|
230
|
+
Label plus Input directly.
|
|
231
|
+
- **Checkbox**, **RadioGroup** and **Select** are for dense or
|
|
232
|
+
utilitarian UI. Questionnaire answers use the house icon-card groups,
|
|
233
|
+
never bare radios or checkboxes.
|
|
234
|
+
- **Dialog** is a centred modal for a focused task (a preview, a
|
|
235
|
+
confirmation). **Sheet** is the mobile bottom sheet for supplementary
|
|
236
|
+
content; on desktop the same content renders as an aside. **Popover**
|
|
237
|
+
anchors transient UI to a control without moving focus.
|
|
238
|
+
- **Accordion** is progressive disclosure inside the app; a public FAQ
|
|
239
|
+
uses native details and summary so answers exist without JavaScript.
|
|
240
|
+
**Tabs** switch between peer views of equal weight; inactive panels
|
|
241
|
+
unmount, so never for content search engines must see.
|
|
242
|
+
- **Card** is the stock surface family for quick composition; the house
|
|
243
|
+
card (rounded-20, warm shadow) is composed from utilities.
|
|
244
|
+
- **Progress** is a flat determinate bar; brand-moment progress bars are
|
|
245
|
+
bespoke. **Calendar** exists for range selection; a single date uses a
|
|
246
|
+
native input. **SortableList** ranks a small capped set with drag,
|
|
247
|
+
touch and keyboard.
|
|
248
|
+
|
|
249
|
+
A component that must import app code (stores, data clients, routes)
|
|
250
|
+
does not belong in the package; it stays in the product, like
|
|
251
|
+
`place-autocomplete`. Dependencies point one way: the app consumes the
|
|
252
|
+
system, never the reverse.
|
|
253
|
+
|
|
254
|
+
## Guardrails and verification
|
|
255
|
+
|
|
256
|
+
- **Brand contract.** `roles.css` lists every property a brand file must
|
|
257
|
+
define, light, dark and theme. `ds-check-brand` fails lint when a file
|
|
258
|
+
defines less or more. A new role is a minor version and a changelog
|
|
259
|
+
note; a contract change a brand must satisfy anew is a major version.
|
|
260
|
+
- **ESLint.** No raw colour in a `className` (hex, oklch, rgb, hsl,
|
|
261
|
+
including arbitrary utilities) and no `text-[clamp(...)]`. Renderers
|
|
262
|
+
that cannot use CSS variables (react-pdf, email HTML, OG images) are
|
|
263
|
+
exempt per product; nothing else is.
|
|
264
|
+
- **Zero visual change.** Token and component refactors are verified by
|
|
265
|
+
each product's snapshot harness, which rasterises resolved colours to
|
|
266
|
+
sRGB bytes and probes the utility layer and real pages, never by eye.
|
|
267
|
+
Snapshot before editing; compare after; clear the framework's build
|
|
268
|
+
cache after restructuring the CSS import graph. An intentional change
|
|
269
|
+
regenerates the committed baseline in the same branch and names its
|
|
270
|
+
delta.
|
|
271
|
+
|
|
272
|
+
## Reject these reflexes
|
|
273
|
+
|
|
274
|
+
Each of these has been corrected more than once. Treat them as defects.
|
|
275
|
+
|
|
276
|
+
- A colour literal in a class, in any form, including a "temporary" one.
|
|
277
|
+
- A hand-authored light and dark pair (`bg-[...] dark:bg-[...]`). The
|
|
278
|
+
token owns both themes; write one class.
|
|
279
|
+
- Theme-varying text on an always-dark surface.
|
|
280
|
+
- A new radius literal, or equal radii on nested corners that meet.
|
|
281
|
+
- An arbitrary clamp() size where a named role exists, or a near-miss
|
|
282
|
+
clamp that drifts a few pixels from one.
|
|
283
|
+
- Four emphasis signals on one card. Remove until one remains.
|
|
284
|
+
- A focus ring painted for pointer users. Use `focus-visible`.
|
|
285
|
+
- A hard seam where an ambient glow is clipped at a section boundary.
|
|
286
|
+
- Tailwind's stock palette in product UI.
|
|
287
|
+
- Values invented in a story or a demo. Storybook and the showcase are
|
|
288
|
+
consumers; a missing value is a finding to raise.
|
|
289
|
+
- Em dashes, anywhere: copy, comments, commit messages, generated
|
|
290
|
+
documents. Use commas, colons, full stops, parentheses.
|
|
291
|
+
- Wellness-speak ("your journey", "mama", "you've got this"), filler
|
|
292
|
+
affirmations ("amazing", "incredible"), AI marketing words
|
|
293
|
+
("seamless", "empower", "unlock", "cutting-edge", "revolutionise").
|
|
294
|
+
- All caps outside the micro kicker label, or Title Case in a heading,
|
|
295
|
+
button or label. The system is sentence case.
|
|
296
|
+
- Centred hero plus three cards, metric boxes, badges as metadata,
|
|
297
|
+
nested cards, decorative gradients, glass, stock imagery, carousels,
|
|
298
|
+
autoplay, a visible theme switcher.
|
|
299
|
+
|
|
300
|
+
Do not answer restraint with a sterile template. Restraint here is a
|
|
301
|
+
precise hierarchy, one warm accent used with intent, exact evidence and
|
|
302
|
+
strong alignment, on a page that loads before the reader's patience runs
|
|
303
|
+
out.
|
|
304
|
+
|
|
305
|
+
## Brand: BirthGuide
|
|
306
|
+
|
|
307
|
+
Australian, trusted, quiet. A companion through pregnancy and the first
|
|
308
|
+
weeks, endorsed by midwives; it reads as something a midwife would
|
|
309
|
+
recommend without hesitation, never as a children's app. Australian
|
|
310
|
+
English throughout: caesarean, labour, antenatal, nappy. "Birth plan" for
|
|
311
|
+
search, "birth preferences" in clinical and community copy; both coexist.
|
|
312
|
+
|
|
313
|
+
- **Palette.** Cream page (`#FAF6EF`), espresso ink (`#2B2620`), rose
|
|
314
|
+
accent (`--brand` `#C2727A`, `--brand-ink` for text on light). Dark is
|
|
315
|
+
espresso surfaces with cream text and a lightened rose.
|
|
316
|
+
`--headline-accent` rides the brand ink in light and turns warm sand in
|
|
317
|
+
dark, because on the espresso page rose barely separates from body
|
|
318
|
+
text. `--dark-brand` (`#DE949A`) is the one non-grey in the on-dark
|
|
319
|
+
ramp, used for the footer heart. `chip-3` is the sister product's
|
|
320
|
+
periwinkle; its ink is that product's exact brand value and is not
|
|
321
|
+
nudged.
|
|
322
|
+
- **Type.** Hanken Grotesk via next/font (`--font-hanken`), Geist Mono,
|
|
323
|
+
both `display: optional` so text never blocks on a webfont.
|
|
324
|
+
- **Surfaces.** Landing page and guides to convert; questionnaire, plan
|
|
325
|
+
editor, published plan page and downloads to engage. Illustration is
|
|
326
|
+
welcome on the landing page and absent from the product.
|
|
327
|
+
- **Repo.** `~/Developer/birthguide`. Brand file
|
|
328
|
+
`src/system/brands/birthguide.css`; `public/brand.css` is the served
|
|
329
|
+
token API, generated by `ds-build-brand-css` and checked in lint. The
|
|
330
|
+
local Storybook is the component gallery for both products; it consumes
|
|
331
|
+
the package and defines nothing.
|
|
332
|
+
|
|
333
|
+
## Brand: birthplans.app
|
|
334
|
+
|
|
335
|
+
The same warm system with the brand hue rotated to periwinkle, for
|
|
336
|
+
English-speaking markets, primarily the US. One output: the birth plan
|
|
337
|
+
PDF, paginated to match its live preview. US English throughout: cesarean,
|
|
338
|
+
labor, color, anesthesiologist, operating room; `nitrous oxide (gas and
|
|
339
|
+
air)`, `oxytocin drip (Pitocin)`. Same voice rules as BirthGuide.
|
|
340
|
+
|
|
341
|
+
- **Palette.** Cream and espresso as BirthGuide; `--brand` `#7480C6`
|
|
342
|
+
periwinkle, `--brand-ink` `#4A529E`, `--brand-soft` `#E8EAF8`; dark
|
|
343
|
+
brand at hue 276. `--headline-accent` is warm sand in both modes, and
|
|
344
|
+
the hero applies it only in dark. `accent-foreground` follows the brand
|
|
345
|
+
ink in light, the one semantic this product tuned. `chip-3` is BirthGuide's
|
|
346
|
+
rose, reasoned and unused. The status ramp is live in the questionnaire:
|
|
347
|
+
want, if necessary, don't want, each with a soft wash.
|
|
348
|
+
- **Type.** Hanken Grotesk and Geist Mono, as BirthGuide.
|
|
349
|
+
- **Guardrails.** The colour rule is on. The fluid-type rule is off until
|
|
350
|
+
a type-role pass converges the landing sections' fourteen clamp
|
|
351
|
+
literals onto the named roles; switch to `designSystemGuardrails()` when
|
|
352
|
+
it lands.
|
|
353
|
+
- **Repo.** `~/Developer/birthplans`. Brand file
|
|
354
|
+
`src/system/brands/birthplans.css`. No Storybook and no served
|
|
355
|
+
`brand.css`; BirthGuide's Storybook documents the shared components.
|
|
7
356
|
|
|
8
|
-
|
|
9
|
-
- The two ESLint guardrails in `@fracazo/design-system/eslint`.
|
|
357
|
+
## Maintaining this file
|
|
10
358
|
|
|
11
|
-
|
|
12
|
-
|
|
359
|
+
Add a prose rule here only when the same correction has been made twice;
|
|
360
|
+
once is a review comment. Prefer moving a rule into the stylesheet or the
|
|
361
|
+
guardrails over writing it down: a token, a lint rule or a contract entry
|
|
362
|
+
enforces itself. Brand chapters state what differs and nothing that the
|
|
363
|
+
core already says. Semantic versioning by hand: a clarification is a
|
|
364
|
+
patch, a new rule a minor, a change to the priority order or the surface
|
|
365
|
+
scopes a major.
|
package/README.md
CHANGED
|
@@ -19,10 +19,11 @@ product from.
|
|
|
19
19
|
| `@fracazo/design-system` and `./ui/*` | `cn` and seventeen shadcn-based components (button, card, dialog, form, select, sortable-list and the rest), each with intent JSDoc: use for, avoid when, variants |
|
|
20
20
|
| `@fracazo/design-system/eslint` | Two guardrails: no raw colours and no arbitrary fluid type sizes in a `className` |
|
|
21
21
|
| `demo/index.html` | A showcase page that renders the roles in both modes off a served `/brand.css` |
|
|
22
|
-
| `DESIGN.md` | The written authority:
|
|
22
|
+
| `DESIGN.md` | The written authority: who the reader is, the priority order, how a page is composed, the rejection list, one short chapter per brand |
|
|
23
23
|
|
|
24
24
|
Brand files live in each product repo, not here. The contract is what keeps
|
|
25
|
-
them honest.
|
|
25
|
+
them honest. A new product starts from the `design-system-starter` template:
|
|
26
|
+
Next 16, Tailwind v4, this package, a blank brand file and the guardrails on.
|
|
26
27
|
|
|
27
28
|
## Consume it
|
|
28
29
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fracazo/design-system",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Roles, brand contract, guardrails and shadcn-based components for a warm, evidence-led product design system. Each product supplies a brand file; the system stays the same.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Alex Fracazo",
|