/* qwu.ke/paxos: basic Paxos visualizer.
   Rides on the site's styles.css (fonts, dither sky, header) and only
   styles things inside .paxos. Colors are read by paxos.js too. */

.paxos {
	--px-text: #D6D6D6;
	--px-dim: #8A8FA8;
	--px-faint: #37477E;
	--px-cool: #5E72BE;
	--px-bright: #C6D0EE;
	--px-warn: #E8A15A;
	--px-line: rgba(125, 125, 125, 0.45);
	--px-panel: rgba(2, 5, 13, 0.66);
	--px-moon: #F2D184;
	--px-star: #8DB4FF;
	--px-prepare: #A78BFA;
	--px-promise: #C4B5FD;
	--px-accept: #5EEAD4;
	--px-accepted: #A7F3E4;
	--px-nack: #FB7185;
	--px-decide: #F4F1FF;
	--px-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

	width: min(1080px, calc(100vw - 2em - 20px));
	margin: 0 auto 4rem;
	text-align: left;
	font-family: OtherFont, sans-serif;
	color: var(--px-text);
}

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

/* main article p is 1.5rem on the rest of the site; reset it in here. */
.paxos p {
	font-size: 1rem;
	font-weight: normal;
	line-height: 1.5;
	margin: 0 0 0.75em;
}

.paxos .px-lede {
	max-width: 44em;
	margin: 0.4rem auto 1.6rem;
	text-align: center;
	font-size: 1.15rem;
	color: #BFC4D8;
}

.paxos .v { font-weight: inherit; }
.paxos .v-moon { color: var(--px-moon); }
.paxos .v-star { color: var(--px-star); }
.paxos .dim { color: var(--px-dim); }
.paxos .bad { color: var(--px-nack); }

.paxos code,
.paxos kbd {
	font-family: var(--px-mono);
	font-size: 0.85em;
	color: var(--px-bright);
}

.paxos kbd {
	padding: 0 0.35em;
	border: 1px solid var(--px-line);
	border-bottom-width: 2px;
}

.paxos a {
	color: var(--px-bright);
	text-decoration: none;
	border-bottom: 1px solid rgba(198, 208, 238, 0.4);
}

.paxos a:hover {
	color: #FFFFFF;
	border-bottom-color: currentColor;
}

/* ---------- buttons ---------- */

.px-btn {
	font-family: HeaderFont, sans-serif;
	font-size: 0.95rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	line-height: 1;
	color: #C6C6C6;
	background: rgba(2, 5, 13, 0.55);
	border: 1px solid var(--px-line);
	border-radius: 0;
	padding: 0.55em 0.85em 0.45em;
	cursor: pointer;
	transition: color 0.15s, border-color 0.15s, background-color 0.15s, box-shadow 0.15s;
}

.px-btn:hover {
	color: #FFFFFF;
	border-color: var(--px-bright);
}

.px-btn:focus-visible,
.px-range input:focus-visible,
.px-switch input:focus-visible + .px-switch-box {
	outline: 2px dashed var(--px-bright);
	outline-offset: 2px;
}

.px-btn[aria-pressed="true"] {
	color: #FFFFFF;
	border-color: var(--px-bright);
	background: rgba(198, 208, 238, 0.09);
	box-shadow: inset 0 -2px 0 var(--px-bright);
}

.px-btn--main {
	min-width: 6.2em;
	color: #FFFFFF;
	border-color: var(--px-bright);
}

.px-btn--quiet {
	color: var(--px-dim);
}

.px-btn .v {
	text-transform: none;
	letter-spacing: 0;
}

/* ---------- layout: scenario rail + stage ---------- */

.px-layout {
	display: grid;
	grid-template-columns: 250px minmax(0, 1fr);
	gap: 16px;
	align-items: start;
}

.px-side {
	display: flex;
	flex-direction: column;
	gap: 16px;
	min-width: 0;
}

.px-main {
	min-width: 0;
}

.px-sc-list {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.px-sc {
	display: flex;
	align-items: baseline;
	width: 100%;
	text-align: left;
	text-transform: none;
	letter-spacing: 0.02em;
	font-size: 1rem;
	line-height: 1.15;
}

.px-num {
	flex: none;
	font-family: var(--px-mono);
	font-size: 0.72em;
	color: var(--px-cool);
	margin-right: 0.6em;
}

.px-sc[aria-pressed="true"] .px-num {
	color: var(--px-bright);
}

/* ---------- stage ---------- */

.px-stage {
	position: relative;
	border: 1px solid var(--px-line);
	background: var(--px-panel);
}

/* HUD corner brackets */
.px-stage::before {
	content: "";
	position: absolute;
	inset: -3px;
	pointer-events: none;
	--k: var(--px-bright);
	background:
		linear-gradient(var(--k), var(--k)) top left / 12px 2px no-repeat,
		linear-gradient(var(--k), var(--k)) top left / 2px 12px no-repeat,
		linear-gradient(var(--k), var(--k)) top right / 12px 2px no-repeat,
		linear-gradient(var(--k), var(--k)) top right / 2px 12px no-repeat,
		linear-gradient(var(--k), var(--k)) bottom left / 12px 2px no-repeat,
		linear-gradient(var(--k), var(--k)) bottom left / 2px 12px no-repeat,
		linear-gradient(var(--k), var(--k)) bottom right / 12px 2px no-repeat,
		linear-gradient(var(--k), var(--k)) bottom right / 2px 12px no-repeat;
}

.px-status {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	gap: 6px 18px;
	padding: 10px 14px;
	border-bottom: 1px dashed var(--px-line);
	font-family: var(--px-mono);
	font-size: 12.5px;
	color: var(--px-text);
}

.px-state {
	display: inline-block;
	min-width: 6.5em;
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--px-dim);
}

.px-state::before {
	content: "";
	display: inline-block;
	width: 6px;
	height: 6px;
	margin-right: 7px;
	vertical-align: 1px;
	background: var(--px-dim);
}

.px-state[data-state="running"] { color: var(--px-accept); }
.px-state[data-state="running"]::before { background: var(--px-accept); animation: px-blink 1s steps(2, jump-none) infinite; }
.px-state[data-state="finished"] { color: var(--px-moon); }
.px-state[data-state="finished"]::before { background: var(--px-moon); }

@keyframes px-blink { 50% { opacity: 0.2; } }

.px-chip {
	display: inline-block;
	padding: 0 6px;
	border: 1px solid currentColor;
	line-height: 1.35;
}

.px-chip.v-moon { background: rgba(242, 209, 132, 0.12); }
.px-chip.v-star { background: rgba(141, 180, 255, 0.12); }

#px-canvas {
	display: block;
	width: 100%;
	touch-action: manipulation;
}

/* ---------- legend ---------- */

.px-legend {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 6px 14px;
	margin: 0;
	padding: 9px 12px;
	list-style: none;
	border-top: 1px dashed var(--px-line);
	font-family: var(--px-mono);
	font-size: 11.5px;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--px-dim);
}

.px-legend li {
	display: flex;
	align-items: center;
	gap: 8px;
}

.px-legend li.sep {
	padding-left: 14px;
	border-left: 1px solid var(--px-line);
}

.px-legend .v { text-transform: none; }

/* message glyphs, same pixel shapes as the canvas: solid = request, hollow = reply */
.g {
	position: relative;
	display: inline-block;
	width: 6px;
	height: 6px;
	margin-left: 14px;
	flex: none;
}

.g-req {
	background: var(--c);
	box-shadow: -5px 0 0 -1px color-mix(in srgb, var(--c) 45%, transparent),
		-9px 0 0 -1px color-mix(in srgb, var(--c) 25%, transparent),
		-13px 0 0 -1px color-mix(in srgb, var(--c) 12%, transparent);
}

.g-rep {
	border: 2px solid var(--c);
	box-shadow: -5px 0 0 -1px color-mix(in srgb, var(--c) 45%, transparent),
		-9px 0 0 -1px color-mix(in srgb, var(--c) 25%, transparent),
		-13px 0 0 -1px color-mix(in srgb, var(--c) 12%, transparent);
}

.g-val {
	width: 10px;
	height: 10px;
	margin-left: 0;
	background-color: var(--c);
	-webkit-mask: repeating-conic-gradient(#000 0 25%, transparent 0 50%) 0 0 / 4px 4px;
	mask: repeating-conic-gradient(#000 0 25%, transparent 0 50%) 0 0 / 4px 4px;
	outline: 1px solid var(--c);
}

/* ---------- console ---------- */

.px-console {
	padding: 12px 14px 14px;
	border-top: 1px solid var(--px-line);
	background: rgba(2, 5, 13, 0.35);
}

.px-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px 22px;
}

.px-row + .px-row {
	margin-top: 10px;
	padding-top: 10px;
	border-top: 1px dashed var(--px-line);
}

.px-group {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
}

.px-push {
	margin-left: auto;
}

.px-hint-touch { display: none; }

@media (hover: none) {
	.px-hint-mouse { display: none; }
	.px-hint-touch { display: inline; }
}

.px-label {
	font-family: HeaderFont, sans-serif;
	font-size: 0.85rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--px-dim);
	margin-right: 4px;
}

.px-node {
	min-width: 2.9em;
	padding-left: 0.6em;
	padding-right: 0.6em;
}

.px-node[aria-pressed="true"] {
	color: var(--px-nack);
	border-color: var(--px-nack);
	background: rgba(251, 113, 133, 0.1);
	box-shadow: inset 0 -2px 0 var(--px-nack);
	text-decoration: line-through;
}

.px-range {
	display: flex;
	align-items: center;
	gap: 9px;
	font-family: HeaderFont, sans-serif;
	font-size: 0.85rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--px-dim);
}

.px-range output {
	min-width: 3.2em;
	font-family: var(--px-mono);
	font-size: 12px;
	letter-spacing: 0;
	text-transform: none;
	color: var(--px-text);
}

.px-range input[type="range"] {
	-webkit-appearance: none;
	appearance: none;
	width: 96px;
	height: 18px;
	margin: 0;
	background: transparent;
	cursor: pointer;
}

.px-range input[type="range"]::-webkit-slider-runnable-track {
	height: 2px;
	background: repeating-linear-gradient(90deg, var(--px-cool) 0 2px, transparent 2px 4px);
}

.px-range input[type="range"]::-moz-range-track {
	height: 2px;
	background: repeating-linear-gradient(90deg, var(--px-cool) 0 2px, transparent 2px 4px);
}

.px-range input[type="range"]::-webkit-slider-thumb {
	-webkit-appearance: none;
	appearance: none;
	width: 10px;
	height: 10px;
	margin-top: -4px;
	border: 0;
	border-radius: 0;
	background: var(--px-bright);
	box-shadow: 0 0 0 2px #02050D;
}

.px-range input[type="range"]::-moz-range-thumb {
	width: 10px;
	height: 10px;
	border: 0;
	border-radius: 0;
	background: var(--px-bright);
	box-shadow: 0 0 0 2px #02050D;
}

.px-switch {
	display: flex;
	align-items: center;
	gap: 9px;
	font-family: HeaderFont, sans-serif;
	font-size: 0.85rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--px-dim);
	cursor: pointer;
}

.px-switch input {
	position: absolute;
	opacity: 0;
	width: 1px;
	height: 1px;
}

.px-switch-box {
	position: relative;
	width: 28px;
	height: 14px;
	border: 1px solid var(--px-line);
	background: rgba(2, 5, 13, 0.6);
}

.px-switch-box::after {
	content: "";
	position: absolute;
	top: 2px;
	left: 2px;
	width: 8px;
	height: 8px;
	background: var(--px-dim);
	transition: transform 0.12s steps(3, end), background-color 0.12s;
}

.px-switch input:checked + .px-switch-box {
	border-color: var(--px-accept);
}

.px-switch input:checked + .px-switch-box::after {
	transform: translateX(14px);
	background: var(--px-accept);
}

.px-switch input:checked ~ span:last-child { color: var(--px-text); }

.px-switch.px-attn { color: var(--px-warn); }
.px-switch.px-attn .px-switch-box { border-color: var(--px-warn); animation: px-attn 0.9s steps(2, jump-none) infinite; }

@keyframes px-attn { 50% { box-shadow: 0 0 0 3px rgba(232, 161, 90, 0.35); } }

.paxos .px-hint {
	margin: 10px 2px 0;
	font-size: 0.85rem;
	color: var(--px-dim);
	text-align: center;
}

/* ---------- panels ---------- */

.px-logpanel {
	margin-top: 16px;
}

.px-panel {
	border: 1px solid var(--px-line);
	background: var(--px-panel);
	padding: 16px 18px 14px;
}

.px-panel h2 {
	margin: 0 0 12px;
	font-family: HeaderFont, sans-serif;
	font-weight: normal;
	font-size: 0.9rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--px-dim);
}

.px-panel h3 {
	margin: 0 0 6px;
	font-family: HeaderFont, sans-serif;
	font-weight: normal;
	font-size: 1.35rem;
	letter-spacing: 0.03em;
	color: #FFFFFF;
}

.px-watch {
	margin: 0 0 12px;
	padding: 0;
	list-style: none;
}

.px-watch li {
	position: relative;
	padding-left: 16px;
	margin-bottom: 8px;
	font-size: 0.92rem;
	line-height: 1.45;
	color: #C9CDDD;
}

.paxos .px-story p {
	font-size: 0.95rem;
}

.px-watch li::before {
	content: "";
	position: absolute;
	left: 2px;
	top: 0.55em;
	width: 6px;
	height: 6px;
	background: var(--px-cool);
}

.paxos .px-verdict {
	margin: 14px 0 0;
	padding: 10px 12px;
	border-left: 2px solid var(--px-bright);
	background: rgba(198, 208, 238, 0.06);
	font-size: 0.98rem;
}

.px-log {
	margin: 0;
	padding: 0 4px 0 0;
	list-style: none;
	height: 300px;
	overflow-y: auto;
	font-family: var(--px-mono);
	font-size: 12px;
	line-height: 1.5;
	scrollbar-width: thin;
	scrollbar-color: var(--px-faint) transparent;
}

.px-log li {
	display: grid;
	grid-template-columns: 3.4em minmax(0, 1fr);
	gap: 8px;
	padding: 3px 0 3px 8px;
	border-left: 2px solid transparent;
	color: #BFC4D8;
}

.px-log .t {
	color: var(--px-faint);
	text-align: right;
}

.px-log b { font-weight: normal; }
.px-log .nd { color: #FFFFFF; }
.px-log .bal { color: var(--px-bright); }
.px-log em { font-style: normal; color: #FFFFFF; }

.px-log .k-prepare { border-left-color: var(--px-prepare); }
.px-log .k-promise { border-left-color: var(--px-promise); }
.px-log .k-quorum { border-left-color: var(--px-bright); color: var(--px-text); }
.px-log .k-acceptmsg,
.px-log .k-accept { border-left-color: var(--px-accept); }
.px-log .k-learn { border-left-color: var(--px-decide); color: var(--px-text); }
.px-log .k-nack,
.px-log .k-preempt,
.px-log .k-crash,
.px-log .k-bad { border-left-color: var(--px-nack); }
.px-log .k-timeout,
.px-log .k-warn { border-left-color: var(--px-warn); }
.px-log .k-recover { border-left-color: var(--px-accept); }
.px-log .k-drop,
.px-log .k-info { color: var(--px-dim); }
.px-log .k-scenario { color: var(--px-bright); border-left-color: var(--px-cool); }
.px-log .k-chosen {
	border-left-color: var(--px-moon);
	background: rgba(242, 209, 132, 0.07);
	color: #FFFFFF;
}

/* ---------- rules ---------- */

.px-rules {
	margin-top: 16px;
}

.px-steps {
	display: grid;
	grid-template-columns: repeat(5, minmax(0, 1fr));
	gap: 14px;
	margin: 0 0 16px;
	padding: 0;
	list-style: none;
}

.px-steps li {
	padding-top: 10px;
	border-top: 2px solid var(--c, var(--px-line));
}

.px-tag {
	display: inline-block;
	margin-bottom: 6px;
	font-family: var(--px-mono);
	font-size: 11.5px;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--c);
}

.paxos .px-steps p {
	font-size: 0.92rem;
	line-height: 1.45;
	color: #C9CDDD;
	margin: 0;
}

.paxos .px-why,
.paxos .px-aside {
	font-size: 0.95rem;
	color: #C9CDDD;
}

.paxos .px-aside {
	margin-bottom: 0;
	padding-top: 12px;
	border-top: 1px dashed var(--px-line);
	color: var(--px-dim);
}

.paxos .px-why b,
.paxos .px-aside b {
	color: var(--px-text);
}

/* ---------- small screens ---------- */

@media (max-width: 1000px) {
	.px-layout { display: flex; flex-direction: column; }
	.px-side { display: contents; }
	.px-scenarios { order: 1; width: 100%; }
	.px-main { order: 2; width: 100%; }
	.px-story { order: 3; width: 100%; }
	.px-sc-list { flex-direction: row; flex-wrap: wrap; }
	.px-sc { width: auto; }
	.px-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 600px) {
	.paxos .px-lede { font-size: 1rem; }
	.px-status { font-size: 11.5px; padding: 8px 10px; }
	.px-legend { gap: 6px 14px; padding: 8px 10px; }
	.px-legend li.sep { padding-left: 0; border-left: 0; }
	.px-push { margin-left: 0; }
	.px-console { padding: 10px; }
	.px-row { gap: 10px 16px; }
	.px-range input[type="range"] { width: 84px; }
	.px-steps { grid-template-columns: minmax(0, 1fr); }
	.px-log { height: 260px; }
	.px-sc { font-size: 0.9rem; padding: 0.5em 0.65em 0.4em; }
}

@media (prefers-reduced-motion: reduce) {
	.px-state[data-state="running"]::before { animation: none; }
	.px-switch-box::after { transition: none; }
	.px-switch.px-attn .px-switch-box { animation: none; }
}
