Static visual reference for the diagnostic report screen built in Phase 2.
The production React version uses Tailwind utilities; the visual hierarchy,
severity color usage, spacing, and information density shown here should be preserved.
The example scenario shown is the canonical fixture: a POST returning 401 with an expired JWT.
apidoctor — diagnostic report
2026-04-25 14:23 UTC
POST https://api.example.com/v1/users
401 Unauthorized
Latency
247 ms
Body
89 B
Protocol
HTTP/2
Findings
2 critical
Timing breakdown
DNS
12 ms
Connect
45 ms
TLS
78 ms
TTFB
95 ms
Download
17 ms
Findings
Bearer token has expiredCritical
The JWT in your Authorization header expired 3 hours ago. This is the most likely cause of the 401.
exp: 2026-04-25T11:23:00Z · expired 3h 0m ago
Suggested fix:
Refresh the token at /oauth/token and retry.
Authorization header has trailing whitespaceCritical
The Authorization value ends with a newline. Some servers reject this as a malformed header.
Authorization: Bearer eyJhbGc...XYZ\n
Suggested fix:
Trim the value before setting the header.
Missing strict-transport-security headerWarning
Response is missing HSTS. Not the cause of your 401, but a security gap worth reporting.
Suggested fix:
Add Strict-Transport-Security on the server.
Design notes
Decisions worth preserving when translating this layout to React + Tailwind:
Severity-first ordering. Findings are sorted critical → warning → info, not chronologically. A TSE doesn't care that the CORS issue was logged before the auth issue; they care which one is causing the ticket.
Title + evidence + fix. Every finding has three layers: a plain-language headline (for non-technical readers), structured raw evidence in monospace (for technical readers), and a suggested fix (for action). The evidence block is what differentiates this from a developer tool.
Semantic severity colors. Critical = red ramp (#fcebeb / #a32d2d). Warning = amber (#faeeda / #854f0b). Info = blue (#e6f1fb / #185fa5). Map these to the equivalent Tailwind red-50/red-700, amber-50/amber-700, blue-50/blue-700 or close equivalents — don't pick from a palette.
Information density. The report is dense but scannable. Don't add hero spacing or oversized headers — that's developer-tool-conventional but reads as wasted space to a TSE who scans 50 tickets a day.
Monospace for raw values. URLs, headers, timestamps, JWT claims, hex bodies — anything where exact characters matter goes in a monospace font. Plain prose stays in the sans-serif body font.
Evidence block is optional. Some findings (like the third one shown) don't need raw evidence — the title and explanation are enough. Don't force-fit empty evidence boxes when there's nothing to show.
Top-level metric cards (Latency / Body / Protocol / Findings) are the at-a-glance summary. Someone glancing at the report should know within one second whether this is a network problem, a payload problem, or a protocol problem. Keep them prominent.
Timing waterfall as a horizontal bar chart, one row per phase. Not a stacked single bar — stacked bars hide phases that are very small (like DNS). Per-row bars show every phase, even when one phase dominates the others.
Mobile responsiveness. The 4-column metrics grid should collapse to 2×2 below ~480px. The findings cards stack naturally. The timing rows already wrap fine.
Action buttons at the bottom. Share, re-run, and export. Share-by-URL becomes the marketing surface — every shared report is a marketing impression. Don't bury these.
The other Phase 2 surfaces — the request composer (URL/method/headers/body form) and the HAR upload page — don't have visual references yet. Mock them in the same visual style: white cards on a soft gray background, 0.5px borders, generous padding, sentence-case labels.