/*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();

Concrete driveways, Metro Vancouver

Professional Concrete Driveway Installation Across Metro Vancouver

VALROC designs and installs concrete driveways for homeowners across Metro Vancouver. Each driveway begins with an assessment of access, grading, drainage, intended use and existing site conditions so the finished installation is designed for the property

Start with a property assessment and a clearly defined scope of work.

Driveway replacement

Replacing damaged driveways

VALROC can remove the existing surface, prepare the ground and install the new concrete driveway.

Driveway rebuilding

Address potential issues

Standing water, surrounding transitions, elevation connections can be corrected within the project scope.

Beyond the driveway

Coordinate concrete features

Custom colours / finishes, adding stairs, sidewalks, borders and transitions can be planned as one property outcome.

CONCRETE DRIVEWAY CONSTRUCTION

How a concrete driveway is built from removal through handover

Each concrete driveway stage has a distinct purpose. Removal exposes the existing conditions; excavation, subgrade preparation and base compaction establish support; formwork, reinforcement and placement shape the slab; finishing and cleanup complete the work. The exact scope is adjusted to the property, drainage, access and intended vehicle use.

  1. Mini excavator removing an existing concrete driveway in Surrey, BC

    Step 1

    Concrete Driveway Demolition

    Concrete driveway demolition clears the way for a new installation by removing failed surfaces with precision tools, tight-access equipment, and eco-conscious concrete recycling.

    • Driveway demolition
    • Concrete removal
    • Concrete recycling
  2. Premium sub-base gravel driveway installation

    Step 2

    Concrete Driveway Site Prep

    Concrete driveway site prep includes grading, subbase rebuilding, and drainage planning to eliminate common causes of failure and ensure long-term strength and stability.

    • Sub-base preparation
    • Grading and drainage
    • Soil compaction
  3. Custom concrete forms for a brand new driveway installation in Langley Brookswood canada

    Step 3

    Concrete Driveway Formwork

    Concrete driveway formwork defines the final shape, slope, and thickness of the slab while ensuring crisp edges, smooth transitions, and a long-lasting finished surface.

    • Concrete formwork
    • Driveway layout
    • Joint planning
  4. Installing rebar for driveway installation

    Step 4

    Concrete Driveway Reinforcement

    Concrete driveway reinforcement uses rebar, mesh, and custom tie-ins to prevent cracking, handle vehicle loads, and improve durability through seasonal weather shifts.

    • Structural reinforcement
    • Load distribution
    • Crack control
  5. VALROC placing concrete for a driveway extension with custom forms and a grass inlay

    Step 5

    Concrete Driveway Placement

    Concrete driveway placement involves pouring, leveling, and compacting the slab with precision to ensure a durable, crack-resistant surface ready for finishing.

    • Concrete placement
    • Slab consistency
    • Controlled pouring
  6. Explore Concrete Driveway Finishing

    Step 6

    Concrete Driveway Finishing

    Driveway finishing includes joint placement, surface texturing, and edge detailing to improve traction, minimize cracking, and deliver a clean, polished result.

    • Concrete finishing
    • Surface traction
    • Curing protection
  7. Pressure washing exposed aggregate after new concrete install installation

    Step 7

    Concrete Driveway Cleanup

    Final driveway cleanup includes debris removal, surface detailing, and jobsite restoration, ensuring a polished handoff with clear instructions for customer use and care.

    • Site cleanup
    • Debris removal
    • Final inspection

Video : Concrete Driveway Installations

At Valroc, we set ourselves apart by owning our entire fleet of heavy machinery, concrete industry equipment / tooling and employing a dedicated, in-house team of concrete professionals ensuring your new driveway is built to the highest standards.

This video walks you through a typical residential driveway restoration project, showcasing our team in action.

can you 

PLANNED AROUND THE PROPERTY

Concrete driveway capability that connects scope, site conditions and construction

A durable concrete driveway begins with understanding the property and defining the work before construction starts. VALROC coordinates the required crew, equipment, materials and connected stages around access, grading, drainage, intended use and the agreed result.

DEFINED SCOPE

Know what the driveway project includes

The onsite assessment and written scope distinguish removal, preparation, reinforcement, drainage, finishes and related property work.

COORDINATED WORK

Keep the construction stages connected

Crews, equipment, material delivery and access are planned around the approved driveway sequence and the conditions on the property.

PROPERTY FIT

Match the driveway to its use and surroundings

Layout, elevations, surface choices and adjoining features are considered together rather than treating the driveway as an isolated slab.

FINISHES AND PERFORMANCE CHOICES

Concrete driveway options selected around appearance, traction and intended use

Broom finish and joint layout are identified as standard selections for this service. Decorative finishes, colour, forming details, reinforcement, thickness, drainage transitions and surface protection are reviewed as additional choices where they suit the property and approved scope.

Concrete driveway installation support

Included in our service:

  • • Driveway layout and property access review

  • • Premium compacted sub-base

  • • Forms set to approved dimensions

  • • Drainage slopes away from structures

  • • Trackable concrete from established suppliers

  • • Reinforcement placed as specified

  • • Concrete placement and professional finishing

  • • Control joints planned for the driveway

  • • Garage, sidewalk and roadway transitions

  • • Written scope, warranty and final walkthrough

Additional driveway options that are available

Exposed aggregate concrete driveway finish

Texture favourite · Slip resistant texture
Exposed aggregate driveway · Textured driveway surface

Stamped concrete driveway patterns

Design flexibility · Custom patterns and colour
Stamped concrete driveway · Patterned driveway finish

Rebar reinforcement for concrete driveways

Strength upgrade · Added load support
Concrete driveway reinforcement · Driveway load support

Finish, joint layout, reinforcement, slab requirements, drainage and adjoining elevations affect one another. Suitability and inclusion should be confirmed in the written scope; an option label must not imply that required structural work can be omitted.

Choose options as one coordinated system

View other available options

Integrated French Drainage

Where runoff or wet ground affects a concrete driveway, integrated French drainage may be coordinated with grading and base preparation to help manage water beside the paved area. | Additional cost

Custom Concrete Thickness

For a concrete driveway expected to carry heavier vehicles or equipment, slab thickness can be assessed alongside the base, reinforcement and actual loading requirements. | Additional cost

Concrete Decorative Edging

Decorative edging can define a concrete driveway's borders and create a deliberate transition to walkways, planting beds or adjoining hardscape. | Additional cost

Custom Concrete Forming

Custom forming can shape a concrete driveway around curves, flared entrances or uneven property lines while maintaining the planned grades and edge layout. | Additional cost

Mixed-Finish Inlay Designs for Concrete

Mixed-finish inlays can distinguish the driveway approach, borders or pedestrian connections through coordinated textures and colours planned before concrete placement. | Additional cost

Smooth Trowel Concrete Finish

A smooth-trowel finish is not the default for an exposed concrete driveway; consider it only for a suitable sheltered area after reviewing wet-weather traction. | Additional cost

Colour Options for Concrete Finishes

Concrete colour options can help a driveway relate to the home's exterior and adjacent hardscape while keeping the finish choice consistent with the planned layout. | Additional cost

Concrete Staining Options

Concrete staining can add variegated colour to a suitable driveway surface, with the desired appearance and ongoing care reviewed before it is selected. | Additional cost

Concrete Additives : Accelerators, Retarders, Binders & Hardeners

For a concrete driveway pour with particular weather, placement or finishing demands, a suitable mix additive may be considered after checking compatibility with the specified concrete and finish. | Additional cost

Concrete Sealing for Surface Protection

A compatible sealer may be selected for a concrete driveway to support surface care, with the finish, vehicle use and maintenance expectations reviewed first. | Additional cost

Catch Basin Lid Adjustment

If a driveway meets an existing catch basin, adjusting the lid and rim elevation may be separately scoped so the finished concrete grades connect appropriately to the drainage inlet. | Additional cost

BEYOND THE DRIVEWAY

Plan the driveway around the rest of the property

Driveways connect to sidewalks, steps, garage slabs, road approaches, drainage systems and changes in property elevation. Coordinating those conditions before placement helps the new concrete work as part of the complete property.

Connected work is not automatically included. Each related service must be confirmed as suitable, selected and documented in the project scope.

  • Connecting sidewalks to the concrete driveway

    Concrete sidewalks that connect to the driveway

    • Driveway sidewalks
    • Concrete transitions
    • Pedestrian access

    Coordinate pedestrian routes, transitions and finished elevations with the concrete driveway layout so the walkway and driving surface meet cleanly.

    Explore sidewalks that connect to driveways
  • Man working on staircase construction in Vancouver, BC, residential project, building new wooden steps.
  • Aaron team member installing a trench drain in front of a garage diverting water that has been damaging the concrete and undermining the foundation

    Drainage coordinated with the driveway

    • Driveway drainage
    • Drainage trenching
    • Water control

    We can install trench drains, French drains, catch basins and required trenching where surface water affects the driveway or nearby structures.

    Explore drainage work for driveways
  • Retaining walls for driveway grade changes

    • Driveway retaining wall
    • Grade support
    • Stair transition

    Engineered retaining walls support sloped driveway edges and create space for properly designed vehicle barriers, lighting, steps and stairs.

    Explore retaining walls that connect to driveways

DOCUMENTED EXPERIENCE

Concrete driveway experience across Metro Vancouver

VALROC builds concrete driveways for homes, strata properties and businesses across Metro Vancouver. Our experience helps coordinate excavation, base preparation, grading, drainage and connections to garages, sidewalks, steps and surrounding concrete. From Brookswood, Willoughby and Walnut Grove to Cloverdale, South Surrey, White Rock and Burnaby, our concrete crews understand the local grades, municipal requirements and neighbourhood conditions that shape driveway construction.

DEFINE THE DRIVEWAY SCOPE

A concrete driveway estimate built around the property and selected work

During your free onsite visit, you’ll meet with a member of our team who specializes in concrete installations. Send your questions beforehand or bring a list to work through together. It’s your opportunity to share ideas, explore options and understand how your driveway will be built, so you can make informed decisions and we can plan the work with a clear understanding of your goals.

  • Share the property and intended result

    Explain what needs to change, how the driveway is used and any known access, drainage or adjoining-work concerns.

  • Review conditions onsite

    Assess the existing surface, grades, access, preparation needs and the options relevant to the property.

  • Receive a defined scope

    Review standard inclusions, additional choices, site-dependent work and responsibilities before construction begins.

  • What affects the cost of a concrete driveway?

    Removal volume, site access, ground and drainage conditions, driveway size and layout, reinforcement or slab requirements, finish selection and connected property work can all affect scope and cost. A property assessment is required before those factors can be priced responsibly.

    What affects the cost of a concrete driveway?

    Removal volume, site access, ground and drainage conditions, driveway size and layout, reinforcement or slab requirements, finish selection and connected property work can all affect scope and cost. A property assessment is required before those factors can be priced responsibly.

    Request Your Free On-site Estimate

    START WITH THE PROPERTY

    A concrete driveway recommendation begins with actual site conditions

    Our onsite assessment establishes how the driveway will be used, how vehicles enter and turn, what lies beneath the existing surface, where water travels and how the driveway connects to the garage, road and surrounding landscape.

  • 01

    Review access and intended use

    Confirm vehicle movements, property access, construction access and the outcome the driveway needs to support.

  • 02

    Evaluate grades and drainage

    Identify current elevations, water movement and connections to the road, garage and surrounding surfaces.

  • 03

    Assess the existing structure

    Consider the existing driveway, ground conditions, removal requirements and what must be verified once the surface is opened.

  • 04

    Define the recommended scope

    Bring preparation, reinforcement, thickness, finishes and connected property work into one written recommendation.

  • Why the recommendation is property-specific

    No two concrete driveways are the same and can require different preparation, drainage, reinforcement or access planning. The recommendation should reflect observed conditions and the intended use rather than applying one standard detail to every property.

    Why the recommendation is property-specific

    No two concrete driveways are the same and can require different preparation, drainage, reinforcement or access planning. The recommendation should reflect observed conditions and the intended use rather than applying one standard detail to every property.

    QUESTIONS BEFORE CONSTRUCTION

    Concrete driveway details worth understanding before the work begins

    These questions cover finish selection, subbase preparation, reinforcement, driveway thickness, curing, maintenance and the timing of use. The connected FAQ records provide the detailed answers while property-specific recommendations remain part of the onsite assessment.

    What makes VALROC Development Ltd. the best choice for a concrete driveway?

    Choosing the right contractor for a concrete driveway comes down to experience, proper licensing, and how well the work is planned before concrete is ever poured.

    • Clear written scopes that define thickness, reinforcement, drainage, and finish expectations.
    • Proper subbase preparation and compaction to prevent settling, cracking, and premature failure.
    • Reinforcement choices that match vehicle loads, access patterns, and long-term use.

    On most projects, VALROC starts with an on-site review, sequences the work carefully, and builds each driveway to suit the specific loads, access conditions, and property layout discussed upfront.

    What makes VALROC Development Ltd. the best choice for a concrete driveway?

    Choosing the right contractor for a concrete driveway comes down to experience, proper licensing, and how well the work is planned before concrete is ever poured.

    • Clear written scopes that define thickness, reinforcement, drainage, and finish expectations.
    • Proper subbase preparation and compaction to prevent settling, cracking, and premature failure.
    • Reinforcement choices that match vehicle loads, access patterns, and long-term use.

    On most projects, VALROC starts with an on-site review, sequences the work carefully, and builds each driveway to suit the specific loads, access conditions, and property layout discussed upfront.

    What are the most popular concrete driveway finishes, and how do I choose?

    Concrete driveways can be finished in several ways, and the right choice depends on how you want the surface to look, feel, and perform over time.

    • Broom finish for a clean, classic appearance with reliable traction.
    • Exposed aggregate for a decorative surface that highlights natural stone and offers durability.
    • Stamped concrete to replicate brick, stone, or wood patterns.
    • Coloured concrete using integral colour or staining for a more customized look.
    • Inlay designs with borders or contrasting textures for added detail.

    VALROC helps clients choose a finish based on the property style, expected use, local climate, and long-term maintenance considerations.

    What are the most popular concrete driveway finishes, and how do I choose?

    Concrete driveways can be finished in several ways, and the right choice depends on how you want the surface to look, feel, and perform over time.

    • Broom finish for a clean, classic appearance with reliable traction.
    • Exposed aggregate for a decorative surface that highlights natural stone and offers durability.
    • Stamped concrete to replicate brick, stone, or wood patterns.
    • Coloured concrete using integral colour or staining for a more customized look.
    • Inlay designs with borders or contrasting textures for added detail.

    VALROC helps clients choose a finish based on the property style, expected use, local climate, and long-term maintenance considerations.

    Why is the subbase so important for a long-lasting concrete driveway?

    The subbase is the structural layer that supports the concrete and determines whether a driveway stays stable or begins to settle and crack over time.

    • Poorly compacted or soft soils can shift with seasonal moisture and temperature changes.
    • Inadequate base materials allow water movement, which weakens support under the slab.
    • Uneven subbase preparation often leads to cracking, sinking, and drainage issues.

    On VALROC projects, we assess existing ground conditions, build a properly compacted subbase, and set grades to control water flow before any concrete is placed.

    Why is the subbase so important for a long-lasting concrete driveway?

    The subbase is the structural layer that supports the concrete and determines whether a driveway stays stable or begins to settle and crack over time.

    • Poorly compacted or soft soils can shift with seasonal moisture and temperature changes.
    • Inadequate base materials allow water movement, which weakens support under the slab.
    • Uneven subbase preparation often leads to cracking, sinking, and drainage issues.

    On VALROC projects, we assess existing ground conditions, build a properly compacted subbase, and set grades to control water flow before any concrete is placed.

    How long does it take to install a concrete driveway, and when can I use it?

    The subbase is the structural support under the concrete, and it largely determines whether a driveway stays level or starts to settle and crack.

    • If the base is soft.
    • or poorly compacted.
    • seasonal soil movement can shift the slab.

    On a VALROC project, we assess the existing ground, build a compacted base to suit the site, and set grades so water sheds away before any concrete is placed.

    How long does it take to install a concrete driveway, and when can I use it?

    The subbase is the structural support under the concrete, and it largely determines whether a driveway stays level or starts to settle and crack.

    • If the base is soft.
    • or poorly compacted.
    • seasonal soil movement can shift the slab.

    On a VALROC project, we assess the existing ground, build a compacted base to suit the site, and set grades so water sheds away before any concrete is placed.

    How do I maintain my concrete driveway to keep it looking great?

    Proper maintenance keeps your driveway strong, clean, and visually appealing. VALROC recommends:

    • Sealing the surface every 2 to 3 years to protect against moisture, stains, and UV damage.

    • Cleaning regularly with a hose or pressure washer to remove dirt and debris.

    • Avoiding de-icing salts in winter, which can cause surface deterioration.

    • Repairing minor cracks early to prevent larger structural issues.

    • Ensuring proper drainage around the driveway, reducing water infiltration.

    With VALROC’s premium materials and expert installation, your concrete driveway will remain strong and beautiful for years to come.

    How do I maintain my concrete driveway to keep it looking great?

    Proper maintenance keeps your driveway strong, clean, and visually appealing. VALROC recommends:

    • Sealing the surface every 2 to 3 years to protect against moisture, stains, and UV damage.

    • Cleaning regularly with a hose or pressure washer to remove dirt and debris.

    • Avoiding de-icing salts in winter, which can cause surface deterioration.

    • Repairing minor cracks early to prevent larger structural issues.

    • Ensuring proper drainage around the driveway, reducing water infiltration.

    With VALROC’s premium materials and expert installation, your concrete driveway will remain strong and beautiful for years to come.

    Should I use fiber mesh or rebar reinforcement in my concrete driveway?

    Both fibre mesh and rebar are used to reinforce concrete driveways, but they serve different purposes depending on how the driveway is expected to perform.

    • Fibre mesh helps limit small surface cracking as concrete cures and is mainly intended for crack control.
    • Rebar provides structural strength and helps the slab handle heavier loads, soil movement, and stress at edges or transitions.
    • In many cases, reinforcement decisions are influenced by subbase quality, drainage, slab thickness, and vehicle use.

    VALROC reviews how the driveway will be used and how the site behaves, then selects reinforcement methods that suit real conditions rather than relying on default specifications.

    Should I use fiber mesh or rebar reinforcement in my concrete driveway?

    Both fibre mesh and rebar are used to reinforce concrete driveways, but they serve different purposes depending on how the driveway is expected to perform.

    • Fibre mesh helps limit small surface cracking as concrete cures and is mainly intended for crack control.
    • Rebar provides structural strength and helps the slab handle heavier loads, soil movement, and stress at edges or transitions.
    • In many cases, reinforcement decisions are influenced by subbase quality, drainage, slab thickness, and vehicle use.

    VALROC reviews how the driveway will be used and how the site behaves, then selects reinforcement methods that suit real conditions rather than relying on default specifications.

    Should rebar be tied into the foundation when installing a garage approach?

    In most cases, tying rebar into the garage foundation is recommended when installing a concrete garage approach.

    • Helps prevent the driveway slab from separating from the garage over time.
    • Reduces movement and settling at the transition point.
    • Provides added structural support where vehicles repeatedly enter and exit.

    VALROC typically drills and dowels rebar into the existing footing or foundation so the driveway and garage slab act as one continuous, stable structure.

    Should rebar be tied into the foundation when installing a garage approach?

    In most cases, tying rebar into the garage foundation is recommended when installing a concrete garage approach.

    • Helps prevent the driveway slab from separating from the garage over time.
    • Reduces movement and settling at the transition point.
    • Provides added structural support where vehicles repeatedly enter and exit.

    VALROC typically drills and dowels rebar into the existing footing or foundation so the driveway and garage slab act as one continuous, stable structure.

    What is the recommended thickness for a concrete driveway?

    The recommended thickness for a concrete driveway depends on the type of vehicles it needs to support and how the space will be used.

    • Standard residential driveways are typically poured at about 4 inches thick, which is suitable for cars and light-duty vehicles.
    • Driveways that regularly support heavier vehicles like SUVs, trailers, or small RVs are usually built at 5 to 6 inches for added strength.
    • Commercial or truck-access areas often require 6 to 8 inches of concrete, along with engineered reinforcement, to handle higher loads.

    On real projects, VALROC determines slab thickness alongside subbase preparation and reinforcement so the driveway is built to handle the actual loads and site conditions it will see over time.

    What is the recommended thickness for a concrete driveway?

    The recommended thickness for a concrete driveway depends on the type of vehicles it needs to support and how the space will be used.

    • Standard residential driveways are typically poured at about 4 inches thick, which is suitable for cars and light-duty vehicles.
    • Driveways that regularly support heavier vehicles like SUVs, trailers, or small RVs are usually built at 5 to 6 inches for added strength.
    • Commercial or truck-access areas often require 6 to 8 inches of concrete, along with engineered reinforcement, to handle higher loads.

    On real projects, VALROC determines slab thickness alongside subbase preparation and reinforcement so the driveway is built to handle the actual loads and site conditions it will see over time.

    Concrete needs time to cure properly before handling traffic. Here’s a standard usage timeline:

    Concrete needs adequate curing time before it can safely handle traffic without risking surface damage or long-term strength loss.

    • Foot traffic is typically safe after 24 to 48 hours.
    • Light vehicle use is usually recommended after 20 to 25 days.
    • Heavy vehicles such as RVs or trucks should wait a min of 28 days, once the concrete reaches full strength.

    VALROC manages curing timelines based on mix design, weather conditions, and finish type, including additional sealing time for stamped or exposed aggregate surfaces.

    Concrete needs time to cure properly before handling traffic. Here’s a standard usage timeline:

    Concrete needs adequate curing time before it can safely handle traffic without risking surface damage or long-term strength loss.

    • Foot traffic is typically safe after 24 to 48 hours.
    • Light vehicle use is usually recommended after 20 to 25 days.
    • Heavy vehicles such as RVs or trucks should wait a min of 28 days, once the concrete reaches full strength.

    VALROC manages curing timelines based on mix design, weather conditions, and finish type, including additional sealing time for stamped or exposed aggregate surfaces.

    Concrete driveway service area

    Concrete driveway construction across Metro Vancouver

    From our Langley construction yard, VALROC installs concrete driveways across Brookswood, Willoughby, Walnut Grove and surrounding communities. Excavation, compacted subbase, forming, reinforcement, concrete delivery and finishing are coordinated around garage elevations, drainage, vehicle use and the connection to the roadway.

    Concrete driveways in Surrey and Delta may serve larger residential properties or additional parking, while Burnaby and White Rock projects can involve steeper grades, tighter access and connections to stairs or retaining walls. Each driveway is planned as part of the wider property rather than an isolated slab.