diff --git a/assets/css/styles.css b/assets/css/styles.css index cd2b2aa..0a20bb6 100644 --- a/assets/css/styles.css +++ b/assets/css/styles.css @@ -42,202 +42,222 @@ body { line-height: 1.6; } -/* Sidebar */ +/* ═══════════════════════════════════════════════════════ + SIDEBAR — diseño alineado con el login + ═══════════════════════════════════════════════════════ */ .sidebar { position: fixed; left: 0; top: 0; - width: 280px; + width: var(--sidebar-width, 270px); height: 100vh; - background: linear-gradient(135deg, var(--tertiary-color), var(--secondary-color)); + background: linear-gradient(160deg, var(--brand-dark, #0d47a1) 0%, var(--brand, #1565c0) 60%, color-mix(in srgb, var(--brand, #1565c0) 75%, #fff) 100%); color: white; z-index: 1000; overflow-y: auto; - transition: all 0.3s ease; - box-shadow: 2px 0 10px rgba(0, 0, 0, 0.1); + overflow-x: hidden; + transition: transform 0.28s ease, box-shadow 0.28s ease; + box-shadow: 4px 0 24px rgba(0, 0, 0, 0.18); + display: flex; + flex-direction: column; } +/* Círculos decorativos (igual que login) */ +.sidebar::before, +.sidebar::after { + content: ''; + position: absolute; + border-radius: 50%; + background: rgba(255, 255, 255, 0.07); + pointer-events: none; + animation: sb-float 9s ease-in-out infinite; +} +.sidebar::before { + width: 260px; height: 260px; + bottom: -80px; right: -80px; + animation-delay: 0s; +} +.sidebar::after { + width: 160px; height: 160px; + top: -50px; left: -50px; + animation-delay: 4s; +} +@keyframes sb-float { + 0%,100% { transform: scale(1); } + 50% { transform: scale(1.06); } +} + +/* ── Cabecera ─────────────────────────────────────────── */ +.sidebar-header { + padding: 20px 20px 16px; + text-align: center; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); + background: rgba(0, 0, 0, 0.15); + backdrop-filter: blur(4px); + position: relative; + z-index: 1; + flex-shrink: 0; +} + +.sidebar-header h4 { + font-size: 1rem; + font-weight: 700; + letter-spacing: 0.02em; + margin: 0; + color: #fff; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* ── Lista de menú ────────────────────────────────────── */ .sidebar-menu { list-style: none; - padding: 0; + padding: 6px 0; margin: 0; + flex: 1; + position: relative; + z-index: 1; } .sidebar-menu li { - border-bottom: 1px solid rgba(255, 255, 255, 0.1); + border-bottom: none; } .sidebar-menu .nav-link { - display: block; - padding: 11px 20px; - color: rgba(255, 255, 255, 0.82); + display: flex; + align-items: center; + padding: 10px 16px; + margin: 2px 10px; + border-radius: 10px; + color: rgba(255, 255, 255, 0.80); text-decoration: none; - transition: all 0.25s ease; + font-size: 0.88rem; + transition: background 0.2s, color 0.2s, transform 0.18s; position: relative; overflow: hidden; - font-size: 0.9rem; -} - -.sidebar-menu .nav-link::before { - content: ''; - position: absolute; - left: 0; - top: 0; - width: 4px; - height: 100%; - background: var(--primary-color); - transform: translateX(-100%); - transition: transform 0.3s ease; } .sidebar-menu .nav-link:hover { - color: white; - background: rgba(255, 255, 255, 0.1); - transform: translateX(5px); + color: #fff; + background: rgba(255, 255, 255, 0.13); + transform: translateX(3px); } .sidebar-menu .nav-link.active { - color: #fff; - background: var(--primary-color); - transform: translateX(5px); + color: var(--brand-dark, #0d47a1); + background: rgba(255, 255, 255, 0.95); font-weight: 600; -} - -.sidebar-menu .nav-link.active::before, -.sidebar-menu .nav-link:hover::before { - transform: translateX(0); + box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18); + transform: translateX(3px); } .sidebar-menu .nav-link i { margin-right: 10px; - width: 20px; + width: 18px; text-align: center; + font-size: 0.95rem; + flex-shrink: 0; } -/* Small badge placed inside sidebar items */ -.sidebar-menu .nav-link .sidebar-badge { - position: absolute; - right: 14px; - top: 50%; - transform: translateY(-50%); - font-size: 0.72rem; - padding: 0.12rem 0.36rem; - border-radius: 999px; - line-height: 1; -} - -/* Divisor del sidebar */ -.sidebar-divider { - margin: 10px 20px; - border-top: 1px solid rgba(255, 255, 255, 0.2); -} - -/* Botón de logout en sidebar */ -.sidebar-menu .logout-link { - color: rgba(255, 255, 255, 0.7); - background: rgba(220, 53, 69, 0.1); - border-top: 1px solid rgba(220, 53, 69, 0.3); -} - -.sidebar-menu .logout-link:hover { - color: white; - background: rgba(220, 53, 69, 0.2); - border-color: rgba(220, 53, 69, 0.4); -} - -.sidebar-menu .logout-link::before { - background: #dc3545; -} - -/* ── Sidebar – cabecera mejorada ─────────────────────────────────── */ -.sidebar-header { - padding: 18px 20px; - text-align: center; - border-bottom: 1px solid rgba(255, 255, 255, 0.1); - background: rgba(0, 0, 0, 0.2); -} - -.sidebar-header h4 { - font-size: 1.05rem; - font-weight: 700; - letter-spacing: 0.02em; - margin: 0; -} - -/* ── Sidebar – etiquetas de categoría ────────────────────────────── */ +/* ── Etiquetas de categoría ───────────────────────────── */ .sidebar-menu li.sidebar-section { border-bottom: none; - padding: 12px 18px 4px; - font-size: 0.67rem; + padding: 14px 18px 3px; + font-size: 0.65rem; font-weight: 800; text-transform: uppercase; - letter-spacing: 0.13em; - color: rgba(255, 255, 255, 0.38); - margin-top: 4px; + letter-spacing: 0.14em; + color: rgba(255, 255, 255, 0.40); pointer-events: none; display: flex; align-items: center; gap: 5px; position: relative; + z-index: 1; } .sidebar-menu li.sidebar-section::after { content: ''; flex: 1; height: 1px; - background: rgba(255, 255, 255, 0.1); + background: rgba(255, 255, 255, 0.12); margin-left: 4px; } -/* ── Sidebar – usuario al pie ────────────────────────────────────── */ +/* ── Badge dentro de un item ──────────────────────────── */ +.sidebar-menu .nav-link .sidebar-badge { + position: absolute; + right: 12px; + top: 50%; + transform: translateY(-50%); + font-size: 0.68rem; + padding: 0.1rem 0.34rem; + border-radius: 999px; + line-height: 1; +} + +/* ── Divisor ──────────────────────────────────────────── */ +.sidebar-divider { + margin: 8px 18px; + border-top: 1px solid rgba(255, 255, 255, 0.15); +} + +/* ── Logout ───────────────────────────────────────────── */ +.sidebar-menu .logout-link { + color: rgba(255, 255, 255, 0.65); + background: rgba(220, 53, 69, 0.08); + border: 1px solid rgba(220, 53, 69, 0.25); +} + +.sidebar-menu .logout-link:hover { + color: #fff; + background: rgba(220, 53, 69, 0.22); + border-color: rgba(220, 53, 69, 0.45); + transform: translateX(3px); +} + +/* ── Usuario al pie ───────────────────────────────────── */ .sidebar-user { - padding: 12px 18px; - border-top: 1px solid rgba(255, 255, 255, 0.1); + padding: 12px 16px; + border-top: 1px solid rgba(255, 255, 255, 0.12); background: rgba(0, 0, 0, 0.18); + backdrop-filter: blur(4px); display: flex; flex-direction: column; gap: 2px; + flex-shrink: 0; + position: relative; + z-index: 1; } .sidebar-user-name { - font-size: 0.85rem; + font-size: 0.84rem; font-weight: 600; - color: rgba(255, 255, 255, 0.9); + color: rgba(255, 255, 255, 0.92); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .sidebar-user-role { - font-size: 0.7rem; + font-size: 0.68rem; color: rgba(255, 255, 255, 0.48); text-transform: uppercase; - letter-spacing: 0.08em; + letter-spacing: 0.09em; } -/* ── Sidebar – scrollbar ─────────────────────────────────────────── */ -.sidebar::-webkit-scrollbar { - width: 4px; -} - -.sidebar::-webkit-scrollbar-track { - background: transparent; -} - -.sidebar::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.18); - border-radius: 2px; -} - -.sidebar::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.32); -} +/* ── Scrollbar ────────────────────────────────────────── */ +.sidebar::-webkit-scrollbar { width: 3px; } +.sidebar::-webkit-scrollbar-track { background: transparent; } +.sidebar::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.18); border-radius: 2px; } +.sidebar::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.35); } /* Main Content */ .main-content { - margin-left: 280px; + margin-left: var(--sidebar-width, 270px); min-height: 100vh; - transition: margin-left 0.3s ease; + transition: margin-left 0.28s ease; } /* Responsive: ver bloque unificado al final del archivo */ @@ -886,43 +906,35 @@ body { @media (max-width: 991.98px) { .sidebar { transform: translateX(-100%); - width: 240px; - transition: transform 0.25s ease; + width: 270px; box-shadow: none; } .sidebar.open, .sidebar.show { transform: translateX(0); - box-shadow: 2px 0 24px rgba(0,0,0,.25); + box-shadow: 4px 0 32px rgba(0,0,0,.30); z-index: 1200; } .main-content { margin-left: 0; } - /* Overlay semitransparente detrás del sidebar */ .sidebar-overlay { position: fixed; inset: 0; - background: rgba(0,0,0,.38); + background: rgba(0,0,0,.40); z-index: 1100; display: none; + backdrop-filter: blur(2px); } - /* Ocultar badge de estado (sin espacio en mobile) */ .status-badge { display: none !important; } - /* Botón «Cerrar Sesión» del header: solo icono en mobile */ - .header-actions .btn-outline-danger .fa-sign-out-alt ~ * { } } /* ── Desktop (>= 992px) ────────────────────────────── */ @media (min-width: 992px) { .sidebar { transform: translateX(0) !important; - width: 280px; + width: var(--sidebar-width, 270px); } - .main-content { - margin-left: 280px; - } - /* Ocultar botón hamburguesa en desktop */ #sidebar-toggle { display: none !important; } } diff --git a/core/Layout.php b/core/Layout.php index 8630412..a6eff5a 100644 --- a/core/Layout.php +++ b/core/Layout.php @@ -33,6 +33,23 @@ class Layout $GLOBALS['_LAYOUT_TITLE'] = $title; $GLOBALS['_LAYOUT_ICON'] = $icon; + // Color de marca desde BD + $brandColor = '#1565c0'; + try { + $row = Database::getInstance()->fetch("SELECT valor FROM lab_config WHERE clave = 'doc_color'"); + if ($row && preg_match('/^#[0-9a-fA-F]{3,8}$/', $row['valor'])) { + $brandColor = $row['valor']; + } + } catch (\Throwable $_) {} + + // Derivar color oscuro para gradiente + $hex = ltrim($brandColor, '#'); + $brandDark = sprintf('#%02x%02x%02x', + max(0, hexdec(substr($hex,0,2)) - 40), + max(0, hexdec(substr($hex,2,2)) - 40), + max(0, hexdec(substr($hex,4,2)) - 40) + ); + // Detectar base URL (para assets relativos) $base = defined('APP_URL') ? rtrim(APP_URL, '/') : ''; ?> @@ -48,26 +65,23 @@ class Layout - +