/* forge: the base stylesheet, light and dark, phone first: tokens, then
   layout, controls, lists and code views. CSS for one feature lives with
   its markup, in a template or include ({% css %}), and reaches only the
   pages that use it. The rules for all of it are in DESIGN.md, and
   lib/check-css.ts holds every stylesheet to them in CI.

   The look: a plain page with the chrome on it (header, tabs, toolbars) and
   the content in panels: raised, square, a hairline edge, an optional
   tinted head strip, rows between hairlines inside; Open Sans for the interface, Noto Sans Mono for what is
   copied or compared, Noto Serif for prose people wrote; hierarchy from
   weight, size and colour, never capitals or tracking; one accent
   (#3148F6) for links, the current tab's bar, focus and primary actions. */

/* == tokens == Every colour, size, weight and family is here; nothing
   below this block names one. The style guide (/design/) shows them. */
/* The fonts, self-hosted, variable in weight, cut to Latin and the symbols
   the pages print (fonts/make-fonts.sh). The sans is preloaded (base.njk). */
@font-face { font-family: "Open Sans"; src: url(./open-sans.tBAnd4FKWi.woff2) format("woff2"); font-weight: 300 800; font-style: normal; font-display: swap; }
@font-face { font-family: "Noto Sans Mono"; src: url(./noto-sans-mono.68oMzOn4Cg.woff2) format("woff2"); font-weight: 400 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Noto Serif"; src: url(./noto-serif.sm1oyiWhId.woff2) format("woff2"); font-weight: 400 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Noto Serif"; src: url(./noto-serif-italic.nl6S0SO_dk.woff2) format("woff2"); font-weight: 400 700; font-style: italic; font-display: swap; }
:root {
	/* colour: the page, panels raised over it with their tinted head strip
	   and a row's hover, ink in three strengths (muted keeps 4.5:1 on the
	   page and every surface, faint on a panel), rules, and the accent */
	--bg: #e9e9e9;
	--raised: #ffffff;
	--tint: #f6f6f6;
	--hover: #f2f3f5;
	--fg: #1c2127;
	--muted: #5b6169;
	--faint: #6f757d;
	--border: #d2d4d7;
	--border-strong: #a9aeb4;
	--link: #3148f6;
	--accent: #3148f6;
	--deep: #1c4b8f;
	--accent-hover: #1c4b8f;
	--on-accent: #ffffff;
	/* meaning: diffs, CI, warnings */
	--add-bg: rgba(14, 132, 32, 0.1);
	--add-fg: #0b7a1d;
	--add-ln: rgba(14, 132, 32, 0.2);
	--del-bg: rgba(199, 22, 43, 0.08);
	--del-fg: #c7162b;
	--del-ln: rgba(199, 22, 43, 0.17);
	--hunk-bg: rgba(49, 72, 246, 0.07);
	--hunk-fg: #1c4b8f;
	--pass: #0b7a1d;
	--fail: #c7162b;
	--warn: #965800;
	--merged: #3148f6;
	/* status labels: white on a fill, the same in both modes */
	--status-open: #0e8420;
	--status-merged: #3148f6;
	--status-closed: #c7162b;
	--status-other: #5b6169;
	/* avatars (lib/avatar.ts): bauhaus tiles drawn from a name, on a paper
	   ground with an ink and three accents; in dark mode the ground and ink
	   swap, so the art keeps its figure and ground */
	--avatar-ground: #eee8dc;
	--avatar-ink: #171717;
	--avatar-red: #c83b2e;
	--avatar-blue: #1e5484;
	--avatar-yellow: #dfb631;
	/* the activity grid (ui.activity): a day with nothing, then four steps
	   of the accent as the day gets busier */
	--heat-0: #e7e8eb;
	--heat-1: #c3cafd;
	--heat-2: #8796fa;
	--heat-3: #5468f7;
	--heat-4: #2a3fd6;
	/* languages on a repo's front matter: the three biggest, then the rest */
	--lang-1: #1e5484;
	--lang-2: #c83b2e;
	--lang-3: #dfb631;
	--lang-rest: #a9aeb4;
	/* a linked line, floating panels, dialogs' backdrop, masks */
	--target-bg: rgba(255, 213, 79, 0.25);
	--target-gut: rgba(255, 213, 79, 0.4);
	--shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
	--scrim: rgba(0, 0, 0, 0.3);
	--mask: #000;
	/* syntax highlighting (highlight.js classes) */
	--tok-comment: #59636e;
	--tok-keyword: #cf222e;
	--tok-string: #0a3069;
	--tok-const: #0550ae;
	--tok-title: #8250df;
	--tok-builtin: #953800;
	--tok-tag: #116329;
	/* charts (insights.ts): checked for colour-blind readers on both pages */
	--viz-1: #3148f6;
	--viz-fail: #c7162b;
	--viz-grid: #d9d9d9;
	--viz-axis: #a9aeb4;

	/* type: the interface, what is copied or compared, and prose */
	--sans: "Open Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
	--mono: "Noto Sans Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	--serif: "Noto Serif", Georgia, Cambria, "Times New Roman", serif;
	--text-xs: 12px;
	--text-code: 12.5px;
	--text-sm: 13.5px;
	--text-md: 15px;
	--text-prose: 16px;
	--text-lg: 18px;
	--text-xl: 22px;
	--text-2xl: 28px;
	/* mono inline in sans text runs large; this brings it level */
	--text-inline-mono: 0.9em;
	/* weights: body, links and controls, emphasis and headings */
	--fw-regular: 400;
	--fw-medium: 500;
	--fw-strong: 650;

	/* space: a 4px scale */
	--space-half: 2px;
	--space-1: 4px;
	--space-2: 8px;
	--space-3: 12px;
	--space-4: 16px;
	--space-5: 20px;
	--space-6: 24px;
	--space-8: 32px;
	--space-10: 40px;
	/* lines, corners and controls: rules are hairlines, the current tab's bar is thicker, nothing is rounded */
	--hairline: 1px;
	--bar: 3px;
	--radius: 0;
	--control-h: 30px;
	/* columns: a time in its own column is as wide as the widest compact
	   one, "Sep 24" or "40m", in the mono */
	--col-time: 6ch;
	color-scheme: light dark;
}
@media (prefers-color-scheme: dark) {
	:root {
		--bg: #08090b;
		--raised: #111418;
		--tint: #15191e;
		--hover: #191d23;
		--fg: #e2e4e7;
		--muted: #8f959d;
		--faint: #7d838b;
		--border: #252a31;
		--border-strong: #3a4048;
		--link: #8e9bff;
		--deep: #b4bcff;
		--accent-hover: #2a3ee0;
		--add-bg: rgba(79, 191, 95, 0.12);
		--add-fg: #4fbf5f;
		--add-ln: rgba(79, 191, 95, 0.24);
		--del-bg: rgba(240, 96, 110, 0.12);
		--del-fg: #f0606e;
		--del-ln: rgba(240, 96, 110, 0.24);
		--hunk-bg: rgba(142, 155, 255, 0.09);
		--hunk-fg: #8e9bff;
		--pass: #4fbf5f;
		--fail: #f0606e;
		--warn: #e3a33b;
		--merged: #8e9bff;
		--target-bg: rgba(255, 213, 79, 0.12);
		--target-gut: rgba(255, 213, 79, 0.22);
		--shadow: 0 8px 28px rgba(0, 0, 0, 0.7);
		--scrim: rgba(0, 0, 0, 0.6);
		--tok-comment: #8b929b;
		--tok-keyword: #ff7b72;
		--tok-string: #a5d6ff;
		--tok-const: #79c0ff;
		--tok-title: #d2a8ff;
		--tok-builtin: #ffa657;
		--tok-tag: #7ee787;
		--viz-1: #6f7fff;
		--viz-fail: #f0606e;
		--viz-grid: #1a1e23;
		--viz-axis: #3a4048;
		--avatar-ground: #2b2823;
		--avatar-ink: #ece6da;
		--avatar-red: #df5443;
		--avatar-blue: #5c8fd3;
		--avatar-yellow: #e4bb3d;
		--heat-0: #1b1f25;
		--heat-1: #232f73;
		--heat-2: #3046b8;
		--heat-3: #5a6ff2;
		--heat-4: #9aa6ff;
		--lang-1: #5c8fd3;
		--lang-2: #df5443;
		--lang-3: #e4bb3d;
		--lang-rest: #4a5058;
	}
}
/* == end tokens == */

*, ::before, ::after { box-sizing: border-box; border-radius: var(--radius); }
html { -webkit-text-size-adjust: 100%; }
/* hidden wins over a display a control's class gives it */
[hidden] { display: none !important; }
body { margin: 0; background: var(--bg); color: var(--fg); font: var(--fw-regular) var(--text-md)/1.5 var(--sans); }
a { color: var(--link); text-decoration: none; }
a:hover { color: var(--deep); text-decoration: underline; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
b, strong, th { font-weight: var(--fw-strong); }
code, kbd, pre, time, .mono, .sha { font-family: var(--mono); }
code, kbd, time, .sha, .mono { font-size: var(--text-inline-mono); }
.mono .sha, .mono time, .mono code, pre code { font-size: inherit; }
h1, h2, h3 { line-height: 1.25; font-weight: var(--fw-strong); }
/* Section headings on the page: sans, strong, over the panel they name; a
   count or note after them is quieter. A panel's own name goes in its head
   strip instead. */
h2 { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-1) var(--space-2); margin: var(--space-8) 0 var(--space-3); font-size: var(--text-md); color: var(--fg); }
h2 .desc, h2 .n { font-weight: var(--fw-regular); color: var(--faint); }
h2 .n { font: var(--fw-regular) var(--text-xs) var(--mono); font-variant-numeric: tabular-nums; }
h2 a { font-weight: var(--fw-medium); }
h3 { font-size: var(--text-md); margin: var(--space-6) 0 var(--space-2); }
.label { font-size: var(--text-sm); font-weight: var(--fw-medium); color: var(--muted); }
.desc, .muted { color: var(--muted); }
.i { color: var(--add-fg); }
.d { color: var(--del-fg); }
.wrap { max-width: 1280px; margin: 0 auto; padding: 0 var(--space-4); }
kbd { border: var(--hairline) solid var(--border-strong); padding: 0 var(--space-1); color: var(--muted); background: var(--raised); }
hr { border: 0; border-top: var(--hairline) solid var(--border); margin: var(--space-6) 0; }
svg.icon { display: inline-block; width: 16px; height: 16px; flex: none; vertical-align: -3px; }

/* header: on the page, over a rule that the current tab's bar sits on */
header.site { border-bottom: var(--hairline) solid var(--border); }
.top { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) 0 var(--space-2); min-width: 0; }
.logo { display: block; color: var(--fg); line-height: 0; flex: none; }
.mark { display: block; width: 28px; height: 28px; }
.title { font-size: var(--text-lg); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); }
.title a { color: var(--muted); }
.title a:hover { color: var(--deep); }
.title b, .title b a { font-weight: var(--fw-strong); color: var(--fg); }
.top .spacer { flex: 1; }
.repo-desc { margin: 0 0 var(--space-2); color: var(--muted); font-size: var(--text-sm); }

/* tabs: where you are. Words, the current one in ink on the accent bar. */
nav.tabs { display: flex; gap: var(--space-6); overflow-x: auto; scrollbar-width: none; font-size: var(--text-md); font-weight: var(--fw-medium); }
nav.tabs::-webkit-scrollbar { display: none; }
nav.tabs a { color: var(--muted); padding: var(--space-2) 0 var(--space-2); white-space: nowrap; }
nav.tabs a:hover { color: var(--fg); text-decoration: none; }
nav.tabs a.cur, nav.tabs a[aria-current="page"], nav.tabs a[aria-current="true"] { color: var(--fg); box-shadow: inset 0 calc(-1 * var(--bar)) 0 var(--accent); }
nav.tabs .n { margin-left: var(--space-1); font: var(--fw-regular) var(--text-xs) var(--mono); color: var(--faint); font-variant-numeric: tabular-nums; }
@media (max-width: 480px) {
	nav.tabs { gap: var(--space-4); }
}
/* Tabs that don't fit scroll sideways; the edge that has more fades out. */
@property --tabs-l { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --tabs-r { syntax: "<length>"; inherits: false; initial-value: 0px; }
@supports (animation-timeline: scroll()) {
	nav.tabs { mask-image: linear-gradient(to right, transparent, var(--mask) var(--tabs-l), var(--mask) calc(100% - var(--tabs-r)), transparent); animation: tabs-edge linear both; animation-timeline: scroll(self inline); }
	@keyframes tabs-edge { from { --tabs-l: 0px; --tabs-r: 32px; } to { --tabs-l: 32px; --tabs-r: 0px; } }
}

/* controls (ui.njk). Buttons do things: secondary is a raised surface,
   primary is filled with the accent. A toggle that is on is filled with
   ink: an icon toggle, or one segment of a segmented control. A checkbox
   is on/off with words. Links only navigate. */
button, .btn, details.clone > summary { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1); min-height: var(--control-h); font: var(--fw-medium) var(--text-sm)/1.2 var(--sans); color: var(--fg); background: var(--raised); border: var(--hairline) solid var(--border-strong); padding: var(--space-1) var(--space-3); cursor: pointer; white-space: nowrap; }
button:hover, .btn:hover { color: var(--fg); border-color: var(--muted); text-decoration: none; }
button.primary, details.clone > summary { color: var(--on-accent); background: var(--accent); border-color: var(--accent); }
button.primary:hover, details.clone > summary:hover, details.clone[open] > summary { color: var(--on-accent); background: var(--accent-hover); border-color: var(--accent-hover); }
button:disabled { opacity: 0.55; cursor: default; }
button kbd { padding: 0 var(--space-1); }
.icon-btn { width: var(--control-h); padding: 0; color: var(--muted); }
.icon-btn:hover { color: var(--fg); }
.icon-btn[aria-pressed="true"], .segmented > button[aria-pressed="true"] { color: var(--bg); background: var(--fg); border-color: var(--fg); }
.segmented { display: inline-flex; }
.segmented > button + button { margin-left: calc(-1 * var(--hairline)); }
.segmented > button[aria-pressed="true"] { position: relative; }
.check { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--control-h); font-size: var(--text-sm); color: var(--muted); cursor: pointer; user-select: none; -webkit-user-select: none; white-space: nowrap; }
.check:has(input:checked) { color: var(--fg); }
.check input { width: 15px; height: 15px; margin: 0; accent-color: var(--accent); }
.input, textarea.input { width: 100%; font: var(--fw-regular) var(--text-md)/1.5 var(--sans); color: var(--fg); background: var(--raised); border: var(--hairline) solid var(--border-strong); padding: var(--space-1) var(--space-2); }
.input.mono { font-family: var(--mono); font-size: var(--text-sm); }
textarea.input { display: block; min-height: 6em; resize: vertical; padding: var(--space-2) var(--space-3); }
.input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 var(--hairline) var(--accent); }

/* clone */
details.clone { position: relative; flex: none; }
details.clone > summary { list-style: none; }
details.clone > summary::-webkit-details-marker { display: none; }
details.clone .panel { position: absolute; right: 0; top: calc(100% + var(--space-2)); z-index: 10; width: min(440px, 92vw); background: var(--raised); border: var(--hairline) solid var(--border); padding: var(--space-3); box-shadow: var(--shadow); }
.copyrow { display: flex; gap: var(--space-2); align-items: center; margin: var(--space-1) 0; }
.copyrow label { width: 44px; font-size: var(--text-sm); color: var(--muted); }
.copyrow .input { flex: 1; min-width: 0; }
.clone-note { margin: var(--space-2) 0 0; font-size: var(--text-sm); color: var(--muted); }
.private-mark { font-size: var(--text-sm); font-weight: var(--fw-medium); color: var(--warn); }
.private-mark:hover { color: var(--warn); }

/* live status: words, no dot */
#live { font: var(--fw-regular) var(--text-xs) var(--mono); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 40vw; }
#live .live-on { color: var(--pass); }
#live .live-off { color: var(--faint); }
#live .live-busy { color: var(--warn); animation: live-pulse 1s ease-in-out infinite alternate; }
@keyframes live-pulse { to { opacity: 0.4; } }

main.wrap { padding-top: var(--space-5); padding-bottom: var(--space-10); }
main.wrap > :first-child { margin-top: 0; }
footer.site { color: var(--muted); padding-bottom: var(--space-6); font-size: var(--text-sm); }

/* toolbars above lists and code */
.bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); margin: 0 0 var(--space-3); }
.bar .grow { flex: 1; }
.crumbs { font-family: var(--mono); font-size: var(--text-sm); overflow-wrap: anywhere; }
details.picker { position: relative; }
details.picker > summary { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--control-h); list-style: none; cursor: pointer; border: var(--hairline) solid var(--border-strong); padding: var(--space-1) var(--space-3); background: var(--raised); font: var(--fw-regular) var(--text-sm)/1.2 var(--mono); }
details.picker > summary b { font-weight: var(--fw-medium); }
details.picker > summary:hover { border-color: var(--muted); }
details.picker > summary::-webkit-details-marker { display: none; }
details.picker #branch-menu { position: absolute; z-index: 10; top: calc(100% + var(--space-1)); left: 0; min-width: 220px; max-height: 60vh; overflow: auto; background: var(--raised); border: var(--hairline) solid var(--border); padding: var(--space-1) 0; box-shadow: var(--shadow); display: flex; flex-direction: column; }
details.picker #branch-menu a { padding: var(--space-1) var(--space-3); font-family: var(--mono); font-size: var(--text-sm); }
details.picker #branch-menu a:hover { background: var(--hover); text-decoration: none; }

/* avatars (lib/avatar.ts): a person's bauhaus tiles, square, on the
   five avatar tokens; the drawing's own classes pick the colour. */
svg.avatar { display: block; flex: none; }
svg.avatar .av-g { fill: var(--avatar-ground); }
svg.avatar .av-i { fill: var(--avatar-ink); }
svg.avatar .av-r { fill: var(--avatar-red); }
svg.avatar .av-b { fill: var(--avatar-blue); }
svg.avatar .av-y { fill: var(--avatar-yellow); }

/* the activity grid (ui.activity): a column a week, a square button a
   day, coloured by how busy it was. The 53 weeks fill the panel's width,
   square cells with --space-half gaps; in a narrower box the cells
   shrink with it down to 10px, and below that the oldest weeks go (a<n>:
   n weeks before this one), a week each 12px, so the latest always show. A picked day has
   an ink outline. A still grid's days (a repo's insights) are spans, the
   same squares with nothing to hover or pick. */
.activity-fit { container: activity / inline-size; }
.activity { --cell: max(10px, calc((100cqw + var(--space-half)) / 53 - var(--space-half))); display: grid; grid-template-rows: repeat(7, var(--cell)); grid-auto-columns: var(--cell); grid-auto-flow: column; gap: var(--space-half); justify-content: start; }
.activity > :is(button, span) { display: block; min-height: 0; width: 100%; height: 100%; padding: 0; border: 0; background: var(--heat-0); }
.activity > button { cursor: pointer; }
.activity > .l1 { background: var(--heat-1); }
.activity > .l2 { background: var(--heat-2); }
.activity > .l3 { background: var(--heat-3); }
.activity > .l4 { background: var(--heat-4); }
.activity > button:hover { outline: var(--hairline) solid var(--muted); outline-offset: 0; }
.activity > button[aria-pressed="true"] { outline: 2px solid var(--fg); outline-offset: 0; position: relative; z-index: 1; }
.activity > button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; position: relative; z-index: 2; }
@container activity (width < 634px) { .activity > .a52 { display: none; } }
@container activity (width < 622px) { .activity > .a51 { display: none; } }
@container activity (width < 610px) { .activity > .a50 { display: none; } }
@container activity (width < 598px) { .activity > .a49 { display: none; } }
@container activity (width < 586px) { .activity > .a48 { display: none; } }
@container activity (width < 574px) { .activity > .a47 { display: none; } }
@container activity (width < 562px) { .activity > .a46 { display: none; } }
@container activity (width < 550px) { .activity > .a45 { display: none; } }
@container activity (width < 538px) { .activity > .a44 { display: none; } }
@container activity (width < 526px) { .activity > .a43 { display: none; } }
@container activity (width < 514px) { .activity > .a42 { display: none; } }
@container activity (width < 502px) { .activity > .a41 { display: none; } }
@container activity (width < 490px) { .activity > .a40 { display: none; } }
@container activity (width < 478px) { .activity > .a39 { display: none; } }
@container activity (width < 466px) { .activity > .a38 { display: none; } }
@container activity (width < 454px) { .activity > .a37 { display: none; } }
@container activity (width < 442px) { .activity > .a36 { display: none; } }
@container activity (width < 430px) { .activity > .a35 { display: none; } }
@container activity (width < 418px) { .activity > .a34 { display: none; } }
@container activity (width < 406px) { .activity > .a33 { display: none; } }
@container activity (width < 394px) { .activity > .a32 { display: none; } }
@container activity (width < 382px) { .activity > .a31 { display: none; } }
@container activity (width < 370px) { .activity > .a30 { display: none; } }
@container activity (width < 358px) { .activity > .a29 { display: none; } }
@container activity (width < 346px) { .activity > .a28 { display: none; } }
@container activity (width < 334px) { .activity > .a27 { display: none; } }
@container activity (width < 322px) { .activity > .a26 { display: none; } }
@container activity (width < 310px) { .activity > .a25 { display: none; } }
@container activity (width < 298px) { .activity > .a24 { display: none; } }
@container activity (width < 286px) { .activity > .a23 { display: none; } }
@container activity (width < 274px) { .activity > .a22 { display: none; } }
@container activity (width < 262px) { .activity > .a21 { display: none; } }
@container activity (width < 250px) { .activity > .a20 { display: none; } }
@container activity (width < 238px) { .activity > .a19 { display: none; } }
@container activity (width < 226px) { .activity > .a18 { display: none; } }
@container activity (width < 214px) { .activity > .a17 { display: none; } }
@container activity (width < 202px) { .activity > .a16 { display: none; } }
@container activity (width < 190px) { .activity > .a15 { display: none; } }
@container activity (width < 178px) { .activity > .a14 { display: none; } }
@container activity (width < 166px) { .activity > .a13 { display: none; } }
@container activity (width < 154px) { .activity > .a12 { display: none; } }
@container activity (width < 142px) { .activity > .a11 { display: none; } }
@container activity (width < 130px) { .activity > .a10 { display: none; } }
@container activity (width < 118px) { .activity > .a9 { display: none; } }
@container activity (width < 106px) { .activity > .a8 { display: none; } }
@container activity (width < 94px) { .activity > .a7 { display: none; } }
@container activity (width < 82px) { .activity > .a6 { display: none; } }
@container activity (width < 70px) { .activity > .a5 { display: none; } }
@container activity (width < 58px) { .activity > .a4 { display: none; } }
@container activity (width < 46px) { .activity > .a3 { display: none; } }
@container activity (width < 34px) { .activity > .a2 { display: none; } }
@container activity (width < 22px) { .activity > .a1 { display: none; } }

/* event rows: what happened, a row each: its kind (as wide as
   "release"), what, and when. The rows share the list's columns (subgrid),
   so every title ends at the same edge; the time is --col-time wide. */
.ev-rows { display: grid; grid-template-columns: 3.6em minmax(0, 1fr) auto; column-gap: var(--space-3); }
.ev { position: relative; grid-column: 1 / -1; display: grid; grid-template-columns: 3.6em minmax(0, 1fr) auto; grid-template-columns: subgrid; column-gap: var(--space-3); align-items: baseline; padding: var(--space-2) var(--space-3); }
.ev:hover, .ev:focus-within { background: var(--hover); }
.ev-kind { font: var(--fw-regular) var(--text-xs) var(--mono); color: var(--muted); }
.ev-what { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--fg); }
a.ev-what:hover { color: var(--fg); }
a.ev-what::after { content: ''; position: absolute; inset: 0; }
.ev-what b { font-weight: var(--fw-strong); }
.ev-what .tag { font-family: var(--mono); font-size: var(--text-inline-mono); color: var(--link); }
.ev time { min-width: var(--col-time); font-size: var(--text-xs); color: var(--faint); text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* panels (ui.panel): where content sits. Lists, file viewers, READMEs,
   diffs and discussions sit in panels; the header, a page's title, tabs
   and toolbars sit on the page. A panel is a raised surface with a
   hairline edge (square, no shadow) and may have a head strip, tinted,
   naming what it holds: quiet sans words, the key item in ink, shas and
   ages in the mono. Rows inside are between hairlines, none under the
   last, and a row's hover tints the whole row. Panels stack 16px apart. */
.panel { display: block; min-width: 0; margin: 0 0 var(--space-4); background: var(--raised); border: var(--hairline) solid var(--border); }
.panel:last-child { margin-bottom: 0; }
.panel-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-3); min-height: calc(var(--control-h) + 2 * var(--space-1)); padding: var(--space-1) var(--space-3); background: var(--tint); border-bottom: var(--hairline) solid var(--border); font-size: var(--text-sm); line-height: 1.5; color: var(--muted); }
.panel-head :is(b, strong, h2, h3) { display: inline; margin: 0; padding: 0; border: 0; font-size: inherit; font-weight: var(--fw-medium); color: var(--fg); }
.panel-head .key, .panel-head .key:hover, .panel-head :is(b, h2, h3) a, .panel-head :is(b, h2, h3) a:hover { color: var(--fg); }
.panel-head :is(.n, time, .sha, .date) { font: var(--fw-regular) var(--text-xs) var(--mono); color: var(--faint); font-variant-numeric: tabular-nums; white-space: nowrap; }
.panel-head a.sha { color: var(--link); }
.panel-head .grow { flex: 1 1 12em; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.panel-head .end { margin-left: auto; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-3); }
.panel-head .check, .panel-head button { min-height: 0; }
.panel-head button { padding-block: var(--space-half); }
/* A panel that folds: a details whose summary is the head strip. */
details.panel > summary.panel-head { cursor: pointer; list-style: none; }
details.panel > summary.panel-head::-webkit-details-marker { display: none; }
details.panel > summary.panel-head::before { content: "\25BE"; width: 1em; margin-right: calc(-1 * var(--space-2)); color: var(--muted); }
details.panel:not([open]) > summary.panel-head::before { content: "\25B8"; }
details.panel:not([open]) > summary.panel-head { border-bottom: 0; }
details.panel > summary.panel-head:hover { color: var(--fg); }
.panel-body { padding: var(--space-3); }
.panel-body > :first-child { margin-top: 0; }
.panel-body > :last-child { margin-bottom: 0; }
/* Rows: a list's items between hairlines; the last has none, the panel's edge is its rule. */
.rows { list-style: none; margin: 0; padding: 0; }
.rows > li { border-bottom: var(--hairline) solid var(--border); }
.panel :is(.rows > li:last-child, table.list > tbody > tr:last-child > td, table.list > tbody > tr:last-child) { border-bottom: 0; }
.empty { margin: 0; color: var(--muted); padding: var(--space-6) var(--space-3); text-align: center; }

/* lists: tables of rows between hairlines, column names in the panel's
   head strip; they restack on phones */
table.list { width: 100%; border-collapse: collapse; }
table.list th, table.list td { text-align: left; padding: var(--space-2); border-bottom: var(--hairline) solid var(--border); vertical-align: baseline; }
table.list :is(th, td):first-child { padding-left: var(--space-3); }
table.list :is(th, td):last-child { padding-right: var(--space-3); }
table.list thead th { font-size: var(--text-sm); font-weight: var(--fw-regular); color: var(--muted); background: var(--tint); white-space: nowrap; }
table.list .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
table.list td.num, table.list td.date { font: var(--fw-regular) var(--text-xs)/1.6 var(--mono); }
table.list td.date { color: var(--faint); }
table.list td.date time { font-size: inherit; }
/* A time in its own column (DESIGN.md, Times) is compact, and as wide as
   "Sep 24" whatever it says, right-aligned in figures of one width: every
   row's text ends at the same edge, and nothing moves when ui.ts rewrites
   it. A time in a sentence (data-ago) is a word in it. */
table.list th.date { text-align: right; }
:is(table.list td.date, .panel-head) time:not([data-ago]) { display: inline-block; min-width: var(--col-time); text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
table.list .nowrap, table.list .date, table.list .sha, table.list td.mono { white-space: nowrap; }
table.list td.mono { font-size: var(--text-sm); }
table.list td.main { width: 100%; overflow-wrap: anywhere; }
/* A row's own link (a subject, a file, a branch) is in ink, and stays ink
   on hover; other links are blue. */
table.list td.main > a:first-of-type { color: var(--fg); font-weight: var(--fw-medium); }
table.list td.main > a:first-of-type:hover { color: var(--fg); }
/* Hover tints the row, never a cell or a link, so it is one even block. */
table.list tbody tr:hover, table.list tbody tr:focus-within, table.list tbody tr.sel { background: var(--hover); }
table.list tbody tr.sel > td:first-child { box-shadow: inset 2px 0 0 var(--accent); }
/* A directory: an icon cell, the name, the size. */
table.files td.file-icon { width: 1%; padding-right: 0; color: var(--muted); }
table.files td.size { color: var(--muted); }

@media (max-width: 720px) {
	table.list thead { display: none; }
	table.list.stack tr { display: flex; flex-wrap: wrap; gap: var(--space-half) var(--space-3); padding: var(--space-2) var(--space-3); border-bottom: var(--hairline) solid var(--border); }
	table.list.stack td, table.list.stack td:first-child, table.list.stack td:last-child { border: 0; padding: 0; font-size: var(--text-sm); color: var(--muted); }
	table.list.stack td.main { flex: 0 0 100%; font-size: var(--text-md); color: var(--fg); }
	table.list.stack tbody tr.sel { box-shadow: inset 2px 0 0 var(--accent); }
	table.list.stack tbody tr.sel > td:first-child { box-shadow: none; }
	table.list.stack .hide-sm { display: none; }
	table.list.stack td { order: 2; }
	table.list.stack td.main { order: 0; }
	table.list.stack td.id { order: 1; }
	/* Stacked, the date is one of the facts under the subject, not a column. */
	table.list.stack td.date time { min-width: 0; }
	.hide-sm { display: none; }
}

/* statuses and CI. A review's status is the one filled shape: a small
   square label, white on the status colour (the same in both modes, so the
   white stays readable). */
.status { display: inline-block; font: var(--fw-strong) var(--text-xs)/1.6 var(--sans); color: var(--on-accent); background: var(--status-other); padding: 0 var(--space-2); white-space: nowrap; vertical-align: 1px; }
.status.open { background: var(--status-open); }
.status.merged { background: var(--status-merged); }
.status.closed { background: var(--status-closed); }
.ci { white-space: nowrap; font-weight: var(--fw-strong); }
.ci[title] { cursor: help; }
.ci.pass { color: var(--pass); }
.ci.fail { color: var(--fail); }
.ci.partial, .ci.unverified { color: var(--warn); }
.st { font-family: var(--mono); font-weight: var(--fw-strong); }
.st.A { color: var(--add-fg); }
.st.D { color: var(--del-fg); }
.st.R, .st.C { color: var(--warn); }
.st.M { color: var(--muted); }

/* code views */
/* The gutter (line numbers, and the +/- marker in diffs) is sticky, so code
   scrolls under it: every gutter cell is opaque, its row's tint (translucent
   in dark mode) layered over the code's background. --w is the widest line
   number's digit count, set per file, so the columns never overlap. */
.code { --lnw: max(3.5em, calc(var(--w, 3) * 1ch + 20px)); font: var(--fw-regular) var(--text-code)/1.55 var(--mono); tab-size: 4; -moz-tab-size: 4; overflow-x: auto; border: var(--hairline) solid var(--border); background: var(--raised); }
.code .rows { display: inline-block; min-width: 100%; padding: var(--space-1) 0; }
.code .l { --gut: transparent; display: flex; color: var(--fg); text-decoration: none; }
.code a.l:hover { text-decoration: none; }
.code .ln, .code .mk { position: sticky; background: linear-gradient(var(--gut), var(--gut)) var(--raised); user-select: none; -webkit-user-select: none; }
.code .ln { flex: none; width: var(--lnw); padding: 0 var(--space-3); text-align: right; color: var(--faint); left: 0; }
.code .ln:hover { color: var(--fg); }
.code .ln + .ln { left: var(--lnw); }
.code .lc { white-space: pre; padding: 0 var(--space-4) 0 var(--space-2); flex: 1; }
.code .mk { flex: none; width: 1.2em; left: calc(2 * var(--lnw)); text-align: center; color: var(--faint); }
.code .l.add { background: var(--add-bg); }
.code .l.add .ln { --gut: var(--add-ln); }
.code .l.add .mk { --gut: var(--add-bg); color: var(--add-fg); }
.code .l.del { background: var(--del-bg); }
.code .l.del .ln { --gut: var(--del-ln); }
.code .l.del .mk { --gut: var(--del-bg); color: var(--del-fg); }
.code .l:target { --gut: var(--target-bg); background: var(--gut); }
.code .l:target .ln, .code .l:target .mk { --gut: var(--target-gut); }
.code .l.meta { color: var(--muted); font-style: italic; }
.code .hunk { background: var(--hunk-bg); color: var(--hunk-fg); padding: var(--space-half) var(--space-3); white-space: pre; }
.code .hunk > span { display: inline-block; position: sticky; left: var(--space-3); }
body.wrap-lines .code .lc { white-space: pre-wrap; overflow-wrap: anywhere; }
body.wrap-lines .code .rows { display: block; }
body.wrap-lines .code .hunk { white-space: pre-wrap; overflow-wrap: anywhere; }
/* Narrow screens wrap unless the reader turned it off (ui.ts sets no-wrap). */
@media (max-width: 720px) {
	body:not(.no-wrap) .code .lc, body:not(.no-wrap) .code .hunk { white-space: pre-wrap; overflow-wrap: anywhere; }
	body:not(.no-wrap) .code .rows { display: block; }
}
/* In a panel, code is the panel's body: no second edge. A diff's file is a
   panel whose head strip (.fh) sticks while its lines scroll by. */
.panel > .code { border: 0; }
.fh { position: sticky; top: 0; z-index: 2; gap: var(--space-1) var(--space-2); }
/* A long path shares the line with the status and counts, wrapping at its
   slashes, rather than wrapping onto a line of its own. */
.fh .fname { font-family: var(--mono); color: var(--fg); font-weight: var(--fw-medium); overflow-wrap: break-word; flex: 1 1 0; min-width: min(4em, 100%); max-width: max-content; }
.fh .counts { font: var(--fw-regular) var(--text-xs) var(--mono); }
.fh .st { font-size: var(--text-xs); }
.fh .view { margin-left: auto; font-size: var(--text-sm); }
.file .note { margin: 0; padding: var(--space-3); color: var(--muted); }
table.diffstat td { padding: var(--space-half) var(--space-2); }
table.diffstat td.num { font-size: var(--text-xs); color: var(--muted); }
table.diffstat td.graph { font: var(--fw-regular) var(--text-xs) var(--mono); white-space: nowrap; }
table.diffstat td.main { overflow-wrap: break-word; }
table.diffstat td.main a { font-family: var(--mono); font-size: var(--text-sm); }
/* Phones: the path takes the row and wraps at slashes; the count and graph
   follow on the same line if they fit, else right-aligned below. */
@media (max-width: 720px) {
	table.diffstat tr { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: baseline; gap: 0 var(--space-2); padding: var(--space-1) var(--space-2); border-bottom: var(--hairline) solid var(--border); }
	table.diffstat td { padding: 0; border: 0; }
	table.diffstat td.main { flex: 1 1 0; width: auto; min-width: min(10em, 100%); }
}

/* syntax highlighting: highlight.js classes, colours from the tokens */
.hljs-comment, .hljs-code, .hljs-formula { color: var(--tok-comment); }
.hljs-keyword, .hljs-doctag, .hljs-template-tag, .hljs-template-variable, .hljs-type, .hljs-variable.language_, .hljs-meta .hljs-keyword { color: var(--tok-keyword); }
.hljs-string, .hljs-regexp, .hljs-meta .hljs-string { color: var(--tok-string); }
.hljs-number, .hljs-literal, .hljs-attr, .hljs-attribute, .hljs-variable, .hljs-meta, .hljs-operator, .hljs-selector-attr, .hljs-selector-class, .hljs-selector-id { color: var(--tok-const); }
.hljs-title, .hljs-section { color: var(--tok-title); }
.hljs-built_in, .hljs-symbol, .hljs-bullet { color: var(--tok-builtin); }
.hljs-name, .hljs-quote, .hljs-selector-tag, .hljs-selector-pseudo { color: var(--tok-tag); }
.hljs-subst, .hljs-params { color: var(--fg); }
.hljs-section, .hljs-strong { font-weight: var(--fw-strong); }
.hljs-emphasis { font-style: italic; }
.hljs-addition { color: var(--add-fg); }
.hljs-deletion { color: var(--del-fg); }

/* commit and review pages */
.meta-head { margin: 0 0 var(--space-4); }
.meta-head h1 { font-size: var(--text-xl); margin: 0 0 var(--space-2); overflow-wrap: anywhere; }
.meta-head h1 a { color: var(--fg); }
.meta-head h1 a:hover { color: var(--fg); }
.meta-head h1 .desc { font: var(--fw-regular) var(--text-lg) var(--mono); color: var(--faint); }
.meta-head .byline { color: var(--muted); font-size: var(--text-sm); }
/* A commit message, or a command to copy, as a panel's body. */
.msg, .panel > pre { margin: 0; padding: var(--space-3); white-space: pre-wrap; overflow-wrap: anywhere; font: var(--fw-regular) var(--text-sm)/1.55 var(--mono); }
.panel > pre { font-size: var(--text-xs); }
.panel > .msg + .facts { border-top: var(--hairline) solid var(--border); }
/* A note under a panel's body, on a rule. */
.panel > p.desc { margin: 0; padding: var(--space-2) var(--space-3); border-top: var(--hairline) solid var(--border); font-size: var(--text-sm); }
.panel > p.desc:first-child, .panel > .panel-head + p.desc { border-top: 0; }
.depth { color: var(--faint); white-space: pre; }

/* Above a diff: the diffstat, a panel with the page's tools in its head strip. */
.count { color: var(--muted); font-size: var(--text-sm); white-space: nowrap; }
@media (max-width: 480px) { .count .wide { display: none; } }
.file .code .l { scroll-margin-top: 2.75rem; }

/* Diff files fold (diffs.ts); review pages add a viewed checkbox. */
.fh.foldable { cursor: pointer; }
.fh .fold { min-height: 0; border: 0; background: none; padding: 0; width: 1.1em; color: var(--muted); font: var(--fw-regular) var(--text-md)/1 var(--sans); }
.fh .fold:hover { background: none; color: var(--fg); }
.fh .fold::before { content: "\25BE"; display: inline-block; transition: transform 0.1s; }
.file.folded .fold::before { transform: rotate(-90deg); }
.file.folded > :not(.fh) { display: none; }
.file.folded > .fh { border-bottom: 0; }
.file.folded:has(.viewed input:checked) .fname { color: var(--muted); font-weight: var(--fw-regular); }
.fh .viewed { margin-left: auto; min-height: 0; }
.fh .view ~ .viewed { margin-left: 0; }

/* prose: README, wiki, release notes, review descriptions, comments: the
   serif, for what people wrote */
.markdown { font: var(--fw-regular) var(--text-prose)/1.65 var(--serif); overflow-wrap: break-word; padding: var(--space-5) var(--space-6); }
.markdown > :first-child { margin-top: 0; }
.markdown h1, .markdown h2, .markdown h3, .markdown h4 { font-family: var(--sans); font-weight: var(--fw-strong); color: var(--fg); }
.markdown h1, .markdown h2 { display: block; border-bottom: var(--hairline) solid var(--border); padding-bottom: var(--space-1); }
.markdown h1 { font-size: var(--text-2xl); margin: var(--space-6) 0 var(--space-3); }
.markdown h2 { font-size: var(--text-xl); margin: var(--space-6) 0 var(--space-3); }
.markdown h3 { font-size: var(--text-lg); }
.markdown h4 { font-size: var(--text-md); }
.markdown a:visited { color: var(--deep); }
.markdown img { max-width: 100%; height: auto; }
.markdown p[align="center"], .markdown div[align="center"] { text-align: center; }
/* Code in prose sits on the panel's tint. Inline code never breaks at a
   hyphen: lib/markdown.ts keeps hyphenated words whole (.nobr) and lets a
   path break after its slashes (<wbr>). */
.markdown code { background: var(--tint); border: var(--hairline) solid var(--border); padding: 0 var(--space-1); }
.markdown code .nobr { white-space: nowrap; }
.markdown pre { font: var(--fw-regular) var(--text-code)/1.55 var(--mono); background: var(--tint); border: var(--hairline) solid var(--border); padding: var(--space-3) var(--space-4); overflow-x: auto; tab-size: 4; }
.markdown pre code { background: none; border: 0; padding: 0; }
/* Diagrams, drawn at build time (lib/diagrams.ts): Pele's SVG takes its
   colours and fonts from these, so it follows light and dark as it is. */
.markdown .diagram { margin: var(--space-4) 0; text-align: center; container-type: inline-size; }
/* A wide diagram's second drawing, laid out for a phone, replaces it there. */
.markdown .diagram > svg + svg { display: none; }
@container (max-width: 640px) {
	.markdown .diagram > svg:has(+ svg) { display: none; }
	.markdown .diagram > svg + svg { display: inline; }
}
.markdown .diagram-source { margin: var(--space-4) 0; }
.markdown .diagram-source figcaption { color: var(--muted); font-size: var(--text-sm); }
.pele {
	--pele-bg: var(--raised); --pele-fg: var(--fg); --pele-muted: var(--muted); --pele-line: var(--muted);
	--pele-surface: var(--tint); --pele-surface-alt: var(--hover); --pele-border: var(--border-strong); --pele-accent: var(--accent);
	--pele-critical: var(--fail); --pele-error: var(--fail); --pele-font: var(--sans); --pele-font-mono: var(--mono); --pele-radius: var(--radius);
	--pele-title-weight: var(--fw-strong); --pele-heading-weight: var(--fw-strong); --pele-bold-weight: var(--fw-strong);
	--pele-series-1: var(--viz-1); --pele-series-2: var(--pass); --pele-series-3: var(--warn); --pele-series-4: var(--fail);
	--pele-series-5: var(--tok-title); --pele-series-6: var(--tok-const); --pele-series-7: var(--tok-builtin); --pele-series-8: var(--muted);
}
.markdown blockquote { margin: var(--space-4) 0; padding: 0 var(--space-4); color: var(--muted); border-left: var(--bar) solid var(--border); }
.markdown table { display: block; max-width: 100%; overflow-x: auto; border-collapse: collapse; margin: var(--space-4) 0; font-size: var(--text-md); }
.markdown th, .markdown td { border-bottom: var(--hairline) solid var(--border); padding: var(--space-2) var(--space-3) var(--space-2) 0; text-align: left; vertical-align: top; }
.markdown th { font-family: var(--sans); font-weight: var(--fw-strong); }
.markdown hr { border-top: var(--hairline) solid var(--border); }
.markdown :target { scroll-margin-top: var(--space-4); }
@media (max-width: 720px) {
	.markdown { padding: var(--space-4) var(--space-3); }
	.markdown h1 { font-size: var(--text-xl); }
	.markdown h2 { font-size: var(--text-lg); }
}
/* jev: commits and repos */
/* What Jev says a commit or a repo is: plain words, quiet. */
.jev-kind { font: var(--fw-regular) var(--text-xs) var(--mono); color: var(--muted); white-space: nowrap; }
.jev-topic { color: var(--muted); white-space: nowrap; }
/* Jev's risk score, 0 to 3: a small number, coloured once it is moderate. */
.jev-score { font: var(--fw-regular) var(--text-xs) var(--mono); font-variant-numeric: tabular-nums; color: var(--faint); white-space: nowrap; }
.jev-score.moderate { color: var(--warn); }
.jev-score.high { color: var(--fail); font-weight: var(--fw-strong); }
.jev-mismatch { font-size: var(--text-sm); color: var(--faint); cursor: help; }
.jev-note { font-size: var(--text-sm); font-style: italic; color: var(--faint); }
/* The log: Jev's type in a narrow column on the left. */
table.log th.kind, table.log td.kind { width: 1%; white-space: nowrap; padding-right: var(--space-1); }
table.log td.risk { width: 1%; }
@media (max-width: 720px) {
	/* Stacked: the type leads the line under the subject. */
	table.log td.kind, table.log td.risk { width: auto; padding-right: 0; }
	table.log td.kind { order: 1; }
	table.log td.kind:empty { display: none; }
}
.notes { padding: var(--space-1) var(--space-3) var(--space-3); font: var(--fw-regular) var(--text-md)/1.6 var(--serif); }
.notes h3 { margin: var(--space-4) 0 var(--space-1); font: var(--fw-strong) var(--text-sm)/1.4 var(--sans); color: var(--muted); }
.notes ul { margin: 0; padding-left: var(--space-5); }
.notes li { margin: var(--space-half) 0; overflow-wrap: anywhere; }
/* Each note is a commit's subject, linked: in ink, like a list's rows. */
.notes li > a:first-child { color: var(--fg); }
.notes li > a:first-child:hover { color: var(--fg); }
.notes details { margin-top: var(--space-3); }
.notes summary { cursor: pointer; font: var(--fw-strong) var(--text-sm)/1.4 var(--sans); color: var(--muted); }
.notes summary:hover { color: var(--fg); }

/* jev: review pages */
.jev-mech, .jev-change { font: var(--fw-regular) var(--text-xs) var(--mono); color: var(--muted); white-space: nowrap; }
.jev-change.behavior, .jev-sum.behavior { color: var(--warn); }
.jev-sum { font-size: var(--text-sm); font-weight: var(--fw-regular); color: var(--muted); }
summary .jev-sum { margin-left: var(--space-2); }
.comment .tag.jev-addressed { color: var(--pass); }
