Skip to main content
Back to Portfolio

Hillcrest Architects

A photography-led WordPress portfolio for a fictional PNW architecture practice — every image cropped to a plate ratio and served as AVIF, WebP and JPEG across six widths, on an image pipeline that replaces core’s outright.

WordPressPHP 8.3ReactGutenbergFull-Site Editingtheme.jsonAVIF / WebPImagickPlaywrightAWS EC2
Hillcrest Architects preview

Overview

A fictional twelve-person architecture practice on Bainbridge Island, rebuilt in 2026 against a full external design system. The question it answers is narrower than "can WordPress do design sites", and more useful: can it serve photographs as well as a purpose-built portfolio platform can.

The design system is the printed architectural monograph. Paper ground, one rationed weathering-steel accent, a high-contrast serif that only ever appears large, and photographs numbered as plates — PL. 04, an italic caption, a hairline. Two themes ship, paper and plate, both designed; the accent flips lightness between them, so three tokens exist solely for the inverted band.

Every image is a Plate. There is no thumbnail, no avatar, no icon illustration and no second image component. A Plate is cropped to one of five aspect ratios and nothing else, carries a number and a describing caption, and is revealed by a clip-path wipe from its bottom edge while the image inside settles from scale(1.06). It never fades. Where a photograph does not exist yet, it renders a well at the correct ratio saying Photography forthcoming — no stock image, no grey mountain.

The image pipeline replaces WordPress's.

add_image_size() generates every registered size for every attachment, so declaring five plate ratios would cut each photograph five ways and discard four of them. And wp_get_attachment_image() emits one format and one srcset; there is no <picture> in core at all.

So each plate carries its own ladder — six widths in AVIF, WebP and JPEG, recorded in attachment meta and deleted with the attachment. The page emits a <picture> with a sizes string computed from the real column arithmetic rather than guessed, explicit dimensions on every image, lazy loading below the fold, and a rel=preload for whichever plate is that page's largest contentful paint.

AVIF needed a host change — the box had only GD, which cannot encode it. Measured afterwards against a 1200px crop: AVIF q60 is 85.6 KB at SSIM 0.9691, WebP is 86.8 KB at 0.9584, JPEG q82 is 152.4 KB at 0.9719. AVIF beats WebP outright and costs 44% fewer bytes than JPEG for the same eye.

Two failures that would have shipped silently.

WP_Image_Editor::save() re-derives the default quality whenever the output format differs from the source format, so a quality set with set_quality() beforehand is discarded — which is exactly how an AVIF ladder ends up larger than the WebP one it exists to beat, and is what the first measurement showed.

And image_editor_output_format is keyed on the requested output format rather than the source. The theme wants jpeg => webp for its media-library thumbnails; without an exemption by filename, that map turns save( 'x-pl1200.jpg', 'image/jpeg' ) into a WebP file named x-pl1200.webp. The JPEG fallback tier of every <picture> on the site would have quietly ceased to exist, with no error and no symptom on any modern browser.

The crops are the designer's own. The handoff shipped ten WebP derivatives at the plate ratios, but downscaled — the wrong thing to encode from. Rather than re-crop by eye, each was matched against the full-resolution master by sliding a window of its aspect across the image and scoring normalised cross-correlation on a grayscale proxy. All ten matched at 0.9995 or better.

Where the reference broke its own contract, it was fixed and said so. The hero fixes itself at 21:9 with overflow: hidden and puts the firm name inside it — at 400px that box is 171px tall and the type needs about 250, so the approved page loses the first line of its own headline. The ratio became a floor rather than a fixed height. And the wash under that type measured 1.5:1 against the photograph behind it; it is now a flat 80% that clears 4.5:1 for all three type colours against a pure white frame.

The Challenge

Architecture firms are pointed at Squarespace, Cargo or Framer, and for a ten-project studio that is often right. The argument weakens at forty projects, each with a gallery, a spec table and a narrative that a practice manager must maintain — but the thing those platforms are genuinely better at is images, and that is precisely where WordPress is worst out of the box: one format, one srcset, and a media library full of sub-sizes nobody asked for.

The Solution

Replace core’s image path rather than working around it. Each plate carries its own ladder — six widths in three formats, generated from a master already cropped to one of five ratios, with a sizes attribute derived from the real layout and a preload for the page’s LCP. The result is measured rather than asserted: 607 design-system checks run against the live site in a committed browser harness.

Results

  • 607 automated checks pass against the live site — six pages at three widths in both themes, plus the plate pipeline in bytes, layout shift, reduced motion, JavaScript disabled, keyboard-only operation, the palette’s contrast contract, and a structural diff against the approved reference pages

  • Lighthouse accessibility, best practices and SEO 100 on all six pages; cumulative layout shift 0

  • Every line of type over a photograph clears 4.5:1 against the brightest pixel in its own bounding box — measured by redrawing the composite to a canvas, not assumed from a token

  • AVIF at 44% fewer bytes than JPEG for equivalent SSIM, after adding the Imagick binding the host was missing

  • Complete pages with JavaScript disabled and under reduced motion — the reveal mask is only applied after a script adds a class, so no image ever ships clipped to nothing

  • Six case studies written, where the previous version had one and five rows reading “forthcoming”

  • Four platform-level gotchas into the shared guide, two of them silent-failure classes in core’s own image editor

Gallery

Hillcrest Architects screenshot 2
Hillcrest Architects screenshot 3
Hillcrest Architects screenshot 4

Interested in working together?

Let's discuss how I can help with your project

Get in Touch