/* -------------------------------------------------- */
/* Leistungen                                           */
/* -------------------------------------------------- */

.section--leistungen h2 {
	color: #fff;
}

.leistungen-grid {
	display: grid;
	grid-template-columns: repeat(12, 1fr);
	grid-auto-flow: row dense;
	gap: 2rem;
	margin-top: 2.5rem;
}

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

/* A white panel with the icon badge sitting over its top-left corner, a round
   bite taken out of the panel around it. Was dark glass; the panel is opaque
   now so the type has a surface of its own whether the section behind it is the
   gradient (home) or white (the Leistungen block with the background switch
   off).
 *
 * The bite is a mask on the surface: one radial gradient, transparent inside
 * the halo radius and opaque beyond, so the section behind shows through as an
 * even ring of air around the badge. A rectangular notch would have been two
 * abutting boxes and no mask, but it steps around the badge in straight lines
 * while the badge itself is a squircle — this follows its shape instead.
 *
 * Hence the split between the two boxes. A mask clips everything its element
 * paints outside the border box, box-shadow included, and filter:
 * drop-shadow() on the same element is applied before the mask and gets cut
 * just the same. So the shadow sits on the card box and the mask on ::before.
 * The card box reaches --surface-top higher than the surface it stands in for;
 * that never shows, because the shadow is offset downwards and pulled back in
 * by a negative spread, so it paints nothing along its own top edge. */
.leistung-card {
	/* Matches .icon-tile in 01-base.css — the badge is that tile, lifted into
	   the corner. Change one and the bite follows. */
	--badge-size: 56px;
	/* Width of the transparent ring between the badge and the white surface. */
	--badge-halo: 10px;
	/* How far down the badge the surface starts. The rest of the badge stands
	   above the card, which is what makes it read as sitting in the corner
	   rather than printed on it. */
	--surface-top: 18px;

	--radius-child: var(--radius-nested);

	/* The card's palette in one place: the surface is painted by ::before, the
	   type by the rules further down. One design everywhere now — white
	   surface, dark ink, brand-coloured badge — so these three stay at their
	   defaults; nothing overrides them per section any more. */
	--card-surface: #fff;
	--card-ink: var(--color-ink);
	--card-body: var(--color-body);

	position: relative;
	/* Contains ::before, which sits at z-index -1 so the card's own content
	   paints over it. Without it the surface would drop behind the section
	   background. */
	isolation: isolate;
	grid-column: span 4;
	display: flex;
	flex-direction: column;
	padding: calc(var(--badge-size) + 1.5rem) 2.5rem 2.5rem;
	border-radius: var(--radius);
	box-shadow: var(--shadow-card);
	text-align: left;
	color: inherit;
	text-decoration: none;
	transition: transform var(--transition), box-shadow var(--transition);
}

.leistung-card::before {
	--hole-r: calc(var(--badge-size) / 2 + var(--badge-halo));
	--hole-x: calc(var(--badge-size) / 2);
	/* The gradient is positioned inside the surface, which starts --surface-top
	   below the badge — so the centre sits that far above its own top edge. */
	--hole-y: calc(var(--badge-size) / 2 - var(--surface-top));

	content: "";
	position: absolute;
	z-index: -1;
	inset: var(--surface-top) 0 0 0;
	background: var(--card-surface);
	border-radius: var(--radius);
	/* The 1px short of the radius is the feather: a hard stop leaves the cut
	   edge aliased, since the mask is resolved without antialiasing. */
	-webkit-mask-image: radial-gradient(circle at var(--hole-x) var(--hole-y), transparent calc(var(--hole-r) - 1px), #000 var(--hole-r));
	mask-image: radial-gradient(circle at var(--hole-x) var(--hole-y), transparent calc(var(--hole-r) - 1px), #000 var(--hole-r));
}

.leistung-card:hover {
	transform: translateY(var(--hover-lift));
	box-shadow: var(--shadow-card-hover);
}

/* -------------------------------------------------- */
/* Badge                                                */
/* -------------------------------------------------- */

/* .icon-tile keeps its size and radius from 01-base.css; here it is lifted out
   of the text flow into the notch. Absolute against the card, not the body, so
   the wide variant — where the tile sits inside a flex child — anchors to the
   same corner.

   Pale brand wash rather than white: on a white section a white badge would
   dissolve into the card beside it, and on the gradient the translucent tint
   the tiles use elsewhere would let the band through and go muddy. This is
   opaque and reads on both. */
.leistung-card .icon-tile {
	position: absolute;
	top: 0;
	left: 0;
	width: var(--badge-size);
	height: var(--badge-size);
	margin-bottom: 0;
	/* The one tile that keeps the outer radius: it straddles the card corner
	   rather than sitting inside the padding, so there is no inner corner for
	   it to be concentric with — see 01-base.css. */
	border-radius: 30px;
	background: var(--color-gradient-end);
	color: #FFF;
	/* An icon size rather than a type size: matched to the 56px tile, so it
	   is not on the type scale. */
	font-size: 1.45rem;
	/* Two layers: a tight ambient ring that falls into the halo and a softer
	   drop below it. The ring is what makes the cut-out legible on a white
	   section — there the gap is white on white and the badge would otherwise
	   look printed straight onto the card. On the gradient band the gap already
	   reads on its own and this only adds depth. */
	box-shadow:
		0 3px 8px rgba(17, 17, 17, 0.16),
		0 10px 22px -10px rgba(17, 17, 17, 0.35);
}

/* Same gradient-clipped glyph as .blog-card__more in 21-blog-listing.css.
   Applies to the <i> a Font Awesome field renders; an SVG icon ignores it and
   keeps the flat pink from `color` above. */
.leistung-card .icon-tile i {
	/* background: linear-gradient(var(--gradient-angle), var(--color-gradient-start), var(--color-gradient-end));
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent; */
}

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

.leistung-card__body {
	display: flex;
	flex-direction: column;
	flex: 1;
}

.leistung-card h3 {
	color: var(--card-ink);
}

.leistung-card p {
	color: var(--card-body);
	margin-bottom: 0;
}

/* Pushed to the foot of the card so the link lines up across a row whatever
   the copy does. The cards have always been links; this makes that visible. */
/* Gradient text is a hover-only reveal, not the resting state — plain ink
   until the card is hovered. It can't be the same layer switching colour on
   :hover, though: background-clip:text is a discrete on/off property, not
   something a `transition: color` can ease between, so toggling it directly
   made the gradient snap back the instant the pointer left instead of
   fading out. Fixed by never toggling it at all — the gradient copy is a
   second, always-clipped layer stacked exactly on top via ::before (see
   below), faded in/out purely with opacity, which *is* smoothly
   interpolable in both directions. */
.leistung-card__more {
	position: relative;
	margin-top: auto;
	padding-top: 2rem;
	display: inline-flex;
	align-items: center;
	gap: 0.4em;
	font-family: var(--font-display);
	font-size: var(--text-xs);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--card-ink);
}

/* content: attr(data-label) mirrors the translated string from the
   data-label attribute (see render.php / template-home.php) rather than
   duplicating the visible text a second time in markup. Positioned to sit
   exactly over the real text: absolute insets are relative to the padding
   edge, which starts padding-top above the text, so top has to repeat that
   2rem to land in the same place rather than at the box's very top. */
.leistung-card__more::before {
	content: attr(data-label);
	position: absolute;
	top: 2rem;
	left: 0;
	white-space: nowrap;
	background: linear-gradient(var(--gradient-angle), var(--color-gradient-start), var(--color-gradient-end));
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	opacity: 0;
	transition: opacity var(--transition);
	pointer-events: none;
}

.leistung-card:hover .leistung-card__more::before {
	opacity: 1;
}

/* The arrow gets the same gradient-on-hover treatment as the label, but it
   can't share .leistung-card__more's own ::before (already the label
   overlay) or ::after (one pseudo-element can't carry two different font
   sizes — the arrow is sized up independently of the label text). So it's a
   real child span instead, each with its own ::before overlay slot. */
.leistung-card__arrow {
	position: relative;
	font-size: 1.35em;
	line-height: 1;
	color: var(--card-ink);
	transition: color var(--transition), transform var(--transition);
}

.leistung-card__arrow::before {
	content: "→";
	position: absolute;
	inset: 0;
	background: linear-gradient(var(--gradient-angle), var(--color-gradient-start), var(--color-gradient-end));
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	opacity: 0;
	transition: opacity var(--transition);
}

.leistung-card:hover .leistung-card__arrow {
	transform: translateX(4px);
}

.leistung-card:hover .leistung-card__arrow::before {
	opacity: 1;
}

/* Click feedback: a bigger flight than the hover nudge, distinct from it.
   Brief on a real link — :active only holds for as long as the mouse button
   is down before navigation — but still reads as the arrow launching off
   rather than just easing over. */
.leistung-card:active .leistung-card__arrow {
	transform: translateX(20px);
}

/* -------------------------------------------------- */
/* Outline on a white section                           */
/* -------------------------------------------------- */

/* On the gradient band the white card reads on its own. On a white section it
   has nothing to push against, so it gets the same hairline every other card
   on white uses (--border-hairline, 01-base.css). The border lives on
   ::before rather than the card itself, so it follows the surface's own
   shape — the same mask that cuts the badge notch cuts the border too,
   breaking it at the corner instead of drawing a line straight through the
   badge.

   Same exception as the type-colour one in 25-blocks.css: the Leistungen
   block with its background switch off — which includes the Angebote
   page's "Unsere Leistungen" now that it's the_content() there rather than
   its own hardcoded section (page-templates/template-angebote.php), so
   there's no separate always-white case to list here any more. */
.ld-block-section:not(:has(> .section__bg-photo)) .leistung-card::before {
	border: var(--border-hairline);
}

/* -------------------------------------------------- */
/* Wide variant (home page, with photo)                 */
/* -------------------------------------------------- */

.leistung-card--wide {
	grid-column: span 8;
	flex-direction: row;
	gap: 2.5rem;
	align-items: center;
}

.leistung-card--wide.is-reverse {
	flex-direction: row-reverse;
}

.leistung-card__image {
	width: 38%;
	flex-shrink: 0;
	aspect-ratio: 1;
	border-radius: var(--radius-child);
	overflow: hidden;
}

.leistung-card__image img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.leistung-card__merkmale {
	margin-top: 1.5rem;
	display: grid;
	gap: 0.5rem;
}

.leistung-card__merkmale li {
	display: flex;
	align-items: center;
	gap: 0.5rem;
	font-weight: 600;
	font-size: var(--text-sm);
	color: var(--card-ink);
}

.leistung-card__merkmale i,
.leistung-card__merkmale svg {
	flex-shrink: 0;
	width: 18px;
	height: 18px;
	color: var(--card-accent, var(--color-gradient-start));
}
