**I. Estructura y Componentes Lógicos:** La página web se puede descomponer en los siguientes componentes lógicos de React, envueltos por un `PageContainer` principal que gestiona el ancho máximo y el centrado del contenido. 1. **PageContainer (`src/components/PageContainer.tsx`):** * **Descripción:** Componente contenedor global que define el `max-width` (aproximadamente `1280px`) y `margin: 0 auto` para centrar todo el contenido de la página. * **Jerarquía DOM Clave:** `div.pageContainer`. 2. **Header (`src/components/Header/Header.tsx`):** * **Descripción:** Contiene el logo de la marca, la navegación principal con enlaces y dropdowns, y un botón de "Empecemos" (Get started). * **Jerarquía DOM Clave:** `
` que contiene un `
` para el logo y un `
); }; export default Header; ``` **`src/components/Header/Header.module.css`** ```css /* src/components/Header/Header.module.css */ .header { display: flex; justify-content: space-between; /* Espacia el logo y la navegación */ align-items: center; padding: 16px 20px; /* Padding interno */ height: 80px; /* Altura fija */ background-color: var(--bg-white); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); /* Sombra sutil */ position: sticky; /* Sticky header */ top: 0; z-index: 1000; /* Asegura que el header esté por encima de otros elementos */ } .logo img { height: 40px; /* Altura del logo */ width: auto; } .nav { display: flex; /* Por defecto, flex para escritorio */ } .navList { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; gap: 30px; /* Espacio entre elementos de navegación */ } .navLink { text-decoration: none; color: var(--text-medium); font-weight: 500; font-size: 16px; padding: 8px 0; transition: color 0.3s ease; display: flex; align-items: center; gap: 4px; /* Espacio para el icono de chevron */ } .navLink:hover { color: var(--primary-blue); /* Color al pasar el ratón */ } .getStartedButton { background-color: var(--primary-blue); color: var(--bg-white); border: none; border-radius: var(--border-radius-button); padding: 12px 24px; font-size: 16px; font-weight: 600; cursor: pointer; transition: background-color 0.3s ease; } .getStartedButton:hover { background-color: #0056e6; /* Azul más oscuro al pasar el ratón */ } /* Estilos para el menú dropdown */ .navItemDropdown { position: relative; } .dropdownMenu { position: absolute; top: 100%; /* Debajo del elemento padre */ left: 0; background-color: var(--bg-white); box-shadow: var(--shadow-sm); border-radius: var(--border-radius-input); list-style: none; padding: 10px 0; margin-top: 5px; /* Pequeño espacio entre el link y el dropdown */ min-width: 200px; /* Ancho ajustado para los ítems con icono */ display: none; /* Oculto por defecto, se muestra con JS */ flex-direction: column; z-index: 1010; } .navItemDropdown:hover .dropdownMenu { display: flex; /* Mostrar en hover para desktop */ } .dropdownMenu li a { display: flex; /* Para alinear el icono y el texto */ align-items: center; gap: 10px; /* Espacio entre icono y texto */ padding: 8px 15px; color: var(--text-medium); text-decoration: none; font-size: 15px; } .dropdownMenu li a:hover { background-color: var(--bg-light-grey); color: var(--primary-blue); } /* Estilos para los iconos dentro del dropdown */ .dropdownMenu li a svg { color: var(--text-light); /* Color del icono por defecto */ transition: color 0.3s ease; } .dropdownMenu li a:hover svg { color: var(--primary-blue); /* Color del icono al pasar el ratón */ } /* Menú de hamburguesa (visible solo en móvil) */ .menuToggle { display: none; /* Oculto por defecto */ background: none; border: none; cursor: pointer; padding: 0; } /* Responsive: Mobile styles */ @media (max-width: 1024px) { .navList { gap: 20px; /* Reduce el espacio entre elementos */ } } @media (max-width: 768px) { .header { padding: 16px; height: 60px; /* Reduce la altura del header en móvil */ } .nav { display: none; /* Oculta la navegación por defecto en móvil */ flex-direction: column; position: absolute; top: 60px; /* Debajo del header */ left: 0; width: 100%; background-color: var(--bg-white); box-shadow: var(--shadow-sm); padding: 20px 0; z-index: 999; /* Animación de deslizamiento */ transform: translateY(-100%); transition: transform 0.3s ease-out; } .nav.navOpen { display: flex; /* Muestra el menú cuando está abierto */ transform: translateY(0); } .navList { flex-direction: column; align-items: flex-start; gap: 10px; } .navList li { width: 100%; padding: 8px 20px; /* Padding para los ítems del menú móvil */ } .navLink { width: 100%; } .navItemDropdown { width: 100%; } .navItemDropdown:hover .dropdownMenu { display: none; /* Deshabilita el hover en mobile, se activa con click */ } .navItemDropdown .dropdownMenu { position: static; /* Cambia a posición estática para que fluya en el menú móvil */ box-shadow: none; border-radius: 0; padding-left: 20px; /* Indentación para sub-items */ margin-top: 0; display: none; /* Oculto por defecto en móvil */ } /* Mostrar dropdowns en móvil al hacer click (aria-expanded="true" lo controla) */ .navItemDropdown a[aria-expanded="true"] + .dropdownMenu { display: flex; } .menuToggle { display: block; /* Muestra el botón de hamburguesa */ } .getStartedButton { width: calc(100% - 40px); /* Ajuste de ancho para botón en móvil */ margin: 10px 20px; text-align: center; } } ``` **`src/components/HeroSection/HeroSection.tsx`** ```tsx import React from 'react'; import styles from './HeroSection.module.css'; const HeroSection: React.FC = () => { // Simula la redirección a una página de registro/inicio de sesión const handleFormAction = () => { console.log("Redirecting to signup page..."); // En una aplicación real: window.location.href = '/signup'; alert("Simulando redirección a /signup"); }; return (

La manera más sencilla de grabar y transmitir en vivo

StreamYard es un estudio profesional para grabar y hacer transmisiones en vivo desde tu navegador. Graba contenido o transmite en vivo a Facebook, YouTube y otras plataformas.

{/* Botón de "Continuar con Google" con texto pre-rellenado simulado */}
O continúa con tu correo electrónico

¡Confiado por más de 12,000,000 creadores!
Al continuar, aceptas nuestros Términos de Servicio del Usuario y{' '} Política de uso del Plan y reconoces la recepción de nuestra Política de Privacidad

¿Ya usas StreamYard? Inicia sesión.

{/* Gráfico de fondo, ahora en el container del formulario para mejor posicionamiento */} StreamYard Interface Graphic
); }; export default HeroSection; ``` **`src/components/HeroSection/HeroSection.module.css`** ```css /* src/components/HeroSection/HeroSection.module.css */ .heroSection { display: flex; justify-content: center; align-items: center; padding: 100px 0; /* Espaciado vertical */ background: linear-gradient(to bottom, var(--light-blue-gradient-start), var(--bg-white)); /* Gradiente de fondo */ gap: 80px; /* Espacio entre el contenido de texto y el formulario */ flex-wrap: wrap; /* Permite que los elementos se envuelvan en pantallas más pequeñas */ } .heroContent { flex: 1; /* Ocupa el espacio disponible */ min-width: 300px; /* Ancho mínimo para el texto */ max-width: 600px; /* Ancho máximo para el texto */ } .heroContent h1 { font-size: var(--font-size-h1); font-weight: var(--font-weight-h1); line-height: var(--line-height-h1); color: var(--text-dark); } .heroContent p { font-size: var(--font-size-p); line-height: var(--line-height-p); color: var(--text-medium); max-width: 500px; /* Limita el ancho del párrafo */ } .heroFormContainer { position: relative; display: flex; flex-direction: column; align-items: flex-end; /* Alinea el formulario y el gráfico a la derecha */ min-width: 350px; } .heroForm { background-color: var(--bg-white); border-radius: var(--border-radius-card); /* Radio de borde para el formulario */ box-shadow: var(--shadow-sm); /* Sombra para el formulario */ padding: 30px; display: flex; flex-direction: column; gap: 15px; /* Espacio entre elementos del formulario */ width: 380px; /* Ancho fijo para el formulario */ z-index: 1; /* Asegura que el formulario esté sobre el gráfico */ } .googleButton { background-color: var(--bg-white); border: 1px solid var(--border-light); border-radius: var(--border-radius-button); padding: 12px 20px; font-size: 16px; font-weight: 500; color: var(--text-medium); display: flex; flex-direction: column; /* Apila el texto principal y el email */ align-items: center; justify-content: center; gap: 5px; /* Espacio entre las líneas de texto */ cursor: pointer; transition: background-color 0.3s ease; } .googleButton:hover { background-color: var(--bg-light-grey); } .googleButton img { position: absolute; /* Posiciona el logo de Google */ left: 20px; height: 20px; width: 20px; } .googleEmail { font-size: 12px; color: var(--text-light); } .separator { text-align: center; font-size: var(--font-size-sm); color: var(--text-light); position: relative; margin: 10px 0; } .separator::before, .separator::after { content: ''; position: absolute; top: 50%; width: 40%; height: 1px; background-color: var(--border-light); } .separator::before { left: 0; } .separator::after { right: 0; } .emailInput { border: 1px solid var(--border-light); border-radius: var(--border-radius-input); padding: 14px 15px; font-size: 16px; width: calc(100% - 30px); /* Ajusta el ancho por el padding */ } .emailInput:focus { outline: none; border-color: var(--primary-blue); box-shadow: 0 0 0 2px rgba(0, 102, 255, 0.2); } .getStartedButton { background-color: var(--primary-blue); color: var(--bg-white); border: none; border-radius: var(--border-radius-button); padding: 16px 20px; font-size: 18px; font-weight: 600; cursor: pointer; transition: background-color 0.3s ease; } .getStartedButton:hover { background-color: #0056e6; } .formFooterText { font-size: 13px; color: var(--text-light); text-align: center; margin-top: 10px; } .formFooterText a, .loginText a { color: var(--primary-blue); text-decoration: none; } .loginText { font-size: var(--font-size-sm); color: var(--text-medium); text-align: center; margin-top: 15px; } .heroGraphic { position: absolute; top: -80px; /* Posiciona el gráfico flotando por encima del formulario */ right: -100px; /* Ajusta la posición del gráfico */ width: 450px; /* Tamaño del gráfico */ height: auto; opacity: 0.8; /* Transparencia para que parezca de fondo */ z-index: 0; /* Detrás del formulario */ filter: blur(1px); /* Ligero desenfoque */ } /* Responsive adjustments */ @media (max-width: 1024px) { .heroSection { flex-direction: column; /* Apila el contenido y el formulario */ padding: 80px 0; gap: 50px; } .heroContent { text-align: center; max-width: 90%; margin: 0 auto; } .heroContent h1 { font-size: 52px; } .heroContent p { font-size: 17px; } .heroFormContainer { align-items: center; /* Centra el formulario */ min-width: unset; width: 100%; } .heroForm { width: 85%; /* El formulario ocupa más ancho en móviles */ max-width: 450px; /* Limita el ancho del formulario */ } .heroGraphic { position: static; /* Quita el posicionamiento absoluto en móvil */ margin-top: 30px; width: 80%; max-width: 400px; opacity: 1; filter: none; } } @media (max-width: 768px) { .heroSection { padding: 60px 0; } .heroContent h1 { font-size: 40px; } .heroForm { width: 95%; /* Aún más ancho en pantallas más pequeñas */ padding: 20px; } } @media (max-width: 480px) { .heroContent h1 { font-size: 32px; } .heroContent p { font-size: 16px; } .googleButton { padding: 12px 10px; font-size: 14px; } .googleButton img { left: 10px; } } ``` **`src/components/FeaturesGrid/FeaturesGrid.tsx`** ```tsx import React, { useState, useRef } from 'react'; import styles from './FeaturesGrid.module.css'; // Mock data for features const features = [ { id: 1, name: 'Marca', icon: 'https://via.placeholder.com/64?text=Marca' }, { id: 2, name: 'Podcasts', icon: 'https://via.placeholder.com/64?text=Podcasts' }, { id: 3, name: 'Reutilización de Video', icon: 'https://via.placeholder.com/64?text=Reutilizar' }, { id: 4, name: 'Seminarios web', icon: 'https://via.placeholder.com/64?text=Seminarios' }, { id: 5, name: 'Participación', icon: 'https://via.placeholder.com/64?text=Partic' }, { id: 6, name: 'Grabación', icon: 'https://via.placeholder.com/64?text=Grab' }, { id: 7, name: 'Transmisión múltiple', icon: 'https://via.placeholder.com/64?text=Multi' }, { id: 8, name: 'Invitados', icon: 'https://via.placeholder.com/64?text=Invitados' }, ]; const FeaturesGrid: React.FC = () => { const scrollRef = useRef(null); const scroll = (direction: 'left' | 'right') => { if (scrollRef.current) { const scrollAmount = 300; // Cantidad de desplazamiento if (direction === 'left') { scrollRef.current.scrollBy({ left: -scrollAmount, behavior: 'smooth' }); } else { scrollRef.current.scrollBy({ left: scrollAmount, behavior: 'smooth' }); } } }; // Simula la redirección al hacer clic en una tarjeta de característica const handleFeatureClick = (featureName: string) => { console.log(`Clicked feature: ${featureName}. Redirecting to signup page...`); // En una aplicación real: window.location.href = `/signup?feature=${encodeURIComponent(featureName)}`; alert(`Simulando redirección a /signup por la característica: ${featureName}`); }; return (
{/* Flecha de navegación izquierda */}
{features.map((feature) => (
handleFeatureClick(feature.name)}> {feature.name}

{feature.name}

))}
{/* Flecha de navegación derecha */}
); }; export default FeaturesGrid; ``` **`src/components/FeaturesGrid/FeaturesGrid.module.css`** ```css /* src/components/FeaturesGrid/FeaturesGrid.module.css */ .featuresSection { padding: 50px 0 100px 0; /* Menos padding superior, más inferior */ background-color: var(--bg-white); /* Fondo blanco, no gris */ text-align: center; /* Centra el texto */ } .carouselContainer { position: relative; max-width: 1200px; /* Ancho máximo para el carrusel */ margin: 0 auto; display: flex; align-items: center; } .featuresGrid { display: flex; overflow-x: auto; /* Permite el desplazamiento horizontal */ -webkit-overflow-scrolling: touch; /* Suaviza el scroll en iOS */ scroll-snap-type: x mandatory; /* Ajuste para el scroll-snap */ gap: 30px; /* Espacio entre las tarjetas */ padding: 20px; /* Padding para evitar que las tarjetas toquen los bordes */ margin: 0 -20px; /* Compensa el padding para que el contenido fluya */ scrollbar-width: none; /* Oculta la barra de desplazamiento en Firefox */ } /* Oculta la barra de desplazamiento en Chrome/Safari */ .featuresGrid::-webkit-scrollbar { display: none; } .featureCard { flex: 0 0 auto; /* No permite que las tarjetas se encojan */ width: 220px; /* Ancho fijo de la tarjeta */ height: 220px; /* Altura fija para que sean cuadradas */ background-color: var(--bg-white); border-radius: var(--border-radius-card); box-shadow: var(--shadow-sm); display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 20px; text-align: center; scroll-snap-align: start; /* Alineación para el scroll-snap */ transition: transform 0.3s ease, box-shadow 0.3s ease; cursor: pointer; border: 1px solid var(--border-light); /* Borde sutil */ } .featureCard:hover { transform: translateY(-5px); /* Pequeño efecto de elevación */ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1); } .featureIcon { width: 64px; /* Tamaño del icono */ height: 64px; margin-bottom: 15px; } .featureCard h3 { font-size: 20px; font-weight: 600; color: var(--text-dark); margin: 0; } .navArrow { position: absolute; top: 50%; transform: translateY(-50%); background-color: var(--bg-white); border: 1px solid var(--border-light); border-radius: 50%; /* Botones circulares */ width: 50px; height: 50px; display: flex; justify-content: center; align-items: center; font-size: 24px; cursor: pointer; z-index: 10; box-shadow: var(--shadow-sm); transition: background-color 0.3s ease, transform 0.3s ease; } .navArrow:hover { background-color: var(--bg-light-grey); transform: translateY(-50%) scale(1.05); } .leftArrow { left: -25px; /* Posicionar fuera del grid */ } .rightArrow { right: -25px; /* Posicionar fuera del grid */ } /* Responsive adjustments */ @media (max-width: 1280px) { .leftArrow { left: 0px; /* Mueve las flechas dentro del padding del contenedor principal */ } .rightArrow { right: 0px; } } @media (max-width: 768px) { .featuresSection { padding: 30px 0 60px 0; /* Ajuste padding */ } .featuresGrid { gap: 20px; /* Reduce el espacio entre tarjetas */ padding: 15px; margin: 0 -15px; } .featureCard { width: 180px; /* Reduce el tamaño de las tarjetas */ height: 180px; padding: 15px; } .featureIcon { width: 50px; height: 50px; } .featureCard h3 { font-size: 18px; } .navArrow { width: 40px; height: 40px; font-size: 20px; } } @media (max-width: 480px) { .featuresGrid { padding: 10px; margin: 0 -10px; } .featureCard { width: 150px; /* Aún más pequeñas */ height: 150px; } .navArrow { display: none; /* Oculta las flechas si el scroll es el método principal */ } } ``` **`src/components/ContentDetailsSection/ContentDetailsSection.tsx`** ```tsx import React, { useState } from 'react'; import styles from './ContentDetailsSection.module.css'; // Mock component for Play/Pause icon const PlayIcon = () => ( ); const PauseIcon = () => ( ); const ContentDetailsSection: React.FC = () => { const [isPlayingAudio, setIsPlayingAudio] = useState(false); const [audioProgress, setAudioProgress] = useState(0); const audioIntervalRef = React.useRef(undefined); // Simula la reproducción de audio const handlePlayPauseAudio = () => { if (isPlayingAudio) { // Pausar setIsPlayingAudio(false); if (audioIntervalRef.current) { clearInterval(audioIntervalRef.current); } setAudioProgress(0); // Reinicia el progreso al pausar } else { // Reproducir setIsPlayingAudio(true); let currentProgress = 0; audioIntervalRef.current = window.setInterval(() => { currentProgress += 10; // Incrementa el progreso if (currentProgress > 100) { currentProgress = 0; setIsPlayingAudio(false); if (audioIntervalRef.current) { clearInterval(audioIntervalRef.current); } } setAudioProgress(currentProgress); }, 500); // Actualiza cada 0.5 segundos } }; React.useEffect(() => { // Limpieza al desmontar el componente return () => { if (audioIntervalRef.current) { clearInterval(audioIntervalRef.current); } }; }, []); return (
{/* Sección 1: Transmite en vivo o graba podcasts con invitados remotos */}

Transmite en vivo o graba podcasts con invitados remotos

Los invitados pueden unirse fácilmente desde su navegador o teléfono en unos pocos clics. No hace falta descargar ningún software.

Más información →
Remote Guests
{/* Sección 2: Grabaciones con calidad de estudio, independientemente de tu conexión */}
Studio Quality
Haz clic para oír la diferencia

Grabaciones con calidad de estudio, independientemente de tu conexión

¿Te cansaste de que tus podcasts queden arruinados con Zoom y Skype? Con las grabaciones locales, se graba un archivo de audio y video por separado en el dispositivo de cada usuario. Incluso si la persona tiene una conexión a Internet débil, las grabaciones no estarán borrosas ni entrecortadas.

Descubre más →
{/* Sección 3: Haz transmisiones múltiples a varias plataformas a la vez */}

Haz transmisiones múltiples a varias plataformas a la vez

Transmite a Facebook, YouTube, Instagram, LinkedIn, X (Twitter), Twitch, y más. Haz que tu público se sienta especial mostrando sus comentarios en pantalla.

Ver todas las integraciones →
Multistream
{/* Sección 4: Lleva tus seminarios web a StreamYard On Air */}
Webinars

Lleva tus seminarios web a StreamYard On Air

StreamYard On-Air es una plataforma de seminarios web en vivo. Estamos redefiniendo los conceptos de estabilidad, simplicidad y calidad de producción para los seminarios web. Incluso puedes insertarlos en tu sitio web para una experiencia de marca totalmente personalizada.

Entérate de por qué todo el mundo está haciendo el cambio →
); }; export default ContentDetailsSection; ``` **`src/components/ContentDetailsSection/ContentDetailsSection.module.css`** ```css /* src/components/ContentDetailsSection/ContentDetailsSection.module.css */ .contentDetailsSection { padding: 0; /* Las secciones internas manejan su propio padding */ } .contentBlock { display: flex; align-items: center; gap: 80px; /* Espacio entre columnas */ padding: 100px 0; /* Espaciado vertical entre bloques */ margin-bottom: 0; /* Cada bloque es una sección, no necesita margen inferior extra */ flex-wrap: wrap; /* Permite envolver columnas en pantallas pequeñas */ } /* Fondos de sección */ .bgPink { background-color: var(--accent-pink); } .bgPurple { background-color: var(--accent-purple); color: var(--bg-white); /* Texto blanco para fondo oscuro */ } .bgPurple h2, .bgPurple p, .bgPurple .learnMoreLink { color: var(--bg-white); } .bgYellow { background-color: var(--accent-yellow); } .bgBlueish { background-color: #EBF7FF; /* Un azul muy claro */ } .textColumn { flex: 1; /* Ocupa el espacio disponible */ min-width: 300px; max-width: 600px; /* Limita el ancho del texto */ } .imageColumn { flex: 1; /* Ocupa el espacio disponible */ min-width: 300px; display: flex; justify-content: center; /* Centra la imagen dentro de su columna */ align-items: center; } .contentImage { max-width: 100%; /* Asegura que la imagen no se desborde */ height: auto; border-radius: var(--border-radius-card); box-shadow: var(--shadow-sm); } .reverseLayout { flex-direction: row-reverse; /* Invierte el orden de las columnas */ } .learnMoreLink { color: var(--primary-blue); text-decoration: none; font-weight: 600; transition: color 0.3s ease; display: inline-flex; align-items: center; gap: 5px; margin-top: 15px; } .bgPurple .learnMoreLink { color: var(--bg-white); } .learnMoreLink:hover { color: #0047b3; /* Azul más oscuro al pasar el ratón */ } /* Estilos para el reproductor de audio simulado */ .audioPlayer { position: relative; width: 100%; max-width: 500px; /* Ancho máximo para el reproductor */ border-radius: var(--border-radius-card); box-shadow: var(--shadow-sm); overflow: hidden; /* Asegura que la imagen y los controles respeten el borde */ } .audioPlayer .contentImage { border-radius: 0; /* La imagen no necesita borde-radius si el contenedor ya lo tiene */ display: block; /* Elimina espacios extra debajo de la imagen */ } .audioControls { position: absolute; bottom: 20px; left: 20px; right: 20px; background-color: rgba(255, 255, 255, 0.9); /* Fondo semitransparente para los controles */ border-radius: var(--border-radius-button); padding: 10px 15px; display: flex; align-items: center; gap: 15px; box-shadow: var(--shadow-sm); } .playPauseButton { background: none; border: none; color: var(--primary-blue); cursor: pointer; padding: 0; display: flex; align-items: center; } .playPauseButton svg { width: 30px; height: 30px; } .progressBarContainer { flex-grow: 1; height: 8px; background-color: var(--border-light); border-radius: 4px; overflow: hidden; } .progressBar { height: 100%; background-color: var(--primary-blue); width: 0%; /* Controlado por el estado de React */ transition: width 0.1s linear; /* Animación suave para el progreso */ } .audioLabel { font-size: var(--font-size-sm); color: var(--text-medium); white-space: nowrap; /* Evita que el texto se rompa */ } /* Responsive adjustments */ @media (max-width: 1024px) { .contentBlock { flex-direction: column; /* Apila las columnas */ text-align: center; padding: 80px 0; gap: 40px; } .reverseLayout { flex-direction: column; /* También apila en layout invertido */ } .textColumn, .imageColumn { max-width: 90%; /* Ajusta el ancho para móvil */ margin: 0 auto; /* Centra las columnas */ } .audioControls { bottom: 15px; left: 15px; right: 15px; padding: 8px 10px; gap: 10px; } .playPauseButton svg { width: 25px; height: 25px; } .audioLabel { font-size: 12px; } } @media (max-width: 768px) { .contentBlock { padding: 60px 0; gap: 30px; } .textColumn h2 { font-size: 32px; } .textColumn p { font-size: 16px; } } @media (max-width: 480px) { .textColumn h2 { font-size: 28px; } } ``` **`src/components/TestimonialsCarousel/TestimonialsCarousel.tsx`** ```tsx import React, { useState, useRef } from 'react'; import styles from './TestimonialsCarousel.module.css'; // Mock data for testimonials const testimonials = [ { id: 1, quote: "Me ENCANTA la simplicidad y la flexibilidad de StreamYard, así como su capacidad de crear y distribuir producciones de buena calidad que se transmiten maravillosamente a través de plataformas de transmisión de TV.", author: "Kisa Puckett", }, { id: 2, quote: "Esto es la razón por la que uso #TheYard. Tuve que reiniciar la computadora en medio de la grabación debido a un ligero pico de tensión, ¡y no perdí nada!", author: "Avery Johnson", }, { id: 3, quote: "Me encanta la combinación de elegancia y la sencillez que ofrece StreamYard. Lo usamos para transmitir nuestro programa semanal de entrevistas de marketing en redes sociales en YouTube, Facebook y LinkedIn. Como presentador, puedo crear sin esfuerzo un programa atractivo sin una persona que se dedique al back-end.", author: "Michael Steltzner", }, { id: 4, quote: "Pasarme de Zoom a StreamYard para mi podcast fue lo mejor que he hecho por mi programa. ¡Gracias por el consejo, Melanie D Brown!", author: "Sonali BestLife Jones", }, { id: 5, quote: "Recomiendo a StreamYard a todo el mundo. Casi dos tercios de mis clientes provienen de mis programas en vivo. Le agradezco de corazón a StreamYard por hacer que las transmisiones en vivo sean tan sencillas, de modo que no tenga que preocuparme por la parte técnica. Solo me enfoco en ejecutar mis programas y hacer mi negocio crezca.", author: "Dr. Al Aidyyan Zhang", }, { id: 6, quote: "StreamYard es un servicio fantástico. La fiabilidad y facilidad para los participantes en pantalla es fenomenal. Además, StreamYard hace que este proceso sea prácticamente infalible.", author: "Matt Schick", }, ]; const TestimonialsCarousel: React.FC = () => { const [currentIndex, setCurrentIndex] = useState(0); const carouselRef = useRef(null); const totalSlides = testimonials.length; // Asumiendo 3 tarjetas visibles a la vez en escritorio const slidesPerPage = 3; const goToSlide = (index: number) => { setCurrentIndex(index); if (carouselRef.current) { const cardWidth = carouselRef.current.children[0]?.clientWidth || 0; const gap = 30; // Definido en CSS carouselRef.current.scrollTo({ left: index * (cardWidth + gap), behavior: 'smooth', }); } }; const nextSlide = () => { const nextIndex = (currentIndex + 1) % totalSlides; goToSlide(nextIndex); }; const prevSlide = () => { const prevIndex = (currentIndex - 1 + totalSlides) % totalSlides; goToSlide(prevIndex); }; return (

Ya se crearon más de 60 millones de transmisiones y grabaciones en StreamYard

{testimonials.map((testimonial) => (

"{testimonial.quote}"

{testimonial.author}

))}
{Array.from({ length: Math.ceil(totalSlides / slidesPerPage) }).map((_, idx) => ( goToSlide(idx * slidesPerPage)} aria-label={`Go to slide ${idx + 1}`} > ))}
); }; export default TestimonialsCarousel; ``` **`src/components/TestimonialsCarousel/TestimonialsCarousel.module.css`** ```css /* src/components/TestimonialsCarousel/TestimonialsCarousel.module.css */ .testimonialsSection { padding: 100px 0; background-color: var(--bg-white); text-align: center; } .testimonialsSection h2 { margin-bottom: 50px; max-width: 800px; margin-left: auto; margin-right: auto; } .carouselContainer { position: relative; max-width: 1200px; margin: 0 auto; display: flex; align-items: center; } .testimonialsGrid { display: flex; overflow-x: hidden; /* Controlado por JS, no scroll nativo */ gap: 30px; padding: 20px; margin: 0 -20px; -webkit-overflow-scrolling: touch; } .testimonialCard { flex: 0 0 auto; /* No permite que se encojan */ width: calc((100% / 3) - 20px); /* Aproximadamente 3 tarjetas por vista con gap */ max-width: 380px; /* Ancho máximo para una tarjeta individual */ min-width: 300px; /* Ancho mínimo para la tarjeta en pantallas pequeñas */ background-color: var(--bg-white); border-radius: var(--border-radius-card); box-shadow: var(--shadow-sm); padding: 30px; text-align: left; display: flex; flex-direction: column; justify-content: space-between; /* Espacia la cita y el autor */ border: 1px solid var(--border-light); } .quote { font-size: 18px; line-height: 1.6; color: var(--text-medium); margin-bottom: 20px; font-style: italic; } .author { font-size: 16px; font-weight: 600; color: var(--text-dark); margin: 0; } .navArrow { position: absolute; top: 50%; transform: translateY(-50%); background-color: var(--bg-white); border: 1px solid var(--border-light); border-radius: 50%; width: 50px; height: 50px; display: flex; justify-content: center; align-items: center; font-size: 24px; cursor: pointer; z-index: 10; box-shadow: var(--shadow-sm); transition: background-color 0.3s ease, transform 0.3s ease; } .navArrow:hover { background-color: var(--bg-light-grey); transform: translateY(-50%) scale(1.05); } .leftArrow { left: -25px; } .rightArrow { right: -25px; } .paginationDots { display: flex; justify-content: center; gap: 10px; margin-top: 30px; } .dot { width: 10px; height: 10px; background-color: var(--border-light); border-radius: 50%; cursor: pointer; transition: background-color 0.3s ease, transform 0.3s ease; } .dot.active { background-color: var(--primary-blue); transform: scale(1.2); } /* Responsive adjustments */ @media (max-width: 1280px) { .leftArrow { left: 0px; } .rightArrow { right: 0px; } } @media (max-width: 1024px) { .testimonialCard { width: calc((100% / 2) - 15px); /* 2 tarjetas por vista en tablets */ } } @media (max-width: 768px) { .testimonialsSection { padding: 60px 0; } .testimonialsSection h2 { font-size: 32px; } .testimonialsGrid { gap: 20px; padding: 15px; margin: 0 -15px; } .testimonialCard { width: 90%; /* 1 tarjeta por vista en móviles, ocupa casi todo el ancho */ max-width: 400px; margin: 0 auto; /* Centra la tarjeta */ padding: 25px; } .navArrow { width: 40px; height: 40px; font-size: 20px; } } @media (max-width: 480px) { .testimonialsSection h2 { font-size: 28px; } .navArrow { display: none; /* Oculta flechas en pantallas muy pequeñas, usa el scroll nativo si se habilita */ } .testimonialCard { min-width: unset; /* Permite que la tarjeta se encoja más si es necesario */ } } ``` **`src/components/CallToActionSection/CallToActionSection.tsx`** ```tsx import React from 'react'; import styles from './CallToActionSection.module.css'; const CallToActionSection: React.FC = () => { const handleGetStartedClick = () => { console.log("Redirecting to signup page from CTA..."); // En una aplicación real: window.location.href = '/signup'; alert("Simulando redirección a /signup"); }; return (

Empieza a crear.

Únete a millones de usuarios de StreamYard y empieza con tus transmisiones o tu podcast hoy mismo.

); }; export default CallToActionSection; ``` **`src/components/CallToActionSection/CallToActionSection.module.css`** ```css /* src/components/CallToActionSection/CallToActionSection.module.css */ .ctaSection { background-color: var(--primary-blue); /* Fondo azul */ /* Imagen de fondo sutil con patrón geométrico */ background-image: url('data:image/svg+xml;utf8,'); background-size: 200px 200px; /* Tamaño del patrón */ color: var(--bg-white); /* Texto blanco */ text-align: center; padding: 120px 20px; /* Espaciado interno */ margin-top: 100px; /* Espacio superior para separar de la sección anterior */ } .ctaContent { max-width: 700px; /* Ancho máximo para el contenido del CTA */ margin: 0 auto; } .ctaContent h2 { font-size: var(--font-size-h2); color: var(--bg-white); margin-bottom: 25px; } .ctaButton { background-color: var(--bg-white); /* Botón blanco sobre fondo azul */ color: var(--primary-blue); border: none; border-radius: var(--border-radius-button); padding: 18px 36px; font-size: 20px; font-weight: 700; cursor: pointer; transition: background-color 0.3s ease, transform 0.3s ease; margin-bottom: 20px; } .ctaButton:hover { background-color: #f0f0f0; /* Ligero cambio de color al pasar el ratón */ transform: translateY(-2px); /* Pequeño efecto de elevación */ } .ctaContent p { font-size: var(--font-size-p); color: rgba(255, 255, 255, 0.8); /* Texto más claro */ margin: 0; } /* Responsive adjustments */ @media (max-width: 768px) { .ctaSection { padding: 80px 16px; margin-top: 80px; } .ctaContent h2 { font-size: 36px; margin-bottom: 20px; } .ctaButton { padding: 16px 30px; font-size: 18px; } .ctaContent p { font-size: 16px; } } @media (max-width: 480px) { .ctaSection { padding: 60px 16px; margin-top: 60px; } .ctaContent h2 { font-size: 30px; } .ctaButton { padding: 14px 24px; font-size: 16px; } } ``` **`src/components/Footer/Footer.tsx`** ```tsx import React, { useState } from 'react'; import styles from './Footer.module.css'; const Footer: React.FC = () => { const [selectedLanguage, setSelectedLanguage] = useState('es'); // Default to Spanish const handleLanguageChange = (event: React.ChangeEvent) => { setSelectedLanguage(event.target.value); console.log(`Language changed to: ${event.target.value}`); // En una aplicación real, aquí se actualizaría el contexto de i18n }; return ( ); }; export default Footer; ``` **`src/components/Footer/Footer.module.css`** ```css /* src/components/Footer/Footer.module.css */ .footer { background-color: var(--bg-white); padding: 80px 20px 40px 20px; /* Padding superior, inferior y lateral */ border-top: 1px solid var(--border-light); /* Línea divisoria sutil */ } .footerContent { display: flex; justify-content: space-between; max-width: 1280px; /* Alineado con PageContainer */ margin: 0 auto; gap: 40px; /* Espacio entre columnas */ flex-wrap: wrap; /* Permite que las columnas se envuelvan */ } .footerLogo { flex: 1 1 200px; /* Permite que el logo tenga un ancho flexible */ margin-right: 40px; /* Espacio extra a la derecha del logo */ } .footerLogo img { height: 40px; width: auto; margin-bottom: 15px; } .footerLogo p { font-size: var(--font-size-sm); color: var(--text-light); line-height: 1.5; } .footerColumn { flex: 1 1 180px; /* Cada columna tiene un ancho flexible */ } .footerColumn h3 { font-size: 18px; font-weight: 600; color: var(--text-dark); margin-bottom: 20px; } .footerColumn ul { list-style: none; padding: 0; margin: 0; } .footerColumn ul li { margin-bottom: 10px; } .footerColumn ul li a { text-decoration: none; color: var(--text-medium); font-size: 15px; transition: color 0.3s ease; display: flex; align-items: center; gap: 8px; /* Espacio para iconos de redes sociales */ } .footerColumn ul li a:hover { color: var(--primary-blue); } .socialLinks img { width: 20px; height: 20px; } .footerBottom { margin-top: 60px; padding-top: 30px; border-top: 1px solid var(--border-light); display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; max-width: 1280px; margin-left: auto; margin-right: auto; } .legalLinks { display: flex; flex-wrap: wrap; gap: 20px; } .legalLinks a { text-decoration: none; color: var(--text-light); font-size: var(--font-size-sm); transition: color 0.3s ease; } .legalLinks a:hover { color: var(--primary-blue); } .languageSelector select { border: 1px solid var(--border-light); border-radius: var(--border-radius-input); padding: 8px 12px; font-size: var(--font-size-sm); color: var(--text-medium); background-color: var(--bg-white); cursor: pointer; -webkit-appearance: none; /* Oculta el estilo nativo del select */ -moz-appearance: none; appearance: none; background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23666666%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13.2-5.4H18.6c-5%200-9.3%201.8-13.2%205.4A17.6%2017.6%200%200%200%200%2082.6c0%204.8%201.8%209.1%205.4%2013.2l128.8%20128.8c3.9%203.9%208.7%205.8%2013.6%205.8s9.7-1.9%2013.6-5.8l128.8-128.8c3.9-3.9%205.8-8.7%205.8-13.6%200-4.8-1.8-9.1-5.4-13.2z%22%2F%3E%3C%2Fsvg%3E'); background-repeat: no-repeat; background-position: right 8px center; background-size: 12px; padding-right: 30px; /* Espacio para el icono de la flecha */ } .languageSelector select:focus { outline: none; border-color: var(--primary-blue); box-shadow: 0 0 0 2px rgba(0, 102, 255, 0.2); } /* Responsive adjustments */ @media (max-width: 1024px) { .footerContent { gap: 30px; justify-content: flex-start; /* Alinea al inicio en pantallas más pequeñas */ } .footerLogo { flex-basis: 100%; /* El logo ocupa todo el ancho */ margin-right: 0; text-align: center; } .footerColumn { flex-basis: calc(50% - 15px); /* Dos columnas por fila */ } } @media (max-width: 768px) { .footer { padding: 60px 16px 30px 16px; } .footerContent { flex-direction: column; /* Columnas apiladas */ gap: 30px; } .footerLogo { margin-bottom: 20px; } .footerColumn { flex-basis: 100%; text-align: center; } .footerColumn ul li a { justify-content: center; /* Centra los enlaces con iconos */ } .footerBottom { flex-direction: column; /* Apila los enlaces legales y el selector */ gap: 20px; margin-top: 40px; padding-top: 20px; } .legalLinks { flex-direction: column; gap: 10px; } .languageSelector { width: 100%; /* El selector de idioma ocupa todo el ancho */ text-align: center; } .languageSelector select { width: 80%; /* Ancho del select para móvil */ max-width: 200px; } } ```