@medquantis/design-system 1.0.0 → 1.1.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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The single source of the MedQuantis visual identity: design tokens, shared CSS, self-hosted fonts and icons, brand assets, guidelines and a Claude skill. Every value is defined once, in `tokens/`, and reaches each consumer as a generated output in its native format ([ADR-0002](docs/architecture/decisions/adr-0002-central-tokens-first-design-system.md)).
4
4
 
5
- > Status: bootstrap. Nothing is published yet; the repository stays private until the pre-public confidentiality audit passes ([ADR-0005](docs/architecture/decisions/adr-0005-public-repo-with-confidentiality-gate.md)).
5
+ > Status: published on npm as `@medquantis/design-system`; the repository is public behind the confidentiality gate ([ADR-0005](docs/architecture/decisions/adr-0005-public-repo-with-confidentiality-gate.md)).
6
6
 
7
7
  ## Outputs
8
8
 
@@ -17,6 +17,8 @@ The single source of the MedQuantis visual identity: design tokens, shared CSS,
17
17
  | `icons/lucide.min.js` | A pinned Lucide build (version and hash in `icons/manifest.json`) |
18
18
  | `brand/` | Monogram, favicon set and wordmark: `wordmark-on-light` and `wordmark-on-navy`, live text for screen and `-print` with outlined text |
19
19
  | `guidelines/` | Brand, voice, colour, typography, chart, data and accessibility rules |
20
+ | `kit-manifest.json`, `dist/kit/` | The homemade-claude-kit delivery-comms renderers (contract 2.0.0): the manifest declares nine modules, each a file in `dist/kit/` (see Using it from the delivery-comms kit) |
21
+ | `dist/DESIGN.md` | Tools and agents outside the kit: the tokens as [Google DESIGN.md](https://github.com/google-labs-code/design.md) front matter, then the guidelines as prose |
20
22
  | `dist/llms.txt`, `dist/llms-full.txt` | The guidelines and the token list for language models ([llmstxt.org](https://llmstxt.org/) format), generated from `guidelines/` and the tokens |
21
23
  | `plugins/medquantis-design-system/` | The Claude skill, as a Claude Code plugin and as a zip for claude.ai (see Claude skill) |
22
24
 
@@ -106,6 +108,57 @@ echo "sha384-$(openssl dgst -sha384 -binary dist/tokens.css | openssl base64 -A)
106
108
 
107
109
  Every other shipped file (`css/*.css`, `fonts/fonts.css`, `dist/kit-contract.css`) works the same way, each with its own hash. Fonts referenced by `fonts.css` load relative to it, so serve the stylesheet and its fonts from the same release URL.
108
110
 
111
+ ## Using it from the delivery-comms kit
112
+
113
+ The homemade-claude-kit renders decks (`com-slide-deck`), artefact views (`com-artefact-viz`) and release notes (`com-release-note`) with the design system a project pins. A project pins this package once, with the kit's `ux-design-system` skill, at an exact version (1.1.0 is the first release with the kit modules):
114
+
115
+ ```sh
116
+ python3 <skill-dir>/scripts/design_system.py point @medquantis/design-system@1.1.0
117
+ ```
118
+
119
+ In the kit's words this is `ux-design-system point @medquantis/design-system@1.1.0`. It writes the pin to `docs/ux/package.json`, checks the package's `kit-manifest.json` through the kit resolver and prints the Dependabot entry (`directory: "/docs/ux"`) that turns later releases into pull requests. Change the pin only with `point`, never by hand, and never add a `docs/ux/tokens.css`. Each render writes `<output>.provenance.json`, which names the module each value came from.
120
+
121
+ `kit-manifest.json`, at the top of the package, declares all nine modules of the contract, so the kit's base theme fills none of them:
122
+
123
+ | Module | File | Carries |
124
+ | :-- | :-- | :-- |
125
+ | `core` | `dist/kit/core.css` | Text, canvas, surface, border, accent and status colours, the tertiary grey of footers and legal lines, the three faces with their font files, title size, spacing, radii and the card shadow |
126
+ | `dataviz` | `dist/kit/dataviz.css` | The ordered navy and blue-grey chart series, the rest series, axis, grid and highlight |
127
+ | `type` | `dist/kit/type.css` | The type scale, the body and tight line heights, weights 400 and 500 |
128
+ | `space-shape` | `dist/kit/space-shape.css` | The smallest and largest spacing steps, the small radius, the 6 px maximum radius (no pill shapes) and the hairline stroke |
129
+ | `document` | `dist/kit/document.css` | The A4 document: page colour, text size, rules, and the MedQuantis rules for the kit's document classes |
130
+ | `slide-frame` | `dist/kit/slide-frame.css` | The 1280 by 720 slide: canvas, padding, section label, and the footer row with the legal line and slide number |
131
+ | `print` | `dist/kit/print.css` | The release-note report: page size, margins, and breaking changes in navy, never a status hue |
132
+ | `brand` | `dist/kit/brand.css` | The wordmarks on light and on navy, the monogram and the legal line |
133
+ | `guidance` | `dist/kit/guidance.md` | The rules from `guidelines/` that the kit's skills read before writing a page |
134
+
135
+ The kit lines a consumer repository adds to its `AGENTS.md` (or `CLAUDE.md`) are the kit's own: copy the [AGENTS.md block of `ux-design-system`](https://github.com/VictorHueni/homemade-claude-kit/blob/release/2.0/plugins/delivery-comms/skills/ux-design-system/references/agents-md-block.md) as it stands at the kit version you use, rather than a copy kept here. Below it, add the MedQuantis lines:
136
+
137
+ ```markdown
138
+ ## MedQuantis brand
139
+ - Anything that carries the MedQuantis brand (slides, A4 reports, web pages, app screens, charts) outside a kit render is built with the `medquantis-design-system` skill, and is not done until its validator (`validate.py --record`) reports no finding.
140
+ - Values come from `--mq-*` tokens only; a local addition uses this project's own prefix and references `var(--mq-*)`, never a literal colour, font or shadow.
141
+ - Documents (slides, reports, papers, the website) are navy only and show a state by mark style; the status colours belong to interactive apps alone.
142
+ - Tools that read a DESIGN.md take the one in the pinned package (`@medquantis/design-system/DESIGN.md`), never a hand-written copy.
143
+ ```
144
+
145
+ To give every session in that repository the `medquantis-design-system` plugin, local and cloud alike, commit this `.claude/settings.json` (merge the two keys into an existing file).
146
+
147
+ ```json
148
+ {
149
+ "extraKnownMarketplaces": {
150
+ "medquantis": {
151
+ "source": { "source": "github", "repo": "MedQuantis/design-system" }
152
+ }
153
+ },
154
+ "enabledPlugins": {
155
+ "medquantis-design-system@medquantis": true
156
+ }
157
+ }
158
+ ```
159
+
160
+ Tools and agents outside the kit read `dist/DESIGN.md` (exported as `@medquantis/design-system/DESIGN.md`): the same tokens and rules in Google's DESIGN.md format, generated by `make build` and checked with Google's linter.
161
+
109
162
  ## Specialisation rules
110
163
 
111
164
  1. Core and semantic tokens are not overridden in a consumer.
@@ -125,8 +178,11 @@ make brand # re-outline the monogram and wordmark SVGs from the pinned Ou
125
178
  make brand-check # prove the committed brand SVGs reproduce byte for byte (Python, not in make check)
126
179
  make skill # regenerate the Claude skill's references, eval graders and assets
127
180
  make skill-zip # zip the skill for claude.ai into dist/
181
+ make kit-check # run the homemade-claude-kit resolver and renderers on the packed package (needs KIT_DIR)
128
182
  ```
129
183
 
184
+ `make kit-check` packs the package as npm would publish it, unpacks it into a fresh temporary folder and runs the kit resolver (`plugins/delivery-comms/shared/design_source.py provenance`) on it, through the kit's own mise environment, expecting all nine modules from this package. It then renders the fictitious fixtures of `tests/fixtures/kit-render/` with the kit's own renderers (a deck, an A4 document and a release-note report) and requires `PASS: no findings` from the kit validator `check_render.py` on each; `KIT_CHECK_OUT=<folder>` keeps a copy of the three pages. `KIT_DIR` names a local homemade-claude-kit checkout, for example `KIT_DIR=../homemade-claude-kit make kit-check`; without it the target prints a skip message and exits 0. It is a separate gate, not part of `make check`, because CI has no kit checkout. `kit-manifest.json` is a build output at the repository root (gitignored), because the kit reads the manifest only at the top of the package.
185
+
130
186
  `fonts/` and `icons/` are committed copies of exact-pinned packages because they ship in the npm package; a unit test fails when they drift, so a Dependabot bump of a font or of Lucide needs `make assets` in the same PR. The screen wordmarks use live text, which renders in Outfit only where the page loads `fonts.css` (inline SVG); in an `<img>` use the `-print` variant.
131
187
 
132
188
  `make build` installs the npm dependencies from `package-lock.json` (`npm ci --ignore-scripts`) when the lockfile changes, then regenerates `dist/` from `tokens/` with Style Dictionary. `make check` is the single local entry point and mirrors CI, which installs the same tools from `mise.toml` and runs the same target. Locally the deny-list scan warns when `MQ_DENYLIST` is unset; point it at a copy of the deny-list (or `tests/fixtures/denylist.txt` for a dry run) to run the full check.
package/css/app.css CHANGED
@@ -1,3 +1,4 @@
1
+ /*! @medquantis/design-system | © 2026 MedQuantis SA | MIT License, see LICENSE */
1
2
  /*
2
3
  * MedQuantis status badges for interactive apps only (ADR-0004). Documents never load this
3
4
  * file. A status badge always carries a word or an icon, never colour alone (WCAG 1.4.1).
package/css/base.css CHANGED
@@ -1,3 +1,4 @@
1
+ /*! @medquantis/design-system | © 2026 MedQuantis SA | MIT License, see LICENSE */
1
2
  /*
2
3
  * MedQuantis typography roles for documents, slides and pages (build-less media).
3
4
  * Tokens only: load dist/tokens.css (and fonts/fonts.css) first. Every selector sits in :where()
@@ -12,7 +13,7 @@
12
13
  font-family: var(--mq-font-family-body);
13
14
  font-size: var(--mq-font-size-body);
14
15
  font-weight: var(--mq-font-weight-body);
15
- line-height: 1.55;
16
+ line-height: var(--mq-font-line-height-body);
16
17
  text-rendering: optimizeLegibility;
17
18
  -webkit-font-smoothing: antialiased;
18
19
  }
@@ -50,7 +51,7 @@
50
51
 
51
52
  :where(.mq-title) {
52
53
  font-size: var(--mq-font-size-h2);
53
- line-height: 1.15;
54
+ line-height: var(--mq-font-line-height-tight);
54
55
  letter-spacing: -0.01em;
55
56
  }
56
57
 
@@ -1,3 +1,4 @@
1
+ /*! @medquantis/design-system | © 2026 MedQuantis SA | MIT License, see LICENSE */
1
2
  /*
2
3
  * MedQuantis document components: cards, navy panel, KPI tiles, table, badges, callout,
3
4
  * progress and distribution bars, legend, takeaway and footer.
@@ -34,7 +35,7 @@
34
35
  color: var(--mq-muted);
35
36
  font-family: var(--mq-font-family-body);
36
37
  font-size: var(--mq-font-size-small);
37
- line-height: 1.55;
38
+ line-height: var(--mq-font-line-height-body);
38
39
  }
39
40
 
40
41
  /* Navy panel */
@@ -73,7 +74,7 @@
73
74
  color: var(--mq-on-navy-second-level);
74
75
  font-family: var(--mq-font-family-body);
75
76
  font-size: var(--mq-font-size-small);
76
- line-height: 1.55;
77
+ line-height: var(--mq-font-line-height-body);
77
78
  }
78
79
 
79
80
  :where(.mq-panel-rule) {
@@ -0,0 +1,91 @@
1
+ /*! @medquantis/design-system | © 2026 MedQuantis SA | MIT License, see LICENSE */
2
+ /*
3
+ * Class rules of the MedQuantis document module for the homemade-claude-kit renderers
4
+ * (com-slide-deck mode: document; Plan-0002 increment 02). Written by hand against contract roles
5
+ * only: core, type, space-shape, dataviz and the document roles, which tokens/kit/ maps. The
6
+ * build copies these rules into dist/kit/document.css after the roles. build/kit-classes.md names
7
+ * the MedQuantis rule each class reproduces: the A4 sheet of css/print.css (mq-page) with the
8
+ * body text of css/base.css (mq-doc).
9
+ *
10
+ * Cascade: com-slide-deck adds its document baseline (doc.baseline.css) after the design layer,
11
+ * so the rules it also writes carry one more element in their selector. The page box and the
12
+ * print margins stay the deck's config.yaml page: block.
13
+ */
14
+
15
+ /* mq-page and mq-doc: the sheet on the canvas colour (owner ruling 9), Newsreader body. */
16
+ body .doc {
17
+ background: var(--doc-page-bg);
18
+ color: var(--ink);
19
+ font-family: var(--font-body);
20
+ font-size: var(--doc-text-size);
21
+ font-weight: var(--font-weight-regular);
22
+ line-height: var(--line-height-body);
23
+ }
24
+
25
+ /* Headings in Outfit 500, never 700 (owner ruling 4, guidelines/typography.md). */
26
+ .doc h1,
27
+ .doc h2,
28
+ .doc h3 {
29
+ margin: var(--space-lg) 0 var(--space-sm);
30
+ color: var(--ink);
31
+ font-family: var(--font-heading);
32
+ font-weight: var(--font-weight-bold);
33
+ line-height: var(--line-height-tight);
34
+ }
35
+
36
+ .doc h1 {
37
+ font-size: var(--title-size);
38
+ letter-spacing: -0.015em;
39
+ }
40
+
41
+ .doc h2 {
42
+ font-size: var(--font-size-lg);
43
+ letter-spacing: -0.01em;
44
+ }
45
+
46
+ .doc h3 {
47
+ font-size: var(--font-size-md);
48
+ }
49
+
50
+ .doc p {
51
+ margin: 0 0 var(--space-md);
52
+ }
53
+
54
+ /* A section opens with its own head; its first element keeps no top margin. */
55
+ .doc-section > :first-child {
56
+ margin-top: 0;
57
+ }
58
+
59
+ /* A section that follows on the same page: a hairline rule and the space between sections. */
60
+ body .doc-section.doc-section--flow {
61
+ margin-top: var(--space-xl);
62
+ padding-top: var(--space-lg);
63
+ border-top: var(--border-width) solid var(--doc-rule);
64
+ }
65
+
66
+ /* mq-eyebrow: Geist Mono 500 capitals in navy above a heading. */
67
+ .doc-label {
68
+ margin: 0 0 var(--space-sm);
69
+ color: var(--accent);
70
+ font-family: var(--font-mono);
71
+ font-size: var(--font-size-xs);
72
+ font-weight: var(--font-weight-bold);
73
+ letter-spacing: 0.16em;
74
+ text-transform: uppercase;
75
+ }
76
+
77
+ /* A block that never splits across pages (guidelines/layout.md, Print and PDF). */
78
+ body .doc-keep {
79
+ break-inside: avoid;
80
+ page-break-inside: avoid;
81
+ }
82
+
83
+ /* In a document the source bar flows as a footnote: the kit's base slide-frame positions it on
84
+ a slide canvas, which a document does not have. */
85
+ .doc .slide-source-bar {
86
+ position: static;
87
+ color: var(--muted);
88
+ font-family: var(--font-body);
89
+ font-size: var(--font-size-sm);
90
+ font-style: italic;
91
+ }
@@ -0,0 +1,81 @@
1
+ /*! @medquantis/design-system | © 2026 MedQuantis SA | MIT License, see LICENSE */
2
+ /*
3
+ * Class rules of the MedQuantis print module for the homemade-claude-kit renderers (the
4
+ * com-release-note report; Plan-0002 increment 02). Written by hand against contract roles only.
5
+ * The report inlines the core, dataviz, type, space-shape and print modules (render_pdf.py
6
+ * REPORT_MODULES, kit #149). The sizes are the A4 print column of guidelines/typography.md, which
7
+ * is not yet a token, and the weight is the heading weight 500 (owner ruling 4); the template's
8
+ * own bold text and chips read --font-weight-bold and --radius-pill from the design. The build
9
+ * copies these rules into dist/kit/print.css after the roles.
10
+ * build/kit-classes.md names the MedQuantis rule each class reproduces: css/print.css (mq-page)
11
+ * and the typography roles of css/base.css.
12
+ *
13
+ * Cascade: the report template's own rules come before the design layer, so these rules, of
14
+ * the same specificity, replace them. The page box is --print-page-size and --print-margin.
15
+ */
16
+
17
+ /* mq-page: the A4 sheet on the canvas colour (owner ruling 9), ink text. */
18
+ .report {
19
+ background: var(--print-bg);
20
+ color: var(--ink);
21
+ }
22
+
23
+ /* mq-eyebrow: Geist Mono 500 capitals in navy, 7.5 pt in print. */
24
+ .report-kicker {
25
+ color: var(--accent);
26
+ font-family: var(--font-mono);
27
+ font-size: 7.5pt;
28
+ font-weight: 500;
29
+ letter-spacing: 0.16em;
30
+ text-transform: uppercase;
31
+ }
32
+
33
+ /* mq-display: the document title in Outfit 500, 26 pt in print. */
34
+ .report-title {
35
+ color: var(--ink);
36
+ font-family: var(--font-heading);
37
+ font-size: 26pt;
38
+ font-weight: 500;
39
+ line-height: 1.08;
40
+ letter-spacing: -0.025em;
41
+ }
42
+
43
+ /* mq-lead: Newsreader italic in the secondary text colour, 11.5 pt in print. */
44
+ .report-framing {
45
+ color: var(--muted);
46
+ font-family: var(--font-body);
47
+ font-size: 11.5pt;
48
+ font-style: italic;
49
+ line-height: 1.5;
50
+ }
51
+
52
+ /* The space between sections (guidelines/layout.md, Widths and spacing). */
53
+ .section {
54
+ margin-top: var(--space-lg);
55
+ }
56
+
57
+ /* A section label: Outfit 500 capitals, 12.5 pt, under a 2 px navy rule like "In brief"
58
+ (guidelines/layout.md, Report skeleton). */
59
+ .section-label {
60
+ padding-bottom: var(--space-sm);
61
+ border-bottom: 2px solid var(--accent);
62
+ color: var(--ink);
63
+ font-family: var(--font-heading);
64
+ font-size: 12.5pt;
65
+ font-weight: 500;
66
+ letter-spacing: 0.04em;
67
+ }
68
+
69
+ /* A section that leads a fresh page (guidelines/layout.md, Print and PDF). */
70
+ .section--page-break {
71
+ break-before: page;
72
+ page-break-before: always;
73
+ }
74
+
75
+ /* Documents are navy only (ADR-0004, guidelines/colour.md): the breaking-changes label reads by
76
+ its words and a navy rule, never by a status hue. --print-breaking is the navy accent, and the
77
+ kit's template washes the breaking-changes panel with it too. */
78
+ .section--breaking .section-label {
79
+ border-bottom-color: var(--print-breaking);
80
+ color: var(--print-breaking);
81
+ }
@@ -0,0 +1,99 @@
1
+ /*! @medquantis/design-system | © 2026 MedQuantis SA | MIT License, see LICENSE */
2
+ /*
3
+ * Class rules of the MedQuantis slide-frame module for the homemade-claude-kit renderers
4
+ * (Plan-0002 increment 02). Written by hand against contract roles only: core, type, space-shape,
5
+ * dataviz and the slide-frame roles, which tokens/kit/ maps. The build copies these rules into
6
+ * dist/kit/slide-frame.css after the roles. build/kit-classes.md names the MedQuantis rule each
7
+ * class reproduces: css/slide.css, with the legal line bottom left and the slide number bottom
8
+ * right (owner ruling 11, guidelines/brand.md).
9
+ *
10
+ * Cascade: the kit inlines its base slide-frame.css before this module, so these rules restyle
11
+ * it; com-slide-deck adds its baseline (controls hint, presentation mode) after the design layer,
12
+ * so the rules for those classes carry one more element in their selector.
13
+ * The footer row and the source line use --tertiary, the tertiary grey of owner ruling 1.
14
+ */
15
+
16
+ /* mq-slide: the canvas, body text in Newsreader. The kit's render.py drops the shadow in the PDF. */
17
+ .slide {
18
+ border-radius: 0;
19
+ box-shadow: var(--shadow);
20
+ font-family: var(--font-body);
21
+ font-size: var(--font-size-md);
22
+ line-height: var(--line-height-body);
23
+ }
24
+
25
+ /* mq-slide-label: mono capitals in navy, 48 px from the top, at the side margin. */
26
+ .slide-label {
27
+ top: var(--space-xl);
28
+ left: var(--slide-padding);
29
+ margin: 0;
30
+ font-weight: var(--font-weight-bold);
31
+ letter-spacing: 0.18em;
32
+ }
33
+
34
+ /* mq-slide-foot: one row, the legal line at the left and the number at the right, 24 px above
35
+ the bottom edge, at the side margins. */
36
+ .slide-footer {
37
+ right: var(--slide-padding);
38
+ bottom: calc(var(--space-md) + var(--space-sm));
39
+ left: var(--slide-padding);
40
+ height: auto;
41
+ align-items: baseline;
42
+ justify-content: space-between;
43
+ gap: calc(var(--space-md) + var(--space-sm));
44
+ color: var(--tertiary);
45
+ font-family: var(--font-mono);
46
+ font-size: var(--font-size-sm);
47
+ line-height: var(--line-height-tight);
48
+ }
49
+
50
+ /* MedQuantis slides carry no logo in the footer row (owner ruling 11, guidelines/layout.md). */
51
+ .slide-logo {
52
+ display: none;
53
+ }
54
+
55
+ .slide-legal {
56
+ margin: 0;
57
+ }
58
+
59
+ /* mq-slide-number: the eyebrow size, tabular figures. */
60
+ .slide-number {
61
+ font-size: var(--font-size-xs);
62
+ font-variant-numeric: tabular-nums;
63
+ }
64
+
65
+ /* A cited source on a slide: the note style of guidelines/typography.md, above the footer row. */
66
+ .slide .slide-source-bar {
67
+ right: var(--slide-padding);
68
+ bottom: calc(var(--space-md) + var(--space-sm) + var(--space-lg));
69
+ left: var(--slide-padding);
70
+ color: var(--tertiary);
71
+ font-family: var(--font-body);
72
+ font-size: var(--font-size-sm);
73
+ font-style: italic;
74
+ }
75
+
76
+ /* The controls hint above the deck: a hint in Geist Mono, as in an empty state (guidelines/layout.md, App patterns). */
77
+ body .controls-hint {
78
+ color: var(--muted);
79
+ font-family: var(--font-mono);
80
+ font-size: var(--font-size-xs);
81
+ letter-spacing: 0.04em;
82
+ }
83
+
84
+ body .controls-hint kbd {
85
+ border-color: var(--border);
86
+ border-radius: var(--radius-sm);
87
+ background: var(--surface);
88
+ color: var(--ink);
89
+ font-family: var(--font-mono);
90
+ }
91
+
92
+ /* Presentation mode: the slide alone on an ink surround, without the desk shadow. */
93
+ html body.presenting {
94
+ background: var(--ink);
95
+ }
96
+
97
+ html body.presenting .slide.active {
98
+ box-shadow: none;
99
+ }
package/css/print.css CHANGED
@@ -1,3 +1,4 @@
1
+ /*! @medquantis/design-system | © 2026 MedQuantis SA | MIT License, see LICENSE */
1
2
  /*
2
3
  * MedQuantis A4 print: one .mq-page per sheet (named page mq-a4), colours printed exactly,
3
4
  * motion stopped. On screen the pages sit on the desk; the desk never reaches paper
package/css/slide.css CHANGED
@@ -1,3 +1,4 @@
1
+ /*! @medquantis/design-system | © 2026 MedQuantis SA | MIT License, see LICENSE */
1
2
  /*
2
3
  * MedQuantis slide canvas: 1280 x 720, section label, title, body area, and a footer row with
3
4
  * the legal line at the left and the slide number at the right (owner ruling 11).
@@ -46,7 +47,7 @@
46
47
  font-family: var(--mq-font-family-heading);
47
48
  font-size: var(--mq-font-size-slide-title);
48
49
  font-weight: var(--mq-font-weight-heading);
49
- line-height: 1.15;
50
+ line-height: var(--mq-font-line-height-tight);
50
51
  letter-spacing: -0.01em;
51
52
  text-wrap: balance;
52
53
  }