/* The file page's frame, the sheet, scrolling, blame. Split from files.css so each sheet has one job. Tokens only. */
/* The file page (File board): the tree, the file, the panel, side by side under the top bar. */
.ab-fileview {
	flex: 1;
	min-width: 0;
	min-height: 0;
	display: flex;
}
.ab-fileview-tree {
	width: var(--tree-width);
	flex: none;
	display: flex;
	flex-direction: column;
	min-height: 0;
	overflow: auto;
	background: var(--paper);
	border-right: 1px solid var(--rule);
}
.ab-fileview-treehead {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
	color: var(--muted);
	font: var(--type-caption);
}
.ab-fileview-jump {
	padding: 0 var(--space-3) var(--space-2);
}
.ab-fileview-main {
	flex: 1;
	min-width: 0;
	min-height: 0;
	overflow: auto;
	background: var(--paper);
}
.ab-fileview-panel {
	flex: none;
	width: var(--panel-width);
	max-width: 100%;
	min-height: 0;
	overflow: auto;
}
.ab-file-path {
	display: flex;
	align-items: center;
	gap: var(--space-2);
}
.ab-file-path .ab-crumbs {
	flex: 1;
	min-width: 0;
}
.ab-file-bar {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-2);
}
.ab-file-actions {
	display: inline-flex;
	flex-wrap: wrap;
	gap: var(--space-1);
}
.ab-file-note {
	margin: 0;
	padding: var(--space-3) var(--space-4);
	color: var(--muted);
	font: var(--type-ui);
}
@media (max-width: 1100px) {
	.ab-fileview.has-panel .ab-fileview-tree {
		display: none;
	}
}
@media (max-width: 640px) {
	.ab-fileview-tree {
		display: none;
	}
	/* The side panel as a bottom sheet (PhoneStory board): over the page's lower part with a grabber, whatever it holds. The code gets room under it to scroll a line out from behind. */
	.ab-fileview-panel {
		position: fixed;
		z-index: 15;
		left: 0;
		right: 0;
		bottom: 0;
		width: auto;
		max-width: none;
		max-height: 70vh;
		padding: 14px 0 env(safe-area-inset-bottom);
		overflow-y: auto;
		overscroll-behavior: contain;
		border-left: 0;
		border-radius: 12px 12px 0 0;
		box-shadow:
			0 -12px 32px rgb(0 0 0 / 0.55),
			0 0 0 1px var(--rule);
	}
	.ab-fileview-panel::before {
		content: "";
		position: absolute;
		top: 6px;
		left: 50%;
		width: 36px;
		height: 4px;
		margin-left: -18px;
		border-radius: 2px;
		background: var(--faint);
	}
	.ab-fileview.has-panel .ab-fileview-body {
		padding-bottom: 50vh;
	}
}

/* The frame's scrolling: the top bar, the header, the tree and the panel stay put; the body scrolls on its own. */
.ab-app.is-full:has(.ab-fileview) {
	height: 100vh;
	min-height: 0;
}
.ab-app.is-full:has(.ab-fileview) .ab-full {
	overflow: hidden;
}
.ab-fileview-main {
	display: flex;
	flex-direction: column;
	overflow: hidden;
}
.ab-fileview-main .ab-file-head {
	flex: none;
}
.ab-fileview-body {
	position: relative;
	flex: 1;
	min-height: 0;
	overflow: auto;
}
.ab-fileview-main .ab-file-head {
	gap: var(--space-2);
}
.ab-file-path .ab-vpick {
	margin-left: auto;
}
.ab-file-head .facts {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: var(--space-1) var(--space-3);
	color: var(--muted);
	font: var(--type-ui);
}
.ab-writtenby {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
}
.ab-fileview-body .ab-folder {
	max-width: var(--measure);
	margin: 0 auto;
	padding: var(--space-4);
	box-sizing: border-box;
}
.ab-fileview-main > .ab-file-head .ab-folder-facts {
	margin: 0;
}

/* Blame mode: a column in front of the gutter says who wrote a run, which change, and when. */
.ab-code.is-blame .ab-line {
	grid-template-columns: 300px 3px 5px 48px 2px minmax(0, 1fr) auto;
}
.ab-line .bi {
	display: flex;
	align-items: baseline;
	gap: var(--space-2);
	min-width: 0;
	padding: 0 var(--space-3) 0 var(--space-4);
	overflow: hidden;
	color: var(--muted);
	font: var(--type-caption);
	text-decoration: none;
	white-space: nowrap;
}
.ab-line .bi b {
	color: var(--ink);
	font-weight: 600;
}
.ab-line .bi .num {
	font-family: var(--font-mono);
}
.ab-line .bi .msg {
	min-width: 0;
	flex: 1;
	overflow: hidden;
	text-overflow: ellipsis;
}
.ab-line a.bi:hover {
	color: var(--ink);
	background: var(--wash);
}
@media (max-width: 900px) {
	.ab-code.is-blame .ab-line {
		grid-template-columns: 3px 5px 48px 2px minmax(0, 1fr) auto;
	}
	.ab-line .bi {
		display: none;
	}
}

/* Blame mode: a column in front of the gutter says who wrote a run, which change, and when. */
.ab-code.is-blame .ab-line {
	grid-template-columns: 300px 3px 5px 48px 2px minmax(0, 1fr) auto;
}
.ab-line .bi {
	display: flex;
	align-items: baseline;
	gap: var(--space-2);
	min-width: 0;
	padding: 0 var(--space-3) 0 var(--space-4);
	overflow: hidden;
	color: var(--muted);
	font: var(--type-caption);
	text-decoration: none;
	white-space: nowrap;
}
.ab-line .bi b {
	color: var(--ink);
	font-weight: 600;
}
.ab-line .bi .num {
	font-family: var(--font-mono);
}
.ab-line .bi .msg {
	min-width: 0;
	flex: 1;
	overflow: hidden;
	text-overflow: ellipsis;
}
.ab-line a.bi:hover {
	color: var(--ink);
	background: var(--wash);
}
@media (max-width: 900px) {
	.ab-code.is-blame .ab-line {
		grid-template-columns: 3px 5px 48px 2px minmax(0, 1fr) auto;
	}
	.ab-line .bi {
		display: none;
	}
}

.ab-history-older {
	margin: 0;
	padding: 12px 4px;
}

/* On a phone the header scrolls away with the page's body: it would take most of the screen otherwise. */
@media (max-width: 640px) {
	.ab-app.is-full:has(.ab-fileview) {
		height: auto;
		min-height: 100vh;
	}
	.ab-app.is-full:has(.ab-fileview) .ab-full {
		overflow: visible;
	}
	.ab-fileview-main {
		display: block;
		overflow: visible;
	}
	.ab-fileview-body {
		overflow-x: auto;
		overflow-y: visible;
	}
	.ab-writtenby > span:not(.ab-strip) {
		display: none;
	}
	.ab-file-head .ab-crumbs .ab-copy,
	.ab-file-head .ab-crumbs button {
		display: none;
	}
}
