Content Blocks thatsadam Design System

thats adam
ACF Flexible Content

All case study pages are assembled from these reusable blocks via ACF Pro flexible content. Each block is a self-contained PHP template with scoped CSS. Editors choose from the block palette in WordPress — no code needed.

Text Block

3-column asymmetric grid. Label + heading in column 1, body copy spans columns 2–3. Forces reading hierarchy — the label anchors the section, the body breathes right.

Research findings

User needs shape every decision

Through twelve stakeholder interviews and two rounds of usability testing, we identified three core user needs that shaped the entire design direction and validated our initial assumptions.

Anatomy

  1. Header (col 1) — label-s + heading-m
  2. Body (col 2–3) — text-l, tertiary colour, spans two columns

ACF Fields

  • labeltextSection eyebrow
  • headingtextSection heading
  • bodytextareaMain copy (large, tertiary)
<section class="acf-block acf-text-block">
  <div class="acf-text-block__header">
    <p class="acf-block__label">Research findings</p>
    <h2 class="acf-block__heading">User needs shape every decision</h2>
  </div>
  <div class="acf-text-block__body">
    <p>Through twelve stakeholder interviews and two rounds of usability testing, we identified three core user needs.</p>
  </div>
  <!-- Optional button -->
  <div class="acf-text-block__actions">
    <a href="/report.pdf" class="btn btn-secondary" target="_self">Read the report</a>
  </div>
</section>

Text Plus

4-variant flexible text block. Layout controlled by an ACF select field. Covers bullet lists, image+text, and body-only compositions.

Variant: --bullets

Approach

How we work

A structured process that moves from broad research to focused delivery.

  • Discovery & stakeholder interviews
  • Synthesis and affinity mapping
  • Prototyping and testing

Variant: --no-image

Context

The brief

A fast-growing logistics startup needed a delivery tracking interface that worked equally well for dispatchers on desktop and couriers on mobile, without a separate codebase.

Variant: --image-left

Image

Process

Mapping the journey

We mapped every touchpoint across the end-to-end delivery experience to identify friction points and prioritise redesign effort.

Variant: --image-right

Outcome

Final solution

A unified responsive interface that reduced dispatcher errors by 34% and cut courier training time in half.

Image

Anatomy

  1. bullets — Two-column bullet grid, no image
  2. no-image — Header col left (1fr), body right (2fr)
  3. image-left — 50/50 grid, image left
  4. image-right — 50/50 grid, image right

ACF Fields

  • layoutselectbullets / no-image / image-left / image-right
  • labeltext
  • headingtext
  • bodywysiwygRich text, supports lists + links
  • imageimageRequired for image-left/right
  • bullet_itemsrepeaterFor bullets layout
<!-- --bullets -->
<section class="acf-block acf-text-plus acf-text-plus--bullets">
  <div class="acf-text-plus__header">
    <p class="acf-block__label">Approach</p>
    <h2 class="acf-block__heading">How we work</h2>
  </div>
  <div class="acf-text-plus__body-bullets">
    <div class="acf-text-plus__body"><p>A structured process that moves from broad research to focused delivery.</p></div>
    <ul class="acf-text-plus__bulletlist">
      <li>Discovery &amp; stakeholder interviews</li>
      <li>Synthesis and affinity mapping</li>
    </ul>
  </div>
</section>

<!-- --no-image -->
<section class="acf-block acf-text-plus acf-text-plus--no-image">
  <div class="acf-text-plus__header">…</div>
  <div class="acf-text-plus__body"><p>…</p></div>
</section>

<!-- --image-left (swap the two children for --image-right) -->
<section class="acf-block acf-text-plus acf-text-plus--image-left">
  <div class="acf-text-plus__image"><img src="journey-map.jpg" alt="Journey map"></div>
  <div class="acf-text-plus__content">
    <p class="acf-block__label">Process</p>
    <h2 class="acf-block__heading">Mapping the journey</h2>
    <div class="acf-text-plus__body"><p>…</p></div>
  </div>
</section>

Large Pull Quote

Full-bleed centred typographic statement. Used sparingly — once per case study — to mark a key finding or design principle. The text size itself communicates importance.

Good design is as little design as possible.

— Dieter Rams

Anatomy

  1. Quote text — text-5xl, fw-black, centered, primary colour
  2. Attribution — text-m, fw-semibold, uppercase, secondary colour

ACF Fields

  • quotetextThe quote text
  • attributiontextName / source
<section class="acf-pull-quote">
  <div class="acf-pull-quote__inner">
    <p class="acf-pull-quote__text">Good design is as little design as possible.</p>
    <p class="acf-pull-quote__attr">— Dieter Rams</p>
  </div>
</section>

Flow Diagram

Alternating left/right task cards with JS-drawn right-angle SVG connector lines (8px radius corners). Visualises user journeys, service blueprints, or process flows.

Discovery

Define the problem space through stakeholder interviews and competitive analysis.

Define

Synthesise research into opportunity areas and a clear design brief.

Deliver

Ship tested, production-ready designs with full developer handoff documentation.

Anatomy

  1. Row — 2-column grid; left → col 1, right → col 2
  2. Card — 106px circle (image or number) + title + body
  3. Connector — JS-drawn SVG path, stroke: primary-30, 8px corners

ACF Fields

  • labeltext
  • headingtext
  • descriptiontextHalf-width intro description
  • stepsrepeaterstep_title, step_body, step_image, side (left/right)
<section class="acf-block acf-flow">
  <div class="acf-flow__header">
    <p class="acf-block__label">Process</p>
    <h2 class="acf-block__heading">From brief to launch</h2>
  </div>
  <p class="acf-flow__description">Optional intro text.</p>

  <div class="acf-flow__track">
    <div class="acf-flow__row acf-flow__row--left">
      <article class="acf-flow__card">
        <div class="acf-flow__img-wrap acf-flow__img-wrap--number" aria-hidden="true">
          <span class="acf-flow__number">01</span>
        </div>
        <div class="acf-flow__text">
          <h3 class="acf-flow__title">Discovery</h3>
          <p class="acf-flow__body">Define the problem space through stakeholder interviews.</p>
        </div>
      </article>
    </div>

    <!-- Connector between steps; JS sets the path from data-from / data-to -->
    <div class="acf-flow__connector acf-flow__connector--left" aria-hidden="true" data-from="25" data-to="75">
      <svg width="100%" height="80" xmlns="http://www.w3.org/2000/svg">
        <path stroke="currentColor" stroke-width="2" fill="none"/>
      </svg>
    </div>

    <div class="acf-flow__row acf-flow__row--right">
      <article class="acf-flow__card">…</article>
    </div>
  </div>
</section>

Table Block

Structured data table with optional row images and bullet lists per cell. Horizontally scrollable on mobile. Used for competitive analysis, feature matrices, and research data.

Feature That's Adam Competitor A Competitor B
Responsive design
Full Partial None
Dark mode
Token-driven None Manual
Design system
  • Figma source
  • CSS tokens
  • Living docs
Style guide only None

Note: first column header renders at text-xl in red; first column cells render in red, uppercase, semibold. Subsequent columns are grey.

Anatomy

  1. Column headers — text-l, fw-black, tertiary grey; first-child: text-xl, red secondary
  2. Row label (col 1) — semibold, red secondary, uppercase, 4px tracking; flex row with optional 150×150px image
  3. Data cells — text-m, tertiary; bullet lists use custom red square marker (no disc)
  4. table-layout: fixed — equal column widths enforced
  5. Mobile — overflow-x: auto, table-layout reverts to auto, min-width 300px per cell

ACF Fields

  • labeltext
  • headingtext
  • columnsrepeatercolumn_heading
  • rowsrepeaterrow_label, row_image, cells (sub-repeater: cell_content, cell_bullets)
<section class="acf-block acf-table-block">
  <div class="acf-table-block__header">
    <p class="acf-block__label">Competitive analysis</p>
    <h2 class="acf-block__heading">How the options compare</h2>
  </div>
  <div style="overflow-x:auto;">
    <table class="acf-table">
      <thead>
        <tr><th>Feature</th><th>That's Adam</th><th>Competitor A</th></tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <div class="acf-table__label-cell">
              <img class="acf-table__row-img" src="row.jpg" alt="Design system">   <!-- optional -->
              Design system
            </div>
          </td>
          <td><ul class="acf-table__bullets"><li>Figma source</li><li>CSS tokens</li></ul></td>
          <td>Style guide only</td>
        </tr>
      </tbody>
    </table>
  </div>
</section>

Screen Mockups

Displays 1–4 screen images with blue drop-shadow glow. PNG exports with transparent backgrounds are required for the glow to work correctly. Supports captions and bullet annotations.

Final screens

Delivered solution

Screen

Dashboard view

Screen

Detail view

Anatomy

  1. Glow — filter: drop-shadow(0 0 24px var(--lightbox-img-shadow))
  2. Container — No overflow:hidden — glow must bleed outside bounds
  3. Images — object-fit: contain (not cover) to preserve frame shape

ACF Fields

  • labeltext
  • headingtext
  • layoutselectdefault / split-meta
  • imagesrepeaterimage, caption, bullets
<section class="acf-block acf-screen-mockups acf-screen-mockups--rounded">
  <div class="acf-screen-mockups__header">
    <p class="acf-block__label">Final screens</p>
    <h2 class="acf-block__heading">Delivered solution</h2>
  </div>
  <div class="acf-screen-mockups__meta acf-screen-mockups__meta--split">
    <div class="acf-screen-mockups__desc"><p>Optional description.</p></div>
    <ul class="acf-screen-mockups__bullets"><li>Optional bullet</li></ul>
  </div>
  <div class="acf-screen-mockups__images acf-screen-mockups__images--scrollable">
    <div class="acf-screen-mockups__item" style="width:198px;">   <!-- 418px tall × the image's ratio -->
      <div class="acf-screen-mockups__mockup">
        <img src="dashboard.png" alt="Dashboard view" style="aspect-ratio:432/911;" loading="lazy">
      </div>
      <p class="acf-screen-mockups__caption">Dashboard view</p>
    </div>
  </div>
</section>

User Interviews

Editorial full-width rows, one per participant. The quote is the typographic hero — extralight italic at clamp scale. Ghost sequence numbers are oversized and purely decorative.

SJ
Sarah Johnson Senior Product Manager
The handoff between design and development was always where things broke down — I needed a designer who understood both sides.

Insights

  • Cross-functional communication
  • Design-dev handoff pain
  • Need for process clarity

Anatomy

  1. Ghost number — absolute right:-0.05em; clamp(120px,22vw,220px); fw-black; red; opacity 0.07; z-index 0
  2. Photo — 240×240px; border-radius:12px; object-position:50% 20% (face-favoured); initials fallback: red fw-black clamp(2rem,5vw,4rem)
  3. Name — `.heading-m` class; primary colour
  4. Role — text-m; fw-semibold; tertiary; uppercase; ls-label-xl (6px)
  5. Quote — clamp(text-xl,3.5vw,2.4rem); fw-extralight; italic; primary; max-width:78ch; ls-heading; lh-xl
  6. Insights label — fw-semibold; secondary red; uppercase; ls-label-xl
  7. Chips — column flex; pill border (surface-branding-primary-30, radius 100px); tertiary text; mobile: flex-wrap row

ACF Fields

  • labeltext
  • headingtext
  • descriptiontextHalf-width intro
  • interviewsrepeaterparticipant_name, participant_role, participant_photo, quote, insights (sub-repeater: insight_text)
<section class="acf-block ui-block">
  <header class="ui-block__header">
    <p class="acf-block__label">Research</p>
    <h2 class="acf-block__heading">What users told us</h2>
  </header>
  <p class="ui-block__description">Optional intro text.</p>
  <div class="ui-block__entries">
    <article class="ui-entry">
      <div class="ui-entry__inner">
        <span class="ui-entry__seq" aria-hidden="true">01</span>
        <div class="ui-entry__main">
          <div class="ui-entry__photo">
            <span class="ui-entry__initials">SJ</span>   <!-- or <img> -->
          </div>
          <div class="ui-entry__content">
            <div class="ui-entry__id">
              <strong class="ui-entry__name heading-m">Sarah Johnson</strong>
              <span class="ui-entry__role">Senior Product Manager</span>
            </div>
            <blockquote class="ui-entry__quote">The handoff between design and development was always where things broke down.</blockquote>
          </div>
        </div>
        <div class="ui-entry__insights">
          <p class="ui-entry__insights-label">Insights</p>
          <ul class="ui-entry__chips" aria-label="Key insights">
            <li class="ui-entry__chip">Design-dev handoff pain</li>
          </ul>
        </div>
      </div>
    </article>
  </div>
</section>

Affinity Map

Interview findings grouped into categories, one post-it note per category. Each note gets a fixed tilt and vertical nudge from a repeating pattern, so the board looks hand-pinned but renders the same every time. Hover or focus straightens the note.

Trust

  • Wants to see real reviews before booking
  • Unsure who is behind the service

Speed

  • Gives up if sign-up takes more than a minute
  • Checks on the phone, between tasks
  • Expects an answer the same day

Cost

  • Hidden fees were the biggest frustration

Pain points

  • Lost progress when the app closed
  • Notifications felt like spam

Delight

  • Loved seeing a progress summary

Anatomy

  1. Grid — auto-fill, min column calc(space-5xl × 2) = 280px; no background or border; space-s top padding clears the tape
  2. Note — square (aspect-ratio 1/1, grows with content); radius-xs on all corners; shadow 0 0 space-l shadow-glow; tilt -2.5° to 2.5° and nudge from spacing tokens, cycled per note
  3. Colours — brand-yellow, brand-yellow-light, brand-blue, brand-red, brand-white. Text is always brand-black. WCAG AA contrast: 11.8, 14.1, 5.9, 5.6 and 21 to 1
  4. Tape — space-4xl × space-l; radius-xxs; 55% brand-white (12% brand-black on the white note); counter-rotated
  5. Title — text-xl; fw-black; ls-heading; 1px divider at 25% brand-black
  6. Points — text-m; lh-xs; space-xs round black bullet
  7. Hover / focus — rotate 0 + scale(1.03), 0.3s ease; no transition with reduced motion. Mobile: one column, half tilt, no nudge, no fixed square

ACF Fields

  • labeltext
  • headingtext
  • descriptiontextareaoptional intro text, line breaks kept
  • categoriesrepeatercategory_title, colour (auto / yellow / light / blue / red / white), points (sub-repeater: point_text)
<section class="acf-block am-block">
  <header class="am-block__header">
    <p class="acf-block__label">Synthesis</p>
    <h2 class="acf-block__heading">Affinity map</h2>
  </header>
  <div class="am-board">
    <!-- Tilt and nudge come from a fixed cycle in PHP, so the board renders the same every time -->
    <article class="am-note am-note--yellow" style="--am-tilt:-2deg;--am-nudge:0px;">
      <span class="am-note__tape" aria-hidden="true"></span>
      <h3 class="am-note__title">Trust</h3>
      <ul class="am-note__points" role="list">
        <li class="am-note__point">Wants to see real reviews before booking</li>
      </ul>
    </article>
    <article class="am-note am-note--blue" style="--am-tilt:1.5deg;--am-nudge:var(--space-s);">…</article>
  </div>
</section>

User Stories

Spider/hub diagram. Desktop: 3-column grid, hub centred, stories left and right, JS-drawn bolt-animation lines connecting hub to cards. Mobile: flex column with hub top-left, vertical connector, horizontal tick lines per card.

As

As a visitor

I want to quickly understand what kind of designer Adam is, so I can decide if he fits my project.

User stories

As a recruiter

I want to see evidence of process, not just polished outputs.

Re
Cl

As a client

I want to contact Adam and get a clear sense of services and pricing.

Anatomy

  1. Neuron canvas — `<canvas class="acf-us-neurons">` — seeded organic node/axon pattern, radial fade to edges, z-index 0
  2. Hub circle — 240px, double box-shadow (outer blue glow + inset tint), grid-column:2, justify-self/align-self:center
  3. SVG lines — JS drawn from hub circumference to nearest card edge; base line: #7e1b42 + glow filter; bolt overlay: animated stroke-dashoffset; dot: leading spark
  4. Cards — 106px img-wrap (radius-xs), title: text-xl fw-black secondary, body: text-m tertiary; hover fires bolt animation + scale(1.04)
  5. Right cards — `.acf-us-spider__card--right { flex-direction:row-reverse }`

ACF Fields

  • labeltext
  • headingtext
  • descriptiontextareaoptional intro text under the heading
  • hub_labeltextcentre hub text, defaults to "User stories"
  • storiesrepeaterstory_title, story_body, story_image
<section class="acf-block acf-user-stories">
  <div class="acf-user-stories__header">
    <p class="acf-block__label">Requirements</p>
    <h2 class="acf-block__heading">User stories</h2>
  </div>
  <canvas class="acf-us-neurons" aria-hidden="true"></canvas>
  <div class="acf-us-spider" id="acf-us-spider-1">
    <!-- JS draws the hub-to-card lines into this SVG -->
    <svg class="acf-us-spider__lines" aria-hidden="true" xmlns="http://www.w3.org/2000/svg"></svg>
    <div class="acf-us-spider__hub" data-us-hub style="grid-column:2; grid-row:1/span 1;">
      <span class="acf-us-spider__hub-label">User stories</span>
    </div>
    <!-- Even stories go left (column 1), odd stories go right (column 3) -->
    <article class="acf-us-spider__card acf-us-spider__card--left" style="grid-column:1;grid-row:1;" data-us-card>
      <div class="acf-us-spider__img-wrap acf-us-spider__img-wrap--initials"><span>As</span></div>
      <div class="acf-us-spider__text">
        <h3 class="acf-us-spider__title">As a visitor</h3>
        <p class="acf-us-spider__body">I want to quickly understand what kind of designer Adam is.</p>
      </div>
    </article>
    <article class="acf-us-spider__card acf-us-spider__card--right" style="grid-column:3;grid-row:1;" data-us-card>…</article>
  </div>
</section>

Personas

Dossier-style cards with two rows. Row 1: full-width 1:1 photo column + bio column (name, glowing 2px divider, italic quote, thumb-icon list items, demographics). Row 2: bio rich text + placeholder squares. Multiple persona blocks alternate left/right via a global PHP counter.

MK

Marcus Klein

“I don't have time to decode a designer's portfolio — show me the impact fast.”

Interests: Startups, SaaS, scale-up culture, impact metrics

Tech frustrations: Designers who can't communicate trade-offs

Job: Head of Product, SaaS startup

Location: Copenhagen, Denmark

Age Group: 35–44

Bio:

Marcus has spent 8 years in product roles at scale-ups across the Nordics. He evaluates design partners primarily on communication quality and ability to translate user insight into shipping decisions.

Anatomy

  1. Photo col — full-width 1:1 image (object-fit:cover, 50% 30%) or placeholder with bold initials (clamp 3–6rem, red)
  2. Bio col — name (48px/900), glowing 2px divider, italic quote (32px/400)
  3. List items — inline SVG thumb-up icon (interests) + thumb-down icon (frustrations), 44px wide, red
  4. Demographics — indented 68px (44px icon + 24px gap) to align with list text
  5. Row 2 — bio rich text section + three placeholder squares (opacity fade)
  6. Alternating layout — even-numbered cards get .prs-card--flip via PHP global counter, reversing row direction

ACF Fields

  • labeltext
  • headingtext
  • persona_cardsrepeatername, tagline, photo, quote, bio (wysiwyg), goals (repeater → goal_text), frustrations (repeater → frustration_text), job, nationality, location, gender, age_group, relationship, kids
<section class="acf-block prs-block">
  <header class="prs-block__header">
    <p class="acf-block__label">Research</p>
    <h2 class="acf-block__heading">Who we're designing for</h2>
  </header>
  <div class="prs-block__list">
    <!-- Every second card adds .prs-card--flip -->
    <div class="prs-card">
      <div class="prs-card__header-row">
        <div class="prs-card__photo-col">
          <img class="prs-card__photo" src="marcus.jpg" alt="Marcus Klein">
        </div>
        <div class="prs-card__bio-col">…</div>   <!-- Bio molecule -->
      </div>
      <div class="prs-card__extended-row">
        <div class="prs-card__bio-section">
          <div class="prs-li prs-li--top">
            <div class="prs-li__icon"><svg class="prs-li__img--bio" …>…</svg></div>
            <div class="prs-li__text prs-li__text--rich"><strong>Bio:</strong><p>Marcus has spent 8 years in product roles…</p></div>
          </div>
        </div>
        <div class="prs-card__placeholder-col" aria-hidden="true">
          <div class="prs-card__placeholder prs-card__placeholder--1"></div>
          <div class="prs-card__placeholder prs-card__placeholder--2"></div>
          <div class="prs-card__placeholder prs-card__placeholder--3"></div>
        </div>
      </div>
    </div>
  </div>
</section>

Image Full Width

Full-bleed image block. Optional label and heading above the image. 8px border-radius, full container width, optional alt text override via ACF field.

Final designs

Delivered solution

Full-width image — any aspect ratio

Anatomy

  1. Header (optional) — .acf-image-full__header: label + heading above image
  2. Image — .acf-image-full__img — fills 100% container width, loading="lazy"
  3. Border radius — var(--radius-xs) 8px on the <img> tag

ACF Fields

  • labeltextOptional eyebrow label
  • headingtextOptional heading
  • imageimageRequired — the image to display
  • alt_texttextOptional override for image alt attribute
<div class="acf-block acf-image-full">
  <div class="acf-image-full__header">
    <p class="acf-block__label">Final designs</p>
    <h2 class="acf-block__heading">Delivered solution</h2>
  </div>
  <img src="final-designs.jpg" alt="Final designs across devices" class="acf-image-full__img" loading="lazy">
  <!-- Optional text + button -->
  <div class="acf-image-full__actions">
    <p class="acf-image-full__actions-text">See the full prototype.</p>
    <a href="https://figma.com/…" class="btn btn-secondary" target="_blank" rel="noopener">Open prototype</a>
  </div>
</div>

Preference Testing

A/B test results visualisation. Donut chart via CSS-masked conic-gradient (no canvas/SVG). Screen mockup images with glow drop-shadow. Outcome panel highlights the winner with a left-border accent.

Visual preference test

Which layout do users prefer?

Homepage hero layout

Participants were shown two homepage hero variants and asked which felt more trustworthy.

  • Option A 68%
  • Option B 32%
Option A — Bold headline first
Screen
Option B — Image first
Screen

Outcome

Option A was chosen by 68% of participants. The bold headline first approach communicated credibility more quickly than leading with imagery.

Anatomy

  1. Donut chart — CSS mask: radial-gradient on conic-gradient background
  2. Legend — Colour dots (border-radius: 2px) + percentage labels
  3. Mockup — aspect-ratio 432/911, glow drop-shadow
  4. Outcome — background: primary-10, border-left: 3px solid primary

ACF Fields

  • labeltext
  • headingtext
  • testsrepeatertest_label, test_desc, options (sub-repeater: option_name, option_colour, option_percentage, option_mockup), outcome_text
<section class="acf-block acf-pref-test">
  <div class="acf-pref-test__header">
    <p class="acf-block__label">Visual preference test</p>
    <h2 class="acf-block__heading">Which layout do users prefer?</h2>
  </div>
  <div class="acf-pref-test__test">
    <div class="acf-pref-test__test-meta">
      <h3 class="acf-pref-test__test-label">Homepage hero layout</h3>
      <p class="acf-pref-test__test-desc">Participants were shown two variants.</p>
    </div>
    <div class="acf-pref-test__body">
      <div class="acf-pref-test__chart-col">
        <div class="acf-pref-test__donut-wrap">
          <!-- Gradient stops are built in PHP from the option percentages -->
          <div class="acf-pref-test__donut" style="background:conic-gradient(from 0deg, var(--chart-1) 0% 68%, var(--chart-2) 68% 100%);"></div>
        </div>
        <ul class="acf-pref-test__legend">
          <li class="acf-pref-test__legend-item">
            <span class="acf-pref-test__legend-dot" style="background:var(--chart-1);"></span>
            <span class="acf-pref-test__legend-name">Option A</span>
            <span class="acf-pref-test__legend-pct">68%</span>
          </li>
        </ul>
      </div>
      <div class="acf-pref-test__options">
        <div class="acf-pref-test__option">
          <div class="acf-pref-test__option-header">
            <span class="acf-pref-test__option-dot" style="background:var(--chart-1);"></span>
            <span class="acf-pref-test__option-name">Option A</span>
          </div>
          <div class="acf-pref-test__mockup"><div class="acf-pref-test__mockup-inner"><img src="option-a.png" alt="Option A"></div></div>
        </div>
      </div>
    </div>
    <div class="acf-pref-test__outcome">
      <p class="acf-pref-test__outcome-label">Outcome</p>
      <p class="acf-pref-test__outcome-text">Option A was chosen by 68% of participants.</p>
    </div>
  </div>
</section>