Nav Bars
Nav with announcement bar
Dismissible notice sitting above the header
Dismissible notice sitting above the header
Create a two-tier site header with Tailwind CSS. The top tier is a neutral-900 announcement bar with centred small text carrying a bold label pill, a sentence about a release, an inline underlined link with an arrow, and a dismiss cross positioned at the right edge. The second tier is the main nav on white with a hairline bottom border: a wordmark, a centre group of five links where one carries a small green "New" badge, and a right group with a search glyph button, a "Sign in" text link and a dark rounded button. Make the whole header sticky as one unit so both tiers scroll together. Then add JavaScript that removes the announcement bar when the cross is clicked, remembers the dismissal in localStorage under a versioned key so a new announcement can reappear, and restores the hidden state on load before paint. <div id="siteHeader" class="sticky top-0 z-40">
<div id="announceBar" class="relative bg-neutral-900 px-10 py-2.5 text-center text-sm text-neutral-200">
<span class="mr-2 rounded-full bg-white px-2 py-0.5 text-[11px] font-medium text-neutral-900">v4.2</span>
Query caching is on for every plan — median dashboards now load in under 400ms.
<a href="#" class="ml-1 font-medium text-white underline underline-offset-4">Read the notes <svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="M14 4h6v6M20 4l-9 9"/><path d="M18 13v6a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6"/></svg></a>
<button id="announceClose" class="absolute right-4 top-1/2 -translate-y-1/2 rounded-md p-1 text-neutral-400 transition hover:bg-neutral-800 hover:text-white" aria-label="Dismiss announcement"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><path d="M6 6l12 12M18 6 6 18"/></svg></button>
</div>
<header class="border-b border-neutral-200 bg-white/90 backdrop-blur">
<div class="mx-auto flex h-16 max-w-6xl items-center justify-between px-6">
<a href="#" class="text-lg font-semibold tracking-tight text-neutral-900">Meridian</a>
<nav class="hidden items-center gap-7 text-sm text-neutral-600 lg:flex">
<a href="#" class="transition hover:text-neutral-900">Platform</a>
<a href="#" class="transition hover:text-neutral-900">Integrations</a>
<a href="#" class="flex items-center gap-1.5 transition hover:text-neutral-900">
Workflows <span class="rounded-full bg-green-100 px-1.5 py-0.5 text-[10px] font-medium text-green-700">New</span>
</a>
<a href="#" class="transition hover:text-neutral-900">Pricing</a>
<a href="#" class="transition hover:text-neutral-900">Docs</a>
</nav>
<div class="flex items-center gap-3">
<button class="grid h-9 w-9 place-items-center rounded-lg text-neutral-500 transition hover:bg-neutral-100 hover:text-neutral-900" aria-label="Search"><svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" class="inline-block h-[1em] w-[1em] shrink-0 align-[-0.125em] transition-transform"><circle cx="11" cy="11" r="7"/><path d="m16 16 4 4"/></svg></button>
<a href="#" class="hidden text-sm text-neutral-600 transition hover:text-neutral-900 sm:block">Sign in</a>
<a href="#" class="rounded-xl bg-neutral-900 px-4 py-2 text-sm font-medium text-white transition hover:bg-neutral-800">Start free</a>
</div>
</div>
</header>
</div> // Bump the key when the message changes so a dismissal does not silence the next one.
var KEY = "announce:v4.2";
var bar = document.getElementById("announceBar");
var close = document.getElementById("announceClose");
try {
if (localStorage.getItem(KEY) === "dismissed") bar.remove();
} catch (e) {
// Private mode or blocked storage — showing the bar is the safe fallback.
}
close.addEventListener("click", function () {
bar.remove();
try {
localStorage.setItem(KEY, "dismissed");
} catch (e) {}
});