Files
portfolio/designs/GP systems/concept-2-dark-workstation.html
T
2026-02-13 16:42:45 +00:00

1458 lines
43 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GP Clinical System — Dark Workstation</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--bg: #0F1117;
--surface: #1A1D27;
--elevated: #232733;
--border: #2E3345;
--text: #E4E4E7;
--secondary: #9CA3AF;
--blue: #60A5FA;
--red: #F87171;
--amber: #FBBF24;
--green: #34D399;
--purple: #A78BFA;
--font-ui: 'Inter', -apple-system, sans-serif;
--font-mono: 'JetBrains Mono', 'Consolas', monospace;
}
html, body {
height: 100%; width: 100%;
font-family: var(--font-ui);
font-size: 13px;
color: var(--text);
background: var(--bg);
overflow: hidden;
line-height: 1.45;
}
.app {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
}
/* ── SCROLLBAR ── */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: #3E445A; }
/* ═══════════════════════════════════════════
1. PATIENT BANNER
═══════════════════════════════════════════ */
.patient-banner {
height: 70px;
background: var(--surface);
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
padding: 0 16px;
gap: 20px;
flex-shrink: 0;
z-index: 100;
}
.patient-avatar {
width: 42px; height: 42px;
border-radius: 50%;
background: linear-gradient(135deg, #3B4252, #434C5E);
display: flex; align-items: center; justify-content: center;
font-weight: 600; font-size: 15px; color: var(--blue);
flex-shrink: 0;
border: 2px solid var(--border);
}
.patient-id {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 180px;
}
.patient-name {
font-size: 16px;
font-weight: 700;
color: #fff;
letter-spacing: -0.01em;
}
.patient-demo {
font-size: 11.5px;
color: var(--secondary);
display: flex; gap: 8px; align-items: center;
}
.patient-demo span { white-space: nowrap; }
.patient-details {
display: flex;
gap: 24px;
flex: 1;
align-items: center;
}
.patient-field {
display: flex;
flex-direction: column;
gap: 1px;
}
.patient-field-label {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.06em;
color: #5E6378;
font-weight: 600;
}
.patient-field-value {
font-size: 12px;
color: var(--text);
font-family: var(--font-mono);
font-weight: 500;
}
.banner-badges {
display: flex;
gap: 8px;
margin-left: auto;
flex-shrink: 0;
}
.badge {
display: flex;
align-items: center;
gap: 5px;
padding: 5px 12px;
border-radius: 4px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
cursor: pointer;
transition: all 0.15s;
}
.badge-allergy {
background: rgba(248,113,113,0.12);
color: var(--red);
border: 1px solid rgba(248,113,113,0.25);
box-shadow: 0 0 12px rgba(248,113,113,0.08), inset 0 0 12px rgba(248,113,113,0.04);
animation: allergyPulse 3s ease-in-out infinite;
}
@keyframes allergyPulse {
0%, 100% { box-shadow: 0 0 12px rgba(248,113,113,0.08); }
50% { box-shadow: 0 0 20px rgba(248,113,113,0.18), 0 0 6px rgba(248,113,113,0.1); }
}
.badge-allergy .badge-dot {
width: 6px; height: 6px;
border-radius: 50%;
background: var(--red);
box-shadow: 0 0 6px var(--red);
}
.badge-alerts {
background: rgba(251,191,36,0.1);
color: var(--amber);
border: 1px solid rgba(251,191,36,0.2);
}
.badge-count {
background: rgba(255,255,255,0.1);
border-radius: 3px;
padding: 1px 5px;
font-size: 10px;
font-family: var(--font-mono);
}
/* ═══════════════════════════════════════════
2. TOOLBAR
═══════════════════════════════════════════ */
.toolbar {
height: 40px;
background: var(--elevated);
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
padding: 0 12px;
gap: 2px;
flex-shrink: 0;
}
.toolbar-btn {
display: flex;
align-items: center;
gap: 5px;
padding: 5px 10px;
border: none;
background: transparent;
color: var(--secondary);
font-family: var(--font-ui);
font-size: 12px;
font-weight: 500;
border-radius: 4px;
cursor: pointer;
transition: all 0.12s;
white-space: nowrap;
}
.toolbar-btn:hover {
background: rgba(96,165,250,0.1);
color: var(--blue);
}
.toolbar-btn:active {
background: rgba(96,165,250,0.15);
}
.toolbar-btn svg {
width: 14px; height: 14px;
stroke: currentColor;
fill: none;
stroke-width: 1.8;
stroke-linecap: round;
stroke-linejoin: round;
}
.toolbar-sep {
width: 1px;
height: 20px;
background: var(--border);
margin: 0 6px;
}
.toolbar-search {
margin-left: auto;
position: relative;
}
.toolbar-search input {
width: 200px;
height: 28px;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 4px;
padding: 0 8px 0 28px;
color: var(--text);
font-family: var(--font-ui);
font-size: 12px;
outline: none;
transition: border-color 0.15s;
}
.toolbar-search input::placeholder { color: #4A5068; }
.toolbar-search input:focus { border-color: var(--blue); }
.toolbar-search svg {
position: absolute;
left: 8px; top: 50%;
transform: translateY(-50%);
width: 13px; height: 13px;
stroke: #4A5068;
fill: none;
stroke-width: 2;
}
.toolbar-search .kbd {
position: absolute;
right: 6px; top: 50%;
transform: translateY(-50%);
font-family: var(--font-mono);
font-size: 10px;
color: #4A5068;
background: var(--bg);
padding: 1px 5px;
border-radius: 3px;
border: 1px solid var(--border);
}
/* ═══════════════════════════════════════════
3. MAIN BODY
═══════════════════════════════════════════ */
.main-body {
display: flex;
flex: 1;
overflow: hidden;
}
/* ── LEFT NAV ── */
.left-nav {
width: 200px;
background: var(--surface);
border-right: 1px solid var(--border);
display: flex;
flex-direction: column;
flex-shrink: 0;
overflow-y: auto;
}
.nav-header {
padding: 10px 12px 6px;
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #4A5068;
font-weight: 600;
}
.nav-item {
display: flex;
align-items: center;
gap: 8px;
padding: 7px 12px;
cursor: pointer;
transition: all 0.1s;
border-left: 3px solid transparent;
font-size: 12.5px;
color: var(--secondary);
}
.nav-item:hover {
background: rgba(255,255,255,0.03);
color: var(--text);
}
.nav-item.active {
background: rgba(96,165,250,0.06);
color: var(--text);
border-left-color: var(--blue);
}
.nav-dot {
width: 7px; height: 7px;
border-radius: 50%;
flex-shrink: 0;
}
.nav-count {
margin-left: auto;
font-family: var(--font-mono);
font-size: 10px;
color: #4A5068;
background: var(--bg);
padding: 1px 6px;
border-radius: 3px;
min-width: 22px;
text-align: center;
}
.nav-item.active .nav-count {
color: var(--blue);
background: rgba(96,165,250,0.1);
}
/* ── THREE-COL WORKSPACE ── */
.workspace {
flex: 1;
display: flex;
overflow: hidden;
}
/* Column 1: Consultation List */
.col-list {
width: 30%;
min-width: 260px;
border-right: 1px solid var(--border);
display: flex;
flex-direction: column;
overflow: hidden;
}
.col-header {
padding: 8px 12px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--secondary);
background: var(--elevated);
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
}
.col-header-count {
font-family: var(--font-mono);
font-size: 10px;
color: #4A5068;
background: var(--bg);
padding: 1px 6px;
border-radius: 3px;
}
.consult-table {
flex: 1;
overflow-y: auto;
}
.consult-table-header {
display: grid;
grid-template-columns: 90px 1fr 110px;
padding: 5px 12px;
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: #4A5068;
border-bottom: 1px solid var(--border);
background: var(--surface);
position: sticky;
top: 0;
}
.consult-row {
display: grid;
grid-template-columns: 90px 1fr 110px;
padding: 8px 12px;
font-size: 12px;
cursor: pointer;
border-left: 3px solid transparent;
border-bottom: 1px solid rgba(46,51,69,0.5);
transition: all 0.1s;
}
.consult-row:hover {
background: rgba(255,255,255,0.02);
}
.consult-row.active {
background: rgba(96,165,250,0.06);
border-left-color: var(--blue);
}
.consult-date {
font-family: var(--font-mono);
font-size: 11.5px;
color: var(--secondary);
}
.consult-clinician {
color: var(--text);
font-weight: 500;
}
.consult-type {
font-size: 11px;
color: var(--secondary);
text-align: right;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.consult-type-badge {
display: inline-block;
padding: 1px 6px;
border-radius: 3px;
font-size: 10px;
font-weight: 500;
}
.type-review { background: rgba(96,165,250,0.1); color: var(--blue); }
.type-routine { background: rgba(52,211,153,0.1); color: var(--green); }
.type-urgent { background: rgba(248,113,113,0.1); color: var(--red); }
.type-followup { background: rgba(251,191,36,0.1); color: var(--amber); }
.type-admin { background: rgba(167,139,250,0.1); color: var(--purple); }
.type-telephone { background: rgba(156,163,175,0.1); color: var(--secondary); }
/* Column 2: Consultation Detail */
.col-detail {
width: 40%;
overflow-y: auto;
padding: 16px;
border-right: 1px solid var(--border);
}
.detail-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 14px;
padding-bottom: 10px;
border-bottom: 1px solid var(--border);
}
.detail-title {
font-size: 15px;
font-weight: 700;
color: #fff;
}
.detail-meta {
display: flex;
gap: 12px;
font-size: 11px;
color: var(--secondary);
}
.detail-meta span { display: flex; align-items: center; gap: 4px; }
.section-label {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.07em;
color: var(--blue);
margin-top: 16px;
margin-bottom: 6px;
display: flex;
align-items: center;
gap: 6px;
}
.section-label::after {
content: '';
flex: 1;
height: 1px;
background: var(--border);
}
.section-label:first-of-type { margin-top: 0; }
.clinical-text {
font-size: 12.5px;
line-height: 1.6;
color: var(--text);
}
.clinical-text p {
margin-bottom: 6px;
}
.clinical-value {
font-family: var(--font-mono);
font-weight: 600;
font-size: 12px;
padding: 1px 4px;
border-radius: 3px;
background: rgba(52,211,153,0.08);
color: var(--green);
}
.clinical-value.amber {
background: rgba(251,191,36,0.08);
color: var(--amber);
}
.clinical-value.red {
background: rgba(248,113,113,0.08);
color: var(--red);
}
.clinical-value.normal {
background: rgba(52,211,153,0.08);
color: var(--green);
}
.snomed-code {
font-family: var(--font-mono);
font-size: 11px;
color: var(--purple);
padding: 1px 5px;
border-radius: 3px;
background: rgba(167,139,250,0.08);
cursor: help;
}
.plan-list {
list-style: none;
padding: 0;
}
.plan-list li {
position: relative;
padding: 4px 0 4px 16px;
font-size: 12.5px;
line-height: 1.5;
color: var(--text);
}
.plan-list li::before {
content: '';
position: absolute;
left: 2px;
color: var(--blue);
font-weight: 700;
font-size: 14px;
line-height: 1.35;
}
.exam-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 6px 16px;
margin: 6px 0;
}
.exam-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 5px 8px;
background: var(--surface);
border-radius: 4px;
border: 1px solid var(--border);
}
.exam-label {
font-size: 11.5px;
color: var(--secondary);
}
.exam-value {
font-family: var(--font-mono);
font-size: 12px;
font-weight: 600;
}
.codes-list {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 4px;
}
.code-tag {
display: flex;
align-items: center;
gap: 5px;
padding: 3px 8px;
background: rgba(167,139,250,0.06);
border: 1px solid rgba(167,139,250,0.12);
border-radius: 4px;
font-size: 11px;
color: var(--text);
}
.code-tag .code-id {
font-family: var(--font-mono);
font-size: 10px;
color: var(--purple);
}
/* Column 3: Clinical Summary */
.col-summary {
width: 30%;
min-width: 240px;
overflow-y: auto;
padding: 0;
}
.summary-section {
border-bottom: 1px solid var(--border);
}
.summary-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px;
cursor: pointer;
background: var(--elevated);
transition: background 0.1s;
user-select: none;
}
.summary-header:hover {
background: #282D3A;
}
.summary-header-title {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--secondary);
display: flex;
align-items: center;
gap: 6px;
}
.summary-header-count {
font-family: var(--font-mono);
font-size: 10px;
color: #4A5068;
}
.summary-chevron {
width: 12px; height: 12px;
stroke: #4A5068;
fill: none;
stroke-width: 2;
transition: transform 0.2s;
}
.summary-section.collapsed .summary-chevron {
transform: rotate(-90deg);
}
.summary-section.collapsed .summary-body {
display: none;
}
.summary-body {
padding: 6px 12px 10px;
}
.problem-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 5px 0;
border-bottom: 1px solid rgba(46,51,69,0.4);
}
.problem-item:last-child { border-bottom: none; }
.problem-name {
font-size: 12px;
color: var(--text);
font-weight: 500;
}
.problem-year {
font-family: var(--font-mono);
font-size: 10.5px;
color: #4A5068;
}
.problem-status {
width: 6px; height: 6px;
border-radius: 50%;
margin-right: 8px;
flex-shrink: 0;
}
.problem-row {
display: flex;
align-items: center;
}
.med-item {
padding: 6px 0;
border-bottom: 1px solid rgba(46,51,69,0.4);
}
.med-item:last-child { border-bottom: none; }
.med-name {
font-size: 12px;
font-weight: 600;
color: var(--text);
}
.med-dose {
font-family: var(--font-mono);
font-size: 11px;
color: var(--green);
}
.med-info {
font-size: 10.5px;
color: var(--secondary);
margin-top: 1px;
}
.result-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 5px 0;
border-bottom: 1px solid rgba(46,51,69,0.4);
}
.result-item:last-child { border-bottom: none; }
.result-dot {
width: 7px; height: 7px;
border-radius: 50%;
margin-right: 8px;
flex-shrink: 0;
}
.result-label {
font-size: 12px;
color: var(--text);
display: flex;
align-items: center;
}
.result-value {
font-family: var(--font-mono);
font-size: 12px;
font-weight: 600;
}
.allergy-item {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px;
background: rgba(248,113,113,0.06);
border: 1px solid rgba(248,113,113,0.15);
border-radius: 4px;
margin: 2px 0;
}
.allergy-icon {
width: 16px; height: 16px;
color: var(--red);
flex-shrink: 0;
}
.allergy-name {
font-size: 12px;
font-weight: 600;
color: var(--red);
}
.allergy-reaction {
font-size: 10.5px;
color: var(--secondary);
}
.reminder-item {
display: flex;
align-items: center;
gap: 8px;
padding: 5px 0;
border-bottom: 1px solid rgba(46,51,69,0.4);
}
.reminder-item:last-child { border-bottom: none; }
.reminder-icon {
width: 14px; height: 14px;
color: var(--amber);
flex-shrink: 0;
}
.reminder-text {
font-size: 12px;
color: var(--text);
}
.reminder-due {
font-family: var(--font-mono);
font-size: 10.5px;
color: var(--amber);
margin-left: auto;
white-space: nowrap;
}
/* ═══════════════════════════════════════════
5. STATUS BAR
═══════════════════════════════════════════ */
.status-bar {
height: 24px;
background: #181B24;
border-top: 1px solid var(--border);
display: flex;
align-items: center;
padding: 0 12px;
font-size: 11px;
color: #4A5068;
gap: 4px;
flex-shrink: 0;
}
.status-item {
display: flex;
align-items: center;
gap: 4px;
padding: 0 8px;
white-space: nowrap;
}
.status-item + .status-item {
border-left: 1px solid var(--border);
}
.status-dot {
width: 6px; height: 6px;
border-radius: 50%;
}
.status-right {
margin-left: auto;
display: flex;
align-items: center;
gap: 4px;
}
/* Utility */
.assessment-list {
list-style: none;
padding: 0;
counter-reset: assess;
}
.assessment-list li {
position: relative;
padding: 3px 0 3px 22px;
font-size: 12.5px;
line-height: 1.5;
counter-increment: assess;
}
.assessment-list li::before {
content: counter(assess) '.';
position: absolute;
left: 2px;
color: var(--blue);
font-weight: 700;
font-family: var(--font-mono);
font-size: 11px;
}
</style>
</head>
<body>
<div class="app">
<!-- ═══════════ 1. PATIENT BANNER ═══════════ -->
<header class="patient-banner">
<div class="patient-avatar">SM</div>
<div class="patient-id">
<div class="patient-name">Sarah Mitchell</div>
<div class="patient-demo">
<span>DOB 14/03/1967</span>
<span style="color:#4A5068;">|</span>
<span>58y</span>
<span style="color:#4A5068;">|</span>
<span>Female</span>
</div>
</div>
<div class="patient-details">
<div class="patient-field">
<span class="patient-field-label">NHS Number</span>
<span class="patient-field-value">943 216 8821</span>
</div>
<div class="patient-field">
<span class="patient-field-label">Address</span>
<span class="patient-field-value" style="font-family:var(--font-ui);font-size:12px;">14 Oakfield Rd, Bristol BS8 2BN</span>
</div>
<div class="patient-field">
<span class="patient-field-label">Phone</span>
<span class="patient-field-value">07712 845 392</span>
</div>
<div class="patient-field">
<span class="patient-field-label">Usual GP</span>
<span class="patient-field-value" style="font-family:var(--font-ui);font-size:12px;">Dr. J Patterson</span>
</div>
</div>
<div class="banner-badges">
<div class="badge badge-allergy">
<div class="badge-dot"></div>
Allergy
<span class="badge-count">Penicillin</span>
</div>
<div class="badge badge-alerts">
<svg style="width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2" viewBox="0 0 24 24"><path d="M12 9v4m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/></svg>
Alerts
<span class="badge-count">2</span>
</div>
</div>
</header>
<!-- ═══════════ 2. TOOLBAR ═══════════ -->
<div class="toolbar">
<button class="toolbar-btn">
<svg viewBox="0 0 24 24"><path d="M12 5v14M5 12h14"/></svg>
New Consultation
</button>
<button class="toolbar-btn">
<svg viewBox="0 0 24 24"><path d="M19 3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2z"/><path d="M9 12h6M12 9v6"/></svg>
Prescribe
</button>
<button class="toolbar-btn">
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="M12 8v8M8 12h8"/></svg>
Add Problem
</button>
<div class="toolbar-sep"></div>
<button class="toolbar-btn">
<svg viewBox="0 0 24 24"><path d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2"/><rect x="9" y="3" width="6" height="4" rx="1"/></svg>
Order Test
</button>
<button class="toolbar-btn">
<svg viewBox="0 0 24 24"><path d="M17 7l-10 10M7 7l10 10"/><rect x="3" y="3" width="18" height="18" rx="2"/></svg>
Refer
</button>
<button class="toolbar-btn">
<svg viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><path d="M14 2v6h6M16 13H8M16 17H8M10 9H8"/></svg>
Fit Note
</button>
<button class="toolbar-btn">
<svg viewBox="0 0 24 24"><path d="M6 9l6 6 6-6"/><path d="M6 4h12"/></svg>
Print
</button>
<div class="toolbar-search">
<svg viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="M21 21l-4.35-4.35"/></svg>
<input type="text" placeholder="Search record...">
<span class="kbd">Ctrl+F</span>
</div>
</div>
<!-- ═══════════ 3. MAIN BODY ═══════════ -->
<div class="main-body">
<!-- LEFT NAV -->
<nav class="left-nav">
<div class="nav-header">Clinical Record</div>
<div class="nav-item active">
<span class="nav-dot" style="background:var(--blue)"></span>
Consultations
<span class="nav-count">24</span>
</div>
<div class="nav-item">
<span class="nav-dot" style="background:var(--amber)"></span>
Problems
<span class="nav-count">3</span>
</div>
<div class="nav-item">
<span class="nav-dot" style="background:var(--green)"></span>
Medications
<span class="nav-count">3</span>
</div>
<div class="nav-item">
<span class="nav-dot" style="background:var(--red)"></span>
Allergies
<span class="nav-count">1</span>
</div>
<div class="nav-item">
<span class="nav-dot" style="background:var(--purple)"></span>
Results
<span class="nav-count">18</span>
</div>
<div class="nav-item">
<span class="nav-dot" style="background:var(--blue)"></span>
Referrals
<span class="nav-count">2</span>
</div>
<div class="nav-item">
<span class="nav-dot" style="background:var(--green)"></span>
Immunisations
<span class="nav-count">12</span>
</div>
<div class="nav-item">
<span class="nav-dot" style="background:var(--secondary)"></span>
Documents
<span class="nav-count">8</span>
</div>
<div class="nav-item">
<span class="nav-dot" style="background:var(--amber)"></span>
Measurements
<span class="nav-count">15</span>
</div>
<div class="nav-item">
<span class="nav-dot" style="background:var(--secondary)"></span>
Family History
<span class="nav-count">4</span>
</div>
</nav>
<!-- THREE-COLUMN WORKSPACE -->
<div class="workspace">
<!-- COL 1: CONSULTATION LIST -->
<div class="col-list">
<div class="col-header">
Consultations
<span class="col-header-count">24 entries</span>
</div>
<div class="consult-table">
<div class="consult-table-header">
<span>Date</span>
<span>Clinician</span>
<span style="text-align:right">Type</span>
</div>
<div class="consult-row active">
<span class="consult-date">13/02/2026</span>
<span class="consult-clinician">Dr Patterson</span>
<span class="consult-type"><span class="consult-type-badge type-review">DM Review</span></span>
</div>
<div class="consult-row">
<span class="consult-date">28/01/2026</span>
<span class="consult-clinician">Dr Patterson</span>
<span class="consult-type"><span class="consult-type-badge type-routine">Routine</span></span>
</div>
<div class="consult-row">
<span class="consult-date">14/01/2026</span>
<span class="consult-clinician">Nurse Williams</span>
<span class="consult-type"><span class="consult-type-badge type-followup">BP F/U</span></span>
</div>
<div class="consult-row">
<span class="consult-date">02/12/2025</span>
<span class="consult-clinician">Dr Ahmed</span>
<span class="consult-type"><span class="consult-type-badge type-urgent">Urgent</span></span>
</div>
<div class="consult-row">
<span class="consult-date">18/11/2025</span>
<span class="consult-clinician">Dr Patterson</span>
<span class="consult-type"><span class="consult-type-badge type-telephone">Telephone</span></span>
</div>
<div class="consult-row">
<span class="consult-date">04/10/2025</span>
<span class="consult-clinician">Dr Patterson</span>
<span class="consult-type"><span class="consult-type-badge type-review">HTN Review</span></span>
</div>
<div class="consult-row">
<span class="consult-date">22/08/2025</span>
<span class="consult-clinician">Nurse Williams</span>
<span class="consult-type"><span class="consult-type-badge type-admin">Bloods</span></span>
</div>
<div class="consult-row">
<span class="consult-date">15/06/2025</span>
<span class="consult-clinician">Dr Patterson</span>
<span class="consult-type"><span class="consult-type-badge type-routine">Routine</span></span>
</div>
</div>
</div>
<!-- COL 2: CONSULTATION DETAIL -->
<div class="col-detail">
<div class="detail-header">
<div>
<div class="detail-title">Diabetes Annual Review</div>
<div class="detail-meta" style="margin-top:4px;">
<span>
<svg style="width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2" viewBox="0 0 24 24"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>
13/02/2026
</span>
<span>
<svg style="width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2" viewBox="0 0 24 24"><path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
Dr. J Patterson
</span>
<span>
<svg style="width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
10:35 — 11:05
</span>
</div>
</div>
</div>
<!-- History -->
<div class="section-label">History</div>
<div class="clinical-text">
<p>Annual diabetes review. Patient reports generally well-controlled sugars on home monitoring. Occasional fasting readings of <span class="clinical-value amber">8-9 mmol/L</span> noted on waking, otherwise within target range. No episodes of hypoglycaemia. Good medication adherence — taking Metformin regularly without GI side effects.</p>
<p>Reports increased right knee stiffness over the past 3 months, using Ibuprofen 1-2 times per week. No chest pain, shortness of breath, polyuria, or polydipsia. Denies visual disturbance. Annual eye screening completed Oct 2025 — no retinopathy detected. Foot check done by podiatry Nov 2025 — normal peripheral pulses, intact sensation.</p>
</div>
<!-- Examination -->
<div class="section-label">Examination</div>
<div class="exam-grid">
<div class="exam-item">
<span class="exam-label">Blood Pressure</span>
<span class="exam-value" style="color:var(--amber)">138/82 mmHg</span>
</div>
<div class="exam-item">
<span class="exam-label">Pulse</span>
<span class="exam-value" style="color:var(--green)">72 bpm, regular</span>
</div>
<div class="exam-item">
<span class="exam-label">Weight</span>
<span class="exam-value" style="color:var(--text)">74.2 kg</span>
</div>
<div class="exam-item">
<span class="exam-label">BMI</span>
<span class="exam-value" style="color:var(--amber)">27.4 kg/m&sup2;</span>
</div>
<div class="exam-item">
<span class="exam-label">HbA1c</span>
<span class="exam-value" style="color:var(--green)">52 mmol/mol</span>
</div>
<div class="exam-item">
<span class="exam-label">Foot Exam</span>
<span class="exam-value" style="color:var(--green)">Normal</span>
</div>
</div>
<!-- Assessment -->
<div class="section-label">Assessment</div>
<ol class="assessment-list">
<li><strong>Type 2 Diabetes Mellitus</strong> — reasonable glycaemic control, HbA1c <span class="clinical-value normal">52 mmol/mol</span> (target &lt;53). Fasting hyperglycaemia noted, consider lifestyle modification before medication change.</li>
<li><strong>Essential Hypertension</strong> — BP <span class="clinical-value amber">138/82</span>, slightly above target of 130/80 for diabetic patient. Re-check in 4 weeks; consider uptitration of Amlodipine if persistently elevated.</li>
<li><strong>Osteoarthritis R Knee</strong> — intermittent symptoms managed with PRN Ibuprofen. Discussed risks of long-term NSAID use with renal and cardiovascular considerations. Advised paracetamol as first-line, topical NSAIDs as alternative.</li>
</ol>
<!-- Plan -->
<div class="section-label">Plan</div>
<ul class="plan-list">
<li>Continue <strong>Metformin 500mg BD</strong> — no dose change at present</li>
<li>Continue <strong>Amlodipine 5mg OD</strong> — review BP in 4 weeks; consider increasing to 10mg if above target</li>
<li>Lifestyle advice: reduce refined carbohydrates at evening meal to address fasting hyperglycaemia; aim for 30 min walking daily</li>
<li>Repeat bloods in 6 months: HbA1c, U&amp;Es, lipid profile, LFTs</li>
<li>Refer to MSK physiotherapy for right knee OA if symptoms worsen</li>
<li>Next annual diabetes review booked — Feb 2027</li>
</ul>
<!-- Codes -->
<div class="section-label">SNOMED CT Codes</div>
<div class="codes-list">
<div class="code-tag">
<span class="code-id">44054006</span>
Type 2 diabetes mellitus
</div>
<div class="code-tag">
<span class="code-id">38341003</span>
Essential hypertension
</div>
<div class="code-tag">
<span class="code-id">239873007</span>
OA right knee
</div>
<div class="code-tag">
<span class="code-id">43396009</span>
HbA1c measurement
</div>
<div class="code-tag">
<span class="code-id">271649006</span>
Blood pressure reading
</div>
<div class="code-tag">
<span class="code-id">60621009</span>
BMI measurement
</div>
</div>
</div>
<!-- COL 3: CLINICAL SUMMARY -->
<div class="col-summary">
<!-- Active Problems -->
<div class="summary-section">
<div class="summary-header" onclick="this.parentElement.classList.toggle('collapsed')">
<span class="summary-header-title">
<svg style="width:13px;height:13px;stroke:var(--amber);fill:none;stroke-width:2" viewBox="0 0 24 24"><path d="M12 9v4m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/></svg>
Active Problems
</span>
<span style="display:flex;align-items:center;gap:6px;">
<span class="summary-header-count">3</span>
<svg class="summary-chevron" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>
</span>
</div>
<div class="summary-body">
<div class="problem-item">
<div class="problem-row">
<span class="problem-status" style="background:var(--amber)"></span>
<span class="problem-name">Type 2 Diabetes Mellitus</span>
</div>
<span class="problem-year">2019</span>
</div>
<div class="problem-item">
<div class="problem-row">
<span class="problem-status" style="background:var(--amber)"></span>
<span class="problem-name">Essential Hypertension</span>
</div>
<span class="problem-year">2015</span>
</div>
<div class="problem-item">
<div class="problem-row">
<span class="problem-status" style="background:var(--green)"></span>
<span class="problem-name">Osteoarthritis R Knee</span>
</div>
<span class="problem-year">2021</span>
</div>
</div>
</div>
<!-- Medications -->
<div class="summary-section">
<div class="summary-header" onclick="this.parentElement.classList.toggle('collapsed')">
<span class="summary-header-title">
<svg style="width:13px;height:13px;stroke:var(--green);fill:none;stroke-width:2" viewBox="0 0 24 24"><path d="M19 3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V5a2 2 0 00-2-2z"/><path d="M9 12h6M12 9v6"/></svg>
Current Medications
</span>
<span style="display:flex;align-items:center;gap:6px;">
<span class="summary-header-count">3</span>
<svg class="summary-chevron" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>
</span>
</div>
<div class="summary-body">
<div class="med-item">
<div class="med-name">Metformin <span class="med-dose">500mg BD</span></div>
<div class="med-info">Oral &middot; Repeat &middot; Since Mar 2019 &middot; 56 tablets</div>
</div>
<div class="med-item">
<div class="med-name">Amlodipine <span class="med-dose">5mg OD</span></div>
<div class="med-info">Oral &middot; Repeat &middot; Since Jun 2015 &middot; 28 tablets</div>
</div>
<div class="med-item">
<div class="med-name">Ibuprofen <span class="med-dose">400mg PRN</span></div>
<div class="med-info">Oral &middot; Acute &middot; Since Sep 2021 &middot; 24 tablets</div>
</div>
</div>
</div>
<!-- Latest Results -->
<div class="summary-section">
<div class="summary-header" onclick="this.parentElement.classList.toggle('collapsed')">
<span class="summary-header-title">
<svg style="width:13px;height:13px;stroke:var(--purple);fill:none;stroke-width:2" viewBox="0 0 24 24"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>
Latest Results
</span>
<span style="display:flex;align-items:center;gap:6px;">
<span class="summary-header-count">4</span>
<svg class="summary-chevron" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>
</span>
</div>
<div class="summary-body">
<div class="result-item">
<span class="result-label">
<span class="result-dot" style="background:var(--green)"></span>
HbA1c
</span>
<span class="result-value" style="color:var(--green)">52 mmol/mol</span>
</div>
<div class="result-item">
<span class="result-label">
<span class="result-dot" style="background:var(--amber)"></span>
eGFR
</span>
<span class="result-value" style="color:var(--amber)">78 mL/min</span>
</div>
<div class="result-item">
<span class="result-label">
<span class="result-dot" style="background:var(--amber)"></span>
Total Cholesterol
</span>
<span class="result-value" style="color:var(--amber)">5.2 mmol/L</span>
</div>
<div class="result-item">
<span class="result-label">
<span class="result-dot" style="background:var(--amber)"></span>
Blood Pressure
</span>
<span class="result-value" style="color:var(--amber)">138/82</span>
</div>
</div>
</div>
<!-- Allergies -->
<div class="summary-section">
<div class="summary-header" onclick="this.parentElement.classList.toggle('collapsed')">
<span class="summary-header-title">
<svg style="width:13px;height:13px;stroke:var(--red);fill:none;stroke-width:2" viewBox="0 0 24 24"><path d="M12 9v4m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/></svg>
Allergies &amp; Adverse Reactions
</span>
<span style="display:flex;align-items:center;gap:6px;">
<span class="summary-header-count">1</span>
<svg class="summary-chevron" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>
</span>
</div>
<div class="summary-body">
<div class="allergy-item">
<svg class="allergy-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M4.93 4.93l14.14 14.14"/></svg>
<div>
<div class="allergy-name">Penicillin</div>
<div class="allergy-reaction">Reaction: Rash, Anaphylaxis risk &middot; Severity: High &middot; Confirmed</div>
</div>
</div>
</div>
</div>
<!-- Reminders -->
<div class="summary-section">
<div class="summary-header" onclick="this.parentElement.classList.toggle('collapsed')">
<span class="summary-header-title">
<svg style="width:13px;height:13px;stroke:var(--amber);fill:none;stroke-width:2" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
Reminders
</span>
<span style="display:flex;align-items:center;gap:6px;">
<span class="summary-header-count">2</span>
<svg class="summary-chevron" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round"><path d="M6 9l6 6 6-6"/></svg>
</span>
</div>
<div class="summary-body">
<div class="reminder-item">
<svg class="reminder-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
<span class="reminder-text">BP re-check</span>
<span class="reminder-due">Mar 2026</span>
</div>
<div class="reminder-item">
<svg class="reminder-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>
<span class="reminder-text">Annual bloods — HbA1c, U&amp;Es, lipids, LFTs</span>
<span class="reminder-due">Aug 2026</span>
</div>
</div>
</div>
</div>
</div><!-- /workspace -->
</div><!-- /main-body -->
<!-- ═══════════ 5. STATUS BAR ═══════════ -->
<div class="status-bar">
<div class="status-item">
<span class="status-dot" style="background:var(--green)"></span>
Oakfield Medical Practice
</div>
<div class="status-item">
<svg style="width:11px;height:11px;stroke:currentColor;fill:none;stroke-width:2" viewBox="0 0 24 24"><path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
Dr. J Patterson
</div>
<div class="status-item" id="statusDateTime">
<svg style="width:11px;height:11px;stroke:currentColor;fill:none;stroke-width:2" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
13/02/2026 &mdash; <span id="liveTime"></span>
</div>
<div class="status-right">
<div class="status-item">
<svg style="width:11px;height:11px;stroke:var(--green);fill:none;stroke-width:2" viewBox="0 0 24 24"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0110 0v4"/></svg>
Record Locked — Editing
</div>
<div class="status-item">
EMIS Web v8.4
</div>
</div>
</div>
</div><!-- /app -->
<script>
// Live clock in status bar
function updateClock() {
const now = new Date();
const h = String(now.getHours()).padStart(2, '0');
const m = String(now.getMinutes()).padStart(2, '0');
const s = String(now.getSeconds()).padStart(2, '0');
document.getElementById('liveTime').textContent = h + ':' + m + ':' + s;
}
updateClock();
setInterval(updateClock, 1000);
// Consultation row click
document.querySelectorAll('.consult-row').forEach(row => {
row.addEventListener('click', () => {
document.querySelectorAll('.consult-row').forEach(r => r.classList.remove('active'));
row.classList.add('active');
});
});
// Nav item click
document.querySelectorAll('.nav-item').forEach(item => {
item.addEventListener('click', () => {
document.querySelectorAll('.nav-item').forEach(n => n.classList.remove('active'));
item.classList.add('active');
});
});
</script>
</body>
</html>