## Context

Step 002 produced a `BaseLayout.astro` that imports `Nav.astro` and `Footer.astro` stubs — both render nothing. The navigation bar is the first visible UI element needed on every page. It must:

- Render correctly on a Midnight (`#102022`) dark background
- Work at build time (Astro SSG — no server runtime)
- Derive the current locale from the URL path (no runtime props)
- Use zero client-side framework code

Available assets confirmed:
- `src/assets/logos/logo-wide.svg` — full "qumo" wordmark, paths filled with `#161616` (near-black — needs override)
- `src/assets/icons/wum-arrow.svg` — chevron arrow, already `stroke="#f3f3f3"` (Snow — correct for dark nav)

## Goals / Non-Goals

**Goals:**
- Fully functional `Nav.astro` replacing the empty stub
- Logo visible on Midnight background
- Three nav links + language switcher + Connect CTA
- Scroll-triggered background transition (transparent → Midnight)
- Mobile hamburger menu with open/close behavior
- All text strings from `en.json` / `nl.json`

**Non-Goals:**
- Animated underline or hover effects beyond Tailwind utilities
- Active page highlighting (deferred — pages don't exist yet to test against)
- Dropdown sub-menus (not on staging site)
- Separate `LanguageSwitcher.astro` component (simple enough to inline)

## Decisions

### 1. Logo: inline SVG with fill override

**Decision:** Inline the `logo-wide.svg` SVG directly in `Nav.astro`. Change all `fill="#161616"` attributes to `fill="currentColor"`. Set `class="text-snow"` on the `<svg>` element so `currentColor` resolves to Snow (`#F3F3F3`).

**Rationale:** The logo is a small, purely decorative SVG — inlining it avoids an extra HTTP request and allows CSS-controlled coloring without filters. `fill="currentColor"` + Tailwind text color is the idiomatic approach. An `<img>` tag cannot be recolored without CSS filters, which look worse.

**Alternative considered:** `<Image>` component with a separate white-fill SVG asset. Rejected: requires maintaining two copies of the same logo.

### 2. Locale detection: Astro.url at build time

**Decision:** In `Nav.astro`, derive locale from `Astro.url.pathname`:
```ts
const isNl = Astro.url.pathname.startsWith('/nl');
const locale = isNl ? 'nl' : 'en';
const alternatePath = isNl
  ? Astro.url.pathname.replace(/^\/nl/, '') || '/'
  : '/nl' + Astro.url.pathname;
```
Pass `locale` to `getContent()` for nav strings. Use `alternatePath` for the language switcher link.

**Rationale:** Astro SSG renders each page at build time with its own `Astro.url`. This approach is zero-JS, works for every route without configuration, and the prefix rule (`/nl/...` ↔ `/...`) holds for all routes on this site. Confirmed with user during explore session (Option B).

**Alternative considered:** Prop threading from `BaseLayout` (Option A). Rejected by user — more verbose, non-standard for nav components.

### 3. Scroll behavior: window scroll event + CSS class toggle

**Decision:** A `<script>` tag in Nav adds/removes a `scrolled` class on the `<nav>` element when `window.scrollY > 20`. Tailwind's `data-scrolled` attribute or a direct class toggle drives the style change.

Implementation approach — use a `data-scrolled` attribute to avoid class name conflicts:
```js
const nav = document.getElementById('main-nav');
window.addEventListener('scroll', () => {
  nav.dataset.scrolled = window.scrollY > 20 ? 'true' : 'false';
}, { passive: true });
```
CSS: nav starts `bg-transparent`, transitions to `bg-midnight` when `data-scrolled="true"`. Use Tailwind's arbitrary variant: `data-[scrolled=true]:bg-midnight`.

**Rationale:** Simple, no dependencies, no layout shift. `passive: true` avoids scroll jank. The `data-*` attribute approach keeps the JS–CSS contract explicit and avoids collisions with Tailwind's JIT-generated class names.

**Alternative considered:** `IntersectionObserver` on a sentinel element. Unnecessary complexity for this use case — scroll position threshold is simpler and more predictable.

### 4. Mobile menu: vanilla JS toggle with CSS transition

**Decision:** The hamburger button toggles `aria-expanded` on itself and a corresponding `data-open` attribute on the mobile menu panel. CSS handles the visual transition (translate or max-height). A `<script>` tag wires up the toggle.

```html
<button id="menu-toggle" aria-expanded="false" aria-controls="mobile-menu">...</button>
<div id="mobile-menu" class="... -translate-y-full data-[open]:translate-y-0 transition-transform">
  ...
</div>
```

**Rationale:** `aria-expanded` is the correct ARIA pattern for disclosure widgets. The `data-open` attribute drives CSS state without needing to manage class lists. `translate` transitions are GPU-accelerated and smooth.

### 5. Nav content: `nav` key in en.json / nl.json

**Decision:** Add a top-level `"nav"` key to both content files:
```json
"nav": {
  "links": [
    { "label": "Services", "href": "/#services" },
    { "label": "AI Launchpad", "href": "/ai-launchpad" },
    { "label": "About", "href": "/about" }
  ],
  "cta": "Connect",
  "langSwitch": { "en": "EN", "nl": "NL" }
}
```
NL links have the same hrefs with `/nl` prefix where needed; CTA becomes "Verbind".

**Rationale:** Consistent with the `meta` key established in step 002. Keeps all user-visible text out of component markup.

**Note on NL link hrefs:** The `/#services` anchor on the EN homepage becomes `/nl#services` in NL (no slash before `#`). The `href` values in `nl.json` must reflect this.

## Risks / Trade-offs

- **Logo SVG inlining grows component size** → The logo SVG is ~1.5KB. Acceptable for a component rendered on every page; Astro will inline it into each page's HTML at build time. If the logo is ever animated or reused frequently, extract to a dedicated `Logo.astro` component.
- **Scroll behavior flickers on page load** → On slow connections the nav may briefly show transparent before JS runs. Mitigation: set `data-scrolled="false"` as the default HTML attribute so no flash occurs on initial render.
- **Mobile menu accessibility** → `aria-expanded` and `aria-controls` are set, but focus trapping inside the open menu is not implemented in this step. Acceptable for now — full accessibility audit is a later concern.
- **NL href construction** → The `alternatePath` logic strips the `/nl` prefix. If a page path ever starts with `/nl` for a reason other than locale (e.g. `/nl-tech`), it would be incorrectly treated as Dutch. This site has no such routes, so it's safe — but document the assumption.
