@pnx-mixtape/mxds 0.1.0-rc.1 → 0.1.0-rc.2

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.
Files changed (198) hide show
  1. package/.storybook/decorators.ts +15 -0
  2. package/.storybook/preview.ts +4 -1
  3. package/.storybook/themes/campus-vibrant.css +181 -0
  4. package/.storybook/themes/civic-formal.css +246 -0
  5. package/.storybook/{theme-demo.css → themes/demo.css} +14 -7
  6. package/.storybook/themes/health-services.css +255 -0
  7. package/.storybook/themes/research-faculty.css +169 -0
  8. package/dist/build/accordion.css +1 -1
  9. package/dist/build/base.css +1 -1
  10. package/dist/build/button.css +1 -1
  11. package/dist/build/chunks/DropMenu-1baQc8Yc.js +1 -0
  12. package/dist/build/chunks/InPageNavigation-CVieEl9u.js +1 -0
  13. package/dist/build/chunks/Popover-Cxg-s5Jn.js +1 -0
  14. package/dist/build/chunks/Sticky-cWUVSOXN.js +1 -0
  15. package/dist/build/chunks/{Tabs-Dm8g301e.js → Tabs-DA_Ez8pv.js} +2 -2
  16. package/dist/build/chunks/polyfills-C7pRt54M.js +1 -0
  17. package/dist/build/constants.css +1 -1
  18. package/dist/build/drop-menu.entry.js +1 -1
  19. package/dist/build/elements.js +1 -1
  20. package/dist/build/form.css +1 -1
  21. package/dist/build/grid.css +1 -1
  22. package/dist/build/in-page-alert.css +1 -1
  23. package/dist/build/in-page-navigation.entry.js +1 -1
  24. package/dist/build/navigation.css +1 -1
  25. package/dist/build/popover.entry.js +1 -1
  26. package/dist/build/print.css +1 -1
  27. package/dist/build/progress-indicator.css +1 -0
  28. package/dist/build/react.js +1 -1
  29. package/dist/build/sidebar.css +1 -1
  30. package/dist/build/sticky.entry.js +1 -1
  31. package/dist/build/tabs.entry.js +1 -1
  32. package/dist/build/tag.css +1 -1
  33. package/dist/build/utilities.css +1 -1
  34. package/dist/types/Atom/DefinitionList/DefinitionList.d.ts +3 -2
  35. package/dist/types/Atom/DefinitionList/DefinitionList.d.ts.map +1 -1
  36. package/dist/types/Atom/Heading/Heading.d.ts.map +1 -1
  37. package/dist/types/Atom/List/List.d.ts +10 -0
  38. package/dist/types/Atom/List/List.d.ts.map +1 -0
  39. package/dist/types/Component/DropMenu/Elements/DropMenu.d.ts.map +1 -1
  40. package/dist/types/Component/InPageNavigation/Elements/InPageNavigation.d.ts +2 -2
  41. package/dist/types/Component/InPageNavigation/Elements/InPageNavigation.d.ts.map +1 -1
  42. package/dist/types/Component/InPageNavigation/Hooks/useInPageNavigation.d.ts.map +1 -1
  43. package/dist/types/Component/ProgressIndicator/ProgressIndicator.d.ts +9 -0
  44. package/dist/types/Component/ProgressIndicator/ProgressIndicator.d.ts.map +1 -0
  45. package/dist/types/Component/Tabs/Elements/Tabs.d.ts.map +1 -1
  46. package/dist/types/Component/Tag/Tag.d.ts +4 -2
  47. package/dist/types/Component/Tag/Tag.d.ts.map +1 -1
  48. package/dist/types/Form/Autocomplete/Autocomplete.d.ts.map +1 -1
  49. package/dist/types/Form/Checkbox/FormCheckbox.d.ts.map +1 -1
  50. package/dist/types/Form/CheckboxCard/CheckboxCard.d.ts +23 -0
  51. package/dist/types/Form/CheckboxCard/CheckboxCard.d.ts.map +1 -0
  52. package/dist/types/Form/Radio/FormRadio.d.ts.map +1 -1
  53. package/dist/types/Form/RadioCard/RadioCard.d.ts +16 -0
  54. package/dist/types/Form/RadioCard/RadioCard.d.ts.map +1 -0
  55. package/dist/types/Form/Select/FormSelect.d.ts.map +1 -1
  56. package/dist/types/Form/TextInput/FormText.d.ts.map +1 -1
  57. package/dist/types/Form/Textarea/FormTextarea.d.ts.map +1 -1
  58. package/dist/types/enums.d.ts +15 -0
  59. package/dist/types/enums.d.ts.map +1 -1
  60. package/dist/types/react.d.ts +4 -0
  61. package/dist/types/react.d.ts.map +1 -1
  62. package/package.json +7 -7
  63. package/src/Atom/Background/_background.css +2 -2
  64. package/src/Atom/Blockquote/_blockquote.css +9 -2
  65. package/src/Atom/Button/README.md +1 -0
  66. package/src/Atom/Button/_buttons-styles.css +6 -6
  67. package/src/Atom/Button/_buttons.css +5 -3
  68. package/src/Atom/DefinitionList/DefinitionList.stories.ts +39 -2
  69. package/src/Atom/DefinitionList/DefinitionList.stories.tsx +36 -0
  70. package/src/Atom/DefinitionList/DefinitionList.tsx +4 -1
  71. package/src/Atom/DefinitionList/DefinitionListItem.stories.ts +1 -1
  72. package/src/Atom/DefinitionList/README.md +43 -0
  73. package/src/Atom/DefinitionList/__snapshots__/DefinitionList.stories.ts.snap +37 -3
  74. package/src/Atom/DefinitionList/__snapshots__/DefinitionList.stories.tsx.snap +2 -0
  75. package/src/Atom/DefinitionList/__snapshots__/DefinitionListItem.stories.ts.snap +3 -3
  76. package/src/Atom/DefinitionList/definition-list-item.twig +1 -0
  77. package/src/Atom/DefinitionList/definition-list.twig +6 -1
  78. package/src/Atom/Heading/Heading.tsx +6 -0
  79. package/src/Atom/Heading/_headings.css +2 -1
  80. package/src/Atom/Icon/_extended-set.css +30 -30
  81. package/src/Atom/Icon/_icon.css +36 -36
  82. package/src/Atom/Image/README.md +2 -2
  83. package/src/Atom/Image/_image.css +12 -6
  84. package/src/Atom/List/List.stories.ts +102 -0
  85. package/src/Atom/List/List.stories.tsx +103 -0
  86. package/src/Atom/List/List.tsx +22 -0
  87. package/src/Atom/List/README.md +150 -0
  88. package/src/Atom/List/__snapshots__/List.stories.ts.snap +43 -0
  89. package/src/Atom/List/__snapshots__/List.stories.tsx.snap +13 -0
  90. package/src/Atom/List/_list.css +123 -0
  91. package/src/Atom/List/list.twig +5 -0
  92. package/src/Atom/Media/Media.stories.ts +1 -1
  93. package/src/Atom/Media/__snapshots__/Media.stories.ts.snap +2 -2
  94. package/src/Atom/Spacing/_spacing.css +24 -24
  95. package/src/Atom/Table/__snapshots__/Table.stories.ts.snap +24 -4
  96. package/src/Atom/Table/_table.css +15 -3
  97. package/src/Atom/Table/table.twig +6 -1
  98. package/src/Atom/Text/__snapshots__/Text.stories.ts.snap +3 -2
  99. package/src/Atom/Text/_text-styles.css +21 -1
  100. package/src/Atom/Text/twig/text-styles-example.twig +3 -2
  101. package/src/Atom/_base.css +6 -0
  102. package/src/Atom/_flow.css +1 -1
  103. package/src/Atom/_generic.css +18 -11
  104. package/src/Component/Accordion/accordion.css +2 -0
  105. package/src/Component/Card/__snapshots__/Card.stories.ts.snap +2 -2
  106. package/src/Component/Card/card.twig +1 -1
  107. package/src/Component/Carousel/Carousel.stories.ts +46 -23
  108. package/src/Component/DropMenu/Elements/DropMenu.ts +10 -1
  109. package/src/Component/InPageAlert/in-page-alert.css +2 -1
  110. package/src/Component/InPageNavigation/Elements/InPageNavigation.ts +10 -5
  111. package/src/Component/InPageNavigation/Hooks/useInPageNavigation.ts +10 -5
  112. package/src/Component/InPageNavigation/InPageNavigation.stories.ts +33 -0
  113. package/src/Component/InPageNavigation/InPageNavigation.stories.tsx +52 -0
  114. package/src/Component/InPageNavigation/__snapshots__/InPageNavigation.stories.ts.snap +26 -0
  115. package/src/Component/InPageNavigation/__snapshots__/InPageNavigation.stories.tsx.snap +2 -0
  116. package/src/Component/InPageNavigation/twig/content-example-duplicate-headings.twig +20 -0
  117. package/src/Component/InPageNavigation/twig/in-page-navigation-story-duplicate-headings.twig +2 -0
  118. package/src/Component/ListItem/__snapshots__/ListItem.stories.ts.snap +4 -4
  119. package/src/Component/ListItem/list-item.twig +2 -2
  120. package/src/Component/Navigation/_navigation.css +1 -1
  121. package/src/Component/Pagination/Pagination.stories.ts +8 -4
  122. package/src/Component/Pagination/pagination.css +2 -2
  123. package/src/Component/ProgressIndicator/ProgressIndicator.stories.ts +36 -0
  124. package/src/Component/ProgressIndicator/ProgressIndicator.stories.tsx +30 -0
  125. package/src/Component/ProgressIndicator/ProgressIndicator.tsx +60 -0
  126. package/src/Component/ProgressIndicator/README.md +111 -0
  127. package/src/Component/ProgressIndicator/__snapshots__/ProgressIndicator.stories.ts.snap +67 -0
  128. package/src/Component/ProgressIndicator/__snapshots__/ProgressIndicator.stories.tsx.snap +7 -0
  129. package/src/Component/ProgressIndicator/progress-indicator.css +59 -0
  130. package/src/Component/ProgressIndicator/progress-indicator.twig +22 -0
  131. package/src/Component/Sticky/Elements/Sticky.ts +1 -1
  132. package/src/Component/Sticky/sticky.css +3 -3
  133. package/src/Component/Tabs/Elements/Tabs.ts +3 -1
  134. package/src/Component/Tabs/Tabs.stories.ts +55 -21
  135. package/src/Component/Tabs/__snapshots__/Tabs.stories.ts.snap +2 -2
  136. package/src/Component/Tag/README.md +52 -26
  137. package/src/Component/Tag/Tag.stories.tsx +24 -0
  138. package/src/Component/Tag/Tag.tsx +12 -2
  139. package/src/Component/Tag/TagItem.stories.ts +25 -0
  140. package/src/Component/Tag/__snapshots__/Tag.stories.ts.snap +2 -2
  141. package/src/Component/Tag/__snapshots__/Tag.stories.tsx.snap +2 -0
  142. package/src/Component/Tag/tag-item.twig +2 -2
  143. package/src/Component/Tag/tag.css +76 -2
  144. package/src/Form/Autocomplete/Autocomplete.stories.ts +8 -3
  145. package/src/Form/Autocomplete/Autocomplete.tsx +1 -4
  146. package/src/Form/Autocomplete/README.md +26 -26
  147. package/src/Form/Autocomplete/__snapshots__/Autocomplete.stories.ts.snap +1 -1
  148. package/src/Form/Autocomplete/__snapshots__/Autocomplete.stories.tsx.snap +1 -1
  149. package/src/Form/Autocomplete/autocomplete.twig +0 -2
  150. package/src/Form/Checkbox/FormCheckbox.tsx +2 -8
  151. package/src/Form/Checkbox/README.md +23 -18
  152. package/src/Form/Checkbox/input-checkbox.twig +0 -2
  153. package/src/Form/CheckboxCard/CheckboxCard.stories.ts +90 -0
  154. package/src/Form/CheckboxCard/CheckboxCard.stories.tsx +43 -0
  155. package/src/Form/CheckboxCard/CheckboxCard.tsx +102 -0
  156. package/src/Form/CheckboxCard/README.md +163 -0
  157. package/src/Form/CheckboxCard/__snapshots__/CheckboxCard.stories.ts.snap +63 -0
  158. package/src/Form/CheckboxCard/__snapshots__/CheckboxCard.stories.tsx.snap +7 -0
  159. package/src/Form/CheckboxCard/checkbox-card.twig +29 -0
  160. package/src/Form/FormItem/__snapshots__/FormItem.stories.ts.snap +2 -2
  161. package/src/Form/README.md +65 -13
  162. package/src/Form/Radio/FormRadio.tsx +1 -4
  163. package/src/Form/Radio/input-radio.twig +0 -2
  164. package/src/Form/RadioCard/README.md +146 -0
  165. package/src/Form/RadioCard/RadioCard.stories.ts +95 -0
  166. package/src/Form/RadioCard/RadioCard.stories.tsx +26 -0
  167. package/src/Form/RadioCard/RadioCard.tsx +59 -0
  168. package/src/Form/RadioCard/__snapshots__/RadioCard.stories.ts.snap +69 -0
  169. package/src/Form/RadioCard/__snapshots__/RadioCard.stories.tsx.snap +3 -0
  170. package/src/Form/RadioCard/radio-card.twig +20 -0
  171. package/src/Form/Select/FormSelect.tsx +1 -4
  172. package/src/Form/Select/input-select.twig +0 -2
  173. package/src/Form/TextInput/FormText.stories.tsx +14 -0
  174. package/src/Form/TextInput/FormText.tsx +1 -4
  175. package/src/Form/TextInput/__snapshots__/FormText.stories.tsx.snap +2 -0
  176. package/src/Form/TextInput/input-text.twig +0 -2
  177. package/src/Form/Textarea/FormTextarea.tsx +1 -4
  178. package/src/Form/Textarea/input-textarea.twig +0 -2
  179. package/src/Form/Validation.stories.ts +153 -0
  180. package/src/Form/__snapshots__/Validation.stories.ts.snap +130 -0
  181. package/src/Form/form.css +155 -28
  182. package/src/Layout/Grid/grid.css +4 -4
  183. package/src/Layout/Sidebar/__snapshots__/Sidebar.stories.ts.snap +5 -5
  184. package/src/Layout/Sidebar/sidebar.css +1 -0
  185. package/src/Layout/Sidebar/sidebar.twig +1 -1
  186. package/src/Utility/_layout-utils.css +8 -0
  187. package/src/Utility/print.css +50 -28
  188. package/src/Utility/utilities.css +2 -2
  189. package/src/constants.css +12 -2
  190. package/src/enums.ts +17 -0
  191. package/src/react.ts +4 -0
  192. package/tools/lib/extract-classnames.mjs +0 -0
  193. package/tools/lint-classnames.mjs +1 -1
  194. package/dist/build/chunks/DropMenu-Co9jZZ4S.js +0 -1
  195. package/dist/build/chunks/InPageNavigation-CzR_KZaz.js +0 -1
  196. package/dist/build/chunks/Popover-De_CQqcd.js +0 -1
  197. package/dist/build/chunks/Sticky-Kyjykb36.js +0 -1
  198. package/dist/build/chunks/polyfills-Dokbkxxk.js +0 -1
@@ -3,5 +3,20 @@ import { Decorator } from "@storybook/html-vite"
3
3
 
4
4
  export const Page: Decorator = (story, { globals }) => {
5
5
  const { background } = globals
6
+ if (background === "theme--demo") {
7
+ import("./themes/demo.css")
8
+ }
9
+ if (background === "theme--civic-formal") {
10
+ import("./themes/civic-formal.css")
11
+ }
12
+ if (background === "theme--health-services") {
13
+ import("./themes/health-services.css")
14
+ }
15
+ if (background === "theme--research-faculty") {
16
+ import("./themes/research-faculty.css")
17
+ }
18
+ if (background === "theme--campus-vibrant") {
19
+ import("./themes/campus-vibrant.css")
20
+ }
6
21
  return `<div class="mx-page ${background}" data-testid="page">${story()}</div>`
7
22
  }
@@ -11,7 +11,6 @@ import "../src/Atom/Icon/icon.css"
11
11
  import "../src/Atom/Button/button.css"
12
12
  import "../src/Form/form.css"
13
13
  import "../src/Component/Navigation/navigation.css"
14
- import "./theme-demo.css"
15
14
  import { Page } from "./decorators"
16
15
 
17
16
  const preview: Preview = {
@@ -59,6 +58,10 @@ const preview: Preview = {
59
58
  "mx-background--primary",
60
59
  "mx-background--accent",
61
60
  "theme--demo",
61
+ "theme--campus-vibrant",
62
+ "theme--research-faculty",
63
+ "theme--civic-formal",
64
+ "theme--health-services",
62
65
  ],
63
66
  },
64
67
  },
@@ -0,0 +1,181 @@
1
+ /* Campus Vibrant — Mixtape theme
2
+ * Persona: undergraduate-facing higher ed (open days, course marketing).
3
+ * Part 1 is token overrides only. Part 2 is a small unlayered personality
4
+ * layer (shapes, motion, card lift) — unlayered CSS beats every design-system
5
+ * layer without !important, so no component internals are touched.
6
+ */
7
+
8
+ @import "https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,500;0,700;0,800;1,600&family=Public+Sans:ital,wght@0,400;0,600;0,700;1,400&display=swap";
9
+
10
+ .theme--campus-vibrant {
11
+ /* Colour. Every primary/accent shade in the system is color-mix()'d off
12
+ these two, so the whole palette moves with them. */
13
+ --colour-primary: #a02000;
14
+ --colour-accent: #fcafda;
15
+ --colour-primary-light: color-mix(in oklch, var(--colour-primary), white 90%);
16
+ --colour-primary-lighter: color-mix(in oklch, var(--colour-primary), white 20%);
17
+ --colour-primary-darker: color-mix(in oklch, var(--colour-primary), black 20%);
18
+ --colour-primary-dark: color-mix(in oklch, var(--colour-primary), black 40%);
19
+ --colour-primary-darkest: color-mix(in oklch, var(--colour-primary), black 50%);
20
+ --colour-accent-light: color-mix(in oklch, var(--colour-accent), white 90%);
21
+ --colour-accent-lighter: color-mix(in oklch, var(--colour-accent), white 20%);
22
+ --colour-accent-darker: color-mix(in oklch, var(--colour-accent), black 10%);
23
+ --colour-accent-dark: color-mix(in oklch, var(--colour-accent), black 40%);
24
+ --colour-accent-darkest: color-mix(in oklch, var(--colour-accent), black 50%);
25
+
26
+ --colour-foreground: light-dark(#1a1014, #fff);
27
+ --colour-foreground-alt: light-dark(#6b4a44, #f0d6c6);
28
+ --colour-background: light-dark(#fff, #1a1014);
29
+ --colour-background-alt: light-dark(#fff4ec, #6b4a44);
30
+ --colour-border: light-dark(#f0d6c6, #6b4a44);
31
+ --colour-link: light-dark(var(--colour-primary), #f0d6c6);
32
+ --colour-foreground-reverse: light-dark(#fff, #1a1014);
33
+ --colour-background-reverse: light-dark(#1a1014, #fff);
34
+ --_colour-outline: light-dark(#b3280a, #f0d6c6);
35
+
36
+ /* Type: high-contrast serif display over a workhorse sans. */
37
+ --font-family: "Public Sans", system-ui, sans-serif;
38
+ --font-family-display: "Playfair Display", georgia, serif;
39
+ --type-ratio: 1.5;
40
+ --font-size: var(--base-font-size);
41
+ --font-size-xs: calc(var(--base-font-size) * pow(var(--type-ratio), -0.5));
42
+ --font-size-s: calc(var(--base-font-size) * pow(var(--type-ratio), -0.25));
43
+ --font-size-m: 1rem;
44
+ --font-size-ml: calc(var(--base-font-size) * pow(var(--type-ratio), 0.5));
45
+ --font-size-l: calc(var(--base-font-size) * pow(var(--type-ratio), 1));
46
+ --font-size-xl: calc(var(--base-font-size) * pow(var(--type-ratio), 2));
47
+ --font-size-xxl: calc(var(--base-font-size) * pow(var(--type-ratio), 3));
48
+ --font-size-xxxl: calc(var(--base-font-size) * pow(var(--type-ratio), 4));
49
+
50
+ /* Shape */
51
+ --border-radius: 1rem;
52
+ --border-radius-l: 2.5rem;
53
+ --hero-image-radius: 2rem;
54
+ --popover-radius: 1rem;
55
+ --container-max-width: 90ch;
56
+ --container-max-width-narrow: 50rem;
57
+ --section-xl: 7rem;
58
+
59
+ /* Depth and motion */
60
+ --shadow-color: #1a101426;
61
+ --shadow-size: 1.25em;
62
+ --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
63
+
64
+ /* Component-level warmth */
65
+ --tag-background: #ff9bd2;
66
+ --tag-foreground: #1a1014;
67
+ --tag-font-size: var(--font-size-s);
68
+ --icon-size: 1rem;
69
+ --alert-background: var(--colour-accent-light);
70
+ --button-font-size: var(--font-size-m);
71
+ --card-gap: var(--gap-l);
72
+
73
+ font-family: var(--font-family);
74
+ font-size: var(--font-size);
75
+ line-height: var(--line-height);
76
+
77
+ /* Display type. Serif headings, tight and optically sized; body stays sans. */
78
+
79
+ & :is(h1, h2, h3) {
80
+ --line-height-h: 1.04;
81
+ --heading-letter-spacing: -0.02em;
82
+
83
+ text-wrap: balance;
84
+ }
85
+
86
+ & :is(h4, h5, h6) {
87
+ --heading-font-family: var(--font-family);
88
+ --heading-letter-spacing: -0.01em;
89
+ }
90
+
91
+ & .mx-text--lede {
92
+ --font-size: var(--font-size-ml);
93
+ }
94
+
95
+ /* Pill buttons with a physical press. */
96
+
97
+ & .mx-button {
98
+ --radius: 999px;
99
+
100
+ transition:
101
+ transform 0.18s var(--ease),
102
+ box-shadow 0.18s var(--ease),
103
+ background-color 0.18s var(--ease);
104
+ }
105
+
106
+ & .mx-button:not(:disabled):hover {
107
+ transform: translateY(-2px);
108
+ box-shadow: 0 0.5em 1.25em #1a101426;
109
+ }
110
+
111
+ & .mx-button:not(:disabled):active {
112
+ transform: translateY(0);
113
+ }
114
+
115
+ /* Tags read as stickers. */
116
+
117
+ & .mx-tag {
118
+ --border-radius: 999px;
119
+ --horizontal-padding: 0.75em;
120
+ --line-width: 0;
121
+ }
122
+
123
+ /* Cards: rounded, cropped media, a lift on hover. */
124
+
125
+ & .mx-card--block:not(.mx-list-item) {
126
+ --card-gap: 0;
127
+
128
+ border-radius: var(--border-radius-l);
129
+ overflow: clip;
130
+ background: var(--background, var(--colour-background));
131
+ box-shadow: 0 0.125em 0.5em #1a10140f;
132
+ transition:
133
+ transform 0.24s var(--ease),
134
+ box-shadow 0.24s var(--ease);
135
+
136
+ &:hover {
137
+ transform: translateY(-6px);
138
+ box-shadow: 0 1em 2em #1a101424;
139
+ }
140
+
141
+ & .mx-card__content {
142
+ padding: var(--spacing-m);
143
+ }
144
+ }
145
+
146
+ & .mx-card__media img {
147
+ border-radius: var(--border-radius);
148
+ }
149
+
150
+ & mx-accordion {
151
+ &:not(:last-child) {
152
+ margin-bottom: var(--spacing-s);
153
+ }
154
+ }
155
+
156
+ & .mx-accordion {
157
+ --horizontal-padding: var(--spacing-xs);
158
+
159
+ border: var(--line-width, 2px) solid var(--line-colour, var(--colour-border));
160
+ border-radius: var(--border-radius);
161
+ background-color: var(--colour-background-alt);
162
+ }
163
+
164
+ & .mx-accordion__toggle {
165
+ --font-weight-normal: 700;
166
+
167
+ & .mx-button {
168
+ border-color: transparent;
169
+ }
170
+ }
171
+
172
+ & .mx-accordion__content {
173
+ border-block-start-width: 0px;
174
+ background-color: var(--colour-background);
175
+ border-radius: var(--border-radius);
176
+ }
177
+
178
+ & .outcome {
179
+ border-radius: var(--border-radius-l);
180
+ }
181
+ }
@@ -0,0 +1,246 @@
1
+ /* Civic Formal — Mixtape theme
2
+ * Persona: Australian federal or state government department.
3
+ * Restrained and authoritative: low saturation, square corners, structured
4
+ * grid, generous whitespace, AAA contrast wherever the pairing allows.
5
+ *
6
+ * Part 1 is token overrides only. Part 2 is unlayered CSS for the shapes a
7
+ * department page needs and Mixtape does not ship: dense data tables,
8
+ * strict validation states, and formal document furniture (media release
9
+ * mastheads, official metadata blocks, legislative-style numbered clauses).
10
+ * Unlayered CSS beats every design-system layer without !important.
11
+ */
12
+
13
+ @import "https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,400;0,500;0,600;0,700;1,400&family=Lora:ital,wght@0,400;0,500;0,600;1,400&display=swap";
14
+
15
+ .theme--civic-formal {
16
+ --colour-primary: #1f3a5f;
17
+ --colour-accent: #97e3fa;
18
+
19
+ --colour-primary-light: color-mix(in oklch, var(--colour-primary), white 90%);
20
+ --colour-primary-lighter: color-mix(in oklch, var(--colour-primary), white 20%);
21
+ --colour-primary-darker: color-mix(in oklch, var(--colour-primary), black 20%);
22
+ --colour-primary-dark: color-mix(in oklch, var(--colour-primary), black 40%);
23
+ --colour-primary-darkest: color-mix(in oklch, var(--colour-primary), black 50%);
24
+ --colour-accent-light: color-mix(in oklch, var(--colour-accent), white 90%);
25
+ --colour-accent-lighter: color-mix(in oklch, var(--colour-accent), white 20%);
26
+ --colour-accent-darker: color-mix(in oklch, var(--colour-accent), black 10%);
27
+ --colour-accent-dark: color-mix(in oklch, var(--colour-accent), black 40%);
28
+ --colour-accent-darkest: color-mix(in oklch, var(--colour-accent), black 50%);
29
+
30
+ --colour-foreground: light-dark(#16181c, #fff);
31
+ --colour-foreground-alt: light-dark(#4a4f57, #eff1f3);
32
+ --colour-background: light-dark(#fff, #16181c);
33
+ --colour-background-alt: light-dark(#eff1f3, #4a4f57);
34
+ --colour-link: light-dark(#183e72, #eff1f3);
35
+ --colour-foreground-reverse: light-dark(#fff, #16181c);
36
+ --colour-background-reverse: light-dark(#16181c, #fff);
37
+ --_colour-outline: light-dark(#1f3a5f, #eff1f3);
38
+
39
+ /* Type: Public Sans for interface and headings, Lora for document prose.
40
+ A restrained 1.28 ratio — the page is read, not scanned. */
41
+ --font-family: "Public Sans", system-ui, sans-serif;
42
+ --font-family-prose: "Lora", georgia, serif;
43
+ --type-ratio: 1.28;
44
+ --font-size: var(--base-font-size);
45
+ --font-size-xs: calc(var(--base-font-size) * pow(var(--type-ratio), -0.5));
46
+ --font-size-s: calc(var(--base-font-size) * pow(var(--type-ratio), -0.25));
47
+ --font-size-m: 1rem;
48
+ --font-size-ml: calc(var(--base-font-size) * pow(var(--type-ratio), 0.5));
49
+ --font-size-l: calc(var(--base-font-size) * pow(var(--type-ratio), 1));
50
+ --font-size-xl: calc(var(--base-font-size) * pow(var(--type-ratio), 2));
51
+ --font-size-xxl: calc(var(--base-font-size) * pow(var(--type-ratio), 3));
52
+ --font-size-xxxl: calc(var(--base-font-size) * pow(var(--type-ratio), 4));
53
+
54
+ /* Shape: square. One radius value, and it is zero. */
55
+ --border-radius: 0;
56
+ --border-radius-l: 0;
57
+ --hero-image-radius: 0;
58
+ --popover-radius: 0;
59
+
60
+ --shadow-color: #16181c1f;
61
+ --shadow-size: 0.35em;
62
+
63
+ --tag-background: #e3e7ec;
64
+ --tag-foreground: #1f3a5f;
65
+ --tag-font-size: var(--font-size-xs);
66
+ --button-font-size: var(--font-size-s);
67
+ --icon-size: 1rem;
68
+
69
+ /* Form geometry: taller targets, visible 2px rules, explicit required text. */
70
+ --form-element-height: 3rem;
71
+ --control-size: 1.5rem;
72
+ --placeholder-colour: var(--colour-foreground-alt);
73
+ --colour-error: #8c1d18;
74
+ --colour-success: #1d5c37;
75
+
76
+ font-family: var(--font-family);
77
+ font-size: var(--font-size);
78
+ line-height: var(--line-height);
79
+
80
+ & .mx-header {
81
+ border-block-end: 4px solid var(--colour-primary);
82
+ }
83
+
84
+ & .mx-footer {
85
+ --scheme: light;
86
+ --background: var(--colour-accent-light);
87
+
88
+ border-block-start: 2px solid var(--colour-border);
89
+ }
90
+
91
+ & .mx-nav {
92
+ --nav-underline: underline;
93
+ --link-colour: var(--colour-link);
94
+ }
95
+
96
+ /* Headings: plain, medium weight, no optical tightening. Authority here comes
97
+ from hierarchy and space, not from expression. */
98
+
99
+ & h1 {
100
+ --heading-letter-spacing: -0.015em;
101
+ }
102
+
103
+ & :is(h2, h3, h4, h5, h6) {
104
+ --font-weight-bold: 600;
105
+ --line-height-h: 1.25;
106
+ --heading-letter-spacing: -0.005em;
107
+
108
+ text-wrap: pretty;
109
+ }
110
+
111
+ & .mx-text--eyebrow {
112
+ --heading-font-weight: 600;
113
+ --heading-letter-spacing: 0.14em;
114
+ }
115
+
116
+ & .mx-button {
117
+ --font-weight-bold: 600;
118
+ --button-letter-spacing: 0.01em;
119
+ --button-min-height: 2.75rem;
120
+ }
121
+
122
+ & .mx-button--large {
123
+ --button-min-height: 3rem;
124
+ }
125
+
126
+ & .mx-button--small {
127
+ --button-min-height: unset;
128
+ }
129
+
130
+ & .mx-tag {
131
+ --tag-font-size: 0.75rem;
132
+ --font-weight-bold: 600;
133
+ --tag-letter-spacing: 0.04em;
134
+ }
135
+
136
+ & .mx-callout {
137
+ --line-width: 4px;
138
+
139
+ background: var(--colour-background-alt);
140
+ padding-block: var(--spacing-xs);
141
+ padding-inline-end: var(--spacing-xs);
142
+ }
143
+
144
+ & .mx-hero-banner {
145
+ &:not(:has(.mx-hero-banner__aside)) {
146
+ --hero-columns: 1fr;
147
+ }
148
+ }
149
+
150
+ /* Document prose: serif, capped measure, numbered clause support. */
151
+
152
+ & .mx-rich-text {
153
+ & h2 {
154
+ --heading-font-size: var(--font-size-l);
155
+ }
156
+
157
+ & h3 {
158
+ --heading-font-size: var(--font-size-ml);
159
+ }
160
+
161
+ & blockquote {
162
+ --line-width: 4px;
163
+
164
+ font-size: var(--font-size-ml);
165
+ }
166
+ }
167
+
168
+ /* Official metadata block: label/value pairs above a document. definitiion list / columns + mx-text--meta */
169
+
170
+ /* Dense data tables.
171
+ zebra, compact + right-aligned figures. */
172
+
173
+ & thead th {
174
+ background: var(--colour-primary);
175
+ color: #fff;
176
+ letter-spacing: 0.04em;
177
+ text-transform: uppercase;
178
+ border-block-end: unset;
179
+ }
180
+
181
+ & .num {
182
+ text-align: end;
183
+ }
184
+
185
+ & dl {
186
+ border-block: 1px solid currentcolor;
187
+ padding-block: var(--spacing-xs);
188
+ }
189
+
190
+ /* Validation: strict and loud. Error state gets rule, tint and a marker so
191
+ the signal is never colour alone. */
192
+
193
+ & .mx-label {
194
+ font-weight: 600;
195
+ }
196
+
197
+ & .mx-required {
198
+ font-weight: 400;
199
+ color: var(--colour-foreground-alt);
200
+ }
201
+
202
+ & :is(.mx-input__text, .mx-input__select, .mx-input__textarea, .mx-choice-card) {
203
+ --outline-color: var(--colour-primary);
204
+ --outline-offset: 2px;
205
+
206
+ &.error {
207
+ border-inline-start-width: 6px;
208
+ background: #fdf6f5;
209
+ }
210
+
211
+ &.success {
212
+ border-inline-start-width: 6px;
213
+ }
214
+ }
215
+
216
+ & .mx-choice-card:has(input:checked) {
217
+ border-inline-start-width: 6px;
218
+ }
219
+
220
+ & .mx-error-message {
221
+ font-weight: 600;
222
+
223
+ &::before {
224
+ content: "Error: ";
225
+ }
226
+ }
227
+
228
+ & .mx-fieldset {
229
+ border: 0;
230
+ padding: 0;
231
+ margin-inline: 0;
232
+ }
233
+
234
+ & .mx-legend {
235
+ font-weight: 600;
236
+ font-size: var(--font-size-m);
237
+ }
238
+
239
+ & .mx-accordion__toggle {
240
+ font-weight: 700;
241
+
242
+ & .mx-button {
243
+ border-color: transparent;
244
+ }
245
+ }
246
+ }
@@ -2,12 +2,18 @@
2
2
 
3
3
  .theme--demo {
4
4
  --font-family: "Mozilla Text", Inter, helvetica, arial, sans-serif;
5
- --heading-font-family: "Mozilla Headline", Inter, helvetica, arial, sans-serif;
6
- --font-size: 18px;
7
- --font-size-xl: 40px;
8
- --font-size-xxl: 60px;
9
- --font-size-xxxl: 80px;
10
- --font-size-l: 30px;
5
+ --font-family-display: "Mozilla Headline", Inter, helvetica, arial, sans-serif;
6
+ --typo-ratio: 1.618;
7
+ --font-size: var(--base-font-size);
8
+ --font-size-xs: calc(var(--base-font-size) * pow(var(--type-ratio), -0.5));
9
+ --font-size-s: calc(var(--base-font-size) * pow(var(--type-ratio), -0.25));
10
+ --font-size-m: 1rem;
11
+ --font-size-ml: calc(var(--base-font-size) * pow(var(--type-ratio), 0.5));
12
+ --font-size-l: calc(var(--base-font-size) * pow(var(--type-ratio), 1));
13
+ --font-size-xl: calc(var(--base-font-size) * pow(var(--type-ratio), 2));
14
+ --font-size-xxl: calc(var(--base-font-size) * pow(var(--type-ratio), 3));
15
+ --font-size-xxxl: calc(var(--base-font-size) * pow(var(--type-ratio), 4));
16
+
11
17
  --container-max-width: 90ch;
12
18
  --container-max-width-narrow: 50rem;
13
19
  --border-radius-l: 4px;
@@ -16,6 +22,7 @@
16
22
 
17
23
  font-family: var(--font-family);
18
24
  font-size: var(--font-size);
25
+ line-height: var(--line-height);
19
26
 
20
27
  & .mx-text--lede {
21
28
  --font-size: var(--font-size-m);
@@ -76,7 +83,7 @@
76
83
  }
77
84
 
78
85
  &[class*="mx-background--"] .mx-hero-banner__aside-image {
79
- margin-bottom: -2rem;
86
+ margin-block-end: -2rem;
80
87
  }
81
88
  }
82
89