@obosbbl/grunnmuren-tailwind 2.0.0-canary.1 → 2.0.0-canary.10

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
@@ -29,7 +29,7 @@ module.exports = {
29
29
  './src/app/**/*.{js,ts,jsx,tsx,}',
30
30
 
31
31
  // If you're using Grunnmuren's React components
32
- './node_modules/@obosbbl/grunnmuren-react/dist/**/*.mjs',
32
+ './node_modules/@obosbbl/grunnmuren-react/dist/**/*.{mjs,js}',
33
33
  ],
34
34
  };
35
35
  ```
@@ -57,19 +57,39 @@ module.exports = {
57
57
  };
58
58
  ```
59
59
 
60
+ ## Fonts
61
+
62
+ Fonts are automatically loaded from OBOS' CDN, so you don't have to host the font files yourself.
63
+
64
+ If you use [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), you have to allow `https://www.obos.no` as a [font-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/font-src), otherwise the fonts will be blocked from loading.
65
+
66
+ The preset includes a (local) fallback font to prevent [CLS](https://web.dev/articles/cls) while the fonts are loading. This is similar to the [font optimization in Next](https://nextjs.org/docs/app/building-your-application/optimizing/fonts). This is enabled by default, but can be disabled with the `includeFontFallback` option.
67
+
68
+ The fallback font metrics is generated with a script that can be run with `pnpm font-fallback` (requires [Bun](https://bun.sh/)). If the fonts are changed, the script must be rerun and the resulting file commited.
69
+
60
70
  ## Migrating from v1?
61
71
 
62
72
  To ease the transition from v1 to v2 of Grunnmuren, it is possible to configure the preset to be (partially) compatible with v1. This allows you to use v2 of the Tailwind preset with v1 of the React components, and upgrade your application over time instead of a full migration.
63
73
 
64
74
  To do that you need to configure the preset with `legacyV1Compatibility` option.
65
75
 
76
+ ## Options
77
+
66
78
  ```js
67
79
  // tailwind.config.js
68
80
 
69
81
  /** @type {import('tailwindcss').Config} */
70
82
  module.exports = {
71
83
  presets: [
72
- require('@obosbbl/grunnmuren-tailwind')({ legacyV1Compatibility: true }),
84
+ require('@obosbbl/grunnmuren-tailwind')({ includeFontFallback: false }),
73
85
  ],
86
+ // content: [ ... ]
74
87
  };
75
88
  ```
89
+
90
+ The preset supports the following options:
91
+
92
+ | Name | Default value | Description |
93
+ | --------------------- | ------------- | --------------------------------------------------- |
94
+ | includeFontFallback | `true` | Whether the preset includes a font fallback |
95
+ | legacyV1Compatibility | `false` | Configures partial compatibility with Grunnmuren v1 |
@@ -0,0 +1 @@
1
+ module.exports = {"OBOSText":{"font-family":"\"__OBOSText_Fallback\"","src":"local(\"Arial\")","size-adjust":"100%","ascent-override":"94%","descent-override":"26%","line-gap-override":"0%"},"OBOSDisplay":{"font-family":"\"__OBOSDisplay_Fallback\"","src":"local(\"Arial\")","size-adjust":"100%","ascent-override":"94%","descent-override":"26%","line-gap-override":"0%"}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@obosbbl/grunnmuren-tailwind",
3
- "version": "2.0.0-canary.1",
3
+ "version": "2.0.0-canary.10",
4
4
  "description": "Grunnmuren Tailwind preset",
5
5
  "repository": {
6
6
  "url": "https://github.com/code-obos/grunnmuren"
@@ -11,16 +11,21 @@
11
11
  ".": "./tailwind-base.cjs"
12
12
  },
13
13
  "files": [
14
- "tailwind-base.cjs"
14
+ "tailwind-base.cjs",
15
+ "fonts/font-fallback.js"
15
16
  ],
16
17
  "dependencies": {
17
18
  "@tailwindcss/aspect-ratio": "^0.4.2",
18
- "@tailwindcss/typography": "^0.5.10"
19
+ "@tailwindcss/typography": "^0.5.10",
20
+ "tailwindcss-animate": "^1.0.7"
19
21
  },
20
22
  "devDependencies": {
21
- "tailwindcss": "3.3.5"
23
+ "tailwindcss": "3.4.17"
22
24
  },
23
25
  "peerDependencies": {
24
- "tailwindcss": "^3.3.5"
26
+ "tailwindcss": "^3.4.0"
27
+ },
28
+ "scripts": {
29
+ "font-fallback": "bun --cwd=./fonts ./generate-font-fallback.ts"
25
30
  }
26
31
  }
package/tailwind-base.cjs CHANGED
@@ -1,32 +1,148 @@
1
+ const defaultTheme = require('tailwindcss/defaultTheme');
1
2
  const plugin = require('tailwindcss/plugin');
3
+ const fontFallbacks = require('./fonts/font-fallback');
2
4
 
3
- const obosFonts = [
4
- {
5
- fontWeight: 400,
6
- fontStyle: 'normal',
7
- url: 'https://www.obos.no/fonts/OBOSText-Regular.woff2',
5
+ const fontDeclarations = {
6
+ OBOSText: [
7
+ {
8
+ fontWeight: 400,
9
+ fontStyle: 'normal',
10
+ url: 'https://www.obos.no/fonts/OBOSText-Regular.woff2',
11
+ },
12
+ {
13
+ fontWeight: 400,
14
+ fontStyle: 'italic',
15
+ url: 'https://www.obos.no/fonts/OBOSText-Italic.woff2',
16
+ },
17
+ {
18
+ fontWeight: 500,
19
+ fontStyle: 'normal',
20
+ url: 'https://www.obos.no/fonts/OBOSText-Medium.woff2',
21
+ },
22
+ ],
23
+ OBOSDisplay: [
24
+ {
25
+ url: 'https://www.obos.no/fonts/OBOSDisplay-SemiBold.woff2',
26
+ },
27
+ ],
28
+ };
29
+
30
+ /**
31
+ * Styles for typography that are reused in both component classes and prose (through the tailwind typography plugin)
32
+ */
33
+ const typography = {
34
+ headingXlText: {
35
+ fontWeight: 'semibold',
36
+ small: {
37
+ fontSize: '2.8125rem',
38
+ lineHeight: '3.625rem',
39
+ },
40
+ large: {
41
+ fontSize: '3.9375rem',
42
+ lineHeight: '5.125rem',
43
+ },
44
+ },
45
+ headingLText: {
46
+ fontWeight: 'semibold',
47
+ small: {
48
+ fontSize: '1.8125rem',
49
+ lineHeight: '2.75rem',
50
+ },
51
+ large: {
52
+ fontSize: '2.25rem',
53
+ lineHeight: '3.5rem',
54
+ },
55
+ },
56
+ headingMText: {
57
+ fontWeight: 'medium',
58
+ small: {
59
+ fontSize: '1.4375rem',
60
+ lineHeight: '2.25rem',
61
+ },
62
+ large: {
63
+ fontSize: '1.625rem',
64
+ lineHeight: '2.5625rem',
65
+ },
66
+ },
67
+ headingSText: {
68
+ fontWeight: 'medium',
69
+ small: {
70
+ fontSize: '1.1875rem',
71
+ lineHeight: '1.1875rem',
72
+ },
73
+ large: {
74
+ fontSize: '1.3125rem',
75
+ lineHeight: '2.125rem',
76
+ },
77
+ },
78
+ headingXsText: {
79
+ fontWeight: 'medium',
80
+ small: {
81
+ fontSize: '1.125rem',
82
+ lineHeight: '1.75rem',
83
+ },
84
+ large: {
85
+ fontSize: '1.1875rem',
86
+ lineHeight: '1.9375rem',
87
+ },
88
+ },
89
+ paragraphText: {
90
+ fontSize: '1rem', // 1rem is the base font size, which is obviously the default size. But it is set explicitly here to make it easier to configure in the future, if this size changes.
91
+ lineHeight: '1.625rem',
8
92
  },
9
- {
10
- fontWeight: 400,
11
- fontStyle: 'italic',
12
- url: 'https://www.obos.no/fonts/OBOSText-Italic.woff2',
93
+ leadText: {
94
+ fontWeight: 'medium',
95
+ small: {
96
+ fontSize: '1.4375rem',
97
+ lineHeight: '2.25rem',
98
+ },
99
+ large: {
100
+ fontSize: '1.625rem',
101
+ lineHeight: '2.5625rem',
102
+ },
13
103
  },
14
- {
15
- fontWeight: 500,
16
- fontStyle: 'normal',
17
- url: 'https://www.obos.no/fonts/OBOSText-Medium.woff2',
104
+ blockquoteText: {
105
+ fontWeight: 'medium',
106
+ display: 'grid',
107
+ gridTemplateColumns: '3rem 1fr',
108
+ columnGap: '0.4375rem',
109
+ small: {
110
+ fontSize: '1.4375rem',
111
+ lineHeight: '2.25rem',
112
+ },
113
+ large: {
114
+ fontSize: '1.625rem',
115
+ lineHeight: '2.5625rem',
116
+ },
117
+ before: {
118
+ content: '"“"',
119
+ fontFamily: 'OBOSDisplay',
120
+ fontSize: '4.6875rem',
121
+ lineHeight: '1.6875rem',
122
+ fontWeight: '400',
123
+ fontStyle: 'normal',
124
+ },
18
125
  },
19
- {
20
- fontWeight: 700,
21
- fontStyle: 'normal',
22
- url: 'https://www.obos.no/fonts/OBOSText-Bold.woff2',
126
+ descriptionText: {
127
+ small: {
128
+ fontSize: '0.875rem',
129
+ lineHeight: '1.4375rem',
130
+ },
131
+ large: {
132
+ fontSize: '0.875rem',
133
+ lineHeight: '1.375rem',
134
+ },
23
135
  },
24
- ];
136
+ };
25
137
 
26
138
  /**
139
+ * @param {boolean} options.includeFontFallback
27
140
  * @param {boolean} options.legacyV1Compatibility
28
141
  */
29
142
  module.exports = (options = {}) => {
143
+ options.includeFontFallback ??= true;
144
+ options.legacyV1Compatibility ??= false;
145
+
30
146
  const v1CompatibilityPlugins = [];
31
147
 
32
148
  if (options.legacyV1Compatibility) {
@@ -39,18 +155,15 @@ module.exports = (options = {}) => {
39
155
  );
40
156
  }
41
157
 
42
- const fontFamily = 'OBOSFont';
43
- const fonts = obosFonts;
44
- const containerSize = '92rem';
45
-
46
158
  return {
47
159
  plugins: [
48
160
  ...v1CompatibilityPlugins,
49
161
  require('@tailwindcss/typography'),
50
- plugin(function ({ addBase, addComponents }) {
162
+ require('tailwindcss-animate'),
163
+ plugin(({ addBase, addComponents, theme }) => {
51
164
  addBase({
52
165
  html: {
53
- '@apply text-black antialiased font-normal': {},
166
+ '@apply text-black antialiased font-normal font-text': {},
54
167
  },
55
168
  b: {
56
169
  fontWeight: 500,
@@ -62,21 +175,68 @@ module.exports = (options = {}) => {
62
175
  'text-decoration': 'underline',
63
176
  },
64
177
  '::selection': { '@apply bg-mint text-black': {} },
178
+ ':root': {
179
+ '--gm-container-width': '92rem',
180
+ '--gm-container-gutter-width': '1rem',
181
+
182
+ '--gm-color-black': hexToRgb('#333'),
183
+ '--gm-color-white': hexToRgb('#fff'),
184
+
185
+ '--gm-color-gray': hexToRgb('#818181'),
186
+ '--gm-color-gray-dark': hexToRgb('#595959'),
187
+ '--gm-color-gray-light': hexToRgb('#e6e6e6'),
188
+ '--gm-color-gray-lightest': hexToRgb('#f1f1f1'),
189
+
190
+ '--gm-color-sky': hexToRgb('#bedfec'),
191
+ '--gm-color-sky-light': hexToRgb('#deeff5'),
192
+ '--gm-color-sky-lightest': hexToRgb('#ebf5f9'),
193
+
194
+ '--gm-color-mint': hexToRgb('#cdece2'),
195
+ '--gm-color-mint-light': hexToRgb('#e6f5f0'),
196
+ '--gm-color-mint-lightest': hexToRgb('#f0f9f6'),
197
+
198
+ '--gm-color-blue': hexToRgb('#0047ba'),
199
+ '--gm-color-blue-light': hexToRgb('#bedfec'),
200
+ '--gm-color-blue-lightest': hexToRgb('#deeff5'),
201
+ '--gm-color-blue-dark': hexToRgb('#002169'),
202
+
203
+ '--gm-color-green': hexToRgb('#008761'),
204
+ '--gm-color-green-dark': hexToRgb('#00524c'),
205
+ '--gm-color-green-light': hexToRgb('#cdece2'),
206
+ '--gm-color-green-lightest': hexToRgb('#e6f5f0'),
207
+
208
+ '--gm-color-red': hexToRgb('#c0385d'),
209
+ '--gm-color-red-light': hexToRgb('#faedef'),
210
+
211
+ '--gm-color-orange': hexToRgb('#e8a74a'),
212
+ '--gm-color-orange-light': hexToRgb('#f8e5c9'),
213
+
214
+ '--gm-color-yellow': hexToRgb('#fff5d2'),
215
+ },
65
216
  });
66
217
 
67
218
  addComponents({
219
+ '.page-layout': {
220
+ display: 'flex',
221
+ flexDirection: 'column',
222
+ minHeight: '100vh',
223
+ },
224
+ '.page-layout-main': {
225
+ backgroundColor: theme('colors.white'),
226
+ flexGrow: '1',
227
+ },
68
228
  '.container': {
69
229
  width: '100%',
70
- paddingLeft: '1rem',
71
- paddingRight: '1rem',
230
+ paddingLeft: 'var(--gm-container-gutter-width)',
231
+ paddingRight: 'var(--gm-container-gutter-width)',
72
232
  marginLeft: 'auto',
73
233
  marginRight: 'auto',
74
- maxWidth: containerSize,
234
+ maxWidth: 'var(--gm-container-width)',
75
235
  },
76
236
  '.container-prose': {
77
237
  width: '100%',
78
- paddingLeft: '1rem',
79
- paddingRight: '1rem',
238
+ paddingLeft: 'var(--gm-container-gutter-width)',
239
+ paddingRight: 'var(--gm-container-gutter-width)',
80
240
  marginLeft: 'auto',
81
241
  marginRight: 'auto',
82
242
  maxWidth: '45.5rem',
@@ -84,57 +244,141 @@ module.exports = (options = {}) => {
84
244
  });
85
245
  }),
86
246
 
87
- plugin(function ({ addBase, addComponents }) {
247
+ plugin(({ addBase, addComponents }) => {
248
+ const {
249
+ headingXlText,
250
+ headingLText,
251
+ headingMText,
252
+ headingSText,
253
+ headingXsText,
254
+ paragraphText,
255
+ leadText,
256
+ blockquoteText,
257
+ descriptionText,
258
+ } = typography;
259
+
88
260
  // This is tailwind syntax for setting both the font-size and the line-height
89
- const h1 = '@apply font-bold text-[28px]/[38px] md:text-[40px]/[56px]';
90
- const h2 = '@apply font-bold text-[24px]/[30px] md:text-[32px]/[42px]';
91
- const h3 = '@apply font-bold text-[20px]/[30px] md:text-[24px]/[34px]';
92
- const h4 = '@apply font-bold text-[18px]/[24px] md:text-[20px]/[28px]';
261
+ const headingXl = `@apply font-display font-${headingXlText.fontWeight} text-[${headingXlText.small.fontSize}]/[${headingXlText.small.lineHeight}] lg:text-[${headingXlText.large.fontSize}]/[${headingXlText.large.lineHeight}]`;
262
+ const headingL = `@apply font-display font-${headingLText.fontWeight} text-[${headingLText.small.fontSize}]/[${headingLText.small.lineHeight}] lg:text-[${headingLText.large.fontSize}]/[${headingLText.large.lineHeight}]`;
263
+ const headingM = `@apply font-text font-${headingMText.fontWeight} text-[${headingMText.small.fontSize}]/[${headingMText.small.lineHeight}] lg:text-[${headingMText.large.fontSize}]/[${headingMText.large.lineHeight}]`;
264
+ const headingS = `@apply font-text font-${headingSText.fontWeight} text-[${headingSText.small.fontSize}]/[${headingSText.small.lineHeight}] lg:text-[${headingSText.large.fontSize}]/[${headingSText.large.lineHeight}]`;
265
+ const headingXs = `@apply font-text font-${headingXsText.fontWeight} text-[${headingXsText.small.fontSize}]/[${headingXsText.small.lineHeight}] lg:text-[${headingXsText.large.fontSize}]/[${headingXsText.large.lineHeight}]`;
266
+
267
+ const paragraph = `@apply text-[${paragraphText.fontSize}]/[${paragraphText.lineHeight}]`;
268
+ const lead = `@apply font-medium text-[${leadText.small.fontSize}]/[${leadText.small.lineHeight}] lg:text-[${leadText.large.fontSize}]/[${leadText.large.lineHeight}]`;
269
+
270
+ const blockquote = `@apply font-${blockquoteText.fontWeight} italic grid grid-cols-[${blockquoteText.gridTemplateColumns.split(' ').join('_')}] gap-x-[${blockquoteText.columnGap}] pt-4
271
+ text-[${blockquoteText.large.fontSize}]/[${blockquoteText.large.lineHeight}] lg:text-[${blockquoteText.small.fontSize}]/[${blockquoteText.small.lineHeight}]
272
+ before:text-[${blockquoteText.before.fontSize}]/[${blockquoteText.before.lineHeight}] before:content-[${blockquoteText.before.content}] before:font-display before:not-italic`;
273
+
274
+ const description = `@apply text-[${descriptionText.large.fontSize}]/[${descriptionText.large.lineHeight}] lg:text-[${descriptionText.small.fontSize}]/[${descriptionText.small.lineHeight}]`;
93
275
 
94
276
  if (options.legacyV1Compatibility) {
95
277
  addBase({
96
278
  h1: {
97
- [h1]: {},
279
+ [headingXl]: {},
98
280
  },
99
281
  h2: {
100
- [h2]: {},
282
+ [headingL]: {},
101
283
  },
102
284
  h3: {
103
- [h3]: {},
285
+ [headingM]: {},
104
286
  },
105
287
  h4: {
106
- [h4]: {},
288
+ [headingS]: {},
107
289
  },
108
290
  });
109
291
  }
110
292
 
111
293
  addComponents({
294
+ /** @deprecated Will be replaced by heading-xl */
112
295
  '.h1': {
113
- [h1]: {},
296
+ [headingXl]: {},
114
297
  },
298
+ /** @deprecated Will be replaced by heading-l */
115
299
  '.h2': {
116
- [h2]: {},
300
+ [headingL]: {},
117
301
  },
302
+ /** @deprecated Will be replaced by heading-m */
118
303
  '.h3': {
119
- [h3]: {},
304
+ [headingM]: {},
120
305
  },
306
+ /** @deprecated Will be replaced by heading-s */
121
307
  '.h4': {
122
- [h4]: {},
308
+ [headingS]: {},
309
+ },
310
+ '.heading-xl': {
311
+ [headingXl]: {},
312
+ },
313
+ '.heading-l': {
314
+ [headingL]: {},
315
+ },
316
+ '.heading-m': {
317
+ [headingM]: {},
318
+ },
319
+ '.heading-s': {
320
+ [headingS]: {},
321
+ },
322
+ '.heading-xs': {
323
+ [headingXs]: {},
324
+ },
325
+ '.paragraph': {
326
+ [paragraph]: {},
327
+ },
328
+ '.lead': {
329
+ [lead]: {},
330
+ },
331
+ '.blockquote': {
332
+ [blockquote]: {},
333
+ },
334
+ '.description': {
335
+ [description]: {},
336
+ },
337
+ /** Standard black focus outline */
338
+ '.outline-focus': {
339
+ '@apply outline outline-2 outline-black': {},
340
+ },
341
+ /** Standard black focus outline with offset */
342
+ '.outline-focus-offset': {
343
+ '@apply outline-focus outline-offset-2': {},
344
+ },
345
+ /** Standard black focus outline with negative offset (inset) */
346
+ '.outline-focus-inset': {
347
+ '@apply outline-focus -outline-offset-4': {},
348
+ },
349
+ /** Standard black focus ring */
350
+ '.ring-focus': {
351
+ '@apply ring-2 ring-black': {},
352
+ },
353
+ /** Standard black focus ring with offset */
354
+ '.ring-focus-offset': {
355
+ '@apply ring-focus ring-offset-2': {},
123
356
  },
124
357
  });
125
358
  }),
126
- plugin(function ({ addBase }) {
359
+ plugin(({ addBase }) => {
127
360
  addBase(
128
- fonts.map((font) => ({
129
- '@font-face': {
130
- fontFamily,
131
- fontWeight: font.fontWeight,
132
- fontStyle: font.fontStyle,
133
- src: `url('${font.url}') format('woff2')`,
134
- fontDisplay: 'swap',
135
- },
136
- })),
361
+ Object.entries(fontDeclarations).flatMap(
362
+ ([fontFamily, fontFamilyDeclarations]) =>
363
+ fontFamilyDeclarations.map((font) => ({
364
+ '@font-face': {
365
+ fontFamily,
366
+ fontWeight: font.fontWeight,
367
+ fontStyle: font.fontStyle,
368
+ src: `url('${font.url}') format('woff2')`,
369
+ fontDisplay: 'swap',
370
+ },
371
+ })),
372
+ ),
137
373
  );
374
+
375
+ if (options.includeFontFallback) {
376
+ addBase(
377
+ Object.values(fontFallbacks).map((fontFallback) => ({
378
+ '@font-face': fontFallback,
379
+ })),
380
+ );
381
+ }
138
382
  }),
139
383
  ],
140
384
  theme: {
@@ -142,56 +386,68 @@ module.exports = (options = {}) => {
142
386
  inherit: 'inherit',
143
387
  current: 'currentColor',
144
388
  transparent: 'transparent',
145
- black: '#333',
146
- white: '#fff',
389
+ black: 'rgb(var(--gm-color-black))',
390
+ white: 'rgb(var(--gm-color-white))',
147
391
  gray: {
148
- DEFAULT: '#818181',
149
- dark: '#595959',
150
- light: '#E6E6E6',
151
- lightest: '#f1f1f1',
392
+ DEFAULT: 'rgb(var(--gm-color-gray))',
393
+ dark: 'rgb(var(--gm-color-gray-dark))',
394
+ light: 'rgb(var(--gm-color-gray-light))',
395
+ lightest: 'rgb(var(--gm-color-gray-lightest))',
152
396
  },
153
397
  sky: {
154
- DEFAULT: '#BEDFEC',
155
- light: '#DEEFF5',
156
- lightest: '#EBF5F9',
398
+ DEFAULT: 'rgb(var(--gm-color-sky))',
399
+ light: 'rgb(var(--gm-color-sky-light))',
400
+ lightest: 'rgb(var(--gm-color-sky-lightest))',
157
401
  },
158
402
  mint: {
159
- DEFAULT: '#CDECE2',
160
- light: '#E6F5F0',
161
- lightest: '#F0F9F6',
403
+ DEFAULT: 'rgb(var(--gm-color-mint))',
404
+ light: 'rgb(var(--gm-color-mint-light))',
405
+ lightest: 'rgb(var(--gm-color-mint-lightest))',
162
406
  },
163
407
  blue: {
164
408
  // OBOS Blue/Primary brand
165
- DEFAULT: '#0047BA',
166
- light: '#BEDFEC',
167
- lightest: '#DEEFF5',
409
+ DEFAULT: 'rgb(var(--gm-color-blue))',
168
410
  // OBOS Ocean
169
- dark: '#002169',
411
+ dark: 'rgb(var(--gm-color-blue-dark))',
412
+ light: 'rgb(var(--gm-color-blue-light))',
413
+ lightest: 'rgb(var(--gm-color-blue-lightest))',
170
414
  },
171
415
  green: {
172
416
  // OBOS Green/Primary brand
173
- DEFAULT: '#008761',
174
- lightest: '#E6F5F0',
175
- light: '#CDECE2',
417
+ DEFAULT: 'rgb(var(--gm-color-green))',
176
418
  // OBOS Forest
177
- dark: '#00524C',
419
+ dark: 'rgb(var(--gm-color-green-dark))',
420
+ light: 'rgb(var(--gm-color-green-light))',
421
+ lightest: 'rgb(var(--gm-color-green-lightest))',
178
422
  },
179
423
  red: {
180
- DEFAULT: '#C0385D',
424
+ DEFAULT: 'rgb(var(--gm-color-red))',
181
425
  // error red
182
- light: '#FAEDEF',
426
+ light: 'rgb(var(--gm-color-red-light))',
183
427
  },
184
428
  orange: {
185
- DEFAULT: '#e8a74a',
186
- light: '#f8e5c9',
429
+ DEFAULT: 'rgb(var(--gm-color-orange))',
430
+ light: 'rgb(var(--gm-color-orange-light))',
187
431
  },
188
432
  yellow: {
189
433
  // open house
190
- DEFAULT: '#fff5d2',
434
+ DEFAULT: 'rgb(var(--gm-color-yellow))',
191
435
  },
192
436
  },
193
437
  fontFamily: {
194
- sans: [fontFamily, 'sans-serif'],
438
+ text: [
439
+ 'OBOSText',
440
+ options.includeFontFallback && fontFallbacks.OBOSText['font-family'],
441
+ 'sans-serif',
442
+ ].filter((f) => f),
443
+ display: [
444
+ 'OBOSDisplay',
445
+ options.includeFontFallback &&
446
+ fontFallbacks.OBOSDisplay['font-family'],
447
+ 'sans-serif',
448
+ ],
449
+ // OBOS doesn't have monospaced font, so we keep Tailwind's default here
450
+ mono: defaultTheme.fontFamily.mono,
195
451
  },
196
452
  extend: {
197
453
  maxWidth: {
@@ -215,59 +471,98 @@ module.exports = (options = {}) => {
215
471
  '--tw-prose-headings': 'inherit',
216
472
  '--tw-prose-lead': 'inherit',
217
473
  '--tw-prose-links': 'inherit',
218
- '--tw-prose-quotes': theme('colors.blue.dark'),
219
- '--tw-prose-quote-borders': theme('colors.green.DEFAULT'),
474
+ '--tw-prose-quotes': 'inherit',
220
475
  '--tw-prose-counters': theme('colors.black'),
221
- '--tw-prose-bullets': theme('colors.green.DEFAULT'),
476
+ '--tw-prose-bullets': theme('colors.black'),
222
477
  color: theme('colors.black'),
223
478
  maxWidth: theme('maxWidth.prose'),
224
479
  a: {
225
480
  fontWeight: 400,
226
481
  },
227
482
  h1: {
228
- fontWeight: theme('fontWeight.bold'),
229
- fontSize: theme('fontSize.3xl'),
230
- '@media (min-width: theme("screens.md"))': {
231
- fontSize: theme('fontSize.5xl'),
483
+ fontFamily: 'OBOSDisplay',
484
+ fontWeight: theme('fontWeight.semibold'),
485
+ ...typography.headingXlText.small,
486
+ '@media (min-width: theme("screens.lg"))': {
487
+ ...typography.headingXlText.large,
232
488
  },
233
489
  },
234
490
  h2: {
235
- fontWeight: theme('fontWeight.bold'),
236
- fontSize: theme('fontSize.2xl'),
237
- '@media (min-width: theme("screens.md"))': {
238
- fontSize: theme('fontSize.4xl'),
491
+ fontFamily: 'OBOSDisplay',
492
+ fontWeight: theme('fontWeight.semibold'),
493
+ ...typography.headingLText.small,
494
+ '@media (min-width: theme("screens.lg"))': {
495
+ ...typography.headingLText.large,
239
496
  },
240
497
  },
241
498
  h3: {
242
- fontWeight: theme('fontWeight.bold'),
243
- fontSize: theme('fontSize.xl'),
244
- '@media (min-width: theme("screens.md"))': {
245
- fontSize: theme('fontSize.2xl'),
499
+ fontFamily: 'OBOSText',
500
+ fontWeight: theme('fontWeight.medium'),
501
+ ...typography.headingMText.small,
502
+ '@media (min-width: theme("screens.lg"))': {
503
+ ...typography.headingMText.large,
246
504
  },
247
505
  },
248
506
  h4: {
507
+ fontFamily: 'OBOSText',
508
+ fontWeight: theme('fontWeight.medium'),
509
+ ...typography.headingSText.small,
510
+ '@media (min-width: theme("screens.lg"))': {
511
+ ...typography.headingSText.large,
512
+ },
513
+ },
514
+ h5: {
515
+ fontFamily: 'OBOSText',
249
516
  fontWeight: theme('fontWeight.bold'),
250
- fontSize: theme('fontSize.lg'),
251
- '@media (min-width: theme("screens.md"))': {
252
- fontSize: theme('fontSize.xl'),
517
+ ...typography.headingXsText.small,
518
+ '@media (min-width: theme("screens.lg"))': {
519
+ ...typography.headingXsText.large,
253
520
  },
254
521
  },
255
522
  li: {
256
- marginTop: '1.5em',
257
- marginBottom: '1.5em',
523
+ ...typography.paragraphText.small,
524
+ '@media (min-width: theme("screens.lg"))': {
525
+ ...typography.paragraphText.large,
526
+ },
258
527
  },
259
- blockquote: {
260
- fontWeight: theme('fontWeight.bold'),
261
- fontStyle: 'normal',
528
+ p: {
529
+ ...typography.paragraphText.small,
530
+ '@media (min-width: theme("screens.lg"))': {
531
+ ...typography.paragraphText.large,
532
+ },
262
533
  },
263
- 'blockquote p:first-of-type::before': {
264
- content: '"«"',
534
+ blockquote: {
535
+ // Reset defaults:
536
+ marginBottom: 'unset',
537
+ padding: 'unset',
538
+ border: 'unset',
539
+ fontWeight: theme('fontWeight.medium'),
540
+ fontStyle: 'italic',
541
+ display: typography.blockquoteText.display,
542
+ gridTemplateColumns:
543
+ typography.blockquoteText.gridTemplateColumns,
544
+ columnGap: typography.blockquoteText.columnGap,
545
+ paddingTop: '1rem',
546
+ ...typography.blockquoteText.small,
547
+ '@media (min-width: theme("screens.lg"))': {
548
+ ...typography.blockquoteText.large,
549
+ },
265
550
  },
266
- 'blockquote p:last-of-type::after': {
267
- content: '"»"',
551
+ 'blockquote::before': {
552
+ ...typography.blockquoteText.before,
268
553
  },
269
554
  '[class~="lead"]': {
270
555
  fontWeight: theme('fontWeight.medium'),
556
+ ...typography.leadText.small,
557
+ '@media (min-width: theme("screens.lg"))': {
558
+ ...typography.leadText.large,
559
+ },
560
+ },
561
+ '[class~="description"]': {
562
+ ...typography.descriptionText.small,
563
+ '@media (min-width: theme("screens.lg"))': {
564
+ ...typography.descriptionText.large,
565
+ },
271
566
  },
272
567
  },
273
568
  },
@@ -277,8 +572,34 @@ module.exports = (options = {}) => {
277
572
  };
278
573
  };
279
574
 
575
+ /**
576
+ * A function that takes in a hex color as a string and returns a string with the color's rgb values.
577
+ * @param {string} hex
578
+ * @returns {string} The rgb values of the color.
579
+ */
580
+ function hexToRgb(hex) {
581
+ // Remove the hash (#) at the start if it's there
582
+ let hexValue = hex.replace(/^#/, '');
583
+
584
+ // If the hex value is shorthand (3 characters), expand it to 6 characters
585
+ if (hexValue.length === 3) {
586
+ hexValue = hexValue
587
+ .split('')
588
+ .map((char) => char + char)
589
+ .join('');
590
+ }
591
+
592
+ // Parse the r, g, and b values from the hex string
593
+ const r = Number.parseInt(hexValue.substring(0, 2), 16);
594
+ const g = Number.parseInt(hexValue.substring(2, 4), 16);
595
+ const b = Number.parseInt(hexValue.substring(4, 6), 16);
596
+
597
+ // Return the RGB values as a whitespace-separated string
598
+ return `${r} ${g} ${b}`;
599
+ }
600
+
280
601
  // These custom components are only used for v1 compat
281
- const button = plugin(function ({ addComponents, theme }) {
602
+ const button = plugin(({ addComponents, theme }) => {
282
603
  const hoverLoadingBgColor = 'rgba(0, 0, 0, 0.1)';
283
604
 
284
605
  addComponents({
@@ -335,7 +656,7 @@ const button = plugin(function ({ addComponents, theme }) {
335
656
  });
336
657
  });
337
658
 
338
- const radio = plugin(function ({ addComponents, theme }) {
659
+ const radio = plugin(({ addComponents, theme }) => {
339
660
  addComponents({
340
661
  '.radio': {
341
662
  // hide the native radio input
@@ -380,7 +701,7 @@ const radio = plugin(function ({ addComponents, theme }) {
380
701
  });
381
702
  });
382
703
 
383
- const checkbox = plugin(function ({ addComponents, theme }) {
704
+ const checkbox = plugin(({ addComponents, theme }) => {
384
705
  addComponents({
385
706
  '.checkbox': {
386
707
  '&::before': {
@@ -401,7 +722,7 @@ const checkbox = plugin(function ({ addComponents, theme }) {
401
722
  });
402
723
  });
403
724
 
404
- const snackbar = plugin(function ({ addComponents, theme }) {
725
+ const snackbar = plugin(({ addComponents, theme }) => {
405
726
  addComponents({
406
727
  '.snackbar': {
407
728
  'grid-template-columns': 'min-content auto',