/*
 * Homepage marketing sections: capability grid, alternating showcase rows and
 * their illustrations.
 *
 * Written mobile-first (base rules are the narrow layout, min-width queries
 * widen it). landing.css predates this and is desktop-first, so keep the two
 * conventions in their own files rather than interleaving them.
 *
 * Breakpoints match the rest of the theme: 600px, 720px, 900px, 1024px.
 */

/* Brand lockup ------------------------------------------------------------ */

/*
 * The full lockup carries its own wordmark, so it is sized by height and keeps
 * its aspect ratio rather than sitting next to a separate text element.
 */
.tf-brand-lockup {
	display: block;
	width: auto;
	height: 34px;
}

@media (max-width: 600px) {
	.tf-brand-lockup {
		height: 26px;
	}

	/* Beats the block's inline width without taking sizing away from it. */
	.tf-brand .custom-logo {
		max-width: 104px;
	}
}

/* Hero product cards ------------------------------------------------------ */

.tf-hero-products {
	display: flex;
	flex-direction: column;
	gap: 24px;
	width: 100%;
	min-width: 0;
}

.tf-hero-product {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 20px;
	padding: 22px;
	border: 1px solid var(--tf-border);
	border-radius: 22px;
	background: var(--tf-surface);
	box-shadow: var(--tf-shadow-lg);
}

.tf-hero-product-head {
	display: flex;
	align-items: flex-start;
	gap: 14px;
}

.tf-hero-product-mark {
	display: grid;
	flex: none;
	place-items: center;
	width: 52px;
	height: 52px;
	overflow: hidden;
	border-radius: 13px;
	background: var(--tf-text);
}

.tf-hero-product-mark img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* The FlowSync mark is a line drawing, so it needs room rather than a crop. */
.tf-hero-product-flowsync .tf-hero-product-mark img {
	width: 68%;
	height: 68%;
	object-fit: contain;
}

.tf-hero-product-id {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.tf-hero-product-eyebrow {
	color: var(--tf-muted);
	font-family: "JetBrains Mono", ui-monospace, monospace;
	font-size: 11px;
	font-weight: 600;
}

.tf-hero-product-faltapay .tf-hero-product-eyebrow {
	color: oklch(60% 0.2 38);
}

.tf-hero-product-flowsync .tf-hero-product-eyebrow {
	color: oklch(52% 0.12 175);
}

.tf-hero-product-id strong {
	color: var(--tf-text);
	font-size: 22px;
	font-weight: 700;
	line-height: 1.15;
	letter-spacing: -0.01em;
}

.tf-hero-product-id small {
	color: var(--tf-muted);
	font-size: 13.5px;
	line-height: 1.35;
}

.tf-hero-product-arabic-badge {
	display: inline-block;
	align-self: flex-start;
	margin-top: 6px;
	padding: 2px 8px;
	border-radius: 5px;
	background: oklch(95% 0.035 62);
	color: var(--tf-accent-ink);
	font-size: 11px;
	font-weight: 600;
	line-height: 1.5;
	letter-spacing: 0;
}

/* Tinted stage behind each mock */

.tf-hero-product-stage {
	position: relative;
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 18px;
	border-radius: 16px;
}

.tf-hero-product-faltapay .tf-hero-product-stage {
	background: oklch(95% 0.035 62);
}

.tf-hero-product-flowsync .tf-hero-product-stage {
	background: oklch(95% 0.028 175);
}

/* The little application window inside each stage */

.tf-hero-window {
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
	border: 1px solid color-mix(in oklch, var(--tf-border) 70%, transparent);
	border-radius: 10px;
	background: var(--tf-surface);
	box-shadow: var(--tf-shadow-sm);
}

.tf-hero-window-bar {
	display: flex;
	align-items: center;
	gap: 4px;
	padding: 7px 10px;
	border-bottom: 1px solid color-mix(in oklch, var(--tf-border) 60%, transparent);
}

.tf-hero-window-bar i {
	width: 5px;
	height: 5px;
	border-radius: 999px;
	background: var(--tf-border-strong);
}

.tf-hero-window-body {
	display: flex;
	flex-direction: column;
	gap: 9px;
	padding: 12px;
}

.tf-hero-bar {
	flex: 1 1 auto;
	height: 9px;
	min-width: 0;
	border-radius: 999px;
	background: var(--tf-inset);
}

/* Checkout mock */

.tf-hero-pay-row {
	display: flex;
	align-items: center;
	gap: 10px;
}

/* Both providers ship square icons rather than wordmarks, so tile them. */
.tf-hero-pay-logo {
	flex: none;
	width: 24px;
	height: 24px;
	padding: 3px;
	border: 1px solid color-mix(in oklch, var(--tf-border) 70%, transparent);
	border-radius: 7px;
	background: var(--tf-surface);
	object-fit: contain;
}

.tf-hero-pay-cta {
	align-self: flex-end;
	margin-top: 2px;
	padding: 7px 14px;
	border-radius: 7px;
	background: var(--tf-text);
	color: var(--tf-bg);
	font-size: 11px;
	font-weight: 600;
	line-height: 1;
}

/* Sync mock */

.tf-hero-source-mark {
	display: grid;
	place-items: center;
	width: 26px;
	height: 26px;
	margin-bottom: 2px;
}

.tf-hero-source-mark img {
	width: 24px;
	height: 24px;
	object-fit: contain;
}

.tf-hero-sync-row {
	display: flex;
	align-items: center;
	gap: 9px;
}

.tf-hero-sync-row i {
	flex: none;
	width: 9px;
	height: 9px;
	border-radius: 999px;
	background: var(--tf-inset);
}

.tf-hero-targets {
	display: flex;
	flex: none;
	flex-direction: column;
	gap: 10px;
}

.tf-hero-target {
	position: relative;
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	border: 1px solid color-mix(in oklch, var(--tf-border) 70%, transparent);
	border-radius: 11px;
	background: var(--tf-surface);
	box-shadow: var(--tf-shadow-sm);
}

/*
 * One dashed run per destination, drawn from the tile back towards the window.
 * Done per tile rather than as one SVG so it stays legible however narrow the
 * gap between the window and the tiles gets.
 */
.tf-hero-target::before {
	content: "";
	position: absolute;
	top: 50%;
	right: 100%;
	width: 14px;
	border-top: 2px dashed color-mix(in oklch, oklch(52% 0.12 175) 55%, var(--tf-border));
}

.tf-hero-target img {
	width: 74%;
	height: 74%;
	object-fit: contain;
}

@media (min-width: 480px) {
	.tf-hero-product {
		padding: 26px;
	}

	.tf-hero-product-mark {
		width: 58px;
		height: 58px;
	}

	.tf-hero-product-id strong {
		font-size: 26px;
	}

	.tf-hero-product-id small {
		font-size: 14.5px;
	}

	.tf-hero-target {
		width: 46px;
		height: 46px;
	}
}

/*
 * Wide enough to stack the cards. The second card overlaps the first, pulled up
 * and across so the pair reads as one composition rather than a list.
 */
@media (min-width: 900px) {
	/*
	 * The pair needs more room than the default hero split gives, otherwise the
	 * second card has to sit on top of the first and hides its mock.
	 */
	.tf-hero-inner-products {
		grid-template-columns: minmax(0, 0.82fr) minmax(0, 1fr);
	}

	.tf-hero-products {
		display: block;
		padding-bottom: 32px;
	}

	/*
	 * The cards sit almost side by side and only just overlap, so each mock
	 * stays fully readable. The negative margin is a percentage of the
	 * container width, which is what pulls the second card up alongside.
	 */
	.tf-hero-product-1,
	.tf-hero-product-2 {
		width: 53%;
	}

	.tf-hero-product-2 {
		margin-top: -36%;
		margin-left: auto;
	}

	/*
	 * A slight outward fan: each card leans away from the centre. Kept to the
	 * wide layout because a tilted full-width card would push its corners past
	 * the viewport edge.
	 */
	.tf-hero-product-1 {
		transform: rotate(-2deg);
	}

	.tf-hero-product-2 {
		transform: rotate(2deg);
	}

	.tf-hero-product-stage {
		gap: 16px;
		padding: 16px;
	}

}


/* Product hero screenshots ------------------------------------------------ */

/*
 * FaltaPay hero pairs two integration cards. Same idea as the homepage
 * product cards: stacked and square on narrow screens, overlapped and fanned
 * outwards once there is room.
 */
.tf-product-shots {
	display: flex;
	flex-direction: column;
	gap: 20px;
	width: 100%;
	min-width: 0;
}

/*
 * The screenshots already include their own card and padding, so this only
 * rounds and lifts them. Adding a border and surface here would read as a
 * second frame around the first.
 */
.tf-product-shot {
	margin: 0;
	overflow: hidden;
	border-radius: 18px;
	box-shadow: var(--tf-shadow-lg);
}

.tf-product-shot img {
	display: block;
	width: 100%;
	height: auto;
}

@media (min-width: 900px) {
	.tf-product-shots {
		display: block;
		padding-bottom: 28px;
	}

	.tf-product-shot-1,
	.tf-product-shot-2 {
		width: 62%;
	}

	.tf-product-shot-2 {
		margin-top: -34%;
		margin-left: auto;
	}

	/* Leaning away from the centre, matching the homepage pair. */
	.tf-product-shot-1 {
		transform: rotate(-2deg);
	}

	.tf-product-shot-2 {
		transform: rotate(2deg);
	}
}

/* Secondary CTA ----------------------------------------------------------- */

/*
 * Sits under the main call to action for the smaller audience, deliberately
 * quiet so it does not compete with it.
 */
.tf-cta-aside {
	margin-top: 20px;
	text-align: center;
}

.tf-cta-aside p {
	margin: 0;
	color: var(--tf-muted);
	font-size: 14px;
}

.tf-cta-aside strong {
	color: var(--tf-text-2);
	font-weight: 600;
}

/*
 * A footnote inside the dark panel rather than under it. .tf-cta is a centred
 * flex column with its own gap, so this only needs the dark-band colours and
 * a position, which lifts it above the panel's dot pattern.
 */
.tf-cta-note {
	position: relative;
	max-width: 46ch;
	margin: -6px 0 0;
	color: color-mix(in oklch, var(--tf-bg) 62%, transparent);
	font-size: 14px;
	line-height: 1.5;
}

.tf-cta-note a {
	color: var(--tf-bg);
	text-decoration: underline;
	text-underline-offset: 3px;
}

.tf-cta-note a:hover {
	text-decoration-thickness: 2px;
}

/* Bridge comparison ------------------------------------------------------- */

/*
 * These two sit full width inside a section rather than in a media column, so
 * they need more room than the 460px the illustrations default to. Doubled up
 * to outrank the plain .tf-figure width, which is declared later in this file.
 */
.tf-figure.tf-figure-bridge,
.tf-figure.tf-figure-flow {
	max-width: 940px;
	margin-top: 12px;
}

/*
 * Two columns making the same point from opposite sides: a provider reaching a
 * few plugins alone, against the same provider reaching all of them through
 * FaltaPay. The "after" column is the one that should catch the eye.
 */
.tf-bridge {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 20px;
	width: 100%;
}

.tf-bridge-panel {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 10px;
	padding: 24px 20px 20px;
	border: 1px solid var(--tf-border);
	border-radius: 18px;
	text-align: center;
}

.tf-bridge-before {
	background: var(--tf-surface-alt);
}

.tf-bridge-after {
	border-color: color-mix(in oklch, var(--tf-accent) 32%, var(--tf-border));
	background: var(--tf-surface);
	box-shadow: var(--tf-shadow-md);
}

.tf-bridge-label {
	color: var(--tf-muted);
	font-family: "JetBrains Mono", ui-monospace, monospace;
	font-size: 10.5px;
	font-weight: 600;
}

.tf-bridge-after .tf-bridge-label {
	color: var(--tf-accent-ink);
}

.tf-bridge-node {
	padding: 9px 16px;
	border: 1px solid var(--tf-border);
	border-radius: 999px;
	background: var(--tf-surface);
	color: var(--tf-text);
	font-size: 13px;
	font-weight: 600;
	line-height: 1.2;
}

.tf-bridge-hub {
	border-color: transparent;
	background: var(--tf-text);
	color: var(--tf-bg);
	box-shadow: var(--tf-shadow-sm);
}

/*
 * The chart is centred in its panel but laid out from the left, so the stem
 * dropping out of a node lines up with the spine of the tree below it.
 * --tf-spine is that shared x position.
 */
.tf-bridge-chart {
	--tf-spine: 11px;
	--tf-branch: 23px;
	--tf-line: var(--tf-border-strong);
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	width: fit-content;
	max-width: 100%;
	margin-inline: auto;
	text-align: left;
}

.tf-bridge-after .tf-bridge-chart {
	--tf-line: color-mix(in oklch, var(--tf-accent) 55%, var(--tf-border));
}

.tf-bridge-stem {
	width: 0;
	height: 14px;
	margin-left: var(--tf-spine);
	border-left: 2px dashed var(--tf-line);
}

/*
 * A branching tree, so every plugin has its own line back to the spine. The
 * earlier bracket only touched the outermost items, which left the ones in
 * between looking unconnected.
 */
.tf-bridge-tree {
	list-style: none;
	margin: 0;
	padding: 0 0 0 calc(var(--tf-spine) + var(--tf-branch));
}

.tf-bridge-tree li {
	position: relative;
	padding: 4px 0;
}

/* The spine, drawn per item and stopping at the last elbow. */
.tf-bridge-tree li::before {
	content: "";
	position: absolute;
	left: calc(var(--tf-branch) * -1);
	top: 0;
	bottom: 0;
	border-left: 2px dashed var(--tf-line);
}

.tf-bridge-tree li:last-child::before {
	bottom: 50%;
}

/* The elbow out to each plugin. */
.tf-bridge-tree li::after {
	content: "";
	position: absolute;
	left: calc(var(--tf-branch) * -1);
	top: 50%;
	width: var(--tf-branch);
	border-top: 2px dashed var(--tf-line);
}

.tf-bridge-chip {
	padding: 6px 11px;
	border: 1px solid var(--tf-border);
	border-radius: 8px;
	background: var(--tf-surface);
	color: var(--tf-text-2);
	font-size: 12px;
	font-weight: 600;
	line-height: 1.2;
}

.tf-bridge-after .tf-bridge-chip {
	border-color: color-mix(in oklch, var(--tf-accent) 22%, var(--tf-border));
	background: var(--tf-accent-soft);
	color: var(--tf-accent-ink);
}

.tf-bridge-note {
	margin-top: 2px;
	color: var(--tf-muted);
	font-size: 12.5px;
}

.tf-bridge-after .tf-bridge-note {
	color: var(--tf-text-2);
	font-weight: 600;
}

@media (min-width: 720px) {
	.tf-bridge {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 24px;
		/* Matched heights so the pair reads as one comparison, not two boxes. */
		align-items: stretch;
	}

	/* Push each note to the foot of its panel so they line up across the pair. */
	.tf-bridge-note {
		margin-top: auto;
		padding-top: 8px;
	}

	/*
	 * One side lists far fewer plugins, so it has spare height. Float its chart
	 * in the middle of that space rather than leaving a void under it.
	 */
	.tf-bridge-chart {
		margin-block: auto;
	}
}

/* Payment lifecycle flow -------------------------------------------------- */

.tf-flow {
	list-style: none;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 34px;
	margin: 0;
	padding: 0;
	width: 100%;
	counter-reset: tf-flow;
}

.tf-flow-stage {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	padding: 22px 18px;
	border: 1px solid var(--tf-border);
	border-radius: 16px;
	background: var(--tf-surface);
	box-shadow: var(--tf-shadow-sm);
	text-align: center;
}

/* The connector between stages: downwards when stacked, across when in a row. */
.tf-flow-stage + .tf-flow-stage::before {
	content: "";
	position: absolute;
	left: 50%;
	bottom: 100%;
	width: 0;
	height: 34px;
	border-left: 2px dashed var(--tf-border-strong);
}

.tf-flow-icon {
	display: grid;
	place-items: center;
	width: 42px;
	height: 42px;
	border-radius: 999px;
	background: var(--tf-accent-soft);
	color: var(--tf-accent-ink);
}

.tf-flow-icon svg {
	width: 19px;
	height: 19px;
}

.tf-flow-stage strong {
	color: var(--tf-text);
	font-size: 15px;
	font-weight: 700;
	line-height: 1.25;
}

.tf-flow-stage small {
	color: var(--tf-muted);
	font-size: 12.5px;
	line-height: 1.4;
}

@media (min-width: 900px) {
	.tf-flow {
		grid-template-columns: repeat(4, minmax(0, 1fr));
		gap: 30px;
	}

	.tf-flow-stage + .tf-flow-stage::before {
		left: auto;
		right: 100%;
		bottom: auto;
		top: 42px;
		width: 30px;
		height: 0;
		border-left: 0;
		border-top: 2px dashed var(--tf-border-strong);
	}
}

/* Provider capability list ------------------------------------------------ */

.tf-provider-points,
.tf-product-points {
	list-style: none;
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
	gap: 8px 16px;
	margin: 4px 0 0;
	padding: 0;
}

/*
 * The price badge below carries a -4px top margin so it can tuck under a
 * paragraph. On a product card the points list sits between the two, so the
 * gap has to come from here or the badge lands on the last point.
 */
.tf-product-points {
	margin-bottom: 24px;
}

.tf-provider-points li,
.tf-product-points li {
	display: flex;
	align-items: center;
	gap: 8px;
	color: var(--tf-text-2);
	font-size: 13.5px;
	line-height: 1.3;
}

.tf-provider-points .tf-check,
.tf-product-points .tf-check {
	flex: none;
	color: var(--tf-success);
}

/* A point that carries its own translation sets it on the line below. */
.tf-product-point-alt {
	display: block;
	color: var(--tf-muted);
}

/* Icon tones -------------------------------------------------------------- */

/*
 * Icons are grouped into three colour families so a grid can be scanned by
 * tone: payments, operations, integrations. The theme accent is already the
 * payments orange, so that family inherits the default and only the other two
 * are restated here.
 *
 * Both selectors are used because the family has to beat .tf-feature-icon in
 * landing.css and .tf-capability-icon below, which are equally specific.
 */
.wp-block-thefalta-icon.tf-icon-tone-operations,
.tf-flow-icon.tf-icon-tone-operations {
	background: var(--tf-success-soft);
	color: oklch(37% 0.11 150);
	border-color: color-mix(in oklch, var(--tf-success) 18%, transparent);
}

.wp-block-thefalta-icon.tf-icon-tone-integrations,
.tf-flow-icon.tf-icon-tone-integrations {
	background: oklch(95% 0.03 250);
	color: oklch(45% 0.14 253);
	border-color: color-mix(in oklch, oklch(52% 0.14 250) 18%, transparent);
}

/* Capability grid -------------------------------------------------------- */

.tf-capability-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 36px 40px;
}

.tf-capability {
	display: grid;
	grid-template-columns: 44px minmax(0, 1fr);
	gap: 4px 16px;
	align-items: start;
	/*
	 * Cards in a row are stretched to the tallest one. Without this the default
	 * align-content: stretch pours that extra height into the auto rows and
	 * prises the heading away from its paragraph.
	 */
	align-content: start;
}

/*
 * The icon block also carries .tf-feature-icon from landing.css, which is a
 * 40px rounded square with a bottom margin. Override both here rather than
 * letting the two sets of rules half-apply.
 */
.tf-capability-icon {
	display: grid;
	place-items: center;
	grid-column: 1;
	grid-row: 1;
	width: 44px;
	height: 44px;
	margin: 0;
	border: 0;
	border-radius: 999px;
	background: var(--tf-accent-soft);
	color: var(--tf-accent-ink);
}

/*
 * Everything except the icon lives in column two. Placing it explicitly keeps
 * the row heights predictable no matter how many children a card has, which
 * matters because one card carries an extra partner badge.
 */
.tf-capability > :not(.tf-capability-icon) {
	grid-column: 2;
}

.tf-capability-icon svg {
	width: 19px;
	height: 19px;
}

.tf-capability h3 {
	margin: 0;
	padding-top: 9px;
	color: var(--tf-text);
	font-size: 17px;
	font-weight: 700;
	line-height: 1.3;
}

.tf-capability p {
	margin: 0;
	color: var(--tf-text-2);
	font-size: 15px;
	line-height: 1.55;
}

.tf-capability .tf-partner-badge {
	justify-self: start;
	margin-top: 12px;
}

@media (min-width: 600px) {
	.tf-capability-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 1024px) {
	.tf-capability-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 44px 48px;
	}
}

/* Section action row ----------------------------------------------------- */

/*
 * blocks.css zeroes the block gap on every direct child of .tf-container, so
 * this needs matching specificity to keep its own spacing.
 */
.tf-container > .tf-section-actions {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 18px;
	margin-top: 56px;
	text-align: center;
}

.tf-section-actions .tf-text-link,
.tf-section-actions .wp-block-button__link {
	white-space: nowrap;
}

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

/*
 * blocks.css zeroes the block gap on direct children of .tf-container, so the
 * search row states its own spacing at matching specificity, the way the
 * section action row above does.
 */
.tf-container > .tf-support-search {
	max-width: 560px;
	margin: 40px auto 0;
}

.tf-support-search .wp-block-search__inside-wrapper {
	padding: 6px;
	border: 1px solid var(--tf-border);
	border-radius: 12px;
	background: var(--tf-surface);
}

.tf-support-search .wp-block-search__input {
	padding: 10px 14px;
	border: 0;
	background: none;
	font-size: 15px;
}

.tf-support-search .wp-block-search__input:focus {
	outline: 0;
}

.tf-support-search .wp-block-search__button {
	min-height: 42px;
	margin: 0;
	padding: 10px 18px;
	border: 1px solid var(--tf-text);
	border-radius: 8px;
	background: var(--tf-text);
	color: var(--tf-bg);
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
}

@media (min-width: 600px) {
	.tf-container > .tf-section-actions {
		flex-direction: row;
		justify-content: center;
		gap: 28px;
	}
}

/* Partner badge ---------------------------------------------------------- */

.tf-partner-badge {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	max-width: 100%;
	padding: 6px 12px 6px 8px;
	border: 1px solid var(--tf-border);
	border-radius: 999px;
	background: var(--tf-surface);
	box-shadow: var(--tf-shadow-sm);
	line-height: 1;
}

.tf-partner-badge-logo {
	width: auto;
	max-width: 84px;
	height: 20px;
	border-radius: 3px;
	object-fit: contain;
}

.tf-partner-badge-name {
	color: var(--tf-text);
	font-size: 13px;
	font-weight: 700;
}

.tf-partner-badge-check {
	display: grid;
	place-items: center;
	width: 16px;
	height: 16px;
	border-radius: 999px;
	background: var(--tf-success);
	color: var(--tf-on-accent);
}

.tf-partner-badge-check svg {
	width: 10px;
	height: 10px;
}

.tf-partner-badge-label {
	color: var(--tf-text-2);
	font-family: "JetBrains Mono", ui-monospace, monospace;
	font-size: 10.5px;
	font-weight: 600;
	white-space: nowrap;
}

/* Alternating showcase rows ---------------------------------------------- */

.tf-showcase {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 40px;
	align-items: center;
}

.tf-showcase + .tf-showcase {
	margin-top: 72px;
}

.tf-showcase-copy {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 16px;
	min-width: 0;
}

.tf-showcase-copy h3 {
	margin: 0;
	color: var(--tf-text);
	font-size: clamp(24px, 3.4vw, 32px);
	font-weight: 700;
	line-height: 1.15;
	letter-spacing: -0.01em;
}

.tf-showcase-copy p {
	margin: 0;
	color: var(--tf-text-2);
	font-size: 16px;
	line-height: 1.65;
}

.tf-eyebrow {
	margin: 0;
	color: var(--tf-accent-ink);
	font-family: "JetBrains Mono", ui-monospace, monospace;
	font-size: 11.5px;
	font-weight: 600;
}

.tf-showcase-media {
	min-width: 0;
}

@media (min-width: 900px) {
	.tf-showcase {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 72px;
	}

	.tf-showcase + .tf-showcase {
		margin-top: 104px;
	}

	/*
	 * Copy stays first in the document on every row so the reading order never
	 * depends on the visual arrangement; only the painted order alternates.
	 */
	.tf-showcase-reverse .tf-showcase-copy {
		order: 2;
	}

	.tf-showcase-reverse .tf-showcase-media {
		order: 1;
	}
}

/* Illustrations ---------------------------------------------------------- */

.tf-figure {
	position: relative;
	width: 100%;
	max-width: 460px;
	margin-inline: auto;
}

.tf-figure-thread {
	display: none;
}

/* Setup steps */

.tf-figure-setup,
.tf-figure-support {
	display: flex;
	flex-direction: column;
	gap: 16px;
}

.tf-figure-step,
.tf-figure-note {
	display: flex;
	align-items: center;
	gap: 12px;
	width: 100%;
	padding: 16px 18px;
	border: 1px solid var(--tf-border);
	border-radius: 14px;
	background: var(--tf-surface);
	box-shadow: var(--tf-shadow-md);
	color: var(--tf-text);
	font-size: 14px;
	font-weight: 600;
	line-height: 1.35;
}

.tf-figure-step-icon {
	display: grid;
	flex: none;
	place-items: center;
	width: 34px;
	height: 34px;
	border-radius: 999px;
	background: var(--tf-inset);
	color: var(--tf-muted);
}

.tf-figure-step-icon svg {
	width: 16px;
	height: 16px;
}

.tf-figure-step-icon-done {
	background: var(--tf-success);
	color: var(--tf-on-accent);
}

/* Support context notes */

.tf-figure-note {
	flex-direction: column;
	align-items: flex-start;
	gap: 4px;
}

.tf-figure-note-label {
	color: var(--tf-muted);
	font-family: "JetBrains Mono", ui-monospace, monospace;
	font-size: 10.5px;
	font-weight: 600;
}

.tf-figure-note strong {
	font-size: 15px;
	font-weight: 700;
}

/* Recurring ledger */

.tf-figure-ledger {
	display: flex;
	flex-direction: column;
	gap: 1px;
	overflow: hidden;
	border: 1px solid var(--tf-border);
	border-radius: 14px;
	background: var(--tf-rule);
	box-shadow: var(--tf-shadow-md);
}

.tf-figure-ledger-row {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: 6px 10px;
	padding: 14px 16px;
	background: var(--tf-surface);
	font-size: 13px;
}

.tf-figure-ledger-label {
	color: var(--tf-text);
	font-weight: 600;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.tf-figure-ledger-date {
	color: var(--tf-muted);
	font-family: "JetBrains Mono", ui-monospace, monospace;
	font-size: 11.5px;
}

.tf-figure-ledger-amount {
	color: var(--tf-text);
	font-family: "JetBrains Mono", ui-monospace, monospace;
	font-size: 13px;
	font-weight: 600;
	text-align: right;
}

/* Secure checkout card */

.tf-figure-secure {
	padding-bottom: 34px;
}

.tf-figure-checkout {
	display: flex;
	flex-direction: column;
	gap: 12px;
	padding: 24px;
	border: 1px solid var(--tf-border);
	border-radius: 18px;
	background: var(--tf-surface);
	box-shadow: var(--tf-shadow-lg);
}

.tf-figure-checkout-mark {
	display: grid;
	place-items: center;
	width: 46px;
	height: 46px;
	margin-inline: auto;
	margin-bottom: 6px;
	border-radius: 999px;
	background: var(--tf-accent);
	color: var(--tf-on-accent);
}

.tf-figure-checkout-mark svg {
	width: 22px;
	height: 22px;
}

.tf-figure-bar {
	height: 12px;
	border-radius: 999px;
	background: var(--tf-inset);
}

.tf-figure-bar-short {
	width: 62%;
}

.tf-figure-cells {
	display: grid;
	grid-template-columns: repeat(5, minmax(0, 1fr));
	gap: 8px;
	margin-top: 6px;
}

.tf-figure-cells i {
	display: block;
	height: 38px;
	border-radius: 8px;
	background: var(--tf-inset);
}

.tf-figure-checkout-actions {
	display: grid;
	grid-template-columns: 1fr 1.6fr;
	gap: 10px;
	margin-top: 8px;
}

.tf-figure-checkout-cancel,
.tf-figure-checkout-submit {
	display: block;
	height: 38px;
	border-radius: 9px;
	background: var(--tf-inset);
}

/*
 * Stated outright rather than mixed with --tf-surface: white has zero chroma,
 * so its hue is powerless and oklch mixing swings the result towards yellow.
 */
.tf-figure-checkout-submit {
	background: oklch(76% 0.13 45);
}

.tf-figure-shield {
	position: absolute;
	right: 8px;
	bottom: 0;
	display: grid;
	place-items: center;
	width: 62px;
	height: 62px;
	border: 1px solid var(--tf-border);
	border-radius: 999px;
	background: var(--tf-text);
	color: var(--tf-bg);
	box-shadow: var(--tf-shadow-lg);
}

.tf-figure-shield svg {
	width: 26px;
	height: 26px;
}

@media (min-width: 600px) {
	.tf-figure-ledger-row {
		grid-template-columns: auto minmax(0, 1fr) auto auto;
		align-items: center;
		gap: 14px;
		padding: 15px 18px;
	}
}

@media (min-width: 900px) {
	/*
	 * Only stagger the stacked cards once there is room for the offset; below
	 * this they stay flush so nothing pushes past the viewport edge.
	 */
	.tf-figure-setup,
	.tf-figure-support {
		gap: 22px;
	}

	.tf-figure-step,
	.tf-figure-note {
		width: 86%;
	}

	.tf-figure-step-2,
	.tf-figure-note-2 {
		margin-inline-start: 7%;
	}

	.tf-figure-step-3,
	.tf-figure-note-3 {
		margin-inline-start: 14%;
	}

	.tf-figure-thread {
		display: block;
		position: absolute;
		inset: 0;
		width: 100%;
		height: 100%;
		fill: none;
		stroke: color-mix(in oklch, var(--tf-accent) 55%, var(--tf-border));
		stroke-width: 1.4;
		stroke-dasharray: 4 5;
	}
}

@media (prefers-reduced-motion: reduce) {
	.tf-figure-step,
	.tf-figure-note {
		transition: none;
	}
}

/* Feature cards that end in a link ---------------------------------------- */

/*
 * The three "What we do" cards each finish with a link. Their copy is different
 * lengths, so the link is pushed to the bottom of the card to keep the row of
 * links on one line.
 */
.tf-feature-grid-linked .tf-feature-card {
	display: flex;
	flex-direction: column;
}

.tf-feature-card-link {
	margin-top: auto;
	padding-top: 18px;
}

/* Service cards ----------------------------------------------------------- */

.tf-service-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 16px;
}

.tf-service-card {
	min-height: 100%;
	padding: 26px;
	border: 1px solid var(--tf-border);
	border-radius: 14px;
	background: var(--tf-surface);
	box-shadow: var(--tf-shadow-sm);
}

.tf-service-card .tf-service-icon {
	display: grid;
	place-items: center;
	width: 40px;
	height: 40px;
	margin-bottom: 18px;
	border: 1px solid var(--tf-border);
	border-radius: 10px;
	background: var(--tf-bg);
	color: var(--tf-accent-ink);
}

.tf-service-card .tf-service-icon svg {
	width: 19px;
	height: 19px;
}

.tf-service-card h3 {
	margin: 0 0 10px;
	color: var(--tf-text);
	font-size: 20px;
	font-weight: 700;
	line-height: 1.2;
}

.tf-service-card > p {
	margin: 0;
	color: var(--tf-text-2);
	font-size: 15px;
	line-height: 1.6;
}

.tf-service-includes-label {
	margin: 22px 0 10px;
	color: var(--tf-muted);
	font-family: "JetBrains Mono", monospace;
	font-size: 11px;
	font-weight: 600;
}

/*
 * The "Includes" items are scope markers rather than prose, so they read as a
 * wrapping row of chips instead of a bulleted column.
 */
.tf-service-includes {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	gap: 7px;
	margin: 0;
	padding: 0;
}

.tf-service-includes li {
	padding: 5px 10px;
	border: 1px solid var(--tf-border);
	border-radius: 999px;
	background: var(--tf-bg);
	color: var(--tf-text-2);
	font-size: 12.5px;
	line-height: 1.3;
}

@media (min-width: 720px) {
	.tf-service-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

/* Pricing plans ----------------------------------------------------------- */

.tf-plan-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 20px;
	max-width: 940px;
	margin: 48px auto 0;
	align-items: start;
}

.tf-plan {
	display: flex;
	flex-direction: column;
	padding: 32px 28px;
	border: 1px solid var(--tf-border);
	border-radius: 18px;
	background: var(--tf-surface);
	box-shadow: var(--tf-shadow-sm);
}

/*
 * The paid card carries the accent border rather than a scale transform, which
 * would blur its text and break the shared baseline with the free card.
 */
.tf-plan-featured {
	border-color: var(--tf-accent-ink);
	box-shadow: var(--tf-shadow-md);
}

.tf-plan-name {
	margin: 0 0 14px;
	color: var(--tf-accent-ink);
	font-family: "JetBrains Mono", ui-monospace, monospace;
	font-size: 12px;
	font-weight: 600;
}

.tf-plan-price,
.tf-plan .tf-price-amount {
	display: block;
	margin: 0;
	color: var(--tf-text);
	font-size: 44px;
	font-weight: 700;
	line-height: 1;
	letter-spacing: -0.03em;
}

.tf-plan-period {
	margin: 10px 0 0;
	color: var(--tf-muted);
	font-size: 13.5px;
}

/* A plan the dashboard has created but not priced yet. */
.tf-plan-price-tbc {
	font-size: 30px;
	letter-spacing: -0.02em;
}

/*
 * The free tier, deliberately quieter than a card: this page sells licences,
 * and the free plugin is downloaded from wordpress.org rather than bought here.
 */
.tf-plan-free {
	max-width: 940px;
	margin: 18px auto 0;
	color: var(--tf-muted);
	font-size: 14px;
	line-height: 1.55;
	text-align: center;
}

.tf-plan-free a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 3px;
}

.tf-plan-free a:hover,
.tf-plan-free a:focus-visible {
	color: var(--tf-accent-ink);
}

/* What every licence includes, below the plan cards. */
.tf-included-grid {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 28px;
	margin-top: 40px;
}

.tf-included .tf-plan-label {
	margin-top: 0;
}

@media (min-width: 760px) {
	.tf-included-grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 36px;
	}
}

.tf-plan-summary {
	margin: 18px 0 0;
	color: var(--tf-text-2);
	font-size: 15px;
	line-height: 1.55;
}

.tf-plan-actions {
	margin: 24px 0 0;
}

/* One CTA per card, and it should read as the card's action. */
.tf-plan-actions .wp-block-button {
	width: 100%;
}

.tf-plan-actions .wp-block-button__link {
	width: 100%;
	justify-content: center;
	text-align: center;
}

.tf-plan-label {
	margin: 28px 0 12px;
	color: var(--tf-muted);
	font-family: "JetBrains Mono", ui-monospace, monospace;
	font-size: 10.5px;
	font-weight: 600;
}

.tf-plan-list,
.tf-plan-platforms {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: 9px;
}

.tf-plan-list li,
.tf-plan-platforms li {
	display: flex;
	align-items: flex-start;
	gap: 9px;
	color: var(--tf-text-2);
	font-size: 14.5px;
	line-height: 1.45;
}

/* The free card's feature list has no icons in the markup, so it draws its own. */
.tf-plan-list li::before {
	content: "";
	flex: none;
	width: 15px;
	height: 15px;
	margin-top: 2px;
	background: currentColor;
	color: var(--tf-success);
	-webkit-mask: var(--tf-check-mask) center / contain no-repeat;
	mask: var(--tf-check-mask) center / contain no-repeat;
}

.tf-plan-platforms .tf-check {
	flex: none;
	margin-top: 2px;
	color: var(--tf-success);
}

.tf-plan-note {
	max-width: 52ch;
	margin: 28px auto 0;
	color: var(--tf-muted);
	font-size: 13.5px;
	line-height: 1.55;
	text-align: center;
}

:root {
	--tf-check-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3 3 7-7'/%3E%3C/svg%3E");
}

@media (min-width: 760px) {
	.tf-plan-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		gap: 24px;
	}

	.tf-plan {
		/* Equal height so the two cards share a bottom edge. */
		height: 100%;
	}
}

/* Homepage hero heading --------------------------------------------------- */

/*
 * 47px, as asked for, but as the ceiling of a clamp rather than a fixed size.
 * A fixed 47px would still be 47px on a 390px phone, where this two-line
 * heading needs about 780px to fit at that size. The clamp holds 47px from
 * roughly 780px upwards and scales down below it.
 *
 * Scoped away from FaltaPay hero, which keeps its larger product-page size.
 */
.tf-hero:not(.tf-faltapay-hero) h1 {
	font-size: clamp(30px, 6vw, 47px);
	/*
	 * landing.css caps the heading at 15ch, which was measured against the old
	 * 64px size. At 47px that cap is narrower than the column it sits in and
	 * costs an extra line or two, most visibly on tablet where it leaves 200px
	 * of the column unused. The grid column is the real constraint.
	 */
	max-width: 100%;
}

/* Support forms ----------------------------------------------------------- */

.tf-form-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 32px;
	align-items: start;
}

.tf-form-intro h2 {
	margin: 0 0 14px;
}

.tf-form-intro p {
	margin: 0 0 12px;
	color: var(--tf-text-2);
	line-height: 1.65;
}

.tf-form {
	padding: 28px;
	border: 1px solid var(--tf-border);
	border-radius: 16px;
	background: var(--tf-surface);
	box-shadow: var(--tf-shadow-sm);
}

/*
 * Two columns, so a form of short answers does not read as a long scroll. Every
 * direct child spans the full width by default and only .tf-field opts into a
 * half column, which keeps the textarea, the submit row and Contact Form 7's
 * own response output full width without naming each of them.
 */
@media (min-width: 620px) {
	.tf-form .wpcf7-form {
		display: grid;
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: 18px;
	}

	.tf-form .wpcf7-form > * {
		grid-column: 1 / -1;
	}

	.tf-form .wpcf7-form > .tf-field {
		grid-column: span 1;
	}

	.tf-form .wpcf7-form > .tf-field-wide {
		grid-column: 1 / -1;
	}
}

.tf-field {
	margin: 0 0 18px;
}

.tf-field label {
	display: block;
	margin-bottom: 7px;
	color: var(--tf-text);
	font-size: 14px;
	font-weight: 600;
}

.tf-field-hint {
	display: block;
	margin-top: 6px;
	color: var(--tf-muted);
	font-size: 12.5px;
	line-height: 1.45;
}

/*
 * Contact Form 7 wraps every control in a span of its own, so the width has to
 * be set on both the wrapper and the control to fill the column.
 */
.tf-form .wpcf7-form-control-wrap {
	display: block;
}

.tf-form :is(input[type="text"], input[type="email"], input[type="url"], input[type="tel"], select, textarea) {
	width: 100%;
	padding: 11px 13px;
	border: 1px solid var(--tf-border-strong);
	border-radius: 9px;
	background: var(--tf-bg);
	color: var(--tf-text);
	font: inherit;
	font-size: 15px;
	line-height: 1.4;
	transition: border-color 120ms ease-out, box-shadow 120ms ease-out;
}

.tf-form textarea {
	min-height: 130px;
	resize: vertical;
}

.tf-form :is(input, select, textarea):focus-visible {
	border-color: var(--tf-accent-ink);
	box-shadow: 0 0 0 3px color-mix(in oklch, var(--tf-accent) 22%, transparent);
	outline: none;
}

.tf-form .wpcf7-radio {
	display: flex;
	flex-wrap: wrap;
	gap: 16px;
}

.tf-form .wpcf7-list-item {
	margin: 0;
}

.tf-form .wpcf7-list-item label {
	display: flex;
	align-items: center;
	gap: 7px;
	margin: 0;
	font-weight: 500;
}

.tf-field-actions {
	margin: 24px 0 0;
}

.tf-form input[type="submit"] {
	width: 100%;
	min-height: 46px;
	padding: 12px 22px;
	border: 1px solid var(--tf-text);
	border-radius: 8px;
	background: var(--tf-text);
	color: var(--tf-bg);
	font: inherit;
	font-size: 15px;
	font-weight: 600;
	cursor: pointer;
	transition: transform 120ms ease-out, background 120ms ease-out;
}

.tf-form input[type="submit"]:hover {
	transform: translateY(-1px);
	background: oklch(12% 0.01 80);
}

/* Validation and response messages, restyled from the plugin defaults. */
.tf-form .wpcf7-not-valid-tip {
	margin-top: 6px;
	color: var(--tf-danger, #b3261e);
	font-size: 13px;
}

.tf-form :is(input, select, textarea).wpcf7-not-valid {
	border-color: var(--tf-danger, #b3261e);
}

.tf-form .wpcf7-response-output {
	margin: 20px 0 0;
	padding: 12px 14px;
	border: 1px solid var(--tf-border-strong);
	border-radius: 9px;
	font-size: 14px;
	line-height: 1.5;
}

.tf-form form.sent .wpcf7-response-output {
	border-color: var(--tf-success);
	background: color-mix(in oklch, var(--tf-success) 8%, transparent);
}

.tf-form form.invalid .wpcf7-response-output,
.tf-form form.failed .wpcf7-response-output {
	border-color: var(--tf-danger, #b3261e);
	background: color-mix(in oklch, #b3261e 7%, transparent);
}

.tf-form-missing {
	margin: 0;
	color: var(--tf-danger, #b3261e);
	font-size: 14px;
}

@media (min-width: 880px) {
	.tf-form-layout {
		grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr);
		gap: 56px;
	}

	.tf-field-actions {
		margin-top: 26px;
	}

	.tf-form input[type="submit"] {
		width: auto;
	}
}

/* Six-step process -------------------------------------------------------- */

/*
 * landing.css lays the process out as a single four-across row with a connector
 * between neighbours. Six steps wrap, so this variant drops to three columns
 * and removes the connectors, which would otherwise point off the end of a row.
 */
.tf-process-grid-six {
	grid-template-columns: minmax(0, 1fr);
}

.tf-process-grid-six .tf-process-step {
	min-height: 0;
}

.tf-process-grid-six .tf-process-step::before {
	margin-bottom: 18px;
}

.tf-process-grid-six .tf-process-step::after {
	display: none;
}

@media (min-width: 600px) {
	.tf-process-grid-six {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (min-width: 900px) {
	.tf-process-grid-six {
		grid-template-columns: repeat(3, minmax(0, 1fr));
	}
}
