diff --git a/ots-signs/config.php b/ots-signs/config.php
index c8efa74..c47100a 100644
--- a/ots-signs/config.php
+++ b/ots-signs/config.php
@@ -8,7 +8,7 @@
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
- * any later version.
+ * any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -17,20 +17,20 @@
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see
Please press the back button in your browser.");
$config = array(
- 'theme_name' => 'otssigns',
- 'theme_title' => 'OTS Signs',
- 'app_name' => 'OTS Signage',
- 'theme_url' => 'CMS Homepage',
- 'cms_source_url' => 'https://github.com/xibosignage/xibo-cms',
- 'cms_install_url' => 'manual/en/install_cms.html',
- 'cms_release_notes_url' => 'manual/en/release_notes.html',
- 'latest_news_url' => 'http://xibo.org.uk/feed/',
- 'client_sendCurrentLayoutAsStatusUpdate_enabled' => false,
- 'client_screenShotRequestInterval_enabled' => false,
- "view_path" => "../web/theme/custom/ots-signs/views",
- 'product_support_url' => 'https://community.xibo.org.uk/c/support'
- );
+ 'theme_name' => 'ots-signs',
+ 'theme_title' => 'OTS Signs',
+ 'app_name' => 'OTS Signage',
+ 'theme_url' => 'CMS Homepage',
+ 'cms_source_url' => 'https://github.com/xibosignage/xibo-cms',
+ 'cms_install_url' => 'manual/en/install_cms.html',
+ 'cms_release_notes_url' => 'manual/en/release_notes.html',
+ 'latest_news_url' => 'http://xibo.org.uk/feed/',
+ 'client_sendCurrentLayoutAsStatusUpdate_enabled' => false,
+ 'client_screenShotRequestInterval_enabled' => false,
+ 'view_path' => '../web/theme/custom/ots-signs/views',
+ 'product_support_url' => 'https://community.xibo.org.uk/c/support'
+);
diff --git a/ots-signs/css/override-dark.css b/ots-signs/css/override-dark.css
deleted file mode 100644
index dfb7588..0000000
--- a/ots-signs/css/override-dark.css
+++ /dev/null
@@ -1,1515 +0,0 @@
-/* =============================================================================
- OTS SIGNAGE DARK THEME (REBUILT)
- February 4, 2026
- ============================================================================= */
-
-@import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400&display=swap');
-
-:root {
- color-scheme: dark;
-
- --ots-bg: #0b111a;
- --ots-surface: #141c2b;
- --ots-surface-2: #1b2436;
- --ots-surface-3: #222c3f;
- --ots-border: #2c3a54;
- --ots-border-soft: #243047;
- --ots-text: #e6eefb;
- --ots-text-muted: #a9b6cc;
- --ots-text-faint: #8d99b4;
- --ots-primary: #e87800;
- --ots-primary-rgb: 232, 120, 0;
- --ots-primary-2: #c46500;
- --ots-success: #2ad4a4;
- --ots-warning: #f4b860;
- --ots-danger: #ff6b6b;
- --ots-info: #5ec0ff;
-
- --ots-shadow-lg: 0 14px 30px rgba(0, 0, 0, 0.35);
- --ots-shadow-md: 0 8px 18px rgba(0, 0, 0, 0.25);
- --ots-shadow-sm: 0 3px 8px rgba(0, 0, 0, 0.2);
-
- --ots-radius-sm: 4px;
- --ots-radius-md: 8px;
- --ots-radius-lg: 12px;
-
- --ots-transition: 160ms ease;
-
- /* Modal pop-ups */
- --modal-backdrop-bg: rgba(2, 6, 23, 0.55);
- --modal-backdrop-blur: 6px;
- --modal-bg: #141c2b;
- --modal-border: #2c3a54;
- --modal-radius: 12px;
- --modal-shadow: 0 24px 64px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(255, 255, 255, 0.04);
- --modal-header-bg: #0f172a;
- --modal-header-border: #2c3a54;
- --modal-header-text: #f1f5f9;
- --modal-body-bg: #141c2b;
- --modal-body-text: #e2e8f0;
- --modal-footer-bg: #0f172a;
- --modal-footer-border: #2c3a54;
- --modal-close-color: #64748b;
- --modal-close-hover: #f1f5f9;
- --modal-input-bg: #0b111a;
- --modal-input-border: #2c3a54;
- --modal-input-text: #e6eefb;
- --modal-input-focus-border: #e87800;
- --modal-input-focus-ring: rgba(var(--ots-primary-rgb), 0.2);
-}
-
-/* =============================================================================
- GLOBAL
- ============================================================================= */
-
-html,
-body {
- background: var(--ots-bg);
- color: var(--ots-text);
-}
-
-body {
- font-family: "DM Sans", system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
- -webkit-font-smoothing: antialiased;
- text-rendering: optimizeLegibility;
- font-feature-settings: "kern" 1, "liga" 1;
-}
-
-a,
-.nav-link,
-.sidebar a {
- color: var(--ots-text);
- text-decoration: none;
- transition: color var(--ots-transition), background var(--ots-transition);
-}
-
-a:hover,
-.nav-link:hover,
-.sidebar a:hover {
- color: var(--ots-primary);
-}
-
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- color: var(--ots-text);
- font-weight: 600;
-}
-
-small,
-.text-muted {
- color: var(--ots-text-muted) !important;
-}
-
-hr {
- border-color: var(--ots-border);
-}
-
-/* ---------- Accessibility: focus-visible ---------- */
-*:focus-visible {
- outline: 2px solid var(--ots-primary);
- outline-offset: 2px;
-}
-
-.btn:focus-visible,
-.form-control:focus-visible,
-.form-select:focus-visible,
-.nav-link:focus-visible {
- outline: 2px solid var(--ots-primary);
- outline-offset: 2px;
- box-shadow: 0 0 0 3px rgba(var(--ots-primary-rgb), 0.25);
-}
-
-.ots-sidebar li a:focus-visible {
- outline: 2px solid var(--ots-primary);
- outline-offset: -2px;
- border-radius: var(--ots-radius-sm);
-}
-
-.sidebar-group-toggle:focus-visible {
- outline: 2px solid var(--ots-primary);
- outline-offset: -2px;
- border-radius: var(--ots-radius-sm);
-}
-
-table tbody tr:focus-within {
- outline: 1px solid var(--ots-primary);
- outline-offset: -1px;
-}
-
-/* =============================================================================
- LAYOUT WRAPPERS
- ============================================================================= */
-
-#page-wrapper,
-#content-wrapper,
-.page-content {
- background: var(--ots-bg);
-}
-
-.page-content {
- padding-top: 24px;
-}
-
-/* =============================================================================
- NAVBAR / TOPBAR
- ============================================================================= */
-
-.navbar,
-.navbar-default {
- background: var(--ots-surface-2);
- border: 1px solid var(--ots-border);
-}
-
-/* Horizontal nav mode: remove sidebar margins from #content-wrapper */
-.navbar.navbar-expand-lg ~ #content-wrapper {
- margin-left: 0 !important;
- width: 100% !important;
- max-width: 100% !important;
- padding-left: 20px !important;
- padding-right: 20px !important;
-}
-
-.navbar.navbar-expand-lg ~ #content-wrapper .page-content {
- padding-left: 0 !important;
- padding-right: 0 !important;
-}
-
-.navbar.navbar-expand-lg ~ #content-wrapper .page-content .row {
- margin-left: 0 !important;
- margin-right: 0 !important;
-}
-
-.navbar.navbar-expand-lg ~ #content-wrapper .page-content [class*="col-"] {
- padding-left: 0 !important;
- padding-right: 0 !important;
-}
-
-.navbar.navbar-expand-lg ~ #content-wrapper .page-content > .row > .col-sm-12 {
- padding-left: 0 !important;
- padding-right: 0 !important;
-}
-
-.navbar.navbar-expand-lg ~ #content-wrapper,
-.navbar.navbar-expand-lg ~ #content-wrapper .page-content {
- background: var(--ots-bg) !important;
- color: var(--ots-text) !important;
-}
-
-.navbar-brand,
-.navbar-brand .xibo-logo {
- color: var(--ots-text);
-}
-
-.navbar-nav > li > a,
-.navbar-nav > .active > a,
-.navbar-nav > .open > a {
- color: var(--ots-text) !important;
- background: transparent !important;
-}
-
-.navbar-nav > li > a:hover {
- color: var(--ots-primary) !important;
-}
-
-.navbar-toggler,
-.navbar-toggler-side {
- color: var(--ots-text);
- border: 1px solid var(--ots-border);
-}
-
-/* Topbar nav refinements (dark) */
-.ots-topbar.navbar-nav {
- background: transparent;
- border: 0;
- padding: 0;
- margin: 0;
- gap: 6px;
- height: auto;
- align-items: center;
-}
-
-.ots-topbar .nav-link {
- display: inline-flex;
- align-items: center;
- gap: 8px;
- padding: 8px 12px;
- border-radius: 10px;
- color: var(--ots-text);
- font-weight: 600;
- transition: background var(--ots-transition), color var(--ots-transition);
-}
-
-.ots-topbar .nav-link:hover,
-.ots-topbar .nav-item.open .nav-link,
-.ots-topbar .nav-item.active .nav-link {
- background: rgba(var(--ots-primary-rgb), 0.18);
- color: var(--ots-primary);
-}
-
-.ots-topbar .dropdown-menu {
- border-radius: 12px;
- padding: 8px;
- box-shadow: var(--ots-shadow-md);
-}
-
-.ots-topbar .dropdown-item,
-.ots-topbar .dropdown-menu a {
- display: flex;
- align-items: center;
- gap: 8px;
- border-radius: 8px;
- padding: 8px 10px;
-}
-
-.ots-topbar-icon {
- width: 16px;
- text-align: center;
- opacity: 0.85;
- font-size: 13px;
-}
-
-/* =============================================================================
- SIDEBAR
- ============================================================================= */
-
-#sidebar-wrapper {
- background: var(--ots-surface);
- border-right: 1px solid var(--ots-border);
- display: flex;
- flex-direction: column;
- height: 100vh;
- overflow: hidden;
-}
-
-/* OTS sidebar override marker */
-.ots-sidebar-wrapper {
- display: flex;
- flex-direction: column;
- height: 100vh;
- background: var(--ots-surface);
-}
-
-/* Sidebar Header */
-.ots-sidebar-header {
- display: flex;
- align-items: center;
- gap: 12px;
- padding: 16px;
- border-bottom: 1px solid var(--ots-border);
- background: var(--ots-surface);
-}
-
-.ots-brand-logo {
- width: 40px;
- height: 40px;
- display: flex;
- align-items: center;
- justify-content: center;
- background: rgba(var(--ots-primary-rgb), 0.15);
- border: 1px solid rgba(var(--ots-primary-rgb), 0.3);
- border-radius: var(--ots-radius-sm);
- font-size: 18px;
- color: var(--ots-primary);
- flex-shrink: 0;
-}
-
-.ots-brand-text {
- flex: 1;
- min-width: 0;
-}
-
-.ots-brand-name {
- display: block;
- font-size: 14px;
- font-weight: 600;
- color: var(--ots-text);
- letter-spacing: 0.5px;
-}
-
-.ots-sidebar-close {
- background: none;
- border: none;
- color: var(--ots-text-secondary);
- cursor: pointer;
- padding: 4px;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: color var(--ots-transition);
- flex-shrink: 0;
-}
-
-.ots-sidebar-close:hover {
- color: var(--ots-text);
-}
-
-/* Sidebar Content */
-.ots-sidebar {
- flex: 1;
- list-style: none;
- margin: 0;
- padding: 12px 0;
- overflow-y: auto;
- overflow-x: hidden;
-}
-
-.ots-sidebar li {
- margin: 0;
- padding: 0;
-}
-
-/* Dark-mode repair overrides: ensure sidebar doesn't draw a vertical divider */
-#sidebar-wrapper,
-.ots-sidebar {
- border-right: none !important;
- box-shadow: none !important;
-}
-
-/* Hide pseudo-elements that might draw a divider */
-.ots-sidebar::before,
-.ots-sidebar::after,
-#sidebar-wrapper::before,
-#sidebar-wrapper::after,
-#page-wrapper::before,
-#page-wrapper::after {
- content: none !important;
- display: none !important;
- background: transparent !important;
- box-shadow: none !important;
-}
-
-/* Sidebar Main Item */
-.ots-sidebar li.sidebar-main > a {
- display: flex;
- align-items: center;
- gap: 12px;
- margin: 0 8px;
- padding: 10px 12px;
- border-radius: var(--ots-radius-sm);
- color: var(--ots-text);
- text-decoration: none;
- transition: background var(--ots-transition), color var(--ots-transition);
- font-size: 14px;
- font-weight: 500;
-}
-
-.ots-sidebar li.sidebar-main > a:hover {
- background: rgba(var(--ots-primary-rgb), 0.12);
- color: var(--ots-primary);
-}
-
-.ots-sidebar li.sidebar-main > a.active {
- background: rgba(var(--ots-primary-rgb), 0.2);
- color: var(--ots-primary);
-}
-
-/* Sidebar Section (Collapsible) */
-.ots-sidebar li.sidebar-section > a.sidebar-section-toggle {
- display: flex;
- align-items: center;
- gap: 12px;
- margin: 0 8px;
- padding: 10px 12px;
- border-radius: var(--ots-radius-sm);
- color: var(--ots-text);
- text-decoration: none;
- transition: background var(--ots-transition), color var(--ots-transition);
- font-size: 14px;
- font-weight: 500;
- cursor: pointer;
- background: none;
- border: none;
- text-align: left;
- width: calc(100% - 16px);
-}
-
-.ots-sidebar li.sidebar-section > a.sidebar-section-toggle:hover {
- background: rgba(var(--ots-primary-rgb), 0.12);
- color: var(--ots-primary);
-}
-
-.ots-sidebar li.sidebar-section > a.sidebar-section-toggle.active {
- background: rgba(var(--ots-primary-rgb), 0.12);
- color: var(--ots-primary);
-}
-
-.ots-section-toggle-icon {
- margin-left: auto;
- font-size: 12px;
- transition: transform var(--ots-transition);
-}
-
-.ots-sidebar li.sidebar-section > a.sidebar-section-toggle.active .ots-section-toggle-icon {
- transform: rotate(180deg);
-}
-
-/* Sidebar Subsection */
-.ots-sidebar .sidebar-subsection {
- list-style: none;
- margin: 0;
- padding: 4px 0;
- display: none;
- background: rgba(var(--ots-primary-rgb), 0.05);
-}
-
-.ots-sidebar .sidebar-subsection.active {
- display: block;
-}
-
-.ots-sidebar .sidebar-subsection li {
- margin: 0;
- padding: 0;
-}
-
-/* Sidebar List Item */
-.ots-sidebar li.sidebar-list > a {
- display: flex;
- align-items: center;
- gap: 12px;
- margin: 2px 12px 2px 28px;
- padding: 8px 12px;
- border-radius: 4px;
- color: var(--ots-text-secondary);
- text-decoration: none;
- transition: background var(--ots-transition), color var(--ots-transition);
- font-size: 13px;
-}
-
-.ots-sidebar li.sidebar-list > a:hover {
- background: rgba(var(--ots-primary-rgb), 0.12);
- color: var(--ots-primary);
-}
-
-.ots-sidebar li.sidebar-list > a.active {
- background: rgba(var(--ots-primary-rgb), 0.15);
- color: var(--ots-primary);
-}
-
-/* Navigation Icons and Text */
-
-/* ==========================================================================
- FORCE DARK BACKGROUND FALLBACKS
- Ensure no white areas appear when scrolling or when elements overflow.
- This uses high-specificity selectors and !important to override stray
- light-background rules from other stylesheets.
- ========================================================================== */
-
-html, body, #page-wrapper, .ots-main, .ots-content, .page-content, .container {
- background-color: var(--color-background) !important;
- background: none !important;
- color: var(--color-text-primary) !important;
-}
-
-/* Remove or neutralise any pseudo-elements that may paint a light background */
-html::before, html::after, body::before, body::after, #page-wrapper::before, #page-wrapper::after {
- background: transparent !important;
- content: none !important;
-}
-
-/* Ensure fixed/backdrop layers are dark where appropriate */
-.modal-backdrop,
-.modal,
-.modal-open,
-.ots-shell,
-.ots-footer {
- background-color: var(--color-background) !important;
-}
-
-/* Defensive: override any explicit white panel backgrounds that leak outside their container */
-.card, .panel, .panel-body, .dashboard-card, .content-card, .ots-sidebar li.sidebar-list.active > a {
- background-color: var(--color-surface) !important;
- color: var(--color-text-primary) !important;
-}
-.ots-nav-icon {
- width: 16px;
- height: 16px;
- display: flex;
- align-items: center;
- justify-content: center;
- text-align: center;
- opacity: 0.85;
- font-size: 14px;
- flex-shrink: 0;
-}
-
-.ots-nav-text {
- flex: 1;
- min-width: 0;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-/* Sidebar Spacer */
-.sidebar-spacer {
- height: 12px;
- margin-top: auto;
-}
-
-/* Sidebar Footer */
-.ots-sidebar-footer {
- display: flex;
- align-items: center;
- gap: 12px;
- padding: 12px 16px;
- border-top: 1px solid var(--ots-border);
- background: var(--ots-surface);
-}
-
-.ots-user-section {
- flex: 1;
- min-width: 0;
-}
-
-.ots-user-role {
- font-size: 11px;
- color: var(--ots-text-secondary);
- text-transform: uppercase;
- letter-spacing: 0.5px;
- margin-bottom: 2px;
-}
-
-.ots-user-name {
- font-size: 13px;
- font-weight: 500;
- color: var(--ots-text);
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.ots-user-profile-link {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 32px;
- height: 32px;
- border-radius: 4px;
- color: var(--ots-text-secondary);
- text-decoration: none;
- transition: background var(--ots-transition), color var(--ots-transition);
- font-size: 16px;
- flex-shrink: 0;
-}
-
-.ots-user-profile-link:hover {
- background: rgba(var(--ots-primary-rgb), 0.12);
- color: var(--ots-primary);
-}
-
-#sidebar-wrapper .sidebar-main a:hover,
-#sidebar-wrapper .sidebar-list a:hover {
- background: rgba(var(--ots-primary-rgb), 0.12);
- color: var(--ots-primary);
-}
-
-#sidebar-wrapper .sidebar-title a {
- padding: 12px 18px 6px;
- color: var(--ots-text-faint);
- font-size: 11px;
- letter-spacing: 0.08em;
- text-transform: uppercase;
-}
-
-/* =============================================================================
- WIDGETS / CARDS
- ============================================================================= */
-
-.widget,
-.card,
-.panel,
-.modal-content {
- background: var(--ots-surface-2);
- border: 1px solid var(--ots-border);
- border-radius: var(--ots-radius-md);
- box-shadow: var(--ots-shadow-sm);
-}
-
-.widget-title,
-.panel-heading,
-.card-header,
-.modal-header {
- background: var(--ots-surface-3);
- border-bottom: 1px solid var(--ots-border);
- color: var(--ots-text);
-}
-
-.widget-body,
-.panel-body,
-.card-body,
-.modal-body {
- color: var(--ots-text);
-}
-
-/* =============================================================================
- BUTTONS
- ============================================================================= */
-
-.btn,
-button,
-input[type="button"],
-input[type="submit"] {
- border-radius: var(--ots-radius-sm);
- border: 1px solid transparent;
- transition: background var(--ots-transition), border var(--ots-transition), color var(--ots-transition);
-}
-
-.btn-default,
-.btn-secondary {
- background: var(--ots-surface-3);
- color: var(--ots-text);
- border-color: var(--ots-border);
-}
-
-.btn-default:hover,
-.btn-secondary:hover {
- background: var(--ots-surface-2);
- border-color: var(--ots-primary);
- color: var(--ots-primary);
-}
-
-.btn-primary {
- background: var(--ots-primary);
- border-color: var(--ots-primary-2);
- color: #0b1020;
-}
-
-.btn-primary:hover {
- background: var(--ots-primary-2);
- border-color: var(--ots-primary-2);
- color: #0b1020;
-}
-
-.btn-success {
- background: var(--ots-success);
- border-color: var(--ots-success);
- color: #041410;
-}
-
-.btn-warning {
- background: var(--ots-warning);
- border-color: var(--ots-warning);
- color: #1c1200;
-}
-
-.btn-danger {
- background: var(--ots-danger);
- border-color: var(--ots-danger);
- color: #220707;
-}
-
-.btn-info {
- background: var(--ots-info);
- border-color: var(--ots-info);
- color: #07101a;
-}
-
-/* =============================================================================
- FORMS
- ============================================================================= */
-
-.form-control,
-input[type="text"],
-input[type="search"],
-input[type="email"],
-input[type="password"],
-select,
-textarea {
- background: var(--ots-surface);
- color: var(--ots-text);
- border: 1px solid var(--ots-border);
- border-radius: var(--ots-radius-sm);
- box-shadow: none;
-}
-
-.form-control:focus,
-input[type="text"]:focus,
-input[type="search"]:focus,
-input[type="email"]:focus,
-input[type="password"]:focus,
-select:focus,
-textarea:focus {
- border-color: var(--ots-primary);
- box-shadow: 0 0 0 2px rgba(var(--ots-primary-rgb), 0.2);
- outline: none;
-}
-
-.input-group-addon {
- background: var(--ots-surface-3);
- border: 1px solid var(--ots-border);
- color: var(--ots-text-muted);
-}
-
-/* =============================================================================
- TABLES / DATATABLES
- ============================================================================= */
-
-.table,
-.table > thead > tr > th,
-.table > tbody > tr > td {
- color: var(--ots-text);
- border-color: var(--ots-border);
-}
-
-.table-striped > tbody > tr:nth-of-type(odd) {
- background: rgba(var(--ots-primary-rgb), 0.04);
-}
-
-.table-hover > tbody > tr:hover {
- background: rgba(var(--ots-primary-rgb), 0.08);
-}
-
-.dataTables_wrapper .dataTables_length,
-.dataTables_wrapper .dataTables_filter,
-.dataTables_wrapper .dataTables_info,
-.dataTables_wrapper .dataTables_paginate {
- color: var(--ots-text-muted) !important;
-}
-
-.dataTables_wrapper .dataTables_filter input,
-.dataTables_wrapper .dataTables_length select {
- background: var(--ots-surface) !important;
- color: var(--ots-text) !important;
- border: 1px solid var(--ots-border) !important;
-}
-
-.dataTables_wrapper table {
- color: var(--ots-text);
-}
-
-/* =============================================================================
- DROPDOWNS / MENUS
- ============================================================================= */
-
-.dropdown-menu {
- background: var(--ots-surface-2);
- border: 1px solid var(--ots-border);
- box-shadow: var(--ots-shadow-md);
-}
-
-.dropdown-item,
-.dropdown-menu > li > a {
- color: var(--ots-text);
-}
-
-.dropdown-item:hover,
-.dropdown-menu > li > a:hover {
- background: rgba(var(--ots-primary-rgb), 0.12);
- color: var(--ots-primary);
-}
-
-/* =============================================================================
- ALERTS / BADGES
- ============================================================================= */
-
-.alert {
- border-radius: var(--ots-radius-sm);
- border: 1px solid var(--ots-border);
-}
-
-.alert-success {
- background: rgba(42, 212, 164, 0.15);
- color: var(--ots-success);
-}
-
-.alert-warning {
- background: rgba(244, 184, 96, 0.15);
- color: var(--ots-warning);
-}
-
-.alert-danger {
- background: rgba(255, 107, 107, 0.15);
- color: var(--ots-danger);
-}
-
-.alert-info {
- background: rgba(94, 192, 255, 0.15);
- color: var(--ots-info);
-}
-
-.badge,
-.label {
- background: var(--ots-surface-3);
- color: var(--ots-text);
- border: 1px solid var(--ots-border);
-}
-
-/* =============================================================================
- TABS / PAGINATION
- ============================================================================= */
-
-.nav-tabs {
- border-bottom: 1px solid var(--ots-border);
-}
-
-.nav-tabs > li > a {
- color: var(--ots-text-muted);
- border: 1px solid transparent;
-}
-
-.nav-tabs > li.active > a,
-.nav-tabs > li.active > a:focus,
-.nav-tabs > li.active > a:hover {
- background: var(--ots-surface-2);
- color: var(--ots-text);
- border: 1px solid var(--ots-border);
- border-bottom-color: transparent;
-}
-
-.pagination > li > a,
-.pagination > li > span {
- background: var(--ots-surface-2);
- border: 1px solid var(--ots-border);
- color: var(--ots-text);
-}
-
-.pagination > li > a:hover,
-.pagination > li > span:hover {
- background: var(--ots-surface-3);
- color: var(--ots-primary);
-}
-
-.pagination > .active > a,
-.pagination > .active > span {
- background: var(--ots-primary);
- border-color: var(--ots-primary-2);
- color: #0b1020;
-}
-
-/* =============================================================================
- MODALS
- ============================================================================= */
-
-/* --- Content wrapper --- */
-.modal-content {
- border-radius: var(--ots-radius-lg);
- background-color: var(--modal-bg, var(--ots-surface)) !important;
- color: var(--modal-body-text, var(--ots-text)) !important;
- border: 1px solid var(--modal-border, var(--ots-border)) !important;
- box-shadow: var(--modal-shadow, var(--ots-shadow-lg)) !important;
- overflow: hidden;
-}
-
-/* --- Transparent parents --- */
-.modal,
-.modal-header,
-.modal-body,
-.modal-footer {
- color: var(--modal-body-text, var(--ots-text)) !important;
-}
-
-/* --- Header --- */
-.modal-header {
- background-color: var(--modal-header-bg, var(--ots-surface)) !important;
- border-bottom: 1px solid var(--modal-header-border, var(--ots-border)) !important;
- padding: 16px 20px !important;
-}
-
-.modal-title,
-.modal-header h4,
-.modal-header h5 {
- color: var(--modal-header-text, var(--ots-text)) !important;
- font-weight: 600;
-}
-
-/* --- Body --- */
-.modal-body {
- background-color: var(--modal-body-bg, var(--ots-surface)) !important;
- color: var(--modal-body-text, var(--ots-text)) !important;
- padding: 20px !important;
-}
-
-/* --- Backdrop --- */
-.modal-backdrop,
-.modal-backdrop.show,
-.modal-backdrop.in {
- background-color: var(--modal-backdrop-bg, rgba(0, 0, 0, 0.3)) !important;
- backdrop-filter: blur(var(--modal-backdrop-blur, 4px)) !important;
- -webkit-backdrop-filter: blur(var(--modal-backdrop-blur, 4px)) !important;
- opacity: 1 !important;
-}
-
-/* --- Footer --- */
-.modal-footer {
- background-color: var(--modal-footer-bg, transparent) !important;
- border-top: 1px solid var(--modal-footer-border, var(--ots-border)) !important;
- padding: 12px 20px !important;
-}
-
-/* Footer buttons — secondary / cancel */
-.modal-footer .btn,
-.modal-footer button {
- background: var(--modal-body-bg, var(--ots-surface-3)) !important;
- color: var(--modal-body-text, var(--ots-text)) !important;
- border: 1px solid var(--modal-border, var(--ots-border)) !important;
- box-shadow: none !important;
- border-radius: var(--ots-radius-sm) !important;
- transition: background var(--ots-transition),
- color var(--ots-transition),
- border-color var(--ots-transition);
-}
-
-.modal-footer .btn:hover,
-.modal-footer button:hover {
- background: rgba(var(--ots-primary-rgb), 0.08) !important;
- color: var(--ots-primary) !important;
- border-color: var(--ots-primary) !important;
-}
-
-/* Footer buttons — primary / submit */
-.modal-footer .btn.btn-primary,
-.modal-footer button.btn-primary {
- background: var(--ots-primary) !important;
- color: #0b1020 !important;
- border-color: var(--ots-primary-2) !important;
- font-weight: 600;
-}
-
-.modal-footer .btn.btn-primary:hover,
-.modal-footer button.btn-primary:hover {
- background: var(--ots-primary-2) !important;
- color: #ffffff !important;
-}
-
-/* Footer buttons — danger */
-.modal-footer .btn.btn-danger {
- background: var(--ots-danger) !important;
- color: #ffffff !important;
- border-color: var(--ots-danger) !important;
-}
-
-/* --- Form controls inside modals --- */
-.modal-body .form-control,
-.modal-body input[type="text"],
-.modal-body input[type="number"],
-.modal-body input[type="email"],
-.modal-body input[type="password"],
-.modal-body textarea,
-.modal-body select {
- background-color: var(--modal-input-bg, var(--ots-bg)) !important;
- border: 1px solid var(--modal-input-border, var(--ots-border)) !important;
- border-radius: var(--ots-radius-sm) !important;
- color: var(--modal-input-text, var(--ots-text)) !important;
-}
-
-.modal-body .form-control:focus,
-.modal-body input:focus,
-.modal-body textarea:focus,
-.modal-body select:focus {
- border-color: var(--modal-input-focus-border, var(--ots-primary)) !important;
- box-shadow: 0 0 0 3px var(--modal-input-focus-ring, rgba(var(--ots-primary-rgb), 0.2)) !important;
- outline: none !important;
-}
-
-/* --- Bootstrap Tagsinput / Tokenfield inside modals --- */
-.modal-body .bootstrap-tagsinput,
-.modal-body .tagsinput,
-.modal-body .tokenfield {
- background-color: var(--modal-input-bg, var(--ots-bg)) !important;
- border: 1px solid var(--modal-input-border, var(--ots-border)) !important;
- border-radius: var(--ots-radius-sm) !important;
- color: var(--modal-input-text, var(--ots-text)) !important;
- min-height: 36px;
- padding: 4px 8px !important;
- box-shadow: none !important;
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- gap: 4px;
-}
-
-.modal-body .bootstrap-tagsinput:focus-within,
-.modal-body .tagsinput:focus-within,
-.modal-body .tokenfield:focus-within {
- border-color: var(--modal-input-focus-border, var(--ots-primary)) !important;
- box-shadow: 0 0 0 3px var(--modal-input-focus-ring, rgba(var(--ots-primary-rgb), 0.2)) !important;
-}
-
-.modal-body .bootstrap-tagsinput input,
-.modal-body .tagsinput input,
-.modal-body .tokenfield input.token-input {
- background: transparent !important;
- color: var(--modal-input-text, var(--ots-text)) !important;
- border: none !important;
- box-shadow: none !important;
- outline: none !important;
- margin: 0 !important;
- padding: 2px 4px !important;
-}
-
-.modal-body .bootstrap-tagsinput input::placeholder,
-.modal-body .tagsinput input::placeholder,
-.modal-body .tokenfield input.token-input::placeholder {
- color: var(--ots-text-faint, #7f8aa3) !important;
-}
-
-.modal-body .bootstrap-tagsinput .tag,
-.modal-body .bootstrap-tagsinput .badge,
-.modal-body .tagsinput .tag,
-.modal-body .tokenfield .token {
- background: rgba(var(--ots-primary-rgb), 0.18) !important;
- border: 1px solid rgba(var(--ots-primary-rgb), 0.35) !important;
- color: var(--ots-primary, #e87800) !important;
- border-radius: 999px !important;
- padding: 2px 8px !important;
- font-size: 0.8rem;
- line-height: 1.5;
-}
-
-.modal-body .bootstrap-tagsinput .tag [data-role="remove"],
-.modal-body .bootstrap-tagsinput .badge [data-role="remove"],
-.modal-body .tokenfield .token .close {
- color: var(--ots-primary, #e87800) !important;
- opacity: 0.7;
- margin-left: 4px;
- cursor: pointer;
-}
-
-.modal-body .bootstrap-tagsinput .tag [data-role="remove"]:hover,
-.modal-body .bootstrap-tagsinput .badge [data-role="remove"]:hover,
-.modal-body .tokenfield .token .close:hover {
- opacity: 1;
-}
-
-/* Global bootstrap-tagsinput theming (outside modals too) */
-.bootstrap-tagsinput,
-.tagsinput,
-.tokenfield {
- background-color: var(--modal-input-bg, var(--ots-bg)) !important;
- border: 1px solid var(--modal-input-border, var(--ots-border)) !important;
- border-radius: var(--ots-radius-sm) !important;
- color: var(--modal-input-text, var(--ots-text)) !important;
- box-shadow: none !important;
-}
-
-.bootstrap-tagsinput input,
-.tagsinput input,
-.tokenfield input.token-input {
- background: transparent !important;
- color: var(--modal-input-text, var(--ots-text)) !important;
-}
-
-.bootstrap-tagsinput .tag,
-.bootstrap-tagsinput .badge,
-.tagsinput .tag,
-.tokenfield .token {
- background: rgba(var(--ots-primary-rgb), 0.18) !important;
- border: 1px solid rgba(var(--ots-primary-rgb), 0.35) !important;
- color: var(--ots-primary, #e87800) !important;
- border-radius: 999px !important;
-}
-
-/* --- Close button --- */
-.modal-header .close,
-.modal-header [data-dismiss="modal"] {
- color: var(--modal-close-color, var(--ots-text-muted)) !important;
- opacity: 1 !important;
- text-shadow: none !important;
-}
-
-.modal-header .close:hover,
-.modal-header [data-dismiss="modal"]:hover {
- color: var(--modal-close-hover, var(--ots-text)) !important;
-}
-
-/* =============================================================================
- HELP PANE / MISC
- ============================================================================= */
-
-#help-pane {
- position: fixed;
- bottom: 20px;
- right: 20px;
- z-index: 10000;
- display: flex;
- flex-direction: column;
- align-items: flex-end;
- gap: 12px;
-}
-
-#help-pane .help-pane-container {
- position: relative;
- width: 400px;
- flex-direction: column;
- align-items: flex-start;
- border-radius: 4px;
- border: 1px solid var(--ots-border);
- background: var(--ots-surface-2);
- overflow: hidden;
- max-height: calc(100vh - 100px);
- overflow-y: auto;
-}
-
-#help-pane .help-pane-btn {
- display: flex;
- justify-content: center;
- align-items: center;
- flex-shrink: 0;
- width: 48px;
- height: 48px;
- border-radius: 50px;
- background: var(--ots-primary);
- color: #0b1020;
- cursor: pointer;
-}
-
-#help-pane .help-pane-btn:hover {
- background: var(--ots-primary-2);
-}
-
-#help-pane .help-pane-btn i {
- font-size: 24px;
- color: #fff;
-}
-
-/* =============================================================================
- OTS DASHBOARD MESSAGE
- ============================================================================= */
-
-.ots-dashboard-message {
- margin: 16px 0 24px;
- padding: 12px 16px;
- border-radius: var(--ots-radius-md);
- background: rgba(var(--ots-primary-rgb), 0.16);
- border: 1px solid rgba(var(--ots-primary-rgb), 0.45);
- color: var(--ots-text);
-}
-
-.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(--ots-text-muted);
-}
-
-/* =============================================================================
- LOGIN / SIGN-IN PAGE
- Styles to match the requested sign-in card: centered panel, dark glass
- surface, orange accent, soft shadow and modern inputs.
- ============================================================================= */
-
-:root {
- --login-accent: #e87800;
- --login-panel-bg: var(--ots-surface-2);
-}
-
-body.login, body.login-page, .xibo-login, #login, .login-wrapper {
- min-height: 100vh;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 40px 20px;
- background: var(--ots-bg);
-}
-
-body.login-page .container {
- width: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- gap: 16px;
-}
-
-.login-card,
-.login-panel,
-.auth-card,
-.xibo-login-box,
-#login-box {
- width: 100%;
- max-width: 520px;
- border-radius: 12px;
- padding: 36px 40px 34px;
- background: var(--ots-surface-2);
- border: 1px solid var(--ots-border);
- box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35);
- color: var(--ots-text);
-}
-
-.login-card .login-logo,
-.login-panel .login-logo {
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 18px;
-}
-
-.login-card .login-logo .logo-icon,
-.login-panel .login-logo .logo-icon {
- width: 92px;
- height: 92px;
- border-radius: 10px;
- background: var(--login-accent);
- display: inline-flex;
- align-items: center;
- justify-content: center;
- box-shadow: 0 6px 18px rgba(0,0,0,0.45);
-}
-
-/* Brand text next to logo on login */
-.login-brand {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- gap: 10px;
- margin-bottom: 18px;
-}
-
-.login-brand .login-logo {
- width: 72px;
- height: 72px;
- display: inline-block;
-}
-
-.login-brand-text {
- color: var(--ots-text);
- font-size: 1.2rem;
- font-weight: 600;
- letter-spacing: 0.02em;
-}
-
-.login-card h1,
-.login-panel h1 {
- text-align: center;
- margin: 8px 0 6px 0;
- font-size: 28px;
- font-weight: 700;
-}
-
-.login-card .lead,
-.login-panel .lead {
- text-align: center;
- color: rgba(226,232,240,0.74);
- margin-bottom: 18px;
- font-size: 0.95rem;
-}
-
-.login-card .form-group,
-.login-panel .form-group {
- margin-bottom: 14px;
-}
-
-.login-card input[type="text"],
-.login-card input[type="email"],
-.login-card input[type="password"],
-.login-card .form-control,
-.login-panel input[type="text"],
-.login-panel input[type="email"],
-.login-panel input[type="password"] {
- width: 100%;
- background: rgba(11, 18, 33, 0.65);
- border: 1px solid rgba(148, 163, 184, 0.18);
- color: var(--ots-text);
- padding: 12px 14px;
- border-radius: 10px;
- font-size: 0.98rem;
- line-height: 1.25;
- transition: border-color 180ms ease, box-shadow 180ms ease, background 180ms ease;
-}
-
-.login-card input:focus,
-.login-panel input:focus,
-.login-card .form-control:focus {
- outline: none;
- border-color: rgba(255,138,0,0.85);
- background: rgba(11, 18, 33, 0.75);
- box-shadow: 0 10px 26px rgba(0,0,0,0.38), 0 0 0 5px rgba(255,138,0,0.08);
-}
-
-.login-card input::placeholder,
-.login-panel input::placeholder {
- color: rgba(255,255,255,0.58);
-}
-
-.login-card input + input,
-.login-card input + .form-control,
-.login-panel input + input {
- margin-top: 10px;
-}
-
-.login-card .form-control[disabled],
-.login-card input[disabled] {
- opacity: 0.7;
-}
-
-.login-card .btn-signin,
-.login-panel .btn-signin,
-.login-card .btn-primary.login,
-.login-panel .btn-primary.login {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- gap: 8px;
- width: 100%;
- padding: 10px 14px;
- background: #f8fafc;
- color: #0b1221 !important;
- border-radius: 10px;
- border: 1px solid rgba(255,255,255,0.8);
- font-weight: 600;
- box-shadow: 0 10px 22px rgba(2,6,23,0.35);
- transition: background 160ms ease, border-color 160ms ease, color 160ms ease, box-shadow 160ms ease, transform 160ms ease;
-}
-
-.login-card .btn-signin .icon,
-.login-panel .btn-signin .icon {
- display: inline-flex;
- align-items: center;
- justify-content: center;
- width: 18px;
- height: 18px;
-}
-
-.login-card .btn-signin:hover,
-.login-panel .btn-signin:hover {
- background: #ffffff;
- border-color: rgba(255,255,255,0.95);
- transform: translateY(-1px);
-}
-
-.login-card .btn-signin:focus,
-.login-panel .btn-signin:focus {
- outline: none;
- box-shadow: 0 10px 24px rgba(0,0,0,0.32), 0 0 0 5px rgba(255,138,0,0.18);
- border-color: rgba(255,138,0,0.45);
-}
-
-.login-card .forgot-link,
-.login-panel .forgot-link {
- display: block;
- text-align: right;
- margin-top: 8px;
- color: var(--ots-text-muted);
-}
-
-/* Small screens: compress card padding */
-@media (max-width: 520px) {
- .login-card, .login-panel { padding: 24px; border-radius: 8px; }
- .login-card .login-logo .logo-icon { width: 72px; height: 72px; }
-}
-
-/* Static orange accent bar — brand anchor at the bottom of the login page */
-body.login-page::after {
- content: '';
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- height: 3px;
- background: var(--login-accent);
- z-index: 10;
-}
-
-/* Bring the login card above the background */
-.login-card,
-.login-panel,
-.auth-card,
-.xibo-login-box,
-#login-box {
- position: relative;
- z-index: 2;
-
-
-/* EXTRA DEFENSIVE: ensure no white background shows through on long pages */
-html, body, #page-wrapper, .ots-shell, .ots-main, #content-wrapper, .content-wrapper, .ots-content, .page-content, .container, .container-fluid, .dashboard-page, .dashboard, .dashboard-card, .content-card, .page {
- background-color: var(--color-background) !important;
- background-image: none !important;
- background-repeat: no-repeat !important;
- color: var(--color-text-primary) !important;
- min-height: 100vh !important;
-}
-
-/* Neutralise any inline styles or late-loaded styles that set white backgrounds */
-*[style] {
- background-color: inherit !important;
-}
-
-/* Provide a small utility to detect offending elements visually (useful while debugging) */
-body.debug-white-areas * {
- outline: 1px solid rgba(255,0,0,0.04) !important;
-}
-
-/* Strong fallback for modals/backdrops */
-.modal-backdrop, .modal, .modal-open, .ots-footer, .page-footer {
- background-color: var(--color-background) !important;
-}
-
-/* Ensure the root html background is also forced dark at the highest level */
-html[style], body[style] {
- background-color: var(--color-background) !important;
-}
-
-/* =============================================================================
- OTS UPLOAD MODAL – Dark-mode refinements
- Supplements override-styles.twig which uses CSS variables for auto theming.
- These rules guarantee the upload modal stays dark when override-dark.css loads.
- ============================================================================= */
-.ots-upload-content {
- background: var(--ots-surface, #141c2b);
- border-color: var(--ots-border, #2c3a54);
-}
-.ots-upload-header {
- background: var(--ots-bg, #0b111a);
- border-bottom-color: var(--ots-border, #2c3a54);
-}
-.ots-upload-title {
- color: var(--ots-text, #e6eefb);
-}
-.ots-upload-body {
- background: var(--ots-surface, #141c2b);
- color: var(--ots-text, #e6eefb);
-}
-.ots-upload-dropzone {
- border-color: var(--ots-border, #2c3a54);
- background: rgba(232,120,0,0.03);
-}
-.ots-upload-dropzone:hover,
-.ots-upload-dropzone:focus-visible {
- border-color: var(--ots-primary, #e87800);
- background: rgba(232,120,0,0.07);
-}
-.ots-upload-dropzone--over {
- border-color: var(--ots-primary, #e87800) !important;
- background: rgba(232,120,0,0.12) !important;
-}
-.ots-upload-file-item {
- background: var(--ots-bg, #0b111a);
- border-color: var(--ots-border-soft, #243047);
-}
-.ots-upload-file-name {
- color: var(--ots-text, #e6eefb);
-}
-.ots-upload-file-meta {
- color: var(--ots-text-muted, #a9b6cc);
-}
-.ots-upload-footer {
- background: var(--ots-bg, #0b111a);
- border-top-color: var(--ots-border, #2c3a54);
-}
-.ots-upload-btn-cancel {
- color: var(--ots-text-muted, #a9b6cc);
- border-color: var(--ots-border, #2c3a54);
-}
-.ots-upload-btn-cancel:hover {
- background: rgba(255,255,255,0.06);
- color: var(--ots-text, #e6eefb);
-}
-.ots-upload-option {
- background: rgba(232,120,0,0.04);
- border-color: rgba(232,120,0,0.08);
- color: var(--ots-text, #e6eefb);
-}
-.ots-upload-option small {
- color: var(--ots-text-muted, #a9b6cc);
-}
diff --git a/ots-signs/css/override.css b/ots-signs/css/override.css
index 9258133..0d94891 100644
--- a/ots-signs/css/override.css
+++ b/ots-signs/css/override.css
@@ -1,7470 +1,64 @@
-/* ============================================================================
- XIBO CMS MODERN THEME - OTS Signs
- Dark Mode Override - Component Styling
- ============================================================================ */
+.well {
-/* Force dark mode */
-:root {
- --color-primary: #e87800;
- --ots-primary-rgb: 232, 120, 0;
- --color-primary-dark: #c46500;
- --color-primary-light: #ff9e20;
- --color-primary-lighter: #fff0d9;
- --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: 8px;
- --ots-sidebar-item-height: 44px;
- --ots-sidebar-item-padding-x: 12px;
- --ots-sidebar-content-gap: 12px;
-
- /* ── DataTable component tokens ── */
- --dt-header-bg: rgba(15, 23, 42, 0.92);
- --dt-header-text: #94a3b8;
- --dt-header-border: rgba(148, 163, 184, 0.18);
- --dt-row-bg: rgba(15, 23, 42, 0.7);
- --dt-row-alt-bg: rgba(30, 41, 59, 0.75);
- --dt-row-hover-bg: rgba(var(--ots-primary-rgb), 0.10);
- --dt-row-selected-bg: rgba(16, 185, 129, 0.20);
- --dt-border: rgba(148, 163, 184, 0.12);
- --dt-empty-icon-color: #475569;
- --dt-empty-text-color: #64748b;
-
- /* ── Pagination tokens ── */
- --dt-page-bg: transparent;
- --dt-page-text: #94a3b8;
- --dt-page-hover-bg: rgba(var(--ots-primary-rgb), 0.12);
- --dt-page-hover-text: var(--color-primary-light);
- --dt-page-active-bg: var(--color-primary);
- --dt-page-active-text: #ffffff;
- --dt-page-disabled-text: #334155;
- --dt-page-radius: 8px;
-
- /* ── Status badge tokens ── */
- --badge-success-bg: rgba(16, 185, 129, 0.15);
- --badge-success-text: #34d399;
- --badge-warning-bg: rgba(245, 158, 11, 0.15);
- --badge-warning-text: #fbbf24;
- --badge-danger-bg: rgba(239, 68, 68, 0.15);
- --badge-danger-text: #f87171;
- --badge-info-bg: rgba(14, 165, 233, 0.15);
- --badge-info-text: #38bdf8;
- --badge-neutral-bg: rgba(148, 163, 184, 0.12);
- --badge-neutral-text: #94a3b8;
-
- /* ── Dashboard stat tile tokens ── */
- --stat-tile-bg: var(--color-surface);
- --stat-tile-border: var(--color-border);
- --stat-tile-number-color: var(--color-text-primary);
- --stat-tile-label-color: var(--color-text-tertiary);
- --stat-tile-icon-color: var(--color-primary);
- --stat-tile-hover-border: rgba(var(--ots-primary-rgb), 0.4);
- --stat-tile-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
-
- /* ── FullCalendar override tokens ── */
- --fc-bg: var(--color-surface);
- --fc-border: var(--color-border);
- --fc-today-bg: rgba(var(--ots-primary-rgb), 0.08);
- --fc-event-text: #ffffff;
- --fc-toolbar-btn-bg: var(--color-surface-elevated);
- --fc-toolbar-btn-text: var(--color-text-primary);
- --fc-toolbar-btn-hover-bg: rgba(var(--ots-primary-rgb), 0.12);
- --fc-toolbar-btn-active-bg: var(--color-primary);
- --fc-toolbar-btn-active-text: #ffffff;
- --fc-day-header-text: var(--color-text-secondary);
- --fc-day-number-text: var(--color-text-tertiary);
-
- /* Editor (playlist / layout timeline) */
- --editor-modal-bg: #1a1a2e;
- --editor-modal-content-bg: #1e293b;
- --editor-modal-header-bg: #0f172a;
- --editor-modal-header-text: #f1f5f9;
-
- /* Modal pop-ups (Bootstrap / Bootbox) */
- --modal-backdrop-bg: rgba(2, 6, 23, 0.55);
- --modal-backdrop-blur: 6px;
- --modal-bg: #141c2b;
- --modal-border: #2c3a54;
- --modal-radius: 12px;
- --modal-shadow: 0 24px 64px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(255, 255, 255, 0.04);
- --modal-header-bg: #0f172a;
- --modal-header-border: #2c3a54;
- --modal-header-text: #f1f5f9;
- --modal-body-bg: #141c2b;
- --modal-body-text: #e2e8f0;
- --modal-footer-bg: #0f172a;
- --modal-footer-border: #2c3a54;
- --modal-close-color: #64748b;
- --modal-close-hover: #f1f5f9;
- --modal-input-bg: #0b111a;
- --modal-input-border: #2c3a54;
- --modal-input-text: #e6eefb;
- --modal-input-focus-border: #e87800;
- --modal-input-focus-ring: rgba(var(--ots-primary-rgb), 0.2);
-
- --editor-body-bg: #1e293b;
- --editor-border: #334155;
- --editor-text: #e2e8f0;
- --editor-text-secondary: #94a3b8;
- --editor-toolbar-bg: #0f172a;
- --editor-toolbar-text: #e2e8f0;
- --editor-toolbar-pane-bg: #1e293b;
- --editor-toolbar-pane-text: #e2e8f0;
- --editor-footer-controls-bg: #0f172a;
- --editor-footer-info-bg: var(--color-primary);
- --editor-footer-text: #f1f5f9;
- --editor-widget-bg: #334155;
- --editor-widget-border: #475569;
- --editor-widget-text: #e2e8f0;
- --editor-widget-label-bg: #0f172a;
- --editor-widget-label-text: #94a3b8;
- --editor-widget-hover-bg: #3b4d6b;
- --editor-widget-selected-bg: #166534;
- --editor-widget-multi-bg: #c2410c;
- --editor-widget-multi-hover-bg: #ea580c;
- --editor-left-margin-bg: #0f172a;
- --editor-timegrid-line: #475569;
- --editor-timegrid-text: #64748b;
- --editor-timegrid-overlay: rgba(30, 41, 59, 0.7);
- --editor-timeline-bg: rgba(30, 41, 59, 0.65);
- --editor-scrollbar-track: #1e293b;
- --editor-scrollbar-thumb: #475569;
- --editor-scrollbar-thumb-hover: #64748b;
- --editor-properties-bg: #1e293b;
- --editor-properties-border: #166534;
- --editor-header-bg: #0f172a;
- --editor-back-btn-bg: #0f172a;
- --editor-back-btn-text: var(--color-primary-light);
-
- color-scheme: dark;
}
-html,
+/* dashboard.css */
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) */
+/*Top header*/
+.row.header {
-
-/* 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;
-}
-
-/* Ensure menus that are intentionally floated into `body` are visible
- (this targets only menus moved by our JS: `.ots-floating-menu` or
- `.dropdown-menu` marked with `data-ots-floating="1`). This avoids
- forcing visibility for all dropdowns. */
-.ots-floating-menu,
-.dropdown-menu[data-ots-floating="1"] {
- display: block !important;
- visibility: visible !important;
- opacity: 1 !important;
-}
-
-/* Elevated z-index for menus so they render above other panels */
-.ots-floating-menu, .dropdown-menu {
- z-index: 99999 !important;
-}
-
-/* Limit aggressive floating/menu overrides to explicit floating menus only.
- Avoid forcing `.dropdown-menu` to be `display:block`/`visibility:visible` so
- native dropdown behaviour (open/close) is preserved. */
-.ots-notif-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;
-}
-
-/* User menu positioning is handled by floatMenu() which adds .ots-floating-menu.
- Only apply fixed positioning when the menu is actively floating. */
-.ots-user-menu.ots-floating-menu {
- position: fixed !important;
- z-index: 2147483647 !important;
- transform: none !important;
- will-change: auto !important;
- pointer-events: auto !important;
-}
-
-/* The rowMenu th is the empty header for the per-row action dropdown.
- Keep it in flow so column count matches tbody, but make it minimal.
- The matching td (last-child) holds the action button and must stay visible.
- NOTE: No background set here — inherits from .ots-table-card .table thead th rules. */
-th.rowMenu {
- width: 40px !important;
- min-width: 40px !important;
- max-width: 40px !important;
- padding: 4px !important;
- text-align: center !important;
- box-sizing: border-box !important;
- border: none !important;
-}
-
-/* Style the action-button td to match the header width */
-table:has(th.rowMenu) > tbody > tr > td:last-child {
- width: 40px !important;
- min-width: 40px !important;
- max-width: 40px !important;
- padding: 4px !important;
- text-align: center !important;
- box-sizing: border-box !important;
- overflow: visible !important;
-}
-
-/* Ensure floating menu children aren't clipped (scoped to floated menus only) */
-.ots-floating-menu li,
-.ots-floating-menu > li > a,
-.ots-floating-menu > li > span,
-.ots-floating-menu ul,
-.ots-floating-menu div {
- overflow: visible !important;
-}
-
-/* Remove transforms inside floating menus that could create stacking context */
-.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(var(--ots-primary-rgb), 0.1) !important;
-}
-
-/* Light mode styles (applied when .ots-light-mode is on html or body) */
-html.ots-light-mode,
-body.ots-light-mode {
- --color-primary: #e87800;
- --ots-primary-rgb: 232, 120, 0;
- --color-primary-dark: #c46500;
- --color-primary-light: #ff9e20;
- --color-primary-lighter: #fff0d9;
- --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 core tokens — light mode overrides */
- --ots-bg: #f8fafc;
- --ots-surface: #ffffff;
- --ots-surface-2: #f1f5f9;
- --ots-surface-3: #e2e8f0;
- --ots-border: #e2e8f0;
- --ots-border-soft: #f1f5f9;
- --ots-text: #0f172a;
- --ots-text-muted: #475569;
- --ots-text-faint: #64748b;
- --ots-primary: #e87800;
- --ots-primary-2: #c46500;
- --ots-success: #059669;
- --ots-warning: #d97706;
- --ots-danger: #dc2626;
- --ots-info: #0284c7;
- --ots-shadow-lg: 0 14px 30px rgba(15, 23, 42, 0.12);
- --ots-shadow-md: 0 8px 18px rgba(15, 23, 42, 0.08);
- --ots-shadow-sm: 0 3px 8px rgba(15, 23, 42, 0.06);
-
- --ots-sidebar-bg: #f1f5f9;
- --ots-sidebar-header-bg: #f1f5f9;
- --ots-sidebar-border: #e2e8f0;
- --ots-sidebar-link: #334155;
- --ots-sidebar-link-hover-bg: rgba(var(--ots-primary-rgb), 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: 8px;
- --ots-sidebar-item-height: 44px;
- --ots-sidebar-item-padding-x: 12px;
-
- /* ── DataTable component tokens — light mode ── */
- --dt-header-bg: #f1f5f9;
- --dt-header-text: #475569;
- --dt-header-border: #e2e8f0;
- --dt-row-bg: #ffffff;
- --dt-row-alt-bg: #f8fafc;
- --dt-row-hover-bg: rgba(var(--ots-primary-rgb), 0.06);
- --dt-row-selected-bg: rgba(16, 185, 129, 0.12);
- --dt-border: #e2e8f0;
- --dt-empty-icon-color: #94a3b8;
- --dt-empty-text-color: #64748b;
-
- /* ── Pagination tokens — light mode ── */
- --dt-page-bg: transparent;
- --dt-page-text: #475569;
- --dt-page-hover-bg: rgba(var(--ots-primary-rgb), 0.08);
- --dt-page-hover-text: var(--color-primary-dark);
- --dt-page-active-bg: var(--color-primary);
- --dt-page-active-text: #ffffff;
- --dt-page-disabled-text: #cbd5e1;
- --dt-page-radius: 8px;
-
- /* ── Status badge tokens — light mode ── */
- --badge-success-bg: rgba(5, 150, 105, 0.10);
- --badge-success-text: #059669;
- --badge-warning-bg: rgba(217, 119, 6, 0.10);
- --badge-warning-text: #b45309;
- --badge-danger-bg: rgba(220, 38, 38, 0.10);
- --badge-danger-text: #dc2626;
- --badge-info-bg: rgba(2, 132, 199, 0.10);
- --badge-info-text: #0284c7;
- --badge-neutral-bg: rgba(100, 116, 139, 0.08);
- --badge-neutral-text: #64748b;
-
- /* ── Dashboard stat tile tokens — light mode ── */
- --stat-tile-bg: #ffffff;
- --stat-tile-border: #e2e8f0;
- --stat-tile-number-color: #0f172a;
- --stat-tile-label-color: #64748b;
- --stat-tile-icon-color: var(--color-primary);
- --stat-tile-hover-border: rgba(var(--ots-primary-rgb), 0.35);
- --stat-tile-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
-
- /* ── FullCalendar override tokens — light mode ── */
- --fc-bg: #ffffff;
- --fc-border: #e2e8f0;
- --fc-today-bg: rgba(var(--ots-primary-rgb), 0.05);
- --fc-event-text: #ffffff;
- --fc-toolbar-btn-bg: #f1f5f9;
- --fc-toolbar-btn-text: #334155;
- --fc-toolbar-btn-hover-bg: rgba(var(--ots-primary-rgb), 0.08);
- --fc-toolbar-btn-active-bg: var(--color-primary);
- --fc-toolbar-btn-active-text: #ffffff;
- --fc-day-header-text: #475569;
- --fc-day-number-text: #64748b;
-
- /* Editor (playlist / layout timeline) */
- --editor-modal-bg: #e8e8e8;
- --editor-modal-content-bg: #ffffff;
- --editor-modal-header-bg: #f1f5f9;
- --editor-modal-header-text: #0f172a;
-
- /* Modal pop-ups (Bootstrap / Bootbox) — light mode */
- --modal-backdrop-bg: rgba(15, 23, 42, 0.25);
- --modal-backdrop-blur: 6px;
- --modal-bg: #ffffff;
- --modal-border: #e2e8f0;
- --modal-radius: 12px;
- --modal-shadow: 0 24px 64px rgba(15, 23, 42, 0.14), 0 0 0 1px rgba(0, 0, 0, 0.04);
- --modal-header-bg: #f8fafc;
- --modal-header-border: #e2e8f0;
- --modal-header-text: #0f172a;
- --modal-body-bg: #ffffff;
- --modal-body-text: #334155;
- --modal-footer-bg: #f8fafc;
- --modal-footer-border: #e2e8f0;
- --modal-close-color: #94a3b8;
- --modal-close-hover: #0f172a;
- --modal-input-bg: #f8fafc;
- --modal-input-border: #e2e8f0;
- --modal-input-text: #0f172a;
- --modal-input-focus-border: #e87800;
- --modal-input-focus-ring: rgba(var(--ots-primary-rgb), 0.18);
-
- --editor-body-bg: #ffffff;
- --editor-border: #e2e8f0;
- --editor-text: #0f172a;
- --editor-text-secondary: #475569;
- --editor-toolbar-bg: #1e3a5f;
- --editor-toolbar-text: #f1f5f9;
- --editor-toolbar-pane-bg: #f3f8ff;
- --editor-toolbar-pane-text: #1775f6;
- --editor-footer-controls-bg: #0e4694;
- --editor-footer-info-bg: var(--color-primary);
- --editor-footer-text: #fcfcfc;
- --editor-widget-bg: #e8f1fe;
- --editor-widget-border: #0e4694;
- --editor-widget-text: #121a5e;
- --editor-widget-label-bg: transparent;
- --editor-widget-label-text: #f3f8ff;
- --editor-widget-hover-bg: #d4e4f7;
- --editor-widget-selected-bg: #6ec071;
- --editor-widget-multi-bg: #eb7857;
- --editor-widget-multi-hover-bg: #f09a82;
- --editor-left-margin-bg: #e9e9e9;
- --editor-timegrid-line: #cecece;
- --editor-timegrid-text: #898989;
- --editor-timegrid-overlay: rgba(255, 255, 255, 0.7);
- --editor-timeline-bg: rgba(255, 255, 255, 0.65);
- --editor-scrollbar-track: #f3f8ff;
- --editor-scrollbar-thumb: #0e4694;
- --editor-scrollbar-thumb-hover: #1264d6;
- --editor-properties-bg: #f3f8ff;
- --editor-properties-border: #6ec071;
- --editor-header-bg: #f1f5f9;
- --editor-back-btn-bg: #1e3a5f;
- --editor-back-btn-text: #ffffff;
-
- background-color: var(--color-background);
- color: var(--color-text-primary);
-}
-
-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(var(--ots-primary-rgb), 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(var(--ots-primary-rgb), 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(var(--ots-primary-rgb), 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;
-}
-
-/* Light-mode collapsed flyout panel */
-body.ots-light-mode .ots-sidebar.collapsed .sidebar-submenu {
- background: #ffffff !important;
- border-color: #e2e8f0 !important;
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12) !important;
-}
-
-body.ots-light-mode .ots-sidebar.collapsed .sidebar-submenu .sidebar-list > a {
- color: #334155 !important;
- background: transparent !important;
- border-left: none !important;
-}
-
-body.ots-light-mode .ots-sidebar.collapsed .sidebar-submenu .sidebar-list > a:hover {
- background: rgba(var(--ots-primary-rgb), 0.1) !important;
- color: #c46500 !important;
-}
-
-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(var(--ots-primary-rgb), 0.06);
- color: var(--ots-primary);
-}
-
-body.ots-light-mode .dashboard-card,
-body.ots-light-mode .content-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(var(--ots-primary-rgb), 0.1);
- color: var(--ots-primary);
-}
-
-body.ots-light-mode .ots-content {
- background-color: var(--color-background);
-}
-
-/* ============================================================================
- ACCESSIBILITY - Focus indicators for keyboard navigation
- ============================================================================ */
-
-*:focus-visible {
- outline: 2px solid var(--color-primary, #e87800);
- outline-offset: 2px;
-}
-
-.btn:focus-visible,
-.form-control:focus-visible,
-.form-select:focus-visible,
-.nav-link:focus-visible {
- outline: 2px solid var(--color-primary, #e87800);
- outline-offset: 2px;
- box-shadow: 0 0 0 3px rgba(var(--ots-primary-rgb), 0.25);
-}
-
-.ots-sidebar li a:focus-visible {
- outline: 2px solid var(--color-primary, #e87800);
- outline-offset: -2px;
- border-radius: 4px;
-}
-
-.sidebar-group-toggle:focus-visible {
- outline: 2px solid var(--color-primary, #e87800);
- outline-offset: -2px;
- border-radius: 4px;
-}
-
-.dropdown-item:focus-visible {
- outline: 2px solid var(--color-primary, #e87800);
- outline-offset: -2px;
- background-color: rgba(var(--ots-primary-rgb), 0.1);
-}
-
-table tbody tr:focus-within {
- outline: 1px solid var(--color-primary, #e87800);
- outline-offset: -1px;
-}
-
-/* ============================================================================
- 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,
-.content-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: max-content !important;
- min-width: var(--ots-sidebar-collapsed-width);
- max-width: 300px;
- height: 100vh;
- background-color: var(--ots-sidebar-bg) !important;
- padding: 0;
- display: flex;
- flex-direction: column;
- overflow-x: hidden;
- overflow-y: auto;
- z-index: 1200;
- transition: width 200ms ease;
-}
-
-.ots-sidebar .ots-nav-text,
-.ots-sidebar .sidebar-submenu .ots-nav-text {
- white-space: nowrap;
}
+/* Sidebar background color */
#sidebar-wrapper {
- background-color: var(--ots-sidebar-bg) !important;
-}
-
-.ots-main {
- flex: 1;
- display: flex;
- flex-direction: column;
- position: relative;
- margin-left: var(--ots-sidebar-actual-width, var(--ots-sidebar-width)) !important;
- width: calc(100vw - var(--ots-sidebar-actual-width, var(--ots-sidebar-width))) !important;
- max-width: calc(100vw - var(--ots-sidebar-actual-width, var(--ots-sidebar-width))) !important;
- transition: margin-left 200ms ease, width 200ms ease, max-width 200ms ease;
- overflow-x: hidden !important;
- box-sizing: border-box !important;
-}
-
-#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;
-}
-
-/* Sidebar mode only — #page-wrapper is absent in horizontal nav mode */
-#page-wrapper #content-wrapper {
- margin-left: var(--ots-sidebar-actual-width, var(--ots-sidebar-width)) !important;
- width: calc(100vw - var(--ots-sidebar-actual-width, var(--ots-sidebar-width))) !important;
- max-width: calc(100vw - var(--ots-sidebar-actual-width, var(--ots-sidebar-width))) !important;
- transition: margin-left 200ms ease, width 200ms ease, max-width 200ms ease;
- padding-left: var(--ots-sidebar-content-gap) !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;
-}
-
-/* Base styles for #content-wrapper in all modes */
-#content-wrapper {
- border-left: none !important;
- box-shadow: none !important;
- outline: none !important;
- overflow-x: hidden !important;
- box-sizing: border-box !important;
-}
-
-/* --- 14a. No-nav pages (layout designer, etc.) – remove sidebar spacing -- */
-#content-wrapper.no-nav {
- margin-left: 0 !important;
- width: 100% !important;
- max-width: 100% !important;
- padding: 0 !important;
-}
-
-#content-wrapper.no-nav .page-content {
- padding: 0 !important;
- margin: 0 !important;
-}
-
-#content-wrapper.no-nav .page-content .row {
- margin: 0 !important;
- padding: 0 !important;
-}
-
-#content-wrapper.no-nav .page-content [class*="col-"] {
- margin: 0 !important;
- padding: 0 !important;
-}
-
-/* --- 14b. Layout editor: reset OTS navbar styling so Xibo's bundled editor CSS
- controls the top bar appearance unimpeded. -------------------------------- */
-body.editor-opened .navbar,
-body.editor-opened .navbar-default,
-#layout-editor .navbar,
-#layout-editor .navbar-default {
- background: transparent !important;
- border: none !important;
- box-shadow: none !important;
-}
-
-/* --- 14c. Hide the page behind the editor (body class set by JS) --------- */
-body.ots-playlist-editor-active .ots-sidebar {
- visibility: hidden !important;
-}
-
-body.ots-playlist-editor-active .ots-topbar {
- visibility: hidden !important;
-}
-
-body.ots-playlist-editor-active .ots-page-actions {
- display: none !important;
-}
-
-body.ots-playlist-editor-active #help-pane {
- display: none !important;
-}
-
-body.ots-playlist-editor-active .page-content > .row > .col-sm-12 > *:not(#editor-container):not(#layout-editor):not(#playlist-editor):not(.loading-overlay) {
- display: none !important;
-}
-
-body.ots-playlist-editor-active #content-wrapper,
-body.ots-playlist-editor-active .ots-main {
- margin-left: 0 !important;
- width: 100% !important;
- max-width: 100% !important;
- padding: 0 !important;
- overflow: visible !important;
-}
-
-body.ots-playlist-editor-active .ots-content,
-body.ots-playlist-editor-active .page-content {
- padding-left: 0 !important;
- padding-right: 0 !important;
-}
-
-body.ots-playlist-editor-active .page-content .row,
-body.ots-playlist-editor-active .page-content [class*="col-"] {
- margin-left: 0 !important;
- margin-right: 0 !important;
- padding-left: 0 !important;
- padding-right: 0 !important;
-}
-
-/* Collapsed: shift content to match the narrow sidebar */
-body.ots-sidebar-collapsed .ots-main,
-body.ots-sidebar-collapsed #content-wrapper,
-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 var(--ots-sidebar-content-gap);
- overflow-y: auto;
- overflow-x: hidden !important;
- max-width: 100% !important;
- box-sizing: border-box !important;
-}
-
-/* Consistent left gap 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 {
- padding-left: var(--ots-sidebar-content-gap) !important;
-}
-
-.ots-main .page-content {
- padding-left: 0 !important;
-}
-
-.ots-main .ots-content {
- padding-left: var(--ots-sidebar-content-gap) !important;
-}
-
-/* Strongly enforce no left gap for content children (not #content-wrapper itself) */
-#content-wrapper .page-content,
-#content-wrapper .page-content .row,
-#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 — top-right cluster (bell + user icon)
- ============================================================================ */
-.ots-page-actions {
- position: absolute;
- top: 14px;
- right: 20px;
- z-index: 1100;
- display: flex;
- align-items: center;
- gap: 2px;
- background: var(--color-surface-elevated);
- border: 1px solid var(--color-border);
- border-radius: 8px;
- padding: 3px 4px;
- 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: 28px !important;
- height: 28px !important;
- padding: 0 !important;
- border-radius: 6px !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(var(--ots-primary-rgb), 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: 20px !important;
- height: 20px !important;
- border-radius: 50% !important;
- object-fit: cover !important;
- border: 1px 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(var(--ots-primary-rgb), 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);
-}
-
-/* ============================================================================
- USER MENU — standalone styles that apply whether the menu is inside
- .ots-page-actions or floated to
- {% trans "An" %} - Oribi Technology Services - {% trans "product." %} -
-{% trans "OTS Signs provides a compact, focused admin UI and proxy for Xibo CMS" %}
- - {% set appVersion = version|default("dev") %} - {% set appEnvironment = appEnvironment|default(environment|default("local")) %} - {% set commitSha = revision|default("") %} - - - -{% trans "OTS Signs provides a compact, focused interface for your digital signage network" %}
- - {% set appVersion = version|default("dev") %} - {% set appEnvironment = appEnvironment|default(environment|default("local")) %} - {% set commitSha = revision|default("") %} - - - -{% trans "Manage API applications and connectors." %}
-