chaiwind 2.1.1 → 3.0.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/CHANGELOG.md +145 -0
- package/README.md +392 -108
- package/package.json +12 -14
- package/src/engine.js +144 -0
- package/src/handlers.js +218 -0
- package/src/index.js +20 -0
- package/src/tokens.js +141 -0
- package/chaiwind.js +0 -383
- package/demo/demo.html +0 -104
package/src/engine.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* engine.js
|
|
3
|
+
* The core of chaiwind — 3 responsibilities:
|
|
4
|
+
*
|
|
5
|
+
* 1. parseClass(cls) — breaks 'chai-bg-piyush' into { utility, value }
|
|
6
|
+
* 2. applyClass(el, cls) — applies inline style + removes the class
|
|
7
|
+
* 3. init() — scans DOM on load + watches live with MutationObserver
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { handlers } from "./handlers.js";
|
|
11
|
+
|
|
12
|
+
// ─── 1. PARSER ────────────────────────────────────────────────────────────────
|
|
13
|
+
// Input: 'chai-bg-piyush-dark'
|
|
14
|
+
// Output: { utility: 'bg', value: 'piyush-dark' }
|
|
15
|
+
//
|
|
16
|
+
// Steps:
|
|
17
|
+
// - slice(5) removes the 'chai-' prefix → 'bg-piyush-dark'
|
|
18
|
+
// - indexOf('-') finds the first dash → index 2
|
|
19
|
+
// - slice(0, 2) gets the utility → 'bg'
|
|
20
|
+
// - slice(3) gets the value → 'piyush-dark'
|
|
21
|
+
//
|
|
22
|
+
// Edge case: 'chai-flex' has no value
|
|
23
|
+
// - indexOf('-') returns -1
|
|
24
|
+
// - utility = 'flex', value = ''
|
|
25
|
+
|
|
26
|
+
function parseClass(cls) {
|
|
27
|
+
const raw = cls.slice(5); // strip 'chai-'
|
|
28
|
+
const dashIdx = raw.indexOf("-"); // find first dash
|
|
29
|
+
|
|
30
|
+
const utility = dashIdx === -1 ? raw : raw.slice(0, dashIdx);
|
|
31
|
+
const value = dashIdx === -1 ? "" : raw.slice(dashIdx + 1);
|
|
32
|
+
|
|
33
|
+
return { utility, value };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ─── 2. APPLY CLASS ───────────────────────────────────────────────────────────
|
|
37
|
+
// Takes one element and one class name
|
|
38
|
+
// Looks up the handler, calls it, removes the class
|
|
39
|
+
|
|
40
|
+
function applyClass(el, cls) {
|
|
41
|
+
const { utility, value } = parseClass(cls);
|
|
42
|
+
|
|
43
|
+
// look up the handler for this utility
|
|
44
|
+
const handler = handlers[utility];
|
|
45
|
+
|
|
46
|
+
if (handler) {
|
|
47
|
+
handler(el, value); // e.g. handlers['bg'](el, 'piyush')
|
|
48
|
+
}
|
|
49
|
+
// unknown utility — silently skip, just remove the class
|
|
50
|
+
|
|
51
|
+
// requirement: always remove chai- class after processing
|
|
52
|
+
el.classList.remove(cls);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ─── 3. PROCESS ELEMENT ───────────────────────────────────────────────────────
|
|
56
|
+
// Takes one element, finds all chai- classes on it, applies each one
|
|
57
|
+
// We snapshot classList into an Array first — important!
|
|
58
|
+
// Because we're removing classes inside the loop,
|
|
59
|
+
// iterating el.classList live would skip some classes
|
|
60
|
+
|
|
61
|
+
function processElement(el) {
|
|
62
|
+
// only process actual HTML elements, skip text nodes / comment nodes
|
|
63
|
+
if (el.nodeType !== 1) return;
|
|
64
|
+
|
|
65
|
+
// snapshot into array so removals don't affect iteration
|
|
66
|
+
const classes = Array.from(el.classList);
|
|
67
|
+
|
|
68
|
+
classes.forEach((cls) => {
|
|
69
|
+
if (cls.startsWith("chai-")) {
|
|
70
|
+
applyClass(el, cls);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ─── 4. SCAN ──────────────────────────────────────────────────────────────────
|
|
76
|
+
// Runs once — traverses the entire DOM
|
|
77
|
+
// Finds every element that has at least one chai- class
|
|
78
|
+
|
|
79
|
+
function scan() {
|
|
80
|
+
// querySelectorAll('[class]') — grabs every element that has a class attribute
|
|
81
|
+
// this is faster than grabbing ALL elements and checking each one
|
|
82
|
+
const elements = document.querySelectorAll("[class]");
|
|
83
|
+
elements.forEach((el) => processElement(el));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ─── 5. MUTATIONOBSERVER ──────────────────────────────────────────────────────
|
|
87
|
+
// Watches the DOM live — any element added after page load also gets processed
|
|
88
|
+
// This handles: JS frameworks, dynamic content, setTimeout additions etc.
|
|
89
|
+
//
|
|
90
|
+
// mutation.addedNodes = list of nodes added in this mutation
|
|
91
|
+
// We process each added node + all its children (querySelectorAll inside it)
|
|
92
|
+
|
|
93
|
+
function watch() {
|
|
94
|
+
const observer = new MutationObserver((mutations) => {
|
|
95
|
+
for (const mutation of mutations) {
|
|
96
|
+
for (const node of mutation.addedNodes) {
|
|
97
|
+
// skip text nodes, comment nodes — only process elements
|
|
98
|
+
if (node.nodeType !== 1) continue;
|
|
99
|
+
|
|
100
|
+
// process the element itself
|
|
101
|
+
processElement(node);
|
|
102
|
+
|
|
103
|
+
// process any children inside it too
|
|
104
|
+
// e.g. a whole section added at once — scan everything inside
|
|
105
|
+
node
|
|
106
|
+
.querySelectorAll("[class]")
|
|
107
|
+
.forEach((child) => processElement(child));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// observe the entire document body
|
|
113
|
+
// childList: true → watch for elements being added or removed
|
|
114
|
+
// subtree: true → watch ALL descendants, not just direct children
|
|
115
|
+
observer.observe(document.body, {
|
|
116
|
+
childList: true,
|
|
117
|
+
subtree: true,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ─── 6. INIT ──────────────────────────────────────────────────────────────────
|
|
122
|
+
// Called from index.js
|
|
123
|
+
// Handles two cases:
|
|
124
|
+
// - script in <head> → HTML not parsed yet → wait for DOMContentLoaded
|
|
125
|
+
// - script at <body> → HTML already parsed → run immediately
|
|
126
|
+
|
|
127
|
+
export function init() {
|
|
128
|
+
if (document.readyState === "loading") {
|
|
129
|
+
// DOM not ready yet — wait
|
|
130
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
131
|
+
scan();
|
|
132
|
+
watch();
|
|
133
|
+
});
|
|
134
|
+
} else {
|
|
135
|
+
// DOM already ready — run now
|
|
136
|
+
scan();
|
|
137
|
+
watch();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
console.log(
|
|
141
|
+
"%c☕ chaiwind ready",
|
|
142
|
+
"color: #c8843a; font-weight: bold; font-size: 13px;",
|
|
143
|
+
);
|
|
144
|
+
}
|
package/src/handlers.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* handlers.js
|
|
3
|
+
* Maps every chai-* utility to a function that sets el.style directly
|
|
4
|
+
*
|
|
5
|
+
* Structure:
|
|
6
|
+
* 'utility': (el, value) => el.style.someProperty = resolvedValue
|
|
7
|
+
*
|
|
8
|
+
* How it's used in engine.js:
|
|
9
|
+
* handlers['bg'](el, 'piyush') → el.style.backgroundColor = '#ec4899'
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { colors, spacing, fontSizes, radii, shadows } from "./tokens.js";
|
|
13
|
+
|
|
14
|
+
export const handlers = {
|
|
15
|
+
// ── padding ───────────────────────────────────────────────────────────────
|
|
16
|
+
p: (el, v) => (el.style.padding = spacing[v] || v + "px"),
|
|
17
|
+
px: (el, v) => {
|
|
18
|
+
el.style.paddingLeft = spacing[v] || v + "px";
|
|
19
|
+
el.style.paddingRight = spacing[v] || v + "px";
|
|
20
|
+
},
|
|
21
|
+
py: (el, v) => {
|
|
22
|
+
el.style.paddingTop = spacing[v] || v + "px";
|
|
23
|
+
el.style.paddingBottom = spacing[v] || v + "px";
|
|
24
|
+
},
|
|
25
|
+
pt: (el, v) => (el.style.paddingTop = spacing[v] || v + "px"),
|
|
26
|
+
pb: (el, v) => (el.style.paddingBottom = spacing[v] || v + "px"),
|
|
27
|
+
pl: (el, v) => (el.style.paddingLeft = spacing[v] || v + "px"),
|
|
28
|
+
pr: (el, v) => (el.style.paddingRight = spacing[v] || v + "px"),
|
|
29
|
+
|
|
30
|
+
// ── margin ────────────────────────────────────────────────────────────────
|
|
31
|
+
m: (el, v) => (el.style.margin = spacing[v] || v + "px"),
|
|
32
|
+
mx: (el, v) => {
|
|
33
|
+
el.style.marginLeft = spacing[v] || v + "px";
|
|
34
|
+
el.style.marginRight = spacing[v] || v + "px";
|
|
35
|
+
},
|
|
36
|
+
my: (el, v) => {
|
|
37
|
+
el.style.marginTop = spacing[v] || v + "px";
|
|
38
|
+
el.style.marginBottom = spacing[v] || v + "px";
|
|
39
|
+
},
|
|
40
|
+
mt: (el, v) => (el.style.marginTop = spacing[v] || v + "px"),
|
|
41
|
+
mb: (el, v) => (el.style.marginBottom = spacing[v] || v + "px"),
|
|
42
|
+
ml: (el, v) => (el.style.marginLeft = spacing[v] || v + "px"),
|
|
43
|
+
mr: (el, v) => (el.style.marginRight = spacing[v] || v + "px"),
|
|
44
|
+
|
|
45
|
+
// ── gap ───────────────────────────────────────────────────────────────────
|
|
46
|
+
gap: (el, v) => (el.style.gap = spacing[v] || v + "px"),
|
|
47
|
+
|
|
48
|
+
// ── colors ────────────────────────────────────────────────────────────────
|
|
49
|
+
// chai-bg-chai, chai-bg-red, chai-bg-#ff0000
|
|
50
|
+
bg: (el, v) => (el.style.backgroundColor = colors[v] || v),
|
|
51
|
+
border: (el, v) => {
|
|
52
|
+
// chai-border → just adds a solid border
|
|
53
|
+
// chai-border-chai → solid border with chai color
|
|
54
|
+
if (!v) {
|
|
55
|
+
el.style.border = "1px solid currentColor";
|
|
56
|
+
} else {
|
|
57
|
+
el.style.border = "1px solid " + (colors[v] || v);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
// ── text — handles 3 things: color, size, alignment ──────────────────────
|
|
62
|
+
// chai-text-chai → color
|
|
63
|
+
// chai-text-xl → font size
|
|
64
|
+
// chai-text-center → text align
|
|
65
|
+
text: (el, v) => {
|
|
66
|
+
if (colors[v]) el.style.color = colors[v];
|
|
67
|
+
else if (fontSizes[v]) el.style.fontSize = fontSizes[v];
|
|
68
|
+
else el.style.textAlign = v;
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
// ── font ──────────────────────────────────────────────────────────────────
|
|
72
|
+
font: (el, v) => {
|
|
73
|
+
const weightMap = {
|
|
74
|
+
thin: "100",
|
|
75
|
+
light: "300",
|
|
76
|
+
normal: "400",
|
|
77
|
+
medium: "500",
|
|
78
|
+
semibold: "600",
|
|
79
|
+
bold: "700",
|
|
80
|
+
black: "900",
|
|
81
|
+
};
|
|
82
|
+
if (weightMap[v]) el.style.fontWeight = weightMap[v];
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
// ── border radius ─────────────────────────────────────────────────────────
|
|
86
|
+
// chai-rounded-md, chai-rounded-full, chai-rounded-20 (raw px)
|
|
87
|
+
rounded: (el, v) => (el.style.borderRadius = radii[v] || v + "px"),
|
|
88
|
+
|
|
89
|
+
// ── shadow ────────────────────────────────────────────────────────────────
|
|
90
|
+
shadow: (el, v) => (el.style.boxShadow = shadows[v] || v),
|
|
91
|
+
|
|
92
|
+
// ── opacity ───────────────────────────────────────────────────────────────
|
|
93
|
+
// chai-opacity-50 → 0.5
|
|
94
|
+
opacity: (el, v) => (el.style.opacity = String(Number(v) / 100)),
|
|
95
|
+
|
|
96
|
+
// ── sizing ────────────────────────────────────────────────────────────────
|
|
97
|
+
w: (el, v) => {
|
|
98
|
+
if (v === "full") el.style.width = "100%";
|
|
99
|
+
else if (v === "screen") el.style.width = "100vw";
|
|
100
|
+
else if (v === "auto") el.style.width = "auto";
|
|
101
|
+
else el.style.width = spacing[v] || v + "px";
|
|
102
|
+
},
|
|
103
|
+
h: (el, v) => {
|
|
104
|
+
if (v === "full") el.style.height = "100%";
|
|
105
|
+
else if (v === "screen") el.style.height = "100vh";
|
|
106
|
+
else if (v === "auto") el.style.height = "auto";
|
|
107
|
+
else el.style.height = spacing[v] || v + "px";
|
|
108
|
+
},
|
|
109
|
+
"max-w": (el, v) => (el.style.maxWidth = spacing[v] || v + "px"),
|
|
110
|
+
"min-h": (el, v) =>
|
|
111
|
+
(el.style.minHeight = v === "screen" ? "100vh" : spacing[v] || v + "px"),
|
|
112
|
+
"min-w": (el, v) =>
|
|
113
|
+
(el.style.minWidth = v === "full" ? "100%" : spacing[v] || v + "px"),
|
|
114
|
+
|
|
115
|
+
// ── display ───────────────────────────────────────────────────────────────
|
|
116
|
+
flex: (el) => (el.style.display = "flex"),
|
|
117
|
+
grid: (el) => (el.style.display = "grid"),
|
|
118
|
+
block: (el) => (el.style.display = "block"),
|
|
119
|
+
"inline-block": (el) => (el.style.display = "inline-block"),
|
|
120
|
+
inline: (el) => (el.style.display = "inline"),
|
|
121
|
+
hidden: (el) => (el.style.display = "none"),
|
|
122
|
+
|
|
123
|
+
// ── flexbox ───────────────────────────────────────────────────────────────
|
|
124
|
+
"flex-col": (el) => (el.style.flexDirection = "column"),
|
|
125
|
+
"flex-row": (el) => (el.style.flexDirection = "row"),
|
|
126
|
+
"flex-wrap": (el) => (el.style.flexWrap = "wrap"),
|
|
127
|
+
"flex-1": (el) => (el.style.flex = "1"),
|
|
128
|
+
items: (el, v) => {
|
|
129
|
+
const map = {
|
|
130
|
+
center: "center",
|
|
131
|
+
start: "flex-start",
|
|
132
|
+
end: "flex-end",
|
|
133
|
+
stretch: "stretch",
|
|
134
|
+
};
|
|
135
|
+
el.style.alignItems = map[v] || v;
|
|
136
|
+
},
|
|
137
|
+
justify: (el, v) => {
|
|
138
|
+
const map = {
|
|
139
|
+
center: "center",
|
|
140
|
+
start: "flex-start",
|
|
141
|
+
end: "flex-end",
|
|
142
|
+
between: "space-between",
|
|
143
|
+
around: "space-around",
|
|
144
|
+
evenly: "space-evenly",
|
|
145
|
+
};
|
|
146
|
+
el.style.justifyContent = map[v] || v;
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
// ── grid ──────────────────────────────────────────────────────────────────
|
|
150
|
+
"grid-cols": (el, v) => (el.style.gridTemplateColumns = `repeat(${v}, 1fr)`),
|
|
151
|
+
"col-span": (el, v) => (el.style.gridColumn = `span ${v}`),
|
|
152
|
+
|
|
153
|
+
// ── position ──────────────────────────────────────────────────────────────
|
|
154
|
+
relative: (el) => (el.style.position = "relative"),
|
|
155
|
+
absolute: (el) => (el.style.position = "absolute"),
|
|
156
|
+
fixed: (el) => (el.style.position = "fixed"),
|
|
157
|
+
sticky: (el) => {
|
|
158
|
+
el.style.position = "sticky";
|
|
159
|
+
el.style.top = "0";
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
// ── overflow ──────────────────────────────────────────────────────────────
|
|
163
|
+
overflow: (el, v) => (el.style.overflow = v || "hidden"),
|
|
164
|
+
"overflow-x": (el, v) => (el.style.overflowX = v || "auto"),
|
|
165
|
+
"overflow-y": (el, v) => (el.style.overflowY = v || "auto"),
|
|
166
|
+
|
|
167
|
+
// ── z-index ───────────────────────────────────────────────────────────────
|
|
168
|
+
z: (el, v) => (el.style.zIndex = v),
|
|
169
|
+
|
|
170
|
+
// ── typography ────────────────────────────────────────────────────────────
|
|
171
|
+
uppercase: (el) => (el.style.textTransform = "uppercase"),
|
|
172
|
+
lowercase: (el) => (el.style.textTransform = "lowercase"),
|
|
173
|
+
capitalize: (el) => (el.style.textTransform = "capitalize"),
|
|
174
|
+
italic: (el) => (el.style.fontStyle = "italic"),
|
|
175
|
+
underline: (el) => (el.style.textDecoration = "underline"),
|
|
176
|
+
"line-through": (el) => (el.style.textDecoration = "line-through"),
|
|
177
|
+
"no-underline": (el) => (el.style.textDecoration = "none"),
|
|
178
|
+
truncate: (el) => {
|
|
179
|
+
el.style.overflow = "hidden";
|
|
180
|
+
el.style.textOverflow = "ellipsis";
|
|
181
|
+
el.style.whiteSpace = "nowrap";
|
|
182
|
+
},
|
|
183
|
+
leading: (el, v) => {
|
|
184
|
+
const map = {
|
|
185
|
+
none: "1",
|
|
186
|
+
tight: "1.25",
|
|
187
|
+
snug: "1.375",
|
|
188
|
+
normal: "1.5",
|
|
189
|
+
relaxed: "1.625",
|
|
190
|
+
loose: "2",
|
|
191
|
+
};
|
|
192
|
+
el.style.lineHeight = map[v] || v;
|
|
193
|
+
},
|
|
194
|
+
tracking: (el, v) => {
|
|
195
|
+
const map = {
|
|
196
|
+
tight: "-0.05em",
|
|
197
|
+
normal: "0",
|
|
198
|
+
wide: "0.05em",
|
|
199
|
+
wider: "0.1em",
|
|
200
|
+
widest: "0.2em",
|
|
201
|
+
};
|
|
202
|
+
el.style.letterSpacing = map[v] || v;
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
// ── cursor ────────────────────────────────────────────────────────────────
|
|
206
|
+
cursor: (el, v) => (el.style.cursor = v),
|
|
207
|
+
|
|
208
|
+
// ── misc ──────────────────────────────────────────────────────────────────
|
|
209
|
+
transition: (el, v) =>
|
|
210
|
+
(el.style.transition = v === "none" ? "none" : "all 150ms ease"),
|
|
211
|
+
"select-none": (el) => (el.style.userSelect = "none"),
|
|
212
|
+
"object-cover": (el) => (el.style.objectFit = "cover"),
|
|
213
|
+
"object-contain": (el) => (el.style.objectFit = "contain"),
|
|
214
|
+
"mx-auto": (el) => {
|
|
215
|
+
el.style.marginLeft = "auto";
|
|
216
|
+
el.style.marginRight = "auto";
|
|
217
|
+
},
|
|
218
|
+
};
|
package/src/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* index.js
|
|
3
|
+
* Entry point for chaiwind
|
|
4
|
+
*
|
|
5
|
+
* Usage with a bundler (Vite, webpack):
|
|
6
|
+
* import { initChai } from 'chaiwind'
|
|
7
|
+
* initChai()
|
|
8
|
+
*
|
|
9
|
+
* Usage in plain HTML:
|
|
10
|
+
* <script type="module">
|
|
11
|
+
* import { initChai } from './node_modules/chaiwind/src/index.js'
|
|
12
|
+
* initChai()
|
|
13
|
+
* </script>
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { init } from "./engine.js";
|
|
17
|
+
|
|
18
|
+
export function initChai() {
|
|
19
|
+
init();
|
|
20
|
+
}
|
package/src/tokens.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hitesh sir — chai, adrak, masala, kulhad, tapri, dudh
|
|
3
|
+
* Piyush sir — piyush, rose, blush, fuschia, lipstick
|
|
4
|
+
* Akash sir — midnight, spacegray, silver, starlight, macos-*
|
|
5
|
+
* ChaiCode — chaicode, chaicode-dark
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const colors = {
|
|
9
|
+
// ── ChaiCode brand ────────────────────────────────────────────────────────
|
|
10
|
+
chaicode: "#f97316",
|
|
11
|
+
"chaicode-dark": "#1a1a2e",
|
|
12
|
+
|
|
13
|
+
// ── ☕ Hitesh sir — chai palette ──────────────────────────────────────────
|
|
14
|
+
chai: "#c8843a", // classic cutting chai
|
|
15
|
+
adrak: "#d4a056", // ginger gold
|
|
16
|
+
masala: "#8b4513", // deep masala brown
|
|
17
|
+
kulhad: "#b5651d", // clay kulhad
|
|
18
|
+
tapri: "#6b3a2a", // dark roasted tapri
|
|
19
|
+
dudh: "#f5f0e8", // milk chai cream
|
|
20
|
+
|
|
21
|
+
// ── 🍵 Tea Collection ─────────────────────────────────────────────────────
|
|
22
|
+
"green-tea": "#7fbf7f",
|
|
23
|
+
"chamomile-tea": "#f5e6a6",
|
|
24
|
+
"black-tea": "#3b2f2f",
|
|
25
|
+
"herbal-tea": "#a3c585",
|
|
26
|
+
"matcha-tea": "#6ea64d",
|
|
27
|
+
"white-tea": "#f2f2f2",
|
|
28
|
+
"masala-chai": "#c68642",
|
|
29
|
+
"darjeeling-tea": "#d4a373",
|
|
30
|
+
"irani-chai": "#b08968",
|
|
31
|
+
"oolong-tea": "#a47148",
|
|
32
|
+
"lemongrass-tea": "#c9e4a7",
|
|
33
|
+
"tandoori-chai": "#b7410e",
|
|
34
|
+
"chai-tea": "#8b5e3c",
|
|
35
|
+
"peach-tea": "#ffb07c",
|
|
36
|
+
"mate-tea": "#6b8e23",
|
|
37
|
+
"rooibos-tea": "#b22222",
|
|
38
|
+
"nilgiri-tea": "#5c4033",
|
|
39
|
+
"dark-tea": "#1c1c1c",
|
|
40
|
+
|
|
41
|
+
// ── 🩷 Piyush sir — pink palette ──────────────────────────────────────────
|
|
42
|
+
piyush: "#ec4899", // signature hot pink
|
|
43
|
+
"piyush-light": "#f9a8d4", // soft blush
|
|
44
|
+
"piyush-dark": "#be185d", // deep magenta
|
|
45
|
+
rose: "#fb7185", // rose
|
|
46
|
+
blush: "#fce7f3", // barely-there blush
|
|
47
|
+
fuschia: "#d946ef", // electric fuschia
|
|
48
|
+
lipstick: "#c2185b", // bold lipstick
|
|
49
|
+
|
|
50
|
+
// ── 🍎 Akash sir — Apple / Mac palette ────────────────────────────────────
|
|
51
|
+
midnight: "#1d1d1f", // Apple midnight black
|
|
52
|
+
spacegray: "#86868b", // Mac space gray
|
|
53
|
+
silver: "#e8e8ed", // Mac silver
|
|
54
|
+
starlight: "#f5f1eb", // MacBook starlight
|
|
55
|
+
"macos-blue": "#0071e3", // Apple blue
|
|
56
|
+
"macos-green": "#34c759", // Apple green
|
|
57
|
+
"macos-red": "#ff3b30", // Apple red
|
|
58
|
+
aluminum: "#d1d1d6", // aluminum body
|
|
59
|
+
|
|
60
|
+
// ── general colors ────────────────────────────────────────────────────────
|
|
61
|
+
white: "#ffffff",
|
|
62
|
+
black: "#000000",
|
|
63
|
+
transparent: "transparent",
|
|
64
|
+
red: "#ef4444",
|
|
65
|
+
orange: "#f97316",
|
|
66
|
+
yellow: "#eab308",
|
|
67
|
+
green: "#22c55e",
|
|
68
|
+
blue: "#3b82f6",
|
|
69
|
+
purple: "#a855f7",
|
|
70
|
+
pink: "#ec4899",
|
|
71
|
+
teal: "#14b8a6",
|
|
72
|
+
indigo: "#6366f1",
|
|
73
|
+
gray: "#6b7280",
|
|
74
|
+
|
|
75
|
+
// ── gray scale ────────────────────────────────────────────────────────────
|
|
76
|
+
"gray-50": "#f9fafb",
|
|
77
|
+
"gray-100": "#f3f4f6",
|
|
78
|
+
"gray-200": "#e5e7eb",
|
|
79
|
+
"gray-300": "#d1d5db",
|
|
80
|
+
"gray-400": "#9ca3af",
|
|
81
|
+
"gray-500": "#6b7280",
|
|
82
|
+
"gray-600": "#4b5563",
|
|
83
|
+
"gray-700": "#374151",
|
|
84
|
+
"gray-800": "#1f2937",
|
|
85
|
+
"gray-900": "#111827",
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const spacing = {
|
|
89
|
+
0: "0px",
|
|
90
|
+
1: "4px",
|
|
91
|
+
2: "8px",
|
|
92
|
+
3: "12px",
|
|
93
|
+
4: "16px",
|
|
94
|
+
5: "20px",
|
|
95
|
+
6: "24px",
|
|
96
|
+
7: "28px",
|
|
97
|
+
8: "32px",
|
|
98
|
+
9: "36px",
|
|
99
|
+
10: "40px",
|
|
100
|
+
12: "48px",
|
|
101
|
+
14: "56px",
|
|
102
|
+
16: "64px",
|
|
103
|
+
20: "80px",
|
|
104
|
+
24: "96px",
|
|
105
|
+
32: "128px",
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
export const fontSizes = {
|
|
109
|
+
xs: "11px",
|
|
110
|
+
sm: "13px",
|
|
111
|
+
base: "16px",
|
|
112
|
+
lg: "18px",
|
|
113
|
+
xl: "20px",
|
|
114
|
+
"2xl": "24px",
|
|
115
|
+
"3xl": "30px",
|
|
116
|
+
"4xl": "36px",
|
|
117
|
+
"5xl": "48px",
|
|
118
|
+
"6xl": "64px",
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const radii = {
|
|
122
|
+
none: "0px",
|
|
123
|
+
sm: "4px",
|
|
124
|
+
md: "8px",
|
|
125
|
+
lg: "12px",
|
|
126
|
+
xl: "16px",
|
|
127
|
+
"2xl": "24px",
|
|
128
|
+
full: "9999px",
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export const shadows = {
|
|
132
|
+
sm: "0 1px 3px rgba(0,0,0,0.10)",
|
|
133
|
+
md: "0 4px 12px rgba(0,0,0,0.12)",
|
|
134
|
+
lg: "0 8px 24px rgba(0,0,0,0.15)",
|
|
135
|
+
xl: "0 16px 48px rgba(0,0,0,0.20)",
|
|
136
|
+
none: "none",
|
|
137
|
+
// ChaiCode special shadows
|
|
138
|
+
chai: "0 4px 20px rgba(200,132,58,0.35)",
|
|
139
|
+
piyush: "0 4px 20px rgba(236,72,153,0.30)",
|
|
140
|
+
mac: "0 8px 32px rgba(29,29,31,0.25)",
|
|
141
|
+
};
|