/*  */
/* Search bar */
/*  */
#search-container {
	margin: .5rem;
	display: flex;
	gap: .5rem;
	justify-content: center;
	align-items: center;

	border-bottom: 1px solid var(--nav-background-color);
}

#start-search,
#clear-search {
	width: 2rem;
	padding: .5rem;
}

#clear-search {
	opacity: 0;

	padding: .55rem;

	transition: opacity 0.3s ease-out;
}

#search-container:focus-within #clear-search {
	opacity: 1;
}

#search-input {
	width: min(20vw, 12rem);
	padding-block: .3rem;
	outline: 0;
	background-color: transparent;
	color: var(--nav-background-color);
	font-size: .9rem;
	transition: border 0.3s ease-out;
}

#search-input::placeholder {
	color: var(--nav-background-color);
	transition: color 0.2s ease-out;
}

#search-input:focus::placeholder {
	color: transparent;
}

/*  */
/* Library Views */
/*  */
main:has(#massedit-toggle:checked) #list-library,
main:not(
	:has(#massedit-toggle:checked)
):has(#view-button > option[value="posters"]:checked) #table-container,
main:not(
	:has(#massedit-toggle:checked)
):has(#view-button > option[value="table"]:checked) #list-library {
	display: none;
}

#library-container {
	padding: 1.5rem;
	position: relative;
}

/*  */
/* Alphabet rail */
/* A strip of the letters the library actually contains, down the right of
   the gallery. Dragging it scrubs; tapping a letter jumps. Positioned
   against the viewport rather than the list so it stays put while the
   library moves underneath it. */
#alphabet-rail {
	position: fixed;
	right: 0;
	top: 50%;
	transform: translateY(-50%);
	z-index: 4;
	/* The strip of letters is under thirty pixels wide, which is a poor
	   target for a thumb. The rail is what receives the pointer, so it
	   reaches further left than it appears to: once the drag has started
	   the position along it is all that is read, and horizontal precision
	   stops mattering entirely. */
	padding: .5rem .25rem .5rem 1.25rem;
	/* The rail is a scrub target: a finger dragging down it must not also
	   drag the page. */
	touch-action: none;
	user-select: none;
	-webkit-user-select: none;
}

#alphabet-letters {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 0;
	padding: .35rem .15rem;
	border-radius: 1rem;
	background-color: var(--foreground-color);
	border: 1px solid var(--border-color);
	box-shadow: 0 0 .35rem rgba(0, 0, 0, .35);
}

.alphabet-letter {
	appearance: none;
	background: none;
	border: none;
	color: var(--text-color);
	font-size: .62rem;
	font-weight: 700;
	line-height: 1.15;
	padding: 0 .3rem;
	margin: 0;
	cursor: pointer;
	/* The pointer is tracked by where it is on the rail, not by which
	   letter it lands on, so the letters themselves must not swallow it. */
	pointer-events: none;
}

/* The letter under the finger, big enough to read while dragging. */
#alphabet-bubble {
	position: fixed;
	right: 3rem;
	top: 50%;
	transform: translateY(-50%);
	z-index: 5;
	min-width: 3.5rem;
	padding: .75rem;
	border-radius: .75rem;
	background-color: var(--header-background-color);
	color: var(--header-color);
	font-size: 2rem;
	font-weight: 700;
	text-align: center;
	pointer-events: none;
	box-shadow: 0 0 .5rem rgba(0, 0, 0, .4);
}

/* Mass edit hands scrolling to the inner table and covers the right-hand
   edge with its action bar; the rail has nowhere to be and nothing to do. */
main:has(#massedit-toggle:checked) #alphabet-rail,
main:has(#massedit-toggle:checked) #alphabet-bubble {
	display: none;
}

main:has(#massedit-toggle:checked) #library-container {
	overflow-y: hidden;
}

:root {
	/* Mask sources for the table's monitored toggle. Same shapes as `icons`
	   in general.js, as images rather than elements -- see `.table-monitored`. */
	--icon-monitored: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M2.849,23.55a2.954,2.954,0,0,0,3.266-.644L12,17.053l5.885,5.853a2.956,2.956,0,0,0,2.1.881,3.05,3.05,0,0,0,1.17-.237A2.953,2.953,0,0,0,23,20.779V5a5.006,5.006,0,0,0-5-5H6A5.006,5.006,0,0,0,1,5V20.779A2.953,2.953,0,0,0,2.849,23.55Z'/%3E%3C/svg%3E");
	--icon-unmonitored: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.137,24a2.8,2.8,0,0,1-1.987-.835L12,17.051,5.85,23.169a2.8,2.8,0,0,1-3.095.609A2.8,2.8,0,0,1,1,21.154V5A5,5,0,0,1,6,0H18a5,5,0,0,1,5,5V21.154a2.8,2.8,0,0,1-1.751,2.624A2.867,2.867,0,0,1,20.137,24ZM6,2A3,3,0,0,0,3,5V21.154a.843.843,0,0,0,1.437.6h0L11.3,14.933a1,1,0,0,1,1.41,0l6.855,6.819a.843.843,0,0,0,1.437-.6V5a3,3,0,0,0-3-3Z'/%3E%3C/svg%3E");
}

/*  */
/* Tool Bar */
/*  */
#sort-button {
	width: 9rem;
}

/*  */
/* Library List */
/*  */
#list-library {
	--entry-width: clamp(7rem, 11%, 9rem);
	display: flex;
	align-items: flex-start;
	flex-wrap: wrap;
	gap: 1rem;
}

.list-entry {
	flex-grow: 1;
	width: var(--entry-width);
	display: flex;
	flex-direction: column;
	justify-content: center;

	text-decoration: none;
	color: var(--dimmed-text-color);
	background-color: var(--foreground-color);
	border-radius: 1px;

	/* No `content-visibility: auto` here, deliberately. It was added when the
	   grid held a shell for every volume -- thousands of them -- and skipping
	   style and paint on the far ones was worth a great deal. Windowing
	   replaced that: about a hundred and thirty cards exist at once now, and
	   skipping paint on the handful outside the viewport saves almost
	   nothing.

	   What it cost was correctness. A skipped card is laid out at
	   `contain-intrinsic-size` rather than its real height -- 15rem against a
	   real 14rem here -- and takes its true height only when it nears the
	   viewport. So every row that came into view shrank by a rem, sliding
	   everything below it up: 95px of drift over six rows, which is how the
	   alphabet rail landed on the K's when it said M. Cards that are all the
	   same height make the spacers, the scrollbar and the rail all tell the
	   truth. */

	transition: box-shadow 200ms ease-in;
}

.list-entry:hover {
	box-shadow: 0 0 12px #000;
	text-decoration: none;
}

.list-img {
	display: block;
	width: 100%;
	aspect-ratio: 2/3;
	object-fit: cover;
	background-color: var(--tool-bar-color);
}

/* A source-less image is an intentional skeleton slot. The real cover URL is
   attached only when the card comes near the viewport. */
.list-img:not([src]) {
	background-image: linear-gradient(
		110deg,
		var(--tool-bar-color),
		var(--foreground-color),
		var(--tool-bar-color)
	);
	background-size: 200% 100%;
}

.list-entry > :where(h2, p) {
	padding: .1rem .2rem;
	text-align: center;
	white-space: nowrap;
	text-overflow: ellipsis;
	overflow-x: hidden;
	font-size: clamp(.65rem, .8vw, .75rem);
	font-weight: 400;
}

.list-entry[monitored] .list-unmonitored,
.list-entry:not([monitored]) .list-monitored {
	display: none;
}

.list-prog-container,
.table-prog-container {
	position: relative;

	overflow: hidden;
	display: flex;
	justify-content: center;

	color: var(--light-color);
	background-color: var(--tool-bar-color);

	text-align: center;
	font-size: clamp(.65rem, .8vw, .75rem);
}

.list-prog-bar,
.table-prog-bar {
	position: absolute;
	inset: 0;
	background-color: var(--error-color);
	
	transition: width 150ms ease-in-out,
				background-color 150ms ease-in-out;
}

.list-prog-num,
.table-prog-num {
	z-index: 1;
}

.list-download-status {
	border-radius: 0;
}

.table-download-status {
	min-width: 8rem;
	margin-top: .25rem;
	text-align: center;
	white-space: nowrap;
}

/* A full-width flex item, so it forces a line break and stands in for
   whole rows of cards rather than sitting beside one. */
#list-library > .library-spacer {
	width: 100%;
	flex: 0 0 100%;
}

.space-taker {
	height: 1rem;
	max-width: 100%;
	width: var(--entry-width);
	flex-grow: 127;
}

/*  */
/* Library Table */
/*  */
#table-container {
	width: 100%;
	overflow-x: auto;

	color: var(--text-color);
}

main:has(#massedit-toggle:checked) #table-container {
	height: 100%;
}

#table-container > table {
	width: max(100%, 26rem);
	border-collapse: collapse;

	/* Auto layout sizes columns by measuring every cell in the table. At
	   5,480 rows that is a full pass over 33,000 cells on every relayout,
	   and it measured at 2.7s of build-and-layout on a desktop against
	   0.8s fixed -- the difference between "slow" and "the tab is gone".
	   It is also what makes windowing possible at all: with auto layout
	   the columns would resize every time rows swapped in and out under
	   the scroll. */
	table-layout: fixed;
}

/* Fixed layout takes its columns from the first row, so they are stated
   once here. The title column is whatever is left. */
/* Everything except the title is a fixed, known shape: a four-digit year,
   a volume number, a ratio, an icon. They get exactly what they need and
   the title gets the rest, because the title is the only column anyone
   scans. At 390px the old numbers left it 60px -- 28px of that padding --
   which is one character and an ellipsis. */
/* The title takes whatever the others do not.
   `width: 100%` rather than leaving it unset: under `table-layout: fixed`
   an unset column is given a share of the remainder rather than all of it,
   and at 390px that share came to 90px against 180px of space actually
   free. Asking for the whole table and being cut down to the remainder is
   the deterministic way to say "the rest". */
#table-container :where(th, td):nth-child(2) { width: 100%; }
#table-container :where(th, td):nth-child(1) { width: 2.5rem; }
/* Wide enough for the heading, which is bold and so wider than the four
   digits or the single number beneath it, plus the 1rem of padding either
   side that this breakpoint keeps. */
#table-container :where(th, td):nth-child(3) { width: 5rem; }
#table-container :where(th, td):nth-child(4) { width: 4.2rem; }
#table-container :where(th, td):nth-child(5) { width: 7rem; }
#table-container :where(th, td):nth-child(6) { width: 4rem; }

/* Every row the same height, which is what lets the spacers above and
   below the window stand in for the rest of the library at an exact
   size. A title too long for its column gets an ellipsis and keeps its
   full text in the tooltip, rather than wrapping onto a second line and
   making that row taller than the ones the scrollbar was measured from. */
.table-entry > td:nth-child(2) {
	overflow: hidden;
}

.table-link {
	display: block;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

/* Stands in for the rows outside the window. Nothing but height. */
.library-spacer {
	padding: 0;
	border: 0;
}

#table-library > .library-spacer > td {
	padding: 0;
}

.table-volume {
	text-align: center;
}

.table-entry {
	border-top: 1px solid var(--border-color);
	transition: background-color 200ms ease-in-out;
}

.table-entry:hover {
	background-color: var(--hover-color);
}

#table-container :where(th, td) {
	padding-inline: 1rem;
	padding-block: .5rem;
}

/* A header wider than its column used to run into the next one -- at 390px
   "Progress" sat on top of "Monitored", which showed as "Mor". Columns are
   sized for their contents, so the header is the thing that has to give. */
#table-container th {
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

/* On a phone the padding was the layout: 16px each side of five columns
   is 160px of a 512px table, none of it showing anything. */
@media (max-width: 600px) {
	#table-container :where(th, td) {
		padding-inline: .4rem;
	}
	#table-container :where(th, td):nth-child(3) { width: 3rem; }
	#table-container :where(th, td):nth-child(4) { width: 2.3rem; }
	#table-container :where(th, td):nth-child(5) { width: 3.9rem; }
	#table-container :where(th, td):nth-child(6) { width: 2.2rem; }

	/* Sized for the header, not the data: "Year" set bold is wider than
	   the four digits underneath it, so at the body font the headings
	   were the thing forcing these columns open -- and when they were
	   not given the room, they clipped to "Y..." and "V...". */
	#table-container th {
		font-size: .68rem;
	}

	/* The bar still reads as a bar at this size; the ratio inside it is
	   what needs to shrink to stay legible rather than clipped. */
	.table-prog-container {
		font-size: .62rem;
	}

	.table-monitored {
		width: 1.15rem;
	}

	#table-container > table {
		width: 100%;
	}
}

.table-prog-container {
	min-width: 0;
	border-radius: 4px;
}

.table-monitored-container {
	width: min-content;
	display: flex;
	justify-content: center;
	align-items: center;
}

/* Drawn as a CSS mask rather than an inline SVG element.
   `LibraryEntry.renderMonitored` used to write the icon into every row with
   `innerHTML`, which cost one HTML-fragment parse per row at build time and
   left a live SVG element tree in each one. A table row is otherwise text, so
   on a large library the icons were the row: 5,000 of them is around 20,000
   SVG nodes carrying their own layout and paint objects, and mobile Chrome
   ran out of room part-way down the table.

   A mask keeps the same two shapes and the same `--dimmed-text-color` fill
   while adding no elements at all, and toggling monitored state becomes one
   attribute write instead of a reparse. */
.table-monitored {
	width: 1.5rem;
	aspect-ratio: 1;

	/* `button:has(img, svg)` in general.css supplied these while the icon was
	   an element inside the button. It no longer matches, and a button falls
	   back to the UA's own padding, which would push every row taller. */
	display: block;
	padding: 0;

	background-color: var(--dimmed-text-color);

	-webkit-mask-image: var(--icon-unmonitored);
	mask-image: var(--icon-unmonitored);
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
}

.table-monitored[data-monitored="true"] {
	-webkit-mask-image: var(--icon-monitored);
	mask-image: var(--icon-monitored);
}

/*  */
/* Lib stats */
/*  */
#lib-stats {
	width: 100%;
	display: flex;
	flex-wrap: wrap;
	gap: clamp(.5rem, 4vw, 3rem);

	padding-top: 2rem;
	color: var(--text-color);

	font-size: .8rem;
}

#lib-stats th {
	padding-right: 1rem;
	padding-block: .25rem;
	text-align: right;
}

/*  */
/* Mass Editor */
/*  */
/* `tr:not(.library-spacer)` matters: a spacer row holds exactly one cell,
   which is therefore always `:first-child`. Hiding it collapsed the spacer
   to nothing, so the table claimed the height of its window instead of the
   height of the library and the scrollbar never reached past the first
   screen of rows. */
main:not(:has(#massedit-toggle:checked)) #table-container
	tr:not(.library-spacer) > :where(td, th):first-child {
	display: none;
}

.action-bar {
	margin-bottom: 1rem;
	position: sticky;
	top: 0px;
	z-index: 2;

	display: none;
	flex-wrap: wrap;
	gap: 1rem;

	padding: .5rem;
	border-radius: 4px;
	background-color: var(--tool-bar-color);
}

main:has(#massedit-toggle:checked) .action-bar {
	display: flex;
}

.action-divider {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
}

.action-bar button {
	min-width: 5rem;

	border: 2px solid var(--border-color);
	border-radius: 4px;
	padding: .4rem .5rem;
	color: var(--text-color);
	background-color: var(--background-color);

	transition: background-color 100ms linear;
}

.action-bar button:hover {
	background-color: var(--foreground-color);
}

.option-container {
    display: flex;
    justify-content: space-between;

	overflow: hidden;
	border-radius: 4px;
	border: 2px solid var(--border-color);
	background-color: var(--background-color);
}

.option-container button {
    min-width: 6.8rem;
	border-radius: 0px;
	border: none;
}

.option-container select {
    flex-grow: 1;
	height: 100%;
	background-color: var(--background-color);
	color: var(--text-color);
}

#cancel-massedit {
	background-color: var(--error-color);
	border-color: var(--error-color);
}

main:has(#massedit-toggle:checked) #lib-stats {
	display: none;
}

@media (max-width: 860px) {
	.action-bar {
        flex-direction: column;
		justify-content: center;
	}
	.action-divider {
		width: 100%;
	}
	.action-divider > *,
	.action-divider  {
        flex: 1 1 0;
	}
    .action-divider > .option-container {
        flex: 1 1 auto;
    }
}

@media (max-width: 535px) {
	header {
		justify-content: flex-start;
	}

	#lib-stats {
		flex-direction: column;
	}

	#lib-stats th {
		width: 50%;
	}
}

@media (max-width: 442px) {
	#library-container {
		padding: 1rem;
	}

	/* Bigger target and more room to move on the surface where the rail is
	   most of the point. */
	.alphabet-letter {
		font-size: .7rem;
		padding: .05rem .35rem;
	}

	#alphabet-bubble {
		right: 3.25rem;
	}

	#list-library {
		gap: .75rem;
	}
}