# Morros Atlas

Interfaz local y estática para organizar datos de Morros **observados visualmente**.

Al abrirla carga `data/morros-live.json` si existe y, si no, la muestra ficticia `data/sample-morros.json`, que está señalada como tal y no afirma datos reales. `data/morros-live.json` sí contiene observaciones reales capturadas localmente por pantalla y revisadas carta por carta; su cobertura es parcial y está descrita en el campo `notes` del propio archivo.

## Ejecutar localmente

### Con Docker Compose

```bash
docker compose up --build -d
# abrir http://localhost:8080
docker compose down
```

El contenedor escucha internamente en el puerto `8080`. Por defecto, Compose lo publica sólo en `127.0.0.1:8080`. El puerto del host puede cambiarse sin editar archivos:

```bash
PORT=9090 docker compose up --build -d
```

Para exponerlo explícitamente en todas las interfaces —por ejemplo, en un servidor con firewall o proxy inverso configurado—:

```bash
BIND_ADDRESS=0.0.0.0 PORT=8080 docker compose up --build -d
```

### Con Docker directamente

```bash
docker build -t tkscan .
docker run --rm -p 127.0.0.1:8080:8080 tkscan
```

### Sin Docker

```bash
python3 -m http.server 8080
# abrir http://localhost:8080
```

No hay dependencias de aplicación, credenciales, conexión al emulador ni API del juego. La imagen sirve únicamente `index.html`, `styles.css`, `app.js`, `README.md`, `assets/` y `data/`; el material de recolección no se incluye.

## Perfil y jerarquía

- El conjunto admite todos los gremios que se observen en Morros.
- Cada gremio tiene integrantes y cada integrante puede tener hasta **5 equipos de hasta 6 cartas**: máximo **30 cartas**.
- El listado muestra a cada integrante con su carta `main` como portada del perfil. Si el perfil observado no designa ninguna —el juego muestra un avatar, no una carta—, la portada es la carta **más fuerte** y la interfaz la etiqueta así, sin presentarla como designación del juego.
- Al abrirlo, aparecen sus cartas completas, ordenadas de **mayor a menor poder**, no por orden del equipo.
- Las cartas se leen en **tabla ordenable**: retrato, nombre, rareza, elemento con su icono, nivel, despertar en estrellas, poder y equipo. Cualquier encabezado ordena.
- El retrato de cada carta sale de la misma captura con guardas de la modal de squads; `collector/extract-card-art.py` los recorta y los deja en `assets/cards/`. No se descarga arte de ninguna fuente externa.
- Los elementos se muestran con su nombre e icono en español —Fuego, Agua, Tierra— tomados de `tokiodbimages/cardtype`. El conjunto sigue guardando la etiqueta interna con la que el detector fue calibrado; la traducción vive sólo en la interfaz.

## Tipografía

Una sola familia para todo: **Archivo variable**, auto-hospedada en `assets/fonts/` (34 KB en latín; el subconjunto latin-ext sólo se descarga si aparece un carácter que lo necesite). No hay serif ni segunda familia: la jerarquía la hacen el peso, el tamaño y el espacio.

Se auto-hospeda a propósito. La versión anterior usaba Avenir Next, que sólo existe en macOS: en cualquier otra máquina la página caía a otra fuente y se veía distinta.

La escala de roles vive en tokens (`--step--2` a `--step-3`, más `--step-data` y `--display`); ningún componente inventa un tamaño suelto. Toda cifra usa `tabular-nums slashed-zero` para que las columnas numéricas alineen y el cero no se confunda con la O.

## Modelo de datos e imágenes

`data/schema.json` es la fuente de verdad. La designación de carta `main` es **opcional**, porque un perfil observado puede no tener ninguna. Lo que nunca se admite es la ambigüedad: no puede haber más de una marca `isMain`, un `mainCardId` debe existir entre las cartas del integrante, y si ambas señales están presentes deben apuntar a la misma carta.

Cada carta debe contener `element`, `level` y `awakening`; los valores numéricos de nivel no pueden ser negativos. No se recopilan ni importan datos ni imágenes de equipamiento.

Los valores no visibles deben omitirse o ser `null`; nunca se adivinan.

## Recolección responsable

Usá `collector/collection-template.json` como bitácora de capturas. La aplicación importa únicamente JSON que el dueño de la cuenta revisó visualmente. No automatiza toques, no evita controles, no modifica BlueStacks/APKs, no llama APIs privadas ni inyecta código. OCR puede ayudar a transcribir capturas proporcionadas por el dueño, pero cada valor debe confirmarse antes de importarlo.

## Importar y exportar

**Importar JSON** valida la forma esencial: gremios/integrantes, 5 equipos, 6 cartas por equipo, 30 cartas por integrante, coherencia de la carta main cuando se declara y los campos obligatorios por carta (`element`, `level`, `awakening`). **Exportar conjunto actual** descarga el conjunto ya cargado.

## Rollback

Eliminar `Dockerfile`, `docker-compose.yml`, `.dockerignore` y `nginx/` revierte únicamente la ejecución en contenedor; el sitio estático sigue funcionando sin Docker.

Eliminar `index.html`, `styles.css`, `app.js`, `assets/`, `data/`, `collector/` y este README revierte el prototipo. `.atl/` permanece intencionalmente sin cambios.
