/* Custom Content Timeline - base styles
   All colors/sizes are driven by CSS custom properties set inline per-instance,
   so every timeline on a page can have its own palette. */

.ct-timeline {
	--ct-line-color: #7c3aed;
	--ct-line-color-muted: #e5e0fa;
	--ct-line-size: 4px;
	--ct-line-left-offset: 0px;
	--ct-card-gap: 28px;

	--ct-icon-bg: #e5e0fa;
	--ct-icon-bg-active: #7c3aed;
	--ct-icon-color: #7c3aed;
	--ct-icon-color-active: #ffffff;
	--ct-bullet-size: 80px;
	--ct-icon-font-size: 32px;
	--ct-bullet-offset-top: 0px;
	--ct-bullet-offset-left: 0px;
	--ct-bullet-border-width: 0px;
	--ct-bullet-border-color: #e5e0fa;
	--ct-bullet-border-color-active: #7c3aed;

	--ct-caret-size: 8px;
	--ct-caret-position: 20px;
	--ct-caret-color: #ffffff;

	--ct-card-bg: #ffffff;
	--ct-title-color: #1a1a2e;
	--ct-text-color: #555555;
	--ct-date-color: #333333;
	--ct-title-align: left;
	--ct-excerpt-align: left;

	--ct-h-tag-bg: #eef2f7;
	--ct-h-tag-text: #475569;
	--ct-h-tag-dot: #2563eb;
	--ct-h-meta-label: #0e9aa7;
	--ct-h-meta-value: #64748b;

	box-sizing: border-box;
}
.ct-timeline *,
.ct-timeline *::before,
.ct-timeline *::after {
	box-sizing: inherit;
}

.ct-timeline__icon .dashicons {
	font-size: var(--ct-icon-font-size);
	width: var(--ct-icon-font-size);
	height: var(--ct-icon-font-size);
}
.ct-timeline__icon img {
	width: var(--ct-icon-font-size);
	height: var(--ct-icon-font-size);
	border-radius: 50%;
	object-fit: cover;
}

.ct-timeline__card {
	background: var(--ct-card-bg);
	padding: 22px 24px;
	position: relative;
}
.ct-timeline--shadow .ct-timeline__card {
	box-shadow: 0 4px 24px rgba(20, 10, 50, 0.10), 0 1px 3px rgba(20, 10, 50, 0.08);
}

/* ---------------- Second in-card icon (optional, per item) ----------------
   Separate from the connector/badge icon: sits inside the card itself,
   above the title/content. Deliberately plain, no circle, no background
   color, no border, nothing forcing it into a shape, just the icon or
   image itself at a controllable size, since it's meant to be dropped
   in exactly as uploaded/chosen rather than styled like the bullet. */
.ct-timeline__card-icon-row {
	display: flex;
	justify-content: flex-start;
	width: 100%;
	margin-bottom: 14px;
}
.ct-timeline__icon-secondary {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	flex-shrink: 0;
}
.ct-timeline__icon-secondary .dashicons {
	font-size: 56px;
	width: 56px;
	height: 56px;
}
.ct-timeline__icon-secondary img {
	display: block;
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	object-fit: contain;
	border-radius: 0;
}

.ct-timeline__date {
	display: inline-block;
	font-size: 13px;
	font-weight: 600;
	color: var(--ct-date-color);
	margin-bottom: 6px;
}

.ct-timeline__title {
	margin: 0 0 8px;
	font-size: 18px;
	line-height: 1.3;
	color: var(--ct-title-color);
	text-align: var(--ct-title-align);
}

.ct-timeline__excerpt {
	margin: 0 0 10px;
	font-size: 14px;
	line-height: 1.6;
	color: var(--ct-text-color);
	text-align: var(--ct-excerpt-align);
}
.ct-timeline__excerpt p:first-child { margin-top: 0; }
.ct-timeline__excerpt p:last-child { margin-bottom: 0; }

/* ---------------- Bullet / icon circle ---------------- */
.ct-timeline__icon {
	width: var(--ct-bullet-size);
	height: var(--ct-bullet-size);
	border-radius: 50%;
	background: var(--ct-icon-bg);
	color: var(--ct-icon-color);
	display: flex;
	align-items: center;
	justify-content: center;
	flex-shrink: 0;
	overflow: hidden;
	border: var(--ct-bullet-border-width) solid var(--ct-bullet-border-color);
	transition: background 0.45s cubic-bezier(0.25, 0.46, 0.45, 0.94), color 0.45s cubic-bezier(0.25, 0.46, 0.45, 0.94), border-color 0.45s cubic-bezier(0.25, 0.46, 0.45, 0.94);
	z-index: 2;
	position: relative;
	top: var(--ct-bullet-offset-top);
	left: var(--ct-bullet-offset-left);
}

.ct-timeline__item--active .ct-timeline__icon,
.ct-timeline__connector--passed .ct-timeline__icon {
	background: var(--ct-icon-bg-active);
	color: var(--ct-icon-color-active);
	border-color: var(--ct-bullet-border-color-active);
}

/* ---------------- Caret (speech-bubble pointer toward the line) ---------------- */
.ct-timeline__card--caret-right::before,
.ct-timeline__card--caret-left::before {
	content: '';
	position: absolute;
	top: var(--ct-caret-position);
	width: 0;
	height: 0;
	pointer-events: none;
}
.ct-timeline__card--caret-right::before {
	right: calc(-1 * var(--ct-caret-size));
	border-width: var(--ct-caret-size) 0 var(--ct-caret-size) var(--ct-caret-size);
	border-style: solid;
	border-color: transparent transparent transparent var(--ct-caret-color);
}
.ct-timeline__card--caret-left::before {
	left: calc(-1 * var(--ct-caret-size));
	border-width: var(--ct-caret-size) var(--ct-caret-size) var(--ct-caret-size) 0;
	border-style: solid;
	border-color: transparent var(--ct-caret-color) transparent transparent;
}

/* ---------------- Button (optional, per item) ---------------- */
.ct-timeline__button {
	display: inline-block;
	margin-top: 12px;
	padding: 8px 18px;
	border-radius: 6px;
	background: var(--ct-icon-bg-active);
	color: #ffffff;
	font-size: 13px;
	font-weight: 600;
	text-decoration: none;
	transition: opacity 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94), background-color 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94), color 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}

/* ============ Scroll-fade entrance for cards ============ */
.ct-timeline__card {
	transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1), transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
}
/* Hidden pre-entrance state is applied by JS, not by default here. This way,
   if the entrance script fails to run for any reason (a conflicting plugin
   script erroring out earlier on the page, aggressive caching, a blocker),
   the card content stays visible instead of vanishing. */
.ct-timeline--scroll-fx .ct-timeline__card.ct-timeline__card--pre-entrance {
	opacity: 0;
	transform: translateY(14px);
	will-change: opacity, transform;
}
.ct-timeline--scroll-fx .ct-timeline__item--in-view .ct-timeline__card {
	opacity: 1;
	transform: translateY(0);
}
/* Horizontal cards use opacity-only entrance, no translateY, since a
   slide-up motion doesn't read as naturally on cards sitting to the
   side of a horizontal line the way it does stacked in a vertical
   list, an upward slide plus the offset already applied to position
   the card above/below the line reads as a slightly odd double-motion. */
.ct-timeline--scroll-fx.ct-timeline--horizontal .ct-timeline__card.ct-timeline__card--pre-entrance {
	transform: none; /* remove the inherited translateY from the vertical rule */
}
.ct-timeline--scroll-fx.ct-timeline--horizontal .ct-timeline__card.ct-timeline__card--pre-entrance-h {
	opacity: 0;
	will-change: opacity;
}
.ct-timeline--scroll-fx.ct-timeline--horizontal .ct-timeline__item--in-view .ct-timeline__card--pre-entrance-h {
	opacity: 1;
}

/* ============ VERTICAL (zigzag, center alignment) ============ */
.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__list {
	position: relative;
	max-width: 900px;
	margin: 0 auto;
	display: grid;
	grid-template-columns: 1fr var(--ct-bullet-size) 1fr;
	column-gap: var(--ct-card-gap);
	row-gap: 30px;
}

.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__line-base,
.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__line-fill {
	position: absolute;
	/* Matches the connector's own padding-top (4px) plus half the
	   bullet size exactly, this is where the first bullet's center
	   actually sits, a fixed, reliable value that doesn't depend on
	   JavaScript timing the way the bottom end (see script.js) has
	   to, since there's no preceding content above the first item to
	   create any uncertainty about it. */
	top: calc(4px + (var(--ct-bullet-size) / 2));
	left: calc(50% + var(--ct-line-left-offset));
	width: var(--ct-line-size);
	transform: translateX(-50%);
}
.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__line-base {
	bottom: 0;
	background: var(--ct-line-color-muted);
	z-index: 1;
}
.ct-timeline--vertical .ct-timeline__line-fill {
	height: 0;
	background: var(--ct-line-color);
	z-index: 1;
	transform-origin: center top;
	will-change: transform;
	pointer-events: none;
}
/* The line's exact length depends on the real, measured position of
   the last bullet (see initVerticalLine in script.js), not just a
   fixed guess, since the last row can be taller than its bullet
   (whenever its card has more content), which would otherwise let the
   line run past the bullet into that extra space. Both lines stay
   hidden until JS has measured and applied the correct length, rather
   than briefly showing a too-long line and then snapping shorter. */
.ct-timeline--vertical .ct-timeline__line-base,
.ct-timeline--vertical .ct-timeline__line-fill {
	opacity: 0;
	transition: opacity 0.2s ease;
}
.ct-timeline--vertical.ct-timeline--line-ready .ct-timeline__line-base,
.ct-timeline--vertical.ct-timeline--line-ready .ct-timeline__line-fill {
	opacity: 1;
}
.ct-timeline--vertical.ct-timeline--no-scroll-fx .ct-timeline__line-base {
	background: var(--ct-line-color);
}
.ct-timeline--vertical.ct-timeline--no-scroll-fx .ct-timeline__line-fill {
	display: none;
}

.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__item {
	display: contents;
}

.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__connector {
	grid-column: 2;
	display: flex;
	justify-content: center;
	align-items: flex-start;
	/* Without this, the connector has no align-self of its own, so it
	   defaults to Grid's stretch behavior (the list's own grid never
	   sets align-items), meaning the connector's own box stretches to
	   match the row's height (set by whichever is taller, the bullet
	   or the card), not just its content. That mismatch between the
	   connector's layout box and where the bullet actually sits is
	   exactly what let the line's JS measurement land below the
	   bullet's real position for a tall last card, this is what
	   actually fixes it at the source rather than working around it. */
	align-self: start;
	position: relative;
	z-index: 2;
	padding-top: 4px;
}

.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__item--left .ct-timeline__card {
	grid-column: 1;
}
.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__item--right .ct-timeline__card {
	grid-column: 3;
}
.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__item--left .ct-timeline__date--aside {
	grid-column: 3;
	text-align: left;
}
.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__item--right .ct-timeline__date--aside {
	grid-column: 1;
	text-align: right;
}
.ct-timeline--vertical .ct-timeline__date--aside {
	align-self: flex-start;
}

@media (max-width: 767px) {
	.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__list {
		grid-template-columns: 44px 1fr;
		column-gap: 16px;
	}
	.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__line-base,
	.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__line-fill {
		left: 22px;
		transform: none;
	}
	.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__connector {
		grid-column: 1;
	}
	.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__item--left .ct-timeline__card,
	.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__item--right .ct-timeline__card {
		grid-column: 2;
	}
	.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__date--aside {
		display: none;
	}
	.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__card .ct-timeline__date {
		display: inline-block !important;
	}
	.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__card--caret-left::before,
	.ct-timeline--vertical.ct-timeline--align-center .ct-timeline__card--caret-right::before {
		display: none; /* caret only makes sense pointing at a line that sits beside the card */
	}
}

/* ============ VERTICAL (left / right alignment, single column) ============ */
.ct-timeline--vertical.ct-timeline--align-left .ct-timeline__list,
.ct-timeline--vertical.ct-timeline--align-right .ct-timeline__list {
	position: relative;
	max-width: 700px;
	margin: 0 auto;
}
.ct-timeline--vertical.ct-timeline--align-left .ct-timeline__line-base,
.ct-timeline--vertical.ct-timeline--align-right .ct-timeline__line-base,
.ct-timeline--vertical.ct-timeline--align-left .ct-timeline__line-fill,
.ct-timeline--vertical.ct-timeline--align-right .ct-timeline__line-fill {
	position: absolute;
	/* Matches where the first bullet's own center actually sits (no
	   extra padding-top in this alignment mode, unlike align-center),
	   a fixed, reliable value independent of JavaScript timing. */
	top: calc(var(--ct-bullet-size) / 2);
	left: calc( ( var(--ct-bullet-size) / 2 ) + var(--ct-line-left-offset) );
	width: var(--ct-line-size);
	transform: translateX(-50%);
}
.ct-timeline--vertical.ct-timeline--align-left .ct-timeline__line-base,
.ct-timeline--vertical.ct-timeline--align-right .ct-timeline__line-base {
	bottom: 0;
	background: var(--ct-line-color-muted);
}
.ct-timeline--vertical.ct-timeline--align-left .ct-timeline__item,
.ct-timeline--vertical.ct-timeline--align-right .ct-timeline__item {
	display: flex;
	align-items: flex-start;
	position: relative;
	margin-bottom: 28px;
}
.ct-timeline--vertical.ct-timeline--align-left .ct-timeline__connector,
.ct-timeline--vertical.ct-timeline--align-right .ct-timeline__connector {
	position: relative;
	z-index: 2;
}
.ct-timeline--vertical.ct-timeline--align-left .ct-timeline__card,
.ct-timeline--vertical.ct-timeline--align-right .ct-timeline__card {
	margin-left: var(--ct-card-gap);
	flex: 1;
}

@media (max-width: 767px) {
	.ct-timeline--vertical .ct-timeline__date--aside {
		display: none;
	}
}

/* ============ HORIZONTAL, three-row layout ============
   Structure (identical to Essential Addons pattern):
     .ct-timeline__scroll          outer wrapper
       .ct-timeline__track         vertical stack of the three rows
         .ct-timeline__row--above  grid row: above-line cards + placeholders
         .ct-timeline__row--middle grid row: all connectors + the line
         .ct-timeline__row--below  grid row: below-line cards + placeholders

   Each row is a CSS Grid with exactly as many equal-width columns as
   there are items (--ct-h-item-count), so the whole thing always fits
   exactly inside whatever Elementor container/column it's placed in,
   it never creates its own wider scrollable area. All three rows
   share the same column count/gap, keeping every column aligned
   across rows without any JS measurement.
   ====================================================================== */

.ct-timeline--horizontal .ct-timeline__scroll {
	position: relative;
	width: 100%;
}

/* Native sticky Horizontal scroll effect. JS supplies the exact natural
   content height plus the line travel and a short final release distance. */
.ct-timeline--horizontal.ct-timeline--h-scroll-stage {
	position: relative;
	width: 100%;
	min-width: 0;
	min-height: var(--ct-h-section-height);
	overflow: visible;
	isolation: isolate;
	scroll-snap-align: none !important;
	scroll-snap-stop: normal !important;
	overscroll-behavior-y: auto;
	touch-action: pan-y;
}
.ct-timeline--horizontal.ct-timeline--h-scroll-stage .ct-timeline__scroll {
	position: -webkit-sticky;
	position: sticky;
	top: var(--ct-h-sticky-top, 0px);
	min-height: var(--ct-h-sticky-height);
	display: flex;
	align-items: center;
	z-index: 1;
}
.ct-timeline--horizontal.ct-timeline--h-scroll-stage .ct-timeline__track {
	flex: 0 0 auto;
}

.ct-timeline--horizontal .ct-timeline__track {
	display: flex;
	flex-direction: column;    /* rows stack vertically: above, middle, below */
	width: 100%;
	position: relative;
	padding: 10px;
}
/* Card order for RTL is handled entirely in PHP (the items array itself
   is reversed there), not here. Whether direction:rtl reliably reverses
   CSS Grid column order the same way it does for flexbox is genuinely
   inconsistent across sources, layering it on top of an already-
   reversed array risked canceling back out to normal order in some
   browsers. One deterministic mechanism (array order) is safer than
   two mechanisms that might fight each other.
   direction: ltr; forces the actual text (numbers, punctuation, mixed
   content) to render normally, RTL here only meant "reverse the card
   order", not "this content is a right-to-left language". */
.ct-timeline--rtl .ct-timeline__track { direction: ltr; }

/* ── Each row is a grid of equal-width columns spanning the full width ── */
.ct-timeline--horizontal .ct-timeline__row {
	display: grid;
	grid-template-columns: repeat(var(--ct-h-item-count, 1), minmax(0, 1fr));
	gap: var(--ct-card-gap);
	width: 100%;
}

/* ── Column unit, min-width:0 lets grid cells shrink below content size
       instead of overflowing when there are many items ── */
.ct-timeline--horizontal .ct-timeline__h-col {
	min-width: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
}

/* ── Placeholder: empty column so the opposite row's card stays aligned ── */
.ct-timeline--horizontal .ct-timeline__h-placeholder {
	min-width: 0;
}

/* ── Above row: cards sit at the bottom of the column (touching the line) ── */
.ct-timeline--horizontal .ct-timeline__row--above .ct-timeline__h-col--card {
	justify-content: flex-end;   /* card sticks to the bottom, closest to the line */
}

/* ── Below row: cards sit at the top of the column (touching the line) ── */
.ct-timeline--horizontal .ct-timeline__row--below .ct-timeline__h-col--card {
	justify-content: flex-start; /* card sticks to the top, closest to the line */
}

/* ── Nudge (odd/even card offset from the line), driven by CSS variables
       rather than a fixed inline pixel value, so it can respond to the
       Tablet/Mobile breakpoints. Item position within each row matches
       item index order (:nth-child(odd) = 1st, 3rd... = index 0, 2...,
       exactly what "odd card" means in the Style settings). A per-item
       "Custom Vertical Offset" override still wins via its own inline
       style, which always beats a class-based rule regardless of order. ── */
.ct-timeline--horizontal .ct-timeline__row--above .ct-timeline__h-col--card:nth-child(odd) {
	padding-bottom: var(--ct-h-nudge-odd, 0px);
}
.ct-timeline--horizontal .ct-timeline__row--above .ct-timeline__h-col--card:nth-child(even) {
	padding-bottom: var(--ct-h-nudge-even, 0px);
}
.ct-timeline--horizontal .ct-timeline__row--below .ct-timeline__h-col--card:nth-child(odd) {
	padding-top: var(--ct-h-nudge-odd, 0px);
}
.ct-timeline--horizontal .ct-timeline__row--below .ct-timeline__h-col--card:nth-child(even) {
	padding-top: var(--ct-h-nudge-even, 0px);
}

/* ── Middle row: connectors are centred on the line ── */
.ct-timeline--horizontal .ct-timeline__row--middle {
	position: relative;
	align-items: center;         /* connectors sit on the line */
	z-index: 1;
}

/* ── Card fills its column, optionally capped by Card Width so it doesn't
       stretch unreasonably wide when there are only one or two items ── */
.ct-timeline--horizontal .ct-timeline__card {
	width: 100%;
	max-width: var(--ct-h-item-width, none);
	margin: 0 auto;
}
/* No carets on horizontal cards */
.ct-timeline--horizontal .ct-timeline__card--caret-left::before,
.ct-timeline--horizontal .ct-timeline__card--caret-right::before {
	display: none;
}

/* ── Min-height on above/below rows so there is always room ── */
.ct-timeline--horizontal .ct-timeline__row--above,
.ct-timeline--horizontal .ct-timeline__row--below {
	min-height: var(--ct-h-row-min-height, 200px);
}

/* ── The line lives inside the middle row, stretches full width by
       default; JS re-measures it to the first/last icon centres ── */
.ct-timeline--horizontal .ct-timeline__line-base--h,
.ct-timeline--horizontal .ct-timeline__line-fill--h {
	position: absolute;
	left: 0;
	top: 50%;
	transform: translateY(-50%);
	height: var(--ct-line-size);
	z-index: 0;
	opacity: 0;
}
.ct-timeline--horizontal.ct-timeline--h-line-ready .ct-timeline__line-base--h,
.ct-timeline--horizontal.ct-timeline--h-line-ready .ct-timeline__line-fill--h {
	opacity: 1;
}
.ct-timeline--horizontal .ct-timeline__line-base--h {
	right: 0;
	background: var(--ct-line-color-muted);
}
.ct-timeline--horizontal .ct-timeline__line-fill--h {
	width: 0;
	background: var(--ct-line-color);
	transition: width 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.2s ease;
	pointer-events: none;
}
.ct-timeline--horizontal.ct-timeline--no-scroll-fx .ct-timeline__line-base--h {
	background: var(--ct-line-color);
}
.ct-timeline--horizontal.ct-timeline--no-scroll-fx .ct-timeline__line-fill--h {
	display: none;
}

/* ── Connector sits above the line z-index ── */
.ct-timeline--horizontal .ct-timeline__connector {
	position: relative;
	z-index: 2;
	flex-shrink: 0;
}

/* ── Scroll-fx entrance: horizontal cards fade in only (no translateY
       since cards are now in their own row and have no transform conflict) ── */
.ct-timeline--scroll-fx.ct-timeline--horizontal .ct-timeline__card.ct-timeline__card--pre-entrance {
	transform: none;
}
.ct-timeline--scroll-fx.ct-timeline--horizontal .ct-timeline__card.ct-timeline__card--pre-entrance-h {
	opacity: 0;
	will-change: opacity;
}
.ct-timeline--scroll-fx.ct-timeline--horizontal .ct-timeline__item--in-view .ct-timeline__card--pre-entrance-h,
.ct-timeline--scroll-fx.ct-timeline--horizontal .ct-timeline__h-col--card.ct-timeline__item--in-view .ct-timeline__card--pre-entrance-h {
	opacity: 1;
}

/* ============ HORIZONTAL "Modern" card style ============
   The icon sits directly on the line (identical to Classic's connector,
   see render_h_connector), Modern's own distinguishing features are the
   card's layout, tag pill, and meta line below. Only active when both
   Layout = Horizontal and Horizontal Card Style = Modern are selected;
   otherwise these rules simply don't match anything. */
.ct-timeline--h-modern .ct-timeline__card {
	text-align: left;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
}

.ct-timeline--h-modern .ct-timeline__h-tag {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 12px;
	font-weight: 600;
	line-height: 1;
	padding: 6px 12px;
	border-radius: 999px;
	margin-bottom: 10px;
	background: var(--ct-h-tag-bg);
	color: var(--ct-h-tag-text);
}
.ct-timeline--h-modern .ct-timeline__h-tag::before {
	content: '';
	width: 6px;
	height: 6px;
	border-radius: 50%;
	background: var(--ct-h-tag-dot);
	flex-shrink: 0;
}

.ct-timeline--h-modern .ct-timeline__h-meta {
	font-size: 13px;
	margin-top: 10px;
	color: var(--ct-h-meta-value);
}
.ct-timeline--h-modern .ct-timeline__h-meta strong {
	color: var(--ct-h-meta-label);
	font-weight: 700;
}

/* ============ SCROLL SERVICES: native sticky reveal ==================
   One semantic section supplies the scroll range while its stage stays
	visible through every item, then releases naturally. Wheel, trackpad,
	touch, momentum, and page keys remain fully browser-native. */
.ct-timeline--scroll-services {
	--ct-services-sticky-top: 16px;
	/* Fill the usable viewport. The last real stop is protected from residual
	   momentum, followed by one compact native release interval. */
	--ct-services-stage-height: calc(100vh - var(--ct-services-sticky-top));
	--ct-services-stage-height: calc(100svh - var(--ct-services-sticky-top));
	--ct-services-step-height: 48vh;
	--ct-services-orbit-size: 820px;
	--ct-services-orbit-width: 1px;
	--ct-services-orbit-x: -70%;
	--ct-services-orbit-y: 50%;
	--ct-services-orbit-angle-offset: 0;
	--ct-services-arc-spread: 48;
	--ct-services-node-size: 68px;
	--ct-services-node-border-width: 1px;
	--ct-services-active-node-scale: 1.1;
	--ct-services-progress: 0;
	--ct-services-progress-color: #181715;
	--ct-services-progress-width: 2px;
	--ct-services-progress-opacity: .88;
	--ct-services-line-duration: 360ms;
	--ct-services-line-easing: cubic-bezier(.22,1,.36,1);
	--ct-services-media-width: 36%;
	--ct-services-column-gap: 56px;
	--ct-services-panel-columns: minmax(0, 1fr) minmax(180px, var(--ct-services-media-width));
	--ct-services-panel-rows: minmax(0, 1fr);
	--ct-services-panel-areas: "content media";
	--ct-services-duration: 620ms;
	--ct-services-reveal: 12px;
	--ct-services-image-x: 50%;
	--ct-services-image-y: 50%;
	--ct-services-background-fit: cover;
	--ct-services-background-x: 50%;
	--ct-services-background-y: 50%;
	--ct-services-panel-bg: #f4f2ee;
	--ct-services-panel-border: transparent;
	--ct-services-panel-border-width: 0px;
	--ct-services-orbit-color: #cbc8c1;
	--ct-services-node-bg: #f4f2ee;
	--ct-services-node-text: #181715;
	--ct-services-node-border: #bcb9b2;
	--ct-services-node-active-bg: #181715;
	--ct-services-node-active-text: #fff;
	--ct-services-node-active-border: #181715;
	--ct-services-phase-color: #6f6a62;
	--ct-services-title-color: #181715;
	--ct-services-body-color: #6f6a62;
	--ct-services-tag-bg: transparent;
	--ct-services-tag-text: #272521;
	--ct-services-tag-border: #d4d0c8;
	--ct-services-tag-border-width: 1px;
	--ct-services-image-shadow: 0%;
	position: relative;
	width: 100%;
	min-height: var(--ct-services-section-height, var(--ct-services-stage-height));
	min-width: 0;
	overflow: visible;
	isolation: isolate;
	scroll-margin-top: var(--ct-services-sticky-top);
	scroll-snap-align: none !important;
	scroll-snap-stop: normal !important;
	overscroll-behavior-y: auto;
	touch-action: pan-y;
}

/* Elementor overflow/fixed-height hosts can otherwise become the sticky
   containing block and clip the timeline before its scroll range finishes. */
.ct-services-sticky-host {
	overflow: visible !important;
}
.ct-services-sticky-host--sized {
	height: auto !important;
	max-height: none !important;
}
.ct-services-snap-host {
	scroll-snap-align: none !important;
	scroll-snap-stop: normal !important;
}

.ct-services__sticky-layer {
	position: -webkit-sticky;
	position: sticky;
	top: var(--ct-services-sticky-top);
	width: 100%;
	/* Saved pages may still contain the old 86/88vh value. Treat it as a
	   minimum and always cover the currently usable viewport, so upgrading an
	   existing widget cannot bring back the exposed strip at the bottom. */
	height: max(var(--ct-services-stage-height), calc(100vh - var(--ct-services-sticky-top)));
	height: max(var(--ct-services-stage-height), calc(100svh - var(--ct-services-sticky-top)));
	max-height: calc(100vh - var(--ct-services-sticky-top));
	max-height: calc(100svh - var(--ct-services-sticky-top));
	min-height: min(420px, calc(100svh - var(--ct-services-sticky-top)));
	overflow: visible;
	z-index: 1;
}

.ct-services__stage {
	position: relative;
	width: 100%;
	max-width: 100%;
	height: 100%;
	min-height: 100%;
	min-width: 0;
	overflow: hidden;
	background: transparent !important;
	border: var(--ct-services-panel-border-width) solid var(--ct-services-panel-border);
	border-radius: 18px;
	padding: 32px 40px;
	transform: translateZ(0);
	-webkit-transform: translateZ(0);
	contain: layout paint style;
	isolation: isolate;
	z-index: 1;
}

.ct-services__backgrounds {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	min-height: 100%;
	overflow: hidden;
	background: var(--ct-services-panel-bg);
	pointer-events: none;
	z-index: 0;
}

/* Elementor keeps the stage/content in its boxed column. Only this visual
   layer is aligned to the viewport and expanded over the parent container's
   top/bottom spacing by the lightweight bounds measurement in script.js. */
.ct-timeline--scroll-services.ct-timeline--elementor .ct-services__backgrounds {
	top: var(--ct-services-background-top, 0px);
	left: var(--ct-services-background-left, calc(50% - 50vw));
	width: var(--ct-services-background-width, 100vw);
	/* JS can extend this layer across Elementor's outer spacing, but it may
	   never be shorter than the sticky stage because of viewport rounding. */
	height: max(100%, var(--ct-services-background-height, 100%));
	min-height: 100%;
}

/* Keep Elementor content boxed while allowing the decorative desktop/tablet
   arc to use the same full-bleed left origin as the background layer. The arc
   is a sibling of the clipped stage, so it cannot be cut at the box edge. */
@media (min-width: 768px) {
	.elementor-widget .ct-timeline--scroll-services .ct-services__orbit,
	.ct-timeline--scroll-services.ct-timeline--elementor .ct-services__orbit {
		left: var(--ct-services-background-left, calc(50% - 50vw));
	}
}

.ct-services__background {
	position: absolute;
	inset: 0;
	opacity: 0;
	visibility: hidden;
	transform: scale(1.012);
	transition: opacity var(--ct-services-duration) cubic-bezier(.22,.65,.3,1),
		transform var(--ct-services-duration) cubic-bezier(.22,.65,.3,1),
		visibility 0s linear var(--ct-services-duration);
}

.ct-services__background.is-active {
	opacity: 1;
	visibility: visible;
	transform: scale(1);
	transition-delay: 0s;
}

.ct-services--near .ct-services__background.is-active {
	will-change: opacity, transform;
}

.ct-services__background::after {
	content: '';
	position: absolute;
	inset: 0;
	background-color: transparent;
	pointer-events: none;
}

.ct-services__background-picture,
.ct-services__background-image,
.ct-services__background-video {
	display: block;
	width: 100%;
	height: 100%;
}

.ct-services__background-image,
.ct-services__background-video {
	object-fit: var(--ct-services-background-fit);
	object-position: var(--ct-services-background-x) var(--ct-services-background-y);
}

.ct-services__orbit {
	position: absolute;
	left: 0;
	top: var(--ct-services-orbit-y);
	width: var(--ct-services-orbit-size);
	height: var(--ct-services-orbit-size);
	border: 0;
	border-radius: 50%;
	transform: translate(var(--ct-services-orbit-x), -50%);
	pointer-events: none;
	z-index: 3;
}

.ct-services__orbit-progress {
	position: absolute;
	inset: 0;
	display: block;
	width: 100%;
	height: 100%;
	overflow: visible;
	pointer-events: none;
	z-index: 1;
}

.ct-services__orbit-track {
	fill: none;
	stroke: var(--ct-services-orbit-color);
	stroke-width: var(--ct-services-orbit-width);
	shape-rendering: geometricPrecision;
	vector-effect: non-scaling-stroke;
}

.ct-services__orbit-progress-path {
	fill: none;
	stroke: var(--ct-services-progress-color);
	stroke-width: var(--ct-services-progress-width);
	stroke-linecap: round;
	stroke-linejoin: round;
	shape-rendering: geometricPrecision;
	opacity: 0;
	vector-effect: non-scaling-stroke;
	transition: stroke var(--ct-services-line-duration) var(--ct-services-line-easing),
		opacity var(--ct-services-line-duration) var(--ct-services-line-easing);
}

.ct-services--ready .ct-services__orbit-progress-path {
	opacity: var(--ct-services-progress-opacity);
}

.ct-services__node {
	-webkit-appearance: none;
	appearance: none;
	position: absolute;
	left: var(--ct-services-node-x, 100%);
	top: var(--ct-services-node-y, 50%);
	width: var(--ct-services-node-size);
	height: var(--ct-services-node-size);
	margin: 0;
	padding: 0;
	border: var(--ct-services-node-border-width) solid var(--ct-services-node-border);
	border-radius: 50%;
	background: var(--ct-services-node-bg);
	color: var(--ct-services-node-text);
	display: inline-flex;
	align-items: center;
	justify-content: center;
	font-family: inherit;
	font-size: clamp(15px, 1.35vw, 22px);
	font-weight: 500;
	line-height: 1;
	cursor: pointer;
	pointer-events: auto;
	z-index: 2;
	transform: translate(-50%, -50%);
	transition: color var(--ct-services-duration) cubic-bezier(.22,1,.36,1),
		background-color var(--ct-services-duration) cubic-bezier(.22,1,.36,1),
		border-color var(--ct-services-duration) cubic-bezier(.22,1,.36,1),
		box-shadow var(--ct-services-duration) cubic-bezier(.22,1,.36,1),
		transform var(--ct-services-duration) cubic-bezier(.22,1,.36,1);
	-webkit-tap-highlight-color: transparent;
}

.ct-services__node:focus-visible {
	transform: translate(-50%, -50%) scale(1.025);
}
.ct-services__node:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 4px;
}
.ct-services__node.is-active {
	background: var(--ct-services-node-active-bg);
	border-color: var(--ct-services-node-active-border);
	color: var(--ct-services-node-active-text);
	box-shadow: 0 10px 24px rgba(24, 23, 21, 0.11);
	transform: translate(-50%, -50%) scale(var(--ct-services-active-node-scale));
}

@media (hover: hover) and (pointer: fine) {
	.ct-services__node:hover {
		transform: translate(-50%, -50%) scale(1.025);
	}
	.ct-services__node.is-active:hover {
		transform: translate(-50%, -50%) scale(var(--ct-services-active-node-scale));
	}
}

.ct-services__panels {
	position: relative;
	height: 100%;
	min-width: 0;
	margin-left: clamp(190px, 22vw, 430px);
	z-index: 2;
}

.ct-services__panel {
	position: absolute;
	inset: 0;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--ct-services-column-gap);
	align-items: center;
	min-width: 0;
	min-height: 0;
	/* Never create a second vertical scroller inside the sticky stage.
	   Nested overflow + overscroll containment can trap wheel/touch input
	   at the card edge and make the page appear stuck on Safari and iOS. */
	overflow: hidden;
	overscroll-behavior: auto;
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transform: translate3d(0, var(--ct-services-reveal), 0);
	transition: opacity var(--ct-services-duration) cubic-bezier(.22,.65,.3,1),
		transform var(--ct-services-duration) cubic-bezier(.22,.65,.3,1),
		visibility 0s linear var(--ct-services-duration);
}
.ct-services__panel.has-media {
	grid-template-columns: var(--ct-services-panel-columns);
	grid-template-rows: var(--ct-services-panel-rows);
	grid-template-areas: var(--ct-services-panel-areas);
}
.ct-services__panel.is-before {
	transform: translate3d(0, calc(var(--ct-services-reveal) * -1), 0);
}
.ct-services__panel.is-active {
	z-index: 2;
	opacity: 1;
	visibility: visible;
	pointer-events: auto;
	transform: translate3d(0, 0, 0);
	transition-delay: 0s;
}

.ct-services--near .ct-services__panel.is-active {
	will-change: opacity, transform;
}

.ct-services__content {
	grid-area: content;
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 18px;
	width: 100%;
	max-width: 500px;
	min-width: 0;
}
.ct-services__phase {
	margin: 0;
	color: var(--ct-services-phase-color);
	font-size: 12px;
	font-weight: 700;
	line-height: 1.25;
	letter-spacing: .12em;
	text-transform: uppercase;
}
.ct-services__title {
	margin: 0;
	color: var(--ct-services-title-color);
	font-family: Georgia, 'Times New Roman', serif;
	font-size: clamp(36px, 4.5vw, 72px);
	font-weight: 400;
	line-height: .98;
	letter-spacing: -.035em;
	text-wrap: balance;
}
.ct-services__description {
	margin: 0;
	color: var(--ct-services-body-color);
	font-size: clamp(14px, 1.1vw, 18px);
	line-height: 1.5;
}
.ct-services__description > :first-child { margin-top: 0; }
.ct-services__description > :last-child { margin-bottom: 0; }
.ct-services__tags {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
}
.ct-services__tag {
	display: inline-flex;
	align-items: center;
	min-height: 32px;
	padding: 8px 16px;
	border: var(--ct-services-tag-border-width) solid var(--ct-services-tag-border);
	border-radius: 999px;
	background: var(--ct-services-tag-bg);
	color: var(--ct-services-tag-text);
	font-size: 13px;
	line-height: 1;
}
.ct-services__button {
	align-self: flex-start;
	margin-top: 0;
	padding: 10px 20px;
	border: 0 solid #181715;
	border-radius: 999px;
	background: #181715;
	color: #fff;
}
.ct-services__button:hover,
.ct-services__button:focus-visible {
	background: #34312c;
	border-color: #34312c;
	color: #fff;
}

.ct-services__media {
	grid-area: media;
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 440px;
	max-height: 100%;
	min-width: 0;
	overflow: hidden;
}
.ct-services__media.is-empty { display: none; }
.ct-services__image {
	position: relative;
	left: calc(var(--ct-services-image-x) - 50%);
	top: calc(var(--ct-services-image-y) - 50%);
	display: block;
	width: 100%;
	height: 100%;
	max-width: 100%;
	object-fit: contain;
	object-position: 50% 50%;
	box-shadow: 0 18px 50px rgb(0 0 0 / var(--ct-services-image-shadow));
	transform: translateZ(0);
	-webkit-transform: translateZ(0);
}

/* A hidden CSS-to-pixel measuring element lets the lightweight script honor
   responsive px/vh values without parsing or guessing CSS units. */
.ct-services__step-meter {
	position: absolute;
	left: 0;
	top: 0;
	width: 1px;
	height: var(--ct-services-step-height);
	visibility: hidden;
	pointer-events: none;
}

@media (max-width: 1024px) {
	.ct-timeline--scroll-services {
		--ct-services-sticky-top: 12px !important;
		--ct-services-stage-height: calc(100vh - var(--ct-services-sticky-top)) !important;
		--ct-services-stage-height: calc(100svh - var(--ct-services-sticky-top)) !important;
		--ct-services-step-height: 44vh !important;
		--ct-services-orbit-size: 600px !important;
		--ct-services-orbit-x: -68% !important;
		--ct-services-orbit-y: 50% !important;
		--ct-services-arc-spread: 46 !important;
		--ct-services-node-size: 56px !important;
		--ct-services-media-width: 38% !important;
		--ct-services-column-gap: 32px !important;
		--ct-services-duration: 580ms !important;
		--ct-services-line-duration: 340ms !important;
		--ct-services-reveal: 10px !important;
	}
	.ct-services__stage {
		padding: 28px;
	}
	.ct-services__panels {
		margin-left: clamp(145px, 21vw, 230px);
	}
	.ct-services__panel.has-media {
		grid-template-columns: var(--ct-services-panel-columns);
	}
	.ct-services__title {
		font-size: clamp(32px, 5vw, 54px);
	}
}

@media (max-width: 767px) {
	.ct-timeline--scroll-services {
		--ct-services-sticky-top: 8px !important;
		--ct-services-stage-height: calc(100vh - var(--ct-services-sticky-top)) !important;
		--ct-services-stage-height: calc(100svh - var(--ct-services-sticky-top)) !important;
		--ct-services-step-height: 40vh !important;
		--ct-services-orbit-size: min(56vw, 280px) !important;
		--ct-services-orbit-x: 0% !important;
		--ct-services-orbit-y: 0% !important;
		--ct-services-orbit-angle-offset: 90 !important;
		--ct-services-node-size: 44px !important;
		--ct-services-media-width: 100% !important;
		--ct-services-column-gap: 18px !important;
		--ct-services-duration: 540ms !important;
		--ct-services-line-duration: 320ms !important;
		--ct-services-reveal: 6px !important;
		/* Keep the compact top arc fully usable in short landscape viewports
		   without overriding the responsive Elementor controls. */
		--ct-services-mobile-orbit-size: min(
			var(--ct-services-orbit-size),
			calc(100vw - var(--ct-services-node-size) - 24px),
			32svh
		);
		/* One node width keeps the outer number centres and their badges below
		   the stage edge while only the lower half of the circle is exposed. */
		--ct-services-mobile-arc-offset: var(--ct-services-node-size);
		--ct-services-mobile-arc-space: calc(
			var(--ct-services-mobile-orbit-size) / 2 +
			var(--ct-services-mobile-arc-offset) +
			var(--ct-services-node-size) / 2 + 12px
		);
		--ct-services-panel-columns: minmax(0, 1fr);
		--ct-services-panel-rows: auto minmax(0, 1fr);
		--ct-services-panel-areas: "content" "media";
	}
	/* Responsive decorations and media remain inside their widget. This rule
	   does not affect the intentionally full-bleed desktop/tablet arc. */
	.ct-timeline--scroll-services,
	.ct-services__sticky-layer,
	.ct-services__stage,
	.ct-services__panels,
	.ct-services__panel,
	.ct-services__media {
		max-width: 100%;
		min-width: 0;
	}
	.ct-timeline--scroll-services {
		overflow-x: clip;
	}
	.ct-services__sticky-layer {
		/* Fill the usable mobile viewport. The previous 88vh stage plus the
		   safety inset exposed a blank strip before the section released. */
		max-height: calc(100vh - var(--ct-services-sticky-top));
		max-height: calc(100svh - var(--ct-services-sticky-top));
		min-height: min(420px, calc(100svh - var(--ct-services-sticky-top)));
	}
	.ct-services__stage {
		display: block;
		min-height: min(440px, calc(100svh - var(--ct-services-sticky-top)));
		padding: 20px;
	}
	.ct-services__orbit {
		position: absolute;
		left: 50%;
		/* Only the useful lower semicircle is exposed on phones. Its centre sits
		   just inside the stage, so nodes remain complete without allowing the
		   orbit to overlap the preceding Elementor section. */
		top: calc(var(--ct-services-orbit-y) + var(--ct-services-mobile-arc-offset));
		width: var(--ct-services-mobile-orbit-size);
		height: var(--ct-services-mobile-orbit-size);
		min-height: 0;
		border: 0;
		border-radius: 50%;
		transform: translate(calc(-50% + var(--ct-services-orbit-x)), -50%);
		-webkit-clip-path: inset(
			calc(50% - var(--ct-services-mobile-arc-offset))
			calc(0px - var(--ct-services-node-size))
			calc(0px - var(--ct-services-node-size))
			calc(0px - var(--ct-services-node-size))
		);
		clip-path: inset(
			calc(50% - var(--ct-services-mobile-arc-offset))
			calc(0px - var(--ct-services-node-size))
			calc(0px - var(--ct-services-node-size))
			calc(0px - var(--ct-services-node-size))
		);
		display: block;
		backface-visibility: hidden;
		-webkit-backface-visibility: hidden;
	}
	.ct-services__orbit::before,
	.ct-services__orbit::after { display: none; }
	.ct-services__orbit-progress {
		display: block;
	}
	.ct-services__node {
		font-size: 13px;
		backface-visibility: hidden;
		-webkit-backface-visibility: hidden;
	}
	/* Keep only the currently animating surfaces on compositor layers. This
	   removes Safari paint flicker without permanently promoting every panel. */
	.ct-services--near .ct-services__panel.is-active,
	.ct-services--near .ct-services__background.is-active {
		backface-visibility: hidden;
		-webkit-backface-visibility: hidden;
	}
	.ct-services__background {
		transform: translate3d(0, 0, 0) scale(1.006);
	}
	.ct-services__background.is-active {
		transform: translate3d(0, 0, 0) scale(1);
	}
	.ct-services__panels {
		width: 100%;
		max-width: 100%;
		height: 100%;
		min-height: 0;
		margin-left: 0;
	}
	.ct-services__panel {
		inset: var(--ct-services-mobile-arc-space) 0 0;
		grid-template-columns: minmax(0, 1fr);
		grid-template-rows: auto minmax(0, 1fr);
		align-content: center;
		gap: var(--ct-services-column-gap);
		overflow-y: hidden;
		overflow-x: hidden;
	}
	.ct-services__panel.has-media {
		grid-template-columns: var(--ct-services-panel-columns);
		grid-template-rows: var(--ct-services-panel-rows);
		grid-template-areas: var(--ct-services-panel-areas);
	}
	.ct-services__content {
		gap: 12px;
		max-width: none;
	}
	.ct-services__title {
		font-size: clamp(30px, 10vw, 46px);
		line-height: 1;
	}
	.ct-services__description {
		font-size: 14px;
		line-height: 1.45;
	}
	.ct-services__tags {
		gap: 7px;
	}
	.ct-services__tag {
		min-height: 28px;
		padding: 6px 11px;
		font-size: 11px;
	}
	.ct-services__media {
		height: min(28vh, 240px);
		height: min(28svh, 240px);
		min-height: 0;
		max-width: 100%;
	}
	.ct-services__image {
		max-width: 100%;
		max-height: 100%;
	}
}

/* Compact tablet landscape / large-phone landscape. Keep the full-bleed arc
   at the left, but prevent a desktop-sized circle from crossing the short
   viewport's top and bottom boundaries. */
@media (min-width: 768px) and (max-width: 1024px) and (max-height: 560px) {
	.ct-timeline--scroll-services {
		--ct-services-sticky-top: 4px !important;
		--ct-services-stage-height: calc(100svh - var(--ct-services-sticky-top)) !important;
		--ct-services-orbit-size: min(56vh, 340px) !important;
		--ct-services-orbit-size: min(56svh, 340px) !important;
		--ct-services-orbit-x: -54% !important;
		--ct-services-node-size: 40px !important;
		--ct-services-column-gap: 18px !important;
	}
	.ct-services__stage {
		padding: 16px 20px;
	}
	.ct-services__panels {
		margin-left: clamp(112px, 19vw, 180px);
	}
	.ct-services__content {
		gap: 8px;
	}
	.ct-services__title {
		font-size: clamp(26px, 4.5vw, 40px);
	}
	.ct-services__media {
		height: min(60svh, 220px);
	}
}

/* ── ACCESSIBILITY ─────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
	.ct-timeline__card,
	.ct-timeline__line-fill,
	.ct-timeline__icon,
	.ct-timeline__button,
	.ct-services__panel,
	.ct-services__node,
	.ct-services__background,
	.ct-services__orbit-progress-path,
	.ct-services__orbit::after {
		transition: none !important;
		animation: none !important;
	}
	.ct-timeline__card--pre-entrance,
	.ct-timeline__card--pre-entrance-h {
		opacity: 1 !important;
		transform: none !important;
	}
}
