Caso · junio de 2026 · v1.0

lopeixapartments.com

Un apartamento vacacional construido como un producto digital completo

Autoría
Joan Arbó
Catálogo
27 rutas × 5 idiomas · 105 posts · 13 audioguías · 636 URLs · 35 schemas JSON-LD
Lectores objetivo
Diseñadores senior y leads de design system que operan sistemas con IA en producción

00 — Aviso al lector

Este documento es lectura honesta del estado del producto Lo Peix a fecha de mayo de 2026. Cubre las decisiones de design system y producto tomadas durante los 78 días que separan el primer commit (23 febrero) del estado actual (269 commits, ~104.600 LOC).

No es caso de éxito. Es el inventario de decisiones que sostiene una operación turística micro convertida en producto digital completo. Algunas funcionan. Otras están vivas. Lo que se mantiene es el criterio que las gobierna.

Sin AI-slop. Sin “elevar”, sin “transformar”, sin “potenciar”. Quien necesite ese lenguaje no es el público de este documento.

01 — La decisión que cambia todo

Lo Peix opera dos apartamentos en La Ràpita, Delta del Ebro. La competencia natural es Booking, Airbnb, Vrbo: distribución masiva, comisión 15-20%, dependencia total de la plataforma, contacto con el huésped intermediado.

La decisión fundacional del proyecto es rechazar OTA como canal primario. Y rechazarlo no construyendo un sitio bonito que enlaza a Booking, sino construyendo el producto digital completo que un hotel boutique consideraría su estándar: web editorial multilingüe, app móvil con concierge IA, audioguías propias, blog generativo, pipeline de contenido automatizado.

La hipótesis: un apartamento con experiencia digital de hotel boutique convierte mejor, fideliza más, justifica prima de precio, y opera con margen completo sin comisión.

Esa decisión obliga a reescribir las preguntas básicas que un equipo de design system suele dar por sentadas en proyectos turísticos:

  • ¿Qué es la marca de un apartamento de 60 m²? El producto digital, no el inmueble.
  • ¿Qué activos editoriales necesita un alojamiento de operador único? Los mismos que un hotel boutique, ejecutados al mismo nivel.
  • ¿Cuál es el lector primario del contenido? Un humano antes de reservar y un agente que ese humano va a consultar.
  • ¿Qué sistema soporta esto sin equipo? Pipeline automatizado, monorepo único, infra de proveedor único.

Lo Peix está construido respondiendo a estas cuatro preguntas con coherencia. El resto del documento explica cómo.

02 — Anatomía del producto: cuatro superficies, un sistema

A diferencia de un alojamiento típico que tiene una web brochure y una ficha en Booking, Lo Peix entrega cuatro superficies coordinadas. Cada una atiende un momento distinto del viaje y todas comparten el mismo design system.

Las cuatro superficies

1. Web editorial multilingüe. Punto de entrada principal. 27 rutas (landing, blog, guías de territorio, FAQ, reserva directa) en cinco idiomas con contenido nativo. El blog es activo permanente: 105 posts escritos sobre el Delta, sus mareas, sus arroces, sus rutas, sus aves. No es content marketing de operador, es revista editorial del territorio firmada por Lo Peix.

2. App móvil concierge. Build Expo + React Native con expo-router. Quince pantallas. Pensada para el huésped que ya tiene la reserva: ofrece concierge IA con conocimiento local (mareas, restaurantes, rutas, miradores), reader del blog y acceso a audioguías. No es captación, es retención y diferencial de producto.

3. Audioguías editoriales. Trece episodios definidos sobre el Delta, dos renderizados con audio en producción. Tres idiomas (castellano, francés, alemán) con voces TTS de ElevenLabs. Cada episodio tiene su podcast feed, su Episode schema, su versión gratuita o premium.

4. Guía premium PDF por destino. Lead magnet generado con Puppeteer. Email gate para descargar. Es la pieza que convierte tráfico SEO en lista de email cualificada.

Lo importante: un solo design system

Las cuatro superficies comparten un único paquete de design system (packages/design-system-react). Tokens en castellano, tipografía Cormorant Garamond + Inter, paleta navy/teal con acento terracota. Los componentes principales viven una vez en el paquete y se consumen desde web, mobile y generación de PDF.

Esto importa porque es la decisión que separa al proyecto de un “solopreneur con stack” del proyecto que escala sin reescribir: cuando el mismo <LogoMark />, el mismo <AudioPlayer />, el mismo <LeadCaptureForm /> aparecen en web, mobile y PDF sin variantes específicas, el coste de mantener cuatro superficies converge al coste de mantener una.

La separación no es por superficie. Es por capa: tokens compartidos, componentes consumidos según contexto, contenido en paquete único (packages/content). Es la disciplina de DS aplicada a un producto de un solo operador.

03 — Cinco idiomas que no son traducciones cosméticas

Lo Peix vive en cinco idiomas: castellano, catalán, inglés, francés y alemán. Cada uno con fichero de traducciones tipado por locale y, para el contenido editorial largo, traducción automática semanal desde el original castellano.

La mezcla de los dos modos es deliberada y merece subrayarse para un DS senior.

Lo que está traducido (cadenas de UI)

Toda la cadena de interfaz tiene su versión en cinco idiomas en locales/{lang}.ts. Etiquetas de navegación, microcopy de CTA, mensajes de error, meta tags SEO. Cinco ficheros tipados, autocompletado en TypeScript, fallback explícito a castellano si falta una clave. Esto es i18n disciplinado, ligero, sin framework pesado (react-i18next rechazado deliberadamente, ver §10).

Lo que se traduce automáticamente (contenido largo)

105 posts de blog originales en castellano se traducen cada lunes a catalán, inglés, francés y alemán mediante worker programado. La traducción se hace con LLM, se guarda en Neon, se republica en build estático. La consecuencia operativa: 105 posts × 5 idiomas = 525+ URLs de contenido editorial indexable.

Por qué esta mezcla y no traducción total

Hay dos lecturas posibles. La primera es que el contenido editorial debería estar escrito nativamente en cinco idiomas (como hace lorsclub) para máxima calidad. La segunda es que para un operador único con presupuesto cero de redacción, la traducción LLM coordinada es la decisión correcta que mantiene la promesa multilingüe operable.

Lo Peix elige la segunda. Es decisión consciente, no atajo. La justificación: el mercado primario del Delta es ibérico-francófono-germano, y la calidad de traducción LLM para contenido editorial turístico es suficiente para captación SEO de cola larga. Cuando un huésped reserva, la experiencia in-situ (audioguías, concierge) sí tiene contenido producido específicamente para su idioma.

Hreflang bidireccional

636 URLs en sitemap con hreflang bidireccional entre todas las versiones. Google y los agentes de búsqueda saben que /es/posts/arroz-delta y /fr/posts/riz-delta son la misma pieza en idiomas distintos. Esta es la decisión SEO que la mayoría de operadores turísticos pequeños no toma porque exige disciplina técnica que un CMS de plantilla no resuelve.

Catalán como idioma de marca, no de cumplimiento

El catalán está incluido como idioma de primer nivel, no como gesto institucional. La Ràpita es catalanohablante. Los topónimos catalanes (Encanyissada, Alfacs, Migjorn) se conservan con su grafía original en todas las versiones de idioma, no se castellanizan. El diccionario de pronunciación TTS (§04) mapea fonéticamente estos topónimos para que las voces castellanas, francesas y alemanas los pronuncien correctamente.

Para el design system esto exige decisión consciente sobre dos cosas: la familia tipográfica soporta diacríticos catalanes completos (paint del glyph “ç”, “·l·” geminada, vocales abiertas), y la longitud media de palabra catalana cabe en los layouts. Cormorant Garamond + Inter cubren ambos.

04 — El pipeline de audio que sustituye al equipo de locución

Esta es la pieza más interesante del producto desde el punto de vista del oficio y la que merece más atención del documento.

El problema

Un hotel boutique entrega audioguías profesionales. Un apartamento de operador único, no. La razón no es presupuesto del audio sino coste fijo del equipo: locutor profesional, estudio, edición, mastering. Multiplicado por tres idiomas y trece episodios, es operación inviable para un solo apartamento.

La solución: pipeline editorial completo

Lo Peix construye una pipeline de producción de audio que sustituye al equipo de locución preservando el control editorial. Cinco pasos en scripts/audio/:

Paso 1 · Guion YAML escrito por humano. Plantilla estructurada con frontmatter (slug, idiomas, voz por idioma, duración objetivo) y cuerpo en texto plano. El humano escribe el contenido, no formatea.

Paso 2 · Validación automática. validate.mjs aplica reglas operativas vinculantes:

  • Banlist de vocabulario prohibido (cero AI-slop, cero “fascinante”, cero “experiencia única”).
  • Longitud entre 280 y 345 palabras (corresponde a aprox. 2 minutos a velocidad TTS).
  • Formato estructural correcto.

Si falla, el guion se rechaza. Sin discusión. El humano corrige y vuelve a someter.

Paso 3 · Render SSML con diccionario fonético. render-ssml.mjs aplica un diccionario de pronunciación con 32 alias catalanes mapeados a grafía fonética castellana. Esto resuelve el problema crítico de los TTS multilingües: una voz castellana lee “Ràpita” como “Rákita” si no se la guía; con SSML correcto, lee “Rápita” correctamente. El diccionario es activo de marca del producto.

Paso 4 · Render TTS multilingüe. render-tts.mjs llama a ElevenLabs Multilingual v2 con la voz asignada por idioma:

  • Castellano: Inés (acento castellano peninsular).
  • Francés: Lior (francés nativo).
  • Alemán: Oliver (alemán nativo).

Tres voces seleccionadas con criterio editorial, no aleatorias. Inés tiene gravedad de comunicadora cultural, no de azafata. Lior tiene cadencia francesa rural, no parisina. Oliver es voz alemana neutra adulta, no juvenil. Las tres están alineadas con la voz de marca de Lo Peix (cultural, sobria, territorial).

Paso 5 · Mastering con FFmpeg. master.mjs aplica cadena de procesamiento estándar broadcast:

  • Loudnorm a -16 LUFS (estándar de podcast).
  • High-pass para limpiar bajos sin información.
  • Compresión moderada para uniformar dinámica.
  • Sting de marca al inicio + outro fijo al final.

El output es MP3 de calidad indistinguible de podcast profesional. Coste marginal de un episodio nuevo: aproximadamente cero, una vez el pipeline está construido.

Por qué esto es DS y no contenido

El pipeline de audio es componente del sistema en el sentido riguroso. Cada audioguía nueva pasa por el mismo flujo. Las decisiones de marca (banlist, longitud, voces, mastering) están codificadas en el sistema, no en el cerebro del operador. Esto significa que cualquier colaborador podría añadir un episodio nuevo respetando la voz de Lo Peix, sin haber leído un manual de marca.

Para un DS senior: esta es la aplicación de la disciplina de tokens y componentes al medio audio. Si tu DS no contempla el audio como medio gobernado por el sistema, tu producto editorial con audio es la suma de las voces de quien grabó cada episodio.

Lo que NO se construyó en audio

  • No locución humana. Decisión deliberada. La consistencia entre 13 episodios × 3 idiomas con presupuesto cero solo se obtiene con TTS.
  • No música de fondo en cuerpo del audio. Solo en sting y outro. La voz lleva la pieza.
  • No paywall server-side robusto. localStorage con expiración 30 días + endpoint /api/audio/unlock para validar cupón. Suficiente para volumen actual; migrar a JWT si escala.
  • No app de podcast propia. El audio se sirve desde /public/audio/ con <AudioPlayer /> embebido y feed RSS con schemas PodcastSeries/Episode para que las apps existentes lo encuentren.

05 — El design system: tokens, componentes, accesibilidad

Lo Peix tiene design system formalizado en packages/design-system-react. Tres capas: tokens, componentes compartidos, criterio accesible.

Tokens

Tipografía dual. Cormorant Garamond para headings, pull quotes, blurbs editoriales. Inter para body, UI, navegación. La decisión es editorial antes que estética: Cormorant transmite gravedad cultural (es la tipografía de revistas literarias y editoriales académicas), Inter transmite legibilidad funcional. La combinación posiciona Lo Peix más cerca de Cereal Magazine que de Booking.

Paleta navy/teal con acento terracota. El fondo hero principal es Tailwind teal-950 (casi negro azulado). El acento es terracota aproximado #C4704E. La paleta evoca el Delta sin caer en cliché turístico: ni azules vacacionales, ni amarillos solares, ni naranjas de ofertón. Es paleta seria que diferencia visualmente de la competencia OTA.

Eyebrows en MAYÚSCULAS con tracking-wider y color slate-500 (sobre fondo claro) o teal-200 (sobre fondo oscuro). Componente repetido en todas las superficies que ancla la jerarquía sin recurrir a tamaños tipográficos extremos.

Componentes compartidos clave

  • LogoMark. SVG monogram inline con fill="currentColor". Significado operativo: el logo se renderiza en cualquier color sin necesidad de variantes. Funciona sobre fondo claro (color foreground), sobre fondo oscuro (color foreground inverso), dentro de un botón con color del botón. Una sola pieza de SVG, infinitos contextos. Es DS bien resuelto.
  • AudioPlayer. Multi-idioma con tabs (ES/FR/DE) y mutex global vía CustomEvent. El detalle del mutex importa: si el usuario abre un episodio en una pestaña y otro en otra pestaña, el sistema garantiza que solo uno reproduce a la vez. Es decisión de UX que evita la cacofonía típica de productos con múltiples reproductores.
  • AudioPaywall. localStorage con expiración 30 días + validación de cupón vía servidor. Es la pieza que convierte 11 de los 13 episodios en producto pagado dejando 2 como muestra editorial.
  • LeadCaptureForm. Fondo gradient con halo radial. Routing por topic (reservas, audioguías, info general). Cada formulario activa secuencia de email drip distinta. El componente es uno, las secuencias son cinco.
  • Footer. Fondo teal-950 con tres zonas: brand + manifiesto, grid de cuatro columnas para navegación secundaria, bottom bar con legal e idioma. El manifiesto en el footer es decisión inusual y merece subrayar: el operador declara su tesis (rechazar OTA, ofrecer experiencia editorial) en cada página del sitio. Es el opuesto del footer-formulario estándar.

Accesibilidad WCAG AA verificada

Contraste auditado en tokens críticos:

  • ink-3 #5F7080 sobre fondo claro
  • success #3F7956 y danger #A83A2F en mobile tokens

Tab shadows reducidos a 0.18/14 para minimizar compositing offscreen en mobile (decisión de performance que también ayuda en accesibilidad).

Controles interactivos en mobile con accessibilityRole y accessibilityLabel explícitos. Cumplimiento WCAG AA es base, no celebración.

06 — El concierge IA: cuando el agente vive dentro del producto

A diferencia de lorsclub donde el agente externo consume contenido del sitio, en Lo Peix el agente vive dentro de la app móvil como producto que el huésped usa durante su estancia.

El componente

El concierge es interfaz conversacional embebida en la app móvil. El huésped pregunta en lenguaje natural sobre cualquier aspecto del Delta: cuándo es la mejor hora para visitar la Encanyissada, qué restaurante de arroz tiene mejor relación calidad-precio, dónde aparcar cerca del miradores de l’Eucaliptus, cuándo es marea baja mañana.

El sistema detrás

Tres piezas coordinadas:

Búsqueda vectorial con pgvector. Embeddings de 1024 dimensiones sobre Neon Postgres (migración 013). El corpus indexado son los 105 posts del blog, las 13 audioguías transcritas, fichas de territorio (mareas, miradores, restaurantes, rutas), y conocimiento estructural del Delta.

Embeddings de Together AI con modelo multilingual-e5-large-instruct. Cross-lingual nativo, lo que significa que un huésped que pregunta en alemán recibe respuesta basada en contenido producido originalmente en castellano sin penalización de calidad. Es la misma decisión técnica que toma lorsclub (índice multilingüe único con modelo cross-lingual), aplicada a un caso operativo distinto.

Generación con Claude vía API Anthropic. El system prompt instruye al modelo a responder solo desde corpus recuperado, citar fuente cuando aplica, decir “no sé” si falta evidencia, mantener tono editorial alineado con la voz de Lo Peix.

Por qué este caso de agente es distinto a lorsclub

En lorsclub el agente primario es externo: Claude, Perplexity, ChatGPT que consumen el sitio y devuelven respuestas a sus usuarios. En Lo Peix el agente primario es embebido: vive dentro de la app móvil que el huésped instala.

Las consecuencias para el DS son distintas. En lorsclub el sistema diseña para ser consumible por agentes externos vía HTTP. En Lo Peix el sistema diseña para que el agente sea componente nativo del producto, con UI propia, estados de loading, manejo de errores, fallbacks cuando no hay conexión.

Esto importa para entender que “diseñar para agentes” no es una sola cosa. Es al menos dos: diseñar para que agentes externos consuman tu producto, y diseñar agentes embebidos dentro de tu producto. Lo Peix hace lo segundo. Lorsclub hace lo primero. Ambos son legítimos y exigen disciplinas de DS distintas.

07 — El reloj editorial: seis crons mantienen el sistema vivo

El producto promete contenido editorial fresco, traducciones al día, audio renderizado, email coherente. Esto solo es sostenible si cada superficie tiene su reloj propio.

Seis cron jobs definidos en cloudflare/workers/cron/:

CronScheduleFunción
generate-post2 veces/día (09:00 + 18:00 UTC)Genera borrador de blog post con LLM y guarda en Neon
translate-postsLunes 07:30 UTCTraduce posts pendientes a CA, EN, FR, DE
email-dripDiario 09:00 UTCEnvía siguiente paso de secuencia drip a cada suscriptor
refresh-seoLunes 06:17 UTCAudita posiciones actuales y sugiere mejoras editoriales
generate-socialLunes 08:00 UTCGenera contenido social a partir de posts recientes
weekly-summaryLunes 08:30 UTCEnvía resumen semanal al operador (suscripciones + plays audio)

Lo que esto significa operativamente

Sin estos seis crons, Lo Peix sería un proyecto que Joan tendría que tocar a diario para mantener fresco. Con ellos, el producto opera sin intervención durante semanas. El operador único interviene como editor (revisar lo generado, aprobar publicación, escribir guiones de audio nuevos), no como productor (no escribe 105 posts, no traduce a cinco idiomas, no genera social, no compone secuencias de email).

Para un DS senior es lectura útil del oficio: la automatización no sustituye al criterio, sustituye a la ejecución. El criterio se codifica una vez (banlist, voces, formatos, secuencias) y se ejecuta infinitas veces.

El cron del resumen semanal

Mención específica para weekly-summary. Cada lunes a las 08:30 UTC el operador recibe un email con tres datos: suscripciones nuevas de la semana, reproducciones de audio por episodio e idioma, y posts nuevos generados. Es el dashboard semanal mínimo viable que un operador único necesita para saber qué está funcionando sin abrir Google Analytics.

Cuando el sistema te informa del estado del sistema sin que tengas que preguntarle, has reducido tu carga cognitiva al mínimo operativo. Esto se subraya porque la mayoría de productos de operador único fracasan por sobrecarga cognitiva, no por falta de tráfico.

08 — 35 schemas JSON-LD: cuando el alojamiento se ofrece como entidad

El sitio inyecta 35 tipos de schema.org en el HTML estático. Es cifra significativa para un alojamiento turístico, donde la mayoría de competidores no pasa de cinco o seis (Organization, LodgingBusiness, Place, Offer, quizá BreadcrumbList).

Los 35 tipos

  • Estructura del alojamiento: LodgingBusiness, Place, PostalAddress, GeoCoordinates, LocationFeatureSpecification, AdministrativeArea, Country.
  • Identidad de marca: Organization, Brand, Person, ContactPoint.
  • Comercio: Offer, MerchantReturnPolicy, PropertyValue, QuantitativeValue.
  • Editorial: Article, BlogPosting, WebPage, WebSite, BreadcrumbList, ItemList, ListItem.
  • Q&A: FAQPage, Question, Answer.
  • Audio: AudioObject, PodcastSeries, PodcastEpisode.
  • Imagen: ImageObject.
  • Eventos: Event.
  • Acción: SearchAction, EntryPoint.
  • Tutoriales: HowTo, HowToStep.
  • App móvil: MobileApplication.

Por qué importa esta densidad

Tres efectos visibles para agentes y motores de búsqueda.

Lo Peix es entidad legible, no página. Cuando un agente pregunta a su LLM “alojamiento boutique Delta del Ebro”, el modelo puede formarse representación interna de Lo Peix como LodgingBusiness situado en La Ràpita con audioguías propias, blog editorial, app móvil, política de reembolso clara. Esa representación es la diferencia entre aparecer en respuesta de agente o no aparecer.

El audio es entidad indexable, no archivo. PodcastSeries y PodcastEpisode permiten que las audioguías aparezcan en Apple Podcasts, Spotify, Google Podcasts sin que Lo Peix tenga apps de podcast propia. El feed RSS las distribuye, los schemas las explican.

La app móvil es entidad pública, no descarga oculta. MobileApplication documenta la app con su tier de precio, idiomas soportados, plataforma. Esto importa cuando un huésped potencial pregunta a su asistente “¿hay app para gestionar mi estancia en Lo Peix?”.

Para un DS senior la lectura es que la indexación agéntica no es trivial: 35 schemas requieren disciplina de implementación en cada plantilla, cada componente, cada ruta. La densidad de schemas es función directa de la disciplina del sistema.

09 — Cinco canales de monetización en stack

CanalMecanismoEstado
Reservas directasLead capture → email drip → reserva directa sin OTAActivo
Audio premium2 episodios gratis + 11 de pago vía paywall localStorage + cupón servidorActivo
Guía premium PDFLead magnet con email gateActivo
App conciergeFreemium previsto (cupón 100% primer mes para huéspedes)En implementación
Partnerships localesPlan de tracción con Patronat de Turisme, SEO/BirdLife, oficinas de turismoEn desarrollo

El detalle estratégico

El producto vende a tres audiencias con disposición a pagar muy distinta y cada una entra por su puerta:

  • Huésped que reserva: entra por SEO largo + reserva directa. Cero comisión OTA.
  • Visitante que descubre el Delta: entra por blog + audioguía gratuita → email + audioguía premium o guía PDF.
  • Operador local interesado en partnership: entra por contact form específico con routing distinto.

Esto es pricing por audiencia, no por feature. La misma decisión arquitectónica que toma lorsclub aplicada a contexto turístico. No hay tabla de precios cruzada que confunda a las tres audiencias. Cada una ve la oferta diseñada para ella.

10 — Lo que NO se construyó

Para un Design System Architect senior esta sección suele ser la más útil del documento: lo que define el sistema es tanto lo que incluye como lo que rechaza.

No construidoPor quéQué ocupó su lugar
OTA (Booking/Airbnb) como canal primarioComisión 15-20% destruye el margen de operador único. Cede contacto con el huésped a un tercero.Reserva directa con email drip propio. Margen completo, contacto directo.
SSR / Next.jsComplejidad operativa innecesaria. Vite + build estático + pre-render cubre el SEO sin pagar la fricción de hidratación SSR.Cloudflare Pages con build estático + Pages Functions para API.
CMS externo (Contentful, Sanity, Strapi)Dependencia, coste recurrente, suscripción a feature roadmap ajeno.Contenido como código en packages/content (TypeScript + Markdown).
Firebase / SupabaseLock-in a proveedor con costes impredecibles a escala.Neon Postgres directo con Cloudflare Workers. Control total.
React Native WebCompartir código UI entre web y mobile generaría compromiso constante. Web y mobile tienen requisitos UX distintos.Web y mobile son apps separadas con paquete de contenido y DS compartidos.
i18n con framework (react-i18next)Bundle grande, configuración compleja, abstracciones que no se usan.Sistema custom ligero con ficheros .ts tipados por locale.
Paywall server-side robusto para audioSobreingeniería para volumen actual.localStorage con expiración 30d + validación de cupón en endpoint.
Locución humana profesionalCoste fijo prohibitivo para 13 episodios × 3 idiomas.Pipeline TTS con ElevenLabs + diccionario fonético + mastering FFmpeg.
App de podcast propiaReinventar lo que Apple, Spotify, Google ya hacen bien.Feed RSS + PodcastSeries schema. Distribución a las apps existentes.

El patrón

Cada “no” preserva una decisión más profunda: el operador único no construye lo que no puede mantener. La regla operativa de Tony Fadell aplicada con disciplina: “you are what you say no to”.

Para un DS senior cada “no” se traduce en componentes que no se construyen. Sin OTA no hay componente de “Reservar con Booking”. Sin CMS no hay componente de “Editar en interfaz visual”. Sin react-native-web no hay disciplina de tres breakpoints compartidos. Cada “no” simplifica el sistema. Cada “sí” añade superficie a mantener.

11 — Voz editorial como parte del sistema

Lo Peix tiene voz editorial pautada. No vive en el cerebro del operador, vive en el sistema.

Dónde está codificada

En la banlist de audio (scripts/audio/validate.mjs). Vocabulario explícitamente prohibido en guiones: cero “fascinante”, cero “experiencia única”, cero “te enamorarás”, cero adjetivos vacíos. Si una palabra prohibida aparece en un guion, el validador lo rechaza.

En la longitud objetivo de audioguías (280-345 palabras). No es estética, es disciplina de duración para que cada episodio dure aproximadamente 2 minutos. La duración condiciona la prosa: obliga a concisión.

En el diccionario de pronunciación (32 alias catalanes). Cada topónimo del Delta tiene su pronunciación pautada. Esto preserva el respeto al territorio: los nombres se dicen como se dicen, no se castellanizan por comodidad.

En la elección de voces TTS. Inés, Lior, Oliver. Tres voces seleccionadas con criterio editorial alineado con la voz de marca: cultural, sobria, territorial. No azafatas, no comerciales, no juveniles.

En la elección tipográfica. Cormorant Garamond + Inter. Posicionamiento editorial culto, no comercial OTA.

Por qué esto importa para un DS

Si la voz solo vive en el cerebro del operador, cada colaborador que escriba un post, grabe una audioguía o redacte un email va a degradarla. Si vive en el sistema como pauta operativa, la voz sobrevive a cambios de equipo y a la fatiga del propio operador (operador que escribe 105 posts en seis meses pierde criterio si el sistema no lo refuerza).

Un design system que no incluye guía de voz vinculante deja la coherencia de marca al azar del último colaborador que escribió. Lo Peix codifica la voz como capa del sistema. Esa es la diferencia entre un proyecto que escala su contenido y un proyecto que escala su descoordinación.

12 — Cronología leída desde el repositorio

269 commits desde el 23 de febrero de 2026 cuentan la historia del build en cuatro fases.

FasePeriodoQué se construyó
1 · Fundación webFeb–Mar 2026Landing, blog, sistema i18n 5 locales, SEO estructurado, lead capture, primera versión del DS
2 · MobileMar–Abr 2026App Expo SDK 54 con expo-router, concierge IA primera versión, blog reader, tabs
3 · AudioAbril 2026Pipeline TTS completo, ElevenLabs multilingüe, paywall localStorage, player con tabs
4 · Backend maduro y testingAbr–May 202616 migraciones SQL, 6 crons activos, pgvector con embeddings cross-lingual, E2E con Playwright + Maestro, audit accesibilidad

Velocidad: 78 días del primer commit a producción completa. Ratio aproximado 3,4 commits por día.

Este ritmo es lectura del oficio: un operador único con disciplina de Design System Architect puede entregar producto completo en menos de tres meses cuando las decisiones arquitectónicas son sólidas desde el día uno (monorepo, tokens compartidos, contenido como código, proveedor único de infra).

13 — Lo que un DS Architect senior se lleva de aquí

Cinco decisiones aplicables a tu propio sistema, ordenadas por dificultad creciente.

1. Tokens y contenido compartidos entre superficies (fácil)

Si tu producto tiene más de una superficie (web, mobile, email, PDF, audio), los tokens y el contenido viven en paquetes compartidos. No es modular por estética. Es operativo: el coste de mantener N superficies converge al de mantener una cuando comparten capa de sistema. Lo Peix entrega cuatro superficies sostenidas por un solo operador.

2. Pipeline editorial completo en lugar de equipo de producción (fácil-medio)

Si tu producto necesita activos editoriales recurrentes (posts, audio, traducciones, social), pipeline automatizado con criterio codificado sustituye al equipo. La regla operativa: el criterio se codifica una vez, la ejecución se ejecuta infinitas veces. La automatización no sustituye al juicio editorial, sustituye a la mecánica.

3. Voz editorial como capa del sistema (medio)

Si tu producto tiene voz reconocible, esa voz vive en el sistema (banlist, formato, longitudes, vocabulario aprobado, tipografía, paleta) no en el cerebro de quien escribe. Sin esto, cada colaborador degrada la voz. Con esto, la voz sobrevive a la fatiga, los cambios de equipo y la inevitable variación humana.

4. Schemas como API pública implícita (medio-difícil)

Si tu producto quiere ser entendido por agentes externos, los schemas JSON-LD son tu API pública. 35 schemas como en Lo Peix no son cosmético SEO, son contrato semántico con el ecosistema de búsqueda y asistentes. Tu producto se vuelve entidad legible, no solo página.

5. Agente embebido vs agente externo: decisiones de DS distintas (difícil)

Si tu producto tiene componente agéntico, distingue entre agente embebido (vive dentro de tu producto, tu DS lo viste con UI propia) y agente externo (consume tu producto desde fuera, tu DS lo sirve con HTML semántico denso). Son disciplinas distintas. Lo Peix hace lo primero. Lorsclub hace lo segundo. Confundirlas es ruta directa al sobreingeniería.

14 — Anexo técnico

Para quien quiera verificar las afirmaciones del documento contra el código.

Stack

CapaTecnología
Frontend webReact 19 + Vite 6 + Tailwind CSS v4
Frontend mobileExpo SDK 54 + React Native + expo-router + Reanimated
Hosting webCloudflare Pages (build estático + Pages Functions)
API serverlessCloudflare Pages Functions (10 endpoints)
Cron jobsCloudflare Workers (6 tareas programadas)
DB principalNeon Postgres (16 migraciones)
Vector searchpgvector sobre Neon (1024d, cosine similarity)
EmbeddingsTogether AI · multilingual-e5-large-instruct
Concierge LLMClaude (Anthropic API)
TTSElevenLabs Multilingual v2
Mastering audioFFmpeg local
Email transaccionalMailChannels Send API (primario) + Resend (fallback)
Mobile buildEAS Build (Expo)
Testing webPlaywright (9 tests, 5 specs, 2 proyectos: chromium + mobile-chrome)
Testing mobileMaestro (9 flows YAML: smoke, tabs, blog, settings, feedback)
CI/CDGitHub Actions + EAS Build
DNS + CDNCloudflare

Estructura del monorepo

lopeix/
├── apps/
│   ├── web-react/          ← Web (24.300 LOC)
│   └── mobile-expo/        ← App móvil (63.000 LOC)
├── packages/
│   ├── content/            ← 105 posts + legal + i18n compartido
│   └── design-system-react/← Tokens, tipografía, componentes UI
├── functions/              ← Cloudflare Pages Functions
│   ├── api/                ← 10 endpoints
│   └── _shared/            ← email, security, types, db
├── cloudflare/
│   └── workers/cron/       ← 6 cron jobs
├── migrations/             ← 16 SQL migrations (Neon)
├── scripts/
│   ├── audio/              ← Pipeline TTS
│   └── ...                 ← build, generate-pdfs, etc.
└── docs/                   ← Documentación interna

Números del repositorio

  • Commits totales: 269
  • LOC: aproximadamente 104.600 (web 24.300 · mobile 63.000 · backend 3.200 · scripts 14.000)
  • Funciones serverless: 10 endpoints
  • Cron jobs: 6
  • Migraciones SQL: 16
  • Posts editoriales: 105
  • Audioguías definidas: 13 (2 con audio renderizado)
  • Idiomas: 5 (ES, CA, EN, FR, DE)
  • URLs en sitemap: 636
  • Schemas JSON-LD: 35 tipos
  • Tests E2E web: 9 (Playwright)
  • Tests E2E mobile: 9 (Maestro flows)

Pipeline de audio en detalle

Guion YAML (humano)
  → validate.mjs
       ├ banlist
       ├ word count 280-345
       └ formato
  → render-ssml.mjs
       └ diccionario fonético catalán → fonética castellana (32 entradas)
  → render-tts.mjs
       └ ElevenLabs Multilingual v2 (3 idiomas × 3 voces)
  → master.mjs
       ├ loudnorm -16 LUFS
       ├ high-pass
       ├ compresión
       └ sting + outro
  → MP3 en /public/audio/

Crons activos con schedule

CronScheduleFunción
generate-post2 veces/día (09:00 + 18:00 UTC)Genera borrador de blog post
translate-postsLunes 07:30 UTCTraduce a CA/EN/FR/DE
email-dripDiario 09:00 UTCSecuencia nurturing
refresh-seoLunes 06:17 UTCAudita posiciones SEO
generate-socialLunes 08:00 UTCContenido social
weekly-summaryLunes 08:30 UTCResumen interno operador

Schemas JSON-LD (35 tipos)

AudioObject · AdministrativeArea · Answer · Article · BlogPosting · Brand · BreadcrumbList · ContactPoint · Country · EntryPoint · Event · FAQPage · GeoCoordinates · HowTo · HowToStep · ImageObject · ItemList · ListItem · LocationFeatureSpecification · LodgingBusiness · MerchantReturnPolicy · MobileApplication · Offer · Organization · Person · Place · PodcastEpisode · PodcastSeries · PostalAddress · PropertyValue · QuantitativeValue · Question · SearchAction · WebPage · WebSite

Verificación reproducible

# Build web
cd apps/web-react && npm run build

# Tests E2E web
npx playwright test

# Tests E2E mobile (requiere simulador iOS)
cd apps/mobile-expo && maestro test .maestro/

# Validar guion audio
node scripts/audio/validate.mjs scripts/audio/guiones/LP_01_arroz.yaml

# Pipeline audio completo (dry run)
node scripts/audio/pipeline.mjs --slug arroz-del-delta --lang es --dry

# Aplicar migraciones pendientes
psql "$NEON_CONNECTION_STRING" -f migrations/016_audio_plays.sql

# Contar URLs en sitemap
grep -c '<url>' apps/web-react/dist/sitemap.xml
# → 636

# Ver cron jobs
cat cloudflare/workers/cron/wrangler.toml | grep crons -A 20

URLs públicas verificables:

  • Web: https://lopeixapartments.com
  • Sitemap: https://lopeixapartments.com/sitemap.xml
  • Feed RSS audioguías: https://lopeixapartments.com/podcast.xml
  • Schemas JSON-LD: inspeccionables en cualquier URL con View Source

Glosario

TérminoDefinición
Delta del EbroHumedal y parque natural en Tarragona, desembocadura del río Ebro
La RàpitaSant Carles de la Ràpita, municipio costero del Delta, sede de Lo Peix
Concierge IAComponente conversacional embebido en la app móvil con conocimiento local del Delta
pgvectorExtensión PostgreSQL para búsqueda por similitud vectorial
ElevenLabs Multilingual v2Modelo TTS multilingüe usado para todas las audioguías del proyecto
Diccionario fonético32 alias catalanes mapeados a grafía fonética para pronunciación correcta en TTS
LUFSLoudness Units Full Scale, estándar de sonoridad para audio broadcast
DTCGDesign Tokens Community Group, formato estándar para design tokens
Drip emailSecuencia automatizada de emails post-suscripción
MaestroFramework de testing E2E para apps móviles basado en YAML
Mutex global de audioMecanismo CustomEvent que garantiza que solo un AudioPlayer reproduce simultáneamente
hreflangAtributo HTML que indica a Google la relación entre versiones idiomáticas

Caso lopeixapartments.com · Lectura desde dentro del oficio · Versión 1.0 · Junio 2026 Autoría: Joan Arbó · joanarbo.com