Header

The site header is a recipe, not an import — compose it from primitives. It's the one place the brand sanctions a blur: 92% white with backdrop-filter once content scrolls beneath it.

Prototyped in design-system-docs/ui_kits/marketing/ and shown live in Storybook under Patterns/Marketing.

Ingredients

Button for the CTA, the wordmark, plain links, and tokens for everything else.

Recipe

import { Button } from '@elirobinson/react/components/atoms/Button';

export function SiteHeader({ active }: { active: string }) {
  const items = ['Home', 'Portfolio', 'Store', 'Services', 'About'];
  return (
    <header className="header">
      <a href="/" className="header__wordmark" aria-label="Miltinson home">
        Miltinson<span className="header__dot">.</span>
      </a>
      <nav className="header__nav" aria-label="Primary">
        {items.map((item) => (
          <a
            key={item}
            href="#"
            className="header__link"
            aria-current={active === item ? 'page' : undefined}
          >
            {item}
          </a>
        ))}
        <Button variant="primary" size="sm">
          Hire me
        </Button>
      </nav>
    </header>
  );
}
.header {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 64px;
  padding: 0 var(--gutter);
  background: oklch(100% 0 0 / 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}

.header__wordmark {
  font-weight: var(--fw-semibold);
  font-size: var(--fs-xl);
  color: var(--fg);
  text-decoration: none;
}

.header__dot {
  color: var(--accent);
}

.header__nav {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}

.header__link {
  font-size: var(--fs-sm);
  color: var(--fg-2);
  text-decoration: none;
  /* nav items are primary controls — keep the 44px target */
  padding: var(--space-3) 0;
}

.header__link:hover,
.header__link[aria-current='page'] {
  color: var(--fg);
}

.header__link[aria-current='page'] {
  font-weight: var(--fw-medium);
}

Rules

  • Height 64px, sticky, always visible. No hide-on-scroll tricks.
  • One CTA at most, size="sm" so it sits inside the 64px band.
  • Active link: ink + medium weight — not amber; amber in the header belongs to the wordmark dot alone.
  • Nav links keep a 44px vertical hit area via padding.
  • On small screens, collapse nav items behind a Sheet-based menu rather than shrinking tap targets.