Nº 398 of 520
Section-tagline nav pill
A dark floating nav pill whose centre tagline rolls to a new cheeky line per section, opens into a menu drawer, and sits beside a stack of collapsible cards.
Preview
Use it
Free to use · credit appreciated1 Once, in your project
npx skills add SusanAcharya/Design-Lounge 2 Then ask
Using the Design Lounge skill, build "Section-tagline nav pill" (piece navbar-section-tagline-pill) 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.
<!-- Design Lounge Nº 398 · "Section-tagline nav pill" · designlounge.vercel.app -->
# Section-tagline nav pill
> **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
Studied from lamalama.com: the small dark nav bar fixed at top centre whose middle text changes to a different cheeky line for each section you scroll into. The hamburger expands the same bar into a menu, and a column of small dark "( + )" cards in the top-right corner open in place. This rebuild is for **Brightwork**, a fictional product studio, on a pale stone page. The pill is 440×48px with a pixel logo, a mono caps tagline, and a burger. As each section crosses the middle of the viewport, the tagline rolls up and the next one rolls in from below ("Let's break something nice" → "Receipts, not promises" → "How the lights stay on" → "People who came back" → "Your move"). The detail worth copying is that the menu is the pill itself growing (grid-rows 0fr → 1fr), not a separate overlay, and it marks the section you are in.
## Reference behaviour
1. First frame: a stone page `#E4E6E1` showing the hero. "[ BRIGHTWORK / PRODUCT STUDIO ]" sits over a 104px heavy headline "Interfaces with a pulse, built by people who answer the phone." with "pulse" on a lime highlight. Below it, a lede and "SCROLL — THE PILL KEEPS UP".
2. The pill is fixed 14px from the top, centred, 440×48, `#111311`, radius 6. Left: a 22px pixel logo (link to top). Centre: the tagline "LET'S BREAK SOMETHING NICE" in 11px mono caps. Right: a 40px burger.
3. The right stack is fixed 14px from the top and right, 220px wide, with 4px gaps: a lime "MV · BOOK A CALL WITH MIRA" link, a dark "STUDIO REEL ( + )" card, and a dark "HOW WE WORK ( + )" card.
4. Scrolling: an IntersectionObserver with `rootMargin: -45% 0px -50% 0px` picks the section crossing the middle band. When the section changes, the old tagline translates −110% and fades, and the new one starts at +110% and slides to 0 (420ms expo-out, opacity 300ms). The old node is removed after 440ms.
5. Burger click: the burger's lines morph into a single minus (outer bars collapse onto the middle, 240ms). The pill's drawer opens (grid-template-rows 0fr → 1fr, 420ms expo-out) and shows five 44px rows (Home 00, Work 01, Services 02, Clients 03, Contact 04) and two buttons, "BOOK A CALL" (outline) and "START A PROJECT" (lime). The page behind gets a veil, 28% ink with a 10px backdrop blur, fading in over 320ms.
6. The row for the current section shows a 6px lime square instead of its number and carries `aria-current="true"`. Focus moves to that row 120ms after opening.
7. The drawer closes on Escape (focus returns to the burger), a veil click, a row click (which also jumps to the anchor), or the burger again. Tab and Shift+Tab cycle inside the pill while it is open.
8. Stack card click: the card's body opens (grid-rows 0fr → 1fr, 380ms expo-out), and the sign reads "( – )". "Studio reel" shows a 118px striped preview with a lime sheen sweeping every 2.6s and the caption "01:12 · 2026 CUT". "How we work" shows three numbered lines. The cards open independently.
9. Work rows on the page: name, black mono chips, "( + )". Hovering a row nudges the name 8px right (240ms expo-out).
10. Reduced motion: the tagline swaps instantly, the drawer and cards open without transition, the reel sheen stops, and smooth scroll is off.
## Structure
```
1280 × 800 viewport, page scrolls
┌──────────── pill 440×48, top 14, r6 ─────────────┐ ┌ stack 220w ──────┐
│ ▙▘ LET'S BREAK SOMETHING NICE ☰ │ │■ BOOK A CALL … │ lime 44
├─────────────────────────────────────────────────┤ │STUDIO REEL ( + )│ 44
(open only) │ Home 00 │ │HOW WE WORK ( + )│ 44
│ Work 01 │ └──────────────────┘
│ Services ■ │ ← current
│ Clients 03 │
│ Contact 04 │
│ [ BOOK A CALL ] [ START A PROJECT ] │ 40px, 8px pad
└─────────────────────────────────────────────────┘
[ BRIGHTWORK / PRODUCT STUDIO ]
Interfaces with a ▓pulse▓, built by 104px / .9 / 800
people who answer the phone.
… 157 more lines. Copy or download for the full brief. Loading the source…Brief
197 linesBuild 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
Studied from lamalama.com: the small dark nav bar fixed at top centre whose middle text changes to a different cheeky line for each section you scroll into. The hamburger expands the same bar into a menu, and a column of small dark ”( + )” cards in the top-right corner open in place. This rebuild is for Brightwork, a fictional product studio, on a pale stone page. The pill is 440×48px with a pixel logo, a mono caps tagline, and a burger. As each section crosses the middle of the viewport, the tagline rolls up and the next one rolls in from below (“Let’s break something nice” → “Receipts, not promises” → “How the lights stay on” → “People who came back” → “Your move”). The detail worth copying is that the menu is the pill itself growing (grid-rows 0fr → 1fr), not a separate overlay, and it marks the section you are in.
Reference behaviour
- First frame: a stone page
#E4E6E1showing the hero. ”[ BRIGHTWORK / PRODUCT STUDIO ]” sits over a 104px heavy headline “Interfaces with a pulse, built by people who answer the phone.” with “pulse” on a lime highlight. Below it, a lede and “SCROLL — THE PILL KEEPS UP”. - The pill is fixed 14px from the top, centred, 440×48,
#111311, radius 6. Left: a 22px pixel logo (link to top). Centre: the tagline “LET’S BREAK SOMETHING NICE” in 11px mono caps. Right: a 40px burger. - The right stack is fixed 14px from the top and right, 220px wide, with 4px gaps: a lime “MV · BOOK A CALL WITH MIRA” link, a dark “STUDIO REEL ( + )” card, and a dark “HOW WE WORK ( + )” card.
- Scrolling: an IntersectionObserver with
rootMargin: -45% 0px -50% 0pxpicks the section crossing the middle band. When the section changes, the old tagline translates −110% and fades, and the new one starts at +110% and slides to 0 (420ms expo-out, opacity 300ms). The old node is removed after 440ms. - Burger click: the burger’s lines morph into a single minus (outer bars collapse onto the middle, 240ms). The pill’s drawer opens (grid-template-rows 0fr → 1fr, 420ms expo-out) and shows five 44px rows (Home 00, Work 01, Services 02, Clients 03, Contact 04) and two buttons, “BOOK A CALL” (outline) and “START A PROJECT” (lime). The page behind gets a veil, 28% ink with a 10px backdrop blur, fading in over 320ms.
- The row for the current section shows a 6px lime square instead of its number and carries
aria-current="true". Focus moves to that row 120ms after opening. - The drawer closes on Escape (focus returns to the burger), a veil click, a row click (which also jumps to the anchor), or the burger again. Tab and Shift+Tab cycle inside the pill while it is open.
- Stack card click: the card’s body opens (grid-rows 0fr → 1fr, 380ms expo-out), and the sign reads ”( – )”. “Studio reel” shows a 118px striped preview with a lime sheen sweeping every 2.6s and the caption “01:12 · 2026 CUT”. “How we work” shows three numbered lines. The cards open independently.
- Work rows on the page: name, black mono chips, ”( + )”. Hovering a row nudges the name 8px right (240ms expo-out).
- Reduced motion: the tagline swaps instantly, the drawer and cards open without transition, the reel sheen stops, and smooth scroll is off.
Structure
1280 × 800 viewport, page scrolls
┌──────────── pill 440×48, top 14, r6 ─────────────┐ ┌ stack 220w ──────┐
│ ▙▘ LET'S BREAK SOMETHING NICE ☰ │ │■ BOOK A CALL … │ lime 44
├─────────────────────────────────────────────────┤ │STUDIO REEL ( + )│ 44
(open only) │ Home 00 │ │HOW WE WORK ( + )│ 44
│ Work 01 │ └──────────────────┘
│ Services ■ │ ← current
│ Clients 03 │
│ Contact 04 │
│ [ BOOK A CALL ] [ START A PROJECT ] │ 40px, 8px pad
└─────────────────────────────────────────────────┘
[ BRIGHTWORK / PRODUCT STUDIO ]
Interfaces with a ▓pulse▓, built by 104px / .9 / 800
people who answer the phone.
Product design and front-end … SCROLL — THE PILL KEEPS UP
header.pill(fixed) holdsdiv.bar(a.logo,div.tag[aria-hidden]with onespan,button.burger[aria-expanded][aria-controls=drawer]) anddiv.drawer#drawer. Inside the drawer:nav[aria-label=Main] > ul.menu > li > a[data-s]anddiv.ctaswith two links.div.veilis a fixed full-screen layer under the pill (z 15 vs 20).aside.stack[aria-label="Quick links"]holdsa.calland twodiv.card[data-open], each with abutton[aria-expanded][aria-controls]anddiv.body.mainholdssection[id][data-tag]: top, work, services, clients, contact. Each is at least 92vh tall (the hero 100vh) with a 1px bottom rule.
Tokens
:root {
--bg: #E4E6E1; /* page */
--ink: #111311; /* page text, chips */
--ink-2: #4A4F4A; /* labels, lede */
--line: #C9CCC5; /* page rules */
--pill: #111311; /* pill, cards */
--pill-2: #1E211E; /* row and burger hover */
--pill-line: #2C302C; /* rules inside pill and cards */
--on-pill: #E9ECE6; /* text on pill */
--on-pill-2: #8E958D; /* row numbers, ( + ) signs */
--lime: #C8F04A; /* primary CTA, current marker, highlight, focus */
--sans: "Schibsted Grotesk", system-ui, sans-serif;
--mono: "IBM Plex Mono", ui-monospace, monospace;
--r: 6px; --pad: 32px;
--ease: cubic-bezier(.2,.7,.2,1);
--expo: cubic-bezier(.16,1,.3,1);
}
Fixed sizes: pill 440×48, bar padding 0 6px 0 14px, burger 40×40, menu rows 44px with 22px inset, CTA buttons 40px, stack 220px wide with 44px card heads and 4px gaps.
Typography
| Role | Family | Size | Weight | Line-height | Tracking | Case |
|---|---|---|---|---|---|---|
| Tagline, labels, chips, CTAs, card heads | IBM Plex Mono | 11px | 500 | 1 | 0.08em | Upper |
| Menu rows | Schibsted Grotesk | 15px | 400 | 44px row | 0 | Title |
| Hero headline | Schibsted Grotesk | 104px | 800 | 0.9 | −0.045em | Sentence |
| Section statement | Schibsted Grotesk | 40px | 500 | 1.12 | −0.02em | Sentence |
| Work row name | Schibsted Grotesk | 22px | 500 | 1.45 | 0 | Title |
| Contact headline | Schibsted Grotesk | 96px | 800 | 0.9 | −0.045em | Sentence |
| Manifesto lines | Schibsted Grotesk | 13px | 400 | 1.35 | 0 | Sentence |
Motion
| Thing | Trigger | Property | From → to | Duration / easing | Reduced motion |
|---|---|---|---|---|---|
| Tagline out | section change | translateY, opacity | 0 → −110%, 1 → 0 | 420ms expo / 300ms | instant replace |
| Tagline in | section change | translateY, opacity | 110% → 0, 0 → 1 | 420ms expo / 300ms | instant |
| Drawer | burger | grid-template-rows | 0fr ↔ 1fr | 420ms expo | instant |
| Burger → minus | burger | ::before / ::after translateY, opacity | ±5px → 0, 1 → 0 | 240ms --ease | instant |
| Veil | burger | opacity (blur 10px fixed) | 0 ↔ 1 | 320ms --ease | instant |
| Menu row hover | hover / focus | padding-left, background | 22 → 28px | 240ms expo / 160ms | instant |
| Stack card | click | grid-template-rows | 0fr ↔ 1fr | 380ms expo | instant |
| Reel sheen | loop | left | −40% → 110% | 2.6s --ease infinite | none |
| Work row name | hover | translateX | 0 → 8px | 240ms expo | instant |
States
- Burger resting: three 16×1.5px bars. Hover:
--pill-2square behind. Open: a single bar (minus),aria-expanded="true", label “Close menu”. - Menu row resting:
--on-pilltext, number in--on-pill-2. Hover and focus:--pill-2fill, 6px extra indent. Current section: the number is replaced by a 6px lime square,aria-current="true". - CTAs: outline (1px
--pill-line) and lime fill. Hover: brightness 1.1. - Stack card closed: ”( + )”. Open: ”( – )”,
aria-expanded="true", body visible. - Focus-visible: 2px lime outline, 2px offset, 4px radius. Lime reads on both the dark pill and the stone page.
- Veil open: the page under it does not receive clicks except to close.
Accessibility
- The pill is a
header. The menu links are insidenav[aria-label="Main"], in the drawer, so they are only in the tab order when open. Collapsed rows have zero height andoverflow: hidden. For a stricter build, addinertto the drawer when closed. - The burger is a
buttonwitharia-expanded,aria-controls="drawer", and anaria-labelthat toggles between “Open menu” and “Close menu”. - On open, focus goes to the current section’s row. While open, Tab cycles inside the pill. Escape closes and returns focus to the burger.
- The tagline is decorative flavour and
aria-hidden. The current section is conveyed byaria-currenton the menu row. - Stack cards are disclosure buttons (
aria-expanded,aria-controls). The ”( + )” sign isaria-hidden. - Contrast:
#E9ECE6on#111311is about 16:1,#8E958Don#111311about 6:1, ink on lime about 15:1, and ink on stone about 15:1. - Targets: burger 40×40, rows 44px, CTAs 40px, card heads 44px.
Responsive rules
- ≥1280: as specified.
- 1024: the same. The stack still fits beside the pill (440 + 220 + gutters).
- ≤900: the stack hides. Move “Book a call” into the drawer CTAs, which already have it. The hero headline is 64px, the contact headline 60px, and the grids go to two columns. Work rows drop their chips.
- ≤520: the pill spans the width with 12px insets (
left: 12px; right: 12px; width: auto),--padis 16px, the headline 44px, the statement 28px, services one column. - The tagline never wraps. It is a single line in a 14px-tall clipping box. Keep taglines under about 30 characters so they fit the 440px pill.
Acceptance checklist
Always
- One fixed pill, top centre, with a logo, a single-line tagline, and a burger.
- The tagline changes only when a different section crosses the middle band. The old line rolls up and the new one rolls in from below.
- The menu is the pill growing (grid-rows 0fr → 1fr), not a separate full-screen overlay.
- The current section is marked in the menu with
aria-currentand a visual marker that is not just colour. - Escape, veil click, and row click close the menu. Focus returns to the burger on Escape.
- Focus is trapped in the open pill.
- Stack cards are independent disclosures with
aria-expandedand a ”( + )” / ”( – )” sign. - The page behind the open menu is veiled and blurred.
- Reduced motion removes every transition and the sheen loop.
- No horizontal overflow at 375px.
This demo
- The pill is 440×48,
#111311, radius 6, 14px from the top. - Taglines: “Let’s break something nice” / “Receipts, not promises” / “How the lights stay on” / “People who came back” / “Your move”.
- Menu rows: Home 00, Work 01, Services 02, Clients 03, Contact 04, 44px each.
- CTAs: “BOOK A CALL” outline and “START A PROJECT” lime
#C8F04A. - The stack is 220px wide: “BOOK A CALL WITH MIRA” (lime), “STUDIO REEL ( + )”, “HOW WE WORK ( + )”.
- The headline is Schibsted Grotesk 800 at 104px, with “pulse” highlighted lime.
Implementation notes
1. Roll the tagline with two spans. Never animate a single node’s text. Insert the next span below, force a reflow, then move both.
function setTag(text) {
if (current.textContent === text) return;
const next = document.createElement('span');
next.textContent = text; next.className = 'below';
box.appendChild(next);
next.offsetWidth; // commit the start position
current.classList.add('above');
next.classList.remove('below');
const old = current; setTimeout(() => old.remove(), 440);
current = next;
}
.tag { height: 14px; overflow: hidden; position: relative; }
.tag span { position: absolute; inset: 0 0 auto; transition: transform 420ms var(--expo), opacity 300ms var(--ease); }
.tag .below { transform: translateY(110%); opacity: 0; }
.tag .above { transform: translateY(-110%); opacity: 0; }
2. Section detection with a thin middle band. rootMargin: '-45% 0px -50% 0px' leaves a 5% strip just above centre, so exactly one section intersects at a time and short sections still register.
3. Grow the pill with grid rows. Animating height: auto does not work. A one-row grid going from 0fr to 1fr, with an overflow: hidden child, animates to the content’s real height.
.drawer { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 420ms var(--expo); }
.pill.open .drawer { grid-template-rows: 1fr; }
.drawer > div { overflow: hidden; }
Common mistakes:
- Making the menu a full-screen takeover. The point is the small bar becoming the menu.
- Updating the tagline on every scroll event instead of on section change.
- Long taglines that wrap or get cut with an ellipsis. Write them short.
- Rounding the pill to a full capsule. It is a 6px-radius bar.
- Leaving drawer links focusable while closed (zero height but still tabbable). Use the open state or
inert. - Blurring the page without dimming it. The 28% ink veil is what makes the menu read.
Details
- Palette
- Type
- Schibsted Grotesk · IBM Plex Mono
- Motion
- Subtle motion
- Build
- One session
- Tags
Studied
Lama LamaA tiny nav bar can carry the voice. Change its one line for each section.
All sources