{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "mega-menu",
  "type": "registry:block",
  "title": "Mega Menu",
  "description": "A nav bar whose mega panel springs open under the hovered trigger and morphs its size and position between triggers, with a caret that tracks and content that slides in from the direction you moved. Each column has a CSS-art preview that comes alive on hover.",
  "docs": "Mega Menu was added to public/vividsites/mega-menu.html. Paste its markup, <style> and <script> where you want it on the page (or open the file to see it alone). Customise it with the CSS variables at the top. Docs and live demo: https://vividsites.app/c/mega-menu",
  "categories": [
    "ui",
    "navigation"
  ],
  "files": [
    {
      "path": "components/vividsites/mega-menu.html",
      "type": "registry:file",
      "target": "public/vividsites/mega-menu.html",
      "content": "<!--\nvs-mega-menu: a nav bar whose mega panel springs open under the hovered trigger, then morphs\n  its width, height and position between triggers on physical springs (interruptible, never a\n  fixed-duration tween). The frame is shaped with clip-path, so the corner radius never\n  distorts mid-morph; a caret tracks the trigger on its own spring; content slides in from the\n  direction you travelled. Column previews are CSS art (no images) tinted by the accent, and\n  they come alive when their column is hovered or focused.\n\n  Markup: each <li> holds a <button class=\"vs-mega-menu-trigger\"> followed by its panel,\n    <div class=\"vs-mega-menu-content\">. Plain links in the list (.vs-mega-menu-top) close it.\n  Attributes on the <nav>:\n    data-open   \"hover\" (default) or \"click\"\n  On an <li>: data-collapse=\"xs\" hides that item under 440px; .vs-mega-menu-end hides under 640px.\n  Modifier: .vs-mega-menu--dark (dark bar and panel).\n  Keyboard: Enter / Space / ArrowDown opens and focuses the panel, Arrow keys move, Tab flows\n    through the panel and on, Escape closes and returns focus. aria-expanded and aria-controls\n    are kept in sync.\n  Events (bubble from the <nav>): \"megaopen\" detail {index}, \"megaclose\".\n  API: window.vsMegaMenu.mount(nav) -> { open(i), close() }.\n  Style with the --vs-mega-menu-* variables below. Reduced motion: no springs, instant.\n-->\n<link href=\"https://fonts.googleapis.com/css2?family=Mulish:wght@400;500;600&display=swap\" rel=\"stylesheet\">\n<nav class=\"vs-mega-menu\" aria-label=\"Main\" data-open=\"hover\">\n  <div class=\"vs-mega-menu-bar\">\n    <ul class=\"vs-mega-menu-list\">\n      <li>\n        <button class=\"vs-mega-menu-trigger\" type=\"button\">Products</button>\n        <div class=\"vs-mega-menu-content\">\n          <div class=\"vs-mega-menu-cols\">\n            <div class=\"vs-mega-menu-col\">\n              <span class=\"vs-mega-menu-art vs-mega-menu-art--stack\" aria-hidden=\"true\"><i></i><i></i><i></i></span>\n              <p class=\"vs-mega-menu-kicker\">Compose</p>\n              <a class=\"vs-mega-menu-item\" href=\"#canvas\"><b>Canvas</b><span>Design and prototype in one file</span></a>\n              <a class=\"vs-mega-menu-item\" href=\"#blocks\"><b>Blocks</b><span>Shared parts, one source</span></a>\n            </div>\n            <div class=\"vs-mega-menu-col\">\n              <span class=\"vs-mega-menu-art vs-mega-menu-art--orbit\" aria-hidden=\"true\"><i></i><i></i><i></i></span>\n              <p class=\"vs-mega-menu-kicker\">Deliver</p>\n              <a class=\"vs-mega-menu-item\" href=\"#relay\"><b>Relay</b><span>Edge delivery in 38 regions</span></a>\n              <a class=\"vs-mega-menu-item\" href=\"#vault\"><b>Vault</b><span>Versioned asset storage</span></a>\n            </div>\n            <div class=\"vs-mega-menu-col\">\n              <span class=\"vs-mega-menu-art vs-mega-menu-art--bars\" aria-hidden=\"true\"><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span>\n              <p class=\"vs-mega-menu-kicker\">Observe</p>\n              <a class=\"vs-mega-menu-item\" href=\"#pulse\"><b>Pulse</b><span>Live metrics, zero setup</span></a>\n              <a class=\"vs-mega-menu-item\" href=\"#trace\"><b>Trace</b><span>Replay any session</span></a>\n            </div>\n          </div>\n          <a class=\"vs-mega-menu-foot\" href=\"#relay-2\"><em>New</em>Relay 2.0 settles traffic before it spikes<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M3 8h9M8.5 4.5 12 8l-3.5 3.5\"/></svg></a>\n        </div>\n      </li>\n      <li>\n        <button class=\"vs-mega-menu-trigger\" type=\"button\">Solutions</button>\n        <div class=\"vs-mega-menu-content\">\n          <div class=\"vs-mega-menu-cols\">\n            <div class=\"vs-mega-menu-col vs-mega-menu-col--list\">\n              <p class=\"vs-mega-menu-kicker\">By team</p>\n              <a class=\"vs-mega-menu-link\" href=\"#design\">Design</a>\n              <a class=\"vs-mega-menu-link\" href=\"#engineering\">Engineering</a>\n              <a class=\"vs-mega-menu-link\" href=\"#marketing\">Marketing</a>\n              <a class=\"vs-mega-menu-link\" href=\"#operations\">Operations</a>\n            </div>\n            <div class=\"vs-mega-menu-col vs-mega-menu-col--list\">\n              <p class=\"vs-mega-menu-kicker\">By stage</p>\n              <a class=\"vs-mega-menu-link\" href=\"#early\">Early teams</a>\n              <a class=\"vs-mega-menu-link\" href=\"#scaling\">Scaling</a>\n              <a class=\"vs-mega-menu-link\" href=\"#enterprise\">Enterprise</a>\n            </div>\n            <a class=\"vs-mega-menu-card\" href=\"#field-guide\">\n              <span class=\"vs-mega-menu-art vs-mega-menu-art--sun\" aria-hidden=\"true\"><i></i><i></i></span>\n              <p class=\"vs-mega-menu-kicker\">Field guide</p>\n              <b>Ship a rebrand in a week</b>\n              <span>How a 40-person team moved every file without a freeze.</span>\n            </a>\n          </div>\n        </div>\n      </li>\n      <li>\n        <button class=\"vs-mega-menu-trigger\" type=\"button\">Resources</button>\n        <div class=\"vs-mega-menu-content\">\n          <div class=\"vs-mega-menu-tiles\">\n            <a class=\"vs-mega-menu-tile\" href=\"#docs\"><span class=\"vs-mega-menu-art vs-mega-menu-art--grid\" aria-hidden=\"true\"><i></i><i></i><i></i></span><b>Docs</b><span>Start in five minutes</span></a>\n            <a class=\"vs-mega-menu-tile\" href=\"#changelog\"><span class=\"vs-mega-menu-art vs-mega-menu-art--arcs\" aria-hidden=\"true\"><i></i><i></i><i></i></span><b>Changelog</b><span>Shipped this week</span></a>\n            <a class=\"vs-mega-menu-tile\" href=\"#templates\"><span class=\"vs-mega-menu-art vs-mega-menu-art--tiles\" aria-hidden=\"true\"><i></i><i></i><i></i><i></i></span><b>Templates</b><span>240 starters</span></a>\n            <a class=\"vs-mega-menu-tile\" href=\"#office-hours\"><span class=\"vs-mega-menu-art vs-mega-menu-art--dial\" aria-hidden=\"true\"><i></i><i></i></span><b>Office hours</b><span>Thursdays, 16:00</span></a>\n          </div>\n        </div>\n      </li>\n      <li data-collapse=\"xs\"><a class=\"vs-mega-menu-top\" href=\"#pricing\">Pricing</a></li>\n    </ul>\n    <div class=\"vs-mega-menu-end\">\n      <a class=\"vs-mega-menu-top\" href=\"#sign-in\">Sign in</a>\n      <a class=\"vs-mega-menu-cta\" href=\"#start\">Start building</a>\n    </div>\n  </div>\n</nav>\n\n<style>\n.vs-mega-menu {\n  --vs-mega-menu-size: 1rem;                   /* scales everything */\n  --vs-mega-menu-font: \"Mulish\", ui-sans-serif, system-ui, sans-serif;\n  --vs-mega-menu-accent: #2f5bff;              /* CTA, art, chips */\n  --vs-mega-menu-accent-ink: #ffffff;          /* text on the accent */\n  --vs-mega-menu-radius: 18px;                 /* panel corner; the bar, items and art follow it */\n  --vs-mega-menu-bg: #ffffff;                  /* bar and panel */\n  --vs-mega-menu-ink: 21, 23, 30;              /* rgb of the text */\n  --vs-mega-menu-edge: rgba(21,23,30,.1);      /* the hairline around the panel */\n  --vs-mega-menu-gap: 10px;                    /* bar to panel */\n  --vs-mega-menu-focus: #2f5bff;\n  --vs-mega-menu-spring: cubic-bezier(.3,1.4,.5,1);\n  --vs-mega-menu-settle: cubic-bezier(.2,1,.3,1);\n\n  --r: var(--vs-mega-menu-radius);\n  --art: color-mix(in srgb, var(--vs-mega-menu-accent) 8%, var(--vs-mega-menu-bg));\n  position: relative; z-index: 30; display: block; height: max-content; align-self: flex-start; font-size: var(--vs-mega-menu-size);\n  font-family: var(--vs-mega-menu-font); color: rgb(var(--vs-mega-menu-ink));\n  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;\n}\n@supports (transition-timing-function: linear(0, 1)) {\n  .vs-mega-menu {\n    --vs-mega-menu-spring: linear(0, .059, .195, .36, .537, .692, .827, .928, 1.002, 1.049, 1.074, 1.082, 1.079, 1.069, 1.055, 1.041, 1.027, 1.016, 1.007, 1.001, .997, .994, .993, .993, .994, .995, .996, .998, 1);\n    --vs-mega-menu-settle: linear(0, .051, .158, .288, .429, .553, .661, .751, .827, .883, .925, .956, .977, .991, 1, 1.005, 1.008, 1.008, 1.008, 1.007, 1.006, 1.005, 1.004, 1.003, 1.002, 1.002, 1.001, 1.001, 1);\n  }\n}\n.vs-mega-menu, .vs-mega-menu * { box-sizing: border-box; }\n.vs-mega-menu p { margin: 0; }\n.vs-mega-menu--dark {\n  --vs-mega-menu-bg: #17191f; --vs-mega-menu-ink: 236, 238, 243; --vs-mega-menu-edge: rgba(255,255,255,.1);\n  --art: color-mix(in srgb, var(--vs-mega-menu-accent) 16%, var(--vs-mega-menu-bg)); --vs-mega-menu-focus: #8fb0ff;\n}\n/* ---------- bar ---------- */\n.vs-mega-menu-bar {\n  position: relative; z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: 1em;\n  padding: .375em; border-radius: calc(var(--r) * .8 + 6px); background: var(--vs-mega-menu-bg);\n  box-shadow: 0 0 0 .5px var(--vs-mega-menu-edge), inset 0 1px 0 rgba(255,255,255,.7),\n    0 1px 2px rgba(var(--vs-mega-menu-ink), .05), 0 .5em 1.5em -.75em rgba(var(--vs-mega-menu-ink), .18);\n}\n.vs-mega-menu--dark .vs-mega-menu-bar { box-shadow: 0 0 0 .5px var(--vs-mega-menu-edge), inset 0 1px 0 rgba(255,255,255,.06), 0 1px 2px rgba(0,0,0,.3), 0 .5em 1.5em -.75em rgba(0,0,0,.6); }\n.vs-mega-menu-hl {\n  position: absolute; inset: 0; pointer-events: none; opacity: 0; border-radius: inherit;\n  background: rgba(var(--vs-mega-menu-ink), .055); clip-path: inset(0 100% 0 0);\n}\n.vs-mega-menu-list, .vs-mega-menu-end { position: relative; display: flex; align-items: center; gap: .125em; margin: 0; padding: 0; list-style: none; }\n.vs-mega-menu-list > li { display: block; margin: 0; }\n.vs-mega-menu-end { gap: .375em; }\n.vs-mega-menu-trigger, .vs-mega-menu-top, .vs-mega-menu-cta {\n  all: unset; box-sizing: border-box; display: inline-flex; align-items: center; gap: .3em; cursor: pointer;\n  padding: .72em .95em; border-radius: calc(var(--r) * .55 + 2px); white-space: nowrap;\n  font: 500 1em/1 var(--vs-mega-menu-font); letter-spacing: -.005em; color: rgba(var(--vs-mega-menu-ink), .7);\n  -webkit-tap-highlight-color: transparent; transition: color 150ms cubic-bezier(.2,0,0,1);\n}\n.vs-mega-menu-trigger:hover, .vs-mega-menu-top:hover, .vs-mega-menu-trigger[aria-expanded=\"true\"] { color: rgb(var(--vs-mega-menu-ink)); }\n.vs-mega-menu-chev { width: .75em; height: .75em; margin-right: -.2em; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; opacity: .55; transition: transform .62s var(--vs-mega-menu-spring), opacity .15s; }\n.vs-mega-menu-trigger[aria-expanded=\"true\"] .vs-mega-menu-chev { transform: rotate(-180deg); opacity: .9; }\n.vs-mega-menu-cta {\n  padding-inline: 1.15em; font-weight: 600; color: var(--vs-mega-menu-accent-ink); background: var(--vs-mega-menu-accent);\n  box-shadow: inset 0 1px 0 rgba(255,255,255,.22), inset 0 0 0 .5px rgba(0,0,0,.12),\n    0 1px 2px color-mix(in srgb, var(--vs-mega-menu-accent) 40%, transparent), 0 .5em 1em -.5em color-mix(in srgb, var(--vs-mega-menu-accent) 70%, transparent);\n  transition: transform .45s var(--vs-mega-menu-settle), filter .15s;\n}\n.vs-mega-menu-cta:hover { transform: translateY(-1px); filter: brightness(1.08); }\n.vs-mega-menu-cta:active { transform: scale(.97); transition-duration: .08s; }\n.vs-mega-menu :is(.vs-mega-menu-trigger, .vs-mega-menu-top, .vs-mega-menu-cta, a):focus-visible {\n  outline: 2px solid var(--vs-mega-menu-focus); outline-offset: 2px;\n}\n.vs-mega-menu :is(button, a)[aria-disabled=\"true\"], .vs-mega-menu button:disabled { opacity: .4; pointer-events: none; }\n/* ---------- the morphing panel ---------- */\n.vs-mega-menu-viewport { position: absolute; left: 0; top: calc(100% + var(--vs-mega-menu-gap)); z-index: 1; visibility: hidden; pointer-events: none; }\n.vs-mega-menu.is-open .vs-mega-menu-viewport { pointer-events: auto; }\n.vs-mega-menu-bridge { position: absolute; left: 0; bottom: 100%; width: 100px; height: calc(var(--vs-mega-menu-gap) + 4px); transform-origin: 0 0; }\n.vs-mega-menu-frame {\n  position: relative; transform-origin: 50% 0; will-change: transform, opacity;\n  filter: drop-shadow(0 .75em 1.25em rgba(var(--vs-mega-menu-ink), .1)) drop-shadow(0 2px 3px rgba(var(--vs-mega-menu-ink), .06));\n}\n.vs-mega-menu--dark .vs-mega-menu-frame { filter: drop-shadow(0 1em 1.5em rgba(0,0,0,.5)) drop-shadow(0 2px 3px rgba(0,0,0,.3)); }\n.vs-mega-menu-edge, .vs-mega-menu-fill, .vs-mega-menu-clip { position: absolute; inset: 0; clip-path: inset(0 100% 100% 0); }\n.vs-mega-menu-edge { background: var(--vs-mega-menu-edge); }\n.vs-mega-menu-fill { background: linear-gradient(180deg, rgba(255,255,255,.5), rgba(255,255,255,0) 4em), var(--vs-mega-menu-bg); }\n.vs-mega-menu--dark .vs-mega-menu-fill { background: linear-gradient(180deg, rgba(255,255,255,.035), rgba(255,255,255,0) 4em), var(--vs-mega-menu-bg); }\n.vs-mega-menu-caret {\n  position: absolute; left: -.375em; top: -.375em; width: .75em; height: .75em; border-radius: 3px 0 0 0;\n  background: var(--vs-mega-menu-bg); box-shadow: -.5px -.5px 0 0 var(--vs-mega-menu-edge);\n}\n.vs-mega-menu-page {\n  position: absolute; left: 0; top: 0; width: max-content; max-width: var(--vs-mega-menu-avail, calc(100vw - 24px));\n  padding: 1.125em; will-change: transform, opacity;\n}\n/* ---------- panel content ---------- */\n.vs-mega-menu-cols { display: flex; gap: 1em; }\n.vs-mega-menu-col { display: flex; flex-direction: column; width: 13.75em; }\n.vs-mega-menu-col--list { width: 10.5em; padding-top: .25em; }\n.vs-mega-menu-kicker {\n  padding: .5em .75em .375em; font: 600 .6875em/1.2 var(--vs-mega-menu-font); letter-spacing: .16em; text-transform: uppercase;\n  color: rgba(var(--vs-mega-menu-ink), .44);\n}\n.vs-mega-menu-item, .vs-mega-menu-link, .vs-mega-menu-foot, .vs-mega-menu-card, .vs-mega-menu-tile {\n  display: block; color: inherit; text-decoration: none; border-radius: calc(var(--r) * .5 + 2px);\n  transition: background-color 150ms cubic-bezier(.2,0,0,1); -webkit-tap-highlight-color: transparent;\n}\n.vs-mega-menu-item { padding: .55em .75em .6em; }\n.vs-mega-menu-item b, .vs-mega-menu-card b, .vs-mega-menu-tile b { display: flex; align-items: center; gap: .35em; font-weight: 600; font-size: .9375em; letter-spacing: -.005em; line-height: 1.25; }\n.vs-mega-menu-item b::after, .vs-mega-menu-tile b::after {\n  content: \"\"; width: .4em; height: .4em; border: solid currentColor; border-width: 1.5px 1.5px 0 0; transform: translateX(-.3em) rotate(45deg);\n  opacity: 0; transition: transform .45s var(--vs-mega-menu-settle), opacity .15s;\n}\n.vs-mega-menu-item:hover b::after, .vs-mega-menu-item:focus-visible b::after, .vs-mega-menu-tile:hover b::after { opacity: .6; transform: translateX(0) rotate(45deg); }\n.vs-mega-menu-item span, .vs-mega-menu-card > span:last-child, .vs-mega-menu-tile > span:last-child {\n  display: block; margin-top: .2em; font-size: .8125em; line-height: 1.4; color: rgba(var(--vs-mega-menu-ink), .55);\n}\n.vs-mega-menu-link { padding: .5em .75em; font-weight: 500; font-size: .9375em; color: rgba(var(--vs-mega-menu-ink), .78); }\n.vs-mega-menu :is(.vs-mega-menu-item, .vs-mega-menu-link, .vs-mega-menu-card, .vs-mega-menu-tile, .vs-mega-menu-foot):hover { background-color: rgba(var(--vs-mega-menu-ink), .045); }\n.vs-mega-menu-link:hover { color: rgb(var(--vs-mega-menu-ink)); }\n.vs-mega-menu-foot {\n  display: flex; align-items: center; gap: .65em; margin-top: .875em; padding: .75em;\n  font-size: .8125em; font-weight: 500; color: rgba(var(--vs-mega-menu-ink), .72);\n  box-shadow: inset 0 .5px 0 var(--vs-mega-menu-edge); border-radius: 0 0 calc(var(--r) * .5 + 2px) calc(var(--r) * .5 + 2px);\n}\n.vs-mega-menu-foot em {\n  font: 600 .8125em/1 var(--vs-mega-menu-font); font-style: normal; letter-spacing: .1em; text-transform: uppercase;\n  padding: .45em .65em; border-radius: 999px; color: var(--vs-mega-menu-accent);\n  background: color-mix(in srgb, var(--vs-mega-menu-accent) 12%, transparent);\n}\n.vs-mega-menu-foot svg { width: 1.1em; height: 1.1em; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; transition: transform .45s var(--vs-mega-menu-settle); }\n.vs-mega-menu-foot:hover svg { transform: translateX(3px); }\n.vs-mega-menu-card { display: flex; flex-direction: column; width: 15.5em; padding: .5em .5em .75em; background: rgba(var(--vs-mega-menu-ink), .025); box-shadow: inset 0 0 0 .5px var(--vs-mega-menu-edge); }\n.vs-mega-menu-card .vs-mega-menu-art { height: 8.5em; margin-bottom: .6em; }\n.vs-mega-menu-card .vs-mega-menu-kicker { padding: .5em .25em .375em; }\n.vs-mega-menu-card b { padding: 0 .25rem; font-size: 1.0625em; }\n.vs-mega-menu-card > span:last-child { padding: 0 .25rem; }\n.vs-mega-menu-tiles { display: grid; grid-template-columns: repeat(2, 15em); gap: .375em; }\n.vs-mega-menu-tile { display: grid; grid-template-columns: 3.75em 1fr; column-gap: .875em; align-content: center; padding: .5em; }\n.vs-mega-menu-tile .vs-mega-menu-art { grid-row: 1 / span 2; height: 3.75em; margin: 0; border-radius: calc(var(--r) * .45 + 2px); }\n.vs-mega-menu-tile b { align-self: end; }\n.vs-mega-menu-tile > span:last-child { margin-top: .1em; align-self: start; }\n/* ---------- CSS art previews (no images): tinted by the accent, alive on hover/focus ---------- */\n.vs-mega-menu-art {\n  --a: var(--vs-mega-menu-accent); --lt: color-mix(in srgb, var(--a) 28%, #fff);\n  position: relative; display: block; height: 7em; margin: 0 0 .5em; overflow: hidden; isolation: isolate;\n  border-radius: calc(var(--r) * .6 + 2px); background: var(--art); box-shadow: inset 0 0 0 .5px rgba(var(--vs-mega-menu-ink), .06);\n}\n.vs-mega-menu-art i { position: absolute; display: block; transition: transform .62s var(--vs-mega-menu-spring); }\n.vs-mega-menu-art::after { content: \"\"; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;\n  background: radial-gradient(120% 90% at 50% 0%, rgba(255,255,255,.55), transparent 60%); mix-blend-mode: soft-light; }\n:is(.vs-mega-menu-col, .vs-mega-menu-card, .vs-mega-menu-tile):is(:hover, :focus-within) .vs-mega-menu-art { --on: 1; }\n/* stack: three sheets that fan out */\n.vs-mega-menu-art--stack i { left: 30%; top: 20%; width: 40%; height: 60%; border-radius: .55em;\n  background: linear-gradient(155deg, var(--lt), var(--a)); box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 .5em 1em -.4em color-mix(in srgb, var(--a) 70%, transparent); }\n.vs-mega-menu-art--stack i:nth-child(1) { opacity: .38; transform: translate(-22%, 5%) rotate(-9deg); }\n.vs-mega-menu-art--stack i:nth-child(2) { opacity: .66; transform: translate(-4%, 1%) rotate(-3deg); }\n.vs-mega-menu-art--stack i:nth-child(3) { transform: translate(14%, -4%) rotate(5deg); }\n.vs-mega-menu-art--stack i:nth-child(3)::before { content: \"\"; position: absolute; left: 14%; right: 30%; top: 18%; height: .3em; border-radius: 1em; background: rgba(255,255,255,.7); box-shadow: 0 .6em 0 rgba(255,255,255,.4), 0 1.2em 0 -.02em rgba(255,255,255,.3); }\n.vs-mega-menu-col:is(:hover, :focus-within) .vs-mega-menu-art--stack i:nth-child(1) { transform: translate(-58%, 12%) rotate(-16deg); }\n.vs-mega-menu-col:is(:hover, :focus-within) .vs-mega-menu-art--stack i:nth-child(2) { transform: translate(-10%, -4%) rotate(-2deg); transition-delay: 30ms; }\n.vs-mega-menu-col:is(:hover, :focus-within) .vs-mega-menu-art--stack i:nth-child(3) { transform: translate(48%, -10%) rotate(11deg); transition-delay: 60ms; }\n/* orbit: a body with two rings; hover sends the satellites round */\n.vs-mega-menu-art--orbit i { left: 50%; top: 50%; border-radius: 50%; }\n.vs-mega-menu-art--orbit i:nth-child(1) { width: 5.5em; height: 5.5em; margin: -2.75em; border: 1px solid color-mix(in srgb, var(--a) 40%, transparent); }\n.vs-mega-menu-art--orbit i:nth-child(2) { width: 9.5em; height: 9.5em; margin: -4.75em; border: 1px dashed color-mix(in srgb, var(--a) 30%, transparent); transform: rotate(-68deg); }\n.vs-mega-menu-art--orbit i:nth-child(1)::after, .vs-mega-menu-art--orbit i:nth-child(2)::after {\n  content: \"\"; position: absolute; left: 50%; top: -.3em; width: .6em; height: .6em; margin-left: -.3em; border-radius: 50%;\n  background: var(--a); box-shadow: 0 0 0 .25em color-mix(in srgb, var(--a) 18%, transparent);\n}\n.vs-mega-menu-art--orbit i:nth-child(2)::after { width: .45em; height: .45em; top: -.225em; margin-left: -.225em; background: var(--lt); box-shadow: 0 0 0 1px var(--a); }\n.vs-mega-menu-art--orbit i:nth-child(3) { width: 2.4em; height: 2.4em; margin: -1.2em;\n  background: radial-gradient(circle at 34% 30%, #fff 0, var(--lt) 22%, var(--a) 70%); box-shadow: 0 .4em 1.2em -.2em color-mix(in srgb, var(--a) 70%, transparent); }\n.vs-mega-menu-col:is(:hover, :focus-within) .vs-mega-menu-art--orbit i:nth-child(1) { transform: rotate(150deg); }\n.vs-mega-menu-col:is(:hover, :focus-within) .vs-mega-menu-art--orbit i:nth-child(2) { transform: rotate(-112deg); }\n.vs-mega-menu-col:is(:hover, :focus-within) .vs-mega-menu-art--orbit i:nth-child(3) { transform: scale(1.12); }\n/* bars: a live chart that re-draws */\n.vs-mega-menu-art--bars { background: linear-gradient(transparent calc(78% - .5px), rgba(var(--vs-mega-menu-ink), .12) calc(78% - .5px) 78%, transparent 78%), var(--art); }\n.vs-mega-menu-art--bars i { bottom: 22%; width: 7%; height: 58%; border-radius: .3em .3em .1em .1em; transform-origin: 50% 100%;\n  background: linear-gradient(0deg, var(--a), var(--lt)); transform: scaleY(var(--s)); }\n.vs-mega-menu-art--bars i:nth-child(1) { left: 15%; --s: .34; --t: .62; }\n.vs-mega-menu-art--bars i:nth-child(2) { left: 25%; --s: .58; --t: .4; }\n.vs-mega-menu-art--bars i:nth-child(3) { left: 35%; --s: .44; --t: .86; }\n.vs-mega-menu-art--bars i:nth-child(4) { left: 45%; --s: .78; --t: .52; }\n.vs-mega-menu-art--bars i:nth-child(5) { left: 55%; --s: .52; --t: 1; }\n.vs-mega-menu-art--bars i:nth-child(6) { left: 65%; --s: .94; --t: .66; }\n.vs-mega-menu-art--bars i:nth-child(7) { left: 75%; --s: .7; --t: .9; opacity: .55; }\n.vs-mega-menu-col:is(:hover, :focus-within) .vs-mega-menu-art--bars i { transform: scaleY(var(--t)); }\n.vs-mega-menu-art--bars i:nth-child(2) { transition-delay: 20ms } .vs-mega-menu-art--bars i:nth-child(3) { transition-delay: 40ms }\n.vs-mega-menu-art--bars i:nth-child(4) { transition-delay: 60ms } .vs-mega-menu-art--bars i:nth-child(5) { transition-delay: 80ms }\n.vs-mega-menu-art--bars i:nth-child(6) { transition-delay: 100ms } .vs-mega-menu-art--bars i:nth-child(7) { transition-delay: 120ms }\n/* sun: a striped disc on a horizon that rises */\n.vs-mega-menu-art--sun { background: linear-gradient(180deg, var(--art), color-mix(in srgb, var(--a) 22%, var(--vs-mega-menu-bg))); }\n.vs-mega-menu-art--sun i:nth-child(1) { left: 50%; bottom: -3.2em; width: 8em; height: 8em; margin-left: -4em; border-radius: 50%;\n  background: radial-gradient(circle at 50% 30%, var(--lt) 0, var(--a) 62%, color-mix(in srgb, var(--a) 70%, #000) 100%);\n  box-shadow: 0 0 3em color-mix(in srgb, var(--a) 45%, transparent); }\n.vs-mega-menu-art--sun i:nth-child(2) { left: 0; right: 0; bottom: 0; height: 46%;\n  background: repeating-linear-gradient(180deg, transparent 0 .55em, color-mix(in srgb, var(--a) 22%, var(--vs-mega-menu-bg)) .55em .8em); }\n.vs-mega-menu-card:is(:hover, :focus-visible) .vs-mega-menu-art--sun i:nth-child(1) { transform: translateY(-1.1em) scale(1.04); }\n.vs-mega-menu-card:is(:hover, :focus-visible) .vs-mega-menu-art--sun i:nth-child(2) { transform: translateY(.35em); }\n/* grid: cells on a lattice; one moves */\n.vs-mega-menu-art--grid { background-image: linear-gradient(color-mix(in srgb, var(--a) 16%, transparent) 1px, transparent 1px), linear-gradient(90deg, color-mix(in srgb, var(--a) 16%, transparent) 1px, transparent 1px); background-size: .9375em .9375em; background-position: -1px -1px; }\n.vs-mega-menu-art--grid i { width: .9375em; height: .9375em; background: var(--a); border-radius: 2px; }\n.vs-mega-menu-art--grid i:nth-child(1) { left: .9375em; top: .9375em; }\n.vs-mega-menu-art--grid i:nth-child(2) { left: 1.875em; top: 1.875em; opacity: .5; }\n.vs-mega-menu-art--grid i:nth-child(3) { left: .9375em; top: 1.875em; opacity: .25; }\n.vs-mega-menu-tile:is(:hover, :focus-visible) .vs-mega-menu-art--grid i:nth-child(1) { transform: translate(.9375em, 0); }\n.vs-mega-menu-tile:is(:hover, :focus-visible) .vs-mega-menu-art--grid i:nth-child(2) { transform: translate(0, -.9375em); }\n/* arcs: rings from a corner, a ripple */\n.vs-mega-menu-art--arcs i { left: 0; bottom: 0; border-radius: 50%; border: 2px solid var(--a); transform: translate(-50%, 50%); }\n.vs-mega-menu-art--arcs i:nth-child(1) { width: 2.2em; height: 2.2em; background: var(--a); }\n.vs-mega-menu-art--arcs i:nth-child(2) { width: 4.2em; height: 4.2em; opacity: .55; }\n.vs-mega-menu-art--arcs i:nth-child(3) { width: 6.2em; height: 6.2em; opacity: .25; }\n.vs-mega-menu-tile:is(:hover, :focus-visible) .vs-mega-menu-art--arcs i { transform: translate(-50%, 50%) scale(1.18); }\n.vs-mega-menu-tile:is(:hover, :focus-visible) .vs-mega-menu-art--arcs i:nth-child(2) { transition-delay: 40ms; }\n.vs-mega-menu-tile:is(:hover, :focus-visible) .vs-mega-menu-art--arcs i:nth-child(3) { transition-delay: 80ms; }\n/* tiles: four blocks that shuffle */\n.vs-mega-menu-art--tiles i { width: 1.2em; height: 1.2em; border-radius: .3em; background: var(--a); left: .6em; top: .6em; }\n.vs-mega-menu-art--tiles i:nth-child(2) { transform: translate(1.35em, 0); opacity: .4; }\n.vs-mega-menu-art--tiles i:nth-child(3) { transform: translate(0, 1.35em); opacity: .6; }\n.vs-mega-menu-art--tiles i:nth-child(4) { transform: translate(1.35em, 1.35em); background: var(--lt); }\n.vs-mega-menu-tile:is(:hover, :focus-visible) .vs-mega-menu-art--tiles i:nth-child(1) { transform: translate(1.35em, 0); }\n.vs-mega-menu-tile:is(:hover, :focus-visible) .vs-mega-menu-art--tiles i:nth-child(2) { transform: translate(1.35em, 1.35em); }\n.vs-mega-menu-tile:is(:hover, :focus-visible) .vs-mega-menu-art--tiles i:nth-child(3) { transform: translate(0, 0); }\n.vs-mega-menu-tile:is(:hover, :focus-visible) .vs-mega-menu-art--tiles i:nth-child(4) { transform: translate(0, 1.35em); }\n/* dial: a clock face whose hand sweeps */\n.vs-mega-menu-art--dial i:nth-child(1) { inset: .55em; border-radius: 50%; border: 1.5px solid color-mix(in srgb, var(--a) 55%, transparent);\n  background: radial-gradient(circle, var(--a) 0 .16em, transparent .17em); }\n.vs-mega-menu-art--dial i:nth-child(2) { left: 50%; top: 50%; width: 1.5px; height: 1.05em; margin-left: -.75px; background: var(--a); border-radius: 1px; transform-origin: 50% 0; transform: rotate(210deg); }\n.vs-mega-menu-tile:is(:hover, :focus-visible) .vs-mega-menu-art--dial i:nth-child(2) { transform: rotate(330deg); }\n/* ---------- small screens: panels become the bar's width, columns stack ---------- */\n@media (max-width: 640px) {\n  .vs-mega-menu-end { display: none; }\n  .vs-mega-menu-trigger, .vs-mega-menu-top { padding-inline: .7em; }\n  .vs-mega-menu-page { width: var(--vs-mega-menu-avail, calc(100vw - 24px)); padding: .75em; }\n  .vs-mega-menu-cols { flex-wrap: wrap; gap: .25em; }\n  .vs-mega-menu-col { width: 100%; display: grid; grid-template-columns: 4.5em 1fr; column-gap: .5em; align-items: start; }\n  .vs-mega-menu-col > .vs-mega-menu-art { grid-row: 1 / span 3; height: 7em; margin: .4em 0 0; font-size: .64em; width: 7em; }\n  .vs-mega-menu-col--list { width: calc(50% - .125em); display: flex; }\n  .vs-mega-menu-card { width: 100%; }\n  .vs-mega-menu-card .vs-mega-menu-art { height: 5.5em; }\n  .vs-mega-menu-tiles { grid-template-columns: 1fr; }\n  .vs-mega-menu-foot { margin-top: .25em; }\n}\n@media (max-width: 440px) { .vs-mega-menu-list > li[data-collapse=\"xs\"] { display: none; } }\n@media (prefers-reduced-motion: reduce) { .vs-mega-menu *, .vs-mega-menu *::after { transition-duration: 0s !important; transition-delay: 0s !important; } }\n@media (forced-colors: active) { .vs-mega-menu-fill { background: Canvas; } .vs-mega-menu-edge { background: CanvasText; } }\n</style>\n\n<script>\n(() => {\n  if (window.vsMegaMenu) return;\n  const reduce = matchMedia('(prefers-reduced-motion: reduce)');\n  const live = new Set(); let raf = 0, last = 0;\n  const tick = now => {\n    const dt = Math.min(.064, (now - last) / 1000 || .016); last = now;\n    for (const t of live) if (!t.update(dt)) live.delete(t);\n    raf = live.size ? requestAnimationFrame(tick) : 0;\n  };\n  const wake = t => { live.add(t); if (!raf) { last = performance.now(); raf = requestAnimationFrame(tick); } };\n  /* semi-implicit Euler spring at 120 Hz substeps; e = settle epsilon */\n  const sp = (x, k, c, e = .05) => ({ x, v: 0, g: x, k, c, e });\n  const run = (s, dt) => {\n    if (reduce.matches) { s.x = s.g; s.v = 0; return false; }\n    const n = Math.max(1, Math.ceil(dt * 120)), h = dt / n;\n    for (let i = 0; i < n; i++) { s.v += (-s.k * (s.x - s.g) - s.c * s.v) * h; s.x += s.v * h; }\n    if (Math.abs(s.v) < s.e && Math.abs(s.x - s.g) < s.e) { s.x = s.g; s.v = 0; return false; }\n    return true;\n  };\n  const snap = (s, v) => { s.x = s.g = v; s.v = 0; };\n  const clamp = (v, a, b) => Math.min(b, Math.max(a, v));\n  const FOCUSABLE = 'a[href], button:not([disabled]), input, select, textarea, [tabindex]:not([tabindex=\"-1\"])';\n  let uid = 0;\n\n  function mount(nav) {\n    if (nav.__vsMm) return nav.__vsMm;\n    const bar = nav.querySelector('.vs-mega-menu-bar'), list = nav.querySelector('.vs-mega-menu-list');\n    if (!bar || !list) return null;\n    const mk = (c, t = 'div') => { const e = document.createElement(t); e.className = c; return e; };\n    const hl = mk('vs-mega-menu-hl', 'span'), vp = mk('vs-mega-menu-viewport'), frame = mk('vs-mega-menu-frame');\n    const edge = mk('vs-mega-menu-edge', 'span'), fill = mk('vs-mega-menu-fill', 'span'), caret = mk('vs-mega-menu-caret', 'span');\n    const clip = mk('vs-mega-menu-clip'), bridge = mk('vs-mega-menu-bridge', 'span');\n    [hl, edge, fill, caret, bridge].forEach(e => e.setAttribute('aria-hidden', 'true'));\n    bar.prepend(hl); frame.append(edge, fill, caret, clip); vp.append(bridge, frame); nav.append(vp);\n    const id = 'vs-mega-menu-' + (++uid);\n    const items = [];\n    list.querySelectorAll(':scope > li').forEach(li => {\n      const trig = li.querySelector(':scope > .vs-mega-menu-trigger'), page = li.querySelector(':scope > .vs-mega-menu-content');\n      if (!trig || !page) return;\n      page.classList.add('vs-mega-menu-page'); if (!page.id) page.id = id + '-' + items.length;\n      clip.append(page); page.inert = true; page.style.visibility = 'hidden';\n      trig.setAttribute('aria-expanded', 'false'); trig.setAttribute('aria-controls', page.id);\n      trig.insertAdjacentHTML('beforeend', '<svg class=\"vs-mega-menu-chev\" viewBox=\"0 0 12 12\" aria-hidden=\"true\"><path d=\"M3 4.6 6 7.6l3-3\"/></svg>');\n      items.push({ trig, page, w: 0, h: 0, o: sp(0, 420, 40, .002), x: sp(0, 300, 32, .1) });\n    });\n    const tops = [...bar.querySelectorAll('.vs-mega-menu-trigger, .vs-mega-menu-top, .vs-mega-menu-cta')];\n    const F = { x: sp(0, 360, 34), w: sp(0, 360, 34), h: sp(0, 360, 34), c: sp(0, 560, 40), o: sp(0, 420, 34, .002),\n      hl: sp(0, 520, 38), hr: sp(0, 520, 38), ho: sp(0, 400, 36, .002) };\n    let cur = -1, hot = null, Wm = 0, Hm = 0, R = 18, tOpen = 0, tClose = 0, ptr = 'mouse';\n    const mode = () => nav.dataset.open === 'click' ? 'click' : 'hover';\n    const visible = el => el.offsetParent !== null;\n\n    function measure() {\n      const narrow = innerWidth <= 640;\n      nav.style.setProperty('--vs-mega-menu-avail', (narrow ? bar.offsetWidth : innerWidth - 24) + 'px');\n      Wm = Hm = 0;\n      for (const it of items) { it.w = it.page.offsetWidth; it.h = it.page.offsetHeight; Wm = Math.max(Wm, it.w); Hm = Math.max(Hm, it.h); }\n      frame.style.width = Wm + 'px'; frame.style.height = Hm + 'px';\n      R = parseFloat(getComputedStyle(nav).getPropertyValue('--vs-mega-menu-radius')) || 18;\n    }\n    function target(i) {\n      const it = items[i], nr = nav.getBoundingClientRect(), tr = it.trig.getBoundingClientRect(), br = bar.getBoundingClientRect();\n      const tc = tr.left + tr.width / 2 - nr.left, bl = br.left - nr.left, bw = br.width, w = it.w;\n      let x = w <= bw ? clamp(tc - w / 2, bl, bl + bw - w) : bl + (bw - w) / 2;\n      x = clamp(x, 12 - nr.left, innerWidth - 12 - nr.left - w);\n      return { x, w, h: it.h, c: clamp(tc - x, R + 14, w - R - 14) };\n    }\n    function aimHl(el) {\n      if (!el || !visible(el)) { F.ho.g = 0; wake(api); return; }\n      const l = el.offsetLeft + (el.offsetParent === bar ? 0 : el.offsetParent.offsetLeft), r = l + el.offsetWidth;\n      if (F.ho.x < .08) { snap(F.hl, l); snap(F.hr, r); } else { F.hl.g = l; F.hr.g = r; }\n      F.ho.g = 1; wake(api);\n    }\n    const restHl = () => aimHl(hot || (cur >= 0 ? items[cur].trig : null));\n\n    function open(i, { focus = false } = {}) {\n      clearTimeout(tOpen); clearTimeout(tClose);\n      if (i < 0 || i >= items.length) return;\n      const it = items[i];\n      if (i !== cur) {\n        const prev = cur; cur = i;\n        const T = target(i), fresh = prev < 0 || F.o.x < .2;\n        if (fresh) {\n          snap(F.x, T.x); snap(F.w, T.w); snap(F.h, T.h); snap(F.c, T.c);\n          items.forEach(o => { snap(o.o, 0); snap(o.x, 0); });\n          snap(it.o, 1);\n        } else {\n          F.x.g = T.x; F.w.g = T.w; F.h.g = T.h; F.c.g = T.c;\n          const dir = Math.sign(i - prev) || 1;\n          // the page leaving fades fast, the arriving one settles slower: no muddy double exposure\n          items.forEach((o, j) => { if (j !== i) { o.o.g = 0; o.o.k = 1100; o.o.c = 66; o.x.g = -dir * 30; } });\n          if (it.o.x < .05) snap(it.x, dir * 36);\n          it.o.g = 1; it.o.k = 240; it.o.c = 30; it.x.g = 0;\n        }\n        F.o.g = 1;\n        items.forEach((o, j) => { o.trig.setAttribute('aria-expanded', String(j === i)); o.page.inert = j !== i; });\n        nav.classList.add('is-open');\n        nav.dispatchEvent(new CustomEvent('megaopen', { bubbles: true, detail: { index: i } }));\n        restHl(); wake(api);\n      }\n      if (focus) { it.page.style.visibility = 'visible'; const f = it.page.querySelector(FOCUSABLE); f && f.focus({ preventScroll: true }); }\n    }\n    function close() {\n      clearTimeout(tOpen); clearTimeout(tClose);\n      if (cur < 0) return;\n      cur = -1; F.o.g = 0;\n      items.forEach(o => { o.trig.setAttribute('aria-expanded', 'false'); o.page.inert = true; });\n      nav.classList.remove('is-open');\n      nav.dispatchEvent(new CustomEvent('megaclose', { bubbles: true }));\n      restHl(); wake(api);\n    }\n\n    const api = {\n      open: i => open(i), close,\n      update(dt) {\n        let moving = false;\n        for (const k in F) if (run(F[k], dt)) moving = true;\n        for (const it of items) { if (run(it.o, dt)) moving = true; if (run(it.x, dt)) moving = true; }\n        const w = F.w.x, h = F.h.x, o = clamp(F.o.x, 0, 1), hw = devicePixelRatio >= 2 ? .5 : 1;\n        const ri = Wm - w, bi = Hm - h;\n        edge.style.clipPath = `inset(0 ${ri.toFixed(2)}px ${bi.toFixed(2)}px 0 round ${R}px)`;\n        clip.style.clipPath = fill.style.clipPath = `inset(${hw}px ${(ri + hw).toFixed(2)}px ${(bi + hw).toFixed(2)}px ${hw}px round ${Math.max(0, R - hw)}px)`;\n        caret.style.transform = `translate3d(${F.c.x.toFixed(2)}px,0,0) rotate(45deg)`;\n        frame.style.transformOrigin = `${F.c.x.toFixed(1)}px 0`;\n        frame.style.transform = `translate3d(${F.x.x.toFixed(2)}px,${(-10 * (1 - o)).toFixed(2)}px,0) scale(${(.965 + .035 * o).toFixed(4)})`;\n        frame.style.opacity = o.toFixed(3);\n        bridge.style.transform = `translate3d(${F.x.x.toFixed(2)}px,0,0) scaleX(${(w / 100).toFixed(4)})`;\n        vp.style.visibility = o < .005 && cur < 0 ? 'hidden' : 'visible';\n        for (const it of items) {\n          const po = clamp(it.o.x, 0, 1);\n          it.page.style.opacity = po.toFixed(3);\n          it.page.style.transform = `translate3d(${it.x.x.toFixed(2)}px,0,0)`;\n          it.page.style.visibility = po < .01 ? 'hidden' : 'visible';\n        }\n        hl.style.clipPath = `inset(.375em ${(bar.offsetWidth - F.hr.x).toFixed(2)}px .375em ${F.hl.x.toFixed(2)}px round ${(R * .55 + 2).toFixed(1)}px)`;\n        hl.style.opacity = clamp(F.ho.x, 0, 1).toFixed(3);\n        return moving;\n      },\n    };\n\n    /* pointer */\n    nav.addEventListener('pointerdown', e => { ptr = e.pointerType; }, true);\n    items.forEach((it, i) => {\n      it.trig.addEventListener('pointerenter', e => {\n        if (e.pointerType !== 'mouse' || mode() !== 'hover') return;\n        clearTimeout(tClose); clearTimeout(tOpen);\n        tOpen = setTimeout(() => open(i), cur < 0 ? 70 : 20);\n      });\n      it.trig.addEventListener('pointerleave', () => clearTimeout(tOpen));\n      it.trig.addEventListener('click', e => {\n        const mouseHover = mode() === 'hover' && e.detail > 0 && ptr === 'mouse';\n        if (mouseHover) { open(i); return; }                 // in hover mode a click never slams it shut\n        cur === i ? close() : open(i);\n      });\n    });\n    bar.addEventListener('pointerover', e => {\n      const t = e.target.closest('.vs-mega-menu-trigger, .vs-mega-menu-top, .vs-mega-menu-cta');\n      if (e.pointerType !== 'mouse') return;\n      hot = t; restHl();\n      if (t && !t.classList.contains('vs-mega-menu-trigger') && mode() === 'hover' && cur >= 0) { clearTimeout(tClose); tClose = setTimeout(close, 90); }\n    });\n    bar.addEventListener('pointerleave', () => { hot = null; restHl(); });\n    nav.addEventListener('pointerenter', () => { if (cur >= 0) clearTimeout(tClose); });\n    nav.addEventListener('pointerleave', e => { if (e.pointerType === 'mouse' && mode() === 'hover' && cur >= 0) { clearTimeout(tClose); tClose = setTimeout(close, 260); } });\n    vp.addEventListener('pointerenter', () => clearTimeout(tClose));\n    document.addEventListener('pointerdown', e => { if (cur >= 0 && !nav.contains(e.target)) close(); });\n\n    /* keyboard */\n    const inPage = () => cur >= 0 ? [...items[cur].page.querySelectorAll(FOCUSABLE)] : [];\n    const topVisible = () => tops.filter(visible);\n    nav.addEventListener('keydown', e => {\n      const a = document.activeElement, T = topVisible(), ti = T.indexOf(a), ii = items.findIndex(it => it.trig === a);\n      if (e.key === 'Escape' && cur >= 0) { const t = items[cur].trig; close(); t.focus(); e.preventDefault(); return; }\n      if (ti >= 0) {\n        if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {\n          e.preventDefault();\n          const n = T[(ti + (e.key === 'ArrowRight' ? 1 : -1) + T.length) % T.length]; n.focus();\n          const j = items.findIndex(it => it.trig === n);\n          if (cur >= 0) j >= 0 ? open(j) : close();\n          return;\n        }\n        if (ii >= 0 && e.key === 'ArrowDown') { e.preventDefault(); open(ii, { focus: true }); return; }\n        if (ii >= 0 && e.key === 'Tab' && !e.shiftKey && cur === ii) { const f = inPage()[0]; if (f) { e.preventDefault(); f.focus(); } return; }\n        return;\n      }\n      const P = inPage(), pi = P.indexOf(a);\n      if (pi < 0) return;\n      if (e.key === 'ArrowDown' || e.key === 'ArrowUp') { e.preventDefault(); P[clamp(pi + (e.key === 'ArrowDown' ? 1 : -1), 0, P.length - 1)].focus(); return; }\n      if (e.key === 'Tab') {\n        const t = items[cur].trig;\n        if (e.shiftKey && pi === 0) { e.preventDefault(); t.focus(); }\n        else if (!e.shiftKey && pi === P.length - 1) { e.preventDefault(); const n = T[T.indexOf(t) + 1]; close(); (n || t).focus(); }\n      }\n    });\n    nav.addEventListener('focusin', e => { const t = e.target.closest('.vs-mega-menu-trigger, .vs-mega-menu-top, .vs-mega-menu-cta'); if (t && t.matches(':focus-visible')) { hot = t; restHl(); } });\n    nav.addEventListener('focusout', () => setTimeout(() => { if (!nav.contains(document.activeElement)) { hot = null; if (ptr !== 'mouse' || mode() === 'click' || !nav.matches(':hover')) close(); restHl(); } }));\n\n    const refit = () => {\n      measure();\n      if (cur >= 0) { const T = target(cur); F.x.g = T.x; F.w.g = T.w; F.h.g = T.h; F.c.g = T.c; if (!live.has(api)) { snap(F.x, T.x); snap(F.w, T.w); snap(F.h, T.h); snap(F.c, T.c); } }\n      wake(api);\n    };\n    const ro = new ResizeObserver(refit); items.forEach(it => ro.observe(it.page)); ro.observe(bar);\n    addEventListener('resize', refit);\n    document.fonts && document.fonts.ready.then(refit);\n    measure(); api.update(0);\n    nav.__vsMm = api;\n    return api;\n  }\n  const init = () => document.querySelectorAll('.vs-mega-menu').forEach(mount);\n  document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', init) : init();\n  window.vsMegaMenu = { mount };\n})();\n</script>\n"
    }
  ],
  "meta": {
    "category": "ui",
    "group": "Navigation",
    "tags": [
      "nav",
      "navbar",
      "mega menu",
      "dropdown",
      "morph",
      "spring",
      "hover",
      "accessibility"
    ],
    "tech": [
      "CSS",
      "JS"
    ],
    "deps": [],
    "source": null,
    "free": true,
    "accent": "#2f5bff",
    "added": "2026-10-01",
    "demo": "https://vividsites.app/api/component/mega-menu/index.html",
    "thumbnail": "https://vividsites.app/api/component/mega-menu/thumb.jpg",
    "video": "https://vividsites.app/api/component/mega-menu/thumb.mp4",
    "page": "https://vividsites.app/c/mega-menu"
  }
}