diff --git a/src/assets/scripts/app.js b/src/assets/scripts/app.js
index 1359a94..fd7b75b 100644
--- a/src/assets/scripts/app.js
+++ b/src/assets/scripts/app.js
@@ -1,6 +1,6 @@
/**
* Modern Adminator Application
- * Main application entry point - replaces jQuery-based initialization
+ * Main application entry point with enhanced mobile support
*/
import bootstrap from 'bootstrap';
@@ -24,7 +24,6 @@ import './vectorMaps';
import './chat';
import './email';
import './googleMaps';
-import './utils';
class AdminatorApp {
constructor() {
@@ -43,7 +42,7 @@ class AdminatorApp {
init() {
if (this.isInitialized) return;
- console.log('๐ Initializing Adminator App (Modern Version)');
+ console.log('๐ Initializing Adminator App (Mobile Optimized)');
try {
// Initialize core components
@@ -52,6 +51,7 @@ class AdminatorApp {
this.initDataTables();
this.initDatePickers();
this.initTheme();
+ this.initMobileEnhancements();
// Setup global event listeners
this.setupGlobalEvents();
@@ -201,97 +201,107 @@ class AdminatorApp {
try {
picker.showPicker();
} catch (e) {
- // Fallback for browsers that don't support showPicker
console.log('๐
Date picker opened via icon click');
}
}
});
-
- // Also make the entire icon container clickable
- const iconContainer = inputGroup.querySelector('.input-group-text');
- if (iconContainer) {
- iconContainer.style.cursor = 'pointer';
- DOM.on(iconContainer, 'click', (event) => {
- event.preventDefault();
- event.stopPropagation();
- picker.focus();
- if (picker.showPicker && typeof picker.showPicker === 'function') {
- try {
- picker.showPicker();
- } catch (e) {
- console.log('๐
Date picker opened via icon container click');
- }
- }
- });
- }
}
}
});
-
- // Add date validation
- [...startDatePickers, ...endDatePickers].forEach(picker => {
- DOM.on(picker, 'change', (event) => {
- const isValid = DateUtils.form.validateDateInput(event.target.value);
- if (!isValid) {
- event.target.classList.add('is-invalid');
- console.warn('Invalid date format:', event.target.value);
- } else {
- event.target.classList.remove('is-invalid');
- console.log('Valid date selected:', DateUtils.formatters.shortDate(event.target.value));
- }
- });
-
- // Add focus/blur handlers for better UX
- DOM.on(picker, 'focus', () => {
- picker.classList.add('focus');
- });
-
- DOM.on(picker, 'blur', () => {
- picker.classList.remove('focus');
- });
- });
}
/**
- * Initialize theme
+ * Initialize theme system with toggle
*/
initTheme() {
+ console.log('๐ Initializing theme system');
+
+ // Initialize theme system first
Theme.init();
-
- // inject toggle switch if missing
- const navRight = document.querySelector('.nav-right');
- if (navRight && !document.getElementById('theme-toggle')) {
+
+ // Inject theme toggle if missing - with retry mechanism
+ setTimeout(() => {
+ const navRight = DOM.select('.nav-right');
+ console.log('๐ nav-right found:', !!navRight);
+ console.log('๐ navRight element:', navRight);
+ console.log('๐ theme-toggle exists:', DOM.exists('#theme-toggle'));
+ console.log('๐ All nav-right li elements:', navRight ? navRight.querySelectorAll('li').length : 0);
+
+ // Debug the DOM structure
+ if (navRight) {
+ console.log('๐ navRight children:', Array.from(navRight.children).map(child => ({
+ tagName: child.tagName,
+ className: child.className,
+ id: child.id
+ })));
+ }
+
+ if (navRight && !DOM.exists('#theme-toggle')) {
const li = document.createElement('li');
li.className = 'theme-toggle d-flex ai-c';
li.innerHTML = `
`;
- navRight.insertBefore(li, navRight.firstElementChild);
-
- const toggleInput = li.querySelector('#theme-toggle');
-
- const updateSwitch = () => {
- toggleInput.checked = Theme.current() === 'dark';
- };
- updateSwitch();
-
- toggleInput.addEventListener('change', (e) => {
- Theme.apply(e.target.checked ? 'dark' : 'light');
- });
+
+ // Insert before user dropdown (last item) - safer approach
+ const lastItem = navRight.querySelector('li:last-child');
+ console.log('๐ lastItem found:', !!lastItem);
+ console.log('๐ lastItem parent:', lastItem ? lastItem.parentNode : null);
+ console.log('๐ navRight:', navRight);
+
+ if (lastItem && lastItem.parentNode === navRight) {
+ navRight.insertBefore(li, lastItem);
+ console.log('โ
Theme toggle inserted before last item');
+ } else {
+ navRight.appendChild(li);
+ console.log('โ
Theme toggle appended to nav-right (safer approach)');
+ }
+
+ // Add toggle functionality
+ const toggle = DOM.select('#theme-toggle');
+ if (toggle) {
+ // Set initial state
+ const currentTheme = Theme.current();
+ toggle.checked = currentTheme === 'dark';
+
+ DOM.on(toggle, 'change', () => {
+ Theme.apply(toggle.checked ? 'dark' : 'light');
+ });
+
+ // Listen for theme changes from other sources
+ window.addEventListener('adminator:themeChanged', (event) => {
+ toggle.checked = event.detail.theme === 'dark';
+
+ // Update charts when theme changes
+ const charts = this.components.get('charts');
+ if (charts) charts.redrawCharts();
+ });
+ }
+ } else {
+ console.log('โ No nav-right found or theme-toggle already exists');
+ }
+ }, 100); // Wait 100ms for DOM to be fully ready
+ }
- window.addEventListener('adminator:themeChanged', () => {
- updateSwitch();
- const charts = this.components.get('charts');
- if (charts) charts.redrawCharts();
- });
+ /**
+ * Initialize mobile-specific enhancements
+ */
+ initMobileEnhancements() {
+ console.log('๐ฑ Initializing mobile enhancements');
+ this.enhanceMobileDropdowns();
+ this.enhanceMobileSearch();
+
+ // Prevent horizontal scroll on mobile
+ if (this.isMobile()) {
+ document.body.style.overflowX = 'hidden';
}
}
@@ -299,55 +309,312 @@ class AdminatorApp {
* Setup global event listeners
*/
setupGlobalEvents() {
- // Global resize handler
- let resizeTimer;
- window.addEventListener('resize', () => {
- clearTimeout(resizeTimer);
- resizeTimer = setTimeout(() => {
- this.handleResize();
- }, 150);
- });
-
- // Global click handler for dynamic content
- document.addEventListener('click', (e) => {
- this.handleGlobalClick(e);
+ // Global click handler
+ DOM.on(document, 'click', (event) => this.handleGlobalClick(event));
+
+ // Window resize handler with debouncing
+ let resizeTimeout;
+ DOM.on(window, 'resize', () => {
+ clearTimeout(resizeTimeout);
+ resizeTimeout = setTimeout(() => this.handleResize(), 250);
});
-
- // Custom event for masonry recalculation
- window.EVENT = new Event('resize');
+
+ console.log('๐ Global event listeners set up');
}
/**
- * Handle window resize
+ * Handle window resize events
*/
handleResize() {
- // Notify charts to resize
- const charts = this.components.get('charts');
- if (charts) {
- charts.redrawCharts();
+ console.log('๐ Window resized, updating mobile features');
+
+ // Close all mobile-specific overlays when switching to desktop
+ if (!this.isMobile()) {
+ document.body.style.overflow = '';
+ document.body.style.overflowX = '';
+
+ // Close dropdowns
+ const dropdowns = DOM.selectAll('.nav-right .dropdown');
+ dropdowns.forEach(dropdown => {
+ dropdown.classList.remove('show');
+ const menu = dropdown.querySelector('.dropdown-menu');
+ if (menu) menu.classList.remove('show');
+ });
+
+ // Close search
+ const searchBox = DOM.select('.search-box');
+ const searchInput = DOM.select('.search-input');
+ if (searchBox && searchInput) {
+ searchBox.classList.remove('active');
+ searchInput.classList.remove('active');
+ }
+ } else {
+ // Re-enable mobile overflow protection
+ document.body.style.overflowX = 'hidden';
}
-
- // Dispatch resize event for other components
- window.dispatchEvent(new CustomEvent('adminator:resize'));
+
+ // Re-apply mobile enhancements
+ this.enhanceMobileDropdowns();
+ this.enhanceMobileSearch();
}
/**
- * Handle global clicks
+ * Handle global click events
*/
handleGlobalClick(event) {
- // Handle any global click events here
- // This can be used for analytics, debugging, etc.
+ // Close mobile dropdowns when clicking outside
+ if (!event.target.closest('.dropdown')) {
+ const dropdowns = DOM.selectAll('.nav-right .dropdown');
+ dropdowns.forEach(dropdown => {
+ dropdown.classList.remove('show');
+ const menu = dropdown.querySelector('.dropdown-menu');
+ if (menu) menu.classList.remove('show');
+ });
+ document.body.style.overflow = '';
+ }
+
+ // Close search when clicking outside
+ if (!event.target.closest('.search-box') && !event.target.closest('.search-input')) {
+ const searchBox = DOM.select('.search-box');
+ const searchInput = DOM.select('.search-input');
+ if (searchBox && searchInput) {
+ searchBox.classList.remove('active');
+ searchInput.classList.remove('active');
+ document.body.style.overflow = '';
+ document.body.classList.remove('mobile-menu-open');
+ }
+ }
+ }
+
+ /**
+ * Check if we're on a mobile device
+ */
+ isMobile() {
+ return window.innerWidth <= 768;
}
/**
- * Get component instance
+ * Enhanced mobile dropdown handling with improved email layout
+ */
+ enhanceMobileDropdowns() {
+ if (!this.isMobile()) return;
+
+ const dropdowns = DOM.selectAll('.nav-right .dropdown');
+
+ dropdowns.forEach(dropdown => {
+ const toggle = dropdown.querySelector('.dropdown-toggle');
+ const menu = dropdown.querySelector('.dropdown-menu');
+
+ if (toggle && menu) {
+ // Remove existing listeners to prevent duplicates
+ const newToggle = toggle.cloneNode(true);
+ toggle.replaceWith(newToggle);
+
+ // Add click functionality for mobile dropdowns
+ DOM.on(newToggle, 'click', (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+
+ // Close search if open
+ const searchBox = DOM.select('.search-box');
+ const searchInput = DOM.select('.search-input');
+ if (searchBox && searchInput) {
+ searchBox.classList.remove('active');
+ searchInput.classList.remove('active');
+ }
+
+ // Close other dropdowns first
+ dropdowns.forEach(otherDropdown => {
+ if (otherDropdown !== dropdown) {
+ otherDropdown.classList.remove('show');
+ const otherMenu = otherDropdown.querySelector('.dropdown-menu');
+ if (otherMenu) otherMenu.classList.remove('show');
+ }
+ });
+
+ // Toggle current dropdown
+ const isOpen = dropdown.classList.contains('show');
+ if (isOpen) {
+ dropdown.classList.remove('show');
+ menu.classList.remove('show');
+ document.body.style.overflow = '';
+ document.body.classList.remove('mobile-menu-open');
+ } else {
+ dropdown.classList.add('show');
+ menu.classList.add('show');
+ document.body.style.overflow = 'hidden';
+ document.body.classList.add('mobile-menu-open');
+ }
+ });
+
+ // Enhanced mobile close button functionality
+ DOM.on(menu, 'click', (e) => {
+ // Check if clicked on the close area (::before pseudo-element area)
+ const rect = menu.getBoundingClientRect();
+ const clickY = e.clientY - rect.top;
+
+ // If clicked in top 50px (close button area)
+ if (clickY <= 50) {
+ dropdown.classList.remove('show');
+ menu.classList.remove('show');
+ document.body.style.overflow = '';
+ document.body.classList.remove('mobile-menu-open');
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ });
+ }
+ });
+
+ // Close dropdowns on escape key
+ DOM.on(document, 'keydown', (e) => {
+ if (e.key === 'Escape') {
+ dropdowns.forEach(dropdown => {
+ dropdown.classList.remove('show');
+ const menu = dropdown.querySelector('.dropdown-menu');
+ if (menu) menu.classList.remove('show');
+ });
+ document.body.style.overflow = '';
+ document.body.classList.remove('mobile-menu-open');
+ }
+ });
+ }
+
+ /**
+ * Enhanced mobile search handling - Full-width search bar
+ */
+ enhanceMobileSearch() {
+ const searchBox = DOM.select('.search-box');
+ const searchInput = DOM.select('.search-input');
+
+ if (searchBox && searchInput) {
+ const searchToggle = searchBox.querySelector('a');
+ const searchField = searchInput.querySelector('input');
+
+ if (searchToggle && searchField) {
+ console.log('๐ Setting up full-width search functionality');
+
+ // Remove existing listeners to prevent duplication
+ const newSearchToggle = searchToggle.cloneNode(true);
+ searchToggle.replaceWith(newSearchToggle);
+
+ DOM.on(newSearchToggle, 'click', (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+
+ console.log('๐ Full-width search toggle clicked');
+
+ // Close any open dropdowns first
+ const dropdowns = DOM.selectAll('.nav-right .dropdown');
+ dropdowns.forEach(dropdown => {
+ dropdown.classList.remove('show');
+ const menu = dropdown.querySelector('.dropdown-menu');
+ if (menu) menu.classList.remove('show');
+ });
+
+ // Toggle search state
+ const isActive = searchInput.classList.contains('active');
+ const searchIcon = newSearchToggle.querySelector('i');
+
+ if (isActive) {
+ // Close search
+ searchInput.classList.remove('active');
+ document.body.classList.remove('search-open');
+
+ // Change icon back to search
+ if (searchIcon) {
+ searchIcon.className = 'ti-search';
+ }
+
+ // Clear input
+ if (searchField) {
+ searchField.value = '';
+ searchField.blur();
+ }
+
+ console.log('๐ Full-width search closed');
+ } else {
+ // Open search
+ searchInput.classList.add('active');
+ document.body.classList.add('search-open');
+
+ // Change icon to close
+ if (searchIcon) {
+ searchIcon.className = 'ti-close';
+ }
+
+ // Focus the input after a short delay
+ setTimeout(() => {
+ if (searchField) {
+ searchField.focus();
+ console.log('๐ Search field focused');
+ }
+ }, 100);
+
+ console.log('๐ Full-width search opened');
+ }
+ });
+
+ // Close search on escape
+ DOM.on(document, 'keydown', (e) => {
+ if (e.key === 'Escape' && searchInput.classList.contains('active')) {
+ searchInput.classList.remove('active');
+ document.body.classList.remove('search-open');
+
+ // Reset icon
+ const searchIcon = newSearchToggle.querySelector('i');
+ if (searchIcon) {
+ searchIcon.className = 'ti-search';
+ }
+
+ // Clear input
+ if (searchField) {
+ searchField.value = '';
+ searchField.blur();
+ }
+
+ console.log('๐ Full-width search closed via escape');
+ }
+ });
+
+ // Handle search input
+ DOM.on(searchField, 'keypress', (e) => {
+ if (e.key === 'Enter') {
+ e.preventDefault();
+ const query = searchField.value.trim();
+ if (query) {
+ console.log('๐ Search query:', query);
+ // Implement your search logic here
+
+ // For demo, close search after "searching"
+ searchInput.classList.remove('active');
+ document.body.classList.remove('search-open');
+
+ const searchIcon = newSearchToggle.querySelector('i');
+ if (searchIcon) {
+ searchIcon.className = 'ti-search';
+ }
+
+ searchField.value = '';
+ searchField.blur();
+ }
+ }
+ });
+
+ console.log('๐ Full-width search functionality initialized');
+ }
+ }
+ }
+
+ /**
+ * Get a component by name
*/
getComponent(name) {
return this.components.get(name);
}
/**
- * Check if app is initialized
+ * Check if app is ready
*/
isReady() {
return this.isInitialized;
@@ -357,45 +624,42 @@ class AdminatorApp {
* Destroy the application
*/
destroy() {
+ console.log('๐๏ธ Destroying Adminator App');
+
// Destroy all components
this.components.forEach((component, name) => {
if (typeof component.destroy === 'function') {
component.destroy();
}
+ console.log(`๐๏ธ ${name} component destroyed`);
});
this.components.clear();
this.isInitialized = false;
-
- console.log('๐งน Adminator App destroyed');
}
/**
- * Refresh all components (useful for dynamic content)
+ * Refresh/reinitialize the application
*/
refresh() {
console.log('๐ Refreshing Adminator App');
- // Refresh sidebar active links
- const sidebar = this.components.get('sidebar');
- if (sidebar) {
- sidebar.refreshActiveLink();
- }
-
- // Reinitialize charts if needed
- const charts = this.components.get('charts');
- if (charts) {
- charts.redrawCharts();
+ if (this.isInitialized) {
+ this.destroy();
}
+
+ setTimeout(() => {
+ this.init();
+ }, 100);
}
-
-
}
-// Create global app instance
+// Initialize the application
+console.log('๐ฑ Starting Adminator (Mobile Optimized)');
const app = new AdminatorApp();
-// Export for external access
+// Make app globally available for debugging
window.AdminatorApp = app;
+// Export for module usage
export default app;
\ No newline at end of file
diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss
index dee00cf..bd01c1d 100755
--- a/src/assets/styles/index.scss
+++ b/src/assets/styles/index.scss
@@ -4,6 +4,7 @@
@use 'spec/index' as *;
@use 'vendor/index' as *;
@import "utils/theme.css";
+@import "utils/mobile.scss";
body {
background: var(--c-bkg-body);
@@ -83,6 +84,118 @@ body {
}
}
}
+
+ // Mobile theme toggle adjustments
+ @media (max-width: 991px) {
+ padding: 0 6px;
+ height: 65px;
+
+ .form-check {
+ .form-check-label {
+ font-size: 10px;
+
+ &:first-child {
+ margin-right: 4px;
+ }
+
+ &:last-child {
+ margin-left: 4px;
+ }
+ }
+
+ .form-check-input {
+ width: 2rem;
+ height: 1rem;
+ }
+ }
+ }
+
+ // Very small mobile adjustments
+ @media (max-width: 480px) {
+ padding: 0 4px;
+
+ .form-check {
+ flex-direction: column;
+ align-items: center;
+ text-align: center;
+
+ .form-check-label {
+ font-size: 8px;
+ margin: 1px 0;
+ white-space: nowrap;
+
+ i {
+ margin: 0 2px;
+ }
+ }
+
+ .form-check-input {
+ width: 1.5rem;
+ height: 0.8rem;
+ margin: 2px 0;
+ }
+ }
+ }
+ }
+}
+
+// Mobile dropdown menu improvements
+@media (max-width: 767px) {
+ .header {
+ .nav-right {
+ .dropdown-menu {
+ position: fixed !important;
+ top: 65px !important;
+ left: 5px !important;
+ right: 5px !important;
+ width: auto !important;
+ max-width: none !important;
+ min-width: auto !important;
+ transform: none !important;
+ z-index: 1050;
+ border-radius: 8px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ max-height: calc(100vh - 85px);
+ overflow-y: auto;
+ }
+
+ .notifications .dropdown-menu {
+ max-height: calc(100vh - 85px);
+ overflow-y: auto;
+ }
+ }
+ }
+}
+
+// Mobile search input overlay
+@media (max-width: 480px) {
+ .header {
+ .search-input {
+ &.active {
+ position: absolute;
+ top: 65px;
+ left: 0;
+ right: 0;
+ background: var(--c-bkg-card);
+ border-top: 1px solid var(--c-border);
+ padding: 10px;
+ z-index: 999;
+
+ input {
+ margin-top: 0;
+ width: 100%;
+ padding: 10px;
+ border: 1px solid var(--c-border);
+ border-radius: 4px;
+ background: var(--c-bkg-card);
+ color: var(--c-text-base);
+
+ &::placeholder {
+ color: var(--c-text-muted);
+ }
+ }
+ }
+ }
}
}
diff --git a/src/assets/styles/spec/components/pageContainer.scss b/src/assets/styles/spec/components/pageContainer.scss
index 44159f0..4589d47 100755
--- a/src/assets/styles/spec/components/pageContainer.scss
+++ b/src/assets/styles/spec/components/pageContainer.scss
@@ -10,15 +10,20 @@
// + @Main Content
// + @Full Container
// + @Collapsed State
+// + @Mobile Layout Fixes
// ---------------------------------------------------------
-// @Page Container
+// @Page Container - MODERN LAYOUT APPROACH
// ---------------------------------------------------------
.page-container {
min-height: 100vh;
padding-left: $offscreen-size;
transition: all 0.2s ease;
+
+ // Modern flexbox layout to prevent footer overlap
+ display: flex;
+ flex-direction: column;
@include between($breakpoint-md, $breakpoint-xl) {
padding-left: $collapsed-size;
@@ -30,16 +35,30 @@
}
// ---------------------------------------------------------
-// @Main Content
+// @Main Content - FLEXIBLE LAYOUT
// ---------------------------------------------------------
.main-content {
padding: 85px 20px 20px;
- min-height: calc(100vh - 61px);
+
+ // Flex-grow to push footer to bottom
+ flex: 1 0 auto;
+ min-height: 0; // Allow flex shrinking
+
+ // Ensure content doesn't overflow
+ overflow-x: hidden;
@include to($breakpoint-md) {
padding: 85px 5px 5px;
}
+
+ @include to($breakpoint-sm) {
+ padding: 85px 10px 30px; // Extra bottom padding on mobile
+ }
+
+ @include to(400px) {
+ padding: 85px 5px 40px; // Even more bottom padding on tiny screens
+ }
}
.remain-height {
@@ -68,6 +87,142 @@
}
}
+// ---------------------------------------------------------
+// @Mobile Layout Fixes - AGGRESSIVE FOOTER SOLUTION
+// ---------------------------------------------------------
+
+// Footer - completely redesigned for mobile
+footer {
+ // Flex-shrink: 0 to prevent compression
+ flex: 0 0 auto;
+
+ // Positioning
+ position: relative;
+ z-index: 1;
+
+ // Styling
+ margin-top: auto;
+ padding: 20px;
+ text-align: center;
+ border-top: 1px solid var(--c-border);
+ background: var(--c-bkg-card);
+ color: var(--c-text-muted);
+ font-size: 12px;
+ line-height: 1.4;
+
+ // Prevent any potential overflow
+ word-wrap: break-word;
+ overflow-wrap: break-word;
+
+ // Tablet footer adjustments
+ @include to($breakpoint-md) {
+ padding: 18px 15px;
+ font-size: 11px;
+ }
+
+ // Mobile footer adjustments
+ @include to($breakpoint-sm) {
+ padding: 15px 10px;
+ font-size: 10px;
+ line-height: 1.3;
+
+ span {
+ display: inline-block;
+ max-width: 100%;
+
+ a {
+ color: var(--c-primary);
+ text-decoration: none;
+ word-break: break-word;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+ }
+ }
+
+ // Tiny screen footer adjustments
+ @include to(400px) {
+ padding: 12px 8px;
+ font-size: 9px;
+ line-height: 1.2;
+
+ span {
+ display: block;
+
+ // Break long text on new lines for readability
+ &::after {
+ content: "";
+ display: block;
+ height: 2px;
+ }
+ }
+ }
+}
+
+// Ensure body and html take full height for flex layout
+html, body {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+// Global mobile overflow prevention
+@include to($breakpoint-sm) {
+ body {
+ overflow-x: hidden;
+ }
+
+ // Prevent any element from causing horizontal scroll
+ * {
+ max-width: 100%;
+ box-sizing: border-box;
+ }
+}
+
+// Additional mobile content spacing
+@include to($breakpoint-sm) {
+ .page-container {
+ .main-content {
+ // Extra margin-bottom to ensure footer never overlaps
+ margin-bottom: 20px;
+
+ // Responsive content adjustments
+ .row {
+ margin-left: 0;
+ margin-right: 0;
+ }
+
+ .col-md-6, .col-md-3, .col-md-12 {
+ padding-left: 5px;
+ padding-right: 5px;
+ }
+ }
+ }
+}
+
+// Emergency footer overlap prevention
+@include to(480px) {
+ .page-container {
+ // Force minimum height that accounts for content
+ min-height: calc(100vh - 80px);
+
+ .main-content {
+ // Ensure there's always space for footer
+ padding-bottom: 60px !important;
+ margin-bottom: 20px !important;
+ }
+ }
+
+ footer {
+ // Stick to bottom on very small screens
+ position: relative;
+ margin-top: auto;
+ clear: both;
+ }
+}
+
// ---------------------------------------------------------
// @Collapsed State
// ---------------------------------------------------------
diff --git a/src/assets/styles/spec/components/topbar.scss b/src/assets/styles/spec/components/topbar.scss
index 25d3b80..9183b8c 100755
--- a/src/assets/styles/spec/components/topbar.scss
+++ b/src/assets/styles/spec/components/topbar.scss
@@ -10,6 +10,7 @@
// + @Topbar
// + @Collapsed State
+// + @Mobile Responsive Fixes
// ---------------------------------------------------------
// @Topbar
@@ -195,6 +196,244 @@
}
}
+// ---------------------------------------------------------
+// @Mobile Responsive Fixes - AGGRESSIVE APPROACH
+// ---------------------------------------------------------
+
+// Tablet mobile fixes (768px to 991px)
+@include to($breakpoint-md) {
+ .header {
+ .header-container {
+ padding: 0 10px;
+
+ .nav-left {
+ margin-left: 5px;
+
+ > li > a {
+ padding: 0 8px !important;
+ }
+ }
+
+ .nav-right {
+ margin-right: 5px;
+
+ > li {
+ > a {
+ padding: 0 8px !important;
+
+ // Hide text in user dropdown on tablet
+ .peer:last-child {
+ display: none;
+ }
+ }
+ }
+
+ // Make theme toggle more compact
+ .theme-toggle {
+ padding: 0 5px !important;
+
+ .form-check-label {
+ font-size: 9px !important;
+ margin: 0 3px !important;
+ }
+
+ .form-check-input {
+ width: 1.8rem !important;
+ height: 1rem !important;
+ }
+ }
+ }
+ }
+ }
+}
+
+// Small mobile phones (576px to 767px)
+@include to($breakpoint-sm) {
+ .header {
+ .header-container {
+ height: auto;
+ min-height: $header-height;
+ padding: 0 5px;
+
+ .nav-left {
+ margin-left: 2px;
+
+ > li > a {
+ padding: 0 5px !important;
+ }
+
+ // Hide search toggle on small mobile - make it icon only when active
+ .search-box:not(.active) {
+ display: none;
+ }
+ }
+
+ .nav-right {
+ margin-right: 2px;
+
+ > li {
+ > a {
+ padding: 0 4px !important;
+
+ // Hide all text content, keep only icons
+ span {
+ display: none;
+ }
+
+ .peer:last-child {
+ display: none;
+ }
+ }
+ }
+
+ // Ultra-compact theme toggle
+ .theme-toggle {
+ padding: 0 3px !important;
+
+ .form-check {
+ flex-direction: column;
+ align-items: center;
+
+ .form-check-label {
+ font-size: 7px !important;
+ margin: 0 !important;
+ line-height: 1 !important;
+
+ span {
+ display: none !important;
+ }
+ }
+
+ .form-check-input {
+ width: 1.5rem !important;
+ height: 0.8rem !important;
+ margin: 1px 0 !important;
+ }
+ }
+ }
+ }
+
+ // Full-screen mobile dropdowns
+ .nav-right .dropdown-menu {
+ position: fixed !important;
+ top: $header-height !important;
+ left: 0 !important;
+ right: 0 !important;
+ bottom: 0 !important;
+ width: 100vw !important;
+ height: calc(100vh - #{$header-height}) !important;
+ max-width: none !important;
+ min-width: auto !important;
+ transform: none !important;
+ border-radius: 0 !important;
+ z-index: 9999;
+ overflow-y: auto;
+
+ // Close button for mobile dropdowns
+ &::before {
+ content: "โ Close";
+ position: sticky;
+ top: 0;
+ display: block;
+ background: var(--c-primary);
+ color: white;
+ text-align: center;
+ padding: 10px;
+ cursor: pointer;
+ font-weight: bold;
+ z-index: 10000;
+ }
+ }
+ }
+ }
+}
+
+// Extra small mobile phones (less than 576px)
+@include to(480px) {
+ .header {
+ .header-container {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex-wrap: nowrap;
+ padding: 0 2px;
+
+ .nav-left {
+ flex: 0 0 auto;
+ margin: 0;
+
+ > li {
+ float: none;
+ display: inline-block;
+
+ > a {
+ padding: 0 3px !important;
+ font-size: 14px !important;
+ }
+ }
+
+ // Search overlay for tiny screens
+ .search-input.active {
+ position: fixed;
+ top: $header-height;
+ left: 0;
+ right: 0;
+ background: var(--c-bkg-card);
+ border-top: 1px solid var(--c-border);
+ padding: 15px;
+ z-index: 9998;
+
+ input {
+ width: 100%;
+ padding: 12px;
+ font-size: 16px;
+ border: 1px solid var(--c-border);
+ border-radius: 6px;
+ background: var(--c-bkg-card);
+ color: var(--c-text-base);
+ margin-top: 0;
+
+ &::placeholder {
+ color: var(--c-text-muted);
+ }
+ }
+ }
+ }
+
+ .nav-right {
+ flex: 0 0 auto;
+ margin: 0;
+
+ > li {
+ float: none;
+ display: inline-block;
+
+ > a {
+ padding: 0 2px !important;
+ font-size: 12px !important;
+ }
+ }
+
+ // Minimal theme toggle
+ .theme-toggle {
+ padding: 0 1px !important;
+
+ .form-check {
+ .form-check-label {
+ display: none !important;
+ }
+
+ .form-check-input {
+ width: 1.2rem !important;
+ height: 0.7rem !important;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
// ---------------------------------------------------------
// @Collapsed State
// ---------------------------------------------------------
@@ -212,3 +451,5 @@
}
}
}
+
+
diff --git a/src/assets/styles/utils/mobile.scss b/src/assets/styles/utils/mobile.scss
new file mode 100644
index 0000000..14d4352
--- /dev/null
+++ b/src/assets/styles/utils/mobile.scss
@@ -0,0 +1,954 @@
+// Mobile Utility Classes and Fixes
+// This file contains mobile-specific utility classes and responsive fixes
+
+// Mobile text utilities - Only hide theme labels on very small screens
+@media (max-width: 480px) {
+ .theme-toggle .form-check-label {
+ display: none !important;
+ }
+
+ .theme-toggle {
+ padding: 0 6px !important;
+ height: 60px !important; // Match header height
+ justify-content: center !important;
+ min-height: 60px !important;
+
+ .form-check {
+ height: 100% !important;
+
+ .form-check-label {
+ font-size: 11px !important; // Slightly smaller for very small screens
+ font-weight: 500 !important;
+
+ i {
+ font-size: 14px !important; // Still reasonable for tiny screens
+ }
+ }
+
+ .form-check-input {
+ margin: 0 6px !important;
+ width: 38px !important; // Bigger than before but not huge for tiny screens
+ height: 22px !important; // Bigger than before but not huge for tiny screens
+ border-radius: 11px !important;
+ border-width: 2px !important;
+ }
+ }
+ }
+
+ // Very small screen adjustments
+ .d-none-xs {
+ display: none !important;
+ }
+
+ .fs-xs {
+ font-size: 10px !important;
+ }
+
+ .p-xs {
+ padding: 5px !important;
+ }
+
+ .m-xs {
+ margin: 5px !important;
+ }
+}
+
+// Mobile dropdown improvements
+@media (max-width: 767px) {
+ .dropdown-menu {
+ // Ensure all dropdowns are mobile-friendly
+ &.show {
+ position: fixed !important;
+ top: 65px !important;
+ left: 5px !important;
+ right: 5px !important;
+ width: auto !important;
+ transform: none !important;
+ z-index: 1050;
+ max-height: calc(100vh - 85px);
+ overflow-y: auto;
+ }
+ }
+
+ // Mobile notification improvements
+ .notifications .dropdown-menu {
+ .scrollable {
+ max-height: 300px;
+ overflow-y: auto;
+ }
+ }
+}
+
+// Mobile header compact mode
+@media (max-width: 991px) {
+ .header .nav-right > li > a {
+ padding: 0 6px !important;
+ }
+
+ .header .nav-left > li > a {
+ padding: 0 8px !important;
+ }
+}
+
+// Ultra-compact mode for very small screens
+@media (max-width: 480px) {
+ .header .nav-right > li > a {
+ padding: 0 4px !important;
+ font-size: 14px !important;
+ }
+
+ .header .nav-left > li > a {
+ padding: 0 6px !important;
+ }
+
+ // Hide search on very small screens when not active
+ .search-box:not(.active) {
+ display: none !important;
+ }
+}
+
+// Mobile-specific spacing utilities
+.mobile-compact {
+ @media (max-width: 767px) {
+ padding: 5px !important;
+ margin: 2px !important;
+ }
+}
+
+.mobile-hidden {
+ @media (max-width: 767px) {
+ display: none !important;
+ }
+}
+
+.mobile-only {
+ display: none !important;
+
+ @media (max-width: 767px) {
+ display: block !important;
+ }
+}
+
+// Prevent horizontal scroll on mobile
+.mobile-no-scroll {
+ @media (max-width: 767px) {
+ overflow-x: hidden !important;
+ }
+}
+
+// COMPREHENSIVE Mobile Header Fixes
+// Better layout, bigger icons, full-width search, and desktop fixes
+
+// =============================================================================
+// DESKTOP FIXES - Remove top spacing issue
+// =============================================================================
+
+@media screen and (min-width: 768px) {
+ .header {
+ margin-top: 0 !important;
+ top: 0 !important;
+ }
+
+ .page-container {
+ padding-top: 61px !important; // Standard header height + 1px border
+ }
+
+ .main-content {
+ margin-top: 0 !important;
+ padding-top: 20px !important;
+ }
+
+ // DESKTOP THEME TOGGLE - Make sure it's fully visible
+ .theme-toggle {
+ display: flex !important;
+ align-items: center !important;
+ height: 65px !important;
+ padding: 0 15px !important;
+
+ .form-check {
+ margin: 0 !important;
+ display: flex !important;
+ align-items: center !important;
+
+ .form-check-label {
+ color: var(--c-text-muted) !important;
+ font-size: 11px !important;
+ font-weight: 500 !important;
+ text-transform: uppercase !important;
+ letter-spacing: 0.5px !important;
+ display: inline !important;
+
+ i {
+ font-size: 12px !important;
+ }
+ }
+
+ .form-check-input {
+ width: 2.5rem !important;
+ height: 1.25rem !important;
+ background-color: var(--c-border) !important;
+ border: 1px solid var(--c-border) !important;
+ cursor: pointer !important;
+ margin: 0 8px !important;
+
+ &:checked {
+ background-color: var(--c-primary) !important;
+ border-color: var(--c-primary) !important;
+ }
+
+ &:focus {
+ box-shadow: 0 0 0 0.2rem color-mix(in srgb, var(--c-primary) 25%, transparent) !important;
+ border-color: var(--c-primary) !important;
+ }
+ }
+ }
+ }
+}
+
+// =============================================================================
+// HEADER NAVIGATION MOBILE FIXES - ENHANCED LAYOUT
+// =============================================================================
+
+// Mobile header fixes with improved spacing and layout
+@media screen and (max-width: 767px) {
+
+ // Force header to be fixed and proper height
+ .header {
+ position: fixed !important;
+ top: 0 !important;
+ left: 0 !important;
+ right: 0 !important;
+ z-index: 1000 !important;
+ width: 100% !important;
+ height: auto !important;
+ min-height: 60px !important;
+ padding: 0 !important;
+ margin: 0 !important;
+ margin-top: 0 !important; // Ensure no top margin on mobile
+ }
+
+ // Header container - IMPROVED EDGE-TO-EDGE LAYOUT
+ .header .header-container {
+ display: flex !important;
+ align-items: center !important;
+ justify-content: space-between !important;
+ flex-wrap: nowrap !important;
+ padding: 8px 8px !important; // Reduced side padding for more space
+ height: auto !important;
+ min-height: 60px !important;
+ max-height: 60px !important;
+ overflow: visible !important;
+ gap: 12px !important; // Larger gap to push items apart
+ }
+
+ // LEFT SECTION: Logo + Hamburger + Search - PUSHED MORE LEFT
+ .header .nav-left {
+ display: flex !important;
+ align-items: center !important;
+ flex: 1 1 auto !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ float: none !important;
+ max-width: 65% !important; // Increased width
+ gap: 4px !important; // Tighter spacing between left items
+ justify-content: flex-start !important; // Push to left edge
+
+ // Logo first - positioned at far left
+ &::before {
+ content: "A" !important;
+ display: inline-flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ width: 32px !important;
+ height: 32px !important;
+ background: #007bff !important;
+ color: white !important;
+ border-radius: 6px !important;
+ font-weight: bold !important;
+ font-size: 18px !important;
+ flex-shrink: 0 !important;
+ order: -1 !important;
+ margin-right: 6px !important; // Small margin to separate from hamburger
+ }
+
+ > li {
+ display: inline-flex !important;
+ align-items: center !important;
+ margin: 0 !important;
+ float: none !important;
+
+ > a {
+ padding: 8px 6px !important; // Reduced padding for tighter spacing
+ margin: 0 !important;
+ min-height: auto !important;
+ line-height: 1 !important;
+ display: flex !important;
+ align-items: center !important;
+ border-radius: 4px !important;
+
+ i {
+ font-size: 20px !important;
+ margin: 0 !important;
+ }
+
+ // Hover state for better UX
+ &:hover {
+ background: rgba(0, 0, 0, 0.05) !important;
+ }
+ }
+
+ // Sidebar toggle (hamburger)
+ &:first-child > a {
+ padding: 8px 6px !important;
+
+ i {
+ font-size: 22px !important;
+ }
+ }
+
+ // Search toggle
+ &.search-box > a {
+ padding: 8px 6px !important;
+
+ i {
+ font-size: 20px !important;
+ }
+ }
+ }
+
+ // FULL-WIDTH SEARCH BAR - CLEANER DESIGN
+ .search-input {
+ display: none !important; // Hidden by default
+ position: fixed !important; // Fixed positioning for full control
+ top: 60px !important; // Right below header
+ left: 0 !important;
+ right: 0 !important;
+ background: var(--c-bkg-card) !important;
+ border-bottom: 1px solid var(--c-border) !important;
+ padding: 15px 20px !important; // More padding for better appearance
+ z-index: 9999 !important;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1) !important; // Subtle shadow
+
+ &.active {
+ display: block !important;
+ }
+
+ input {
+ width: 100% !important;
+ padding: 12px 16px !important; // Better padding
+ font-size: 16px !important;
+ border: 1px solid var(--c-border) !important;
+ border-radius: 8px !important; // Rounded corners
+ background: var(--c-bkg-body) !important;
+ color: var(--c-text-base) !important;
+ margin: 0 !important;
+ outline: none !important;
+
+ &::placeholder {
+ color: var(--c-text-muted) !important;
+ }
+
+ &:focus {
+ outline: none !important;
+ border-color: var(--c-primary) !important;
+ box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25) !important;
+ }
+ }
+ }
+ }
+
+ // RIGHT SECTION: Notifications + Messages + Theme Toggle + Profile - PERFECT ALIGNMENT
+ .header .nav-right {
+ display: flex !important;
+ align-items: center !important;
+ flex: 0 0 auto !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ float: none !important;
+ flex-wrap: nowrap !important;
+ gap: 4px !important; // Consistent spacing
+ justify-content: flex-end !important; // Push to right edge
+ height: 60px !important; // Match header height exactly
+
+ > li {
+ display: flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ float: none !important;
+ flex: 0 0 auto !important;
+ position: relative !important;
+ height: 60px !important; // Force exact height for all items
+ min-height: 60px !important; // Ensure minimum height
+
+ > a {
+ padding: 0 !important; // NO padding for perfect alignment
+ margin: 0 !important;
+ width: 44px !important; // Fixed width for all nav items
+ height: 44px !important; // Fixed height for all nav items
+ line-height: 1 !important;
+ display: flex !important;
+ align-items: center !important; // Perfect vertical centering
+ justify-content: center !important; // Perfect horizontal centering
+ position: relative !important;
+ border-radius: 50% !important; // Circular touch targets
+ background: transparent !important;
+ transition: all 0.2s ease !important; // Smooth transitions
+
+ i {
+ font-size: 20px !important; // Consistent icon size for all nav items
+ margin: 0 !important;
+ display: block !important;
+ line-height: 1 !important;
+ text-align: center !important;
+ }
+
+ // Hide text content, keep only icons
+ span:not(.counter) {
+ display: none !important;
+ }
+
+ // Hide user avatar text
+ .peer:last-child {
+ display: none !important;
+ }
+
+ // Hover state - subtle and theme-consistent
+ &:hover {
+ background: var(--c-grey-100) !important;
+ transform: scale(1.05) !important;
+ transition: all 0.2s ease !important;
+ }
+ }
+
+ // User dropdown - special styling for avatar
+ &:last-child > a {
+ .peer {
+ &:first-child {
+ margin-right: 0 !important;
+ display: flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ }
+
+ img {
+ width: 36px !important;
+ height: 36px !important;
+ max-width: 36px !important;
+ max-height: 36px !important;
+ border-radius: 50% !important;
+ object-fit: cover !important;
+ }
+ }
+ }
+ }
+
+ // NOTIFICATION COUNTERS - CORRECTLY ANCHORED
+ > li {
+ position: relative !important; // This is the anchor
+
+ .counter {
+ position: absolute !important;
+ top: 10px !important;
+ right: 10px !important;
+ z-index: 10 !important;
+
+ // The design of the counter itself is inherited
+ }
+ }
+
+ // Theme toggle - perfectly aligned with other nav icons
+ .theme-toggle {
+ padding: 0 !important;
+ display: flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ height: 60px !important; // Match header height exactly
+ min-height: 60px !important; // Force exact height
+ width: 44px !important; // Same width as other nav items
+
+ .form-check {
+ margin: 0 !important;
+ padding: 0 !important;
+ align-items: center !important;
+ justify-content: center !important;
+ display: flex !important;
+ height: 44px !important; // Same height as other nav items
+ width: 44px !important; // Same width as other nav items
+ border-radius: 50% !important; // Match other nav items
+ position: relative !important;
+
+ .form-check-label {
+ display: none !important; // Hide labels on mobile for consistency
+ }
+
+ .form-check-input {
+ width: 28px !important; // Smaller switch to fit in circular area
+ height: 16px !important; // Smaller switch to fit in circular area
+ margin: 0 !important; // No margin for perfect centering
+ flex-shrink: 0 !important;
+ border-radius: 8px !important; // Proportional border radius
+ border-width: 1px !important; // Standard border
+ position: absolute !important;
+ top: 50% !important;
+ left: 50% !important;
+ transform: translate(-50%, -50%) !important; // Perfect centering
+ }
+
+ // Hover state to match other nav items
+ &:hover {
+ background: var(--c-grey-100) !important;
+ transform: scale(1.05) !important;
+ transition: all 0.2s ease !important;
+ }
+ }
+ }
+ }
+
+ // Full-screen mobile dropdowns
+ .header .nav-right .dropdown-menu {
+ position: fixed !important;
+ top: 60px !important;
+ left: 0 !important;
+ right: 0 !important;
+ bottom: 0 !important;
+ width: 100vw !important;
+ height: calc(100vh - 60px) !important;
+ max-width: none !important;
+ min-width: auto !important;
+ transform: none !important;
+ border-radius: 0 !important;
+ z-index: 9999 !important;
+ overflow-y: auto !important;
+ border: none !important;
+ margin: 0 !important;
+ padding: 0 !important;
+
+ // Mobile close button
+ &::before {
+ content: "โ Close" !important;
+ position: sticky !important;
+ top: 0 !important;
+ display: block !important;
+ background: var(--c-primary) !important;
+ color: white !important;
+ text-align: center !important;
+ padding: 15px !important;
+ cursor: pointer !important;
+ font-weight: bold !important;
+ z-index: 10000 !important;
+ font-size: 16px !important;
+ }
+
+ // UNIFIED EMAIL/NOTIFICATION MOBILE LAYOUT
+ .peers {
+ padding: 15px 20px !important;
+ flex-wrap: wrap !important;
+ align-items: flex-start !important;
+
+ .peer {
+ max-width: 100% !important;
+
+ img {
+ width: 40px !important;
+ height: 40px !important;
+ margin-right: 12px !important;
+ flex-shrink: 0 !important;
+ }
+
+ &.peer-greed {
+ flex: 1 !important;
+ min-width: 0 !important;
+
+ // NOTIFICATIONS STYLE - Direct content (span > fw-500 + c-grey-600, then p > small)
+ > span {
+ display: block !important;
+ margin-bottom: 4px !important;
+
+ .fw-500 {
+ font-size: 14px !important;
+ font-weight: 600 !important;
+ margin: 0 !important;
+ color: var(--c-text-base) !important;
+ display: inline !important;
+ }
+
+ .c-grey-600 {
+ font-size: 13px !important;
+ color: var(--c-text-muted) !important;
+ line-height: 1.4 !important;
+ display: inline !important;
+ }
+ }
+
+ > p {
+ margin: 0 !important;
+
+ small {
+ font-size: 12px !important;
+ color: var(--c-text-muted) !important;
+ }
+ }
+
+ // EMAILS STYLE - Match notifications exactly
+ > div {
+ // Completely restructure emails to match notification layout
+ display: block !important;
+
+ .peers {
+ display: inline !important; // Make name and action on same line
+ margin: 0 !important;
+
+ .peer {
+ &:first-child {
+ // Name section
+ p {
+ font-size: 14px !important;
+ font-weight: 600 !important;
+ margin: 0 !important;
+ color: var(--c-text-base) !important;
+ display: inline !important;
+ }
+
+ // Add action text after name
+ &::after {
+ content: " sent you a message" !important;
+ font-size: 13px !important;
+ color: var(--c-text-muted) !important;
+ font-weight: normal !important;
+ }
+ }
+
+ &:last-child {
+ // Move timestamp to its own line below (like notifications)
+ display: block !important;
+ margin-top: 2px !important;
+
+ small {
+ font-size: 12px !important;
+ color: var(--c-text-muted) !important;
+ display: block !important;
+ }
+ }
+ }
+ }
+
+ // Hide the email preview text completely to match notifications
+ > .c-grey-600,
+ .c-grey-600.fsz-sm {
+ display: none !important;
+ }
+ }
+ }
+ }
+ }
+
+ // Header items in dropdown
+ .pX-20 {
+ padding-left: 20px !important;
+ padding-right: 20px !important;
+
+ .fw-600 {
+ font-size: 16px !important;
+ font-weight: 600 !important;
+ }
+ }
+
+ // Footer links in dropdown
+ .ta-c {
+ padding: 15px 20px !important;
+
+ a {
+ font-size: 14px !important;
+ font-weight: 500 !important;
+ }
+ }
+ }
+}
+
+// Extra small screens - refined adjustments
+@media screen and (max-width: 479px) {
+ .header .header-container {
+ padding: 8px 5px !important; // Even less padding for tiny screens
+ gap: 8px !important;
+ }
+
+ .header .nav-left {
+ max-width: 60% !important;
+ gap: 2px !important; // Even tighter spacing
+
+ &::before {
+ width: 28px !important;
+ height: 28px !important;
+ font-size: 16px !important;
+ margin-right: 4px !important;
+ }
+
+ > li > a {
+ padding: 8px 4px !important;
+
+ i {
+ font-size: 18px !important;
+ }
+ }
+ }
+
+ .header .nav-right {
+ gap: 1px !important; // Minimal spacing
+
+ > li > a {
+ padding: 8px 4px !important;
+
+ i {
+ font-size: 18px !important; // Slightly smaller for tiny screens
+ }
+ }
+
+ .theme-toggle .form-check-input {
+ width: 28px !important;
+ height: 16px !important;
+ }
+ }
+
+ // Full-width search bar on tiny screens
+ .header .nav-left .search-input {
+ padding: 12px 15px !important;
+
+ input {
+ padding: 10px 12px !important;
+ font-size: 16px !important; // Prevent zoom on iOS
+ }
+ }
+}
+
+// =============================================================================
+// FOOTER OVERLAP FIXES - MAINTAINING PREVIOUS FIXES
+// =============================================================================
+
+// Global layout fixes
+html, body {
+ height: 100% !important;
+ margin: 0 !important;
+ padding: 0 !important;
+ overflow-x: hidden !important;
+}
+
+// Page container - force flexbox layout
+.page-container {
+ display: flex !important;
+ flex-direction: column !important;
+ min-height: 100vh !important;
+ margin: 0 !important;
+ padding-top: 60px !important;
+}
+
+// Main content - flexible
+.main-content {
+ flex: 1 0 auto !important;
+ padding: 20px 10px 40px !important;
+ margin: 0 !important;
+ min-height: 0 !important;
+ overflow-x: hidden !important;
+}
+
+// Footer - fixed to bottom
+footer {
+ flex: 0 0 auto !important;
+ margin-top: auto !important;
+ padding: 15px 10px !important;
+ background: var(--c-bkg-card) !important;
+ border-top: 1px solid var(--c-border) !important;
+ text-align: center !important;
+ font-size: 11px !important;
+ line-height: 1.3 !important;
+ z-index: 10 !important;
+ position: relative !important;
+ width: 100% !important;
+ clear: both !important;
+
+ // CRITICAL: Override lh-0 class that causes overlap
+ &.lh-0 {
+ line-height: 1.3 !important; // Force proper line height
+ }
+}
+
+@media screen and (max-width: 767px) {
+ .page-container {
+ padding-left: 0 !important;
+ min-height: 100vh !important; // Ensure full height
+ position: relative !important; // Ensure positioning context
+ }
+
+ .main-content {
+ padding: 15px 8px 60px !important; // Increased bottom padding for footer space
+ margin-bottom: 0 !important;
+ width: 100% !important;
+ box-sizing: border-box !important;
+ }
+
+ footer {
+ position: relative !important; // Ensure footer stays in flow
+ width: 100% !important;
+ padding: 15px 10px !important; // Increased padding for better spacing
+ font-size: 11px !important; // Slightly larger for readability
+ line-height: 1.4 !important; // Better line height for mobile
+ background: var(--c-bkg-card) !important;
+ border-top: 1px solid var(--c-border) !important;
+ margin-top: auto !important;
+ box-sizing: border-box !important;
+
+ // CRITICAL MOBILE FIXES: Override all conflicting utility classes
+ &.lh-0 {
+ line-height: 1.4 !important; // Override line-height: 0 that causes overlap
+ }
+
+ &.p-30 {
+ padding: 15px 10px !important; // Override desktop padding
+ }
+
+ &.fsz-sm {
+ font-size: 11px !important; // Ensure readable font size on mobile
+ }
+
+ span {
+ display: block !important; // Force block for better wrapping
+ word-wrap: break-word !important;
+ max-width: 100% !important;
+ text-align: center !important;
+ line-height: 1.4 !important;
+
+ // Handle long text better
+ hyphens: auto !important;
+ word-break: break-word !important;
+
+ a {
+ color: var(--c-primary) !important;
+ text-decoration: none !important;
+ display: inline !important; // Keep link inline within text
+
+ &:hover {
+ text-decoration: underline !important;
+ }
+ }
+ }
+ }
+}
+
+@media screen and (max-width: 479px) {
+ .main-content {
+ padding: 10px 8px 50px !important; // Adequate bottom space for footer
+ }
+
+ footer {
+ padding: 12px 8px !important;
+ font-size: 10px !important;
+ line-height: 1.5 !important; // Better readability on small screens
+
+ // Override utility classes for small screens
+ &.lh-0 {
+ line-height: 1.5 !important; // Override line-height: 0
+ }
+
+ &.p-30 {
+ padding: 12px 8px !important; // Override desktop padding
+ }
+
+ &.fsz-sm {
+ font-size: 10px !important; // Ensure readable font size
+ }
+
+ span {
+ display: block !important;
+ margin: 0 !important; // Remove extra margins
+ padding: 0 !important;
+ text-align: center !important;
+
+ // Split long copyright text into multiple lines if needed
+ word-spacing: normal !important;
+ letter-spacing: normal !important;
+
+ // Ensure links are readable
+ a {
+ display: inline !important;
+ white-space: nowrap !important; // Keep "Colorlib" as one word
+ }
+ }
+ }
+}
+
+// Additional mobile footer fixes
+@media screen and (max-width: 360px) {
+ footer {
+ font-size: 9px !important;
+ padding: 10px 5px !important;
+
+ // Override utility classes for extra small screens
+ &.lh-0 {
+ line-height: 1.6 !important; // Even better line height for tiny screens
+ }
+
+ &.p-30 {
+ padding: 10px 5px !important; // Override desktop padding
+ }
+
+ &.fsz-sm {
+ font-size: 9px !important; // Readable font size for tiny screens
+ }
+
+ span {
+ line-height: 1.6 !important; // Ensure good readability
+
+ // For very small screens, ensure text doesn't overlap
+ word-break: break-word !important;
+ overflow-wrap: break-word !important;
+
+ // Ensure links are readable
+ a {
+ font-weight: bold !important;
+ color: var(--c-primary) !important;
+ }
+ }
+ }
+}
+
+// =============================================================================
+// UTILITY CLASSES FOR MOBILE
+// =============================================================================
+
+// Prevent body scroll when mobile menus are open
+body.mobile-menu-open {
+ overflow: hidden !important;
+ position: fixed !important;
+ width: 100% !important;
+}
+
+// Emergency fixes for any remaining issues
+@media screen and (max-width: 767px) {
+ // Ensure dropdowns don't break layout
+ .dropdown-menu.show {
+ position: fixed !important;
+ }
+
+ // Prevent content overflow
+ .row {
+ margin-left: 0 !important;
+ margin-right: 0 !important;
+ }
+
+ [class*="col-"] {
+ padding-left: 5px !important;
+ padding-right: 5px !important;
+ }
+
+ // Hide on mobile utility
+ .d-none-mobile {
+ display: none !important;
+ }
+
+ // Force no horizontal scroll
+ * {
+ max-width: 100% !important;
+ box-sizing: border-box !important;
+ }
+}
\ No newline at end of file