/*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 #mobile_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;
}

: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 #mobile_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;
}
 
/* 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();

2024 Michigan Climate Summit

The 2024 Michigan Climate Summit, held in September 2024 at the University of Michigan in Ann Arbor in association with the University of Michigan School for Environment and Sustainability, was an in-person gathering dedicated to exploring the intersections of civic engagement, social justice, and climate action under the theme of Climate Civics.

2024 Summit Photo Collage

September 25, 2024 | University of Michigan, Ann Arbor

The event featured inspiring programming aimed at addressing the intertwined crises of democracy and climate justice, empowering attendees to become lifelong climate voters, and providing actionable ways to serve their communities.

Keynote speakers included Michigan Secretary of State Jocelyn Benson, who highlighted the importance of free and fair elections ahead of November’s critical ballot, and environmentalist and author Bill McKibben, whose closing address at Rackham Auditorium reflected his unparalleled influence on the fight for a livable planet. McKibben’s longstanding connection to Michigan includes his foundational role in the Oil & Water Don’t Mix campaign.

The Summit was designed to educate, inspire, and uplift attendees while fostering inclusivity and providing accommodations to ensure access for all participants. It served as a critical platform for community members to connect, learn, and take action for climate and democracy.

Summit 2024 Graphic e

Summit Schedule

• MICHIGAN CLIMATE SUMMIT BEGINS •

Thursday, September 26, 2024

ART BUILD – NEST FOR OUR COMMON FUTURE • Ingalls Mall (tented)

SPONSOR ORGANIZATION TABLING • Ingalls Mall (tented)

Tabling Instructions, Organization List & Map

EARTH FEST STUDENT GROUP TABLING • The Diag

CHECK-IN/REGISTRATION TABLE • Rackham Lobby

Also an Info-Only Station in the Michigan Union Lobby

BREAKFAST/REGISTRATION OPEN • Rackham Lobby
WELCOME: HOSTED BY MiCAN and UM • Rackham Auditorium
Dr. Denise Keele
MiCAN Executive Director
Bio
Dr. Denise Keele
Colleen Ludwig
MiCAN Artistic Director and Associate Professor of Art at Oakland University
Bio
Colleen Ludwig
Liesl Clark
UM Director of Sustainable Climate Action Engagement
Bio
Liesl Clark
Shalanda Baker
University of Michigan Vice Provost for Sustainability & Climate Action
Bio
Shalanda Baker
Dr. Jonathan Overpeck
Samuel A. Graham Dean; William B. Stapp Collegiate Professor of Environmental Education; Professor, Climate and Space Sciences and Engineering; Professor, Earth and Environmental Sciences
Bio
Dr. Jonathan Overpeck
Dr. Jenna Bednar
UMICH Votes & Democratic Engagement Faculty Director, Year of Democracy initiative Co-Chair
Bio
Dr. Jenna Bednar

KEYNOTE • Rackham Auditorium

Followed by an Election Integrity Panel Discussion

Jocelyn Benson
Michigan Secretary of State
Bio
Jocelyn Benson
Melanie Ryska
Sterling Heights City Clerk, 2020 Clerk of the Year, Michigan Association of Municipal Clerks (MAMC) President
Melanie Ryska
Jackie Beaudry
Ann Arbor City Clerk, 2019 Clerk of the Year, Michigan Association of Municipal Clerks (MAMC) Immediate Past President
Jackie Beaudry

NETWORKING BREAK • Rackham Lobby

Art & Tabling @ Ingalls Mall. Refreshments in the Rackham Lobby

GETTING OUT THE CLIMATE VOTE • Rackham Auditorium

Making Your Voice Heard Through Climate Voter Campaigns

Dr. Denise Keele (Moderator)
MiCAN Executive Director
Bio
Dr. Denise Keele (Moderator)
Maurielle Courtois
Turn Up Turnout Co-President, UM Rising Senior Political Science Student
Bio
Maurielle Courtois
Janet Zahn
Co-Chair Grand Rapids Climate Coalition
Bio
Janet Zahn
Marwan Mikdadi
Citizens Climate Lobby Higher Ed and Youth Action Teams
Bio
Marwan Mikdadi
Lisa DelBuono
Michigan Clinicians for Climate Action President & Founder
Bio
Lisa DelBuono
Sandra Sorini Elser
League of Women Voters Michigan Environmental Network Chair
Bio
Sandra Sorini Elser
BUILDING UNUSUALLY EFFECTIVE CAMPAIGNS • Kuenzel Rm @ Union 1st Fl
Ellen Vial (Moderator)
Michigan Environmental Council Detroit Program Manager
Bio
Ellen Vial (Moderator)
Conan Smith
Michigan Environmental Council President & CEO
Bio
Conan Smith
Jamie Lyons-Eddy
Voters Not Politicians & Voters Not Politicians Education Fund Executive Director
Bio
Jamie Lyons-Eddy
Selma Tucker
Michigan Environmental Council At-Large Member, GSO Solutions Principal
Bio
Selma Tucker
Jeff Jones
Third Act
Bio
Jeff Jones

WAYS TO SUSTAIN: ROOTS THAT RUN DEEP • Pendelton Rm @ Union 2nd Fl

Sustaining Advocates

Bryan Smigielski (Moderator)
Sierra Club Detroit Field Organizer
Bryan Smigielski (Moderator)
Dr. Laura Carter Robinson
Humanity&Planet, LLC Founder, Clinical Psychologist
Bio
Dr. Laura Carter Robinson
LaUra Schmidt
Good Grief Network Founding Director
Bio
LaUra Schmidt
Marnese Jackson
Midwest Building Decarbonization Coalition Executive Director
Bio
Marnese Jackson
Jack MacQuaig
Michigan State Sunrise Movement
Jack MacQuaig

MONEY ON THE TABLE • Anderson ABCD @ Union 1st Fl

What the Inflation Reduction Act Can Do for You (and the Climate)

Bentley Johnson (Moderator)
Michigan League of Convervation Voters Federal Government Affairs Director
Bio
Bentley Johnson (Moderator)
Dan Utech
Environmental Protection Agency Chief of Staff
Bio
Dan Utech
Kara Cook
Michigan Department of Environment, Great Lakes, and Energy (EGLE) Chief Climate and Energy Strategist
Bio
Kara Cook
Dr. Missy Stults
City of Ann Arbor Office of Sustainability & Innovations Director
Bio
Dr. Missy Stults
Jenna Warmuth
Rewiring America Sr. Manager Midwest Regional Policy
Bio
Jenna Warmuth
Tim Skrotzki
Elevate Associate Director of Partnerships
Bio
Tim Skrotzki
HOW TO: ROADMAP TO PUBLIC POWER • Wolverine Rm @ Union 3rd Fl
Dr. Mike Shriberg
UM Practice & Engagement Professor, Cooperative Institute for Great Lakes Research (CIGLR) & Michigan Sea Grant (MISG) Director of Engagement
Bio
Dr. Mike Shriberg
Andy Buchsbaum
UM Law School Lecturer, Former National Wildlife Federation (NWF) Conservation Partnerships Vice President, Former NWF Great Lakes Office & Action Fund Director
Bio
Andy Buchsbaum
Eneida Hysi
Dane County Wisconsin Office of Energy and Climate Change Community Energy Fellow
Bio
Eneida Hysi

LUNCH • Rogel Ballroom @ Union

Networking. Plus Art, Tabling @ Ingalls Mall

INSPIRING MUSIC FOR ACTIVISTS • The Diag

Musical Performances by Seth Bernard & Friends

Seth Bernard
Vocals, Guitar
Bio
Seth Bernard
Amber Hasan
Vocals, Spoken Word
Bio
Amber Hasan
Patrick Booth
Saxophone
Bio
Patrick Booth
Fred Bueltmann
Sousaphone
Bio
Fred Bueltmann
Dan Rickabus
Drums, Vocals
Bio
Dan Rickabus

THE FOURTH ESTATE • Rackham Auditorium

The Role of Media in Climate Democracy

Nina Ignaczak (Moderator)
Planet Detroit Founder, Publisher, Editor
Bio
Nina Ignaczak (Moderator)
Sarah Cwiek
Michigan Public
Bio
Sarah Cwiek
Jena Brooker
BridgeDetroit
Bio
Jena Brooker
Sheri McWhirter
MLive
Bio
Sheri McWhirter
Rukiya Colvin
Freelance Journalist
Bio
Rukiya Colvin
Lisa John Rogers
Great Lakes Now
Bio
Lisa John Rogers
WAYS TO ENGAGE: AIR PERMITTING PROCESS • Kuenzel Rm @ Union 1st Fl
Regina Strong (Moderator)
EGLE Environmental Justice Public Advocate
Bio
Regina Strong (Moderator)
Randy Dykhuis
Capital Area Friends of the Environment (CAFE) Board President
Bio
Randy Dykhuis
Nick Leonard
Great Lakes Environmental Law Center Executive Director
Bio
Nick Leonard
Darren Riley
JustAir Solutions CEO & Co-Founder
Bio
Darren Riley
Rep. Abraham Aiyash
Majority Floor Leader, 9th House District
Bio
Rep. Abraham Aiyash
JUST WORKFORCE TRANSITION • Pendelton Rm @ Union 2nd Fl
Liesl Clark (Moderator)
UM Sustainable Climate Action Engagement Director
Bio
Liesl Clark (Moderator)
Derrick Meeking
Walker-Miller Energy Services Director of Workforce Development
Bio
Derrick Meeking
Joe Lange
City of Ann Arbor Energy Analyst
Bio
Joe Lange
Glenn Stevens Jr.
MichAuto Executive Director; Detroit Regional Chamber Vice President Automotive and Mobility Initiatives
Bio
Glenn Stevens Jr.
Jennifer Mefford
MUST Workforce Consultant
Bio
Jennifer Mefford
Frank Houston
BlueGreen Alliance MI Senior State Policy Manager
Bio
Frank Houston

EMPOWERING COMMUNITIES • Anderson ABCD @ Union 1st Fl

The Fight for Energy Democracy and Resilient, Localized Power

Michelle Martinez (Moderator)
SEAS Lecturer and Inaugural Director of the Tishman Center for Social Justice and the Environment
Bio
Michelle Martinez (Moderator)
Greg Woodring
Ann Arbor for Public Power Board President
Bio
Greg Woodring
Sergio Cira-Reyes
Urban Core Collective Climate Justice Catalyst
Bio
Sergio Cira-Reyes
Rafael Mojica
Soulardarity Program Director
Bio
Rafael Mojica
Liz Jacob
Sugar Law Center Skadden Fellow: Energy Insecurity Coordinator
Bio
Liz Jacob
Kamau Clark
We The People Southeast MI Lead Organizer
Bio
Kamau Clark
HOW TO: STORYTELLING WORKSHOP • Wolverine Rm @ Union 3rd Fl
Kabie Stein (Moderator)
Here:Say Creative Director & Producer
Bio
Kabie Stein (Moderator)

NETWORKING BREAK • Rackham Lobby

Art & Tabling @ Ingalls Mall. Refreshments in the Rackham Lobby

COLLEGE VOICES FOR CLIMATE ACTION • Rackham Auditorium
Beatrice Kaskie (Moderator)
Rising Junior at University of Michigan in the College of Literature, Science, and Arts; Representing Turn Up Turnout (TUT)
Bio
Beatrice Kaskie (Moderator)
Dani Kasper
Sophomore at University of Michigan, PitE Major with specialization in Environmental Justice & Activism, Community Action and Social Change Minor, President Elect of UM Sierra Club Chapter
Dani Kasper
Ethan Devereaux
Senior at University of Michigan, PitE Major, Energy Sciences Minor, Students for Clean Energy Policy Chair
Ethan Devereaux
Mia Breznau
Freshman at Western Michigan University, Enviro Geology & Sustainability Major, 2023 Youth Climate Leader of the Year, Former MiCAN Influencer, Current Climate Voting Intern at WMU, National Youth for the Climate Emergency (NYCE) Founder
Mia Breznau
Andrew van Baal
Accelerated Master’s Student (4+1) at UM-SEAS, Energy Equity Project Energy Justice Research Assistant, Student Sustainability Coalition Co-President
Bio
Andrew van Baal

A PEOPLE POWERED CAMPAIGN • Kuenzel Rm @ Union 1st Fl

For Public Power in Michigan

Ebony Elmore
Organizing Manager at Michigan Environmental Justice Coalition
Bio
Ebony Elmore
Xandr Brown
Michigan Environmental Justice Coalition Communications Associate
Bio
Xandr Brown
Ruta Hailu
Freshman at University of Michigan in the College of Language, Science, Sociology; PitE Major, Michigan Environmental Justice Coalition Clinic Advocate & Campaign Volunteer
Bio
Ruta Hailu

WAYS TO SUSTAIN: THE ART OF US • Pendelton Rm @ Union 2nd Fl

Building Community Action Through Culture and Creativity

Serena Amdur (Moderator)
MiCAN Digital Community Manager
Bio
Serena Amdur (Moderator)
William Lawrence
MI Rent Is Too Damn High Coalition Coordinator
Bio
William Lawrence
Jenna Downs
Third-Year Undergraduate STAMPS Student, Art Build Team
Bio
Jenna Downs
Piper Carter
Arts and Culture Organizer
Bio
Piper Carter
Dominique Campbell
Artist, Social Entrepreneur, and Cultural Organizer
Bio
Dominique Campbell
Seth Bernard
Music Maker, Cultural Warrior, Water Protector
Bio
Seth Bernard
RURAL ENERGY RESILIENCY • Anderson ABCD @ Union 1st Fl
Jeff Smith (Moderator)
Groundwork Center Communications Director
Bio
Jeff Smith (Moderator)
Brenden Miller
Land & Liberty Coalition Deputy Director
Bio
Brenden Miller
Nicholas Jansen
Groundwork Center Rural Clean Energy Organizer
Bio
Nicholas Jansen
Peter Sinclair
Independent Climate and Renewable Energy Videographer
Bio
Peter Sinclair
Deidre Iciek
Regenerative Connections Co-Founder, Dairy Owner, Regulatory Consultant
Bio
Deidre Iciek

THE FUEL THAT FAILED US • Wolverine Rm @ Union 3rd Fl

The Urgency Behind Shutting Down Line 5

Erica Bouldin (Moderator)
MiCAN Line 5 Engagement Coordinator
Bio
Erica Bouldin (Moderator)
Ross Fisher
Oil & Water Don’t Mix Organizing Coordinator
Bio
Ross Fisher
Ashley Rudzinski
Groundwork Center Climate & Environment Program Director
Bio
Ashley Rudzinski
Nichole Keway Biber
MI Clean Water Action Mid-Michigan Campaign Organizer
Bio
Nichole Keway Biber
Kathleen Brosemer
Michigan Technological University PhD Candidate in Energy and Environmental Policy
Bio
Kathleen Brosemer
Holly T. Bird
Title Track Co-Executive Director
Bio
Holly T. Bird

NETWORKING BREAK • Rackham Lobby

Art & Tabling @ Ingalls Mall. Refreshments in the Rackham Lobby

KEYNOTE • Rackham Auditorium
Bill McKibben
Third Act Founder, Author, Educator, Environmentalist
Bio
Bill McKibben
RECEPTION & MUSICAL PERFORMANCE • Rackham Lobby
Nique Love Rhodes
Detroit Hip-Hop Artist
Bio
Nique Love Rhodes

With Great Appreciation to our Event Hosts

University of michigan seas

Activism Ally

Michigan energy michigan jobs
Rewiring america
The growth shark
GfG box label v3

Climate Cruisader

CAFE - Capital Area Friends of the Environment
A logo with a map of Michigan, a butterfly, and children, promoting an environmental campaign—Clear the Air.
Climate Stick Thermometer with green grass background.
Edf action
Logo for Fivenson Dermatology
Forest to mi faucet
Michigan alliance for justice in climate
Michigan league of conservation voters
The Climate Reality Project - Washtenaw County

Community Pillar

Asthma and Allergy Foundation of America Michigan Chapter logo.
Logo of Michigan with stylized "L" and circular green and blue accents.
Elevate equity through climate action
Grand Rapids Climate Coalition logo featuring trees, sun, and water, promoting climate change awareness in Michigan.
Green portfolio solutions
Michigan environmental council
North by nature landscapes
Oil and water dont mix
Porter Family Foundation logo
Logo of TeichnerLaw featuring a green leafy tree design.

Nonprofit Partner

Main logo(4)
Leslie science and nature center
Barn Sanctuary logo, animal silhouettes and house outline, environmental conservation organization.
Green beaded leaf badge for citizen resistance at Fermi Two.
Detroit 2030 District
Eastside community network
GVSU Grand Valley State University Geography and Sustainable Planning Department logo
Great lakes bioneers
Great lakes creatives
Great lakes renewable energy association
Michigan green amendment coalition
Greenfield presbyterian church
Groundwork center
Killowatts for a cause
League of Women Voters of Michigan logo.
Mirrors for earth energy rebalancing meer
Michigan alliance for outdoor education
Michigan clinicians for climate action
Michigan electric vehicle alliance
Michigan mosaic energy coopertive
Michigan saves
Michigan united
Michiganders for fair and transparent elections
Midwest building decarbonization coalition
Moms clean air force
National wildlife federation
Old growth forest network
Resource generation
Sierra club michigan chapter
Soulardarity
St francis of assisi parish
Statewide indivisible michigan
Superior watershed partnership
Temple beth emeth dayenu circle
Center for oil and gas organizing
The Climate Reality Project - Washtenaw County
Third act michigan
Title track
Veterans for Peace logo featuring peace symbol with aircraft and ship silhouettes.
Voters not politicians
West michigan environmental action council
Wmu climate change working group