[
MAINHACK
]
Mail Test
BC
Config Scan
HOME
Create...
New File
New Folder
Viewing / Editing File: nhs-case-study.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>NHS Service Finder — Case Study | Rikon Rahman</title> <meta name="description" content="Designing secure access and accessible service journeys for NHS Service Finder — moving 100,000+ health and care professionals to Care Identity Authentication while improving accessibility across critical service journeys." /> <link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Archivo+Black&family=Georgia&family=Instrument+Serif:ital@0;1&family=Manrope:wght@400;500;600;700;800&display=swap" /> <link rel="stylesheet" href="css/style.css" /> <style> /* ========================================================= NHS Case Study — page-scoped styles. All values pull from tokens declared in css/style.css. No hardcoded hex / px outside the existing scale. ========================================================= */ /* ---------- shell ---------- */ .case-study { padding-block: clamp(40px, 5vw, 72px) clamp(64px, 8vw, 120px); } .case-study .container { max-width: 1180px; } .cs-back-wrap { margin-bottom: clamp(24px, 3vw, 36px); } .cs-back { display: inline-flex; align-items: center; gap: 8px; font-weight: 500; font-size: 15px; color: var(--ink-2); transition: color var(--dur) var(--ease), gap var(--dur) var(--ease); } .cs-back__chev { width: 8px; height: 14px; flex: 0 0 auto; } .cs-back:hover { color: var(--accent); gap: 12px; } .cs-back:hover .cs-back__chev { color: var(--accent); } .cs-back:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 4px; } /* ---------- section primitives ---------- */ .cs-section { padding-block: clamp(48px, 6vw, 88px); border-bottom: 1px solid var(--line); } .cs-section:last-of-type { border-bottom: 0; } .cs-section__head { display: flex; flex-direction: column; gap: 14px; max-width: 760px; margin-bottom: clamp(28px, 4vw, 48px); } .cs-section__head--center { margin-inline: auto; text-align: center; align-items: center; } .cs-section__title { margin: 0; font-family: var(--font-serif); font-size: clamp(28px, 3.2vw, 44px); line-height: 1.2; letter-spacing: -0.02em; color: var(--ink); } .cs-section__title em { font-style: italic; color: var(--accent); } .cs-section__sub { font-family: var(--font-sans); font-weight: 800; font-size: 12px; letter-spacing: 2.64px; text-transform: uppercase; color: var(--muted-2); line-height: 18px; } .cs-prose { font-size: 18px; line-height: 28px; color: var(--muted); max-width: 64ch; } .cs-prose + .cs-prose { margin-top: 16px; } .cs-prose strong { color: var(--ink-2); font-weight: 700; } /* Two-column body: lead heading + body copy */ .cs-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: clamp(24px, 3.5vw, 64px); } .cs-body__lead { font-family: var(--font-sans); font-weight: 800; font-size: 13px; letter-spacing: 2.64px; text-transform: uppercase; color: var(--ink); line-height: 18px; } .cs-body__lead + .cs-body__lead-title { margin-top: 14px; font-family: var(--font-serif); font-size: clamp(22px, 2vw, 28px); line-height: 1.25; letter-spacing: -0.01em; color: var(--ink); } /* Inline collaboration / impact note */ .cs-callout { margin-top: 24px; padding: 18px 22px; background: var(--bg-2); border-left: 2px solid var(--accent); border-radius: 4px; font-size: 16px; line-height: 24px; color: var(--ink-2); } .cs-callout strong { color: var(--ink); font-weight: 700; } /* ---------- Hero (case-study header) ---------- */ .cs-hero { padding: clamp(8px, 1vw, 16px) 0 clamp(28px, 3vw, 40px); } /* Text column constrained to ~60% of container, image is full width */ .cs-hero__text { max-width: 720px; } .cs-hero__title { margin: 18px 0 24px; font-family: var(--font-serif); font-size: clamp(36px, 4.6vw, 56px); line-height: 1.14; letter-spacing: -0.02em; color: var(--ink); } .cs-hero__lede { max-width: 640px; font-size: 16px; line-height: 26px; color: var(--muted); } .cs-hero__lede strong { font-weight: 700; color: var(--ink); } /* Hero image (NHS Service Finder composition) — full container width */ .cs-hero-media { margin: clamp(28px, 3vw, 40px) 0 0; border-radius: var(--radius-card); overflow: hidden; background: var(--bg-2); border: 1px solid var(--line); } .cs-hero-media img { display: block; width: 100%; height: auto; } /* ---------- Meta block ---------- */ .cs-meta { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border: 1px solid var(--line); border-radius: var(--radius-card); margin: clamp(20px, 2vw, 28px) 0 0; overflow: hidden; background: transparent; } .cs-meta__cell { display: flex; flex-direction: column; gap: 10px; padding: clamp(20px, 2.2vw, 26px) clamp(20px, 2vw, 28px); border-left: 1px solid var(--line); } .cs-meta__cell:first-child { border-left: 0; } .cs-meta__label { font-family: var(--font-sans); font-weight: 700; font-size: 12px; letter-spacing: 2px; text-transform: uppercase; color: var(--muted-2); } .cs-meta__value { font-size: 16px; line-height: 22px; color: var(--ink); font-weight: 500; } /* ---------- Impact stats grid ---------- */ .cs-impact { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: clamp(12px, 1.4vw, 18px); } .cs-stat { background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-card); padding: clamp(20px, 2vw, 28px); display: flex; flex-direction: column; gap: 12px; min-height: 196px; } .cs-stat__num { font-family: var(--font-display); font-size: clamp(34px, 3.6vw, 48px); line-height: 1; letter-spacing: -0.02em; color: var(--ink); } .cs-stat__num em { font-style: normal; color: var(--accent); } .cs-stat__label { font-family: var(--font-sans); font-weight: 800; font-size: 11px; letter-spacing: 2.4px; text-transform: uppercase; color: var(--accent); } .cs-stat__copy { margin-top: auto; font-size: 14px; line-height: 20px; color: var(--muted); } /* ---------- Numbered problem cards ---------- */ .cs-problems-row { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: clamp(12px, 1.4vw, 18px); margin-bottom: clamp(28px, 3vw, 40px); } .cs-problem-chip { background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-media); padding: 20px 18px; display: flex; flex-direction: column; gap: 12px; min-height: 132px; } .cs-problem-chip__num { font-family: var(--font-display); font-size: 22px; line-height: 1; color: var(--accent); } .cs-problem-chip__label { font-family: var(--font-sans); font-weight: 700; font-size: 14px; line-height: 20px; color: var(--ink); } .cs-problems-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(20px, 2.5vw, 36px); } .cs-problem { display: flex; flex-direction: column; gap: 10px; } .cs-problem__num { font-family: var(--font-display); font-size: 20px; line-height: 1; color: var(--accent); } .cs-problem__title { margin: 0; font-family: var(--font-serif); font-size: clamp(18px, 1.5vw, 22px); line-height: 1.3; letter-spacing: -0.01em; color: var(--ink); } .cs-problem__copy { margin: 0; font-size: 16px; line-height: 24px; color: var(--muted); } .cs-pullquote { margin: clamp(24px, 3vw, 40px) 0 0; padding: clamp(24px, 3vw, 36px) clamp(24px, 3vw, 40px); background: var(--bg-3); border-left: 3px solid var(--accent); border-radius: 4px; font-family: var(--font-serif); font-style: italic; font-size: clamp(20px, 2vw, 26px); line-height: 1.4; letter-spacing: -0.01em; color: var(--ink-2); } .cs-pullquote::before { content: "“"; color: var(--accent); margin-right: 4px; } .cs-pullquote::after { content: "”"; color: var(--accent); margin-left: 4px; } /* ---------- Role contributions (4 columns) ---------- */ .cs-role-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(24px, 3vw, 40px); padding-top: clamp(24px, 3vw, 36px); border-top: 1px solid var(--line); } .cs-role-col { display: flex; flex-direction: column; gap: 18px; } .cs-role-col__head { font-family: var(--font-sans); font-weight: 800; font-size: 12px; letter-spacing: 2.64px; text-transform: uppercase; color: var(--accent); line-height: 18px; } .cs-role-col__list { display: flex; flex-direction: column; gap: 12px; } .cs-role-col__list li { position: relative; padding-left: 18px; font-size: 15px; line-height: 22px; color: var(--ink-2); } .cs-role-col__list li::before { content: ""; position: absolute; left: 0; top: 9px; width: 8px; height: 1px; background: var(--accent); } /* ---------- Chapter marker ---------- */ .cs-chapter { display: grid; grid-template-columns: auto 1fr; gap: clamp(20px, 2vw, 28px); align-items: end; padding-bottom: clamp(20px, 2vw, 28px); border-bottom: 1px solid var(--line); margin-bottom: clamp(40px, 5vw, 64px); } .cs-chapter__num { font-family: var(--font-display); font-size: clamp(56px, 7vw, 96px); line-height: 0.85; letter-spacing: -0.04em; color: var(--accent); } .cs-chapter__meta { display: flex; flex-direction: column; gap: 6px; padding-bottom: 8px; } .cs-chapter__label { font-family: var(--font-sans); font-weight: 800; font-size: 12px; letter-spacing: 2.64px; text-transform: uppercase; color: var(--muted-2); } .cs-chapter__title { margin: 0; font-family: var(--font-serif); font-size: clamp(24px, 2.4vw, 32px); line-height: 1.2; letter-spacing: -0.02em; color: var(--ink); } /* ---------- USER STATE table ---------- */ .cs-table { margin-top: clamp(28px, 3vw, 40px); border: 1px solid var(--line); border-radius: var(--radius-card); overflow: hidden; background: var(--bg-2); } .cs-table__row { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1.2fr) minmax(0, 1fr); gap: clamp(16px, 2vw, 32px); padding: 18px clamp(20px, 2vw, 28px); border-bottom: 1px solid var(--line); } .cs-table__row:last-child { border-bottom: 0; } .cs-table__row--head { background: var(--bg-3); } .cs-table__row--head > * { font-family: var(--font-sans); font-weight: 800; font-size: 11px; letter-spacing: 2.4px; text-transform: uppercase; color: var(--muted-2); } .cs-table__cell { font-size: 15px; line-height: 22px; color: var(--ink-2); } .cs-table__cell--state { font-weight: 700; color: var(--ink); } .cs-table__cell--risk { color: var(--muted); } .cs-table__cell--route { font-family: var(--font-italic-serif); font-style: italic; color: var(--accent); } /* ---------- Migration timeline (6 phases) ---------- */ .cs-legend { display: flex; flex-wrap: wrap; gap: 20px; margin-top: clamp(20px, 2vw, 28px); } .cs-legend__item { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted-2); } .cs-legend__swatch { display: inline-block; width: 12px; height: 12px; border-radius: 3px; } .cs-legend__swatch--owned { background: var(--accent); } .cs-legend__swatch--wider { background: transparent; border: 1.5px solid var(--muted-2); } .cs-legend__swatch--aligned { background: transparent; border: 1.5px dashed var(--accent); } .cs-timeline { margin-top: clamp(20px, 2vw, 28px); display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: clamp(12px, 1.4vw, 18px); } .cs-timeline__col { background: var(--bg-2); border-top: 3px solid var(--accent); border-radius: 0 0 var(--radius-media) var(--radius-media); padding: 18px 16px; display: flex; flex-direction: column; gap: 10px; } .cs-timeline__phase { font-family: var(--font-sans); font-weight: 800; font-size: 11px; letter-spacing: 2.4px; text-transform: uppercase; color: var(--accent); } .cs-timeline__when { font-size: 12px; color: var(--muted-2); font-style: italic; font-family: var(--font-italic-serif); } .cs-timeline__list { display: flex; flex-direction: column; gap: 6px; font-size: 13px; line-height: 18px; color: var(--ink-2); } /* ---------- Setup vs Login comparison ---------- */ .cs-compare { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(16px, 2vw, 28px); margin-top: clamp(24px, 3vw, 36px); } .cs-compare__col { background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-card); padding: clamp(24px, 2.5vw, 32px); display: flex; flex-direction: column; gap: 16px; } .cs-compare__label { font-family: var(--font-sans); font-weight: 800; font-size: 11px; letter-spacing: 2.4px; text-transform: uppercase; color: var(--accent); } .cs-compare__title { margin: 0; font-family: var(--font-serif); font-size: clamp(20px, 1.8vw, 24px); line-height: 1.25; color: var(--ink); } .cs-steps { display: flex; flex-direction: column; gap: 14px; counter-reset: step; } .cs-steps__item { display: grid; grid-template-columns: 28px 1fr; gap: 14px; align-items: start; } .cs-steps__num { display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--paper); border: 1px solid var(--line); color: var(--accent); font-family: var(--font-display); font-size: 14px; } .cs-steps__body { font-size: 15px; line-height: 22px; color: var(--ink-2); } .cs-steps__sub { display: block; font-size: 13px; color: var(--muted); margin-top: 2px; } /* ---------- Recovery state cards ---------- */ .cs-recovery { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(16px, 1.8vw, 22px); margin-top: clamp(24px, 3vw, 36px); } .cs-recovery-card { background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-card); padding: clamp(20px, 2vw, 26px); display: flex; flex-direction: column; gap: 12px; } .cs-recovery-card__label { font-family: var(--font-sans); font-weight: 800; font-size: 11px; letter-spacing: 2.4px; text-transform: uppercase; color: var(--accent); } .cs-recovery-card__title { margin: 0; font-family: var(--font-serif); font-size: 17px; line-height: 1.3; color: var(--ink); } .cs-recovery-card__copy { font-size: 14px; line-height: 20px; color: var(--muted); } .cs-recovery-card__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: auto; padding-top: 8px; } .cs-recovery-card__action { font-size: 12px; padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--radius-pill); color: var(--ink-2); background: var(--paper); } .cs-recovery-card__action:first-child { background: var(--accent); border-color: var(--accent); color: #fff; } /* ---------- Decision matrix table ---------- */ .cs-matrix { display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.6fr) minmax(0, 1.2fr); margin-top: clamp(24px, 3vw, 36px); border: 1px solid var(--line); border-radius: var(--radius-card); overflow: hidden; background: var(--bg-2); } .cs-matrix > * { padding: 16px clamp(18px, 2vw, 24px); border-bottom: 1px solid var(--line); font-size: 15px; line-height: 22px; color: var(--ink-2); } .cs-matrix > *:nth-last-child(-n+3) { border-bottom: 0; } .cs-matrix__head { background: var(--bg-3); font-family: var(--font-sans); font-weight: 800; font-size: 11px !important; letter-spacing: 2.4px; text-transform: uppercase; color: var(--muted-2); } .cs-matrix__type { font-weight: 700; color: var(--ink); } .cs-matrix__decision { font-family: var(--font-italic-serif); font-style: italic; color: var(--accent); } /* ---------- Quick fixes / Structural issues split ---------- */ .cs-split { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(20px, 2.5vw, 36px); margin-top: clamp(24px, 3vw, 36px); } .cs-split__col { padding: clamp(20px, 2.4vw, 28px); border: 1px solid var(--line); border-radius: var(--radius-card); background: var(--bg-2); } .cs-split__label { font-family: var(--font-sans); font-weight: 800; font-size: 12px; letter-spacing: 2.64px; text-transform: uppercase; color: var(--accent); } .cs-split__copy { margin-top: 10px; font-size: 16px; line-height: 24px; color: var(--ink-2); } /* ---------- Sample Jira ticket ---------- */ .cs-ticket { margin-top: clamp(24px, 3vw, 36px); background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-card); overflow: hidden; } .cs-ticket__head { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; padding: 16px clamp(20px, 2.4vw, 28px); background: var(--bg-3); border-bottom: 1px solid var(--line); } .cs-ticket__tag { display: inline-flex; align-items: center; padding: 4px 10px; font-size: 11px; letter-spacing: 1.6px; text-transform: uppercase; font-weight: 800; border-radius: var(--radius-pill); } .cs-ticket__tag--design { background: var(--accent); color: #fff; } .cs-ticket__tag--id { background: var(--paper); color: var(--ink-2); border: 1px solid var(--line); } .cs-ticket__tag--type { background: transparent; color: var(--muted-2); } .cs-ticket__title { margin: 0; padding: 18px clamp(20px, 2.4vw, 28px) 8px; font-family: var(--font-serif); font-size: clamp(20px, 2vw, 26px); line-height: 1.25; letter-spacing: -0.01em; color: var(--ink); } .cs-ticket__rows { padding: 8px clamp(20px, 2.4vw, 28px) 24px; } .cs-ticket__row { display: grid; grid-template-columns: 180px 1fr; gap: 16px; padding: 14px 0; border-top: 1px solid var(--line); } .cs-ticket__row:first-child { border-top: 0; } .cs-ticket__row-label { font-family: var(--font-sans); font-weight: 800; font-size: 11px; letter-spacing: 2.4px; text-transform: uppercase; color: var(--muted-2); padding-top: 2px; } .cs-ticket__row-body { font-size: 15px; line-height: 22px; color: var(--ink-2); } /* ---------- Three priority levels ---------- */ .cs-priorities { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(16px, 2vw, 24px); margin-top: clamp(24px, 3vw, 36px); } .cs-priority { padding: clamp(20px, 2vw, 26px); background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--radius-card); display: flex; flex-direction: column; gap: 10px; } .cs-priority__label { font-family: var(--font-sans); font-weight: 800; font-size: 11px; letter-spacing: 2.4px; text-transform: uppercase; color: var(--accent); } .cs-priority__copy { font-size: 15px; line-height: 22px; color: var(--ink-2); } /* ---------- Result before/after card mockups ---------- */ .cs-result-compare { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(20px, 2.5vw, 32px); margin-top: clamp(24px, 3vw, 36px); } .cs-result-card { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-card); padding: clamp(20px, 2vw, 28px); } .cs-result-card__label { font-family: var(--font-sans); font-weight: 800; font-size: 11px; letter-spacing: 2.4px; text-transform: uppercase; color: var(--muted-2); margin-bottom: 18px; } .cs-result-card__name { margin: 0 0 8px; font-family: var(--font-serif); font-size: 19px; line-height: 1.3; color: var(--ink); } .cs-result-card__flat { font-size: 14px; line-height: 22px; color: var(--ink-2); } .cs-result-card__note { margin-top: 18px; padding-top: 14px; border-top: 1px dashed var(--line); font-size: 13px; color: var(--muted); font-family: var(--font-italic-serif); font-style: italic; } .cs-result-tier { margin-top: 18px; } .cs-result-tier + .cs-result-tier { border-top: 1px solid var(--line); padding-top: 16px; } .cs-result-tier__label { font-family: var(--font-sans); font-weight: 800; font-size: 10px; letter-spacing: 2px; text-transform: uppercase; color: var(--accent); margin-bottom: 8px; } .cs-result-tier__primary { font-family: var(--font-serif); font-size: 18px; line-height: 1.3; color: var(--ink); } .cs-result-tier__primary-status { display: inline-block; margin-top: 4px; font-size: 12px; padding: 4px 10px; background: rgba(34, 139, 90, 0.12); color: #2e7d4f; border-radius: var(--radius-pill); letter-spacing: 0.4px; font-weight: 700; } .cs-result-tier__pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; font-size: 13px; color: var(--ink-2); } .cs-result-tier__pair-label { display: block; color: var(--muted-2); font-size: 11px; letter-spacing: 1.4px; text-transform: uppercase; font-weight: 700; margin-bottom: 2px; } .cs-result-tier__support { font-size: 13px; line-height: 19px; color: var(--muted); } .cs-result-tier__cta { margin-top: 8px; display: inline-flex; align-items: center; padding: 8px 14px; font-size: 12px; font-weight: 700; background: var(--accent); color: #fff; border-radius: var(--radius-pill); } /* ---------- Tile (placeholder image card) — sections #1, #3, #5 ---------- */ .cs-tile { position: relative; background: var(--bg-2); border: 1.5px dashed var(--line); border-radius: var(--radius-media); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px; padding: clamp(20px, 2.4vw, 32px) 18px; text-align: center; min-height: 168px; } .cs-tile__icon { width: 28px; height: 22px; color: var(--muted); opacity: 0.7; } .cs-tile__label { font-family: var(--font-sans); font-weight: 800; font-size: 12px; line-height: 18px; letter-spacing: 2.64px; text-transform: uppercase; color: var(--accent); } .cs-tile__copy { margin: 0; font-weight: 500; font-size: 16px; line-height: 24px; color: var(--muted-2); max-width: 28ch; } .cs-pattern-row { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: clamp(12px, 1.4vw, 18px); } .cs-pattern-row .cs-tile { min-height: 156px; gap: 14px; } .cs-tile-quote { max-width: 920px; margin: clamp(20px, 3vw, 32px) auto 0; text-align: center; font-family: var(--font-italic-serif); font-style: italic; font-size: 18px; line-height: 1.55; color: var(--muted-2); } .cs-rule { display: block; width: 56px; height: 1px; margin: clamp(28px, 4vw, 48px) auto; background: var(--line); border: 0; } /* Section 2 — large annotated visual placeholder card */ .cs-annotation { background: var(--bg-2); border: 1.5px dashed var(--line); border-radius: var(--radius-media); padding: clamp(36px, 5vw, 72px) clamp(28px, 4vw, 80px); text-align: center; max-width: 1080px; margin-inline: auto; } .cs-annotation__icon { width: 32px; height: 26px; margin-inline: auto; color: var(--muted); opacity: 0.7; } .cs-annotation__label { margin: 22px 0 0; font-weight: 800; font-size: 14px; line-height: 18px; letter-spacing: 3px; text-transform: uppercase; color: var(--accent); } .cs-annotation__body { margin: 22px auto 0; max-width: 38ch; font-size: 18px; line-height: 28px; color: var(--muted); } .cs-annotation__divider { display: block; width: min(360px, 80%); height: 1px; margin: clamp(22px, 3vw, 32px) auto; background: var(--line); border: 0; } .cs-annotation__quote { max-width: 44ch; margin: 0 auto; font-family: var(--font-italic-serif); font-style: italic; font-size: 18px; line-height: 1.55; color: var(--muted-2); } /* Section 3 — variant grid (3 × 2) */ .cs-variant-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(16px, 1.6vw, 22px); } .cs-variant-grid .cs-tile { min-height: 232px; padding-block: clamp(28px, 3vw, 40px); } /* Section 4 — narrower accessibility card */ .cs-accessibility { max-width: 560px; } /* Section 5 — page tile grid (4 × 2) */ .cs-page-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(16px, 1.6vw, 22px); } .cs-page-grid .cs-tile { min-height: 232px; } /* ---------- Numbered accessibility areas ---------- */ .cs-numbered { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(16px, 2vw, 24px) clamp(24px, 3vw, 40px); margin-top: clamp(24px, 3vw, 36px); } .cs-numbered__item { display: grid; grid-template-columns: 36px 1fr; gap: 16px; } .cs-numbered__num { display: inline-grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; background: var(--accent); color: #fff; font-family: var(--font-display); font-size: 15px; line-height: 1; } .cs-numbered__body { font-size: 15px; line-height: 22px; color: var(--ink-2); } .cs-numbered__body strong { color: var(--ink); font-weight: 700; } /* ---------- Outcomes ---------- */ .cs-outcomes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(20px, 2.5vw, 36px) clamp(28px, 4vw, 64px); margin-top: clamp(24px, 3vw, 40px); } .cs-outcome { display: flex; flex-direction: column; gap: 10px; } .cs-outcome__title { margin: 0; font-family: var(--font-serif); font-size: clamp(20px, 1.8vw, 24px); line-height: 1.25; letter-spacing: -0.01em; color: var(--ink); } .cs-outcome__copy { font-size: 16px; line-height: 24px; color: var(--muted); } /* ---------- Reflection ---------- */ .cs-reflection { max-width: 880px; margin-inline: auto; text-align: center; padding-block: clamp(40px, 5vw, 64px); } .cs-reflection__quote { margin: 0 0 clamp(28px, 3vw, 40px); font-family: var(--font-serif); font-style: italic; font-size: clamp(28px, 3.4vw, 44px); line-height: 1.2; letter-spacing: -0.02em; color: var(--ink); } .cs-reflection__quote::before { content: "“"; color: var(--accent); } .cs-reflection__quote::after { content: "”"; color: var(--accent); } .cs-reflection__copy { font-size: 17px; line-height: 28px; color: var(--muted); text-align: left; max-width: 64ch; margin-inline: auto; } .cs-reflection__copy + .cs-reflection__copy { margin-top: 18px; } /* ---------- Footer ---------- */ .cs-footer { margin-top: clamp(56px, 7vw, 96px); padding: clamp(24px, 3vw, 32px) 0; border-top: 1px solid var(--line); } .cs-footer__inner { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 16px; } .cs-footer__copy { font-size: 14px; color: var(--muted-2); } .cs-footer__links { display: flex; flex-wrap: wrap; gap: 24px; } .cs-footer__links a { font-size: 14px; color: var(--ink-2); transition: color var(--dur) var(--ease); } .cs-footer__links a:hover { color: var(--accent); } /* ---------- Responsive ---------- */ @media (max-width: 980px) { .cs-meta { grid-template-columns: repeat(2, minmax(0, 1fr)); } .cs-impact { grid-template-columns: repeat(3, minmax(0, 1fr)); } .cs-problems-row { grid-template-columns: repeat(3, minmax(0, 1fr)); } .cs-problems-grid { grid-template-columns: 1fr; } .cs-role-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .cs-body { grid-template-columns: 1fr; } .cs-table__row, .cs-matrix { grid-template-columns: 1fr; } .cs-matrix > * { border-bottom: 1px solid var(--line) !important; } .cs-matrix > *:last-child { border-bottom: 0 !important; } .cs-timeline { grid-template-columns: repeat(3, minmax(0, 1fr)); } .cs-recovery { grid-template-columns: repeat(2, minmax(0, 1fr)); } .cs-priorities { grid-template-columns: 1fr; } .cs-result-compare, .cs-compare, .cs-split, .cs-outcomes, .cs-numbered { grid-template-columns: 1fr; } .cs-pattern-row { grid-template-columns: repeat(3, minmax(0, 1fr)); } .cs-variant-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .cs-page-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .cs-ticket__row { grid-template-columns: 1fr; gap: 4px; } } @media (max-width: 560px) { .cs-meta { grid-template-columns: 1fr; } .cs-impact, .cs-problems-row, .cs-role-grid, .cs-timeline, .cs-recovery { grid-template-columns: 1fr; } .cs-pattern-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } .cs-variant-grid { grid-template-columns: 1fr; } .cs-page-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .cs-chapter { grid-template-columns: 1fr; align-items: start; } } </style> <meta name="theme-color" content="#f3efe6" media="(prefers-color-scheme: light)" /> <meta name="theme-color" content="#14110d" media="(prefers-color-scheme: dark)" /> <script> (function () { try { var saved = localStorage.getItem("theme"); var prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches; var theme = saved === "light" || saved === "dark" ? saved : prefersDark ? "dark" : "light"; document.documentElement.dataset.theme = theme; } catch (_) { document.documentElement.dataset.theme = "light"; } })(); </script> </head> <body> <a class="skip-link" href="#main">Skip to content</a> <!-- Reusable SVG placeholder icon --> <svg width="0" height="0" style="position:absolute" aria-hidden="true"> <defs> <symbol id="ph-image" viewBox="0 0 32 24"> <rect x="0" y="2" width="32" height="3" rx="1" /> <rect x="0" y="9" width="32" height="3" rx="1" /> <rect x="0" y="16" width="32" height="3" rx="1" /> </symbol> </defs> </svg> <header class="site-header" data-reveal> <div class="container header__inner"> <a class="logo" href="index.html" aria-label="Rikon Rahman — home"> RR<span class="logo__dot">.</span> </a> <div class="header__right"> <nav class="nav" aria-label="Primary"> <a class="nav__link" href="index.html#work">Work</a> <a class="nav__link" href="index.html#about">About</a> <a class="nav__link" href="index.html#contact">Contact</a> <a class="btn btn--ghost" href="assets/resume.pdf">Resume</a> </nav> <button class="theme-toggle" type="button" role="switch" aria-checked="false" aria-label="Switch to dark mode" > <span class="theme-toggle__track" aria-hidden="true"> <svg class="theme-toggle__icon theme-toggle__icon--sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="4"></circle> <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"></path> </svg> <svg class="theme-toggle__icon theme-toggle__icon--moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path> </svg> <span class="theme-toggle__thumb"></span> </span> </button> <button class="nav-toggle" type="button" aria-controls="mobileNav" aria-expanded="false" aria-label="Open menu" > <span></span><span></span><span></span> </button> </div> </div> <div class="mobile-nav" id="mobileNav" hidden> <a class="mobile-nav__link" href="index.html#work">Work</a> <a class="mobile-nav__link" href="index.html#about">About</a> <a class="mobile-nav__link" href="index.html#contact">Contact</a> <a class="btn btn--ghost mobile-nav__cta" href="assets/resume.pdf">Resume</a> </div> </header> <main id="main" class="case-study"> <div class="container"> <p class="cs-back-wrap"> <a class="cs-back" href="index.html#work"> <svg class="cs-back__chev" viewBox="0 0 8 14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" > <polyline points="6.5,1 1.5,7 6.5,13"></polyline> </svg> All case studies </a> </p> <!-- ========================================================= HERO ========================================================= --> <header class="cs-hero" data-reveal> <div class="cs-hero__text"> <p class="eyebrow">Healthcare / Public Sector</p> <h1 class="cs-hero__title"> Designing secure access and accessible service journeys for NHS Service Finder </h1> <p class="cs-hero__lede"> I led UX for a national Service Finder modernisation, helping move <strong>100,000+ health and care professionals</strong> from legacy email/password login toward <strong>Care Identity Authentication (CIS2)</strong>, while improving accessibility across critical service journeys. This was not only a login migration — it was a service modernisation across identity, user readiness, account states, accessibility barriers, and local component debt. </p> </div> <figure class="cs-hero-media" data-reveal data-reveal-delay="120"> <img src="assets/images/case-nhs.png" alt="NHS Service Finder — secure access and accessible service search for 100,000+ health and care professionals." loading="eager" decoding="async" /> </figure> </header> <!-- Meta block: role / timeline / product / scale --> <dl class="cs-meta" data-reveal data-reveal-delay="180"> <div class="cs-meta__cell"> <dt class="cs-meta__label">Role</dt> <dd class="cs-meta__value">Senior UX & Interaction Designer</dd> </div> <div class="cs-meta__cell"> <dt class="cs-meta__label">Timeline</dt> <dd class="cs-meta__value">June 2025 – April 2026</dd> </div> <div class="cs-meta__cell"> <dt class="cs-meta__label">Product</dt> <dd class="cs-meta__value">NHS Service Finder</dd> </div> <div class="cs-meta__cell"> <dt class="cs-meta__label">Scale</dt> <dd class="cs-meta__value">100,000+ health and care professionals</dd> </div> </dl> <!-- ========================================================= IMPACT AT A GLANCE ========================================================= --> <section class="cs-section" aria-labelledby="impact-tag"> <header class="cs-section__head"> <p class="eyebrow" id="impact-tag" data-reveal>Impact at a glance</p> <h2 class="cs-section__title" data-reveal data-reveal-delay="100"> Six numbers that shaped the <em>brief, the work, and the outcome.</em> </h2> </header> <ul class="cs-impact" data-reveal data-reveal-delay="160"> <li class="cs-stat"> <span class="cs-stat__num">100<em>k+</em></span> <span class="cs-stat__label">Professionals supported</span> <p class="cs-stat__copy"> Health and care professionals supported across NHS services. </p> </li> <li class="cs-stat"> <span class="cs-stat__num">94<em>%</em></span> <span class="cs-stat__label">Migrated unaided</span> <p class="cs-stat__copy"> Completed the migration without contacting support in the first week. </p> </li> <li class="cs-stat"> <span class="cs-stat__num">2.4d<em> → now</em></span> <span class="cs-stat__label">Onboarding</span> <p class="cs-stat__copy"> Reduced to near real-time using trusted organisation and role data. </p> </li> <li class="cs-stat"> <span class="cs-stat__num">36 / <em>25</em></span> <span class="cs-stat__label">Audit coverage</span> <p class="cs-stat__copy"> Key pages audited across web and mobile — 25 had accessibility issues. </p> </li> <li class="cs-stat"> <span class="cs-stat__num">35<em>%</em></span> <span class="cs-stat__label">Faster task completion</span> <p class="cs-stat__copy"> Improvement for users with accessibility needs in internal testing. </p> </li> <li class="cs-stat"> <span class="cs-stat__num">NHS<em> DS</em></span> <span class="cs-stat__label">Design system aligned</span> <p class="cs-stat__copy"> Used as a sustainable accessibility strategy, not a one-off fix. </p> </li> </ul> </section> <!-- ========================================================= PRODUCT CONTEXT ========================================================= --> <section class="cs-section" aria-labelledby="context-tag"> <header class="cs-section__head"> <p class="eyebrow" id="context-tag" data-reveal>Product context</p> <h2 class="cs-section__title" data-reveal data-reveal-delay="100"> What is <em>NHS Service Finder?</em> </h2> </header> <div class="cs-body" data-reveal data-reveal-delay="160"> <div> <p class="cs-body__lead">The product</p> <p class="cs-prose" style="margin-top:14px;"> NHS Service Finder is used by health and care professionals to find accurate, up-to-date information about available services in a specific location. Users may be looking for urgent treatment centres, pharmacies, mental health support, referral routes, eligibility criteria, opening times, or contact details. </p> </div> <div> <p class="cs-prose"> These users often work under pressure. They need to find the right service quickly, trust the information, and recover easily when something goes wrong. This is not a general public-facing search tool — it supports professional workflows where <strong>accuracy, speed, trust, and accessibility matter</strong>. </p> <div class="cs-callout"> Service Finder supports time-sensitive decisions by helping health and care professionals find relevant services, referral routes, eligibility details, and availability information. </div> </div> </div> </section> <!-- ========================================================= THE CHALLENGE ========================================================= --> <section class="cs-section" aria-labelledby="challenge-tag"> <header class="cs-section__head"> <p class="eyebrow" id="challenge-tag" data-reveal>The challenge</p> <h2 class="cs-section__title" data-reveal data-reveal-delay="100"> Five connected service <em>journey problems</em> </h2> <p class="cs-prose" data-reveal data-reveal-delay="160"> This was a connected service modernisation problem, not one isolated login screen. </p> </header> <ol class="cs-problems-row" data-reveal data-reveal-delay="200"> <li class="cs-problem-chip"> <span class="cs-problem-chip__num">01</span> <span class="cs-problem-chip__label">Legacy login</span> </li> <li class="cs-problem-chip"> <span class="cs-problem-chip__num">02</span> <span class="cs-problem-chip__label">Account states</span> </li> <li class="cs-problem-chip"> <span class="cs-problem-chip__num">03</span> <span class="cs-problem-chip__label">Care Identity handoff</span> </li> <li class="cs-problem-chip"> <span class="cs-problem-chip__num">04</span> <span class="cs-problem-chip__label">Accessibility gaps</span> </li> <li class="cs-problem-chip"> <span class="cs-problem-chip__num">05</span> <span class="cs-problem-chip__label">Component debt</span> </li> </ol> <div class="cs-problems-grid" data-reveal data-reveal-delay="260"> <article class="cs-problem"> <span class="cs-problem__num">01</span> <h3 class="cs-problem__title"> Legacy login created a behaviour-change challenge </h3> <p class="cs-problem__copy"> Users relied on familiar email/password login. Moving to Care Identity improved security, but required users to change an established behaviour under time pressure. Users had mixed digital confidence and many needed repeated guidance and reassurance. </p> </article> <article class="cs-problem"> <span class="cs-problem__num">02</span> <h3 class="cs-problem__title"> Users entered from multiple account contexts </h3> <p class="cs-problem__copy"> New users, existing users, Cognito users, and mismatched accounts each needed different routes, logic, and recovery paths. Each context required a distinct journey and a clear path when something went wrong. </p> </article> <article class="cs-problem"> <span class="cs-problem__num">03</span> <h3 class="cs-problem__title"> Care Identity setup happened outside Service Finder </h3> <p class="cs-problem__copy"> Setup opened on a separate NHS platform in a new tab and required users to return manually. Login redirected users back automatically after MFA. This technically correct behaviour was confusing for users. </p> </article> <article class="cs-problem"> <span class="cs-problem__num">04</span> <h3 class="cs-problem__title"> Accessibility issues existed at multiple levels </h3> <p class="cs-problem__copy"> Some issues were minor and could be fixed quickly. Others affected interaction behaviour, page hierarchy, keyboard order, search flows, and repeated patterns — requiring design work, not just surface fixes. </p> </article> <article class="cs-problem"> <span class="cs-problem__num">05</span> <h3 class="cs-problem__title"> The local component library became a constraint </h3> <p class="cs-problem__copy"> Service Finder used a local React library that had drifted from NHS Design System standards, creating inconsistent UI patterns, accessibility gaps, duplication, and growing maintenance overhead. </p> </article> <blockquote class="cs-pullquote" data-reveal> These issues were connected: the identity migration exposed account-state complexity, the accessibility audit exposed structural barriers, and those barriers exposed the limits of the local component library. </blockquote> </div> </section> <!-- ========================================================= MY ROLE ========================================================= --> <section class="cs-section" aria-labelledby="role-tag"> <header class="cs-section__head"> <p class="eyebrow" id="role-tag" data-reveal>My role</p> <h2 class="cs-section__title" data-reveal data-reveal-delay="100"> Senior UX & <em>Interaction Designer</em> </h2> <p class="cs-prose" data-reveal data-reveal-delay="160"> I led UX across secure access, accessibility, search, and design system alignment — making complex constraints understandable for users, developers, product stakeholders, and clinical teams. </p> </header> <div class="cs-role-grid" data-reveal data-reveal-delay="200"> <div class="cs-role-col"> <p class="cs-role-col__head">CIS2 Migration</p> <ul class="cs-role-col__list"> <li>Mapped login journeys and account states</li> <li>Designed staged migration messaging</li> <li>Aligned in-product experience with wider comms</li> <li>Defined recovery paths and access flows</li> </ul> </div> <div class="cs-role-col"> <p class="cs-role-col__head">Accessibility</p> <ul class="cs-role-col__list"> <li>Audited 36 key pages across web and mobile</li> <li>Prioritised quick fixes and structural issues</li> <li>Translated findings into developer-ready tickets</li> <li>Redesigned critical accessibility barriers</li> </ul> </div> <div class="cs-role-col"> <p class="cs-role-col__head">Design System</p> <ul class="cs-role-col__list"> <li>Audited local patterns against NHS Design System</li> <li>Defined Match / Minor change / Does not match</li> <li>Challenged patching in favour of system-level alignment</li> </ul> </div> <div class="cs-role-col"> <p class="cs-role-col__head">Interaction Craft</p> <ul class="cs-role-col__list"> <li>Redesigned dense search results for scannability</li> <li>Improved structure, hierarchy, and interaction clarity</li> <li>Designed search patterns for different intents and devices</li> </ul> </div> </div> <blockquote class="cs-pullquote" data-reveal> Main contribution: making complex identity, accessibility, and design system constraints understandable for users, developers, product stakeholders, and clinical teams. </blockquote> </section> <!-- ========================================================= CHAPTER 01 — CARE IDENTITY MIGRATION ========================================================= --> <section class="cs-section" aria-label="Chapter 01: Care Identity migration"> <header class="cs-chapter" data-reveal> <span class="cs-chapter__num">01</span> <div class="cs-chapter__meta"> <span class="cs-chapter__label">Chapter</span> <h2 class="cs-chapter__title">Care Identity migration</h2> </div> </header> <!-- 1a. One migration, many starting points --> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Designing for multiple user and account contexts </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> One migration, <em>many different starting points</em> </h3> </div> <div class="cs-body" data-reveal data-reveal-delay="160"> <div> <p class="cs-body__lead">Why this mattered</p> <p class="cs-prose" style="margin-top:14px;"> The Care Identity migration was not a single linear flow. Users arrived with different account histories and levels of readiness. A new user without Care Identity needed a different route from an existing Service Finder user migrating account data. A user with an email mismatch needed a different path again. A user blocked before login still needed help. </p> </div> <div> <p class="cs-prose"> Without this mapping, users could take the wrong route: creating a new account instead of migrating, failing to link accounts because emails did not match, or being blocked before reaching help. </p> <div class="cs-callout"> <strong>Collaboration:</strong> I worked with a service designer to map the key account states. My focus was translating those states into clear product journeys, interactions, guidance, and recovery paths. </div> </div> </div> <div class="cs-table" data-reveal> <div class="cs-table__row cs-table__row--head"> <div>User state</div> <div>Risk UX</div> <div>Designed route</div> </div> <div class="cs-table__row"> <div class="cs-table__cell cs-table__cell--state">New user without Care Identity</div> <div class="cs-table__cell cs-table__cell--risk">Gets locked out without preparation</div> <div class="cs-table__cell cs-table__cell--route">Setup guidance + return instructions</div> </div> <div class="cs-table__row"> <div class="cs-table__cell cs-table__cell--state">New user with Care Identity</div> <div class="cs-table__cell cs-table__cell--risk">Abandons at cross-platform boundary</div> <div class="cs-table__cell cs-table__cell--route">Detection → MFA → account creation</div> </div> <div class="cs-table__row"> <div class="cs-table__cell cs-table__cell--state">Existing user with Care Identity</div> <div class="cs-table__cell cs-table__cell--risk">Thinks account is permanently locked</div> <div class="cs-table__cell cs-table__cell--route">Migration route + email linking</div> </div> <div class="cs-table__row"> <div class="cs-table__cell cs-table__cell--state">User on legacy Cognito login</div> <div class="cs-table__cell cs-table__cell--risk">Creates duplicate account</div> <div class="cs-table__cell cs-table__cell--route">Staged warnings → interrupt → decommission</div> </div> <div class="cs-table__row"> <div class="cs-table__cell cs-table__cell--state">User with email mismatch</div> <div class="cs-table__cell cs-table__cell--risk">Assumes something is broken</div> <div class="cs-table__cell cs-table__cell--route">Manual email step + recovery route</div> </div> <div class="cs-table__row"> <div class="cs-table__cell cs-table__cell--state">User needing approval</div> <div class="cs-table__cell cs-table__cell--risk">Unsure whether to log in or migrate</div> <div class="cs-table__cell cs-table__cell--route">Approval state + timeline + next steps</div> </div> <div class="cs-table__row"> <div class="cs-table__cell cs-table__cell--state">User needing help before login</div> <div class="cs-table__cell cs-table__cell--risk">Blocked before reaching support</div> <div class="cs-table__cell cs-table__cell--route">Help available without authentication</div> </div> </div> </section> <!-- ========================================================= 1b. Staged in-product migration messages ========================================================= --> <section class="cs-section" aria-label="Staged in-product migration"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Designing the transition, not just the login </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Staged in-product <em>migration messages</em> </h3> </div> <div class="cs-body" data-reveal data-reveal-delay="160"> <div> <p class="cs-body__lead">The challenge</p> <p class="cs-prose" style="margin-top:14px;"> The hardest part of the migration was not the authentication technology. It was helping a large, busy, mixed-confidence user base change a familiar behaviour. My role was to align the in-product experience with the wider communication plan — landing-page messages, login warnings, interrupt pages, password reset warnings, help pages, and final decommissioning states. </p> </div> <div> <p class="cs-prose"> The staged approach gave users repeated chances to understand, prepare, act, and recover. In the first week of migration, <strong>94% of users completed the process without contacting support</strong>. </p> <div class="cs-callout"> <strong>Collaboration:</strong> I worked with the content designer on every in-product message. They owned wording and tone; I owned placement, login, and recovery flows. We reviewed each stage together before sprint delivery. </div> </div> </div> <div class="cs-legend" data-reveal> <span class="cs-legend__item"> <span class="cs-legend__swatch cs-legend__swatch--owned" aria-hidden="true"></span> Owned by me </span> <span class="cs-legend__item"> <span class="cs-legend__swatch cs-legend__swatch--wider" aria-hidden="true"></span> Wider team </span> <span class="cs-legend__item"> <span class="cs-legend__swatch cs-legend__swatch--aligned" aria-hidden="true"></span> Aligned with me </span> </div> <ol class="cs-timeline" data-reveal data-reveal-delay="100"> <li class="cs-timeline__col"> <span class="cs-timeline__phase">Awareness</span> <span class="cs-timeline__when">Early phase</span> <ul class="cs-timeline__list"> <li>Landing page banner</li> <li>Login soft prompt</li> <li>Email announcement</li> <li>Webinar invitation</li> </ul> </li> <li class="cs-timeline__col"> <span class="cs-timeline__phase">Preparation</span> <span class="cs-timeline__when">Mid phase</span> <ul class="cs-timeline__list"> <li>What is Care Identity?</li> <li>How-to-set-up guide</li> <li>Before-you-start page</li> <li>Email: step-by-step</li> <li>Webinar 1 + 2</li> </ul> </li> <li class="cs-timeline__col"> <span class="cs-timeline__phase">Deadline</span> <span class="cs-timeline__when">Oct 2025</span> <ul class="cs-timeline__list"> <li>Warning banner on login</li> <li>Password reset warning</li> <li>Help pages updated</li> <li>Email: deadline reminder</li> </ul> </li> <li class="cs-timeline__col"> <span class="cs-timeline__phase">Friction</span> <span class="cs-timeline__when">Nov 2025</span> <ul class="cs-timeline__list"> <li>Interrupt page</li> <li>Skip-for-now option</li> <li>“Having trouble?” link</li> </ul> </li> <li class="cs-timeline__col"> <span class="cs-timeline__phase">Decommission</span> <span class="cs-timeline__when">Nov 2025+</span> <ul class="cs-timeline__list"> <li>Legacy login removed</li> <li>CIS2-only landing state</li> <li>Support before login</li> </ul> </li> <li class="cs-timeline__col"> <span class="cs-timeline__phase">Sunset</span> <span class="cs-timeline__when">Mar 2026</span> <ul class="cs-timeline__list"> <li>Ambulance trust warning</li> <li>Temp access ending Mar 31</li> <li>Email to trust users</li> </ul> </li> </ol> </section> <!-- ========================================================= 1c. Security versus clinical continuity ========================================================= --> <section class="cs-section" aria-label="Protecting emergency access during winter pressure"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Protecting emergency access during winter pressure </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Security versus <em>clinical continuity</em> </h3> </div> <div class="cs-body" data-reveal data-reveal-delay="160"> <div> <p class="cs-body__lead">The tradeoff</p> <p class="cs-prose" style="margin-top:14px;"> From a security standpoint, the cleanest option was to move everyone to Care Identity and remove the old login. But the timing overlapped with winter pressure, when urgent and emergency care services face increased demand. </p> </div> <div> <p class="cs-prose"> I worked with engineering to use <strong>Ambulance Trust ODS codes as an eligibility rule</strong> — recognising users linked to ambulance trusts and routing them through a temporary safe path. The exception was limited, temporary, intentional, and based on clinical risk — not convenience. </p> </div> </div> </section> <!-- ========================================================= 1d. Setup vs login — handoff comparison ========================================================= --> <section class="cs-section" aria-label="Setup vs login handoff"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Making the external handoff understandable and recoverable </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Setup vs login: <em>two different handoff behaviours</em> </h3> </div> <div class="cs-body" data-reveal data-reveal-delay="160"> <div> <p class="cs-body__lead">The problem</p> <p class="cs-prose" style="margin-top:14px;"> Care Identity was owned by another national team. Setup and login behaved differently: setup opened in a new tab and required users to return manually; login opened in the same tab and returned users automatically after MFA. This was technically correct, but confusing. </p> </div> <div> <p class="cs-prose"> Working with a content designer, I made the handoff explicit before users left Service Finder — explaining where they were going, why, whether they needed to return manually, and what to do if setup or login failed. A key decision was making <strong>help available before login</strong>, so users blocked before authentication could still get support. </p> </div> </div> <div class="cs-compare" data-reveal> <article class="cs-compare__col"> <span class="cs-compare__label">Setup — new tab — manual return</span> <h4 class="cs-compare__title">Care Identity setup</h4> <ol class="cs-steps"> <li class="cs-steps__item"> <span class="cs-steps__num" aria-hidden="true">1</span> <span class="cs-steps__body"> User begins setup from Service Finder <span class="cs-steps__sub">“Before you start” guidance explains what will happen</span> </span> </li> <li class="cs-steps__item"> <span class="cs-steps__num" aria-hidden="true">2</span> <span class="cs-steps__body"> Care Identity opens in a new tab <span class="cs-steps__sub">Explicitly told a new tab will open and why</span> </span> </li> <li class="cs-steps__item"> <span class="cs-steps__num" aria-hidden="true">3</span> <span class="cs-steps__body">User completes MFA and account creation</span> </li> <li class="cs-steps__item"> <span class="cs-steps__num" aria-hidden="true">4</span> <span class="cs-steps__body"> User must return to Service Finder manually <span class="cs-steps__sub">Guidance explains return steps before they leave</span> </span> </li> <li class="cs-steps__item"> <span class="cs-steps__num" aria-hidden="true">5</span> <span class="cs-steps__body">User logs in with new Care Identity credentials</span> </li> </ol> </article> <article class="cs-compare__col"> <span class="cs-compare__label">Login — same tab — automatic return</span> <h4 class="cs-compare__title">Care Identity login</h4> <ol class="cs-steps"> <li class="cs-steps__item"> <span class="cs-steps__num" aria-hidden="true">1</span> <span class="cs-steps__body"> User selects Care Identity login <span class="cs-steps__sub">Same-tab redirect begins immediately</span> </span> </li> <li class="cs-steps__item"> <span class="cs-steps__num" aria-hidden="true">2</span> <span class="cs-steps__body">Care Identity opens in the same tab</span> </li> <li class="cs-steps__item"> <span class="cs-steps__num" aria-hidden="true">3</span> <span class="cs-steps__body">User completes MFA on Care Identity</span> </li> <li class="cs-steps__item"> <span class="cs-steps__num" aria-hidden="true">4</span> <span class="cs-steps__body"> Service Finder returns the user automatically <span class="cs-steps__sub">No manual return needed — access granted</span> </span> </li> </ol> </article> </div> </section> <!-- ========================================================= 1e. Recovery states — login failure scenarios ========================================================= --> <section class="cs-section" aria-label="Recovery states"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Recovery states — login failure scenarios </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Honest <em>recovery,</em> never a dead end </h3> </div> <ul class="cs-recovery" data-reveal data-reveal-delay="160"> <li class="cs-recovery-card"> <span class="cs-recovery-card__label">MFA failed</span> <h4 class="cs-recovery-card__title"> Your authentication code didn’t work </h4> <p class="cs-recovery-card__copy"> The code may have expired, or your authenticator app may not be synced. This is common and doesn’t mean your account is locked. </p> <div class="cs-recovery-card__actions"> <span class="cs-recovery-card__action">Try again</span> <span class="cs-recovery-card__action">Request a new code</span> <span class="cs-recovery-card__action">Contact local IT</span> </div> </li> <li class="cs-recovery-card"> <span class="cs-recovery-card__label">Incomplete setup</span> <h4 class="cs-recovery-card__title"> Your Care Identity setup isn’t finished </h4> <p class="cs-recovery-card__copy"> You started setting up Care Identity but didn’t complete all steps. Return to finish, then come back and log in. </p> <div class="cs-recovery-card__actions"> <span class="cs-recovery-card__action">Return to setup</span> <span class="cs-recovery-card__action">Get help</span> </div> </li> <li class="cs-recovery-card"> <span class="cs-recovery-card__label">Email or role mismatch</span> <h4 class="cs-recovery-card__title"> We couldn’t match your accounts </h4> <p class="cs-recovery-card__copy"> The email or role on your Care Identity account differs from your Service Finder account. You can update or contact support to link them manually. </p> <div class="cs-recovery-card__actions"> <span class="cs-recovery-card__action">Update email</span> <span class="cs-recovery-card__action">Contact support</span> </div> </li> <li class="cs-recovery-card"> <span class="cs-recovery-card__label">Missing organisation data</span> <h4 class="cs-recovery-card__title"> We couldn’t verify your access level </h4> <p class="cs-recovery-card__copy"> Your organisation or role wasn’t found in Care Identity. This may need to be added by your organisation’s administrator before access can be granted. </p> <div class="cs-recovery-card__actions"> <span class="cs-recovery-card__action">Contact organisation</span> <span class="cs-recovery-card__action">Request support</span> </div> </li> </ul> </section> <!-- ========================================================= 1f. Organisation and role verification ========================================================= --> <section class="cs-section" aria-label="Organisation and role verification"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Supporting organisation and role verification </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Designing the <em>professional information journey</em> </h3> </div> <div class="cs-body" data-reveal data-reveal-delay="160"> <div> <p class="cs-body__lead">The design work</p> <p class="cs-prose" style="margin-top:14px;"> Care Identity did more than authenticate users. It also created an opportunity to use trusted organisation and role data to reduce manual access checks. </p> <p class="cs-prose" style="margin-top:14px;"> As part of the migration, I designed the Service Finder side of the journey for users who needed to provide or confirm professional information, organisation details, and role data before access could be granted. </p> </div> <div> <p class="cs-prose"> This helped the service route users more clearly: eligible users could continue with less manual intervention, users with missing or unclear data were guided to approval or support, and users understood why extra information was needed before accessing the service. The goal was to avoid asking users to manually re-enter information the system could already verify through trusted identity data. </p> <div class="cs-callout"> <strong>Impact:</strong> Manual onboarding previously took an average of 2.4 days. Using trusted organisation and role data helped reduce access time to near real time for eligible users. </div> </div> </div> </section> <!-- ========================================================= CHAPTER 02 — ACCESSIBILITY AUDIT ========================================================= --> <section class="cs-section" aria-label="Chapter 02: Accessibility audit and prioritisation"> <header class="cs-chapter" data-reveal> <span class="cs-chapter__num">02</span> <div class="cs-chapter__meta"> <span class="cs-chapter__label">Chapter</span> <h2 class="cs-chapter__title">Accessibility audit and prioritisation</h2> </div> </header> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> From leadership priority to service-wide audit </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> 36 pages, 25 issues, <em>two types of problems</em> </h3> </div> <div class="cs-body" data-reveal data-reveal-delay="160"> <div> <p class="cs-body__lead">The approach</p> <p class="cs-prose" style="margin-top:14px;"> After the Care Identity migration, accessibility surfaced as the next priority across leadership, product, design, and engineering. I started with a service-wide audit across 36 key pages on web and mobile — 25 pages had accessibility issues. </p> </div> <div> <p class="cs-prose"> I classified issues as <strong>quick fixes</strong> (labels, contrast, helper text, small focus state issues) and <strong>structural issues</strong> (semantic structure, search behaviour, page hierarchy, keyboard order, form behaviour, no-results recovery, repeated component patterns). This allowed quick fixes to move fast while structural issues were redesigned properly rather than patched. </p> </div> </div> <ul class="cs-impact" style="grid-template-columns: repeat(4, minmax(0, 1fr));" data-reveal> <li class="cs-stat"> <span class="cs-stat__num">36</span> <span class="cs-stat__label">Pages audited</span> <p class="cs-stat__copy">Web and mobile.</p> </li> <li class="cs-stat"> <span class="cs-stat__num">25</span> <span class="cs-stat__label">Pages with issues</span> <p class="cs-stat__copy">Identified for remediation.</p> </li> <li class="cs-stat"> <span class="cs-stat__num">2</span> <span class="cs-stat__label">Issue types</span> <p class="cs-stat__copy">Quick fixes + structural issues.</p> </li> <li class="cs-stat"> <span class="cs-stat__num">WCAG <em>AA</em></span> <span class="cs-stat__label">Compliance target</span> <p class="cs-stat__copy">Across all screens.</p> </li> </ul> <div class="cs-split" data-reveal data-reveal-delay="100"> <article class="cs-split__col"> <span class="cs-split__label">Quick fixes</span> <p class="cs-split__copy"> Labels · helper text · colour contrast · small focus states · semantic structure · content clarity </p> </article> <article class="cs-split__col"> <span class="cs-split__label">Structural issues</span> <p class="cs-split__copy"> Search auto-navigation · missing submit actions · incorrect focus order · unclear link purpose · dense result hierarchy · repeated component patterns </p> </article> </div> </section> <!-- 2b. Findings → developer-ready Jira tickets --> <section class="cs-section" aria-label="Audit to Jira tickets"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Turning findings into developer-ready work </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> From audit spreadsheet to <em>actionable Jira tickets</em> </h3> </div> <p class="cs-prose" data-reveal data-reveal-delay="160"> The audit spreadsheet identified issues, but it was not implementation-ready. Developers needed clear guidance on what each issue meant, why it mattered, and what behaviour was expected. I translated each finding into a structured Jira ticket with issue description, user impact, WCAG reference, expected behaviour, design guidance, and whether additional design work was required. </p> <article class="cs-ticket" data-reveal data-reveal-delay="220"> <header class="cs-ticket__head"> <span class="cs-ticket__tag cs-ticket__tag--design">Design required</span> <span class="cs-ticket__tag cs-ticket__tag--id">SF-2841</span> <span class="cs-ticket__tag cs-ticket__tag--type">· Accessibility</span> </header> <h4 class="cs-ticket__title"> Search input auto-navigates after two characters typed </h4> <div class="cs-ticket__rows"> <div class="cs-ticket__row"> <span class="cs-ticket__row-label">Issue</span> <span class="cs-ticket__row-body"> Search input triggers automatic page navigation after user types two or more characters, without any user action. </span> </div> <div class="cs-ticket__row"> <span class="cs-ticket__row-label">User impact</span> <span class="cs-ticket__row-body"> Screen reader users are moved to a new state without warning. Users on keyboard-only navigation lose context and cannot predict or control the interaction. </span> </div> <div class="cs-ticket__row"> <span class="cs-ticket__row-label">WCAG</span> <span class="cs-ticket__row-body"> 3.2.2 On Input — changing a setting should not automatically cause change of context. </span> </div> <div class="cs-ticket__row"> <span class="cs-ticket__row-label">Expected behaviour</span> <span class="cs-ticket__row-body"> User controls submission with a clear, explicit action (submit button or Enter key press). No automatic navigation. </span> </div> <div class="cs-ticket__row"> <span class="cs-ticket__row-label">Design required</span> <span class="cs-ticket__row-body"> Yes — new submit action and updated search interaction pattern needed. </span> </div> </div> </article> </section> <!-- 2c. Accessibility as a shared team practice --> <section class="cs-section" aria-label="Accessibility as a shared practice"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Building accessibility understanding in the team </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Accessibility as a <em>shared team practice</em> </h3> </div> <p class="cs-prose" data-reveal data-reveal-delay="160"> Accessibility was not treated as a final QA checklist. I helped the team build shared understanding through guidance, tool usage, and workshop activity. The team explored the product from different perspectives: keyboard navigation, VoiceOver, one-finger trackpad use, zoom, and reduced visual contrast. </p> </section> <!-- 2d. Redesigning structural barriers --> <section class="cs-section" aria-label="Redesigning structural barriers"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Redesigning structural accessibility barriers </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Interaction redesign, <em>not surface-level patches</em> </h3> </div> <p class="cs-prose" data-reveal data-reveal-delay="160"> Some findings could not be solved through small UI tweaks. Structural issues included search behaviour that moved users unexpectedly, missing or unclear submit actions, incorrect focus order, unclear link purpose, low contrast or undersized actions, dense result pages, and repeated patterns that made keyboard and screen reader navigation harder. I redesigned these areas so actions were visible, page changes were predictable, and key information was easier to understand. </p> </section> <!-- 2e. Validation --> <section class="cs-section" aria-label="Validation testing"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal>Validation</p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Testing and <em>accessibility labs</em> </h3> </div> <div class="cs-body" data-reveal data-reveal-delay="160"> <div> <p class="cs-body__lead">The outcome</p> <p class="cs-prose" style="margin-top:14px;"> Improvements were validated through usability testing and accessibility testing, including accessibility lab sessions. </p> </div> <div> <div class="cs-callout"> Internal task-based testing showed a <strong>35% improvement in completion speed</strong> for users with accessibility needs after the redesign. </div> </div> </div> </section> <!-- ========================================================= CHAPTER 03 — NHS DESIGN SYSTEM ALIGNMENT ========================================================= --> <section class="cs-section" aria-label="Chapter 03: NHS Design System alignment"> <header class="cs-chapter" data-reveal> <span class="cs-chapter__num">03</span> <div class="cs-chapter__meta"> <span class="cs-chapter__label">Chapter</span> <h2 class="cs-chapter__title">NHS Design System alignment</h2> </div> </header> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> From local component debt to system-level alignment </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Sustainable accessibility as a <em>Design System strategy</em> </h3> </div> <div class="cs-body" data-reveal data-reveal-delay="160"> <div> <p class="cs-body__lead">The tradeoff</p> <p class="cs-prose" style="margin-top:14px;"> The accessibility work exposed a deeper issue: many barriers were tied to repeated local components that had drifted from NHS Design System standards. Developers proposed patching local components for speed. </p> </div> <div> <p class="cs-prose"> I understood the short-term logic — but patching would preserve the long-term problem: maintaining components that imitated NHS patterns and reworking them whenever accessibility or design system standards changed. The better long-term approach was to move repeated patterns toward NHS Design System components where possible, adapt minor differences, and design Service Finder-specific patterns only where standard NHS components did not fit the use case. </p> </div> </div> <div class="cs-matrix" data-reveal> <span class="cs-matrix__head">Type</span> <span class="cs-matrix__head">Example</span> <span class="cs-matrix__head">Decision</span> <span class="cs-matrix__type">Match</span> <span>Button, input, checkbox</span> <span class="cs-matrix__decision">Use NHS Design System directly</span> <span class="cs-matrix__type">Minor change</span> <span>Form error, filter panel, banner</span> <span class="cs-matrix__decision">Align content, spacing, focus, labels</span> <span class="cs-matrix__type">Does not match</span> <span>Search result card, auth recovery state, ODS journey</span> <span class="cs-matrix__decision">Create Service Finder-specific pattern</span> </div> </section> <section class="cs-section" aria-label="Service Finder-specific components"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Service Finder-specific components </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Where NHS patterns <em>didn’t fit</em> </h3> </div> <p class="cs-prose" data-reveal data-reveal-delay="160"> Not every Service Finder pattern had a direct NHS Design System equivalent. For dense service result cards, quick search, symptom or clinical keyword search, opening times tables, open/closed status tags, authentication recovery states, and ODS information flows — I documented the use case, accessibility needs, interaction behaviour, and relationship to existing NHS patterns before deciding whether to keep the pattern local or discuss it with the NHS Design System team. </p> </section> <!-- ========================================================= CHAPTER 04 — ACCESSIBLE SERVICE SEARCH ========================================================= --> <section class="cs-section" aria-label="Chapter 04: Accessible service search and interaction craft"> <header class="cs-chapter" data-reveal> <span class="cs-chapter__num">04</span> <div class="cs-chapter__meta"> <span class="cs-chapter__label">Chapter</span> <h2 class="cs-chapter__title">Accessible service search and interaction craft</h2> </div> </header> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Making service search easier to scan </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Dense service information, <em>fast clinical decisions</em> </h3> </div> <div class="cs-body" data-reveal data-reveal-delay="160"> <div> <p class="cs-body__lead">The problem</p> <p class="cs-prose" style="margin-top:14px;"> Each search result carried dense service information: service name, type, distance, opening status, referral route, eligibility, access instructions, contact details, and notes. The problem was not displaying this information — it was helping users compare services quickly and confidently. </p> </div> <div> <p class="cs-prose"> I grouped service information into three priority levels. Each level answers a different question the user is asking in the moment. </p> </div> </div> <ol class="cs-priorities" data-reveal data-reveal-delay="200"> <li class="cs-priority"> <span class="cs-priority__label">Primary</span> <p class="cs-priority__copy">Service name, type, opening status, distance.</p> </li> <li class="cs-priority"> <span class="cs-priority__label">Secondary</span> <p class="cs-priority__copy">Referral route, eligibility, access criteria.</p> </li> <li class="cs-priority"> <span class="cs-priority__label">Supporting</span> <p class="cs-priority__copy">Access notes, contact details, additional information.</p> </li> </ol> <!-- Before / After result card mockup comparison --> <div class="cs-result-compare" data-reveal data-reveal-delay="260"> <article class="cs-result-card"> <span class="cs-result-card__label">Before — flat, undifferentiated information</span> <h4 class="cs-result-card__name">St Thomas’ Urgent Treatment Centre</h4> <p class="cs-result-card__flat"> Urgent Treatment Centre · 1.2 miles · Open until 22:00 · Self-referral · No appointment needed · Adults and children 2+ · Parking available · 020 7188 7188 · Minor injuries, illness, infections </p> <p class="cs-result-card__flat" style="margin-top:8px;color:var(--accent);"> View full details → </p> <p class="cs-result-card__note"> All information at the same visual weight. Users must read everything to find what they need. </p> </article> <article class="cs-result-card"> <span class="cs-result-card__label">After — three-tier hierarchy</span> <div class="cs-result-tier"> <span class="cs-result-tier__label">Primary</span> <span class="cs-result-tier__primary-status">Open until 22:00</span> <p class="cs-result-tier__primary" style="margin: 8px 0 4px;"> St Thomas’ Urgent Treatment Centre </p> <p class="cs-result-tier__support">Urgent Treatment Centre · 1.2 miles</p> </div> <div class="cs-result-tier"> <span class="cs-result-tier__label">Secondary</span> <div class="cs-result-tier__pair"> <span> <span class="cs-result-tier__pair-label">Referral</span> Self-referral </span> <span> <span class="cs-result-tier__pair-label">Eligibility</span> Adults & children 2+ </span> </div> </div> <div class="cs-result-tier"> <span class="cs-result-tier__label">Supporting</span> <p class="cs-result-tier__support"> Minor injuries, illness, infections · Parking available · 020 7188 7188 </p> <a class="cs-result-tier__cta" href="#" aria-disabled="true">Refer this service →</a> </div> <p class="cs-result-card__note"> Users answer “Is it open?” and “Can I refer?” within seconds. </p> </article> </div> </section> <!-- ========================================================= [Image #1] — compact pattern row ========================================================= --> <section class="cs-section" aria-label="Search patterns at a glance"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Supporting different search behaviours </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Consistent patterns <em>across different search intents</em> </h3> <p class="cs-prose" data-reveal data-reveal-delay="160"> Service Finder supported different ways to search: service search, clinical keyword or symptom search, and quick search. These needed consistent patterns while still supporting different user intents. I designed and aligned search behaviours across desktop and mobile, making sure users could understand where they were, what they were searching for, and how to recover when results were not useful. </p> </div> <ul class="cs-pattern-row" data-reveal data-reveal-delay="200"> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Service Search</span> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Symptom / Clinical</span> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Quick Search</span> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">No-Results State</span> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Desktop Result</span> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Mobile Result</span> </li> </ul> <p class="cs-tile-quote" data-reveal data-reveal-delay="260"> “Search patterns were aligned across different user intents and screen sizes while preserving clear hierarchy and recovery guidance.” </p> <hr class="cs-rule" /> </section> <!-- ========================================================= [Image #2] — large annotated visual ========================================================= --> <section class="cs-section" aria-label="Search result before and after — annotated visual"> <article class="cs-annotation" data-reveal> <svg class="cs-annotation__icon" aria-hidden="true"><use href="#ph-image" /></svg> <p class="cs-annotation__label"> Search Result Before / After — Large Annotated Visual </p> <p class="cs-annotation__body"> Large real before/after screenshot. Annotate: 1. service name and type · 2. availability/opening status · 3. distance · 4. referral route · 5. eligibility · 6. access notes · 7. clear action. </p> <hr class="cs-annotation__divider" /> <p class="cs-annotation__quote"> “The redesigned result structure helped users answer key questions quickly: Is it open? Is it nearby? Can I refer? Is the patient eligible?” </p> </article> </section> <!-- ========================================================= [Image #3] — variant grid 3×2 ========================================================= --> <section class="cs-section" aria-label="Search pattern variants"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Supporting different search behaviours </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Consistent patterns <em>across intent and device</em> </h3> </div> <ul class="cs-variant-grid" data-reveal data-reveal-delay="160"> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Service Search</span> <p class="cs-tile__copy">Service-type driven search with filter panel</p> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Symptom / Clinical Search</span> <p class="cs-tile__copy">Keyword or clinical condition search</p> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Quick Search</span> <p class="cs-tile__copy">Minimal input, immediate results</p> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">No-Results State</span> <p class="cs-tile__copy">Actionable guidance: broaden, filter, or try nearby</p> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Desktop Result</span> <p class="cs-tile__copy">Full result card with tiered hierarchy</p> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Mobile Result</span> <p class="cs-tile__copy">Same hierarchy adapted for smaller screens</p> </li> </ul> <p class="cs-tile-quote" data-reveal data-reveal-delay="220"> “Search patterns were aligned across different intents and screen sizes while preserving clear hierarchy and recovery guidance.” </p> </section> <!-- ========================================================= ACCESSIBILITY BEYOND COMPONENTS + [Image #4] ========================================================= --> <section class="cs-section" aria-label="Accessibility beyond components"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal> Accessibility beyond components </p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Accessible journeys, <em>not just accessible components</em> </h3> </div> <div class="cs-body" data-reveal data-reveal-delay="160"> <div> <p class="cs-body__lead">The focus</p> <p class="cs-prose" style="margin-top:14px;"> Accessible components were not enough. A button can be accessible in isolation, but the journey can still fail if the page structure is confusing, keyboard order is wrong, error content is unclear, or users cannot recover from no-results states. </p> </div> <div> <p class="cs-prose"> Accessibility had to work at the level of structure, content, hierarchy, interaction states, and recovery paths. Each numbered area below was redesigned across the service. </p> </div> </div> <div class="cs-body" style="grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);" data-reveal> <ol class="cs-numbered"> <li class="cs-numbered__item"> <span class="cs-numbered__num" aria-hidden="true">1</span> <span class="cs-numbered__body"> <strong>Heading structure</strong> — logical hierarchy for screen reader navigation across all pages. </span> </li> <li class="cs-numbered__item"> <span class="cs-numbered__num" aria-hidden="true">2</span> <span class="cs-numbered__body"> <strong>Keyboard focus order</strong> — follows visual reading order through each result and page. </span> </li> <li class="cs-numbered__item"> <span class="cs-numbered__num" aria-hidden="true">3</span> <span class="cs-numbered__body"> <strong>Visible focus states</strong> — 3px solid ring, visible in light and forced-colour modes, WCAG 2.2. </span> </li> <li class="cs-numbered__item"> <span class="cs-numbered__num" aria-hidden="true">4</span> <span class="cs-numbered__body"> <strong>Form labels and errors</strong> — persistent labels, errors above the field, linked via aria-describedby. </span> </li> <li class="cs-numbered__item"> <span class="cs-numbered__num" aria-hidden="true">5</span> <span class="cs-numbered__body"> <strong>No-results recovery</strong> — actionable next steps instead of dead ends. </span> </li> <li class="cs-numbered__item"> <span class="cs-numbered__num" aria-hidden="true">6</span> <span class="cs-numbered__body"> <strong>Colour contrast and readability</strong> — 4.5:1 for text, 3:1 for UI components across all screens. </span> </li> <li class="cs-numbered__item"> <span class="cs-numbered__num" aria-hidden="true">7</span> <span class="cs-numbered__body"> <strong>Authentication error recovery</strong> — h1, plain language explanation, and role="alert" for screen readers. </span> </li> </ol> <article class="cs-annotation cs-accessibility"> <svg class="cs-annotation__icon" aria-hidden="true"><use href="#ph-image" /></svg> <p class="cs-annotation__label">Annotated Accessibility Screen</p> <p class="cs-annotation__body"> One actual page screenshot with numbered callouts: heading hierarchy · focus order · visible focus state · form labels · error placement · no-results recovery · contrast · screen reader grouping </p> <hr class="cs-annotation__divider" /> <p class="cs-annotation__quote"> “Accessibility continued beyond component replacement — it depended on structure, flow, content, interaction states, and recovery paths.” </p> </article> </div> </section> <!-- ========================================================= [Image #5] — page tile grid 4×2 ========================================================= --> <section class="cs-section" aria-label="Selected final UI"> <div class="cs-section__head"> <p class="cs-section__sub" data-reveal>Selected final UI</p> <h3 class="cs-section__title" data-reveal data-reveal-delay="100"> Final <em>screens</em> </h3> <p class="cs-prose" data-reveal data-reveal-delay="160"> Selected final screens from the secure access migration and accessibility-led redesign. </p> </div> <ul class="cs-page-grid" data-reveal data-reveal-delay="220"> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Homepage</span> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Care Identity Login / Setup</span> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Help / Migration Guidance</span> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">ODS / Organisation Screen</span> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Recovery State</span> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Search Results</span> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Mobile Search</span> </li> <li class="cs-tile"> <svg class="cs-tile__icon" aria-hidden="true"><use href="#ph-image" /></svg> <span class="cs-tile__label">Mobile Recovery / Result</span> </li> </ul> </section> <!-- ========================================================= OUTCOMES ========================================================= --> <section class="cs-section" aria-labelledby="outcomes-tag"> <header class="cs-section__head"> <p class="eyebrow" id="outcomes-tag" data-reveal>Outcomes</p> <h2 class="cs-section__title" data-reveal data-reveal-delay="100"> What the work <em>achieved</em> </h2> </header> <div class="cs-outcomes" data-reveal data-reveal-delay="160"> <article class="cs-outcome"> <h3 class="cs-outcome__title"> Secure access improved without compromising continuity </h3> <p class="cs-outcome__copy"> The wider user base moved toward MFA-backed Care Identity access. Ambulance trust users had a controlled temporary exception during winter pressure, with a time-bound sunset on 31 March 2026. </p> </article> <article class="cs-outcome"> <h3 class="cs-outcome__title"> 94% completed migration without contacting support </h3> <p class="cs-outcome__copy"> Users moved through staged in-product messaging: awareness, preparation, deadline warnings, interrupt pages, decommissioning, and emergency-user sunset. In the first week, 94% completed migration without support. </p> </article> <article class="cs-outcome"> <h3 class="cs-outcome__title"> Onboarding moved from days to near real time </h3> <p class="cs-outcome__copy"> Manual verification previously took an average of 2.4 days. By using Care Identity-backed organisation and role data, eligible users could access Service Finder in near real time, while unclear cases were routed to approval, support, or recovery instead of becoming dead ends. </p> </article> <article class="cs-outcome"> <h3 class="cs-outcome__title"> Accessibility improved across critical journeys </h3> <p class="cs-outcome__copy"> 36 key pages audited; 25 had issues. Structural barriers were redesigned across login, onboarding, search, and recovery journeys. Internal testing showed a 35% improvement in completion speed for users with accessibility needs. </p> </article> <article class="cs-outcome"> <h3 class="cs-outcome__title"> Interface became more consistent and maintainable </h3> <p class="cs-outcome__copy"> Moving repeated patterns toward the NHS Design System reduced inconsistency, accessibility risk, and repeated local rework. The audit clarified where NHS components could be used directly and where Service Finder-specific patterns were justified. </p> </article> <article class="cs-outcome"> <h3 class="cs-outcome__title"> Search results became easier to scan </h3> <p class="cs-outcome__copy"> The redesigned result structure helped users compare service type, availability, distance, referral route, and eligibility more efficiently. The tiered hierarchy made results more predictable for screen reader users and faster for sighted users. </p> </article> </div> </section> <!-- ========================================================= FINAL REFLECTION ========================================================= --> <section class="cs-section" aria-labelledby="reflection-tag"> <header class="cs-section__head cs-section__head--center"> <p class="eyebrow" id="reflection-tag" data-reveal>Final reflection</p> </header> <div class="cs-reflection" data-reveal data-reveal-delay="100"> <blockquote class="cs-reflection__quote"> Security and accessibility both depend on trust. </blockquote> <p class="cs-reflection__copy"> A secure login only works if users understand what is happening, know what to do next, and can recover when something fails. An accessible component only matters if the whole journey is accessible: structure, content, hierarchy, keyboard order, interaction states, and recovery paths all have to work together. </p> <p class="cs-reflection__copy"> This work also showed me that cross-platform journeys need more guidance than journeys contained inside one product. When users leave one service for another, the interface has to explain where they are going, why, whether they will return automatically, and what to do if they do not. </p> <p class="cs-reflection__copy"> If I were doing this again, I would bring accessibility, content design, and design system discussions together even earlier. Accessibility shouldn’t be treated as a final QA or a list of fixes. It should shape the journey, the design system, and the way teams make product decisions. </p> <p class="cs-reflection__copy"> For Service Finder, good UX meant making a complex security migration feel clear, safe, and recoverable — while building a more accessible and maintainable foundation for the service. </p> </div> </section> <!-- ========================================================= FOOTER ========================================================= --> <footer class="cs-footer"> <div class="cs-footer__inner"> <p class="cs-footer__copy">© 2026 Rikon Rahman. All rights reserved.</p> <ul class="cs-footer__links"> <li><a href="https://dribbble.com/">Dribbble</a></li> <li><a href="https://www.instagram.com/">Instagram</a></li> <li><a href="https://www.linkedin.com/">LinkedIn</a></li> <li><a href="mailto:neo.rikon@gmail.com">Email</a></li> <li><a href="assets/resume.pdf">Resume</a></li> </ul> </div> </footer> </div> </main> <script src="js/script.js" defer></script> </body> </html>
Save Changes
Cancel / Back
Close ×
Server Info
Hostname: premium264.web-hosting.com
Server IP: 69.57.162.13
PHP Version: 8.1.34
Server Software: LiteSpeed
System: Linux premium264.web-hosting.com 4.18.0-553.45.1.lve.el8.x86_64 #1 SMP Wed Mar 26 12:08:09 UTC 2025 x86_64
HDD Total: 97.87 GB
HDD Free: 73.77 GB
Domains on IP: N/A (Requires external lookup)
System Features
Safe Mode:
Off
disable_functions:
None
allow_url_fopen:
On
allow_url_include:
Off
magic_quotes_gpc:
Off
register_globals:
Off
open_basedir:
None
cURL:
Enabled
ZipArchive:
Enabled
MySQLi:
Enabled
PDO:
Enabled
wget:
Yes
curl (cmd):
Yes
perl:
Yes
python:
Yes (py3)
gcc:
No
pkexec:
No
git:
Yes
User Info
Username: kidscntx
User ID (UID): 1154
Group ID (GID): 1112
Script Owner UID: 1154
Current Dir Owner: 1154