diff --git a/custom/otssignange/css/override-dark.css b/custom/otssignange/css/override-dark.css index 013518a..48edfb7 100644 --- a/custom/otssignange/css/override-dark.css +++ b/custom/otssignange/css/override-dark.css @@ -904,19 +904,29 @@ body.login, body.login-page, .xibo-login, #login, .login-wrapper { background-size: 48px 48px, cover; } +body.login-page .container { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 16px; +} + .login-card, .login-panel, .auth-card, .xibo-login-box, #login-box { width: 100%; - max-width: 560px; - border-radius: 12px; - padding: 32px 36px; - background: var(--login-panel-bg); - border: 1px solid rgba(255,255,255,0.04); - box-shadow: var(--ots-shadow-lg); + max-width: 520px; + border-radius: 16px; + padding: 36px 40px 34px; + background: linear-gradient(180deg, rgba(7,12,22,0.92), rgba(10,16,30,0.9)); + border: 1px solid rgba(255,255,255,0.08); + box-shadow: 0 28px 70px rgba(2, 6, 23, 0.55); color: var(--ots-text); + backdrop-filter: blur(14px); } .login-card .login-logo, @@ -942,23 +952,24 @@ body.login, body.login-page, .xibo-login, #login, .login-wrapper { /* Brand text next to logo on login */ .login-brand { display: flex; + flex-direction: column; align-items: center; justify-content: center; - gap: 18px; + gap: 10px; margin-bottom: 18px; } .login-brand .login-logo { - width: 92px; - height: 92px; + width: 72px; + height: 72px; display: inline-block; } .login-brand-text { color: var(--ots-text); - font-size: 1.5rem; - font-weight: 700; - letter-spacing: 0.01em; + font-size: 1.2rem; + font-weight: 600; + letter-spacing: 0.02em; } .login-card h1, @@ -972,8 +983,9 @@ body.login, body.login-page, .xibo-login, #login, .login-wrapper { .login-card .lead, .login-panel .lead { text-align: center; - color: var(--ots-text-muted); + color: rgba(226,232,240,0.74); margin-bottom: 18px; + font-size: 0.95rem; } .login-card .form-group, @@ -989,12 +1001,12 @@ body.login, body.login-page, .xibo-login, #login, .login-wrapper { .login-panel input[type="email"], .login-panel input[type="password"] { width: 100%; - background: linear-gradient(180deg, rgba(255,255,255,0.016), rgba(255,255,255,0.01)); - border: 1px solid rgba(255,255,255,0.06); + background: rgba(11, 18, 33, 0.65); + border: 1px solid rgba(148, 163, 184, 0.18); color: var(--ots-text); - padding: 14px 16px; - border-radius: 12px; - font-size: 1rem; + padding: 12px 14px; + border-radius: 10px; + font-size: 0.98rem; line-height: 1.25; transition: border-color 180ms ease, box-shadow 180ms ease, background 180ms ease; } @@ -1003,9 +1015,9 @@ body.login, body.login-page, .xibo-login, #login, .login-wrapper { .login-panel input:focus, .login-card .form-control:focus { outline: none; - border-color: rgba(255,138,0,0.95); - background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)); - box-shadow: 0 8px 22px rgba(0,0,0,0.32), 0 0 0 6px rgba(255,138,0,0.04); + border-color: rgba(255,138,0,0.85); + background: rgba(11, 18, 33, 0.75); + box-shadow: 0 10px 26px rgba(0,0,0,0.38), 0 0 0 5px rgba(255,138,0,0.08); } .login-card input::placeholder, @@ -1034,13 +1046,13 @@ body.login, body.login-page, .xibo-login, #login, .login-wrapper { gap: 8px; width: 100%; padding: 10px 14px; - background: rgba(255,255,255,0.03); - color: var(--ots-text); + background: #f8fafc; + color: #0b1221 !important; border-radius: 10px; - border: 1px solid rgba(255,255,255,0.12); + border: 1px solid rgba(255,255,255,0.8); font-weight: 600; - box-shadow: none; - transition: background 160ms ease, border-color 160ms ease, color 160ms ease, box-shadow 160ms ease; + box-shadow: 0 10px 22px rgba(2,6,23,0.35); + transition: background 160ms ease, border-color 160ms ease, color 160ms ease, box-shadow 160ms ease, transform 160ms ease; } .login-card .btn-signin .icon, @@ -1054,15 +1066,16 @@ body.login, body.login-page, .xibo-login, #login, .login-wrapper { .login-card .btn-signin:hover, .login-panel .btn-signin:hover { - background: rgba(255,255,255,0.06); - border-color: rgba(255,255,255,0.18); + background: #ffffff; + border-color: rgba(255,255,255,0.95); + transform: translateY(-1px); } .login-card .btn-signin:focus, .login-panel .btn-signin:focus { outline: none; - box-shadow: 0 6px 18px rgba(0,0,0,0.28), 0 0 0 6px rgba(255,138,0,0.04); - border-color: rgba(255,138,0,0.28); + box-shadow: 0 10px 24px rgba(0,0,0,0.32), 0 0 0 5px rgba(255,138,0,0.18); + border-color: rgba(255,138,0,0.45); } .login-card .forgot-link, @@ -1075,7 +1088,7 @@ body.login, body.login-page, .xibo-login, #login, .login-wrapper { /* Small screens: compress card padding */ @media (max-width: 520px) { - .login-card, .login-panel { padding: 20px; border-radius: 10px; } + .login-card, .login-panel { padding: 24px; border-radius: 12px; } .login-card .login-logo .logo-icon { width: 72px; height: 72px; } } @@ -1129,7 +1142,7 @@ body.login-page::before { left: -8%; top: -6%; background: radial-gradient(circle at 30% 30%, rgba(79,140,255,0.65), rgba(79,140,255,0.18) 35%, transparent 50%); - animation: ots-blob-move-1 20s ease-in-out infinite alternate !important; + animation: ots-blob-move-1 16s ease-in-out infinite alternate !important; } .ots-login-blob--2 { @@ -1138,7 +1151,7 @@ body.login-page::before { right: 6%; bottom: 18%; background: radial-gradient(circle at 60% 40%, rgba(255,138,0,0.45), rgba(255,138,0,0.14) 36%, transparent 55%); - animation: ots-blob-move-2 26s ease-in-out infinite alternate !important; + animation: ots-blob-move-2 20s ease-in-out infinite alternate !important; } .ots-login-blob--3 { @@ -1147,7 +1160,11 @@ body.login-page::before { left: 18%; bottom: -4%; background: radial-gradient(circle at 40% 60%, rgba(94,200,255,0.28), rgba(94,200,255,0.08) 40%, transparent 60%); - animation: ots-blob-move-3 22s ease-in-out infinite alternate !important; + animation: ots-blob-move-3 18s ease-in-out infinite alternate !important; +} + +.ots-login-bg { + animation-duration: 10s !important; } /* Disable other animations/transitions on the login page so only blobs animate */ diff --git a/custom/otssignange/css/override.css b/custom/otssignange/css/override.css index f6527b3..330e541 100644 --- a/custom/otssignange/css/override.css +++ b/custom/otssignange/css/override.css @@ -52,7 +52,47 @@ --ots-sidebar-item-radius: 10px; --ots-sidebar-item-height: 44px; --ots-sidebar-item-padding-x: 12px; - + --ots-sidebar-content-gap: 12px; + + /* Editor (playlist / layout timeline) */ + --editor-modal-bg: #1a1a2e; + --editor-modal-content-bg: #1e293b; + --editor-modal-header-bg: #0f172a; + --editor-modal-header-text: #f1f5f9; + --editor-body-bg: #1e293b; + --editor-border: #334155; + --editor-text: #e2e8f0; + --editor-text-secondary: #94a3b8; + --editor-toolbar-bg: #0f172a; + --editor-toolbar-text: #e2e8f0; + --editor-toolbar-pane-bg: #1e293b; + --editor-toolbar-pane-text: #e2e8f0; + --editor-footer-controls-bg: #0f172a; + --editor-footer-info-bg: var(--color-primary); + --editor-footer-text: #f1f5f9; + --editor-widget-bg: #334155; + --editor-widget-border: #475569; + --editor-widget-text: #e2e8f0; + --editor-widget-label-bg: #0f172a; + --editor-widget-label-text: #94a3b8; + --editor-widget-hover-bg: #3b4d6b; + --editor-widget-selected-bg: #166534; + --editor-widget-multi-bg: #c2410c; + --editor-widget-multi-hover-bg: #ea580c; + --editor-left-margin-bg: #0f172a; + --editor-timegrid-line: #475569; + --editor-timegrid-text: #64748b; + --editor-timegrid-overlay: rgba(30, 41, 59, 0.7); + --editor-timeline-bg: rgba(30, 41, 59, 0.65); + --editor-scrollbar-track: #1e293b; + --editor-scrollbar-thumb: #475569; + --editor-scrollbar-thumb-hover: #64748b; + --editor-properties-bg: #1e293b; + --editor-properties-border: #166534; + --editor-header-bg: #0f172a; + --editor-back-btn-bg: #0f172a; + --editor-back-btn-text: var(--color-primary-light); + color-scheme: dark; } @@ -200,7 +240,46 @@ body.ots-light-mode { --ots-sidebar-item-radius: 10px; --ots-sidebar-item-height: 44px; --ots-sidebar-item-padding-x: 12px; - + + /* Editor (playlist / layout timeline) */ + --editor-modal-bg: #e8e8e8; + --editor-modal-content-bg: #ffffff; + --editor-modal-header-bg: #f1f5f9; + --editor-modal-header-text: #0f172a; + --editor-body-bg: #ffffff; + --editor-border: #e2e8f0; + --editor-text: #0f172a; + --editor-text-secondary: #475569; + --editor-toolbar-bg: #1e3a5f; + --editor-toolbar-text: #f1f5f9; + --editor-toolbar-pane-bg: #f3f8ff; + --editor-toolbar-pane-text: #1775f6; + --editor-footer-controls-bg: #0e4694; + --editor-footer-info-bg: var(--color-primary); + --editor-footer-text: #fcfcfc; + --editor-widget-bg: #e8f1fe; + --editor-widget-border: #0e4694; + --editor-widget-text: #121a5e; + --editor-widget-label-bg: transparent; + --editor-widget-label-text: #f3f8ff; + --editor-widget-hover-bg: #d4e4f7; + --editor-widget-selected-bg: #6ec071; + --editor-widget-multi-bg: #eb7857; + --editor-widget-multi-hover-bg: #f09a82; + --editor-left-margin-bg: #e9e9e9; + --editor-timegrid-line: #cecece; + --editor-timegrid-text: #898989; + --editor-timegrid-overlay: rgba(255, 255, 255, 0.7); + --editor-timeline-bg: rgba(255, 255, 255, 0.65); + --editor-scrollbar-track: #f3f8ff; + --editor-scrollbar-thumb: #0e4694; + --editor-scrollbar-thumb-hover: #1264d6; + --editor-properties-bg: #f3f8ff; + --editor-properties-border: #6ec071; + --editor-header-bg: #f1f5f9; + --editor-back-btn-bg: #1e3a5f; + --editor-back-btn-text: #ffffff; + background-color: var(--color-background); color: var(--color-text-primary); } @@ -264,6 +343,24 @@ body.ots-light-mode .sidebar-submenu .sidebar-list > a { border-left-color: #cbd5e1; } +/* Light-mode collapsed flyout panel */ +body.ots-light-mode .ots-sidebar.collapsed .sidebar-submenu { + background: #ffffff !important; + border-color: #e2e8f0 !important; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12) !important; +} + +body.ots-light-mode .ots-sidebar.collapsed .sidebar-submenu .sidebar-list > a { + color: #334155 !important; + background: transparent !important; + border-left: none !important; +} + +body.ots-light-mode .ots-sidebar.collapsed .sidebar-submenu .sidebar-list > a:hover { + background: rgba(59, 130, 246, 0.1) !important; + color: #1d4ed8 !important; +} + body.ots-light-mode .sidebar-header { border-bottom-color: #e2e8f0; background: #f1f5f9; @@ -367,26 +464,37 @@ html, body, #page-wrapper, .ots-main, .ots-content, .page-content { position: fixed; left: 0; top: 0; - width: var(--ots-sidebar-width) !important; + width: max-content !important; + min-width: var(--ots-sidebar-collapsed-width); + max-width: 300px; height: 100vh; - background-color: var(--ots-sidebar-bg); - border-right: 1px solid var(--ots-sidebar-border); + background-color: var(--ots-sidebar-bg) !important; padding: 0; display: flex; flex-direction: column; - overflow: hidden; + overflow-x: hidden; + overflow-y: auto; z-index: 1200; transition: width 200ms ease; } +.ots-sidebar .ots-nav-text, +.ots-sidebar .sidebar-submenu .ots-nav-text { + white-space: nowrap; +} + +#sidebar-wrapper { + background-color: var(--ots-sidebar-bg) !important; +} + .ots-main { flex: 1; display: flex; flex-direction: column; position: relative; - margin-left: var(--ots-sidebar-width) !important; - width: calc(100vw - var(--ots-sidebar-width)) !important; - max-width: calc(100vw - var(--ots-sidebar-width)) !important; + margin-left: var(--ots-sidebar-actual-width, var(--ots-sidebar-width)) !important; + width: calc(100vw - var(--ots-sidebar-actual-width, var(--ots-sidebar-width))) !important; + max-width: calc(100vw - var(--ots-sidebar-actual-width, var(--ots-sidebar-width))) !important; transition: margin-left 200ms ease, width 200ms ease, max-width 200ms ease; overflow-x: hidden !important; box-sizing: border-box !important; @@ -410,11 +518,11 @@ html, body, #page-wrapper, .ots-main, .ots-content, .page-content { } #content-wrapper { - margin-left: var(--ots-sidebar-width) !important; - width: calc(100vw - var(--ots-sidebar-width)) !important; - max-width: calc(100vw - var(--ots-sidebar-width)) !important; + margin-left: var(--ots-sidebar-actual-width, var(--ots-sidebar-width)) !important; + width: calc(100vw - var(--ots-sidebar-actual-width, var(--ots-sidebar-width))) !important; + max-width: calc(100vw - var(--ots-sidebar-actual-width, var(--ots-sidebar-width))) !important; transition: margin-left 200ms ease, width 200ms ease, max-width 200ms ease; - padding-left: 16px !important; + padding-left: var(--ots-sidebar-content-gap) !important; padding-right: 16px !important; border-left: none !important; box-shadow: none !important; @@ -423,6 +531,1098 @@ html, body, #page-wrapper, .ots-main, .ots-content, .page-content { box-sizing: border-box !important; } +/* ============================================================================ + PLAYLIST / LAYOUT EDITOR – themed for dark/light mode + The .editor-modal is AJAX-injected into #editor-container (inside + #page-wrapper > #content-wrapper > .page-content). It borrows Bootstrap's + .modal class for position:fixed but is NOT opened via $.modal(). + All colours use --editor-* CSS variables defined in :root and + body.ots-light-mode so they follow the active theme. + ============================================================================ */ + +/* --- 1. The .editor-modal overlay ---------------------------------------- */ +.editor-modal.modal { + position: fixed !important; + top: 0 !important; + left: 0 !important; + width: 100% !important; + height: 100% !important; + max-width: none !important; + margin: 0 !important; + background-color: var(--editor-modal-bg) !important; + background-image: none !important; + border: none !important; + box-shadow: none !important; + z-index: 1201 !important; + display: block !important; + opacity: 1 !important; + overflow: auto !important; +} + +.editor-modal .editor-modal-dialog { + max-width: 100%; + height: calc(100% - 6rem); + margin: 3rem; +} + +.editor-modal .editor-modal-content { + background-color: var(--editor-modal-content-bg) !important; + color: var(--editor-text) !important; + border: none !important; + height: 100%; +} + +.editor-modal .editor-modal-header { + background-color: var(--editor-modal-header-bg) !important; + color: var(--editor-modal-header-text) !important; + border-bottom: 1px solid var(--editor-border) !important; +} + +.editor-modal .editor-modal-header .modal-header--left, +.editor-modal .editor-modal-title { + color: var(--editor-modal-header-text) !important; +} + +.editor-modal .editor-modal-header .playlist-info-widgets, +.editor-modal .editor-modal-header .playlist-info-duration { + color: var(--editor-modal-header-text) !important; +} + +.editor-modal .editor-modal-close { + color: var(--editor-text-secondary) !important; +} + +.editor-modal .editor-modal-body { + background-color: var(--editor-modal-content-bg) !important; +} + +/* --- 2. Inner editor containers ------------------------------------------ */ +#playlist-editor, +#layout-editor, +.playlist-editor, +.layout-editor { + background-color: var(--editor-body-bg) !important; + border-color: var(--color-primary) !important; + color: var(--editor-text) !important; +} + +#playlist-editor-container, +#playlist-editor-container .editor-body, +.playlist-editor-inline-container { + background-color: var(--editor-body-bg) !important; + background-image: none !important; +} + +/* --- 3. Left margin gutter ---------------------------------------------- */ +#playlist-editor .left-margin { + background-color: var(--editor-left-margin-bg) !important; +} + +/* --- 4. Time grid (horizontal lines behind timeline) -------------------- */ +#playlist-editor .time-grid { + color: var(--editor-timegrid-text) !important; +} + +#playlist-editor .time-grid .time-grid-step { + background-color: var(--editor-timegrid-line) !important; +} + +#playlist-editor .time-grid .step-value { + color: var(--editor-timegrid-text) !important; +} + +#playlist-editor .time-grid::after { + background-color: var(--editor-timegrid-overlay) !important; +} + +/* --- 5. Timeline area ---------------------------------------------------- */ +#playlist-timeline { + background-color: var(--editor-timeline-bg) !important; + background-image: none !important; +} + +#timeline-container { + background-color: transparent !important; +} + +/* --- 6. Widget cards in timeline ----------------------------------------- */ +#playlist-timeline .playlist-widget { + background-color: var(--editor-widget-bg) !important; + outline-color: var(--editor-widget-border) !important; + color: var(--editor-widget-text) !important; +} + +#playlist-timeline .playlist-widget .widgetLabel { + background-color: var(--editor-widget-label-bg) !important; + color: var(--editor-widget-label-text) !important; +} + +#playlist-timeline .playlist-widget .widgetName { + color: var(--editor-widget-text) !important; +} + +#playlist-timeline .playlist-widget .widgetProperties, +#playlist-timeline .playlist-widget .widgetProperties i { + color: var(--editor-text-secondary) !important; +} + +#playlist-timeline .playlist-widget .widgetDuration { + color: var(--editor-widget-label-text) !important; +} + +#playlist-timeline .playlist-widget i.editProperty { + color: var(--editor-widget-text) !important; +} + +#playlist-timeline .playlist-widget.selectable:hover { + background-color: var(--editor-widget-hover-bg) !important; +} + +#playlist-timeline .playlist-widget.selected { + background-color: var(--editor-widget-selected-bg) !important; +} + +/* Multi-select */ +#playlist-editor.multi-select .playlist-widget:hover { + background-color: var(--editor-widget-multi-hover-bg) !important; +} + +#playlist-editor.multi-select .playlist-widget.multi-selected { + background-color: var(--editor-widget-multi-bg) !important; +} + +/* --- 7. Footer bar ------------------------------------------------------- */ +#playlist-editor .editor-footer .footer-controls { + background-color: var(--editor-footer-controls-bg) !important; +} + +#playlist-editor .editor-footer .footer-controls .btn { + color: var(--editor-footer-text) !important; +} + +#playlist-editor .editor-footer .footer-controls .btn:hover { + color: #ffffff !important; + background-color: var(--color-secondary, #121a5e) !important; +} + +#playlist-editor .editor-footer .footer-info { + background-color: var(--editor-footer-info-bg) !important; + color: var(--editor-footer-text) !important; +} + +#playlist-editor .editor-footer .footer-info .selected-info { + color: var(--editor-footer-text) !important; +} + +#playlist-editor .editor-footer .footer-actions button { + color: var(--editor-footer-text) !important; +} + +/* --- 8. Editor toolbar / sidebar (fixed left panel) ---------------------- */ +.editor-toolbar.editor-side-bar-playlist-editor nav, +.editor-toolbar.editor-side-bar nav, +.editor-toolbar nav { + background-color: var(--editor-toolbar-bg) !important; + color: var(--editor-toolbar-text) !important; +} + +.editor-toolbar nav .toolbar-menu-content .toolbar-pane { + background-color: var(--editor-toolbar-pane-bg) !important; + color: var(--editor-toolbar-pane-text) !important; +} + +.editor-toolbar nav .toolbar-menu-content .toolbar-pane .content-title { + color: var(--editor-toolbar-pane-text) !important; +} + +.editor-toolbar nav .toolbar-menu-content .toolbar-pane .close-content { + color: var(--editor-text-secondary) !important; +} + +/* Toolbar card rows */ +.editor-toolbar nav tr.toolbar-card { + color: var(--editor-toolbar-pane-text) !important; +} + +.editor-toolbar nav tr.toolbar-card.card-selected { + background-color: color-mix(in srgb, var(--color-primary) 15%, transparent) !important; +} + +/* Toolbar buttons */ +.editor-toolbar nav .toolbar-menu .toolbar-menu-btn { + color: var(--editor-toolbar-text) !important; +} + +.editor-toolbar nav .toolbar-menu .toolbar-menu-btn:hover, +.editor-toolbar nav .toolbar-menu .toolbar-menu-btn.active { + background-color: rgba(255, 255, 255, 0.15) !important; +} + +/* --- 9. Back button (fixed top-left) ------------------------------------- */ +.editor-modal .back-button, +.back-button { + background-color: var(--editor-back-btn-bg) !important; +} + +.editor-modal .back-button a, +.back-button a { + color: var(--editor-back-btn-text) !important; +} + +.editor-modal .back-button a:hover, +.back-button a:hover { + background-color: rgba(255, 255, 255, 0.1) !important; +} + +.editor-modal .back-button span { + color: var(--editor-back-btn-text) !important; +} + +/* --- 10. Properties panel (right side) ----------------------------------- */ +.properties-panel-playlist-editor, +.properties-panel-container { + background-color: var(--editor-body-bg) !important; +} + +.properties-panel-container #properties-panel { + background-color: var(--editor-body-bg) !important; + color: var(--editor-text) !important; +} + +.properties-panel-container #properties-panel-form-container { + background-color: var(--editor-modal-content-bg) !important; + color: var(--editor-text) !important; +} + +.properties-panel-container #properties-panel .loading-container { + background-color: var(--editor-properties-bg) !important; +} + +.properties-panel-container #properties-panel .loading-icon { + color: var(--color-primary) !important; +} + +.properties-panel-container #properties-panel .unsuccessMessage { + color: #ffffff !important; +} + +/* Tab styling for properties panel — initial pass (reinforced at end of file) */ +.properties-panel-container #properties-panel .nav .nav-link, +.properties-panel-container #properties-panel .nav > li > a, +#properties-panel .nav .nav-link, +#properties-panel .nav > li > a { + color: var(--editor-text-secondary) !important; + background: var(--editor-header-bg) !important; + background-color: var(--editor-header-bg) !important; + border: none !important; + border-color: transparent !important; + box-shadow: none !important; + opacity: 1 !important; +} + +.properties-panel-container #properties-panel .nav .nav-link.active, +.properties-panel-container #properties-panel .nav > li > a.active, +#properties-panel .nav .nav-link.active, +#properties-panel .nav > li > a.active { + color: var(--color-primary) !important; + background: var(--editor-header-bg) !important; + background-color: var(--editor-header-bg) !important; + border: none !important; + border-bottom: 2px solid var(--color-primary) !important; + opacity: 1 !important; +} + +.properties-panel-container #properties-panel .nav, +.properties-panel-container #properties-panel .nav-tabs, +#properties-panel .nav, +#properties-panel .nav-tabs { + background: var(--editor-header-bg) !important; + background-color: var(--editor-header-bg) !important; +} + +.properties-panel-container #properties-panel .form-content label { + color: var(--editor-text) !important; +} + +/* More aggressive label overrides for all label elements in properties panel */ +#properties-panel label, +#properties-panel .label, +#properties-panel .form-label, +.properties-panel-container label, +.properties-panel-container .label, +.properties-panel-container .form-label, +.form-group label { + color: var(--editor-text) !important; +} + +.properties-panel-container #properties-panel .form-content .form-control { + background-color: var(--color-surface) !important; + color: var(--editor-text) !important; + border-color: var(--editor-border) !important; +} + +/* Select2 elements inside properties panel */ +.properties-panel-container .select2-container--default .select2-selection--single { + background-color: var(--color-surface) !important; + color: var(--editor-text) !important; + border-color: var(--editor-border) !important; +} + +.properties-panel-container .select2-container--default .select2-selection--single .select2-selection__rendered { + color: var(--editor-text) !important; +} + +/* Placeholder text in select2 */ +.properties-panel-container .select2-container--default .select2-selection--single .select2-selection__placeholder { + color: var(--editor-text-secondary) !important; +} + +.properties-panel-container .select2-container--default .select2-selection--single .select2-selection__arrow b { + border-color: var(--editor-text-secondary) transparent transparent transparent !important; +} + +/* Select2 dropdown theming (appended to body, not in panel) */ +.select2-container--open .select2-dropdown { + background-color: var(--color-surface) !important; + color: var(--editor-text, var(--color-text-primary)) !important; + border-color: var(--editor-border, var(--color-border)) !important; +} + +.select2-container--default .select2-results__option { + color: var(--editor-text, var(--color-text-primary)) !important; +} + +.select2-container--default .select2-results__option[aria-selected=true] { + background-color: color-mix(in srgb, var(--color-primary) 15%, var(--color-surface)) !important; + color: var(--editor-text, var(--color-text-primary)) !important; +} + +.select2-container--default .select2-search--dropdown .select2-search__field { + background-color: var(--color-surface-elevated) !important; + color: var(--color-text-primary) !important; + border-color: var(--color-border) !important; +} + +#playlist-properties-panel { + background-color: var(--editor-properties-bg) !important; + border-color: var(--editor-properties-border) !important; + color: var(--editor-text) !important; +} + +/* --- 11. Scrollbars inside editor ---------------------------------------- */ +#playlist-editor ::-webkit-scrollbar-track, +#layout-editor ::-webkit-scrollbar-track { + background: var(--editor-scrollbar-track) !important; +} + +#playlist-editor ::-webkit-scrollbar-thumb, +#layout-editor ::-webkit-scrollbar-thumb { + background: var(--editor-scrollbar-thumb) !important; +} + +#playlist-editor ::-webkit-scrollbar-thumb:hover, +#layout-editor ::-webkit-scrollbar-thumb:hover { + background: var(--editor-scrollbar-thumb-hover) !important; +} + +/* --- 12. Drag-drop overlay ----------------------------------------------- */ +#timeline-overlay-container { + background-color: var(--editor-body-bg) !important; +} + +#timeline-overlay-container .timeline-overlay-step { + background-color: var(--color-primary-light) !important; +} + +#timeline-overlay-container .timeline-overlay-step:hover { + background-color: var(--color-primary-lighter, #dbeafe) !important; +} + +/* --- 13. Layout editor viewer panel -------------------------------------- */ +#layout-editor { + background-color: var(--editor-body-bg) !important; + color: var(--editor-text) !important; +} + +#layout-editor .main-panel-wrapper { + background-color: var(--editor-left-margin-bg) !important; + border-color: var(--color-primary-light) !important; +} + +#layout-editor #layout-viewer { + background-color: var(--editor-left-margin-bg) !important; +} + +#layout-editor .editor-bottom-bar { + background-color: var(--editor-footer-controls-bg) !important; + color: var(--editor-footer-text) !important; +} + +/* --- 15. Properties panel – nav tabs, forms, buttons, labels ------------- */ + +/* Tab navigation inside properties panel */ +.properties-panel-container .nav > li > a, +#properties-panel .nav > li > a, +#properties-panel .form-container .nav > li > a { + color: var(--editor-text-secondary) !important; + background: var(--editor-header-bg) !important; + background-color: var(--editor-header-bg) !important; + border: none !important; +} + +/* Widget editor tabs (Configure/Advanced) should blend with surrounding background */ +.editor-modal .widget-form .nav-tabs, +.editor-modal .widget-form .nav-tabs .nav-link { + background-color: transparent !important; + border-color: transparent !important; +} + +.editor-modal .widget-form .nav-tabs .nav-link { + color: var(--editor-text) !important; + opacity: 1 !important; +} + +.editor-modal .widget-form .nav-tabs .nav-link.active { + color: var(--color-primary) !important; + border-bottom: 2px solid var(--color-primary) !important; + background-color: transparent !important; +} + +/* Ultra-specific override to beat editor tab defaults */ +#properties-panel .widget-form ul.nav.nav-tabs, +#properties-panel .widget-form ul.nav.nav-tabs > li.nav-item, +#properties-panel .widget-form ul.nav.nav-tabs > li.nav-item > a.nav-link, +#properties-panel .widget-form ul.nav.nav-tabs > li.nav-item > a.nav-link > span, +.editor-modal #properties-panel .widget-form ul.nav.nav-tabs, +.editor-modal #properties-panel .widget-form ul.nav.nav-tabs > li.nav-item, +.editor-modal #properties-panel .widget-form ul.nav.nav-tabs > li.nav-item > a.nav-link, +.editor-modal #properties-panel .widget-form ul.nav.nav-tabs > li.nav-item > a.nav-link > span { + background-color: transparent !important; + background-image: none !important; + box-shadow: none !important; + border-color: transparent !important; +} + +#properties-panel .widget-form ul.nav.nav-tabs > li.nav-item > a.nav-link, +.editor-modal #properties-panel .widget-form ul.nav.nav-tabs > li.nav-item > a.nav-link { + color: var(--editor-text) !important; + opacity: 1 !important; +} + +#properties-panel .widget-form ul.nav.nav-tabs > li.nav-item > a.nav-link.active, +.editor-modal #properties-panel .widget-form ul.nav.nav-tabs > li.nav-item > a.nav-link.active { + color: var(--color-primary) !important; + border-bottom: 2px solid var(--color-primary) !important; + background-color: transparent !important; +} + +.properties-panel-container .nav > li > a.active, +#properties-panel .nav > li > a.active, +.form-container .nav > li > a.active { + color: var(--color-primary) !important; + background-color: var(--editor-modal-content-bg) !important; +} + +/* Form groups, labels, text in properties panel */ +#properties-panel .form-group, +#properties-panel .form-check, +#properties-panel .input-group, +#properties-panel label, +#properties-panel .form-label, +#properties-panel legend, +#properties-panel .help-block, +#properties-panel .control-label { + color: var(--editor-text) !important; +} + +/* Info/help icons */ +#properties-panel .info-icon, +#properties-panel .fa-info-circle, +#properties-panel .fa-question-circle { + color: var(--color-primary) !important; +} + +/* Action buttons in properties panel */ +#properties-panel .button-container .btn, +#properties-panel .form-buttons .btn { + color: var(--editor-text) !important; + border-color: var(--editor-border) !important; +} + +#properties-panel .button-container .btn-info, +#properties-panel .form-buttons .btn-info { + background-color: var(--color-primary) !important; + color: #ffffff !important; + border-color: var(--color-primary) !important; +} + +#properties-panel .button-container .btn-white, +#properties-panel .button-container .btn-default, +#properties-panel .form-buttons .btn-white, +#properties-panel .form-buttons .btn-default { + background-color: var(--color-surface) !important; + color: var(--editor-text) !important; + border-color: var(--editor-border) !important; +} + +/* Actions content buttons (layout editor actions pane) */ +#properties-panel .actions-content-button { + background-color: var(--color-surface-elevated) !important; + color: var(--color-primary) !important; + border-color: var(--editor-border) !important; +} + +/* Action forms inside properties panel */ +#properties-panel .action-edit-form, +#properties-panel .action-view { + background-color: var(--color-surface) !important; + border-color: var(--editor-border) !important; +} + +#properties-panel .action-label, +#properties-panel .action-value { + color: var(--editor-text) !important; +} + +#properties-panel .action-btn { + color: #ffffff !important; +} + +#properties-panel .action-btn[data-action="close"], +#properties-panel .action-edit-widget-btn { + color: var(--color-primary) !important; + border-color: var(--editor-border) !important; +} + +/* Action target widget controls */ +#properties-panel .action-target-widget-edit-container { + background-color: var(--color-surface-elevated) !important; +} + +#properties-panel .action-target-widget-dropdown-button { + color: var(--color-primary) !important; + border-color: var(--editor-border) !important; +} + +#properties-panel .action-target-widget-dropdown-container { + background-color: var(--color-surface) !important; +} + +#properties-panel .action-target-widget-dropdown-container .action-edit-widget-btn { + color: var(--editor-text) !important; +} + +/* Form content title border */ +#properties-panel .form-content-title { + border-bottom-color: var(--editor-border) !important; + color: var(--editor-text) !important; +} + +/* Textarea buttons bar (rich text) */ +#properties-panel .text-area-buttons { + background-color: var(--color-surface-elevated) !important; +} + +/* Panel headings */ +#properties-panel .panel-heading { + background-color: var(--color-surface-elevated) !important; +} + +#properties-panel .panel-title { + color: var(--color-primary) !important; +} + +/* Snippet selector */ +#properties-panel .snippet-selector .select2-selection { + background-color: var(--color-surface-elevated) !important; +} + +#properties-panel .snippet-selector .select2-selection__placeholder { + color: var(--editor-text-secondary) !important; +} + +/* Image replace area */ +#properties-panel .image-replace-control-area { + color: var(--editor-text) !important; + background-color: var(--color-surface-elevated) !important; +} + +/* Rich text dimensions control */ +#properties-panel .rich-text-dimensions-control.detached { + background-color: var(--color-surface) !important; + color: var(--editor-text) !important; +} + +/* Button switch input group */ +#properties-panel .button-switch-input-group button { + color: var(--color-primary) !important; + border-color: var(--editor-border) !important; +} + +/* Description / compat messages */ +#properties-panel .desc, +#properties-panel .message { + color: var(--editor-text-secondary) !important; +} + +/* Developer template controls */ +#properties-panel .developer-template-placeholder { + color: var(--color-primary) !important; + background-color: var(--color-surface-elevated) !important; +} + +#properties-panel .developer-template-control-item { + background-color: var(--color-surface-elevated) !important; + color: var(--editor-text) !important; +} + +/* Background image controls */ +#properties-panel .background-image-add { + background-color: var(--color-surface-elevated) !important; + color: var(--editor-text) !important; +} + +#properties-panel .background-image-actions .btn-group { + background-color: var(--color-surface) !important; +} + +/* --- 16. Toolbar pane cards & content ------------------------------------ */ + +/* Toolbar cards */ +.editor-toolbar .toolbar-card { + background-color: var(--color-surface-elevated) !important; + color: var(--editor-text) !important; +} + +.editor-toolbar .toolbar-card .card-icon { + color: var(--color-primary) !important; +} + +.editor-toolbar .toolbar-card .media-title { + color: var(--editor-text) !important; +} + +.editor-toolbar .toolbar-card .media-duration { + background-color: var(--editor-footer-controls-bg) !important; + color: var(--editor-footer-text) !important; +} + +.editor-toolbar .toolbar-card .select-button { + background-color: var(--color-surface-elevated) !important; + color: var(--editor-toolbar-text) !important; +} + +.editor-toolbar .toolbar-card .preview-button { + background-color: var(--color-primary) !important; + color: #ffffff !important; +} + +.editor-toolbar .toolbar-card.has-thumb .toolbar-content { + color: var(--editor-text) !important; +} + +.editor-toolbar .toolbar-playlists-pane .toolbar-card-preview { + background-color: var(--color-surface-elevated) !important; + color: var(--editor-text) !important; +} + +/* Upload container */ +.editor-toolbar .upload-container { + background-color: var(--color-surface) !important; + color: var(--editor-text) !important; +} + +/* Show more button */ +.editor-toolbar .show-more { + background-color: var(--color-surface) !important; + color: var(--color-primary) !important; +} + +/* Provider badge */ +.editor-toolbar .provider img { + background-color: var(--color-surface) !important; +} + +/* Toolbar search forms */ +.editor-toolbar .toolbar-pane form label { + color: var(--editor-toolbar-pane-text) !important; +} + +.editor-toolbar .toolbar-pane form .form-control { + background-color: var(--color-surface) !important; + color: var(--editor-text) !important; + border-color: var(--editor-border) !important; +} + +/* Toolbar navbar buttons (bottom icons) */ +.editor-toolbar .navbar-buttons a { + color: var(--editor-toolbar-text) !important; +} + +.editor-toolbar .navbar-buttons a.active { + background-color: var(--color-surface-elevated) !important; + color: var(--color-primary) !important; +} + +/* Toolbar navbar submenu */ +.editor-toolbar .navbar-submenu > a { + color: var(--editor-toolbar-text) !important; +} + +.editor-toolbar .navbar-submenu > a:hover { + background-color: rgba(255, 255, 255, 0.1) !important; + color: #ffffff !important; +} + +.editor-toolbar .navbar-submenu .trash-container { + color: var(--color-danger) !important; +} + +/* --- 17. Layout editor top bar & bottom bar ------------------------------ */ + +/* Top bar */ +.editor-top-bar nav, +body.editor-opened .header-side { + background-color: var(--editor-modal-header-bg) !important; + color: var(--editor-text) !important; +} + +.editor-top-bar .navbar-text.layout-info { + color: var(--editor-text) !important; +} + +/* Bottom bar nav & buttons */ +.editor-bottom-bar nav { + background-color: var(--editor-modal-content-bg) !important; + color: var(--editor-text) !important; +} + +.editor-bottom-bar nav .btn { + color: var(--editor-text) !important; +} + +.editor-bottom-bar nav .btn:hover { + color: var(--color-primary) !important; +} + +.editor-bottom-bar .viewer-navbar-info { + background-color: var(--color-primary) !important; + color: #ffffff !important; +} + +.editor-bottom-bar .viewer-navbar-info .btn { + color: #ffffff !important; +} + +/* Fullscreen & layer manager buttons */ +#layout-editor #fullscreenBtn, +#layout-editor #layerManagerBtn, +#layout-editor .snap-controls > .btn { + background-color: var(--color-surface) !important; + color: var(--color-primary) !important; +} + +#layout-editor #layerManagerBtn.active, +#layout-editor .snap-controls > .btn.active { + background-color: var(--color-primary) !important; + color: #ffffff !important; +} + +#layout-editor .snap-to-grid-value { + color: var(--color-primary) !important; +} + +/* --- 18. Layer manager --------------------------------------------------- */ + +#layerManager { + background-color: var(--color-surface) !important; + color: var(--editor-text) !important; +} + +#layerManager .layer-manager-header { + background-color: var(--color-primary) !important; + color: #ffffff !important; +} + +#layerManager .layer-manager-layer-item { + color: var(--editor-text) !important; +} + +#layerManager .layer-manager-layer-item .layer { + background-color: var(--color-surface-elevated) !important; + color: var(--editor-text) !important; +} + +#layerManager .layer-manager-layer-item.selectable:not(.selected):hover { + color: var(--color-primary) !important; +} + +#layerManager .layer-manager-canvas-layers .layer-manager-layer-item { + background-color: var(--color-surface-elevated) !important; +} + +#layerManager .has-group { + background-color: var(--color-surface-elevated) !important; +} + +/* --- 19. Action screen helpers (viewer interactions) ---------------------- */ + +.action-screen-helper { + background-color: var(--color-surface) !important; + color: var(--color-primary) !important; +} + +.action-screen-recent { + background-color: var(--color-surface) !important; + color: var(--editor-text) !important; +} + +.action-layout-dock-search-button { + background-color: var(--color-surface) !important; + color: var(--color-primary) !important; +} + +.action-layout-dock-search-results-container { + background-color: var(--color-surface) !important; +} + +.action-layout-dock-search-find { + color: var(--editor-text) !important; + background-color: var(--color-surface-elevated) !important; +} + +.action-layout-dock-option { + background-color: var(--color-surface) !important; + color: var(--editor-text) !important; +} + +/* --- 20. Context menus inside editor ------------------------------------- */ + +.context-menu { + background-color: var(--color-surface) !important; + border-color: var(--editor-border) !important; +} + +.context-menu-btn { + color: var(--color-primary) !important; +} + +.context-menu-btn:hover { + background-color: var(--color-surface-elevated) !important; +} + +/* --- 21. Scaled timeline footer controls --------------------------------- */ +#playlist-editor.timeline-scaled .footer-controls .btn-scale-control { + background-color: var(--color-surface) !important; + color: var(--color-primary) !important; +} + +#playlist-editor.timeline-scaled .footer-controls .btn-scale-control:hover { + background-color: var(--color-surface-elevated) !important; +} + +/* --- 22. Popovers inside editor ------------------------------------------ */ +.editor-modal .popover, +#layout-editor .popover { + background-color: var(--color-surface) !important; + color: var(--editor-text) !important; + border-color: var(--editor-border) !important; +} + +/* --- 23. External playlist message --------------------------------------- */ +.external-playlist-message-container { + color: var(--editor-text) !important; +} + +/* --- 24. General form/input overrides inside any editor context ----------- */ +.editor-modal input[type="text"], +.editor-modal input[type="number"], +.editor-modal input[type="search"], +.editor-modal textarea, +.editor-modal select, +#layout-editor input[type="text"], +#layout-editor input[type="number"], +#layout-editor input[type="search"], +#layout-editor textarea, +#layout-editor select { + background-color: var(--color-surface) !important; + color: var(--editor-text) !important; + border-color: var(--editor-border) !important; +} + +.editor-modal label, +.editor-modal .form-label, +.editor-modal legend, +.editor-modal .control-label, +#layout-editor label, +#layout-editor .form-label, +#layout-editor legend, +#layout-editor .control-label { + color: var(--editor-text) !important; +} + +/* --- 25. Comprehensive form element overrides for all contexts ----------- */ + +/* ANY form-group label anywhere */ +body #properties-panel .form-group > label:first-child, +body .editor-modal .form-group > label:first-child, +body #layout-editor .form-group > label:first-child, +body .container-designer .form-group > label:first-child { + color: var(--editor-text) !important; +} + +/* ANY select dropdown (native and enhanced) */ +body #properties-panel select, +body #properties-panel .select2-container, +body .editor-modal select, +body .editor-modal .select2-container, +body #layout-editor select, +body #layout-editor .select2-container { + color: var(--editor-text) !important; +} + +/* Specific override for properties panel form rows */ +#properties-panel .form-row, +#properties-panel .row { + color: var(--editor-text) !important; +} + +/* Form group text */ +#properties-panel .form-group, +.editor-modal .form-group, +#layout-editor .form-group { + color: var(--editor-text) !important; +} + +/* Input placeholders */ +.editor-modal input::placeholder, +#properties-panel input::placeholder, +#layout-editor input::placeholder, +.editor-modal textarea::placeholder, +#properties-panel textarea::placeholder, +#layout-editor textarea::placeholder { + color: var(--editor-text-secondary) !important; + opacity: 0.7; +} + +/* Help text and descriptions */ +.editor-modal .help-block, +.editor-modal small, +.editor-modal .form-text, +.editor-modal .invalid-feedback, +.editor-modal .valid-feedback, +#properties-panel .help-block, +#properties-panel small, +#properties-panel .form-text, +#properties-panel .invalid-feedback, +#properties-panel .valid-feedback, +#layout-editor .help-block, +#layout-editor small, +#layout-editor .form-text, +#layout-editor .invalid-feedback, +#layout-editor .valid-feedback { + color: var(--editor-text-secondary) !important; +} + +/* Form check labels (checkboxes, radios) */ +.editor-modal .form-check-label, +.editor-modal .form-check input ~ label, +#properties-panel .form-check-label, +#properties-panel .form-check input ~ label, +#layout-editor .form-check-label, +#layout-editor .form-check input ~ label { + color: var(--editor-text) !important; +} + +/* Input addon text */ +.editor-modal .input-group-text, +.editor-modal .input-group-addon, +#properties-panel .input-group-text, +#properties-panel .input-group-addon, +#layout-editor .input-group-text, +#layout-editor .input-group-addon { + background-color: var(--color-surface-elevated) !important; + color: var(--editor-text) !important; + border-color: var(--editor-border) !important; +} + +/* Button in form context */ +.editor-modal button, +.editor-modal .btn, +#properties-panel button, +#properties-panel .btn, +#layout-editor button, +#layout-editor .btn { + color: var(--editor-text) !important; +} + +/* --- 14a. No-nav pages (layout designer, etc.) – remove sidebar spacing -- */ +#content-wrapper.no-nav { + margin-left: 0 !important; + width: 100% !important; + max-width: 100% !important; + padding: 0 !important; +} + +#content-wrapper.no-nav .page-content { + padding: 0 !important; + margin: 0 !important; +} + +#content-wrapper.no-nav .page-content .row { + margin: 0 !important; + padding: 0 !important; +} + +#content-wrapper.no-nav .page-content [class*="col-"] { + margin: 0 !important; + padding: 0 !important; +} + +/* --- 14b. Hide the page behind the editor (body class set by JS) --------- */ +body.ots-playlist-editor-active .ots-sidebar { + visibility: hidden !important; +} + +body.ots-playlist-editor-active .ots-topbar { + visibility: hidden !important; +} + +body.ots-playlist-editor-active .ots-page-actions { + display: none !important; +} + +body.ots-playlist-editor-active #help-pane { + display: none !important; +} + +body.ots-playlist-editor-active .page-content > .row > .col-sm-12 > *:not(#editor-container):not(#layout-editor):not(#playlist-editor):not(.loading-overlay) { + display: none !important; +} + +body.ots-playlist-editor-active #content-wrapper, +body.ots-playlist-editor-active .ots-main { + margin-left: 0 !important; + width: 100% !important; + max-width: 100% !important; + padding: 0 !important; + overflow: visible !important; +} + +body.ots-playlist-editor-active .ots-content, +body.ots-playlist-editor-active .page-content { + padding-left: 0 !important; + padding-right: 0 !important; +} + +body.ots-playlist-editor-active .page-content .row, +body.ots-playlist-editor-active .page-content [class*="col-"] { + margin-left: 0 !important; + margin-right: 0 !important; + padding-left: 0 !important; + padding-right: 0 !important; +} + /* Collapsed: shift content to match the narrow sidebar */ body.ots-sidebar-collapsed .ots-main, body.ots-sidebar-collapsed #content-wrapper, @@ -435,14 +1635,14 @@ html.ots-sidebar-collapsed #content-wrapper { .ots-content { flex: 1; - padding: 32px 16px 32px 0; + padding: 32px 16px 32px var(--ots-sidebar-content-gap); overflow-y: auto; overflow-x: hidden !important; max-width: 100% !important; box-sizing: border-box !important; } -/* Remove left padding between sidebar and page content */ +/* Consistent left gap between sidebar and page content */ .page-content { padding-left: 0 !important; max-width: 100% !important; @@ -463,12 +1663,18 @@ html.ots-sidebar-collapsed #content-wrapper { padding-right: 0 !important; } -.ots-main #content-wrapper, -.ots-main .page-content, -.ots-main .ots-content { +.ots-main #content-wrapper { + padding-left: var(--ots-sidebar-content-gap) !important; +} + +.ots-main .page-content { padding-left: 0 !important; } +.ots-main .ots-content { + padding-left: var(--ots-sidebar-content-gap) !important; +} + /* Strongly enforce no left gap for content children (not #content-wrapper itself) */ #content-wrapper .page-content, #content-wrapper .page-content .row, @@ -510,20 +1716,20 @@ html.ots-sidebar-collapsed #content-wrapper { } /* ============================================================================ - PAGE ACTIONS — fixed top-right cluster (bell + user icon) + PAGE ACTIONS — top-right cluster (bell + user icon) ============================================================================ */ .ots-page-actions { - position: fixed; + position: absolute; top: 12px; right: 20px; z-index: 1100; display: flex; align-items: center; - gap: 4px; + gap: 2px; background: var(--color-surface-elevated); border: 1px solid var(--color-border); - border-radius: 12px; - padding: 4px 6px; + border-radius: 8px; + padding: 3px 4px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10); } @@ -547,10 +1753,10 @@ html.ots-sidebar-collapsed #content-wrapper { display: inline-flex !important; align-items: center !important; justify-content: center !important; - width: 36px !important; - height: 36px !important; + width: 28px !important; + height: 28px !important; padding: 0 !important; - border-radius: 8px !important; + border-radius: 6px !important; color: var(--color-text-secondary) !important; transition: all 150ms ease !important; border: none !important; @@ -573,11 +1779,11 @@ html.ots-sidebar-collapsed #content-wrapper { .ots-page-actions .ots-topbar-action img.nav-avatar { display: block !important; - width: 28px !important; - height: 28px !important; + width: 24px !important; + height: 24px !important; border-radius: 50% !important; object-fit: cover !important; - border: 2px solid transparent !important; + border: 1px solid transparent !important; transition: border-color 150ms ease !important; } @@ -735,7 +1941,7 @@ body.ots-light-mode .ots-page-actions { .sidebar-nav { list-style: none; margin: 0; - padding: 100px 0 140px; + padding: 8px 0 16px; } .sidebar-nav li { @@ -767,6 +1973,8 @@ body.ots-light-mode .ots-page-actions { width: 100%; box-sizing: border-box; padding-right: 48px; /* reserve space for caret */ + text-indent: 0; + float: none; } /* Force readable text in sidebar links */ @@ -821,20 +2029,14 @@ body.ots-light-mode .ots-page-actions { color: var(--ots-sidebar-active-text) !important; } -/* Collapsed sidebar: show a subtle circular highlight behind the icon */ +/* Collapsed sidebar: active item highlight */ .ots-sidebar.collapsed .sidebar-list > a.active, .ots-sidebar.collapsed .sidebar-group-toggle.active { - background: transparent !important; + background: var(--ots-sidebar-active-bg) !important; + color: var(--ots-sidebar-active-text) !important; } .ots-sidebar.collapsed .sidebar-list > a.active .ots-nav-icon, .ots-sidebar.collapsed .sidebar-group-toggle.active .ots-nav-icon { - background-color: var(--ots-sidebar-collapsed-item-bg) !important; - width: 40px !important; - height: 40px !important; - border-radius: 10px !important; - display: inline-flex !important; - align-items: center !important; - justify-content: center !important; color: var(--ots-sidebar-active-text) !important; } @@ -958,6 +2160,11 @@ body.ots-light-mode .ots-page-actions { overflow: visible !important; /* allow popout menus to escape */ } +/* When collapsed the sidebar-content must also allow flyout menus to escape */ +.ots-sidebar.collapsed .sidebar-content { + overflow: visible !important; +} + /* Ensure parent wrapper doesn't clip flyout menus and doesn't create a visible bar. The sidebar is position:fixed so this wrapper should be invisible in the flow. Using display:contents so the sidebar inside still renders but the wrapper @@ -981,8 +2188,8 @@ body.ots-light-mode .ots-page-actions { } .ots-sidebar.collapsed .brand-text, -.ots-sidebar.collapsed .sidebar-group-toggle .ots-nav-text, -.ots-sidebar.collapsed .sidebar-list .ots-nav-text, +.ots-sidebar.collapsed > .sidebar-content > .ots-sidebar-nav > .sidebar-group > .sidebar-group-toggle > .ots-nav-text, +.ots-sidebar.collapsed > .sidebar-content > .ots-sidebar-nav > .sidebar-list > a > .ots-nav-text, .ots-sidebar.collapsed .sidebar-group-caret, .ots-sidebar.collapsed .user-details, .ots-sidebar.collapsed .sidebar-header .sidebar-collapse-btn, @@ -990,30 +2197,127 @@ body.ots-light-mode .ots-page-actions { display: none !important; } -/* Collapsed: hide submenus by default, show on hover as flyout */ +/* ── Collapsed sidebar: flyout submenu on hover ────────────────────────── + When collapsed, submenus are hidden by default and shown as floating + panels anchored to the right of the sidebar icon on hover. + We deliberately do NOT use display:none here — the JS toggle also sets + inline display, so we use visibility + opacity + pointer-events to hide + the panel and then override on :hover. This avoids the inline + display:none set by JS from blocking the CSS :hover rule. + ─────────────────────────────────────────────────────────────────────── */ .ots-sidebar.collapsed .sidebar-submenu { - display: none !important; + /* Positioning */ position: absolute !important; left: 100% !important; top: 0 !important; - min-width: 200px !important; + margin-left: 4px !important; + z-index: 10000 !important; + + /* Sizing */ + min-width: 220px !important; + width: max-content !important; + max-height: 80vh !important; + overflow-y: auto !important; + + /* Hidden by default (visibility so :hover can override inline display) */ + visibility: hidden !important; + opacity: 0 !important; + pointer-events: none !important; + + /* Appearance */ background: var(--color-surface-elevated, #334155) !important; border: 1px solid var(--color-border, #475569) !important; border-radius: 8px !important; - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3) !important; - padding: 8px 0 !important; - margin-left: 4px !important; - z-index: 9999 !important; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35) !important; + padding: 0 0 8px 0 !important; list-style: none !important; + + transition: opacity 0.15s ease, visibility 0.15s ease !important; } -/* Flyout: show submenu on hover over the group */ +/* Flyout: show submenu on hover — uses visibility/opacity so it works + even when JS has set an inline display:none or display:block */ .ots-sidebar.collapsed .sidebar-group:hover > .sidebar-submenu, .ots-sidebar.collapsed .sidebar-group.flyout-open > .sidebar-submenu { display: block !important; + visibility: visible !important; + opacity: 1 !important; + pointer-events: auto !important; } -/* Flyout submenu items */ +/* ── Flyout header (category icon + name) ──────────────────────────── */ +.flyout-header { + display: none; /* hidden in expanded sidebar */ +} + +.ots-sidebar.collapsed .sidebar-submenu .flyout-header { + display: flex !important; + flex-direction: row !important; + align-items: center !important; + gap: 10px !important; + padding: 12px 16px !important; + margin: 0 !important; + border-bottom: none !important; + background: var(--color-primary, #3b82f6) !important; + pointer-events: none !important; + user-select: none !important; + white-space: nowrap !important; + list-style: none !important; + border-radius: 8px 8px 0 0 !important; + width: 100% !important; + box-sizing: border-box !important; +} + +.ots-sidebar.collapsed .sidebar-submenu .flyout-header-icon { + display: inline-flex !important; + visibility: visible !important; + align-items: center !important; + justify-content: center !important; + width: 22px !important; + height: 22px !important; + font-size: 16px !important; + color: #ffffff !important; + opacity: 1 !important; + flex-shrink: 0 !important; + order: -1 !important; +} + +.ots-sidebar.collapsed .sidebar-submenu .flyout-header-text { + display: inline !important; + visibility: visible !important; + font-size: 14px !important; + font-weight: 700 !important; + text-transform: none !important; + letter-spacing: 0.01em !important; + color: #ffffff !important; + opacity: 1 !important; + width: auto !important; + overflow: visible !important; +} + +/* Light mode flyout header — keep the same primary banner */ +body.ots-light-mode .ots-sidebar.collapsed .sidebar-submenu .flyout-header { + background: var(--color-primary, #3b82f6) !important; + border-bottom: none !important; +} + +body.ots-light-mode .ots-sidebar.collapsed .sidebar-submenu .flyout-header-icon { + color: #ffffff !important; +} + +body.ots-light-mode .ots-sidebar.collapsed .sidebar-submenu .flyout-header-text { + color: #ffffff !important; +} + +/* Flyout submenu
  • — full width, no centering */ +.ots-sidebar.collapsed .sidebar-submenu .sidebar-list { + display: block !important; + width: 100% !important; + margin: 0 !important; + padding: 0 !important; +} + +/* Flyout submenu items — stretch to fill the popup width */ .ots-sidebar.collapsed .sidebar-submenu .sidebar-list > a { display: flex !important; align-items: center !important; @@ -1022,32 +2326,52 @@ body.ots-light-mode .ots-page-actions { padding: 8px 16px !important; margin: 2px 6px !important; height: auto !important; - width: auto !important; + width: calc(100% - 12px) !important; background: transparent !important; color: var(--color-text-secondary, #f1f5f9) !important; border-radius: 6px !important; font-size: 13px !important; white-space: nowrap !important; + border: none !important; + border-left: none !important; + text-decoration: none !important; + box-sizing: border-box !important; } .ots-sidebar.collapsed .sidebar-submenu .sidebar-list > a:hover { - background: rgba(59, 130, 246, 0.12) !important; + background: rgba(59, 130, 246, 0.15) !important; color: #ffffff !important; } -/* Show text labels inside flyout submenu */ +/* Show text labels inside flyout submenu — high specificity to override + the global .ots-sidebar.collapsed .ots-nav-text { display:none } */ +.ots-sidebar.collapsed .sidebar-submenu .sidebar-list .ots-nav-text, +.ots-sidebar.collapsed .sidebar-submenu .sidebar-list > a .ots-nav-text, .ots-sidebar.collapsed .sidebar-submenu .ots-nav-text { display: inline !important; visibility: visible !important; width: auto !important; overflow: visible !important; + color: inherit !important; + font-size: 13px !important; + font-weight: 500 !important; } -/* Flyout icon sizing */ +/* Show icons inside flyout submenu — high specificity to override + collapsed icon sizing/color that makes them 20px sidebar icons */ +.ots-sidebar.collapsed .sidebar-submenu .sidebar-list .ots-nav-icon, +.ots-sidebar.collapsed .sidebar-submenu .sidebar-list > a .ots-nav-icon, .ots-sidebar.collapsed .sidebar-submenu .ots-nav-icon { - width: 16px !important; - height: 16px !important; + display: inline-flex !important; + visibility: visible !important; + width: 18px !important; + height: 18px !important; font-size: 14px !important; + flex-shrink: 0 !important; + color: inherit !important; + margin: 0 !important; + align-items: center !important; + justify-content: center !important; } /* Make sidebar-group position relative so flyout anchors correctly */ @@ -1055,6 +2379,21 @@ body.ots-light-mode .ots-page-actions { position: relative !important; } +/* Add a bridge element so the mouse can travel from the icon to the flyout + without losing :hover (covers the 4px gap + some tolerance) */ +.ots-sidebar.collapsed .sidebar-group-toggle::before { + content: '' !important; + position: absolute !important; + top: 0 !important; + right: -12px !important; + width: 12px !important; + height: 100% !important; + background: transparent !important; + display: block !important; + pointer-events: auto !important; + z-index: 9999 !important; +} + /* Also show a label tooltip on hover for top-level items */ .ots-sidebar.collapsed .sidebar-group-toggle::after { content: attr(data-group); @@ -1123,28 +2462,82 @@ body.ots-light-mode .ots-page-actions { flex-shrink: 0; } -.ots-sidebar.collapsed .sidebar-group-toggle, -.ots-sidebar.collapsed .sidebar-list > a { +/* ── Collapsed sidebar: reset base Xibo styles and center icons ───────── */ + +/* The