/* The SNL cast timeline (/nerd-alert/snl-cast-history). The markup is plain
   lists - seasons, then cast members with their stints - and this file turns
   them into one grid: a name column, then one column per season. Every
   list inside shares the grid's columns through subgrid, so a stint is
   placed by its season numbers alone (--from / --to, written by the
   template; --to is the line after the last season).

   The season columns are drawn on top of the bars and let the pointer
   through: they carry the gridlines, the fade on seasons not yet watched,
   and the hover highlight. Light vs dark encodes featured vs repertory. */

.snl-cast-history {
	.key {
		display: flex;
		gap: 1.5em;
		margin-top: 1em;

		li {
			display: flex;
			align-items: center;
			gap: 0.5em;
		}

		li::before {
			content: '';
			width: 1.5em;
			height: var(--stint-height);
			background: var(--stint-color);
		}
	}

	.source {
		margin-top: 1.5em;
	}

	.source + p {
		margin-top: 0.25em;
	}
}

/* The two roles, as the slots the bars and the key both read. */
.snl-cast-history [data-role] {
	--stint-height: 0.6em;
	--stint-color: var(--ink-primary);

	&[data-role='featured'] {
		--stint-color: var(--ink-auxiliary);
	}
}

cast-timeline {
	--name-measure: 11em;
	--season-min: 1.75em;
	--unwatched-veil: 65%;
	--dimmed: 0.2;

	--highlight-mix: 15%;

	/* Two explicit rows - the season numbers, then the cast - so the season
	   columns can span both (1 / -1). The top padding is room for the marker's
	   label, which the horizontal scroll would otherwise clip. */
	display: grid;
	grid-template-columns: var(--name-measure) repeat(var(--season-count), minmax(var(--season-min), 1fr));
	grid-template-rows: auto auto;
	position: relative;
	isolation: isolate;
	margin-top: 1.5em;
	padding-top: 1.5em;
	overflow-x: auto;

	.cast,
	.member {
		display: grid;
		grid-column: 1 / -1;
		grid-template-columns: subgrid;
	}

	.seasons,
	.season-columns,
	.stints {
		display: grid;
		grid-column: 2 / -1;
		grid-template-columns: subgrid;
	}

	.seasons {
		grid-row: 1;
		padding-bottom: 0.5em;
		text-align: center;
	}

	.season {
		position: relative;
	}

	/* The rewatch marker's label sits above the column it marks. */
	.here {
		position: absolute;
		bottom: 100%;
		left: 50%;
		translate: -50% 0;
		white-space: nowrap;
	}

	.cast {
		grid-row: 2;
	}

	.member {
		align-items: center;
		transition: opacity 0.2s;
	}

	/* A name longer than its column wraps rather than being cut off - the
	   whole name is the point of the row. On a screen too narrow for every
	   season the timeline scrolls sideways, and the names stay put so a
	   bar never loses its person; the paper behind them covers the bars
	   (and the season columns, z 1) sliding underneath. */
	.name {
		position: sticky;
		left: 0;
		z-index: 2;
		align-self: stretch;
		display: flex;
		align-items: center;
		padding-inline-end: 1em;
		background: var(--fill-primary);
	}

	.stints {
		grid-row: 1;
	}

	.stint {
		grid-column: var(--from) / var(--to);
		height: var(--stint-height);
		background: var(--stint-color);
	}

	.season-columns {
		grid-row: 1 / -1;
		z-index: 1;
		pointer-events: none;

		span {
			border-inline-start: 1px solid var(--stroke-secondary);
		}

		span:not([data-watched]) {
			background: color-mix(in oklab, var(--fill-primary) var(--unwatched-veil), transparent);
		}

		span[data-here] {
			border-inline-end: 2px solid var(--accent);
		}

		span.is-highlighted {
			background: color-mix(in oklab, var(--accent) var(--highlight-mix), transparent);
		}
	}

	/* Hovering a season: its cast stays, everyone else steps back. */
	&[data-highlight] .member:not(.is-in-season) {
		opacity: var(--dimmed);
	}
}
