/*
 * MBP Shorts
 *
 * Every colour is a custom property declared on .mbp-shorts, so a site with a
 * different palette overrides the block rather than this file. The defaults
 * are the MamboPerv Dark Cinema tokens.
 */

.mbp-shorts,
.mbp-shorts-grid,
.mbp-shorts-rail {
	--mbp-s-bg: #1B202B;
	--mbp-s-surface: #242A38;
	--mbp-s-raised: #2B3242;
	--mbp-s-ink: #FFFFFF;
	--mbp-s-muted: #BFC6D6;
	--mbp-s-accent: #C348AF;
	--mbp-s-radius: 5px;
	--mbp-s-font: Poppins, sans-serif;
}

/* ---------------------------------------------------------------- feed shell */

/*
 * On a shorts page the feed is the page. It sits above the theme header
 * (which tops out at z-index 250) and well below the age verification overlay
 * at 999999, which must always stay in front of it.
 */
body.mbp-shorts-page {
	overflow: hidden;
}

body.mbp-shorts-page .mbp-shorts {
	position: fixed;
	inset: 0;
	z-index: 800;
	background: var(--mbp-s-bg);
}

.mbp-shorts {
	position: relative;
	background: var(--mbp-s-bg);
	font-family: var(--mbp-s-font);

	/*
	 * The video box, not the slide.
	 *
	 * A slide is the whole viewport; the picture inside it is a 9:16 box
	 * fitted to height. The caption, the side rail and the description sheet
	 * all belong to the picture, so they are sized and placed from these two
	 * numbers rather than from the slide's edges -- otherwise on a desktop
	 * the caption runs the full width of the screen and the rail floats off
	 * near the window frame, hundreds of pixels from the video.
	 */
	--mbp-s-inset: 16px;
	/* Height-driven, but capped by the width the slide actually leaves: on a
	   very tall viewport the 9:16 box runs out of width first, and the stage's
	   own max-width caps it against the content box, gutters excluded. */
	--mbp-s-stage-w: min(
		calc(100% - var(--mbp-s-inset) * 2),
		calc((100dvh - var(--mbp-s-inset) * 2) * 9 / 16)
	);

	/*
	 * Clearance for the Bunny player's control bar along the bottom of the
	 * iframe. Two rows: Plyr moves the progress bar onto its own line at the
	 * width a 9:16 box has at any normal screen height, and the library's
	 * Custom HTML head enlarges the icons. That bar is cross-origin and
	 * cannot be measured, so this is an estimate -- it is the one number to
	 * nudge (or drop to 0) if the caption sits too close to it, or if those
	 * controls are ever turned off.
	 */
	--mbp-s-controlbar: 80px;

	/*
	 * How much of the picture the caption is allowed to take, and how much of
	 * the description shows before the tap target. Both are deliberately
	 * small: the caption is a label on a video, not a paragraph printed over
	 * one, and the full text is one tap away in the sheet. These are the two
	 * numbers to change if it should say more, or less.
	 */
	/* A multiplier, not a percentage: this is multiplied by a length, and
	   length * percentage is invalid -- the declaration would be dropped and
	   the box would quietly fall back to shrink-to-fit. */
	--mbp-s-caption-w: .72;
	--mbp-s-desc-w: 15ch;

	/* Legibility over moving video now that no scrim sits behind the text:
	   a tight shadow for edge definition, a soft one to knock back a bright
	   background behind the glyphs. */
	--mbp-s-textshadow: 0 1px 3px rgba(0, 0, 0, .9), 0 0 14px rgba(0, 0, 0, .55);

	/* Overridden per site from Shorts -> Settings -> Caption, as an inline
	   style on this element. Percentages because that is what both `opacity`
	   and `color-mix` take, so the number crosses from PHP to CSS unconverted. */
	--mbp-s-desc-opacity: 100%;
	--mbp-s-cta-opacity: 80%;
}

.mbp-shorts__track {
	height: 100dvh;
	overflow-y: scroll;
	overflow-x: hidden;
	scroll-snap-type: y mandatory;
	scroll-behavior: smooth;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
	outline: none;
}

.mbp-shorts__track::-webkit-scrollbar {
	display: none;
}

@media (prefers-reduced-motion: reduce) {
	.mbp-shorts__track {
		scroll-behavior: auto;
	}
}

/* ---------------------------------------------------------------- one slide */

.mbp-short {
	position: relative;
	height: 100dvh;
	scroll-snap-align: start;
	scroll-snap-stop: always;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--mbp-s-inset);
	box-sizing: border-box;
}

/*
 * 9:16, fitted to whichever of height or width runs out first. The area either
 * side of it on a desktop is left as flat ground -- no blurred backdrop, which
 * would be decoration the design direction rules out.
 */
.mbp-short__stage {
	position: relative;
	height: 100%;
	aspect-ratio: 9 / 16;
	max-width: 100%;
	background: #000;
	border-radius: var(--mbp-s-radius);
	overflow: hidden;
}

.mbp-short__poster,
.mbp-short__stage iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
	display: block;
}

.mbp-short__poster {
	object-fit: cover;
}

/* Once the player is mounted the poster is only there to cover the iframe's
   own start-up flash, so it goes as soon as playback is under way. */
.mbp-short.is-playing .mbp-short__poster {
	opacity: 0;
	transition: opacity .15s linear;
}

.mbp-short__player {
	position: absolute;
	inset: 0;
}

/* ---------------------------------------------------------------- overlays */

.mbp-short__meta {
	position: absolute;
	/* The picture's own bottom-left corner. */
	left: calc(50% - var(--mbp-s-stage-w) / 2);
	bottom: var(--mbp-s-inset);
	width: calc(var(--mbp-s-stage-w) * var(--mbp-s-caption-w));
	box-sizing: border-box;
	/* The bottom clears the player's own controls. */
	padding: 8px 8px calc(var(--mbp-s-controlbar) + 12px) 16px;
	pointer-events: none;
	/*
	 * No scrim. A full-width gradient darkened the whole bottom of the frame
	 * to make room for two lines of text, which is the thing that read as
	 * fighting the video; a box this small would look worse still with a dark
	 * rectangle behind it. Legibility comes from the text shadows below
	 * instead -- the same trade TikTok makes.
	 */
}

.mbp-short__meta > * {
	pointer-events: auto;
}

.mbp-short__title {
	margin: 0 0 4px;
	font-family: var(--mbp-s-font);
	font-weight: 700;
	font-size: 1rem;
	line-height: 1.3;
	/* A long title must not grow the box up the frame. */
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	text-shadow: var(--mbp-s-textshadow);
}

.mbp-short__title a {
	color: var(--mbp-s-ink);
	text-decoration: none;
}

.mbp-short__terms {
	margin: 0 0 10px;
	font-size: .8rem;
	line-height: 1.5;
	color: var(--mbp-s-muted);
	text-shadow: var(--mbp-s-textshadow);
}

.mbp-short__terms a,
.mbp-short__terms span {
	color: var(--mbp-s-muted);
	text-decoration: none;
	margin-right: 10px;
}

.mbp-short__terms a:hover {
	color: var(--mbp-s-ink);
}

.mbp-short__cta {
	display: inline-block;
	/* Solid first as the fallback, then the same accent with a little of the
	   picture showing through. The blur is what keeps the label readable: it
	   softens whatever is moving behind without hiding that something is. */
	background: var(--mbp-s-accent);
	background: color-mix(in srgb, var(--mbp-s-accent) var(--mbp-s-cta-opacity), transparent);
	-webkit-backdrop-filter: blur(4px);
	backdrop-filter: blur(4px);
	color: var(--mbp-s-ink);
	font-weight: 600;
	font-size: .82rem;
	line-height: 1;
	padding: 10px 16px;
	border-radius: var(--mbp-s-radius);
	text-decoration: none;
}

.mbp-short__cta:hover,
.mbp-short__cta:focus {
	color: var(--mbp-s-ink);
	filter: brightness(1.08);
}

/* ---------------------------------------------------------------- side rail */

.mbp-short__rail {
	position: absolute;
	/* 10px inside the video's right edge, wherever that falls. */
	right: calc(50% - var(--mbp-s-stage-w) / 2 + 10px);
	bottom: calc(var(--mbp-s-inset) + var(--mbp-s-controlbar) + 20px);
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.mbp-short__btn,
.mbp-shorts__nav {
	width: 40px;
	height: 40px;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: 1px solid rgba(255, 255, 255, .16);
	border-radius: var(--mbp-s-radius);
	background: rgba(27, 32, 43, .72);
	color: var(--mbp-s-ink);
	cursor: pointer;
}

.mbp-short__btn:hover,
.mbp-shorts__nav:hover {
	background: var(--mbp-s-raised);
}

.mbp-short__btn:focus-visible,
.mbp-shorts__nav:focus-visible,
.mbp-short__cta:focus-visible {
	outline: 2px solid var(--mbp-s-accent);
	outline-offset: 2px;
}

/* The speaker icon shows one of its two states, never both. */
.mbp-short__btn--sound .mbp-icon-loud,
.mbp-short__btn--sound[aria-pressed="true"] .mbp-icon-muted {
	display: none;
}

.mbp-short__btn--sound[aria-pressed="true"] .mbp-icon-loud {
	display: block;
}

.mbp-short__btn.is-done {
	border-color: var(--mbp-s-accent);
}

/* ---------------------------------------------------------------- exit */

.mbp-shorts__back {
	position: absolute;
	top: 16px;
	left: 16px;
	z-index: 3;
	width: 40px;
	height: 40px;
	display: none;
	align-items: center;
	justify-content: center;
	border: 1px solid rgba(255, 255, 255, .16);
	border-radius: var(--mbp-s-radius);
	background: rgba(27, 32, 43, .72);
	color: var(--mbp-s-ink);
}

/* Only needed while the feed is covering the site's own header. */
body.mbp-shorts-page .mbp-shorts__back {
	display: flex;
}

.mbp-shorts__back:hover {
	background: var(--mbp-s-raised);
	color: var(--mbp-s-ink);
}

.mbp-shorts__back:focus-visible {
	outline: 2px solid var(--mbp-s-accent);
	outline-offset: 2px;
}

/* ---------------------------------------------------------------- feed nav */

.mbp-shorts__nav {
	position: absolute;
	right: 24px;
	z-index: 2;
}

.mbp-shorts__nav--up {
	top: calc(50% - 48px);
}

.mbp-shorts__nav--down {
	top: calc(50% + 8px);
}

.mbp-shorts__nav[disabled] {
	opacity: .35;
	cursor: default;
}

/* Pointer-driven affordance only -- on touch the gesture is the control. */
@media (max-width: 900px), (hover: none) {
	.mbp-shorts__nav {
		display: none;
	}
}

/* ---------------------------------------------------------------- end + empty */

.mbp-shorts__end,
.mbp-shorts-empty {
	height: 100dvh;
	scroll-snap-align: start;
	display: flex;
	align-items: center;
	justify-content: center;
	color: var(--mbp-s-muted);
	font-family: var(--mbp-s-font);
	font-size: .9rem;
	background: var(--mbp-s-bg);
}

.mbp-shorts-empty p {
	margin: 0;
	padding: 40px 16px;
	text-align: center;
}

.mbp-shorts__toast {
	position: absolute;
	left: 50%;
	bottom: 24px;
	transform: translateX(-50%);
	z-index: 3;
	background: var(--mbp-s-raised);
	color: var(--mbp-s-ink);
	font-family: var(--mbp-s-font);
	font-size: .8rem;
	padding: 8px 14px;
	border-radius: 999px;
}

/* ---------------------------------------------------------------- phones */

@media (max-width: 768px) {
	/* Fill the screen: at this width the viewport is already close to 9:16,
	   and a fitted box would leave bands top and bottom. With no gutter and a
	   full-width picture, the overlay geometry above collapses to the screen
	   edges on its own. */
	.mbp-shorts {
		--mbp-s-inset: 0px;
		--mbp-s-stage-w: 100%;
	}

	.mbp-short__stage {
		width: 100%;
		height: 100%;
		aspect-ratio: auto;
		border-radius: 0;
	}
}

/*
 * Touch targets.
 *
 * 40px is a fine pointer target and too small for a thumb -- both Android and
 * iOS put the minimum at around 48px. Sized up here rather than everywhere,
 * because on a desktop the smaller buttons intrude less on the picture.
 *
 * The offsets also lift the feed's own controls clear of the Bunny player's
 * control bar along the bottom of the iframe. That bar's contents are a
 * property of the Bunny library's player settings, not something this page can
 * change, so the overlay works around it: --mbp-s-controlbar is the one number
 * to adjust (or drop to 0) if those controls are ever turned off.
 */
@media (hover: none), (max-width: 768px) {
	/* No letterbox gutter on a touch screen -- it would only cost video.
	   Portrait already dropped it above; this picks up landscape too, where the
	   viewport is wider than 768px. */
	.mbp-shorts {
		--mbp-s-inset: 0px;
	}

	.mbp-short__btn,
	.mbp-shorts__back {
		width: 56px;
		height: 56px;
		touch-action: manipulation;
	}

	.mbp-short__btn svg,
	.mbp-shorts__back svg {
		width: 26px;
		height: 26px;
	}

	.mbp-short__rail {
		right: calc(50% - var(--mbp-s-stage-w) / 2 + 12px);
		bottom: calc(var(--mbp-s-controlbar) + 24px + env(safe-area-inset-bottom, 0px));
		gap: 14px;
	}

	.mbp-short__meta {
		padding: 8px 8px calc(var(--mbp-s-controlbar) + 12px + env(safe-area-inset-bottom, 0px)) 16px;
	}

	.mbp-short__title {
		font-size: 1.05rem;
	}

	.mbp-short__terms {
		font-size: .85rem;
	}

	/* The CTA is the whole point of the feed, so it gets a real button's
	   height rather than the compact desktop treatment. */
	.mbp-short__cta {
		font-size: .95rem;
		padding: 14px 22px;
		min-height: 48px;
		display: inline-flex;
		align-items: center;
		touch-action: manipulation;
	}

	.mbp-shorts__back {
		top: calc(12px + env(safe-area-inset-top, 0px));
		left: 12px;
	}
}

/*
 * Landscape on a phone.
 *
 * The viewport is wider than the portrait breakpoint, so the full-bleed rule
 * above does not apply and the stage stays fitted to its 9:16 box. That part
 * is right: rotating does not give the video more room, because at 9:16 the
 * height is the limit and the height just got shorter. Stretching the stage
 * full-width would only detach the player's control bar from the video it
 * belongs to.
 *
 * What used to be wrong here -- the overlay positioned against the slide,
 * stranding the title in the bottom-left corner of the screen with the picture
 * in the middle -- is now handled for every viewport by --mbp-s-stage-w. All
 * that is left is tighter padding, because vertical space is what ran out.
 */
@media (hover: none) and (orientation: landscape) {
	.mbp-short__meta {
		padding: 8px 8px calc(var(--mbp-s-controlbar) + 8px) 12px;
	}

	.mbp-short__rail {
		bottom: calc(var(--mbp-s-controlbar) + 12px);
	}
}

/* ------------------------------------------------------- grid + rail shell */

.mbp-shorts-grid,
.mbp-shorts-rail {
	margin: 0 0 36px;
	font-family: var(--mbp-s-font);
}

.mbp-shorts-head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	margin-bottom: 10px;
	padding-bottom: 10px;
	border-bottom: 1px solid rgba(191, 198, 214, .18);
}

.mbp-shorts-head__title {
	margin: 0;
	font-size: 1rem;
	font-weight: 700;
	color: var(--mbp-s-ink);
}

.mbp-shorts-head__all {
	font-size: .8rem;
	color: var(--mbp-s-accent);
	text-decoration: none;
	white-space: nowrap;
}

/* Column count comes from the shortcode as --mbp-s-cols, then steps down at
   each breakpoint -- a 9:16 card at six across is unreadable on a phone. */
.mbp-shorts-grid__items {
	display: grid;
	grid-template-columns: repeat(var(--mbp-s-cols, 6), minmax(0, 1fr));
	gap: 10px;
}

@media (max-width: 1200px) {
	.mbp-shorts-grid__items {
		grid-template-columns: repeat(min(var(--mbp-s-cols, 6), 4), minmax(0, 1fr));
	}
}

@media (max-width: 767px) {
	.mbp-shorts-grid__items {
		grid-template-columns: repeat(min(var(--mbp-s-cols, 6), 3), minmax(0, 1fr));
	}
}

@media (max-width: 480px) {
	.mbp-shorts-grid__items {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

.mbp-shorts-rail__strip {
	display: flex;
	gap: 10px;
	overflow-x: auto;
	scroll-snap-type: x proximity;
	padding-bottom: 6px;
	scrollbar-width: thin;
}

.mbp-shorts-rail__strip .mbp-shorts-card {
	flex: 0 0 150px;
	scroll-snap-align: start;
}

/* ---------------------------------------------------------------- card */

.mbp-shorts-card {
	position: relative;
	display: block;
	aspect-ratio: 9 / 16;
	border-radius: var(--mbp-s-radius);
	overflow: hidden;
	background: var(--mbp-s-surface);
	text-decoration: none;
}

/*
 * The theme sets a global `img { height: auto }`, which beats a bare `height`
 * here on specificity ties and lets the poster render at its natural size --
 * which is what makes one card fill the whole row. Pinned to the card box.
 */
.mbp-shorts-card img {
	width: 100%;
	height: 100%;
	max-width: none;
	object-fit: cover;
	display: block;
	margin: 0;
	border-radius: 0;
}

.mbp-shorts-card__play {
	position: absolute;
	top: 8px;
	left: 8px;
	width: 30px;
	height: 30px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: var(--mbp-s-radius);
	background: rgba(27, 32, 43, .72);
	color: var(--mbp-s-ink);
}

.mbp-shorts-card__label {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 24px 8px 8px;
	font-size: .75rem;
	line-height: 1.35;
	color: var(--mbp-s-ink);
	background: linear-gradient(to top, rgba(0, 0, 0, .8), rgba(0, 0, 0, 0));
}

.mbp-shorts-card:hover .mbp-shorts-card__play {
	background: var(--mbp-s-accent);
}

/*
 * Grid cards get the same hover the theme's own video thumbnails have: a 3%
 * lift plus an accent ring drawn as an overlay, so the border never shifts
 * the image inside the card. Scoped to the grid -- the rail scrolls inside an
 * overflow-x box, which would clip a scaled card.
 */
.mbp-shorts-grid__items .mbp-shorts-card {
	transition: transform 250ms ease-in-out;
}

.mbp-shorts-grid__items .mbp-shorts-card::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: var(--mbp-s-radius);
	border: 4px solid transparent;
	z-index: 5;
	pointer-events: none;
	transition: border-color 250ms ease-in-out;
}

.mbp-shorts-grid__items .mbp-shorts-card:hover {
	transform: scale(1.03);
	z-index: 20;
}

.mbp-shorts-grid__items .mbp-shorts-card:hover::after,
.mbp-shorts-grid__items .mbp-shorts-card:focus-visible::after {
	border-color: var(--mbp-s-accent);
}

@media (prefers-reduced-motion: reduce) {
	.mbp-shorts-grid__items .mbp-shorts-card:hover {
		transform: none;
	}
}

/* ------------------------------------------------------- members-only card */

/*
 * A locked card keeps its poster fully visible by default -- a short is a
 * teaser for a scene, and a poster nobody can make out sells nothing. Blur is
 * opt-in per short via the Blur field, which sets --mbp-s-blur inline and adds
 * .has-blur; without it no filter is applied at all.
 *
 * The slight scale-up only exists to push the blurred edges out of frame, so
 * it belongs with the blur rather than with .is-locked.
 */
.mbp-shorts-card.is-locked.has-blur img {
	filter: blur(var(--mbp-s-blur, 10px)) brightness(.66);
	transform: scale(1.08);
}

.mbp-shorts-card__lock {
	position: absolute;
	top: 8px;
	left: 8px;
	width: 30px;
	height: 30px;
	display: flex;
	align-items: center;
	justify-content: center;
	border-radius: var(--mbp-s-radius);
	background: var(--mbp-s-accent);
	color: var(--mbp-s-ink);
}

.screen-reader-text {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(1px, 1px, 1px, 1px);
	clip-path: inset(50%);
	white-space: nowrap;
}

/* ---------------------------------------------------------------- feed gate */

/* Same opt-in rule in the feed. The percentage resolves to a larger pixel
   value here than on a card, because the image is far larger. */
.mbp-short.is-locked.has-blur .mbp-short__poster {
	filter: blur(var(--mbp-s-blur, 20px)) brightness(.6);
	transform: scale(1.1);
}

/* Unblurred locked posters still need the gate to stay readable over them. */
.mbp-short.is-locked .mbp-short__gate {
	background: rgba(0, 0, 0, .45);
}

.mbp-short__gate {
	position: absolute;
	inset: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 4px;
	padding: 24px;
	text-align: center;
	font-family: var(--mbp-s-font);
	color: var(--mbp-s-ink);
}

.mbp-short__gate-icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	margin-bottom: 8px;
	border-radius: 50%;
	background: var(--mbp-s-raised);
	color: var(--mbp-s-ink);
}

.mbp-short__gate-title {
	margin: 0;
	font-size: 1.05rem;
	font-weight: 700;
}

.mbp-short__gate-text {
	margin: 0 0 14px;
	font-size: .85rem;
	color: var(--mbp-s-muted);
}

.mbp-short__gate-alt {
	margin-top: 10px;
	font-size: .82rem;
	color: var(--mbp-s-muted);
	text-decoration: underline;
}

.mbp-short__gate-alt:hover {
	color: var(--mbp-s-ink);
}

.mbp-shorts-card:focus-visible {
	outline: 2px solid var(--mbp-s-accent);
	outline-offset: 2px;
}

/* ------------------------------------------------- description + its sheet */

/*
 * One line under the title, then a tap target for the rest.
 *
 * The caption is deliberately never allowed to wrap. This overlay grows
 * upward, so a three-line description on a phone eats the picture and pushes
 * the "watch the full scene" button -- the reason the feed exists -- towards
 * the middle of the screen. The full text lives in the sheet instead.
 */
.mbp-short__desc {
	display: inline-flex;
	align-items: baseline;
	gap: 5px;
	max-width: 100%;
	margin: 0 0 8px;
	padding: 0;
	border: 0;
	background: none;
	color: var(--mbp-s-muted);
	font-family: var(--mbp-s-font);
	font-size: .82rem;
	line-height: 1.45;
	text-align: left;
	cursor: pointer;
	text-shadow: var(--mbp-s-textshadow);
	opacity: var(--mbp-s-desc-opacity);
}

/*
 * A teaser, not the description. Capped in characters rather than as a share
 * of the box so it reads the same on a phone and a desktop, and so the ellipsis
 * lands in roughly the same place either way.
 *
 * overflow:hidden is also what lets this shrink: a flex item keeps its
 * min-width:auto floor until its overflow stops being visible.
 */
.mbp-short__desc-line {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	max-width: var(--mbp-s-desc-w);
}

.mbp-short__desc:hover {
	color: var(--mbp-s-ink);
}

.mbp-short__desc:focus-visible {
	outline: 2px solid var(--mbp-s-accent);
	outline-offset: 2px;
}

/*
 * Both the description and the chips are switched off, so the caption is the
 * title alone.
 *
 * The box is anchored to the bottom of the picture, which means losing those
 * lines has already dropped the title as far as it goes -- what is left to
 * reclaim is the padding they were holding. It cannot sit lower than this: the
 * bottom padding is still reserving the player's own control bar.
 */
.mbp-shorts.is-title-only .mbp-short__meta {
	padding-top: 0;
}

.mbp-shorts.is-title-only .mbp-short__title {
	margin-bottom: 10px;
}

/* Carries the full text on the slide for the sheet to read. Never rendered
   here, and not left to the hidden attribute alone -- themes reset it. */
.mbp-short__desc-full {
	display: none;
}

/*
 * The sheet. One per feed, filled from whichever short is in view.
 *
 * visibility rather than display so it can slide, and so it is out of the tab
 * order while closed; the transition delay on the way out keeps it visible
 * for the length of the slide down.
 */
.mbp-shorts__sheet {
	position: absolute;
	left: 0;
	right: 0;
	bottom: var(--mbp-s-inset);
	z-index: 6;
	margin: 0 auto;
	/* Exactly over the picture, like the panel the YouTube app slides up. */
	width: var(--mbp-s-stage-w);
	max-height: 62%;
	display: flex;
	flex-direction: column;
	background: var(--mbp-s-surface);
	color: var(--mbp-s-ink);
	font-family: var(--mbp-s-font);
	border-top: 1px solid rgba(255, 255, 255, .1);
	/* Bottom corners match the video's own, which it is sitting on. */
	border-radius: 12px 12px var(--mbp-s-radius) var(--mbp-s-radius);
	transform: translateY(100%);
	visibility: hidden;
	transition: transform .22s ease, visibility 0s linear .22s;
}

.mbp-shorts__sheet.is-open {
	transform: none;
	visibility: visible;
	transition: transform .22s ease, visibility 0s;
}

@media (prefers-reduced-motion: reduce) {
	.mbp-shorts__sheet,
	.mbp-shorts__sheet.is-open {
		transition: none;
	}
}

.mbp-shorts__sheet-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 12px 8px 8px 16px;
}

.mbp-shorts__sheet-title {
	margin: 0;
	font-size: 1rem;
	font-weight: 700;
	color: var(--mbp-s-ink);
}

.mbp-shorts__sheet-close {
	flex: 0 0 auto;
	width: 40px;
	height: 40px;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: 0;
	border-radius: var(--mbp-s-radius);
	background: none;
	color: var(--mbp-s-muted);
	cursor: pointer;
}

.mbp-shorts__sheet-close:hover {
	background: var(--mbp-s-raised);
	color: var(--mbp-s-ink);
}

.mbp-shorts__sheet-close:focus-visible {
	outline: 2px solid var(--mbp-s-accent);
	outline-offset: -2px;
}

/*
 * pre-wrap: the description arrives as plain text with its blank lines intact,
 * which is what lets the PHP template and the JS render it identically without
 * either of them building markup out of it.
 *
 * overscroll-behavior matters more than it looks: without it, scrolling to the
 * end of a long description hands the gesture back to the snap track and jumps
 * the visitor to the next short.
 */
.mbp-shorts__sheet-body {
	overflow-y: auto;
	overscroll-behavior: contain;
	-webkit-overflow-scrolling: touch;
	padding: 0 16px calc(20px + env(safe-area-inset-bottom, 0px));
	font-size: .9rem;
	line-height: 1.6;
	color: var(--mbp-s-muted);
	white-space: pre-wrap;
	overflow-wrap: break-word;
}

@media (hover: none), (max-width: 768px) {
	/* 20px of text is a fine pointer target and far too small for a thumb.
	   The line keeps its single-line clamp; only the hit area grows. */
	.mbp-short__desc {
		font-size: .88rem;
		min-height: 44px;
		align-items: center;
		margin-bottom: 2px;
		touch-action: manipulation;
	}

	.mbp-shorts__sheet {
		max-height: 70%;
	}

	.mbp-shorts__sheet-close {
		width: 48px;
		height: 48px;
		touch-action: manipulation;
	}
}

/* Landscape leaves the sheet very little height, so let it take more of it.
   The width already follows the picture. */
@media (hover: none) and (orientation: landscape) {
	.mbp-shorts__sheet {
		max-height: 78%;
	}
}

/* Lightweight Shorts overlays. Keep touch targets generous without painting boxes. */
.mbp-shorts .mbp-short__meta {
 width:calc(var(--mbp-s-stage-w) - 68px);
 padding:8px 8px calc(var(--mbp-s-controlbar) + 14px + env(safe-area-inset-bottom, 0px)) 14px;
}
.mbp-shorts .mbp-short__title {font-size:18px;line-height:1.3;margin-bottom:4px;overflow-wrap:anywhere;}
.mbp-shorts .mbp-short__title a {font:inherit;color:var(--mbp-s-ink);}
.mbp-shorts .mbp-short__desc {display:flex;font-size:15px;line-height:1.45;min-height:44px;width:100%;opacity:1;color:var(--mbp-s-ink);margin:0;}
.mbp-shorts .mbp-short__desc-line {max-width:100%;white-space:nowrap;display:block;overflow:hidden;text-overflow:ellipsis;}
.mbp-shorts .mbp-short__terms {font-size:14px;max-height:22px;overflow:hidden;margin-bottom:6px;}
.mbp-shorts .mbp-short__cta {font-size:14px;line-height:1.3;min-height:44px;box-sizing:border-box;padding:10px 12px;display:inline-flex;align-items:center;background:rgba(27,32,43,.65);border:1px solid rgba(255,255,255,.45);color:var(--mbp-s-ink);text-shadow:var(--mbp-s-textshadow);}
.mbp-shorts .mbp-short__rail {gap:10px;right:calc(50% - var(--mbp-s-stage-w)/2 + 6px);bottom:calc(var(--mbp-s-inset) + var(--mbp-s-controlbar) + 14px + env(safe-area-inset-bottom, 0px));}
.mbp-shorts .mbp-short__btn,
.mbp-shorts .mbp-shorts__back {border:0;background:transparent;box-shadow:none;}
.mbp-shorts .mbp-short__btn {width:52px;height:54px;min-height:48px;flex-direction:column;gap:4px;border-radius:var(--mbp-s-radius);font-family:var(--mbp-s-font);touch-action:manipulation;padding:0;}
.mbp-shorts .mbp-short__btn[hidden] {display:none;}
.mbp-shorts .mbp-short__btn svg,
.mbp-shorts .mbp-shorts__back svg {width:28px;height:28px;flex-shrink:0;filter:drop-shadow(0 1px 2px rgba(27,32,43,.95)) drop-shadow(0 0 1px rgba(27,32,43,.95));}
.mbp-shorts .mbp-short__action-label {font-size:12px;font-weight:500;line-height:1.15;letter-spacing:0;color:var(--mbp-s-ink);text-shadow:var(--mbp-s-textshadow);}
.mbp-shorts .mbp-short__btn:hover,
.mbp-shorts .mbp-shorts__back:hover {background:transparent;}
.mbp-shorts .mbp-short__btn:active {transform:scale(.94);}
.mbp-shorts .mbp-short__btn:focus-visible {outline:2px solid var(--mbp-s-ink);outline-offset:2px;background:rgba(27,32,43,.65);}
.mbp-shorts .mbp-shorts__back {width:48px;height:48px;top:calc(10px + env(safe-area-inset-top, 0px));}
.mbp-shorts .mbp-shorts__sheet-title {font-size:20px;line-height:1.2;}
.mbp-shorts .mbp-shorts__sheet-body {font-size:16px;line-height:1.6;color:var(--mbp-s-ink);}
.mbp-shorts .mbp-shorts__sheet-close {width:48px;height:48px;}
.mbp-shorts .mbp-shorts__toast {font-size:14px;bottom:calc(20px + env(safe-area-inset-bottom, 0px));border-radius:var(--mbp-s-radius);max-width:85%;text-align:center;}
/* The rail always stays inside the visible picture, including phones
   reporting a desktop viewport or hover-capable input. */
.mbp-shorts .mbp-short__rail {
 position:absolute;
 display:flex;
 flex-direction:column;
 right:max(8px, calc(50% - var(--mbp-s-stage-w) / 2 + 8px));
 left:auto;
 z-index:3;
 visibility:visible;
 opacity:1;
 pointer-events:auto;
}
.mbp-shorts .mbp-short__btn,
.mbp-shorts .mbp-short__btn:hover,
.mbp-shorts .mbp-short__btn:active {
 background:transparent;
 background-image:none;
 border:0;
 box-shadow:none;
 color:var(--mbp-s-ink);
 opacity:1;
}
.mbp-shorts .mbp-short__btn svg {
 stroke:currentColor;
}

@media(max-width:768px) {
 .mbp-shorts .mbp-short__title {font-size:18px;}
}
@media(max-height:540px) and (orientation:landscape) {
 .mbp-shorts {--mbp-s-stage-w:100%;--mbp-s-inset:0px;}
 .mbp-shorts .mbp-short__meta {width:calc(50% - 100px);left:12px;padding:12px;bottom:12px;}
 .mbp-shorts .mbp-short__rail {right:10px;bottom:12px;gap:2px;}
 .mbp-shorts .mbp-short__btn {height:48px;}
 .mbp-shorts .mbp-short__title {font-size:16px;}
 .mbp-shorts .mbp-short__desc {font-size:14px;}
 .mbp-shorts .mbp-shorts__sheet {width:min(100%,560px);}
}
@media(prefers-reduced-motion:reduce) {
 .mbp-shorts .mbp-short__btn:active {transform:none;}
}

/*
 * Desktop action rail.
 *
 * Keep the mobile/touch overlay above unchanged. On a pointer-driven desktop
 * the viewport has room for a YouTube-style action column beside the 9:16
 * picture, which leaves the video itself clear and gives every action a stable
 * dark surface away from changing imagery.
 */
@media (min-width: 769px) and (hover: hover) and (pointer: fine) {
 .mbp-shorts .mbp-short__rail {
  right:calc(50% - var(--mbp-s-stage-w) / 2 - 76px);
  bottom:calc(var(--mbp-s-inset) + 20px);
  align-items:center;
  gap:10px;
 }
 .mbp-shorts .mbp-short__btn {
  width:64px;
  height:68px;
  gap:5px;
 }
 .mbp-shorts .mbp-short__btn svg {
  width:24px;
  height:24px;
  padding:12px;
  box-sizing:content-box;
  border:1px solid rgba(255,255,255,.12);
  border-radius:50%;
  background:var(--mbp-s-raised);
  filter:none;
 }
 .mbp-shorts .mbp-short__btn:hover svg {
  background:var(--mbp-s-surface);
 }
 .mbp-shorts .mbp-short__btn:focus-visible {
  outline-color:var(--mbp-s-accent);
  background:transparent;
 }
 .mbp-shorts .mbp-short__action-label {
  color:var(--mbp-s-muted);
  text-shadow:none;
 }
 .mbp-shorts .mbp-short__meta {
  width:calc(var(--mbp-s-stage-w) - 28px);
 }
}
