globals.css define input:focus-visible { outline: 3px solid
rgb(0 85 184 / .5); ... } como indicador de foco por teclado global,
intencional (no se toca). Le gana en especificidad CSS a la utilidad
outline-none de Tailwind, asi que seguia mostrandose sobre el input
propio del buscador (commit anterior) -- pero como ese input no tenia
border-radius, se veia como un rectangulo de esquinas rectas
superpuesto al pill redondeado, reportado en produccion (v1.0.192).
Agrega rounded-full al input para que el mismo outline (que se debe
conservar) siga el contorno del pill en vez de cortarlo.
El fix anterior (focus:border-0 focus:ring-0) no elimino de forma
confiable el focus:ring-4 focus:ring-cyan-300/30 hardcodeado del
componente <Input> compartido dentro de este contenedor compuesto
(input + boton circular en el mismo wrapper) -- reportado en
produccion (v1.0.191): un segundo ring amarillo se superponia y
cortaba visualmente el boton de la lupa al hacer click.
En vez de seguir peleando el override via tailwind-merge, el buscador
deja de usar el <Input> compartido y usa un <input> nativo con sus
propias clases minimas, sin nada que sobreescribir.
El Input base (components/ui/input.tsx) trae focus:border-cyan-500 y
focus:ring-4 focus:ring-cyan-300/30 hardcodeados. La correccion
anterior del buscador solo anulaba focus-visible:ring-0, una variante
distinta a :focus -- el ring cian del componente base seguia
disparandose al hacer click, superpuesto al ring amarillo del wrapper
nuevo (dos anillos visibles a la vez, reportado por el usuario en
produccion tras el deploy de v1.0.190).
focus:border-0 focus:ring-0 anula correctamente ambas utilidades del
Input base via tailwind-merge (mismo variant+propiedad).
predictive-search.tsx nunca estuvo en el alcance de ninguna sub-fase
de ADR 0008 (sub-fase 2 solo tocaba navbar.tsx/footer.tsx), asi que
seguia con el borde degradado cian/violeta/fucsia y acentos violeta
del esquema arcoiris original -- confirmado visualmente en produccion
(captura del usuario) y en el codigo.
Reemplaza el wrapper de gradiente por un input con borde solido y un
boton circular azul (--color-ari-marino) con la lupa a la derecha, en
vez del icono flotando a la izquierda sobre el degradado. Foco usa
ring amarillo (--color-ari-coral-claro), igual que el resto de
componentes interactivos del sitio (button.tsx). Hover/foco del panel
de resultados y del boton 'Buscar en todo el catalogo' pasan de
violeta a los tokens de marca.
El header de /images/:path* (7 dias, pensado para fotos de producto
que no cambian) tambien alcanzaba a los assets de marca (logo,
favicon), que si cambian con cada iteracion de identidad visual.
Confirmado en vivo contra shop.cruzcloud.net: Cloudflare seguia
sirviendo el logo de la iteracion anterior 'Navy & Coral'
(fill #122844/#D85A30) mas de 14h despues de que el pod ya corria
v1.0.185 con el logo 'Azul & Amarillo' (#0055B8/#FFC220) --
cf-cache-status: HIT, age: 51378s, last-modified anterior al redeploy.
No es un bug del logo.svg en si (el contenido del archivo ya era
correcto desde la sub-fase 1 de ADR 0008) sino de una politica de
cache compartida con assets que no deberian tener el mismo TTL.
hasTrustDialogAccepted vive en ~/.claude.json (archivo suelto en
/root), no dentro de ~/.claude/ que ya estaba montado -- se perdia en
cada recreacion del contenedor pese a que el login si persistia.
Fix: bind mount archivo-a-archivo, sembrado con el .claude.json ya
confirmado. Verificado en vivo: claude arranca sin re-pedir el
dialogo tras recrear el contenedor.
El comando docker run documentado no funcionaba realmente desde
dentro del contenedor: /DATA/AppData es un symlink absoluto a
/media/HDD-Storage/AppData, que queda roto si solo se monta /DATA.
Agrega el mount que falta, el git safe.directory necesario (baked en
el arranque, no persiste en el volumen de credenciales), y documenta
ambos gotchas con como se detectaron.
Explica el problema que resuelve (persistencia de sesion ante cortes
de red/dispositivo, distinto de limites de cuota), la arquitectura
del contenedor tmux-host, y por que Docker en vez de instalacion
nativa (squashfs read-only en ZimaOS).
ADR 0008: pivote de paleta de "Navy & Coral" a "Azul & Amarillo"
(Walmart-inspirada), confirmado explicitamente por el usuario. Sub-fases
1-3 ya en main heredan la paleta nueva via CSS vars sin tocarse.
Merge directo local, patron estandar aprobado para cierres de sub-fase
de este proyecto (ver sub-fases 1-2).
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.
DepartmentsMegaMenu posicionaba el panel con absolute left-0 relativo
al wrapper que envuelve solo el boton (relative shrink-0), el cual no
arranca en x=0 del viewport (hay hamburger+gap+px-4 antes). Con
width: min(92vw,64rem) eso desbordaba por la derecha en pantallas
angostas (confirmado: 43px de overflow en 360px, 39px en 412px).
Se mueve el contexto de posicionamiento (relative) al contenedor
completo de la fila del nav, que si ocupa el ancho real del viewport,
y se agrega max-h-[80vh] overflow-y-auto para scroll vertical si el
arbol de categorias excede la altura de pantalla.
Validado con build real (typecheck+lint+build) y Playwright headless
en 360px y 412px: panel queda en x=0, sin scroll horizontal de pagina.
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.
Aplica la paleta marino/coral al navbar y footer, reemplazando los
ultimos restos del esquema arcoiris original (barra de promo
amber/lima, linea decorativa cyan/violeta/fucsia, pills y mega-menu
fucsia/violeta) documentados en el ADR 0008 seccion 5. Aplica
logo-ari.svg (lockup nuevo) en navbar y footer, reemplazando
logo-ari.png y el marco circular que no encajaba con el aspect ratio
del lockup.
Ver docs-portal/docs/decisiones/0008-identidad-navy-coral.md.
Reemplaza ADR 0007 (Atelier calido, ciruela/carbon/cobre) tras dos
ciclos de implementar-y-descartar en produccion. Esta vez la direccion
se valido con mockups fuera de este entorno antes de tocar codigo.
- globals.css: paleta marino/coral/coral-claro + alias temporales de
los tokens de ADR 0007 (se resuelven ya contra la paleta nueva para
no dejar catalog-client/product-card/button.tsx sin estilo hasta que
cada sub-fase migre el nombre de clase; se eliminan en la sub-fase 5).
- layout.tsx: Poppins peso 700 reemplaza a Domine en --font-display.
- Nuevo isotipo (mariposa de 4 elipses) como logo-ari.svg (lockup) y
app/icon.svg (favicon reducido, convencion Next.js App Router);
favicon.png anterior eliminado por no estar referenciado.
- docs: ADR 0008 con la cronologia completa y el hallazgo de los
gradientes arcoiris nunca actualizados en navbar.tsx; ADR 0007
marcado como superseded sin borrar su contenido.
Validado con npm ci + typecheck + lint + build de produccion via
Docker (no hay node/npm en este shell) y verificando el CSS
compilado: los alias resuelven a la paleta nueva y las utilities
bg-ari-ciruela/text-ari-carbon/bg-ari-hueso se siguen generando.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01F8c83sjFBP7c4m4UVN5d3d
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.
Propuesta de rediseno visual del storefront, aprobada por el usuario
tras una correccion de direccion explicita: no clonar la estetica de
Amazon, adoptar los principios de UX del mercado (jerarquia visual,
densidad sin saturacion, senales de confianza, contraste) para
construir una identidad propia y distintiva -- paleta terracota/
espresso/pino/crema validada con contraste WCAG AA real, tipografia
Fraunces+Inter, lenguaje de forma propio, 3 detalles deliberados no
genericos.
Alcance: solo visual, no toca catalogo/backend/taxonomia ni la
estructura de navegacion ya construida en ADR 0005. Plan de
implementacion en 5 sub-fases (tokens -> header/footer -> product
card+catalog -> home -> product detail/drawers), sin codigo de
produccion tocado todavia.
Reemplaza los placeholders "TODO (fase 2+)" por narrativa completa,
grounded en el codigo/manifiestos/incidentes reales del lab (no
generico):
- ADR 0001 (por que k3d) y ADR 0002 (por que Argo CD): pasan de
template vacio a Contexto/Opciones/Decision/Consecuencias reales,
apoyados en known-issues.md (blackhole MTU) y en la config real de
ecommerce-app.yaml.
- vision-general.md: el "por que" de cada frontera de confianza del
diagrama.
- gitops-flujo.md: ejemplo real con hashes de commit (Fase 3b de
ADR 0006, v1.0.171 -> hotfix -> v1.0.172), selfHeal explicado con el
syncPolicy real del repo.
- red-y-exposicion.md: diagrama de terminacion TLS real, por que todo
va "proxied", patron de diagnostico "interno sano, publico roto".
- glosario.md: 9 terminos nuevos, cada uno con ejemplo real y
verificado del repo (Namespace, ResourceQuota, LimitRange,
NetworkPolicy, Deployment, Service, Ingress, StatefulSet, Init
container).
- notas-sueltas.md: MinIO/S3, limites reales del subscriber
revalidate-storefront.ts, que se automatizaria desde cero.
Validado con `docker build --target build` (mkdocs build --strict,
mismo paso que el pipeline real) -- cero links rotos, cero warnings.
Verificado en vivo contra shop.cruzcloud.net: /store/search reporta
estimatedTotalHits (campo `count`) en 0 cuando limit=0, aunque
facetDistribution si trae los valores correctos (limit>=1 lo reporta
bien). El bucket "Todas"/"Todos" del sidebar de facetas (Fase 3b)
dependia de ese campo -- ahora suma los valores de la propia
facetDistribution, que da el total real sin ese problema.
Fase 3b (ultima) de ADR 0006 Etapa 2: los conteos de categoria/marca/edad
del sidebar de /catalog dejan de ser un snapshot client-side fijo. Ahora
se refetchean en vivo contra /api/search en cada cambio de filtro (query
debounced 300ms), tres llamadas paralelas -- una por dimension, cada una
omitiendo su propio filtro para preservar el patron Amazon de "cuantos
resultados habria si eligiera este otro valor".
- catalog-client.tsx: useMemo client-side originales pasan a ser fallback
(mock/shopify sin searchWithFacets, o cuando la categoria activa es un
grupo raiz sintetico que Meilisearch no puede filtrar).
- ProductFilters gana `limit` opcional; /api/search y el provider medusa
lo reenvian -- las llamadas de solo-conteo piden limit=0 para no
rehidratar precios de productos que no se van a mostrar.