clampography 2.0.0-beta.10 → 2.0.0-beta.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clampography",
3
- "version": "2.0.0-beta.10",
3
+ "version": "2.0.0-beta.11",
4
4
  "description": "Fluid typography system based on CSS clamp() with optional themes and extra styles. A feature-rich alternative to Tailwind CSS Typography plugin.",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/base.css CHANGED
@@ -252,7 +252,7 @@
252
252
  /* Time element */
253
253
  time {
254
254
  font-style: normal;
255
- font-variant-numeric: tabular-nums; /* Monospace numbers for alignment */
255
+ font-variant-numeric: tabular-nums;
256
256
  }
257
257
 
258
258
  /* --------------------------------------------------------------------------
package/src/base.js CHANGED
@@ -144,15 +144,13 @@ export default {
144
144
  "line-height": "1.5",
145
145
  },
146
146
 
147
- kbd: {
147
+ ":where(code, kbd, samp)": {
148
148
  "font-family": "var(--font-family-mono)",
149
149
  "font-size": "0.875em",
150
- "font-weight": "600",
151
150
  },
152
151
 
153
- samp: {
154
- "font-family": "var(--font-family-mono)",
155
- "font-size": "0.875em",
152
+ kbd: {
153
+ "font-weight": "600",
156
154
  },
157
155
 
158
156
  data: {
@@ -331,7 +329,6 @@ export default {
331
329
  "margin-top": "var(--spacing-md)",
332
330
  "margin-bottom": "var(--spacing-md)",
333
331
  padding: "var(--spacing-md)",
334
- border: "0",
335
332
  },
336
333
 
337
334
  legend: {
package/src/convert.js ADDED
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env bun
2
+
3
+ /**
4
+ * Converts base.css to base.js format with preserved comments
5
+ * https://claude.ai/chat/90dedd98-3e31-4831-a620-c35d6523b836
6
+ */
7
+
8
+ import { readFileSync, writeFileSync } from "fs";
9
+ import { resolve } from "path";
10
+
11
+ // Configuration
12
+ const INPUT_FILE = "base.css";
13
+ const OUTPUT_FILE = "base.js";
14
+
15
+ /**
16
+ * Parse CSS content into structured data
17
+ */
18
+ function parseCSS(css) {
19
+ const result = {};
20
+ const lines = css.split("\n");
21
+ let currentContext = result;
22
+ let contextStack = [result];
23
+ let currentSelector = null;
24
+ let inAtLayer = false;
25
+ let buffer = "";
26
+ let commentBuffer = [];
27
+
28
+ for (let i = 0; i < lines.length; i++) {
29
+ const line = lines[i].trim();
30
+
31
+ // Skip empty lines
32
+ if (!line) {
33
+ if (commentBuffer.length > 0) {
34
+ commentBuffer.push("");
35
+ }
36
+ continue;
37
+ }
38
+
39
+ // Capture comments
40
+ if (line.startsWith("/*")) {
41
+ const commentLines = [line];
42
+ while (i < lines.length && !lines[i].includes("*/")) {
43
+ i++;
44
+ commentLines.push(lines[i].trim());
45
+ }
46
+ commentBuffer.push(...commentLines);
47
+ continue;
48
+ }
49
+
50
+ // Handle @layer
51
+ if (line.startsWith("@layer")) {
52
+ const match = line.match(/@layer\s+(\w+)/);
53
+ if (match) {
54
+ inAtLayer = true;
55
+ currentContext["@layer base"] = {};
56
+ contextStack.push(currentContext["@layer base"]);
57
+ currentContext = currentContext["@layer base"];
58
+ }
59
+ continue;
60
+ }
61
+
62
+ // Handle opening brace (new rule)
63
+ if (line.includes("{") && !line.includes("}")) {
64
+ const selector = line.replace("{", "").trim();
65
+
66
+ // Store comments before selector
67
+ if (commentBuffer.length > 0) {
68
+ currentContext[`__comment_${Object.keys(currentContext).length}`] =
69
+ commentBuffer.join("\n");
70
+ commentBuffer = [];
71
+ }
72
+
73
+ currentContext[selector] = {};
74
+ contextStack.push(currentContext[selector]);
75
+ currentContext = currentContext[selector];
76
+ currentSelector = selector;
77
+ continue;
78
+ }
79
+
80
+ // Handle closing brace
81
+ if (line === "}") {
82
+ contextStack.pop();
83
+ currentContext = contextStack[contextStack.length - 1];
84
+ currentSelector = null;
85
+ continue;
86
+ }
87
+
88
+ // Handle properties
89
+ if (line.includes(":") && currentSelector) {
90
+ let [prop, ...valueParts] = line.split(":");
91
+ let value = valueParts.join(":").trim();
92
+
93
+ // Remove semicolon and inline comments
94
+ const inlineComment = value.match(/\/\*.*?\*\//);
95
+ if (inlineComment) {
96
+ value = value.replace(inlineComment[0], "").trim();
97
+ }
98
+ value = value.replace(";", "").trim();
99
+
100
+ prop = prop.trim();
101
+
102
+ // Store inline comment separately if exists
103
+ if (inlineComment && inlineComment[0]) {
104
+ currentContext[`__inline_comment_${prop}`] = inlineComment[0];
105
+ }
106
+
107
+ currentContext[prop] = value;
108
+ }
109
+ }
110
+
111
+ return result;
112
+ }
113
+
114
+ /**
115
+ * Convert parsed CSS to JS object string
116
+ */
117
+ function toJSObject(obj, indent = 0) {
118
+ const spaces = " ".repeat(indent);
119
+ const lines = [];
120
+
121
+ for (const [key, value] of Object.entries(obj)) {
122
+ // Handle comments
123
+ if (key.startsWith("__comment_")) {
124
+ const comment = value.split("\n").map((line) => `${spaces}${line}`).join(
125
+ "\n",
126
+ );
127
+ lines.push(comment);
128
+ continue;
129
+ }
130
+
131
+ if (key.startsWith("__inline_comment_")) {
132
+ continue; // Skip inline comments in first pass
133
+ }
134
+
135
+ if (typeof value === "object" && !Array.isArray(value)) {
136
+ // It's a nested object (selector)
137
+ lines.push(`${spaces}"${key}": {`);
138
+ lines.push(toJSObject(value, indent + 1));
139
+ lines.push(`${spaces}},`);
140
+ } else {
141
+ // It's a property
142
+ const formattedValue = value.includes('"') || value.includes("'")
143
+ ? `"${value.replace(/"/g, '\\"')}"`
144
+ : `"${value}"`;
145
+
146
+ // Check for inline comment
147
+ const inlineCommentKey = `__inline_comment_${key}`;
148
+ const inlineComment = obj[inlineCommentKey];
149
+ const comment = inlineComment ? ` ${inlineComment}` : "";
150
+
151
+ lines.push(`${spaces}"${key}": ${formattedValue},${comment}`);
152
+ }
153
+ }
154
+
155
+ return lines.join("\n");
156
+ }
157
+
158
+ /**
159
+ * Main conversion function
160
+ */
161
+ function convertCSStoJS(cssContent) {
162
+ const parsed = parseCSS(cssContent);
163
+ const jsContent = `export default {\n${
164
+ toJSObject(parsed["@layer base"] || parsed, 1)
165
+ }\n};\n`;
166
+ return jsContent;
167
+ }
168
+
169
+ // Main execution
170
+ try {
171
+ console.log(`📖 Reading ${INPUT_FILE}...`);
172
+ const cssContent = readFileSync(resolve(INPUT_FILE), "utf-8");
173
+
174
+ console.log("⚙️ Converting CSS to JS...");
175
+ const jsContent = convertCSStoJS(cssContent);
176
+
177
+ console.log(`💾 Writing ${OUTPUT_FILE}...`);
178
+ writeFileSync(resolve(OUTPUT_FILE), jsContent, "utf-8");
179
+
180
+ console.log("✅ Conversion complete!");
181
+ console.log(`📄 Output: ${OUTPUT_FILE}`);
182
+ } catch (error) {
183
+ console.error("❌ Error:", error.message);
184
+ process.exit(1);
185
+ }
package/src/extra.js CHANGED
@@ -2,63 +2,79 @@
2
2
  * Extra opinionated styles and coloring.
3
3
  * Applies colors to the structural base elements.
4
4
  */
5
+
5
6
  export default {
6
7
  // --- Basic Coloring (Applying theme variables) ---
7
-
8
8
  "body": {
9
- "background-color": "var(--clampography-background)",
10
- "color": "var(--clampography-text)",
9
+ "background-color": "oklch(var(--clampography-background))",
10
+ "color": "oklch(var(--clampography-text))",
11
11
  },
12
12
 
13
13
  ":where(h1, h2, h3, h4, h5, h6)": {
14
- "color": "var(--clampography-heading)",
14
+ "color": "oklch(var(--clampography-heading))",
15
15
  },
16
16
 
17
17
  "a": {
18
- "color": "var(--clampography-link)",
18
+ "color": "oklch(var(--clampography-link))",
19
19
  },
20
20
 
21
21
  // Lists
22
22
  "ul > li::before": {
23
- "background-color": "var(--clampography-primary)", // Bullet points
23
+ "background-color": "oklch(var(--clampography-primary))", // Bullet points
24
24
  },
25
25
 
26
26
  "ol > li::before": {
27
- "color": "var(--clampography-secondary)", // Numbers
27
+ "color": "oklch(var(--clampography-secondary))", // Numbers
28
28
  },
29
29
 
30
30
  // Inline Code
31
31
  ":where(code, kbd, samp)": {
32
- "background-color": "var(--clampography-surface)",
33
- "color": "var(--clampography-heading)",
34
- "border": "1px solid var(--clampography-border)",
32
+ "background-color": "oklch(var(--clampography-surface))",
33
+ "color": "oklch(var(--clampography-heading))",
34
+ "border": "1px solid oklch(var(--clampography-border))",
35
35
  "border-radius": "0.25rem",
36
+ "padding": "0.125rem var(--spacing-xs)",
37
+ },
38
+
39
+ // Keyboard input - vertical alignment
40
+ "kbd": {
41
+ transform: "translateY(-0.15em)",
36
42
  },
37
43
 
38
44
  // Preformatted Code Blocks
39
45
  "pre": {
40
- "background-color": "var(--clampography-surface)",
41
- "border": "1px solid var(--clampography-border)",
46
+ "background-color": "oklch(var(--clampography-surface))",
47
+ "border": "1px solid oklch(var(--clampography-border))",
42
48
  "border-radius": "0.375rem",
43
49
  "padding": "1rem",
44
50
  },
45
51
 
46
52
  // Tables
53
+ "table": {
54
+ "padding": "var(--spacing-sm)",
55
+ "border": "1px solid oklch(var(--clampography-border))",
56
+ },
57
+
47
58
  "th": {
48
- "color": "var(--clampography-heading)",
59
+ "color": "oklch(var(--clampography-heading))",
49
60
  },
50
61
 
51
62
  "th, td": {
52
- "border-bottom": "1px solid var(--clampography-border)",
63
+ "border": "1px solid oklch(var(--clampography-border))",
53
64
  },
54
65
 
55
66
  "thead th": {
56
67
  "border-bottom-width": "2px",
57
68
  },
58
69
 
70
+ // Zebra striping for table rows
71
+ "tbody tr:nth-child(even)": {
72
+ "background-color": "oklch(var(--clampography-surface))",
73
+ },
74
+
59
75
  // Captions & Muted text
60
76
  "caption, figcaption, .muted": {
61
- "color": "var(--clampography-muted)",
77
+ "color": "oklch(var(--clampography-muted))",
62
78
  },
63
79
 
64
80
  // Horizontal Rule (Thematic)
@@ -67,7 +83,7 @@ export default {
67
83
  "border-width": "0",
68
84
  "margin-top": "3rem",
69
85
  "margin-bottom": "3rem",
70
- "background-color": "var(--clampography-border)",
86
+ "background-color": "oklch(var(--clampography-border))",
71
87
  },
72
88
 
73
89
  // --- Opinionated Extras ---
@@ -75,12 +91,12 @@ export default {
75
91
  // Styled Blockquote
76
92
  "blockquote": {
77
93
  "border-left-width": "4px",
78
- "border-left-color": "var(--clampography-primary)",
79
- "background-color": "var(--clampography-surface)",
94
+ "border-left-color": "oklch(var(--clampography-primary))",
95
+ "background-color": "oklch(var(--clampography-surface))",
80
96
  "padding": "1rem",
81
97
  "border-radius": "0.25rem",
82
98
  "font-style": "italic",
83
- "color": "var(--clampography-heading)",
99
+ "color": "oklch(var(--clampography-heading))",
84
100
  },
85
101
 
86
102
  // Styled Links (Enhanced)
@@ -95,44 +111,60 @@ export default {
95
111
  },
96
112
 
97
113
  "a:hover": {
98
- "text-decoration-color": "var(--clampography-primary)",
114
+ "text-decoration-color": "oklch(var(--clampography-primary))",
99
115
  },
100
116
 
101
117
  // Mark
102
118
  "mark": {
103
- "background-color": "var(--clampography-primary)",
104
- "color": "var(--clampography-background)",
119
+ "background-color": "oklch(var(--clampography-primary))",
120
+ "color": "oklch(var(--clampography-background))",
121
+ "padding": "0.125rem var(--spacing-xs)",
122
+ "border-radius": "0.25rem",
105
123
  },
106
124
 
107
125
  // Deleted Text
108
126
  "del": {
109
- "text-decoration-color": "var(--clampography-secondary)",
127
+ "text-decoration-color": "oklch(var(--clampography-secondary))",
110
128
  "text-decoration-thickness": "2px",
111
129
  },
112
130
 
131
+ // Buttons - All types
132
+ ":where(button, [type='button'], [type='reset'], [type='submit'])": {
133
+ "padding": "var(--spacing-xs) var(--spacing-sm)",
134
+ "border": "1px solid oklch(var(--clampography-border))",
135
+ "border-radius": "0.375rem", // ← Rounded corners
136
+ },
137
+
138
+ // Inputs - All types
139
+ ":where(input:not([type='checkbox'], [type='radio']), textarea, select)": {
140
+ "padding": "var(--spacing-xs) var(--spacing-sm)",
141
+ "border": "1px solid oklch(var(--clampography-border))",
142
+ "border-radius": "0.375rem", // ← Rounded corners
143
+ },
144
+
113
145
  // Fieldset
114
146
  "fieldset": {
115
- "border": "1px solid var(--clampography-border)",
147
+ "border": "1px solid oklch(var(--clampography-border))",
116
148
  "border-radius": "0.375rem",
117
149
  },
118
150
 
119
151
  "legend": {
120
- "color": "var(--clampography-heading)",
152
+ "color": "oklch(var(--clampography-heading))",
121
153
  },
122
154
 
123
155
  // Details
124
156
  "details": {
125
- "border": "1px solid var(--clampography-border)",
157
+ "border": "1px solid oklch(var(--clampography-border))",
126
158
  "border-radius": "0.375rem",
127
159
  "padding": "0.5rem",
128
160
  },
129
161
 
130
162
  "summary": {
131
- "color": "var(--clampography-heading)",
163
+ "color": "oklch(var(--clampography-heading))",
132
164
  },
133
165
 
134
166
  "details[open] > summary": {
135
- "border-bottom": "1px solid var(--clampography-border)",
167
+ "border-bottom": "1px solid oklch(var(--clampography-border))",
136
168
  "padding-bottom": "0.5rem",
137
169
  },
138
170
  };
package/src/index.js CHANGED
@@ -16,94 +16,120 @@ const resolveBool = (value, defaultValue) => {
16
16
  /**
17
17
  * Main plugin function.
18
18
  */
19
- export default plugin.withOptions((options = {}) => {
20
- return ({ addBase }) => {
21
- // 1. Load Base and Extra styles
22
- // We use the helper to correctly parse "false" string from CSS
23
- const includeBase = resolveBool(options.base, true); // Default: true
24
- const includeExtra = resolveBool(options.extra, false); // Default: false
25
-
26
- includeBase && addBase(baseStyles);
27
- includeExtra && addBase(extraStyles);
28
-
29
- // 2. Parse themes configuration
30
- let configThemes = options.themes;
31
- let themesToInclude = [];
32
- let defaultThemeName = null;
33
- let prefersDarkTheme = false;
34
- let rootSelector = options.root ?? ":root";
35
-
36
- // Normalize input to an array of strings
37
- let rawThemeList = [];
38
-
39
- if (typeof configThemes === "string") {
40
- if (configThemes.trim() === "all") {
41
- // Special case: themes: all
42
- rawThemeList = Object.keys(builtInThemes);
43
- } else if (configThemes.trim() === "false") {
44
- // Explicitly disabled themes
45
- rawThemeList = [];
19
+ export default plugin.withOptions(
20
+ (options = {}) => {
21
+ return ({ addBase }) => {
22
+ // 1. Load Base and Extra styles
23
+ // We use the helper to correctly parse "false" string from CSS
24
+ const includeBase = resolveBool(options.base, true); // Default: true
25
+ const includeExtra = resolveBool(options.extra, false); // Default: false
26
+
27
+ includeBase && addBase(baseStyles);
28
+ includeExtra && addBase(extraStyles);
29
+
30
+ // 2. Parse themes configuration
31
+ let configThemes = options.themes;
32
+ let themesToInclude = [];
33
+ let defaultThemeName = null;
34
+ let prefersDarkTheme = false;
35
+ let rootSelector = options.root ?? ":root";
36
+
37
+ // Normalize input to an array of strings
38
+ let rawThemeList = [];
39
+
40
+ if (typeof configThemes === "string") {
41
+ if (["all", "true", "yes"].includes(configThemes.trim())) {
42
+ // Special case: themes: all
43
+ rawThemeList = Object.keys(builtInThemes);
44
+ } else if (["false", "none", "no"].includes(configThemes.trim())) {
45
+ // Explicitly disabled themes
46
+ rawThemeList = [];
47
+ } else {
48
+ rawThemeList = configThemes.split(",");
49
+ }
50
+ } else if (Array.isArray(configThemes)) {
51
+ rawThemeList = configThemes;
46
52
  } else {
47
- rawThemeList = configThemes.split(",");
48
- }
49
- } else if (Array.isArray(configThemes)) {
50
- rawThemeList = configThemes;
51
- } else {
52
- // Default behavior: NO themes loaded automatically.
53
- // User must specify themes to load them.
54
- rawThemeList = [];
55
- }
56
-
57
- // 3. Process the list and look for flags (--default, --prefersdark)
58
- rawThemeList.forEach((rawItem) => {
59
- let themeName = rawItem.trim();
60
-
61
- // Ignore empty entries
62
- if (!themeName) return;
63
-
64
- // Check for --default flag
65
- if (themeName.includes("--default")) {
66
- themeName = themeName.replace("--default", "").trim();
67
- defaultThemeName = themeName;
53
+ // Default behavior: NO themes loaded automatically.
54
+ // User must specify themes to load them.
55
+ rawThemeList = [];
68
56
  }
69
57
 
70
- // Check for --prefersdark flag
71
- if (themeName.toLowerCase().includes("--prefersdark")) {
72
- themeName = themeName.replace(/--prefersdark/i, "").trim();
73
- prefersDarkTheme = themeName;
58
+ // 3. Process the list and look for flags (--default, --prefersdark)
59
+ rawThemeList.forEach((rawItem) => {
60
+ let themeName = rawItem.trim();
61
+
62
+ // Ignore empty entries
63
+ if (!themeName) return;
64
+
65
+ // Check for --default flag
66
+ if (themeName.includes("--default")) {
67
+ themeName = themeName.replace("--default", "").trim();
68
+ defaultThemeName = themeName;
69
+ }
70
+
71
+ // Check for --prefersdark flag
72
+ if (themeName.toLowerCase().includes("--prefersdark")) {
73
+ themeName = themeName.replace(/--prefersdark/i, "").trim();
74
+ prefersDarkTheme = themeName;
75
+ }
76
+
77
+ // Check if theme exists in the database
78
+ if (builtInThemes[themeName]) {
79
+ themesToInclude.push(themeName);
80
+ }
81
+ });
82
+
83
+ // If list is empty after filtering, stop here
84
+ if (
85
+ themesToInclude.length === 0 && !defaultThemeName && !prefersDarkTheme
86
+ ) return;
87
+
88
+ // 4. Generate CSS
89
+ const themeStyles = {};
90
+
91
+ // A. Default theme (:root)
92
+ if (defaultThemeName && builtInThemes[defaultThemeName]) {
93
+ themeStyles[rootSelector] = builtInThemes[defaultThemeName];
74
94
  }
75
95
 
76
- // Check if theme exists in the database
77
- if (builtInThemes[themeName]) {
78
- themesToInclude.push(themeName);
96
+ // B. Theme for prefers-color-scheme: dark
97
+ if (prefersDarkTheme && builtInThemes[prefersDarkTheme]) {
98
+ themeStyles["@media (prefers-color-scheme: dark)"] = {
99
+ [rootSelector]: builtInThemes[prefersDarkTheme],
100
+ };
79
101
  }
80
- });
81
-
82
- // If list is empty after filtering, stop here
83
- if (
84
- themesToInclude.length === 0 && !defaultThemeName && !prefersDarkTheme
85
- ) return;
86
-
87
- // 4. Generate CSS
88
- const themeStyles = {};
89
-
90
- // A. Default theme (:root)
91
- if (defaultThemeName && builtInThemes[defaultThemeName]) {
92
- themeStyles[rootSelector] = builtInThemes[defaultThemeName];
93
- }
94
-
95
- // B. Theme for prefers-color-scheme: dark
96
- if (prefersDarkTheme && builtInThemes[prefersDarkTheme]) {
97
- themeStyles["@media (prefers-color-scheme: dark)"] = {
98
- [rootSelector]: builtInThemes[prefersDarkTheme],
99
- };
100
- }
101
-
102
- // C. Scoped styles [data-theme="..."]
103
- themesToInclude.forEach((themeName) => {
104
- themeStyles[`[data-theme="${themeName}"]`] = builtInThemes[themeName];
105
- });
106
-
107
- addBase(themeStyles);
108
- };
109
- });
102
+
103
+ // C. Scoped styles [data-theme="..."]
104
+ themesToInclude.forEach((themeName) => {
105
+ themeStyles[`[data-theme="${themeName}"]`] = builtInThemes[themeName];
106
+ });
107
+
108
+ addBase(themeStyles);
109
+ };
110
+ },
111
+ // Theme extension - enables utilities like bg-surface, text-heading, etc.
112
+ (options = {}) => {
113
+ return {
114
+ theme: {
115
+ extend: {
116
+ colors: {
117
+ background: "oklch(var(--clampography-background) / <alpha-value>)",
118
+ border: "oklch(var(--clampography-border) / <alpha-value>)",
119
+ error: "oklch(var(--clampography-error) / <alpha-value>)",
120
+ heading: "oklch(var(--clampography-heading) / <alpha-value>)",
121
+ info: "oklch(var(--clampography-info) / <alpha-value>)",
122
+ link: "oklch(var(--clampography-link) / <alpha-value>)",
123
+ muted: "oklch(var(--clampography-muted) / <alpha-value>)",
124
+ primary: "oklch(var(--clampography-primary) / <alpha-value>)",
125
+ secondary: "oklch(var(--clampography-secondary) / <alpha-value>)",
126
+ success: "oklch(var(--clampography-success) / <alpha-value>)",
127
+ surface: "oklch(var(--clampography-surface) / <alpha-value>)",
128
+ text: "oklch(var(--clampography-text) / <alpha-value>)",
129
+ warning: "oklch(var(--clampography-warning) / <alpha-value>)",
130
+ },
131
+ },
132
+ },
133
+ };
134
+ },
135
+ );
@@ -27,14 +27,18 @@ export default plugin.withOptions((options = {}) => {
27
27
  // Mapping of simplified keys to full CSS variable names
28
28
  const keyMap = {
29
29
  "background": "--clampography-background",
30
- "surface": "--clampography-surface",
31
30
  "border": "--clampography-border",
31
+ "error": "--clampography-error",
32
32
  "heading": "--clampography-heading",
33
- "text": "--clampography-text",
34
- "muted": "--clampography-muted",
33
+ "info": "--clampography-info",
35
34
  "link": "--clampography-link",
35
+ "muted": "--clampography-muted",
36
36
  "primary": "--clampography-primary",
37
37
  "secondary": "--clampography-secondary",
38
+ "success": "--clampography-success",
39
+ "surface": "--clampography-surface",
40
+ "text": "--clampography-text",
41
+ "warning": "--clampography-warning",
38
42
  };
39
43
 
40
44
  // First, populate with fallback colors
package/src/themes.js CHANGED
@@ -1,51 +1,67 @@
1
1
  export const themes = {
2
2
  light: {
3
3
  "color-scheme": "light",
4
- "--clampography-background": "#ffffff",
5
- "--clampography-surface": "#f3f4f6",
6
- "--clampography-border": "#e5e7eb",
7
- "--clampography-heading": "#111827",
8
- "--clampography-text": "#374151",
9
- "--clampography-muted": "#6b7280",
10
- "--clampography-link": "#2563eb",
11
- "--clampography-primary": "#3b82f6",
12
- "--clampography-secondary": "#9333ea",
4
+ "--clampography-background": "100% 0 0",
5
+ "--clampography-border": "92% 0.003 264",
6
+ "--clampography-error": "63% 0.22 27",
7
+ "--clampography-heading": "15% 0.02 264",
8
+ "--clampography-info": "63% 0.258 262",
9
+ "--clampography-link": "43% 0.19 264",
10
+ "--clampography-muted": "52% 0.014 258",
11
+ "--clampography-primary": "63% 0.258 262",
12
+ "--clampography-secondary": "55% 0.28 300",
13
+ "--clampography-success": "65% 0.17 165",
14
+ "--clampography-surface": "96% 0.003 264",
15
+ "--clampography-text": "31% 0.02 257",
16
+ "--clampography-warning": "72% 0.17 65",
13
17
  },
14
18
  dark: {
15
19
  "color-scheme": "dark",
16
- "--clampography-background": "#0f172a",
17
- "--clampography-surface": "#1e293b",
18
- "--clampography-border": "#334155",
19
- "--clampography-heading": "#f8fafc",
20
- "--clampography-text": "#cbd5e1",
21
- "--clampography-muted": "#94a3b8",
22
- "--clampography-link": "#60a5fa",
23
- "--clampography-primary": "#3b82f6",
24
- "--clampography-secondary": "#a855f7",
20
+ "--clampography-background": "10% 0 0",
21
+ "--clampography-border": "31% 0.03 254",
22
+ "--clampography-error": "63% 0.22 27",
23
+ "--clampography-heading": "98% 0.003 264",
24
+ "--clampography-info": "72% 0.17 254",
25
+ "--clampography-link": "72% 0.17 254",
26
+ "--clampography-muted": "68% 0.024 254",
27
+ "--clampography-primary": "63% 0.258 262",
28
+ "--clampography-secondary": "63% 0.25 300",
29
+ "--clampography-success": "65% 0.17 165",
30
+ "--clampography-surface": "12% 0 0",
31
+ "--clampography-text": "95% 0 0",
32
+ "--clampography-warning": "72% 0.17 65",
25
33
  },
26
34
  retro: {
27
35
  "color-scheme": "light",
28
- "--clampography-background": "#ece3ca",
29
- "--clampography-surface": "#e0d6b6",
30
- "--clampography-border": "#cbbd99",
31
- "--clampography-heading": "#2c2420",
32
- "--clampography-text": "#4a3b32",
33
- "--clampography-muted": "#756354",
34
- "--clampography-link": "#d97757",
35
- "--clampography-primary": "#e45f2b",
36
- "--clampography-secondary": "#f6c342",
36
+ "--clampography-background": "91% 0.03 85",
37
+ "--clampography-border": "78% 0.05 85",
38
+ "--clampography-error": "52% 0.15 35",
39
+ "--clampography-heading": "18% 0.02 35",
40
+ "--clampography-info": "60% 0.06 230",
41
+ "--clampography-link": "63% 0.13 40",
42
+ "--clampography-muted": "44% 0.03 45",
43
+ "--clampography-primary": "60% 0.19 35",
44
+ "--clampography-secondary": "80% 0.14 85",
45
+ "--clampography-success": "62% 0.10 130",
46
+ "--clampography-surface": "87% 0.04 85",
47
+ "--clampography-text": "28% 0.03 40",
48
+ "--clampography-warning": "80% 0.14 85",
37
49
  },
38
50
  cyberpunk: {
39
51
  "color-scheme": "dark",
40
- "--clampography-background": "#000b1e",
41
- "--clampography-surface": "#051630",
42
- "--clampography-border": "#0f3661",
43
- "--clampography-heading": "#ffffff",
44
- "--clampography-text": "#00f0ff",
45
- "--clampography-muted": "#008f99",
46
- "--clampography-link": "#ff0099",
47
- "--clampography-primary": "#fcee0a",
48
- "--clampography-secondary": "#05ffa1",
52
+ "--clampography-background": "8% 0.04 264",
53
+ "--clampography-border": "27% 0.09 254",
54
+ "--clampography-error": "60% 0.29 340",
55
+ "--clampography-heading": "100% 0 0",
56
+ "--clampography-info": "88% 0.16 195",
57
+ "--clampography-link": "60% 0.29 340",
58
+ "--clampography-muted": "55% 0.07 200",
59
+ "--clampography-primary": "93% 0.22 105",
60
+ "--clampography-secondary": "87% 0.20 165",
61
+ "--clampography-success": "87% 0.20 165",
62
+ "--clampography-surface": "12% 0.05 264",
63
+ "--clampography-text": "88% 0.16 195",
64
+ "--clampography-warning": "93% 0.22 105",
49
65
  },
50
66
  };
51
67