Canonical site header — rollout sketch
Date: 2026-05-15
Companion to: feedback_canonical_site_header.md (the principle, parked 2026-05-08); your post-lunch sketch
Scope: dare.co.uk first; pattern portable to dogwood.house + audreyinc.com afterwards
The bar you drew
Reading the screenshot:
| Element | Spec |
|---|---|
| Wordmark | dark, bold sans (Helvetica system stack), left-aligned |
| Kicker | grey, regular weight, ~14px, inline-right of wordmark, vertically baseline-aligned |
| Right-nav | three links, regular weight, active link bolded, no underline, ~15px tracking |
| Ground | dare cream (#fdfaf0 or thereabouts — sample from the canonical archive header) |
| Rule | 1px horizontal line under header, ~70% cream-on-cream (faint, not black) |
| Padding | generous vertical (~28px each side), generous horizontal (~5% margin) |
Visual reference
Desktop — canonical (the bar you sketched)
Cream ground, wordmark + kicker baseline-aligned left, three-mode nav right with active link in bold rather than colour. Quiet, editorial.
Mobile — homepage (showing how the header sits over the hero)
Header collapses to wordmark + hamburger on narrow viewports. Hero copy — “A playbook for brave business” with the red italic-accent on brave, lede “Methods, culture, and field notes from the people who choose courage over consensus — and design futures worth defending” — is the manifesto register the brand-voice four pillars memory has been pointing at. The header doesn’t fight it.
Mobile — Field Notes archive (showing the canonical archive template)
Same wordmark, three-mode nav (visible because the nav fits at this width). Below the bar: red caps kicker, italic-accent H1 “Field notes”, lede paragraph, “FEATURED · CURATED HIGHLIGHTS” strip. The header is one component of a larger canonical template, not a standalone element — the rollout actually needs to think about the whole vertical strip (header + kicker + H1 + lede + featured strip), not just the bar.
What the visual reference tells us beyond the sketch
Three observations the images surface that the text-only sketch missed:
- The nav is three modes. Methods · Culture · Field Notes. About + Contact move to footer entirely. Observations and the topical verticals (cinema, architecture, photography, etc.) nest under the IA rather than appearing in the top nav.
- Active state is weight, not colour. Bold weight only — keeps the red strictly as an accent (used for italic-Newsreader kickers + the hero
<em>only). - The header is the top of a template, not a standalone bar. Phase 4 of the rollout (the patcher) needs to slot into a canonical vertical strip — header + kicker + H1 + lede — not just replace
<header>in isolation. That changes the patcher’s design: it’s a template applier, not a bar applier. - The header is a decoupled code block. Single source of truth at
templates/_header.html; every page renders the same snippet; future evolution touches one file. Replaces today’s per-page drift entirely.
Open questions for post-lunch resolution
One open question for you to settle pre-implementation:
The wordmark on this sketch reads “Product X”. The CLAUDE.md flag from 2026-05-06 still says: “index.html wordmark reads ‘Product X’ while JSON-LD Organization.name is ‘DARE’.” This sketch is a forcing function — what’s the wordmark in production going to be? Three candidates: - DARE (per
feedback_dare_brand_spelling— body-copy entity ref) - dare+ (the logomark perfeedback_dare_brand_voice_four_pillars— but body copy stays DARE caps) - Something the post-lunch reassessment surfacesWhichever wins becomes the canonical wordmark in this header.
The kicker “Playbook for Business” is also new — is that the positioning you’re trying on, or sample text? It reads well, especially against the four-mode IA.
The page taxonomy
dare.co.uk has six distinct page templates today. The header rolls out per template:
| Template | Count | Current header state |
|---|---|---|
Homepage (/) |
1 | Custom hero, no nav bar |
| Article (migrated post template) | 668 | WP-era chrome variant or post-migration variant, drifts |
| Archive grid (methods/culture/field-notes section roots) | 3 | Has canonical-style header today (the model you screenshotted) |
| Section index (cinema/architecture/photography/books/people/brands/observations/future-media/industrial-design/user-interface) | 10 | Built this morning; varies — some have the canonical header, some are partial |
| Policy (privacy/anti-spam/dmca) | 3 | Plain — no header bar |
Contact (/contact/) |
1 | Plain — no header bar |
Sitemap (/sitemap/) |
1 | Plain |
Approx 687 pages to touch. Half of them already migrated through the article template, which means: patch the template once, re-migrate to retrofit. The other half are bespoke.
The plumbing — audit then patch
Two scripts, same shape as dare_404_audit.py / dare_url_resolution_audit.py:
dare_header_audit.py
Walks every */index.html, fingerprints the <header>...</header> block (or its absence), groups by variant. Output: a markdown report listing every distinct header variant + count of pages on each + sample URLs.
Mock output:
Variant A (canonical, the screenshot) : 3 pages (the archive grids)
Variant B (legacy WP chrome with site logo) : 412 pages (Tier-1 migrations from 2026-05-06)
Variant C (sparse migrated, no nav) : 256 pages (long-tail Haiku migrations)
Variant D (no header) : 16 pages (policy + contact + sitemap)
The audit makes the drift visible. Today it would surface that the archive grids are already canonical and the 668 articles vary by migration tier.
dare_header_patch.py
Reads the canonical header block from a single source-of-truth file (templates/_header.html in the repo). For each page, replaces the existing <header> with the canonical block, slotting in per-page values:
- Active nav highlight: which of methods/culture/field-notes (or none) gets
aria-current="page"styling - Kicker line (optional): article title sometimes shows in the kicker slot, sometimes the section name
- Skip for: pages explicitly opted out (e.g., the homepage, which has its own hero)
Idempotent (running twice is a no-op). Dry-run default. Backs up before overwriting (per CLAUDE.md). Re-runs after a template change to propagate.
Drift prevention
Once the rollout is at variant-A-only, add dare_header_audit.py to the daily cron alongside dare_404_audit.py. It surfaces a non-zero variant count the moment a new template diverges. Cheaper than catching it three months later when twenty bespoke pages have drifted independently.
Rollout sequence
| Phase | Scope | Risk | Effort |
|---|---|---|---|
| 0 | Settle wordmark + kicker copy (your call after lunch) | Editorial | 5 min |
| 1 | Write templates/_header.html — the canonical block, slot-marked |
Low | 15 min |
| 2 | Build dare_header_audit.py — surface today’s variant landscape |
Low | 30 min |
| 3 | Patch the article template in dare_migrate_articles.py so all future migrations bake in the canonical header |
Low | 20 min |
| 4 | Build dare_header_patch.py — dry-run against the 668 articles, review diff on 5 random pages, full-apply |
Medium — touches 668 files; commit in 5-section batches so any visual bug is bounded | 90 min |
| 5 | Hand-patch the bespoke pages (homepage, policy, contact, sitemap) — each is a one-off decision about whether the header belongs | Low | 30 min |
| 6 | Re-run audit. Expected: variant-A-only across all pages. | — | 5 min |
| 7 | Add audit to daily cron, alongside 404 audit | Low | 10 min |
Total: ~3.5 hours of focused work, split across two or three sessions. Phase 0-2 are this afternoon if you want.
What’s portable to dogwood and audrey
The pattern, not the contents. Each brand keeps its own:
templates/_header.html(different wordmark, different kicker, different nav)dogwood_header_audit.py/audrey_header_audit.py(same script, different--repo+--siteflags — if we generalise to oneportfolio_header_audit.py --site dare|dogwood|audrey, even better)- A canonical block per brand, derived from the brand-voice memories
The discipline is the same: audit, patch, prevent drift. The content is brand-specific. That’s the services-1.0 split.
For dogwood specifically, this matters more than for dare — dogwood is service-business, the header carries trust signals (phone, “book a visit” CTA), and inconsistency reads as unprofessional in ways that don’t apply to a 20-year archive site.
What this tells us
The reason “consistent header” feels harder than it should is that there’s no single source of truth today — each page is its own copy. Whichever sub-tree was migrated when has whichever header was current then. The canonical pattern exists in the archive grids (3 pages), and everything else is drift away from it.
The senior move: stop trying to keep things consistent by hand. Build the substrate (templates/_header.html + the audit + the patcher) and run it. After phase 6, “consistent” is a property of the build pipeline, not something requiring human discipline.
Watch items
- The migration script’s article template is the highest-leverage edit — touch it once, every future migration is correct. Don’t skip Phase 3 just because Phase 4 is more visible.
- Big-batch patching across 668 files is the riskiest phase. The 5-section commit cadence in Phase 4 is non-negotiable — if a CSS bug ships, the blast radius needs to be bounded.
- Mobile breakpoint isn’t sketched here. The desktop bar collapses to a hamburger or a stacked logo+nav on narrow screens; that pattern needs to be in the canonical block from day one, not retrofitted later.
Recommendations
- Settle Phase 0 in writing today — wordmark + kicker decision. Without it the canonical block can’t be authored.
- Run Phase 2 (audit) before Phase 4 (patch) — see the actual variant landscape on the current site before assuming what’s there. The audit output is also the artefact you’d want in a future client case-study about brand-system rollouts.
- Treat this as the dare-toolkit’s next compounding asset — the audit+patch pair is reusable for any element that should be canonical but drifts (footers, JSON-LD blocks, meta-description templates, OG image patterns). Once one of these audit+patch pairs exists, the next is a copy-and-modify.
Consistency without a substrate is unstable. Build the substrate, then consistency is a property, not a chore.


