@mastors/core 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +940 -0
  3. package/api/_index.scss +5 -0
  4. package/dist/mastors-core.css +7419 -0
  5. package/dist/mastors-core.css.map +1 -0
  6. package/package.json +73 -0
  7. package/postinstall.js +41 -0
  8. package/scripts/generate-tokens.js +259 -0
  9. package/scss/abstracts/_index.scss +6 -0
  10. package/scss/abstracts/_maps.scss +9 -0
  11. package/scss/abstracts/_placeholders.scss +7 -0
  12. package/scss/accessibility/_focus.scss +21 -0
  13. package/scss/accessibility/_index.scss +7 -0
  14. package/scss/accessibility/_motion.scss +14 -0
  15. package/scss/accessibility/_print.scss +52 -0
  16. package/scss/accessibility/_screen-reader.scss +31 -0
  17. package/scss/api/_index.scss +14 -0
  18. package/scss/base/_box-sizing.scss +6 -0
  19. package/scss/base/_index.scss +7 -0
  20. package/scss/base/_reset.scss +59 -0
  21. package/scss/base/_root.scss +43 -0
  22. package/scss/base/_typography-base.scss +40 -0
  23. package/scss/config/_flags.scss +13 -0
  24. package/scss/config/_index.scss +12 -0
  25. package/scss/config/_settings.scss +18 -0
  26. package/scss/functions/_color.scss +66 -0
  27. package/scss/functions/_em.scss +28 -0
  28. package/scss/functions/_index.scss +15 -0
  29. package/scss/functions/_map-helpers.scss +29 -0
  30. package/scss/functions/_math.scss +40 -0
  31. package/scss/functions/_rem.scss +27 -0
  32. package/scss/functions/_string.scss +57 -0
  33. package/scss/functions/_vars.scss +49 -0
  34. package/scss/generators/_class-generator.scss +83 -0
  35. package/scss/generators/_custom-property-generator.scss +29 -0
  36. package/scss/generators/_index.scss +6 -0
  37. package/scss/generators/_responsive-generator.scss +28 -0
  38. package/scss/helpers/_clearfix.scss +9 -0
  39. package/scss/helpers/_index.scss +7 -0
  40. package/scss/helpers/_ratio.scss +22 -0
  41. package/scss/helpers/_truncate.scss +25 -0
  42. package/scss/helpers/_visually-hidden.scss +39 -0
  43. package/scss/index.scss +41 -0
  44. package/scss/mixins/_breakpoint.scss +33 -0
  45. package/scss/mixins/_container.scss +20 -0
  46. package/scss/mixins/_elevation.scss +12 -0
  47. package/scss/mixins/_index.scss +9 -0
  48. package/scss/mixins/_pseudo.scss +13 -0
  49. package/scss/mixins/_theme.scss +31 -0
  50. package/scss/mixins/_transition.scss +20 -0
  51. package/scss/responsive/_container-queries.scss +31 -0
  52. package/scss/responsive/_engine.scss +65 -0
  53. package/scss/responsive/_fluid-type.scss +40 -0
  54. package/scss/responsive/_index.scss +6 -0
  55. package/scss/semantic/_colors.scss +29 -0
  56. package/scss/semantic/_index.scss +6 -0
  57. package/scss/semantic/_spacing.scss +13 -0
  58. package/scss/semantic/_typography.scss +13 -0
  59. package/scss/themes/_base-theme.scss +28 -0
  60. package/scss/themes/_dark.scss +59 -0
  61. package/scss/themes/_index.scss +6 -0
  62. package/scss/themes/_light.scss +31 -0
  63. package/scss/tokens/_color.scss +100 -0
  64. package/scss/tokens/_index.scss +12 -0
  65. package/scss/tokens/_opacity.scss +28 -0
  66. package/scss/tokens/_radii.scss +21 -0
  67. package/scss/tokens/_shadows.scss +20 -0
  68. package/scss/tokens/_sizing.scss +47 -0
  69. package/scss/tokens/_spacing.scss +48 -0
  70. package/scss/tokens/_transitions.scss +27 -0
  71. package/scss/tokens/_typography.scss +63 -0
  72. package/scss/tokens/_z-index.scss +21 -0
  73. package/scss/utilities/_animation.scss +125 -0
  74. package/scss/utilities/_borders.scss +55 -0
  75. package/scss/utilities/_colors.scss +42 -0
  76. package/scss/utilities/_cursor.scss +28 -0
  77. package/scss/utilities/_display.scss +26 -0
  78. package/scss/utilities/_index.scss +20 -0
  79. package/scss/utilities/_interaction.scss +156 -0
  80. package/scss/utilities/_layout.scss +162 -0
  81. package/scss/utilities/_opacity.scss +9 -0
  82. package/scss/utilities/_overflow.scss +36 -0
  83. package/scss/utilities/_pointer-events.scss +6 -0
  84. package/scss/utilities/_position.scss +32 -0
  85. package/scss/utilities/_shadows.scss +11 -0
  86. package/scss/utilities/_sizing.scss +40 -0
  87. package/scss/utilities/_spacing.scss +42 -0
  88. package/scss/utilities/_transform.scss +43 -0
  89. package/scss/utilities/_typography.scss +163 -0
  90. package/scss/utilities/_z-index.scss +9 -0
  91. package/scss/variables/_breakpoints.scss +14 -0
  92. package/scss/variables/_container.scss +13 -0
  93. package/scss/variables/_global.scss +8 -0
  94. package/scss/variables/_grid.scss +7 -0
  95. package/scss/variables/_index.scss +7 -0
  96. package/scss/vendors/_index.scss +15 -0
package/README.md ADDED
@@ -0,0 +1,940 @@
1
+ # @mastors/core
2
+
3
+ > The foundational layer of the Mastors ecosystem — design tokens, SCSS functions, mixins, generators, reset, responsive engine, and theme system.
4
+
5
+ [![npm](https://img.shields.io/npm/v/@mastors/core.svg)](https://www.npmjs.com/package/@mastors/core)
6
+ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
7
+ [![sass](https://img.shields.io/badge/requires-sass%20%3E%3D1.80-CC6699.svg)](https://sass-lang.com)
8
+
9
+ ---
10
+
11
+ ## Table of Contents
12
+
13
+ - [Overview](#overview)
14
+ - [Installation](#installation)
15
+ - [Usage](#usage)
16
+ - [Full stylesheet import](#full-stylesheet-import)
17
+ - [Public API (zero output)](#public-api-zero-output)
18
+ - [TypeScript / JavaScript](#typescript--javascript)
19
+ - [Configuration](#configuration)
20
+ - [Feature flags](#feature-flags)
21
+ - [Dark mode strategy](#dark-mode-strategy)
22
+ - [Class prefix](#class-prefix)
23
+ - [Config via public API](#config-via-public-api)
24
+ - [Design Tokens](#design-tokens)
25
+ - [Color](#color)
26
+ - [Spacing](#spacing)
27
+ - [Typography](#typography)
28
+ - [Border Radius](#border-radius)
29
+ - [Shadows](#shadows)
30
+ - [Z-Index](#z-index)
31
+ - [Opacity](#opacity)
32
+ - [Transitions](#transitions)
33
+ - [Functions](#functions)
34
+ - [vars()](#vars)
35
+ - [Mixins](#mixins)
36
+ - [Breakpoints](#breakpoints)
37
+ - [Theme](#theme)
38
+ - [Elevation](#elevation)
39
+ - [Transition](#transition)
40
+ - [Container](#container)
41
+ - [Pseudo](#pseudo)
42
+ - [Responsive Engine](#responsive-engine)
43
+ - [Container Queries](#container-queries)
44
+ - [Fluid Typography](#fluid-typography)
45
+ - [Theme System](#theme-system)
46
+ - [Base Layer](#base-layer)
47
+ - [Utility Classes](#utility-classes)
48
+ - [Helpers](#helpers)
49
+ - [Accessibility](#accessibility)
50
+ - [Generator Engine](#generator-engine)
51
+ - [Semantic Layer](#semantic-layer)
52
+ - [Known Stubs](#known-stubs)
53
+ - [Package Exports](#package-exports)
54
+ - [Peer Dependencies](#peer-dependencies)
55
+ - [Changelog](#changelog)
56
+
57
+ ---
58
+
59
+ ## Overview
60
+
61
+ `@mastors/core` is the only required package in the Mastors ecosystem. It provides:
62
+
63
+ - **Design tokens** — color, spacing, typography, radius, shadows, z-index, opacity, and transitions as SCSS maps
64
+ - **Functions** — `rem()`, `em()`, `color()`, `spacing()`, `tint()`, `shade()`, `alpha()`, `contrast()`, `fluid()`, `map-deep-get()`, `map-collect()`, `str-replace()`, `vars()`
65
+ - **Mixins** — `bp()`, `dark-mode()`, `light-mode()`, `theme()`, `elevation()`, `transition()`, `container()`, `pseudo()`
66
+ - **Generator engine** — `generate-utilities()`, `emit-custom-properties()`, and responsive-generator mixins used by all utility packages
67
+ - **Reset** — modern CSS reset and document defaults
68
+ - **Theme system** — CSS custom property-based light/dark theming with a full semantic contract
69
+ - **Responsive engine** — breakpoint-aware utility variant generation (`sm:`, `md:`, `lg:`, `xl:`, `2xl:`)
70
+ - **Container queries** — `.cq-inline`, `.cq-size`, `cq()` mixin for `@container` rules
71
+ - **Fluid typography** — `fluid-type()` mixin and function using `clamp()`
72
+ - **Utility classes** — display, position, overflow, spacing, sizing, colors, borders (full directional radius scale), shadows, opacity, cursor, z-index, transforms, typography, animation, interaction, layout (aspect-ratio, object-fit/position, blend modes)
73
+ - **Accessibility** — focus ring, reduced-motion, screen-reader utilities, print layer
74
+ - **TypeScript types and runtime token mirror**
75
+
76
+ All other `@mastors/*` packages consume `@mastors/core/api` for shared tokens, functions, and mixins.
77
+
78
+ ---
79
+
80
+ ## Installation
81
+
82
+ ```bash
83
+ npm install @mastors/core sass
84
+ # or
85
+ pnpm add @mastors/core sass
86
+ ```
87
+
88
+ `sass >= 1.80.0` is required as a peer dependency.
89
+
90
+ ---
91
+
92
+ ## Usage
93
+
94
+ ### Full stylesheet import
95
+
96
+ Import the complete compiled stylesheet — reset, tokens, themes, utilities, helpers, and accessibility:
97
+
98
+ ```scss
99
+ @use "@mastors/core/scss";
100
+ ```
101
+
102
+ ### Public API (zero output)
103
+
104
+ Import only the public API surface. No CSS is emitted — you get access to all tokens, functions, mixins, and config:
105
+
106
+ ```scss
107
+ @use "@mastors/core/api" as m;
108
+
109
+ .card {
110
+ padding: m.spacing(6);
111
+ background-color: m.color("neutral", 50);
112
+ border-radius: m.radius("xl");
113
+ box-shadow: m.vars(shadow-md);
114
+ transition: box-shadow m.vars(duration-200) m.vars(ease-out);
115
+
116
+ @include m.bp("lg") {
117
+ padding: m.spacing(10);
118
+ }
119
+
120
+ @include m.dark-mode {
121
+ background-color: m.color("neutral", 800);
122
+ color: m.color("neutral", 100);
123
+ }
124
+ }
125
+ ```
126
+
127
+ ### TypeScript / JavaScript
128
+
129
+ Access design token values at runtime for CSS-in-JS, design tools, or testing:
130
+
131
+ ```ts
132
+ import { tokens } from '@mastors/core'
133
+
134
+ const primary600 = tokens.color.primary['600'] // '#2563eb'
135
+ const spacing4 = tokens.spacing['4'] // '1rem'
136
+ const shadowMd = tokens.shadow.md // '0 4px 6px ...'
137
+ const radiusXl = tokens.radius.xl // '0.75rem'
138
+ const duration200 = tokens.duration['200'] // '200ms'
139
+ ```
140
+
141
+ Import TypeScript types:
142
+
143
+ ```ts
144
+ import type {
145
+ MastorsConfig,
146
+ Breakpoint,
147
+ ThemeMode,
148
+ Tokens,
149
+ ColorPalette,
150
+ SpacingKey,
151
+ RadiusKey,
152
+ } from '@mastors/core'
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Configuration
158
+
159
+ Override the global config map before importing core to customise behaviour. The config must be set before any `@use "@mastors/core"` statement in your project.
160
+
161
+ ```scss
162
+ // styles/_config.scss — set BEFORE @use "@mastors/core"
163
+ @use "@mastors/core/scss/config/settings" with (
164
+ $mastors-config: (
165
+ "prefix": "", // optional class prefix, e.g. "m-" -> .m-flex
166
+ "important": false, // append !important to all utility declarations
167
+ "dark-mode": "class", // "class" | "media"
168
+ "rtl": false, // enable RTL logical property variants
169
+ )
170
+ );
171
+ ```
172
+
173
+ ### Feature flags
174
+
175
+ Disable any layer you don't need to reduce output size:
176
+
177
+ ```scss
178
+ @use "@mastors/core/scss/config/flags" with (
179
+ $enable-utilities: true,
180
+ $enable-responsive: true,
181
+ $enable-helpers: true,
182
+ $enable-a11y: true,
183
+ $enable-themes: true,
184
+ );
185
+ ```
186
+
187
+ ### Dark mode strategy
188
+
189
+ **Class-based** (default) — add `.dark` or `data-theme="dark"` to `<html>`:
190
+
191
+ ```html
192
+ <html class="dark">...</html>
193
+ ```
194
+
195
+ **Media-query** — responds automatically to the OS preference:
196
+
197
+ ```scss
198
+ @use "@mastors/core/scss/config/settings" with (
199
+ $mastors-config: ("dark-mode": "media")
200
+ );
201
+ ```
202
+
203
+ ### Class prefix
204
+
205
+ Add a prefix to every generated utility class to prevent collisions:
206
+
207
+ ```scss
208
+ $mastors-config: ("prefix": "m-") !default;
209
+ // .m-flex, .m-block, .m-grid-cols-3, ...
210
+ ```
211
+
212
+ ### Config via public API
213
+
214
+ As of v1.2, both the `$mastors-config` map / `config()` accessor and all `$enable-*` flags are forwarded through the public API surface. Downstream consumers no longer need a direct partial import to read them:
215
+
216
+ ```scss
217
+ @use "@mastors/core/api" as m;
218
+
219
+ // Read a config value
220
+ $prefix: m.config("prefix");
221
+
222
+ // Read feature flags
223
+ @if m.$enable-responsive {
224
+ // emit responsive variants
225
+ }
226
+ ```
227
+
228
+ ---
229
+
230
+ ## Design Tokens
231
+
232
+ All tokens are available via the public API after `@use "@mastors/core/api" as m`.
233
+
234
+ ### Color
235
+
236
+ Six semantic palettes, each with 11 shades (50-950), plus `white`, `black`, and `transparent`.
237
+
238
+ ```scss
239
+ m.color("primary", 600) // #2563eb
240
+ m.color("neutral", 100) // #f3f4f6
241
+ m.color("success", 500) // #22c55e
242
+ m.color("warning", 400) // #fbbf24
243
+ m.color("error", 600) // #dc2626
244
+ m.color("info", 500) // #06b6d4
245
+ m.color("white") // #ffffff
246
+ m.color("black") // #000000
247
+ ```
248
+
249
+ Palettes: `primary` - `neutral` - `success` - `warning` - `error` - `info`
250
+
251
+ ### Spacing
252
+
253
+ 35-step scale from `0` to `96` (matching Tailwind's spacing scale):
254
+
255
+ ```scss
256
+ m.spacing(0) // 0px
257
+ m.spacing(1) // 0.25rem
258
+ m.spacing(4) // 1rem
259
+ m.spacing(8) // 2rem
260
+ m.spacing(16) // 4rem
261
+ m.spacing(96) // 24rem
262
+ ```
263
+
264
+ Half-step keys (`0.5`, `1.5`, `2.5`, `3.5`) are also available:
265
+
266
+ ```scss
267
+ m.spacing("0.5") // 0.125rem
268
+ m.spacing("1.5") // 0.375rem
269
+ ```
270
+
271
+ ### Typography
272
+
273
+ ```scss
274
+ // Font sizes (xs -> 9xl)
275
+ m.font-size("sm") // 0.875rem
276
+ m.font-size("base") // 1rem
277
+ m.font-size("2xl") // 1.5rem
278
+ m.font-size("5xl") // 3rem
279
+
280
+ // Font families
281
+ m.font-family("sans") // system-ui, -apple-system, ...
282
+ m.font-family("mono") // ui-monospace, SFMono-Regular, ...
283
+
284
+ // Font weights
285
+ m.font-weight("semibold") // 600
286
+ m.font-weight("bold") // 700
287
+
288
+ // Line heights
289
+ m.line-height("tight") // 1.25
290
+ m.line-height("normal") // 1.5
291
+
292
+ // Letter spacing
293
+ m.letter-spacing("wide") // 0.025em
294
+ ```
295
+
296
+ ### Border Radius
297
+
298
+ ```scss
299
+ m.radius("none") // 0px
300
+ m.radius("sm") // 0.125rem
301
+ m.radius("md") // 0.375rem
302
+ m.radius("lg") // 0.5rem
303
+ m.radius("xl") // 0.75rem
304
+ m.radius("2xl") // 1rem
305
+ m.radius("3xl") // 1.5rem
306
+ m.radius("full") // 9999px
307
+ ```
308
+
309
+ ### Shadows
310
+
311
+ ```scss
312
+ m.shadow("xs") // subtle shadow
313
+ m.shadow("sm") // small shadow
314
+ m.shadow("md") // medium shadow (default)
315
+ m.shadow("lg") // large shadow
316
+ m.shadow("xl") // extra large shadow
317
+ m.shadow("2xl") // page-level shadow
318
+ m.shadow("inner") // inset shadow
319
+ m.shadow("none") // none
320
+ ```
321
+
322
+ ### Z-Index
323
+
324
+ ```scss
325
+ m.z("base") // 0
326
+ m.z("raised") // 10
327
+ m.z("dropdown") // 100
328
+ m.z("sticky") // 200
329
+ m.z("overlay") // 300
330
+ m.z("modal") // 400
331
+ m.z("toast") // 500
332
+ m.z("tooltip") // 600
333
+ m.z("max") // 9999
334
+ ```
335
+
336
+ ### Opacity
337
+
338
+ ```scss
339
+ m.opacity("0") // 0
340
+ m.opacity("50") // 0.5
341
+ m.opacity("75") // 0.75
342
+ m.opacity("100") // 1
343
+ ```
344
+
345
+ ### Transitions
346
+
347
+ ```scss
348
+ m.duration("150") // 150ms
349
+ m.duration("200") // 200ms
350
+ m.duration("300") // 300ms
351
+
352
+ m.easing("in-out") // cubic-bezier(0.4, 0, 0.2, 1)
353
+ m.easing("out") // cubic-bezier(0, 0, 0.2, 1)
354
+ m.easing("bounce") // cubic-bezier(0.34, 1.56, 0.64, 1)
355
+ ```
356
+
357
+ ---
358
+
359
+ ## Functions
360
+
361
+ | Function | Description | Example |
362
+ |---|---|---|
363
+ | `rem($px)` | Convert px to rem | `rem(16px)` -> `1rem` |
364
+ | `em($px)` | Convert px to em | `em(16px)` -> `1em` |
365
+ | `color($palette, $shade)` | Get a color token | `color("primary", 600)` |
366
+ | `spacing($key)` | Get a spacing token | `spacing(4)` -> `1rem` |
367
+ | `radius($key)` | Get a radius token | `radius("xl")` -> `0.75rem` |
368
+ | `shadow($key)` | Get a shadow token | `shadow("md")` |
369
+ | `z($key)` | Get a z-index token | `z("modal")` -> `400` |
370
+ | `opacity($key)` | Get an opacity token | `opacity("50")` -> `0.5` |
371
+ | `duration($key)` | Get a duration token | `duration("200")` -> `200ms` |
372
+ | `easing($key)` | Get an easing token | `easing("in-out")` |
373
+ | `tint($c, $pct)` | Mix color with white | `tint(blue, 20%)` |
374
+ | `shade($c, $pct)` | Mix color with black | `shade(blue, 20%)` |
375
+ | `alpha($c, $a)` | Adjust alpha channel | `alpha(blue, 0.5)` |
376
+ | `contrast($bg)` | Black or white for contrast (1) | `contrast(#1e40af)` -> white |
377
+ | `fluid($min, $max)` | Clamp-based fluid value | `fluid(1rem, 2rem)` |
378
+ | `map-deep-get($map, $keys...)` | Deep nested map access | `map-deep-get($tokens, "primary", "600")` |
379
+ | `map-collect($maps...)` | Shallow-merge multiple maps | `map-collect($a, $b)` |
380
+ | `str-replace($str, $search)` | Replace substring | `str-replace("a-b", "-", "_")` |
381
+ | `vars($token, $fallback?)` | CSS custom property reference | `vars(shadow-md)` -> `var(--mastors-shadow-md)` |
382
+
383
+ (1) `contrast()` uses a simplified linear luminance approximation without sRGB gamma expansion. The threshold is set to `0.35` (not the WCAG `0.179`) to compensate for the missing gamma step — this gives correct results across the neutral scale. Suitable for UI decisions; implement full sRGB linearisation for strict WCAG 2.1 contrast-ratio auditing.
384
+
385
+ ### vars()
386
+
387
+ `vars()` lets you reference any emitted design token as a CSS custom property by name, without hard-coding the `--mastors-` prefix. If the token name ever changes or the prefix is reconfigured, only the function implementation needs to update — all call sites stay the same.
388
+
389
+ ```scss
390
+ @use "@mastors/core/api" as m;
391
+
392
+ .button {
393
+ // Basic token reference
394
+ color: m.vars(accent);
395
+ box-shadow: m.vars(shadow-sm);
396
+
397
+ // With CSS fallback (passed through verbatim)
398
+ background: m.vars(surface-raised, #f9fafb);
399
+ transition: opacity m.vars(duration-150) m.vars(ease-out);
400
+
401
+ &:hover {
402
+ box-shadow: m.vars(shadow-md);
403
+ transform: translateY(-1px);
404
+ }
405
+ }
406
+
407
+ // Composes cleanly with other values in shorthand properties
408
+ .chip {
409
+ border: 1px solid m.vars(border);
410
+ padding: m.rem(4px) m.rem(10px);
411
+ }
412
+ ```
413
+
414
+ Token names follow the same `--mastors-{name}` convention used in `:root`. Common examples:
415
+
416
+ | Call | Emits |
417
+ |---|---|
418
+ | `m.vars(accent)` | `var(--mastors-accent)` |
419
+ | `m.vars(surface)` | `var(--mastors-surface)` |
420
+ | `m.vars(shadow-lg)` | `var(--mastors-shadow-lg)` |
421
+ | `m.vars(duration-200)` | `var(--mastors-duration-200)` |
422
+ | `m.vars(ease-in-out)` | `var(--mastors-ease-in-out)` |
423
+ | `m.vars(border, #e5e7eb)` | `var(--mastors-border, #e5e7eb)` |
424
+
425
+ ---
426
+
427
+ ## Mixins
428
+
429
+ ### Breakpoints
430
+
431
+ Mobile-first, min-width media queries using the named breakpoint map.
432
+
433
+ ```scss
434
+ // Breakpoints: xs (0px) - sm (640px) - md (768px) - lg (1024px) - xl (1280px) - 2xl (1536px)
435
+
436
+ @include m.bp("md") {
437
+ // Applies at 768px and above
438
+ }
439
+
440
+ @include m.breakpoint-down("lg") {
441
+ // Applies below 1024px
442
+ }
443
+
444
+ // Aliases
445
+ @include m.respond-to("xl") { ... }
446
+ @include m.breakpoint-up("sm") { ... }
447
+ ```
448
+
449
+ ### Theme
450
+
451
+ ```scss
452
+ @include m.dark-mode {
453
+ // Activates when .dark is on <html> (class mode)
454
+ // or prefers-color-scheme: dark (media mode)
455
+ background-color: m.color("neutral", 900);
456
+ }
457
+
458
+ @include m.light-mode {
459
+ background-color: m.color("white");
460
+ }
461
+
462
+ @include m.theme("ocean") {
463
+ // Activates under [data-theme="ocean"]
464
+ --accent: #0891b2;
465
+ }
466
+ ```
467
+
468
+ ### Elevation
469
+
470
+ ```scss
471
+ @include m.elevation("sm"); // box-shadow: 0 1px 3px ...
472
+ @include m.elevation("lg"); // box-shadow: 0 10px 15px ...
473
+ @include m.elevation("none"); // box-shadow: none
474
+ ```
475
+
476
+ ### Transition
477
+
478
+ ```scss
479
+ // All properties, 200ms, in-out easing (defaults)
480
+ @include m.transition();
481
+
482
+ // Specific properties
483
+ @include m.transition((color, background-color), "150", "out");
484
+
485
+ // Custom combination
486
+ @include m.transition((transform, opacity), "300", "bounce");
487
+ ```
488
+
489
+ ### Container
490
+
491
+ ```scss
492
+ .page-section {
493
+ @include m.container();
494
+ // max-width per breakpoint, auto horizontal margins, configurable padding
495
+ }
496
+ ```
497
+
498
+ ### Pseudo
499
+
500
+ ```scss
501
+ .icon::before {
502
+ @include m.pseudo();
503
+ // Sets display: block, position: absolute, content: ""
504
+ }
505
+ ```
506
+
507
+ ---
508
+
509
+ ## Responsive Engine
510
+
511
+ The engine in `responsive/_engine.scss` wraps utility maps in breakpoint media queries. Sub-packages can call `@include engine.run($utilities)` directly for standalone use.
512
+
513
+ For the standard workflow, responsive variant generation is built into `generate-utilities()` — any utility entry that declares `responsive: true` automatically emits both base classes and breakpoint-prefixed variants in a single call. No separate invocation is required.
514
+
515
+ Generated class pattern: `.{breakpoint}\:{class}`
516
+
517
+ ```html
518
+ <!-- Responsive display -->
519
+ <div class="hidden md:block lg:flex">...</div>
520
+
521
+ <!-- Responsive position -->
522
+ <div class="relative md:absolute lg:sticky">...</div>
523
+
524
+ <!-- Responsive layout (from @mastors/flexer or @mastors/gridder) -->
525
+ <div class="flex flex-col md:flex-row lg:gap-8">...</div>
526
+ ```
527
+
528
+ Utilities with responsive support at v1.0: `display`, `position`.
529
+ Additional responsive utilities added in v1.2: `text-align`, `float`, `flex-direction` (via flexer), `grid-template-columns` (via gridder).
530
+
531
+ ---
532
+
533
+ ## Container Queries
534
+
535
+ Container queries are supported via `responsive/_container-queries.scss`.
536
+
537
+ **Setup classes:**
538
+
539
+ | Class | Effect |
540
+ |---|---|
541
+ | `.cq-inline` | `container-type: inline-size` |
542
+ | `.cq-size` | `container-type: size` |
543
+ | `.cq-normal` | `container-type: normal` |
544
+ | `[data-container]` | `container-type: inline-size` (attribute-based) |
545
+
546
+ **Usage:**
547
+
548
+ ```html
549
+ <div class="cq-inline">
550
+ <div class="child">Responds to container width, not viewport</div>
551
+ </div>
552
+ ```
553
+
554
+ ```scss
555
+ @use "@mastors/core/api" as m;
556
+
557
+ .child {
558
+ font-size: 1rem;
559
+
560
+ @include m.cq(40rem) {
561
+ font-size: 1.25rem;
562
+ }
563
+
564
+ // Named container query
565
+ @include m.cq(30rem, "card") {
566
+ padding: m.spacing(6);
567
+ }
568
+ }
569
+ ```
570
+
571
+ ---
572
+
573
+ ## Fluid Typography
574
+
575
+ `responsive/_fluid-type.scss` provides clamp()-based fluid font sizes that scale between two viewport widths without media queries.
576
+
577
+ ```scss
578
+ @use "@mastors/core/api" as m;
579
+
580
+ // As a mixin (applies font-size property)
581
+ h1 { @include m.fluid-type(2rem, 3.75rem); }
582
+
583
+ // As a function (use in any property value)
584
+ h1 { font-size: m.fluid-type(2rem, 3.75rem); }
585
+
586
+ // Custom viewport range
587
+ h2 { @include m.fluid-type(1.5rem, 3rem, 480px, 1440px); }
588
+ ```
589
+
590
+ Opt-in preset scale for all heading levels:
591
+
592
+ ```scss
593
+ @use "@mastors/core/scss/responsive/fluid-type" as ft;
594
+ @include ft.fluid-scale();
595
+ // Applies fluid-type() to h1-h6 and p
596
+ ```
597
+
598
+ ---
599
+
600
+ ## Theme System
601
+
602
+ Core emits all design tokens as `--mastors-*` CSS custom properties on `:root`. Theme layers override a semantic subset.
603
+
604
+ **Default (light) theme properties:**
605
+
606
+ ```css
607
+ :root {
608
+ --mastors-bg: #ffffff;
609
+ --mastors-bg-subtle: #f9fafb;
610
+ --mastors-surface: #ffffff;
611
+ --mastors-surface-raised: #f9fafb;
612
+ --mastors-surface-overlay: #f3f4f6;
613
+ --mastors-text: #111827;
614
+ --mastors-text-muted: #6b7280;
615
+ --mastors-text-subtle: #9ca3af;
616
+ --mastors-text-inverse: #ffffff;
617
+ --mastors-border: #e5e7eb;
618
+ --mastors-border-strong: #9ca3af;
619
+ --mastors-accent: #2563eb;
620
+ --mastors-accent-hover: #1d4ed8;
621
+ --mastors-accent-subtle: #eff6ff;
622
+ --mastors-accent-text: #ffffff;
623
+ }
624
+ ```
625
+
626
+ **Dark theme** activates via `.dark` on `<html>` (or `prefers-color-scheme` in media mode):
627
+
628
+ ```html
629
+ <html class="dark">...</html>
630
+ ```
631
+
632
+ Use semantic custom properties directly in your CSS for automatic theme switching:
633
+
634
+ ```css
635
+ .card {
636
+ background-color: var(--mastors-surface);
637
+ color: var(--mastors-text);
638
+ border-color: var(--mastors-border);
639
+ }
640
+ ```
641
+
642
+ Or use `vars()` in SCSS for the same result without the prefix noise:
643
+
644
+ ```scss
645
+ .card {
646
+ background-color: m.vars(surface);
647
+ color: m.vars(text);
648
+ border-color: m.vars(border);
649
+ }
650
+ ```
651
+
652
+ Custom themes can be applied with any `data-theme` attribute:
653
+
654
+ ```scss
655
+ @use "@mastors/core/api" as m;
656
+
657
+ @include m.theme("ocean") {
658
+ --mastors-accent: #0891b2;
659
+ --mastors-accent-hover: #0e7490;
660
+ }
661
+ ```
662
+
663
+ ```html
664
+ <div data-theme="ocean">
665
+ <!-- accent color is teal inside here -->
666
+ </div>
667
+ ```
668
+
669
+ ---
670
+
671
+ ## Base Layer
672
+
673
+ The base layer emits a modern CSS reset and document defaults when you import the full stylesheet:
674
+
675
+ - `box-sizing: border-box` on all elements (declared once in `_reset.scss`)
676
+ - Zero margin and padding on all elements
677
+ - `img`, `video`, `canvas`, `svg` set to `display: block; max-width: 100%`
678
+ - `input`, `button`, `textarea`, `select` inherit font
679
+ - Smooth scroll behaviour on `html`
680
+ - `-webkit-font-smoothing: antialiased` on `body`
681
+ - Base `color` and `background-color` on `html` driven by semantic custom properties
682
+ - Heading sizes (h1-h6) driven by the typography token scale
683
+ - Code/pre elements default to the mono font family
684
+
685
+ ---
686
+
687
+ ## Utility Classes
688
+
689
+ When importing the full stylesheet, core emits these utility classes:
690
+
691
+ | Group | Classes |
692
+ |---|---|
693
+ | Display | `.block` `.inline-block` `.inline` `.flex` `.inline-flex` `.grid` `.inline-grid` `.hidden` `.contents` `.table` `.table-cell` `.table-row` |
694
+ | Position | `.static` `.relative` `.absolute` `.fixed` `.sticky` - `.inset-*` `.top-*` `.right-*` `.bottom-*` `.left-*` |
695
+ | Overflow | `.overflow-auto/hidden/scroll/visible/clip` - `.overflow-x-*` `.overflow-y-*` |
696
+ | Spacing | `.m-*` `.mx-*` `.my-*` `.mt/r/b/l/s/e-*` - `.p-*` `.px-*` `.py-*` `.pt/r/b/l/s/e-*` - `.gap-*` `.gap-x-*` `.gap-y-*` |
697
+ | Sizing | `.w-*` `.h-*` - `.min-w-*` `.max-w-*` `.min-h-*` `.max-h-*` |
698
+ | Colors | `.text-*` `.bg-*` (all palettes x all shades + semantic) |
699
+ | Borders | `.border` `.border-*` `.rounded-*` `.rounded-{t\|b\|l\|r}-*` (full scale, all token steps) |
700
+ | Shadows | `.shadow-*` |
701
+ | Opacity | `.opacity-*` |
702
+ | Cursor | `.cursor-pointer` `.cursor-not-allowed` `.cursor-grab` etc. |
703
+ | Pointer events | `.pointer-events-none` `.pointer-events-auto` |
704
+ | Z-index | `.z-base` `.z-dropdown` `.z-modal` `.z-tooltip` etc. |
705
+ | Transforms | `.translate-x-*` `.translate-y-*` `.rotate-*` `.scale-*` `.origin-*` `.transform-gpu` `.transform-none` |
706
+ | Typography | `.text-{left\|center\|right\|justify\|start\|end}` (responsive) · `.text-{xs…9xl}` · `.font-{thin…black}` · `.font-{sans\|mono\|display}` · `.italic` `.not-italic` · `.leading-*` · `.tracking-*` · `.underline` `.overline` `.line-through` `.no-underline` · `.decoration-{solid\|dashed\|dotted\|double\|wavy}` · `.decoration-{1\|2\|4\|8}` · `.uppercase` `.lowercase` `.capitalize` `.normal-case` · `.text-ellipsis` `.text-clip` · `.whitespace-*` · `.break-normal` `.break-words` `.break-all` `.break-keep` · `.align-{baseline\|top\|middle\|bottom}` · `.list-none` `.list-disc` `.list-decimal` · `.antialiased` `.subpixel-antialiased` |
707
+ | Animation | `.transition` `.transition-{colors\|opacity\|shadow\|transform\|none\|all}` · `.duration-*` · `.ease-*` · `.delay-*` · `.animate-{spin\|ping\|pulse\|bounce\|fade-in\|fade-out\|slide-up\|slide-down\|scale-in\|none}` · `.fill-{none\|forwards\|backwards\|both}` · `.animation-{running\|paused}` · `.animate-repeat-{0\|1\|infinite}` |
708
+ | Interaction | `.select-{none\|text\|all\|auto}` · `.resize-{none\|x\|y}` `.resize` · `.scroll-{auto\|smooth}` · `.snap-{none\|x\|y\|both\|mandatory\|proximity}` · `.snap-{start\|end\|center}` · `.snap-stop-{always\|normal}` · `.scroll-m-*` `.scroll-p-*` · `.touch-{auto\|none\|pan-x\|pan-y\|manipulation}` · `hover:opacity-*` `hover:bg-accent` `hover:underline` `hover:shadow-lg` `hover:scale-{105\|110}` `hover:-translate-y-1` · `focus:ring` `focus:ring-2` `focus:ring-offset-2` `focus:ring-none` · `disabled:opacity-50` `disabled:cursor-not-allowed` `disabled:pointer-events-none` |
709
+ | Layout | `.aspect-{auto\|square\|video\|4-3\|3-2\|21-9\|9-16\|golden}` · `.object-{contain\|cover\|fill\|none\|scale-down}` · `.object-{center\|top\|bottom\|left\|right\|…}` · `.float-{left\|right\|none\|start\|end}` (responsive) · `.clear-*` · `.isolate` `.isolation-auto` · `.mix-blend-*` · `.bg-blend-*` · `.box-decoration-{clone\|slice}` · `.appearance-{none\|auto}` · `.will-change-{auto\|scroll\|contents\|transform}` |
710
+
711
+ Display and position utilities support responsive prefixes (`sm:`, `md:`, `lg:`, `xl:`, `2xl:`). Text-align and float also support responsive prefixes.
712
+
713
+ ---
714
+
715
+ ## Helpers
716
+
717
+ | Class | Effect |
718
+ |---|---|
719
+ | `.visually-hidden`, `.vh` | Visually hidden, screen-reader accessible |
720
+ | `.visually-hidden-focusable` | Hidden until focused (use for skip links) |
721
+ | `.truncate` | Single-line text truncation with ellipsis |
722
+ | `.line-clamp-{1-6}` | Multi-line text clamp |
723
+ | `.break-words` | `overflow-wrap: break-word` |
724
+ | `.break-all` | `word-break: break-all` |
725
+ | `.break-keep` | `word-break: keep-all` |
726
+ | `.ratio-auto` | `aspect-ratio: auto` |
727
+ | `.ratio-square` | `aspect-ratio: 1 / 1` |
728
+ | `.ratio-video` | `aspect-ratio: 16 / 9` |
729
+ | `.ratio-portrait` | `aspect-ratio: 3 / 4` |
730
+ | `.ratio-wide` | `aspect-ratio: 21 / 9` |
731
+ | `.ratio-golden` | `aspect-ratio: 1.618 / 1` |
732
+ | `.clearfix` | Float clearfix via `::after` |
733
+
734
+ ---
735
+
736
+ ## Accessibility
737
+
738
+ | Class / Rule | Effect |
739
+ |---|---|
740
+ | `.sr-only` | Visually hidden, announced by screen readers |
741
+ | `.not-sr-only` | Undoes `.sr-only` |
742
+ | `.visually-hidden`, `.vh` | Equivalent to `.sr-only` with `!important` guards |
743
+ | `.visually-hidden-focusable` | Hidden until focused (skip-link pattern) |
744
+ | `:focus-visible` | 2px primary-500 ring, 2px offset — keyboard only |
745
+ | `:focus:not(:focus-visible)` | Removes ring for mouse/pointer users |
746
+ | `prefers-reduced-motion: reduce` | Collapses all animation/transition durations to 0.01ms |
747
+ | `.print\:hidden` | `display: none` inside `@media print` |
748
+ | `.screen\:hidden` | `display: none` outside `@media print` (print-only element) |
749
+ | `.print\:break-inside-avoid` | Prevents page breaks inside the element when printing |
750
+ | `.print\:break-before` | Forces a page break before the element |
751
+ | `.print\:break-after` | Forces a page break after the element |
752
+ | `.print\:text-black` | Forces `color: #000` for print output |
753
+ | `.print\:bg-white` | Forces `background: #fff` for print output |
754
+ | `.print\:border-none` | Removes borders for print output |
755
+ | `.print\:shadow-none` | Removes box-shadow for print output |
756
+ | `a[href]::after` *(print)* | Appends `(url)` after links so destinations are visible on paper |
757
+
758
+ ---
759
+
760
+ ## Generator Engine
761
+
762
+ The three generator mixins are the engine behind all utility class output in the Mastors ecosystem.
763
+
764
+ ### `generate-utilities($utilities)`
765
+
766
+ Generates utility classes from a configuration map. Used by `@mastors/flexer`, `@mastors/gridder`, and all core utility partials.
767
+
768
+ The mixin runs in two passes:
769
+ - **Pass 1** — emits base (unprefixed) classes for every entry.
770
+ - **Pass 2** — for every entry with `responsive: true`, iterates all breakpoints (skipping `xs`/0px) and emits breakpoint-prefixed variants inside `@media` blocks. Respects the `$enable-responsive` flag and the global prefix/`!important` config.
771
+
772
+ ```scss
773
+ @use "@mastors/core/scss/generators/class-generator" as gen;
774
+
775
+ @include gen.generate-utilities((
776
+ "text-align": (
777
+ property: text-align,
778
+ prefix: "text",
779
+ responsive: true,
780
+ values: (
781
+ "left": left,
782
+ "center": center,
783
+ "right": right,
784
+ ),
785
+ ),
786
+ ));
787
+ // Emits: .text-left, .text-center, .text-right
788
+ // And: .sm\:text-left, .md\:text-left, … for all breakpoints
789
+ ```
790
+
791
+ ### `emit-custom-properties($map, $prefix)`
792
+
793
+ Emits flat CSS custom properties from a token map onto the current selector.
794
+
795
+ ```scss
796
+ :root {
797
+ @include gen.emit-custom-properties($spacing-tokens, "mastors-spacing");
798
+ // -> --mastors-spacing-4: 1rem; etc.
799
+ }
800
+ ```
801
+
802
+ ### `emit-nested-custom-properties($map, $prefix)`
803
+
804
+ Recursively emits custom properties from a nested map (e.g. color palettes).
805
+
806
+ ```scss
807
+ :root {
808
+ @include gen.emit-nested-custom-properties($color-tokens, "mastors-color");
809
+ // -> --mastors-color-primary-500: #3b82f6; etc.
810
+ }
811
+ ```
812
+
813
+ ---
814
+
815
+ ## Semantic Layer
816
+
817
+ The semantic layer in `semantic/` provides role-based SCSS variable aliases on top of the raw token maps. Use these in component SCSS instead of raw token references to get automatic theme compatibility.
818
+
819
+ **Colors:**
820
+
821
+ ```scss
822
+ @use "@mastors/core/scss/semantic/colors" as sem;
823
+
824
+ .my-card {
825
+ background: sem.$color-surface; // var(--mastors-surface)
826
+ color: sem.$color-text; // var(--mastors-text)
827
+ border: 1px solid sem.$color-border; // var(--mastors-border)
828
+ }
829
+ ```
830
+
831
+ **Spacing:**
832
+
833
+ ```scss
834
+ @use "@mastors/core/scss/semantic/spacing" as sem;
835
+
836
+ .section {
837
+ padding: sem.$space-section; // spacing(16) = 4rem
838
+ gap: sem.$space-component; // spacing(4) = 1rem
839
+ }
840
+ ```
841
+
842
+ **Typography:**
843
+
844
+ ```scss
845
+ @use "@mastors/core/scss/semantic/typography" as sem;
846
+
847
+ body { font-family: sem.$font-body; } // system-ui stack
848
+ code { font-family: sem.$font-mono; } // monospace stack
849
+ ```
850
+
851
+ ---
852
+
853
+ ## Known Stubs
854
+
855
+ Two files are intentionally empty at v1.0 and act as reserved extension points:
856
+
857
+ | File | Purpose |
858
+ |---|---|
859
+ | `abstracts/_maps.scss` | Shared utility maps consumed by 3+ unrelated files. Empty until such maps exist. |
860
+ | `vendors/_index.scss` | Third-party CSS overrides. Add a partial and `@forward` it here when needed. |
861
+ | `base/_box-sizing.scss` | Retained as a named path slot; box-sizing is declared in `_reset.scss`. |
862
+
863
+ These stubs are documented in each file's header comment.
864
+
865
+ ---
866
+
867
+ ## Package Exports
868
+
869
+ ```scss
870
+ /* Full stylesheet — reset + tokens + themes + utilities */
871
+ @use "@mastors/core/scss";
872
+
873
+ /* Public API — zero CSS output, all tokens/mixins/functions/config */
874
+ @use "@mastors/core/api" as m;
875
+
876
+ /* Individual partials */
877
+ @use "@mastors/core/scss/tokens/color" as ct;
878
+ @use "@mastors/core/scss/mixins/breakpoint" as bp;
879
+ @use "@mastors/core/scss/functions/rem" as r;
880
+ @use "@mastors/core/scss/functions/vars"; /* vars() standalone */
881
+ @use "@mastors/core/scss/responsive/fluid-type" as ft;
882
+ @use "@mastors/core/scss/config/settings"; /* $mastors-config, config() */
883
+ @use "@mastors/core/scss/config/flags"; /* $enable-* flags */
884
+ ```
885
+
886
+ ```ts
887
+ // Runtime token access
888
+ import { tokens } from '@mastors/core'
889
+
890
+ // TypeScript types
891
+ import type { MastorsConfig, Breakpoint, ThemeMode, Tokens } from '@mastors/core'
892
+ ```
893
+
894
+ ---
895
+
896
+ ## Peer Dependencies
897
+
898
+ | Package | Version |
899
+ |---|---|
900
+ | `sass` | `>= 1.80.0` |
901
+
902
+ ---
903
+
904
+ ## Changelog
905
+
906
+ ### v1.2.0
907
+
908
+ - **Added:** `vars($token, $fallback?)` function in `functions/_vars.scss` — wraps the `--mastors-` namespace so downstream consumers reference tokens as `var(--mastors-{name})` without hard-coding the prefix. Namespace stored in `$-namespace: "mastors" !default`. Forwarded through `functions/_index.scss` and exposed via `@use "@mastors/core/api"`.
909
+ - **Added:** `config/_index.scss` shim — `@forward`s both `_settings.scss` and `_flags.scss`. `api/_index.scss` now includes `@forward "../config/index"`, exposing `config()` accessor and all `$enable-*` flags through the public API surface without a direct partial import.
910
+ - **Added:** `utilities/_typography.scss` — full typography utility surface covering text-align (responsive), font-size (token-driven `@each`), font-weight (token-driven), font-family (token-driven), font-style (`.italic` / `.not-italic`), line-height / leading (token-driven), letter-spacing / tracking (token-driven), text-decoration (line + style + thickness), text-transform, text-overflow, white-space, word-break, text-indent, vertical-align, list-style, font-smoothing.
911
+ - **Added:** `utilities/_animation.scss` — transition-property presets (`.transition`, `.transition-colors`, `.transition-opacity`, `.transition-shadow`, `.transition-transform`, `.transition-none`, `.transition-all`), token-driven `.duration-*` and `.delay-*`, token-driven `.ease-*`, named animation presets (`.animate-spin/ping/pulse/bounce/fade-in/fade-out/slide-up/slide-down/scale-in/none`), full `@keyframes` definitions prefixed `mastors-*`, animation fill-mode / play-state / iteration utilities.
912
+ - **Added:** `utilities/_interaction.scss` — user-select, resize, scroll-behavior (`.scroll-auto` / `.scroll-smooth`), scroll-snap (type + align + stop + scroll-margin/padding), touch-action, and state-variant pseudo-class utilities: `hover:opacity-*`, `hover:bg-accent`, `hover:text-accent`, `hover:underline`, `hover:no-underline`, `hover:shadow-lg`, `hover:scale-105`, `hover:scale-110`, `hover:-translate-y-1`, `focus:ring`, `focus:ring-2`, `focus:ring-offset-2`, `focus:ring-none`, `disabled:opacity-50`, `disabled:cursor-not-allowed`, `disabled:pointer-events-none`.
913
+ - **Added:** `utilities/_layout.scss` — aspect-ratio block (`.aspect-auto`, `.aspect-square`, `.aspect-video`, `.aspect-4-3`, `.aspect-3-2`, `.aspect-21-9`, `.aspect-9-16`, `.aspect-golden`; the `$-aspect-ratios` map is `!default`-overridable). Documented alongside object-fit and object-position which were already present.
914
+ - **Added:** `accessibility/_print.scss` — `print:hidden`, `screen:hidden`, `print:break-inside-avoid`, `print:break-before`, `print:break-after`, `print:text-black`, `print:bg-white`, `print:border-none`, `print:shadow-none`, automatic `a[href]::after` link expansion, suppression for `#` and `javascript:` links.
915
+
916
+ ### v1.0.0
917
+
918
+ - Initial public release
919
+ - Full token system: color, spacing, typography, radii, shadows, z-index, opacity, transitions, sizing
920
+ - Complete functions layer: `rem`, `em`, `color`, `spacing`, `radius`, `shadow`, `z`, `opacity`, `duration`, `easing`, `tint`, `shade`, `alpha`, `contrast`, `fluid`, `map-deep-get`, `map-collect`, `str-replace`
921
+ - Complete mixins layer: `bp`, `respond-to`, `breakpoint-up`, `breakpoint-down`, `dark-mode`, `light-mode`, `theme`, `elevation`, `transition`, `container`, `pseudo`
922
+ - **Fixed:** `generate-utilities()` now runs a two-pass emit — Pass 1 outputs base classes, Pass 2 automatically emits breakpoint-prefixed responsive variants for all entries with `responsive: true`. Previously responsive variants were silently not emitted.
923
+ - **Fixed:** `generators/_responsive-generator.scss` replaced the `@content`-based no-op stub with a thin wrapper that correctly delegates to `engine.run()` for backward compatibility.
924
+ - **Fixed:** `contrast()` luminance threshold corrected from `0.179` (WCAG linearised) to `0.35` (calibrated for the simplified non-gamma-expanded approximation in use). Prevents wrong light/dark decisions on mid-grey backgrounds.
925
+ - **Added:** `stylelint` linting with `stylelint-config-standard-scss` — `pnpm lint` now runs real SCSS style checks. `postcss-scss`, `stylelint`, and `stylelint-config-standard-scss` added to `devDependencies`; `.stylelintrc.json` added to `packages/core`.
926
+ - Generator engine: `generate-utilities` (with integrated responsive Pass 2), `emit-custom-properties`, `emit-nested-custom-properties`
927
+ - Responsive engine with correct numeric breakpoint escaping (`2xl:` prefix)
928
+ - Container queries: `.cq-inline`, `.cq-size`, `.cq-normal`, `[data-container]`, `cq()` mixin
929
+ - Fluid typography: `fluid-type()` mixin + function + `fluid-scale()` preset
930
+ - Full directional border-radius utility scale — all four sides x all token steps
931
+ - Light and dark themes via CSS custom property semantic contract (15 semantic props)
932
+ - Modern CSS reset — no duplicate `box-sizing` declarations
933
+ - Accessibility layer: `:focus-visible` ring, `prefers-reduced-motion` override, `.sr-only`, `.visually-hidden`
934
+ - Dual dark-mode strategy: class-based and media-query, configurable via `$mastors-config`
935
+
936
+ ---
937
+
938
+ ## License
939
+
940
+ MIT (c) Mastors Contributors