﻿/* ==========================================================================
   COMPONENTS
   --------------------------------------------------------------------------
   Theme-specific pieces Bootstrap has no component for. Anything that IS a
   Bootstrap component (buttons, cards, accordion, pagination, dropdowns) is
   only recoloured, in 02-bootstrap.css — not rebuilt here.
   ========================================================================== */


/* --------------------------------------------------------------------------
   Icon chips
   --------------------------------------------------------------------------
   The class sits on the <svg> itself, not a wrapper, so the tinted square is
   made with padding + box-sizing and the SVG scales into the content box.
   -------------------------------------------------------------------------- */

.mtfs-contact-list__icon {
	box-sizing: border-box;
	width: 40px;
	height: 40px;
	padding: 11px;
	border-radius: var(--mtfs-radius-sm);
	background: var(--mtfs-tint-primary);
	color: var(--mtfs-color-primary);
}

.mtfs-features__icon {
	box-sizing: border-box;
	width: 48px;
	height: 48px;
	padding: 13px;
	border-radius: var(--mtfs-radius);
	background: var(--mtfs-tint-primary);
	color: var(--mtfs-color-primary);
}

/*
 * The last row of cards grows to fill the width, which is how the frames
 * draw a five-card grid: three across, then two at half width each. Only
 * flex-grow is added — Bootstrap keeps owning the column widths, so a full
 * row has no free space to distribute and stays exactly three across.
 */
.mtfs-cards--fill .row > * {
	flex-grow: 1;
}

/*
 * A grid continuing the band above it — the second row of the product frame's
 * substrate classifications — still needs air between the two rows. Joined, the
 * section has no padding of its own and the row's negative gutter margin puts
 * the cards flush against the row above, so the gap is put back here: the same
 * 60 the frame leaves under a heading.
 */
.mtfs-cards.mtfs-section--no-space-top > .container > .row:first-child {
	margin-top: calc(var(--mtfs-heading-space) - var(--bs-gutter-y));
}

/*
 * Card typography. The frames use two sizes and the section picks between
 * them: About us sets a 24px title over reading-size copy, while the packaging
 * and customizable-content grids run a denser 20/14 so four fit across. Both
 * are scoped to this section, because a blog card is set at reading size.
 */
/* A short card can be centred against the taller ones beside it rather than
   sitting at the top of its box — measured on the packaging grid, where
   "Sheets" starts 11px lower than the three cards around it. Off by default:
   the weaving and glossary grids line their titles up. */
.mtfs-cards--middle .card-body {
	display: flex;
	flex-direction: column;
	justify-content: center;
}

/* The frames draw the card on the surface tint with a hairline round it, not
   on white — except on a band that is already that tint, where it inverts. */
.mtfs-cards .card {
	--bs-card-bg: var(--mtfs-color-surface);
}

.mtfs-section--muted.mtfs-cards .card,
.mtfs-cards--white .card {
	--bs-card-bg: var(--mtfs-white);
}

.mtfs-section--muted.mtfs-cards--white .card {
	--bs-card-bg: var(--mtfs-color-surface);
}

/* Inset, the picture keeps corners of its own and is spaced off the card's
   edges by the same padding the copy under it has. */
.mtfs-cards--media-inset .mtfs-card__media {
	margin: var(--mtfs-space-5) var(--mtfs-space-5) 0;
	border-radius: var(--mtfs-radius);
}

.mtfs-cards--media-inset .card-body {
	padding-top: var(--mtfs-space-5);
}

/* How deep the crop is. The applications grid runs 16:9 — measured at 366x209
   inside a 411 card — and the product frame's substrate row is shallower. */
.mtfs-cards--media-inset .card-img-top {
	aspect-ratio: 16 / 9;
}

.mtfs-cards--shape-wide .card-img-top {
	aspect-ratio: 2 / 1;
}

.mtfs-cards--shape-photo .card-img-top {
	aspect-ratio: 3 / 2;
}

/* The product frame gives the two pictures in its substrate row the same
   height even though their cards are different widths, which no single
   proportion can do. */
.mtfs-cards--shape-fixed .card-img-top {
	height: var(--mtfs-card-media-h);
	aspect-ratio: auto;
}

.mtfs-cards .card-title {
	line-height: var(--mtfs-line-height-card);
}

.mtfs-cards--large .card-title {
	font-size: var(--mtfs-size-h3);
}

.mtfs-cards--compact .card {
	--bs-card-spacer-y: var(--mtfs-space-5);
	--bs-card-spacer-x: var(--mtfs-space-5);
	--bs-card-title-spacer-y: var(--mtfs-space-5);
}

/* Small copy sits closer to its title than reading-size copy does — measured
   at 16 on the packaging grid against 24 everywhere the body is 16px. */
.mtfs-cards--text-small .card {
	--bs-card-title-spacer-y: var(--mtfs-space-4);
}

.mtfs-cards--compact .card-title {
	font-size: var(--mtfs-size-h4);
}

/* The body size is set on its own, because the frames mix the two: the
   resources cards pair a compact title with reading-size copy. */
.mtfs-cards--text-small .card-text {
	font-size: var(--mtfs-size-body-2);
	line-height: var(--mtfs-line-height-answer);
}

.mtfs-cards__icon {
	color: var(--mtfs-color-primary);
}

.mtfs-contact-list__label {
	color: var(--mtfs-color-heading);
}


/* --------------------------------------------------------------------------
   Social links
   -------------------------------------------------------------------------- */

.mtfs-social__link {
	width: 38px;
	height: 38px;
	border-radius: var(--mtfs-radius-sm);
	background: var(--mtfs-color-surface);
	color: var(--mtfs-color-heading);
	transition: background-color var(--mtfs-transition), color var(--mtfs-transition);
}

.mtfs-social__link:hover {
	background: var(--mtfs-color-primary);
	color: var(--mtfs-white);
}


/* --------------------------------------------------------------------------
   Sidebar widgets
   -------------------------------------------------------------------------- */

.mtfs-widget {
	padding: var(--mtfs-space-5);
	margin-bottom: var(--mtfs-space-5);
	background: var(--mtfs-color-surface);
	border-radius: var(--mtfs-radius);
}

.mtfs-widget:last-child {
	margin-bottom: 0;
}

.mtfs-widget__title {
	margin-bottom: var(--mtfs-space-4);
	font-size: var(--mtfs-size-h5);
}

.mtfs-widget ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

.mtfs-widget li + li {
	margin-top: var(--mtfs-space-2);
	padding-top: var(--mtfs-space-2);
	border-top: 1px solid var(--mtfs-color-border);
}


/* --------------------------------------------------------------------------
   Contact Form 7
   --------------------------------------------------------------------------
   inc/cf7.php adds Bootstrap classes to the inputs automatically, so these
   rules only cover the wrappers CF7 emits that Bootstrap knows nothing about.
   -------------------------------------------------------------------------- */

.mtfsibra-form__title {
	margin-bottom: var(--mtfs-space-5);
}

.mtfsibra-form__notice {
	padding: var(--mtfs-space-3) var(--mtfs-space-4);
	border-left: 3px solid var(--mtfs-color-warning);
	background: color-mix(in srgb, var(--mtfs-color-warning) 10%, transparent);
	color: var(--mtfs-color-heading);
}

.mtfs-cf7 .wpcf7-form-control-wrap {
	display: block;
}

/* Select arrow -------------------------------------------------------------
   Bootstrap draws it as a background image whose stroke colour is baked into
   the data URI, so it stayed dark grey on the quote card's dark fields and
   all but disappeared. It also does not follow a palette change.

   So Bootstrap's image is switched off and the arrow is drawn on the field's
   wrapper as a masked chevron — the same 13x7 mark the navigation uses, on
   currentColor, so one rule covers a light form and a dark one and both track
   the palette. :has() is what lets the wrapper know it holds a select; the
   wrappers around text inputs are left alone. */

.mtfs-cf7 .wpcf7-form-control-wrap:has(.form-select) {
	position: relative;
	color: var(--mtfs-color-body);
}

.mtfs-cf7 .wpcf7-form-control-wrap:has(.form-select)::after {
	content: "";
	position: absolute;
	top: 50%;
	right: var(--mtfs-space-4);
	width: var(--mtfs-caret-w);
	height: var(--mtfs-caret-h);
	transform: translateY(-50%);
	background-color: currentColor;
	-webkit-mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 8' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='1 1.5 7 6.5 13 1.5'/%3e%3c/svg%3e") center / contain no-repeat;
	mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 8' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='1 1.5 7 6.5 13 1.5'/%3e%3c/svg%3e") center / contain no-repeat;

	/* The click still has to reach the select underneath. */
	pointer-events: none;
}

.mtfs-cf7 .form-select {
	background-image: none;

	/* Room for the chevron the wrapper now draws. */
	padding-right: calc(var(--mtfs-space-4) * 2 + var(--mtfs-caret-w));
}

.mtfsibra-form--on-dark .mtfs-cf7 .wpcf7-form-control-wrap:has(.form-select) {
	color: var(--mtfs-white);
}

/* Every label is a field label sitting above its input — except the upload
   chip, which is a label wrapped AROUND its input and sizes to its content. */
.mtfs-cf7 label:not(.mtfs-upload) {
	display: block;
	width: 100%;
	margin-bottom: var(--mtfs-space-2);
	font-weight: 600;
	line-height: var(--mtfs-line-height-control);
	color: var(--mtfs-color-heading);
}

/* CF7 always prints the response line, empty and aria-hidden, until a form is
   submitted. Left in flow it reserved 30-odd pixels under every form. */
.wpcf7 form.init .wpcf7-response-output,
.wpcf7 form.resetting .wpcf7-response-output {
	display: none;
}

/*
 * The spinner is a sibling of the submit button. With a full-width button it
 * wrapped onto its own line and pushed everything below it down by 32px, on
 * every form. Taken out of flow it overlays the end of the button instead,
 * and CF7 keeps control of when it becomes visible.
 */
.mtfs-cf7 {
	position: relative;
}

.mtfs-cf7 .wpcf7-spinner {
	position: absolute;
	right: var(--mtfs-space-5);
	bottom: var(--mtfs-space-4);
	margin: 0;
}

.mtfs-cf7 .wpcf7-not-valid-tip {
	margin-top: var(--mtfs-space-1);
	font-size: var(--mtfs-size-body-2);
	color: var(--mtfs-color-error);
}

.mtfs-cf7 .wpcf7-not-valid {
	border-color: var(--mtfs-color-error);
}

.wpcf7 form .wpcf7-response-output {
	margin: var(--mtfs-space-4) 0 0;
	padding: var(--mtfs-space-3) var(--mtfs-space-4);
	border-width: 1px;
	border-radius: var(--mtfs-radius-sm);
	font-size: var(--mtfs-size-body-2);
}

.wpcf7 form.sent .wpcf7-response-output {
	border-color: var(--mtfs-color-success);
	color: var(--mtfs-color-success);
}

.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.failed .wpcf7-response-output {
	border-color: var(--mtfs-color-error);
	color: var(--mtfs-color-error);
}

/* On a dark card ------------------------------------------------------------
   The quote section drops the same form onto a dark panel, so the labels go
   white and the fields become the palette's gray with a slightly lighter
   hairline — both sampled from the design. Only colours change; the sizing
   and the grid stay Bootstrap's, so a form built for a light page works here
   without being rewritten. */

.mtfsibra-form--on-dark .mtfsibra-form__title,
.mtfsibra-form--on-dark .mtfs-cf7 label {
	color: var(--mtfs-white);
}

.mtfsibra-form--on-dark .mtfs-cf7 .form-control,
.mtfsibra-form--on-dark .mtfs-cf7 .form-select {
	border-color: var(--mtfs-field-border-on-dark);
	background-color: var(--mtfs-field-on-dark);
	color: var(--mtfs-white);
}

.mtfsibra-form--on-dark .mtfs-cf7 .form-control::placeholder {
	color: var(--mtfs-on-dark-muted);
}

/* Bootstrap's focus ring is drawn for a light page and disappears here. */
.mtfsibra-form--on-dark .mtfs-cf7 .form-control:focus,
.mtfsibra-form--on-dark .mtfs-cf7 .form-select:focus {
	border-color: var(--mtfs-outline-on-dark);
	background-color: var(--mtfs-field-on-dark);
	box-shadow: var(--mtfs-focus-ring);
	color: var(--mtfs-white);
}

/* Upload chip -------------------------------------------------------------
   The design draws the file field as a small button — an upload glyph and the
   words "Upload file" — not as the browser's "Choose file / No file chosen"
   bar, which cannot be restyled or relabelled.

   So the form template wraps the input in a <label>. The input itself is
   hidden but still focusable, and the label is what gets drawn; clicking it
   opens the picker because that is what a label does, with no JS involved.
   main.js only writes the chosen filename back into the label afterwards. */

.mtfs-upload {
	display: inline-flex;
	align-items: center;
	gap: var(--mtfs-space-2);
	max-width: 100%;
	padding: var(--mtfs-space-3) var(--mtfs-space-4);
	border: 1px solid var(--mtfs-color-border);
	border-radius: var(--mtfs-radius-sm);
	background: var(--mtfs-color-surface);
	color: var(--mtfs-color-heading);
	font-size: var(--mtfs-size-body-2);
	font-weight: 500;
	cursor: pointer;
	transition: border-color var(--mtfs-transition), background var(--mtfs-transition);
}

.mtfs-upload:hover {
	border-color: var(--mtfs-color-primary);
}

.mtfs-upload .mtfs-icon {
	flex: none;
}

.mtfs-upload__label {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/*
 * Not display:none — a hidden input cannot be focused, and CF7's own
 * validation moves focus to a field that failed. Clipped to nothing instead,
 * so it keeps its place in the tab order.
 */
.mtfs-upload .wpcf7-file {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	border: 0;
	clip-path: inset(50%);
	overflow: hidden;
}

.mtfs-upload:focus-within {
	border-color: var(--mtfs-color-primary);
	box-shadow: var(--mtfs-focus-ring);
}

/* On the quote card the chip takes the dark panel fill. */
.mtfsibra-form--on-dark .mtfs-upload {
	border-color: var(--mtfs-border-on-dark);
	background: var(--mtfs-surface-on-dark);
	color: var(--mtfs-white);
}

.mtfsibra-form--on-dark .mtfs-upload:hover {
	border-color: var(--mtfs-outline-on-dark);
}

.mtfsibra-form--on-dark .mtfs-cf7 .wpcf7-submit {
	width: 100%;
}

.mtfsibra-form--on-dark .wpcf7 form .wpcf7-response-output,
.mtfsibra-form--on-dark .mtfs-cf7 .wpcf7-response-output {
	color: var(--mtfs-white);
}



/* --------------------------------------------------------------------------
   Hover underline
   --------------------------------------------------------------------------
   Shared by the header navigation and the four footer menus, so the two read
   as the same gesture rather than as two effects that happen to look alike.

   A scaled pseudo-element rather than an animated `width`: transform is
   composited, where width would relayout the line on every frame. The origin
   flips on the way out so the rule retracts to the right instead of snapping
   back, which is what makes the wipe read as one movement.

   Drawn on ::before, not ::after: the dropdown toggles already use ::after
   for their chevron, and an element only has one of each — sharing it blanked
   the carets on Services and Resources.

   Two knobs, set by whichever component uses it:
     --mtfs-underline-inset   pulls the rule in from the link's own padding
     --mtfs-underline-offset  how far below the text it sits
   -------------------------------------------------------------------------- */

.mtfs-nav .nav-link,
.mtfs-footer__menu a {
	position: relative;
}

.mtfs-nav .nav-link::before,
.mtfs-footer__menu a::before {
	content: "";
	position: absolute;
	left: var(--mtfs-underline-inset, 0);
	right: var(--mtfs-underline-inset, 0);
	bottom: var(--mtfs-underline-offset, calc(var(--mtfs-space-1) * -1));
	height: var(--mtfs-underline-h);
	background: currentColor;
	transform: scaleX(0);
	transform-origin: right center;
	transition: transform var(--mtfs-transition);
}

.mtfs-nav .nav-link:hover::before,
.mtfs-nav .nav-link:focus-visible::before,
.mtfs-footer__menu a:hover::before,
.mtfs-footer__menu a:focus-visible::before {
	transform: scaleX(1);
	transform-origin: left center;
}

/* The nav links carry their own horizontal padding, so the rule is inset to
   the label rather than run across the whole hit area. */
.mtfs-nav .nav-link {
	--mtfs-underline-inset: var(--mtfs-space-3);
	--mtfs-underline-offset: var(--mtfs-space-1);
}

/* Someone who has asked for less motion gets the underline, not the wipe. */
@media (prefers-reduced-motion: reduce) {

	.mtfs-nav .nav-link::before,
	.mtfs-footer__menu a::before {
		transition: none;
	}
}


/* --------------------------------------------------------------------------
   Back to top
   -------------------------------------------------------------------------- */

.mtfs-to-top {
	position: fixed;
	right: var(--mtfs-space-5);
	bottom: var(--mtfs-space-5);
	z-index: var(--mtfs-z-to-top);
	display: flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border: 0;
	border-radius: var(--mtfs-radius-pill);
	background: var(--mtfs-color-primary);
	color: var(--mtfs-white);
	box-shadow: var(--mtfs-shadow);
	opacity: 0;
	transform: translateY(8px);
	transition: opacity var(--mtfs-transition), transform var(--mtfs-transition);
}

.mtfs-to-top.is-visible {
	opacity: 1;
	transform: none;
}


/* --------------------------------------------------------------------------
   Floating contact tabs
   -------------------------------------------------------------------------- */

.mtfs-sticky-tabs {
	position: fixed;
	top: 50%;
	z-index: var(--mtfs-z-sticky-tabs);
	transform: translateY(-50%);
}

.mtfs-sticky-tabs--right { right: 0; }
.mtfs-sticky-tabs--left  { left: 0; }

.mtfs-sticky-tabs__list {
	display: grid;
	gap: 2px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.mtfs-sticky-tabs__item {
	position: relative;
}

.mtfs-sticky-tabs__tab {
	--mtfs-tab-bg: var(--mtfs-color-primary);

	display: flex;
	align-items: center;
	justify-content: center;
	width: 52px;
	height: 52px;
	border: 0;
	background: var(--mtfs-tab-bg);
	color: var(--mtfs-white);
	text-decoration: none;
	transition: filter var(--mtfs-transition);
}

.mtfs-sticky-tabs__tab:hover {
	filter: brightness(1.1);
	color: var(--mtfs-white);
}

.mtfs-sticky-tabs__panel {
	position: absolute;
	top: 0;
	width: min(360px, calc(100vw - 80px));
	padding: var(--mtfs-space-4);
	background: var(--mtfs-white);
	border-radius: var(--mtfs-radius);
	box-shadow: var(--mtfs-shadow-lg);
}

.mtfs-sticky-tabs--right .mtfs-sticky-tabs__panel { right: calc(100% + var(--mtfs-space-2)); }
.mtfs-sticky-tabs--left  .mtfs-sticky-tabs__panel { left:  calc(100% + var(--mtfs-space-2)); }

.mtfs-sticky-tabs__panel[hidden] {
	display: none;
}

.mtfs-sticky-tabs__panel-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--mtfs-space-3);
	margin-bottom: var(--mtfs-space-3);
	color: var(--mtfs-color-heading);
}

.mtfs-sticky-tabs__close {
	padding: var(--mtfs-space-1);
	border: 0;
	background: none;
	color: inherit;
}

/* On phones the column becomes a bar pinned to the bottom edge. */
@media (max-width: 767.98px) {

	.mtfs-sticky-tabs {
		top: auto;
		right: 0;
		bottom: 0;
		left: 0;
		transform: none;
	}

	.mtfs-sticky-tabs__list {
		grid-auto-flow: column;
		grid-auto-columns: 1fr;
	}

	.mtfs-sticky-tabs__tab {
		width: 100%;
		height: 48px;
	}

	.mtfs-sticky-tabs__panel {
		position: fixed;
		top: auto;
		right: var(--mtfs-space-3);
		bottom: 56px;
		left: var(--mtfs-space-3);
		width: auto;
		max-height: 70vh;
		overflow-y: auto;
	}
}


/* --------------------------------------------------------------------------
   Image + caption card
   --------------------------------------------------------------------------
   Measured from the Figma: 3:2 image, 82px caption band, 1px border, and the
   caption centred so a two-line title still lines up with its neighbours.
   -------------------------------------------------------------------------- */

.mtfs-icard {
	display: flex;
	flex-direction: column;
	height: 100%;
	border: 1px solid var(--mtfs-color-border);
	border-radius: var(--mtfs-radius-sm);
	background: var(--mtfs-white);
	overflow: hidden;
	text-decoration: none;
	transition: border-color var(--mtfs-transition), box-shadow var(--mtfs-transition), transform var(--mtfs-transition);
}

a.mtfs-icard:hover {
	border-color: var(--mtfs-color-primary);
	box-shadow: var(--mtfs-shadow);
	transform: translateY(-3px);
}

/* The shape comes from the section's "Image shape" control — a grid of
   portrait certificate scans and a grid of landscape product photos are the
   same card, and neither gets cropped to suit the other. */
.mtfs-icard__media {
	overflow: hidden;
	aspect-ratio: var(--mtfs-icard-ratio, var(--mtfs-ratio-landscape));
	background: var(--mtfs-color-surface);
}

.mtfs-image-cards--ratio-photo {
	--mtfs-icard-ratio: var(--mtfs-ratio-photo);
}

.mtfs-image-cards--ratio-square {
	--mtfs-icard-ratio: var(--mtfs-ratio-square);
}

.mtfs-image-cards--ratio-portrait {
	--mtfs-icard-ratio: var(--mtfs-ratio-portrait);
}

.mtfs-icard__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 0.45s ease;
}

a.mtfs-icard:hover .mtfs-icard__media img {
	transform: scale(1.06);
}

/* The band grows to fill whatever height the tallest card in the row needs —
   flex:1 plus a minimum, rather than a fixed height that a two-line title
   would overflow.

   The minimum is the design's one-line band. It used to be set to the height
   of a TWO-line band, which padded every single-line caption out by 24px and
   made a row of short titles taller than the frame.

   Titles sit at the TOP of the band, not its middle: where a row holds both
   one- and two-line captions the frame lines their first lines up with each
   other, which centring the short ones breaks. Rows whose captions all run to
   the same depth read the same either way. */
.mtfs-icard__body {
	display: flex;
	flex: 1;
	align-items: flex-start;
	justify-content: center;
	min-height: var(--mtfs-icard-caption-h);
	padding: var(--mtfs-space-4);
	text-align: center;
}

.mtfs-icard__title {
	margin: 0;
	/* 03-base.css balances heading line lengths, which rewrapped these
	   captions differently from the design. Card captions wrap naturally. */
	/* 'wrap', not 'normal' — normal is not a text-wrap value, so the
	   declaration was dropped and the balanced wrap stayed in force. */
	text-wrap: wrap;
	font-size: var(--mtfs-size-h4);
	font-weight: 500;
	line-height: var(--mtfs-line-height-card);
	color: var(--mtfs-color-heading);
}

a.mtfs-icard:hover .mtfs-icard__title {
	color: var(--mtfs-color-primary);
}


/* --------------------------------------------------------------------------
   Slider
   --------------------------------------------------------------------------
   Swiper handles the sliding, the drag, the looping and the breakpoints. Only
   the skin lives here: the arrow buttons from the design, and the breathing
   room a card's hover lift needs inside the clipping viewport.

   Swiper is only loaded on pages that contain a slider — see
   mtfs_page_has_slider() in inc/enqueue.php.
   -------------------------------------------------------------------------- */

/* The heading inside this row carries mb-0, because the row is what holds the
   gap — and that gap is the same 60px a heading block gets anywhere else, so a
   carousel section lines up with the static grid above it. */
.mtfs-slider__head {
	margin-bottom: var(--mtfs-heading-space);
}

.mtfs-slider__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: var(--mtfs-slider-btn);
	height: var(--mtfs-slider-btn);

	/* A button carries the browser's own 1px 6px padding, which shrank the
	   content box to 26px — and 03-base.css caps every svg at max-width:100%,
	   so the chevron was capped to that instead of the size set below. */
	padding: 0;
	border: 1px solid var(--mtfs-color-border);
	border-radius: var(--mtfs-radius);
	background: var(--mtfs-white);
	color: var(--mtfs-color-heading);
	transition: background-color var(--mtfs-transition), border-color var(--mtfs-transition), color var(--mtfs-transition);
}

/* The template asks for an 18px icon, which every other chevron in the theme
   is; here the design draws a noticeably bigger mark, so the size is set on
   the SVG rather than forked in two templates.

   The stroke does NOT scale with it. The icon set is drawn on a 24 grid at
   stroke-width 2, so blowing the box up to 34 also thickened the line to
   2.8px — the design keeps it at 2 however large the chevron is. */
.mtfs-slider__btn .mtfs-icon {
	width: var(--mtfs-slider-icon);
	height: var(--mtfs-slider-icon);
	vector-effect: non-scaling-stroke;
}

.mtfs-slider__btn .mtfs-icon * {
	vector-effect: non-scaling-stroke;
}

.mtfs-slider__btn:hover {
	border-color: var(--mtfs-color-primary);
	background: var(--mtfs-color-primary);
	color: var(--mtfs-white);
}

/* Swiper adds this class when there is nothing further in that direction. */
.mtfs-slider__btn.is-disabled {
	opacity: 0.4;
	pointer-events: none;
}

/*
 * Swiper clips its viewport, which would cut off a card's hover lift and its
 * shadow. Padding inside the slider plus an equal negative margin gives the
 * card room without shifting the row's alignment.
 */
.mtfs-slider {
	padding: var(--mtfs-space-2);
	margin: calc(var(--mtfs-space-2) * -1);
}

/* Equal-height slides, so a two-line caption does not leave a short card. */
.mtfs-slider .swiper-slide {
	height: auto;
}

.mtfs-slider .swiper-slide > .mtfs-icard {
	height: 100%;
}



/* A single wide card can put its title in one half and its copy in the other —
   the ventilation card that closes the industries page. */
@media (min-width: 768px) {

	.mtfs-cards--split .card-body {
		display: grid;
		grid-template-columns: 1fr 1fr;
		gap: var(--mtfs-gutter-wide);
		align-items: start;
	}

	.mtfs-cards--split .card-title {
		margin-bottom: 0;
	}
}


/* Picture beside the text ---------------------------------------------------
   The deep-processing frame lists its manufacturing processes as full-width
   cards with a photograph standing on the left and the copy beside it.
   Measured from that frame at 1920: the card runs the container's 1280 and is
   226 tall, the picture 220x180 inside 24 of padding.

   The picture is a flex item of its own rather than the card's usual
   card-img-top, so it keeps its width whatever the copy beside it does. */

.mtfs-cards--aside .card {
	flex-direction: row;
	align-items: flex-start;
	padding: var(--mtfs-space-5);
	gap: var(--mtfs-space-5);
}

.mtfs-cards--aside .mtfs-card__media {
	flex: 0 0 var(--mtfs-card-aside-w);
	width: var(--mtfs-card-aside-w);
	height: var(--mtfs-card-aside-h);
	overflow: hidden;
	border-radius: var(--mtfs-radius);
}

.mtfs-cards--aside .mtfs-card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* The body already sits inside the card's own padding above. */
.mtfs-cards--aside .card-body {
	padding: 0;
}

/* Stacked on a phone, where 220 of picture leaves the copy nothing. */
@media (max-width: 575.98px) {

	.mtfs-cards--aside .card {
		flex-direction: column;
	}

	.mtfs-cards--aside .mtfs-card__media {
		width: 100%;
		flex-basis: auto;
	}
}


/* Heading beside the grid ---------------------------------------------------
   The deep-processing frame's filter-classification band, and the welded-mesh
   frame's application areas, set the heading in the left half of the row with
   the cards in the right — the same 610 / 610 split on the same 60 gutter that
   a text-and-image band uses.

   The template puts both halves in a row of their own, so the grid inside the
   right half keeps its own gutter and a two-column grid still works there. */

/*
 * The wide gutter goes on the container as well as the row: a container's
 * padding reads the same variable the row's negative margins do, so a row told
 * about it on its own hangs 18 past the container. Only once the two halves
 * are side by side — stacked, the row keeps the ordinary gutter.
 */
@media (min-width: 992px) {

	.mtfs-cards--heading-beside > .container,
	.mtfs-cards__beside {
		--bs-gutter-x: var(--mtfs-gutter-wide);
	}

	.mtfs-cards--heading-beside .mtfs-cards__beside .mtfs-heading {
		margin-bottom: 0;
	}
}

/* Beside a heading the cards pack down their columns rather than lining up in
   rows of equal height: the welded-mesh frame runs three down the left column
   and two down the right, each card only as tall as its own copy. Bootstrap's
   row is turned into a multi-column block for that, and the columns it holds
   go full width so the count comes from the column rule rather than the class. */
@media (min-width: 992px) {

	.mtfs-cards--heading-beside .mtfs-cards__beside > * > .row {
		display: block;
		columns: var(--mtfs-cards-beside-cols, 1);
		column-gap: var(--mtfs-space-5);
	}

	.mtfs-cards--heading-beside .mtfs-cards__beside > * > .row > * {
		width: 100%;
		max-width: none;
		margin-bottom: var(--mtfs-space-5);
		break-inside: avoid;
	}

	/* The last card carries no gap under it, or the column runs long. */
	.mtfs-cards--heading-beside .mtfs-cards__beside > * > .row > *:last-child {
		margin-bottom: 0;
	}
}

/* Plain: no fill and no hairline, the card sitting straight on the band. The
   jingang frame's specification pairs are held apart by the title-beside-text
   split alone, with nothing drawn round them. */
.mtfs-cards--plain .card {
	--bs-card-bg: transparent;
	--bs-card-border-width: 0;
}

.mtfs-cards--plain .card-body {
	padding-inline: 0;
}

/* The left cell of a split card: the title with its line of explanation under
   it, which is how the jingang frame writes a specification pair. */
.mtfs-card__lead-text {
	margin: var(--mtfs-space-3) 0 0;
	font-size: var(--mtfs-size-body-2);
	line-height: var(--mtfs-line-height-answer);
	color: var(--mtfs-color-body);
}

/* Card copy written a line at a time becomes a list rather than a paragraph. */
.mtfs-card__list {
	margin: 0;
	padding-left: var(--mtfs-space-4);
}

.mtfs-card__list > li + li {
	margin-top: var(--mtfs-space-2);
}

/* Related insights ----------------------------------------------------------
   The blog frame's sidebar stacks the same card the home page draws inside the
   widget's tinted panel: picture, the date and reading time, then the title.
   The panel already carries the tint, so the cards are white against it. */

.mtfs-widget__cards {
	display: grid;
	gap: var(--mtfs-space-5);
}

.mtfs-bcard--aside {
	background: var(--mtfs-white);
}

/* No excerpt to take the slack, so the body is only as tall as it needs. */
.mtfs-bcard--aside .mtfs-bcard__body {
	padding-bottom: var(--mtfs-space-5);
}

.mtfs-bcard--aside .mtfs-bcard__title {
	display: -webkit-box;
	margin: 0;
	overflow: hidden;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: var(--mtfs-bcard-lines);
}
