/* Rings Menu ---------------------------------------------------------------
 * A taijitu you turn. The field is split down the middle, paper on the left
 * and ink on the right, and the type is knocked out of it by difference
 * blending — so a label crossing the seam splits mid-letter. The selected
 * item sits on the seam and is always half of each.
 * ------------------------------------------------------------------------ */

.tkr {
	--tkr-ink: #0a0a0a;
	--tkr-paper: #ffffff;
	--tkr-fg: var(--tkr-paper);

	--tkr-font: "Helvetica Neue", Helvetica, Inter, "Segoe UI", Roboto, Arial, sans-serif;

	--tkr-dur: 520ms;
	--tkr-ease: cubic-bezier(.16, 1.02, .3, 1);
	--tkr-btn: 62px;
	--tkr-inset: 22px;
	--tkr-z: 99990;

	--tkr-field: 380px;
	--tkr-a: 0deg;
}

.tkr *,
.tkr *::before,
.tkr *::after {
	box-sizing: border-box;
}

.tkr.is-hidden {
	display: none;
}

/* Field -------------------------------------------------------------------
 * The background lives on the stage, not on a separate scrim, so the type
 * inside can blend against it.
 * ---------------------------------------------------------------------- */

.tkr-stage {
	position: fixed;
	inset: 0;
	z-index: calc(var(--tkr-z) - 1);
	overflow: hidden;
	opacity: 0;
	pointer-events: none;
	transition: opacity var(--tkr-dur) ease;
	background: var(--tkr-ink);
}

.tkr[data-tkr-field="split"] .tkr-stage {
	background: linear-gradient(to right, var(--tkr-paper) 0 50%, var(--tkr-ink) 50% 100%);
}

.tkr[data-tkr-field="paper"] .tkr-stage {
	background: var(--tkr-paper);
	--tkr-fg: var(--tkr-ink);
}

.tkr.is-open .tkr-stage {
	opacity: 1;
	pointer-events: auto;
}

.tkr-stage[hidden] {
	display: none;
}

/* Dial --------------------------------------------------------------------
 * The taijitu is the knob. Labels ride a ring around it and stay upright.
 * The one at the mark is selected.
 * ---------------------------------------------------------------------- */

.tkr-dial {
	position: absolute;
	left: 50%;
	top: 50%;
	width: var(--tkr-field);
	height: var(--tkr-field);
	margin: calc(var(--tkr-field) / -2) 0 0 calc(var(--tkr-field) / -2);
	transform: scale(.78);
	transition: transform var(--tkr-dur) var(--tkr-ease);
	touch-action: none;
}

.tkr.is-open .tkr-dial {
	transform: scale(1);
}

/* The mark at twelve o'clock, sitting on the seam. */
.tkr-dial__mark {
	position: absolute;
	left: 50%;
	top: calc(50% - var(--tkr-field) * .458);
	width: 1px;
	height: calc(var(--tkr-field) * .052);
	margin-left: -.5px;
	background: var(--tkr-paper);
	mix-blend-mode: difference;
	opacity: .7;
}

/*
 * The hub runs counter to the field: ink on the left, paper on the right,
 * where the field is the reverse. A small inversion at the centre of a
 * large one.
 */
.tkr-hub {
	position: absolute;
	left: 50%;
	top: 50%;
	width: calc(var(--tkr-field) * .34);
	height: calc(var(--tkr-field) * .34);
	margin: calc(var(--tkr-field) * -.17) 0 0 calc(var(--tkr-field) * -.17);
	transform: rotate(calc(var(--tkr-a) + 180deg));
	cursor: grab;
}

.tkr-dial.is-dragging .tkr-hub {
	cursor: grabbing;
}

.tkr-hub svg {
	width: 100%;
	height: 100%;
	display: block;
}

.tkr-ring-track {
	position: absolute;
	inset: 0;
}

.tkr-spoke {
	position: absolute;
	left: 50%;
	top: 50%;
	width: 0;
	height: 0;
	transform: rotate(calc(var(--th) + var(--tkr-a)))
		translateY(calc(var(--tkr-field) * -.335));
}

.tkr-dial__label {
	position: absolute;
	left: 50%;
	top: 50%;
	display: block;
	max-width: calc(var(--tkr-field) * .5);
	padding: .22em .45em;
	transform: translate(-50%, -50%) rotate(calc(-1 * (var(--th) + var(--tkr-a))));
	font-family: var(--tkr-font);
	font-size: calc(var(--tkr-field) * .054);
	font-weight: 800;
	letter-spacing: -.038em;
	line-height: 1;
	text-transform: lowercase;
	text-decoration: none;
	white-space: nowrap;
	color: var(--tkr-fg);
	opacity: .45;
	transition: font-size 260ms var(--tkr-ease), opacity 260ms ease;
}

/* Knocked out of the split field, so each label carries the opposite of
   whichever half it is standing on. */
.tkr[data-tkr-field="split"] .tkr-dial__label,
.tkr[data-tkr-field="split"] .tkr-dial__label.is-current {
	color: var(--tkr-paper);
	background: none;
	mix-blend-mode: difference;
}

.tkr-spoke.is-active .tkr-dial__label {
	font-size: calc(var(--tkr-field) * .094);
	opacity: 1;
}

.tkr-spoke.is-behind .tkr-dial__label {
	opacity: .18;
}

.tkr-dial__label:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 5px;
}

/* Current page inverts, on the plain fields where inversion still reads. */
.tkr-dial__label.is-current {
	color: var(--tkr-ink);
	background: var(--tkr-fg);
	border-radius: 999px;
}

.tkr[data-tkr-field="paper"] .tkr-dial__label.is-current {
	color: var(--tkr-paper);
	background: var(--tkr-ink);
}

/* Toggle ------------------------------------------------------------------
 * Always ink and paper, never themed: a two-tone disc carries its own
 * contrast against any page behind it, so it needs no shadow and no ring.
 * ---------------------------------------------------------------------- */

.tkr-toggle {
	position: fixed;
	z-index: var(--tkr-z);
	width: var(--tkr-btn);
	height: var(--tkr-btn);
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	cursor: pointer;
	-webkit-tap-highlight-color: transparent;
}

.tkr[data-tkr-position="bottom-center"] .tkr-toggle {
	left: 50%;
	bottom: calc(var(--tkr-inset) + env(safe-area-inset-bottom, 0px));
	transform: translateX(-50%);
}

.tkr[data-tkr-position="bottom-right"] .tkr-toggle {
	right: var(--tkr-inset);
	bottom: calc(var(--tkr-inset) + env(safe-area-inset-bottom, 0px));
}

.tkr[data-tkr-position="top-right"] .tkr-toggle {
	right: var(--tkr-inset);
	top: calc(var(--tkr-inset) + env(safe-area-inset-top, 0px));
}

.tkr-toggle:focus-visible {
	outline: 2px solid var(--tkr-ink);
	outline-offset: 4px;
}

.tkr-toggle__icon {
	position: absolute;
	inset: 0;
	display: block;
	transform: rotate(var(--tkr-turn, 0deg));
	transition: transform var(--tkr-spin-dur, 700ms) cubic-bezier(.12, .78, .18, 1);
}

.tkr-glyph {
	width: 100%;
	height: 100%;
	display: block;
}

/* Idle pulse: one thin ring, once every eight seconds, then gone. */
.tkr-toggle__pulse {
	position: absolute;
	inset: 0;
	border-radius: 50%;
	border: 1px solid var(--tkr-ink);
	opacity: 0;
	pointer-events: none;
}

.tkr[data-tkr-pulse="1"]:not(.is-open) .tkr-toggle__pulse {
	animation: tkr-pulse 8s ease-out infinite;
}

@keyframes tkr-pulse {
	0%, 78% { transform: scale(1); opacity: 0; }
	84%     { opacity: .45; }
	100%    { transform: scale(1.9); opacity: 0; }
}

/* Body lock --------------------------------------------------------------- */

html.tkr-locked,
html.tkr-locked body {
	overflow: hidden;
	overscroll-behavior: none;
}

/* Where blending is unavailable, fall back to a single ink field so the
   type never lands white on white. */
@supports not (mix-blend-mode: difference) {
	.tkr[data-tkr-field="split"] .tkr-stage {
		background: var(--tkr-ink);
	}

	.tkr[data-tkr-field="split"] .tkr-dial__label {
		mix-blend-mode: normal;
	}
}

/* Reduced motion ---------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.tkr-dial {
		transform: scale(1);
		transition: none;
	}

	.tkr-stage {
		transition-duration: 160ms;
	}

	.tkr-dial__label,
	.tkr-toggle__icon {
		transition-duration: 120ms;
	}

	.tkr-toggle__pulse {
		animation: none !important;
	}
}
