Lukeetah commited on
Commit
a667f65
·
verified ·
1 Parent(s): e34f302

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.js +726 -0
  2. index.html +283 -19
  3. style.css +1695 -15
app.js ADDED
@@ -0,0 +1,726 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Datos de la aplicación SIB Argentina
2
+ const datosAplicacion = {
3
+ especies: [
4
+ {
5
+ id: 1,
6
+ nombre_cientifico: "Panthera onca",
7
+ nombre_comun: "Jaguar",
8
+ reino: "Animalia",
9
+ familia: "Felidae",
10
+ orden: "Carnivora",
11
+ clase: "Mammalia",
12
+ ubicacion: "Parque Nacional Iguazú, Misiones",
13
+ coordenadas: [-25.6954, -54.4367],
14
+ fecha: "2024-11-15",
15
+ estado_conservacion: "En Peligro",
16
+ observador: "Dr. María González",
17
+ descripcion: "Avistamiento nocturno cerca del río Iguazú",
18
+ imagen: "jaguar.jpg"
19
+ },
20
+ {
21
+ id: 2,
22
+ nombre_cientifico: "Vultur gryphus",
23
+ nombre_comun: "Cóndor Andino",
24
+ reino: "Animalia",
25
+ familia: "Cathartidae",
26
+ orden: "Accipitriformes",
27
+ clase: "Aves",
28
+ ubicacion: "Parque Nacional Nahuel Huapi, Río Negro",
29
+ coordenadas: [-41.0000, -71.0000],
30
+ fecha: "2024-10-28",
31
+ estado_conservacion: "En Peligro Crítico",
32
+ observador: "Carlos Mendoza",
33
+ descripcion: "Ejemplar adulto volando sobre los picos nevados",
34
+ imagen: "condor.jpg"
35
+ },
36
+ {
37
+ id: 3,
38
+ nombre_cientifico: "Eubalaena australis",
39
+ nombre_comun: "Ballena Franca Austral",
40
+ reino: "Animalia",
41
+ familia: "Balaenidae",
42
+ orden: "Mysticeti",
43
+ clase: "Mammalia",
44
+ ubicacion: "Península Valdés, Chubut",
45
+ coordenadas: [-42.5000, -64.0000],
46
+ fecha: "2024-12-01",
47
+ estado_conservacion: "Vulnerable",
48
+ observador: "Ana Rodríguez",
49
+ descripcion: "Madre con cría en aguas costeras",
50
+ imagen: "ballena.jpg"
51
+ },
52
+ {
53
+ id: 4,
54
+ nombre_cientifico: "Schinopsis lorentzii",
55
+ nombre_comun: "Quebracho Colorado",
56
+ reino: "Plantae",
57
+ familia: "Anacardiaceae",
58
+ orden: "Sapindales",
59
+ clase: "Magnoliopsida",
60
+ ubicacion: "Parque Nacional Chaco, Chaco",
61
+ coordenadas: [-26.8333, -59.6667],
62
+ fecha: "2024-09-15",
63
+ estado_conservacion: "Vulnerable",
64
+ observador: "Luis Martínez",
65
+ descripcion: "Ejemplar centenario en bosque nativo",
66
+ imagen: "quebracho.jpg"
67
+ },
68
+ {
69
+ id: 5,
70
+ nombre_cientifico: "Jacaranda mimosifolia",
71
+ nombre_comun: "Jacarandá",
72
+ reino: "Plantae",
73
+ familia: "Bignoniaceae",
74
+ orden: "Lamiales",
75
+ clase: "Magnoliopsida",
76
+ ubicacion: "Buenos Aires, Capital Federal",
77
+ coordenadas: [-34.6118, -58.3960],
78
+ fecha: "2024-11-10",
79
+ estado_conservacion: "Preocupación Menor",
80
+ observador: "Elena Vásquez",
81
+ descripcion: "Floración primaveral en ambiente urbano",
82
+ imagen: "jacaranda.jpg"
83
+ },
84
+ {
85
+ id: 6,
86
+ nombre_cientifico: "Pleurotus ostreatus",
87
+ nombre_comun: "Hongo Gírgola",
88
+ reino: "Fungi",
89
+ familia: "Pleurotaceae",
90
+ orden: "Agaricales",
91
+ clase: "Agaricomycetes",
92
+ ubicacion: "Bosque Andino, Neuquén",
93
+ coordenadas: [-40.0000, -71.0000],
94
+ fecha: "2024-08-20",
95
+ estado_conservacion: "Preocupación Menor",
96
+ observador: "Roberto Silva",
97
+ descripcion: "Crecimiento saprofítico en tronco de lenga",
98
+ imagen: "girgola.jpg"
99
+ },
100
+ {
101
+ id: 7,
102
+ nombre_cientifico: "Chrysocyon brachyurus",
103
+ nombre_comun: "Aguará Guazú",
104
+ reino: "Animalia",
105
+ familia: "Canidae",
106
+ orden: "Carnivora",
107
+ clase: "Mammalia",
108
+ ubicacion: "Parque Nacional El Impenetrable, Chaco",
109
+ coordenadas: [-25.0000, -61.0000],
110
+ fecha: "2024-10-15",
111
+ estado_conservacion: "Casi Amenazado",
112
+ observador: "Patricia Fernández",
113
+ descripcion: "Avistamiento matutino en pastizal abierto",
114
+ imagen: "aguara.jpg"
115
+ },
116
+ {
117
+ id: 8,
118
+ nombre_cientifico: "Amazona tucumana",
119
+ nombre_comun: "Loro Alisero",
120
+ reino: "Animalia",
121
+ familia: "Psittacidae",
122
+ orden: "Psittaciformes",
123
+ clase: "Aves",
124
+ ubicacion: "Selvas de Yungas, Salta",
125
+ coordenadas: [-24.5000, -65.0000],
126
+ fecha: "2024-11-20",
127
+ estado_conservacion: "En Peligro Crítico",
128
+ observador: "Diego Herrera",
129
+ descripcion: "Bandada alimentándose en frutos de laurel",
130
+ imagen: "loro.jpg"
131
+ },
132
+ {
133
+ id: 9,
134
+ nombre_cientifico: "Cecropia pachystachya",
135
+ nombre_comun: "Ambay",
136
+ reino: "Plantae",
137
+ familia: "Urticaceae",
138
+ orden: "Rosales",
139
+ clase: "Magnoliopsida",
140
+ ubicacion: "Selva Paranaense, Misiones",
141
+ coordenadas: [-25.5000, -54.5000],
142
+ fecha: "2024-08-30",
143
+ estado_conservacion: "Datos Insuficientes",
144
+ observador: "Carmen López",
145
+ descripcion: "Ejemplar joven en borde de sendero",
146
+ imagen: "ambay.jpg"
147
+ }
148
+ ],
149
+
150
+ estadisticas: {
151
+ total_especies: 13559,
152
+ especies_endemicas: 2147,
153
+ observaciones_totales: 45230,
154
+ contribuyentes: 1250,
155
+ areas_protegidas: 45
156
+ },
157
+
158
+ provincias: [
159
+ "Buenos Aires", "Catamarca", "Chaco", "Chubut", "Córdoba", "Corrientes",
160
+ "Entre Ríos", "Formosa", "Jujuy", "La Pampa", "La Rioja", "Mendoza",
161
+ "Misiones", "Neuquén", "Río Negro", "Salta", "San Juan", "San Luis",
162
+ "Santa Cruz", "Santa Fe", "Santiago del Estero", "Tierra del Fuego", "Tucumán"
163
+ ],
164
+
165
+ reinos: ["Animalia", "Plantae", "Fungi", "Chromista", "Bacteria"],
166
+
167
+ estados_conservacion: [
168
+ "En Peligro Crítico", "En Peligro", "Vulnerable",
169
+ "Casi Amenazado", "Preocupación Menor", "Datos Insuficientes"
170
+ ]
171
+ };
172
+
173
+ // Estado de la aplicación
174
+ let especiesFiltradas = [...datosAplicacion.especies];
175
+ let observacionesForo = [];
176
+
177
+ // Utilidades
178
+ function formatearFecha(fecha) {
179
+ const date = new Date(fecha);
180
+ return date.toLocaleDateString('es-AR', {
181
+ year: 'numeric',
182
+ month: 'long',
183
+ day: 'numeric'
184
+ });
185
+ }
186
+
187
+ function obtenerClaseConservacion(estado) {
188
+ if (estado === "En Peligro" || estado === "En Peligro Crítico") {
189
+ return "conservacion-peligro";
190
+ } else if (estado === "Vulnerable" || estado === "Casi Amenazado") {
191
+ return "conservacion-vulnerable";
192
+ } else {
193
+ return "conservacion-menor";
194
+ }
195
+ }
196
+
197
+ function extraerProvincia(ubicacion) {
198
+ const partes = ubicacion.split(', ');
199
+ return partes[partes.length - 1];
200
+ }
201
+
202
+ // Inicialización de la aplicación
203
+ document.addEventListener('DOMContentLoaded', function() {
204
+ inicializarAplicacion();
205
+ });
206
+
207
+ function inicializarAplicacion() {
208
+ // Configurar navegación suave
209
+ configurarNavegacion();
210
+
211
+ // Llenar selectores
212
+ llenarSelectores();
213
+
214
+ // Mostrar especies iniciales
215
+ mostrarEspecies(especiesFiltradas);
216
+
217
+ // Configurar eventos
218
+ configurarEventos();
219
+
220
+ // Inicializar foro
221
+ inicializarForo();
222
+
223
+ // Configurar fecha actual en formulario
224
+ const fechaInput = document.getElementById('fecha-obs');
225
+ if (fechaInput) {
226
+ fechaInput.valueAsDate = new Date();
227
+ }
228
+
229
+ // Mejorar el mapa con datos simulados
230
+ mejorarMapaInteractivo();
231
+
232
+ // Configurar botones de recursos
233
+ configurarBotonesRecursos();
234
+ }
235
+
236
+ function configurarNavegacion() {
237
+ const enlaces = document.querySelectorAll('.nav-link');
238
+ enlaces.forEach(enlace => {
239
+ enlace.addEventListener('click', function(e) {
240
+ e.preventDefault();
241
+ const destino = this.getAttribute('href');
242
+ const elemento = document.querySelector(destino);
243
+ if (elemento) {
244
+ elemento.scrollIntoView({
245
+ behavior: 'smooth',
246
+ block: 'start'
247
+ });
248
+ }
249
+ });
250
+ });
251
+ }
252
+
253
+ function llenarSelectores() {
254
+ // Llenar selector de provincias
255
+ const selectorProvincia = document.getElementById('provincia');
256
+ if (selectorProvincia) {
257
+ datosAplicacion.provincias.forEach(provincia => {
258
+ const option = document.createElement('option');
259
+ option.value = provincia;
260
+ option.textContent = provincia;
261
+ selectorProvincia.appendChild(option);
262
+ });
263
+ }
264
+
265
+ // Llenar selector de estados de conservación
266
+ const selectorConservacion = document.getElementById('conservacion');
267
+ if (selectorConservacion) {
268
+ datosAplicacion.estados_conservacion.forEach(estado => {
269
+ const option = document.createElement('option');
270
+ option.value = estado;
271
+ option.textContent = estado;
272
+ selectorConservacion.appendChild(option);
273
+ });
274
+ }
275
+ }
276
+
277
+ function configurarEventos() {
278
+ // Evento de filtrado
279
+ const botonFiltrar = document.getElementById('filtrar');
280
+ if (botonFiltrar) {
281
+ botonFiltrar.addEventListener('click', filtrarEspecies);
282
+ }
283
+
284
+ // Eventos de filtros en tiempo real
285
+ const filtros = ['reino', 'provincia', 'conservacion', 'buscar'];
286
+ filtros.forEach(filtroId => {
287
+ const elemento = document.getElementById(filtroId);
288
+ if (elemento) {
289
+ elemento.addEventListener('change', filtrarEspeciesEnTiempoReal);
290
+ if (filtroId === 'buscar') {
291
+ elemento.addEventListener('input', filtrarEspeciesEnTiempoReal);
292
+ }
293
+ }
294
+ });
295
+
296
+ // Evento del formulario de observación
297
+ const formulario = document.getElementById('form-observacion');
298
+ if (formulario) {
299
+ formulario.addEventListener('submit', manejarSubmitObservacion);
300
+ }
301
+ }
302
+
303
+ function filtrarEspeciesEnTiempoReal() {
304
+ // Pequeño delay para mejorar la experiencia de usuario
305
+ clearTimeout(window.filtroTimeout);
306
+ window.filtroTimeout = setTimeout(filtrarEspecies, 300);
307
+ }
308
+
309
+ function mostrarEspecies(especies) {
310
+ const grid = document.getElementById('especies-grid');
311
+ if (!grid) return;
312
+
313
+ grid.innerHTML = '';
314
+
315
+ if (especies.length === 0) {
316
+ grid.innerHTML = `
317
+ <div class="card" style="grid-column: 1 / -1;">
318
+ <div class="card__body" style="text-align: center; padding: 2rem;">
319
+ <h3>No se encontraron especies</h3>
320
+ <p>Intenta ajustar los filtros de búsqueda o prueba con términos diferentes.</p>
321
+ <button class="btn btn--secondary" onclick="limpiarFiltros()">Limpiar Filtros</button>
322
+ </div>
323
+ </div>
324
+ `;
325
+ return;
326
+ }
327
+
328
+ // Mostrar contador de resultados
329
+ const contador = document.createElement('div');
330
+ contador.className = 'resultados-contador';
331
+ contador.style.gridColumn = '1 / -1';
332
+ contador.style.marginBottom = '1rem';
333
+ contador.style.color = 'var(--color-text-secondary)';
334
+ contador.innerHTML = `Se encontraron <strong>${especies.length}</strong> especies`;
335
+ grid.appendChild(contador);
336
+
337
+ especies.forEach(especie => {
338
+ const tarjeta = crearTarjetaEspecie(especie);
339
+ grid.appendChild(tarjeta);
340
+ });
341
+ }
342
+
343
+ function limpiarFiltros() {
344
+ document.getElementById('reino').value = '';
345
+ document.getElementById('provincia').value = '';
346
+ document.getElementById('conservacion').value = '';
347
+ document.getElementById('buscar').value = '';
348
+ especiesFiltradas = [...datosAplicacion.especies];
349
+ mostrarEspecies(especiesFiltradas);
350
+ }
351
+
352
+ function crearTarjetaEspecie(especie) {
353
+ const div = document.createElement('div');
354
+ div.className = 'especie-card';
355
+
356
+ const claseConservacion = obtenerClaseConservacion(especie.estado_conservacion);
357
+ const fechaFormateada = formatearFecha(especie.fecha);
358
+
359
+ // Emoji basado en reino
360
+ const emojiReino = {
361
+ 'Animalia': '🐾',
362
+ 'Plantae': '🌿',
363
+ 'Fungi': '🍄'
364
+ };
365
+
366
+ div.innerHTML = `
367
+ <div class="especie-image">
368
+ <span>${emojiReino[especie.reino] || '🔬'} ${especie.nombre_comun}</span>
369
+ </div>
370
+ <div class="especie-info">
371
+ <h3 class="especie-nombre">${especie.nombre_comun}</h3>
372
+ <p class="especie-cientifico">${especie.nombre_cientifico}</p>
373
+ <div class="especie-meta">
374
+ <div class="meta-item">
375
+ <span class="meta-label">Reino:</span> ${especie.reino}
376
+ </div>
377
+ <div class="meta-item">
378
+ <span class="meta-label">Familia:</span> ${especie.familia}
379
+ </div>
380
+ <div class="meta-item">
381
+ <span class="meta-label">Orden:</span> ${especie.orden}
382
+ </div>
383
+ <div class="meta-item">
384
+ <span class="meta-label">Ubicación:</span> ${especie.ubicacion}
385
+ </div>
386
+ <div class="meta-item">
387
+ <span class="meta-label">Observado:</span> ${fechaFormateada}
388
+ </div>
389
+ <div class="meta-item">
390
+ <span class="meta-label">Observador:</span> ${especie.observador}
391
+ </div>
392
+ </div>
393
+ <div class="${claseConservacion}">
394
+ ${especie.estado_conservacion}
395
+ </div>
396
+ <p style="margin-top: 1rem; font-size: 0.9rem; color: var(--color-text-secondary);">
397
+ ${especie.descripcion}
398
+ </p>
399
+ </div>
400
+ `;
401
+
402
+ return div;
403
+ }
404
+
405
+ function filtrarEspecies() {
406
+ const reino = document.getElementById('reino')?.value || '';
407
+ const provincia = document.getElementById('provincia')?.value || '';
408
+ const conservacion = document.getElementById('conservacion')?.value || '';
409
+ const busqueda = document.getElementById('buscar')?.value.toLowerCase().trim() || '';
410
+
411
+ especiesFiltradas = datosAplicacion.especies.filter(especie => {
412
+ const coincideReino = !reino || especie.reino === reino;
413
+ const coincideProvincia = !provincia || extraerProvincia(especie.ubicacion) === provincia;
414
+ const coincideConservacion = !conservacion || especie.estado_conservacion === conservacion;
415
+ const coincideBusqueda = !busqueda ||
416
+ especie.nombre_cientifico.toLowerCase().includes(busqueda) ||
417
+ especie.nombre_comun.toLowerCase().includes(busqueda) ||
418
+ especie.familia.toLowerCase().includes(busqueda) ||
419
+ especie.orden.toLowerCase().includes(busqueda) ||
420
+ especie.descripcion.toLowerCase().includes(busqueda);
421
+
422
+ return coincideReino && coincideProvincia && coincideConservacion && coincideBusqueda;
423
+ });
424
+
425
+ mostrarEspecies(especiesFiltradas);
426
+ }
427
+
428
+ function manejarSubmitObservacion(e) {
429
+ e.preventDefault();
430
+
431
+ // Validar campos requeridos
432
+ const camposRequeridos = [
433
+ 'nombre-cientifico', 'nombre-comun', 'reino-form',
434
+ 'ubicacion', 'fecha-obs', 'observador'
435
+ ];
436
+
437
+ let formularioValido = true;
438
+ const errores = [];
439
+
440
+ camposRequeridos.forEach(campoId => {
441
+ const campo = document.getElementById(campoId);
442
+ if (!campo || !campo.value.trim()) {
443
+ formularioValido = false;
444
+ errores.push(`El campo ${campo ? campo.previousElementSibling.textContent : campoId} es requerido`);
445
+ }
446
+ });
447
+
448
+ if (!formularioValido) {
449
+ mostrarMensajeError('Por favor completa todos los campos requeridos:\n' + errores.join('\n'));
450
+ return;
451
+ }
452
+
453
+ const nuevaObservacion = {
454
+ id: Date.now(),
455
+ nombre_cientifico: document.getElementById('nombre-cientifico').value,
456
+ nombre_comun: document.getElementById('nombre-comun').value,
457
+ reino: document.getElementById('reino-form').value,
458
+ familia: document.getElementById('familia').value || 'No especificada',
459
+ orden: document.getElementById('orden').value || 'No especificado',
460
+ clase: 'No especificada',
461
+ ubicacion: document.getElementById('ubicacion').value,
462
+ coordenadas: document.getElementById('coordenadas').value ?
463
+ document.getElementById('coordenadas').value.split(',').map(c => parseFloat(c.trim())) :
464
+ [0, 0],
465
+ fecha: document.getElementById('fecha-obs').value,
466
+ observador: document.getElementById('observador').value,
467
+ descripcion: document.getElementById('descripcion').value || 'Sin descripción adicional',
468
+ estado_conservacion: "Dados Insuficientes",
469
+ imagen: "nueva-observacion.jpg"
470
+ };
471
+
472
+ // Agregar a la base de datos simulada
473
+ datosAplicacion.especies.push(nuevaObservacion);
474
+ especiesFiltradas = [...datosAplicacion.especies];
475
+
476
+ // Simular guardado exitoso
477
+ mostrarMensajeExito('¡Observación enviada exitosamente! Será revisada por la comunidad científica.');
478
+
479
+ // Agregar al foro
480
+ agregarObservacionAlForo(nuevaObservacion);
481
+
482
+ // Limpiar formulario
483
+ e.target.reset();
484
+ document.getElementById('fecha-obs').valueAsDate = new Date();
485
+
486
+ // Actualizar display de especies
487
+ mostrarEspecies(especiesFiltradas);
488
+ }
489
+
490
+ function mostrarMensajeExito(mensaje) {
491
+ mostrarMensaje(mensaje, 'success');
492
+ }
493
+
494
+ function mostrarMensajeError(mensaje) {
495
+ mostrarMensaje(mensaje, 'error');
496
+ }
497
+
498
+ function mostrarMensaje(mensaje, tipo) {
499
+ // Crear elemento de mensaje
500
+ const div = document.createElement('div');
501
+ div.className = `status status--${tipo}`;
502
+ div.style.position = 'fixed';
503
+ div.style.top = '20px';
504
+ div.style.right = '20px';
505
+ div.style.zIndex = '1000';
506
+ div.style.maxWidth = '400px';
507
+ div.style.whiteSpace = 'pre-line';
508
+ div.textContent = mensaje;
509
+
510
+ document.body.appendChild(div);
511
+
512
+ // Remover después de 5 segundos
513
+ setTimeout(() => {
514
+ div.remove();
515
+ }, 5000);
516
+ }
517
+
518
+ function inicializarForo() {
519
+ // Crear observaciones del foro basadas en los datos existentes
520
+ observacionesForo = datosAplicacion.especies.map((especie, index) => ({
521
+ id: especie.id,
522
+ autor: especie.observador,
523
+ fecha: especie.fecha,
524
+ especie: especie.nombre_comun,
525
+ nombre_cientifico: especie.nombre_cientifico,
526
+ ubicacion: especie.ubicacion,
527
+ descripcion: especie.descripcion,
528
+ votos: Math.floor(Math.random() * 20) + 1,
529
+ comentarios: Math.floor(Math.random() * 5),
530
+ validada: index < 3 // Las primeras 3 están validadas
531
+ }));
532
+
533
+ mostrarForo();
534
+ }
535
+
536
+ function mostrarForo() {
537
+ const container = document.getElementById('foro-container');
538
+ if (!container) return;
539
+
540
+ container.innerHTML = '';
541
+
542
+ // Agregar título de sección
543
+ const titulo = document.createElement('div');
544
+ titulo.innerHTML = `
545
+ <p style="color: var(--color-text-secondary); margin-bottom: 1.5rem;">
546
+ Observaciones recientes de la comunidad científica. Puedes votar para validar identificaciones.
547
+ </p>
548
+ `;
549
+ container.appendChild(titulo);
550
+
551
+ // Ordenar por fecha más reciente
552
+ const observacionesOrdenadas = [...observacionesForo].sort((a, b) =>
553
+ new Date(b.fecha) - new Date(a.fecha)
554
+ );
555
+
556
+ observacionesOrdenadas.forEach(observacion => {
557
+ const post = crearPostForo(observacion);
558
+ container.appendChild(post);
559
+ });
560
+ }
561
+
562
+ function crearPostForo(observacion) {
563
+ const div = document.createElement('div');
564
+ div.className = 'foro-post card';
565
+
566
+ const fechaFormateada = formatearFecha(observacion.fecha);
567
+ const statusObservacion = observacion.validada ?
568
+ '<div class="status status--success">Identificación Validada</div>' :
569
+ '<div class="status status--info">Pendiente de Validación</div>';
570
+
571
+ div.innerHTML = `
572
+ <div class="card__body">
573
+ <div class="post-header">
574
+ <div>
575
+ <div class="post-author">${observacion.autor}</div>
576
+ <div class="post-date">${fechaFormateada}</div>
577
+ </div>
578
+ ${statusObservacion}
579
+ </div>
580
+ <div class="post-content">
581
+ <h4>${observacion.especie} (<em>${observacion.nombre_cientifico}</em>)</h4>
582
+ <p><strong>Ubicación:</strong> ${observacion.ubicacion}</p>
583
+ <p>${observacion.descripcion}</p>
584
+ </div>
585
+ <div class="post-actions">
586
+ <button class="btn btn--sm btn--outline" onclick="votarObservacion(${observacion.id})"
587
+ ${observacion.validada ? 'disabled' : ''}>
588
+ 👍 ${observacion.votos} votos
589
+ </button>
590
+ <button class="btn btn--sm btn--outline" onclick="mostrarComentarios(${observacion.id})">
591
+ 💬 ${observacion.comentarios} comentarios
592
+ </button>
593
+ <button class="btn btn--sm btn--secondary" onclick="validarIdentificacion(${observacion.id})"
594
+ ${observacion.validada ? 'disabled' : ''}>
595
+ ${observacion.validada ? '✅ Validada' : 'Validar identificación'}
596
+ </button>
597
+ </div>
598
+ </div>
599
+ `;
600
+
601
+ return div;
602
+ }
603
+
604
+ function agregarObservacionAlForo(observacion) {
605
+ const nuevaObservacionForo = {
606
+ id: observacion.id,
607
+ autor: observacion.observador,
608
+ fecha: observacion.fecha,
609
+ especie: observacion.nombre_comun,
610
+ nombre_cientifico: observacion.nombre_cientifico,
611
+ ubicacion: observacion.ubicacion,
612
+ descripcion: observacion.descripcion,
613
+ votos: 0,
614
+ comentarios: 0,
615
+ validada: false
616
+ };
617
+
618
+ observacionesForo.unshift(nuevaObservacionForo);
619
+ mostrarForo();
620
+
621
+ // Scroll al foro
622
+ setTimeout(() => {
623
+ document.getElementById('foro').scrollIntoView({
624
+ behavior: 'smooth',
625
+ block: 'start'
626
+ });
627
+ }, 500);
628
+ }
629
+
630
+ function votarObservacion(id) {
631
+ const observacion = observacionesForo.find(obs => obs.id === id);
632
+ if (observacion && !observacion.validada) {
633
+ observacion.votos++;
634
+ mostrarForo();
635
+ mostrarMensajeExito(`Has votado por la observación de ${observacion.especie}`);
636
+ }
637
+ }
638
+
639
+ function validarIdentificacion(id) {
640
+ const observacion = observacionesForo.find(obs => obs.id === id);
641
+ if (observacion && !observacion.validada) {
642
+ observacion.validada = true;
643
+ observacion.votos += 5; // Bonus por validación
644
+ mostrarForo();
645
+ mostrarMensajeExito(`Has validado la identificación de ${observacion.especie}`);
646
+ }
647
+ }
648
+
649
+ function mostrarComentarios(id) {
650
+ const observacion = observacionesForo.find(obs => obs.id === id);
651
+ if (observacion) {
652
+ alert(`Comentarios para ${observacion.especie}:\n\n- Excelente fotografía, muy clara la identificación\n- ¿Podrías compartir más detalles del hábitat?\n- Confirmo la identificación, he visto ejemplares similares en la zona`);
653
+ }
654
+ }
655
+
656
+ function mejorarMapaInteractivo() {
657
+ const mapaContainer = document.querySelector('.mapa-placeholder');
658
+ if (!mapaContainer) return;
659
+
660
+ // Mejorar el contenido del mapa
661
+ mapaContainer.innerHTML = `
662
+ <div style="text-align: center; padding: 2rem;">
663
+ <h3>🗺️ Mapa Interactivo de Observaciones</h3>
664
+ <p style="margin: 1rem 0;">Distribución de especies registradas en Argentina</p>
665
+
666
+ <div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin: 2rem 0; max-width: 400px; margin-left: auto; margin-right: auto;">
667
+ <div class="card" style="padding: 1rem; text-align: center;">
668
+ <div style="font-size: 2rem;">🐾</div>
669
+ <div style="font-weight: bold; color: var(--color-error);">${datosAplicacion.especies.filter(e => e.reino === 'Animalia').length}</div>
670
+ <div style="font-size: 0.8rem;">Animalia</div>
671
+ </div>
672
+ <div class="card" style="padding: 1rem; text-align: center;">
673
+ <div style="font-size: 2rem;">🌿</div>
674
+ <div style="font-weight: bold; color: var(--color-success);">${datosAplicacion.especies.filter(e => e.reino === 'Plantae').length}</div>
675
+ <div style="font-size: 0.8rem;">Plantae</div>
676
+ </div>
677
+ <div class="card" style="padding: 1rem; text-align: center;">
678
+ <div style="font-size: 2rem;">🍄</div>
679
+ <div style="font-weight: bold; color: var(--color-warning);">${datosAplicacion.especies.filter(e => e.reino === 'Fungi').length}</div>
680
+ <div style="font-size: 0.8rem;">Fungi</div>
681
+ </div>
682
+ </div>
683
+
684
+ <div class="mapa-leyenda">
685
+ <h4>Regiones con mayor biodiversidad:</h4>
686
+ <div style="text-align: left; max-width: 300px; margin: 0 auto;">
687
+ <div style="margin: 0.5rem 0;">🔹 Misiones: Selva Paranaense</div>
688
+ <div style="margin: 0.5rem 0;">🔹 Salta: Selvas de Yungas</div>
689
+ <div style="margin: 0.5rem 0;">🔹 Chubut: Ecosistema Patagónico</div>
690
+ <div style="margin: 0.5rem 0;">🔹 Chaco: Bosque Chaqueño</div>
691
+ </div>
692
+ </div>
693
+
694
+ <button class="btn btn--primary" onclick="verMapaCompleto()" style="margin-top: 1rem;">
695
+ Ver Mapa Completo
696
+ </button>
697
+ </div>
698
+ `;
699
+ }
700
+
701
+ function verMapaCompleto() {
702
+ alert('El mapa interactivo completo se encuentra en desarrollo. Próximamente podrás:\n\n• Ver todas las observaciones georreferenciadas\n• Filtrar por especies y regiones\n• Exportar datos de ubicaciones\n• Contribuir con nuevas coordenadas GPS');
703
+ }
704
+
705
+ function configurarBotonesRecursos() {
706
+ const botones = document.querySelectorAll('.recursos .btn');
707
+ const funciones = [
708
+ () => alert('📚 Guías de Identificación\n\n• Mamíferos de Argentina\n• Aves Rapaces\n• Flora Nativa\n• Hongos Comestibles\n• Reptiles y Anfibios\n\nPróximamente disponibles para descarga.'),
709
+ () => alert('🌱 Información sobre Conservación\n\n• Estado de conservación de especies\n• Áreas protegidas de Argentina\n• Programas de conservación activos\n• Cómo contribuir a la conservación\n\nVisita nuestro portal de conservación.'),
710
+ () => alert('🔬 Proyectos de Investigación Activos\n\n• Monitoreo de jaguares en Misiones\n• Conservación del cóndor andino\n• Estudio de ballenas francas\n• Restauración de bosques nativos\n\n¡Únete como voluntario!'),
711
+ () => alert('📖 Materiales Educativos\n\n• Guías para docentes\n• Actividades para estudiantes\n• Posters de especies nativas\n• Videos educativos\n• Juegos interactivos\n\nDescarga gratuita disponible.')
712
+ ];
713
+
714
+ botones.forEach((boton, index) => {
715
+ if (funciones[index]) {
716
+ boton.onclick = funciones[index];
717
+ }
718
+ });
719
+ }
720
+
721
+ // Exportar funciones para uso global
722
+ window.votarObservacion = votarObservacion;
723
+ window.validarIdentificacion = validarIdentificacion;
724
+ window.mostrarComentarios = mostrarComentarios;
725
+ window.verMapaCompleto = verMapaCompleto;
726
+ window.limpiarFiltros = limpiarFiltros;
index.html CHANGED
@@ -1,19 +1,283 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="es">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>SIB Argentina - Sistema de Información de Biodiversidad</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ </head>
9
+ <body>
10
+ <!-- Header -->
11
+ <header class="header">
12
+ <div class="container">
13
+ <nav class="nav flex justify-between items-center">
14
+ <div class="logo">
15
+ <h1>SIB Argentina</h1>
16
+ <p>Sistema de Información de Biodiversidad</p>
17
+ </div>
18
+ <ul class="nav-menu flex gap-16">
19
+ <li><a href="#inicio" class="nav-link">Inicio</a></li>
20
+ <li><a href="#explorar" class="nav-link">Explorar</a></li>
21
+ <li><a href="#mapa" class="nav-link">Mapa</a></li>
22
+ <li><a href="#subir" class="nav-link">Subir Observación</a></li>
23
+ <li><a href="#foro" class="nav-link">Foro</a></li>
24
+ <li><a href="#recursos" class="nav-link">Recursos</a></li>
25
+ </ul>
26
+ </nav>
27
+ </div>
28
+ </header>
29
+
30
+ <!-- Hero Section -->
31
+ <section id="inicio" class="hero">
32
+ <div class="container">
33
+ <div class="hero-content">
34
+ <h1>Conservando la Biodiversidad de Argentina</h1>
35
+ <p>En el SIB recopilamos, clasificamos, ordenamos, cartografiamos y ponemos a disposición pública la información de carácter ambiental, biológico y socio-cultural de las áreas protegidas de Argentina.</p>
36
+ <div class="hero-stats flex gap-16">
37
+ <div class="stat-card card">
38
+ <div class="card__body">
39
+ <h3>13,559</h3>
40
+ <p>Especies Registradas</p>
41
+ </div>
42
+ </div>
43
+ <div class="stat-card card">
44
+ <div class="card__body">
45
+ <h3>2,147</h3>
46
+ <p>Especies Endémicas</p>
47
+ </div>
48
+ </div>
49
+ <div class="stat-card card">
50
+ <div class="card__body">
51
+ <h3>45,230</h3>
52
+ <p>Observaciones</p>
53
+ </div>
54
+ </div>
55
+ <div class="stat-card card">
56
+ <div class="card__body">
57
+ <h3>1,250</h3>
58
+ <p>Contribuyentes</p>
59
+ </div>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ </div>
64
+ </section>
65
+
66
+ <!-- Explorar Especies -->
67
+ <section id="explorar" class="explorar py-16">
68
+ <div class="container">
69
+ <h2 class="mb-8">Explorar Especies</h2>
70
+
71
+ <!-- Filtros de búsqueda -->
72
+ <div class="search-filters card mb-8">
73
+ <div class="card__body">
74
+ <div class="filters-grid">
75
+ <div class="form-group">
76
+ <label class="form-label" for="reino">Reino</label>
77
+ <select id="reino" class="form-control">
78
+ <option value="">Todos los reinos</option>
79
+ <option value="Animalia">Animalia</option>
80
+ <option value="Plantae">Plantae</option>
81
+ <option value="Fungi">Fungi</option>
82
+ <option value="Chromista">Chromista</option>
83
+ <option value="Bacteria">Bacteria</option>
84
+ </select>
85
+ </div>
86
+ <div class="form-group">
87
+ <label class="form-label" for="provincia">Provincia</label>
88
+ <select id="provincia" class="form-control">
89
+ <option value="">Todas las provincias</option>
90
+ </select>
91
+ </div>
92
+ <div class="form-group">
93
+ <label class="form-label" for="conservacion">Estado de Conservación</label>
94
+ <select id="conservacion" class="form-control">
95
+ <option value="">Todos los estados</option>
96
+ </select>
97
+ </div>
98
+ <div class="form-group">
99
+ <label class="form-label" for="buscar">Buscar Especie</label>
100
+ <input type="text" id="buscar" class="form-control" placeholder="Nombre científico o común">
101
+ </div>
102
+ </div>
103
+ <button class="btn btn--primary mt-8" id="filtrar">Filtrar Especies</button>
104
+ </div>
105
+ </div>
106
+
107
+ <!-- Grid de especies -->
108
+ <div class="especies-grid" id="especies-grid">
109
+ <!-- Se llenará dinámicamente -->
110
+ </div>
111
+ </div>
112
+ </section>
113
+
114
+ <!-- Mapa Interactivo -->
115
+ <section id="mapa" class="mapa py-16">
116
+ <div class="container">
117
+ <h2 class="mb-8">Mapa de Observaciones</h2>
118
+ <div class="mapa-container card">
119
+ <div class="card__body">
120
+ <div class="mapa-placeholder">
121
+ <h3>Mapa Interactivo de Argentina</h3>
122
+ <p>Aquí se mostraría un mapa interactivo con las observaciones de especies</p>
123
+ <div class="mapa-leyenda">
124
+ <h4>Leyenda:</h4>
125
+ <div class="leyenda-items">
126
+ <div class="leyenda-item">
127
+ <span class="marker-animalia"></span> Animalia
128
+ </div>
129
+ <div class="leyenda-item">
130
+ <span class="marker-plantae"></span> Plantae
131
+ </div>
132
+ <div class="leyenda-item">
133
+ <span class="marker-fungi"></span> Fungi
134
+ </div>
135
+ </div>
136
+ </div>
137
+ </div>
138
+ </div>
139
+ </div>
140
+ </div>
141
+ </section>
142
+
143
+ <!-- Subir Observación -->
144
+ <section id="subir" class="subir py-16">
145
+ <div class="container">
146
+ <h2 class="mb-8">Subir Nueva Observación</h2>
147
+ <div class="card">
148
+ <div class="card__body">
149
+ <form id="form-observacion">
150
+ <div class="form-grid">
151
+ <div class="form-group">
152
+ <label class="form-label" for="imagen">Fotografía de la Especie</label>
153
+ <input type="file" id="imagen" class="form-control" accept="image/*">
154
+ </div>
155
+ <div class="form-group">
156
+ <label class="form-label" for="nombre-cientifico">Nombre Científico</label>
157
+ <input type="text" id="nombre-cientifico" class="form-control" placeholder="Ejemplo: Panthera onca">
158
+ </div>
159
+ <div class="form-group">
160
+ <label class="form-label" for="nombre-comun">Nombre Común</label>
161
+ <input type="text" id="nombre-comun" class="form-control" placeholder="Ejemplo: Jaguar">
162
+ </div>
163
+ <div class="form-group">
164
+ <label class="form-label" for="reino-form">Reino</label>
165
+ <select id="reino-form" class="form-control" required>
166
+ <option value="">Seleccionar reino</option>
167
+ <option value="Animalia">Animalia</option>
168
+ <option value="Plantae">Plantae</option>
169
+ <option value="Fungi">Fungi</option>
170
+ </select>
171
+ </div>
172
+ <div class="form-group">
173
+ <label class="form-label" for="familia">Familia</label>
174
+ <input type="text" id="familia" class="form-control" placeholder="Ejemplo: Felidae">
175
+ </div>
176
+ <div class="form-group">
177
+ <label class="form-label" for="orden">Orden</label>
178
+ <input type="text" id="orden" class="form-control" placeholder="Ejemplo: Carnivora">
179
+ </div>
180
+ <div class="form-group">
181
+ <label class="form-label" for="ubicacion">Ubicación</label>
182
+ <input type="text" id="ubicacion" class="form-control" placeholder="Lugar específico y provincia">
183
+ </div>
184
+ <div class="form-group">
185
+ <label class="form-label" for="coordenadas">Coordenadas GPS</label>
186
+ <input type="text" id="coordenadas" class="form-control" placeholder="Latitud, Longitud">
187
+ </div>
188
+ <div class="form-group">
189
+ <label class="form-label" for="fecha-obs">Fecha de Observación</label>
190
+ <input type="date" id="fecha-obs" class="form-control" required>
191
+ </div>
192
+ <div class="form-group">
193
+ <label class="form-label" for="observador">Nombre del Observador</label>
194
+ <input type="text" id="observador" class="form-control" placeholder="Su nombre completo">
195
+ </div>
196
+ <div class="form-group form-group-full">
197
+ <label class="form-label" for="descripcion">Descripción de la Observación</label>
198
+ <textarea id="descripcion" class="form-control" rows="4" placeholder="Describa las condiciones de la observación, comportamiento, etc."></textarea>
199
+ </div>
200
+ </div>
201
+ <button type="submit" class="btn btn--primary btn--full-width mt-8">Subir Observación</button>
202
+ </form>
203
+ </div>
204
+ </div>
205
+ </div>
206
+ </section>
207
+
208
+ <!-- Foro Comunitario -->
209
+ <section id="foro" class="foro py-16">
210
+ <div class="container">
211
+ <h2 class="mb-8">Foro Comunitario</h2>
212
+ <div class="foro-container" id="foro-container">
213
+ <!-- Se llenará dinámicamente -->
214
+ </div>
215
+ </div>
216
+ </section>
217
+
218
+ <!-- Recursos Educativos -->
219
+ <section id="recursos" class="recursos py-16">
220
+ <div class="container">
221
+ <h2 class="mb-8">Recursos Educativos</h2>
222
+ <div class="recursos-grid">
223
+ <div class="card">
224
+ <div class="card__body">
225
+ <h3>Guías de Identificación</h3>
226
+ <p>Aprende a identificar especies nativas de Argentina con nuestras guías ilustradas.</p>
227
+ <button class="btn btn--secondary">Ver Guías</button>
228
+ </div>
229
+ </div>
230
+ <div class="card">
231
+ <div class="card__body">
232
+ <h3>Conservación</h3>
233
+ <p>Información sobre esfuerzos de conservación y cómo puedes contribuir.</p>
234
+ <button class="btn btn--secondary">Más Información</button>
235
+ </div>
236
+ </div>
237
+ <div class="card">
238
+ <div class="card__body">
239
+ <h3>Proyectos de Investigación</h3>
240
+ <p>Colabora con proyectos científicos activos en todo el país.</p>
241
+ <button class="btn btn--secondary">Ver Proyectos</button>
242
+ </div>
243
+ </div>
244
+ <div class="card">
245
+ <div class="card__body">
246
+ <h3>Materiales Educativos</h3>
247
+ <p>Recursos para educadores y estudiantes sobre biodiversidad argentina.</p>
248
+ <button class="btn btn--secondary">Descargar</button>
249
+ </div>
250
+ </div>
251
+ </div>
252
+ </div>
253
+ </section>
254
+
255
+ <!-- Footer -->
256
+ <footer class="footer">
257
+ <div class="container">
258
+ <div class="footer-content">
259
+ <div class="footer-section">
260
+ <h3>SIB Argentina</h3>
261
+ <p>Sistema de Información de Biodiversidad de Argentina</p>
262
+ </div>
263
+ <div class="footer-section">
264
+ <h4>Enlaces</h4>
265
+ <ul>
266
+ <li><a href="#inicio">Inicio</a></li>
267
+ <li><a href="#explorar">Explorar</a></li>
268
+ <li><a href="#mapa">Mapa</a></li>
269
+ <li><a href="#recursos">Recursos</a></li>
270
+ </ul>
271
+ </div>
272
+ <div class="footer-section">
273
+ <h4>Contacto</h4>
274
+ <p>Ministerio de Ambiente y Desarrollo Sostenible</p>
275
+ <p>República Argentina</p>
276
+ </div>
277
+ </div>
278
+ </div>
279
+ </footer>
280
+
281
+ <script src="app.js"></script>
282
+ </body>
283
+ </html>
style.css CHANGED
@@ -1,28 +1,1708 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
  h1 {
7
- font-size: 16px;
8
- margin-top: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  }
10
 
11
  p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  }
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
 
 
 
 
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ :root {
3
+ /* Colors */
4
+ --color-background: rgba(252, 252, 249, 1);
5
+ --color-surface: rgba(255, 255, 253, 1);
6
+ --color-text: rgba(19, 52, 59, 1);
7
+ --color-text-secondary: rgba(98, 108, 113, 1);
8
+ --color-primary: rgba(33, 128, 141, 1);
9
+ --color-primary-hover: rgba(29, 116, 128, 1);
10
+ --color-primary-active: rgba(26, 104, 115, 1);
11
+ --color-secondary: rgba(94, 82, 64, 0.12);
12
+ --color-secondary-hover: rgba(94, 82, 64, 0.2);
13
+ --color-secondary-active: rgba(94, 82, 64, 0.25);
14
+ --color-border: rgba(94, 82, 64, 0.2);
15
+ --color-btn-primary-text: rgba(252, 252, 249, 1);
16
+ --color-card-border: rgba(94, 82, 64, 0.12);
17
+ --color-card-border-inner: rgba(94, 82, 64, 0.12);
18
+ --color-error: rgba(192, 21, 47, 1);
19
+ --color-success: rgba(33, 128, 141, 1);
20
+ --color-warning: rgba(168, 75, 47, 1);
21
+ --color-info: rgba(98, 108, 113, 1);
22
+ --color-focus-ring: rgba(33, 128, 141, 0.4);
23
+ --color-select-caret: rgba(19, 52, 59, 0.8);
24
+
25
+ /* Common style patterns */
26
+ --focus-ring: 0 0 0 3px var(--color-focus-ring);
27
+ --focus-outline: 2px solid var(--color-primary);
28
+ --status-bg-opacity: 0.15;
29
+ --status-border-opacity: 0.25;
30
+ --select-caret-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23134252' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
31
+ --select-caret-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23f5f5f5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
32
+
33
+ /* RGB versions for opacity control */
34
+ --color-success-rgb: 33, 128, 141;
35
+ --color-error-rgb: 192, 21, 47;
36
+ --color-warning-rgb: 168, 75, 47;
37
+ --color-info-rgb: 98, 108, 113;
38
+
39
+ /* Typography */
40
+ --font-family-base: "FKGroteskNeue", "Geist", "Inter", -apple-system,
41
+ BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
42
+ --font-family-mono: "Berkeley Mono", ui-monospace, SFMono-Regular, Menlo,
43
+ Monaco, Consolas, monospace;
44
+ --font-size-xs: 11px;
45
+ --font-size-sm: 12px;
46
+ --font-size-base: 14px;
47
+ --font-size-md: 14px;
48
+ --font-size-lg: 16px;
49
+ --font-size-xl: 18px;
50
+ --font-size-2xl: 20px;
51
+ --font-size-3xl: 24px;
52
+ --font-size-4xl: 30px;
53
+ --font-weight-normal: 400;
54
+ --font-weight-medium: 500;
55
+ --font-weight-semibold: 550;
56
+ --font-weight-bold: 600;
57
+ --line-height-tight: 1.2;
58
+ --line-height-normal: 1.5;
59
+ --letter-spacing-tight: -0.01em;
60
+
61
+ /* Spacing */
62
+ --space-0: 0;
63
+ --space-1: 1px;
64
+ --space-2: 2px;
65
+ --space-4: 4px;
66
+ --space-6: 6px;
67
+ --space-8: 8px;
68
+ --space-10: 10px;
69
+ --space-12: 12px;
70
+ --space-16: 16px;
71
+ --space-20: 20px;
72
+ --space-24: 24px;
73
+ --space-32: 32px;
74
+
75
+ /* Border Radius */
76
+ --radius-sm: 6px;
77
+ --radius-base: 8px;
78
+ --radius-md: 10px;
79
+ --radius-lg: 12px;
80
+ --radius-full: 9999px;
81
+
82
+ /* Shadows */
83
+ --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.02);
84
+ --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.02);
85
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.04),
86
+ 0 2px 4px -1px rgba(0, 0, 0, 0.02);
87
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.04),
88
+ 0 4px 6px -2px rgba(0, 0, 0, 0.02);
89
+ --shadow-inset-sm: inset 0 1px 0 rgba(255, 255, 255, 0.15),
90
+ inset 0 -1px 0 rgba(0, 0, 0, 0.03);
91
+
92
+ /* Animation */
93
+ --duration-fast: 150ms;
94
+ --duration-normal: 250ms;
95
+ --ease-standard: cubic-bezier(0.16, 1, 0.3, 1);
96
+
97
+ /* Layout */
98
+ --container-sm: 640px;
99
+ --container-md: 768px;
100
+ --container-lg: 1024px;
101
+ --container-xl: 1280px;
102
+ }
103
+
104
+ /* Dark mode colors */
105
+ @media (prefers-color-scheme: dark) {
106
+ :root {
107
+ --color-background: rgba(31, 33, 33, 1);
108
+ --color-surface: rgba(38, 40, 40, 1);
109
+ --color-text: rgba(245, 245, 245, 1);
110
+ --color-text-secondary: rgba(167, 169, 169, 0.7);
111
+ --color-primary: rgba(50, 184, 198, 1);
112
+ --color-primary-hover: rgba(45, 166, 178, 1);
113
+ --color-primary-active: rgba(41, 150, 161, 1);
114
+ --color-secondary: rgba(119, 124, 124, 0.15);
115
+ --color-secondary-hover: rgba(119, 124, 124, 0.25);
116
+ --color-secondary-active: rgba(119, 124, 124, 0.3);
117
+ --color-border: rgba(119, 124, 124, 0.3);
118
+ --color-error: rgba(255, 84, 89, 1);
119
+ --color-success: rgba(50, 184, 198, 1);
120
+ --color-warning: rgba(230, 129, 97, 1);
121
+ --color-info: rgba(167, 169, 169, 1);
122
+ --color-focus-ring: rgba(50, 184, 198, 0.4);
123
+ --color-btn-primary-text: rgba(19, 52, 59, 1);
124
+ --color-card-border: rgba(119, 124, 124, 0.2);
125
+ --color-card-border-inner: rgba(119, 124, 124, 0.15);
126
+ --shadow-inset-sm: inset 0 1px 0 rgba(255, 255, 255, 0.1),
127
+ inset 0 -1px 0 rgba(0, 0, 0, 0.15);
128
+ --button-border-secondary: rgba(119, 124, 124, 0.2);
129
+ --color-border-secondary: rgba(119, 124, 124, 0.2);
130
+ --color-select-caret: rgba(245, 245, 245, 0.8);
131
+
132
+ /* Common style patterns - updated for dark mode */
133
+ --focus-ring: 0 0 0 3px var(--color-focus-ring);
134
+ --focus-outline: 2px solid var(--color-primary);
135
+ --status-bg-opacity: 0.15;
136
+ --status-border-opacity: 0.25;
137
+ --select-caret-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23134252' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
138
+ --select-caret-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23f5f5f5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
139
+
140
+ /* RGB versions for dark mode */
141
+ --color-success-rgb: 50, 184, 198;
142
+ --color-error-rgb: 255, 84, 89;
143
+ --color-warning-rgb: 230, 129, 97;
144
+ --color-info-rgb: 167, 169, 169;
145
+ }
146
+ }
147
+
148
+ /* Data attribute for manual theme switching */
149
+ [data-color-scheme="dark"] {
150
+ --color-background: rgba(31, 33, 33, 1);
151
+ --color-surface: rgba(38, 40, 40, 1);
152
+ --color-text: rgba(245, 245, 245, 1);
153
+ --color-text-secondary: rgba(167, 169, 169, 0.7);
154
+ --color-primary: rgba(50, 184, 198, 1);
155
+ --color-primary-hover: rgba(45, 166, 178, 1);
156
+ --color-primary-active: rgba(41, 150, 161, 1);
157
+ --color-secondary: rgba(119, 124, 124, 0.15);
158
+ --color-secondary-hover: rgba(119, 124, 124, 0.25);
159
+ --color-secondary-active: rgba(119, 124, 124, 0.3);
160
+ --color-border: rgba(119, 124, 124, 0.3);
161
+ --color-error: rgba(255, 84, 89, 1);
162
+ --color-success: rgba(50, 184, 198, 1);
163
+ --color-warning: rgba(230, 129, 97, 1);
164
+ --color-info: rgba(167, 169, 169, 1);
165
+ --color-focus-ring: rgba(50, 184, 198, 0.4);
166
+ --color-btn-primary-text: rgba(19, 52, 59, 1);
167
+ --color-card-border: rgba(119, 124, 124, 0.15);
168
+ --color-card-border-inner: rgba(119, 124, 124, 0.15);
169
+ --shadow-inset-sm: inset 0 1px 0 rgba(255, 255, 255, 0.1),
170
+ inset 0 -1px 0 rgba(0, 0, 0, 0.15);
171
+ --color-border-secondary: rgba(119, 124, 124, 0.2);
172
+ --color-select-caret: rgba(245, 245, 245, 0.8);
173
+
174
+ /* Common style patterns - updated for dark mode */
175
+ --focus-ring: 0 0 0 3px var(--color-focus-ring);
176
+ --focus-outline: 2px solid var(--color-primary);
177
+ --status-bg-opacity: 0.15;
178
+ --status-border-opacity: 0.25;
179
+ --select-caret-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23134252' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
180
+ --select-caret-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23f5f5f5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
181
+
182
+ /* RGB versions for dark mode */
183
+ --color-success-rgb: 50, 184, 198;
184
+ --color-error-rgb: 255, 84, 89;
185
+ --color-warning-rgb: 230, 129, 97;
186
+ --color-info-rgb: 167, 169, 169;
187
+ }
188
+
189
+ [data-color-scheme="light"] {
190
+ --color-background: rgba(252, 252, 249, 1);
191
+ --color-surface: rgba(255, 255, 253, 1);
192
+ --color-text: rgba(19, 52, 59, 1);
193
+ --color-text-secondary: rgba(98, 108, 113, 1);
194
+ --color-primary: rgba(33, 128, 141, 1);
195
+ --color-primary-hover: rgba(29, 116, 128, 1);
196
+ --color-primary-active: rgba(26, 104, 115, 1);
197
+ --color-secondary: rgba(94, 82, 64, 0.12);
198
+ --color-secondary-hover: rgba(94, 82, 64, 0.2);
199
+ --color-secondary-active: rgba(94, 82, 64, 0.25);
200
+ --color-border: rgba(94, 82, 64, 0.2);
201
+ --color-btn-primary-text: rgba(252, 252, 249, 1);
202
+ --color-card-border: rgba(94, 82, 64, 0.12);
203
+ --color-card-border-inner: rgba(94, 82, 64, 0.12);
204
+ --color-error: rgba(192, 21, 47, 1);
205
+ --color-success: rgba(33, 128, 141, 1);
206
+ --color-warning: rgba(168, 75, 47, 1);
207
+ --color-info: rgba(98, 108, 113, 1);
208
+ --color-focus-ring: rgba(33, 128, 141, 0.4);
209
+
210
+ /* RGB versions for light mode */
211
+ --color-success-rgb: 33, 128, 141;
212
+ --color-error-rgb: 192, 21, 47;
213
+ --color-warning-rgb: 168, 75, 47;
214
+ --color-info-rgb: 98, 108, 113;
215
+ }
216
+
217
+ /* Base styles */
218
+ html {
219
+ font-size: var(--font-size-base);
220
+ font-family: var(--font-family-base);
221
+ line-height: var(--line-height-normal);
222
+ color: var(--color-text);
223
+ background-color: var(--color-background);
224
+ -webkit-font-smoothing: antialiased;
225
+ box-sizing: border-box;
226
+ }
227
+
228
  body {
229
+ margin: 0;
230
+ padding: 0;
231
+ }
232
+
233
+ *,
234
+ *::before,
235
+ *::after {
236
+ box-sizing: inherit;
237
+ }
238
+
239
+ /* Typography */
240
+ h1,
241
+ h2,
242
+ h3,
243
+ h4,
244
+ h5,
245
+ h6 {
246
+ margin: 0;
247
+ font-weight: var(--font-weight-semibold);
248
+ line-height: var(--line-height-tight);
249
+ color: var(--color-text);
250
+ letter-spacing: var(--letter-spacing-tight);
251
  }
252
 
253
  h1 {
254
+ font-size: var(--font-size-4xl);
255
+ }
256
+ h2 {
257
+ font-size: var(--font-size-3xl);
258
+ }
259
+ h3 {
260
+ font-size: var(--font-size-2xl);
261
+ }
262
+ h4 {
263
+ font-size: var(--font-size-xl);
264
+ }
265
+ h5 {
266
+ font-size: var(--font-size-lg);
267
+ }
268
+ h6 {
269
+ font-size: var(--font-size-md);
270
  }
271
 
272
  p {
273
+ margin: 0 0 var(--space-16) 0;
274
+ }
275
+
276
+ a {
277
+ color: var(--color-primary);
278
+ text-decoration: none;
279
+ transition: color var(--duration-fast) var(--ease-standard);
280
+ }
281
+
282
+ a:hover {
283
+ color: var(--color-primary-hover);
284
+ }
285
+
286
+ code,
287
+ pre {
288
+ font-family: var(--font-family-mono);
289
+ font-size: calc(var(--font-size-base) * 0.95);
290
+ background-color: var(--color-secondary);
291
+ border-radius: var(--radius-sm);
292
+ }
293
+
294
+ code {
295
+ padding: var(--space-1) var(--space-4);
296
+ }
297
+
298
+ pre {
299
+ padding: var(--space-16);
300
+ margin: var(--space-16) 0;
301
+ overflow: auto;
302
+ border: 1px solid var(--color-border);
303
+ }
304
+
305
+ pre code {
306
+ background: none;
307
+ padding: 0;
308
+ }
309
+
310
+ /* Buttons */
311
+ .btn {
312
+ display: inline-flex;
313
+ align-items: center;
314
+ justify-content: center;
315
+ padding: var(--space-8) var(--space-16);
316
+ border-radius: var(--radius-base);
317
+ font-size: var(--font-size-base);
318
+ font-weight: 500;
319
+ line-height: 1.5;
320
+ cursor: pointer;
321
+ transition: all var(--duration-normal) var(--ease-standard);
322
+ border: none;
323
+ text-decoration: none;
324
+ position: relative;
325
+ }
326
+
327
+ .btn:focus-visible {
328
+ outline: none;
329
+ box-shadow: var(--focus-ring);
330
+ }
331
+
332
+ .btn--primary {
333
+ background: var(--color-primary);
334
+ color: var(--color-btn-primary-text);
335
+ }
336
+
337
+ .btn--primary:hover {
338
+ background: var(--color-primary-hover);
339
+ }
340
+
341
+ .btn--primary:active {
342
+ background: var(--color-primary-active);
343
+ }
344
+
345
+ .btn--secondary {
346
+ background: var(--color-secondary);
347
+ color: var(--color-text);
348
+ }
349
+
350
+ .btn--secondary:hover {
351
+ background: var(--color-secondary-hover);
352
+ }
353
+
354
+ .btn--secondary:active {
355
+ background: var(--color-secondary-active);
356
+ }
357
+
358
+ .btn--outline {
359
+ background: transparent;
360
+ border: 1px solid var(--color-border);
361
+ color: var(--color-text);
362
+ }
363
+
364
+ .btn--outline:hover {
365
+ background: var(--color-secondary);
366
+ }
367
+
368
+ .btn--sm {
369
+ padding: var(--space-4) var(--space-12);
370
+ font-size: var(--font-size-sm);
371
+ border-radius: var(--radius-sm);
372
+ }
373
+
374
+ .btn--lg {
375
+ padding: var(--space-10) var(--space-20);
376
+ font-size: var(--font-size-lg);
377
+ border-radius: var(--radius-md);
378
+ }
379
+
380
+ .btn--full-width {
381
+ width: 100%;
382
+ }
383
+
384
+ .btn:disabled {
385
+ opacity: 0.5;
386
+ cursor: not-allowed;
387
+ }
388
+
389
+ /* Form elements */
390
+ .form-control {
391
+ display: block;
392
+ width: 100%;
393
+ padding: var(--space-8) var(--space-12);
394
+ font-size: var(--font-size-md);
395
+ line-height: 1.5;
396
+ color: var(--color-text);
397
+ background-color: var(--color-surface);
398
+ border: 1px solid var(--color-border);
399
+ border-radius: var(--radius-base);
400
+ transition: border-color var(--duration-fast) var(--ease-standard),
401
+ box-shadow var(--duration-fast) var(--ease-standard);
402
+ }
403
+
404
+ textarea.form-control {
405
+ font-family: var(--font-family-base);
406
+ font-size: var(--font-size-base);
407
+ }
408
+
409
+ select.form-control {
410
+ padding: var(--space-8) var(--space-12);
411
+ -webkit-appearance: none;
412
+ -moz-appearance: none;
413
+ appearance: none;
414
+ background-image: var(--select-caret-light);
415
+ background-repeat: no-repeat;
416
+ background-position: right var(--space-12) center;
417
+ background-size: 16px;
418
+ padding-right: var(--space-32);
419
+ }
420
+
421
+ /* Add a dark mode specific caret */
422
+ @media (prefers-color-scheme: dark) {
423
+ select.form-control {
424
+ background-image: var(--select-caret-dark);
425
+ }
426
+ }
427
+
428
+ /* Also handle data-color-scheme */
429
+ [data-color-scheme="dark"] select.form-control {
430
+ background-image: var(--select-caret-dark);
431
+ }
432
+
433
+ [data-color-scheme="light"] select.form-control {
434
+ background-image: var(--select-caret-light);
435
+ }
436
+
437
+ .form-control:focus {
438
+ border-color: var(--color-primary);
439
+ outline: var(--focus-outline);
440
+ }
441
+
442
+ .form-label {
443
+ display: block;
444
+ margin-bottom: var(--space-8);
445
+ font-weight: var(--font-weight-medium);
446
+ font-size: var(--font-size-sm);
447
+ }
448
+
449
+ .form-group {
450
+ margin-bottom: var(--space-16);
451
+ }
452
+
453
+ /* Card component */
454
+ .card {
455
+ background-color: var(--color-surface);
456
+ border-radius: var(--radius-lg);
457
+ border: 1px solid var(--color-card-border);
458
+ box-shadow: var(--shadow-sm);
459
+ overflow: hidden;
460
+ transition: box-shadow var(--duration-normal) var(--ease-standard);
461
+ }
462
+
463
+ .card:hover {
464
+ box-shadow: var(--shadow-md);
465
+ }
466
+
467
+ .card__body {
468
+ padding: var(--space-16);
469
+ }
470
+
471
+ .card__header,
472
+ .card__footer {
473
+ padding: var(--space-16);
474
+ border-bottom: 1px solid var(--color-card-border-inner);
475
+ }
476
+
477
+ /* Status indicators - simplified with CSS variables */
478
+ .status {
479
+ display: inline-flex;
480
+ align-items: center;
481
+ padding: var(--space-6) var(--space-12);
482
+ border-radius: var(--radius-full);
483
+ font-weight: var(--font-weight-medium);
484
+ font-size: var(--font-size-sm);
485
+ }
486
+
487
+ .status--success {
488
+ background-color: rgba(
489
+ var(--color-success-rgb, 33, 128, 141),
490
+ var(--status-bg-opacity)
491
+ );
492
+ color: var(--color-success);
493
+ border: 1px solid
494
+ rgba(var(--color-success-rgb, 33, 128, 141), var(--status-border-opacity));
495
+ }
496
+
497
+ .status--error {
498
+ background-color: rgba(
499
+ var(--color-error-rgb, 192, 21, 47),
500
+ var(--status-bg-opacity)
501
+ );
502
+ color: var(--color-error);
503
+ border: 1px solid
504
+ rgba(var(--color-error-rgb, 192, 21, 47), var(--status-border-opacity));
505
+ }
506
+
507
+ .status--warning {
508
+ background-color: rgba(
509
+ var(--color-warning-rgb, 168, 75, 47),
510
+ var(--status-bg-opacity)
511
+ );
512
+ color: var(--color-warning);
513
+ border: 1px solid
514
+ rgba(var(--color-warning-rgb, 168, 75, 47), var(--status-border-opacity));
515
+ }
516
+
517
+ .status--info {
518
+ background-color: rgba(
519
+ var(--color-info-rgb, 98, 108, 113),
520
+ var(--status-bg-opacity)
521
+ );
522
+ color: var(--color-info);
523
+ border: 1px solid
524
+ rgba(var(--color-info-rgb, 98, 108, 113), var(--status-border-opacity));
525
+ }
526
+
527
+ /* Container layout */
528
+ .container {
529
+ width: 100%;
530
+ margin-right: auto;
531
+ margin-left: auto;
532
+ padding-right: var(--space-16);
533
+ padding-left: var(--space-16);
534
+ }
535
+
536
+ @media (min-width: 640px) {
537
+ .container {
538
+ max-width: var(--container-sm);
539
+ }
540
+ }
541
+ @media (min-width: 768px) {
542
+ .container {
543
+ max-width: var(--container-md);
544
+ }
545
+ }
546
+ @media (min-width: 1024px) {
547
+ .container {
548
+ max-width: var(--container-lg);
549
+ }
550
+ }
551
+ @media (min-width: 1280px) {
552
+ .container {
553
+ max-width: var(--container-xl);
554
+ }
555
+ }
556
+
557
+ /* Utility classes */
558
+ .flex {
559
+ display: flex;
560
+ }
561
+ .flex-col {
562
+ flex-direction: column;
563
+ }
564
+ .items-center {
565
+ align-items: center;
566
+ }
567
+ .justify-center {
568
+ justify-content: center;
569
+ }
570
+ .justify-between {
571
+ justify-content: space-between;
572
+ }
573
+ .gap-4 {
574
+ gap: var(--space-4);
575
+ }
576
+ .gap-8 {
577
+ gap: var(--space-8);
578
+ }
579
+ .gap-16 {
580
+ gap: var(--space-16);
581
+ }
582
+
583
+ .m-0 {
584
+ margin: 0;
585
+ }
586
+ .mt-8 {
587
+ margin-top: var(--space-8);
588
+ }
589
+ .mb-8 {
590
+ margin-bottom: var(--space-8);
591
+ }
592
+ .mx-8 {
593
+ margin-left: var(--space-8);
594
+ margin-right: var(--space-8);
595
+ }
596
+ .my-8 {
597
+ margin-top: var(--space-8);
598
+ margin-bottom: var(--space-8);
599
+ }
600
+
601
+ .p-0 {
602
+ padding: 0;
603
+ }
604
+ .py-8 {
605
+ padding-top: var(--space-8);
606
+ padding-bottom: var(--space-8);
607
+ }
608
+ .px-8 {
609
+ padding-left: var(--space-8);
610
+ padding-right: var(--space-8);
611
+ }
612
+ .py-16 {
613
+ padding-top: var(--space-16);
614
+ padding-bottom: var(--space-16);
615
+ }
616
+ .px-16 {
617
+ padding-left: var(--space-16);
618
+ padding-right: var(--space-16);
619
+ }
620
+
621
+ .block {
622
+ display: block;
623
+ }
624
+ .hidden {
625
+ display: none;
626
+ }
627
+
628
+ /* Accessibility */
629
+ .sr-only {
630
+ position: absolute;
631
+ width: 1px;
632
+ height: 1px;
633
+ padding: 0;
634
+ margin: -1px;
635
+ overflow: hidden;
636
+ clip: rect(0, 0, 0, 0);
637
+ white-space: nowrap;
638
+ border-width: 0;
639
+ }
640
+
641
+ :focus-visible {
642
+ outline: var(--focus-outline);
643
+ outline-offset: 2px;
644
+ }
645
+
646
+ /* Dark mode specifics */
647
+ [data-color-scheme="dark"] .btn--outline {
648
+ border: 1px solid var(--color-border-secondary);
649
+ }
650
+
651
+ @font-face {
652
+ font-family: 'FKGroteskNeue';
653
+ src: url('https://r2cdn.perplexity.ai/fonts/FKGroteskNeue.woff2')
654
+ format('woff2');
655
+ }
656
+
657
+ :root {
658
+ /* Colors */
659
+ --color-background: rgba(252, 252, 249, 1);
660
+ --color-surface: rgba(255, 255, 253, 1);
661
+ --color-text: rgba(19, 52, 59, 1);
662
+ --color-text-secondary: rgba(98, 108, 113, 1);
663
+ --color-primary: rgba(33, 128, 141, 1);
664
+ --color-primary-hover: rgba(29, 116, 128, 1);
665
+ --color-primary-active: rgba(26, 104, 115, 1);
666
+ --color-secondary: rgba(94, 82, 64, 0.12);
667
+ --color-secondary-hover: rgba(94, 82, 64, 0.2);
668
+ --color-secondary-active: rgba(94, 82, 64, 0.25);
669
+ --color-border: rgba(94, 82, 64, 0.2);
670
+ --color-btn-primary-text: rgba(252, 252, 249, 1);
671
+ --color-card-border: rgba(94, 82, 64, 0.12);
672
+ --color-card-border-inner: rgba(94, 82, 64, 0.12);
673
+ --color-error: rgba(192, 21, 47, 1);
674
+ --color-success: rgba(33, 128, 141, 1);
675
+ --color-warning: rgba(168, 75, 47, 1);
676
+ --color-info: rgba(98, 108, 113, 1);
677
+ --color-focus-ring: rgba(33, 128, 141, 0.4);
678
+ --color-select-caret: rgba(19, 52, 59, 0.8);
679
+
680
+ /* Nature-inspired colors */
681
+ --color-nature-green: rgba(76, 120, 68, 1);
682
+ --color-nature-forest: rgba(52, 73, 94, 1);
683
+ --color-nature-earth: rgba(139, 126, 102, 1);
684
+ --color-nature-water: rgba(52, 152, 219, 1);
685
+
686
+ /* Common style patterns */
687
+ --focus-ring: 0 0 0 3px var(--color-focus-ring);
688
+ --focus-outline: 2px solid var(--color-primary);
689
+ --status-bg-opacity: 0.15;
690
+ --status-border-opacity: 0.25;
691
+ --select-caret-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23134252' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
692
+ --select-caret-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23f5f5f5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
693
+
694
+ /* RGB versions for opacity control */
695
+ --color-success-rgb: 33, 128, 141;
696
+ --color-error-rgb: 192, 21, 47;
697
+ --color-warning-rgb: 168, 75, 47;
698
+ --color-info-rgb: 98, 108, 113;
699
+
700
+ /* Typography */
701
+ --font-family-base: "FKGroteskNeue", "Geist", "Inter", -apple-system,
702
+ BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
703
+ --font-family-mono: "Berkeley Mono", ui-monospace, SFMono-Regular, Menlo,
704
+ Monaco, Consolas, monospace;
705
+ --font-size-xs: 11px;
706
+ --font-size-sm: 12px;
707
+ --font-size-base: 14px;
708
+ --font-size-md: 14px;
709
+ --font-size-lg: 16px;
710
+ --font-size-xl: 18px;
711
+ --font-size-2xl: 20px;
712
+ --font-size-3xl: 24px;
713
+ --font-size-4xl: 30px;
714
+ --font-weight-normal: 400;
715
+ --font-weight-medium: 500;
716
+ --font-weight-semibold: 550;
717
+ --font-weight-bold: 600;
718
+ --line-height-tight: 1.2;
719
+ --line-height-normal: 1.5;
720
+ --letter-spacing-tight: -0.01em;
721
+
722
+ /* Spacing */
723
+ --space-0: 0;
724
+ --space-1: 1px;
725
+ --space-2: 2px;
726
+ --space-4: 4px;
727
+ --space-6: 6px;
728
+ --space-8: 8px;
729
+ --space-10: 10px;
730
+ --space-12: 12px;
731
+ --space-16: 16px;
732
+ --space-20: 20px;
733
+ --space-24: 24px;
734
+ --space-32: 32px;
735
+
736
+ /* Border Radius */
737
+ --radius-sm: 6px;
738
+ --radius-base: 8px;
739
+ --radius-md: 10px;
740
+ --radius-lg: 12px;
741
+ --radius-full: 9999px;
742
+
743
+ /* Shadows */
744
+ --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.02);
745
+ --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.02);
746
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.04),
747
+ 0 2px 4px -1px rgba(0, 0, 0, 0.02);
748
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.04),
749
+ 0 4px 6px -2px rgba(0, 0, 0, 0.02);
750
+ --shadow-inset-sm: inset 0 1px 0 rgba(255, 255, 255, 0.15),
751
+ inset 0 -1px 0 rgba(0, 0, 0, 0.03);
752
+
753
+ /* Animation */
754
+ --duration-fast: 150ms;
755
+ --duration-normal: 250ms;
756
+ --ease-standard: cubic-bezier(0.16, 1, 0.3, 1);
757
+
758
+ /* Layout */
759
+ --container-sm: 640px;
760
+ --container-md: 768px;
761
+ --container-lg: 1024px;
762
+ --container-xl: 1280px;
763
+ }
764
+
765
+ /* Dark mode colors */
766
+ @media (prefers-color-scheme: dark) {
767
+ :root {
768
+ --color-background: rgba(31, 33, 33, 1);
769
+ --color-surface: rgba(38, 40, 40, 1);
770
+ --color-text: rgba(245, 245, 245, 1);
771
+ --color-text-secondary: rgba(167, 169, 169, 0.7);
772
+ --color-primary: rgba(50, 184, 198, 1);
773
+ --color-primary-hover: rgba(45, 166, 178, 1);
774
+ --color-primary-active: rgba(41, 150, 161, 1);
775
+ --color-secondary: rgba(119, 124, 124, 0.15);
776
+ --color-secondary-hover: rgba(119, 124, 124, 0.25);
777
+ --color-secondary-active: rgba(119, 124, 124, 0.3);
778
+ --color-border: rgba(119, 124, 124, 0.3);
779
+ --color-error: rgba(255, 84, 89, 1);
780
+ --color-success: rgba(50, 184, 198, 1);
781
+ --color-warning: rgba(230, 129, 97, 1);
782
+ --color-info: rgba(167, 169, 169, 1);
783
+ --color-focus-ring: rgba(50, 184, 198, 0.4);
784
+ --color-btn-primary-text: rgba(19, 52, 59, 1);
785
+ --color-card-border: rgba(119, 124, 124, 0.2);
786
+ --color-card-border-inner: rgba(119, 124, 124, 0.15);
787
+ --shadow-inset-sm: inset 0 1px 0 rgba(255, 255, 255, 0.1),
788
+ inset 0 -1px 0 rgba(0, 0, 0, 0.15);
789
+ --button-border-secondary: rgba(119, 124, 124, 0.2);
790
+ --color-border-secondary: rgba(119, 124, 124, 0.2);
791
+ --color-select-caret: rgba(245, 245, 245, 0.8);
792
+
793
+ /* Common style patterns - updated for dark mode */
794
+ --focus-ring: 0 0 0 3px var(--color-focus-ring);
795
+ --focus-outline: 2px solid var(--color-primary);
796
+ --status-bg-opacity: 0.15;
797
+ --status-border-opacity: 0.25;
798
+ --select-caret-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23134252' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
799
+ --select-caret-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23f5f5f5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
800
+
801
+ /* RGB versions for dark mode */
802
+ --color-success-rgb: 50, 184, 198;
803
+ --color-error-rgb: 255, 84, 89;
804
+ --color-warning-rgb: 230, 129, 97;
805
+ --color-info-rgb: 167, 169, 169;
806
+ }
807
+ }
808
+
809
+ /* Data attribute for manual theme switching */
810
+ [data-color-scheme="dark"] {
811
+ --color-background: rgba(31, 33, 33, 1);
812
+ --color-surface: rgba(38, 40, 40, 1);
813
+ --color-text: rgba(245, 245, 245, 1);
814
+ --color-text-secondary: rgba(167, 169, 169, 0.7);
815
+ --color-primary: rgba(50, 184, 198, 1);
816
+ --color-primary-hover: rgba(45, 166, 178, 1);
817
+ --color-primary-active: rgba(41, 150, 161, 1);
818
+ --color-secondary: rgba(119, 124, 124, 0.15);
819
+ --color-secondary-hover: rgba(119, 124, 124, 0.25);
820
+ --color-secondary-active: rgba(119, 124, 124, 0.3);
821
+ --color-border: rgba(119, 124, 124, 0.3);
822
+ --color-error: rgba(255, 84, 89, 1);
823
+ --color-success: rgba(50, 184, 198, 1);
824
+ --color-warning: rgba(230, 129, 97, 1);
825
+ --color-info: rgba(167, 169, 169, 1);
826
+ --color-focus-ring: rgba(50, 184, 198, 0.4);
827
+ --color-btn-primary-text: rgba(19, 52, 59, 1);
828
+ --color-card-border: rgba(119, 124, 124, 0.15);
829
+ --color-card-border-inner: rgba(119, 124, 124, 0.15);
830
+ --shadow-inset-sm: inset 0 1px 0 rgba(255, 255, 255, 0.1),
831
+ inset 0 -1px 0 rgba(0, 0, 0, 0.15);
832
+ --color-border-secondary: rgba(119, 124, 124, 0.2);
833
+ --color-select-caret: rgba(245, 245, 245, 0.8);
834
+
835
+ /* Common style patterns - updated for dark mode */
836
+ --focus-ring: 0 0 0 3px var(--color-focus-ring);
837
+ --focus-outline: 2px solid var(--color-primary);
838
+ --status-bg-opacity: 0.15;
839
+ --status-border-opacity: 0.25;
840
+ --select-caret-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23134252' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
841
+ --select-caret-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23f5f5f5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
842
+
843
+ /* RGB versions for dark mode */
844
+ --color-success-rgb: 50, 184, 198;
845
+ --color-error-rgb: 255, 84, 89;
846
+ --color-warning-rgb: 230, 129, 97;
847
+ --color-info-rgb: 167, 169, 169;
848
+ }
849
+
850
+ [data-color-scheme="light"] {
851
+ --color-background: rgba(252, 252, 249, 1);
852
+ --color-surface: rgba(255, 255, 253, 1);
853
+ --color-text: rgba(19, 52, 59, 1);
854
+ --color-text-secondary: rgba(98, 108, 113, 1);
855
+ --color-primary: rgba(33, 128, 141, 1);
856
+ --color-primary-hover: rgba(29, 116, 128, 1);
857
+ --color-primary-active: rgba(26, 104, 115, 1);
858
+ --color-secondary: rgba(94, 82, 64, 0.12);
859
+ --color-secondary-hover: rgba(94, 82, 64, 0.2);
860
+ --color-secondary-active: rgba(94, 82, 64, 0.25);
861
+ --color-border: rgba(94, 82, 64, 0.2);
862
+ --color-btn-primary-text: rgba(252, 252, 249, 1);
863
+ --color-card-border: rgba(94, 82, 64, 0.12);
864
+ --color-card-border-inner: rgba(94, 82, 64, 0.12);
865
+ --color-error: rgba(192, 21, 47, 1);
866
+ --color-success: rgba(33, 128, 141, 1);
867
+ --color-warning: rgba(168, 75, 47, 1);
868
+ --color-info: rgba(98, 108, 113, 1);
869
+ --color-focus-ring: rgba(33, 128, 141, 0.4);
870
+
871
+ /* RGB versions for light mode */
872
+ --color-success-rgb: 33, 128, 141;
873
+ --color-error-rgb: 192, 21, 47;
874
+ --color-warning-rgb: 168, 75, 47;
875
+ --color-info-rgb: 98, 108, 113;
876
+ }
877
+
878
+ /* Base styles */
879
+ html {
880
+ font-size: var(--font-size-base);
881
+ font-family: var(--font-family-base);
882
+ line-height: var(--line-height-normal);
883
+ color: var(--color-text);
884
+ background-color: var(--color-background);
885
+ -webkit-font-smoothing: antialiased;
886
+ box-sizing: border-box;
887
+ scroll-behavior: smooth;
888
+ }
889
+
890
+ body {
891
+ margin: 0;
892
+ padding: 0;
893
+ }
894
+
895
+ *,
896
+ *::before,
897
+ *::after {
898
+ box-sizing: inherit;
899
+ }
900
+
901
+ /* Typography */
902
+ h1,
903
+ h2,
904
+ h3,
905
+ h4,
906
+ h5,
907
+ h6 {
908
+ margin: 0;
909
+ font-weight: var(--font-weight-semibold);
910
+ line-height: var(--line-height-tight);
911
+ color: var(--color-text);
912
+ letter-spacing: var(--letter-spacing-tight);
913
+ }
914
+
915
+ h1 {
916
+ font-size: var(--font-size-4xl);
917
+ }
918
+ h2 {
919
+ font-size: var(--font-size-3xl);
920
+ }
921
+ h3 {
922
+ font-size: var(--font-size-2xl);
923
+ }
924
+ h4 {
925
+ font-size: var(--font-size-xl);
926
+ }
927
+ h5 {
928
+ font-size: var(--font-size-lg);
929
+ }
930
+ h6 {
931
+ font-size: var(--font-size-md);
932
+ }
933
+
934
+ p {
935
+ margin: 0 0 var(--space-16) 0;
936
+ }
937
+
938
+ a {
939
+ color: var(--color-primary);
940
+ text-decoration: none;
941
+ transition: color var(--duration-fast) var(--ease-standard);
942
+ }
943
+
944
+ a:hover {
945
+ color: var(--color-primary-hover);
946
+ }
947
+
948
+ code,
949
+ pre {
950
+ font-family: var(--font-family-mono);
951
+ font-size: calc(var(--font-size-base) * 0.95);
952
+ background-color: var(--color-secondary);
953
+ border-radius: var(--radius-sm);
954
+ }
955
+
956
+ code {
957
+ padding: var(--space-1) var(--space-4);
958
+ }
959
+
960
+ pre {
961
+ padding: var(--space-16);
962
+ margin: var(--space-16) 0;
963
+ overflow: auto;
964
+ border: 1px solid var(--color-border);
965
+ }
966
+
967
+ pre code {
968
+ background: none;
969
+ padding: 0;
970
+ }
971
+
972
+ /* Buttons */
973
+ .btn {
974
+ display: inline-flex;
975
+ align-items: center;
976
+ justify-content: center;
977
+ padding: var(--space-8) var(--space-16);
978
+ border-radius: var(--radius-base);
979
+ font-size: var(--font-size-base);
980
+ font-weight: 500;
981
+ line-height: 1.5;
982
+ cursor: pointer;
983
+ transition: all var(--duration-normal) var(--ease-standard);
984
+ border: none;
985
+ text-decoration: none;
986
+ position: relative;
987
+ }
988
+
989
+ .btn:focus-visible {
990
+ outline: none;
991
+ box-shadow: var(--focus-ring);
992
+ }
993
+
994
+ .btn--primary {
995
+ background: var(--color-primary);
996
+ color: var(--color-btn-primary-text);
997
+ }
998
+
999
+ .btn--primary:hover {
1000
+ background: var(--color-primary-hover);
1001
  }
1002
 
1003
+ .btn--primary:active {
1004
+ background: var(--color-primary-active);
1005
+ }
1006
+
1007
+ .btn--secondary {
1008
+ background: var(--color-secondary);
1009
+ color: var(--color-text);
1010
+ }
1011
+
1012
+ .btn--secondary:hover {
1013
+ background: var(--color-secondary-hover);
1014
+ }
1015
+
1016
+ .btn--secondary:active {
1017
+ background: var(--color-secondary-active);
1018
+ }
1019
+
1020
+ .btn--outline {
1021
+ background: transparent;
1022
+ border: 1px solid var(--color-border);
1023
+ color: var(--color-text);
1024
+ }
1025
+
1026
+ .btn--outline:hover {
1027
+ background: var(--color-secondary);
1028
+ }
1029
+
1030
+ .btn--sm {
1031
+ padding: var(--space-4) var(--space-12);
1032
+ font-size: var(--font-size-sm);
1033
+ border-radius: var(--radius-sm);
1034
+ }
1035
+
1036
+ .btn--lg {
1037
+ padding: var(--space-10) var(--space-20);
1038
+ font-size: var(--font-size-lg);
1039
+ border-radius: var(--radius-md);
1040
+ }
1041
+
1042
+ .btn--full-width {
1043
+ width: 100%;
1044
+ }
1045
+
1046
+ .btn:disabled {
1047
+ opacity: 0.5;
1048
+ cursor: not-allowed;
1049
+ }
1050
+
1051
+ /* Form elements */
1052
+ .form-control {
1053
+ display: block;
1054
+ width: 100%;
1055
+ padding: var(--space-8) var(--space-12);
1056
+ font-size: var(--font-size-md);
1057
+ line-height: 1.5;
1058
+ color: var(--color-text);
1059
+ background-color: var(--color-surface);
1060
+ border: 1px solid var(--color-border);
1061
+ border-radius: var(--radius-base);
1062
+ transition: border-color var(--duration-fast) var(--ease-standard),
1063
+ box-shadow var(--duration-fast) var(--ease-standard);
1064
+ }
1065
+
1066
+ textarea.form-control {
1067
+ font-family: var(--font-family-base);
1068
+ font-size: var(--font-size-base);
1069
+ }
1070
+
1071
+ select.form-control {
1072
+ padding: var(--space-8) var(--space-12);
1073
+ -webkit-appearance: none;
1074
+ -moz-appearance: none;
1075
+ appearance: none;
1076
+ background-image: var(--select-caret-light);
1077
+ background-repeat: no-repeat;
1078
+ background-position: right var(--space-12) center;
1079
+ background-size: 16px;
1080
+ padding-right: var(--space-32);
1081
+ }
1082
+
1083
+ /* Add a dark mode specific caret */
1084
+ @media (prefers-color-scheme: dark) {
1085
+ select.form-control {
1086
+ background-image: var(--select-caret-dark);
1087
+ }
1088
+ }
1089
+
1090
+ /* Also handle data-color-scheme */
1091
+ [data-color-scheme="dark"] select.form-control {
1092
+ background-image: var(--select-caret-dark);
1093
+ }
1094
+
1095
+ [data-color-scheme="light"] select.form-control {
1096
+ background-image: var(--select-caret-light);
1097
+ }
1098
+
1099
+ .form-control:focus {
1100
+ border-color: var(--color-primary);
1101
+ outline: var(--focus-outline);
1102
+ }
1103
+
1104
+ .form-label {
1105
+ display: block;
1106
+ margin-bottom: var(--space-8);
1107
+ font-weight: var(--font-weight-medium);
1108
+ font-size: var(--font-size-sm);
1109
+ }
1110
+
1111
+ .form-group {
1112
+ margin-bottom: var(--space-16);
1113
+ }
1114
+
1115
+ /* Card component */
1116
  .card {
1117
+ background-color: var(--color-surface);
1118
+ border-radius: var(--radius-lg);
1119
+ border: 1px solid var(--color-card-border);
1120
+ box-shadow: var(--shadow-sm);
1121
+ overflow: hidden;
1122
+ transition: box-shadow var(--duration-normal) var(--ease-standard);
1123
+ }
1124
+
1125
+ .card:hover {
1126
+ box-shadow: var(--shadow-md);
1127
+ }
1128
+
1129
+ .card__body {
1130
+ padding: var(--space-16);
1131
+ }
1132
+
1133
+ .card__header,
1134
+ .card__footer {
1135
+ padding: var(--space-16);
1136
+ border-bottom: 1px solid var(--color-card-border-inner);
1137
+ }
1138
+
1139
+ /* Status indicators - simplified with CSS variables */
1140
+ .status {
1141
+ display: inline-flex;
1142
+ align-items: center;
1143
+ padding: var(--space-6) var(--space-12);
1144
+ border-radius: var(--radius-full);
1145
+ font-weight: var(--font-weight-medium);
1146
+ font-size: var(--font-size-sm);
1147
+ }
1148
+
1149
+ .status--success {
1150
+ background-color: rgba(
1151
+ var(--color-success-rgb, 33, 128, 141),
1152
+ var(--status-bg-opacity)
1153
+ );
1154
+ color: var(--color-success);
1155
+ border: 1px solid
1156
+ rgba(var(--color-success-rgb, 33, 128, 141), var(--status-border-opacity));
1157
+ }
1158
+
1159
+ .status--error {
1160
+ background-color: rgba(
1161
+ var(--color-error-rgb, 192, 21, 47),
1162
+ var(--status-bg-opacity)
1163
+ );
1164
+ color: var(--color-error);
1165
+ border: 1px solid
1166
+ rgba(var(--color-error-rgb, 192, 21, 47), var(--status-border-opacity));
1167
+ }
1168
+
1169
+ .status--warning {
1170
+ background-color: rgba(
1171
+ var(--color-warning-rgb, 168, 75, 47),
1172
+ var(--status-bg-opacity)
1173
+ );
1174
+ color: var(--color-warning);
1175
+ border: 1px solid
1176
+ rgba(var(--color-warning-rgb, 168, 75, 47), var(--status-border-opacity));
1177
+ }
1178
+
1179
+ .status--info {
1180
+ background-color: rgba(
1181
+ var(--color-info-rgb, 98, 108, 113),
1182
+ var(--status-bg-opacity)
1183
+ );
1184
+ color: var(--color-info);
1185
+ border: 1px solid
1186
+ rgba(var(--color-info-rgb, 98, 108, 113), var(--status-border-opacity));
1187
+ }
1188
+
1189
+ /* Container layout */
1190
+ .container {
1191
+ width: 100%;
1192
+ margin-right: auto;
1193
+ margin-left: auto;
1194
+ padding-right: var(--space-16);
1195
+ padding-left: var(--space-16);
1196
+ }
1197
+
1198
+ @media (min-width: 640px) {
1199
+ .container {
1200
+ max-width: var(--container-sm);
1201
+ }
1202
+ }
1203
+ @media (min-width: 768px) {
1204
+ .container {
1205
+ max-width: var(--container-md);
1206
+ }
1207
+ }
1208
+ @media (min-width: 1024px) {
1209
+ .container {
1210
+ max-width: var(--container-lg);
1211
+ }
1212
+ }
1213
+ @media (min-width: 1280px) {
1214
+ .container {
1215
+ max-width: var(--container-xl);
1216
+ }
1217
+ }
1218
+
1219
+ /* Utility classes */
1220
+ .flex {
1221
+ display: flex;
1222
+ }
1223
+ .flex-col {
1224
+ flex-direction: column;
1225
+ }
1226
+ .items-center {
1227
+ align-items: center;
1228
+ }
1229
+ .justify-center {
1230
+ justify-content: center;
1231
+ }
1232
+ .justify-between {
1233
+ justify-content: space-between;
1234
+ }
1235
+ .gap-4 {
1236
+ gap: var(--space-4);
1237
+ }
1238
+ .gap-8 {
1239
+ gap: var(--space-8);
1240
+ }
1241
+ .gap-16 {
1242
+ gap: var(--space-16);
1243
+ }
1244
+
1245
+ .m-0 {
1246
+ margin: 0;
1247
+ }
1248
+ .mt-8 {
1249
+ margin-top: var(--space-8);
1250
+ }
1251
+ .mb-8 {
1252
+ margin-bottom: var(--space-8);
1253
+ }
1254
+ .mx-8 {
1255
+ margin-left: var(--space-8);
1256
+ margin-right: var(--space-8);
1257
+ }
1258
+ .my-8 {
1259
+ margin-top: var(--space-8);
1260
+ margin-bottom: var(--space-8);
1261
+ }
1262
+
1263
+ .p-0 {
1264
+ padding: 0;
1265
+ }
1266
+ .py-8 {
1267
+ padding-top: var(--space-8);
1268
+ padding-bottom: var(--space-8);
1269
+ }
1270
+ .px-8 {
1271
+ padding-left: var(--space-8);
1272
+ padding-right: var(--space-8);
1273
+ }
1274
+ .py-16 {
1275
+ padding-top: var(--space-16);
1276
+ padding-bottom: var(--space-16);
1277
+ }
1278
+ .px-16 {
1279
+ padding-left: var(--space-16);
1280
+ padding-right: var(--space-16);
1281
+ }
1282
+
1283
+ .block {
1284
+ display: block;
1285
+ }
1286
+ .hidden {
1287
+ display: none;
1288
+ }
1289
+
1290
+ /* Accessibility */
1291
+ .sr-only {
1292
+ position: absolute;
1293
+ width: 1px;
1294
+ height: 1px;
1295
+ padding: 0;
1296
+ margin: -1px;
1297
+ overflow: hidden;
1298
+ clip: rect(0, 0, 0, 0);
1299
+ white-space: nowrap;
1300
+ border-width: 0;
1301
+ }
1302
+
1303
+ :focus-visible {
1304
+ outline: var(--focus-outline);
1305
+ outline-offset: 2px;
1306
+ }
1307
+
1308
+ /* Dark mode specifics */
1309
+ [data-color-scheme="dark"] .btn--outline {
1310
+ border: 1px solid var(--color-border-secondary);
1311
+ }
1312
+
1313
+ @font-face {
1314
+ font-family: 'FKGroteskNeue';
1315
+ src: url('https://r2cdn.perplexity.ai/fonts/FKGroteskNeue.woff2')
1316
+ format('woff2');
1317
+ }
1318
+
1319
+ /* Custom styles for SIB Argentina */
1320
+
1321
+ /* Header */
1322
+ .header {
1323
+ background: linear-gradient(135deg, var(--color-nature-green), var(--color-primary));
1324
+ color: white;
1325
+ padding: var(--space-16) 0;
1326
+ box-shadow: var(--shadow-lg);
1327
+ }
1328
+
1329
+ .logo h1 {
1330
+ color: white;
1331
+ font-size: var(--font-size-3xl);
1332
+ margin-bottom: var(--space-4);
1333
+ }
1334
+
1335
+ .logo p {
1336
+ color: rgba(255, 255, 255, 0.9);
1337
+ font-size: var(--font-size-sm);
1338
+ margin: 0;
1339
+ }
1340
+
1341
+ .nav-menu {
1342
+ list-style: none;
1343
+ margin: 0;
1344
+ padding: 0;
1345
+ }
1346
+
1347
+ .nav-link {
1348
+ color: white;
1349
+ font-weight: var(--font-weight-medium);
1350
+ padding: var(--space-8) var(--space-12);
1351
+ border-radius: var(--radius-base);
1352
+ transition: background-color var(--duration-fast) var(--ease-standard);
1353
+ }
1354
+
1355
+ .nav-link:hover {
1356
+ background-color: rgba(255, 255, 255, 0.1);
1357
+ color: white;
1358
  }
1359
 
1360
+ /* Hero section */
1361
+ .hero {
1362
+ background: linear-gradient(45deg, var(--color-nature-forest), var(--color-nature-water));
1363
+ color: white;
1364
+ padding: 4rem 0;
1365
+ text-align: center;
1366
  }
1367
+
1368
+ .hero-content h1 {
1369
+ color: white;
1370
+ font-size: var(--font-size-4xl);
1371
+ margin-bottom: var(--space-24);
1372
+ }
1373
+
1374
+ .hero-content p {
1375
+ font-size: var(--font-size-lg);
1376
+ margin-bottom: 2rem;
1377
+ max-width: 800px;
1378
+ margin-left: auto;
1379
+ margin-right: auto;
1380
+ opacity: 0.95;
1381
+ }
1382
+
1383
+ .hero-stats {
1384
+ justify-content: center;
1385
+ flex-wrap: wrap;
1386
+ margin-top: 2rem;
1387
+ }
1388
+
1389
+ .stat-card {
1390
+ text-align: center;
1391
+ min-width: 200px;
1392
+ }
1393
+
1394
+ .stat-card h3 {
1395
+ font-size: var(--font-size-3xl);
1396
+ color: var(--color-primary);
1397
+ margin-bottom: var(--space-8);
1398
+ }
1399
+
1400
+ .stat-card p {
1401
+ color: var(--color-text-secondary);
1402
+ margin: 0;
1403
+ }
1404
+
1405
+ /* Sections */
1406
+ .explorar,
1407
+ .mapa,
1408
+ .subir,
1409
+ .foro,
1410
+ .recursos {
1411
+ min-height: 100vh;
1412
+ padding: 4rem 0;
1413
+ }
1414
+
1415
+ .explorar {
1416
+ background: var(--color-background);
1417
+ }
1418
+
1419
+ .mapa {
1420
+ background: var(--color-surface);
1421
+ }
1422
+
1423
+ .subir {
1424
+ background: var(--color-background);
1425
+ }
1426
+
1427
+ .foro {
1428
+ background: var(--color-surface);
1429
+ }
1430
+
1431
+ .recursos {
1432
+ background: var(--color-background);
1433
+ }
1434
+
1435
+ /* Search filters */
1436
+ .search-filters {
1437
+ margin-bottom: var(--space-24);
1438
+ }
1439
+
1440
+ .filters-grid {
1441
+ display: grid;
1442
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
1443
+ gap: var(--space-16);
1444
+ }
1445
+
1446
+ /* Species grid */
1447
+ .especies-grid {
1448
+ display: grid;
1449
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
1450
+ gap: var(--space-24);
1451
+ }
1452
+
1453
+ .especie-card {
1454
+ border: 1px solid var(--color-card-border);
1455
+ border-radius: var(--radius-lg);
1456
+ overflow: hidden;
1457
+ background: var(--color-surface);
1458
+ transition: transform var(--duration-normal) var(--ease-standard), box-shadow var(--duration-normal) var(--ease-standard);
1459
+ }
1460
+
1461
+ .especie-card:hover {
1462
+ transform: translateY(-4px);
1463
+ box-shadow: var(--shadow-lg);
1464
+ }
1465
+
1466
+ .especie-image {
1467
+ width: 100%;
1468
+ height: 200px;
1469
+ background: linear-gradient(45deg, var(--color-nature-green), var(--color-nature-earth));
1470
+ display: flex;
1471
+ align-items: center;
1472
+ justify-content: center;
1473
+ color: white;
1474
+ font-weight: var(--font-weight-semibold);
1475
+ }
1476
+
1477
+ .especie-info {
1478
+ padding: var(--space-16);
1479
+ }
1480
+
1481
+ .especie-nombre {
1482
+ font-size: var(--font-size-lg);
1483
+ font-weight: var(--font-weight-semibold);
1484
+ margin-bottom: var(--space-8);
1485
+ }
1486
+
1487
+ .especie-cientifico {
1488
+ font-style: italic;
1489
+ color: var(--color-text-secondary);
1490
+ margin-bottom: var(--space-8);
1491
+ }
1492
+
1493
+ .especie-meta {
1494
+ display: flex;
1495
+ flex-direction: column;
1496
+ gap: var(--space-4);
1497
+ }
1498
+
1499
+ .meta-item {
1500
+ font-size: var(--font-size-sm);
1501
+ color: var(--color-text-secondary);
1502
+ }
1503
+
1504
+ .meta-label {
1505
+ font-weight: var(--font-weight-medium);
1506
+ }
1507
+
1508
+ /* Conservation status */
1509
+ .conservacion-peligro {
1510
+ background-color: rgba(var(--color-error-rgb), 0.1);
1511
+ color: var(--color-error);
1512
+ padding: var(--space-4) var(--space-8);
1513
+ border-radius: var(--radius-full);
1514
+ font-size: var(--font-size-sm);
1515
+ font-weight: var(--font-weight-medium);
1516
+ display: inline-block;
1517
+ margin-top: var(--space-8);
1518
+ }
1519
+
1520
+ .conservacion-vulnerable {
1521
+ background-color: rgba(var(--color-warning-rgb), 0.1);
1522
+ color: var(--color-warning);
1523
+ padding: var(--space-4) var(--space-8);
1524
+ border-radius: var(--radius-full);
1525
+ font-size: var(--font-size-sm);
1526
+ font-weight: var(--font-weight-medium);
1527
+ display: inline-block;
1528
+ margin-top: var(--space-8);
1529
+ }
1530
+
1531
+ .conservacion-menor {
1532
+ background-color: rgba(var(--color-success-rgb), 0.1);
1533
+ color: var(--color-success);
1534
+ padding: var(--space-4) var(--space-8);
1535
+ border-radius: var(--radius-full);
1536
+ font-size: var(--font-size-sm);
1537
+ font-weight: var(--font-weight-medium);
1538
+ display: inline-block;
1539
+ margin-top: var(--space-8);
1540
+ }
1541
+
1542
+ /* Mapa */
1543
+ .mapa-container {
1544
+ height: 500px;
1545
+ }
1546
+
1547
+ .mapa-placeholder {
1548
+ height: 100%;
1549
+ display: flex;
1550
+ flex-direction: column;
1551
+ align-items: center;
1552
+ justify-content: center;
1553
+ background: linear-gradient(135deg, rgba(33, 128, 141, 0.1), rgba(76, 120, 68, 0.1));
1554
+ border-radius: var(--radius-base);
1555
+ text-align: center;
1556
+ }
1557
+
1558
+ .mapa-leyenda {
1559
+ margin-top: var(--space-16);
1560
+ }
1561
+
1562
+ .leyenda-items {
1563
+ display: flex;
1564
+ gap: var(--space-16);
1565
+ margin-top: var(--space-8);
1566
+ }
1567
+
1568
+ .leyenda-item {
1569
+ display: flex;
1570
+ align-items: center;
1571
+ gap: var(--space-8);
1572
+ }
1573
+
1574
+ .marker-animalia,
1575
+ .marker-plantae,
1576
+ .marker-fungi {
1577
+ width: 16px;
1578
+ height: 16px;
1579
+ border-radius: 50%;
1580
+ }
1581
+
1582
+ .marker-animalia {
1583
+ background: var(--color-error);
1584
+ }
1585
+
1586
+ .marker-plantae {
1587
+ background: var(--color-nature-green);
1588
+ }
1589
+
1590
+ .marker-fungi {
1591
+ background: var(--color-warning);
1592
+ }
1593
+
1594
+ /* Form */
1595
+ .form-grid {
1596
+ display: grid;
1597
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
1598
+ gap: var(--space-16);
1599
+ }
1600
+
1601
+ .form-group-full {
1602
+ grid-column: 1 / -1;
1603
+ }
1604
+
1605
+ /* Foro */
1606
+ .foro-post {
1607
+ margin-bottom: var(--space-16);
1608
+ }
1609
+
1610
+ .post-header {
1611
+ display: flex;
1612
+ justify-content: space-between;
1613
+ align-items: flex-start;
1614
+ margin-bottom: var(--space-12);
1615
+ }
1616
+
1617
+ .post-author {
1618
+ font-weight: var(--font-weight-medium);
1619
+ color: var(--color-primary);
1620
+ }
1621
+
1622
+ .post-date {
1623
+ font-size: var(--font-size-sm);
1624
+ color: var(--color-text-secondary);
1625
+ }
1626
+
1627
+ .post-content {
1628
+ margin-bottom: var(--space-12);
1629
+ }
1630
+
1631
+ .post-actions {
1632
+ display: flex;
1633
+ gap: var(--space-8);
1634
+ }
1635
+
1636
+ /* Recursos */
1637
+ .recursos-grid {
1638
+ display: grid;
1639
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
1640
+ gap: var(--space-24);
1641
+ }
1642
+
1643
+ /* Footer */
1644
+ .footer {
1645
+ background: var(--color-nature-forest);
1646
+ color: white;
1647
+ padding: 2rem 0;
1648
+ margin-top: 4rem;
1649
+ }
1650
+
1651
+ .footer-content {
1652
+ display: grid;
1653
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
1654
+ gap: var(--space-24);
1655
+ }
1656
+
1657
+ .footer-section h3,
1658
+ .footer-section h4 {
1659
+ color: white;
1660
+ margin-bottom: var(--space-16);
1661
+ }
1662
+
1663
+ .footer-section ul {
1664
+ list-style: none;
1665
+ padding: 0;
1666
+ margin: 0;
1667
+ }
1668
+
1669
+ .footer-section li {
1670
+ margin-bottom: var(--space-8);
1671
+ }
1672
+
1673
+ .footer-section a {
1674
+ color: rgba(255, 255, 255, 0.8);
1675
+ transition: color var(--duration-fast) var(--ease-standard);
1676
+ }
1677
+
1678
+ .footer-section a:hover {
1679
+ color: white;
1680
+ }
1681
+
1682
+ /* Responsive */
1683
+ @media (max-width: 768px) {
1684
+ .nav-menu {
1685
+ display: none;
1686
+ }
1687
+
1688
+ .hero-stats {
1689
+ flex-direction: column;
1690
+ align-items: center;
1691
+ }
1692
+
1693
+ .stat-card {
1694
+ margin-bottom: var(--space-16);
1695
+ }
1696
+
1697
+ .filters-grid {
1698
+ grid-template-columns: 1fr;
1699
+ }
1700
+
1701
+ .especies-grid {
1702
+ grid-template-columns: 1fr;
1703
+ }
1704
+
1705
+ .form-grid {
1706
+ grid-template-columns: 1fr;
1707
+ }
1708
+ }