/*prevent FOUC on mobile when using sidebar */
.dwc-mobile :is(.bricks-is-frontend.brx-header-left, .bricks-is-frontend.brx-header-right) #brx-header {
  position: relative;
  inline-size: 100%;
  flex-direction: column;
}

.dwc-mobile .bricks-is-frontend:is(.brx-header-left, .brx-header-right) :is(#brx-content, #brx-footer) {
  margin-inline-start: 0;
}

/*prevent FOUC on desktop when using sidebar */
.bricks-is-frontend:is(.brx-header-left, .brx-header-right):not(.show-nav) .dwc-nav-wrapper {
  display: none;
}

/*=== sidebar css ===*/
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header {
  flex-direction: column;
  box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.7);  
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]).no-scroll {
  overflow: visible;
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu.brxe-nav-nested .brx-nav-nested-items {
  max-block-size: 100dvb;
  padding-block-end: 12rem;
  overscroll-behavior: contain;
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nav-wrapper {
  position: relative;
  overflow: hidden;
  block-size: 100%;
  transform: translateX(0%);
  visibility: visible;
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) .dwc-nest-menu .brxe-toggle {
  display: none !important;
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu {
  display: flex;
  flex-direction: column;
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-header > div {
  display: flex;
  grid-template-columns: 1fr;
  block-size: 100%;
  flex-direction: column;
  justify-content: flex-start;
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-menu-wrap {
  inline-size: 100%;
  display: grid;
  grid-template-columns: 1fr;
  block-size: 100%;
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header :is(.brxe-code, .dwc-nest-menu-overlay) {
  display: none;
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-header {
  inline-size: 100%;
  padding-inline: 0;
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu-top {
  min-block-size: var(--top-offset);
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu:not( [data-hide-close-bar = 'true']) .brx-dropdown-content {
  inset-block-start: calc(var(--top-offset) + 1px) !important;

}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu:not( [data-submenu-reveal = 'slide']) .brx-dropdown-content:not([data-submenu-reveal = 'slide'] *) {  
  inset-inline-start: 0;
  inset-block-start: unset !important;
  overflow: hidden;
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu:not([data-submenu-reveal = 'slide']) .brxe-dropdown:not(.open.active) > .brx-dropdown-content > .brxe-dropdown:not([data-submenu-reveal = 'slide'] *){
  visibility: hidden;  
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu.brxe-nav-nested.brx-open .brxe-dropdown > .brx-dropdown-content {
  overscroll-behavior: contain;
  min-inline-size: var(--mobile-menu-width);

}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu .brxe-dropdown.open > .brx-submenu-toggle button:not([data-submenu-reveal = 'expand'] button)  {
  min-block-size: calc(var(--top-offset) - 1px);
  inset-block-start: 0;
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu .brxe-dropdown.open[data-submenu-reveal = 'slide'] > .brx-submenu-toggle button  {
  min-block-size: calc(var(--top-offset) - 1px);
  inset-block-start: 0;
}

html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu .brxe-dropdown .brx-submenu-toggle button {
  min-block-size: 0;    
}

/* sidebar css ends*/



/*sidebar in builder*/
/*=== sidebar css ===*/
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header {
  flex-direction: column;
  box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.7);
  --top-offset: 40px;
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu.brxe-nav-nested .brx-nav-nested-items {
  max-block-size: 100dvb;
  padding-block-end: 12rem;
  overscroll-behavior: contain;
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nav-wrapper {
  position: relative;
  overflow: hidden;
  block-size: 100%;
  transform: translateX(0%);
  visibility: visible;
}

body:is(.brx-header-left, .brx-header-right)[data-builder-window] .dwc-nest-menu .brxe-toggle {
  display: none !important;
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu {
  display: flex;
  flex-direction: column;
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-header > div {
  display: flex;
  grid-template-columns: 1fr;
  block-size: 100%;
  flex-direction: column;
  justify-content: flex-start;
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-menu-wrap {
  inline-size: 100%;
  display: grid;
  grid-template-columns: 1fr;
  block-size: 100%;
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-header {
  inline-size: 100%;
  padding-inline: 0;
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu-top {
  min-block-size: var(--top-offset);
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu .brx-dropdown-content {
  inset-block-start: calc(var(--top-offset) - 1px) !important;
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu.brxe-nav-nested.brx-open .brxe-dropdown > .brx-dropdown-content {
  overscroll-behavior: contain;  
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu .brxe-dropdown.open > .brx-submenu-toggle button {
  min-block-size: calc(var(--top-offset) - 1px);
  inset-block-start: 0;
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu .brxe-dropdown .brx-submenu-toggle button {
  min-block-size: 0;    
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] .dwc-nest-menu {
  margin: 0 !important;
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] .brx-nav-nested-items {  
  flex-direction: column !important;  
}
   
:is(.brx-header-left, .brx-header-right)[data-builder-window] .dwc-nest-toggle--open.brxe-toggle {
  display: flex !important;
}
 
:is(.brx-header-left, .brx-header-right)[data-builder-window] .dwc-nest-menu .brx-nav-nested-items {
  position: relative !Important;
  background: var(--mobile-menu-bg) !important;
  align-items: stretch;
  flex: 1;
}

:where(.brx-header-left, .brx-header-right)[data-builder-mode]:not(:has(.dwc-sidebar)) .dwc-nest-menu-top::before {
    content: 'this space is the back text bar';
    padding: 1rem;
    background-color: gray;
    color: white;
    width: 100%;
    text-transform: uppercase;
    font-size: 12px;
    font-weight: bold;
    letter-spacing: 1px;
}
 
/* MENU CTA (LAST BUTTON) */
:is(.brx-header-left, .brx-header-right)[data-builder-window] [data-last-item-is-button="true"].dwc-nest-menu .brx-nav-nested-items > .menu-item:last-of-type {
  padding-inline: var(--menu-item-inline-padding) !important;
  padding-block: var(--menu-item-block-padding) !important;
}
 
:is(.brx-header-left, .brx-header-right)[data-builder-window] .dwc-nest-menu-top {
  min-block-size: 80px !important;
}
 
:is(.brx-header-left, .brx-header-right)[data-builder-window] .dwc-nest-nav-items {
  overflow-y: scroll;
}

:is(.brx-header-left, .brx-header-right)[data-builder-mode] .brx-dropdown-content {
  min-inline-size: var(--mobile-menu-width);
  position: static;
}

:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu.brxe-nav-nested .brx-nav-nested-items {
  flex-wrap: nowrap;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu .brx-dropdown-content {   
  visibility: visible !important;
  opacity: 1;
}

/*OVERLAY SIDEBAR*/


html:not(.dwc-mobile):has([data-overlay-sidebar=true])  {
 --mobile-menu-bg: rgb(255 255 255 / 0%);
  --menu-item-border: solid 1px rgb(255 255 255 / 50%);
 
}

html:not(.dwc-mobile):has([data-overlay-sidebar=true]) :is(.brx-header-left, .brx-header-right):not([data-builder-modee]) :is(main, footer){
  margin: 0 !important
}

html:not(.dwc-mobile):has([data-overlay-sidebar=true]) :is(.brx-header-left, .brx-header-right):not([data-builder-modee]) :is(main, footer) :where(section):not(section>section) {
  padding-inline-start: calc(var(--mobile-menu-width) + clamp(1.5rem, calc(0.625vw + 1.375rem), 1.875rem));
  max-inline-size: 100%
}

html:not(.dwc-mobile):has([data-overlay-sidebar=true]) :is(.brx-header-left, .brx-header-right):not([data-builder-modee]) #brx-header {
  border-radius: var(--overlay-sidebar-radius);
  overflow: hidden;
  background: var(--overlay-sidebar-bg);
  box-shadow: var(--overlay-sidebar-shadow) !important;
  inset: var(--overlay-sidebar-inset);
}

html:not(.dwc-mobile):has([data-overlay-sidebar=true]) :is(.brx-header-left, .brx-header-right):not([data-builder-modee]) .dwc-nest-header{
  backdrop-filter: blur(13px);
  background: transparent !important;
}

html:not(.dwc-mobile):has([data-overlay-sidebar=true]):not([data-builder-modee])  .brx-dropdown-content {
   background-color: rgb(255 255 255 / 100%);
}

/*NO BRX-OPEN STYLES*/
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu.brxe-nav-nested .brx-nav-nested-items {
  display: flex;
  flex-wrap: nowrap;
  flex-direction: column !important;
}


  html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) .dwc-nest-menu.brxe-nav-nested .brxe-dropdown .brx-dropdown-content {
      visibility: visible;
      min-inline-size: var(--mobile-menu-width) !important;
  }


  html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) .dwc-nest-menu[data-submenu-reveal="expand"] .brxe-dropdown.open>.brx-dropdown-content {
   position: static;
}


class SidebarNavigation {
  constructor(options = {}) {
    // Basic configuration properties
    this.config = {
      minWidth: options.minWidth || MegaMenuCONFIG.minWidth, // Using external minWidth variable
      menuSelector: options.menuSelector || '.dwc-nest-menu',
      openClass: options.openClass || 'brx-open',
      activeClasses: options.activeClasses || ['open', 'active'],
      leftHeaderClass: options.leftHeaderClass || 'brx-header-left',
      rightHeaderClass: options.rightHeaderClass || 'brx-header-right',
      debounceDelay: options.debounceDelay || 100,
      menuItemClickDelay: options.menuItemClickDelay || 300
    };
    
    // Set dependent selectors
    const menuSelector = this.config.menuSelector;
    this.config.submenuToggleSelector = options.submenuToggleSelector || `${menuSelector} .brx-submenu-toggle`;
    this.config.dropdownSelector = options.dropdownSelector || `${menuSelector} .brxe-dropdown`;
    this.config.dropdownContentSelector = options.dropdownContentSelector || `${menuSelector} .brx-dropdown-content`;
    
    // State
    this.previousHeaderClass = null;
    this.dropdownClickHandlers = new Map();
    this.menuHoverHandlers = null;
    this.menuItemClickTimeout = null;
    this.keyboardNavHandler = null;
    this.cachedFocusableElements = null;
    this.cachedElements = {
      menuElement: null,
      navElement: null,
      dropdowns: null,
      dropdownToggles: null,
      menuItems: null
    };
    
    // Bind methods to this instance
    this.handleResize = this.debounce(this.handleMenu.bind(this), this.config.debounceDelay);
    this.handleOutsideClick = this.handleOutsideClick.bind(this);
  }
  
  // Initialize everything - called once
  init() {
    // Wait for DOM to be fully loaded before attaching events
    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', () => {
        this.initAfterDOMLoaded();
      }, { once: true });
    } else {
      this.initAfterDOMLoaded();
    }
    
    return this;
  }
  
  // Separate initialization method to run after DOM is loaded
  initAfterDOMLoaded() {
    // Cache DOM elements once
    this.cacheElements();
    
    // Setup resize event with passive flag
    window.addEventListener('resize', this.handleResize, { passive: true });
    
    // Setup mutation observer for critical class changes only
    this.setupMutationObserver();
    
    // Initial setup based on current screen size
    this.handleMenu();
    
    // Cache focusable elements once if header class is present
    if (this.hasHeaderClass()) {
      this.cacheFocusableElements();
      this.setupMenuFocusNavigation();
    }
  }
  
  // Cache all required DOM elements upfront
  cacheElements() {
    this.cachedElements.menuElement = document.querySelector(this.config.menuSelector);
    
    if (this.cachedElements.menuElement) {
      this.cachedElements.navElement = this.cachedElements.menuElement.querySelector('.dwc-nest-nav-items');
      this.cachedElements.dropdowns = Array.from(document.querySelectorAll(this.config.dropdownSelector));
      this.cachedElements.dropdownToggles = Array.from(document.querySelectorAll(this.config.submenuToggleSelector));
      this.cachedElements.menuItems = Array.from(document.querySelectorAll(`${this.config.menuSelector} .menu-item`));
    }
  }
  
  // Set up a focused mutation observer only for dropdown state changes
  setupMutationObserver() {
    if (!this.cachedElements.dropdowns || this.cachedElements.dropdowns.length === 0) return;
    
    const callback = (mutations) => {
      for (let mutation of mutations) {
        if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
          const target = mutation.target;
          const prevClassList = mutation.oldValue ? mutation.oldValue.split(' ') : [];
          const hadBothBefore = prevClassList.includes('open') && prevClassList.includes('active');
          const hasBothNow = target.classList.contains('open') && target.classList.contains('active');
    
          if (hadBothBefore !== hasBothNow) {
            this.updateDropdownAccessibility();
            break; // Only need to update once per batch
          }
        }
      }
    };
    
    // Create observer with optimized options
    this.classObserver = new MutationObserver(callback);
    
    // Observe only the dropdown elements
    this.cachedElements.dropdowns.forEach(dropdown => {
      this.classObserver.observe(dropdown, { 
        attributes: true, 
        attributeFilter: ['class'], 
        attributeOldValue: true 
      });
    });
  }
  
  // Cache focusable elements for keyboard navigation
  cacheFocusableElements() {
    if (!this.cachedElements.navElement) return;
    
    // Get direct children of nav
    const directChildren = Array.from(this.cachedElements.navElement.children);
    
    // Find the first focusable element within each direct child
    this.cachedFocusableElements = directChildren.map(child => {
      // Check if the child itself is focusable
      if (child.matches('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])')) {
        return child;
      }
      // Otherwise, find the first focusable element within this child
      return child.querySelector('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])');
    }).filter(Boolean); // Remove null/undefined values
  }
  
  // Clean up all event listeners and observers
  destroy() {
    // Clean up the mutation observer
    if (this.classObserver) {
      this.classObserver.disconnect();
      this.classObserver = null;
    }
    
    // Clean up resize listener
    window.removeEventListener('resize', this.handleResize);
    
    // Clean up click handlers
    if (this.dropdownClickHandlers.size > 0) {
      this.dropdownClickHandlers.forEach((handler, toggle) => {
        toggle.removeEventListener('click', handler);
      });
      this.dropdownClickHandlers.clear();
    }
    
    // Clean up hover handlers
    this.cleanupMenuHover();
    
    // Clean up menu item click handlers
    this.cleanupMenuItemClicks();
    
    // Clean up outside click handler
    document.removeEventListener('click', this.handleOutsideClick);
    
    // Clean up keyboard navigation
    if (this.keyboardNavHandler) {
      document.removeEventListener('keydown', this.keyboardNavHandler);
      this.keyboardNavHandler = null;
    }
    
    // Clear any pending timeouts
    if (this.menuItemClickTimeout) {
      clearTimeout(this.menuItemClickTimeout);
      this.menuItemClickTimeout = null;
    }
  }
  
  // Utility methods
  hasHeaderClass() {
    return document.body.classList.contains(this.config.leftHeaderClass) || 
           document.body.classList.contains(this.config.rightHeaderClass);
  }
  
  debounce(func, delay) {
    let timer;
    return (...args) => {
      clearTimeout(timer);
      timer = setTimeout(() => func(...args), delay);
    };
  }

  // Check if an element has all the required active classes
  hasAllActiveClasses(element) {
    return this.config.activeClasses.every(className => element.classList.contains(className));
  }
  
  // Toggle all active classes on an element
  toggleActiveClasses(element) {
    this.config.activeClasses.forEach(className => {
      element.classList.toggle(className);
    });
  }
  
  // Core functionality methods
  handleMenu() {
    if (!this.cachedElements.menuElement) return;
    if (!this.hasHeaderClass() && !this.previousHeaderClass) return;

    const screenWidth = window.innerWidth;
    const isLargeScreen = screenWidth >= this.config.minWidth;
    const menuElement = this.cachedElements.menuElement;

    if (!isLargeScreen) {
      // Save which class was present before removal
      if (this.hasHeaderClass()) {
        this.previousHeaderClass = document.body.classList.contains(this.config.leftHeaderClass) 
          ? this.config.leftHeaderClass 
          : this.config.rightHeaderClass;
        
        // Remove header classes
        document.body.classList.remove(this.config.leftHeaderClass, this.config.rightHeaderClass);
        menuElement.classList.remove(this.config.openClass);
        
        // Reset accessibility attributes
        this.resetAccessibilityAttributes();
      }
      
      // Clean up event handlers for mobile view
      this.cleanupMenuHover();
      this.cleanupMenuItemClicks();
      this.cleanupDropdownHandlers();
      document.removeEventListener('click', this.handleOutsideClick);
      
      return;
    }

    // Large screen behavior
    if (!this.hasHeaderClass() && this.previousHeaderClass) {
      document.body.classList.add(this.previousHeaderClass);
    }

    if (this.hasHeaderClass()) {
      if (!menuElement.classList.contains(this.config.openClass)) {
        menuElement.classList.add(this.config.openClass);
      }
      
      // Setup elements for large screen view
      this.setupMenuHover();
      this.setupMenuItemClicks();
      this.setupDropdownHandlers();
      this.setupMenuFocusNavigation();
      this.updateDropdownAccessibility();
      
      // Ensure outside click handler is set up
      document.removeEventListener('click', this.handleOutsideClick);
      document.addEventListener('click', this.handleOutsideClick, { passive: false });
    }
  }
  
  // Reset accessibility attributes when switching to mobile
  resetAccessibilityAttributes() {
    if (!this.cachedElements.dropdowns) return;
    
    // Remove all inert attributes from dropdown contents
    this.cachedElements.dropdowns.forEach(dropdown => {
      const content = dropdown.querySelector(this.config.dropdownContentSelector);
      if (content) {
        content.removeAttribute('inert');
      }
      
      const button = dropdown.querySelector('button');
      if (button) {
        button.setAttribute('aria-expanded', 'false');
      }
    });
  }
  
  setupMenuFocusNavigation() {
    // Only run if hasHeaderClass() is true and we have focusable elements
    if (!this.hasHeaderClass() || !this.cachedFocusableElements || this.cachedFocusableElements.length === 0) {
      return;
    }
    
    // Clean up previous handler if it exists
    if (this.keyboardNavHandler) {
      document.removeEventListener('keydown', this.keyboardNavHandler, true);
      this.keyboardNavHandler = null;
    }
    
    const navMenu = this.cachedElements.menuElement;
    const focusableElements = this.cachedFocusableElements;
    const firstFocusableElement = focusableElements[0];
    const lastFocusableElement = focusableElements[focusableElements.length - 1];
    
    // Find adjacent focusable elements outside the menu (only once during setup)
    const headerElement = navMenu.closest('header') || document.querySelector('header');
    
    // Prepare variables to hold adjacent elements
    let prevFocusableElement = null;
    let nextFocusableElement = null;
    let firstElementAfterHeader = null;
    
    if (headerElement) {
      // Get all focusable elements within the header - do this once and cache the result
      const headerFocusables = Array.from(
        headerElement.querySelectorAll('a:not([tabindex="-1"]), button:not([tabindex="-1"]), input:not([tabindex="-1"]), select:not([tabindex="-1"]), textarea:not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])')
      ).filter(el => window.getComputedStyle(el).display !== 'none');
      
      // Find the index of our first and last menu elements in one pass
      const menuStartIndex = headerFocusables.indexOf(firstFocusableElement);
      const menuEndIndex = headerFocusables.indexOf(lastFocusableElement);
      
      // Cache the adjacent elements
      if (menuStartIndex > 0) {
        prevFocusableElement = headerFocusables[menuStartIndex - 1];
      }
      
      if (menuEndIndex !== -1 && menuEndIndex < headerFocusables.length - 1) {
        nextFocusableElement = headerFocusables[menuEndIndex + 1];
      }
      
      // Pre-calculate the first element after header - but only if needed
      if (!nextFocusableElement) {
        // Use a more efficient selector that targets immediate children of body that aren't the header
        const selector = 'body > *:not(header)';
        const nonHeaderElements = document.querySelectorAll(selector);
        
        // Only process if we have elements
        if (nonHeaderElements.length > 0) {
          // Create a function to find the first focusable element (used later if needed)
          this.findFirstFocusableAfterHeader = () => {
            for (const element of nonHeaderElements) {
              const focusable = element.querySelector('a:not([tabindex="-1"]), button:not([tabindex="-1"]), input:not([tabindex="-1"]), select:not([tabindex="-1"]), textarea:not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])');
              if (focusable && window.getComputedStyle(focusable).display !== 'none') {
                return focusable;
              }
            }
            return null;
          };
        }
      }
    }
    
    // Create keyboard navigation handler with closure over the cached elements
    this.keyboardNavHandler = (e) => {
      // Quick check for Tab key first
      if (e.key !== 'Tab') return;
      
      // Then check if focus is inside the menu
      if (!navMenu.contains(document.activeElement)) return;
      
      let targetElement = null;
      
      // Handle tab navigation at boundaries only
      if (!e.shiftKey && document.activeElement === lastFocusableElement) {
        // Forward tab from last element
        e.preventDefault();
        e.stopPropagation();
        
        if (nextFocusableElement) {
          targetElement = nextFocusableElement;
        } else if (this.findFirstFocusableAfterHeader) {
          // Only search for elements after header if needed and not already found
          firstElementAfterHeader = this.findFirstFocusableAfterHeader();
          targetElement = firstElementAfterHeader;
        }
        
        // Focus on the target or body as fallback
        setTimeout(() => {
          if (targetElement) {
            targetElement.focus();
          } else {
            document.body.setAttribute('tabindex', '-1');
            document.body.focus();
            document.body.removeAttribute('tabindex');
          }
        }, 10);
      } 
      else if (e.shiftKey && document.activeElement === firstFocusableElement) {
        // Backward tab from first element
        e.preventDefault();
        e.stopPropagation();
        
        setTimeout(() => {
          if (prevFocusableElement) {
            prevFocusableElement.focus();
          } else {
            document.body.setAttribute('tabindex', '-1');
            document.body.focus();
            document.body.removeAttribute('tabindex');
          }
        }, 10);
      }
    };
    
    // Use capture phase for the event
    document.addEventListener('keydown', this.keyboardNavHandler, true);
  }
  
  setupMenuHover() {
    const menuElement = this.cachedElements.menuElement;
    if (!menuElement) return;
    
    // Clean up existing hover handlers first
    this.cleanupMenuHover();
    
    // Create event handlers
    const mouseenterHandler = () => {
      menuElement.classList.add(this.config.openClass);
    };
    
    const mouseleaveHandler = () => {
      menuElement.classList.remove(this.config.openClass);
    };
    
    // Add event listeners with passive flag for better performance
    menuElement.addEventListener('mouseenter', mouseenterHandler, { passive: true });
    menuElement.addEventListener('mouseleave', mouseleaveHandler, { passive: true });
    
    // Store the handlers for cleanup
    this.menuHoverHandlers = {
      element: menuElement,
      mouseenter: mouseenterHandler,
      mouseleave: mouseleaveHandler
    };
  }
  
  cleanupMenuHover() {
    if (this.menuHoverHandlers) {
      const { element, mouseenter, mouseleave } = this.menuHoverHandlers;
      element.removeEventListener('mouseenter', mouseenter);
      element.removeEventListener('mouseleave', mouseleave);
      this.menuHoverHandlers = null;
    }
  }
  
  setupMenuItemClicks() {
    if (!this.cachedElements.menuItems || this.cachedElements.menuItems.length === 0) return;
    
    // Clean up existing handlers first
    this.cleanupMenuItemClicks();
    
    const menuElement = this.cachedElements.menuElement;
    const menuItemHandlers = new Map();
    
    this.cachedElements.menuItems.forEach(item => {
      const clickHandler = () => {
        if (this.hasHeaderClass()) {
          // Clear any existing timeout
          if (this.menuItemClickTimeout) {
            clearTimeout(this.menuItemClickTimeout);
          }
          
          // Set timeout before adding the class
          this.menuItemClickTimeout = setTimeout(() => {
            if (!menuElement.classList.contains(this.config.openClass)) {
              menuElement.classList.add(this.config.openClass);
            }
          }, this.config.menuItemClickDelay);
        }
      };
      
      menuItemHandlers.set(item, clickHandler);
      item.addEventListener('click', clickHandler);
    });
    
    this.menuItemClickHandlers = menuItemHandlers;
  }
  
  cleanupMenuItemClicks() {
    if (this.menuItemClickHandlers && this.menuItemClickHandlers instanceof Map) {
      this.menuItemClickHandlers.forEach((handler, item) => {
        item.removeEventListener('click', handler);
      });
      this.menuItemClickHandlers.clear();
    }
    
    if (this.menuItemClickTimeout) {
      clearTimeout(this.menuItemClickTimeout);
      this.menuItemClickTimeout = null;
    }
  }
  
  setupDropdownHandlers() {
    if (!this.hasHeaderClass() || !this.cachedElements.dropdownToggles) return;
    
    // Clean up existing handlers first
    this.cleanupDropdownHandlers();
    
    this.cachedElements.dropdownToggles.forEach(toggle => {
      const clickHandler = (event) => {
        event.stopPropagation();
        event.preventDefault();
        
        const dropdown = toggle.closest(this.config.dropdownSelector);
        if (dropdown) {
          this.toggleActiveClasses(dropdown);
          this.updateDropdownAccessibility();
        }
      };
      
      this.dropdownClickHandlers.set(toggle, clickHandler);
      toggle.addEventListener('click', clickHandler);
    });
  }
  
  cleanupDropdownHandlers() {
    if (this.dropdownClickHandlers.size > 0) {
      this.dropdownClickHandlers.forEach((handler, toggle) => {
        toggle.removeEventListener('click', handler);
      });
      this.dropdownClickHandlers.clear();
    }
  }
  
  handleOutsideClick(event) {
    if (event.target.tagName === 'A') return;
    if (!event.target.closest(this.config.dropdownSelector)) return;
    if (!event.target.closest(this.config.submenuToggleSelector)) {
      event.preventDefault();
      event.stopPropagation();
    }
  }
  
  updateDropdownAccessibility() {
    // Only run if hasHeaderClass() is true
    if (!this.hasHeaderClass() || !this.cachedElements.dropdowns) return;
    
    this.cachedElements.dropdowns.forEach(dropdown => {
      const content = dropdown.querySelector(this.config.dropdownContentSelector);
      const button = dropdown.querySelector('button');
      
      // Check if dropdown has all active classes
      const isOpen = this.hasAllActiveClasses(dropdown);
      
      if (content) {
        if (isOpen) {
          content.removeAttribute('inert');
        } else {
          content.setAttribute('inert', '');
        }
      }
      
      if (button) {
        button.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
      }
    });
  }
}


const sidebarNav = new SidebarNavigation().init();

GROUNDWORK BEFORE CONSTRUCTION

Complete Site Preparation Services for Metro Vancouver

Site preparation establishes the clearing, excavation, access and grades needed for the next build phase. VALROC works from the available plans and site conditions to define what groundwork is included.

The site preparation scope is written before excavation and material movement begin.

Excavation site preparation with John Deere excavator and laser rotary measurement tool in use
PLANNING

Start with the build requirements

Review plans, access and intended elevations before mobilization.

GROUNDWORK

Prepare the contracted area

Coordinate clearing, excavation and material handling for the next phase.

GRADE

Set up the handoff

Confirm grade, compaction and inspection responsibilities in the scope.

HOW THE WORK PROCEEDS

How site preparation is planned and carried out

Site preparation isn’t just clearing land, it’s about creating the right conditions for safe, code-compliant, and efficient construction. Our team manages all phases with expert planning and in-house equipment. Precision excavation for foundations, utilities, or slab-on-grade builds The connected stages cover planning, site mobilization and active excavation. Clearing, grading, base preparation and handoff are included only where the approved plan and contract call for them.

  1. site Survey grading, stick being installed

    Step 1

    Excavation Planning

    Initial on-site consultation, permitting guidance, and full-scope planning for excavation, demolition, trucking, and recycling, setting the foundation for organized, build-ready site preparation.

    • Site planning
    • Plan review
    • Access assessment
  2. Excavator unloading for excavation and site preparation by VALROC Development

    Step 2

    Excavation Site Prep

    Site preparation mobilization includes safety checks, signage, equipment delivery, on-site meetings, and a structured setup for smooth, coordinated excavation work aligned with approved plans.

    • Equipment mobilization
    • Work zones
    • Utility review
  3. VALROC crew performing footing and foundation excavation for a residential build in White Rock, removing soil and shaping the site for structural concrete work.

    Step 3

    Active Excavation

    Execution of excavation based on approved plans, including digging structural foundations, setting grades and elevations, managing sub-base materials, and coordinating removals or haul-away with precision and care.

    • Site excavation
    • Grade setting
    • Material removal

Video, Excavation, Demolition & Site Preparation Overview

A project compilation showing VALROC Development Ltd. performing excavation, demolition, trucking, grading, drainage preparation, asphalt removal, and site preparation services across Metro Vancouver and the Fraser Valley.

can you 

MATCH THE WORK TO THE SITE

Where site preparation fits

VALROC Development Ltd. provides full-spectrum site preparation services for residential, strata, and commercial clients across Metro Vancouver. From property clearing to final grading, we get your land ready for what comes next, whether that’s foundations, roadways, or complete new builds.

Smart Start for Every Build

Streamlined with Our Own Equipment

Diverse machinery fleet with various excavator sizes and attachments

Mobile service trucks equipped for on-site issue resolution

High-capacity dump trailers, skid steers, compactors, and more

Reduced wait times and minimized subcontractor coordination

Built for Long-Term Performance

Site preparation may involve property clearing, excavation, grade setting, material removal and specified base work. The goal is to give the next trade a defined work area and elevations, not to presume a completed foundation or utility system.

ACCESS

Plan machine movement

Review entry, staging and protection of adjacent areas.

CLEARING

Define what leaves the site

Specify vegetation, debris or existing surface removal.

GRADING

Work to the design levels

Shape the contracted area to supplied elevations.

BASE

Prepare for what follows

Confirm material, compaction and inspection requirements.

DEFINE THE CONTRACTED TASK

Scope choices for site preparation

Site preparation choices depend on the existing ground, planned construction and required finished elevations. Clearing, excavation, hauling, imported materials, compaction and grading are coordinated for the defined work area.

Site preparation from mobilization to handoff

Included in our service:

  • • Property access and work area planning

  • • Clearing and selective demolition

  • • Topsoil stripping and material separation

  • • Bulk excavation and rough grading

  • • Cut and fill balance coordination

  • • Imported aggregate and soil delivery

  • • Compaction with appropriate equipment

  • • Drainage and building elevation preparation

  • • Survey or inspection coordination when required

  • • Final grade review and clean handoff

Demolition, hauling, imported base, compaction and final grading depend on the project. Each item needs a location, quantity or performance requirement in the written scope.

Coordinate the task and the handoff

COORDINATE THE NEXT PHASE

Coordinate site preparation with adjacent work

Strategic layout and base prep for long-term water management Site preparation often precedes foundations, utility trenches, driveway bases and new building work. Those later installations remain separately defined even when VALROC coordinates the sequence.

Demolition, engineered design, utility installation, foundation work and complete landscaping are not automatic site preparation inclusions.

  • Valroc excavators clearing residential demolition debris in Metro Vancouver

    Excavation and machine work for site preparation

    • Site excavation
    • Machine services
    • Material movement

    Excavators, trucks and compact equipment turn a site plan into workable grades and access routes. Coordinating the machines with the preparation sequence helps move soil, aggregate and debris efficiently.

    Explore excavation and machine services
  • Building pad preparation for foundations and footings

    • Foundation site preparation
    • Building pad
    • Footing access

    Foundation work benefits from a stable, accurately graded building area with suitable access. Preparing the pad first helps excavation, layout and concrete crews work from the intended elevations.

    Explore foundations and footings
  • Luxury custom home build with lots of amazing features, showing a construction sign of Valroc Development Ltd. showing it's thier construction site

    Site preparation for custom home construction

    • Custom home site
    • Construction access
    • Building preparation

    A custom home build starts with access, clearing, erosion control and practical working space. Early site preparation helps the home, services, drainage and exterior improvements come together in the right sequence.

    Explore custom home construction
  • Site preparation for detached garages

    • Garage site preparation
    • Garage footprint
    • Vehicle access

    Garage construction may require clearing, excavation access, subgrade correction and space for material delivery. Preparing the garage area around the planned footprint supports the foundation, slab and driveway work that follows.

    Explore detached garage construction
  • To catch basins tied into perimeter drainage system on a new build that was done with Valroc as the contractor in Burnaby Canada

    Drainage planning during site preparation

    • Site drainage
    • Perimeter drainage
    • Grade planning

    Surface and subsurface water should be considered before final grades and hard surfaces are established. Perimeter drainage routes can be coordinated early to protect building areas and direct water appropriately.

    Explore perimeter drainage systems

DOCUMENTED EXPERIENCE

Site preparation experience across Metro Vancouver

VALROC prepares residential, strata, commercial and light industrial properties for the construction that follows. Our experience with clearing, demolition, excavation, grading and drainage helps create a practical starting point for the complete project. Our Langley construction yard supports site preparation throughout Surrey, Burnaby, Coquitlam, Maple Ridge and Vancouver, where local bylaws, inspections, engineering and neighbourhood access can all influence the work plan.

DEFINE THE WORK BEFORE BOOKING

Discuss a site preparation proposal

Share your plans, photos and work goals with VALROC. An onsite review can establish equipment needs, access and the limits of a site preparation scope.

  • Share the task

    Explain the planned excavation, site access and available drawings.

  • Review the property

    Review the intended construction, engineered drawings where available, access, existing structures, utilities, ground conditions and required approvals.

  • Confirm the arrangement

    Review equipment, materials, timing and handoff in the written scope.

  • What affects a site preparation estimate?

    Property size, clearing, excavation depth, access, material volumes, disposal, imported base and grade requirements affect the proposal. A current site review is needed for a property specific price.

    What affects a site preparation estimate?

    Property size, clearing, excavation depth, access, material volumes, disposal, imported base and grade requirements affect the proposal. A current site review is needed for a property specific price.

    Request Your Free On-site Estimate

    CHECK THE ACTUAL CONDITIONS

    Assess the site before site preparation

    Final grading for water control, elevation, and drainage performance Coordination with engineers, inspectors, and municipal permit offices Review the intended construction, engineered drawings where available, access, existing structures, utilities, ground conditions and required approvals.

  • 01

    Define the task

    Review the intended construction, engineered drawings where available, access, existing structures, utilities, ground conditions and required approvals.

  • 02

    Review access

    Check machine access, adjacent structures and the work area.

  • 03

    Check known services

    Confirm available locate information and any excavation constraints.

  • 04

    Write the scope

    Specify machine work, material handling and handoff responsibilities.

  • What the surface cannot show

    Unseen material, buried services or unsuitable soil may require design input or a change in excavation and disposal scope.

    What the surface cannot show

    Unseen material, buried services or unsuitable soil may require design input or a change in excavation and disposal scope.

    ANSWERS NEED PROJECT CONTEXT

    Questions about site preparation

    The linked questions address the preparation sequence, plans, permits and handoff. One duplicated question is excluded from the Engine draft, while its WordPress relationship remains for later cleanup.

    What is site preparation, and why is it important?

    Site preparation is the process of getting land ready for construction by clearing, grading, compacting, and preparing utilities. It is essential for:

    • Ensuring a stable foundation – Prevents settling, erosion, and drainage issues.

    • Complying with zoning & environmental regulations – Meets local municipal and engineering standards.

    • Facilitating smooth construction – Provides a clear, level workspace for builders and heavy equipment.

    • Optimizing drainage & land stability – Prevents flooding, soil shifting, and washouts.

    At VALROC Development Ltd., we provide end-to-end site preparation services, ensuring your project starts on a solid, well-prepared foundation.

    What is site preparation, and why is it important?

    Site preparation is the process of getting land ready for construction by clearing, grading, compacting, and preparing utilities. It is essential for:

    • Ensuring a stable foundation – Prevents settling, erosion, and drainage issues.

    • Complying with zoning & environmental regulations – Meets local municipal and engineering standards.

    • Facilitating smooth construction – Provides a clear, level workspace for builders and heavy equipment.

    • Optimizing drainage & land stability – Prevents flooding, soil shifting, and washouts.

    At VALROC Development Ltd., we provide end-to-end site preparation services, ensuring your project starts on a solid, well-prepared foundation.

    What is site preparation, and why is it important?

    Site preparation is the first and most critical phase of construction, ensuring that the land is properly cleared, leveled, and organized before building begins. It includes:

    • Clearing debris, trees, and obstructions – Creating a clean, workable site.

    • Grading and leveling – Ensuring a stable, well-compacted base for foundations and structures.

    • Excavation and trenching – Preparing for utility installations and foundation work.

    • Drainage and erosion control – Preventing water damage, soil instability, and flooding.

    • Material cleanup and site organization – Keeping the site clean and efficient for ongoing work.

    • Recycling and responsible waste disposal – Ensuring environmentally friendly construction practices.

    At VALROC Development Ltd., we handle every aspect of site preparation, ensuring that your project starts on a well-organized, stable, and regulation-compliant foundation.

    What is site preparation, and why is it important?

    Site preparation is the first and most critical phase of construction, ensuring that the land is properly cleared, leveled, and organized before building begins. It includes:

    • Clearing debris, trees, and obstructions – Creating a clean, workable site.

    • Grading and leveling – Ensuring a stable, well-compacted base for foundations and structures.

    • Excavation and trenching – Preparing for utility installations and foundation work.

    • Drainage and erosion control – Preventing water damage, soil instability, and flooding.

    • Material cleanup and site organization – Keeping the site clean and efficient for ongoing work.

    • Recycling and responsible waste disposal – Ensuring environmentally friendly construction practices.

    At VALROC Development Ltd., we handle every aspect of site preparation, ensuring that your project starts on a well-organized, stable, and regulation-compliant foundation.

    What does VALROC’s site preparation process include?

    We offer comprehensive site preparation services to ensure a clean, stable, and well-managed worksite, including:

    • Land clearing & vegetation removal – Removing trees, brush, and rocks.

    • Debris cleanup & waste management – Ensuring a safe and uncluttered work area.

    • Grading & soil compaction – Creating a solid base for construction.

    • Trenching & foundation excavation – Preparing for utility lines and concrete work.

    • Stormwater drainage & erosion control – Preventing future washouts or flooding.

    • Material recycling & sustainable disposal – Reusing concrete, wood, and metal when possible.

    With our fleet of heavy equipment and skilled operators, we provide fast, efficient, and environmentally responsible site preparation.

    What does VALROC’s site preparation process include?

    We offer comprehensive site preparation services to ensure a clean, stable, and well-managed worksite, including:

    • Land clearing & vegetation removal – Removing trees, brush, and rocks.

    • Debris cleanup & waste management – Ensuring a safe and uncluttered work area.

    • Grading & soil compaction – Creating a solid base for construction.

    • Trenching & foundation excavation – Preparing for utility lines and concrete work.

    • Stormwater drainage & erosion control – Preventing future washouts or flooding.

    • Material recycling & sustainable disposal – Reusing concrete, wood, and metal when possible.

    With our fleet of heavy equipment and skilled operators, we provide fast, efficient, and environmentally responsible site preparation.

    Does VALROC work with engineers and surveyors to ensure proper site preparation?

    Yes! We collaborate with civil engineers, geotechnical specialists, and land surveyors to ensure:

    • Proper grading & foundation stability – Verifying compaction levels and soil conditions.

    • Drainage planning & erosion control – Meeting municipal and environmental regulations.

    • Utility coordination – Planning and trenching for water, sewer, and electrical installations.

    • Zoning and compliance checks – Ensuring the site meets building code requirements.

    With engineering-backed site preparation, we prevent costly mistakes and ensure long-term durability.

    Does VALROC work with engineers and surveyors to ensure proper site preparation?

    Yes! We collaborate with civil engineers, geotechnical specialists, and land surveyors to ensure:

    • Proper grading & foundation stability – Verifying compaction levels and soil conditions.

    • Drainage planning & erosion control – Meeting municipal and environmental regulations.

    • Utility coordination – Planning and trenching for water, sewer, and electrical installations.

    • Zoning and compliance checks – Ensuring the site meets building code requirements.

    With engineering-backed site preparation, we prevent costly mistakes and ensure long-term durability.

    What permits are required for site preparation, and does VALROC handle them?

    Site preparation may require permits and regulatory approvals, including:

    • Land clearing & tree removal permits – Required in environmentally protected zones.

    • Excavation & grading permits – Ensuring compliance with zoning and stormwater management laws.

    • Utility coordination approvals – For safe installation of water, sewer, and electrical systems.

    • Erosion control & sediment management plans – Ensuring compliance with environmental standards.

    At VALROC Development Ltd., we assist with permit applications and compliance, ensuring a smooth approval process for your project.

    What permits are required for site preparation, and does VALROC handle them?

    Site preparation may require permits and regulatory approvals, including:

    • Land clearing & tree removal permits – Required in environmentally protected zones.

    • Excavation & grading permits – Ensuring compliance with zoning and stormwater management laws.

    • Utility coordination approvals – For safe installation of water, sewer, and electrical systems.

    • Erosion control & sediment management plans – Ensuring compliance with environmental standards.

    At VALROC Development Ltd., we assist with permit applications and compliance, ensuring a smooth approval process for your project.

    What happens after site preparation is completed?

    Once site preparation is finished, we move on to the next construction phases, including:

    • Foundation excavation & trenching – Preparing for footings, basements, and concrete work.

    • Utility installation – Running lines for water, sewer, gas, and electrical services.

    • Final grading & soil compaction – Ensuring a stable base for driveways, roads, and landscaping.

    • Concrete pouring & initial construction – Transitioning into structural development.

    Because VALROC Development Ltd. provides full-service construction support, we ensure seamless coordination from site preparation to final build.

    What happens after site preparation is completed?

    Once site preparation is finished, we move on to the next construction phases, including:

    • Foundation excavation & trenching – Preparing for footings, basements, and concrete work.

    • Utility installation – Running lines for water, sewer, gas, and electrical services.

    • Final grading & soil compaction – Ensuring a stable base for driveways, roads, and landscaping.

    • Concrete pouring & initial construction – Transitioning into structural development.

    Because VALROC Development Ltd. provides full-service construction support, we ensure seamless coordination from site preparation to final build.

    METRO VANCOUVER GROUNDWORK

    Property specific site preparation across Metro Vancouver

    From Langley, VALROC provides site preparation for custom homes, garages, shops, additions and exterior construction. Clearing, selective demolition, excavation, material removal, imported aggregate, compaction and rough grading are coordinated with the building footprint, access route and required elevations.

    Projects in Surrey and White Rock may require slope and retaining coordination, Burnaby infill sites often need compact equipment and controlled deliveries, and Delta properties can place greater emphasis on drainage and ground conditions. The prepared site must support the construction stages that follow.