Default
gray-900 · Medium 14
Design system · 04 Navigation
The bar above is the live component, not a picture of one. Open the menus, tab through it, scroll the page. Everything below documents what it does and why, so it can be rebuilt in Figma and in code without a second interpretation.
Five top-level destinations, one account link, one primary action. The bar is a routing device — it answers “what is ezee, what does it cost, how do I get it, who do I ask” and nothing else.
Wayfinding
Utility
/, German at /de/. A switcher in the bar
is the only honest place for it.
Deliberately not here
redesign-synthesis.md lists “Support / FAQs” as a
top-level item and Contact as a separate node in the tree. Six text items plus a utility rail plus a CTA does not
breathe at 1192px, so Contact and Scam prevention sit inside a Support menu. Both stay one click away and
the bar keeps its rhythm. If Contact needs to be top-level for a business reason, say so and it moves out.
Three zones, read left to right: who we are, where you can go, what you do next. The gap between zone two and zone three is what stops the bar reading as one undifferentiated row of links.
Every value resolves to a token — no ad-hoc numbers.
| Element | Spec | Tokens | |
|---|---|---|---|
| 1 | Bar | 72px tall, fixed. White surface, 1px bottom hairline. Sticky at top:0, z-index 100. |
--header-h --surface --border |
| 2 | Logo | Full lockup at 120 × 42 — the stated web-header minimum. Links to home; the whole lockup is the target. | ezee-logo-full.svg |
| 3 | Nav item | Roboto Medium 14/20. 40px tall, 12px side padding, 16px between items — 40px of visual air between labels. Hover paints an 8px-radius tint behind it. | --fs-sm --space-4 --radius-xs |
| 4 | Current page | Teal, Bold, and a 2px rule sitting on the bar's bottom edge. Three signals, so colour is never doing the work alone. | --primary-500 --primary-700 |
| 5 | Utility rail | Language · 1px × 24px divider · Log in. All quiet: secondary colour, no fill, 14px. | --text-secondary --border |
| 6 | Primary CTA | Filled teal pill, small button. The only filled element in the bar. | .btn--brand.btn--sm |
| 7 | Scrolled bar | Background drops to 88% white with a 12px backdrop blur and picks up the card shadow. Height never changes, so nothing below reflows. | --shadow-card |
Shown open below so they can be measured and redlined without hovering. Two shapes only: a mega panel where the choice deserves description, and a plain list where it does not.
720 × auto · anchored to the trigger, 16px below the bar
Products
Everything private. One secure vault.
The things you would otherwise keep in notes and screenshots now have somewhere to live.
Explore Password VaultThe second row is shown in its hover state and the third in its coming-soon state. Cloud Storage stays clickable — the page exists and captures interest — but its icon tile drops to neutral and its name to secondary, so the eye reads it as not-yet before it reads the badge.
248px minimum · one column
Right-aligned to the trigger · current locale carries a tick
Required by the brief for navigation and buttons. Printed here rather than described, so a reviewer can check them side by side.
Default
gray-900 · Medium 14
Hover
primary-700 on primary-50 tint
Focus visible
2px teal ring, 3px offset — keyboard only
Pressed
primary-100 tint
Current page
Bold + teal + 2px rule
Menu open
Tint held, chevron rotated 180°
Default
Teal glyph on primary-50 tile
Hover
Row tints, tile inverts to solid teal
Current
Held on primary-50
Coming soon
Neutral tile, secondary name, badge
CTA — default
primary-500
CTA — hover
primary-700 + teal glow
CTA — focus visible
White inner ring on teal
CTA — disabled
50% · pointer events off. Not used in the live bar.
Log in — default
gray-900 Medium 14, no chrome
Log in — hover
primary-700
The bar has to survive a mouse, a keyboard and a screen reader without three different designs.
| Input | What happens |
|---|---|
| Pointer hover | Menu opens immediately; closing waits 140ms, so a diagonal path from trigger to panel does not dismiss it. Hover is bound to (hover:hover) only, so touch gets a clean tap-to-open. |
| Click trigger | Toggles. Opening one menu closes any other — never two panels at once. |
| Click outside | Closes the open menu. |
| Tab | Walks the bar in reading order. Tabbing past the last item in a panel closes it behind you rather than leaving an orphaned open menu. |
| ↓ / ↑ on a trigger | Opens the menu and moves focus onto the first item, then cycles. Home / End jump to the ends. |
| Escape | Closes the menu and returns focus to its trigger. |
| Scroll | Past 8px the bar goes translucent and raised. rAF-throttled, passive listener, no layout change. |
| Reduced motion | Panels appear and disappear with no transform or fade; the chevron still rotates because it reports state. |
| No JavaScript | Every destination in both menus is duplicated in the footer, so the site stays navigable. The bar degrades to plain links. |
| Attribute | Where and why |
|---|---|
<nav aria-label> | “Primary” on the bar. A page can carry more than one nav landmark; unlabelled ones are indistinguishable in a landmark list. |
aria-expanded | On both triggers. It is the state, so it is read, not inferred from a rotated chevron. |
aria-controls | Ties each trigger to its panel id. |
hidden | A closed panel is hidden, not just transparent — otherwise its links stay in the tab order and in the screen-reader tree. |
aria-current="page" | On the active nav item. Drives the visual current state through CSS, so the two can never disagree. |
aria-label on logo | “ezee — home”. The lockup is an image; the link needs a name. |
| Skip link | First focusable element on every page, jumps past the bar to #main. |
| Contrast | Measured: gray-900 on white 13.4:1 · primary-700 on primary-50 (hover) 6.7:1 · primary-700 on primary-100 (pressed) 5.0:1 · gray-500 menu descriptions on white 5.0:1 · white on primary-500 (CTA) 4.5:1 · focus ring on white 4.5:1. Every pair clears AA, but the CTA sits on the line — if the brand teal is ever retuned lighter, the button's label has to go with it. |
aria-current="page" on the item matching the current section — including for child pages, so Password Vault marks Products.Scroll back up to see the bar return to its resting state.