# Component Page Template Menu Container

## Essence

Private menu container used by `Component Page Template` page composition.

It stores the side `Menu` and owns sticky positioning plus vertical scroll limits for the navigation area.

## Hook

Use when `Component Page Template` needs a side navigation container that can hold a `Menu` and control menu scrolling.

## Status

Private

## Aliases

- Side menu container
- Template menu container
- Former `ds-sidebar`

## Contract

- Owns the side menu container area.
- Owns default width of 420px through the parent layout variable `--menu-container-width`.
- Owns the right-side divider border.
- Owns horizontal resizing through the vertical divider handle.
- Owns sticky positioning on desktop.
- Owns menu height relative to the viewport after Header.
- Owns the `--menu-max-height` context consumed by `Menu`.
- Does not own menu item labels, grouping, active state, or disclosure behavior.
- Is the only allowed parent for `Menu`.
- Does not own page-level content layout.
- Does not render Header, Menu Navigation, or content sections.

## Ownership

| Owner | Responsibilities |
| --- | --- |
| Component | Side menu container, sticky behavior, menu height, and scroll boundary context. |
| Parent | Supplies `Menu`, navigation data, page placement, and the `--menu-container-width` layout variable. |
| Preview | May render sample menu groups to demonstrate scroll behavior. |
| Token system | Supplies breakpoint and spacing values indirectly through layout context. |
| Page/layout | Owns page grid, Header, and content region. |

## Public Props

- `ariaLabel`: accessible label for the menu container landmark.

## Preview-Only Context

- Sample menu groups are documentation-only.
- Preview may use a small test menu to show container behavior.

## Internal Rules

- Use `aside` as the landmark wrapper.
- Render a 1px solid right border using the line color token.
- Default menu container width is 420px.
- Allow desktop users to resize the menu container horizontally by dragging the right divider.
- Set `--menu-max-height` to the remaining viewport height after Header.
- Keep Menu as one vertical navigation tree on Mobile; do not split it into multiple columns.
- Keep desktop behavior sticky at the top of the content area.
- On mobile, release sticky behavior and let the menu become normal document flow.
- On mobile, hide the resize handle.
- Do not create scroll behavior inside nested menu groups.

## Non-Goals

- Does not replace `Menu`.
- Does not define `Menu Item` or `Collapsible Menu Item`.
- Does not control selected route state.
- Does not own content area spacing.

## Use When

- Component Page Template needs side navigation.
- DesignSystemShell needs to render the Design System side menu.
- A preview needs to show the menu container contract.

## Do Not Use When

- Rendering standalone navigation outside Component Page Template.
- A component needs only individual menu items.
- A page does not have a side menu.

## Edge Cases

- If Header height changes, the remaining viewport height calculation must be reviewed.
- If mobile menu becomes collapsible later, this component owns the container behavior but not item disclosure.
- If the menu is longer than available height, the whole Menu should scroll as one unit.
- If the menu is resized, `Menu` still fills 100% of the container width.

## Accessibility Notes

- Container exposes an `aside` landmark with `aria-label`.
- Resize handle exposes a button label and keyboard arrow support.
- The child `Menu` owns navigation semantics.
- Sticky behavior must not trap keyboard navigation.
- Scrollable menu content must remain keyboard reachable.

## Token Dependencies

- Header height assumption: `3.5rem`.
- Mobile breakpoint: `max-width: 639px`.
- `--color-line` for the right divider border.
- `--menu-max-height` context for `Menu`.
- `--menu-container-width` context owned by the parent layout, defaulting to `420px`.

## Related Components And Patterns

| Item | Relationship | Direction | Notes |
| --- | --- | --- | --- |
| `Component Page Template` | Used By | Parent -> Child | Template page composition uses this as its private menu area. |
| `DesignSystemShell` | Used By | Parent -> Child | Current implementation consumes this container for the actual DS side menu. |
| `Menu` | Composes | Parent -> Child | Menu is placed inside this container and is used only here. |
| `Collapsible Menu Item` | Used By | Container -> Descendant | Descendant behavior must not create nested scroll ownership. |
| `Menu Item` | Used By | Container -> Descendant | Descendant active state is owned by Menu/Shell logic. |

## Change Impact

| Change | Risk | Review Needed |
| --- | --- | --- |
| Sticky positioning | Medium | Check desktop side menu while scrolling long pages. |
| Right border | Low | Check contrast against content background. |
| Height calculation | High | Check Header height, viewport fit, and menu scroll. |
| Mobile behavior | Medium | Check mobile stacked menu/content layout. |
| `--menu-max-height` context | High | Check Menu overflow and nested groups. |

## Source Of Truth

| Source | Path / Link | Notes |
| --- | --- | --- |
| Component implementation | `packages/design-system/src/components/ComponentPageTemplateMenuContainer.astro` | Primary behavior and layout source. |
| Shell usage | `packages/design-system/src/components/DesignSystemShell.astro` | Actual page integration. |
| DS page | `apps/portfolio-site/src/pages/design-system/index.astro` | Visible documentation and preview. |
| Relationship map | `docs/design-system/maps/component-relationship-map.md` | Component relationships. |

## Rule Confidence

| Rule | Evidence | Confidence |
| --- | --- | --- |
| Private to Component Page Template | User requested a private component to Component Page Template. | High |
| Owns scroll behavior | User explicitly requested menu container with scrollable behavior. | High |
| Does not use Menu Navigation | User explicitly requested Menu Container should not use this component. | High |
| Used by current shell | DesignSystemShell now consumes this component. | High |

## Open Questions

- Should Header height be exposed as a token so `3.5rem` is not repeated as a layout assumption?
- Should this component eventually replace the remaining `DesignSystemShell` layout wrapper?

## Code Paths

- `packages/design-system/src/components/ComponentPageTemplateMenuContainer.astro`
- `packages/design-system/src/components/DesignSystemShell.astro`
- `packages/design-system/src/components/Menu.astro`
- `apps/portfolio-site/src/pages/design-system/index.astro`
- `apps/portfolio-site/src/pages/design-system/essences/[slug].md.ts`
- `docs/design-system/maps/component-relationship-map.md`

## Validation Checklist

- [x] Canonical name is clear
- [x] Aliases are captured
- [x] Contract is explicit
- [x] Ownership is separated
- [x] Public props are separated from preview-only context
- [x] Token dependencies are listed
- [x] Related items use typed relationships
- [x] Accessibility notes are present
- [x] Change impact is described
- [x] Code paths are listed
- [x] DS page link is updated
- [x] Route slug is updated
- [x] Relationship map is updated
- [x] Build passed
