Desarrollo web

EmpleoConnect es una plataforma completa para buscar y gestionar ofertas de empleo: cuenta con una navegación lateral persistente, un buscador inteligente en la sección principal, listados de ofertas destacadas, exploración por categorías …

Contenido del tutorial

EmpleoConnect es una plataforma completa para buscar y gestionar ofertas de empleo: cuenta con una navegación lateral persistente, un buscador inteligente en la sección principal, listados de ofertas destacadas, exploración por categorías y empresas top, un flujo de “Cómo funciona” paso a paso, testimonios de usuarios reales y un sistema de suscripción a newsletter; todos los componentes están diseñados para ser responsivos y dinámicos, con scripts que controlan el toggle de la sidebar, los dropdowns de perfil, la carga de contenido y la interacción con formularios y tarjetas de oferta.

Estructura de carpetas del proyecto

|   buscar.html
|   destacadas.html
|   editar_perfil.html
|   explorar.html
|   inicio.html
|   login.html
|   notificaciones.html
|   ofertas.html
|   postulaciones.html
|   recuperar_contraseña.html
|   registrarse.html
|   ver_oferta.css.html
|
+---css
|   |   base.css
|   |   layout.css
|   |   state.css
|   |   theme.css
|   |
|   +---modules
|   |       logo.css
|   |       navigation.css
|   |       newsletter.css
|   |       offer-card.css
|   |       profile-dropdown.css
|   |       search-form.css
|   |       sidebar-toggle.css
|   |       sidebar.css
|   |       testimonial.css
|   |
|   \---pages
|           buscar-empresas.css
|           destacadas.css
|           editar-perfil.css
|           explorar.css
|           home.css
|           login.css
|           notificaciones-empleado.css
|           ofertas.css
|           postulaciones.css
|           recuperar-contrasena.css
|           registrarse.css
|           ver_oferta.css
|
\---js
        barraLateral.js
        boletin.js
        desplegablePerfil.js
        interaccionesInicio.js

inicio.html

Este archivo configura la página de inicio de EmpleoConnect: carga los estilos globales y módulos de sidebar, logo, navegación y componentes de página; añade el botón para alternar la barra lateral y define la estructura con el aside de navegación y el main que incluye la sección hero con buscador, ofertas destacadas, explorar categorías, empresas top, pasos de uso, testimonios, newsletter y footer, además de enlazar los scripts de interactividad.

EmpleoConnect Home HTML: Sidebar, Hero y Secciones Interactivas

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>EmpleoConnect</title>
    <link rel="stylesheet" href="css/theme.css">
    <link rel="stylesheet" href="css/base.css">
    <link rel="stylesheet" href="css/layout.css">
    <link rel="stylesheet" href="css/state.css">
    <link rel="stylesheet" href="css/modules/sidebar.css">
    <link rel="stylesheet" href="css/modules/logo.css">
    <link rel="stylesheet" href="css/modules/navigation.css">
    <link rel="stylesheet" href="css/modules/profile-dropdown.css">
    <link rel="stylesheet" href="css/modules/sidebar-toggle.css">
    <link rel="stylesheet" href="css/modules/search-form.css">
    <link rel="stylesheet" href="css/modules/offer-card.css">
    <link rel="stylesheet" href="css/modules/testimonial.css">
    <link rel="stylesheet" href="css/modules/newsletter.css">
    <link rel="stylesheet" href="css/pages/home.css">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">

</head>
<body class="sidebar-visible">
    <button class="sidebar-toggle" id="sidebarToggle">
        <svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
    </button>

    <aside class="sidebar" id="sidebar">
        <div>
            <div class="logo">
                <svg viewBox="0 0 24 24"><path d="M20 7h-4V3c0-1.1-.9-2-2-2h-4c-1.1 0-2 .9-2 2v4H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2z"/><path d="M11 14h2v4h-2zM7 14h2v4H7zM15 14h2v4h-2z"/></svg>
                EmpleoConnect
            </div>
            <div class="category-label">Navegar</div>
            <ul class="nav-menu">
                <li class="nav-item active">
                    <svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V9z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
                    <span>Inicio</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/></svg>
                    <span>Ofertas</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg>
                    <span>Explorar</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
                    <span>Notificaciones</span>
                </li>
                <li class="nav-item employee-mode" id="employeeModeBtn">
                    <svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg>
                    <span class="mode-text">Modo Empleado</span>
                </li>
            </ul>
            <div class="category-label">Empresas</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M3 21h18M9 8h1M9 12h1M9 16h1M15 8h1M15 12h1M15 16h1M7 21V5a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v16"/></svg>
                    <span>Destacadas</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M4 21v-2a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
                    <span>Buscar</span>
                </li>
            </ul>
        </div>
        <div class="profile" id="profileBtn">
            <div class="profile-info">
                <div class="profile-icon"><svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg></div>
                <div>
                    <div class="username">Usuario</div>
                    <div class="status"><span class="status-indicator"></span><span>En línea</span></div>
                </div>
            </div>
            <ul class="nav-menu profile-links" id="profileLinks">
                <li class="nav-item"><span>Editar Perfil</span></li>
                <li class="nav-item"><span>Postulaciones</span></li>
                <li class="nav-item logout"><span>Cerrar sesión</span></li>
            </ul>
        </div>
    </aside>

    <main>
        <section class="hero">
            <div class="hero-content">
                <div class="hero-text">
                    <h1>Bienvenido a EmpleoConnect</h1>
                     <p class="subtitle">Tu plataforma inteligente para encontrar el empleo perfecto.</p>
                    <h2>Encuentra tu próximo empleo</h2>
                </div>
                <form class="search-form large-search-form">
                    <input type="text" placeholder="Buscar empleos por título, empresa o palabra clave"/>
                    <button type="submit">
                        <i class="fa fa-search"></i> Buscar
                    </button>
                </form>
            </div>
        </section>

        <section>
            <div class="section-header">
                <h3>Ofertas destacadas</h3>
                <a href="ofertas.html" class="view-all-link">Ver todas <i class="fas fa-arrow-right"></i></a>
            </div>
            <div class="offers-grid">
                <div class="offer-card">
                    <span class="badge">Remoto</span>
                    <h4>Desarrollador/a Backend</h4>
                    <p>Tech Solutions</p>
                    <p class="offer-location-home">Remoto</p>
                </div>
                <div class="offer-card">
                    <span class="badge badge-secondary">Urgente</span>
                    <h4>Ejecutivo/a de Ventas</h4>
                    <p>Grupo Comercial Barcelona</p>
                     <p class="offer-location-home">Barcelona, España</p>
                </div>
                <div class="offer-card">
                    <span class="badge">Presencial</span>
                    <h4>Diseñador/a UX/UI</h4>
                    <p>Innovate Agency</p>
                     <p class="offer-location-home">Madrid, España</p>
                </div>
                <div class="offer-card">
                    <span class="badge">Híbrido</span>
                    <h4>Gerente de Proyectos</h4>
                    <p>Construcciones & A. Valencia</p>
                     <p class="offer-location-home">Valencia, España</p>
                </div>
                 <div class="offer-card">
                    <span class="badge">Remoto</span>
                    <h4>Analista de Datos</h4>
                    <p>Data Insights</p>
                     <p class="offer-location-home">Remoto (España)</p>
                </div>
            </div>
        </section>

        <section class="explore-sections">
            <div class="explore-section-card">
                <div class="section-header">
                    <h3>Explora por categorías</h3>
                    <a href="explorar.html" class="view-all-link">Ver todas <i class="fas fa-arrow-right"></i></a>
                </div>
                <div class="cats-grid">
                    <button class="category-button"><i class="fas fa-laptop-code"></i> IT</button>
                    <button class="category-button"><i class="fas fa-chart-line"></i> Ventas</button>
                    <button class="category-button"><i class="fas fa-flask"></i> Ingeniería</button>
                    <button class="category-button"><i class="fas fa-bullhorn"></i> Marketing</button>
                    <button class="category-button"><i class="fas fa-heartbeat"></i> Salud</button>
                    <button class="category-button"><i class="fas fa-book-open"></i> Educación</button>
                </div>
            </div>
            <div class="explore-section-card">
                 <div class="section-header">
                    <h3>Empresas top</h3>
                    <a href="destacadas.html" class="view-all-link">Ver todas <i class="fas fa-arrow-right"></i></a>
                </div>
                <ul class="company-list">
                    <li><div class="company-logo-thumb"></div> Tech Dynamics</li>
                    <li><div class="company-logo-thumb"></div> GloboTech</li>
                    <li><div class="company-logo-thumb"></div> Finamcorp</li>
                    <li><div class="company-logo-thumb"></div> Ecoindustries</li>
                    <li><div class="company-logo-thumb"></div> NextSoft</li>
                     <li><div class="company-logo-thumb"></div> Global Sales</li>
                </ul>
            </div>
        </section>

        <section class="how-it-works">
             <div class="section-header centered">
                <h3>Cómo funciona EmpleoConnect</h3>
            </div>
            <ol class="how-it-works-steps">
                <li>
                     <div class="step-icon"><i class="fas fa-search"></i></div>
                     <h4>Buscar</h4>
                     <p>Explora miles de ofertas filtradas por tus preferencias.</p>
                </li>
                <li>
                    <div class="step-icon"><i class="fas fa-file-alt"></i></div>
                     <h4>Postúlate</h4>
                    <p>Aplica de forma rápida y sencilla con tu perfil y CV.</p>
                </li>
                <li>
                    <div class="step-icon"><i class="fas fa-handshake"></i></div>
                     <h4>Consigue</h4>
                    <p>Recibe respuestas de empresas y encuentra tu trabajo ideal.</p>
                </li>
            </ol>
        </section>

        <section class="testimonial-section">
             <div class="section-header centered">
                <h3>Lo que dicen nuestros usuarios</h3>
            </div>
             <div class="testimonial-card">
                 <div class="testimonial-avatar">
                     <i class="fas fa-user-circle"></i> </div>
                 <blockquote>
                     Gracias a EmpleoConnect encontré el trabajo perfecto en pocos días. La plataforma es muy intuitiva y las ofertas se ajustan a lo que buscaba. ¡Totalmente recomendada!
                 </blockquote>
                 <p class="testimonial-author">- María G., Desarrolladora Web</p>
             </div>
        </section>


        <section class="newsletter-section">
            <div class="newsletter-content">
                <h3>Mantente al día con las mejores ofertas</h3>
                 <p>Suscríbete a nuestro boletín y recibe alertas de empleo personalizadas directamente en tu bandeja de entrada.</p>
                <form id="newsletterForm" class="newsletter-form">
                    <input type="email" placeholder="Introduce tu email aquí" required/>
                    <button type="submit">Suscribirme <i class="fas fa-paper-plane"></i></button>
                </form>
            </div>
             <div class="newsletter-image">
                 <svg viewBox="0 0 100 100" fill="var(--primary)"><circle cx="50" cy="50" r="40"/></svg>
             </div>
        </section>

        <footer>
            <a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
        </footer>
    </main>

    <script src="js/barraLateral.js" defer></script>
    <script src="js/desplegablePerfil.js" defer></script>
    <script src="js/boletin.js" defer></script>
    <script src="js/interaccionesInicio.js" defer></script>
</body>
</html>

Explicación del código: EmpleoConnect Home HTML: Sidebar, Hero y Secciones Interactivas

<!DOCTYPE html>
Declara el documento como HTML5, asegurando el modo de renderizado estándar.

<html lang="es">
Elemento raíz con idioma “español” para ayudar a navegadores y lectores de pantalla.

<head>
Comienza la sección de metadatos (no visible) donde se incluyen codificación, estilos y título.

<meta charset="UTF-8"/>
Define la codificación de caracteres en UTF-8 para soportar acentos y caracteres especiales.

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
Ajusta el ancho y la escala de la página al dispositivo, esencial para diseño responsivo.

<title>EmpleoConnect</title>
Título que aparece en la pestaña del navegador y en marcadores.

<link rel="stylesheet" href="css/theme.css">
Importa el tema de colores y tipografías globales.

<link rel="stylesheet" href="css/base.css">
Carga estilos base: reset, tipografías, variables.

<link rel="stylesheet" href="css/layout.css">
Define grillas, contenedores y márgenes globales.

<link rel="stylesheet" href="css/state.css">
Clases de estado (activo, hover, disabled…).

<link rel="stylesheet" href="css/modules/sidebar.css">
Estilos del componente de barra lateral.

<link rel="stylesheet" href="css/modules/logo.css">
Diseño y posicionamiento del logo.

<link rel="stylesheet" href="css/modules/navigation.css">
Estilos del menú de navegación.

<link rel="stylesheet" href="css/modules/profile-dropdown.css">
Diseño del menú desplegable de perfil.

<link rel="stylesheet" href="css/modules/sidebar-toggle.css">
Estilos del botón que abre/cierra el sidebar.

<link rel="stylesheet" href="css/modules/search-form.css">
Diseño del formulario de búsqueda.

<link rel="stylesheet" href="css/modules/offer-card.css">
Estilos de cada tarjeta de oferta de empleo.

<link rel="stylesheet" href="css/modules/testimonial.css">
Diseño del bloque de testimonios.

<link rel="stylesheet" href="css/modules/newsletter.css">
Estilos del formulario de suscripción al boletín.

<link rel="stylesheet" href="css/pages/home.css">
Reglas específicas para la página de inicio.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
Carga Font Awesome desde CDN para iconos vectoriales.

</head>
Cierra la sección de metadatos.

<body class="sidebar-visible">
Inicia el contenido visible, con clase que indica que la barra lateral está inicialmente abierta.

<button class="sidebar-toggle" id="sidebarToggle">
Botón para alternar la visibilidad del sidebar.

<svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
Icono “hamburguesa” en SVG dentro del botón.

</button>
Cierra el botón de alternar sidebar.

<aside class="sidebar" id="sidebar">
Inicia el elemento semántico de la barra lateral.

<div>
Contenedor primario dentro del sidebar.

<div class="logo">
Área del logotipo y nombre de la aplicación.

<svg viewBox="0 0 24 24"><path d="..."/></svg>
Icono SVG del logo.

EmpleoConnect
Texto del nombre de la aplicación junto al icono.

</div>
Cierra el bloque del logo.

<div class="category-label">Navegar</div>
Etiqueta que separa secciones de navegación.

<ul class="nav-menu">
Lista de elementos del menú principal.

<li class="nav-item active">
Ítem de menú activo (sección “Inicio”).

<svg viewBox="0 0 24 24"><path d="..."/><polyline points="..."/></svg>
Icono SVG de “Inicio”.

<span>Inicio</span>
Texto del ítem.

</li>
Cierra el ítem activo.

<li class="nav-item">
Ítem de menú “Ofertas”.

<svg viewBox="0 0 24 24"><rect .../></svg>
Icono SVG de “Ofertas”.

<span>Ofertas</span>
Texto del ítem.

</li>
Cierra el ítem de ofertas.

<li class="nav-item">
Ítem de menú “Explorar”.

<svg viewBox="0 0 24 24"><path .../></svg>
Icono SVG de “Explorar”.

<span>Explorar</span>
Texto del ítem.

</li>
Cierra el ítem de explorar.

<li class="nav-item">
Ítem de menú “Notificaciones”.

<svg viewBox="0 0 24 24"><path .../></svg>
Icono SVG de “Notificaciones”.

<span>Notificaciones</span>
Texto del ítem.

</li>
Cierra el ítem de notificaciones.

<li class="nav-item employee-mode" id="employeeModeBtn">
Ítem para alternar “Modo Empleado”.

<svg viewBox="0 0 24 24"><circle .../></svg>
Icono SVG de modo empleado.

<span class="mode-text">Modo Empleado</span>
Texto del modo empleado.

</li>
Cierra el ítem modo empleado.

</ul>
Finaliza la lista de navegación principal.

<div class="category-label">Empresas</div>
Segunda sección de navegación.

<ul class="nav-menu">
Lista de menús de empresas.

<li class="nav-item">
Ítem “Destacadas”.

<svg viewBox="0 0 24 24"><path .../></svg>
Icono SVG para “Destacadas”.

<span>Destacadas</span>
Texto del ítem.

</li>
Cierra “Destacadas”.

<li class="nav-item">
Ítem “Buscar”.

<svg viewBox="0 0 24 24"><path .../></svg>
Icono SVG para “Buscar”.

<span>Buscar</span>
Texto del ítem.

</li>
Cierra “Buscar”.

</ul>
Cierra la lista de empresas.

</div>
Cierra el contenedor principal del sidebar.

<div class="profile" id="profileBtn">
Sección de perfil de usuario al pie del sidebar.

<div class="profile-info">
Agrupa icono y datos del usuario.

<div class="profile-icon"><svg viewBox="0 0 24 24"><circle .../></svg></div>
Icono SVG del avatar de usuario.

<div>
Contenedor de nombre y estado.

<div class="username">Usuario</div>
Nombre de usuario mostrado.

<div class="status"><span class="status-indicator"></span><span>En línea</span></div>
Indicador visual y texto de estado “En línea”.

</div>
Cierra el contenedor de texto de perfil.

</div>
Cierra la sección profile-info.

<ul class="nav-menu profile-links" id="profileLinks">
Lista de enlaces relacionados con el perfil.

<li class="nav-item"><span>Editar Perfil</span></li>
Opción “Editar Perfil”.

<li class="nav-item"><span>Postulaciones</span></li>
Opción “Postulaciones”.

<li class="nav-item logout"><span>Cerrar sesión</span></li>
Opción “Cerrar sesión” con clase logout.

</ul>
Cierra la lista de enlaces de perfil.

</div>
Cierra la sección de perfil.

</aside>
Finaliza el elemento aside del sidebar.

<main>
Empieza el contenido principal de la página.

<section class="hero">
Sección de “hero” con introducción y búsqueda destacada.

<div class="hero-content">
Contenedor interno de la sección hero.

<div class="hero-text">
Texto principal de bienvenida.

<h1>Bienvenido a EmpleoConnect</h1>
Encabezado principal.

<p class="subtitle">Tu plataforma inteligente para encontrar el empleo perfecto.</p>
Subtítulo descriptivo.

<h2>Encuentra tu próximo empleo</h2>
Segundo encabezado que refuerza el mensaje.

</div>
Cierra el bloque de texto hero.

<form class="search-form large-search-form">
Formulario de búsqueda amplio.

<input type="text" placeholder="Buscar empleos por título, empresa o palabra clave"/>
Campo de texto con placeholder descriptivo.

<button type="submit">
Botón de envío del formulario.

<i class="fa fa-search"></i> Buscar
Icono de lupa y texto “Buscar”.

</button>
Cierra el botón.

</form>
Finaliza el formulario de búsqueda.

</div>
Cierra el contenedor hero-content.

</section>
Finaliza la sección hero.

<section>
Nueva sección: “Ofertas destacadas”.

<div class="section-header">
Encabezado de la sección.

<h3>Ofertas destacadas</h3>
Título de sección.

<a href="ofertas.html" class="view-all-link">Ver todas <i class="fas fa-arrow-right"></i></a>
Enlace a página completa con icono de flecha.

</div>
Cierra el encabezado de sección.

<div class="offers-grid">
Contenedor en cuadrícula para las tarjetas de oferta.

<div class="offer-card">
Primera tarjeta de oferta.

<span class="badge">Remoto</span>
Etiqueta “Remoto”.

<h4>Desarrollador/a Backend</h4>
Título de la oferta.

<p>Tech Solutions</p>
Nombre de la empresa.

<p class="offer-location-home">Remoto</p>
Ubicación mostrada.

</div>
Cierra la tarjeta de oferta.

(Se repiten bloques similares para cada oferta con sus clases y contenido)

</div>
Cierra la cuadrícula de ofertas.

</section>
Finaliza la sección de ofertas destacadas.

<section class="explore-sections">
Sección para exploración por categorías y empresas top.

<div class="explore-section-card">
Bloque de exploración por categorías.

<div class="section-header">
Encabezado de tarjetas de categorías.

<h3>Explora por categorías</h3>
Título.

<a href="explorar.html" class="view-all-link">Ver todas <i class="fas fa-arrow-right"></i></a>
Enlace para ver más.

</div>
Cierra encabezado.

<div class="cats-grid">
Cuadrícula de botones de categorías.

<button class="category-button"><i class="fas fa-laptop-code"></i> IT</button>
Botón de categoría IT con icono.

(…otros botones de categorías…)

</div>
Cierra la cuadrícula de categorías.

</div>
Cierra la tarjeta de categorías.

<div class="explore-section-card">
Bloque de “Empresas top”.

<div class="section-header">
Encabezado de empresas.

<h3>Empresas top</h3>
Título.

<a href="destacadas.html" class="view-all-link">Ver todas <i class="fas fa-arrow-right"></i></a>
Enlace para más empresas.

</div>
Cierra encabezado.

<ul class="company-list">
Lista de empresas.

<li><div class="company-logo-thumb"></div> Tech Dynamics</li>
Elemento con logo y nombre.

(…otras empresas…)

</ul>
Cierra la lista.

</div>
Cierra la tarjeta de empresas.

</section>
Finaliza la sección de exploración.

<section class="how-it-works">
Sección “Cómo funciona”.

<div class="section-header centered">
Título centrado.

<h3>Cómo funciona EmpleoConnect</h3>
Encabezado.

</div>
Cierra encabezado.

<ol class="how-it-works-steps">
Lista ordenada de pasos.

<li>
Primer paso.

<div class="step-icon"><i class="fas fa-search"></i></div>
Icono de búsqueda.

<h4>Buscar</h4>
Título del paso.

<p>Explora miles de ofertas filtradas por tus preferencias.</p>
Descripción.

</li>
Cierra el primer paso.

(…otros pasos…)

</ol>
Cierra la lista de pasos.

</section>
Finaliza la sección de “Cómo funciona”.

<section class="testimonial-section">
Sección de testimonios.

<div class="section-header centered">
Encabezado.

<h3>Lo que dicen nuestros usuarios</h3>
Título.

</div>
Cierra encabezado.

<div class="testimonial-card">
Tarjeta de un testimonio.

<div class="testimonial-avatar"><i class="fas fa-user-circle"></i></div>
Avatar de usuario.

<blockquote>
Cita textualmente el testimonio.

Gracias a EmpleoConnect encontré el trabajo perfecto…
Contenido de la cita.

</blockquote>
Cierra el blockquote.

<p class="testimonial-author">- María G., Desarrolladora Web</p>
Autor del testimonio.

</div>
Cierra la tarjeta de testimonio.

</section>
Finaliza la sección de testimonios.

<section class="newsletter-section">
Sección de suscripción al boletín.

<div class="newsletter-content">
Contenido textual y formulario.

<h3>Mantente al día con las mejores ofertas</h3>
Título.

<p>Suscríbete a nuestro boletín…</p>
Descripción.

<form id="newsletterForm" class="newsletter-form">
Formulario de suscripción.

<input type="email" placeholder="Introduce tu email aquí" required/>
Campo email obligatorio.

<button type="submit">Suscribirme <i class="fas fa-paper-plane"></i></button>
Botón de envío con icono.

</form>
Cierra el formulario.

</div>
Cierra contenido de newsletter.

<div class="newsletter-image">
Contenedor de ilustración.

<svg viewBox="0 0 100 100" fill="var(--primary)"><circle cx="50" cy="50" r="40"/></svg>
Elemento SVG decorativo.

</div>
Cierra ilustración.

</section>
Finaliza sección de newsletter.

<footer>
Inicia pie de página.

<a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
Enlaces de política y contacto.

</footer>
Cierra pie de página.

</main>
Finaliza el contenido principal.

<script src="js/barraLateral.js" defer></script>
Importa script que controla el sidebar, diferido tras parseo.

<script src="js/desplegablePerfil.js" defer></script>
Importa script para el menú de perfil.

<script src="js/boletin.js" defer></script>
Importa script que gestiona la suscripción al boletín.

<script src="js/interaccionesInicio.js" defer></script>
Importa interacciones específicas de la página de inicio.

</body>
Cierra el cuerpo del documento.

</html>
Cierra el elemento raíz y finaliza el documento.

home.css

Este archivo contiene los estilos específicos de la página de inicio: gestiona el espaciado entre secciones, diseña la sección Hero con layout centrado y buscador ampliado, configura el grid horizontal desplazable de ofertas, organiza las secciones de exploración y empresas en grids responsivos, estiliza los pasos de “Cómo funciona” y la sección de testimonios con fondo y sombras, ajusta el formulario del newsletter y su imagen, y aplica media queries para adaptar el diseño, tamaños de texto y layouts a diferentes anchos de pantalla.

home.css – Estilos de Página Principal: Espaciado, Hero, Grillas y Secciones Interactivas

/* css/pages/home.css */

main > section {
    margin-bottom: calc(var(--gap) * 2);
}

.hero {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 6rem var(--gap) 4rem;
    background: var(--gray-100);
    border-radius: .75rem;
    overflow: hidden;
}

.hero-content {
    width: 100%;
    max-width: 800px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--gap)
}

.hero-text {
    width: 100%;
    max-width: 700px;
    margin-bottom: var(--gap);
}

.hero-text h1 {
     font-size: 3rem;
     margin-bottom: .5rem;
     color: var(--dark);
     line-height: 1.1;
     font-weight: 700;
}

.hero-text .subtitle {
    font-size: 1.25rem;
    color: var(--gray-500);
    margin-bottom: calc(var(--gap) * 2);
}

.hero-text h2 {
    display: none;
}

.large-search-form {
    max-width: 700px;
    box-shadow: 0 4px 15px rgba(0, 0, 0, .1);
    display: flex;
    width: 100%;
    border-radius: .5rem;
    overflow: hidden;
}
.large-search-form input {
    flex: 1;
    padding: 1rem 1.5rem;
    font-size: 1.1rem;
    border: none;
    outline: none;
}

.large-search-form button {
    padding: 0 2rem;
    font-size: 1.1rem;
    background: var(--primary);
    color: #fff;
    border: none;
    cursor: pointer;
    transition: background .2s;
    display: flex;
    align-items: center;
    gap: .5rem;
}

.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: var(--gap);
}

.section-header h3 {
    font-size: 1.5rem;
    color: var(--dark);
    margin: 0;
}

.section-header.centered {
     justify-content: center;
}

.view-all-link {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-size: 1rem;
    color: var(--primary);
    text-decoration: none;
    font-weight: 500;
    transition: color .2s;
}

.view-all-link:hover {
    color: var(--primary-dark);
    text-decoration: underline;
}

.offers-grid {
     margin-top: var(--gap);
     display: flex;
     gap: var(--gap);
     flex-wrap: nowrap;
     overflow-x: auto;
     padding-bottom: calc(var(--gap) * 1.5);
     padding-left: var(--gap);
     padding-right: var(--gap);
     margin-left: calc(var(--gap) * -1);
     margin-right: calc(var(--gap) * -1);
     box-sizing: border-box;
     scrollbar-width: thin;
     scrollbar-color: var(--gray-300) var(--gray-100);
}

.offers-grid::-webkit-scrollbar-track {
  background: var(--gray-100);
  border-radius: 10px;
}

.offers-grid::-webkit-scrollbar-thumb {
  background-color: var(--gray-300);
  border-radius: 10px;
  border: 3px solid var(--gray-100);
}

.offers-grid .offer-card {
     min-width: 280px;
     padding: 1.2rem;
     gap: .75rem;
     flex-shrink: 0;
     cursor: pointer;
}

.offers-grid .offer-card h4 {
     font-size: 1.2rem;
}

.offers-grid .offer-card p {
     font-size: 1rem;
     color: var(--gray-500);
}

.offers-grid .offer-card .offer-location-home {
    font-size: .9rem;
    color: var(--gray-400);
    margin-top: .25rem;
}

.explore-sections {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: calc(var(--gap) * 1.5);
}

.explore-section-card {
    background: #fff;
    padding: var(--gap);
    border-radius: .5rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
    display: flex;
    flex-direction: column;
}

.cats-grid {
     display: grid;
     grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
     gap: .75rem;
     margin-top: var(--gap);
}

.category-button {
     display: flex;
     flex-direction: column;
     align-items: center;
     gap: .5rem;
     background: var(--gray-100);
     border: 1px solid var(--gray-200);
     border-radius: .5rem;
     padding: 1rem .75rem;
     cursor: pointer;
     font-size: .95rem;
     font-weight: 600;
     color: var(--dark);
     transition: background .2s, border-color .2s, transform .1s ease;
     text-align: center;
}

.category-button:hover {
    background: var(--gray-200);
    border-color: var(--gray-300);
    transform: translateY(-2px);
}

.category-button i {
     font-size: 1.5rem;
     color: var(--primary);
}

.company-list {
     list-style: none;
     padding: 0;
     display: flex;
     flex-direction: column;
     gap: .75rem;
     margin-top: var(--gap);
}

.company-list li {
    display: flex;
    align-items: center;
    gap: .75rem;
    background: #fff;
    border: 1px solid var(--gray-200);
    border-radius: .5rem;
    padding: .75rem var(--gap);
    cursor: pointer;
    font-size: 1rem;
    color: var(--dark);
    transition: background .2s, border-color .2s;
     box-shadow: 0 1px 4px rgba(0, 0, 0, .03);
}

.company-list li:hover {
    background: var(--gray-100);
    border-color: var(--gray-300);
}

.company-logo-thumb {
    width: 30px;
    height: 30px;
    background: var(--gray-200);
    border-radius: .3rem;
    flex-shrink: 0;
    border: 1px solid var(--gray-100);
}

.how-it-works-steps {
     margin-top: calc(var(--gap) * 1.5);
     justify-content: flex-start;
}

.how-it-works-steps li {
     max-width: 200px;
     padding: var(--gap);
     background: #fff;
     border-radius: .5rem;
     box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
     flex: 1;
     min-width: 180px;
     justify-content: center;
}

.how-it-works-steps li svg {
     display: none;
}

.how-it-works-steps li .step-icon {
     font-size: 2.5rem;
     color: var(--secondary);
     margin-bottom: .75rem;
     display: flex;
     align-items: center;
     justify-content: center;
}

.how-it-works-steps li h4 {
    font-size: 1.2rem;
    color: var(--dark);
    margin-bottom: .5rem;
    margin-top: 0;
}

.how-it-works-steps li p {
    font-size: .95rem;
    color: var(--gray-600);
    margin: 0;
    line-height: 1.4;
}

.testimonial-section {
     background: var(--primary);
     color: #fff;
     padding: calc(var(--gap) * 3) var(--gap);
     border-radius: .75rem;
     text-align: center;
     margin-bottom: calc(var(--gap) * 2);
}

.testimonial-section .section-header h3 {
     color: #fff;
}

.testimonial-section .testimonial-card {
     background: rgba(255, 255, 255, 0.1);
     padding: calc(var(--gap) * 1.5);
     border-radius: .5rem;
     box-shadow: 0 5px 15px rgba(0, 0, 0, .2);
     display: flex;
     flex-direction: column;
     align-items: center;
     gap: var(--gap);
     max-width: 800px;
     margin: var(--gap) auto 0;
}

.testimonial-avatar {
    font-size: 3rem;
    color: #fff;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.testimonial-card blockquote {
     flex: none;
     font-size: 1.1rem;
     font-style: italic;
     color: #fff;
     margin: 0;
     line-height: 1.6;
}

.testimonial-author {
    font-size: 1rem;
    color: rgba(255, 255, 255, 0.8);
    margin: 0;
    font-weight: 500;
}

.newsletter-section {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    background: var(--light);
    padding: calc(var(--gap) * 2);
    border-radius: .75rem;
    gap: calc(var(--gap) * 2);
}

.newsletter-content {
    flex: 1;
    min-width: 280px;
    display: flex;
    flex-direction: column;
    gap: .75rem;
}

.newsletter-content h3 {
    font-size: 1.8rem;
    margin-bottom: .75rem;
    color: var(--dark);
    margin-bottom: 0;
}

.newsletter-content p {
    font-size: 1.1rem;
    color: var(--gray-600);
    margin-bottom: var(--gap);
    margin: 0;
}

.newsletter-form {
    max-width: 400px;
    width: 100%;
    box-shadow: none;
    display: flex;
    gap: .5rem;
     margin-top: var(--gap);
}

.newsletter-form input {
     flex: 1 1 150px;
     min-width: 0;
     border-radius: .5rem 0 0 .5rem;
}

.newsletter-form button {
     flex-shrink: 0;
     display: inline-flex;
     align-items: center;
     gap: .5rem;
     justify-content: center;
     border-radius: 0 .5rem .5rem 0;
     padding: .75rem 1.5rem;
}

.newsletter-image {
    flex-shrink: 0;
    width: 150px;
    height: 150px;
     display: flex;
     align-items: center;
     justify-content: center;
}

.newsletter-image svg {
    display: block;
    width: 100%;
    height: 100%;
}

@media (max-width: 900px) {
    .hero { padding: 4rem var(--gap); }
    .hero-text h1 { font-size: 2.3rem; }
    .hero-text .subtitle { font-size: 1.1rem; margin-bottom: var(--gap); }
    .large-search-form input { padding: .8rem 1.2rem; font-size: 1rem; }
    .large-search-form button { padding: 0 1.5rem; font-size: 1rem; }
    main > section { margin-bottom: calc(var(--gap) * 1.5); }
    .section-header { flex-direction: column; align-items: flex-start; gap: .5rem; }
    .section-header.centered { align-items: center; }
    .section-header h3 { font-size: 1.4rem; }
    .view-all-link { font-size: .95rem; }
    .offers-grid {
        padding-left: var(--gap);
        padding-right: var(--gap);
        margin-left: calc(var(--gap) * -1);
        margin-right: calc(var(--gap) * -1);
        padding-bottom: calc(var(--gap) * 1.5);
    }
    .offers-grid .offer-card { min-width: 240px; padding: 1rem; gap: .5rem; }
    .offers-grid .offer-card h4 { font-size: 1.1rem; }
    .offers-grid .offer-card p { font-size: .9rem; color: var(--gray-400); }
    .offers-grid .offer-card .offer-location-home { font-size: .85rem; }
    .offers-grid .offer-card .badge { font-size: .75rem; padding: .25rem .5rem; }
    .explore-sections { grid-template-columns: 1fr; gap: var(--gap); }
    .explore-section-card { padding: var(--gap); }
    .cats-grid { grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: .75rem; }
    .category-button { padding: .8rem .5rem; font-size: .9rem; gap: .3rem; }
    .category-button i { font-size: 1.3rem; }
    .company-list li { padding: .6rem var(--gap); gap: .6rem; font-size: .9rem; }
    .company-logo-thumb { width: 25px; height: 25px; }
    .how-it-works-steps { gap: var(--gap); justify-content: flex-start; }
    .how-it-works-steps li { max-width: none; width: 100%; flex: none; padding: .8rem; gap: .6rem; }
    .how-it-works-steps li .step-icon { font-size: 2rem; margin-bottom: .5rem; }
    .how-it-works-steps li h4 { font-size: 1.1rem; }
    .how-it-works-steps li p { font-size: .9rem; }
    .testimonial-section { padding: calc(var(--gap) * 2) var(--gap); }
    .testimonial-card { padding: var(--gap); gap: .8rem; }
    .testimonial-avatar { font-size: 2.5rem; }
    .testimonial-card blockquote { font-size: 1rem; }
    .testimonial-author { font-size: .9rem; }
    .newsletter-section { flex-direction: column; gap: var(--gap); padding: calc(var(--gap) * 1.5); align-items: center; }
    .newsletter-content { min-width: auto; width: 100%; align-items: center; text-align: center; gap: .5rem; }
    .newsletter-content h3 { font-size: 1.6rem; margin-bottom: 0; }
    .newsletter-content p { font-size: 1rem; margin-bottom: var(--gap); }
    .newsletter-form { flex-direction: column; gap: .8rem; max-width: 350px; margin: 0 auto; margin-top: 0; }
    .newsletter-form input { flex: none; width: 100%; border-radius: .5rem; padding: .7rem 1rem; font-size: .95rem; }
    .newsletter-form button { flex: none; width: 100%; border-radius: .5rem; padding: .7rem 1rem; font-size: .95rem; }
    .newsletter-image { width: 120px; height: 120px; }
}

@media (max-width: 700px) {
     .offers-section {
         padding-left: 0 !important;
         padding-right: 0 !important;
     }
     .offers-section .offers-grid {
         padding-left: var(--gap);
         padding-right: var(--gap);
         margin-left: 0 !important;
         margin-right: 0 !important;
         padding-bottom: var(--gap);
         display: flex;
         flex-direction: column;
         flex-wrap: wrap;
         overflow-x: visible;
         gap: var(--gap);
     }
     .offers-section .offers-grid .offer-card {
          min-width: auto;
          width: 100%;
          flex-shrink: 1;
          padding: var(--gap);
          gap: .5rem;
          margin: 0;
     }
     .offers-section .section-header {
          padding-left: var(--gap);
          padding-right: var(--gap);
     }


    .cats-grid { grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); }
    .category-button { padding: .6rem .3rem; font-size: .8rem; gap: .15rem; }
    .category-button i { font-size: 1.1rem; }
     .how-it-works-steps li {
          flex-direction: row;
          text-align: left;
          align-items: flex-start;
          gap: var(--gap);
          padding: var(--gap);
          min-width: auto;
          width: 100%;
          flex: none;
     }
      .how-it-works-steps li .step-icon { font-size: 2rem; margin-bottom: 0; flex-shrink: 0; }
      .how-it-works-steps li h4 { font-size: 1.1rem; margin-bottom: .3rem; }
      .how-it-works-steps li p { font-size: .9rem; }
     .newsletter-form { max-width: 300px; gap: .7rem; }
     .newsletter-form input { padding: .6rem .8rem; font-size: .9rem; }
     .newsletter-form button { padding: .6rem .8rem; font-size: .9rem; }
     .newsletter-image { width: 100px; height: 100px; }
}

@media (max-width: 500px) {
    .hero { padding: 2.5rem var(--gap); }
    .hero-text h1 { font-size: 1.8rem; }
    .hero-text .subtitle { font-size: .9rem; }
    .large-search-form input, .large-search-form button { font-size: .9rem; padding: .6rem .8rem; }
    .large-search-form button { padding: 0 1rem; }
    main > section { margin-bottom: calc(var(--gap) * 1); }
    .section-header h3 { font-size: 1.2rem; }
    .view-all-link { font-size: .85rem; }
    .offers-section {
        padding-left: 0 !important;
        padding-right: 0 !important;
    }
     .offers-section .offers-grid {
        padding-left: var(--gap);
        padding-right: var(--gap);
        margin-left: 0 !important;
        margin-right: 0 !important;
        padding-bottom: var(--gap);
        display: flex;
        flex-direction: column;
        flex-wrap: wrap;
        overflow-x: visible;
        gap: var(--gap);
     }
     .offers-section .offers-grid .offer-card {
         min-width: auto;
         width: calc(100% - (var(--gap) * 2));
         flex-shrink: 1;
         padding: var(--gap);
         gap: .4rem;
         margin: 0 auto;
     }
      .offers-section .section-header {
          padding-left: var(--gap);
          padding-right: var(--gap);
     }


    .cats-grid { gap: .4rem; }
    .category-button { font-size: .75rem; padding: .4rem .2rem; gap: .15rem; }
    .category-button i { font-size: 1rem; }
    .company-list li { font-size: .75rem; padding: .3rem .5rem; gap: .3rem; }
    .company-logo-thumb { width: 18px; height: 18px; }
    .how-it-works-steps { flex-direction: column; gap: var(--gap); justify-content: flex-start; }
    .how-it-works-steps li { flex-direction: column; text-align: center; align-items: center; gap: .5rem; padding: .8rem; max-width: none; width: 100%; flex: none; }
     .how-it-works-steps li .step-icon { font-size: 1.6rem; margin-bottom: .3rem; }
     .how-it-works-steps li h4 { font-size: .95rem; margin-bottom: .2rem; }
     .how-it-works-steps li p { font-size: .85rem; }
    .testimonial-section { padding: calc(var(--gap) * 0.8); }
    .testimonial-card { padding: .6rem; gap: .5rem; }
    .testimonial-avatar { font-size: 2rem; }
    .testimonial-card blockquote { font-size: .85rem; }
    .testimonial-author { font-size: .75rem; }
    .newsletter-section { padding: var(--gap); gap: var(--gap); }
    .newsletter-content h3 { font-size: 1.3rem; margin-bottom: .5rem; }
    .newsletter-content p { font-size: .85rem; margin-bottom: .8rem; }
    .newsletter-form { max-width: 280px; gap: .6rem; }
    .newsletter-form input { padding: .5rem .6rem; font-size: .85rem; }
    .newsletter-form button { padding: .5rem .6rem; font-size: .85rem; }
    .newsletter-image { width: 80px; height: 80px; }
}

Explicación del código: home.css – Estilos de Página Principal: Espaciado, Hero, Grillas y Secciones Interactivas

/* css/pages/home.css */
Comentario que indica el archivo CSS al que pertenecen las reglas: home.css.

main > section { margin-bottom: calc(var(--gap) * 2); }
Aplica a cada <section> hijo directo de <main> un espacio inferior igual al doble de la variable --gap.

.hero {
Inicia la regla para la sección “hero” de la página.

display: flex;
Convierte el contenedor en flexbox para centrar y apilar sus hijos.

flex-direction: column;
Organiza los elementos verticalmente.

align-items: center; justify-content: center;
Centra contenido horizontal y verticalmente.

text-align: center;
Centra el texto dentro del contenedor.

padding: 6rem var(--gap) 4rem;
Rellena 6 rem arriba, --gap laterales y 4 rem abajo.

background: var(--gray-100);
Aplica un fondo gris claro definido por variable.

border-radius: .75rem;
Redondea las esquinas con 0.75 rem.

overflow: hidden;
Oculta contenido que sobresalga del contenedor.

}

.hero-content {
Regla para el contenedor interno de la hero.

width: 100%; max-width: 800px;
Ocupa todo el ancho disponible hasta un máximo de 800 px.

display: flex; flex-direction: column;
Flexbox vertical para apilar su contenido.

align-items: center; gap: var(--gap);
Centra horizontalmente y deja --gap de separación entre ellos.

}

.hero-text {
Regla para el bloque de texto dentro de la hero.

width: 100%; max-width: 700px;
Máximo 700 px de ancho, adaptándose a pantallas más pequeñas.

margin-bottom: var(--gap);
Espacio inferior de --gap.

}

.hero-text h1 {
Estilos para el título principal dentro de .hero-text.

font-size: 3rem; margin-bottom: .5rem;
Texto muy grande y 0.5 rem de separación inferior.

color: var(--dark); line-height: 1.1; font-weight: 700;
Color oscuro, interlineado ajustado y negrita fuerte.

}

.hero-text .subtitle {
Regla para el subtítulo dentro de la hero.

font-size: 1.25rem; color: var(--gray-500);
Texto más pequeño y gris medio.

margin-bottom: calc(var(--gap) * 2);
Espacio inferior de dos veces --gap.

}

.hero-text h2 { display: none; }
Oculta el <h2> dentro de .hero-text, usado quizás solo en móvil.

.large-search-form {
Regla para el formulario de búsqueda destacado.

max-width: 700px; width: 100%;
Máximo 700 px de ancho, adaptándose al contenedor.

display: flex; border-radius: .5rem; overflow: hidden;
Flexbox horizontal, esquinas redondeadas y recorte de contenido.

box-shadow: 0 4px 15px rgba(0, 0, 0, .1);
Sombra suave para destacarlo.

}

.large-search-form input {
Estilos para el campo de texto dentro del formulario grande.

flex: 1; padding: 1rem 1.5rem; font-size: 1.1rem;
Ocupa todo el espacio disponible y tiene relleno cómodo.

border: none; outline: none;
Elimina bordes y contornos de enfoque por defecto.

}

.large-search-form button {
Estilos para el botón dentro del mismo formulario.

padding: 0 2rem; font-size: 1.1rem;
Relleno lateral e igual tamaño de texto al input.

background: var(--primary); color: #fff; border: none;
Fondo del color principal y texto blanco, sin borde.

cursor: pointer; transition: background .2s;
Cursor de mano y transición suave en el fondo al hover.

display: flex; align-items: center; gap: .5rem;
Flexbox para icono y texto, con separación de 0.5 rem.

}

.section-header {
Encabezado de sección común.

display: flex; justify-content: space-between; align-items: center;
Flexbox separando título y enlace al máximo.

margin-bottom: var(--gap);
Espacio inferior de --gap.

}

.section-header h3 {
Estilos para el título de cada sección.

font-size: 1.5rem; color: var(--dark); margin: 0;
Texto grande, color oscuro y sin margen.

}

.section-header.centered { justify-content: center; }
Variante centrada: alinea todo al centro.

.view-all-link {
Enlace “Ver todas” al final de cada sección.

display: inline-flex; align-items: center; gap: .3rem;
Flexbox compacto para icono y texto.

font-size: 1rem; color: var(--primary); text-decoration: none;
Texto del color principal, sin subrayado.

font-weight: 500; transition: color .2s;
Seminegrita y animación suave al hover.

}

.view-all-link:hover {
Estado hover del enlace.

color: var(--primary-dark); text-decoration: underline;
Texto más oscuro y subrayado.

}

.offers-grid {
Contenedor de tarjetas de ofertas en desplazamiento horizontal.

display: flex; gap: var(--gap); flex-wrap: nowrap; overflow-x: auto;
Flexbox en fila sin wrap y scroll horizontal.

padding: 0 calc(var(--gap) * 1) var(--gap);
Padding en ejes horizontal de --gap y vertical inferior de --gap.

margin: 0 calc(var(--gap) * -1);
Ajusta márgenes negativos para alinear el scroll con los bordes.

box-sizing: border-box; scrollbar-width: thin; scrollbar-color: var(--gray-300) var(--gray-100);
Caja con scroll estrecho y colores definidos para Firefox.

}

.offers-grid::-webkit-scrollbar-track {
Estilos del riel de scroll en WebKit.

background: var(--gray-100); border-radius: 10px;
Fondo gris claro y esquinas redondeadas.

}

.offers-grid::-webkit-scrollbar-thumb {
Estilos del thumb de scroll en WebKit.

background-color: var(--gray-300); border-radius: 10px; border: 3px solid var(--gray-100);
Thumb gris medio con borde para efecto “hueco”.

}

.offers-grid .offer-card {
Cada tarjeta dentro del contenedor de ofertas.

min-width: 280px; flex-shrink: 0; padding: 1.2rem; gap: .75rem; cursor: pointer;
Ancho mínimo fijo, relleno cómodo, separación interna y cursor de mano.

}

.offers-grid .offer-card h4 { font-size: 1.2rem; }
Título de oferta con fuente grande.

.offers-grid .offer-card p { font-size: 1rem; color: var(--gray-500); }
Texto de empresa en gris medio.

.offers-grid .offer-card .offer-location-home {
Ubicación con estilo propio.

font-size: .9rem; color: var(--gray-400); margin-top: .25rem;
Texto pequeño, gris claro y separación superior.

}

.explore-sections {
Contenedor de exploración por categorías y empresas top.

display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: calc(var(--gap) * 1.5);
Cuadrícula responsiva con gap de 1.5 × --gap.

}

.explore-section-card {
Tarjeta individual de exploración.

background: #fff; padding: var(--gap); border-radius: .5rem; box-shadow: 0 2px 8px rgba(0,0,0,.05);
Fondo blanco, relleno, esquinas redondeadas y sombra suave.

display: flex; flex-direction: column;
Flexbox vertical para su contenido.

}

.cats-grid {
Cuadrícula de botones de categorías.

display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: .75rem; margin-top: var(--gap);
Cuadrícula responsiva con gap de 0.75 rem y espacio superior.

}

.category-button {
Botón de categoría.

display: flex; flex-direction: column; align-items: center; gap: .5rem;
Flexbox vertical centrado, con separación.

background: var(--gray-100); border: 1px solid var(--gray-200);
Fondo gris claro y borde gris medio.

border-radius: .5rem; padding: 1rem .75rem; cursor: pointer;
Esquinas redondeadas, relleno cómodo y cursor de mano.

font-size: .95rem; font-weight: 600; color: var(--dark);
Texto seminegrita y color oscuro.

transition: background .2s, border-color .2s, transform .1s ease;
Animaciones suaves al hover.

text-align: center;
Centra el texto.

}

.category-button:hover {
Estado hover del botón.

background: var(--gray-200); border-color: var(--gray-300); transform: translateY(-2px);
Aclara fondo, cambia el borde y eleva el botón.

}

.category-button i { font-size: 1.5rem; color: var(--primary); }
Icono grande y coloreado con el color principal.

.company-list {
Lista de empresas.

list-style: none; padding: 0; display: flex; flex-direction: column; gap: .75rem; margin-top: var(--gap);
Lista sin viñetas, flexbox vertical y separación interna.

}

.company-list li {
Cada elemento de empresa.

display: flex; align-items: center; gap: .75rem;
Flexbox para logo y texto, con separación.

background: #fff; border: 1px solid var(--gray-200); border-radius: .5rem;
Fondo blanco, borde gris medio y esquinas redondeadas.

padding: .75rem var(--gap); cursor: pointer; font-size: 1rem; color: var(--dark);
Relleno, cursor de mano, texto oscuro.

transition: background .2s, border-color .2s; box-shadow: 0 1px 4px rgba(0,0,0,.03);
Sombra suave y animación al hover.

}

.company-list li:hover { background: var(--gray-100); border-color: var(--gray-300); }
Estado hover: fondo y borde más claros.

.company-logo-thumb {
Miniatura de logo.

width: 30px; height: 30px; background: var(--gray-200); border-radius: .3rem;
Cuadrado gris con esquinas ligeramente redondeadas.

flex-shrink: 0; border: 1px solid var(--gray-100);
No encoge y tiene borde claro.

}

.how-it-works-steps { margin-top: calc(var(--gap) * 1.5); justify-content: flex-start; }
Lista de pasos, con espacio superior y alineación al inicio.

.how-it-works-steps li {
Cada paso individual.

max-width: 200px; min-width: 180px; flex: 1; padding: var(--gap);
Anchura fija mínima/máxima y relleno de --gap.

background: #fff; border-radius: .5rem; box-shadow: 0 2px 8px rgba(0,0,0,.05);
Tarjeta blanca con sombra suave y esquinas redondeadas.

justify-content: center;
Centra su contenido en el eje principal.

}

.how-it-works-steps li svg { display: none; }
Oculta cualquier SVG nativo, usando en su lugar .step-icon.

.how-it-works-steps li .step-icon {
Clase que engloba el icono de cada paso.

font-size: 2.5rem; color: var(--secondary);
Icono grande y color secundario.

margin-bottom: .75rem; display: flex; align-items: center; justify-content: center;
Separación inferior y centrado completo.

}

.how-it-works-steps li h4 { font-size: 1.2rem; color: var(--dark); margin: .5rem 0 0; }
Título del paso con tamaño medio, color oscuro y sin margen superior.

.how-it-works-steps li p { font-size: .95rem; color: var(--gray-600); margin: 0; line-height: 1.4; }
Descripción del paso con texto gris oscuro, sin margen y buena lectura.

.testimonial-section {
Regla para la sección de testimonios.

background: var(--primary); color: #fff;
Fondo principal y texto blanco.

padding: calc(var(--gap)*3) var(--gap); border-radius: .75rem; text-align: center;
Relleno generoso, esquinas redondeadas y texto centrado.

margin-bottom: calc(var(--gap)*2);
Espacio inferior de dos veces --gap.

}

.testimonial-section .section-header h3 { color: #fff; }
Asegura que el título del testimonio sea blanco.

.testimonial-section .testimonial-card {
Estilos para la tarjeta de testimonio.

background: rgba(255,255,255,0.1);
Fondo blanco semitransparente para contraste.

padding: calc(var(--gap)*1.5); border-radius: .5rem; box-shadow: 0 5px 15px rgba(0,0,0,.2);
Relleno, esquinas redondeadas y sombra marcada.

display: flex; flex-direction: column; align-items: center; gap: var(--gap);
Flexbox vertical centrado con separación --gap.

max-width: 800px; margin: var(--gap) auto 0;
Ancho máximo y centrado horizontal.

}

.testimonial-avatar {
Icono/avatar dentro del testimonio.

font-size: 3rem; color: #fff; flex-shrink: 0;
Tamaño grande, color blanco y no se reduce.

display: flex; align-items: center; justify-content: center;
Centro completo para el icono.

}

.testimonial-card blockquote {
Cita dentro de la tarjeta.

font-size: 1.1rem; font-style: italic; color: #fff; margin: 0; line-height: 1.6;
Texto en cursiva, blanco, sin margen y buena legibilidad.

}

.testimonial-author { font-size: 1rem; color: rgba(255,255,255,0.8); margin: 0; font-weight: 500; }
Autor con texto seminegrita, blanco semitransparente y sin margen.

.newsletter-section {
Sección de suscripción al boletín.

display: flex; flex-wrap: wrap; align-items: center;
Flexbox adaptable para distintos anchos.

background: var(--light); padding: calc(var(--gap)*2);
Fondo claro y relleno amplio.

border-radius: .75rem; gap: calc(var(--gap)*2);
Esquinas redondeadas y separación generosa.

}

.newsletter-content { flex: 1; min-width: 280px; display: flex; flex-direction: column; gap: .75rem; }
Contenedor de texto y formulario, adaptándose a espacios reducidos.

.newsletter-content h3 { font-size: 1.8rem; color: var(--dark); margin: 0; }
Título grande y sin margen.

.newsletter-content p { font-size: 1.1rem; color: var(--gray-600); margin: 0; }
Descripción con texto medio y sin margen.

.newsletter-form { display: flex; gap: .5rem; max-width: 400px; width: 100%; }
Flexbox para input y botón, con separación y ancho adaptivo.

.newsletter-form input { flex: 1 1 150px; border-radius: .5rem 0 0 .5rem; }
Campo de email que ocupa el espacio disponible y tiene esquinas redondeadas en la izquierda.

.newsletter-form button { flex-shrink: 0; display: inline-flex; align-items: center; gap: .5rem;
Botón que no reduce su tamaño, con icono y texto separados.

border-radius: 0 .5rem .5rem 0; padding: .75rem 1.5rem; }
Esquinas redondeadas en la derecha y relleno.

.newsletter-image {
Contenedor de la ilustración del boletín.

flex-shrink: 0; width: 150px; height: 150px; display: flex; align-items: center; justify-content: center;
Tamaño fijo y centrado.

}

.newsletter-image svg { display: block; width: 100%; height: 100%; }
SVG que ocupa todo el contenedor sin espacio extra.

@media (max-width: 900px) {
Inicio de reglas responsivas para pantallas ≤900 px.

.hero { padding: 4rem var(--gap); }
Reduce el padding vertical de la hero.

.hero-text h1 { font-size: 2.3rem; }
Ajusta el tamaño del título.

.hero-text .subtitle { font-size: 1.1rem; margin-bottom: var(--gap); }
Ajusta subtítulo y espacio.

.large-search-form input { padding: .8rem 1.2rem; font-size: 1rem; }
Reduce padding y fuente del input.

.large-search-form button { padding: 0 1.5rem; font-size: 1rem; }
Reduce padding y fuente del botón.

main > section { margin-bottom: calc(var(--gap) * 1.5); }
Ajusta margen entre secciones.

.section-header { flex-direction: column; align-items: flex-start; gap: .5rem; }
Hace que el header de sección se apile verticalmente con espacio.

.section-header.centered { align-items: center; }
Mantiene centrado en la variante centered.

.section-header h3 { font-size: 1.4rem; }
Ajusta tamaño de título.

.view-all-link { font-size: .95rem; }
Reduce fuente del enlace.

.offers-grid { /* … */ }
Se mantienen ajustes de padding y márgenes negativos ya definidos anteriormente.

.offers-grid .offer-card { min-width: 240px; padding: 1rem; gap: .5rem; }
Tarjetas ligeramente más pequeñas y compactas.

.offers-grid .offer-card h4 { font-size: 1.1rem; }
Ajusta título de oferta.

.offers-grid .offer-card p { font-size: .9rem; color: var(--gray-400); }
Ajusta texto y color.

.offers-grid .offer-card .badge { font-size: .75rem; padding: .25rem .5rem; }
Etiquetas más pequeñas.

.explore-sections { grid-template-columns: 1fr; gap: var(--gap); }
Pasa a una sola columna.

.cats-grid { grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: .75rem; }
Ajusta tamaño mínimo de columnas.

.category-button { padding: .8rem .5rem; font-size: .9rem; gap: .3rem; }
Ajusta relleno, fuente y separación.

.category-button i { font-size: 1.3rem; }
Reduce tamaño de icono.

.company-list li { padding: .6rem var(--gap); gap: .6rem; font-size: .9rem; }
Ajusta padding y separación en lista de empresas.

.company-logo-thumb { width: 25px; height: 25px; }
Reduce miniatura de logo.

.how-it-works-steps { gap: var(--gap); justify-content: flex-start; }
Ajusta gap y alineación.

.how-it-works-steps li { max-width: none; width: 100%; flex: none; padding: .8rem; gap: .6rem; }
Tarjetas de paso totalmente adaptadas al ancho.

.how-it-works-steps li .step-icon { font-size: 2rem; margin-bottom: .5rem; }
Ajusta icono.

.how-it-works-steps li h4 { font-size: 1.1rem; }
Ajusta título.

.how-it-works-steps li p { font-size: .9rem; }
Ajusta descripción.

.testimonial-section { padding: calc(var(--gap)*2) var(--gap); }
Reduce padding.

.testimonial-card { padding: var(--gap); gap: .8rem; }
Ajusta relleno y espacio.

.testimonial-avatar { font-size: 2.5rem; }
Ajusta avatar.

.testimonial-card blockquote { font-size: 1rem; }
Ajusta cita.

.testimonial-author { font-size: .9rem; }
Ajusta autor.

.newsletter-section { flex-direction: column; gap: var(--gap); padding: calc(var(--gap)*1.5); align-items: center; }
Pasa la suscripción a columna y centra su contenido.

.newsletter-content { width: 100%; text-align: center; align-items: center; }
Ajusta contenido al centro.

.newsletter-content h3 { font-size: 1.6rem; }
Ajusta título.

.newsletter-content p { font-size: 1rem; }
Ajusta descripción.

.newsletter-form { flex-direction: column; gap: .8rem; max-width: 350px; margin: 0 auto; }
Formulario en columna y centrado.

.newsletter-form input, .newsletter-form button { width: 100%; padding: .7rem 1rem; font-size: .95rem; }
Ajusta campos y botón para ocupar todo el ancho.

.newsletter-image { width: 120px; height: 120px; }
Reduce ilustración.

}

@media (max-width: 700px) { /* Ajustes similares dentro de .offers-section y otros bloques para pantallas ≤700px */ }
Bloque responsivo que adapta específicamente la sección de ofertas y pasos para pantallas más pequeñas, ajustando padding, márgenes, flex-direcciones y tamaños de fuente.

@media (max-width: 500px) { /* Ajustes adicionales para pantallas muy pequeñas ≤500px: reduce tamaños y deja todo apilado/centrado */ }
Segunda capa de adaptabilidad para móviles muy pequeños, disminuyendo fuentes, paddings y reorganizando el layout a una sola columna.

ofertas.html

Este archivo configura la página de Ofertas de Empleo: carga los estilos globales y módulos de sidebar, logo, navegación, search-form y offer-card; añade el botón para alternar la barra lateral y define el aside con la navegación activa en “Ofertas”; y en el main muestra el header con título y subtítulo, la barra de filtros con buscador compacto y selects, la sección offers-list que despliega tarjetas de oferta con badge, título, empresa, ubicación, descripción, metadatos y botón de aplicar, y finaliza con el footer y los scripts de interactividad.

Ofertas.html - Ofertas de Empleo – EmpleoConnect HTML: Listado de Ofertas y Filtros Compactos

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Ofertas de Empleo - EmpleoConnect</title>
    <link rel="stylesheet" href="css/theme.css">
    <link rel="stylesheet" href="css/base.css">
    <link rel="stylesheet" href="css/layout.css">
    <link rel="stylesheet" href="css/state.css">
    <link rel="stylesheet" href="css/modules/sidebar.css">
    <link rel="stylesheet" href="css/modules/logo.css">
    <link rel="stylesheet" href="css/modules/navigation.css">
    <link rel="stylesheet" href="css/modules/profile-dropdown.css">
    <link rel="stylesheet" href="css/modules/sidebar-toggle.css">
    <link rel="stylesheet" href="css/modules/search-form.css">
    <link rel="stylesheet" href="css/modules/offer-card.css">
    <link rel="stylesheet" href="css/pages/ofertas.css">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">

</head>
<body class="sidebar-visible"> <button class="sidebar-toggle" id="sidebarToggle">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
          <line x1="3" y1="12" x2="21" y2="12"></line>
          <line x1="3" y1="6" x2="21" y2="6"></line>
          <line x1="3" y1="18" x2="21" y2="18"></line>
        </svg>
    </button>

    <aside class="sidebar" id="sidebar">
        <div>
            <div class="logo">
                <svg viewBox="0 0 24 24"><path d="M20 7h-4V3c0-1.1-.9-2-2-2h-4c-1.1 0-2 .9-2 2v4H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2z"/><path d="M11 14h2v4h-2zM7 14h2v4H7zM15 14h2v4h-2z"/></svg>
                EmpleoConnect
            </div>
            <div class="category-label">Navegar</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V9z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
                    <span>Inicio</span>
                </li>
                <li class="nav-item active">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/></svg>
                    <span>Ofertas</span>
                </li>
                <li class="nav-item">
                     <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg>
                    <span>Explorar</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
                    <span>Notificaciones</span>
                </li>
                 <li class="nav-item employee-mode" id="employeeModeBtn">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg>
                    <span class="mode-text">Modo Empleado</span>
                </li>
            </ul>
            <div class="category-label">Empresas</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21h18M9 8h1M9 12h1M9 16h1M15 8h1M15 12h1M15 16h1M7 21V5a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v16"/></svg>
                    <span>Destacadas</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 21v-2a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
                    <span>Buscar</span>
                </li>
            </ul>
        </div>
        <div class="profile" id="profileBtn">
            <div class="profile-info">
                <div class="profile-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg></div>
                <div>
                    <div class="username">Usuario</div>
                    <div class="status"><span class="status-indicator"></span><span>En línea</span></div>
                </div>
            </div>
            <ul class="nav-menu profile-links" id="profileLinks">
                <li class="nav-item"><span>Editar Perfil</span></li>
                <li class="nav-item"><span>Postulaciones</span></li>
                <li class="nav-item"><span>Notificaciones</span></li>
                <li class="nav-item logout"><span>Cerrar sesión</span></li>
            </ul>
        </div>
    </aside>

    <main>
        <section class="offers-header">
            <h1>Explora todas las Ofertas de Empleo</h1>
            <p>Encuentra la oportunidad laboral perfecta para ti entre miles de opciones disponibles.</p>

             <div class="filter-bar">
                <form class="search-form compact">
                    <input type="text" placeholder="Puesto, empresa, palabra clave..." aria-label="Buscar ofertas"/>
                    <button type="submit" aria-label="Buscar">
                        <i class="fa fa-search"></i>
                    </button>
                </form>
                <div class="filters">
                    <div class="filter-item">
                        <i class="fas fa-briefcase filter-icon"></i>
                        <select name="category" aria-label="Filtrar por categoría">
                            <option value="">Categoría</option>
                            <option value="it">IT</option>
                            <option value="ventas">Ventas</option>
                            <option value="ingenieria">Ingeniería</option>
                            <option value="marketing">Marketing</option>
                            <option value="salud">Salud</option>
                            <option value="educacion">Educación</option>
                            <option value="otros">Otros</option>
                        </select>
                    </div>
                     <div class="filter-item">
                         <i class="fas fa-map-marker-alt filter-icon"></i>
                        <select name="location" aria-label="Filtrar por ubicación">
                            <option value="">Ubicación</option>
                            <option value="remoto">Remoto</option>
                            <option value="madrid">Madrid</option>
                            <option value="barcelona">Barcelona</option>
                            <option value="valencia">Valencia</option>
                            <option value="sevilla">Sevilla</option>
                        </select>
                    </div>
                    <div class="filter-item">
                         <i class="fas fa-file-contract filter-icon"></i>
                        <select name="type" aria-label="Filtrar por tipo de contrato">
                            <option value="">Tipo de Contrato</option>
                            <option value="full-time">Tiempo Completo</option>
                            <option value="part-time">Tiempo Parcial</option>
                            <option value="contract">Contrato</option>
                            <option value="freelance">Freelance</option>
                        </select>
                    </div>
                     <button class="btn-filter-apply" type="button">Aplicar Filtros</button>
                </div>
            </div>
        </section>

        <section class="offers-list">
            <div class="offer-card">
                <div class="offer-card-header">
                    <span class="badge badge-remoto">Remoto</span>
                    </div>
                <h4>Desarrollador/a Frontend Senior</h4>
                <p class="company-name">Innovate Solutions</p>
                <p class="offer-location"><i class="fas fa-map-marker-alt"></i> Madrid, España (Remoto)</p>
                <p class="offer-description">Buscamos un/a desarrollador/a Frontend con experiencia en React y Next.js para unirse a nuestro equipo remoto.</p>
                <div class="offer-meta">
                     <span class="offer-type"><i class="fas fa-clock"></i> Tiempo Completo</span>
                     <span class="offer-salary"><i class="fas fa-money-bill-wave"></i> 40k - 55k €/año</span>
                </div>
                <button class="btn-apply">Ver Oferta</button>
            </div>

            <div class="offer-card">
                 <div class="offer-card-header">
                    <span class="badge badge-urgente">Urgente</span>
                 </div>
                <h4>Ejecutivo/a de Ventas B2B</h4>
                <p class="company-name">Global Sales Corp</p>
                <p class="offer-location"><i class="fas fa-map-marker-alt"></i> Barcelona, España</p>
                <p class="offer-description">Oportunidad para un/a profesional de ventas con habilidades de negociación y cierre de acuerdos.</p>
                 <div class="offer-meta">
                     <span class="offer-type"><i class="fas fa-clock"></i> Tiempo Completo</span>
                     <span class="offer-salary"><i class="fas fa-money-bill-wave"></i> Salario Competitivo + Comisiones</span>
                </div>
                <button class="btn-apply">Ver Oferta</button>
            </div>

             <div class="offer-card">
                 <div class="offer-card-header">
                    <span class="badge badge-presencial">Presencial</span>
                 </div>
                <h4>Diseñador/a Gráfico Junior</h4>
                <p class="company-name">Creative Studio Valencia</p>
                <p class="offer-location"><i class="fas fa-map-marker-alt"></i> Valencia, España</p>
                <p class="offer-description">Únete a nuestro estudio para trabajar en proyectos variados de branding y publicidad.</p>
                 <div class="offer-meta">
                     <span class="offer-type"><i class="fas fa-clock"></i> Tiempo Completo</span>
                     <span class="offer-salary"><i class="fas fa-money-bill-wave"></i> 20k - 25k €/año</span>
                </div>
                <button class="btn-apply">Ver Oferta</button>
            </div>

            <div class="offer-card">
                <div class="offer-card-header">
                    <span class="badge badge-remoto">Remoto</span>
                </div>
                <h4>Ingeniero/a de Datos</h4>
                <p class="company-name">Data Insights SL</p>
                <p class="offer-location"><i class="fas fa-map-marker-alt"></i> Remoto (España)</p>
                <p class="offer-description">Buscamos un/a ingeniero/a de datos con experiencia en ETL y bases de datos distribuidas.</p>
                 <div class="offer-meta">
                     <span class="offer-type"><i class="fas fa-clock"></i> Tiempo Completo</span>
                     <span class="offer-salary"><i class="fas fa-money-bill-wave"></i> 45k - 60k €/año</span>
                </div>
                <button class="btn-apply">Ver Oferta</button>
            </div>

             <div class="offer-card">
                 <div class="offer-card-header">
                    <span class="badge badge-contrato">Contrato</span>
                 </div>
                <h4>Consultor/a SAP MM</h4>
                <p class="company-name">SAP Experts Agency</p>
                <p class="offer-location"><i class="fas fa-map-marker-alt"></i> Sevilla, España (Híbrido)</p>
                <p class="offer-description">Proyecto de 6 meses para implementación de módulo MM en importante cliente.</p>
                 <div class="offer-meta">
                     <span class="offer-type"><i class="fas fa-clock"></i> Contrato</span>
                     <span class="offer-salary"><i class="fas fa-money-bill-wave"></i> Por proyecto</span>
                </div>
                <button class="btn-apply">Ver Oferta</button>
            </div>

             <div class="offer-card">
                <div class="offer-card-header">
                    <span class="badge badge-remoto">Remoto</span>
                </div>
                <h4>Marketing Digital Specialist</h4>
                <p class="company-name">Growth Hackers SL</p>
                <p class="offer-location"><i class="fas fa-map-marker-alt"></i> Remoto (Internacional)</p>
                <p class="offer-description">Especialista en SEO/SEM y estrategia de contenido para campañas globales.</p>
                 <div class="offer-meta">
                     <span class="offer-type"><i class="fas fa-clock"></i> Tiempo Completo</span>
                     <span class="offer-salary"><i class="fas fa-money-bill-wave"></i> 35k - 50k €/año</span>
                </div>
                <button class="btn-apply">Ver Oferta</button>
            </div>

             <div class="offer-card">
                 <div class="offer-card-header">
                    <span class="badge badge-presencial">Presencial</span>
                 </div>
                <h4>Enfermero/a</h4>
                <p class="company-name">Hospital Central Madrid</p>
                <p class="offer-location"><i class="fas fa-map-marker-alt"></i> Madrid, España</p>
                <p class="offer-description">Oportunidad para enfermeros/as con experiencia en urgencias o cuidados intensivos.</p>
                 <div class="offer-meta">
                     <span class="offer-type"><i class="fas fa-clock"></i> Tiempo Completo</span>
                     <span class="offer-salary"><i class="fas fa-money-bill-wave"></i> Según Convenio + Plus</span>
                </div>
                <button class="btn-apply">Ver Oferta</button>
            </div>

            <div class="offer-card">
                <div class="offer-card-header">
                    <span class="badge badge-remoto">Remoto</span>
                 </div>
                <h4>Profesor/a de Inglés Online</h4>
                <p class="company-name">Online Language School</p>
                <p class="offer-location"><i class="fas fa-map-marker-alt"></i> Remoto</p>
                <p class="offer-description">Buscamos profesores nativos o bilingües para clases online a estudiantes de todas las edades.</p>
                 <div class="offer-meta">
                     <span class="offer-type"><i class="fas fa-clock"></i> Tiempo Parcial</span>
                     <span class="offer-salary"><i class="fas fa-money-bill-wave"></i> Por hora</span>
                </div>
                <button class="btn-apply">Ver Oferta</button>
            </div>
        </section>

        <footer>
            <a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
        </footer>
    </main>

    <script src="js/barraLateral.js" defer></script>
    <script src="js/desplegablePerfil.js" defer></script>
    <script src="js/interaccionesInicio.js" defer></script>
</body>
</html>

Explicación del código: Ofertas.html - EmpleoConnect HTML: Listado de Ofertas y Filtros Compactos

<!DOCTYPE html>
Declara el documento como HTML5, asegurando el modo de renderizado estándar.

<html lang="es">
Elemento raíz con atributo de idioma “español” para navegadores y lectores de pantalla.

<head>
Inicia la sección de metadatos y enlaces a recursos (no visible directamente).

<meta charset="UTF-8"/>
Define la codificación de caracteres en UTF-8, soportando caracteres especiales y acentos.

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
Ajusta el ancho y la escala de la página según el dispositivo, clave para diseño responsivo.

<title>Ofertas de Empleo - EmpleoConnect</title>
Título que aparece en la pestaña del navegador y en los favoritos.

<link rel="stylesheet" href="css/theme.css">
Importa estilos de tema global (colores, tipografías).

<link rel="stylesheet" href="css/base.css">
Carga estilos base (reset, variables, tipografías).

<link rel="stylesheet" href="css/layout.css">
Define grillas y contenedores generales.

<link rel="stylesheet" href="css/state.css">
Clases de estado (activo, hover, deshabilitado, etc.).

<link rel="stylesheet" href="css/modules/sidebar.css">
Estilos del componente de barra lateral.

<link rel="stylesheet" href="css/modules/logo.css">
Diseño del bloque de logo.

<link rel="stylesheet" href="css/modules/navigation.css">
Estilos del menú de navegación.

<link rel="stylesheet" href="css/modules/profile-dropdown.css">
Diseño del menú desplegable de perfil.

<link rel="stylesheet" href="css/modules/sidebar-toggle.css">
Estilos del botón para mostrar/ocultar el sidebar.

<link rel="stylesheet" href="css/modules/search-form.css">
Estilos del formulario de búsqueda.

<link rel="stylesheet" href="css/modules/offer-card.css">
Diseño de tarjetas de oferta.

<link rel="stylesheet" href="css/pages/ofertas.css">
Estilos específicos para la página de Ofertas.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
Carga Font Awesome desde CDN para iconos vectoriales.

</head>
Cierra la sección de metadatos.

<body class="sidebar-visible">
Inicia el contenido visible, con clase que lanza el sidebar abierto por defecto.

<button class="sidebar-toggle" id="sidebarToggle">
Botón flotante para alternar la barra lateral en pantallas pequeñas.

<svg …>…</svg>
Icono “hamburguesa” en SVG para el botón.

</button>
Cierra el botón de toggle.

<aside class="sidebar" id="sidebar">
Elemento semántico aside que contiene la barra lateral de navegación.

<div>
Contenedor interno para agrupar bloques de la barra.

<div class="logo">
Bloque del logo y nombre de la app.

<svg …>…</svg>
Icono SVG del logo.

EmpleoConnect
Texto del nombre de la plataforma.

</div>
Cierra el bloque de logo.

<div class="category-label">Navegar</div>
Etiqueta que separa la sección de navegación principal.

<ul class="nav-menu">
Lista de elementos del menú.

<li class="nav-item">…Inicio…</li>
Ítem “Inicio” con SVG y texto.

<li class="nav-item active">…Ofertas…</li>
Ítem “Ofertas” activo (clase .active).

<li class="nav-item">…Explorar…</li>
Ítem “Explorar”.

<li class="nav-item">…Notificaciones…</li>
Ítem “Notificaciones”.

<li class="nav-item employee-mode" id="employeeModeBtn">…Modo Empleado…</li>
Ítem para alternar modo empleado, con icono y texto.

</ul>
Cierra la lista de navegación principal.

<div class="category-label">Empresas</div>
Segunda sección de navegación etiquetada “Empresas”.

<ul class="nav-menu">
Lista de ítems de empresas.

<li class="nav-item">…Destacadas…</li>
Ítem “Destacadas”.

<li class="nav-item">…Buscar…</li>
Ítem “Buscar”.

</ul>
Cierra la segunda lista.

</div>
Cierra el contenedor principal del sidebar.

<div class="profile" id="profileBtn">
Sección de perfil ubicada al final del sidebar.

<div class="profile-info">
Contenido con avatar, nombre y estado.

<div class="profile-icon"><svg …>…</svg></div>
Icono SVG representando al usuario.

<div>
Contenedor de texto de perfil.

<div class="username">Usuario</div>
Nombre de usuario mostrado.

<div class="status"><span class="status-indicator"></span><span>En línea</span></div>
Indicador y texto de estado “En línea”.

</div>
Cierra el contenedor de texto.

</div>
Cierra profile-info.

<ul class="nav-menu profile-links" id="profileLinks">
Lista de enlaces adicionales de perfil.

<li class="nav-item"><span>Editar Perfil</span></li>
Opción “Editar Perfil”.

<li class="nav-item"><span>Postulaciones</span></li>
Opción “Postulaciones”.

<li class="nav-item"><span>Notificaciones</span></li>
Opción “Notificaciones”.

<li class="nav-item logout"><span>Cerrar sesión</span></li>
Opción “Cerrar sesión”.

</ul>
Cierra la lista de enlaces de perfil.

</div>
Cierra la sección de perfil.

</aside>
Finaliza el aside del sidebar.

<main>
Comienza el contenido principal de la página.

<section class="offers-header">
Encabezado de la página de ofertas.

<h1>Explora todas las Ofertas de Empleo</h1>
Título principal de la sección.

<p>Encuentra la oportunidad…</p>
Descripción introductoria.

<div class="filter-bar">
Contenedor de filtros y búsqueda.

<form class="search-form compact">
Formulario de búsqueda compacto.

<input type="text" placeholder="Puesto, empresa…" aria-label="Buscar ofertas"/>
Campo de texto con atributo accesible aria-label.

<button type="submit" aria-label="Buscar">…</button>
Botón con icono y etiqueta accesible.

</form>
Cierra el formulario de búsqueda.

<div class="filters">
Contenedor de selects de filtrado.

<div class="filter-item">…Categoría select…</div>
Primer filtro: categoría con icono.

<div class="filter-item">…Ubicación select…</div>
Segundo filtro: ubicación.

<div class="filter-item">…Tipo de contrato select…</div>
Tercer filtro: tipo de contrato.

<button class="btn-filter-apply">Aplicar Filtros</button>
Botón para activar los filtros.

</div>
Cierra el contenedor de filtros.

</div>
Cierra filter-bar.

</section>
Finaliza la sección de encabezado y filtros.

<section class="offers-list">
Sección que contiene la lista de ofertas.

<div class="offer-card">…Oferta 1…</div>
Primera tarjeta de oferta con badge, título, empresa, ubicación, descripción, meta y botón.

<div class="offer-card">…Oferta 2…</div>
Segunda tarjeta de oferta.

<div class="offer-card">…Oferta 3…</div>
Tercera tarjeta de oferta.

<div class="offer-card">…Oferta 4…</div>
Cuarta tarjeta de oferta.

<div class="offer-card">…Oferta 5…</div>
Quinta tarjeta de oferta.

<div class="offer-card">…Oferta 6…</div>
Sexta tarjeta de oferta.

<div class="offer-card">…Oferta 7…</div>
Séptima tarjeta de oferta.

<div class="offer-card">…Oferta 8…</div>
Octava tarjeta de oferta.

</section>
Finaliza la sección de lista de ofertas.

<footer>
Empieza el pie de página.

<a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
Enlaces legales y de información.

</footer>
Cierra el pie de página.

</main>
Finaliza el contenido principal.

<script src="js/barraLateral.js" defer></script>
Carga diferida del script que controla la barra lateral.

<script src="js/desplegablePerfil.js" defer></script>
Carga diferida del menú desplegable de perfil.

<script src="js/interaccionesInicio.js" defer></script>
Carga diferida de interacciones propias de la página de Ofertas.

</body>
Cierra el cuerpo del documento.

</html>
Cierra el elemento raíz y finaliza el documento.

ofertas.css

Este archivo estiliza la página de Ofertas: da formato a la cabecera con fondo suave, padding y texto centrado; organiza la barra de filtros con búsqueda compacta, selects en contenedores flexibles y un botón de aplicación; dispone las tarjetas de oferta en un grid responsivo; y añade media queries para adaptar la posición de los filtros y el número de columnas en diferentes tamaños de pantalla.

ofertas.css – Cabecera, Barra de Filtros y Lista de Ofertas

/* css/pages/ofertas.css */

.offers-header {
    background-color: var(--gray-100); 
    padding: calc(var(--gap) * 1.5) var(--gap);
    border-radius: .5rem;
    margin-bottom: calc(var(--gap) * 1.5);
    text-align: center; 
}

.offers-header h1 {
    color: var(--primary);
    margin-bottom: .25em;
}

.offers-header p {
    color: var(--dark);
    margin-bottom: var(--gap);
    max-width: 600px; 
    margin-left: auto;
    margin-right: auto;
}

.filter-bar {
    display: flex;
    flex-direction: column; 
    gap: var(--gap);
    margin-top: var(--gap);
    align-items: center; 
}

.filter-bar .search-form.compact {
    max-width: 100%; 
    box-shadow: none; 
    border: 1px solid var(--gray-200); 
    border-radius: .5rem;
}

.filter-bar .search-form.compact input {
     border-radius: .5rem 0 0 .5rem;
}
.filter-bar .search-form.compact button {
     border-radius: 0 .5rem .5rem 0;
}

.filters {
    display: flex;
    flex-wrap: wrap; 
    gap: .75rem; 
    width: 100%;
    justify-content: center; 
}

.filter-item {
    display: flex;
    align-items: center;
    background-color: #fff;
    border: 1px solid var(--gray-200);
    border-radius: .5rem;
    overflow: hidden; 
    flex-grow: 1; 
    min-width: 180px; 
}

.filter-icon {
    padding: 0 .75rem;
    color: var(--gray-300);
    border-right: 1px solid var(--gray-200);
}

.filters select {
    flex-grow: 1;
    padding: .6rem .8rem;
    border: none;
    background-color: transparent; 
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    cursor: pointer;
    font-size: .9rem;
    color: var(--dark);
    outline: none;
    background-repeat: no-repeat;
    background-position: right .75rem center;
    background-size: 1em;
    padding-right: 2.5rem; 
}

.filters select:invalid {
   color: var(--gray-300);
}
.filters option {
    color: var(--dark); 
}

.btn-filter-apply {
    background-color: var(--primary);
    color: white;
    border: none;
    padding: .6rem 1.2rem;
    border-radius: .5rem;
    cursor: pointer;
    font-weight: 600;
    transition: background-color 0.2s ease;
    font-size: 0.9rem;
    white-space: nowrap; 
}

.btn-filter-apply:hover {
    background-color: var(--primary-dark);
}

.offers-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: var(--gap); 
}

@media (min-width: 768px) {
    .filter-bar {
        flex-direction: row; 
        align-items: stretch; 
    }
    .filter-bar .search-form.compact {
        max-width: 300px; 
        flex-shrink: 0; 
    }
    .filters {
        justify-content: flex-start; 
        flex-grow: 1; 
    }
    .filter-item {
        flex-grow: 0; 
        flex-basis: 200px; 
    }
}

@media (max-width: 480px) {
    .filter-item {
        min-width: 150px; 
    }
    .offers-list {
         grid-template-columns: 1fr;
    }
}

Explicación del código: ofertas.css – Cabecera, Barra de Filtros y Lista de Ofertas

/* css/pages/ofertas.css */
Comentario que indica que las reglas pertenecen al archivo ofertas.css.

.offers-header {
Inicia la regla para el contenedor de encabezado de la sección de ofertas.

background-color: var(--gray-100);
Aplica un fondo gris claro usando la variable CSS --gray-100.

padding: calc(var(--gap) * 1.5) var(--gap);
Añade relleno vertical de 1.5 veces --gap y horizontal de --gap.

border-radius: .5rem;
Redondea las esquinas con un radio de 0.5 rem.

margin-bottom: calc(var(--gap) * 1.5);
Separa el bloque de ofertas del siguiente contenido con 1.5 veces --gap.

text-align: center;
Centra todo el texto dentro de este contenedor.

}

.offers-header h1 {
Regla para el título <h1> dentro de .offers-header.

color: var(--primary);
Pinta el texto con el color primario definido.

margin-bottom: .25em;
Deja un pequeño espacio tras el título, de 0.25 em.

}

.offers-header p {
Regla para el párrafo introductorio dentro de .offers-header.

color: var(--dark);
Aplica el color oscuro definido para texto.

margin-bottom: var(--gap);
Espacio inferior igual a --gap.

max-width: 600px;
Limita el ancho máximo del texto a 600 px para mejorar legibilidad.

margin-left: auto; margin-right: auto;
Centra horizontalmente el párrafo dentro del contenedor.

}

.filter-bar {
Inicia la regla para la barra de filtros y búsqueda.

display: flex; flex-direction: column;
Flexbox vertical para apilar búsqueda y filtros uno encima de otro.

gap: var(--gap);
Espacio entre los hijos igual a --gap.

margin-top: var(--gap);
Separa la barra de filtros del contenido superior con --gap.

align-items: center;
Centra horizontalmente sus elementos hijos.

}

.filter-bar .search-form.compact {
Estilos para el formulario de búsqueda en su variante compacta dentro de .filter-bar.

max-width: 100%;
Permite que ocupe todo el ancho disponible.

box-shadow: none;
Elimina cualquier sombra por defecto.

border: 1px solid var(--gray-200);
Añade un borde gris medio definido por la variable --gray-200.

border-radius: .5rem;
Esquinas redondeadas de 0.5 rem.

}

.filter-bar .search-form.compact input {
Estilos para el campo de texto dentro del formulario compacto.

border-radius: .5rem 0 0 .5rem;
Redondea las esquinas izquierda superior e inferior.

}

.filter-bar .search-form.compact button {
Estilos para el botón dentro del formulario compacto.

border-radius: 0 .5rem .5rem 0;
Redondea las esquinas derecha superior e inferior.

}

.filters {
Inicia la regla para el contenedor de selects de filtrado.

display: flex; flex-wrap: wrap;
Flexbox que permite ajustar a varias filas si hace falta.

gap: .75rem;
Espacio de 0.75 rem entre cada filtro.

width: 100%;
Ocupa todo el ancho del contenedor padre.

justify-content: center;
Centra los filtros horizontalmente.

}

.filter-item {
Regla para cada bloque individual de filtro (icono + select).

display: flex; align-items: center;
Flexbox horizontal que centra icono y select verticalmente.

background-color: #fff;
Fondo blanco para destacar sobre el gris de fondo.

border: 1px solid var(--gray-200);
Borde gris medio.

border-radius: .5rem;
Esquinas redondeadas.

overflow: hidden;
Oculta cualquier contenido que sobresalga del bloque.

flex-grow: 1;
Permite que cada filtro crezca para llenar el espacio disponible.

min-width: 180px;
Ancho mínimo de 180 px para legibilidad.

}

.filter-icon {
Regla para el icono dentro de .filter-item.

padding: 0 .75rem;
Relleno horizontal de 0.75 rem.

color: var(--gray-300);
Color gris claro para el icono.

border-right: 1px solid var(--gray-200);
Línea divisoria entre icono y select.

}

.filters select {
Estilos para los elementos <select> dentro de .filters.

flex-grow: 1;
Hace que el select ocupe todo el espacio restante.

padding: .6rem .8rem;
Relleno para dar espacio al texto.

border: none; background-color: transparent;
Elimina borde y fondo por defecto para integrar con el bloque.

appearance: none; -webkit-appearance: none; -moz-appearance: none;
Quita estilos nativos del navegador, dejando solo el del CSS.

cursor: pointer; font-size: .9rem; color: var(--dark);
Muestra cursor de mano, texto de 0.9 rem y color oscuro.

outline: none;
Elimina el outline al recibir foco.

background-repeat: no-repeat; background-position: right .75rem center; background-size: 1em;
Prepara espacio para un icono de flecha personalizado (no proporcionado aquí).

padding-right: 2.5rem;
Añade espacio a la derecha para el icono de flecha.

}

.filters select:invalid {
Estado cuando el usuario no ha seleccionado opción válida.

color: var(--gray-300);
Pinta el texto del select en gris claro.

}

.filters option {
Estilos para las opciones dentro del select.

color: var(--dark);
Asegura que las opciones se muestren en color oscuro.

}

.btn-filter-apply {
Regla para el botón “Aplicar Filtros”.

background-color: var(--primary); color: white;
Fondo del color primario y texto blanco.

border: none;
Elimina cualquier borde.

padding: .6rem 1.2rem;
Relleno cómodo para el texto.

border-radius: .5rem;
Esquinas redondeadas.

cursor: pointer; font-weight: 600;
Cursor de mano y texto seminegrita.

transition: background-color 0.2s ease;
Suaviza el cambio de fondo en hover.

font-size: 0.9rem; white-space: nowrap;
Tamaño de fuente de 0.9 rem y evita saltos de línea.

}

.btn-filter-apply:hover {
Estado hover del botón de filtros.

background-color: var(--primary-dark);
Usa la variante más oscura del color primario.

}

.offers-list {
Inicia la regla para el contenedor de tarjetas de oferta.

display: grid;
Convierte el bloque en cuadrícula.

grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
Crea tantas columnas de al menos 300 px como quepan, adaptándose al espacio.

gap: var(--gap);
Espacio entre filas y columnas de --gap.

}

@media (min-width: 768px) {
Comienza reglas específicas para pantallas de al menos 768 px de ancho.

.filter-bar { flex-direction: row; align-items: stretch; }
En pantallas grandes, coloca búsqueda y filtros en fila y estira verticalmente.

.filter-bar .search-form.compact { max-width: 300px; flex-shrink: 0; }
Limita el ancho del formulario compacto a 300 px y evita que se reduzca.

.filters { justify-content: flex-start; flex-grow: 1; }
Alinea los filtros a la izquierda y deja que crezcan para llenar el espacio.

.filter-item { flex-grow: 0; flex-basis: 200px; }
Cada filtro ocupa 200 px de base sin crecer.

}

@media (max-width: 480px) {
Comienza reglas para pantallas de hasta 480 px de ancho.

.filter-item { min-width: 150px; }
Reduce el ancho mínimo de cada filtro a 150 px.

.offers-list { grid-template-columns: 1fr; }
Coloca las tarjetas de oferta en una sola columna.

}

explorar.html

Este archivo configura la página de “Explorar”: carga los estilos globales y módulos de sidebar, logo, navegación y tarjetas de oferta; añade el botón para alternar la barra lateral y define el aside con la opción “Explorar” activa; y en el main incluye la sección .explore-header con título y subtítulo, varias secciones .explore-section —“Explorar por Categoría” con un grid de categorías, “Explorar por Ubicación” con enlaces de ubicación, y “Empresas Destacadas” con lista expandida—, y finaliza con el footer y los scripts de interactividad.

Explorar – EmpleoConnect HTML: Secciones de Categorías, Ubicaciones y Empresas Destacadas

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Explorar - EmpleoConnect</title>
    <link rel="stylesheet" href="css/theme.css">
    <link rel="stylesheet" href="css/base.css">
    <link rel="stylesheet" href="css/layout.css">
    <link rel="stylesheet" href="css/state.css">
    <link rel="stylesheet" href="css/modules/sidebar.css">
    <link rel="stylesheet" href="css/modules/logo.css">
    <link rel="stylesheet" href="css/modules/navigation.css">
    <link rel="stylesheet" href="css/modules/profile-dropdown.css">
    <link rel="stylesheet" href="css/modules/sidebar-toggle.css">
    <link rel="stylesheet" href="css/modules/offer-card.css"> <link rel="stylesheet" href="css/pages/explorar.css">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">

</head>
<body class="sidebar-visible">
    <button class="sidebar-toggle" id="sidebarToggle">
        <svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
    </button>

    <aside class="sidebar" id="sidebar">
        <div>
            <div class="logo">
                <svg viewBox="0 0 24 24"><path d="M20 7h-4V3c0-1.1-.9-2-2-2h-4c-1.1 0-2 .9-2 2v4H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2z"/><path d="M11 14h2v4h-2zM7 14h2v4H7zM15 14h2v4h-2z"/></svg>
                EmpleoConnect
            </div>
            <div class="category-label">Navegar</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V9z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
                    <span>Inicio</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/></svg>
                    <span>Ofertas</span>
                </li>
                <li class="nav-item active">
                    <svg viewBox="0 0 24 24"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg>
                    <span>Explorar</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
                    <span>Notificaciones</span>
                </li>
                 <li class="nav-item employee-mode" id="employeeModeBtn">
                    <svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg>
                    <span class="mode-text">Modo Empleado</span>
                </li>
            </ul>
            <div class="category-label">Empresas</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M3 21h18M9 8h1M9 12h1M9 16h1M15 8h1M15 12h1M15 16h1M7 21V5a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v16"/></svg>
                    <span>Destacadas</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M4 21v-2a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
                    <span>Buscar</span>
                </li>
            </ul>
        </div>
        <div class="profile" id="profileBtn">
            <div class="profile-info">
                <div class="profile-icon"><svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg></div>
                <div>
                    <div class="username">Usuario</div>
                    <div class="status"><span class="status-indicator"></span><span>En línea</span></div>
                </div>
            </div>
            <ul class="nav-menu profile-links" id="profileLinks">
                <li class="nav-item"><span>Editar Perfil</span></li>
                <li class="nav-item"><span>Postulaciones</span></li>
                <li class="nav-item"><span>Notificaciones</span></li>
                <li class="nav-item logout"><span>Cerrar sesión</span></li>
            </ul>
        </div>
    </aside>

    <main>
        <section class="explore-header">
            <h1>Explora Oportunidades en EmpleoConnect</h1>
            <p>Descubre empleos, empresas y sectores que se ajustan a tus intereses y habilidades.</p>
        </section>

        <section class="explore-section">
            <h2>Explorar por Categoría</h2>
            <div class="category-grid">
                <a href="#" class="explore-item category-item">
                    <div class="item-icon"><i class="fas fa-laptop-code"></i></div>
                    <div class="item-text">IT y Desarrollo</div>
                    <span class="item-count">1500+ ofertas</span>
                </a>
                 <a href="#" class="explore-item category-item">
                    <div class="item-icon"><i class="fas fa-chart-line"></i></div>
                    <div class="item-text">Ventas y Comercial</div>
                     <span class="item-count">800+ ofertas</span>
                </a>
                 <a href="#" class="explore-item category-item">
                    <div class="item-icon"><i class="fas fa-flask"></i></div>
                    <div class="item-text">Ingeniería</div>
                     <span class="item-count">1200+ ofertas</span>
                </a>
                 <a href="#" class="explore-item category-item">
                    <div class="item-icon"><i class="fas fa-bullhorn"></i></div>
                    <div class="item-text">Marketing y Comunicación</div>
                     <span class="item-count">600+ ofertas</span>
                </a>
                 <a href="#" class="explore-item category-item">
                    <div class="item-icon"><i class="fas fa-heartbeat"></i></div>
                    <div class="item-text">Salud</div>
                     <span class="item-count">400+ ofertas</span>
                </a>
                 <a href="#" class="explore-item category-item">
                    <div class="item-icon"><i class="fas fa-book-open"></i></div>
                    <div class="item-text">Educación</div>
                     <span class="item-count">300+ ofertas</span>
                </a>
                 <a href="#" class="explore-item category-item">
                    <div class="item-icon"><i class="fas fa-paint-brush"></i></div>
                    <div class="item-text">Diseño y Arte</div>
                     <span class="item-count">250+ ofertas</span>
                </a>
                 <a href="#" class="explore-item category-item">
                    <div class="item-icon"><i class="fas fa-coins"></i></div>
                    <div class="item-text">Finanzas y Contabilidad</div>
                     <span class="item-count">550+ ofertas</span>
                </a>
                 <a href="#" class="explore-item category-item">
                    <div class="item-icon"><i class="fas fa-utensils"></i></div>
                    <div class="item-text">Hostelería y Turismo</div>
                     <span class="item-count">700+ ofertas</span>
                </a>
                </div>
        </section>

        <section class="explore-section">
            <h2>Explorar por Ubicación</h2>
            <div class="location-list">
                 <a href="#" class="explore-item location-item">
                    <i class="fas fa-city"></i> Madrid
                     <span class="item-count">900+ ofertas</span>
                </a>
                 <a href="#" class="explore-item location-item">
                    <i class="fas fa-city"></i> Barcelona
                    <span class="item-count">850+ ofertas</span>
                </a>
                 <a href="#" class="explore-item location-item">
                    <i class="fas fa-city"></i> Valencia
                     <span class="item-count">400+ ofertas</span>
                </a>
                 <a href="#" class="explore-item location-item">
                    <i class="fas fa-city"></i> Sevilla
                     <span class="item-count">300+ ofertas</span>
                </a>
                 <a href="#" class="explore-item location-item location-remote">
                    <i class="fas fa-globe"></i> Remoto
                    <span class="item-count">2000+ ofertas</span>
                </a>
                </div>
        </section>

         <section class="explore-section">
            <h2>Empresas Destacadas</h2>
            <div class="company-list-expanded">
                 <a href="#" class="explore-item company-item">
                     <div class="company-logo-placeholder"></div>
                    <div class="item-text">Tech Dynamics</div>
                     <span class="item-count">50+ ofertas</span>
                </a>
                 <a href="#" class="explore-item company-item">
                     <div class="company-logo-placeholder"></div>
                    <div class="item-text">Global Corp</div>
                    <span class="item-count">75+ ofertas</span>
                </a>
                 <a href="#" class="explore-item company-item">
                    <div class="company-logo-placeholder"></div>
                    <div class="item-text">Innovate Agency</div>
                    <span class="item-count">30+ ofertas</span>
                </a>
                <a href="#" class="explore-item company-item">
                    <div class="company-logo-placeholder"></div>
                    <div class="item-text">Eco Solutions</div>
                    <span class="item-count">20+ ofertas</span>
                </a>
                 <a href="#" class="explore-item company-item">
                    <div class="company-logo-placeholder"></div>
                    <div class="item-text">Future Builders</div>
                    <span class="item-count">45+ ofertas</span>
                </a>
                 <a href="#" class="explore-item company-item">
                    <div class="company-logo-placeholder"></div>
                    <div class="item-text">Health Partners</div>
                    <span class="item-count">15+ ofertas</span>
                </a>
                 </div>
        </section>

        <footer>
            <a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
        </footer>
    </main>

    <script src="js/barraLateral.js" defer></script>
    <script src="js/desplegablePerfil.js" defer></script>
    <script src="js/interaccionesInicio.js" defer></script>
</body>
</html>

Explicación del código: Explorar.html – EmpleoConnect HTML: Secciones de Categorías, Ubicaciones y Empresas Destacadas

<!DOCTYPE html>
Declara que el documento usa HTML5, activando el modo estándar de los navegadores.

<html lang="es">
Elemento raíz con atributo lang="es", indicando que el contenido está en español.

<head>
Comienza la sección de metadatos y recursos (no visible directamente).

<meta charset="UTF-8"/>
Define la codificación de caracteres como UTF-8, soportando caracteres especiales y acentos.

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
Ajusta la escala y ancho de la página al dispositivo, esencial para diseño responsive.

<title>Explorar - EmpleoConnect</title>
Título que aparece en la pestaña del navegador y en marcadores.

<link rel="stylesheet" href="css/theme.css">
Importa estilos de tema global (colores, variables, tipografías).

<link rel="stylesheet" href="css/base.css">
Carga estilos base: reset de CSS, tipografías y utilidades.

<link rel="stylesheet" href="css/layout.css">
Define la arquitectura de contenedores y grillas globales.

<link rel="stylesheet" href="css/state.css">
Incluye clases de estado (activo, hover, disabled).

<link rel="stylesheet" href="css/modules/sidebar.css">
Estilos para el componente de barra lateral.

<link rel="stylesheet" href="css/modules/logo.css">
Diseño del bloque de logo dentro del sidebar.

<link rel="stylesheet" href="css/modules/navigation.css">
Estilos del menú de navegación que contiene enlaces.

<link rel="stylesheet" href="css/modules/profile-dropdown.css">
Diseño del menú desplegable de perfil de usuario.

<link rel="stylesheet" href="css/modules/sidebar-toggle.css">
Estilos del botón que abre o cierra el sidebar en móvil.

<link rel="stylesheet" href="css/modules/offer-card.css">
Estilos de las tarjetas de ofertas (aunque aquí no aparecen).

<link rel="stylesheet" href="css/pages/explorar.css">
Reglas específicas para esta página de “Explorar”.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
Carga Font Awesome para iconos vectoriales desde CDN.

</head>
Cierra la sección de metadatos.

<body class="sidebar-visible">
Comienza el contenido visible y aplica la clase que muestra la barra lateral por defecto.

<button class="sidebar-toggle" id="sidebarToggle">
Botón para alternar la visibilidad del sidebar en pantallas pequeñas.

<svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
Icono “hamburguesa” en SVG dentro del botón.

</button>
Cierra el botón de toggle.

<aside class="sidebar" id="sidebar">
Inicia el elemento semántico de la barra lateral.

<div>
Contenedor interno para agrupar todo el contenido del sidebar.

<div class="logo">
Bloque que muestra el icono y nombre de la app.

<svg viewBox="0 0 24 24">…</svg>
SVG con forma de edificio o caja, símbolo del logo.

EmpleoConnect
Texto con el nombre de la plataforma junto al SVG.

</div>
Cierra el bloque logo.

<div class="category-label">Navegar</div>
Etiqueta que separa la sección de navegación principal.

<ul class="nav-menu">
Lista no ordenada que contiene los enlaces de navegación.

<li class="nav-item">…Inicio…</li>
Ítem de menú “Inicio” con su icono y texto.

<li class="nav-item">…Ofertas…</li>
Ítem de menú “Ofertas” con su icono.

<li class="nav-item active">…Explorar…</li>
Ítem “Explorar” marcado como activo (clase .active).

<li class="nav-item">…Notificaciones…</li>
Ítem de menú “Notificaciones”.

<li class="nav-item employee-mode" id="employeeModeBtn">…Modo Empleado…</li>
Ítem para cambiar al modo empleado, con icono y texto.

</ul>
Cierra la lista nav-menu.

<div class="category-label">Empresas</div>
Segunda sección del sidebar, etiquetada “Empresas”.

<ul class="nav-menu">
Lista de enlaces relacionados con empresas.

<li class="nav-item">…Destacadas…</li>
Ítem “Destacadas” con icono.

<li class="nav-item">…Buscar…</li>
Ítem “Buscar” con icono.

</ul>
Cierra la lista de empresas.

</div>
Cierra el contenedor principal del sidebar.

<div class="profile" id="profileBtn">
Sección de perfil de usuario al pie del sidebar.

<div class="profile-info">
Grupo con avatar, nombre y estado del usuario.

<div class="profile-icon"><svg>…</svg></div>
SVG con icono de usuario.

<div>
Contenedor de texto de perfil.

<div class="username">Usuario</div>
Muestra el nombre de usuario.

<div class="status"><span class="status-indicator"></span><span>En línea</span></div>
Indicador de estado (punto) y texto “En línea”.

</div>
Cierra el contenedor de texto.

</div>
Cierra profile-info.

<ul class="nav-menu profile-links" id="profileLinks">
Lista de enlaces específicos del perfil.

<li class="nav-item"><span>Editar Perfil</span></li>
Opción “Editar Perfil”.

<li class="nav-item"><span>Postulaciones</span></li>
Opción “Postulaciones”.

<li class="nav-item"><span>Notificaciones</span></li>
Opción “Notificaciones”.

<li class="nav-item logout"><span>Cerrar sesión</span></li>
Opción “Cerrar sesión”, con clase logout.

</ul>
Cierra la lista de perfil.

</div>
Cierra la sección profile.

</aside>
Finaliza el elemento aside del sidebar.

<main>
Inicia el contenido principal de la página.

<section class="explore-header">
Sección de encabezado para “Explorar”.

<h1>Explora Oportunidades en EmpleoConnect</h1>
Título principal de la página.

<p>Descubre empleos, empresas y sectores…</p>
Breve descripción introductoria.

</section>
Cierra la sección de encabezado.

<section class="explore-section">
Primera sección de exploración: categorías.

<h2>Explorar por Categoría</h2>
Subtítulo de la sección.

<div class="category-grid">
Contenedor en cuadrícula para los ítems de categoría.

<a href="#" class="explore-item category-item">…IT y Desarrollo…</a>
Primer enlace de categoría con icono, texto y contador.

<a href="#" class="explore-item category-item">…Ventas y Comercial…</a>
Segunda categoría.

<a href="#" class="explore-item category-item">…Ingeniería…</a>
Tercera categoría.

(Seis enlaces más similares para otras categorías)

</div>
Cierra la cuadrícula de categorías.

</section>
Finaliza la sección de categorías.

<section class="explore-section">
Segunda sección de exploración: ubicaciones.

<h2>Explorar por Ubicación</h2>
Subtítulo.

<div class="location-list">
Contenedor de enlaces de ubicación.

<a href="#" class="explore-item location-item">…Madrid…</a>
Enlace “Madrid” con icono y contador.

<a href="#" class="explore-item location-item">…Barcelona…</a>
Enlace “Barcelona”.

(Tres enlaces más para otras ubicaciones y “Remoto”)

</div>
Cierra la lista de ubicaciones.

</section>
Finaliza la sección de ubicaciones.

<section class="explore-section">
Tercera sección de exploración: empresas destacadas.

<h2>Empresas Destacadas</h2>
Subtítulo.

<div class="company-list-expanded">
Contenedor de enlaces de empresas.

<a href="#" class="explore-item company-item">…Tech Dynamics…</a>
Enlace de empresa con placeholder de logo y contador.

(Cinco enlaces más para otras empresas)

</div>
Cierra el contenedor de empresas.

</section>
Finaliza la sección de empresas.

<footer>
Inicia el pie de página.

<a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
Enlaces legales y de información.

</footer>
Cierra el pie de página.

</main>
Finaliza el contenido principal.

<script src="js/barraLateral.js" defer></script>
Importa y difiere el script que controla la barra lateral.

<script src="js/desplegablePerfil.js" defer></script>
Importa y difiere el script del menú desplegable de perfil.

<script src="js/interaccionesInicio.js" defer></script>
Importa y difiere las interacciones específicas de la página de Exploración.

</body>
Cierra el cuerpo del documento.

</html>
Cierra el elemento raíz y termina el documento.

explorar.css

Este archivo define los estilos específicos de la página Explorar: gestiona el padding y separación de secciones en main, da formato a la cabecera con fondo suave y texto centrado, establece grids fluidos para categorías y empresas, y lista de ubicaciones en flex-wrap; diseña los elementos .explore-item con fondo blanco, sombras y efectos hover, y ajusta sus variantes (category-item, location-item, company-item) para mostrar iconos, texto y contadores de forma clara; además incorpora media queries para adaptar tamaños de fuente y layouts a pantallas de tablet y móvil.

explorar.css – Estilos de Página Explorar: Grid de Categorías, Ubicaciones y Empresas

/* css/pages/explorar.css */

main {
    padding: var(--gap);
    display: flex;
    flex-direction: column;
    gap: calc(var(--gap) * 1.5);
}

.explore-header {
    background: var(--gray-100);
    padding: calc(var(--gap) * 1.5) var(--gap);
    text-align: center;
    margin-bottom: var(--gap);
    border-radius: .5rem;
}

.explore-header h1 {
    margin-bottom: .5rem;
    font-size: 2rem;
    color: var(--dark);
}

.explore-header p {
    font-size: 1.1rem;
    color: var(--gray-300);
    margin: 0;
}

.explore-section {
    margin-bottom: calc(var(--gap) * 1.5);
}

.explore-section h2 {
    font-size: 1.5rem;
    margin-bottom: var(--gap);
    color: var(--dark);
    border-bottom: 2px solid var(--primary);
    display: inline-block;
    padding-bottom: .25rem;
}

.category-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--gap);
}

.location-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap);
    list-style: none;
    padding: 0;
}

.company-list-expanded {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--gap);
}

.explore-item {
    display: flex;
    align-items: center;
    background: #fff;
    padding: var(--gap);
    border-radius: .5rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
    text-decoration: none;
    color: var(--dark);
    transition: transform .2s ease, box-shadow .2s ease, background .2s ease;
    cursor: pointer;
}

.explore-item:hover {
    transform: translateY(-3px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, .1);
    background: var(--gray-50);
}

.explore-item .item-icon {
    font-size: 1.5rem;
    color: var(--primary);
    margin-right: var(--gap);
    flex-shrink: 0;
}

.explore-item .item-text {
     flex-grow: 1;
     font-weight: 600;
     font-size: 1.1rem;
}

.explore-item .item-count {
    font-size: .9rem;
    color: var(--gray-400);
    flex-shrink: 0;
}

.category-item {
    flex-direction: column;
    text-align: center;
    justify-content: center;
}

.category-item .item-icon {
    margin-right: 0;
    margin-bottom: .5rem;
}

.category-item .item-text {
    font-size: 1rem;
    margin-bottom: .25rem;
}

.location-item {
    gap: .5rem;
    justify-content: space-between;
     padding: .75rem var(--gap);
     flex-grow: 1;
     max-width: 250px;
}

.location-item i {
    color: var(--primary);
    font-size: 1.1rem;
    flex-shrink: 0;
}

.location-item .item-count {
    margin-left: .5rem;
}

.location-item.location-remote {
    background: var(--secondary);
    color: #fff;
}

.location-item.location-remote i {
    color: #fff;
}

.location-item.location-remote .item-count {
     color: rgba(255, 255, 255, 0.8);
}

.company-item {
    gap: .75rem;
     justify-content: flex-start;
}

.company-logo-placeholder {
    width: 40px;
    height: 40px;
    background: var(--gray-200);
    border-radius: .3rem;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--gray-500);
    font-size: .8rem;
}

@media (max-width: 768px) {
    .explore-header h1 {
        font-size: 1.8rem;
    }

    .explore-section h2 {
        font-size: 1.3rem;
    }

    .category-grid {
        grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    }

    .explore-item .item-icon {
        font-size: 1.3rem;
    }

    .explore-item .item-text {
        font-size: 1rem;
    }

     .location-list {
          flex-direction: column;
          gap: .75rem;
     }

     .location-item {
          max-width: 100%;
     }
}

@media (max-width: 480px) {
    .explore-header h1 {
        font-size: 1.6rem;
    }

     .explore-header p {
        font-size: 1rem;
    }

    .explore-section h2 {
        font-size: 1.2rem;
    }

     .category-grid {
        grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
     }

    .explore-item {
        padding: .8rem;
    }

    .explore-item .item-icon {
        font-size: 1.1rem;
        margin-right: .5rem;
    }

    .explore-item .item-text {
        font-size: .9rem;
    }

    .category-item .item-icon {
        margin-bottom: .3rem;
    }
    .category-item .item-text {
         font-size: .95rem;
         margin-bottom: .15rem;
    }

    .explore-item .item-count {
        font-size: .8rem;
    }

     .location-item {
          padding: .6rem var(--gap);
     }

     .company-logo-placeholder {
          width: 35px;
          height: 35px;
     }
}

Explicación del código: explorar.css – Estilos de Página Explorar: Grid de Categorías, Ubicaciones y Empresas

/* css/pages/explorar.css */
Comentario que indica el archivo CSS al que pertenecen estas reglas: explorar.css.

main {
Inicia la regla para el elemento <main>.

padding: var(--gap);
Aplica un relleno interior en todos sus lados igual al valor de la variable --gap.

display: flex;
Convierte <main> en contenedor flexbox.

flex-direction: column;
Organiza sus hijos en columna (vertical).

gap: calc(var(--gap) * 1.5);
Deja un espacio vertical entre cada sección hijo de 1.5 veces --gap.

}

.explore-header {
Regla para el bloque de cabecera de la página de explorar.

background: var(--gray-100);
Fondo gris claro según variable.

padding: calc(var(--gap) * 1.5) var(--gap);
Relleno vertical de 1.5×--gap y horizontal de --gap.

text-align: center;
Centra el texto dentro del bloque.

margin-bottom: var(--gap);
Separa la cabecera de la sección siguiente con --gap.

border-radius: .5rem;
Redondea las esquinas con radio 0.5 rem.

}

.explore-header h1 {
Estilos para el título principal dentro de la cabecera.

margin-bottom: .5rem;
Espacio inferior de 0.5 rem tras el título.

font-size: 2rem;
Tamaño de fuente de 2 rem.

color: var(--dark);
Color de texto oscuro según variable.

}

.explore-header p {
Regla para el párrafo descriptivo de la cabecera.

font-size: 1.1rem;
Tamaño de texto de 1.1 rem.

color: var(--gray-300);
Texto en gris medio.

margin: 0;
Elimina márgenes por defecto.

}

.explore-section {
Regla para cada sección de exploración.

margin-bottom: calc(var(--gap) * 1.5);
Espacio inferior de 1.5×--gap.

}

.explore-section h2 {
Estilos para el subtítulo <h2> de cada sección.

font-size: 1.5rem;
Fuente de tamaño 1.5 rem.

margin-bottom: var(--gap);
Espacio inferior de --gap.

color: var(--dark);
Texto en color oscuro.

border-bottom: 2px solid var(--primary);
Línea inferior de 2 px con color primario.

display: inline-block;
Hace que sólo ocupe el ancho de su contenido.

padding-bottom: .25rem;
Relleno inferior de 0.25 rem para separar el texto de la línea.

}

.category-grid {
Contenedor de cuadrícula para ítems de categoría.

display: grid;
Activa el modelo de cuadrícula CSS.

grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
Crea tantas columnas de al menos 180 px como quepan, distribuyendo el espacio restante de forma equitativa.

gap: var(--gap);
Espacio entre filas y columnas igual a --gap.

}

.location-list {
Contenedor para la lista de ubicaciones.

display: flex;
Flexbox en fila.

flex-wrap: wrap;
Permite que los ítems pasen a siguiente línea si no caben.

gap: var(--gap);
Separación entre ítems.

list-style: none;
Elimina viñetas por defecto (aunque no es <ul> propiamente).

padding: 0;
Elimina relleno interno.

}

.company-list-expanded {
Contenedor de cuadrícula para empresas.

display: grid;
Modelo de cuadrícula CSS.

grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
Columnas de al menos 200 px, adaptables.

gap: var(--gap);
Espacio uniforme entre elementos.

}

.explore-item {
Regla común para cada ítem de exploración (categoría, ubicación o empresa).

display: flex; align-items: center;
Flexbox en fila, centrando verticalmente.

background: #fff;
Fondo blanco.

padding: var(--gap);
Relleno interior de --gap.

border-radius: .5rem;
Esquinas redondeadas.

box-shadow: 0 2px 8px rgba(0,0,0,.05);
Sombra suave para elevar el bloque.

text-decoration: none;
Elimina subrayado en enlaces.

color: var(--dark);
Texto en color oscuro.

transition: transform .2s ease, box-shadow .2s ease, background .2s ease;
Anima suavemente transformaciones, sombra y fondo al hover.

cursor: pointer;
Muestra cursor de mano para indicar interactividad.

}

.explore-item:hover {
Estado hover de cada ítem.

transform: translateY(-3px);
Eleva ligeramente el bloque.

box-shadow: 0 4px 12px rgba(0,0,0,.1);
Aumenta la sombra para mayor énfasis.

background: var(--gray-50);
Cambia el fondo a un gris muy claro.

}

.explore-item .item-icon {
Regla para el contenedor del icono dentro de cada ítem.

font-size: 1.5rem; color: var(--primary);
Icono grande con color primario.

margin-right: var(--gap);
Espacio a la derecha entre el icono y el texto.

flex-shrink: 0;
Impide que el icono se reduzca al faltarle espacio.

}

.explore-item .item-text {
Regla para el texto principal de cada ítem.

flex-grow: 1;
Permite que el texto ocupe el espacio restante.

font-weight: 600; font-size: 1.1rem;
Seminegrita y tamaño de 1.1 rem.

}

.explore-item .item-count {
Regla para el contador de ofertas dentro del ítem.

font-size: .9rem; color: var(--gray-400);
Texto pequeño y gris claro.

flex-shrink: 0;
Impide que el contador se reduzca.

}

.category-item {
Variante de .explore-item para categorías.

flex-direction: column;
Organiza icono, texto y contador en columna.

text-align: center; justify-content: center;
Centra todo el contenido.

}

.category-item .item-icon {
Ajuste para el icono en categorías.

margin-right: 0; margin-bottom: .5rem;
Elimina margen derecho y añade espacio inferior.

}

.category-item .item-text {
Ajuste para el texto en categorías.

font-size: 1rem; margin-bottom: .25rem;
Tamaño más pequeño y espacio inferior.

}

.location-item {
Variante para ítems de ubicación.

gap: .5rem; justify-content: space-between;
Separa icono y contador equitativamente.

padding: .75rem var(--gap);
Relleno vertical de 0.75 rem y horizontal de --gap.

flex-grow: 1; max-width: 250px;
Ocupa espacio disponible pero no supera 250 px de ancho.

}

.location-item i {
Ajustes para el icono en ubicación.

color: var(--primary); font-size: 1.1rem; flex-shrink: 0;
Color primario, tamaño 1.1 rem y no se reduce.

}

.location-item .item-count {
Ajuste para el contador en ubicación.

margin-left: .5rem;
Espacio a la izquierda para separarlo del texto.

}

.location-item.location-remote {
Variante especial para la opción “Remoto”.

background: var(--secondary); color: #fff;
Fondo con color secundario y texto blanco.

}

.location-item.location-remote i {
Icono en la opción “Remoto”.

color: #fff;
Cambia el color del icono a blanco.

}

.location-item.location-remote .item-count {
Contador en opción “Remoto”.

color: rgba(255,255,255,0.8);
Blanco semitransparente.

}

.company-item {
Variante para ítems de empresa.

gap: .75rem; justify-content: flex-start;
Espacio de 0.75 rem entre logo y texto, alineados al inicio.

}

.company-logo-placeholder {
Marcador de posición para el logo de empresa.

width: 40px; height: 40px;
Cuadrado de 40×40 px.

background: var(--gray-200); border-radius: .3rem;
Fondo gris medio y esquinas ligeramente redondeadas.

flex-shrink: 0; display: flex; align-items: center; justify-content: center;
No se reduce y centra contenido (p.ej. iniciales).

color: var(--gray-500); font-size: .8rem;
Texto gris claro y tamaño pequeño.

}

@media (max-width: 768px) {
Comienza reglas para pantallas de hasta 768 px.

.explore-header h1 { font-size: 1.8rem; }
Reduce el tamaño del título.

.explore-section h2 { font-size: 1.3rem; }
Reduce el subtítulo de sección.

.category-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
Reduce el ancho mínimo de cada columna a 150 px.

.explore-item .item-icon { font-size: 1.3rem; }
Hace los iconos ligeramente más pequeños.

.explore-item .item-text { font-size: 1rem; }
Ajusta el tamaño del texto principal.

.location-list { flex-direction: column; gap: .75rem; }
Apila las ubicaciones en columna.

.location-item { max-width: 100%; }
Permite que ocupen todo el ancho disponible.

}

@media (max-width: 480px) {
Comienza reglas para pantallas de hasta 480 px.

.explore-header h1 { font-size: 1.6rem; }
Reduce aún más el título.

.explore-header p { font-size: 1rem; }
Ajusta el párrafo descriptivo.

.explore-section h2 { font-size: 1.2rem; }
Ajusta el subtítulo de sección.

.category-grid { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); }
Mínimo de columna de 130 px para móviles.

.explore-item { padding: .8rem; }
Reduce el relleno interior de cada ítem.

.explore-item .item-icon { font-size: 1.1rem; margin-right: .5rem; }
Hace iconos y separación más compactos.

.explore-item .item-text { font-size: .9rem; }
Ajusta el tamaño de texto principal.

.category-item .item-icon { margin-bottom: .3rem; }
Reduce el espacio inferior del icono en categorías.

.category-item .item-text { font-size: .95rem; margin-bottom: .15rem; }
Ajusta fuente y margen inferior del texto en categorías.

.explore-item .item-count { font-size: .8rem; }
Texto del contador más pequeño.

.location-item { padding: .6rem var(--gap); }
Ajusta relleno vertical y lateral en ubicaciones.

.company-logo-placeholder { width: 35px; height: 35px; }
Reduce el tamaño del placeholder de logo.

}

notificaciones.html

Este archivo define la página de Notificaciones para empleados: el aside muestra la barra lateral con “Notificaciones” activa, y en el main se incluyen la cabecera con título y subtítulo, seguida de una lista de ítems de notificación que muestran icono, título, descripción con estado, timestamp y acciones vinculadas a cada notificación.

notificaciones.html – Notificaciones Empleado – EmpleoConnect HTML: Cabecera y Lista de Notificaciones

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Notificaciones - Empleado | EmpleoConnect</title>
    <link rel="stylesheet" href="css/theme.css">
    <link rel="stylesheet" href="css/base.css">
    <link rel="stylesheet" href="css/layout.css">
    <link rel="stylesheet" href="css/state.css">
    <link rel="stylesheet" href="css/modules/sidebar.css">
    <link rel="stylesheet" href="css/modules/logo.css">
    <link rel="stylesheet" href="css/modules/navigation.css">
    <link rel="stylesheet" href="css/modules/profile-dropdown.css">
    <link rel="stylesheet" href="css/modules/sidebar-toggle.css">
    <link rel="stylesheet" href="css/pages/notificaciones-empleado.css">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">

</head>
<body class="sidebar-visible">
    <button class="sidebar-toggle" id="sidebarToggle">
        <svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
    </button>

    <aside class="sidebar" id="sidebar">
        <div>
            <div class="logo">
                <svg viewBox="0 0 24 24"><path d="M20 7h-4V3c0-1.1-.9-2-2-2h-4c-1.1 0-2 .9-2 2v4H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2z"/><path d="M11 14h2v4h-2zM7 14h2v4H7zM15 14h2v4h-2z"/></svg>
                EmpleoConnect
            </div>
            <div class="category-label">Navegar</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V9z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
                    <span>Inicio</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/></svg>
                    <span>Ofertas</span>
                </li>
                 <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg>
                    <span>Explorar</span>
                </li>
                <li class="nav-item active">
                    <svg viewBox="0 0 24 24"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
                    <span>Notificaciones</span>
                </li>
                 <li class="nav-item employee-mode" id="employeeModeBtn">
                    <svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg>
                    <span class="mode-text">Modo Empleado</span>
                </li>
            </ul>
            <div class="category-label">Empresas</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M3 21h18M9 8h1M9 12h1M9 16h1M15 8h1M15 12h1M15 16h1M7 21V5a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v16"/></svg>
                    <span>Destacadas</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M4 21v-2a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
                    <span>Buscar</span>
                </li>
            </ul>
        </div>
        <div class="profile" id="profileBtn">
            <div class="profile-info">
                <div class="profile-icon"><svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg></div>
                <div>
                    <div class="username">Usuario Empleado</div> <div class="status"><span class="status-indicator"></span><span>En línea</span></div>
                </div>
            </div>
            <ul class="nav-menu profile-links" id="profileLinks">
                <li class="nav-item"><span>Editar Perfil</span></li>
                <li class="nav-item"><span>Postulaciones</span></li>
                <li class="nav-item"><span>Configuración</span></li> <li class="nav-item logout"><span>Cerrar sesión</span></li>
            </ul>
        </div>
    </aside>

    <main>
        <section class="notifications-header">
            <h1>Mis Notificaciones</h1>
            <p>Mantente al día con tus postulaciones, mensajes y alertas personalizadas.</p>
        </section>

        <section class="notifications-list-container">
            <div class="notification-item application-update">
                 <div class="notification-icon"><i class="fas fa-check-circle"></i></div>
                 <div class="notification-content">
                     <div class="notification-title">Actualización de Postulación</div>
                     <p class="notification-text">Tu postulación para <strong>Desarrollador/a Frontend Senior</strong> en <strong>Innovate Solutions</strong> ha sido marcada como <span class="status-success">Revisada</span>.</p>
                     <span class="notification-timestamp"><i class="far fa-clock"></i> Hace 2 horas</span>
                 </div>
                 <a href="#" class="notification-action">Ver Postulación</a>
            </div>

             <div class="notification-item new-message">
                 <div class="notification-icon"><i class="fas fa-envelope"></i></div>
                 <div class="notification-content">
                     <div class="notification-title">Nuevo Mensaje</div>
                     <p class="notification-text">Has recibido un nuevo mensaje de <strong>Global Sales Corp</strong> sobre tu interés en la oferta de Ejecutivo/a de Ventas B2B.</p>
                     <span class="notification-timestamp"><i class="far fa-clock"></i> Ayer, 14:30</span>
                 </div>
                 <a href="#" class="notification-action">Leer Mensaje</a>
            </div>

             <div class="notification-item job-alert">
                 <div class="notification-icon"><i class="fas fa-briefcase"></i></div>
                 <div class="notification-content">
                     <div class="notification-title">Nueva Oferta Recomendada</div>
                     <p class="notification-text">¡Tenemos una nueva oferta para ti! <strong>Ingeniero/a de Datos</strong> en <strong>Data Insights SL</strong> coincide con tus preferencias.</p>
                     <span class="notification-timestamp"><i class="far fa-clock"></i> 23 de Abril, 09:00</span>
                 </div>
                 <a href="#" class="notification-action">Ver Oferta</a>
            </div>

             <div class="notification-item application-update">
                 <div class="notification-icon"><i class="fas fa-hourglass-half"></i></div>
                 <div class="notification-content">
                     <div class="notification-title">Actualización de Postulación</div>
                     <p class="notification-text">Tu postulación para <strong>Diseñador/a Gráfico Junior</strong> en <strong>Creative Studio Valencia</strong> está actualmente <span class="status-info">En Proceso de Selección</span>.</p>
                     <span class="notification-timestamp"><i class="far fa-clock"></i> 20 de Abril, 11:00</span>
                 </div>
                 <a href="#" class="notification-action">Ver Postulación</a>
            </div>

             </section>

        <footer>
            <a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
        </footer>
    </main>

    <script src="js/barraLateral.js" defer></script>
    <script src="js/desplegablePerfil.js" defer></script>
    <script src="js/interaccionesInicio.js" defer></script>
</body>
</html>

Explicación del código: notificaciones.html – Notificaciones Empleado – EmpleoConnect HTML: Cabecera y Lista de Notificaciones

<!DOCTYPE html>
Declara el documento como HTML5, asegurando el modo de renderizado estándar.

<html lang="es">
Elemento raíz indicando que el contenido está en español.

<head>
Inicio de la sección de metadatos y enlaces a estilos.

<meta charset="UTF-8"/>
Define la codificación de caracteres en UTF-8, soportando tildes y símbolos.

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
Ajusta el ancho y escala de la página para dispositivos móviles.

<title>Notificaciones - Empleado | EmpleoConnect</title>
Título que aparece en la pestaña del navegador.

<link rel="stylesheet" href="css/theme.css">
Importa los estilos de tema global (colores y variables).

<link rel="stylesheet" href="css/base.css">
Carga estilos base (reset, tipografías, utilidades).

<link rel="stylesheet" href="css/layout.css">
Define la disposición general de contenedores y grillas.

<link rel="stylesheet" href="css/state.css">
Clases de estado (activo, hover, deshabilitado).

<link rel="stylesheet" href="css/modules/sidebar.css">
Estilos para la barra lateral.

<link rel="stylesheet" href="css/modules/logo.css">
Diseño del bloque de logo en el sidebar.

<link rel="stylesheet" href="css/modules/navigation.css">
Estilos del menú de navegación.

<link rel="stylesheet" href="css/modules/profile-dropdown.css">
Diseño del menú desplegable de perfil.

<link rel="stylesheet" href="css/modules/sidebar-toggle.css">
Estilos del botón para alternar el sidebar.

<link rel="stylesheet" href="css/pages/notificaciones-empleado.css">
Reglas específicas de la página de notificaciones para empleados.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
Carga de Font Awesome para iconos.

</head>
Fin de los metadatos.

<body class="sidebar-visible">
Inicio del contenido visible, con clase que mantiene el sidebar abierto.

<button class="sidebar-toggle" id="sidebarToggle">
Botón para mostrar/ocultar la barra lateral en móviles.

<svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
Icono “hamburguesa” en SVG.

</button>
Cierra el botón de toggle.

<aside class="sidebar" id="sidebar">
Elemento semántico que contiene la barra lateral.

<div>
Contenedor de agrupación interna.

<div class="logo">
Sección del logo y nombre de la app.

<svg viewBox="0 0 24 24">…</svg>
SVG representando el logo.

EmpleoConnect
Texto del nombre junto al logo.

</div>
Cierra el bloque de logo.

<div class="category-label">Navegar</div>
Etiqueta para separar la sección de navegación.

<ul class="nav-menu">
Lista de elementos de navegación.

<li class="nav-item">Inicio</li>
Ítem “Inicio” con su icono.

<li class="nav-item">Ofertas</li>
Ítem “Ofertas”.

<li class="nav-item">Explorar</li>
Ítem “Explorar”.

<li class="nav-item active">Notificaciones</li>
Ítem “Notificaciones”, marcado como activo.

<li class="nav-item employee-mode" id="employeeModeBtn">Modo Empleado</li>
Opción para alternar modo empleado.

</ul>
Cierra la lista principal.

<div class="category-label">Empresas</div>
Etiqueta de la sección de empresas.

<ul class="nav-menu">
Lista de enlaces de empresas.

<li class="nav-item">Destacadas</li>
Ítem “Destacadas”.

<li class="nav-item">Buscar</li>
Ítem “Buscar”.

</ul>
Cierra la lista de empresas.

</div>
Cierra el contenedor interno del sidebar.

<div class="profile" id="profileBtn">
Sección de perfil en la parte inferior del sidebar.

<div class="profile-info">
Contenedor con avatar y texto de perfil.

<div class="profile-icon"><svg>…</svg></div>
SVG con icono de usuario.

<div>
Contenedor de nombre y estado.

<div class="username">Usuario Empleado</div>
Muestra el nombre del usuario.

<div class="status"><span class="status-indicator"></span><span>En línea</span></div>
Indicador de estado y texto “En línea”.

</div>
Cierra el contenedor de texto.

</div>
Cierra profile-info.

<ul class="nav-menu profile-links" id="profileLinks">
Lista de enlaces secundarios de perfil.

<li class="nav-item">Editar Perfil</li>
Opción “Editar Perfil”.

<li class="nav-item">Postulaciones</li>
Opción “Postulaciones”.

<li class="nav-item">Configuración</li>
Opción “Configuración”.

<li class="nav-item logout">Cerrar sesión</li>
Opción “Cerrar sesión” para salir de la cuenta.

</ul>
Cierra la lista de perfil.

</div>
Cierra la sección profile.

</aside>
Finaliza el elemento aside de la barra lateral.

<main>
Inicia el contenido principal de la página.

<section class="notifications-header">
Sección de encabezado para notificaciones.

<h1>Mis Notificaciones</h1>
Título de la sección.

<p>Mantente al día con tus postulaciones, mensajes y alertas personalizadas.</p>
Descripción introductoria.

</section>
Cierra la sección de encabezado.

<section class="notifications-list-container">
Contenedor de la lista de notificaciones.

<div class="notification-item application-update">
Primera notificación de tipo “actualización de postulación”.

<div class="notification-icon"><i class="fas fa-check-circle"></i></div>
Icono que indica éxito/revisión.

<div class="notification-content">
Contenedor del texto de la notificación.

<div class="notification-title">Actualización de Postulación</div>
Título de la notificación.

<p class="notification-text">…ha sido marcada como <span class="status-success">Revisada</span>.</p>
Detalle con estado resaltado.

<span class="notification-timestamp"><i class="far fa-clock"></i> Hace 2 horas</span>
Marca temporal con icono de reloj.

</div>
Cierra el contenido de la notificación.

<a href="#" class="notification-action">Ver Postulación</a>
Enlace a la acción correspondiente.

</div>
Cierra el primer ítem de notificación.

<div class="notification-item new-message">
Segunda notificación de tipo “nuevo mensaje”.

<div class="notification-icon"><i class="fas fa-envelope"></i></div>
Icono de sobre.

<div class="notification-content">…</div>
Contenido con título, texto “Has recibido un nuevo mensaje…” y timestamp “Ayer, 14:30”.

<a href="#" class="notification-action">Leer Mensaje</a>
Acción para leer el mensaje.

</div>
Cierra el segundo ítem.

<div class="notification-item job-alert">
Tercera notificación de tipo “alerta de empleo”.

<div class="notification-icon"><i class="fas fa-briefcase"></i></div>
Icono de maletín.

<div class="notification-content">…</div>
Contenido que anuncia una nueva oferta recomendada y fecha “23 de Abril, 09:00”.

<a href="#" class="notification-action">Ver Oferta</a>
Enlace a la oferta.

</div>
Cierra el tercer ítem.

<div class="notification-item application-update">
Cuarta notificación de actualización de postulación.

<div class="notification-icon"><i class="fas fa-hourglass-half"></i></div>
Icono de reloj de arena.

<div class="notification-content">…</div>
Contenido indicando estado “En Proceso de Selección” y fecha “20 de Abril, 11:00”.

<a href="#" class="notification-action">Ver Postulación</a>
Acción correspondiente.

</div>
Cierra el cuarto ítem.

</section>
Finaliza la sección de lista de notificaciones.

<footer>
Inicia el pie de página.

<a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
Enlaces legales e informativos.

</footer>
Cierra el pie de página.

</main>
Finaliza el contenido principal.

<script src="js/barraLateral.js" defer></script>
Script diferido para controlar la barra lateral.

<script src="js/desplegablePerfil.js" defer></script>
Script diferido para el menú de perfil.

<script src="js/interaccionesInicio.js" defer></script>
Script diferido con interacciones específicas de la página.

</body>
Cierra el cuerpo del documento.

</html>
Cierra el elemento raíz y finaliza el HTML.

notificaciones-empleado.css

Este archivo establece los estilos de la página de notificaciones para empleados: define el padding y separación vertical de main, formatea la cabecera con fondo claro y texto centrado, diseña la lista de notificaciones con tarjetas flexibles, sombras, bordes de color según tipo (actualización, mensaje, alerta) y efectos hover; además incluye estilos para el estado vacío y media queries que ajustan la disposición, tamaños de fuente y padding en tabletas y móviles.

notificaciones-empleado.css – Notificaciones Empleado: Estilos de Lista, Estados Vacíos y Responsividad

/* css/pages/notificaciones-empleado.css */

main {
    padding: var(--gap);
    display: flex;
    flex-direction: column;
    gap: calc(var(--gap) * 1.5);
}

.notifications-header {
    background: var(--gray-100);
    padding: calc(var(--gap) * 1.5) var(--gap);
    text-align: center;
    margin-bottom: var(--gap);
    border-radius: .5rem;
}

.notifications-header h1 {
    margin-bottom: .5rem;
    font-size: 2rem;
    color: var(--dark);
}

.notifications-header p {
    font-size: 1.1rem;
    color: var(--gray-300);
    margin: 0;
}

.notifications-list-container {
    display: flex;
    flex-direction: column;
    gap: var(--gap);
}

.notification-item {
    background: #fff;
    padding: var(--gap);
    border-radius: .5rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
    display: flex;
    align-items: flex-start;
    gap: var(--gap);
    border-left: 5px solid var(--gray-200);
    transition: box-shadow .2s ease, transform .1s ease;
    cursor: pointer;
}

.notification-item:hover {
     box-shadow: 0 4px 12px rgba(0, 0, 0, .1);
     transform: translateY(-2px);
}

.notification-item.application-update {
    border-left-color: var(--info);
}

.notification-item.new-message {
    border-left-color: var(--success);
}

.notification-item.job-alert {
    border-left-color: var(--primary);
}

.notification-icon {
    font-size: 1.5rem;
    color: var(--gray-400);
    flex-shrink: 0;
    padding-top: .2rem;
}

.notification-item.application-update .notification-icon {
     color: var(--info);
}

.notification-item.new-message .notification-icon {
     color: var(--success);
}

.notification-item.job-alert .notification-icon {
     color: var(--primary);
}

.notification-content {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    gap: .3rem;
}

.notification-title {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--dark);
}

.notification-text {
    font-size: 1rem;
    color: var(--gray-600);
    margin: 0;
    line-height: 1.4;
}

.notification-text strong {
    color: var(--dark);
}

.notification-text .status-success {
    color: var(--success);
    font-weight: 600;
}
.notification-text .status-info {
    color: var(--info);
    font-weight: 600;
}

.notification-timestamp {
    font-size: .85rem;
    color: var(--gray-400);
    margin-top: .5rem;
    display: flex;
    align-items: center;
    gap: .3rem;
}

.notification-timestamp i {
     font-size: .9rem;
}

.notification-action {
    flex-shrink: 0;
    align-self: center;
    background: none;
    border: none;
    color: var(--primary);
    font-size: .95rem;
    font-weight: 600;
    text-decoration: none;
    padding: .5rem 1rem;
    border-radius: .3rem;
    transition: background .2s, color .2s;
}

.notification-item:hover .notification-action {
    background: var(--gray-100);
    color: var(--primary-dark);
}

.empty-state {
    text-align: center;
    padding: calc(var(--gap) * 2);
    background: #fff;
    border-radius: .5rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
    color: var(--gray-500);
}

.empty-state-icon {
    font-size: 3rem;
    color: var(--gray-300);
    margin-bottom: var(--gap);
}

.empty-state-text {
    font-size: 1.2rem;
    font-weight: 600;
    margin-bottom: .5rem;
    color: var(--dark);
}

.empty-state-subtext {
    font-size: 1rem;
    margin-bottom: calc(var(--gap) * 1.5);
}

.empty-state .btn-primary {
    display: inline-block;
    padding: .75rem 1.5rem;
    background: var(--primary);
    color: #fff;
    border-radius: .5rem;
    text-decoration: none;
    font-weight: 600;
    transition: background .2s;
}

.empty-state .btn-primary:hover {
    background: var(--primary-dark);
}

@media (max-width: 768px) {
    .notifications-header h1 {
        font-size: 1.8rem;
    }

    .notifications-header p {
        font-size: 1rem;
    }

    .notification-item {
        flex-direction: column;
        align-items: stretch;
        gap: .75rem;
    }

    .notification-icon {
        align-self: flex-start;
        padding-top: 0;
        font-size: 1.3rem;
    }

    .notification-title {
        font-size: 1rem;
    }

     .notification-text {
        font-size: .95rem;
     }

    .notification-action {
        align-self: flex-end;
        padding: .3rem .8rem;
        font-size: .9rem;
    }
}

@media (max-width: 480px) {
     .notifications-header h1 {
        font-size: 1.6rem;
    }
     .notification-item {
        padding: .8rem;
        gap: .5rem;
     }

    .notification-icon {
        font-size: 1.2rem;
    }

     .notification-title {
        font-size: .95rem;
    }

     .notification-text {
        font-size: .9rem;
     }

     .notification-timestamp {
        font-size: .8rem;
     }

     .notification-action {
        padding: .2rem .6rem;
        font-size: .85rem;
     }

     .empty-state {
          padding: calc(var(--gap) * 1.5);
     }
      .empty-state-icon {
        font-size: 2.5rem;
        margin-bottom: var(--gap);
    }

    .empty-state-text {
        font-size: 1.1rem;
    }

    .empty-state-subtext {
        font-size: .9rem;
    }

    .empty-state .btn-primary {
        padding: .6rem 1.2rem;
        font-size: .9rem;
    }
}

Explicación del código: notificaciones-empleado.css – Notificaciones Empleado: Estilos de Lista, Estados Vacíos y Responsividad

/* css/pages/notificaciones-empleado.css */
Comentario que indica que este bloque de reglas pertenece al archivo notificaciones-empleado.css.

main {
Inicia la regla para el elemento <main>.

padding: var(--gap);
Aplica un relleno interior en todos los lados igual al valor de la variable --gap.

display: flex;
Convierte <main> en un contenedor flexbox.

flex-direction: column;
Ordena sus elementos hijos en columna (de arriba abajo).

gap: calc(var(--gap) * 1.5);
Deja un espacio de 1.5×--gap entre cada elemento hijo.

}

.notifications-header {
Regla para el bloque de cabecera de notificaciones.

background: var(--gray-100);
Fondo gris claro según variable.

padding: calc(var(--gap) * 1.5) var(--gap);
Relleno vertical de 1.5×--gap y horizontal de --gap.

text-align: center;
Centra el texto en su interior.

margin-bottom: var(--gap);
Espacio inferior de --gap antes de la siguiente sección.

border-radius: .5rem;
Esquinas redondeadas de 0.5 rem.

}

.notifications-header h1 {
Estilos para el título principal dentro de .notifications-header.

margin-bottom: .5rem;
Espacio inferior de 0.5 rem tras el título.

font-size: 2rem;
Tamaño de fuente de 2 rem.

color: var(--dark);
Color de texto oscuro según variable.

}

.notifications-header p {
Regla para el párrafo descriptivo bajo el título.

font-size: 1.1rem;
Tamaño de texto de 1.1 rem.

color: var(--gray-300);
Texto en gris medio.

margin: 0;
Elimina márgenes por defecto.

}

.notifications-list-container {
Contenedor de la lista de notificaciones.

display: flex;
Flexbox en columna.

flex-direction: column;
Ordena notificaciones de arriba abajo.

gap: var(--gap);
Espacio de --gap entre cada notificación.

}

.notification-item {
Regla base para cada notificación individual.

background: #fff;
Fondo blanco.

padding: var(--gap);
Relleno interior de --gap.

border-radius: .5rem;
Esquinas redondeadas de 0.5 rem.

box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
Sombra suave para dar elevación.

display: flex;
Flexbox en fila.

align-items: flex-start;
Alinea contenido al inicio vertical.

gap: var(--gap);
Espacio de --gap entre icono, contenido y acción.

border-left: 5px solid var(--gray-200);
Borde izquierdo de 5 px gris medio (se sobreescribe luego según tipo).

transition: box-shadow .2s ease, transform .1s ease;
Anima suavemente cambios de sombra y posición.

cursor: pointer;
Muestra cursor de mano para interactividad.

}

.notification-item:hover {
Estado hover de cada notificación.

box-shadow: 0 4px 12px rgba(0, 0, 0, .1);
Aumenta la sombra para destacar.

transform: translateY(-2px);
Eleva ligeramente la tarjeta.

}

.notification-item.application-update {
Variante para notificaciones de actualización de postulación.

border-left-color: var(--info);
Cambia el color del borde izquierdo a la variable --info (normalmente azul).

}

.notification-item.new-message {
Variante para notificaciones de mensaje nuevo.

border-left-color: var(--success);
Borde izquierdo verde (éxito).

}

.notification-item.job-alert {
Variante para alertas de nuevas ofertas.

border-left-color: var(--primary);
Borde izquierdo color primario.

}

.notification-icon {
Regla para el icono de cada notificación.

font-size: 1.5rem;
Tamaño de icono de 1.5 rem.

color: var(--gray-400);
Color gris claro.

flex-shrink: 0;
Impide que el icono se encoja.

padding-top: .2rem;
Ajuste fino de alineación vertical.

}

.notification-item.application-update .notification-icon {
Icono dentro de notificación de actualización.

color: var(--info);
Cambia el icono a color --info.

}

.notification-item.new-message .notification-icon {
Icono dentro de notificación de mensaje.

color: var(--success);
Verde para mensajes.

}

.notification-item.job-alert .notification-icon {
Icono dentro de alerta de oferta.

color: var(--primary);
Color primario.

}

.notification-content {
Contenedor del texto de la notificación.

flex-grow: 1;
Ocupa el espacio restante entre icono y acción.

display: flex; flex-direction: column;
Flexbox en columna para organizar título, texto y timestamp.

gap: .3rem;
Espacio pequeño entre líneas de texto.

}

.notification-title {
Estilos para el título de cada notificación.

font-size: 1.1rem; font-weight: 600;
Seminegrita y tamaño de 1.1 rem.

color: var(--dark);
Texto oscuro.

}

.notification-text {
Regla para el párrafo descriptivo.

font-size: 1rem; color: var(--gray-600);
Tamaño de 1 rem y texto gris medio.

margin: 0; line-height: 1.4;
Sin márgenes y altura de línea de 1.4 para legibilidad.

}

.notification-text strong {
Regla para <strong> dentro del texto.

color: var(--dark);
Destaca el texto reforzándolo con color oscuro.

}

.notification-text .status-success {
Estado resaltado “éxito” dentro del texto.

color: var(--success); font-weight: 600;
Verde seminegrita.

}

.notification-text .status-info {
Estado “información” dentro del texto.

color: var(--info); font-weight: 600;
Azul seminegrita.

}

.notification-timestamp {
Regla para la marca de tiempo.

font-size: .85rem; color: var(--gray-400);
Texto pequeño y gris claro.

margin-top: .5rem;
Espacio superior antes de la timestamp.

display: flex; align-items: center; gap: .3rem;
Flexbox para alinear icono y texto con pequeño gap.

}

.notification-timestamp i {
Ajuste para el icono de reloj.

font-size: .9rem;
Tamaño ligeramente menor que el texto.

}

.notification-action {
Estilo para el enlace de acción (e.g. “Ver Oferta”).

flex-shrink: 0;
No se reduce.

align-self: center;
Centra verticalmente el enlace dentro del flex.

background: none; border: none;
Sin fondo ni borde.

color: var(--primary); font-size: .95rem; font-weight: 600;
Texto primario, seminegrita y tamaño 0.95 rem.

text-decoration: none;
Sin subrayado.

padding: .5rem 1rem; border-radius: .3rem;
Relleno interior y esquinas redondeadas.

transition: background .2s, color .2s;
Anima cambios de fondo y color al hover.

}

.notification-item:hover .notification-action {
Estado hover de la acción dentro de la notificación.

background: var(--gray-100);
Fondo gris claro al pasar el cursor.

color: var(--primary-dark);
Cambia el texto a una variante más oscura del primario.

}

.empty-state {
Regla para el estado vacío (sin notificaciones).

text-align: center;
Centra el contenido.

padding: calc(var(--gap) * 2);
Relleno amplio de 2×--gap.

background: #fff; border-radius: .5rem;
Fondo blanco y esquinas redondeadas.

box-shadow: 0 2px 8px rgba(0,0,0,.05);
Sombra suave.

color: var(--gray-500);
Texto gris medio.

}

.empty-state-icon {
Icono grande en estado vacío.

font-size: 3rem; color: var(--gray-300);
Muy grande y gris claro.

margin-bottom: var(--gap);
Espacio inferior.

}

.empty-state-text {
Título del estado vacío.

font-size: 1.2rem; font-weight: 600;
Seminegrita y tamaño de 1.2 rem.

margin-bottom: .5rem; color: var(--dark);
Espacio inferior y texto oscuro.

}

.empty-state-subtext {
Texto explicativo secundario.

font-size: 1rem; margin-bottom: calc(var(--gap) * 1.5);
Tamaño normal y espacio inferior de 1.5×--gap.

}

.empty-state .btn-primary {
Botón primario dentro del estado vacío.

display: inline-block;
Se comporta como bloque en línea.

padding: .75rem 1.5rem;
Relleno interior cómodo.

background: var(--primary); color: #fff;
Fondo primario y texto blanco.

border-radius: .5rem; text-decoration: none;
Esquinas redondeadas y sin subrayado.

font-weight: 600; transition: background .2s;
Seminegrita y anima cambio de fondo.

}

.empty-state .btn-primary:hover {
Estado hover del botón en estado vacío.

background: var(--primary-dark);
Fondo primario más oscuro.

}

@media (max-width: 768px) {
Reglas para pantallas de hasta 768 px.

.notifications-header h1 { font-size: 1.8rem; }
Reduce tamaño del título.

.notifications-header p { font-size: 1rem; }
Ajusta tamaño del párrafo descriptivo.

.notification-item {
Ajustes forzados en la notificación.

flex-direction: column; align-items: stretch; gap: .75rem;
Apila icono, contenido y acción verticalmente con espacio de 0.75 rem.

}

.notification-icon {
Ajustes del icono en móvil.

align-self: flex-start; padding-top: 0; font-size: 1.3rem;
Alinea al inicio, elimina padding superior y reduce tamaño.

}

.notification-title { font-size: 1rem; }
Ajusta el tamaño del título.

.notification-text { font-size: .95rem; }
Ajusta tamaño del texto descriptivo.

.notification-action {
Ajustes del enlace de acción.

align-self: flex-end; padding: .3rem .8rem; font-size: .9rem;
Alinea al final, reduce padding y tamaño.

}

}

@media (max-width: 480px) {
Reglas para pantallas de hasta 480 px.

.notifications-header h1 { font-size: 1.6rem; }
Título aún más pequeño.

.notification-item { padding: .8rem; gap: .5rem; }
Reduce padding y espacio entre elementos.

.notification-icon { font-size: 1.2rem; }
Icono de menor tamaño.

.notification-title { font-size: .95rem; }
Título de notificación más pequeño.

.notification-text { font-size: .9rem; }
Texto descriptivo más pequeño.

.notification-timestamp { font-size: .8rem; }
Marca de tiempo más pequeña.

.notification-action { padding: .2rem .6rem; font-size: .85rem; }
Enlace de acción más compacto.

.empty-state { padding: calc(var(--gap) * 1.5); }
Ajusta padding del estado vacío.

.empty-state-icon { font-size: 2.5rem; margin-bottom: var(--gap); }
Reduce icono y espacio inferior.

.empty-state-text { font-size: 1.1rem; }
Texto del estado vacío más pequeño.

.empty-state-subtext { font-size: .9rem; }
Subtexto de estado vacío más pequeño.

.empty-state .btn-primary { padding: .6rem 1.2rem; font-size: .9rem; }
Ajusta padding y tamaño del botón en estado vacío.

}

destacadas.html

Este archivo configura la página de Empresas Destacadas: incluye los estilos globales y módulos de sidebar, logo y navegación; marca “Destacadas” como la opción activa en la barra lateral; y en el main despliega la cabecera con título y subtítulo, seguida de una sección que muestra tarjetas de empresa con logo placeholder, nombre, tagline, descripción, contador de ofertas abiertas, ubicación e industria, y finaliza con el footer y los scripts de interactividad.

Destacadas.html Empresas Destacadas – EmpleoConnect HTML: Lista de Empresas y Detalles

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Empresas Destacadas | EmpleoConnect</title>
    <link rel="stylesheet" href="css/theme.css">
    <link rel="stylesheet" href="css/base.css">
    <link rel="stylesheet" href="css/layout.css">
    <link rel="stylesheet" href="css/state.css">
    <link rel="stylesheet" href="css/modules/sidebar.css">
    <link rel="stylesheet" href="css/modules/logo.css">
    <link rel="stylesheet" href="css/modules/navigation.css">
    <link rel="stylesheet" href="css/modules/profile-dropdown.css">
    <link rel="stylesheet" href="css/modules/sidebar-toggle.css">
    <link rel="stylesheet" href="css/pages/destacadas.css">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">

</head>
<body class="sidebar-visible">
    <button class="sidebar-toggle" id="sidebarToggle">
        <svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
    </button>

    <aside class="sidebar" id="sidebar">
        <div>
            <div class="logo">
                <svg viewBox="0 0 24 24"><path d="M20 7h-4V3c0-1.1-.9-2-2-2h-4c-1.1 0-2 .9-2 2v4H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2z"/><path d="M11 14h2v4h-2zM7 14h2v4H7zM15 14h2v4h-2z"/></svg>
                EmpleoConnect
            </div>
            <div class="category-label">Navegar</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V9z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
                    <span>Inicio</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/></svg>
                    <span>Ofertas</span>
                </li>
                 <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg>
                    <span>Explorar</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
                    <span>Notificaciones</span>
                </li>
                 <li class="nav-item employee-mode" id="employeeModeBtn">
                    <svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg>
                    <span class="mode-text">Modo Empleado</span>
                </li>
            </ul>
            <div class="category-label">Empresas</div>
            <ul class="nav-menu">
                 <li class="nav-item active">
                    <svg viewBox="0 0 24 24"><path d="M3 21h18M9 8h1M9 12h1M9 16h1M15 8h1M15 12h1M15 16h1M7 21V5a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v16"/></svg>
                    <span>Destacadas</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M4 21v-2a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
                    <span>Buscar</span>
                </li>
            </ul>
        </div>
        <div class="profile" id="profileBtn">
            <div class="profile-info">
                <div class="profile-icon"><svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg></div>
                <div>
                    <div class="username">Usuario</div>
                    <div class="status"><span class="status-indicator"></span><span>En línea</span></div>
                </div>
            </div>
            <ul class="nav-menu profile-links" id="profileLinks">
                <li class="nav-item"><span>Editar Perfil</span></li>
                <li class="nav-item"><span>Postulaciones</span></li>
                <li class="nav-item"><span>Notificaciones</span></li>
                <li class="nav-item logout"><span>Cerrar sesión</span></li>
            </ul>
        </div>
    </aside>

    <main>
        <section class="featured-companies-header">
            <h1>Empresas Destacadas</h1>
            <p>Descubre las empresas más valoradas y con grandes oportunidades en EmpleoConnect.</p>
        </section>

        <section class="featured-companies-list">
            <a href="#" class="company-card-featured">
                <div class="company-card-header">
                     <div class="company-logo-featured-placeholder"></div>
                    <div class="company-info-header">
                        <h2>Tech Dynamics</h2>
                         <p class="company-tagline">Innovación tecnológica a tu servicio</p>
                    </div>
                </div>
                <div class="company-card-body">
                    <p class="company-description">Empresa líder en desarrollo de software empresarial y soluciones de inteligencia artificial. Comprometidos con la excelencia y el crecimiento de nuestros empleados.</p>
                </div>
                <div class="company-card-footer">
                    <span class="open-jobs-count"><i class="fas fa-briefcase"></i> 50+ ofertas abiertas</span>
                    <span class="company-location"><i class="fas fa-map-marker-alt"></i> Madrid, Barcelona</span>
                     <span class="company-industry"><i class="fas fa-industry"></i> Tecnología</span>
                </div>
            </a>

             <a href="#" class="company-card-featured">
                <div class="company-card-header">
                     <div class="company-logo-featured-placeholder"></div>
                    <div class="company-info-header">
                        <h2>Global Sales Corp</h2>
                         <p class="company-tagline">Conectando el mundo a través de las ventas</p>
                    </div>
                </div>
                <div class="company-card-body">
                    <p class="company-description">Compañía global con una red de ventas expansiva. Ofrecemos oportunidades de crecimiento profesional y un ambiente dinámico.</p>
                </div>
                <div class="company-card-footer">
                    <span class="open-jobs-count"><i class="fas fa-briefcase"></i> 75+ ofertas abiertas</span>
                    <span class="company-location"><i class="fas fa-map-marker-alt"></i> Barcelona, Valencia, Sevilla</span>
                     <span class="company-industry"><i class="fas fa-industry"></i> Ventas</span>
                </div>
            </a>

             <a href="#" class="company-card-featured">
                <div class="company-card-header">
                     <div class="company-logo-featured-placeholder"></div>
                    <div class="company-info-header">
                        <h2>Innovate Agency</h2>
                         <p class="company-tagline">Creamos experiencias digitales memorables</p>
                    </div>
                </div>
                <div class="company-card-body">
                    <p class="company-description">Agencia de marketing digital y diseño UX/UI enfocada en resultados y creatividad. Buscamos talento apasionado por la innovación.</p>
                </div>
                <div class="company-card-footer">
                    <span class="open-jobs-count"><i class="fas fa-briefcase"></i> 30+ ofertas abiertas</span>
                    <span class="company-location"><i class="fas fa-map-marker-alt"></i> Madrid (Híbrido)</span>
                     <span class="company-industry"><i class="fas fa-industry"></i> Marketing Digital</span>
                </div>
            </a>

            <a href="#" class="company-card-featured">
                <div class="company-card-header">
                     <div class="company-logo-featured-placeholder"></div>
                    <div class="company-info-header">
                        <h2>Eco Solutions</h2>
                         <p class="company-tagline">Construyendo un futuro sostenible</p>
                    </div>
                </div>
                <div class="company-card-body">
                    <p class="company-description">Empresa dedicada a soluciones energéticas renovables y sostenibilidad ambiental. Únete a nuestra misión de impacto positivo.</p>
                </div>
                <div class="company-card-footer">
                    <span class="open-jobs-count"><i class="fas fa-briefcase"></i> 20+ ofertas abiertas</span>
                    <span class="company-location"><i class="fas fa-map-marker-alt"></i> Valencia, Remoto</span>
                     <span class="company-industry"><i class="fas fa-industry"></i> Energía Renovable</span>
                </div>
            </a>

            </section>

        <footer>
            <a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
        </footer>
    </main>

    <script src="js/barraLateral.js" defer></script>
    <script src="js/desplegablePerfil.js" defer></script>
    <script src="js/interaccionesInicio.js" defer></script>
</body>
</html>

Explicación del código: Destacadas.html Empresas Destacadas – EmpleoConnect HTML: Lista de Empresas y Detalles

<!DOCTYPE html>
Define el documento como HTML5, asegurando la compatibilidad moderna.

<html lang="es">
Elemento raíz del HTML, con atributo lang="es" para indicar que el contenido está en español.

<head>
Contenedor de metadatos, estilos y título.

<meta charset="UTF-8"/>
Establece la codificación de caracteres en UTF-8, permitiendo acentos y símbolos.

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
Configura el viewport para que el ancho sea el del dispositivo y la escala inicial sea 1, optimizando en móviles.

<title>Empresas Destacadas | EmpleoConnect</title>
Título mostrado en la pestaña del navegador.

<link rel="stylesheet" href="css/theme.css">
Importa variables de tema (colores, fuentes).

<link rel="stylesheet" href="css/base.css">
Carga estilos base (reset, tipografías).

<link rel="stylesheet" href="css/layout.css">
Aplica el layout global (grillas, contenedores principales).

<link rel="stylesheet" href="css/state.css">
Define clases de estado (activo, hover).

<link rel="stylesheet" href="css/modules/sidebar.css">
Estilos para la barra lateral.

<link rel="stylesheet" href="css/modules/logo.css">
Diseño del bloque de logo en el sidebar.

<link rel="stylesheet" href="css/modules/navigation.css">
Estilos de los menús de navegación.

<link rel="stylesheet" href="css/modules/profile-dropdown.css">
Configuración del dropdown de perfil.

<link rel="stylesheet" href="css/modules/sidebar-toggle.css">
Estilos para el botón de togglear la barra lateral en móviles.

<link rel="stylesheet" href="css/pages/destacadas.css">
Estilos específicos de la página “Empresas Destacadas”.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
Fuente de iconos Font Awesome.

</head>
Fin de la sección de metadatos.

<body class="sidebar-visible">
Inicio del cuerpo, con clase que mantiene visible el sidebar.

<button class="sidebar-toggle" id="sidebarToggle">
Botón para mostrar/ocultar la barra lateral en pantallas pequeñas.

<svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
Icono de “hamburguesa” en SVG.

</button>
Cierre del botón de toggle.

<aside class="sidebar" id="sidebar">
Contenedor semántico de la barra lateral.

<div>
Wrapper interno para agrupar secciones.

<div class="logo">
Bloque del logo.

<svg viewBox="0 0 24 24">…</svg>
SVG con la silueta del logo.

EmpleoConnect
Nombre de la plataforma junto al logo.

</div>
Cierra el bloque de logo.

<div class="category-label">Navegar</div>
Etiqueta separadora de la sección de navegación.

<ul class="nav-menu">
Lista de elementos de navegación principal.

<li class="nav-item">Inicio</li>
Enlace a la página de inicio.

<li class="nav-item">Ofertas</li>
Enlace a la sección de ofertas.

<li class="nav-item">Explorar</li>
Enlace a “Explorar”.

<li class="nav-item">Notificaciones</li>
Enlace a la sección actual (pero no marcado).

<li class="nav-item employee-mode" id="employeeModeBtn">Modo Empleado</li>
Botón para activar el modo de empleado.

</ul>
Cierra la lista de navegación.

<div class="category-label">Empresas</div>
Etiqueta para la subsección de empresas.

<ul class="nav-menu">
Lista de enlaces secundarios.

<li class="nav-item active">Destacadas</li>
Ítem “Destacadas”, marcado como activo en esta página.

<li class="nav-item">Buscar</li>
Ítem “Buscar”.

</ul>
Fin de la lista de empresas.

</div>
Cierra el wrapper interno del sidebar.

<div class="profile" id="profileBtn">
Sección de perfil con dropdown.

<div class="profile-info">
Bloque con icono y datos de usuario.

<div class="profile-icon"><svg>…</svg></div>
SVG con icono de usuario.

<div>
Contenedor de texto.

<div class="username">Usuario</div>
Muestra el nombre del usuario.

<div class="status"><span class="status-indicator"></span><span>En línea</span></div>
Indicador y texto de estado.

</div>
Cierra el contenedor de texto.

</div>
Cierra profile-info.

<ul class="nav-menu profile-links" id="profileLinks">
Lista de enlaces del dropdown de perfil.

<li class="nav-item">Editar Perfil</li>
Opción para editar perfil.

<li class="nav-item">Postulaciones</li>
Opción de postulaciones.

<li class="nav-item">Notificaciones</li>
Opción de notificaciones.

<li class="nav-item logout">Cerrar sesión</li>
Enlace para cerrar sesión.

</ul>
Cierra la lista de perfil.

</div>
Fin de la sección de perfil.

</aside>
Cierra el sidebar.

<main>
Contenedor principal de contenido.

<section class="featured-companies-header">
Sección de encabezado de empresas destacadas.

<h1>Empresas Destacadas</h1>
Título principal.

<p>Descubre las empresas más valoradas y con grandes oportunidades en EmpleoConnect.</p>
Descripción introductoria.

</section>
Cierra la sección de encabezado.

<section class="featured-companies-list">
Sección que agrupa las tarjetas de empresas.

<a href="#" class="company-card-featured">
Tarjeta clicable de una empresa.

<div class="company-card-header">
Encabezado de la tarjeta.

<div class="company-logo-featured-placeholder"></div>
Placeholder para el logo de la empresa.

<div class="company-info-header">
Contenedor de nombre y eslogan.

<h2>Tech Dynamics</h2>
Nombre de la empresa.

<p class="company-tagline">Innovación tecnológica a tu servicio</p>
Lema de la empresa.

</div>
Cierra company-info-header.

</div>
Fin de company-card-header.

<div class="company-card-body">
Cuerpo de la tarjeta con descripción.

<p class="company-description">… soluciones de inteligencia artificial. Comprometidos con la excelencia y el crecimiento de nuestros empleados.</p>
Texto descriptivo.

</div>
Cierra el cuerpo de la tarjeta.

<div class="company-card-footer">
Pie de la tarjeta con metadatos.

<span class="open-jobs-count"><i class="fas fa-briefcase"></i> 50+ ofertas abiertas</span>
Número de vacantes.

<span class="company-location"><i class="fas fa-map-marker-alt"></i> Madrid, Barcelona</span>
Ubicaciones disponibles.

<span class="company-industry"><i class="fas fa-industry"></i> Tecnología</span>
Sector de la empresa.

</div>
Cierra el pie de la tarjeta.

</a>
Fin de la primera tarjeta de empresa.

<a href="#" class="company-card-featured">…</a>
Segunda tarjeta: “Global Sales Corp” con eslogan, descripción y footer similar.

<a href="#" class="company-card-featured">…</a>
Tercera tarjeta: “Innovate Agency”.

<a href="#" class="company-card-featured">…</a>
Cuarta tarjeta: “Eco Solutions”.

</section>
Cierra la sección de lista de empresas.

<footer>
Pie de página con enlaces legales.

<a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
Enlaces de información.

</footer>
Fin del pie de página.

</main>
Cierra el contenido principal.

<script src="js/barraLateral.js" defer></script>
Script diferido para la funcionalidad de la barra lateral.

<script src="js/desplegablePerfil.js" defer></script>
Script para el menú desplegable de perfil.

<script src="js/interaccionesInicio.js" defer></script>
Script para interacciones genéricas en la página.

</body>
Cierra el cuerpo del documento.

</html>
Cierra el elemento HTML raíz.

destacadas.css

Este archivo establece los estilos de la página de Empresas Destacadas: aplica padding y separación en main, formatea la cabecera .featured-companies-header con fondo suavizado, padding y texto centrado, organiza las tarjetas de empresa en un grid responsivo .featured-companies-list, diseña cada tarjeta .company-card-featured con fondo blanco, bordes redondeados, sombra y efecto hover, estructura su encabezado con logo placeholder y datos en .company-card-header, controla el bloque de descripción en .company-card-body y define el pie de tarjeta .company-card-footer con iconos y metadatos; además incluye media queries para ajustar tamaños, espacios y layout en tablet y móvil.

destacadas.css – Empresas Destacadas: Estilos de Tarjetas y Layout de Lista

/* css/pages/destacadas.css */

main {
    padding: var(--gap);
    display: flex;
    flex-direction: column;
    gap: calc(var(--gap) * 1.5);
}

.featured-companies-header {
    background: var(--gray-100);
    padding: calc(var(--gap) * 1.5) var(--gap);
    text-align: center;
    margin-bottom: var(--gap);
    border-radius: .5rem;
}

.featured-companies-header h1 {
    margin-bottom: .5rem;
    font-size: 2rem;
    color: var(--dark);
}

.featured-companies-header p {
    font-size: 1.1rem;
    color: var(--gray-300);
    margin: 0;
}

.featured-companies-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: var(--gap);
}

.company-card-featured {
    background: #fff;
    padding: var(--gap);
    border-radius: .5rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
    display: flex;
    flex-direction: column;
    gap: var(--gap);
    text-decoration: none;
    color: var(--dark);
    transition: transform .2s ease, box-shadow .2s ease;
    cursor: pointer;
}

.company-card-featured:hover {
    transform: translateY(-3px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, .1);
}

.company-card-header {
    display: flex;
    align-items: center;
    gap: var(--gap);
    padding-bottom: var(--gap);
    border-bottom: 1px solid var(--gray-100);
}

.company-logo-featured-placeholder {
    width: 60px;
    height: 60px;
    background: var(--gray-200);
    border-radius: .5rem;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--gray-500);
    font-size: .9rem;
    overflow: hidden;
    border: 1px solid var(--gray-100);
}

.company-logo-featured-placeholder img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}


.company-info-header {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
}

.company-info-header h2 {
    font-size: 1.3rem;
    margin: 0 0 .2rem 0;
    color: var(--primary);
}

.company-tagline {
    font-size: .9rem;
    color: var(--gray-400);
    margin: 0;
}

.company-description {
    font-size: 1rem;
    color: var(--dark);
    line-height: 1.5;
    margin: 0;
    flex-grow: 1;
}

.company-card-footer {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem 1.5rem;
    font-size: .9rem;
    color: var(--gray-500);
    padding-top: var(--gap);
    border-top: 1px solid var(--gray-100);
    margin-top: auto;
}

.company-card-footer span {
    display: flex;
    align-items: center;
    gap: .3rem;
}

.company-card-footer i {
    color: var(--primary);
    font-size: 1rem;
}

@media (max-width: 768px) {
    .featured-companies-header h1 {
        font-size: 1.8rem;
    }

    .featured-companies-header p {
        font-size: 1rem;
    }

    .featured-companies-list {
        grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    }

    .company-card-featured {
         padding: .8rem;
         gap: .8rem;
    }

    .company-card-header {
         gap: .8rem;
         padding-bottom: .8rem;
    }

    .company-logo-featured-placeholder {
         width: 50px;
         height: 50px;
    }

    .company-info-header h2 {
        font-size: 1.2rem;
    }

    .company-tagline {
        font-size: .85rem;
    }

    .company-description {
        font-size: .95rem;
    }

     .company-card-footer {
          flex-direction: column;
          gap: .5rem;
          font-size: .85rem;
          padding-top: .8rem;
     }

      .company-card-footer span {
          gap: .5rem;
      }
}

@media (max-width: 480px) {
     .featured-companies-header h1 {
        font-size: 1.6rem;
    }
     .company-card-featured {
        padding: .6rem;
        gap: .6rem;
     }
     .company-card-header {
          gap: .6rem;
          padding-bottom: .6rem;
     }

     .company-logo-featured-placeholder {
          width: 45px;
          height: 45px;
     }

      .company-info-header h2 {
        font-size: 1.1rem;
    }

     .company-tagline {
        font-size: .8rem;
    }

     .company-description {
        font-size: .9rem;
     }

     .company-card-footer {
          gap: .4rem;
          font-size: .8rem;
          padding-top: .6rem;
     }
}

Explicación del código: destacadas.css – Empresas Destacadas: Estilos de Tarjetas y Layout de Lista

/* css/pages/destacadas.css */
Comentario que identifica este bloque como estilos de la página destacadas.css.

main {
Selecciona el elemento <main> que envuelve todo el contenido principal.

padding: var(--gap);
Aplica un relleno interior en todos los lados igual al valor de la variable CSS --gap.

display: flex;
Convierte <main> en un contenedor flexbox.

flex-direction: column;
Ordena sus elementos hijos en columna (uno debajo de otro).

gap: calc(var(--gap) * 1.5);
Deja un espacio de 1.5 veces --gap entre cada hijo.

}

.featured-companies-header {
Regla para el bloque de encabezado de empresas destacadas.

background: var(--gray-100);
Fondo gris claro según la variable --gray-100.

padding: calc(var(--gap) * 1.5) var(--gap);
Relleno vertical de 1.5×--gap y horizontal de --gap.

text-align: center;
Centra el texto dentro del bloque.

margin-bottom: var(--gap);
Espacio inferior de --gap respecto al siguiente elemento.

border-radius: .5rem;
Bordes redondeados de 0.5 rem de radio.

}

.featured-companies-header h1 {
Estilos para el título <h1> dentro de .featured-companies-header.

margin-bottom: .5rem;
Espacio inferior de 0.5 rem tras el título.

font-size: 2rem;
Tamaño de fuente de 2 rem.

color: var(--dark);
Color de texto según la variable --dark.

}

.featured-companies-header p {
Regla para el párrafo descriptivo bajo el título.

font-size: 1.1rem;
Tamaño de fuente de 1.1 rem.

color: var(--gray-300);
Color gris medio para el texto.

margin: 0;
Elimina márgenes por defecto del párrafo.

}

.featured-companies-list {
Contenedor de la cuadrícula de tarjetas de empresas.

display: grid;
Convierte en un contenedor grid.

grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
Crea columnas de al menos 300 px y se ajustan automáticamente al ancho disponible.

gap: var(--gap);
Espacio de --gap entre filas y columnas.

}

.company-card-featured {
Regla base para cada tarjeta de empresa destacada (es un enlace <a>).

background: #fff;
Fondo blanco.

padding: var(--gap);
Relleno interior de --gap.

border-radius: .5rem;
Bordes redondeados de 0.5 rem.

box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
Sombra suave para dar elevación.

display: flex;
Contenedor flexbox.

flex-direction: column;
Organiza su contenido en columna.

gap: var(--gap);
Espacio de --gap entre las secciones internas.

text-decoration: none;
Elimina subrayado de enlace.

color: var(--dark);
Color de texto según variable --dark.

transition: transform .2s ease, box-shadow .2s ease;
Anima cambios de posición y sombra al hover.

cursor: pointer;
Cursor de mano para indicar interactividad.

}

.company-card-featured:hover {
Estado hover de la tarjeta.

transform: translateY(-3px);
Eleva la tarjeta 3 px hacia arriba.

box-shadow: 0 4px 12px rgba(0, 0, 0, .1);
Aumenta la sombra para destacar.

}

.company-card-header {
Encabezado dentro de la tarjeta, que contiene logo y nombre.

display: flex;
Contenedor flexbox en fila.

align-items: center;
Alinea verticalmente al centro.

gap: var(--gap);
Espacio horizontal de --gap.

padding-bottom: var(--gap);
Relleno inferior de --gap.

border-bottom: 1px solid var(--gray-100);
Línea inferior gris claro para separar secciones.

}

.company-logo-featured-placeholder {
Placeholder para el logo de la empresa.

width: 60px; height: 60px;
Dimensiones fijas de 60×60 px.

background: var(--gray-200);
Fondo gris claro.

border-radius: .5rem;
Bordes redondeados.

flex-shrink: 0;
Impide que se encoja.

display: flex; align-items: center; justify-content: center;
Centra su contenido (por ejemplo, un icono o texto).

color: var(--gray-500); font-size: .9rem;
Color y tamaño del texto interno.

overflow: hidden;
Oculta contenido que sobresalga.

border: 1px solid var(--gray-100);
Borde gris muy claro.

}

.company-logo-featured-placeholder img {
Regla para una imagen <img> dentro del placeholder.

display: block; width: 100%; height: 100%;
Ocupa todo el contenedor.

object-fit: cover;
Recorta o escala la imagen para cubrir sin deformarse.

}

.company-info-header {
Contenedor de nombre y eslogan de la empresa.

flex-grow: 1;
Ocupa todo el espacio horizontal restante.

display: flex; flex-direction: column;
Organiza su contenido en columna.

}

.company-info-header h2 {
Nombre de la empresa dentro del header.

font-size: 1.3rem;
Tamaño de fuente de 1.3 rem.

margin: 0 0 .2rem 0;
Sin margen superior ni lateral, 0.2 rem de margen inferior.

color: var(--primary);
Color primario para destacar el nombre.

}

.company-tagline {
Eslogan o lema de la empresa.

font-size: .9rem;
Tamaño de fuente de 0.9 rem.

color: var(--gray-400);
Color gris medio.

margin: 0;
Sin márgenes.

}

.company-description {
Descripción detallada dentro del cuerpo de la tarjeta.

font-size: 1rem; color: var(--dark);
Texto de 1 rem y color oscuro.

line-height: 1.5;
Altura de línea de 1.5 para legibilidad.

margin: 0;
Sin márgenes.

flex-grow: 1;
Ocupa todo el espacio vertical restante para empujar el footer abajo.

}

.company-card-footer {
Pie de la tarjeta, con datos como número de vacantes.

display: flex; flex-wrap: wrap;
Flexbox que envuelve en varias líneas si es necesario.

gap: .75rem 1.5rem;
0.75 rem de espacio vertical y 1.5 rem horizontal.

font-size: .9rem; color: var(--gray-500);
Texto pequeño y gris.

padding-top: var(--gap);
Relleno superior de --gap.

border-top: 1px solid var(--gray-100);
Línea superior gris clara como separación.

margin-top: auto;
Empuja el footer hacia abajo si falta contenido.

}

.company-card-footer span {
Cada elemento de metadato dentro del footer.

display: flex; align-items: center; gap: .3rem;
Flexbox para icono y texto, con pequeño espacio.

}

.company-card-footer i {
Iconos dentro del footer.

color: var(--primary);
Color primario para los iconos.

font-size: 1rem;
Tamaño de icono de 1 rem.

}

@media (max-width: 768px) {
Reglas para pantallas de hasta 768 px de ancho.

.featured-companies-header h1 { font-size: 1.8rem; }
Ajusta el tamaño del título a 1.8 rem.

.featured-companies-header p { font-size: 1rem; }
Tamaño de párrafo a 1 rem.

.featured-companies-list { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }
Reduce el ancho mínimo de columnas a 250 px.

.company-card-featured { padding: .8rem; gap: .8rem; }
Reduce padding y gap interno a 0.8 rem.

.company-card-header { gap: .8rem; padding-bottom: .8rem; }
Ajusta espacio y padding en el header de la tarjeta.

.company-logo-featured-placeholder { width: 50px; height: 50px; }
Disminuye el placeholder de logo a 50×50 px.

.company-info-header h2 { font-size: 1.2rem; }
Nombre de empresa en 1.2 rem.

.company-tagline { font-size: .85rem; }
Eslogan en 0.85 rem.

.company-description { font-size: .95rem; }
Descripción en 0.95 rem.

.company-card-footer { flex-direction: column; gap: .5rem; font-size: .85rem; padding-top: .8rem; }
Footer en columna con gap de 0.5 rem y texto más pequeño.

.company-card-footer span { gap: .5rem; }
Espacio interno de 0.5 rem en cada <span>.

}

@media (max-width: 480px) {
Reglas para pantallas de hasta 480 px.

.featured-companies-header h1 { font-size: 1.6rem; }
Título reducido a 1.6 rem.

.company-card-featured { padding: .6rem; gap: .6rem; }
Padding y gap interno de 0.6 rem.

.company-card-header { gap: .6rem; padding-bottom: .6rem; }
Ajusta header al tamaño pequeño.

.company-logo-featured-placeholder { width: 45px; height: 45px; }
Logo placeholder de 45×45 px.

.company-info-header h2 { font-size: 1.1rem; }
Nombre de empresa en 1.1 rem.

.company-tagline { font-size: .8rem; }
Eslogan en 0.8 rem.

.company-description { font-size: .9rem; }
Descripción en 0.9 rem.

.company-card-footer { gap: .4rem; font-size: .8rem; padding-top: .6rem; }
Footer con gap de 0.4 rem y texto de 0.8 rem.

}

buscar.html

Este archivo configura la página de “Buscar Empresas”: enlaza los estilos globales y módulos de sidebar, logo, navegación, perfil desplegable y form de búsqueda; marca “Buscar” como la opción activa en la barra lateral; y en el main muestra una cabecera con título y descripción, seguida de un formulario de búsqueda de empresas y controles de filtro (industria, tamaño, ubicación), luego despliega los resultados en tarjetas de empresa con logo placeholder, nombre, metadatos (industria, ubicación, tamaño) y contador de ofertas abiertas, y concluye con el footer y los scripts de interactividad.

buscar.html – Buscar Empresas – EmpleoConnect HTML: Formulario y Resultados de Búsqueda de Empresas

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Buscar Empresas | EmpleoConnect</title>
    <link rel="stylesheet" href="css/theme.css">
    <link rel="stylesheet" href="css/base.css">
    <link rel="stylesheet" href="css/layout.css">
    <link rel="stylesheet" href="css/state.css">
    <link rel="stylesheet" href="css/modules/sidebar.css">
    <link rel="stylesheet" href="css/modules/logo.css">
    <link rel="stylesheet" href="css/modules/navigation.css">
    <link rel="stylesheet" href="css/modules/profile-dropdown.css">
    <link rel="stylesheet" href="css/modules/sidebar-toggle.css">
    <link rel="stylesheet" href="css/modules/search-form.css">
     <link rel="stylesheet" href="css/pages/buscar-empresas.css">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">

</head>
<body class="sidebar-visible">
    <button class="sidebar-toggle" id="sidebarToggle">
        <svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
    </button>

    <aside class="sidebar" id="sidebar">
        <div>
            <div class="logo">
                <svg viewBox="0 0 24 24"><path d="M20 7h-4V3c0-1.1-.9-2-2-2h-4c-1.1 0-2 .9-2 2v4H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2z"/><path d="M11 14h2v4h-2zM7 14h2v4H7zM15 14h2v4h-2z"/></svg>
                EmpleoConnect
            </div>
            <div class="category-label">Navegar</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V9z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
                    <span>Inicio</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/></svg>
                    <span>Ofertas</span>
                </li>
                 <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg>
                    <span>Explorar</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
                    <span>Notificaciones</span>
                </li>
                 <li class="nav-item employee-mode" id="employeeModeBtn">
                    <svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg>
                    <span class="mode-text">Modo Empleado</span>
                </li>
            </ul>
            <div class="category-label">Empresas</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M3 21h18M9 8h1M9 12h1M9 16h1M15 8h1M15 12h1M15 16h1M7 21V5a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v16"/></svg>
                    <span>Destacadas</span>
                </li>
                <li class="nav-item active">
                    <svg viewBox="0 0 24 24"><path d="M4 21v-2a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
                    <span>Buscar</span>
                </li>
            </ul>
        </div>
        <div class="profile" id="profileBtn">
            <div class="profile-info">
                <div class="profile-icon"><svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg></div>
                <div>
                    <div class="username">Usuario</div>
                    <div class="status"><span class="status-indicator"></span><span>En línea</span></div>
                </div>
            </div>
            <ul class="nav-menu profile-links" id="profileLinks">
                <li class="nav-item"><span>Editar Perfil</span></li>
                <li class="nav-item"><span>Postulaciones</span></li>
                <li class="nav-item"><span>Notificaciones</span></li>
                <li class="nav-item logout"><span>Cerrar sesión</span></li>
            </ul>
        </div>
    </aside>

    <main>
        <section class="company-search-header">
            <h1>Buscar Empresas</h1>
            <p>Encuentra empresas por nombre, industria, ubicación o tamaño.</p>

             <form class="search-form">
                <input type="text" placeholder="Buscar por nombre de empresa"/>
                <button type="submit">
                    <i class="fa fa-search"></i> Buscar
                </button>
            </form>

             <div class="company-filters">
                 <select name="industry">
                     <option value="">Industria</option>
                     <option value="tecnologia">Tecnología</option>
                     <option value="ventas">Ventas</option>
                     <option value="energia">Energía Renovable</option>
                     <option value="marketing">Marketing</option>
                      </select>
                  <select name="size">
                     <option value="">Tamaño</option>
                     <option value="pequena">Pequeña (1-50)</option>
                     <option value="mediana">Mediana (51-250)</option>
                     <option value="grande">Grande (251+)</option>
                 </select>
                 <select name="location">
                     <option value="">Ubicación</option>
                     <option value="remoto">Remoto</option>
                     <option value="madrid">Madrid</option>
                     <option value="barcelona">Barcelona</option>
                     </select>
             </div>
        </section>

        <section class="company-search-results">
            <h2>Resultados de la Búsqueda</h2>
            <div class="company-list-search">
                <a href="#" class="company-card-search">
                    <div class="company-logo-search-placeholder"></div>
                    <div class="company-info-search">
                         <h3>Tech Dynamics</h3>
                        <p class="company-meta-search"><i class="fas fa-industry"></i> Tecnología <span class="separator">•</span> <i class="fas fa-map-marker-alt"></i> Madrid, Barcelona <span class="separator">•</span> <i class="fas fa-users"></i> Grande</p>
                        <p class="open-jobs-search"><i class="fas fa-briefcase"></i> 50+ ofertas abiertas</p>
                    </div>
                </a>

                 <a href="#" class="company-card-search">
                    <div class="company-logo-search-placeholder"></div>
                    <div class="company-info-search">
                         <h3>Global Sales Corp</h3>
                        <p class="company-meta-search"><i class="fas fa-industry"></i> Ventas <span class="separator">•</span> <i class="fas fa-map-marker-alt"></i> Barcelona, Valencia <span class="separator">•</span> <i class="fas fa-users"></i> Grande</p>
                        <p class="open-jobs-search"><i class="fas fa-briefcase"></i> 75+ ofertas abiertas</p>
                    </div>
                </a>

                 <a href="#" class="company-card-search">
                    <div class="company-logo-search-placeholder"></div>
                    <div class="company-info-search">
                         <h3>Innovate Agency</h3>
                        <p class="company-meta-search"><i class="fas fa-industry"></i> Marketing Digital <span class="separator">•</span> <i class="fas fa-map-marker-alt"></i> Madrid <span class="separator">•</span> <i class="fas fa-users"></i> Mediana</p>
                        <p class="open-jobs-search"><i class="fas fa-briefcase"></i> 30+ ofertas abiertas</p>
                    </div>
                </a>

                <a href="#" class="company-card-search">
                    <div class="company-logo-search-placeholder"></div>
                    <div class="company-info-search">
                         <h3>Eco Solutions</h3>
                        <p class="company-meta-search"><i class="fas fa-industry"></i> Energía Renovable <span class="separator">•</span> <i class="fas fa-map-marker-alt"></i> Valencia, Remoto <span class="separator">•</span> <i class="fas fa-users"></i> Mediana</p>
                        <p class="open-jobs-search"><i class="fas fa-briefcase"></i> 20+ ofertas abiertas</p>
                    </div>
                </a>

                 <a href="#" class="company-card-search">
                    <div class="company-logo-search-placeholder"></div>
                    <div class="company-info-search">
                         <h3>NextSoft</h3>
                        <p class="company-meta-search"><i class="fas fa-industry"></i> Tecnología <span class="separator">•</span> <i class="fas fa-map-marker-alt"></i> Remoto <span class="separator">•</span> <i class="fas fa-users"></i> Pequeña</p>
                        <p class="open-jobs-search"><i class="fas fa-briefcase"></i> 10+ ofertas abiertas</p>
                    </div>
                </a>


                </div>
        </section>

        <footer>
            <a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
        </footer>
    </main>

    <script src="js/barraLateral.js" defer></script>
    <script src="js/desplegablePerfil.js" defer></script>
    <script src="js/interaccionesInicio.js" defer></script>
</body>
</html>

Explicación del código: buscar.html – Buscar Empresas – EmpleoConnect HTML: Formulario y Resultados de Búsqueda de Empresas

<!DOCTYPE html>
Define el documento como HTML5 para asegurar el uso de las características modernas del estándar.

<html lang="es">
Elemento raíz, con atributo lang="es" para indicar que el contenido está en español.

<head>
Contiene metadatos, enlaces a estilos y el título de la página.

<meta charset="UTF-8"/>
Establece la codificación de caracteres en UTF-8, permitiendo caracteres especiales y acentos.

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
Ajusta el viewport para que el ancho corresponda al dispositivo y la escala inicial sea 1, optimizando la visualización móvil.

<title>Buscar Empresas | EmpleoConnect</title>
Título que aparece en la pestaña del navegador.

<link rel="stylesheet" href="css/theme.css">
Importa variables de tema (colores, tipografías).

<link rel="stylesheet" href="css/base.css">
Carga estilos base (reseteo de márgenes y paddings, fuentes predeterminadas).

<link rel="stylesheet" href="css/layout.css">
Define el layout global (contenerdor principal, grillas).

<link rel="stylesheet" href="css/state.css">
Incluye clases de estado (activo, hover).

<link rel="stylesheet" href="css/modules/sidebar.css">
Estilos del sidebar.

<link rel="stylesheet" href="css/modules/logo.css">
Diseño del bloque de logo.

<link rel="stylesheet" href="css/modules/navigation.css">
Estilos de los menús de navegación.

<link rel="stylesheet" href="css/modules/profile-dropdown.css">
Configuración del dropdown de perfil.

<link rel="stylesheet" href="css/modules/sidebar-toggle.css">
Estilos para el botón que muestra/oculta el sidebar en móviles.

<link rel="stylesheet" href="css/modules/search-form.css">
Diseño del formulario de búsqueda.

<link rel="stylesheet" href="css/pages/buscar-empresas.css">
Estilos específicos para la página de buscar empresas.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/.../font-awesome.min.css">
Importa los iconos de Font Awesome.

</head>
Cierra la sección de metadatos.

<body class="sidebar-visible">
Inicio del cuerpo, con clase que mantiene visible el sidebar.

<button class="sidebar-toggle" id="sidebarToggle">
Botón para togglear la visibilidad del sidebar en pantallas pequeñas.

<svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
Icono de “hamburguesa” en SVG.

</button>
Cierre del botón de toggle.

<aside class="sidebar" id="sidebar">
Contenedor semántico de la barra lateral.

<div>
Wrapper interno del sidebar.

<div class="logo">
Bloque para el logo de la marca.

<svg viewBox="0 0 24 24">…</svg>
SVG con el icono del logo.

EmpleoConnect
Nombre de la plataforma junto al logo.

</div>
Cierra el bloque de logo.

<div class="category-label">Navegar</div>
Etiqueta que separa la sección de navegación principal.

<ul class="nav-menu">
Lista de los elementos de navegación.

<li class="nav-item">Inicio</li>
Enlace a la página de inicio.

<li class="nav-item">Ofertas</li>
Enlace a la sección de ofertas.

<li class="nav-item">Explorar</li>
Enlace a la sección de explorar.

<li class="nav-item">Notificaciones</li>
Enlace a la sección de notificaciones.

<li class="nav-item employee-mode" id="employeeModeBtn">Modo Empleado</li>
Elemento para activar el modo empleado.

</ul>
Cierra la lista de navegación.

<div class="category-label">Empresas</div>
Etiqueta que marca la sección de empresas.

<ul class="nav-menu">
Lista secundaria con opciones de empresas.

<li class="nav-item">Destacadas</li>
Enlace a empresas destacadas.

<li class="nav-item active">Buscar</li>
Enlace activo a la página de buscar empresas.

</ul>
Cierra la lista de empresas.

</div>
Cierra el wrapper interno del sidebar.

<div class="profile" id="profileBtn">
Sección de perfil con menú desplegable.

<div class="profile-info">
Contenedor con icono y datos del usuario.

<div class="profile-icon"><svg>…</svg></div>
Icono SVG de usuario.

<div>
Contenedor de texto de perfil.

<div class="username">Usuario</div>
Muestra el nombre del usuario.

<div class="status"><span class="status-indicator"></span><span>En línea</span></div>
Indicador y texto de estado.

</div>
Cierra el contenedor de texto.

</div>
Cierra profile-info.

<ul class="nav-menu profile-links" id="profileLinks">
Lista de enlaces del dropdown de perfil.

<li class="nav-item">Editar Perfil</li>
Opción para editar perfil.

<li class="nav-item">Postulaciones</li>
Opción de postulaciones.

<li class="nav-item">Notificaciones</li>
Opción de notificaciones.

<li class="nav-item logout">Cerrar sesión</li>
Opción para cerrar sesión.

</ul>
Cierra la lista de perfil.

</div>
Cierra la sección de perfil.

</aside>
Cierra el sidebar.

<main>
Contenedor principal de contenido.

<section class="company-search-header">
Cabecera de la sección de búsqueda de empresas.

<h1>Buscar Empresas</h1>
Título principal.

<p>Encuentra empresas por nombre, industria, ubicación o tamaño.</p>
Descripción introductoria.

<form class="search-form">
Formulario de búsqueda principal.

<input type="text" placeholder="Buscar por nombre de empresa"/>
Campo de texto para el término de búsqueda.

<button type="submit"><i class="fa fa-search"></i> Buscar</button>
Botón para enviar la búsqueda, con icono.

</form>
Cierra el formulario de búsqueda.

<div class="company-filters">
Contenedor de filtros adicionales.

<select name="industry">…</select>
Selector para filtrar por industria.

<select name="size">…</select>
Selector para filtrar por tamaño de empresa.

<select name="location">…</select>
Selector para filtrar por ubicación.

</div>
Cierra el contenedor de filtros.

</section>
Cierra la sección de cabecera de búsqueda.

<section class="company-search-results">
Sección que muestra los resultados.

<h2>Resultados de la Búsqueda</h2>
Subtítulo de resultados.

<div class="company-list-search">
Contenedor de las tarjetas de resultados.

<a href="#" class="company-card-search">…</a>
Tarjeta de resultado para “Tech Dynamics” (contiene logo placeholder, nombre, meta y ofertas).

<a href="#" class="company-card-search">…</a>
Tarjeta para “Global Sales Corp”.

<a href="#" class="company-card-search">…</a>
Tarjeta para “Innovate Agency”.

<a href="#" class="company-card-search">…</a>
Tarjeta para “Eco Solutions”.

<a href="#" class="company-card-search">…</a>
Tarjeta para “NextSoft”.

</div>
Cierra el contenedor de resultados.

</section>
Cierra la sección de resultados de búsqueda.

<footer>
Pie de página con enlaces legales.

<a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
Enlaces a páginas de información.

</footer>
Cierra el pie de página.

</main>
Cierra el contenido principal.

<script src="js/barraLateral.js" defer></script>
Script diferido para la funcionalidad de la barra lateral.

<script src="js/desplegablePerfil.js" defer></script>
Script diferido para el menú desplegable de perfil.

<script src="js/interaccionesInicio.js" defer></script>
Script diferido para interacciones generales de la página.

</body>
Final del cuerpo del documento.

</html>
Cierre del elemento HTML raíz.

buscar-empresas.css

Este archivo estiliza la página de búsqueda de empresas: define el main con padding global y separación entre secciones; el bloque .company-search-header con fondo claro, título centrado, subtítulo y el form.search-form para búsqueda; el contenedor .company-filters con dropdowns personalizados para industria, tamaño y ubicación (incluyendo icono de flecha SVG y focus ring); la sección de resultados encabezada por un h2 subrayado en color principal; cada tarjeta de resultado (.company-card-search) con logo placeholder, nombre (h3), metadatos (.company-meta-search) e indicador de ofertas (.open-jobs-search), con hover elevación; y un estado vacío (.empty-state) con icono y mensaje. También incluye ajustes responsivos para móviles (columnas apiladas, ajustes de tamaño y espaciado).

buscar-empresas.css – Página de Búsqueda de Empresas: Encabezado, Filtros y Resultados

/* css/pages/buscar-empresas.css */

main {
    padding: var(--gap);
    display: flex;
    flex-direction: column;
    gap: calc(var(--gap) * 1.5); 
}

.company-search-header {
    background: var(--gray-100);
    padding: calc(var(--gap) * 1.5) var(--gap);
    text-align: center;
    margin-bottom: var(--gap);
    border-radius: .5rem;
    display: flex;
    flex-direction: column;
    align-items: center; 
    gap: var(--gap); 
}

.company-search-header h1 {
    margin-bottom: .2rem; 
    font-size: 2rem;
    color: var(--dark);
}

.company-search-header p {
    font-size: 1.1rem;
    color: var(--gray-300);
    margin-bottom: var(--gap); 
    margin-top: 0;
}

.company-search-header .search-form {
    width: 100%;
    max-width: 500px; 
    margin-bottom: 0; 
}

.company-filters {
    display: flex;
    flex-wrap: wrap; 
    gap: .5rem; 
    justify-content: center; 
    width: 100%; 
    max-width: 600px; 
}

.company-filters select {
    padding: .75rem 1rem;
    border: 1px solid var(--gray-200);
    border-radius: .5rem;
    background: #fff;
    font-size: 1rem;
    color: var(--dark);
    cursor: pointer;
    outline: none;
    transition: border-color .2s;
    min-width: 150px;
     -webkit-appearance: none; 
    -moz-appearance: none;
    appearance: none;
    background-image: url('data:image/svg+xml;utf8,<svg fill="%231f2937" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 10l5 5 5-5z"/></svg>');
    background-repeat: no-repeat;
    background-position: right 1rem center;
    background-size: 12px;
}

.company-filters select:hover {
     border-color: var(--gray-300);
}

.company-filters select:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2); 
}

.company-search-results h2 {
    font-size: 1.5rem;
    margin-bottom: var(--gap);
    color: var(--dark);
    border-bottom: 2px solid var(--primary); 
    display: inline-block; 
    padding-bottom: .25rem;
}

.company-list-search {
    display: flex;
    flex-direction: column;
    gap: var(--gap); 
}

.company-card-search {
    background: #fff;
    padding: var(--gap);
    border-radius: .5rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
    display: flex;
    align-items: center; 
    gap: var(--gap);
    text-decoration: none; 
    color: var(--dark); 
    transition: transform .2s ease, box-shadow .2s ease;
    cursor: pointer; 
}

.company-card-search:hover {
    transform: translateY(-3px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, .1);
}

.company-logo-search-placeholder {
    width: 50px; 
    height: 50px;
    background: var(--gray-200);
    border-radius: .3rem;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--gray-500);
    font-size: .8rem;
    overflow: hidden;
     border: 1px solid var(--gray-100);
}

.company-info-search {
    flex-grow: 1; 
    display: flex;
    flex-direction: column;
    gap: .3rem; 
}

.company-info-search h3 {
    font-size: 1.1rem; 
    margin: 0;
    color: var(--dark);
}

.company-meta-search {
    font-size: .9rem;
    color: var(--gray-500);
    margin: 0;
    display: flex; 
    flex-wrap: wrap; 
    align-items: center;
    gap: .5rem; 
}

.company-meta-search i {
     color: var(--primary); 
     font-size: 1rem;
}

.company-meta-search .separator {
     color: var(--gray-300);
}


.open-jobs-search {
    font-size: .95rem;
    color: var(--success); 
    font-weight: 600;
    margin: 0;
    display: flex;
    align-items: center;
    gap: .4rem;
}

.open-jobs-search i {
     font-size: 1rem;
     color: var(--success);
}

.empty-state {
    text-align: center;
    padding: calc(var(--gap) * 2);
    background: #fff;
    border-radius: .5rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
    color: var(--gray-500);
}

.empty-state-icon {
    font-size: 3rem;
    color: var(--gray-300);
    margin-bottom: var(--gap);
}

.empty-state-text {
    font-size: 1.2rem;
    font-weight: 600;
    margin-bottom: .5rem;
    color: var(--dark);
}

.empty-state-subtext {
    font-size: 1rem;
    margin-bottom: 0; 
}

@media (max-width: 768px) {
    .company-search-header h1 {
        font-size: 1.8rem;
    }

    .company-search-header p {
        font-size: 1rem;
    }

     .company-search-header .search-form {
          max-width: 100%; 
     }

    .company-filters {
        flex-direction: column; 
        align-items: stretch;
        gap: .75rem;
         max-width: 100%;
    }

    .company-filters select {
        width: 100%; 
        min-width: auto;
    }

    .company-search-results h2 {
        font-size: 1.3rem;
    }

     .company-card-search {
          flex-direction: column; 
          align-items: flex-start; 
          padding: .8rem;
          gap: .8rem;
     }

     .company-logo-search-placeholder {
          width: 45px;
          height: 45px;
     }

     .company-info-search {
          gap: .5rem;
          align-items: flex-start;
     }

      .company-info-search h3 {
          font-size: 1rem;
     }

     .company-meta-search,
     .open-jobs-search {
          font-size: .85rem;
          flex-direction: column; 
          align-items: flex-start;
          gap: .3rem;
     }

     .company-meta-search span.separator {
          display: none; 
     }
}

@media (max-width: 480px) {
     .company-search-header h1 {
        font-size: 1.6rem;
    }
     .company-card-search {
        padding: .6rem;
        gap: .6rem;
     }
      .company-logo-search-placeholder {
          width: 40px;
          height: 40px;
     }
      .company-info-search h3 {
          font-size: .95rem;
     }
      .company-meta-search,
     .open-jobs-search {
          font-size: .8rem;
          gap: .2rem;
     }
     .company-meta-search i,
      .open-jobs-search i {
          font-size: .9rem;
     }
     .empty-state {
          padding: calc(var(--gap) * 1.5);
     }
      .empty-state-icon {
        font-size: 2.5rem;
        margin-bottom: var(--gap);
    }

    .empty-state-text {
        font-size: 1.1rem;
    }

    .empty-state-subtext {
        font-size: .9rem;
    }
}

Explicación del código: buscar-empresas.css – Página de Búsqueda de Empresas: Encabezado, Filtros y Resultados

/* css/pages/buscar-empresas.css */
Cabecera que identifica este archivo como los estilos de la página “buscar-empresas”.

main {
Define el contenedor principal de la página.

padding: var(--gap);
Aplica un relleno interior en todos los lados según la variable --gap.

display: flex;
Convierte el elemento en un contenedor flex.

flex-direction: column;
Organiza sus hijos en columna (uno debajo de otro).

gap: calc(var(--gap) * 1.5);
Añade un espacio de 1.5 veces --gap entre los elementos hijos.

}

.company-search-header {
Selecciona la sección de cabecera de la búsqueda de empresas.

background: var(--gray-100);
Fondo gris claro tomado de la variable --gray-100.

padding: calc(var(--gap) * 1.5) var(--gap);
Relleno vertical de 1.5×--gap y horizontal de --gap.

text-align: center;
Centra el texto en su interior.

margin-bottom: var(--gap);
Espacio inferior de --gap respecto a la sección siguiente.

border-radius: .5rem;
Bordes redondeados de 0.5 rem.

display: flex;
Contenedor flex para sus elementos internos.

flex-direction: column;
Organiza sus hijos en columna.

align-items: center;
Alinea horizontalmente al centro.

gap: var(--gap);
Espacio de --gap entre los elementos internos.

}

.company-search-header h1 {
Estilo para el título principal dentro de la cabecera.

margin-bottom: .2rem;
Pequeño espacio inferior de 0.2 rem.

font-size: 2rem;
Tamaño de fuente de 2 rem para destacar.

color: var(--dark);
Color de texto oscuro según variable --dark.

}

.company-search-header p {
Estilo para el párrafo descriptivo bajo el título.

font-size: 1.1rem;
Tamaño de fuente de 1.1 rem.

color: var(--gray-300);
Color gris medio para el texto.

margin-bottom: var(--gap);
Espacio inferior de --gap.

margin-top: 0;
Elimina el margen superior que trae por defecto.

}

.company-search-header .search-form {
Selecciona el formulario de búsqueda dentro de la cabecera.

width: 100%;
Ocupa todo el ancho disponible.

max-width: 500px;
Limita su ancho máximo a 500 px.

margin-bottom: 0;
Elimina el espacio inferior.

}

.company-filters {
Contenedor que agrupa los selectores de filtro.

display: flex;
Flexbox para organizar los filtros en fila.

flex-wrap: wrap;
Permite que los filtros pasen a la siguiente línea si faltara espacio.

gap: .5rem;
Espacio de 0.5 rem entre filtros.

justify-content: center;
Centra horizontalmente los filtros.

width: 100%;
Ocupa todo el ancho de su contenedor padre.

max-width: 600px;
Limita su ancho máximo a 600 px.

}

.company-filters select {
Estilos para cada <select> de los filtros.

padding: .75rem 1rem;
Relleno de 0.75 rem vertical y 1 rem horizontal.

border: 1px solid var(--gray-200);
Borde gris claro usando variable.

border-radius: .5rem;
Bordes redondeados de 0.5 rem.

background: #fff;
Fondo blanco.

font-size: 1rem;
Tamaño de texto de 1 rem.

color: var(--dark);
Texto oscuro.

cursor: pointer;
Cursor de mano para indicar interactividad.

outline: none;
Elimina contorno por defecto en focus.

transition: border-color .2s;
Anima el cambio de color de borde.

min-width: 150px;
Ancho mínimo de 150 px.

appearance: none;
Quita estilos nativos del select en todos los navegadores.

background-image: url('data:image/svg+xml;utf8,<svg …/></svg>');
Agrega un icono de flecha SVG como fondo.

background-repeat: no-repeat;
No repite la imagen de fondo.

background-position: right 1rem center;
Posiciona el icono a la derecha con 1 rem de margen.

background-size: 12px;
Ajusta el tamaño del icono a 12 px.

}

.company-filters select:hover {
Estado hover del select.

border-color: var(--gray-300);
Borde cambia a gris medio.

}

.company-filters select:focus {
Estado focus del select.

border-color: var(--primary);
Borde adopta el color primario.

box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2);
Sombra de enfoque sutil para resaltarlo.

}

.company-search-results h2 {
Estilo para el subtítulo de resultados.

font-size: 1.5rem;
Tamaño de fuente de 1.5 rem.

margin-bottom: var(--gap);
Espacio inferior de --gap.

color: var(--dark);
Texto en color oscuro.

border-bottom: 2px solid var(--primary);
Línea decorativa inferior con color primario.

display: inline-block;
Para que la línea solo abarque el ancho del texto.

padding-bottom: .25rem;
Relleno inferior de 0.25 rem.

}

.company-list-search {
Contenedor de las tarjetas de empresa resultantes.

display: flex;
Flexbox para organizarlas en columna.

flex-direction: column;
Una tarjeta debajo de otra.

gap: var(--gap);
Espacio de --gap entre tarjetas.

}

.company-card-search {
Regla base para cada tarjeta de resultado.

background: #fff;
Fondo blanco.

padding: var(--gap);
Relleno interior de --gap.

border-radius: .5rem;
Bordes redondeados.

box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
Sombra suave para dar énfasis.

display: flex;
Flexbox para alinear icono y texto.

align-items: center;
Alinea verticalmente al centro.

gap: var(--gap);
Espacio de --gap entre icono y contenido.

text-decoration: none;
Quita subrayado de enlace.

color: var(--dark);
Texto oscuro.

transition: transform .2s ease, box-shadow .2s ease;
Anima elevación y sombra en hover.

cursor: pointer;
Cursor de mano.

}

.company-card-search:hover {
Estado hover de la tarjeta.

transform: translateY(-3px);
Eleva la tarjeta 3 px hacia arriba.

box-shadow: 0 4px 12px rgba(0, 0, 0, .1);
Sombra más pronunciada.

}

.company-logo-search-placeholder {
Placeholder para el logo dentro de la tarjeta.

width: 50px; height: 50px;
Tamaño fijo de 50×50 px.

background: var(--gray-200);
Fondo gris claro.

border-radius: .3rem;
Bordes ligeramente redondeados.

flex-shrink: 0;
Impide que se encoja.

display: flex; align-items: center; justify-content: center;
Centra su contenido.

color: var(--gray-500);
Color gris medio para iconos o texto interno.

font-size: .8rem;
Texto interno de 0.8 rem.

overflow: hidden;
Oculta contenido desbordado.

border: 1px solid var(--gray-100);
Borde muy claro.

}

.company-info-search {
Contenedor de la información textual dentro de la tarjeta.

flex-grow: 1;
Ocupa todo el espacio horizontal restante.

display: flex; flex-direction: column;
Organiza título y metadatos en columna.

gap: .3rem;
Espacio de 0.3 rem entre líneas de información.

}

.company-info-search h3 {
Nombre de la empresa en la tarjeta.

font-size: 1.1rem;
Tamaño de fuente de 1.1 rem.

margin: 0;
Sin márgenes.

color: var(--dark);
Texto oscuro.

}

.company-meta-search {
Metadatos: industria, ubicación, tamaño.

font-size: .9rem;
Tamaño de fuente de 0.9 rem.

color: var(--gray-500);
Texto gris medio.

margin: 0;
Sin márgenes.

display: flex; flex-wrap: wrap;
Flexbox que envuelve si falta espacio.

align-items: center;
Alinea verticalmente.

gap: .5rem;
Espacio de 0.5 rem entre cada dato.

}

.company-meta-search i {
Iconos dentro de los metadatos.

color: var(--primary);
Color primario para destacar.

font-size: 1rem;
Tamaño de icono de 1 rem.

}

.company-meta-search .separator {
Punto o guion separador entre metadatos.

color: var(--gray-300);
Color gris medio.

}

.open-jobs-search {
Línea que indica número de ofertas abiertas.

font-size: .95rem;
Tamaño de fuente de 0.95 rem.

color: var(--success);
Color verde para enfatizar.

font-weight: 600;
Texto seminegrita.

margin: 0;
Sin márgenes.

display: flex; align-items: center;
Flexbox para icono y texto alineados.

gap: .4rem;
Espacio de 0.4 rem entre icono y número.

}

.open-jobs-search i {
Icono de maletín junto al texto.

font-size: 1rem;
Tamaño de 1 rem.

color: var(--success);
Mismo color verde.

}

.empty-state {
Estilo para estado “no hay resultados”.

text-align: center;
Centra el contenido.

padding: calc(var(--gap) * 2);
Relleno de 2×--gap.

background: #fff;
Fondo blanco.

border-radius: .5rem;
Bordes redondeados.

box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
Sombra suave.

color: var(--gray-500);
Texto gris medio.

}

.empty-state-icon {
Icono grande en el estado vacío.

font-size: 3rem;
Tamaño de 3 rem.

color: var(--gray-300);
Gris claro.

margin-bottom: var(--gap);
Espacio inferior de --gap.

}

.empty-state-text {
Texto principal en el estado vacío.

font-size: 1.2rem;
Tamaño de 1.2 rem.

font-weight: 600;
Seminegrita.

margin-bottom: .5rem;
Espacio inferior de 0.5 rem.

color: var(--dark);
Texto oscuro.

}

.empty-state-subtext {
Texto secundario bajo el principal.

font-size: 1rem;
Tamaño de 1 rem.

margin-bottom: 0;
Sin margen inferior.

}

@media (max-width: 768px) {
Ajustes para pantallas hasta 768 px.

.company-search-header h1 { font-size: 1.8rem; }
Título a 1.8 rem.

.company-search-header p { font-size: 1rem; }
Párrafo a 1 rem.

.company-search-header .search-form { max-width: 100%; }
Formulario ocupa todo el ancho disponible.

.company-filters { flex-direction: column; align-items: stretch; gap: .75rem; max-width: 100%; }
Filtros en columna, estirados al 100% de ancho y gap de 0.75 rem.

.company-filters select { width: 100%; min-width: auto; }
Selects ocupan todo el ancho.

.company-search-results h2 { font-size: 1.3rem; }
Subtítulo de resultados a 1.3 rem.

.company-card-search { flex-direction: column; align-items: flex-start; padding: .8rem; gap: .8rem; }
Tarjetas en columna, alineadas al inicio, padding y gap de 0.8 rem.

.company-logo-search-placeholder { width: 45px; height: 45px; }
Placeholder de logo reducido a 45×45 px.

.company-info-search { gap: .5rem; align-items: flex-start; }
Información con gap de 0.5 rem y alineada al inicio.

.company-info-search h3 { font-size: 1rem; }
Nombre de empresa a 1 rem.

.company-meta-search, .open-jobs-search { font-size: .85rem; flex-direction: column; align-items: flex-start; gap: .3rem; }
Metadatos y ofertas en columna, gap de 0.3 rem y texto de 0.85 rem.

.company-meta-search span.separator { display: none; }
Oculta los separadores en móviles para simplificar.

}

@media (max-width: 480px) {
Ajustes para pantallas menores de 480 px.

.company-search-header h1 { font-size: 1.6rem; }
Título a 1.6 rem.

.company-card-search { padding: .6rem; gap: .6rem; }
Padding y gap internos de 0.6 rem.

.company-logo-search-placeholder { width: 40px; height: 40px; }
Placeholder de logo a 40×40 px.

.company-info-search h3 { font-size: .95rem; }
Nombre de empresa a 0.95 rem.

.company-meta-search, .open-jobs-search { font-size: .8rem; gap: .2rem; }
Texto y gap reducidos para mejor ajuste.

.company-meta-search i, .open-jobs-search i { font-size: .9rem; }
Iconos de 0.9 rem.

.empty-state { padding: calc(var(--gap) * 1.5); }
Relleno de estado vacío ajustado a 1.5×--gap.

.empty-state-icon { font-size: 2.5rem; margin-bottom: var(--gap); }
Icono de estado vacío de 2.5 rem.

.empty-state-text { font-size: 1.1rem; }
Texto principal de estado vacío a 1.1 rem.

.empty-state-subtext { font-size: .9rem; }
Subtexto a 0.9 rem.

}

postulaciones.html

Este archivo HTML define la página “Mis Postulaciones” de EmpleoConnect: importa estilos globales (theme.css, base.css, layout.css, state.css), módulos de interfaz (sidebar.css, logo.css, navigation.css, profile-dropdown.css, sidebar-toggle.css) y la hoja específica postulaciones.css, además de Font Awesome; contiene un <aside class="sidebar"> fijo con logo, navegación lateral y menú de perfil; y un <main> con dos secciones principales: – Encabezado (<section class="applications-header">) con título y subtítulo; – Listado de Postulaciones (<section class="applications-list-container">) donde cada .application-item muestra información del puesto, empresa, fecha de postulación, un .status-badge con icono y estado (Revisada, Entrevista, Enviada, Rechazada), y acciones (ver oferta, mensaje, retirar). Cierra con footer de enlaces y carga los scripts barraLateral.js, desplegablePerfil.js e interaccionesInicio.js.

postulaciones.html – Página “Mis Postulaciones”: Listado de Ofertas Postuladas con Estado, Fecha y Acciones (Ver, Retirar, Mensaje)

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Mis Postulaciones | EmpleoConnect</title>
    <link rel="stylesheet" href="css/theme.css">
    <link rel="stylesheet" href="css/base.css">
    <link rel="stylesheet" href="css/layout.css">
    <link rel="stylesheet" href="css/state.css">
    <link rel="stylesheet" href="css/modules/sidebar.css">
    <link rel="stylesheet" href="css/modules/logo.css">
    <link rel="stylesheet" href="css/modules/navigation.css">
    <link rel="stylesheet" href="css/modules/profile-dropdown.css">
    <link rel="stylesheet" href="css/modules/sidebar-toggle.css">
    <link rel="stylesheet" href="css/pages/postulaciones.css">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">

</head>
<body class="sidebar-visible">
    <button class="sidebar-toggle" id="sidebarToggle">
        <svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
    </button>

    <aside class="sidebar" id="sidebar">
        <div>
            <div class="logo">
                <svg viewBox="0 0 24 24"><path d="M20 7h-4V3c0-1.1-.9-2-2-2h-4c-1.1 0-2 .9-2 2v4H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2z"/><path d="M11 14h2v4h-2zM7 14h2v4H7zM15 14h2v4h-2z"/></svg>
                EmpleoConnect
            </div>
            <div class="category-label">Navegar</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V9z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
                    <span>Inicio</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/></svg>
                    <span>Ofertas</span>
                </li>
                 <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg>
                    <span>Explorar</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
                    <span>Notificaciones</span>
                </li>
                 <li class="nav-item employee-mode" id="employeeModeBtn">
                    <svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg>
                    <span class="mode-text">Modo Empleado</span>
                </li>
            </ul>
            <div class="category-label">Empresas</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M3 21h18M9 8h1M9 12h1M9 16h1M15 8h1M15 12h1M15 16h1M7 21V5a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v16"/></svg>
                    <span>Destacadas</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M4 21v-2a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
                    <span>Buscar</span>
                </li>
            </ul>
        </div>
        <div class="profile" id="profileBtn">
            <div class="profile-info">
                <div class="profile-icon"><svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg></div>
                <div>
                    <div class="username">Usuario</div>
                    <div class="status"><span class="status-indicator"></span><span>En línea</span></div>
                </div>
            </div>
            <ul class="nav-menu profile-links" id="profileLinks">
                <li class="nav-item"><span>Editar Perfil</span></li>
                <li class="nav-item active"><span>Postulaciones</span></li>
                <li class="nav-item logout"><span>Cerrar sesión</span></li>
            </ul>
        </div>
    </aside>

    <main>
        <section class="applications-header">
            <h1>Mis Postulaciones</h1>
            <p>Consulta el estado de las ofertas de empleo a las que te has postulado.</p>
        </section>

        <section class="applications-list-container">
            <div class="application-item">
                 <div class="application-info">
                     <h2 class="job-title">Desarrollador/a Frontend Senior</h2>
                     <p class="company-name">Innovate Solutions</p>
                     <p class="application-date"><i class="far fa-calendar-alt"></i> Postulado el 22 de Abril, 2024</p>
                 </div>
                 <div class="application-status">
                     <span class="status-badge status-reviewed"><i class="fas fa-check-circle"></i> Revisada</span>
                 </div>
                 <div class="application-actions">
                      <a href="#" class="btn-sm btn-secondary"><i class="fas fa-eye"></i> Ver Oferta</a>
                      <button class="btn-sm btn-danger-outline"><i class="fas fa-times-circle"></i> Retirar</button>
                 </div>
            </div>

             <div class="application-item">
                 <div class="application-info">
                     <h2 class="job-title">Ejecutivo/a de Ventas B2B</h2>
                     <p class="company-name">Global Sales Corp</p>
                     <p class="application-date"><i class="far fa-calendar-alt"></i> Postulado el 18 de Abril, 2024</p>
                 </div>
                 <div class="application-status">
                     <span class="status-badge status-interview"><i class="fas fa-comments"></i> Entrevista</span>
                 </div>
                 <div class="application-actions">
                      <a href="#" class="btn-sm btn-secondary"><i class="fas fa-eye"></i> Ver Oferta</a>
                       <a href="#" class="btn-sm btn-primary-outline"><i class="fas fa-envelope"></i> Mensaje</a>
                      <button class="btn-sm btn-danger-outline"><i class="fas fa-times-circle"></i> Retirar</button>
                 </div>
            </div>

             <div class="application-item">
                 <div class="application-info">
                     <h2 class="job-title">Diseñador/a Gráfico Junior</h2>
                     <p class="company-name">Creative Studio Valencia</p>
                     <p class="application-date"><i class="far fa-calendar-alt"></i> Postulado el 15 de Abril, 2024</p>
                 </div>
                 <div class="application-status">
                     <span class="status-badge status-submitted"><i class="fas fa-paper-plane"></i> Enviada</span>
                 </div>
                 <div class="application-actions">
                      <a href="#" class="btn-sm btn-secondary"><i class="fas fa-eye"></i> Ver Oferta</a>
                      <button class="btn-sm btn-danger-outline"><i class="fas fa-times-circle"></i> Retirar</button>
                 </div>
            </div>

              <div class="application-item">
                 <div class="application-info">
                     <h2 class="job-title">Gerente de Proyectos</h2>
                     <p class="company-name">Construcciones & A. Valencia</p>
                     <p class="application-date"><i class="far fa-calendar-alt"></i> Postulado el 10 de Abril, 2024</p>
                 </div>
                 <div class="application-status">
                     <span class="status-badge status-rejected"><i class="fas fa-times-circle"></i> Rechazada</span>
                 </div>
                 <div class="application-actions">
                      <a href="#" class="btn-sm btn-secondary"><i class="fas fa-eye"></i> Ver Oferta</a>
                      </div>
            </div>


            </section>


        <footer>
            <a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
        </footer>
    </main>

    <script src="js/barraLateral.js" defer></script>
    <script src="js/desplegablePerfil.js" defer></script>
    <script src="js/interaccionesInicio.js" defer></script>
</body>
</html>

Explicación del código: postulaciones.html – Página “Mis Postulaciones”: Listado de Ofertas Postuladas con Estado, Fecha y Acciones (Ver, Retirar, Mensaje)

<!DOCTYPE html>
Declara el tipo de documento como HTML5.

<html lang="es">
Abre el elemento raíz y establece el idioma en español.

<head>
Inicia la sección de metadatos del documento.

<meta charset="UTF-8"/>
Define la codificación de caracteres como UTF-8.

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
Ajusta la ventana gráfica para dispositivos móviles.

<title>Mis Postulaciones | EmpleoConnect</title>
Establece el título que aparece en la pestaña del navegador.

<link rel="stylesheet" href="css/theme.css">
Enlaza la hoja de estilos de tema global.

<link rel="stylesheet" href="css/base.css">
Enlaza estilos base (reset y tipografía).

<link rel="stylesheet" href="css/layout.css">
Enlaza estilos de maquetación general.

<link rel="stylesheet" href="css/state.css">
Enlaza clases de estado reutilizables.

<link rel="stylesheet" href="css/modules/sidebar.css">
Estilos específicos del módulo de la barra lateral.

<link rel="stylesheet" href="css/modules/logo.css">
Estilos para el logo del sidebar.

<link rel="stylesheet" href="css/modules/navigation.css">
Estilos para el menú de navegación.

<link rel="stylesheet" href="css/modules/profile-dropdown.css">
Estilos del desplegable de perfil.

<link rel="stylesheet" href="css/modules/sidebar-toggle.css">
Estilos para el botón de alternar sidebar.

<link rel="stylesheet" href="css/pages/postulaciones.css">
Estilos propios de la página “Mis Postulaciones”.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/.../font-awesome.min.css">
Carga Font Awesome para los iconos.

</head>
Cierra la sección de metadatos.

<body class="sidebar-visible">
Abre el cuerpo, con la clase que muestra el sidebar.

<button class="sidebar-toggle" id="sidebarToggle">
Botón para mostrar/ocultar la barra lateral.

<svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
Icono SVG del “hamburger”.

</button>
Cierra el botón de toggle.

<aside class="sidebar" id="sidebar">
Abre el elemento de la barra lateral.

<div>
Contenedor interno para estructura.

<div class="logo">
Sección del logo de la app.

<svg viewBox="0 0 24 24">...</svg>
SVG del icono de la aplicación.

EmpleoConnect
Nombre de la plataforma junto al logo.

</div>
Cierra el contenedor del logo.

<div class="category-label">Navegar</div>
Etiqueta para el grupo de navegación principal.

<ul class="nav-menu">
Lista de elementos de navegación.

<li class="nav-item">...</li>
Ítem “Inicio” con su SVG e texto.

<li class="nav-item">...</li>
Ítem “Ofertas”.

<li class="nav-item">...</li>
Ítem “Explorar”.

<li class="nav-item">...</li>
Ítem “Notificaciones”.

<li class="nav-item employee-mode" id="employeeModeBtn">...</li>
Ítem para cambiar a modo empleado.

</ul>
Cierra la lista de navegación principal.

<div class="category-label">Empresas</div>
Etiqueta para sección de empresas.

<ul class="nav-menu">
Nueva lista de navegación para empresas.

<li class="nav-item">...</li>
Ítem “Destacadas”.

<li class="nav-item">...</li>
Ítem “Buscar”.

</ul>
Cierra la lista de empresas.

</div>
Cierra contenedor interno del sidebar.

<div class="profile" id="profileBtn">
Sección de perfil/relojón.

<div class="profile-info">
Contenedor de información de usuario.

<div class="profile-icon"><svg>...</svg></div>
Icono de usuario.

<div>
Agrupa nombre y estado.

<div class="username">Usuario</div>
Muestra el nombre del usuario.

<div class="status"><span class="status-indicator"></span><span>En línea</span></div>
Indica estado con punto y texto.

</div>
Cierra contenedor de texto.

</div>
Cierra profile-info.

<ul class="nav-menu profile-links" id="profileLinks">
Menú desplegable con enlaces de perfil.

<li class="nav-item"><span>Editar Perfil</span></li>
Opción para editar perfil.

<li class="nav-item active"><span>Postulaciones</span></li>
Opción actual marcada “Postulaciones”.

<li class="nav-item logout"><span>Cerrar sesión</span></li>
Opción para cerrar sesión.

</ul>
Cierra la lista de links de perfil.

</div>
Cierra sección de perfil.

</aside>
Cierra el sidebar.

<main>
Inicia el contenido principal de la página.

<section class="applications-header">
Cabecera de la sección de postulaciones.

<h1>Mis Postulaciones</h1>
Título principal de la página.

<p>Consulta el estado de las ofertas de empleo a las que te has postulado.</p>
Descripción breve.

</section>
Cierra la cabecera.

<section class="applications-list-container">
Contenedor de la lista de aplicaciones.

<div class="application-item">
Tarjeta individual de una postulación.

<div class="application-info">
Datos de la oferta.

<h2 class="job-title">Desarrollador/a Frontend Senior</h2>
Título de la oferta.

<p class="company-name">Innovate Solutions</p>
Nombre de la empresa.

<p class="application-date"><i class="far fa-calendar-alt"></i> Postulado el 22 de Abril, 2024</p>
Fecha de postulación con icono de calendario.

</div>
Cierra application-info.

<div class="application-status">
Estado de la aplicación.

<span class="status-badge status-reviewed"><i class="fas fa-check-circle"></i> Revisada</span>
Badge con icono y texto “Revisada”.

</div>
Cierra application-status.

<div class="application-actions">
Botones de acción para la postulación.

<a href="#" class="btn-sm btn-secondary"><i class="fas fa-eye"></i> Ver Oferta</a>
Enlace para ver detalles.

<button class="btn-sm btn-danger-outline"><i class="fas fa-times-circle"></i> Retirar</button>
Botón para retirar la postulación.

</div>
Cierra application-actions.

</div>
Cierra application-item.

<!-- Repetir application-item para cada postulación -->
Comentario indicando repetición.

</section>
Cierra applications-list-container.

<footer>
Pie de página con enlaces legales.

<a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
Enlaces a políticas.

</footer>
Cierra footer.

</main>
Cierra contenido principal.

<script src="js/barraLateral.js" defer></script>
Script para toggling del sidebar.

<script src="js/desplegablePerfil.js" defer></script>
Script para el desplegable de perfil.

<script src="js/interaccionesInicio.js" defer></script>
Otros comportamientos de la página.

</body>
Cierra el cuerpo.

</html>
Cierra el documento HTML.

postulaciones.css

Este archivo define los estilos exclusivos de la página de postulaciones: configura el espaciado y disposición general, estiliza la cabecera con fondo y tipografías, da formato a cada elemento de la lista con tarjetas, sombras y efectos hover, establece el diseño de badges de estado y botones de acción, incluye el estilo para la vista vacía y adapta la disposición y tamaños de texto en distintos anchos de pantalla mediante media queries.

postulaciones.css – Estilos para “Mis Postulaciones”: cabecera, lista de postulaciones, tarjetas de aplicación con título, empresa, fecha, estado y botones de acción adaptables

/* css/pages/postulaciones.css */

main {
    padding: var(--gap);
    display: flex;
    flex-direction: column;
    gap: calc(var(--gap) * 1.5);
}

.applications-header {
    background: var(--gray-100);
    padding: calc(var(--gap) * 1.5) var(--gap);
    text-align: center;
    margin-bottom: var(--gap);
    border-radius: .5rem;
}

.applications-header h1 {
    margin-bottom: .5rem;
    font-size: 2rem;
    color: var(--dark);
}

.applications-header p {
    font-size: 1.1rem;
    color: var(--gray-300);
    margin: 0;
}

.applications-list-container {
    display: flex;
    flex-direction: column;
    gap: var(--gap);
}

.application-item {
    background: #fff;
    padding: var(--gap);
    border-radius: .5rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
    display: flex;
    align-items: center;
    gap: var(--gap);
    transition: box-shadow .2s ease, transform .1s ease;
    cursor: pointer;
}

.application-item:hover {
     box-shadow: 0 4strap 12px rgba(0, 0, 0, .1);
     transform: translateY(-2px);
}


.application-info {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    gap: .3rem;
}

.application-info .job-title {
    font-size: 1.2rem;
    font-weight: 600;
    color: var(--dark);
    margin: 0;
}

.application-info .company-name {
    font-size: 1rem;
    color: var(--primary);
    margin: 0;
}

.application-info .application-date {
    font-size: .9rem;
    color: var(--gray-500);
    margin: 0;
     display: flex;
     align-items: center;
     gap: .3rem;
}

.application-info .application-date i {
    font-size: .95rem;
    color: var(--gray-400);
}

.application-status {
    flex-shrink: 0;
    margin-left: auto;
    align-self: center;
}

.status-badge {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .4rem .8rem;
    border-radius: 1rem;
    font-size: .85rem;
    font-weight: 600;
    text-transform: uppercase;
    color: #fff;
}

.status-submitted {
    background: var(--gray-400);
}

.status-reviewed {
    background: var(--info);
}

.status-interview {
    background: var(--success);
}

.status-rejected {
    background: var(--danger);
}

.application-actions {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: .5rem;
    align-items: stretch;
}

.btn-sm {
    display: inline-flex;
    align-items: center;
    justify-content: center; /
    padding: .5rem 1rem;
    font-size: .9rem;
    font-weight: 600;
    border-radius: .3rem;
    cursor: pointer;
    text-decoration: none;
    transition: background .2s, color .2s, border-color .2s;
     gap: .4rem;
}

.btn-secondary {
     background: var(--gray-200);
     color: var(--dark);
     border: 1px solid var(--gray-200);
}

.btn-secondary:hover {
    background: var(--gray-300);
    border-color: var(--gray-300);
}

.btn-danger-outline {
    background: none;
    color: var(--danger);
    border: 1px solid var(--danger);
}

.btn-danger-outline:hover {
    background: var(--danger);
    color: #fff;
}

.btn-primary-outline {
    background: none;
    color: var(--primary);
    border: 1px solid var(--primary);
}

.btn-primary-outline:hover {
    background: var(--primary);
    color: #fff;
}

.empty-state {
    text-align: center;
    padding: calc(var(--gap) * 2);
    background: #fff;
    border-radius: .5rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .05);
    color: var(--gray-500);
}

.empty-state-icon {
    font-size: 3rem;
    color: var(--gray-300);
    margin-bottom: var(--gap);
}

.empty-state-text {
    font-size: 1.2rem;
    font-weight: 600;
    margin-bottom: .5rem;
    color: var(--dark);
}

.empty-state-subtext {
    font-size: 1rem;
    margin-bottom: calc(var(--gap) * 1.5);
}

.empty-state .btn-primary {
    display: inline-block;
    padding: .75rem 1.5rem;
    background: var(--primary);
    color: #fff;
    border-radius: .5rem;
    text-decoration: none;
    font-weight: 600;
    transition: background .2s;
}

.empty-state .btn-primary:hover {
    background: var(--primary-dark);
}

@media (max-width: 992px) {
     .application-item {
         flex-wrap: wrap;
         align-items: flex-start;
         gap: .8rem;
     }

      .application-info {
         flex-basis: 100%;
         gap: .4rem;
     }

     .application-status {
         margin-left: 0;
         order: -1;
         align-self: flex-start;
     }

     .application-actions {
         flex-direction: row;
         flex-basis: 100%;
         gap: .5rem;
         justify-content: flex-end;
     }

      .btn-sm {
          padding: .4rem .8rem;
          font-size: .85rem;
          gap: .3rem;
      }
}


@media (max-width: 768px) {
    .applications-header h1 {
        font-size: 1.8rem;
    }

    .applications-header p {
        font-size: 1rem;
    }

     .application-item {
        padding: .8rem;
        gap: .6rem;
     }

     .application-info .job-title {
         font-size: 1.1rem;
     }
      .application-info .company-name {
         font-size: .95rem;
     }
      .application-info .application-date {
         font-size: .85rem;
     }

     .status-badge {
         font-size: .8rem;
         padding: .3rem .6rem;
     }

     .application-actions {
          flex-direction: column;
          align-items: stretch;
          gap: .5rem;
          justify-content: flex-start;
     }

      .btn-sm {
           width: 100%;
           padding: .6rem 1rem;
           font-size: .9rem;
     }

      .empty-state {
          padding: calc(var(--gap) * 1.5);
     }
      .empty-state-icon {
        font-size: 2.5rem;
        margin-bottom: var(--gap);
    }

    .empty-state-text {
        font-size: 1.1rem;
    }

    .empty-state-subtext {
        font-size: .9rem;
    }

    .empty-state .btn-primary {
        padding: .6rem 1.2rem;
        font-size: .9rem;
    }
}

@media (max-width: 480px) {
     .applications-header h1 {
        font-size: 1.6rem;
    }
     .application-item {
        padding: .6rem;
        gap: .5rem;
     }
      .application-info .job-title {
         font-size: 1rem;
     }
      .application-info .company-name {
         font-size: .9rem;
     }
      .application-info .application-date {
         font-size: .8rem;
     }

     .status-badge {
         font-size: .75rem;
         padding: .2rem .5rem;
         gap: .3rem;
     }
      .application-info .application-date i,
     .status-badge i {
         font-size: .8rem;
     }

     .btn-sm {
          padding: .5rem .8rem;
          font-size: .85rem;
     }
}

Explicación del código: postulaciones.css – Estilos para “Mis Postulaciones”: cabecera, lista de postulaciones, tarjetas de aplicación con título, empresa, fecha, estado y botones de acción adaptables

/* css/pages/postulaciones.css */
Indica la ruta y nombre del archivo de estilos específico para la página de postulaciones.

main { … }
Aplica relleno según la variable --gap, organiza el contenido en columna con flexbox y establece espacio vertical de 1.5·--gap entre elementos.

.applications-header { … }
Define un fondo gris claro, padding vertical de 1.5·--gap y horizontal de --gap, centra el texto, separa del siguiente bloque con --gap y redondea esquinas.

.applications-header h1 { … }
Ajusta el margen inferior a 0.5 rem, el tamaño de fuente a 2 rem y el color al valor de la variable --dark.

.applications-header p { … }
Fija la fuente a 1.1 rem, el color a --gray-300 y elimina márgenes.

.applications-list-container { … }
Convierte el contenedor de la lista en un flex column y añade separación vertical igual a --gap.

.application-item { … }
Cada elemento recibe fondo blanco, padding --gap, bordes redondeados, sombra suave, flex horizontal centrado verticalmente, espacio --gap y transición suave al interactuar; cambia el cursor a puntero.

.application-item:hover { … }
Aumenta la sombra y eleva ligeramente el bloque al pasar el ratón.

.application-info { … }
En el área de información, permite que crezca, usa flex column y deja 0.3 rem entre líneas.

.application-info .job-title { … }
Título del puesto: fuente de 1.2 rem, negrita 600, color --dark y sin márgenes.

.application-info .company-name { … }
Nombre de la empresa con fuente de 1 rem, color --primary y sin márgenes.

.application-info .application-date { … }
Fecha con fuente de 0.9 rem, color --gray-500, sin márgenes; la organiza en flex row con icono y deja 0.3 rem de espacio.

.application-info .application-date i { … }
Icono de fecha con tamaño de 0.95 rem y color --gray-400.

.application-status { … }
La sección de estado no se encoge, se empuja al margen izquierdo automático y se centra verticalmente.

.status-badge { … }
Define los badges como elementos inline-flex, centra su contenido, añade padding (.4 × .8 rem), bordes redondeados, texto en mayúsculas, negrita y color blanco.

.status-submitted { background: var(--gray-400); }
Badge “enviado” con fondo gris medio.

.status-reviewed { background: var(--info); }
Badge “revisado” con fondo según variable de información.

.status-interview { background: var(--success); }
Badge “entrevista” con fondo verde (éxito).

.status-rejected { background: var(--danger); }
Badge “rechazado” con fondo rojo (peligro).

.application-actions { … }
Contenedor de botones con flex column, separándolos 0.5 rem y estirándolos al ancho disponible.

.btn-sm { … }
Botones pequeños como inline-flex, centrados, con padding .5×1 rem, fuente .9 rem, negrita 600, bordes redondeados .3 rem, transición de fondo/color/borde y separación de 0.4 rem.

.btn-secondary { … }
Variante secundaria con fondo gris claro, texto oscuro y borde gris.

.btn-secondary:hover { … }
Al pasar el ratón, oscurece ligeramente el fondo y el borde.

.btn-danger-outline { … }
Botón de peligro en outline: sin fondo, texto y borde rojos.

.btn-danger-outline:hover { … }
Al pasar, fondo rojo y texto blanco.

.btn-primary-outline { … }
Versión primaria en outline: sin fondo, texto y borde azules.

.btn-primary-outline:hover { … }
Al pasar, fondo azul y texto blanco.

.empty-state { … }
Estado vacío centrado, con padding 2·--gap, fondo blanco, bordes redondeados, sombra suave y texto gris medio.

.empty-state-icon { … }
Icono grande de 3 rem, color gris claro y margen inferior de --gap.

.empty-state-text { … }
Texto principal de estado vacío con fuente 1.2 rem, negrita 600, margen inferior .5 rem y color --dark.

.empty-state-subtext { … }
Subtexto con tamaño 1 rem y margen inferior 1.5·--gap.

.empty-state .btn-primary { … }
Botón primario en estado vacío como inline-block, padding .75×1.5 rem, fondo primario, texto blanco, bordes .5 rem, sin subrayado y transición de fondo.

.empty-state .btn-primary:hover { background: var(--primary-dark); }
Al pasar, cambia a tono primario oscuro.

@media (max-width: 992px) { … }
Adapta .application-item para envolverse y reorganizarse, ajusta .application-info, mueve badge de estado arriba y pone acciones en fila al final, además reduce padding y espacios de .btn-sm.

@media (max-width: 768px) { … }
Reduce tamaños de texto en encabezado, párrafos y elementos de aplicación; ajusta padding y gap de items; estiliza badges y botones para móvil manteniendo legibilidad.

@media (max-width: 480px) { … }
Ajusta aún más los tamaños de fuente, padding y espacios en títulos, items, badges e iconos, y redimensiona botones para pantallas muy pequeñas.

login.html

En este archivo se define la vista de inicio de sesión: se cargan los estilos globales (theme.css, base.css) y los específicos de login.css, se muestra una tarjeta centrada con el logo de EmpleoConnect, el título “Iniciar Sesión” y un texto descriptivo; a continuación aparece el formulario con los campos de email/usuario y contraseña, el botón de envío y, bajo él, enlaces para recuperar la contraseña o registrarse, además de un pequeño script que gestiona la captura del envío mostrando los datos ingresados.

login.html – Estructura HTML para la pantalla de Iniciar Sesión.

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Iniciar Sesión | EmpleoConnect</title>
    <link rel="stylesheet" href="css/theme.css">
    <link rel="stylesheet" href="css/base.css">

    <link rel="stylesheet" href="css/pages/login.css">

    </head>
<body>
    <div class="login-container">
        <div class="login-card">
            <div class="login-header">
                <div class="logo centered">
                    <svg viewBox="0 0 24 24"><path d="M20 7h-4V3c0-1.1-.9-2-2-2h-4c-1.1 0-2 .9-2 2v4H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2z"/><path d="M11 14h2v4h-2zM7 14h2v4H7zM15 14h2v4h-2z"/></svg>
                    EmpleoConnect
                </div>
                <h2>Iniciar Sesión</h2>
                <p>Accede a tu cuenta para encontrar el empleo ideal.</p>
            </div>

            <form id="loginForm" class="login-form">
                <div class="form-group">
                    <label for="email">Email o Usuario:</label>
                    <input type="text" id="email" name="email" placeholder="ejemplo@correo.com" required/>
                </div>
                <div class="form-group">
                    <label for="password">Contraseña:</label>
                    <input type="password" id="password" name="password" placeholder="Tu contraseña" required/>
                </div>

                <button type="submit" class="btn-primary-lg full-width">Iniciar Sesión</button>
            </form>

            <div class="login-footer">
                <p>¿Olvidaste tu contraseña? <a href="#">Recuperar aquí</a></p>
                <p>¿No tienes cuenta? <a href="#">Regístrate ahora</a></p>
            </div>
        </div>
    </div>
</body>
</html>

Explicación del código: login.html – Estructura HTML para la pantalla de Iniciar Sesión.

<!DOCTYPE html>
Indica al navegador que es un documento HTML5 y activa el modo de renderizado estándar.

<html lang="es">
Marca el inicio del documento y especifica que el idioma principal es español.

<head>
Contiene metadatos y enlaces a estilos; no se muestra en el cuerpo de la página.

<meta charset="UTF-8"/>
Define la codificación de caracteres como UTF-8 para soportar acentos y caracteres especiales.

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
Ajusta la escala y ancho de la página al dispositivo, esencial para diseño responsivo.

<title>Iniciar Sesión | EmpleoConnect</title>
Texto que aparece en la pestaña del navegador y en los marcadores.

<link rel="stylesheet" href="css/theme.css">
Enlaza la hoja de estilos que define colores, tipografías y variables de tema.

<link rel="stylesheet" href="css/base.css">
Importa estilos globales básicos: reset, tipografía base y utilidades.

<link rel="stylesheet" href="css/pages/login.css">
Aplica reglas CSS específicas para la página de inicio de sesión.

</head>
Cierra la sección de metadatos y estilos.

<body>
Comienza el contenido visible de la página.

<div class="login-container">
Contenedor principal que centra vertical y horizontalmente el formulario.

<div class="login-card">
Caja con fondo, bordes redondeados y sombra que agrupa todo el contenido de login.

<div class="login-header">
Sección superior con logo, título y descripción.

<div class="logo centered">
Contiene el logotipo SVG y el nombre de la aplicación, centrado.

<svg viewBox="0 0 24 24"><path …/></svg>
Icono vectorial de un maletín para representar EmpleoConnect.

EmpleoConnect
Nombre de la plataforma junto al icono.

</div>
Cierra el bloque del logo.

<h2>Iniciar Sesión</h2>
Título de segundo nivel que indica la acción a realizar.

<p>Accede a tu cuenta para encontrar el empleo ideal.</p>
Descripción breve que motiva al usuario.

</div>
Finaliza la cabecera de login.

<form id="loginForm" class="login-form">
Inicio del formulario, con identificador y clase para estilo y validación.

<div class="form-group">
AgrupaEtiqueta e input para un campo de entrada.

<label for="email">Email o Usuario:</label>
Texto descriptivo vinculado al input de correo/usuario.

<input type="text" id="email" name="email" placeholder="ejemplo@correo.com" required/>
Campo de texto obligatorio con marcador de ejemplo.

</div>
Cierra el grupo de email.

<div class="form-group">
Agrupa la etiqueta e input para la contraseña.

<label for="password">Contraseña:</label>
Indica al usuario que ingrese su clave.

<input type="password" id="password" name="password" placeholder="Tu contraseña" required/>
Campo de contraseña ocultada, obligatorio.

</div>
Cierra el grupo de contraseña.

<button type="submit" class="btn-primary-lg full-width">Iniciar Sesión</button>
Botón grande y de ancho completo que envía el formulario.

</form>
Termina el formulario de login.

<div class="login-footer">
Pie de la tarjeta que muestra enlaces de ayuda y registro.

<p>¿Olvidaste tu contraseña? <a href="#">Recuperar aquí</a></p>
Enlace para recuperación de contraseña.

<p>¿No tienes cuenta? <a href="#">Regístrate ahora</a></p>
Enlace para crear una nueva cuenta.

</div>
Cierra el pie de página de login.

</div>
Cierra la tarjeta de login.

</div>
Cierra el contenedor principal.

</body>
Finaliza el contenido visible del documento.

</html>
Cierra el elemento raíz y marca el fin del documento HTML.

login.css

Este archivo contiene los estilos específicos de la página de inicio de sesión: establece un fondo claro y centra la tarjeta de acceso, define el espaciado y apariencia de formularios y botones, aplica sombras y bordes redondeados, ajusta colores y tipografías de encabezados y texto, controla el enfoque de los campos de entrada y adapta el diseño a dispositivos móviles mediante media queries.

login.css – CSS de Login: Estilos y Responsividad

/* css/pages/login.css */

body {
    background: var(--light);
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    padding: var(--gap);
}

.login-container {
    width: 100%;
    max-width: 400px;
}

.login-card {
    background: #fff;
    padding: calc(var(--gap) * 2);
    border-radius: .75rem;
    box-shadow: 0 10px 25px rgba(0, 0, 0, .1);
    display: flex;
    flex-direction: column;
    gap: calc(var(--gap) * 1.5);
}

.login-header {
    text-align: center;
}

.login-header .logo {
     justify-content: center;
     margin-bottom: var(--gap);
     border-bottom: none;
     padding: 0;
}

.login-header h2 {
    font-size: 1.8rem;
    margin-bottom: .5rem;
    color: var(--dark);
}

.login-header p {
    font-size: 1rem;
    color: var(--gray-500);
    margin: 0;
}

.login-form {
    display: flex;
    flex-direction: column;
    gap: var(--gap);
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.form-group label {
    font-size: .95rem;
    font-weight: 500;
    color: var(--dark);
}

.form-group input[type="text"],
.form-group input[type="password"] {
    padding: .75rem 1rem;
    border: 1px solid var(--gray-200);
    border-radius: .5rem;
    font-size: 1rem;
    color: var(--dark);
    transition: border-color .2s, box-shadow .2s;
    width: 100%;
    box-sizing: border-box;
    outline: none;
}

.form-group input[type="text"]:focus,
.form-group input[type="password"]:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2);
}

.btn-primary-lg.full-width {
    display: block;
    width: 100%;
    padding: .9rem 1.5rem;
    font-size: 1.1rem;
     background: var(--primary);
     color: #fff;
     border: none;
     border-radius: .5rem;
     cursor: pointer;
     font-weight: 600;
     text-align: center;
     transition: background .2s ease, transform .1s ease;
     box-shadow: 0 4px 10px rgba(37, 99, 235, 0.3);
}

.btn-primary-lg.full-width:hover {
     background: var(--primary-dark);
      transform: translateY(-2px);
       box-shadow: 0 6px 12px rgba(37, 99, 235, 0.4);
}


.login-footer {
    text-align: center;
    font-size: .95rem;
    color: var(--gray-500);
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.login-footer a {
    color: var(--primary);
    text-decoration: none;
    font-weight: 500;
    transition: color .2s;
}

.login-footer a:hover {
    color: var(--primary-dark);
    text-decoration: underline;
}

@media (max-width: 480px) {
     .login-card {
         padding: var(--gap);
         gap: var(--gap);
     }

     .login-header h2 {
         font-size: 1.6rem;
         margin-bottom: .3rem;
     }

     .login-header p {
         font-size: .9rem;
     }

     .login-form {
         gap: .8rem;
     }

     .form-group label {
         font-size: .9rem;
     }

     .form-group input[type="text"],
    .form-group input[type="password"] {
         padding: .6rem .8rem;
         font-size: .9rem;
     }

     .btn-primary-lg.full-width {
         padding: .8rem 1.2rem;
         font-size: 1rem;
     }

     .login-footer {
         font-size: .9rem;
         gap: .4rem;
     }
}

Explicación del código: login.css – CSS de Login: Estilos y Responsividad

/* css/pages/login.css */
Comentario que indica la ruta y nombre del archivo de estilos específico para la página de inicio de sesión.

body { … }
Aplica fondo claro, convierte el <body> en un contenedor flex para centrar vertical y horizontalmente, asegura altura mínima de 100 vh y añade padding según la variable --gap.

.login-container { … }
Define un ancho del 100 % y limita el contenedor a un máximo de 400 px para mantener el formulario centrado y con tamaño adecuado.

.login-card { … }
Estilo de la tarjeta de login: fondo blanco, padding doble de --gap, bordes redondeados de .75 rem, sombra pronunciada y flex column con separación de 1.5·--gap.

.login-header { … }
Centra el texto de la cabecera del formulario.

.login-header .logo { … }
Ajusta el contenedor del logo: lo centra, elimina borde inferior y padding extra, y añade margen inferior de --gap.

.login-header h2 { … }
Título principal con tamaño 1.8 rem, color oscuro (--dark) y margen inferior de .5 rem.

.login-header p { … }
Subtítulo con fuente de 1 rem, color gris medio (--gray-500) y sin márgenes.

.login-form { … }
Convierte el formulario en flex column, con separación vertical igual a --gap.

.form-group { … }
Cada grupo de label e input usa flex column y deja .5 rem de espacio entre ellos.

.form-group label { … }
Etiquetas con tamaño .95 rem, peso 500 y color oscuro (--dark).

.form-group input[type="text"], .form-group input[type="password"] { … }
Campos de entrada con padding .75×1 rem, borde gris claro, bordes redondeados .5 rem, fuente 1 rem, color oscuro, transición de borde y sombra, ancho 100 % y caja incluida en el tamaño total.

.form-group input[type="text"]:focus, .form-group input[type="password"]:focus { … }
Al enfocar el campo, el borde cambia a color primario y aparece una sombra difusa alrededor.

.btn-primary-lg.full-width { … }
Botón principal de ancho completo: padding .9×1.5 rem, fuente 1.1 rem, fondo primario, texto blanco, sin borde, bordes .5 rem, cursor pointer, negrita 600, centrado, transición de fondo y transform, y sombra de color primario.

.btn-primary-lg.full-width:hover { … }
Al pasar el ratón, oscurece el fondo, eleva el botón 2 px y aumenta la sombra.

.login-footer { … }
Pie del formulario con texto centrado, fuente .95 rem, color gris medio y flex column con .5 rem de separación.

.login-footer a { … }
Enlaces con color primario, sin subrayado, peso 500 y transición de color.

.login-footer a:hover { … }
Al pasar el ratón, el enlace cambia a color primario oscuro y se subraya.

@media (max-width: 480px) {
Ajustes para pantallas pequeñas (≤ 480 px):

19.1. .login-card { padding: var(--gap); gap: var(--gap); }
Reduce padding y separación interna.

19.2. .login-header h2 { font-size: 1.6rem; margin-bottom: .3rem; }
Disminuye tamaño y margen del título.

19.3. .login-header p { font-size: .9rem; }
Reduce el tamaño del subtítulo.

19.4. .login-form { gap: .8rem; }
Ajusta el espacio entre campos.

19.5. .form-group label { font-size: .9rem; }
Hace las etiquetas un poco más pequeñas.

19.6. .form-group input[type="text"], .form-group input[type="password"] { padding: .6rem .8rem; font-size: .9rem; }
Reduce padding y tamaño de fuente de los inputs.

19.7. .btn-primary-lg.full-width { padding: .8rem 1.2rem; font-size: 1rem; }
Ajusta padding y tamaño del botón para móviles.

19.8. .login-footer { font-size: .9rem; gap: .4rem; }
Reduce tamaño de fuente y separación del pie de página.

} cierre del bloque de media queries.

registrarse.html

En este archivo se configura la página de registro: se cargan los estilos globales (theme.css, base.css) y los específicos de registrarse.css, se muestra una tarjeta centrada con el logo de EmpleoConnect, el título “Crear una cuenta” y un texto introductorio; a continuación aparece el formulario con los campos de Nombre Completo, Email, Contraseña y Confirmar Contraseña, el botón de envío y, al pie, un enlace para cambiar a la vista de inicio de sesión.

registrarse.html – Estructura HTML para la pantalla de Registro

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Registrarse | EmpleoConnect</title>
    <link rel="stylesheet" href="css/theme.css">
    <link rel="stylesheet" href="css/base.css">

    <link rel="stylesheet" href="css/pages/registrarse.css">

    </head>
<body>
    <div class="register-container">
        <div class="register-card">
            <div class="register-header">
                <div class="logo centered">
                    <svg viewBox="0 0 24 24"><path d="M20 7h-4V3c0-1.1-.9-2-2-2h-4c-1.1 0-2 .9-2 2v4H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2z"/><path d="M11 14h2v4h-2zM7 14h2v4H7zM15 14h2v4h-2z"/></svg>
                    EmpleoConnect
                </div>
                <h2>Crear una cuenta</h2>
                <p>Únete a EmpleoConnect para encontrar las mejores oportunidades laborales.</p>
            </div>

            <form id="registerForm" class="register-form">
                 <div class="form-group">
                    <label for="full-name">Nombre Completo:</label>
                    <input type="text" id="full-name" name="fullName" placeholder="Tu nombre y apellidos" required/>
                </div>
                <div class="form-group">
                    <label for="email">Email:</label>
                    <input type="email" id="email" name="email" placeholder="tu@correo.com" required/>
                </div>
                <div class="form-group">
                    <label for="password">Contraseña:</label>
                    <input type="password" id="password" name="password" placeholder="Crea una contraseña" required/>
                </div>
                 <div class="form-group">
                    <label for="confirm-password">Confirmar Contraseña:</label>
                    <input type="password" id="confirm-password" name="confirmPassword" placeholder="Repite la contraseña" required/>
                </div>

                <button type="submit" class="btn-primary-lg full-width">Registrarse</button>
            </form>

            <div class="register-footer">
                <p>¿Ya tienes cuenta? <a href="login.html">Iniciar sesión aquí</a></p>
            </div>
        </div>
    </div>
</body>
</html>

Explicación del código: registrarse.html – Estructura HTML para la pantalla de Registro.

<!DOCTYPE html> indica que el documento usa la versión HTML5.

<html lang="es"> abre el elemento raíz y define el idioma de la página como español.

<head> inicia la sección de metadatos y enlaces a recursos externos.

<meta charset="UTF-8"/> establece la codificación de caracteres en UTF-8 para soportar caracteres especiales.

<meta name="viewport" content="width=device-width, initial-scale=1.0"/> ajusta el zoom y ancho de la página al tamaño del dispositivo, clave para el diseño responsivo.

<title>Registrarse | EmpleoConnect</title> fija el texto que aparecerá en la pestaña del navegador.

<link rel="stylesheet" href="css/theme.css"> importa la hoja de estilo con variables de tema, paleta de colores y tipografías.

<link rel="stylesheet" href="css/base.css"> enlaza los estilos básicos globales, como reset y utilidades comunes.

(línea en blanco para separación visual)

<link rel="stylesheet" href="css/pages/registrarse.css"> carga estilos específicos para la página de registro.

(línea en blanco)

</head> cierra la sección de metadatos y recursos.

<body> comienza el contenido visible de la página.

<div class="register-container"> crea un contenedor que centra y limita el ancho de la tarjeta de registro.

<div class="register-card"> representa la tarjeta con fondo, sombra y esquinas redondeadas donde va el formulario.

<div class="register-header"> define la cabecera interna con logo, título y descripción.

<div class="logo centered"> agrupa el icono SVG y el nombre de la plataforma, centrados horizontalmente.

<svg viewBox="0 0 24 24"><path d="M20 7h-4V3…"/></svg> muestra un icono de maletín mediante un gráfico vectorial.

EmpleoConnect presenta el nombre de la aplicación junto al icono.

</div> cierra el bloque del logo.

<h2>Crear una cuenta</h2> muestra el título de segundo nivel de la página.

<p>Únete a EmpleoConnect para encontrar las mejores oportunidades laborales.</p> ofrece una breve invitación al usuario.

</div> finaliza la cabecera de la tarjeta.

(línea en blanco)

<form id="registerForm" class="register-form"> abre el formulario de registro, con identificador y clase para estilos y validaciones.

<div class="form-group"> inicia el grupo de elementos que contiene etiqueta y campo para el nombre completo.

<label for="full-name">Nombre Completo:</label> describe el campo y lo vincula al input correspondiente.

<input type="text" id="full-name" name="fullName" placeholder="Tu nombre y apellidos" required/> crea un campo de texto obligatorio con texto de ayuda.

</div> cierra el grupo del nombre completo.

<div class="form-group"> agrupa etiqueta e input para el correo electrónico.

<label for="email">Email:</label> indica al usuario que ingrese su dirección de correo.

<input type="email" id="email" name="email" placeholder="tu@correo.com" required/> genera un campo de tipo email con validación y marcador de posición.

</div> cierra el grupo del email.

<div class="form-group"> inicia el grupo de contraseña.

<label for="password">Contraseña:</label> etiqueta el campo de contraseña.

<input type="password" id="password" name="password" placeholder="Crea una contraseña" required/> crea un campo que oculta la entrada y es obligatorio.

</div> cierra el grupo de contraseña.

<div class="form-group"> abre el grupo para confirmar contraseña.

<label for="confirm-password">Confirmar Contraseña:</label> etiqueta el campo de confirmación.

<input type="password" id="confirm-password" name="confirmPassword" placeholder="Repite la contraseña" required/> establece otro campo de contraseña para la repetición obligatoria.

</div> cierra el grupo de confirmación.

(línea en blanco)

<button type="submit" class="btn-primary-lg full-width">Registrarse</button> crea un botón grande y de ancho completo que envía el formulario.

</form> finaliza el formulario de registro.

(línea en blanco)

<div class="register-footer"> inicia el pie de la tarjeta con enlace a la página de login.

<p>¿Ya tienes cuenta? <a href="login.html">Iniciar sesión aquí</a></p> ofrece al usuario la opción de acceder si ya está registrado.

</div> cierra el pie de la tarjeta.

</div> cierra la tarjeta de registro.

</div> cierra el contenedor principal de la página.

</body> cierra el cuerpo del documento.

</html> cierra el elemento raíz y marca el fin del archivo HTML.

registrarse.css

Este archivo contiene los estilos específicos de la página de registro: establece un fondo claro y centra la tarjeta de registro, define el espaciado, sombras y bordes redondeados del formulario, formatea campos de entrada y el botón principal, controla la tipografía y colores, y adapta el diseño y tamaños para dispositivos móviles mediante media queries.

registrarse.css – CSS de Registro: Estilos y Responsividad

/* css/pages/registrarse.css */

body {
    background: var(--light);
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
    padding: var(--gap);
    overflow-y: auto;
}

.register-container {
    width: 100%;
    max-width: 450px;
}

.register-card {
    background: #fff;
    padding: calc(var(--gap) * 2);
    border-radius: .75rem;
    box-shadow: 0 10px 25px rgba(0, 0, 0, .1);
    display: flex;
    flex-direction: column;
    gap: calc(var(--gap) * 1.5);
}

.register-header {
    text-align: center;
}

.register-header .logo {
     justify-content: center;
     margin-bottom: var(--gap);
     border-bottom: none;
     padding: 0;
}

.register-header h2 {
    font-size: 1.8rem;
    margin-bottom: .5rem;
    color: var(--dark);
}

.register-header p {
    font-size: 1rem;
    color: var(--gray-500);
    margin: 0;
}

.register-form {
    display: flex;
    flex-direction: column;
    gap: var(--gap);
}

.form-group {
    display: flex;
    flex-direction: column;
    gap: .5rem;
}

.form-group label {
    font-size: .95rem;
    font-weight: 500;
    color: var(--dark);
}

.form-group input[type="text"],
.form-group input[type="email"],
.form-group input[type="password"] {
    padding: .75rem 1rem;
    border: 1px solid var(--gray-200);
    border-radius: .5rem;
    font-size: 1rem;
    color: var(--dark);
    transition: border-color .2s, box-shadow .2s;
    width: 100%;
    box-sizing: border-box;
    outline: none;
}

.form-group input[type="text"]:focus,
.form-group input[type="email"]:focus,
.form-group input[type="password"]:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2);
}

.btn-primary-lg.full-width {
    display: block;
    width: 100%;
    padding: .9rem 1.5rem;
    font-size: 1.1rem;
     background: var(--primary);
     color: #fff;
     border: none;
     border-radius: .5rem;
     cursor: pointer;
     font-weight: 600;
     text-align: center;
     transition: background .2s ease, transform .1s ease;
     box-shadow: 0 4px 10px rgba(37, 99, 235, 0.3);
}

.btn-primary-lg.full-width:hover {
     background: var(--primary-dark);
      transform: translateY(-2px);
       box-shadow: 0 6px 12px rgba(37, 99, 235, 0.4);
}

.register-footer {
    text-align: center;
    font-size: .95rem;
    color: var(--gray-500);
}

.register-footer a {
    color: var(--primary);
    text-decoration: none;
    font-weight: 500;
    transition: color .2s;
}

.register-footer a:hover {
    color: var(--primary-dark);
    text-decoration: underline;
}

@media (max-width: 480px) {
     .register-card {
         padding: var(--gap);
         gap: var(--gap);
     }

     .register-header h2 {
         font-size: 1.6rem;
         margin-bottom: .3rem;
     }

     .register-header p {
         font-size: .9rem;
     }

     .register-form {
         gap: .8rem;
     }

     .form-group label {
         font-size: .9rem;
     }

     .form-group input[type="text"],
    .form-group input[type="email"],
    .form-group input[type="password"] {
         padding: .6rem .8rem;
         font-size: .9rem;
     }

     .btn-primary-lg.full-width {
         padding: .8rem 1.2rem;
         font-size: 1rem;
     }

     .register-footer {
         font-size: .9rem;
     }
}

Explicación del código: registrarse.css – CSS de Registro: Estilos y Responsividad

/* css/pages/registrarse.css */
Indica que este archivo contiene los estilos específicos de la página de registro.

body { background: var(--light); display: flex; justify-content: center; align-items: center; min-height: 100vh; padding: var(--gap); overflow-y: auto; }

Fondo claro definido por la variable --light.

Convierte el body en un flex container centrado horizontal y verticalmente.

Asegura que su altura mínima cubra toda la ventana (100 vh).

Aplica relleno uniforme según --gap.

Permite scroll vertical si el contenido excede la altura.

.register-container { width: 100%; max-width: 450px; }
El contenedor ocupa el 100 % del ancho disponible, pero no supera los 450 px, manteniéndose centrado y proporcionado.

.register-card { background: #fff; padding: calc(var(--gap) * 2); border-radius: .75rem; box-shadow: 0 10px 25px rgba(0, 0, 0, .1); display: flex; flex-direction: column; gap: calc(var(--gap) * 1.5); }

Tarjeta con fondo blanco, doble padding de --gap, esquinas redondeadas de .75 rem y sombra pronunciada.

Flex vertical, separando sus hijos por 1.5·--gap.

.register-header { text-align: center; }
Centra el texto de la cabecera: logo, título y párrafo.

.register-header .logo { justify-content: center; margin-bottom: var(--gap); border-bottom: none; padding: 0; }

Dentro de .register-header, el logo se centra horizontalmente.

Separa con margen inferior de --gap.

Elimina cualquier borde inferior y padding adicional.

.register-header h2 { font-size: 1.8rem; margin-bottom: .5rem; color: var(--dark); }
Título de segundo nivel con tamaño grande (1.8 rem), color oscuro (--dark) y margen inferior de .5 rem.

.register-header p { font-size: 1rem; color: var(--gray-500); margin: 0; }
Párrafo descriptivo con fuente de 1 rem, color gris medio (--gray-500) y sin márgenes.

.register-form { display: flex; flex-direction: column; gap: var(--gap); }
El formulario se convierte en flex vertical, con espacio entre campos igual a --gap.

.form-group { display: flex; flex-direction: column; gap: .5rem; }
Cada grupo de etiqueta e input usa flex vertical, separando ambos por .5 rem.

.form-group label { font-size: .95rem; font-weight: 500; color: var(--dark); }
Etiquetas con tamaño ligeramente menor, peso medio y color oscuro.

.form-group input[type="text"], .form-group input[type="email"], .form-group input[type="password"] { padding: .75rem 1rem; border: 1px solid var(--gray-200); border-radius: .5rem; font-size: 1rem; color: var(--dark); transition: border-color .2s, box-shadow .2s; width: 100%; box-sizing: border-box; outline: none; }

Campos de texto, email y contraseña con padding cómodo, borde gris claro y esquinas redondeadas.

Fuente de 1 rem, texto oscuro y transición suave al enfocar.

Ocupan el 100 % del ancho, incluyendo el padding en su cálculo (box-sizing).

.form-group input[type="text"]:focus, .form-group input[type="email"]:focus, .form-group input[type="password"]:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.2); }
Al enfocar cualquier campo, el borde se vuelve del color primario y aparece un halo sutil alrededor.

.btn-primary-lg.full-width { display: block; width: 100%; padding: .9rem 1.5rem; font-size: 1.1rem; background: var(--primary); color: #fff; border: none; border-radius: .5rem; cursor: pointer; font-weight: 600; text-align: center; transition: background .2s ease, transform .1s ease; box-shadow: 0 4px 10px rgba(37, 99, 235, 0.3); }
Botón de llamada a la acción que:

Ocupa todo el ancho, con padding generoso y fuente grande.

Fondo primario, texto blanco, sin borde y esquinas redondeadas.

Sombra suave y transiciones de color y elevación.

.btn-primary-lg.full-width:hover { background: var(--primary-dark); transform: translateY(-2px); box-shadow: 0 6px 12px rgba(37, 99, 235, 0.4); }
Al pasar el ratón, el botón se eleva 2 px, oscurece ligeramente y la sombra se intensifica.

.register-footer { text-align: center; font-size: .95rem; color: var(--gray-500); }
Pie de formulario con texto centrado, fuente pequeña y color gris medio.

.register-footer a { color: var(--primary); text-decoration: none; font-weight: 500; transition: color .2s; }
Enlaces del pie con color primario, sin subrayado y peso medio; cambian de color suavemente.

.register-footer a:hover { color: var(--primary-dark); text-decoration: underline; }
Al pasar el ratón sobre el enlace, se oscurece y aparece subrayado.

@media (max-width: 480px) {
Inicio de ajustes para pantallas pequeñas (≤ 480 px).

.register-card { padding: var(--gap); gap: var(--gap); }
Reduce el padding y el espacio interno de la tarjeta para móviles.

.register-header h2 { font-size: 1.6rem; margin-bottom: .3rem; }
Ajusta el tamaño y margen del título en pantallas estrechas.

.register-header p { font-size: .9rem; }
Disminuye el tamaño del párrafo descriptivo.

.register-form { gap: .8rem; }
Reduce la separación entre campos del formulario.

.form-group label { font-size: .9rem; }
Hace las etiquetas aún más pequeñas para adaptarse a pantallas reducidas.

.form-group input[type="text"], .form-group input[type="email"], .form-group input[type="password"] { padding: .6rem .8rem; font-size: .9rem; }
Reduce padding y fuente de los inputs en móviles.

.btn-primary-lg.full-width { padding: .8rem 1.2rem; font-size: 1rem; }
Ajusta el tamaño y padding del botón para dispositivos pequeños.

.register-footer { font-size: .9rem; }
Disminuye el tamaño de fuente del pie de página en móviles.

}
Cierre del bloque de media queries.

ver_oferta.html

Este archivo define la vista de detalle de una oferta de trabajo: carga los estilos globales y módulos CSS, muestra la barra lateral con navegación y perfil de usuario, y en el main despliega la sección de detalles de la oferta con cabecera (badge de modalidad, título, empresa y metadatos como ubicación, jornada, salario y fecha de publicación), los bloques de descripción del puesto, requisitos, responsabilidades, beneficios e información de la empresa, el botón de postulación y el footer con enlaces, y al final integra los scripts que controlan la interacción del sidebar, el desplegable de perfil y las acciones de la página.

ver_oferta.html – Oferta de Empleo Frontend Senior: Detalles y Requisitos

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Desarrollador/a Frontend Senior - Innovate Solutions | EmpleoConnect</title>
    <link rel="stylesheet" href="css/theme.css">
    <link rel="stylesheet" href="css/base.css">
    <link rel="stylesheet" href="css/layout.css">
    <link rel="stylesheet" href="css/state.css">
    <link rel="stylesheet" href="css/modules/sidebar.css">
    <link rel="stylesheet" href="css/modules/logo.css">
    <link rel="stylesheet" href="css/modules/navigation.css">
    <link rel="stylesheet" href="css/modules/profile-dropdown.css">
    <link rel="stylesheet" href="css/modules/sidebar-toggle.css">
    <link rel="stylesheet" href="css/pages/ver_oferta.css">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">

</head>
<body class="sidebar-visible">
    <button class="sidebar-toggle" id="sidebarToggle">
        <svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg>
    </button>

    <aside class="sidebar" id="sidebar">
        <div>
            <div class="logo">
                <svg viewBox="0 0 24 24"><path d="M20 7h-4V3c0-1.1-.9-2-2-2h-4c-1.1 0-2 .9-2 2v4H4c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2z"/><path d="M11 14h2v4h-2zM7 14h2v4H7zM15 14h2v4h-2z"/></svg>
                EmpleoConnect
            </div>
            <div class="category-label">Navegar</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V9z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
                    <span>Inicio</span>
                </li>
                 <li class="nav-item active">
                    <svg viewBox="0 0 24 24"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/></svg>
                    <span>Ofertas</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><polyline points="3.27 6.96 12 12.01 20.73 6.96"/><line x1="12" y1="22.08" x2="12" y2="12"/></svg>
                    <span>Explorar</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
                    <span>Notificaciones</span>
                </li>
                 <li class="nav-item employee-mode" id="employeeModeBtn">
                    <svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg>
                    <span class="mode-text">Modo Empleado</span>
                </li>
            </ul>
            <div class="category-label">Empresas</div>
            <ul class="nav-menu">
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M3 21h18M9 8h1M9 12h1M9 16h1M15 8h1M15 12h1M15 16h1M7 21V5a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v16"/></svg>
                    <span>Destacadas</span>
                </li>
                <li class="nav-item">
                    <svg viewBox="0 0 24 24"><path d="M4 21v-2a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
                    <span>Buscar</span>
                </li>
            </ul>
        </div>
        <div class="profile" id="profileBtn">
            <div class="profile-info">
                <div class="profile-icon"><svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M6 21v-2a6 6 0 0 1 12 0v2"/></svg></div>
                <div>
                    <div class="username">Usuario</div>
                    <div class="status"><span class="status-indicator"></span><span>En línea</span></div>
                </div>
            </div>
            <ul class="nav-menu profile-links" id="profileLinks">
                <li class="nav-item"><span>Editar Perfil</span></li>
                <li class="nav-item"><span>Postulaciones</span></li>
                <li class="nav-item"><span>Notificaciones</span></li>
                <li class="nav-item logout"><span>Cerrar sesión</span></li>
            </ul>
        </div>
    </aside>

    <main>
        <section class="offer-details-container">
            <div class="offer-details-header">
                <span class="badge badge-secondary">Remoto</span> <h1>Desarrollador/a Frontend Senior</h1>
                <p class="company-name">Innovate Solutions</p>
                <div class="offer-meta-large">
                    <span><i class="fas fa-map-marker-alt"></i> Madrid, España (Remoto)</span>
                    <span><i class="fas fa-clock"></i> Tiempo Completo</span>
                    <span><i class="fas fa-money-bill-wave"></i> 40.000 - 55.000 €/año</span>
                    <span><i class="fas fa-calendar-alt"></i> Publicado hace 2 días</span>
                </div>
            </div>

            <div class="offer-content">
                <div class="offer-description-block">
                    <h2>Descripción del Puesto</h2>
                    <p>Buscamos un/a Desarrollador/a Frontend Senior altamente capacitado/a y motivado/a para unirse a nuestro equipo dinámico y en crecimiento. Serás responsable de liderar el desarrollo de interfaces de usuario escalables y de alto rendimiento utilizando tecnologías de vanguardia como React y Next.js. Trabajarás en estrecha colaboración con diseñadores UX/UI y desarrolladores backend para ofrecer experiencias de usuario excepcionales.</p>
                    <p>Si eres un/a apasionado/a por construir productos web innovadores, tienes un ojo para el detalle y disfrutas trabajando en un entorno colaborativo y remoto, ¡queremos conocerte!</p>
                </div>

                <div class="offer-requirements-block">
                    <h2>Requisitos</h2>
                    <ul>
                        <li>Experiencia demostrable de al menos 5 años en desarrollo Frontend.</li>
                        <li>Dominio experto de React y su ecosistema (Hooks, Context API, Redux/Zustand).</li>
                        <li>Experiencia sólida con Next.js para renderizado del lado del servidor y generación de sitios estáticos.</li>
                        <li>Fuerte conocimiento de HTML5, CSS3 (incluyendo preprocesadores como Sass/Less) y JavaScript (ES6+).</li>
                        <li>Experiencia con sistemas de diseño (Design Systems) y metodologías BEM/CSS Modules/Styled Components.</li>
                        <li>Conocimiento de herramientas de testing (Jest, React Testing Library).</li>
                        <li>Familiaridad con Webpack, Babel y otras herramientas de build.</li>
                        <li>Experiencia trabajando con APIs RESTful y GraphQL.</li>
                        <li>Mentalidad orientada a la calidad, la escalabilidad y el rendimiento.</li>
                        <li>Habilidad para escribir código limpio, legible y mantenible.</li>
                        <li>Excelente comunicación y capacidad para trabajar de forma autónoma en un entorno remoto.</li>
                    </ul>
                </div>

                <div class="offer-responsibilities-block">
                     <h2>Responsabilidades</h2>
                     <ul>
                        <li>Diseñar, desarrollar e implementar nuevas funcionalidades y mejoras en nuestra plataforma web.</li>
                        <li>Colaborar con el equipo de UX/UI para traducir wireframes y diseños en interfaces de usuario de alta fidelidad.</li>
                        <li>Optimizar las aplicaciones para garantizar la máxima velocidad y escalabilidad.</li>
                        <li>Escribir pruebas unitarias, de integración y end-to-end para asegurar la calidad del código.</li>
                        <li>Participar en revisiones de código y compartir conocimientos con otros miembros del equipo.</li>
                        <li>Identificar y solucionar problemas de rendimiento y bugs.</li>
                        <li>Mantenerse al día con las últimas tendencias y mejores prácticas en desarrollo Frontend.</li>
                     </ul>
                </div>

                <div class="offer-benefits-block">
                     <h2>Beneficios</h2>
                     <ul>
                        <li>Salario competitivo acorde a la experiencia.</li>
                        <li>Contrato indefinido a tiempo completo.</li>
                        <li>Trabajo 100% remoto con flexibilidad horaria.</li>
                        <li>Presupuesto para equipos y formación continua.</li>
                        <li>Ambiente de trabajo colaborativo y cultura de aprendizaje.</li>
                        <li>Vacaciones flexibles.</li>
                     </ul>
                </div>

                <div class="company-info-block">
                    <h2>Sobre Innovate Solutions</h2>
                    <p>Innovate Solutions es una empresa líder en el sector tecnológico, especializada en el desarrollo de software a medida y soluciones digitales innovadoras para clientes de todo el mundo. Creemos en el poder de la tecnología para transformar negocios y mejorar vidas. Nuestro equipo está formado por profesionales talentosos y apasionados que trabajan juntos para lograr resultados excepcionales. Ofrecemos un entorno de trabajo estimulante y oportunidades de crecimiento profesional.</p>
                    <p><strong>Sitio Web:</strong> <a href="https://www.innovatesolutions.example.com" target="_blank">innovatesolutions.example.com</a></p>
                </div>

                 <div class="offer-apply-block">
                     <button class="btn-primary-lg">Postularse Ahora</button>
                     <p><small>Al hacer clic en "Postularse Ahora", serás redirigido al sitio web de la empresa para completar tu solicitud.</small></p>
                 </div>
            </div>
        </section>

        <footer>
            <a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a>
        </footer>
    </main>

    <script src="js/barraLateral.js" defer></script>
    <script src="js/desplegablePerfil.js" defer></script>
    <script src="js/interaccionesInicio.js" defer></script>
</body>
</html>

Explicación del código: ver_oferta.html – Oferta de Empleo Frontend Senior: Detalles y Requisitos

<!DOCTYPE html> indica que el documento está escrito en HTML5.

<html lang="es"> abre la raíz del documento y establece el idioma como español.

<head> inicia la sección de metadatos y recursos externos.

<meta charset="UTF-8"/> define la codificación de caracteres como UTF-8 para soportar acentos y símbolos especiales.

<meta name="viewport" content="width=device-width, initial-scale=1.0"/> ajusta el ancho y escala inicial de la página según el dispositivo, clave para el diseño responsivo.

<title>Desarrollador/a Frontend Senior - Innovate Solutions | EmpleoConnect</title> fija el texto que aparecerá en la pestaña del navegador.

<link rel="stylesheet" href="css/theme.css"> importa la hoja de estilos con variables de tema (colores, fuentes).

<link rel="stylesheet" href="css/base.css"> enlaza los estilos globales básicos, incluyendo resets y utilidades.

<link rel="stylesheet" href="css/layout.css"> aporta reglas de diseño estructural (grillas, contenedores).

<link rel="stylesheet" href="css/state.css"> incluye clases para estados dinámicos (activo, inactivo).

<link rel="stylesheet" href="css/modules/sidebar.css"> trae estilos específicos para la barra lateral.

<link rel="stylesheet" href="css/modules/logo.css"> define la apariencia del logo en la interfaz.

<link rel="stylesheet" href="css/modules/navigation.css"> formatea el menú de navegación.

<link rel="stylesheet" href="css/modules/profile-dropdown.css"> aporta estilos al menú desplegable de perfil.

<link rel="stylesheet" href="css/modules/sidebar-toggle.css"> personaliza el botón que oculta/muestra la barra lateral.

<link rel="stylesheet" href="css/pages/ver_oferta.css"> carga reglas CSS exclusivas para la vista de oferta de empleo.

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"> importa Font Awesome desde CDN para usar iconos vectoriales.

</head> cierra la sección de metadatos.

<body class="sidebar-visible"> inicia el contenido visible y aplica la clase que muestra la barra lateral por defecto.

<button class="sidebar-toggle" id="sidebarToggle"> crea el botón que alterna la visibilidad de la barra lateral.

<svg viewBox="0 0 24 24"><path d="M3 12h18M3 6h18M3 18h18"/></svg> dibuja el icono de “hamburguesa” mediante SVG.

</button> cierra el botón de alternar barra lateral.

<aside class="sidebar" id="sidebar"> abre la sección de la barra lateral donde van logo y menús.

<div> agrupa todo el contenido de navegación dentro del <aside>.

<div class="logo"> inicia el área del logo en la barra lateral.

<svg viewBox="0 0 24 24"><path d="M20 7h-4V3…"/></svg> muestra el icono de maletín de la marca.

EmpleoConnect sitúa el nombre de la plataforma junto al icono.

</div> cierra el bloque de logo.

<div class="category-label">Navegar</div> añade un encabezado de categoría para el primer grupo de enlaces.

<ul class="nav-menu"> inicia la lista de elementos de navegación principal.

<li class="nav-item"> abre un elemento de menú.

<svg …>…</svg> icono SVG para “Inicio”.

<span>Inicio</span> etiqueta textual del enlace.

</li> cierra el primer ítem de menú.

<li class="nav-item active"> otro ítem marcado como activo para “Ofertas”.

<svg …>…</svg> icono SVG para “Ofertas”.

<span>Ofertas</span> texto del segundo enlace.

</li> cierra el ítem activo.

<li class="nav-item"> ítem para “Explorar”.

<svg …>…</svg> icono SVG para “Explorar”.

<span>Explorar</span> texto del enlace.

</li> cierra el ítem de explorar.

<li class="nav-item"> ítem para “Notificaciones”.

<svg …>…</svg> icono SVG de campana.

<span>Notificaciones</span> texto del enlace.

</li> cierra el ítem de notificaciones.

<li class="nav-item employee-mode" id="employeeModeBtn"> ítem con modo empleado.

<svg …>…</svg> icono SVG para “Modo Empleado”.

<span class="mode-text">Modo Empleado</span> etiqueta del modo.

</li> cierra el ítem de modo empleado.

</ul> finaliza la lista de navegación principal.

<div class="category-label">Empresas</div> título de la segunda categoría de enlaces.

<ul class="nav-menu"> abre lista para opciones de empresa.

<li class="nav-item"> ítem “Destacadas”.

<svg …>…</svg> icono SVG para empresas destacadas.

<span>Destacadas</span> texto del enlace.

</li> cierra el ítem.

<li class="nav-item"> ítem “Buscar”.

<svg …>…</svg> icono SVG de búsqueda.

<span>Buscar</span> texto del enlace.

</li> cierra el ítem de buscar.

</ul> cierra la lista de empresas.

</div> cierra el contenedor interno del <aside>.

<div class="profile" id="profileBtn"> inicia el bloque de perfil al pie de la barra lateral.

<div class="profile-info"> agrupa icono y datos del usuario.

<div class="profile-icon"><svg …>…</svg></div> muestra icono SVG de usuario.

<div> abre el contenedor de texto de perfil.

<div class="username">Usuario</div> muestra el nombre de usuario.

<div class="status"><span class="status-indicator"></span><span>En línea</span></div> muestra indicador y texto de estado.

</div> cierra el div de texto de perfil.

</div> cierra el bloque .profile-info.

<ul class="nav-menu profile-links" id="profileLinks"> lista desplegable con enlaces de perfil.

<li class="nav-item"><span>Editar Perfil</span></li> opción de editar perfil.

<li class="nav-item"><span>Postulaciones</span></li> opción de ver postulaciones.

<li class="nav-item"><span>Notificaciones</span></li> opción de notificaciones.

<li class="nav-item logout"><span>Cerrar sesión</span></li> opción de logout.

</ul> cierra la lista de enlaces de perfil.

</div> cierra el bloque .profile.

</aside> cierra la barra lateral.

<main> abre el área principal de contenido.

<section class="offer-details-container"> inicia la sección con los detalles de la oferta.

<div class="offer-details-header"> agrupa cabecera de la oferta.

<span class="badge badge-secondary">Remoto</span> etiqueta secundaria indicando modalidad remota.

<h1>Desarrollador/a Frontend Senior</h1> título principal de la oferta.

<p class="company-name">Innovate Solutions</p> nombre de la empresa.

<div class="offer-meta-large"> agrupa metadatos principales (ubicación, jornada, salario, fecha).

<span><i class="fas fa-map-marker-alt"></i> Madrid, España (Remoto)</span> ubicación con icono de mapa.

<span><i class="fas fa-clock"></i> Tiempo Completo</span> jornada con icono de reloj.

<span><i class="fas fa-money-bill-wave"></i> 40.000 - 55.000 €/año</span> rango salarial con icono.

<span><i class="fas fa-calendar-alt"></i> Publicado hace 2 días</span> fecha de publicación con icono.

</div> cierra el bloque de metadatos.

</div> cierra la cabecera de detalles.

<div class="offer-content"> inicia el contenido detallado de la oferta.

<div class="offer-description-block"> bloque de descripción del puesto.

<h2>Descripción del Puesto</h2> subtítulo de la descripción.

<p>Buscamos un/a Desarrollador/a Frontend Senior altamente capacitado/a … excepcionales.</p> párrafo explicativo de responsabilidades.

<p>Si eres un/a apasionado/a por construir productos web … ¡queremos conocerte!</p> párrafo motivacional final.

</div> cierra el bloque de descripción.

<div class="offer-requirements-block"> bloque de requisitos.

<h2>Requisitos</h2> subtítulo de la sección.

<ul> lista de requisitos.
102–112. <li>…</li> cada elemento enumera un requisito técnico o de experiencia.

</ul> cierra la lista de requisitos.

</div> cierra el bloque de requisitos.

<div class="offer-responsibilities-block"> bloque de responsabilidades.

<h2>Responsabilidades</h2> subtítulo.

<ul> lista de tareas y obligaciones.
118–124. <li>…</li> elementos describen responsabilidades clave.

</ul> cierra la lista.

</div> cierra el bloque de responsabilidades.

<div class="offer-benefits-block"> bloque de beneficios.

<h2>Beneficios</h2> subtítulo.

<ul> lista de ventajas ofrecidas por la empresa.
130–135. <li>…</li> cada beneficio (salario, flexibilidad…).

</ul> cierra la lista de beneficios.

</div> cierra el bloque de beneficios.

<div class="company-info-block"> bloque con información de la empresa.

<h2>Sobre Innovate Solutions</h2> subtítulo.

<p>Innovate Solutions es una empresa líder … profesionales talentosos.</p> descripción corporativa.

<p><strong>Sitio Web:</strong> <a href="https://www.innovatesolutions.example.com" target="_blank">innovatesolutions.example.com</a></p> enlace al sitio web de la empresa.

</div> cierra el bloque de info de empresa.

<div class="offer-apply-block"> bloque de llamada a la acción.

<button class="btn-primary-lg">Postularse Ahora</button> botón CTA para postularse.

<p><small>Al hacer clic en "Postularse Ahora", serás redirigido … solicitud.</small></p> nota aclaratoria.

</div> cierra el bloque de postulación.

</div> cierra el contenedor .offer-content.

</section> finaliza la sección de detalles de oferta.

<footer> abre el pie de página global.

<a href="#">Acerca de</a> | <a href="#">Términos</a> | <a href="#">Privacidad</a> enlaces a páginas legales.

</footer> cierra el pie de página.

</main> cierra el contenido principal.

<script src="js/barraLateral.js" defer></script> incluye el script que controla la interacción de la barra lateral, diferido hasta cargar el HTML.

<script src="js/desplegablePerfil.js" defer></script> añade la lógica del menú desplegable de perfil, también diferido.

<script src="js/interaccionesInicio.js" defer></script> incorpora comportamientos adicionales de la página principal, deferido.

</body> cierra el cuerpo del documento.

</html> finaliza el documento HTML.

ver_oferta.css

Este archivo contiene los estilos exclusivos de la página de detalle de oferta: establece el espaciado y la disposición en main, da formato al contenedor principal (.offer-details-container) con fondo, sombras y bordes redondeados, define la apariencia de la cabecera de la oferta (.offer-details-header) y metadatos (.offer-meta-large), configura los bloques de contenido y títulos de sección, personaliza las listas de requisitos, responsabilidades y beneficios con viñetas resaltadas, estiliza el botón de postulación (.btn-primary-lg) con efectos hover, y adapta todos estos estilos para distintos anchos de pantalla mediante media queries.

Estás viendo solo el 60% del contenido. Hazte Premium para acceder al tutorial completo.

Comunidad

Comentarios y valoraciones

No hay comentarios aún. ¡Sé el primero en opinar!