@aravindc26/velu 0.7.0 → 0.9.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/src/themes.ts CHANGED
@@ -88,10 +88,6 @@ function deriveAccentPalette(primary: string): { dark: Pick<ColorSet, "accentLow
88
88
  }
89
89
 
90
90
  // ── Gray palettes ────────────────────────────────────────────────────────────
91
- // Starlight convention: gray-1 = strongest foreground, gray-7 = subtlest
92
- // In dark mode: gray-1 is light, gray-7 is dark
93
- // In light mode: gray-1 is dark, gray-7 is light
94
- // --sl-color-white = foreground extreme, --sl-color-black = background extreme
95
91
 
96
92
  const GRAY_SLATE = {
97
93
  dark: {
@@ -280,21 +276,10 @@ const THEMES: Record<string, ThemePreset> = {
280
276
 
281
277
  // ── CSS generator ────────────────────────────────────────────────────────────
282
278
 
283
- function colorSetToCss(colors: ColorSet): string {
284
- return [
285
- ` --sl-color-accent-low: ${colors.accentLow};`,
286
- ` --sl-color-accent: ${colors.accent};`,
287
- ` --sl-color-accent-high: ${colors.accentHigh};`,
288
- ` --sl-color-white: ${colors.white};`,
289
- ` --sl-color-gray-1: ${colors.gray1};`,
290
- ` --sl-color-gray-2: ${colors.gray2};`,
291
- ` --sl-color-gray-3: ${colors.gray3};`,
292
- ` --sl-color-gray-4: ${colors.gray4};`,
293
- ` --sl-color-gray-5: ${colors.gray5};`,
294
- ` --sl-color-gray-6: ${colors.gray6};`,
295
- ` --sl-color-gray-7: ${colors.gray7};`,
296
- ` --sl-color-black: ${colors.black};`,
297
- ].join("\n");
279
+ function textColorFor(hex: string): string {
280
+ const [r, g, b] = hexToRgb(hex);
281
+ const yiq = (r * 299 + g * 587 + b * 114) / 1000;
282
+ return yiq >= 140 ? "#111111" : "#ffffff";
298
283
  }
299
284
 
300
285
  function generateThemeCss(config: ThemeConfig): string {
@@ -330,22 +315,42 @@ function generateThemeCss(config: ThemeConfig): string {
330
315
  lines.push(`/* Velu Theme: ${themeName} */`);
331
316
  lines.push("");
332
317
 
333
- // Dark mode (Starlight default)
318
+ // Light mode (default)
334
319
  lines.push(":root {");
335
- lines.push(colorSetToCss(darkColors));
320
+ lines.push(` --color-fd-primary: ${lightColors.accent};`);
321
+ lines.push(` --color-fd-primary-foreground: ${textColorFor(lightColors.accent)};`);
322
+ lines.push(` --color-fd-accent: ${lightColors.accentLow};`);
323
+ lines.push(` --color-fd-accent-foreground: ${textColorFor(lightColors.accentLow)};`);
324
+ lines.push(` --color-fd-ring: ${lightColors.accent};`);
325
+ lines.push("}");
326
+
327
+ // Dark mode
328
+ lines.push("");
329
+ lines.push(".dark {");
330
+ lines.push(` --color-fd-primary: ${darkColors.accent};`);
331
+ lines.push(` --color-fd-primary-foreground: ${textColorFor(darkColors.accent)};`);
332
+ lines.push(` --color-fd-accent: ${darkColors.accentLow};`);
333
+ lines.push(` --color-fd-accent-foreground: ${textColorFor(darkColors.accentLow)};`);
334
+ lines.push(` --color-fd-ring: ${darkColors.accent};`);
335
+ lines.push("}");
336
+
337
+ if (preset.font || preset.fontMono) {
338
+ lines.push("");
339
+ }
336
340
  if (preset.font) {
337
- lines.push(` --sl-font: ${preset.font};`);
341
+ lines.push(`body { font-family: ${preset.font}; }`);
338
342
  }
339
343
  if (preset.fontMono) {
340
- lines.push(` --sl-font-mono: ${preset.fontMono};`);
344
+ lines.push(`code, pre, kbd, samp { font-family: ${preset.fontMono}; }`);
341
345
  }
342
- lines.push("}");
343
- lines.push("");
344
346
 
345
- // Light mode
346
- lines.push(":root[data-theme='light'] {");
347
- lines.push(colorSetToCss(lightColors));
348
- lines.push("}");
347
+ if (config.appearance === "light") {
348
+ lines.push("");
349
+ lines.push("html { color-scheme: light; }");
350
+ } else if (config.appearance === "dark") {
351
+ lines.push("");
352
+ lines.push("html { color-scheme: dark; }");
353
+ }
349
354
  lines.push("");
350
355
 
351
356
  return lines.join("\n");
package/src/validate.ts CHANGED
@@ -5,6 +5,7 @@ import { resolve, join } from "node:path";
5
5
 
6
6
  interface VeluGroup {
7
7
  group: string;
8
+ slug: string;
8
9
  icon?: string;
9
10
  tag?: string;
10
11
  expanded?: boolean;
@@ -13,6 +14,7 @@ interface VeluGroup {
13
14
 
14
15
  interface VeluTab {
15
16
  tab: string;
17
+ slug: string;
16
18
  icon?: string;
17
19
  href?: string;
18
20
  pages?: string[];
@@ -26,9 +28,7 @@ interface VeluConfig {
26
28
  appearance?: "system" | "light" | "dark";
27
29
  styling?: { codeblocks?: { theme?: string | { light: string; dark: string } } };
28
30
  navigation: {
29
- tabs?: VeluTab[];
30
- groups?: VeluGroup[];
31
- pages?: string[];
31
+ tabs: VeluTab[];
32
32
  };
33
33
  }
34
34
 
@@ -50,27 +50,13 @@ function collectPages(config: VeluConfig): string[] {
50
50
  }
51
51
  }
52
52
 
53
- const nav = config.navigation;
54
-
55
- if (nav.pages) {
56
- pages.push(...nav.pages);
57
- }
58
-
59
- if (nav.groups) {
60
- for (const group of nav.groups) {
61
- collectFromGroup(group);
53
+ for (const tab of config.navigation.tabs) {
54
+ if (tab.pages) {
55
+ pages.push(...tab.pages);
62
56
  }
63
- }
64
-
65
- if (nav.tabs) {
66
- for (const tab of nav.tabs) {
67
- if (tab.pages) {
68
- pages.push(...tab.pages);
69
- }
70
- if (tab.groups) {
71
- for (const group of tab.groups) {
72
- collectFromGroup(group);
73
- }
57
+ if (tab.groups) {
58
+ for (const group of tab.groups) {
59
+ collectFromGroup(group);
74
60
  }
75
61
  }
76
62
  }