Threat Shield
Inbound requests converging on a shield that scores every one, then fanning out to a card with the requests scored, a column chart of the last minutes stacked by verdict, and each verdict (allowed, challenged, blocked) counting up as pulses arrive.
Installation
The source for threat-shield comes with a Cortexcn Pro license, along with every other chart and the website templates. Pick a license on the pricing page.
Already have a license? Open the code
Usage
import { ThreatShield } from "@/components/threat-shield";<ThreatShield
title="Last 15 minutes"
verdicts={[
{ name: "Allowed", detail: "Passed every rule", count: 41870, tone: "accent" },
{ name: "Challenged", detail: "Asked to prove they're human", count: 1284, tone: "warning" },
{ name: "Blocked", detail: "Matched a rule", count: 362, tone: "destructive" },
]}
/>Each verdict gets a row with its count and share, and a band in every column of the chart. Use it on the page for a firewall, bot protection, rate limiting, or sign-in security, to show what reaches the app and what is stopped.
Examples
Sign-in checks
The same shield checking sign-in attempts over the last hour.
Static
With animated={false}, nothing moves and the counts stay as given.
Behavior
- While the flow is on screen, pulses run from the left into the shield, then on to each verdict. The counts count up from zero, then each verdict adds its
perPulseevery time a pulse reaches it, and the newest column of the chart grows as they arrive. tonecolors a verdict's marker, its band in the chart, and, for"destructive", its count."warning"and"destructive"use the theme's warning and destructive colors, so they follow light and dark mode.- The chart splits
title's window intocolumns. Each column's height is a steady variation on the verdicts' average, the same on every render. - With reduced motion enabled, or off screen, nothing moves and every count shows its given value.
- The whole flow is one SVG that scales to its container. It lays out at
minWidthor wider (560px by default); in a narrower container it scrolls sideways and takes keyboard focus. - Screen readers hear the total, then each verdict's count and share.
Props
ThreatShield
| Prop | Type | Default | Description |
|---|---|---|---|
verdicts | ThreatShieldVerdict[] | Three sample verdicts | The verdicts, in list and stacking order |
title | string | "Last 15 minutes" | The card's title, the window the numbers cover |
totalLabel | string | "Requests scored" | The label over the total |
columns | number | 15 | How many columns the chart splits title into |
shieldName | string | "Shield" | The name in the middle node |
shieldCaption | string | "Scores every request" | A line under the middle node |
sourceLabel | string | "Inbound requests" | The label over the incoming lines |
rateLabel | string | "requests a minute" | The words after the rate under the source label |
apiLabel | string | "Rules" | The label on the lines into the card |
note | string | "Blocked requests never reach your app." | A note at the foot of the card |
caption | string | "Illustrative numbers" | A small label in the bottom-left corner |
locale | string | "en-US" | The locale numbers are written in |
lines | number | 22 | How many lines of traffic come in from the left |
accent | string | "var(--foreground)" | Color of the pulses and of "accent" verdicts |
animated | boolean | true | Run the pulses and count up while on screen |
minWidth | number | 560 | Narrowest layout width in pixels; below it, scroll |
ariaLabel | string | "Threat shield" | Names the flow for screen readers |
className | string | - | Extra classes on the frame |
ThreatShieldVerdict
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | - | The verdict, such as "Blocked" |
detail | string | - | Why requests get it |
count | number | - | Requests that got it so far |
tone | "accent" | "warning" | "destructive" | "accent" | Its color |
perPulse | number | 1 | Requests added each time a pulse reaches it while live |