@pnx-mixtape/mxds 0.1.0-rc.4 → 0.1.0-rc.5
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/.claude/skills/create-mxds-component/SKILL.md +77 -0
- package/DESIGN.md +595 -0
- package/README.md +1 -2
- package/dist/build/accordion.entry.js +2 -1
- package/dist/build/autocomplete.entry.js +1 -1
- package/dist/build/back-to-top.css +1 -0
- package/dist/build/back-to-top.entry.js +1 -0
- package/dist/build/button.css +1 -1
- package/dist/build/card.css +1 -1
- package/dist/build/chunks/Accordion-D2wp8hBG.js +44 -0
- package/dist/build/chunks/AccordionGroup-BYtoAFxg.js +47 -0
- package/dist/build/chunks/AccordionMobile-D3sTeiM5.js +26 -0
- package/dist/build/chunks/Autocomplete-kRo8RNbC.js +135 -0
- package/dist/build/chunks/BackToTop-4M-Wl7z3.js +64 -0
- package/dist/build/chunks/ClosableAlert-yy84gae6.js +55 -0
- package/dist/build/chunks/CookieConsent-wd8gQ2Oe.js +18 -0
- package/dist/build/chunks/Dialog-DWoXW-7Z.js +48 -0
- package/dist/build/chunks/DropMenu-CSTZq0Zt.js +68 -0
- package/dist/build/chunks/FeedbackForm-BochXEDx.js +64 -0
- package/dist/build/chunks/Gallery-Rkfv7Mbb.js +165 -0
- package/dist/build/chunks/GlobalToggle-CzlkpLpc.js +82 -0
- package/dist/build/chunks/InPageNavigation-D1Kk-rCm.js +86 -0
- package/dist/build/chunks/Navigation-CDQnN61h.js +147 -0
- package/dist/build/chunks/Popover-CiTAftNU.js +30 -0
- package/dist/build/chunks/Sticky-DoVndENm.js +51 -0
- package/dist/build/chunks/Tabs-BDlxCDNh.js +160 -0
- package/dist/build/chunks/Translate-bmM38j6z.js +46 -0
- package/dist/build/chunks/cookie-compliance-CG6x-TcV.js +119 -0
- package/dist/build/chunks/enums-BrHxPZZ_.js +36 -0
- package/dist/build/chunks/polyfills-D-qh1a_2.js +33 -0
- package/dist/build/chunks/utilities-Dd-08SW6.js +255 -0
- package/dist/build/content-block.css +1 -1
- package/dist/build/cookie-consent.entry.js +1 -1
- package/dist/build/dialog.entry.js +1 -1
- package/dist/build/drop-menu.entry.js +1 -1
- package/dist/build/elements.js +147 -1
- package/dist/build/feedback-form.css +1 -0
- package/dist/build/feedback-form.entry.js +1 -0
- package/dist/build/filters.entry.js +145 -1
- package/dist/build/gallery.entry.js +1 -1
- package/dist/build/global-alert.entry.js +1 -1
- package/dist/build/header.css +1 -1
- package/dist/build/header.entry.js +1 -1
- package/dist/build/icon.css +1 -1
- package/dist/build/in-page-navigation.entry.js +1 -1
- package/dist/build/navigation.entry.js +1 -1
- package/dist/build/pagination.css +1 -1
- package/dist/build/popover.entry.js +1 -1
- package/dist/build/react.js +2270 -1
- package/dist/build/sticky.entry.js +1 -1
- package/dist/build/tabs.entry.js +1 -1
- package/dist/build/translate.css +1 -0
- package/dist/build/translate.entry.js +1 -0
- package/dist/build/utility-list.entry.js +53 -1
- package/dist/types/Component/BackToTop/BackToTop.d.ts +20 -0
- package/dist/types/Component/BackToTop/BackToTop.d.ts.map +1 -0
- package/dist/types/Component/BackToTop/Elements/BackToTop.d.ts +27 -0
- package/dist/types/Component/BackToTop/Elements/BackToTop.d.ts.map +1 -0
- package/dist/types/Component/BackToTop/back-to-top.entry.d.ts +2 -0
- package/dist/types/Component/BackToTop/back-to-top.entry.d.ts.map +1 -0
- package/dist/types/Component/DropMenu/DropMenu.d.ts +2 -1
- package/dist/types/Component/DropMenu/DropMenu.d.ts.map +1 -1
- package/dist/types/Component/Tabs/Components/TabDropMenu.d.ts.map +1 -1
- package/dist/types/Component/Tabs/Elements/Tabs.d.ts.map +1 -1
- package/dist/types/Component/Translate/Elements/Translate.d.ts +23 -0
- package/dist/types/Component/Translate/Elements/Translate.d.ts.map +1 -0
- package/dist/types/Component/Translate/Translate.d.ts +37 -0
- package/dist/types/Component/Translate/Translate.d.ts.map +1 -0
- package/dist/types/Component/Translate/languages.d.ts +11 -0
- package/dist/types/Component/Translate/languages.d.ts.map +1 -0
- package/dist/types/Component/Translate/translate.entry.d.ts +2 -0
- package/dist/types/Component/Translate/translate.entry.d.ts.map +1 -0
- package/dist/types/Form/FeedbackForm/Elements/FeedbackForm.d.ts +37 -0
- package/dist/types/Form/FeedbackForm/Elements/FeedbackForm.d.ts.map +1 -0
- package/dist/types/Form/FeedbackForm/FeedbackForm.d.ts +36 -0
- package/dist/types/Form/FeedbackForm/FeedbackForm.d.ts.map +1 -0
- package/dist/types/Form/FeedbackForm/feedback-form.entry.d.ts +2 -0
- package/dist/types/Form/FeedbackForm/feedback-form.entry.d.ts.map +1 -0
- package/dist/types/Utility/Elements/google-translate-widget.d.ts +91 -0
- package/dist/types/Utility/Elements/google-translate-widget.d.ts.map +1 -0
- package/dist/types/Utility/utilities.d.ts +2 -0
- package/dist/types/Utility/utilities.d.ts.map +1 -1
- package/dist/types/elements.d.ts +3 -0
- package/dist/types/elements.d.ts.map +1 -1
- package/dist/types/enums.d.ts +3 -1
- package/dist/types/enums.d.ts.map +1 -1
- package/dist/types/react.d.ts +3 -0
- package/dist/types/react.d.ts.map +1 -1
- package/docs/API.md +1215 -0
- package/docs/CSSGuidelines.md +891 -0
- package/docs/CodeQuality.md +940 -0
- package/docs/ComponentArchitecture.md +714 -0
- package/docs/Contributing.md +626 -0
- package/docs/MemoryManagement.md +598 -0
- package/docs/Migrations.md +6 -0
- package/docs/README.md +100 -0
- package/docs/Security.md +444 -0
- package/docs/Testing.md +739 -0
- package/docs/Troubleshooting.md +674 -0
- package/package.json +6 -3
- package/src/Atom/Button/Button.tsx +1 -1
- package/src/Atom/Button/__snapshots__/Button.stories.tsx.snap +2 -2
- package/src/Atom/Button/_buttons.css +1 -0
- package/src/Atom/Icon/README.md +1 -1
- package/src/Atom/Icon/_icon.css +1 -0
- package/src/Atom/Icon/images/thumb.svg +1 -0
- package/src/Atom/Media/__snapshots__/Media.stories.ts.snap +4 -9
- package/src/Atom/Media/media.twig +4 -5
- package/src/Component/BackToTop/BackToTop.stories.ts +127 -0
- package/src/Component/BackToTop/BackToTop.stories.tsx +53 -0
- package/src/Component/BackToTop/BackToTop.tsx +120 -0
- package/src/Component/BackToTop/Elements/BackToTop.ts +119 -0
- package/src/Component/BackToTop/README.md +164 -0
- package/src/Component/BackToTop/__snapshots__/BackToTop.stories.ts.snap +24 -0
- package/src/Component/BackToTop/__snapshots__/BackToTop.stories.tsx.snap +3 -0
- package/src/Component/BackToTop/back-to-top.css +70 -0
- package/src/Component/BackToTop/back-to-top.entry.js +1 -0
- package/src/Component/BackToTop/back-to-top.twig +26 -0
- package/src/Component/Card/Components/CardContent.tsx +1 -1
- package/src/Component/Card/Components/CardMedia.tsx +1 -1
- package/src/Component/Card/__snapshots__/Card.stories.tsx.snap +3 -3
- package/src/Component/Card/card.css +1 -1
- package/src/Component/Carousel/Carousel.stories.ts +66 -36
- package/src/Component/Carousel/__snapshots__/Carousel.stories.tsx.snap +5 -5
- package/src/Component/ContentBlock/Components/ContentBlockMedia.tsx +1 -1
- package/src/Component/ContentBlock/content-block.css +1 -1
- package/src/Component/DropMenu/DropMenu.stories.ts +21 -2
- package/src/Component/DropMenu/DropMenu.tsx +14 -4
- package/src/Component/DropMenu/__snapshots__/DropMenu.stories.ts.snap +3 -3
- package/src/Component/DropMenu/__snapshots__/DropMenu.stories.tsx.snap +2 -2
- package/src/Component/DropMenu/drop-menu.twig +7 -1
- package/src/Component/HeroBanner/__snapshots__/HeroBanner.stories.tsx.snap +1 -1
- package/src/Component/InPageNavigation/__snapshots__/InPageNavigation.stories.ts.snap +48 -13
- package/src/Component/InPageNavigation/in-page-navigation.twig +4 -6
- package/src/Component/ListItem/Components/ListItemMedia.tsx +1 -1
- package/src/Component/Pagination/Pagination.stories.ts +57 -27
- package/src/Component/Pagination/pagination.css +16 -7
- package/src/Component/Popover/__snapshots__/Popover.stories.tsx.snap +3 -3
- package/src/Component/Tabs/Components/TabDropMenu.tsx +7 -1
- package/src/Component/Tabs/Elements/Tabs.ts +13 -3
- package/src/Component/Tabs/Tabs.stories.ts +33 -12
- package/src/Component/Tabs/Tabs.stories.tsx +28 -14
- package/src/Component/Tabs/__snapshots__/Tabs.stories.ts.snap +3 -3
- package/src/Component/Tabs/__snapshots__/Tabs.stories.tsx.snap +2 -2
- package/src/Component/Translate/Elements/Translate.ts +76 -0
- package/src/Component/Translate/README.md +283 -0
- package/src/Component/Translate/Translate.stories.ts +87 -0
- package/src/Component/Translate/Translate.stories.tsx +77 -0
- package/src/Component/Translate/Translate.tsx +213 -0
- package/src/Component/Translate/__snapshots__/Translate.stories.ts.snap +18 -0
- package/src/Component/Translate/__snapshots__/Translate.stories.tsx.snap +3 -0
- package/src/Component/Translate/languages.ts +39 -0
- package/src/Component/Translate/translate.css +62 -0
- package/src/Component/Translate/translate.entry.js +1 -0
- package/src/Component/Translate/translate.twig +44 -0
- package/src/Form/Autocomplete/Autocomplete.stories.tsx +2 -1
- package/src/Form/FeedbackForm/Elements/FeedbackForm.ts +122 -0
- package/src/Form/FeedbackForm/FeedbackForm.stories.ts +99 -0
- package/src/Form/FeedbackForm/FeedbackForm.stories.tsx +73 -0
- package/src/Form/FeedbackForm/FeedbackForm.tsx +196 -0
- package/src/Form/FeedbackForm/README.md +233 -0
- package/src/Form/FeedbackForm/__snapshots__/FeedbackForm.stories.ts.snap +125 -0
- package/src/Form/FeedbackForm/__snapshots__/FeedbackForm.stories.tsx.snap +5 -0
- package/src/Form/FeedbackForm/feedback-form.css +74 -0
- package/src/Form/FeedbackForm/feedback-form.entry.js +1 -0
- package/src/Form/FeedbackForm/feedback-form.twig +80 -0
- package/src/Layout/Header/Components/GlobalToggle.tsx +1 -1
- package/src/Layout/Header/Header.stories.ts +53 -48
- package/src/Layout/Header/Header.stories.tsx +35 -22
- package/src/Layout/Header/Header.tsx +2 -2
- package/src/Layout/Header/__snapshots__/Header.stories.ts.snap +14 -10
- package/src/Layout/Header/__snapshots__/Header.stories.tsx.snap +2 -2
- package/src/Layout/Header/_toggles.css +7 -7
- package/src/Layout/Page/__snapshots__/Page.stories.tsx.snap +1 -1
- package/src/Utility/Elements/google-translate-widget.ts +293 -0
- package/src/Utility/global.d.ts +4 -0
- package/src/Utility/utilities.ts +2 -0
- package/src/elements.ts +3 -0
- package/src/enums.ts +2 -0
- package/src/react.ts +3 -0
- package/dist/build/chunks/Accordion-GN0sME4W.js +0 -1
- package/dist/build/chunks/AccordionGroup-Bzqp5__q.js +0 -1
- package/dist/build/chunks/AccordionMobile-DG5jSe8Q.js +0 -1
- package/dist/build/chunks/Autocomplete-B4RtkAyh.js +0 -1
- package/dist/build/chunks/ClosableAlert-DEhj8Nxm.js +0 -1
- package/dist/build/chunks/CookieConsent-BkCMRVST.js +0 -1
- package/dist/build/chunks/Dialog-Haahn-Yn.js +0 -1
- package/dist/build/chunks/DropMenu-1baQc8Yc.js +0 -1
- package/dist/build/chunks/Gallery-D8NGXy2Q.js +0 -1
- package/dist/build/chunks/GlobalToggle-B52fdBQu.js +0 -1
- package/dist/build/chunks/InPageNavigation-Dyn2TR-N.js +0 -1
- package/dist/build/chunks/Navigation-hOrfLq7h.js +0 -1
- package/dist/build/chunks/Popover-Cxg-s5Jn.js +0 -1
- package/dist/build/chunks/Sticky-BGCuuEJK.js +0 -1
- package/dist/build/chunks/Tabs-DYy1YTdU.js +0 -15
- package/dist/build/chunks/cookie-compliance-Bbm-0vpj.js +0 -1
- package/dist/build/chunks/enums-DLV_1NAf.js +0 -1
- package/dist/build/chunks/polyfills-C7pRt54M.js +0 -1
- package/dist/build/chunks/utilities-_Bq3TxAQ.js +0 -1
package/DESIGN.md
ADDED
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
# Mixtape Design System — Design Reference
|
|
2
|
+
|
|
3
|
+
> This file is a structured reference for AI Design based tool onboarding (eg. Claude Design). It maps the design system's
|
|
4
|
+
> tokens, components, conventions, and rules so the Agent can accurately generate designs and prototypes
|
|
5
|
+
> using this system without ambiguity.
|
|
6
|
+
>
|
|
7
|
+
> **Read this as instruction, not advice.** Every "read X" below is a directive, not a suggestion — if a
|
|
8
|
+
> section says to read a file or use a specific class, do that; do not infer an alternative from context.
|
|
9
|
+
> When in doubt, prefer an existing class or token over inventing one.
|
|
10
|
+
>
|
|
11
|
+
> **When linking this repo to an AI Design tool:**
|
|
12
|
+
>
|
|
13
|
+
> - ✅ Include `dist/build/` — Browser-ready CSS with all tokens resolved, for accurate design generation
|
|
14
|
+
> - ✅ Include `src/` — source files for reference on component structure, token definitions, and CSS architecture
|
|
15
|
+
> - ✅ Include `docs/` — how-to guides, component architecture, CSS conventions
|
|
16
|
+
> - ✅ Include `mockups/` — full page composition examples showing how components assemble together
|
|
17
|
+
> - ❌ Exclude `notes/` — internal development notes, not relevant to design generation
|
|
18
|
+
> - ❌ Exclude build/config files (`pnpm-lock.yaml`, `vite.config.js`, `docker-compose*.yml`, `vitest.config.js`) — these add noise without design value
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Package
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
@pnx-mixtape/mxds
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- Storybook: https://mxds.pnx.io/
|
|
29
|
+
- npm: https://www.npmjs.com/package/@pnx-mixtape/mxds
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Reference materials
|
|
34
|
+
|
|
35
|
+
**For full-page composition examples, read [`mockups/HomePage.stories.ts`](./mockups/HomePage.stories.ts) first.** It shows how Atoms, Components, and Layouts assemble into a complete page using real classes — before generating anything, read at least one mockup end-to-end.
|
|
36
|
+
|
|
37
|
+
**Mockups are Storybook stories; the `args` field is the source HTML.** Ignore the `meta`, decorators, and Storybook boilerplate — the composition you want lives in each story's `args`. Other full-page examples in [`mockups/`](./mockups/): `ArticlePage`, `ArticleListingPage`, `BasicPage`, `ContactPage`, `EventPage`, `EventListingPage`, `LandingPage`, `SearchResultPage`, `SidebarPage`.
|
|
38
|
+
|
|
39
|
+
Each component README ends with a `→ Used in context:` footer pointing at the mockup line where it's composed — follow it to see the component in a real page.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Design Tokens
|
|
44
|
+
|
|
45
|
+
Tokens are defined in **`src/tokens.js`** and compiled into CSS custom properties via `postcss-design-tokens`.
|
|
46
|
+
|
|
47
|
+
The resolved custom properties live in **`src/constants.css`** inside `@layer design-system.defaults`.
|
|
48
|
+
|
|
49
|
+
### Colours
|
|
50
|
+
|
|
51
|
+
| Token path | CSS custom property | Value |
|
|
52
|
+
| ----------------------- | ----------------------------- | --------------------------------- |
|
|
53
|
+
| `colour.primary.colour` | `--colour-primary` | `hsl(223 100% 50%)` — vivid blue |
|
|
54
|
+
| `colour.accent.colour` | `--colour-accent` | `hsl(60, 94%, 68%)` — warm yellow |
|
|
55
|
+
| `colour.main.fg` | `--colour-foreground` | `hsl(60 30% 6%)` — near-black |
|
|
56
|
+
| `colour.main.bg` | `--colour-background` | `hsl(60 0% 100%)` — white |
|
|
57
|
+
| `colour.main.fgAlt` | `--colour-foreground-alt` | `hsl(60 30% 20%)` |
|
|
58
|
+
| `colour.main.bgAlt` | `--colour-background-alt` | `hsl(60 30% 95%)` |
|
|
59
|
+
| `colour.main.border` | `--colour-border` | `hsl(60 5% 85%)` |
|
|
60
|
+
| `colour.reverse.fg` | `--colour-foreground-reverse` | `hsl(60 0% 100%)` |
|
|
61
|
+
| `colour.reverse.bg` | `--colour-background-reverse` | `hsl(60 30% 6%)` |
|
|
62
|
+
| `colour.error` | `--colour-error` | `hsl(348 100% 33%)` — red |
|
|
63
|
+
| `colour.success` | `--colour-success` | `hsl(120 100% 26%)` — green |
|
|
64
|
+
| `colour.warning` | `--colour-warning` | `hsl(35 100% 32%)` — amber |
|
|
65
|
+
| `colour.info` | `--colour-info` | `hsl(223 100% 50%)` — blue |
|
|
66
|
+
|
|
67
|
+
Light/dark mode: colours use `light-dark()` CSS function. The scheme is controlled by `--scheme` (`light | dark`).
|
|
68
|
+
|
|
69
|
+
Tints are derived automatically via `color-mix()`:
|
|
70
|
+
|
|
71
|
+
- `--colour-primary-light` — primary + 90% white
|
|
72
|
+
- `--colour-primary-lighter` — primary + 20% white
|
|
73
|
+
- `--colour-primary-darker` — primary + 10% black
|
|
74
|
+
|
|
75
|
+
### Typography
|
|
76
|
+
|
|
77
|
+
The size scale is generated from a single ratio (`--type-ratio`, default `1.414` — augmentedFourth) using `pow()`, so each step is `base × ratio^n`.
|
|
78
|
+
The ratio comes from `font.size.ratio` in `src/tokens.js`; on `--medium-down` viewports it is replaced with `font.size.ratioSmall` (default `1.2` — minorThird) so the scale tightens automatically on mobile.
|
|
79
|
+
Both values index into a `global.typeScales` table of named scales (`minorSecond` 1.067 → `goldenRatio` 1.618) — swap either token to apply a different musical scale across the whole system.
|
|
80
|
+
|
|
81
|
+
| CSS custom property | Value / formula |
|
|
82
|
+
| ---------------------- | --------------------------------------------------------- |
|
|
83
|
+
| `--font-family` | `system-ui, sans-serif` |
|
|
84
|
+
| `--base-font-size` | `max(1rem, 16px)` |
|
|
85
|
+
| `--type-ratio` | `1.414` desktop / `1.2` mobile (`--medium-down` override) |
|
|
86
|
+
| `--font-size` | base (1rem) — used as the inherited default |
|
|
87
|
+
| `--font-size-xs` | base × `pow(--type-ratio, -0.5)` |
|
|
88
|
+
| `--font-size-s` | base × `pow(--type-ratio, -0.25)` |
|
|
89
|
+
| `--font-size-m` | `1rem` (anchor — equal to base) |
|
|
90
|
+
| `--font-size-ml` | base × `pow(--type-ratio, 0.5)` |
|
|
91
|
+
| `--font-size-l` | base × `pow(--type-ratio, 1)` |
|
|
92
|
+
| `--font-size-xl` | base × `pow(--type-ratio, 2)` |
|
|
93
|
+
| `--font-size-xxl` | base × `pow(--type-ratio, 3)` |
|
|
94
|
+
| `--font-size-xxxl` | base × `pow(--type-ratio, 4)` |
|
|
95
|
+
| `--font-size-diff` | `0.3` — fluid-clamp drop, used by `clamp()` text sizing |
|
|
96
|
+
| `--font-weight-normal` | 400 |
|
|
97
|
+
| `--font-weight-bold` | 700 |
|
|
98
|
+
| `--line-height` | 1.6 (body) |
|
|
99
|
+
| `--line-height-h` | 1.2 (headings) |
|
|
100
|
+
| `--line-height-ui` | `0.9rem` (form controls) |
|
|
101
|
+
|
|
102
|
+
Because `--type-ratio` swaps on the breakpoint, every `--font-size-*` (other than `m`) recalculates fluidly — there is no separate mobile size scale to maintain.
|
|
103
|
+
|
|
104
|
+
> See [`docs/CSSGuidelines.md → Swapping the type scale`](./docs/CSSGuidelines.md#swapping-the-type-scale) for a worked example of overriding to a different musical scale (perfect fourth, golden ratio, etc.).
|
|
105
|
+
|
|
106
|
+
### Spacing
|
|
107
|
+
|
|
108
|
+
Scale is `em`-based. All values map to `--spacing-{size}`:
|
|
109
|
+
|
|
110
|
+
| Size | Value |
|
|
111
|
+
| ------- | ------- |
|
|
112
|
+
| `xxxxs` | 0.25em |
|
|
113
|
+
| `xxxs` | 0.5em |
|
|
114
|
+
| `xxs` | 0.75em |
|
|
115
|
+
| `xs` | 0.875em |
|
|
116
|
+
| `s` | 1em |
|
|
117
|
+
| `m` | 1.5em |
|
|
118
|
+
| `l` | 2em |
|
|
119
|
+
| `xl` | 2.5em |
|
|
120
|
+
| `xxl` | 3em |
|
|
121
|
+
| `xxxl` | 3.5em |
|
|
122
|
+
| `xxxxl` | 4em |
|
|
123
|
+
| `ul` | 4.5em |
|
|
124
|
+
| `uul` | 5em |
|
|
125
|
+
| `uuul` | 5.5em |
|
|
126
|
+
|
|
127
|
+
Gap shortcuts: `--gap-s` (1em), `--gap` (1.5em), `--gap-l` (2em), `--gap-xl` (2.5em)
|
|
128
|
+
|
|
129
|
+
### Breakpoints
|
|
130
|
+
|
|
131
|
+
| Name | Value | Custom media |
|
|
132
|
+
| ----- | ------ | --------------------------------- |
|
|
133
|
+
| `xxs` | 320px | — |
|
|
134
|
+
| `xs` | 420px | `--x-small-up` / `--x-small-down` |
|
|
135
|
+
| `s` | 540px | `--small-up` / `--small-down` |
|
|
136
|
+
| `m` | 720px | `--medium-up` / `--medium-down` |
|
|
137
|
+
| `l` | 946px | `--large-up` / `--large-down` |
|
|
138
|
+
| `xl` | 1100px | `--x-large-up` / `--x-large-down` |
|
|
139
|
+
|
|
140
|
+
Additional utility media queries available: `--touch`, `--mouse`, `--dark`, `--light`, `--use-motion`, `--reduce-motion`, `--high-contrast`, `--portrait`, `--landscape`.
|
|
141
|
+
|
|
142
|
+
This system is **mobile-first** — use `--medium-up` etc. to progressively enhance.
|
|
143
|
+
|
|
144
|
+
### Layout
|
|
145
|
+
|
|
146
|
+
| CSS custom property | Value |
|
|
147
|
+
| ------------------------------ | --------------------------------- |
|
|
148
|
+
| `--container-max-width` | `76ch` (aligned) |
|
|
149
|
+
| `--container-max-width-narrow` | `58ch` (narrow) |
|
|
150
|
+
| `--gutter-min` | `1em` |
|
|
151
|
+
| `--gutter-max` | `2em` |
|
|
152
|
+
| `--border-radius` | `4px` |
|
|
153
|
+
| `--border-radius-l` | `2em` (pill) |
|
|
154
|
+
| `--border-radius-round` | `50%` (circle) |
|
|
155
|
+
| `--box-shadow` | `0 0 0.875em hsl(0 0% 13% / 15%)` |
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## CSS Architecture
|
|
160
|
+
|
|
161
|
+
→ See [`docs/CSSGuidelines.md`](./docs/CSSGuidelines.md) for full details on PostCSS pipeline, BEM naming, cascade layers, custom media, logical properties, and override patterns.
|
|
162
|
+
|
|
163
|
+
**Key facts for quick reference:**
|
|
164
|
+
|
|
165
|
+
- All styles are in named `@layer` sub-layers (`design-system.defaults` → `.atoms` → `.layout` → `.components` → `.utilities`)
|
|
166
|
+
- Class prefix: `mx-` — modifiers are BEM-style `mx-component--modifier`
|
|
167
|
+
- Each component has `component.css` (full), `_component.css` (structure), `_component-styles.css` (colour variants)
|
|
168
|
+
- Any **unlayered CSS wins** over all design system styles — no specificity battles
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Canonical class inventory
|
|
173
|
+
|
|
174
|
+
> **This is the complete list of public `mx-*` classes that exist in the CSS.** Generated from `src/**/*.css`.
|
|
175
|
+
> To regenerate: `grep -rhoE '\.mx-[a-z0-9][a-zA-Z0-9-]*' src --include="*.css" | sort -u`
|
|
176
|
+
>
|
|
177
|
+
> **Nothing else exists — do not invent classes.** If a class you want is not in this list, it is not part of
|
|
178
|
+
> the system. Use an existing class, a CSS custom property override, or unlayered CSS instead.
|
|
179
|
+
|
|
180
|
+
### Atoms
|
|
181
|
+
|
|
182
|
+
| Class | Purpose |
|
|
183
|
+
| ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
184
|
+
| `mx-background--primary` `--accent` `--alt` `--reverse` `--box` `--image` | Coloured background regions |
|
|
185
|
+
| `mx-button` | Base button |
|
|
186
|
+
| `mx-button--dark` `--light` `--accent` `--secondary` `--destructive` `--white` | Button colour variants |
|
|
187
|
+
| `mx-button--outline` | Outline style — **requires a colour modifier** (see grammar) |
|
|
188
|
+
| `mx-button--small` `--large` `--full-width` `--icon-only` | Button layout/size |
|
|
189
|
+
| `mx-heading--xs` `--s` `--m` `--l` `--xl` `--xxl` | Heading size overrides |
|
|
190
|
+
| `mx-headline` | Display headline |
|
|
191
|
+
| `mx-icon` | Base icon |
|
|
192
|
+
| `mx-icon--{name}` | Icon glyph — `{name}` from the `Icons` enum (e.g. `--close`) |
|
|
193
|
+
| `mx-icon--color-brand` `--color-accent` `--color-error` `--color-info` `--color-success` `--color-warning` | Icon colour |
|
|
194
|
+
| `mx-icon--size-sm` `--size-md` `--size-lg` `--size-xl` | Icon size |
|
|
195
|
+
| `mx-icon--rotate-90` `--rotate-180` `--rotate-270` | Icon rotation |
|
|
196
|
+
| `mx-icon--end` `--only` `--status` | Icon placement / icon-only |
|
|
197
|
+
| `mx-link` | Base link |
|
|
198
|
+
| `mx-link--external` `--download` `--more` | Link variants |
|
|
199
|
+
| `mx-list` | Base `<ul>`/`<ol>` list |
|
|
200
|
+
| `mx-list--notes` `--refs` `--stats` `--columns` `--summary` `__action` | List variants — footnotes, hanging-indent references, stat grid, column grid, and (`DefinitionList`-only) review-answers summary rows with an action slot |
|
|
201
|
+
| `mx-media--left` `--center` `--right` `--video` | Media alignment / video aspect |
|
|
202
|
+
| `mx-rich-text` | Rich text (CMS content) region |
|
|
203
|
+
| `mx-table--bordered` `--striped` `--flush` `--small` `--responsive` `--reset` | Table variants |
|
|
204
|
+
| `mx-text--xs` `--s` `--m` `--l` `--xl` `--xxl` `--xxxl` | Text size |
|
|
205
|
+
| `mx-text--primary` `--accent` `--alt` | Text colour |
|
|
206
|
+
| `mx-text--left` `--center` `--right` | Text alignment |
|
|
207
|
+
| `mx-text--eyebrow` `--lede` `--meta` `--embellished` `--embellished-headline` `--section-headline` `--fluid` | Special text styles |
|
|
208
|
+
| `mx-video` | Video embed |
|
|
209
|
+
| `mx-spacing--{side}-{size}` `mx-spacing--reset` `mx-spacing--{side}-reset` | Padding utility — `{side}` = top/bottom/left/right, `{size}` = spacing scale |
|
|
210
|
+
| `mx-margin--{side}-{size}` `mx-margin--reset` `mx-margin--{side}-reset` | Margin utility — same `{side}`/`{size}` grammar as spacing |
|
|
211
|
+
| `mx-animated--fade-in` `--fade-out` `--scale-up` `--scale-down` `--spin` | Animation utilities |
|
|
212
|
+
|
|
213
|
+
### Components
|
|
214
|
+
|
|
215
|
+
| Class | Purpose |
|
|
216
|
+
| ---------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
|
|
217
|
+
| `mx-accordion` `mx-accordions` `mx-accordion--divided` | Accordion + group |
|
|
218
|
+
| `mx-back-to-top` `mx-back-to-top--l` | Scroll-to-top trigger (breakpoint-gated) |
|
|
219
|
+
| `mx-callout` | Callout aside |
|
|
220
|
+
| `mx-card` `mx-card--block` `mx-card--collapse` `mx-card--reversed` | Card + variants |
|
|
221
|
+
| `mx-carousel` | Carousel |
|
|
222
|
+
| `mx-content-block` | Rich content region |
|
|
223
|
+
| `mx-cookie-consent` `mx-cookie-consent__actions` `mx-cookie-consent__inner` | Site-wide cookie consent banner |
|
|
224
|
+
| `mx-dialog` `mx-dialog--fullscreen` | Modal dialog |
|
|
225
|
+
| `mx-drop-menu` | Dropdown menu |
|
|
226
|
+
| `mx-filters` `mx-filters--right` `mx-filters--sticky` `mx-filter-item` | Filter controls |
|
|
227
|
+
| `mx-gallery` `mx-gallery__preview` `mx-gallery__trigger` | Image preview → fullscreen carousel modal |
|
|
228
|
+
| `mx-global-alert` `mx-global-alert--critical` | Site-wide alert banner |
|
|
229
|
+
| `mx-hero-banner` `mx-hero-banner--hero` | Hero banner (also used by HeroSearch) |
|
|
230
|
+
| `mx-in-page-navigation` | In-page TOC nav |
|
|
231
|
+
| `mx-link-list` | Link list |
|
|
232
|
+
| `mx-list-item` | List item (extends Card) |
|
|
233
|
+
| `mx-nav` | Base navigation |
|
|
234
|
+
| `mx-nav--breadcrumbs` `--collapsible` `--dropdown` `--mega-nav` `--inline` `--reverse` `--footer` `--open` | Navigation variants + state |
|
|
235
|
+
| `mx-pagination` | Pagination |
|
|
236
|
+
| `mx-popover` | Popover panel |
|
|
237
|
+
| `mx-progress-indicator` `__count` `__track` `__marker` `--done` `--now` `__steps` `__step` `--done` | Horizontal step-progress tracker for wizards/forms |
|
|
238
|
+
| `mx-results-bar` | Results count + sort bar |
|
|
239
|
+
| `mx-side-nav` | Secondary vertical nav |
|
|
240
|
+
| `mx-social-links` | Social profile links |
|
|
241
|
+
| `mx-social-share` | Share-to-social buttons |
|
|
242
|
+
| `mx-steps` `mx-steps--counters` `--fill` `--dark` `--supplementary` | Step indicator |
|
|
243
|
+
| `mx-sticky` `mx-sticky--m` `mx-sticky--l` | Sticky wrapper (breakpoint-gated) |
|
|
244
|
+
| `mx-tabs` `mx-tabs--lined` `mx-tabs--centered` | Tabs |
|
|
245
|
+
| `mx-tag` `mx-tags` `mx-tag--dismissible` | Tag + tag list. **No colour/outline variants exist** |
|
|
246
|
+
| `mx-translate` `__trigger` `__code` `__menu` `__item` `__notice` | Language switcher, drives Google's Website Translator |
|
|
247
|
+
| `mx-utility-list` | Utility link bar |
|
|
248
|
+
|
|
249
|
+
### Forms
|
|
250
|
+
|
|
251
|
+
| Class | Purpose |
|
|
252
|
+
| --------------------------------------------------------------------------- | ----------------------------------------------------- |
|
|
253
|
+
| `mx-autocomplete` `mx-autocomplete__listbox` `mx-autocomplete__option` | Editable combobox with a suggestion listbox |
|
|
254
|
+
| `mx-feedback-form` `__rating` `__option` `__secondary` `__error` `__reveal` | Yes/no feedback control with a revealed comment field |
|
|
255
|
+
| `mx-form-actions` `mx-form--inline-button` | Form actions row / inline button |
|
|
256
|
+
| `mx-form-item` `mx-form-item--inline` | Field group |
|
|
257
|
+
| `mx-fieldset` `mx-fieldset--inline` `mx-fieldset--plain` | Fieldset |
|
|
258
|
+
| `mx-legend` | Fieldset legend |
|
|
259
|
+
| `mx-label` `mx-label--inline` | Field label |
|
|
260
|
+
| `mx-input` `mx-input--icon` `mx-input--small` `mx-input--wide` | Text input |
|
|
261
|
+
| `mx-checkbox` `mx-radio` | Checkbox / radio |
|
|
262
|
+
| `mx-choice-card` `mx-choice-card__hint` `mx-choice-divider` | Card-style checkbox/radio + shared "or" divider |
|
|
263
|
+
| `mx-description` | Field helper text |
|
|
264
|
+
| `mx-required` | Required indicator |
|
|
265
|
+
| `mx-error-message` `mx-success-message` | Field status messages |
|
|
266
|
+
|
|
267
|
+
### Layout
|
|
268
|
+
|
|
269
|
+
| Class | Purpose |
|
|
270
|
+
| ------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
|
|
271
|
+
| `mx-page` `mx-page--full` `mx-page--feature` `mx-page--narrow` | Page grid wrapper + track widths |
|
|
272
|
+
| `mx-container` | Container-query context (**not** a width constraint) |
|
|
273
|
+
| `mx-section` | Page section |
|
|
274
|
+
| `mx-section--s` `--m` `--l` `--xl` | Section padding scale |
|
|
275
|
+
| `mx-section--top-s/-m/-l/-xl` `mx-section--bottom-s/-m/-l/-xl` | Directional section padding |
|
|
276
|
+
| `mx-section--flow` `--group` `--divider` `--full` `--feature` `--narrow` | Section modes / layout |
|
|
277
|
+
| `mx-section--has-background` | Legacy `:has()` fallback for containing background images (no padding) |
|
|
278
|
+
| `mx-grid` `mx-grid-item` | Grid wrapper + item |
|
|
279
|
+
| `mx-grid--cols-{bp}-{n}` | Column count per breakpoint (`bp` = xs/sm/md/lg/xl, `n` = 2/3/4) |
|
|
280
|
+
| `mx-grid--collapse` `--collapse-cols` `--collapse-rows` | Grid gap collapse |
|
|
281
|
+
| `mx-grid--sidebar` `--sidebar-rev` `--sidebar-rev-lg` | Sidebar grid variants |
|
|
282
|
+
| `mx-header` | Site header |
|
|
283
|
+
| `mx-masthead` | Top branding bar |
|
|
284
|
+
| `mx-footer` | Site footer |
|
|
285
|
+
| `mx-logo` | Logo |
|
|
286
|
+
| `mx-skip-links` | Skip-link container |
|
|
287
|
+
|
|
288
|
+
### Utilities
|
|
289
|
+
|
|
290
|
+
| Class | Purpose |
|
|
291
|
+
| ------------------------------------------------------------------ | --------------------------- |
|
|
292
|
+
| `mx-vertical-flow` `mx-vertical-flow-flex` `mx-vertical-flow-grid` | Vertical flow spacing |
|
|
293
|
+
| `mx-horizontal-flow-flex` | Horizontal flow spacing |
|
|
294
|
+
| `skeleton--bg` | Loading skeleton background |
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Composition grammar
|
|
299
|
+
|
|
300
|
+
The rules below live in CSS and are invisible to a consumer reading a README. **Follow them exactly.**
|
|
301
|
+
|
|
302
|
+
### Modifiers that require a colour partner
|
|
303
|
+
|
|
304
|
+
- `mx-button--outline` does **nothing on its own** — it only styles when combined with a colour modifier:
|
|
305
|
+
`mx-button--outline mx-button--dark` (also works with `--accent`, `--destructive`, `--white`). Outline + `--light`/`--secondary` has no effect.
|
|
306
|
+
|
|
307
|
+
### Backgrounds & full-bleed
|
|
308
|
+
|
|
309
|
+
`mx-page` **defines** a named column grid (`full` / `container` / `feature` / `narrow`) — see [Page layout](./src/Layout/Page/README.md). **Only a _direct grid child_ of `mx-page` can span the full-bleed width.** This is the most common invisible-rule bug: a background applied at the wrong nesting level silently fails to span.
|
|
310
|
+
|
|
311
|
+
- **Put `mx-background--*` on a section-level wrapper that is a direct child of `mx-page`** — not on inner content. When it is, that element spans `full` and inherits the parent's tracks as a **subgrid**, so its own children fall back to the `container` track automatically (the colour bleeds edge-to-edge while text stays aligned). Only these nested full-bleed children (and nested `mx-page` elements) become subgrids — the top-level `mx-page` is the grid definition itself, not a subgrid.
|
|
312
|
+
- **Add section padding** with a spacing modifier (`mx-section--m` / `--l` / etc.) — a coloured region with no padding looks broken. Padding comes from the spacing classes, _not_ from the background.
|
|
313
|
+
- **`mx-section--has-background`** is a legacy `:has()` fallback (for browsers without `:has()` support) that sets `overflow`/`position` so a background image is contained — it does **not** add padding. Modern browsers derive this from `:has(.mx-background--image)` automatically.
|
|
314
|
+
- **Exception:** `mx-background--box` is an inline, non-bleeding background (a boxed panel) — it does _not_ trigger the subgrid span and can sit on inner content.
|
|
315
|
+
|
|
316
|
+
Correct nesting:
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
mx-page
|
|
320
|
+
└─ mx-section mx-section--l mx-background--primary ← direct child, spans full-bleed (--l adds padding)
|
|
321
|
+
└─ content ← stays on the container track
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Wrong (background won't span — applied below the grid child):
|
|
325
|
+
|
|
326
|
+
```
|
|
327
|
+
mx-page
|
|
328
|
+
└─ mx-section
|
|
329
|
+
└─ div.mx-background--primary ← not a direct grid child; no full-bleed
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Card layout requires a container-query wrapper
|
|
333
|
+
|
|
334
|
+
`mx-card`'s two-column (media + content) layout is driven by **container queries**, not viewport breakpoints. It only activates when the card sits inside an element that establishes the `card` container context — in practice, wrap the card in `mx-container` (or place it as a direct child of `mx-grid`, which sets it up).
|
|
335
|
+
|
|
336
|
+
- ✅ `<div class="mx-container"><div class="mx-card">…</div></div>` → card can switch to side-by-side at wide container widths.
|
|
337
|
+
- ❌ A bare `mx-card` with no `mx-container` / `mx-grid` ancestor → stays stacked forever, regardless of available width. Same invisible-rule class as `mx-button--outline` without a colour: the class is correct but a required companion is missing.
|
|
338
|
+
|
|
339
|
+
### Modifiers that combine
|
|
340
|
+
|
|
341
|
+
- **Button:** one colour (`--dark`/`--light`/`--accent`/`--secondary`/`--destructive`/`--white`) + optionally `--outline` + optionally one size (`--small`/`--large`) + optionally `--full-width` or `--icon-only`.
|
|
342
|
+
- **Steps:** `mx-steps--counters` adds numbered counters; combine with a colour mode (`--dark`/`--supplementary`) and/or `--fill`.
|
|
343
|
+
- **Section:** a padding scale (`--s`/`--m`/`--l`/`--xl`) + optionally `--flow` or `--group`. For colour, add an `mx-background--*` class (the padding still comes from the scale class). `--has-background` is only the legacy `:has()` fallback, not part of this composition.
|
|
344
|
+
|
|
345
|
+
### Modifiers that do NOT exist (common false positives)
|
|
346
|
+
|
|
347
|
+
- ❌ `mx-button--primary` — use `mx-button--dark`
|
|
348
|
+
- ❌ `mx-section--primary` — use `mx-section` + `mx-background--primary`
|
|
349
|
+
- ❌ `mx-tag--accent`, `mx-tag--outline`, `mx-tag--primary` — Tag has **no colour or outline variants**; only `mx-tag--dismissible`
|
|
350
|
+
- ❌ `mx-hero__eyebrow` or any custom eyebrow class — use `mx-text--eyebrow`
|
|
351
|
+
- ❌ `mx-card--primary` / colour modifiers on Card — set a background via `mx-background--*` on the card or its section
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Anti-patterns — things that look right but aren't
|
|
356
|
+
|
|
357
|
+
- **`mx-button--outline` without a colour modifier.** Renders invisible. Always pair with a colour (see [Composition grammar](#composition-grammar)).
|
|
358
|
+
- **A `mx-background--*` region that doesn't bleed.** Almost always caused by applying it below the direct child of `mx-page` — see [Backgrounds & full-bleed](#backgrounds--full-bleed).
|
|
359
|
+
- **A `mx-card` stuck in stacked layout.** Missing the `mx-container` / `mx-grid` wrapper that provides its container-query context — see [Card layout requires a container-query wrapper](#card-layout-requires-a-container-query-wrapper).
|
|
360
|
+
|
|
361
|
+
> Reinventing classes that don't exist (`mx-button--primary`, custom eyebrow utilities, `--primary` colour modifiers, etc.) is covered in [Modifiers that do NOT exist](#modifiers-that-do-not-exist-common-false-positives) — don't do it.
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## What to use for X — cheatsheet
|
|
366
|
+
|
|
367
|
+
Common visual intents mapped to the idiomatic Mixtape class. Reach for these before inventing anything.
|
|
368
|
+
|
|
369
|
+
| I want… | Use |
|
|
370
|
+
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
371
|
+
| Small uppercase label above a heading (eyebrow) | `mx-text--eyebrow` (with underbar: `mx-text--embellished`) |
|
|
372
|
+
| A section with a brand-coloured background | `mx-section` + `mx-background--primary` |
|
|
373
|
+
| A bold call-to-action button on a light surface | `mx-button--dark` |
|
|
374
|
+
| A CTA button on a dark/reverse surface | `mx-button--white` |
|
|
375
|
+
| A secondary/outline button | `mx-button--outline` **+** a colour (e.g. `mx-button--dark`) |
|
|
376
|
+
| An accent-coloured button | `mx-button--accent` |
|
|
377
|
+
| A large display heading | `mx-headline` or `mx-heading--xl` / `--xxl` |
|
|
378
|
+
| Lead / intro paragraph | `mx-text--lede` |
|
|
379
|
+
| A responsive multi-column card grid | `mx-grid` + `mx-grid--cols-lg-3` (etc.) |
|
|
380
|
+
| A category label/badge | `mx-tag` (no colour variants — style via `--tag-*` tokens) |
|
|
381
|
+
| Constrain content width | Content inside `mx-page` sits in the `container` track (`76ch`) by default; use `mx-section--narrow` (`58ch`) for reading width, `mx-section--feature` / `mx-section--full` to widen. See [Page layout](./src/Layout/Page/README.md). `mx-container` is **not** a width constraint — it establishes a container-query context. |
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## Public token API
|
|
386
|
+
|
|
387
|
+
These CSS custom properties are the **intended override surface** — set them (scoped to a context class) to customise a component. They are recognisable in source by the `var(--token, fallback)` pattern and are marked `/* @public */` in the CSS. **Everything else (`--line-width`, `--counter-top`, `--font-min`, `--plus`/`--minus`, `--grid-repeat`, positioning tokens, etc.) is internal — do not override.**
|
|
388
|
+
|
|
389
|
+
### Button
|
|
390
|
+
|
|
391
|
+
| Property | Default | Intent |
|
|
392
|
+
| -------------------------------------------------------------------- | ---------------------------------------------- | -------------------------- |
|
|
393
|
+
| `--button-dark-bg` / `--button-dark-fg` / `--button-dark-line` | `--colour-link` / reverse fg / `--colour-link` | Dark button colours |
|
|
394
|
+
| `--button-accent-bg` / `--button-accent-fg` / `--button-accent-line` | accent / `--colour-foreground` / accent | Accent button colours |
|
|
395
|
+
| `--button-light-bg` / `--button-light-fg` / `--button-light-line` | transparent / link / transparent | Light button colours |
|
|
396
|
+
| `--button-accent-scheme` | `light` | Colour scheme for accent |
|
|
397
|
+
| `--button-font-size` | inherited | Button text size |
|
|
398
|
+
| `--button-gap` | `--spacing-s` | Gap between button content |
|
|
399
|
+
| `--button-min-height` | — | Minimum height |
|
|
400
|
+
|
|
401
|
+
### Tag
|
|
402
|
+
|
|
403
|
+
| Property | Default | Intent |
|
|
404
|
+
| ------------------ | --------------------- | ---------------- |
|
|
405
|
+
| `--tag-background` | `--colour-background` | Tag fill |
|
|
406
|
+
| `--tag-foreground` | `--colour-foreground` | Tag text |
|
|
407
|
+
| `--tag-font-size` | `--font-size-xs` | Tag text size |
|
|
408
|
+
| `--tags-gap` | `--spacing-s` | Gap between tags |
|
|
409
|
+
|
|
410
|
+
### Card
|
|
411
|
+
|
|
412
|
+
| Property | Default | Intent |
|
|
413
|
+
| ------------------ | --------- | --------------------------- |
|
|
414
|
+
| `--card-gap` | `--gap` | Gap between card regions |
|
|
415
|
+
| `--card-alignment` | `stretch` | Cross-axis alignment |
|
|
416
|
+
| `--large-card-gap` | `6rem` | Gap for large/feature cards |
|
|
417
|
+
|
|
418
|
+
### Alert (GlobalAlert / InPageAlert)
|
|
419
|
+
|
|
420
|
+
| Property | Default | Intent |
|
|
421
|
+
| -------------------- | ------------------------ | ------------- |
|
|
422
|
+
| `--alert-background` | `--colour-primary-light` | Alert fill |
|
|
423
|
+
| `--alert-foreground` | `--colour-foreground` | Alert text |
|
|
424
|
+
| `--alert-scheme` | `light` | Colour scheme |
|
|
425
|
+
|
|
426
|
+
### HeroBanner / HeroSearch
|
|
427
|
+
|
|
428
|
+
| Property | Default | Intent |
|
|
429
|
+
| --------------------- | ----------------- | ------------------- |
|
|
430
|
+
| `--hero-height` | `600px` | Minimum hero height |
|
|
431
|
+
| `--hero-columns` | `50% 50%` | Content/aside split |
|
|
432
|
+
| `--hero-align` | `center` | Vertical alignment |
|
|
433
|
+
| `--hero-image-radius` | `--border-radius` | Aside image radius |
|
|
434
|
+
|
|
435
|
+
### Popover
|
|
436
|
+
|
|
437
|
+
| Property | Default | Intent |
|
|
438
|
+
| ---------------------- | --------------------- | ------------- |
|
|
439
|
+
| `--popover-padding` | `--spacing-xs` | Inner padding |
|
|
440
|
+
| `--popover-background` | `--colour-background` | Fill |
|
|
441
|
+
| `--popover-foreground` | `--colour-foreground` | Text |
|
|
442
|
+
| `--popover-radius` | `--border-radius` | Corner radius |
|
|
443
|
+
| `--popover-width` | `30ch` | Max width |
|
|
444
|
+
|
|
445
|
+
### Section
|
|
446
|
+
|
|
447
|
+
| Property | Default | Intent |
|
|
448
|
+
| -------------------------------------------------------------- | ------------- | --------------------------------- |
|
|
449
|
+
| `--section-s` / `--section-m` / `--section-l` / `--section-xl` | spacing scale | Per-size section padding override |
|
|
450
|
+
|
|
451
|
+
### Lines & borders (global)
|
|
452
|
+
|
|
453
|
+
Cross-cutting tokens used by borders, dividers, underlines, and focus outlines across many components (forms, buttons, tags, popover, etc.). Scope them to a context class to restyle lines in bulk, or override per-component.
|
|
454
|
+
|
|
455
|
+
| Property | Default (per component) | Intent |
|
|
456
|
+
| --------------- | ---------------------------------------- | ----------------------- |
|
|
457
|
+
| `--line-width` | `2px` (forms/buttons), `1px` (tags/etc.) | Border / line thickness |
|
|
458
|
+
| `--line-colour` | `--colour-border` (varies per component) | Border / line colour |
|
|
459
|
+
|
|
460
|
+
> Global tokens (`--colour-*`, `--font-size-*`, `--spacing-*`, `--gap*`, `--border-radius*`, `--box-shadow`, breakpoints) documented in [Design Tokens](#design-tokens) above are also public and overridable.
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
## Component Modifiers (from `@pnx-mixtape/ids-shape`)
|
|
465
|
+
|
|
466
|
+
> Modifier enums live in [`@pnx-mixtape/ids-shape`](https://www.npmjs.com/package/@pnx-mixtape/ids-shape).
|
|
467
|
+
> Full API reference: [TypeDoc-generated docs](https://unpkg.com/@pnx-mixtape/ids-shape/docs/index.html)
|
|
468
|
+
|
|
469
|
+
→ See individual README.md files (eg. src/Atom/Button/README.md) for full modifier reference, React props, and CSS custom property overrides.
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
## Component Inventory
|
|
474
|
+
|
|
475
|
+
> This lists components by name with descriptions. For the exhaustive list of every CSS **class**, see [Canonical class inventory](#canonical-class-inventory) above.
|
|
476
|
+
|
|
477
|
+
### Atoms (`src/Atom/`)
|
|
478
|
+
|
|
479
|
+
Smallest, single-purpose elements. Always use these as building blocks; never reproduce their styles.
|
|
480
|
+
|
|
481
|
+
| Component | Description |
|
|
482
|
+
| ---------------- | --------------------------------------------------------------- |
|
|
483
|
+
| `Background` | Coloured background regions with scheme switching |
|
|
484
|
+
| `Blockquote` | Styled `<blockquote>` for pull quotes |
|
|
485
|
+
| `Button` | All button and button-link variants |
|
|
486
|
+
| `DefinitionList` | Styled `<dl>` for key/value pairs |
|
|
487
|
+
| `Heading` | Typographic headings (h1–h6) with size/weight modifiers |
|
|
488
|
+
| `Icon` | SVG icon via CSS mask-image, sized with `--icon-size` |
|
|
489
|
+
| `Image` | Responsive image wrapper with ratio control |
|
|
490
|
+
| `InlineSvg` | Inline SVG component |
|
|
491
|
+
| `Link` | Base anchor with hover/focus styles |
|
|
492
|
+
| `LinkedImage` | Image wrapped in a link |
|
|
493
|
+
| `List` | Styled `<ul>`/`<ol>` with notes, references, and stats variants |
|
|
494
|
+
| `Media` | Generic media container (images, video) |
|
|
495
|
+
| `Spacing` | Whitespace utility component |
|
|
496
|
+
| `Table` | Accessible, responsive table |
|
|
497
|
+
| `Text` | Body text wrapper |
|
|
498
|
+
| `Video` | Video embed with aspect ratio |
|
|
499
|
+
|
|
500
|
+
### Components (`src/Component/`)
|
|
501
|
+
|
|
502
|
+
Composed from Atoms. Have their own interaction behaviour.
|
|
503
|
+
|
|
504
|
+
| Component | Description |
|
|
505
|
+
| ------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
506
|
+
| `Accordion` | Collapsible content panels (Web Component: `<mx-accordion>`) |
|
|
507
|
+
| `BackToTop` | Trigger that appears after a scroll threshold and jumps back to a target element (Web Component: `<mx-back-to-top>`) |
|
|
508
|
+
| `Breadcrumb` | Hierarchical navigation trail |
|
|
509
|
+
| `Callout` | Highlighted aside/tip block |
|
|
510
|
+
| `Card` | Content card with image, title, body, and actions |
|
|
511
|
+
| `Carousel` | Scrollable item carousel |
|
|
512
|
+
| `ContentBlock` | Rich text content region |
|
|
513
|
+
| `CookieConsent` | Site-wide cookie consent banner, fixed to viewport bottom |
|
|
514
|
+
| `Dialog` | Modal dialog (Web Component) |
|
|
515
|
+
| `DropMenu` | Dropdown navigation menu |
|
|
516
|
+
| `Filters` | Filter controls for listing pages |
|
|
517
|
+
| `Gallery` | Image preview that opens a fullscreen carousel modal |
|
|
518
|
+
| `GlobalAlert` | Site-wide dismissible alert banner |
|
|
519
|
+
| `HeroBanner` | Full-width hero with image and headline |
|
|
520
|
+
| `HeroSearch` | Hero with integrated search input |
|
|
521
|
+
| `InPageAlert` | Inline status alert (info/success/warning/error) |
|
|
522
|
+
| `InPageNavigation` | Anchor-link navigation for long pages |
|
|
523
|
+
| `LinkList` | Vertical or horizontal list of links |
|
|
524
|
+
| `ListItem` | Single item within a list context |
|
|
525
|
+
| `Navigation` | Primary site navigation |
|
|
526
|
+
| `Pagination` | Page navigation controls |
|
|
527
|
+
| `Popover` | Floating contextual content panel |
|
|
528
|
+
| `ProgressIndicator` | Horizontal step-progress tracker for multi-step forms/wizards |
|
|
529
|
+
| `ResultsBar` | Shows result count and sort controls |
|
|
530
|
+
| `SideNavigation` | Secondary vertical navigation |
|
|
531
|
+
| `SocialLinks` | Links to social media profiles |
|
|
532
|
+
| `SocialShare` | Share-to-social buttons |
|
|
533
|
+
| `Steps` | Numbered step indicator |
|
|
534
|
+
| `Sticky` | Sticky-positioned wrapper |
|
|
535
|
+
| `Tabs` | Tab panel navigation |
|
|
536
|
+
| `Tag` | Label/badge for categorisation |
|
|
537
|
+
| `Translate` | Language switcher that drives Google's Website Translator widget, built on DropMenu |
|
|
538
|
+
| `UtilityList` | Utility link bar |
|
|
539
|
+
|
|
540
|
+
### Forms (`src/Form/`)
|
|
541
|
+
|
|
542
|
+
| Component | Description |
|
|
543
|
+
| -------------- | -------------------------------------------------------------------------------------------- |
|
|
544
|
+
| `Autocomplete` | Editable combobox with a suggestion listbox |
|
|
545
|
+
| `Checkbox` | Styled checkbox input |
|
|
546
|
+
| `CheckboxCard` | Card-style checkbox with a larger tap target |
|
|
547
|
+
| `Description` | Helper/hint text for form fields |
|
|
548
|
+
| `FeedbackForm` | Yes/no feedback control that reveals a comment field, with a submit contract for any backend |
|
|
549
|
+
| `Form` | Form wrapper with spacing |
|
|
550
|
+
| `FormItem` | Field group (label + input + description + error) |
|
|
551
|
+
| `Label` | Form field label |
|
|
552
|
+
| `Radio` | Styled radio input |
|
|
553
|
+
| `RadioCard` | Card-style radio with a larger tap target |
|
|
554
|
+
| `Search` | Search input with button |
|
|
555
|
+
| `Select` | Styled `<select>` dropdown |
|
|
556
|
+
| `Textarea` | Styled `<textarea>` |
|
|
557
|
+
| `TextInput` | Styled text `<input>` |
|
|
558
|
+
|
|
559
|
+
### Layout (`src/Layout/`)
|
|
560
|
+
|
|
561
|
+
| Component | Description |
|
|
562
|
+
| ---------- | ------------------------- |
|
|
563
|
+
| `Footer` | Site footer |
|
|
564
|
+
| `Grid` | CSS grid layout wrapper |
|
|
565
|
+
| `Header` | Site header |
|
|
566
|
+
| `Masthead` | Top-of-page branding bar |
|
|
567
|
+
| `Page` | Full page layout wrapper |
|
|
568
|
+
| `Section` | Page section with spacing |
|
|
569
|
+
| `Sidebar` | Two-column sidebar layout |
|
|
570
|
+
|
|
571
|
+
### Utilities (`src/Utility/`)
|
|
572
|
+
|
|
573
|
+
Utility classes, hooks, and context providers. Includes print styles, layout utilities, Drupal-specific helpers, and React hooks.
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
## React & Web Component Usage
|
|
578
|
+
|
|
579
|
+
→ See [`docs/ComponentArchitecture.md`](./docs/ComponentArchitecture.md) for full patterns.
|
|
580
|
+
|
|
581
|
+
React components are exported from `src/react.ts`. Web Components auto-register on import and use the `mx-` custom element prefix (e.g. `<mx-accordion>`).
|
|
582
|
+
|
|
583
|
+
---
|
|
584
|
+
|
|
585
|
+
## Accessibility
|
|
586
|
+
|
|
587
|
+
→ WCAG 2.0 AA compliant. See [`docs/CSSGuidelines.md`](./docs/CSSGuidelines.md) for media query hooks (`--use-motion`, `--high-contrast`, etc.) and [`docs/ComponentArchitecture.md`](./docs/ComponentArchitecture.md) for ARIA patterns.
|
|
588
|
+
|
|
589
|
+
---
|
|
590
|
+
|
|
591
|
+
## Overriding Styles
|
|
592
|
+
|
|
593
|
+
→ See [`docs/CSSGuidelines.md`](./docs/CSSGuidelines.md) for the full override guide.
|
|
594
|
+
|
|
595
|
+
**Short version:** prefer CSS custom property overrides scoped to a context class. Unlayered CSS wins globally without needing `!important`.
|
package/README.md
CHANGED
|
@@ -222,8 +222,7 @@ Mixtape uses [@layers](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer)
|
|
|
222
222
|
@import "@pnx-mixtape/mxds/src/Atom/base.css";
|
|
223
223
|
|
|
224
224
|
/* Or manually define layer order */
|
|
225
|
-
@layer design-system.defaults, design-system.atoms, design-system.layout,
|
|
226
|
-
design-system.components, design-system.utilities;
|
|
225
|
+
@layer design-system.defaults, design-system.atoms, design-system.layout, design-system.components, design-system.utilities;
|
|
227
226
|
|
|
228
227
|
/* Your unlayered CSS automatically overrides design system */
|
|
229
228
|
.mx-button {
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
import"./chunks/Accordion-
|
|
1
|
+
import "./chunks/Accordion-D2wp8hBG.js";
|
|
2
|
+
import "./chunks/AccordionGroup-BYtoAFxg.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./chunks/Autocomplete-
|
|
1
|
+
import "./chunks/Autocomplete-kRo8RNbC.js";
|