# Hero, two covers

> An opening built from two identical photograph frames side by side with a hairline gutter between them. The left frame carries an opaque plate with the eyebrow, the headline and the one action; the right frame carries nothing at all. Both covers include replaceable example photographs. States no colour and no font of its own. Ships with a short hand-off row on your theme's paper below it, so the opening reads as a section and not the page.

Canonical: https://patternpaste.com/pattern/hero-two-covers.html
Section: Hero
Access: Included in Pattern Paste access.
Needs: Requires a block theme on WordPress 7.0 to 7.1. Classic themes and page builders are outside our supported setup. Adaptive patterns use the block theme’s colour, spacing and typography presets; styled variations declare their own colours or type.
Blocks: button, buttons, column, columns, cover, group, heading, paragraph
Keywords: hero, cover, two up, diptych, photo, opening, plate

## Variations (3)

### Loaded left (the default)

Identical markup in every theme.

Two 32rem frames at 50/50 under a 30% veil of your contrast colour, the plate set into the left frame's bottom corner and the right photograph carrying no text or plate. Below 782 the frames stack and the frame with the plate comes first.

### Loaded right

Identical markup in every theme.

The composition mirrors: the frame with the plate moves to the right and the plate to its bottom-right corner, so the section reads right to left. The photograph without a plate opens the row instead. Nothing about the colour or the type changes.

### Ink plate

Identical markup in every theme.

The plate inverts: your contrast as the ground, your base as the type, and the button inverts with it. The two frames, the veil and the composition are untouched, so this is the colour move on its own.


---

## The signature moment: density contrast

Two frames of identical size, weight and colour, one loaded and one empty, so
the eye is told where to go by density alone rather than by scale, position or
colour. The emptiness of the right frame is the design, not a slot waiting to
be filled: it is what makes the plate in the left frame read as the thing to
read. **Resist adding a caption to the right frame.** A label there balances
the two halves, and the moment they are balanced the section is a 50/50 photo
row with some text in it, which is the competent-and-forgettable failure this
catalogue exists to avoid.

## What it inherits, what it decides

Inherits: every colour (the plate is `base` with `contrast` type, the veil is
`contrast` at 30%, the button is `contrast` with `base` type), the typeface,
the spacing scale. Decides: the 50/50 split, the 32rem frame height, the
gutter, the plate's 27rem measure and its padding, and the type ramp on the
plate (a 13px tracked eyebrow at 0.22em, a headline from 28px to 44px at 1.05
line-height and -0.025em, one button sized by padding rather than by a font
size).

Each cover states its own `style.color.text` as a `base` chain, so core's
`:where(.wp-block-cover:not(.has-text-color))` rule, which would otherwise
paint everything inside a cover a literal `#fff`, never fires.

## Two photographs, not one

This is the one thing to know before the buyer starts. The pattern holds two
covers, and it only works when they are two DIFFERENT photographs: one that
can carry a plate over its corner and one that is worth looking at with
nothing on it at all. Both the preview and copied markup include two different stills for that reason. Choose Replace on each cover to select your images, then use the focal-point tool to adjust their crops.

## Type never sits on a photograph

Every word in this pattern is on the plate, whose ground is a `base` chain and
whose type is a `contrast` chain, so the contrast is measured as an
ordinary guaranteed pair rather than as type on an image. A photograph's
luminance is unknowable and the buyer swaps it anyway; the veil over both
frames is decoration and may recede without loss.

## The button carries no `typography`

Sized by padding only. A `core/button` with a `typography` attribute does not
stay valid across editor versions, and nothing about the render gives it away.

## Below 782

Core stacks the columns, so the two frames become two full-width bands. In the
base the loaded frame is first in source order, which is what a phone should
open with. In **Loaded right** the empty frame comes first, which is the
ordinary picture-then-text order on a phone and is the price of the mirror;
the mirror is a desktop composition and it says so.

## Variations

- **Loaded right** (`covers-swapped`): the composition mirrors. The loaded
  frame becomes the right one, its plate moves to the bottom-right corner
  through `contentPosition: "bottom right"` and a constrained wrapper with
  `justifyContent: right`, and the empty frame opens the row. One axis:
  composition. Colour and type are untouched.
- **Ink plate** (`ink-plate`): the colour move on its own, by inversion. The
  plate becomes `contrast` ground with `base` type, and the button inverts
  with it so it stays legible on the new ground. Inversion between `base` and
  `contrast` is the only colour move that arrives in every theme; `base-2` is
  plain white in both Twenty Twenty-Four and Twenty Twenty-Five. The frames,
  the veil and the layout are identical to the base.

## The hand-off row

Two full-bleed frames on their own fill the preview on this page edge to edge,
and on a buyer's page the opening is never alone. So the pattern ships with
what comes next: a short row on your theme's paper under the frames, a tracked
label at a fixed 12rem and one paragraph at a 34rem measure, in a wrapping
flex row so the label does not break in two on a phone. It is ordinary page
copy and it is the first thing a buyer rewrites or deletes.

## Why the loaded frame has a fluid inset

The frames are full-bleed and the hand-off row below them is a constrained band
at `1240px`, so the two are sized by different things: past about 1350 the band
stops filling the window and starts centring its column, while a
`contentPosition` plate goes on being positioned against the cover's own
full-bleed edge. Measured at 1280 and 1920 in Twenty Twenty-Five, the plate's
text and the hand-off copy started 250px further apart at the wider window;
mirrored in **Loaded right**, where the plate is pinned to the opposite page
edge and the row is not, the drift was 353px, the largest in the catalogue.

The fix is on the loaded cover only, as
`padding-left: max(0rem, min(100%, 50vw) + 0.5rem - 660px)` (`padding-right` in
the mirror). `660px` is the band's half-column, `620px`, plus the plate's own
`2.5rem` padding, and the `0.5rem` is half the gutter, so the plate's text
lands on the same column edge the copy below it does. It is `0` at and below
1280, which is the width this catalogue is authored at, so nothing about the
1280 rendering moves and the plate is still flush into the frame's corner
there; the `min(100%, 50vw)` term keeps it `0` below 782 as well, where core
stacks the columns and `100%` becomes the whole page. No CSS, no class: it is
one length on one block, and a theme that never gets that wide never sees it.

## Why the height is in rem

`minHeight` is `32rem`, never a `vh` value. The preview on this page sizes its
frame to the pattern, and a viewport-relative height would size the pattern to
the frame in turn, a loop that only ever shrinks.

## Measured

The cover's markup was checked on WordPress 7.0: the element
order the two covers are authored in, the `has-background-dim-30` class that a
`dimRatio` of 30 emits, and `isUserOverlayColor`. Columns-level
`verticalAlignment` is deliberately absent here: it does nothing on the front
end, and with two frames of equal height there is nothing to align.

## Included images

The copied markup includes WordPress Photo Directory example photographs. The public image URLs
keep the examples visible after pasting. Select an image or cover and choose
**Replace** to use your own Media Library files. See [image credits](/image-credits/)
for the sources and licenses. Pasting an image URL does not import a Media Library
attachment.
