/* Equal-height service cards (homepage Insurance grid, Insurance overview,
   Mortgage overview) — client asked for equal card heights per row, titles
   at a fixed height so body copy starts level, and "Learn more" pinned to
   the bottom of every card.

   ElementsKit's own built-in "Equal Height" widget toggle was tried first
   and rejected: it applies height:100% down a chain of plain (non-flex)
   wrapper divs, and on this site's Elementor "container" (flexbox) layout
   that chain breaks — cards overlapped and a whole row collapsed when
   tested. Using flex-grow instead of percentage heights avoids that; each
   level below is only responsible for filling its own already-flex parent,
   so nothing depends on an ancestor's resolved pixel height. */

.services-items {
	display: flex;
	flex-direction: column;
	/* This is a flex ITEM of its own wrapper (an Elementor container in
	   column direction), where the wrapper is already stretched to match
	   the tallest card in its row. Cross-axis "stretch" only affects width
	   in a column flex container — filling the wrapper's full height needs
	   flex-grow here too, otherwise this element just sizes to its own
	   content and only the row's naturally-tallest card ends up matching
	   the wrapper (confirmed by measuring: every mismatch was exactly the
	   gap between this element's un-grown content height and its already-
	   correctly-stretched wrapper). */
	flex: 1 1 auto;
}

.services-items .elementor-widget-container,
.services-items .ekit-wid-con {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
	width: 100%;
}

.services-items .elementskit-infobox {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
}

.services-items .box-body {
	display: flex;
	flex-direction: column;
	flex: 1 1 auto;
}

/* Fallback reservation, used only by any .services-items grid that hasn't
   been given its own services-grid-* class below (e.g. content outside the
   four grids this was built for). Sized to the worst case ever measured
   anywhere on the site at the CURRENT title size (2 lines) so it never
   under-reserves for something unclassed — deliberately generous as a
   safety net, not tuned per-grid. Every grid this task actually covers now
   has its own more accurate rule further down, which wins over this one on
   selector specificity regardless of source order.

   Re-derived 2026-08-21 for the title's move from 36px to 18px (see the
   per-grid block below for the full re-measurement methodology and
   results) — was 5em/3.75em, sized for a 36px title wrapping up to 4
   lines. At 18px nothing anywhere on the site wraps past 2 lines, so the
   old tablet (1024px) step down from the desktop value no longer does
   anything real; dropped rather than kept as a no-op. */
.services-items .elementskit-info-box-title {
	min-height: 2.4em;
}

@media ( max-width: 767px ) {
	.services-items .elementskit-info-box-title {
		min-height: 0;
	}
}

/* Per-grid reservations. Each class is added via Elementor's own "CSS
   Classes" advanced control on that grid's row container — NOTE the
   container control uses the settings key `css_classes` (no leading
   underscore), unlike widgets which use `_css_classes`; confirmed in
   Elementor's own container.php vs. common-base.php. Using the wrong key
   silently no-ops (saves to the DB, never reaches the rendered HTML) —
   caught this the hard way on the first grid and had to fix it before
   trusting the value.

   RE-DERIVED 2026-08-21 — the values below (and this whole comment block)
   used to describe a 36px title wrapping up to 4 lines; the title dropped
   to 18px the same day (see the Elementor Kit "Secondary" global-typography
   fix and the elsewhere-in-project notes on it) and every number here was
   re-measured from scratch against the 18px size, not adjusted from the
   old ones. At 18px, line-height is a consistent 1.2x multiple of
   font-size (confirmed: 21.6px measured line-height / 18px font-size —
   this also comes directly from this same day's explicit custom
   line-height:1.2em override on the title, not a separate coincidence),
   so each value below is lines x 1.2em.

   Measured with Playwright, at 1440/1024/768px, per grid: with the title's
   OWN min-height and CSS transition temporarily neutralized first (both
   are necessary — leaving the old min-height in place papers over the
   real content height with a fixed floor, and this element has a plugin-
   supplied `transition: all 0.4s ease` that means a style change read back
   immediately, before the transition settles, reports a stale value; both
   traps were hit and fixed during this investigation, worth remembering
   for whoever re-measures this next), then reading each title's actual
   line count via Range.getClientRects() rather than inferring it from
   element height. Mobile (<=767px) always drops to 0 across every grid —
   the layout is a single full-width column there (bisection-confirmed
   breakpoint: 766px still 2-up, 767px 1-up), so no title comes close to
   needing reserved space; this is the one rule that must be present in
   EVERY services-grid-* block below, or that grid loses its mobile/small-
   screen behavior and keeps a desktop-sized gap on phones. */

/* Home Insurance + Insurance overview (12 cards each, different card order
   and Insurance overview has an extra "Mortgage Services" card Home
   doesn't). At 18px, worst case is 2 lines both at >=1025px desktop
   ("Mortgage Cover / Income Protection" / "Student / Partner Insurance" /
   "Parent / Visitor Insurance", tied) AND at <=767px..1024px tablet width
   ("Mortgage Cover / Income Protection" again) — 1024px itself never wraps
   past 1 line (the grid drops to fewer columns there, so each card is
   actually wider than at 768px despite the narrower viewport), but the
   shared tablet media query has to cover the full 768-1024 range as one
   bucket, sized to the worse (768px) end. Desktop and tablet both landing
   on the same 2-line worst case is why there's no separate 1024px override
   below any more — the base rule alone already covers both. Grouped
   because the VALUES are identical, not because the grids are — if either
   grid's worst case ever changes independently (e.g. new/edited card
   copy), split this back into two separate blocks rather than edit one arm
   of a shared rule and accidentally change both grids at once. */
.services-grid-home-insurance .services-items .elementskit-info-box-title,
.services-grid-insurance-overview .services-items .elementskit-info-box-title {
	min-height: 2.4em;
}

@media ( max-width: 767px ) {
	.services-grid-home-insurance .services-items .elementskit-info-box-title,
	.services-grid-insurance-overview .services-items .elementskit-info-box-title {
		min-height: 0;
	}
}

/* Home Mortgage + the standalone Mortgage Services overview page — BOTH
   are 8-card grids sharing the same titles (corrected 2026-08-21: this
   comment previously said the standalone page had 6 cards in an uneven
   4/2 split; confirmed live via the page's actual generated CSS that it's
   8, same as Home's mortgage grid — a pre-existing inaccuracy, unrelated
   to the title-size change, fixed while re-deriving these values anyway).
   At 18px, worst case is 2 lines at >=1025px desktop ("Investment Property
   Loans" / "Business & Commercial Finance", tied), dropping to 1 line
   across the whole 768-1024 tablet range (confirmed at both ends) — unlike
   the insurance pair above, desktop and tablet genuinely differ here, so
   the 1024px override stays. Split back into two blocks if these ever
   diverge. */
.services-grid-home-mortgage .services-items .elementskit-info-box-title,
.services-grid-mortgage-page .services-items .elementskit-info-box-title {
	min-height: 2.4em;
}

@media ( max-width: 1024px ) {
	.services-grid-home-mortgage .services-items .elementskit-info-box-title,
	.services-grid-mortgage-page .services-items .elementskit-info-box-title {
		min-height: 1.2em;
	}
}

@media ( max-width: 767px ) {
	.services-grid-home-mortgage .services-items .elementskit-info-box-title,
	.services-grid-mortgage-page .services-items .elementskit-info-box-title {
		min-height: 0;
	}
}

/* Title-to-description gap tightened 10px -> 6px (2026-08-21) — 10px was
   the Levis demo's own value (and this site's per-widget setting matched
   it already, generated per-card as e.g. `margin:0px 0px 10px 0px` on
   .elementskit-info-box-title), but that spacing was tuned for the demo's
   18px title in ITS OWN layout; client felt it read as too loose here and
   asked for it tightened. Overridden here (one shared rule, !important
   needed to beat each card's own higher-specificity generated CSS rule:
   `.elementor-element-XXXXX .elementskit-infobox .elementskit-info-box-title`,
   3 selector segments vs. this rule's 2) rather than editing all 40 card
   widgets' _elementor_data individually — same visual result, far lower
   risk, and trivially keeps all four grids consistent from one place. */
.services-items .elementskit-info-box-title {
	margin-bottom: 6px !important;
}

.services-items .box-body > p {
	flex: 1 1 auto;
}

.services-items .box-footer {
	margin-top: auto;
}

/* Icon disappears on hover for Font-Awesome-icon cards (2026-08-21) — the
   parent theme (levis/style.css:4220-4246) already runs a deliberate hover
   effect on these cards: `.elementskit-info-box-icon:before` is a white
   circle at scale(0), scaled to 1 on `.elementskit-infobox:hover`, growing
   to cover the icon's own coloured circle. It ships a compensating recolor
   rule for that white background — `.services-items .elementskit-infobox
   :hover .elementskit-info-box-icon svg path{fill:var(--e-global-color-
   primary)}` — but that selector only matches inline SVG icons (Elementor's
   SVG-library icon-picker inlines uploaded SVGs as real <svg><path> markup
   in the page, which is why the 8 custom-uploaded service-card icons
   already recolor correctly and were never part of this bug). Font Awesome
   icons render as `<i class="fas fa-x">` glyphs, which `svg path` cannot
   match by definition — nothing ever un-whites them, so on hover they sit
   white-on-white against the same white circle and vanish. Confirmed via
   direct hover screenshots before this fix (not just computed-style
   inspection, which the first pass here got wrong: reading the DOM too
   soon after mouse-move landed mid-transition — the trigger is a
   `::before{transform:scale()}` transition off the plugin's own
   `.elementskit-info-box-icon:before` rule, ~0.4s, so anything read before
   that settles reports stale, unaffected-looking values).
   Fix mirrors the existing SVG rule exactly, for the icon-font case it
   doesn't cover — same color, same trigger, same scoping precedent
   (`.services-items .elementskit-infobox:hover`). Scoped to `.services-
   items` specifically (not a bare `.elementskit-infobox:hover .elementskit-
   info-box-icon i` — ElementsKit's icon-box widget is used elsewhere on
   this site outside the service-card grids, e.g. the Services-page FAQ
   icon boxes and the About-page feature icons, which must NOT be touched
   by this rule and don't share this hover-hides-icon problem in the first
   place, since they don't share this exact `.elementskit-info-box-icon:
   before` white-circle-grow treatment scoped to `.services-items` either). */
.services-items .elementskit-infobox:hover .elementskit-info-box-icon i {
	color: var( --e-global-color-primary );
}
