@mastors/core 1.1.0 → 2.0.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.
- package/README.md +12 -121
- package/dist/mastors-core.css +62 -1615
- package/dist/mastors-core.css.map +1 -1
- package/package.json +6 -8
- package/scss/abstracts/_maps.scss +9 -0
- package/scss/accessibility/_index.scss +0 -1
- package/scss/accessibility/_screen-reader.scss +1 -4
- package/scss/api/_index.scss +0 -1
- package/scss/base/_reset.scss +1 -1
- package/scss/config/_flags.scss +9 -9
- package/scss/functions/_color.scss +15 -32
- package/scss/functions/_em.scss +2 -2
- package/scss/functions/_index.scss +0 -6
- package/scss/functions/_math.scss +0 -19
- package/scss/functions/_string.scss +0 -35
- package/scss/generators/_class-generator.scss +42 -31
- package/scss/generators/_responsive-generator.scss +4 -0
- package/scss/helpers/_visually-hidden.scss +14 -27
- package/scss/mixins/_breakpoint.scss +3 -3
- package/scss/mixins/_transition.scss +1 -1
- package/scss/responsive/_engine.scss +5 -3
- package/scss/responsive/_fluid-type.scss +9 -8
- package/scss/semantic/_colors.scss +15 -15
- package/scss/semantic/_spacing.scss +5 -5
- package/scss/semantic/_typography.scss +5 -5
- package/scss/themes/_base-theme.scss +5 -0
- package/scss/themes/_dark.scss +7 -8
- package/scss/tokens/_color.scss +4 -8
- package/scss/tokens/_shadows.scss +9 -7
- package/scss/tokens/_sizing.scss +6 -3
- package/scss/tokens/_typography.scss +10 -9
- package/scss/utilities/_borders.scss +6 -4
- package/scss/utilities/_colors.scss +1 -1
- package/scss/utilities/_index.scss +0 -4
- package/scss/utilities/_sizing.scss +2 -2
- package/scss/variables/_global.scss +4 -4
- package/scss/variables/_grid.scss +3 -3
- package/scss/vendors/_index.scss +2 -0
- package/src/index.ts +11 -0
- package/src/tokens.ts +314 -0
- package/src/types.ts +52 -0
- package/postinstall.js +0 -41
- package/scripts/generate-tokens.js +0 -259
- package/scss/accessibility/_print.scss +0 -52
- package/scss/config/_index.scss +0 -12
- package/scss/functions/_vars.scss +0 -49
- package/scss/utilities/_animation.scss +0 -125
- package/scss/utilities/_interaction.scss +0 -156
- package/scss/utilities/_layout.scss +0 -162
- package/scss/utilities/_typography.scss +0 -163
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
// ─────────────────────────────────────────────────────────────
|
|
4
4
|
|
|
5
5
|
@use "sass:color";
|
|
6
|
-
@use "sass:list";
|
|
7
6
|
@use "sass:math";
|
|
8
7
|
@use "../tokens/color" as ct;
|
|
9
8
|
|
|
@@ -23,6 +22,21 @@
|
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
/// Return black or white for maximum contrast against $bg.
|
|
25
|
+
///
|
|
26
|
+
/// Method: simplified linear luminance (no sRGB gamma expansion).
|
|
27
|
+
/// The three RGB coefficients (0.2126 / 0.7152 / 0.0722) are the WCAG
|
|
28
|
+
/// standard weights, but they are meant to be applied to *linearised*
|
|
29
|
+
/// channel values (after the 0.04045 piecewise inverse-gamma step).
|
|
30
|
+
/// Skipping gamma expansion makes mid-tones appear lighter than they
|
|
31
|
+
/// really are, so the WCAG threshold (0.179) would incorrectly return
|
|
32
|
+
/// $dark for many mid-grey backgrounds.
|
|
33
|
+
///
|
|
34
|
+
/// To compensate, the threshold is adjusted to ~0.35 — empirically
|
|
35
|
+
/// calibrated for the non-linearised approximation used here. This
|
|
36
|
+
/// gives correct light/dark decisions across the full neutral scale.
|
|
37
|
+
///
|
|
38
|
+
/// Do NOT use the return value for strict WCAG 2.1 contrast-ratio
|
|
39
|
+
/// calculations; implement full sRGB linearisation for that use case.
|
|
26
40
|
@function contrast($bg, $light: white, $dark: black) {
|
|
27
41
|
$luminance: 0.2126 * color.channel($bg, "red", $space: rgb) / 255
|
|
28
42
|
+ 0.7152 * color.channel($bg, "green", $space: rgb) / 255
|
|
@@ -33,34 +47,3 @@
|
|
|
33
47
|
@return $light;
|
|
34
48
|
}
|
|
35
49
|
}
|
|
36
|
-
|
|
37
|
-
/// Quick palette accessor — shorthand for ct.color()
|
|
38
|
-
@function palette($name, $shade: null) {
|
|
39
|
-
@return ct.color($name, $shade);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/// Emit a color as rgb() with optional opacity.
|
|
43
|
-
@function rgb-color($name, $shade, $opacity: 1) {
|
|
44
|
-
$c: ct.color($name, $shade);
|
|
45
|
-
@if $opacity == 1 { @return $c; }
|
|
46
|
-
$r: color.channel($c, "red", $space: rgb);
|
|
47
|
-
$g: color.channel($c, "green", $space: rgb);
|
|
48
|
-
$b: color.channel($c, "blue", $space: rgb);
|
|
49
|
-
@return rgb($r $g $b / $opacity);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/// Create a stepped tint/shade ramp on the fly.
|
|
53
|
-
@function color-ramp($base, $steps: 5, $dir: "tint") {
|
|
54
|
-
$result: ();
|
|
55
|
-
@for $i from 1 through $steps {
|
|
56
|
-
$pct: math.div($i * 100%, $steps + 1);
|
|
57
|
-
$step: null;
|
|
58
|
-
@if $dir == "tint" {
|
|
59
|
-
$step: tint($base, $pct);
|
|
60
|
-
} @else {
|
|
61
|
-
$step: shade($base, $pct);
|
|
62
|
-
}
|
|
63
|
-
$result: list.append($result, $step, comma);
|
|
64
|
-
}
|
|
65
|
-
@return $result;
|
|
66
|
-
}
|
package/scss/functions/_em.scss
CHANGED
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
/// @param {Number} $context - context font size in px (default: base)
|
|
11
11
|
/// @return {Number} em value
|
|
12
12
|
@function em($px, $context: vars.$base-font-size) {
|
|
13
|
-
$base:
|
|
13
|
+
$base: 0;
|
|
14
14
|
@if math.compatible($px, 1px) {
|
|
15
15
|
$base: math.div($px, 1px);
|
|
16
16
|
} @else {
|
|
17
17
|
$base: $px;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
$ctx:
|
|
20
|
+
$ctx: 0;
|
|
21
21
|
@if math.compatible($context, 1px) {
|
|
22
22
|
$ctx: math.div($context, 1px);
|
|
23
23
|
} @else {
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
// functions/_index.scss
|
|
2
2
|
// ─────────────────────────────────────────────────────────────
|
|
3
|
-
// NOTE: _vars.scss is intentionally NOT forwarded here.
|
|
4
|
-
// _string.scss already defines vars() and vars-or().
|
|
5
|
-
// _vars.scss defines a single-token vars($token, $fallback) variant
|
|
6
|
-
// under a different signature — forwarding both causes a "two modules
|
|
7
|
-
// define vars" conflict. Consumers who need the _vars.scss variant
|
|
8
|
-
// should @use it directly.
|
|
9
3
|
|
|
10
4
|
@forward "color";
|
|
11
5
|
@forward "math";
|
|
@@ -19,22 +19,3 @@
|
|
|
19
19
|
$intercept: $min-val - $slope * $min-vw;
|
|
20
20
|
@return clamp(#{$min-val}, #{$slope * 100vw} + #{$intercept}, #{$max-val});
|
|
21
21
|
}
|
|
22
|
-
|
|
23
|
-
/// Strip the unit from a number: strip-unit(16px) → 16
|
|
24
|
-
@function strip-unit($number) {
|
|
25
|
-
@return math.div($number, ($number * 0 + 1));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/// Round to N decimal places: round-to(3.14159, 2) → 3.14
|
|
29
|
-
@function round-to($number, $decimals: 2) {
|
|
30
|
-
$n: math.pow(10, $decimals);
|
|
31
|
-
@return math.div(math.round($number * $n), $n);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/// Linear interpolation between two values
|
|
35
|
-
/// @param {Number} $a - start value
|
|
36
|
-
/// @param {Number} $b - end value
|
|
37
|
-
/// @param {Number} $t - interpolation factor (0–1)
|
|
38
|
-
@function lerp($a, $b, $t) {
|
|
39
|
-
@return $a + ($b - $a) * $t;
|
|
40
|
-
}
|
|
@@ -20,38 +20,3 @@
|
|
|
20
20
|
@function to-string($value) {
|
|
21
21
|
@return #{$value};
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
/// Reference any design token as a CSS custom property (var()).
|
|
25
|
-
/// Builds the --mastors-{category}-{keys...} expression at zero runtime cost.
|
|
26
|
-
///
|
|
27
|
-
/// Usage:
|
|
28
|
-
/// color: vars(color, primary, 500); → var(--mastors-color-primary-500)
|
|
29
|
-
/// padding: vars(spacing, 4); → var(--mastors-spacing-4)
|
|
30
|
-
/// border-radius: vars(radius, lg); → var(--mastors-radius-lg)
|
|
31
|
-
/// transition-duration:vars(duration, 200); → var(--mastors-duration-200)
|
|
32
|
-
/// z-index: vars(z, modal); → var(--mastors-z-modal)
|
|
33
|
-
/// box-shadow: vars(shadow, md); → var(--mastors-shadow-md)
|
|
34
|
-
///
|
|
35
|
-
/// @param {String} $category - Token category prefix (color, spacing, radius…)
|
|
36
|
-
/// @param {ArgList} $keys - One or more path segments
|
|
37
|
-
/// @return {String} - CSS var() expression
|
|
38
|
-
@function vars($category, $keys...) {
|
|
39
|
-
$prop: "--mastors-#{$category}";
|
|
40
|
-
@each $key in $keys {
|
|
41
|
-
$prop: "#{$prop}-#{$key}";
|
|
42
|
-
}
|
|
43
|
-
@return var(#{$prop});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/// vars() with a fallback value.
|
|
47
|
-
/// Usage: color: vars-or(color, #3b82f6, primary, 500);
|
|
48
|
-
/// @param {String} $category - Token category prefix
|
|
49
|
-
/// @param {*} $fallback - Fallback value if custom property is not set
|
|
50
|
-
/// @param {ArgList} $keys - Path segments
|
|
51
|
-
@function vars-or($category, $fallback, $keys...) {
|
|
52
|
-
$prop: "--mastors-#{$category}";
|
|
53
|
-
@each $key in $keys {
|
|
54
|
-
$prop: "#{$prop}-#{$key}";
|
|
55
|
-
}
|
|
56
|
-
@return var(#{$prop}, #{$fallback});
|
|
57
|
-
}
|
|
@@ -10,13 +10,34 @@
|
|
|
10
10
|
@use "../variables/breakpoints" as bpvars;
|
|
11
11
|
|
|
12
12
|
/// Core utility class generator engine.
|
|
13
|
+
/// Emits base utility classes AND, for any entry with responsive: true,
|
|
14
|
+
/// also emits breakpoint-prefixed variants via the built-in responsive pass.
|
|
15
|
+
///
|
|
16
|
+
/// @param {Map} $utilities - map of utility configs, each with:
|
|
17
|
+
/// - property {String} CSS property name
|
|
18
|
+
/// - values {Map} class-suffix → value pairs
|
|
19
|
+
/// - prefix {String} optional class prefix (e.g. "flex")
|
|
20
|
+
/// - responsive {Boolean} emit responsive variants (default false)
|
|
21
|
+
///
|
|
22
|
+
/// Usage:
|
|
23
|
+
/// @include generate-utilities((
|
|
24
|
+
/// "flex-direction": (
|
|
25
|
+
/// property: flex-direction,
|
|
26
|
+
/// prefix: "flex",
|
|
27
|
+
/// values: ("row": row, "col": column, "row-reverse": row-reverse),
|
|
28
|
+
/// responsive: true,
|
|
29
|
+
/// ),
|
|
30
|
+
/// ));
|
|
13
31
|
@mixin generate-utilities($utilities) {
|
|
14
32
|
$cls-prefix: cfg.config("prefix");
|
|
15
|
-
$
|
|
33
|
+
$important: null;
|
|
34
|
+
@if cfg.config("important") {
|
|
35
|
+
$important: !important;
|
|
36
|
+
}
|
|
16
37
|
|
|
17
38
|
// ── Pass 1: base (unprefixed) classes ──────────────────────
|
|
18
39
|
@each $name, $config in $utilities {
|
|
19
|
-
$prop:
|
|
40
|
+
$prop: map.get($config, property);
|
|
20
41
|
$values: map.get($config, values);
|
|
21
42
|
$prefix: map.get($config, prefix);
|
|
22
43
|
|
|
@@ -26,52 +47,42 @@
|
|
|
26
47
|
$class-name: "#{$cls-prefix}#{$prefix}-#{$suffix}";
|
|
27
48
|
}
|
|
28
49
|
.#{$class-name} {
|
|
29
|
-
|
|
30
|
-
#{$prop}: $value !important;
|
|
31
|
-
} @else {
|
|
32
|
-
#{$prop}: $value;
|
|
33
|
-
}
|
|
50
|
+
#{$prop}: $value $important;
|
|
34
51
|
}
|
|
35
52
|
}
|
|
36
53
|
}
|
|
37
54
|
|
|
38
55
|
// ── Pass 2: responsive variants (.sm\:, .md\:, …) ─────────
|
|
56
|
+
// Only runs when $enable-responsive is true and at least one
|
|
57
|
+
// utility in the map declares responsive: true.
|
|
39
58
|
@if flags.$enable-responsive {
|
|
40
59
|
@each $bp-key, $bp-value in bpvars.$breakpoints {
|
|
41
|
-
|
|
60
|
+
// xs (0px) → no media query wrapper; base classes already cover it.
|
|
61
|
+
@if $bp-value != 0px {
|
|
42
62
|
@media (min-width: #{$bp-value}) {
|
|
43
63
|
@each $name, $config in $utilities {
|
|
44
64
|
@if map.get($config, responsive) == true {
|
|
45
|
-
$prop:
|
|
65
|
+
$prop: map.get($config, property);
|
|
46
66
|
$values: map.get($config, values);
|
|
47
67
|
$prefix: map.get($config, prefix);
|
|
48
68
|
|
|
49
69
|
@each $suffix, $value in $values {
|
|
50
|
-
$class:
|
|
51
|
-
@if $prefix {
|
|
52
|
-
$class: "#{$cls-prefix}#{$prefix}-#{$suffix}";
|
|
53
|
-
} @else {
|
|
54
|
-
$class: "#{$cls-prefix}#{$suffix}";
|
|
55
|
-
}
|
|
70
|
+
$class: if($prefix, "#{$cls-prefix}#{$prefix}-#{$suffix}", "#{$cls-prefix}#{$suffix}");
|
|
56
71
|
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
$
|
|
60
|
-
$
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
$
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
// CSS identifiers cannot start with a digit.
|
|
73
|
+
// Escape numeric-leading breakpoint keys (e.g. "2xl" → "\32 xl").
|
|
74
|
+
$first: string.slice("#{$bp-key}", 1, 1);
|
|
75
|
+
$rest: string.slice("#{$bp-key}", 2);
|
|
76
|
+
$safe-bp: if(
|
|
77
|
+
$first == "0" or $first == "1" or $first == "2" or $first == "3" or
|
|
78
|
+
$first == "4" or $first == "5" or $first == "6" or $first == "7" or
|
|
79
|
+
$first == "8" or $first == "9",
|
|
80
|
+
"\\3#{$first} #{$rest}",
|
|
81
|
+
"#{$bp-key}"
|
|
82
|
+
);
|
|
68
83
|
|
|
69
84
|
@at-root .#{$safe-bp}\:#{$class} {
|
|
70
|
-
|
|
71
|
-
#{$prop}: $value !important;
|
|
72
|
-
} @else {
|
|
73
|
-
#{$prop}: $value;
|
|
74
|
-
}
|
|
85
|
+
#{$prop}: $value $important;
|
|
75
86
|
}
|
|
76
87
|
}
|
|
77
88
|
}
|
|
@@ -4,14 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
// NOTE: Responsive class generation is now handled directly inside
|
|
6
6
|
// generate-utilities() in _class-generator.scss (Pass 2).
|
|
7
|
+
//
|
|
7
8
|
// This file previously contained a generate-responsive() mixin that
|
|
8
9
|
// accepted @content blocks but never emitted any CSS itself, making it
|
|
9
10
|
// a silent no-op. That stub has been removed to prevent confusion.
|
|
11
|
+
//
|
|
10
12
|
// — If you need to run the responsive engine standalone (e.g. from a
|
|
11
13
|
// sub-package that builds its own $utilities map independently of
|
|
12
14
|
// generate-utilities), use the engine mixin directly:
|
|
15
|
+
//
|
|
13
16
|
// @use "@mastors/core/scss/responsive/engine" as engine;
|
|
14
17
|
// @include engine.run($my-utilities);
|
|
18
|
+
//
|
|
15
19
|
// — For the standard case, simply pass your $utilities map to
|
|
16
20
|
// generate-utilities() and set responsive: true on any entry that
|
|
17
21
|
// needs breakpoint variants — the responsive pass runs automatically.
|
|
@@ -1,39 +1,26 @@
|
|
|
1
1
|
// helpers/_visually-hidden.scss
|
|
2
2
|
// Visually hides content while keeping it accessible to screen readers.
|
|
3
3
|
// ─────────────────────────────────────────────────────────────
|
|
4
|
-
// The canonical implementation lives in accessibility/_screen-reader.scss
|
|
5
|
-
// (.sr-only / .not-sr-only — the modern standard class names).
|
|
6
|
-
// This file provides the legacy aliases (.visually-hidden, .vh,
|
|
7
|
-
// .visually-hidden-focusable) that map onto the same rules, so existing
|
|
8
|
-
// codebases using either naming convention continue to work without
|
|
9
|
-
// duplicating any declarations.
|
|
10
4
|
|
|
11
|
-
|
|
5
|
+
// Shared styles as a placeholder to avoid cross-module @extend issues
|
|
6
|
+
%visually-hidden-base {
|
|
7
|
+
position: absolute !important;
|
|
8
|
+
width: 1px !important;
|
|
9
|
+
height: 1px !important;
|
|
10
|
+
padding: 0 !important;
|
|
11
|
+
margin: -1px !important;
|
|
12
|
+
overflow: hidden !important;
|
|
13
|
+
clip: rect(0, 0, 0, 0) !important;
|
|
14
|
+
white-space: nowrap !important;
|
|
15
|
+
border: 0 !important;
|
|
16
|
+
}
|
|
12
17
|
|
|
13
|
-
// Legacy aliases — extend the canonical sr-only rules
|
|
14
|
-
// so no extra CSS is emitted; both class names share one rule block.
|
|
15
18
|
.visually-hidden,
|
|
16
19
|
.vh {
|
|
17
|
-
|
|
18
|
-
width: 1px;
|
|
19
|
-
height: 1px;
|
|
20
|
-
padding: 0;
|
|
21
|
-
margin: -1px;
|
|
22
|
-
overflow: hidden;
|
|
23
|
-
clip: rect(0, 0, 0, 0);
|
|
24
|
-
white-space: nowrap;
|
|
25
|
-
border-width: 0;
|
|
20
|
+
@extend %visually-hidden-base;
|
|
26
21
|
}
|
|
27
22
|
|
|
28
23
|
// Undo visually-hidden when focused (e.g. skip links)
|
|
29
24
|
.visually-hidden-focusable:not(:focus):not(:focus-within) {
|
|
30
|
-
|
|
31
|
-
width: 1px;
|
|
32
|
-
height: 1px;
|
|
33
|
-
padding: 0;
|
|
34
|
-
margin: -1px;
|
|
35
|
-
overflow: hidden;
|
|
36
|
-
clip: rect(0, 0, 0, 0);
|
|
37
|
-
white-space: nowrap;
|
|
38
|
-
border-width: 0;
|
|
25
|
+
@extend %visually-hidden-base;
|
|
39
26
|
}
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
/// @param {String} $bp - breakpoint key (sm, md, lg, xl, 2xl)
|
|
10
10
|
@mixin bp($bp) {
|
|
11
11
|
$value: map.get(bpvars.$breakpoints, $bp);
|
|
12
|
-
@if
|
|
12
|
+
@if $value == null {
|
|
13
13
|
@error "bp(): unknown breakpoint '#{$bp}'. Available: #{map.keys(bpvars.$breakpoints)}";
|
|
14
14
|
}
|
|
15
|
-
@if $value ==
|
|
15
|
+
@if $value == 0px {
|
|
16
16
|
@content;
|
|
17
17
|
} @else {
|
|
18
18
|
@media (min-width: #{$value}) { @content; }
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
/// Emit styles below a named breakpoint
|
|
27
27
|
@mixin breakpoint-down($bp) {
|
|
28
28
|
$value: map.get(bpvars.$breakpoints, $bp);
|
|
29
|
-
@if
|
|
29
|
+
@if $value == null {
|
|
30
30
|
@error "breakpoint-down(): unknown breakpoint '#{$bp}'";
|
|
31
31
|
}
|
|
32
32
|
@media (max-width: #{$value - 0.02px}) { @content; }
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
/// @param {String} $duration - duration token key (default: "200")
|
|
11
11
|
/// @param {String} $easing - easing token key (default: "in-out")
|
|
12
12
|
@mixin transition($properties: (all), $duration: "200", $easing: "in-out") {
|
|
13
|
-
$dur:
|
|
13
|
+
$dur: tr.duration($duration);
|
|
14
14
|
$ease: tr.easing($easing);
|
|
15
15
|
$transitions: ();
|
|
16
16
|
@each $prop in $properties {
|
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
// Responsive engine — generates breakpoint-prefixed variants
|
|
10
10
|
// of any utility that declares responsive: true.
|
|
11
|
+
//
|
|
11
12
|
// Class pattern: .{bp}\:{utility}
|
|
12
13
|
// Example output: .sm\:hidden, .md\:flex, .lg\:gap-8
|
|
14
|
+
//
|
|
13
15
|
// Sub-packages pass their $utilities map here via @include engine.run()
|
|
14
16
|
// so the engine iterates breakpoints and re-emits the classes.
|
|
15
17
|
|
|
@@ -19,11 +21,11 @@
|
|
|
19
21
|
@if flags.$enable-responsive {
|
|
20
22
|
@each $bp-key, $bp-value in bpvars.$breakpoints {
|
|
21
23
|
// Skip xs — no prefix, already emitted as base classes
|
|
22
|
-
@if $bp-value !=
|
|
24
|
+
@if $bp-value != 0px {
|
|
23
25
|
@media (min-width: #{$bp-value}) {
|
|
24
26
|
@each $name, $config in $utilities {
|
|
25
27
|
@if map.get($config, responsive) == true {
|
|
26
|
-
$prop:
|
|
28
|
+
$prop: map.get($config, property);
|
|
27
29
|
$values: map.get($config, values);
|
|
28
30
|
$prefix: map.get($config, prefix);
|
|
29
31
|
|
|
@@ -39,7 +41,7 @@
|
|
|
39
41
|
// When the breakpoint key begins with a number (e.g. "2xl"),
|
|
40
42
|
// escape it using the CSS identifier-escape syntax: \3X (space after hex).
|
|
41
43
|
$first: string.slice("#{$bp-key}", 1, 1);
|
|
42
|
-
$rest:
|
|
44
|
+
$rest: string.slice("#{$bp-key}", 2);
|
|
43
45
|
$safe-bp: null;
|
|
44
46
|
@if $first == "0" or $first == "1" or $first == "2" or $first == "3" or
|
|
45
47
|
$first == "4" or $first == "5" or $first == "6" or $first == "7" or
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
// Fluid type scale — font sizes that scale smoothly between two viewport widths.
|
|
9
9
|
// Uses clamp() so no media queries are needed.
|
|
10
|
+
//
|
|
10
11
|
// Usage in component SCSS:
|
|
11
12
|
// @use "@mastors/core/api" as m;
|
|
12
13
|
// font-size: m.fluid-type(1rem, 1.5rem);
|
|
@@ -16,7 +17,7 @@
|
|
|
16
17
|
/// @param {Number} $max-size - maximum font size (rem)
|
|
17
18
|
/// @param {Number} $min-vw - viewport at which min applies (px, default 320px)
|
|
18
19
|
/// @param {Number} $max-vw - viewport at which max applies (px, default 1280px)
|
|
19
|
-
@mixin
|
|
20
|
+
@mixin fluid-type($min-size, $max-size, $min-vw: 320px, $max-vw: 1280px) {
|
|
20
21
|
font-size: mathfn.fluid($min-size, $max-size, $min-vw, $max-vw);
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -30,11 +31,11 @@
|
|
|
30
31
|
// Include with: @use "@mastors/core/scss/responsive/fluid-type" as ft;
|
|
31
32
|
// @include ft.fluid-scale();
|
|
32
33
|
@mixin fluid-scale {
|
|
33
|
-
h1 { @include
|
|
34
|
-
h2 { @include
|
|
35
|
-
h3 { @include
|
|
36
|
-
h4 { @include
|
|
37
|
-
h5 { @include
|
|
38
|
-
h6 { @include
|
|
39
|
-
p { @include
|
|
34
|
+
h1 { @include fluid-type(2rem, 3.75rem); }
|
|
35
|
+
h2 { @include fluid-type(1.5rem, 3rem); }
|
|
36
|
+
h3 { @include fluid-type(1.25rem, 2.25rem); }
|
|
37
|
+
h4 { @include fluid-type(1.125rem, 1.875rem); }
|
|
38
|
+
h5 { @include fluid-type(1rem, 1.5rem); }
|
|
39
|
+
h6 { @include fluid-type(0.875rem, 1.25rem); }
|
|
40
|
+
p { @include fluid-type(0.875rem, 1.125rem); }
|
|
40
41
|
}
|
|
@@ -9,21 +9,21 @@
|
|
|
9
9
|
// emitted by themes/_base-theme.scss, _light.scss, _dark.scss.
|
|
10
10
|
// Downstream packages can @use this file to access semantic names.
|
|
11
11
|
|
|
12
|
-
$color-bg:
|
|
13
|
-
$color-bg-subtle:
|
|
14
|
-
$color-surface:
|
|
15
|
-
$color-surface-raised:
|
|
16
|
-
$color-surface-overlay: var(--mastors-surface-overlay)
|
|
12
|
+
$color-bg: var(--mastors-bg) !default;
|
|
13
|
+
$color-bg-subtle: var(--mastors-bg-subtle) !default;
|
|
14
|
+
$color-surface: var(--mastors-surface) !default;
|
|
15
|
+
$color-surface-raised: var(--mastors-surface-raised) !default;
|
|
16
|
+
$color-surface-overlay: var(--mastors-surface-overlay) !default;
|
|
17
17
|
|
|
18
|
-
$color-text:
|
|
19
|
-
$color-text-muted:
|
|
20
|
-
$color-text-subtle:
|
|
21
|
-
$color-text-inverse:
|
|
18
|
+
$color-text: var(--mastors-text) !default;
|
|
19
|
+
$color-text-muted: var(--mastors-text-muted) !default;
|
|
20
|
+
$color-text-subtle: var(--mastors-text-subtle) !default;
|
|
21
|
+
$color-text-inverse: var(--mastors-text-inverse) !default;
|
|
22
22
|
|
|
23
|
-
$color-border:
|
|
24
|
-
$color-border-strong:
|
|
23
|
+
$color-border: var(--mastors-border) !default;
|
|
24
|
+
$color-border-strong: var(--mastors-border-strong) !default;
|
|
25
25
|
|
|
26
|
-
$color-accent:
|
|
27
|
-
$color-accent-hover:
|
|
28
|
-
$color-accent-subtle:
|
|
29
|
-
$color-accent-text:
|
|
26
|
+
$color-accent: var(--mastors-accent) !default;
|
|
27
|
+
$color-accent-hover: var(--mastors-accent-hover) !default;
|
|
28
|
+
$color-accent-subtle: var(--mastors-accent-subtle) !default;
|
|
29
|
+
$color-accent-text: var(--mastors-accent-text) !default;
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
// Semantic spacing aliases — layout-level naming on top of raw scale tokens.
|
|
8
8
|
|
|
9
|
-
$space-inline:
|
|
10
|
-
$space-element:
|
|
11
|
-
$space-component:
|
|
12
|
-
$space-section:
|
|
13
|
-
$space-page:
|
|
9
|
+
$space-inline: sp.spacing(1) !default; // 0.25rem — tight inline gap
|
|
10
|
+
$space-element: sp.spacing(2) !default; // 0.5rem — within a component
|
|
11
|
+
$space-component: sp.spacing(4) !default; // 1rem — between component parts
|
|
12
|
+
$space-section: sp.spacing(16) !default; // 4rem — between page sections
|
|
13
|
+
$space-page: sp.spacing(24) !default; // 6rem — page-level breathing room
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
// Semantic typography role aliases.
|
|
8
8
|
|
|
9
|
-
$font-display:
|
|
10
|
-
$font-heading:
|
|
11
|
-
$font-body:
|
|
12
|
-
$font-mono:
|
|
13
|
-
$font-ui:
|
|
9
|
+
$font-display: ty.font-family("sans") !default; // Hero headings
|
|
10
|
+
$font-heading: ty.font-family("sans") !default; // h1–h6
|
|
11
|
+
$font-body: ty.font-family("sans") !default; // p, li, td
|
|
12
|
+
$font-mono: ty.font-family("mono") !default; // code, pre, kbd
|
|
13
|
+
$font-ui: ty.font-family("sans") !default; // labels, buttons, nav
|
|
@@ -5,21 +5,26 @@
|
|
|
5
5
|
// The light and dark themes (_light.scss, _dark.scss) are the actual emitters.
|
|
6
6
|
// This file documents the full semantic custom property contract
|
|
7
7
|
// that all themes must implement, without producing any CSS output.
|
|
8
|
+
//
|
|
8
9
|
// Semantic custom properties contract:
|
|
10
|
+
//
|
|
9
11
|
// Surfaces
|
|
10
12
|
// --mastors-bg ← page background
|
|
11
13
|
// --mastors-bg-subtle ← subdued page background
|
|
12
14
|
// --mastors-surface ← card / panel surface
|
|
13
15
|
// --mastors-surface-raised ← elevated surface (dropdowns, tooltips)
|
|
14
16
|
// --mastors-surface-overlay ← modal/overlay surface
|
|
17
|
+
//
|
|
15
18
|
// Text
|
|
16
19
|
// --mastors-text ← primary text
|
|
17
20
|
// --mastors-text-muted ← secondary / supporting text
|
|
18
21
|
// --mastors-text-subtle ← tertiary / placeholder text
|
|
19
22
|
// --mastors-text-inverse ← text on dark/accent surfaces
|
|
23
|
+
//
|
|
20
24
|
// Borders
|
|
21
25
|
// --mastors-border ← default border
|
|
22
26
|
// --mastors-border-strong ← emphasis border
|
|
27
|
+
//
|
|
23
28
|
// Brand / Accent
|
|
24
29
|
// --mastors-accent ← primary brand color
|
|
25
30
|
// --mastors-accent-hover ← accent hover state
|
package/scss/themes/_dark.scss
CHANGED
|
@@ -2,18 +2,17 @@
|
|
|
2
2
|
// Dark theme CSS custom property overrides.
|
|
3
3
|
// ─────────────────────────────────────────────────────────────
|
|
4
4
|
|
|
5
|
-
@use "../tokens/color"
|
|
5
|
+
@use "../tokens/color" as ct;
|
|
6
|
+
@use "../config/settings" as cfg;
|
|
6
7
|
|
|
7
8
|
// Dark theme — inverts surface/text/border semantics.
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// "media" → activated by prefers-color-scheme: dark
|
|
9
|
+
// Activated by .dark class on <html> (class mode)
|
|
10
|
+
// or automatically via prefers-color-scheme (media mode).
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
$-dark-selectors: '[data-theme="dark"], .dark';
|
|
13
13
|
|
|
14
|
-
@if
|
|
15
|
-
|
|
16
|
-
.dark {
|
|
14
|
+
@if cfg.config("dark-mode") == "class" {
|
|
15
|
+
#{$-dark-selectors} {
|
|
17
16
|
--mastors-bg: #{ct.color("neutral", 950)};
|
|
18
17
|
--mastors-bg-subtle: #{ct.color("neutral", 900)};
|
|
19
18
|
--mastors-surface: #{ct.color("neutral", 900)};
|
package/scss/tokens/_color.scss
CHANGED
|
@@ -83,18 +83,14 @@ $color-tokens: (
|
|
|
83
83
|
"900": #164e63,
|
|
84
84
|
"950": #083344,
|
|
85
85
|
),
|
|
86
|
-
"white": #
|
|
87
|
-
"black": #
|
|
86
|
+
"white": #ffffff,
|
|
87
|
+
"black": #000000,
|
|
88
88
|
"transparent": transparent,
|
|
89
89
|
) !default;
|
|
90
90
|
|
|
91
91
|
// Accessor: color("primary", 600)
|
|
92
92
|
@function color($palette, $shade: null) {
|
|
93
93
|
$p: map.get($color-tokens, $palette);
|
|
94
|
-
|
|
95
|
-
@
|
|
96
|
-
@return map.get($p, "#{$shade}");
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
@return $p;
|
|
94
|
+
@if $shade == null { @return $p; }
|
|
95
|
+
@return map.get($p, "#{$shade}");
|
|
100
96
|
}
|
|
@@ -4,14 +4,16 @@
|
|
|
4
4
|
|
|
5
5
|
@use "sass:map";
|
|
6
6
|
|
|
7
|
+
// Multi-layer shadow values must be wrapped in extra parens inside a map
|
|
8
|
+
// so the comma is not misread as a map-entry separator.
|
|
7
9
|
$shadow-tokens: (
|
|
8
|
-
"xs": (0 1px 2px 0 rgb(0 0 0 /
|
|
9
|
-
"sm": (0 1px 3px 0 rgb(0 0 0 / 10
|
|
10
|
-
"md": (0 4px 6px -1px rgb(0 0 0 / 10
|
|
11
|
-
"lg": (0 10px 15px -3px rgb(0 0 0 / 10
|
|
12
|
-
"xl": (0 20px 25px -5px rgb(0 0 0 / 10
|
|
13
|
-
"2xl": (0 25px 50px -12px rgb(0 0 0 / 25
|
|
14
|
-
"inner": (inset 0 2px 4px 0 rgb(0 0 0 /
|
|
10
|
+
"xs": (0 1px 2px 0 rgb(0 0 0 / 0.05)),
|
|
11
|
+
"sm": (0 1px 3px 0 rgb(0 0 0 / 0.10), 0 1px 2px -1px rgb(0 0 0 / 0.10)),
|
|
12
|
+
"md": (0 4px 6px -1px rgb(0 0 0 / 0.10), 0 2px 4px -2px rgb(0 0 0 / 0.10)),
|
|
13
|
+
"lg": (0 10px 15px -3px rgb(0 0 0 / 0.10), 0 4px 6px -4px rgb(0 0 0 / 0.10)),
|
|
14
|
+
"xl": (0 20px 25px -5px rgb(0 0 0 / 0.10), 0 8px 10px -6px rgb(0 0 0 / 0.10)),
|
|
15
|
+
"2xl": (0 25px 50px -12px rgb(0 0 0 / 0.25)),
|
|
16
|
+
"inner": (inset 0 2px 4px 0 rgb(0 0 0 / 0.05)),
|
|
15
17
|
"none": none,
|
|
16
18
|
) !default;
|
|
17
19
|
|
package/scss/tokens/_sizing.scss
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
@use "sass:map";
|
|
6
6
|
|
|
7
7
|
$sizing-tokens: (
|
|
8
|
-
|
|
8
|
+
// Fixed scale (shares spacing scale keys)
|
|
9
|
+
"0": 0px,
|
|
9
10
|
"px": 1px,
|
|
10
11
|
"1": 0.25rem,
|
|
11
12
|
"2": 0.5rem,
|
|
@@ -23,15 +24,17 @@ $sizing-tokens: (
|
|
|
23
24
|
"72": 18rem,
|
|
24
25
|
"80": 20rem,
|
|
25
26
|
"96": 24rem,
|
|
27
|
+
// Fractions
|
|
26
28
|
"1\\/2": 50%,
|
|
27
|
-
"1\\/3": 33.
|
|
28
|
-
"2\\/3": 66.
|
|
29
|
+
"1\\/3": 33.333333%,
|
|
30
|
+
"2\\/3": 66.666667%,
|
|
29
31
|
"1\\/4": 25%,
|
|
30
32
|
"3\\/4": 75%,
|
|
31
33
|
"1\\/5": 20%,
|
|
32
34
|
"2\\/5": 40%,
|
|
33
35
|
"3\\/5": 60%,
|
|
34
36
|
"4\\/5": 80%,
|
|
37
|
+
// Keywords
|
|
35
38
|
"auto": auto,
|
|
36
39
|
"full": 100%,
|
|
37
40
|
"screen": 100vw,
|