@loworbitstudio/visor-theme-engine 0.16.0 → 0.17.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/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js +136 -77
- package/dist/{chunk-DQ256PSE.js → chunk-BUWBBUFG.js} +64 -2
- package/dist/index.d.ts +179 -5
- package/dist/index.js +243 -12
- package/dist/{types-BstIS9rL.d.ts → types-Cvm7vFwe.d.ts} +79 -4
- package/package.json +1 -1
- package/src/visor-theme.schema.json +83 -2
package/dist/adapters/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { k as GeneratedPrimitives,
|
|
1
|
+
import { k as GeneratedPrimitives, s as SemanticTokens, R as ResolvedThemeConfig } from '../types-Cvm7vFwe.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Adapter types for the Visor theme engine.
|
package/dist/adapters/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
resolveThemeBrand,
|
|
21
21
|
resolveThemeFonts,
|
|
22
22
|
sectionComment
|
|
23
|
-
} from "../chunk-
|
|
23
|
+
} from "../chunk-BUWBBUFG.js";
|
|
24
24
|
|
|
25
25
|
// src/adapters/brand-passthrough.ts
|
|
26
26
|
var SENTINEL_COLOR = "#ff00ff";
|
|
@@ -43,7 +43,7 @@ function indentBlock(selector, decls) {
|
|
|
43
43
|
if (decls.length === 0) return "";
|
|
44
44
|
return [selector + " {", ...decls.map((d) => ` ${d}`), "}"].join("\n");
|
|
45
45
|
}
|
|
46
|
-
function generateBrandPassthroughCss(passthrough, selectors) {
|
|
46
|
+
function generateBrandPassthroughCss(passthrough, selectors, colorScheme = "adaptive") {
|
|
47
47
|
const lightKeys = Object.keys(passthrough.light);
|
|
48
48
|
const darkKeys = Object.keys(passthrough.dark);
|
|
49
49
|
if (lightKeys.length === 0 && darkKeys.length === 0) return "";
|
|
@@ -53,6 +53,20 @@ function generateBrandPassthroughCss(passthrough, selectors) {
|
|
|
53
53
|
const count = lightKeys.length + darkKeys.length;
|
|
54
54
|
blocks.push(`/* [visor-brand] ${count} passthrough: ${names} */`);
|
|
55
55
|
}
|
|
56
|
+
if (colorScheme === "dark-only") {
|
|
57
|
+
if (darkKeys.length > 0) {
|
|
58
|
+
const decls = darkKeys.map((k) => declFor(k, passthrough.dark[k]));
|
|
59
|
+
blocks.push(indentBlock(selectors.light, decls));
|
|
60
|
+
}
|
|
61
|
+
return blocks.filter(Boolean).join("\n\n");
|
|
62
|
+
}
|
|
63
|
+
if (colorScheme === "light-only") {
|
|
64
|
+
if (lightKeys.length > 0) {
|
|
65
|
+
const decls = lightKeys.map((k) => declFor(k, passthrough.light[k]));
|
|
66
|
+
blocks.push(indentBlock(selectors.light, decls));
|
|
67
|
+
}
|
|
68
|
+
return blocks.filter(Boolean).join("\n\n");
|
|
69
|
+
}
|
|
56
70
|
if (lightKeys.length > 0) {
|
|
57
71
|
const decls = lightKeys.map((k) => declFor(k, passthrough.light[k]));
|
|
58
72
|
blocks.push(indentBlock(selectors.light, decls));
|
|
@@ -86,6 +100,7 @@ function nextjsAdapter(input, options) {
|
|
|
86
100
|
const includeFontImports = options?.includeFontImports ?? true;
|
|
87
101
|
const includeFowt = options?.includeFowt ?? true;
|
|
88
102
|
const scopePrefix = options?.scopePrefix;
|
|
103
|
+
const colorScheme = input.config["color-scheme"] ?? "adaptive";
|
|
89
104
|
const lines = [];
|
|
90
105
|
const slug = toKebabCase(input.config.name);
|
|
91
106
|
const aliasedFamilies = /* @__PURE__ */ new Map();
|
|
@@ -156,7 +171,7 @@ function nextjsAdapter(input, options) {
|
|
|
156
171
|
light: scopePrefix ?? ":root",
|
|
157
172
|
dark: darkSelectors.join(",\n"),
|
|
158
173
|
prefers: scopePrefix ? `${scopePrefix}:not(.light):not(.theme-light):not([data-theme="light"])` : ':root:not(.light):not(.theme-light):not([data-theme="light"])'
|
|
159
|
-
});
|
|
174
|
+
}, colorScheme);
|
|
160
175
|
if (passthroughCss) {
|
|
161
176
|
lines.push(wrapInLayer("visor-brand", passthroughCss));
|
|
162
177
|
lines.push("");
|
|
@@ -173,43 +188,60 @@ function nextjsAdapter(input, options) {
|
|
|
173
188
|
semanticLines.push(sectionComment("Discrete: Space aliases (--space-N)"));
|
|
174
189
|
semanticLines.push(block(hostSelector, generateSpaceAliasDecls(input.config)));
|
|
175
190
|
semanticLines.push("");
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
semanticLines.push(
|
|
191
|
+
if (colorScheme === "dark-only") {
|
|
192
|
+
semanticLines.push(sectionComment("Intent aliases (dark) \u2014 host"));
|
|
193
|
+
semanticLines.push(block(hostSelector, generateIntentDecls(input.tokens, "dark")));
|
|
194
|
+
semanticLines.push("");
|
|
195
|
+
semanticLines.push(sectionComment("Hairline aliases (dark) \u2014 host"));
|
|
196
|
+
semanticLines.push(block(hostSelector, generateHairlineDecls(input.tokens, "dark")));
|
|
197
|
+
semanticLines.push("");
|
|
198
|
+
} else if (colorScheme === "light-only") {
|
|
199
|
+
semanticLines.push(sectionComment("Intent aliases (light) \u2014 host"));
|
|
200
|
+
semanticLines.push(block(hostSelector, generateIntentDecls(input.tokens, "light")));
|
|
201
|
+
semanticLines.push("");
|
|
202
|
+
semanticLines.push(sectionComment("Hairline aliases (light) \u2014 host"));
|
|
203
|
+
semanticLines.push(block(hostSelector, generateHairlineDecls(input.tokens, "light")));
|
|
204
|
+
semanticLines.push("");
|
|
205
|
+
} else {
|
|
206
|
+
semanticLines.push(sectionComment("Intent aliases (light)"));
|
|
207
|
+
semanticLines.push(block(lightModeSelector, generateIntentDecls(input.tokens, "light")));
|
|
208
|
+
semanticLines.push("");
|
|
209
|
+
semanticLines.push(sectionComment("Hairline aliases (light)"));
|
|
210
|
+
semanticLines.push(block(lightModeSelector, generateHairlineDecls(input.tokens, "light")));
|
|
211
|
+
semanticLines.push("");
|
|
212
|
+
semanticLines.push(sectionComment("Intent aliases (dark) \u2014 manual toggle"));
|
|
213
|
+
semanticLines.push(block(darkModeSelector, generateIntentDecls(input.tokens, "dark")));
|
|
214
|
+
semanticLines.push("");
|
|
215
|
+
semanticLines.push(sectionComment("Hairline aliases (dark) \u2014 manual toggle"));
|
|
216
|
+
semanticLines.push(block(darkModeSelector, generateHairlineDecls(input.tokens, "dark")));
|
|
217
|
+
semanticLines.push("");
|
|
218
|
+
semanticLines.push(sectionComment("Intent aliases (dark) \u2014 prefers-color-scheme"));
|
|
219
|
+
{
|
|
220
|
+
const inner = block(prefersSelector, generateIntentDecls(input.tokens, "dark"));
|
|
221
|
+
semanticLines.push(`@media (prefers-color-scheme: dark) {
|
|
192
222
|
${inner.split("\n").map((l) => ` ${l}`).join("\n")}
|
|
193
223
|
}`);
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
224
|
+
}
|
|
225
|
+
semanticLines.push("");
|
|
226
|
+
semanticLines.push(sectionComment("Hairline aliases (dark) \u2014 prefers-color-scheme"));
|
|
227
|
+
{
|
|
228
|
+
const inner = block(prefersSelector, generateHairlineDecls(input.tokens, "dark"));
|
|
229
|
+
semanticLines.push(`@media (prefers-color-scheme: dark) {
|
|
200
230
|
${inner.split("\n").map((l) => ` ${l}`).join("\n")}
|
|
201
231
|
}`);
|
|
232
|
+
}
|
|
233
|
+
semanticLines.push("");
|
|
202
234
|
}
|
|
203
|
-
semanticLines.push("");
|
|
204
235
|
const semanticLayer = wrapInLayer("visor-semantic", semanticLines.join("\n").trim());
|
|
205
236
|
if (semanticLayer) {
|
|
206
237
|
lines.push(semanticLayer);
|
|
207
238
|
lines.push("");
|
|
208
239
|
}
|
|
209
|
-
const lightBody = stripHeader(generateLightCss(input.tokens, { scopePrefix }));
|
|
210
|
-
const darkBody = stripHeader(generateDarkCss(input.tokens, { scopePrefix }));
|
|
240
|
+
const lightBody = stripHeader(generateLightCss(input.tokens, { scopePrefix, colorScheme }));
|
|
241
|
+
const darkBody = stripHeader(generateDarkCss(input.tokens, { scopePrefix, colorScheme }));
|
|
242
|
+
const adaptiveBody = [lightBody, darkBody].filter(Boolean).join("\n\n");
|
|
211
243
|
lines.push(
|
|
212
|
-
wrapInLayer("visor-adaptive",
|
|
244
|
+
wrapInLayer("visor-adaptive", adaptiveBody)
|
|
213
245
|
);
|
|
214
246
|
if (includeFowt) {
|
|
215
247
|
lines.push("");
|
|
@@ -554,6 +586,14 @@ function sectionComment2(label) {
|
|
|
554
586
|
function docsAdapter(input, options) {
|
|
555
587
|
const slug = toKebabCase3(input.config.name);
|
|
556
588
|
const scopeClass = `.${slug}-theme`;
|
|
589
|
+
const colorScheme = input.config["color-scheme"] ?? "adaptive";
|
|
590
|
+
const singleMode = colorScheme === "dark-only" ? "dark" : colorScheme === "light-only" ? "light" : null;
|
|
591
|
+
const emitDark = colorScheme !== "light-only";
|
|
592
|
+
const emitLight = colorScheme !== "dark-only";
|
|
593
|
+
const emitPrefers = colorScheme === "adaptive";
|
|
594
|
+
const darkSel = singleMode ? scopeClass : `.dark ${scopeClass}`;
|
|
595
|
+
const lightSel = singleMode ? scopeClass : `html:not(.dark) ${scopeClass}`;
|
|
596
|
+
const darkSuffix = singleMode ? " \u2014 host" : " \u2014 manual toggle";
|
|
557
597
|
const includeFontImports = options?.includeFontImports ?? true;
|
|
558
598
|
const fontLines = [];
|
|
559
599
|
const lines = [];
|
|
@@ -601,6 +641,8 @@ function docsAdapter(input, options) {
|
|
|
601
641
|
const sharedDecls = [
|
|
602
642
|
"min-height: 100vh;",
|
|
603
643
|
"font-size: 1rem;",
|
|
644
|
+
// BO-56: pin UA chrome to the brand's single mode (adaptive emits nothing).
|
|
645
|
+
...singleMode ? [`color-scheme: ${singleMode};`] : [],
|
|
604
646
|
`background: var(--surface-page, var(--surface-background));`,
|
|
605
647
|
"color: var(--text-primary);",
|
|
606
648
|
"font-family: var(--font-sans);"
|
|
@@ -650,9 +692,9 @@ function docsAdapter(input, options) {
|
|
|
650
692
|
}
|
|
651
693
|
}
|
|
652
694
|
}
|
|
653
|
-
if (darkPrimitiveOverrides.length > 0) {
|
|
695
|
+
if (darkPrimitiveOverrides.length > 0 && emitDark) {
|
|
654
696
|
lines.push(sectionComment2("Primitive overrides (dark) \u2014 dark brand color anchors at shade 500"));
|
|
655
|
-
lines.push(block2(
|
|
697
|
+
lines.push(block2(darkSel, darkPrimitiveOverrides));
|
|
656
698
|
lines.push("");
|
|
657
699
|
}
|
|
658
700
|
const categories = ["Text", "Surface", "Border", "Interactive"];
|
|
@@ -662,10 +704,12 @@ function docsAdapter(input, options) {
|
|
|
662
704
|
Object.entries(input.tokens.border).map(([n, v]) => `--border-${n}: ${v.dark};`),
|
|
663
705
|
Object.entries(input.tokens.interactive).map(([n, v]) => `--interactive-${n}: ${v.dark};`)
|
|
664
706
|
];
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
707
|
+
if (emitDark) {
|
|
708
|
+
for (let i = 0; i < categories.length; i++) {
|
|
709
|
+
lines.push(sectionComment2(`Adaptive: ${categories[i]} (dark)${darkSuffix}`));
|
|
710
|
+
lines.push(block2(darkSel, categoryDecls[i]));
|
|
711
|
+
lines.push("");
|
|
712
|
+
}
|
|
669
713
|
}
|
|
670
714
|
const pcsCategories = [
|
|
671
715
|
{ label: "Text", entries: Object.entries(input.tokens.text).map(([n, v]) => `--text-${n}: ${v.dark};`) },
|
|
@@ -673,15 +717,17 @@ function docsAdapter(input, options) {
|
|
|
673
717
|
{ label: "Border", entries: Object.entries(input.tokens.border).map(([n, v]) => `--border-${n}: ${v.dark};`) },
|
|
674
718
|
{ label: "Interactive", entries: Object.entries(input.tokens.interactive).map(([n, v]) => `--interactive-${n}: ${v.dark};`) }
|
|
675
719
|
];
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
720
|
+
if (emitPrefers) {
|
|
721
|
+
for (const cat of pcsCategories) {
|
|
722
|
+
lines.push(sectionComment2(`Adaptive: ${cat.label} (dark) \u2014 prefers-color-scheme`));
|
|
723
|
+
const inner = block2(`${scopeClass}:not(.light):not(.theme-light):not([data-theme="light"])`, cat.entries);
|
|
724
|
+
lines.push(`@media (prefers-color-scheme: dark) {
|
|
680
725
|
${inner.split("\n").map((l) => ` ${l}`).join("\n")}
|
|
681
726
|
}`);
|
|
682
|
-
|
|
727
|
+
lines.push("");
|
|
728
|
+
}
|
|
683
729
|
}
|
|
684
|
-
if (darkPrimitiveOverrides.length > 0) {
|
|
730
|
+
if (darkPrimitiveOverrides.length > 0 && emitPrefers) {
|
|
685
731
|
lines.push(sectionComment2("Primitive overrides (dark) \u2014 prefers-color-scheme"));
|
|
686
732
|
const inner = block2(`${scopeClass}:not(.light):not(.theme-light):not([data-theme="light"])`, darkPrimitiveOverrides);
|
|
687
733
|
lines.push(`@media (prefers-color-scheme: dark) {
|
|
@@ -696,17 +742,23 @@ ${inner.split("\n").map((l) => ` ${l}`).join("\n")}
|
|
|
696
742
|
{ label: "Border", entries: Object.entries(input.tokens.border).map(([n, v]) => `--border-${n}: ${v.light};`) },
|
|
697
743
|
{ label: "Interactive", entries: Object.entries(input.tokens.interactive).map(([n, v]) => `--interactive-${n}: ${v.light};`) }
|
|
698
744
|
];
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
745
|
+
if (emitLight) {
|
|
746
|
+
for (const cat of lightCategoryDecls) {
|
|
747
|
+
lines.push(sectionComment2(`Adaptive: ${cat.label} (light)`));
|
|
748
|
+
lines.push(block2(lightSel, cat.entries));
|
|
749
|
+
lines.push("");
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
if (emitDark) {
|
|
753
|
+
lines.push(sectionComment2("Fumadocs bridge: dark"));
|
|
754
|
+
lines.push(block2(darkSel, generateFumadocsBridgeDecls(input.tokens, "dark")));
|
|
755
|
+
lines.push("");
|
|
756
|
+
}
|
|
757
|
+
if (emitLight) {
|
|
758
|
+
lines.push(sectionComment2("Fumadocs bridge: light"));
|
|
759
|
+
lines.push(block2(lightSel, generateFumadocsBridgeDecls(input.tokens, "light")));
|
|
702
760
|
lines.push("");
|
|
703
761
|
}
|
|
704
|
-
lines.push(sectionComment2("Fumadocs bridge: dark"));
|
|
705
|
-
lines.push(block2(`.dark ${scopeClass}`, generateFumadocsBridgeDecls(input.tokens, "dark")));
|
|
706
|
-
lines.push("");
|
|
707
|
-
lines.push(sectionComment2("Fumadocs bridge: light"));
|
|
708
|
-
lines.push(block2(`html:not(.dark) ${scopeClass}`, generateFumadocsBridgeDecls(input.tokens, "light")));
|
|
709
|
-
lines.push("");
|
|
710
762
|
const semanticLines = [];
|
|
711
763
|
semanticLines.push("\n/* \u2500\u2500 Layer: Semantic aliases (VI-451) \u2500\u2500 */");
|
|
712
764
|
semanticLines.push(sectionComment2("Discrete: Text size aliases (--text-N)"));
|
|
@@ -715,42 +767,49 @@ ${inner.split("\n").map((l) => ` ${l}`).join("\n")}
|
|
|
715
767
|
semanticLines.push(sectionComment2("Discrete: Space aliases (--space-N)"));
|
|
716
768
|
semanticLines.push(block2(scopeClass, generateSpaceAliasDecls(input.config)));
|
|
717
769
|
semanticLines.push("");
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
770
|
+
if (emitLight) {
|
|
771
|
+
semanticLines.push(sectionComment2("Intent aliases (light)"));
|
|
772
|
+
semanticLines.push(block2(lightSel, generateIntentDecls(input.tokens, "light")));
|
|
773
|
+
semanticLines.push("");
|
|
774
|
+
semanticLines.push(sectionComment2("Hairline aliases (light)"));
|
|
775
|
+
semanticLines.push(block2(lightSel, generateHairlineDecls(input.tokens, "light")));
|
|
776
|
+
semanticLines.push("");
|
|
777
|
+
}
|
|
778
|
+
if (emitDark) {
|
|
779
|
+
semanticLines.push(sectionComment2(`Intent aliases (dark)${darkSuffix}`));
|
|
780
|
+
semanticLines.push(block2(darkSel, generateIntentDecls(input.tokens, "dark")));
|
|
781
|
+
semanticLines.push("");
|
|
782
|
+
semanticLines.push(sectionComment2(`Hairline aliases (dark)${darkSuffix}`));
|
|
783
|
+
semanticLines.push(block2(darkSel, generateHairlineDecls(input.tokens, "dark")));
|
|
784
|
+
semanticLines.push("");
|
|
785
|
+
}
|
|
786
|
+
if (emitPrefers) {
|
|
787
|
+
semanticLines.push(sectionComment2("Intent aliases (dark) \u2014 prefers-color-scheme"));
|
|
788
|
+
{
|
|
789
|
+
const inner = block2(`${scopeClass}:not(.light):not(.theme-light):not([data-theme="light"])`, generateIntentDecls(input.tokens, "dark"));
|
|
790
|
+
semanticLines.push(`@media (prefers-color-scheme: dark) {
|
|
734
791
|
${inner.split("\n").map((l) => ` ${l}`).join("\n")}
|
|
735
792
|
}`);
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
793
|
+
}
|
|
794
|
+
semanticLines.push("");
|
|
795
|
+
semanticLines.push(sectionComment2("Hairline aliases (dark) \u2014 prefers-color-scheme"));
|
|
796
|
+
{
|
|
797
|
+
const inner = block2(`${scopeClass}:not(.light):not(.theme-light):not([data-theme="light"])`, generateHairlineDecls(input.tokens, "dark"));
|
|
798
|
+
semanticLines.push(`@media (prefers-color-scheme: dark) {
|
|
742
799
|
${inner.split("\n").map((l) => ` ${l}`).join("\n")}
|
|
743
800
|
}`);
|
|
801
|
+
}
|
|
802
|
+
semanticLines.push("");
|
|
744
803
|
}
|
|
745
|
-
|
|
746
|
-
const brandResult = resolveThemeBrand(input.config.brand, { scope: scopeClass });
|
|
804
|
+
const brandResult = resolveThemeBrand(input.config.brand, { scope: scopeClass, colorScheme });
|
|
747
805
|
const passthroughCss = generateBrandPassthroughCss(
|
|
748
806
|
collectBrandPassthrough(input.tokens, input.config.overrides),
|
|
749
807
|
{
|
|
750
|
-
light:
|
|
751
|
-
dark:
|
|
808
|
+
light: lightSel,
|
|
809
|
+
dark: darkSel,
|
|
752
810
|
prefers: `${scopeClass}:not(.light):not(.theme-light):not([data-theme="light"])`
|
|
753
|
-
}
|
|
811
|
+
},
|
|
812
|
+
colorScheme
|
|
754
813
|
);
|
|
755
814
|
const adaptiveLayer = wrapInLayer("visor-adaptive", lines.join("\n").trim());
|
|
756
815
|
const semanticLayer = wrapInLayer("visor-semantic", semanticLines.join("\n").trim());
|
|
@@ -829,7 +829,7 @@ function block(selector, decls) {
|
|
|
829
829
|
if (decls.length === 0) return "";
|
|
830
830
|
return [`${selector} {`, ...decls.map((d) => ` ${d}`), "}"].join("\n");
|
|
831
831
|
}
|
|
832
|
-
function generateBrandCSS(resolutions, scope) {
|
|
832
|
+
function generateBrandCSS(resolutions, scope, colorScheme = "adaptive") {
|
|
833
833
|
if (resolutions.length === 0) return "";
|
|
834
834
|
const baseSelector = scope ? scope : ":root";
|
|
835
835
|
const lightSelector = scope ? `html:not(.dark) ${scope}` : ":root";
|
|
@@ -840,6 +840,18 @@ function generateBrandCSS(resolutions, scope) {
|
|
|
840
840
|
lines.push("/* --- Brand: forced-mode aliases + tokens --- */");
|
|
841
841
|
lines.push(block(baseSelector, staticDecls));
|
|
842
842
|
lines.push("");
|
|
843
|
+
if (colorScheme === "dark-only") {
|
|
844
|
+
const darkDecls2 = resolutions.map((r) => modeDecl(r, "dark"));
|
|
845
|
+
lines.push("/* --- Brand: variants (dark) \u2014 host --- */");
|
|
846
|
+
lines.push(block(baseSelector, darkDecls2));
|
|
847
|
+
return lines.join("\n").trim();
|
|
848
|
+
}
|
|
849
|
+
if (colorScheme === "light-only") {
|
|
850
|
+
const lightDecls2 = resolutions.map((r) => modeDecl(r, "light"));
|
|
851
|
+
lines.push("/* --- Brand: variants (light) \u2014 host --- */");
|
|
852
|
+
lines.push(block(baseSelector, lightDecls2));
|
|
853
|
+
return lines.join("\n").trim();
|
|
854
|
+
}
|
|
843
855
|
const lightDecls = resolutions.map((r) => modeDecl(r, "light"));
|
|
844
856
|
lines.push("/* --- Brand: variants (light) --- */");
|
|
845
857
|
lines.push(block(lightSelector, lightDecls));
|
|
@@ -860,6 +872,7 @@ ${inner.split("\n").map((l) => ` ${l}`).join("\n")}
|
|
|
860
872
|
function resolveThemeBrand(brand, options) {
|
|
861
873
|
const effective = brand ?? DEFAULT_VISOR_BRAND;
|
|
862
874
|
const scope = options?.scope ?? "";
|
|
875
|
+
const colorScheme = options?.colorScheme ?? "adaptive";
|
|
863
876
|
const source = resolveBrandSource(effective);
|
|
864
877
|
const org = effective.org ?? null;
|
|
865
878
|
const cdnBase = effective["cdn-overrides"]?.["visor-brands"] ?? null;
|
|
@@ -881,7 +894,7 @@ function resolveThemeBrand(brand, options) {
|
|
|
881
894
|
if (resolution.guidance) warnings.push(resolution.guidance);
|
|
882
895
|
}
|
|
883
896
|
}
|
|
884
|
-
const css = generateBrandCSS([...variants, ...custom], scope);
|
|
897
|
+
const css = generateBrandCSS([...variants, ...custom], scope, colorScheme);
|
|
885
898
|
return { variants, custom, css, warnings };
|
|
886
899
|
}
|
|
887
900
|
|
|
@@ -1730,9 +1743,15 @@ function buildAdaptiveDecls(tokens, theme) {
|
|
|
1730
1743
|
return { textDecls, surfaceDecls, borderDecls, interactiveDecls, intentDecls, hairlineDecls };
|
|
1731
1744
|
}
|
|
1732
1745
|
function generateLightCss(tokens, options) {
|
|
1746
|
+
const colorScheme = options?.colorScheme ?? "adaptive";
|
|
1747
|
+
if (colorScheme === "dark-only") return "";
|
|
1733
1748
|
const lines = [];
|
|
1734
1749
|
const { textDecls, surfaceDecls, borderDecls, interactiveDecls, intentDecls, hairlineDecls } = buildAdaptiveDecls(tokens, "light");
|
|
1735
1750
|
const host = options?.scopePrefix ?? ":root";
|
|
1751
|
+
if (colorScheme === "light-only") {
|
|
1752
|
+
lines.push(sectionComment("Adaptive: color-scheme (light)"));
|
|
1753
|
+
lines.push(block2(host, ["color-scheme: light;"]));
|
|
1754
|
+
}
|
|
1736
1755
|
lines.push(sectionComment("Adaptive: Text (light)"));
|
|
1737
1756
|
lines.push(block2(host, textDecls));
|
|
1738
1757
|
lines.push(sectionComment("Adaptive: Surface (light)"));
|
|
@@ -1748,8 +1767,28 @@ function generateLightCss(tokens, options) {
|
|
|
1748
1767
|
return header("Visor Theme \u2014 Light") + lines.join("\n");
|
|
1749
1768
|
}
|
|
1750
1769
|
function generateDarkCss(tokens, options) {
|
|
1770
|
+
const colorScheme = options?.colorScheme ?? "adaptive";
|
|
1771
|
+
if (colorScheme === "light-only") return "";
|
|
1751
1772
|
const lines = [];
|
|
1752
1773
|
const { textDecls, surfaceDecls, borderDecls, interactiveDecls, intentDecls, hairlineDecls } = buildAdaptiveDecls(tokens, "dark");
|
|
1774
|
+
if (colorScheme === "dark-only") {
|
|
1775
|
+
const host = options?.scopePrefix ?? ":root";
|
|
1776
|
+
lines.push(sectionComment("Adaptive: color-scheme (dark)"));
|
|
1777
|
+
lines.push(block2(host, ["color-scheme: dark;"]));
|
|
1778
|
+
lines.push(sectionComment("Adaptive: Text (dark) \u2014 host"));
|
|
1779
|
+
lines.push(block2(host, textDecls));
|
|
1780
|
+
lines.push(sectionComment("Adaptive: Surface (dark) \u2014 host"));
|
|
1781
|
+
lines.push(block2(host, surfaceDecls));
|
|
1782
|
+
lines.push(sectionComment("Adaptive: Border (dark) \u2014 host"));
|
|
1783
|
+
lines.push(block2(host, borderDecls));
|
|
1784
|
+
lines.push(sectionComment("Adaptive: Interactive (dark) \u2014 host"));
|
|
1785
|
+
lines.push(block2(host, interactiveDecls));
|
|
1786
|
+
lines.push(sectionComment("Adaptive: Intent aliases (dark) \u2014 host"));
|
|
1787
|
+
lines.push(block2(host, intentDecls));
|
|
1788
|
+
lines.push(sectionComment("Adaptive: Hairline aliases (dark) \u2014 host"));
|
|
1789
|
+
lines.push(block2(host, hairlineDecls));
|
|
1790
|
+
return header("Visor Theme \u2014 Dark") + lines.join("\n");
|
|
1791
|
+
}
|
|
1753
1792
|
const prefix = options?.scopePrefix;
|
|
1754
1793
|
const darkSelectors = prefix ? [`${prefix}.dark`, `${prefix}.theme-dark`, `${prefix}[data-theme="dark"]`] : [".dark", ".theme-dark", '[data-theme="dark"]'];
|
|
1755
1794
|
const darkSelector = darkSelectors.join(",\n");
|
|
@@ -1829,6 +1868,29 @@ function generateFullBundleCss(primitives, tokens, config) {
|
|
|
1829
1868
|
);
|
|
1830
1869
|
const primitivesBody = generatePrimitivesCss(primitives, config).split("\n").slice(6).join("\n");
|
|
1831
1870
|
lines.push(primitivesBody);
|
|
1871
|
+
const colorScheme = config["color-scheme"] ?? "adaptive";
|
|
1872
|
+
if (colorScheme === "dark-only") {
|
|
1873
|
+
lines.push(
|
|
1874
|
+
"/* ============================================",
|
|
1875
|
+
" Tier 3: Adaptive \u2014 Dark Theme (:root host) + color-scheme: dark",
|
|
1876
|
+
" ============================================ */"
|
|
1877
|
+
);
|
|
1878
|
+
lines.push(
|
|
1879
|
+
generateDarkCss(tokens, { colorScheme }).split("\n").slice(6).join("\n")
|
|
1880
|
+
);
|
|
1881
|
+
return lines.join("\n");
|
|
1882
|
+
}
|
|
1883
|
+
if (colorScheme === "light-only") {
|
|
1884
|
+
lines.push(
|
|
1885
|
+
"/* ============================================",
|
|
1886
|
+
" Tier 3: Adaptive \u2014 Light Theme (:root host) + color-scheme: light",
|
|
1887
|
+
" ============================================ */"
|
|
1888
|
+
);
|
|
1889
|
+
lines.push(
|
|
1890
|
+
generateLightCss(tokens, { colorScheme }).split("\n").slice(6).join("\n")
|
|
1891
|
+
);
|
|
1892
|
+
return lines.join("\n");
|
|
1893
|
+
}
|
|
1832
1894
|
lines.push(
|
|
1833
1895
|
"/* ============================================",
|
|
1834
1896
|
" Tier 3: Adaptive \u2014 Light Theme (:root)",
|