@timmo001/groundwork-tokens 0.9.40 → 0.10.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.
@@ -2706,6 +2706,53 @@
2706
2706
  "row-padding": "var(--gw-space-3)"
2707
2707
  },
2708
2708
  "modes": {
2709
+ "light": {
2710
+ "surface-lower": "#d0d5e3",
2711
+ "surface-low": "#dadbe0",
2712
+ "surface-default": "#e1e2e7",
2713
+ "surface-raised": "#e9e9ed",
2714
+ "surface-overlay": "#e1e1e5",
2715
+ "border-quiet": "#ced2e4",
2716
+ "border-normal": "#c4c8da",
2717
+ "border-loud": "#abafc0",
2718
+ "text-strong": "#3760bf",
2719
+ "text-primary": "#3760bf",
2720
+ "text-secondary": "#6172b0",
2721
+ "text-disabled": "#6172b099",
2722
+ "fill-neutral-resting": "#dfdfe3",
2723
+ "fill-neutral-hovered": "#d5d5d9",
2724
+ "fill-neutral-pressed": "#ccccd0",
2725
+ "fill-neutral-selected": "#cfcfd3",
2726
+ "fill-neutral-disabled": "#e4e4e8",
2727
+ "fill-primary-resting": "#3760bf",
2728
+ "fill-primary-hovered": "#4772d3",
2729
+ "fill-primary-pressed": "#537fe1",
2730
+ "on-primary": "#e1e2e7",
2731
+ "accent": "#2e7de9",
2732
+ "fill-accent-resting": "#2e7de9",
2733
+ "fill-accent-hovered": "#0042a5",
2734
+ "fill-accent-pressed": "#0059c0",
2735
+ "fill-accent-quiet": "#0051b729",
2736
+ "border-accent": "#0051b780",
2737
+ "on-accent": "#ffffff",
2738
+ "focus": "#2e7de9",
2739
+ "link": "#0051b7",
2740
+ "info": "#2e7de9",
2741
+ "fill-info-quiet": "#2e7de924",
2742
+ "border-info": "#2e7de973",
2743
+ "success": "#587539",
2744
+ "fill-success-quiet": "#58753924",
2745
+ "border-success": "#58753973",
2746
+ "important": "#9854f1",
2747
+ "fill-important-quiet": "#9854f124",
2748
+ "border-important": "#9854f173",
2749
+ "warning": "#8c6c3e",
2750
+ "fill-warning-quiet": "#8c6c3e24",
2751
+ "border-warning": "#8c6c3e73",
2752
+ "danger": "#f52a65",
2753
+ "fill-danger-quiet": "#f52a6524",
2754
+ "border-danger": "#f52a6573"
2755
+ },
2709
2756
  "dark": {
2710
2757
  "surface-lower": "#16161e",
2711
2758
  "surface-low": "#171823",
@@ -2803,9 +2850,9 @@
2803
2850
  }
2804
2851
  },
2805
2852
  {
2806
- "id": "tokyo-night-day",
2807
- "name": "Tokyo Night Day",
2808
- "description": "Tokyo Night Day, mapped onto the roles so it stays faithful to the Tokyo Night palette.",
2853
+ "id": "tokyo-night-moon",
2854
+ "name": "Tokyo Night Moon",
2855
+ "description": "Tokyo Night Moon, mapped onto the roles so it stays faithful to the Tokyo Night palette.",
2809
2856
  "optional": true,
2810
2857
  "family": "Tokyo Night",
2811
2858
  "examples": [],
@@ -2925,86 +2972,7 @@
2925
2972
  "danger": "#f52a65",
2926
2973
  "fill-danger-quiet": "#f52a6524",
2927
2974
  "border-danger": "#f52a6573"
2928
- }
2929
- }
2930
- },
2931
- {
2932
- "id": "tokyo-night-moon",
2933
- "name": "Tokyo Night Moon",
2934
- "description": "Tokyo Night Moon, mapped onto the roles so it stays faithful to the Tokyo Night palette.",
2935
- "optional": true,
2936
- "family": "Tokyo Night",
2937
- "examples": [],
2938
- "style": {
2939
- "font": "Mona Sans",
2940
- "mono": "Geist Mono",
2941
- "radius": {
2942
- "panel": 10,
2943
- "control": 8,
2944
- "chip": 6
2945
- },
2946
- "border": {
2947
- "width": 1,
2948
- "strength": "hairline"
2949
- },
2950
- "weights": {
2951
- "regular": 400,
2952
- "strong": 600
2953
- },
2954
- "density": "normal",
2955
- "capitals": false,
2956
- "link": {
2957
- "color": "accent",
2958
- "underline": "thin"
2959
2975
  },
2960
- "surfaceAccent": "none",
2961
- "rows": "cards"
2962
- },
2963
- "properties": {
2964
- "font-sans": "\"Mona Sans Variable\", \"Mona Sans\", system-ui, sans-serif",
2965
- "font-figures": "\"Mona Sans Variable\", \"Mona Sans\", system-ui, sans-serif",
2966
- "font-mono": "\"Geist Mono Variable\", \"Geist Mono\", ui-monospace, monospace",
2967
- "font-weight-regular": "400",
2968
- "font-weight-strong": "600",
2969
- "density": "1",
2970
- "control-scale": "1",
2971
- "space-0-5": "calc(0.125rem * var(--gw-density))",
2972
- "space-1": "calc(0.25rem * var(--gw-density))",
2973
- "space-2": "calc(0.5rem * var(--gw-density))",
2974
- "space-3": "calc(0.75rem * var(--gw-density))",
2975
- "space-4": "calc(1rem * var(--gw-density))",
2976
- "space-5": "calc(1.25rem * var(--gw-density))",
2977
- "space-6": "calc(1.5rem * var(--gw-density))",
2978
- "space-7": "calc(1.75rem * var(--gw-density))",
2979
- "space-8": "calc(2rem * var(--gw-density))",
2980
- "space-9": "calc(2.25rem * var(--gw-density))",
2981
- "space-10": "calc(2.5rem * var(--gw-density))",
2982
- "space-11": "calc(2.75rem * var(--gw-density))",
2983
- "space-12": "calc(3rem * var(--gw-density))",
2984
- "space-13": "calc(3.25rem * var(--gw-density))",
2985
- "space-14": "calc(3.5rem * var(--gw-density))",
2986
- "space-15": "calc(3.75rem * var(--gw-density))",
2987
- "space-16": "calc(4rem * var(--gw-density))",
2988
- "space-17": "calc(4.25rem * var(--gw-density))",
2989
- "space-18": "calc(4.5rem * var(--gw-density))",
2990
- "space-19": "calc(4.75rem * var(--gw-density))",
2991
- "space-20": "calc(5rem * var(--gw-density))",
2992
- "radius-panel": "10px",
2993
- "radius-control": "8px",
2994
- "radius-chip": "6px",
2995
- "border-width": "1px",
2996
- "border-color": "var(--gw-color-border-quiet)",
2997
- "label-transform": "none",
2998
- "label-tracking": "normal",
2999
- "link-color": "var(--gw-color-link)",
3000
- "link-underline": "1px",
3001
- "panel-sheen": "none",
3002
- "panel-marker": "0px",
3003
- "panel-flange": "0px",
3004
- "panel-flange-color": "var(--gw-border-color)",
3005
- "row-padding": "var(--gw-space-3)"
3006
- },
3007
- "modes": {
3008
2976
  "dark": {
3009
2977
  "surface-lower": "#1e2030",
3010
2978
  "surface-low": "#202234",
@@ -3178,6 +3146,53 @@
3178
3146
  "row-padding": "var(--gw-space-3)"
3179
3147
  },
3180
3148
  "modes": {
3149
+ "light": {
3150
+ "surface-lower": "#d0d5e3",
3151
+ "surface-low": "#dadbe0",
3152
+ "surface-default": "#e1e2e7",
3153
+ "surface-raised": "#e9e9ed",
3154
+ "surface-overlay": "#e1e1e5",
3155
+ "border-quiet": "#ced2e4",
3156
+ "border-normal": "#c4c8da",
3157
+ "border-loud": "#abafc0",
3158
+ "text-strong": "#3760bf",
3159
+ "text-primary": "#3760bf",
3160
+ "text-secondary": "#6172b0",
3161
+ "text-disabled": "#6172b099",
3162
+ "fill-neutral-resting": "#dfdfe3",
3163
+ "fill-neutral-hovered": "#d5d5d9",
3164
+ "fill-neutral-pressed": "#ccccd0",
3165
+ "fill-neutral-selected": "#cfcfd3",
3166
+ "fill-neutral-disabled": "#e4e4e8",
3167
+ "fill-primary-resting": "#3760bf",
3168
+ "fill-primary-hovered": "#4772d3",
3169
+ "fill-primary-pressed": "#537fe1",
3170
+ "on-primary": "#e1e2e7",
3171
+ "accent": "#2e7de9",
3172
+ "fill-accent-resting": "#2e7de9",
3173
+ "fill-accent-hovered": "#0042a5",
3174
+ "fill-accent-pressed": "#0059c0",
3175
+ "fill-accent-quiet": "#0051b729",
3176
+ "border-accent": "#0051b780",
3177
+ "on-accent": "#ffffff",
3178
+ "focus": "#2e7de9",
3179
+ "link": "#0051b7",
3180
+ "info": "#2e7de9",
3181
+ "fill-info-quiet": "#2e7de924",
3182
+ "border-info": "#2e7de973",
3183
+ "success": "#587539",
3184
+ "fill-success-quiet": "#58753924",
3185
+ "border-success": "#58753973",
3186
+ "important": "#9854f1",
3187
+ "fill-important-quiet": "#9854f124",
3188
+ "border-important": "#9854f173",
3189
+ "warning": "#8c6c3e",
3190
+ "fill-warning-quiet": "#8c6c3e24",
3191
+ "border-warning": "#8c6c3e73",
3192
+ "danger": "#f52a65",
3193
+ "fill-danger-quiet": "#f52a6524",
3194
+ "border-danger": "#f52a6573"
3195
+ },
3181
3196
  "dark": {
3182
3197
  "surface-lower": "#1f2335",
3183
3198
  "surface-low": "#222538",
@@ -2707,6 +2707,53 @@ export const themes = [
2707
2707
  "row-padding": "var(--gw-space-3)"
2708
2708
  },
2709
2709
  "modes": {
2710
+ "light": {
2711
+ "surface-lower": "#d0d5e3",
2712
+ "surface-low": "#dadbe0",
2713
+ "surface-default": "#e1e2e7",
2714
+ "surface-raised": "#e9e9ed",
2715
+ "surface-overlay": "#e1e1e5",
2716
+ "border-quiet": "#ced2e4",
2717
+ "border-normal": "#c4c8da",
2718
+ "border-loud": "#abafc0",
2719
+ "text-strong": "#3760bf",
2720
+ "text-primary": "#3760bf",
2721
+ "text-secondary": "#6172b0",
2722
+ "text-disabled": "#6172b099",
2723
+ "fill-neutral-resting": "#dfdfe3",
2724
+ "fill-neutral-hovered": "#d5d5d9",
2725
+ "fill-neutral-pressed": "#ccccd0",
2726
+ "fill-neutral-selected": "#cfcfd3",
2727
+ "fill-neutral-disabled": "#e4e4e8",
2728
+ "fill-primary-resting": "#3760bf",
2729
+ "fill-primary-hovered": "#4772d3",
2730
+ "fill-primary-pressed": "#537fe1",
2731
+ "on-primary": "#e1e2e7",
2732
+ "accent": "#2e7de9",
2733
+ "fill-accent-resting": "#2e7de9",
2734
+ "fill-accent-hovered": "#0042a5",
2735
+ "fill-accent-pressed": "#0059c0",
2736
+ "fill-accent-quiet": "#0051b729",
2737
+ "border-accent": "#0051b780",
2738
+ "on-accent": "#ffffff",
2739
+ "focus": "#2e7de9",
2740
+ "link": "#0051b7",
2741
+ "info": "#2e7de9",
2742
+ "fill-info-quiet": "#2e7de924",
2743
+ "border-info": "#2e7de973",
2744
+ "success": "#587539",
2745
+ "fill-success-quiet": "#58753924",
2746
+ "border-success": "#58753973",
2747
+ "important": "#9854f1",
2748
+ "fill-important-quiet": "#9854f124",
2749
+ "border-important": "#9854f173",
2750
+ "warning": "#8c6c3e",
2751
+ "fill-warning-quiet": "#8c6c3e24",
2752
+ "border-warning": "#8c6c3e73",
2753
+ "danger": "#f52a65",
2754
+ "fill-danger-quiet": "#f52a6524",
2755
+ "border-danger": "#f52a6573"
2756
+ },
2710
2757
  "dark": {
2711
2758
  "surface-lower": "#16161e",
2712
2759
  "surface-low": "#171823",
@@ -2804,9 +2851,9 @@ export const themes = [
2804
2851
  }
2805
2852
  },
2806
2853
  {
2807
- "id": "tokyo-night-day",
2808
- "name": "Tokyo Night Day",
2809
- "description": "Tokyo Night Day, mapped onto the roles so it stays faithful to the Tokyo Night palette.",
2854
+ "id": "tokyo-night-moon",
2855
+ "name": "Tokyo Night Moon",
2856
+ "description": "Tokyo Night Moon, mapped onto the roles so it stays faithful to the Tokyo Night palette.",
2810
2857
  "optional": true,
2811
2858
  "family": "Tokyo Night",
2812
2859
  "examples": [],
@@ -2926,86 +2973,7 @@ export const themes = [
2926
2973
  "danger": "#f52a65",
2927
2974
  "fill-danger-quiet": "#f52a6524",
2928
2975
  "border-danger": "#f52a6573"
2929
- }
2930
- }
2931
- },
2932
- {
2933
- "id": "tokyo-night-moon",
2934
- "name": "Tokyo Night Moon",
2935
- "description": "Tokyo Night Moon, mapped onto the roles so it stays faithful to the Tokyo Night palette.",
2936
- "optional": true,
2937
- "family": "Tokyo Night",
2938
- "examples": [],
2939
- "style": {
2940
- "font": "Mona Sans",
2941
- "mono": "Geist Mono",
2942
- "radius": {
2943
- "panel": 10,
2944
- "control": 8,
2945
- "chip": 6
2946
- },
2947
- "border": {
2948
- "width": 1,
2949
- "strength": "hairline"
2950
- },
2951
- "weights": {
2952
- "regular": 400,
2953
- "strong": 600
2954
- },
2955
- "density": "normal",
2956
- "capitals": false,
2957
- "link": {
2958
- "color": "accent",
2959
- "underline": "thin"
2960
2976
  },
2961
- "surfaceAccent": "none",
2962
- "rows": "cards"
2963
- },
2964
- "properties": {
2965
- "font-sans": "\"Mona Sans Variable\", \"Mona Sans\", system-ui, sans-serif",
2966
- "font-figures": "\"Mona Sans Variable\", \"Mona Sans\", system-ui, sans-serif",
2967
- "font-mono": "\"Geist Mono Variable\", \"Geist Mono\", ui-monospace, monospace",
2968
- "font-weight-regular": "400",
2969
- "font-weight-strong": "600",
2970
- "density": "1",
2971
- "control-scale": "1",
2972
- "space-0-5": "calc(0.125rem * var(--gw-density))",
2973
- "space-1": "calc(0.25rem * var(--gw-density))",
2974
- "space-2": "calc(0.5rem * var(--gw-density))",
2975
- "space-3": "calc(0.75rem * var(--gw-density))",
2976
- "space-4": "calc(1rem * var(--gw-density))",
2977
- "space-5": "calc(1.25rem * var(--gw-density))",
2978
- "space-6": "calc(1.5rem * var(--gw-density))",
2979
- "space-7": "calc(1.75rem * var(--gw-density))",
2980
- "space-8": "calc(2rem * var(--gw-density))",
2981
- "space-9": "calc(2.25rem * var(--gw-density))",
2982
- "space-10": "calc(2.5rem * var(--gw-density))",
2983
- "space-11": "calc(2.75rem * var(--gw-density))",
2984
- "space-12": "calc(3rem * var(--gw-density))",
2985
- "space-13": "calc(3.25rem * var(--gw-density))",
2986
- "space-14": "calc(3.5rem * var(--gw-density))",
2987
- "space-15": "calc(3.75rem * var(--gw-density))",
2988
- "space-16": "calc(4rem * var(--gw-density))",
2989
- "space-17": "calc(4.25rem * var(--gw-density))",
2990
- "space-18": "calc(4.5rem * var(--gw-density))",
2991
- "space-19": "calc(4.75rem * var(--gw-density))",
2992
- "space-20": "calc(5rem * var(--gw-density))",
2993
- "radius-panel": "10px",
2994
- "radius-control": "8px",
2995
- "radius-chip": "6px",
2996
- "border-width": "1px",
2997
- "border-color": "var(--gw-color-border-quiet)",
2998
- "label-transform": "none",
2999
- "label-tracking": "normal",
3000
- "link-color": "var(--gw-color-link)",
3001
- "link-underline": "1px",
3002
- "panel-sheen": "none",
3003
- "panel-marker": "0px",
3004
- "panel-flange": "0px",
3005
- "panel-flange-color": "var(--gw-border-color)",
3006
- "row-padding": "var(--gw-space-3)"
3007
- },
3008
- "modes": {
3009
2977
  "dark": {
3010
2978
  "surface-lower": "#1e2030",
3011
2979
  "surface-low": "#202234",
@@ -3179,6 +3147,53 @@ export const themes = [
3179
3147
  "row-padding": "var(--gw-space-3)"
3180
3148
  },
3181
3149
  "modes": {
3150
+ "light": {
3151
+ "surface-lower": "#d0d5e3",
3152
+ "surface-low": "#dadbe0",
3153
+ "surface-default": "#e1e2e7",
3154
+ "surface-raised": "#e9e9ed",
3155
+ "surface-overlay": "#e1e1e5",
3156
+ "border-quiet": "#ced2e4",
3157
+ "border-normal": "#c4c8da",
3158
+ "border-loud": "#abafc0",
3159
+ "text-strong": "#3760bf",
3160
+ "text-primary": "#3760bf",
3161
+ "text-secondary": "#6172b0",
3162
+ "text-disabled": "#6172b099",
3163
+ "fill-neutral-resting": "#dfdfe3",
3164
+ "fill-neutral-hovered": "#d5d5d9",
3165
+ "fill-neutral-pressed": "#ccccd0",
3166
+ "fill-neutral-selected": "#cfcfd3",
3167
+ "fill-neutral-disabled": "#e4e4e8",
3168
+ "fill-primary-resting": "#3760bf",
3169
+ "fill-primary-hovered": "#4772d3",
3170
+ "fill-primary-pressed": "#537fe1",
3171
+ "on-primary": "#e1e2e7",
3172
+ "accent": "#2e7de9",
3173
+ "fill-accent-resting": "#2e7de9",
3174
+ "fill-accent-hovered": "#0042a5",
3175
+ "fill-accent-pressed": "#0059c0",
3176
+ "fill-accent-quiet": "#0051b729",
3177
+ "border-accent": "#0051b780",
3178
+ "on-accent": "#ffffff",
3179
+ "focus": "#2e7de9",
3180
+ "link": "#0051b7",
3181
+ "info": "#2e7de9",
3182
+ "fill-info-quiet": "#2e7de924",
3183
+ "border-info": "#2e7de973",
3184
+ "success": "#587539",
3185
+ "fill-success-quiet": "#58753924",
3186
+ "border-success": "#58753973",
3187
+ "important": "#9854f1",
3188
+ "fill-important-quiet": "#9854f124",
3189
+ "border-important": "#9854f173",
3190
+ "warning": "#8c6c3e",
3191
+ "fill-warning-quiet": "#8c6c3e24",
3192
+ "border-warning": "#8c6c3e73",
3193
+ "danger": "#f52a65",
3194
+ "fill-danger-quiet": "#f52a6524",
3195
+ "border-danger": "#f52a6573"
3196
+ },
3182
3197
  "dark": {
3183
3198
  "surface-lower": "#1f2335",
3184
3199
  "surface-low": "#222538",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timmo001/groundwork-tokens",
3
- "version": "0.9.40",
3
+ "version": "0.10.1",
4
4
  "description": "Groundwork's design tokens: the theme schema, the OKLCH solver and every theme as CSS and JSON",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
package/src/choices.ts CHANGED
@@ -19,7 +19,6 @@ import glazing from "../themes/glazing.json" with { type: "json" };
19
19
  import slate from "../themes/slate.json" with { type: "json" };
20
20
  import snag from "../themes/snag.json" with { type: "json" };
21
21
  import survey from "../themes/survey.json" with { type: "json" };
22
- import tokyoNightDay from "../themes/tokyo-night-day.json" with { type: "json" };
23
22
  import tokyoNightMoon from "../themes/tokyo-night-moon.json" with { type: "json" };
24
23
  import tokyoNightStorm from "../themes/tokyo-night-storm.json" with { type: "json" };
25
24
  import tokyoNight from "../themes/tokyo-night.json" with { type: "json" };
@@ -44,8 +43,8 @@ export const omarchyThemeStyleId = "gw-omarchy-theme";
44
43
 
45
44
  /**
46
45
  * A theme to offer, by id and name. A `Theme` document is one. `mode` marks
47
- * a theme with only one scheme, such as Catppuccin Latte: it's offered and
48
- * kept for that scheme alone, beside a pick for the other.
46
+ * a theme with only one scheme, such as Catppuccin Latte: while it's picked,
47
+ * the page stays in that scheme.
49
48
  */
50
49
  export interface ThemeChoice {
51
50
  readonly id: string;
@@ -59,6 +58,34 @@ export interface ThemeChoice {
59
58
  export const themeCovers = (choice: ThemeChoice, scheme: ThemeScheme) =>
60
59
  choice.mode === undefined || choice.mode === scheme;
61
60
 
61
+ /**
62
+ * Whether `mode` can be used with `choice`: any for a theme with both
63
+ * schemes, and only its own for one with one. Auto could land on the other
64
+ * scheme, so it's left out too.
65
+ */
66
+ export const themeAllows = (choice: ThemeChoice, mode: ThemeMode) =>
67
+ choice.mode === undefined ||
68
+ (mode !== "auto" && themeCovers(choice, mode === "light" ? "light" : "dark"));
69
+
70
+ /**
71
+ * Choices as a picker's options, grouped: a choice's `family`, or `group`
72
+ * for those without one. Each carries the schemes it covers as search
73
+ * keywords. Order the choices as the picker should list them,
74
+ * usually the app's own theme, then the other core themes, then the optional
75
+ * ones.
76
+ */
77
+ export const themeOptions = (
78
+ choices: readonly ThemeChoice[],
79
+ group = "Groundwork",
80
+ ) =>
81
+ choices.map(({ id, name, family, mode }) => ({
82
+ value: id,
83
+ label: name,
84
+ group: family ?? group,
85
+ // So a search for light or dark finds the themes that have it
86
+ keywords: mode === undefined ? ["light", "dark"] : [mode],
87
+ }));
88
+
62
89
  /** The core themes by id and name, in the order the docs list them. */
63
90
  export const coreThemeChoices: readonly ThemeChoice[] = [
64
91
  base,
@@ -79,7 +106,6 @@ export const optionalThemeDocuments = [
79
106
  catppuccinFrappe,
80
107
  catppuccinMacchiato,
81
108
  catppuccinMocha,
82
- tokyoNightDay,
83
109
  tokyoNight,
84
110
  tokyoNightStorm,
85
111
  tokyoNightMoon,
@@ -114,22 +140,16 @@ export interface ThemeBootOptions {
114
140
  readonly defaultTheme: string;
115
141
  /** The mode to start with. Defaults to `auto`. */
116
142
  readonly defaultMode?: ThemeMode;
117
- /**
118
- * Whether the Omarchy theme takes over while the visitor hasn't picked
119
- * one. With `false` it's only offered, and `defaultTheme` stays in use.
120
- * Defaults to `true`.
121
- */
122
- readonly followOmarchy?: boolean;
123
143
  }
124
144
 
125
145
  /** The local storage keys a pick is kept under. */
126
146
  export const themeStorageKeys = (key: string) => ({
127
147
  mode: `${key}:mode`,
128
148
  theme: `${key}:id`,
129
- dark: `${key}:id-dark`,
130
149
  document: `${key}:custom`,
131
150
  css: `${key}:custom-css`,
132
151
  name: `${key}:custom-name`,
152
+ scheme: `${key}:custom-mode`,
133
153
  });
134
154
 
135
155
  /** The Omarchy theme's cache, kept apart so a reset doesn't drop it. */
@@ -142,7 +162,8 @@ export const omarchyStorageKeys = (key: string) => ({
142
162
  /**
143
163
  * An inline script that applies the stored mode, theme and any custom or
144
164
  * Omarchy theme's cached CSS before the first paint. Takes the same key and
145
- * defaults as `pageTheme`.
165
+ * defaults as `pageTheme`. Picking a theme stores the mode it needs, so the
166
+ * two stay in step.
146
167
  */
147
168
  export const themeBootScript = (options: ThemeBootOptions) => {
148
169
  const config = JSON.stringify({
@@ -150,14 +171,13 @@ export const themeBootScript = (options: ThemeBootOptions) => {
150
171
  omarchy: omarchyStorageKeys(options.key),
151
172
  theme: options.defaultTheme,
152
173
  mode: options.defaultMode ?? "auto",
153
- follow: options.followOmarchy !== false,
154
174
  custom: customThemeId,
155
175
  style: customThemeStyleId,
156
176
  omarchyId: omarchyThemeId,
157
177
  omarchyStyle: omarchyThemeStyleId,
158
178
  });
159
179
 
160
- // With nothing picked, a cached Omarchy theme for the scheme is the
161
- // default, unless it's only offered
162
- return `(()=>{const c=${config};let s;try{s=localStorage}catch{}const g=(k)=>{try{return s?.getItem(k)??null}catch{return null}};const r=document.documentElement;const a=(id,css)=>{const e=document.createElement("style");e.id=id;e.textContent=css;document.head.append(e)};const m=g(c.keys.mode)??c.mode;const d=m==="dark"||m==="darker"||(m==="auto"&&matchMedia("(prefers-color-scheme: dark)").matches);const o=g(c.omarchy.css);let t=(d?g(c.keys.dark):null)??g(c.keys.theme)??(c.follow&&o&&g(c.omarchy.mode)===(d?"dark":"light")?c.omarchyId:c.theme);if(t===c.custom){const css=g(c.keys.css);if(css)a(c.style,css);else t=c.theme}else if(t===c.omarchyId){if(o)a(c.omarchyStyle,o);else t=c.theme}r.setAttribute("data-gw-theme",t);if(m==="auto")r.removeAttribute("data-gw-mode");else r.setAttribute("data-gw-mode",m)})();`;
180
+ // An imported or Omarchy theme only applies once it's been picked, and
181
+ // falls back to the default when its CSS has gone
182
+ return `(()=>{const c=${config};let s;try{s=localStorage}catch{}const g=(k)=>{try{return s?.getItem(k)??null}catch{return null}};const r=document.documentElement;const a=(id,css)=>{const e=document.createElement("style");e.id=id;e.textContent=css;document.head.append(e)};let m=g(c.keys.mode)??c.mode;let t=g(c.keys.theme)??c.theme;const o=t===c.custom?g(c.keys.css):t===c.omarchyId?g(c.omarchy.css):null;if(t===c.custom||t===c.omarchyId){if(o)a(t===c.custom?c.style:c.omarchyStyle,o);else{t=c.theme;m=c.mode}}r.setAttribute("data-gw-theme",t);if(m==="auto")r.removeAttribute("data-gw-mode");else r.setAttribute("data-gw-mode",m)})();`;
163
183
  };
package/src/generate.ts CHANGED
@@ -536,17 +536,17 @@ export const blumeTheme = (theme: ResolvedTheme) =>
536
536
  ].join("\n\n") + "\n";
537
537
 
538
538
  /**
539
- * Every core theme as Blume's tokens, each under `data-gw-docs-theme`, for a
540
- * site that lets readers pick one with the theme picker.
539
+ * Every theme, core and optional, as Blume's tokens, each under
540
+ * `data-gw-docs-theme`, for a site that lets readers pick one with the theme
541
+ * picker. An optional theme with one scheme has rules for that scheme only;
542
+ * the picker keeps the page in it.
541
543
  */
542
544
  export const blumeThemes = (themes: readonly ResolvedTheme[]) =>
543
545
  [
544
546
  `/* ${header} */`,
545
- ...themes
546
- .filter((theme) => !theme.optional)
547
- .flatMap((theme) =>
548
- blumeRules(theme, `:root[data-gw-docs-theme="${theme.id}"]`),
549
- ),
547
+ ...themes.flatMap((theme) =>
548
+ blumeRules(theme, `:root[data-gw-docs-theme="${theme.id}"]`),
549
+ ),
550
550
  ].join("\n\n") + "\n";
551
551
 
552
552
  const hexRoles = (roles: Roles) =>
@@ -761,7 +761,7 @@ export const optionalPage = (themes: readonly ResolvedTheme[]) => {
761
761
  "",
762
762
  `{/* ${header} */}`,
763
763
  "",
764
- "Most flavors are one mode of their palette, and GitHub's cover both light and dark. Each is mapped straight onto the roles rather than solved, so it looks the way the palette's authors intended. They take Base's style. The [contrast report](/themes/contrast) shows where a palette sits below the core targets.",
764
+ "Catppuccin's flavors are one mode each, so an app in one stays in its scheme. GitHub's cover both light and dark, and so do Tokyo Night's, each taking Day as its light side. Each is mapped straight onto the roles rather than solved, so it looks the way the palette's authors intended. They take Base's style. The [contrast report](/themes/contrast) shows where a palette sits below the core targets.",
765
765
  "",
766
766
  ...families.flatMap((family) => [
767
767
  `## ${family}`,