Blocks / Marketing
Site header
A marketing site header: a note about what is new, the brand, a mega menu and two actions, folding when narrow.
Install
Writes the block to components/blocks/site-header.tsx and its .css, and every part it uses to components/equip/, with the parts those are built from.
npx https://equip.studio311.app/equip.tgz add block:site-headerBuilt from 5 parts
Notes
- The NavMenu goes in the TopBar nav slot with orientation="auto", so under 640px of the bar's own width it folds into the menu panel as a list of full-width rows.
- Below about 384px Sign in leaves the bar and appears at the foot of the folded menu, through TopBar's foldedActions, so the brand and Start free keep their room.
- maxWidth="76rem" on the TopBar lines its contents up with the page column; the border and background still span the window.
- skipTo points at #main: give your page's main element that id, or change it.
- The note above the bar is a status Banner; keep it to one short line and point its action at a real page.
Source
components/blocks/site-header.tsx94 lines
import { Badge } from "@/components/equip/badge";
import { Banner, BannerAction } from "@/components/equip/banner";
import { Button } from "@/components/equip/button";
import { NavMenu, NavMenuItem, NavMenuLink, NavMenuSection } from "@/components/equip/nav-menu";
import { TopBar } from "@/components/equip/top-bar";
import "./site-header.css";
/*
* The top of a marketing site: a thin note about what is new, then the bar with the brand,
* a mega menu and the two ways in. Under 640px of its own width the menu folds behind a button.
*/
export default function SiteHeader() {
return (
<div className="blk-site-header">
<Banner className="blk-site-header-strip" align="center">
<span className="blk-site-header-strip-line">
<Badge tone="ok" dot>
New
</Badge>
<span>
Supplier price alerts
<span className="blk-site-header-strip-more">, so a dearer case of butter never surprises you at the invoice</span>
</span>
<BannerAction href="#changelog">Read the changelog</BannerAction>
</span>
</Banner>
<TopBar
className="blk-site-header-bar"
skipTo="#main"
maxWidth="76rem"
brand={
<a href="#top">
<svg viewBox="0 0 24 24" width="22" height="22" aria-hidden="true" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<path d="M7 4h10" />
<path d="M8 4v2.5a3 3 0 0 1-1.5 2.6A3 3 0 0 0 5 11.7V18a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-6.3a3 3 0 0 0-1.5-2.6A3 3 0 0 1 16 6.5V4" />
<path d="M5 13h14" />
</svg>
Larder
</a>
}
nav={
<NavMenu aria-label="Main" orientation="auto">
<NavMenuItem label="Product">
<NavMenuSection title="Count" className="blk-site-header-col">
<NavMenuLink href="#stock-counts" icon="clipboard-check" title="Stock counts" description="Count a walk-in in ten minutes, on a phone." />
<NavMenuLink href="#sales-sync" icon="receipt" title="Sales sync" description="Every dish sold takes its ingredients off the shelf." />
<NavMenuLink href="#waste-log" icon="trash" title="Waste log" description="Bin it, log it, see what it cost." />
</NavMenuSection>
<NavMenuSection title="Order" className="blk-site-header-col">
<NavMenuLink href="#supplier-orders" icon="truck" title="Supplier orders" description="Built from your par levels, sent before cut-off." />
<NavMenuLink href="#price-alerts" icon="bell" title="Price alerts" description="Told when a supplier puts a price up." />
<NavMenuLink href="#deliveries" icon="package" title="Delivery check-in" description="Tick off each line as it comes through the door." />
</NavMenuSection>
<NavMenuSection title="Learn" className="blk-site-header-col">
<NavMenuLink href="#guides" icon="book-open" title="Kitchen guides" description="Par levels, dish costing and stock rotation." />
<NavMenuLink href="#dish-costing" icon="percent" title="Dish costing" description="Know a plate's margin before it goes on the menu." />
<NavMenuLink href="#help" icon="life-buoy" title="Help centre" description="Answers, and a person when you need one." />
</NavMenuSection>
</NavMenuItem>
<NavMenuItem label="Customers">
<NavMenuSection title="By kitchen" className="blk-site-header-col">
<NavMenuLink href="#restaurants" icon="utensils" title="Restaurants" description="From 30 covers to a busy Saturday of 200." />
<NavMenuLink href="#bakeries" icon="flame" title="Bakeries" description="Flour, butter and the 4am bake list." />
<NavMenuLink href="#cafes" icon="coffee" title="Cafes" description="Milk, beans and the pastry case." />
</NavMenuSection>
<NavMenuSection title="Stories" className="blk-site-header-col">
<NavMenuLink href="#story-marrow" icon="store" title="Marrow, Hackney" description="Waste down from 6% to 3% in one winter." />
<NavMenuLink href="#stories" icon="newspaper" title="All customer stories" description="Forty kitchens on what changed." />
</NavMenuSection>
</NavMenuItem>
<NavMenuItem label="Pricing" href="#pricing" />
<NavMenuItem label="Changelog" href="#changelog" />
</NavMenu>
}
foldedActions={
<Button href="#sign-in" variant="outline" className="blk-site-header-panel-sign-in">
Sign in
</Button>
}
actions={
<>
<Button href="#sign-in" size="s" variant="ghost" className="blk-site-header-sign-in">
Sign in
</Button>
<Button href="#start" size="s" variant="accent">
Start free
</Button>
</>
}
/>
</div>
);
}components/blocks/site-header.css50 lines
@layer blocks {
.blk-site-header {
container: blk-site-header / inline-size;
background: var(--eq-surface);
color: var(--eq-ink);
}
/* The note above the bar (a Banner with align="center"): one line that wraps politely, its pieces
centred on each line, never a second banner's worth. */
.blk-site-header-strip-line {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: var(--eq-space-1) var(--eq-space-3);
text-align: center;
}
.blk-site-header-strip-more {
display: none;
}
/* Three columns of 13.5rem sit side by side inside the panel's 720px limit. */
.blk-site-header-col {
flex-basis: 13.5rem;
inline-size: 13.5rem;
}
/* The copy of Sign in in TopBar's foldedActions, shown only once the one on the bar is hidden. */
.blk-site-header-panel-sign-in {
display: none;
}
/* Very narrow: Sign in moves off the bar and into the folded menu, so brand and Start free keep their room. */
@container blk-site-header (width < 24rem) {
.blk-site-header-sign-in {
display: none;
}
.blk-site-header-panel-sign-in {
display: inline-flex;
}
}
@container blk-site-header (width >= 40rem) {
.blk-site-header-strip-more {
display: inline;
}
}
}