/**
 * JMeks Advisory Network styles.
 *
 * Disciplines sit in a column grid and each spans as many columns as it has
 * people, so the browser packs them onto rows and wraps when the next will not
 * fit: two plus one share a row, three plus two do not. The span comes from PHP
 * as a custom property, already clamped to the column count — a span wider than
 * the grid would create implicit columns and push the group off the side.
 *
 * A group scrolls only when it holds more people than it has columns, and then
 * the scrolling is the browser's own: snap points, momentum, keyboard, and a
 * focusable region. Nothing moves on a timer. These are names people read and
 * links they click, and moving them on their behalf makes both harder — see
 * WCAG 2.2.2, which an auto-scrolling version of this would fail.
 *
 * The layout is fixed here rather than exposed as controls. Every number below
 * depends on the others — the peek is subtracted from the card, the trailing
 * ramp is measured from where the card ends, the reach decides whether the peek
 * is on screen at all — so a panel full of sliders offers a granularity this
 * section cannot actually use, and most combinations of them are wrong. The
 * Text tab still styles the words.
 *
 * Custom properties (all set here; --span is per group, from PHP):
 *   --jmeks-network-columns            columns in the grid
 *   --jmeks-network-column-gap         between people
 *   --jmeks-network-row-gap            between groups
 *   --jmeks-network-peek               how much of the next person shows
 *   --jmeks-network-reach              how far a scrolling row runs past the
 *                                      content edge
 *   --jmeks-network-fade               how far the edge fade ramps
 *   --jmeks-network-fade-lead-size     that ramp at the leading edge
 *   --jmeks-network-fade-trail-size    and at the trailing one
 *   --jmeks-network-span               a group's width in columns (from PHP)
 */

.elementor-widget-jmeks_advisory_network {
	width: 100%;
}

.jmeks-network {
	--jmeks-network-columns: 4;
	--jmeks-network-column-gap: 24px;
	--jmeks-network-row-gap: 48px;
	--jmeks-network-peek: 20px;

	/*
	 * Far enough into the margin beside the content for the peek to land on
	 * screen. Below the multi-column breakpoint there is no such margin, so the
	 * rule at the end of this file takes it back to zero and the peek comes off
	 * the card instead.
	 */
	--jmeks-network-reach: 80px;

	/*
	 * The two ends of the ramp are sized separately, because what sits at each
	 * end differs by breakpoint: on a wide screen both are half-scrolled cards,
	 * on a phone the leading end is a card snapped flush against it.
	 */
	--jmeks-network-fade: 72px;
	--jmeks-network-fade-lead-size: var( --jmeks-network-fade );
	--jmeks-network-fade-trail-size: var( --jmeks-network-fade );

	width: 100%;
}

.jmeks-network__eyebrow {
	margin: 0 0 32px;
}

.jmeks-network__groups {
	display: grid;
	grid-template-columns: repeat( var( --jmeks-network-columns ), 1fr );
	column-gap: var( --jmeks-network-column-gap );
	row-gap: var( --jmeks-network-row-gap );
}

.jmeks-network__group {
	/* Substitution is textual, so `span var(--n)` becomes `span 2`. */
	grid-column: span var( --jmeks-network-span, 1 );
	min-width: 0;
}

.jmeks-network__head {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 16px;
	margin-bottom: 20px;
	padding-bottom: 10px;
	border-bottom: 1px solid currentColor;
}

.jmeks-network__label {
	margin: 0;
}

/*
 * Two classes on the colour: the kit writes heading colours as
 * `.elementor-kit-N h2` (0,1,1), which beats one class and would paint this
 * heading in the site's heading colour instead of the widget's.
 */
.jmeks-network .jmeks-network__label {
	color: inherit;
}

/*
 * Hidden until the runtime says the row can move. It is in the markup for every
 * row that could ever overflow, because whether one does depends on the width;
 * hiding it here means a browser running no JavaScript shows no controls at all
 * rather than dead ones, and native scrolling still works.
 */
.jmeks-network__nav {
	display: none;
}

.jmeks-network__group.is-scrollable .jmeks-network__nav {
	display: flex;
	flex: 0 0 auto;
	gap: 4px;
}


.jmeks-network__arrow {
	border: 0;
	background: none;
	padding: 0 6px;
	color: inherit;
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
}

.jmeks-network__arrow[disabled] {
	opacity: 0.3;
	cursor: default;
}

.jmeks-network__scroller {
	display: flex;
	gap: var( --jmeks-network-column-gap );
}

.jmeks-network__person {
	/*
	 * One column wide, so people line up across groups of different widths:
	 * the group is as many columns as it spans, plus the gaps between them.
	 *
	 * How many actually fit is the SMALLER of the group's span and the columns
	 * on offer at this width. The span is worked out in PHP and baked in, so it
	 * cannot change per breakpoint; the column count is a responsive control
	 * and can. Dividing by the span alone leaves quarter-width cards on a phone
	 * — four names across a 390px screen — however the control is set.
	 */
	--jmeks-network-across: min( var( --jmeks-network-span, 1 ), var( --jmeks-network-columns, 4 ) );

	/*
	 * Exactly one column, and nothing is allowed to shave it.
	 *
	 * Taking the peek off the row before dividing does show the next person,
	 * but it shortens every card in THAT row by peek/across — so its names
	 * creep left a little further with each column while the rows above and
	 * below stay on the grid. Two disciplines one under the other then have
	 * their third names five pixels apart, which reads as sloppy long before
	 * anyone works out why.
	 *
	 * The peek is a property of the scrollport instead: see the reach below.
	 */
	flex: 0 0 calc( ( 100% - ( var( --jmeks-network-across ) - 1 ) * var( --jmeks-network-column-gap ) ) / var( --jmeks-network-across ) );
	min-width: 0;
}

.jmeks-network__name {
	display: block;
	margin-bottom: 12px;
	color: inherit;
	text-decoration: none;
}

/*
 * A person's link sits on their company (their name if there is none) and is
 * underlined all the time, so it reads as a link without hovering. The site
 * kit styles every link (`.elementor-kit-N a`, a class and a tag), so these
 * carry the widget's class too.
 */
.jmeks-network a.jmeks-network__link,
.jmeks-network a.jmeks-network__link:hover,
.jmeks-network a.jmeks-network__link:focus {
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
}

.jmeks-network a.jmeks-network__link:hover {
	text-decoration-thickness: 2px;
}

.jmeks-network a.jmeks-network__link:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

/* The company keeps the line's own look (Style > Text), not the kit's link look. */
.jmeks-network .jmeks-network__meta a.jmeks-network__company {
	color: inherit;
	font: inherit;
	letter-spacing: inherit;
	text-transform: inherit;
}

.jmeks-network__meta,
.jmeks-network__speciality {
	margin: 0 0 4px;
}

/*
 * Company and role sit on one line with a set gap between them (the Gap
 * control), wrapping the role to its own line if the card is too narrow.
 * The space between the two spans in the markup is ignored in a flex line,
 * so the gap is the only spacing.
 */
.jmeks-network__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	column-gap: 0.3em;
}

/*
 * Dimmer than the company by default. The dimming is in the colour, not an
 * opacity, so a colour picked in Style > Text > Role shows exactly as picked
 * rather than at 60% of itself.
 */
.jmeks-network__role {
	color: color-mix( in srgb, currentColor 60%, transparent );
}

/*
 * Bleed. A scrolling row runs on past its container into the margin, so an
 * overflowing discipline reads as "there is more" rather than being cut at the
 * content edge — while the group's label, rule and first card stay on the grid.
 *
 * The negative margin widens the box and the padding gives the row somewhere to
 * scroll into. They cancel for sizing: with border-box the content box comes
 * back to exactly the group's width, so the cards keep their column widths and
 * still line up with groups that are not scrolling.
 */
.jmeks-network__group--scrolls .jmeks-network__scroller {
	margin-inline-end: calc( -1 * var( --jmeks-network-reach ) );
	padding-inline-end: var( --jmeks-network-reach );
}

/* ------------------------------------------------------------- scrolling */

.jmeks-network__group--scrolls .jmeks-network__scroller {
	/*
	 * Both edges reach zero, and that is the whole point.
	 *
	 * The row is clipped at the scrollport boundary whatever the mask does, so
	 * whatever opacity the ramp has reached there IS the edge you see. Stopping
	 * at 45% to keep the text readable only clips text that is 45% opaque: a
	 * paler cut, still a cut. Widening the ramp instead makes it worse, because
	 * it dims more without ever finishing.
	 *
	 * Readability comes from the ramp being SHORT, not from refusing to finish
	 * it: full strength until the last 72px, then gone.
	 *
	 * The two knobs pull against each other. Fading less keeps the text
	 * readable but shortens the ramp, which reads as a harder cut — so
	 * softness comes from the DISTANCE, not the depth: a long gentle ramp that
	 * never takes much away. Composed once here so the three edge states below
	 * share it.
	 */
	overflow-x: auto;
	/*
	 * No snapping on a wide screen. Snapping earns its keep where a card fills
	 * the view and a swipe should land on one; with a mouse on a wide screen it
	 * only fights the person, realigning a pull that ended exactly where they
	 * meant it to. See the phone rule at the end of this file.
	 */
	scroll-snap-type: none;
	scrollbar-width: none;
	cursor: auto;
}

.jmeks-network__group--scrolls .jmeks-network__scroller::-webkit-scrollbar {
	display: none;
}

.jmeks-network__group--scrolls.is-scrollable .jmeks-network__scroller {
	cursor: grab;

	/*
	 * Only a row that actually overflows is masked.
	 *
	 * The markup marks every row that COULD overflow, since that depends on the
	 * width, but a fade is a promise that something is hidden past the edge. On
	 * a row that fits it greys out a name for nothing — a two-person row read as
	 * a broken first card. is-scrollable is the runtime's answer to "is there
	 * anything to scroll", so the mask hangs off that and not off the markup.
	 *
	 * Then is-at-start and is-at-end below drop whichever side has nothing
	 * behind it.
	 */
	-webkit-mask-image: linear-gradient( to right, transparent 0, #000 var( --jmeks-network-fade-lead-size ), #000 calc( 100% - var( --jmeks-network-fade-trail-size ) ), transparent 100% );
	mask-image: linear-gradient( to right, transparent 0, #000 var( --jmeks-network-fade-lead-size ), #000 calc( 100% - var( --jmeks-network-fade-trail-size ) ), transparent 100% );
}

.jmeks-network__group--scrolls.is-dragging .jmeks-network__scroller {
	cursor: grabbing;
	scroll-snap-type: none;
	user-select: none;
}

/* Still coasting from a flick: snapping waits until it has landed. */
.jmeks-network__group--scrolls.is-settling .jmeks-network__scroller {
	scroll-snap-type: none;
}

.jmeks-network__group--scrolls.is-scrollable.is-at-start .jmeks-network__scroller {
	-webkit-mask-image: linear-gradient( to right, #000 0, #000 calc( 100% - var( --jmeks-network-fade-trail-size ) ), transparent 100% );
	mask-image: linear-gradient( to right, #000 0, #000 calc( 100% - var( --jmeks-network-fade-trail-size ) ), transparent 100% );
}

.jmeks-network__group--scrolls.is-scrollable.is-at-end .jmeks-network__scroller {
	-webkit-mask-image: linear-gradient( to right, transparent 0, #000 var( --jmeks-network-fade-lead-size ), #000 100% );
	mask-image: linear-gradient( to right, transparent 0, #000 var( --jmeks-network-fade-lead-size ), #000 100% );
}

.jmeks-network__group--scrolls .jmeks-network__person {
	scroll-snap-align: start;
}

/* --------------------------------------------------------------- stacked */

/*
 * Below the desktop breakpoint every discipline takes its own row. The span
 * baked in by PHP is the desktop column count, so a four-column group dropped
 * into a two-column grid would spill into implicit columns and run off the
 * side; spanning the whole row sidesteps that at every narrower width.
 */
@media ( max-width: 1024px ) {
	.jmeks-network__group {
		grid-column: 1 / -1;
	}

	/*
	 * The peek comes off the card here, and it has to.
	 *
	 * Above this breakpoint it lives in the margin beside the content, which is
	 * on screen and wide. Below it there is no such margin: the card fills the
	 * content width and the gap alone is wider than the gutter, so the next
	 * person starts past the edge of the SCREEN and no value of the control can
	 * pull it back into view.
	 *
	 * Narrowing the card is safe here in a way it is not above, where it put
	 * groups of different widths out of step with each other. Every discipline
	 * takes the whole row below this breakpoint, so they all start at the same
	 * left edge; and the row divides by the column count rather than by how
	 * many people this particular group has, so every card everywhere on the
	 * page comes out the same width.
	 */
	.jmeks-network__person {
		flex: 0 0 calc( ( 100% - var( --jmeks-network-peek, 0px ) - var( --jmeks-network-columns, 1 ) * var( --jmeks-network-column-gap ) ) / var( --jmeks-network-columns, 1 ) );
	}

	/*
	 * And the row stops at the content edge. Reaching past it is what shows the
	 * peek on a wide screen; here it would only push the peek, and the trailing
	 * ramp with it, off the side of the screen.
	 */

	/*
	 * No leading fade. A chevron step and a snap both land a card flush against
	 * the start of the scrollport, so a ramp there dims the first characters of
	 * a name that is entirely on screen — "Chris" arriving two letters short.
	 * The back chevron already says there is something behind it.
	 *
	 * The trailing ramp is sized from the peek and the gap instead of the
	 * desktop distance, so it starts exactly where the card ends: it covers the
	 * gap and ghosts the peeking sliver, and never touches readable text.
	 */
	.jmeks-network {
		--jmeks-network-reach: 0px;
		--jmeks-network-fade-lead-size: 0px;
		--jmeks-network-fade-trail-size: calc( var( --jmeks-network-peek, 0px ) + var( --jmeks-network-column-gap ) );
	}

	/*
	 * The same steps the Columns control defaults to. Stated here as well so
	 * the widget is right on its own, before Elementor has generated any CSS
	 * for it — a control's value only reaches the page once it is in the saved
	 * document. Anything actually set in the panel outranks this.
	 */
	.jmeks-network {
		--jmeks-network-columns: 2;
	}
}

@media ( max-width: 767px ) {
	.jmeks-network {
		--jmeks-network-columns: 1;
	}


	/*
	 * A card fills the screen here, so a swipe should land on one rather than
	 * stopping halfway across two. The dragging and settling rules above are
	 * three classes and still override this, so a mouse drag is unaffected.
	 */
	.jmeks-network__group--scrolls .jmeks-network__scroller {
		scroll-snap-type: x mandatory;
	}
}

@media ( prefers-reduced-motion: reduce ) {
	.jmeks-network__scroller {
		scroll-behavior: auto;
	}
}
