A Chrome extension to quickly capture URLs into Semble Collections at https://semble.so
semble.so
at-proto
semble
chrome-extension
1/**
2 * Semble Quick Capture - Styles
3 * Matches Semble's design system using Mantine-inspired styling
4 *
5 * @format
6 */
7
8/* ========== CSS Variables ========== */
9:root {
10 /* Semble Colors - Light Mode */
11 --tangerine-6: #ff6400;
12 --tangerine-7: #e45800;
13 --tangerine-8: #cb4d00;
14
15 --stone-0: #fafaf9;
16 --stone-1: #f5f5f4;
17 --stone-2: #e7e5e4;
18 --stone-3: #d6d3d1;
19 --stone-4: #a8a29e;
20 --stone-5: #78716c;
21 --stone-6: #57534e;
22 --stone-7: #44403c;
23 --stone-8: #292524;
24 --stone-9: #0c0a09;
25
26 /* Semantic Colors - Light Mode */
27 --bg-default: #ffffff;
28 --bg-subtle: var(--stone-0);
29 --bg-filled: var(--stone-1);
30 --text-primary: var(--stone-9);
31 --text-secondary: var(--stone-6);
32 --text-dimmed: var(--stone-5);
33 --border-default: var(--stone-2);
34 --border-subtle: var(--stone-1);
35
36 --primary-color: var(--tangerine-6);
37 --primary-hover: var(--tangerine-7);
38 --primary-active: var(--tangerine-8);
39
40 /* Filled button (dark) */
41 --filled-bg: var(--stone-8);
42 --filled-hover: var(--stone-7);
43 --filled-active: var(--stone-9);
44
45 /* Error colors */
46 --error-bg: #fef2f2;
47 --error-border: #fca5a5;
48 --error-text: #991b1b;
49
50 /* Success colors */
51 --success-bg: #f0fdf4;
52 --success-border: #86efac;
53 --success-text: #166534;
54
55 /* Spacing */
56 --spacing-xs: 0.625rem;
57 --spacing-sm: 0.75rem;
58 --spacing-md: 1rem;
59 --spacing-lg: 1.25rem;
60 --spacing-xl: 1.5rem;
61
62 /* Radius */
63 --radius-sm: 0.25rem;
64 --radius-md: 0.5rem;
65 --radius-lg: 0.75rem;
66 --radius-xl: 1rem;
67
68 /* Font sizes */
69 --font-size-xs: 0.75rem;
70 --font-size-sm: 0.875rem;
71 --font-size-md: 1rem;
72 --font-size-lg: 1.125rem;
73 --font-size-xl: 1.25rem;
74}
75
76/* Dark Mode */
77@media (prefers-color-scheme: dark) {
78 :root {
79 /* Background colors */
80 --bg-default: var(--stone-9);
81 --bg-subtle: var(--stone-8);
82 --bg-filled: var(--stone-7);
83
84 /* Text colors */
85 --text-primary: var(--stone-0);
86 --text-secondary: var(--stone-3);
87 --text-dimmed: var(--stone-4);
88
89 /* Border colors */
90 --border-default: var(--stone-7);
91 --border-subtle: var(--stone-8);
92
93 /* Filled button stays dark in dark mode */
94 --filled-bg: var(--stone-1);
95 --filled-hover: var(--stone-2);
96 --filled-active: var(--stone-0);
97
98 /* Error colors - dark mode */
99 --error-bg: #450a0a;
100 --error-border: #7f1d1d;
101 --error-text: #fca5a5;
102
103 /* Success colors - dark mode */
104 --success-bg: #052e16;
105 --success-border: #166534;
106 --success-text: #86efac;
107 }
108}
109
110/* ========== Base Styles ========== */
111* {
112 box-sizing: border-box;
113}
114
115body {
116 width: 360px;
117 min-height: 300px;
118 max-height: 600px;
119 margin: 0;
120 padding: 0;
121 font-family: 'Hanken Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI',
122 Roboto, 'Helvetica Neue', Arial, sans-serif;
123 font-size: var(--font-size-md);
124 color: var(--text-primary);
125 background-color: var(--bg-default);
126 overflow-y: auto;
127}
128
129:focus {
130 outline: 2px solid var(--primary-color);
131}
132
133/* ========== Layout Components ========== */
134.screen {
135 min-height: 300px;
136}
137
138.container {
139 padding: var(--spacing-xl);
140}
141
142.header {
143 display: flex;
144 justify-content: space-between;
145 align-items: center;
146 padding: var(--spacing-md) var(--spacing-lg);
147 background-color: var(--bg-default);
148 border-bottom: 1px solid var(--border-default);
149}
150
151.header-title {
152 font-size: var(--font-size-lg);
153 font-weight: 700;
154 margin: 0;
155 color: var(--text-primary);
156}
157
158/* ========== Typography ========== */
159.title {
160 font-size: var(--font-size-xl);
161 font-weight: 700;
162 margin: 0 0 var(--spacing-sm) 0;
163 color: var(--text-primary);
164}
165
166.subtitle {
167 font-size: var(--font-size-sm);
168 color: var(--text-secondary);
169 margin: 0 0 var(--spacing-lg) 0;
170}
171
172.loading-text {
173 font-size: var(--font-size-sm);
174 color: var(--text-secondary);
175 margin-top: var(--spacing-md);
176}
177
178/* ========== Form Components ========== */
179.form-stack {
180 display: flex;
181 flex-direction: column;
182 gap: var(--spacing-lg);
183}
184
185.form-group {
186 display: flex;
187 flex-direction: column;
188 gap: var(--spacing-xs);
189}
190
191.form-label {
192 font-size: var(--font-size-sm);
193 font-weight: 600;
194 color: var(--text-primary);
195}
196
197.form-hint {
198 font-size: var(--font-size-sm);
199 color: var(--text-dimmed);
200 margin: 0;
201 line-height: 1.4;
202}
203
204.form-link {
205 color: var(--primary-color);
206 text-decoration: none;
207 font-weight: 500;
208 transition: color 150ms ease;
209}
210
211.form-link:hover {
212 color: var(--primary-hover);
213 text-decoration: underline;
214}
215
216/* Filled Input Variant (Mantine style) */
217.input-filled {
218 width: 100%;
219 padding: calc(var(--spacing-md) - 2px) var(--spacing-md);
220 font-size: var(--font-size-md);
221 font-family: inherit;
222 color: var(--text-primary);
223 background-color: var(--bg-filled);
224 border: 2px solid transparent;
225 border-radius: var(--radius-md);
226 transition: all 150ms ease;
227}
228
229.input-filled::placeholder {
230 color: var(--text-dimmed);
231}
232
233.input-filled:hover {
234 background-color: var(--bg-subtle);
235}
236
237/* .input-filled:focus {
238 outline: 1px solid;
239 out-
240 background-color: var(--bg-default);
241 border-color: var(--primary-color);
242} */
243
244.input-filled:disabled {
245 opacity: 0.6;
246 cursor: not-allowed;
247}
248
249/* Textarea specific */
250textarea.input-filled {
251 resize: vertical;
252 min-height: 80px;
253 font-family: inherit;
254}
255
256/* Select specific */
257select.input-filled {
258 cursor: pointer;
259 appearance: none;
260 background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 6l4 4 4-4" stroke="%2378716c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>');
261 background-repeat: no-repeat;
262 background-position: right var(--spacing-md) center;
263 padding-right: calc(var(--spacing-md) * 2.5);
264}
265
266@media (prefers-color-scheme: dark) {
267 select.input-filled {
268 background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M4 6l4 4 4-4" stroke="%23d6d3d1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>');
269 }
270}
271
272/* ========== Buttons ========== */
273.btn {
274 width: 100%;
275 padding: var(--spacing-md) var(--spacing-lg);
276 font-size: var(--font-size-md);
277 font-weight: 600;
278 font-family: inherit;
279 border: none;
280 border-radius: var(--radius-xl);
281 cursor: pointer;
282 transition: all 150ms ease;
283 display: flex;
284 align-items: center;
285 justify-content: center;
286 gap: var(--spacing-sm);
287}
288
289.btn-primary {
290 background-color: var(--primary-color);
291 color: white;
292}
293
294.btn-primary:hover:not(:disabled) {
295 background-color: var(--primary-hover);
296}
297
298.btn-primary:active:not(:disabled) {
299 background-color: var(--primary-active);
300 transform: translateY(1px);
301}
302
303.btn-primary:disabled {
304 opacity: 0.4;
305 cursor: not-allowed;
306}
307
308.btn-link {
309 background: none;
310 border: none;
311 padding: var(--spacing-xs) var(--spacing-sm);
312 font-size: var(--font-size-sm);
313 font-weight: 500;
314 font-family: inherit;
315 color: var(--text-secondary);
316 cursor: pointer;
317 border-radius: var(--radius-md);
318 transition: all 150ms ease;
319}
320
321.btn-link:hover {
322 color: var(--text-primary);
323 background-color: var(--bg-subtle);
324}
325
326/* ========== URL Display ========== */
327.url-display {
328 padding: var(--spacing-md);
329 font-size: var(--font-size-sm);
330 color: var(--text-secondary);
331 background-color: var(--bg-filled);
332 border: 1px solid var(--border-default);
333 border-radius: var(--radius-md);
334 word-break: break-all;
335 max-height: 100px;
336 overflow-y: auto;
337}
338
339/* ========== Alerts ========== */
340.alert {
341 padding: var(--spacing-md);
342 border-radius: var(--radius-md);
343 font-size: var(--font-size-sm);
344 border: 1px solid;
345}
346
347.alert-error {
348 background-color: var(--error-bg);
349 border-color: var(--error-border);
350 color: var(--error-text);
351}
352
353.alert-success {
354 background-color: var(--success-bg);
355 border-color: var(--success-border);
356 color: var(--success-text);
357}
358
359.alert-loading {
360 background-color: var(--bg-filled);
361 border-color: var(--border-default);
362 color: var(--text-secondary);
363}
364
365/* ========== Loading Spinner ========== */
366.loading-container {
367 display: flex;
368 flex-direction: column;
369 align-items: center;
370 justify-content: center;
371 min-height: 300px;
372}
373
374.spinner {
375 width: 32px;
376 height: 32px;
377 border: 3px solid var(--border-default);
378 border-top-color: var(--primary-color);
379 border-radius: 50%;
380 animation: spin 0.8s linear infinite;
381}
382
383@keyframes spin {
384 to {
385 transform: rotate(360deg);
386 }
387}
388
389/* ========== Utility Classes ========== */
390.hidden {
391 display: none !important;
392}