@mastorscdn/core 1.0.0 → 1.0.2

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/index.js ADDED
@@ -0,0 +1,39 @@
1
+ // =============================================================================
2
+ // @mastorscdn/core | index.js
3
+ // JavaScript entry point — exposes helpers for tooling integrations.
4
+ //
5
+ // What this gives you:
6
+ // const mc = require('@mastorscdn/core');
7
+ // mc.sassLoadPaths → pass to Vite / Next sassOptions.loadPaths
8
+ // mc.importer → pass to sass.compile({ importers: [mc.importer] })
9
+ // mc.scssEntry → absolute path to scss/_index.scss
10
+ // =============================================================================
11
+
12
+ 'use strict';
13
+
14
+ const path = require('path');
15
+ const { importer, getLoadPath, getNodeModulesPath } = require('./importer');
16
+
17
+ const PKG_ROOT = path.resolve(__dirname);
18
+ const SCSS_ENTRY = path.join(PKG_ROOT, 'scss', '_index.scss');
19
+ const SCSS_COMPILE = path.join(PKG_ROOT, 'scss', 'mastors-core.scss');
20
+
21
+ module.exports = {
22
+ /** Sass FileImporter for programmatic sass.compile() */
23
+ importer,
24
+
25
+ /** Absolute path to this package's root (for --load-path) */
26
+ getLoadPath,
27
+
28
+ /** Absolute path to node_modules containing this package */
29
+ getNodeModulesPath,
30
+
31
+ /** Ready-to-use array for Vite / Next.js sassOptions.loadPaths */
32
+ get sassLoadPaths() { return [getNodeModulesPath()]; },
33
+
34
+ /** scss/_index.scss — use for @use API (no CSS output) */
35
+ scssEntry: SCSS_ENTRY,
36
+
37
+ /** scss/mastors-core.scss — compile this for the full CSS bundle */
38
+ scssCompileEntry: SCSS_COMPILE,
39
+ };
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@mastorscdn/core",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Mastors-Core — foundational SCSS architecture for the Mastors CDN ecosystem",
5
- "main": "scss/_index.scss",
6
- "sass": "scss/_index.scss",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "sass": "scss/_index.scss",
7
8
  "style": "dist/mastors-core.css",
8
9
  "keywords": [
9
10
  "scss",
@@ -36,34 +37,46 @@
36
37
  "license": "MIT",
37
38
  "exports": {
38
39
  ".": {
39
- "sass": "./scss/_index.scss",
40
- "style": "./dist/mastors-core.css"
40
+ "sass": "./scss/_index.scss",
41
+ "scss": "./scss/_index.scss",
42
+ "style": "./dist/mastors-core.css",
43
+ "require": "./index.js",
44
+ "import": "./index.js",
45
+ "default": "./dist/mastors-core.css"
41
46
  },
42
- "./dist/mastors-core.css": "./dist/mastors-core.css",
47
+ "./importer": "./importer.js",
48
+ "./scss": "./scss/_index.scss",
49
+ "./scss/*": "./scss/*",
50
+ "./dist/mastors-core.css": "./dist/mastors-core.css",
43
51
  "./dist/mastors-core.min.css": "./dist/mastors-core.min.css"
44
52
  },
45
53
  "files": [
46
54
  "dist/",
47
55
  "scss/",
56
+ "scripts/",
57
+ "index.js",
58
+ "index.d.ts",
59
+ "importer.js",
48
60
  "README.md",
49
61
  "LICENSE"
50
62
  ],
51
63
  "scripts": {
52
- "build": "vite build",
53
- "dev": "vite",
54
- "sass:build": "sass scss/mastors-core.scss dist/mastors-core.css --style expanded --source-map",
55
- "sass:min": "sass scss/mastors-core.scss dist/mastors-core.min.css --style compressed --no-source-map",
56
- "sass:watch": "sass --watch scss/mastors-core.scss:dist/mastors-core.css --style expanded --source-map",
57
- "sass:all": "npm run sass:build && npm run sass:min",
58
- "build:all": "npm run sass:all && npm run build",
59
- "clean": "rimraf dist",
60
- "prebuild": "npm run clean",
64
+ "postinstall": "node scripts/postinstall.js",
65
+ "build": "vite build",
66
+ "dev": "vite",
67
+ "sass:build": "sass scss/mastors-core.scss dist/mastors-core.css --style expanded --source-map --load-path=node_modules",
68
+ "sass:min": "sass scss/mastors-core.scss dist/mastors-core.min.css --style compressed --no-source-map --load-path=node_modules",
69
+ "sass:watch": "sass --watch scss/mastors-core.scss:dist/mastors-core.css --style expanded --source-map --load-path=node_modules",
70
+ "sass:all": "npm run sass:build && npm run sass:min",
71
+ "build:all": "npm run sass:all && npm run build",
72
+ "clean": "rimraf dist",
73
+ "prebuild": "npm run clean",
61
74
  "prepublishOnly": "npm run sass:all"
62
75
  },
63
76
  "devDependencies": {
64
- "sass": "^1.77.0",
65
- "vite": "^5.3.0",
66
- "rimraf": "^5.0.0"
77
+ "rimraf": "^5.0.0",
78
+ "sass": "^1.77.0",
79
+ "vite": "^5.3.0"
67
80
  },
68
81
  "peerDependencies": {
69
82
  "sass": ">=1.70.0"
@@ -73,10 +86,10 @@
73
86
  },
74
87
  "repository": {
75
88
  "type": "git",
76
- "url": "git+https://github.com/KEHEM-IT/Mastors-Core.git"
89
+ "url": "git+https://github.com/KEHEM-IT/Mastors-Core.git"
77
90
  },
78
91
  "bugs": {
79
92
  "url": "https://github.com/KEHEM-IT/Mastors-Core/issues"
80
93
  },
81
- "homepage": "https://mastorscdn.kehem.com/mastors-core"
82
- }
94
+ "homepage": "https://mastorscdn.kehem.com/"
95
+ }
@@ -0,0 +1,325 @@
1
+ #!/usr/bin/env node
2
+ // =============================================================================
3
+ // Mastors-Core | postinstall.js
4
+ // Runs after `npm install @mastorscdn/core`
5
+ // Auto-detects the user's framework and prints the exact setup guide.
6
+ // =============================================================================
7
+
8
+ 'use strict';
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+
13
+ // ── ANSI colours ─────────────────────────────────────────────────────────────
14
+ const C = {
15
+ reset: '\x1b[0m',
16
+ bold: '\x1b[1m',
17
+ cyan: '\x1b[36m',
18
+ green: '\x1b[32m',
19
+ yellow: '\x1b[33m',
20
+ magenta: '\x1b[35m',
21
+ gray: '\x1b[90m',
22
+ };
23
+
24
+ const b = (s) => `${C.bold}${s}${C.reset}`;
25
+ const c = (s) => `${C.cyan}${s}${C.reset}`;
26
+ const g = (s) => `${C.green}${s}${C.reset}`;
27
+ const y = (s) => `${C.yellow}${s}${C.reset}`;
28
+ const m = (s) => `${C.magenta}${s}${C.reset}`;
29
+ const gr = (s) => `${C.gray}${s}${C.reset}`;
30
+
31
+ // ── Resolve user's project root ───────────────────────────────────────────────
32
+ // When installed as a dep, __dirname = .../node_modules/@mastorscdn/core/scripts
33
+ // So root is several levels up from here.
34
+ function findProjectRoot() {
35
+ let dir = __dirname;
36
+ for (let i = 0; i < 6; i++) {
37
+ const pkg = path.join(dir, 'package.json');
38
+ if (fs.existsSync(pkg)) {
39
+ try {
40
+ const p = JSON.parse(fs.readFileSync(pkg, 'utf8'));
41
+ if (p.name !== '@mastorscdn/core') return dir;
42
+ } catch (_) {}
43
+ }
44
+ const parent = path.dirname(dir);
45
+ if (parent === dir) break;
46
+ dir = parent;
47
+ }
48
+ return process.cwd();
49
+ }
50
+
51
+ const ROOT = findProjectRoot();
52
+
53
+ function getUserPkg() {
54
+ try {
55
+ return JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8'));
56
+ } catch (_) {
57
+ return {};
58
+ }
59
+ }
60
+
61
+ // ── Framework detection ───────────────────────────────────────────────────────
62
+ function detectFramework(pkg) {
63
+ const all = {
64
+ ...pkg.dependencies,
65
+ ...pkg.devDependencies,
66
+ ...pkg.peerDependencies,
67
+ };
68
+ const has = (name) => Boolean(all[name]);
69
+
70
+ if (has('next')) return 'next';
71
+ if (has('nuxt') || has('@nuxt/ui')) return 'nuxt';
72
+ if (has('astro') || has('@astrojs/react')) return 'astro';
73
+ if (has('@sveltejs/kit')) return 'sveltekit';
74
+ if (has('svelte')) return 'svelte';
75
+ if (has('@remix-run/react') || has('@remix-run/node')) return 'remix';
76
+ if (has('vite') && has('vue')) return 'vite-vue';
77
+ if (has('vite') && has('react')) return 'vite-react';
78
+ if (has('vite')) return 'vite';
79
+ if (has('vue')) return 'vue-cli';
80
+ if (has('@angular/core')) return 'angular';
81
+ if (has('react')) return 'react';
82
+ return 'node';
83
+ }
84
+
85
+ // ── Banner ────────────────────────────────────────────────────────────────────
86
+ function banner() {
87
+ console.log('');
88
+ console.log(b(c(' ╔══════════════════════════════════════════╗')));
89
+ console.log(b(c(' ║ @mastorscdn/core installed! ║')));
90
+ console.log(b(c(' ╚══════════════════════════════════════════╝')));
91
+ console.log('');
92
+ }
93
+
94
+ // ── Guides ────────────────────────────────────────────────────────────────────
95
+
96
+ function guideNode() {
97
+ console.log(b(g(' ✔ Plain Node + Sass')));
98
+ console.log('');
99
+ console.log(' Run sass with --load-path:');
100
+ console.log('');
101
+ console.log(c(' sass --watch src/main.scss:dist/main.css --load-path=node_modules'));
102
+ console.log('');
103
+ console.log(' Or add to your package.json scripts:');
104
+ console.log('');
105
+ console.log(gr(' "sass:watch": "sass --watch src/main.scss:dist/main.css --load-path=node_modules"'));
106
+ console.log('');
107
+ console.log(' Then in your SCSS:');
108
+ console.log(m(" @use '@mastorscdn/core' as mc;"));
109
+ console.log('');
110
+ }
111
+
112
+ function guideNext() {
113
+ console.log(b(g(' ✔ Next.js detected')));
114
+ console.log('');
115
+ console.log(' Add to ' + c('next.config.mjs') + ':');
116
+ console.log('');
117
+ console.log(gr(" const nextConfig = {"));
118
+ console.log(gr(" sassOptions: { loadPaths: ['./node_modules'] },"));
119
+ console.log(gr(" };"));
120
+ console.log(gr(" export default nextConfig;"));
121
+ console.log('');
122
+ console.log(' Import in ' + c('app/layout.tsx') + ' or ' + c('pages/_app.js') + ':');
123
+ console.log(gr(" import '../styles/globals.scss';"));
124
+ console.log('');
125
+ console.log(' In globals.scss:');
126
+ console.log(m(" @use '@mastorscdn/core' as mc;"));
127
+ console.log('');
128
+ }
129
+
130
+ function guideVite(flavour) {
131
+ const label = { 'vite-vue': 'Vite + Vue', 'vite-react': 'Vite + React', 'vite': 'Vite' }[flavour] || 'Vite';
132
+ console.log(b(g(` ✔ ${label} detected`)));
133
+ console.log('');
134
+ console.log(' Add to ' + c('vite.config.js') + ':');
135
+ console.log('');
136
+ console.log(gr(" import path from 'path';"));
137
+ console.log(gr(" export default defineConfig({"));
138
+ console.log(gr(" css: {"));
139
+ console.log(gr(" preprocessorOptions: {"));
140
+ console.log(gr(" scss: {"));
141
+ console.log(gr(" api: 'modern-compiler',"));
142
+ console.log(gr(" loadPaths: [path.resolve(__dirname, 'node_modules')],"));
143
+ console.log(gr(" },"));
144
+ console.log(gr(" },"));
145
+ console.log(gr(" },"));
146
+ console.log(gr(" });"));
147
+ console.log('');
148
+ console.log(m(" @use '@mastorscdn/core' as mc;"));
149
+ console.log('');
150
+ }
151
+
152
+ function guideNuxt() {
153
+ console.log(b(g(' ✔ Nuxt detected')));
154
+ console.log('');
155
+ console.log(' Add to ' + c('nuxt.config.ts') + ':');
156
+ console.log('');
157
+ console.log(gr(" export default defineNuxtConfig({"));
158
+ console.log(gr(" vite: {"));
159
+ console.log(gr(" css: {"));
160
+ console.log(gr(" preprocessorOptions: {"));
161
+ console.log(gr(" scss: {"));
162
+ console.log(gr(" api: 'modern-compiler',"));
163
+ console.log(gr(" loadPaths: ['./node_modules'],"));
164
+ console.log(gr(" },"));
165
+ console.log(gr(" },"));
166
+ console.log(gr(" },"));
167
+ console.log(gr(" },"));
168
+ console.log(gr(" });"));
169
+ console.log('');
170
+ console.log(m(" @use '@mastorscdn/core' as mc;"));
171
+ console.log('');
172
+ }
173
+
174
+ function guideAstro() {
175
+ console.log(b(g(' ✔ Astro detected')));
176
+ console.log('');
177
+ console.log(' Add to ' + c('astro.config.mjs') + ':');
178
+ console.log('');
179
+ console.log(gr(" import path from 'path';"));
180
+ console.log(gr(" export default defineConfig({"));
181
+ console.log(gr(" vite: {"));
182
+ console.log(gr(" css: { preprocessorOptions: { scss: {"));
183
+ console.log(gr(" api: 'modern-compiler',"));
184
+ console.log(gr(" loadPaths: [path.resolve('./node_modules')],"));
185
+ console.log(gr(" } } },"));
186
+ console.log(gr(" },"));
187
+ console.log(gr(" });"));
188
+ console.log('');
189
+ console.log(m(" @use '@mastorscdn/core' as mc;"));
190
+ console.log('');
191
+ }
192
+
193
+ function guideSvelteKit() {
194
+ console.log(b(g(' ✔ SvelteKit detected')));
195
+ console.log('');
196
+ console.log(' Add to ' + c('vite.config.js') + ':');
197
+ console.log('');
198
+ console.log(gr(" import path from 'path';"));
199
+ console.log(gr(" export default { plugins: [sveltekit()],"));
200
+ console.log(gr(" css: { preprocessorOptions: { scss: {"));
201
+ console.log(gr(" api: 'modern-compiler',"));
202
+ console.log(gr(" loadPaths: [path.resolve('./node_modules')],"));
203
+ console.log(gr(" } } },"));
204
+ console.log(gr(" };"));
205
+ console.log('');
206
+ console.log(m(" @use '@mastorscdn/core' as mc;"));
207
+ console.log('');
208
+ }
209
+
210
+ function guideRemix() {
211
+ console.log(b(g(' ✔ Remix detected')));
212
+ console.log('');
213
+ console.log(' Add to ' + c('vite.config.ts') + ' css section:');
214
+ console.log('');
215
+ console.log(gr(" css: { preprocessorOptions: { scss: {"));
216
+ console.log(gr(" api: 'modern-compiler',"));
217
+ console.log(gr(" loadPaths: ['./node_modules'],"));
218
+ console.log(gr(" } } },"));
219
+ console.log('');
220
+ console.log(m(" @use '@mastorscdn/core' as mc;"));
221
+ console.log('');
222
+ }
223
+
224
+ function guideAngular() {
225
+ console.log(b(g(' ✔ Angular detected')));
226
+ console.log('');
227
+ console.log(' In ' + c('angular.json') + ' under build > options:');
228
+ console.log('');
229
+ console.log(gr(' "stylePreprocessorOptions": {'));
230
+ console.log(gr(' "includePaths": ["node_modules"]'));
231
+ console.log(gr(' }'));
232
+ console.log('');
233
+ console.log(m(" @use '@mastorscdn/core' as mc;"));
234
+ console.log('');
235
+ }
236
+
237
+ // ── Write mc.config.js ────────────────────────────────────────────────────────
238
+ function writeMcConfig(framework) {
239
+ const configPath = path.join(ROOT, 'mc.config.js');
240
+ if (fs.existsSync(configPath)) return;
241
+
242
+ const content = `// =============================================================================
243
+ // mc.config.js — Mastors Core Configuration Reference
244
+ // Auto-generated by @mastorscdn/core on install
245
+ // Detected framework: ${framework}
246
+ //
247
+ // Copy the relevant snippet from this file into your bundler config.
248
+ // Full docs: https://mastorscdn.kehem.com/
249
+ // =============================================================================
250
+
251
+ /** @type {import('@mastorscdn/core').McConfig} */
252
+ const mcConfig = {
253
+ // Add to your bundler's scss preprocessorOptions:
254
+ loadPaths: ['./node_modules'],
255
+
256
+ // Override Mastors tokens in SCSS:
257
+ // @use '@mastorscdn/core' with (
258
+ // $enable-dark-theme: true,
259
+ // $enable-utilities: true,
260
+ // $mastors-prefix: 'mc',
261
+ // );
262
+ };
263
+
264
+ module.exports = mcConfig;
265
+ `;
266
+
267
+ try { fs.writeFileSync(configPath, content, 'utf8'); } catch (_) {}
268
+ }
269
+
270
+ // ── Footer ────────────────────────────────────────────────────────────────────
271
+ function footer(framework) {
272
+ console.log(b(' ─────────────────────────────────────────────'));
273
+ console.log('');
274
+ console.log(' ' + b('In any .scss file:'));
275
+ console.log('');
276
+ console.log(m(" @use '@mastorscdn/core' as mc;"));
277
+ console.log('');
278
+ console.log(gr(' .card {'));
279
+ console.log(gr(" color: mc.color('primary');"));
280
+ console.log(gr(" border-radius: mc.radius('lg');"));
281
+ console.log(gr(" box-shadow: mc.shadow('md');"));
282
+ console.log(gr(" @include mc.up('md') { padding: 2rem; }"));
283
+ console.log(gr(' }'));
284
+ console.log('');
285
+ console.log(' ' + b('Docs:') + ' ' + c('https://mastorscdn.kehem.com/'));
286
+ console.log(' ' + b('npm:') + ' ' + c('https://www.npmjs.com/package/@mastorscdn/core'));
287
+ console.log('');
288
+ if (framework !== 'node') {
289
+ console.log(' ' + y('📄 mc.config.js written to your project root.'));
290
+ console.log('');
291
+ }
292
+ console.log(b(c(' Happy styling with Mastors Core! 🚀')));
293
+ console.log('');
294
+ }
295
+
296
+ // ── Main ──────────────────────────────────────────────────────────────────────
297
+ function main() {
298
+ if (process.env.CI && process.env.MASTORS_SILENT) return;
299
+
300
+ const pkg = getUserPkg();
301
+ const framework = detectFramework(pkg);
302
+
303
+ banner();
304
+ console.log(` ${b('Detected environment:')} ${g(framework)}`);
305
+ console.log('');
306
+
307
+ switch (framework) {
308
+ case 'next': guideNext(); break;
309
+ case 'nuxt': guideNuxt(); break;
310
+ case 'astro': guideAstro(); break;
311
+ case 'sveltekit':
312
+ case 'svelte': guideSvelteKit(); break;
313
+ case 'remix': guideRemix(); break;
314
+ case 'vite-vue': guideVite('vite-vue'); break;
315
+ case 'vite-react': guideVite('vite-react'); break;
316
+ case 'vite': guideVite('vite'); break;
317
+ case 'angular': guideAngular(); break;
318
+ default: guideNode(); break;
319
+ }
320
+
321
+ if (framework !== 'node') writeMcConfig(framework);
322
+ footer(framework);
323
+ }
324
+
325
+ main();
package/scss/_index.scss CHANGED
@@ -107,3 +107,17 @@
107
107
 
108
108
  // --- Abstracts ---
109
109
  @forward 'abstracts';
110
+
111
+ // --- CSS Output Modules ---
112
+ // These are forwarded so that `@use '@mastorscdn/core' with (...)` emits
113
+ // actual CSS (themes, variables, reset, utilities, etc.).
114
+ // Without these forwards the _index.scss barrel is a Sass-API-only file
115
+ // and no CSS variables or theme tokens are written to the stylesheet.
116
+ @forward 'vendors';
117
+ @forward 'base';
118
+ @forward 'themes';
119
+ @forward 'accessibility';
120
+ @forward 'helpers';
121
+ @forward 'generators';
122
+ @forward 'utilities';
123
+ @forward 'mixins/css-vars';
@@ -41,7 +41,7 @@
41
41
  left: 1rem;
42
42
  z-index: 9999;
43
43
  padding: 0.5rem 1rem;
44
- background: var(--mastors-color-primary, #2563eb);
44
+ background: var(--#{cfg.$mastors-prefix}-color-primary, #2563eb);
45
45
  color: #ffffff;
46
46
  border-radius: 0 0 8px 8px;
47
47
  font-weight: 600;
@@ -58,7 +58,7 @@
58
58
  // --- Focus Visible: global keyboard nav ---
59
59
  @if cfg.$enable-focus-visible {
60
60
  :focus-visible {
61
- outline: 3px solid var(--mastors-border-focus, #2563eb);
61
+ outline: 3px solid var(--#{cfg.$mastors-prefix}-border-focus, #2563eb);
62
62
  outline-offset: 2px;
63
63
  border-radius: 2px;
64
64
  }
@@ -92,6 +92,6 @@
92
92
 
93
93
  // --- Keyboard navigation indicator ---
94
94
  .mastors-keyboard-nav *:focus {
95
- outline: 3px solid var(--mastors-border-focus, #2563eb);
95
+ outline: 3px solid var(--#{cfg.$mastors-prefix}-border-focus, #2563eb);
96
96
  outline-offset: 2px;
97
97
  }
@@ -34,8 +34,8 @@ html {
34
34
  body {
35
35
  margin: 0;
36
36
  min-height: 100vh;
37
- background-color: var(--mastors-bg-body, #ffffff);
38
- color: var(--mastors-text-primary, #111827);
37
+ background-color: var(--#{cfg.$mastors-prefix}-bg-body, #ffffff);
38
+ color: var(--#{cfg.$mastors-prefix}-text-primary, #111827);
39
39
  line-height: inherit;
40
40
  -webkit-font-smoothing: antialiased;
41
41
  -moz-osx-font-smoothing: grayscale;
@@ -107,13 +107,13 @@ button,
107
107
  input::-moz-placeholder,
108
108
  textarea::-moz-placeholder {
109
109
  opacity: 1;
110
- color: var(--mastors-text-muted, #6b7280);
110
+ color: var(--#{cfg.$mastors-prefix}-text-muted, #6b7280);
111
111
  }
112
112
 
113
113
  input::placeholder,
114
114
  textarea::placeholder {
115
115
  opacity: 1;
116
- color: var(--mastors-text-muted, #6b7280);
116
+ color: var(--#{cfg.$mastors-prefix}-text-muted, #6b7280);
117
117
  }
118
118
 
119
119
  textarea { resize: vertical; }
@@ -149,7 +149,7 @@ hr {
149
149
  height: 0;
150
150
  color: inherit;
151
151
  border-top-width: 1px;
152
- border-color: var(--mastors-border-default, #e5e7eb);
152
+ border-color: var(--#{cfg.$mastors-prefix}-border-default, #e5e7eb);
153
153
  margin: 0;
154
154
  }
155
155
 
@@ -173,6 +173,6 @@ svg {
173
173
 
174
174
  // --- Selection ---
175
175
  ::selection {
176
- background-color: var(--mastors-color-primary, #2563eb);
176
+ background-color: var(--#{cfg.$mastors-prefix}-color-primary, #2563eb);
177
177
  color: #ffffff;
178
178
  }
@@ -3,6 +3,8 @@
3
3
  // Reusable state classes for hover, focus, active, disabled
4
4
  // =============================================================================
5
5
 
6
+ @use '../config/settings' as cfg;
7
+
6
8
  // --- Interactive base ---
7
9
  .mastors-interactive {
8
10
  cursor: pointer;
@@ -65,7 +67,7 @@
65
67
  100% { background-position: -200% 0; }
66
68
  }
67
69
 
68
- [data-theme='dark'] & {
70
+ [#{cfg.$mastors-theme-attr}='dark'] & {
69
71
  background: linear-gradient(90deg, #374151 25%, #4b5563 50%, #374151 75%);
70
72
  background-size: 200% 100%;
71
73
  }
@@ -75,3 +75,10 @@
75
75
  @include generate-all-vars;
76
76
  }
77
77
  }
78
+
79
+ // --- Auto-emit when this module is @forwarded from _index.scss ---
80
+ // When a consumer does `@use '@mastorscdn/core' with (...)`, this top-level
81
+ // block ensures CSS variables are written without needing a separate @include.
82
+ @if cfg.$enable-css-variables {
83
+ @include generate-all-vars;
84
+ }
@@ -5,37 +5,37 @@
5
5
  @use '../config/settings' as cfg;
6
6
 
7
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;
8
+ --#{cfg.$mastors-prefix}-text-primary: #f9fafb;
9
+ --#{cfg.$mastors-prefix}-text-secondary: #e5e7eb;
10
+ --#{cfg.$mastors-prefix}-text-muted: #9ca3af;
11
+ --#{cfg.$mastors-prefix}-text-disabled: #6b7280;
12
+ --#{cfg.$mastors-prefix}-text-inverse: #111827;
13
+
14
+ --#{cfg.$mastors-prefix}-bg-body: #0f172a;
15
+ --#{cfg.$mastors-prefix}-bg-subtle: #1e293b;
16
+ --#{cfg.$mastors-prefix}-bg-muted: #334155;
17
+ --#{cfg.$mastors-prefix}-bg-inverse: #f9fafb;
18
+
19
+ --#{cfg.$mastors-prefix}-border-default: #334155;
20
+ --#{cfg.$mastors-prefix}-border-strong: #475569;
21
+ --#{cfg.$mastors-prefix}-border-focus: #60a5fa;
22
+
23
+ --#{cfg.$mastors-prefix}-surface: #1e293b;
24
+ --#{cfg.$mastors-prefix}-surface-raised: #334155;
25
+ --#{cfg.$mastors-prefix}-surface-overlay: rgba(15, 23, 42, 0.95);
26
+
27
+ --#{cfg.$mastors-prefix}-shadow-ambient: 0 1px 3px rgba(0, 0, 0, 0.50);
28
+
29
+ --#{cfg.$mastors-prefix}-color-primary: #60a5fa;
30
+ --#{cfg.$mastors-prefix}-color-secondary: #a78bfa;
31
+ --#{cfg.$mastors-prefix}-color-accent: #38bdf8;
32
+ --#{cfg.$mastors-prefix}-color-success: #4ade80;
33
+ --#{cfg.$mastors-prefix}-color-warning: #fbbf24;
34
+ --#{cfg.$mastors-prefix}-color-danger: #f87171;
35
+ --#{cfg.$mastors-prefix}-color-info: #22d3ee;
36
+
37
+ --#{cfg.$mastors-prefix}-scrollbar-thumb: rgba(255, 255, 255, 0.2);
38
+ --#{cfg.$mastors-prefix}-scrollbar-track: transparent;
39
39
  }
40
40
 
41
41
  // Attribute-based dark mode