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

Artikelen over Verbindende / Geweldloze communicatie

Emotionele intelligentie, Psyhologische veiligheid, Geweldloze communicatie, Mindfulness, Deep democracy

In dit blog vind je artikelen over Verbindende / Geweldloze communicatie en gerelateerde onderwerpen in het domein van Emotionele intelligentie en Psychologische veiligheid.  Op deze pagina vind je de meest recente artikelen. Kijk hier voor het overzicht van alle posts.  Wil je op de hoogte blijven, meld je dan aan met je email adres onderaan de pagina. Veel leesplezier!

  • Stop polarisatie in je team

    Het structureel aanbieden van training in geweldloze communicatie in combinatie met gerichte inclusietraining is een succesvolle combinatie om polarisatie in teams tegen te gaan, zo betoogt Vivian Acquah van Amplify DEI.
    Lees verder
    Vivian Acquah over polarisatie Geweldloze communicatie en Inclusie
  • Geweldloos verzet en Geweldloze communicatie: moedig ouderschap in verbinding

    Geweldloos verzet en Verbindend gezag worden soms verward met Geweldloze of Verbindende communicatie. Dat is begrijpelijk, omdat beide benaderingen geworteld zijn in dezelfde principes van Nonviolence. Lees hier wat ze voor jou als ouder kunnen betekenen, en wat Equanimity hierover te bieden heeft.
    Lees verder
    geweldloos verzet en geweldloze communicatie verbindend gezag en verbindenden communicatie
  • Psychologische veiligheid in teams met Geweldloze communicatie

    In ieder team zijn er verschillen van mening, twijfels over besluiten, andere perspectieven, een gevoel dat er een betere oplossing mogelijk is. Of we ons wel of niet uitspreken op de werkvloer zegt veel over de cultuur van een team. Hebben we het idee dat onze input welkom is of houden we het voor ons?
    Lees verder
    hoe kan geweldloze communicatie bijdragen aan psychologische veiligheid
  • Geweldloosheid (Nonviolence) als ‘de derde weg’

    In dit artikel verken ik de betekenis van geweldloosheid als “de derde weg”. Geïnspireerd door het werk van Marshall Rosenberg, Mahatma Gandhi, Martin Luther King en Walter Wink kijken we naar geweldloosheid als een manier om actief op te komen voor rechtvaardigheid zonder de menselijkheid van de ander op te geven.
    Lees verder
    geweldloosheid de derde weg nonviolence as the third way
  • Empathie-valkuilen: waarom goedbedoelde reacties soms totaal niet helpen

    Wanneer je boos bent, ergens mee zit of iets verdrietigs hebt meegemaakt, hoop je op een empathische reactie van een ander. Toch is niet iedere reactie die je krijgt en die wellicht goed bedoeld is, ook daadwerkelijk helpend. Hoe komt dat?
    Lees verder
    de empathie valkuil
  • Conflict en de kunst van het verbinden

    Het vermogen om conflicten aan te gaan en op te lossen is één van de basispijlers van goed presterende teams. Maar hoe creëer je een duurzame cultuur die diversiteit omarmt en waar conflicten gezien kunnen worden als een weg naar verbinding, innovatie en vernieuwing?
    Lees verder
    conflict als kans voor verbinding
  • Baas in eigen oor: de vier manieren van luisteren in Geweldloze communicatie

    Wat we horen is in zekere zin een keuze. Door te leren herkennen welke oren we op hebben ontstaat er ruimte om bewust te kiezen hoe je gaat reageren. Binnen Geweldloze Communicatie worden verschillende manieren van luisteren onderscheiden waarmee je kunt oefenen.
    Lees verder
    empathisch luisteren als een giraf
  • Schaamte als sleutel naar verbinding

    Meestal zien we boosheid, schuld en schaamte als gevoelens waar we liever van af willen. We vinden ze ongemakkelijk, soms beschamend en dus duwen we ze weg - vaak al voordat we ons ervan bewust zijn dat we ze hebben. Maar wat nu als juist deze gevoelens de sleutels zijn naar verbinding?
    Lees verder
    schaamte en schuld
  • Balans in emotieregulatie: over het Gevaarsysteem, Jaagsysteem en Zorgsysteem

    Professor Paul Gilbert benadrukt dat een goede balans tussen drie emotieregulatie systemen essentieel is voor ons welzijn. Hoe kunnen Geweldloze communicatie en Mindfulness bijdragen aan deze balans?
    Lees verder
    Het Gevaarsysteem, het Jaagsystem en het Zorgsysteem. Emotieregulatie met Geweldloze communicatie en Mindfulness en compassie
  • “Hoezo geweldloos?” Over ‘Nonviolence’ in Geweldloze communicatie

    "Dat woord 'Geweldloos', ik weet het niet hoor, moeten we nou de hele tijd aardig tegen elkaar gaan doen ofzo?". Niet zelden hoor ik een variant op deze zin bij aanvang van een training bij een bedrijf of organisatie. Kennelijk roept het woord een allergische reactie bij sommige mensen op.
    Lees verder
    Nonviolence ahimsa geweldloosheid en geweldloze communicatie
  • Quasi-gevoelens en hoe ze bijdragen aan conflict en polarisatie

    Het uitspreken van je gevoelens kan erg opluchten en een verbindend effect hebben. Toch stuit je misschien ook wel eens op weerstand of irritatie. Hoe komt dat? De kans is groot dat je je hebt uitgesproken in quasi-gevoelens.
    Lees verder
    quasi emoties quasi gevoelens gedoelens
  • Gabor Maté over de mythe van normaal

    Iedereen verlangt naar verbinding, en soms is dit verlangen zo groot dat we onderweg onszelf verliezen. In zijn boek 'De mythe van normaal' laat arts en trauma-expert Gabor Maté zien hoe dat gebeurt en hoe we onze authenticiteit kunnen hervinden. Geweldloze Communicatie kan ons daarbij helpen.
    Lees verder
    gabor mate en geweldloze communicatie nonviolen communication
  • Over de stille macht van de superrijken en onze eigen invloed

    Als we willen bouwen aan een wereld van gelijkwaardigheid en zorg voor de planeet, kunnen we niet blijven denken binnen de kaders van het huidige systeem. Het vraagt om het durven zien van de stille invloed van de machtigen én van onze eigen invloed op de wereld.
    Lees verder
    Winners Take All van Anand Giridharadas en macht van de superrijken
  • De Giraf en de Jakhals in Geweldloze communicatie

    De Giraf en de Jakhals worden in Verbindende / Geweldloze communicatie gebruikt als metafoor voor verschillende manier van denken en communiceren. De Jakhals staat daarbij voor denken en communiceren vanuit dominantie en onderwerping en de Giraf voor denken en communiceren vanuit compassie en zelfbewustzijn.
    Lees verder
    verschillende manieren van luisteren in geweldloze communicatie
  • Verbindende besluitvorming: Deep democracy en Geweldloze communicatie

    Waar Geweldloze communicatie zich met name richt op indivuele introspectie en interpersoonlijke dialoog, richt Deep Democracy zich meer op gespreksvoering en besluitvorming met groepen. In deze post vertel ik hoe Deep Democracy en Geweldloze communicatie elkaar kunnen aanvullen.
    Lees verder
    geweldloze communicatie in deep democracy
  • Waarom leuk werk je ziek kan maken

    Hoe komt het dat mensen met leuk of betekenisvol werk substantieel vaker 'omvallen'? Hoogleraar Media Studies Mark Deuze schreef er een boek over waarin hij uiteenzet waarom medewerkers uit de creatieve sector onevenredig veel te maken hebben met stress, burn-out en depressie.
    Lees verder
    stress en burnout in de creatieve sector
  • Omgaan met boosheid en irritatie

    Boosheid is een primaire vechtreactie, waarbij er maar weinig ruimte zit tussen de aanleiding van je boosheid, en jouw reactie daarop. Hoe bozer je wordt hoe minder innerlijke ruimte je hebt om nog te relativeren en te luisteren en hoe moeilijker het wordt om te voelen en te bedenken wat je wél wilt. Hoe beter…
    Lees verder
    omgaan met boosheid en irritatie
  • De kunst van het niet beledigd zijn

    Als de woede van iemand op ons afkomt, is onze primaire reactie ons te verdedigen door van ons af te bijten en terug schelden, of we zoeken dekking door ons klein en onzichtbaar te maken. Dit helpt eigenlijk nooit. Als je heel hard terug scheldt kom je samen in een neerwaartse spiraal van verwijten en…
    Lees verder
    omgaan met woede en boosheid door geweldloze communicatie en empathie
  • Van Safe space naar Brave Space: Psychologische veiligheid in de creatieve sector

    Er is veel aandacht voor psychologische veiligheid in de creatieve sector. In de film- en televisiewereld, de modewereld en de podiumkunsten, overal wordt machtsmisbruik, seksisme en discriminatie steeds verder uit het normaal getrokken. Maar er is nog steeds een weg te gaan. Wat is er nodig om psychologische veiligheid te bereiken?
    Lees verder
    van brave space naar safe space met geweldloze communicatie en mindfulness
  • Duurzame verbindingen in CPO Wij_land

    Sinds twee jaar woon ik met veel plezier in Wij_land, een CPO (Collectief Particulier Opdrachtgeverschap) op Centrumeiland, IJburg in Amsterdam. Graag deel ik mijn ervaringen over het wonen in Wij_land en wat Geweldloze Communicatie kan betekenen voor een CPO.
    Lees verder
    wijland CPO centrum eiland amsterdam IJBURG
  • Vrede kun je leren

    “Wake me up when it’s all over” las ik op een steunpilaar van de A1 langs het kanaal. Kon het maar zo eenvoudig zijn. Dat we op een dag wakker worden en dat alle uitdagingen die op ons afkomen ineens opgelost zijn: Corona, klimaatproblemen, polarisatie, oorlog en vluchtelingenstromen. Helaas. De consequenties van onze manier van…
    Lees verder
    Vrede kun je leren Equanimity Geweldloze communicatie en mindfulness
  • Waar komen de Giraf- en de Jakhalspop vandaan?

    Om verschillende manieren van communiceren te illustreren, worden in Geweldloze communicatie de Giraf en de Jakhals als symbool gebruikt. Maar waar komen die malle poppen van Marshall Rosenberg eigenlijk vandaan?
    Lees verder
    jakhals en giraffe poppen marshall rosenberg
  • Insight dialogue: mediteren in interactie

    Insight Dialogue is een vorm van Vipassana meditatie maar dan in interactie met anderen. De methode is ontwikkeld door de Amerikaan Gregory Kramer. In plaats van alleen in stilte te zitten, deel je bij Insight Dialogue je ervaringen met anderen tijdens het mediteren. Je oefent als het ware om in contact te blijven met jezelf…
    Lees verder
    Insight dialogue MIndfulness Vipassana meditatie geweldloze communicatie
  • Ik hoor bij mezelf en daarom bij iedereen

    ‘Erbij horen’ is voor mij altijd een lastig onderwerp geweest. Lange tijd beschouwde ik mezelf waar en met wie ik ook was als een buitenstaander. Maar toen ik ouder werd gebeurde er iets geks. Telkens als ik mensen tegenkwam van vroeger spraken ze steevast over mij en zichzelf in termen van ‘ons’ en ‘wij’. Tot…
    Lees verder
    erbij horen jezelf zijn equanimity emotionele intelligentie en geweldloze communicatie
  • De Vrijman: Verbinding in de buurt

    De Vrijman is een ontmoetingsplek voor bezinning, verbinding en inspiratie van en voor bewoners van IJburg in Amsterdam. We bieden allerlei activiteiten aan zoals Yoga-, Tai Chi en Ademlessen en ik geef er zelf de Mindfulness en Geweldloze communicatietrainingen van Equanimity.
    Lees verder
    de vrijman mindfulness geweldloze communicatie IJburg amsterdam
  • Yuval Noah Harari en het ontstaan van dominantie systemen

    In zijn boek “Sapiens" omschrijft Yuval Noah Harari de ontwikkeling van de menselijke beschaving. Hij laat zien hoe het ontstaan van samenlevingen altijd gepaard gaat met het geloof in een dominante ‘fictieve’ waarheid waarin bepaalde mensen als belangrijker worden neergezet dan anderen. Harari's concept van de ‘denkbeeldige orde is vergelijkbaar met het concept van de…
    Lees verder
  • Over Marshall Rosenberg

    De Amerikaanse psycholoog Marshall Rosenberg (1934 – 2015) is de bedenker van het model voor Nonviolent communication (in het Nederlands Geweldloze of Verbindende communicatie genoemd). Geweld in de definitie van Rosenberg is vrij breed. Het kan gericht zijn op een ander maar ook op jezelf. Het kan verbaal of fysiek zijn, maar ook iemand negeren…
    Lees verder
    Marshall Rosenberg geweldloze communicatie verbindende communicatie nonviolebt communication
  • Oefenen met gevoelenskaarten en behoeftekaarten

    In Geweldloze communicatietrainingen en Emotionele intelligentie workshops van Equanimity wordt veel gebruik gemaakt van Gevoelenskaarten en behoeftekaarten. In deze blogpost lees je meer over waarom dergelijke kaarten zo’n handig hulpmiddel zijn, en vind je een link naar verschillende aanbieders van vergelijkbare kaartensets.
    Lees verder
    gevoelenskaarten en behoeftekaarten
  • Het verschil tussen schaamte en schuld

    Hoewel je vast wel eens schaamte en schuld ervaart, is de kans groot dat je niet makkelijk onder woorden kunt brengen hoe deze emoties precies voelen. Dat is niet zo gek, want we willen schaamte en schuld liever niet voelen en we praten er al helemaal liever niet over. De Amerikaanse wetenschapster Brené Brown doet…
    Lees verder
    schaamte en schuld
  • Wat heeft de zeebravis te maken met het menselijk stress systeem?

    In veel artikelen en blogs over emotionele intelligentie worden stress en menselijke emoties besproken aan de hand van hoe onze hersenen werken. Maar onze hersenen zijn slechts één onderdeel van het stress regulerende systeem in ons lichaam.
    Lees verder
    zeebravis menselijk emotionele systeem stress systeem emotionele intelligentie equanimity
  • Je hebt maar één brein

    De Amerikaanse neurobioloog Paul MacLean lanceerde in de jaren ’60 de theorie van ‘The Triune Brain’. Volgens deze nog steeds zeer populaire theorie bestaat ons brein uit drie min of meer afzonderlijke ‘gestapelde’ breinen. Hersenwetenschappers weten echter al vele jaren dat de theorie niet correct is omdat hij een onjuiste voorstelling geeft van de ontstaansgeschiedenis…
    Lees verder
    emotionele intelligentie je hebt maar een brein hersenen
  • “Doe eens normaal man!” en meer over dominantie systemen

    De manier waarop wij over onszelf en elkaar denken wordt beïnvloed door wat we ‘normaal’ vinden. ‘Normaal’ betekent ‘volgens de norm’ en deze norm leiden we af door naar elkaar te kijken. ‘Normaal’ vinden we dat wat de meeste mensen doen en ‘abnormaal’ is alles wat daar op de één of andere manier van afwijkt.…
    Lees verder
    dominante systemen dominantie systemen geweldloze communicatie walter wink marshall rosenberg
  • Een kwestie van mentale hygiëne

    De meeste mensen zijn zich ervan bewust dat hun lichamelijke gezondheid sterk wordt bepaald door hun levensstijl. Als je voldoende beweegt, niet rookt, een beetje rustig aan doen met alcohol, gezond eet en genoeg slaapt dan leef je doorgaans langer en met aanzienlijk minder nare ziektes en kwalen. Minder bekend is dat hetzelfde geldt voor…
    Lees verder
    wat is geweldloze communicatie en geweldloos of verbindend communiceren
  • Boris Buskruit

    Boosheid is iets waar ik al mijn hele leven mee worstel. Mijn ouders noemden mij als kind al grappend ‘Boris Buskruit’ omdat ik zo ongelooflijk kwaad kon worden. Boosheid is iets geworden waar ik me voor schaam en me schuldig over voel.
    Lees verder

Blijf op de hoogte

Wil je op de hoogte wilt blijven van nieuwe trainingsdata en blogposts? Je ontvangt een paar keer per jaar een mail en je kunt je te allen tijde eenvoudig afmelden.