@howssatoshi/quantumcss 1.0.2 → 1.1.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/README.md +17 -13
- package/dist/quantum.min.css +1 -1
- package/package.json +1 -1
- package/src/defaults.js +33 -164
- package/src/generator.js +141 -132
- package/src/styles/quantum-components.css +60 -28
- package/src/styles/quantum.css +19 -7
- package/src/styles/starlight-ui.css +252 -60
package/src/generator.js
CHANGED
|
@@ -3,181 +3,190 @@ const path = require('path');
|
|
|
3
3
|
const { glob } = require('glob');
|
|
4
4
|
const { defaultTheme, utilityMaps } = require('./defaults');
|
|
5
5
|
|
|
6
|
-
const breakpoints = {
|
|
7
|
-
sm: '640px',
|
|
8
|
-
md: '768px',
|
|
9
|
-
lg: '1024px',
|
|
10
|
-
xl: '1280px',
|
|
11
|
-
};
|
|
6
|
+
const breakpoints = { sm: '640px', md: '768px', lg: '1024px', xl: '1280px', '2xl': '1536px' };
|
|
12
7
|
|
|
13
8
|
function generateCSS(configPath) {
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
const resolvedPath = path.resolve(configPath);
|
|
10
|
+
if (fs.existsSync(resolvedPath)) delete require.cache[resolvedPath];
|
|
11
|
+
const config = fs.existsSync(resolvedPath) ? require(resolvedPath) : { content: [], theme: {} };
|
|
16
12
|
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
13
|
+
const theme = JSON.parse(JSON.stringify(defaultTheme || {}));
|
|
14
|
+
theme.colors = theme.colors || {};
|
|
15
|
+
theme.spacing = theme.spacing || {};
|
|
16
|
+
theme.borderRadius = theme.borderRadius || {};
|
|
17
|
+
theme.fontSize = theme.fontSize || {};
|
|
18
|
+
|
|
19
|
+
if (config.theme && config.theme.extend) {
|
|
20
|
+
const ext = config.theme.extend;
|
|
21
|
+
if (ext.colors) Object.assign(theme.colors, ext.colors);
|
|
22
|
+
if (ext.spacing) Object.assign(theme.spacing, ext.spacing);
|
|
23
|
+
if (ext.borderRadius) Object.assign(theme.borderRadius, ext.borderRadius);
|
|
24
|
+
if (ext.fontSize) Object.assign(theme.fontSize, ext.fontSize);
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
const flattenedColors = {};
|
|
31
28
|
Object.entries(theme.colors).forEach(([name, value]) => {
|
|
32
|
-
if (typeof value === 'string')
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
flattenedColors[`${name}-${shade}`] = hex;
|
|
37
|
-
});
|
|
29
|
+
if (typeof value === 'string') flattenedColors[name] = value;
|
|
30
|
+
else {
|
|
31
|
+
Object.entries(value || {}).forEach(([shade, hex]) => { flattenedColors[`${name}-${shade}`] = hex; });
|
|
32
|
+
if (value && value['500']) flattenedColors[name] = value['500'];
|
|
38
33
|
}
|
|
39
34
|
});
|
|
40
35
|
|
|
41
|
-
|
|
36
|
+
function resolveColor(key) {
|
|
37
|
+
if (!key) return null;
|
|
38
|
+
if (flattenedColors[key]) return flattenedColors[key];
|
|
39
|
+
if (key.includes('/')) {
|
|
40
|
+
const [base, opacity] = key.split('/');
|
|
41
|
+
const color = flattenedColors[base] || flattenedColors[`${base}-500`];
|
|
42
|
+
if (color && color.startsWith('#')) {
|
|
43
|
+
const r = parseInt(color.slice(1, 3), 16), g = parseInt(color.slice(3, 5), 16), b = parseInt(color.slice(5, 7), 16);
|
|
44
|
+
return `rgba(${r}, ${g}, ${b}, ${parseInt(opacity) / 100})`;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const files = (config.content || []).flatMap(p => glob.sync(p));
|
|
42
51
|
const rawClasses = new Set();
|
|
52
|
+
const classAttrRegex = /class="([^"]+)"/g;
|
|
43
53
|
|
|
44
54
|
files.forEach(file => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
55
|
+
try {
|
|
56
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
57
|
+
let match;
|
|
58
|
+
while ((match = classAttrRegex.exec(content)) !== null) {
|
|
59
|
+
match[1].split(/\s+/).forEach(cls => { if (cls) rawClasses.add(cls); });
|
|
60
|
+
}
|
|
61
|
+
} catch (e) {}
|
|
50
62
|
});
|
|
51
63
|
|
|
52
|
-
let css = '/* Quantum CSS - High Performance Output */\n';
|
|
53
|
-
css += '*, ::before, ::after { box-sizing: border-box; border-width: 0; border-style: solid; border-color: #e5e7eb; }\n';
|
|
54
|
-
css += 'html { line-height: 1.5; -webkit-text-size-adjust: 100%; font-family: Inter, ui-sans-serif, system-ui, sans-serif; }\n';
|
|
55
|
-
css += 'body { margin: 0; line-height: inherit; }\n';
|
|
56
|
-
css += 'img { display: block; max-width: 100%; height: auto; }\n';
|
|
57
|
-
css += 'button { cursor: pointer; background: transparent; padding: 0; color: inherit; font: inherit; }\n\n';
|
|
58
|
-
|
|
59
64
|
const utilities = new Set();
|
|
60
|
-
const responsiveUtils = { sm: new Set(), md: new Set(), lg: new Set(), xl: new Set() };
|
|
65
|
+
const responsiveUtils = { sm: new Set(), md: new Set(), lg: new Set(), xl: new Set(), '2xl': new Set() };
|
|
66
|
+
|
|
67
|
+
const sideMap = {
|
|
68
|
+
p: 'padding', pt: 'padding-top', pr: 'padding-right', pb: 'padding-bottom', pl: 'padding-left',
|
|
69
|
+
px: ['padding-left', 'padding-right'], py: ['padding-top', 'padding-bottom'],
|
|
70
|
+
m: 'margin', mt: 'margin-top', mr: 'margin-right', mb: 'margin-bottom', ml: 'margin-left',
|
|
71
|
+
mx: ['margin-left', 'margin-right'], my: ['margin-top', 'margin-bottom'],
|
|
72
|
+
w: 'width', h: 'height', top: 'top', right: 'right', bottom: 'bottom', left: 'left',
|
|
73
|
+
'max-w': 'max-width', 'max-h': 'max-height', 'min-w': 'min-width', 'min-h': 'min-height',
|
|
74
|
+
gap: 'gap', 'gap-x': 'column-gap', 'gap-y': 'row-gap'
|
|
75
|
+
};
|
|
61
76
|
|
|
62
77
|
function processClass(fullCls) {
|
|
63
|
-
let cls = fullCls;
|
|
64
|
-
|
|
65
|
-
let breakpoint = null;
|
|
66
|
-
|
|
78
|
+
let cls = fullCls, variant = null, breakpoint = null, isNeg = false;
|
|
79
|
+
if (cls.startsWith('-')) { isNeg = true; cls = cls.substring(1); }
|
|
67
80
|
const parts = cls.split(':');
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
variant = subParts[0];
|
|
76
|
-
cls = subParts[1];
|
|
77
|
-
} else if (!breakpoint) {
|
|
78
|
-
variant = parts[0];
|
|
79
|
-
cls = parts[1];
|
|
80
|
-
}
|
|
81
|
+
let currentPart = 0;
|
|
82
|
+
while (currentPart < parts.length) {
|
|
83
|
+
const p = parts[currentPart];
|
|
84
|
+
if (breakpoints[p]) { breakpoint = p; }
|
|
85
|
+
else if (['hover', 'focus', 'placeholder', 'group-hover'].includes(p)) { variant = p; }
|
|
86
|
+
else { cls = parts.slice(currentPart).join(':'); break; }
|
|
87
|
+
currentPart++;
|
|
81
88
|
}
|
|
82
89
|
|
|
83
|
-
let property = null;
|
|
84
|
-
let value = null;
|
|
85
|
-
|
|
90
|
+
let property = null, value = null, customSelector = null;
|
|
86
91
|
if (utilityMaps[cls]) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
} else {
|
|
91
|
-
property = utilityMaps[cls];
|
|
92
|
-
}
|
|
92
|
+
const entry = utilityMaps[cls];
|
|
93
|
+
if (typeof entry === 'object' && !Array.isArray(entry)) { property = entry.property; value = entry.value; }
|
|
94
|
+
else { property = entry; }
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
if (!property || !value) {
|
|
96
98
|
const cParts = cls.split('-');
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
let prefix = cParts[0], valKey = cParts.slice(1).join('-');
|
|
100
|
+
|
|
101
|
+
if ((prefix === 'max' || prefix === 'min' || prefix === 'gap' || prefix === 'gap-x' || prefix === 'gap-y') && cParts[1]) {
|
|
102
|
+
if (['w', 'h', 'x', 'y'].includes(cParts[1])) {
|
|
103
|
+
prefix = `${cParts[0]}-${cParts[1]}`;
|
|
104
|
+
valKey = cParts.slice(2).join('-');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
99
107
|
|
|
100
108
|
if (prefix === 'text') {
|
|
101
|
-
if (theme.fontSize[valKey]) { property = 'font-size'; value = theme.fontSize[valKey]; }
|
|
102
|
-
else
|
|
103
|
-
} else if (prefix === 'bg') {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
property = '
|
|
109
|
+
if (theme.fontSize[valKey]) { property = ['font-size', 'line-height']; value = [theme.fontSize[valKey], (valKey.includes('xl') || parseInt(valKey) >= 3) ? '1.2' : '1.5']; }
|
|
110
|
+
else { const color = resolveColor(valKey); if (color) { property = 'color'; value = color; } }
|
|
111
|
+
} else if (prefix === 'bg') { const color = resolveColor(valKey); if (color) { property = 'background-color'; value = color; } }
|
|
112
|
+
else if (prefix === 'z') { property = 'z-index'; value = isNeg ? `-${valKey}` : valKey; }
|
|
113
|
+
else if (prefix === 'aspect') {
|
|
114
|
+
property = ['aspect-ratio', 'width', 'height'];
|
|
115
|
+
let ratio = 'auto';
|
|
116
|
+
if (valKey.startsWith('[') && valKey.endsWith(']')) ratio = valKey.slice(1, -1).replace(/\//g, ' / ');
|
|
117
|
+
else if (valKey === 'video') ratio = '16 / 9';
|
|
118
|
+
else if (valKey === 'square') ratio = '1 / 1';
|
|
119
|
+
else ratio = valKey.replace(/\//g, ' / ');
|
|
120
|
+
value = [ratio, '100%', 'auto'];
|
|
121
|
+
} else if (prefix === 'grid' && cParts[1] === 'cols') {
|
|
122
|
+
property = 'grid-template-columns'; value = `repeat(${cParts[2]}, minmax(0, 1fr))`;
|
|
123
|
+
} else if (prefix === 'col' && cParts[1] === 'span') {
|
|
124
|
+
property = 'grid-column'; value = `span ${cParts[2]} / span ${cParts[2]}`;
|
|
125
|
+
} else if (prefix === 'space') {
|
|
126
|
+
const amount = theme.spacing[cParts[2]] || `${parseInt(cParts[2]) * 0.25}rem`;
|
|
127
|
+
const escaped = fullCls.replace(/([:[\/])/g, '\\$1');
|
|
128
|
+
customSelector = `.${escaped} > * + *`;
|
|
129
|
+
property = cParts[1] === 'y' ? 'margin-top' : 'margin-left';
|
|
130
|
+
value = isNeg ? `-${amount}` : amount;
|
|
107
131
|
} else if (prefix === 'rounded') {
|
|
108
132
|
property = 'border-radius';
|
|
109
|
-
if (valKey
|
|
110
|
-
else if (valKey
|
|
111
|
-
else
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
property = 'border-color'; value = flattenedColors[valKey];
|
|
115
|
-
} else if (cParts[1] === 'l' || cParts[1] === 'r' || cParts[1] === 't' || cParts[1] === 'b') {
|
|
116
|
-
const sideMap = { l: 'left', r: 'right', t: 'top', b: 'bottom' };
|
|
117
|
-
property = `border-${sideMap[cParts[1]]}-width`;
|
|
118
|
-
value = `${cParts[2]}px`;
|
|
119
|
-
}
|
|
120
|
-
} else if (prefix === 'gap') {
|
|
121
|
-
property = 'gap'; value = theme.spacing[valKey] || (valKey ? (isNaN(valKey) ? valKey : `${valKey}rem`) : '0px');
|
|
122
|
-
} else if (prefix === 'grid' && cParts[1] === 'cols') {
|
|
123
|
-
property = 'grid-template-columns';
|
|
124
|
-
value = `repeat(${cParts[2]}, minmax(0, 1fr))`;
|
|
125
|
-
} else if (prefix === 'flex' && cParts[1] === 'row') {
|
|
126
|
-
property = 'flex-direction';
|
|
127
|
-
value = 'row';
|
|
128
|
-
} else if (prefix === 'w' || prefix === 'h') {
|
|
129
|
-
property = utilityMaps[prefix];
|
|
130
|
-
if (valKey.includes('/')) {
|
|
131
|
-
const [n, d] = valKey.split('/');
|
|
132
|
-
value = `${(parseInt(n)/parseInt(d)*100).toFixed(2)}%`;
|
|
133
|
-
} else {
|
|
134
|
-
value = theme.spacing[valKey] || valKey;
|
|
135
|
-
}
|
|
136
|
-
} else if (utilityMaps[prefix]) {
|
|
137
|
-
const mapEntry = utilityMaps[prefix];
|
|
138
|
-
if (typeof mapEntry === 'object' && !Array.isArray(mapEntry)) {
|
|
139
|
-
property = mapEntry.property;
|
|
140
|
-
value = mapEntry.value;
|
|
141
|
-
} else {
|
|
142
|
-
property = mapEntry;
|
|
143
|
-
value = theme.spacing[valKey] || valKey;
|
|
133
|
+
if (valKey.startsWith('[') && valKey.endsWith(']')) value = valKey.slice(1, -1);
|
|
134
|
+
else if (theme.borderRadius[valKey]) value = theme.borderRadius[valKey];
|
|
135
|
+
else {
|
|
136
|
+
const num = parseInt(valKey);
|
|
137
|
+
value = isNaN(num) ? '0.375rem' : `${num * 0.125}rem`;
|
|
144
138
|
}
|
|
139
|
+
} else if (prefix === 'scale') {
|
|
140
|
+
property = 'transform';
|
|
141
|
+
value = `scale(${parseInt(valKey) / 100})`;
|
|
142
|
+
} else if (prefix === 'transition') {
|
|
143
|
+
property = 'transition-property';
|
|
144
|
+
if (valKey === 'all') value = 'all';
|
|
145
|
+
else if (valKey === 'colors') value = 'color, background-color, border-color, text-decoration-color, fill, stroke';
|
|
146
|
+
else if (valKey === 'transform') value = 'transform';
|
|
147
|
+
else value = valKey;
|
|
148
|
+
} else if (prefix === 'duration') {
|
|
149
|
+
property = 'transition-duration';
|
|
150
|
+
value = `${valKey}ms`;
|
|
151
|
+
} else if (sideMap[prefix]) {
|
|
152
|
+
property = sideMap[prefix];
|
|
153
|
+
let v = valKey;
|
|
154
|
+
if (v.startsWith('[') && v.endsWith(']')) v = v.slice(1, -1);
|
|
155
|
+
else if (v.includes('/')) v = `${(parseInt(v.split('/')[0])/parseInt(v.split('/')[1])*100).toFixed(2)}%`;
|
|
156
|
+
else v = theme.spacing[v] || v;
|
|
157
|
+
value = isNeg ? (Array.isArray(v) ? v.map(x => `-${x}`) : `-${v}`) : v;
|
|
158
|
+
} else if (prefix === 'border') {
|
|
159
|
+
const color = resolveColor(valKey);
|
|
160
|
+
if (color) { property = 'border-color'; value = color; }
|
|
161
|
+
else if (['l', 'r', 't', 'b'].includes(cParts[1])) {
|
|
162
|
+
const sideMapSide = { l: 'left', r: 'right', t: 'top', b: 'bottom' };
|
|
163
|
+
property = `border-${sideMapSide[cParts[1]]}-width`;
|
|
164
|
+
value = `${cParts[2]}px`;
|
|
165
|
+
} else if (!isNaN(parseInt(valKey))) { property = 'border-width'; value = `${parseInt(valKey)}px`; }
|
|
145
166
|
}
|
|
146
167
|
}
|
|
147
168
|
|
|
148
169
|
if (property && value) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
let rules = ''
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
} else {
|
|
160
|
-
rules = ` ${property}: ${value};`;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const cssBlock = `${selector} {\n${rules}\n}\n`;
|
|
164
|
-
if (breakpoint) { responsiveUtils[breakpoint].add(cssBlock); }
|
|
165
|
-
else { utilities.add(cssBlock); }
|
|
170
|
+
const escapedFull = fullCls.replace(/([:[\/])/g, '\\$1');
|
|
171
|
+
let selector = customSelector || `.${escapedFull}`;
|
|
172
|
+
if (variant) { if (variant === 'group-hover') selector = `.group:hover ${selector}`; else selector += `:${variant}`}
|
|
173
|
+
let rules = Array.isArray(property) ? property.map((p, i) => ` ${p}: ${Array.isArray(value) ? value[i] : value};`).join('\n') : ` ${property}: ${value};`;
|
|
174
|
+
const block = `${selector} {
|
|
175
|
+
${rules}
|
|
176
|
+
}
|
|
177
|
+
`;
|
|
178
|
+
if (breakpoint) responsiveUtils[breakpoint].add(block); else utilities.add(block);
|
|
166
179
|
}
|
|
167
180
|
}
|
|
168
181
|
|
|
169
182
|
rawClasses.forEach(processClass);
|
|
170
|
-
|
|
171
|
-
css += Array.from(utilities).join('\n');
|
|
183
|
+
let css = '/* Quantum CSS JIT Output */\n' + Array.from(utilities).join('\n');
|
|
172
184
|
Object.entries(breakpoints).forEach(([name, width]) => {
|
|
173
185
|
if (responsiveUtils[name].size > 0) {
|
|
174
|
-
css += `\n@media (min-width: ${width}) {\n`;
|
|
175
|
-
css += Array.from(responsiveUtils[name]).map(u => ' ' + u.replace(/\n/g, '\n ')).join('\n').trimEnd();
|
|
176
|
-
css += '\n}\n';
|
|
186
|
+
css += `\n@media (min-width: ${width}) {\n${Array.from(responsiveUtils[name]).map(u => ' ' + u.replace(/\n/g, '\n ')).join('\n').trimEnd()}\n}\n`;
|
|
177
187
|
}
|
|
178
188
|
});
|
|
179
|
-
|
|
180
189
|
return css;
|
|
181
190
|
}
|
|
182
191
|
|
|
183
|
-
module.exports = { generateCSS };
|
|
192
|
+
module.exports = { generateCSS };
|
|
@@ -189,12 +189,41 @@
|
|
|
189
189
|
transition: all var(--duration-150) var(--ease-in-out);
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
textarea.input {
|
|
193
|
+
min-height: 100px;
|
|
194
|
+
}
|
|
195
|
+
|
|
192
196
|
.input:focus {
|
|
193
197
|
outline: none;
|
|
194
198
|
border-color: var(--color-primary);
|
|
195
199
|
box-shadow: 0 0 0 3px var(--color-primary);
|
|
196
200
|
}
|
|
197
201
|
|
|
202
|
+
/* Date & Time Input Specifics */
|
|
203
|
+
input[type="date"].input,
|
|
204
|
+
input[type="datetime-local"].input,
|
|
205
|
+
input[type="time"].input {
|
|
206
|
+
appearance: none;
|
|
207
|
+
-webkit-appearance: none;
|
|
208
|
+
min-height: 2.5rem;
|
|
209
|
+
display: inline-flex;
|
|
210
|
+
align-items: center;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/* Ensure dark-mode calendar picker */
|
|
214
|
+
.glass input[type="date"],
|
|
215
|
+
.starlight-card input[type="date"],
|
|
216
|
+
[class*="dark"] input[type="date"] {
|
|
217
|
+
color-scheme: dark;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* Fix for alignment in flex containers */
|
|
221
|
+
input[type="date"]::-webkit-calendar-picker-indicator {
|
|
222
|
+
cursor: pointer;
|
|
223
|
+
filter: invert(0.5);
|
|
224
|
+
margin-left: 0.5rem;
|
|
225
|
+
}
|
|
226
|
+
|
|
198
227
|
.input:disabled {
|
|
199
228
|
background-color: #f3f4f6;
|
|
200
229
|
color: #6b7280;
|
|
@@ -214,37 +243,45 @@
|
|
|
214
243
|
.badge {
|
|
215
244
|
display: inline-flex;
|
|
216
245
|
align-items: center;
|
|
217
|
-
padding:
|
|
218
|
-
border-radius:
|
|
246
|
+
padding: 0.25rem 0.75rem;
|
|
247
|
+
border-radius: 0.375rem;
|
|
219
248
|
font-size: 0.75rem;
|
|
220
|
-
font-weight:
|
|
249
|
+
font-weight: 600;
|
|
221
250
|
text-transform: uppercase;
|
|
222
251
|
letter-spacing: 0.05em;
|
|
252
|
+
border: 1px solid;
|
|
253
|
+
backdrop-filter: blur(4px);
|
|
254
|
+
-webkit-backdrop-filter: blur(4px);
|
|
223
255
|
}
|
|
224
256
|
|
|
225
257
|
.badge-primary {
|
|
226
|
-
background-color:
|
|
227
|
-
color:
|
|
258
|
+
background-color: rgba(0, 212, 255, 0.15);
|
|
259
|
+
color: #00d4ff;
|
|
260
|
+
border-color: rgba(0, 212, 255, 0.3);
|
|
228
261
|
}
|
|
229
262
|
|
|
230
263
|
.badge-secondary {
|
|
231
|
-
background-color:
|
|
232
|
-
color:
|
|
264
|
+
background-color: rgba(255, 255, 255, 0.05);
|
|
265
|
+
color: rgba(255, 255, 255, 0.8);
|
|
266
|
+
border-color: rgba(255, 255, 255, 0.1);
|
|
233
267
|
}
|
|
234
268
|
|
|
235
269
|
.badge-success {
|
|
236
|
-
background-color:
|
|
237
|
-
color: #
|
|
270
|
+
background-color: rgba(16, 185, 129, 0.15);
|
|
271
|
+
color: #10b981;
|
|
272
|
+
border-color: rgba(16, 185, 129, 0.3);
|
|
238
273
|
}
|
|
239
274
|
|
|
240
275
|
.badge-warning {
|
|
241
|
-
background-color:
|
|
242
|
-
color: #
|
|
276
|
+
background-color: rgba(245, 158, 11, 0.15);
|
|
277
|
+
color: #f59e0b;
|
|
278
|
+
border-color: rgba(245, 158, 11, 0.3);
|
|
243
279
|
}
|
|
244
280
|
|
|
245
281
|
.badge-error {
|
|
246
|
-
background-color:
|
|
247
|
-
color: #
|
|
282
|
+
background-color: rgba(239, 68, 68, 0.15);
|
|
283
|
+
color: #ef4444;
|
|
284
|
+
border-color: rgba(239, 68, 68, 0.3);
|
|
248
285
|
}
|
|
249
286
|
|
|
250
287
|
/* Alert Component */
|
|
@@ -303,8 +340,8 @@
|
|
|
303
340
|
display: inline-block;
|
|
304
341
|
width: 1.5rem;
|
|
305
342
|
height: 1.5rem;
|
|
306
|
-
border: 2px solid
|
|
307
|
-
border-top-color:
|
|
343
|
+
border: 2px solid rgba(255, 255, 255, 0.1);
|
|
344
|
+
border-top-color: var(--color-primary);
|
|
308
345
|
border-radius: 50%;
|
|
309
346
|
animation: spin 1s linear infinite;
|
|
310
347
|
}
|
|
@@ -313,29 +350,24 @@
|
|
|
313
350
|
to { transform: rotate(360deg); }
|
|
314
351
|
}
|
|
315
352
|
|
|
316
|
-
.spinner-sm {
|
|
317
|
-
width: 1rem;
|
|
318
|
-
height: 1rem;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
.spinner-lg {
|
|
322
|
-
width: 2rem;
|
|
323
|
-
height: 2rem;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
353
|
/* Skeleton Loading */
|
|
327
354
|
.skeleton {
|
|
328
|
-
background: linear-gradient(90deg,
|
|
355
|
+
background: linear-gradient(90deg, rgba(255,255,255,0.05) 25%, rgba(255,255,255,0.1) 50%, rgba(255,255,255,0.05) 75%);
|
|
329
356
|
background-size: 200% 100%;
|
|
330
|
-
animation:
|
|
357
|
+
animation: shimmer 2s infinite;
|
|
331
358
|
border-radius: var(--radius-md);
|
|
332
359
|
}
|
|
333
360
|
|
|
334
|
-
@keyframes
|
|
361
|
+
@keyframes shimmer {
|
|
335
362
|
0% { background-position: 200% 0; }
|
|
336
363
|
100% { background-position: -200% 0; }
|
|
337
364
|
}
|
|
338
365
|
|
|
366
|
+
body.light-mode .skeleton {
|
|
367
|
+
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
|
368
|
+
background-size: 200% 100%;
|
|
369
|
+
}
|
|
370
|
+
|
|
339
371
|
/* Tooltip Component */
|
|
340
372
|
.tooltip {
|
|
341
373
|
position: relative;
|
package/src/styles/quantum.css
CHANGED
|
@@ -140,6 +140,18 @@ body {
|
|
|
140
140
|
line-height: inherit;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
input, textarea, select, button {
|
|
144
|
+
font-family: inherit;
|
|
145
|
+
font-size: inherit;
|
|
146
|
+
line-height: inherit;
|
|
147
|
+
color: inherit;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
textarea {
|
|
151
|
+
resize: vertical;
|
|
152
|
+
min-height: 5rem;
|
|
153
|
+
}
|
|
154
|
+
|
|
143
155
|
/* Layout Utilities */
|
|
144
156
|
.container {
|
|
145
157
|
width: 100%;
|
|
@@ -262,7 +274,7 @@ body {
|
|
|
262
274
|
.text-2xl { font-size: 1.5rem; line-height: 2rem; }
|
|
263
275
|
.text-3xl { font-size: 1.875rem; line-height: 2.25rem; }
|
|
264
276
|
.text-4xl { font-size: 2.25rem; line-height: 2.5rem; }
|
|
265
|
-
.text-5xl { font-size: 3rem; line-height: 1; }
|
|
277
|
+
.text-5xl { font-size: 3rem; line-height: 1.2; }
|
|
266
278
|
|
|
267
279
|
.font-light { font-weight: 300; }
|
|
268
280
|
.font-normal { font-weight: 400; }
|
|
@@ -844,19 +856,19 @@ body {
|
|
|
844
856
|
}
|
|
845
857
|
|
|
846
858
|
/* Utility for Quick Prototyping */
|
|
847
|
-
.
|
|
859
|
+
.prose {
|
|
848
860
|
max-width: 65ch;
|
|
849
861
|
line-height: 1.75;
|
|
850
862
|
}
|
|
851
863
|
|
|
852
|
-
.
|
|
864
|
+
.prose h1 {
|
|
853
865
|
font-size: 2.25rem;
|
|
854
866
|
font-weight: 700;
|
|
855
867
|
line-height: 1.25;
|
|
856
868
|
margin-bottom: 1rem;
|
|
857
869
|
}
|
|
858
870
|
|
|
859
|
-
.
|
|
871
|
+
.prose h2 {
|
|
860
872
|
font-size: 1.875rem;
|
|
861
873
|
font-weight: 600;
|
|
862
874
|
line-height: 1.25;
|
|
@@ -864,16 +876,16 @@ body {
|
|
|
864
876
|
margin-bottom: 1rem;
|
|
865
877
|
}
|
|
866
878
|
|
|
867
|
-
.
|
|
879
|
+
.prose p {
|
|
868
880
|
margin-bottom: 1rem;
|
|
869
881
|
}
|
|
870
882
|
|
|
871
|
-
.
|
|
883
|
+
.prose a {
|
|
872
884
|
color: var(--color-primary);
|
|
873
885
|
text-decoration: underline;
|
|
874
886
|
}
|
|
875
887
|
|
|
876
|
-
.
|
|
888
|
+
.prose a:hover {
|
|
877
889
|
color: var(--color-primary-600);
|
|
878
890
|
}
|
|
879
891
|
|