/**
 * Testimonial Manager - front end.
 *
 * Everything themeable is a custom property, so a builder can restyle a grid
 * by setting variables inline rather than fighting selector specificity.
 */

/* Shared visual tokens. The modal is moved to <body>, so it sits outside
   .tm-grid and would otherwise resolve these to nothing - which is how the
   popup stars ended up black. The script copies the grid's own values over
   these defaults when a card opens the popup. */
.tm-grid,
.tm-modal,
.tm-slider {
	--tm-accent: #ef7100;

	--tm-text-color: #042246;
	--tm-name-color: #042246;
	--tm-role-color: #7b8792;

	--tm-star-color: var(--tm-accent);
	--tm-star-empty-color: #f5ebcc;
	--tm-star-size: 17px;
	--tm-star-gap: 3px;

	--tm-quote-mark-size: 44px;

	--tm-avatar-size: 44px;

	--tm-font: inherit;

	--tm-quote-size: 15px;
	--tm-quote-align: justify;
	--tm-quote-style: italic;
	--tm-quote-weight: 400;
	--tm-quote-lh: 1.62;
	--tm-quote-spacing: normal;

	--tm-name-size: 17px;
	--tm-name-weight: 500;
	--tm-name-lh: 1.3;
	--tm-name-spacing: normal;
	--tm-name-transform: none;

	--tm-role-size: 13px;
	--tm-role-weight: 400;
	--tm-role-lh: 1.35;
}

.tm-grid {
	--tm-cols: 3;
	--tm-cols-t: 2;
	--tm-cols-m: 1;
	--tm-gap: 24px;

	--tm-card-bg: #ffffff;
	--tm-card-border-color: #ecdba4;
	--tm-card-border-width: 1px;
	--tm-card-radius: 2px;

	--tm-btn-bg: var(--tm-accent);
	--tm-btn-color: #ffffff;
	--tm-btn-border-color: var(--tm-accent);
	--tm-btn-bg-hover: #ef7100;
	--tm-btn-color-hover: #ffffff;
	--tm-btn-border-hover: #ef7100;
	--tm-btn-border-width: 1px;
	--tm-btn-radius: 2px;
	--tm-btn-padding: 14px 18px;
	--tm-btn-font-size: 14px;
	--tm-btn-weight: 500;
	--tm-btn-spacing: 0.06em;
	--tm-btn-transform: uppercase;
	--tm-card-shadow: none;

	--tm-card-padding: 26px;

	display: grid;
	grid-template-columns: repeat(var(--tm-active-cols, var(--tm-cols)), minmax(0, 1fr));
	gap: var(--tm-gap);
}

/* Laptop first, so the tablet and mobile rules below still override it. */
@media (max-width: 1300px) {
	.tm-grid { --tm-active-cols: var(--tm-cols-l, var(--tm-cols)); }
}

@media (max-width: 1024px) {
	.tm-grid { --tm-active-cols: var(--tm-cols-t); }
}

@media (max-width: 767px) {
	.tm-grid { --tm-active-cols: var(--tm-cols-m); }
}

/* ---------- Card ---------- */

.tm-card {
	display: flex;
	flex-direction: column;
	padding: var(--tm-card-padding);
	background: var(--tm-card-bg);
	border: var(--tm-card-border-width) solid var(--tm-card-border-color);
	border-radius: var(--tm-card-radius);
	box-shadow: var(--tm-card-shadow);
	font-family: var(--tm-font);
}

.tm-quote { margin: 0; }

/* ---------- Quote mark ----------
   Themes decorate a <blockquote> with their own large quote glyph, which lands
   behind the first words of the testimonial. It is switched off here and drawn
   by the plugin instead, so it is an option rather than a surprise. */
.tm-quote::before,
.tm-quote::after,
.tm-excerpt::before,
.tm-excerpt::after,
.tm-excerpt p::before,
.tm-excerpt p::after,
.tm-slide-quote::before,
.tm-slide-quote::after,
.tm-slide-quote p::before,
.tm-slide-quote p::after,
.tm-modal-quote::before,
.tm-modal-quote::after,
.tm-modal-quote p::before,
.tm-modal-quote p::after,
.tm-home-quote::before,
.tm-home-quote::after,
.tm-home-quote p::before,
.tm-home-quote p::after {
	content: none !important;
	display: none !important;
	background: none !important;
}

.tm-show-quote .tm-excerpt::before,
.tm-show-quote .tm-slide-quote::before,
.tm-show-quote .tm-modal-quote::before {
	content: '\201C' !important;
	display: block !important;
	color: var(--tm-quote-mark-color, var(--tm-accent));
	font-size: var(--tm-quote-mark-size, 44px);
	font-family: Georgia, 'Times New Roman', serif;
	font-style: normal;
	line-height: 0.9;
	margin-bottom: 6px;
}

.tm-excerpt {
	margin: 0;
	padding: 0;
	border: 0;
	quotes: none;
	color: var(--tm-text-color);
	font-style: var(--tm-quote-style);
	font-size: var(--tm-quote-size);
	font-weight: var(--tm-quote-weight);
	line-height: var(--tm-quote-lh);
	letter-spacing: var(--tm-quote-spacing);
	text-align: var(--tm-quote-align);
	hyphens: auto;
}

.tm-excerpt p { margin: 0; }

/* ---------- Stars ---------- */

.tm-stars {
	display: flex;
	gap: var(--tm-star-gap, 3px);
	margin-bottom: 18px;
}

.tm-star {
	width: var(--tm-star-size);
	height: var(--tm-star-size);
	flex: 0 0 auto;
	fill: var(--tm-star-empty-color);
}

.tm-star.is-on { fill: var(--tm-star-color); }

/* ---------- Client ---------- */

/* margin-top:auto pushes the client block and button to the bottom, so cards
   with different amounts of text still line their buttons up. */
.tm-person {
	display: flex;
	align-items: center;
	gap: 14px;
	margin-top: auto;
	padding-top: 26px;
}

.tm-avatar {
	width: var(--tm-avatar-size);
	height: var(--tm-avatar-size);
	flex: 0 0 auto;
	border-radius: 50%;
	object-fit: cover;
	display: block;
}

.tm-avatar-fallback {
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--tm-accent);
	color: #fff;
	font-size: calc(var(--tm-avatar-size) * 0.42);
	font-weight: 600;
	line-height: 1;
}

.tm-person-text {
	min-width: 0;
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.tm-grid .tm-card .tm-name,
.tm-modal .tm-modal-body .tm-name {
	margin: 0;
	padding: 0;
	color: var(--tm-name-color);
	font-size: var(--tm-name-size);
	font-weight: var(--tm-name-weight);
	line-height: var(--tm-name-lh);
	letter-spacing: var(--tm-name-spacing);
	text-transform: var(--tm-name-transform);
}

.tm-grid .tm-card .tm-name::before,
.tm-grid .tm-card .tm-name::after {
	content: none;
}

.tm-role {
	color: var(--tm-role-color);
	font-size: var(--tm-role-size);
	font-weight: var(--tm-role-weight);
	line-height: var(--tm-role-lh);
}

/* ---------- Button ---------- */

.tm-btn {
	display: block;
	width: 100%;
	margin-top: 22px;
	padding: var(--tm-btn-padding);
	background: var(--tm-btn-bg);
	color: var(--tm-btn-color);
	border: var(--tm-btn-border-width) solid var(--tm-btn-border-hover);
	border-radius: var(--tm-btn-radius);
	font-family: inherit;
	font-size: var(--tm-btn-font-size);
	font-weight: var(--tm-btn-weight);
	letter-spacing: var(--tm-btn-spacing);
	text-transform: var(--tm-btn-transform);
	text-align: center;
	cursor: pointer;
	transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

/* Every interactive state is pinned to the plugin's own colours. Themes
   commonly style button:focus and button:active, and :focus-visible does not
   match a mouse click, so a clicked button would otherwise keep the theme
   colour after the popup closed. */
.tm-grid .tm-card .tm-btn:hover,
.tm-grid .tm-card .tm-btn:focus,
.tm-grid .tm-card .tm-btn:focus-visible,
.tm-grid .tm-card .tm-btn:active {
	background: none;
	color: var(--tm-btn-bg);
	border-color: var(--tm-btn-border-hover);
}

.tm-grid .tm-card .tm-btn:focus-visible,
.tm-modal-close:focus-visible {
	outline: 3px solid var(--tm-btn-bg, #ef7100);
	outline-offset: 2px;
}

/* Keyboard focus stays visible; a mouse click does not leave a ring behind. */
.tm-grid .tm-card .tm-btn:focus:not(:focus-visible) {
	outline: none;
}

/* ---------- Modal ---------- */

.tm-modal {
	--tm-modal-max-width: 840px;
	--tm-modal-bg: #ffffff;
	--tm-modal-overlay: rgba(20, 30, 38, 0.72);
	--tm-modal-text-color: #042246;
	--tm-modal-font-size: 16px;
	--tm-modal-radius: 2px;
	--tm-modal-padding: 38px;
	--tm-modal-close-bg: #ef7100;
	--tm-modal-close-color: #ffffff;

	position: fixed;
	inset: 0;
	z-index: 999999;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 48px 20px 20px;
}

.tm-modal[hidden] { display: none; }

.tm-modal-overlay {
	position: absolute;
	inset: 0;
	background: var(--tm-modal-overlay);
	animation: tm-fade 0.2s ease;
}

.tm-modal-dialog {
	position: relative;
	width: 100%;
	max-width: var(--tm-modal-max-width);
	max-height: calc(100vh - 68px);
	overflow-y: auto;
	padding: var(--tm-modal-padding);
	background: var(--tm-modal-bg);
	border-radius: var(--tm-modal-radius);
	color: var(--tm-modal-text-color);
	animation: tm-rise 0.22s ease;
}

.tm-modal-dialog:focus { outline: none; }

/* The popup is re-parented to <body>, where the theme's own button rules apply
   to it. These are forced so the close button stays a circle of the right
   size and colour whatever the active theme does to <button>. */
.tm-modal .tm-modal-close {
	position: absolute !important;
	top: var(--tm-close-top, 12px) !important;
	right: var(--tm-close-right, 12px) !important;
	left: var(--tm-close-left, auto) !important;
	bottom: auto !important;
	transform: var(--tm-close-transform, none) !important;
	z-index: 2;

	width: var(--tm-close-size, 40px) !important;
	height: var(--tm-close-size, 40px) !important;
	min-width: 0 !important;
	min-height: 0 !important;
	max-width: none !important;
	flex: 0 0 auto !important;

	display: flex !important;
	align-items: center !important;
	justify-content: center !important;

	margin: 0 !important;
	padding: 0 !important;
	background: var(--tm-modal-close-bg, #ef7100) !important;
	background-image: none !important;
	color: var(--tm-modal-close-color, #ffffff) !important;
	border: 0 !important;
	border-radius: 50% !important;
	box-shadow: none !important;
	text-transform: none !important;
	letter-spacing: normal !important;
	line-height: 1 !important;
	cursor: pointer;
	opacity: 1 !important;
}

.tm-modal .tm-modal-close svg {
	display: block !important;
	width: 45% !important;
	height: 45% !important;
	stroke: currentColor !important;
	fill: none !important;
}

.tm-modal .tm-modal-close:hover {
	filter: brightness(0.92);
}

/* Keep the stars and text clear of a corner-positioned close button. */
.tm-modal-body { padding-right: 34px; }

.tm-modal-body .tm-stars { margin-bottom: 20px; }

.tm-modal-quote {
	color: inherit;
	font-style: italic;
	font-size: var(--tm-modal-font-size);
	line-height: 1.7;
}

.tm-modal-quote p { margin: 0 0 1em; }
.tm-modal-quote p:last-child { margin-bottom: 0; }

.tm-modal-body .tm-person {
	margin-top: 26px;
	padding-top: 0;
}

.tm-modal-body .tm-name {
	color: var(--tm-name-color, #042246);
}

/* Set by the script while the modal is open. */
body.tm-modal-open { overflow: hidden; }

@keyframes tm-fade {
	from { opacity: 0; }
	to   { opacity: 1; }
}

@keyframes tm-rise {
	from { opacity: 0; transform: translateY(12px); }
	to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
	.tm-modal-overlay,
	.tm-modal-dialog { animation: none; }
	.tm-btn { transition: none; }
}

@media (max-width: 767px) {
	.tm-modal { padding: 44px 14px 14px; }
	.tm-modal-dialog { padding: 26px 20px; }
	.tm-modal-body { padding-right: 26px; }
	.tm-excerpt { text-align: left; hyphens: manual; }
}

/* Only used when the theme does not already provide it. */
.tm-grid .screen-reader-text,
.tm-modal .screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}


/* =========================================================
 * SLIDER
 * ========================================================= */

.tm-slider {
	--tm-slider-bg: rgba(18, 26, 32, 0.72);
	--tm-slider-color: #ffffff;
	--tm-slider-padding: 44px;
	--tm-slider-radius: 0px;
	--tm-slider-min-height: 0px;
	--tm-slider-quote-size: 19px;
	--tm-slider-quote-weight: 400;
	--tm-slider-quote-lh: 1.6;
	--tm-slider-quote-style: italic;
	--tm-slider-quote-align: left;
	--tm-slider-quote-spacing: normal;
	--tm-slider-role-size: 13px;
	--tm-slider-name-size: 18px;
	--tm-slider-name-weight: 500;
	--tm-slider-nav-color: #ffffff;
	--tm-slider-nav-bg: rgba(255, 255, 255, 0.14);
	--tm-slider-dot: rgba(255, 255, 255, 0.4);
	--tm-slider-dot-active: var(--tm-accent);

	/* The panel sits over a banner image, so white is the working default. */
	--tm-name-color: #ffffff;
	--tm-role-color: rgba(255, 255, 255, 0.75);

	position: relative;
	background: var(--tm-slider-bg);
	border-radius: var(--tm-slider-radius);
	color: var(--tm-slider-color);
}

.tm-slider-viewport {
	overflow: hidden;
	padding: var(--tm-slider-padding);
	min-height: var(--tm-slider-min-height);
}

/* Every slide occupies the same grid cell, so the track is as tall as the
   longest testimonial and swapping slides never changes the layout. */
.tm-slides {
	display: grid;
	align-items: start;
}

.tm-slide {
	grid-area: 1 / 1;
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.5s ease, transform 0.5s ease;
	pointer-events: none;
}

.tm-slide.is-active {
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
}

.tm-effect-slide .tm-slide { transform: translateX(28px); }
.tm-effect-slide .tm-slide.is-active { transform: none; }

.tm-slide .tm-stars { margin-bottom: 20px; }

.tm-slide-quote {
	margin: 0 0 26px;
	padding: 0;
	border: 0;
	quotes: none;
	color: inherit;
	font-style: var(--tm-slider-quote-style);
	font-size: var(--tm-slider-quote-size);
	font-weight: var(--tm-slider-quote-weight);
	line-height: var(--tm-slider-quote-lh);
	text-align: var(--tm-slider-quote-align);
	letter-spacing: var(--tm-slider-quote-spacing);
}

.tm-slide-quote p { margin: 0; }

.tm-slide .tm-person {
	margin-top: 0;
	padding-top: 0;
}

.tm-slider .tm-name {
	color: var(--tm-name-color);
	font-size: var(--tm-slider-name-size);
	font-weight: var(--tm-slider-name-weight);
	line-height: 1.3;
}

.tm-slider .tm-role {
	color: var(--tm-role-color);
	font-size: var(--tm-slider-role-size, 13px);
}

/* ---------- Navigation ---------- */

/* Forced for the same reason as the popup close button: themes style <button>
   with their own min-width and padding, and a 50% radius on a box that is not
   square draws an ellipse rather than a circle. */
.tm-slider .tm-slider-nav {
	position: absolute !important;
	top: 50% !important;
	transform: translateY(-50%) !important;
	display: flex !important;
	align-items: center !important;
	justify-content: center !important;
	width: 38px !important;
	height: 38px !important;
	min-width: 0 !important;
	min-height: 0 !important;
	max-width: none !important;
	margin: 0 !important;
	padding: 0 !important;
	background: var(--tm-slider-nav-bg) !important;
	background-image: none !important;
	color: var(--tm-slider-nav-color) !important;
	border: 0 !important;
	border-radius: 50% !important;
	box-shadow: none !important;
	line-height: 1 !important;
	cursor: pointer;
	transition: background-color 0.2s ease;
}

.tm-slider-prev { left: 10px !important; right: auto !important; }
.tm-slider-next { right: 10px !important; left: auto !important; }

.tm-slider.tm-has-arrows .tm-slider-viewport {
	padding-left: calc(var(--tm-slider-padding) + 40px);
	padding-right: calc(var(--tm-slider-padding) + 40px);
}

.tm-slider-nav svg { width: 20px; height: 20px; }

.tm-slider .tm-slider-nav:hover { background: var(--tm-accent) !important; }

.tm-slider-dots {
	display: flex;
	justify-content: center;
	gap: 8px;
	padding: 0 0 18px;
}

.tm-slider .tm-slider-dot {
	display: block !important;
	width: 9px !important;
	height: 9px !important;
	min-width: 0 !important;
	min-height: 0 !important;
	max-width: none !important;
	margin: 0 !important;
	padding: 0 !important;
	background: var(--tm-slider-dot) !important;
	background-image: none !important;
	border: 0 !important;
	border-radius: 50% !important;
	box-shadow: none !important;
	font-size: 0 !important;
	line-height: 0 !important;
	cursor: pointer;
	transition: background-color 0.2s ease, transform 0.2s ease;
}

.tm-slider .tm-slider-dot.is-active {
	background: var(--tm-slider-dot-active) !important;
	transform: scale(1.25);
}

.tm-slider-nav:focus-visible,
.tm-slider-dot:focus-visible {
	outline: 2px solid var(--tm-slider-color);
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	.tm-slide,
	.tm-slider-nav,
	.tm-slider-dot { transition: none; }
	.tm-effect-slide .tm-slide { transform: none; }
}

@media (max-width: 767px) {
	.tm-slider { --tm-slider-padding: 26px; --tm-slider-quote-size: 16px; }
	.tm-slider-nav { display: none; }
}


/* =========================================================
 * HOME TESTIMONIAL
 *
 * A wide tinted panel: oversized quote mark and client photo down the left,
 * testimonial and signature to their right, chevrons bottom right. It reuses
 * the slider's skeleton and script, so everything here is scoped to .tm-home
 * and the existing slider is untouched.
 * ========================================================= */

.tm-slider.tm-home {
	/* No panel behind it any more: the row it sits in carries whatever
	   background there is, and a second one only disagrees with the first. */
	--tm-home-bg: transparent;
	--tm-home-font: Karla, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
	--tm-star-size: 22px;
	--tm-star-gap: 6px;
	--tm-home-radius: 0px;
	/* Vertical and horizontal are separate: the chevrons anchor to the
	   vertical figure, and a two-value shorthand cannot be used for that. */
	/* Zero, for the same reason: with no panel to sit inside, the space
	   belongs to the row. Both are still fields on the element. */
	--tm-home-pad-y: 0px;
	--tm-home-pad-x: 0px;
	--tm-home-min-height: 0px;

	/* Left column: wide enough for the quote mark and the photo below it. */
	--tm-home-col: 128px;
	--tm-home-col-gap: 20px;
	--tm-home-row-gap: 40px;
	--tm-home-mark-space: 40px;
	--tm-home-quote-space: 46px;
	--tm-home-rating-space: 10px;

	--tm-home-mark-color: #ef7100;
	--tm-home-mark-size: 96px;
	--tm-home-mark-weight: 700;
	--tm-home-mark-img-width: 96px;

	--tm-home-quote-color: #162542;
	--tm-home-quote-size: 20px;
	--tm-home-quote-weight: 400;
	--tm-home-quote-lh: 34px;
	--tm-home-quote-style: normal;
	--tm-home-quote-align: left;
	--tm-home-quote-spacing: normal;

	--tm-avatar-size: 92px;
	--tm-home-ring-color: #ef7100;
	--tm-home-ring-width: 3px;

	--tm-home-name-color: #162542;
	--tm-home-name-size: 20px;
	--tm-home-name-weight: 500;
	--tm-home-name-style: normal;
	--tm-home-name-lh: 1.5;
	--tm-home-role-size: 14px;

	/* Two square buttons at the foot of the panel: the previous outlined in
	   navy, the next filled gold, as the approved panel has them. */
	--tm-home-nav-size: 22px;
	--tm-home-nav-box: 46px;
	--tm-home-nav-gap: 10px;
	--tm-home-nav-bottom: 0px;
	--tm-home-nav-right: 0px;
	--tm-home-nav-color: #162542;
	--tm-home-nav-bg: transparent;
	--tm-home-nav-border: #162542;
	--tm-home-next-color: #ffffff;
	--tm-home-next-bg: #ef7100;
	--tm-home-next-border: #ef7100;
	--tm-home-nav-hover: #ffffff;
	--tm-home-nav-bg-hover: #162542;

	--tm-home-bg-image: none;
	--tm-home-bg-size: cover;
	--tm-home-bg-position: center;
	--tm-home-bg-repeat: no-repeat;
	--tm-home-bg-opacity: 1;

	background-color: var(--tm-home-bg);
	border-radius: var(--tm-home-radius);
	color: var(--tm-home-quote-color);
	font-family: var(--tm-home-font);
	overflow: hidden;
}

/*
 * The same panel on a dark section.
 *
 * Navy type on a navy row is invisible, and so is the previous arrow, which
 * is outlined in the same navy - which is why only the gold next arrow shows
 * when the panel is dropped into a dark row. Every value below is still a
 * field; this only changes what they start at.
 */
.tm-slider.tm-home--on-dark {
	--tm-home-quote-color: #ffffff;
	--tm-home-name-color: #ffffff;
	--tm-home-nav-color: #ffffff;
	--tm-home-nav-border: #ffffff;
	--tm-home-nav-hover: #162542;
	--tm-home-nav-bg-hover: #ffffff;
	--tm-role-color: rgba(255, 255, 255, 0.78);
	--tm-star-empty-color: rgba(255, 255, 255, 0.3);
}

/* The background image is its own layer rather than a shorthand on the panel,
   so it can carry an opacity and let the colour show through behind it. */
.tm-slider.tm-home::before {
	content: '';
	position: absolute;
	inset: 0;
	z-index: 0;
	background-image: var(--tm-home-bg-image, none);
	background-size: var(--tm-home-bg-size, cover);
	background-position: var(--tm-home-bg-position, center);
	background-repeat: var(--tm-home-bg-repeat, no-repeat);
	opacity: var(--tm-home-bg-opacity, 1);
	pointer-events: none;
}

/* Content clears that layer. The chevrons are positioned, so they are lifted
   explicitly rather than by a blanket rule that would break their placement. */
.tm-slider.tm-home > .tm-slider-viewport { position: relative; z-index: 1; }
.tm-slider.tm-home .tm-home-nav { z-index: 2; }
.tm-slider.tm-home > .tm-slider-dots { position: relative; z-index: 2; }

.tm-slider.tm-home .tm-slider-viewport {
	padding: var(--tm-home-pad-y) var(--tm-home-pad-x);
	min-height: var(--tm-home-min-height);

	/* The track fills the panel, however tall the panel is told to be. */
	display: flex;
	flex-direction: column;
}

/*
 * Every slide is the full height of the track, and the signature row sits on
 * the floor of it.
 *
 * Slides share one grid cell, so the cell is as tall as the LONGEST
 * testimonial. Left top-aligned, a two-word review put its photo and name
 * near the top of that cell while the chevrons stayed at the bottom - the
 * shorter the review, the wider the gap. Stretching the slide and pushing the
 * signature to the bottom puts it on the same line for every slide, which is
 * the line the chevrons are on.
 */
.tm-slider.tm-home .tm-slides {
	flex: 1;
	align-items: stretch;
}

.tm-slider.tm-home .tm-slide { display: flex; }

.tm-slider.tm-home .tm-home-inner {
	flex: 1;
	align-content: space-between;
}

/*
 * One column, everything on the same left edge.
 *
 * It used to be two - the mark over the photo, the text over the signature -
 * which only earned its keep while the panel carried a client photo. The
 * approved panel has none, so the second track was an indent with nothing in
 * it. Spacing between the three blocks is set on each rather than by row-gap,
 * because the name sits tight under the stars while the stars sit well clear
 * of the quote, and one gap cannot be both.
 */
.tm-home-inner {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	row-gap: 0;
	align-items: start;
}

.tm-home-mark {
	grid-column: 1;
	margin-bottom: var(--tm-home-mark-space);
	color: var(--tm-home-mark-color);
	font-size: var(--tm-home-mark-size);
	font-weight: var(--tm-home-mark-weight);
	font-style: normal;
	line-height: 0.78;
}

/* An uploaded mark replaces the glyph; it scales on its own width so the
   typographic size control does not silently distort it. */
.tm-home-mark-img {
	display: block;
	width: var(--tm-home-mark-img-width, 96px);
	max-width: 100%;
	height: auto;
}

.tm-home-rating {
	grid-column: 1;
	margin: 0 0 var(--tm-home-rating-space);
}

.tm-home-rating .tm-stars { margin-bottom: 0; }

.tm-slider.tm-home .tm-home-quote {
	grid-column: 1;
	margin: 0 0 var(--tm-home-quote-space);
	padding: 0;
	border: 0;
	quotes: none;
	color: var(--tm-home-quote-color);
	font-size: var(--tm-home-quote-size);
	font-weight: var(--tm-home-quote-weight);
	font-style: var(--tm-home-quote-style);
	line-height: var(--tm-home-quote-lh);
	text-align: var(--tm-home-quote-align);
	letter-spacing: var(--tm-home-quote-spacing);
}

.tm-home-quote p { margin: 0; }

/* A row, not a track: with no photo it collapses to just the name, and with
   one it still sits beside it. */
.tm-home-person {
	grid-column: 1;
	display: flex;
	align-items: center;
	gap: var(--tm-home-col-gap);
}

.tm-home-person:empty,
.tm-home-avatar:empty { display: none; }

.tm-slider.tm-home .tm-avatar {
	width: var(--tm-avatar-size);
	height: var(--tm-avatar-size);
	border-radius: 50%;
	object-fit: cover;
	background: #ffffff;
	box-shadow: 0 0 0 var(--tm-home-ring-width) var(--tm-home-ring-color);
}

.tm-slider.tm-home .tm-avatar-fallback {
	display: flex;
	align-items: center;
	justify-content: center;
}

.tm-home-person-text { display: flex; flex-direction: column; }

.tm-slider.tm-home .tm-home-salutation,
.tm-slider.tm-home .tm-home-person-text .tm-name {
	color: var(--tm-home-name-color);
	font-size: var(--tm-home-name-size);
	font-weight: var(--tm-home-name-weight);
	font-style: var(--tm-home-name-style);
	line-height: var(--tm-home-name-lh);
}

.tm-slider.tm-home .tm-home-person-text .tm-role {
	color: var(--tm-role-color, rgba(22, 37, 66, 0.72));
	font-size: var(--tm-home-role-size);
}

/* ---------- Chevrons ----------
   Plain glyphs rather than the round buttons used by the banner slider, so
   the forced circle styling there has to be undone at higher specificity. */
.tm-home-nav {
	position: absolute;
	right: var(--tm-home-nav-right);
	bottom: var(--tm-home-nav-bottom);
	display: flex;
	align-items: center;
	gap: var(--tm-home-nav-gap);
}

/*
 * The chevrons line up with the signature row - the photo and the client's
 * name - at every width.
 *
 * A hand-set offset from the bottom of the panel cannot do that: the panel's
 * height moves with the length of the quote, so the row it is meant to match
 * moves with it. The signature row is the last thing in the panel, so the
 * bottom padding plus the photo's own height puts the chevrons on its centre
 * line wherever it lands, with no figure to keep re-tuning per breakpoint.
 */
.tm-slider.tm-home .tm-home-nav {
	bottom: var(--tm-home-pad-y);
	height: var(--tm-home-nav-box);
	align-items: center;
}

.tm-slider.tm-home .tm-home-nav .tm-slider-nav {
	position: static !important;
	transform: none !important;
	display: flex !important;
	align-items: center;
	justify-content: center;
	width: var(--tm-home-nav-box) !important;
	height: var(--tm-home-nav-box) !important;
	padding: 0 !important;
	background: var(--tm-home-nav-bg) !important;
	border: 1px solid var(--tm-home-nav-border) !important;
	border-radius: 0 !important;
	color: var(--tm-home-nav-color) !important;
	opacity: 1 !important;
	transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease !important;
}

/* The next button is the primary one, filled; the previous is outlined. */
.tm-slider.tm-home .tm-home-nav .tm-slider-next {
	background: var(--tm-home-next-bg) !important;
	border-color: var(--tm-home-next-border) !important;
	color: var(--tm-home-next-color) !important;
}

.tm-slider.tm-home .tm-home-nav .tm-slider-nav:hover,
.tm-slider.tm-home .tm-home-nav .tm-slider-nav:focus-visible {
	background: var(--tm-home-nav-bg-hover) !important;
	border-color: var(--tm-home-nav-bg-hover) !important;
	color: var(--tm-home-nav-hover) !important;
}

.tm-slider.tm-home .tm-home-nav .tm-slider-nav svg {
	width: var(--tm-home-nav-size) !important;
	height: var(--tm-home-nav-size) !important;
}

/* ---------- Responsive ---------- */

/*
 * Rewritten for the panel as it is now.
 *
 * The old blocks were tuned for a teal panel with a client photo beside the
 * quote in a second column: they put the padding back, shrank the quote and
 * retuned columns that no longer exist. With the panel gone there is nothing
 * to inset from, so the only thing that changes with the screen is the size
 * of the type and the mark.
 */
@media (max-width: 1024px) {
	.tm-slider.tm-home {
		--tm-home-mark-size: 76px;
		--tm-home-mark-img-width: 76px;
		--tm-home-mark-space: 30px;
		--tm-home-quote-space: 36px;
	}
}

@media (max-width: 767px) {
	.tm-slider.tm-home {
		--tm-home-mark-size: 60px;
		--tm-home-mark-img-width: 60px;
		--tm-home-mark-space: 22px;
		--tm-home-quote-size: 17px;
		--tm-home-quote-lh: 28px;
		--tm-home-quote-space: 28px;
		--tm-home-name-size: 18px;
		--tm-home-nav-box: 40px;
		--tm-home-nav-size: 18px;
	}

	/* The arrows drop under the name rather than overlapping it - on a phone
	   there is no room for both on one line. */
	.tm-slider.tm-home .tm-home-nav {
		position: static;
		justify-content: flex-start;
		height: auto;
		margin-top: 22px;
	}
}

/* -------------------------------------------------------------------------
 * Category filter buttons
 *
 * The same outline shape as Read More, without the arrow: navy border, navy
 * text, and the whole box filling navy with white text on hover and while
 * selected. Every value is a custom property the element can override.
 * ---------------------------------------------------------------------- */

.tm-filterable {
	--tm-filter-color: #162542;
	--tm-filter-bg: transparent;
	--tm-filter-border: #162542;
	--tm-filter-color-active: #ffffff;
	--tm-filter-bg-active: #162542;
	--tm-filter-size: 15px;
	--tm-filter-lh: 20px;
	--tm-filter-weight: 500;
	--tm-filter-padding: 13px 26px;
	--tm-filter-radius: 0px;
	--tm-filter-border-width: 1px;
	--tm-filter-gap: 12px;
	--tm-filter-space: 36px;
	--tm-filter-align: center;
	--tm-filter-transform: uppercase;
	--tm-filter-tracking: 0.04em;
}

/*
 * One row, always.
 *
 * flex-wrap stays on so the script can see what falls onto a second line and
 * move it into the panel; once it has, nothing is left to wrap.
 */
.tm-filters {
	position: relative;
	display: flex;
	flex-wrap: wrap;
	justify-content: var(--tm-filter-align);
	gap: var(--tm-filter-gap);
	margin: 0 0 var(--tm-filter-space);
}

.tm-filters__more { position: relative; }
.tm-filters__more[hidden] { display: none; }

/* The overflow, as a panel under "More" rather than a second row. */
.tm-filters__panel {
	position: absolute;
	top: calc(100% + 8px);
	right: 0;
	z-index: 20;
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 6px;
	min-width: 100%;
	max-height: 320px;
	padding: 8px;
	overflow-y: auto;
	background: #ffffff;
	border: var(--tm-filter-border-width) solid var(--tm-filter-border);
	box-shadow: 0 14px 34px rgba(8, 23, 41, 0.16);
}

.tm-filters__panel[hidden] { display: none; }

.tm-filters__panel .tm-filter {
	white-space: nowrap;
	justify-content: flex-start;
	border-color: transparent;
}

.tm-filters__panel .tm-filter:hover,
.tm-filters__panel .tm-filter:focus-visible,
.tm-filters__panel .tm-filter.is-active {
	border-color: var(--tm-filter-bg-active);
}

.tm-filter {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	margin: 0;
	padding: var(--tm-filter-padding);
	background: var(--tm-filter-bg);
	border: var(--tm-filter-border-width) solid var(--tm-filter-border);
	border-radius: var(--tm-filter-radius);
	color: var(--tm-filter-color);
	font-family: inherit;
	font-size: var(--tm-filter-size);
	line-height: var(--tm-filter-lh);
	font-weight: var(--tm-filter-weight);
	letter-spacing: var(--tm-filter-tracking);
	text-transform: var(--tm-filter-transform);
	text-decoration: none;
	cursor: pointer;
	transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}

.tm-filter[hidden] { display: none; }

.tm-filter:hover,
.tm-filter:focus-visible,
.tm-filter.is-active {
	background: var(--tm-filter-bg-active);
	border-color: var(--tm-filter-bg-active);
	color: var(--tm-filter-color-active);
}

.tm-filter:focus-visible {
	outline: 3px solid var(--tm-filter-border);
	outline-offset: 3px;
}

/* A card filtered out is taken out of the grid, not just made invisible, so
   the remaining cards close up rather than leaving holes in the rows. */
.tm-card[hidden] { display: none !important; }

@media (max-width: 767px) {
	.tm-filterable {
		--tm-filter-gap: 8px;
		--tm-filter-size: 13px;
		--tm-filter-padding: 10px 16px;
		--tm-filter-space: 24px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.tm-filter { transition: none; }
}

/* -------------------------------------------------------------------------
 * Filtering, animated
 *
 * FLIP: the cards that stay are put back where they were and released, so the
 * grid closes up by sliding rather than jumping. Only the wrapper opts in, and
 * anyone who has asked their system for less motion gets none of it.
 * ---------------------------------------------------------------------- */

.tm-filterable.is-animated {
	--tm-filter-anim: 380ms;
}

.tm-filterable.is-animated .tm-card {
	transition:
		opacity var(--tm-filter-anim) ease,
		transform var(--tm-filter-anim) cubic-bezier(0.2, 0.7, 0.3, 1);
}

/*
 * Leaving: faded out before the grid reflows, so nothing vanishes mid-slide.
 *
 * Shorter than the slide - the same 0.45 the script waits - because a full
 * fade followed by a full slide left the grid sitting still for the best part
 * of half a second.
 */
.tm-filterable.is-animated .tm-card.is-leaving {
	opacity: 0;
	transform: scale(0.96);
	pointer-events: none;
	transition-duration: calc(var(--tm-filter-anim) * 0.45);
}

/*
 * Held still for one frame while it is measured and offset. Without this the
 * card would animate from its new position to its new position - which is to
 * say, not at all.
 */
.tm-filterable.is-animated .tm-card.is-flipping {
	transition: none;
}

.tm-filterable.is-animated .tm-card.is-entering {
	opacity: 0;
	transform: translateY(12px) scale(0.98);
	transition: none;
}

@media (prefers-reduced-motion: reduce) {
	.tm-filterable.is-animated .tm-card,
	.tm-filterable.is-animated .tm-card.is-leaving,
	.tm-filterable.is-animated .tm-card.is-entering {
		transition: none;
		opacity: 1;
		transform: none;
	}
}
