html {
	/* reserve the scrollbar gutter: a page growing past the viewport
	   (async fills, loading placeholder -> full page) must not nudge
	   the whole layout left when the scrollbar appears */
	scrollbar-gutter: stable;
}

body {
	color: #000;
	background-color: #fff;
	font-family: monospace;
}

h1, h2, h3, h4, h5, h6 {
	font-size: 1em;
	margin: 0;
}

img, h1, h2 {
	vertical-align: middle;
}

img {
	border: 0;
}

a:target {
	background-color: #ccc;
}

a.d,
a.h,
a.i,
a.line {
	text-decoration: none;
}

#blob a {
	color: #555;
}

#blob a:hover {
	color: blue;
	text-decoration: none;
}

table thead td {
	font-weight: bold;
}

table td {
	padding: 0 0.4em;
}

#content table td {
	vertical-align: top;
	white-space: nowrap;
}

#branches tr:hover td,
#tags tr:hover td,
#index tr:hover td,
#log tr:hover td,
#files tr:hover td {
	background-color: #eee;
}

/* let long ref decorations wrap under the fixed-width subject box */
#log tr td:nth-child(2) {
	white-space: normal;
}

/* Fixed-width cell content: cells that fill in asynchronously (per fetch
   round) hold their text in a constant-width box, so a table's geometry
   is identical before and after the data arrives — variable-length text
   is clipped with an ellipsis instead of resizing its column. */
.cw {
	display: inline-block;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	vertical-align: bottom;
}
/* log subject / index description: 60ch, but yield on narrow viewports
   (the sibling columns need ~36ch) instead of forcing page-wide hscroll */
/* Message/description columns track the viewport: they grow to use a wide
   screen (up to a readable cap) and shrink on a narrow one, reserving room
   for the sibling columns. The width depends only on the viewport, never on
   the (async-arriving) cell text, so the table geometry is still stable as
   rows stream in. */
.cmsg { width: clamp(16ch, calc(100vw - 36ch), 90ch); }
.cdesc { width: clamp(16ch, calc(100vw - 36ch), 90ch); }
.cdate { width: 16ch; } /* refs: "YYYY-MM-DD HH:MM", reserved while loading */
.cgx { width: clamp(12ch, calc(100vw - 30ch), 33ch); } /* graph merge chip */
.csize { min-width: 6ch; text-align: right; } /* tree: size in bytes */

/* Reveal a clipped message cell's full text on hover, pure CSS (no script):
   the clipped span is lifted out of flow (position:absolute, so the table
   never reflows) into a solid box over its neighbours — readable, and
   selectable/copyable right there. The 0.4em padding leaves a little slack
   past each end so a drag can grab the whole name incl. the last character;
   -webkit-user-drag stops the anchor drag that would otherwise start
   instead of a text selection. The full text is always in the DOM, so
   selecting across a row copies it even without the reveal.

   Gated on (hover: hover): touch devices have no hover, so instead of an
   unreachable reveal they show the message unclipped (see (hover: none)
   below). Table cells are the positioning context for the absolute span. */
@media (hover: hover) {
	#content table td,
	#graph td {
		position: relative;
	}
	/* Reveal the box's inner content, not the box: the fixed-width .cw
	   span stays in flow, so the table column cannot shrink a few px on
	   hover (the old form pulled the span out of flow, shifting the
	   Author column until unhover). */
	td:hover > .cmsg > *,
	td:hover > .cdesc > *,
	#graph td.gm:hover > .gmt > * {
		position: absolute;
		top: 0;
		left: 0;
		z-index: 5;
		width: max-content;
		max-width: 90vw;
		padding: 0 0.4em;
		overflow: visible;
		white-space: normal;
		background-color: #eee;
		-webkit-user-drag: none;
	}
	/* the trailing "(HEAD -> master)" would show through the revealed box */
	td:hover > .cmsg ~ .refs,
	#graph td.gm:hover > .gmt ~ .refs {
		visibility: hidden;
	}
}

/* Touch (no hover): show the message unclipped so the full text is visible
   with no interaction at all — nothing to reveal, nothing to tap. It keeps
   its reserved column width and simply wraps within it, so the sibling
   columns still fit without pushing the table into horizontal scroll. */
@media (hover: none) {
	.cmsg,
	.cdesc {
		/* plain inline text that flows and wraps inside the cell, instead of
		   a fixed-width clipped box — so the column sizes to the available
		   width and any trailing ref decoration sits right after the text */
		display: inline;
		white-space: normal;
		overflow: visible;
	}
}

/* let a drag select the message text instead of dragging the link URL, so
   the revealed name can be selected/copied */
.cmsg a,
.cdesc a,
#graph .gmt a {
	-webkit-user-drag: none;
}

td.num {
	text-align: right;
}

.desc {
	color: #555;
	/* own line with reserved height: a description arriving a round
	   after the first paint must not reflow the header */
	display: block;
	min-height: 1.25em;
}

/* "on <ish>: log · graph · ..." strip under the header when viewing a
   non-HEAD commit-ish (the header nav itself always points at HEAD) */
.ref-context {
	color: #555;
	margin-bottom: 0.75em;
}

.head {
	color: #555;
	font-size: 0.85em;
}

hr {
	border: 0;
	border-top: 1px solid #555;
	height: 1px;
}

pre {
	font-family: monospace;
}

pre a.h {
	color: #00a;
}

.A,
span.i,
pre a.i {
	color: #070;
}

.D,
span.d,
pre a.d {
	color: #e00;
}

pre a.h:hover,
pre a.i:hover,
pre a.d:hover {
	text-decoration: none;
}

@media (prefers-color-scheme: dark) {
	body {
		background-color: #000;
		color: #bdbdbd;
	}
	hr {
		border-color: #222;
	}
	a {
		color: #56c8ff;
	}
	a:target {
		background-color: #222;
	}
	.desc {
		color: #aaa;
	}
	#blob a {
		color: #555;
	}
	#blob a:target {
		color: #eee;
	}
	#blob a:hover {
		color: #56c8ff;
	}
	pre a.h {
		color: #00cdcd;
	}
	.A,
	span.i,
	pre a.i {
		color: #00cd00;
	}
	.D,
	span.d,
	pre a.d {
		color: #cd0000;
	}
	.head {
		color: #aaa;
	}
	#branches tr:hover td,
	#tags tr:hover td,
	#index tr:hover td,
	#log tr:hover td,
	#files tr:hover td {
		background-color: #111;
	}
	@media (hover: hover) {
		td:hover > .cmsg > *,
		td:hover > .cdesc > *,
		#graph td.gm:hover > .gmt > * {
			background-color: #111;
		}
	}
}

/* stagit-ng additions: in-page anchors ride the ?query (and standalone
   routes the hash), so :target never matches; stagit-ng.js applies
   .target to the ?anchor element instead. */
.target {
	background-color: #ccc;
}

/* bottom-anchored: the repo header (logo, name, description, clone url)
   owns the top of the page, and on narrow viewports a top-right overlay
   sits right on it. The bottom corner can only ever cover body rows —
   transient placeholders while a load is in flight. */
#stagit-ng-status {
	position: fixed;
	bottom: 0;
	/* clear of the (gutter-stable) scrollbar, aligned with the panel */
	right: 1.2em;
	padding: 0.2em 0.6em;
	background-color: #eee;
	color: #555;
	font-family: monospace;
	font-size: 0.85em;
	/* fits "loading… 12345 KiB": the growing byte counter must not
	   resize (and so shift) the box on every fetch */
	min-width: 16ch;
	text-align: right;
	cursor: pointer; /* opens the transfer stats panel */
}

/* idle: the indicator collapses to a small always-present icon (⇅) that
   reopens the stats panel */
#stagit-ng-status.idle {
	min-width: 0;
}

/* per-type transfer stats above the status line: a fixed overlay, so
   opening it never reflows the page; it grows upward from a fixed
   bottom edge, away from the page content */
#stagit-ng-stats {
	position: fixed;
	bottom: 1.7em;
	right: 1.2em;
	padding: 0.4em 2em 0.5em 0.8em; /* right gap for the × */
	background-color: #eee;
	color: #333;
	font-family: monospace;
	font-size: 0.85em;
	z-index: 1;
}
#stagit-ng-stats .close {
	position: absolute;
	top: 0;
	right: 0;
	/* a fat corner target, well clear of the window scrollbar */
	padding: 0.15em 0.5em 0.4em 0.6em;
	cursor: pointer;
}
#stagit-ng-stats pre {
	margin: 0;
	font: inherit;
}
/* the cache half of the stats line: matches the ░ bar segment, so the
   muted numbers read as "the gray part" without a legend; #777 keeps
   enough contrast on both the light (#eee) and dark (#111) panel */
#stagit-ng-stats .dim {
	color: #777;
}
#stagit-ng-stats p {
	margin: 0.4em 0 0;
}
#stagit-ng-stats .warn {
	color: #d70;
}
#stagit-ng-stats .retry {
	cursor: pointer;
	text-decoration: underline;
}

.refs {
	color: #d70;
	font-size: 0.9em;
}

/* rendered markdown (about tab, *.md blobs); the global h1-h6 reset
   flattens headings, so restore a modest hierarchy here */
#readme {
	max-width: 100ch;
}
#readme h1 {
	font-size: 1.3em;
	margin: 1em 0 0.4em;
}
#readme h2 {
	font-size: 1.15em;
	margin: 1em 0 0.4em;
}
#readme h3,
#readme h4,
#readme h5,
#readme h6 {
	font-size: 1em;
	margin: 1em 0 0.4em;
}
#readme img {
	max-width: 100%;
	height: auto;
	border: 1px solid #ccc;
}
#readme pre {
	margin-left: 2ch;
}

@media (prefers-color-scheme: dark) {
	.target {
		background-color: #222;
	}
	#stagit-ng-status {
		background-color: #111;
		color: #aaa;
	}
	#stagit-ng-stats {
		background-color: #111;
		color: #aaa;
	}
	#stagit-ng-stats .warn {
		color: #e90;
	}
	.refs {
		color: #e90;
	}
	#readme img {
		border-color: #333;
	}
}

/* first-parent commit graph (graph/<ish>) */
#graph {
	border-collapse: collapse;
}
#graph td {
	padding: 0 0.4em;
	white-space: nowrap;
	height: 18px;
	line-height: 18px;
	vertical-align: middle;
}
#graph td.gc {
	padding: 0;
	/* fits two lanes; grows when nested expansions add deeper lanes */
	min-width: 30px;
}
#graph svg.g {
	display: block;
}
#graph .gt {
	stroke: #d1332e;
	stroke-width: 2;
}
#graph .gs {
	fill: none;
	stroke: #0a58ca;
	stroke-width: 1.5;
	opacity: 0.5;
}
#graph .gs2 {
	fill: none;
	stroke: #0a58ca;
	stroke-width: 2;
}
#graph .gdash {
	stroke-dasharray: 2 3;
	opacity: 0.6;
}
#graph .gn {
	fill: #d1332e;
}
#graph .gns {
	fill: #0a58ca;
}
#graph .gmerge {
	fill: #fff;
	stroke: #d1332e;
	stroke-width: 2;
}
#graph .gmerges {
	fill: #fff;
	stroke: #0a58ca;
	stroke-width: 2;
}
#graph .gtag {
	fill: #d70;
	stroke: #fff;
	stroke-width: 1;
}
#graph td.gsha a {
	color: #555;
}
#graph .gmt {
	display: inline-block;
	/* viewport-based (not content-based) so rows streaming in never resize
	   the column, but a narrow screen still shrinks it instead of forcing
	   page-wide horizontal scroll (and a wide one gets more room). */
	width: clamp(30ch, calc(100vw - 44ch), 90ch);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	vertical-align: bottom;
}
#graph a.gexp {
	text-decoration: none;
	border: 1px solid #9bf;
	border-radius: 8px;
	padding: 0 0.4em;
	font-size: 0.9em;
	white-space: nowrap;
}
#graph a.gexp:hover {
	background-color: #eef4ff;
}
#graph tr:hover td {
	background-color: #eee;
}

@media (prefers-color-scheme: dark) {
	#graph .gmerge,
	#graph .gmerges {
		fill: #000;
	}
	#graph .gtag {
		stroke: #000;
	}
	#graph td.gsha a {
		color: #888;
	}
	#graph a.gexp {
		border-color: #356;
	}
	#graph a.gexp:hover {
		background-color: #123;
	}
	#graph tr:hover td {
		background-color: #111;
	}
}

/* standalone mode: remote-repo entry form and recents on the index page */
#remote input {
	font-family: monospace;
	font-size: 1em;
	background-color: inherit;
	color: inherit;
	border: 1px solid #999;
	padding: 0.15em 0.4em;
}
.remote-label {
	margin-bottom: 0.3em;
}
#recent-list,
#examples {
	margin: 0.3em 0;
	padding-left: 2em;
}

@media (prefers-color-scheme: dark) {
	#remote input {
		border-color: #444;
	}
}

/* Narrow viewports (phones). The message columns already shrink with the
   viewport, so most pages fit; a genuinely wide table (the commit graph,
   or a blob with long lines) scrolls horizontally *inside* the content
   area instead of widening the whole page — so the header, nav and the
   rest stay put at device width. */
@media (max-width: 600px) {
	/* long clone URLs / repo descriptions wrap instead of scrolling */
	.desc {
		overflow-wrap: anywhere;
	}
	/* Date + full message + author is three columns too many for a phone.
	   The author is the least essential in a commit log, so drop it and let
	   the date and the (unclipped) message have the room. Fixed layout so
	   the message column is bounded by the viewport and wraps, instead of an
	   auto table sizing to the longest subject and overflowing the page. */
	#log tr > :nth-child(3) {
		display: none;
	}
	#log {
		table-layout: fixed;
		width: 100%;
	}
	#log td:first-child {
		width: 17ch; /* the fixed-format "YYYY-MM-DD HH:MM" date, one line */
	}
}

/* Content that can't wrap — code blobs, diffs, the commit graph — scrolls
   horizontally within its own box, so a long line or a wide graph never
   widens the whole page (which would push every other page's layout too).
   Everything else (the log/summary tables) stays constrained and wraps. */
#content pre,
.xscroll {
	overflow-x: auto;
}
