Law Firm — Case / Matter Tracker
An authoritative matter-management board for a law firm listing active cases with a horizontal Intake to Closed status stepper, next deadline, assigned attorney and practice area, plus a slide-in detail drawer revealing a chronological timeline of events for each matter.
MCP
Code
:root {
--navy: #1b2a4a;
--navy-d: #101b33;
--gold: #b08d57;
--gold-soft: #efe3cf;
--ink: #1a1f2b;
--muted: #5b6577;
--bg: #f5f3ee;
--white: #ffffff;
--line: #e2ddd2;
--line-soft: #ece8df;
--ok: #2f6f4f;
--warn: #9a6b1e;
--serif: "Georgia", "Times New Roman", serif;
--sans: "Inter", system-ui, -apple-system, sans-serif;
--radius: 10px;
--shadow: 0 1px 2px rgba(16, 27, 51, 0.06), 0 8px 24px rgba(16, 27, 51, 0.07);
}
* {
box-sizing: border-box;
}
html {
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
font-family: var(--sans);
color: var(--ink);
background: var(--bg);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
.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: 920px;
margin: 0 auto;
padding: 32px 22px 56px;
}
/* ---------- Masthead ---------- */
.masthead {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 24px;
flex-wrap: wrap;
padding-bottom: 18px;
border-bottom: 2px solid var(--navy);
}
.masthead__brand {
display: flex;
align-items: center;
gap: 14px;
}
.masthead__mark {
flex: none;
width: 52px;
height: 52px;
display: grid;
place-items: center;
background: var(--navy);
color: var(--gold-soft);
font-family: var(--serif);
font-size: 17px;
letter-spacing: 0.5px;
border-radius: 8px;
border: 1px solid var(--gold);
}
.masthead__firm {
margin: 0;
font-size: 12px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--gold);
font-weight: 600;
}
.masthead__title {
margin: 2px 0 0;
font-family: var(--serif);
font-weight: 600;
font-size: 27px;
color: var(--navy-d);
letter-spacing: -0.01em;
}
.masthead__stats {
display: flex;
gap: 28px;
margin: 0;
}
.masthead__stats div {
text-align: right;
}
.masthead__stats dt {
font-size: 11px;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--muted);
}
.masthead__stats dd {
margin: 2px 0 0;
font-family: var(--serif);
font-size: 26px;
color: var(--navy);
}
/* ---------- Toolbar ---------- */
.toolbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
flex-wrap: wrap;
margin: 22px 0 18px;
}
.toolbar__filters {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.chip {
appearance: none;
font-family: var(--sans);
font-size: 13px;
color: var(--muted);
background: var(--white);
border: 1px solid var(--line);
border-radius: 999px;
padding: 7px 14px;
cursor: pointer;
transition: border-color 0.16s, color 0.16s, background 0.16s;
}
.chip:hover {
border-color: var(--gold);
color: var(--ink);
}
.chip--on {
background: var(--navy);
border-color: var(--navy);
color: var(--gold-soft);
}
.chip:focus-visible {
outline: 2px solid var(--gold);
outline-offset: 2px;
}
.toolbar__count {
margin: 0;
font-size: 13px;
color: var(--muted);
}
.toolbar__count span {
font-weight: 600;
color: var(--ink);
}
/* ---------- Docket ---------- */
.docket {
list-style: none;
margin: 0;
padding: 0;
display: grid;
gap: 16px;
}
.matter {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--radius);
box-shadow: var(--shadow);
padding: 18px 20px 20px;
position: relative;
overflow: hidden;
}
.matter::before {
content: "";
position: absolute;
inset: 0 auto 0 0;
width: 3px;
background: var(--gold);
}
.matter__top {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 16px;
flex-wrap: wrap;
}
.matter__no {
margin: 0;
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--gold);
font-weight: 600;
}
.matter__name {
margin: 3px 0 0;
font-family: var(--serif);
font-size: 19px;
color: var(--navy-d);
}
.matter__area {
margin: 4px 0 0;
font-size: 13px;
color: var(--muted);
}
.badge {
flex: none;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.04em;
padding: 4px 10px;
border-radius: 999px;
border: 1px solid transparent;
white-space: nowrap;
}
.badge--due {
background: #fbf1e1;
color: var(--warn);
border-color: #ecd6ad;
}
.badge--ok {
background: #e7f1ea;
color: var(--ok);
border-color: #c6e0d0;
}
.badge--closed {
background: #eceef2;
color: var(--muted);
border-color: var(--line);
}
/* ---------- Stepper ---------- */
.stepper {
display: flex;
margin: 18px 0 16px;
padding: 0;
list-style: none;
counter-reset: step;
}
.stepper li {
flex: 1;
position: relative;
text-align: center;
font-size: 11px;
color: var(--muted);
letter-spacing: 0.02em;
padding-top: 26px;
min-width: 0;
}
.stepper li::before {
counter-increment: step;
content: counter(step);
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 18px;
height: 18px;
border-radius: 50%;
background: var(--white);
border: 1.5px solid var(--line);
color: var(--muted);
font-weight: 600;
font-size: 10px;
line-height: 15px;
z-index: 2;
}
.stepper li::after {
content: "";
position: absolute;
top: 8px;
left: -50%;
width: 100%;
height: 1.5px;
background: var(--line);
z-index: 1;
}
.stepper li:first-child::after {
display: none;
}
.stepper li span {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.stepper li.done::before {
background: var(--gold);
border-color: var(--gold);
color: var(--white);
content: "✓";
}
.stepper li.done::after,
.stepper li.current::after {
background: var(--gold);
}
.stepper li.done span {
color: var(--ink);
}
.stepper li.current::before {
background: var(--navy);
border-color: var(--navy);
color: var(--gold-soft);
box-shadow: 0 0 0 4px rgba(27, 42, 74, 0.12);
animation: pulse 2.2s ease-in-out infinite;
}
.stepper li.current span {
color: var(--navy);
font-weight: 600;
}
@keyframes pulse {
0%,
100% {
box-shadow: 0 0 0 4px rgba(27, 42, 74, 0.12);
}
50% {
box-shadow: 0 0 0 7px rgba(27, 42, 74, 0.05);
}
}
/* ---------- Matter footer ---------- */
.matter__foot {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
flex-wrap: wrap;
padding-top: 14px;
border-top: 1px solid var(--line-soft);
}
.matter__person {
display: flex;
align-items: center;
gap: 10px;
}
.avatar {
flex: none;
width: 32px;
height: 32px;
border-radius: 50%;
display: grid;
place-items: center;
background: var(--gold-soft);
color: var(--navy);
font-size: 12px;
font-weight: 600;
}
.matter__person small {
display: block;
color: var(--muted);
font-size: 11px;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.matter__person strong {
font-weight: 600;
font-size: 14px;
color: var(--ink);
}
.matter__view {
appearance: none;
font-family: var(--sans);
font-size: 13px;
font-weight: 600;
color: var(--navy);
background: transparent;
border: 1px solid var(--navy);
border-radius: 7px;
padding: 8px 16px;
cursor: pointer;
transition: background 0.16s, color 0.16s;
}
.matter__view:hover {
background: var(--navy);
color: var(--gold-soft);
}
.matter__view:focus-visible {
outline: 2px solid var(--gold);
outline-offset: 2px;
}
.docket__empty {
text-align: center;
color: var(--muted);
font-style: italic;
padding: 40px 0;
}
/* ---------- Footnote ---------- */
.footnote {
margin-top: 34px;
font-size: 12px;
color: var(--muted);
text-align: center;
letter-spacing: 0.03em;
}
.footnote .rule {
display: block;
width: 64px;
height: 1px;
background: var(--gold);
margin: 0 auto 12px;
}
/* ---------- Drawer ---------- */
.drawer {
position: fixed;
inset: 0;
visibility: hidden;
z-index: 40;
}
.drawer.open {
visibility: visible;
}
.drawer__backdrop {
position: absolute;
inset: 0;
background: rgba(16, 27, 51, 0.45);
opacity: 0;
transition: opacity 0.25s ease;
}
.drawer.open .drawer__backdrop {
opacity: 1;
}
.drawer__panel {
position: absolute;
top: 0;
right: 0;
height: 100%;
width: min(440px, 92vw);
background: var(--bg);
box-shadow: -12px 0 40px rgba(16, 27, 51, 0.25);
transform: translateX(100%);
transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
overflow-y: auto;
padding: 24px 26px 36px;
}
.drawer.open .drawer__panel {
transform: translateX(0);
}
.drawer__head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
padding-bottom: 16px;
border-bottom: 2px solid var(--navy);
}
.drawer__matterno {
margin: 0;
font-size: 11px;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--gold);
font-weight: 600;
}
.drawer__title {
margin: 4px 0 0;
font-family: var(--serif);
font-size: 22px;
color: var(--navy-d);
}
.drawer__close {
appearance: none;
flex: none;
width: 34px;
height: 34px;
border-radius: 50%;
border: 1px solid var(--line);
background: var(--white);
color: var(--muted);
font-size: 22px;
line-height: 1;
cursor: pointer;
transition: color 0.16s, border-color 0.16s;
}
.drawer__close:hover {
color: var(--navy);
border-color: var(--gold);
}
.drawer__close:focus-visible {
outline: 2px solid var(--gold);
outline-offset: 2px;
}
.drawer__meta {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 14px 18px;
margin: 18px 0 4px;
}
.drawer__meta dt {
font-size: 11px;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--muted);
}
.drawer__meta dd {
margin: 3px 0 0;
font-size: 14px;
color: var(--ink);
font-weight: 500;
}
.drawer__phase {
margin: 20px 0 6px;
}
.drawer__phase .stepper {
margin: 0;
}
.drawer__sub {
font-family: var(--serif);
font-size: 16px;
color: var(--navy-d);
margin: 26px 0 14px;
padding-bottom: 8px;
border-bottom: 1px solid var(--gold);
}
/* ---------- Timeline ---------- */
.timeline {
list-style: none;
margin: 0;
padding: 0 0 0 18px;
position: relative;
}
.timeline::before {
content: "";
position: absolute;
left: 4px;
top: 4px;
bottom: 4px;
width: 1.5px;
background: var(--line);
}
.timeline li {
position: relative;
padding: 0 0 18px 18px;
}
.timeline li:last-child {
padding-bottom: 0;
}
.timeline li::before {
content: "";
position: absolute;
left: -18px;
top: 4px;
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--white);
border: 2px solid var(--gold);
}
.timeline li.event--key::before {
background: var(--gold);
}
.timeline time {
display: block;
font-size: 11px;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--gold);
font-weight: 600;
}
.timeline strong {
display: block;
font-size: 14px;
color: var(--ink);
margin: 2px 0 1px;
}
.timeline p {
margin: 0;
font-size: 13px;
color: var(--muted);
}
/* ---------- Responsive ---------- */
@media (max-width: 520px) {
.shell {
padding: 22px 14px 44px;
}
.masthead {
align-items: flex-start;
}
.masthead__stats {
gap: 20px;
}
.masthead__stats div {
text-align: left;
}
.masthead__title {
font-size: 22px;
}
.stepper li span {
font-size: 0;
}
.stepper li::before {
font-size: 10px;
}
.matter__foot {
align-items: flex-start;
}
.matter__view {
width: 100%;
text-align: center;
}
.drawer__meta {
grid-template-columns: 1fr;
gap: 12px;
}
}(function () {
"use strict";
var PHASES = ["Intake", "Discovery", "Negotiation", "Trial", "Closed"];
var MATTERS = [
{
no: "2026-CV-0481",
name: "Vance Robotics v. Nexa Systems",
area: "Commercial Litigation · Trade Secrets",
phase: "Discovery",
attorney: "Dana Calloway",
role: "Lead Counsel",
deadline: "Jun 30, 2026",
deadlineLabel: "Document production due",
due: true,
client: "Vance Robotics, Inc.",
court: "N.D. Cal., Hon. P. Ruiz",
opened: "Feb 11, 2026",
timeline: [
{ date: "Feb 11", title: "Complaint filed", note: "Filed in N.D. Cal.; jury demand included.", key: true },
{ date: "Mar 04", title: "Answer & counterclaims served", note: "Nexa asserted two counterclaims." },
{ date: "Apr 22", title: "Rule 26(f) conference", note: "Discovery plan submitted to the court." },
{ date: "Jun 09", title: "First set of interrogatories", note: "Served 18 interrogatories on defendant.", key: true },
{ date: "Jun 30", title: "Document production due", note: "Outstanding — paralegal preparing privilege log." }
]
},
{
no: "2026-FAM-0337",
name: "Estate of Harriet Lindqvist",
area: "Estate Planning · Probate",
phase: "Negotiation",
attorney: "Marcus Reed",
role: "Partner",
deadline: "Jul 14, 2026",
deadlineLabel: "Mediation session",
due: false,
client: "Lindqvist Family Trust",
court: "Probate Div., Hon. A. Bell",
opened: "Jan 28, 2026",
timeline: [
{ date: "Jan 28", title: "Petition for probate", note: "Will admitted; executor appointed.", key: true },
{ date: "Mar 16", title: "Heir notification", note: "Statutory notice mailed to four beneficiaries." },
{ date: "May 02", title: "Asset inventory filed", note: "Appraisal of real property completed." },
{ date: "Jul 14", title: "Mediation session", note: "Scheduled to resolve distribution dispute." }
]
},
{
no: "2026-CV-0512",
name: "Okafor v. Brightline Freight Co.",
area: "Personal Injury · Negligence",
phase: "Trial",
attorney: "Priya Anand",
role: "Trial Counsel",
deadline: "Jun 26, 2026",
deadlineLabel: "Pre-trial conference",
due: true,
client: "Daniel Okafor",
court: "Superior Ct., Hon. R. Tan",
opened: "Sep 09, 2025",
timeline: [
{ date: "Sep 09 '25", title: "Claim opened", note: "Intake interview and medical records request." },
{ date: "Nov 20 '25", title: "Demand letter sent", note: "Settlement demand rejected by insurer." },
{ date: "Feb 18", title: "Depositions completed", note: "Defendant driver and two witnesses deposed.", key: true },
{ date: "May 30", title: "Expert reports exchanged", note: "Biomechanical and economic experts disclosed." },
{ date: "Jun 26", title: "Pre-trial conference", note: "Jury instructions and exhibit list to be finalized.", key: true }
]
},
{
no: "2026-CORP-0190",
name: "Meridian Labs — Series B Financing",
area: "Corporate · Venture Finance",
phase: "Intake",
attorney: "Dana Calloway",
role: "Lead Counsel",
deadline: "Jul 02, 2026",
deadlineLabel: "Term sheet review",
due: false,
client: "Meridian Labs, Inc.",
court: "Transactional (no court)",
opened: "Jun 15, 2026",
timeline: [
{ date: "Jun 15", title: "Engagement signed", note: "Conflict check cleared; matter opened.", key: true },
{ date: "Jun 19", title: "Cap table reviewed", note: "Existing convertible notes catalogued." },
{ date: "Jul 02", title: "Term sheet review", note: "Lead investor term sheet under negotiation." }
]
},
{
no: "2025-CV-0904",
name: "Sandoval v. Cedar Ridge HOA",
area: "Real Property · Easement",
phase: "Closed",
attorney: "Marcus Reed",
role: "Partner",
deadline: "May 19, 2026",
deadlineLabel: "Matter closed",
due: false,
client: "Elena Sandoval",
court: "Superior Ct., Hon. K. Owens",
opened: "Mar 03, 2025",
timeline: [
{ date: "Mar 03 '25", title: "Complaint filed", note: "Sought declaratory relief on easement.", key: true },
{ date: "Oct 11 '25", title: "Summary judgment granted", note: "Court ruled easement enforceable." },
{ date: "Apr 30", title: "Settlement executed", note: "HOA agreed to recorded access terms." },
{ date: "May 19", title: "Matter closed", note: "File archived; final invoice issued.", key: true }
]
},
{
no: "2026-EMP-0273",
name: "Tran v. Hollis Marketing Group",
area: "Employment · Wrongful Termination",
phase: "Discovery",
attorney: "Priya Anand",
role: "Associate",
deadline: "Jul 09, 2026",
deadlineLabel: "Deposition of plaintiff",
due: false,
client: "Kevin Tran",
court: "Superior Ct., Hon. J. Mercer",
opened: "Apr 07, 2026",
timeline: [
{ date: "Apr 07", title: "EEOC right-to-sue received", note: "Complaint filed within 90-day window.", key: true },
{ date: "May 12", title: "Answer filed", note: "Defendant denied retaliation allegations." },
{ date: "Jun 18", title: "Written discovery served", note: "Requests for production exchanged." },
{ date: "Jul 09", title: "Deposition of plaintiff", note: "Noticed by defense counsel." }
]
}
];
var docket = document.getElementById("docket");
var emptyEl = document.getElementById("empty");
var visibleCountEl = document.getElementById("visibleCount");
var chips = Array.prototype.slice.call(document.querySelectorAll(".chip"));
/* ---- helpers ---- */
function initials(name) {
return name
.split(" ")
.map(function (p) {
return p.charAt(0);
})
.join("")
.slice(0, 2)
.toUpperCase();
}
function stepperMarkup(currentPhase) {
var idx = PHASES.indexOf(currentPhase);
var items = PHASES.map(function (phase, i) {
var cls = i < idx ? "done" : i === idx ? "current" : "";
// Closed matters: mark every prior phase done and Closed as current.
return '<li class="' + cls + '"><span>' + phase + "</span></li>";
}).join("");
return '<ol class="stepper" aria-label="Case phase">' + items + "</ol>";
}
function phaseBadge(m) {
if (m.phase === "Closed") {
return '<span class="badge badge--closed">Closed</span>';
}
if (m.due) {
return '<span class="badge badge--due">Due ' + m.deadline + "</span>";
}
return '<span class="badge badge--ok">On track</span>';
}
/* ---- render cards ---- */
function renderCards() {
docket.innerHTML = MATTERS.map(function (m, i) {
return (
'<li class="matter" data-phase="' +
m.phase +
'">' +
'<div class="matter__top">' +
"<div>" +
'<p class="matter__no">Matter ' +
m.no +
"</p>" +
'<h3 class="matter__name">' +
m.name +
"</h3>" +
'<p class="matter__area">' +
m.area +
"</p>" +
"</div>" +
phaseBadge(m) +
"</div>" +
stepperMarkup(m.phase) +
'<div class="matter__foot">' +
'<div class="matter__person">' +
'<span class="avatar" aria-hidden="true">' +
initials(m.attorney) +
"</span>" +
"<span>" +
"<small>" +
m.role +
"</small>" +
"<strong>" +
m.attorney +
"</strong>" +
"</span>" +
"</div>" +
'<button class="matter__view" type="button" data-open="' +
i +
'">View matter</button>' +
"</div>" +
"</li>"
);
}).join("");
}
/* ---- filtering ---- */
function applyFilter(filter) {
var cards = docket.querySelectorAll(".matter");
var visible = 0;
cards.forEach(function (card) {
var show = filter === "all" || card.getAttribute("data-phase") === filter;
card.hidden = !show;
if (show) visible++;
});
visibleCountEl.textContent = visible;
emptyEl.hidden = visible !== 0;
}
chips.forEach(function (chip) {
chip.addEventListener("click", function () {
chips.forEach(function (c) {
c.classList.remove("chip--on");
c.setAttribute("aria-pressed", "false");
});
chip.classList.add("chip--on");
chip.setAttribute("aria-pressed", "true");
applyFilter(chip.getAttribute("data-filter"));
});
});
/* ---- drawer ---- */
var drawer = document.getElementById("drawer");
var panel = drawer.querySelector(".drawer__panel");
var lastFocused = null;
function openDrawer(index) {
var m = MATTERS[index];
if (!m) return;
lastFocused = document.activeElement;
document.getElementById("drawerNo").textContent = "Matter " + m.no;
document.getElementById("drawerTitle").textContent = m.name;
document.getElementById("drawerMeta").innerHTML =
"<div><dt>Client</dt><dd>" +
m.client +
"</dd></div>" +
"<div><dt>Practice area</dt><dd>" +
m.area +
"</dd></div>" +
"<div><dt>Assigned attorney</dt><dd>" +
m.attorney +
"</dd></div>" +
"<div><dt>Venue</dt><dd>" +
m.court +
"</dd></div>" +
"<div><dt>Opened</dt><dd>" +
m.opened +
"</dd></div>" +
"<div><dt>Next deadline</dt><dd>" +
m.deadlineLabel +
" — " +
m.deadline +
"</dd></div>";
document.getElementById("drawerPhase").innerHTML = stepperMarkup(m.phase);
document.getElementById("timeline").innerHTML = m.timeline
.map(function (ev) {
return (
'<li class="' +
(ev.key ? "event--key" : "") +
'">' +
"<time>" +
ev.date +
"</time>" +
"<strong>" +
ev.title +
"</strong>" +
"<p>" +
ev.note +
"</p>" +
"</li>"
);
})
.join("");
drawer.classList.add("open");
drawer.setAttribute("aria-hidden", "false");
panel.focus();
}
function closeDrawer() {
if (!drawer.classList.contains("open")) return;
drawer.classList.remove("open");
drawer.setAttribute("aria-hidden", "true");
if (lastFocused && typeof lastFocused.focus === "function") {
lastFocused.focus();
}
}
docket.addEventListener("click", function (e) {
var btn = e.target.closest("[data-open]");
if (btn) openDrawer(parseInt(btn.getAttribute("data-open"), 10));
});
drawer.addEventListener("click", function (e) {
if (e.target.closest("[data-close]")) closeDrawer();
});
document.addEventListener("keydown", function (e) {
if (e.key === "Escape") closeDrawer();
});
/* ---- boot ---- */
renderCards();
applyFilter("all");
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Case / Matter Tracker — Calloway & Reed LLP</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="shell">
<header class="masthead">
<div class="masthead__brand">
<span class="masthead__mark" aria-hidden="true">C&R</span>
<div>
<p class="masthead__firm">Calloway & Reed LLP</p>
<h1 class="masthead__title">Case & Matter Tracker</h1>
</div>
</div>
<dl class="masthead__stats">
<div>
<dt>Open matters</dt>
<dd id="statOpen">6</dd>
</div>
<div>
<dt>Due this week</dt>
<dd id="statDue">3</dd>
</div>
</dl>
</header>
<section class="toolbar" aria-label="Filter matters">
<div class="toolbar__filters" role="group" aria-label="Filter by phase">
<button class="chip chip--on" type="button" data-filter="all" aria-pressed="true">All phases</button>
<button class="chip" type="button" data-filter="Intake" aria-pressed="false">Intake</button>
<button class="chip" type="button" data-filter="Discovery" aria-pressed="false">Discovery</button>
<button class="chip" type="button" data-filter="Negotiation" aria-pressed="false">Negotiation</button>
<button class="chip" type="button" data-filter="Trial" aria-pressed="false">Trial</button>
<button class="chip" type="button" data-filter="Closed" aria-pressed="false">Closed</button>
</div>
<p class="toolbar__count"><span id="visibleCount">6</span> matters shown</p>
</section>
<main>
<h2 class="sr-only">Active matters</h2>
<ul class="docket" id="docket"><!-- matter cards injected by script.js --></ul>
<p class="docket__empty" id="empty" hidden>No matters in this phase.</p>
</main>
<footer class="footnote">
<span class="rule" aria-hidden="true"></span>
Privileged & confidential — attorney work product. Illustrative demo only.
</footer>
</div>
<!-- Detail drawer -->
<div class="drawer" id="drawer" aria-hidden="true">
<div class="drawer__backdrop" data-close></div>
<aside
class="drawer__panel"
role="dialog"
aria-modal="true"
aria-labelledby="drawerTitle"
tabindex="-1"
>
<header class="drawer__head">
<div>
<p class="drawer__matterno" id="drawerNo">—</p>
<h2 class="drawer__title" id="drawerTitle">Matter</h2>
</div>
<button class="drawer__close" type="button" data-close aria-label="Close matter detail">×</button>
</header>
<dl class="drawer__meta" id="drawerMeta"><!-- meta injected --></dl>
<div class="drawer__phase" id="drawerPhase"><!-- mini stepper injected --></div>
<h3 class="drawer__sub">Timeline of events</h3>
<ol class="timeline" id="timeline"><!-- timeline injected --></ol>
</aside>
</div>
<script src="script.js"></script>
</body>
</html>Case / Matter Tracker
An authoritative, trust-first dashboard for the legal vertical. Each active matter is rendered as a card carrying its client, practice area, assigned attorney, next deadline and a horizontal status stepper that walks a case through Intake → Discovery → Negotiation → Trial → Closed. Completed phases are filled in gold, the current phase pulses, and upcoming phases stay muted.
A filter bar above the list lets you narrow the docket by phase and shows a live count of visible matters. Selecting View matter opens a slide-in detail drawer that presents the full matter header alongside a vertical timeline of events — filings, hearings, depositions and client calls — each with a date and short note. The drawer closes on the close button, the backdrop or the Escape key, and focus is returned to the triggering card.
Everything is plain HTML, CSS custom properties and vanilla JavaScript — no frameworks, no build step. The serif headings, navy chrome and thin gold rules give it the considered, paper-on-desk feel of an established practice.
Illustrative UI only — not legal advice and not intended for real case management.