demeter

Autonomous Hydroponic Intelligence

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}