@mindvalley/design-system 3.4.2 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,552 @@
1
+ # Typography font loading
2
+
3
+ This guide provides comprehensive instructions on how to load Mindvalley Design System typography fonts in your application across different frameworks and scenarios.
4
+
5
+ ## Overview
6
+
7
+ The Mindvalley Design System provides pre-generated `@font-face` CSS declarations that you can easily import into your project. The fonts are hosted on Fastly CDN and optimized for performance with `font-display: swap`.
8
+
9
+ ## Available fonts
10
+
11
+ The design system includes fonts for two brands:
12
+
13
+ - **Mindvalley** (`@mindvalley/design-system/typography/mindvalley/fonts.css`)
14
+ - **B2B** (`@mindvalley/design-system/typography/b2b/fonts.css`)
15
+
16
+ Each brand includes the following font families:
17
+
18
+ - Sharp Grotesk Cyr Book 19
19
+ - Sharp Grotesk Cyr Book Itl 19
20
+ - Sharp Grotesk Cyr Medium 19
21
+ - Sharp Grotesk Cyr Medium 20
22
+ - Sharp Grotesk Cyr Medium 22
23
+ - Sharp Grotesk Cyr Semibold 20
24
+
25
+ ## Installation
26
+
27
+ First, ensure you have the design system package installed:
28
+
29
+ ```bash
30
+ npm install @mindvalley/design-system
31
+ ```
32
+
33
+ or
34
+
35
+ ```bash
36
+ yarn add @mindvalley/design-system
37
+ ```
38
+
39
+ ---
40
+
41
+ ## Basic usage
42
+
43
+ ### Direct CSS import
44
+
45
+ > ⚠️ **Important for PostCSS users**: If you're using `@import` in SCSS/CSS files with `postcss-import`, make sure to configure it to resolve from `node_modules` and use the full `dist/` path. See [PostCSS configuration](#using-with-postcss-and-scss-import-phoenix-webpack--scss) for details.
46
+
47
+ #### Mindvalley brand only
48
+
49
+ ```css
50
+ @import '@mindvalley/design-system/typography/mindvalley/fonts.css';
51
+ ```
52
+
53
+ #### B2B brand only
54
+
55
+ ```css
56
+ @import '@mindvalley/design-system/typography/b2b/fonts.css';
57
+ ```
58
+
59
+ #### Both brands
60
+
61
+ If your application uses both Mindvalley and B2B typography:
62
+
63
+ ```css
64
+ @import '@mindvalley/design-system/typography/mindvalley/fonts.css';
65
+ @import '@mindvalley/design-system/typography/b2b/fonts.css';
66
+ ```
67
+
68
+ ### Using without a bundler
69
+
70
+ If you're working on a static HTML project without a bundler (Webpack, Vite, etc.), you'll need to copy the CSS file to your public assets directory:
71
+
72
+ **Build script example:**
73
+
74
+ ```json
75
+ {
76
+ "scripts": {
77
+ "copy-fonts": "cp node_modules/@mindvalley/design-system/dist/typography/mindvalley/fonts.css public/assets/css/"
78
+ }
79
+ }
80
+ ```
81
+
82
+ Then reference it in your HTML:
83
+
84
+ ```html
85
+ <link rel="stylesheet" href="/assets/css/fonts.css">
86
+ ```
87
+
88
+ **Note:** For modern JavaScript projects, use the import method instead (see above), which is handled automatically by your bundler.
89
+
90
+ ---
91
+
92
+ ## Framework-specific integration
93
+
94
+ ### Next.js
95
+
96
+ #### App Router (Next.js 13+)
97
+
98
+ **Using in Root Layout (`app/layout.tsx`):**
99
+
100
+ ```tsx
101
+ import '@mindvalley/design-system/typography/mindvalley/fonts.css'
102
+
103
+ export default function RootLayout({
104
+ children,
105
+ }: {
106
+ children: React.ReactNode
107
+ }) {
108
+ return (
109
+ <html lang="en">
110
+ <body>{children}</body>
111
+ </html>
112
+ )
113
+ }
114
+ ```
115
+
116
+ #### Pages Router (Next.js 12 and below)
117
+
118
+ **Using in custom app (`pages/_app.tsx`):**
119
+
120
+ ```tsx
121
+ import '@mindvalley/design-system/typography/mindvalley/fonts.css'
122
+ import type { AppProps } from 'next/app'
123
+
124
+ export default function App({ Component, pageProps }: AppProps) {
125
+ return <Component {...pageProps} />
126
+ }
127
+ ```
128
+
129
+ #### Loading fonts in a component
130
+
131
+ If you only need fonts in specific pages or components:
132
+
133
+ ```tsx
134
+ import '@mindvalley/design-system/typography/b2b/fonts.css'
135
+
136
+ export default function B2BPage() {
137
+ return (
138
+ <div className="title-bold-5">
139
+ B2B Page Content
140
+ </div>
141
+ )
142
+ }
143
+ ```
144
+
145
+ ---
146
+
147
+ ### Vite + React
148
+
149
+ **In your main entry point (`src/main.tsx` or `src/index.tsx`):**
150
+
151
+ ```tsx
152
+ import React from 'react'
153
+ import ReactDOM from 'react-dom/client'
154
+ import '@mindvalley/design-system/typography/mindvalley/fonts.css'
155
+ import App from './App'
156
+
157
+ ReactDOM.createRoot(document.getElementById('root')!).render(
158
+ <React.StrictMode>
159
+ <App />
160
+ </React.StrictMode>,
161
+ )
162
+ ```
163
+
164
+ **Or in your global CSS file (`src/index.css`):**
165
+
166
+ ```css
167
+ @import '@mindvalley/design-system/typography/mindvalley/fonts.css';
168
+
169
+ /* Your other global styles */
170
+ ```
171
+
172
+ ---
173
+
174
+ ### Vue.js (Vite or Vue CLI)
175
+
176
+ #### Using in main entry point
177
+
178
+ **In your main entry file (`src/main.ts` or `src/main.js`):**
179
+
180
+ ```ts
181
+ import { createApp } from 'vue'
182
+ import '@mindvalley/design-system/typography/mindvalley/fonts.css'
183
+ import App from './App.vue'
184
+
185
+ createApp(App).mount('#app')
186
+ ```
187
+
188
+ #### Using in a component
189
+
190
+ **In a single file component:**
191
+
192
+ ```vue
193
+ <template>
194
+ <div>
195
+ <h1 class="title-bold-5">Welcome to Mindvalley</h1>
196
+ <p class="body">This uses design system typography.</p>
197
+ </div>
198
+ </template>
199
+
200
+ <style>
201
+ @import '@mindvalley/design-system/typography/mindvalley/fonts.css';
202
+ </style>
203
+ ```
204
+
205
+ #### Using in global CSS
206
+
207
+ **In your global CSS file (`src/assets/main.css`):**
208
+
209
+ ```css
210
+ @import '@mindvalley/design-system/typography/mindvalley/fonts.css';
211
+
212
+ /* Your other global styles */
213
+ ```
214
+
215
+ Then import it in your main entry:
216
+
217
+ ```ts
218
+ import { createApp } from 'vue'
219
+ import './assets/main.css'
220
+ import App from './App.vue'
221
+
222
+ createApp(App).mount('#app')
223
+ ```
224
+
225
+ #### Composition API with programmatic usage
226
+
227
+ If you need to access font CSS programmatically:
228
+
229
+ ```vue
230
+ <script setup>
231
+ import { fontFaceCSS } from '@mindvalley/design-system/typography/mindvalley/fonts'
232
+
233
+ // Inject into head if needed
234
+ const injectFonts = () => {
235
+ const style = document.createElement('style')
236
+ style.textContent = fontFaceCSS
237
+ document.head.appendChild(style)
238
+ }
239
+ </script>
240
+ ```
241
+
242
+ ---
243
+
244
+ ### Webpack
245
+
246
+ #### Using in entry point
247
+
248
+ **In your main JavaScript/TypeScript file:**
249
+
250
+ ```js
251
+ import '@mindvalley/design-system/typography/mindvalley/fonts.css'
252
+ ```
253
+
254
+ #### Webpack configuration
255
+
256
+ Ensure your webpack config has CSS loading capability:
257
+
258
+ ```js
259
+ module.exports = {
260
+ module: {
261
+ rules: [
262
+ {
263
+ test: /\.css$/i,
264
+ use: ['style-loader', 'css-loader'],
265
+ },
266
+ ],
267
+ },
268
+ }
269
+ ```
270
+
271
+ ---
272
+
273
+ ### Phoenix (Elixir)
274
+
275
+ #### Using with esbuild (Phoenix 1.6+)
276
+
277
+ **1. Import in your app.js:**
278
+
279
+ ```js
280
+ // assets/js/app.js
281
+ import '@mindvalley/design-system/typography/mindvalley/fonts.css'
282
+ ```
283
+
284
+ **2. Ensure CSS is configured in `config/config.exs`:**
285
+
286
+ ```elixir
287
+ config :esbuild,
288
+ version: "0.17.11",
289
+ default: [
290
+ args: ~w(js/app.js --bundle --target=es2017 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
291
+ cd: Path.expand("../assets", __DIR__),
292
+ env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
293
+ ]
294
+ ```
295
+
296
+ #### Using with Webpack (Phoenix 1.5 and below)
297
+
298
+ **1. Import in your app.js:**
299
+
300
+ ```js
301
+ // assets/js/app.js
302
+ import '@mindvalley/design-system/typography/mindvalley/fonts.css'
303
+ ```
304
+
305
+ **2. Ensure webpack config has CSS loader:**
306
+
307
+ ```js
308
+ // assets/webpack.config.js
309
+ module.exports = {
310
+ module: {
311
+ rules: [
312
+ {
313
+ test: /\.css$/,
314
+ use: ['style-loader', 'css-loader']
315
+ }
316
+ ]
317
+ }
318
+ }
319
+ ```
320
+
321
+ #### Using with PostCSS and SCSS @import (Phoenix Webpack + SCSS)
322
+
323
+ If you're using SCSS files with `@import` statements instead of JavaScript imports, you'll need to configure `postcss-import` to resolve from `node_modules`:
324
+
325
+ **1. Configure PostCSS (`assets/postcss.config.js`):**
326
+
327
+ ```js
328
+ module.exports = {
329
+ plugins: [
330
+ require('postcss-import')({
331
+ path: ['node_modules']
332
+ }),
333
+ require('tailwindcss'),
334
+ require('autoprefixer')
335
+ ],
336
+ }
337
+ ```
338
+
339
+ **2. Import in your SCSS file (`assets/css/app.scss`):**
340
+
341
+ ```scss
342
+ @import '@mindvalley/design-system/dist/typography/mindvalley/fonts.css';
343
+ ```
344
+
345
+ > **Note:** When using `@import` with `postcss-import`, you must use the full `dist/` path since postcss-import doesn't use package export resolution like modern JavaScript bundlers do.
346
+
347
+ ---
348
+
349
+ ## CSS-in-JS solutions
350
+
351
+ ### Styled Components
352
+
353
+ **Using global styles:**
354
+
355
+ ```tsx
356
+ import { createGlobalStyle } from 'styled-components'
357
+ import { fontFaceCSS } from '@mindvalley/design-system/typography/mindvalley/fonts'
358
+
359
+ const GlobalStyles = createGlobalStyle`
360
+ ${fontFaceCSS}
361
+
362
+ /* Your other global styles */
363
+ body {
364
+ font-family: 'Sharp Grotesk Cyr Book 19', sans-serif;
365
+ }
366
+ `
367
+
368
+ export default function App() {
369
+ return (
370
+ <>
371
+ <GlobalStyles />
372
+ {/* Your app content */}
373
+ </>
374
+ )
375
+ }
376
+ ```
377
+
378
+ ---
379
+
380
+ ## JavaScript/TypeScript module usage
381
+
382
+ For programmatic use cases where you need the CSS as a string:
383
+
384
+ ### ES modules
385
+
386
+ ```typescript
387
+ import { fontFaceCSS } from '@mindvalley/design-system/typography/mindvalley/fonts'
388
+
389
+ // Inject into a style tag
390
+ const styleElement = document.createElement('style')
391
+ styleElement.textContent = fontFaceCSS
392
+ document.head.appendChild(styleElement)
393
+ ```
394
+
395
+ ### CommonJS
396
+
397
+ ```javascript
398
+ const { fontFaceCSS } = require('@mindvalley/design-system/typography/mindvalley/fonts')
399
+
400
+ // Use the CSS string as needed
401
+ console.log(fontFaceCSS)
402
+ ```
403
+
404
+ ---
405
+
406
+ ## Brand-specific examples
407
+
408
+ ### Mindvalley brand project
409
+
410
+ ```tsx
411
+ // src/main.tsx
412
+ import '@mindvalley/design-system/typography/mindvalley/fonts.css'
413
+ import { colors } from '@mindvalley/design-system'
414
+
415
+ // Now use Mindvalley typography classes
416
+ function Hero() {
417
+ return (
418
+ <h1 className="title-bold-1" style={{ color: colors.brandAccent }}>
419
+ Welcome to Mindvalley
420
+ </h1>
421
+ )
422
+ }
423
+ ```
424
+
425
+ ### B2B brand project
426
+
427
+ ```tsx
428
+ // src/main.tsx
429
+ import '@mindvalley/design-system/typography/b2b/fonts.css'
430
+ import { colors } from '@mindvalley/design-system/b2b'
431
+
432
+ // Now use B2B typography classes
433
+ function Hero() {
434
+ return (
435
+ <h1 className="title-bold-1" style={{ color: colors.brandAccent }}>
436
+ Welcome to Mindvalley B2B
437
+ </h1>
438
+ )
439
+ }
440
+ ```
441
+
442
+ ### Multi-brand project
443
+
444
+ If your application needs to support both brands (e.g., a platform that serves both consumer and B2B users):
445
+
446
+ ```tsx
447
+ // src/main.tsx
448
+ import '@mindvalley/design-system/typography/mindvalley/fonts.css'
449
+ import '@mindvalley/design-system/typography/b2b/fonts.css'
450
+
451
+ // Now both brand fonts are available
452
+ function App() {
453
+ const isBB2User = checkUserType() // Your logic
454
+
455
+ return (
456
+ <div className={isBB2User ? 'b2b-theme' : 'mindvalley-theme'}>
457
+ {/* Your app content */}
458
+ </div>
459
+ )
460
+ }
461
+ ```
462
+
463
+ ---
464
+
465
+ ## Best practices
466
+
467
+ ### Performance optimization
468
+
469
+ 1. **Only Import What You Need**: If you only use one brand, only import that brand's fonts.
470
+
471
+ 2. **Use `font-display: swap`**: All generated font files use `font-display: swap` by default, which shows fallback text immediately and swaps to custom fonts when loaded.
472
+
473
+ 3. **Preload Critical Fonts** (Optional): For even better performance, you can preload the most critical font files:
474
+
475
+ ```html
476
+ <link rel="preload" href="https://assets.mindvalley.com/api/v1/assets/b61f86ec-3dbd-4674-907a-f3f26f5101ce.woff2" as="font" type="font/woff2" crossorigin>
477
+ ```
478
+
479
+ ### Font loading strategy
480
+
481
+ The fonts are loaded with `font-display: swap`, which means:
482
+
483
+ 1. Text is immediately visible using fallback fonts (Helvetica, Arial, sans-serif)
484
+ 2. Custom fonts load in the background
485
+ 3. Text swaps to custom fonts once loaded
486
+ 4. No layout shift since line heights are optimized
487
+
488
+ ### Fallback fonts
489
+
490
+ All typography classes include proper fallback fonts:
491
+
492
+ ```css
493
+ font-family: 'Sharp Grotesk Cyr Book 19', Helvetica, Arial, sans-serif;
494
+ ```
495
+
496
+ ---
497
+
498
+ ## Troubleshooting
499
+
500
+ ### Fonts not loading
501
+
502
+ 1. **Check Import Path**: Ensure you're using the correct import path with `/typography/` in the path.
503
+ 2. **Build Configuration**: Verify your bundler is configured to handle CSS imports from node_modules.
504
+ 3. **PostCSS Import**: If using `@import` in SCSS/CSS files, ensure `postcss-import` is configured with `path: ['node_modules']`. See [PostCSS configuration](#using-with-postcss-and-scss-import-phoenix-webpack--scss).
505
+ 4. **CDN Access**: Ensure your application can access the Fastly CDN URLs.
506
+
507
+ ### TypeScript errors
508
+
509
+ If you get TypeScript errors when importing CSS:
510
+
511
+ ```typescript
512
+ // Add to your tsconfig.json or create a declaration file
513
+ declare module '*.css' {
514
+ const content: string
515
+ export default content
516
+ }
517
+ ```
518
+
519
+ Or specifically for the design system:
520
+
521
+ ```typescript
522
+ // src/types/design-system.d.ts
523
+ declare module '@mindvalley/design-system/typography/*/fonts' {
524
+ export const fontFaceCSS: string
525
+ export default fontFaceCSS
526
+ }
527
+ ```
528
+
529
+ ### Webpack/bundler issues
530
+
531
+ Ensure you have the appropriate loaders installed:
532
+
533
+ ```bash
534
+ npm install --save-dev style-loader css-loader
535
+ ```
536
+
537
+ ---
538
+
539
+ ## Related documentation
540
+
541
+ - [Typography Plugin Usage](./USAGE.md#%EF%B8%8F-typography) - How to use typography classes
542
+ - [Color System](./USAGE.md#-colors) - Working with design system colors
543
+ - [Icon System](./USAGE.md#%EF%B8%8F-icons) - Using design system icons
544
+
545
+ ---
546
+
547
+ ## Support
548
+
549
+ For issues or questions:
550
+
551
+ - [GitHub Issues](https://github.com/mindvalley/mv-design-system/issues)
552
+ - [Design System Documentation](../README.md)
@@ -0,0 +1,156 @@
1
+ ****# Typography Token Pipeline (B2B)
2
+
3
+ This document explains, end‑to‑end, how B2B typography tokens are processed in this repository: where they start, which hooks/transforms/filters run, and what the final output is. It also highlights the current gap around using group‑level `description` during transforms and options to fix it.
4
+
5
+ ## Problem Statement
6
+
7
+ We want to use the typography group’s `description` (e.g., "Sharp Grotesk … 20/21/22") to build the final `fontFamily` string. However, leaf tokens (base/mobile/tablet/desktop) do not surface that parent `description` in transforms, so `getFontFamily` cannot read it directly.
8
+
9
+ ## Initial State (Source Tokens)
10
+
11
+ - Location: `src/tokens/brands/b2b/typography.json`
12
+ - Origin: Exported by Supernova.
13
+ - Shape:
14
+ - Nested groups under `typography` (e.g., `deprecated-mobile`, `header`, `display`, `heading‑1`, …)
15
+ - Leaf tokens look like `{ value: { fontFamily, fontSize, lineHeight, letterSpacing, ... }, type: 'typography' }`
16
+ - The group’s human‑readable descriptor lives on the group as `description` (e.g., on `display‑1`, `heading‑6`, etc.), not on the leaf tokens.
17
+
18
+ Example (condensed):
19
+
20
+ ```json
21
+ {
22
+ "typography": {
23
+ "header": {
24
+ "heading-6": {
25
+ "base": { "value": { "fontFamily": "Sharp Grotesk Cyr Medium", "fontSize": "16px", ... }, "type": "typography" },
26
+ "mobile": { "value": { ... }, "type": "typography" },
27
+ "desktop": { "value": { ... }, "type": "typography" },
28
+ "description": "Sharp Grotesk Cyr Medium 20"
29
+ }
30
+ }
31
+ }
32
+ }
33
+ ```
34
+
35
+ ## Build Entry
36
+
37
+ - Command: `npm run build:styledictionary`
38
+ - Script: `ts-node ./build.ts`
39
+ - Brands built: currently `b2b` (see `build.ts`)
40
+
41
+ ## Registration (build.ts)
42
+
43
+ - Transforms registered: from `src/utilities/style-dictonary/transforms` (color, typography, naming), plus SD built‑ins.
44
+ - Transform groups (`src/utilities/style-dictonary/transformGroups/index.ts`):
45
+ - `js-object`: `['attribute/cti', 'font/object', 'name/ti/kebab', 'name/ts/kebab']`
46
+ - `js-ti`: `['attribute/cti', 'color/rgbaOrHex', 'name/ti/kebab']`
47
+ - Filters: `b2b-typography` / `mindvalley-typography` from `src/utilities/style-dictonary/filters`.
48
+ - Formats: `typescript/module-flat` from `src/utilities/style-dictonary/formats/typescript.ts`.
49
+
50
+ Note: `typography/responsive` transform is registered but not referenced in `js-object`. Responsive consolidation currently happens in the formatter (`formatters/responsiveTypography.ts`).
51
+
52
+ ## Platform Config (build.ts → getStyleDictionaryConfig)
53
+
54
+ - `source`: `src/tokens/brands/b2b/*.json`
55
+ - Platforms:
56
+ - `js` platform
57
+ - `transformGroup`: `js-ti`
58
+ - Outputs color tokens to `src/build/js/b2b/colors.js`
59
+ - `typography` platform
60
+ - `transformGroup`: `js-object`
61
+ - `filter`: `b2b-typography`
62
+ - `format`: `typescript/module-flat`
63
+ - Output: `src/tailwind/plugins/tokens/b2b/typography.ts`
64
+
65
+ ## Processing Sequence (Typography)
66
+
67
+ 1) Source ingestion
68
+
69
+ - Style Dictionary reads `src/tokens/brands/b2b/typography.json` into a token tree.
70
+ - Built‑in `attribute/cti` later derives `token.attributes` (`category`, `type`, `item`, …) from `token.path`.
71
+
72
+ 2) Filter
73
+
74
+ - The file entry for typography uses the `b2b-typography` filter to keep only typography tokens under the desired categories (`display`, `header`, `heading`) and exclude deprecated ones.
75
+
76
+ 3) Transform group: `js-object`
77
+
78
+ - `attribute/cti` (built‑in): populates `token.attributes` used by subsequent transforms.
79
+ - `font/object` (`src/utilities/style-dictonary/transforms/typography.ts`):
80
+ - Filter: only typography tokens (`token.attributes.category === 'typography'`).
81
+ - Builds a normalized value object:
82
+ - `fontFamily`: via `getFontFamily(token)`.
83
+ - `fontSize`, `lineHeight`, `letterSpacing`: normalized to strings; accepts both structured measure/unit and simple strings like `"80px"`.
84
+ - `getFontFamily(token)`
85
+ - Intended to prefer a Sharp Grotesk face derived from the group’s descriptor.
86
+ - Fallback to a mapping for known family names.
87
+ - Current limitation: transforms do not receive the group’s `description` on leaf tokens; neither `token.original.description` nor `token.comment` is populated by default for this source.
88
+ - `name/ti/kebab` and `name/ts/kebab` (naming transforms): compute token names based on path/type.
89
+
90
+ 4) Format: `typescript/module-flat`
91
+
92
+ - File: `src/utilities/style-dictonary/formats/typescript.ts`.
93
+ - Uses `groupAndOptimizeTokens` (`formatters/responsiveTypography.ts`) to:
94
+ - Deduplicate path segments (e.g., remove category prefix redundancies).
95
+ - Decide whether to emit single tokens or `-mobile`/`-desktop` responsive variants by comparing values across breakpoints.
96
+ - Produce the final JS object with `fontFamily`, `fontSize`, `letterSpacing`, `lineHeight`, `fontWeight?`.
97
+ - Output file: `src/tailwind/plugins/tokens/b2b/typography.ts` (TypeScript module with an interface + token object).
98
+
99
+ ## End State (Artifacts)
100
+
101
+ - Colors: `src/build/js/b2b/colors.js` (if any)
102
+ - Typography: `src/tailwind/plugins/tokens/b2b/typography.ts`
103
+ - Contains a flat object keyed by token names (some with `-mobile` and `-desktop`).
104
+ - Values are normalized strings; `fontFamily` uses mapping or description logic if available.
105
+
106
+ ## Sequence Diagram (Typography Flow)
107
+
108
+ ```mermaid
109
+ flowchart TD
110
+ A[Source JSON\nsrc/tokens/brands/b2b/typography.json] --> B[Style Dictionary Config\n(build.ts)]
111
+ B --> C[Filter: b2b-typography]
112
+ C --> D[Transform Group: js-object]
113
+ D --> D1[attribute/cti]
114
+ D1 --> D2[font/object\n(getFontFamily, unit normalization)]
115
+ D2 --> D3[name/ti/kebab + name/ts/kebab]
116
+ D3 --> E[Format: typescript/module-flat\n(groupAndOptimizeTokens)]
117
+ E --> F[Output\nsrc/tailwind/plugins/tokens/b2b/typography.ts]
118
+ ```
119
+
120
+ ## Current Gap (Root Cause)
121
+
122
+ - The typography group’s `description` is defined on the group (e.g., `heading-6`) and is not present on leaf tokens (`base`/`mobile`/`tablet`/`desktop`).
123
+ - Style Dictionary does not, by default, surface that parent `description` on the leaf token objects available to transforms:
124
+ - `token.original.description` → empty
125
+ - `token.original.$description` → empty
126
+ - `token.comment` → empty
127
+ - Attempts to inject description via parser or preprocessor did not appear in `token.comment` or `token.original` during transforms in this pipeline, so `getFontFamily` cannot use it directly.
128
+
129
+ ## Options to Resolve
130
+
131
+ - Formatter‑based resolution (recommended, minimal)
132
+ - In the formatter, use `dictionary.tokens` and `token.path` to find the parent group node and read its `description`. Build the `fontFamily` string there.
133
+ - Pros: Full dictionary context; no reliance on transform‑time token shape.
134
+ - Cons: Couples font family logic to this formatter (acceptable given current architecture).
135
+
136
+ - Preprocessor (central normalization)
137
+ - Use a preprocessor to copy the nearest group `description` onto leaf tokens as `comment` and/or `$description` before transforms.
138
+ - Ensure it operates on SD v5 `$value`/`$type` schema if needed.
139
+ - Pros: Keeps transforms simple; consistent across formats.
140
+ - Cons: Needs careful verification that the hook runs on our inputs; our initial attempt didn’t surface values during transforms.
141
+
142
+ - Upstream token export change
143
+ - Adjust Supernova export to include the `description` on leaves (as `comment` or `$description`).
144
+ - Pros: Zero build‑time logic; most robust long‑term.
145
+ - Cons: Requires coordination/change to export settings.
146
+
147
+ ## Where the Issue Is
148
+
149
+ - Stage: Transform (`font/object` → `getFontFamily`).
150
+ - Symptom: No access to group‑level descriptor (`description`) on leaf tokens at transform time.
151
+ - Impact: `fontFamily` can’t be built using the intended descriptor; fallback mapping is used instead.
152
+
153
+ ## Next Step (Proposed)
154
+
155
+ - Implement formatter‑based descriptor lookup for `fontFamily` in `typescript/module-flat` (using `dictionary` + `path`).
156
+ - Alternatively, finalize a preprocessor that provably runs on our inputs and sets `token.comment` for transforms.