# Multilevel Navigation

> Desktop flyouts and mobile nested panels with staggered open motion — full multilevel site navigation.

**Definition:** Multilevel Navigation is a navigation UI animation from collections.html. It is built with HTML, CSS, JavaScript, and GSAP, ships with a live preview, and is free to copy into personal and commercial projects.

## Facts
- Category: Navigation
- Stack: HTML, CSS, JavaScript, and GSAP
- Added: 2026-08-04
- Canonical page: https://html.bosconvertpro.com/collection/multilevel-navigation
- Full-page preview: https://html.bosconvertpro.com/collection/multilevel-navigation/full
- Live demo: https://html.bosconvertpro.com/demos/multilevel-navigation/index.html
- Markdown mirror: https://html.bosconvertpro.com/collection/multilevel-navigation/index.md
- License: https://html.bosconvertpro.com/terms

## How to use
1. Open https://html.bosconvertpro.com/collection/multilevel-navigation/full to preview the animation in full screen.
2. Copy index.html, styles.css, and script.js from the code tabs on https://html.bosconvertpro.com/collection/multilevel-navigation.
3. Paste the files into your project and adjust timing, easing, and content as needed.

## FAQ
### What is Multilevel Navigation?

Multilevel Navigation is a navigation UI animation from collections.html. Desktop flyouts and mobile nested panels with staggered open motion — full multilevel site navigation.

### What is Multilevel Navigation built with?

Multilevel Navigation is built with HTML, CSS, JavaScript, and GSAP. The source for every file is shown on the animation page and can be copied straight into your project.

### How do I use Multilevel Navigation in my project?

Open the animation page (https://html.bosconvertpro.com/collection/multilevel-navigation), preview it live, then copy index.html, styles.css, and script.js from the code tabs. Paste the files into your project and adjust timing, easing, and content as needed. A standalone demo runs at https://html.bosconvertpro.com/demos/multilevel-navigation/index.html.

### Is Multilevel Navigation free to use?

Yes. The Multilevel Navigation demo code may be used in personal and commercial projects. You may not resell or redistribute the collection itself as a competing template pack. Full terms: https://html.bosconvertpro.com/terms.

## Source — index.html
````html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Multilevel Navigation</title>
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link rel="preconnect" href="https://images.unsplash.com" />
    <link
      href="https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,600;9..40,700&display=swap"
      rel="stylesheet"
    />
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <nav class="site-nav" data-mobile-menu="closed" data-theme="light" aria-label="Main">
      <div class="site-nav__shell">
        <div class="site-nav__panel-bg" data-nav-panel-bg></div>

        <div class="site-nav__bar">
          <a href="#" class="site-nav__brand" aria-label="Furniture home">Furniture</a>

          <div class="site-nav__menu" data-nav-menu>
            <ul class="site-nav__list" role="list">
              <li class="site-nav__item">
                <button
                  type="button"
                  class="site-nav__link"
                  data-nav-dropdown-trigger
                  aria-expanded="false"
                  aria-haspopup="true"
                >
                  <span class="site-nav__link-text">Products</span>
                  <svg
                    class="site-nav__chevron"
                    xmlns="http://www.w3.org/2000/svg"
                    viewBox="0 0 17 10"
                    fill="none"
                    aria-hidden="true"
                  >
                    <path
                      d="M1.5 1.5L8.5 8.5L15.5 1.5"
                      stroke="currentColor"
                      stroke-width="1.5"
                      stroke-linecap="round"
                      stroke-linejoin="round"
                    />
                  </svg>
                </button>

                <div class="nav-dropdown" data-nav-dropdown-panel aria-hidden="true">
                  <div class="nav-dropdown__collapse">
                    <div class="nav-dropdown__content">
                      <ul class="nav-dropdown__list" role="list">
                        <li class="nav-dropdown__item" data-nav-dropdown-item>
                          <a href="#olaf" class="nav-card nav-card--with-image">
                            <div class="nav-card__media">
                              <img
                                class="nav-card__image nav-card__image--default"
                                src="https://images.unsplash.com/photo-1555041469-a586c61ea9bc?auto=format&fit=crop&w=900&q=80"
                                alt="Olaf modular sofa in warm linen"
                                loading="lazy"
                              />
                              <img
                                class="nav-card__image nav-card__image--hover"
                                src="https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?auto=format&fit=crop&w=900&q=80"
                                alt=""
                                aria-hidden="true"
                                loading="lazy"
                              />
                              <div class="nav-card__overlay"></div>
                            </div>
                            <div class="nav-card__footer">
                              <span class="nav-card__title">Olaf</span>
                              <span class="nav-card__action" aria-hidden="true"><svg viewBox="0 0 16 16" fill="currentColor"><path d="M2 7.25h8.19L7.22 4.28a.75.75 0 0 1 1.06-1.06l4.5 4.5a.75.75 0 0 1 0 1.06l-4.5 4.5a.75.75 0 1 1-1.06-1.06l2.97-2.97H2a.75.75 0 0 1 0-1.5Z"/></svg></span>
                            </div>
                          </a>
                        </li>
                        <li class="nav-dropdown__item" data-nav-dropdown-item>
                          <a href="#stijn" class="nav-card nav-card--with-image">
                            <div class="nav-card__media">
                              <img
                                class="nav-card__image nav-card__image--default"
                                src="https://images.unsplash.com/photo-1567538096630-e0c55bd6374c?auto=format&fit=crop&w=900&q=80"
                                alt="Stijn lounge chair"
                                loading="lazy"
                              />
                              <img
                                class="nav-card__image nav-card__image--hover"
                                src="https://images.unsplash.com/photo-1506439773649-6e0eb8cfb237?auto=format&fit=crop&w=900&q=80"
                                alt=""
                                aria-hidden="true"
                                loading="lazy"
                              />
                              <div class="nav-card__overlay"></div>
                            </div>
                            <div class="nav-card__footer">
                              <span class="nav-card__title">Stijn</span>
                              <span class="nav-card__action" aria-hidden="true"><svg viewBox="0 0 16 16" fill="currentColor"><path d="M2 7.25h8.19L7.22 4.28a.75.75 0 0 1 1.06-1.06l4.5 4.5a.75.75 0 0 1 0 1.06l-4.5 4.5a.75.75 0 1 1-1.06-1.06l2.97-2.97H2a.75.75 0 0 1 0-1.5Z"/></svg></span>
                            </div>
                          </a>
                        </li>
                        <li class="nav-dropdown__item" data-nav-dropdown-item>
                          <a href="#kees" class="nav-card nav-card--with-image">
                            <div class="nav-card__media">
                              <img
                                class="nav-card__image nav-card__image--default"
                                src="https://images.unsplash.com/photo-1592078615290-033ee584e267?auto=format&fit=crop&w=900&q=80"
                                alt="Kees accent chair"
                                loading="lazy"
                              />
                              <img
                                class="nav-card__image nav-card__image--hover"
                                src="https://images.unsplash.com/photo-1580480055273-228ff5388ef8?auto=format&fit=crop&w=900&q=80"
                                alt=""
                                aria-hidden="true"
                                loading="lazy"
                              />
                              <div class="nav-card__overlay"></div>
                            </div>
                            <div class="nav-card__footer">
                              <span class="nav-card__title">Kees</span>
                              <span class="nav-card__action" aria-hidden="true"><svg viewBox="0 0 16 16" fill="currentColor"><path d="M2 7.25h8.19L7.22 4.28a.75.75 0 0 1 1.06-1.06l4.5 4.5a.75.75 0 0 1 0 1.06l-4.5 4.5a.75.75 0 1 1-1.06-1.06l2.97-2.97H2a.75.75 0 0 1 0-1.5Z"/></svg></span>
                            </div>
                          </a>
                        </li>
                        <li class="nav-dropdown__item" data-nav-dropdown-item>
                          <a href="#nelis" class="nav-card nav-card--with-image">
                            <div class="nav-card__media">
                              <img
                                class="nav-card__image nav-card__image--default"
                                src="https://images.unsplash.com/photo-1586023492125-27b2c045efd7?auto=format&fit=crop&w=900&q=80"
                                alt="Nelis dining table setting"
                                loading="lazy"
                              />
                              <img
                                class="nav-card__image nav-card__image--hover"
                                src="https://images.unsplash.com/photo-1617806118233-18e1de247200?auto=format&fit=crop&w=900&q=80"
                                alt=""
                                aria-hidden="true"
                                loading="lazy"
                              />
                              <div class="nav-card__overlay"></div>
                            </div>
                            <div class="nav-card__footer">
                              <span class="nav-card__title">Nelis</span>
                              <span class="nav-card__action" aria-hidden="true"><svg viewBox="0 0 16 16" fill="currentColor"><path d="M2 7.25h8.19L7.22 4.28a.75.75 0 0 1 1.06-1.06l4.5 4.5a.75.75 0 0 1 0 1.06l-4.5 4.5a.75.75 0 1 1-1.06-1.06l2.97-2.97H2a.75.75 0 0 1 0-1.5Z"/></svg></span>
                            </div>
                          </a>
                        </li>
                      </ul>
                    </div>
                  </div>
                </div>
              </li>

              <li class="site-nav__item">
                <button
                  type="button"
                  class="site-nav__link"
                  data-nav-dropdown-trigger
                  aria-expanded="false"
                  aria-haspopup="true"
                >
                  <span class="site-nav__link-text">Services</span>
                  <svg
                    class="site-nav__chevron"
                    xmlns="http://www.w3.org/2000/svg"
                    viewBox="0 0 17 10"
                    fill="none"
                    aria-hidden="true"
                  >
                    <path
                      d="M1.5 1.5L8.5 8.5L15.5 1.5"
                      stroke="currentColor"
                      stroke-width="1.5"
                      stroke-linecap="round"
                      stroke-linejoin="round"
                    />
                  </svg>
                </button>

                <div class="nav-dropdown" data-nav-dropdown-panel aria-hidden="true">
                  <div class="nav-dropdown__collapse">
                    <div class="nav-dropdown__content">
                      <ul class="nav-dropdown__list nav-dropdown__list--color-cards" role="list">
                        <li class="nav-dropdown__item" data-nav-dropdown-item>
                          <a href="#custom" class="nav-card nav-card--color">
                            <span class="nav-card__color-layer" aria-hidden="true"></span>
                            <div class="nav-card__footer">
                              <span class="nav-card__title">Custom Pieces</span>
                              <span class="nav-card__action" aria-hidden="true"><svg viewBox="0 0 16 16" fill="currentColor"><path d="M2 7.25h8.19L7.22 4.28a.75.75 0 0 1 1.06-1.06l4.5 4.5a.75.75 0 0 1 0 1.06l-4.5 4.5a.75.75 0 1 1-1.06-1.06l2.97-2.97H2a.75.75 0 0 1 0-1.5Z"/></svg></span>
                            </div>
                          </a>
                        </li>
                        <li class="nav-dropdown__item" data-nav-dropdown-item>
                          <a href="#renovation" class="nav-card nav-card--color">
                            <span class="nav-card__color-layer" aria-hidden="true"></span>
                            <div class="nav-card__footer">
                              <span class="nav-card__title">Renovation</span>
                              <span class="nav-card__action" aria-hidden="true"><svg viewBox="0 0 16 16" fill="currentColor"><path d="M2 7.25h8.19L7.22 4.28a.75.75 0 0 1 1.06-1.06l4.5 4.5a.75.75 0 0 1 0 1.06l-4.5 4.5a.75.75 0 1 1-1.06-1.06l2.97-2.97H2a.75.75 0 0 1 0-1.5Z"/></svg></span>
                            </div>
                          </a>
                        </li>
                        <li class="nav-dropdown__item" data-nav-dropdown-item>
                          <a href="#wholesale" class="nav-card nav-card--color">
                            <span class="nav-card__color-layer" aria-hidden="true"></span>
                            <div class="nav-card__footer">
                              <span class="nav-card__title">Wholesale</span>
                              <span class="nav-card__action" aria-hidden="true"><svg viewBox="0 0 16 16" fill="currentColor"><path d="M2 7.25h8.19L7.22 4.28a.75.75 0 0 1 1.06-1.06l4.5 4.5a.75.75 0 0 1 0 1.06l-4.5 4.5a.75.75 0 1 1-1.06-1.06l2.97-2.97H2a.75.75 0 0 1 0-1.5Z"/></svg></span>
                            </div>
                          </a>
                        </li>
                      </ul>
                    </div>
                  </div>
                </div>
              </li>

              <li class="site-nav__item">
                <a href="#about" class="site-nav__link site-nav__link--simple">
                  <span class="site-nav__link-text">About</span>
                </a>
              </li>
              <li class="site-nav__item">
                <a href="#news" class="site-nav__link site-nav__link--simple">
                  <span class="site-nav__link-text">News</span>
                </a>
              </li>
            </ul>
          </div>

          <div class="site-nav__actions">
            <a href="#contact" class="site-nav__button site-nav__button--outline hide-on-tablet">
              <span>Contact Us</span>
            </a>
            <a href="#enquire" class="site-nav__button site-nav__button--solid">
              <span>Enquire Now</span>
            </a>
            <button
              type="button"
              class="site-nav__menu-toggle"
              data-mobile-menu-toggle
              aria-label="Open menu"
              aria-expanded="false"
              aria-controls="site-nav-mobile-nav"
            >
              <span class="site-nav__menu-toggle-line"></span>
              <span class="site-nav__menu-toggle-line"></span>
            </button>
          </div>
        </div>
      </div>

      <div class="site-nav__page-dim" data-nav-page-dim></div>
    </nav>

    <main class="hero">
      <img
        class="hero__image"
        src="https://images.unsplash.com/photo-1618221195710-dd6b41faaea6?auto=format&fit=crop&w=2200&q=80"
        alt="Minimal interior with sculptural furniture and soft natural light"
      />
      <div class="hero__veil"></div>
      <div class="hero__content">
        <p class="hero__eyebrow">Handcrafted interiors</p>
        <h1 class="hero__title">Spaces made<br />to be lived in.</h1>
        <p class="hero__text">
          Timeless furniture and quiet design details for refined homes.
        </p>
        <a href="#enquire" class="hero__cta">Explore the collection</a>
      </div>
    </main>

    <script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
    <script src="script.js"></script>
  </body>
</html>
````

## Source — styles.css
````css
/* ============================================
   Multilevel Navigation
   Premium warm palette · fluid type · GSAP-ready
   ============================================ */

:root {
  /* Premium palette — deep charcoal, ivory, champagne */
  --color-ink: #141210;
  --color-ink-soft: #2c2824;
  --color-cream: #f6f2eb;
  --color-sand: #ebe4d8;
  --color-taupe: #d4cbbd;
  --color-white: #faf8f4;
  --color-champagne: #c2a878;
  --color-overlay: rgba(12, 10, 8, 0.48);

  --ease-out-expo: cubic-bezier(0.525, 0, 0, 1);
  --ease-out-soft: cubic-bezier(0.625, 0.05, 0, 1);

  --duration-fast: 0.2s;
  --duration-normal: 0.45s;

  --nav-bar-height: 5em;
  --nav-dropdown-pad-top: 2.5em;
  --nav-dropdown-pad-bottom: 3em;
  --nav-card-height: 20em;
  --nav-open-height: calc(
    var(--nav-bar-height) + var(--nav-dropdown-pad-top) + var(--nav-card-height) +
      var(--nav-dropdown-pad-bottom)
  );

  --font-body: "DM Sans", system-ui, -apple-system, sans-serif;

  --nav-side-padding: 3em;
  --radius-sm: 0;
  --radius-md: 0;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font-body);
  color: var(--color-white);
  background: var(--color-ink);
  overflow-x: hidden;
}

body.is-mobile-menu-open {
  overflow: hidden;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

img {
  display: block;
  max-width: 100%;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--color-ink);
  outline-offset: 3px;
}

/* ---------- Hero ---------- */

.hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  width: 100%;
  height: 100svh;
  min-height: 32rem;
  padding: 2.5em 3em 3em;
  color: var(--color-white);
  overflow: hidden;
}

.hero__image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

.hero__veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(
    180deg,
    rgba(12, 10, 8, 0.42) 0%,
    rgba(12, 10, 8, 0.12) 42%,
    rgba(12, 10, 8, 0.62) 100%
  );
  pointer-events: none;
}

.hero__content {
  position: relative;
  z-index: 2;
  max-width: 42rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem;
}

.hero__eyebrow {
  margin: 0;
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-champagne);
}

.hero__title {
  margin: 0;
  font-size: clamp(2.75rem, 7.5vw, 5.5rem);
  font-weight: 500;
  line-height: 1.02;
  letter-spacing: -0.03em;
  color: var(--color-white);
}

.hero__text {
  margin: 0;
  max-width: 28rem;
  font-size: clamp(1rem, 1.6vw, 1.2rem);
  font-weight: 400;
  line-height: 1.55;
  color: rgba(250, 248, 244, 0.78);
}

.hero__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 0.75rem;
  min-height: 3em;
  padding: 0 1.4em;
  border: 1px solid var(--color-white);
  border-radius: 0;
  background: var(--color-white);
  color: var(--color-ink);
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  transition:
    background-color var(--duration-fast) var(--ease-out-expo),
    color var(--duration-fast) var(--ease-out-expo),
    border-color var(--duration-fast) var(--ease-out-expo);
}

.hero__cta:hover,
.hero__cta:focus-visible {
  background: transparent;
  color: var(--color-white);
  border-color: var(--color-white);
}

/* ---------- Navigation shell ---------- */

.site-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  color: var(--color-white);
}

.site-nav[data-theme="dark"] {
  color: var(--color-ink);
}

.site-nav__shell {
  position: relative;
  z-index: 2;
  width: 100%;
  padding: 0 var(--nav-side-padding);
}

.site-nav__panel-bg {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 0;
  background: var(--color-white);
  border-bottom-left-radius: var(--radius-md);
  border-bottom-right-radius: var(--radius-md);
  pointer-events: none;
  z-index: 0;
  will-change: height;
}

.site-nav__page-dim {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  background: var(--color-overlay);
  opacity: 0;
  pointer-events: none;
  z-index: 0;
  will-change: opacity;
}

.site-nav__bar {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-height: var(--nav-bar-height);
  padding-top: 2em;
}

.site-nav__brand {
  position: relative;
  z-index: 2;
  display: block;
  flex-shrink: 0;
  font-size: 1.35rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
}

.site-nav__menu {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex;
  justify-content: center;
}

.site-nav__list {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.15em;
}

/* Keep items static so fixed panels share one stacking context
   (otherwise an open panel covers sibling nav links) */
.site-nav__item {
  position: static;
}

.site-nav__link {
  position: relative;
  z-index: 10;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375em;
  padding: 0.75em 1.25em;
  border-radius: var(--radius-sm);
  background: transparent;
  transition: background-color var(--duration-fast) var(--ease-out-expo);
}

.site-nav__link.is-active {
  background: var(--color-sand);
}

.site-nav__link-text {
  position: relative;
  font-size: 1.25em;
  font-weight: 500;
  line-height: 1;
}

.site-nav__link--simple .site-nav__link-text::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform var(--duration-normal) var(--ease-out-expo);
}

.site-nav__link--simple:hover .site-nav__link-text::after,
.site-nav__link--simple:focus-visible .site-nav__link-text::after {
  transform: scaleX(1);
  transform-origin: left center;
}

.site-nav__chevron {
  width: 0.875em;
  height: auto;
  flex-shrink: 0;
  transition: transform var(--duration-normal) var(--ease-out-expo);
}

.site-nav__link.is-active .site-nav__chevron {
  transform: rotate(180deg);
}

.site-nav__actions {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: stretch;
  justify-content: flex-end;
  gap: 0.75em;
  flex-shrink: 0;
}

.site-nav__button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 3em;
  padding: 0 1.1em;
  border: 1px solid currentColor;
  border-radius: var(--radius-sm);
  font-size: 1em;
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
  transition:
    color var(--duration-fast) var(--ease-out-expo),
    background-color var(--duration-fast) var(--ease-out-expo),
    border-color var(--duration-fast) var(--ease-out-expo);
}

.site-nav__button--solid {
  color: var(--color-ink);
  background: var(--color-white);
  border-color: var(--color-white);
}

.site-nav[data-theme="dark"] .site-nav__button--outline {
  color: var(--color-ink);
  border-color: var(--color-ink);
}

.site-nav[data-theme="dark"] .site-nav__button--solid {
  color: var(--color-white);
  background: var(--color-ink);
  border-color: var(--color-ink);
}

.site-nav__menu-toggle {
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.28em;
  width: 3em;
  height: 3em;
  border-radius: var(--radius-sm);
  background: currentColor;
  padding: 0.75em;
}

.site-nav__menu-toggle-line {
  display: block;
  width: 100%;
  height: 1.5px;
  background: var(--color-ink);
  border-radius: 0;
  transform-origin: center;
  will-change: transform, background-color;
}

/* ---------- Dropdown panels ---------- */

.nav-dropdown {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1;
  
  padding: calc(var(--nav-bar-height) + var(--nav-dropdown-pad-top) - 0.5em)
    var(--nav-side-padding) var(--nav-dropdown-pad-bottom);
  opacity: 0;
  visibility: hidden;
  /* Panel shell never steals hover from nav links */
  pointer-events: none;
}

.nav-dropdown.is-open {
  opacity: 1;
  visibility: visible;
}

/* Only the cards themselves receive pointer events */
.nav-dropdown.is-open .nav-dropdown__content {
  pointer-events: auto;
}

.nav-dropdown__collapse {
  width: 100%;
}

.nav-dropdown__content {
  width: 100%;
  pointer-events: none;
}

.nav-dropdown__list {
  display: flex;
  gap: 1.25em;
  width: 100%;
}

.nav-dropdown__list--color-cards {
  /* same flex row, fewer cards stretch naturally */
}

.nav-dropdown__item {
  flex: 1;
  min-width: 0;
  opacity: 0;
  transform: translate3d(3.5em, 0, 0);
  will-change: transform, opacity;
}

/* ---------- Product / service cards ---------- */

.nav-card {
  --card-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --card-duration: 0.7s;

  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: stretch;
  width: 100%;
  height: var(--nav-card-height);
  padding: 1.5em;
  border-radius: var(--radius-sm);
  overflow: hidden;
  color: var(--color-white);
  background: var(--color-sand);
}

/* ----- Image cards: dual-image crossfade ----- */

.nav-card__media {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.nav-card__image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  will-change: transform, opacity;
}

.nav-card__image--default {
  opacity: 1;
  transform: scale(1);
  transition:
    opacity var(--card-duration) var(--card-ease),
    transform 1s var(--card-ease);
  z-index: 0;
}

.nav-card__image--hover {
  opacity: 0;
  transform: scale(1.08);
  transition:
    opacity var(--card-duration) var(--card-ease),
    transform 1s var(--card-ease);
  z-index: 1;
}

.nav-card__overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(
    to top,
    rgba(12, 10, 8, 0.62) 0%,
    rgba(12, 10, 8, 0.12) 52%,
    transparent 100%
  );
  opacity: 1;
  transition: opacity var(--card-duration) var(--card-ease);
  pointer-events: none;
}

.nav-card--with-image:hover .nav-card__image--default,
.nav-card--with-image:focus-visible .nav-card__image--default {
  opacity: 0;
  transform: scale(1.06);
}

.nav-card--with-image:hover .nav-card__image--hover,
.nav-card--with-image:focus-visible .nav-card__image--hover {
  opacity: 1;
  transform: scale(1);
}

.nav-card--with-image:hover .nav-card__overlay,
.nav-card--with-image:focus-visible .nav-card__overlay {
  opacity: 0.55;
}

/* ----- Static / color cards: smooth premium tint ----- */

.nav-card--color {
  color: var(--color-ink);
  background: var(--color-sand);
  transition: color var(--card-duration) var(--card-ease);
}

.nav-card__color-layer {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: linear-gradient(
    145deg,
    var(--color-sand) 0%,
    var(--color-taupe) 55%,
    #c9b89a 100%
  );
  opacity: 1;
  transition:
    opacity var(--card-duration) var(--card-ease),
    transform 0.85s var(--card-ease);
  transform: scale(1);
}

.nav-card--color::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: linear-gradient(
    145deg,
    var(--color-ink-soft) 0%,
    var(--color-ink) 48%,
    #3a3228 100%
  );
  opacity: 0;
  transform: scale(1.04);
  transition:
    opacity var(--card-duration) var(--card-ease),
    transform 0.85s var(--card-ease);
  pointer-events: none;
}

.nav-card--color:hover,
.nav-card--color:focus-visible {
  color: var(--color-white);
}

.nav-card--color:hover .nav-card__color-layer,
.nav-card--color:focus-visible .nav-card__color-layer {
  opacity: 0;
  transform: scale(1.06);
}

.nav-card--color:hover::after,
.nav-card--color:focus-visible::after {
  opacity: 1;
  transform: scale(1);
}

.nav-card__footer {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1em;
}

.nav-card__title {
  font-size: 1.75em;
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.02em;
  transition: transform 0.45s var(--card-ease);
}

.nav-card:hover .nav-card__title,
.nav-card:focus-visible .nav-card__title {
  transform: translateY(-2px);
}

/* Premium solid arrow — no border / no stroke outline */
.nav-card__action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.35em;
  height: 2.35em;
  padding: 0;
  border: 0;
  outline: 0;
  border-radius: 0;
  flex-shrink: 0;
  background: var(--color-ink);
  color: var(--color-cream);
  box-shadow: none;
  transition:
    transform 0.5s var(--card-ease),
    background-color 0.5s var(--card-ease),
    color 0.5s var(--card-ease);
}

.nav-card__action svg {
  width: 0.95em;
  height: 0.95em;
  display: block;
  fill: currentColor;
}

/* Image cards — soft ivory chip */
.nav-card--with-image .nav-card__action {
  background: var(--color-cream);
  color: var(--color-ink);
}

.nav-card--with-image:hover .nav-card__action,
.nav-card--with-image:focus-visible .nav-card__action {
  background: var(--color-champagne);
  color: var(--color-ink);
  transform: translateX(0.2em);
}

/* Color cards — ink chip → champagne on hover */
.nav-card--color .nav-card__action {
  background: var(--color-ink);
  color: var(--color-cream);
}

.nav-card--color:hover .nav-card__action,
.nav-card--color:focus-visible .nav-card__action {
  background: var(--color-champagne);
  color: var(--color-ink);
  transform: translateX(0.2em);
}

@media (prefers-reduced-motion: reduce) {
  .nav-card,
  .nav-card__image,
  .nav-card__overlay,
  .nav-card__color-layer,
  .nav-card--color::after,
  .nav-card__title,
  .nav-card__action {
    transition-duration: 0.01ms !important;
  }
}

/* ---------- Responsive ---------- */

@media screen and (max-width: 991px) {
  :root {
    --nav-side-padding: 1.25em;
  }

  .site-nav__bar {
    padding-top: 1.25em;
  }

  .site-nav__link {
    padding-left: 1em;
    padding-right: 1em;
  }

  .site-nav__link-text {
    font-size: 1em;
  }

  .hide-on-tablet {
    display: none;
  }
}

@media screen and (max-width: 767px) {
  :root {
    --nav-open-height: 100dvh;
  }

  .site-nav__menu-toggle {
    display: flex;
  }

  .site-nav__menu {
    position: absolute;
    top: 0;
    left: calc(var(--nav-side-padding) * -1);
    right: calc(var(--nav-side-padding) * -1);
    height: 100dvh;
    opacity: 0;
    visibility: hidden;
    transform: translateY(1em);
    pointer-events: none;
    z-index: 0;
    justify-content: flex-start;
    align-items: stretch;
  }

  .site-nav[data-mobile-menu="open"] .site-nav__menu {
    pointer-events: auto;
  }

  .site-nav__list {
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    width: 100%;
    height: 100%;
    padding: 7.5em var(--nav-side-padding) 2em;
    overflow-y: auto;
    gap: 0;
  }

  .site-nav__item {
    width: 100%;
  }

  .site-nav__link {
    width: 100%;
    justify-content: space-between;
    padding: 1em 0.25em;
    border-radius: 0;
  }

  .site-nav__link.is-active {
    background: transparent;
  }

  .site-nav__link-text {
    font-size: 2em;
    font-weight: 500;
  }

  .site-nav__chevron {
    width: 1em;
  }

  .nav-dropdown {
    position: relative;
    top: auto;
    left: auto;
    right: auto;
    padding: 0;
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    height: auto;
    z-index: auto;
  }

  .nav-dropdown .nav-dropdown__content,
  .nav-dropdown.is-open .nav-dropdown__content {
    pointer-events: auto;
  }

  .nav-dropdown:not(.is-open) .nav-dropdown__collapse {
    height: 0;
    overflow: hidden;
  }

  .nav-dropdown.is-open .nav-dropdown__collapse {
    height: auto;
    overflow: visible;
  }

  .nav-dropdown__list {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.75em;
    padding: 0.75em 0 1.25em;
  }

  .nav-dropdown__list--color-cards {
    grid-template-columns: 1fr;
  }

  .nav-dropdown__item {
    transform: translateX(1.5em);
  }

  .nav-card {
    height: auto;
    aspect-ratio: 1;
    padding: 1em;
  }

  .nav-card--color {
    aspect-ratio: auto;
    min-height: 4.5em;
  }

  .nav-card__title {
    font-size: 1.25em;
  }

  .site-nav[data-mobile-menu="open"] .site-nav__menu-toggle {
    background: var(--color-ink);
  }

  .site-nav[data-mobile-menu="open"] .site-nav__menu-toggle-line {
    background: var(--color-white);
  }
}

@media screen and (max-width: 479px) {
  .hero {
    padding: 1.5em 1.25em 2em;
  }

  .hero__title {
    font-size: clamp(2.25rem, 11vw, 3.25rem);
  }

  .hero__cta {
    min-height: 2.75em;
    font-size: 0.9rem;
  }

  .site-nav__brand {
    font-size: 1.15rem;
  }

  .site-nav__actions {
    gap: 0.5em;
  }

  .site-nav__button--solid {
    height: 2.5em;
    padding: 0 0.85em;
    font-size: 0.95em;
  }

  .site-nav__menu-toggle {
    width: 2.5em;
    height: 2.5em;
  }

  .nav-card {
    padding: 0.75em;
  }

  .nav-card__title {
    font-size: 1em;
  }

  .nav-card__action {
    width: 1.9em;
    height: 1.9em;
  }

  .nav-card__action svg {
    width: 0.85em;
    height: 0.85em;
  }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
````

## Source — script.js
````javascript
/* ============================================
   Multilevel Navigation — GSAP interactions
   ============================================ */

(() => {
  const EASE = "power3.out";
  const OPEN_DURATION = 0.48;
  const ITEM_STAGGER = 0.055;
  const MOBILE_BREAKPOINT = 768;
  const CLOSE_DELAY_MS = 160;

  const siteNav = document.querySelector(".site-nav");
  if (!siteNav || typeof gsap === "undefined") return;

  const panelBackground = siteNav.querySelector("[data-nav-panel-bg]");
  const pageDim = siteNav.querySelector("[data-nav-page-dim]");
  const navMenu = siteNav.querySelector("[data-nav-menu]");
  const mobileMenuToggle = siteNav.querySelector("[data-mobile-menu-toggle]");
  const mobileMenuToggleLines = mobileMenuToggle
    ? Array.from(mobileMenuToggle.querySelectorAll(".site-nav__menu-toggle-line"))
    : [];
  const simpleLinks = Array.from(siteNav.querySelectorAll(".site-nav__link--simple"));

  const dropdownEntries = Array.from(siteNav.querySelectorAll(".site-nav__item"))
    .map((item) => {
      const trigger = item.querySelector("[data-nav-dropdown-trigger]");
      const panel = item.querySelector("[data-nav-dropdown-panel]");
      if (!trigger || !panel) return null;

      // Content has pointer-events:auto — used for hover keep-alive
      const panelContent =
        panel.querySelector(".nav-dropdown__content") ||
        panel.querySelector(".nav-dropdown__list") ||
        panel;

      return { item, trigger, panel, panelContent };
    })
    .filter(Boolean);

  let currentMode = null;
  let activeDropdown = null;
  let isMobileMenuOpen = false;
  let openTimeline = null;
  let closeTimer = null;
  let prefersReducedMotion = window.matchMedia(
    "(prefers-reduced-motion: reduce)"
  ).matches;

  const desktopListeners = [];
  const mobileListeners = [];

  const isMobileView = () => window.innerWidth < MOBILE_BREAKPOINT;

  function getPanelOpenHeight() {
    if (isMobileView()) return window.innerHeight;

    const probe = document.createElement("div");
    probe.style.cssText =
      "position:absolute;visibility:hidden;pointer-events:none;height:var(--nav-open-height)";
    document.body.appendChild(probe);
    const heightInPixels = probe.getBoundingClientRect().height;
    probe.remove();
    return heightInPixels > 0 ? heightInPixels : "30.5em";
  }

  function setNavTheme(isDark) {
    siteNav.dataset.theme = isDark ? "dark" : "light";
  }

  function killOpenTimeline() {
    if (openTimeline) {
      openTimeline.kill();
      openTimeline = null;
    }
  }

  function clearCloseTimer() {
    if (closeTimer) {
      clearTimeout(closeTimer);
      closeTimer = null;
    }
  }

  function openNavShell({ instant = false } = {}) {
    const duration = prefersReducedMotion || instant ? 0 : OPEN_DURATION;

    gsap.to(panelBackground, {
      height: getPanelOpenHeight(),
      duration,
      ease: EASE,
      overwrite: "auto",
    });

    gsap.to(pageDim, {
      opacity: 1,
      duration: prefersReducedMotion || instant ? 0 : 0.28,
      ease: "power2.out",
      overwrite: "auto",
    });

    setNavTheme(true);
  }

  function closeNavShell({ instant = false } = {}) {
    const duration = prefersReducedMotion || instant ? 0 : OPEN_DURATION * 0.85;

    gsap.to(panelBackground, {
      height: 0,
      duration,
      ease: EASE,
      overwrite: "auto",
    });

    gsap.to(pageDim, {
      opacity: 0,
      duration: prefersReducedMotion || instant ? 0 : 0.22,
      ease: "power2.out",
      overwrite: "auto",
    });

    setNavTheme(false);
  }

  function getDropdownItems(panel) {
    return panel.querySelectorAll("[data-nav-dropdown-item]");
  }

  function resetDropdownItems(panel) {
    const items = getDropdownItems(panel);
    gsap.killTweensOf(items);
    gsap.set(items, {
      opacity: 0,
      x: isMobileView() ? 20 : 56,
    });
  }

  function animateDropdownItemsIn(panel, { fromMobile = false, isSwitch = false } = {}) {
    const items = getDropdownItems(panel);
    killOpenTimeline();
    gsap.killTweensOf(items);

    const fromX = fromMobile ? 20 : isSwitch ? 32 : 56;
    const delay = prefersReducedMotion ? 0 : isSwitch ? 0.04 : 0.14;

    gsap.set(items, { opacity: 0, x: fromX });

    openTimeline = gsap.timeline({ defaults: { ease: EASE } });
    openTimeline.to(items, {
      opacity: 1,
      x: 0,
      duration: prefersReducedMotion ? 0 : isSwitch ? 0.38 : OPEN_DURATION,
      stagger: prefersReducedMotion ? 0 : ITEM_STAGGER,
      delay,
    });
  }

  function deactivateDropdown(entry) {
    if (!entry?.panel) return;

    killOpenTimeline();
    gsap.killTweensOf(getDropdownItems(entry.panel));

    entry.panel.classList.remove("is-open");
    entry.panel.setAttribute("aria-hidden", "true");
    entry.trigger.classList.remove("is-active");
    entry.trigger.setAttribute("aria-expanded", "false");
    resetDropdownItems(entry.panel);

    if (activeDropdown === entry) activeDropdown = null;
  }

  /** Open or switch a desktop dropdown panel */
  function openDesktopDropdown(entry) {
    if (!entry?.panel) return;
    clearCloseTimer();

    if (activeDropdown === entry && entry.panel.classList.contains("is-open")) {
      return;
    }

    const isSwitching = Boolean(activeDropdown && activeDropdown !== entry);

    if (isSwitching) {
      deactivateDropdown(activeDropdown);
    }

    entry.panel.classList.add("is-open");
    entry.panel.setAttribute("aria-hidden", "false");
    entry.trigger.classList.add("is-active");
    entry.trigger.setAttribute("aria-expanded", "true");
    activeDropdown = entry;

    // Keep white shell open when swapping Products ↔ Services
    openNavShell({ instant: isSwitching });
    animateDropdownItemsIn(entry.panel, { isSwitch: isSwitching });
  }

  function closeDesktopDropdown(entry, { instant = false } = {}) {
    if (!entry) return;
    clearCloseTimer();

    const finishClose = () => {
      deactivateDropdown(entry);
      closeNavShell({ instant });
    };

    if (instant || prefersReducedMotion) {
      finishClose();
      return;
    }

    const items = getDropdownItems(entry.panel);
    killOpenTimeline();
    gsap.killTweensOf(items);

    gsap.to(items, {
      opacity: 0,
      x: -16,
      duration: 0.18,
      stagger: 0.015,
      ease: "power2.in",
      overwrite: "auto",
      onComplete: finishClose,
    });
  }

  function scheduleDesktopDropdownClose(entry) {
    clearCloseTimer();
    closeTimer = setTimeout(() => {
      if (activeDropdown === entry) closeDesktopDropdown(entry);
      closeTimer = null;
    }, CLOSE_DELAY_MS);
  }

  function bindDesktopInteractions() {
    const controller = new AbortController();
    desktopListeners.push(controller);
    const { signal } = controller;

    dropdownEntries.forEach((entry) => {
      entry.trigger.addEventListener(
        "mouseenter",
        () => openDesktopDropdown(entry),
        { signal }
      );

      entry.trigger.addEventListener(
        "mouseleave",
        (event) => {
          const related = event.relatedTarget;

          if (related instanceof Node && entry.panelContent.contains(related)) {
            clearCloseTimer();
            return;
          }

          if (
            related instanceof Element &&
            related.closest("[data-nav-dropdown-trigger]")
          ) {
            return;
          }

          scheduleDesktopDropdownClose(entry);
        },
        { signal }
      );

      entry.panelContent.addEventListener(
        "mouseenter",
        () => {
          clearCloseTimer();
          if (activeDropdown !== entry) openDesktopDropdown(entry);
        },
        { signal }
      );

      entry.panelContent.addEventListener(
        "mouseleave",
        (event) => {
          const related = event.relatedTarget;

          if (
            related instanceof Element &&
            related.closest("[data-nav-dropdown-trigger]")
          ) {
            return;
          }

          if (related instanceof Node && entry.trigger.contains(related)) {
            clearCloseTimer();
            return;
          }

          scheduleDesktopDropdownClose(entry);
        },
        { signal }
      );

      entry.trigger.addEventListener(
        "click",
        (event) => {
          event.preventDefault();
          if (activeDropdown === entry && entry.panel.classList.contains("is-open")) {
            closeDesktopDropdown(entry);
          } else {
            openDesktopDropdown(entry);
          }
        },
        { signal }
      );

      entry.trigger.addEventListener(
        "keydown",
        (event) => {
          if (event.key === "Escape") {
            closeDesktopDropdown(entry, { instant: true });
            entry.trigger.focus();
          }
        },
        { signal }
      );
    });

    simpleLinks.forEach((link) => {
      link.addEventListener(
        "mouseenter",
        () => {
          if (activeDropdown) closeDesktopDropdown(activeDropdown);
        },
        { signal }
      );
    });

    document.addEventListener(
      "keydown",
      (event) => {
        if (event.key === "Escape" && activeDropdown) {
          closeDesktopDropdown(activeDropdown, { instant: true });
        }
      },
      { signal }
    );

    document.addEventListener(
      "pointerdown",
      (event) => {
        if (!activeDropdown) return;
        if (siteNav.contains(event.target)) return;
        closeDesktopDropdown(activeDropdown);
      },
      { signal }
    );
  }

  function unbindDesktopInteractions() {
    desktopListeners.splice(0).forEach((controller) => controller.abort());
    clearCloseTimer();
    if (activeDropdown) {
      deactivateDropdown(activeDropdown);
    }
    closeNavShell({ instant: true });
    activeDropdown = null;
  }

  /* ---------- Mobile ---------- */

  function animateMobileMenuToggle(isOpen) {
    if (!mobileMenuToggleLines.length) return;
    const duration = prefersReducedMotion ? 0 : 0.4;

    if (isOpen) {
      gsap.to(mobileMenuToggleLines[0], {
        y: 3.25,
        rotation: 135,
        backgroundColor: "#ffffff",
        duration,
        ease: EASE,
        overwrite: "auto",
      });
      gsap.to(mobileMenuToggleLines[1], {
        y: -3.25,
        rotation: -135,
        backgroundColor: "#ffffff",
        duration,
        ease: EASE,
        overwrite: "auto",
      });
    } else {
      gsap.to(mobileMenuToggleLines, {
        y: 0,
        rotation: 0,
        backgroundColor: "#141210",
        duration,
        ease: EASE,
        overwrite: "auto",
      });
    }
  }

  function openMobileMenu() {
    isMobileMenuOpen = true;
    siteNav.dataset.mobileMenu = "open";
    mobileMenuToggle?.setAttribute("aria-expanded", "true");
    mobileMenuToggle?.setAttribute("aria-label", "Close menu");
    document.body.classList.add("is-mobile-menu-open");

    openNavShell();
    animateMobileMenuToggle(true);

    gsap.fromTo(
      navMenu,
      { opacity: 0, y: 18, visibility: "hidden" },
      {
        opacity: 1,
        y: 0,
        visibility: "visible",
        duration: prefersReducedMotion ? 0 : 0.48,
        delay: prefersReducedMotion ? 0 : 0.1,
        ease: EASE,
        overwrite: "auto",
      }
    );
  }

  function closeMobileDropdown(entry, { instant = false } = {}) {
    const collapse = entry.panel.querySelector(".nav-dropdown__collapse");

    const finishClose = () => {
      entry.panel.classList.remove("is-open");
      entry.panel.setAttribute("aria-hidden", "true");
      entry.trigger.classList.remove("is-active");
      entry.trigger.setAttribute("aria-expanded", "false");
      resetDropdownItems(entry.panel);
      if (collapse) gsap.set(collapse, { clearProps: "height,overflow" });
    };

    if (
      collapse &&
      !instant &&
      !prefersReducedMotion &&
      entry.panel.classList.contains("is-open")
    ) {
      gsap.to(collapse, {
        height: 0,
        duration: 0.32,
        ease: "power2.inOut",
        overwrite: "auto",
        onStart: () => gsap.set(collapse, { overflow: "hidden" }),
        onComplete: finishClose,
      });
    } else {
      finishClose();
    }
  }

  function openMobileDropdown(entry) {
    dropdownEntries.forEach((other) => {
      if (other !== entry && other.panel.classList.contains("is-open")) {
        closeMobileDropdown(other, { instant: true });
      }
    });

    entry.panel.classList.add("is-open");
    entry.panel.setAttribute("aria-hidden", "false");
    entry.trigger.classList.add("is-active");
    entry.trigger.setAttribute("aria-expanded", "true");

    const collapse = entry.panel.querySelector(".nav-dropdown__collapse");
    if (collapse && !prefersReducedMotion) {
      gsap.fromTo(
        collapse,
        { height: 0, overflow: "hidden" },
        {
          height: "auto",
          duration: 0.42,
          ease: EASE,
          overwrite: "auto",
          onComplete: () => gsap.set(collapse, { clearProps: "height,overflow" }),
        }
      );
    }

    animateDropdownItemsIn(entry.panel, { fromMobile: true });
  }

  function closeMobileMenu({ instant = false } = {}) {
    dropdownEntries.forEach((entry) => {
      if (entry.panel.classList.contains("is-open")) {
        closeMobileDropdown(entry, { instant: true });
      }
    });

    isMobileMenuOpen = false;
    siteNav.dataset.mobileMenu = "closed";
    mobileMenuToggle?.setAttribute("aria-expanded", "false");
    mobileMenuToggle?.setAttribute("aria-label", "Open menu");
    document.body.classList.remove("is-mobile-menu-open");

    gsap.to(navMenu, {
      opacity: 0,
      y: 12,
      duration: prefersReducedMotion || instant ? 0 : 0.28,
      ease: "power2.in",
      overwrite: "auto",
      onComplete: () => gsap.set(navMenu, { visibility: "hidden" }),
    });

    closeNavShell({ instant });
    animateMobileMenuToggle(false);
  }

  function bindMobileInteractions() {
    const controller = new AbortController();
    mobileListeners.push(controller);
    const { signal } = controller;

    gsap.set(navMenu, { opacity: 0, visibility: "hidden", y: 12 });

    mobileMenuToggle?.addEventListener(
      "click",
      () => {
        if (isMobileMenuOpen) closeMobileMenu();
        else openMobileMenu();
      },
      { signal }
    );

    dropdownEntries.forEach((entry) => {
      entry.trigger.addEventListener(
        "click",
        () => {
          if (!isMobileView()) return;
          if (entry.panel.classList.contains("is-open")) {
            closeMobileDropdown(entry);
          } else {
            openMobileDropdown(entry);
          }
        },
        { signal }
      );
    });
  }

  function unbindMobileInteractions() {
    mobileListeners.splice(0).forEach((controller) => controller.abort());
    if (isMobileMenuOpen) closeMobileMenu({ instant: true });
    gsap.set(navMenu, { clearProps: "all" });
    gsap.set(mobileMenuToggleLines, { clearProps: "all" });

    dropdownEntries.forEach((entry) => {
      entry.panel.classList.remove("is-open");
      entry.panel.setAttribute("aria-hidden", "true");
      entry.trigger.classList.remove("is-active");
      entry.trigger.setAttribute("aria-expanded", "false");
      resetDropdownItems(entry.panel);
    });
  }

  function applyViewportMode() {
    const nextMode = isMobileView() ? "mobile" : "desktop";
    if (nextMode === currentMode) return;

    if (currentMode === "desktop") unbindDesktopInteractions();
    if (currentMode === "mobile") unbindMobileInteractions();

    currentMode = nextMode;
    if (currentMode === "mobile") bindMobileInteractions();
    else bindDesktopInteractions();
  }

  function debounce(fn, delay) {
    let timer;
    return (...args) => {
      clearTimeout(timer);
      timer = setTimeout(() => fn(...args), delay);
    };
  }

  /* ---------- Init ---------- */

  dropdownEntries.forEach((entry) => resetDropdownItems(entry.panel));
  gsap.set(panelBackground, { height: 0 });
  gsap.set(pageDim, { opacity: 0 });

  applyViewportMode();
  window.addEventListener("resize", debounce(applyViewportMode, 180));

  window
    .matchMedia("(prefers-reduced-motion: reduce)")
    .addEventListener("change", (event) => {
      prefersReducedMotion = event.matches;
    });
})();
````
