demeter
Autonomous Hydroponic Intelligencegit clone https://github.com/maydayv7/demeter
frontend/src/index.css (8191B)
1@import url("https://fonts.googleapis.com/css2?family=Syne:wght@400;500;600;700;800&family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300&family=Instrument+Serif:ital@0;1&family=Noto+Sans+Devanagari:wght@400;500;600;700&display=swap");
2
3@tailwind base;
4@tailwind components;
5@tailwind utilities;
6
7/* Dark Theme */
8:root,
9[data-theme="dark"] {
10 --bg: #0c1a0e;
11 --bg-2: #111f13;
12 --bg-3: #162018;
13 --surface: #1a2b1c;
14 --surface-2: #1f3322;
15 --border: #2a3f2c;
16 --border-bright: #3d6040;
17 --text: #e8f0e9;
18 --text-2: #a8bfaa;
19 --text-3: #6a8a6d;
20 --green: #4ade80;
21 --green-dim: #2d7a44;
22 --amber: #f59e0b;
23 --amber-dim: #92400e;
24 --red: #f87171;
25 --red-dim: #7f1d1d;
26 --blue: #60a5fa;
27 --blue-dim: #1e3a5f;
28
29 /* Component tokens */
30 --input-bg: #162018;
31 --scrollbar-thumb: #3d6040;
32 --tooltip-bg: #1a2b1c;
33 --shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
34
35 /* Log / terminal area */
36 --log-bg: #080f09;
37 --log-text: #a8bfaa;
38
39 /* Hover backgrounds */
40 --hover-bg: rgba(255, 255, 255, 0.04);
41 --hover-bg-alt: rgba(74, 222, 128, 0.06);
42
43 /* Button text on green background */
44 --btn-on-green: #0c1a0e;
45}
46
47/* Light Theme */
48[data-theme="light"] {
49 --bg: #f0f7f1;
50 --bg-2: #ffffff;
51 --bg-3: #e8f2ea;
52 --surface: #ffffff;
53 --surface-2: #f4faf5;
54 --border: #c8deca;
55 --border-bright: #7db688;
56 --text: #1a2e1c;
57 --text-2: #3d5e42;
58 --text-3: #6a8a6d;
59 --green: #1a7c3a;
60 --green-dim: #c8e6d0;
61 --amber: #b45309;
62 --amber-dim: #fde68a;
63 --red: #dc2626;
64 --red-dim: #fecaca;
65 --blue: #1d4ed8;
66 --blue-dim: #bfdbfe;
67
68 --input-bg: #f4faf5;
69 --scrollbar-thumb: #7db688;
70 --tooltip-bg: #ffffff;
71 --shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
72
73 /* Log / terminal area - light but distinct */
74 --log-bg: #f0f5f1;
75 --log-text: #3d5e42;
76
77 /* Hover backgrounds */
78 --hover-bg: rgba(0, 0, 0, 0.04);
79 --hover-bg-alt: rgba(26, 124, 58, 0.06);
80
81 /* Button text on green background */
82 --btn-on-green: #ffffff;
83}
84
85/* Hindi font body override */
86[data-lang="hi"] body,
87[data-lang="hi"] button,
88[data-lang="hi"] input,
89[data-lang="hi"] select {
90 font-family: "Noto Sans Devanagari", "Syne", sans-serif;
91}
92
93/* Reset */
94* {
95 box-sizing: border-box;
96}
97
98body {
99 margin: 0;
100 background: var(--bg);
101 color: var(--text);
102 font-family: "Syne", sans-serif;
103 -webkit-font-smoothing: antialiased;
104 overflow-x: hidden;
105 transition:
106 background 0.25s ease,
107 color 0.25s ease;
108}
109
110/* Scrollbar */
111::-webkit-scrollbar {
112 width: 6px;
113 height: 6px;
114}
115::-webkit-scrollbar-track {
116 background: var(--bg-2);
117}
118::-webkit-scrollbar-thumb {
119 background: var(--scrollbar-thumb);
120 border-radius: 3px;
121}
122
123/* TYPOGRAPHY */
124.section-label {
125 font-size: 11px;
126 font-family: "DM Mono", monospace;
127 color: var(--text-3);
128 letter-spacing: 0.08em;
129 text-transform: uppercase;
130 display: flex;
131 align-items: center;
132 gap: 6px;
133 margin-bottom: 14px;
134}
135.section-label::before {
136 content: "//";
137 color: var(--green);
138 opacity: 0.6;
139 font-weight: 700;
140}
141
142.sensor-value {
143 font-size: 28px;
144 font-weight: 700;
145 font-family: "DM Mono", monospace;
146 line-height: 1;
147}
148.sensor-value-sm {
149 font-size: 20px;
150 font-weight: 700;
151 font-family: "DM Mono", monospace;
152 line-height: 1;
153}
154.sensor-value-xs {
155 font-size: 15px;
156 font-weight: 600;
157 font-family: "DM Mono", monospace;
158}
159.sensor-label {
160 font-size: 11px;
161 font-family: "DM Mono", monospace;
162 color: var(--text-3);
163 letter-spacing: 0.06em;
164 text-transform: uppercase;
165 margin-bottom: 4px;
166}
167.sensor-unit {
168 font-size: 13px;
169 font-weight: 400;
170 color: var(--text-3);
171 margin-left: 3px;
172}
173
174.page-title {
175 font-size: 20px;
176 font-weight: 700;
177 color: var(--text);
178 margin: 0;
179}
180.page-subtitle {
181 font-size: 12px;
182 font-family: "DM Mono", monospace;
183 color: var(--text-3);
184 margin: 2px 0 0;
185}
186
187/* Table */
188.data-table th {
189 font-size: 11px;
190 font-family: "DM Mono", monospace;
191 color: var(--text-3);
192 font-weight: 500;
193 letter-spacing: 0.05em;
194 text-transform: uppercase;
195 padding: 10px 20px;
196 text-align: left;
197 background: var(--bg-3);
198 border-bottom: 1px solid var(--border);
199}
200.data-table td {
201 padding: 11px 20px;
202 font-size: 13px;
203 border-bottom: 1px solid var(--border);
204 color: var(--text-2);
205}
206.data-table tr:last-child td {
207 border-bottom: none;
208}
209
210/* UTILITIES */
211.font-mono {
212 font-family: "DM Mono", monospace;
213}
214.font-serif {
215 font-family: "Instrument Serif", serif;
216}
217
218.glow-green {
219 box-shadow:
220 0 0 20px rgba(74, 222, 128, 0.15),
221 0 0 60px rgba(74, 222, 128, 0.05);
222}
223
224/* Scan line (dark only) */
225@keyframes scanline {
226 0% {
227 transform: translateY(-100%);
228 }
229 100% {
230 transform: translateY(100vh);
231 }
232}
233.scanline {
234 position: fixed;
235 top: 0;
236 left: 0;
237 right: 0;
238 height: 2px;
239 background: linear-gradient(
240 90deg,
241 transparent,
242 rgba(74, 222, 128, 0.1),
243 transparent
244 );
245 animation: scanline 8s linear infinite;
246 pointer-events: none;
247 z-index: 9999;
248}
249[data-theme="light"] .scanline {
250 display: none;
251}
252
253/* Animations */
254@keyframes fadeUp {
255 from {
256 opacity: 0;
257 transform: translateY(16px);
258 }
259 to {
260 opacity: 1;
261 transform: translateY(0);
262 }
263}
264@keyframes fadeIn {
265 from {
266 opacity: 0;
267 }
268 to {
269 opacity: 1;
270 }
271}
272@keyframes statusPulse {
273 0%,
274 100% {
275 opacity: 1;
276 transform: scale(1);
277 }
278 50% {
279 opacity: 0.5;
280 transform: scale(0.8);
281 }
282}
283@keyframes alertPulse {
284 0%,
285 100% {
286 box-shadow: 0 0 0 0 rgba(248, 113, 113, 0.4);
287 }
288 70% {
289 box-shadow: 0 0 0 8px rgba(248, 113, 113, 0);
290 }
291}
292@keyframes harvestPulse {
293 0%,
294 100% {
295 box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.35);
296 }
297 70% {
298 box-shadow: 0 0 0 10px rgba(245, 158, 11, 0);
299 }
300}
301@keyframes shimmer {
302 0% {
303 background-position: -200% 0;
304 }
305 100% {
306 background-position: 200% 0;
307 }
308}
309@keyframes progressFill {
310 from {
311 width: 0;
312 }
313}
314@keyframes blink {
315 0%,
316 100% {
317 opacity: 1;
318 }
319 50% {
320 opacity: 0;
321 }
322}
323
324@keyframes slideDownRight {
325 from {
326 opacity: 0;
327 transform: translate(-20px, -20px) scale(0.95);
328 }
329 to {
330 opacity: 1;
331 transform: translate(0, 0) scale(1);
332 }
333}
334@keyframes fadeScale {
335 from {
336 opacity: 0;
337 transform: scale(0.95);
338 }
339 to {
340 opacity: 1;
341 transform: scale(1);
342 }
343}
344
345.animate-fade-up {
346 animation: fadeUp 0.5s ease forwards;
347}
348.animate-fade-in {
349 animation: fadeIn 0.3s ease forwards;
350}
351.animate-slide-down-right {
352 animation: slideDownRight 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
353}
354.animate-fade-scale {
355 animation: fadeScale 0.7s cubic-bezier(0.16, 1, 0.3, 1) forwards;
356}
357.status-dot {
358 animation: statusPulse 2s ease-in-out infinite;
359}
360.alert-pulse {
361 animation: alertPulse 2s ease infinite;
362}
363.harvest-pulse {
364 animation: harvestPulse 2.5s ease infinite;
365}
366.progress-fill {
367 animation: progressFill 1s ease forwards;
368}
369.cursor-blink::after {
370 content: "|";
371 animation: blink 1s step-end infinite;
372 color: var(--green);
373}
374
375.shimmer {
376 background: linear-gradient(
377 90deg,
378 var(--surface) 25%,
379 var(--surface-2) 50%,
380 var(--surface) 75%
381 );
382 background-size: 200% 100%;
383 animation: shimmer 1.5s infinite;
384}
385
386.card-hover {
387 transition:
388 transform 0.2s ease,
389 box-shadow 0.2s ease,
390 border-color 0.2s ease;
391}
392.card-hover:hover {
393 transform: translateY(-2px);
394 border-color: var(--border-bright);
395 box-shadow: var(--shadow);
396}
397
398.grid-bg {
399 background-image:
400 linear-gradient(rgba(74, 222, 128, 0.03) 1px, transparent 1px),
401 linear-gradient(90deg, rgba(74, 222, 128, 0.03) 1px, transparent 1px);
402 background-size: 40px 40px;
403}
404[data-theme="light"] .grid-bg {
405 background-image:
406 linear-gradient(rgba(26, 124, 58, 0.05) 1px, transparent 1px),
407 linear-gradient(90deg, rgba(26, 124, 58, 0.05) 1px, transparent 1px);
408}
409
410/* Input fields */
411input,
412select,
413textarea {
414 background: var(--input-bg);
415 color: var(--text);
416 border-color: var(--border);
417 transition:
418 background 0.2s,
419 color 0.2s,
420 border-color 0.2s;
421}
422input::placeholder {
423 color: var(--text-3);
424}
425
426/* Harvest badge animation */
427.harvest-badge {
428 animation: harvestPulse 2.5s ease infinite;
429}
430
431/* Log / terminal area */
432.log-area {
433 background: var(--log-bg) !important;
434 color: var(--log-text);
435}