RoyAalekh commited on
Commit
e72be16
Β·
1 Parent(s): e60c2f9

Implement unified modern design system

Browse files

✨ Features:
- Created comprehensive design system with sophisticated color palette
- Green-focused brand colors for forest/nature theme
- Unified typography with Inter and Playfair Display fonts
- Consistent glassmorphism effects and modern UI patterns

🎨 Design Updates:
- All pages now use consistent forest gradient headers
- Modernized login page with elegant glassmorphism container
- Enhanced form page with improved GPS button styling
- Updated map page with animated wave header effects
- Added emoji icons for better visual hierarchy

πŸ“± Mobile Improvements:
- Fixed GPS button color consistency in mobile mode
- Enhanced touch-friendly interactions
- Improved responsive layouts across all pages
- Better button sizing and spacing on mobile devices

πŸ”§ Technical:
- Centralized CSS design system in design-system.css
- CSS custom properties for consistent theming
- Improved accessibility with focus states
- Optimized animations and transitions

The UI now has a cohesive, modern, and elegant appearance while maintaining
the minimal aesthetic with sophisticated design touches.

Files changed (4) hide show
  1. static/css/design-system.css +787 -0
  2. static/index.html +39 -225
  3. static/login.html +93 -175
  4. static/map.html +70 -137
static/css/design-system.css ADDED
@@ -0,0 +1,787 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* TreeTrack Design System v2.0 */
2
+ /* Modern, minimal, and elegant design system for TreeTrack */
3
+
4
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=Playfair+Display:wght@400;500;600;700&display=swap');
5
+
6
+ :root {
7
+ /* Primary Brand Colors - Sophisticated green palette */
8
+ --primary-50: #f0fdf5;
9
+ --primary-100: #dcfce8;
10
+ --primary-200: #bbf7d1;
11
+ --primary-300: #86efac;
12
+ --primary-400: #4ade80;
13
+ --primary-500: #22c55e;
14
+ --primary-600: #16a34a;
15
+ --primary-700: #15803d;
16
+ --primary-800: #166534;
17
+ --primary-900: #14532d;
18
+
19
+ /* Secondary Brand Colors - Elegant blue accent */
20
+ --secondary-50: #eff6ff;
21
+ --secondary-100: #dbeafe;
22
+ --secondary-200: #bfdbfe;
23
+ --secondary-300: #93c5fd;
24
+ --secondary-400: #60a5fa;
25
+ --secondary-500: #3b82f6;
26
+ --secondary-600: #2563eb;
27
+ --secondary-700: #1d4ed8;
28
+ --secondary-800: #1e40af;
29
+ --secondary-900: #1e3a8a;
30
+
31
+ /* Neutral Colors - Sophisticated grayscale */
32
+ --gray-50: #fafafa;
33
+ --gray-100: #f5f5f5;
34
+ --gray-200: #e5e5e5;
35
+ --gray-300: #d4d4d4;
36
+ --gray-400: #a3a3a3;
37
+ --gray-500: #737373;
38
+ --gray-600: #525252;
39
+ --gray-700: #404040;
40
+ --gray-800: #262626;
41
+ --gray-900: #171717;
42
+ --gray-950: #0a0a0a;
43
+
44
+ /* Status Colors */
45
+ --success-50: #f0fdf4;
46
+ --success-500: #22c55e;
47
+ --success-600: #16a34a;
48
+ --success-700: #15803d;
49
+
50
+ --warning-50: #fffbeb;
51
+ --warning-500: #f59e0b;
52
+ --warning-600: #d97706;
53
+ --warning-700: #b45309;
54
+
55
+ --error-50: #fef2f2;
56
+ --error-500: #ef4444;
57
+ --error-600: #dc2626;
58
+ --error-700: #b91c1c;
59
+
60
+ --info-50: #eff6ff;
61
+ --info-500: #3b82f6;
62
+ --info-600: #2563eb;
63
+ --info-700: #1d4ed8;
64
+
65
+ /* Spacing Scale */
66
+ --space-px: 1px;
67
+ --space-0: 0;
68
+ --space-1: 0.25rem;
69
+ --space-2: 0.5rem;
70
+ --space-3: 0.75rem;
71
+ --space-4: 1rem;
72
+ --space-5: 1.25rem;
73
+ --space-6: 1.5rem;
74
+ --space-7: 1.75rem;
75
+ --space-8: 2rem;
76
+ --space-10: 2.5rem;
77
+ --space-12: 3rem;
78
+ --space-16: 4rem;
79
+ --space-20: 5rem;
80
+ --space-24: 6rem;
81
+ --space-32: 8rem;
82
+
83
+ /* Typography Scale */
84
+ --text-xs: 0.75rem; /* 12px */
85
+ --text-sm: 0.875rem; /* 14px */
86
+ --text-base: 1rem; /* 16px */
87
+ --text-lg: 1.125rem; /* 18px */
88
+ --text-xl: 1.25rem; /* 20px */
89
+ --text-2xl: 1.5rem; /* 24px */
90
+ --text-3xl: 1.875rem; /* 30px */
91
+ --text-4xl: 2.25rem; /* 36px */
92
+ --text-5xl: 3rem; /* 48px */
93
+ --text-6xl: 3.75rem; /* 60px */
94
+
95
+ /* Line Heights */
96
+ --leading-none: 1;
97
+ --leading-tight: 1.25;
98
+ --leading-snug: 1.375;
99
+ --leading-normal: 1.5;
100
+ --leading-relaxed: 1.625;
101
+ --leading-loose: 2;
102
+
103
+ /* Font Weights */
104
+ --font-light: 300;
105
+ --font-normal: 400;
106
+ --font-medium: 500;
107
+ --font-semibold: 600;
108
+ --font-bold: 700;
109
+ --font-extrabold: 800;
110
+
111
+ /* Border Radius */
112
+ --radius-none: 0;
113
+ --radius-sm: 0.25rem;
114
+ --radius-md: 0.375rem;
115
+ --radius-lg: 0.5rem;
116
+ --radius-xl: 0.75rem;
117
+ --radius-2xl: 1rem;
118
+ --radius-3xl: 1.5rem;
119
+ --radius-full: 9999px;
120
+
121
+ /* Shadows */
122
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
123
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
124
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
125
+ --shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
126
+ --shadow-2xl: 0 25px 50px -12px rgb(0 0 0 / 0.25);
127
+ --shadow-inner: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
128
+
129
+ /* Glassmorphism Effects */
130
+ --glass-bg: rgba(255, 255, 255, 0.85);
131
+ --glass-bg-dark: rgba(255, 255, 255, 0.1);
132
+ --glass-blur: blur(12px);
133
+ --glass-border: 1px solid rgba(255, 255, 255, 0.2);
134
+
135
+ /* Gradients */
136
+ --gradient-primary: linear-gradient(135deg, var(--primary-600) 0%, var(--primary-700) 50%, var(--primary-800) 100%);
137
+ --gradient-secondary: linear-gradient(135deg, var(--secondary-600) 0%, var(--secondary-700) 50%, var(--secondary-800) 100%);
138
+ --gradient-forest: linear-gradient(135deg, #134e4a 0%, #14532d 25%, #166534 50%, #15803d 75%, #16a34a 100%);
139
+ --gradient-sky: linear-gradient(135deg, #0c4a6e 0%, #1e40af 25%, #2563eb 50%, #3b82f6 75%, #60a5fa 100%);
140
+ --gradient-sunset: linear-gradient(135deg, #7c2d12 0%, #dc2626 25%, #f59e0b 50%, #fbbf24 75%, #fde047 100%);
141
+
142
+ /* Transitions */
143
+ --transition-fast: 0.15s ease;
144
+ --transition-normal: 0.2s ease;
145
+ --transition-slow: 0.3s ease;
146
+ --transition-bounce: 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
147
+
148
+ /* Z-Index Scale */
149
+ --z-dropdown: 1000;
150
+ --z-sticky: 1020;
151
+ --z-fixed: 1030;
152
+ --z-modal-backdrop: 1040;
153
+ --z-modal: 1050;
154
+ --z-popover: 1060;
155
+ --z-tooltip: 1070;
156
+ --z-toast: 1080;
157
+ }
158
+
159
+ /* Base Styles */
160
+ * {
161
+ margin: 0;
162
+ padding: 0;
163
+ box-sizing: border-box;
164
+ }
165
+
166
+ ::selection {
167
+ background: var(--primary-500);
168
+ color: white;
169
+ }
170
+
171
+ ::-moz-selection {
172
+ background: var(--primary-500);
173
+ color: white;
174
+ }
175
+
176
+ html {
177
+ font-size: 16px;
178
+ scroll-behavior: smooth;
179
+ }
180
+
181
+ body {
182
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
183
+ font-feature-settings: 'cv11' 1, 'ss01' 1, 'kern' 1;
184
+ line-height: var(--leading-normal);
185
+ color: var(--gray-800);
186
+ background: var(--gray-50);
187
+ -webkit-font-smoothing: antialiased;
188
+ -moz-osx-font-smoothing: grayscale;
189
+ text-rendering: optimizeLegibility;
190
+ }
191
+
192
+ /* Typography */
193
+ .font-display {
194
+ font-family: 'Playfair Display', serif;
195
+ }
196
+
197
+ .font-mono {
198
+ font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', monospace;
199
+ font-variant-numeric: tabular-nums;
200
+ }
201
+
202
+ /* Headings */
203
+ h1, h2, h3, h4, h5, h6 {
204
+ font-weight: var(--font-semibold);
205
+ line-height: var(--leading-tight);
206
+ letter-spacing: -0.025em;
207
+ color: var(--gray-900);
208
+ }
209
+
210
+ h1 {
211
+ font-size: var(--text-4xl);
212
+ font-weight: var(--font-bold);
213
+ }
214
+
215
+ h2 {
216
+ font-size: var(--text-3xl);
217
+ }
218
+
219
+ h3 {
220
+ font-size: var(--text-2xl);
221
+ }
222
+
223
+ h4 {
224
+ font-size: var(--text-xl);
225
+ }
226
+
227
+ h5 {
228
+ font-size: var(--text-lg);
229
+ }
230
+
231
+ h6 {
232
+ font-size: var(--text-base);
233
+ }
234
+
235
+ /* Links */
236
+ a {
237
+ color: var(--primary-600);
238
+ text-decoration: none;
239
+ transition: color var(--transition-fast);
240
+ }
241
+
242
+ a:hover {
243
+ color: var(--primary-700);
244
+ }
245
+
246
+ a:focus {
247
+ outline: 2px solid var(--primary-500);
248
+ outline-offset: 2px;
249
+ }
250
+
251
+ /* Layout Components */
252
+ .container {
253
+ max-width: 1280px;
254
+ margin: 0 auto;
255
+ padding: 0 var(--space-4);
256
+ }
257
+
258
+ @media (min-width: 640px) {
259
+ .container {
260
+ padding: 0 var(--space-6);
261
+ }
262
+ }
263
+
264
+ @media (min-width: 1024px) {
265
+ .container {
266
+ padding: 0 var(--space-8);
267
+ }
268
+ }
269
+
270
+ /* Modern Header Component */
271
+ .tt-header {
272
+ background: var(--gradient-forest);
273
+ color: white;
274
+ position: sticky;
275
+ top: 0;
276
+ z-index: var(--z-sticky);
277
+ backdrop-filter: var(--glass-blur);
278
+ border-bottom: var(--glass-border);
279
+ box-shadow: var(--shadow-lg);
280
+ }
281
+
282
+ .tt-header-content {
283
+ display: flex;
284
+ justify-content: space-between;
285
+ align-items: center;
286
+ padding: var(--space-4) var(--space-6);
287
+ gap: var(--space-6);
288
+ flex-wrap: wrap;
289
+ }
290
+
291
+ .tt-header-brand {
292
+ display: flex;
293
+ flex-direction: column;
294
+ gap: var(--space-1);
295
+ }
296
+
297
+ .tt-header-logo {
298
+ font-size: var(--text-2xl);
299
+ font-weight: var(--font-bold);
300
+ letter-spacing: -0.02em;
301
+ display: flex;
302
+ align-items: center;
303
+ gap: var(--space-2);
304
+ }
305
+
306
+ .tt-header-logo::before {
307
+ content: '🌳';
308
+ font-size: var(--text-3xl);
309
+ }
310
+
311
+ .tt-header-subtitle {
312
+ font-size: var(--text-sm);
313
+ opacity: 0.9;
314
+ font-weight: var(--font-normal);
315
+ }
316
+
317
+ .tt-header-actions {
318
+ display: flex;
319
+ align-items: center;
320
+ gap: var(--space-4);
321
+ flex-wrap: wrap;
322
+ }
323
+
324
+ /* User Info Component */
325
+ .tt-user-info {
326
+ display: flex;
327
+ align-items: center;
328
+ gap: var(--space-3);
329
+ padding: var(--space-2) var(--space-4);
330
+ background: var(--glass-bg-dark);
331
+ border-radius: var(--radius-full);
332
+ border: var(--glass-border);
333
+ backdrop-filter: var(--glass-blur);
334
+ }
335
+
336
+ .tt-user-avatar {
337
+ width: 36px;
338
+ height: 36px;
339
+ border-radius: var(--radius-full);
340
+ background: var(--gradient-secondary);
341
+ display: flex;
342
+ align-items: center;
343
+ justify-content: center;
344
+ font-weight: var(--font-bold);
345
+ font-size: var(--text-sm);
346
+ color: white;
347
+ border: 2px solid rgba(255, 255, 255, 0.2);
348
+ }
349
+
350
+ .tt-user-details {
351
+ display: flex;
352
+ flex-direction: column;
353
+ gap: var(--space-px);
354
+ }
355
+
356
+ .tt-user-name {
357
+ font-size: var(--text-sm);
358
+ font-weight: var(--font-semibold);
359
+ color: white;
360
+ }
361
+
362
+ .tt-user-role {
363
+ font-size: var(--text-xs);
364
+ opacity: 0.8;
365
+ text-transform: capitalize;
366
+ }
367
+
368
+ /* Button System */
369
+ .tt-btn {
370
+ display: inline-flex;
371
+ align-items: center;
372
+ justify-content: center;
373
+ gap: var(--space-2);
374
+ padding: var(--space-3) var(--space-6);
375
+ font-size: var(--text-sm);
376
+ font-weight: var(--font-medium);
377
+ line-height: var(--leading-none);
378
+ border-radius: var(--radius-lg);
379
+ border: none;
380
+ cursor: pointer;
381
+ transition: all var(--transition-normal);
382
+ text-decoration: none;
383
+ outline: none;
384
+ position: relative;
385
+ overflow: hidden;
386
+ white-space: nowrap;
387
+ user-select: none;
388
+ }
389
+
390
+ .tt-btn:focus-visible {
391
+ outline: 2px solid var(--primary-500);
392
+ outline-offset: 2px;
393
+ }
394
+
395
+ .tt-btn:disabled {
396
+ opacity: 0.6;
397
+ cursor: not-allowed;
398
+ pointer-events: none;
399
+ }
400
+
401
+ /* Button Variants */
402
+ .tt-btn-primary {
403
+ background: var(--gradient-primary);
404
+ color: white;
405
+ box-shadow: var(--shadow-md);
406
+ }
407
+
408
+ .tt-btn-primary:hover {
409
+ transform: translateY(-2px);
410
+ box-shadow: var(--shadow-lg);
411
+ }
412
+
413
+ .tt-btn-primary:active {
414
+ transform: translateY(0);
415
+ }
416
+
417
+ .tt-btn-secondary {
418
+ background: var(--glass-bg-dark);
419
+ color: white;
420
+ border: var(--glass-border);
421
+ backdrop-filter: var(--glass-blur);
422
+ }
423
+
424
+ .tt-btn-secondary:hover {
425
+ background: rgba(255, 255, 255, 0.2);
426
+ transform: translateY(-1px);
427
+ }
428
+
429
+ .tt-btn-outline {
430
+ background: transparent;
431
+ color: var(--gray-700);
432
+ border: 1px solid var(--gray-300);
433
+ }
434
+
435
+ .tt-btn-outline:hover {
436
+ background: var(--gray-100);
437
+ border-color: var(--gray-400);
438
+ transform: translateY(-1px);
439
+ }
440
+
441
+ .tt-btn-ghost {
442
+ background: transparent;
443
+ color: var(--gray-600);
444
+ }
445
+
446
+ .tt-btn-ghost:hover {
447
+ background: var(--gray-100);
448
+ color: var(--gray-800);
449
+ }
450
+
451
+ /* Button Sizes */
452
+ .tt-btn-xs {
453
+ padding: var(--space-1) var(--space-3);
454
+ font-size: var(--text-xs);
455
+ }
456
+
457
+ .tt-btn-sm {
458
+ padding: var(--space-2) var(--space-4);
459
+ font-size: var(--text-sm);
460
+ }
461
+
462
+ .tt-btn-lg {
463
+ padding: var(--space-4) var(--space-8);
464
+ font-size: var(--text-lg);
465
+ font-weight: var(--font-semibold);
466
+ }
467
+
468
+ .tt-btn-xl {
469
+ padding: var(--space-5) var(--space-10);
470
+ font-size: var(--text-xl);
471
+ font-weight: var(--font-semibold);
472
+ }
473
+
474
+ /* Form Components */
475
+ .tt-form-group {
476
+ display: flex;
477
+ flex-direction: column;
478
+ gap: var(--space-2);
479
+ }
480
+
481
+ .tt-form-label {
482
+ font-size: var(--text-sm);
483
+ font-weight: var(--font-medium);
484
+ color: var(--gray-700);
485
+ }
486
+
487
+ .tt-form-label.required::after {
488
+ content: '*';
489
+ color: var(--error-500);
490
+ margin-left: var(--space-1);
491
+ }
492
+
493
+ .tt-form-input {
494
+ padding: var(--space-3) var(--space-4);
495
+ font-size: var(--text-sm);
496
+ color: var(--gray-900);
497
+ background: white;
498
+ border: 2px solid var(--gray-200);
499
+ border-radius: var(--radius-lg);
500
+ transition: all var(--transition-fast);
501
+ outline: none;
502
+ }
503
+
504
+ .tt-form-input:focus {
505
+ border-color: var(--primary-500);
506
+ box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.1);
507
+ transform: translateY(-1px);
508
+ }
509
+
510
+ .tt-form-input:disabled {
511
+ background: var(--gray-100);
512
+ color: var(--gray-500);
513
+ cursor: not-allowed;
514
+ }
515
+
516
+ .tt-form-input::placeholder {
517
+ color: var(--gray-400);
518
+ }
519
+
520
+ /* Card Components */
521
+ .tt-card {
522
+ background: white;
523
+ border-radius: var(--radius-2xl);
524
+ border: 1px solid var(--gray-200);
525
+ box-shadow: var(--shadow-sm);
526
+ overflow: hidden;
527
+ transition: all var(--transition-normal);
528
+ }
529
+
530
+ .tt-card:hover {
531
+ box-shadow: var(--shadow-md);
532
+ border-color: var(--gray-300);
533
+ transform: translateY(-1px);
534
+ }
535
+
536
+ .tt-card-header {
537
+ padding: var(--space-6);
538
+ border-bottom: 1px solid var(--gray-100);
539
+ background: var(--gray-50);
540
+ }
541
+
542
+ .tt-card-content {
543
+ padding: var(--space-6);
544
+ }
545
+
546
+ .tt-card-footer {
547
+ padding: var(--space-4) var(--space-6);
548
+ border-top: 1px solid var(--gray-100);
549
+ background: var(--gray-50);
550
+ }
551
+
552
+ /* Message Components */
553
+ .tt-message {
554
+ padding: var(--space-4);
555
+ border-radius: var(--radius-lg);
556
+ font-size: var(--text-sm);
557
+ font-weight: var(--font-medium);
558
+ border: 1px solid transparent;
559
+ display: flex;
560
+ align-items: center;
561
+ gap: var(--space-3);
562
+ }
563
+
564
+ .tt-message-success {
565
+ background: var(--success-50);
566
+ color: var(--success-700);
567
+ border-color: var(--success-500);
568
+ }
569
+
570
+ .tt-message-error {
571
+ background: var(--error-50);
572
+ color: var(--error-700);
573
+ border-color: var(--error-500);
574
+ }
575
+
576
+ .tt-message-warning {
577
+ background: var(--warning-50);
578
+ color: var(--warning-700);
579
+ border-color: var(--warning-500);
580
+ }
581
+
582
+ .tt-message-info {
583
+ background: var(--info-50);
584
+ color: var(--info-700);
585
+ border-color: var(--info-500);
586
+ }
587
+
588
+ /* Loading Components */
589
+ .tt-loading {
590
+ display: flex;
591
+ align-items: center;
592
+ justify-content: center;
593
+ gap: var(--space-3);
594
+ padding: var(--space-8);
595
+ }
596
+
597
+ .tt-spinner {
598
+ border: 3px solid var(--gray-200);
599
+ border-top: 3px solid var(--primary-500);
600
+ border-radius: var(--radius-full);
601
+ width: var(--space-6);
602
+ height: var(--space-6);
603
+ animation: tt-spin 1s linear infinite;
604
+ }
605
+
606
+ @keyframes tt-spin {
607
+ 0% { transform: rotate(0deg); }
608
+ 100% { transform: rotate(360deg); }
609
+ }
610
+
611
+ /* Mobile Responsiveness */
612
+ @media (max-width: 768px) {
613
+ .tt-header-content {
614
+ padding: var(--space-3) var(--space-4);
615
+ flex-direction: column;
616
+ align-items: stretch;
617
+ gap: var(--space-4);
618
+ }
619
+
620
+ .tt-header-logo {
621
+ font-size: var(--text-xl);
622
+ text-align: center;
623
+ }
624
+
625
+ .tt-header-actions {
626
+ justify-content: space-between;
627
+ width: 100%;
628
+ }
629
+
630
+ .tt-user-details {
631
+ display: none;
632
+ }
633
+
634
+ .tt-btn {
635
+ padding: var(--space-3) var(--space-4);
636
+ font-size: var(--text-sm);
637
+ }
638
+
639
+ .tt-btn-lg {
640
+ padding: var(--space-4) var(--space-6);
641
+ font-size: var(--text-base);
642
+ }
643
+ }
644
+
645
+ @media (max-width: 480px) {
646
+ .tt-header-logo {
647
+ font-size: var(--text-lg);
648
+ }
649
+
650
+ .tt-header-subtitle {
651
+ font-size: var(--text-xs);
652
+ text-align: center;
653
+ }
654
+
655
+ .tt-btn {
656
+ padding: var(--space-2) var(--space-3);
657
+ font-size: var(--text-xs);
658
+ }
659
+ }
660
+
661
+ /* Special Components */
662
+
663
+ /* GPS Button Enhanced Mobile Styling */
664
+ .tt-btn-gps {
665
+ background: var(--gradient-primary);
666
+ color: white;
667
+ box-shadow: var(--shadow-md);
668
+ position: relative;
669
+ overflow: hidden;
670
+ }
671
+
672
+ .tt-btn-gps::before {
673
+ content: '';
674
+ position: absolute;
675
+ top: 0;
676
+ left: -100%;
677
+ width: 100%;
678
+ height: 100%;
679
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
680
+ transition: left 0.5s;
681
+ }
682
+
683
+ .tt-btn-gps:hover::before {
684
+ left: 100%;
685
+ }
686
+
687
+ .tt-btn-gps:hover {
688
+ transform: translateY(-2px);
689
+ box-shadow: var(--shadow-lg);
690
+ }
691
+
692
+ /* Mobile-specific GPS button styling */
693
+ @media (max-width: 768px) {
694
+ .tt-btn-gps {
695
+ width: 100%;
696
+ justify-content: center;
697
+ min-height: 48px;
698
+ font-weight: var(--font-semibold);
699
+ background: var(--gradient-primary);
700
+ border: none;
701
+ color: white;
702
+ }
703
+
704
+ .tt-btn-gps:hover {
705
+ background: var(--gradient-primary);
706
+ filter: brightness(1.1);
707
+ }
708
+
709
+ .tt-btn-gps:active {
710
+ transform: scale(0.98);
711
+ }
712
+ }
713
+
714
+ /* Glassmorphism Login Container */
715
+ .tt-login-container {
716
+ background: var(--glass-bg);
717
+ backdrop-filter: var(--glass-blur);
718
+ border-radius: var(--radius-3xl);
719
+ border: var(--glass-border);
720
+ box-shadow: var(--shadow-2xl);
721
+ padding: var(--space-8);
722
+ width: 100%;
723
+ max-width: 420px;
724
+ animation: tt-slideIn 0.6s ease-out;
725
+ }
726
+
727
+ @keyframes tt-slideIn {
728
+ from {
729
+ opacity: 0;
730
+ transform: translateY(30px) scale(0.95);
731
+ }
732
+ to {
733
+ opacity: 1;
734
+ transform: translateY(0) scale(1);
735
+ }
736
+ }
737
+
738
+ /* Utility Classes */
739
+ .tt-sr-only {
740
+ position: absolute;
741
+ width: 1px;
742
+ height: 1px;
743
+ padding: 0;
744
+ margin: -1px;
745
+ overflow: hidden;
746
+ clip: rect(0, 0, 0, 0);
747
+ white-space: nowrap;
748
+ border: 0;
749
+ }
750
+
751
+ .tt-hidden {
752
+ display: none !important;
753
+ }
754
+
755
+ .tt-fade-in {
756
+ animation: tt-fadeIn 0.3s ease-out;
757
+ }
758
+
759
+ @keyframes tt-fadeIn {
760
+ from { opacity: 0; transform: translateY(-10px); }
761
+ to { opacity: 1; transform: translateY(0); }
762
+ }
763
+
764
+ /* Custom scrollbar */
765
+ ::-webkit-scrollbar {
766
+ width: 8px;
767
+ }
768
+
769
+ ::-webkit-scrollbar-track {
770
+ background: var(--gray-100);
771
+ border-radius: var(--radius-md);
772
+ }
773
+
774
+ ::-webkit-scrollbar-thumb {
775
+ background: var(--gray-400);
776
+ border-radius: var(--radius-md);
777
+ }
778
+
779
+ ::-webkit-scrollbar-thumb:hover {
780
+ background: var(--primary-500);
781
+ }
782
+
783
+ /* Focus improvements */
784
+ *:focus-visible {
785
+ outline: 2px solid var(--primary-500);
786
+ outline-offset: 2px;
787
+ }
static/index.html CHANGED
@@ -7,8 +7,8 @@
7
  <meta http-equiv="Pragma" content="no-cache">
8
  <meta http-equiv="Expires" content="0">
9
  <title>TreeTrack - Professional Field Research</title>
 
10
  <style>
11
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
12
 
13
  :root {
14
  /* Colors */
@@ -80,163 +80,9 @@
80
  -moz-osx-font-smoothing: grayscale;
81
  }
82
 
83
- /* Modern Header */
84
- .header {
85
- background: white;
86
- color: var(--gray-900);
87
- position: sticky;
88
- top: 0;
89
- z-index: 100;
90
- border-bottom: 1px solid var(--gray-200);
91
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
92
- }
93
-
94
- .header-content {
95
- max-width: 1400px;
96
- margin: 0 auto;
97
- padding: var(--space-3) var(--space-4);
98
- display: flex;
99
- justify-content: space-between;
100
- align-items: center;
101
- flex-wrap: wrap;
102
- gap: var(--space-3);
103
- }
104
-
105
- .header-brand {
106
- display: flex;
107
- flex-direction: column;
108
- gap: var(--space-1);
109
- }
110
-
111
- .header h1 {
112
- font-size: 1.5rem;
113
- font-weight: 600;
114
- margin: 0;
115
- letter-spacing: -0.025em;
116
- color: var(--gray-900);
117
- display: flex;
118
- align-items: center;
119
- gap: var(--space-2);
120
- }
121
-
122
-
123
- .header-subtitle {
124
- font-size: 0.75rem;
125
- color: var(--gray-600);
126
- font-weight: 400;
127
- }
128
-
129
- .header-actions {
130
- display: flex;
131
- align-items: center;
132
- gap: var(--space-3);
133
- }
134
-
135
- .user-info {
136
- display: flex;
137
- align-items: center;
138
- gap: var(--space-2);
139
- padding: var(--space-2) var(--space-3);
140
- background: var(--gray-50);
141
- border-radius: var(--radius-lg);
142
- border: 1px solid var(--gray-200);
143
- }
144
-
145
- .user-avatar {
146
- width: 28px;
147
- height: 28px;
148
- border-radius: 50%;
149
- background: var(--primary-500);
150
- display: flex;
151
- align-items: center;
152
- justify-content: center;
153
- font-weight: 600;
154
- font-size: 0.75rem;
155
- color: white;
156
- }
157
 
158
- .user-details {
159
- display: flex;
160
- flex-direction: column;
161
- gap: 0;
162
- }
163
-
164
- .user-name {
165
- font-size: 0.8125rem;
166
- font-weight: 500;
167
- color: var(--gray-900);
168
- }
169
-
170
- .user-role {
171
- font-size: 0.6875rem;
172
- color: var(--gray-600);
173
- text-transform: capitalize;
174
- }
175
-
176
- .btn {
177
- display: inline-flex;
178
- align-items: center;
179
- justify-content: center;
180
- gap: var(--space-2);
181
- padding: var(--space-2) var(--space-4);
182
- font-size: 0.875rem;
183
- font-weight: 500;
184
- line-height: 1.25;
185
- border-radius: var(--radius-md);
186
- border: none;
187
- cursor: pointer;
188
- transition: all 0.15s ease;
189
- text-decoration: none;
190
- outline: none;
191
- position: relative;
192
- overflow: hidden;
193
- }
194
-
195
- .btn-primary {
196
- background: var(--primary-500);
197
- color: white;
198
- }
199
-
200
- .btn-primary:hover {
201
- background: var(--primary-600);
202
- transform: translateY(-1px);
203
- box-shadow: var(--shadow-md);
204
- }
205
-
206
- .btn-secondary {
207
- background: var(--gray-100);
208
- color: var(--gray-700);
209
- border: 1px solid var(--gray-200);
210
- font-size: 0.8125rem;
211
- padding: var(--space-2) var(--space-3);
212
- }
213
-
214
- .btn-secondary:hover {
215
- background: var(--gray-200);
216
- color: var(--gray-800);
217
- transform: translateY(-1px);
218
- }
219
-
220
- .btn-outline {
221
- background: transparent;
222
- color: var(--gray-700);
223
- border: 1px solid var(--gray-300);
224
- }
225
-
226
- .btn-outline:hover {
227
- background: var(--gray-50);
228
- border-color: var(--gray-400);
229
- }
230
-
231
- .btn-lg {
232
- padding: var(--space-3) var(--space-6);
233
- font-size: 1rem;
234
- }
235
-
236
- .btn-sm {
237
- padding: var(--space-1) var(--space-3);
238
- font-size: 0.8125rem;
239
- }
240
 
241
  /* Main Content */
242
  .main-container {
@@ -511,12 +357,12 @@
511
  flex-shrink: 0;
512
  }
513
 
514
- /* Location buttons redesign */
515
  .location-buttons {
516
  display: flex;
517
  gap: var(--space-3);
518
  align-items: center;
519
- margin-top: var(--space-2);
520
  }
521
 
522
  .location-btn-gps {
@@ -531,46 +377,14 @@
531
  @media (max-width: 768px) {
532
  .location-buttons {
533
  flex-direction: column;
534
- gap: var(--space-3);
535
- margin-top: var(--space-4);
536
- }
537
-
538
- .location-btn-gps,
539
- .location-btn-map {
540
- width: 100%;
541
- justify-content: center;
542
- min-height: 48px;
543
- font-size: 0.875rem;
544
- font-weight: 500;
545
- padding: var(--space-3) var(--space-4);
546
- }
547
-
548
- .location-btn-gps {
549
- background: var(--primary-500);
550
- color: white;
551
- border: none;
552
- }
553
-
554
- .location-btn-gps:hover {
555
- background: var(--primary-600);
556
  }
557
  }
558
 
559
  @media (max-width: 480px) {
560
  .location-buttons {
561
- gap: var(--space-2);
562
- }
563
-
564
- .location-btn-gps,
565
- .location-btn-map {
566
- min-height: 44px;
567
- font-size: 0.8125rem;
568
- padding: var(--space-2) var(--space-3);
569
- }
570
-
571
- /* Ensure button text is always visible on mobile */
572
- .btn-text {
573
- display: inline !important;
574
  }
575
  }
576
 
@@ -1090,34 +904,34 @@
1090
  </script>
1091
  </head>
1092
  <body>
1093
- <div class="header">
1094
- <div class="header-content">
1095
- <div class="header-brand">
1096
- <h1>TreeTrack</h1>
1097
- <div class="header-subtitle">Professional Field Research Platform</div>
1098
  </div>
1099
- <div class="header-actions">
1100
- <div class="user-info" id="userInfo">
1101
- <div class="user-avatar" id="userAvatar">U</div>
1102
- <div class="user-details">
1103
- <div class="user-name" id="userName">Loading...</div>
1104
- <div class="user-role" id="userRole">User</div>
1105
  </div>
1106
  </div>
1107
- <a href="/static/map.html" class="btn btn-secondary">View Map</a>
1108
- <button id="logoutBtn" class="btn btn-secondary">Logout</button>
1109
  </div>
1110
  </div>
1111
  </div>
1112
 
1113
  <div class="main-container">
1114
  <div class="content-grid">
1115
- <div class="card">
1116
- <div class="card-header">
1117
- <h2 class="card-title">Tree Documentation Form</h2>
1118
- <p class="card-subtitle">Complete the form below to document tree specimens in the field. All required fields are marked with an asterisk.</p>
1119
  </div>
1120
- <div class="card-content">
1121
  <form id="treeForm">
1122
  <!-- Location Section -->
1123
  <div class="form-section">
@@ -1139,11 +953,11 @@
1139
 
1140
  <div class="form-group">
1141
  <div class="location-buttons">
1142
- <button type="button" id="getLocation" class="btn btn-outline location-btn-gps">
1143
- <span class="btn-text">Get GPS Location</span>
1144
  </button>
1145
- <a href="/static/map.html" class="btn btn-primary location-btn-map">
1146
- <span class="btn-text">Select from Map</span>
1147
  </a>
1148
  </div>
1149
  </div>
@@ -1273,8 +1087,8 @@
1273
  </div>
1274
 
1275
  <div class="form-actions">
1276
- <button type="button" id="resetForm" class="btn btn-outline">Reset Form</button>
1277
- <button type="submit" class="btn btn-primary btn-lg">Save Tree Record</button>
1278
  </div>
1279
  </form>
1280
 
@@ -1282,15 +1096,15 @@
1282
  </div>
1283
  </div>
1284
 
1285
- <div class="card">
1286
- <div class="card-header">
1287
- <h3 class="card-title">Recent Trees</h3>
1288
- <p class="card-subtitle">Recently documented specimens</p>
1289
  </div>
1290
- <div class="card-content">
1291
  <div id="treeList" class="tree-list">
1292
- <div class="loading">
1293
- <div class="spinner"></div>
1294
  Loading trees...
1295
  </div>
1296
  </div>
 
7
  <meta http-equiv="Pragma" content="no-cache">
8
  <meta http-equiv="Expires" content="0">
9
  <title>TreeTrack - Professional Field Research</title>
10
+ <link rel="stylesheet" href="/static/css/design-system.css">
11
  <style>
 
12
 
13
  :root {
14
  /* Colors */
 
80
  -moz-osx-font-smoothing: grayscale;
81
  }
82
 
83
+ /* Updated header to match design system */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
+ /* Button styles now handled by design system */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
  /* Main Content */
88
  .main-container {
 
357
  flex-shrink: 0;
358
  }
359
 
360
+ /* Enhanced location button styling with design system */
361
  .location-buttons {
362
  display: flex;
363
  gap: var(--space-3);
364
  align-items: center;
365
+ margin-top: var(--space-4);
366
  }
367
 
368
  .location-btn-gps {
 
377
  @media (max-width: 768px) {
378
  .location-buttons {
379
  flex-direction: column;
380
+ gap: var(--space-4);
381
+ margin-top: var(--space-6);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
382
  }
383
  }
384
 
385
  @media (max-width: 480px) {
386
  .location-buttons {
387
+ gap: var(--space-3);
 
 
 
 
 
 
 
 
 
 
 
 
388
  }
389
  }
390
 
 
904
  </script>
905
  </head>
906
  <body>
907
+ <div class="tt-header">
908
+ <div class="tt-header-content">
909
+ <div class="tt-header-brand">
910
+ <div class="tt-header-logo">TreeTrack</div>
911
+ <div class="tt-header-subtitle">Professional Field Research Platform</div>
912
  </div>
913
+ <div class="tt-header-actions">
914
+ <div class="tt-user-info" id="userInfo">
915
+ <div class="tt-user-avatar" id="userAvatar">U</div>
916
+ <div class="tt-user-details">
917
+ <div class="tt-user-name" id="userName">Loading...</div>
918
+ <div class="tt-user-role" id="userRole">User</div>
919
  </div>
920
  </div>
921
+ <a href="/static/map.html" class="tt-btn tt-btn-secondary">View Map</a>
922
+ <button id="logoutBtn" class="tt-btn tt-btn-secondary">Logout</button>
923
  </div>
924
  </div>
925
  </div>
926
 
927
  <div class="main-container">
928
  <div class="content-grid">
929
+ <div class="tt-card">
930
+ <div class="tt-card-header">
931
+ <h2 class="tt-card-title">Tree Documentation Form</h2>
932
+ <p class="tt-card-subtitle">Complete the form below to document tree specimens in the field. All required fields are marked with an asterisk.</p>
933
  </div>
934
+ <div class="tt-card-content">
935
  <form id="treeForm">
936
  <!-- Location Section -->
937
  <div class="form-section">
 
953
 
954
  <div class="form-group">
955
  <div class="location-buttons">
956
+ <button type="button" id="getLocation" class="tt-btn tt-btn-gps location-btn-gps">
957
+ <span class="btn-text">πŸ“ Get GPS Location</span>
958
  </button>
959
+ <a href="/static/map.html" class="tt-btn tt-btn-primary location-btn-map">
960
+ <span class="btn-text">πŸ—ΊοΈ Select from Map</span>
961
  </a>
962
  </div>
963
  </div>
 
1087
  </div>
1088
 
1089
  <div class="form-actions">
1090
+ <button type="button" id="resetForm" class="tt-btn tt-btn-outline">Reset Form</button>
1091
+ <button type="submit" class="tt-btn tt-btn-primary tt-btn-lg">🌳 Save Tree Record</button>
1092
  </div>
1093
  </form>
1094
 
 
1096
  </div>
1097
  </div>
1098
 
1099
+ <div class="tt-card">
1100
+ <div class="tt-card-header">
1101
+ <h3 class="tt-card-title">Recent Trees</h3>
1102
+ <p class="tt-card-subtitle">Recently documented specimens</p>
1103
  </div>
1104
+ <div class="tt-card-content">
1105
  <div id="treeList" class="tree-list">
1106
+ <div class="tt-loading">
1107
+ <div class="tt-spinner"></div>
1108
  Loading trees...
1109
  </div>
1110
  </div>
static/login.html CHANGED
@@ -4,134 +4,57 @@
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>TreeTrack Login - Field Research Access</title>
 
7
  <style>
8
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
9
-
10
- * {
11
- margin: 0;
12
- padding: 0;
13
- box-sizing: border-box;
14
- }
15
-
16
  body {
17
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
18
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
19
  min-height: 100vh;
20
  display: flex;
21
  align-items: center;
22
  justify-content: center;
23
- padding: 1rem;
24
- }
25
-
26
- .login-container {
27
- background: rgba(255, 255, 255, 0.95);
28
- backdrop-filter: blur(20px);
29
- border-radius: 24px;
30
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
31
- border: 1px solid rgba(255, 255, 255, 0.2);
32
- width: 100%;
33
- max-width: 400px;
34
- padding: 2.5rem;
35
- animation: slideIn 0.6s ease-out;
36
- }
37
-
38
- @keyframes slideIn {
39
- from {
40
- opacity: 0;
41
- transform: translateY(30px) scale(0.95);
42
- }
43
- to {
44
- opacity: 1;
45
- transform: translateY(0) scale(1);
46
- }
47
  }
48
 
49
  .logo-section {
50
  text-align: center;
51
- margin-bottom: 2rem;
52
  }
53
 
54
  .logo {
55
- font-size: 2.5rem;
56
- font-weight: 700;
57
- background: linear-gradient(135deg, #1e40af, #3b82f6);
58
- -webkit-background-clip: text;
59
- -webkit-text-fill-color: transparent;
60
- background-clip: text;
61
- margin-bottom: 0.5rem;
62
  letter-spacing: -0.02em;
 
 
 
 
63
  }
64
 
65
- .logo-subtitle {
66
- color: #6b7280;
67
- font-size: 0.875rem;
68
- font-weight: 500;
69
  }
70
 
71
- .login-form {
72
- display: flex;
73
- flex-direction: column;
74
- gap: 1.5rem;
75
  }
76
 
77
- .form-group {
78
  display: flex;
79
  flex-direction: column;
80
- gap: 0.5rem;
81
- }
82
-
83
- .form-label {
84
- font-weight: 600;
85
- color: #374151;
86
- font-size: 0.875rem;
87
- }
88
-
89
- .form-input {
90
- padding: 0.875rem 1rem;
91
- border: 2px solid #e5e7eb;
92
- border-radius: 12px;
93
- font-size: 1rem;
94
- transition: all 0.2s ease;
95
- background: #ffffff;
96
- outline: none;
97
- }
98
-
99
- .form-input:focus {
100
- border-color: #3b82f6;
101
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
102
- transform: scale(1.02);
103
  }
104
 
105
  .login-button {
106
- background: linear-gradient(135deg, #1e40af 0%, #3b82f6 100%);
107
- color: white;
108
- border: none;
109
- padding: 1rem;
110
- border-radius: 12px;
111
- font-size: 1rem;
112
- font-weight: 600;
113
- cursor: pointer;
114
- transition: all 0.3s ease;
115
- margin-top: 1rem;
116
  position: relative;
117
  overflow: hidden;
118
  }
119
 
120
- .login-button:hover {
121
- transform: translateY(-2px);
122
- box-shadow: 0 10px 25px -5px rgba(59, 130, 246, 0.4);
123
- }
124
-
125
- .login-button:active {
126
- transform: translateY(0);
127
- }
128
-
129
- .login-button:disabled {
130
- opacity: 0.7;
131
- cursor: not-allowed;
132
- transform: none;
133
- }
134
-
135
  .login-button.loading::after {
136
  content: '';
137
  position: absolute;
@@ -143,134 +66,129 @@
143
  border: 2px solid transparent;
144
  border-top: 2px solid #ffffff;
145
  border-radius: 50%;
146
- animation: spin 1s linear infinite;
147
- }
148
-
149
- @keyframes spin {
150
- 0% { transform: rotate(0deg); }
151
- 100% { transform: rotate(360deg); }
152
- }
153
-
154
- .message {
155
- padding: 1rem;
156
- border-radius: 12px;
157
- margin-bottom: 1.5rem;
158
- font-size: 0.875rem;
159
- font-weight: 500;
160
- text-align: center;
161
- animation: fadeIn 0.3s ease;
162
- }
163
-
164
- @keyframes fadeIn {
165
- from { opacity: 0; transform: translateY(-10px); }
166
- to { opacity: 1; transform: translateY(0); }
167
- }
168
-
169
- .message.error {
170
- background: #fef2f2;
171
- color: #dc2626;
172
- border: 1px solid #fecaca;
173
- }
174
-
175
- .message.success {
176
- background: #f0fdf4;
177
- color: #16a34a;
178
- border: 1px solid #bbf7d0;
179
  }
180
 
181
  .demo-accounts {
182
- margin-top: 2rem;
183
- padding: 1.5rem;
184
- background: rgba(59, 130, 246, 0.05);
185
- border: 1px solid rgba(59, 130, 246, 0.1);
186
- border-radius: 16px;
187
  }
188
 
189
  .demo-title {
190
- font-size: 0.875rem;
191
- font-weight: 600;
192
- color: #1e40af;
193
- margin-bottom: 1rem;
194
  text-align: center;
 
 
 
 
 
 
 
 
195
  }
196
 
197
  .account-list {
198
  display: flex;
199
  flex-direction: column;
200
- gap: 0.75rem;
201
  }
202
 
203
  .account-item {
204
- background: rgba(255, 255, 255, 0.7);
205
- padding: 0.75rem;
206
- border-radius: 8px;
207
- font-size: 0.75rem;
208
  cursor: pointer;
209
- transition: all 0.2s ease;
210
- border: 1px solid rgba(59, 130, 246, 0.1);
 
211
  }
212
 
213
  .account-item:hover {
214
- background: rgba(255, 255, 255, 0.9);
215
- transform: translateY(-1px);
 
 
216
  }
217
 
218
  .account-role {
219
- font-weight: 600;
220
- color: #1e40af;
 
221
  }
222
 
223
  .account-username {
224
- color: #6b7280;
225
- margin-top: 0.25rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  }
227
 
228
  .footer {
229
  text-align: center;
230
- margin-top: 2rem;
231
- color: #9ca3af;
232
- font-size: 0.75rem;
233
  }
234
 
235
  @media (max-width: 480px) {
236
- .login-container {
237
- padding: 2rem 1.5rem;
238
- margin: 0 1rem;
239
  }
240
 
241
  .logo {
242
- font-size: 2rem;
243
  }
244
  }
245
  </style>
246
  </head>
247
  <body>
248
- <div class="login-container">
249
  <div class="logo-section">
250
- <div class="logo">🌳 TreeTrack</div>
251
  <div class="logo-subtitle">Secure Field Research Access</div>
252
  </div>
253
 
254
  <form class="login-form" id="loginForm">
255
- <div id="message" class="message" style="display: none;"></div>
256
 
257
- <div class="form-group">
258
- <label class="form-label" for="username">Username</label>
259
- <input class="form-input" type="text" id="username" name="username" required autocomplete="username">
260
  </div>
261
 
262
- <div class="form-group">
263
- <label class="form-label" for="password">Password</label>
264
- <input class="form-input" type="password" id="password" name="password" required autocomplete="current-password">
265
  </div>
266
 
267
- <button class="login-button" type="submit" id="loginButton">
268
  <span id="buttonText">Sign In to TreeTrack</span>
269
  </button>
270
  </form>
271
 
272
  <div class="demo-accounts">
273
- <div class="demo-title">πŸ” Available Accounts</div>
274
  <div class="account-list">
275
  <div class="account-item" onclick="fillCredentials('aalekh', event)">
276
  <div class="account-role">Aalekh (Admin)</div>
@@ -289,8 +207,8 @@
289
  <div class="account-username">Tree research & documentation</div>
290
  </div>
291
  </div>
292
- <div style="margin-top: 1rem; padding: 0.75rem; background: rgba(34, 197, 94, 0.1); border: 1px solid rgba(34, 197, 94, 0.3); border-radius: 8px; font-size: 0.75rem; color: #166534;">
293
- βœ… <strong>Secure Authentication:</strong> All passwords are configured via environment variables for maximum security.
294
  </div>
295
  </div>
296
 
@@ -327,7 +245,7 @@
327
  function showMessage(message, type = 'error') {
328
  const messageEl = document.getElementById('message');
329
  messageEl.textContent = message;
330
- messageEl.className = `message ${type}`;
331
  messageEl.style.display = 'block';
332
 
333
  if (type === 'success') {
 
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>TreeTrack Login - Field Research Access</title>
7
+ <link rel="stylesheet" href="/static/css/design-system.css">
8
  <style>
 
 
 
 
 
 
 
 
9
  body {
10
+ background: var(--gradient-forest);
 
11
  min-height: 100vh;
12
  display: flex;
13
  align-items: center;
14
  justify-content: center;
15
+ padding: var(--space-4);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  }
17
 
18
  .logo-section {
19
  text-align: center;
20
+ margin-bottom: var(--space-8);
21
  }
22
 
23
  .logo {
24
+ font-size: var(--text-4xl);
25
+ font-weight: var(--font-bold);
26
+ color: var(--primary-600);
27
+ margin-bottom: var(--space-2);
 
 
 
28
  letter-spacing: -0.02em;
29
+ display: flex;
30
+ align-items: center;
31
+ justify-content: center;
32
+ gap: var(--space-2);
33
  }
34
 
35
+ .logo::before {
36
+ content: '🌳';
37
+ font-size: var(--text-5xl);
 
38
  }
39
 
40
+ .logo-subtitle {
41
+ color: var(--gray-600);
42
+ font-size: var(--text-sm);
43
+ font-weight: var(--font-medium);
44
  }
45
 
46
+ .login-form {
47
  display: flex;
48
  flex-direction: column;
49
+ gap: var(--space-6);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
51
 
52
  .login-button {
53
+ margin-top: var(--space-4);
 
 
 
 
 
 
 
 
 
54
  position: relative;
55
  overflow: hidden;
56
  }
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  .login-button.loading::after {
59
  content: '';
60
  position: absolute;
 
66
  border: 2px solid transparent;
67
  border-top: 2px solid #ffffff;
68
  border-radius: 50%;
69
+ animation: tt-spin 1s linear infinite;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  }
71
 
72
  .demo-accounts {
73
+ margin-top: var(--space-8);
74
+ padding: var(--space-6);
75
+ background: rgba(34, 197, 94, 0.05);
76
+ border: 1px solid rgba(34, 197, 94, 0.1);
77
+ border-radius: var(--radius-2xl);
78
  }
79
 
80
  .demo-title {
81
+ font-size: var(--text-sm);
82
+ font-weight: var(--font-semibold);
83
+ color: var(--primary-700);
84
+ margin-bottom: var(--space-4);
85
  text-align: center;
86
+ display: flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ gap: var(--space-2);
90
+ }
91
+
92
+ .demo-title::before {
93
+ content: 'πŸ”';
94
  }
95
 
96
  .account-list {
97
  display: flex;
98
  flex-direction: column;
99
+ gap: var(--space-3);
100
  }
101
 
102
  .account-item {
103
+ background: white;
104
+ padding: var(--space-4);
105
+ border-radius: var(--radius-lg);
106
+ font-size: var(--text-sm);
107
  cursor: pointer;
108
+ transition: all var(--transition-normal);
109
+ border: 1px solid var(--gray-200);
110
+ box-shadow: var(--shadow-sm);
111
  }
112
 
113
  .account-item:hover {
114
+ background: var(--primary-50);
115
+ border-color: var(--primary-300);
116
+ transform: translateY(-2px);
117
+ box-shadow: var(--shadow-md);
118
  }
119
 
120
  .account-role {
121
+ font-weight: var(--font-semibold);
122
+ color: var(--primary-700);
123
+ margin-bottom: var(--space-1);
124
  }
125
 
126
  .account-username {
127
+ color: var(--gray-600);
128
+ font-size: var(--text-xs);
129
+ }
130
+
131
+ .security-notice {
132
+ margin-top: var(--space-4);
133
+ padding: var(--space-4);
134
+ background: var(--success-50);
135
+ border: 1px solid var(--success-200);
136
+ border-radius: var(--radius-lg);
137
+ font-size: var(--text-xs);
138
+ color: var(--success-700);
139
+ }
140
+
141
+ .security-notice::before {
142
+ content: 'βœ…';
143
+ margin-right: var(--space-2);
144
  }
145
 
146
  .footer {
147
  text-align: center;
148
+ margin-top: var(--space-8);
149
+ color: var(--gray-500);
150
+ font-size: var(--text-xs);
151
  }
152
 
153
  @media (max-width: 480px) {
154
+ .tt-login-container {
155
+ padding: var(--space-6) var(--space-4);
156
+ margin: 0 var(--space-4);
157
  }
158
 
159
  .logo {
160
+ font-size: var(--text-3xl);
161
  }
162
  }
163
  </style>
164
  </head>
165
  <body>
166
+ <div class="tt-login-container">
167
  <div class="logo-section">
168
+ <div class="logo">TreeTrack</div>
169
  <div class="logo-subtitle">Secure Field Research Access</div>
170
  </div>
171
 
172
  <form class="login-form" id="loginForm">
173
+ <div id="message" class="tt-message" style="display: none;"></div>
174
 
175
+ <div class="tt-form-group">
176
+ <label class="tt-form-label" for="username">Username</label>
177
+ <input class="tt-form-input" type="text" id="username" name="username" required autocomplete="username">
178
  </div>
179
 
180
+ <div class="tt-form-group">
181
+ <label class="tt-form-label" for="password">Password</label>
182
+ <input class="tt-form-input" type="password" id="password" name="password" required autocomplete="current-password">
183
  </div>
184
 
185
+ <button class="tt-btn tt-btn-primary tt-btn-lg login-button" type="submit" id="loginButton">
186
  <span id="buttonText">Sign In to TreeTrack</span>
187
  </button>
188
  </form>
189
 
190
  <div class="demo-accounts">
191
+ <div class="demo-title">Available Accounts</div>
192
  <div class="account-list">
193
  <div class="account-item" onclick="fillCredentials('aalekh', event)">
194
  <div class="account-role">Aalekh (Admin)</div>
 
207
  <div class="account-username">Tree research & documentation</div>
208
  </div>
209
  </div>
210
+ <div class="security-notice">
211
+ <strong>Secure Authentication:</strong> All passwords are configured via environment variables for maximum security.
212
  </div>
213
  </div>
214
 
 
245
  function showMessage(message, type = 'error') {
246
  const messageEl = document.getElementById('message');
247
  messageEl.textContent = message;
248
+ messageEl.className = `tt-message tt-message-${type} tt-fade-in`;
249
  messageEl.style.display = 'block';
250
 
251
  if (type === 'success') {
static/map.html CHANGED
@@ -10,9 +10,9 @@
10
 
11
  <!-- Leaflet CSS -->
12
  <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
 
13
 
14
  <style>
15
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
16
 
17
  :root {
18
  /* Colors */
@@ -92,66 +92,74 @@
92
  flex-direction: column;
93
  }
94
 
95
- /* Header */
96
- .header {
97
- background: linear-gradient(135deg, var(--primary-600) 0%, var(--primary-700) 100%);
98
- color: white;
99
- z-index: 1000;
100
- border-bottom: 1px solid rgba(255, 255, 255, 0.1);
101
- backdrop-filter: blur(12px);
102
- }
103
-
104
- .header-content {
105
- padding: var(--space-4) var(--space-6);
106
- display: flex;
107
- justify-content: space-between;
108
- align-items: center;
109
- flex-wrap: wrap;
110
- gap: var(--space-4);
111
- max-width: none;
112
  }
113
-
114
- .header-brand {
115
- display: flex;
116
- align-items: center;
117
- gap: var(--space-3);
 
 
 
 
 
 
 
118
  }
119
-
120
- .logo {
121
- font-size: 1.5rem;
122
- font-weight: 700;
123
- letter-spacing: -0.025em;
124
  }
125
 
126
  .header-stats {
127
  display: flex;
128
  align-items: center;
129
- gap: var(--space-6);
130
  }
131
 
132
  .stat-item {
133
  display: flex;
134
  align-items: center;
135
  gap: var(--space-2);
136
- padding: var(--space-2) var(--space-4);
137
- background: rgba(255, 255, 255, 0.1);
138
- border-radius: var(--radius-lg);
139
- border: 1px solid rgba(255, 255, 255, 0.2);
140
- backdrop-filter: blur(8px);
 
 
 
 
 
 
141
  }
142
 
143
  .stat-icon {
144
- font-size: 1.125rem;
 
 
 
 
 
 
 
145
  }
146
 
147
  .stat-text {
148
- font-size: 0.875rem;
149
- font-weight: 500;
 
150
  }
151
 
152
  .stat-number {
153
- font-size: 1rem;
154
- font-weight: 700;
155
  color: var(--primary-100);
156
  }
157
 
@@ -161,88 +169,12 @@
161
  gap: var(--space-3);
162
  }
163
 
164
- .user-info {
165
- display: flex;
166
- align-items: center;
167
- gap: var(--space-3);
168
- padding: var(--space-2) var(--space-4);
169
- background: rgba(255, 255, 255, 0.1);
170
- border-radius: var(--radius-xl);
171
- border: 1px solid rgba(255, 255, 255, 0.2);
172
- backdrop-filter: blur(8px);
173
- }
174
-
175
- .user-avatar {
176
- width: 32px;
177
- height: 32px;
178
- border-radius: 50%;
179
- background: var(--primary-500);
180
- display: flex;
181
- align-items: center;
182
- justify-content: center;
183
- font-weight: 600;
184
- font-size: 0.875rem;
185
- }
186
-
187
- .user-details {
188
- display: flex;
189
- flex-direction: column;
190
- }
191
-
192
- .user-name {
193
- font-size: 0.875rem;
194
- font-weight: 600;
195
- }
196
-
197
- .user-role {
198
- font-size: 0.75rem;
199
- opacity: 0.8;
200
- }
201
-
202
- .btn {
203
- display: inline-flex;
204
- align-items: center;
205
- justify-content: center;
206
- gap: var(--space-2);
207
- padding: var(--space-2) var(--space-4);
208
- font-size: 0.875rem;
209
- font-weight: 500;
210
- line-height: 1.25;
211
- border-radius: var(--radius-md);
212
- border: none;
213
- cursor: pointer;
214
- transition: all 0.15s ease;
215
- text-decoration: none;
216
- outline: none;
217
- white-space: nowrap;
218
- }
219
-
220
- .btn-primary {
221
- background: var(--primary-500);
222
- color: white;
223
- }
224
-
225
- .btn-primary:hover {
226
- background: var(--primary-600);
227
- transform: translateY(-1px);
228
- box-shadow: var(--shadow-md);
229
- }
230
-
231
- .btn-secondary {
232
- background: rgba(255, 255, 255, 0.1);
233
- color: white;
234
- border: 1px solid rgba(255, 255, 255, 0.2);
235
  }
236
 
237
- .btn-secondary:hover {
238
- background: rgba(255, 255, 255, 0.2);
239
- transform: translateY(-1px);
240
- }
241
-
242
- .btn-sm {
243
- padding: var(--space-1) var(--space-3);
244
- font-size: 0.8125rem;
245
- }
246
 
247
  /* Map Container */
248
  .map-container {
@@ -770,35 +702,36 @@
770
  <body>
771
  <div class="app-container">
772
  <!-- Header -->
773
- <div class="header">
774
- <div class="header-content">
775
- <div class="header-brand">
776
- <div class="logo">TreeTrack Map</div>
 
777
  </div>
778
 
779
  <div class="header-stats">
780
  <div class="stat-item">
781
- <span class="stat-icon">T</span>
782
  <span class="stat-text">Trees:</span>
783
  <span class="stat-number" id="treeCount">0</span>
784
  </div>
785
  <div class="stat-item">
786
- <span class="stat-icon">S</span>
787
  <span class="stat-text">Selected:</span>
788
  <span class="stat-number" id="selectedCount">0</span>
789
  </div>
790
  </div>
791
 
792
- <div class="header-actions">
793
- <div class="user-info" id="userInfo">
794
- <div class="user-avatar" id="userAvatar">U</div>
795
- <div class="user-details">
796
- <div class="user-name" id="userName">Loading...</div>
797
- <div class="user-role" id="userRole">User</div>
798
  </div>
799
  </div>
800
- <a href="/" class="btn btn-secondary">Add Tree</a>
801
- <button id="logoutBtn" class="btn btn-secondary">Logout</button>
802
  </div>
803
  </div>
804
  </div>
@@ -847,11 +780,11 @@
847
  </div>
848
  </div>
849
  <div class="location-actions">
850
- <button id="useLocationBtn" class="btn btn-primary">
851
- Use This Location
852
  </button>
853
- <button id="cancelBtn" class="btn btn-secondary">
854
- Cancel
855
  </button>
856
  </div>
857
  </div>
 
10
 
11
  <!-- Leaflet CSS -->
12
  <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
13
+ <link rel="stylesheet" href="/static/css/design-system.css">
14
 
15
  <style>
 
16
 
17
  :root {
18
  /* Colors */
 
92
  flex-direction: column;
93
  }
94
 
95
+ /* Map-specific header styling */
96
+ .map-header {
97
+ background: var(--gradient-forest);
98
+ position: relative;
99
+ overflow: hidden;
 
 
 
 
 
 
 
 
 
 
 
 
100
  }
101
+
102
+ .map-header::before {
103
+ content: '';
104
+ position: absolute;
105
+ top: 0;
106
+ left: 0;
107
+ right: 0;
108
+ bottom: 0;
109
+ background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 20"><defs><linearGradient id="wave" x1="0" y1="0" x2="1" y2="0"><stop offset="0%" style="stop-color:rgba(255,255,255,0.1)"/><stop offset="50%" style="stop-color:rgba(255,255,255,0.05)"/><stop offset="100%" style="stop-color:rgba(255,255,255,0.1)"/></linearGradient></defs><path d="M0,10 Q25,0 50,10 T100,10 V20 H0 Z" fill="url(%23wave)"/></svg>') repeat-x;
110
+ background-size: 200px 20px;
111
+ background-position: bottom;
112
+ animation: wave 8s linear infinite;
113
  }
114
+
115
+ @keyframes wave {
116
+ 0% { background-position-x: 0; }
117
+ 100% { background-position-x: 200px; }
 
118
  }
119
 
120
  .header-stats {
121
  display: flex;
122
  align-items: center;
123
+ gap: var(--space-4);
124
  }
125
 
126
  .stat-item {
127
  display: flex;
128
  align-items: center;
129
  gap: var(--space-2);
130
+ padding: var(--space-3) var(--space-4);
131
+ background: var(--glass-bg-dark);
132
+ border-radius: var(--radius-xl);
133
+ border: var(--glass-border);
134
+ backdrop-filter: var(--glass-blur);
135
+ transition: all var(--transition-normal);
136
+ }
137
+
138
+ .stat-item:hover {
139
+ background: rgba(255, 255, 255, 0.2);
140
+ transform: translateY(-1px);
141
  }
142
 
143
  .stat-icon {
144
+ font-size: var(--text-lg);
145
+ width: 24px;
146
+ height: 24px;
147
+ display: flex;
148
+ align-items: center;
149
+ justify-content: center;
150
+ background: rgba(255, 255, 255, 0.2);
151
+ border-radius: var(--radius-md);
152
  }
153
 
154
  .stat-text {
155
+ font-size: var(--text-sm);
156
+ font-weight: var(--font-medium);
157
+ opacity: 0.9;
158
  }
159
 
160
  .stat-number {
161
+ font-size: var(--text-lg);
162
+ font-weight: var(--font-bold);
163
  color: var(--primary-100);
164
  }
165
 
 
169
  gap: var(--space-3);
170
  }
171
 
172
+ /* Map-specific adjustments for user info */
173
+ .map-user-info {
174
+ padding: var(--space-3) var(--space-5);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  }
176
 
177
+ /* Button styles handled by design system */
 
 
 
 
 
 
 
 
178
 
179
  /* Map Container */
180
  .map-container {
 
702
  <body>
703
  <div class="app-container">
704
  <!-- Header -->
705
+ <div class="tt-header map-header">
706
+ <div class="tt-header-content">
707
+ <div class="tt-header-brand">
708
+ <div class="tt-header-logo">TreeTrack Map</div>
709
+ <div class="tt-header-subtitle">Interactive Field Research View</div>
710
  </div>
711
 
712
  <div class="header-stats">
713
  <div class="stat-item">
714
+ <span class="stat-icon">🌳</span>
715
  <span class="stat-text">Trees:</span>
716
  <span class="stat-number" id="treeCount">0</span>
717
  </div>
718
  <div class="stat-item">
719
+ <span class="stat-icon">πŸ“</span>
720
  <span class="stat-text">Selected:</span>
721
  <span class="stat-number" id="selectedCount">0</span>
722
  </div>
723
  </div>
724
 
725
+ <div class="tt-header-actions">
726
+ <div class="tt-user-info map-user-info" id="userInfo">
727
+ <div class="tt-user-avatar" id="userAvatar">U</div>
728
+ <div class="tt-user-details">
729
+ <div class="tt-user-name" id="userName">Loading...</div>
730
+ <div class="tt-user-role" id="userRole">User</div>
731
  </div>
732
  </div>
733
+ <a href="/" class="tt-btn tt-btn-secondary">🌱 Add Tree</a>
734
+ <button id="logoutBtn" class="tt-btn tt-btn-secondary">Logout</button>
735
  </div>
736
  </div>
737
  </div>
 
780
  </div>
781
  </div>
782
  <div class="location-actions">
783
+ <button id="useLocationBtn" class="tt-btn tt-btn-primary">
784
+ βœ… Use This Location
785
  </button>
786
+ <button id="cancelBtn" class="tt-btn tt-btn-secondary">
787
+ ❌ Cancel
788
  </button>
789
  </div>
790
  </div>