# Menu tabs with height glide (`menu-tabs`)

Long price lists become category tabs (Cuts / Colour / Finish) whose panel glides to its new height while rows slide in and out. Printed-menu rows with dotted leaders and mono prices.

| | |
|---|---|
| Tag | Flow |
| Size | 2.3 KB gzipped own code (JS 1.4 KB + CSS 1.0 KB; 5.2 KB raw) |
| Dependency | AutoAnimate 0.10.0 (MIT, 3.2 KB gz, vendored) |
| Best for | Salons, barbers, nails, restaurants and cafes (Breakfast / Lunch), detailers (Interior / Exterior), med spa |
| Demo | `index.html` in this folder (live: https://wbl-code-lib.pages.dev/modules/menu-tabs/) |

## What it does
The markup is plain sections (heading + list), complete without JS. The script builds a real ARIA tablist (roving tabindex, ←/→/Home/End, automatic activation) and one tabpanel, then swaps the list rows per tab. AutoAnimate (MIT, 3.3 KB gzipped, loaded on demand from vendor/) animates the panel's height and the rows entering/leaving with transforms (FLIP); if it fails to load, tabs switch instantly.

## When to use
- Menus or price lists over ~10 rows (Mobbin: sweetgreen category tabs).
- Pair with Service picker below it, or use its rows as the picker's source.

## Don't
- Fewer than 2 real categories, or one-row tabs.
- Hide the main service's price behind a second tab: put the bestsellers in the first tab.

## Reduced motion, no JS, accessibility
- Reduced motion: AutoAnimate disables itself; tab colours change instantly.
- No JS: all sections visible with headings.
- WAI-ARIA tabs pattern; the panel is focusable and labelled by the selected tab.

## Notes
- AutoAnimate is an ES module: module.js imports it relative to its own URL, so keep vendor/ next to module.js.

## Relation to the effects libraries
Batch 2's flip-filter (GSAP Flip) filters a photo grid; batch 3's flip-layout toggles grid/list. This is the menu/price tabs with height glide, at 1/10 the weight.

## Use it
Copy this folder to the site as `/wbl/menu-tabs/` (keep `vendor/` if there is one), then:

```html
<!-- Menu tabs with height glide (WBL Code Library) -->
<!-- in <head>: -->
<script>document.documentElement.classList.add('wbl-js')</script>
<link rel="stylesheet" href="/wbl/menu-tabs/module.css">
<script src="/wbl/menu-tabs/module.js" defer></script>

<!-- markup: -->
<div class="wbl-mt" data-wbl="menu-tabs" aria-label="Services and prices">
  <section class="wbl-mt-sec"><h3>Cuts</h3>
    <ul class="wbl-mt-list">
      <li><b>Women's cut + blow-dry</b><i aria-hidden="true"></i><span class="p">$65</span><small>Shampoo, cut, blow-dry. About an hour.</small></li>
      <li><b>Men's cut</b><i aria-hidden="true"></i><span class="p">$40</span><small>Scissor or clipper, hot towel finish.</small></li>
      <li><b>Kids cut</b><i aria-hidden="true"></i><span class="p">$30</span><small>Under 12.</small></li>
      <li><b>Fringe trim</b><i aria-hidden="true"></i><span class="p">$15</span><small>Free between cuts for clients.</small></li>
    </ul></section>
  <section class="wbl-mt-sec"><h3>Colour</h3>
    <ul class="wbl-mt-list">
      <li><b>Gloss / toner</b><i aria-hidden="true"></i><span class="p">$55</span><small>Shine and tone refresh, 45 min.</small></li>
      <li><b>Root touch-up</b><i aria-hidden="true"></i><span class="p">$85</span><small>Single process, up to 1 inch.</small></li>
      <li><b>Balayage</b><i aria-hidden="true"></i><span class="p">from $220</span><small>Price after a strand test.</small></li>
      <li><b>Vivid colour</b><i aria-hidden="true"></i><span class="p">from $180</span><small>Reds, coppers, pinks. Consult first.</small></li>
      <li><b>Colour correction</b><i aria-hidden="true"></i><span class="p">by consult</span><small>Box-dye fixes, one or two visits.</small></li>
      <li><b>Gray blending</b><i aria-hidden="true"></i><span class="p">$120</span><small>Soft lowlights, no hard regrowth line.</small></li>
    </ul></section>
  <section class="wbl-mt-sec"><h3>Finish</h3>
    <ul class="wbl-mt-list">
      <li><b>Blow-dry</b><i aria-hidden="true"></i><span class="p">$45</span><small>Smooth or bouncy.</small></li>
      <li><b>Bond repair</b><i aria-hidden="true"></i><span class="p">$35</span><small>Add to any colour.</small></li>
    </ul></section>
</div>
```

Colours come from CSS variables with safe defaults: `--wbl-accent`, `--wbl-on-accent`, `--wbl-ink`, `--wbl-paper`,
`--wbl-card`, `--wbl-line`, `--wbl-muted`, `--wbl-band`, `--wbl-radius`, `--wbl-head` (see the library README for the
one-line bridge to the preview builder's `--a / --ink / --bg …`).

## License
Our code: WBL-owned, original. AutoAnimate 0.10.0: MIT (https://github.com/formkit/auto-animate), licence text in `vendor/`
