Design Lounge
Install

Nº 421 of 520

Split navbar with centred wordmark

Links split left and right of a centred serif wordmark over a dark hero. After 80px of scroll it turns into a paper bar and the wordmark shrinks 40px to 24px.

Preview

Open full size
1280 × 800 · 12.9 KB · 249 lines

Use it

Free to use · credit appreciated

1 Once, in your project

npx skills add SusanAcharya/Design-Lounge

2 Then ask

Using the Design Lounge skill, build "Split navbar with centred wordmark" (piece navbar-split-centered-logo) in my stack. Match its brief; restyle it onto my product's theme.

No skill? Paste the brief instead. It carries the numbers, tokens and behaviour.

Brief

297 lines

Build brief for a coding agent. Rebuild this piece in the reader’s stack. If they haven’t said which stack, ask once, then default to semantic HTML + CSS + a little vanilla JS. Match the numbers below; don’t “improve” them.

What it is

The top bar for Verane, a fictional lake hotel with a dining room. The wordmark sits in the exact centre. Three links sit to its left (Rooms, Dining, Garden). Two links and an outlined “Reserve a table” button sit to its right (Events, Journal). At the top of the page the bar is transparent and its text is ivory over a deep green hero drawn in CSS: a radial gradient, three brass hairline arches, and a brass sun. After 80px of scroll the bar fills with paper, the text turns dark, a 1px hairline appears under it, and the wordmark scales from 40px to 24px. The detail worth copying: a three-column grid of minmax(0,1fr) auto minmax(0,1fr) keeps the wordmark in the true centre no matter how long each side is.

Reference behaviour

  1. First frame: scroll is 0. The bar is 104px tall, transparent, with ivory text #f7f2e8 and a 1px bottom line in rgba(247,242,232,.18).
  2. The wordmark “VERANE” is Cormorant Garamond 500, 40px, tracked 0.32em, uppercase. Under it sits “EST. 1931” in Jost 9px, tracked 0.5em, at 80% opacity.
  3. “Dining” is the current page. It has aria-current="page" and a 1px underline 4px below the text.
  4. The hero fills the viewport (100vh, min 640px). Its headline “Supper under the long arches” is 76px serif, centred, 72px from the bottom. “long arches” is italic brass #d9b878.
  5. The user scrolls. When scrollY passes 80, the bar gets the class solid. Over 320ms on cubic-bezier(.2,.7,.2,1):
    • height goes 104px to 68px,
    • background goes transparent to paper #f4efe4,
    • text goes ivory to ink #1b1f1c,
    • the bottom line goes to #d8cfbb,
    • the wordmark scales from 1 to 0.6 (40px to 24px),
    • “EST. 1931” fades to 0 over 200ms.
  6. The button “Reserve a table” is outlined in currentColor over the hero. In the solid bar its border and text turn deep green #1d3a2f.
  7. Scrolling back above 80px reverses every change on the same timing.
  8. Hovering a link draws the 1px underline from left to right over 200ms.
  9. Hovering the button fills it. Over the hero: ivory fill, green text. In the solid bar: green fill, paper text.
  10. The page scrolls through real sections below the hero: Dining (menu with prices), Rooms (three room cards), Garden, Reserve. Each section is a two-column band with a 1px rule under it.
  11. Below 900px wide the links and the button hide. A 44px square menu button appears on the left. The wordmark stays centred.
  12. Clicking the menu button opens a paper panel under the bar with all five links and the button at full width. aria-expanded flips. Escape closes it and returns focus to the button. Clicking a link closes it.

Structure

1280 x 800 frame, header fixed, padding 0 48px

transparent state, 104px tall
+--------------------------------------------------------------------------+
| ROOMS  DINING  GARDEN        V E R A N E        EVENTS JOURNAL [RESERVE A TABLE ->] |
|                               EST. 1931                                  |
+------------------------------------------------------------------------- 1px rgba line
|                    deep green hero, 100vh                                 |
|        (arch)            ( arch  + sun )              (arch)              |
|                 HOTEL AND DINING ROOM · LAKE OSSIACH                     |
|                  Supper under the long arches   76px                     |
| SCROLL                                              KITCHEN 18:30 – 23:00 |
+--------------------------------------------------------------------------+

solid state, 68px tall, paper, 1px #d8cfbb line
| ROOMS  DINING  GARDEN           VERANE (24px)      EVENTS JOURNAL [RESERVE A TABLE ->] |

grid: minmax(0,1fr) | auto | minmax(0,1fr), gap 32px
  • The bar is a header, position: fixed, full width, z-index: 10.
  • Inside, one div holds the three-column grid, max-width 1280px.
  • The left links are a nav labelled “Primary, left” with a ul.
  • The wordmark is a link to the top of the page, aria-label="Verane, home".
  • The right column is a flex row, justify-content: flex-end: a nav labelled “Primary, right” with two links, then the button link.
  • The menu button is the first child of the grid but is display: none above 900px, so it does not take a column.
  • The mobile panel is a sibling of the header, fixed under it.
  • The hero is a section with decorative divs for the arches, sun and floor shade. They carry no text.
  • The sections below use section with an h2 each. The hero h1 is the only h1.

Tokens

:root {
  /* surfaces */
  --paper: #f4efe4;        /* solid bar, page */
  --paper-2: #ebe4d4;      /* card swatches */
  --green: #1d3a2f;        /* hero, button in solid bar */
  --green-2: #142a22;      /* hero edge */

  /* ink */
  --ink: #1b1f1c;          /* text in solid bar */
  --ink-2: #4a524c;        /* body copy */
  --on-dark: #f7f2e8;      /* text over hero */
  --on-dark-2: rgba(247,242,232,.72);

  /* accent */
  --brass: #b08d4a;        /* arches, sun, focus ring */
  --brass-2: #8a6a2f;      /* kicker text on paper */
  --line: #d8cfbb;         /* hairline */

  /* type */
  --serif: "Cormorant Garamond", Georgia, serif;
  --sans: "Jost", system-ui, sans-serif;
  --fs-mark: 40px;
  --fs-link: 12px;
  --fs-h1: 76px;
  --fs-h2: 52px;
  --fs-body: 16px;

  /* space */
  --space-1: 8px;
  --space-2: 16px;
  --space-3: 24px;
  --space-4: 32px;
  --space-6: 48px;
  --space-8: 64px;

  /* bar */
  --bar-h: 104px;
  --bar-h-solid: 68px;
  --mark-scale-solid: 0.6;
  --threshold: 80px;

  /* radius and shadow */
  --radius: 0;
  --shadow: none;

  /* motion */
  --ease: cubic-bezier(.2,.7,.2,1);
  --dur: 320ms;
  --dur-micro: 200ms;
}

Typography

RoleFamilySizeWeightLine-heightTrackingCase
WordmarkCormorant Garamond40px, scaled to 24px50010.32emupper
Wordmark subJost9px50010.5emupper
Nav linkJost12px5001.60.22emupper
ButtonJost12px50010.2emupper
Hero eyebrowJost12px4001.60.32emupper
Hero h1Cormorant Garamond76px5001-0.01emsentence
Section kickerJost12px4001.60.28emupper
Section h2Cormorant Garamond52px5001.050sentence
BodyJost16px4001.60sentence
Menu itemCormorant Garamond22px5001.60sentence

The serif is only for the wordmark, headings and menu items. Links and buttons stay in the sans. Add margin-right: -0.32em to the wordmark so its trailing tracking does not push it off centre.

Motion

ThingTriggerPropertyFrom → toDurationEasing
Bar heightscrollY crosses 80height104px → 68px320ms--ease
Bar fillsamebackground-colortransparent → #f4efe4320ms--ease
Bar textsamecolor#f7f2e8 → #1b1f1c320ms--ease
Bar linesameborder-bottom-colorrgba(247,242,232,.18) → #d8cfbb320ms--ease
Wordmarksametransformscale(1) → scale(0.6)320ms--ease
Sub linesameopacity0.8 → 0200ms--ease
Buttonsameborder and text colourcurrentColor → #1d3a2f200ms--ease
Link underlinehovertransformscaleX(0) → scaleX(1), origin left200ms--ease
Button fillhoverbackground, colournone → filled200ms--ease
  • There is no delay and no stagger. Everything moves together.
  • Scale the wordmark with transform, not font-size, so the row does not reflow during the move.
  • Reduced motion: set every transition to 0ms. The bar still switches at 80px, it just switches at once. Turn off smooth scroll.

States

  • Transparent bar: ivory text, no fill, faint ivory hairline.
  • Solid bar: paper fill, ink text, #d8cfbb hairline, wordmark at 0.6 scale, sub line hidden.
  • Link resting: no underline.
  • Link hover: 1px underline in currentColor, 4px under the baseline box.
  • Link current: aria-current="page" and the same underline, always shown.
  • Button resting: 1px border, 42px tall, 0 18px padding, no radius.
  • Button hover: filled (see Motion).
  • Focus-visible: 2px brass outline #b08d4a, offset 3px, on every link, the wordmark, the button and the menu button.
  • Menu panel closed: display: none. Open: paper panel with 1px rules between links. The current link is brass #8a6a2f.
  • No loading, empty or error state. This is navigation.

Accessibility

  • Two nav elements, labelled “Primary, left” and “Primary, right”. Screen readers read them in DOM order, left first.
  • The wordmark is a link with aria-label="Verane, home". The sub line is inside it and is decorative.
  • The current link has aria-current="page". Only one link carries it.
  • The menu button has aria-controls="panel", aria-expanded, and an aria-label that switches between “Open menu” and “Close menu”.
  • Escape closes the panel and returns focus to the menu button.
  • Tab order: left links, wordmark, right links, button. On small screens: menu button, wordmark, then the panel links when open.
  • Contrast: #f7f2e8 on #1d3a2f is about 11:1. #1b1f1c on #f4efe4 is about 15:1. Both pass at 12px.
  • Hit targets: links are 12px text at line-height 1.6 with 10px vertical padding, so about 40px tall. The button is 42px. The menu button is 44px square.
  • Decorative hero shapes carry no text and need no labels.
  • Icons are inline SVG with aria-hidden="true".

Responsive rules

  • At 1280 and above: the full layout. Bar padding 0 48px. Link gap 32px. Button reads “Reserve a table”.
  • At 1180 and below: padding 0 32px, grid gap 24px, link gap 24px, link tracking 0.16em, the button reads “Reserve”.
  • At 1024: the same as 1180. Check that the right column does not touch the wordmark.
  • Below 900: hide both nav elements and the button. Show the 44px menu button in the left column. The wordmark drops to 28px and the sub line hides. The bar is 72px tall, 60px when solid. The solid wordmark scale is 0.86.
  • Below 900, also: the hero h1 is 44px, the h2 is 38px, and sections stack to one column with 72px 24px padding. Room cards stack to one column.
  • Never let the row wrap. If a product has more than three links per side, collapse earlier instead of shrinking type below 11px.
  • The page never scrolls sideways. Use minmax(0,1fr) on every grid column.

Acceptance checklist

Always

  • The wordmark is centred in the viewport within 1px at every width, whatever the link count on each side.
  • The bar is transparent with light text at scroll 0 and solid with dark text past the threshold.
  • The switch happens at one scroll threshold and reverses when scrolling back.
  • The wordmark shrinks with transform: scale, not by changing font-size.
  • Exactly one link has aria-current="page".
  • The primary action is an outlined button on the right, 42px tall.
  • Focus rings are visible on every control in both bar states.
  • Below the collapse width a 44px menu button opens a panel; aria-expanded tracks it; Escape closes it.
  • Reduced motion removes every transition but keeps both states.
  • No horizontal scroll at any width from 360 to 1600.

This demo

  • The threshold is 80px of scroll.
  • The bar is 104px tall, then 68px when solid.
  • The wordmark is “VERANE”, 40px, scaling to 0.6 (24px).
  • Left links: Rooms, Dining, Garden. Right links: Events, Journal. Button: “Reserve a table”.
  • Dining is the current link.
  • Hero is #1d3a2f with three brass arches and a brass sun, no images.
  • The solid bar is #f4efe4 with a #d8cfbb hairline.
  • The menu collapses below 900px.

Implementation notes

Always: this is one bar with two looks. Do not render two headers and swap them.

The grid that keeps the wordmark centred:

.bar-in {
  display: grid;
  grid-template-columns: minmax(0,1fr) auto minmax(0,1fr);
  align-items: center;
  gap: 32px;
  height: 100%;
  padding: 0 48px;
}
.right-group { display: flex; justify-content: flex-end; align-items: center; gap: 32px; min-width: 0; }
.mark { letter-spacing: .32em; margin-right: -.32em; transform-origin: center; }

The two outer columns are equal, so the middle one sits in the true centre. A flex row with space-between does not do this: with three links on the left and two links plus a button on the right, the wordmark drifts.

The scroll switch, throttled to one frame:

const bar = document.getElementById('bar');
const THRESHOLD = 80;
let ticking = false;
function update() {
  bar.classList.toggle('solid', window.scrollY > THRESHOLD);
  ticking = false;
}
addEventListener('scroll', () => {
  if (!ticking) { requestAnimationFrame(update); ticking = true; }
}, { passive: true });
update();

Call update() once on load so a page restored mid-scroll starts solid.

The state styles:

.bar { height: var(--bar-h); color: var(--on-dark); background: rgba(244,239,228,0);
  border-bottom: 1px solid rgba(247,242,232,.18);
  transition: height var(--dur) var(--ease), background-color var(--dur) var(--ease),
              color var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.bar.solid { height: var(--bar-h-solid); background: var(--paper); color: var(--ink); border-bottom-color: var(--line); }
.mark { transition: transform var(--dur) var(--ease); }
.bar.solid .mark { transform: scale(.6); }
.bar.solid .cta { border-color: var(--green); color: var(--green); }

Use rgba(244,239,228,0) as the start colour, not transparent. Some engines fade transparent through grey.

Common mistakes:

  • Centring the wordmark with position: absolute; left: 50% and letting links slide under it at 1024px.
  • Animating font-size on the wordmark, which reflows the row 20 times during the move.
  • Forgetting margin-right: -0.32em, so a tracked wordmark sits a few pixels left of centre.
  • Putting the hero under the bar with a top margin. The hero starts at 0 and the bar floats over it.
  • Leaving ivory text in the solid bar, or dark text over the hero, for one frame on load.
  • A drop shadow on the solid bar. The hairline is the separation.
  • Using a photo for the hero. This piece draws it in CSS.
  • Five links on one side and none on the other. Split them so each side reads as a group.
  • A filled button. On a luxe site the reserve action is outlined until hover.

Rebuild order:

  1. Build the fixed header with the three-column grid.
  2. Place three links, the wordmark, two links and the button.
  3. Build the green hero at 100vh with the arches and sun.
  4. Add the solid class styles and the scroll listener.
  5. Add the sections below so the page scrolls.
  6. Add the 1180 and 900 breakpoints and the menu panel.
  7. Check focus rings in both states.
  8. Turn on reduced motion and confirm the switch is instant.

Details

Palette
Type
Cormorant Garamond · Jost
Motion
Subtle motion
Build
One session
Designed bySusan AcharyaKathmandu

Studied

Lama Lama

A tiny nav bar can carry the voice. Change its one line for each section.

All sources

On the shelves