clampography 2.0.0-beta.2 → 2.0.0-beta.21

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/index.js CHANGED
@@ -3,99 +3,247 @@ import { themes as builtInThemes } from "./themes.js";
3
3
  import baseStyles from "./base.js";
4
4
  import extraStyles from "./extra.js";
5
5
 
6
+ // Import version from package.json
7
+ import { version } from "../package.json" with { type: "json" };
8
+
9
+ /**
10
+ * Helper to resolve boolean options from CSS configuration.
11
+ * CSS values often come as strings ("true"/"false"), which are both truthy in JS.
12
+ */
13
+ const resolveBool = (value, defaultValue) => {
14
+ if (
15
+ value === "false" || value === false || value === "no" || value === "none"
16
+ ) return false;
17
+ if (value === "true" || value === true || value === "yes") return true;
18
+ return defaultValue;
19
+ };
20
+
6
21
  /**
7
22
  * Main plugin function.
8
23
  */
9
- export default plugin.withOptions((options = {}) => {
10
- return ({ addBase }) => {
11
- // 1. Load Base and Extra styles
12
- const includeBase = options.base ?? true;
13
- const includeExtra = options.extra ?? false;
14
-
15
- if (includeBase) addBase(baseStyles);
16
- if (includeExtra) addBase(extraStyles);
17
-
18
- // 2. Parse themes configuration
19
- let configThemes = options.themes;
20
-
21
- // Default values
22
- let themesToInclude = [];
23
- let defaultThemeName = "light";
24
- let prefersDarkTheme = false;
25
- let rootSelector = options.root ?? ":root";
26
-
27
- // Normalize input to an array of strings
28
- // CSS might pass this as a single long string separated by commas
29
- let rawThemeList = [];
30
-
31
- if (typeof configThemes === "string") {
32
- if (configThemes.trim() === "all") {
33
- // Special case: themes: all
34
- rawThemeList = Object.keys(builtInThemes);
35
- } else if (configThemes.trim() === "false") {
36
- rawThemeList = [];
37
- } else {
38
- // Split by comma: "light --default, dark --prefersdark"
39
- rawThemeList = configThemes.split(",");
40
- }
41
- } else if (Array.isArray(configThemes)) {
42
- rawThemeList = configThemes;
43
- } else {
44
- // Default fallback if nothing provided
45
- rawThemeList = ["light", "dark"];
46
- }
47
-
48
- // 3. Process the list and look for flags (--default, --prefersdark)
49
- // If "all" was used, we don't look for flags (we use default light/dark logic) unless implemented otherwise.
50
- // Here we focus on the explicit list.
51
-
52
- rawThemeList.forEach((rawItem) => {
53
- let themeName = rawItem.trim();
54
-
55
- // Ignore empty entries
56
- if (!themeName) return;
57
-
58
- // Check for --default flag
59
- if (themeName.includes("--default")) {
60
- themeName = themeName.replace("--default", "").trim();
61
- defaultThemeName = themeName;
62
- }
63
-
64
- // Check for --prefersdark flag (case insensitive just in case)
65
- if (themeName.toLowerCase().includes("--prefersdark")) {
66
- themeName = themeName.replace(/--prefersdark/i, "").trim();
67
- prefersDarkTheme = themeName;
68
- }
69
-
70
- // Check if theme exists in the database
71
- if (builtInThemes[themeName]) {
72
- themesToInclude.push(themeName);
73
- }
74
- });
75
-
76
- // If list is empty after filtering, stop here
77
- if (themesToInclude.length === 0) return;
78
-
79
- // 4. Generate CSS
80
- const themeStyles = {};
81
-
82
- // A. Default theme (:root)
83
- if (builtInThemes[defaultThemeName]) {
84
- themeStyles[rootSelector] = builtInThemes[defaultThemeName];
85
- }
86
-
87
- // B. Theme for prefers-color-scheme: dark
88
- if (prefersDarkTheme && builtInThemes[prefersDarkTheme]) {
89
- themeStyles["@media (prefers-color-scheme: dark)"] = {
90
- [rootSelector]: builtInThemes[prefersDarkTheme],
24
+ export default plugin.withOptions(
25
+ (() => {
26
+ let firstRun = true; // Track first run for logging
27
+
28
+ return (options = {}) => {
29
+ return ({ addBase }) => {
30
+ // Extract logs option (default: true)
31
+ const showLogs = resolveBool(options.logs, true);
32
+
33
+ // Show startup log only once
34
+ if (showLogs && firstRun) {
35
+ console.log(`🍀 Clampography v${version} loaded successfully`);
36
+ firstRun = false;
37
+ }
38
+
39
+ // 1. Load Base and Extra styles
40
+ // We use the helper to correctly parse "false" string from CSS
41
+ const includeBase = resolveBool(options.base, true); // Default: true
42
+ const includeExtra = resolveBool(options.extra, false); // Default: false
43
+
44
+ // Pass options to the style functions to enable scoping
45
+ includeBase && addBase(baseStyles(options));
46
+ includeExtra && addBase(extraStyles(options));
47
+
48
+ // 2. Parse themes configuration
49
+ let configThemes = options.themes;
50
+ let themesToInclude = [];
51
+ let defaultThemeName = null;
52
+ let prefersDarkTheme = false;
53
+ let rootSelector = options.root || ":root";
54
+ let isAllThemes = false; // Track if user specified "all"
55
+
56
+ // Normalize input to an array of strings
57
+ let rawThemeList = [];
58
+ if (typeof configThemes === "string") {
59
+ if (["all", "true", "yes"].includes(configThemes.trim())) {
60
+ // Special case: themes: all
61
+ isAllThemes = true;
62
+ rawThemeList = Object.keys(builtInThemes);
63
+ } else if (["false", "none", "no"].includes(configThemes.trim())) {
64
+ // Explicitly disabled themes
65
+ rawThemeList = [];
66
+ } else {
67
+ rawThemeList = configThemes.split(",");
68
+ }
69
+ } else if (Array.isArray(configThemes)) {
70
+ rawThemeList = configThemes;
71
+ } else {
72
+ // Default behavior: NO themes loaded automatically.
73
+ // User must specify themes to load them.
74
+ rawThemeList = [];
75
+ }
76
+
77
+ // 3. Process the list and look for flags (--default, --prefersdark)
78
+ rawThemeList.forEach((rawItem) => {
79
+ let themeName = rawItem.trim();
80
+
81
+ // Ignore empty entries
82
+ if (!themeName) return;
83
+
84
+ // Check for --default flag
85
+ if (themeName.includes("--default")) {
86
+ themeName = themeName.replace("--default", "").trim();
87
+ defaultThemeName = themeName;
88
+ }
89
+
90
+ // Check for --prefersdark flag
91
+ if (themeName.toLowerCase().includes("--prefersdark")) {
92
+ themeName = themeName.replace(/--prefersdark/i, "").trim();
93
+ prefersDarkTheme = themeName;
94
+ }
95
+
96
+ // Check if theme exists in the database
97
+ if (builtInThemes[themeName]) {
98
+ themesToInclude.push(themeName);
99
+ }
100
+ });
101
+
102
+ // 4. Auto-configure defaults for "themes: all"
103
+ if (isAllThemes) {
104
+ if (!defaultThemeName) {
105
+ if (themesToInclude.includes("light")) {
106
+ defaultThemeName = "light";
107
+ } else if (themesToInclude.length > 0) {
108
+ defaultThemeName = themesToInclude[0];
109
+ }
110
+ }
111
+ if (!prefersDarkTheme && themesToInclude.includes("dark")) {
112
+ prefersDarkTheme = "dark";
113
+ }
114
+ }
115
+
116
+ // LOGGING: Built-in themes summary
117
+ if (showLogs) {
118
+ const explicitlyDisabled = ["false", "no", "none"].includes(
119
+ String(options.themes).trim(),
120
+ );
121
+
122
+ if (themesToInclude.length > 0) {
123
+ const themesList = themesToInclude.map((theme) => {
124
+ const flags = [];
125
+ if (theme === defaultThemeName) flags.push("default");
126
+ if (theme === prefersDarkTheme) flags.push("prefersdark");
127
+
128
+ const flagStr = flags.length > 0 ? ` (${flags.join(", ")})` : "";
129
+ return `${theme}${flagStr}`;
130
+ });
131
+
132
+ console.log(
133
+ `🍀 Clampography: Loaded ${themesToInclude.length} built-in themes: ${
134
+ themesList.join(", ")
135
+ }`,
136
+ );
137
+ } else if (!explicitlyDisabled) {
138
+ console.info("ℹ️ Clampography: No built-in themes loaded.");
139
+ }
140
+ }
141
+
142
+ // Final check before generating CSS
143
+ if (
144
+ themesToInclude.length === 0 && !defaultThemeName && !prefersDarkTheme
145
+ ) return;
146
+
147
+ // 5. Generate CSS
148
+ const themeStyles = {};
149
+
150
+ // A. Default theme - uses :where() for lower specificity
151
+ // Helper to combine root and data-theme
152
+ // If root is ":root", we use "html[data-theme...]" for backwards compatibility.
153
+ // If root is custom (e.g. "#morda"), we generate "#morda[data-theme...]"
154
+ const getThemeSelector = (themeName) => {
155
+ if (rootSelector === ":root") {
156
+ return `html[data-theme="${themeName}"], [data-theme="${themeName}"]`;
157
+ }
158
+ // For custom root, attach data-theme directly to it
159
+ // AND allow a nested data-theme inside it (optional, but good for nesting)
160
+ return `${rootSelector}[data-theme="${themeName}"], ${rootSelector} [data-theme="${themeName}"]`;
161
+ };
162
+
163
+ // A. Default theme
164
+ if (defaultThemeName && builtInThemes[defaultThemeName]) {
165
+ // Default variables applied to the root element itself without data-theme attribute
166
+ // uses :where() for lower specificity so it can be overridden
167
+ const defaultSelector = `:where(${rootSelector})`;
168
+
169
+ // Also apply if explicitly selected
170
+ const explicitSelector = getThemeSelector(defaultThemeName);
171
+
172
+ themeStyles[`${defaultSelector}, ${explicitSelector}`] =
173
+ builtInThemes[defaultThemeName];
174
+ }
175
+
176
+ // B. Theme for prefers-color-scheme: dark
177
+ if (prefersDarkTheme && builtInThemes[prefersDarkTheme]) {
178
+ themeStyles["@media (prefers-color-scheme: dark)"] = {
179
+ [rootSelector]: builtInThemes[prefersDarkTheme],
180
+ };
181
+ }
182
+
183
+ // C. All themes available via [data-theme] attribute
184
+ themesToInclude.forEach((themeName) => {
185
+ if (themeName === defaultThemeName) return;
186
+ const selector = getThemeSelector(themeName);
187
+ themeStyles[selector] = builtInThemes[themeName];
188
+ });
189
+
190
+ // D. Override media query with data-theme selectors
191
+ if (prefersDarkTheme) {
192
+ themeStyles["@media (prefers-color-scheme: dark)"] = {
193
+ ...themeStyles["@media (prefers-color-scheme: dark)"],
194
+ };
195
+
196
+ themesToInclude.forEach((themeName) => {
197
+ if (themeName === prefersDarkTheme) return;
198
+ const selector = getThemeSelector(themeName);
199
+
200
+ if (!themeStyles["@media (prefers-color-scheme: dark)"][selector]) {
201
+ themeStyles["@media (prefers-color-scheme: dark)"][selector] =
202
+ builtInThemes[themeName];
203
+ }
204
+ });
205
+ }
206
+
207
+ addBase(themeStyles);
91
208
  };
92
- }
93
-
94
- // C. Scoped styles [data-theme="..."]
95
- themesToInclude.forEach((themeName) => {
96
- themeStyles[`[data-theme="${themeName}"]`] = builtInThemes[themeName];
97
- });
98
-
99
- addBase(themeStyles);
100
- };
101
- });
209
+ };
210
+ })(),
211
+ // Theme extension - enables utilities like bg-surface, text-heading, etc.
212
+ (options = {}) => {
213
+ // ✅ Extract prefix option (default: "clampography")
214
+ // This prefix is ONLY used for Tailwind utility classes (e.g., bg-clampography-primary)
215
+ // CSS variables remain unchanged (always --clampography-*)
216
+ const prefixEnabled = resolveBool(options.prefix, true);
217
+ const prefix = prefixEnabled
218
+ ? (typeof options.prefix === "string" &&
219
+ !["false", "no", "none", "true"].includes(options.prefix)
220
+ ? options.prefix
221
+ : "clampography")
222
+ : "";
223
+
224
+ // Helper to add prefix with separator
225
+ const addPrefix = (name) => prefix ? `${prefix}-${name}` : name;
226
+
227
+ return {
228
+ theme: {
229
+ extend: {
230
+ colors: {
231
+ [addPrefix("background")]: "var(--clampography-background)",
232
+ [addPrefix("border")]: "var(--clampography-border)",
233
+ [addPrefix("error")]: "var(--clampography-error)",
234
+ [addPrefix("heading")]: "var(--clampography-heading)",
235
+ [addPrefix("info")]: "var(--clampography-info)",
236
+ [addPrefix("link")]: "var(--clampography-link)",
237
+ [addPrefix("muted")]: "var(--clampography-muted)",
238
+ [addPrefix("primary")]: "var(--clampography-primary)",
239
+ [addPrefix("secondary")]: "var(--clampography-secondary)",
240
+ [addPrefix("success")]: "var(--clampography-success)",
241
+ [addPrefix("surface")]: "var(--clampography-surface)",
242
+ [addPrefix("text")]: "var(--clampography-text)",
243
+ [addPrefix("warning")]: "var(--clampography-warning)",
244
+ },
245
+ },
246
+ },
247
+ };
248
+ },
249
+ );
@@ -1,70 +1,130 @@
1
1
  import plugin from "tailwindcss/plugin";
2
-
3
- // List of required color keys for validation (optional but good practice)
4
- const REQUIRED_KEYS = [
5
- "--clampography-background",
6
- "--clampography-text",
7
- "--clampography-link",
8
- "--clampography-primary",
9
- "--clampography-secondary",
10
- ];
2
+ import { themes as builtInThemes } from "./themes.js";
11
3
 
12
4
  export default plugin.withOptions((options = {}) => {
13
5
  return ({ addBase }) => {
14
6
  // 1. Extract metadata
15
7
  const themeName = options.name;
16
8
  const isDefault = options.default ?? false;
17
- const isPrefersDark = options.prefersdark ?? false; // lowercase because CSS might force it
18
- const rootSelector = options.root ?? ":root";
9
+ const isPrefersDark = options.prefersdark ?? false;
10
+ const rootSelector = options.root || ":root";
11
+ const colorScheme = options["color-scheme"] ?? "light";
12
+
13
+ // This option is completely separate from the main plugin's logs option
14
+ const showLogs = options.logs !== false;
19
15
 
20
16
  if (!themeName) {
21
- console.warn("Clampography: Theme definition missing 'name' property.");
17
+ if (showLogs) {
18
+ console.warn(
19
+ "🍀 Clampography: Theme definition missing 'name' property.",
20
+ );
21
+ }
22
22
  return;
23
23
  }
24
24
 
25
- // 2. Extract colors from options
26
- // We iterate over the options object and pick anything that looks like our CSS variable
27
- // or simply take all known keys.
28
- const themeColors = {};
25
+ // LOGGING: Custom theme loaded
26
+ if (showLogs) {
27
+ const flags = [];
28
+ if (isDefault) flags.push("Default");
29
+ if (isPrefersDark) flags.push("Dark Pref");
30
+ const flagStr = flags.length > 0 ? ` (${flags.join(", ")})` : "";
31
+
32
+ console.log(
33
+ `✨ Clampography: Loaded custom theme "${themeName}"${flagStr}`,
34
+ );
35
+ }
29
36
 
30
- // You can also support short aliases here if you want (e.g., 'primary' -> '--clampography-primary')
31
- // For now, let's assume user passes full variable names or mapped keys.
37
+ // 2. Prepare Base Colors (Fallback)
38
+ // We fetch the full palette of the requested color scheme (light/dark)
39
+ // to fill in any missing gaps in the user's definition.
40
+ const fallbackTheme = builtInThemes[colorScheme] || builtInThemes["light"];
32
41
 
33
- // Helper to map simplified keys to full CSS vars (optional convenience)
42
+ // 3. Extract & Merge Colors
43
+ const themeColors = {};
44
+
45
+ // Mapping of simplified keys to full CSS variable names
34
46
  const keyMap = {
35
47
  "background": "--clampography-background",
36
- "surface": "--clampography-surface",
37
48
  "border": "--clampography-border",
49
+ "error": "--clampography-error",
38
50
  "heading": "--clampography-heading",
39
- "text": "--clampography-text",
40
- "muted": "--clampography-muted",
51
+ "info": "--clampography-info",
41
52
  "link": "--clampography-link",
53
+ "muted": "--clampography-muted",
42
54
  "primary": "--clampography-primary",
43
55
  "secondary": "--clampography-secondary",
56
+ "success": "--clampography-success",
57
+ "surface": "--clampography-surface",
58
+ "text": "--clampography-text",
59
+ "warning": "--clampography-warning",
44
60
  };
45
61
 
62
+ // First, populate with fallback colors
63
+ Object.keys(fallbackTheme).forEach((key) => {
64
+ themeColors[key] = fallbackTheme[key];
65
+ });
66
+
67
+ // Then override with user provided values
46
68
  Object.keys(options).forEach((key) => {
47
- // Check if it's one of our mapped short keys
69
+ // Ignore metadata keys
70
+ if (
71
+ ["name", "default", "prefersdark", "root", "color-scheme", "logs"]
72
+ .includes(key)
73
+ ) return;
74
+
75
+ const value = options[key];
76
+
48
77
  if (keyMap[key]) {
49
- themeColors[keyMap[key]] = options[key];
50
- } // Or if it is already a custom property key (starts with --)
51
- else if (key.startsWith("--")) {
52
- themeColors[key] = options[key];
78
+ // Validate color format (only if logs enabled)
79
+ if (showLogs && value && typeof value === "string") {
80
+ // Check if value starts with oklch() or is a valid CSS color
81
+ const isOklch = value.trim().startsWith("oklch(");
82
+ const isHex = /^#[0-9A-Fa-f]{3,8}$/.test(value.trim());
83
+ const isRgb = value.trim().startsWith("rgb(") ||
84
+ value.trim().startsWith("rgba(");
85
+
86
+ if (!isOklch && !isHex && !isRgb) {
87
+ console.warn(
88
+ `Clampography (${themeName}): Color "${key}" has value "${value}" which may not be a valid color format. ` +
89
+ `For best compatibility with opacity modifiers (e.g., bg-${key}/20), use full OKLCH format: ` +
90
+ `oklch(70% 0.2 180) or oklch(0.7 0.2 180)`,
91
+ );
92
+ }
93
+
94
+ if (isHex || isRgb) {
95
+ console.info(
96
+ `🍀 Clampography (${themeName}): Color "${key}" uses ${
97
+ isHex ? "HEX" : "RGB"
98
+ } format. ` +
99
+ `Consider using OKLCH format for better color space support and smoother gradients.`,
100
+ );
101
+ }
102
+ }
103
+
104
+ themeColors[keyMap[key]] = value;
105
+ } else if (key.startsWith("--")) {
106
+ themeColors[key] = value;
53
107
  }
54
108
  });
55
109
 
56
- // 3. Generate Styles
110
+ // Add the CSS property 'color-scheme' for browser UI adaptation (scrollbars, etc.)
111
+ themeColors["color-scheme"] = colorScheme;
112
+
113
+ // 4. Generate Styles
57
114
  const styles = {};
58
115
 
59
- // A. Define the theme as a named data-theme (always available)
60
- styles[`[data-theme="${themeName}"]`] = themeColors;
116
+ // Build selector based on flags
117
+ let selector = `[data-theme="${themeName}"]`;
61
118
 
62
- // B. If marked as default, apply to :root
119
+ // If default, prepend :where(root) with lower specificity
63
120
  if (isDefault) {
64
- styles[rootSelector] = themeColors;
121
+ selector = `:where(${rootSelector}),${selector}`;
65
122
  }
66
123
 
67
- // C. If marked as prefers-dark, apply to media query
124
+ // Apply theme to the constructed selector
125
+ styles[selector] = themeColors;
126
+
127
+ // If prefers-dark, apply only to root selector in media query
68
128
  if (isPrefersDark) {
69
129
  styles["@media (prefers-color-scheme: dark)"] = {
70
130
  [rootSelector]: themeColors,
package/src/themes.js CHANGED
@@ -1,47 +1,67 @@
1
1
  export const themes = {
2
2
  light: {
3
- "--clampography-background": "#ffffff",
4
- "--clampography-surface": "#f3f4f6",
5
- "--clampography-border": "#e5e7eb",
6
- "--clampography-heading": "#111827",
7
- "--clampography-text": "#374151",
8
- "--clampography-muted": "#6b7280",
9
- "--clampography-link": "#2563eb",
10
- "--clampography-primary": "#3b82f6",
11
- "--clampography-secondary": "#9333ea",
3
+ "color-scheme": "light",
4
+ "--clampography-background": "oklch(100% 0 0)",
5
+ "--clampography-border": "oklch(92% 0.003 264)",
6
+ "--clampography-error": "oklch(63% 0.22 27)",
7
+ "--clampography-heading": "oklch(15% 0.02 264)",
8
+ "--clampography-info": "oklch(63% 0.258 262)",
9
+ "--clampography-link": "oklch(43% 0.19 264)",
10
+ "--clampography-muted": "oklch(52% 0.014 258)",
11
+ "--clampography-primary": "oklch(63% 0.258 262)",
12
+ "--clampography-secondary": "oklch(55% 0.28 300)",
13
+ "--clampography-success": "oklch(65% 0.17 165)",
14
+ "--clampography-surface": "oklch(96% 0.003 264)",
15
+ "--clampography-text": "oklch(31% 0.02 257)",
16
+ "--clampography-warning": "oklch(72% 0.17 65)",
12
17
  },
13
18
  dark: {
14
- "--clampography-background": "#0f172a",
15
- "--clampography-surface": "#1e293b",
16
- "--clampography-border": "#334155",
17
- "--clampography-heading": "#f8fafc",
18
- "--clampography-text": "#cbd5e1",
19
- "--clampography-muted": "#94a3b8",
20
- "--clampography-link": "#60a5fa",
21
- "--clampography-primary": "#3b82f6",
22
- "--clampography-secondary": "#a855f7",
19
+ "color-scheme": "dark",
20
+ "--clampography-background": "oklch(10% 0 0)",
21
+ "--clampography-border": "oklch(31% 0.03 254)",
22
+ "--clampography-error": "oklch(63% 0.22 27)",
23
+ "--clampography-heading": "oklch(98% 0.003 264)",
24
+ "--clampography-info": "oklch(72% 0.17 254)",
25
+ "--clampography-link": "oklch(72% 0.17 254)",
26
+ "--clampography-muted": "oklch(68% 0.024 254)",
27
+ "--clampography-primary": "oklch(63% 0.258 262)",
28
+ "--clampography-secondary": "oklch(63% 0.25 300)",
29
+ "--clampography-success": "oklch(65% 0.17 165)",
30
+ "--clampography-surface": "oklch(12% 0 0)",
31
+ "--clampography-text": "oklch(95% 0 0)",
32
+ "--clampography-warning": "oklch(72% 0.17 65)",
23
33
  },
24
34
  retro: {
25
- "--clampography-background": "#ece3ca",
26
- "--clampography-surface": "#e0d6b6",
27
- "--clampography-border": "#cbbd99",
28
- "--clampography-heading": "#2c2420",
29
- "--clampography-text": "#4a3b32",
30
- "--clampography-muted": "#756354",
31
- "--clampography-link": "#d97757",
32
- "--clampography-primary": "#e45f2b",
33
- "--clampography-secondary": "#f6c342",
35
+ "color-scheme": "light",
36
+ "--clampography-background": "oklch(91% 0.03 85)",
37
+ "--clampography-border": "oklch(78% 0.05 85)",
38
+ "--clampography-error": "oklch(52% 0.15 35)",
39
+ "--clampography-heading": "oklch(18% 0.02 35)",
40
+ "--clampography-info": "oklch(60% 0.06 230)",
41
+ "--clampography-link": "oklch(63% 0.13 40)",
42
+ "--clampography-muted": "oklch(44% 0.03 45)",
43
+ "--clampography-primary": "oklch(60% 0.19 35)",
44
+ "--clampography-secondary": "oklch(80% 0.14 85)",
45
+ "--clampography-success": "oklch(62% 0.10 130)",
46
+ "--clampography-surface": "oklch(87% 0.04 85)",
47
+ "--clampography-text": "oklch(28% 0.03 40)",
48
+ "--clampography-warning": "oklch(80% 0.14 85)",
34
49
  },
35
50
  cyberpunk: {
36
- "--clampography-background": "#000b1e",
37
- "--clampography-surface": "#051630",
38
- "--clampography-border": "#0f3661",
39
- "--clampography-heading": "#ffffff",
40
- "--clampography-text": "#00f0ff",
41
- "--clampography-muted": "#008f99",
42
- "--clampography-link": "#ff0099",
43
- "--clampography-primary": "#fcee0a",
44
- "--clampography-secondary": "#05ffa1",
51
+ "color-scheme": "dark",
52
+ "--clampography-background": "oklch(8% 0.04 264)",
53
+ "--clampography-border": "oklch(27% 0.09 254)",
54
+ "--clampography-error": "oklch(60% 0.29 340)",
55
+ "--clampography-heading": "oklch(100% 0 0)",
56
+ "--clampography-info": "oklch(88% 0.16 195)",
57
+ "--clampography-link": "oklch(60% 0.29 340)",
58
+ "--clampography-muted": "oklch(55% 0.07 200)",
59
+ "--clampography-primary": "oklch(93% 0.22 105)",
60
+ "--clampography-secondary": "oklch(87% 0.20 165)",
61
+ "--clampography-success": "oklch(87% 0.20 165)",
62
+ "--clampography-surface": "oklch(12% 0.05 264)",
63
+ "--clampography-text": "oklch(88% 0.16 195)",
64
+ "--clampography-warning": "oklch(93% 0.22 105)",
45
65
  },
46
66
  };
47
67
 
@@ -0,0 +1,14 @@
1
+ import type { Config, PluginCreator } from "tailwindcss/types/config";
2
+
3
+ interface ClampographyOptions {
4
+ themes?: string | string[] | boolean;
5
+ base?: boolean;
6
+ extra?: boolean;
7
+ root?: string;
8
+ prefix?: string | boolean;
9
+ logs?: boolean;
10
+ }
11
+
12
+ declare const clampographyPlugin: PluginCreator<ClampographyOptions>;
13
+
14
+ export default clampographyPlugin;