/*
 * Dots & Boxes - web edition: online play (owner: web client; see js/online.js and ONLINE.md).
 * Screens 'online' and 'lobby', the online additions to the game / results screens, the chat panel and reactions.
 *
 * Sizes are design units (--u, set by the shell; UE Slate units) and the shell's type tokens (--fs-*), which follow
 * <html data-layout="wide|narrow">. Colors come only from the theme custom properties (DB.Themes.apply()).
 * Per-player color: --on-pc (inline). Logical properties keep RTL (Arabic) and LTR (English) right.
 * Every class is prefixed "on-".
 */

/* ====================================================================== Main menu: the Online button (menus.js) */

.mn-screen .mn-online-btn {
	border-color: color-mix(in srgb, var(--accent2) 55%, var(--panel-border));
	box-shadow:
		0 calc(4 * var(--u)) calc(12 * var(--u)) var(--shadow),
		0 0 calc(16 * var(--u)) color-mix(in srgb, var(--accent2) 22%, transparent);
}

.mn-screen .mn-online-btn .db-icon {
	color: var(--accent2);
}

/* ====================================================================== Shared pieces */

.on-screen {
	position: relative;
}

.on-content {
	display: flex;
	flex-direction: column;
	gap: calc(24 * var(--u));
}

.on-narrow .on-content {
	gap: calc(16 * var(--u));
}

.db-panel.on-panel {
	display: flex;
	flex-direction: column;
	gap: calc(14 * var(--u));
	min-width: 0;
}

.on-narrow .db-panel.on-panel {
	padding: calc(18 * var(--u));
}

.on-panel-head {
	display: flex;
	align-items: center;
	gap: calc(12 * var(--u));
	min-width: 0;
}

.on-panel-icon {
	flex: none;
	display: inline-grid;
	place-items: center;
	width: calc(44 * var(--u));
	height: calc(44 * var(--u));
	min-width: 30px;
	min-height: 30px;
	border-radius: calc(14 * var(--u));
	background: color-mix(in srgb, var(--accent) 18%, transparent);
	color: var(--accent);
}

.on-panel-icon .db-icon {
	width: 58%;
	height: 58%;
}

.on-body {
	color: var(--text-muted);
	font-size: max(13px, var(--fs-small));
	line-height: 1.45;
}

.on-field-label,
.on-label {
	display: block;
	font-weight: 700;
	font-size: max(12.5px, var(--fs-small));
	line-height: 1.3;
	color: var(--text-muted);
}

.on-spacer {
	flex: 1 1 auto;
	min-height: calc(4 * var(--u));
}

.on-muted {
	color: var(--text-muted);
	font-size: max(12.5px, var(--fs-small));
}

.on-summary {
	font-weight: 700;
	font-size: max(14px, var(--fs-body));
	line-height: 1.35;
	color: var(--text);
}

.on-screen .db-btn {
	max-width: 100%;
}

/* Connection-lost pill (lobby, game, results). */
.on-conn {
	position: absolute;
	z-index: 15;
	left: 50%;
	bottom: max(calc(18 * var(--u)), env(safe-area-inset-bottom, 0px));
	max-width: calc(100% - 32px);
	padding: calc(9 * var(--u)) calc(20 * var(--u));
	border-radius: 999px;
	border: 1.5px solid var(--warning);
	background-color: var(--bg-bottom);
	background-image: linear-gradient(var(--panel), var(--panel));
	box-shadow: 0 calc(6 * var(--u)) calc(18 * var(--u)) var(--shadow);
	color: var(--text);
	font-weight: 700;
	font-size: max(13px, var(--fs-small));
	line-height: 1.3;
	text-align: center;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	pointer-events: none;
	opacity: 0;
	transform: translate(-50%, 150%);
	transition: opacity 0.2s ease, transform 0.28s var(--ease-out);
}

.on-conn.is-on {
	opacity: 1;
	transform: translate(-50%, 0);
}

.on-conn::before {
	content: '';
	display: inline-block;
	width: 0.6em;
	height: 0.6em;
	margin-inline-end: 0.55em;
	border-radius: 50%;
	background: var(--warning);
	vertical-align: 0.05em;
	animation: on-pulse 1.1s ease-in-out infinite;
}

/* Short status messages (mute confirmation, rate limits). */
.on-notice {
	position: absolute;
	z-index: 16;
	left: 50%;
	top: calc(96 * var(--u));
	max-width: calc(100% - 32px);
	padding: calc(10 * var(--u)) calc(22 * var(--u));
	border-radius: 999px;
	border: 1.5px solid var(--panel-border);
	background-color: var(--bg-bottom);
	background-image: linear-gradient(var(--panel), var(--panel));
	box-shadow: 0 calc(8 * var(--u)) calc(22 * var(--u)) var(--shadow);
	color: var(--text);
	font-weight: 700;
	font-size: max(13px, var(--fs-small));
	line-height: 1.3;
	text-align: center;
	pointer-events: none;
	opacity: 0;
	transform: translate(-50%, calc(-12 * var(--u)));
	transition: opacity 0.2s ease, transform 0.25s var(--ease-out);
}

.on-notice.is-on {
	opacity: 1;
	transform: translate(-50%, 0);
}

@keyframes on-pulse {
	0%, 100% { opacity: 1; }
	50% { opacity: 0.35; }
}

/* ====================================================================== Screen: online */

.on-top-panel {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: calc(14 * var(--u));
}

.on-wide .on-top-panel {
	grid-template-columns: minmax(0, calc(560 * var(--u))) minmax(0, 1fr);
	align-items: end;
	column-gap: calc(28 * var(--u));
}

.on-name-row {
	display: flex;
	flex-direction: column;
	gap: calc(8 * var(--u));
	min-width: 0;
}

.on-status {
	display: flex;
	align-items: center;
	gap: calc(10 * var(--u));
	min-width: 0;
	min-height: max(40px, calc(46 * var(--u)));
	padding: calc(6 * var(--u)) calc(16 * var(--u));
	border-radius: var(--chip-r);
	background: var(--control);
	color: var(--text);
	font-weight: 700;
	font-size: max(12.5px, var(--fs-small));
	line-height: 1.35;
}

.on-status-text {
	flex: 1 1 auto;
	min-width: 0;
}

.on-status-dot {
	flex: none;
	width: max(9px, calc(12 * var(--u)));
	height: max(9px, calc(12 * var(--u)));
	border-radius: 50%;
	background: var(--text-muted);
}

.on-status[data-tone='ok'] .on-status-dot {
	background: var(--success);
	box-shadow: 0 0 calc(10 * var(--u)) var(--success);
}

.on-status[data-tone='wait'] .on-status-dot {
	background: var(--warning);
	animation: on-pulse 1.1s ease-in-out infinite;
}

.on-status[data-tone='bad'] .on-status-dot {
	background: var(--danger);
}

.on-screen .on-status-retry {
	--bh: max(34px, calc(40 * var(--u)));
	flex: none;
	min-width: 0;
	padding-inline: calc(12 * var(--u));
	font-size: max(12.5px, var(--fs-small));
}

.on-alert {
	grid-column: 1 / -1;
	display: flex;
	align-items: center;
	gap: calc(10 * var(--u));
	padding: calc(12 * var(--u)) calc(16 * var(--u));
	border-radius: var(--chip-r);
	border: 1.5px solid color-mix(in srgb, var(--danger) 55%, transparent);
	background: color-mix(in srgb, var(--danger) 14%, transparent);
	color: var(--text);
	font-weight: 700;
	font-size: max(13px, var(--fs-small));
	line-height: 1.4;
}

.on-alert .db-icon {
	flex: none;
	color: var(--danger);
}

.on-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(100%, calc(400 * var(--u))), 1fr));
	gap: calc(24 * var(--u));
	align-items: stretch;
}

.on-narrow .on-grid {
	grid-template-columns: minmax(0, 1fr);
	gap: calc(16 * var(--u));
}

.on-box {
	flex: 1 1 auto;
	display: flex;
	flex-direction: column;
	gap: calc(12 * var(--u));
	min-width: 0;
}

.on-box .db-seg {
	width: 100%;
}

.on-step-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: calc(12 * var(--u));
	min-width: 0;
}

.on-step-row .db-stepper {
	flex: none;
	width: calc(200 * var(--u));
}

.on-step-row .on-count-seg {
	flex: none;
	width: calc(200 * var(--u));
}

.on-narrow .on-step-row .db-stepper,
.on-narrow .on-step-row .on-count-seg {
	width: calc(210 * var(--u));
}

.on-name-input,
.on-code-input {
	-webkit-user-select: text;
	user-select: text;
}

.on-code-input {
	display: block;
	width: 100%;
	min-width: 0;
	height: max(52px, calc(68 * var(--u)));
	margin: 0;
	padding: 0 calc(14 * var(--u));
	border: 1.5px solid var(--panel-border);
	border-radius: var(--chip-r);
	background: var(--control);
	color: var(--text);
	font-family: ui-monospace, 'Cascadia Mono', Consolas, 'Tajawal', monospace;
	font-weight: 800;
	font-size: max(22px, calc(36 * var(--fs-k) * var(--u)));
	letter-spacing: 0.3em;
	text-indent: 0.3em;
	text-align: center;
	text-transform: uppercase;
	outline: none;
	-webkit-appearance: none;
	appearance: none;
	transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

.on-code-input::placeholder {
	color: var(--text-muted);
	opacity: 0.35;
}

.on-code-input:focus {
	border-color: var(--accent);
	box-shadow: 0 0 0 calc(3 * var(--u)) rgba(var(--accent-rgb), 0.25);
}

.on-code-input:disabled,
.on-name-input:disabled {
	opacity: 0.6;
}

.on-searching {
	align-items: center;
	text-align: center;
}

.on-searching .db-btn {
	width: 100%;
}

.on-spinner {
	flex: none;
	width: calc(56 * var(--u));
	height: calc(56 * var(--u));
	min-width: 36px;
	min-height: 36px;
	margin-top: calc(6 * var(--u));
	border-radius: 50%;
	border: max(4px, calc(5 * var(--u))) solid var(--control);
	border-top-color: var(--accent);
	border-inline-end-color: var(--accent2);
	animation: db-spin 900ms linear infinite;
}

.on-search-title {
	font-weight: 800;
	font-size: max(15px, var(--fs-body));
	line-height: 1.35;
}

.on-search-time {
	color: var(--text-muted);
	font-size: max(13px, var(--fs-small));
	font-variant-numeric: tabular-nums;
}

.on-search-note {
	color: var(--text-muted);
	font-size: max(12.5px, var(--fs-small));
	line-height: 1.4;
}

.on-offline-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: calc(8 * var(--u)) calc(14 * var(--u));
	color: var(--text-muted);
	font-size: max(12.5px, var(--fs-small));
	text-align: center;
}

.on-screen .on-offline-btn {
	--bh: max(40px, calc(48 * var(--u)));
	min-width: 0;
	font-size: max(13px, var(--fs-small));
}

.on-online.is-unavailable .on-grid {
	opacity: 0.55;
}

/* ====================================================================== Screen: lobby */

.on-header-end {
	grid-column: 3;
	grid-row: 1;
	justify-self: end;
	display: flex;
	align-items: center;
}

.on-lobby-grid {
	display: grid;
	grid-template-columns: minmax(0, calc(460 * var(--u))) minmax(0, 1fr);
	gap: calc(28 * var(--u));
	align-items: start;
}

.on-lobby-side {
	display: flex;
	flex-direction: column;
	gap: calc(20 * var(--u));
	min-width: 0;
}

.db-panel.on-code-card {
	align-items: center;
	text-align: center;
	gap: calc(10 * var(--u));
}

.on-code {
	padding-inline-start: 0.14em; /* balances the letter spacing after the last letter */
	font-family: var(--font-display);
	font-weight: 400;
	font-size: calc(76 * var(--fs-k) * var(--u));
	line-height: 1.15;
	letter-spacing: 0.14em;
	color: var(--text);
	text-shadow: 0 0 calc(24 * var(--u)) rgba(var(--accent-rgb), 0.45);
	-webkit-user-select: all;
	user-select: all;
}

.on-narrow .on-code {
	font-size: calc(58 * var(--fs-k) * var(--u));
}

.on-code-actions {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: calc(12 * var(--u));
}

.on-screen .on-copy-btn,
.on-screen .on-share-btn {
	--bh: max(42px, calc(52 * var(--u)));
	min-width: calc(150 * var(--u));
	font-size: max(14px, var(--fs-body));
}

.on-seats {
	display: flex;
	flex-direction: column;
	gap: calc(12 * var(--u));
}

.on-seat {
	--on-pc: var(--accent);
	display: grid;
	grid-template-columns: auto minmax(0, 1fr) auto;
	align-items: center;
	column-gap: calc(14 * var(--u));
	row-gap: calc(10 * var(--u));
	padding: calc(12 * var(--u)) calc(14 * var(--u));
	border-radius: calc(18 * var(--u));
	border: 1.5px solid transparent;
	border-inline-start: max(3px, calc(4 * var(--u))) solid var(--on-pc);
	background: var(--control);
}

.on-seat.is-me {
	border-color: color-mix(in srgb, var(--on-pc) 55%, transparent);
	border-inline-start-color: var(--on-pc);
	background: color-mix(in srgb, var(--on-pc) 10%, var(--control));
}

.on-seat.is-open {
	border-inline-start-style: dashed;
	border-inline-start-color: var(--text-muted);
}

.on-seat-av {
	position: relative;
	flex: none;
	display: grid;
	place-items: center;
	width: calc(52 * var(--u));
	height: calc(52 * var(--u));
	min-width: 36px;
	min-height: 36px;
	border-radius: 50%;
	background: var(--on-pc);
	color: #FFFFFF;
	box-shadow: 0 0 calc(18 * var(--u)) color-mix(in srgb, var(--on-pc) 40%, transparent);
}

.on-seat.is-open .on-seat-av {
	background: transparent;
	border: 2px dashed var(--text-muted);
	color: var(--text-muted);
	box-shadow: none;
}

.on-seat-av > .db-icon {
	width: 55%;
	height: 55%;
}

.on-seat-initial {
	font-weight: 800;
	font-size: max(15px, calc(23 * var(--fs-k) * var(--u)));
	line-height: 1;
	transform: translateY(0.06em);
}

.on-dot {
	position: absolute;
	bottom: -1px;
	inset-inline-end: -1px;
	width: max(11px, calc(16 * var(--u)));
	height: max(11px, calc(16 * var(--u)));
	border-radius: 50%;
	border: max(2px, calc(3 * var(--u))) solid var(--control);
	background: var(--success);
}

.on-dot.is-off {
	background: var(--text-muted);
}

.on-dot.is-away {
	background: var(--warning);
}

.on-seat-text {
	min-width: 0;
}

.on-seat-name {
	display: flex;
	align-items: center;
	gap: calc(8 * var(--u));
	min-width: 0;
	font-weight: 800;
	font-size: max(15px, var(--fs-body));
	line-height: 1.3;
}

.on-seat.is-open .on-seat-name {
	color: var(--text-muted);
	font-weight: 700;
}

.on-seat-name-text {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.on-crown {
	flex: none;
	display: inline-flex;
	color: #E9B530;
	filter: drop-shadow(0 0 calc(6 * var(--u)) rgba(233, 181, 48, 0.55));
}

.on-crown .db-icon {
	width: max(15px, calc(20 * var(--u)));
	height: max(15px, calc(20 * var(--u)));
}

.on-tag {
	flex: none;
	padding: calc(2 * var(--u)) calc(10 * var(--u));
	border-radius: 999px;
	background: color-mix(in srgb, var(--accent) 22%, transparent);
	color: var(--text);
	font-size: max(11px, calc(var(--fs-small) * 0.85));
	font-weight: 800;
	line-height: 1.4;
}

.on-seat-sub {
	display: flex;
	align-items: center;
	gap: calc(6 * var(--u));
	min-width: 0;
	color: var(--text-muted);
	font-size: max(12.5px, var(--fs-small));
	line-height: 1.35;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

.on-seat-sub > span:last-child {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
}

.on-seat-plat {
	flex: none;
	display: inline-flex;
}

.on-seat-plat .db-icon {
	width: max(13px, calc(16 * var(--u)));
	height: max(13px, calc(16 * var(--u)));
}

.on-screen .on-seat-mute {
	--bh: max(38px, calc(46 * var(--u)));
}

.on-seat-mute.is-muted {
	color: var(--danger);
}

.on-seat-host {
	grid-column: 1 / -1;
	display: flex;
	flex-wrap: wrap;
	gap: calc(10 * var(--u));
}

.on-kind-seg {
	flex: 1 1 calc(200 * var(--u));
	height: calc(44 * var(--u));
	min-height: 36px;
}

.on-diff-seg {
	flex: 2 1 calc(300 * var(--u));
	/* Too narrow for all four levels (e.g. the side chat is open): wrap under the open/bot switch, never truncate. */
	min-width: min(100%, calc(340 * var(--u)));
	height: calc(44 * var(--u));
	min-height: 36px;
	--fs-seg: max(11.5px, calc(17 * var(--fs-k) * var(--u)));
}

.on-colors {
	display: grid;
	grid-template-columns: repeat(8, minmax(0, 1fr));
	justify-items: center;
	align-items: center;
}

.on-start-area {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: calc(10 * var(--u));
}

.on-wide .on-start-btn {
	--bh: calc(72 * var(--u));
	font-size: calc(var(--fs-button) + 2 * var(--fs-k) * var(--u));
}

.on-start-note {
	text-align: center;
	color: var(--text-muted);
	font-size: max(12.5px, var(--fs-small));
}

.on-wait {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: calc(12 * var(--u));
	min-height: var(--btn-h);
	padding: calc(10 * var(--u)) calc(18 * var(--u));
	border-radius: var(--btn-r);
	background: var(--control);
	color: var(--text-muted);
	font-weight: 700;
	font-size: max(13px, var(--fs-small));
	text-align: center;
}

.on-wait-dots {
	display: inline-flex;
	gap: calc(5 * var(--u));
}

.on-wait-dots i {
	display: block;
	width: max(6px, calc(8 * var(--u)));
	height: max(6px, calc(8 * var(--u)));
	border-radius: 50%;
	background: var(--accent);
	animation: on-bounce 0.9s ease-in-out infinite;
}

.on-wait-dots i:nth-child(2) {
	animation-delay: 0.12s;
}

.on-wait-dots i:nth-child(3) {
	animation-delay: 0.24s;
}

@keyframes on-bounce {
	0%, 60%, 100% { transform: translateY(30%); opacity: 0.45; }
	30% { transform: translateY(-40%); opacity: 1; }
}

.on-screen .on-leave-btn {
	color: var(--text-muted);
}

.on-pinned {
	flex-direction: column;
	align-items: center;
}

/* ====================================================================== Online game additions */

/* Room for the chat button in the phone top bar: the theme button stays in Settings. */
.on-game.dbg-narrow .dbg-theme-btn {
	display: none;
}

.on-avwrap {
	position: relative;
	flex: none;
	display: inline-grid;
	place-items: center;
}

.on-ring {
	position: absolute;
	left: calc(-5 * var(--g-u));
	top: calc(-5 * var(--g-u));
	width: calc(100% + 10 * var(--g-u));
	height: calc(100% + 10 * var(--g-u));
	overflow: visible;
	transform: rotate(-90deg);
	opacity: 0;
	transition: opacity 0.2s ease;
	pointer-events: none;
}

.dbg-banner.on-timed .on-ring {
	opacity: 1;
}

.on-ring-track,
.on-ring-arc {
	fill: none;
	stroke-width: 3.4;
}

.on-ring-track {
	stroke: rgba(var(--g-pc-rgb, 140, 109, 255), 0.2);
}

.on-ring-arc {
	stroke: rgb(var(--g-pc-rgb, 140, 109, 255));
	stroke-linecap: round;
	transition: stroke-dashoffset 0.25s linear, stroke 0.2s ease;
}

.dbg-banner.on-clock-low .on-ring-arc {
	stroke: var(--danger);
}

.on-clock-text {
	flex: none;
	margin-inline-start: calc(4 * var(--g-u));
	min-width: 2.2em;
	color: var(--text-muted);
	font-weight: 800;
	font-size: calc(18 * var(--g-f));
	line-height: 1;
	font-variant-numeric: tabular-nums;
	text-align: end;
	white-space: nowrap;
}

.dbg-narrow .on-clock-text {
	font-size: calc(15 * var(--g-f));
}

.dbg-banner:not(.on-timed) .on-clock-text {
	display: none;
}

.dbg-banner.on-clock-low .on-clock-text {
	color: var(--danger);
	animation: on-pulse 1s ease-in-out infinite;
}

.dbg-banner.on-banner-mine {
	box-shadow:
		0 0 calc(26 * var(--g-u)) rgba(var(--g-pc-rgb), 0.5),
		0 0 calc(8 * var(--g-u)) rgba(var(--g-pc-rgb), 0.3);
}

.dbg-hint.on-hint-mine {
	color: var(--text);
	font-weight: 800;
}

.on-card-dot {
	position: absolute;
	bottom: -1px;
	inset-inline-end: -1px;
	width: max(9px, calc(14 * var(--g-u)));
	height: max(9px, calc(14 * var(--g-u)));
	border-radius: 50%;
	background: var(--success);
	box-shadow: 0 0 0 max(2px, calc(2.5 * var(--g-u))) var(--bg-bottom);
}

.on-card-dot.is-off {
	background: var(--text-muted);
}

.on-card-dot.is-away {
	background: var(--warning);
}

.on-card-dot.is-hidden {
	display: none;
}

.on-card-flags {
	position: absolute;
	z-index: 2;
	top: calc(6 * var(--g-u));
	inset-inline-end: calc(10 * var(--g-u));
	display: flex;
	gap: calc(4 * var(--g-u));
	pointer-events: none;
}

.dbg-card.is-compact .on-card-flags {
	top: calc(-10 * var(--g-u));
	inset-inline-end: calc(8 * var(--g-u));
}

.on-flag {
	display: inline-flex;
	align-items: center;
	gap: calc(4 * var(--g-u));
	padding: calc(1 * var(--g-u)) calc(8 * var(--g-u));
	border-radius: 999px;
	background: var(--control);
	border: 1px solid var(--panel-border);
	color: var(--text-muted);
	font-weight: 800;
	font-size: max(10.5px, calc(13 * var(--g-f)));
	line-height: 1.5;
	white-space: nowrap;
}

.on-flag.is-away {
	color: var(--warning);
}

.on-flag.is-muted {
	color: var(--danger);
	padding-inline: calc(5 * var(--g-u));
}

.on-flag .db-icon {
	width: max(12px, calc(15 * var(--g-u)));
	height: max(12px, calc(15 * var(--g-u)));
}

.on-game .dbg-card:not(.on-card-me) {
	-webkit-touch-callout: none;
}

.on-pause-note {
	margin: calc(-1 * var(--g-m)) 0 var(--g-l);
	color: var(--text-muted);
	font-size: var(--g-fs-small);
	line-height: 1.4;
	text-align: center;
}

.on-game .on-notice {
	top: auto;
	bottom: calc(120 * var(--u));
}

/* ====================================================================== Online results additions */

.on-results-top {
	position: absolute;
	z-index: 6;
	top: max(calc(16 * var(--u)), env(safe-area-inset-top, 0px));
	inset-inline-end: calc(16 * var(--u));
}

.on-results-actions > .on-span,
.on-results-actions > .on-votes {
	grid-column: 1 / -1;
}

.on-votes {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: calc(8 * var(--u));
}

.on-vote {
	display: inline-flex;
	align-items: center;
	gap: calc(6 * var(--u));
	padding: calc(4 * var(--u)) calc(12 * var(--u));
	border-radius: 999px;
	background: color-mix(in srgb, var(--on-pc) 18%, transparent);
	color: var(--text);
	font-weight: 700;
	font-size: max(12.5px, var(--fs-small));
	line-height: 1.35;
}

.on-vote .db-icon {
	width: max(13px, calc(16 * var(--u)));
	height: max(13px, calc(16 * var(--u)));
	color: var(--on-pc);
}

/* ====================================================================== Chat button + panel */

.on-chat-btn {
	position: relative;
}

.on-badge {
	position: absolute;
	top: calc(-4 * var(--u));
	inset-inline-end: calc(-4 * var(--u));
	min-width: max(17px, calc(22 * var(--u)));
	height: max(17px, calc(22 * var(--u)));
	padding: 0 calc(5 * var(--u));
	border-radius: 999px;
	background: var(--danger);
	color: #FFFFFF;
	font-family: var(--font-body);
	font-weight: 800;
	font-size: max(10.5px, calc(13 * var(--fs-k) * var(--u)));
	line-height: max(17px, calc(22 * var(--u)));
	text-align: center;
	box-shadow: 0 0 0 2px var(--bg-top);
	pointer-events: none;
	animation: on-badge-pop 0.3s var(--ease-back);
}

@keyframes on-badge-pop {
	from { transform: scale(0.4); }
}

.on-chat {
	position: absolute;
	inset: 0;
	z-index: 14;
	pointer-events: none;
	visibility: hidden;
	transition: visibility 0s linear 0.3s;
}

.on-chat.is-open {
	visibility: visible;
	transition: none;
}

.on-chat.is-sheet.is-open {
	pointer-events: auto;
}

.on-chat-backdrop {
	position: absolute;
	inset: 0;
	background: rgba(0, 0, 0, 0.45);
	opacity: 0;
	transition: opacity 0.25s ease;
}

.on-chat.is-sheet.is-open .on-chat-backdrop {
	opacity: 1;
}

.on-chat.is-side .on-chat-backdrop {
	display: none;
}

.on-chat-sheet {
	position: absolute;
	display: flex;
	flex-direction: column;
	gap: calc(12 * var(--u));
	min-height: 0;
	overflow-x: hidden;
	overflow-y: auto; /* very short screens: everything stays reachable */
	overscroll-behavior: contain;
	scrollbar-width: none;
	padding: calc(16 * var(--u)) calc(18 * var(--u));
	border: 1.5px solid var(--panel-border);
	background-color: var(--bg-bottom);
	background-image: linear-gradient(var(--panel), var(--panel));
	box-shadow: 0 calc(10 * var(--u)) calc(40 * var(--u)) var(--shadow);
	color: var(--text);
	pointer-events: auto;
	transition: transform 0.3s var(--ease-out);
}

.on-chat.is-sheet .on-chat-sheet {
	left: 0;
	right: 0;
	bottom: 0;
	max-height: 86%;
	padding-bottom: max(calc(16 * var(--u)), env(safe-area-inset-bottom, 0px));
	border-bottom: 0;
	border-radius: calc(24 * var(--u)) calc(24 * var(--u)) 0 0;
	transform: translateY(105%);
}

.on-chat.is-sheet.is-full .on-chat-sheet {
	height: 78%;
}

.on-chat.is-side .on-chat-sheet {
	top: calc(16 * var(--u));
	bottom: calc(16 * var(--u));
	inset-inline-end: calc(16 * var(--u));
	width: min(calc(470 * var(--u)), calc(100% - 32px));
	border-radius: calc(24 * var(--u));
	transform: translateX(calc(var(--flow) * 115%));
}

.on-chat.is-side.is-emoji .on-chat-sheet {
	bottom: auto;
}

.on-chat.is-open .on-chat-sheet {
	transform: none;
}

/*
 * Wide layouts: while the side panel is open its screen gives up the panel's width on the end side, so the panel never
 * covers the board (lines under it could not be clicked), the lobby seat controls or the results actions.
 * (online.js createChat -> reserveSide toggles .on-side-chat on the screen root.)
 */
.on-side-chat {
	--on-chat-reserve: calc(16 * var(--u) + min(calc(470 * var(--u)), calc(100vw - 32px)) + 12 * var(--u));
}

/* Game: the end-side card column stays under the panel; the board shrinks to end at the panel's edge. */
.dbg-root.on-side-chat .dbg-main {
	padding-inline-end: max(var(--g-l), calc(var(--on-chat-reserve) - var(--g-card-w, calc(280 * var(--g-u))) - var(--g-l)));
}

.dbr-root.on-side-chat .dbr-scroll,
.on-screen.on-side-chat > .mn-scroll-wrap {
	padding-inline-end: var(--on-chat-reserve);
}

.on-chat-sheet:focus {
	outline: none;
}

.on-chat-head {
	flex: none;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: calc(10 * var(--u));
}

.on-chat-title {
	min-width: 0;
	font-family: var(--font-display);
	font-weight: 400;
	font-size: var(--fs-h2);
	line-height: 1.3;
}

.on-screen .on-chat-close,
.on-chat .on-chat-close {
	--bh: max(38px, calc(46 * var(--u)));
}

.on-chat-people {
	flex: none;
	display: flex;
	flex-wrap: wrap;
	gap: calc(8 * var(--u));
}

.on-person {
	--on-pc: var(--accent);
	display: inline-flex;
	align-items: center;
	gap: calc(8 * var(--u));
	max-width: 100%;
	height: max(34px, calc(40 * var(--u)));
	margin: 0;
	padding: 0 calc(12 * var(--u));
	border-radius: 999px;
	border: 1.5px solid var(--panel-border);
	background: var(--control);
	color: var(--text);
	font-family: var(--font-body);
	font-weight: 700;
	font-size: max(12.5px, var(--fs-small));
	cursor: pointer;
	touch-action: manipulation;
}

.on-person-dot {
	flex: none;
	width: max(9px, calc(12 * var(--u)));
	height: max(9px, calc(12 * var(--u)));
	border-radius: 50%;
	background: var(--on-pc);
}

.on-person-name {
	min-width: 0;
	max-width: calc(160 * var(--u));
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.on-person .db-icon {
	width: max(14px, calc(18 * var(--u)));
	height: max(14px, calc(18 * var(--u)));
	color: var(--text-muted);
}

.on-person.is-muted {
	opacity: 0.75;
}

.on-person.is-muted .on-person-name {
	text-decoration: line-through;
}

.on-person.is-muted .db-icon {
	color: var(--danger);
}

.on-chat-log {
	flex: 1 1 auto;
	min-height: calc(110 * var(--u));
	display: flex;
	flex-direction: column;
	gap: calc(8 * var(--u));
	padding: calc(10 * var(--u));
	border-radius: calc(16 * var(--u));
	background: rgba(0, 0, 0, 0.16);
	overflow-x: hidden;
	overflow-y: auto;
	overscroll-behavior: contain;
	scrollbar-width: thin;
	scrollbar-color: var(--panel-border) transparent;
	-webkit-user-select: text;
	user-select: text;
}

:root[data-light='1'] .on-chat-log {
	background: rgba(0, 0, 0, 0.045);
}

.on-chat-empty {
	margin: auto;
	color: var(--text-muted);
	font-size: max(12.5px, var(--fs-small));
	text-align: center;
}

.on-msg {
	--on-pc: var(--accent);
	align-self: flex-start;
	display: flex;
	flex-direction: column;
	gap: calc(2 * var(--u));
	max-width: 86%;
	padding: calc(7 * var(--u)) calc(12 * var(--u));
	border-radius: calc(14 * var(--u));
	border-start-start-radius: calc(4 * var(--u));
	border-inline-start: max(2px, calc(3 * var(--u))) solid var(--on-pc);
	background: var(--control);
	overflow-wrap: anywhere;
}

.on-msg.is-own {
	align-self: flex-end;
	border-start-start-radius: calc(14 * var(--u));
	border-start-end-radius: calc(4 * var(--u));
	border-inline-start: 0;
	border-inline-end: max(2px, calc(3 * var(--u))) solid var(--on-pc);
	background: color-mix(in srgb, var(--accent) 22%, var(--control));
}

.on-msg-name {
	color: var(--on-pc);
	font-weight: 800;
	font-size: max(11.5px, calc(var(--fs-small) * 0.9));
	line-height: 1.3;
}

:root[data-light='1'] .on-msg-name {
	color: color-mix(in srgb, var(--on-pc) 80%, var(--text));
}

.on-msg-text {
	color: var(--text);
	font-size: max(13.5px, calc(var(--fs-small) * 1.05));
	line-height: 1.4;
	white-space: pre-wrap;
}

.on-msg.is-quick .on-msg-text {
	font-weight: 800;
}

.on-msg.is-system {
	align-self: center;
	max-width: 100%;
	padding: calc(2 * var(--u)) calc(8 * var(--u));
	border: 0;
	background: none;
	color: var(--text-muted);
	font-size: max(11.5px, calc(var(--fs-small) * 0.9));
	text-align: center;
}

.on-chat-quick {
	flex: none;
	display: flex;
	gap: calc(8 * var(--u));
	overflow-x: auto;
	overscroll-behavior: contain;
	scrollbar-width: none;
	padding-block: calc(2 * var(--u));
}

.on-chat-quick::-webkit-scrollbar {
	display: none;
}

.on-qp {
	flex: none;
	height: max(34px, calc(40 * var(--u)));
	margin: 0;
	padding: 0 calc(14 * var(--u));
	border-radius: 999px;
	border: 1.5px solid var(--panel-border);
	background: var(--control);
	color: var(--text);
	font-family: var(--font-body);
	font-weight: 700;
	font-size: max(12.5px, var(--fs-small));
	white-space: nowrap;
	cursor: pointer;
	touch-action: manipulation;
	transition: border-color 0.12s ease, transform 0.12s ease;
}

.on-chat-emoji {
	flex: none;
	display: grid;
	grid-template-columns: repeat(8, minmax(0, 1fr));
	gap: calc(6 * var(--u));
}

.on-emo {
	display: grid;
	place-items: center;
	aspect-ratio: 1;
	min-height: 34px;
	margin: 0;
	padding: 0;
	border: 1.5px solid transparent;
	border-radius: calc(12 * var(--u));
	background: var(--control);
	cursor: pointer;
	touch-action: manipulation;
	transition: transform 0.12s ease, border-color 0.12s ease;
}

.on-emo-glyph,
.on-float.is-emoji .on-float-in {
	font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', 'Segoe UI Symbol', sans-serif;
	font-variant-emoji: emoji;
}

.on-emo-glyph {
	font-size: max(20px, calc(28 * var(--u)));
	line-height: 1;
}

.on-qp:active,
.on-emo:active {
	transform: scale(0.9);
}

@media (hover: hover) and (pointer: fine) {
	.on-qp:hover,
	.on-emo:hover,
	.on-person:hover {
		border-color: var(--accent);
	}

	.on-emo:hover {
		transform: scale(1.08);
	}
}

.on-chat-form {
	flex: none;
	display: flex;
	align-items: center;
	gap: calc(10 * var(--u));
}

.on-chat-field {
	position: relative;
	flex: 1 1 auto;
	min-width: 0;
}

.on-chat-input {
	display: block;
	width: 100%;
	height: max(44px, calc(52 * var(--u)));
	margin: 0;
	padding: 0 calc(16 * var(--u));
	padding-inline-end: calc(70 * var(--u));
	border: 1.5px solid var(--panel-border);
	border-radius: 999px;
	background: var(--control);
	color: var(--text);
	font-family: var(--font-body);
	font-weight: 700;
	font-size: max(16px, calc(var(--fs-body) * 0.9)); /* >= 16px: no iOS zoom on focus */
	outline: none;
	-webkit-appearance: none;
	appearance: none;
	-webkit-user-select: text;
	user-select: text;
}

.on-chat-input::placeholder {
	color: var(--text-muted);
	opacity: 0.8;
}

.on-chat-input:focus {
	border-color: var(--accent);
	box-shadow: 0 0 0 calc(3 * var(--u)) rgba(var(--accent-rgb), 0.25);
}

.on-chat-count {
	position: absolute;
	top: 50%;
	inset-inline-end: calc(16 * var(--u));
	transform: translateY(-50%);
	color: var(--text-muted);
	font-size: max(11px, calc(var(--fs-small) * 0.8));
	font-variant-numeric: tabular-nums;
	pointer-events: none;
}

.on-chat-count.is-max {
	color: var(--danger);
}

.on-chat .on-chat-send {
	--bh: max(44px, calc(52 * var(--u)));
}

.on-chat-hint {
	flex: none;
	color: var(--warning);
	font-weight: 700;
	font-size: max(12.5px, var(--fs-small));
	text-align: center;
}

.on-chat-hint:not(.is-on) {
	display: none;
}

/* Short screens (landscape phones, small windows): the reactions become one scrolling row, the sheet grows. */
@media (max-height: 640px) {
	.on-chat-emoji {
		grid-template-columns: none;
		grid-auto-flow: column;
		grid-auto-columns: max(38px, calc(50 * var(--u)));
		overflow-x: auto;
		overscroll-behavior: contain;
		scrollbar-width: none;
	}

	.on-chat-emoji::-webkit-scrollbar {
		display: none;
	}

	.on-chat.is-sheet .on-chat-sheet {
		max-height: 94%;
		gap: calc(8 * var(--u));
		padding-top: calc(10 * var(--u));
	}

	.on-chat.is-sheet.is-full .on-chat-sheet {
		height: 94%;
	}

	.on-chat-log {
		min-height: 60px;
	}
}

/* ====================================================================== Floating reactions */

.on-float {
	--on-pc: var(--accent);
	position: absolute;
	z-index: 13;
	transform: translate(-50%, -50%);
	pointer-events: none;
}

.on-float-in {
	display: block;
}

.on-float.is-emoji .on-float-in {
	font-size: max(38px, calc(66 * var(--u)));
	line-height: 1;
	filter: drop-shadow(0 calc(4 * var(--u)) calc(10 * var(--u)) rgba(0, 0, 0, 0.35));
	animation: on-rise 1.6s var(--ease-out) forwards;
}

.on-float.is-text .on-float-in {
	max-width: min(calc(320 * var(--u)), 70vw);
	padding: calc(8 * var(--u)) calc(16 * var(--u));
	border-radius: calc(16 * var(--u));
	border: 2px solid var(--on-pc);
	background-color: var(--bg-bottom);
	background-image: linear-gradient(var(--panel), var(--panel));
	box-shadow: 0 0 calc(18 * var(--u)) color-mix(in srgb, var(--on-pc) 40%, transparent);
	color: var(--text);
	font-weight: 800;
	font-size: max(13px, calc(var(--fs-small) * 1.05));
	line-height: 1.35;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
	animation: on-bubble 2.6s ease forwards;
}

.on-float.is-still .on-float-in {
	animation-name: on-fade;
}

@keyframes on-rise {
	0% { opacity: 0; transform: translateY(calc(12 * var(--u))) scale(0.5); }
	12% { opacity: 1; transform: translateY(0) scale(1.18); }
	26% { transform: translateY(calc(-12 * var(--u))) scale(1); }
	72% { opacity: 1; }
	/* --on-rise: set by online.js floatOver on phones, so the emoji stops under the top bar. */
	100% { opacity: 0; transform: translateY(calc(-1 * min(var(--on-rise, calc(120 * var(--u))), calc(120 * var(--u))))) scale(0.95); }
}

@keyframes on-bubble {
	0% { opacity: 0; transform: translateY(calc(8 * var(--u))) scale(0.85); }
	10% { opacity: 1; transform: translateY(0) scale(1); }
	80% { opacity: 1; transform: translateY(calc(-14 * var(--u))); }
	100% { opacity: 0; transform: translateY(calc(-24 * var(--u))); }
}

@keyframes on-fade {
	0% { opacity: 0; }
	15% { opacity: 1; }
	80% { opacity: 1; }
	100% { opacity: 0; }
}

/* ====================================================================== Reduced motion */

@media (prefers-reduced-motion: reduce) {
	.on-chat-sheet,
	.on-chat-backdrop,
	.on-conn,
	.on-notice,
	.on-ring-arc {
		transition-duration: 1ms !important;
	}

	.on-spinner,
	.on-wait-dots i,
	.on-status[data-tone='wait'] .on-status-dot,
	.on-conn::before,
	.dbg-banner.on-clock-low .on-clock-text,
	.on-badge {
		animation: none !important;
	}

	.on-float .on-float-in {
		animation-name: on-fade !important;
	}
}

/* ---- Online safety screen, report buttons, legal links ---- */

.on-safety {
	max-width: calc(820 * var(--u));
	margin-inline: auto;
}

.on-safety-panel {
	display: flex;
	flex-direction: column;
	gap: calc(12 * var(--u));
}

.on-rules {
	margin: 0;
	padding: 0;
	list-style: none;
	display: flex;
	flex-direction: column;
	gap: calc(8 * var(--u));
	color: var(--text);
	font-size: max(14.5px, var(--fs-body));
	line-height: 1.45;
}

.on-rules li {
	position: relative;
	padding-inline-start: calc(24 * var(--u));
}

.on-rules li::before {
	content: '';
	position: absolute;
	inset-inline-start: calc(4 * var(--u));
	top: 0.55em;
	width: max(7px, calc(9 * var(--u)));
	height: max(7px, calc(9 * var(--u)));
	border-radius: 50%;
	background: var(--accent);
}

.on-year-input {
	max-width: calc(280 * var(--u));
	letter-spacing: 0.2em;
	text-indent: 0.2em;
}

.on-year-input::placeholder {
	letter-spacing: 0;
	text-indent: 0;
	font-family: var(--font-body);
	font-size: max(15px, var(--fs-body));
}

.on-legal {
	display: flex;
	flex-wrap: wrap;
	gap: calc(10 * var(--u));
}

.on-legal-link {
	flex: 1 1 calc(180 * var(--u));
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: max(44px, calc(52 * var(--u)));
	padding: 0 calc(16 * var(--u));
	border-radius: var(--chip-r);
	border: 1.5px solid var(--panel-border);
	background: var(--secondary);
	color: var(--text);
	font-weight: 700;
	font-size: max(13.5px, var(--fs-small));
	text-decoration: none;
	text-align: center;
}

.on-legal-link:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

.on-child-note {
	margin: 0;
}

.on-report {
	display: inline-flex;
	align-items: center;
	height: max(34px, calc(40 * var(--u)));
	margin: 0;
	padding: 0 calc(12 * var(--u));
	border-radius: 999px;
	border: 1.5px solid var(--panel-border);
	background: transparent;
	color: var(--text-muted);
	font-family: var(--font-body);
	font-weight: 700;
	font-size: max(12.5px, var(--fs-small));
	cursor: pointer;
	touch-action: manipulation;
}

.on-report.is-pending {
	border-color: var(--danger);
	background: var(--danger);
	color: #fff;
}

.on-report.is-done,
.on-report:disabled {
	cursor: default;
	opacity: 0.7;
}

.on-report:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

@media (hover: hover) {
	.on-legal-link:hover {
		border-color: var(--accent);
	}

	.on-report:not(:disabled):not(.is-pending):hover {
		border-color: var(--danger);
		color: var(--text);
	}
}
