/*
 * Single video page.
 *
 * Conditionally enqueued — is_singular('post') only. The homepage renders a grid
 * of 40 cards and must not pay for any of this. See inc/enqueue.php.
 *
 * Tokens only.
 */

.tt-single {
	padding-top: var(--tt-s4);
}

/* ---------------------------------------------------------------- layout */

/*
 * Two columns on desktop: a flexible main column and a fixed 340px sidebar for
 * "Nová videa". minmax(0, 1fr) — NOT plain 1fr — so the main column can shrink
 * below its content's intrinsic width; without it the related-video .tt-grid
 * inside pushes the whole column wide and the sidebar off the row.
 *
 * The sidebar is the LAST grid child, so on one column (mobile) it stacks at the
 * very bottom of the page, after the related grid and the models strip.
 */
.tt-single__grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: var(--tt-s5);
	align-items: start;
}

.tt-single__main {
	min-width: 0;
}

@media (min-width: 1024px) {
	.tt-single__grid {
		grid-template-columns: minmax(0, 1fr) 340px;
	}
}

/* ---------------------------------------------------------------- player */

/*
 * Direct source embed, dropped into a responsive 16:9 box so it scales on every
 * width. (The old click-to-load facade was removed by owner decision — see
 * template-parts/single/player.php.)
 */
.tt-player--raw {
	position: relative;
	aspect-ratio: var(--tt-thumb-ratio);
	overflow: hidden;
	border-radius: var(--tt-radius);
	background: var(--tt-bg-raised);
}

.tt-player--raw iframe,
.tt-player--raw video,
.tt-player--raw embed,
.tt-player--raw object {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}


/* No embed at all */
.tt-player--empty {
	display: grid;
	place-items: center;
	cursor: default;
}

.tt-player__msg {
	margin: 0;
	color: var(--tt-text-muted);
	font-size: var(--tt-fs-md);
}

/* ---------------------------------------------------------------- title + views */

.tt-single__title {
	margin: var(--tt-s4) 0 var(--tt-s2);
	font-size: clamp(1.1rem, 2.5vw, var(--tt-fs-3xl));
	line-height: 1.3;
}

.tt-single__views {
	margin: 0 0 var(--tt-s4);
	color: var(--tt-text-muted);
	font-size: var(--tt-fs-sm);
	font-variant-numeric: tabular-nums;
}

/* Rendered hidden at 0 views; viewCounter reveals it after the REST bump. Explicit
   so an author display rule can never beat the [hidden] attribute (a known trap). */
.tt-single__views[hidden] {
	display: none;
}

/* ---------------------------------------------------------------- share */

.tt-share {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--tt-s2);
	margin: 0 0 var(--tt-s4);
}

/* Share + chip row labels share one look and one width so SDÍLET / MODELKY /
   KATEGORIE / ŠTÍTKY line up and every chip row starts at the same x. */
.tt-share__label,
.tt-chips__label {
	flex: 0 0 auto;
	min-width: 78px;
	color: var(--tt-text-muted);
	font-size: var(--tt-fs-2xs);
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: 0.06em;
}

.tt-share__btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px var(--tt-s3);
	border: 1px solid var(--tt-border);
	border-radius: var(--tt-radius-pill);
	background: var(--tt-bg-surface);
	color: var(--tt-text);
	font-size: var(--tt-fs-sm);
	font-weight: 600;
	line-height: 1;
	cursor: pointer;
	transition: background var(--tt-speed), border-color var(--tt-speed), color var(--tt-speed);
}

.tt-share__btn svg {
	flex: 0 0 auto;
}

.tt-share__btn:hover {
	border-color: var(--tt-accent);
	color: var(--tt-accent);
}

.tt-share__btn--copy.is-copied {
	border-color: var(--tt-info);
	color: var(--tt-info);
}

/* ---------------------------------------------------------------- chips */

.tt-chips {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--tt-s2);
	margin-bottom: var(--tt-s3);
}

.tt-chips__list {
	display: flex;
	flex-wrap: wrap;
	gap: var(--tt-s2);
}

.tt-chip {
	display: inline-block;
	padding: 5px var(--tt-s3);
	border: 1px solid var(--tt-border);
	border-radius: var(--tt-radius-pill);
	background: var(--tt-bg-surface);
	color: var(--tt-text);
	font-size: var(--tt-fs-sm);
	font-weight: 500;
	line-height: 1.4;
	transition: border-color var(--tt-speed), color var(--tt-speed), background var(--tt-speed);
}

.tt-chip:hover {
	border-color: var(--tt-accent);
	background: var(--tt-bg-raised);
	color: var(--tt-accent);
}

/*
 * Actors are the highest-value link on the page — 159 real terms. A SOLID accent
 * fill (not just an accent border) makes the model name the thing the eye lands
 * on in the meta block, clearly primary over categories and tags.
 */
.tt-chip--actor {
	border-color: var(--tt-accent);
	background: var(--tt-accent);
	color: var(--tt-accent-contrast);
	font-weight: 700;
	box-shadow: 0 2px 8px color-mix(in srgb, var(--tt-accent) 30%, transparent);
}

.tt-chip--actor:hover {
	border-color: var(--tt-accent-dark);
	background: var(--tt-accent-dark);
	color: var(--tt-accent-contrast);
}

/* ---------------------------------------------------------------- description + read-more */

.tt-readmore {
	margin: var(--tt-s5) 0;
}

.tt-single__content {
	/* Full width of its container — the 70ch reading cap was removed by request. */
	max-width: none;
	/* Reading text — see the note on .tt-prose in components.css. */
	color: var(--tt-text);
	/*
	 * 14px by owner request (0.35.10), down from 15px, after --tt-maxw dropped to
	 * 1280 and the rest of the type came with it. It is the low end for 400+ word
	 * prose, so it is a deliberate choice rather than a default: do not "correct"
	 * it back up.
	 */
	font-size: var(--tt-fs-md);
}

/*
 * Prose links inside a video description MUST be re-styled here.
 * base.css sets `a { color: inherit; text-decoration: none }` globally, so an
 * <a> in body copy renders identical to the text around it and is invisible
 * until hover. .tt-archive-desc already carries this override, which is why
 * links show on category and model pages; descriptions had no equivalent, so
 * the 2 do 3 internal links every new import carries (owner, 2026-08-25) were
 * rendering as plain text. Nothing reports this: the anchors are in the HTML,
 * they resolve 200, and every render check passes. Same class of bug as the
 * partner-tile label and the logo variants.
 */
.tt-single__content a {
	color: var(--tt-accent);
}

.tt-single__content a:hover {
	text-decoration: underline;
}

/* The wrapper owns the block's outer spacing; the body only the inner rhythm. */
.tt-readmore__body {
	margin: 0;
}

/*
 * Collapsed: clamp to 4 lines. -webkit-line-clamp is what makes scrollHeight >
 * clientHeight when there's more text, which is exactly the overflow test
 * readMore() in main.js uses to decide whether to keep the toggle.
 */
.tt-readmore__body.is-collapsed {
	display: -webkit-box;
	-webkit-line-clamp: 4;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.tt-readmore__toggle {
	margin-top: var(--tt-s2);
	padding: 6px var(--tt-s3);
	border: 1px solid var(--tt-border);
	border-radius: var(--tt-radius-pill);
	background: var(--tt-bg-surface);
	color: var(--tt-accent);
	font-size: var(--tt-fs-sm);
	font-weight: 700;
	cursor: pointer;
	transition: border-color var(--tt-speed);
}

.tt-readmore__toggle:hover {
	border-color: var(--tt-accent);
}

/* ---------------------------------------------------------------- related + models */

.tt-related {
	margin-top: var(--tt-s7);
}

/* The reused homepage models strip needs top separation from the related grid. */
.tt-single__main .tt-models {
	margin-top: var(--tt-s7);
}

/* NOTE: .tt-section-title / .tt-models live in components.css (loaded globally),
   not here — search.php, 404.php and the homepage use them too. */

/* ---------------------------------------------------------------- sidebar rail */

.tt-single__aside {
	min-width: 0;
}

/*
 * The wrapper moved out of the rail template part in v0.21.0 so the article page
 * could stack two blocks in one column. That handed the column a new failure
 * mode: when every block inside bails, the <aside> still exists and the grid
 * holds its 340px track open — a dead gap where the sidebar used to simply not
 * be. `:empty` restores the old behaviour declaratively.
 *
 * Safe because the aside's only children are the blocks themselves; :empty is
 * whitespace-sensitive, and PHP that outputs nothing outputs nothing.
 */
.tt-single__aside:empty {
	display: none;
}

/* Stacked rail blocks (popular videos + more articles on an article page). */
.tt-upnext + .tt-upnext {
	margin-top: var(--tt-s4);
}

@media (min-width: 1024px) {
	/* Follow the scroll on desktop. Small offset — the header is no longer sticky,
	   so there's nothing to clear beyond a little breathing room. */
	.tt-single__aside {
		position: sticky;
		top: var(--tt-s4);

		/*
		 * ⚠️ THIS IS A CORRECTNESS RULE, NOT POLISH (v0.21.3).
		 *
		 * A `position: sticky` element TALLER than the viewport pins at its top
		 * edge and everything past the fold becomes permanently unreachable:
		 * scrolling moves the page, not the pinned column, so the bottom of the
		 * sidebar can never be brought into view. There is no pure-CSS
		 * "scroll-then-stick-to-bottom"; that needs JS.
		 *
		 * This caught the article page in v0.21.2, where a 10-row video rail
		 * pushed the whole articles block into that dead zone. Reordering the
		 * blocks and cutting the rail to 5 fixed THAT instance, but the bug comes
		 * back the moment anyone adds a block, raises a count, or opens the site
		 * on a short laptop screen.
		 *
		 * Capping the height at the viewport and letting the column scroll
		 * internally removes the failure mode entirely: content may need
		 * scrolling, but it can never be unreachable. The overflow only engages
		 * when the column genuinely doesn't fit, so on a normal desktop nothing
		 * changes visually.
		 */
		max-height: calc(100vh - var(--tt-s4) * 2);
		overflow-y: auto;
		overscroll-behavior: contain;
		scrollbar-width: none;
	}

	.tt-single__aside::-webkit-scrollbar {
		display: none;
	}
}

.tt-upnext {
	padding: var(--tt-s3);
	border: 1px solid var(--tt-border);
	border-radius: var(--tt-radius);
	background: var(--tt-bg-surface);
}

.tt-upnext__title {
	margin: 0 0 var(--tt-s3);
	font-size: var(--tt-fs-lg);
	font-weight: 800;
}

.tt-upnext__list {
	display: flex;
	flex-direction: column;
	gap: var(--tt-s2);
	margin: 0;
	padding: 0;
	list-style: none;
}

.tt-upnext__link {
	display: flex;
	gap: var(--tt-s3);
	padding: var(--tt-s2);
	border-radius: var(--tt-radius);
	transition: background var(--tt-speed);
}

.tt-upnext__link:hover {
	background: var(--tt-bg-raised);
}

.tt-upnext__media {
	flex: 0 0 132px;
	aspect-ratio: var(--tt-thumb-ratio);
	overflow: hidden;
	border-radius: calc(var(--tt-radius) - 2px);
	background: var(--tt-bg-raised);
}

.tt-upnext__thumb {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.tt-upnext__body {
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.tt-upnext__name {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	color: var(--tt-text);
	font-size: var(--tt-fs-sm);
	font-weight: 600;
	line-height: 1.35;
}

.tt-upnext__views {
	color: var(--tt-text-muted);
	font-size: var(--tt-fs-xs);
	font-variant-numeric: tabular-nums;
}
