/*
 * Ported verbatim from the legacy theme's style.css/responsive.css (values,
 * not paraphrased) for the homepage block markup that reproduces the legacy
 * DOM structure/class names exactly. Owl Carousel/Swiper themselves are not
 * part of this rebuild - assets/js/home-carousel.js is a small dependency-
 * free replacement driving the same [data-evolution-carousel] markup
 * contract (N items per breakpoint, looping prev/next nav, autoplay), styled
 * below to match the legacy owl-nav look. Every visual (color/spacing/
 * typography) rule from the legacy carousel-arrow CSS was kept; only the
 * Owl/Swiper-library-specific positioning internals were replaced with the
 * flex/transform track this JS drives.
 */

/* Carousel track/slide mechanics, shared by every [data-evolution-carousel] instance */
[data-evolution-carousel] {
	position: relative;
	overflow: hidden;
	/* Confirmed live (not guessed): overflow:hidden alone stops the visible
	   scrollbar and programmatic/keyboard scrolling, but not touch/trackpad
	   drag-scroll gestures on the track underneath - a known cross-browser
	   inconsistency, particularly on Windows precision touchpads. The track
	   holds every slide side by side (most shifted off-screen via
	   transform:translateX() as part of this carousel's own JS-driven
	   navigation - see home-carousel.js), so its own scrollWidth is several
	   times the visible viewport (confirmed directly: up to ~4x on this
	   site's carousels) - exactly the content a touch/trackpad gesture could
	   still drag-scroll despite overflow:hidden, producing a real, working
	   horizontal scrollbar the user could see and drag. touch-action:pan-y
	   restricts touch gestures on this element to vertical panning only,
	   closing that gap - navigation here is already driven by the prev/next
	   buttons and JS, never by touch-drag, so nothing intended is lost. */
	touch-action: pan-y;
	overscroll-behavior-x: contain;
}
/* Confirmed live via a full ancestor-chain trace (getBoundingClientRect on
   every element from .evolution-carousel__track up to <html>): the track's
   own box already stays within its parent's width by default (a flex
   container's box size does not automatically grow to the sum of its
   unwrapped children's widths - only the VISUAL content overflows, which
   [data-evolution-carousel]'s own overflow:hidden above already clips
   correctly), and no ancestor in that chain exceeded the viewport in this
   trace. width/max-width:100% here is a defensive, explicit constraint
   closing any remaining ambiguity in how a given browser/zoom/DPI
   combination computes a flex container's own box size, rather than
   relying on that default sizing behaviour implicitly. */
[data-evolution-carousel] .evolution-carousel__track {
	display: flex;
	width: 100%;
	max-width: 100%;
	transition: transform 400ms ease;
}
[data-evolution-carousel] .evolution-carousel__slide {
	box-sizing: border-box;
	padding: 0 10px;
}
[data-evolution-carousel].evolution-carousel--single-view .owl-nav {
	display: none;
}

/* Nav arrows - visual values ported from the legacy .owl-nav [class*=owl-] rules (style.css ~6105-6192) */
[data-evolution-carousel] .owl-nav {
	position: absolute;
	top: 43%;
	left: 0;
	right: unset;
	width: 100%;
	z-index: 2;
	pointer-events: none;
}
[data-evolution-carousel] .owl-nav button {
	pointer-events: auto;
	position: absolute;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 45px;
	height: 45px;
	line-height: 45px;
	font-size: 26px;
	color: #fff;
	background: #6B5CF6;
	border: 2px solid #6B5CF6;
	border-radius: 100%;
	cursor: pointer;
	transition: all .5s ease 0s;
}
[data-evolution-carousel] .owl-nav .prev-btn {
	left: 20px;
}
[data-evolution-carousel] .owl-nav .next-btn {
	right: 20px;
	left: unset;
}
[data-evolution-carousel] .owl-nav button:hover {
	background: rgb(107 92 246 / 56%);
	border-color: rgb(107 92 246 / 56%);
}
/* Confirmed live (not guessed): the 20px above is legacy's BASE
   [class*=owl-] rule (style.css) - it is never the value that actually wins.
   Legacy always overrides it per-carousel-type:
     .courses-categories-slider/.home-sliders .owl-prev/.owl-next -> 70px
     .brand-slider (partners) .owl-nav button.owl-prev/.owl-next -> -50px
       (arrows sit OUTSIDE the white rounded strip, against the purple
       background) plus a different translucent-white button background
       (rgb(255 255 255 / 33%) instead of the shared purple), since purple
       arrows would blend into a purple background.
   The shared 20px rule above was left as the ONLY value in this rebuild,
   which is the pre-override legacy default, not what legacy actually
   renders for any of these three carousel types. */
.evolution-home-slider .owl-nav .prev-btn,
.evolution-home-courses .owl-nav .prev-btn {
	left: 70px;
}
.evolution-home-slider .owl-nav .next-btn,
.evolution-home-courses .owl-nav .next-btn {
	right: 70px;
}
.evolution-home-partners .owl-nav .prev-btn {
	left: -50px;
	background: rgb(255 255 255 / 33%);
}
.evolution-home-partners .owl-nav .next-btn {
	right: -50px;
	background: rgb(255 255 255 / 33%);
}
.evolution-home-partners .owl-nav button:hover {
	background: rgb(255 255 255 / 33%);
}
/* The shared [data-evolution-carousel] { overflow:hidden } rule above clips
   ANY descendant positioned outside its own 0-100% box - including this
   instance's own .owl-nav buttons, which are deliberately positioned at
   left/right:-50px (see above) to sit outside the white rounded strip
   against the purple background, exactly like legacy. Confirmed live: with
   the shared rule in place, those buttons were being clipped to invisible
   rather than just visually cropped (this was reported as "buttons not
   visible", not "buttons cut off" - i.e. fully clipped, not partially).
   class-home-blocks.php's partner-carousel markup now wraps just the track
   in an extra .evolution-carousel__viewport div (JS is unaffected - its
   querySelector('.evolution-carousel__track') finds it at any depth), so
   overflow can be cancelled on the outer element and reapplied one level
   in, freeing .owl-nav (still a child of the outer element, now
   overflow:visible) to render outside the strip uncropped. Scoped to this
   one instance only - the other four [data-evolution-carousel] instances
   (home-slider, home-courses, home-testimonials, home-blog-posts) keep the
   shared rule untouched, since their nav buttons sit at 20px/70px, safely
   inside bounds, and their markup was not changed. */
.evolution-home-partners [data-evolution-carousel] {
	overflow: visible;
}
.evolution-home-partners [data-evolution-carousel] .evolution-carousel__viewport {
	overflow: hidden;
	touch-action: pan-y;
	overscroll-behavior-x: contain;
}
.evolution-home-slider .owl-nav,
.evolution-home-partners .owl-nav {
	top: 33%;
}

/*
 * Grid/container utilities. The legacy theme relies on Bootstrap's grid
 * globally; this rebuild does not include Bootstrap, so - following the
 * existing convention already established in legacy-page-blocks.css and
 * course-catalogue.css (each block scopes its own .container/.row/.col-*
 * rather than relying on a global framework) - every homepage section that
 * uses a .container/.row/.col-* wrapper gets one here, computed as standard
 * 12-column percentages (5/12=41.6667%, 7/12=58.3333%, 12/12=100%), not
 * invented values.
 *
 * CORRECTED (confirmed live against legacy's actual Bootstrap 5.0.2
 * bootstrap.min.css, not assumed): .container's real gutter is
 * `--bs-gutter-x: .75rem` (12px each side), not 15px, and Bootstrap's real
 * .container max-width is RESPONSIVE per breakpoint - 540/720/960/1140/
 * 1320px at 576/768/992/1200/1400px - not a flat 1140px at every viewport.
 * The missing >=1400px:1320px step is what made every homepage section's
 * content column (and, downstream, the Popular Courses cards inside it)
 * render visibly narrower than legacy at wide desktop viewports - confirmed
 * via a direct user screenshot comparison at ~1900px width, where legacy's
 * real container is 1320px and this rebuild's was capped at 1140px.
 * .container-fluid (testimonials) is intentionally its own rule below with
 * NO max-width at all, matching Bootstrap's real .container-fluid exactly
 * (width:100% at every breakpoint) - it was wrongly folded into the same
 * capped-width rule as every actual .container before this fix.
 */
.evolution-home-slider .container,
.evolution-home-courses .container,
.evolution-home-why-with-us .container,
.evolution-home-blog-posts .container,
.evolution-home-partners .container,
.evolution-social-posts .container {
	box-sizing: border-box;
	margin-left: auto;
	margin-right: auto;
	max-width: 1140px;
	padding-left: 12px;
	padding-right: 12px;
	width: 100%;
}
@media (min-width: 1400px) {
	.evolution-home-slider .container,
	.evolution-home-courses .container,
	.evolution-home-why-with-us .container,
	.evolution-home-blog-posts .container,
	.evolution-home-partners .container,
	.evolution-social-posts .container {
		max-width: 1320px;
	}
}
.evolution-home-testimonials .container-fluid {
	box-sizing: border-box;
	margin-left: auto;
	margin-right: auto;
	padding-left: 12px;
	padding-right: 12px;
	width: 100%;
}
.evolution-home-why-with-us .row,
.evolution-home-testimonials .row,
.evolution-social-posts .row {
	display: flex;
	flex-wrap: wrap;
	margin: 0 -15px;
}
.evolution-home-why-with-us .row.align-items-center,
.evolution-home-testimonials .row.align-items-center {
	align-items: center;
}
.evolution-home-why-with-us [class*="col-xl-"],
.evolution-home-testimonials [class*="col-xl-"],
.evolution-home-testimonials [class*="col-lg-"],
.evolution-social-posts [class*="col-lg-"] {
	padding: 0 15px;
	box-sizing: border-box;
}
.evolution-home-why-with-us .col-xl-5,
.evolution-home-testimonials .col-xl-5,
.evolution-home-testimonials .col-lg-5 {
	flex: 0 0 41.6667%;
	max-width: 41.6667%;
}
.evolution-home-why-with-us .col-xl-7,
.evolution-home-testimonials .col-xl-7,
.evolution-home-testimonials .col-lg-7 {
	flex: 0 0 58.3333%;
	max-width: 58.3333%;
}
.evolution-home-why-with-us .col-xl-12 {
	flex: 0 0 100%;
	max-width: 100%;
}
.evolution-social-posts .col-lg-4 {
	flex: 0 0 33.3333%;
	max-width: 33.3333%;
}
@media (max-width: 1200px) {
	.evolution-home-why-with-us .col-xl-5,
	.evolution-home-why-with-us .col-xl-7,
	.evolution-home-testimonials .col-xl-5,
	.evolution-home-testimonials .col-xl-7,
	.evolution-home-testimonials .col-lg-5,
	.evolution-home-testimonials .col-lg-7 {
		flex: 0 0 100%;
		max-width: 100%;
	}
}
@media (max-width: 767px) {
	.evolution-social-posts .col-lg-4 {
		flex: 0 0 50%;
		max-width: 50%;
	}
}
@media (max-width: 575px) {
	.evolution-social-posts .col-lg-4 {
		flex: 0 0 100%;
		max-width: 100%;
	}
}

/* Shared utility (Bootstrap-convention class name copied from legacy markup,
   same as this project's earlier .container/.row/.col-* fix for the
   Enrolment Application Portal - this codebase doesn't load Bootstrap, so
   any Bootstrap-named class used in markup needs its own real rule here.
   .text-center appears across every homepage section's markup (courses
   heading, "View All Courses" links, testimonials/social/blog headings,
   carousel item captions), never scoped to one section, so it belongs
   alongside the other genuinely shared utilities below rather than gated
   behind a single .evolution-home-* ancestor. */
.text-center {
	text-align: center;
}

/* Shared button (legacy: style.css ~2955-3007) */
.btn-standard,
.home-six-btn {
	position: relative;
	background: #6B5CF6;
	color: #FFFFFF;
	border: none;
	padding: 15px 45px;
	border-radius: 20px;
	overflow: hidden;
	z-index: 1;
	display: inline-block;
	font-size: 18px;
}
/* Confirmed live via legacy source (style.css:219-224): legacy has a GLOBAL
   `a { text-decoration: none !important; }` reset applied to every anchor
   site-wide, which is why none of legacy's own per-component link rules
   below ever needed to set it themselves. This rebuild's theme deliberately
   does NOT carry that same global reset (its own `a { text-underline-offset:
   0.18em; }` in style.css implies underlined inline links are an intentional
   accessibility choice for genuine body-text links) - but that means every
   card-title/button/CTA-style anchor that used to inherit "no underline" for
   free from legacy's reset needs it set explicitly here instead, or it falls
   back to the browser default underline. Applied to every such anchor in
   this file (course card titles, the shared CTA button, "View All Courses",
   blog post titles) rather than reintroducing a global reset that would
   fight the theme's own deliberate default for prose links. */
.home-six-btn a {
	color: #FFFFFF;
	position: relative;
	z-index: 1;
	font-size: 18px;
	font-weight: 500;
	text-decoration: none;
}
.home-six-btn::before {
	content: '';
	position: absolute;
	top: 0;
	left: 0;
	width: 8px;
	height: 102%;
	background: #6B5CF6;
	transition: width 500ms;
	z-index: 0;
}
.home-six-btn:hover {
	background: #6B5CF6;
	color: #fff;
	opacity: 0.9;
}
.home-six-btn:hover a {
	color: #fff;
}
.home-six-btn:hover::before {
	width: 100%;
}
/* Scoped to the hero slider's own button instance only - .home-six-btn is
   shared with the blog-card "Read more" and course-card buttons elsewhere on
   the homepage, which should not gain these changes. */
.evolution-home-slider .slider-btn .home-six-btn a {
	font-size: 18px;
	font-weight: 500;
	letter-spacing: 1.5px;
}

/* Shared section heading (legacy: style.css ~2919-2953) */
.section-pretitle {
	color: #333333;
	font-size: 20px;
	font-weight: 600;
	line-height: 15px !important;
	margin-bottom: 20px;
}
.section-title {
	color: #333333;
	font-size: 50px;
	font-weight: 700;
	line-height: 60px;
}
@media (max-width: 1200px) {
	.section-pretitle {
		font-size: 20px;
	}
	.section-title {
		font-size: 40px;
	}
}
@media (max-width: 600px) {
	.section-title {
		font-size: 28px;
		line-height: 34px;
	}
}
@media (max-width: 576px) {
	.section-title-area-six .section-pretitle {
		font-size: 16px;
		line-height: 0 !important;
	}
	.section-title-area-six .section-title {
		font-size: 30px;
		line-height: 40px;
	}
}

/* === Section 1: Hero slider (legacy: .react-slider-part-six / .home-sliders) === */
.evolution-home-slider .home-sliders {
	position: relative;
}
.evolution-home-slider .single-slide {
	position: relative;
}
/* Confirmed live (not guessed) that legacy has NO min-height/max-height/
   object-fit on this image at desktop widths at all - searched every active
   legacy stylesheet, the only such rule (single-slide img{min-height:350px;
   object-fit:cover}, responsive.css) is nested inside
   @media (max-width:767px) (see below). Above 767px legacy relies solely on
   Owl Carousel's own .owl-item img{width:100%;display:block} plus the
   generic img{height:auto} reset - i.e. the image is never cropped at
   desktop/tablet widths, only scaled to track width at its own natural
   aspect ratio. This rule previously applied min-height:350px;
   max-height:640px (640px has no legacy source at all) unconditionally,
   cropping the hero at every breakpoint where legacy never does. */
.evolution-home-slider .slider-img img {
	width: 100%;
	display: block;
}
/* Legacy's Owl config for .home-sliders uses margin:0 (assets/js/main.js) -
   zero horizontal gutter, edge-to-edge slides. The shared
   [data-evolution-carousel] .evolution-carousel__slide{padding:0 10px} rule
   above was never overridden for the single-item hero the way it correctly
   is for the multi-item carousels (testimonials/partners, which DO have a
   legacy Owl margin), leaving an unwanted ~10px gutter legacy doesn't have. */
.evolution-home-slider .evolution-carousel__slide {
	padding: 0;
}
.evolution-home-slider .content-part {
	background: hsl(0deg 0% 0% / 50%);
	padding: 40px;
	border-radius: 28px;
	transform: scale(1);
}
.evolution-home-slider .slider-content {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 60px;
	max-width: 900px;
	margin: 0 auto;
	padding: 0 15px;
	transform: translateX(-8vw);
}
@keyframes evolution-hero-fade-in {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}
@keyframes evolution-hero-slide-down {
	from {
		transform: translateY(-3vh);
	}
	to {
		transform: translateY(0);
	}
}
.evolution-home-slider .slider-content .slider-title {
	font-size: 64px;
	margin-bottom: 15px;
	color: #fff;
	line-height: 74px;
	font-weight: 700;
	display: block;
	margin-top: 20px;
	animation: evolution-hero-fade-in 1s ease forwards, evolution-hero-slide-down 2s ease forwards;
}
.evolution-home-slider .slider-content .slider-pretitle {
	display: inline-block;
	padding: 3px 15px 8px;
	font-size: 26px;
	color: #fff;
	margin-bottom: 22px;
	font-weight: 400;
	line-height: 32px;
	background: #D62B7B;
	animation: evolution-hero-fade-in 2s ease forwards;
}
/* Confirmed live (not guessed) that this base rule is NOT what actually wins
   in legacy's real DOM. The real markup (blocks/home/slider.php) nests
   .slider-pretitle inside a .content-part wrapper, and legacy ships a SEPARATE,
   higher-specificity rule for exactly that combination -
   ".react-slider-part-six .slider-content .content-part .slider-pretitle"
   (4 classes, specificity 0,4,0) - which zeroes out both the background and
   the padding: "background:0 0; text-transform:uppercase; padding:0"
   (style.css). That beats the plain ".home-sliders .slider-content
   .slider-pretitle" rule above (3 classes, 0,3,0) regardless of source
   order, so legacy's real, rendered eyebrow has NO pink rectangle behind it -
   confirmed by a human production screenshot report, and now confirmed here
   by tracing the actual winning selector rather than the first one found. */
.evolution-home-slider .slider-content .content-part .slider-pretitle {
	background: transparent;
	padding: 0;
	text-transform: uppercase;
}
.evolution-home-slider .slider-content .slider-btn {
	margin-top: 32px;
	animation: evolution-hero-fade-in 2s ease forwards, evolution-hero-slide-down 3s ease forwards;
}
@media (max-width: 1200px) {
	.evolution-home-slider .slider-content .slider-title {
		font-size: 44px;
		line-height: 48px;
	}
}
@media (max-width: 991px) {
	.evolution-home-slider .slider-content .slider-title {
		font-size: 38px;
		line-height: 46px;
		margin: 0 0 10px;
	}
	.evolution-home-slider .slider-content .slider-btn {
		margin-top: 15px;
	}
	.evolution-home-slider .content-part {
		padding: 20px;
	}
	.evolution-home-slider .slider-content {
		top: 30px;
		bottom: 30px;
		align-items: center;
		display: flex;
		max-width: 580px;
	}
}
@media (max-width: 767px) {
	.evolution-home-slider .slider-content .slider-pretitle {
		font-size: 14px;
	}
	/* Only legacy source for min-height/object-fit on this image (see the
	   comment above the unconditional .slider-img img rule) - mobile-only,
	   matching responsive.css's .single-slide img rule exactly. */
	.evolution-home-slider .slider-img img {
		min-height: 350px;
		object-fit: cover;
	}
}
@media (max-width: 600px) {
	.evolution-home-slider .slider-content .slider-title {
		font-size: 30px;
		line-height: 36px;
	}
}

/* === Section 2: Popular Courses (legacy: .react_popular_topics) === */
/* Bug found via the user's own computed-style comparison (not guessed): the
   legacy markup - and this project's own PHP port of it, class-home-
   blocks.php - puts pt---60/pb---60 and evolution-home-courses as THREE
   classes on the SAME single div (<div class="react_popular_topics
   pt---60 pb---60 evolution-home-courses">), but these two rules used a
   descendant combinator (a space), which only matches .pt---60/.pb---60 as
   a DESCENDANT of a separate .evolution-home-courses ancestor element - it
   can never match a class living on that same element. Both rules were
   consequently dead code: the section's real padding-top/padding-bottom was
   always the browser default (0), not 60px, no matter the viewport - which
   is what the user's computed-style paste of the legacy element (showing
   padding-top: 60px; padding-bottom: 60px actually applied) was pointing at.
   Removing the space makes these compound selectors matching classes on the
   SAME element, as intended. The .mb---60 rule below is unaffected by this
   bug - that class lives on a genuinely separate descendant element
   (.academics-top-contents), so its own descendant-combinator rule already
   matched correctly. */
.evolution-home-courses.pt---60 {
	padding-top: 60px;
}
.evolution-home-courses.pb---60 {
	padding-bottom: 60px;
}
.evolution-home-courses .mb---60 {
	margin-bottom: 60px;
}
/* Confirmed via the live legacy site's own computed styles for h2.section-
   title (not guessed): margin: 0 0 25px is set explicitly there. This
   project's .section-title (base rule above, shared across sections) never
   set a margin at all, so it fell back to the browser's UA-default h2 margin
   - roughly 0.83em top AND bottom, i.e. ~41.5px on BOTH sides at this 50px
   font-size, versus legacy's asymmetric 0 top / 25px bottom. That extra,
   unwanted top margin (legacy has none) is what was reading as a spacing/
   alignment mismatch under the "Courses" pretitle above it. Also restoring
   legacy's own `text-align: center !important` directly on the heading
   (rather than relying solely on the inherited value from the
   .academics-top-contents.text-center ancestor) for the same reason legacy
   defends it defensively - matching the verified computed style exactly.
   Scoped to .evolution-home-courses rather than the shared base .section-
   title so only this section's heading is affected. */
.evolution-home-courses .section-title {
	margin: 0 0 25px;
	text-align: center !important;
}
/* Font-family gap found while auditing this section (not guessed - confirmed
   in legacy's own style.css ~160-217): legacy sets font-family: 'Montserrat',
   sans-serif GLOBALLY on body/html AND on h1-h6, so every component in
   legacy - including every rule above/below - inherits it for free and never
   needed to repeat it itself. This project's theme.json sets a DIFFERENT
   global default instead (styles.typography.fontFamily: system-sans, i.e.
   -apple-system/Segoe UI/Helvetica Neue/Arial), and NOTHING in this
   stylesheet (home-blocks.css has zero font-family declarations anywhere,
   confirmed by grepping the whole file) ever overrides that back to
   Montserrat for the homepage content sections - only the theme's own
   style.css does, and only for header/nav/footer. So every text element in
   Popular Courses (and, unaudited so far, every other section in this file)
   has been rendering in the wrong font family site-wide. Montserrat IS
   already loaded (functions.php enqueues it from Google Fonts) - it just
   was never applied here. Scoped to .evolution-home-courses per this
   request; the same gap likely exists in every other section in this file. */
.evolution-home-courses .section-pretitle,
.evolution-home-courses .section-title,
.evolution-home-courses .item__inner .react-content h3,
.evolution-home-courses .item__inner .home-six-btn,
.evolution-home-courses .view-all {
	font-family: 'Montserrat', sans-serif;
}
.evolution-home-courses .item__inner {
	position: relative;
	transition: all .5s ease 0s;
	margin-bottom: 30px;
	background: #F1F0FF;
	border-radius: 20px;
	overflow: hidden;
}
.evolution-home-courses .item__inner .icon img {
	width: 100%;
	height: 300px;
	object-fit: cover;
	border-radius: 20px;
}
.evolution-home-courses .item__inner .react-content {
	display: flex;
	flex-direction: column;
	min-height: 120px;
	padding: 25px 32px 30px;
}
.evolution-home-courses .item__inner .react-content h3 {
	font-size: 22px;
	color: #333333;
	line-height: 27.65px;
	margin: 0 0 20px;
	font-weight: 700;
	overflow: hidden;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}
.evolution-home-courses .item__inner .react-content h3 a {
	color: #333333;
	text-decoration: none;
}
.evolution-home-courses .item__inner .react-content h3 a:hover {
	color: #b5b2b2;
}
.evolution-home-courses .item__inner .home-six-btn {
	align-self: flex-start;
	margin-top: auto;
	padding: 14px 20px;
	border-radius: 20px;
}
.evolution-home-courses .view-all {
	color: #999;
	text-decoration: none;
}
.evolution-home-courses .view-all:hover {
	color: #D62B7B;
}
@media (max-width: 1200px) {
	.evolution-home-courses .item__inner .react-content h3 {
		font-size: 18px;
	}
}
/* Two gaps found against legacy source, both missing here entirely (not
   guessed - confirmed in the legacy theme's own stylesheets):
   1. responsive.css ~402-407: the shared .section-title selector list
      (.react__title__section h2, .about__area h2, .react__title__section-all
      h2, .section-title) steps down to 30px specifically at this breakpoint,
      between the 1200px:40px step above and the existing 600px:28px step
      below - this project had the outer two steps but not this middle one.
      Scoped to .evolution-home-courses rather than the bare global
      .section-title so only this section's heading is affected.
   2. custom-spacing.css ~3260-3272: .pt---60/.pb---60 (among other pt/pb
      utilities) drop from 60px to 40px at this same breakpoint - this
      project's .pt---60/.pb---60 rules above had no responsive step at all,
      so the section stayed at the full 60px top/bottom padding all the way
      down to mobile instead of legacy's tighter tablet/mobile spacing. */
@media (max-width: 991px) {
	.evolution-home-courses .section-title {
		font-size: 30px;
	}
	.evolution-home-courses.pt---60 {
		padding-top: 40px;
	}
	.evolution-home-courses.pb---60 {
		padding-bottom: 40px;
	}
}
@media (max-width: 767px) {
	.evolution-home-courses .item__inner .react-content {
		min-height: 150px;
		padding: 15px 20px;
	}
}

/* === Section 3: Why study with us (legacy: .about-section.home-about-section) === */
.evolution-home-why-with-us {
	background: linear-gradient(90deg, #FFFFFF 16%, #F3F3F3 15%);
}
.evolution-home-why-with-us .pt---60 {
	padding-top: 60px;
}
.evolution-home-why-with-us .pb---80 {
	padding-bottom: 80px;
}
.evolution-home-why-with-us .mb----30 {
	margin-bottom: 30px;
}
.evolution-home-why-with-us .about__image img {
	width: 100%;
	max-height: 500px;
	object-fit: cover;
}
.evolution-home-why-with-us .about-contents {
	max-width: 470px;
	padding: 20px 40px;
	background: url( "../images/combined-shape.svg" ) no-repeat right top;
}
.evolution-home-why-with-us .about-btn {
	margin-top: 25px;
}
@media (max-width: 1200px) {
	.evolution-home-why-with-us .about-contents {
		max-width: 100%;
	}
}
@media (max-width: 767px) {
	.evolution-home-why-with-us .about-contents {
		padding: 15px 20px;
	}
}

/* === Section 4: Social posts — reuses .evolution-course-catalogue-results (course-catalogue.css) for
   .single-studies/.inner-course/.case-img/.case-content/.case-title, since the legacy theme uses the
   exact same card markup/classes for both, plus its own .row/.col-lg-4 grid above. === */
.evolution-social-posts {
	padding-top: 80px;
	padding-bottom: 80px;
}
.evolution-social-posts .pt---80 {
	padding-top: 80px;
}
.evolution-social-posts .pb---80 {
	padding-bottom: 80px;
}
.evolution-social-posts .pb---20 {
	padding-bottom: 20px;
}
/* The Instagram handle link and the "Load More" button both sit in a
   shared .text-center utility wrapper, but the user asked for these two
   specifically to be left-aligned (matching the cards/content column's own
   left edge) rather than centered - scoped here rather than touching the
   global .text-center utility other sections still rely on. */
.evolution-social-posts .pb---20.text-center,
.evolution-social-posts > .container > div.text-center {
	text-align: left;
}
/* legacy: custom.css .social-post-page a svg { height: 36px; width: 36px; } - without this the
   raw embedded icon SVG (no width/height attributes of its own) renders at browser-default
   intrinsic size, which can be very large. */
.evolution-social-posts a svg {
	height: 36px;
	width: 36px;
}

/* No legacy rule targets this profile link's own display/colour explicitly -
   it relies on legacy's global `a { color: #2D2D73; text-decoration: none
   !important; }` reset (style.css:219-224), the same reset this rebuild
   deliberately doesn't carry globally (see the .home-six-btn a comment
   above) - so it needs the same colour/no-underline set explicitly here,
   plus a small inline-flex gap so the icon and "@handle" text (both real,
   ported from legacy's own `@<?php echo $social_id[3] ?>` markup - see
   class-home-blocks.php) sit side by side cleanly instead of relying on
   default inline whitespace flow. */
.evolution-social-posts .pb---20 a {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	color: #2D2D73;
	text-decoration: none;
}

/* Confirmed live (not guessed) that this reused-class assumption was wrong for
   this one property: course-catalogue.css's .case-img img rule (height:220px,
   no object-position) is only enqueued as a style dependency of the
   evolution/course-catalogue block, which never appears on the homepage - so
   this section's card images were receiving zero height/object-fit CSS at
   all, just the generic img{max-width:100%;height:auto} reset, producing
   inconsistent card heights instead of 3 equal cards. Legacy's own value for
   THIS specific class combination (.react-course-filter.social-post-page,
   style.css) is height:300px with object-position:top - not
   course-catalogue.css's 220px - so it's restored here directly, scoped to
   this section, rather than by trying to force the homepage to load
   course-catalogue.css just for one property. */
.evolution-social-posts .case-img img {
	width: 100%;
	height: 300px;
	object-fit: cover;
	object-position: top;
}

/* The SAME missing-course-catalogue.css-dependency gap as the .case-img fix
   above, just for the rest of the card's chrome this time (confirmed live,
   not guessed - course-catalogue.css is never enqueued on the homepage, so
   every one of these reused .single-studies/.inner-course/.case-content/
   .case-title rules was silently absent): legacy's real values (style.css
   ~5864-5919) are the card's own light-lavender background, box-shadow,
   rounded corners, and the title's spacing/colour/hover state - restored
   here directly, scoped to this section, matching the same "case-img"
   precedent above rather than force-loading a whole second stylesheet. */
.evolution-social-posts .single-studies {
	margin-bottom: 25px;
}
.evolution-social-posts .inner-course {
	display: flex;
	flex-direction: column;
	height: 100%;
	overflow: hidden;
	background: #f1f0fe;
	border-radius: 20px;
	box-shadow: 0 1px 2px rgba(15, 18, 22, 0.1);
	text-decoration: none;
}
.evolution-social-posts .case-content {
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	height: 100%;
	padding: 30px 20px 20px;
}
.evolution-social-posts .case-title {
	margin: 6px 0 30px;
	font-size: 20px;
	font-weight: 600;
	color: #1E1E1E;
}
.evolution-social-posts .inner-course:hover .case-title {
	color: #2D2D73;
}

/* === Section 5: Testimonials (legacy: .student_satisfaction-section) === */
.evolution-home-testimonials {
	background: linear-gradient(90deg, rgb(255, 255, 255) 16%, rgb(243, 243, 243) 15%);
	padding-top: 60px;
	padding-bottom: 60px;
}
.evolution-home-testimonials .pb---30 {
	padding-bottom: 30px;
}
/* legacy Owl config: margin: 25 (12.5px each side) */
.evolution-home-testimonials .feedreact-slider .evolution-carousel__slide {
	padding: 0 12px;
}

/* Testimonial-specific owl-nav override: legacy scopes this at
   .student_satisfaction-section .owl-carousel .owl-nav (style.css
   ~13107-13154) - a real, complete override (50px circles, box-shadow,
   solid-purple hover) separate from the shared [class*=owl-] rule used by
   the courses/hero/partners carousels. It sits in normal document flow below
   the slide track (display:block, margin-top:40px, text-align:right) rather
   than absolutely centred over it like those three - the arrows-over-text
   bug from centring this section the same way as the others is why it stays
   on static/flex positioning here; only the sizing/shadow/hover values below
   were missing/wrong, not that positioning call. */
.evolution-home-testimonials .owl-nav {
	position: static;
	display: flex;
	justify-content: flex-end;
	gap: 10px;
	width: auto;
	margin-top: 40px;
}
.evolution-home-testimonials .owl-nav button {
	position: static;
	width: 50px;
	height: 50px;
	line-height: 48px;
	box-shadow: -6px 20px 30px rgba(15, 18, 22, .06);
}
.evolution-home-testimonials .owl-nav button:hover {
	background: #6B5CF6;
	border-color: #6B5CF6;
	opacity: 0.8;
}
.evolution-home-testimonials .event__card {
	background: #494949;
	border-radius: 20px;
	transition: 0.5s;
	margin-bottom: 30px;
}
.evolution-home-testimonials .event__card:hover {
	background: #262626;
}
.evolution-home-testimonials .event__card .event__card--content {
	padding: 48px 25px 0 30px;
	position: relative;
}
.evolution-home-testimonials .event__card .event__card--content .parag {
	color: #FFFFFF;
	line-height: 30px;
	margin: 6px 0 0;
	font-size: 18px;
	height: 310px;
	overflow: hidden;
	overflow-y: scroll;
	padding-right: 10px;
}
/* Legacy deliberately scrolls long quote text within a fixed-height card
   rather than truncating it (confirmed in the legacy stylesheet) - this
   custom thin-scrollbar styling was missing here, so real testimonial text
   (longer than the placeholder content used when this block was first
   built) fell back to the browser's unstyled default scrollbar instead of
   legacy's intended thin, rounded one. */
.evolution-home-testimonials .event__card .event__card--content .parag::-webkit-scrollbar-track {
	-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
	border-radius: 10px;
	background-color: #F5F5F5;
}
.evolution-home-testimonials .event__card .event__card--content .parag::-webkit-scrollbar {
	width: 8px;
	background-color: #F5F5F5;
	border-radius: 10px;
}
.evolution-home-testimonials .event__card .event__card--content .parag::-webkit-scrollbar-thumb {
	border-radius: 10px;
	-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
	background-color: #555;
}
.evolution-home-testimonials .poly {
	width: 62px !important;
	height: 44px;
	object-fit: contain;
	margin-bottom: 30px;
}
.evolution-home-testimonials .author-sec {
	display: flex;
	align-items: center;
	padding: 30px 48px;
}
.evolution-home-testimonials .author-sec .icon {
	margin-right: 15px;
}
.evolution-home-testimonials .author-sec .icon img {
	width: 66px;
	height: 66px;
	object-fit: cover;
	object-position: top;
	border-radius: 50%;
}
.evolution-home-testimonials .author-sec .text {
	flex: 1;
}
.evolution-home-testimonials .author-sec .text h4 {
	margin: 0 0 5px;
	font-weight: 700;
	font-size: 18px;
	line-height: 23px;
	color: #FFFFFF;
}
.evolution-home-testimonials .author-sec .text p {
	margin: 0;
	font-size: 14px;
	line-height: 17px;
	color: #FFFFFF;
	opacity: 0.5;
}
/* Pink dotted-square decoration: legacy source (style.css ~1905-1910) applies
   this as a background-image on the ".contents" wrapper, NOT the heading
   itself - .student_satisfaction-section .contents shares the exact same
   rule as .home-about-section .about-contents (see
   .evolution-home-why-with-us .about-contents above), both using the same
   176x176 dot-grid SVG asset (fill #f8d1df, plugins/evolution-core/assets/
   images/combined-shape.svg) at native size, no-repeat, anchored to the
   wrapper's top-right corner. */
.evolution-home-testimonials .contents {
	max-width: 470px;
	padding: 20px 40px;
	background: url( "../images/combined-shape.svg" ) no-repeat right top;
}
.evolution-home-testimonials .react__title__section-all h2 {
	font-size: 44px;
	font-weight: 700;
	color: #1E1E1E;
	margin: 0 0 10px;
	line-height: 54px;
}
.evolution-home-testimonials .react__title__section-all h6 {
	font-size: 20px;
	color: #333333;
	font-weight: 600;
	margin: 0 0 12px;
}
@media (max-width: 1200px) {
	.evolution-home-testimonials .contents {
		max-width: 100%;
	}
	.evolution-home-testimonials .react__title__section-all h2 {
		font-size: 40px;
	}
	.evolution-home-testimonials .event__card .event__card--content {
		padding: 20px 20px 0;
	}
}
@media (max-width: 991px) {
	.evolution-home-testimonials .react__title__section-all h2 {
		font-size: 30px;
	}
	.evolution-home-testimonials .event__card .event__card--content {
		padding: 20px 20px 0;
	}
}
@media (max-width: 767px) {
	.evolution-home-testimonials .contents {
		padding: 15px 20px;
	}
	.evolution-home-testimonials .react__title__section-all.pb---30 {
		padding-bottom: 0;
	}
}
@media (max-width: 600px) {
	.evolution-home-testimonials .react__title__section-all h2 {
		font-size: 28px;
		line-height: 34px;
	}
}
@media (max-width: 575px) {
	.evolution-home-testimonials .owl-nav button {
		display: none;
	}
}

/* === Section 6: Blog posts (legacy: .blog-section-seven.home-blog-section) === */
.evolution-home-blog-posts {
	background: linear-gradient(90deg, rgb(188 188 188 / 50%) 73%, rgb(255, 255, 255) 16%);
}
/* This carousel never got its own prev/next position override (unlike
   .evolution-home-slider/-courses at 70px or .evolution-home-partners at
   -50px, see the shared [data-evolution-carousel] .owl-nav rule above), so
   it was stuck on the generic 20px-from-edge fallback - overlapping the
   slide's own text/image at that width instead of framing it. Removed
   rather than repositioned per explicit request; the single-item slide
   already autoplays (data-autoplay="2500"), so it doesn't depend on manual
   nav to be usable. */
.evolution-home-blog-posts .owl-nav {
	display: none;
}
/* Compound selector (no space) - confirmed live that pt---100/pb---100/
   evolution-home-blog-posts all sit on the SAME element, not nested. The
   previous descendant-combinator version (".evolution-home-blog-posts
   .pt---100") required pt---100 to be a CHILD of evolution-home-blog-posts
   and so never matched anything at all - the visible 100px was coming from
   some other, unscoped .pt---100/.pb---100 utility rule this never
   overrode. */
.evolution-home-blog-posts.pt---100 {
	padding-top: 90px;
}
.evolution-home-blog-posts.pb---100 {
	padding-bottom: 90px;
}
/* height:100% is required, not just align-items:center - the carousel
   track's slides stretch to match the tallest neighbouring slide's content
   (the track's own default flex align-items:stretch), but .blog-card itself
   had no height set, so it only ever sized to its own content and sat flush
   at the top of that taller slide box - its align-items:center had no
   extra vertical room within its OWN box to redistribute, since the unused
   space existed outside the card (between the card's bottom edge and the
   slide's), not inside it. This is what let a shorter card's picture end up
   uncentred (small gap above, large gap below) whenever a neighbouring
   slide's text pushed the shared slide height taller than this card's own
   content. */
.evolution-home-blog-posts .blog-card {
	display: flex;
	gap: 40px;
	align-items: center;
	height: 100%;
	margin-bottom: 30px;
}
.evolution-home-blog-posts .blog-card button.home-six-btn {
	margin-top: 20px;
}
.evolution-home-blog-posts .blog-picture {
	margin-bottom: 20px;
	overflow: hidden;
	min-width: 45%;
}
.evolution-home-blog-posts .blog-picture img {
	width: 100%;
	border-radius: 20px;
}
.evolution-home-blog-posts .blog-date {
	color: #2D2D73;
	font-size: 16px;
	margin-bottom: 7px;
}
.evolution-home-blog-posts .blog-title {
	margin-bottom: 15px;
	max-width: 550px;
	overflow: hidden;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
}
/* a.blog-title (compound, no nested-descendant "a") - confirmed live: the
   markup is <a class="blog-title section-title">, the anchor itself
   carries blog-title directly, there is no separate nested <a> inside a
   .blog-title wrapper. The previous ".blog-title a" selector required
   exactly that nesting and so never matched anything. Only text-decoration
   is carried over here, by explicit user request - the color/font-size/
   font-weight/line-height this dead rule also carried were never actually
   part of the site's real, seen appearance either, and introducing them
   now changed the look beyond just the underline. */
.evolution-home-blog-posts a.blog-title {
	text-decoration: none;
}
@media (max-width: 600px) {
	.evolution-home-blog-posts .blog-card {
		gap: 0px;
		flex-direction: column-reverse;
	}
}

/* === Section 7: Partners/brand logos (legacy: .brand-secton) === */
/* Confirmed live (not guessed) that legacy's section background is the flat
   purple PLUS a dotted-map graphic (style.css: "#6B5CF6 url(assets/images/
   resources/dotted_map_white_bg.png) center no-repeat"); only the flat color
   survived the original port and the map asset was never carried into the
   destination theme/plugin images at all. Restored here from the legacy
   source file, copied byte-for-byte to assets/images/. */
.evolution-home-partners {
	background: #6B5CF6 url( "../images/dotted_map_white_bg.png" ) center no-repeat;
	background-size: 100%;
}
/* Compound selectors (no space) - confirmed live that pt---50/pb---50/
   evolution-home-partners all sit on the SAME element (brand-secton
   pt---50 pb---50 evolution-home-partners), not nested, so the previous
   descendant-combinator versions never matched anything - the same bug
   already found and fixed for the blog section's pt---100/pb---100. */
.evolution-home-partners.pt---50 {
	padding-top: 90px;
}
.evolution-home-partners.pb---50 {
	padding-bottom: 90px;
}
/* legacy: .brand-secton .owl-stage-outer { background:#FFFFFF; border-radius:85px; padding:20px; } -
   Owl Carousel auto-wraps the track in .owl-stage-outer; .brand-slider IS the carousel root here, so
   the equivalent white rounded strip is applied directly to it. */
.evolution-home-partners .brand-slider {
	background: #FFFFFF;
	border-radius: 85px;
	padding: 20px;
}
/* legacy Owl config: margin: 40 (20px each side) */
.evolution-home-partners .evolution-carousel__slide {
	padding: 0 20px;
}
.evolution-home-partners img {
	height: 95px;
	object-fit: contain;
	padding: 10px 0;
}
