/* ============================================================================ XIBO CMS MODERN THEME - OTS Signs Dark Mode Override - Component Styling ============================================================================ */ /* Force dark mode */ :root { --color-primary: #3b82f6; --color-primary-dark: #1d4ed8; --color-primary-light: #60a5fa; --color-primary-lighter: #dbeafe; --color-secondary: #7c3aed; --color-success: #10b981; --color-warning: #f59e0b; --color-danger: #ef4444; --color-info: #0ea5e9; --color-background: #0f172a; --color-surface: #1e293b; --color-surface-elevated: #334155; --color-border: #475569; --color-border-light: #1e293b; --color-text-primary: #ffffff; --color-text-secondary: #f1f5f9; --color-text-tertiary: #e2e8f0; --color-text-inverse: #ffffff; --color-on-primary: #ffffff; --ots-sidebar-bg: #08132a; --ots-sidebar-header-bg: #08132a; --ots-sidebar-border: rgba(255, 255, 255, 0.08); --ots-sidebar-link: #f9fbff; --ots-sidebar-link-hover-bg: rgba(255, 255, 255, 0.08); --ots-sidebar-link-hover-text: #ffffff; --ots-sidebar-active-bg: rgba(255, 255, 255, 0.06); --ots-sidebar-active-text: #ffffff; --ots-sidebar-active-shadow: 0 8px 18px rgba(15, 23, 42, 0.25); --ots-sidebar-muted-text: #8ea4c7; --ots-sidebar-group-bg: rgba(255, 255, 255, 0.03); --ots-sidebar-group-hover-bg: rgba(255, 255, 255, 0.1); --ots-sidebar-submenu-bg: rgba(15, 23, 42, 0.6); --ots-sidebar-submenu-border: rgba(255, 255, 255, 0.9); --ots-sidebar-submenu-hover-bg: rgba(255, 255, 255, 0.1); --ots-sidebar-button-bg: rgba(255, 255, 255, 0.08); --ots-sidebar-button-bg-hover: rgba(255, 255, 255, 0.16); --ots-sidebar-button-text: #d7e2f8; --ots-sidebar-collapsed-item-bg: rgba(255, 255, 255, 0.08); --ots-sidebar-collapsed-item-hover-bg: rgba(255, 255, 255, 0.16); --ots-sidebar-width: 256px; --ots-sidebar-collapsed-width: 64px; --ots-sidebar-header-height: 64px; --ots-sidebar-item-radius: 10px; --ots-sidebar-item-height: 44px; --ots-sidebar-item-padding-x: 12px; color-scheme: dark; } html, body { background-color: var(--color-background); color: var(--color-text-primary); overflow-x: hidden !important; max-width: 100vw !important; } /* Minimal mapping so `.dashboard-card` inherits the visual treatment used by widgets/panels. This allows collapsing one level of DOM without visual regressions. */ /* Consolidated dashboard-card styling (now in CONSOLIDATED CARD/PANEL/WIDGET section) */ /* Floating menus that are moved to body to escape overflowed containers */ .ots-floating-menu { border-radius: 8px; box-shadow: 0 8px 24px rgba(2,6,23,0.6); background-color: var(--color-surface); border: 1px solid var(--color-border); overflow: visible !important; position: fixed !important; transform: none !important; } /* Elevated z-index for menus so they render above other panels */ .ots-floating-menu, .dropdown-menu { z-index: 99999 !important; } /* Force ALL dropdown/context menu classes to render on top of everything. This is maximally aggressive to defeat any stacking context or overflow clipping. */ .dropdown-menu, .ots-notif-menu, .ots-user-menu, .context-menu, .row-menu, .rowMenu, .menu-popover, .dataTables_buttons .dropdown-menu, .ots-floating-menu { position: fixed !important; z-index: 2147483647 !important; transform: none !important; will-change: auto !important; pointer-events: auto !important; visibility: visible !important; display: block !important; opacity: 1 !important; } /* Ensure dropdown list items and children aren't clipped */ .dropdown-menu li, .dropdown-menu > li > a, .dropdown-menu > li > span, .dropdown-menu ul, .dropdown-menu div { overflow: visible !important; position: relative !important; z-index: 2147483647 !important; } /* Remove any transform or overflow from menu ancestors that could create stacking context */ .dropdown-menu *, .ots-floating-menu * { transform: none !important; } /* Light/dark mode toggle */ #ots-theme-toggle { display: flex !important; align-items: center; gap: 8px; cursor: pointer; } #ots-theme-toggle:hover { background-color: rgba(59, 130, 246, 0.1) !important; } /* Light mode styles (applied when .ots-light-mode is on body) */ body.ots-light-mode { --color-primary: #2563eb; --color-primary-dark: #1d4ed8; --color-primary-light: #60a5fa; --color-primary-lighter: #eff6ff; --color-secondary: #7c3aed; --color-success: #059669; --color-warning: #d97706; --color-danger: #dc2626; --color-info: #0284c7; --color-background: #f8fafc; --color-surface: #ffffff; --color-surface-elevated: #f1f5f9; --color-border: #e2e8f0; --color-border-light: #f1f5f9; --color-text-primary: #0f172a; --color-text-secondary: #334155; --color-text-tertiary: #475569; --color-text-inverse: #0f172a; --color-on-primary: #ffffff; --ots-sidebar-bg: #f1f5f9; --ots-sidebar-header-bg: #f1f5f9; --ots-sidebar-border: #e2e8f0; --ots-sidebar-link: #334155; --ots-sidebar-link-hover-bg: rgba(59, 130, 246, 0.08); --ots-sidebar-link-hover-text: #0f172a; --ots-sidebar-active-bg: #ffffff; --ots-sidebar-active-text: #0f172a; --ots-sidebar-active-shadow: 0 8px 18px rgba(15, 23, 42, 0.12); --ots-sidebar-muted-text: #64748b; --ots-sidebar-group-bg: rgba(0, 0, 0, 0.03); --ots-sidebar-group-hover-bg: rgba(0, 0, 0, 0.06); --ots-sidebar-submenu-bg: rgba(0, 0, 0, 0.04); --ots-sidebar-submenu-border: #cbd5e1; --ots-sidebar-submenu-hover-bg: rgba(0, 0, 0, 0.08); --ots-sidebar-button-bg: rgba(0, 0, 0, 0.04); --ots-sidebar-button-bg-hover: rgba(0, 0, 0, 0.08); --ots-sidebar-button-text: #334155; --ots-sidebar-collapsed-item-bg: rgba(0, 0, 0, 0.04); --ots-sidebar-collapsed-item-hover-bg: rgba(0, 0, 0, 0.08); --ots-sidebar-width: 256px; --ots-sidebar-collapsed-width: 64px; --ots-sidebar-header-height: 64px; --ots-sidebar-item-radius: 10px; --ots-sidebar-item-height: 44px; --ots-sidebar-item-padding-x: 12px; background-color: var(--color-background); color: var(--color-text-primary); } body.ots-light-mode .ots-sidebar { background-color: #f1f5f9 !important; border-right-color: #e2e8f0 !important; } body.ots-light-mode .ots-sidebar.collapsed .sidebar-group-toggle, body.ots-light-mode .ots-sidebar.collapsed .sidebar-list > a { background: rgba(59, 130, 246, 0.06) !important; color: #334155 !important; } body.ots-light-mode .ots-sidebar.collapsed .sidebar-group-toggle:hover, body.ots-light-mode .ots-sidebar.collapsed .sidebar-list > a:hover { background: rgba(59, 130, 246, 0.12) !important; color: #0f172a !important; } body.ots-light-mode .ots-sidebar.collapsed .ots-nav-icon { color: #334155 !important; } body.ots-light-mode .ots-sidebar.collapsed .ots-nav-icon::before, body.ots-light-mode .ots-sidebar.collapsed .ots-nav-icon.fa::before, body.ots-light-mode .ots-sidebar.collapsed .fa::before { color: #334155 !important; } body.ots-light-mode .ots-sidebar li.sidebar-list > a, body.ots-light-mode .ots-sidebar li.sidebar-main > a { color: #334155; } body.ots-light-mode .ots-sidebar li.sidebar-list > a:hover { color: #0f172a; background-color: rgba(59, 130, 246, 0.08); } body.ots-light-mode .sidebar-group-toggle { color: #334155; background: rgba(0, 0, 0, 0.03); } body.ots-light-mode .sidebar-group-toggle:hover { background: rgba(0, 0, 0, 0.06); color: #0f172a; } body.ots-light-mode .sidebar-group.is-open > .sidebar-group-toggle, body.ots-light-mode .sidebar-group-toggle[aria-expanded="true"] { background: #ffffff; color: #0b1221 !important; } body.ots-light-mode .sidebar-submenu .sidebar-list > a { background: rgba(0, 0, 0, 0.04); color: #334155; border-left-color: #cbd5e1; } body.ots-light-mode .sidebar-header { border-bottom-color: #e2e8f0; background: #f1f5f9; } body.ots-light-mode .ots-topbar { background-color: transparent; border-bottom: none; } /* (topbar strip is now hidden — light-mode overrides removed) */ body.ots-light-mode .ots-topbar .nav-link { color: #334155; } body.ots-light-mode .ots-topbar .nav-link:hover { background-color: rgba(59, 130, 246, 0.06); color: #2563eb; } body.ots-light-mode .dashboard-card { background: linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(241, 245, 249, 0.95)); border-color: #e2e8f0; } body.ots-light-mode .dropdown-menu, body.ots-light-mode .dropdown-right { background-color: #ffffff; border-color: #e2e8f0; color: #0f172a; } body.ots-light-mode .dropdown-item { color: #334155; } body.ots-light-mode .dropdown-item:hover, body.ots-light-mode .dropdown-menu a:hover { background-color: rgba(59, 130, 246, 0.1); color: #2563eb; } body.ots-light-mode .ots-content { background-color: var(--color-background); } /* ============================================================================ THEME ENFORCE - Ensure page backgrounds follow the light/dark CSS variables This block uses high-specificity rules and !important to override other theme rules that may hardcode colors so the toggle always reflects the `--color-*` variables set by `body.ots-light-mode` or :root. ============================================================================ */ html, body, #page-wrapper, .ots-main, .ots-content, .page-content { background-color: var(--color-background) !important; color: var(--color-text-primary) !important; } /* Topbar, footer and panels should use surface variables (elevated where appropriate) */ .ots-topbar, .ots-footer, .dashboard-card, .dropdown-menu, .dropdown-right, .modal-content { background-color: var(--color-surface) !important; color: var(--color-text-primary) !important; } /* Surface-elevated elements (cards, panels) */ .card, .card-body, .panel, .panel-body, .ots-panel, .modal-body { background-color: var(--color-surface-elevated) !important; color: var(--color-text-primary) !important; } /* Ensure sidebar and its components still receive their own overrides */ .ots-sidebar, .ots-sidebar .sidebar-header, .ots-sidebar .sidebar-content { background-color: var(--ots-sidebar-bg) !important; color: var(--ots-sidebar-link) !important; } /* ============================================================================ SHELL LAYOUT - SIDEBAR + MAIN ============================================================================ */ .ots-shell { display: flex; min-height: 100vh; } .ots-sidebar { position: fixed; left: 0; top: 0; width: var(--ots-sidebar-width) !important; height: 100vh; background-color: var(--ots-sidebar-bg); border-right: 1px solid var(--ots-sidebar-border); padding: 0; display: flex; flex-direction: column; overflow: hidden; z-index: 1200; transition: width 200ms ease; } .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; transition: margin-left 200ms ease, width 200ms ease, max-width 200ms ease; overflow-x: hidden !important; box-sizing: border-box !important; } #page-wrapper { position: relative; margin-left: 0 !important; padding-left: 0 !important; border: none !important; box-shadow: none !important; background-color: var(--color-background) !important; max-width: 100vw !important; overflow-x: hidden !important; box-sizing: border-box !important; } #page-wrapper.active { padding-left: 0 !important; margin-left: 0 !important; } #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; transition: margin-left 200ms ease, width 200ms ease, max-width 200ms ease; padding-left: 16px !important; padding-right: 16px !important; border-left: none !important; box-shadow: none !important; outline: none !important; overflow-x: hidden !important; box-sizing: border-box !important; } /* Collapsed: shift content to match the narrow sidebar */ body.ots-sidebar-collapsed .ots-main, body.ots-sidebar-collapsed #content-wrapper, html.ots-sidebar-collapsed .ots-main, html.ots-sidebar-collapsed #content-wrapper { margin-left: var(--ots-sidebar-collapsed-width) !important; width: calc(100vw - var(--ots-sidebar-collapsed-width)) !important; max-width: calc(100vw - var(--ots-sidebar-collapsed-width)) !important; } .ots-content { flex: 1; padding: 32px 16px 32px 0; overflow-y: auto; overflow-x: hidden !important; max-width: 100% !important; box-sizing: border-box !important; } /* Remove left padding between sidebar and page content */ .page-content { padding-left: 0 !important; max-width: 100% !important; overflow-x: hidden !important; box-sizing: border-box !important; } /* Remove bootstrap gutters for main content so it sits flush against sidebar */ .ots-main .page-content .row { margin-left: 0 !important; margin-right: 0 !important; max-width: 100% !important; overflow-x: hidden !important; } .ots-main .page-content [class*="col-"] { padding-left: 0 !important; padding-right: 0 !important; } .ots-main #content-wrapper, .ots-main .page-content, .ots-main .ots-content { padding-left: 0 !important; } /* Strongly enforce no left gap for content children (not #content-wrapper itself) */ #content-wrapper .page-content, #content-wrapper .page-content .row, #content-wrapper .page-content [class*="col-"] { margin-left: 0 !important; padding-left: 0 !important; } /* Ensure page header and meta area align flush */ .page-header { margin-left: 0 !important; padding-left: 0 !important; } /* Prevent XiboGrid, folder grids, and data containers from causing page overflow */ .XiboGrid, .grid-with-folders-container, .XiboData, #datatable-container { max-width: 100% !important; overflow-x: auto !important; box-sizing: border-box !important; } /* ============================================================================ TOPBAR STRIP — HIDDEN The old full-width topbar is no longer shown. The notification bell and user menu now live in .ots-page-actions (fixed top-right on every page). ============================================================================ */ .row.header.header-side, .ots-topbar-strip { display: none !important; height: 0 !important; margin: 0 !important; padding: 0 !important; overflow: hidden !important; border: none !important; box-shadow: none !important; } /* ============================================================================ PAGE ACTIONS — fixed top-right cluster (bell + user icon) ============================================================================ */ .ots-page-actions { position: fixed; top: 12px; right: 20px; z-index: 1100; display: flex; align-items: center; gap: 4px; background: var(--color-surface-elevated); border: 1px solid var(--color-border); border-radius: 12px; padding: 4px 6px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.10); } /* Each action inside the cluster — NO position:relative so dropdowns anchor to .ots-page-actions (position:fixed) instead */ .ots-page-actions .ots-topbar-action { display: inline-flex !important; align-items: center !important; position: static !important; } .ots-page-actions .ots-topbar-action .nav-item, .ots-page-actions .ots-topbar-action .dropdown, .ots-page-actions .ots-topbar-action > div { display: inline-flex !important; align-items: center !important; position: static !important; } .ots-page-actions .ots-topbar-action .nav-link { display: inline-flex !important; align-items: center !important; justify-content: center !important; width: 36px !important; height: 36px !important; padding: 0 !important; border-radius: 8px !important; color: var(--color-text-secondary) !important; transition: all 150ms ease !important; border: none !important; background: transparent !important; } .ots-page-actions .ots-topbar-action .nav-link:hover { background-color: rgba(59, 130, 246, 0.08) !important; color: var(--color-primary) !important; } .ots-page-actions .ots-topbar-action .ots-topbar-icon { display: flex !important; align-items: center !important; justify-content: center !important; width: 18px !important; height: 18px !important; font-size: 16px !important; } .ots-page-actions .ots-topbar-action img.nav-avatar { display: block !important; width: 28px !important; height: 28px !important; border-radius: 50% !important; object-fit: cover !important; border: 2px solid transparent !important; transition: border-color 150ms ease !important; } .ots-page-actions .ots-topbar-action .nav-link:hover img.nav-avatar { border-color: var(--color-primary) !important; } /* Dropdown menus from the page actions cluster */ .ots-page-actions .dropdown-menu { position: absolute !important; top: 100% !important; right: 0 !important; left: auto !important; margin-top: 0 !important; min-width: 200px !important; background-color: var(--color-surface-elevated) !important; border: 1px solid var(--color-border) !important; border-radius: 10px !important; box-shadow: 0 12px 36px rgba(0, 0, 0, 0.25) !important; padding: 6px 0 !important; z-index: 3000 !important; overflow: visible !important; } /* Bridge the gap between the pill and dropdown so it looks connected */ .ots-page-actions .dropdown-menu::before { content: '' !important; display: block !important; position: absolute !important; top: -4px !important; right: 8px !important; width: 48px !important; height: 4px !important; background: transparent !important; } .ots-page-actions .dropdown-item, .ots-page-actions .dropdown-menu a { display: flex !important; align-items: center !important; gap: 8px !important; padding: 8px 14px !important; margin: 1px 6px !important; border-radius: 6px !important; color: var(--color-text-secondary) !important; font-size: 13px !important; font-weight: 500 !important; transition: all 150ms ease !important; text-decoration: none !important; } .ots-page-actions .dropdown-item:hover, .ots-page-actions .dropdown-menu a:hover { background-color: rgba(59, 130, 246, 0.08) !important; color: var(--color-primary) !important; } /* Light mode adjustments for the actions cluster */ body.ots-light-mode .ots-page-actions { background: #ffffff; border-color: #e2e8f0; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); } .page-header { background: transparent !important; box-shadow: none !important; } .ots-footer { border-top: 1px solid var(--color-border); padding: 16px 32px; background-color: var(--color-surface-elevated); text-align: center; color: var(--color-text-primary); } /* Responsive sidebar */ @media (max-width: 768px) { .ots-sidebar { transform: translateX(-100%); transition: transform var(--transition-base); width: 280px; } .ots-sidebar.active { transform: translateX(0); box-shadow: 2px 0 8px rgba(0, 0, 0, 0.3); } .ots-main { margin-left: 0 !important; } .ots-content { color: var(--color-text-primary); } } /* Responsive helpers for paged selects and other inline-width controls */ .pagedSelect { min-width: 12.5rem; /* 200px */ } @media (max-width: 600px) { .pagedSelect { min-width: auto; width: 100%; box-sizing: border-box; } } /* ============================================================================ SIDEBAR STYLES ============================================================================ */ .sidebar-header { padding: 12px 16px; border-bottom: 1px solid var(--color-border); display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-shrink: 0; height: var(--ots-sidebar-header-height); } .brand-link { display: flex; align-items: center; gap: 12px; color: var(--color-text-primary); font-weight: 700; font-size: 16px; text-decoration: none; flex: 1; } .brand-icon { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; font-size: 24px; flex-shrink: 0; } .sidebar-content { flex: 1; padding: 8px 0; overflow-y: auto; min-height: 0; } .sidebar-nav { list-style: none; margin: 0; padding: 100px 0 140px; } .sidebar-nav li { display: block; margin-top: 6px; } /* Compatibility: Xibo sidebar markup uses `sidebar-list`, `sidebar-main`, `sidebar-title`. Map those into the modern `.nav-item/.nav-text/.nav-icon` style system so styles apply. */ .ots-sidebar li.sidebar-list > a, .ots-sidebar li.sidebar-main > a, .ots-sidebar li.sidebar-title > a { display: flex; align-items: center; gap: 12px; padding: 8px var(--ots-sidebar-item-padding-x); color: var(--ots-sidebar-link); text-decoration: none; transition: all var(--transition-fast); position: relative; font-size: 14px; font-weight: 500; border-left: 2px solid transparent; margin: 3px 0; border-radius: var(--ots-sidebar-item-radius); min-height: var(--ots-sidebar-item-height); 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: var(--ots-sidebar-link); } .ots-sidebar li.sidebar-list > a:hover { color: var(--ots-sidebar-link-hover-text); background-color: var(--ots-sidebar-link-hover-bg); } .ots-sidebar li.sidebar-list.active > a, .ots-sidebar li.sidebar-list > a.active, .ots-sidebar li.sidebar-main.active > a, .ots-sidebar li.sidebar-main > a.active { color: var(--ots-sidebar-active-text); background-color: var(--ots-sidebar-active-bg); border-left-color: transparent; font-weight: 600; box-shadow: var(--ots-sidebar-active-shadow); } .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: var(--ots-sidebar-active-text); } /* Stronger active state rules to ensure the currently active page is visibly highlighted regardless of other theme CSS. Covers both `li.active > a` and `a.active` patterns as well as collapsed sidebar appearance. */ .ots-sidebar li.sidebar-list.active > a, .ots-sidebar li.sidebar-list > a.active, #sidebar-wrapper .sidebar-list a.active, .ots-sidebar li.sidebar-main.active > a, .ots-sidebar li.sidebar-main > a.active, .ots-sidebar .sidebar-list > a[aria-current="page"] { background-color: var(--ots-sidebar-active-bg) !important; color: var(--ots-sidebar-active-text) !important; border-left-color: transparent !important; font-weight: 600 !important; box-shadow: var(--ots-sidebar-active-shadow) !important; } /* Ensure the icon in the active link also uses active text color */ .ots-sidebar li.sidebar-list.active > a .ots-nav-icon, .ots-sidebar li.sidebar-list > a.active .ots-nav-icon, #sidebar-wrapper .sidebar-list a.active .ots-nav-icon { color: var(--ots-sidebar-active-text) !important; } /* Collapsed sidebar: show a subtle circular highlight behind the icon */ .ots-sidebar.collapsed .sidebar-list > a.active, .ots-sidebar.collapsed .sidebar-group-toggle.active { background: transparent !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; } .ots-sidebar .ots-nav-icon { width: 28px; height: 28px; display: flex !important; align-items: center; justify-content: center; flex-shrink: 0; font-size: 16px; color: currentColor; margin: 0; text-align: center; line-height: 1; } .ots-sidebar .ots-nav-text { font-size: 14px; font-weight: 500; flex: 1; line-height: 1.2; } .sidebar-group-toggle .ots-nav-icon, .ots-sidebar-nav .ots-nav-icon { justify-self: start; } .ots-sidebar li.sidebar-title > a { display: block; font-size: 10px; font-weight: 700; text-transform: uppercase; color: var(--ots-sidebar-muted-text); letter-spacing: 0.12em; padding: 12px 14px 4px; margin: 8px 0 0; min-height: auto; line-height: 1; } .brand-logo { width: 40px; height: 40px; object-fit: contain; } .brand-text { color: var(--color-text-primary); font-size: 18px; font-weight: 600; letter-spacing: 0.02em; } .sidebar-header { padding: 12px 16px; border-bottom: 1px solid var(--ots-sidebar-border); display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-shrink: 0; height: var(--ots-sidebar-header-height); box-sizing: border-box; position: relative; background: var(--ots-sidebar-header-bg); z-index: 1; } .sidebar-collapse-btn { width: 32px; height: 32px; border-radius: 8px; border: 0; background: var(--ots-sidebar-button-bg); color: var(--ots-sidebar-button-text); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: all var(--transition-fast); } .sidebar-collapse-btn:hover { background: var(--ots-sidebar-button-bg-hover); color: var(--ots-sidebar-link-hover-text); } /* Expand button - visible only when collapsed */ .sidebar-expand-btn { width: 32px; height: 32px; border-radius: 8px; border: 0; background: var(--ots-sidebar-button-bg); color: var(--ots-sidebar-button-text); display: none; align-items: center; justify-content: center; cursor: pointer; transition: all var(--transition-fast); } .sidebar-expand-btn:hover { background: var(--ots-sidebar-button-bg-hover); color: var(--ots-sidebar-link-hover-text); } .ots-sidebar.collapsed .sidebar-expand-btn { display: inline-flex !important; } .ots-sidebar.collapsed .sidebar-collapse-btn-visible { display: none !important; } .ots-sidebar.collapsed { width: var(--ots-sidebar-collapsed-width) !important; overflow: visible !important; /* allow popout menus to escape */ } /* 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 itself produces no box at all — eliminating the black bar. */ .navbar-collapse-side, .navbar-collapse-side.collapse, #navbar-collapse-1 { display: contents !important; overflow: visible !important; width: 0 !important; min-width: 0 !important; max-width: 0 !important; height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; border: none !important; background: transparent !important; box-shadow: none !important; outline: none !important; } .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-group-caret, .ots-sidebar.collapsed .user-details, .ots-sidebar.collapsed .sidebar-header .sidebar-collapse-btn, .ots-sidebar.collapsed .brand-link .brand-text { display: none !important; } /* Collapsed: hide submenus by default, show on hover as flyout */ .ots-sidebar.collapsed .sidebar-submenu { display: none !important; position: absolute !important; left: 100% !important; top: 0 !important; min-width: 200px !important; 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; list-style: none !important; } /* Flyout: show submenu on hover over the group */ .ots-sidebar.collapsed .sidebar-group:hover > .sidebar-submenu, .ots-sidebar.collapsed .sidebar-group.flyout-open > .sidebar-submenu { display: block !important; } /* Flyout submenu items */ .ots-sidebar.collapsed .sidebar-submenu .sidebar-list > a { display: flex !important; align-items: center !important; justify-content: flex-start !important; gap: 10px !important; padding: 8px 16px !important; margin: 2px 6px !important; height: auto !important; width: auto !important; background: transparent !important; color: var(--color-text-secondary, #f1f5f9) !important; border-radius: 6px !important; font-size: 13px !important; white-space: nowrap !important; } .ots-sidebar.collapsed .sidebar-submenu .sidebar-list > a:hover { background: rgba(59, 130, 246, 0.12) !important; color: #ffffff !important; } /* Show text labels inside flyout submenu */ .ots-sidebar.collapsed .sidebar-submenu .ots-nav-text { display: inline !important; visibility: visible !important; width: auto !important; overflow: visible !important; } /* Flyout icon sizing */ .ots-sidebar.collapsed .sidebar-submenu .ots-nav-icon { width: 16px !important; height: 16px !important; font-size: 14px !important; } /* Make sidebar-group position relative so flyout anchors correctly */ .ots-sidebar.collapsed .sidebar-group { position: relative !important; } /* Also show a label tooltip on hover for top-level items */ .ots-sidebar.collapsed .sidebar-group-toggle::after { content: attr(data-group); position: absolute; left: 100%; top: 50%; transform: translateY(-50%); background: var(--color-surface-elevated, #334155); color: var(--color-text-primary, #fff); padding: 4px 12px; border-radius: 6px; font-size: 13px; font-weight: 500; white-space: nowrap; margin-left: 8px; pointer-events: none; opacity: 0; transition: opacity 0.15s; z-index: 9999; box-shadow: 0 4px 12px rgba(0,0,0,0.2); } .ots-sidebar.collapsed .sidebar-group:hover > .sidebar-group-toggle::after { display: none; /* hide tooltip when submenu flyout is showing instead */ } /* Single items (Dashboard etc) - show tooltip on hover */ .ots-sidebar.collapsed > .sidebar-content .sidebar-nav > .sidebar-list > a { position: relative !important; } .ots-sidebar.collapsed > .sidebar-content .sidebar-nav > .sidebar-list > a::after { content: attr(data-tooltip); position: absolute; left: 100%; top: 50%; transform: translateY(-50%); background: var(--color-surface-elevated, #334155); color: var(--color-text-primary, #fff); padding: 4px 12px; border-radius: 6px; font-size: 13px; font-weight: 500; white-space: nowrap; margin-left: 8px; pointer-events: none; opacity: 0; transition: opacity 0.15s; z-index: 9999; box-shadow: 0 4px 12px rgba(0,0,0,0.2); } .ots-sidebar.collapsed > .sidebar-content .sidebar-nav > .sidebar-list:hover > a::after { opacity: 1; } .ots-sidebar.collapsed .sidebar-header { height: auto; padding: 8px; justify-content: center; flex-direction: column; gap: 8px; } .ots-sidebar.collapsed .brand-icon { flex-shrink: 0; } .ots-sidebar.collapsed .sidebar-group-toggle, .ots-sidebar.collapsed .sidebar-list > a { display: flex !important; align-items: center !important; justify-content: center !important; padding: 0 !important; width: 100% !important; height: 56px !important; background: var(--ots-sidebar-collapsed-item-bg) !important; color: var(--ots-sidebar-link) !important; border-radius: 12px !important; margin: 8px 6px !important; box-sizing: border-box !important; overflow: visible !important; flex-direction: row !important; gap: 0 !important; } /* When collapsed, hide all nav text labels so only icons are visible */ .ots-sidebar.collapsed .ots-nav-text, .ots-sidebar.collapsed .sidebar-group-toggle .ots-nav-text, .ots-sidebar.collapsed .sidebar-list .ots-nav-text, .ots-sidebar.collapsed .brand-text, .ots-sidebar.collapsed .user-details { display: none !important; visibility: hidden !important; width: 0 !important; overflow: hidden !important; } .ots-sidebar.collapsed .sidebar-group-toggle:hover, .ots-sidebar.collapsed .sidebar-list > a:hover { background: var(--ots-sidebar-collapsed-item-hover-bg) !important; } /* Hide caret when collapsed */ .ots-sidebar.collapsed .sidebar-group-caret { display: none !important; } /* Center icons when collapsed — triple-class + ID selector to beat expanded-state rules like #sidebar-wrapper .sidebar-list .ots-nav-icon { margin-right:8px } Specificity: (1,3,0) beats (1,2,0) */ #sidebar-wrapper.ots-sidebar.collapsed .ots-nav-icon, #navbar-collapse-1 .ots-sidebar.collapsed .ots-nav-icon, .ots-sidebar.collapsed .ots-nav-icon { display: flex !important; width: 20px !important; height: 20px !important; align-items: center !important; justify-content: center !important; flex-shrink: 0 !important; font-size: 20px !important; margin: 0 auto !important; margin-left: auto !important; margin-right: auto !important; padding: 0 !important; color: var(--ots-sidebar-link) !important; visibility: visible !important; line-height: 1 !important; } /* Stronger collapsed-state icon overrides */ .ots-sidebar.collapsed .ots-nav-icon, .ots-sidebar.collapsed .ots-nav-icon i, .ots-sidebar.collapsed .ots-nav-icon svg, .ots-sidebar.collapsed .btn-icon { color: var(--ots-sidebar-link) !important; fill: currentColor !important; stroke: currentColor !important; opacity: 1 !important; } /* Force-fill any SVG child shapes (paths, g) to currentColor so embedded fills are overridden */ .ots-sidebar.collapsed .ots-nav-icon svg *, .ots-sidebar.collapsed .ots-nav-icon svg path, .ots-sidebar.collapsed .ots-nav-icon svg g { fill: currentColor !important; stroke: currentColor !important; opacity: 1 !important; } /* Remove potential dimming filters */ .ots-sidebar.collapsed .ots-nav-icon svg, .ots-sidebar.collapsed .ots-nav-icon i { filter: none !important; } /* Very strong override: force collapsed icons to a bright foreground in dark mode, and to a dark foreground in light mode. This is intentionally specific to override icon fills coming from embedded SVGs, fonts, or background images. */ :root .ots-sidebar.collapsed .sidebar-list > a .ots-nav-icon, :root .ots-sidebar.collapsed .sidebar-group-toggle .ots-nav-icon, :root .ots-sidebar.collapsed .ots-nav-icon, :root .ots-sidebar.collapsed .ots-nav-icon * { color: #ffffff !important; fill: #ffffff !important; stroke: #ffffff !important; opacity: 1 !important; filter: none !important; } /* Light mode: force dark icons */ body.ots-light-mode .ots-sidebar.collapsed .sidebar-list > a .ots-nav-icon, body.ots-light-mode .ots-sidebar.collapsed .sidebar-group-toggle .ots-nav-icon, body.ots-light-mode .ots-sidebar.collapsed .ots-nav-icon, body.ots-light-mode .ots-sidebar.collapsed .ots-nav-icon * { color: #0b1221 !important; fill: #0b1221 !important; stroke: #0b1221 !important; opacity: 1 !important; filter: none !important; } /* Target Font Awesome pseudo-element glyphs (fa, fa-*) which render via ::before */ :root .ots-sidebar.collapsed .ots-nav-icon::before, :root .ots-sidebar.collapsed .ots-nav-icon.fa::before, :root .ots-sidebar.collapsed .fa::before, :root .ots-sidebar.collapsed .ots-nav-icon .fa::before { color: #ffffff !important; opacity: 1 !important; text-shadow: none !important; } body.ots-light-mode .ots-sidebar.collapsed .ots-nav-icon::before, body.ots-light-mode .ots-sidebar.collapsed .ots-nav-icon.fa::before, body.ots-light-mode .ots-sidebar.collapsed .fa::before, body.ots-light-mode .ots-sidebar.collapsed .ots-nav-icon .fa::before { color: #0b1221 !important; opacity: 1 !important; text-shadow: none !important; } /* Center Font Awesome pseudo-elements inside icon containers */ .ots-sidebar .ots-nav-icon::before, .ots-sidebar .ots-nav-icon.fa::before, .ots-sidebar .fa::before { display: inline-block !important; line-height: 1 !important; } /* Ensure icon glyphs (font icons and svgs) follow the sidebar link color and adapt to light/dark mode. Use currentColor for SVG fill/stroke. */ .ots-sidebar .ots-nav-icon, .ots-sidebar.collapsed .ots-nav-icon, .ots-sidebar .ots-nav-icon i, .ots-sidebar .ots-nav-icon svg { color: var(--ots-sidebar-link) !important; } .ots-sidebar .ots-nav-icon svg { fill: currentColor !important; stroke: currentColor !important; } /* Explicitly handle light-mode variant (redundant but higher specificity) */ body.ots-light-mode .ots-sidebar .ots-nav-icon, body.ots-light-mode .ots-sidebar.collapsed .ots-nav-icon { color: var(--ots-sidebar-link) !important; } /* Show expand button when collapsed, hide collapse button */ .ots-sidebar.collapsed .sidebar-expand-btn { display: inline-flex !important; } .ots-sidebar.collapsed .sidebar-collapse-btn-visible { display: none !important; } body.ots-sidebar-collapsed #content-wrapper, body.ots-sidebar-collapsed .ots-main, html.ots-sidebar-collapsed #content-wrapper, html.ots-sidebar-collapsed .ots-main { margin-left: var(--ots-sidebar-collapsed-width) !important; transition: margin-left 200ms ease; } .ots-sidebar-nav { padding: 12px 0 140px; padding-top: 6px; } /* When collapsed, add extra top padding so menu items sit below the header (logo + buttons) */ .ots-sidebar.collapsed .ots-sidebar-nav, body.ots-sidebar-collapsed .ots-sidebar-nav { padding-top: 72px !important; } .ots-sidebar:not(.collapsed) .ots-sidebar-nav { padding-top: 72px !important; } .sidebar-group { margin-top: 6px; } /* Center nav icons inside their item containers */ .ots-sidebar .sidebar-list > a, .ots-sidebar .sidebar-group-toggle { align-items: center !important; } .ots-sidebar .ots-nav-icon { margin: 0 auto !important; display: inline-flex !important; align-items: center !important; justify-content: center !important; } .sidebar-group-toggle { display: flex; align-items: center; gap: 12px; padding: 8px var(--ots-sidebar-item-padding-x); margin: 6px 0; border-radius: var(--ots-sidebar-item-radius); color: var(--ots-sidebar-link); text-decoration: none; background: var(--ots-sidebar-group-bg); 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: var(--ots-sidebar-active-bg); color: var(--ots-sidebar-active-text) !important; box-shadow: var(--ots-sidebar-active-shadow); } .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: var(--ots-sidebar-active-text) !important; } .sidebar-group-toggle:hover { background: var(--ots-sidebar-group-hover-bg); color: var(--ots-sidebar-link-hover-text); } .sidebar-group-caret { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); font-size: 12px; opacity: 0.95; cursor: pointer; pointer-events: auto; display: inline-flex; /* ensure visible whether open or closed */ align-items: center; justify-content: center; color: var(--ots-sidebar-link); /* default visible color */ } .sidebar-submenu { list-style: none; margin: 4px 0 8px; padding: 0 0 0 12px; border-left: 1px solid var(--ots-sidebar-border); display: none; } /* Show submenu on hover for accessibility and collapsed sidebar UX */ .ots-sidebar .sidebar-group:hover > .sidebar-submenu { display: block; } /* When the sidebar is collapsed, float submenus to the right as panels */ .ots-sidebar.collapsed .sidebar-submenu { position: absolute !important; left: calc(var(--ots-sidebar-collapsed-width) + 8px) !important; top: 0 !important; margin: 0 !important; padding: 8px !important; background: var(--color-surface) !important; border: 1px solid var(--color-border) !important; box-shadow: 0 8px 24px rgba(0,0,0,0.45) !important; min-width: 220px !important; z-index: 1300 !important; border-radius: 8px !important; display: none; list-style: none; } .ots-sidebar.collapsed .sidebar-group:hover > .sidebar-submenu { display: block !important; } /* Style submenu items when displayed in the hover panel */ .ots-sidebar.collapsed .sidebar-submenu .sidebar-list > a { display: flex !important; align-items: center !important; gap: 12px !important; padding: 10px 12px !important; margin: 4px 0 !important; width: 100% !important; height: auto !important; background: transparent !important; border-radius: 6px !important; color: var(--color-text-primary) !important; text-decoration: none !important; transition: all var(--transition-fast) !important; box-sizing: border-box !important; border: none !important; } .ots-sidebar.collapsed .sidebar-submenu .sidebar-list > a:hover { background: rgba(59, 130, 246, 0.12) !important; color: var(--color-primary) !important; } /* Show text and icon in submenu items when hovering */ .ots-sidebar.collapsed .sidebar-submenu .ots-nav-text, .ots-sidebar.collapsed .sidebar-submenu .ots-nav-icon { display: inline-flex !important; visibility: visible !important; width: auto !important; overflow: visible !important; } .ots-sidebar.collapsed .sidebar-submenu .ots-nav-icon { width: 20px !important; height: 20px !important; font-size: 14px !important; flex-shrink: 0 !important; margin: 0 !important; color: var(--color-text-primary) !important; } .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 0; background: var(--ots-sidebar-submenu-bg); 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 var(--ots-sidebar-submenu-border); border-radius: var(--ots-sidebar-item-radius); color: var(--ots-sidebar-link); font-weight: 500; } .sidebar-submenu .sidebar-list > a:hover { background: var(--ots-sidebar-submenu-hover-bg); color: var(--ots-sidebar-link-hover-text); } /* 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 { background: var(--ots-sidebar-submenu-hover-bg); } .sidebar-submenu .sidebar-list.active > a, .sidebar-submenu .sidebar-list > a.active { color: var(--ots-sidebar-active-text); background-color: var(--ots-sidebar-active-bg); box-shadow: var(--ots-sidebar-active-shadow); border-left-color: var(--color-primary); font-weight: 600; } /* sidebar-footer removed; account bar intentionally omitted */ .nav-section-divider { padding: 12px 16px 8px; margin-top: 8px; border-top: 1px solid var(--color-border); } .nav-label { display: block; font-size: 11px; font-weight: 700; text-transform: uppercase; color: var(--color-text-tertiary); letter-spacing: 0.08em; padding: 12px 16px 8px; margin-top: 8px; } .nav-item { display: flex; align-items: center; gap: 14px; padding: 12px 16px; color: var(--color-text-primary); text-decoration: none; transition: all var(--transition-fast); position: relative; font-size: 14px; font-weight: 500; border-left: 2px solid transparent; margin: 0 4px; border-radius: 6px; } .nav-item:hover { color: var(--color-text-primary); background-color: rgba(59, 130, 246, 0.1); border-left-color: transparent; } .nav-item.active { color: var(--color-primary); background-color: rgba(59, 130, 246, 0.12); border-left-color: var(--color-primary); font-weight: 600; } .nav-item.active::after { content: ''; position: absolute; right: 8px; width: 8px; height: 8px; background-color: var(--color-primary); border-radius: 50%; } .nav-icon { width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-size: 18px; } .nav-text { font-size: 14px; font-weight: 500; flex: 1; } .sidebar-footer { border-top: 1px solid var(--color-border); padding: 16px; background-color: rgba(59, 130, 246, 0.05); flex-shrink: 0; } .sidebar-user { display: flex; align-items: center; gap: 12px; } .user-avatar-lg { width: 40px; height: 40px; border-radius: 50%; background: linear-gradient(135deg, #3b82f6, #7c3aed); color: white; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 16px; flex-shrink: 0; } .user-details { min-width: 0; } .user-name { font-size: 14px; font-weight: 600; color: var(--color-text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .user-role { color: var(--color-text-secondary); white-space: nowrap; } /* ============================================================================ TOPBAR STYLES - CLEAN MODERN SINGLE LINE MENU BAR ============================================================================ Design decisions: - 56px total height — compact, modern feel - All interactive elements are 36px (buttons, avatar, icons) - Consistent 4px gap between nav items - Clean border-bottom separator, no heavy shadows - Proper z-index layering for dropdowns ============================================================================ */ .ots-topbar { background-color: transparent; padding: 0; display: flex; align-items: center; justify-content: flex-start; gap: 4px; height: 56px; z-index: 1000; position: relative; flex: 1; min-width: 0; } body.ots-sidebar-open .ots-topbar { background-color: transparent !important; box-shadow: none !important; } /* Topbar nav container - override .navbar-nav defaults */ .ots-topbar.navbar-nav { background: transparent !important; border: 0 !important; padding: 0 !important; margin: 0 !important; gap: 2px; height: 100%; align-items: center; flex-wrap: nowrap; } .ots-topbar .nav-item { display: flex; align-items: center; height: 100%; margin: 0 !important; padding: 0 !important; } .ots-topbar .nav-link { display: inline-flex; align-items: center; height: 36px; gap: 6px; padding: 0 10px; border-radius: 6px; color: var(--color-text-secondary); font-weight: 500; font-size: 13px; white-space: nowrap; transition: all 150ms ease; position: relative; border: 0 !important; background: transparent !important; box-shadow: none !important; } .ots-topbar .nav-link:hover { background-color: rgba(59, 130, 246, 0.06); color: var(--color-primary); } /* Ensure dropdowns, popovers and modals appear above the sticky topbar */ .dropdown, .dropdown-menu, .popover, .modal { z-index: 1201 !important; } /* Modal backdrop should sit behind the modal but above other content */ .modal-backdrop { z-index: 1200 !important; } .ots-topbar .nav-item.open .nav-link, .ots-topbar .nav-item.active .nav-link { background-color: rgba(59, 130, 246, 0.1); color: var(--color-primary); font-weight: 600; } .ots-topbar .dropdown-toggle::after { content: ''; display: inline-block; margin-left: 4px; width: 0; height: 0; border-left: 3.5px solid transparent; border-right: 3.5px solid transparent; border-top: 3.5px solid currentColor; opacity: 0.5; transition: transform 150ms ease; } .ots-topbar .nav-item.open .dropdown-toggle::after { transform: rotate(180deg); } .ots-topbar .dropdown-menu { border-radius: 10px; padding: 6px 0; margin-top: 4px; box-shadow: 0 12px 36px rgba(0, 0, 0, 0.25); border: 1px solid var(--color-border) !important; background-color: var(--color-surface-elevated); min-width: 180px; z-index: 3000; } .ots-topbar .dropdown-item, .ots-topbar .dropdown-menu a { display: flex; align-items: center; gap: 8px; border-radius: 6px; padding: 8px 12px; color: var(--color-text-secondary); font-size: 13px; font-weight: 500; margin: 1px 6px; transition: all 150ms ease; } .ots-topbar .dropdown-item:hover, .ots-topbar .dropdown-menu a:hover { background-color: rgba(59, 130, 246, 0.08); color: var(--color-primary); } /* Icon sizing for topbar and nav */ .ots-topbar-icon { width: 16px; height: 16px; display: flex; align-items: center; justify-content: center; font-size: 13px; opacity: 0.85; flex-shrink: 0; } .ots-topbar .dropdown-menu .ots-topbar-icon { font-size: 12px; } /* Left section: toggle, title, nav */ .topbar-left { display: flex; align-items: center; gap: 16px; flex: 1; min-width: 0; } .topbar-toggle { display: none; width: 36px; height: 36px; padding: 0; border: none; background-color: transparent; color: var(--color-text-primary); cursor: pointer; border-radius: 6px; transition: all var(--transition-fast); flex-shrink: 0; } .topbar-toggle:hover { background-color: rgba(59, 130, 246, 0.1); } .topbar-toggle:active { background-color: rgba(59, 130, 246, 0.15); } .topbar-toggle .icon { width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; } /* Title section with proper vertical centering */ .topbar-title { display: flex; flex-direction: column; justify-content: center; gap: 0; min-width: 0; } .topbar-title h1 { margin: 0; padding: 0; font-size: 18px; font-weight: 700; color: var(--color-text-primary); line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .topbar-title p { margin: 0; padding: 0; font-size: 12px; color: var(--color-text-tertiary); line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* Right section: search, actions */ .topbar-right { display: flex; align-items: center; gap: 12px; flex-shrink: 0; } /* Search box - 36px height to match button grid */ .topbar-search { position: relative; height: 36px; width: 240px; display: flex; align-items: center; background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: 6px; padding: 0 12px; gap: 8px; transition: all var(--transition-fast); } .topbar-search:focus-within { border-color: var(--color-primary); box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1); } .topbar-search .search-icon { color: var(--color-text-tertiary); flex-shrink: 0; font-size: 16px; width: 16px; height: 16px; display: flex; align-items: center; justify-content: center; } .topbar-search .search-input { flex: 1; background: none; border: none; color: var(--color-text-primary); font-size: 14px; outline: none; padding: 0; height: 100%; min-width: 120px; } .topbar-search .search-input::placeholder { color: var(--color-text-tertiary); } /* Action buttons container */ .topbar-actions { display: flex; align-items: center; gap: 4px; } /* Consistent 36px button sizing */ .topbar-btn { width: 36px; height: 36px; min-width: 36px; min-height: 36px; padding: 0; border: none; background-color: transparent; color: var(--color-text-secondary); cursor: pointer; border-radius: 6px; display: flex; align-items: center; justify-content: center; transition: all var(--transition-fast); position: relative; } .topbar-btn:hover { background-color: rgba(59, 130, 246, 0.08); color: var(--color-primary); } .topbar-btn:active { background-color: rgba(59, 130, 246, 0.12); } .topbar-btn .icon { width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; font-size: 16px; } .user-btn { padding: 2px; } .avatar { width: 36px; height: 36px; border-radius: 50%; background: linear-gradient(135deg, #3b82f6, #7c3aed); color: white; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 14px; } .avatar-sm { width: 32px; height: 32px; font-size: 13px; } .dropdown { position: relative; } .dropdown-menu, .dropdown-right { position: absolute; top: 100%; right: 0; margin-top: 8px; background-color: var(--color-surface-elevated); border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 8px; box-shadow: 0 20px 45px rgba(0, 0, 0, 0.3); list-style: none; padding: 8px 0; min-width: 180px; display: none; z-index: 1001; overflow: hidden; } /* Make DataTables button collections compatible with OTS dropdown styling */ .dt-buttons { position: relative; display: inline-block; } .dt-button-collection { position: absolute; top: 100%; right: 0; margin-top: 6px; display: none; z-index: 1002; min-width: 160px; background-color: var(--color-surface-elevated); border: 1px solid rgba(255, 255, 255, 0.08); border-radius: 8px; box-shadow: 0 20px 45px rgba(0, 0, 0, 0.3); overflow: hidden; padding: 6px 0; } .dt-buttons.active .dt-button-collection, .dt-button-collection.active, .dt-button-collection.show { display: block; animation: slideDown 150ms ease-out; } /* Ensure collection items are visible and styled */ .dt-button-collection .dt-button, .dt-button-collection button, .dt-button-collection a { display: block; width: 100%; padding: 6px 12px; color: var(--color-text-primary); background: transparent; text-decoration: none; font-size: 13px; text-align: left; border: none; } .dt-button-collection .dt-button:hover, .dt-button-collection a:hover, .dt-button-collection button:hover { background-color: rgba(59, 130, 246, 0.06); color: var(--color-primary); } .dt-button-collection input[type="checkbox"] { margin-right: 8px; vertical-align: middle; } .dt-button-collection .dt-button:focus, .dt-button-collection a:focus, .dt-button-collection button:focus { outline: none; box-shadow: none; } /* DataTables sometimes nests a `div.dropdown-menu` inside the collection. Ensure that inner dropdown-menu is visible when the collection is shown. */ .dt-button-collection .dropdown-menu { display: block !important; position: static !important; background: transparent !important; border: none !important; box-shadow: none !important; padding: 0 !important; min-width: 160px !important; } .dt-button-collection .dropdown-menu .dropdown-item, .dt-button-collection .dropdown-menu a, .dt-button-collection .dropdown-menu .dt-button { display: block !important; padding: 6px 12px !important; color: var(--color-text-primary) !important; text-decoration: none !important; background: transparent !important; text-align: left !important; } .dt-button-collection .dropdown-menu .dropdown-item:hover, .dt-button-collection .dropdown-menu a:hover, .dt-button-collection .dropdown-menu .dt-button:hover { background-color: rgba(59, 130, 246, 0.06) !important; color: var(--color-primary) !important; } .dropdown.active .dropdown-menu, .dropdown:focus-within .dropdown-menu { display: block; animation: slideDown 150ms ease-out; } @keyframes slideDown { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: translateY(0); } } .dropdown-menu li { display: block; } /* OTS topbar badge removed */ .dropdown-menu li a { display: flex; align-items: center; gap: 12px; padding: 10px 16px; color: var(--color-text-primary); text-decoration: none; font-size: 14px; transition: all var(--transition-fast); font-weight: 500; } .dropdown-menu li a:hover { background-color: rgba(59, 130, 246, 0.1); color: var(--color-primary); } .dropdown-menu li a:active { background-color: rgba(59, 130, 246, 0.15); } /* ============================================================================ DASHBOARD PAGE ============================================================================ */ .dashboard-card { background: linear-gradient(180deg, rgba(30, 41, 59, 0.92), rgba(15, 23, 42, 0.92)); border: 1px solid rgba(148, 163, 184, 0.18); border-radius: 16px; box-shadow: 0 18px 40px rgba(8, 15, 30, 0.35); backdrop-filter: blur(6px); transition: transform var(--transition-base), box-shadow var(--transition-base), border-color var(--transition-base); overflow: hidden; } .dashboard-card:hover { transform: translateY(-2px); box-shadow: 0 22px 50px rgba(8, 15, 30, 0.45); border-color: rgba(59, 130, 246, 0.45); } .dashboard-card .panel-header, .dashboard-card .widget-title { background: linear-gradient(90deg, rgba(59, 130, 246, 0.16), rgba(99, 102, 241, 0.12)); border-bottom: 1px solid rgba(148, 163, 184, 0.2); padding: 18px 20px; border-radius: 16px 16px 0 0; } .dashboard-card .panel-header h3, .dashboard-card .widget-title h3, .dashboard-card .panel-header h4, .dashboard-card .widget-title h4 { color: var(--color-text-primary); font-weight: 700; } .dashboard-card .panel-body, .dashboard-card .widget-body { padding: 20px; min-width: 0; width: 100%; } /* Ensure XiboData expands in grid */ .XiboData { width: 100%; min-width: 0; flex: 1; overflow: visible; } .kpi-card--modern { position: relative; overflow: hidden; } .kpi-card.dashboard-card { border-radius: 18px; padding: 22px; } .kpi-card--modern::after { content: ''; position: absolute; inset: 0; background: radial-gradient(circle at top right, rgba(59, 130, 246, 0.18), transparent 55%); pointer-events: none; } .kpi-card--modern .kpi-number { font-size: 36px; letter-spacing: -0.02em; } .kpi-card--modern .kpi-icon-box { background: linear-gradient(135deg, rgba(59, 130, 246, 0.28), rgba(99, 102, 241, 0.2)); color: #e2e8f0; } .action-card--modern { border-radius: 16px; background: linear-gradient(180deg, rgba(30, 41, 59, 0.9), rgba(15, 23, 42, 0.88)); border: 1px solid rgba(148, 163, 184, 0.2); box-shadow: 0 14px 30px rgba(8, 15, 30, 0.35); } .action-card--modern:hover { transform: translateY(-4px); border-color: rgba(59, 130, 246, 0.45); box-shadow: 0 20px 36px rgba(8, 15, 30, 0.45); } /* OTS dashboard message (theme-dashboard-message.twig) */ .ots-dashboard-message { margin: 16px 0 24px; padding: 12px 16px; border-radius: 10px; background: rgba(59, 130, 246, 0.12); border: 1px solid rgba(59, 130, 246, 0.35); color: var(--color-text-primary); } .ots-dashboard-message__title { font-weight: 700; letter-spacing: 0.02em; text-transform: uppercase; font-size: 12px; margin-bottom: 4px; } .ots-dashboard-message__body { font-size: 13px; color: var(--color-text-secondary); } .dashboard-page { display: flex; flex-direction: column; gap: 32px; } .page-header { margin-bottom: 16px; margin-left: 0 !important; } .page-header h1 { margin: 0 0 8px; font-size: 32px; font-weight: 700; } .page-header .text-muted { margin: 0; font-size: 16px; color: var(--color-text-secondary); } /* KPI Section */ .kpi-section { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 20px; } .kpi-card { background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: 8px; padding: 20px; transition: all var(--transition-base); } .kpi-card:hover { border-color: var(--color-primary); box-shadow: 0 0 0 1px var(--color-primary); } .kpi-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 16px; } .kpi-label { margin: 0; font-size: 14px; font-weight: 600; color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.05em; } .kpi-icon-box { width: 40px; height: 40px; border-radius: 6px; background: linear-gradient(135deg, rgba(59, 130, 246, 0.2), rgba(124, 58, 237, 0.2)); display: flex; align-items: center; justify-content: center; color: var(--color-primary); } .kpi-body { margin-bottom: 12px; } .kpi-number { font-size: 32px; font-weight: 700; color: var(--color-text-primary); line-height: 1; margin-bottom: 4px; } .kpi-meta { font-size: 13px; color: var(--color-text-secondary); } .kpi-footer { display: flex; align-items: center; gap: 8px; padding-top: 12px; border-top: 1px solid var(--color-border); } /* Badges */ .badge { display: inline-block; padding: 4px 10px; border-radius: 4px; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; } .badge-success { background-color: rgba(16, 185, 129, 0.2); color: #a7f3d0; } .badge-danger { background-color: rgba(239, 68, 68, 0.2); color: #fca5a5; } .badge-info { background-color: rgba(14, 165, 233, 0.2); color: #7dd3fc; } .badge-secondary { background-color: rgba(124, 58, 237, 0.2); color: #d8b4fe; } /* Dashboard Panels */ .dashboard-panels { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; } /* Dashboard chart cards (bandwidth/library) */ .dashboard-chart-card { background: linear-gradient(180deg, rgba(59, 130, 246, 0.06), rgba(59, 130, 246, 0.02)); border: 1px solid rgba(59, 130, 246, 0.18); box-shadow: 0 12px 26px rgba(8, 15, 30, 0.35); display: flex !important; flex-direction: column !important; min-height: 380px; height: 380px; align-items: stretch !important; overflow: visible !important; } .dashboard-chart-card > * { width: 100% !important; float: none !important; clear: both !important; } .dashboard-chart-header { display: flex !important; flex-direction: column !important; gap: 10px !important; align-items: flex-start !important; padding: 12px 16px !important; box-sizing: border-box !important; width: 100% !important; background: transparent !important; border: none !important; float: none !important; clear: both !important; position: static !important; inset: auto !important; overflow: visible !important; height: auto !important; max-width: none !important; flex: 0 0 auto !important; } .panel .dashboard-chart-header { padding: 12px 20px !important; } .dashboard-chart-info { display: flex !important; align-items: center !important; gap: 10px !important; flex: 0 0 auto !important; min-width: 0 !important; } .dashboard-chart-icon { width: 32px !important; height: 32px !important; border-radius: 10px !important; background: rgba(59, 130, 246, 0.18) !important; color: var(--color-primary-light) !important; display: flex !important; align-items: center !important; justify-content: center !important; font-size: 16px !important; flex-shrink: 0 !important; border: none !important; padding: 0 !important; margin: 0 !important; } .dashboard-chart-meta { display: flex !important; flex-direction: column !important; gap: 2px !important; flex-shrink: 0 !important; } .dashboard-chart-heading { margin: 0; font-size: 15px; font-weight: 700; line-height: 1.2; } .dashboard-chart-subtitle { margin: 0; font-size: 11px; color: var(--color-text-secondary); line-height: 1.2; } .dashboard-chart-actions { display: flex !important; align-items: center !important; gap: 12px !important; width: 100% !important; flex-shrink: 0 !important; padding: 0 !important; border: none !important; } .dashboard-chart-toggle { display: inline-flex; align-items: center; gap: 4px; padding: 4px; border-radius: 999px; background: rgba(15, 23, 42, 0.45); } .dashboard-chart-toggle-button { border: none; background: transparent; color: var(--color-text-secondary); font-size: 12px; font-weight: 600; width: 40px; height: 34px; padding: 0; border-radius: 999px; cursor: pointer; transition: all 150ms ease; display: inline-flex; align-items: center; justify-content: center; } .dashboard-chart-toggle-button:hover { color: var(--color-text-primary); } .dashboard-chart-toggle-button.is-active { background: rgba(59, 130, 246, 0.22); color: var(--color-text-primary); } .dashboard-chart-toggle-button i { font-size: 16px; line-height: 1; display: inline-block; } .dashboard-chart-body { padding: 0 20px 20px; flex: 1; display: flex; flex-direction: column; width: 100%; box-sizing: border-box; float: none; min-height: 0; } .dashboard-chart-canvas { /* Make chart containers visually match their parent dashboard card by removing their independent background and chrome so the card's background (gradient or surface) shows through. */ background: transparent !important; border: none !important; border-radius: inherit !important; padding: 0 !important; height: 200px; width: 100%; position: relative; overflow: hidden; flex: 1; box-shadow: none !important; } .dashboard-chart-canvas canvas { display: block; width: 100% !important; height: 100% !important; max-width: 100% !important; max-height: 100% !important; margin: 0 !important; background: transparent !important; } .dashboard-chart-card .panel-body canvas, .dashboard-chart-card .widget-body canvas { min-height: 0 !important; } /* Enhanced chart container styling */ .dashboard-chart-card { transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1) !important; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important; } .dashboard-chart-card:hover { box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25) !important; transform: translateY(-2px); } /* Chart action improvements */ .dashboard-chart-actions { gap: 16px !important; } .dashboard-chart-link { font-size: 13px; font-weight: 500; color: var(--color-primary-light); text-decoration: none; white-space: nowrap; transition: all 150ms ease; padding: 4px 8px; border-radius: 6px; display: inline-block; } .dashboard-chart-link:hover { color: var(--color-primary); background: rgba(59, 130, 246, 0.1); } /* Modern toggle improvements */ .dashboard-chart-toggle { background: rgba(15, 23, 42, 0.6); border: 1px solid rgba(59, 130, 246, 0.2); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); } .dashboard-chart-toggle-button { transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1); border: 1px solid transparent; } .dashboard-chart-toggle-button:hover { background: rgba(59, 130, 246, 0.12); border-color: rgba(59, 130, 246, 0.2); } .dashboard-chart-toggle-button.is-active { background: linear-gradient(135deg, rgba(59, 130, 246, 0.3), rgba(59, 130, 246, 0.2)); border-color: rgba(59, 130, 246, 0.3); box-shadow: 0 0 12px rgba(59, 130, 246, 0.2); } .dashboard-chart-toggle-button i { transition: transform 200ms ease; } .dashboard-chart-toggle-button:hover i { transform: scale(1.15); } /* Responsive chart cards */ @media (max-width: 1200px) { .dashboard-chart-canvas { height: 180px; } } @media (max-width: 768px) { .dashboard-chart-card { max-height: none; } .dashboard-chart-header { flex-direction: row !important; justify-content: space-between !important; align-items: center !important; gap: 12px !important; } .dashboard-chart-info { flex: 1; min-width: 0; } .dashboard-chart-actions { flex-shrink: 0; } .dashboard-chart-canvas { height: 200px; } } .panel { background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: 8px; overflow: hidden; display: flex; flex-direction: column; } /* ============================================================================ CONSOLIDATED CARD/PANEL/WIDGET STYLING (Simplified, single source of truth) ============================================================================ */ .card, .panel, .panel.panel-default, .panel.panel-white, .panel.box, .widget, .dashboard-card { background-color: var(--color-surface) !important; color: var(--color-text-primary) !important; border: 1px solid var(--color-border) !important; border-radius: 6px; display: flex; flex-direction: column; overflow: hidden; } /* Unified header/heading styling */ .panel-heading, .panel-header, .widget-title, .card-header, .dashboard-card-header { background-color: var(--color-surface-elevated) !important; border-bottom: 1px solid var(--color-border) !important; color: var(--color-text-primary) !important; padding: 12px 16px; font-weight: 600; } /* Unified body styling */ .panel-body, .panel-footer, .widget-body, .card-body, .dashboard-card-body { flex: 1; padding: 12px 16px; color: var(--color-text-primary) !important; background-color: transparent !important; min-height: 0; } /* Tables inside cards inherit styling */ .panel table, .panel table thead, .panel table tbody, .panel table tr, .panel table td, .panel table th, .panel .dataTables_wrapper, .card .dataTables_wrapper, .widget .dataTables_wrapper { background-color: transparent !important; color: var(--color-text-primary) !important; } .panel-full { grid-column: 1 / -1; } .panel-header { padding: 20px; border-bottom: 1px solid var(--color-border); display: flex; justify-content: space-between; align-items: center; } .panel-header h3 { margin: 0; font-size: 16px; font-weight: 600; color: var(--color-text-primary); } .link-secondary { color: var(--color-primary); text-decoration: none; font-size: 13px; font-weight: 500; transition: color var(--transition-fast); } .link-secondary:hover { color: var(--color-primary-light); } .panel-body { padding: 20px; flex: 1; display: flex; flex-direction: column; min-height: 0; } .empty-state-compact { text-align: center; padding: 20px 0; } .empty-state-compact p { margin: 0 0 16px; color: var(--color-text-secondary); } /* Quick Actions */ .quick-actions-grid { margin-top: 32px; } .section-title { margin: 0 0 16px; font-size: 18px; font-weight: 600; color: var(--color-text-primary); } .action-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; } .action-card { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 24px; background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: 8px; text-decoration: none; color: var(--color-text-primary); transition: all var(--transition-base); cursor: pointer; } .action-card:hover { border-color: var(--color-primary); background-color: rgba(59, 130, 246, 0.05); transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); } .action-icon { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; color: var(--color-primary); } .action-label { font-size: 14px; font-weight: 600; text-align: center; } /* ============================================================================ TWO-COLUMN LAYOUT (Displays, Media) ============================================================================ */ .ots-displays-page .page-header { margin-bottom: 20px; } .ots-displays-card { padding: 0; display: flex; flex-direction: column; min-width: 0; overflow: visible !important; } .ots-displays-body { flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: visible !important; } .ots-displays-body .XiboGrid { flex: 1; min-width: 0; display: flex; flex-direction: column; overflow: visible !important; } .ots-displays-title { font-size: 18px; font-weight: 700; letter-spacing: 0.02em; } .ots-filter-card { background-color: var(--color-surface-elevated) !important; background-image: none !important; border: 1px solid var(--color-border) !important; box-shadow: var(--ots-shadow-md, 0 8px 18px rgba(0,0,0,0.12)); margin-bottom: 0; border-radius: 12px; overflow: hidden; } /* Strongly remove any remaining gradients / shadows inside filters */ .ots-filter-card *, .ots-filter-card *::before, .ots-filter-card *::after { background-image: none !important; background: transparent !important; box-shadow: none !important; } .ots-filter-card .form-control, .ots-filter-card select, .ots-filter-card .select2-selection, .ots-filter-card .input-group-addon, .ots-filter-card button, .ots-filter-card .btn { background-color: var(--color-surface) !important; background-image: none !important; box-shadow: none !important; color: var(--color-text-primary) !important; } /* Extra strong fallbacks targeting various control classes used in filter markup */ .ots-filter-card input.form-control, .ots-filter-card input[type="text"], .ots-filter-card input[type="search"], .ots-filter-card textarea, .ots-filter-card select, .ots-filter-card select.custom-select, .ots-filter-card .custom-select, .ots-filter-card .input-group-text, .ots-filter-card .input-group-addon, .ots-filter-card .input-group-append, .ots-filter-card .input-group { background-color: var(--color-surface, var(--ots-surface, var(--color-background))) !important; background-image: none !important; background: var(--color-surface, var(--ots-surface, var(--color-background))) !important; box-shadow: none !important; border: 1px solid var(--color-border, var(--ots-border)) !important; } .ots-filter-card select option { background: var(--color-surface, var(--ots-surface)) !important; color: var(--color-text-primary, var(--ots-text)) !important; } /* Specific override for the append/addon area (checkbox + operator) */ .ots-filter-card .input-group-append, .ots-filter-card .input-group-append .input-group-text, .ots-filter-card .input-group-append .input-group-addon, .ots-filter-card .input-group-append .custom-select, .ots-filter-card .input-group-append .select, .ots-filter-card .input-group-append .btn, .ots-filter-card .input-group-append .dropdown-toggle { background-color: var(--color-surface) !important; background-image: none !important; background: var(--color-surface) !important; box-shadow: none !important; border: 1px solid var(--color-border) !important; color: var(--color-text-primary) !important; } /* Force checkbox wrapper to be transparent so only checkbox is visible */ .ots-filter-card .input-group-text input[type="checkbox"], .ots-filter-card .input-group-text input[type="checkbox"] + label { background: transparent !important; box-shadow: none !important; } /* Aggressive override: force all direct children of input-group to use solid surface */ .ots-filter-card .input-group > *, .ots-filter-card .input-group > *::before, .ots-filter-card .input-group > *::after { background: var(--color-surface, var(--ots-surface, var(--color-background))) !important; background-image: none !important; box-shadow: none !important; border-radius: 6px !important; border: 1px solid var(--color-border, var(--ots-border)) !important; color: var(--color-text-primary, var(--ots-text)) !important; } /* If any decorative pseudo elements are used to create the rounded pills, hide them */ .ots-filter-card .input-group > *::before, .ots-filter-card .input-group > *::after { content: none !important; display: none !important; } /* Filter header with collapse button */ .ots-filter-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: none; background: transparent; } .ots-filter-title { font-weight: 600; color: var(--color-text-primary); font-size: 14px; margin: 0; } .ots-filter-toggle { width: 32px; height: 32px; padding: 0; border: none; background: transparent; color: var(--color-text-secondary); cursor: pointer; display: flex; align-items: center; justify-content: center; border-radius: 6px; transition: all var(--transition-fast); } .ots-filter-toggle:hover { background: rgba(59, 130, 246, 0.1); color: var(--color-primary); } .ots-filter-content { padding: 16px; max-height: none; min-height: auto; overflow: visible; transition: max-height 300ms ease-out, padding 300ms ease-out; display: block; } .ots-filter-content.collapsed { max-height: 0; min-height: 0; padding: 0 16px; overflow: hidden; display: none; } .ots-filter-card .nav-tabs { border-bottom: 1px solid var(--color-border); gap: 8px; margin-bottom: 14px; } .ots-filter-card .nav-tabs .nav-link { color: var(--color-text-secondary); border: 0; border-radius: 8px; padding: 10px 14px; background: transparent; font-size: 13px; font-weight: 500; transition: all var(--transition-fast); } .ots-filter-card .nav-tabs .nav-link.active, .ots-filter-card .nav-tabs .nav-link:hover { color: var(--color-text-primary); background: rgba(59, 130, 246, 0.12); } .ots-filter-card .form-inline .form-group, .ots-filter-card .form-inline .input-group { margin-right: 16px; margin-bottom: 12px; } .ots-filter-card .form-control, .ots-filter-card select, .ots-filter-card .select2-selection, .ots-filter-card .input-group-addon { background: var(--color-surface) !important; background-image: none !important; border: 1px solid var(--color-border) !important; color: var(--color-text-primary) !important; border-radius: 6px !important; padding: 8px 12px !important; font-size: 13px !important; transition: all var(--transition-fast) !important; height: 36px !important; box-shadow: none !important; } .ots-filter-card .form-control:focus, .ots-filter-card select:focus { border-color: var(--color-primary) !important; box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.08) !important; background: var(--color-surface) !important; background-image: none !important; } /* Fix: force checkboxes to respect light/dark theme (remove hard dark square) */ .ots-filter-card input[type="checkbox"], .ots-filter-card .form-check-input, .ots-filter-card .custom-control-input { -webkit-appearance: none !important; appearance: none !important; width: 18px !important; height: 18px !important; display: inline-block !important; vertical-align: middle !important; border-radius: 4px !important; background-color: var(--color-surface) !important; background-image: none !important; border: 1px solid var(--color-border) !important; box-shadow: none !important; } .ots-filter-card input[type="checkbox"]:checked, .ots-filter-card .form-check-input:checked, .ots-filter-card .custom-control-input:checked { background-color: var(--color-primary) !important; border-color: var(--color-primary) !important; background-image: none !important; box-shadow: none !important; } /* Support bootstrap/custom-control markup where labels render the box via ::before */ .ots-filter-card .custom-control-input + .custom-control-label::before, .ots-filter-card .form-check-input + label::before, .modal .custom-control-input + .custom-control-label::before, .modal .form-check-input + label::before { background-color: var(--color-surface) !important; background-image: none !important; border: 1px solid var(--color-border) !important; box-shadow: none !important; } .ots-filter-card .custom-control-input:checked + .custom-control-label::before, .ots-filter-card .form-check-input:checked + label::before, .modal .custom-control-input:checked + .custom-control-label::before, .modal .form-check-input:checked + label::before { background-color: var(--color-primary) !important; border-color: var(--color-primary) !important; background-image: none !important; box-shadow: none !important; } /* Also apply broadly inside modals/popovers in case the checkbox is outside the filter card */ .modal input[type="checkbox"], .modal .form-check-input, .popover input[type="checkbox"], .popover .form-check-input { -webkit-appearance: none !important; appearance: none !important; width: 18px !important; height: 18px !important; background-color: var(--color-surface) !important; background-image: none !important; border: 1px solid var(--color-border) !important; box-shadow: none !important; } .modal input[type="checkbox"]:checked, .modal .form-check-input:checked, .popover input[type="checkbox"]:checked, .popover .form-check-input:checked { background-color: var(--color-primary) !important; border-color: var(--color-primary) !important; background-image: none !important; } .ots-filter-card label { color: var(--color-text-secondary); font-size: 12px; font-weight: 500; margin-bottom: 4px; display: block; } .ots-grid-with-folders { display: grid; grid-template-columns: 260px 1fr; gap: 32px; align-items: start; width: 100%; transition: grid-template-columns 200ms ease-out; } .ots-grid-with-folders.ots-folder-collapsed { grid-template-columns: 1fr; gap: 0; } .ots-grid-with-folders.ots-folder-collapsed .ots-folder-tree { display: none; width: 0; overflow: hidden; } .ots-folder-tree { min-height: 320px; padding: 16px; margin-right: -8px; max-width: 100%; box-sizing: content-box; } .ots-folder-tree .form-check { margin-top: 12px; } .ots-grid-controller { margin-top: 8px; } .ots-grid-controller .btn { border-radius: 10px; box-shadow: 0 6px 16px rgba(8, 15, 30, 0.25); } /* ============================================================================ SIMPLIFIED TABLE & DATATABLES STYLING (Consolidated) ============================================================================ */ .table, .table > thead > tr > th, .table > tbody > tr > td { color: var(--color-text-primary) !important; border-color: var(--color-border) !important; background-color: transparent !important; } .table-striped > tbody > tr:nth-of-type(odd) { background-color: rgba(79, 140, 255, 0.04) !important; } .table-hover > tbody > tr:hover { background-color: rgba(79, 140, 255, 0.08) !important; color: var(--color-text-primary) !important; } /* Selected rows */ .table tbody tr.selected, .table tbody tr.dt-row-selected { background-color: rgba(16, 185, 129, 0.25) !important; color: var(--color-text-primary) !important; } /* DataTables controls */ .dataTables_wrapper { color: var(--color-text-primary) !important; } .dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter, .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_paginate { color: var(--color-text-secondary) !important; } .dataTables_wrapper .dataTables_filter input, .dataTables_wrapper .dataTables_length select { background-color: var(--color-surface) !important; color: var(--color-text-primary) !important; border: 1px solid var(--color-border) !important; padding: 4px 8px; border-radius: 4px; } /* OTS table card (inherits from consolidated .card rule above) */ .ots-table-card { flex: 1; min-width: 0; overflow: hidden; } #datatable-container { width: 100%; overflow-x: auto; } .ots-table-card .table thead th { background: rgba(15, 23, 42, 0.9); color: var(--color-text-primary); border-bottom: 1px solid rgba(148, 163, 184, 0.2); } .ots-table-card .table thead th, .ots-table-card .table tbody td, .ots-table-card .table tbody th, .ots-table-card .table tbody tr { color: #e2e8f0; } .ots-table-card .table tbody tr { background: rgba(15, 23, 42, 0.7); } .ots-table-card .table tbody tr:nth-child(even) { background: rgba(30, 41, 59, 0.75); } .ots-table-card .table tbody tr:hover { background: rgba(59, 130, 246, 0.14); color: #ffffff; } .ots-table-card .table tbody tr.selected, .ots-table-card .table tbody tr.dt-row-selected, .ots-table-card .table tbody tr.selected td, .ots-table-card .table tbody tr.dt-row-selected td { background: rgba(16, 185, 129, 0.25) !important; color: #ffffff !important; } /* === Row dropdown menus (context menus on table rows) === When opened, these get moved to by JS so they escape all overflow:hidden containers. Styled here for both in-situ and body-appended states. */ body > .dropdown-menu.ots-row-dropdown { position: fixed !important; z-index: 1199 !important; display: block !important; background-color: var(--color-surface-elevated) !important; border: 1px solid var(--color-border) !important; border-radius: 8px !important; box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4) !important; padding: 6px 0 !important; min-width: 180px !important; max-height: 80vh; overflow-y: auto; } body > .dropdown-menu.ots-row-dropdown a, body > .dropdown-menu.ots-row-dropdown .dropdown-item { color: var(--color-text-primary) !important; padding: 8px 16px !important; font-size: 13px !important; display: block !important; white-space: nowrap !important; text-decoration: none !important; transition: background 120ms ease !important; } body > .dropdown-menu.ots-row-dropdown a:hover, body > .dropdown-menu.ots-row-dropdown .dropdown-item:hover { background-color: rgba(59, 130, 246, 0.12) !important; color: var(--color-primary-light) !important; } body > .dropdown-menu.ots-row-dropdown .divider, body > .dropdown-menu.ots-row-dropdown .dropdown-divider { border-top: 1px solid var(--color-border) !important; margin: 4px 0 !important; } /* Table toolbar — action buttons row inside the table card */ .ots-table-toolbar { display: flex; align-items: center; gap: 8px; padding: 8px 16px 12px; flex-wrap: wrap; } .ots-table-toolbar .btn { display: inline-flex !important; align-items: center !important; gap: 6px !important; font-size: 13px !important; font-weight: 600 !important; padding: 6px 14px !important; border-radius: 8px !important; white-space: nowrap !important; line-height: 1.4 !important; } .ots-table-toolbar .btn i, .ots-table-toolbar .btn .fa { font-size: 14px !important; } /* Light mode toolbar buttons */ body.ots-light-mode .ots-table-toolbar .btn-success { background-color: #10b981 !important; border-color: #10b981 !important; color: #ffffff !important; } body.ots-light-mode .ots-table-toolbar .btn-warning { background-color: #f59e0b !important; border-color: #f59e0b !important; color: #ffffff !important; } body.ots-light-mode .ots-table-toolbar .btn-primary { background-color: #3b82f6 !important; border-color: #3b82f6 !important; color: #ffffff !important; } .ots-table-card .dataTables_wrapper, .ots-table-card .dataTables_wrapper * { color: #e2e8f0 !important; } .ots-table-card .dataTables_wrapper .dataTables_filter input, .ots-table-card .dataTables_wrapper .dataTables_length select { background: rgba(15, 23, 42, 0.8) !important; color: #e2e8f0 !important; border: 1px solid rgba(148, 163, 184, 0.25) !important; } /* Extra specificity for Xibo Displays DataTable */ .ots-displays-page #datatable-container .XiboData .table, .ots-displays-page #datatable-container .XiboData table.dataTable { color: #e2e8f0 !important; } .ots-displays-page #datatable-container .XiboData .table thead th, .ots-displays-page #datatable-container .XiboData table.dataTable thead th { color: #cbd5e1 !important; background-color: var(--color-surface) !important; font-weight: 600 !important; opacity: 1 !important; } .ots-displays-page #datatable-container .XiboData .table tbody td, .ots-displays-page #datatable-container .XiboData table.dataTable tbody td { color: #e2e8f0 !important; opacity: 1 !important; } .ots-displays-page #datatable-container .XiboData table.dataTable tbody tr { background-color: rgba(15, 23, 42, 0.75) !important; } /* Status icons in Displays table */ .ots-displays-page #datatable-container .fa-check, .ots-displays-page #datatable-container .fa-check-circle { color: var(--color-success) !important; } .ots-displays-page #datatable-container .fa-times, .ots-displays-page #datatable-container .fa-times-circle, .ots-displays-page #datatable-container .fa-x { color: var(--color-danger) !important; } .ots-displays-page #datatable-container .XiboData table.dataTable tbody tr:nth-child(even) { background-color: rgba(30, 41, 59, 0.8) !important; } .ots-table-card .table tbody tr:hover { background: rgba(59, 130, 246, 0.08); } .ots-map-card { margin-top: 16px; min-height: 360px; background: rgba(15, 23, 42, 0.6); border: 1px solid rgba(148, 163, 184, 0.2); border-radius: 16px; } @media (max-width: 1024px) { .ots-grid-with-folders { grid-template-columns: 1fr; } } /* Light-mode table color overrides to ensure contrast and legibility */ body.ots-light-mode .ots-table-card .table thead th { background: var(--color-surface-elevated) !important; color: var(--color-text-primary) !important; border-bottom: 1px solid var(--color-border) !important; opacity: 1 !important; } body.ots-light-mode .ots-table-card .table thead th, body.ots-light-mode .ots-table-card .table tbody td, body.ots-light-mode .ots-table-card .table tbody th, body.ots-light-mode .ots-table-card .table tbody tr { color: var(--color-text-primary) !important; } body.ots-light-mode .ots-table-card .table tbody tr { background: var(--color-surface) !important; } body.ots-light-mode .ots-table-card .table tbody tr:nth-child(even) { background: var(--color-surface-elevated) !important; } body.ots-light-mode .ots-table-card .table tbody tr:hover { background: rgba(37, 99, 235, 0.06) !important; /* subtle blue hover */ color: var(--color-text-primary) !important; } body.ots-light-mode .ots-table-card .table tbody tr.selected, body.ots-light-mode .ots-table-card .table tbody tr.dt-row-selected, body.ots-light-mode .ots-table-card .table tbody tr.selected td, body.ots-light-mode .ots-table-card .table tbody tr.dt-row-selected td { background: rgba(16, 185, 129, 0.12) !important; color: var(--color-text-primary) !important; } body.ots-light-mode .ots-table-card .dataTables_wrapper, body.ots-light-mode .ots-table-card .dataTables_wrapper * { color: var(--color-text-primary) !important; } body.ots-light-mode .ots-table-card .dataTables_wrapper .dataTables_filter input, body.ots-light-mode .ots-table-card .dataTables_wrapper .dataTables_length select { background: var(--color-surface) !important; color: var(--color-text-primary) !important; border: 1px solid var(--color-border) !important; } /* Ensure Displays page specific table rows are light in light-mode */ body.ots-light-mode .ots-displays-page #datatable-container .XiboData table.dataTable tbody tr { background-color: transparent !important; } body.ots-light-mode .ots-displays-page #datatable-container .XiboData table.dataTable tbody tr:nth-child(even) { background-color: var(--color-surface-elevated) !important; } .two-column-layout { display: grid; grid-template-columns: 280px 1fr; gap: 24px; height: calc(100vh - 130px); } .left-panel { background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: 8px; display: flex; flex-direction: column; overflow-y: auto; } .content-panel { display: flex; flex-direction: column; gap: 16px; } .folder-tree { padding: 8px 0; } .folder-item { display: flex; align-items: center; gap: 12px; padding: 10px 16px; color: var(--color-text-secondary); cursor: pointer; transition: all var(--transition-fast); } .folder-item:hover { background-color: var(--color-surface-elevated); color: var(--color-text-primary); } .folder-item.active { background-color: rgba(59, 130, 246, 0.15); color: var(--color-primary); } .folder-icon { width: 18px; height: 18px; flex-shrink: 0; } .folder-name { font-size: 14px; font-weight: 500; } .content-toolbar { display: flex; align-items: center; gap: 16px; padding: 16px; background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: 8px; } .search-wrapper { flex: 1; position: relative; display: flex; align-items: center; background-color: var(--color-surface-elevated); border: 1px solid var(--color-border); border-radius: 6px; padding: 8px 12px; } .search-icon { color: var(--color-text-tertiary); margin-right: 8px; flex-shrink: 0; } .search-field { flex: 1; background: none; border: none; color: var(--color-text-primary); font-size: 14px; outline: none; padding: 0; } .search-field::placeholder { color: var(--color-text-tertiary); } .toolbar-actions { display: flex; align-items: center; gap: 12px; } .stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px; } .stat-box { background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: 6px; padding: 12px; text-align: center; } .stat-label { font-size: 12px; color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 8px; } .stat-value { font-size: 24px; font-weight: 700; color: var(--color-text-primary); } .text-success { color: #10b981; } .text-danger { color: #ef4444; } /* ============================================================================ TABLES ============================================================================ */ .table-wrapper { background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: 8px; overflow-x: auto; } .table { width: 100%; border-collapse: collapse; margin: 0; font-size: 14px; } .table thead { background-color: var(--color-surface); border-bottom: 2px solid var(--color-border); } .table thead th { padding: 12px 16px; text-align: left; font-weight: 600; color: var(--color-text-secondary); text-transform: uppercase; letter-spacing: 0.05em; font-size: 11px; background-color: var(--color-surface); } /* Status icons and checkmarks color */ .table tbody td .fa-check, .table tbody td .fa-check-circle { color: var(--color-success); } .table tbody td .fa-times, .table tbody td .fa-times-circle, .table tbody td .fa-x { color: var(--color-danger); } .table tbody td .fa-exclamation, .table tbody td .fa-exclamation-circle, .table tbody td .fa-question-circle { color: var(--color-warning); } .table tbody td .fa-info-circle { color: var(--color-info); } .table tbody tr { border-bottom: 1px solid var(--color-border); transition: background-color var(--transition-fast); } .table tbody tr:hover { background-color: var(--color-surface-elevated); } .table tbody td { padding: 12px 16px; color: var(--color-text-primary); } .table-striped tbody tr:nth-child(even) { background-color: rgba(59, 130, 246, 0.02); } /* ============================================================================ MEDIA LIBRARY ============================================================================ */ .media-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; padding: 16px; background-color: var(--color-surface); border: 1px solid var(--color-border); border-radius: 8px; } .media-item { background-color: var(--color-surface-elevated); border: 1px solid var(--color-border); border-radius: 6px; overflow: hidden; cursor: pointer; transition: all var(--transition-base); } .media-item:hover { border-color: var(--color-primary); box-shadow: 0 4px 12px rgba(59, 130, 246, 0.2); transform: translateY(-4px); } .media-thumbnail { position: relative; width: 100%; padding-bottom: 75%; overflow: hidden; background-color: var(--color-border); } .media-thumbnail img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; } .media-type-badge { position: absolute; top: 8px; right: 8px; background-color: rgba(0, 0, 0, 0.6); color: white; padding: 4px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; text-transform: uppercase; } .media-info { padding: 12px; } .media-name { margin: 0 0 4px; font-size: 14px; font-weight: 600; color: var(--color-text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .media-size { margin: 0; color: var(--color-text-tertiary); } /* ============================================================================ BUTTONS ============================================================================ */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 10px 16px; border: none; border-radius: 6px; font-size: 14px; font-weight: 600; text-decoration: none; cursor: pointer; transition: all var(--transition-fast); white-space: nowrap; } .btn-primary { background-color: var(--color-primary); color: white; } .btn-primary:hover { background-color: var(--color-primary-dark); } .btn-outline { background-color: transparent; border: 1px solid var(--color-border); color: var(--color-text-primary); } .btn-outline:hover { background-color: var(--color-surface); border-color: var(--color-primary); color: var(--color-primary); } .btn-sm { padding: 6px 12px; font-size: 13px; } .btn-ghost { background-color: transparent; color: var(--color-text-secondary); padding: 0; } .btn-ghost:hover { color: var(--color-text-primary); } /* Minimal Icon-Only Buttons */ .btn-icon { width: 40px !important; height: 40px !important; padding: 0 !important; border-radius: 8px !important; display: inline-flex !important; align-items: center !important; justify-content: center !important; background-color: var(--color-surface-elevated) !important; border: 1px solid var(--color-border) !important; color: var(--color-text-secondary) !important; font-size: 0 !important; transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1) !important; cursor: pointer !important; position: relative !important; margin-left: 6px !important; flex-shrink: 0 !important; } .btn-icon:hover { background-color: rgba(59, 130, 246, 0.12) !important; border-color: rgba(59, 130, 246, 0.3) !important; color: var(--color-primary-light) !important; box-shadow: 0 2px 8px rgba(59, 130, 246, 0.1) !important; } .btn-icon:active { background-color: rgba(59, 130, 246, 0.2) !important; border-color: rgba(59, 130, 246, 0.4) !important; transform: scale(0.95); } .btn-icon i, .btn-icon svg { font-size: 17px !important; line-height: 1 !important; display: inline-block !important; } .btn-icon.btn-success { background-color: rgba(34, 197, 94, 0.08) !important; border-color: rgba(34, 197, 94, 0.2) !important; color: rgb(34, 197, 94) !important; } .btn-icon.btn-success:hover { background-color: rgba(34, 197, 94, 0.15) !important; border-color: rgba(34, 197, 94, 0.4) !important; box-shadow: 0 2px 8px rgba(34, 197, 94, 0.1) !important; } /* ============================================================================ UTILITY CLASSES ============================================================================ */ .text-muted { color: var(--color-text-secondary); } .text-tertiary { color: var(--color-text-tertiary); } .text-xs { font-size: 12px; } .text-sm { font-size: 14px; } .form-control { background-color: var(--color-surface); border: 1px solid var(--color-border); color: var(--color-text-primary); padding: 8px 12px; border-radius: 6px; font-size: 14px; } .form-control::placeholder { color: var(--color-text-secondary); } .form-control:focus { outline: none; border-color: var(--color-primary); box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); } /* ============================================================================ RESPONSIVE ============================================================================ */ @media (max-width: 768px) { .ots-topbar { flex-direction: column; align-items: flex-start; gap: 12px; height: auto; padding: 12px 16px; } .topbar-right { width: 100%; flex-direction: column; } .topbar-search { width: 100%; } .two-column-layout { grid-template-columns: 1fr; height: auto; } .left-panel { max-height: 300px; } .dashboard-panels { grid-template-columns: 1fr; } .kpi-section { grid-template-columns: 1fr; } .action-cards { grid-template-columns: 1fr; } .media-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); } .ots-content { padding: 16px 16px 16px 0; } .ots-footer { padding: 12px 16px; } } /* ============================================================================ CANVAS / CHART ELEMENTS ============================================================================ */ /* Ensure canvas elements and chart containers render properly */ canvas { max-width: 100%; height: auto; display: block; } .chart-container, .chart-wrapper { position: relative; width: 100%; height: 100%; } /* OTS sidebar override marker */ .ots-sidebar-wrapper { box-shadow: inset 0 0 0 1px rgba(59, 130, 246, 0.15); } .ots-sidebar .sidebar-list a, .ots-sidebar .sidebar-main a { display: flex; align-items: center; gap: 10px; } .ots-nav-icon { width: 18px; text-align: center; opacity: 0.85; font-size: 14px; } .ots-nav-text { flex: 1; min-width: 0; } /* Xibo sidebar refinements (light) */ #sidebar-wrapper .sidebar-title a { color: var(--color-text-tertiary); font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; padding: 12px 16px 6px; } #sidebar-wrapper .sidebar-list a, #sidebar-wrapper .sidebar-main a { display: flex; align-items: center; gap: 12px; margin: 2px 8px; padding: 10px 12px; border-radius: 8px; transition: background-color var(--transition-fast), color var(--transition-fast); } #sidebar-wrapper .sidebar-list a:hover, #sidebar-wrapper .sidebar-main a:hover { background: rgba(59, 130, 246, 0.1); color: var(--color-primary); } /* Ensure chart parent containers have proper sizing */ .panel-body canvas, .panel-body .chart-container { flex: 1; min-height: 300px; } .panel-body > .chart-container, .panel-body > .chart-wrapper { width: 100% !important; height: 100% !important; } .panel-body > .chart-container > canvas, .panel-body > .chart-wrapper > canvas { width: 100% !important; height: 100% !important; } .dashboard-chart-card [class*="chart"] { height: auto; } /* Hidden dashboard chart canvas bridge */ .chart-sandbox { position: absolute; left: -10000px; top: -10000px; width: 1px; height: 1px; overflow: hidden; pointer-events: none; } .chart-sandbox canvas { width: 1px !important; height: 1px !important; } /* Transition variable fallback */ :root { --transition-fast: 150ms ease-in-out; --transition-base: 200ms ease-in-out; --transition-slow: 300ms ease-in-out; } /* ================================================================ Modern table styles (theme override) Applied: makes XIBO tables look cleaner and responsive ================================================================ */ .modern-table-card { background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)); border-radius: 10px; box-shadow: 0 6px 18px rgba(2,6,23,0.45); padding: 18px; margin: 16px 0; border: 1px solid rgba(255,255,255,0.02); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial; } .modern-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; color: var(--color-text-primary); } .modern-table thead th { background: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.03)); color: var(--color-text-primary); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; font-size: 11px; padding: 10px 12px; border-bottom: 1px solid rgba(255,255,255,0.1); position: sticky; top: 0; z-index: 2; } .modern-table tbody tr { background: transparent; } .modern-table tbody tr:nth-child(odd) { background: rgba(255,255,255,0.01); } .modern-table tbody tr:hover { background: rgba(59,130,246,0.06); } .modern-table td { padding: 12px; vertical-align: middle; border-bottom: 1px solid rgba(255,255,255,0.02); } .table-controls { display:flex; gap:8px; align-items:center; justify-content:flex-end; margin-bottom:12px; } .table-controls .btn { background: var(--color-primary); color: var(--color-on-primary); border-radius: 999px; padding: 6px 10px; font-size: 13px; border: none; cursor: pointer; } .table-controls .btn.ghost { background:transparent; color:var(--color-primary); border:1px solid rgba(59,130,246,0.12); } .table-meta { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding-top: 10px; font-size: 13px; color: var(--color-text-secondary); } @media (max-width: 880px) { .modern-table thead th:nth-child(n+6), .modern-table tbody td:nth-child(n+6) { display: none; } .modern-table tbody td.details-toggle { display: table-cell; } .modern-table-card { padding: 12px; /* Backdrop shown when sidebar is active on small screens */ .ots-backdrop { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.45); z-index: 1040; } .ots-backdrop.show { display: block; } } } /* Improve legibility: force table and datatables text to full contrast */ .modern-table, .modern-table tbody, .modern-table tbody tr, .modern-table td, .dataTables_wrapper, .dataTables_wrapper table, .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_length, .dataTables_wrapper .dataTables_filter { color: var(--Color-fallback, var(--color-text-primary)) !important; opacity: 1 !important; } /* Stronger selected row for readability */ .modern-table tbody tr.selected, .modern-table tbody tr.dt-row-selected, .dataTables_wrapper table tbody tr.selected, .dataTable tbody tr.selected { background: rgba(16,185,129,0.14) !important; /* stronger mint */ color: var(--color-text-primary) !important; } /* Inputs and selects used in filters/search should be readable */ .dataTables_wrapper .dataTables_filter input, .dataTables_wrapper .dataTables_length select, .topbar-search .search-input, .table-controls input, input[type="search"], input[type="text"], select, textarea { background: var(--color-surface) !important; color: var(--color-text-primary) !important; border: 1px solid var(--color-border) !important; } /* Buttons - ensure contrast */ .btn, .button, .dataTables_wrapper .dataTables_paginate .paginate_button { color: var(--color-text-primary) !important; } /* If panels or overlays dim content, ensure table contents remain fully visible */ .panel, .panel-body, .table-wrapper, .dataTables_wrapper .dataTables_scrollBody { opacity: 1 !important; background: transparent !important; } /* DataTables color adjustments to ensure legibility in dark theme */ .dataTables_wrapper, .dataTables_wrapper * { color: var(--color-text-primary) !important; } /* Ensure tables scroll within their container, not the page */ .dataTables_wrapper { max-width: 100% !important; overflow-x: auto !important; box-sizing: border-box !important; } table.dataTable, .XiboData table, .ots-table-card table { max-width: 100% !important; table-layout: auto !important; } .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_paginate { color: var(--color-text-primary) !important; } .dataTables_wrapper .dataTables_paginate .paginate_button { background: transparent; color: var(--color-text-primary) !important; border: 1px solid transparent; border-radius: 6px; padding: 4px 8px; } .dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover { background: var(--color-primary) !important; color: var(--color-on-primary) !important; border-color: rgba(255,255,255,0.06); } /* Global legibility overrides */ body, .ots-content, .content, .container, .card, .panel, .panel-body, .table, .dataTables_wrapper, .dropdown-menu, .dropdown-right { color: var(--color-text-primary) !important; } .text-muted, .text-secondary, .text-tertiary { color: var(--color-text-secondary) !important; opacity: 1 !important; } .ots-sidebar a, .ots-sidebar .nav-item, .ots-sidebar .nav-label, .ots-sidebar .nav-text { color: var(--color-text-primary) !important; } a, .nav-link { color: var(--color-text-primary); } a:hover, .nav-link:hover { color: var(--color-primary); } /* ============================================================================ COMPREHENSIVE DARK THEME ENFORCEMENT Ensure all elements have readable contrast and dark backgrounds ============================================================================ */ /* Force ALL text to be readable - master override */ * { color-scheme: dark; } /* Ensure headings are always visible */ h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { color: var(--color-text-primary) !important; } /* 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; } /* Override: when collapsed, center icons — must follow expanded rules above */ #sidebar-wrapper.ots-sidebar.collapsed .ots-nav-icon, #sidebar-wrapper.collapsed .sidebar-list .ots-nav-icon, #sidebar-wrapper.collapsed .sidebar-main .ots-nav-icon { display: flex !important; width: 20px !important; height: 20px !important; margin: 0 auto !important; margin-left: auto !important; margin-right: auto !important; text-align: center !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, legend { color: var(--color-text-primary) !important; } /* Dropdowns, modals, and popovers */ .dropdown-menu, .dropdown-toggle, .popover { background-color: var(--color-surface) !important; color: var(--color-text-primary) !important; border: 1px solid var(--color-border) !important; } .modal, .modal-body, .modal-footer { background-color: transparent !important; color: var(--color-text-primary) !important; border: 1px solid var(--color-border) !important; } .modal-content { background-color: var(--color-surface) !important; color: var(--color-text-primary) !important; border: 1px solid var(--color-border) !important; } .modal-backdrop, .modal-backdrop.show, .modal-backdrop.in { background-color: rgba(0, 0, 0, 0.3) !important; backdrop-filter: blur(4px) !important; opacity: 1 !important; } .modal-header { background-color: var(--color-surface-elevated) !important; border-bottom: 1px solid var(--color-border) !important; } .dropdown-menu a, .dropdown-item { color: var(--color-text-primary) !important; } .dropdown-menu a:hover, .dropdown-item:hover { background-color: rgba(59, 130, 246, 0.12) !important; color: var(--color-primary) !important; } /* Ensure all pop-up/dialog surfaces follow theme variables (light/dark toggle) */ .modal, .modal-content, .modal-header, .modal-body, .modal-footer, .popover, .popover .popover-body, .tooltip, .tooltip .tooltip-inner, .dropdown-menu, .select2-dropdown, .select2-container--default .select2-dropdown { background-color: var(--color-surface) !important; color: var(--color-text-primary) !important; border: 1px solid var(--color-border) !important; box-shadow: var(--shadow-base, 0 6px 18px rgba(0,0,0,0.08)) !important; } /* Elevated headers inside modals should use elevated surface */ .modal-header { background-color: var(--color-surface-elevated) !important; border-bottom: 1px solid var(--color-border) !important; } /* Tooltips */ .tooltip .tooltip-inner { background-color: var(--color-text-primary) !important; color: var(--color-background) !important; border-radius: 6px !important; } /* Select2 dropdowns and choices */ .select2-container--default .select2-results__option[aria-selected=true], .select2-container--default .select2-results__option--highlighted { background-color: rgba(var(--color-primary-rgb, 37,99,235), 0.12) !important; } /* Modal backdrop should be lighter in light mode */ .modal-backdrop, .modal-backdrop.show, .modal-backdrop.in { background-color: rgba(0,0,0,0.3) !important; } body.ots-light-mode .modal-backdrop, body.ots-light-mode .modal-backdrop.show, body.ots-light-mode .modal-backdrop.in { background-color: rgba(0,0,0,0.06) !important; } /* Ensure form elements are dark and readable */ .form-group, .form-check, .input-group { color: var(--color-text-primary) !important; } input, textarea, select, .form-control, .form-select { background-color: var(--color-surface) !important; color: var(--color-text-primary) !important; border: 1px solid var(--color-border) !important; } input::placeholder, textarea::placeholder { color: var(--color-text-secondary) !important; } input:focus, textarea:focus, select:focus { background-color: var(--color-surface) !important; color: var(--color-text-primary) !important; border-color: var(--color-primary) !important; box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important; } /* Alerts and messages */ .alert, .alert-info, .alert-warning, .alert-success, .alert-danger, .alert-light { background-color: var(--color-surface) !important; border: 1px solid var(--color-border) !important; color: var(--color-text-primary) !important; } .alert-light { background-color: var(--color-surface-elevated) !important; } /* Tooltips and help text */ .tooltip, .tooltip-inner, .help-block, .form-text, small { color: var(--color-text-secondary) !important; background-color: transparent !important; } /* Breadcrumbs */ .breadcrumb { background-color: transparent !important; color: var(--color-text-primary) !important; } .breadcrumb a { color: var(--color-primary) !important; } .breadcrumb-item.active { color: var(--color-text-secondary) !important; } /* Pagination */ .pagination, .pager { background-color: transparent !important; } .pagination a, .pagination button, .pager a { color: var(--color-text-primary) !important; background-color: transparent !important; border: 1px solid var(--color-border) !important; } .pagination a:hover, .pagination button:hover, .pager a:hover { background-color: var(--color-surface) !important; color: var(--color-primary) !important; border-color: var(--color-primary) !important; } .pagination .active a, .pagination .active button, .pager .active a { background-color: var(--color-primary) !important; border-color: var(--color-primary) !important; color: white !important; } /* Disabled state */ [disabled], :disabled, .disabled { opacity: 0.6 !important; color: var(--color-text-secondary) !important; } /* Badge customization */ .badge, .badge-default { background-color: var(--color-surface-elevated) !important; color: var(--color-text-primary) !important; } /* List groups */ .list-group, .list-group-item { background-color: var(--color-surface) !important; color: var(--color-text-primary) !important; border: 1px solid var(--color-border) !important; } .list-group-item:hover { background-color: var(--color-surface-elevated) !important; } .list-group-item.active { background-color: var(--color-primary) !important; border-color: var(--color-primary) !important; color: white !important; } /* Tabs */ .nav-tabs, .nav-pills { background-color: transparent !important; } .nav-tabs .nav-link, .nav-pills .nav-link { color: var(--color-text-secondary) !important; background-color: transparent !important; } .nav-tabs .nav-link:hover, .nav-pills .nav-link:hover { color: var(--color-text-primary) !important; background-color: rgba(59, 130, 246, 0.1) !important; } .nav-tabs .nav-link.active, .nav-pills .nav-link.active { color: white !important; background-color: var(--color-primary) !important; border-color: var(--color-primary) !important; } /* Cards */ .card { background-color: var(--color-surface) !important; color: var(--color-text-primary) !important; border: 1px solid var(--color-border) !important; } .card-header { background-color: var(--color-surface-elevated) !important; border-bottom: 1px solid var(--color-border) !important; color: var(--color-text-primary) !important; } .card-footer { background-color: var(--color-surface-elevated) !important; border-top: 1px solid var(--color-border) !important; color: var(--color-text-secondary) !important; } /* Progress bars */ .progress { background-color: var(--color-surface-elevated) !important; } .progress-bar { background-color: var(--color-primary) !important; } /* Ensure code blocks are readable */ code, .code, pre { background-color: var(--color-surface-elevated) !important; color: var(--color-text-primary) !important; border: 1px solid var(--color-border) !important; } /* DataTables specific overrides */ .dataTables_wrapper { color: var(--color-text-primary) !important; } .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_paginate { background-color: transparent !important; color: var(--color-text-primary) !important; } .dataTables_wrapper table tbody tr { color: var(--color-text-primary) !important; } .dataTables_wrapper table tbody tr:hover { background-color: rgba(59, 130, 246, 0.08) !important; } /* Spinner/loading indicators */ .spinner, .spinner-border, .spinner-grow { border-color: rgba(255, 255, 255, 0.25) !important; } .spinner-border.text-primary, .spinner-grow.text-primary { color: var(--color-primary) !important; border-color: var(--color-primary) !important; } /* Links should always be visible and contrasting */ a { color: var(--color-primary) !important; text-decoration: none; } a:hover { color: var(--color-primary-light) !important; text-decoration: underline; } a.text-muted { color: var(--color-text-secondary) !important; } /* Tidy (library) button - broom icon and amber colouring */ .btn-tidy { background-color: var(--color-warning) !important; border-color: rgba(0,0,0,0.08) !important; color: var(--color-on-primary) !important; } .btn-tidy .fa, .btn-tidy .fas, .btn-tidy .far { color: var(--color-on-primary) !important; } /* Slightly darker hover for contrast (fallback where color-mix isn't available) */ .btn-tidy:hover { filter: brightness(0.95) !important; color: var(--color-on-primary) !important; } /* Ensure inline SVG broom inherits the tidy button colour and sizes nicely */ .btn-tidy svg.icon-broom, .btn-tidy svg.icon-broom-pantry { width: 18px !important; height: 18px !important; display: inline-block !important; vertical-align: middle !important; fill: currentColor !important; } a.text-muted:hover { color: var(--color-text-primary) !important; } /* Ensure absolutely nothing is invisible */ .hidden, [hidden] { display: none !important; } .invisible { visibility: hidden !important; } /* ============================================================================ FILTER FIELDS PADDING ============================================================================ */ .FilterDiv.card-body { padding-top: 20px !important; } /* ============================================================================ LOGO WITH TEXT STYLING ============================================================================ */ .navbar-brand.xibo-logo-container { display: flex; align-items: center; gap: 10px; padding: 0; margin-right: 12px; height: 56px; } .xibo-logo-text { color: var(--color-text-primary); font-size: 18px; font-weight: 600; margin: 0; white-space: nowrap; } /* Strong final light-mode table overrides (high specificity & !important) Placed at file end to ensure highest precedence over earlier dark rules. */ body.ots-light-mode .table, body.ots-light-mode .dataTable, body.ots-light-mode .dataTables_wrapper, body.ots-light-mode .ots-table-card .table, body.ots-light-mode .ots-table-card .dataTables_wrapper { color: var(--color-text-primary) !important; background-color: transparent !important; opacity: 1 !important; } body.ots-light-mode .table thead th, body.ots-light-mode .dataTable thead th, body.ots-light-mode .ots-table-card .table thead th { color: var(--color-text-secondary) !important; background-color: var(--color-surface) !important; opacity: 1 !important; } body.ots-light-mode .table tbody td, body.ots-light-mode .dataTable tbody td, body.ots-light-mode .ots-table-card .table tbody td { color: var(--color-text-primary) !important; opacity: 1 !important; } body.ots-light-mode .table tbody tr, body.ots-light-mode .dataTable tbody tr, body.ots-light-mode .ots-table-card .table tbody tr { background: transparent !important; } body.ots-light-mode .table tbody tr:nth-child(even), body.ots-light-mode .dataTable tbody tr:nth-child(even), body.ots-light-mode .ots-table-card .table tbody tr:nth-child(even) { background: var(--color-surface-elevated) !important; } body.ots-light-mode .table tbody tr:hover, body.ots-light-mode .dataTable tbody tr:hover, body.ots-light-mode .ots-table-card .table tbody tr:hover { background: rgba(37, 99, 235, 0.06) !important; } /* Ensure disabled/low-contrast states do not dim important table text */ body.ots-light-mode .table [disabled], body.ots-light-mode .table .disabled, body.ots-light-mode .table :disabled { opacity: 1 !important; color: var(--color-text-secondary) !important; } /* Target Xibo-specific table selectors that used light colors with !important */ body.ots-light-mode .ots-displays-page #datatable-container .XiboData .table thead th, body.ots-light-mode .ots-displays-page #datatable-container .XiboData table.dataTable thead th { color: var(--color-text-secondary) !important; background-color: var(--color-surface) !important; } body.ots-light-mode .ots-displays-page #datatable-container .XiboData .table tbody td, body.ots-light-mode .ots-displays-page #datatable-container .XiboData table.dataTable tbody td { color: var(--color-text-primary) !important; opacity: 1 !important; } /* Also ensure any `.text-muted` or tertiary text inside tables becomes readable in light-mode */ body.ots-light-mode .table thead th .text-muted, body.ots-light-mode .table tbody td .text-muted, body.ots-light-mode .ots-table-card .table thead th .text-muted { color: var(--color-text-tertiary) !important; opacity: 1 !important; } /* Override the hardcoded #e2e8f0 colors from lines 2659 & 2673 in light-mode by matching exact selectors with body.ots-light-mode prefix */ body.ots-light-mode .ots-displays-page #datatable-container .XiboData .table, body.ots-light-mode .ots-displays-page #datatable-container .XiboData table.dataTable { color: var(--color-text-primary) !important; } body.ots-light-mode .ots-displays-page #datatable-container .XiboData .table tbody td, body.ots-light-mode .ots-displays-page #datatable-container .XiboData table.dataTable tbody td { color: var(--color-text-primary) !important; opacity: 1 !important; } /* Ensure all table cells and text are dark in light-mode */ body.ots-light-mode .ots-displays-page #datatable-container .XiboData .table tr, body.ots-light-mode .ots-displays-page #datatable-container .XiboData table.dataTable tr { color: var(--color-text-primary) !important; } /* ============================================================================ Remove hover animations inside the page wrapper This prevents elements inside `#page-wrapper` from animating on hover while keeping other site transitions intact. ============================================================================ */ #page-wrapper *:hover { transition: none !important; transform: none !important; animation: none !important; box-shadow: none !important; } #page-wrapper, #page-wrapper * { will-change: auto !important; } /* Re-enable hover/transform/animation behavior inside dashboard areas only */ #page-wrapper .dashboard-page *:hover, #page-wrapper .dashboard-card *:hover, #page-wrapper .dashboard-panels *:hover, #page-wrapper .dashboard-chart-card *:hover { transition: initial !important; transform: initial !important; animation: initial !important; box-shadow: initial !important; } #page-wrapper .dashboard-page, #page-wrapper .dashboard-card, #page-wrapper .dashboard-panels, #page-wrapper .dashboard-chart-card { will-change: auto !important; } /* Ensure the very bottom of the page follows the theme variables (light/dark) by forcing html/body and shell containers to use the variable-driven background. This prevents residual dark bars under the footer. */ html, body, .ots-shell, #page-wrapper { min-height: 100% !important; background-color: var(--color-background) !important; } /* Repair: remove any visible divider/seam between sidebar and main content Some themes add a border or pseudo-element that creates a dark vertical bar. Force those to be transparent/none so the content sits flush. */ .ots-sidebar, #sidebar-wrapper { border-right: none !important; box-shadow: none !important; } /* Hide common pseudo-elements used as dividers or overlays */ .ots-sidebar::after, .ots-sidebar::before, #page-wrapper::before, #page-wrapper::after, .ots-main::before, .ots-main::after { content: none !important; display: none !important; background: transparent !important; box-shadow: none !important; } .ots-footer { background-color: var(--color-surface-elevated) !important; color: var(--color-text-primary) !important; } /* Content area tracks the sidebar width. The expanded value comes from --ots-sidebar-width (256px) set in :root. The collapsed value comes from body.ots-sidebar-collapsed overrides. */ #content-wrapper, .ots-main { margin-left: var(--ots-sidebar-width) !important; width: calc(100vw - var(--ots-sidebar-width)) !important; max-width: calc(100vw - 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; } body.ots-sidebar-collapsed #content-wrapper, body.ots-sidebar-collapsed .ots-main, html.ots-sidebar-collapsed #content-wrapper, html.ots-sidebar-collapsed .ots-main { margin-left: var(--ots-sidebar-collapsed-width) !important; width: calc(100vw - var(--ots-sidebar-collapsed-width)) !important; max-width: calc(100vw - var(--ots-sidebar-collapsed-width)) !important; } /* Emergency: force root/background pseudo-elements to follow theme variables This clears any leftover background-images or pseudo-element fills that can create a dark bar at the bottom. */ html, html:before, html:after, body, body:before, body:after, .ots-shell, #page-wrapper, #page-wrapper:before, #page-wrapper:after { background-image: none !important; background-color: var(--color-background) !important; color: var(--color-text-primary) !important; min-height: 100vh !important; } /* Remove any content on pseudo-elements that might draw a dark strip */ html:before, html:after, body:before, body:after, #page-wrapper:before, #page-wrapper:after { content: none !important; } /* ============================================================================ COMPREHENSIVE LIGHT-MODE TABLE OVERRIDES (Final Pass) Force all table colors to be light-background + dark-text in light mode ============================================================================ */ body.ots-light-mode .table, body.ots-light-mode .table thead, body.ots-light-mode .table tbody, body.ots-light-mode .table thead th, body.ots-light-mode .table tbody td, body.ots-light-mode .table tbody tr, body.ots-light-mode .dataTables_wrapper, body.ots-light-mode .dataTables_wrapper table, body.ots-light-mode .dataTables_wrapper thead, body.ots-light-mode .dataTables_wrapper thead th, body.ots-light-mode .dataTables_wrapper tbody, body.ots-light-mode .dataTables_wrapper tbody td, body.ots-light-mode .dataTables_wrapper tbody tr, body.ots-light-mode .modern-table, body.ots-light-mode .modern-table thead, body.ots-light-mode .modern-table thead th, body.ots-light-mode .modern-table tbody, body.ots-light-mode .modern-table tbody tr, body.ots-light-mode .modern-table tbody td { color: var(--color-text-primary) !important; background-color: transparent !important; opacity: 1 !important; } body.ots-light-mode .table thead th, body.ots-light-mode .dataTables_wrapper thead th, body.ots-light-mode .modern-table thead th { background-color: var(--color-surface-elevated) !important; color: var(--color-text-secondary) !important; } body.ots-light-mode .table tbody tr:nth-child(even), body.ots-light-mode .dataTables_wrapper tbody tr:nth-child(even), body.ots-light-mode .modern-table tbody tr:nth-child(even) { background-color: var(--color-surface-elevated) !important; } body.ots-light-mode .table tbody tr:hover, body.ots-light-mode .dataTables_wrapper tbody tr:hover, body.ots-light-mode .modern-table tbody tr:hover { background-color: rgba(37, 99, 235, 0.06) !important; } body.ots-light-mode .dataTables_wrapper .dataTables_info, body.ots-light-mode .dataTables_wrapper .dataTables_length, body.ots-light-mode .dataTables_wrapper .dataTables_filter, body.ots-light-mode .dataTables_wrapper .dataTables_paginate { color: var(--color-text-primary) !important; } body.ots-light-mode .dataTables_wrapper .dataTables_filter input, body.ots-light-mode .dataTables_wrapper .dataTables_length select { background-color: var(--color-surface) !important; color: var(--color-text-primary) !important; border-color: var(--color-border) !important; } body.ots-light-mode .dataTables_wrapper .dataTables_paginate .paginate_button { background-color: var(--color-surface) !important; color: var(--color-text-primary) !important; border-color: var(--color-border) !important; } body.ots-light-mode .dataTables_wrapper .dataTables_paginate .paginate_button.current { background-color: var(--color-primary) !important; color: white !important; border-color: var(--color-primary) !important; } /* Aggressive unconditional overrides to ensure table text is readable These apply regardless of light/dark mode */ .table td, .table th, .dataTable td, .dataTable th, .dataTables_wrapper td, .dataTables_wrapper th, .modern-table td, .modern-table th { color: #0f172a !important; } .dataTables_wrapper .dataTables_info, .dataTables_wrapper .dataTables_filter, .dataTables_wrapper .dataTables_length { color: #0f172a !important; } .table thead, .dataTable thead, .modern-table thead { background-color: #f1f5f9 !important; } .dataTables_wrapper .dataTables_filter input, .dataTables_wrapper .dataTables_length select { color: #0f172a !important; background-color: #ffffff !important; border-color: #e2e8f0 !important; }