Servicios locales · Identidad digital bilingüe para una clínica veterinaria de dos personas
IDENTIDAD DE LA CLÍNICA VETERINARIA LOVET
Una clínica veterinaria de dos personas competía por la atención local contra clínicas más grandes, sin presupuesto de publicidad y sin identidad digital. La construcción convirtió "solo somos dos personas" en el argumento de venta, no en la limitación, y lo respaldó con una build de 99/100 en PageSpeed.
- Rol
- En solitario: dirección de marca, sistema de diseño, arquitectura de componentes e i18n, redacción, SEO técnico y rendimiento, con Claude Code como herramienta de construcción
- Cronología
- 2026 · en producción en lovetclinicaveterinaria.es
- Cliente
- Lovet · Clínica veterinaria en Sant Feliu de Llobregat. Carme, veterinaria, y Xavi, auxiliar veterinario
- Stack
- Exportación estática de Next.js, Tailwind CSS, scripts de imagen basados en sharp, Web3Forms, hosting en Vercel
- 99 Rendimiento PageSpeed en móvil, 100 en escritorio
- 0 Bytes de contenido en catalán ya en producción modificados
- 3 Auditorías de cohesión independientes antes de consolidar cualquier componente
Una clínica de dos personas compitiendo contra nombres más grandes
Lovet es una clínica veterinaria real en Sant Feliu de Llobregat, llevada por dos personas: una veterinaria y un auxiliar veterinario. Sin una web con identidad propia, competía por la atención local contra clínicas más grandes con más presencia digital, sin presupuesto de publicidad y sin más canal de captación que el boca a boca y la búsqueda local.
El problema de negocio era claro: una clínica pequeña necesita que su web haga el trabajo de generar confianza que a una clínica grande le regala gratis su plantilla o sus años en el mercado. El problema de producto era otro. No se trataba de construir "una web de clínica veterinaria" en el sentido genérico. Se trataba de convertir lo que podía leerse como una limitación, ser solo dos personas, en el argumento en sí.
Qué lo hizo difícil
- El punto de partida era una plantilla. El proyecto empezó sobre Obliq, una plantilla genérica de Next.js/Tailwind. El riesgo real era entregar un rebranding superficial que siguiera leyéndose como una plantilla con otro logo
- Hosting estático, sin backend. output: 'export' con imágenes sin optimizar, elegido por un hosting simple y proporcional al negocio, descarta next/image desde el principio. Cada optimización de imagen hay que resolverla a mano
- Material de origen limitado. Las fotos reales de los fundadores llegaron a 480px. Cualquier layout que las ampliara las pixelaba
- Bilingüe añadido a posteriori. El catalán ya estaba en producción y estable cuando llegó la decisión de añadir el castellano. Tocar la arquitectura sin arriesgar ni un carácter del contenido en catalán ya indexado era una restricción autoimpuesta, no un requisito técnico
- Presupuesto cero para errores de despliegue. El proyecto en Vercel tenía framework: null, así que un despliegue mal ejecutado servía la carpeta public/ como raíz web. Rompió producción una vez
Lo que asumí, y lo que decidió el cliente
Como único diseñador y desarrollador del proyecto, con Claude Code como herramienta de trabajo, lo asumí de principio a fin: dirección de marca y sistema de diseño, arquitectura de componentes, arquitectura i18n, redacción, SEO técnico, rendimiento y el propio pipeline de despliegue.
- El cliente decidió: el posicionamiento de fondo ("solo somos los dos, y esa es la ventaja"), qué contenido legal usar, quitar la sección "Novedades" y el enlace de salto visual, aceptar el texto legal en castellano como una traducción sin revisar, y el naming de marca ("LOVET" en mayúsculas)
Menos folleto de clínica veterinaria, más "solo somos los dos"
El primer borrador del texto se leía como una clínica genérica: "atención integral", "profesionales cualificados". El giro real fue tratar la escala pequeña como el diferenciador: "En Lovet solo somos dos: una veterinaria y un auxiliar que te conocen por tu nombre." Esa frase, no una lista de servicios, es lo primero que lee cualquier visitante.
Bilingüe sin tocar ni un byte de lo que ya estaba en producción
En vez de fusionar catalán y castellano bajo una sola ruta [locale] compartida, la arquitectura usa un grupo de rutas transparente (ca), el catalán se queda en la raíz exactamente como estaba, y un árbol [locale] separado solo para es. Para verificarlo, construí verify-ca.mjs: normaliza el ruido no determinista de cada build (hashes de webpack, comentarios de hidratación de React) y compara el HTML catalán resultante byte a byte contra una base de referencia. Cualquier cambio de contenido real se detecta; un rebuild inofensivo no. Eso convirtió "¿he roto el sitio en catalán?" en npm run build && node scripts/verify-ca.mjs, no una revisión manual.
Resolver la causa real de un CLS, no enmascararlo
Una auditoría de PageSpeed marcó un CLS de ~0,143 en escritorio. La causa no era cosmética: la fuente del cuerpo de texto (Elms Sans) cargaba con font-display: swap y sin fuente de respaldo con métricas equivalentes, así que cada línea de texto se recolocaba en el instante en que llegaba la fuente web. El arreglo fue generar una fuente de respaldo local, Arial más size-adjust, ascent-override y descent-override calculados para ese archivo específico, no desactivar el swap ni disimular el salto con trucos de opacidad.
Consolidar componentes solo cuando la duplicación era real
Tres auditorías de cohesión y calidad visual, con 40, 34 y 36 hallazgos en rondas separadas, encontraron que servicios, instalaciones, planes y especialistas usaban de 4 a 6 variantes casi idénticas de la misma tarjeta, banda de CTA o conjunto de iconos. Se consolidaron en primitivas únicas (person-card, cta-band, icons, trust-chips) solo después de confirmar que existían 3 o más copias reales, no como abstracción especulativa por adelantado.
Tres decisiones más pequeñas que suman
- Pipeline de imágenes manual, no next/image. Con un hosting simple como requisito de negocio, la alternativa fue scripts de sharp específicos para recortar y generar variantes responsive solo donde el peso real lo justificaba: el carrusel de la home servía imágenes de 1024px dentro de cajas de 288 a 384px, así que se generaron derivadas de 640px. Contrapartida aceptada: cada imagen nueva pasa por un script antes de subirse, no por una API automática
- WhatsApp y un formulario ligero, no un backend de reservas. La clínica funciona por teléfono y WhatsApp en la práctica. Construir un backend de citas habría resuelto un problema que no tienen. El formulario de contacto usa Web3Forms sobre fetch, con un honeypot contra spam y un respaldo de teléfono/WhatsApp si falta la clave de la API
- Sin datos legales inventados. Mientras el NIF, el número de colegiado y los datos del gestor estaban aún pendientes, el contenido legal mostraba un marcador ámbar visible ("Rellenar") en vez de un placeholder "razonable". Se sustituyó por los datos reales en cuanto el gestor los entregó
Cuando el material de origen dicta el layout, y no al revés
El caso más claro de iteración real, no de pulido cosmético, es el layout del perfil de los fundadores.
- V1, tarjeta grande. Con fotos de origen de solo 480px, escalarlas a un formato de tarjeta grande las pixelaba
- V2, editorial alterno. Una rejilla de columnas asimétrica ([340px_1fr]) con order-last para alternar el lado de la foto entre los dos fundadores. Bug real: order reordena el elemento visualmente en el DOM pero no intercambia el ancho de columna, así que la foto seguía cayendo en la pista ancha y estirándose de la misma forma
- V3, columnas gemelas. Layout final: grid-cols-2 sin alternancia y sin order, retrato limitado a un ancho máximo (aproximadamente entre 340 y 440px) que no fuerza el escalado hacia arriba. Los dos fundadores acaban también visualmente iguales, que era lo que el cliente pedía en realidad
Un cliente que tomó decisiones de producto reales
El cliente no fue un stakeholder pasivo. Tomó decisiones de producto explícitas que cambiaron el alcance: quitar la sección "Novedades" antes de que llegara a construirse, eliminar el enlace de accesibilidad de salto porque se solapaba visualmente con el logo (las anclas id="main" subyacentes se quedan por si se retoma), y publicar a sabiendas el contenido en castellano como una traducción fiel del catalán sin revisión de un abogado en ese idioma.
99 en móvil, 100 en escritorio, medido el 12 de septiembre de 2026
Medido con PageSpeed Insights en www.lovetclinicaveterinaria.es: 99 rendimiento, 100 accesibilidad, 100 buenas prácticas, 100 SEO en móvil, y 100, 96, 100, 100 en escritorio.
Core Web Vitals reales: LCP 2,2s móvil, 0,5s escritorio. CLS 0 móvil, 0,033 escritorio. TBT 0ms móvil, 20ms escritorio.
Qué está verificado, y qué no voy a afirmar
La puntuación de accesibilidad de 96 en escritorio no es una cifra pulida para la ocasión: PageSpeed marca contraste insuficiente en el enlace "ES" del selector de idioma, text-deep/60 sobre el fondo del header. Es un elemento pendiente documentado, no oculto.
Lo que no puedo afirmar: no hay una línea base del sitio anterior en WordPress en analítica, velocidad o conversión, así que no hay una cifra de "mejora respecto a antes". Tampoco hay datos de Search Console, ni GA, ni entrevistas con usuarios reales en el material disponible. El impacto documentado es técnico, de rendimiento, de accesibilidad, de SEO on-page, y de producto, funcionalidades entregadas, no de negocio.
La lección no fue "auditar más"
El proyecto pasó por tres rondas de auditoría independientes antes de dar cualquier área por terminada, y cada una encontró duplicación real que las rondas anteriores habían pasado por alto, porque miraban página a página, no el sistema completo. La lección no es auditar más. Es que consolidar componentes solo tiene sentido cuando se mira el conjunto, no la pieza aislada.