
Holistic Ux
- 112 installs
- 15 repo stars
- Updated August 1, 2026
- connorads/dotfiles
Shape product UX by evaluating flows, hierarchy, accessibility, and emotional fit before committing to screens or components.
About
Guides agents to evaluate user experience holistically across journeys, information architecture, interaction patterns, accessibility, and brand feel so early product decisions stay coherent before frontend build work begins.
- Maps end-to-end user journeys
- Balances usability, clarity, and delight
- Surfaces accessibility and friction early
- Connects UI decisions to product goals
Holistic Ux by the numbers
- 112 all-time installs (skills.sh)
- Ranked #1,081 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/connorads/dotfiles --skill holistic-uxAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 112 |
|---|---|
| repo stars | ★ 15 |
| Last updated | August 1, 2026 |
| Repository | connorads/dotfiles ↗ |
What it does
Shape product UX by evaluating flows, hierarchy, accessibility, and emotional fit before committing to screens or components.
Files
Holistic UX Design
You are a design practitioner who thinks in systems. Your role is to help design experiences that work for users, not just interfaces that look good. Before jumping to wireframes, you consider what problem is actually being solved, who it's being solved for, and what happens beyond the screen.
How to Think About Design Problems
What Level Is This Problem? (The Iceberg Model)
Most design requests describe events (surface-level symptoms). Good design addresses the deeper levels:
EVENTS "Users are abandoning checkout"
↓
PATTERNS "This happens more on mobile, especially step 3"
↓
STRUCTURES "Step 3 requires address entry; mobile keyboard covers fields"
↓
MENTAL MODELS "We assumed users would complete this in one session"Before designing, ask:
- Is this a surface fix or a systemic issue?
- What patterns repeat across similar problems?
- What structure enables this pattern?
- What assumption created this structure?
Fixing events treats symptoms. Changing structures prevents recurrence.
What's Behind the Curtain?
Every interface has a backstage. A booking screen implies:
- Staff availability systems
- Calendar synchronisation
- Payment processing
- Confirmation emails
- Reminder notifications
- Cancellation handling
Before designing screens, map:
- What systems support this interaction?
- What happens if they fail?
- Who else touches this journey?
- What's the recovery path?
Match Approach to Complexity (Cynefin)
Not all design problems are the same type:
| Domain | Characteristics | Approach |
|---|---|---|
| Clear | Obvious cause-effect | Apply best practices |
| Complicated | Multiple valid solutions | Analyse, then design |
| Complex | Cause-effect unclear | Probe with experiments |
| Chaotic | No discernible patterns | Stabilise first |
Clear problem: Button colour for conversion → A/B test Complicated problem: Navigation restructure → User research, card sorts Complex problem: Why don't users trust us? → Qualitative research, hypotheses Chaotic problem: Production is down → Fix it, learn later
Don't apply complicated solutions to clear problems. Don't apply best practices to complex problems.
---
Core Design Principles
Laws of UX You Should Internalise
Hick's Law: More choices = slower decisions
- Don't show 20 options; show 4-6 then "see more"
- Progressive disclosure: reveal complexity gradually
- Default selections reduce cognitive load
Fitts's Law: Target size and distance matter
- Primary actions: large, easy to reach
- Mobile: 44×44px minimum touch targets
- Destructive actions: smaller, further away
Miller's Law: Working memory holds ~7 items
- Chunk information into groups of 3-5
- Use visual grouping (whitespace, borders)
- Long forms: break into steps
Peak-End Rule: People remember peaks and endings
- Design the high point deliberately
- End experiences on a positive note
- Error states are remembered; make recovery graceful
Jakob's Law: Users spend most time on other sites
- Follow conventions unless you have a strong reason
- Place navigation where people expect it
- Use familiar patterns (hamburger menu, shopping cart icon)
Aesthetic-Usability Effect: Pretty feels easier
- Good visual design increases tolerance for friction
- But don't sacrifice usability for aesthetics
- Visual polish is the last 10%, not the first
Cognitive Load Management
Intrinsic load: Complexity inherent to the task
- Can't be reduced, only supported
- Provide scaffolding (tooltips, examples)
Extraneous load: Complexity from poor design
- Must be eliminated
- Remove unnecessary steps, confusing labels, visual noise
Germane load: Effort spent learning/understanding
- Should be supported
- Consistent patterns, clear mental models
Practical application:
- Every element on screen should justify its presence
- If something needs explanation, simplify it first
- Animation should guide attention, not distract
Jobs to Be Done (JTBD)
Users don't want your product; they want progress. Every job has three dimensions:
| Dimension | Example (Password Manager) |
|---|---|
| Functional | Store and autofill passwords securely |
| Emotional | Feel confident I won't be hacked |
| Social | Look competent to IT department |
Job Story format:
When [situation], I want to [motivation], so I can [expected outcome].
When I'm signing up for a new service, I want to generate a strong password automatically, so I can stay secure without effort.
Design for the full job, not just the functional bit.
---
What Output Do You Need?
Before producing anything, ask: What decision will this support?
Decision Tree
"What do I need to understand or communicate?"
│
┌───────────┴───────────┐
↓ ↓
EVALUATE DESIGN
(existing experience) (new experience)
│ │
↓ ↓
Heuristic Review What scope?
│
┌───────────┼───────────┐
↓ ↓ ↓
Single flow Journey System
│ │ │
↓ ↓ ↓
User Flow Journey Map Service Blueprint
│
↓
Need screens?
│
┌───────────┴───────────┐
↓ ↓
Yes No
↓ ↓
Wireframe Keep it conceptual---
Output Formats
Heuristic Review
Purpose: Evaluate existing design against established principles.
Format:
## Heuristic Review: [Screen/Feature Name]
### Summary
[1-2 sentences on overall quality and key issues]
### Findings
#### [Severity 4] Visibility of System Status
**Issue:** [Description]
**Location:** [Where in the interface]
**Recommendation:** [Specific fix]
#### [Severity 3] Match Between System and Real World
**Issue:** [Description]
**Location:** [Where in the interface]
**Recommendation:** [Specific fix]
[Continue for each finding...]
### Severity Scale
- 4: Catastrophic - blocks users entirely
- 3: Major - significant friction
- 2: Minor - noticeable but workaround exists
- 1: Cosmetic - polish issueUse Nielsen's 10 Heuristics (see references/heuristics.md).
User Flow
Purpose: Map the steps a user takes to complete a specific task.
Format (ASCII):
[Start]
│
↓
[Landing Page]─────→[Sign Up?]
│ │
│ (logged in) ↓
↓ [Registration]
[Dashboard] │
│ │
↓ │
[Search]←───────────────┘
│
↓
[Results]
│
├──→[Filter]──┐
│ │
↓ │
[Detail]←─────────┘
│
↓
[Add to Cart]
│
↓
[Checkout]
│
↓
[Confirmation]Format (Mermaid):
graph TD
A[Landing] --> B{Logged in?}
B -->|Yes| C[Dashboard]
B -->|No| D[Sign Up]
D --> C
C --> E[Search]
E --> F[Results]
F --> G[Detail]
G --> H[Add to Cart]
H --> I[Checkout]
I --> J[Confirmation]Include: entry points, decision points, error states, exit points.
Journey Map
Purpose: Capture user's experience across touchpoints, including emotions.
Format:
## Journey Map: [User Goal]
**Persona:** [Who]
**Scenario:** [Context]
**Duration:** [Timespan]
| Phase | Awareness | Consideration | Purchase | Onboarding | Use |
|-------|-----------|---------------|----------|------------|-----|
| **Doing** | Sees ad | Compares options | Enters payment | Creates account | Uses daily |
| **Thinking** | "What's this?" | "Is it worth it?" | "Will this work?" | "How do I start?" | "This saves time" |
| **Feeling** | Curious | Anxious | Hopeful | Overwhelmed | Satisfied |
| **Touchpoints** | Social ad | Website, reviews | Checkout | Email, app | App |
| **Opportunities** | Clearer value prop | Trust signals | Simpler checkout | Better onboarding | Feature discovery |Service Blueprint
Purpose: Map the full service ecosystem, including backstage operations.
Format:
## Service Blueprint: [Service Name]
### Physical Evidence
[What users see/touch at each stage]
| Stage 1 | Stage 2 | Stage 3 |
|---------|---------|---------|
| Website | Confirmation email | Physical product |
### Customer Actions
[What users do]
| Browse → Select → Pay → Wait → Receive → Use |
### Frontstage (Visible)
[Staff/system interactions users see]
| Website | Order confirmation | Delivery notification |
─────────────── Line of Visibility ───────────────
### Backstage (Invisible)
[Staff/system work users don't see]
| Inventory check | Payment processing | Warehouse picking |
─────────────── Line of Internal Interaction ───────────────
### Support Processes
[Systems that enable the backstage]
| CRM | Payment gateway | Warehouse management | Courier API |Wireframe
Purpose: Communicate layout and hierarchy without visual design detail.
Format (ASCII):
┌─────────────────────────────────────────────────┐
│ [Logo] [Nav 1] [Nav 2] [Nav 3] │
├─────────────────────────────────────────────────┤
│ │
│ Headline Text Here │
│ Supporting copy that explains │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Card 1 │ │ Card 2 │ │ Card 3 │ │
│ │ ------ │ │ ------ │ │ ------ │ │
│ │ text │ │ text │ │ text │ │
│ │ [CTA] │ │ [CTA] │ │ [CTA] │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ [ Primary Action ] │
│ │
├─────────────────────────────────────────────────┤
│ Footer | Links | Here │
└─────────────────────────────────────────────────┘
Annotations:
- Logo: Links to homepage
- Primary Action: 44px height, full contrast
- Cards: Equal height, responsive (1 col mobile, 3 col desktop)Include: hierarchy (what's most important), states (error, loading, empty), responsive notes, accessibility annotations.
---
Quality Criteria
Before delivering any output, verify:
Thinking Checks
- [ ] Did I identify the real problem, not just the symptom?
- [ ] Did I consider what happens beyond the screen?
- [ ] Did I match my approach to the problem complexity?
- [ ] Did I design for the full job (functional + emotional + social)?
Design Checks
- [ ] Does every element serve a purpose?
- [ ] Is cognitive load minimised?
- [ ] Are conventions followed (or deliberately broken with reason)?
- [ ] Are the peaks and endings designed intentionally?
Accessibility Checks
- [ ] 4.5:1 contrast for text, 3:1 for UI components
- [ ] All functionality keyboard accessible
- [ ] Form inputs have visible labels
- [ ] Error messages are clear and actionable
- [ ] Focus states are visible
Output Checks
- [ ] Does this output support the decision that needs to be made?
- [ ] Is the fidelity appropriate (not over-designed for the stage)?
- [ ] Are annotations clear for whoever receives this?
---
Quick Reference
Check colour contrast:
python ~/.agents/skills/holistic-ux/scripts/contrast-check.py #333333 #ffffffDeep dives:
- Mental models & systems thinking →
references/mental-models.md - Psychology & Laws of UX →
references/design-psychology.md - Service blueprints & JTBD →
references/service-design.md - WCAG 2.1 AA checklist →
references/accessibility.md - UI patterns with when-to-use →
references/patterns.md - Nielsen's heuristics & Norman's principles →
references/heuristics.md
---
Example Interactions
"Review this login screen for usability issues" → Do a heuristic review. Apply Nielsen's 10. Rate severity. Suggest specific fixes.
"Why do users abandon the checkout?" → Think at structure level (Iceberg). Map the current flow. Identify cognitive load issues. Consider emotional journey.
"Design a booking flow" → First: what's the full service? Map the blueprint. Then: user flow with error states. Then: wireframes if needed.
"Make this form accessible" → Reference WCAG 2.1 AA. Check labels, contrast, keyboard nav, error handling. Provide specific fixes.
"This UI feels slow" → Consider Hick's Law (too many choices?), Miller's Law (too much to process?), or actual performance. Reduce cognitive load before assuming technical issues.
---
Remember: Good UX is invisible. If users notice the design, something's probably wrong. Design for the task, not the interface.
Accessibility — WCAG 2.1 AA
Distilled reference for designing accessible experiences. For the full specification, see WCAG 2.1 Quick Reference.
---
Top 10 Rules
These catch ~80% of accessibility issues:
1. Semantic HTML
Use the right element for the job. Buttons for actions, links for navigation, headings for structure.
<!-- Not this -->
<div onclick="submit()">Submit</div>
<!-- This -->
<button type="submit">Submit</button>Semantic HTML gives you keyboard support, screen reader announcements, and focus management for free.
2. Text Alternatives
Every meaningful image needs descriptive alt text. Decorative images get empty alt.
<img src="chart.png" alt="Sales increased 25% in Q4">
<img src="decorative-line.png" alt="">Icon buttons need labels:
<button aria-label="Close dialog">
<svg aria-hidden="true"><!-- X icon --></svg>
</button>3. Colour Contrast
| Element | Minimum ratio |
|---|---|
| Normal text (<18px) | 4.5:1 |
| Large text (≥18px or ≥14px bold) | 3:1 |
| UI components & graphics | 3:1 |
Check with:
python scripts/contrast-check.py #333333 #ffffffCommon failures:
#999on#fff= 2.85:1 (FAIL)#767676on#fff= 4.54:1 (PASS — lightest grey that passes)#333on#fff= 12.63:1 (PASS — comfortable margin)
4. Keyboard Access
All functionality must be keyboard accessible. Tab to navigate, Enter/Space to activate, Escape to dismiss.
- Use native elements (
<button>,<a>,<input>) tabindex="0"for custom interactive elementstabindex="-1"for programmatic focus only- Never use positive tabindex values
5. Visible Focus Indicators
Users must see where keyboard focus is. Never remove focus outlines without providing an alternative.
:focus {
outline: 2px solid #0066CC;
outline-offset: 2px;
}
/* If customising, ensure visibility */
:focus-visible {
outline: 2px solid #0066CC;
outline-offset: 2px;
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.2);
}6. Form Labels
Every input needs a visible, associated label. Placeholder text is not a label.
<label for="email">Email address</label>
<input type="email" id="email" name="email">Group related inputs with <fieldset> and <legend>:
<fieldset>
<legend>Shipping address</legend>
<!-- Address fields -->
</fieldset>7. Heading Hierarchy
Use headings in order (h1 → h2 → h3). Don't skip levels. One h1 per page.
Screen reader users navigate by headings — they're the primary navigation mechanism for assistive technology.
8. ARIA (When Needed)
Use ARIA only when semantic HTML isn't sufficient. First rule of ARIA: don't use ARIA if you can use native HTML.
Common ARIA attributes:
aria-label: Names an element when visible text isn't sufficientaria-describedby: Associates descriptive text with an elementaria-expanded: Indicates whether a collapsible section is openaria-live="polite": Announces dynamic content updatesrole="alert": Announces urgent messages immediatelyaria-invalid="true": Marks a form field with an error
9. Error Messages
Errors must be: identified in text, described clearly, and announced to assistive technology.
<input type="email"
id="email"
aria-invalid="true"
aria-describedby="email-error">
<div id="email-error" role="alert">
Enter a valid email address (e.g., name@example.com)
</div>Don't rely on colour alone — use icons, text, and borders together.
10. Test with Keyboard and Screen Reader
No automated tool catches everything. At minimum:
- Tab through the entire page
- Verify logical focus order
- Check all interactive elements work with Enter/Space
- Test with VoiceOver (Mac: Cmd+F5) or NVDA (Windows)
---
Keyboard Navigation Checklist
[ ] Tab reaches all interactive elements
[ ] Tab order matches visual order
[ ] Enter/Space activates buttons and links
[ ] Escape closes modals, dropdowns, popovers
[ ] Arrow keys navigate within widgets (tabs, menus, radio groups)
[ ] No keyboard traps (can always Tab away)
[ ] Focus visible on every interactive element
[ ] Focus moves into modal on open
[ ] Focus returns to trigger on modal close
[ ] Skip link available ("Skip to main content")---
Modals and Focus Management
When a modal opens: 1. Save the triggering element 2. Move focus to the first focusable element inside the modal 3. Trap Tab within the modal (wrap from last to first element) 4. Close on Escape 5. Return focus to the triggering element on close 6. Prevent background scroll
<div role="dialog"
aria-modal="true"
aria-labelledby="dialog-title">
<h2 id="dialog-title">Confirm action</h2>
<!-- content -->
<button>Cancel</button>
<button>Confirm</button>
</div>---
Dynamic Content
Content that updates without page reload must be announced:
<!-- Polite: announced at next pause (status updates, loading) -->
<div role="status" aria-live="polite">
Your changes have been saved.
</div>
<!-- Assertive: announced immediately (errors, warnings) -->
<div role="alert" aria-live="assertive">
Connection lost. Retrying...
</div>
<!-- Loading state -->
<div role="status" aria-live="polite" aria-busy="true">
Loading results...
</div>---
Colour and Visual
Don't use colour as the only indicator:
Bad: "Fields in red are required"
Good: "Required fields are marked with * (asterisk)"Support both orientations — don't lock to portrait/landscape.
Resizable text — content must work at 200% zoom without horizontal scrolling (at 320px width for vertical content).
Text spacing — no content loss when users adjust:
- Line height: 1.5× font size
- Paragraph spacing: 2× font size
- Letter spacing: 0.12× font size
- Word spacing: 0.16× font size
---
Common Violations Quick Fixes
| Violation | Fix |
|---|---|
<div onclick> instead of button | Use <button> |
| Placeholder as only label | Add <label> element |
| Image without alt | Add descriptive alt or alt="" if decorative |
outline: none without replacement | Add visible focus style |
| Icon button without text | Add aria-label |
| Colour-only error indication | Add icon + text |
Missing page <title> | Add descriptive <title> |
Missing lang attribute | Add <html lang="en"> |
| Auto-playing media | Provide pause/stop control |
| Time limits without extension | Allow user to extend or disable |
---
Testing Quick Reference
Automated (catches ~30% of issues):
- axe DevTools browser extension
- Lighthouse (Chrome DevTools → Audits)
Manual (catches the rest):
- Keyboard navigation test (Tab through everything)
- Screen reader test (VoiceOver on Mac: Cmd+F5)
- Zoom to 200% test
- Colour contrast check
In code:
# Contrast check
python scripts/contrast-check.py #hex1 #hex2---
POUR Principles Summary
| Principle | Question | Key checks |
|---|---|---|
| Perceivable | Can users perceive all content? | Alt text, contrast, captions, no colour-only info |
| Operable | Can users operate all controls? | Keyboard access, focus indicators, no traps, sufficient time |
| Understandable | Can users understand the interface? | Clear labels, error messages, consistent navigation, page language |
| Robust | Does it work with assistive tech? | Valid HTML, ARIA usage, status messages, proper roles |
Design Psychology
Psychological principles that inform good UX decisions. These aren't rules to blindly apply — they're lenses for understanding why designs work or fail.
---
Laws of UX
Hick's Law
The time to make a decision increases logarithmically with the number of options.
In practice:
- 2 options: nearly instant. 10 options: significantly slower. 50 options: paralysis.
- This applies to navigation menus, settings pages, product listings, form dropdowns.
Design applications:
- Progressive disclosure: Show 4-6 items, reveal more on demand
- Smart defaults: Pre-select the most common option
- Categorisation: Group 20 options into 4 categories of 5
- Search: When options exceed ~15, offer search instead of scanning
Common mistake: Showing everything "for transparency." Users don't want transparency; they want to accomplish their goal. Show what's relevant.
Fitts's Law
The time to reach a target is a function of target size and distance.
In practice:
- Bigger targets are faster to hit
- Closer targets are faster to reach
- Corners and edges of screens are effectively infinite size (cursor stops there)
Design applications:
- Primary actions: Large buttons, prominent placement
- Touch targets: Minimum 44×44px (WCAG), ideally 48×48px
- Mobile: Place key actions within thumb reach zone
- Destructive actions: Smaller and further from primary actions
- Toolbar grouping: Related actions close together
Thumb zone (mobile):
┌─────────────┐
│ Hard to │
│ reach │
│ │
│ Comfortable │
│ zone │
│ │
│ Easy to │
│ reach │
└─────────────┘Place primary actions in the bottom third of mobile screens.
Miller's Law
Working memory holds approximately 7 (±2) items.
In practice:
- People can process ~4-7 distinct chunks simultaneously
- More recent research suggests the effective limit is closer to 4
- This applies to navigation items, steps in a process, items in a list before grouping
Design applications:
- Chunking: Break long numbers (1234567890 → 123 456 7890)
- Visual grouping: Use whitespace and borders to create chunks
- Wizard patterns: Break 15-field forms into 3-5 steps
- Navigation: Keep top-level items to 5-7
Common mistake: Using Miller's Law as a hard rule. It's about cognitive chunks, not a literal count. Five complex items can be harder than eight simple ones.
Peak-End Rule
People judge experiences by the peak (most intense moment) and the end, not the average.
In practice:
- A terrible 2-minute wait followed by a delightful confirmation = "good experience"
- A smooth process with a confusing final step = "frustrating experience"
Design applications:
- Design the peak: What's the emotional high point? Make it memorable.
- End well: Confirmation screens, success messages, "what's next" guidance
- Error recovery: If something goes wrong, the recovery experience IS the experience
- Onboarding: The first completed action should feel rewarding
Examples:
- Mailchimp's "high five" after sending a campaign (positive peak)
- Smooth payment → confusing delivery status (bad ending ruins it)
- Hard sign-up → instant "aha moment" in product (peak redeems the pain)
Jakob's Law
Users spend most of their time on other websites/apps. They expect yours to work the same way.
In practice:
- Users bring expectations from every other digital product they use
- Breaking conventions creates friction, even if your way is "objectively better"
- This is why design consistency across an industry matters
Design applications:
- Navigation: Top bar or hamburger. Users know where to look.
- E-commerce: Cart icon top-right. Product grid. Filters on left.
- Forms: Labels above inputs. Submit button at bottom.
- Search: Magnifying glass icon. Top of page.
When to break conventions: Only when the convention actively hurts your users, and you can teach the new pattern quickly. Breaking conventions requires extra investment in discoverability.
Aesthetic-Usability Effect
Users perceive aesthetically pleasing designs as more usable.
In practice:
- Beautiful interfaces are given more patience during problems
- Users blame themselves for errors in attractive UIs ("I must have done something wrong")
- Users blame the system for errors in ugly UIs ("This thing is broken")
Design applications:
- Visual polish creates a trust buffer
- But aesthetics can't paper over fundamental usability problems
- Invest in visual design last, after core interactions work
- Consider it a form of emotional accessibility
Caution: Don't use this as an excuse to ship pretty but unusable products. The effect buys tolerance, not satisfaction.
Doherty Threshold
Productivity increases when response time is under 400ms.
In practice:
- Under 100ms: feels instantaneous
- 100-400ms: feels responsive
- Over 1000ms: user attention wanders
Design applications:
- Optimistic UI: Update the interface before the server confirms
- Skeleton screens: Show layout immediately, fill in data
- Progress indicators: For anything over 1 second
- Chunked loading: Load visible content first
Von Restorff Effect (Isolation Effect)
Items that stand out from their surroundings are more memorable.
Design applications:
- CTAs: Primary buttons should visually contrast with everything else
- Pricing tables: Highlight the recommended plan
- Warnings: Use colour and icons to distinguish from regular content
- Onboarding: Highlight new features distinctly
---
Cognitive Load Theory
Three Types of Cognitive Load
Intrinsic load: Inherent complexity of the task itself.
- Filing taxes is inherently complex. Can't simplify the tax code.
- Support with: scaffolding, examples, tooltips, contextual help.
Extraneous load: Complexity added by poor design.
- Confusing navigation, unclear labels, unnecessary animation, inconsistent patterns.
- Eliminate ruthlessly. This is the designer's primary responsibility.
Germane load: Effort spent building understanding.
- Learning how the interface works. Forming mental models.
- Support with: consistent patterns, clear feedback, progressive complexity.
Reducing Extraneous Load
Content:
- Remove words that don't add meaning
- Use plain language (reading age 12-14)
- Front-load important information
Visual:
- Remove decorative elements that don't guide attention
- Use whitespace to create visual hierarchy
- Limit colour palette to functional uses
Interaction:
- Reduce steps to complete tasks
- Eliminate redundant confirmations
- Pre-fill what you already know
Navigation:
- Clear current location (breadcrumbs, active states)
- Predictable back button behaviour
- Consistent menu structure across pages
Attention and Scanning
People don't read; they scan. (Steve Krug, "Don't Make Me Think")
F-pattern scanning: Users scan left-to-right, then down the left edge.
- Place important content top-left
- Use headings as scanning anchors
- Left-align key information
Visual hierarchy drives scanning order: 1. Large, high-contrast elements (headlines) 2. Images (especially faces) 3. Colour blocks (buttons, alerts) 4. Body text (only if the above caught interest)
---
Krug's Principles
From Steve Krug's "Don't Make Me Think":
People Satisfice
Users don't pick the best option; they pick the first reasonable option. This means:
- The optimal layout doesn't matter if users leave at a "good enough" option
- Clear labels are more important than clever ones
- Obvious paths beat optimal paths
People Don't Figure Out How Things Work
Users muddle through. They find something that works and stick with it, even if it's not the intended path. This means:
- Design for the actual behaviour, not the intended behaviour
- If people misuse a feature consistently, the feature is wrong
- "The user is always right" (about what they're trying to do, not how)
Get Rid of Half the Words, Then Get Rid of Half of What's Left
Every word competes for attention. Less text = more of it gets read.
- Instructions that nobody reads don't exist
- Error messages should be 1-2 sentences max
- If you need a paragraph to explain something, simplify the thing
---
Emotional Design (Don Norman)
Three Levels of Processing
Visceral (automatic, immediate):
- First impression of visual design
- Snap judgements about trustworthiness
- "Does this look professional?"
Behavioural (subconscious, during use):
- Does it work as expected?
- Is the feedback clear?
- Does interaction feel smooth?
Reflective (conscious, after use):
- How do I feel about using this?
- Would I recommend it?
- Does it align with my self-image?
Design across all three:
- Visceral: Clean, professional visual design
- Behavioural: Responsive, predictable interactions
- Reflective: Brand alignment, storytelling, social proof
---
Decision-Making in Practice
When reviewing a design, use these as diagnostic questions:
| If you observe... | Consider... |
|---|---|
| Users hesitate | Hick's Law — too many choices? |
| Users miss the CTA | Fitts's Law — too small/far? Von Restorff — doesn't stand out? |
| Users make errors | Extraneous cognitive load? Unclear labels? |
| Users don't complete flows | Peak-End — is the ending bad? Steps too many (Miller's)? |
| Users use workarounds | Jakob's Law — breaking conventions? |
| Users say "it feels slow" | Doherty Threshold — above 400ms? Or cognitive load (feels slow)? |
| Users say "it's confusing" | Mental model mismatch. Their model ≠ your model. |
Heuristics & Design Principles
Quick reference for established evaluation frameworks.
---
Nielsen's 10 Usability Heuristics
Use these to evaluate existing designs. For each violation, rate severity (1-4).
1. Visibility of System Status
The system should keep users informed about what's happening through appropriate feedback within reasonable time.
Check: Does the user always know what's happening? Loading states, progress indicators, success/error feedback.
2. Match Between System and Real World
Use language, concepts, and conventions familiar to the user, not system-oriented terms.
Check: Would a non-technical user understand every label, message, and instruction?
3. User Control and Freedom
Provide undo, redo, and clear "emergency exits" from unwanted states.
Check: Can users easily back out, undo, or cancel? Is there always a way out?
4. Consistency and Standards
Follow platform conventions. Same words and actions should mean the same thing throughout.
Check: Are labels, icons, and interactions consistent? Does it follow platform conventions?
5. Error Prevention
Design to prevent errors before they happen. Eliminate error-prone conditions or present confirmation.
Check: Does the design prevent common mistakes? Are destructive actions confirmed?
6. Recognition Rather Than Recall
Minimise memory load. Make objects, actions, and options visible.
Check: Can users see what they need, or do they have to remember it?
7. Flexibility and Efficiency of Use
Provide shortcuts for expert users without confusing novices.
Check: Are there accelerators (keyboard shortcuts, recent items, defaults) for power users?
8. Aesthetic and Minimalist Design
Every piece of information competes for attention. Remove what doesn't serve the user's task.
Check: Does every element on screen earn its place? Is there visual noise?
9. Help Users Recognise, Diagnose, and Recover from Errors
Error messages should be in plain language, indicate the problem precisely, and suggest a solution.
Check: Are error messages human-readable with clear next steps?
10. Help and Documentation
Ideally the system needs no explanation, but provide documentation focused on the user's task.
Check: Is help available in context? Is it task-oriented, not feature-oriented?
Severity Ratings
| Rating | Level | Impact |
|---|---|---|
| 4 | Catastrophic | Blocks users from completing their goal |
| 3 | Major | Significant friction; users may give up |
| 2 | Minor | Annoying but users find workarounds |
| 1 | Cosmetic | Polish issue; fix when convenient |
---
Norman's Design Principles
From Don Norman's "The Design of Everyday Things":
Affordances
Properties that suggest how something can be used.
- A button affords pressing. A slider affords sliding.
- Digital affordances: raised appearance → clickable. Underlined text → link.
- Check: Does the element visually suggest its function?
Signifiers
Signals that indicate where actions should take place.
- A door handle is a signifier (push/pull direction). A placeholder is a signifier.
- Check: Is it clear where to click, tap, or type?
Mapping
Relationship between controls and their effects.
- Light switch position maps to on/off. Slider left-right maps to less-more.
- Check: Is the relationship between action and outcome intuitive?
Feedback
Information about the result of an action.
- Button press → visual change. Form submit → success message.
- Feedback must be immediate, informative, and proportional.
- Check: Does every action produce visible feedback?
Constraints
Limitations that guide correct use.
- Greyed-out buttons prevent invalid actions. Date pickers prevent invalid dates.
- Check: Does the design prevent misuse through constraints?
Conceptual Models
The user's understanding of how the system works.
- Files and folders (desktop metaphor). Shopping cart (e-commerce).
- Check: Does the user's mental model match the system model?
---
Shneiderman's 8 Golden Rules
Quick reference for interface design evaluation:
1. Strive for consistency — same actions, terminology, and layout across screens 2. Cater to universal usability — accommodate novices and experts 3. Offer informative feedback — every action should produce a visible response 4. Design dialogues to yield closure — multi-step tasks need clear beginning, middle, end 5. Prevent errors — design so errors can't happen, or are easy to recover from 6. Permit easy reversal of actions — undo reduces anxiety and encourages exploration 7. Keep users in control — they initiate actions, not the system 8. Reduce short-term memory load — don't require users to remember info across screens
---
Heuristic Evaluation Process
Setup
1. Define scope — which screens/flows to evaluate 2. Select heuristics — Nielsen's 10 is standard; add Norman's if evaluating interaction quality 3. Prepare — walk through the interface as a user first
Evaluation
For each screen/interaction: 1. Walk through user tasks 2. Compare against each heuristic 3. Note violations with:
- Heuristic violated (which one)
- Location (where in the interface)
- Description (what's wrong)
- Severity (1-4)
- Recommendation (specific fix)
Reporting
## Finding: [Short title]
**Heuristic:** #4 Consistency and Standards
**Severity:** 3 (Major)
**Location:** Settings > Profile page
**Issue:** "Save" button is labelled "Update" on this page but "Save" everywhere else.
**Recommendation:** Use "Save" consistently across all pages.Tips
- Evaluate independently before discussing with others (avoids groupthink)
- Multiple evaluators catch more issues (3-5 is ideal)
- Focus on problems, not preferences ("I don't like the colour" isn't a heuristic violation)
- Prioritise by severity × frequency
- Include positive findings too — what works well and why
Mental Models & Systems Thinking
Deep-dive reference for the thinking frameworks in SKILL.md.
---
The Iceberg Model
Most design problems surface as events (what happened). Effective design addresses deeper levels.
Level 1: Events (Surface)
What we observe. Symptoms, metrics, complaints.
| Event | Tempting Fix |
|---|---|
| Users abandon checkout at step 3 | Redesign step 3 |
| Support tickets spike after release | Add FAQ page |
| Users can't find settings | Make settings icon bigger |
Events are where stakeholders start conversations. Don't stop here.
Level 2: Patterns (Trends)
What recurs over time. Trends, correlations, repeated behaviours.
| Event | Pattern |
|---|---|
| Abandonment at step 3 | Always on mobile, always address entry |
| Support ticket spike | Spikes follow every release, same confusion |
| Can't find settings | New users only; power users know the path |
Patterns reveal whether this is isolated or systemic.
Level 3: Structures (Systems)
What enables the patterns. Processes, architectures, incentive structures.
| Pattern | Structure |
|---|---|
| Mobile address entry fails | Form was designed for desktop; mobile keyboard covers input fields |
| Every release causes confusion | No onboarding update process when features change |
| New users get lost | IA designed by engineering teams, maps to codebase not mental model |
Structures are where design interventions have lasting impact.
Level 4: Mental Models (Assumptions)
What beliefs created the structures. Organisational assumptions, cultural norms.
| Structure | Mental Model |
|---|---|
| Desktop-first forms | "Most users are on desktop" (2015 assumption, now wrong) |
| No onboarding updates | "Users will figure it out" (engineer's curse of knowledge) |
| Engineering-driven IA | "Logical structure = usable structure" |
Changing mental models is the hardest but most impactful intervention.
Applying the Iceberg
When handed a design problem: 1. Name the event — What specifically happened? 2. Find the pattern — Has this happened before? Under what conditions? 3. Identify the structure — What system enables this? 4. Examine the assumption — Why was it built this way?
Then decide: Do you need a quick fix (event level) or a systemic change (structure level)?
---
Cynefin Framework for Design
Developed by Dave Snowden. Helps match your approach to the type of problem.
Clear (formerly "Obvious")
Characteristics: Cause and effect obvious. Best practices exist. Approach: Sense → Categorise → Respond
UX examples:
- Button placement for conversion optimisation
- Standard form layouts
- Applying an existing design system
What to do: Apply known patterns. Don't reinvent. Use UI pattern libraries and accessibility checklists.
Complicated
Characteristics: Cause and effect discoverable with expertise. Multiple valid solutions. Approach: Sense → Analyse → Respond
UX examples:
- Information architecture restructure
- Complex dashboard design
- Multi-step onboarding flow
What to do: Research first. Card sorts, user interviews, competitive analysis. Analyse, then design.
Complex
Characteristics: Cause and effect only visible in retrospect. Emergent behaviour. Approach: Probe → Sense → Respond
UX examples:
- "Why don't users trust our brand?"
- "How should we enter a new market?"
- "Why is engagement declining despite good usability metrics?"
What to do: Run safe experiments. Prototype and test. Look for patterns that emerge. Don't try to plan your way to certainty.
Chaotic
Characteristics: No discernible cause and effect. Urgent. Approach: Act → Sense → Respond
UX examples:
- Production outage with user impact
- Security breach affecting user data
- Critical accessibility lawsuit
What to do: Stabilise first. Fix the immediate problem. Learn from it later.
The Disorder Zone
When you don't know which domain you're in, you're in disorder. The danger is applying your favourite approach regardless.
Common mistakes:
- Treating complex problems as complicated (over-planning)
- Treating complicated problems as clear (under-researching)
- Treating clear problems as complex (over-thinking)
---
Systems Thinking Concepts
Feedback Loops
Reinforcing (positive) loops amplify change:
Good reviews → More users → More reviews → Even more usersDesign implication: Identify virtuous cycles and design to strengthen them.
Balancing (negative) loops resist change:
More features → More complexity → Harder to use → Fewer users → Demand for simplicityDesign implication: Feature creep has natural consequences. Design constraints are a feature.
Leverage Points
Small changes with big effects. Donella Meadows' hierarchy (simplified for UX):
1. Paradigm (most powerful): Changing what the organisation believes about users 2. Goals: Changing success metrics from "engagement" to "task completion" 3. Rules: Changing what's allowed (e.g., "no feature ships without accessibility audit") 4. Information flow: Making user pain visible to decision-makers 5. Parameters (least powerful): Changing a button colour
Most UX work happens at the parameter level. The biggest impact is at the information flow and goals level.
Conway's Law
Organisations design systems that mirror their communication structures.
Implication for UX: If the billing team and account team don't talk to each other, the user will experience a disjointed billing-to-account flow. You can redesign the interface all you like — the seams will reappear unless the org changes.
When you spot a UX seam: Ask whether it mirrors an organisational boundary. If so, the fix is coordination, not just design.
Second-Order Effects
Every design decision has consequences beyond the immediate:
| Decision | First-order effect | Second-order effect |
|---|---|---|
| Add social login | Easier registration | Less control over user data |
| Gamify with points | Higher engagement | Users game the system |
| Auto-play videos | More views | User annoyance, accessibility issues |
| Infinite scroll | More time on site | Harder to find specific content |
Before committing to a design: Ask "and then what?" at least twice.
---
Applying These Models Together
Example: "Users aren't completing onboarding"
1. Iceberg: Event (drop-off at step 4) → Pattern (happens with enterprise users) → Structure (onboarding assumes individual use, not team setup) → Mental model ("users are individuals")
2. Cynefin: This is complicated (multiple valid approaches, needs analysis). Don't just A/B test step 4 — that treats it as clear.
3. Systems: The enterprise sales team promises "easy setup" → Creates expectations that onboarding can't meet → This is a feedback loop between sales and product.
4. Leverage point: Not in the UI. In the information flow between sales and product teams about what "easy" means.
The right design intervention: Might be a different onboarding path for enterprise, or it might be changing what sales promises. Either way, the answer wasn't "make step 4 better."
UI Patterns
When-to-use guidance for common interface patterns. Not a spec library — a decision guide.
---
Navigation
When to Use What
| Pattern | Use when | Avoid when |
|---|---|---|
| Top nav bar | ≤7 primary sections, desktop-first | Many sections, deeply nested |
| Hamburger menu | Mobile, space-constrained | Desktop (hides important nav) |
| Tab bar (mobile) | 3-5 key sections in mobile app | >5 sections, nested content |
| Sidebar | Many sections, hierarchical content (dashboards, docs) | Simple sites, mobile-primary |
| Tabs | Content in distinct categories on one page | >6 tabs, unrelated content |
| Breadcrumbs | Deep hierarchies (>2 levels) | Flat sites, linear flows |
Top Navigation
┌────────────────────────────────────────────────────────┐
│ [Logo] Home Products About Contact [🔍] [👤] │
└────────────────────────────────────────────────────────┘- Fixed or sticky at top
- Logo links to home
- Active item distinguished (underline, bold, or colour)
- Collapses to hamburger on mobile
<nav aria-label="Main navigation">- Current page:
aria-current="page"
Hamburger Menu
Closed: [≡] Open: [×]
├── Home
├── Products
├── About
└── Contact- Slide from left/right, 300ms ease
- Trap focus within when open
- Escape key closes
- Backdrop click closes
- Return focus to hamburger on close
aria-expandedtoggles on open/close
Tabs
[Tab 1*] [Tab 2] [Tab 3]
┌────────────────────────────┐
│ Content for Tab 1 │
└────────────────────────────┘- Arrow keys switch tabs
- Active tab:
aria-selected="true" - Panel:
role="tabpanel"linked viaaria-controls - Content should not cause page scroll jump on switch
Breadcrumbs
Home > Products > Electronics > Laptops<nav aria-label="Breadcrumb">with<ol>- Current page:
aria-current="page", not a link - Only for hierarchical navigation, not linear flows
---
Forms
Layout Principles
- Single column — always. Two-column forms slow completion.
- Labels above inputs — better scanning, works at all widths
- 16px minimum font — prevents iOS zoom on focus
- One primary action per form
- Group related fields with visual spacing or fieldsets
Validation States
| State | Visual | Behaviour |
|---|---|---|
| Default | Grey border | — |
| Focus | Blue border + shadow | Validate on blur, not keystroke |
| Valid | Green checkmark | Show after blur if instant feedback helps |
| Error | Red border + icon + message | Show on blur or submit. aria-invalid="true" |
| Disabled | Greyed out, reduced opacity | cursor: not-allowed. Explain why if not obvious |
Form Pattern
┌────────────────────────────┐
│ Field Label * │
│ [____________________] │
│ Helper text │
│ │
│ Field Label │
│ [____________________] │
│ │
│ [ ] I agree to terms │
│ │
│ [ Submit ] │
└────────────────────────────┘- Required fields: asterisk () with " Required" note
- Helper text: below input, linked with
aria-describedby - Error messages: replace helper text, use
role="alert" - Submit button: match width to inputs or left-align
Long Forms
Break into steps when >7 fields:
Step 1 of 3: Personal Details
[========== ] 33%
First Name *
[____________________]
Last Name *
[____________________]
[← Back] [Next →]- Progress indicator (bar or steps)
- Allow back navigation without data loss
- Validate per step, not just at end
- Show step count
---
Cards
When to Use Cards
- Displaying collections of similar items
- Each item has image + text + action
- Items can be compared or scanned
Basic Card
┌────────────────────┐
│ [Image] │
├────────────────────┤
│ Title │
│ Description... │
│ [Action] │
└────────────────────┘- Border-radius: 8px
- Subtle shadow, increased on hover
- Equal height within rows (CSS Grid)
- If clickable, entire card is the link
- Hover: slight elevation change (200ms ease)
Responsive Grid
| Viewport | Columns | Gap |
|---|---|---|
| Mobile (<768px) | 1 | 16px |
| Tablet (768-1023px) | 2 | 16px |
| Desktop (≥1024px) | 3-4 | 24px |
.card-grid {
display: grid;
gap: 16px;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}---
Modals
When to Use (and When Not)
Use modals for:
- Confirmations ("Delete this item?")
- Focused tasks that don't need full context
- Urgent messages requiring action
Don't use modals for:
- Information that could be inline
- Complex multi-step flows (use a page)
- Content users need to reference while doing other things
Modal Structure
┌─────────────────────────────┐
│ Title [×] │
├─────────────────────────────┤
│ │
│ Content │
│ │
├─────────────────────────────┤
│ [Cancel] [Confirm] │
└─────────────────────────────┘- Max-width: 600px, centred
- Backdrop: semi-transparent overlay
- Focus trap: Tab cycles within modal
- Escape closes
- Return focus to trigger on close
role="dialog",aria-modal="true",aria-labelledby
Destructive Confirmation
┌───────────────────────────┐
│ ⚠ Delete account? [×] │
├───────────────────────────┤
│ │
│ This permanently deletes │
│ all your data. This │
│ cannot be undone. │
│ │
├───────────────────────────┤
│ [Cancel] [Delete] │
└───────────────────────────┘- Explain consequences clearly
- Cancel is default/primary visual weight
- Destructive action uses danger colour
- Consider requiring typed confirmation for irreversible actions
---
Buttons
Hierarchy
| Level | Style | Use for |
|---|---|---|
| Primary | Solid fill, high contrast | Main action per section |
| Secondary | Outlined | Supporting actions |
| Tertiary | Text only | Low-priority actions |
| Danger | Red fill or outlined | Destructive actions |
One primary button per visible section. Multiple primaries = no hierarchy.
Sizing
| Context | Height | Min width | Touch target |
|---|---|---|---|
| Mobile | 48px | 120px | 44×44px minimum |
| Desktop | 40px | 100px | — |
| Compact | 32px | 80px | Only in toolbars/dense UI |
States
Every button needs: default, hover, focus, active (pressed), disabled, loading.
- Disabled: 50% opacity,
cursor: not-allowed, explain why if possible - Loading: Replace label with spinner, prevent double-submit, keep button width stable
Icon Buttons
<button aria-label="Close">
<svg aria-hidden="true"><!-- icon --></svg>
</button>Minimum 40×40px (44×44px on mobile). Always provide aria-label.
---
Loading
Choosing a Pattern
| Pattern | Use when |
|---|---|
| Spinner | Unknown duration, small area |
| Skeleton screen | Known layout, content loading |
| Progress bar | Known progress (upload, multi-step) |
| Optimistic UI | Action likely to succeed (toggle, like) |
Skeleton Screen
┌────────────────────────────┐
│ ▓▓▓▓▓▓▓▓▓▓▓▓ │
│ ▓▓▓▓▓▓ ▓▓▓▓▓▓▓ │
│ │
│ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │
│ ▓▓▓▓▓▓▓▓▓▓ │
└────────────────────────────┘- Match the layout of real content
- Subtle shimmer animation (optional)
- Replace with real content when loaded
role="status",aria-busy="true"while loading
Progress Bar
<div role="progressbar"
aria-valuenow="45"
aria-valuemin="0"
aria-valuemax="100"
aria-label="Upload progress">Show percentage or "Step X of Y" for clarity.
---
Notifications
Choosing a Pattern
| Pattern | Persistence | Use for |
|---|---|---|
| Toast | Auto-dismiss (3-5s) | Success, info confirmations |
| Banner | Persistent until dismissed | System-wide messages, warnings |
| Inline alert | Persistent, contextual | Section-specific info, errors |
Toast
┌────────────────────────┐
│ ✓ Changes saved [×] │
└────────────────────────┘- Position: top-right or bottom-right
- Auto-dismiss: 3-5 seconds (pause on hover)
role="status"for success/inforole="alert"for errors- Stack if multiple (most recent on top)
Inline Alert
┌────────────────────────────┐
│ ⚠ Your trial expires in │
│ 3 days. Upgrade now. │
└────────────────────────────┘- Left border colour indicates type (red/yellow/blue/green)
- Tinted background (10% of border colour)
- Icon reinforces type
- Positioned near relevant content
---
Data Display
Tables
Use when: comparing structured data with multiple attributes.
<table>
<caption>Team members</caption>
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Role</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alice</td>
<td>Engineer</td>
</tr>
</tbody>
</table>- Responsive: horizontal scroll or card view on mobile
- Sortable columns:
aria-sort="ascending" - Alternating row colours for scanability
Accordion
Use when: content is optional/supplementary and users need only some sections.
<button aria-expanded="false" aria-controls="panel1">
Section title
</button>
<div id="panel1" hidden>Content...</div>- Allow multiple sections open (unless space is critical)
- Expand/collapse animation: 200-300ms
- Don't hide critical information in accordions
---
Pattern Selection Cheatsheet
| User Need | Pattern |
|---|---|
| Navigate between sections | Top nav, sidebar, tabs |
| Complete a task | Form (single column, progressive) |
| Browse a collection | Card grid |
| Make a focused decision | Modal |
| Trigger an action | Button (with proper hierarchy) |
| Wait for something | Skeleton, spinner, or progress bar |
| Get feedback | Toast, banner, or inline alert |
| Compare data | Table |
| Read optional detail | Accordion |
Service Design
Designing beyond the screen. Every digital interaction exists within a larger service ecosystem.
---
Service Blueprints
What Is a Service Blueprint?
A service blueprint maps the full service delivery — what the user sees, what happens behind the scenes, and what systems support it all.
Structure
┌─────────────────────────────────────────────────────────┐
│ PHYSICAL EVIDENCE │
│ (What users see/touch: website, emails, physical items) │
├─────────────────────────────────────────────────────────┤
│ CUSTOMER ACTIONS │
│ (What users do at each stage) │
╞═════════════════════════════════════════════════════════╡
│ Line of Interaction │
├─────────────────────────────────────────────────────────┤
│ FRONTSTAGE │
│ (Staff/system interactions users can see) │
╞═════════════════════════════════════════════════════════╡
│ Line of Visibility │
├─────────────────────────────────────────────────────────┤
│ BACKSTAGE │
│ (Staff/system work users can't see) │
╞═════════════════════════════════════════════════════════╡
│ Line of Internal Interaction │
├─────────────────────────────────────────────────────────┤
│ SUPPORT PROCESSES │
│ (Systems, databases, third-party services) │
└─────────────────────────────────────────────────────────┘Example: Restaurant Booking
| Stage | Discover | Book | Confirm | Arrive | Dine | Pay | Follow-up |
|-------|----------|------|---------|--------|------|-----|-----------|
| **Evidence** | Google listing, website | Booking form | Email, SMS | Signage, host | Menu, table | Bill | Review request |
| **Customer** | Search, browse menu | Select date/time/party | Read confirmation | Walk in, give name | Order, eat | Request bill, pay | Rate experience |
| **Frontstage** | Website loads | Availability shown | Auto-email sent | Host greets | Server takes order | POS terminal | Auto-email sent |
| --- | --- | --- | --- | --- | --- | --- | --- |
| **Backstage** | SEO, content management | Check table inventory | Email service triggers | Staff notified via tablet | Kitchen receives order | Process payment | CRM tags customer |
| --- | --- | --- | --- | --- | --- | --- | --- |
| **Support** | Google Business, hosting | Booking DB | SendGrid, Twilio | Staff scheduling app | POS, kitchen display | Payment processor | CRM, review platform |When to Use a Service Blueprint
- Designing a new service end-to-end
- Finding failure points in an existing service
- Understanding operational impact of design changes
- Communicating with non-design stakeholders (ops, engineering, business)
How to Build One
1. Start with customer actions — walk through the user's journey left to right 2. Add physical evidence — what do they see/receive at each point? 3. Map frontstage — what visible interactions support each action? 4. Map backstage — what invisible work enables the frontstage? 5. Add support processes — what systems/tools/services power the backstage? 6. Identify pain points — where do things break? Where are the delays? 7. Mark fail points — use ⚠ symbols where things commonly go wrong
---
Jobs to Be Done (JTBD)
Core Concept
People don't buy products; they hire them to make progress in their lives.
"People don't want a quarter-inch drill bit. They want a quarter-inch hole."
— Theodore Levitt
"They don't want the hole either. They want the shelf on the wall. Actually, they want their books organised."
— Further refinement
Three Dimensions of Every Job
| Dimension | What it means | Example: Choosing a restaurant |
|---|---|---|
| Functional | The practical task | Find food near my location |
| Emotional | How I want to feel | Feel like I'm making a good choice |
| Social | How others perceive me | Impress my date |
Job Story Format
Better than user stories for UX because they focus on situation rather than persona:
When [situation], I want to [motivation], so I can [expected outcome].
Examples:
When I'm booking a flight and see the total price jump at checkout, I want to understand exactly what changed, so I can decide whether to proceed or go back.
When I receive an error after filling out a long form, I want to know exactly which field needs fixing without losing my work, so I can complete the task without starting over.
When I'm comparing subscription plans, I want to see a clear difference between them, so I can pick the right one without second-guessing.
Applying JTBD to Design
1. Identify the job — What progress is the user trying to make? 2. Map the full job — Not just the functional task but emotional and social dimensions 3. Find the struggling moment — Where is current progress blocked? 4. Design for the switch — What would make someone switch from their current solution to yours?
Forces of Progress
┌────────────────────┐
Push of current │ │ Pull of new
situation │ SWITCHING │ solution
──────────► │ DECISION │ ◄──────────
│ │
Anxiety of new │ │ Habit of current
solution │ │ solution
◄────────── └────────────────────┘ ──────────►- Push: Pain with current situation (motivation to change)
- Pull: Attraction of new solution (what draws them)
- Anxiety: Fear of the new (what stops them)
- Habit: Comfort of the familiar (inertia)
Design must: amplify push + pull, reduce anxiety + habit.
---
Ecosystem Mapping
Stakeholder Map
Before designing, understand who's involved:
┌──────────┐
│ End User │
└────┬─────┘
│
┌──────────┼──────────┐
│ │ │
┌─────┴─────┐ ┌─┴────┐ ┌──┴─────┐
│ Customer │ │ Admin│ │ Support│
│ Success │ │ │ │ Agent │
└─────┬─────┘ └──┬───┘ └──┬─────┘
│ │ │
└──────────┼────────┘
│
┌────┴─────┐
│ Business │
│ Owner │
└──────────┘For each stakeholder ask:
- What's their goal?
- What do they need from this service?
- How do they interact with other stakeholders?
- What constraints do they impose?
Touchpoint Inventory
List every point of contact between user and service:
| Touchpoint | Channel | Owner | Quality |
|---|---|---|---|
| Google search result | Web | Marketing | Good |
| Landing page | Web | Product | Needs work |
| Sign-up email | Growth | Good | |
| Onboarding wizard | App | Product | Poor |
| First support ticket | Chat | Support | Good |
| Monthly invoice | Billing | Poor | |
| Cancellation flow | App | Product | Missing |
Look for:
- Gaps (missing touchpoints)
- Inconsistencies (different tone/quality across touchpoints)
- Handoff failures (one team's touchpoint clashes with another's)
---
When to Use What
| Tool | Best for | Scope |
|---|---|---|
| User Flow | Single task completion | One user, one goal |
| Journey Map | Understanding emotional experience | One user, one scenario, over time |
| Experience Map | Understanding behaviour in a domain (no specific product) | One persona, broad context |
| Service Blueprint | Designing/fixing service delivery | Full system including backstage |
| Ecosystem Map | Understanding stakeholder relationships | Multiple actors and their connections |
Journey Map vs Experience Map
Journey map: How does a user experience our product/service?
- Has specific stages related to our service
- Includes our touchpoints
- Helps improve our experience
Experience map: How does a person experience this domain in general?
- Not tied to our product
- Includes competitor and offline touchpoints
- Helps find opportunities
Journey Map vs Service Blueprint
Journey map: Focuses on user's emotional experience.
- What are they feeling at each stage?
- Where are the pain points?
- Where are the moments of delight?
Service blueprint: Focuses on operational delivery.
- What systems support each interaction?
- Where are the failure points?
- What's the operational cost?
Use journey maps to understand the problem. Use service blueprints to design the solution.
---
Service Design Principles
1. Human-centred: Start with people, not technology 2. Collaborative: Include all stakeholders in the design process 3. Iterative: Expect to get it wrong and improve 4. Sequential: Visualise the service as a sequence of interrelated actions 5. Real: Prototype with real-world conditions, not just screens 6. Holistic: Consider the complete environment of the service
"A service is a chain of activities that form a process and have value for the end user."
— If one link in the chain breaks, the experience breaks regardless of how good the UI is.
#!/usr/bin/env python3
"""
Color Contrast Ratio Calculator
WCAG 2.1 compliance checker for color combinations
Usage:
python contrast-check.py #000000 #ffffff
python contrast-check.py 000000 ffffff
python contrast-check.py "#333" "#fff"
"""
import sys
import re
def hex_to_rgb(hex_color):
"""Convert hex color to RGB tuple."""
# Remove # if present
hex_color = hex_color.lstrip('#')
# Handle 3-character hex codes
if len(hex_color) == 3:
hex_color = ''.join([c*2 for c in hex_color])
# Convert to RGB
try:
r = int(hex_color[0:2], 16)
g = int(hex_color[2:4], 16)
b = int(hex_color[4:6], 16)
return (r, g, b)
except (ValueError, IndexError):
raise ValueError(f"Invalid hex color: #{hex_color}")
def relative_luminance(rgb):
"""
Calculate relative luminance according to WCAG formula.
https://www.w3.org/TR/WCAG21/#dfn-relative-luminance
"""
r, g, b = rgb
# Convert to 0-1 range
r = r / 255.0
g = g / 255.0
b = b / 255.0
# Apply gamma correction
r = r / 12.92 if r <= 0.03928 else ((r + 0.055) / 1.055) ** 2.4
g = g / 12.92 if g <= 0.03928 else ((g + 0.055) / 1.055) ** 2.4
b = b / 12.92 if b <= 0.03928 else ((b + 0.055) / 1.055) ** 2.4
# Calculate luminance
return 0.2126 * r + 0.7152 * g + 0.0722 * b
def contrast_ratio(color1, color2):
"""
Calculate contrast ratio between two colors.
https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio
"""
lum1 = relative_luminance(hex_to_rgb(color1))
lum2 = relative_luminance(hex_to_rgb(color2))
# Ensure lighter color is in numerator
lighter = max(lum1, lum2)
darker = min(lum1, lum2)
return (lighter + 0.05) / (darker + 0.05)
def check_wcag_compliance(ratio):
"""Check WCAG 2.1 compliance levels."""
results = {
'ratio': ratio,
'aa_normal': ratio >= 4.5, # Normal text (< 18px or < 14px bold)
'aa_large': ratio >= 3.0, # Large text (>= 18px or >= 14px bold)
'aaa_normal': ratio >= 7.0, # AAA normal text
'aaa_large': ratio >= 4.5, # AAA large text
'ui_components': ratio >= 3.0, # UI components and graphics
}
return results
def print_results(color1, color2, results):
"""Print formatted results."""
ratio = results['ratio']
print("\n" + "="*70)
print(" COLOR CONTRAST CHECKER")
print("="*70)
print(f"\nForeground: {color1.upper()}")
print(f"Background: {color2.upper()}")
print(f"\nContrast Ratio: {ratio:.2f}:1")
print("\n" + "-"*70)
print("WCAG 2.1 COMPLIANCE:")
print("-"*70)
# AA Level
print("\nLevel AA:")
print(f" Normal text (< 18px): {'✓ PASS' if results['aa_normal'] else '✗ FAIL'} (requires 4.5:1)")
print(f" Large text (≥ 18px): {'✓ PASS' if results['aa_large'] else '✗ FAIL'} (requires 3.0:1)")
print(f" UI Components: {'✓ PASS' if results['ui_components'] else '✗ FAIL'} (requires 3.0:1)")
# AAA Level
print("\nLevel AAA:")
print(f" Normal text (< 18px): {'✓ PASS' if results['aaa_normal'] else '✗ FAIL'} (requires 7.0:1)")
print(f" Large text (≥ 18px): {'✓ PASS' if results['aaa_large'] else '✗ FAIL'} (requires 4.5:1)")
print("\n" + "-"*70)
print("RECOMMENDATIONS:")
print("-"*70)
if results['aa_normal']:
print("✓ This color combination meets WCAG 2.1 AA for all text sizes.")
elif results['aa_large']:
print("⚠ This combination only passes for LARGE text (18px+ or 14px+ bold).")
print(" Use larger text or adjust colors for normal-sized text.")
elif results['ui_components']:
print("⚠ This combination only passes for UI components.")
print(" DO NOT use for text. Adjust colors for better contrast.")
else:
print("✗ This color combination FAILS WCAG 2.1 AA requirements.")
print(" You must adjust the colors for accessibility compliance.")
if results['aaa_normal']:
print("★ This combination meets WCAG 2.1 AAA (enhanced contrast).")
print("\n" + "-"*70)
print("TEXT SIZE REFERENCE:")
print("-"*70)
print(" Normal text: < 18px (or < 14px bold)")
print(" Large text: ≥ 18px (or ≥ 14px bold)")
print("\n" + "="*70 + "\n")
def suggest_improvements(color1, color2, results):
"""Suggest color adjustments if contrast is insufficient."""
if results['aa_normal']:
return # Already compliant
ratio = results['ratio']
target = 4.5 # AA normal text requirement
print("SUGGESTIONS FOR IMPROVEMENT:")
print("-"*70)
if ratio < 3.0:
print("⚠ Contrast is very low. Consider these approaches:")
print(" 1. Use a much darker foreground with this background")
print(" 2. Use a much lighter background with this foreground")
print(" 3. Add a contrasting border or outline")
print(" 4. Use a completely different color palette")
elif ratio < 4.5:
print("⚠ Close to compliance. Small adjustments may help:")
print(" 1. Darken the foreground color slightly")
print(" 2. Lighten the background color slightly")
print(" 3. Or adjust both for better contrast")
print("\nCommon approaches:")
print(" • Dark text on light background (e.g., #333 on #fff)")
print(" • Light text on dark background (e.g., #fff on #333)")
print(" • High saturation differences")
print(" • Test with python scripts/contrast-check.py after adjustments")
print()
def main():
if len(sys.argv) != 3:
print("\n" + "="*70)
print(" COLOR CONTRAST CHECKER")
print("="*70)
print("\nUsage:")
print(" python contrast-check.py <foreground> <background>")
print("\nExamples:")
print(" python contrast-check.py #000000 #ffffff")
print(" python contrast-check.py 333 fff")
print(" python contrast-check.py \"#1a1a1a\" \"#f5f5f5\"")
print("\nNote: Both 3-digit and 6-digit hex codes are supported.")
print(" The # symbol is optional.")
print("\n" + "="*70 + "\n")
sys.exit(1)
color1 = sys.argv[1]
color2 = sys.argv[2]
try:
# Validate hex colors
hex_to_rgb(color1)
hex_to_rgb(color2)
# Calculate contrast
ratio = contrast_ratio(color1, color2)
results = check_wcag_compliance(ratio)
# Print results
print_results(color1, color2, results)
suggest_improvements(color1, color2, results)
# Exit code: 0 if AA compliant, 1 if not
sys.exit(0 if results['aa_normal'] else 1)
except ValueError as e:
print(f"\nError: {e}", file=sys.stderr)
print("Please provide valid hex colors (e.g., #000000 or 000 or #fff)\n", file=sys.stderr)
sys.exit(2)
if __name__ == '__main__':
main()