# Navigation menu

A site header's links, where an item with a caret opens a wide panel of described links and a featured column.

Block: `smbk-navigation-menu`. Status: proposed. Figma: the Figma file, https://www.figma.com/community/file/1688324308358870630. Desktop and mobile: differ by presentation only.

## Options

| Axis | Values | Default | Meaning |
|---|---|---|---|
| `align` | `start`, `end` | `start` | Which edge of the row the open panel lines up with: start for links at the start of a header, end for links at its end, so the panel stays on the page. |

Parts: `smbk-navigation-menu__list`, `smbk-navigation-menu__item`, `smbk-navigation-menu__trigger`, `smbk-navigation-menu__panel`, `smbk-navigation-menu__column`, `smbk-navigation-menu__heading`, `smbk-navigation-menu__links`, `smbk-navigation-menu__link`, `smbk-navigation-menu__link-icon`, `smbk-navigation-menu__link-text`, `smbk-navigation-menu__link-title`, `smbk-navigation-menu__link-description`, `smbk-navigation-menu__featured`, `smbk-navigation-menu__featured-text`, `smbk-navigation-menu__featured-title`, `smbk-navigation-menu__featured-description`, `smbk-navigation-menu__featured-link`

## Markup

```html
<nav class="smbk-navigation-menu smbk-navigation-menu--align-start" aria-label="Main, configure">
  <ul class="smbk-navigation-menu__list">
    <li class="smbk-navigation-menu__item"><button type="button" class="smbk-nav-item smbk-nav-item--size-md smbk-navigation-menu__trigger" aria-expanded="true" aria-controls="navigation-menu-1-panel-0"><span class="smbk-nav-item__label" data-label="Product">Product</span><i class="ph ph-caret-down smbk-icon smbk-icon--size-md smbk-nav-item__caret" aria-hidden="true"></i></button><div id="navigation-menu-1-panel-0" class="smbk-navigation-menu__panel"><div class="smbk-navigation-menu__column"><p id="navigation-menu-1-panel-0-heading-0" class="smbk-navigation-menu__heading">Build</p><ul class="smbk-navigation-menu__links" aria-labelledby="navigation-menu-1-panel-0-heading-0"><li><a class="smbk-navigation-menu__link" href="#components"><i class="ph ph-squares-four smbk-icon smbk-icon--size-md smbk-navigation-menu__link-icon" aria-hidden="true"></i><span class="smbk-navigation-menu__link-text"><span class="smbk-navigation-menu__link-title">Components</span><span class="smbk-navigation-menu__link-description">Seventy parts, each with its states and sizes.</span></span></a></li><li><a class="smbk-navigation-menu__link" href="#tokens"><i class="ph ph-diamonds-four smbk-icon smbk-icon--size-md smbk-navigation-menu__link-icon" aria-hidden="true"></i><span class="smbk-navigation-menu__link-text"><span class="smbk-navigation-menu__link-title">Tokens</span><span class="smbk-navigation-menu__link-description">Color, space and type as named values.</span></span></a></li><li><a class="smbk-navigation-menu__link" href="#icons"><i class="ph ph-star smbk-icon smbk-icon--size-md smbk-navigation-menu__link-icon" aria-hidden="true"></i><span class="smbk-navigation-menu__link-text"><span class="smbk-navigation-menu__link-title">Icons</span><span class="smbk-navigation-menu__link-description">One icon set, drawn on one grid.</span></span></a></li></ul></div><div class="smbk-navigation-menu__column"><p id="navigation-menu-1-panel-0-heading-1" class="smbk-navigation-menu__heading">Learn</p><ul class="smbk-navigation-menu__links" aria-labelledby="navigation-menu-1-panel-0-heading-1"><li><a class="smbk-navigation-menu__link" href="#start"><i class="ph ph-rocket-launch smbk-icon smbk-icon--size-md smbk-navigation-menu__link-icon" aria-hidden="true"></i><span class="smbk-navigation-menu__link-text"><span class="smbk-navigation-menu__link-title">Getting started</span><span class="smbk-navigation-menu__link-description">Install, link the stylesheet, build a page.</span></span></a></li><li><a class="smbk-navigation-menu__link" href="#naming"><i class="ph ph-book smbk-icon smbk-icon--size-md smbk-navigation-menu__link-icon" aria-hidden="true"></i><span class="smbk-navigation-menu__link-text"><span class="smbk-navigation-menu__link-title">Naming</span><span class="smbk-navigation-menu__link-description">How every class and token gets its name.</span></span></a></li><li><a class="smbk-navigation-menu__link" href="#notes"><i class="ph ph-article smbk-icon smbk-icon--size-md smbk-navigation-menu__link-icon" aria-hidden="true"></i><span class="smbk-navigation-menu__link-text"><span class="smbk-navigation-menu__link-title">Release notes</span><span class="smbk-navigation-menu__link-description">What changed in each version.</span></span></a></li></ul></div><div class="smbk-navigation-menu__featured"><span class="smbk-image-placeholder" aria-hidden="true" style="aspect-ratio:9 / 4"></span><div class="smbk-navigation-menu__featured-text"><p id="navigation-menu-1-panel-0-featured" class="smbk-navigation-menu__featured-title">New in version 2.4</p><p class="smbk-navigation-menu__featured-description">The board, the stat strip and the price card.</p></div><a class="smbk-link smbk-link--size-sm smbk-link--standalone smbk-navigation-menu__featured-link" href="#new" aria-describedby="navigation-menu-1-panel-0-featured"><span class="smbk-link__label">Read the notes</span><i class="ph ph-arrow-right smbk-icon smbk-icon--size-md smbk-link__icon" aria-hidden="true"></i></a></div></div></li>
    <li class="smbk-navigation-menu__item"><button type="button" class="smbk-nav-item smbk-nav-item--size-md smbk-navigation-menu__trigger" aria-expanded="false" aria-controls="navigation-menu-1-panel-1"><span class="smbk-nav-item__label" data-label="Resources">Resources</span><i class="ph ph-caret-down smbk-icon smbk-icon--size-md smbk-nav-item__caret" aria-hidden="true"></i></button><div id="navigation-menu-1-panel-1" class="smbk-navigation-menu__panel" hidden=""><div class="smbk-navigation-menu__column"><ul class="smbk-navigation-menu__links"><li><a class="smbk-navigation-menu__link" href="#figma"><i class="ph ph-figma-logo smbk-icon smbk-icon--size-md smbk-navigation-menu__link-icon" aria-hidden="true"></i><span class="smbk-navigation-menu__link-text"><span class="smbk-navigation-menu__link-title">Figma library</span><span class="smbk-navigation-menu__link-description">Every component, ready to drag in.</span></span></a></li><li><a class="smbk-navigation-menu__link" href="#templates"><i class="ph ph-layout smbk-icon smbk-icon--size-md smbk-navigation-menu__link-icon" aria-hidden="true"></i><span class="smbk-navigation-menu__link-text"><span class="smbk-navigation-menu__link-title">Templates</span><span class="smbk-navigation-menu__link-description">Dashboards and pages to start from.</span></span></a></li></ul></div></div></li>
    <li class="smbk-navigation-menu__item"><a class="smbk-nav-item smbk-nav-item--size-md" href="#pricing"><span class="smbk-nav-item__label" data-label="Pricing">Pricing</span></a></li>
    <li class="smbk-navigation-menu__item"><a class="smbk-nav-item smbk-nav-item--size-md" href="#changelog"><span class="smbk-nav-item__label" data-label="Changelog">Changelog</span></a></li>
  </ul>
</nav>
```

## React

```tsx
import { NavigationMenu } from './design-system/components/navigation-menu/navigation-menu.js';

<NavigationMenu aria-label="Main, configure" align="start" items={[{ label: "Product", columns: [{ heading: "Build", links: [{ title: "Components", description: "Seventy parts, each with its states and sizes.", href: "#components", icon: "SquaresFour" }, { title: "Tokens", description: "Color, space and type as named values.", href: "#tokens", icon: "DiamondsFour" }, { title: "Icons", description: "One icon set, drawn on one grid.", href: "#icons", icon: "Star" }] }, { heading: "Learn", links: [{ title: "Getting started", description: "Install, link the stylesheet, build a page.", href: "#start", icon: "RocketLaunch" }, { title: "Naming", description: "How every class and token gets its name.", href: "#naming", icon: "Book" }, { title: "Release notes", description: "What changed in each version.", href: "#notes", icon: "Article" }] }], featured: { title: "New in version 2.4", description: "The board, the stat strip and the price card.", href: "#new", linkLabel: "Read the notes" } }, { label: "Resources", columns: [{ links: [{ title: "Figma library", description: "Every component, ready to drag in.", href: "#figma", icon: "FigmaLogo" }, { title: "Templates", description: "Dashboards and pages to start from.", href: "#templates", icon: "Layout" }] }] }, { label: "Pricing", href: "#pricing" }, { label: "Changelog", href: "#changelog" }]} defaultOpen="Product" />
```

## Stylesheet

```css
/* smbk-navigation-menu — Navigation menu. Figma "NavigationMenu" 8217:3602 (State: Closed, Open) and
 * "NavigationLink" 8217:3405 (State: Default, Hover, Focus).
 * A site header's links: a row of navigation items at the medium size; an item with a caret opens a wide panel under
 * the row, holding columns of links (each an icon, a title and a line of description) under small headings, and
 * an optional featured column with a picture, a title and a link. The items are the navigation item component; its
 * stylesheet draws them, the open one raised as hover raises it. The panel drops in and fades out with the floating
 * panels' motion (floating/floating.css names it). In a narrow space (the layout switch) the row stacks into a
 * list and each panel opens in place under its item, its columns one under another. */

.smbk-navigation-menu {
  position: relative;
  color: var(--smbk-color-text-default);
}

.smbk-navigation-menu__list {
  display: flex;
  align-items: center;
  gap: var(--smbk-space-inline-xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

.smbk-navigation-menu__item {
  display: block;
}

/* ---- the panel: under the row, lined up with its start edge (or its end edge, align end). In a wide space narrower
   than its columns, the columns that do not fit wrap under the others rather than leaving the window. ---- */

.smbk-navigation-menu__panel {
  box-sizing: border-box;
  position: absolute;
  top: calc(100% + var(--smbk-space-stack-xs));
  inset-inline-start: 0;
  z-index: var(--smbk-layer-overlay);
  display: flex;
  flex-wrap: wrap;
  gap: var(--smbk-space-inline-lg);
  width: max-content;
  max-width: calc(100vw - 2 * var(--smbk-space-inset-xl));
  padding: var(--smbk-space-inset-lg);
  border: var(--smbk-border-width-hairline) solid var(--smbk-color-border-rim);
  border-radius: var(--smbk-radius-container-md);
  background: var(--smbk-color-surface-overlay);
  box-shadow: var(--smbk-elevation-overlay);
  transform-origin: top;
}

.smbk-navigation-menu--align-end .smbk-navigation-menu__panel {
  inset-inline-start: auto;
  inset-inline-end: 0;
}

.smbk-navigation-menu__column {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* A column's heading: Label SM in the subtlest text, a row the medium mark's height, lined up with the links' text. */
.smbk-navigation-menu__heading {
  display: flex;
  align-items: center;
  min-height: var(--smbk-size-mark-lg);
  margin: 0;
  padding: 0 var(--smbk-space-inset-lg);
  color: var(--smbk-color-text-subtlest);
  font-family: var(--smbk-typography-label-sm-font-family);
  font-size: var(--smbk-typography-label-sm-font-size);
  font-weight: var(--smbk-typography-label-sm-font-weight);
  line-height: var(--smbk-typography-label-sm-line-height);
  letter-spacing: var(--smbk-typography-label-sm-letter-spacing);
}

.smbk-navigation-menu__links {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* ---- a link in the panel (Figma's NavigationLink): an icon, a title and a line of description ---- */

.smbk-navigation-menu__link {
  box-sizing: border-box;
  display: flex;
  align-items: flex-start;
  gap: var(--smbk-space-inline-md);
  width: var(--smbk-size-width-240);
  max-width: 100%;
  padding: var(--smbk-space-inset-lg);
  border-radius: var(--smbk-radius-control-md);
  color: var(--smbk-color-text-default);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

@media (hover: hover) {
  .smbk-navigation-menu__link:hover {
    background: var(--smbk-color-surface-hover);
  }
}

.smbk-navigation-menu__link:focus-visible {
  outline: var(--smbk-focus-ring-width) solid var(--smbk-color-border-focus);
  outline-offset: var(--smbk-focus-ring-offset);
  background: var(--smbk-color-surface-hover);
}

.smbk-navigation-menu__link-icon {
  flex-shrink: 0;
  color: var(--smbk-color-icon-subtle);
  font-size: var(--smbk-size-icon-md);
}

.smbk-navigation-menu__link-text,
.smbk-navigation-menu__featured-text {
  display: flex;
  flex-direction: column;
  gap: var(--smbk-space-text-label);
  min-width: 0;
}

.smbk-navigation-menu__link-title,
.smbk-navigation-menu__featured-title {
  margin: 0;
  color: var(--smbk-color-text-default);
  font-family: var(--smbk-typography-label-lg-font-family);
  font-size: var(--smbk-typography-label-lg-font-size);
  font-weight: var(--smbk-typography-label-lg-font-weight);
  line-height: var(--smbk-typography-label-lg-line-height);
  letter-spacing: var(--smbk-typography-label-lg-letter-spacing);
}

/* The current page's link sits on the selected surface. Figma draws no current link; Label LG has no bolder weight. */
.smbk-navigation-menu__link[aria-current="page"] {
  background: var(--smbk-color-surface-selected);
}

.smbk-navigation-menu__link-description,
.smbk-navigation-menu__featured-description {
  margin: 0;
  color: var(--smbk-color-text-subtle);
  font-family: var(--smbk-typography-body-sm-font-family);
  font-size: var(--smbk-typography-body-sm-font-size);
  font-weight: var(--smbk-typography-body-sm-font-weight);
  line-height: var(--smbk-typography-body-sm-line-height);
  letter-spacing: var(--smbk-typography-body-sm-letter-spacing);
}

/* ---- the featured column: a picture, a title, a line and a link, padded as a link is ---- */

.smbk-navigation-menu__featured {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--smbk-space-stack-sm);
  width: var(--smbk-size-width-240);
  max-width: 100%;
  padding: var(--smbk-space-inset-lg);
}

.smbk-navigation-menu__featured > :first-child {
  align-self: stretch;
}

/* ---- narrow: the row stacks, each item fills it with its caret at the far end, and a panel opens in place under
   its item, its columns and its featured column one under another, set in a step so they read as the item's. ---- */

@container style(--smbk-layout: narrow) {
  .smbk-navigation-menu__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
  }

  .smbk-navigation-menu__item > .smbk-nav-item {
    display: flex;
    width: 100%;
    justify-content: space-between;
  }

  .smbk-navigation-menu__panel,
  .smbk-navigation-menu--align-end .smbk-navigation-menu__panel {
    position: static;
    flex-direction: column;
    gap: var(--smbk-space-stack-sm);
    width: auto;
    max-width: none;
    padding: var(--smbk-space-stack-xs) 0 var(--smbk-space-stack-sm) var(--smbk-space-inset-lg);
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
  }

  .smbk-navigation-menu__link,
  .smbk-navigation-menu__featured {
    width: 100%;
  }
}

/* ---- touch: a link in the panel already passes the comfortable target. Stacked in a narrow space, the top items
   touch: where one item meets the next, each keeps its own edge, so each stays one press. Under an open panel an
   item is not touching another, so the nav item's own area reaches out there, as everywhere else. Nothing drawn
   moves. ---- */

@container style(--smbk-layout: narrow) {
  @media (pointer: coarse) {
    .smbk-navigation-menu__item:not(:has(> .smbk-navigation-menu__panel:not([hidden]))) + .smbk-navigation-menu__item > .smbk-nav-item::after {
      inset-block-start: 0;
    }

    .smbk-navigation-menu__item:has(+ .smbk-navigation-menu__item):not(:has(> .smbk-navigation-menu__panel:not([hidden]))) > .smbk-nav-item::after {
      inset-block-end: 0;
    }
  }
}

/* ---- high contrast (forced colors) ---- */
/* In Windows high-contrast mode the browser drops fills and shadows; this puts the meaning back with the
   user's own colors. Nothing here applies outside that mode. */

@media (forced-colors: active) {
  .smbk-navigation-menu__link[aria-current="page"] {
    outline: var(--smbk-border-width-hairline) solid Highlight;
  }
}
```

## Tokens it reads

```json
{
  "motion": {
    "enter": {
      "duration": {
        "$type": "duration",
        "$value": "{{duration.320}}"
      },
      "easing": {
        "$type": "cubicBezier",
        "$value": "{{easing.expo-out}}"
      }
    },
    "exit": {
      "duration": {
        "$type": "duration",
        "$value": "{{duration.200}}"
      },
      "easing": {
        "$type": "cubicBezier",
        "$value": "{{easing.expo-in}}"
      }
    }
  },
  "space": {
    "stack": {
      "xs": {
        "$type": "dimension",
        "$value": "{{space.4}}",
        "$description": "Gap between things stacked one above another, extra small."
      },
      "sm": {
        "$type": "dimension",
        "$value": "{{space.8}}",
        "$description": "Gap between things stacked one above another, small."
      }
    },
    "inline": {
      "xs": {
        "$type": "dimension",
        "$value": "{{space.4}}",
        "$description": "Gap between things side by side, extra small."
      },
      "lg": {
        "$type": "dimension",
        "$value": "{{space.12}}",
        "$description": "Gap between things side by side, large."
      },
      "md": {
        "$type": "dimension",
        "$value": "{{space.8}}",
        "$description": "Gap between things side by side, medium."
      }
    },
    "inset": {
      "xl": {
        "$type": "dimension",
        "$value": "{{space.16}}",
        "$description": "Padding inside a component, extra large."
      },
      "lg": {
        "$type": "dimension",
        "$value": "{{space.12}}",
        "$description": "Padding inside a component, large."
      }
    },
    "text": {
      "label": {
        "$type": "dimension",
        "$value": "{{space.0}}",
        "$description": "Between a label or title and the line of supporting text right under it, inside a component. None: untrimmed line height already spaces the two lines."
      }
    }
  },
  "color": {
    "text": {
      "default": {
        "$type": "color",
        "$value": "{{color.grey.900}}",
        "$description": "Main text."
      },
      "subtlest": {
        "$type": "color",
        "$value": "{{color.grey.600}}",
        "$description": "Quietest text: hints, captions, placeholders."
      },
      "subtle": {
        "$type": "color",
        "$value": "{{color.grey.700}}",
        "$description": "Secondary text: descriptions, metadata."
      }
    },
    "border": {
      "rim": {
        "$type": "color",
        "$value": "{{color.alpha.white.90}}",
        "$description": "The light rim that makes a surface look lit: fields, chosen pills, cards."
      },
      "focus": {
        "$type": "color",
        "$value": "{{color.red.600}}",
        "$description": "Keyboard focus ring on controls."
      }
    },
    "surface": {
      "overlay": {
        "$type": "color",
        "$value": "{{color.alpha.white.100}}",
        "$description": "Floating panels opened from a control: the dropdown and select list, the combobox list, the date picker and the popover. One step above surface/raised, so a menu opened in a modal, a drawer or on a card stands apart. Dialogs (modal, drawer, command palette) stay on surface/default. Not see-through (that is surface/translucent)."
      },
      "hover": {
        "$type": "color",
        "$value": "{{color.alpha.grey-800.15}}",
        "$description": "A row or option under the pointer or the keyboard highlight: menu options, table rows. Translucent, so it works on any surface."
      },
      "selected": {
        "$type": "color",
        "$value": "{{color.alpha.grey-800.10}}",
        "$description": "The current or chosen item, such as the current page in the sidebar. Translucent, so it shows by the same step on the default, raised, sunken and canvas surfaces."
      }
    },
    "icon": {
      "subtle": {
        "$type": "color",
        "$value": "{{color.grey.700}}",
        "$description": "Quiet icons."
      }
    }
  },
  "layer": {
    "overlay": {
      "$type": "number",
      "$value": 1200
    }
  },
  "border-width": {
    "hairline": {
      "$type": "dimension",
      "$value": "{{border-width.1}}",
      "$description": "Thin lines: dividers and almost every edge."
    }
  },
  "radius": {
    "container": {
      "md": {
        "$type": "dimension",
        "$value": "{{radius.12}}",
        "$description": "Corners of cards, panels and dialogs, medium."
      }
    },
    "control": {
      "md": {
        "$type": "dimension",
        "$value": "{{radius.6}}",
        "$description": "Corners of controls, medium."
      }
    }
  },
  "elevation": {
    "overlay": {
      "$type": "shadow",
      "$value": {
        "light": "0px 12px 16px 2px #373d431a, 0px 2px 8px 0px #373d4326",
        "dark": "0px 12px 16px 2px #00000026, 0px 2px 8px 0px #00000033"
      }
    }
  },
  "size": {
    "mark": {
      "lg": {
        "$type": "dimension",
        "$value": "{{size.24}}",
        "$description": "Small fixed marks inside components (dots, bars, keys), large."
      }
    },
    "width": {
      "240": {
        "$type": "dimension",
        "$value": "240px",
        "$description": "A fixed width of 240 px: a narrow column, a list’s greatest height. Semantic sizes point here."
      }
    },
    "icon": {
      "md": {
        "$type": "dimension",
        "$value": "{{size.20}}",
        "$description": "Icon box, medium."
      }
    }
  },
  "typography": {
    "label-sm": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Geist, Geist Fallback, system-ui, sans-serif",
        "fontSize": "12px",
        "fontWeight": 500,
        "lineHeight": 1.4,
        "letterSpacing": "0px"
      },
      "$description": "Label SM: labels on controls and short UI text (buttons, chips, tabs, menu headings). Geist Medium, sentence case. Code and keys use Code SM and Code MD."
    },
    "label-lg": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Geist, Geist Fallback, system-ui, sans-serif",
        "fontSize": "16px",
        "fontWeight": 500,
        "lineHeight": 1.4,
        "letterSpacing": "0px"
      },
      "$description": "Label LG: labels on controls and short UI text (buttons, chips, tabs, menu headings). Geist Medium, sentence case. Code and keys use Code SM and Code MD."
    },
    "body-sm": {
      "$type": "typography",
      "$value": {
        "fontFamily": "Geist, Geist Fallback, system-ui, sans-serif",
        "fontSize": "14px",
        "fontWeight": 400,
        "lineHeight": 1.5,
        "letterSpacing": "0px"
      }
    }
  },
  "focus": {
    "ring": {
      "width": {
        "$type": "dimension",
        "$value": "{{border-width.2}}",
        "$description": "Thickness of the focus ring."
      },
      "offset": {
        "$type": "dimension",
        "$value": "{{space.2}}",
        "$description": "Gap between a control and its focus ring."
      }
    }
  }
}
```

## Purpose

A site header's links, where an item with a caret opens a wide panel under the row: columns of links, each with an icon, a title and a line saying what is there, and an optional featured column with a picture and one link. It suits a site with more pages than a row can hold, grouped so a visitor can see what each section offers before going there. For a short list of links under one item, the header's own dropdown is enough.

## Anatomy

- The block, a navigation landmark, named "Main" unless given another name.
- The list part, the row of items.
- The item part, one entry in the row: a navigation item that links, or one with a caret, the trigger part, that opens its panel.
- The panel part, under the row, lined up with its start or end edge: on the overlay surface with the overlay shadow.
- The column part, one list of links under an optional heading part that names it.
- The link part, one link in a panel: the link icon, then the link title over the link description.
- The featured part, optional, at the panel's end: a picture, the featured title and description, and a link.

## When to use

- The main links of a marketing site or a documentation site, with sections that each hold several pages worth describing.
- A header where a visitor benefits from seeing a section's pages, and what each is for, before choosing one.

## When not to use

- A few links under one item, with no descriptions. Use the [header](header.md)'s links, whose dropdown lists them.
- Actions, such as Rename or Delete. Use the [dropdown](dropdown.md).
- An app's own navigation between its views. Use the [sidebar](sidebar.md) or the [app bar](app-bar.md).

## Behavior

Pressing an item with a caret opens its panel under the row and raises the item, and the caret turns; pressing it again closes it. One panel is open at a time: opening another closes the first. Escape, a press anywhere outside the item and its panel, or Tab moving focus past the panel's last link close it. The panel drops in and fades as it opens and fades out as it closes; under reduced motion it only fades.

With `openOnHover`, in a wide space a panel also opens while a mouse rests on its item and closes a moment after the mouse leaves the item and its panel. A press still opens it, and a press on a panel the mouse opened keeps it open, so touch and the keyboard work the same either way. It is off by default: a panel that opens as the pointer passes over the row gets in the way.

The panel lines up with the row's start edge, or with its end edge (`align="end"`) for links at the end of a header, so it stays on the page.

In a narrow space, as on a phone, the row stacks into a list, each item fills it with its caret at the far end, and a panel opens in place under its item, its columns and its featured column one under another. There it stays open until its item is pressed again or Escape is pressed, as a group in a list does.

## Accessibility

### What it does for you

- It follows the disclosure pattern for navigation, not a menu: a navigation landmark holding a list, where an item that opens a panel is a button saying whether its panel is open (`aria-expanded`) and which panel it controls (`aria-controls`). Screen readers read the links as links, and Tab moves through them in order.
- The panel follows its button, so Tab goes from the button into the open panel's links, and past the last one to the next item.
- Escape closes the open panel and puts focus back on its button when focus was inside it.
- Each column's links are a list named by its heading. The featured link is described by the featured title, so "Read the notes" is heard with what it is about.
- The current page's link is marked `aria-current="page"` and sits on the selected surface.

### What you must do

- Give the block a name of its own when a page has more than one navigation landmark, such as "Main" and "Footer".
- Write each link's title and description so they make sense heard alone, and keep the featured link's words short; the title describes it.
- Give a featured picture an empty `alt` when it only decorates, or words when it says something the title does not.
- In markup written by hand, the buttons need script to open and close their panels and to set `aria-expanded`; without it, give each item a link to its section's own page instead.

### How to test

- Tab to an item with a caret and press Enter: the panel opens and the button is announced as expanded. Tab moves through its links; Escape closes it and focus is back on the button.
- Press outside the open panel: it closes.
- With a screen reader, the block is read as navigation by its name, each item as a link or a button with its state, and each column as a list by its heading.
- With the page 320 pixels wide, the items stack and a panel opens under its item; nothing scrolls sideways.

### Keyboard

| Key | What it does |
|---|---|
| Tab | Moves to the next item, or through the open panel's links; past the last link the panel closes. |
| Enter or Space | Opens the focused item's panel, or closes it when it is open. |
| Escape | Closes the open panel and puts focus back on its button. |

## Usage rules

### Do

- Group a section's pages into two or three columns under short headings.
- Keep each description to one line that says what a reader finds there.
- Use `align="end"` when the links sit at the end of the header.

### Don't

- Put actions or form controls in a panel.
- Make a top item both a link and the opener of a panel: give the section's own page a link in its panel instead.
- Turn `openOnHover` on in a row a visitor has to cross to reach the rest of the page.
