All UI components used across the site, grouped by type. Each component shows its name, CSS class(es), a short description, a live preview, and which pages use it.
Colour Palette — Semantic Colours
All values are CSS custom properties defined in :root (light) and [data-theme="dark"] in main.css. Toggle dark mode in the sidebar to see both sets live.
Base body text: Plus Jakarta Sans, 17px, line-height 2em. Applied globally via the body rule.
Used on: All pages
The bad news is that buying a car is a messy business, and people take a substantial amount of time dealing with their emotions — a rollercoaster spanning excitement, doubt, confusion and joy.
Article paragraph.article p
20px / Atkinson Hyperlegible, line-height 1.5. Applied to paragraphs inside an .article wrapper. Optimised for readability in long-form content.
Used on: conversational_v2.html, Ecosystem_V2.html, project_template.html, what_ai_exposes.html, AI_tracking_for_elderly_people.html
The goal wasn't to have complete online sales, but rather to drive more people down the funnel, increasing the amount of self-serve tasks while facilitating a journey where people can stop and continue seamlessly.
Typography — Font Variants
Modern (default).modern
Plus Jakarta Sans. Default site typeface. Applied by the font switcher when "modern" is selected.
Used on: conversational_v2.html, Ecosystem_V2.html, project_template.html (via font switcher)
The future is conversational — when it works.
Serif.serif
TNY Adobe Caslon Pro Regular. Elegant classic serif, offered as an alternative reading style.
Used on: conversational_v2.html, Ecosystem_V2.html, project_template.html (via font switcher)
The future is conversational — when it works.
Sans-serif (Accessible).sans-serif
Atkinson Hyperlegible. Dyslexia-friendly typeface. The accessibility-focused reading option.
Used on: conversational_v2.html, Ecosystem_V2.html, project_template.html (via font switcher)
The future is conversational — when it works.
Typography — Text Utilities
Highlight.highlights
Inline yellow highlight (light mode) / blue (dark mode). Wraps key words or phrases for emphasis.
Used on: index.html, about.html, contacts.html, all project pages
A generalist with a soft spot for complex systems.
Grey / Muted.grey
Muted text colour (var(--text-color-grey)). Used for secondary or supporting text.
Used on: All pages with secondary text
Primary text. Secondary muted text alongside it.
Subtitle.subtitle
32px / weight 500, letter-spacing -1px. Used directly under hero headings.
Used on: conversational_v2.html, Ecosystem_V2.html, project_template.html
When a conversational interface helps.
Typography — Paragraph Quote
Paragraph Quote.paragraph-quote
Inline block-quote style for pull quotes inside article body text. Left border (2px, var(--input-border)) with 48px left padding. Used as a <p> containing <i>-wrapped quote text, followed by a <p><small> attribution line.
Used on: what_ai_exposes.html, AI_tracking_for_elderly_people.html
"The self-serving bias rules many situations, but, surprisingly, it doesn't work when it comes to computers and applications!"
Lucy Adams, Why Users Blame Themselves for Designers' Mistakes
Buttons & Links — Primary Button
Primary (Dark) Button.btn.btn-dark.btn--arrowed
Main CTA button with animated SVG arrow. Hover animates the arrow right and darkens the background.
Used on: index.html, about.html, contacts.html, all project pages
Coloured, underlined inline link. Used inside article body text and captions for "View full size" and external references.
Used on: conversational_v2.html, Ecosystem_V2.html, contacts.html, about.html, what_ai_exposes.html, AI_tracking_for_elderly_people.html
A service blueprinting of the journey we considered. View full size ↗
Buttons & Links — Nav Links
Nav Link.navtrans
Navigation menu items. Weight 600, 0.4s transition. Active/hover state: bold, colour #196AE3. Used with a direction icon (/repository/img/Right.svg or Left.svg).
End-of-article back navigation link. Combines .navtrans (nav transition behaviour) with .goback (padding-top 6%, cursor pointer). Placed after the last .article block, inside the .col-lg-12 wrapper. Uses ‹ Back to articles with blue colour.
Used on: what_ai_exposes.html, AI_tracking_for_elderly_people.html
Fixed top navigation bar. Logo sits in a pill-shaped .logo-bubble; nav links in a matching .nav-bubble. Both use a frosted-glass backdrop blur effect. Includes the scroll progress bar.
Used on: All pages
Navigation — Dark Mode Toggle
Dark Mode Toggle.toggle-switch .slider .darkmode
Custom checkbox toggle in the navbar. Blue pill knob slides right when checked. Moon icon visible in unchecked state. Persists preference to localStorage.
Used on: All pages
Dark Mode
Navigation — Scroll Progress Bar
Scroll Progress Bar.scroll-line
4px teal line at the very top of the navbar. Width is set dynamically via JS (0–100%) as the user scrolls.
Used on: All pages
← 65% scrolled (example)
Layout & Sections — Article Page Layout
Article Page Shell.top-shape .title-space
.top-shape is the outermost <section> for article pages: 90vw, centred with auto margins (max 1800px on very wide screens). Inside it, a .col-lg-10.offset-lg-1 column contains a .container-fluid > .row.title-space which provides 20% top margin. The row holds alternating .article.article-content text blocks and <section class="reveal"> image blocks as siblings.
Used on: what_ai_exposes.html, AI_tracking_for_elderly_people.html
Constrains long-form body text to a max-width of 700px at ≥992px viewport, 100% at smaller screens. Always paired with .article-content on the same element. Images are placed outside this div (as <section class="reveal"> siblings) so they can span the full column width.
Used on: what_ai_exposes.html, AI_tracking_for_elderly_people.html
This paragraph is constrained to 700px on large screens. Images sit outside this div as siblings in the row, allowing them to span the full column width.
Layout & Sections — Case Hero
Case Hero.case-hero
Full-bleed hero header for case studies. Centred text, 8rem top padding. Animates in via fadeInUp (paused until body.loaded). h1 and .subtitle also fade in with staggered delays. Includes a JS-driven parallax scroll effect.
Used on: conversational_v2.html, Ecosystem_V2.html, project_template.html
The Future is Conversational
(when it works)
When a conversational interface helps, and when it doesn't.
Layout & Sections — Case Study Sections
Case Intro.case-intro
Wider wrapper (max-width 1200px) for hero area and leading image at the top of a case study page.
Used on: conversational_v2.html, Ecosystem_V2.html, project_template.html
max-width: 1200px — contains .case-hero and opening media
Case Study.case-study
Narrower wrapper (max-width 860px) for the body content of a case study. Contains one or more .case-content articles.
Used on: conversational_v2.html, Ecosystem_V2.html, project_template.html
max-width: 860px — main body container
Layout & Sections — Article Content
Article Content Section.article-content
A div wrapping a chunk of article text. Receives font-size modifier classes (.font-size-normal/medium/large) from the font-size switcher. On article pages, always also carries .article to apply the 700px max-width constraint.
Used on: conversational_v2.html, Ecosystem_V2.html, project_template.html, what_ai_exposes.html, AI_tracking_for_elderly_people.html
The hypothesis
In 2019, we prototyped a chatbot for an automotive eCommerce platform. The assumption: conversational UI would reduce friction in complex vehicle discovery and quoting tasks.
Layout & Sections — Article List
Article Bullet List.ul-art
Used for bullet lists inside article body text. Restores indentation (padding-left: 24px) and disc bullets (list-style: disc !important) overriding the global body padding reset. Place inside .article.article-content. Font size is inherited from the font-size switcher via the li selector in typography.css.
Used on: what_ai_exposes.html
Continuous Discovery — an ongoing practice of learning about customers through frequent interaction.
Parallel Research Stream — research runs in parallel with design/development streams.
Layout & Sections — Notes Box
Notes / Highlight Box.notes
A paragraph with a coloured background (var(--highlights)) and 16px padding. Used for disclaimers or important callouts at the start of a section.
Used on: Ecosystem_V2.html
Before we start: I will talk about multiple systems, but I can only show the consumer-facing ones.
Layout & Sections — Keywords
Keywords.keywords
End-of-article tag strip. Muted text, 0.95rem, separated by a top border. Lists thematic keywords for the piece.
Used on: conversational_v2.html, Ecosystem_V2.html, project_template.html
Keywords: User Experience | AI · Conversational UI | Behavioural Design | Concept Testing | Service Design
Layout & Sections — Wiseness Box
Wiseness Box.wiseness
A gradient-background container (light → slightly darker, via CSS vars). Used on the About page to wrap a featured content block.
Used on: about.html
What I've done and what I do.
Content inside a wiseness box with gradient background.
Media — Images
Responsive Image.img-responsive
block, max-width 100%, height auto. The default wrapper for all images.
Used on: All pages
Article Page Image.img-responsive.projectpics
Full-width image used inside <section class="reveal"> blocks on article pages. .projectpics sets max-width: 100% and zero padding; on screens ≤768px it constrains to 90% width with 5% margin. Always paired with .img-responsive. The wrapping <section class="reveal"> sits outside the .article div so images span the full column, not the 700px text width.
Used on: what_ai_exposes.html, AI_tracking_for_elderly_people.html
Lightbox Trigger.lightbox-trigger
Added alongside .img-responsive. Changes cursor to zoom-in. Paired with onclick="openLightbox(this.src, this.alt)".
Used on: conversational_v2.html, Ecosystem_V2.html
Full-screen overlay (z-index 9999, rgba black background). Hidden by default; .open switches it to flex. A single shared instance — the #lightboxImg src is swapped dynamically by openLightbox(src, alt). Close button uses /repository/img/Close.svg. Also closes on Escape or clicking the backdrop.
Used on: conversational_v2.html, Ecosystem_V2.html
Lightbox HTML lives once at the bottom of the page. openLightbox(src, alt) sets the image before showing it.
Controls — Font Controls
Font Controls Panel.font-controls-wrapper .font-control-section .font-chip-group
Two-column panel at the top of article pages. Left section: font family switcher (Modern / Serif / Accessible). Right section: font size switcher (Normal / Medium / Large). Separated by a 1px vertical line on wider screens. Font family JS applies the chosen class to all p, li, and .link-text elements; font size JS adds .font-size-normal/medium/large to all .article-content elements.
Used on: conversational_v2.html, Ecosystem_V2.html, project_template.html, what_ai_exposes.html, AI_tracking_for_elderly_people.html
Alternative Fonts:
Font Size:
Controls — Text-to-Speech
TTS Floating Button.speech-button #speakBtn
Floating "Listen" button fixed at bottom-right of the page. Triggers Web Speech API on the page's article content. Activates a collapsed drawer with speed, voice, and playback controls.
Used on: conversational_v2.html, Ecosystem_V2.html, project_template.html
Expanded drawer with pause, stop, speed (range), and voice (select) controls. Pause has a yellow hover; stop has a red hover. Active read-aloud text gets a green .tts-highlight.
Used on: conversational_v2.html, Ecosystem_V2.html, project_template.html
1.0×
Animations — Reveal on Scroll
Reveal.reveal .reveal.visible
Elements start opacity 0 / translateY(20px). When scrolled into view, JS adds .visible → opacity 1 / translateY(0) over 1s. 2nd, 3rd and 4th siblings get staggered delays (0.1s–0.3s). Used as a wrapper around almost every content section.