From 55bccae0ad17c730c531a69978b3d5b423a027c4 Mon Sep 17 00:00:00 2001 From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com> Date: Thu, 9 Jul 2026 20:42:39 -0500 Subject: [PATCH] fix: dark mode completamente reescrito con Bootstrap 5.3 data-bs-theme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Agrega script inline en de Layout.php, lugar.php y recepcion.php que detecta prefers-color-scheme y activa data-bs-theme="dark" en antes del primer paint (evita flash de contenido blanco) - sidebar.php: script de fallback para páginas con head propio no actualizado - Layout.php: corrige background hardcodeado #f8f9fa en .main-content y reemplaza bg-white por bg-body-tertiary en barra de título - styles.css: elimina bloque @media duplicado y contradictorio; nuevo bloque unificado cubre @media (fallback sin JS) + [data-bs-theme="dark"] para elementos custom (sidebar, chat); Bootstrap maneja el resto automáticamente - Bump styles.css a v=15 en los tres templates Co-Authored-By: Claude Sonnet 4.6 --- assets/css/styles.css | 239 ++++++++++++++-------------- core/Layout.php | 9 +- modules/turnero/views/lugar.php | 3 +- modules/turnero/views/recepcion.php | 3 +- shared/components/sidebar.php | 5 + 5 files changed, 132 insertions(+), 127 deletions(-) diff --git a/assets/css/styles.css b/assets/css/styles.css index 7fa6cd7..39b55ca 100644 --- a/assets/css/styles.css +++ b/assets/css/styles.css @@ -935,32 +935,6 @@ body { #sidebar-toggle { display: none !important; } } -/* Dark Mode Support */ -@media (prefers-color-scheme: dark) { - :root { - --light-bg: #1f2937; - --text-primary: #f9fafb; - --text-secondary: #d1d5db; - --border-color: #374151; - } - - body { - background-color: var(--dark-bg); - color: var(--text-primary); - } - - .card { - background: #374151; - } - - .card-header { - background: #4b5563; - } - - .table th { - background: #4b5563; - } -} /* Utility Classes */ .text-center { text-align: center; } @@ -1483,104 +1457,125 @@ body { border: 1px solid rgba(255, 255, 255, 0.5); } -/* ===== Ajustes para modo nocturno (dark mode) ===== */ +/* ───────────────────────────────────────────────────────────────────────── + MODO OSCURO + Activación dual: + 1) @media (prefers-color-scheme: dark) — OS sin JS + 2) [data-bs-theme="dark"] en — Bootstrap 5.3 via script inline + + Bootstrap 5.3 maneja automáticamente (cuando data-bs-theme está activo): + card, modal, table, form-control, form-select, dropdown, badge, alert, + list-group, nav, pagination, offcanvas, toast, popover, etc. + Aquí solo cubrimos variables custom y elementos no-Bootstrap. +───────────────────────────────────────────────────────────────────────── */ + +/* ── Variables custom para elementos no-Bootstrap ── */ @media (prefers-color-scheme: dark) { :root { - --light-bg: #071322; - --text-primary: #e6eef1; + --dm-body: #0a1628; + --dm-surf: #071322; + --dm-surf2: #0b1c32; + --dm-bdr: #163240; + --dm-txt: #e6eef1; + --dm-muted: #9ca3af; + --dm-link: #a6f3c9; + /* Alias compatibilidad con código que usa estas vars */ + --light-bg: #071322; + --text-primary: #e6eef1; --text-secondary: #9ca3af; - --border-color: #163240; + --border-color: #163240; } - - body { - background-color: var(--light-bg); - color: var(--text-primary); - } - - /* Encabezados y títulos */ - .content-header h1, - .card-header h5, - .sidebar-header h4, - .status-text, - .status-indicator, - .conversation-empty { - color: var(--text-primary) !important; - } - - /* Contenedores */ - .content-header, - .card, - .chat-container { - background: #071322; - color: var(--text-primary); - border-color: var(--border-color); - box-shadow: none; - } - - .card-header { - background: transparent; - border-bottom-color: rgba(255,255,255,0.04); - } - - /* Formularios y botones */ - .form-control { - background: #072033; - color: var(--text-primary); - border-color: #163240; - } - - .btn { - color: inherit; - } - - /* Sidebar */ - .sidebar { - background: linear-gradient(135deg,#08131a,#0b2221); - color: #e6eef1; - } - - .conversation-actions .btn { - background: #0b1220; - border-color: #1f2937; - color: var(--text-secondary); - } - - /* Chat específico */ - .chat-header { - background: linear-gradient(135deg, #1f5a3f 0%, #0f513e 100%); - color: #fff; - } - - .message-bubble { - color: #e6eef1; - } - - .message-incoming { - background: #0b1220; - color: #e6eef1; - box-shadow: none; - } - - .message-outgoing { - background: #0f513e; - color: #fff; - } - - .message-document, - .media-preview { - background: rgba(255,255,255,0.03); - color: var(--text-primary); - } - - .conversation-search { - background: rgba(255,255,255,0.04); - color: var(--text-primary); - } - - a, .nav-link { - color: #a6f3c9; - } - - /* Placeholders visibles */ - ::placeholder { color: #9ca3af !important; opacity: 1; } } +[data-bs-theme="dark"] { + --dm-body: #0a1628; + --dm-surf: #071322; + --dm-surf2: #0b1c32; + --dm-bdr: #163240; + --dm-txt: #e6eef1; + --dm-muted: #9ca3af; + --dm-link: #a6f3c9; + --light-bg: #071322; + --text-primary: #e6eef1; + --text-secondary: #9ca3af; + --border-color: #163240; +} + +/* ── Reglas para modo OS sin JS (fallback) ── */ +@media (prefers-color-scheme: dark) { + body { background-color: var(--dm-body); color: var(--dm-txt); } + + /* Fondo principal */ + .main-content { background-color: var(--dm-body) !important; } + + /* Bootstrap no cambia bg-white — forzamos adaptación */ + .bg-white { background-color: var(--dm-surf) !important; color: var(--dm-txt) !important; } + + /* Encabezados y texto */ + .content-header { background: var(--dm-surf); border-color: var(--dm-bdr) !important; color: var(--dm-txt); } + .content-header h1, .card-header h5, .sidebar-header h4, + .status-text, .status-indicator, .conversation-empty { color: var(--dm-txt) !important; } + + /* Componentes Bootstrap (fallback sin data-bs-theme) */ + .card { background: var(--dm-surf); color: var(--dm-txt); border-color: var(--dm-bdr); box-shadow: none; } + .card-header { background: transparent; border-color: rgba(255,255,255,.06); } + .form-control, .form-select { + background: var(--dm-surf2); + color: var(--dm-txt); + border-color: var(--dm-bdr); + } + .form-control:focus, .form-select:focus { + background: var(--dm-surf2); + color: var(--dm-txt); + border-color: #2d6a8a; + box-shadow: 0 0 0 .2rem rgba(45,106,138,.25); + } + .table { color: var(--dm-txt); border-color: var(--dm-bdr); } + .table th { background: var(--dm-surf2); color: var(--dm-txt); } + .modal-content { background: var(--dm-surf); color: var(--dm-txt); } + .modal-header, .modal-footer { border-color: var(--dm-bdr); } + .dropdown-menu { background: var(--dm-surf); border-color: var(--dm-bdr); } + .dropdown-item { color: var(--dm-txt); } + .dropdown-item:hover { background: var(--dm-surf2); color: var(--dm-txt); } + .list-group-item { background: var(--dm-surf); color: var(--dm-txt); border-color: var(--dm-bdr); } + .input-group-text { background: var(--dm-surf2); color: var(--dm-txt); border-color: var(--dm-bdr); } + .nav-tabs .nav-link { color: var(--dm-muted); } + .nav-tabs .nav-link.active { background: var(--dm-surf); color: var(--dm-txt); border-color: var(--dm-bdr); } + + /* Sidebar custom */ + .sidebar { background: linear-gradient(135deg, #08131a, #0b2221); color: #e6eef1; } + + /* Chat */ + .chat-container { background: var(--dm-surf); color: var(--dm-txt); border-color: var(--dm-bdr); } + .chat-header { background: linear-gradient(135deg, #1f5a3f, #0f513e); color: #fff; } + .message-bubble { color: var(--dm-txt); } + .message-incoming { background: var(--dm-surf2); color: var(--dm-txt); box-shadow: none; } + .message-outgoing { background: #0f513e; color: #fff; } + .message-document, .media-preview { background: rgba(255,255,255,.03); color: var(--dm-txt); } + .conversation-search { background: rgba(255,255,255,.04); color: var(--dm-txt); } + .conversation-actions .btn { background: #0b1220; border-color: #1f2937; color: var(--dm-muted); } + + /* Links */ + a:not(.btn):not(.badge), .nav-link { color: var(--dm-link); } + + /* Placeholders */ + ::placeholder { color: var(--dm-muted) !important; opacity: 1; } +} + +/* ── Reglas para Bootstrap dark mode activo (data-bs-theme="dark") ── */ +/* Bootstrap ya maneja card, modal, table, form, dropdown, badge, alert, etc. */ +/* Solo corregimos lo que Bootstrap no toca: elementos custom y clases forzadas */ + +[data-bs-theme="dark"] .main-content { background-color: var(--dm-body, #0a1628) !important; } +[data-bs-theme="dark"] .bg-white { background-color: var(--bs-body-bg) !important; color: var(--bs-body-color) !important; } +[data-bs-theme="dark"] .sidebar { background: linear-gradient(135deg, #08131a, #0b2221) !important; color: #e6eef1; } +[data-bs-theme="dark"] .chat-container { background: var(--dm-surf, #071322); border-color: var(--dm-bdr, #163240); } +[data-bs-theme="dark"] .chat-header { background: linear-gradient(135deg, #1f5a3f, #0f513e); color: #fff; } +[data-bs-theme="dark"] .message-bubble { color: var(--dm-txt, #e6eef1); } +[data-bs-theme="dark"] .message-incoming { background: var(--dm-surf2, #0b1c32); color: var(--dm-txt, #e6eef1); box-shadow: none; } +[data-bs-theme="dark"] .message-outgoing { background: #0f513e; color: #fff; } +[data-bs-theme="dark"] .message-document, +[data-bs-theme="dark"] .media-preview { background: rgba(255,255,255,.03); color: var(--dm-txt, #e6eef1); } +[data-bs-theme="dark"] .conversation-search { background: rgba(255,255,255,.04); color: var(--dm-txt, #e6eef1); } +[data-bs-theme="dark"] .conversation-actions .btn { background: #0b1220; border-color: #1f2937; color: var(--dm-muted, #9ca3af); } +[data-bs-theme="dark"] a:not(.btn):not(.badge) { color: var(--dm-link, #a6f3c9); } +[data-bs-theme="dark"] ::placeholder { color: var(--dm-muted, #9ca3af) !important; opacity: 1; } diff --git a/core/Layout.php b/core/Layout.php index a9cf26e..d0d0939 100644 --- a/core/Layout.php +++ b/core/Layout.php @@ -60,12 +60,15 @@ class Layout <?= $safeTitle ?> — <?= htmlspecialchars($appName, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?> + + + - + \n"; + // Dark mode: activa Bootstrap 5.3 data-bs-theme si el head de la página no lo hizo ya + if (!defined('_DM_SCRIPT_INJECTED')) { + define('_DM_SCRIPT_INJECTED', true); + echo '' . "\n"; + } } // Ruta del script que está siendo cargado actualmente