AvanzaCast/docs/landingtemplate_UX.md

30 KiB

TEMPLATE HTML5, CSS3, JS BASADO EN STREAMYARD.COM

Este template busca replicar la estructura modular, la estética "pixel-perfect" y las funcionalidades clave observadas.


1. HTML5 (Estructura Modular)

Este es un ejemplo de cómo podrías estructurar una página principal, incorporando componentes y secciones comunes. Las páginas específicas (como /login, /signup, artículos de blog) tendrían variaciones en la sección <main>.

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>StreamYard Clon - La manera más sencilla de grabar y transmitir en vivo</title>
    <link rel="stylesheet" href="css/styles.css">
    <link href="https://fonts.googleapis.com/css2?family=AvertaStd-Regular&display=swap" rel="stylesheet">
    <!-- Asumiendo que AvertaStd-Regular es una fuente personalizada o similar a una de Google Fonts, o cargada localmente.
         Si es una fuente personalizada, se cargaría vía @font-face en CSS. -->
</head>
<body>

    <!-- Header Section (HeaderSection, Navigation, Logo) -->
    <header id="main-header" class="header-section">
        <div class="container header-content">
            <a href="/" class="logo">
                <img src="img/logo-streamyard.svg" alt="StreamYard Logo">
            </a>
            <nav id="main-nav" class="main-navigation">
                <button class="nav-toggle" aria-label="Abrir menú"></button>
                <ul class="nav-links">
                    <li><a href="/producto">Producto</a>
                        <ul class="dropdown">
                            <li><a href="/why-streamyard">Por qué StreamYard</a></li>
                            <li><a href="/multistreaming">Transmisión Múltiple</a></li>
                            <li><a href="/branding">Marca</a></li>
                            <!-- Más enlaces de producto aquí -->
                        </ul>
                    </li>
                    <li><a href="/contacto">Contacto</a></li>
                    <li><a href="/precios">Precios</a></li>
                    <li><a href="/novedades">Novedades</a></li>
                    <li><a href="/para-empresas">Para empresas</a></li>
                    <li><a href="/accede">Accede</a></li>
                    <li><a href="/signup" class="btn btn-primary">Empecemos</a></li>
                </ul>
            </nav>
        </div>
    </header>

    <!-- Main Content Area -->
    <main>
        <!-- Hero Section (presente en la mayoría de las landing pages) -->
        <section class="hero-section">
            <div class="container hero-grid">
                <div class="hero-content">
                    <h1>La manera más sencilla de grabar y transmitir en vivo</h1>
                    <p>StreamYard es un estudio profesional para grabar y hacer transmisiones en vivo desde tu navegador...</p>
                    <div class="cta-form">
                        <input type="email" placeholder="Ingresa la dirección de correo electrónico">
                        <button class="btn btn-secondary">Empieza, es gratis!</button>
                        <p class="terms-text">Al continuar, aceptas nuestros <a href="/terms">Términos de Servicio del Usuario</a> y <a href="/privacy">Política de Uso del Plan</a>.</p>
                    </div>
                </div>
                <div class="hero-image">
                    <!-- Imagen o componente de video aquí -->
                </div>
            </div>
            <!-- Carrusel de Logos de Clientes o Funcionalidades (GridComponent) -->
            <div class="client-logos-grid container">
                <!-- Varios logos de empresas (Microsoft, Google, etc.) -->
            </div>
        </section>

        <!-- Feature Sections (ej. MultistreamingFeatureSection, BrandingFeatureSection) -->
        <section class="feature-section light-bg">
            <div class="container feature-grid">
                <div class="feature-image">
                    <img src="img/feature-image-1.png" alt="Descripción de la característica">
                </div>
                <div class="feature-content">
                    <h2>Transmite en vivo o graba podcasts con invitados remotos</h2>
                    <p>Los invitados pueden unirse fácilmente desde su navegador o teléfono en unos pocos clics...</p>
                    <a href="/feature-detail" class="text-link">Saber más &rarr;</a>
                </div>
            </div>
        </section>

        <section class="feature-section">
            <div class="container feature-grid reverse-grid">
                <div class="feature-content">
                    <h2>Grabaciones con calidad de estudio, independientemente de tu conexión</h2>
                    <p>¿Te cansaste de que tus podcasts queden arruinados con Zoom y Skype?...</p>
                    <a href="/feature-detail" class="text-link">Saber más &rarr;</a>
                </div>
                <div class="feature-image">
                    <img src="img/feature-image-2.png" alt="Descripción de la característica">
                </div>
            </div>
        </section>

        <!-- Blog Section (BlogPostCard, PaginationComponent) -->
        <section class="blog-section dark-blue-bg">
            <div class="container">
                <h2>Transmite mejor, crece más rápido</h2>
                <div class="blog-grid">
                    <article class="blog-post-card">
                        <img src="img/blog-thumb-1.jpg" alt="Título del post">
                        <h3><a href="/blog/post-1">Cómo programar una transmisión en vivo en YouTube</a></h3>
                        <a href="/blog/post-1" class="read-more">Leer más &rarr;</a>
                    </article>
                    <article class="blog-post-card">
                        <img src="img/blog-thumb-2.jpg" alt="Título del post">
                        <h3><a href="/blog/post-2">7 formas de mejorar el audio de la transmisión en vivo</a></h3>
                        <a href="/blog/post-2" class="read-more">Leer más &rarr;</a>
                    </article>
                    <!-- Más BlogPostCard aquí -->
                </div>
                <div class="pagination-component">
                    <!-- Componente de paginación -->
                </div>
            </div>
        </section>

        <!-- Testimonial Section (TestimonialSection) -->
        <section class="testimonial-section light-bg">
            <div class="container testimonial-slider">
                <!-- Testimonios individuales aquí (posiblemente un carrusel) -->
                <div class="testimonial-card">
                    <p>"Me impresionó el increíble producto y la tecnología de StreamYard. Me permite mandar mi mensaje al mundo."</p>
                    <span class="author">Gary Vaynerchuk</span>
                    <span class="role">Empresario</span>
                </div>
            </div>
        </section>

        <!-- Call to Action Section -->
        <section class="cta-banner blue-bg">
            <div class="container">
                <h2>Empieza a crear.</h2>
                <button class="btn btn-primary">Empieza, es gratis!</button>
                <p>Únete a millones de usuarios de StreamYard y empieza con tus transmisiones o tu podcast hoy mismo.</p>
            </div>
        </section>
    </main>

    <!-- Footer Section (FooterSection) -->
    <footer class="footer-section">
        <div class="container footer-grid">
            <div class="footer-col">
                <a href="/" class="footer-logo">
                    <img src="img/logo-streamyard-white.svg" alt="StreamYard Logo Blanco">
                </a>
                <p>La manera más sencilla de grabar y transmitir en vivo</p>
            </div>
            <div class="footer-col">
                <h4>Producto</h4>
                <ul>
                    <li><a href="/why-streamyard">Por qué StreamYard</a></li>
                    <li><a href="/multistreaming">Transmisión múltiple</a></li>
                    <!-- Más enlaces de producto -->
                </ul>
            </div>
            <div class="footer-col">
                <h4>Comunidad</h4>
                <ul>
                    <li><a href="/blog">Blog</a></li>
                    <li><a href="/affiliates">Afiliados</a></li>
                    <!-- Más enlaces de comunidad -->
                </ul>
            </div>
            <div class="footer-col">
                <h4>StreamYard para</h4>
                <ul>
                    <li><a href="/business">Comercial</a></li>
                    <!-- Más enlaces de para -->
                </ul>
            </div>
            <div class="footer-col">
                <h4>Únete a nosotros</h4>
                <ul class="social-links">
                    <li><a href="https://facebook.com/streamyard" target="_blank">Facebook</a></li>
                    <li><a href="https://twitter.com/streamyardapp" target="_blank">X (Twitter)</a></li>
                    <!-- Más enlaces de redes sociales -->
                </ul>
            </div>
        </div>
        <div class="container footer-bottom">
            <p>&copy; 2023 StreamYard. Todos los derechos reservados.</p>
            <ul class="legal-links">
                <li><a href="/terms">Términos de servicio</a></li>
                <li><a href="/privacy">Política de privacidad</a></li>
                <li><a href="/cookies">Política de Cookies</a></li>
                <!-- Más enlaces legales -->
            </ul>
        </div>
    </footer>

    <!-- Cookie Consent Modal (funcionalidad) -->
    <div id="cookie-consent-modal" class="cookie-modal hidden">
        <div class="cookie-content">
            <p>Usamos cookies para mejorar tu experiencia. Al continuar, aceptas nuestra <a href="/cookies">política de cookies</a>.</p>
            <button id="accept-cookies" class="btn btn-primary">Aceptar</button>
        </div>
    </div>

    <script src="js/main.js"></script>
</body>
</html>

2. CSS3 (Estilos Globales y de Componentes)

css/styles.css

/* Variables CSS para consistencia de colores y fuentes */
:root {
    --primary-blue: #1877F2; /* Un azul típico de CTA/enlaces */
    --secondary-blue: #007bff; /* Otro tono de azul */
    --light-blue-bg: #EAF0F6; /* Fondo azul claro, como el de las secciones */
    --dark-blue-bg: #0C1322; /* Fondo azul oscuro */
    --white: rgb(255, 255, 255);
    --black: rgb(0, 0, 0);
    --text-color-dark: rgb(27, 31, 41); /* Para texto principal */
    --text-color-medium: rgb(80, 88, 104); /* Para párrafos generales */
    --text-color-light: rgb(105, 110, 124); /* Texto más claro */
    --font-family-base: "AvertaStd-Regular", Arial, "Noto Sans JP", Prompt, sans-serif;
    --spacing-unit: 1rem; /* 16px */
}

/* Base Global Styles (Métricas Pixel-Perfect Consistentes) */
html {
    scroll-behavior: smooth;
}

body {
    margin: 0;
    font-family: var(--font-family-base);
    color: var(--text-color-medium);
    background-color: var(--white);
    line-height: 1.6;
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 var(--spacing-unit);
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-family-base); /* Consistente con el body */
    color: var(--text-color-dark);
    margin-top: 0;
    line-height: 1.2;
}

h1 { font-size: 3rem; color: var(--black); } /* Puede variar, como en el blog */
h2 { font-size: 2.5rem; }
h3 { font-size: 2rem; }
p { margin-bottom: 1rem; }

a {
    color: var(--primary-blue);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

.btn {
    display: inline-block;
    padding: 0.8rem 1.5rem;
    border-radius: 5px;
    font-weight: bold;
    text-align: center;
    cursor: pointer;
    transition: background-color 0.3s ease;
    border: none;
}

.btn-primary {
    background-color: var(--primary-blue);
    color: var(--white);
}

.btn-primary:hover {
    background-color: darken(var(--primary-blue), 10%); /* Usar una función darken si se usa preprocesador, o un color fijo */
    text-decoration: none;
}

.btn-secondary {
    background-color: var(--secondary-blue); /* O un color de contraste, como el azul más oscuro en el CTA */
    color: var(--white);
}

.btn-secondary:hover {
    background-color: darken(var(--secondary-blue), 10%);
    text-decoration: none;
}

.text-link {
    color: var(--primary-blue);
    text-decoration: none;
    font-weight: bold;
}

.text-link:hover {
    text-decoration: underline;
}

/* Header Section */
.header-section {
    background-color: var(--white);
    padding: var(--spacing-unit) 0;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    position: sticky; /* Navegación pegajosa */
    top: 0;
    z-index: 1000;
}

.header-content {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.logo img {
    height: 40px; /* Tamaño del logo */
}

/* Navigation */
.main-navigation ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    align-items: center;
}

.main-navigation ul li {
    position: relative;
    margin-left: 20px;
}

.main-navigation ul li a {
    color: var(--text-color-dark);
    font-weight: 500;
    padding: 10px 0;
    display: block;
}

.main-navigation ul li a:hover {
    color: var(--primary-blue);
    text-decoration: none;
}

/* Dropdown */
.main-navigation .dropdown {
    display: none;
    position: absolute;
    background-color: var(--white);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    min-width: 180px;
    z-index: 1;
    padding: 10px 0;
    border-radius: 5px;
}

.main-navigation ul li:hover > .dropdown {
    display: block;
}

.main-navigation .dropdown li {
    margin: 0;
}

.main-navigation .dropdown a {
    padding: 8px 20px;
    white-space: nowrap;
}

.nav-toggle {
    display: none; /* Oculto en desktop */
    background: none;
    border: none;
    font-size: 2rem;
    cursor: pointer;
    color: var(--text-color-dark);
}

/* Hero Section */
.hero-section {
    padding: 4rem 0;
    text-align: center;
    background-color: var(--light-blue-bg); /* O blanco puro, dependiendo de la página */
}

.hero-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2rem;
    align-items: center;
    text-align: left;
}

.hero-content h1 {
    color: var(--black);
    margin-bottom: 1rem;
}

.hero-content p {
    font-size: 1.1rem;
    margin-bottom: 2rem;
}

.cta-form {
    display: flex;
    flex-direction: column; /* Cambiar a row en desktop */
    gap: 1rem;
    margin-bottom: 1rem;
}

.cta-form input[type="email"] {
    padding: 0.8rem 1rem;
    border: 1px solid #ccc;
    border-radius: 5px;
    font-size: 1rem;
}

.terms-text {
    font-size: 0.85rem;
    color: var(--text-color-light);
}

/* Feature Sections */
.feature-section {
    padding: 6rem 0;
    background-color: var(--white);
}

.feature-section.light-bg {
    background-color: var(--light-blue-bg);
}

.feature-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4rem;
    align-items: center;
}

.feature-grid.reverse-grid {
    grid-template-areas: "content image";
}

.feature-grid.reverse-grid .feature-image {
    grid-area: image;
}

.feature-grid.reverse-grid .feature-content {
    grid-area: content;
}

.feature-image img {
    max-width: 100%;
    height: auto;
    display: block;
}

.feature-content h2 {
    font-size: 2.2rem;
    margin-bottom: 1.5rem;
}

/* Blog Section */
.blog-section {
    padding: 6rem 0;
    background-color: var(--dark-blue-bg);
    color: var(--white);
    text-align: center;
}

.blog-section h2 {
    color: var(--white);
    margin-bottom: 3rem;
}

.blog-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 2rem;
    margin-bottom: 3rem;
}

.blog-post-card {
    background-color: var(--white);
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
    text-align: left;
}

.blog-post-card img {
    width: 100%;
    height: 200px;
    object-fit: cover;
}

.blog-post-card h3 {
    font-size: 1.3rem;
    padding: 1.5rem 1rem 0.5rem;
    color: var(--text-color-dark);
}

.blog-post-card h3 a {
    color: var(--text-color-dark);
}

.blog-post-card h3 a:hover {
    color: var(--primary-blue);
    text-decoration: none;
}

.blog-post-card .read-more {
    display: inline-block;
    padding: 0 1rem 1.5rem;
    color: var(--primary-blue);
    font-weight: bold;
}

/* Testimonial Section */
.testimonial-section {
    padding: 6rem 0;
    text-align: center;
    background-color: var(--white); /* Puede ser light-bg también */
}

.testimonial-slider {
    max-width: 800px; /* Para centrar y limitar el ancho del testimonio */
    margin: 0 auto;
}

.testimonial-card {
    padding: 2rem;
    background-color: #f9f9f9;
    border-radius: 8px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.testimonial-card p {
    font-size: 1.4rem;
    font-style: italic;
    color: var(--text-color-dark);
    margin-bottom: 1.5rem;
}

.testimonial-card .author {
    display: block;
    font-weight: bold;
    color: var(--primary-blue);
    margin-bottom: 0.3rem;
}

.testimonial-card .role {
    font-size: 0.9rem;
    color: var(--text-color-medium);
}

/* Call to Action Banner */
.cta-banner {
    padding: 5rem 0;
    background-color: var(--primary-blue); /* o un azul más oscuro */
    color: var(--white);
    text-align: center;
}

.cta-banner h2 {
    color: var(--white);
    font-size: 2.5rem;
    margin-bottom: 1.5rem;
}

.cta-banner .btn {
    margin-bottom: 1rem;
}

.cta-banner p {
    font-size: 1.1rem;
    opacity: 0.9;
}


/* Footer Section */
.footer-section {
    background-color: var(--dark-blue-bg);
    color: var(--white);
    padding: 4rem 0 2rem;
}

.footer-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 2rem;
    margin-bottom: 3rem;
}

.footer-col .footer-logo img {
    height: 30px;
    margin-bottom: 1rem;
}

.footer-col h4 {
    color: var(--white);
    font-size: 1.1rem;
    margin-bottom: 1rem;
}

.footer-col ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.footer-col ul li {
    margin-bottom: 0.7rem;
}

.footer-col ul li a {
    color: var(--white);
    opacity: 0.8;
    transition: opacity 0.3s ease;
}

.footer-col ul li a:hover {
    opacity: 1;
    text-decoration: underline;
}

.footer-bottom {
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    padding-top: 2rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
    font-size: 0.9rem;
}

.footer-bottom p {
    margin: 0;
    opacity: 0.7;
}

.footer-bottom .legal-links {
    display: flex;
    gap: 1.5rem;
    list-style: none;
    padding: 0;
    margin: 0;
}

.footer-bottom .legal-links a {
    color: var(--white);
    opacity: 0.7;
}

.footer-bottom .legal-links a:hover {
    opacity: 1;
    text-decoration: underline;
}

/* Cookie Consent Modal */
.cookie-modal {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    color: var(--white);
    padding: 1.5rem;
    text-align: center;
    z-index: 2000;
    transform: translateY(100%);
    transition: transform 0.3s ease-in-out;
}

.cookie-modal.show {
    transform: translateY(0);
}

.cookie-modal.hidden {
    display: none; /* Asegura que no ocupe espacio cuando está oculto */
}

.cookie-content {
    max-width: 900px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 1rem;
}

.cookie-content p {
    margin: 0;
    flex-grow: 1;
    font-size: 0.95rem;
}

.cookie-content a {
    color: var(--primary-blue);
    text-decoration: underline;
}

.cookie-content .btn {
    flex-shrink: 0;
}

/* Responsive Design */
@media (max-width: 992px) {
    .hero-grid, .feature-grid {
        grid-template-columns: 1fr;
        text-align: center;
    }

    .hero-grid .hero-image, .feature-grid .feature-image {
        order: -1; /* Mueve la imagen arriba en móvil */
    }

    .feature-grid.reverse-grid {
        grid-template-areas: none; /* Reset para móviles */
    }

    .feature-grid.reverse-grid .feature-image,
    .feature-grid.reverse-grid .feature-content {
        grid-area: unset;
    }

    .cta-form {
        flex-direction: column;
    }

    .main-navigation .nav-links {
        display: none;
        flex-direction: column;
        width: 100%;
        position: absolute;
        top: 100%;
        left: 0;
        background-color: var(--white);
        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
        padding-bottom: 1rem;
    }

    .main-navigation .nav-links.active {
        display: flex;
    }

    .main-navigation ul li {
        margin: 0;
        width: 100%;
        text-align: center;
    }

    .main-navigation ul li a {
        padding: 15px 0;
        border-bottom: 1px solid #eee;
    }

    .main-navigation ul li:last-child a {
        border-bottom: none;
    }

    .main-navigation .nav-toggle {
        display: block;
    }

    .main-navigation .dropdown {
        position: static;
        box-shadow: none;
        padding: 0;
        border-radius: 0;
        width: 100%;
        background-color: #f8f8f8;
    }

    .main-navigation .dropdown a {
        padding-left: 40px; /* Indent dropdown items */
    }

    .footer-bottom {
        flex-direction: column;
    }

    .footer-bottom .legal-links {
        flex-direction: column;
        gap: 0.5rem;
        text-align: center;
    }
}

@media (max-width: 768px) {
    h1 { font-size: 2.5rem; }
    h2 { font-size: 2rem; }
    .hero-section { padding: 3rem 0; }
    .feature-section { padding: 4rem 0; }
    .blog-section { padding: 4rem 0; }
    .cta-banner { padding: 4rem 0; }
    .footer-section { padding: 3rem 0; }
}

3. JavaScript (Funcionalidades Clave)

js/main.js

document.addEventListener('DOMContentLoaded', () => {
    // 1. Navegación Pegajosa (Sticky Header)
    const header = document.getElementById('main-header');
    if (header) {
        let lastScrollY = window.scrollY;
        window.addEventListener('scroll', () => {
            if (window.scrollY > header.offsetHeight && window.scrollY > lastScrollY) {
                // Scrolling down, hide header (o hacerla más compacta)
                header.classList.add('header-scrolled');
            } else {
                // Scrolling up, show header
                header.classList.remove('header-scrolled');
            }
            lastScrollY = window.scrollY;
        });
    }

    // 2. Navegación Móvil (Menú Hamburguesa)
    const navToggle = document.querySelector('.nav-toggle');
    const navLinks = document.querySelector('.nav-links');

    if (navToggle && navLinks) {
        navToggle.addEventListener('click', () => {
            navLinks.classList.toggle('active');
            navToggle.setAttribute('aria-expanded', navLinks.classList.contains('active'));
        });
        // Cerrar menú si se hace clic fuera (opcional)
        document.addEventListener('click', (event) => {
            if (!navLinks.contains(event.target) && !navToggle.contains(event.target) && navLinks.classList.contains('active')) {
                navLinks.classList.remove('active');
                navToggle.setAttribute('aria-expanded', 'false');
            }
        });
    }


    // 3. Modal de Consentimiento de Cookies
    const cookieModal = document.getElementById('cookie-consent-modal');
    const acceptCookiesBtn = document.getElementById('accept-cookies');
    const cookieName = 'streamyard_cookie_consent';

    // Función para mostrar el modal de cookies
    function showCookieModal() {
        if (cookieModal && !localStorage.getItem(cookieName)) {
            cookieModal.classList.add('show');
            cookieModal.classList.remove('hidden'); // Asegura que se muestre
        } else if (cookieModal) {
            cookieModal.classList.add('hidden'); // Ocultar si ya aceptó
            cookieModal.classList.remove('show');
        }
    }

    // Función para ocultar y guardar preferencia
    function hideCookieModal() {
        if (cookieModal) {
            cookieModal.classList.remove('show');
            cookieModal.classList.add('hidden');
            localStorage.setItem(cookieName, 'accepted');
        }
    }

    if (acceptCookiesBtn) {
        acceptCookiesBtn.addEventListener('click', hideCookieModal);
    }

    showCookieModal(); // Mostrar el modal al cargar la página si no ha aceptado


    // 4. Placeholder para Validación de Formularios (Ej. en Login/Signup)
    const ctaForm = document.querySelector('.cta-form');
    if (ctaForm) {
        const emailInput = ctaForm.querySelector('input[type="email"]');
        const submitButton = ctaForm.querySelector('.btn-secondary');

        if (submitButton && emailInput) {
            submitButton.addEventListener('click', (event) => {
                // event.preventDefault(); // Descomentar para prevenir envío automático y hacer validación JS
                if (!emailInput.value || !emailInput.value.includes('@')) {
                    alert('Por favor, ingresa un correo electrónico válido.');
                    // emailInput.focus();
                    return false;
                }
                // Si la validación pasa, el formulario se enviaría (o se realizaría una llamada AJAX)
                // console.log('Formulario válido, enviando...');
            });
        }
    }


    // 5. Placeholder para Carrusel/Slider (si aplica en testimonial-slider)
    // Esto sería una implementación más compleja con librerías como Swiper.js, Slick Carousel, etc.
    // Ejemplo de un carrusel muy básico (sin funcionalidad de desplazamiento real, solo estructura)
    const testimonialSlider = document.querySelector('.testimonial-slider');
    if (testimonialSlider) {
        // Podrías inicializar una librería de carrusel aquí
        // console.log('Inicializando carrusel de testimonios...');
        // Por ejemplo, con Swiper:
        /*
        new Swiper(testimonialSlider, {
            slidesPerView: 1,
            spaceBetween: 30,
            navigation: {
                nextEl: '.swiper-button-next',
                prevEl: '.swiper-button-prev',
            },
            pagination: {
                el: '.swiper-pagination',
                clickable: true,
            },
        });
        */
    }

    // 6. Carga Diferida (Lazy Loading) para imágenes (Concepto)
    // Para imágenes que están más abajo en la página.
    // `<img src="placeholder.jpg" data-src="imagen-real.jpg" alt="..." class="lazyload">`
    const lazyImages = document.querySelectorAll('img[data-src]');
    if ('IntersectionObserver' in window) {
        let lazyImageObserver = new IntersectionObserver((entries, observer) => {
            entries.forEach((entry) => {
                if (entry.isIntersecting) {
                    let lazyImage = entry.target;
                    lazyImage.src = lazyImage.dataset.src;
                    lazyImage.removeAttribute('data-src');
                    lazyImageObserver.unobserve(lazyImage);
                }
            });
        });
        lazyImages.forEach((lazyImage) => {
            lazyImageObserver.observe(lazyImage);
        });
    } else {
        // Fallback para navegadores antiguos
        lazyImages.forEach((lazyImage) => {
            lazyImage.src = lazyImage.dataset.src;
            lazyImage.removeAttribute('data-src');
        });
    }
});

// Puedes añadir más scripts específicos aquí si los necesitas para otras páginas,
// o cargarlos condicionalmente.

Consideraciones Adicionales para el Desarrollo:

  • Fuentes Personalizadas: La fuente AvertaStd-Regular se asume como una fuente que necesitarías cargar (ya sea a través de Google Fonts si hay una alternativa similar, o mediante @font-face si es un archivo de fuente personalizado). Para el template, he puesto un link a Google Fonts como ejemplo, pero si no existe, deberías gestionarlo con un @font-face en tu CSS.
  • Imágenes: Las rutas img/ son placeholders. Deberías reemplazarlas con tus propias imágenes.
  • Modularidad Avanzada: Para un proyecto grande, considera usar un framework o librería de componentes (React, Vue, Angular) o un generador de sitios estáticos (Next.js, Gatsby) para gestionar la complejidad y la reutilización de componentes de forma más eficiente.
  • Preprocesadores CSS: Para la función darken() en el CSS, necesitarías un preprocesador como Sass o Less. Si no, usa valores de color hexadecimal/RGB predefinidos.
  • Scripts Dinámicos del Servidor: Funcionalidades como "Iniciar sesión" o "Registrarse" implican un backend. El JavaScript proporcionado es solo para la lógica del lado del cliente.
  • Accesibilidad (A11y): He incluido aria-label para el botón de navegación, pero un sitio web completo requeriría una auditoría y mejoras de accesibilidad más profundas.
  • Optimización: Considera la optimización de imágenes, la minificación de CSS/JS y el uso de CDNs para mejorar el rendimiento en producción.

Este template te proporciona una base sólida que refleja la estructura y el diseño de StreamYard.com, permitiéndote construir un sitio con una estética y funcionalidad consistentes.