@mastorscdn/core 1.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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +475 -0
  3. package/dist/mastors-core.css +4566 -0
  4. package/dist/mastors-core.css.map +1 -0
  5. package/dist/mastors-core.min.css +1 -0
  6. package/package.json +82 -0
  7. package/scss/_index.scss +109 -0
  8. package/scss/abstracts/_index.scss +5 -0
  9. package/scss/abstracts/_placeholders.scss +90 -0
  10. package/scss/accessibility/_a11y.scss +97 -0
  11. package/scss/accessibility/_index.scss +12 -0
  12. package/scss/base/_index.scss +16 -0
  13. package/scss/base/_motion.scss +19 -0
  14. package/scss/base/_reset.scss +178 -0
  15. package/scss/config/_index.scss +5 -0
  16. package/scss/config/_settings.scss +29 -0
  17. package/scss/functions/_index.scss +7 -0
  18. package/scss/functions/_map-helpers.scss +30 -0
  19. package/scss/functions/_math.scss +35 -0
  20. package/scss/functions/_token-accessors.scss +85 -0
  21. package/scss/generators/_colors.scss +30 -0
  22. package/scss/generators/_display.scss +78 -0
  23. package/scss/generators/_index.scss +18 -0
  24. package/scss/generators/_opacity.scss +13 -0
  25. package/scss/generators/_radius.scss +33 -0
  26. package/scss/generators/_shadows.scss +13 -0
  27. package/scss/generators/_transitions.scss +13 -0
  28. package/scss/generators/_zindex.scss +13 -0
  29. package/scss/helpers/_container.scss +34 -0
  30. package/scss/helpers/_index.scss +6 -0
  31. package/scss/helpers/_states.scss +120 -0
  32. package/scss/mastors-core.scss +35 -0
  33. package/scss/mixins/_css-vars.scss +77 -0
  34. package/scss/mixins/_helpers.scss +208 -0
  35. package/scss/mixins/_index.scss +7 -0
  36. package/scss/mixins/_responsive.scss +112 -0
  37. package/scss/themes/_custom.scss +33 -0
  38. package/scss/themes/_dark.scss +53 -0
  39. package/scss/themes/_index.scss +7 -0
  40. package/scss/themes/_light.scss +49 -0
  41. package/scss/tokens/_borders.scss +26 -0
  42. package/scss/tokens/_breakpoints.scss +24 -0
  43. package/scss/tokens/_colors.scss +83 -0
  44. package/scss/tokens/_index.scss +13 -0
  45. package/scss/tokens/_motion.scss +46 -0
  46. package/scss/tokens/_opacity.scss +22 -0
  47. package/scss/tokens/_radius.scss +15 -0
  48. package/scss/tokens/_shadows.scss +27 -0
  49. package/scss/tokens/_zindex.scss +27 -0
  50. package/scss/utilities/_borders.scss +35 -0
  51. package/scss/utilities/_index.scss +14 -0
  52. package/scss/utilities/_sizing.scss +131 -0
  53. package/scss/utilities/_spacing.scss +68 -0
  54. package/scss/vendors/_index.scss +5 -0
  55. package/scss/vendors/_normalize.scss +69 -0
@@ -0,0 +1,120 @@
1
+ // =============================================================================
2
+ // Mastors-Core | Helpers: Interaction States
3
+ // Reusable state classes for hover, focus, active, disabled
4
+ // =============================================================================
5
+
6
+ // --- Interactive base ---
7
+ .mastors-interactive {
8
+ cursor: pointer;
9
+ transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);
10
+ user-select: none;
11
+
12
+ @media (hover: hover) and (pointer: fine) {
13
+ &:hover { opacity: 0.85; }
14
+ }
15
+
16
+ &:active { transform: scale(0.98); }
17
+
18
+ &:disabled,
19
+ &[aria-disabled='true'] {
20
+ opacity: 0.5;
21
+ cursor: not-allowed;
22
+ pointer-events: none;
23
+ }
24
+ }
25
+
26
+ // --- Hover opacity ---
27
+ .mastors-hover-opacity {
28
+ @media (hover: hover) and (pointer: fine) {
29
+ &:hover { opacity: 0.8; }
30
+ }
31
+ }
32
+
33
+ // --- Hover lift ---
34
+ .mastors-hover-lift {
35
+ transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1),
36
+ box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
37
+
38
+ @media (hover: hover) and (pointer: fine) {
39
+ &:hover {
40
+ transform: translateY(-4px);
41
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);
42
+ }
43
+ }
44
+ }
45
+
46
+ // --- Hover scale ---
47
+ .mastors-hover-scale {
48
+ transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
49
+
50
+ @media (hover: hover) and (pointer: fine) {
51
+ &:hover { transform: scale(1.02); }
52
+ }
53
+ &:active { transform: scale(0.98); }
54
+ }
55
+
56
+ // --- Loading skeleton ---
57
+ .mastors-skeleton {
58
+ background: linear-gradient(90deg, #e5e7eb 25%, #f3f4f6 50%, #e5e7eb 75%);
59
+ background-size: 200% 100%;
60
+ animation: mastors-skeleton-pulse 1.5s ease-in-out infinite;
61
+ border-radius: 4px;
62
+
63
+ @keyframes mastors-skeleton-pulse {
64
+ 0% { background-position: 200% 0; }
65
+ 100% { background-position: -200% 0; }
66
+ }
67
+
68
+ [data-theme='dark'] & {
69
+ background: linear-gradient(90deg, #374151 25%, #4b5563 50%, #374151 75%);
70
+ background-size: 200% 100%;
71
+ }
72
+ }
73
+
74
+ // --- Pulse animation ---
75
+ .mastors-pulse {
76
+ animation: mastors-pulse-anim 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
77
+
78
+ @keyframes mastors-pulse-anim {
79
+ 0%, 100% { opacity: 1; }
80
+ 50% { opacity: 0.5; }
81
+ }
82
+ }
83
+
84
+ // --- Spin animation ---
85
+ .mastors-spin {
86
+ animation: mastors-spin-anim 1s linear infinite;
87
+
88
+ @keyframes mastors-spin-anim {
89
+ from { transform: rotate(0deg); }
90
+ to { transform: rotate(360deg); }
91
+ }
92
+ }
93
+
94
+ // --- Ping animation ---
95
+ .mastors-ping {
96
+ animation: mastors-ping-anim 1s cubic-bezier(0, 0, 0.2, 1) infinite;
97
+
98
+ @keyframes mastors-ping-anim {
99
+ 75%, 100% {
100
+ transform: scale(2);
101
+ opacity: 0;
102
+ }
103
+ }
104
+ }
105
+
106
+ // --- Bounce animation ---
107
+ .mastors-bounce {
108
+ animation: mastors-bounce-anim 1s infinite;
109
+
110
+ @keyframes mastors-bounce-anim {
111
+ 0%, 100% {
112
+ transform: translateY(-25%);
113
+ animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
114
+ }
115
+ 50% {
116
+ transform: none;
117
+ animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
118
+ }
119
+ }
120
+ }
@@ -0,0 +1,35 @@
1
+ // =============================================================================
2
+ // Mastors-Core | mastors-core.scss
3
+ // Main compiled output entry — produces the full CSS bundle
4
+ //
5
+ // Compile this file to get mastors-core.css
6
+ // All runtime CSS is generated here. _index.scss is for SCSS @use only.
7
+ //
8
+ // RULE: All @use statements must appear before any other rules.
9
+ // Conditional output is handled inside each module's own _index.scss,
10
+ // or via guard mixins called below after all @use declarations.
11
+ // =============================================================================
12
+
13
+ // ── All @use declarations (must be first, no exceptions) ────────────────────
14
+ @use 'sass:meta';
15
+ @use 'config' as cfg;
16
+ @use 'tokens';
17
+ @use 'functions';
18
+ @use 'mixins';
19
+ @use 'mixins/css-vars' as cvars;
20
+ @use 'abstracts';
21
+ @use 'vendors';
22
+ @use 'base';
23
+ @use 'themes';
24
+ @use 'accessibility';
25
+ @use 'helpers';
26
+ @use 'generators';
27
+ @use 'utilities';
28
+
29
+ // ── Output ───────────────────────────────────────────────────────────────────
30
+ // All @use above produces no CSS on its own (modules guard their own output).
31
+ // The only explicit CSS trigger needed here is the CSS variable engine.
32
+
33
+ // ── 6. CSS Variable Engine ───────────────────────────────────────────────────
34
+ // Guarded by cfg.$enable-css-variables inside the mixin itself.
35
+ @include cvars.generate-all-vars-if-enabled;
@@ -0,0 +1,77 @@
1
+ // =============================================================================
2
+ // Mastors-Core | Mixins: CSS Variable Engine
3
+ // Generates CSS custom properties from token maps
4
+ // =============================================================================
5
+
6
+ @use 'sass:map';
7
+ @use 'sass:string';
8
+ @use '../config/settings' as cfg;
9
+ @use '../tokens/colors' as t-colors;
10
+ @use '../tokens/shadows' as t-shadows;
11
+ @use '../tokens/radius' as t-radius;
12
+ @use '../tokens/zindex' as t-z;
13
+ @use '../tokens/opacity' as t-opacity;
14
+ @use '../tokens/motion' as t-motion;
15
+ @use '../tokens/borders' as t-borders;
16
+
17
+ // --- Generate CSS vars from any map ---
18
+ @mixin generate-vars($map, $prefix, $root: ':root') {
19
+ #{$root} {
20
+ @each $key, $value in $map {
21
+ --#{cfg.$mastors-prefix}-#{$prefix}-#{$key}: #{$value};
22
+ }
23
+ }
24
+ }
25
+
26
+ // --- Generate all core CSS variables (unconditional) ---
27
+ @mixin generate-all-vars {
28
+ :root {
29
+ // Colors
30
+ @each $key, $value in t-colors.$mastors-colors {
31
+ --#{cfg.$mastors-prefix}-color-#{$key}: #{$value};
32
+ }
33
+
34
+ // Semantic
35
+ @each $key, $value in t-colors.$mastors-semantic {
36
+ --#{cfg.$mastors-prefix}-#{$key}: #{$value};
37
+ }
38
+
39
+ // Shadows
40
+ @each $key, $value in t-shadows.$mastors-shadows {
41
+ --#{cfg.$mastors-prefix}-shadow-#{$key}: #{$value};
42
+ }
43
+
44
+ // Radius
45
+ @each $key, $value in t-radius.$mastors-radius {
46
+ --#{cfg.$mastors-prefix}-radius-#{$key}: #{$value};
47
+ }
48
+
49
+ // Z-Index
50
+ @each $key, $value in t-z.$mastors-z-index {
51
+ --#{cfg.$mastors-prefix}-z-#{$key}: #{$value};
52
+ }
53
+
54
+ // Opacity
55
+ @each $key, $value in t-opacity.$mastors-opacity {
56
+ --#{cfg.$mastors-prefix}-opacity-#{$key}: #{$value};
57
+ }
58
+
59
+ // Durations
60
+ @each $key, $value in t-motion.$mastors-durations {
61
+ --#{cfg.$mastors-prefix}-duration-#{$key}: #{$value};
62
+ }
63
+
64
+ // Easings
65
+ @each $key, $value in t-motion.$mastors-easings {
66
+ --#{cfg.$mastors-prefix}-easing-#{$key}: #{$value};
67
+ }
68
+ }
69
+ }
70
+
71
+ // --- Conditionally generate all CSS variables (checks $enable-css-variables) ---
72
+ // Used by mastors-core.scss to avoid @use inside @if.
73
+ @mixin generate-all-vars-if-enabled {
74
+ @if cfg.$enable-css-variables {
75
+ @include generate-all-vars;
76
+ }
77
+ }
@@ -0,0 +1,208 @@
1
+ // =============================================================================
2
+ // Mastors-Core | Mixins: Helpers
3
+ // Reusable UI pattern mixins for enterprise components
4
+ // =============================================================================
5
+
6
+ @use 'sass:map';
7
+ @use '../tokens/motion' as t-motion;
8
+ @use '../tokens/radius' as t-radius;
9
+ @use '../tokens/shadows' as t-shadows;
10
+ @use '../tokens/colors' as t-colors;
11
+
12
+ // --- Absolute Center ---
13
+ @mixin absolute-center {
14
+ position: absolute;
15
+ top: 50%;
16
+ left: 50%;
17
+ transform: translate(-50%, -50%);
18
+ }
19
+
20
+ // --- Flex Center ---
21
+ @mixin flex-center {
22
+ display: flex;
23
+ align-items: center;
24
+ justify-content: center;
25
+ }
26
+
27
+ // --- Text Truncate (single line) ---
28
+ @mixin truncate {
29
+ overflow: hidden;
30
+ text-overflow: ellipsis;
31
+ white-space: nowrap;
32
+ }
33
+
34
+ // --- Line Clamp (multi-line) ---
35
+ @mixin line-clamp($lines: 2) {
36
+ display: -webkit-box;
37
+ -webkit-line-clamp: $lines;
38
+ -webkit-box-orient: vertical;
39
+ overflow: hidden;
40
+ }
41
+
42
+ // --- Aspect Ratio ---
43
+ @mixin aspect-ratio($ratio: '16/9') {
44
+ aspect-ratio: #{$ratio};
45
+ }
46
+
47
+ // --- Glassmorphism ---
48
+ @mixin glassmorphism(
49
+ $blur: 16px,
50
+ $bg: rgba(255, 255, 255, 0.12),
51
+ $border: rgba(255, 255, 255, 0.18),
52
+ $shadow: 0 8px 32px rgba(0, 0, 0, 0.15)
53
+ ) {
54
+ background: $bg;
55
+ backdrop-filter: blur($blur);
56
+ -webkit-backdrop-filter: blur($blur);
57
+ border: 1px solid $border;
58
+ box-shadow: $shadow;
59
+ }
60
+
61
+ // --- Neumorphism ---
62
+ @mixin neumorphism(
63
+ $bg: #e0e5ec,
64
+ $light: rgba(255, 255, 255, 0.8),
65
+ $dark: rgba(163, 177, 198, 0.6),
66
+ $intensity: 6px
67
+ ) {
68
+ background: $bg;
69
+ box-shadow:
70
+ #{$intensity} #{$intensity} #{$intensity * 2} $dark,
71
+ #{-$intensity} #{-$intensity} #{$intensity * 2} $light;
72
+ }
73
+
74
+ // --- Custom Scrollbar ---
75
+ @mixin custom-scrollbar(
76
+ $width: 6px,
77
+ $track: transparent,
78
+ $thumb: rgba(0, 0, 0, 0.2),
79
+ $thumb-hover: rgba(0, 0, 0, 0.4)
80
+ ) {
81
+ scrollbar-width: thin;
82
+ scrollbar-color: $thumb $track;
83
+
84
+ &::-webkit-scrollbar {
85
+ width: $width;
86
+ height: $width;
87
+ }
88
+
89
+ &::-webkit-scrollbar-track {
90
+ background: $track;
91
+ }
92
+
93
+ &::-webkit-scrollbar-thumb {
94
+ background: $thumb;
95
+ border-radius: 9999px;
96
+
97
+ &:hover {
98
+ background: $thumb-hover;
99
+ }
100
+ }
101
+ }
102
+
103
+ // --- Focus Ring ---
104
+ @mixin focus-ring(
105
+ $color: #2563eb,
106
+ $width: 3px,
107
+ $offset: 2px,
108
+ $style: solid
109
+ ) {
110
+ outline: $width $style $color;
111
+ outline-offset: $offset;
112
+ }
113
+
114
+ // --- Focus Visible ---
115
+ @mixin focus-visible {
116
+ &:focus { outline: none; }
117
+ &:focus-visible {
118
+ @include focus-ring;
119
+ }
120
+ }
121
+
122
+ // --- Smooth Transition ---
123
+ @mixin smooth-transition($props: all, $dur: 200ms, $ease: cubic-bezier(0.4, 0, 0.2, 1)) {
124
+ transition: $props $dur $ease;
125
+ }
126
+
127
+ // --- Hover lift effect ---
128
+ @mixin hover-lift($y: -4px, $shadow: 0 10px 20px rgba(0,0,0,0.15)) {
129
+ transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1),
130
+ box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
131
+
132
+ @media (hover: hover) and (pointer: fine) {
133
+ &:hover {
134
+ transform: translateY($y);
135
+ box-shadow: $shadow;
136
+ }
137
+ }
138
+ }
139
+
140
+ // --- Loading State ---
141
+ @mixin loading-state {
142
+ pointer-events: none;
143
+ opacity: 0.7;
144
+ cursor: wait;
145
+ position: relative;
146
+
147
+ &::after {
148
+ content: '';
149
+ position: absolute;
150
+ inset: 0;
151
+ background: rgba(255, 255, 255, 0.3);
152
+ border-radius: inherit;
153
+ }
154
+ }
155
+
156
+ // --- Skeleton Loading ---
157
+ @mixin skeleton-loading(
158
+ $bg-from: #e5e7eb,
159
+ $bg-to: #f3f4f6,
160
+ $duration: 1.5s
161
+ ) {
162
+ background: linear-gradient(
163
+ 90deg,
164
+ $bg-from 25%,
165
+ $bg-to 50%,
166
+ $bg-from 75%
167
+ );
168
+ background-size: 200% 100%;
169
+ animation: mastors-skeleton $duration ease-in-out infinite;
170
+
171
+ @keyframes mastors-skeleton {
172
+ 0% { background-position: 200% 0; }
173
+ 100% { background-position: -200% 0; }
174
+ }
175
+ }
176
+
177
+ // --- Cover / Fill ---
178
+ @mixin cover {
179
+ position: absolute;
180
+ inset: 0;
181
+ width: 100%;
182
+ height: 100%;
183
+ }
184
+
185
+ // --- Visually Hidden (accessibility) ---
186
+ @mixin visually-hidden {
187
+ position: absolute;
188
+ width: 1px;
189
+ height: 1px;
190
+ padding: 0;
191
+ margin: -1px;
192
+ overflow: hidden;
193
+ clip: rect(0, 0, 0, 0);
194
+ white-space: nowrap;
195
+ border-width: 0;
196
+ }
197
+
198
+ // --- Reset visually hidden ---
199
+ @mixin visually-visible {
200
+ position: static;
201
+ width: auto;
202
+ height: auto;
203
+ padding: 0;
204
+ margin: 0;
205
+ overflow: visible;
206
+ clip: auto;
207
+ white-space: normal;
208
+ }
@@ -0,0 +1,7 @@
1
+ // =============================================================================
2
+ // Mastors-Core | Mixins: Index
3
+ // =============================================================================
4
+
5
+ @forward 'responsive';
6
+ @forward 'helpers';
7
+ @forward 'css-vars';
@@ -0,0 +1,112 @@
1
+ // =============================================================================
2
+ // Mastors-Core | Mixins: Responsive Engine
3
+ // Modern media query system for Mastors CDN
4
+ // =============================================================================
5
+
6
+ @use 'sass:map';
7
+ @use 'sass:list';
8
+ @use '../tokens/breakpoints' as t;
9
+
10
+ // --- up($bp) — min-width (mobile first) ---
11
+ @mixin up($bp) {
12
+ @if map.has-key(t.$mastors-breakpoints, $bp) {
13
+ $value: map.get(t.$mastors-breakpoints, $bp);
14
+ @if $value == 0 {
15
+ @content;
16
+ } @else {
17
+ @media (min-width: #{$value}) {
18
+ @content;
19
+ }
20
+ }
21
+ } @else {
22
+ // Custom pixel value passed
23
+ @media (min-width: #{$bp}) {
24
+ @content;
25
+ }
26
+ }
27
+ }
28
+
29
+ // --- down($bp) — max-width ---
30
+ @mixin down($bp) {
31
+ @if map.has-key(t.$mastors-breakpoints, $bp) {
32
+ $value: map.get(t.$mastors-breakpoints, $bp);
33
+ $max: $value - 0.02px;
34
+ @if $value == 0 {
35
+ @warn '[mastors] down(xs) targets nothing. Use up(sm) instead.';
36
+ } @else {
37
+ @media (max-width: #{$max}) {
38
+ @content;
39
+ }
40
+ }
41
+ } @else {
42
+ @media (max-width: #{$bp}) {
43
+ @content;
44
+ }
45
+ }
46
+ }
47
+
48
+ // --- between($lower, $upper) ---
49
+ @mixin between($lower, $upper) {
50
+ $min: map.get(t.$mastors-breakpoints, $lower);
51
+ $max: map.get(t.$mastors-breakpoints, $upper);
52
+
53
+ @if $min == null or $max == null {
54
+ @warn '[mastors] between() requires valid breakpoint keys.';
55
+ } @else {
56
+ @media (min-width: #{$min}) and (max-width: #{$max - 0.02px}) {
57
+ @content;
58
+ }
59
+ }
60
+ }
61
+
62
+ // --- only($bp) — single breakpoint range ---
63
+ @mixin only($bp) {
64
+ $keys: map.keys(t.$mastors-breakpoints);
65
+ $index: list.index($keys, $bp);
66
+
67
+ @if $index == null {
68
+ @warn '[mastors] only() requires a valid breakpoint key.';
69
+ } @else if $index == list.length($keys) {
70
+ @include up($bp) { @content; }
71
+ } @else {
72
+ $next: list.nth($keys, $index + 1);
73
+ @include between($bp, $next) { @content; }
74
+ }
75
+ }
76
+
77
+ // --- hover (pointer device check) ---
78
+ @mixin hover {
79
+ @media (hover: hover) and (pointer: fine) {
80
+ &:hover { @content; }
81
+ }
82
+ }
83
+
84
+ // --- dark media query ---
85
+ @mixin prefers-dark {
86
+ @media (prefers-color-scheme: dark) {
87
+ @content;
88
+ }
89
+ }
90
+
91
+ // --- reduced motion ---
92
+ @mixin prefers-reduced-motion {
93
+ @media (prefers-reduced-motion: reduce) {
94
+ @content;
95
+ }
96
+ }
97
+
98
+ // --- print ---
99
+ @mixin print {
100
+ @media print {
101
+ @content;
102
+ }
103
+ }
104
+
105
+ // --- portrait / landscape ---
106
+ @mixin portrait {
107
+ @media (orientation: portrait) { @content; }
108
+ }
109
+
110
+ @mixin landscape {
111
+ @media (orientation: landscape) { @content; }
112
+ }
@@ -0,0 +1,33 @@
1
+ // =============================================================================
2
+ // Mastors-Core | Themes: Custom Theme API
3
+ // Allows building custom themes for ERP, eCommerce, SaaS products
4
+ // =============================================================================
5
+
6
+ // Usage:
7
+ // @use 'mastors-core/themes/custom' with (
8
+ // $theme-name: 'enterprise',
9
+ // $custom-tokens: (
10
+ // '--mastors-color-primary': #0f4c75,
11
+ // '--mastors-bg-body': #1b262c,
12
+ // )
13
+ // );
14
+
15
+ @use 'sass:map';
16
+ @use 'sass:list';
17
+ @use '../config/settings' as cfg;
18
+
19
+ $theme-name: 'custom' !default;
20
+ $custom-tokens: () !default;
21
+
22
+ @mixin apply-custom-theme($name: $theme-name, $tokens: $custom-tokens) {
23
+ [#{cfg.$mastors-theme-attr}='#{$name}'] {
24
+ @each $prop, $value in $tokens {
25
+ #{$prop}: #{$value};
26
+ }
27
+ }
28
+ }
29
+
30
+ // Auto-apply if custom tokens provided
31
+ @if list.length(map.keys($custom-tokens)) > 0 {
32
+ @include apply-custom-theme;
33
+ }
@@ -0,0 +1,53 @@
1
+ // =============================================================================
2
+ // Mastors-Core | Themes: Dark Theme
3
+ // =============================================================================
4
+
5
+ @use '../config/settings' as cfg;
6
+
7
+ @mixin dark-theme {
8
+ --mastors-text-primary: #f9fafb;
9
+ --mastors-text-secondary: #e5e7eb;
10
+ --mastors-text-muted: #9ca3af;
11
+ --mastors-text-disabled: #6b7280;
12
+ --mastors-text-inverse: #111827;
13
+
14
+ --mastors-bg-body: #0f172a;
15
+ --mastors-bg-subtle: #1e293b;
16
+ --mastors-bg-muted: #334155;
17
+ --mastors-bg-inverse: #f9fafb;
18
+
19
+ --mastors-border-default: #334155;
20
+ --mastors-border-strong: #475569;
21
+ --mastors-border-focus: #60a5fa;
22
+
23
+ --mastors-surface: #1e293b;
24
+ --mastors-surface-raised: #334155;
25
+ --mastors-surface-overlay: rgba(15, 23, 42, 0.95);
26
+
27
+ --mastors-shadow-ambient: 0 1px 3px rgba(0, 0, 0, 0.50);
28
+
29
+ --mastors-color-primary: #60a5fa;
30
+ --mastors-color-secondary: #a78bfa;
31
+ --mastors-color-accent: #38bdf8;
32
+ --mastors-color-success: #4ade80;
33
+ --mastors-color-warning: #fbbf24;
34
+ --mastors-color-danger: #f87171;
35
+ --mastors-color-info: #22d3ee;
36
+
37
+ --mastors-scrollbar-thumb: rgba(255, 255, 255, 0.2);
38
+ --mastors-scrollbar-track: transparent;
39
+ }
40
+
41
+ // Attribute-based dark mode
42
+ @if cfg.$enable-dark-theme {
43
+ [#{cfg.$mastors-theme-attr}='dark'] {
44
+ @include dark-theme;
45
+ }
46
+
47
+ // OS-level dark mode
48
+ @media (prefers-color-scheme: dark) {
49
+ :root:not([#{cfg.$mastors-theme-attr}='light']) {
50
+ @include dark-theme;
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,7 @@
1
+ // =============================================================================
2
+ // Mastors-Core | Themes: Index
3
+ // =============================================================================
4
+
5
+ @forward 'light';
6
+ @forward 'dark';
7
+ @forward 'custom';
@@ -0,0 +1,49 @@
1
+ // =============================================================================
2
+ // Mastors-Core | Themes: Light Theme (default)
3
+ // =============================================================================
4
+
5
+ @use '../config/settings' as cfg;
6
+
7
+ @mixin light-theme {
8
+ --mastors-text-primary: #111827;
9
+ --mastors-text-secondary: #374151;
10
+ --mastors-text-muted: #6b7280;
11
+ --mastors-text-disabled: #9ca3af;
12
+ --mastors-text-inverse: #ffffff;
13
+
14
+ --mastors-bg-body: #ffffff;
15
+ --mastors-bg-subtle: #f9fafb;
16
+ --mastors-bg-muted: #f3f4f6;
17
+ --mastors-bg-inverse: #111827;
18
+
19
+ --mastors-border-default: #e5e7eb;
20
+ --mastors-border-strong: #d1d5db;
21
+ --mastors-border-focus: #2563eb;
22
+
23
+ --mastors-surface: #ffffff;
24
+ --mastors-surface-raised: #f9fafb;
25
+ --mastors-surface-overlay: rgba(255, 255, 255, 0.95);
26
+
27
+ --mastors-shadow-ambient: 0 1px 3px rgba(0, 0, 0, 0.10);
28
+
29
+ --mastors-color-primary: #2563eb;
30
+ --mastors-color-secondary: #7c3aed;
31
+ --mastors-color-accent: #0ea5e9;
32
+ --mastors-color-success: #16a34a;
33
+ --mastors-color-warning: #d97706;
34
+ --mastors-color-danger: #dc2626;
35
+ --mastors-color-info: #0891b2;
36
+
37
+ --mastors-scrollbar-thumb: rgba(0, 0, 0, 0.2);
38
+ --mastors-scrollbar-track: transparent;
39
+ }
40
+
41
+ // Apply to :root
42
+ :root {
43
+ @include light-theme;
44
+ }
45
+
46
+ // Explicit light attribute
47
+ [#{cfg.$mastors-theme-attr}='light'] {
48
+ @include light-theme;
49
+ }