From 3f5ca4b2de8cd5f8704ad48a243a3a2457cb8677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gestor=C3=ADa=20LP?= Date: Mon, 2 Mar 2026 08:25:34 +0000 Subject: [PATCH] feat: agregar selector de tema oscuro/claro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Toggle sol/luna en el navbar que permite cambiar entre tema oscuro (por defecto) y tema claro. Preferencia guardada en localStorage. Incluye overrides de CSS para todos los componentes con colores hardcodeados, inversión de logo, y transición suave entre temas. Co-Authored-By: Claude Opus 4.6 --- assets/css/style.css | 282 +++++++++++++++++++++++++++++++++++++++++++ assets/js/main.js | 35 ++++++ includes/footer.php | 2 +- includes/header.php | 6 +- 4 files changed, 323 insertions(+), 2 deletions(-) diff --git a/assets/css/style.css b/assets/css/style.css index a281eb1..68a0273 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -90,6 +90,288 @@ --container-narrow: 800px; } +/* ----- Light Theme Overrides ----- */ +[data-theme="light"] { + --color-primary: #f5f5f5; + --color-primary-dark: #e8e8e8; + --color-primary-light: #ffffff; + --color-accent: #333333; + --color-accent-dark: #555555; + --color-accent-light: #222222; + + --gradient-silver: linear-gradient(135deg, #222 0%, #333 25%, #2a2a2a 50%, #444 75%, #222 100%); + --gradient-dark: linear-gradient(135deg, #f5f5f5 0%, #ffffff 50%, #fafafa 100%); + --gradient-hero: linear-gradient(135deg, #e8e8e8 0%, #f5f5f5 40%, #efefef 100%); + + --color-white: #111111; + --color-off-white: #eaeaea; + --color-gray-100: #e8e8e8; + --color-gray-200: #d4d4d4; + --color-gray-300: #bbbbbb; + --color-gray-400: #999999; + --color-gray-500: #777777; + --color-gray-600: #555555; + --color-gray-700: #3a3a3a; + --color-gray-800: #2a2a2a; + --color-gray-900: #1a1a1a; + + --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08); + --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1); + --shadow-lg: 0 8px 30px rgba(0, 0, 0, 0.12); + --shadow-xl: 0 16px 48px rgba(0, 0, 0, 0.15); + --shadow-silver: 0 0 20px rgba(0, 0, 0, 0.05); +} + +/* Light-theme element overrides (hardcoded colors) */ +[data-theme="light"] .navbar { + background-color: rgba(255, 255, 255, 0.95); + border-bottom-color: rgba(0, 0, 0, 0.08); +} + +[data-theme="light"] .navbar--scrolled { + background-color: rgba(255, 255, 255, 0.98); + box-shadow: 0 2px 20px rgba(0, 0, 0, 0.1); + border-bottom-color: rgba(0, 0, 0, 0.1); +} + +[data-theme="light"] .navbar__dropdown { + background-color: #ffffff; + border-color: rgba(0, 0, 0, 0.1); + box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12); +} + +[data-theme="light"] .navbar__link:hover { + background-color: rgba(0, 0, 0, 0.05); +} + +[data-theme="light"] .navbar__dropdown-link:hover { + background-color: rgba(0, 0, 0, 0.05); +} + +[data-theme="light"] .card--service, +[data-theme="light"] .value-card, +[data-theme="light"] .testimonial-card, +[data-theme="light"] .contact__info-card, +[data-theme="light"] .confirmation-card { + background-color: #ffffff; + border-color: rgba(0, 0, 0, 0.1); +} + +[data-theme="light"] .card--service:hover { + box-shadow: 0 8px 30px rgba(0, 0, 0, 0.1), 0 0 20px rgba(0, 0, 0, 0.03); + border-color: rgba(0, 0, 0, 0.18); +} + +[data-theme="light"] .testimonial-card:hover { + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + border-color: rgba(0, 0, 0, 0.15); +} + +[data-theme="light"] .contact__info-card:hover { + background-color: #f8f8f8; + border-color: rgba(0, 0, 0, 0.15); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); +} + +[data-theme="light"] .service-detail__form { + background-color: #ffffff; + border-color: rgba(0, 0, 0, 0.1); +} + +[data-theme="light"] .form-control { + background-color: #ffffff; + border-color: rgba(0, 0, 0, 0.2); + color: #1a1a1a; +} + +[data-theme="light"] .form-control:focus { + border-color: #333333; + box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.08); +} + +[data-theme="light"] .form-control::placeholder { + color: #999999; +} + +[data-theme="light"] select.form-control { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%23333333' viewBox='0 0 16 16'%3E%3Cpath d='M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/%3E%3C/svg%3E"); +} + +[data-theme="light"] .footer { + background-color: #e0e0e0; + color: rgba(30, 30, 30, 0.7); + border-top-color: rgba(0, 0, 0, 0.08); +} + +[data-theme="light"] .footer__text { + color: rgba(30, 30, 30, 0.6); +} + +[data-theme="light"] .footer__contact-list a { + color: rgba(30, 30, 30, 0.7); +} + +[data-theme="light"] .footer__bottom { + color: rgba(30, 30, 30, 0.4); +} + +[data-theme="light"] .footer__grid { + border-bottom-color: rgba(0, 0, 0, 0.1); +} + +[data-theme="light"] .footer__social-link { + background-color: rgba(0, 0, 0, 0.06); + border-color: rgba(0, 0, 0, 0.1); +} + +[data-theme="light"] .footer__social-link:hover { + box-shadow: 0 0 15px rgba(0, 0, 0, 0.1); +} + +[data-theme="light"] .navbar__logo, +[data-theme="light"] .footer__logo { + filter: invert(1); +} + +[data-theme="light"] .btn--primary { + background: var(--gradient-silver); + color: #ffffff; + border-color: rgba(0, 0, 0, 0.2); +} + +[data-theme="light"] .btn--primary:hover { + background: linear-gradient(135deg, #111 0%, #2a2a2a 25%, #1a1a1a 50%, #333 75%, #111 100%); + border-color: rgba(0, 0, 0, 0.3); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); +} + +[data-theme="light"] .btn--secondary { + background-color: #e8e8e8; + border-color: #555555; +} + +[data-theme="light"] .btn--secondary:hover { + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); +} + +[data-theme="light"] .card__icon, +[data-theme="light"] .value-card__icon { + background: rgba(0, 0, 0, 0.05); + border-color: rgba(0, 0, 0, 0.1); +} + +[data-theme="light"] .card--service:hover .card__icon { + background: rgba(0, 0, 0, 0.08); + border-color: rgba(0, 0, 0, 0.15); +} + +[data-theme="light"] .contact__info-icon { + background: rgba(0, 0, 0, 0.05); + border-color: rgba(0, 0, 0, 0.1); +} + +[data-theme="light"] .section__badge { + background-color: rgba(0, 0, 0, 0.05); + border-color: rgba(0, 0, 0, 0.12); +} + +[data-theme="light"] .hero__overlay { + background-image: + radial-gradient(ellipse at 20% 80%, rgba(0, 0, 0, 0.03) 0%, transparent 50%), + radial-gradient(ellipse at 80% 20%, rgba(0, 0, 0, 0.02) 0%, transparent 50%); +} + +[data-theme="light"] .hero__subtitle { + color: rgba(80, 80, 80, 0.85); +} + +[data-theme="light"] .hero__stats { + border-top-color: rgba(0, 0, 0, 0.1); +} + +[data-theme="light"] .hero__stat-label { + color: rgba(80, 80, 80, 0.6); +} + +[data-theme="light"] .service-hero { + border-bottom-color: rgba(0, 0, 0, 0.06); +} + +[data-theme="light"] .service-hero__price { + color: rgba(80, 80, 80, 0.75); +} + +[data-theme="light"] .service-hero__icon { + background: rgba(0, 0, 0, 0.04); + border-color: rgba(0, 0, 0, 0.12); +} + +[data-theme="light"] .contact__map { + border-color: rgba(0, 0, 0, 0.1); +} + +[data-theme="light"] .navbar__overlay { + background-color: rgba(0, 0, 0, 0.3); +} + +[data-theme="light"] .form-heading { + border-bottom-color: rgba(0, 0, 0, 0.15); +} + +/* Mobile menu light override */ +@media (max-width: 768px) { + [data-theme="light"] .navbar__menu { + background-color: #ffffff; + border-left-color: rgba(0, 0, 0, 0.08); + } + + [data-theme="light"] .navbar__link { + border-bottom-color: rgba(0, 0, 0, 0.06); + } + + [data-theme="light"] .navbar__dropdown-link { + border-bottom-color: rgba(0, 0, 0, 0.06); + } +} + +/* Theme toggle button */ +.theme-toggle { + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 50%; + background: transparent; + border: 1.5px solid rgba(192, 192, 192, 0.2); + color: var(--color-accent); + font-size: 1.1rem; + cursor: pointer; + transition: all var(--transition-base); + flex-shrink: 0; + margin-right: var(--space-sm); +} + +.theme-toggle:hover { + background-color: rgba(192, 192, 192, 0.1); + border-color: rgba(192, 192, 192, 0.35); + transform: scale(1.05); +} + +[data-theme="light"] .theme-toggle { + border-color: rgba(0, 0, 0, 0.15); +} + +[data-theme="light"] .theme-toggle:hover { + background-color: rgba(0, 0, 0, 0.05); + border-color: rgba(0, 0, 0, 0.25); +} + +/* Smooth theme transition */ +html { + transition: background-color 0.3s ease, color 0.3s ease; +} + /* ============================================================ CSS Reset (Modern) ============================================================ */ diff --git a/assets/js/main.js b/assets/js/main.js index 9b569ae..913d176 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -177,4 +177,39 @@ document.addEventListener('DOMContentLoaded', function () { } }); + // ================================================================ + // 7. Dark / Light Theme Toggle + // ================================================================ + var themeToggle = document.getElementById('themeToggle'); + var themeIcon = document.getElementById('themeIcon'); + + function setTheme(theme) { + document.documentElement.setAttribute('data-theme', theme); + localStorage.setItem('theme', theme); + if (themeIcon) { + themeIcon.className = theme === 'light' ? 'fas fa-sun' : 'fas fa-moon'; + } + // Update theme-color meta tag + var metaTheme = document.querySelector('meta[name="theme-color"]'); + if (metaTheme) { + metaTheme.setAttribute('content', theme === 'light' ? '#f5f5f5' : '#0a0a0a'); + } + } + + // Determine initial theme: localStorage > system preference > dark + var savedTheme = localStorage.getItem('theme'); + if (savedTheme) { + setTheme(savedTheme); + } else if (window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) { + setTheme('light'); + } + // else: default is dark (no data-theme attribute needed) + + if (themeToggle) { + themeToggle.addEventListener('click', function () { + var current = document.documentElement.getAttribute('data-theme'); + setTheme(current === 'light' ? 'dark' : 'light'); + }); + } + }); diff --git a/includes/footer.php b/includes/footer.php index 2922aa7..55b2d7e 100644 --- a/includes/footer.php +++ b/includes/footer.php @@ -58,6 +58,6 @@ - + diff --git a/includes/header.php b/includes/header.php index b686bb2..3837f11 100644 --- a/includes/header.php +++ b/includes/header.php @@ -15,7 +15,7 @@ - + @@ -58,6 +58,10 @@ + +