# Marca de la plataforma

Cómo se define la identidad visual del cliente y cómo se cambia para otro
cliente sin tocar código.

La plataforma no tiene ningún color, logo ni nombre escrito dentro de las
pantallas. Todo sale de un solo archivo, `config/branding.php`, y todo se puede
sobrescribir desde el `.env`. A partir de ahí, `App\Support\Marca` deriva la
paleta completa y la publica como variables CSS, que es lo que consumen los
componentes.

---

## 1. Cambiar de cliente en cinco minutos

### Paso 1 · Los tres archivos de logo (2 minutos)

Copie los logos del nuevo cliente a `public/img/` y conserve los nombres, o
cámbielos y ajuste el `.env` en el paso 2.

| Archivo                       | Qué es                                   | Requisito                                                    |
| ----------------------------- | ---------------------------------------- | ------------------------------------------------------------ |
| `public/img/fedef-logo-color.webp`  | Logo principal, para fondos claros | PNG o WebP con fondo transparente, alto mínimo 240 px         |
| `public/img/fedef-logo-blanco.webp` | Versión blanca, para fondos oscuros y fotografía | **Obligatoria.** Sin ella el logo se pierde sobre el verde |
| `public/img/fedef-logo-verde.webp`  | Marca reducida (isotipo) para cabeceras estrechas y móvil | Cuadrada o casi cuadrada si es posible          |
| `public/favicon.ico`                | Icono de la pestaña (navegadores antiguos) | `.ico` con varios tamaños, generado desde el isotipo   |
| `public/favicon-32.png`             | Icono de la pestaña, nítido       | 32 × 32 px, PNG con fondo transparente                          |
| `public/img/icono-192.png`          | Icono de acceso directo en Android y del escritorio | 192 × 192 px, PNG                             |
| `public/img/apple-touch-icon.png`   | Icono de acceso directo en iPhone y iPad | 180 × 180 px, PNG con fondo opaco (iOS no admite transparencia) |

Los cuatro iconos de FEDEF se generaron desde la flor del isotipo. Para otro
cliente, genere los cuatro desde su isotipo (cualquier conversor de favicon en
línea los produce a partir de un PNG cuadrado) y conserve los nombres, o
cámbielos y ajuste `MARCA_FAVICON`, `MARCA_FAVICON_PNG` y `MARCA_ICONO_192` en el
paso 2. Los enlaces `<link rel="icon">` y `<link rel="apple-touch-icon">` los
imprime `resources/views/app.blade.php`; no hay que tocarlo.

También conviene reemplazar `public/img/login-fondo.jpg`, la fotografía del
panel de ingreso (ver `docs/IMAGEN_LOGIN.md`).

### Paso 2 · Las variables de entorno (2 minutos)

Pegue este bloque en el `.env` (o en `.env.docker`) y cambie los valores. Todo
lo que no ponga usa el valor por defecto de FEDEF.

```dotenv
# --- Nombre de la aplicación -----------------------------------------------
# Este NO es una variable MARCA_*. Ya no forma parte de la identidad visual:
# el título de la pestaña lo arma resources/js/app.js con MARCA_CORTO y
# MARCA_PRODUCTO («Mi cuenta · FEDEF»; sin título de página, «OKRFEDEF»).
# APP_NAME solo queda como respaldo si la marca no llegara al navegador y como
# remitente de los correos (MAIL_FROM_NAME). Conviene dejarlo igual que
# MARCA_PRODUCTO.
APP_NAME="OKRFEDEF"

# --- Identidad -------------------------------------------------------------
MARCA_PRODUCTO="OKRFEDEF"
MARCA_CLIENTE="Fondo de Empleados del Sector Empresarial Colombiano"
MARCA_CORTO="FEDEF"
MARCA_LEMA="Creciendo Contigo"
MARCA_DESCRIPCION="Plataforma del plan estratégico: diagnóstico, apuestas, objetivos y seguimiento."

# --- Logos (rutas relativas a public/) -------------------------------------
MARCA_LOGO_COLOR="img/fedef-logo-color.webp"
MARCA_LOGO_BLANCO="img/fedef-logo-blanco.webp"
MARCA_LOGO_ISO="img/fedef-logo-verde.webp"
MARCA_FAVICON="favicon.ico"
MARCA_LOGO_ALTO_COLOR=44
MARCA_LOGO_ALTO_BLANCO=52
MARCA_LOGO_ALTO_ISO=32
MARCA_LOGO_PROPORCION=1.477

# --- Colores ---------------------------------------------------------------
MARCA_COLOR_PRIMARIO="#046600"
MARCA_COLOR_PRIMARIO_OSCURO="#023B01"
MARCA_COLOR_PRIMARIO_CLARO="#53AF07"
MARCA_COLOR_SECUNDARIO="#C4EC1B"
MARCA_COLOR_ACENTO="#FFBA00"
MARCA_COLOR_EXITO="#12803A"
MARCA_COLOR_ATENCION="#FFBA00"
MARCA_COLOR_PELIGRO="#D92D20"
MARCA_COLOR_INFORMACION="#0B6BA8"

# --- Neutros ---------------------------------------------------------------
MARCA_COLOR_FONDO="#F3F5EF"
MARCA_COLOR_SUPERFICIE="#FFFFFF"
MARCA_COLOR_SUPERFICIE_ALT="#F7F9F4"
MARCA_COLOR_BORDE="#DFE4DA"
MARCA_COLOR_BORDE_FUERTE="#7C8B78"
MARCA_COLOR_TEXTO="#0E1A0C"
MARCA_COLOR_TEXTO_TENUE="#5C6B59"
MARCA_COLOR_TEXTO_SOBRE_PRIMARIO=""

# --- Tipografía ------------------------------------------------------------
MARCA_FUENTE_TITULOS="Figtree"
MARCA_FUENTE_TEXTO="Figtree"
MARCA_FUENTE_WEB="https://fonts.bunny.net/css?family=figtree:400,500,600,700,800&display=swap"

# --- Forma -----------------------------------------------------------------
MARCA_RADIO_BASE="0.75rem"
MARCA_SOMBRA="media"
MARCA_SOMBRA_COLOR="#023B01"
MARCA_DENSIDAD="comoda"
```

Notas sobre tres valores que suelen dar dudas:

- `MARCA_COLOR_TEXTO_SOBRE_PRIMARIO` **debe dejarse vacío** salvo que el manual
  de marca del cliente obligue a un color concreto. Vacío significa «calcúlalo»,
  y el cálculo mide el contraste real: un cliente con un primario amarillo
  recibe texto oscuro automáticamente, no blanco ilegible.
- `MARCA_SOMBRA` acepta `plana`, `suave`, `media` o `marcada`. `plana` deja la
  interfaz sin sombras, útil si el cliente tiene una identidad muy gráfica.
- `MARCA_DENSIDAD` acepta `compacta`, `comoda` o `amplia`. Multiplica toda la
  escala de espaciado a la vez.

### Paso 3 · Aplicar (1 minuto)

```bash
docker compose -f docker/compose.yaml exec -T app php artisan config:clear
docker compose -f docker/compose.yaml exec -T app npm run build
```

El `config:clear` basta si solo cambió colores, textos o iconos de `MARCA_*`.
El `npm run build` hace falta únicamente si tocó archivos de `resources/`.

### Título de la pestaña

Lo compone `resources/js/app.js` a partir del objeto `window.MARCA` que imprime
`app.blade.php`: «Página · MARCA_CORTO» cuando la pantalla declara un título
(`<Head title="Mi cuenta" />` → «Mi cuenta · FEDEF») y `MARCA_PRODUCTO` a secas
cuando no lo declara. Las pantallas ponen títulos en español y sin el nombre
del producto, que ya lo añade la plantilla.

### Paso 4 · Verificar

```bash
docker compose -f docker/compose.yaml exec -T app php artisan test --filter=MarcaTest
```

La prueba mide el contraste de la paleta que quedó activa y falla si alguna
combinación baja del mínimo. Es la red de seguridad: si el cliente nuevo trae un
color imposible, se entera antes de proyectarlo en una sala.

---

## 2. Qué pasa con los colores que usted no define

Del **primario** y del **secundario** se deriva automáticamente una escala de
diez tonos, del 50 (casi blanco) al 900 (casi negro). El color que usted
configuró se conserva **exacto** en el paso 600: la marca del cliente nunca se
altera, solo se acompaña.

Para cada uno de los veinte tonos se calcula además el color de texto que se lee
encima, comparando la relación de contraste con blanco y con la tinta y
quedándose con el mayor. Ese es el sentido de las variables `…-texto`.

Los cuatro colores de estado reciben un tratamiento más corto: fondo suave,
borde, relleno y una versión «fuerte» oscurecida lo justo para leerse sobre su
propio fondo suave con 4,5 a 1.

Ejemplo con la paleta de FEDEF:

| Paso | Primario  | Texto encima | Uso habitual                          |
| ---- | --------- | ------------ | ------------------------------------- |
| 50   | `#EBF3EB` | oscuro       | fondo de una fila resaltada           |
| 100  | `#CADFC9` | oscuro       | fondo de insignia, zona seleccionada  |
| 200  | `#A8CAA6` | oscuro       | bordes de marca                       |
| 300  | `#84B482` | oscuro       | separadores fuertes, gráficas         |
| 400  | `#5F9D5C` | oscuro       | series de datos                       |
| 500  | `#368533` | claro        | estados hover claros                  |
| 600  | `#046600` | claro        | **color de marca**, botón principal   |
| 700  | `#035400` | claro        | botón principal al pasar el puntero   |
| 800  | `#034400` | claro        | botón principal pulsado               |
| 900  | `#023500` | claro        | fondos de marca profundos, cabeceras  |

---

## 3. Archivos que intervienen

| Archivo                                     | Papel                                                                 |
| ------------------------------------------- | --------------------------------------------------------------------- |
| `config/branding.php`                       | Única fuente de la identidad. Cada clave comentada.                    |
| `app/Support/Marca.php`                     | Deriva escalas, mide contraste y publica variables.                    |
| `resources/views/app.blade.php`             | Imprime `:root { … }`, el título, el favicon y la fuente web.          |
| `app/Http/Middleware/HandleInertiaRequests.php` | Comparte el objeto `marca` con el frontend.                       |
| `resources/css/tokens.css`                  | Sistema de diseño construido sobre las variables de marca.             |
| `tailwind.config.js`                        | Puente para poder escribir `bg-marca-primario`, `rounded-tarjeta`, etc.|
| `tests/Unit/MarcaTest.php`                  | Protege el cálculo y el contraste.                                     |

Nada de esto contiene valores de FEDEF escritos a mano salvo los valores por
defecto de `config/branding.php` y el respaldo de emergencia del principio de
`tokens.css` (por si la página se sirve sin el bloque del servidor).

---

## 4. Cómo se consume la marca desde el código

### Desde CSS

```css
.boton-principal {
    background: var(--marca-primario);
    color: var(--marca-primario-texto); /* claro u oscuro, ya decidido */
    border-radius: var(--radio-control);
}
```

### Desde Tailwind

```html
<button class="bg-marca-primario text-marca-sobre-primario rounded-control shadow-2">
    Guardar
</button>
```

### Desde Vue

```js
import { usePage } from '@inertiajs/vue3';

const marca = computed(() => usePage().props.marca);
// marca.value.logos.color, marca.value.corto, marca.value.colores.primario …
```

Los tonos derivados (`--marca-primario-300` y compañía) **no** viajan por
Inertia: están solo como variables CSS, que es donde se usan. Si un componente
necesita un tono en JavaScript, lo lee con
`getComputedStyle(document.documentElement).getPropertyValue('--marca-primario-300')`.

---

## 5. Lista de verificación de contraste

Ejecútela cada vez que cambie un color. Los valores de la columna derecha son
los de la paleta de FEDEF a fecha de hoy; los recalcula
`App\Support\Marca::auditoria()` y los comprueba `MarcaTest`.

| Combinación                              | Mínimo | FEDEF     |
| ---------------------------------------- | ------ | --------- |
| Texto principal sobre el fondo           | 4,5    | 16,32 ✔  |
| Texto principal sobre superficie         | 4,5    | 17,92 ✔  |
| Texto tenue sobre superficie             | 4,5    | 5,67 ✔   |
| Texto tenue sobre el fondo               | 4,5    | 5,16 ✔   |
| Texto del botón principal                | 4,5    | 7,23 ✔   |
| Primario como texto sobre superficie     | 4,5    | 7,23 ✔   |
| Borde de campo sobre superficie          | 3,0    | 3,61 ✔   |
| Texto sobre el secundario                | 4,5    | 13,11 ✔  |
| Texto sobre el acento                    | 4,5    | 10,48 ✔  |
| Aviso de éxito (texto sobre fondo suave) | 4,5    | 4,67 ✔   |
| Aviso de atención                        | 4,5    | 4,78 ✔   |
| Aviso de peligro                         | 4,5    | 4,76 ✔   |
| Aviso de información                     | 4,5    | 4,94 ✔   |
| Logo blanco sobre primario oscuro        | 4,5    | 12,89 ✔  |

Para verla en cualquier momento con la paleta activa:

```bash
docker compose -f docker/compose.yaml exec -T app php artisan tinker \
  --execute="foreach (App\Support\Marca::auditoria() as \$n => \$r) { printf('%-42s %6.2f %s%s', \$n, \$r['relacion'], \$r['cumple'] ? 'ok' : 'FALLA', PHP_EOL); }"
```

### Reglas que la herramienta no puede comprobar sola

- **Nada se explica solo con color.** Un estado en rojo lleva además texto o
  icono. Un dato en verde, una etiqueta.
- **Foco visible siempre.** `tokens.css` lo garantiza por defecto; si un
  componente pinta su propio foco, que no lo quite.
- **Área táctil de 44 × 44 px como mínimo** en todo lo que se toque desde el
  celular. Token `--toque-min`.
- **Texto grande** (24 px normal o 18,66 px en negrita) puede bajar a 3,0.
- El **acento ámbar** y el **secundario lima** son colores claros: nunca texto
  claro encima. La variable `…-texto` ya lo resuelve, pero si escribe el color a
  mano, recuérdelo.

---

## 6. Preguntas frecuentes

**Cambié un color y no pasa nada.**
Falta `php artisan config:clear`. En producción, además, `php artisan config:cache`.

**El logo se ve gigante o diminuto.**
El logo del cliente tiene otra proporción. Ajuste `MARCA_LOGO_ALTO_*` y
`MARCA_LOGO_PROPORCION` en vez de retocar cada pantalla.

**El día del retiro no habrá internet.**
La fuente web se descarga de un servidor externo. Ponga `MARCA_FUENTE_WEB=""`
para desactivarla: la plataforma usará las fuentes del sistema y la maqueta no
cambia, porque las pilas de alternativas están definidas. Conviene probarlo
antes con el portátil sin red.

**Quiero una plataforma sin sombras y con esquinas rectas.**
`MARCA_SOMBRA=plana` y `MARCA_RADIO_BASE=0`. Todos los radios del sistema son
múltiplos del base, así que la interfaz entera queda recta.

**¿Modo oscuro?**
Existe, pero no se fuerza: la plataforma es clara por decisión de marca y así se
proyecta. Se activa poniendo `data-tema="oscuro"` en el elemento raíz, o
`data-tema="auto"` para seguir al sistema operativo. Sin ese atributo no ocurre
nada.

---

## 7. Iconos de la pestaña y del celular

Cómo se compone el título de la pestaña está en la sección 1 («Título de la
pestaña»). Aquí, los archivos de icono.

Todos se generaron desde la flor del logotipo de FEDEF. Para otro cliente se
reemplazan los cuatro y se conservan los nombres (o se cambian en el `.env`).

| Archivo                          | Clave en `config/branding.php` | Variable de entorno   | Dónde se usa                                             |
| -------------------------------- | ------------------------------ | --------------------- | -------------------------------------------------------- |
| `public/favicon.ico`             | `logos.favicon`                | `MARCA_FAVICON`       | Pestaña del navegador. Multitamaño: 16, 32, 48 y 64 px   |
| `public/favicon-32.png`          | `logos.favicon_png`            | `MARCA_FAVICON_PNG`   | Navegadores que prefieren PNG (32 × 32)                  |
| `public/img/icono-192.png`       | `logos.icono_192`              | `MARCA_ICONO_192`     | Android y acceso directo en la pantalla de inicio        |
| `public/img/apple-touch-icon.png`| `logos.iso`                    | `MARCA_LOGO_ISO`      | iPhone e iPad al «añadir a pantalla de inicio»; también es la marca reducida (`ApplicationMark`) |

Los cuatro se enlazan en `resources/views/app.blade.php` (`<link rel="icon">`
y `<link rel="apple-touch-icon">`), y `<meta name="theme-color">` toma el
color primario para teñir la barra del navegador en el celular.

Recomendaciones para el icono de otro cliente:

- Usar el **isotipo** (la parte gráfica), nunca el logotipo con texto: a 16 px
  el texto no se lee.
- Fondo del color primario con el símbolo en blanco, o símbolo a color sobre
  fondo transparente si tiene suficiente contraste sobre blanco y sobre gris.
- Generar el `.ico` con varios tamaños dentro; un PNG renombrado a `.ico` se ve
  borroso en Windows.
- Tras reemplazar los archivos, `php artisan config:clear` si cambió alguna
  clave; los navegadores guardan el icono en caché, así que puede hacer falta
  recargar con la caché vacía para verlo.
- La cabecera de la aplicación (`AppLayout`) muestra el logotipo a color
  (`MARCA_LOGO_COLOR`) al alto que declara `MARCA_LOGO_ALTO_COLOR`; en celular
  se contiene a 40 px. La marca reducida (`ApplicationMark`) toma `logos.iso`.
