Design system · 04 Navigation

Global 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.

Status
Ready for review
Frame
1440 · container 1192
Height
72px, fixed
Source
assets/css/ezee-legacy.css
IA source
redesign-synthesis.md

Information architecture

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

Products Menu The suite, not one app. This is where the repositioning happens.
  • ezeeVPN
  • Password Vault
  • Cloud Storage — coming soon
Why ezeeThe argument, kept off the homepage so the homepage can route.
PricingMonthly · 6 months · Yearly.
DownloadThe consolidated all-platform hub.
Support Menu Three destinations that each need a page but none of which earn a slot on their own.
  • FAQs
  • Contact us
  • Scam prevention

Utility

Language The site is bilingual: English at /, German at /de/. A switcher in the bar is the only honest place for it.
Log inExisting customers. Text link — it must not compete with the CTA.
Get ezee CTAThe one filled element in the bar. Same label on every page, no exceptions.

Deliberately not here

Imprint · Terms · PrivacyLegal lives in the footer. Putting it in the bar spends a slot on something nobody navigates to.
HomeThe logo is the home link. A “Home” item beside it is a duplicate.
SearchNot built. An input that returns nothing is worse than no input.
A second CTA“Get ezee” everywhere. Competing primaries are how a bar stops converting.
Built with room for German. At 1440 the bar uses 947 of the container's 1192px, leaving 245px spare. That is deliberate: German labels run 20–30% longer than English (“Download” → “Herunterladen”), and the bar has to hold the DE build without a second layout. Nothing in the row is allowed to shrink — if a translation ever does exhaust the headroom, shorten the label rather than the spacing.
One decision worth flagging. The IA in 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.

Anatomy

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.

EN Get ezee

Specification

Every value resolves to a token — no ad-hoc numbers.

ElementSpecTokens
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

Menus

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.

Products

720 × auto · anchored to the trigger, 16px below the bar

The 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.

Support

248px minimum · one column

Language

Right-aligned to the trigger · current locale carries a tick

Interaction states

Required by the brief for navigation and buttons. Printed here rather than described, so a reviewer can check them side by side.

Nav item

Pricing

Default

gray-900 · Medium 14

Pricing

Hover

primary-700 on primary-50 tint

Pricing

Focus visible

2px teal ring, 3px offset — keyboard only

Pricing

Pressed

primary-100 tint

Pricing

Current page

Bold + teal + 2px rule

Products

Menu open

Tint held, chevron rotated 180°

Menu row

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

Actions

Get ezee

CTA — default

primary-500

Get ezee

CTA — hover

primary-700 + teal glow

Get ezee

CTA — focus visible

White inner ring on teal

Get ezee

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

Behaviour & accessibility

The bar has to survive a mouse, a keyboard and a screen reader without three different designs.

InputWhat happens
Pointer hoverMenu 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 triggerToggles. Opening one menu closes any other — never two panels at once.
Click outsideCloses the open menu.
TabWalks 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 triggerOpens the menu and moves focus onto the first item, then cycles. Home / End jump to the ends.
EscapeCloses the menu and returns focus to its trigger.
ScrollPast 8px the bar goes translucent and raised. rAF-throttled, passive listener, no layout change.
Reduced motionPanels appear and disappear with no transform or fade; the chevron still rotates because it reports state.
No JavaScriptEvery destination in both menus is duplicated in the footer, so the site stays navigable. The bar degrades to plain links.

Semantics

AttributeWhere 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-expandedOn both triggers. It is the state, so it is read, not inferred from a rotated chevron.
aria-controlsTies each trigger to its panel id.
hiddenA 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 linkFirst focusable element on every page, jumps past the bar to #main.
ContrastMeasured: 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.

Using it

Do

  • Keep “Get ezee” as the label on every page. One primary action, one name.
  • Set aria-current="page" on the item matching the current section — including for child pages, so Password Vault marks Products.
  • Add new products as rows inside the Products menu, not as new top-level items.
  • Keep the bar's own contents identical on every page. Page-specific wayfinding belongs in a sub-nav below it, as on Scam prevention.

Don't

  • Add a second filled button. “Log in” stays a text link.
  • Swap the CTA for a page-specific action like “Download now” — that belongs in the hero.
  • Shrink the bar on scroll. A moving header makes every anchor offset wrong.
  • Announce Cloud Storage as available anywhere in the menu, including the badge.
  • Nest a third level inside the menus. If a menu needs a menu, the IA is wrong.

Scroll back up to see the bar return to its resting state.