/* =========================================================
   Vertical explore feed (template-clips.php)
   ========================================================= */

.cf-clip {
	padding: 40px 0 72px;
}

.cf-clip__head {
	margin-bottom: 24px;
	text-align: center;
}

.cf-clip__title {
	margin: 0;
	font-size: clamp(28px, 5vw, 44px);
	font-weight: 800;
	letter-spacing: .5px;
}

.cf-clip__lead {
	margin: 8px 0 0;
	color: #6b6b6b;
}

.cf-clip__empty {
	padding: 60px 0;
	text-align: center;
	color: #8a8a8a;
}

/* ---------- search ---------- */

.cf-clip-search {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	/* Wide enough that the button's gold ring, which is drawn outside its box,
	   does not crowd the field beside it. */
	gap: 12px;
	max-width: 520px;
	margin: 24px auto 0;
}

.cf-clip-search__box {
	position: relative;
	display: flex;
	flex: 1 1 220px;
	min-width: 0;
}

.cf-clip-search__icon {
	position: absolute;
	/* Against the field's own box, so a wrapped row cannot strand the icon
	   between the two lines. */
	top: 50%;
	left: 18px;
	transform: translateY(-50%);
	color: #8a6a4a;
	font-size: 15px;
	pointer-events: none;
}

/* Scoped under the form on purpose. style.css styles every search input as
   `input[type="search"]`, which outranks a single class no matter how late this
   file loads - and it was quietly winning on border, radius and padding, which
   left the icon sitting on top of the placeholder. The parent class puts this
   rule ahead of it without reaching for !important. The submit button below is
   scoped the same way, for the bare `button` rule in that stylesheet. */
.cf-clip-search .cf-clip-search__field {
	flex: 1 1 auto;
	width: 100%;
	box-sizing: border-box;
	min-height: 48px;
	/* Room on the left for the icon sitting over the field. */
	padding: 11px 20px 11px 44px;
	border: 2px solid #3f1e11;
	border-radius: 999px;
	background: #fff;
	color: #2c241d;
	font-size: 16px;
	line-height: 1.4;
	/* iOS zooms the page in on focus when the field is under 16px, and the
	   appearance reset stops Safari drawing its own rounded search box over
	   the one above. */
	-webkit-appearance: none;
	appearance: none;
	min-width: 0;
	-webkit-text-fill-color: #2c241d;
}

.cf-clip-search .cf-clip-search__field::placeholder {
	color: #b9afa4;
	opacity: 1;
	-webkit-text-fill-color: #b9afa4;
}

.cf-clip-search .cf-clip-search__field:focus {
	outline: none;
	border-color: #b47a25;
	box-shadow: 0 0 0 3px rgb(180 122 37 / 16%);
}

/* The register form's primary button, kept to the same colours, border and
   layered ring so the two pages read as one campaign. Sriracha comes from
   dth.css, which clip.css already depends on. */
.cf-clip-search .cf-clip-search__submit {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 48px;
	padding: 8px 28px;
	color: #e0bd6e;
	font-family: "Sriracha", cursive;
	font-size: 18px;
	font-style: italic;
	font-weight: 400;
	line-height: 1.2;
	white-space: nowrap;
	cursor: pointer;
	background-color: #3f1e11;
	border: 1.5px solid #ffffff;
	border-radius: 999px;
	box-shadow: inset 0 0 0 1.5px #3f1e11, 0 0 0 2.5px #e0bd6e, 0 4px 10px rgba(0, 0, 0, .25);
	transition: background-color .2s ease, border-color .2s ease, box-shadow .2s ease;
}

.cf-clip-search .cf-clip-search__submit:hover,
.cf-clip-search .cf-clip-search__submit:focus-visible {
	color: #f1bf60;
	background-color: #4d2616;
	border-color: #ffffff;
	box-shadow: inset 0 0 0 1.5px #4d2616, 0 0 0 2.5px #e0bd6e, 0 4px 12px rgba(0, 0, 0, .35);
}

.cf-clip-search__clear {
	flex: 0 0 auto;
	color: #6b5546;
	font-size: 14px;
	text-decoration: underline;
}

.cf-clip-search__clear:hover,
.cf-clip-search__clear:focus-visible {
	color: #3f1e11;
}

@media (max-width: 767px) {
	.cf-clip-search {
		gap: 10px;
	}

	.cf-clip-search .cf-clip-search__field {
		/* Held at 16px: anything smaller makes iOS zoom the page in on focus. */
		padding-right: 14px;
		padding-left: 40px;
	}

	.cf-clip-search__icon {
		left: 15px;
		font-size: 14px;
	}

	.cf-clip-search .cf-clip-search__submit {
		padding: 8px 18px;
		font-size: 16px;
	}

	/* Wrapped onto its own line rather than stealing width from the field, which
	   a cat's name needs more than the link does. In flow rather than positioned
	   over the page, so the heading below is pushed down instead of overlapped. */
	.cf-clip-search__clear {
		width: 100%;
		margin-top: -2px;
		text-align: center;
	}
}

/* ---------- sections ---------- */

.cf-clip-section + .cf-clip-section {
	margin-top: 44px;
}

.cf-clip-section__title {
	margin: 0 0 16px;
	font-size: clamp(20px, 2.4vw, 28px);
	font-weight: 800;
	letter-spacing: .3px;
}

/* A fixed column count rather than auto-fill: the row has to hold exactly six
   at the widest step, and auto-fill would keep adding narrower tiles as the
   viewport grew instead of letting each one get bigger. */
.cf-clip__grid {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: 16px;
}

@media (max-width: 1199px) {
	.cf-clip__grid {
		grid-template-columns: repeat(4, minmax(0, 1fr));
	}
}

@media (max-width: 767px) {
	.cf-clip__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 12px;
	}
}

/* ---------- load more ---------- */

.cf-clip-more {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 32px 0 8px;
}

.cf-clip-more[hidden] {
	display: none;
}

/* Kept to the same colours, border and layered ring as the search button, so
   every control on the page reads as one campaign. */
.cf-clip-more__button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	min-height: 48px;
	padding: 8px 32px;
	color: #e0bd6e;
	font-family: "Sriracha", cursive;
	font-size: 16px;
	font-style: italic;
	font-weight: 400;
	line-height: 1.2;
	white-space: nowrap;
	cursor: pointer;
	background-color: #3f1e11;
	border: 1.5px solid #ffffff;
	border-radius: 999px;
	box-shadow: inset 0 0 0 1.5px #3f1e11, 0 0 0 2.5px #e0bd6e, 0 4px 10px rgba(0, 0, 0, .25);
	transition: background-color .2s ease, border-color .2s ease, box-shadow .2s ease, opacity .2s ease;
}

.cf-clip-more__button:hover,
.cf-clip-more__button:focus-visible {
	color: #f1bf60;
	background-color: #4d2616;
	border-color: #ffffff;
}

.cf-clip-more__button:disabled {
	cursor: default;
	opacity: .7;
}

/* Hidden until the button is busy, so the label sits on its own the rest of
   the time instead of a static ring nobody is spinning. */
.cf-clip-more__spinner {
	display: none;
	width: 16px;
	height: 16px;
	border: 2px solid rgba(224, 189, 110, .35);
	border-top-color: #e0bd6e;
	border-radius: 50%;
	animation: cf-clip-more-spin .8s linear infinite;
}

.cf-clip-more__button.is-loading .cf-clip-more__spinner {
	display: inline-block;
}

@keyframes cf-clip-more-spin {
	to {
		transform: rotate(360deg);
	}
}

@media (prefers-reduced-motion: reduce) {
	.cf-clip-more__spinner {
		animation-duration: 3s;
	}
}

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

.cf-clip-card {
	position: relative;
	display: block;
	width: 100%;
	padding: 0;
	border: 0;
	aspect-ratio: 9 / 16;
	border-radius: 14px;
	overflow: hidden;
	cursor: pointer;
	transition: transform .25s ease, box-shadow .25s ease;
}

.cf-clip-card:hover,
.cf-clip-card:focus-visible {
	transform: translateY(-4px);
	box-shadow: 0 16px 36px rgba(0, 0, 0, .28);
}

.cf-clip-card__poster {
	position: absolute;
	inset: 0;
	background-color: #111;
	background-position: center;
	background-repeat: no-repeat;
	background-size: cover;
}

.cf-clip-card__shade {
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(0, 0, 0, .72), rgba(0, 0, 0, 0) 45%);
}

.cf-clip-card__play {
	position: absolute;
	top: 50%;
	left: 50%;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 52px;
	transform: translate(-50%, -50%) scale(.9);
	border-radius: 50%;
	background: rgba(0, 0, 0, .38);
	backdrop-filter: blur(8px);
	color: #fff;
	font-size: 17px;
	opacity: 0;
	transition: opacity .25s ease, transform .25s ease;
}

.cf-clip-card:hover .cf-clip-card__play,
.cf-clip-card:focus-visible .cf-clip-card__play {
	opacity: 1;
	transform: translate(-50%, -50%) scale(1);
}

.cf-clip-card__meta {
	position: absolute;
	right: 10px;
	bottom: 10px;
	left: 10px;
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 8px;
	color: #fff;
	text-align: left;
}

.cf-clip-card__name {
	overflow: hidden;
	font-size: 14px;
	font-weight: 700;
	white-space: nowrap;
	text-overflow: ellipsis;
	text-shadow: 0 2px 8px rgba(0, 0, 0, .6);
}

.cf-clip-card__likes {
	flex-shrink: 0;
	font-size: 12px;
	font-weight: 600;
	opacity: .9;
}

/* =========================================================
   Player overlay
   ========================================================= */

.cf-clip-player {
	/*
	 * On a phone the clip owns the whole screen, edge to edge. On a desktop
	 * window it sits in a rounded frame with air above and below instead - the
	 * gap cannot be padding on the slide, because the overlays inside are
	 * absolutely positioned and would resolve against the padding box and
	 * ignore it, so every one of them is inset by this variable directly.
	 */
	--cf-clip-gap: 0px;
	--cf-clip-radius: 0px;

	/*
	 * The frame a clip plays in. A phone gets one size and keeps it - there is
	 * no room to give a landscape clip anything wider. A desktop window has
	 * room, so there the frame keeps its height and takes its width from the
	 * clip's own shape (JS writes --cf-clip-aspect when a clip becomes active),
	 * which lets a landscape clip play in full instead of cropped to a column.
	 * Only the width moves: the height is what the feed scrolls by, and a
	 * height that changed per clip would move every clip's resting position.
	 */
	--cf-clip-aspect: 0.5625;
	--cf-clip-frame-height: 100dvh;
	--cf-clip-frame-width: 100%;

	position: fixed;
	inset: 0;
	z-index: 9999;
	background: #000;
	opacity: 0;
	transition: opacity .22s ease;
}

@media (min-width: 901px) {

	.cf-clip-player {
		--cf-clip-gap: 26px;
		--cf-clip-radius: 22px;

		/* Capped so the clip does not sprawl on a 4K monitor: past this it is
		   upscaling a 1080p source and asking the eye to track a bigger arc. */
		--cf-clip-frame-height: min(calc(100dvh - var(--cf-clip-gap) * 2), 900px);

		/* `100vw - 320px` keeps the margins the action rail and the step buttons
		   stand in, so a wide clip cannot grow over its own controls. */
		--cf-clip-frame-width: min(
			calc(var(--cf-clip-frame-height) * var(--cf-clip-aspect)),
			1200px,
			calc(100vw - 320px)
		);

		background: #0b0b0b;
	}
}

.cf-clip-player[hidden] {
	display: none;
}

.cf-clip-player.is-open {
	opacity: 1;
}

body.cf-clip-locked {
	overflow: hidden;
}

/*
 * The scrolling box *is* the frame, not a full-height column with a frame drawn
 * over it: a taller scroller would keep painting the clip in the gap above and
 * below while it travelled, spilling past the rounded corners mid-swipe. Being
 * the frame, it clips every clip that moves through it.
 *
 * It is also phone-shaped rather than window-wide, because the overlay pinned
 * to it carries the caption and the seek bar - stretched to a desktop window
 * those would end up at the screen edges, far from the video they describe.
 */
.cf-clip-player__feed {
	position: absolute;
	top: 50%;
	left: 50%;
	width: var(--cf-clip-frame-width);
	height: var(--cf-clip-frame-height);
	transform: translate(-50%, -50%);
	overflow-y: auto;
	border-radius: var(--cf-clip-radius);
	scroll-snap-type: y mandatory;
	overscroll-behavior: contain;
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.cf-clip-player__feed::-webkit-scrollbar {
	display: none;
}

/*
 * The feed is focused when the player opens so the arrow keys reach it, but it
 * is not a tab stop and its ring traces the whole frame. A browser draws that
 * ring when the page was opened straight from a link, with no interaction
 * behind the focus to tell it otherwise. The controls inside keep theirs.
 */
.cf-clip-player__feed:focus,
.cf-clip-player__feed:focus-visible {
	outline: none;
}

.cf-clip-player__close,
.cf-clip-player__sound,
.cf-clip-player__step {
	position: absolute;
	z-index: 20;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(255, 255, 255, .14);
	backdrop-filter: blur(10px);
	color: #fff;
	font-size: 18px;
	line-height: 1;
	cursor: pointer;
	transition: background .2s ease, transform .2s ease;
}

.cf-clip-player__close:hover,
.cf-clip-player__step:hover {
	background: rgba(255, 255, 255, .26);
}

/*
 * Anchored to the clip, not to the window: half the frame width back from the
 * centre line is its left edge, so both controls stay on the video however wide
 * the window gets, and follow the gap down on a desktop frame.
 */
.cf-clip-player__sound {
	top: calc(50% - var(--cf-clip-frame-height) / 2 + 14px);
	left: calc(50% - var(--cf-clip-frame-width) / 2 + 12px);
	transition: opacity .2s ease;
	background: none;
	backdrop-filter: none;
	font-size: 20px;

	/* No pill behind it, so the icon carries its own contrast for bright frames. */
	text-shadow: 0 2px 10px rgba(0, 0, 0, .75);
}

.cf-clip-player__sound:hover {
	opacity: .75;
}

.cf-clip-player__close {
	top: calc(50% - var(--cf-clip-frame-height) / 2 + 14px);
	right: calc(50% - var(--cf-clip-frame-width) / 2 + 12px);
	transition: background .2s ease;
}

/* Wheel and swipe both move the feed; these are the visible affordance on desktop. */
.cf-clip-player__step {
	right: 24px;
}

.cf-clip-player__step--prev {
	top: calc(50% - 56px);
}

.cf-clip-player__step--next {
	top: calc(50% + 12px);
}

.cf-clip-player__step[disabled] {
	opacity: .3;
	cursor: default;
}

@media (max-width: 900px) {

	.cf-clip-player__step {
		display: none;
	}
}

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

.cf-clip-slide {
	position: relative;
	width: 100%;
	height: 100%;
	overflow: hidden;
	scroll-snap-align: start;
	scroll-snap-stop: always;
}

.cf-clip-slide__stage {
	position: absolute;
	inset: 0;
	cursor: pointer;
}

.cf-clip-slide__video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	background: #000;
}

.cf-clip-slide__poster {
	position: absolute;
	inset: 0;
	background-color: #000;
	background-position: center;
	background-repeat: no-repeat;
	background-size: cover;
	transition: opacity .3s ease;
}

.cf-clip-slide.is-playing .cf-clip-slide__poster {
	opacity: 0;
}

/*
 * `contain` rather than `cover` once the frame follows the clip: the frame
 * cannot always match it - a very wide source runs into the width caps - and
 * cropping it back to the frame is the one thing all of this was meant to
 * avoid. Where the frame does match, which is every portrait clip, the two
 * behave identically and no bars appear at all. A phone keeps `cover`, where
 * a full-bleed clip matters more than seeing every edge of it.
 */
@media (min-width: 901px) {

	.cf-clip-slide__video {
		object-fit: contain;
	}

	.cf-clip-slide__poster {
		background-size: contain;
	}
}

.cf-clip-slide__spinner {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 38px;
	height: 38px;
	margin: -19px 0 0 -19px;
	border: 3px solid rgba(255, 255, 255, .25);
	border-top-color: #fff;
	border-radius: 50%;
	opacity: 0;
	animation: cf-clip-spin 1s linear infinite;
	pointer-events: none;
}

.cf-clip-slide.is-loading .cf-clip-slide__spinner {
	opacity: 1;
}

@keyframes cf-clip-spin {

	to {
		transform: rotate(360deg);
	}
}

.cf-clip-slide__paused {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%) scale(.7);
	color: rgba(255, 255, 255, .85);
	font-size: 64px;
	opacity: 0;
	pointer-events: none;
	transition: opacity .2s ease, transform .2s ease;
}

.cf-clip-slide.is-paused .cf-clip-slide__paused {
	transform: translate(-50%, -50%) scale(1);
	opacity: 1;
}

.cf-clip-player__shade {
	position: absolute;
	inset: 0;
	background: linear-gradient(to top, rgba(0, 0, 0, .78), rgba(0, 0, 0, .12) 42%, rgba(0, 0, 0, .3));
}

.cf-clip-slide__heart {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%) scale(0);
	color: #fff;
	font-size: 110px;
	opacity: 0;
	pointer-events: none;
	transition: transform .35s ease, opacity .35s ease;
}

.cf-clip-slide__heart.is-shown {
	transform: translate(-50%, -50%) scale(1);
	opacity: .92;
}

/* ---------- pinned overlay ---------- */

.cf-clip-player__overlay {
	position: absolute;
	top: 50%;
	left: 50%;
	z-index: 15;
	width: var(--cf-clip-frame-width);
	height: var(--cf-clip-frame-height);
	transform: translate(-50%, -50%);
	overflow: hidden;
	border-radius: var(--cf-clip-radius);

	/* Taps belong to the video underneath; only the seek bar takes them back. */
	pointer-events: none;
}

.cf-clip-player__info {
	position: absolute;
	right: 92px;
	bottom: 28px;
	left: 20px;
	color: #fff;
}

.cf-clip-player__owner {
	margin: 0;
	font-size: 14px;
	opacity: .85;
	text-shadow: 0 2px 8px rgba(0, 0, 0, .6);
}

.cf-clip-player__name {
	margin: 4px 0 0;
	font-size: 19px;
	font-weight: 700;
	text-shadow: 0 2px 10px rgba(0, 0, 0, .6);
}

.cf-clip-player__caption {
	margin: 8px 0 0;
	font-size: 14px;
	line-height: 1.5;
	color: #f1f1f1;
	text-shadow: 0 2px 10px rgba(0, 0, 0, .5);
}

/* ---------- action rail ---------- */

/*
 * Fixed to the player, not to a slide. On a phone it rides over the clip the
 * way it always has; on a desktop frame it steps outside the video entirely and
 * stands in the margin beside it.
 */
.cf-clip-player__actions {
	position: absolute;
	right: 14px;
	bottom: calc(92px + var(--cf-clip-gap));
	z-index: 20;
	display: flex;
	flex-direction: column;
	gap: 16px;
}

@media (min-width: 901px) {

	.cf-clip-player__actions {
		right: auto;
		bottom: calc(50% - var(--cf-clip-frame-height) / 2 + 24px);
		left: calc(50% + var(--cf-clip-frame-width) / 2 + 20px);
	}

	/* Off the video there is no footage to sit on, so the pill carries its own. */
	.cf-clip-player__actions .cf-clip-action {
		background: rgba(255, 255, 255, .12);
	}

	.cf-clip-player__actions .cf-clip-action:hover {
		background: rgba(255, 255, 255, .2);
	}

	/* Nothing overlaps the caption on this side any more. */
	.cf-clip-player__info {
		right: 20px;
	}
}

.cf-clip-action {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 5px;
	width: 60px;
	height: 60px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(0, 0, 0, .35);
	backdrop-filter: blur(12px);
	box-shadow: 0 8px 24px rgba(0, 0, 0, .35);
	color: #fff;
	cursor: pointer;
	transition: transform .2s ease, color .2s ease;
}

.cf-clip-action:hover {
	transform: scale(1.06);
}

.cf-clip-action:active {
	transform: scale(.94);
}

.cf-clip-action i {
	font-size: 21px;
}

.cf-clip-action span {
	font-size: 11px;
	font-weight: 600;
}

.cf-clip-action.is-liked {
	color: #ff2456;
}

.cf-clip-action.is-liked i {
	animation: cf-clip-pop .35s;
}

/*
 * A like cannot be taken back, so the heart is disabled once it is given. It
 * keeps its liked colouring rather than picking up the browser's greyed-out
 * treatment: the state being shown is "done", not "unavailable".
 */
.cf-clip-action:disabled {
	cursor: default;
	opacity: 1;
}

.cf-clip-action:disabled:hover,
.cf-clip-action:disabled:active {
	transform: none;
}

/*
 * The heart and its note. The note is taken out of the flow so the rail stays a
 * single column of 60px circles - letting it take space would widen the column
 * and pull the heart out of line with the share button under it.
 */
.cf-clip-action-group {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
}

.cf-clip-action-note {
	position: absolute;
	top: 50%;
	/* On a phone the rail hugs the right edge, so the note sits on the inward
	   side where there is room for it. */
	right: calc(100% + 6px);
	display: flex;
	width: 26px;
	height: 26px;
	align-items: center;
	justify-content: center;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: rgba(0, 0, 0, .45);
	backdrop-filter: blur(12px);
	color: rgba(255, 255, 255, .82);
	cursor: pointer;
	transform: translateY(-50%);
	transition: color .2s ease, background .2s ease;
}

.cf-clip-action-note:hover,
.cf-clip-action-note:focus-visible {
	background: rgba(0, 0, 0, .65);
	color: #fff;
}

.cf-clip-action-note i {
	font-size: 15px;
}

.cf-clip-action-note__bubble {
	position: absolute;
	bottom: calc(100% + 8px);
	right: 0;
	width: max-content;
	max-width: 210px;
	padding: 8px 11px;
	border-radius: 9px;
	background: rgba(20, 20, 24, .95);
	box-shadow: 0 8px 24px rgba(0, 0, 0, .4);
	color: #fff;
	font-size: 12px;
	font-weight: 500;
	line-height: 1.45;
	opacity: 0;
	pointer-events: none;
	text-align: left;
	transition: opacity .18s ease, transform .18s ease;
	transform: translateY(4px);
}

/* Hover covers the desktop, focus covers both the keyboard and a phone tap -
   there is no hover to reveal anything on a touch screen. */
.cf-clip-action-note:hover .cf-clip-action-note__bubble,
.cf-clip-action-note:focus .cf-clip-action-note__bubble {
	opacity: 1;
	transform: translateY(0);
}

@media (min-width: 901px) {

	/* Off the video the rail stands in the right-hand margin, so the note has
	   room on its outward side instead. */
	.cf-clip-action-note {
		right: auto;
		left: calc(100% + 6px);
	}

	.cf-clip-action-note__bubble {
		right: auto;
		left: 0;
	}
}

@keyframes cf-clip-pop {

	0% {
		transform: scale(.5);
	}

	50% {
		transform: scale(1.25);
	}

	100% {
		transform: scale(1);
	}
}

/* ---------- progress / scrubber ---------- */

/*
 * The element is taller than the line it draws: 3px is an honest target for a
 * mouse and no target at all for a thumb, so the bar keeps its hairline look
 * while the box around it stays big enough to grab. `touch-action: none` keeps
 * a horizontal drag from being handed to the feed as a vertical swipe.
 */
.cf-clip-player__progress {
	position: absolute;
	right: 0;
	bottom: 0;
	left: 0;
	z-index: 6;
	pointer-events: auto;
	display: flex;
	align-items: flex-end;
	height: 22px;
	cursor: pointer;
	touch-action: none;
}

.cf-clip-player__track {
	position: relative;
	display: block;
	width: 100%;
	height: 3px;
	background: rgba(255, 255, 255, .22);
	transition: height .15s ease;
}

.cf-clip-player__progress:hover .cf-clip-player__track,
.cf-clip-player__progress:focus-visible .cf-clip-player__track,
.cf-clip-player__progress.is-scrubbing .cf-clip-player__track {
	height: 6px;
}

.cf-clip-player__bar {
	display: block;
	width: 0;
	height: 100%;
	background: #fff;
	transition: width .1s linear;
}

.cf-clip-player__progress.is-scrubbing .cf-clip-player__bar {
	/* Following the finger has to be immediate; the easing above would lag it. */
	transition: none;
}

.cf-clip-player__knob {
	position: absolute;
	top: 50%;
	left: 0;
	width: 12px;
	height: 12px;
	margin-left: -6px;
	transform: translateY(-50%) scale(0);
	border-radius: 50%;
	background: #fff;
	box-shadow: 0 2px 8px rgba(0, 0, 0, .45);
	transition: transform .15s ease;
}

.cf-clip-player__progress:hover .cf-clip-player__knob,
.cf-clip-player__progress:focus-visible .cf-clip-player__knob,
.cf-clip-player__progress.is-scrubbing .cf-clip-player__knob {
	transform: translateY(-50%) scale(1);
}

@media (prefers-reduced-motion: reduce) {

	.cf-clip-card,
	.cf-clip-action,
	.cf-clip-action-note,
	.cf-clip-action-note__bubble,
	.cf-clip-slide__heart,
	.cf-clip-player {
		transition: none;
	}

	/* The bubble still has to appear, so it loses the slide rather than the
	   reveal itself. */
	.cf-clip-action-note__bubble {
		transform: none;
	}
}

/* =========================================================
   Share sheet
   ========================================================= */

.cf-clip-share {
	position: absolute;
	inset: 0;
	z-index: 40;
	display: flex;
	align-items: flex-end;
	justify-content: center;
}

.cf-clip-share[hidden] {
	display: none;
}

.cf-clip-share__backdrop {
	position: absolute;
	inset: 0;
	background: rgba(0, 0, 0, .6);
}

.cf-clip-share__sheet {
	position: relative;
	z-index: 1;
	width: 100%;
	max-width: 520px;
	padding: 18px 0 24px;
	background: #1c1c1c;
	border-radius: 20px 20px 0 0;
	box-shadow: 0 -12px 40px rgba(0, 0, 0, .5);
	color: #fff;
	transform: translateY(100%);
	transition: transform .28s ease;
}

.cf-clip-share.is-open .cf-clip-share__sheet {
	transform: translateY(0);
}

.cf-clip-share__head {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 0 56px 14px;
}

.cf-clip-share__title {
	margin: 0;
	font-size: 17px;
	font-weight: 700;
}

.cf-clip-share__close {
	position: absolute;
	top: 50%;
	right: 16px;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: none;
	color: #fff;
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
	transform: translateY(-50%);
	transition: opacity .2s ease;
}

.cf-clip-share__close:hover {
	opacity: .7;
}

/*
 * A scrolling row rather than a wrapping grid: more targets can be added later
 * without the sheet growing taller, which is what every share sheet of this
 * shape does.
 */
.cf-clip-share__targets {
	display: flex;
	gap: 20px;
	padding: 6px 20px 4px;
	overflow-x: auto;
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.cf-clip-share__targets::-webkit-scrollbar {
	display: none;
}

.cf-clip-share__target {
	display: flex;
	flex: 0 0 auto;
	flex-direction: column;
	align-items: center;
	gap: 8px;
	width: 68px;
	padding: 0;
	border: 0;
	background: none;
	color: #fff;
	cursor: pointer;
}

.cf-clip-share__icon {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	border-radius: 50%;
	font-size: 23px;
	line-height: 1;
	transition: transform .2s ease;
}

.cf-clip-share__target:hover .cf-clip-share__icon {
	transform: scale(1.07);
}

.cf-clip-share__target:active .cf-clip-share__icon {
	transform: scale(.94);
}

.cf-clip-share__icon--facebook {
	background: #1877f2;
}

.cf-clip-share__icon--line {
	background: #06c755;
}

/* X's own colour is the sheet's colour, so it is given an edge to sit on. */
.cf-clip-share__icon--x {
	background: #000;
	box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .25);
}

.cf-clip-share__icon--copy {
	background: #2f6feb;
}

.cf-clip-share__label {
	font-size: 12px;
	line-height: 1.3;
	text-align: center;
	word-break: break-word;
}

.cf-clip-share__link {
	margin: 14px 20px 0;
	overflow: hidden;
	color: rgba(255, 255, 255, .5);
	font-size: 12px;
	white-space: nowrap;
	text-overflow: ellipsis;
}

.cf-clip-share__response {
	margin: 8px 20px 0;
	min-height: 18px;
	color: #7ad38f;
	font-size: 13px;
}

@media (min-width: 620px) {

	.cf-clip-share {
		align-items: center;
	}

	.cf-clip-share__sheet {
		border-radius: 20px;
		box-shadow: 0 24px 60px rgba(0, 0, 0, .55);
		transform: translateY(16px) scale(.98);
		opacity: 0;
		transition: transform .22s ease, opacity .22s ease;
	}

	.cf-clip-share.is-open .cf-clip-share__sheet {
		transform: translateY(0) scale(1);
		opacity: 1;
	}
}

@media (prefers-reduced-motion: reduce) {

	.cf-clip-share__sheet {
		transition: none;
	}
}
