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