fix: dark mode completamente reescrito con Bootstrap 5.3 data-bs-theme
- Agrega script inline en <head> de Layout.php, lugar.php y recepcion.php que detecta prefers-color-scheme y activa data-bs-theme="dark" en <html> 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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
fdc04d615c
commit
55bccae0ad
+117
-122
@@ -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 <html> — 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; }
|
||||
|
||||
+6
-3
@@ -60,12 +60,15 @@ class Layout
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= $safeTitle ?> — <?= htmlspecialchars($appName, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?></title>
|
||||
|
||||
<!-- Dark mode: aplica data-bs-theme antes del primer paint para evitar flash -->
|
||||
<script>(function(){try{var m=window.matchMedia('(prefers-color-scheme: dark)');function a(d){document.documentElement.setAttribute('data-bs-theme',d?'dark':'light');}a(m.matches);m.addEventListener('change',function(e){a(e.matches);});}catch(e){}})();</script>
|
||||
|
||||
<!-- Bootstrap 5 -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Font Awesome 6 -->
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
||||
<!-- Estilos del sistema -->
|
||||
<link href="<?= $base ?>/assets/css/styles.css?v=14" rel="stylesheet">
|
||||
<link href="<?= $base ?>/assets/css/styles.css?v=15" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
:root {
|
||||
@@ -77,7 +80,7 @@ class Layout
|
||||
.main-content {
|
||||
margin-left: var(--sidebar-width);
|
||||
min-height: 100vh;
|
||||
background: #f8f9fa;
|
||||
background: var(--bs-body-bg, #f8f9fa);
|
||||
}
|
||||
@media (max-width: 991.98px) {
|
||||
.main-content { margin-left: 0; }
|
||||
@@ -108,7 +111,7 @@ class Layout
|
||||
<!-- Contenido principal -->
|
||||
<main class="main-content">
|
||||
<!-- Barra de título de módulo -->
|
||||
<div class="bg-white border-bottom px-4 py-3 d-flex align-items-center justify-content-between">
|
||||
<div class="bg-body-tertiary border-bottom px-4 py-3 d-flex align-items-center justify-content-between">
|
||||
<h5 class="mb-0 fw-semibold">
|
||||
<i class="<?= $safeIcon ?> me-2 text-primary"></i><?= $safeTitle ?>
|
||||
</h5>
|
||||
|
||||
@@ -89,9 +89,10 @@ try {
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= htmlspecialchars($lugarNombre) ?> — Turnero</title>
|
||||
<script>(function(){try{var m=window.matchMedia('(prefers-color-scheme: dark)');function a(d){document.documentElement.setAttribute('data-bs-theme',d?'dark':'light');}a(m.matches);m.addEventListener('change',function(e){a(e.matches);});}catch(e){}})();</script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
||||
<link href="<?= BASE_URL ?>assets/css/styles.css?v=12" rel="stylesheet">
|
||||
<link href="<?= BASE_URL ?>assets/css/styles.css?v=15" rel="stylesheet">
|
||||
<style>
|
||||
/* ── Layout ─────────────────────────────────────────────── */
|
||||
.lugar-layout {
|
||||
|
||||
@@ -134,9 +134,10 @@ $adminNombre = $_SESSION['admin_user']['full_name'] ?? $_SESSION['admin_user']['
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= htmlspecialchars($deskNombre ?? 'Recepción') ?> — Turnero</title>
|
||||
<script>(function(){try{var m=window.matchMedia('(prefers-color-scheme: dark)');function a(d){document.documentElement.setAttribute('data-bs-theme',d?'dark':'light');}a(m.matches);m.addEventListener('change',function(e){a(e.matches);});}catch(e){}})();</script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
||||
<link href="<?= BASE_URL ?>assets/css/styles.css?v=12" rel="stylesheet">
|
||||
<link href="<?= BASE_URL ?>assets/css/styles.css?v=15" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/tom-select@2.4.3/dist/css/tom-select.bootstrap5.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.jsdelivr.net/npm/tom-select@2.4.3/dist/js/tom-select.complete.min.js"></script>
|
||||
<style>
|
||||
|
||||
@@ -56,6 +56,11 @@ if (!defined('_SIDEBAR_BRAND_INJECTED')) {
|
||||
}
|
||||
} catch (\Throwable $_) {}
|
||||
echo "<style>:root{--brand:{$_sb_brand};--brand-dark:{$_sb_brand_dark}}</style>\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 '<script>(function(){if(document.documentElement.hasAttribute("data-bs-theme"))return;try{var m=window.matchMedia("(prefers-color-scheme: dark)");function a(d){document.documentElement.setAttribute("data-bs-theme",d?"dark":"light");}a(m.matches);m.addEventListener("change",function(e){a(e.matches);});}catch(e){}})();</script>' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Ruta del script que está siendo cargado actualmente
|
||||
|
||||
Reference in New Issue
Block a user