@mastors/core 1.2.0 → 1.2.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.
- package/README.md +141 -810
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,940 +1,271 @@
|
|
|
1
1
|
# @mastors/core
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Foundational tokens, mixins, functions, reset, and responsive engine for the Mastors ecosystem.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@mastors/core)
|
|
5
|
+
[](https://www.npmjs.com/package/@mastors/core)
|
|
6
6
|
[](../../LICENSE)
|
|
7
|
-
[](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
7
|
|
|
57
8
|
---
|
|
58
9
|
|
|
59
10
|
## Overview
|
|
60
11
|
|
|
61
|
-
`@mastors/core` is the
|
|
12
|
+
`@mastors/core` is the foundation of the Mastors SCSS ecosystem. It provides:
|
|
62
13
|
|
|
63
|
-
- **
|
|
64
|
-
- **Functions** — `rem()`, `em()`, `color()`, `spacing()`, `
|
|
65
|
-
- **Mixins** — `bp()`, `dark-mode()`, `
|
|
66
|
-
- **Generator engine** — `generate-utilities()`, `emit-custom-properties()`,
|
|
67
|
-
- **
|
|
68
|
-
- **Theme system** — CSS custom property
|
|
69
|
-
- **Responsive engine** — breakpoint-
|
|
70
|
-
- **
|
|
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**
|
|
14
|
+
- **Token system** — color, spacing, typography, radii, shadows, z-index, opacity, transitions, sizing
|
|
15
|
+
- **Functions** — `rem()`, `em()`, `color()`, `spacing()`, `vars()`, `tint()`, `shade()`, `fluid()`, and more
|
|
16
|
+
- **Mixins** — `bp()`, `dark-mode()`, `theme()`, `elevation()`, `transition()`, `container()`, `pseudo()`
|
|
17
|
+
- **Generator engine** — `generate-utilities()`, `emit-custom-properties()`, `generate-responsive()`
|
|
18
|
+
- **Utility classes** — display, spacing, sizing, colors, borders, shadows, typography, animation, interaction, layout, accessibility
|
|
19
|
+
- **Theme system** — CSS custom property contract, light/dark themes, `data-theme` support
|
|
20
|
+
- **Responsive engine** — breakpoint-prefixed variant generation, container queries, fluid typography
|
|
21
|
+
- **TypeScript mirror** — runtime token access and full type definitions
|
|
75
22
|
|
|
76
|
-
All other `@mastors/*` packages consume `@mastors/core/api`
|
|
23
|
+
All other `@mastors/*` packages consume `@mastors/core/api` as a peer dependency.
|
|
77
24
|
|
|
78
25
|
---
|
|
79
26
|
|
|
80
27
|
## Installation
|
|
81
28
|
|
|
82
29
|
```bash
|
|
83
|
-
npm install @mastors/core
|
|
30
|
+
npm install @mastors/core
|
|
84
31
|
# or
|
|
85
|
-
pnpm add @mastors/core
|
|
32
|
+
pnpm add @mastors/core
|
|
33
|
+
# or
|
|
34
|
+
yarn add @mastors/core
|
|
86
35
|
```
|
|
87
36
|
|
|
88
|
-
`sass >= 1.80.0`
|
|
37
|
+
Requires `sass >= 1.80.0` as a peer dependency:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install --save-dev sass
|
|
41
|
+
```
|
|
89
42
|
|
|
90
43
|
---
|
|
91
44
|
|
|
92
45
|
## Usage
|
|
93
46
|
|
|
94
|
-
###
|
|
95
|
-
|
|
96
|
-
Import the complete compiled stylesheet — reset, tokens, themes, utilities, helpers, and accessibility:
|
|
47
|
+
### Import the full stylesheet
|
|
97
48
|
|
|
98
49
|
```scss
|
|
99
50
|
@use "@mastors/core/scss";
|
|
100
51
|
```
|
|
101
52
|
|
|
102
|
-
|
|
53
|
+
This imports the complete output: reset, custom properties, themes, utilities, helpers, and accessibility classes.
|
|
103
54
|
|
|
104
|
-
|
|
55
|
+
### Use the public API (zero CSS output)
|
|
105
56
|
|
|
106
57
|
```scss
|
|
107
58
|
@use "@mastors/core/api" as m;
|
|
108
59
|
|
|
109
60
|
.card {
|
|
110
|
-
padding:
|
|
111
|
-
|
|
112
|
-
border-radius:
|
|
113
|
-
box-shadow:
|
|
114
|
-
transition:
|
|
61
|
+
padding: m.spacing(6);
|
|
62
|
+
color: m.color("primary", 700);
|
|
63
|
+
border-radius: m.radius("lg");
|
|
64
|
+
box-shadow: m.vars(shadow-md);
|
|
65
|
+
transition: transform m.vars(duration-200) m.vars(ease-out);
|
|
115
66
|
|
|
116
|
-
@include m.bp("
|
|
67
|
+
@include m.bp("md") {
|
|
117
68
|
padding: m.spacing(10);
|
|
118
69
|
}
|
|
119
70
|
|
|
120
71
|
@include m.dark-mode {
|
|
121
|
-
|
|
122
|
-
color: m.color("neutral", 100);
|
|
72
|
+
color: m.color("primary", 300);
|
|
123
73
|
}
|
|
124
74
|
}
|
|
125
75
|
```
|
|
126
76
|
|
|
127
|
-
###
|
|
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.
|
|
77
|
+
### Import a single partial
|
|
160
78
|
|
|
161
79
|
```scss
|
|
162
|
-
|
|
163
|
-
@use "@mastors/core/scss/
|
|
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
|
-
);
|
|
80
|
+
@use "@mastors/core/scss/tokens/color" as colors;
|
|
81
|
+
@use "@mastors/core/scss/mixins/breakpoint" as bp;
|
|
171
82
|
```
|
|
172
83
|
|
|
173
|
-
###
|
|
84
|
+
### JavaScript / TypeScript
|
|
174
85
|
|
|
175
|
-
|
|
86
|
+
```ts
|
|
87
|
+
import { tokens } from '@mastors/core'
|
|
88
|
+
import type { Breakpoint, SpacingKey, ColorPalette } from '@mastors/core'
|
|
176
89
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
$enable-utilities: true,
|
|
180
|
-
$enable-responsive: true,
|
|
181
|
-
$enable-helpers: true,
|
|
182
|
-
$enable-a11y: true,
|
|
183
|
-
$enable-themes: true,
|
|
184
|
-
);
|
|
90
|
+
const primary = tokens.color.primary['600'] // '#2563eb'
|
|
91
|
+
const space4 = tokens.spacing['4'] // '1rem'
|
|
185
92
|
```
|
|
186
93
|
|
|
187
|
-
|
|
94
|
+
---
|
|
188
95
|
|
|
189
|
-
|
|
96
|
+
## Package Exports
|
|
190
97
|
|
|
191
|
-
```
|
|
192
|
-
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
".": { "import": "./dist/index.mjs", "require": "./dist/index.js", "types": "./dist/index.d.ts" },
|
|
101
|
+
"./scss": "./scss/index.scss",
|
|
102
|
+
"./scss/*": "./scss/*",
|
|
103
|
+
"./api": "./scss/api/_index.scss",
|
|
104
|
+
"./dist/mastors-core.css": "./dist/mastors-core.css"
|
|
105
|
+
}
|
|
193
106
|
```
|
|
194
107
|
|
|
195
|
-
|
|
108
|
+
---
|
|
196
109
|
|
|
197
|
-
|
|
198
|
-
@use "@mastors/core/scss/config/settings" with (
|
|
199
|
-
$mastors-config: ("dark-mode": "media")
|
|
200
|
-
);
|
|
201
|
-
```
|
|
110
|
+
## Public API (`@mastors/core/api`)
|
|
202
111
|
|
|
203
|
-
|
|
112
|
+
Importing `@mastors/core/api` gives access to:
|
|
204
113
|
|
|
205
|
-
|
|
114
|
+
### Functions
|
|
206
115
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
116
|
+
| Function | Description |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `color($name, $shade)` | Look up a palette color by name and shade |
|
|
119
|
+
| `spacing($key)` | Look up a spacing token |
|
|
120
|
+
| `radius($key)` | Look up a border-radius token |
|
|
121
|
+
| `shadow($key)` | Look up a box-shadow token |
|
|
122
|
+
| `z($key)` | Look up a z-index token |
|
|
123
|
+
| `opacity($key)` | Look up an opacity token |
|
|
124
|
+
| `duration($key)` | Look up a transition duration |
|
|
125
|
+
| `easing($key)` | Look up an easing curve |
|
|
126
|
+
| `vars($token, $fallback?)` | Emit `var(--mastors-{token})` with optional fallback |
|
|
127
|
+
| `rem($px)` | Convert px to rem |
|
|
128
|
+
| `em($px, $base?)` | Convert px to em |
|
|
129
|
+
| `tint($color, $amount)` | Mix color toward white |
|
|
130
|
+
| `shade($color, $amount)` | Mix color toward black |
|
|
131
|
+
| `alpha($color, $opacity)` | Set color opacity |
|
|
132
|
+
| `fluid($min, $max, $min-bp?, $max-bp?)` | Generate a fluid `clamp()` value |
|
|
133
|
+
|
|
134
|
+
### Mixins
|
|
135
|
+
|
|
136
|
+
| Mixin | Description |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `bp($key)` | Mobile-first breakpoint media query |
|
|
139
|
+
| `breakpoint-up($key)` | Alias for `bp()` |
|
|
140
|
+
| `breakpoint-down($key)` | Max-width media query |
|
|
141
|
+
| `respond-to($key)` | Alias for `bp()` |
|
|
142
|
+
| `dark-mode` | Dark mode block (class or media, per config) |
|
|
143
|
+
| `light-mode` | Light mode block |
|
|
144
|
+
| `theme($name)` | `[data-theme="name"]` scoped block |
|
|
145
|
+
| `elevation($level)` | Token-driven box-shadow by level |
|
|
146
|
+
| `transition($props...)` | Token-driven transition shorthand |
|
|
147
|
+
| `container($size?)` | Responsive container width |
|
|
148
|
+
| `pseudo($display, $pos, $content)` | `::before` / `::after` boilerplate |
|
|
149
|
+
| `cq($size, $name?)` | Container query block |
|
|
150
|
+
| `fluid-type($min, $max, $min-bp?, $max-bp?)` | Fluid font-size via `clamp()` |
|
|
151
|
+
|
|
152
|
+
### Config
|
|
215
153
|
|
|
216
154
|
```scss
|
|
217
155
|
@use "@mastors/core/api" as m;
|
|
218
156
|
|
|
219
|
-
// Read
|
|
220
|
-
$
|
|
157
|
+
// Read config values
|
|
158
|
+
$mode: m.config("dark-mode"); // "class" | "media"
|
|
221
159
|
|
|
222
|
-
//
|
|
223
|
-
|
|
224
|
-
// emit responsive variants
|
|
225
|
-
}
|
|
160
|
+
// Check feature flags
|
|
161
|
+
$enabled: m.$enable-flexer;
|
|
226
162
|
```
|
|
227
163
|
|
|
228
164
|
---
|
|
229
165
|
|
|
230
|
-
##
|
|
231
|
-
|
|
232
|
-
All tokens are available via the public API after `@use "@mastors/core/api" as m`.
|
|
166
|
+
## Token Reference
|
|
233
167
|
|
|
234
168
|
### Color
|
|
235
169
|
|
|
236
|
-
|
|
170
|
+
Palette keys: `primary`, `secondary`, `neutral`, `success`, `warning`, `danger`, `info`
|
|
171
|
+
Shades: `50`, `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`, `950`
|
|
237
172
|
|
|
238
173
|
```scss
|
|
239
|
-
m.color("primary", 600)
|
|
240
|
-
m.color("neutral", 100)
|
|
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
|
|
174
|
+
m.color("primary", 600) // #2563eb
|
|
175
|
+
m.color("neutral", 100) // #f5f5f5
|
|
247
176
|
```
|
|
248
177
|
|
|
249
|
-
Palettes: `primary` - `neutral` - `success` - `warning` - `error` - `info`
|
|
250
|
-
|
|
251
178
|
### Spacing
|
|
252
179
|
|
|
253
|
-
35-step 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
|
|
180
|
+
35-step scale — `0` through `96`:
|
|
297
181
|
|
|
298
182
|
```scss
|
|
299
|
-
m.
|
|
300
|
-
m.
|
|
301
|
-
m.
|
|
302
|
-
m.
|
|
303
|
-
m.radius("xl") // 0.75rem
|
|
304
|
-
m.radius("2xl") // 1rem
|
|
305
|
-
m.radius("3xl") // 1.5rem
|
|
306
|
-
m.radius("full") // 9999px
|
|
183
|
+
m.spacing(0) // 0
|
|
184
|
+
m.spacing(1) // 0.25rem
|
|
185
|
+
m.spacing(4) // 1rem
|
|
186
|
+
m.spacing(16) // 4rem
|
|
307
187
|
```
|
|
308
188
|
|
|
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
189
|
### Breakpoints
|
|
430
190
|
|
|
431
|
-
|
|
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 |
|
|
191
|
+
| Key | Min-width |
|
|
540
192
|
|---|---|
|
|
541
|
-
|
|
|
542
|
-
|
|
|
543
|
-
|
|
|
544
|
-
| `
|
|
193
|
+
| `xs` | 0px (base) |
|
|
194
|
+
| `sm` | 640px |
|
|
195
|
+
| `md` | 768px |
|
|
196
|
+
| `lg` | 1024px |
|
|
197
|
+
| `xl` | 1280px |
|
|
198
|
+
| `2xl` | 1536px |
|
|
545
199
|
|
|
546
|
-
|
|
200
|
+
### Radii
|
|
547
201
|
|
|
548
|
-
|
|
549
|
-
<div class="cq-inline">
|
|
550
|
-
<div class="child">Responds to container width, not viewport</div>
|
|
551
|
-
</div>
|
|
552
|
-
```
|
|
202
|
+
`none`, `sm`, `md`, `lg`, `xl`, `2xl`, `3xl`, `full`
|
|
553
203
|
|
|
554
|
-
|
|
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;
|
|
204
|
+
### Shadows
|
|
579
205
|
|
|
580
|
-
|
|
581
|
-
h1 { @include m.fluid-type(2rem, 3.75rem); }
|
|
206
|
+
`xs`, `sm`, `md`, `lg`, `xl`, `2xl`, `inner`, `none`
|
|
582
207
|
|
|
583
|
-
|
|
584
|
-
h1 { font-size: m.fluid-type(2rem, 3.75rem); }
|
|
208
|
+
### Durations
|
|
585
209
|
|
|
586
|
-
|
|
587
|
-
h2 { @include m.fluid-type(1.5rem, 3rem, 480px, 1440px); }
|
|
588
|
-
```
|
|
210
|
+
`75`, `100`, `150`, `200`, `300`, `500`, `700`, `1000` (ms)
|
|
589
211
|
|
|
590
|
-
|
|
212
|
+
### Easings
|
|
591
213
|
|
|
592
|
-
|
|
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
|
-
```
|
|
214
|
+
`linear`, `in`, `out`, `in-out`
|
|
597
215
|
|
|
598
216
|
---
|
|
599
217
|
|
|
600
218
|
## Theme System
|
|
601
219
|
|
|
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
220
|
```scss
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
221
|
+
// Class-based dark mode (default)
|
|
222
|
+
// Activate with: <html class="dark">
|
|
223
|
+
$mastors-config: ("dark-mode": "class") !default;
|
|
224
|
+
|
|
225
|
+
// Media-query dark mode
|
|
226
|
+
$mastors-config: ("dark-mode": "media") !default;
|
|
650
227
|
```
|
|
651
228
|
|
|
652
|
-
Custom
|
|
229
|
+
Custom theme:
|
|
653
230
|
|
|
654
231
|
```scss
|
|
655
|
-
@use "@mastors/core/api" as m;
|
|
656
|
-
|
|
657
232
|
@include m.theme("ocean") {
|
|
658
233
|
--mastors-accent: #0891b2;
|
|
659
|
-
--mastors-accent-hover: #0e7490;
|
|
660
234
|
}
|
|
661
235
|
```
|
|
662
236
|
|
|
663
237
|
```html
|
|
664
|
-
<div data-theme="ocean">
|
|
665
|
-
<!-- accent color is teal inside here -->
|
|
666
|
-
</div>
|
|
238
|
+
<div data-theme="ocean">...</div>
|
|
667
239
|
```
|
|
668
240
|
|
|
669
241
|
---
|
|
670
242
|
|
|
671
|
-
##
|
|
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 |
|
|
243
|
+
## Build
|
|
757
244
|
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
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;
|
|
245
|
+
```bash
|
|
246
|
+
# From the monorepo root
|
|
247
|
+
pnpm build:core
|
|
846
248
|
|
|
847
|
-
|
|
848
|
-
|
|
249
|
+
# Or from this package
|
|
250
|
+
node build.js
|
|
849
251
|
```
|
|
850
252
|
|
|
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";
|
|
253
|
+
Build steps: clean → compile SCSS → regenerate `src/tokens.ts` → compile TypeScript.
|
|
872
254
|
|
|
873
|
-
|
|
874
|
-
@use "@mastors/core/api" as m;
|
|
255
|
+
To regenerate the TypeScript token mirror without a full build:
|
|
875
256
|
|
|
876
|
-
|
|
877
|
-
|
|
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'
|
|
257
|
+
```bash
|
|
258
|
+
node scripts/generate-tokens.js
|
|
892
259
|
```
|
|
893
260
|
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
## Peer Dependencies
|
|
897
|
-
|
|
898
|
-
| Package | Version |
|
|
899
|
-
|---|---|
|
|
900
|
-
| `sass` | `>= 1.80.0` |
|
|
261
|
+
> `src/tokens.ts` is auto-generated — never edit it manually.
|
|
901
262
|
|
|
902
263
|
---
|
|
903
264
|
|
|
904
265
|
## Changelog
|
|
905
266
|
|
|
906
|
-
|
|
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
|
-
---
|
|
267
|
+
See the [root CHANGELOG](../../README.md#changelog).
|
|
937
268
|
|
|
938
269
|
## License
|
|
939
270
|
|
|
940
|
-
MIT
|
|
271
|
+
MIT © Mastors Contributors
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastors/core",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Mastors Core — foundational tokens, mixins, functions, and SCSS architecture",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Mastors Contributors",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"stylelint-config-standard-scss": "^13.0.0",
|
|
52
52
|
"typescript": "^5.3.0",
|
|
53
53
|
"@mastors/build-utils": "2.0.0",
|
|
54
|
-
"@mastors/
|
|
55
|
-
"@mastors/
|
|
54
|
+
"@mastors/tsconfig": "1.0.1",
|
|
55
|
+
"@mastors/sass-config": "1.0.1"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"sass": ">=1.80.0"
|