Insurance — Claims Queue
An adjuster claims queue with a sortable, filterable table of claims showing number, claimant, type, amount, age and priority, color-coded SLA age warnings, an assign-to-me action with live unassigned counts, and a slide-in detail drawer rendering each claim timeline.
MCP
Code
:root {
--blue: #2563eb;
--blue-d: #1d4ed8;
--blue-50: #eef4ff;
--green: #15a06b;
--green-50: #e6f6ef;
--ink: #0f1a2b;
--muted: #5a6b82;
--bg: #f3f7fc;
--white: #ffffff;
--line: #e2eaf4;
--amber: #d97706;
--amber-50: #fef3e2;
--red: #dc2626;
--red-50: #fdecec;
--radius: 16px;
--radius-sm: 10px;
--shadow: 0 1px 2px rgba(15, 26, 43, .05), 0 12px 30px rgba(15, 26, 43, .07);
--shadow-sm: 0 1px 2px rgba(15, 26, 43, .06);
--font: 'Inter', system-ui, -apple-system, sans-serif;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: var(--font);
background: var(--bg);
color: var(--ink);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
padding: 28px 18px 60px;
}
.sr-only {
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.shell { max-width: 1080px; margin: 0 auto; }
/* Topbar */
.topbar {
display: flex; align-items: center; justify-content: space-between;
gap: 16px; margin-bottom: 22px;
}
.brand { display: flex; align-items: center; gap: 14px; }
.brand-mark {
display: grid; place-items: center; width: 44px; height: 44px;
border-radius: 12px; background: linear-gradient(135deg, var(--blue), var(--blue-d));
color: #fff; font-size: 20px; box-shadow: 0 6px 16px rgba(37, 99, 235, .3);
}
.topbar h1 { font-size: 1.5rem; font-weight: 800; letter-spacing: -.02em; }
.brand-sub { color: var(--muted); font-size: .85rem; font-weight: 500; }
.me { display: flex; align-items: center; gap: 10px; }
.me-name { font-weight: 600; font-size: .9rem; }
.me-avatar {
display: grid; place-items: center; width: 38px; height: 38px;
border-radius: 50%; background: var(--blue-50); color: var(--blue-d);
font-weight: 700; font-size: .82rem;
}
/* Stats */
.stats {
display: grid; grid-template-columns: repeat(4, 1fr);
gap: 14px; margin-bottom: 20px;
}
.stat {
background: var(--white); border: 1px solid var(--line);
border-radius: var(--radius); padding: 16px 18px;
display: flex; flex-direction: column; gap: 2px; box-shadow: var(--shadow-sm);
}
.stat-label { color: var(--muted); font-size: .78rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.stat-value { font-size: 1.85rem; font-weight: 800; letter-spacing: -.03em; line-height: 1.15; }
.stat-foot { color: var(--muted); font-size: .78rem; }
.stat--warn .stat-value { color: var(--amber); }
/* Filters */
.filters {
display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
background: var(--white); border: 1px solid var(--line);
border-radius: var(--radius); padding: 12px; margin-bottom: 16px;
box-shadow: var(--shadow-sm);
}
.search { position: relative; flex: 1 1 240px; min-width: 200px; }
.search-ico {
position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
color: var(--muted); font-size: 1.05rem;
}
.search input {
width: 100%; padding: 11px 12px 11px 34px; font: inherit;
border: 1px solid var(--line); border-radius: var(--radius-sm);
background: var(--bg); color: var(--ink);
}
.select {
padding: 11px 12px; font: inherit; border: 1px solid var(--line);
border-radius: var(--radius-sm); background: var(--bg); color: var(--ink);
cursor: pointer;
}
.toggle {
display: inline-flex; align-items: center; gap: 8px; font-size: .88rem;
font-weight: 600; color: var(--muted); cursor: pointer; padding: 0 6px;
}
.toggle input { width: 16px; height: 16px; accent-color: var(--blue); cursor: pointer; }
input:focus-visible, select:focus-visible, button:focus-visible, .toggle input:focus-visible {
outline: 2px solid var(--blue); outline-offset: 2px;
}
/* Table */
.table-wrap {
background: var(--white); border: 1px solid var(--line);
border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden;
}
.claims { width: 100%; border-collapse: collapse; }
.claims thead th {
text-align: left; font-size: .74rem; text-transform: uppercase;
letter-spacing: .05em; color: var(--muted); font-weight: 700;
padding: 14px 16px; border-bottom: 1px solid var(--line); background: #fafcff;
white-space: nowrap;
}
.claims th.num, .claims td.num { text-align: right; }
.th-sort button {
background: none; border: 0; font: inherit; font-size: inherit;
text-transform: inherit; letter-spacing: inherit; color: inherit;
font-weight: 700; cursor: pointer; display: inline-flex; align-items: center;
gap: 5px; padding: 0;
}
.caret { width: 0; height: 0; }
.th-sort.asc .caret { border-left: 4px solid transparent; border-right: 4px solid transparent; border-bottom: 5px solid var(--blue); }
.th-sort.desc .caret { border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid var(--blue); }
.th-sort.asc button, .th-sort.desc button { color: var(--blue-d); }
.claims tbody tr {
cursor: pointer; transition: background .12s ease;
}
.claims tbody tr:hover { background: var(--blue-50); }
.claims td {
padding: 14px 16px; border-bottom: 1px solid var(--line);
font-size: .9rem; vertical-align: middle;
}
.claims tbody tr:last-child td { border-bottom: 0; }
.cnum { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ink); }
.claimant { display: flex; flex-direction: column; }
.claimant b { font-weight: 600; }
.claimant span { color: var(--muted); font-size: .8rem; }
.amount { font-weight: 700; font-variant-numeric: tabular-nums; }
.type-chip {
display: inline-block; padding: 3px 9px; border-radius: 999px;
font-size: .76rem; font-weight: 600; background: var(--blue-50); color: var(--blue-d);
}
/* Age + SLA color coding */
.age { font-variant-numeric: tabular-nums; font-weight: 600; }
.age small { display: block; font-weight: 500; font-size: .72rem; }
.age--ok { color: var(--green); }
.age--warn { color: var(--amber); }
.age--late { color: var(--red); }
/* Priority */
.pri {
display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px;
border-radius: 999px; font-size: .76rem; font-weight: 700;
}
.pri::before { content: ""; width: 7px; height: 7px; border-radius: 50%; }
.pri--high { background: var(--red-50); color: var(--red); }
.pri--high::before { background: var(--red); }
.pri--medium { background: var(--amber-50); color: var(--amber); }
.pri--medium::before { background: var(--amber); }
.pri--low { background: var(--green-50); color: var(--green); }
.pri--low::before { background: var(--green); }
/* Status badge */
.badge {
display: inline-block; padding: 4px 10px; border-radius: 999px;
font-size: .76rem; font-weight: 600; border: 1px solid transparent; white-space: nowrap;
}
.badge--new { background: var(--blue-50); color: var(--blue-d); }
.badge--review { background: #f1ecfe; color: #6d28d9; }
.badge--inspection { background: var(--amber-50); color: var(--amber); }
.badge--docs { background: #fdecec; color: var(--red); }
.badge--approved { background: var(--green-50); color: var(--green); }
.adj { color: var(--muted); font-size: .85rem; }
.adj--mine { color: var(--blue-d); font-weight: 600; }
.assign {
padding: 7px 12px; font: inherit; font-size: .8rem; font-weight: 600;
border: 1px solid var(--blue); background: var(--white); color: var(--blue-d);
border-radius: 999px; cursor: pointer; white-space: nowrap; transition: all .12s ease;
}
.assign:hover { background: var(--blue); color: #fff; }
.assigned-tick { color: var(--green); font-weight: 700; font-size: .85rem; white-space: nowrap; }
.empty { padding: 40px; text-align: center; color: var(--muted); font-weight: 500; }
/* Drawer */
.drawer-overlay {
position: fixed; inset: 0; background: rgba(15, 26, 43, .42);
opacity: 0; transition: opacity .22s ease; z-index: 40;
}
.drawer-overlay.show { opacity: 1; }
.drawer {
position: fixed; top: 0; right: 0; height: 100%; width: 420px; max-width: 92vw;
background: var(--white); box-shadow: -10px 0 40px rgba(15, 26, 43, .18);
transform: translateX(100%); transition: transform .26s cubic-bezier(.4, 0, .2, 1);
z-index: 50; display: flex; flex-direction: column;
}
.drawer.show { transform: translateX(0); }
.drawer-head {
display: flex; align-items: flex-start; justify-content: space-between;
gap: 12px; padding: 22px 22px 16px; border-bottom: 1px solid var(--line);
}
.drawer-eyebrow { color: var(--muted); font-size: .78rem; font-weight: 700; letter-spacing: .04em; }
.drawer-head h2 { font-size: 1.2rem; font-weight: 800; letter-spacing: -.02em; margin-top: 2px; }
.drawer-close {
background: var(--bg); border: 1px solid var(--line); border-radius: 10px;
width: 34px; height: 34px; cursor: pointer; color: var(--muted); font-size: 1rem;
flex-shrink: 0; transition: all .12s ease;
}
.drawer-close:hover { background: var(--red-50); color: var(--red); }
.drawer-body { padding: 20px 22px 30px; overflow-y: auto; }
.d-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 22px; }
.d-cell .d-k { color: var(--muted); font-size: .76rem; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; }
.d-cell .d-v { font-weight: 600; font-size: .95rem; margin-top: 2px; }
.d-cell .d-v.big { font-size: 1.4rem; font-weight: 800; letter-spacing: -.02em; }
.d-section-title { font-size: .82rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); margin-bottom: 14px; }
.timeline { list-style: none; position: relative; padding-left: 26px; }
.timeline::before { content: ""; position: absolute; left: 7px; top: 6px; bottom: 6px; width: 2px; background: var(--line); }
.timeline li { position: relative; padding-bottom: 20px; }
.timeline li:last-child { padding-bottom: 0; }
.timeline li::before {
content: ""; position: absolute; left: -26px; top: 3px; width: 16px; height: 16px;
border-radius: 50%; background: var(--white); border: 3px solid var(--line);
}
.timeline li.done::before { border-color: var(--green); background: var(--green); }
.timeline li.current::before { border-color: var(--blue); background: var(--blue); box-shadow: 0 0 0 4px var(--blue-50); }
.tl-title { font-weight: 600; font-size: .92rem; }
.tl-meta { color: var(--muted); font-size: .8rem; margin-top: 1px; }
/* Responsive */
@media (max-width: 820px) {
.stats { grid-template-columns: repeat(2, 1fr); }
.claims thead { display: none; }
.claims, .claims tbody, .claims tr, .claims td { display: block; width: 100%; }
.claims tbody tr {
border: 1px solid var(--line); border-radius: var(--radius-sm);
margin-bottom: 12px; padding: 6px 4px;
}
.claims td { border: 0; padding: 7px 14px; display: flex; justify-content: space-between; gap: 14px; }
.claims td.num { text-align: left; }
.claims td::before {
content: attr(data-label); color: var(--muted); font-size: .76rem;
font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
}
}
@media (max-width: 520px) {
body { padding: 18px 12px 50px; }
.stats { grid-template-columns: 1fr; }
.topbar h1 { font-size: 1.25rem; }
.me-name { display: none; }
.filters { padding: 10px; }
.select, .search { flex: 1 1 100%; }
.stat-value { font-size: 1.55rem; }
.drawer { width: 100%; max-width: 100vw; }
}(function () {
"use strict";
var ME = "Dana Okafor";
// SLA target in days per priority
var SLA = { high: 3, medium: 7, low: 14 };
var PRI_RANK = { high: 3, medium: 2, low: 1 };
var STATUS_CLASS = {
"New": "badge--new",
"In review": "badge--review",
"Inspection": "badge--inspection",
"Awaiting docs": "badge--docs",
"Approved": "badge--approved"
};
// Realistic placeholder dataset
var claims = [
{ number: "CLM-48217", claimant: "Marcus Halloway", policy: "AUTO-77120", type: "Auto", amount: 8450, age: 5, priority: "high", status: "Inspection", adjuster: "Priya Nair", incident: "Rear-end collision, I-90 onramp", filed: "Jun 17" },
{ number: "CLM-48209", claimant: "Elena Vasquez", policy: "HOME-30418", type: "Property", amount: 23900, age: 9, priority: "high", status: "Awaiting docs", adjuster: null, incident: "Kitchen fire, smoke damage", filed: "Jun 13" },
{ number: "CLM-48231", claimant: "Theodore Brandt", policy: "AUTO-77910", type: "Auto", amount: 3120, age: 1, priority: "low", status: "New", adjuster: null, incident: "Hail damage to windshield", filed: "Jun 21" },
{ number: "CLM-48198", claimant: "Aisha Rahman", policy: "HLTH-55203", type: "Health", amount: 1480, age: 12, priority: "medium", status: "In review", adjuster: "Dana Okafor", incident: "Outpatient procedure reimbursement", filed: "Jun 10" },
{ number: "CLM-48224", claimant: "Grace Lindqvist", policy: "TRVL-90011", type: "Travel", amount: 2240, age: 3, priority: "medium", status: "New", adjuster: null, incident: "Trip cancellation, medical", filed: "Jun 19" },
{ number: "CLM-48176", claimant: "Omar Said", policy: "LIAB-12044", type: "Liability", amount: 14750, age: 16, priority: "high", status: "In review", adjuster: "Dana Okafor", incident: "Slip-and-fall, retail premises", filed: "Jun 06" },
{ number: "CLM-48240", claimant: "Beatrice Okonkwo", policy: "HOME-30802", type: "Property", amount: 6890, age: 2, priority: "low", status: "New", adjuster: null, incident: "Water damage, burst pipe", filed: "Jun 20" },
{ number: "CLM-48205", claimant: "Henrik Sorensen", policy: "AUTO-78033", type: "Auto", amount: 11200, age: 8, priority: "medium", status: "Inspection", adjuster: "Priya Nair", incident: "Side-impact at intersection", filed: "Jun 14" },
{ number: "CLM-48190", claimant: "Carla Mendez", policy: "HLTH-55719", type: "Health", amount: 970, age: 11, priority: "low", status: "Approved", adjuster: "Dana Okafor", incident: "Specialist visit claim", filed: "Jun 11" },
{ number: "CLM-48236", claimant: "Jonas Weber", policy: "TRVL-90245", type: "Travel", amount: 1650, age: 1, priority: "medium", status: "New", adjuster: null, incident: "Lost baggage, international", filed: "Jun 21" },
{ number: "CLM-48162", claimant: "Sofia Petrova", policy: "LIAB-12190", type: "Liability", amount: 31500, age: 19, priority: "high", status: "Awaiting docs", adjuster: "Marcus Lee", incident: "Property damage dispute", filed: "Jun 03" },
{ number: "CLM-48228", claimant: "Daniel Friedman", policy: "AUTO-78211", type: "Auto", amount: 4380, age: 4, priority: "low", status: "In review", adjuster: null, incident: "Parking lot fender bender", filed: "Jun 18" }
];
var sort = { key: "priority", dir: "desc" };
var filters = { q: "", type: "", priority: "", status: "", mine: false };
var rowsEl = document.getElementById("rows");
var emptyEl = document.getElementById("empty");
function fmtMoney(n) {
return "$" + n.toLocaleString("en-US");
}
function ageBand(c) {
var target = SLA[c.priority];
if (c.age >= target) return "late";
if (c.age >= target - 2) return "warn";
return "ok";
}
function isOpen(c) {
return c.status !== "Approved";
}
function matches(c) {
if (filters.type && c.type !== filters.type) return false;
if (filters.priority && c.priority !== filters.priority) return false;
if (filters.status && c.status !== filters.status) return false;
if (filters.mine && c.adjuster !== ME) return false;
if (filters.q) {
var q = filters.q.toLowerCase();
if (c.claimant.toLowerCase().indexOf(q) === -1 &&
c.number.toLowerCase().indexOf(q) === -1) return false;
}
return true;
}
function compare(a, b) {
var v;
if (sort.key === "priority") v = PRI_RANK[a.priority] - PRI_RANK[b.priority];
else if (sort.key === "age") v = a.age - b.age;
else v = a.number < b.number ? -1 : a.number > b.number ? 1 : 0;
return sort.dir === "asc" ? v : -v;
}
function renderStats() {
var open = claims.filter(isOpen);
var reserve = open.reduce(function (s, c) { return s + c.amount; }, 0);
var sla = open.filter(function (c) { return ageBand(c) === "late"; }).length;
var unassigned = open.filter(function (c) { return !c.adjuster; }).length;
document.getElementById("statOpen").textContent = open.length;
document.getElementById("statReserve").textContent = fmtMoney(reserve);
document.getElementById("statSla").textContent = sla;
document.getElementById("statUnassigned").textContent = unassigned;
}
function priLabel(p) { return p.charAt(0).toUpperCase() + p.slice(1); }
function render() {
var list = claims.filter(matches).slice().sort(compare);
rowsEl.innerHTML = "";
emptyEl.hidden = list.length !== 0;
list.forEach(function (c) {
var tr = document.createElement("tr");
tr.setAttribute("tabindex", "0");
tr.dataset.number = c.number;
var band = ageBand(c);
var slaTxt = band === "late" ? "SLA breached" : band === "warn" ? "due soon" : "on track";
var mine = c.adjuster === ME;
var adjCell = c.adjuster
? '<span class="adj' + (mine ? ' adj--mine' : '') + '">' + (mine ? "You" : c.adjuster) + '</span>'
: '<span class="adj">Unassigned</span>';
var actionCell = c.adjuster
? '<span class="assigned-tick">✓ assigned</span>'
: '<button type="button" class="assign" data-assign="' + c.number + '">Assign to me</button>';
tr.innerHTML =
'<td data-label="Claim #"><span class="cnum">' + c.number + '</span></td>' +
'<td data-label="Claimant"><span class="claimant"><b>' + c.claimant + '</b><span>' + c.policy + '</span></span></td>' +
'<td data-label="Type"><span class="type-chip">' + c.type + '</span></td>' +
'<td data-label="Reserve" class="num"><span class="amount">' + fmtMoney(c.amount) + '</span></td>' +
'<td data-label="Age"><span class="age age--' + band + '">' + c.age + 'd<small>' + slaTxt + '</small></span></td>' +
'<td data-label="Priority"><span class="pri pri--' + c.priority + '">' + priLabel(c.priority) + '</span></td>' +
'<td data-label="Status"><span class="badge ' + STATUS_CLASS[c.status] + '">' + c.status + '</span></td>' +
'<td data-label="Adjuster">' + adjCell + '</td>' +
'<td data-label="">' + actionCell + '</td>';
rowsEl.appendChild(tr);
});
renderStats();
updateSortHeaders();
}
function updateSortHeaders() {
document.querySelectorAll(".th-sort").forEach(function (th) {
th.classList.remove("asc", "desc");
if (th.dataset.sort === sort.key) th.classList.add(sort.dir);
});
}
// ----- Drawer -----
var drawer = document.getElementById("drawer");
var overlay = document.getElementById("overlay");
var lastFocus = null;
function buildTimeline(c) {
var steps = [
{ t: "Claim filed", m: c.filed + " · by claimant", done: true },
{ t: "Acknowledged", m: c.filed + " · auto-reply sent", done: true },
{ t: "Assigned to adjuster", m: c.adjuster ? (c.adjuster === ME ? "You" : c.adjuster) : "Pending", done: !!c.adjuster },
{ t: "Inspection / review", m: c.status === "Inspection" || c.status === "In review" ? "In progress" : (c.status === "Approved" || c.status === "Awaiting docs" ? "Complete" : "Not started"), done: c.status === "Approved" || c.status === "Awaiting docs" },
{ t: "Estimate / decision", m: c.status === "Approved" ? "Approved · " + fmtMoney(c.amount) : "Awaiting outcome", done: c.status === "Approved" }
];
// mark current
var currentIdx = -1;
for (var i = 0; i < steps.length; i++) if (!steps[i].done) { currentIdx = i; break; }
return steps.map(function (s, i) {
var cls = s.done ? "done" : (i === currentIdx ? "current" : "");
return '<li class="' + cls + '"><div class="tl-title">' + s.t + '</div><div class="tl-meta">' + s.m + '</div></li>';
}).join("");
}
function openDrawer(number) {
var c = claims.filter(function (x) { return x.number === number; })[0];
if (!c) return;
lastFocus = document.activeElement;
document.getElementById("drawerNum").textContent = c.number + " · " + c.type;
document.getElementById("drawerTitle").textContent = c.claimant;
var band = ageBand(c);
var slaTxt = band === "late" ? "SLA breached" : band === "warn" ? "due soon" : "on track";
document.getElementById("drawerBody").innerHTML =
'<div class="d-grid">' +
'<div class="d-cell"><div class="d-k">Reserve</div><div class="d-v big">' + fmtMoney(c.amount) + '</div></div>' +
'<div class="d-cell"><div class="d-k">Priority</div><div class="d-v"><span class="pri pri--' + c.priority + '">' + priLabel(c.priority) + '</span></div></div>' +
'<div class="d-cell"><div class="d-k">Policy</div><div class="d-v">' + c.policy + '</div></div>' +
'<div class="d-cell"><div class="d-k">Age</div><div class="d-v"><span class="age age--' + band + '">' + c.age + ' days · ' + slaTxt + '</span></div></div>' +
'<div class="d-cell"><div class="d-k">Status</div><div class="d-v"><span class="badge ' + STATUS_CLASS[c.status] + '">' + c.status + '</span></div></div>' +
'<div class="d-cell"><div class="d-k">Adjuster</div><div class="d-v">' + (c.adjuster ? (c.adjuster === ME ? "You" : c.adjuster) : "Unassigned") + '</div></div>' +
'<div class="d-cell" style="grid-column:1/-1"><div class="d-k">Incident</div><div class="d-v" style="font-weight:500">' + c.incident + '</div></div>' +
'</div>' +
'<h3 class="d-section-title">Claim timeline</h3>' +
'<ul class="timeline">' + buildTimeline(c) + '</ul>';
overlay.hidden = false;
drawer.setAttribute("aria-hidden", "false");
requestAnimationFrame(function () {
overlay.classList.add("show");
drawer.classList.add("show");
});
document.getElementById("drawerClose").focus();
}
function closeDrawer() {
overlay.classList.remove("show");
drawer.classList.remove("show");
drawer.setAttribute("aria-hidden", "true");
setTimeout(function () { overlay.hidden = true; }, 240);
if (lastFocus && lastFocus.focus) lastFocus.focus();
}
// ----- Events -----
document.getElementById("search").addEventListener("input", function (e) {
filters.q = e.target.value.trim(); render();
});
document.getElementById("fType").addEventListener("change", function (e) { filters.type = e.target.value; render(); });
document.getElementById("fPriority").addEventListener("change", function (e) { filters.priority = e.target.value; render(); });
document.getElementById("fStatus").addEventListener("change", function (e) { filters.status = e.target.value; render(); });
document.getElementById("fMine").addEventListener("change", function (e) { filters.mine = e.target.checked; render(); });
document.querySelectorAll(".th-sort").forEach(function (th) {
th.addEventListener("click", function () {
var key = th.dataset.sort;
if (sort.key === key) sort.dir = sort.dir === "asc" ? "desc" : "asc";
else { sort.key = key; sort.dir = key === "number" ? "asc" : "desc"; }
render();
});
});
rowsEl.addEventListener("click", function (e) {
var btn = e.target.closest("[data-assign]");
if (btn) {
e.stopPropagation();
var c = claims.filter(function (x) { return x.number === btn.dataset.assign; })[0];
if (c) { c.adjuster = ME; render(); }
return;
}
var tr = e.target.closest("tr");
if (tr && tr.dataset.number) openDrawer(tr.dataset.number);
});
rowsEl.addEventListener("keydown", function (e) {
if ((e.key === "Enter" || e.key === " ") && e.target.tagName === "TR" && e.target.dataset.number) {
e.preventDefault();
openDrawer(e.target.dataset.number);
}
});
document.getElementById("drawerClose").addEventListener("click", closeDrawer);
overlay.addEventListener("click", closeDrawer);
document.addEventListener("keydown", function (e) {
if (e.key === "Escape" && drawer.classList.contains("show")) closeDrawer();
});
render();
})();<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Claims Queue — Adjuster Console</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<main class="shell" role="main">
<header class="topbar">
<div class="brand">
<span class="brand-mark" aria-hidden="true">◆</span>
<div>
<h1>Claims Queue</h1>
<p class="brand-sub">Adjuster console · Northwind Mutual</p>
</div>
</div>
<div class="me">
<span class="me-name">Dana Okafor</span>
<span class="me-avatar" aria-hidden="true">DO</span>
</div>
</header>
<section class="stats" aria-label="Queue summary">
<article class="stat">
<span class="stat-label">Open claims</span>
<strong class="stat-value" id="statOpen">0</strong>
<span class="stat-foot">across all lines</span>
</article>
<article class="stat">
<span class="stat-label">Total reserve</span>
<strong class="stat-value" id="statReserve">$0</strong>
<span class="stat-foot">estimated exposure</span>
</article>
<article class="stat stat--warn">
<span class="stat-label">Breaching SLA</span>
<strong class="stat-value" id="statSla">0</strong>
<span class="stat-foot">need action today</span>
</article>
<article class="stat">
<span class="stat-label">Unassigned</span>
<strong class="stat-value" id="statUnassigned">0</strong>
<span class="stat-foot">waiting for an adjuster</span>
</article>
</section>
<section class="filters" aria-label="Filter claims">
<div class="search">
<span class="search-ico" aria-hidden="true">⌕</span>
<label class="sr-only" for="search">Search claims</label>
<input id="search" type="search" placeholder="Search claimant or claim #…" autocomplete="off" />
</div>
<label class="sr-only" for="fType">Claim type</label>
<select id="fType" class="select">
<option value="">All types</option>
<option value="Auto">Auto</option>
<option value="Property">Property</option>
<option value="Liability">Liability</option>
<option value="Health">Health</option>
<option value="Travel">Travel</option>
</select>
<label class="sr-only" for="fPriority">Priority</label>
<select id="fPriority" class="select">
<option value="">All priorities</option>
<option value="high">High</option>
<option value="medium">Medium</option>
<option value="low">Low</option>
</select>
<label class="sr-only" for="fStatus">Status</label>
<select id="fStatus" class="select">
<option value="">All statuses</option>
<option value="New">New</option>
<option value="In review">In review</option>
<option value="Inspection">Inspection</option>
<option value="Awaiting docs">Awaiting docs</option>
<option value="Approved">Approved</option>
</select>
<label class="toggle">
<input type="checkbox" id="fMine" />
<span>My claims only</span>
</label>
</section>
<section class="table-wrap" aria-label="Claims">
<table class="claims">
<thead>
<tr>
<th scope="col" class="th-sort" data-sort="number"><button type="button">Claim # <span class="caret"></span></button></th>
<th scope="col">Claimant</th>
<th scope="col">Type</th>
<th scope="col" class="num">Reserve</th>
<th scope="col" class="th-sort" data-sort="age"><button type="button">Age <span class="caret"></span></button></th>
<th scope="col" class="th-sort" data-sort="priority"><button type="button">Priority <span class="caret"></span></button></th>
<th scope="col">Status</th>
<th scope="col">Adjuster</th>
<th scope="col"><span class="sr-only">Actions</span></th>
</tr>
</thead>
<tbody id="rows"><!-- rendered by script.js --></tbody>
</table>
<p class="empty" id="empty" hidden>No claims match your filters.</p>
</section>
</main>
<!-- Detail drawer -->
<div class="drawer-overlay" id="overlay" hidden></div>
<aside class="drawer" id="drawer" aria-hidden="true" aria-labelledby="drawerTitle" role="dialog">
<header class="drawer-head">
<div>
<span class="drawer-eyebrow" id="drawerNum">—</span>
<h2 id="drawerTitle">Claim detail</h2>
</div>
<button type="button" class="drawer-close" id="drawerClose" aria-label="Close detail">✕</button>
</header>
<div class="drawer-body" id="drawerBody"><!-- rendered by script.js --></div>
</aside>
<script src="script.js"></script>
</body>
</html>Claims Queue
A reassuring, work-ready claims queue for an insurance adjuster. The header surfaces big confident numbers — open claims, total reserve and how many breach SLA — while a filter bar lets you search by claimant or number, narrow by claim type, priority and status, and toggle My claims only.
The table lists every claim with its number, claimant, type, reserve amount, age and a priority pill, and color-codes the age column so claims nearing or past their SLA stand out. Click any column header to sort by priority or age (and back again). The Assign to me button claims an item, drops the unassigned count and reassigns it to the current adjuster in place.
Selecting a row slides in a detail drawer with the claimant, policy, reserve and a full status timeline — filed, acknowledged, inspected, estimate sent — so you can pick up exactly where the claim left off. Everything runs on vanilla JS with no dependencies.
Illustrative UI only — not for real insurance or claims-handling use.