/*
 * Brand Dial - logos on an orbit around a hub, with a read-out panel.
 *
 * Every colour and size below is a custom property the widget writes through
 * Elementor `selectors`, so this sheet holds the geometry and the defaults and
 * the panel holds the decisions. The defaults are the SUTEK palette, which is
 * what the widget looks like before anybody opens the Style tab.
 *
 * Geometry note: the ring is NOT a rotation of the whole dial. The dial sets
 * `--rot` and each node sits at `--i * step + var(--rot)`, then counter-rotates
 * itself by the same angle - so the pills travel the circle while their logos
 * stay upright. Spinning the container instead would turn every logo upside
 * down on the way past 180deg.
 */

.tqcd {
	/* Geometry. These five and the hub diameter are ALSO the defaults on the
	   Ring and Hub style controls - a control reset to empty has to land back
	   on what it was showing, so the two sets are edited together. */
	--tqcd-r: 200px;          /* orbit radius      */
	--tqcd-hub: 200px;        /* hub diameter      */
	--tqcd-nw: 120px;         /* node width        */
	--tqcd-nh: 60px;          /* node height       */
	--tqcd-gap: 60px;         /* dial <-> panel    */
	--tqcd-node-radius: 100px;
	--tqcd-beam-h: 3px;
	--tqcd-hub-logo: 86%;
	--tqcd-mark-h: 48px;
	--tqcd-btn-h: 46px;
	--tqcd-btn-radius: 999px;
	--tqcd-tag-radius: 999px;
	--tqcd-blurb-w: 40ch;

	/* The panel's vertical rhythm. Every gap between two things in the panel
	   is one of these and nothing else, so each is one control in the Style
	   tab rather than a number buried in a rule. */
	--tqcd-sp-mark: 18px;     /* under the brand logo  */
	--tqcd-sp-meta: 9px;      /* under the eyebrow     */
	--tqcd-sp-blurb: 11px;    /* over the description  */
	--tqcd-sp-tags: 18px;     /* over the tags         */
	--tqcd-sp-acts: 24px;     /* over the buttons      */
	--tqcd-sp-tag-gap: 7px;   /* between tags          */
	--tqcd-sp-btn-gap: 10px;  /* between buttons       */

	/* palette */
	--tqcd-brand: #1d91b8;
	--tqcd-brand-700: #115d78;
	--tqcd-accent: #5fd0ef;
	--tqcd-tint: #e8f4f9;
	--tqcd-tint-2: #d2e9f2;
	--tqcd-card: #ffffff;
	--tqcd-line: #e3ebf0;
	--tqcd-line-2: #c9d8e1;
	--tqcd-ink: #0e1d25;
	--tqcd-muted: #657f8e;

	--tqcd-ease: cubic-bezier(.22, .61, .36, 1);

	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--tqcd-gap);
}

/* The ratio the widget prints on every `<img>` it builds, as the host
   plugin's images carry it. The `width`/`height` attributes alone do not
   survive Elementor's `.elementor img { height: auto }`, so without a
   SPECIFIED aspect-ratio the browser reserves no box and every logo here is
   a layout shift - and DevTools says so, once per image.

   Inside `:where()` so it carries no specificity: anything that wants to set
   its own ratio still wins, and an image with no attachment behind it (a URL
   typed in by hand) falls through to `auto`. */
:where(.tqcd img) {
	aspect-ratio: var(--tef-img-ar, auto);
}

/* ============================================================ the dial */

.tqcd__dial {
	position: relative;
	flex: none;
	/* The box has to clear the ring plus half a node on each side, or the
	   pills at 12 and 6 o-clock are clipped by the widget bounds. */
	width: calc(var(--tqcd-r) * 2 + var(--tqcd-nw));
	height: calc(var(--tqcd-r) * 2 + var(--tqcd-nh));
}

.tqcd__orbit {
	position: absolute;
	left: 50%;
	top: 50%;
	width: calc(var(--tqcd-r) * 2);
	height: calc(var(--tqcd-r) * 2);
	margin: calc(var(--tqcd-r) * -1) 0 0 calc(var(--tqcd-r) * -1);
	border: 1px dashed var(--tqcd-line-2);
	border-radius: 50%;
}

/* Hub -> focus slot. The slot is 3 o-clock, or 9 o-clock under RTL, which is
   also where the script parks the selected node - see the --rot note above. */
.tqcd__beam {
	position: absolute;
	top: 50%;
	z-index: 4;
	left: calc(50% + var(--tqcd-hub) / 2 + 4px);
	width: calc(var(--tqcd-r) - var(--tqcd-hub) / 2 - var(--tqcd-nw) / 2 + 16px);
	height: var(--tqcd-beam-h);
	transform: translateY(-50%);
	border-radius: var(--tqcd-beam-h);
	background: linear-gradient(90deg,
		color-mix(in srgb, var(--tqcd-brand) 18%, transparent) 0%,
		var(--tqcd-brand) 60%,
		var(--tqcd-accent) 100%);
	box-shadow: 0 0 12px -2px color-mix(in srgb, var(--tqcd-accent) 70%, transparent);
}

.tqcd__beam::before,
.tqcd__beam::after {
	content: "";
	position: absolute;
	top: 50%;
	border-radius: 50%;
}

/* The dot the beam lands on. */
.tqcd__beam::before {
	right: -1px;
	width: 9px;
	height: 9px;
	transform: translate(50%, -50%);
	background: var(--tqcd-accent);
	box-shadow: 0 0 0 4px color-mix(in srgb, var(--tqcd-accent) 24%, transparent);
}

/* The travelling pulse. */
.tqcd__beam::after {
	left: 0;
	width: 6px;
	height: 6px;
	transform: translate(-50%, -50%);
	background: #fff;
	box-shadow: 0 0 8px 2px var(--tqcd-accent);
	animation: tqcd-pulse 2.4s cubic-bezier(.55, 0, .45, 1) infinite;
}

@keyframes tqcd-pulse {
	0%   { left: 0;    opacity: 0 }
	18%  { opacity: 1 }
	82%  { opacity: 1 }
	100% { left: 100%; opacity: 0 }
}

.tqcd--no-orbit .tqcd__orbit,
.tqcd--no-beam .tqcd__beam { display: none }

/* RTL: the panel sits to the left of the dial, so the beam has to point the
   other way. Mirrored by hand rather than with scaleX(-1), which would also
   mirror the gradient direction and flip the landing dot inwards. */
.rtl .tqcd__beam,
[dir="rtl"] .tqcd__beam {
	left: auto;
	right: calc(50% + var(--tqcd-hub) / 2 + 4px);
	background: linear-gradient(270deg,
		color-mix(in srgb, var(--tqcd-brand) 18%, transparent) 0%,
		var(--tqcd-brand) 60%,
		var(--tqcd-accent) 100%);
}

.rtl .tqcd__beam::before,
[dir="rtl"] .tqcd__beam::before {
	right: auto;
	left: -1px;
	transform: translate(-50%, -50%);
}

.rtl .tqcd__beam::after,
[dir="rtl"] .tqcd__beam::after {
	left: auto;
	right: 0;
	transform: translate(50%, -50%);
	animation-name: tqcd-pulse-rtl;
}

@keyframes tqcd-pulse-rtl {
	0%   { right: 0;    opacity: 0 }
	18%  { opacity: 1 }
	82%  { opacity: 1 }
	100% { right: 100%; opacity: 0 }
}

/* ============================================================== the hub */

.tqcd__hub {
	position: absolute;
	left: 50%;
	top: 50%;
	z-index: 3;
	width: var(--tqcd-hub);
	aspect-ratio: 1;
	transform: translate(-50%, -50%);
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 7px;
	padding: 18px;
	border: 1px solid var(--tqcd-line);
	border-radius: 50%;
	background: var(--tqcd-card);
	box-shadow: 0 20px 40px -24px rgba(11, 62, 82, .55);
}

/* No pixel cap on top of the percentage: the hub is sized by a control, and a
   hard max-width meant growing the hub left the logo the size it was. The
   percentage is of the hub's content box, so the padding above is what keeps
   the mark off the edge. */
.tqcd__hub img {
	display: block;
	width: var(--tqcd-hub-logo);
	height: auto;
}

.tqcd__hub-tag {
	font-size: 9.5px;
	font-weight: 700;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--tqcd-brand);
	text-align: center;
	line-height: 1.2;
}

/* ============================================================ the nodes */

.tqcd__nodes {
	position: absolute;
	inset: 0;
	z-index: 2;
}

.tqcd__node {
	position: absolute;
	left: 50%;
	top: 50%;
	width: var(--tqcd-nw);
	height: var(--tqcd-nh);
	/* Tight on purpose: the logo is capped by the pill's CONTENT box, so every
	   pixel of padding here is a pixel off the mark inside it. */
	padding: 8px 12px;
	--a: calc(var(--i) * var(--tqcd-step, 45deg) + var(--rot, 0deg));
	transform: translate(-50%, -50%) rotate(var(--a)) translate(var(--tqcd-r)) rotate(calc(-1 * var(--a)));
	transition:
		transform .66s cubic-bezier(.33, 1, .68, 1),
		border-color .25s var(--tqcd-ease),
		box-shadow .25s var(--tqcd-ease);
	display: flex;
	align-items: center;
	justify-content: center;
	cursor: pointer;
	border: 1px solid var(--tqcd-line);
	border-radius: var(--tqcd-node-radius);
	background: var(--tqcd-card);
	box-shadow: 0 1px 2px rgba(14, 29, 37, .04), 0 10px 26px -14px rgba(14, 29, 37, .14);
}

.tqcd__node-logo {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
}

.tqcd__node img {
	display: block;
	max-width: 100%;
	max-height: 100%;
	width: auto;
	height: auto;
	transition: filter .25s var(--tqcd-ease), opacity .25s var(--tqcd-ease);
}

/* The text stand-in for a brand with no logo picked yet. Not a placeholder
   image on purpose: a dial of grey boxes says the widget is broken, a dial of
   brand names says which logo goes where. */
.tqcd__node-text {
	font-size: 13px;
	font-weight: 700;
	letter-spacing: .04em;
	color: var(--tqcd-muted);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.tqcd--dim-logos .tqcd__node img {
	filter: grayscale(1);
	opacity: .45;
}

.tqcd__node:hover,
.tqcd__node:focus-visible {
	outline: 0;
	border-color: var(--tqcd-brand);
	box-shadow: 0 14px 26px -16px color-mix(in srgb, var(--tqcd-brand) 55%, transparent);
}

.tqcd__node[data-on] {
	border-color: var(--tqcd-brand);
	box-shadow:
		0 0 0 4px var(--tqcd-tint),
		0 18px 34px -18px color-mix(in srgb, var(--tqcd-brand) 70%, transparent);
}

.tqcd--dim-logos .tqcd__node:hover img,
.tqcd--dim-logos .tqcd__node:focus-visible img,
.tqcd--dim-logos .tqcd__node[data-on] img {
	filter: none;
	opacity: 1;
}

.tqcd__node:hover .tqcd__node-text,
.tqcd__node[data-on] .tqcd__node-text { color: var(--tqcd-brand-700) }

/* ============================================================= the panel */

.tqcd__panels {
	flex: 0 1 468px;
	min-width: 0;
	position: relative;
}

.tqcd__panel {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
}

.tqcd__panel[hidden] { display: none }

.tqcd__panel.is-swapping { animation: tqcd-swap .36s var(--tqcd-ease) }

@keyframes tqcd-swap {
	from { opacity: 0; transform: translateX(16px) }
	to   { opacity: 1; transform: none }
}

.rtl .tqcd__panel.is-swapping,
[dir="rtl"] .tqcd__panel.is-swapping { animation-name: tqcd-swap-rtl }

@keyframes tqcd-swap-rtl {
	from { opacity: 0; transform: translateX(-16px) }
	to   { opacity: 1; transform: none }
}

.tqcd__mark {
	height: var(--tqcd-mark-h);
	display: flex;
	align-items: center;
	margin-block-end: var(--tqcd-sp-mark);
}

.tqcd__mark img {
	max-height: 100%;
	max-width: min(100%, 200px);
	width: auto;
	height: auto;
	display: block;
}

.tqcd__mark-text {
	font-size: 22px;
	font-weight: 800;
	letter-spacing: .02em;
	color: var(--tqcd-ink);
}

.tqcd__meta {
	margin: 0 0 var(--tqcd-sp-meta);
	font-size: 11px;
	font-weight: 700;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--tqcd-brand);
}

.tqcd__meta i {
	font-style: normal;
	opacity: .45;
	margin: 0 4px;
}

.tqcd__name {
	margin: 0;
	font-size: 21px;
	font-weight: 750;
	line-height: 1.25;
	letter-spacing: -.01em;
	color: var(--tqcd-ink);
}

.tqcd__blurb {
	margin: var(--tqcd-sp-blurb) 0 0;
	font-size: 13.5px;
	line-height: 1.65;
	color: var(--tqcd-muted);
	max-width: var(--tqcd-blurb-w);
}

.tqcd__tags {
	display: flex;
	flex-wrap: wrap;
	gap: var(--tqcd-sp-tag-gap);
	margin-block-start: var(--tqcd-sp-tags);
}

.tqcd__tags span {
	font-size: 11px;
	font-weight: 600;
	color: var(--tqcd-brand-700);
	background: var(--tqcd-tint);
	border: 1px solid var(--tqcd-tint-2);
	border-radius: var(--tqcd-tag-radius);
	padding: 4px 10px;
}

.tqcd__acts {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--tqcd-sp-btn-gap);
	margin-block-start: var(--tqcd-sp-acts);
}

/* ============================================================== buttons */

.tqcd__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 9px;
	height: var(--tqcd-btn-h);
	padding: 0 20px;
	border: 1px solid var(--tqcd-line-2);
	border-radius: var(--tqcd-btn-radius);
	background: var(--tqcd-card);
	color: var(--tqcd-ink);
	font-size: 14px;
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
	cursor: pointer;
	transition: all .18s var(--tqcd-ease);
}

.tqcd__btn:hover,
.tqcd__btn:focus-visible {
	border-color: var(--tqcd-brand);
	color: var(--tqcd-brand-700);
	transform: translateY(-1px);
	text-decoration: none;
}

.tqcd__btn:active { transform: translateY(0) }

.tqcd__btn--solid {
	background: var(--tqcd-brand);
	border-color: var(--tqcd-brand);
	color: #fff;
	box-shadow: 0 8px 20px -10px color-mix(in srgb, var(--tqcd-brand) 80%, transparent);
}

.tqcd__btn--solid:hover,
.tqcd__btn--solid:focus-visible {
	background: var(--tqcd-brand-700);
	border-color: var(--tqcd-brand-700);
	color: #fff;
}

.tqcd__btn--ghost {
	background: transparent;
	border-color: transparent;
	color: var(--tqcd-muted);
}

.tqcd__btn--ghost:hover,
.tqcd__btn--ghost:focus-visible {
	background: var(--tqcd-tint);
	color: var(--tqcd-brand-700);
}

.tqcd__btn svg {
	width: 18px;
	height: 18px;
	flex: none;
	fill: none;
	stroke: currentColor;
	stroke-width: 1.6;
	stroke-linecap: round;
	stroke-linejoin: round;
}

.rtl .tqcd__btn svg,
[dir="rtl"] .tqcd__btn svg { transform: scaleX(-1) }

/* ========================================================== dark mode */

/* Opt-in, and keyed on the two selectors the Elementra dark mode actually
   sets: the explicit attribute for the manual path, and the media query
   guarded by :not([data-tewido-theme="light"]) for the system-preference
   path. Off by default because a site with no dark mode at all must not
   invert its logos just because the visitor OS is dark. */
html[data-tewido-theme="dark"] .tqcd--invert-dark img {
	filter: brightness(0) invert(1);
	opacity: 1;
}

html[data-tewido-theme="dark"] .tqcd--invert-dark.tqcd--dim-logos .tqcd__node img {
	filter: brightness(0) invert(1);
	opacity: .4;
}

html[data-tewido-theme="dark"] .tqcd--invert-dark.tqcd--dim-logos .tqcd__node:hover img,
html[data-tewido-theme="dark"] .tqcd--invert-dark.tqcd--dim-logos .tqcd__node:focus-visible img,
html[data-tewido-theme="dark"] .tqcd--invert-dark.tqcd--dim-logos .tqcd__node[data-on] img {
	filter: brightness(0) invert(1);
	opacity: 1;
}

@media (prefers-color-scheme: dark) {
	html:not([data-tewido-theme="light"]) .tqcd--invert-dark img {
		filter: brightness(0) invert(1);
		opacity: 1;
	}

	html:not([data-tewido-theme="light"]) .tqcd--invert-dark.tqcd--dim-logos .tqcd__node img {
		filter: brightness(0) invert(1);
		opacity: .4;
	}

	html:not([data-tewido-theme="light"]) .tqcd--invert-dark.tqcd--dim-logos .tqcd__node:hover img,
	html:not([data-tewido-theme="light"]) .tqcd--invert-dark.tqcd--dim-logos .tqcd__node:focus-visible img,
	html:not([data-tewido-theme="light"]) .tqcd--invert-dark.tqcd--dim-logos .tqcd__node[data-on] img {
		filter: brightness(0) invert(1);
		opacity: 1;
	}
}

/* ========================================================== responsive */

@media (max-width: 1080px) {
	.tqcd {
		flex-direction: column;
		gap: 30px;
		max-width: 620px;
		margin-inline: auto;
	}

	.tqcd__panels {
		flex: 1 1 auto;
		width: 100%;
	}

	.tqcd__blurb { --tqcd-blurb-w: 52ch }
}

/* Below ~860px the ring pills start colliding, so the dial unrolls into a hub
   above a grid of logos. Same nodes, same script, no second markup. */
@media (max-width: 860px) {
	.tqcd__dial {
		width: 100%;
		height: auto;
		display: flex;
		flex-direction: column;
		gap: 14px;
	}

	.tqcd__orbit,
	.tqcd__beam { display: none }

	.tqcd__hub {
		position: static;
		transform: none;
		width: 100%;
		aspect-ratio: auto;
		border-radius: 18px;
		flex-direction: row;
		justify-content: center;
		gap: 14px;
		padding: 16px 18px;
	}

	.tqcd__hub img {
		width: auto;
		height: 34px;
	}

	.tqcd__hub-tag { font-size: 10px }

	.tqcd__nodes {
		position: static;
		inset: auto;
		display: grid;
		grid-template-columns: repeat(2, 1fr);
		gap: 9px;
	}

	.tqcd__node {
		position: static;
		transform: none;
		width: auto;
		height: 66px;
		padding: 12px 14px;
		transition: border-color .22s var(--tqcd-ease), box-shadow .22s var(--tqcd-ease);
	}

	.tqcd__node[data-on] { box-shadow: 0 0 0 3px var(--tqcd-tint) }
}

@media (max-width: 560px) {
	.tqcd__nodes { gap: 8px }

	.tqcd__node {
		height: 58px;
		padding: 10px 12px;
	}

	.tqcd__acts .tqcd__btn {
		width: 100%;
		justify-content: center;
	}
}

@media (prefers-reduced-motion: reduce) {
	.tqcd__beam::after { animation: none; opacity: 0 }
	.tqcd__node { transition: border-color .22s linear, box-shadow .22s linear }
	.tqcd__panel.is-swapping { animation: none }
}
