diff --git a/CUSTOMIZATION.md b/CUSTOMIZATION.md
deleted file mode 100644
index f1ff402..0000000
--- a/CUSTOMIZATION.md
+++ /dev/null
@@ -1,361 +0,0 @@
-# Theme Customization Cookbook
-
-Quick recipes for common customization tasks in your Xibo CMS theme.
-
-## 1. Change Primary Brand Color
-
-**File:** `css/override.css`
-
-Find the `:root` selector and update:
-
-```css
-:root {
- --color-primary: #006bb3; /* Change from blue #2563eb to custom blue */
- --color-primary-dark: #004c80; /* Darker shade for hover/active states */
- --color-primary-light: #1a9ad1; /* Lighter shade for backgrounds */
- --color-primary-lighter: #d4e6f1; /* Very light for highlights */
-}
-```
-
-This single change affects:
-- Header bar background
-- Sidebar primary colors
-- Buttons, links, and focus states
-- Widget title bars
-
-## 2. Use a Custom Font
-
-**File:** `css/override.css`
-
-Replace the `--font-family-base` variable:
-
-```css
-:root {
- /* Option A: Google Font (add to
in Twig override) */
- --font-family-base: "Inter", "Segoe UI", sans-serif;
-
- /* Option B: Local font file */
- @font-face {
- font-family: "MyCustomFont";
- src: url('../fonts/my-font.woff2') format('woff2');
- }
- --font-family-base: "MyCustomFont", sans-serif;
-}
-```
-
-To use Google Fonts, add this line to a Twig template (e.g., in a view override):
-```html
-
-
-```
-
-## 3. Implement a Company Logo in Header
-
-**Files:** `css/override.css` (styling), `img/` (asset)
-
-1. Replace logo files in `custom/otssignange/img/`:
- - `xibologo.png` (header logo, ~40x40px)
- - `192x192.png` (app icon for app manifest)
- - `512x512.png` (splash/bookmarklet icon)
-
-2. If you need to style the logo more prominently, add to `override.css`:
-
-```css
-.navbar-brand {
- display: flex;
- align-items: center;
- gap: var(--space-2);
- padding-left: var(--space-4);
-}
-
-.navbar-brand img {
- height: 40px;
- width: auto;
-}
-```
-
-## 4. Darken the Sidebar
-
-**File:** `css/override.css`
-
-Update sidebar color tokens:
-
-```css
-:root {
- --color-surface: #2d3748; /* Darker gray instead of light */
- --color-text-primary: #ffffff; /* White text on dark background */
-}
-
-#sidebar-wrapper {
- background-color: #1a202c; /* Even darker for contrast */
-}
-
-ul.sidebar .sidebar-list a {
- color: #cbd5e1; /* Light gray text */
-}
-
-ul.sidebar .sidebar-list a:hover {
- background-color: #2d3748; /* Slightly lighter on hover */
- color: #ffffff;
-}
-```
-
-## 5. Increase Widget Spacing & Padding
-
-**File:** `css/override.css`
-
-Modify spacing tokens to make everything roomier:
-
-```css
-:root {
- /* Scale up all spacing */
- --space-4: 1.25rem; /* was 1rem (16px → 20px) */
- --space-6: 2rem; /* was 1.5rem (24px → 32px) */
- --space-8: 2.75rem; /* was 2rem (32px → 44px) */
-}
-
-.widget {
- padding: var(--space-8); /* Uses new token value */
-}
-```
-
-## 6. Remove Shadows (Flat Design)
-
-**File:** `css/override.css`
-
-Set all shadows to none:
-
-```css
-:root {
- --shadow-xs: none;
- --shadow-sm: none;
- --shadow-base: none;
- --shadow-md: none;
- --shadow-lg: none;
- --shadow-xl: none;
-}
-```
-
-## 7. Customize Button Styles
-
-**File:** `css/override.css`
-
-Make buttons larger with more rounded corners:
-
-```css
-button,
-.btn {
- padding: var(--space-4) var(--space-6); /* Increase from var(--space-3) var(--space-4) */
- border-radius: var(--radius-xl); /* Make more rounded */
- font-weight: var(--font-weight-semibold); /* Make text bolder */
- text-transform: uppercase; /* OPTIONAL: Uppercase labels */
- letter-spacing: 0.05em; /* OPTIONAL: Wider letter spacing */
-}
-```
-
-## 8. Force Light Mode (Disable Dark Mode)
-
-**File:** `css/override.css`
-
-Remove the dark mode media query or override it:
-
-```css
-/* Delete or comment out this section: */
-/*
-@media (prefers-color-scheme: dark) {
- :root { ... }
-}
-*/
-
-/* OR force light mode explicitly: */
-:root {
- color-scheme: light; /* Tells browser to not apply dark UI elements */
-}
-
-/* Force light colors even if system prefers dark */
-@media (prefers-color-scheme: dark) {
- :root {
- /* Keep all light mode values, don't override */
- }
-}
-```
-
-## 9. Add a Custom Alert Style
-
-**File:** `css/override.css`
-
-Append a new alert variant (e.g., for secondary notifications):
-
-```css
-.alert-secondary {
- background-color: #e2e8f0;
- border-color: #cbd5e1;
- color: #334155;
-}
-
-.alert-secondary a {
- color: #2563eb;
- font-weight: var(--font-weight-semibold);
-}
-```
-
-Use in Xibo: Apply `.alert alert-secondary` class to a notification element.
-
-## 10. Improve Form Focus States
-
-**File:** `css/override.css`
-
-Make focused form inputs more prominent:
-
-```css
-input[type="text"]:focus,
-input[type="email"]:focus,
-input[type="password"]:focus,
-textarea:focus,
-select:focus {
- outline: none;
- border-color: var(--color-primary);
- box-shadow: 0 0 0 4px var(--color-primary-lighter), /* Outer glow */
- 0 0 0 1px var(--color-primary); /* Inner border */
- background-color: #fafbff; /* Subtle highlight */
-}
-```
-
-## 11. Create a Compact Theme Variant
-
-**File:** `css/override.css`
-
-Add a utility class for a denser layout:
-
-```css
-.theme-compact {
- --space-4: 0.75rem;
- --space-6: 1rem;
- --font-size-base: 0.875rem; /* Slightly smaller text */
-}
-
-/* Apply to body or any container */
-body.theme-compact {
- /* All tokens inherit new values */
-}
-```
-
-Then toggle with a Twig override or JS:
-```javascript
-document.body.classList.toggle('theme-compact');
-```
-
-## 12. Modify Widget Title Bar Colors
-
-**File:** `css/override.css`
-
-Make widget titles more distinctive:
-
-```css
-.widget .widget-title {
- background: linear-gradient(135deg, var(--color-primary), var(--color-primary-dark));
- color: var(--color-text-inverse);
- text-transform: uppercase;
- letter-spacing: 0.05em;
- font-size: var(--font-size-sm);
- padding: var(--space-6);
- border-bottom: 2px solid var(--color-primary-dark);
-}
-```
-
-## 13. Style Table Headers Distinctly
-
-**File:** `css/override.css`
-
-Make tables look more modern:
-
-```css
-thead {
- background: linear-gradient(to bottom, var(--color-primary-lighter), var(--color-gray-100));
-}
-
-th {
- color: var(--color-primary);
- font-weight: var(--font-weight-bold);
- text-transform: uppercase;
- letter-spacing: 0.05em;
- font-size: var(--font-size-sm);
- padding: var(--space-6) var(--space-4);
- border-bottom: 2px solid var(--color-primary);
-}
-
-tbody tr:nth-child(odd) {
- background-color: var(--color-gray-50);
-}
-
-tbody tr:hover {
- background-color: var(--color-primary-lighter);
-}
-```
-
-## 14. Enable Full Dark Mode in Browser
-
-Some users may have `prefers-color-scheme: dark` set. To test locally:
-
-**Chrome DevTools:**
-1. Open DevTools (F12)
-2. Ctrl+Shift+P (or Cmd+Shift+P on Mac)
-3. Type "rendering"
-4. Select "Show Rendering"
-5. Scroll to "Prefers color scheme" and select "dark"
-6. Refresh page
-
-**Firefox:**
-1. about:config
-2. Search for `ui.systemUsesDarkTheme`
-3. Set to `1` for dark mode
-
-## 15. Add Custom Utility Classes
-
-**File:** `css/override.css`
-
-Extend the theme with custom utilities at the end:
-
-```css
-/* Custom utilities */
-.text-primary {
- color: var(--color-primary);
-}
-
-.bg-primary {
- background-color: var(--color-primary);
- color: var(--color-text-inverse);
-}
-
-.border-primary {
- border-color: var(--color-primary);
-}
-
-.opacity-50 {
- opacity: 0.5;
-}
-
-.cursor-pointer {
- cursor: pointer;
-}
-
-.no-wrap {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.flex-center {
- display: flex;
- align-items: center;
- justify-content: center;
-}
-```
-
----
-
-**Pro Tips:**
-- Always test changes in a staging Xibo instance before deploying to production
-- Use browser DevTools to inspect elements and live-edit CSS before making permanent changes
-- Keep a backup of your original CSS before making large modifications
-- Document any custom changes you make in comments within the CSS file for future reference
diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md
deleted file mode 100644
index 3780e3f..0000000
--- a/DEPLOYMENT.md
+++ /dev/null
@@ -1,175 +0,0 @@
-# Deployment Checklist & Quick Start
-
-## Pre-Deployment Checklist
-
-- [ ] Review the modern theme changes in [README.md](README.md)
-- [ ] Test CSS syntax validation (no errors reported)
-- [ ] Backup existing `custom/otssignange/css/override.css`
-- [ ] Verify asset paths (logos, preview images)
-- [ ] Check browser compatibility requirements
-- [ ] Test on your development Xibo instance first
-- [ ] Verify dark mode toggle if using system preference
-- [ ] Test responsive layout on mobile devices
-
-## Installation Steps
-
-### Option A: Direct File Copy
-
-```bash
-# Navigate to your Xibo installation root
-cd /path/to/xibo
-
-# Backup original theme files
-cp web/theme/custom/otssignange/css/override.css web/theme/custom/otssignange/css/override.css.backup
-cp web/theme/custom/otssignange/css/html-preview.css web/theme/custom/otssignange/css/html-preview.css.backup
-
-# Copy new theme files
-cp /Users/matt/dev/theme/custom/otssignange/css/override.css web/theme/custom/otssignange/css/
-cp /Users/matt/dev/theme/custom/otssignange/css/html-preview.css web/theme/custom/otssignange/css/
-cp /Users/matt/dev/theme/custom/otssignange/css/client.css web/theme/custom/otssignange/css/
-
-# Verify files copied
-ls -la web/theme/custom/otssignange/css/
-```
-
-### Option B: Using Git (if version-controlled)
-
-```bash
-cd /path/to/xibo
-git checkout web/theme/custom/otssignange/css/
-# Or manually merge your changes with the new files
-```
-
-## Post-Deployment Validation
-
-1. **Clear Xibo Cache** (if applicable):
- ```bash
- # Xibo may cache CSS—clear if using PHP APC or similar
- rm -rf web/uploads/temp/*
- ```
-
-2. **Verify in Browser**:
- - Open Xibo CMS admin interface
- - Inspect elements for CSS color changes
- - Check Network tab for CSS file loads (should see override.css)
- - Verify no CSS errors in browser console
-
-3. **Test Key Features**:
- - [ ] Login page displays correctly
- - [ ] Header bar shows primary color
- - [ ] Sidebar navigation is styled properly
- - [ ] Dashboard widgets render as cards with shadows
- - [ ] Links have correct color and hover state
- - [ ] Forms have proper focus states (blue outline)
- - [ ] Mobile layout: open DevTools (F12) and resize to <640px
- - [ ] Sidebar collapses into hamburger menu on mobile
- - [ ] Dark mode: open DevTools → Rendering → Prefers color scheme: dark
-
-4. **Check Asset Loading**:
- - Verify `xibologo.png` displays in header
- - Check preview splash screen background loads
- - Confirm favicon appears in browser tab
-
-## Rollback Plan
-
-If issues occur:
-
-```bash
-cd /path/to/xibo
-
-# Restore backup
-cp web/theme/custom/otssignange/css/override.css.backup web/theme/custom/otssignange/css/override.css
-cp web/theme/custom/otssignange/css/html-preview.css.backup web/theme/custom/otssignange/css/html-preview.css
-
-# Optional: Remove new client.css if causing issues
-rm web/theme/custom/otssignange/css/client.css
-
-# Clear cache
-rm -rf web/uploads/temp/*
-
-# Refresh browser (Ctrl+Shift+R for hard refresh)
-```
-
-## Browser Support
-
-### Fully Supported (CSS Variables)
-- Chrome/Edge 49+
-- Firefox 31+
-- Safari 9.1+
-- Opera 36+
-- Mobile browsers (iOS Safari 9.3+, Chrome Mobile 49+)
-
-### Partial Support (Fallbacks Recommended)
-- IE 11 and below: Not supported
-
-To add IE11 fallbacks, modify `override.css` (advanced):
-```css
-/* Fallback for older browsers */
-.widget {
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); /* IE fallback */
- box-shadow: var(--shadow-sm);
-}
-```
-
-## Performance Notes
-
-- **CSS File Size**: `override.css` is ~35KB (gzipped ~8KB)
-- **Variables**: 70+ CSS variables—negligible performance impact
-- **Dark Mode**: Uses `prefers-color-scheme` media query (no JavaScript required)
-- **Responsive**: Mobile-first approach—efficient layout recalculation
-
-## Next Steps
-
-1. **Optional Enhancements**:
- - Add SVG icon sprite to `img/` for consistent iconography
- - Create Twig view overrides for deeper layout customization
- - Implement user-controlled dark mode toggle
-
-2. **Documentation**:
- - See [CUSTOMIZATION.md](CUSTOMIZATION.md) for 15+ customization recipes
- - See [README.md](README.md) for full feature documentation
-
-3. **Testing in CI/CD**:
- - Add CSS linter (stylelint) to your build pipeline
- - Validate HTML/CSS in staging before production push
-
-## Support & Troubleshooting
-
-### Issue: CSS Not Loading
-**Solution**:
-- Hard refresh browser: Ctrl+Shift+R (Windows/Linux) or Cmd+Shift+R (Mac)
-- Check browser console for 404 errors on CSS files
-- Verify file permissions: `chmod 644 override.css`
-
-### Issue: Colors Look Wrong
-**Solution**:
-- Check if system dark mode is enabled (see Post-Deployment Validation)
-- Verify `--color-primary` value in `:root` matches intended brand color
-- Test in different browsers
-
-### Issue: Sidebar Doesn't Collapse on Mobile
-**Solution**:
-- Verify viewport meta tag is in Xibo's ``: ``
-- Check browser DevTools for responsive mode enabled
-- Ensure no custom CSS is overriding the media query
-
-### Issue: Fonts Not Loading
-**Solution**:
-- Verify system fonts are available (`-apple-system`, `Segoe UI`, etc.)
-- If using Google Fonts, check internet connectivity
-- Add font-family fallback: `-fallback-font, sans-serif`
-
----
-
-## Quick Links
-
-- [Theme README](README.md) — Feature overview and tokens reference
-- [Customization Cookbook](CUSTOMIZATION.md) — 15+ customization recipes
-- [Xibo Developer Docs](https://account.xibosignage.com/docs/developer/)
-- [Config Reference](custom/otssignange/config.php)
-
----
-
-**Version**: 1.0.0 (Modern)
-**Last Updated**: February 2026
-**Status**: Ready for Production
diff --git a/DESIGN_SYSTEM.md b/DESIGN_SYSTEM.md
deleted file mode 100644
index d4e78a3..0000000
--- a/DESIGN_SYSTEM.md
+++ /dev/null
@@ -1,391 +0,0 @@
-# Design System Reference Card
-
-A quick visual and technical reference for the OTS Signage Modern Theme.
-
-## 🎨 Color Palette
-
-### Brand Colors
-```
---color-primary #2563eb ████████████ Blue
---color-primary-dark #1d4ed8 ██████████ Darker Blue
---color-primary-light #3b82f6 ██████████████ Lighter Blue
---color-secondary #7c3aed ████████████ Purple
-```
-
-### Status Colors
-```
---color-success #10b981 ██████████ Green
---color-warning #f59e0b ██████████ Amber
---color-danger #ef4444 ██████████ Red
---color-info #0ea5e9 ██████████ Cyan
-```
-
-### Gray Scale (Neutral)
-```
-Level Color Hex Usage
-50 Very Light #f9fafb Backgrounds, light surfaces
-100 Light #f3f4f6 Hover states, borders
-200 Light Gray #e5e7eb Borders, dividers
-300 Gray #d1d5db Form inputs, disabled
-400 Gray #9ca3af Placeholder text
-500 Medium Gray #6b7280 Secondary text
-600 Dark Gray #4b5563 Body text, labels
-700 Darker Gray #374151 Headings
-800 Very Dark #1f2937 Primary text
-900 Darkest #111827 High contrast text
-```
-
-### Semantic Colors
-```
---color-background #ffffff (dark: #0f172a)
---color-surface #f9fafb (dark: #1e293b)
---color-surface-elevated #ffffff (dark: #334155)
---color-text-primary #1f2937 (dark: #f1f5f9)
---color-text-secondary #6b7280 (dark: #cbd5e1)
---color-text-tertiary #9ca3af (dark: #94a3b8)
---color-border #e5e7eb (dark: #475569)
-```
-
----
-
-## 📝 Typography Scale
-
-### Font Family
-```
---font-family-base: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif
---font-family-mono: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", Menlo, Courier, monospace
-```
-
-### Font Sizes
-```
-Size Pixels Usage
---font-size-xs 12px Small labels, badges, captions
---font-size-sm 14px Form hints, table cells, small text
---font-size-base 16px Body text, default size
---font-size-lg 18px Subheadings, callouts
---font-size-xl 20px Section headings
---font-size-2xl 24px Page headings
---font-size-3xl 30px Large headings
---font-size-4xl 36px Main titles
-```
-
-### Font Weights
-```
-Weight Value Usage
---font-weight-normal 400 Body text, regular content
---font-weight-medium 500 Form labels, emphasis
---font-weight-semibold 600 Headings, strong emphasis
---font-weight-bold 700 Major headings, highlights
-```
-
-### Line Heights
-```
-Height Value Usage
---line-height-tight 1.25 Tight headings
---line-height-snug 1.375 Subheadings
---line-height-normal 1.5 Default, body text
---line-height-relaxed 1.625 Large text blocks
---line-height-loose 2 Extra spacing
-```
-
----
-
-## 📏 Spacing Scale (8px base unit)
-
-```
-Token Pixels CSS Rem
---space-1 4px 0.25rem Tightest spacing
---space-2 8px 0.5rem Small padding
---space-3 12px 0.75rem Medium-small
---space-4 16px 1rem Standard padding
---space-5 20px 1.25rem Medium spacing
---space-6 24px 1.5rem Default margins
---space-7 28px 1.75rem Large spacing
---space-8 32px 2rem Section spacing
---space-10 40px 2.5rem Large spacing
---space-12 48px 3rem Very large
---space-16 64px 4rem Extra large
---space-20 80px 5rem Massive spacing
-```
-
-**Usage Example:**
-```css
-.widget {
- padding: var(--space-6); /* 24px all sides */
- margin-bottom: var(--space-8); /* 32px below */
- gap: var(--space-4); /* 16px between items */
-}
-```
-
----
-
-## 🎭 Shadows (Elevation System)
-
-```
-Level Shadow Usage
-none none No elevation
-xs 0 1px 2px 0 rgba(0, 0, 0, 0.05) Subtle depth
-sm 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 ... Small cards
-base 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px ... Default cards
-md 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px ... Medium elevation
-lg 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px ... Large hover
-xl 0 25px 50px -12px rgba(0, 0, 0, 0.25) Maximum depth
-```
-
----
-
-## 🔲 Border Radius
-
-```
-Token Pixels Usage
---radius-none 0px Sharp corners
---radius-sm 4px Minimal rounding
---radius-base 6px Default input fields
---radius-md 8px Standard components
---radius-lg 12px Cards, modals
---radius-xl 16px Large containers
---radius-2xl 24px Extra rounded
---radius-full 9999px Fully rounded (pills, circles)
-```
-
----
-
-## ⚡ Transitions
-
-```
-Token Duration Easing Usage
---transition-fast 150ms ease-in-out Hover, quick interactions
---transition-base 200ms ease-in-out Default, UI changes
---transition-slow 300ms ease-in-out Page transitions, major changes
-```
-
-**Usage:**
-```css
-a {
- transition: color var(--transition-fast);
-}
-
-.widget {
- transition: box-shadow var(--transition-base), transform var(--transition-base);
-}
-```
-
----
-
-## 📱 Responsive Breakpoints
-
-```
-Name Width Use Case
-sm 640px Mobile phones (landscape)
-md 768px Tablets
-lg 1024px Desktop screens
-xl 1280px Large desktops
-2xl 1536px Ultra-wide displays
-```
-
-**Usage Pattern (Mobile-First):**
-```css
-/* Mobile first (default) */
-.widget {
- grid-template-columns: 1fr;
-}
-
-/* Tablets and up */
-@media (min-width: 768px) {
- .widget {
- grid-template-columns: repeat(2, 1fr);
- }
-}
-
-/* Desktops and up */
-@media (min-width: 1024px) {
- .widget {
- grid-template-columns: repeat(3, 1fr);
- }
-}
-```
-
----
-
-## 🎯 Component Reference
-
-### Buttons
-```css
-.btn {
- padding: var(--space-3) var(--space-4); /* 12px × 16px */
- border-radius: var(--radius-md); /* 8px */
- font-weight: var(--font-weight-medium); /* 500 */
- font-size: var(--font-size-base); /* 16px */
-}
-
-.btn-primary {
- background: var(--color-primary); /* #2563eb */
- color: var(--color-text-inverse); /* White */
-}
-
-.btn-primary:hover {
- background: var(--color-primary-dark); /* #1d4ed8 */
-}
-```
-
-### Form Inputs
-```css
-input, textarea, select {
- background: var(--color-background); /* #ffffff */
- border: 1px solid var(--color-border); /* #e5e7eb */
- border-radius: var(--radius-md); /* 8px */
- padding: var(--space-3) var(--space-4); /* 12px × 16px */
- font-size: var(--font-size-base); /* 16px */
-}
-
-input:focus {
- border-color: var(--color-primary); /* #2563eb */
- box-shadow: 0 0 0 3px var(--color-primary-lighter);
-}
-```
-
-### Cards/Widgets
-```css
-.widget {
- background: var(--color-surface-elevated); /* #ffffff */
- border: 1px solid var(--color-border); /* #e5e7eb */
- border-radius: var(--radius-lg); /* 12px */
- box-shadow: var(--shadow-sm); /* Subtle depth */
- padding: var(--space-6); /* 24px */
-}
-
-.widget:hover {
- box-shadow: var(--shadow-base); /* More elevation */
- transform: translateY(-1px); /* Slight lift */
-}
-```
-
-### Alerts
-```css
-.alert {
- border-radius: var(--radius-md); /* 8px */
- padding: var(--space-4) var(--space-6); /* 16px × 24px */
- border-left: 4px solid var(--color-success);
-}
-```
-
----
-
-## 🌙 Dark Mode
-
-All colors automatically switch when `prefers-color-scheme: dark` is detected:
-
-```css
-@media (prefers-color-scheme: dark) {
- :root {
- --color-background: #0f172a; /* Deep navy */
- --color-surface: #1e293b; /* Slate */
- --color-text-primary: #f1f5f9; /* Near white */
- /* ... other dark mode overrides ... */
- }
-}
-```
-
-**Test in Browser DevTools:**
-1. F12 (Open DevTools)
-2. Ctrl+Shift+P (Search in Chrome)
-3. Type "rendering"
-4. Toggle "Prefers color scheme" to dark
-5. Page updates instantly
-
----
-
-## ♿ Accessibility
-
-### Color Contrast
-```
-Element Ratio WCAG Level
-Primary text on white 7:1 AAA
-Secondary text on white 4.5:1 AA
-Links on white 5:1 AA
-Buttons 4.5:1 AA
-```
-
-### Focus Indicators
-```css
-*:focus-visible {
- outline: 2px solid var(--color-primary); /* #2563eb */
- outline-offset: 2px;
-}
-```
-
-### Keyboard Navigation
-- All interactive elements are tab-accessible
-- Logical tab order maintained
-- No keyboard traps
-- Focus always visible
-
----
-
-## 🔧 Using CSS Variables
-
-### Override in Your Code
-```css
-/* In your custom CSS, you can override tokens: */
-:root {
- --color-primary: #006bb3; /* Your brand blue */
- --font-size-base: 18px; /* Larger default text */
-}
-
-/* All components using tokens will update automatically */
-```
-
-### Reference in Components
-```css
-.my-component {
- background: var(--color-surface);
- color: var(--color-text-primary);
- padding: var(--space-4);
- border-radius: var(--radius-md);
- box-shadow: var(--shadow-base);
-}
-```
-
-### With Fallbacks (IE11 compat, optional)
-```css
-.my-component {
- background: #f9fafb; /* Fallback */
- background: var(--color-surface); /* Modern */
-
- color: #1f2937; /* Fallback */
- color: var(--color-text-primary); /* Modern */
-}
-```
-
----
-
-## 📊 Quick Lookup Table
-
-| Need | Variable | Value |
-|------|----------|-------|
-| Brand color | `--color-primary` | #2563eb |
-| Button padding | `--space-3` + `--space-4` | 12px × 16px |
-| Card shadow | `--shadow-base` | 4px 6px -1px rgba... |
-| Body text | `--font-size-base` | 16px |
-| Heading | `--font-size-2xl` | 24px |
-| Default spacing | `--space-6` | 24px |
-| Card radius | `--radius-lg` | 12px |
-| Focus outline | `--color-primary` | #2563eb |
-| Dark background | --color-surface (dark mode) | #1e293b |
-
----
-
-## 🎓 Pro Tips
-
-1. **Always use variables** — Don't hardcode colors or sizes
-2. **Spacing is 8px-based** — Use `--space-*` for consistency
-3. **Test dark mode** — Use DevTools (see above)
-4. **Mobile-first queries** — Styles default to mobile, expand on larger screens
-5. **Focus states matter** — Never remove `outline` without adding alternative
-6. **Semantic colors** — Use `--color-surface` instead of hardcoding #ffffff
-
----
-
-**Last Updated**: February 2026
-**Theme Version**: 1.0.0 (Modern)
-**Xibo Compatibility**: 3.x+
diff --git a/IMPLEMENTATION_COMPLETE.md b/IMPLEMENTATION_COMPLETE.md
deleted file mode 100644
index 301b0ef..0000000
--- a/IMPLEMENTATION_COMPLETE.md
+++ /dev/null
@@ -1,307 +0,0 @@
-# Implementation Summary: OTS Signs Xibo Theme Redesign
-
-## ✅ Complete Implementation
-
-Your custom Xibo CMS theme has been fully redesigned and modernized to match the screenshots you provided. All major views and components have been replaced with a contemporary dark-themed UI.
-
----
-
-## 📋 What Was Changed
-
-### **View Files (5 files updated)**
-
-| File | Changes |
-|------|---------|
-| `authed.twig` | Modern shell layout with fixed sidebar (250px) + main area. SVG icons in topbar, responsive hamburger menu, user avatar dropdown |
-| `authed-sidebar.twig` | Reorganized navigation with section dividers, SVG icons for all menu items, user profile card at bottom |
-| `dashboard.twig` | 3-column KPI card grid (Displays, Schedules, Users), status panels, quick action grid with 3 action cards |
-| `displays.twig` | Two-column layout: left folder tree with 6 folder items, right content with search bar, stat boxes, modern data table |
-| `media.twig` | Two-column layout: left folder tree, right media grid with 4 sample images, storage stats, media type badges |
-
-### **CSS Styling (override.css - ~1,050 lines)**
-
-**Dark theme colors:**
-- Background: `#0f172a` (dark navy)
-- Surface: `#1e293b` (slate)
-- Elevated: `#334155` (darker slate)
-- Primary: `#3b82f6` (bright blue)
-- Text: `#f1f5f9` (off-white)
-
-**Component system:**
-- ✅ Sidebar (fixed, collapsible on mobile)
-- ✅ Topbar (search, notifications, user menu)
-- ✅ KPI cards (3-column grid, hover effects)
-- ✅ Badges (success, danger, info, secondary)
-- ✅ Panels (full-width and half-width)
-- ✅ Tables (striped, hover states)
-- ✅ Media grid (3-column, responsive)
-- ✅ Buttons (primary, outline, small, ghost)
-- ✅ Forms (search input styling)
-- ✅ Responsive layout (768px breakpoint)
-
-### **JavaScript (theme.js - ~120 lines)**
-
-- Sidebar toggle on mobile
-- Dropdown menu interactions
-- Search focus states
-- Folder item selection feedback
-- Mobile viewport detection
-- Click-outside-to-close menus
-
----
-
-## 🎯 Key Visual Changes
-
-### **Before → After**
-
-| Element | Before | After |
-|---------|--------|-------|
-| **Background** | Light white | Dark navy (#0f172a) |
-| **Sidebar** | Icon emoji (📊🖥📁) | SVG icons + proper hierarchy |
-| **Dashboard KPI** | Simple text cards | Large numbered cards with gradients |
-| **Tables** | Basic Bootstrap | Modern dark tables with hover states |
-| **Buttons** | Basic styling | Modern gradient primary, outline variants |
-| **Media Items** | Text list | Image thumbnail grid with badges |
-| **Navigation** | Flat list | Organized sections with dividers |
-
----
-
-## 📁 Files Modified
-
-```
-custom/otssignange/
-├── config.php ..................... (unchanged - already correct)
-├── css/
-│ ├── override.css ............... ✅ REPLACED (1,050 lines dark theme)
-│ ├── client.css ................. (unchanged)
-│ └── html-preview.css ........... (unchanged)
-├── js/
-│ └── theme.js ................... ✅ UPDATED (interactivity)
-└── views/
- ├── authed.twig ................ ✅ REPLACED (shell + topbar)
- ├── authed-sidebar.twig ........ ✅ REPLACED (nav sidebar)
- ├── dashboard.twig ............. ✅ REPLACED (KPI cards)
- ├── displays.twig .............. ✅ REPLACED (two-column)
- ├── media.twig ................. ✅ REPLACED (media grid)
- ├── index.html ................. (unchanged)
- └── layouts/ ................... (inherited from Xibo)
-```
-
----
-
-## 🚀 Next Steps
-
-### 1. **Deploy to Xibo CMS**
-
-If you have Xibo installed locally:
-
-```bash
-# Copy theme to Xibo installation
-cp -r /path/to/otssignstheme/custom/otssignange /path/to/xibo-cms/web/theme/custom/
-
-# Clear cache in Xibo admin UI:
-# Settings → Maintenance → Purge Cache
-```
-
-### 2. **Enable Theme in Xibo**
-
-1. Log in to Xibo CMS admin
-2. Go to **Settings → Preferences → Themes**
-3. Select **"OTS Signs"** from dropdown
-4. Click **Save**
-5. Refresh browser
-
-### 3. **Test Pages**
-
-After enabling, verify these pages render correctly:
-
-- [ ] **Dashboard** - KPI cards should display (3 columns)
-- [ ] **Displays** - Folder tree on left, table on right
-- [ ] **Media Library** - Folder tree, image grid with thumbnails
-- [ ] **Sidebar** - Toggle on mobile (<768px)
-- [ ] **Topbar** - Search, notifications, user menu
-- [ ] **Responsive** - Test on mobile/tablet view
-
-### 4. **Customize (Optional)**
-
-Edit `/custom/otssignange/css/override.css`:
-
-**Change primary color (line ~19):**
-```css
---color-primary: #3b82f6; /* Change to #8b5cf6 for purple, etc. */
-```
-
-**Change sidebar width (line ~58):**
-```css
-width: 250px; /* Change to 280px, 300px, etc. */
-```
-
-**Add company logo (views/authed-sidebar.twig, line ~7):**
-Replace `🎯` with:
-```twig
-
-```
-
----
-
-## 🎨 Design Highlights
-
-### **Color Palette**
-```
-Primary Blue: #3b82f6 (accents, buttons, hover states)
-Success Green: #10b981 (online status badges)
-Danger Red: #ef4444 (offline status, alerts)
-Warning Orange: #f59e0b (warnings)
-Info Cyan: #0ea5e9 (information)
-Background: #0f172a (main background)
-Surface: #1e293b (cards, panels)
-Text Primary: #f1f5f9 (headings, main text)
-Text Secondary: #cbd5e1 (descriptions, labels)
-```
-
-### **Typography**
-- Font: System fonts (-apple-system, BlinkMacSystemFont, Segoe UI, Roboto)
-- Sizes: 12px (xs) → 36px (4xl)
-- Weights: 400 (normal) → 700 (bold)
-- Line heights: 1.25 (tight) → 2 (loose)
-
-### **Spacing**
-- 8px base unit
-- Padding: 8px, 12px, 16px, 20px, 24px, 32px
-- Gaps: 12px, 16px, 20px, 24px, 32px
-- Margins: Based on spacing scale
-
-### **Rounded Corners**
-- Buttons/inputs: 6px
-- Cards: 8px
-- Badges: 4px
-- Full: 9999px (circles)
-
-### **Shadows**
-- Hover cards: `0 4px 12px rgba(0, 0, 0, 0.15)`
-- Dropdowns: `0 20px 25px -5px rgba(0, 0, 0, 0.1)`
-- Large modals: `0 25px 50px -12px rgba(0, 0, 0, 0.25)`
-
----
-
-## 🔧 Technical Details
-
-### **CSS Architecture**
-- **Design tokens:** 50+ CSS variables
-- **Component system:** Sidebar, topbar, KPI, panel, badge, button, table, media
-- **Responsive:** Mobile-first, 768px breakpoint
-- **Accessibility:** Proper focus states, contrast ratios (WCAG AA)
-
-### **JavaScript Features**
-- ES6 IIFE module pattern
-- Event delegation
-- localStorage for state
-- Mobile viewport detection
-- No external dependencies
-
-### **Browser Support**
-- ✅ Chrome/Edge (latest 2 versions)
-- ✅ Firefox (latest 2 versions)
-- ✅ Safari (latest 2 versions)
-- ❌ IE11 (CSS Grid not supported)
-
----
-
-## 📊 Size & Performance
-
-- **CSS:** ~8 KB (override.css)
-- **JavaScript:** ~3 KB (theme.js)
-- **Total impact:** ~11 KB additional
-- **Load time:** <500ms on typical connection
-- **Lighthouse:** 85+ score (with optimized images)
-
----
-
-## 🐛 Troubleshooting
-
-### Sidebar toggle not working
-→ Check browser console (F12) for JavaScript errors
-→ Ensure `theme.js` is loading from: `/theme/custom/otssignange/js/theme.js`
-
-### Dark theme not applying
-→ Clear Xibo cache: Settings → Maintenance → Purge Cache
-→ Clear browser cache: Ctrl+Shift+Delete (Windows) / Cmd+Shift+Delete (Mac)
-
-### Images in media grid not showing
-→ Check image URLs are accessible
-→ Verify image permissions (644)
-→ Test with different image formats (JPEG, PNG, GIF)
-
-### Search bar styling broken
-→ Verify CSS file loaded: check Network tab (F12)
-→ Check CSS file size (~8 KB)
-→ Look for parse errors in Console (F12)
-
----
-
-## 📚 Documentation
-
-Complete documentation available in:
-- **[THEME_IMPLEMENTATION.md](./THEME_IMPLEMENTATION.md)** - Full feature guide, customization, troubleshooting
-- **[config.php](./custom/otssignange/config.php)** - Theme registration
-- **Individual view files** - Twig comments explaining structure
-
----
-
-## ✨ What Makes This Theme Great
-
-✅ **Pixel-perfect match** to your screenshots
-✅ **Fully responsive** from mobile to 4K
-✅ **Modern dark theme** with professional color palette
-✅ **SVG icons** for crisp appearance at any size
-✅ **Smooth animations** and transitions
-✅ **Keyboard accessible** navigation
-✅ **Mobile-optimized** sidebar and menus
-✅ **Zero external dependencies** (pure CSS/JS)
-✅ **Well-commented code** for easy maintenance
-✅ **Design token system** for quick customization
-
----
-
-## 🎓 Learning Resources
-
-**If you want to modify the theme further:**
-
-1. **CSS Variables:** Start with `:root` block in override.css (lines 1-25)
-2. **Component classes:** Follow `.ots-` naming in CSS
-3. **Twig syntax:** Check `views/*.twig` files for template structure
-4. **SVG icons:** Edit SVG directly in Twig files or replace with icon font
-5. **JavaScript:** Modify `js/theme.js` for new interactions
-
----
-
-## 🎁 Deliverables Checklist
-
-- ✅ Dashboard page redesigned (KPI cards, panels, quick actions)
-- ✅ Displays page redesigned (folder tree, table, search)
-- ✅ Media Library page redesigned (media grid, thumbnails)
-- ✅ Sidebar navigation modernized (SVG icons, sections)
-- ✅ Topbar created (search, notifications, user menu)
-- ✅ Dark theme applied (colors, contrast, shadows)
-- ✅ Responsive design (mobile sidebar, flexible layouts)
-- ✅ Interactive components (toggles, dropdowns, focus states)
-- ✅ Documentation (README, comments, customization guide)
-- ✅ Zero breaking changes (Xibo integration intact)
-
----
-
-## 📞 Support
-
-If you encounter issues:
-
-1. **Check console errors:** F12 → Console tab
-2. **Review Network tab:** F12 → Network tab (all resources loading?)
-3. **Test in incognito:** Browser incognito mode (clear caching)
-4. **Verify file paths:** All CSS/JS paths relative to baseUrl
-5. **Contact Xibo community:** https://community.xibo.org.uk/
-
----
-
-**Theme implementation complete!** 🎉
-
-Your OTS Signs theme is ready for deployment. All views match your screenshots with a modern dark interface, responsive design, and interactive components.
diff --git a/INDEX.md b/INDEX.md
deleted file mode 100644
index bed3938..0000000
--- a/INDEX.md
+++ /dev/null
@@ -1,267 +0,0 @@
-# OTS Signage Modern Theme - Complete Package
-
-Welcome! Your Xibo CMS theme has been fully modernized. This file is your starting point.
-
-## 📚 Documentation Index
-
-Start here based on what you need:
-
-### 🚀 First Time? Start Here
-**→ [SUMMARY.md](SUMMARY.md)** — 5 min read
-- High-level overview of what was implemented
-- Before/after comparison
-- Quick start (3 steps to deploy)
-- What's next suggestions
-
-### 🎨 Want to Customize?
-**→ [CUSTOMIZATION.md](CUSTOMIZATION.md)** — Browse as needed
-- 15 ready-made customization recipes
-- Change colors, fonts, spacing, etc.
-- Code examples for each task
-- Advanced tips and tricks
-
-### 📦 Ready to Deploy?
-**→ [DEPLOYMENT.md](DEPLOYMENT.md)** — Follow step-by-step
-- Pre-deployment checklist
-- Installation instructions (3 methods)
-- Post-deployment validation
-- Troubleshooting guide
-- Rollback procedure
-
-### 📖 Full Documentation
-**→ [README.md](README.md)** — Complete reference
-- Feature documentation
-- Design tokens reference
-- File structure
-- Accessibility checklist
-- Browser compatibility
-
----
-
-## 📁 Your Theme Structure
-
-```
-theme/ (Root)
-├── SUMMARY.md ← START HERE (high-level overview)
-├── README.md ← Full feature documentation
-├── CUSTOMIZATION.md ← Customization recipes (15+)
-├── DEPLOYMENT.md ← Deployment & troubleshooting
-├── INDEX.md ← This file
-└── custom/otssignange/
- ├── config.php (Theme configuration—unchanged)
- ├── css/
- │ ├── override.css ✨ MODERNIZED (800 lines)
- │ ├── html-preview.css ✨ UPDATED (gradient background)
- │ └── client.css ✨ NEW (widget styling)
- ├── img/ (Logo assets)
- ├── layouts/ (Layout templates)
- └── views/ (Twig overrides—empty, ready for custom)
-```
-
----
-
-## 🎯 What Was Delivered
-
-### ✅ Design System
-- **70+ CSS Variables** — Colors, typography, spacing, shadows, transitions
-- **Dark Mode** — Automatic via system preference
-- **Responsive Layout** — Mobile-first, 5 breakpoints
-- **Accessibility** — WCAG AA color contrast, focus states, keyboard nav
-
-### ✅ Modern Components
-- Header/navbar with brand color
-- Sidebar navigation with collapse on mobile
-- Card-based widgets with shadows and hover effects
-- Form controls with focus rings
-- Button variants (primary, secondary, success, danger)
-- Alerts/notifications (4 status types)
-- Tables with hover states
-
-### ✅ Documentation
-- **4 comprehensive guides** (README, Customization, Deployment, Summary)
-- **15+ customization recipes** with code examples
-- **Complete API reference** for CSS variables
-- **Deployment checklist** with validation steps
-- **Troubleshooting guide** for common issues
-
----
-
-## 🚀 Quick Start (3 Steps)
-
-### Step 1: Review Changes
-```bash
-# Look at what changed
-ls -la custom/otssignange/css/
-```
-Output: `override.css` (800 lines), `html-preview.css` (updated), `client.css` (new)
-
-### Step 2: Backup & Deploy
-```bash
-# Backup original
-cp custom/otssignange/css/override.css custom/otssignange/css/override.css.backup
-
-# Copy to your Xibo installation
-cp custom/otssignange/css/* /path/to/xibo/web/theme/custom/otssignange/css/
-```
-
-### Step 3: Test
-1. Hard refresh browser: Ctrl+Shift+R (or Cmd+Shift+R on Mac)
-2. Log into Xibo CMS
-3. Verify header, sidebar, and widgets show new styling
-4. Test on mobile: Resize to <640px or use device
-
-✅ Done! Your CMS looks modern now.
-
----
-
-## 🎨 Popular Customizations
-
-Want to make it your own? Here are 3 easiest changes:
-
-### 1. Change Brand Color (5 min)
-Edit `custom/otssignange/css/override.css`:
-```css
-:root {
- --color-primary: #006bb3; /* Your color here */
- --color-primary-dark: #004c80; /* Darker version */
- --color-primary-light: #1a9ad1; /* Lighter version */
-}
-```
-
-### 2. Update Logo (2 min)
-Replace these files in `custom/otssignange/img/`:
-- `xibologo.png` (header logo)
-- `192x192.png` (app icon)
-- `512x512.png` (splash icon)
-
-### 3. Change Font (5 min)
-Edit `custom/otssignange/css/override.css`:
-```css
-:root {
- --font-family-base: "Your Font", sans-serif;
-}
-```
-
-**→ See [CUSTOMIZATION.md](CUSTOMIZATION.md) for 12+ more recipes!**
-
----
-
-## 📊 What's Different
-
-| Feature | Before | After |
-|---------|--------|-------|
-| CSS Architecture | Empty hooks | Full token system |
-| Colors | Hardcoded | 70+ CSS variables |
-| Dark Mode | ❌ None | ✅ Full system support |
-| Responsive | Basic | ✅ Mobile-first |
-| Components | Minimal | ✅ Complete design system |
-| Accessibility | Basic | ✅ WCAG AA compliant |
-| Documentation | Minimal | ✅ 4 complete guides |
-
----
-
-## 🔧 Technical Details
-
-### Files Modified/Created
-- **override.css** — Rewritten (50 → 800 lines)
-- **html-preview.css** — Updated with gradient
-- **client.css** — New file for widget styling
-
-### CSS Features Used
-- CSS Variables (Custom Properties)
-- Media Queries (responsive, dark mode)
-- Flexbox & Grid layouts
-- Focus-visible for accessibility
-- prefers-color-scheme for dark mode
-
-### Browser Support
-✅ All modern browsers (Chrome, Firefox, Safari, Edge, Mobile)
-⚠️ IE 11 and below: Not supported (CSS variables required)
-
----
-
-## 📋 Next Steps
-
-### Today: Deploy & Test
-1. Read [SUMMARY.md](SUMMARY.md) (5 min overview)
-2. Follow [DEPLOYMENT.md](DEPLOYMENT.md) (step-by-step)
-3. Test on mobile and desktop
-
-### This Week: Customize
-1. Browse [CUSTOMIZATION.md](CUSTOMIZATION.md) recipes
-2. Try 1–2 customizations
-3. Share with your team
-
-### This Month: Enhance
-1. Add SVG icons to `custom/otssignange/img/`
-2. Create Twig view overrides for advanced layout changes
-3. Implement user-controlled dark mode toggle
-
----
-
-## 💬 FAQ
-
-**Q: Will this work with my Xibo version?**
-A: Yes, tested on Xibo 3.x+. CSS-first approach means fewer compatibility issues.
-
-**Q: Do I need to modify any PHP code?**
-A: No. All changes are CSS-based. `config.php` is unchanged.
-
-**Q: Can I still upgrade Xibo?**
-A: Yes! CSS overrides are upgrade-safe. Just re-deploy the theme files after upgrades.
-
-**Q: How do I test dark mode?**
-A: Open DevTools (F12) → Rendering → Prefers color scheme: dark
-
-**Q: What if something breaks?**
-A: See [DEPLOYMENT.md](DEPLOYMENT.md) Rollback section. Takes 2 minutes.
-
----
-
-## 📞 Support Resources
-
-- **Customization Help**: [CUSTOMIZATION.md](CUSTOMIZATION.md) — 15+ recipes
-- **Deployment Help**: [DEPLOYMENT.md](DEPLOYMENT.md) — Troubleshooting guide
-- **Feature Reference**: [README.md](README.md) — Complete documentation
-- **Xibo Official Docs**: [account.xibosignage.com/docs/](https://account.xibosignage.com/docs/)
-
----
-
-## ✅ Quality Checklist
-
-- [x] CSS syntax validated (no errors)
-- [x] Design tokens comprehensive (70+ variables)
-- [x] Dark mode fully working
-- [x] Responsive on all devices
-- [x] WCAG AA accessible
-- [x] Documentation complete
-- [x] Customization examples provided
-- [x] Deployment steps clear
-- [x] Rollback procedure documented
-- [x] Production ready
-
----
-
-## 📝 Version & License
-
-- **Theme**: OTS Signage (Modern)
-- **Version**: 1.0.0
-- **Status**: ✅ Production Ready
-- **License**: AGPLv3 (per Xibo requirements)
-- **Compatibility**: Xibo CMS 3.x+
-
----
-
-## 🎉 You're All Set!
-
-Your Xibo CMS now has a modern, professional theme with a complete design system.
-
-**Next action**: Read [SUMMARY.md](SUMMARY.md) (5 min) → Deploy (10 min) → Celebrate! 🚀
-
----
-
-**Questions?** Check the guides above. Most answers are in [CUSTOMIZATION.md](CUSTOMIZATION.md) or [DEPLOYMENT.md](DEPLOYMENT.md).
-
-**Ready to go live?** See [DEPLOYMENT.md](DEPLOYMENT.md) for step-by-step instructions.
-
-**Want to customize?** See [CUSTOMIZATION.md](CUSTOMIZATION.md) for 15+ ready-made recipes.
diff --git a/QUICK_REFERENCE.md b/QUICK_REFERENCE.md
deleted file mode 100644
index 6e1e997..0000000
--- a/QUICK_REFERENCE.md
+++ /dev/null
@@ -1,262 +0,0 @@
-# OTS Signs Xibo Theme - Quick Reference Card
-
-## 🚀 Quick Start (2 minutes)
-
-### Step 1: Deploy Theme
-```bash
-# Copy to your Xibo installation (if you have it)
-cp -r ~/dev/otssignstheme/custom/otssignange /path/to/xibo-cms/web/theme/custom/
-```
-
-### Step 2: Enable in Xibo
-1. Login to Xibo CMS
-2. Settings → Preferences → Themes
-3. Select "OTS Signs"
-4. Click Save
-5. Refresh page
-
-### Step 3: Verify
-- Dashboard shows 3 KPI cards (Displays, Schedules, Users)
-- Sidebar has organized menu sections
-- Dark theme applied (navy background)
-- Mobile sidebar toggle works on narrow screens
-
----
-
-## 📂 File Map
-
-| Path | Size | Purpose |
-|------|------|---------|
-| `css/override.css` | 20 KB | Dark theme + all components |
-| `js/theme.js` | 4.6 KB | Sidebar toggle, dropdowns |
-| `views/authed.twig` | 3.4 KB | Main layout shell |
-| `views/authed-sidebar.twig` | 5.9 KB | Left navigation sidebar |
-| `views/dashboard.twig` | 4.9 KB | Dashboard page |
-| `views/displays.twig` | 5.1 KB | Displays management |
-| `views/media.twig` | 5.2 KB | Media library |
-
----
-
-## 🎨 Color Reference
-
-```
---color-primary: #3b82f6 Blue (buttons, accents)
---color-background: #0f172a Navy (main background)
---color-surface: #1e293b Slate (cards)
---color-surface-elevated: #334155 Darker slate (headers)
---color-text-primary: #f1f5f9 Off-white (text)
---color-text-secondary: #cbd5e1 Gray (labels)
---color-success: #10b981 Green (online status)
---color-danger: #ef4444 Red (offline status)
-```
-
----
-
-## 🔧 Quick Customization
-
-### Change Primary Color
-**File:** `css/override.css` (line ~19)
-```css
---color-primary: #3b82f6; /* Change me! */
---color-primary-dark: #1d4ed8;
---color-primary-light: #60a5fa;
-```
-
-**Suggested colors:**
-- Purple: `#8b5cf6` / `#7c3aed` / `#6d28d9`
-- Red: `#ef4444` / `#dc2626` / `#b91c1c`
-- Green: `#10b981` / `#059669` / `#047857`
-- Orange: `#f97316` / `#ea580c` / `#c2410c`
-
-### Change Sidebar Width
-**File:** `css/override.css` (line ~58)
-```css
-.ots-sidebar {
- width: 250px; /* Change to 280px, 300px, etc. */
-}
-.ots-main {
- margin-left: 250px; /* Must match sidebar width */
-}
-```
-
-### Add Company Logo
-**File:** `views/authed-sidebar.twig` (line ~7)
-```twig
-
-🎯
-
-
-
-```
-
----
-
-## ✅ Component Classes
-
-### Layout
-- `.ots-shell` - Main wrapper
-- `.ots-sidebar` - Left navigation
-- `.ots-topbar` - Top header
-- `.ots-content` - Main content area
-- `.ots-footer` - Footer
-
-### Dashboard
-- `.kpi-section` - KPI cards container
-- `.kpi-card` - Single KPI card
-- `.dashboard-panels` - Panel grid
-- `.panel` - Card component
-- `.action-cards` - Quick actions grid
-
-### Displays/Media
-- `.two-column-layout` - Layout wrapper
-- `.left-panel` - Sidebar panel
-- `.content-panel` - Main content
-- `.folder-tree` - Folder list
-- `.media-grid` - Image grid
-
-### Common
-- `.btn`, `.btn-primary`, `.btn-outline`, `.btn-sm`
-- `.badge`, `.badge-success`, `.badge-danger`
-- `.table`, `.table-striped`
-- `.text-muted`, `.text-xs`
-
----
-
-## 🐛 Common Issues
-
-| Issue | Solution |
-|-------|----------|
-| Dark theme not showing | Clear cache: Settings → Maintenance → Purge Cache |
-| Sidebar toggle not working | Check browser console (F12) for errors |
-| Images not showing in media grid | Verify image URLs are accessible, check permissions |
-| Mobile sidebar stuck off-screen | Test in new browser tab, clear localStorage |
-| CSS not loading | Check file exists at `web/theme/custom/otssignange/css/override.css` |
-
----
-
-## 📱 Responsive Breakpoints
-
-```css
-Mobile: max-width: 640px
-Tablet: 641px - 768px
-Desktop: 769px+
-
-Key behavior:
-- Sidebar: hidden/drawer on mobile, fixed on desktop
-- Topbar: flex-column on mobile, flex-row on desktop
-- Grids: 1 column on mobile, 2+ columns on desktop
-```
-
----
-
-## 🎯 CSS Variables Quick Edit
-
-**File:** `css/override.css` top section
-
-Change any of these to customize the entire theme:
-
-```css
---color-primary: #3b82f6; /* Primary brand color */
---color-background: #0f172a; /* Main background */
---color-surface: #1e293b; /* Card background */
---color-border: #475569; /* Divider lines */
---color-text-primary: #f1f5f9; /* Main text */
---color-text-secondary: #cbd5e1; /* Secondary text */
---color-text-tertiary: #94a3b8; /* Muted text */
-```
-
----
-
-## 🔗 Important Paths
-
-Relative to Xibo root:
-
-```
-/web/theme/custom/otssignange/
-├── config.php
-├── css/override.css ← Main styling
-├── js/theme.js ← Interactions
-└── views/
- ├── authed.twig ← Main shell
- ├── authed-sidebar.twig ← Sidebar nav
- ├── dashboard.twig
- ├── displays.twig
- └── media.twig
-```
-
----
-
-## 📊 File Sizes
-
-- `override.css`: 20 KB
-- `theme.js`: 4.6 KB
-- `authed.twig`: 3.4 KB
-- `authed-sidebar.twig`: 5.9 KB
-- `dashboard.twig`: 4.9 KB
-- `displays.twig`: 5.1 KB
-- `media.twig`: 5.2 KB
-
-**Total theme size:** ~49 KB
-
----
-
-## 🎓 Code Examples
-
-### Use in Twig
-```twig
-
-
-
-
-Add Display
-
-
-Online
-```
-
-### CSS Variables in Custom Styles
-```css
-.my-component {
- background: var(--color-surface);
- color: var(--color-text-primary);
- border: 1px solid var(--color-border);
- border-radius: var(--radius-md);
- padding: var(--space-4);
- transition: all var(--transition-base);
-}
-```
-
----
-
-## 🚨 Before Modifying
-
-1. **Backup original:** `cp override.css override.css.backup`
-2. **Test locally:** Use browser DevTools to test changes
-3. **Clear cache:** After any CSS/JS change, purge Xibo cache
-4. **Check mobile:** Test responsive changes at 375px width
-
----
-
-## 📞 Need Help?
-
-Check these files in order:
-
-1. `IMPLEMENTATION_COMPLETE.md` - What was changed
-2. `THEME_IMPLEMENTATION.md` - Full documentation
-3. `views/authed.twig` - Template structure
-4. `css/override.css` - Component styling
-5. `js/theme.js` - Interactivity
-
----
-
-**Last Updated:** February 4, 2026
-**Theme Version:** 1.0.0
-**Xibo Compatibility:** v4.0+
diff --git a/README.md b/README.md
deleted file mode 100644
index 5897d58..0000000
--- a/README.md
+++ /dev/null
@@ -1,266 +0,0 @@
-# OTS Signage - Modern Xibo CMS Theme
-
-A modernized theme for Xibo CMS that brings contemporary UI/UX patterns, improved accessibility, and a comprehensive design token system.
-
-## What's New
-
-### 🎨 Design Tokens System
-- **Color palette**: 10 semantic colors + 9-step gray scale with light/dark mode support
-- **Typography**: System font stack, 8-step type scale, 5 font weights
-- **Spacing**: 8px-based scale (0–80px) for consistent margins and padding
-- **Elevation**: Shadow system with 6 levels for depth perception
-- **Radius**: Border radius scale from sharp to full-rounded
-- **Transitions**: Predefined animation durations for consistency
-
-### 🌙 Dark Mode Support
-- Automatic dark mode via `prefers-color-scheme` media query
-- Token overrides for dark theme built-in
-- No additional JavaScript required for system preference
-
-### 📱 Responsive Layout
-- Mobile-first responsive grid system
-- Sidebar collapses into hamburger on screens ≤768px
-- Flexible widget containers with auto-fit grid
-- Optimized breakpoints (sm: 640px, md: 768px, lg: 1024px, xl: 1280px)
-
-### 🎯 Modern Components
-- **Cards**: Widgets styled as elevated cards with shadows and hover effects
-- **Typography**: Improved hierarchy with modern font sizing
-- **Forms**: Refined input styling with focus ring system
-- **Buttons**: Consistent button styles with proper color variants
-- **Alerts**: Color-coded alerts (success, danger, warning, info)
-- **Tables**: Clean table styling with hover states
-
-### ♿ Accessibility Improvements
-- WCAG AA compliant color contrasts (verified on primary palette)
-- Focus-visible outlines for keyboard navigation
-- Semantic HTML structure preserved
-- Proper heading hierarchy support
-- Form labels and ARIA attributes maintained
-
-### 📊 Widget Styling
-- Card-based widget design with consistent shadows
-- Hover lift effect for interactivity feedback
-- Proper spacing and padding via tokens
-- Title bars with semantic color distinction
-- Dashboard grid with responsive columns
-
-## File Structure
-
-```
-custom/otssignange/
-├── config.php # Theme configuration (unchanged)
-├── css/
-│ ├── override.css # Main theme styles + design tokens (UPDATED)
-│ ├── html-preview.css # Preview splash screen (UPDATED)
-│ └── client.css # Widget embedding styles (NEW)
-├── img/
-│ ├── favicon.ico
-│ ├── 192x192.png
-│ ├── 512x512.png
-│ └── xibologo.png
-├── layouts/
-│ └── default-layout.zip
-└── views/
- └── index.html # Empty - ready for Twig overrides if needed
-```
-
-## CSS Variables Reference
-
-### Colors
-```css
-/* Brand Colors */
---color-primary: #2563eb
---color-primary-dark: #1d4ed8
---color-primary-light: #3b82f6
---color-secondary: #7c3aed
-
-/* Semantic Colors */
---color-success: #10b981
---color-warning: #f59e0b
---color-danger: #ef4444
---color-info: #0ea5e9
-
-/* Grays (50–900) */
---color-gray-50, 100, 200, 300, 400, 500, 600, 700, 800, 900
-
-/* Semantic Semantic */
---color-background: #ffffff (dark: #0f172a)
---color-surface: #f9fafb (dark: #1e293b)
---color-text-primary: #1f2937 (dark: #f1f5f9)
---color-text-secondary: #6b7280 (dark: #cbd5e1)
---color-border: #e5e7eb (dark: #475569)
-```
-
-### Typography
-```css
---font-family-base: System font stack
---font-size-xs to 4xl: 0.75rem → 2.25rem
---font-weight-normal/medium/semibold/bold: 400–700
---line-height-tight/snug/normal/relaxed/loose: 1.25–2
-```
-
-### Spacing (8px base)
-```css
---space-1 through --space-20: 0.25rem → 5rem
-```
-
-### Elevation & Borders
-```css
---shadow-none/xs/sm/base/md/lg/xl
---radius-none/sm/base/md/lg/xl/2xl/full
---transition-fast/base/slow: 150ms–300ms
-```
-
-## Customization Guide
-
-### Change Brand Color
-Edit `override.css` root selector:
-```css
-:root {
- --color-primary: #your-color;
- --color-primary-dark: #darker-shade;
- --color-primary-light: #lighter-shade;
-}
-```
-
-### Update Typography
-Modify font family and scale:
-```css
-:root {
- --font-family-base: "Your Font", sans-serif;
- --font-size-base: 1.125rem; /* Increase base from 16px to 18px */
-}
-```
-
-### Adjust Spacing
-Change the base spacing multiplier (affects all --space-* variables):
-```css
-/* If you prefer tighter spacing, reduce proportionally */
---space-4: 0.75rem; /* was 1rem */
---space-6: 1.125rem; /* was 1.5rem */
-```
-
-### Implement Dark Mode Toggle (Optional)
-If you want a user-controlled toggle instead of system preference:
-
-1. Add a button to toggle theme in a Twig view override
-2. Store preference in localStorage
-3. Add to `override.css`:
-```css
-[data-theme="dark"] {
- --color-background: #0f172a;
- --color-surface: #1e293b;
- /* etc. */
-}
-```
-
-## Files Modified
-
-### `css/override.css`
-**Changes:**
-- Replaced empty CSS hooks with comprehensive design token system
-- Added global styles using tokens
-- Implemented responsive header/sidebar with mobile hamburger
-- Added widget card styling with elevation effects
-- Included form, button, table, and alert component styles
-- Added responsive grid utilities and spacing classes
-
-**Size:** ~800 lines (was ~50 lines)
-
-### `css/html-preview.css`
-**Changes:**
-- Updated splash screen with gradient background matching brand color
-- Added preview widget styling for consistency
-- Improved visual fidelity with shadows and spacing
-
-### `css/client.css` (NEW)
-**Purpose:**
-- Styles HTML/embedded widgets on displays
-- Uses mirrored design tokens for consistency
-- Includes typography, form, button, and alert styles
-- Supports dark mode with prefers-color-scheme
-
-## Deployment Notes
-
-### Before Deploying to Production
-
-1. **Test in your Xibo CMS instance:**
- - Log in and verify admin UI appearance
- - Check sidebar navigation, widgets, and forms
- - Test on mobile (resize browser or use device)
- - Verify color contrast with a tool like WAVE or aXe
-
-2. **Verify Asset Paths:**
- - Ensure `preview/img/xibologo.png` is accessible
- - Check that logo files in `img/` are served correctly
- - Validate CSS paths resolve in your installation
-
-3. **Browser Compatibility:**
- - CSS variables supported in all modern browsers (Chrome 49+, Firefox 31+, Safari 9.1+, Edge 15+)
- - For legacy browser support, add CSS fallbacks (not included)
-
-4. **Backup:**
- - Keep a backup of original `override.css` before deployment
-
-### Installation
-
-1. Copy the updated theme files to `/web/theme/custom/otssignange/`
-2. Clear Xibo CMS cache if applicable
-3. Reload the CMS in your browser
-4. No database changes or CMS restart required
-
-### Rollback
-
-If issues occur, revert to backup:
-```bash
-cp override.css.backup override.css
-# Refresh browser cache
-```
-
-## Responsive Breakpoints
-
-| Breakpoint | Width | Use Case |
-|-----------|-------|----------|
-| **Mobile** | < 640px | Single column layout |
-| **Tablet** | 640–768px | Sidebar collapse |
-| **Desktop** | 768–1024px | 2–3 column grids |
-| **Large** | 1024–1280px | Multi-column dashboards |
-| **Ultra** | ≥ 1280px | Full-width content |
-
-## Accessibility Checklist
-
-- [x] WCAG AA color contrast (4.5:1 text, 3:1 components)
-- [x] Focus visible outlines (2px solid primary color)
-- [x] Keyboard navigation preserved
-- [x] Semantic HTML maintained
-- [x] Form labels and ARIA attributes respected
-- [x] No color-only information conveyed
-- [x] Sufficient touch target sizes (≥44px)
-
-## Future Enhancements
-
-Suggested follow-ups:
-- Create Twig view overrides for `authed.twig` and `authed-sidebar.twig` for DOM-level layout improvements
-- Add SVG icon sprite for consistent iconography across CMS
-- Implement animated transitions for sidebar collapse
-- Add data visualization component styles (charts, graphs)
-- Create documentation portal in Xibo for custom branding
-
-## Support & Questions
-
-For documentation on Xibo CMS theming:
-- [Xibo Developer Docs](https://account.xibosignage.com/docs/developer/)
-- Theme config reference: `config.php`
-- Available Twig overrides: Check `/web/theme/default/views/` in your Xibo installation
-
-## License
-
-This theme extends Xibo CMS and is subject to AGPLv3 license per Xibo requirements.
-Xibo is © 2006–2021 Xibo Signage Ltd.
-
----
-
-**Theme Version:** 1.0.0 (Modern)
-**Last Updated:** February 2026
-**Xibo CMS Compatibility:** 3.x and above
diff --git a/SUMMARY.md b/SUMMARY.md
deleted file mode 100644
index cf2d981..0000000
--- a/SUMMARY.md
+++ /dev/null
@@ -1,260 +0,0 @@
-# Implementation Summary
-
-## What Was Done
-
-Your Xibo CMS OTS Signage theme has been fully modernized with a comprehensive design system. Here's what's been delivered:
-
-### 📁 Files Created/Updated
-
-#### 1. **`css/override.css`** (Main Theme File)
-- **Status**: ✅ Complete rewrite
-- **Lines**: ~800 (was ~50)
-- **Contains**:
- - 70+ CSS variables defining colors, typography, spacing, shadows, transitions
- - Dark mode support via `prefers-color-scheme`
- - Global typography styles with proper hierarchy
- - Modern header/navbar styling
- - Responsive sidebar with mobile hamburger menu
- - Card-based widget styling with elevation effects
- - Form controls with focus rings
- - Button component variants (primary, secondary, success, danger)
- - Alert/notification styling
- - Table styling with hover effects
- - Responsive grid utilities
- - Accessibility features (focus-visible, color contrast)
-
-#### 2. **`css/html-preview.css`** (Preview Styling)
-- **Status**: ✅ Updated
-- **Changes**:
- - Gradient background matching brand color
- - Preview widget component styling
- - Consistent with main theme tokens
-
-#### 3. **`css/client.css`** (Widget Styling)
-- **Status**: ✅ New file created
-- **Purpose**: Styles HTML/embedded widgets on displays
-- **Includes**: Typography, forms, buttons, tables, alerts, dark mode support
-
-#### 4. **`README.md`** (Full Documentation)
-- **Status**: ✅ Comprehensive guide created
-- **Contents**:
- - Feature overview (design tokens, dark mode, responsive, accessibility)
- - File structure reference
- - CSS variable reference guide
- - Customization basics
- - Deployment notes
- - Responsive breakpoints
- - Accessibility compliance checklist
-
-#### 5. **`CUSTOMIZATION.md`** (Recipes & Cookbook)
-- **Status**: ✅ 15 customization recipes provided
-- **Examples**:
- - Change brand colors
- - Update typography
- - Adjust spacing
- - Implement dark mode toggle
- - Create custom alert styles
- - And 10 more...
-
-#### 6. **`DEPLOYMENT.md`** (Quick Start & Checklist)
-- **Status**: ✅ Ready for production
-- **Includes**:
- - Pre-deployment checklist
- - Step-by-step installation (3 methods)
- - Post-deployment validation
- - Rollback procedures
- - Browser support matrix
- - Troubleshooting guide
-
----
-
-## 🎯 Key Features Implemented
-
-### Design System
-| Element | Details |
-|---------|---------|
-| **Color Palette** | 10 semantic colors + 9-step gray scale |
-| **Typography** | System font stack, 8-step type scale, 5 weights |
-| **Spacing** | 8px-based scale (13 units from 4px to 80px) |
-| **Shadows** | 6-level elevation system for depth |
-| **Radius** | 8 border radius options (sharp to full-round) |
-| **Transitions** | 3 predefined animation speeds |
-
-### Responsive Design
-- Mobile-first approach
-- Sidebar collapses into hamburger menu on screens ≤768px
-- Flexible grid layouts with auto-fit
-- 5 breakpoints (sm, md, lg, xl, 2xl)
-
-### Dark Mode
-- Automatic via system preference (`prefers-color-scheme: dark`)
-- No JavaScript required
-- All colors adjusted for readability in dark mode
-
-### Accessibility
-- WCAG AA color contrast compliance
-- Focus-visible outlines for keyboard navigation
-- Semantic HTML preserved
-- Form labels and ARIA attributes maintained
-- Proper heading hierarchy support
-
-### Components
-- Header/navbar with brand color
-- Sidebar navigation with active states
-- Cards with elevation and hover effects
-- Forms with focus rings
-- Buttons (4 color variants)
-- Alerts (4 status types)
-- Tables with hover states
-- Modal & dialog support ready
-
----
-
-## 📊 Comparison: Before vs. After
-
-| Aspect | Before | After |
-|--------|--------|-------|
-| **CSS Architecture** | Empty hooks | Comprehensive token system |
-| **Color System** | No tokens | 70+ CSS variables |
-| **Dark Mode** | Not supported | Full system preference support |
-| **Responsive** | Basic | Mobile-first with breakpoints |
-| **Components** | Minimal | Complete design system |
-| **Accessibility** | Baseline | WCAG AA compliant |
-| **Documentation** | Minimal | 4 comprehensive guides |
-| **Customization** | Limited | 15+ recipes provided |
-
----
-
-## 🚀 Quick Start
-
-### 1. Review the Changes
-```bash
-# Check modified files
-ls -la custom/otssignange/css/
-# Output:
-# override.css (800 lines, modernized)
-# html-preview.css (updated with gradient)
-# client.css (new, for widgets)
-```
-
-### 2. Backup Current Theme
-```bash
-cp custom/otssignange/css/override.css custom/otssignange/css/override.css.backup
-```
-
-### 3. Deploy to Xibo
-Copy the three CSS files to your Xibo installation:
-```bash
-cp custom/otssignange/css/* /path/to/xibo/web/theme/custom/otssignange/css/
-```
-
-### 4. Clear Cache & Test
-- Hard refresh browser: Ctrl+Shift+R
-- Log into Xibo CMS
-- Verify header, sidebar, and widgets display with new styling
-- Test on mobile: Resize browser to <640px or use device
-
-### 5. Customize (Optional)
-See [CUSTOMIZATION.md](CUSTOMIZATION.md) for 15 ready-made recipes to adjust colors, fonts, spacing, etc.
-
----
-
-## 📋 What's Next?
-
-### Immediate (Try It)
-1. Deploy to your Xibo test instance
-2. Verify appearance across devices
-3. Test color contrast with WAVE or aXe tools
-4. Customize brand colors if needed (see CUSTOMIZATION.md)
-
-### Short Term (Enhancement)
-- Add SVG icon sprite to `img/` for better iconography
-- Create Twig view overrides for header/sidebar layout customization
-- Implement user-controlled dark mode toggle
-
-### Medium Term (Polish)
-- Add data visualization component styles (charts, graphs)
-- Create mini documentation portal within Xibo for custom branding
-- Add animations/transitions for sidebar collapse, form interactions
-
-### Long Term (Expansion)
-- Style custom Xibo modules/extensions
-- Create light/dark theme variants as separate CSS files
-- Build theme generator tool for rapid customization
-
----
-
-## 🔄 Rollback (If Needed)
-
-If any issues occur after deployment:
-
-```bash
-# Restore backup
-cp custom/otssignange/css/override.css.backup custom/otssignange/css/override.css
-
-# Remove new file if problematic
-rm custom/otssignange/css/client.css
-
-# Clear cache and refresh
-# (Clear Xibo cache or hard-refresh browser)
-```
-
----
-
-## 📚 Documentation Files
-
-| File | Purpose |
-|------|---------|
-| **README.md** | Full feature documentation, tokens reference, accessibility checklist |
-| **CUSTOMIZATION.md** | 15+ customization recipes (change colors, fonts, spacing, etc.) |
-| **DEPLOYMENT.md** | Installation steps, validation checklist, troubleshooting |
-| **SUMMARY.md** | This file—high-level overview |
-
----
-
-## ✅ Quality Assurance
-
-- [x] CSS syntax validated (no errors)
-- [x] Design tokens comprehensive (70+ variables)
-- [x] Dark mode fully implemented
-- [x] Responsive breakpoints correct
-- [x] Color contrast WCAG AA compliant
-- [x] Accessibility features included
-- [x] Documentation complete
-- [x] Customization recipes provided
-- [x] Deployment guide created
-- [x] Rollback procedure documented
-
----
-
-## 🎓 Learning Resources
-
-- **CSS Variables**: [MDN - CSS Custom Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/--*)
-- **Dark Mode**: [MDN - prefers-color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme)
-- **Responsive Design**: [MDN - Responsive Design](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Responsive_Design)
-- **Xibo Theming**: [Xibo Developer Docs](https://account.xibosignage.com/docs/developer/)
-
----
-
-## 📝 Version Info
-
-- **Theme Name**: OTS Signage (Modern)
-- **Version**: 1.0.0
-- **Status**: Production Ready
-- **Last Updated**: February 2026
-- **Xibo Compatibility**: 3.x and above
-- **Browser Support**: All modern browsers (Chrome, Firefox, Safari, Edge, Mobile)
-
----
-
-## 💡 Support
-
-For issues or questions:
-1. Check [DEPLOYMENT.md](DEPLOYMENT.md) troubleshooting section
-2. Review [CUSTOMIZATION.md](CUSTOMIZATION.md) for common tasks
-3. Consult [README.md](README.md) for feature details
-4. Refer to [Xibo Developer Docs](https://account.xibosignage.com/docs/developer/)
-
----
-
-**Status**: ✅ Implementation Complete & Ready for Deployment
diff --git a/THEME_IMPLEMENTATION.md b/THEME_IMPLEMENTATION.md
deleted file mode 100644
index 7b3ce10..0000000
--- a/THEME_IMPLEMENTATION.md
+++ /dev/null
@@ -1,396 +0,0 @@
-# OTS Signs Xibo CMS Theme - Implementation Guide
-
-## Overview
-
-This is a modern, dark-themed Xibo CMS theme with a professional UI redesign. The theme replaces all major views (dashboard, displays, media library) with contemporary components, a responsive sidebar navigation, and a modern topbar layout.
-
-**Theme Name:** OTS Signs
-**Theme Directory:** `custom/otssignange/`
-**Target Xibo Version:** Latest stable (v4.0+)
-**License:** AGPL-3.0 (Xibo)
-
----
-
-## Implementation Summary
-
-### ✅ Completed Changes
-
-#### 1. **Views Updated**
-- **authed.twig** - Modern shell with fixed sidebar + main layout, SVG icons, responsive topbar
-- **authed-sidebar.twig** - Enhanced sidebar with organized nav sections, user profile card, SVG icons
-- **dashboard.twig** - KPI cards, status panels, quick action grid
-- **displays.twig** - Two-column layout with folder tree, modern table, stat boxes
-- **media.twig** - Media grid with image previews, storage stats, folder structure
-
-#### 2. **CSS Styling (override.css)**
-- **Dark theme colors:** Navy backgrounds (#0f172a), slate surfaces (#1e293b), blue accents (#3b82f6)
-- **Component system:** Sidebar, topbar, KPI cards, badges, buttons, tables, media grid
-- **Responsive design:** Mobile breakpoints at 768px, flexible grid layouts
-- **Transitions & effects:** Smooth hover states, focus states, elevation shadows
-- **CSS variables:** Comprehensive design token system for easy customization
-
-#### 3. **JavaScript Functionality (theme.js)**
-- Sidebar toggle with mobile responsiveness
-- Dropdown menu interactions (user menu)
-- Search form focus states
-- Page-specific interactions (folder selection, media item interaction)
-- Mobile viewport detection and adaptive behavior
-
----
-
-## File Structure
-
-```
-custom/otssignange/
-├── config.php # Theme registration & configuration
-├── css/
-│ ├── client.css # HTML widget styling (mirrored design tokens)
-│ ├── override.css # Main dark theme & component styles (1000+ lines)
-│ └── html-preview.css # Preview mode styles
-├── js/
-│ └── theme.js # Interactive components & sidebar toggle
-├── img/ # Placeholder for logo/icons
-├── views/
-│ ├── authed.twig # Main shell (sidebar + topbar + main area)
-│ ├── authed-sidebar.twig # Left navigation sidebar
-│ ├── dashboard.twig # Dashboard page with KPI cards
-│ ├── displays.twig # Displays management page
-│ ├── media.twig # Media library page
-│ ├── index.html # Fallback page
-│ └── layouts/ # Layout templates (inherited from Xibo core)
-└── README.md # This file
-
-```
-
----
-
-## Key Features
-
-### 🎨 **Dark Theme**
-- **Colors:** Dark navy backgrounds, slate panels, bright blue primary accent
-- **Contrast:** WCAG AA compliant (high contrast text)
-- **Consistent:** Applied across all pages and components
-
-### 📱 **Responsive Layout**
-- **Sidebar:** Fixed on desktop, slide-in drawer on mobile (<768px)
-- **Topbar:** Responsive search bar, user menu, notification button
-- **Content:** Flexible grids that stack on smaller screens
-- **Tables:** Horizontal scroll on mobile, proper alignment
-
-### 🎯 **Modern Components**
-- **KPI Cards:** Display key metrics (displays online, schedules, users)
-- **Panels:** Two-column layouts for displays & media sections
-- **Tables:** Striped rows, hover states, action menus
-- **Media Grid:** Thumbnail preview cards with metadata
-- **Badges:** Status indicators (Online/Offline, Success/Danger/Info)
-- **Buttons:** Primary (blue), outline, small, and ghost variants
-
-### ⚡ **Interactivity**
-- Sidebar toggle on mobile
-- Dropdown menus (user profile menu)
-- Folder/item selection with visual feedback
-- Search input focus states
-- Smooth transitions (150-300ms)
-
----
-
-## Installation & Deployment
-
-### Option 1: Local Development (Xibo CMS Installed)
-
-1. **Navigate to theme directory:**
- ```bash
- cd /path/to/xibo-cms/web/theme/custom/
- ```
-
-2. **Copy the theme folder:**
- ```bash
- cp -r /path/to/otssignstheme/custom/otssignange ./
- ```
-
-3. **Enable in Xibo Admin:**
- - Go to **Settings → Preferences → Themes**
- - Select "OTS Signs" from the dropdown
- - Click **Save**
-
-4. **Clear caches:**
- - Go to **Settings → Maintenance → Purge Cache**
- - Refresh the page
-
-### Option 2: Package for Distribution
-
-Create a ZIP file for sharing:
-
-```bash
-cd /path/to/otssignstheme/custom/
-zip -r ots-signs-theme.zip otssignange/
-```
-
-**Distribution contents:**
-- `otssignange/` - Full theme directory
-- `INSTALLATION.txt` - Setup instructions
-- `LICENSE` - AGPL-3.0 license
-
----
-
-## Customization
-
-### Change Primary Color
-
-Edit `css/override.css`, line ~10:
-
-```css
---color-primary: #3b82f6; /* Change from blue to your color */
---color-primary-dark: #1d4ed8;
---color-primary-light: #60a5fa;
-```
-
-**Hex color suggestions:**
-- Purple: `#8b5cf6`
-- Red: `#ef4444`
-- Green: `#10b981`
-- Orange: `#f97316`
-
-### Adjust Sidebar Width
-
-Edit `css/override.css`, line ~58:
-
-```css
-.ots-sidebar {
- width: 250px; /* Change to 280px, 300px, etc. */
-}
-
-.ots-main {
- margin-left: 250px; /* Must match sidebar width */
-}
-```
-
-### Customize Fonts
-
-Edit `css/override.css`:
-
-```css
-/* Base font family */
---font-family-base: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
-
-/* Monospace (for code) */
---font-family-mono: 'Monaco', monospace;
-```
-
-### Add Company Logo
-
-1. Place logo at `img/logo.png` (recommended: 40x40px, PNG/SVG)
-2. Edit `views/authed-sidebar.twig`, line ~7:
- ```twig
- 🎯
-
- ```
-
----
-
-## Browser Compatibility
-
-- **Chrome/Edge:** ✅ Full support (latest 2 versions)
-- **Firefox:** ✅ Full support (latest 2 versions)
-- **Safari:** ✅ Full support (latest 2 versions)
-- **IE11:** ❌ Not supported (CSS Grid, CSS Variables not available)
-
-**CSS Features Used:**
-- CSS Grid (layout)
-- CSS Flexbox (alignment)
-- CSS Variables (theming)
-- CSS Transitions (animations)
-- SVG inline (icons)
-
----
-
-## Common Issues & Troubleshooting
-
-### Issue: Sidebar not toggling on mobile
-**Solution:** Ensure `theme.js` is loaded. Check browser console for errors:
-```bash
-Press F12 → Console tab → Look for red errors
-```
-
-### Issue: Dark theme not applying
-**Solution:** Clear Xibo cache and browser cache:
-1. **Xibo:** Settings → Maintenance → Purge Cache
-2. **Browser:** Ctrl+Shift+Delete (Windows) or Cmd+Shift+Delete (Mac)
-
-### Issue: Images in media grid not showing
-**Solution:** Verify image URLs are accessible. Check:
-1. File permissions (644 for files, 755 for directories)
-2. Image format is supported (JPEG, PNG, GIF, WebP)
-
-### Issue: Search bar styling broken
-**Solution:** Ensure `override.css` is fully loaded. Check:
-1. CSS file size: should be ~8-10 KB
-2. No CSS parse errors in DevTools (F12 → Console)
-
----
-
-## Development & Debugging
-
-### Enable Debug Mode
-
-Edit `config.php`:
-
-```php
-// Add at top of file
-define('DEBUG', true);
-```
-
-### View Generated HTML
-
-In browser, right-click → **Inspect Element** to see:
-- DOM structure
-- Applied CSS classes
-- CSS rules (with file/line)
-- SVG icons rendering
-
-### Test Responsive Design
-
-In browser DevTools (F12):
-1. Click **Toggle Device Toolbar** (or Ctrl+Shift+M)
-2. Select mobile device (iPhone 12, Pixel 5, etc.)
-3. Test sidebar toggle, search, menus
-
----
-
-## Performance Metrics
-
-- **CSS file size:** ~8 KB (minified)
-- **JS file size:** ~3 KB (minified)
-- **Load time (typical):** <500ms additional
-- **Lighthouse score:** 85+ (with proper images)
-
----
-
-## Xibo CMS Integration Notes
-
-### Theme Hooks (Twig Blocks)
-
-The theme extends `base.twig` and overrides:
-
-- `{% block head %}` - Link to custom CSS
-- `{% block htmlTag %}` - Dark mode attribute
-- `{% block body %}` - Custom shell structure
-- `{% block header %}` - Topbar
-- `{% block content %}` - Main content area
-- `{% block footer %}` - Footer
-- `{% block scripts %}` - Include theme.js
-
-### Available Twig Variables
-
-In views, you can access:
-
-```twig
-{{ baseUrl }} # Base URL of Xibo CMS
-{{ app_name }} # Application name (from config.php)
-{{ user.username }} # Current user's login
-{{ currentDate }} # Current date/time
-{{ pageTitle }} # Page title (from view)
-{{ pageSubtitle }} # Optional page subtitle
-```
-
-### CSS Class Conventions
-
-Custom classes follow BEM naming:
-
-```
-.ots- # Root component
-.ots-__item # Child element
-.ots---active # Modifier
-```
-
----
-
-## Future Enhancements
-
-### Planned Features
-- [ ] Light mode toggle (currently dark only)
-- [ ] Custom color picker in admin
-- [ ] Theme variants (compact, expanded sidebar)
-- [ ] Export/import settings
-- [ ] RTL (Right-to-Left) support
-
-### Community Contribution Ideas
-- Additional color schemes
-- Accessibility improvements (AAA contrast)
-- More page overrides (Settings, Users, Schedules)
-- Keyboard navigation enhancements
-- Dashboard widget system
-
----
-
-## Support & License
-
-**License:** AGPL-3.0 (inherited from Xibo CMS)
-
-**Legal Notice:**
-This theme is provided as-is for use with Xibo Digital Signage CMS. It maintains compatibility with Xibo's AGPL license. Any modifications must be shared with the community under the same license.
-
-**Support Channels:**
-- Xibo Community Forum: https://community.xibo.org.uk/
-- GitHub Issues: https://github.com/xibosignage/xibo-cms/issues
-
----
-
-## Credits
-
-**Theme Created For:** OTS Signs
-**Based On:** Xibo CMS v4.0+ default theme
-**Design System:** Modern dark theme with blue accent
-**Created:** February 2026
-
----
-
-## Changelog
-
-### v1.0.0 (Initial Release)
-- Complete redesign of dashboard, displays, media views
-- Dark theme with blue accent color
-- Responsive sidebar & topbar
-- Modern component system
-- SVG icon integration
-- Keyboard & mobile accessibility
-- ~1000 lines of new CSS
-- Interactive JavaScript components
-
----
-
-## Quick Reference
-
-### CSS Variables
-```css
---color-primary: #3b82f6 /* Main brand color */
---color-background: #0f172a /* Page background */
---color-surface: #1e293b /* Card/panel background */
---color-text-primary: #f1f5f9 /* Main text */
---color-border: #475569 /* Dividers */
-```
-
-### Breakpoints
-```css
-Mobile: max-width: 640px
-Tablet: 641px - 768px
-Desktop: 769px+
-```
-
-### Key Classes
-```
-.ots-shell /* Main layout wrapper */
-.ots-sidebar /* Left navigation */
-.ots-topbar /* Top header bar */
-.ots-content /* Main content area */
-.kpi-section /* Dashboard KPI grid */
-.panel /* Card component */
-.btn /* Button */
-.badge /* Status badge */
-.table /* Data table */
-.media-grid /* Image grid */
-```
-
----
-
-**For questions or issues, refer to the Xibo Community Forum or review the theme files directly.**
diff --git a/custom/otssignange/css/override-dark.css b/custom/otssignange/css/override-dark.css
index bd61508..2cc43b8 100644
--- a/custom/otssignange/css/override-dark.css
+++ b/custom/otssignange/css/override-dark.css
@@ -1,1098 +1,581 @@
-/* ============================================================================
- XIBO CMS MODERN THEME - OTS Signs
- Dark Mode Override - Component Styling
- ============================================================================ */
+/* =============================================================================
+ OTS SIGNAGE DARK THEME (REBUILT)
+ February 4, 2026
+ ============================================================================= */
-/* 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: #f1f5f9;
- --color-text-secondary: #cbd5e1;
- --color-text-tertiary: #94a3b8;
- --color-text-inverse: #0f172a;
-
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: #7f8aa3;
+ --ots-primary: #4f8cff;
+ --ots-primary-2: #2f6bff;
+ --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: 6px;
+ --ots-radius-md: 10px;
+ --ots-radius-lg: 14px;
+
+ --ots-transition: 160ms ease;
}
+/* =============================================================================
+ GLOBAL
+ ============================================================================= */
+
html,
body {
- background-color: var(--color-background);
- color: var(--color-text-primary);
+ background: var(--ots-bg);
+ color: var(--ots-text);
}
-/* ============================================================================
- SHELL LAYOUT - SIDEBAR + MAIN
- ============================================================================ */
-
-.ots-shell {
- display: flex;
- min-height: 100vh;
+body {
+ font-family: "Inter", "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
+ -webkit-font-smoothing: antialiased;
+ text-rendering: optimizeLegibility;
}
-.ots-sidebar {
- position: fixed;
- left: 0;
- top: 0;
- width: 250px;
- height: 100vh;
- background-color: var(--color-surface);
- border-right: 1px solid var(--color-border);
- display: flex;
- flex-direction: column;
- overflow-y: auto;
- z-index: 1000;
-}
-
-.ots-main {
- flex: 1;
- margin-left: 250px;
- display: flex;
- flex-direction: column;
-}
-
-.ots-content {
- flex: 1;
- padding: 32px;
- overflow-y: auto;
-}
-
-.ots-footer {
- border-top: 1px solid var(--color-border);
- padding: 16px 32px;
- background-color: var(--color-surface-elevated);
- text-align: center;
-}
-
-/* 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;
- }
-}
-
-/* ============================================================================
- SIDEBAR STYLES
- ============================================================================ */
-
-.sidebar-header {
- padding: 24px 16px;
- border-bottom: 1px solid var(--color-border);
- display: flex;
- align-items: center;
- gap: 12px;
-}
-
-.brand-link {
- display: flex;
- align-items: center;
- gap: 12px;
- color: var(--color-text-primary);
+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;
- font-size: 18px;
}
-.brand-icon {
- font-size: 28px;
+small,
+.text-muted {
+ color: var(--ots-text-muted) !important;
}
-.sidebar-content {
- flex: 1;
- padding: 12px 0;
- overflow-y: auto;
+hr {
+ border-color: var(--ots-border);
}
-.sidebar-nav {
- list-style: none;
- margin: 0;
+/* =============================================================================
+ 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);
+ box-shadow: var(--ots-shadow-sm);
+}
+
+.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;
}
-.sidebar-nav li {
- display: block;
-}
-
-.nav-section-divider {
- padding: 12px 16px 8px;
- margin-top: 8px;
- border-top: 1px solid var(--color-border);
-}
-
-.nav-label {
- display: block;
- font-size: 12px;
+.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;
- text-transform: uppercase;
- color: var(--color-text-tertiary);
- letter-spacing: 0.05em;
+ transition: background var(--ots-transition), color var(--ots-transition);
}
-.nav-item {
+.ots-topbar .nav-link:hover,
+.ots-topbar .nav-item.open .nav-link,
+.ots-topbar .nav-item.active .nav-link {
+ background: rgba(79, 140, 255, 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: 12px;
- padding: 12px 16px;
- color: var(--color-text-secondary);
- text-decoration: none;
- transition: all var(--transition-fast);
- position: relative;
+ gap: 8px;
+ border-radius: 8px;
+ padding: 8px 10px;
}
-.nav-item:hover {
- color: var(--color-text-primary);
- background-color: rgba(59, 130, 246, 0.1);
+.ots-topbar-icon {
+ width: 16px;
+ text-align: center;
+ opacity: 0.85;
+ font-size: 13px;
}
-.nav-item.active {
- color: var(--color-primary);
- background-color: rgba(59, 130, 246, 0.15);
- border-left: 3px solid var(--color-primary);
- padding-left: 13px;
+/* =============================================================================
+ SIDEBAR
+ ============================================================================= */
+
+#sidebar-wrapper {
+ background: var(--ots-surface);
+ border-right: 1px solid var(--ots-border);
}
-.nav-icon {
- width: 20px;
- height: 20px;
- flex-shrink: 0;
+/* OTS sidebar override marker */
+.ots-sidebar-wrapper {
+ box-shadow: inset 0 0 0 1px rgba(79, 140, 255, 0.2);
}
-.nav-text {
+.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;
- font-weight: 500;
}
-.sidebar-footer {
- border-top: 1px solid var(--color-border);
- padding: 16px;
- background-color: rgba(59, 130, 246, 0.05);
-}
-
-.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 {
+.ots-nav-text {
+ flex: 1;
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-tertiary);
- white-space: nowrap;
-}
-
-/* ============================================================================
- TOPBAR STYLES
- ============================================================================ */
-
-.ots-topbar {
- background-color: var(--color-surface-elevated);
- border-bottom: 1px solid var(--color-border);
- padding: 12px 32px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: 24px;
- height: 70px;
-}
-
-.topbar-left {
- display: flex;
- align-items: center;
- gap: 16px;
- flex: 1;
-}
-
-.topbar-toggle {
- display: none;
- width: 40px;
- height: 40px;
- padding: 0;
- border: none;
- background-color: transparent;
- color: var(--color-text-primary);
- cursor: pointer;
- border-radius: 6px;
- transition: background-color var(--transition-fast);
-}
-
-.topbar-toggle:hover {
- background-color: var(--color-surface);
-}
-
-.topbar-toggle .icon {
- width: 24px;
- height: 24px;
-}
-
-.topbar-title h1 {
- margin: 0;
- font-size: 24px;
- font-weight: 600;
- color: var(--color-text-primary);
-}
-
-.topbar-title p {
- margin: 0;
- font-size: 14px;
- color: var(--color-text-secondary);
-}
-
-.topbar-right {
- display: flex;
- align-items: center;
- gap: 24px;
-}
-
-.topbar-search {
- position: relative;
- width: 280px;
- display: flex;
- align-items: center;
- background-color: var(--color-surface);
- border: 1px solid var(--color-border);
- border-radius: 6px;
- padding: 8px 12px;
-}
-
-.topbar-search .search-icon {
- color: var(--color-text-tertiary);
- flex-shrink: 0;
- margin-right: 8px;
-}
-
-.topbar-search .search-input {
- flex: 1;
- background: none;
- border: none;
- color: var(--color-text-primary);
- font-size: 14px;
- outline: none;
-}
-
-.topbar-search .search-input::placeholder {
- color: var(--color-text-tertiary);
-}
-
-.topbar-actions {
- display: flex;
- align-items: center;
- gap: 12px;
-}
-
-.topbar-btn {
- width: 40px;
- height: 40px;
- 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);
-}
-
-.topbar-btn:hover {
- background-color: var(--color-surface);
- color: var(--color-text-primary);
-}
-
-.topbar-btn .icon {
- width: 20px;
- height: 20px;
-}
-
-.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 {
- position: absolute;
- top: 100%;
- right: 0;
- margin-top: 8px;
- background-color: var(--color-surface-elevated);
- border: 1px solid var(--color-border);
- border-radius: 6px;
- box-shadow: var(--shadow-lg);
- list-style: none;
- padding: 8px 0;
- min-width: 160px;
- display: none;
- z-index: 1001;
-}
-
-.dropdown.active .dropdown-menu,
-.dropdown:focus-within .dropdown-menu {
- display: block;
-}
-
-.dropdown-menu li {
- display: block;
-}
-
-.dropdown-menu li a {
- display: block;
- padding: 10px 16px;
- color: var(--color-text-primary);
- text-decoration: none;
- font-size: 14px;
- transition: background-color var(--transition-fast);
-}
-
-.dropdown-menu li a:hover {
- background-color: var(--color-surface);
-}
-
-/* ============================================================================
- DASHBOARD PAGE
- ============================================================================ */
-
-.dashboard-page {
- display: flex;
- flex-direction: column;
- gap: 32px;
-}
-
-.page-header {
- margin-bottom: 16px;
-}
-
-.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;
-}
-
-.panel {
- background-color: var(--color-surface);
- border: 1px solid var(--color-border);
- border-radius: 8px;
- overflow: hidden;
-}
-
-.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;
-}
-
-.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)
- ============================================================================ */
-
-.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;
-}
-
-.panel-header {
- padding: 16px;
- border-bottom: 1px solid var(--color-border);
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-
-.panel-header h3 {
- margin: 0;
- font-size: 14px;
- font-weight: 600;
- color: var(--color-text-primary);
- text-transform: uppercase;
- letter-spacing: 0.05em;
-}
-
-.btn-icon-sm {
- width: 32px;
- height: 32px;
- padding: 0;
- border: none;
- background-color: transparent;
- color: var(--color-text-secondary);
- cursor: pointer;
- border-radius: 4px;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: all var(--transition-fast);
-}
-
-.btn-icon-sm:hover {
- background-color: var(--color-surface-elevated);
- color: var(--color-text-primary);
-}
-
-.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-elevated);
- border-bottom: 1px 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: 12px;
-}
-
-.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;
+/* Xibo sidebar refinements (dark) */
+#sidebar-wrapper .sidebar-title a {
+ color: var(--ots-text-faint);
font-size: 11px;
- font-weight: 600;
+ letter-spacing: 0.08em;
+ text-transform: uppercase;
+ padding: 12px 16px 6px;
+}
+
+#sidebar-wrapper .sidebar-list a,
+#sidebar-wrapper .sidebar-main a {
+ display: block;
+ margin: 2px 8px;
+ padding: 10px 12px;
+ border-radius: var(--ots-radius-sm);
+ transition: background var(--ots-transition), color var(--ots-transition);
+}
+
+#sidebar-wrapper .sidebar-list a:hover,
+#sidebar-wrapper .sidebar-main a:hover {
+ background: rgba(79, 140, 255, 0.12);
+ color: var(--ots-primary);
+}
+
+#sidebar-wrapper .sidebar {
+ padding: 14px 0;
+}
+
+#sidebar-wrapper .sidebar-main a,
+#sidebar-wrapper .sidebar-list a {
+ display: block;
+ padding: 10px 18px;
+ color: var(--ots-text);
+ border-left: 3px solid transparent;
+}
+
+#sidebar-wrapper .sidebar-main a:hover,
+#sidebar-wrapper .sidebar-list a:hover {
+ background: rgba(79, 140, 255, 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;
}
-.media-info {
- padding: 12px;
+/* =============================================================================
+ 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);
}
-.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;
+.widget-title,
+.panel-heading,
+.card-header,
+.modal-header {
+ background: var(--ots-surface-3);
+ border-bottom: 1px solid var(--ots-border);
+ color: var(--ots-text);
}
-.media-size {
- margin: 0;
- color: var(--color-text-tertiary);
+.widget-body,
+.panel-body,
+.card-body,
+.modal-body {
+ color: var(--ots-text);
}
-/* ============================================================================
+/* =============================================================================
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,
+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-color: var(--color-primary);
- color: white;
+ background: var(--ots-primary);
+ border-color: var(--ots-primary-2);
+ color: #0b1020;
}
.btn-primary:hover {
- background-color: var(--color-primary-dark);
+ background: var(--ots-primary-2);
+ border-color: var(--ots-primary-2);
+ color: #0b1020;
}
-.btn-outline {
- background-color: transparent;
- border: 1px solid var(--color-border);
- color: var(--color-text-primary);
+.btn-success {
+ background: var(--ots-success);
+ border-color: var(--ots-success);
+ color: #041410;
}
-.btn-outline:hover {
- background-color: var(--color-surface);
- border-color: var(--color-primary);
- color: var(--color-primary);
+.btn-warning {
+ background: var(--ots-warning);
+ border-color: var(--ots-warning);
+ color: #1c1200;
}
-.btn-sm {
- padding: 6px 12px;
- font-size: 13px;
+.btn-danger {
+ background: var(--ots-danger);
+ border-color: var(--ots-danger);
+ color: #220707;
}
-.btn-ghost {
- background-color: transparent;
- color: var(--color-text-secondary);
- padding: 0;
+.btn-info {
+ background: var(--ots-info);
+ border-color: var(--ots-info);
+ color: #07101a;
}
-.btn-ghost:hover {
- color: var(--color-text-primary);
+/* =============================================================================
+ 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;
}
-/* ============================================================================
- UTILITY CLASSES
- ============================================================================ */
-
-.text-muted {
- color: var(--color-text-secondary);
+.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(79, 140, 255, 0.2);
+ outline: none;
}
-.text-tertiary {
- color: var(--color-text-tertiary);
+.input-group-addon {
+ background: var(--ots-surface-3);
+ border: 1px solid var(--ots-border);
+ color: var(--ots-text-muted);
}
-.text-xs {
+/* =============================================================================
+ 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(79, 140, 255, 0.04);
+}
+
+.table-hover > tbody > tr:hover {
+ background: rgba(79, 140, 255, 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(79, 140, 255, 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
+ ============================================================================= */
+
+.modal-content {
+ border-radius: var(--ots-radius-lg);
+}
+
+.modal-footer {
+ border-top: 1px solid var(--ots-border);
+}
+
+/* =============================================================================
+ HELP PANE / MISC
+ ============================================================================= */
+
+#help-pane {
+ background: var(--ots-surface-2);
+ border: 1px solid var(--ots-border);
+}
+
+#help-pane .help-pane-btn {
+ background: var(--ots-primary);
+ color: #0b1020;
+}
+
+/* =============================================================================
+ OTS DASHBOARD MESSAGE
+ ============================================================================= */
+
+.ots-dashboard-message {
+ margin: 16px 0 24px;
+ padding: 12px 16px;
+ border-radius: var(--ots-radius-md);
+ background: rgba(79, 140, 255, 0.16);
+ border: 1px solid rgba(79, 140, 255, 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;
}
-.text-sm {
- font-size: 14px;
-}
-
-/* ============================================================================
- 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-dashboard-message__body {
+ font-size: 13px;
+ color: var(--ots-text-muted);
}
diff --git a/custom/otssignange/css/override.css b/custom/otssignange/css/override.css
index 8c56481..a933705 100644
--- a/custom/otssignange/css/override.css
+++ b/custom/otssignange/css/override.css
@@ -20,10 +20,11 @@
--color-surface-elevated: #334155;
--color-border: #475569;
--color-border-light: #1e293b;
- --color-text-primary: #f1f5f9;
- --color-text-secondary: #cbd5e1;
- --color-text-tertiary: #94a3b8;
- --color-text-inverse: #0f172a;
+ --color-text-primary: #ffffff;
+ --color-text-secondary: #f1f5f9;
+ --color-text-tertiary: #e2e8f0;
+ --color-text-inverse: #ffffff;
+ --color-on-primary: #ffffff;
color-scheme: dark;
}
@@ -47,10 +48,11 @@ body {
position: fixed;
left: 0;
top: 0;
- width: 250px;
+ width: 260px;
height: 100vh;
- background-color: var(--color-surface);
- border-right: 1px solid var(--color-border);
+ background-color: #08132a;
+ border-right: 1px solid rgba(255, 255, 255, 0.06);
+ padding: 0;
display: flex;
flex-direction: column;
overflow-y: auto;
@@ -59,9 +61,9 @@ body {
.ots-main {
flex: 1;
- margin-left: 250px;
display: flex;
flex-direction: column;
+ margin-left: 260px;
}
.ots-content {
@@ -75,6 +77,7 @@ body {
padding: 16px 32px;
background-color: var(--color-surface-elevated);
text-align: center;
+ color: var(--color-text-primary);
}
/* Responsive sidebar */
@@ -84,7 +87,6 @@ body {
transition: transform var(--transition-base);
width: 280px;
}
-
.ots-sidebar.active {
transform: translateX(0);
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.3);
@@ -93,6 +95,10 @@ body {
.ots-main {
margin-left: 0;
}
+
+ .ots-content {
+ color: var(--color-text-primary);
+ }
}
/* ============================================================================
@@ -100,10 +106,11 @@ body {
============================================================================ */
.sidebar-header {
- padding: 24px 16px;
+ padding: 20px 16px;
border-bottom: 1px solid var(--color-border);
display: flex;
align-items: center;
+ justify-content: space-between;
gap: 12px;
}
@@ -112,13 +119,20 @@ body {
align-items: center;
gap: 12px;
color: var(--color-text-primary);
+ font-weight: 700;
+ font-size: 16px;
text-decoration: none;
- font-weight: 600;
- font-size: 18px;
+ flex: 1;
}
.brand-icon {
- font-size: 28px;
+ width: 32px;
+ height: 32px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 24px;
+ flex-shrink: 0;
}
.sidebar-content {
@@ -130,13 +144,85 @@ body {
.sidebar-nav {
list-style: none;
margin: 0;
- padding: 0;
+ padding: 12px 0 120px;
}
.sidebar-nav li {
display: block;
}
+/* 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: grid;
+ grid-template-columns: 20px 1fr;
+ align-items: center;
+ column-gap: 12px;
+ padding: 8px 12px;
+ color: #c8d5ee;
+ text-decoration: none;
+ transition: all var(--transition-fast);
+ position: relative;
+ font-size: 14px;
+ font-weight: 500;
+ border-left: 2px solid transparent;
+ margin: 3px 10px;
+ border-radius: 12px;
+ min-height: 40px;
+ line-height: 1.25;
+}
+
+.ots-sidebar li.sidebar-list > a:hover {
+ color: #ffffff;
+ background-color: rgba(255, 255, 255, 0.08);
+}
+
+.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: #0b1221;
+ background-color: #ffffff;
+ border-left-color: transparent;
+ font-weight: 600;
+ box-shadow: 0 8px 18px rgba(15, 23, 42, 0.25);
+}
+
+.ots-sidebar .ots-nav-icon {
+ width: 24px;
+ height: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-shrink: 0;
+ font-size: 16px;
+ color: currentColor;
+ justify-self: center;
+}
+
+.ots-sidebar .ots-nav-text {
+ font-size: 14px;
+ font-weight: 500;
+ flex: 1;
+ line-height: 1.2;
+}
+
+.ots-sidebar li.sidebar-title > a {
+ display: block;
+ font-size: 10px;
+ font-weight: 700;
+ text-transform: uppercase;
+ color: #8ea4c7;
+ letter-spacing: 0.12em;
+ padding: 12px 14px 4px;
+ margin: 8px 0 0;
+ min-height: auto;
+ line-height: 1;
+}
+
.nav-section-divider {
padding: 12px 16px 8px;
margin-top: 8px;
@@ -145,45 +231,68 @@ body {
.nav-label {
display: block;
- font-size: 12px;
- font-weight: 600;
+ font-size: 11px;
+ font-weight: 700;
text-transform: uppercase;
color: var(--color-text-tertiary);
- letter-spacing: 0.05em;
+ letter-spacing: 0.08em;
+ padding: 12px 16px 8px;
+ margin-top: 8px;
}
.nav-item {
display: flex;
align-items: center;
- gap: 12px;
+ gap: 14px;
padding: 12px 16px;
- color: var(--color-text-secondary);
+ 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.15);
- border-left: 3px solid var(--color-primary);
- padding-left: 13px;
+ 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: 20px;
- height: 20px;
+ 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 {
@@ -226,30 +335,151 @@ body {
}
.user-role {
- color: var(--color-text-tertiary);
+ color: var(--color-text-secondary);
white-space: nowrap;
}
/* ============================================================================
- TOPBAR STYLES
+ TOPBAR STYLES - DEEP ANALYSIS & MODERN OVERHAUL
+ ============================================================================
+ Design decisions:
+ - 64px total height (44px content + 10px top/bottom padding) = consistent baseline
+ - All interactive elements are 40px (buttons, search height)
+ - Icon sizing: 20px container, 16px icon (scale-friendly)
+ - Consistent 16px gap spacing throughout
+ - Remove conflicting .navbar-nav rules
+ - Proper z-index layering for dropdowns
============================================================================ */
.ots-topbar {
background-color: var(--color-surface-elevated);
- border-bottom: 1px solid var(--color-border);
- padding: 12px 32px;
+ border-bottom: 2px solid var(--color-border);
+ padding: 10px 32px;
display: flex;
align-items: center;
justify-content: space-between;
- gap: 24px;
- height: 70px;
+ gap: 16px;
+ height: 64px;
+ z-index: 1000;
}
+/* Topbar nav container - override .navbar-nav defaults */
+.ots-topbar.navbar-nav {
+ background: transparent !important;
+ border: 0 !important;
+ padding: 0 !important;
+ margin: 0 !important;
+ gap: 4px;
+ height: 100%;
+ align-items: center;
+}
+
+.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: 100%;
+ gap: 6px;
+ padding: 0 12px;
+ border-radius: 6px;
+ color: var(--color-text-secondary);
+ font-weight: 500;
+ font-size: 14px;
+ white-space: nowrap;
+ transition: all var(--transition-fast);
+ position: relative;
+}
+
+.ots-topbar .nav-link:hover {
+ background-color: rgba(59, 130, 246, 0.08);
+ color: var(--color-primary);
+}
+
+.ots-topbar .nav-item.open .nav-link,
+.ots-topbar .nav-item.active .nav-link {
+ background-color: rgba(59, 130, 246, 0.12);
+ color: var(--color-primary);
+ font-weight: 600;
+}
+
+.ots-topbar .dropdown-toggle::after {
+ content: '';
+ display: inline-block;
+ margin-left: 6px;
+ width: 0;
+ height: 0;
+ border-left: 4px solid transparent;
+ border-right: 4px solid transparent;
+ border-top: 4px solid currentColor;
+ opacity: 0.6;
+ transition: transform var(--transition-fast);
+}
+
+.ots-topbar .nav-item.open .dropdown-toggle::after {
+ transform: rotate(180deg);
+}
+
+.ots-topbar .dropdown-menu {
+ border-radius: 8px;
+ padding: 6px 0;
+ margin-top: 4px;
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
+ border: 1px solid var(--color-border);
+ background-color: var(--color-surface);
+ min-width: 180px;
+ z-index: 1100;
+}
+
+.ots-topbar .dropdown-item,
+.ots-topbar .dropdown-menu a {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ border-radius: 4px;
+ padding: 8px 14px;
+ color: var(--color-text-secondary);
+ font-size: 14px;
+ font-weight: 500;
+ margin: 2px 6px;
+ transition: all var(--transition-fast);
+}
+
+.ots-topbar .dropdown-item:hover,
+.ots-topbar .dropdown-menu a:hover {
+ background-color: rgba(59, 130, 246, 0.1);
+ color: var(--color-primary);
+}
+
+/* Icon sizing for topbar and nav */
+.ots-topbar-icon {
+ width: 20px;
+ height: 20px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 14px;
+ opacity: 0.9;
+ flex-shrink: 0;
+}
+
+.ots-topbar .dropdown-menu .ots-topbar-icon {
+ font-size: 13px;
+}
+
+/* Left section: toggle, title, nav */
.topbar-left {
display: flex;
align-items: center;
gap: 16px;
flex: 1;
+ min-width: 0;
}
.topbar-toggle {
@@ -262,52 +492,95 @@ body {
color: var(--color-text-primary);
cursor: pointer;
border-radius: 6px;
- transition: background-color var(--transition-fast);
+ transition: all var(--transition-fast);
+ flex-shrink: 0;
}
.topbar-toggle:hover {
- background-color: var(--color-surface);
+ background-color: rgba(59, 130, 246, 0.1);
+}
+
+.topbar-toggle:active {
+ background-color: rgba(59, 130, 246, 0.15);
}
.topbar-toggle .icon {
- width: 24px;
- height: 24px;
+ 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;
- font-size: 24px;
- font-weight: 600;
+ 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;
- font-size: 14px;
- color: var(--color-text-secondary);
+ 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: 24px;
+ gap: 12px;
+ flex-shrink: 0;
}
+/* Search box - 40px height to match button grid */
.topbar-search {
position: relative;
+ height: 40px;
width: 280px;
display: flex;
align-items: center;
background-color: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 6px;
- padding: 8px 12px;
+ 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;
- margin-right: 8px;
+ font-size: 16px;
+ width: 16px;
+ height: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
}
.topbar-search .search-input {
@@ -317,21 +590,28 @@ body {
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: 12px;
+ gap: 4px;
}
+/* Consistent 40px button sizing */
.topbar-btn {
width: 40px;
height: 40px;
+ min-width: 40px;
+ min-height: 40px;
padding: 0;
border: none;
background-color: transparent;
@@ -342,16 +622,25 @@ body {
align-items: center;
justify-content: center;
transition: all var(--transition-fast);
+ position: relative;
}
.topbar-btn:hover {
- background-color: var(--color-surface);
- color: var(--color-text-primary);
+ 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 {
@@ -388,42 +677,187 @@ body {
right: 0;
margin-top: 8px;
background-color: var(--color-surface-elevated);
- border: 1px solid var(--color-border);
- border-radius: 6px;
- box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
+ 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: 160px;
+ min-width: 180px;
display: none;
z-index: 1001;
+ overflow: hidden;
}
.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 theme badge in topbar (authed-theme-topbar.twig) */
+.ots-theme-badge .nav-link {
+ display: inline-flex;
+ align-items: center;
+ padding: 6px 10px;
+ border-radius: 999px;
+ background: rgba(59, 130, 246, 0.12);
+ color: var(--color-text-primary);
+ font-size: 12px;
+ font-weight: 600;
+ letter-spacing: 0.04em;
+ text-transform: uppercase;
+}
+
.dropdown-menu li a {
- display: block;
+ display: flex;
+ align-items: center;
+ gap: 12px;
padding: 10px 16px;
color: var(--color-text-primary);
text-decoration: none;
font-size: 14px;
- transition: background-color var(--transition-fast);
+ transition: all var(--transition-fast);
+ font-weight: 500;
}
.dropdown-menu li a:hover {
- background-color: var(--color-surface);
+ 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;
+}
+
+.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;
@@ -556,11 +990,188 @@ body {
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;
+ flex-direction: column;
+ min-height: 360px;
+ align-items: stretch;
+}
+
+.dashboard-chart-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 16px;
+ width: 100%;
+ box-sizing: border-box;
+ float: none;
+ flex-wrap: wrap;
+ position: static !important;
+ inset: auto !important;
+}
+
+.dashboard-chart-card .widget-title,
+.dashboard-chart-card .widget-body {
+ width: 100%;
+ float: none !important;
+ clear: both;
+ display: block !important;
+ position: static !important;
+}
+
+.dashboard-chart-card .widget-title {
+ flex: 0 0 auto;
+}
+
+.dashboard-chart-card .widget-body {
+ position: relative !important;
+}
+
+.dashboard-chart-title {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+.dashboard-chart-icon {
+ width: 40px;
+ height: 40px;
+ border-radius: 12px;
+ background: rgba(59, 130, 246, 0.18);
+ color: var(--color-primary-light);
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 18px;
+ flex-shrink: 0;
+}
+
+.dashboard-chart-heading {
+ margin: 0;
+ font-size: 16px;
+ font-weight: 700;
+}
+
+.dashboard-chart-subtitle {
+ margin: 4px 0 0;
+ font-size: 12px;
+ color: var(--color-text-secondary);
+}
+
+.dashboard-chart-link {
+ font-size: 12px;
+ font-weight: 600;
+ color: var(--color-primary);
+ text-decoration: none;
+ padding: 6px 10px;
+ border-radius: 999px;
+ border: 1px solid rgba(59, 130, 246, 0.24);
+ background: rgba(59, 130, 246, 0.12);
+ transition: all var(--transition-fast);
+ white-space: nowrap;
+}
+
+.dashboard-chart-link:hover {
+ color: var(--color-text-primary);
+ border-color: rgba(59, 130, 246, 0.5);
+ background: rgba(59, 130, 246, 0.22);
+}
+
+.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 {
+ background: rgba(15, 23, 42, 0.45);
+ border: 1px solid rgba(255, 255, 255, 0.05);
+ border-radius: 12px;
+ padding: 12px;
+ height: clamp(220px, 32vh, 280px);
+ width: 100%;
+ position: relative;
+ overflow: hidden;
+ flex: 1;
+}
+
+.dashboard-chart-canvas canvas {
+ display: block;
+ width: 100% !important;
+ height: 100% !important;
+ max-width: 100% !important;
+ max-height: 100% !important;
+ margin: 0 !important;
+}
+
+.dashboard-chart-card .panel-body canvas,
+.dashboard-chart-card .widget-body canvas {
+ min-height: 0 !important;
+}
+
.panel {
background-color: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 8px;
overflow: hidden;
+ display: flex;
+ flex-direction: column;
+}
+
+/* Force Xibo panels/cards to dark theme (use higher specificity to override core styles) */
+body .panel,
+body .panel.panel-default,
+.panel.panel-white,
+.panel.card,
+.panel.box,
+.widget {
+ background-color: var(--color-surface) !important;
+ color: var(--color-text-primary) !important;
+ border: 1px solid var(--color-border) !important;
+}
+
+body .panel .panel-body,
+body .panel .panel-footer,
+body .panel .panel-heading,
+.panel .panel-header {
+ background-color: transparent !important;
+ color: var(--color-text-primary) !important;
+ border-color: var(--color-border) !important;
+}
+
+body .panel .panel-heading,
+.panel .panel-header {
+ background-color: var(--color-surface-elevated) !important;
+ border-bottom: 1px solid var(--color-border) !important;
+}
+
+/* Tables inside panels should inherit dark background and readable text */
+.panel table,
+.panel table thead,
+.panel table tbody,
+.panel table tr,
+.panel table td,
+.panel table th,
+.panel .dataTables_wrapper {
+ background-color: transparent !important;
+ color: var(--color-text-primary) !important;
+}
+
+/* Card-specific fallbacks */
+.card,
+.card .card-body {
+ background-color: var(--color-surface) !important;
+ color: var(--color-text-primary) !important;
+ border: 1px solid var(--color-border) !important;
}
.panel-full {
@@ -596,6 +1207,10 @@ body {
.panel-body {
padding: 20px;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ min-height: 0;
}
.empty-state-compact {
@@ -668,6 +1283,311 @@ body {
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;
+}
+
+.ots-displays-body {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ flex-direction: column;
+}
+
+.ots-displays-body .XiboGrid {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ flex-direction: column;
+}
+
+.ots-displays-title {
+ font-size: 18px;
+ font-weight: 700;
+ letter-spacing: 0.02em;
+}
+
+.ots-filter-card {
+ background: linear-gradient(180deg, rgba(30, 41, 59, 0.95), rgba(15, 23, 42, 0.92));
+ border: 1px solid rgba(148, 163, 184, 0.22);
+ box-shadow: 0 18px 34px rgba(8, 15, 30, 0.32);
+ margin-bottom: 0;
+ border-radius: 12px;
+ overflow: hidden;
+}
+
+/* Filter header with collapse button */
+.ots-filter-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 14px 16px;
+ border-bottom: 1px solid rgba(148, 163, 184, 0.2);
+ background: rgba(15, 23, 42, 0.3);
+}
+
+.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: 600px;
+ overflow: hidden;
+ transition: max-height 300ms ease-out, padding 300ms ease-out;
+}
+
+.ots-filter-content.collapsed {
+ max-height: 0;
+ padding: 0 16px;
+ overflow: hidden;
+}
+
+.ots-filter-card .nav-tabs {
+ border-bottom: 1px solid rgba(148, 163, 184, 0.2);
+ 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;
+ 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;
+}
+
+.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.1) !important;
+ background: var(--color-surface) !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);
+}
+
+.ots-table-card {
+ padding: 12px 16px 16px;
+ 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;
+}
+
+.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;
+ }
+}
+
.two-column-layout {
display: grid;
grid-template-columns: 280px 1fr;
@@ -827,8 +1747,8 @@ body {
}
.table thead {
- background-color: var(--color-surface-elevated);
- border-bottom: 1px solid var(--color-border);
+ background-color: var(--color-surface);
+ border-bottom: 2px solid var(--color-border);
}
.table thead th {
@@ -838,7 +1758,30 @@ body {
color: var(--color-text-secondary);
text-transform: uppercase;
letter-spacing: 0.05em;
- font-size: 12px;
+ 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 {
@@ -1023,7 +1966,7 @@ body {
}
.form-control::placeholder {
- color: var(--color-text-tertiary);
+ color: var(--color-text-secondary);
}
.form-control:focus {
@@ -1088,9 +2031,638 @@ body {
}
}
+/* ============================================================================
+ 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: block;
+ 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;
+ }
+}
+
+/* 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;
+}
+.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 */
+label,
+.label,
+.form-label,
+legend {
+ color: var(--color-text-primary) !important;
+}
+
+/* Dropdowns, modals, and popovers */
+.dropdown-menu,
+.dropdown-toggle,
+.popover,
+.modal,
+.modal-content,
+.modal-header,
+.modal-body,
+.modal-footer {
+ background-color: var(--color-surface) !important;
+ color: var(--color-text-primary) !important;
+ border: 1px solid var(--color-border) !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 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;
+}
+
+a.text-muted:hover {
+ color: var(--color-text-primary) !important;
+}
+
+/* Ensure absolutely nothing is invisible */
+.hidden,
+[hidden] {
+ display: none !important;
+}
+
+.invisible {
+ visibility: hidden !important;
+}
diff --git a/custom/otssignange/js/theme.js b/custom/otssignange/js/theme.js
index 3cb2b5b..c9a5e3f 100644
--- a/custom/otssignange/js/theme.js
+++ b/custom/otssignange/js/theme.js
@@ -131,6 +131,123 @@
});
}
+ /**
+ * Prevent Chart.js errors when chart elements are missing
+ */
+ function initChartSafeguard() {
+ if (!window.Chart) return;
+
+ if (typeof window.Chart.acquireContext === 'function') {
+ window.Chart.acquireContext = function(item) {
+ if (!item) return null;
+
+ const candidate = item.length ? item[0] : item;
+ if (candidate && typeof candidate.getContext === 'function') {
+ return candidate.getContext('2d');
+ }
+
+ return null;
+ };
+ return;
+ }
+
+ if (window.Chart.prototype && typeof window.Chart.prototype.acquireContext === 'function') {
+ window.Chart.prototype.acquireContext = function(item) {
+ if (!item) return null;
+
+ const candidate = item.length ? item[0] : item;
+ if (candidate && typeof candidate.getContext === 'function') {
+ return candidate.getContext('2d');
+ }
+
+ return null;
+ };
+ }
+ }
+
+ /**
+ * Enhance tables: wrap in card, add per-table search box, client-side filtering
+ * Non-destructive: skips tables already enhanced
+ */
+ function enhanceTables() {
+ const selector = '.ots-content table, .content table, .container table, .card table, table';
+ const tables = Array.from(document.querySelectorAll(selector));
+ let counter = 0;
+
+ tables.forEach(table => {
+ // only enhance tables that have a thead and tbody
+ if (!table || table.classList.contains('modern-table')) return;
+ if (!table.querySelector('thead') || !table.querySelector('tbody')) return;
+
+ counter += 1;
+ table.classList.add('modern-table');
+
+ // Build wrapper structure
+ const wrapper = document.createElement('div');
+ wrapper.className = 'modern-table-card';
+
+ const controls = document.createElement('div');
+ controls.className = 'table-controls';
+
+ const input = document.createElement('input');
+ input.type = 'search';
+ input.placeholder = 'Search…';
+ input.className = 'table-search-input';
+ input.setAttribute('aria-label', 'Table search');
+ input.style.minWidth = '180px';
+
+ controls.appendChild(input);
+
+ const tableWrapper = document.createElement('div');
+ tableWrapper.className = 'table-wrapper';
+ tableWrapper.style.overflow = 'auto';
+
+ // Insert wrapper into DOM in place of the table
+ const parent = table.parentNode;
+ parent.replaceChild(wrapper, table);
+ wrapper.appendChild(controls);
+ wrapper.appendChild(tableWrapper);
+ tableWrapper.appendChild(table);
+
+ // Simple, light-weight search filtering for this table only
+ input.addEventListener('input', function (e) {
+ const term = (e.target.value || '').toLowerCase();
+ table.querySelectorAll('tbody tr').forEach(tr => {
+ const text = tr.textContent.toLowerCase();
+ tr.style.display = term === '' || text.includes(term) ? '' : 'none';
+ });
+ });
+ });
+ }
+
+ /**
+ * Initialize DataTables for enhanced behavior when available.
+ * Falls back gracefully if DataTables or jQuery are not present.
+ */
+ function initDataTables() {
+ if (!window.jQuery) return;
+ const $ = window.jQuery;
+ if (!$.fn || !$.fn.dataTable) return;
+
+ $('.modern-table, table').each(function () {
+ try {
+ if (!$.fn.dataTable.isDataTable(this)) {
+ $(this).DataTable({
+ responsive: true,
+ lengthChange: false,
+ pageLength: 10,
+ autoWidth: false,
+ dom: '<"table-controls"f>rt<"table-meta"ip>',
+ language: { search: '' }
+ });
+ }
+ } catch (err) {
+ // If initialization fails, ignore and allow fallback enhancer
+ console.warn('DataTables init failed for table', this, err);
+ }
+ });
+ }
+
/**
* Initialize all features when DOM is ready
*/
@@ -139,35 +256,13 @@
initDropdowns();
initSearch();
initPageInteractions();
+ initDataTables();
+ enhanceTables();
makeResponsive();
+ initChartSafeguard();
}
// Wait for DOM to be ready
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', init);
- } else {
- init();
- }
-})();
-
- themeBtn.addEventListener('click', function() {
- const currentTheme = html.getAttribute('data-theme') || 'light';
- const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
-
- html.setAttribute('data-theme', newTheme);
- localStorage.setItem(STORAGE_KEYS.themeMode, newTheme);
- themeBtn.setAttribute('aria-pressed', newTheme === 'dark');
- });
- }
-
- /**
- * Initialize page on DOM ready
- */
- function init() {
- initSidebarToggle();
- initThemeToggle();
- }
-
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
diff --git a/custom/otssignange/views/authed-sidebar.twig b/custom/otssignange/views/authed-sidebar.twig
index 4c92876..b351ddf 100644
--- a/custom/otssignange/views/authed-sidebar.twig
+++ b/custom/otssignange/views/authed-sidebar.twig
@@ -1,116 +1,356 @@
-{#
- OTS Signage Modern Theme - Sidebar Override
- Modern left navigation sidebar with collapsible state and icons
-#}
-