Antes el único zoom era el modal interactivo (click -> Dialog con scale/
drag). Ahora la imagen principal también hace zoom estilo lupa (2.2x)
que sigue la posición del cursor con mousemove/transform-origin, sin
tocar el modal existente (sigue abriéndose igual con el click).
Solo mouse -- mousemove no dispara de forma continua en touch, así que
en mobile simplemente no aparece el efecto, sin romper nada ahí.
Verificado: tsc --noEmit limpio, página de producto renderiza 200 con
datos mock y el nuevo markup presente. No se pudo verificar visualmente
el hover en un navegador real (sin chromium-cli ni claude-in-chrome
disponibles en este shell headless).
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01THZFwPzrwv6VAbuwmaf5vR
variant.available (calculado en lib/headless/providers/medusa.ts a
partir de manage_inventory/allow_backorder/inventory_quantity) ya
llegaba correcto hasta el componente, pero ningun boton de compra lo
usaba -- se podia seguir agregando al carrito un producto con stock 0.
Afecta product-purchase.tsx (pagina de producto), mobile-add-to-cart.tsx
(barra fija mobile) y product-card.tsx (tarjetas de catalogo): boton
deshabilitado + label "Agotado" en los tres, mas badge/overlay en la
tarjeta de catalogo.
Reportado en produccion: en mobile aparecian dos botones 'Añadir al
carrito' apilados. ProductPurchase.tsx nunca ocultaba su boton en
mobile, y MobileAddToCart.tsx (barra fija abajo, solo lg:hidden) ya
cubre esa misma accion ahi -- se agrega hidden lg:inline-flex al
primero para que solo uno este visible por breakpoint.
De paso, dos leftovers del esquema arcoiris original en la misma
pagina, vistos en la misma sesion de pruebas: el badge de variante
seleccionada (border-fuchsia-500 bg-fuchsia-50 text-fuchsia-700 -> azul
de marca) y la etiqueta de categoria/coleccion (text-fuchsia-600 ->
ari-coral).
Reemplaza los valores de marino/coral/coral-claro de "Navy & Coral"
por una paleta azul solido (#0055B8, ancla + accion unica) + amarillo
(#FFC220, acento en badges/detalles, nunca en botones). Los nombres de
token (--color-ari-marino/coral/coral-claro) no cambian, solo sus
valores, por lo que el resto de componentes que ya migraron en las
sub-fases 1-3 heredan la paleta nueva automaticamente via CSS vars.
Ajustes puntuales de contraste: badges de descuento/destacado en
product-card.tsx pasan de texto blanco a texto marino sobre fondo
amarillo; linea decorativa del navbar pasa de coral (ahora identico al
marino) a coral-claro para seguir siendo visible contra el header.
Reemplaza los alias de compatibilidad de ADR 0007 por los tokens
definitivos de ADR 0008 en product-card.tsx y catalog-client.tsx:
ari-ciruela -> ari-coral, ari-carbon(-oscuro) -> ari-marino,
ari-cobre -> ari-coral-claro, ari-terracota-oscuro -> ari-coral,
ari-hueso -> bg-white. Cambio puramente mecanico de nombre de clase,
sin cambio de comportamiento ni de jerarquia visual.
Fuera de alcance (confirmado contra ADR 0008 SS6): borde gradiente de
components/search/predictive-search.tsx (no encaja en ninguna de las
5 sub-fases documentadas) y bg-ari-ciruela/bg-ari-cobre en
components/ui/button.tsx (sub-fase 5, boton de carrito).
Validado con npm ci + tsc --noEmit + next lint + next build en
contenedor node:24.18.0-bookworm-slim (mismo runtime del Dockerfile);
CSS compilado inspeccionado: tokens nuevos presentes, cero clases
legacy generadas desde los dos archivos tocados.
Identidad visual propia premium (ver docs-portal/docs/decisiones/0007-identidad-visual-propia.md,
revision 2). Correccion de proceso respecto al intento anterior
(v1.0.176, revertido): en vez de un token aislado en un solo boton,
esta pasada toca de punta a punta los componentes que se ven juntos en
la misma pantalla para que ninguna card quede a mitad de camino.
- globals.css: paleta ciruela/carbon-oscuro/cobre/hueso (reemplaza
cyan/magenta/yellow/blue, confirmado sin uso previo). Domine
(titulares/precio) + Inter (UI/cuerpo) via next/font/google -- antes
"Inter" era solo un fallback de CSS sin garantia real de carga.
- button.tsx: variant "magenta" renombrada a "primary" (ya no es
magenta, es ciruela solida) y su color redefinido -- renombrada en
los 8 archivos que la usaban para no dejar un nombre enganoso.
Radio base rounded-full -> rounded-lg, ring de foco retintado.
- product-card.tsx: badges NUEVO/TOP/descuento en la paleta nueva (no
mas fucsia/amarillo neon), precio en Domine, radio y sombra
consistentes con el boton.
- catalog-client.tsx: solo clases de color/radio en breadcrumb, filtro
de precio, pills de filtro y boton de reset -- cero cambios de
logica.
Header, footer, home y pagina de producto/drawers quedan con la
paleta anterior a proposito -- Sub-fases 2, 4 y 5 pendientes.
Validado con `docker build --target builder` (npm ci + next build con
typecheck completo) -- compila limpio.
El smoke test en aislamiento (boton CTA terracota + precio en
Fraunces) no se puede juzgar de forma justa rodeado del resto de la
pagina, que sigue en la paleta anterior (badges NUEVO/TOP en fucsia/
amarillo, fondo blanco) -- choque visual real, no una direccion de
marca evaluable. Ademas la direccion terracota/artesanal en si no era
lo que se buscaba (se quiere premium/serio, no rustico).
Vuelve product-card.tsx y button.tsx a su estado anterior a Sub-fase
1. globals.css/layout.tsx quedan con los tokens y next/font ya
integrados (nadie los consume todavia, cero impacto visual) para no
rehacer ese trabajo de infraestructura -- la proxima iteracion de
diseno se construye y aprueba en una preview aislada (fuera del
storefront real) antes de volver a tocar produccion.
Identidad visual propia (ver docs-portal/docs/decisiones/0007-identidad-visual-propia.md):
paleta terracota/espresso/pino/crema/carbon reemplaza los tokens
--color-ari-cyan/magenta/yellow/blue (confirmado sin uso en ningun
componente antes de tocarlos). Fraunces + Inter cargadas via
next/font/google (antes "Inter" era solo un fallback de CSS sin
garantia real de carga).
Cambio minimo a proposito: nueva variant "primary" en button.tsx sin
tocar la clase base compartida (radio, ring de foco quedan igual para
el resto del sitio), aplicada como smoke test unico en el CTA y el
precio de ProductCard. El resto de la propagacion (header, footer,
badges, home, product detail) queda para las Sub-fases 2-5, cada una
con su propio gate.
Validado con `docker build --target builder` (npm ci + next build con
typecheck completo) -- compila limpio.
Expone ProductVariant.inventoryQuantity (ya calculado desde
variant.inventory_quantity en Medusa, hoy colapsado al booleano
available) y lo usa para mostrar "Quedan N" cuando el stock real es
bajo (<=5), tanto en la tarjeta de producto como en la ficha. null
indica inventario no gestionado (backorder / manage_inventory=false),
donde nunca se muestra un numero. ADR 0005 seccion 3 (patron eBay).
Catalogo mock actualizado (data/products.json) con
inventoryQuantity=null en todas las variantes para seguir tipando
contra Product[] via `satisfies`.
Reutiliza Product.variants[].{name,value,available}, ya expuesto por el
provider de Medusa (variant.options[0]), para swatches clicables en la
tarjeta del catalogo/home -- no solo en la ficha de producto. Solo se
muestra cuando el producto tiene mas de una variante; la variante
seleccionada se usa al agregar al carrito. ADR 0005 seccion 3 (patron
eBay), cero cambio de modelo de datos.
Reutiliza Product.compareAtPrice (ya calculado en el provider de Medusa
via original_amount > calculated_amount) para mostrar precio tachado +
badge de descuento en la grilla/catalogo, no solo en la ficha de
producto. ADR 0005 seccion 3, patron Walmart -- cero cambio de modelo
de datos.