Molecules thatsadam Design System

thats adam
Composite Elements

Purposeful groupings of atoms working together as a unit. A project card is a molecule — it combines an image, a label, and a heading into a single reusable component that carries clear meaning on its own.

Project Card

Portfolio item preview combining image, type label, and title. Assembled into the Project Grid organism. The square crop image is the primary visual anchor — the hover scale draws the eye.

Anatomy

  1. Image — 1:1 square, border-radius: var(--radius-xs), overflow hidden, hover: scale(1.03) transition 0.4s
  2. Type label — label-m, red secondary, uppercase, 4px tracking
  3. Title — text-xl, fw-black, primary colour
<!-- Rendered output. Odd-numbered cards add .project-card--flip (image on the right). -->
<article class="project-card" data-type="ux-design" data-date="1714521600" data-title="spotted">
  <a href="/work/spotted/" class="project-card__image-link" tabindex="-1" aria-hidden="true">
    <div class="project-card__image">
      <img src="spotted.jpg" alt="Spotted app screens" loading="lazy" class="project-card__img">
    </div>
  </a>
  <div class="project-card__meta">
    <p class="project-card__type label-m">UX Design / 2024</p>
    <h3 class="project-card__title"><a href="/work/spotted/">Spotted</a></h3>
    <p class="project-card__excerpt">First paragraph of the case study…</p>
    <a href="/work/spotted/" class="btn btn-secondary project-card__cta">View project</a>
  </div>
</article>

Stat Item

A large numeric value paired with an uppercase label. Combined into the Stats Bar organism. The number is the primary visual element — weight and scale do the work.

17+Years experience
50+Projects shipped
3Industry awards
<div class="stats-bar__item">
  <span class="stats-bar__value">17+</span>
  <span class="stats-bar__label label-s">Years of experience</span>
</div>

Service Card

Used in the 2-column services grid. Numbered badge, heading, optional body, and a bottom divider as a visual full-stop. The divider is pushed to the bottom via margin-top: auto.

01

UX / UI Design

End-to-end interface design from research and wireframes through to polished, developer-ready specifications.

Anatomy

  1. Number — label-s, padded with str_pad( $i, 2, '0', STR_PAD_LEFT ) in PHP
  2. Heading — text-2xl, fw-black
  3. Body — body-m, optional
  4. Divider — 1px border-top, pushed to bottom with margin-top: auto
<div class="svc-card">
  <div class="svc-card__title">
    <p class="label-s">01</p>
    <h2 class="svc-card__heading">UX / UI Design</h2>
  </div>
  <p class="svc-card__body body-m">End-to-end interface design from research and wireframes through to polished, developer-ready specifications.</p>
  <div class="svc-card__divider"></div>
</div>

Accordion Item

Native <details>/<summary> element — no JavaScript required. Chevron SVG rotates 180° via CSS details[open] selector. Used in the Services process section.

Discovery & Research

Once the task type is defined we understand how big the diamonds will be — establishing what we already know and where to source knowledge we need.

Define

Design criteria agreed and signed off — preventing design loops later.

<div class="svc-accordion">
  <details class="svc-accordion__item" open>
    <summary class="svc-accordion__summary">
      <span class="svc-accordion__title">Discovery &amp; Research</span>
      <svg class="svc-accordion__chevron" width="16" height="10" viewBox="0 0 16 10" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
        <path d="M1 1L8 8L15 1" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
      </svg>
    </summary>
    <div class="svc-accordion__body">
      <p>Establishing what we already know and where to source the knowledge we need.</p>
    </div>
  </details>
</div>

Filter Bar

Full-width bar: .work-filter-bar__tabs on the left, sort label + <select> on the right. Bottom border divides it from the project grid below.

Anatomy

  1. Tabs left — .work-filter-bar__tabs · gap: var(--space-xs) 8px · idle tabs: grey · active tab: white text + blue ::after underline
  2. Sort right — .label-s "Sort by" label + .work-sort-select <select> (not an icon toggle)
  3. Bottom border — 1px var(--surface-branding-primary-30)
  4. Padding — padding-bottom: var(--space-2xl) 64px
<div class="work-filter-bar container">
  <div class="work-filter-bar__tabs" role="tablist" aria-label="Filter projects">
    <button class="work-filter-tab work-filter-tab--active" data-filter="all" role="tab" aria-selected="true">All projects</button>
    <button class="work-filter-tab" data-filter="ux-design" role="tab" aria-selected="false">UX Design</button>
  </div>
  <div class="work-filter-bar__sort">
    <label for="work-sort" class="label-s">Sort by</label>
    <select id="work-sort" class="work-sort-select">
      <option value="date-desc">Newest first</option>
      <option value="date-asc">Oldest first</option>
      <option value="title-asc">A – Z</option>
    </select>
  </div>
</div>

Input Field

Full input molecule — label + base input + optional helper text. Label is always a red semibold uppercase label. Four states matching the base atom.

Idle
Focus
Error
Please enter a valid email address
Success
✓ Looks good

Anatomy

  1. Label — .label-s: 12px · 600 · uppercase · red · 2px tracking
  2. Input base atom — bottom border, Roboto 20px
  3. Helper text — 12px · coloured to match state (red/green) · only shown on error/success
<div class="contact-form__field">
  <label class="label-s" for="contact_email">Email <span class="contact-form__required" aria-hidden="true">*</span></label>
  <input class="contact-form__input" type="email" id="contact_email" name="contact_email"
         required autocomplete="email" placeholder="your@email.com">
</div>

<!-- Two fields side by side -->
<div class="contact-form__row">
  <div class="contact-form__field">…</div>
  <div class="contact-form__field">…</div>
</div>

Header Text Content

Centred page-header block for interior pages. Sub-heading, hero heading, description, and optional CTA button — all centred in a max-width 800px container.

Services

Design that
delivers

End-to-end UX/UI design — from user research and strategy through to polished, developer-ready specifications.

Anatomy

  1. Sub-heading — .label-s (12px · 600 · red · uppercase)
  2. Heading — .heading-xxxl / .heading-xxl (responsive, 900 weight)
  3. Description — .body-l (Roboto 20px · tertiary)
  4. CTA — .btn.btn-secondary (optional, e.g. PDF download)
  5. Container — text-align:center · max-width: 800px · margin-inline:auto
<header class="page-header">
  <p class="label-s">Services</p>
  <h1 class="page-header__heading">Design that<br>delivers</h1>
  <p class="body-l">End-to-end UX/UI design — from user research and strategy through to polished, developer-ready specifications.</p>
  <div><a href="/services.pdf" class="btn btn-secondary">Download PDF</a></div>
</header>

Table Row

Individual row within the Table organism. Two types: header (2px bottom border) and body (1px). Column 1 is always red; remaining columns are grey.

Header row
Feature That's Adam Competitor
Body row — single value
Responsive Full Partial
Body row — multi (bullet list cells)
Process
  • Figma source of truth
  • CSS design tokens
  • Living docs
  • Style guide only
Typography per column type
Header col 1var(--text-xl) 24px · var(--fw-black) · var(--text-on-dark-secondary) red
Header othervar(--text-l) 20px · var(--fw-black) · var(--text-on-dark-tertiary)
Body col 1var(--text-m) 16px · var(--fw-semibold) · uppercase · 4px tracking · red
Body othervar(--text-m) 16px · var(--fw-regular) · tertiary
paddingvar(--space-l) var(--space-m) — 24px 16px
<table class="acf-table">
  <thead>
    <tr><th>Feature</th><th>That's Adam</th><th>Competitor</th></tr>
  </thead>
  <tbody>
    <!-- Single value -->
    <tr>
      <td><div class="acf-table__label-cell">Responsive</div></td>
      <td>Full</td>
      <td>Partial</td>
    </tr>
    <!-- Multi value: a cell with more than one line becomes a bullet list -->
    <tr>
      <td><div class="acf-table__label-cell">Process</div></td>
      <td><ul class="acf-table__bullets"><li>Figma source of truth</li><li>CSS design tokens</li><li>Living docs</li></ul></td>
      <td>Style guide only</td>
    </tr>
  </tbody>
</table>

Bio

Persona bio column. Name → glowing divider → italic quote → list items → demographics block. Demographics are indented 68px to align with list item text.

Marcus Klein

"I don't have time to decode a portfolio — show me the impact."

Interests: Startups, SaaS, impact metrics

Job: Head of Product

Location: Copenhagen, Denmark

Age Group: 35–44

Anatomy

  1. Name — 48px · 900 · primary · letter-spacing: -0.03em
  2. Glowing divider — 2px height · primary background · box-shadow 0 0 30px black shadow
  3. Quote — var(--text-2xl) · var(--fw-regular) · italic · primary
  4. List items — List item atoms (thumb icons + bold label + body)
  5. Demographics — padding-left: 68px (= 44px icon + 24px gap)
<div class="prs-card__bio-col">
  <div class="prs-card__heading-wrap">
    <h3 class="prs-card__name">Marcus Klein</h3>
    <div class="prs-card__divider" aria-hidden="true"></div>
    <p class="prs-card__quote">“I don't have time to decode a portfolio — show me the impact.”</p>
  </div>
  <div class="prs-card__list-items">
    <div class="prs-li">…</div>   <!-- List Item atom -->
  </div>
  <div class="prs-card__demographics">
    <p class="prs-demo__line"><strong>Job:</strong> Head of Product</p>
    <p class="prs-demo__line"><strong>Location:</strong> Copenhagen, Denmark</p>
    <p class="prs-demo__line"><strong>Age Group:</strong> 35–44</p>
  </div>
</div>

Card

Generic content card used across multiple sections. Optional rounded image, red title, grey body. The image slot is 106×106px with 8px radius.

Image

UX Research

Systematic investigation to understand user needs and behaviours before committing to a direction.

Without image

When no image is present the card begins directly with the title. Often used for service descriptions.

Spec
image106×106px · border-radius: var(--radius-xs) 8px · optional
titlevar(--text-xl) 24px · var(--fw-black) · var(--text-on-dark-secondary) red
bodyvar(--text-m) 16px · var(--fw-regular) · var(--text-on-dark-tertiary)
gapimage→text: var(--space-l) 24px · title→body: var(--space-s) 12px
<article class="content-card">
  <img class="content-card__img" src="research.jpg" alt="" width="106" height="106">   <!-- optional -->
  <div class="content-card__text">
    <h3 class="content-card__title">UX Research</h3>
    <p class="content-card__body">Systematic investigation to understand user needs and behaviours before committing to a direction.</p>
  </div>
</article>