caxton 0.1.4

A secure WebAssembly runtime for multi-agent systems
Documentation
<!-- Accessible Navigation Component -->
<a href="#main-content" class="skip-link">Skip to main content</a>

<nav class="navbar" role="navigation" aria-label="Primary navigation">
  <div class="navbar__container container">
    <!-- Logo and brand -->
    <a href="{{ '/' | relative_url }}" class="navbar__brand" aria-label="Caxton home">
      <img src="{{ '/assets/img/logo.svg' | relative_url }}"
           alt=""
           class="navbar__logo"
           width="32"
           height="32"
           loading="eager">
      <span class="navbar__title">Caxton</span>
    </a>

    <!-- Mobile menu button -->
    <button class="navbar__toggle"
            id="mobile-menu-toggle"
            aria-expanded="false"
            aria-controls="navbar-menu"
            aria-label="Toggle navigation menu">
      <span class="navbar__toggle-icon" aria-hidden="true">
        <span></span>
        <span></span>
        <span></span>
      </span>
    </button>

    <!-- Navigation menu -->
    <div class="navbar__menu" id="navbar-menu">
      <ul class="navbar__list" role="list">
        {% for item in site.navigation.main %}
        <li class="navbar__item">
          {% if item.external %}
          <a href="{{ item.url }}"
             class="navbar__link"
             target="_blank"
             rel="noopener noreferrer">
            {{ item.title }}
            <svg class="navbar__external-icon"
                 width="12"
                 height="12"
                 viewBox="0 0 12 12"
                 fill="currentColor"
                 aria-label="Opens in new window">
              <path d="M10.5 1.5v3h-1v-2L5 7l-.7-.7L8.8 2h-2v-1h3z"/>
              <path d="M9.5 7.5v3h-8v-8h3v-1h-4v10h10v-4h-1z"/>
            </svg>
          </a>
          {% else %}
          <a href="{{ item.url | relative_url }}"
             class="navbar__link {% if page.url == item.url %}navbar__link--active{% endif %}"
             {% if page.url == item.url %}aria-current="page"{% endif %}>
            {{ item.title }}
          </a>
          {% endif %}
        </li>
        {% endfor %}
      </ul>

    </div>
  </div>
</nav>

<style>
.navbar {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background-color: var(--bg-secondary);
  border-bottom: 1px solid var(--color-surface0);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.navbar__container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-6);

  @media (max-width: 768px) {
    padding: var(--space-3) var(--space-4);
  }
}

.navbar__brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  color: var(--text-primary);
  font-weight: var(--font-semibold);
  font-size: var(--font-size-lg);
  transition: opacity var(--transition-fast);

  &:hover {
    opacity: 0.8;
    text-decoration: none;
  }

  &:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 4px;
    border-radius: var(--radius-sm);
  }
}

.navbar__logo {
  width: 32px;
  height: 32px;
  display: block;
}

.navbar__title {
  @media (max-width: 480px) {
    display: none;
  }
}

.navbar__toggle {
  display: none;
  background: transparent;
  border: none;
  padding: var(--space-2);
  cursor: pointer;
  color: var(--text-primary);

  @media (max-width: 768px) {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  &:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
  }
}

.navbar__toggle-icon {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 24px;
  height: 24px;
  position: relative;

  span {
    display: block;
    width: 100%;
    height: 2px;
    background-color: currentColor;
    transition: all var(--transition-fast);
    transform-origin: center;
  }

  .navbar__toggle[aria-expanded="true"] & {
    span:nth-child(1) {
      transform: translateY(6px) rotate(45deg);
    }

    span:nth-child(2) {
      opacity: 0;
    }

    span:nth-child(3) {
      transform: translateY(-6px) rotate(-45deg);
    }
  }
}

.navbar__menu {
  display: flex;
  align-items: center;
  gap: var(--space-8);

  @media (max-width: 768px) {
    position: fixed;
    top: 60px;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: var(--bg-secondary);
    flex-direction: column;
    padding: var(--space-6);
    transform: translateX(-100%);
    opacity: 0;
    visibility: hidden;
    transition: all var(--transition-base);
    overflow-y: auto;

    &.navbar__menu--open {
      transform: translateX(0);
      opacity: 1;
      visibility: visible;
    }
  }
}

.navbar__list {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  list-style: none;
  margin: 0;
  padding: 0;

  @media (max-width: 768px) {
    flex-direction: column;
    width: 100%;
    gap: var(--space-2);
  }
}

.navbar__item {
  @media (max-width: 768px) {
    width: 100%;
  }
}

.navbar__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  color: var(--text-secondary);
  text-decoration: none;
  font-weight: var(--font-medium);
  border-radius: var(--radius-md);
  transition: all var(--transition-fast);
  position: relative;

  @media (max-width: 768px) {
    width: 100%;
    padding: var(--space-3) var(--space-4);
    font-size: var(--font-size-md);
  }

  &:hover {
    color: var(--text-primary);
    background-color: var(--bg-surface);
    text-decoration: none;
  }

  &:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
  }

  &--active {
    color: var(--color-primary);

    &::after {
      content: '';
      position: absolute;
      bottom: -2px;
      left: var(--space-3);
      right: var(--space-3);
      height: 2px;
      background-color: var(--color-primary);
      border-radius: var(--radius-full);

      @media (max-width: 768px) {
        display: none;
      }
    }

    @media (max-width: 768px) {
      background-color: var(--bg-surface);
    }
  }
}

.navbar__external-icon {
  opacity: 0.7;
  margin-left: var(--space-1);
}



/* Overlay for mobile menu */
.navbar__overlay {
  display: none;

  @media (max-width: 768px) {
    display: block;
    position: fixed;
    top: 60px;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(4px);
    opacity: 0;
    visibility: hidden;
    transition: all var(--transition-base);
    z-index: var(--z-overlay - 1);

    &.navbar__overlay--visible {
      opacity: 1;
      visibility: visible;
    }
  }
}
</style>

<script>
// Mobile menu toggle with accessibility
document.addEventListener('DOMContentLoaded', function() {
  const toggle = document.getElementById('mobile-menu-toggle');
  const menu = document.getElementById('navbar-menu');
  const links = menu.querySelectorAll('.navbar__link');
  let isOpen = false;

  // Create overlay element
  const overlay = document.createElement('div');
  overlay.className = 'navbar__overlay';
  document.body.appendChild(overlay);

  function toggleMenu() {
    isOpen = !isOpen;
    toggle.setAttribute('aria-expanded', isOpen);
    menu.classList.toggle('navbar__menu--open', isOpen);
    overlay.classList.toggle('navbar__overlay--visible', isOpen);
    document.body.style.overflow = isOpen ? 'hidden' : '';

    // Focus management
    if (isOpen) {
      menu.querySelector('.navbar__link').focus();
    } else {
      toggle.focus();
    }
  }

  function closeMenu() {
    if (isOpen) {
      toggleMenu();
    }
  }

  // Toggle button click
  toggle.addEventListener('click', toggleMenu);

  // Close on overlay click
  overlay.addEventListener('click', closeMenu);

  // Close on escape key
  document.addEventListener('keydown', function(e) {
    if (e.key === 'Escape' && isOpen) {
      closeMenu();
    }
  });

  // Close on link click (mobile)
  links.forEach(link => {
    link.addEventListener('click', function() {
      if (window.innerWidth <= 768) {
        closeMenu();
      }
    });
  });

  // Handle resize
  let resizeTimer;
  window.addEventListener('resize', function() {
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(function() {
      if (window.innerWidth > 768 && isOpen) {
        closeMenu();
      }
    }, 250);
  });

  // Trap focus when menu is open
  menu.addEventListener('keydown', function(e) {
    if (!isOpen) return;

    if (e.key === 'Tab') {
      const focusableElements = menu.querySelectorAll(
        'a, button, [tabindex]:not([tabindex="-1"])'
      );
      const firstElement = focusableElements[0];
      const lastElement = focusableElements[focusableElements.length - 1];

      if (e.shiftKey && document.activeElement === firstElement) {
        e.preventDefault();
        lastElement.focus();
      } else if (!e.shiftKey && document.activeElement === lastElement) {
        e.preventDefault();
        firstElement.focus();
      }
    }
  });
});

</script>