# review-mockup — E250-C0094

**Aprobada:** `v1-text-acciones-button.html`
**Motivo:** es la única variante que rotula la estrategia con la copy literal que el contrato exige (SPEC-PAN-10 y su ejemplo: "Coincidencia exacta" / "Por cercanía" / "Por cercanía (15 min)" — minutos entre paréntesis), se mantiene estrictamente en alcance, y reproduce con máxima fidelidad la densidad y estructura del `PanelExperiencesView.vue` real. Verificada visualmente con Playwright: nombre con id degradado a subtítulo, nueva columna "Casado de horas" entre Unidades y Estado, y dropdown DaisyUI único con `stopPropagation` y condicionalidad correcta (fila 1 completa+escritura muestra las 3 acciones; fila 3 incompleta omite "Código de inserción").

Las tres variantes son coherentes con el shell real (mismo `max-w-6xl`, card+header+table, subtítulos `TT ·`/`VT ·` en `font-mono`, badges de estado `badge-success`/`badge-warning`, bloque de tema `e250`, banner+badge "MOCKUP — no producción" presentes) y cubren los tres cambios del contrato. Lo que las separa es la presentación de la columna de estrategia y la fidelidad a la copy del contrato.

## Findings por variante

### v1-text-acciones-button.html (aprobada)
- ✅ Tema e250, DaisyUI semántico (`card`, `table table-sm`, `dropdown`, `menu`, `badge`, `btn btn-ghost`), banner+badge de mockup presentes.
- ✅ Copy de estrategia exacta a contrato, incluida "Por cercanía (15 min)" entre paréntesis tal como dicta el ejemplo de SPEC-PAN-10.
- ✅ Dropdown con `onclick="event.stopPropagation()"` en el contenedor → abrir el menú o usar sus acciones no dispara la navegación de la fila (en el real será `@click.stop`, ya usado hoy en los botones sueltos).
- ✅ Condicionalidad cubierta: fila 3 incompleta omite "Código de inserción".
- [ ] Menor: el trigger es un `<div role="button" class="btn btn-ghost btn-xs">` con texto "Acciones ▾". Al implementar por TDD, conviene un `aria-label`/foco coherente (las otras variantes ya añaden `aria-label="Acciones"` al kebab) — no bloqueante.
- [ ] Cobertura de condicionalidad incompleta respecto al contrato: v1 sólo ejemplifica el caso "incompleta" (omite Código de inserción) pero no el caso "sin permiso de escritura" (omite Editar). No es un defecto del mockup (la regla está clara en el contrato y v2 sí lo ilustra), pero `build-frontend` debe cubrir ambas omisiones por separado.

### v2-badge-kebab-icon.html
- ✅ Kebab `⋮` (`btn-square`, `aria-label`) compacto y limpio; ilustra el caso más restrictivo del menú (fila 3 incompleta + sólo lectura → sólo "Diagnosticar horas"), lo que documenta mejor la condicionalidad.
- [ ] **Bloqueante para aprobar v2:** la estrategia "Coincidencia exacta" usa `badge badge-ghost`, que en el tema e250 se renderiza casi invisible (sin borde, se confunde con texto plano), mientras que las filas "Por cercanía" llevan `badge-info badge-outline` con borde de color. Resultado: la columna se ve inconsistente — dos valores parecen badges y uno parece texto suelto. Fix: o dar a la exacta un badge con borde visible (p.ej. `badge-ghost` + `badge-outline`, o `badge-neutral badge-outline`), o renunciar al badge y usar texto en las tres (que es justo v1).

### v3-icon-label-kebab.html
- ✅ Columna de estrategia visualmente consistente entre las tres filas (icono + etiqueta); el kebab es idéntico al de v2.
- [ ] **Bloqueante para aprobar v3:** desvía de la copy literal del contrato. SPEC-PAN-10 y su ejemplo exigen "Por cercanía (15 min)" con los minutos entre paréntesis; v3 baja la tolerancia a una segunda línea "tolerancia 15 min", una redacción/formato que el contrato no contempla y que contradice el ejemplo. Fix: rotular entre paréntesis como exige el contrato (o, si se quiere proponer el cambio de copy, hacerlo en el contrato primero, no en el mockup).
- [ ] Fuera de alcance menor: los iconos semánticos `◎`/`≈` son adorno no pedido por el contrato; añaden ruido y un glifo no estándar. No bloqueante por sí solo, pero refuerza preferir v1.

## Nota transversal (no bloqueante, no es defecto de mockup)
El botón "＋ Nueva experiencia" se ve morado (primary DaisyUI por defecto) en vez del verde e250 `#2eac66` en las tres capturas. Es un artefacto de cómo el CDN de Tailwind aplica el tema en un HTML estático; en el widget real el tema e250 se compila vía `tailwind.config.js` y el botón saldrá verde. No afecta al veredicto ni a ninguna variante en particular.

## Veredicto
aprobado: `v1-text-acciones-button.html` — con el ajuste menor de `aria-label`/foco en el trigger del dropdown al implementarlo, y recordando a `build-frontend` cubrir por TDD las dos omisiones condicionales por separado (incompleta → sin Código de inserción; sin escritura → sin Editar).
