:root {
	/* =========================================================
	   CONTROL PANEL
	   All geometry is expressed in multiples of one master module.
	   Change values here; the rest of the CSS and JS derive from them.
	   ========================================================= */

	--module: 25px;
	--text-scale: 0.75;

	/* Type families and shared optical weights */
	--font-en: sans-serif;
	--font-ja: "Yu Mincho", serif;
	--font-ja-strong: "Yu Mincho Demibold", "Yu Mincho", serif;

	/* Optical weight matching */
	--weight-strong-en: 700;
	--weight-strong-ja: 700;
	--weight-light-en: 300;
	--weight-light-ja: 500;

	/* Extra optical thickness for Japanese strong text only */
	--ja-strong-stroke: 0.65px;

	--page-inset-m: 2;
	--cluster-gap-m: 1;
	--pair-gap-m: 1;
	--interlock-gap-m: 2;
	--zone-gap-m: 2;

	--shape-edge-m: 2;
	--territory-offset-m: 2;
	--shape-band-m: 1;

	/* Super-ball
	   Radius and physical quantities derive from the master module. */
	--ball-radius-m: 0.5;
	--ball-launch-speed-mps: 4.8;
	--ball-gravity-mps2: 10;
	--ball-bounce: 0.96;
	--ball-min-bounce-mps: 2.1;
	--ball-squash: 0.14;

	/* Natural energy loss / eventual rest */
	--ball-drag-per-s: 0.055;
	--ball-rest-speed-mps: 0.22;

	/* Grab / throw */
	--ball-grab-radius-m: 0.9;
	--ball-throw-scale: 1;
	--ball-max-throw-mps: 48;
	--ball-release-deadzone-mps: 0.35;

	/* Derived lengths */
	--text-size: calc(var(--module) * var(--text-scale));
	--page-inset: calc(var(--module) * var(--page-inset-m));
	--cluster-gap: calc(var(--module) * var(--cluster-gap-m));
	--pair-gap: calc(var(--module) * var(--pair-gap-m));
	--interlock-gap: calc(var(--module) * var(--interlock-gap-m));
	--zone-gap: calc(var(--module) * var(--zone-gap-m));

	/* Live colors; JS replaces these once per second */
	--background-color: #ffffff;
	--text-color: #000000;
	--shape-color: #808080;
}

/* ---------- Base ---------- */

* {
	box-sizing: border-box;
}

html,
body {
	margin: 0;
	width: 100%;
	min-height: 100%;
}

body {
	position: relative;
	color: var(--text-color);
	background: var(--background-color);
}

/* ---------- Generated shape ---------- */

.free-shape-layer {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 0;
	display: block;
	pointer-events: none;
	overflow: hidden;
}

/* ---------- Page ---------- */

.page {
	position: relative;
	z-index: 1;
	width: 100%;
	min-height: 100svh;
	padding: var(--page-inset);

	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: var(--zone-gap);
}

.zone {
	width: 100%;
	display: flex;
	flex-flow: row nowrap;
	justify-content: space-between;
	align-items: flex-start;
	gap: var(--pair-gap);
}

.top-zone {
	align-self: flex-start;
}

.bottom-zone {
	align-self: flex-end;
}

.top-left,
.top-right,
.bottom-left,
.bottom-right {
	width: max-content;
	max-width: 100%;
	min-width: min-content;
	flex: 0 1 auto;
}

.top-left,
.bottom-left {
	text-align: left;
}

.top-right,
.bottom-right {
	text-align: right;
}

.bottom-zone:not(.stacked) .bottom-left,
.bottom-zone:not(.stacked) .bottom-right {
	align-self: flex-end;
}

.top-zone.stacked,
.bottom-zone.stacked {
	flex-direction: column;
	justify-content: flex-start;
	gap: var(--interlock-gap);
}

.top-zone.stacked .top-left,
.bottom-zone.stacked .bottom-left {
	align-self: flex-start;
}

.top-zone.stacked .top-right,
.bottom-zone.stacked .bottom-right {
	align-self: flex-end;
}

/* ---------- Semantic wrapping ---------- */

.atom {
	white-space: nowrap;
}

/* ---------- Internal information gaps ---------- */

.top-right .cluster + .cluster,
.bottom-left .cluster {
	margin-top: var(--cluster-gap);
}

/* ---------- Type ---------- */

.type1E,
.type1J,
.type2E,
.type2J,
a {
	font-size: var(--text-size);
	line-height: var(--module);
}

.type1E {
	font-family: var(--font-en);
	font-weight: var(--weight-strong-en);
}

.type1J {
	font-family: var(--font-ja);
	font-weight: var(--weight-strong-ja);

	-webkit-text-stroke:
		var(--ja-strong-stroke)
		currentColor;

	paint-order: stroke fill;
}

.type2E,
a {
	font-family: var(--font-en);
	font-weight: var(--weight-light-en);
}

.type2J {
	font-family: var(--font-ja);
	font-weight: var(--weight-light-ja);
}

/* ---------- Links ---------- */

a,
a:visited {
	display: block;
	color: inherit;
}


/* ---------- Super-ball ---------- */

.ball {
	pointer-events: none;
	fill: var(--background-color);
	stroke: none;
}



/* ---------- Ball interaction target ---------- */

/*
   A normal HTML element owns the touch gesture.
   This is intentionally separate from the decorative SVG.
*/
.ball-hit {
	position: absolute;
	z-index: 3;

	width: 1px;
	height: 1px;
	border-radius: 50%;

	background: transparent;

	pointer-events: auto;
	touch-action: none;

	user-select: none;
	-webkit-user-select: none;
	-webkit-touch-callout: none;

	cursor: grab;
}

.ball-hit:active {
	cursor: grabbing;
}
