diff --git a/custom/otssignange/css/override.css b/custom/otssignange/css/override.css index ad0d92e..8ae1b59 100644 --- a/custom/otssignange/css/override.css +++ b/custom/otssignange/css/override.css @@ -48,7 +48,7 @@ body { position: fixed; left: 0; top: 0; - width: 260px; + width: auto !important; height: 100vh; background-color: #08132a; border-right: 1px solid rgba(255, 255, 255, 0.06); @@ -63,12 +63,14 @@ body { flex: 1; display: flex; flex-direction: column; - margin-left: 260px; + margin-left: calc(var(--ots-sidebar-width, 240px)) !important; } .ots-main, #page-wrapper { position: relative; + margin-left: calc(var(--ots-sidebar-width, 240px) - 1px) !important; + transition: margin-left 150ms ease-out; } .ots-content { @@ -168,18 +170,27 @@ body { display: flex; align-items: center; gap: 12px; - padding: 8px 12px; - color: #c8d5ee; + padding: 8px 16px 8px 12px; + color: #f9fbff; text-decoration: none; transition: all var(--transition-fast); position: relative; font-size: 14px; font-weight: 500; border-left: 2px solid transparent; - margin: 3px 10px; + margin: 3px 0; border-radius: 12px; min-height: 48px; line-height: 1.25; + width: 100%; + box-sizing: border-box; + padding-right: 48px; /* reserve space for caret */ +} + +/* Force readable text in sidebar links */ +.ots-sidebar a, +.ots-sidebar .ots-nav-text { + color: #f9fbff; } .ots-sidebar li.sidebar-list > a:hover { @@ -198,6 +209,13 @@ body { box-shadow: 0 8px 18px rgba(15, 23, 42, 0.25); } +.ots-sidebar li.sidebar-list.active > a .ots-nav-text, +.ots-sidebar li.sidebar-list > a.active .ots-nav-text, +.ots-sidebar li.sidebar-main.active > a .ots-nav-text, +.ots-sidebar li.sidebar-main > a.active .ots-nav-text { + color: #0b1221; +} + .ots-sidebar .ots-nav-icon { width: 28px; height: 28px; @@ -302,6 +320,11 @@ body { padding: 10px; } +/* Hide caret when collapsed */ +.ots-sidebar.collapsed .sidebar-group-caret { + display: none !important; +} + /* Center icons when collapsed */ .ots-sidebar.collapsed .ots-nav-icon { justify-self: center !important; @@ -326,24 +349,54 @@ body { display: flex; align-items: center; gap: 12px; - padding: 10px 12px; - margin: 6px 10px; + padding: 10px 16px 10px 12px; + margin: 6px 0; border-radius: 12px; - color: #d7e2f8; + color: #f9fbff; text-decoration: none; background: rgba(255, 255, 255, 0.03); transition: all var(--transition-fast); + position: relative; /* for absolutely positioned caret */ + width: 100%; + box-sizing: border-box; + padding-right: 48px; /* reserve space for caret */ +} + +/* Highlight parent item like screenshot */ +.ots-sidebar .sidebar-group.is-open > .sidebar-group-toggle, +.ots-sidebar .sidebar-group-toggle[aria-expanded="true"], +.ots-sidebar .sidebar-group-toggle.active { + background: #ffffff; + color: #0b1221 !important; + box-shadow: 0 10px 22px rgba(15, 23, 42, 0.2); +} + +.ots-sidebar .sidebar-group.is-open > .sidebar-group-toggle .ots-nav-text, +.ots-sidebar .sidebar-group.is-open > .sidebar-group-toggle .ots-nav-icon, +.ots-sidebar .sidebar-group.is-open > .sidebar-group-toggle .sidebar-group-caret, +.ots-sidebar .sidebar-group-toggle[aria-expanded="true"] .ots-nav-text, +.ots-sidebar .sidebar-group-toggle[aria-expanded="true"] .ots-nav-icon, +.ots-sidebar .sidebar-group-toggle[aria-expanded="true"] .sidebar-group-caret, +.ots-sidebar .sidebar-group-toggle.active .ots-nav-text, +.ots-sidebar .sidebar-group-toggle.active .ots-nav-icon, +.ots-sidebar .sidebar-group-toggle.active .sidebar-group-caret { + color: #0b1221 !important; } .sidebar-group-toggle:hover { - background: rgba(255, 255, 255, 0.08); + background: rgba(255, 255, 255, 0.1); color: #ffffff; } .sidebar-group-caret { - margin-left: auto; + position: absolute; + right: 12px; + top: 50%; + transform: translateY(-50%); font-size: 12px; - opacity: 0.8; + opacity: 0.85; + cursor: pointer; + pointer-events: auto; } .sidebar-submenu { @@ -351,15 +404,36 @@ body { margin: 4px 0 8px; padding: 0 0 0 12px; border-left: 1px solid rgba(255, 255, 255, 0.08); + display: none; } .sidebar-group.is-open .sidebar-group-caret { transform: rotate(180deg); } +.sidebar-group.is-open .sidebar-submenu { + display: block; +} + .sidebar-submenu .sidebar-list > a { - margin: 4px 10px 4px 18px; - background: rgba(255, 255, 255, 0.04); + margin: 4px 0; + background: rgba(15, 23, 42, 0.6); + width: 100%; + box-sizing: border-box; + padding-right: 48px; /* keep caret space for nested items */ + /* Slight indent for submenu items */ + padding-left: 28px !important; + border-left: 4px solid rgba(255, 255, 255, 0.9); + border-radius: 12px; + color: #f9fbff; +} + +/* Ensure parent toggles and top-level links span full sidebar width */ +.ots-sidebar .sidebar-group-toggle, +.ots-sidebar li.sidebar-list > a, +.ots-sidebar li.sidebar-main > a { + width: 100% !important; + box-sizing: border-box !important; } .sidebar-submenu .sidebar-list > a:hover { @@ -373,42 +447,7 @@ body { box-shadow: 0 8px 18px rgba(15, 23, 42, 0.25); } -.sidebar-footer { - border-top: 1px solid rgba(255, 255, 255, 0.08); - padding: 16px; - display: flex; - align-items: center; - justify-content: space-between; - gap: 12px; - background-color: rgba(15, 23, 42, 0.6); -} - -.sidebar-theme-toggle { - width: 36px; - height: 36px; - border-radius: 10px; - border: 0; - background: rgba(255, 255, 255, 0.08); - color: #ffffff; - display: inline-flex; - align-items: center; - justify-content: center; - cursor: pointer; - transition: all var(--transition-fast); -} - -.sidebar-theme-toggle:hover { - background: rgba(255, 255, 255, 0.16); -} - -.user-role { - display: inline-flex; - align-items: center; - gap: 8px; - font-size: 12px; - color: var(--color-text-secondary); - margin-bottom: 4px; -} +/* sidebar-footer removed; account bar intentionally omitted */ .nav-section-divider { padding: 12px 16px 8px; @@ -2860,6 +2899,49 @@ h1, h2, h3, h4, h5, h6, } /* All labels must be readable */ + +/* Strong override: force sidebar items to show icon then text (left-aligned) */ +#sidebar-wrapper .sidebar-list a, +#sidebar-wrapper .sidebar-main a, +.ots-sidebar .sidebar-group-toggle, +.ots-sidebar .sidebar-list > a { + display: flex !important; + flex-direction: row !important; + align-items: center !important; + gap: 8px !important; + white-space: nowrap !important; +} + +.ots-sidebar .ots-nav-icon, +#sidebar-wrapper .sidebar-list .ots-nav-icon, +#sidebar-wrapper .sidebar-main .ots-nav-icon { + display: inline-flex !important; + width: 26px !important; + height: 26px !important; + margin-right: 8px !important; + margin-left: 0 !important; + text-align: center !important; + vertical-align: middle !important; +} + +.ots-sidebar .ots-nav-text, +#sidebar-wrapper .sidebar-list .ots-nav-text { + display: inline-block !important; + flex: 1 1 auto !important; + order: 2 !important; +} + +.ots-sidebar .ots-nav-icon { order: 1 !important; } + +/* Ensure group caret stays to the far right */ +.sidebar-group-caret { margin-left: 12px !important; order: 3 !important; } + +/* Safety: collapse any grid-template overrides */ +.ots-sidebar .sidebar-group-toggle, .ots-sidebar .sidebar-list > a { grid-template-columns: none !important; } + +/* Reduce submenu left border padding so text fits better */ +.sidebar-submenu { padding-left: 8px !important; } + label, .label, .form-label, diff --git a/custom/otssignange/js/theme.js b/custom/otssignange/js/theme.js index effed8e..da1ae98 100644 --- a/custom/otssignange/js/theme.js +++ b/custom/otssignange/js/theme.js @@ -50,6 +50,8 @@ sidebar.classList.toggle('collapsed'); body.classList.toggle('ots-sidebar-collapsed', nowCollapsed); localStorage.setItem(STORAGE_KEYS.sidebarCollapsed, nowCollapsed ? 'true' : 'false'); + // Update measured sidebar width when collapsed state changes + updateSidebarWidth(); }); } @@ -69,6 +71,20 @@ }); } + /** + * Measure sidebar width and set CSS variable for layout + */ + function updateSidebarWidth() { + const sidebar = document.querySelector('.ots-sidebar'); + if (!sidebar) return; + // If collapsed, use the known collapsed width; otherwise use measured width + const collapsed = sidebar.classList.contains('collapsed'); + const base = collapsed ? 88 : sidebar.offsetWidth || sidebar.getBoundingClientRect().width || 240; + const padding = 5; // user requested ~5px padding + const value = Math.max(88, Math.round(base + padding)); + document.documentElement.style.setProperty('--ots-sidebar-width', `${value}px`); + } + /** * Initialize sidebar section collapse/expand functionality */ @@ -76,6 +92,15 @@ const groupToggles = document.querySelectorAll('.sidebar-group-toggle'); groupToggles.forEach(toggle => { + const group = toggle.closest('.sidebar-group'); + const submenu = group ? group.querySelector('.sidebar-submenu') : null; + const caret = toggle.querySelector('.sidebar-group-caret'); + if (submenu) { + const isOpen = group.classList.contains('is-open'); + submenu.style.display = isOpen ? 'block' : 'none'; + toggle.setAttribute('aria-expanded', isOpen.toString()); + } + toggle.addEventListener('click', function(e) { e.preventDefault(); @@ -88,7 +113,35 @@ toggle.setAttribute('aria-expanded', (!isOpen).toString()); submenu.style.display = isOpen ? 'none' : 'block'; }); + + if (caret) { + caret.addEventListener('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + toggle.click(); + }); + } }); + + // Capture-phase handler to override any conflicting listeners + document.addEventListener('click', function(e) { + const caret = e.target.closest('.sidebar-group-caret'); + const toggle = e.target.closest('.sidebar-group-toggle'); + const target = toggle || (caret ? caret.closest('.sidebar-group-toggle') : null); + if (!target) return; + + e.preventDefault(); + e.stopPropagation(); + + const group = target.closest('.sidebar-group'); + const submenu = group ? group.querySelector('.sidebar-submenu') : null; + if (!submenu) return; + + const isOpen = group.classList.contains('is-open'); + group.classList.toggle('is-open', !isOpen); + target.setAttribute('aria-expanded', (!isOpen).toString()); + submenu.style.display = isOpen ? 'none' : 'block'; + }, true); } /** @@ -273,6 +326,8 @@ } else { sidebar.classList.add('mobile'); } + // Recompute sidebar width on resize + updateSidebarWidth(); }); } @@ -405,6 +460,9 @@ enhanceTables(); makeResponsive(); initChartSafeguard(); + // Set initial sidebar width variable and keep it updated + updateSidebarWidth(); + window.addEventListener('resize', updateSidebarWidth); } // Wait for DOM to be ready diff --git a/custom/otssignange/views/authed-sidebar.twig b/custom/otssignange/views/authed-sidebar.twig index 1df8291..3bbabe3 100644 --- a/custom/otssignange/views/authed-sidebar.twig +++ b/custom/otssignange/views/authed-sidebar.twig @@ -27,8 +27,8 @@ {% set scheduleCount = currentUser.featureEnabledCount(["schedule.view", "daypart.view"]) %} {% if scheduleCount > 0 %} -