section-028

Client Proof Sheet

Vault only: not sold separatelyGet the Vault

A clients and logos section printed like a two-ink riso proof: a ruled sheet of client wordmarks where each marked case re-inks a live halftone photo and its story from the side you picked it.

advanced
8 more details
canvashalftoneduotoneinterruptible-transitionsprogressive-enhancementkeyboard-navigationcontainer-queriesresponsive-section

This section reads better at your own screen size than in the frame below:

Released

About this section

Client Proof Sheet Section shows who a business has worked with and what it made for a few of them. The client wordmarks sit in one ruled grid on a saturated yellow stock, like a print proof with registration marks at its corners, under a heading set large enough to act as the section's structure. Clients with a case carry a case number; picking one prints that case into the proof beside the logos.

Read the full section overview

The proof is the signature. The case photograph is screened live on a canvas into two halftone plates at different screen angles, fluorescent pink for the mid-tones and black for the shadows, overprinted on the paper colour. Each new selection lifts the ink from the current print and re-inks the next one in a wave that starts from the logo you picked, with the black plate landing a beat late and out of register before it settles. The copy plate carries the client's wordmark, a one-line proof of the work, what was made and a link.

The fictional Tandem Press, a design and riso print studio, shows twelve clients and five cases with generated photographs. Everything is ordinary markup: a list of clients, each with a logo image, a sector, a link and an optional case. Counts, case numbers and the proof's navigation all come from that list, and without JavaScript every case reads in full beneath its logo.

Client Proof Sheet - website section preview

What's included

10 items
  • Ruled logo sheet on a committed riso palette: yellow stock, fluorescent pink spot ink, black key ink
  • Live two-plate halftone of each case photo on canvas, screened at two angles with auto levels
  • Re-inking wave that starts from the chosen logo, with a late, misregistered black plate that settles
  • Rapid picks, reversal mid-print and prev/next all settle on the last choice
  • Case numbers, count and navigation derived from the client list; empty cells fill the last row
  • Twelve fictional wordmarks supplied as plain SVG files, replaceable with any logo image
  • Readable fallback without JavaScript: every case written out with a duotone photo
  • Keyboard, touch and reduced-motion support, live status for screen readers
  • Container-query layout from a wide proof beside the logos to a phone column
  • Independent instances, root-scoped brand variables and exact teardown

Perfect for

4 use cases
  • Design studios, printers and agencies showing clients alongside the work
  • Freelancers and small practices with a handful of case studies among many clients
  • Venues, festivals and publishers listing partners and what they did together
  • Any client or partner logo wall that needs to say more than a row of logos

How it works

3 sections

The client list is the source of truth. The script reads every client and every case from the markup, adds a picker button to each case cell and builds the proof in the space the grid reserves for it. A small boot snippet reserves that space before first paint, so nothing jumps when the script mounts, and hands the page back to the readable list if the script never runs.

For each case the photograph is drawn once, cover-cropped at its focus point, into a small sampling canvas. Its luminance is stretched to full range and turned into two rotated grids of dots: a pink plate whose dots grow with every mid-tone and a black plate that only prints the shadows. Both are drawn with multiply blending on the paper colour. A single GSAP tween drives print progress; each dot's place in the wave is its distance from the chosen logo, and it lands with a small overshoot. The black plate follows the pink and slides into register as it settles.

A selection during a print lifts the ink from wherever it has reached, and a selection while the ink is lifting or a photo is loading only changes the target, so any burst of input ends on the last choice. Reduced motion swaps instantly, including when the preference changes while the section is mounted. If the photo's pixels cannot be read, the proof keeps a flat duotone photo instead.

Difficulty Advanced
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Vault only

Get the Vault to use this section.

The Vault includes Client Proof Sheet, the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate. Sections are available only in the Vault for now while the collection is small.

Documentation

Quick Start

Files to copy:

Code snippet omitted: it ships with the download.

  1. Load the fonts, the stylesheet, GSAP and the script:

Code snippet omitted: it ships with the download.

  1. Copy everything between CLIENT PROOF SHEET SECTION: EXTRACT START and EXTRACT END in index.html: the small boot <script> and the <section class="cps">. The boot script reserves the proof's space before first paint so the grid does not jump when the section mounts; if the main script never runs it hands the page back to the plain list after four seconds. Keep it directly before the first section on the page (one copy serves every instance).

Everything outside that block in index.html (the page background and <main>) is demo furniture.

No build step. GSAP core only, no plugins. The section does not install smooth scrolling or pin anything.

Make it yours

Clients

Each client is one <li data-cps-client> in <ul data-cps-list>, in display order:

Code snippet omitted: it ships with the download.

  • Logo: src, alt (the client's name; it is also used for the picker label and the "Visit" link) and the image's own width/height so its space is reserved. Any SVG, PNG or WebP works. Logos are shown in one colour on the paper, so a single-colour dark logo on a transparent background reads best.
  • Sector: a short plain label under the logo.
  • Link: the client's site. Without a case, the whole cell is the link; with a case, the link moves into the proof as "Visit ".

Add, remove or reorder <li> elements freely. The count in the intro (data-cps-count, written as a word up to twenty), the case numbers, the "Case 01 / 05" counter and prev/next all follow the list. When the client count does not fill the last row, hatched blank cells complete it. Keep role="list" on the <ul> and role="listitem" on each <li>: the list is laid out with display: contents, and the roles keep it announced as a list.

Cases

Put a <div data-cps-case> inside any client to make it a case:

Code snippet omitted: it ships with the download.

The first case in the list opens first. One case works (prev/next hide); a sheet with no cases is a plain logo grid. Five or six cases suit the desktop proof; the proof line reads best under about twelve words.

Photographs

Each case photo is an ordinary <img> in the case's <figure>:

File Source size Shown as
assets/img/records.webp, cinema.webp, bookfair.webp, lido.webp, climbing.webp 1400 x 933 (3:2) Portrait-ish crop beside the copy on desktop, 4:3 on phones

To replace one, point src at your own photo, update width, height and alt, and set the focal point with --cps-focus on the <figure> (x% y%, as for object-position). Any aspect ratio works; the proof crops to cover. Choose photos with clear lights and darks: they are printed as halftone, so tonal shape matters more than colour. srcset on the image is copied to the proof as well.

The halftone reads the photo's pixels, so photos must be served from the same origin as the page (or with CORS headers and crossorigin="anonymous"). If they cannot be read, for example when opened from file://, the proof shows the photo as a flat pink duotone instead.

Brand variables

Set these on .cps (or on one section's style to brand only that instance):

Variable Default Role
--cps-paper #ffe23b Ground and the halftone's paper
--cps-ink #161412 Type, rules and the black plate
--cps-spot #ff4fa7 Spot plate, selected cell, offset shadows
--cps-font-display Sofia Sans Extra Condensed Heading, proof line, footer line
--cps-font-body Familjen Grotesk Body copy
--cps-font-label IBM Plex Mono Small labels
--cps-max 1480px Maximum sheet width
--cps-pad clamp(16px, 3.6vw, 56px) Side padding
--cps-rule 2px Grid rule weight
--cps-row clamp(150px, 13.5vw, 200px) Logo cell height
--cps-tx, --cps-ty 0.035em, 0.022em Pink plate offset under display type

A rebrand example, pale blue stock with orange and navy inks:

Code snippet omitted: it ships with the download.

The halftone reads the three colours when it prints, so it follows the variables. Keep text contrast in mind: --cps-ink carries all small text on --cps-paper and on --cps-spot, and pink or orange spot colours are only used for large or decorative marks.

Behaviour and options

  • data-dot="6" on the section: halftone dot pitch in px. Narrow proofs use a finer pitch automatically.
  • Picking a case lifts the current print and re-inks the next one in a wave from the picked logo (prev/next start from the proof's left or right edge). The black plate lands late, out of register, and settles. Rapid picks and picks during a print always end on the last choice.
  • On a single-column layout, picking a case scrolls the proof into view.
  • The heading's pink plate drops into register once when the section is first seen.

Script API, one per page:

Code snippet omitted: it ships with the download.

Tune timings and the print look at the top of assets/script.js (CPS_PRINT_TIME, CPS_KEY_LAG, CPS_MISREG_START, the tone constants).

Accessibility and integration

  • The heading is an <h2>; case proof lines are <h3>. Change the tags freely: styles use classes.
  • Case pickers are real buttons with aria-pressed and aria-controls; the proof is a labelled region with a polite live status ("Showing Low Tide Records, case 1 of 5"). The halftone canvas is hidden from assistive technology; the photo's alt stays in the proof.
  • Keyboard: Tab to any logo, Enter or Space to show its case; prev/next buttons in the proof.
  • Reduced motion: cases swap instantly and the heading does not move, including when the preference changes while mounted.
  • Without JavaScript, or if GSAP fails to load, every case is written out in full under its logo with a duotone photo.
  • The layout follows its own container width (container queries), so it works in narrow columns as well as full width. It needs no fixed height and scrolls with the page.
  • Tested in Chromium at desktop, laptop, 390px phone and a 440px host column, with a hostile host stylesheet and two instances on one page.

Dependencies and credits

  • GSAP 3 core (free, standard GSAP licence).
  • Fonts from Google Fonts under the SIL Open Font Licence: Sofia Sans Extra Condensed, Familjen Grotesk, IBM Plex Mono.
  • Client wordmarks in assets/logos/ are fictional, built for this demo from glyph outlines of OFL Google Fonts (Rubik Mono One, DM Serif Display, Shrikhand, Bungee, Staatliches, Monoton, Alfa Slab One, Righteous, Italiana, Abril Fatface, Bagel Fat One, Archivo Black) and Ultra (Apache 2.0). They are placeholders: replace them with your clients' own logos.
  • Case photographs are AI-generated concept images of fictional places and people, created for this demo. They do not document real clients or real work.

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.