/* cveboard. Direction: "Line status board" (impeccable, seed:3a85f752079c93a3).
   The three sources run as lines on a status board: enamel navy, one colour per line, Fira Sans. */

@font-face { font-family: "Fira Sans"; src: url("/fonts/fira-sans-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Fira Sans"; src: url("/fonts/fira-sans-600.woff2") format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Fira Sans"; src: url("/fonts/fira-sans-800.woff2") format("woff2"); font-weight: 800; font-display: swap; }

:root {
	--ground: #ffffff;
	--ink: #0b1f4b;
	--muted: #46557a;
	--rule: #d8deea;
	--field: #eef1f7;
	--underline: rgb(11 31 75 / 0.35);
	--panel: #0b1f4b;
	--panel-ink: #ffffff;
	--panel-muted: #c5cde3;
	--panel-edge: #22397a;
	--focus: #0b1f4b;

	/* The lines. Each colour names one source; yellow also marks focus, selection and hover. */
	--red: #e1251b;
	--on-red: #ffffff;
	--yellow: #f8c300;
	--on-yellow: #0b1f4b;
	--green: #00843d;
	--on-green: #ffffff;

	--display: clamp(2.5rem, 1.5rem + 3.4vw, 4.25rem);
	--head: clamp(1.5rem, 1.2rem + 1vw, 2.125rem);
	--lead: clamp(1.1875rem, 1.1rem + 0.35vw, 1.375rem);
	--body: 1.0625rem;
	--small: 0.9375rem;

	--margin: clamp(16px, 3vw, 40px);
	--gutter: max(var(--margin), calc((100% - 1360px) / 2));
	--section: clamp(72px, 9vw, 128px);
	--ease: cubic-bezier(0.16, 1, 0.3, 1);
	color-scheme: light;
}

/* Dark: the same board at night. The system decides unless the reader picked a theme (prefs.js). */
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) {
		--ground: #0a142e;
		--ink: #e8ecf6;
		--muted: #a8b2cc;
		--rule: #24345f;
		--field: #16264f;
		--underline: rgb(232 236 246 / 0.4);
		--panel: #14244f;
		--panel-muted: #b9c3dd;
		--panel-edge: #2a4080;
		--focus: #f8c300;
		color-scheme: dark;
	}
}
:root[data-theme="dark"] {
	--ground: #0a142e;
	--ink: #e8ecf6;
	--muted: #a8b2cc;
	--rule: #24345f;
	--field: #16264f;
	--underline: rgb(232 236 246 / 0.4);
	--panel: #14244f;
	--panel-muted: #b9c3dd;
	--panel-edge: #2a4080;
	--focus: #f8c300;
	color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scrollbar-color: var(--muted) var(--ground); }
body {
	margin: 0;
	background: var(--ground);
	color: var(--ink);
	font-family: "Fira Sans", "Segoe UI", system-ui, sans-serif;
	font-size: var(--body);
	line-height: 1.55;
	font-variant-numeric: tabular-nums;
	overflow-x: clip;
}
h1, h2, h3, p, ol, ul, dl, dd, figure { margin: 0; }
p, li, dd { text-wrap: pretty; }
ol, ul { padding: 0; list-style: none; }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.22em; text-decoration-color: var(--underline); }
a:hover { text-decoration-color: currentColor; text-decoration-thickness: 2px; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: 2px; }
::selection { background: var(--yellow); color: var(--on-yellow); }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip { position: absolute; left: var(--margin); top: -100px; z-index: 10; background: var(--yellow); color: var(--on-yellow); padding: 10px 14px; font-weight: 600; }
.skip:focus { top: 8px; }

.button {
	display: inline-flex; align-items: center; min-height: 44px; padding: 0 18px;
	background: var(--ink); color: var(--ground); border: 0; border-radius: 4px;
	font: inherit; font-weight: 600; text-decoration: none; cursor: pointer;
	transition: background-color 160ms var(--ease);
}

/* The navy panels: masthead, board, notice head and footer. Focus turns yellow on them. */
.mast, .lines, .notice-head, .foot { background: var(--panel); color: var(--panel-ink); --focus: var(--yellow); --underline: rgb(255 255 255 / 0.4); }

.mast { display: flex; align-items: center; gap: clamp(16px, 2.4vw, 32px); min-height: 72px; padding: 12px var(--gutter); }
.wordmark { display: inline-flex; align-items: center; gap: 10px; font-size: var(--lead); font-weight: 800; letter-spacing: -0.01em; text-decoration: none; }
.mast nav { display: flex; gap: clamp(16px, 2vw, 28px); margin-left: auto; }
.mast nav a { text-decoration: none; }
.mast nav a:hover { text-decoration: underline; }
.mast .button { background: var(--panel-ink); color: var(--panel); }
.mast .button:hover { background: var(--yellow); color: var(--on-yellow); }
.theme { display: grid; place-items: center; width: 44px; height: 44px; padding: 0; background: transparent; color: inherit; border: 2px solid var(--panel-edge); border-radius: 4px; cursor: pointer; transition: border-color 160ms var(--ease); }
.theme[hidden] { display: none; }
.theme:hover { border-color: var(--panel-ink); }

/* The opening: the reader's question as the headline, the wire's own facts beside it. */
.list { padding: 0 var(--gutter); scroll-margin-top: 16px; }
.opening { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 24px 48px; align-items: end; padding: clamp(36px, 5vw, 72px) 0 clamp(24px, 3vw, 36px); }
.opening h1 { font-size: var(--display); font-weight: 800; line-height: 1.02; letter-spacing: -0.025em; text-wrap: balance; }
.opening-side { max-width: 52ch; }
.status { margin-top: 10px; color: var(--muted); font-size: var(--small); }

/* The board: one column per line, its colour bar on top. */
.lines { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-radius: 4px; overflow: hidden; }
.line { position: relative; padding: 36px 24px 24px; }
.line + .line { box-shadow: inset 2px 0 0 var(--panel-edge); }
.line::before { content: ""; position: absolute; inset: 0 0 auto; height: 14px; background: var(--line); transform-origin: left; }
.line-kev { --line: var(--red); }
.line-ghsa { --line: var(--yellow); }
.line-hibp { --line: var(--green); }
.line-name { font-size: var(--lead); font-weight: 800; letter-spacing: -0.01em; text-decoration: none; }
.line-name:hover { text-decoration: underline; }
.line-count { margin-top: 4px; color: var(--panel-muted); }
.line-count a { color: var(--panel-ink); }

/* The notices, by day. */
.list-body { padding-top: clamp(32px, 4vw, 48px); }
.filter-note { margin-bottom: 24px; color: var(--muted); font-size: var(--small); }
.filter-note a { color: var(--ink); }
.days > li + li { margin-top: 36px; }
.day-date { padding-bottom: 6px; font-size: var(--body); font-weight: 800; }
.day-date::first-letter { text-transform: uppercase; }
.row { display: grid; grid-template-columns: 9.5rem 11rem minmax(0, 1fr) auto; column-gap: 20px; align-items: center; min-height: 46px; padding: 5px 0; }
.tags { display: flex; flex-wrap: wrap; gap: 6px; }
.tag { display: inline-flex; align-items: center; min-height: 26px; padding: 0 8px; border-radius: 3px; background: var(--tag); color: var(--tag-ink); font-size: var(--small); font-weight: 600; line-height: 1; white-space: nowrap; }
.tag-kev { --tag: var(--red); --tag-ink: var(--on-red); }
.tag-ghsa { --tag: var(--yellow); --tag-ink: var(--on-yellow); }
.tag-hibp { --tag: var(--green); --tag-ink: var(--on-green); }
/* Withdrawn keeps its line but loses the fill, so the state never rests on colour alone. */
.tag.is-withdrawn { background: transparent; color: inherit; box-shadow: inset 0 0 0 2px var(--tag); }
.row-id { overflow: hidden; font-size: var(--small); font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
.row-title { overflow-wrap: anywhere; }
/* A breach has no id: its title takes the id column instead of leaving a hole. */
.row-id:empty { display: none; }
.row-id:empty + .row-title { grid-column: span 2; }
.row-value { color: var(--muted); font-size: var(--small); text-align: right; white-space: nowrap; }
.older { margin-top: 48px; }
.empty { max-width: 40rem; font-size: var(--lead); }

/* Every half hour: one run of the cron as a strip map, each segment as long as its stage. */
.how { padding: var(--section) var(--gutter) 0; }
.how h2, .agents-statement { font-size: var(--head); font-weight: 800; line-height: 1.2; letter-spacing: -0.015em; }
.route { position: relative; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 40px; }
.stop { position: relative; display: grid; align-content: start; gap: 6px; padding: 52px 28px 0 0; }
.stop::before { content: ""; position: absolute; top: 14px; left: 0; right: 0; height: 10px; background: var(--ink); }
.stop::after, .route::after { content: ""; position: absolute; top: 5px; left: 0; width: 28px; height: 28px; border-radius: 50%; background: var(--ground); box-shadow: inset 0 0 0 6px var(--ink); }
.route::after { left: auto; right: 0; }
.stop-duration { font-size: var(--lead); font-weight: 800; }
.stop-clause { max-width: 36ch; }

/* For agents: one sentence with the controls set in it. */
.agents { padding: var(--section) var(--gutter); }
.agents-statement { max-width: 46ch; }
.slot { display: inline-flex; align-items: center; padding: 0 0.3em; border: 2px solid var(--ink); border-radius: 4px; background: var(--field); text-decoration: none; transition: background-color 160ms var(--ease); }
.slot:hover, .slot:focus-within { background: var(--rule); }
.slot-control { position: relative; }
/* A drawn chevron: the CSP allows no data: images, and a text glyph is not an icon. */
.slot-control::after { content: ""; position: absolute; right: 0.35em; width: 0.5em; height: 0.3em; background: currentColor; clip-path: polygon(0 0, 100% 0, 50% 100%); pointer-events: none; }
.slot select { padding: 0 1.1em 0 0; background: transparent; color: inherit; border: 0; font: inherit; cursor: pointer; appearance: none; }
.slot select option { background: var(--ground); color: var(--ink); }
.agents-support { display: grid; justify-items: start; gap: 18px; max-width: 46rem; margin-top: 40px; }
.check { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; cursor: pointer; }
.check input { width: 20px; height: 20px; accent-color: var(--ink); }
.endpoints { display: grid; gap: 10px; width: 100%; }
.endpoints div { display: grid; grid-template-columns: 5.5rem minmax(0, 1fr); gap: 12px; align-items: baseline; }
.endpoints dt { color: var(--muted); font-size: var(--small); font-weight: 600; }
.endpoints dd { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.endpoints a { font-size: var(--small); overflow-wrap: anywhere; }
.copy { flex: none; min-height: 36px; padding: 0 12px; background: var(--field); color: var(--ink); border: 0; border-radius: 4px; font: inherit; font-size: var(--small); font-weight: 600; cursor: pointer; transition: background-color 160ms var(--ease); }
.copy:hover { background: var(--rule); }
.js [data-apply] { display: none; }
html:not(.js) .copy { display: none; }

/* Footer: the three lines run out to the end of the page. */
.foot-lines { display: grid; grid-template-columns: repeat(3, 1fr); height: 10px; }
.bar-kev { background: var(--red); }
.bar-ghsa { background: var(--yellow); }
.bar-hibp { background: var(--green); }
.bar-none { background: var(--panel-edge); }
.foot-grid { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: 28px 48px; padding: 48px var(--gutter) 32px; color: var(--panel-muted); font-size: var(--small); }
.foot-notes { display: grid; gap: 8px; max-width: 68ch; }
.foot-word { color: var(--panel-ink); font-size: var(--lead); font-weight: 800; }
.foot a { color: var(--panel-ink); }
.foot-links { display: grid; align-content: start; justify-items: start; gap: 6px; }
.foot-made { grid-column: 1 / -1; }

/* Incident page: a notice posted on its line, the evidence below it. */
.notice { padding: clamp(24px, 3vw, 40px) var(--gutter) var(--section); }
.notice-head { --pad: clamp(20px, 3vw, 40px); padding: 0 var(--pad) clamp(24px, 3vw, 36px); border-radius: 4px; overflow: hidden; }
.notice-bar { display: flex; height: 14px; margin: 0 calc(-1 * var(--pad)) clamp(20px, 3vw, 32px); }
.notice-bar span { flex: 1; }
.notice-name { font-size: var(--display); font-weight: 800; line-height: 1; letter-spacing: -0.025em; overflow-wrap: anywhere; }
.notice-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 16px; }
.notice-kind { color: var(--panel-muted); }
.notice-title { max-width: 60ch; margin-top: 16px; font-size: var(--lead); line-height: 1.4; }
.notice-body { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); gap: 56px; margin-top: 48px; }
.note { margin-bottom: 16px; color: var(--muted); font-size: var(--small); }
.notice-summary { max-width: 65ch; line-height: 1.6; }
.facts { display: grid; max-width: 65ch; margin-top: 32px; }
.facts div { display: grid; grid-template-columns: 13rem minmax(0, 1fr); gap: 4px 20px; padding: 12px 0; box-shadow: inset 0 -1px 0 var(--rule); }
.facts dt { font-weight: 600; }
.packages li + li { margin-top: 6px; }
.notice-side h2 { margin: 32px 0 14px; font-size: var(--body); font-weight: 800; }
.notice-side h2:first-child { margin-top: 0; }
/* The timeline is the same strip map, run downwards: one stop per source event. */
.timeline { position: relative; display: grid; gap: 20px; padding-left: 40px; }
.timeline::before { content: ""; position: absolute; top: 8px; bottom: 8px; left: 9px; width: 6px; background: var(--ink); }
.timeline li { position: relative; }
.timeline li::before { content: ""; position: absolute; top: 1px; left: -40px; width: 24px; height: 24px; border-radius: 50%; background: var(--ground); box-shadow: inset 0 0 0 5px var(--ink); }
.timeline time { display: block; font-weight: 600; }
.sources li + li { margin-top: 6px; }
.notice-links { display: flex; flex-wrap: wrap; gap: 8px 20px; margin-top: 28px; }
.notice-back { margin-top: 28px; }

/* Motion: the line bars draw in once when the board arrives. Nothing else moves. */
@media (prefers-reduced-motion: no-preference) {
	html { scroll-behavior: smooth; }
	.line::before { animation: line-in 900ms var(--ease) both; }
	.line-ghsa::before { animation-delay: 120ms; }
	.line-hibp::before { animation-delay: 240ms; }
	@keyframes line-in { from { transform: scaleX(0); } }
}

@media (max-width: 1000px) {
	.opening, .notice-body { grid-template-columns: minmax(0, 1fr); }
	.notice-body { gap: 48px; }
	.row { grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "tags id value" "title title title"; row-gap: 4px; padding: 10px 0; }
	.tags { grid-area: tags; }
	.row-id { grid-area: id; }
	.row-value { grid-area: value; }
	.row-title, .row-id:empty + .row-title { grid-area: title; }
}
@media (width < 760px) {
	.mast { flex-wrap: wrap; row-gap: 4px; }
	.mast nav { order: 3; width: 100%; margin-left: 0; gap: 18px; padding-bottom: 4px; }
	.wordmark { margin-right: auto; }
	.lines { grid-template-columns: minmax(0, 1fr); }
	.line { padding: 30px 20px 18px; }
	.line + .line { box-shadow: inset 0 2px 0 var(--panel-edge); }
	.row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "tags value" "id id" "title title"; }
	.row-id { color: var(--muted); }
	/* On phones the sentence runs past two lines, so it reads as a paragraph, not a headline. */
	.agents-statement { font-size: var(--lead); font-weight: 400; line-height: 1.5; letter-spacing: 0; }
	.route { grid-template-columns: minmax(0, 1fr); padding-bottom: 28px; }
	.stop { padding: 0 0 32px 48px; }
	.stop::before { top: 0; bottom: 0; left: 9px; right: auto; width: 10px; height: auto; }
	.stop::after { top: 0; }
	.route::after { top: auto; right: auto; bottom: 0; left: 0; }
	.endpoints div { grid-template-columns: minmax(0, 1fr); gap: 4px; }
	.foot-grid { grid-template-columns: minmax(0, 1fr); }
	.facts div { grid-template-columns: minmax(0, 1fr); }
}
