feat(sprint-3): biblioteca, recursos TO-BE, ROI mejorado e identidad de marca

Sprint 3 completo — 7 etapas:

- Etapa 1-2: biblioteca de procesos con agrupación por cliente (Dexie v4,
  LibraryPage, library-store, groupId/tags en Process)
- Etapa 3: modal de configuración global por proceso (horizonte, frecuencia,
  inversión, moneda) con validación y persistencia
- Etapa 4: panel de recursos rediseñado con soporte de unidades y minutos
  de utilización (utilizationMinutes + units)
- Etapa 5: recursos en escenario automatizado — motor de simulación,
  UI de edición en ActivityPanel, comparación AS-IS/TO-BE en reporte
- Etapa 6: PDF recursos automatizados, automatedAssignedResources requerido,
  561 tests pasando
- Etapa 7: identidad de marca — AppHeader gradiente naranja/magenta con logo
  InQuality en 5 páginas, favicon con logo real, logo/marca navegan a home

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 11:49:43 -03:00
parent d2746f07d1
commit 67e259e6ed
57 changed files with 4372 additions and 82 deletions

View File

@@ -0,0 +1,267 @@
# Sprint 3 — Etapa 7: Polish — Identidad de marca en la web app
## Contexto
Sos Claude Code trabajando en **InQ ROI**. Las reglas de implementación están en `simulador-web/CLAUDE.md`. El brief del sprint está en `sprints/sprint-3/BRIEF.md`.
**Estado al iniciar esta etapa:**
- Etapas 16 completadas. Sprint 3 funcionalmente completo.
- La web app no muestra en ningún lugar el nombre del producto "InQ ROI" ni el logo de InQuality. El `AppFooter` existe pero tiene texto muy tenue (`text-slate-300`) que pasa desapercibido.
- El favicon actual (`public/favicon.svg`) es un gráfico de barras azul genérico — no representa la marca InQ.
- Los logos en PNG están en `assets/` en la raíz del proyecto. Vite sirve estáticos desde `public/`. Los archivos tienen espacios en el nombre y necesitan ser copiados con nombres limpios.
**Esta etapa es de branding puro. No hay lógica de negocio, no hay stores, no hay modelos.**
---
## Objetivo
Agregar identidad visual de InQ ROI en la web app:
1. **Nuevo componente `AppHeader`:** barra naranja horizontal con logo InQuality en blanco y nombre del producto "InQ ROI". Aparece en todas las páginas principales.
2. **Logos en `public/`:** copiar los PNGs relevantes con nombres sin espacios.
3. **Favicon actualizado:** isotipo InQ naranja en lugar del gráfico de barras azul genérico.
---
## Paso 0 — Copiar logos a `public/`
Antes de cualquier código, copiar los siguientes archivos desde `assets/` a `public/`:
```bash
# Ejecutar desde simulador-web/
cp "assets/MARCA FINAL 2023 AREA DE SEGURIDAD 1 BCO.png" "public/inquality-logo-white.png"
cp "assets/MARCA FINAL 2023 AREA DE SEGURIDAD 1 COLOR.png" "public/inquality-logo-color.png"
```
Estos son archivos binarios — copiarlos sin modificar. Los nombres de destino no tienen espacios para compatibilidad con Vite.
---
## Cambios autorizados
### `public/inquality-logo-white.png` (NUEVO — binario copiado)
### `public/inquality-logo-color.png` (NUEVO — binario copiado)
### `public/favicon.svg` (MODIFICAR)
Reemplazar el contenido actual con un favicon naranja InQ. Usar el isotipo simplificado — una "Q" con el naranja de marca en un fondo redondeado:
```svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="none">
<!-- Fondo redondeado naranja InQ -->
<rect width="32" height="32" rx="7" fill="#F59845"/>
<!-- Letra "Q" en blanco — representa el producto InQ ROI -->
<text
x="16" y="23"
font-family="Georgia, 'Times New Roman', serif"
font-size="22"
font-weight="700"
fill="white"
text-anchor="middle"
>Q</text>
</svg>
```
### `src/components/AppHeader.tsx` (NUEVO)
Componente de barra de marca. Diseño: fondo degradado `#F59845 → #ED3E8F` (gradiente de identidad InQ), logo blanco a la izquierda, texto "InQ ROI" a la derecha en blanco. Altura: 44px.
```tsx
export function AppHeader() {
return (
<header
style={{
background: 'linear-gradient(135deg, #F59845 0%, #ED3E8F 100%)',
height: 44,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
paddingLeft: 20,
paddingRight: 20,
flexShrink: 0,
}}
>
{/* Logo InQuality blanco */}
<img
src="/inquality-logo-white.png"
alt="InQuality"
style={{ height: 24, objectFit: 'contain' }}
/>
{/* Nombre del producto */}
<span
style={{
color: 'white',
fontSize: 13,
fontWeight: 600,
letterSpacing: '0.04em',
opacity: 0.92,
}}
>
InQ ROI
</span>
</header>
)
}
```
**Notas de diseño:**
- El gradiente (`#F59845 → #ED3E8F`) es el gradiente de identidad definido en `CLAUDE.md`. No usar colores CONCILIA.
- El logo blanco (`/inquality-logo-white.png`) es adecuado para fondos oscuros/naranja.
- La altura 44px es la misma que la mayoría de los headers internos de la app para no generar desplazamiento visual brusco.
### `src/features/library/LibraryPage.tsx`
Agregar `<AppHeader />` como primer elemento del render raíz:
```tsx
import { AppHeader } from '@/components/AppHeader'
// En el return del componente:
return (
<div className="min-h-screen bg-background">
<AppHeader /> {/* 🆕 */}
<div className="max-w-4xl mx-auto px-6 py-8">
{/* contenido existente sin cambio */}
</div>
</div>
)
```
### `src/features/workspace/WorkspacePage.tsx`
Agregar `<AppHeader />` antes del `<header>` interno de la workspace:
```tsx
import { AppHeader } from '@/components/AppHeader'
// En el return del componente (el div raíz flex-col):
return (
<div className="h-screen flex flex-col overflow-hidden">
<AppHeader /> {/* 🆕 — encima del header del workspace */}
<header className="min-h-12 bg-white border-b border-slate-200 ...">
{/* header existente sin cambio */}
</header>
{/* resto sin cambio */}
</div>
)
```
### `src/features/report/ReportPage.tsx`
Agregar `<AppHeader />` al inicio del div raíz:
```tsx
import { AppHeader } from '@/components/AppHeader'
// En el return del componente:
return (
<TooltipProvider>
<div className="min-h-screen bg-slate-50">
<AppHeader /> {/* 🆕 */}
{/* banner stale y resto sin cambio */}
</div>
</TooltipProvider>
)
```
### `src/features/import/ImportPage.tsx`
Agregar `<AppHeader />` al inicio del div raíz de la página.
### `src/features/settings/SettingsPage.tsx`
Agregar `<AppHeader />` al inicio del div raíz de la página.
### `src/components/AppFooter.tsx`
El footer ya tiene el texto correcto. Hacerlo levemente más visible:
```tsx
// Cambiar text-slate-300 → text-slate-400 para mejor contraste
<p className="text-xs text-slate-400">
InQ ROI · Powered by InQuality · v0.1.0 · Hecho desde Paraguay 🇵🇾
</p>
```
---
## ❌ Lo que NO entra en esta etapa
- Cambios en stores, simulación, persistencia, dominio
- Cambios en componentes de UI que no sean los listados arriba
- Nuevo routing o cambios en `router.tsx`
- Modificar el logo PNG o cambiar la identidad visual establecida
- Agregar links de navegación en el `AppHeader` (solo marca, sin nav)
- `pdf-sections.ts` — el header del PDF ya tiene logo (implementado en sprints anteriores)
---
## Verificación antes de entregar
```bash
# 1. Build limpio
npm run build
# 2. Tests sin regresión
npm run test
# 3. Control de scope
git diff --name-only HEAD
```
El diff debe mostrar únicamente:
- `public/favicon.svg`
- `public/inquality-logo-white.png` (binario nuevo)
- `public/inquality-logo-color.png` (binario nuevo)
- `src/components/AppHeader.tsx` (nuevo)
- `src/features/library/LibraryPage.tsx`
- `src/features/workspace/WorkspacePage.tsx`
- `src/features/report/ReportPage.tsx`
- `src/features/import/ImportPage.tsx`
- `src/features/settings/SettingsPage.tsx`
- `src/components/AppFooter.tsx`
Si aparece cualquier archivo de `src/store/`, `src/domain/`, `src/persistence/`, o `src/lib/export/`: **revertir y reportar**.
### Verificación funcional mandatoria
Antes de reportar, verificar manualmente:
1. **Logo visible en biblioteca:** abrir la home → ver barra naranja/magenta con logo blanco de InQuality y "InQ ROI" a la derecha.
2. **Logo en workspace:** abrir un proceso → la barra aparece encima del header del proceso.
3. **Logo en reporte:** navegar al reporte → la barra está arriba de todo, incluso por encima del banner stale si existe.
4. **Logo en import:** ir a importar BPMN → la barra está presente.
5. **Logo en settings:** ir a configuración → la barra está presente.
6. **Favicon:** en el tab del browser se ve el fondo naranja con "Q", no el gráfico de barras azul.
7. **Sin regresión de layout:** el workspace no tiene scroll horizontal inesperado por la nueva barra.
---
## Criterios de aceptación
- [ ] Logo InQuality visible en las 5 páginas principales.
- [ ] Favicon actualizado a isotipo naranja InQ.
- [ ] Gradiente `#F59845 → #ED3E8F` correcto — no colores CONCILIA.
- [ ] Build sin errores TypeScript.
- [ ] Todos los tests previos siguen verdes (561).
- [ ] Validación visual del director aprobada — OK formal requerido antes de cerrar.
---
## Reporte esperado al terminar
1. Resultado de `git diff --name-only HEAD`.
2. Resultado de `npm run build` y `npm run test`.
3. Confirmación de los 7 casos de verificación funcional.
4. Cualquier decisión de iniciativa tomada (Nivel 1/2/3).
---
## Referencias
- `CLAUDE.md` — reglas de marca: gradiente `#F59845 → #ED3E8F`, no usar colores CONCILIA
- `assets/MARCA FINAL 2023 AREA DE SEGURIDAD 1 BCO.png` — logo horizontal blanco (para fondo naranja)
- `assets/MARCA FINAL 2023 AREA DE SEGURIDAD 1 COLOR.png` — logo horizontal color (para fondo blanco)
- `src/components/AppFooter.tsx` — patrón de componente de marca existente
- `methodology/PATTERNS.md` — C.7 (git diff como control preventivo)