# masthead

A full-bleed **editorial masthead** — a gradient band carrying an oversized
Newsreader serif title, an uppercase kicker, a subtitle, and an optional row of
stat "barometers". The front-page treatment (vs the plain `page-header`),
distilled from home.gf.cx's Almanac into a **static, reusable** form — no
weather, no day/night paint JS, no countdown logic.

- **Live:** https://assets.gf.cx/masthead/
- **CSS:** https://assets.gf.cx/masthead/masthead.css

## Use

```html
<link rel="stylesheet" href="https://assets.gf.cx/masthead/masthead.css">

<header class="masthead masthead--warm">
  <div class="masthead__inner">
    <div class="masthead__kicker">
      <span>seo.gf.cx</span><span class="where">center of excellence</span>
    </div>
    <h1 class="masthead__title">SEO — a Center of <em>Excellence</em></h1>
    <p class="masthead__sub">Practical SEO, kept in the open — used, not admired.</p>
    <div class="masthead__stats">
      <div class="stat"><span class="stat__val">3</span><span class="stat__lbl">domains tracked</span></div>
      <div class="stat stat--accent"><span class="stat__val">1</span><span class="stat__lbl">playbook live</span></div>
      <div class="stat"><span class="stat__val">4</span><span class="stat__lbl">pillars</span></div>
    </div>
  </div>
</header>
```

Place it as the **first child of `<body>`**, before the centred `<main>`. The
band is full-bleed via `margin: 0 -100vw` — the host page **must** set
`html, body { overflow-x: clip; }` or the break-out triggers a horizontal
scrollbar (the "page very wide" bug). The `.stat` row is optional; drop it for a
plain masthead.

## Classes

| Class | Role |
| --- | --- |
| `.masthead` | the full-bleed gradient band (cool Almanac sky by default) |
| `.masthead--warm` | sage→paper gradient — a warmer, distinct band |
| `.masthead--dark` | for **dark** surfaces — the top stop lifts off the page's own `--bg` toward a cool slate (a gentle glow, not a pale wash); also softens `--mh-line`. Inks adapt via the surface's tokens |
| `.masthead--tight` | smaller title clamp for shorter surfaces |
| `.masthead--compact` | slim band (reduced height + title) for second-level **record** pages — composes with `--warm` |
| `.masthead--duo` | **two-colour** band — a light cool sky (`--duo-cool`, #cdd9df) blends to a light warm honey glow (`--duo-warm`, #ffe4af) melting into paper (status.gf.cx/triage treatment). Knobs: `--duo-cool` / `--duo-warm` / `--duo-angle` (98deg) / `--duo-grain` (0 = off). Shares the `--duo-*` family with almanac's `.sky-wash--duo`, so one set of knobs re-skins both. Keep text ink dark and any accent in a readable gold — the honey is a band glow only (fails AA). First surface: abbeyroad.gf.cx/future/ |
| `.masthead__inner` | the centred column — matches the page measure (`--mh-measure`, default 760px) |
| `.masthead__kicker` | uppercase letterspaced label; `.where` = muted second clause |
| `.masthead__title` | oversized Newsreader serif; `<em>` = italic accent; add `.upright` for the restrained serif voice |
| `.masthead__sub` | one muted subtitle line |
| `.masthead__stats` | the "barometer" row — flex-wrap of `.stat` |
| `.stat__val` / `.stat__lbl` | big serif number (`.u` for a unit) · uppercase label |
| `.stat--accent` | colour that stat's number with `--accent` (e.g. the "live" one) |

## Tokens

Reads the design-system tokens, each with a hex fallback, so it inherits the
surface's `:root`: `--serif --sans --accent --ink --ink-soft --line --bg`.
Tune the band per surface with `--mh-top` / `--mh-bot`, and the column width
with `--mh-measure`.

| Knob | Default | Role |
| --- | --- | --- |
| `--mh-top` / `--mh-bot` | cool sky → `--bg` | the band's gradient stops |
| `--mh-measure` | `760px` | the centred column width (match the page measure) |
| `--mh-sub-lines` | `0` (off) | **reserve the subtitle to N lines** — the way to equalise a *set* of mastheads |
| `--mh-title-lines` | `0` (off) | **reserve the title to N lines** — the sibling of `--mh-sub-lines` for when titles *also* vary in wrap across the set |
| `--mh-min-h` | `0` (off) | a blunt band-height floor — the cruder alternative to the line-reserve knobs |

## Equalising a set of mastheads (the sticky-rail fix)

The band is **content-sized**: a page with a shorter subtitle (fewer wrap lines)
gets a shorter band. Across a *set* of pages that share a **sticky left rail**
(e.g. the four pillars of a Center of Excellence), that means the rail rests at a
different Y page-to-page and the nav appears to "jump" as you move between pages.

Fix it by reserving the variable element — the subtitle — to the set's
**maximum** line-count, so every page's *content* fills its band to the same
height:

```css
.masthead { --mh-sub-lines: 3; }   /* set to the tallest subtitle in the set */
```

When the **title** varies in wrap too (some pages 1 line, some 2), reserve both
— each to the set's max — so the whole content column, not just the subtitle,
fills to equal height:

```css
.masthead { --mh-sub-lines: 5; --mh-title-lines: 2; }
```

This equalises by **content**, not by box: the bands match (rail aligned) *and*
no page floats high with dead space below its stats. `--mh-min-h` floors the
band height too, but it's blunt — it equalises the band while leaving a
short-content page's text floating with a gap at the band's foot. Reach for
the line-reserve knobs first; keep `--mh-min-h` for the rare case where the
varying element is neither the title nor the subtitle. (seo.gf.cx's four pillars
use `--mh-sub-lines: 3`; abbeyroad's 15 `/future` pages use
`--mh-sub-lines: 5` + `--mh-title-lines: 2`.)

The principle, surface-agnostic:
[patterns.gf.cx/equal-bands-for-a-shared-rail](https://patterns.gf.cx/equal-bands-for-a-shared-rail/).

## Lineage

The static distillation of home.gf.cx's Almanac masthead (`.sky` band +
barometers). The Almanac keeps its bespoke day/night `paintSky()` + weather;
everything reusable lives here.
