// ============================================================ // ESTUDIO RETÓRICA · Páginas internas // ============================================================ const RETORICA_IMAGES = { diada: getRetoricaAssetUrl('assets/Proyecto-nuevo-1.png'), redbuzz: getRetoricaAssetUrl('assets/Proyecto-nuevo.jpg'), signature: getRetoricaAssetUrl('assets/Proyecto-nuevo-3.png'), matrix: getRetoricaAssetUrl('assets/matrix-events-1.png'), disruptivos: getRetoricaAssetUrl('assets/Logo-Disruptivos-1.png'), tucanes: getRetoricaAssetUrl('assets/los-tucanes.png'), cultural: getRetoricaAssetUrl('assets/cultural-bytes.png'), eco: getRetoricaAssetUrl('assets/Eco3Planet-03.jpg'), editorial: getRetoricaAssetUrl('assets/1.png'), radical: getRetoricaAssetUrl('assets/3-1.png'), }; const imageStyle = (url, overlay = 'linear-gradient(180deg, rgba(0,0,0,0.03) 0%, rgba(0,0,0,0.18) 100%)') => ({ backgroundImage: `${overlay}, url(${url})`, }); const WHATSAPP_NUMBER = '34617492461'; const CONTACT_SERVICES = ['Identidad corporativa', 'Diseño web', 'Marketing digital', 'Contenido y audiovisual', 'Proyecto integral']; const buildWhatsappUrl = ({ name, email, service, message }) => { const text = [ 'Hola, quiero hablar con Estudio Retórica.', '', `Nombre: ${name || ''}`, `Email: ${email || ''}`, `Servicio de interés: ${service || ''}`, 'Mensaje:', message || '', ].join('\n'); return `https://api.whatsapp.com/send/?app_absent=0&phone=${WHATSAPP_NUMBER}&text=${encodeURIComponent(text)}&type=phone_number`; }; const portfolioProjects = [ { slug: 'matrix-events', name: 'Matrix Events', category: 'Eventos', summary: 'Identidad con fuerza visual para marcas y activaciones que necesitan presencia inmediata.', image: RETORICA_IMAGES.matrix, featured: true, span: 'page-card--span-6', services: ['Branding', 'Piezas de comunicación', 'Sistema de marca'], impact: 'Refuerza presencia, lectura y recordación en escenarios, piezas y formatos promocionales.', challenge: 'Necesidad de una identidad con lectura instantánea y suficiente presencia para convivir con entornos de alta energía visual.', approach: 'Se construyó un lenguaje de marca de contraste alto y aplicaciones directas para piezas, escenarios y activos promocionales.', deliverables: ['Identidad visual', 'Sistema cromático', 'Piezas de comunicación', 'Material promocional'], result: 'Un caso que transmite seguridad, impacto y una sensación de marca lista para operar en contextos presenciales.', related: ['disruptivos', 'diada-tec', 'eco3planet'], }, { slug: 'disruptivos', name: 'Disruptivos', category: 'Contenido', summary: 'Un universo gráfico más expresivo para video, podcast y comunicación digital.', image: RETORICA_IMAGES.disruptivos, featured: true, span: 'page-card--span-6', services: ['Branding', 'Contenido', 'Audiovisual'], impact: 'Permite adaptar la marca a covers, redes, reels y piezas editoriales con coherencia.', challenge: 'La marca debía sostenerse en múltiples formatos digitales y conservar personalidad sin perder claridad.', approach: 'Se enfatizó flexibilidad visual para portadas, activos sociales, piezas audiovisuales y contenidos editoriales.', deliverables: ['Sistema de marca', 'Assets para contenido', 'Aplicaciones para digital', 'Base visual para audiovisual'], result: 'Una identidad lista para moverse con facilidad entre contenido, social media y formatos audiovisuales.', related: ['cultural-bytes', 'matrix-events', 'proyecto-firma'], }, { slug: 'diada-tec', name: 'Diada Tec', category: 'Branding', summary: 'Lenguaje visual limpio y corporativo para una marca con lectura clara y actual.', image: RETORICA_IMAGES.diada, span: 'page-card--span-4', services: ['Logo', 'Aplicaciones', 'Sistema visual'], impact: 'Aporta solidez comercial y una presencia que se siente profesional desde el primer vistazo.', challenge: 'Conseguir una presentación más técnica y confiable sin recargar la comunicación.', approach: 'Se trabajó una estética limpia y ordenada, útil para lectura rápida y percepción corporativa.', deliverables: ['Logo', 'Sistema visual', 'Aplicaciones base'], result: 'Una marca con mejor balance entre claridad, profesionalismo y adaptabilidad.', related: ['matrix-events', 'eco3planet', 'redbuzz'], }, { slug: 'redbuzz', name: 'Redbuzz', category: 'Branding', summary: 'Marca de alto contraste con personalidad y aplicaciones versátiles.', image: RETORICA_IMAGES.redbuzz, span: 'page-card--span-4', services: ['Dirección visual', 'Branding', 'Piezas de marca'], impact: 'Eleva recordación y ayuda a diferenciar la marca con una estética de más carácter.', challenge: 'Crear una presencia fuerte y reconocible sin sacrificar versatilidad en piezas futuras.', approach: 'Se consolidó una línea de marca expresiva para sostener campañas, piezas y presencia digital.', deliverables: ['Branding', 'Piezas de marca', 'Dirección visual'], result: 'Una identidad de mayor impacto visual y mejor recordación.', related: ['proyecto-firma', 'los-tucanes', 'matrix-events'], }, { slug: 'proyecto-firma', name: 'Proyecto firma', category: 'Branding', summary: 'Dirección visual elegante para piezas personales o marcas con tono más editorial.', image: RETORICA_IMAGES.signature, span: 'page-card--span-4', services: ['Identidad', 'Editorial', 'Presentación'], impact: 'Aporta un tono más refinado, útil para propuestas de valor premium o consultivas.', challenge: 'Transmitir cuidado y un tono más editorial sin perder funcionalidad.', approach: 'Se trabajó una estética sobria y cuidada para reforzar percepción premium.', deliverables: ['Dirección visual', 'Piezas editoriales', 'Aplicaciones de presentación'], result: 'Un caso que eleva percepción de valor con un lenguaje más refinado.', related: ['redbuzz', 'disruptivos', 'proyecto-editorial'], }, { slug: 'los-tucanes', name: 'Los Tucanes', category: 'Branding', summary: 'Propuesta gráfica directa y llamativa para públicos de consumo masivo.', image: RETORICA_IMAGES.tucanes, span: 'page-card--span-4', services: ['Marca', 'Piezas promocionales', 'Aplicación visual'], impact: 'Favorece una comunicación popular, rápida y con alta visibilidad.', challenge: 'Lograr una comunicación popular y visible que sostuviera recordación.', approach: 'Se impulsó una línea gráfica frontal y reconocible, pensada para captar rápido.', deliverables: ['Marca', 'Piezas promocionales', 'Aplicaciones visuales'], result: 'Una propuesta más visible para públicos amplios y contextos de alta exposición.', related: ['redbuzz', 'matrix-events', 'cultural-bytes'], }, { slug: 'cultural-bytes', name: 'Cultural Bytes', category: 'Digital', summary: 'Activos pensados para entornos educativos, comunicación digital y recordación de marca.', image: RETORICA_IMAGES.cultural, span: 'page-card--span-4', services: ['Digital', 'Contenido', 'Branding'], impact: 'Hace más clara la conexión entre identidad, comunidad y piezas digitales.', challenge: 'Unir comunidad, educación y marca dentro de una presencia visual clara.', approach: 'Se desarrolló una base gráfica flexible para piezas digitales y comunicación recurrente.', deliverables: ['Assets digitales', 'Sistema visual', 'Piezas de comunicación'], result: 'Una identidad más lista para habitar entornos digitales y contenidos continuos.', related: ['disruptivos', 'eco3planet', 'los-tucanes'], }, { slug: 'eco3planet', name: 'Eco3Planet', category: 'Digital', summary: 'Presentación visual con look tecnológico y sensación de producto bien construido.', image: RETORICA_IMAGES.eco, span: 'page-card--span-4', services: ['Web', 'Presentación', 'Visual product'], impact: 'Refuerza percepción de innovación y ayuda a que la propuesta se sienta más sólida.', challenge: 'Comunicar innovación y solidez sin perder claridad en la propuesta.', approach: 'Se trabajó una presentación visual de tono tecnológico con una estructura más ordenada.', deliverables: ['Presentación visual', 'Web support', 'Activos de producto'], result: 'Un caso que eleva percepción de innovación y seriedad comercial.', related: ['diada-tec', 'cultural-bytes', 'matrix-events'], }, { slug: 'proyecto-editorial', name: 'Proyecto editorial', category: 'Branding', summary: 'Piezas editoriales y de marca para elevar la percepción premium.', image: RETORICA_IMAGES.editorial, span: 'page-card--span-4', services: ['Editorial', 'Branding', 'Comunicación'], impact: 'Aporta narrativa visual y una sensación de cuidado superior.', challenge: 'Construir piezas que comunicaran mayor cuidado y refinamiento.', approach: 'Se priorizó una dirección visual sobria y editorial para reforzar valor percibido.', deliverables: ['Piezas editoriales', 'Branding support', 'Comunicación'], result: 'Una propuesta más premium y con mejor lectura visual.', related: ['proyecto-firma', 'redbuzz', 'eco3planet'], }, { slug: 'radical-trainer', name: 'Radical Trainer', category: 'Branding', summary: 'Marca con presencia contundente y look deportivo/comercial.', image: RETORICA_IMAGES.radical, span: 'page-card--span-4', services: ['Logo', 'Aplicaciones', 'Branding'], impact: 'Construye una presencia fuerte que se reconoce rápido incluso en formatos grandes.', challenge: 'Generar una identidad potente y legible para una marca con energía alta.', approach: 'Se definió un sistema fuerte de contraste y lectura rápida para piezas físicas y digitales.', deliverables: ['Logo', 'Aplicaciones', 'Branding'], result: 'Una presencia contundente que comunica energía y recordación.', related: ['matrix-events', 'redbuzz', 'diada-tec'], }, ]; const portfolioFilters = ['Todos', 'Branding', 'Digital', 'Contenido', 'Eventos']; const getProjectBySlug = (slug) => portfolioProjects.find((item) => item.slug === slug) || portfolioProjects[0]; const usePortfolioPointer = (ref) => { React.useEffect(() => { const node = ref.current; if (!node) return; const setPosition = (clientX, clientY) => { const rect = node.getBoundingClientRect(); const x = clientX - rect.left; const y = clientY - rect.top; const px = rect.width ? x / rect.width : 0.5; const py = rect.height ? y / rect.height : 0.5; node.style.setProperty('--mx', `${(px * 100).toFixed(2)}%`); node.style.setProperty('--my', `${(py * 100).toFixed(2)}%`); node.style.setProperty('--rx', `${(py - 0.5) * -9}deg`); node.style.setProperty('--ry', `${(px - 0.5) * 10}deg`); }; const reset = () => { node.style.setProperty('--mx', '50%'); node.style.setProperty('--my', '50%'); node.style.setProperty('--rx', '0deg'); node.style.setProperty('--ry', '0deg'); }; reset(); const onMove = (event) => setPosition(event.clientX, event.clientY); const onTouchMove = (event) => { const touch = event.touches && event.touches[0]; if (touch) setPosition(touch.clientX, touch.clientY); }; node.addEventListener('mousemove', onMove); node.addEventListener('touchmove', onTouchMove, { passive: true }); node.addEventListener('mouseleave', reset); return () => { node.removeEventListener('mousemove', onMove); node.removeEventListener('touchmove', onTouchMove); node.removeEventListener('mouseleave', reset); }; }, [ref]); }; const PortfolioMotionStage = () => { const stageProjects = [getProjectBySlug('matrix-events'), getProjectBySlug('radical-trainer'), getProjectBySlug('disruptivos'), getProjectBySlug('cultural-bytes'), getProjectBySlug('eco3planet')]; const [active, setActive] = React.useState(stageProjects[0]); const [pulses, setPulses] = React.useState([]); const ref = React.useRef(null); usePortfolioPointer(ref); const launchPulse = (event) => { const rect = ref.current.getBoundingClientRect(); const pulse = { id: `${Date.now()}-${Math.random()}`, x: event.clientX - rect.left, y: event.clientY - rect.top, }; setPulses((current) => [...current, pulse]); window.setTimeout(() => setPulses((current) => current.filter((item) => item.id !== pulse.id)), 700); }; return (
); }; const PortfolioPage = () => { const [filter, setFilter] = React.useState('Todos'); const [activeProject, setActiveProject] = React.useState(portfolioProjects[0]); const visibleProjects = filter === 'Todos' ? portfolioProjects : portfolioProjects.filter((item) => item.category === filter); React.useEffect(() => { if (!visibleProjects.find((item) => item.name === activeProject.name)) { setActiveProject(visibleProjects[0] || portfolioProjects[0]); } }, [filter]); return ( <> Casos y clientes que convierten el trabajo en prueba social visible.} subtitle="Una selección de marcas y proyectos donde Retórica convirtió estrategia, diseño y contenido en una presencia más fuerte y vendible." ctaLabel="Ir a contacto" />
Selección destacada

Una vitrina de marcas que ya pasaron del concepto a una presencia con carácter.

Cada proyecto revela una parte del criterio de Retórica: marcas que se ven mejor, comunican mejor y llegan con más fuerza a su audiencia.

{['Branding', 'Digital', 'Contenido', 'Eventos', 'Identidad visual'].map((item) => ( {item} ))}
{portfolioFilters.map((item) => ( ))}
{visibleProjects.map((item) => (
{item.category}
{item.name}
{item.summary}
{item.services.slice(0, 3).map((service) => {service})}
Ver caso
))}
Proyecto en foco

{activeProject.name}

{activeProject.impact}

{activeProject.services.map((item) => ( {item} ))}
{portfolioProjects.map((item, index) => (
{item.name} {item.name}
))}
); }; const CasePage = () => { const search = new URLSearchParams(window.location.search); const project = getProjectBySlug(search.get('project')); const relatedProjects = project.related.map((slug) => getProjectBySlug(slug)).filter(Boolean); return ( <> {project.name}} subtitle={project.summary} bg="black" ctaLabel="Solicitar propuesta" ctaHref="/contacto/#contact" />
Resumen del caso

Un caso para ver cómo Retórica convierte intención en presencia de marca.

{project.impact}

{project.services.map((item) => {item})}
{[ ['Reto', project.challenge], ['Enfoque', project.approach], ['Entregables', project.deliverables.join(' · ')], ['Resultado', project.result], ].map(([title, text]) => (
{title}

{text}

))}
Más trabajo

Otros casos para seguir recorriendo el trabajo del estudio.

Ver todos
{relatedProjects.map((item) => (
{item.category}
{item.name}
{item.summary}
))}
Siguiente paso

¿Quieres una página, identidad o campaña con este nivel de presencia?

El sitio ya incluye brief inicial y contacto por WhatsApp para empezar una propuesta con mejor contexto desde el primer mensaje.

); }; const ServicesPage = () => ( <> Retórica articula branding, desarrollo web, marketing y contenido dentro de una sola propuesta de agencia.} subtitle="Branding, desarrollo web, marketing digital y contenido articulados para que una marca gane presencia, orden y capacidad comercial." bg="black" ctaLabel="Ver portafolio" ctaHref="/portafolio/" />
Capacidades

Una oferta más clara, estratégica y orientada a conversión.

    {['Identidad corporativa', 'Diseño web', 'Gestión de redes sociales', 'Buzoneo y street marketing', 'Posicionamiento web y marketing', 'Audiovisual y podcast'].map((item) => (
  • {item}
  • ))}
Qué comunica esta página

Todo lo que una marca necesita para verse mejor y vender con más fuerza.

Retórica conecta identidad, web, marketing y contenido para que la marca tenga una base coherente, atractiva y lista para salir a buscar resultados.

{[ { n: '01', title: 'Identidad corporativa', desc: 'Sistema visual, presentaciones, aplicaciones y tono verbal para construir reconocimiento.', items: ['Logo y versiones', 'Paleta y tipografía', 'Aplicaciones de marca', 'Piezas de presentación'], }, { n: '02', title: 'Diseño web', desc: 'Sitios a medida que presentan mejor el valor de la marca y funcionan como escaparate para clientes y oportunidades.', items: ['Home comercial', 'Páginas de servicio', 'Portafolio visual', 'Formularios y CTA'], }, { n: '03', title: 'Redes, SEO y marketing', desc: 'Una misma base para social media, posicionamiento web, contenido y campañas online.', items: ['Gestión de redes', 'Contenido editorial', 'SEO y captación', 'Landing de campaña'], }, { n: '04', title: 'Audiovisual y activaciones', desc: 'La propuesta también cubre reels, podcast, piezas visuales, fotografía, video y marketing directo.', items: ['Video y podcast', 'Fotografía', 'Street marketing', 'Buzoneo'], }, ].map((item) => (
{item.n}

{item.title}

{item.desc}

    {item.items.map((sub) =>
  • {sub}
  • )}
))}
); const StudioPage = () => ( <> Retórica pone el discurso en el centro para convertir marcas en presencia, presencia en confianza y confianza en negocio.} subtitle="Una agencia donde la estrategia verbal, la identidad visual y la ejecución digital trabajan juntas para mover una marca con más claridad y más intención." ctaLabel="Ver servicios" ctaHref="/servicios/" />
Qué define esta propuesta

Una agencia que piensa, diseña y activa marcas con una lógica clara de crecimiento.

Retórica trabaja desde una idea simple y poderosa: cuando el mensaje está bien construido, la marca se siente más sólida, el sitio convence más y el marketing encuentra mejor dirección.

Principios
    {['Propuesta de valor entendible desde la home', 'Más dinamismo sin sacrificar claridad', 'Portafolio organizado para explicar mejor el trabajo', 'Canales de contacto listos para convertir'].map((item) => (
  • {item}
  • ))}
{[ ['01', 'Atracción', 'La primera pantalla comunica mejor el perfil de agencia, su tono y la amplitud de servicios que puede articular.'], ['02', 'Confianza', 'Los proyectos, clientes y casos funcionan como prueba visible del criterio y la capacidad de ejecución de Retórica.'], ['03', 'Conversión', 'Brief, correo y WhatsApp facilitan el inicio de la conversación, la solicitud de propuesta y la maduración del lead.'], ].map(([year, title, text]) => (
{year}
{title}

{text}

))}
); const JournalContactSection = () => { const [sent, setSent] = React.useState(false); const [waUrl, setWaUrl] = React.useState(''); const [form, setForm] = React.useState({ name: '', email: '', service: CONTACT_SERVICES[0], message: '', }); const handleChange = (key, value) => setForm((prev) => ({ ...prev, [key]: value })); const handleSubmit = (e) => { e.preventDefault(); const url = buildWhatsappUrl(form); setWaUrl(url); setSent(true); window.open(url, '_blank', 'noopener'); }; return (
Formulario de contacto

Cuéntanos qué necesita tu marca y llevemos la conversación a una propuesta clara.

Si ya tienes una idea, un sitio por mejorar, una campaña por lanzar o una marca por ordenar, este formulario ayuda a que Retórica reciba el contexto correcto desde el primer mensaje.

{!sent ? ( <>
handleChange('name', e.target.value)} required />
handleChange('email', e.target.value)} required />
{CONTACT_SERVICES.map((service) => ( ))}