View our other brands
// Configuration object for centralized settings
const TabbedNavConfig = {
  DESKTOP_BREAKPOINT: 1201,
  DEBOUNCE_DELAY: 250,
  OPEN_FIRST_TAB: true,
  CLOSE_TAB_ON_MOUSEOUT: false
};

// Custom config for tabbed hero containers
const tabbedHeroConfig = {
  ...TabbedNavConfig,
  OPEN_FIRST_TAB: false,
  CLOSE_TAB_ON_MOUSEOUT: true
};

// Function to determine the appropriate config based on container context
function getConfigForContainer(container) {
  // Check if container has closest ancestor with [data-tabbed-hero="true"]
  const heroAncestor = container.getAttribute('data-tabbed-hero') === 'true'   ? container : container.closest('[data-tabbed-dropdown="true"]');
  
  if (heroAncestor) {
    return tabbedHeroConfig;
  }
  
  // Check for specific data-instance attributes (if you still want to support them)
  // const instance = container.getAttribute('data-instance');
  // if (instance === 'two') {
  //   // You can still have specific instance configs if needed
  //   return {
  //     ...TabbedNavConfig,
  //     OPEN_FIRST_TAB: false,
  //     CLOSE_TAB_ON_MOUSEOUT: true
  //   };
  // }
  
  // Default config
  return TabbedNavConfig;
}

class TabbedNavigation {
  constructor(container, config = TabbedNavConfig) {
    this.container = container;
    this.config = config;
    this.activeItem = null;
    this.isDesktop = window.innerWidth >= this.config.DESKTOP_BREAKPOINT;
    this.hasMouseListeners = false;
    this.megamenuParent = null;
    this.megamenuObserver = null;
    
    // Initialize bound handlers - these will be reused across reinitializations
    this.mouseEnterHandler = this.handleMouseEnter.bind(this);
    this.mouseLeaveHandler = this.handleMouseLeave.bind(this);
    this.resizeHandler = this.debounce(this.handleResize.bind(this), this.config.DEBOUNCE_DELAY);
    this.handleMegamenuToggle = this.handleMegamenuToggle.bind(this);
    
    this.init();
  }

  init() {
    // Cache DOM elements fresh each time
    this.navItems = [...this.container.querySelectorAll('.dwc-tabbed-nav-list__li')];
    this.elementsCache = new Map();
    
    this.cacheElements();
    this.setupAccessibility();
    this.setupMegamenuObserver();
    this.bindEvents();

    // Set initial state
    this.updateLayout();
    this.setBackText()

    // Show first item on page load only if desktop, not nested, and OPEN_FIRST_TAB is true
    if (this.navItems.length > 0 && this.isDesktop && this.config.OPEN_FIRST_TAB) {
      setTimeout(() => {
        const firstItem = this.navItems[0];

        // Count how many .dwc-tabbed-nav-container ancestors this.container has
        let count = 0;
        let current = this.container.parentElement;
        while (current) {
          if (current.classList?.contains('dwc-tabbed-nav-container')) {
            count++;
          }
          current = current.parentElement;
        }

        const isNested = count >= 1;

        if (!isNested && this.elementsCache.has(firstItem)) {
          this.showTab(firstItem);
        }
      }, 0);
    }
  }

  // Setup observer for megamenu parent
  setupMegamenuObserver() {
    // Find the .brx-has-megamenu parent
    this.megamenuParent = this.container.closest('.brx-has-megamenu');
    
    if (this.megamenuParent) {
      // Set initial inert state
      this.updateInertState();
      
      // Create a MutationObserver to watch for class changes
      this.megamenuObserver = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
          if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
            this.updateInertState();
          }
        });
      });
      
      // Start observing the megamenu parent for class changes
      this.megamenuObserver.observe(this.megamenuParent, {
        attributes: true,
        attributeFilter: ['class']
      });
    }
  }

  // Update inert state based on megamenu open/closed state
  updateInertState() {
    if (!this.megamenuParent) return;
    
    const isOpen = this.megamenuParent.classList.contains('open');
    
    if (isOpen) {
      this.container.removeAttribute('inert');
    } else {
      this.container.setAttribute('inert', '');
    }
  }

  // Handle megamenu toggle (for manual triggering if needed)
  handleMegamenuToggle() {
    this.updateInertState();
  }

  // Method to clean up event listeners and reset state
  cleanup() {
    // Remove all event listeners
    this.container.removeEventListener('click', this.handleClick);
    this.container.removeEventListener('keydown', this.handleKeydown);
    this.container.removeEventListener('focus', this.handleFocus);
    
    // Remove mouse listeners if they exist
    if (this.hasMouseListeners) {
      this.container.removeEventListener('mouseenter', this.mouseEnterHandler, true);
      this.container.removeEventListener('mouseleave', this.mouseLeaveHandler, true);
    }
    
    // Remove resize listener
    window.removeEventListener('resize', this.resizeHandler);
    
    // Clean up megamenu observer
    if (this.megamenuObserver) {
      this.megamenuObserver.disconnect();
      this.megamenuObserver = null;
    }
    
    // Reset state
    this.activeItem = null;
    this.hasMouseListeners = false;
    this.megamenuParent = null;
    
    // Clear caches
    if (this.elementsCache) {
      this.elementsCache.clear();
    }
    this.navItems = [];
    
    // Reset all tab states and accessibility attributes
    const allNavItems = this.container.querySelectorAll('.dwc-tabbed-nav-list__li');
    allNavItems.forEach(item => {
      const button = item.querySelector('.dwc-tabbed-nav-list__li__button') || 
                    item.querySelector('.dwc-tabbed-nav-list__li__btn-txt');
      const content = item.querySelector('.dwc-tabbed-nav-list__li__content');
      
      // Remove classes
      item.classList.remove('active');
      
      // Reset button attributes
      if (button) {
        button.removeAttribute('role');
        button.removeAttribute('aria-controls');
        button.removeAttribute('aria-expanded');
        button.removeAttribute('aria-selected');
        button.removeAttribute('tabindex');
        button.removeAttribute('id');
      }
      
      // Reset content attributes
      if (content) {
        content.removeAttribute('role');
        content.removeAttribute('aria-labelledby');
        content.removeAttribute('id');
        content.removeAttribute('aria-hidden');
        content.style.maxHeight = '';
      }
      
      // Remove data attributes
      item.removeAttribute('data-tab-index');
    });
    
    // Reset nav list role
    const navList = this.container.querySelector('.dwc-tabbed-nav-list');
    if (navList) {
      navList.removeAttribute('role');
    }
    
    // Remove inert attribute
    this.container.removeAttribute('inert');
  }

  // Public method to reinitialize the navigation
  reinitialize() {
    this.cleanup();
    this.isDesktop = window.innerWidth >= this.config.DESKTOP_BREAKPOINT; // Use config breakpoint
    this.init();
  }

  // Cache DOM elements to avoid repeated queries
  cacheElements() {
    const uniqueIdBase = `tab-${Date.now()}`;
    
    this.navItems.forEach((item, index) => {
      const button = item.querySelector('.dwc-tabbed-nav-list__li__button') || 
                    item.querySelector('.dwc-tabbed-nav-list__li__btn-txt');
      const content = item.querySelector('.dwc-tabbed-nav-list__li__content');
      
      this.elementsCache.set(item, {
        button,
        content,
        uniqueId: `${uniqueIdBase}-${index}`,
        index
      });
    });
  }

  setupAccessibility() {
    const navList = this.container.querySelector('.dwc-tabbed-nav-list');
    if (!navList) return;
    
    navList.setAttribute('role', 'tablist');
    
    for (const [item, cache] of this.elementsCache) {
      const { button, content, uniqueId, index } = cache;
      
      if (button) {
        button.setAttribute('role', 'tab');
        button.setAttribute('aria-controls', `${uniqueId}-panel`);
        button.setAttribute('aria-expanded', 'false');
        button.setAttribute('aria-selected', 'false');
        button.setAttribute('tabindex', '0');
        button.setAttribute('id', `${uniqueId}-tab`);
      }
      
      if (content) {
        content.setAttribute('role', 'tabpanel');
        content.setAttribute('aria-labelledby', `${uniqueId}-tab`);
        content.setAttribute('id', `${uniqueId}-panel`);
        content.setAttribute('aria-hidden', 'true');
      }
      
      item.setAttribute('data-tab-index', index);
    }
  }

  bindEvents() {
    // Store bound handlers for cleanup
    this.handleClick = this.handleClick.bind(this);
    this.handleKeydown = this.handleKeydown.bind(this);
    this.handleFocus = this.handleFocus.bind(this);
    
    // Single event delegation for better performance
    this.container.addEventListener('click', this.handleClick);
    this.container.addEventListener('keydown', this.handleKeydown);
    this.container.addEventListener('focus', this.handleFocus, true);
    
    // Passive resize listener for better performance
    window.addEventListener('resize', this.resizeHandler, { passive: true });
    
    this.updateMouseListeners();
  }

  updateMouseListeners() {
    if (this.isDesktop && !this.hasMouseListeners) {
      this.container.addEventListener('mouseenter', this.mouseEnterHandler, true);
      this.container.addEventListener('mouseleave', this.mouseLeaveHandler, true);
      this.hasMouseListeners = true;
    } else if (!this.isDesktop && this.hasMouseListeners) {
      this.container.removeEventListener('mouseenter', this.mouseEnterHandler, true);
      this.container.removeEventListener('mouseleave', this.mouseLeaveHandler, true);
      this.hasMouseListeners = false;
    }
  }

  // Helper method to get sibling nav items (nav items in the same container level)
  getSiblingNavItems(navItem) {
    // Find the direct parent container of this nav item
    const navItemContainer = navItem.closest('.dwc-tabbed-nav-list');
    if (!navItemContainer) return [];
    
    // Get all nav items that are direct children of the same container
    const siblingItems = [...navItemContainer.querySelectorAll('.dwc-tabbed-nav-list__li')];
    
    // Filter to only include items that are siblings (not the navItem itself)
    // and check if they belong to any TabbedNavigation instance
    return siblingItems.filter(item => item !== navItem);
  }

  handleFocus(e) {
    if (!this.isDesktop) return;

    const button = e.target.closest('[role="tab"]');
    if (!button) return;
    
    const navItem = button.closest('.dwc-tabbed-nav-list__li');
    if (!navItem || !this.elementsCache.has(navItem)) return;
    
    this.handleTabInteraction(navItem, 'focus');
  }

  handleClick(e) {
    const navItem = e.target.closest('.dwc-tabbed-nav-list__li');
    if (!navItem || !this.elementsCache.has(navItem)) return;
    
    const button = e.target.closest('.dwc-tabbed-nav-list__li__button, .dwc-tabbed-nav-list__li__btn-txt');
    if (!button) return;
    
    e.preventDefault();
    this.handleTabInteraction(navItem, 'click');
  }

  handleKeydown(e) {
    const button = e.target.closest('[role="tab"]');
    if (!button) return;
    
    const navItem = button.closest('.dwc-tabbed-nav-list__li');
    if (!navItem || !this.elementsCache.has(navItem)) return;
    
    const { index: currentIndex } = this.elementsCache.get(navItem);
    
    switch (e.key) {
      case 'Enter':
      case ' ':
        e.preventDefault();
        this.handleTabInteraction(navItem, 'keyboard');
        break;
      case 'ArrowRight':
      case 'ArrowDown':
        e.preventDefault();
        this.focusNextTab(currentIndex);
        break;
      case 'ArrowLeft':
      case 'ArrowUp':
        e.preventDefault();
        this.focusPrevTab(currentIndex);
        break;
      case 'Home':
        e.preventDefault();
        this.focusTab(0);
        break;
      case 'End':
        e.preventDefault();
        this.focusTab(this.navItems.length - 1);
        break;
    }
  }
  
  handleMouseEnter(e) {
    if (!this.isDesktop) return;
    
    const navItem = e.target.closest('.dwc-tabbed-nav-list__li') || 
                   (e.target.matches('.dwc-tabbed-nav-list__li') ? e.target : null);
    if (!navItem || !this.elementsCache.has(navItem)) return;
    
    this.handleTabInteraction(navItem, 'hover');
  }

  handleMouseLeave(e) {
    if (!this.isDesktop) return;
    
    // Only close tabs if CLOSE_TAB_ON_MOUSEOUT is enabled
    if (this.config.CLOSE_TAB_ON_MOUSEOUT) {
      // Check if mouse is leaving the entire container
      const rect = this.container.getBoundingClientRect();
      const { clientX, clientY } = e;
      
      // Check if mouse position is outside the container bounds
      const isOutsideContainer = (
        clientX < rect.left || 
        clientX > rect.right || 
        clientY < rect.top || 
        clientY > rect.bottom
      );
      
      if (isOutsideContainer) {
        this.hideAllTabs();
      }
    }
    // If CLOSE_TAB_ON_MOUSEOUT is false, keep content visible (original behavior)
  }

  // Unified method to handle all tab interactions with nesting support
  handleTabInteraction(navItem, interactionType) {
    if (!this.elementsCache.has(navItem)) return;
    
    if (this.isDesktop) {
      // Simply hide siblings and show the target - works for all scenarios
      this.hideSiblingTabs(navItem);
      this.showTab(navItem);
    } else {
      // Mobile accordion behavior
      if (interactionType === 'click' || interactionType === 'keyboard') {
        this.toggleTabMobile(navItem);
      }
    }
  }

  // Hide only sibling tabs (same container level)
  hideSiblingTabs(navItem) {
   // console.log('Nav Item: ', navItem)
    const siblings = this.getSiblingNavItems(navItem);
    
    siblings.forEach(sibling => {
      
         //console.log('sibling: ', sibling)
      // Only hide siblings that have the active class to avoid affecting other instances
      if (sibling.classList.contains('active')) {
        this.hideSiblingTab(sibling);
      }
    });
  }

  // Hide a sibling tab (used when we know it's a sibling from another instance)
  hideSiblingTab(navItem) {
    const button = navItem.querySelector('.dwc-tabbed-nav-list__li__button') || 
                  navItem.querySelector('.dwc-tabbed-nav-list__li__btn-txt');
    const content = navItem.querySelector('.dwc-tabbed-nav-list__li__content');
    
    if (content && button) {
      content.setAttribute('aria-hidden', 'true');
      button.setAttribute('aria-expanded', 'false');
      button.setAttribute('aria-selected', 'false');
      navItem.classList.remove('active');
      
      // Also handle mobile accordion collapse
      if (!this.isDesktop) {
        content.style.maxHeight = '0';
      }
    }
  }

  // Mobile-specific toggle behavior with proper nesting support
  toggleTabMobile(navItem) {
    if (!this.elementsCache.has(navItem)) return;
    
    const isActive = navItem.classList.contains('active');
    
    if (isActive) {
      this.collapseTab(navItem);
    } else {
      // Close sibling tabs and open this one
      this.hideSiblingTabs(navItem);
      this.expandTab(navItem);
    }
  }

  toggleTab(navItem) {
    if (!this.elementsCache.has(navItem)) return;
    
    if (this.isDesktop) {
      this.handleTabInteraction(navItem, 'click');
    } else {
      this.toggleTabMobile(navItem);
    }
  }

  showTab(navItem) {
    if (!this.elementsCache.has(navItem)) return;
    
    const { button, content } = this.elementsCache.get(navItem);
    
    if (content && button) {
      content.setAttribute('aria-hidden', 'false');
      button.setAttribute('aria-expanded', 'true');
      button.setAttribute('aria-selected', 'true');
      navItem.classList.add('active');
    }
    
    this.setActiveTab(navItem);
  }

  hideTab(navItem) {
    if (!this.elementsCache.has(navItem)) return;
    
    const { button, content } = this.elementsCache.get(navItem);
    
    if (content && button) {
      content.setAttribute('aria-hidden', 'true');
      button.setAttribute('aria-expanded', 'false');
      button.setAttribute('aria-selected', 'false');
      navItem.classList.remove('active');
    }
    
    // Only clear activeItem if it belongs to THIS navigation instance
    // and it's the exact item being hidden
    if (this.activeItem === navItem && this.navItems.includes(navItem)) {
      this.activeItem = null;
    }
  }

  expandTab(navItem) {
    if (!this.elementsCache.has(navItem)) return;
    
    // Close sibling tabs
    this.hideSiblingTabs(navItem);
    
    this.showTab(navItem);
    
    // Smooth height animation
    const { content } = this.elementsCache.get(navItem);
    if (content) {
      const height = content.scrollHeight;
      content.style.maxHeight = `${height}px`;
    }
  }

  collapseTab(navItem) {
    if (!this.elementsCache.has(navItem)) return;
    
    this.hideTab(navItem);
    
    const { content } = this.elementsCache.get(navItem);
    if (content) {
      content.style.maxHeight = '0';
    }
  }

  hideAllTabs() {
    this.navItems.forEach(item => this.hideTab(item));
  }

  setActiveTab(navItem) {
    // Only update aria-selected for tabs in THIS navigation instance
    this.navItems.forEach(item => {
      const cache = this.elementsCache.get(item);
      if (cache?.button) {
        cache.button.setAttribute('aria-selected', item === navItem ? 'true' : 'false');
      }
    });
    
    // Only set activeItem if this navItem belongs to THIS navigation instance
    if (this.navItems.includes(navItem)) {
      this.activeItem = navItem;
    }
  }

  focusTab(index) {
    if (index >= 0 && index < this.navItems.length) {
      const cache = this.elementsCache.get(this.navItems[index]);
      if (cache?.button) {
        cache.button.focus();
      }
    }
  }

  focusNextTab(currentIndex) {
    const nextIndex = (currentIndex + 1) % this.navItems.length;
    this.focusTab(nextIndex);
  }

  focusPrevTab(currentIndex) {
    const prevIndex = currentIndex === 0 ? this.navItems.length - 1 : currentIndex - 1;
    this.focusTab(prevIndex);
  }

  handleResize() {
    const wasDesktop = this.isDesktop;
    this.isDesktop = window.innerWidth >= this.config.DESKTOP_BREAKPOINT; // Use config breakpoint
    
    if (wasDesktop !== this.isDesktop) {
      this.updateMouseListeners();
      this.updateLayout();
    }
  }

  updateLayout() {
    const currentlyActive = this.activeItem;

    // Reset all states
    this.hideAllTabs();

    // Clear inline styles
    this.navItems.forEach(item => {
      const cache = this.elementsCache.get(item);
      if (cache?.content) {
        cache.content.style.maxHeight = '';
      }
    });

    if (this.isDesktop) {
      // Determine if this tab instance is nested
      let count = 0;
      let current = this.container.parentElement;
      while (current) {
        if (current.classList?.contains('dwc-tabbed-nav-container')) {
          count++;
        }
        current = current.parentElement;
      }
      const isNested = count >= 1;

      if (!isNested && this.config.OPEN_FIRST_TAB) {
        if (currentlyActive) {
          this.showTab(currentlyActive);
        } else if (this.navItems.length > 0) {
          this.showTab(this.navItems[0]);
        }
      }
    }
  }

  setBackText(){
    let tabElement = document.querySelector('.dwc-tabbed-nav-container');
    let tabBackText = tabElement.getAttribute('data-back-text')
    document.querySelectorAll('.dwc-tabbed-nav-list__li__button').forEach(tabBtn => {
        const textContent = tabBtn.textContent.trim();
        const tabIcon = tabBtn.querySelector('.dwc-tabbed-nav-list__li__arrow-icon');
        if (tabIcon) {
            tabIcon.setAttribute('data-text', textContent);
            tabIcon.setAttribute('data-back-text', tabBackText);
        }
    });
  }

  // Simple debounce for resize
  debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
      const later = () => {
        clearTimeout(timeout);
        func(...args);
      };
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
    };
  }

  // Public method to destroy the instance completely
  destroy() {
    this.cleanup();
    // Additional cleanup can be added here if needed
  }

  // Public method to manually update inert state (if needed)
  updateInert() {
    this.updateInertState();
  }
}

// Simplified initialization on DOM ready
document.addEventListener('DOMContentLoaded', function() {
  const tabbedNavContainers = document.querySelectorAll('.dwc-tabbed-nav-container');
  
  tabbedNavContainers.forEach(container => {
    // Skip if this container is nested inside another dwc-tabbed-nav-container
    const parentNavContainer = container.parentElement.closest('.dwc-tabbed-nav-container');
    if (parentNavContainer) {
      return; // Skip nested containers
    }
    
    // Get the appropriate config for this container
    const config = getConfigForContainer(container);
    
    // Initialize with the determined config
    new TabbedNavigation(container, config);
  });
});

// For dynamic content - Updated version
window.initTabbedNav = function(container, customConfig = null) {
  if (container && container.classList.contains('dwc-tabbed-nav-container')) {
    // Check if this is a nested container
    const parentNavContainer = container.parentElement.closest('.dwc-tabbed-nav-container');
    if (parentNavContainer) {
      return null; // Don't initialize nested containers
    }
    
    // Use custom config if provided, otherwise determine config automatically
    const config = customConfig || getConfigForContainer(container);
    return new TabbedNavigation(container, config);
  }
  return null;
};

/*
// TO REINITIALIZE USE THIS
// Create an instance of TabbedNavigation
const tabbedNav = new TabbedNavigation(document.querySelector('.dwc-tabbed-nav-container'));

// Call reinitialize on the instance
tabbedNav.reinitialize();

// TO USE WITH CUSTOM CONFIG
const customConfig = {
  DESKTOP_BREAKPOINT: 768,
  DEBOUNCE_DELAY: 300,
  OPEN_FIRST_TAB: false,  // This will prevent first tab from opening automatically
  CLOSE_TAB_ON_MOUSEOUT: true  // This will close tabs when mouse leaves container
};
const tabbedNavCustom = new TabbedNavigation(document.querySelector('.dwc-tabbed-nav-container'), customConfig);

// TO UPDATE ON URL CHANGE
function onUrlChange() {
    setTimeout(function () {
const tabbedNav = new TabbedNavigation(document.querySelector('.dwc-tabbed-nav-container'));
tabbedNav.reinitialize();

    }, 1500); // Delay execution by 2 seconds
}

// Listen for popstate event (history navigation)
window.addEventListener('popstate', onUrlChange);

// Listen for hashchange event (URL hash change)
window.addEventListener('hashchange', onUrlChange);

// Handle pushState and replaceState
(function (history) {
    const pushState = history.pushState;
    const replaceState = history.replaceState;

    history.pushState = function (state) {
        if (typeof history.onpushstate == "function") {
            history.onpushstate({ state: state });
        }
        const result = pushState.apply(history, arguments);
        onUrlChange(); // Call the function when pushState is used
        return result;
    };

    history.replaceState = function (state) {
        if (typeof history.onreplacestate == "function") {
            history.onreplacestate({ state: state });
        }
        const result = replaceState.apply(history, arguments);
        onUrlChange(); // Call the function when replaceState is used
        return result;
    };
})(window.history);

*/

console.log('%c<Jamie Sheehan Web Design Mega Menu Pro Tabbed Navigation v1.0>', 'color: #b388eb');

3 Ways Email Breaks Down Nomination Workflows

August 29, 2025

In this post...

All Articles

Email is everywhere. It’s quick, convenient, and everyone knows how to use it. But when it becomes the primary tool for managing complex, multi-step oil movements, things can get… messy.  

What starts as simple mistakes can spiral fast. Here are a few common scenarios we see:  

  • Missing attachments for quality testing instructions causes miscommunications where testing is then conducted per terminal practice instead.
  • Disorganized inboxes can result in lost or overlooked nominations which trigger delays, and even demurrage. 
  • Accidentally omitting key details for invoice submission, cost sharing, or update requirements can cause payment bottlenecks, or missed cost recovery opportunities.  

These aren’t just annoyances, but real risks to timelines, margins, and trust in partnerships. 

When you look beyond the convenience, email starts to show its cracks. Moving hydrocarbons is a high-value, time-sensitive process involving multiple stakeholders, constant updates, and critical data points that must be accurate from start to finish. Each data point also holds enormous insight potential.

Email simply wasn’t designed for that kind of work. 

Why Email Can’t Keep Up  

Below, we’ll explore three reasons why email-driven nomination workflows break down — and how moving to a centralized, structured platform can change everything. 

1. Using Static Tools for a Dynamic Workflow 

For many companies, nominations start with a saved Word, Excel or email template that gets filled out, attached and sent. At first glance, this feels like introducing structure. In reality, it locks the process into a rigid, manual pattern.  

The problem? With these static avenues, every change means manual editing, updating multiple versions and hoping everyone is working from the latest copy. This slows everything down and increases the risk of human error. Without built-in validation, even a small oversight can lead to costly mistakes.  

Why it happens: Email is linear, but nominations are dynamic. It’s hard to ensure everyone is looking at the same data source when that truth keeps shifting across email threads and attachments. 

2. Trading Momentary Convenience for Insight Potential 

Email works for sending instructions or conversations – but terrible for extracting trends, measuring performance, or identifying bottlenecks. Once messages are buried in inboxes, the only way to find insights is by digging through individual threads – one at a time.  

The problem? Without a centralized repository of structured data, there’s no easy way to compare movements, spot recurring issues, or evaluate vendor performance. That means missed opportunities to optimize growth and reduce costs.  

Why it happens: Email is built for communication, not analysis. Nominations hold rich, valuable data that needs to be measured, reviewed and improved over time, and email offers no straightforward way to make that happen. 

3. Compromising Visibility Across Teams 

The nomination lifecycle has multiple touchpoints across various teams. In an email-only world, visibility and progress updates are limited to whoever is on the CC line. If a scheduler or inspector is offline or on leave, updates get delayed and decisions stall.  

The problem? Without a shared, real-time view of nomination status, teams waste time chasing updates, confirming details, and re-entering information that already exists elsewhere – just not where they can see it.  

Why it happens: Email is private by design. Unless someone forwards the thread or remembers to CC all parties involved, information doesn’t automatically flow to the people who need it. 

What a Strategic Workflow Looks Like 

The alternative to email isn’t just going digital but creating an ecosystem that adequately reflects the reality of your day to day. An environment that flexes with your needs. A workspace that yields scalable, sustainable growth that is:  

Dynamic and Adaptable – Changes update automatically for all stakeholders, with built-in validation to prevent common errors with a bird’s eye view in one single location. 

Searchable and Reportable – Every nomination and its history are stored in a structured format, making analytics and performance tracking easy. 

Shared in Real-time – Teams keep the momentum going when everyone sees the same data at the same time, resulting in improved collaboration. 

The Bottom Line 

Email will always have a place in business communication — but it’s not a long-term solution for complex, high-stakes work like hydrocarbon nominations. As supply chains become faster, more interconnected, and more data-driven, the need for a shared, real-time, insight-rich platform becomes impossible to ignore. 

Navarik Inspection was built for that reality. By moving away from static, email-based processes, you give your teams the tools they need to work faster, smarter, and with complete confidence in every decision.  

Stop letting critical details get lost in the thread. 
Reach out to our specialists and learn how to centralize your nominations today.