/* /geoguessr/leaflet/leaflet.css */
/* required styles */

.leaflet-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-container,
.leaflet-pane > svg,
.leaflet-pane > canvas,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
	position: absolute;
	left: 0;
	top: 0;
	}
.leaflet-container {
	overflow: hidden;
	}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
	-webkit-user-select: none;
	   -moz-user-select: none;
	        user-select: none;
	  -webkit-user-drag: none;
	}
/* Prevents IE11 from highlighting tiles in blue */
.leaflet-tile::selection {
	background: transparent;
}
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
.leaflet-safari .leaflet-tile {
	image-rendering: -webkit-optimize-contrast;
	}
/* hack that prevents hw layers "stretching" when loading new tiles */
.leaflet-safari .leaflet-tile-container {
	width: 1600px;
	height: 1600px;
	-webkit-transform-origin: 0 0;
	}
.leaflet-marker-icon,
.leaflet-marker-shadow {
	display: block;
	}
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container .leaflet-overlay-pane svg {
	max-width: none !important;
	max-height: none !important;
	}
.leaflet-container .leaflet-marker-pane img,
.leaflet-container .leaflet-shadow-pane img,
.leaflet-container .leaflet-tile-pane img,
.leaflet-container img.leaflet-image-layer,
.leaflet-container .leaflet-tile {
	max-width: none !important;
	max-height: none !important;
	width: auto;
	padding: 0;
	}

.leaflet-container img.leaflet-tile {
	/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
	mix-blend-mode: plus-lighter;
}

.leaflet-container.leaflet-touch-zoom {
	-ms-touch-action: pan-x pan-y;
	touch-action: pan-x pan-y;
	}
.leaflet-container.leaflet-touch-drag {
	-ms-touch-action: pinch-zoom;
	/* Fallback for FF which doesn't support pinch-zoom */
	touch-action: none;
	touch-action: pinch-zoom;
}
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
	-ms-touch-action: none;
	touch-action: none;
}
.leaflet-container {
	-webkit-tap-highlight-color: transparent;
}
.leaflet-container a {
	-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
}
.leaflet-tile {
	filter: inherit;
	visibility: hidden;
	}
.leaflet-tile-loaded {
	visibility: inherit;
	}
.leaflet-zoom-box {
	width: 0;
	height: 0;
	-moz-box-sizing: border-box;
	     box-sizing: border-box;
	z-index: 800;
	}
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
.leaflet-overlay-pane svg {
	-moz-user-select: none;
	}

.leaflet-pane         { z-index: 400; }

.leaflet-tile-pane    { z-index: 200; }
.leaflet-overlay-pane { z-index: 400; }
.leaflet-shadow-pane  { z-index: 500; }
.leaflet-marker-pane  { z-index: 600; }
.leaflet-tooltip-pane   { z-index: 650; }
.leaflet-popup-pane   { z-index: 700; }

.leaflet-map-pane canvas { z-index: 100; }
.leaflet-map-pane svg    { z-index: 200; }

.leaflet-vml-shape {
	width: 1px;
	height: 1px;
	}
.lvml {
	behavior: url(#default#VML);
	display: inline-block;
	position: absolute;
	}


/* control positioning */

.leaflet-control {
	position: relative;
	z-index: 800;
	pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
	pointer-events: auto;
	}
.leaflet-top,
.leaflet-bottom {
	position: absolute;
	z-index: 1000;
	pointer-events: none;
	}
.leaflet-top {
	top: 0;
	}
.leaflet-right {
	right: 0;
	}
.leaflet-bottom {
	bottom: 0;
	}
.leaflet-left {
	left: 0;
	}
.leaflet-control {
	float: left;
	clear: both;
	}
.leaflet-right .leaflet-control {
	float: right;
	}
.leaflet-top .leaflet-control {
	margin-top: 10px;
	}
.leaflet-bottom .leaflet-control {
	margin-bottom: 10px;
	}
.leaflet-left .leaflet-control {
	margin-left: 10px;
	}
.leaflet-right .leaflet-control {
	margin-right: 10px;
	}


/* zoom and fade animations */

.leaflet-fade-anim .leaflet-popup {
	opacity: 0;
	-webkit-transition: opacity 0.2s linear;
	   -moz-transition: opacity 0.2s linear;
	        transition: opacity 0.2s linear;
	}
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
	opacity: 1;
	}
.leaflet-zoom-animated {
	-webkit-transform-origin: 0 0;
	    -ms-transform-origin: 0 0;
	        transform-origin: 0 0;
	}
svg.leaflet-zoom-animated {
	will-change: transform;
}

.leaflet-zoom-anim .leaflet-zoom-animated {
	-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
	   -moz-transition:    -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
	        transition:         transform 0.25s cubic-bezier(0,0,0.25,1);
	}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile {
	-webkit-transition: none;
	   -moz-transition: none;
	        transition: none;
	}

.leaflet-zoom-anim .leaflet-zoom-hide {
	visibility: hidden;
	}


/* cursors */

.leaflet-interactive {
	cursor: pointer;
	}
.leaflet-grab {
	cursor: -webkit-grab;
	cursor:    -moz-grab;
	cursor:         grab;
	}
.leaflet-crosshair,
.leaflet-crosshair .leaflet-interactive {
	cursor: crosshair;
	}
.leaflet-popup-pane,
.leaflet-control {
	cursor: auto;
	}
.leaflet-dragging .leaflet-grab,
.leaflet-dragging .leaflet-grab .leaflet-interactive,
.leaflet-dragging .leaflet-marker-draggable {
	cursor: move;
	cursor: -webkit-grabbing;
	cursor:    -moz-grabbing;
	cursor:         grabbing;
	}

/* marker & overlays interactivity */
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-image-layer,
.leaflet-pane > svg path,
.leaflet-tile-container {
	pointer-events: none;
	}

.leaflet-marker-icon.leaflet-interactive,
.leaflet-image-layer.leaflet-interactive,
.leaflet-pane > svg path.leaflet-interactive,
svg.leaflet-image-layer.leaflet-interactive path {
	pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
	pointer-events: auto;
	}

/* visual tweaks */

.leaflet-container {
	background: #ddd;
	outline-offset: 1px;
	}
.leaflet-container a {
	color: #0078A8;
	}
.leaflet-zoom-box {
	border: 2px dotted #38f;
	background: rgba(255,255,255,0.5);
	}


/* general typography */
.leaflet-container {
	font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
	font-size: 12px;
	font-size: 0.75rem;
	line-height: 1.5;
	}


/* general toolbar styles */

.leaflet-bar {
	box-shadow: 0 1px 5px rgba(0,0,0,0.65);
	border-radius: 4px;
	}
.leaflet-bar a {
	background-color: #fff;
	border-bottom: 1px solid #ccc;
	width: 26px;
	height: 26px;
	line-height: 26px;
	display: block;
	text-align: center;
	text-decoration: none;
	color: black;
	}
.leaflet-bar a,
.leaflet-control-layers-toggle {
	background-position: 50% 50%;
	background-repeat: no-repeat;
	display: block;
	}
.leaflet-bar a:hover,
.leaflet-bar a:focus {
	background-color: #f4f4f4;
	}
.leaflet-bar a:first-child {
	border-top-left-radius: 4px;
	border-top-right-radius: 4px;
	}
.leaflet-bar a:last-child {
	border-bottom-left-radius: 4px;
	border-bottom-right-radius: 4px;
	border-bottom: none;
	}
.leaflet-bar a.leaflet-disabled {
	cursor: default;
	background-color: #f4f4f4;
	color: #bbb;
	}

.leaflet-touch .leaflet-bar a {
	width: 30px;
	height: 30px;
	line-height: 30px;
	}
.leaflet-touch .leaflet-bar a:first-child {
	border-top-left-radius: 2px;
	border-top-right-radius: 2px;
	}
.leaflet-touch .leaflet-bar a:last-child {
	border-bottom-left-radius: 2px;
	border-bottom-right-radius: 2px;
	}

/* zoom control */

.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
	font: bold 18px 'Lucida Console', Monaco, monospace;
	text-indent: 1px;
	}

.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out  {
	font-size: 22px;
	}


/* layers control */

.leaflet-control-layers {
	box-shadow: 0 1px 5px rgba(0,0,0,0.4);
	background: #fff;
	border-radius: 5px;
	}
.leaflet-control-layers-toggle {
	background-image: url(/geoguessr/leaflet/images/layers.png);
	width: 36px;
	height: 36px;
	}
.leaflet-retina .leaflet-control-layers-toggle {
	background-image: url(/geoguessr/leaflet/images/layers-2x.png);
	background-size: 26px 26px;
	}
.leaflet-touch .leaflet-control-layers-toggle {
	width: 44px;
	height: 44px;
	}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
	display: none;
	}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
	display: block;
	position: relative;
	}
.leaflet-control-layers-expanded {
	padding: 6px 10px 6px 6px;
	color: #333;
	background: #fff;
	}
.leaflet-control-layers-scrollbar {
	overflow-y: scroll;
	overflow-x: hidden;
	padding-right: 5px;
	}
.leaflet-control-layers-selector {
	margin-top: 2px;
	position: relative;
	top: 1px;
	}
.leaflet-control-layers label {
	display: block;
	font-size: 13px;
	font-size: 1.08333em;
	}
.leaflet-control-layers-separator {
	height: 0;
	border-top: 1px solid #ddd;
	margin: 5px -10px 5px -6px;
	}

/* Default icon URLs */
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
	background-image: url(/geoguessr/leaflet/images/marker-icon.png);
	}


/* attribution and scale controls */

.leaflet-container .leaflet-control-attribution {
	background: #fff;
	background: rgba(255, 255, 255, 0.8);
	margin: 0;
	}
.leaflet-control-attribution,
.leaflet-control-scale-line {
	padding: 0 5px;
	color: #333;
	line-height: 1.4;
	}
.leaflet-control-attribution a {
	text-decoration: none;
	}
.leaflet-control-attribution a:hover,
.leaflet-control-attribution a:focus {
	text-decoration: underline;
	}
.leaflet-attribution-flag {
	display: inline !important;
	vertical-align: baseline !important;
	width: 1em;
	height: 0.6669em;
	}
.leaflet-left .leaflet-control-scale {
	margin-left: 5px;
	}
.leaflet-bottom .leaflet-control-scale {
	margin-bottom: 5px;
	}
.leaflet-control-scale-line {
	border: 2px solid #777;
	border-top: none;
	line-height: 1.1;
	padding: 2px 5px 1px;
	white-space: nowrap;
	-moz-box-sizing: border-box;
	     box-sizing: border-box;
	background: rgba(255, 255, 255, 0.8);
	text-shadow: 1px 1px #fff;
	}
.leaflet-control-scale-line:not(:first-child) {
	border-top: 2px solid #777;
	border-bottom: none;
	margin-top: -2px;
	}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
	border-bottom: 2px solid #777;
	}

.leaflet-touch .leaflet-control-attribution,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
	box-shadow: none;
	}
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
	border: 2px solid rgba(0,0,0,0.2);
	background-clip: padding-box;
	}


/* popup */

.leaflet-popup {
	position: absolute;
	text-align: center;
	margin-bottom: 20px;
	}
.leaflet-popup-content-wrapper {
	padding: 1px;
	text-align: left;
	border-radius: 12px;
	}
.leaflet-popup-content {
	margin: 13px 24px 13px 20px;
	line-height: 1.3;
	font-size: 13px;
	font-size: 1.08333em;
	min-height: 1px;
	}
.leaflet-popup-content p {
	margin: 17px 0;
	margin: 1.3em 0;
	}
.leaflet-popup-tip-container {
	width: 40px;
	height: 20px;
	position: absolute;
	left: 50%;
	margin-top: -1px;
	margin-left: -20px;
	overflow: hidden;
	pointer-events: none;
	}
.leaflet-popup-tip {
	width: 17px;
	height: 17px;
	padding: 1px;

	margin: -10px auto 0;
	pointer-events: auto;

	-webkit-transform: rotate(45deg);
	   -moz-transform: rotate(45deg);
	    -ms-transform: rotate(45deg);
	        transform: rotate(45deg);
	}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
	background: white;
	color: #333;
	box-shadow: 0 3px 14px rgba(0,0,0,0.4);
	}
.leaflet-container a.leaflet-popup-close-button {
	position: absolute;
	top: 0;
	right: 0;
	border: none;
	text-align: center;
	width: 24px;
	height: 24px;
	font: 16px/24px Tahoma, Verdana, sans-serif;
	color: #757575;
	text-decoration: none;
	background: transparent;
	}
.leaflet-container a.leaflet-popup-close-button:hover,
.leaflet-container a.leaflet-popup-close-button:focus {
	color: #585858;
	}
.leaflet-popup-scrolled {
	overflow: auto;
	}

.leaflet-oldie .leaflet-popup-content-wrapper {
	-ms-zoom: 1;
	}
.leaflet-oldie .leaflet-popup-tip {
	width: 24px;
	margin: 0 auto;

	-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
	filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
	}

.leaflet-oldie .leaflet-control-zoom,
.leaflet-oldie .leaflet-control-layers,
.leaflet-oldie .leaflet-popup-content-wrapper,
.leaflet-oldie .leaflet-popup-tip {
	border: 1px solid #999;
	}


/* div icon */

.leaflet-div-icon {
	background: #fff;
	border: 1px solid #666;
	}


/* Tooltip */
/* Base styles for the element that has a tooltip */
.leaflet-tooltip {
	position: absolute;
	padding: 6px;
	background-color: #fff;
	border: 1px solid #fff;
	border-radius: 3px;
	color: #222;
	white-space: nowrap;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
	pointer-events: none;
	box-shadow: 0 1px 3px rgba(0,0,0,0.4);
	}
.leaflet-tooltip.leaflet-interactive {
	cursor: pointer;
	pointer-events: auto;
	}
.leaflet-tooltip-top:before,
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
	position: absolute;
	pointer-events: none;
	border: 6px solid transparent;
	background: transparent;
	content: "";
	}

/* Directions */

.leaflet-tooltip-bottom {
	margin-top: 6px;
}
.leaflet-tooltip-top {
	margin-top: -6px;
}
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-top:before {
	left: 50%;
	margin-left: -6px;
	}
.leaflet-tooltip-top:before {
	bottom: 0;
	margin-bottom: -12px;
	border-top-color: #fff;
	}
.leaflet-tooltip-bottom:before {
	top: 0;
	margin-top: -12px;
	margin-left: -6px;
	border-bottom-color: #fff;
	}
.leaflet-tooltip-left {
	margin-left: -6px;
}
.leaflet-tooltip-right {
	margin-left: 6px;
}
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
	top: 50%;
	margin-top: -6px;
	}
.leaflet-tooltip-left:before {
	right: 0;
	margin-right: -12px;
	border-left-color: #fff;
	}
.leaflet-tooltip-right:before {
	left: 0;
	margin-left: -12px;
	border-right-color: #fff;
	}

/* Printing */

@media print {
	/* Prevent printers from removing background-images of controls. */
	.leaflet-control {
		-webkit-print-color-adjust: exact;
		print-color-adjust: exact;
		}
	}
/* /onboarding.css */
/* ==================== */
/* Onboarding Module    */
/* Shared carousel for  */
/* client-only games    */
/* ==================== */

:root {
    --onboarding-accent: var(--accent-pink, #ff3b6f);
    --onboarding-accent-dark: var(--accent-pink-dark, #cc2f59);
    --onboarding-shadow: rgba(255, 59, 111, 0.3);
    --onboarding-shadow-hover: rgba(255, 59, 111, 0.4);
}

#onboarding-screen {
    position: relative;
    height: 100vh;
    height: var(--app-height, 100dvh);
    overflow: hidden;
}

#onboarding-screen > .btn-back {
    z-index: 30;
    pointer-events: auto;
    touch-action: manipulation;
}

.onboarding-container {
    display: flex;
    flex-direction: column;
    height: 100%;
    justify-content: flex-start;
    align-items: center;
    padding-top: 40px;
}

.onboarding-slides {
    flex: 1;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 5vh;
    width: 100%;
    position: relative;
}

.onboarding-slide {
    display: none;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 20px;
    animation: fadeIn 0.4s ease;
    user-select: none;
    -webkit-user-select: none;
}

.onboarding-slide.active {
    display: flex;
}

/* Short or landscape screens: centre the active slide in the space above the dots.
   Auto margins fall back to 0 when the slide is taller than that space, so it never runs off the top. */
.onboarding-slides > .onboarding-slide.active {
    margin-top: auto;
    margin-bottom: auto;
}

/* Portrait screens: one geometry for every game.
   Buttons and dots sit at the same distance from the bottom, the title always starts at the
   middle of the screen, and the art fills the zone above it, anchored to its bottom.
   Games with their own half-screen art layout keep their slides but share the bottom rows. */
@media (min-height: 610px) and (max-aspect-ratio: 4/5) {
    #onboarding-screen.screen {
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }

    #onboarding-screen.screen .onboarding-container {
        padding-bottom: 0;
        gap: 0;
    }

    #onboarding-screen.screen :is(.onboarding-dots, .ww-pagination-row, .decoder-pagination-row) {
        height: 10px;
        margin: 0 0 30px;
    }

    #onboarding-screen.screen .onboarding-buttons {
        height: 56px;
        margin: 0 0 20px;
        align-items: stretch;
    }

    #onboarding-screen.screen .onboarding-buttons > button {
        min-height: 0;
        padding-top: 0;
        padding-bottom: 0;
    }

    #onboarding-screen.screen .onboarding-container:not(.taboo-onboarding):not(.secret-hitler-onboarding):not(.ww-ru-onboarding):not(.decoder-ru-onboarding) .onboarding-slides {
        align-items: stretch;
        padding-top: 0;
        padding-bottom: 0;
        min-height: 0;
    }

    /* Title line = screen height minus the bottom rows (116 px) minus this text zone = 50 %;
       below ~652 px the 210 px floor lifts it a little so long rule texts keep a gap above the dots. */
    #onboarding-screen {
        --onboarding-text-zone: max(210px, calc(var(--app-height, 100dvh) * 0.5 - 116px));
    }

    #onboarding-screen :is(.taboo-onboarding .onboarding-slide, .secret-hitler-onboarding .onboarding-slide, .ww-ru-onboarding .ww-page, .decoder-ru-onboarding .decoder-page) {
        grid-template-rows: minmax(0, calc(100% - var(--onboarding-text-zone))) auto 1fr;
    }

    #onboarding-screen :is(.taboo-onboarding, .secret-hitler-onboarding, .ww-ru-onboarding, .decoder-ru-onboarding) .slide-title {
        margin-top: 0;
    }

    #onboarding-screen .onboarding-container:not(.taboo-onboarding):not(.secret-hitler-onboarding):not(.ww-ru-onboarding):not(.decoder-ru-onboarding) .onboarding-slides > .onboarding-slide.active {
        display: grid;
        row-gap: 0;
        grid-template-rows: minmax(0, calc(100% - var(--onboarding-text-zone))) auto 1fr;
        grid-template-columns: minmax(0, 1fr);
        justify-items: center;
        align-content: stretch;
        margin-top: 0;
        margin-bottom: 0;
        padding-top: 0;
        padding-bottom: 0;
    }

    #onboarding-screen .onboarding-container:not(.taboo-onboarding):not(.secret-hitler-onboarding):not(.ww-ru-onboarding):not(.decoder-ru-onboarding) .onboarding-slide.active > :first-child {
        align-self: end;
    }

    /* Same breathing room between the art and the title in every game. */
    #onboarding-screen.screen :is(.onboarding-slide, .ww-page, .decoder-page) > :is(.slide-icon, .rule-remotion-stage, .taboo-art, .sh-art, .ww-art, .decoder-art) {
        margin-bottom: var(--onboarding-art-gap, 32px);
    }

    #onboarding-screen .onboarding-container:not(.taboo-onboarding):not(.secret-hitler-onboarding):not(.ww-ru-onboarding):not(.decoder-ru-onboarding) .onboarding-slide.active > .slide-title {
        align-self: start;
        margin-top: 0;
    }

    #onboarding-screen .onboarding-container:not(.taboo-onboarding):not(.secret-hitler-onboarding):not(.ww-ru-onboarding):not(.decoder-ru-onboarding) .onboarding-slide.active > .slide-text {
        align-self: start;
        min-height: 0;
    }
}

.onboarding-slide.active.slide-in-left {
    animation: slideInLeft 0.3s ease;
}

.onboarding-slide.active.slide-in-right {
    animation: slideInRight 0.3s ease;
}

@keyframes slideInLeft {
    from { opacity: 0; transform: translateX(60px); }
    to   { opacity: 1; transform: translateX(0); }
}

@keyframes slideInRight {
    from { opacity: 0; transform: translateX(-60px); }
    to   { opacity: 1; transform: translateX(0); }
}

.slide-icon {
    font-size: 80px;
    margin-bottom: 30px;
}

.slide-title {
    font-size: 24px;
    font-weight: 700;
    margin-bottom: 20px;
    color: var(--text-primary);
}

.slide-text {
    font-size: 16px;
    color: var(--text-secondary);
    line-height: 1.6;
    max-width: 300px;
}

.onboarding-dots {
    display: flex;
    gap: 10px;
    margin-bottom: 30px;
}

.dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--bg-card);
    cursor: pointer;
    transition: all 0.3s ease;
}

.dot.active {
    background: var(--onboarding-accent);
    width: 30px;
    border-radius: 5px;
}

.onboarding-buttons {
    display: flex;
    gap: 16px;
    width: 100%;
    max-width: 320px;
    margin-bottom: 20px;
}

.btn-skip {
    flex: 1;
    background: transparent;
    border: 2px solid var(--text-secondary);
    color: var(--text-secondary);
    padding: 16px;
    border-radius: 30px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
}

@media (hover: hover) {
    .btn-skip:hover {
        border-color: var(--text-primary);
        color: var(--text-primary);
    }
}

.btn-next-slide {
    flex: 1.5;
    background: linear-gradient(135deg, var(--onboarding-accent) 0%, var(--onboarding-accent-dark) 100%);
    border: none;
    color: white;
    padding: 16px;
    border-radius: 30px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    box-shadow: 0 4px 20px var(--onboarding-shadow);
}

@media (hover: hover) {
    .btn-next-slide:hover {
        transform: translateY(-2px);
        box-shadow: 0 6px 25px var(--onboarding-shadow-hover);
    }
}

/* ==================== */
/* Rule Animation Stage */
/* ==================== */

.rule-animated-onboarding .onboarding-slides {
    align-items: stretch;
    padding-top: 0;
}

.rule-animated-onboarding .onboarding-slide {
    width: 100%;
    max-width: 360px;
    padding: 4px 4px 0;
    animation: none;
}

.rule-animated-onboarding .onboarding-slide.active.slide-in-left,
.rule-animated-onboarding .onboarding-slide.active.slide-in-right {
    animation: none;
}

.rule-remotion-stage {
    position: relative;
    width: min(100%, 320px);
    height: 244px;
    margin: 0 auto 18px;
    overflow: visible;
    background: transparent;
    box-shadow: none;
    isolation: isolate;
}

.rule-remotion-stage > div,
.rule-remotion-fill {
    width: 100%;
    height: 100%;
}

.rule-motion-layer {
    position: absolute;
    inset: 0;
}

.rule-motion-asset {
    position: absolute;
    display: block;
    height: auto;
    pointer-events: none;
    user-select: none;
    -webkit-user-select: none;
    transform-origin: center;
    will-change: transform, opacity;
    filter: drop-shadow(0 14px 18px rgba(0,0,0,0.28));
}

.rule-motion-asset-word-card,
.rule-motion-asset-question-card,
.rule-motion-asset-canvas,
.rule-motion-asset-score {
    filter: drop-shadow(0 10px 14px rgba(0,0,0,0.22));
}

.rule-animated-onboarding .slide-title {
    font-size: 22px;
    line-height: 1.16;
    max-width: 340px;
    margin-bottom: 12px;
}

.rule-animated-onboarding .slide-text {
    max-width: 340px;
    min-height: 94px;
    line-height: 1.48;
}

@media (max-width: 380px) {
    .rule-remotion-stage {
        width: min(100%, 294px);
        height: 224px;
    }
}

@media (max-height: 700px) {
    .rule-animated-onboarding {
        padding-top: 6px;
    }

    .rule-remotion-stage {
        width: min(100%, 284px);
        height: 216px;
        margin-bottom: 12px;
    }

    .rule-animated-onboarding .slide-title {
        font-size: 19px;
        margin-bottom: 8px;
    }

    .rule-animated-onboarding .slide-text {
        min-height: 78px;
        font-size: 14px;
        line-height: 1.36;
    }
}

/* ==================== */
/* Responsive           */
/* ==================== */
@media (max-width: 480px) {
    .slide-icon {
        font-size: 60px;
        margin-bottom: 20px;
    }

    .slide-title {
        font-size: 20px;
        margin-bottom: 16px;
    }

    .slide-text {
        font-size: 14px;
        max-width: 280px;
    }

    .onboarding-buttons {
        gap: 12px;
    }

    .btn-skip,
    .btn-next-slide {
        padding: 14px;
        font-size: 14px;
    }
}

@media (max-height: 600px) {
    .onboarding-slides {
        min-height: 200px;
    }

    .slide-icon {
        font-size: 40px;
        margin-bottom: 16px;
    }

    .onboarding-container {
        gap: 16px;
    }
}

/* Question-mark glyph inside animated onboarding art.
   The host shape is a size container, so the «?» scales with the shape and always fits inside it.
   Put .onboarding-qmark-host on the shape (it needs a fixed width/height) and wrap the «?» in .onboarding-qmark.
   A host can shrink its glyph further with --onboarding-qmark-size (e.g. a star with a small inner area). */
.onboarding-qmark {
    font-size: 20px;
    font-weight: 900;
    line-height: 1;
}

@supports (width: 1cqmin) {
    .onboarding-qmark-host {
        container-type: size;
    }

    .onboarding-qmark {
        font-size: var(--onboarding-qmark-size, 44cqmin);
    }
}

/* Scenes whose animation reaches past the 320 box use viewBox="-24 -24 368 368" and
   <img data-art-bleed>: drawn 115% wide with -7.5% margins, so the art keeps its size and
   layout box while the extra edge stays visible instead of being clipped. */
#onboarding-screen .slide-icon picture > img[data-art-bleed],
#onboarding-screen .slide-icon > img[data-art-bleed] {
    width: 115%;
    max-width: none;
    height: auto;
    max-height: none;
    margin: -7.5%;
}
/* /connection-overlay.css */
/* RoomPlay shared connection overlay («Переподключение…» / «Нет соединения») for online games.
   Markup: <div class="connection-overlay" id="connection-overlay"> with an optional
   .connection-spinner and a .connection-text / [data-connection-text] / #connection-copy element.
   Toggled by shared/client/connection-overlay.ts (adds/removes .visible).
   Link it BEFORE the game's stylesheet and *-theme.css: games tune it through the custom
   properties below or override these rules directly (theme selectors stay more specific). */

.connection-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--rp-connection-z, 100);
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--rp-connection-gap, 16px);
    color: var(--rp-connection-color, inherit);
    background: var(--rp-connection-bg, rgba(13, 19, 41, 0.9));
}

.connection-overlay.visible {
    display: flex;
}

.connection-spinner {
    width: 40px;
    height: 40px;
    border: 3px solid var(--rp-connection-track, var(--bg-card, rgba(255, 255, 255, 0.1)));
    border-top-color: var(--rp-connection-arc, var(--accent-primary, #fff));
    border-radius: 50%;
    animation: rp-connection-spin 0.8s linear infinite;
}

@keyframes rp-connection-spin {
    to { transform: rotate(360deg); }
}

.connection-text {
    color: var(--rp-connection-text, var(--text-secondary));
    font-size: 16px;
}
/* /geoguessr/style.css */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

:root {
    --accent-green: #10b981;
    --accent-green-dark: #059669;
    --accent-coral: #ff6b6b;
}

/* ==================== */
/* Screen System        */
/* ==================== */

@keyframes slideIn {
    from { opacity: 0; transform: translateX(-20px); }
    to { opacity: 1; transform: translateX(0); }
}

/* ==================== */
/* Typography           */
/* ==================== */

/* ==================== */
/* Buttons              */
/* ==================== */

@media (hover: hover) {
    .btn-join:hover {
        background: var(--accent-green);
        color: var(--text-primary);
    }
}

.btn-join.active {
    background: linear-gradient(135deg, var(--accent-green) 0%, var(--accent-green-dark) 100%);
    border-color: transparent;
    color: var(--text-primary);
    box-shadow: 0 4px 20px rgba(16, 185, 129, 0.3);
}

.btn-play.outlined {
    background: transparent;
    border: 2px solid var(--accent-green);
    color: var(--accent-green);
    box-shadow: none;
}

@media (hover: hover) {
    .btn-copy:hover {
        background: var(--bg-secondary);
        color: var(--text-primary);
    }
}

/* ==================== */
/* Inputs               */
/* ==================== */

.name-input {
    margin-bottom: 20px;
    text-align: center;
}

.code-input {
    width: 100%;
    text-align: center;
    font-size: 24px;
    font-weight: 700;
    letter-spacing: 8px;
    text-transform: uppercase;
    font-family: 'Courier New', monospace;
}

/* ==================== */
/* Main Screen          */
/* ==================== */

.main-content {
    justify-content: center;
    align-items: center;
}

.game-logo {
    font-size: 80px;
    margin-bottom: 16px;
}

.actions-columns {
    display: flex;
    gap: 16px;
    width: 100%;
    align-items: stretch;
    margin-top: 24px;
}

.action-col {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 12px;
    justify-content: center;
    min-width: 0;
}

.col-divider {
    width: 1px;
    background: rgba(255, 255, 255, 0.1);
}

.error-message {
    color: var(--error);
    font-size: 14px;
    text-align: center;
    min-height: 20px;
    margin-top: 16px;
}

/* ==================== */
/* Lobby Screen         */
/* ==================== */

.qr-code-block {
    display: flex;
    justify-content: center;
    margin: 0 0 16px;
}

.qr-code-img {
    width: 160px;
    height: 160px;
    border-radius: 12px;
    border: 2px solid rgba(255, 255, 255, 0.1);
    background: #ffffff;
    padding: 8px;
}

/* ==================== */
/* Game Screen          */
/* ==================== */

.game-content {
    padding-top: calc(24px + env(safe-area-inset-top, 0px));
}

.game-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
    padding-left: 40px;
}

.round-badge {
    background: var(--bg-card);
    padding: 8px 16px;
    border-radius: 20px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-secondary);
}

.timer-badge {
    width: 48px;
    height: 48px;
    background: var(--accent-green);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    font-weight: 700;
}

.timer-badge.warning {
    background: var(--error);
    animation: pulse 0.5s ease infinite alternate;
}

@keyframes pulse {
    from { transform: scale(1); }
    to { transform: scale(1.1); }
}

/* ==================== */
/* Street Photo         */
/* ==================== */

.street-photo-container {
    width: 100%;
    aspect-ratio: 16/9;
    border-radius: 16px;
    overflow: hidden;
    background: var(--bg-card);
    margin-bottom: 16px;
    position: relative;
    touch-action: none;
}

.street-photo {
    width: 100%;
    height: 104%;
    object-fit: cover;
    object-position: center top;
    display: block;
    transform-origin: 0 0;
    will-change: transform;
}

/* Google Street View sphere (street-view.ts): kept in the DOM for the whole page, shown on rounds with a panorama. */
.street-pano {
    position: absolute;
    inset: 0;
    visibility: hidden;
    z-index: 0; /* keeps Google's own z-indexes under the vote pill and flag */
}

.street-photo-container.has-pano {
    aspect-ratio: 4/3; /* a sphere needs more room to look around than a photo */
}

.street-photo-container.has-pano .street-pano {
    visibility: visible;
}

/* Next round's place loading on the start screen / leaderboard (street-view.ts preloadPanorama): the hidden
   game screen is laid out full screen so Google fetches the tiles it will show, but transparent, under
   everything and inert. Only the sphere is painted; the panorama element is never moved (Google blanks it). */
#game-screen.sv-preloading:not(.active) {
    display: flex;
    position: fixed;
    inset: 0;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    z-index: -1;
    animation: none;
}

#game-screen.sv-preloading:not(.active) .street-photo-container {
    position: fixed;
    inset: 0;
    width: auto;
    aspect-ratio: auto;
    margin: 0;
}

#game-screen.sv-preloading:not(.active) .street-pano {
    visibility: visible;
}

.street-photo.zoom-reset {
    transition: transform 0.2s ease-out;
}

.photo-loading {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-card);
}

/* ==================== */
/* Map Guess Container  */
/* ==================== */

.map-guess-container {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-bottom: 16px;
}

.guess-map {
    position: relative;
    width: 100%;
    height: 200px;
    border-radius: 12px;
    overflow: hidden;
    z-index: 1;
}

/* «© OpenStreetMap / © CARTO» credit the tile providers require; small enough for the 132 px preview. */
.leaflet-container .leaflet-control-attribution {
    font-size: 9px;
    line-height: 1.3;
    padding: 0 4px;
    background: rgba(255, 255, 255, 0.7);
}

/* Shown by map-loader.ts when neither Leaflet nor any map tiles could be loaded. */
.geo-map-error {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 16px;
    text-align: center;
    background: var(--bg-card);
}

.geo-map-error p {
    margin: 0;
    font-size: 14px;
    color: var(--text-secondary);
}

.geo-map-retry {
    padding: 10px 22px;
    border: none;
    border-radius: 30px;
    font: inherit;
    font-weight: 600;
    color: var(--text-primary);
    background: var(--accent-green);
    cursor: pointer;
}

.btn-confirm-guess {
    width: 100%;
    padding: 14px;
    background: linear-gradient(135deg, var(--accent-green) 0%, var(--accent-green-dark) 100%);
    border: none;
    border-radius: 30px;
    color: var(--text-primary);
    font-size: 16px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: all 0.3s ease;
    box-shadow: 0 4px 20px rgba(16, 185, 129, 0.3);
}

@media (hover: hover) {
    .btn-confirm-guess:hover {
        transform: translateY(-2px);
        box-shadow: 0 6px 24px rgba(16, 185, 129, 0.4);
    }
}

.btn-confirm-guess:disabled {
    background: var(--bg-card);
    box-shadow: none;
    cursor: not-allowed;
    opacity: 0.6;
}

/* ==================== */
/* Quiz Options         */
/* ==================== */

.quiz-options {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-bottom: 16px;
}

.quiz-option {
    display: flex;
    align-items: center;
    padding: 16px 20px;
    background: var(--bg-card);
    border: 2px solid transparent;
    border-radius: 16px;
    cursor: pointer;
    transition: all 0.3s ease;
    font-family: inherit;
    color: var(--text-primary);
    text-align: left;
    width: 100%;
    font-size: 16px;
}

@media (hover: hover) {
    .quiz-option:hover:not(:disabled) {
        border-color: var(--accent-blue);
        transform: translateX(4px);
    }
}

.quiz-option:active:not(:disabled) {
    transform: scale(0.98);
}

.quiz-option:disabled {
    cursor: default;
}

.quiz-option.selected {
    border-color: var(--accent-blue);
    background: rgba(74, 108, 247, 0.15);
}

.quiz-option.correct {
    border-color: var(--rp-correct);
    background: color-mix(in srgb, var(--rp-correct) 15%, transparent);
    animation: correctPulse 0.5s ease;
}

@keyframes correctPulse {
    0% { transform: scale(1); }
    50% { transform: scale(1.02); }
    100% { transform: scale(1); }
}

.quiz-option.wrong {
    border-color: var(--rp-wrong);
    background: color-mix(in srgb, var(--rp-wrong) 15%, transparent);
    animation: wrongShake 0.4s ease;
}

@keyframes wrongShake {
    0%, 100% { transform: translateX(0); }
    25% { transform: translateX(-6px); }
    75% { transform: translateX(6px); }
}

.option-letter {
    width: 40px;
    height: 40px;
    background: var(--accent-blue);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 18px;
    margin-right: 16px;
    flex-shrink: 0;
}

.quiz-option.correct .option-letter {
    background: var(--rp-correct);
    color: var(--rp-correct-ink);
}

.quiz-option.wrong .option-letter {
    background: var(--rp-wrong);
    color: var(--rp-wrong-ink);
}

/* The answer mark replaces the option letter: the shared upright ✓ / ✕ from answer-marks.css keep the result readable without colour. */
.quiz-option.correct .option-letter,
.quiz-option.wrong .option-letter {
    font-size: 0;
}

.quiz-option.correct .option-letter::after,
.quiz-option.wrong .option-letter::after {
    content: "";
    display: block;
    width: 18px;
    height: 18px;
    background-color: currentColor;
    -webkit-mask: var(--rp-icon-check) center / contain no-repeat;
    mask: var(--rp-icon-check) center / contain no-repeat;
}

.quiz-option.wrong .option-letter::after {
    -webkit-mask-image: var(--rp-icon-cross);
    mask-image: var(--rp-icon-cross);
}

.quiz-option.wrong .option-text {
    text-decoration: line-through;
    text-decoration-thickness: 2px;
    text-decoration-color: color-mix(in srgb, var(--rp-wrong) 75%, transparent);
}

.option-text {
    font-size: 16px;
    font-weight: 500;
    flex: 1;
}

/* ==================== */
/* Answer Feedback      */
/* ==================== */

.answer-feedback {
    min-height: 24px;
    text-align: center;
    font-size: 16px;
    font-weight: 600;
    margin-bottom: 12px;
}

.answer-feedback.success {
    color: var(--success);
}

.answer-feedback.fail {
    color: var(--error);
}

/* ==================== */
/* Mini Scoreboard      */
/* ==================== */

.mini-scoreboard::-webkit-scrollbar {
    display: none;
}

/* ==================== */
/* Round Results Screen */
/* ==================== */

.round-results-content {
    align-items: center;
}

.quiz-options.revealed .quiz-option {
    cursor: default;
    pointer-events: none;
}

.quiz-options.revealed .quiz-option.correct {
    border-color: var(--rp-correct);
    background: color-mix(in srgb, var(--rp-correct) 15%, transparent);
}

/* ==================== */
/* Results Map          */
/* ==================== */

.results-map-container {
    width: 100%;
    margin-bottom: 16px;
    padding-top: calc(16px + env(safe-area-inset-top, 0px));
    position: relative;
    z-index: 6;
}

#reveal-container {
    position: relative;
}

#reveal-container .rr-context-image {
    clip-path: inset(0 0 4% 0);
}

.results-map {
    position: relative;
    width: 100%;
    height: 250px;
    border-radius: 12px;
    overflow: hidden;
    z-index: 1;
}

.correct-location-info {
    font-size: 18px;
    font-weight: 600;
    text-align: center;
    color: var(--rp-correct);
    margin-bottom: 8px;
}

.correct-location-detail {
    font-size: 14px;
    text-align: center;
    color: var(--text-secondary);
    margin-bottom: 16px;
}

/* ==================== */
/* Round Photo          */
/* ==================== */

.round-photo {
    width: 100%;
    max-width: 300px;
    aspect-ratio: 16/9;
    border-radius: 12px;
    object-fit: cover;
    clip-path: inset(0 0 4% 0);
    margin-bottom: 12px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
    background: var(--bg-card);
}

/* ==================== */
/* Map Hint             */
/* ==================== */

.map-hint {
    text-align: center;
    color: var(--text-secondary);
    font-size: 13px;
    margin-bottom: 8px;
}

/* ==================== */
/* Results Screen       */
/* ==================== */

/* ==================== */
/* Connection Overlay   */
/* ==================== */
/* Base styles: ../connection-overlay.css */

.connection-overlay { --rp-connection-arc: var(--accent-green); }

/* ==================== */
/* Mode Toggle (Lobby)  */
/* ==================== */

.mode-toggle {
    display: flex;
    gap: 4px;
    margin-bottom: 16px;
    background: var(--bg-card);
    padding: 4px;
    border-radius: 20px;
    width: 100%;
}

.mode-btn {
    flex: 1;
    padding: 10px 16px;
    background: transparent;
    border: none;
    border-radius: 16px;
    color: var(--text-secondary);
    font-size: 14px;
    font-weight: 600;
    font-family: inherit;
    cursor: pointer;
    transition: all 0.2s ease;
}

.mode-btn.active {
    background: var(--accent-green);
    color: var(--text-primary);
}

/* ==================== */
/* Responsive           */
/* ==================== */

@media (max-width: 480px) {
    .screen-content {
        padding: 24px 16px;
        padding-top: calc(24px + env(safe-area-inset-top, 0px));
    }

    .title {
        font-size: 24px;
    }

    .game-logo {
        font-size: 60px;
    }

    .room-code-display {
        font-size: 36px;
        padding: 12px 24px;
        letter-spacing: 8px;
    }

    .quiz-option {
        padding: 14px 16px;
    }

    .option-letter {
        width: 34px;
        height: 34px;
        font-size: 16px;
        margin-right: 12px;
    }

    .option-text {
        font-size: 14px;
    }

    .timer-badge {
        width: 42px;
        height: 42px;
        font-size: 18px;
    }

    .guess-map { height: 180px; }
    .results-map { height: 200px; }
    .round-photo { max-width: 250px; }
}

@media (min-width: 768px) {
    .screen-content {
        padding: 50px 40px;
    }

    .title {
        font-size: 32px;
    }

    .quiz-option {
        padding: 18px 24px;
    }

    .option-text {
        font-size: 18px;
    }

    .timer-badge {
        width: 56px;
        height: 56px;
        font-size: 24px;
    }

    .guess-map { height: 280px; }
    .results-map { height: 300px; }
}

/* ==================== */
/* Sphere rounds        */
/* ==================== */
/* A round with a Google panorama (main.ts setSphereLayout): the sphere fills the screen, the
   header floats over it and the guess map is a corner preview (.is-open = the usual size). */

.geo-map-expand {
    display: none;
}

#game-screen.geo-sphere .street-photo-container {
    position: fixed;
    inset: 0;
    z-index: 0;
    width: auto;
    aspect-ratio: auto;
    margin: 0;
    border-radius: 0;
    box-shadow: none;
    animation: none;
}

#game-screen.geo-sphere .game-header {
    position: relative;
    z-index: 2;
    padding-left: 52px;
}

/* On the dark surface so it reads over a bright sky. */
#game-screen.geo-sphere .btn-back {
    z-index: 3;
    border-radius: 50%;
    background: rgb(33 28 84 / 82%);
}

#game-screen.geo-sphere .geo-card-vote {
    top: calc(68px + env(safe-area-inset-top, 0px));
    bottom: auto;
}

#game-screen.geo-sphere .geo-report-flag {
    top: calc(72px + env(safe-area-inset-top, 0px));
    right: 12px;
}

#game-screen.geo-sphere .answer-feedback {
    position: fixed;
    left: 50%;
    top: calc(116px + env(safe-area-inset-top, 0px));
    z-index: 3;
    transform: translateX(-50%);
    margin: 0;
    padding: 4px 14px;
    min-height: 0;
    border-radius: 999px;
    background: rgb(33 28 84 / 82%);
}

#game-screen.geo-sphere .answer-feedback:empty,
#game-screen.geo-sphere .mini-scoreboard,
#game-screen.geo-sphere .map-hint {
    display: none;
}

/* Above Google's footer (logo, terms) so it stays visible. */
#game-screen.geo-sphere .map-guess-container {
    position: fixed;
    right: 12px;
    bottom: calc(32px + env(safe-area-inset-bottom, 0px));
    z-index: 3;
    width: 132px;
    gap: 8px;
    margin: 0;
    animation: none;
    transition: width 0.2s ease;
}

#game-screen.geo-sphere .guess-map-wrap {
    position: relative;
}

#game-screen.geo-sphere .guess-map {
    height: 96px;
    box-shadow: 0 0 0 3px #fff, 0 4px 14px rgb(0 0 0 / 35%);
    transition: height 0.2s ease;
}

#game-screen.geo-sphere .geo-map-expand {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 2;
    background: transparent;
    border: 0;
    border-radius: 12px;
    cursor: zoom-in;
}

#game-screen.geo-sphere .map-guess-container:not(.is-open) .leaflet-control-container {
    display: none;
}

#game-screen.geo-sphere .map-guess-container:not(.is-open) .btn-confirm-guess {
    padding: 8px;
    font-size: 13px;
}

#game-screen.geo-sphere .map-guess-container:not(.is-open) .btn-confirm-guess:disabled {
    display: none;
}

#game-screen.geo-sphere .map-guess-container.is-open {
    width: calc(100% - 24px);
}

#game-screen.geo-sphere .map-guess-container.is-open .guess-map {
    height: 300px;
}

#game-screen.geo-sphere .map-guess-container.is-open .geo-map-expand {
    display: none;
}

/* Results-map marker tooltip: player avatar + name */
.geo-guess-tooltip { display: inline-flex; align-items: center; gap: 6px; }
.geo-guess-avatar {
    flex: none; width: 20px; height: 20px; border-radius: 50%; overflow: hidden;
    display: inline-grid; place-items: center; font-size: 9px; font-weight: 800;
    background: rgba(0, 0, 0, .12); color: inherit;
}
.geo-guess-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* /confirm-dialog.css */
/*
 * Back/exit confirmation dialog. Game Themes recolour it through the --rp-dialog-* tokens
 * (shared with settings-popup.css), set once on :root or [data-rp-game] in the theme:
 *   --rp-dialog-overlay, --rp-dialog-bg, --rp-dialog-border, --rp-dialog-shadow, --rp-dialog-radius,
 *   --rp-dialog-title, --rp-dialog-text, --rp-dialog-primary-bg, --rp-dialog-primary-text,
 *   --rp-dialog-primary-shadow, --rp-dialog-btn-radius, --rp-dialog-secondary-bg,
 *   --rp-dialog-secondary-border, --rp-dialog-secondary-text.
 * Fallbacks are the original navy look, so a game without tokens is unchanged. Unset tokens
 * follow related ones: secondary text = --rp-dialog-text; in the settings popup the value and
 * −/+ text = --rp-dialog-title, the toggle text = --rp-dialog-text and the «on» toggle = the primary button.
 */
.confirm-dialog-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: var(--rp-dialog-overlay, rgba(0, 0, 0, 0.85));
    z-index: 1000;
    justify-content: center;
    align-items: center;
    padding: 24px;
}

.confirm-dialog-overlay.active {
    display: flex;
}

.confirm-dialog-modal {
    background: var(--rp-dialog-bg, linear-gradient(135deg, #252b4a 0%, #1a2140 100%));
    border: var(--rp-dialog-border, none);
    box-shadow: var(--rp-dialog-shadow, none);
    border-radius: var(--rp-dialog-radius, 24px);
    padding: 32px 24px;
    max-width: 340px;
    width: 100%;
    text-align: center;
}

.confirm-dialog-title {
    font-size: 20px;
    font-weight: 700;
    color: var(--rp-dialog-title, #ffffff);
    margin-bottom: 8px;
}

.confirm-dialog-subtitle {
    font-size: 14px;
    color: var(--rp-dialog-text, #8892b0);
    margin-bottom: 24px;
}

.confirm-dialog-buttons {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.confirm-dialog-btn {
    width: 100%;
    padding: 14px;
    border: none;
    border-radius: var(--rp-dialog-btn-radius, 30px);
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
}

.confirm-dialog-btn-confirm {
    background: var(--rp-dialog-primary-bg, linear-gradient(135deg, #ff3b6f, #cc2f59));
    color: var(--rp-dialog-primary-text, white);
    box-shadow: var(--rp-dialog-primary-shadow, none);
}

.confirm-dialog-btn-cancel {
    background: var(--rp-dialog-secondary-bg, transparent);
    border: 2px solid var(--rp-dialog-secondary-border, #3a4167);
    color: var(--rp-dialog-secondary-text, var(--rp-dialog-text, #8892b0));
}

/* Optional «why are you leaving» chips (ConfirmDialog.show(..., { reasons: true })). */
.confirm-dialog-reasons {
    margin: -8px 0 20px;
}
.confirm-dialog-reasons[hidden] { display: none; }
.confirm-dialog-reasons-title {
    font-size: 13px;
    color: var(--rp-dialog-text, #8892b0);
    margin-bottom: 10px;
}
.confirm-dialog-reason-list {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
}
.confirm-dialog-reason {
    min-height: 36px;
    padding: 7px 14px;
    border: 1.5px solid var(--rp-dialog-secondary-border, #3a4167);
    border-radius: 18px;
    background: transparent;
    color: var(--rp-dialog-title, #ffffff);
    font: inherit;
    font-size: 14px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 150ms ease, border-color 150ms ease, transform 150ms ease;
}
.confirm-dialog-reason:active { transform: scale(0.95); }
.confirm-dialog-reason[aria-pressed="true"] {
    background: var(--rp-dialog-primary-bg, linear-gradient(135deg, #ff3b6f, #cc2f59));
    border-color: transparent;
    color: var(--rp-dialog-primary-text, #ffffff);
}
.confirm-dialog-reason:focus-visible { outline: 2px solid var(--rp-dialog-primary-text, #ffffff); outline-offset: 2px; }
/* /video-task.css */
/* «Сними ролик» (video-task.js, owner 2026-10-22): the quiet button «Получи до 7 500 ₽ за это видео. Как?»
 * inside the task card, right under the task text, and the sheet with two ways to be paid.
 * Calm on purpose (owner: it must not look like an ad banner): no shine, no pulse, it takes the
 * card's own ink (currentColor) on a light tint, «Как?» underlined like a link.
 * No emoji: icons from ui-icons.css. With prefers-reduced-motion nothing moves. */

.rp-video-task-cta[hidden] { display: none; }

.rp-video-task-cta {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 10px;
    box-sizing: border-box;
    width: 100%;
    min-height: 48px;
    margin: 16px 0 0;
    padding: 10px 14px;
    border: 1px solid color-mix(in srgb, currentColor 30%, transparent);
    border-radius: 14px;
    background: color-mix(in srgb, currentColor 10%, transparent);
    color: inherit;
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: normal;
    text-transform: none;
    text-align: left;
    cursor: pointer;
    transition: background .15s ease, transform .1s ease;
    -webkit-tap-highlight-color: transparent;
}
.rp-video-task-cta .rp-icon { flex: none; width: 20px; height: 20px; }
.rp-video-task-cta-how { font-weight: 800; text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }
.rp-video-task-cta:hover { background: color-mix(in srgb, currentColor 16%, transparent); }
.rp-video-task-cta:active { transform: scale(.98); }
.rp-video-task-cta:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }

.rp-video-task-card {
    box-shadow: 0 0 0 2px rgba(255, 255, 255, .45), 0 18px 40px rgba(0, 0, 0, .35) !important;
}
/* The video task is not a card of the deck: no thumbs and no report flag on it. */
.rp-video-task-card .rp-card-vote,
.rp-video-task-card .rp-report-flag { visibility: hidden; }

/* The sheet: RoomPlay core surfaces, like «Час Premium за репост» (share-pass.js). */
.rp-video-task-overlay {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: rgba(10, 15, 31, .72);
    opacity: 0;
    transition: opacity .2s ease;
}
.rp-video-task-overlay.visible { opacity: 1; }
.rp-video-task-sheet {
    position: relative;
    box-sizing: border-box;
    width: 100%;
    max-width: 480px;
    max-height: 100%;
    overflow-y: auto;
    padding: 24px 16px calc(20px + env(safe-area-inset-bottom));
    border-radius: 24px 24px 0 0;
    background: #1a2140;
    color: #fff;
    font-family: inherit;
    text-align: center;
    transform: translateY(24px);
    transition: transform .2s ease;
}
.rp-video-task-overlay.visible .rp-video-task-sheet { transform: none; }
.rp-video-task-sheet:focus { outline: none; }
.rp-video-task-close {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 44px;
    height: 44px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: inherit;
    font-size: 20px;
    opacity: .75;
    cursor: pointer;
}
.rp-video-task-title { margin: 8px 40px 8px; font-size: 22px; font-weight: 800; line-height: 1.25; }
.rp-video-task-lead { margin: 0 0 16px; font-size: 16px; line-height: 1.45; color: #c9cfe6; }
.rp-video-task-option {
    margin: 0 0 12px;
    padding: 18px 16px 16px;
    border-radius: 20px;
    background: rgba(255, 255, 255, .06);
    border: 1px solid rgba(255, 255, 255, .12);
    text-align: left;
}
.rp-video-task-option-icon { display: block; width: 28px; height: 28px; margin: 0 0 8px; }
.rp-video-task-option--premium .rp-video-task-option-icon { color: #ffd166; }
.rp-video-task-option--money .rp-video-task-option-icon { color: #6ee7b7; }
.rp-video-task-option-title { margin: 0 0 6px; font-size: 18px; font-weight: 800; line-height: 1.25; }
.rp-video-task-option-text { margin: 0 0 14px; font-size: 15px; line-height: 1.45; color: #c9cfe6; }
.rp-video-task-option-cta {
    display: block;
    width: 100%;
    min-height: 48px;
    padding: 10px 16px;
    border: 0;
    border-radius: 30px;
    background: var(--settings-accent, #7c3aed);
    color: var(--rp-video-cta-ink, #fff);
    font: inherit;
    font-size: 16px;
    font-weight: 700;
    cursor: pointer;
}
.rp-video-task-option--money .rp-video-task-option-cta {
    background: transparent;
    color: #fff;
    box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .35);
}
.rp-video-task-close:focus-visible, .rp-video-task-option-cta:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
    .rp-video-task-cta { transition: none; }
    .rp-video-task-overlay, .rp-video-task-sheet { transition: none; }
}
/* /settings-popup.css */
/*
 * Settings popup. Game Themes recolour it through the --rp-dialog-* tokens shared with
 * confirm-dialog.css (see there), plus the controls:
 *   --rp-dialog-control-bg (selector track), --rp-dialog-control-btn-bg / -text / -active / -radius (−/+),
 *   --rp-dialog-value, --rp-dialog-toggle-bg / -text, --rp-dialog-toggle-on-bg / -on-text.
 * The primary «Готово» falls back to --settings-accent; fallbacks keep the original navy look.
 */
.settings-popup-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: var(--rp-dialog-overlay, rgba(0, 0, 0, 0.85));
    z-index: 1000;
    justify-content: center;
    align-items: center;
    padding: 24px;
}

.settings-popup-overlay.active {
    display: flex;
}

.settings-popup-modal {
    background: var(--rp-dialog-bg, linear-gradient(135deg, #252b4a 0%, #1a2140 100%));
    /* Base text colour for currentColor parts such as «Предложить идею». */
    color: var(--rp-dialog-title, #ffffff);
    border: var(--rp-dialog-border, none);
    box-shadow: var(--rp-dialog-shadow, none);
    border-radius: var(--rp-dialog-radius, 24px);
    padding: 32px 24px;
    max-width: 380px;
    width: 100%;
    /* A tall sheet (many rows, a short phone): the title and «Готово» stay put and only the rows
       scroll; a fade at the bottom edge (.settings-popup-content--more) shows there is more below. */
    max-height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.settings-popup-title {
    font-size: 20px;
    font-weight: 700;
    color: var(--rp-dialog-title, #ffffff);
    margin-bottom: 24px;
    text-align: center;
}

.settings-popup-content {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-bottom: 24px;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    /* Room for focus outlines at the clipped edges. */
    margin-inline: -4px;
    padding: 2px 4px;
}
.settings-popup-content > * { flex: none; }
.settings-popup-title,
.settings-popup-done { flex: none; }
.settings-popup-content--more {
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 56px), transparent);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 56px), transparent);
}

.settings-popup-row {
    /* Rows sit directly on the modal surface: Game Themes recolour the modal,
       controls and text, never the row itself (a tinted row reads as a stray strip). */
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

/* App-wide «Звуки» / «Вибрация» rows (ui-feedback.js) follow the game's own settings,
   separated by a thin divider in the label colour; when they are the only rows, no divider. */
.settings-popup-row-app-first:not(:first-child) {
    padding-top: 16px;
    border-top: 1px solid color-mix(in srgb, currentColor 14%, transparent);
}

.settings-popup-label {
    font-size: 15px;
    color: var(--rp-dialog-text, #c0c8e0);
    flex: 1;
    min-width: 0;
}

.settings-popup-selector {
    display: flex;
    align-items: center;
    gap: 0;
    background: var(--rp-dialog-control-bg, rgba(255, 255, 255, 0.06));
    border-radius: 14px;
    padding: 4px;
    flex-shrink: 0;
}

.settings-popup-btn {
    width: 40px;
    height: 40px;
    border: none;
    border-radius: var(--rp-dialog-control-btn-radius, 12px);
    background: var(--rp-dialog-control-btn-bg, rgba(255, 255, 255, 0.08));
    color: var(--rp-dialog-control-btn-text, var(--rp-dialog-title, #ffffff));
    font-size: 20px;
    font-weight: 600;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.2s;
    font-family: inherit;
}

.settings-popup-btn:active {
    background: var(--rp-dialog-control-btn-active, rgba(255, 255, 255, 0.15));
}

/* Hit areas. The shared press animation (game-motion.css: scale .96 + 2px down) moves a button
   away from the finger, so a tap on its top edge was lifted outside it and lost, and the 4px
   track padding around −/+ never counted. An invisible ::before larger than the button moves
   with it and keeps those taps; −/+ also cover the track padding. Choice options touch each
   other (4px gap), so they only grow into half the gap. */
.settings-popup-btn,
.settings-popup-toggle,
.settings-popup-link {
    position: relative;
    touch-action: manipulation;
}

.settings-popup-btn::before,
.settings-popup-toggle::before,
.settings-popup-link::before {
    content: '';
    position: absolute;
    inset: -8px -6px;
}

.settings-popup-choice-option::before {
    inset: -2px;
}

.settings-popup-link::before {
    inset: -4px;
}

.settings-popup-value {
    min-width: 60px;
    padding: 0 8px;
    white-space: nowrap;
    text-align: center;
    font-size: 18px;
    font-weight: 700;
    color: var(--rp-dialog-value, var(--rp-dialog-title, #ffffff));
}

.settings-popup-row-choice {
    flex-wrap: wrap;
    gap: 8px;
}

.settings-popup-row-choice .settings-popup-label {
    flex-basis: 100%;
}

/* Segmented control for `type: 'choice'`: equal options, the chosen one in the primary colour. */
.settings-popup-choice {
    flex: 1 1 100%;
    flex-wrap: wrap;
    min-width: 0;
    gap: 4px;
}

.settings-popup-choice-option {
    /* Sized by their labels, so a short «Классика» leaves room for «Большинство»; a label set
       too long for one row wraps onto a second line instead of splitting a word. */
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    min-height: 44px;
    height: auto;
    padding: 6px 4px;
    font-size: 13px;
    font-weight: 700;
    line-height: 1.15;
    overflow-wrap: anywhere;
    background: transparent;
    color: var(--rp-dialog-text, #c0c8e0);
}

.settings-popup-choice-option.active {
    color: var(--rp-dialog-toggle-on-text, var(--rp-dialog-primary-text, #ffffff));
    background: var(--rp-dialog-toggle-on-bg, var(--rp-dialog-primary-bg, var(--settings-accent, #ff3b6f)));
}

/* Phones narrower than ~380 px can't fit three or more labels in a row: list them one under another. */
@media (max-width: 380px) {
    .settings-popup-choice:has(> :nth-child(3)) { flex-direction: column; align-items: stretch; }
    .settings-popup-choice:has(> :nth-child(3)) .settings-popup-choice-option { min-height: 40px; }
}

.settings-popup-choice-option:focus-visible {
    outline: 3px solid #ffffff;
    outline-offset: 2px;
}

.settings-popup-choice-hint {
    flex-basis: 100%;
    margin: 0;
    font-size: 13px;
    line-height: 1.35;
    color: var(--rp-dialog-text, #c0c8e0);
    opacity: 0.8;
}

.settings-popup-toggle {
    min-width: 104px;
    min-height: 48px;
    padding: 4px 6px 4px 12px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    border: 0;
    border-radius: 24px;
    color: var(--rp-dialog-toggle-text, var(--rp-dialog-text, #c0c8e0));
    background: var(--rp-dialog-toggle-bg, rgba(255, 255, 255, 0.08));
    cursor: pointer;
    font: inherit;
    font-weight: 700;
}

.settings-popup-toggle::after {
    content: '';
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: #ffffff;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.24);
    transition: transform 0.2s ease;
}

.settings-popup-toggle.active {
    color: var(--rp-dialog-toggle-on-text, var(--rp-dialog-primary-text, #ffffff));
    background: var(--rp-dialog-toggle-on-bg, var(--rp-dialog-primary-bg, var(--settings-accent, #ff3b6f)));
}

.settings-popup-toggle.active::after {
    transform: scale(0.78);
}

.settings-popup-toggle:focus-visible {
    outline: 3px solid #ffffff;
    outline-offset: 3px;
}

.settings-popup-done {
    width: 100%;
    padding: 14px;
    border: none;
    border-radius: var(--rp-dialog-btn-radius, 30px);
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    font-family: inherit;
    background: var(--rp-dialog-primary-bg, linear-gradient(135deg, var(--settings-accent, #ff3b6f), var(--settings-accent-dark, #cc2f59)));
    color: var(--rp-dialog-primary-text, white);
    box-shadow: var(--rp-dialog-primary-shadow, none);
}

.btn-additional-settings {
    width: 100%;
    background: transparent;
    border: 2px solid var(--settings-accent, #ff3b6f);
    color: var(--text-primary, #ffffff);
    padding: 16px;
    border-radius: 30px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s;
    font-family: inherit;
    margin-bottom: 12px;
}

.btn-additional-settings:hover {
    background: color-mix(in srgb, var(--settings-accent, #ff3b6f) 10%, transparent);
}

.btn-additional-settings:active {
    transform: scale(0.98);
}

/* «Предложить идею»: a quiet text button under the app rows, and the idea form drawn in the
   same modal. Colours come from currentColor so every Game Theme's modal palette applies. */
.settings-popup-row-idea { justify-content: center; }
.settings-popup-idea,
.settings-popup-idea-back {
    min-height: 44px;
    padding: 8px 12px;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
    opacity: 0.8;
    cursor: pointer;
}
.settings-popup-idea-back { align-self: center; }
.settings-popup-idea:focus-visible,
.settings-popup-idea-back:focus-visible,
.settings-popup-idea-text:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.settings-popup-idea-hint,
.settings-popup-idea-thanks {
    margin: 0;
    font-size: 15px;
    line-height: 1.4;
    text-align: center;
    opacity: 0.85;
}
.settings-popup-idea-thanks { font-size: 17px; opacity: 1; padding: 16px 0; }
.settings-popup-idea-text {
    width: 100%;
    min-height: 112px;
    padding: 12px;
    box-sizing: border-box;
    border: 1px solid color-mix(in srgb, currentColor 30%, transparent);
    border-radius: 16px;
    background: color-mix(in srgb, currentColor 6%, transparent);
    color: inherit;
    font: inherit;
    font-size: 16px;
    resize: vertical;
}
.settings-popup-idea-text::placeholder { color: inherit; opacity: 0.55; }
.settings-popup-idea-status { margin: 0; min-height: 18px; font-size: 14px; color: var(--rp-wrong, #ff8a9a); text-align: center; }
.settings-popup-done:disabled { opacity: 0.5; cursor: default; }

/* `type: 'link'` row: opens a game's own sub-screen. Summary text + chevron, same control
   surface as the steppers so it reads as part of the same sheet. */
.settings-popup-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    max-width: 55%;
    min-height: 48px;
    padding: 4px 12px 4px 16px;
    border: 0;
    border-radius: 14px;
    background: var(--rp-dialog-control-bg, rgba(255, 255, 255, 0.06));
    color: var(--rp-dialog-value, var(--rp-dialog-title, #ffffff));
    font: inherit;
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
}

.settings-popup-link-value {
    min-width: 0;
    overflow-wrap: anywhere;
    text-align: right;
}

.settings-popup-link::after {
    content: '';
    flex-shrink: 0;
    width: 8px;
    height: 8px;
    border-right: 2.1px solid currentColor;
    border-top: 2.1px solid currentColor;
    border-radius: 1px;
    transform: rotate(45deg);
    margin-right: 4px;
}

.settings-popup-link:active {
    background: var(--rp-dialog-control-btn-active, rgba(255, 255, 255, 0.15));
}

.settings-popup-link:focus-visible {
    outline: 3px solid currentColor;
    outline-offset: 2px;
}

/* «Получи до 7 500 ₽ за рекомендацию RoomPlay. Как?»: the video task's quiet button (video-task.css) as a settings row. */
.settings-popup-row-earn { justify-content: center; }
.settings-popup-earn.rp-video-task-cta { margin: 0; justify-content: center; }
/* /pause-overlay.css */
/*
 * Shared round pause button + overlay (see pause-overlay.js). Load before the game's styles.css;
 * game themes keep overriding .btn-pause / .pause-overlay / .pause-overlay-text directly.
 * Per-game differences go through custom properties (fallbacks are the common look):
 *   --pause-btn-bg, --pause-btn-border, --pause-btn-color, --pause-btn-padding,
 *   --pause-btn-font-size, --pause-btn-hover-bg, --pause-btn-hover-color,
 *   --pause-overlay-bg, --pause-overlay-text-color.
 * Layout-only properties (align-self, flex-shrink, min-height, z-index) stay in the game.
 * The overlay is position:absolute — the game's screen must be its positioned ancestor.
 */
.btn-pause {
    background: var(--pause-btn-bg, rgba(255, 255, 255, 0.1));
    border: 1px solid var(--pause-btn-border, rgba(255, 255, 255, 0.2));
    color: var(--pause-btn-color, var(--text-secondary));
    padding: var(--pause-btn-padding, 6px 16px);
    border-radius: 16px;
    font-size: var(--pause-btn-font-size, 13px);
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s ease;
    white-space: nowrap;
}

@media (hover: hover) {
    .btn-pause:hover {
        background: var(--pause-btn-hover-bg, rgba(255, 255, 255, 0.2));
        color: var(--pause-btn-hover-color, var(--text-primary));
    }
}

.pause-overlay {
    display: none;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: var(--pause-overlay-bg, rgba(13, 19, 41, 0.95));
    z-index: 50;
    align-items: center;
    justify-content: center;
}

.pause-overlay.active {
    display: flex;
    cursor: pointer;
}

.pause-overlay-text {
    font-size: 32px;
    font-weight: 700;
    color: var(--pause-overlay-text-color, var(--text-secondary));
}

/*
 * Online games (shared/client/online-pause.ts): the host's «Пауза» button (in the round's header, else in the top right corner) and
 * the «Пауза» / «Ждём хоста…» screen every phone sees over the game. Same tokens as above.
 */
.rp-online-pause-btn {
    position: fixed;
    top: calc(20px + env(safe-area-inset-top, 0px));
    right: 16px;
    z-index: 60;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 36px;
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}
.rp-online-pause-btn[hidden] { display: none; }
/* Inside the round's .game-header: between the round title and the timer. */
.rp-online-pause-btn--inline {
    position: static;
    flex-shrink: 0;
    margin: 0 8px;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}

#online-pause-overlay.pause-overlay--online,
#pause-overlay.pause-overlay--local,
.pause-overlay.pause-overlay--local.pause-overlay--local {
    /* One palette in every game (owner 2026-10-21: game themes made the title unreadable): a dark
       scrim with white text, whatever the game's own --text-* and --pause-* tokens are. */
    --rp-pause-ink: #ffffff;
    --rp-pause-muted: rgba(255, 255, 255, 0.74);
    --rp-pause-chip: rgba(255, 255, 255, 0.12);
    --rp-pause-line: rgba(255, 255, 255, 0.26);
    background: rgba(9, 11, 20, 0.9);
    color: var(--rp-pause-ink);
    position: fixed;
    z-index: 980;
    padding: 24px 16px;
    box-sizing: border-box;
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}
.pause-overlay--online.active {
    cursor: default;
    animation: rp-pause-in 220ms ease-out;
}
.rp-pause-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    width: 100%;
    max-width: 340px;
    text-align: center;
}
.rp-pause-badge {
    display: grid;
    place-items: center;
    width: 76px;
    height: 76px;
    margin-bottom: 4px;
    border-radius: 50%;
    background: var(--rp-pause-chip);
    border: 1px solid var(--rp-pause-line);
    color: var(--rp-pause-ink);
    font-size: 30px;
}
.pause-overlay--away .rp-pause-badge .rp-icon { animation: rp-pause-wait 1.6s ease-in-out infinite; }
#online-pause-overlay .pause-overlay-text,
.pause-overlay--local .pause-overlay-text { color: var(--rp-pause-ink); }
/* One-phone games (pause-overlay.js): the same card; a tap anywhere still resumes. */
.pause-overlay--local.active { animation: rp-pause-in 220ms ease-out; }
/* «Ждём игрока…»: the player the game waits on, as an avatar chip. */
.rp-pause-player {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    max-width: 100%;
    padding: 4px 14px 4px 4px;
    border-radius: 999px;
    background: var(--rp-pause-chip);
    border: 1px solid var(--rp-pause-line);
    color: var(--rp-pause-ink);
    font-weight: 600;
}
.rp-pause-player[hidden] { display: none; }
.rp-pause-player-avatar {
    display: grid;
    place-items: center;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--rp-pause-line);
    font-size: 13px;
    font-weight: 700;
}
.rp-pause-player-avatar img { width: 100%; height: 100%; object-fit: cover; }
.rp-pause-player-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rp-pause-hint {
    font-size: 15px;
    line-height: 1.4;
    color: var(--rp-pause-muted);
}
/* Room code and join QR on the network pause (owner 2026-11-02: «добавь qr и код комнаты в паузу телефона»):
   the room screen's invite card (client/create-room .invite-card) in the pause palette. Tap on the code copies
   the invite. Not on the /tv/ screen, which shows its own code. */
.rp-pause-invite {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    padding: 10px 12px;
    box-sizing: border-box;
    border-radius: 18px;
    background: var(--rp-pause-chip);
    border: 1px solid var(--rp-pause-line);
    text-align: left;
}
.rp-pause-invite-side { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.rp-pause-invite-label {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--rp-pause-muted);
}
.rp-pause-invite-code {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-height: 42px;
    padding: 4px 12px 4px 14px;
    background: transparent;
    color: var(--rp-pause-ink);
    border: 1.5px solid var(--rp-pause-line);
    border-radius: 12px;
    font: 800 24px/1.1 monospace;
    letter-spacing: 5px;
    cursor: pointer;
    transition: transform 0.12s ease;
}
.rp-pause-invite-code:active { transform: scale(0.97); }
.rp-pause-invite-copy {
    width: 20px; height: 20px; flex-shrink: 0; opacity: 0.8;
    fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
    transition: opacity 0.2s ease;
}
.rp-pause-invite-code.is-copied .rp-pause-invite-copy { opacity: 0; }
.rp-pause-invite-qr {
    width: 84px;
    height: 84px;
    flex-shrink: 0;
    padding: 5px;
    box-sizing: border-box;
    border-radius: 12px;
    background: #ffffff;
    image-rendering: pixelated;
}
#online-pause-overlay.tv-pause .rp-pause-invite { display: none; }
#online-pause-overlay .rp-pause-resume,
.pause-overlay--local .rp-pause-resume.rp-pause-resume {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    margin-top: 12px;
    /* The same light pill in every game, not the game's .btn-play colours. */
    background: var(--rp-pause-ink);
    color: #12131a;
    border: none;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.rp-pause-exit {
    margin-top: 4px;
    padding: 10px 16px;
    background: none;
    border: none;
    color: var(--rp-pause-muted);
    font: inherit;
    font-size: 15px;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}
.pause-overlay--online [hidden] { display: none; }
/* The host's «Убрать игрока» (shared/client/online-pause.ts): an outlined action on the card, like «Завершить
   игру»; it swaps the card for the list (avatar chips with the room screen's quiet ✕, client/create-room
   .player-remove), which scrolls for any number of players; «Назад» brings the card back. */
.rp-pause-roster-open,
.rp-pause-roster-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: 52px;
    padding: 0 18px;
    border-radius: 30px;
    border: 2px solid var(--rp-pause-line, rgba(255, 255, 255, 0.26));
    background: transparent;
    color: var(--rp-pause-ink, #ffffff);
    font: inherit;
    font-size: 16px;
    font-weight: 700;
    cursor: pointer;
    transition: transform 0.12s ease;
}
.rp-pause-roster-open:active,
.rp-pause-roster-back:active { transform: scale(0.97); }
.rp-pause-card--roster > :not(.rp-pause-roster) { display: none !important; }
.rp-pause-roster {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 14px;
    width: 100%;
}
.rp-pause-roster-title { text-align: center; }
.rp-pause-roster-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    /* Ten and more players scroll here; the title and «Назад» stay on screen. */
    max-height: calc(100vh - 240px);
    max-height: calc(100dvh - 240px);
    overflow-y: auto;
    overscroll-behavior: contain;
}
.rp-pause-roster-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.rp-pause-roster-chip { min-width: 0; }
.rp-pause-roster-row--offline .rp-pause-roster-chip { opacity: 0.45; }
/* «Ушёл»: quiet, like the room screen's «Не в сети», between the chip and the ✕. */
.rp-pause-roster-status {
    margin-left: auto;
    font-size: 13px;
    font-weight: 600;
    color: var(--rp-pause-muted);
    white-space: nowrap;
}
.rp-pause-remove {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--rp-pause-muted);
    cursor: pointer;
    transition: transform 0.12s ease;
}
.rp-pause-remove::after { content: ''; position: absolute; inset: -4px; }
.rp-pause-remove:active { color: #f43f5e; background: rgba(244, 63, 94, 0.13); transform: scale(0.92); }
.rp-pause-remove svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }

/* The game behind the pause stops on the spot: its animations hold until the game goes on. */
html.rp-game-paused .screen,
html.rp-game-paused .screen *,
html.rp-game-paused .screen *::before,
html.rp-game-paused .screen *::after {
    animation-play-state: paused !important;
}

@keyframes rp-pause-in {
    from { opacity: 0; }
    to { opacity: 1; }
}
@keyframes rp-pause-wait {
    0%, 100% { transform: rotate(0deg); }
    50% { transform: rotate(180deg); }
}
@media (prefers-reduced-motion: reduce) {
    .pause-overlay--online.active,
    .pause-overlay--away .rp-pause-badge .rp-icon { animation: none; }
}
/* /content-report.css */
/*
 * Content report sheet (client/assets/js/content-report.js) and the small flag button
 * games put on their card. Shared component: games only set the --rp-report-* tokens.
 * Defaults sit in :where(:root) (zero specificity), so a game theme's :root tokens win whether
 * its stylesheet loads before or after this one.
 */
:where(:root) {
    --rp-report-surface: #1f2438;
    --rp-report-text: #ffffff;
    --rp-report-muted: #a7aec8;
    --rp-report-line: rgba(255, 255, 255, 0.14);
    --rp-report-chip: rgba(255, 255, 255, 0.08);
    --rp-report-accent: #ff3b6f;
    --rp-report-accent-ink: #ffffff;
    --rp-report-error: var(--rp-wrong, #ff8a9a);
    --rp-report-radius: 24px;
    --rp-report-button-radius: 30px;
    --rp-report-flag: rgba(255, 255, 255, 0.55);
}

/* Flag button on the card: 44 px hit area, quiet until pressed. */
.rp-report-flag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--rp-report-flag);
    font-size: 18px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: color 150ms ease, background-color 150ms ease, transform 150ms ease;
}
.rp-report-flag:active { transform: scale(0.9); background: rgba(255, 255, 255, 0.08); }
.rp-report-flag:focus-visible { outline: 2px solid var(--rp-report-accent); outline-offset: 2px; }
@media (hover: hover) { .rp-report-flag:hover { color: var(--rp-report-text); } }

.rp-report {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    pointer-events: none;
}
.rp-report.is-open { pointer-events: auto; }
.rp-report__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    opacity: 0;
    transition: opacity 200ms ease;
}
.rp-report.is-open .rp-report__backdrop { opacity: 1; }

.rp-report__sheet {
    position: relative;
    width: 100%;
    max-width: 440px;
    max-height: calc(100dvh - 24px);
    overflow-y: auto;
    padding: 24px 16px calc(16px + env(safe-area-inset-bottom, 0px));
    border-radius: var(--rp-report-radius) var(--rp-report-radius) 0 0;
    background: var(--rp-report-surface);
    color: var(--rp-report-text);
    font-family: inherit;
    transform: translateY(100%);
    transition: transform 240ms cubic-bezier(.2, .9, .3, 1);
}
.rp-report.is-open .rp-report__sheet { transform: none; }
@media (min-width: 600px) and (min-height: 560px) {
    .rp-report { align-items: center; padding: 24px; }
    .rp-report__sheet { border-radius: var(--rp-report-radius); padding-bottom: 20px; }
}

.rp-report__title {
    margin: 0 0 8px;
    font-family: Unbounded, Manrope, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 20px;
    font-weight: 800;
    letter-spacing: -0.035em;
    line-height: 1.2;
    text-wrap: balance;
}
.rp-report__card {
    margin: 0 0 16px;
    padding: 8px 12px;
    border-left: 3px solid var(--rp-report-accent);
    border-radius: 4px;
    background: var(--rp-report-chip);
    color: var(--rp-report-muted);
    font-size: 15px;
    line-height: 1.4;
    overflow-wrap: anywhere;
}
.rp-report__reasons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 12px;
}
.rp-report__chip {
    min-height: 44px;
    padding: 8px 16px;
    border: 1px solid var(--rp-report-line);
    border-radius: 999px;
    background: var(--rp-report-chip);
    color: var(--rp-report-text);
    font: inherit;
    font-size: 16px;
    cursor: pointer;
    transition: background-color 150ms ease, border-color 150ms ease, transform 150ms ease;
}
.rp-report__chip:active { transform: scale(0.96); }
.rp-report__chip[aria-pressed="true"] {
    border-color: var(--rp-report-accent);
    background: var(--rp-report-accent);
    color: var(--rp-report-accent-ink);
}
.rp-report__comment {
    display: block;
    width: 100%;
    min-height: 64px;
    padding: 12px;
    border: 1px solid var(--rp-report-line);
    border-radius: 16px;
    background: transparent;
    color: var(--rp-report-text);
    font: inherit;
    font-size: 16px;
    resize: vertical;
    box-sizing: border-box;
}
.rp-report__comment::placeholder { color: var(--rp-report-muted); opacity: 1; }
.rp-report__status {
    min-height: 20px;
    margin: 8px 0;
    color: var(--rp-report-error);
    font-size: 14px;
}
.rp-report__actions {
    display: flex;
    gap: 8px;
}
.rp-report__button {
    flex: 1;
    min-height: 48px;
    padding: 12px 16px;
    border: 1px solid transparent;
    border-radius: var(--rp-report-button-radius);
    font: inherit;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
    transition: opacity 150ms ease, transform 150ms ease;
}
.rp-report__button:active:not(:disabled) { transform: scale(0.97); }
.rp-report__button--primary { background: var(--rp-report-accent); color: var(--rp-report-accent-ink); }
.rp-report__button--secondary { border-color: var(--rp-report-line); background: transparent; color: var(--rp-report-text); }
.rp-report__button:disabled { opacity: 0.45; cursor: default; }
.rp-report__chip:focus-visible,
.rp-report__button:focus-visible,
.rp-report__comment:focus-visible { outline: 2px solid var(--rp-report-accent); outline-offset: 2px; }

.rp-report__sheet.is-done {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    padding-top: 32px;
    text-align: center;
}
.rp-report__sheet.is-done .rp-report__button { flex: none; width: 100%; }
.rp-report__done-mark {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--rp-report-accent);
    position: relative;
}
.rp-report__done-mark::after {
    content: "";
    position: absolute;
    inset: 14px;
    background: var(--rp-report-accent-ink);
    -webkit-mask: var(--rp-icon-check, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E")) center / contain no-repeat;
    mask: var(--rp-icon-check, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E")) center / contain no-repeat;
}
.rp-report__done-text { margin: 0; font-size: 17px; line-height: 1.4; }

@media (prefers-reduced-motion: reduce) {
    .rp-report__backdrop,
    .rp-report__sheet,
    .rp-report-flag,
    .rp-report__chip,
    .rp-report__button { transition: none; }
}

/* Like / dislike under the card (ContentReport.attachVotes): quiet thumbs, filled when chosen. */
.rp-card-vote[hidden] { display: none; }
.rp-card-vote {
    display: flex;
    justify-content: center;
    gap: 6px;
}
.rp-card-vote__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--rp-report-flag);
    font-size: 20px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: color 150ms ease, background-color 150ms ease, transform 150ms ease;
}
.rp-card-vote__btn--dislike .rp-icon { transform: rotate(180deg); }
.rp-card-vote__btn--report { margin-left: 6px; color: var(--rp-report-flag); font-size: 18px; }
.rp-card-vote__btn[aria-pressed="true"] { color: var(--rp-report-accent); }
.rp-card-vote__btn:active { transform: scale(0.88); background: rgba(255, 255, 255, 0.08); }
.rp-card-vote__btn:focus-visible { outline: 2px solid var(--rp-report-accent); outline-offset: 2px; }
@media (hover: hover) { .rp-card-vote__btn:hover:not([aria-pressed="true"]) { color: var(--rp-report-text); } }
/* Thumbs + flag as the last row inside a content card (word, task, location): one look in every game.
   The game sets --rp-report-flag on its card to a muted tone of the card's ink (light cards need a dark one). */
.rp-card-vote--in-card { margin: 14px -8px -14px; }
.rp-card-vote--in-card .rp-card-vote__btn--report { margin-left: 0; }
@media (prefers-reduced-motion: no-preference) {
    .rp-card-vote__btn[aria-pressed="true"] .rp-icon { animation: rp-card-vote-pop 260ms ease-out; }
    .rp-card-vote__btn--dislike[aria-pressed="true"] .rp-icon { animation-name: rp-card-vote-pop-down; }
}
@keyframes rp-card-vote-pop { 0% { transform: scale(0.7); } 60% { transform: scale(1.18); } 100% { transform: scale(1); } }
@keyframes rp-card-vote-pop-down { 0% { transform: rotate(180deg) scale(0.7); } 60% { transform: rotate(180deg) scale(1.18); } 100% { transform: rotate(180deg) scale(1); } }
/* /reveal-results.css */
/* ========================================
   Reveal Results — Shared Module Styles
   2-screen round-end reveal with animations

   Colours default to a dark game. A light Game Theme sets the component tokens on its page
   instead of restyling each class: --rr-ink / --rr-muted (text on the page),
   --rr-card-ink / --rr-card-muted (text on cards and rows, default to the page ones),
   --rr-surface / --rr-border (cards and rows), --rr-leading-surface / --rr-leading-border
   (the leader's row), --rr-correct-surface / --rr-wrong-surface / --rr-correct-text (answer
   cards; default to tints of --rp-correct / --rp-wrong).
   ======================================== */

/* Container */
.rr-container {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  z-index: 5;
}

/* In-flow variant (container with .rr-flow, e.g. Геоугадайка under its results map): the reveal
   follows the content above it and the page's screen scrolls, instead of covering the screen.
   The shown screen stays in flow; the hidden one leaves it so it adds no empty space. */
.rr-flow > .rr-container {
  position: relative;
  inset: auto;
  flex: none;
}

.rr-flow > .rr-container > .rr-screen1,
.rr-flow > .rr-container > .rr-screen2 {
  position: absolute;
  inset: 0 0 auto;
  overflow: visible;
  padding-top: 8px;
}

.rr-flow > .rr-container > .rr-screen1:not(.rr-hidden),
.rr-flow > .rr-container > .rr-screen2.rr-visible {
  position: relative;
}

/* ========== Screen 1: Votes Reveal ========== */

.rr-screen1,
.rr-screen2 {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  padding: 20px;
  padding-top: calc(56px + env(safe-area-inset-top, 0px));
  padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px));
  transition: opacity 0.4s ease, transform 0.4s ease;
}

.rr-screen1.rr-hidden {
  opacity: 0;
  transform: translateX(-30px);
  pointer-events: none;
}

.rr-screen2 {
  opacity: 0;
  transform: translateX(30px);
  pointer-events: none;
}

.rr-screen2.rr-visible {
  opacity: 1;
  transform: translateX(0);
  pointer-events: auto;
}

/* Context area (question / image) */
.rr-context {
  text-align: center;
  margin-bottom: 20px;
  opacity: 0;
  animation: rrFadeIn 0.4s ease forwards;
}

.rr-context-text {
  font-size: 18px;
  font-weight: 600;
  color: var(--rr-ink, #fff);
  line-height: 1.4;
}

.rr-context-subtext {
  font-size: 14px;
  color: var(--rr-muted, rgba(255, 255, 255, 0.6));
  margin-top: 8px;
}

/* A part that gives the round away (ctx.atEnd in reveal-results.js) keeps its place and fades in with the last answer. */
.rr-context .rr-held,
.rr-context .rr-held-done {
  transition: opacity 0.5s ease;
}

.rr-context .rr-held {
  opacity: 0;
  visibility: hidden;
}

.rr-context-image {
  max-width: 200px;
  max-height: 150px;
  border-radius: 12px;
  margin: 0 auto 8px;
  display: block;
  object-fit: cover;
}

.rr-context-fourphoto {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px;
  width: 200px;
  margin: 0 auto 8px;
  border-radius: 10px;
  overflow: hidden;
}

.rr-context-fourphoto img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
  display: block;
  background: var(--bg-card, #252b4a);
}

.rr-context-drawing {
  max-width: 240px;
  max-height: 200px;
  border-radius: 12px;
  margin: 0 auto 8px;
  display: block;
  background: #fff;
  object-fit: contain;
}

/* Options list */
.rr-options {
  display: flex;
  flex-direction: column;
  gap: 12px;
  flex: 1;
}

/* Single option card */
.rr-option {
  background: var(--rr-surface, rgba(255, 255, 255, 0.06));
  border: 1px solid var(--rr-border, rgba(255, 255, 255, 0.1));
  border-radius: 14px;
  padding: 14px 16px;
  opacity: 0;
  transform: translateX(-20px);
  transition: opacity 0.9s ease, transform 0.9s ease;
}

.rr-option.rr-visible {
  opacity: 1;
  transform: translateX(0);
}

/* Correct option styling: tone comes from the game's --rp-correct; the ✓ mark carries the meaning without colour. */
.rr-option.rr-type-correct {
  background: var(--rr-correct-surface, color-mix(in srgb, var(--rp-correct, #4ade80) 12%, transparent));
  border-color: color-mix(in srgb, var(--rp-correct, #4ade80) 45%, transparent);
}

.rr-option.rr-type-correct .rr-option-text {
  color: var(--rr-correct-text, var(--rp-correct, #4ade80));
}

/* Wrong option styling */
.rr-option.rr-type-wrong {
  background: var(--rr-wrong-surface, color-mix(in srgb, var(--rp-wrong, #f87171) 8%, transparent));
  border-color: color-mix(in srgb, var(--rp-wrong, #f87171) 22%, transparent);
}

/* Answer marks: shared upright ✓ / ✕ from answer-marks.css (shape, not only colour). */
.rr-option.rr-type-correct .rr-option-text::before,
.rr-option.rr-type-wrong .rr-option-text::before {
  content: "";
  display: inline-block;
  width: 22px;
  height: 22px;
  margin-right: 8px;
  vertical-align: -5px;
  -webkit-mask: var(--rp-icon-check-badge) center / contain no-repeat;
  mask: var(--rp-icon-check-badge) center / contain no-repeat;
}

.rr-option.rr-type-correct .rr-option-text::before {
  background-color: var(--rr-correct-text, var(--rp-correct, #4ade80));
}

.rr-option.rr-type-wrong .rr-option-text::before {
  -webkit-mask-image: var(--rp-icon-cross-badge);
  mask-image: var(--rp-icon-cross-badge);
  background-color: var(--rp-wrong, #f87171);
}

.rr-option-text:empty::before {
  display: none !important;
}

/* Neutral option (Quiplash loser, etc.) */
.rr-option.rr-type-neutral {
  background: var(--rr-surface, rgba(255, 255, 255, 0.04));
  border-color: var(--rr-border, rgba(255, 255, 255, 0.08));
}

/* Option header */
.rr-option-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.rr-option-text {
  font-size: 17px;
  font-weight: 600;
  color: var(--rr-card-ink, var(--rr-ink, #fff));
  flex: 1;
  word-break: break-word;
}

.rr-option-badge {
  font-size: 12px;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: 8px;
  white-space: nowrap;
  flex-shrink: 0;
}

.rr-option.rr-type-correct .rr-option-badge {
  background: color-mix(in srgb, var(--rp-correct, #4ade80) 20%, transparent);
  color: var(--rp-correct, #4ade80);
}

.rr-badge-quiplash {
  background: linear-gradient(135deg, #f59e0b, #ef4444) !important;
  color: #fff !important;
  font-size: 12px !important;
  padding: 3px 10px !important;
  animation: rrPulse 0.6s ease;
}

/* Vote count (Quiplash) */
.rr-vote-count {
  font-size: 14px;
  font-weight: 700;
  color: var(--rr-muted, rgba(255, 255, 255, 0.7));
  margin-left: auto;
  flex-shrink: 0;
}

/* Option image (Imaginarium cards) */
.rr-option-image-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  padding: 4px 0;
}

.rr-option-image-card {
  width: calc(33.333% - 8px);
  min-width: 90px;
  max-width: 120px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--rr-surface, rgba(255, 255, 255, 0.06));
  border: 2px solid var(--rr-border, rgba(255, 255, 255, 0.1));
  opacity: 0;
  transform: scale(0.9);
  transition: opacity 0.4s ease, transform 0.4s ease;
}

.rr-option-image-card.rr-visible {
  opacity: 1;
  transform: scale(1);
}

.rr-option-image-card.rr-type-correct {
  position: relative;
  border-color: color-mix(in srgb, var(--rp-correct, #4ade80) 70%, transparent);
  box-shadow: 0 0 12px color-mix(in srgb, var(--rp-correct, #4ade80) 30%, transparent);
}

.rr-option-image-card.rr-type-correct::before,
.rr-option-image-card.rr-type-correct::after {
  content: "";
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 1;
  width: 24px;
  height: 24px;
}

.rr-option-image-card.rr-type-correct::before {
  border-radius: 50%;
  background: var(--rp-correct, #4ade80);
}

.rr-option-image-card.rr-type-correct::after {
  z-index: 2;
  background-color: var(--rp-correct-ink, #17191f);
  -webkit-mask: var(--rp-icon-check) center / 15px no-repeat;
  mask: var(--rp-icon-check) center / 15px no-repeat;
}

.rr-option-image-card img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  display: block;
}

/* Three-panel comic option (Joking Hazard). It stays readable on phones
   instead of shrinking all panels into a single narrow thumbnail. */
.rr-option-image-card.rr-option-comic {
  width: 100%;
  min-width: 0;
  max-width: 620px;
}

.rr-option-comic-strip {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  padding: 6px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
}

.rr-option-comic-strip img {
  aspect-ratio: 295 / 420;
  border-radius: 8px;
}

.rr-option-image-info {
  padding: 6px 8px;
}

.rr-option-image-owner {
  font-size: 11px;
  font-weight: 600;
  color: var(--rr-card-ink, var(--rr-ink, #fff));
}

.rr-option-image-voters {
  font-size: 10px;
  color: var(--rr-muted, rgba(255, 255, 255, 0.5));
  margin-top: 2px;
}

/* «Автор:» / «Голосовали:» before the names on an image card (option.whoLabels, «Что за мем» 2026-11-02). */
.rr-option-image-label {
  font-weight: 500;
  color: var(--rr-muted, rgba(255, 255, 255, 0.5));
  margin-right: 4px;
}

.rr-option-image-owner .rr-author-points {
  margin-left: auto;
}

/* Author label */
.rr-author {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 13px;
  color: var(--rr-muted, rgba(255, 255, 255, 0.5));
  margin-top: 8px;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.75s ease, transform 0.75s ease;
}

.rr-author.rr-visible {
  opacity: 1;
  transform: translateY(0);
}

.rr-author-label {
  color: var(--rr-muted, rgba(255, 255, 255, 0.4));
}

.rr-author-name {
  color: #ff9f43;
  font-weight: 600;
}

.rr-author-points {
  color: var(--rp-correct, #4ade80);
  font-weight: 600;
  margin-left: 4px;
}

/* Voters list */
.rr-voters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 10px;
  align-items: center;
}

.rr-voters-label {
  font-size: 13px;
  color: var(--rr-muted, rgba(255, 255, 255, 0.4));
  font-weight: 500;
}

.rr-voter {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  padding: 4px 10px;
  border-radius: 10px;
  background: var(--rr-surface, rgba(255, 255, 255, 0.08));
  color: var(--rr-muted, rgba(255, 255, 255, 0.8));
  opacity: 0;
  transform: scale(0.8);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.rr-voter.rr-visible {
  opacity: 1;
  transform: scale(1);
}

/* Player avatar (reveal-results.js _playerAvatar): photo, or the name's first letter on an accent tile. */
.rr-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent-purple, #8b5cf6) 45%, transparent);
  color: #fff;
  font-weight: 700;
  line-height: 1;
}

.rr-avatar.has-photo {
  background: none;
}

.rr-avatar img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  transform: scale(1.5);
}

.rr-voter-avatar,
.rr-author-avatar {
  width: 18px;
  height: 18px;
  font-size: 10px;
}

.rr-owner-avatar {
  width: 14px;
  height: 14px;
  font-size: 8px;
  margin-right: 4px;
  vertical-align: middle;
}

.rr-option-image-voter {
  display: inline-flex;
  align-items: center;
}

.rr-voter-points {
  color: var(--rp-correct, #4ade80);
  font-weight: 700;
  font-size: 12px;
}

/* ========== Screen 2: Leaderboard ========== */

.rr-leaderboard-title {
  text-align: center;
  font-size: 17px;
  font-weight: 700;
  color: var(--rr-muted, rgba(255, 255, 255, 0.6));
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-bottom: 20px;
  opacity: 0;
  animation: rrFadeIn 0.3s ease forwards;
}

.rr-leaderboard {
  display: flex;
  flex-direction: column;
  gap: 8px;
  position: relative;
}

.rr-lb-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: var(--rr-surface, rgba(255, 255, 255, 0.06));
  border: 1px solid var(--rr-border, rgba(255, 255, 255, 0.08));
  border-radius: 14px;
  transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1), background 0.3s ease, border-color 0.3s ease;
  position: relative;
}

.rr-lb-row.rr-leading {
  background: var(--rr-leading-surface, rgba(255, 255, 255, 0.1));
  border-color: var(--rr-leading-border, rgba(255, 255, 255, 0.15));
}

.rr-lb-pos {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
  color: var(--rr-muted, rgba(255, 255, 255, 0.5));
  background: var(--rr-surface, rgba(255, 255, 255, 0.08));
  flex-shrink: 0;
}

.rr-lb-pos.rr-gold { background: linear-gradient(135deg, #f59e0b, #d97706); color: #fff; }
.rr-lb-pos.rr-silver { background: linear-gradient(135deg, #9ca3af, #6b7280); color: #fff; }
.rr-lb-pos.rr-bronze { background: linear-gradient(135deg, #d97706, #92400e); color: #fff; }

.rr-lb-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  object-fit: contain;
  flex-shrink: 0;
  transform: scale(1.5);
}

.rr-lb-name {
  flex: 1;
  font-size: 16px;
  font-weight: 600;
  color: var(--rr-card-ink, var(--rr-ink, #fff));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rr-lb-score-area {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

.rr-lb-score {
  font-size: 17px;
  font-weight: 700;
  color: var(--rr-card-ink, var(--rr-ink, #fff));
  min-width: 40px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.rr-lb-delta {
  font-size: 13px;
  font-weight: 700;
  color: var(--rr-correct-text, var(--rp-correct, #4ade80));
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.3s ease, transform 0.3s ease;
  white-space: nowrap;
}

.rr-lb-delta.rr-visible {
  opacity: 1;
  transform: translateY(0);
}

.rr-lb-delta.rr-zero {
  color: var(--rr-card-muted, var(--rr-muted, rgba(255, 255, 255, 0.3)));
}

/* Row swap animation */
.rr-lb-row.rr-swapping {
  z-index: 2;
}

/* ========== Keyframes ========== */

@keyframes rrFadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes rrPulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.15); }
  100% { transform: scale(1); }
}

@keyframes rrFloatUp {
  0% { opacity: 0; transform: translateY(8px); }
  30% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-20px); }
}

/* ========== Dashboard wide layout ========== */

.rr-container.rr-dashboard .rr-screen1,
.rr-container.rr-dashboard .rr-screen2 {
  padding: 32px 40px;
}

.rr-container.rr-dashboard .rr-context-text {
  font-size: 24px;
}

.rr-container.rr-dashboard .rr-option {
  padding: 18px 22px;
}

.rr-container.rr-dashboard .rr-option-text {
  font-size: 20px;
}

.rr-container.rr-dashboard .rr-voter {
  font-size: 15px;
  padding: 5px 12px;
}

.rr-container.rr-dashboard .rr-author {
  font-size: 15px;
}

.rr-container.rr-dashboard .rr-lb-row {
  padding: 16px 22px;
}

.rr-container.rr-dashboard .rr-lb-name {
  font-size: 19px;
}

.rr-container.rr-dashboard .rr-lb-score {
  font-size: 20px;
}

.rr-container.rr-dashboard .rr-lb-delta {
  font-size: 15px;
}

.rr-container.rr-dashboard .rr-leaderboard-title {
  font-size: 20px;
}

.rr-container.rr-dashboard .rr-option-image-card {
  max-width: 160px;
}

.rr-container.rr-dashboard .rr-option-image-card.rr-option-comic {
  max-width: 760px;
}

@media (max-width: 480px) {
  .rr-option-comic-strip {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: min(72vw, 260px);
    justify-content: start;
    scroll-snap-type: x mandatory;
  }

  .rr-option-comic-strip img {
    scroll-snap-align: center;
  }
}

/* Question blank highlight (for Fibbage) */
.rr-question-blank {
  color: var(--accent-pink, #ff3b6f);
  font-weight: 700;
  border-bottom: 2px solid var(--accent-pink, #ff3b6f);
  padding: 0 2px;
}

/* ========== One-phone turn results (quick mode) ========== */

/* Inline host: the reveal fills the space between the screen header and the game's own
   «Продолжить» button instead of covering the whole screen. */
.rr-host {
  position: relative;
  flex: 1 1 auto;
  min-height: 240px;
  width: 100%;
  /* One-phone games take the page's own text and card tokens (game-ui.css + the Game Theme). */
  --rr-ink: var(--text-primary, #fff);
  --rr-muted: var(--text-secondary, rgba(255, 255, 255, 0.6));
  --rr-surface: var(--bg-card, rgba(255, 255, 255, 0.06));
  --rr-border: color-mix(in srgb, var(--text-primary, #fff) 14%, transparent);
  --rr-leading-surface: var(--bg-card, rgba(255, 255, 255, 0.1));
  --rr-leading-border: color-mix(in srgb, var(--text-primary, #fff) 55%, transparent);
}

.rr-host .rr-screen1,
.rr-host .rr-screen2 {
  padding: 4px 2px 12px;
}

.rr-container.rr-quick .rr-screen1 {
  cursor: pointer;
}

.rr-container.rr-quick .rr-options {
  gap: 8px;
  flex: 0 0 auto;
}

.rr-container.rr-quick .rr-option {
  padding: 11px 14px;
  transition-duration: 0.45s;
}

.rr-container.rr-quick .rr-option-text {
  font-size: 16px;
}

/* Skipped answer (word games): shared skip icon instead of ✓ / ✕. */
.rr-option.rr-type-skipped .rr-option-text {
  color: var(--rr-card-muted, var(--rr-muted, rgba(255, 255, 255, 0.65)));
}

.rr-option.rr-type-skipped .rr-option-text::before {
  content: "";
  display: inline-block;
  width: 18px;
  height: 18px;
  margin: 0 10px 0 2px;
  vertical-align: -3px;
  background-color: currentColor;
  -webkit-mask: var(--rp-icon-skip) center / contain no-repeat;
  mask: var(--rp-icon-skip) center / contain no-repeat;
}

/* Leaderboard name with a team colour dot or a player chip (PlayerAvatar.html). */
.rr-lb-name--rich {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.rr-lb-color {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}

.rr-lb-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Flow host: the leaderboard sits in a scrolling page and takes the height of its rows. */
.rr-host.rr-host--flow {
  flex: 0 0 auto;
  min-height: 0;
}

.rr-host--flow .rr-container,
.rr-host--flow .rr-screen2 {
  position: relative;
  inset: auto;
  overflow: visible;
  padding: 0;
}

/* A player named in the question or the line under it («Что выбрал [нмг]?», «[Тата] +500: тебя знают!»): the
   «Аватарка с именем» chip as a pill, like the voters below. */
.rr-context :is(.rr-context-text, .rr-context-subtext) .rp-player {
  padding: .1em .6em .1em .1em;
  border-radius: 999px;
  background: var(--rr-surface, rgba(255, 255, 255, 0.1));
  white-space: nowrap;
}

/* Host's «Дальше» on the round reveal (shared/client/reveal-next.ts: every /tv/ game; Квиз has the same pill as
   .quiz-reveal-next). Fixed at the bottom; the reveal keeps room for it. */
.rr-next-btn:not([hidden]) {
  position: fixed;
  left: 50%;
  bottom: max(20px, env(safe-area-inset-bottom));
  /* Above a game's own layers (Рисовач cards), below pause (980) and popups (1000). */
  z-index: 900;
  translate: -50% 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 22px;
  border-radius: 999px;
  background: var(--bg-primary);
  box-shadow: 0 4px 14px rgb(0 0 0 / 25%);
  font-weight: 700;
}

body:has(.rr-next-btn:not([hidden])) :is(#round-results-screen, #reveal-screen) { padding-bottom: 84px; }
/* PC stage: the /tv/ reveal (dashboard, Геоугадайка map) keeps a strip for the pill, so it never sits on a card. */
html.rp-stage body:has(.rr-next-btn:not([hidden])) :is(.qs-reveal > .rr-container, #round-results-screen > .gss-root) { bottom: 80px; }
/* Phone: the answers scroll inside the reveal, so the last one can be scrolled above the pill (Рисовач). */
body:has(.rr-next-btn:not([hidden])) .rr-container:not(.rr-dashboard) .rr-options { padding-bottom: 76px; }
body:has(.rr-next-btn:not([hidden])) .rr-container:not(.rr-dashboard) .rr-option { scroll-margin-bottom: 84px; }
/* A game theme's outlined .btn-skip (Рисовач, Геоугадайка: transparent) must not let the reveal show through the pill. */
body .rr-next-btn.btn-skip:not([hidden]) { background: var(--bg-primary, #fff); }
/* /player-avatar.css */
/* PlayerAvatar — «avatar + name» chip for one-phone games (player-avatar.js).
   Sizes follow the surrounding font, so the same markup works in a turn title and in a result row.
   The emoji/initial tile uses the game theme: --ps-accent (player setup accent) or --accent. */

.rp-player {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    max-width: 100%;
    min-width: 0;
    vertical-align: middle;
}

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

.rp-player-avatar {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 1.6em;
    height: 1.6em;
    border-radius: 50%;
    overflow: hidden;
    background: color-mix(in srgb, var(--ps-accent, var(--accent, #7c5cff)) 28%, transparent);
    color: inherit;
    font-size: 1em;
    font-weight: 700;
    line-height: 1;
    vertical-align: middle;
    text-transform: none;
    letter-spacing: 0;
    user-select: none;
}

.rp-player-avatar--emoji {
    font-size: 0.95em;
    font-weight: 400;
}

.rp-player-avatar--initial,
.rp-player-avatar--image {
    font-size: 0.8em;
    width: 2em;
    height: 2em;
}

/* Photo/GIF avatars are cut-out stickers (transparent background), drawn like in online rooms
   (game-ui.css .player-avatar.has-photo): no tile, whole sticker, slightly enlarged past the box. */
.rp-player-avatar[data-rp-avatar-state="ready"] {
    background: none;
    overflow: visible;
    color: transparent;
}

.rp-player-avatar img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
    object-fit: contain;
    transform: scale(1.25);
}

/* Larger hero variant: «Ход игрока …», role cards. */
.rp-player--lg .rp-player-avatar {
    width: 1.9em;
    height: 1.9em;
}

.rp-player--lg .rp-player-avatar--initial,
.rp-player--lg .rp-player-avatar--image {
    width: 2.375em;
    height: 2.375em;
}

/* Stacked variant: big avatar above the name (pass-the-phone screens). */
.rp-player--stack {
    flex-direction: column;
    gap: 0.25em;
}

.rp-player--stack .rp-player-name {
    white-space: normal;
    overflow-wrap: anywhere;
    text-align: center;
}
/* /game-intro.css */
/*
 * Intro screen before a game («заставка»): RoomPlay logo, game icon and name, the players, while the host
 * says the greeting; it leaves through a portal into round 1. Markup and timing:
 * client/assets/js/game-intro.js. Colours come from the game's *-theme.css: --bg-primary, --bg-secondary,
 * --text-primary, --text-secondary, --rp-intro-accent (falls back to --rp-countdown-accent, then
 * --onboarding-accent) and --rp-intro-glow (falls back to --onboarding-accent). No emoji, no text of its own.
 */
/* Not inherited: the hole grows every frame, and an inherited value would restyle every node of the intro each frame
   (the stutter after the intro, owner 2026-10-29). The rim (.rp-intro-portal) runs the same animation itself. */
@property --rp-intro-hole {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

.rp-intro {
  --rp-in-accent: var(--rp-intro-accent, var(--rp-countdown-accent, var(--onboarding-accent, #a677ef)));
  --rp-in-glow: var(--rp-intro-glow, var(--onboarding-accent, var(--accent-primary, #6640ba)));
  --rp-in-ease: cubic-bezier(.2, .9, .3, 1.25);
  position: fixed;
  inset: 0;
  /* Over the speed games' start screen (995) and the game; below confirm dialogs (1000). */
  z-index: 996;
  overflow: hidden;
  color: var(--text-primary, #fff);
  font-family: var(--font-body, inherit);
  text-align: center;
  background:
    radial-gradient(ellipse at 50% 38%, color-mix(in srgb, var(--rp-in-glow) 55%, transparent) 0, transparent 58%),
    linear-gradient(180deg, var(--bg-secondary, #211759) 0%, var(--bg-primary, #100f36) 70%);
  opacity: 0;
  transition: opacity 240ms ease-out;
  user-select: none;
  -webkit-user-select: none;
}
.rp-intro.visible { opacity: 1; }

.rp-intro-backdrop { position: absolute; inset: 0; pointer-events: none; }
/* The rim of the portal: a glowing ring just outside the hole, growing with it. */
.rp-intro-portal {
  position: absolute;
  left: var(--rp-intro-x, 50%);
  top: var(--rp-intro-y, 40%);
  width: calc(var(--rp-intro-hole) * 2 + 16px);
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  border: 5px solid var(--rp-in-accent);
  box-shadow: 0 0 24px 6px color-mix(in srgb, var(--rp-in-accent) 70%, transparent), inset 0 0 18px 2px color-mix(in srgb, var(--rp-in-accent) 60%, transparent);
  opacity: 0;
  pointer-events: none;
}
/* Spotlight rays turning slowly behind the icon. */
.rp-intro-rays {
  position: absolute;
  left: 50%;
  top: 38%;
  width: 190vmax;
  aspect-ratio: 1;
  translate: -50% -50%;
  background: repeating-conic-gradient(from 0deg, color-mix(in srgb, var(--rp-in-accent) 16%, transparent) 0deg 7deg, transparent 7deg 20deg);
  -webkit-mask: radial-gradient(circle, #000 0, rgba(0, 0, 0, .7) 18%, transparent 46%);
  mask: radial-gradient(circle, #000 0, rgba(0, 0, 0, .7) 18%, transparent 46%);
  opacity: 0;
}
/* Small sparks drifting up, scattered at random (game-intro.js sparksNode): no grid. */
.rp-intro-sparks {
  position: absolute;
  inset: 0;
  opacity: 0;
}
.rp-intro-spark {
  position: absolute;
  width: var(--size, 3px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: rgba(255, 255, 255, .8);
  box-shadow: 0 0 calc(var(--size, 3px) * 1.6) rgba(255, 255, 255, .45);
  opacity: calc(var(--glow, .7) * .8);
}
.rp-intro-spark.accent {
  background: color-mix(in srgb, var(--rp-in-accent) 85%, #fff);
  box-shadow: 0 0 calc(var(--size, 3px) * 2) color-mix(in srgb, var(--rp-in-accent) 70%, transparent);
}

.rp-intro-stage {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: max(20px, env(safe-area-inset-top)) 16px max(36px, env(safe-area-inset-bottom));
  box-sizing: border-box;
}
/* Everything but the logo, centred in the space under it. */
.rp-intro-main {
  flex: 1;
  min-height: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: safe center;
  gap: clamp(10px, 2.4vh, 20px);
  padding-top: 12px;
}

.rp-intro-brand {
  flex: none;
  width: clamp(120px, 34vw, 170px);
  height: auto;
  /* The wordmark is white: a soft shadow keeps it readable on light palettes too. */
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, .35));
}

.rp-intro-hero {
  position: relative;
  width: clamp(130px, 40vw, 190px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  perspective: 700px;
}
.rp-intro-icon {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 28%;
  object-fit: cover;
  box-shadow:
    0 0 0 4px color-mix(in srgb, var(--rp-in-accent) 80%, transparent),
    0 18px 40px rgba(0, 0, 0, .45),
    0 0 60px color-mix(in srgb, var(--rp-in-accent) 45%, transparent);
}
.rp-intro-halo {
  position: absolute;
  inset: -8%;
  border-radius: 32%;
  border: 3px solid var(--rp-in-accent);
  opacity: 0;
}

.rp-intro-title {
  margin: 4px 0 0;
  max-width: 420px;
  font-family: var(--font-display, inherit);
  font-size: clamp(30px, 9vw, 46px);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -.01em;
  overflow-wrap: anywhere;
  text-shadow: 0 6px 0 rgba(0, 0, 0, .22);
}
.rp-intro-word { display: inline-block; white-space: nowrap; }
.rp-intro-letter { display: inline-block; }

/* Sound bars: shown while the host speaks. */
.rp-intro-voice {
  display: flex;
  align-items: center;
  gap: 4px;
  height: 22px;
  opacity: 0;
  transition: opacity 200ms ease;
}
.rp-intro-voice i {
  width: 4px;
  height: 100%;
  border-radius: 2px;
  background: var(--rp-in-accent);
  transform: scaleY(.25);
}
.rp-intro.speaking .rp-intro-voice { opacity: 1; }

.rp-intro-players {
  list-style: none;
  margin: clamp(6px, 2vh, 16px) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 10px;
  max-width: 460px;
}
.rp-intro-chip {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  padding: 6px 14px 6px 6px;
  border-radius: 999px;
  font-size: 16px;
  font-weight: 700;
  background: color-mix(in srgb, var(--text-primary, #fff) 12%, transparent);
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--rp-in-accent) 50%, transparent);
}
.rp-intro-chip .rp-player { max-width: 40vw; }
.rp-intro-more { padding: 6px 14px; color: var(--text-secondary, rgba(255, 255, 255, .8)); }

/* How long until the game: fills over the intro's whole time. */
.rp-intro-progress {
  position: absolute;
  left: 50%;
  bottom: max(18px, env(safe-area-inset-bottom));
  width: min(56vw, 240px);
  height: 4px;
  translate: -50% 0;
  border-radius: 2px;
  overflow: hidden;
  background: color-mix(in srgb, var(--text-primary, #fff) 16%, transparent);
}
.rp-intro-progress span {
  display: block;
  height: 100%;
  background: var(--rp-in-accent);
  transform-origin: left;
  transform: scaleX(0);
}
/* An animation, not a transition: a transition is skipped (the bar jumps to full) when the page hasn't styled
   the bar before `.visible` lands, e.g. the intro arrives while the tab is in the background. */
.rp-intro.visible .rp-intro-progress span { animation: rp-intro-progress var(--rp-intro-ms, 4000ms) linear forwards; }

/* Short screens (landscape phones, small phones): smaller icon and name so the players still fit. */
@media (max-height: 600px) {
  .rp-intro-stage { padding-top: max(10px, env(safe-area-inset-top)); }
  .rp-intro-main { gap: 8px; padding-top: 6px; }
  .rp-intro-brand { width: 110px; }
  .rp-intro-hero { width: min(21vh, 150px); }
  .rp-intro-title { font-size: clamp(24px, 6vh, 34px); }
  .rp-intro-players { max-width: 640px; margin-top: 2px; }
}

@media (prefers-reduced-motion: no-preference) {
  /* ---- Entrance ---- */
  .rp-intro.visible .rp-intro-rays { animation: rp-intro-fade 900ms ease-out both, rp-intro-spin 24s linear infinite; }
  .rp-intro.visible .rp-intro-sparks { animation: rp-intro-fade 900ms ease-out 300ms both; }
  .rp-intro-spark { animation: rp-intro-spark var(--dur, 6s) linear var(--delay, 0s) infinite; }
  .rp-intro.visible .rp-intro-brand { animation: rp-intro-brand-in 640ms var(--rp-in-ease) 80ms both; }
  .rp-intro.visible .rp-intro-icon { animation: rp-intro-icon-in 900ms cubic-bezier(.2, .8, .25, 1.15) 200ms both, rp-intro-float 2600ms ease-in-out 1100ms infinite; }
  .rp-intro.visible .rp-intro-halo { animation: rp-intro-halo 1800ms ease-out 900ms infinite; }
  .rp-intro.visible .rp-intro-halo.second { animation-delay: 1800ms; }
  .rp-intro.visible .rp-intro-letter { animation: rp-intro-letter-in 560ms var(--rp-in-ease) calc(620ms + var(--i) * 38ms) both; }
  .rp-intro.visible .rp-intro-chip { animation: rp-intro-deal 620ms var(--rp-in-ease) calc(1000ms + var(--i) * 110ms) both; }
  .rp-intro.speaking .rp-intro-voice i { animation: rp-intro-bar 700ms ease-in-out calc(var(--b) * -140ms) infinite alternate; }

  /* ---- Leaving: the portal ---- */
  .rp-intro.leaving {
    -webkit-mask: radial-gradient(circle at var(--rp-intro-x, 50%) var(--rp-intro-y, 40%), transparent var(--rp-intro-hole), #000 calc(var(--rp-intro-hole) + 1.5px));
    mask: radial-gradient(circle at var(--rp-intro-x, 50%) var(--rp-intro-y, 40%), transparent var(--rp-intro-hole), #000 calc(var(--rp-intro-hole) + 1.5px));
    animation: rp-intro-iris 620ms cubic-bezier(.65, 0, .35, 1) 200ms forwards;
  }
  .rp-intro.leaving .rp-intro-chip,
  .rp-intro.leaving .rp-intro-brand,
  .rp-intro.leaving .rp-intro-title,
  .rp-intro.leaving .rp-intro-voice {
    animation: rp-intro-fly 520ms cubic-bezier(.55, 0, .8, .2) both;
  }
  .rp-intro.leaving .rp-intro-chip { animation-delay: calc(var(--i) * 18ms); }
  .rp-intro.leaving .rp-intro-icon { animation: rp-intro-rush 820ms cubic-bezier(.6, -.25, .7, .2) both; }
  .rp-intro.leaving .rp-intro-halo { animation: rp-intro-shock 520ms ease-out both; }
  .rp-intro.leaving .rp-intro-halo.second { animation-delay: 90ms; }
  .rp-intro.leaving .rp-intro-rays { animation: rp-intro-spin-out 820ms ease-in both; }
  .rp-intro.leaving .rp-intro-progress { opacity: 0; transition: opacity 150ms; }
  .rp-intro.leaving .rp-intro-portal { opacity: 1; transition: opacity 120ms 200ms; animation: rp-intro-iris 620ms cubic-bezier(.65, 0, .35, 1) 200ms forwards; }
  /* The page under the opaque intro stands still (game-intro.js sets the class until the portal opens): its
     background bubbles and spinners would otherwise restyle every frame together with the intro's own animations. */
  html.rp-intro-covering body > :not(.rp-intro),
  html.rp-intro-covering body > :not(.rp-intro) * { animation-play-state: paused !important; }
}

@media (prefers-reduced-motion: reduce) {
  .rp-intro.visible .rp-intro-rays, .rp-intro.visible .rp-intro-sparks { opacity: 1; }
  .rp-intro.leaving { opacity: 0; transition-duration: 300ms; }
}

@keyframes rp-intro-progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes rp-intro-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes rp-intro-spin { from { rotate: 0deg; } to { rotate: 360deg; } }
@keyframes rp-intro-spark {
  0% { opacity: 0; transform: translate(0, 0) scale(.6); }
  20% { opacity: var(--glow, .7); }
  50% { transform: translate(var(--sway, 0px), calc(var(--rise, -120px) * .5)) scale(1); }
  80% { opacity: var(--glow, .7); }
  100% { opacity: 0; transform: translate(0, var(--rise, -120px)) scale(.6); }
}
@keyframes rp-intro-brand-in {
  from { opacity: 0; transform: translateY(-40px) scale(.8); filter: blur(8px); }
  to { opacity: 1; transform: none; filter: blur(0); }
}
@keyframes rp-intro-icon-in {
  0% { opacity: 0; transform: rotateY(-540deg) rotateZ(-20deg) scale(.15); filter: brightness(2.2); }
  55% { opacity: 1; transform: rotateY(20deg) rotateZ(4deg) scale(1.14); filter: brightness(1.3); }
  78% { transform: rotateY(-8deg) rotateZ(-2deg) scale(.96); filter: brightness(1); }
  100% { opacity: 1; transform: none; }
}
@keyframes rp-intro-float { 0%, 100% { translate: 0 0; } 50% { translate: 0 -7px; } }
@keyframes rp-intro-halo { 0% { opacity: .9; transform: scale(.92); } 100% { opacity: 0; transform: scale(1.45); } }
@keyframes rp-intro-letter-in {
  0% { opacity: 0; transform: translateY(.9em) rotateX(90deg) scale(.6); }
  60% { opacity: 1; transform: translateY(-.12em) rotateX(-12deg) scale(1.08); }
  100% { opacity: 1; transform: none; }
}
@keyframes rp-intro-deal {
  0% { opacity: 0; transform: translateY(70px) rotate(var(--tilt)) scale(.6); }
  65% { opacity: 1; transform: translateY(-6px) rotate(calc(var(--tilt) * -.3)) scale(1.05); }
  100% { opacity: 1; transform: none; }
}
@keyframes rp-intro-bar { from { transform: scaleY(.25); } to { transform: scaleY(1); } }
/* The portal moves only transform and opacity (no filter, no border-width): a blur or brightness on the icon blown up
   ninefold, or a border growing, made the phone repaint every frame and the portal stuttered (owner 2026-10-29). */
@keyframes rp-intro-fly {
  to { opacity: 0; transform: translate(var(--fly-x, 0), var(--fly-y, -60vh)) rotate(var(--tilt, 12deg)) scale(.7); }
}
@keyframes rp-intro-rush {
  0% { transform: none; }
  22% { transform: scale(.82) rotate(-6deg); }
  100% { transform: scale(9) rotate(12deg); opacity: 0; }
}
@keyframes rp-intro-shock { 0% { opacity: 1; transform: scale(1); } 100% { opacity: 0; transform: scale(4); } }
@keyframes rp-intro-spin-out { to { rotate: 160deg; scale: 1.6; opacity: 0; } }
@keyframes rp-intro-iris { from { --rp-intro-hole: 0px; } to { --rp-intro-hole: 150vmax; } }
/* /packs.css */
/* ==================== */
/* Shared Pack Styles   */
/* ==================== */

.packs-container {
    flex: 1;
    overflow-y: auto;
    padding-top: 4px;
    padding-bottom: 20px;
}

/* Layout: List (row cards, e.g. ALIAS) */
.packs-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* Layout: Grid (2 columns, e.g. yesno) */
.packs-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
}

/* Layout: Illustrated square gallery */
/* `.screen.` outranks the `.rp-local/.rp-direct .screen { height: auto }` reset, so the
   gallery scrolls inside a screen-tall layout and Play stays pinned at the bottom. */
.screen.packs-illustrated-screen {
    height: 100vh;
    height: var(--app-height, 100dvh);
    min-height: 0;
    overflow: hidden;
}

.packs-illustrated-content {
    min-height: 0;
    overflow: hidden;
}

.packs-illustrated-scroll {
    width: 100%;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    /* Room for the selected card's glow and tap pop, so its top edge is never cut. */
    padding: 8px 4px 18px;
    /* Soft edge above the action bar instead of a hard cut, hinting there is more below. */
    -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 16px), transparent);
    mask-image: linear-gradient(180deg, #000 calc(100% - 16px), transparent);
}

.packs-illustrated-actions {
    position: relative;
    z-index: 5;
    flex: 0 0 auto;
    width: 100%;
    margin-top: 0;
    /* No plate behind the bar (owner 2026-10-31: «вокруг круглой кнопки квадратный background»): the round
       «Правила», «Дополнительные настройки» and «Играть» sit straight on the page background. The gallery
       scrolls in its own box above (.packs-illustrated-scroll, soft masked edge), so nothing runs under them. */
    background: none;
}

/* One header geometry on every pack screen (the NHIE layout): back button and title share
   the first 44px row at the same height, subtitle right under it. Themes keep their own
   fonts and colours; only position and spacing are pinned, hence the !important against
   per-game margins and absolute offsets. */
.screen.packs-screen-shell {
    position: relative;
    padding-top: calc(20px + env(safe-area-inset-top, 0px)) !important;
}

.screen.packs-screen-shell > .screen-content {
    padding-top: 0 !important;
}

.screen.packs-screen-shell > .btn-back {
    position: absolute !important;
    z-index: 6;
    top: calc(20px + env(safe-area-inset-top, 0px)) !important;
    left: 12px !important;
    right: auto !important;
    width: 44px;
    height: 44px;
    margin: 0 !important;
    transform: none !important;
}

.screen.packs-screen-shell .title {
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 100%;
    min-height: 44px;
    margin: 0 0 2px !important;
    padding: 0 48px !important;
    line-height: 1.1;
    text-align: center;
}

.screen.packs-screen-shell .title + .subtitle {
    margin: 0 0 16px !important;
    text-align: center;
}

.screen.packs-screen-shell .packs-container {
    margin-top: 0 !important;
}

.screen.packs-screen-shell .subtitle + .subtitle {
    margin-top: -10px !important;
}

/* Compact action bar on every pack screen (any layout): on short phones the stacked
   summary card + settings + Play took ~240px and left the gallery a ~300px window. The
   settings button shares one row with Play, so the gallery keeps most of the screen.
   `.screen .bottom-section` lifts specificity above per-game theme rules. */
.screen .bottom-section.packs-compact-actions {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 8px 10px;
    padding-top: 10px;
}

.screen .bottom-section.packs-compact-actions > * {
    flex: 1 1 100%;
    min-width: 0;
    margin: 0;
}

.screen .bottom-section.packs-compact-actions > .packs-summary {
    order: -2;
    padding: 6px 12px;
    line-height: 20px;
}

/* The count lives inside Play (packs.js `_mirrorCountIntoPlay`); the summary card stays
   in the DOM as the games' data source. */
.screen .bottom-section.packs-count-in-play > .packs-summary {
    display: none;
}

.screen .bottom-section.packs-count-in-play > .btn-play {
    flex-wrap: wrap;
    align-content: center;
    row-gap: 1px;
    line-height: 1.15;
}

.packs-play-count {
    display: block;
    flex-basis: 100%;
    font-size: 12px;
    font-weight: 600;
    opacity: 0.82;
}

.packs-play-count:empty {
    display: none;
}

.screen .bottom-section.packs-compact-actions > .form-message {
    order: -1;
}

.screen .bottom-section.packs-compact-actions > :is(.btn-additional-settings, .btn-settings-link) {
    flex: 1 1 0;
    min-height: 54px;
    padding: 8px 12px;
    font-size: 14px;
    line-height: 1.15;
}

.screen .bottom-section.packs-compact-actions > .btn-play {
    flex: 1.35 1 0;
    min-height: 54px;
    padding: 8px 16px;
}

@media (max-width: 380px) {
    .screen .bottom-section.packs-compact-actions > :is(.btn-additional-settings, .btn-settings-link) {
        padding: 6px 8px;
        font-size: 13px;
    }

    .screen .bottom-section.packs-compact-actions > .btn-play {
        flex-grow: 1;
    }
}

.packs-illustrated-grid {
    --packs-accent: var(--accent-pink);
    --packs-feedback-rgb: 255, 59, 111;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-content: start;
    gap: 12px;
    width: 100%;
}

.packs-illustrated-grid .pack-card {
    isolation: isolate;
    aspect-ratio: 1;
    min-width: 0;
    padding: 0;
    overflow: hidden;
    border: 2px solid rgba(148, 163, 184, 0.72);
    border-radius: 18px;
    background: var(--bg-card);
    box-shadow: 0 10px 24px rgba(2, 6, 23, 0.28);
    transform: translateZ(0);
}

.packs-illustrated-grid .pack-card.premium,
.packs-illustrated-grid .pack-card.locked {
    border-color: rgba(148, 163, 184, 0.72);
    background: var(--bg-card);
}

.packs-illustrated-grid .pack-card.selected,
.packs-illustrated-grid .pack-card.premium.selected {
    border-color: var(--packs-accent);
    background: var(--bg-card);
    box-shadow: 0 0 0 2px rgba(var(--packs-feedback-rgb), 0.28),
                0 14px 30px rgba(var(--packs-feedback-rgb), 0.24);
}

.packs-illustrated-grid .pack-card.locked {
    opacity: 1;
}

.packs-illustrated-grid .pack-art {
    position: absolute;
    inset: 0;
    z-index: -2;
    width: 100%;
    height: 100%;
    border-radius: 0;
    object-fit: cover;
    transition: transform 0.35s cubic-bezier(0.18, 0.82, 0.22, 1), filter 0.25s ease;
}

.packs-illustrated-grid .pack-card.locked .pack-art {
    filter: brightness(0.66) saturate(0.78);
}

.packs-illustrated-grid .pack-art-shade {
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(180deg,
        rgba(7, 11, 25, 0.02) 28%,
        rgba(7, 11, 25, 0.38) 58%,
        rgba(7, 11, 25, 0.94) 100%);
}

.packs-illustrated-grid .pack-copy {
    position: absolute;
    left: 12px;
    right: 12px;
    bottom: 11px;
    text-align: left;
    text-shadow: 0 2px 8px rgba(0, 0, 0, 0.85);
}

.packs-illustrated-grid .pack-name {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    font-size: clamp(13px, 3.8vw, 16px);
    font-weight: 800;
    line-height: 1.08;
    color: #fff;
}

.packs-illustrated-grid .pack-count {
    margin-top: 4px;
    color: rgba(255, 255, 255, 0.76);
    font-size: 11px;
    font-weight: 600;
    line-height: 1.1;
}

.packs-illustrated-grid .premium-badge {
    position: absolute;
    top: 9px;
    right: 9px;
    z-index: 2;
    display: grid;
    place-items: center;
    width: 27px;
    height: 27px;
    border-radius: 50%;
    background: rgba(10, 15, 31, 0.74);
    font-size: 14px;
    line-height: 1;
    backdrop-filter: blur(6px);
}

.packs-illustrated-grid .pack-lock-image {
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 2;
    width: 68px;
    height: 68px;
    object-fit: contain;
    transform: translate(-50%, -58%);
    filter: drop-shadow(0 8px 13px rgba(0, 0, 0, 0.55));
}

@media (hover: hover) {
    .packs-illustrated-grid .pack-card:not(.locked):hover {
        border-color: var(--packs-accent);
        transform: translateY(-3px);
        box-shadow: 0 0 0 2px rgba(var(--packs-feedback-rgb), 0.2),
                    0 16px 34px rgba(var(--packs-feedback-rgb), 0.22);
    }

    .packs-illustrated-grid .pack-card:not(.locked):hover .pack-art {
        transform: scale(1.045);
    }
}

/* ---- Pack Card (common) ---- */
.pack-card {
    background: var(--bg-card);
    border-radius: 16px;
    cursor: pointer;
    transition: all 0.3s ease;
    border: 2px solid transparent;
    position: relative;
    display: flex;
    align-items: center;
}

@media (hover: hover) {
    .pack-card:hover {
        transform: translateY(-2px);
        border-color: var(--accent-pink);
    }
}

.pack-card:active {
    transform: scale(0.98);
}

/* List layout card */
.packs-list .pack-card {
    flex-direction: row;
    gap: 16px;
    padding: 16px 20px;
    width: 100%;
}

/* Grid layout card */
.packs-grid .pack-card {
    flex-direction: column;
    gap: 8px;
    padding: 20px 16px;
    text-align: center;
}

.packs-grid .pack-card:active {
    transform: scale(0.97);
}

/* ---- State Styles ---- */
.pack-card.selected {
    border-color: var(--accent-pink);
    background: linear-gradient(135deg, rgba(255, 59, 111, 0.15) 0%, rgba(74, 108, 247, 0.15) 100%);
}

.pack-card.premium {
    border-color: rgba(255, 215, 0, 0.3);
    background: linear-gradient(135deg, var(--bg-card) 0%, rgba(255, 215, 0, 0.08) 100%);
}

.pack-card.premium.selected {
    border-color: #ffd700;
    background: linear-gradient(135deg, rgba(255, 215, 0, 0.15) 0%, rgba(255, 59, 111, 0.1) 100%);
}

.pack-card.locked {
    opacity: 0.7;
    cursor: not-allowed;
}

@media (hover: hover) {
    .pack-card.locked:hover {
        transform: none;
        border-color: rgba(255, 215, 0, 0.3);
    }
}

.pack-card.locked:active {
    transform: none;
}

/* Opt-in press feedback plus a CSS fallback for selection animation. */
.pack-card.packs-touch-press:not(.locked) {
    transform: scale(0.965);
    box-shadow: 0 0 0 3px rgba(255, 92, 138, 0.26), 0 8px 22px rgba(233, 30, 99, 0.24);
}

.pack-card.packs-touch-press:not(.locked) .pack-art {
    transform: scale(1.09);
    transition-duration: 0.12s;
}

.pack-card.packs-touch-pop:not(.locked) {
    animation: packsTouchPop 0.68s cubic-bezier(0.18, 0.82, 0.22, 1);
}

.pack-card.packs-touch-pop:not(.locked) .pack-art {
    animation: packsArtTouchPop 0.68s cubic-bezier(0.18, 0.82, 0.22, 1);
}

@keyframes packsTouchPop {
    0% { transform: scale(calc(1 - .06 * var(--rp-motion-pack-intensity, 1))); }
    55% { transform: scale(calc(1 + .035 * var(--rp-motion-pack-intensity, 1))); }
    100% { transform: scale(1); }
}

@keyframes packsArtTouchPop {
    0% { transform: scale(calc(1 + .12 * var(--rp-motion-pack-intensity, 1))); }
    100% { transform: scale(calc(1 + .01 * var(--rp-motion-pack-intensity, 1))); }
}

@media (prefers-reduced-motion: reduce) {
    .pack-card.packs-touch-press,
    .pack-card.packs-touch-pop,
    .pack-card.packs-touch-pop .pack-art {
        animation: none;
        transform: none;
    }

    /* Native WebViews can report reduced motion by default. The opt-in illustrated
       gallery keeps its short selection feedback so taps never feel unresponsive. */
    .packs-illustrated-grid .pack-card.packs-touch-press:not(.locked) {
        transform: scale(0.965);
    }

    .packs-illustrated-grid .pack-card.packs-touch-pop:not(.locked) {
        animation: packsTouchPop 0.68s cubic-bezier(0.18, 0.82, 0.22, 1);
    }

    .packs-illustrated-grid .pack-card.packs-touch-pop:not(.locked) .pack-art {
        animation: packsArtTouchPop 0.68s cubic-bezier(0.18, 0.82, 0.22, 1);
    }
}

/* ---- Elements ---- */
.pack-icon {
    font-size: 36px;
    flex-shrink: 0;
    transition: transform 0.3s ease;
}

.pack-art {
    flex-shrink: 0;
    width: 64px;
    height: 64px;
    border-radius: 14px;
    object-fit: cover;
}

.pack-art-progressive {
    opacity: 0.9;
}

.pack-art-progressive.is-full-res {
    opacity: 1;
    transition: opacity 0.2s ease;
}

.packs-list .pack-art {
    width: 56px;
    height: 56px;
    border-radius: 12px;
}

.pack-info {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.pack-name {
    font-size: 16px;
    font-weight: 600;
    color: var(--text-primary);
}

.pack-count {
    font-size: 13px;
    color: var(--text-secondary);
}

.pack-status {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

/* Premium badge — inline in list, absolute in grid. Crown and lock are SVG (pack-glyph), not emoji. */
.premium-badge {
    font-size: 18px;
    color: #ffd166;
}

.pack-glyph {
    display: block;
    flex: none;
}

/* Premium pack the test sites open to everyone: the crown badge widens into a pill with «Тест». */
.premium-badge--test {
    display: inline-flex;
    align-items: center;
    gap: 3px;
}

.premium-badge-test-label {
    font-size: 10px;
    font-weight: 800;
    line-height: 1;
    letter-spacing: 0.02em;
}

.packs-illustrated-grid .premium-badge.premium-badge--test,
.packs-illustrated-grid--3 .premium-badge.premium-badge--test {
    display: flex;
    width: auto;
    padding: 0 8px 0 6px;
    border-radius: 999px;
}

.packs-illustrated-grid--3 .premium-badge.premium-badge--test {
    padding: 0 6px 0 5px;
}

.packs-illustrated-grid--3 .premium-badge-test-label {
    font-size: 9px;
}

.packs-grid .premium-badge {
    position: absolute;
    top: 8px;
    right: 8px;
    font-size: 14px;
}

.pack-lock {
    font-size: 20px;
}

.pack-lock-image {
    width: 24px;
    height: 24px;
    object-fit: contain;
}

.packs-grid .pack-lock {
    margin-top: 4px;
}

.pack-check {
    width: 26px;
    height: 26px;
    background: var(--accent-pink);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    color: white;
    font-weight: 700;
}

/* ---- Shake Animation ---- */
@keyframes shake {
    0%, 100% { transform: translateX(0); }
    25% { transform: translateX(-5px); }
    75% { transform: translateX(5px); }
}

.pack-card.shake {
    animation: shake 0.3s ease;
}

/* ---- Summary Bar ---- */
.packs-summary {
    text-align: center;
    margin-bottom: 12px;
    padding: 12px;
    background: var(--bg-card);
    border-radius: 12px;
}

.summary-text {
    color: var(--text-secondary);
    font-size: 14px;
}

.summary-text strong {
    color: var(--accent-pink);
    font-size: 18px;
}

/* ---- Responsive: Small screens ---- */
@media (max-width: 480px) {
    .packs-list,
    .packs-grid {
        gap: 10px;
    }

    .packs-illustrated-grid {
        gap: 10px;
    }

    .packs-illustrated-grid .pack-card {
        border-radius: 14px;
    }

    .pack-card {
        border-radius: 12px;
    }

    .packs-list .pack-card {
        padding: 14px 16px;
        gap: 12px;
    }

    .packs-grid .pack-card {
        padding: 16px 12px;
    }

    .pack-icon {
        font-size: 30px;
    }

    .pack-name {
        font-size: 14px;
    }

    .pack-count {
        font-size: 12px;
    }

    .premium-badge {
        font-size: 14px;
    }

    .pack-check {
        width: 22px;
        height: 22px;
        font-size: 12px;
    }

    .packs-summary {
        padding: 10px;
    }

    .summary-text {
        font-size: 13px;
    }

    .summary-text strong {
        font-size: 16px;
    }
}

/* ---- Responsive: Large screens ---- */
@media (min-width: 768px) {
    .packs-list,
    .packs-grid {
        gap: 16px;
    }

    .packs-illustrated-grid {
        gap: 16px;
    }

    .packs-illustrated-grid .pack-name {
        font-size: 17px;
    }

    .packs-list .pack-card {
        padding: 18px 24px;
    }

    .pack-icon {
        font-size: 42px;
    }

    .pack-name {
        font-size: 18px;
    }

    .pack-count {
        font-size: 14px;
    }
}

/* ==================== */
/* Choice gate          */
/* ==================== */

/* Until a pack is picked, the screen's actions are removed and the action bar
   loses its backdrop, so the gallery uses the whole screen with nothing covering it. */
.packs-awaiting-choice .bottom-section :is(.btn-play, .btn-additional-settings, .btn-settings-link, .packs-summary),
.packs-awaiting-choice .bottom-section .rp-setup-actions:not(:has(> :not(.btn-play, .btn-additional-settings, .btn-settings-link, .packs-summary))) {
    display: none !important;
}

.packs-awaiting-choice .bottom-section {
    padding-top: 0;
    background: none;
}

.packs-choice-cue {
    position: absolute;
    z-index: 6;
    top: 8px;
    right: 8px;
    width: 64px;
    height: 56px;
    color: var(--packs-cue-color, var(--packs-accent, var(--accent-pink, #ff3b6f)));
    pointer-events: none;
    filter: drop-shadow(0 3px 0 var(--packs-cue-shadow, rgba(255, 255, 255, 0.92)));
}

.packs-choice-cue svg {
    display: block;
    width: 100%;
    height: 100%;
}

.packs-list .packs-choice-cue {
    top: 50%;
    right: 12px;
    width: 46px;
    height: 40px;
    margin-top: -20px;
}

@media (prefers-reduced-motion: no-preference) {
    .packs-choice-cue {
        animation: packs-choice-point 800ms ease-in-out infinite alternate;
    }

    .packs-choice-revealed .bottom-section :is(.btn-play, .btn-additional-settings, .btn-settings-link, .packs-summary) {
        animation: packs-choice-reveal 420ms cubic-bezier(0.2, 0.9, 0.3, 1.25) both;
    }

    .packs-choice-revealed .bottom-section .btn-play {
        animation-delay: 60ms;
    }
}

@keyframes packs-choice-point {
    from { transform: translate(calc(3px * var(--rp-motion-artwork-intensity, 1)), calc(-3px * var(--rp-motion-artwork-intensity, 1))); }
    to { transform: translate(calc(-8px * var(--rp-motion-artwork-intensity, 1)), calc(8px * var(--rp-motion-artwork-intensity, 1))); }
}

@keyframes packs-choice-reveal {
    from { opacity: 0; transform: translateY(12px) scale(0.96); }
    to { opacity: 1; transform: none; }
}

/* ==================== */
/* Flat character covers */
/* ==================== */

/* Packs with an animated cover (pack.activeImage) use the flat character art:
   premium covers stay at full colour and a small flat lock sits in the top-right
   corner instead of the centred glossy lock, in every layout. */
.pack-card.pack-card--flat-art.locked {
    opacity: 1;
}

.pack-card.pack-card--flat-art.locked .pack-art {
    filter: none;
}

.pack-card.pack-card--flat-art .pack-lock-image {
    position: absolute;
    top: 10px;
    right: 10px;
    left: auto;
    z-index: 2;
    width: 34px;
    height: 34px;
    margin: 0;
    transform: none;
    filter: drop-shadow(0 2px 6px rgba(23, 25, 31, 0.35));
}

/* ==================== */
/* Selected state       */
/* ==================== */

/* Every game marks a picked pack the same clear way: a thick ring in the game's cue
   colour (palette atlas, checked for contrast with the ink outline) plus a check badge
   in the top-left corner (the lock sits top-right, and a picked pack is never locked).
   `.screen` + `!important` win over per-game theme borders that were too subtle. */
.screen .pack-card {
    --packs-select: var(--packs-cue-color, var(--packs-accent, var(--accent-pink, #ff3b6f)));
}

.screen .pack-card.selected:not(.locked),
.screen .pack-card.premium.selected:not(.locked) {
    border-color: var(--packs-select) !important;
    border-width: 4px !important;
    border-style: solid !important;
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.16), 0 10px 26px rgba(0, 0, 0, 0.32) !important;
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--packs-select) 45%, transparent),
                0 10px 26px rgba(0, 0, 0, 0.32) !important;
}

.pack-selected-mark {
    position: absolute;
    z-index: 7;
    top: 8px;
    left: 8px;
    display: none;
    width: 32px;
    height: 32px;
    border: 2.5px solid #fff;
    border-radius: 50%;
    background-color: var(--packs-select);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5' fill='none' stroke='%23111211' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-position: center;
    background-repeat: no-repeat;
    background-size: 20px 20px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
    pointer-events: none;
}

.pack-card.selected:not(.locked) > .pack-selected-mark {
    display: block;
}

@media (prefers-reduced-motion: no-preference) {
    .pack-card.selected:not(.locked) > .pack-selected-mark {
        animation: packs-mark-pop 260ms cubic-bezier(0.2, 0.9, 0.3, 1.4) both;
    }
}

@keyframes packs-mark-pop {
    from { transform: scale(0.4); opacity: 0; }
    to { transform: none; opacity: 1; }
}

/* Long single words (German, Scandinavian) hyphenate where the browser can; otherwise
   packs.js `_fitPackText` shrinks the name so whole words fit. */
.pack-card .pack-name {
    -webkit-hyphens: auto;
    hyphens: auto;
}

/* The shared badge replaces the old list-layout ✓. */
.pack-card .pack-check {
    display: none;
}


/* «Выбрать все» tile (packs.js adds it first when no pack is premium): a flat card fan on
   the game's cue colour instead of cover art; selected when every pack is picked. */
.pack-card.pack-select-all {
    cursor: pointer;
}

/* `.screen` beats theme rules sized for cover images (Quiz shrinks .pack-art to 72%). */
.screen .packs-illustrated-grid .pack-select-all-art {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    height: 100%;
    padding: 14% 0 0;
    box-sizing: border-box;
    background: radial-gradient(circle at 50% 36%, color-mix(in srgb, var(--packs-select) 34%, transparent) 0 38%, transparent 62%);
}

.packs-illustrated-grid .pack-select-all-art .pack-select-all-icon {
    width: 64%;
    height: auto;
    transition: transform 0.35s cubic-bezier(0.18, 0.82, 0.22, 1);
}

.packs-illustrated-grid .pack-select-all.selected .pack-select-all-icon {
    transform: scale(1.06) rotate(-3deg);
}

.packs-grid .pack-select-all > .pack-select-all-icon,
.packs-list .pack-select-all > .pack-select-all-icon {
    flex-shrink: 0;
    width: 56px;
    height: auto;
}

/* Plain grid with cover art: the fan fills the cover box (`.pack-art`, sized by the game
   theme) instead of a 56px icon in the corner. */
.screen .packs-grid .pack-select-all-art {
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--packs-select) 34%, transparent) 0 42%, transparent 66%);
}

.packs-grid .pack-select-all-art .pack-select-all-icon {
    width: 82%;
    max-height: 100%;
    height: auto;
    transition: transform 0.35s cubic-bezier(0.18, 0.82, 0.22, 1);
}

.packs-grid .pack-select-all.selected .pack-select-all-art .pack-select-all-icon {
    transform: scale(1.06) rotate(-3deg);
}

/* Illustrated grid, three in a row (Packs.render `columns: 3`): for games with many packs.
   Smaller covers, so the name, count, lock and «selected» mark shrink with them. */
.packs-illustrated-grid.packs-illustrated-grid--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
}

.packs-illustrated-grid--3 .pack-card {
    border-radius: 14px;
}

.packs-illustrated-grid--3 .pack-copy {
    left: 7px;
    right: 7px;
    bottom: 7px;
}

.packs-illustrated-grid--3 .pack-name {
    font-size: clamp(11px, 3vw, 14px);
}

.packs-illustrated-grid--3 .pack-count {
    margin-top: 2px;
    font-size: 10px;
}

.packs-illustrated-grid--3 .premium-badge {
    top: 6px;
    right: 6px;
    width: 22px;
    height: 22px;
    font-size: 12px;
}

.packs-illustrated-grid--3 .pack-lock-image {
    width: 46px;
    height: 46px;
}

.packs-illustrated-grid--3 .pack-card > .pack-selected-mark {
    top: 6px;
    left: 6px;
    width: 24px;
    height: 24px;
    border-width: 2px;
    background-size: 15px 15px;
}

@media (min-width: 768px) {
    .packs-illustrated-grid.packs-illustrated-grid--3 {
        gap: 12px;
    }

    .packs-illustrated-grid--3 .pack-name {
        font-size: 15px;
    }
}

/* Section heading inside a pack list (a pack's `section`, e.g. Melody «Режимы» / «Наборы»): spans the
   whole row of any layout, so modes and packs read as two groups. */
.packs-section-title {
    grid-column: 1 / -1;
    margin: 10px 2px 0;
    font-family: var(--font-display, inherit);
    font-size: 15px;
    font-weight: 800;
    line-height: 1.3;
    letter-spacing: 0.02em;
    color: var(--text-secondary, rgba(255, 255, 255, 0.72));
}

.packs-section-title:first-child {
    margin-top: 0;
}
/* /mode-cards.css */
/*
 * RoomPlay shared mode screen (#mode-screen .mode-cards): two cards, blob art on the left, title and
 * description on the right. Layout, sizes, states and motion are the same in every game; a game only
 * colours it through tokens in its *-theme.css (on :root, the game scope or one card, e.g. #mode-team):
 *   --mode-card-bg, --mode-card-ink, --mode-card-muted, --mode-card-border, --mode-card-accent (hover/focus),
 *   --mode-card-shadow, --mode-art-a (main blob), --mode-art-b (teammates / prop), --mode-art-ink (eyes),
 *   --mode-art-mouth.
 * Markup:  <div class="mode-cards"><div class="mode-card" id="mode-solo" role="button" tabindex="0">
 *            <div class="mode-card-icon"><span data-rp-mode-art="solo"></span></div>
 *            <div class="mode-card-title">…</div><div class="mode-card-desc">…</div></div>…</div>
 *   Art: solo | team | word | question from mode-art.js. Do not restyle these classes in a game.
 */
.mode-cards { display: flex; flex-direction: column; justify-content: center; gap: 16px; flex: 1; width: 100%; max-width: 420px; margin: 0 auto; padding: 16px 0; }
.mode-cards .mode-card {
  display: grid; grid-template-columns: 88px 1fr; column-gap: 16px; align-items: center;
  width: 100%; margin: 0; padding: 20px; border-radius: 20px;
  border: 2px solid var(--mode-card-border, transparent);
  background: var(--mode-card-bg, var(--bg-card));
  color: var(--mode-card-ink, var(--text-primary));
  box-shadow: var(--mode-card-shadow, none);
  font: inherit; text-align: left; cursor: pointer; appearance: none;
  transition: transform 160ms ease-out, border-color 160ms ease-out;
}
.mode-cards .mode-card:active { transform: scale(.98); }
.mode-cards .mode-card:focus-visible { outline: 3px solid var(--mode-card-accent, var(--game-accent, currentColor)); outline-offset: 3px; }
@media (hover: hover) { .mode-cards .mode-card:hover { transform: none; border-color: var(--mode-card-accent, var(--game-accent, currentColor)); box-shadow: var(--mode-card-shadow, none); } }
.mode-cards .mode-card-icon { grid-row: 1 / 3; width: 88px; height: 88px; margin: 0; font-size: 0; }
.mode-cards .mode-card-icon .mode-art { display: block; width: 88px; height: 88px; margin: 0; overflow: visible; }
.mode-cards .mode-card-title { align-self: end; margin: 0; font-family: inherit; font-size: 20px; font-weight: 800; line-height: 1.25; color: var(--mode-card-ink, var(--text-primary)); overflow-wrap: anywhere; }
.mode-cards .mode-card-desc { align-self: start; margin: 4px 0 0; font-size: 16px; line-height: 1.4; color: var(--mode-card-muted, var(--text-secondary)); opacity: 1; }
.mode-card .mode-fill-a { fill: var(--mode-art-a, var(--game-accent, #7c3aed)); }
.mode-card .mode-fill-b { fill: var(--mode-art-b, var(--accent-blue, #3b82f6)); }
.mode-card .mode-pupil, .mode-card .mode-mouth-fill { fill: var(--mode-art-ink, #17191f); }
.mode-card .mode-mouth { stroke: var(--mode-art-mouth, var(--mode-art-ink, #17191f)); }
@media (max-width: 360px) {
  .mode-cards .mode-card { grid-template-columns: 64px 1fr; column-gap: 12px; padding: 16px; }
  .mode-cards .mode-card-icon, .mode-cards .mode-card-icon .mode-art { width: 64px; height: 64px; }
}
@media (prefers-reduced-motion: no-preference) {
  /* Whole blob breathes, eyes included, from its feet; a prop (card, speech bubble) bobs beside it. */
  .mode-card .mode-blob { transform-box: fill-box; transform-origin: 50% 100%; animation: rp-mode-breathe 2.4s ease-in-out infinite; }
  .mode-card .mode-blob--late { animation-delay: -1.2s; }
  .mode-card .mode-blob--side { animation-delay: -.6s; }
  .mode-card .mode-prop { transform-box: fill-box; transform-origin: 0% 100%; animation: rp-mode-bob 2.4s ease-in-out -1.2s infinite; }
  .mode-card:active .mode-blob { animation: rp-mode-hop 320ms ease-out; }
  @keyframes rp-mode-breathe { 0%, 100% { transform: scale(1, 1); } 50% { transform: scale(1.04, .95); } }
  @keyframes rp-mode-bob { 0%, 100% { transform: none; } 50% { transform: translateY(-4px) rotate(-4deg); } }
  @keyframes rp-mode-hop { 0% { transform: scale(1.08, .88); } 55% { transform: translateY(-8%) scale(.96, 1.06); } 100% { transform: none; } }
}
/* /geoguessr/geo-theme.css */
/* Game Theme only. Palette: COMMON/roomplay-palettes.html / geoguessr (Steam edition cover adaptation).
   bg #302778 indigo, surface #211C54 (white text everywhere), accent #D63037 red for actions (white text 4.8:1),
   secondary #9BCB31 globe green for timers, scores and highlights (ink text 9.2:1). Map tiles are untouched;
   only the frame and controls around them follow the palette. Success/error tokens are unchanged. */
:root {
  /* Answer and gender tones: COMMON/roomplay-palettes.html / geoguessr (correct, wrong, male, female). */
  --rp-correct: #9bcb31;
  --rp-correct-ink: #17191f;
  --rp-wrong: #fe726d;
  --rp-wrong-ink: #17191f;
  --rp-male: #63b0fc;
  --rp-female: #f77cb0;
  --bg-primary: #302778;
  --bg-secondary: #211c54;
  --bg-card: #211c54;
  --text-primary: #ffffff;
  --text-secondary: #c9c4f0;
  --text-placeholder: #a9a3e3;
  --accent-purple: #d63037;
  --accent-purple-dark: #b0252b;
  --accent-blue: #d63037;
  --accent-pink: #d63037;
  --accent-pink-dark: #b0252b;
  --accent-green: #d63037;
  --accent-green-dark: #b0252b;
  --geo-red: #d63037;
  --geo-red-dark: #b0252b;
  --geo-green: #9bcb31;
  --geo-surface: #211c54;
  --geo-ink: #17191f;
  --geo-line: rgba(255, 255, 255, .14);
  /* «3, 2, 1» start screen: globe green (the red action colour is too dark for big text on indigo). */
  --rp-countdown-accent: #9bcb31;
  --rp-countdown-accent-ink: #17191f;
  --onboarding-accent: #d63037;
  --onboarding-accent-dark: #d63037;
  --onboarding-shadow: transparent;
  --onboarding-shadow-hover: transparent;
  --settings-accent: #d63037;
  --settings-accent-dark: #b0252b;
  --packs-accent: #9bcb31;
  --packs-feedback-rgb: 155, 203, 49;
  --ps-accent: #d63037;
  --game-accent: #d63037;
}
html, body[data-rp-game="geoguessr"], .page-loader { background: var(--bg-primary); }
body[data-rp-game="geoguessr"] { color: #fff; }
[data-rp-game="geoguessr"] .loader-spinner,
[data-rp-game="geoguessr"] .connection-spinner,
[data-rp-game="geoguessr"] .rp-waiting-spinner { border-color: rgba(255, 255, 255, .15); border-top-color: var(--geo-green); }

/* Actions: red primary, white outline secondary. */
[data-rp-game="geoguessr"] .btn-play,
[data-rp-game="geoguessr"] .btn-next-slide,
[data-rp-game="geoguessr"] .btn-join.active,
[data-rp-game="geoguessr"] .geo-map-error { background: var(--geo-surface); }
[data-rp-game="geoguessr"] .geo-map-retry { color: #fff; background: var(--geo-red); }
[data-rp-game="geoguessr"] .btn-confirm-guess { color: #fff; background: var(--geo-red); border-color: transparent; box-shadow: none; }
[data-rp-game="geoguessr"] .btn-play:disabled,
[data-rp-game="geoguessr"] .btn-confirm-guess:disabled { color: var(--text-secondary); background: var(--geo-surface); opacity: 1; }
[data-rp-game="geoguessr"] .btn-join,
[data-rp-game="geoguessr"] .btn-play.outlined,
[data-rp-game="geoguessr"] .btn-skip { color: #fff; border-color: #fff; background: transparent; box-shadow: none; }
[data-rp-game="geoguessr"] .btn-copy { color: #fff; background: var(--geo-surface); border-color: var(--geo-line); }
[data-rp-game="geoguessr"] .dot { background: rgba(255, 255, 255, .3); }
[data-rp-game="geoguessr"] .dot.active { background: #fff; }
[data-rp-game="geoguessr"] .input { color: #fff; background: var(--geo-surface); }
[data-rp-game="geoguessr"] .subtitle,
[data-rp-game="geoguessr"] .lobby-hint,
[data-rp-game="geoguessr"] .lobby-status,
[data-rp-game="geoguessr"] .map-hint { color: var(--text-secondary); }

/* Lobby and mode toggle. */
[data-rp-game="geoguessr"] .room-code-display { color: var(--geo-green); background: var(--geo-surface); }
[data-rp-game="geoguessr"] .player-item { color: #fff; background: var(--geo-surface); }
[data-rp-game="geoguessr"] .player-avatar:not(.has-photo),
[data-rp-game="geoguessr"] .mini-score-avatar-letter { color: var(--geo-ink); background: var(--geo-green); }
[data-rp-game="geoguessr"] .player-host { color: var(--geo-green); }
[data-rp-game="geoguessr"] .mode-toggle { background: var(--geo-surface); }
[data-rp-game="geoguessr"] .mode-btn { color: var(--text-secondary); }
[data-rp-game="geoguessr"] .mode-btn.active { color: #fff; background: var(--geo-red); }

/* Round: white photo frame, green timer, red letters. */
[data-rp-game="geoguessr"] .round-badge { color: var(--text-secondary); background: var(--geo-surface); }
[data-rp-game="geoguessr"] .timer-badge { color: var(--geo-ink); background: var(--geo-green); }
[data-rp-game="geoguessr"] .timer-badge.warning { color: var(--geo-ink); background: var(--error); }
[data-rp-game="geoguessr"] .street-photo-container { background: var(--geo-surface); box-shadow: 0 0 0 4px #fff; }
[data-rp-game="geoguessr"] .photo-loading { background: var(--geo-surface); }
[data-rp-game="geoguessr"] .quiz-option { color: #fff; }
[data-rp-game="geoguessr"] .option-letter { color: #fff; background: var(--geo-red); }
[data-rp-game="geoguessr"] .quiz-option.selected:not(.correct):not(.wrong) { border-color: #fff; background: rgba(255, 255, 255, .12); }
@media (hover: hover) {
  [data-rp-game="geoguessr"] .quiz-option:hover:not(:disabled):not(.selected) { border-color: #fff; }
}
[data-rp-game="geoguessr"] .answer-feedback:not(:empty) { width: fit-content; margin-inline: auto; padding: 6px 14px; border-radius: 999px; background: var(--geo-surface); }
[data-rp-game="geoguessr"] .guess-map,
[data-rp-game="geoguessr"] .results-map { box-shadow: 0 0 0 3px var(--geo-surface); }
[data-rp-game="geoguessr"] .leaflet-bar { border-color: var(--geo-line); }
[data-rp-game="geoguessr"] .leaflet-bar a,
[data-rp-game="geoguessr"] .leaflet-bar a:hover { color: #fff; background: var(--geo-surface); border-bottom-color: var(--geo-line); }
[data-rp-game="geoguessr"] .correct-location-info { color: var(--geo-green); }
[data-rp-game="geoguessr"] .mini-score-item { color: #fff; background: var(--geo-surface); }
[data-rp-game="geoguessr"] .mini-score-value { color: var(--geo-green); }

/* Round reveal (shared RevealResults) on surface cards; stock green/red keep their meaning. */
[data-rp-game="geoguessr"] .rr-context-subtext,
[data-rp-game="geoguessr"] .rr-leaderboard-title { color: var(--text-secondary); }
[data-rp-game="geoguessr"] .rr-context-image { box-shadow: 0 0 0 4px #fff; }
[data-rp-game="geoguessr"] .rr-option { background: var(--geo-surface); border-color: var(--geo-line); }
[data-rp-game="geoguessr"] .rr-option.rr-type-wrong { border-color: color-mix(in srgb, var(--rp-wrong) 35%, transparent); }
[data-rp-game="geoguessr"] .rr-voter { background: rgba(255, 255, 255, .12); color: #fff; }
[data-rp-game="geoguessr"] .rr-voters-label,
[data-rp-game="geoguessr"] .rr-vote-count { color: var(--text-secondary); }
[data-rp-game="geoguessr"] .rr-lb-row { background: var(--geo-surface); border-color: var(--geo-line); }
[data-rp-game="geoguessr"] .rr-lb-row.rr-leading { border-color: var(--geo-green); background: var(--geo-surface); }
[data-rp-game="geoguessr"] .rr-lb-pos { color: var(--text-secondary); background: rgba(255, 255, 255, .1); }

/* Final results. */
[data-rp-game="geoguessr"] .winner-name { color: var(--geo-green); }
[data-rp-game="geoguessr"] .score-item { color: #fff; background: var(--geo-surface); border: 2px solid transparent; }
[data-rp-game="geoguessr"] .score-item.leading { border-color: var(--geo-green); background: var(--geo-surface); }
[data-rp-game="geoguessr"] .score-value { color: var(--geo-green); }
[data-rp-game="geoguessr"] .score-position:not(.gold):not(.silver):not(.bronze) { color: #fff; background: rgba(255, 255, 255, .12); }
[data-rp-game="geoguessr"] #roomplay-party-finale { border: 1px solid var(--geo-line); background: var(--geo-surface); }
[data-rp-game="geoguessr"] #roomplay-party-finale p { color: var(--text-secondary); }
[data-rp-game="geoguessr"] #roomplay-party-finale .rpf-kicker { color: var(--geo-green); }
[data-rp-game="geoguessr"] #roomplay-party-finale :is(.rpf-share, .rpf-premium) { color: #fff; background: var(--geo-red); }
[data-rp-game="geoguessr"] #roomplay-party-finale .rpf-next { color: #fff; background: rgba(255, 255, 255, .12); }

/* Overlays and popups. */
[data-rp-game="geoguessr"] .connection-overlay { background: rgba(48, 39, 120, .96); }
[data-rp-game="geoguessr"] .connection-text { color: var(--text-secondary); }
/* Exit confirmation and settings popups: violet sheet, red primary, white outline secondary.
   Colours go through the shared --rp-dialog-* tokens (assets/css/confirm-dialog.css). */
[data-rp-game="geoguessr"] {
  --rp-dialog-overlay: rgba(20, 16, 52, .82);
  --rp-dialog-bg: var(--geo-surface);
  --rp-dialog-border: 1px solid var(--geo-line);
  --rp-dialog-text: var(--text-secondary);
  --rp-dialog-primary-bg: var(--geo-red);
  --rp-dialog-secondary-border: #fff;
  --rp-dialog-secondary-text: #fff;
}

/* Onboarding: animated flat SVG characters (static copies via <picture> for reduced motion). */
[data-rp-game="geoguessr"] #onboarding-screen .slide-icon { width: min(240px, 55vw); margin-bottom: 18px; font-size: 0; line-height: 0; }
[data-rp-game="geoguessr"] #onboarding-screen .slide-icon picture,
[data-rp-game="geoguessr"] #onboarding-screen .slide-icon img { display: block; width: 100%; height: auto; }
[data-rp-game="geoguessr"] .slide-title { color: #fff; }
[data-rp-game="geoguessr"] .slide-text { color: var(--text-secondary); }
@media (max-height: 600px) {
  [data-rp-game="geoguessr"] #onboarding-screen .slide-icon { width: 120px; margin-bottom: 8px; }
}
/* Short landscape phones: character beside the copy so the text never runs under the dots/buttons. */
@media (max-height: 500px) and (min-width: 560px) {
  [data-rp-game="geoguessr"] #onboarding-screen .onboarding-slide.active { display: grid; grid-template-columns: auto minmax(0, 340px); grid-template-rows: auto auto; column-gap: 24px; align-items: center; padding-top: 0; text-align: left; }
  [data-rp-game="geoguessr"] #onboarding-screen .slide-icon { grid-row: 1 / span 2; width: 120px; margin: 0; }
  [data-rp-game="geoguessr"] #onboarding-screen .slide-title { align-self: end; margin-bottom: 6px; }
  [data-rp-game="geoguessr"] #onboarding-screen .slide-text { align-self: start; max-width: none; }
}

/* Light motion, same rhythm as «Я никогда не» (cutout-theme.css). Decorative only: never delays answers,
   the map, timers or scoring; fully off under prefers-reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
  [data-rp-game="geoguessr"] {
    --geo-press: 100ms;
    --geo-settle: 240ms;
    --geo-spring: cubic-bezier(.2, .9, .3, 1.25);
  }
  [data-rp-game="geoguessr"] button:not(:disabled) {
    transition: scale var(--geo-settle) var(--geo-spring), translate var(--geo-settle) var(--geo-spring),
      background-color 150ms ease, border-color 150ms ease, color 150ms ease;
  }
  [data-rp-game="geoguessr"] button:not(:disabled):active { scale: .96; translate: 0 2px; transition-duration: var(--geo-press); }
  [data-rp-game="geoguessr"] .btn-back:active { scale: .88; }
  [data-rp-game="geoguessr"] .dot { transition: background-color 180ms ease, scale 180ms var(--geo-spring); }
  [data-rp-game="geoguessr"] .dot.active { scale: 1.12; }

  [data-rp-game="geoguessr"] .onboarding-slide.active .slide-icon { animation: geo-character-arrive 380ms var(--geo-spring) both; }
  [data-rp-game="geoguessr"] #lobby-screen.active .room-code-display { animation: geo-stamp-in 360ms var(--geo-spring) both; }

  /* Round: the photo lands like a postcard, options deal in, the map card slides up. */
  [data-rp-game="geoguessr"] #game-screen.active .street-photo-container { animation: geo-postcard 320ms var(--geo-spring) both; }
  [data-rp-game="geoguessr"] #game-screen.active .quiz-option:not(.correct):not(.wrong) { animation: geo-paper-arrive 280ms var(--geo-spring) both; }
  [data-rp-game="geoguessr"] #game-screen.active .quiz-option:not(.correct):not(.wrong):nth-child(2) { animation-delay: 40ms; }
  [data-rp-game="geoguessr"] #game-screen.active .quiz-option:not(.correct):not(.wrong):nth-child(3) { animation-delay: 80ms; }
  [data-rp-game="geoguessr"] #game-screen.active .quiz-option:not(.correct):not(.wrong):nth-child(4) { animation-delay: 120ms; }
  [data-rp-game="geoguessr"] #game-screen.active .map-guess-container { animation: geo-paper-arrive 280ms var(--geo-spring) both; }
  [data-rp-game="geoguessr"] #game-screen.active .quiz-option:not(.correct):not(.wrong).selected { animation: geo-answer-stamp 260ms var(--geo-spring); }
  [data-rp-game="geoguessr"] .answer-feedback.success,
  [data-rp-game="geoguessr"] .answer-feedback.fail { animation: geo-stamp-in 360ms var(--geo-spring); }
  [data-rp-game="geoguessr"] .leaflet-marker-icon:not(.leaflet-div-icon) { animation: geo-pin-drop 360ms var(--geo-spring); }
  [data-rp-game="geoguessr"] #round-results-screen.active .correct-location-info { animation: geo-stamp-in 360ms var(--geo-spring) both; }

  /* Final standings and popups. */
  [data-rp-game="geoguessr"] #results-screen.active .winner-icon { animation: geo-nod 420ms ease-out 200ms both; }
  [data-rp-game="geoguessr"] #results-screen.active .score-item { animation: geo-paper-arrive 280ms var(--geo-spring) both; }
  [data-rp-game="geoguessr"] #results-screen.active .score-item:nth-child(2) { animation-delay: 60ms; }
  [data-rp-game="geoguessr"] #results-screen.active .score-item:nth-child(3) { animation-delay: 120ms; }
  [data-rp-game="geoguessr"] #results-screen.active .score-item:nth-child(n+4) { animation-delay: 160ms; }
  [data-rp-game="geoguessr"] .confirm-dialog-overlay.active .confirm-dialog-modal { animation: geo-paper-arrive 280ms var(--geo-spring); }
}
@keyframes geo-character-arrive { from { opacity: 0; scale: .82; rotate: -10deg; } to { opacity: 1; scale: 1; rotate: 0deg; } }
@keyframes geo-nod { 0%, 100% { rotate: 0deg; } 35% { rotate: -8deg; } 70% { rotate: 5deg; } }
@keyframes geo-paper-arrive { from { opacity: 0; translate: 0 12px; scale: .97; } to { opacity: 1; translate: 0 0; scale: 1; } }
@keyframes geo-postcard { from { opacity: 0; translate: 0 12px; rotate: -2deg; scale: .96; } to { opacity: 1; translate: 0 0; rotate: 0deg; scale: 1; } }
@keyframes geo-stamp-in { from { opacity: 0; scale: 1.45; } to { opacity: 1; scale: 1; } }
@keyframes geo-answer-stamp { 0% { scale: .94; } 65% { scale: 1.025; } 100% { scale: 1; } }
@keyframes geo-pin-drop { from { translate: 0 -18px; } to { translate: 0 0; } }

/* Classic results: the correct-location label was centred full-width at the very top, so longer names
   («Рио-де-Жанейро, Бразилия») ran under the absolute back arrow (left 16px, 44×44) and the map's top
   edge sat under the arrow too. Keep the label in the arrow's row but clear of it on both sides. */
[data-rp-game="geoguessr"] #round-results-screen .correct-location-info {
  display: flex; align-items: center; justify-content: center;
  min-height: 44px; margin-bottom: 8px; padding: 0 64px;
  line-height: 1.2; overflow-wrap: anywhere;
}

/* Like / dislike / report on the location (shared content-report.css), on the round's photo while guessing. */
:root {
  --rp-report-surface: var(--geo-surface);
  --rp-report-text: #ffffff;
  --rp-report-muted: var(--text-secondary);
  --rp-report-accent: var(--geo-green);
  --rp-report-accent-ink: var(--geo-ink);
}
/* On the round's photo (it is the card): thumbs in a pill at the bottom centre, the flag in a round
   badge top-right, both on the dark surface so they read over any picture. */
[data-rp-game="geoguessr"] .street-photo-container .geo-card-vote {
  position: absolute; left: 50%; bottom: 8px; z-index: 3; transform: translateX(-50%);
  margin: 0; padding: 2px 6px; border-radius: 999px;
  background: rgb(33 28 84 / 82%); /* --geo-surface */
  box-shadow: 0 2px 8px rgb(0 0 0 / 25%);
}
[data-rp-game="geoguessr"] .geo-report-flag {
  position: absolute; top: 8px; right: 8px; z-index: 3; width: 36px; height: 36px; font-size: 16px;
  background: rgb(33 28 84 / 82%); color: rgb(201 196 240 / 85%);
  box-shadow: 0 2px 8px rgb(0 0 0 / 25%);
}
[data-rp-game="geoguessr"] .geo-report-flag[hidden] { display: none; }
[data-rp-game="geoguessr"] .geo-card-vote .rp-card-vote__btn { color: rgb(201 196 240 / 75%); }
[data-rp-game="geoguessr"] .geo-card-vote .rp-card-vote__btn[aria-pressed="true"] { color: var(--geo-green); }

/* Mode screen (shared mode-cards.css): surface cards, red and green blobs. */
:root {
  --mode-card-bg: var(--geo-surface);
  --mode-card-ink: #fff;
  --mode-card-muted: var(--text-secondary);
  --mode-card-border: var(--geo-line);
  --mode-card-accent: var(--geo-green);
  --mode-art-a: var(--geo-red);
  --mode-art-b: var(--geo-green);
  --mode-art-ink: var(--geo-ink);
  --mode-art-mouth: #fff;
}
[data-rp-game="geoguessr"] #mode-screen { padding-inline: 16px; padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px)); overflow-y: auto; }
[data-rp-game="geoguessr"] #mode-screen .mode-cards { flex: 0 1 auto; margin-block: auto; }

/* Round role line under the header: the impostor in red, the team in green, the eliminated muted. */
[data-rp-game="geoguessr"] .geo-role {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: fit-content; max-width: calc(100% - 24px); margin: 0 auto 10px; padding: 6px 14px;
  border-radius: 18px; background: var(--geo-surface); color: #fff;
  font-size: 14px; font-weight: 700; line-height: 1.3; text-align: left;
}
[data-rp-game="geoguessr"] .geo-role[hidden] { display: none; }
[data-rp-game="geoguessr"] .geo-role .rp-icon { flex: none; font-size: 18px; }
[data-rp-game="geoguessr"] .geo-role.is-impostor { background: var(--geo-red); }
[data-rp-game="geoguessr"] .geo-role.is-team .rp-icon { color: var(--geo-green); }
[data-rp-game="geoguessr"] .geo-role.is-out { color: var(--text-secondary); }
/* Street View rounds: the line floats over the panorama under the header, above the answer pill. */
#game-screen.geo-sphere .geo-role {
  position: fixed; left: 50%; top: calc(64px + env(safe-area-inset-top, 0px)); z-index: 3;
  transform: translateX(-50%); margin: 0; width: max-content; max-width: min(92vw, 420px);
  background: rgb(33 28 84 / 88%); box-shadow: 0 2px 8px rgb(0 0 0 / 25%);
}
#game-screen.geo-sphere .geo-role.is-impostor { background: rgb(214 48 55 / 92%); }
/* The like pill and flag sit lower while the role line is shown. */
#game-screen.geo-sphere:has(.geo-role:not([hidden])) .geo-card-vote { top: calc(134px + env(safe-area-inset-top, 0px)); }
#game-screen.geo-sphere:has(.geo-role:not([hidden])) .geo-report-flag { top: calc(138px + env(safe-area-inset-top, 0px)); }
#game-screen.geo-sphere:has(.geo-role:not([hidden])) .answer-feedback { top: calc(182px + env(safe-area-inset-top, 0px)); }

/* Lives: green hearts, lost ones faded. */
[data-rp-game="geoguessr"] .geo-hearts { display: inline-flex; flex: none; gap: 2px; }
[data-rp-game="geoguessr"] .geo-heart { font-size: 16px; color: rgba(255, 255, 255, .22); }
[data-rp-game="geoguessr"] .geo-heart.active { color: var(--geo-green); }
[data-rp-game="geoguessr"] .geo-heart.breaking { color: var(--geo-red); }

/* Player avatars on the vote, the round note and the lives board: photo cropped round, else initials. */
[data-rp-game="geoguessr"] :is(.geo-candidate-avatar, .geo-note-avatar, .geo-lives-avatar) {
  display: inline-grid; place-items: center; overflow: hidden; border-radius: 50%;
  background: var(--geo-green); color: var(--geo-ink); font-size: 15px; font-weight: 800;
}
[data-rp-game="geoguessr"] :is(.geo-candidate-avatar, .geo-note-avatar, .geo-lives-avatar) img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Round result line («Импостер: …» / «Теряет жизнь: …»). */
[data-rp-game="geoguessr"] .geo-round-note {
  width: min(100% - 32px, 480px); margin: 12px auto 0; padding: 12px 16px; box-sizing: border-box;
  border: 2px solid var(--geo-line); border-radius: 16px; background: var(--geo-surface); color: #fff; text-align: center;
}
[data-rp-game="geoguessr"] .geo-round-note[hidden] { display: none; }
[data-rp-game="geoguessr"] .geo-round-note p { margin: 0; color: var(--text-secondary); font-size: 15px; line-height: 1.4; }
[data-rp-game="geoguessr"] .geo-round-note-who { display: flex; align-items: center; justify-content: center; gap: 10px; margin-bottom: 6px; font-size: 18px; }
[data-rp-game="geoguessr"] .geo-note-avatar { width: 36px; height: 36px; flex: none; }
[data-rp-game="geoguessr"] .geo-round-note.is-caught { border-color: var(--geo-green); }
[data-rp-game="geoguessr"] .geo-round-note.is-escaped { border-color: var(--geo-red); }

/* «Кто импостер?» vote: avatar chips in a grid. */
[data-rp-game="geoguessr"] .vote-content { align-items: center; padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px)); }
[data-rp-game="geoguessr"] .geo-vote-progress { min-height: 20px; margin: 4px 0 12px; color: var(--text-secondary); font-size: 14px; text-align: center; }
[data-rp-game="geoguessr"] .geo-candidates { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; width: 100%; max-width: 480px; }
[data-rp-game="geoguessr"] .geo-candidate {
  display: flex; flex-direction: column; align-items: center; gap: 8px; min-height: 112px; padding: 14px 8px;
  border: 2px solid var(--geo-line); border-radius: 16px; background: var(--geo-surface); color: #fff;
  font: inherit; cursor: pointer;
}
[data-rp-game="geoguessr"] .geo-candidate strong { max-width: 100%; overflow-wrap: anywhere; font-size: 15px; line-height: 1.25; }
[data-rp-game="geoguessr"] .geo-candidate-avatar { width: 52px; height: 52px; flex: none; }
[data-rp-game="geoguessr"] .geo-candidate:disabled { cursor: default; opacity: .55; }
[data-rp-game="geoguessr"] .geo-candidate.selected,
[data-rp-game="geoguessr"] .geo-candidate.selected:disabled { opacity: 1; border-color: var(--geo-red); background: rgb(214 48 55 / 22%); }
@media (hover: hover) {
  [data-rp-game="geoguessr"] .geo-candidate:hover:not(:disabled) { border-color: #fff; }
}

/* «На выбывание» round board: lives instead of points. */
[data-rp-game="geoguessr"] .geo-lives-board { display: flex; flex-direction: column; gap: 8px; width: 100%; max-width: 480px; margin: 12px auto 0; }
[data-rp-game="geoguessr"] .geo-lives-row {
  display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; grid-template-areas: "avatar name hearts" "avatar dist hearts";
  align-items: center; column-gap: 10px; padding: 10px 14px;
  border: 2px solid var(--geo-line); border-radius: 14px; background: var(--geo-surface); color: #fff;
}
[data-rp-game="geoguessr"] .geo-lives-avatar { grid-area: avatar; width: 36px; height: 36px; }
[data-rp-game="geoguessr"] .geo-lives-name { grid-area: name; overflow: hidden; font-weight: 700; text-overflow: ellipsis; white-space: nowrap; }
[data-rp-game="geoguessr"] .geo-lives-row .geo-hearts { grid-area: hearts; }
[data-rp-game="geoguessr"] .geo-lives-distance { grid-area: dist; color: var(--text-secondary); font-size: 13px; }
[data-rp-game="geoguessr"] .geo-lives-row.is-losing { border-color: var(--geo-red); }
[data-rp-game="geoguessr"] .geo-lives-row.is-out { opacity: .55; }

/* Map markers: the impostor's view of the real place, the impostor's pin on the results map. */
.geo-impostor-target {
  width: 28px; height: 28px; box-sizing: border-box; border: 4px solid #9bcb31; border-radius: 50%;
  background: rgb(155 203 49 / 25%); box-shadow: 0 0 0 2px #fff;
}
.geo-impostor-pin {
  width: 16px; height: 16px; box-sizing: border-box; border: 3px solid #fff; border-radius: 50%;
  background: #c084fc; box-shadow: 0 2px 6px rgb(0 0 0 / 30%);
}
@media (prefers-reduced-motion: no-preference) {
  .geo-impostor-target { animation: geo-target-pulse 1.6s ease-in-out infinite; }
  [data-rp-game="geoguessr"] .geo-heart.breaking { animation: geo-heart-break 600ms ease-out both; }
  [data-rp-game="geoguessr"] #vote-screen.active .geo-candidate { animation: geo-paper-arrive 280ms var(--geo-spring) both; }
}
@keyframes geo-target-pulse { 0%, 100% { scale: 1; } 50% { scale: 1.18; } }
@keyframes geo-heart-break { 0% { scale: 1.4; } 40% { rotate: -14deg; } 70% { rotate: 10deg; } 100% { scale: 1; rotate: 0deg; } }

/* ── The /tv/ look on the phones and the PC (owner 2026-10-29: «на тел, пк и тв стили должны выглядеть одинаково…
   за образец возьми тв»), as «Кто из нас» and «Что за мем?» ──
   Background: the TV's spheres (particles.js, body[data-rp-spheres]) in the game's palette, the same as on /tv/.
   Cut paper: the boards are the shared cut-paper.css (<body data-rp-paper>) with the globe green; here the game's own
   cut pieces as on /tv/ (geo-stage.css): the results map in a white frame with the green shadow, the place stamped on
   a white label, the round note and the lives rows as cut cards, the vote's players as cut cards. The results map's
   flag and avatar pins are the /tv/ ones (shared/client/geo-stage.ts drawGeoGuesses). */
body[data-rp-game="geoguessr"] {
  --paper-gold: var(--geo-green);
  --paper-surface: var(--geo-surface);
  --paper-line: var(--geo-line);
  --paper-lead-shadow: 5px 6px 0 color-mix(in srgb, var(--geo-green) 55%, #000);
}
[data-rp-paper][data-rp-game="geoguessr"] .results-map {
  border: 6px solid #fff; border-radius: var(--cut-1); box-sizing: border-box;
  box-shadow: 6px 7px 0 color-mix(in srgb, var(--geo-green) 55%, transparent); rotate: -.5deg;
}
[data-rp-paper][data-rp-game="geoguessr"] #round-results-screen .correct-location-info {
  width: fit-content; max-width: calc(100% - 128px); margin: 0 auto 12px; padding: 8px 16px; min-height: 0;
  font-family: var(--font-display); font-weight: 800; color: var(--geo-ink); background: #fff;
  border-radius: var(--cut-3); box-shadow: 4px 5px 0 color-mix(in srgb, var(--geo-green) 60%, transparent); rotate: .8deg;
}
[data-rp-paper][data-rp-game="geoguessr"] :is(.geo-round-note, .geo-lives-row, .geo-candidate) { border-radius: var(--cut-1); box-shadow: var(--cut-shadow); rotate: -.5deg; }
/* The note stays straight: the reveal below starts at its edge, a tilt would tuck its corner under it. */
[data-rp-paper][data-rp-game="geoguessr"] .geo-round-note { rotate: none; }
[data-rp-paper][data-rp-game="geoguessr"] :is(.geo-lives-row, .geo-candidate):nth-child(4n + 2) { border-radius: var(--cut-2); rotate: .6deg; }
[data-rp-paper][data-rp-game="geoguessr"] :is(.geo-lives-row, .geo-candidate):nth-child(4n + 3) { border-radius: var(--cut-3); rotate: -.3deg; }
[data-rp-paper][data-rp-game="geoguessr"] :is(.geo-lives-row, .geo-candidate):nth-child(4n + 4) { border-radius: var(--cut-4); rotate: .4deg; }
[data-rp-paper][data-rp-game="geoguessr"] .geo-lives-row:first-child { box-shadow: var(--paper-lead-shadow); }
[data-rp-paper][data-rp-game="geoguessr"] .geo-candidate.selected { box-shadow: 5px 6px 0 color-mix(in srgb, var(--geo-red) 55%, #000); }
/* The phone's results map: the pins a little smaller than on the big screen. */
[data-rp-game="geoguessr"] .results-map .gss-pin-avatar { font-size: 11px; }
[data-rp-game="geoguessr"] .results-map .leaflet-tooltip.gss-tooltip { font-size: 13px; }
/* The PC stage's results live in the round results screen; the phone column never shows them. */
html:not(.rp-stage) #round-results-screen > .gss-root { display: none; }
/* /cut-paper.css */
/* «Вырезанная бумага» — the /tv/ look on the phones and the PC (owner 2026-10-29: «на тел, пк и тв стили должны
   выглядеть одинаково… за образец возьми тв»; one shared file since 2026-10-29: «почему не применяется
   переиспользование?»). Opt in with <body data-rp-paper> and load this file AFTER the game's theme CSS.

   Answers, the reveal's answers and the boards are hand-cut pieces as on /tv/ (tv/style.css): uneven corners in
   turn, a slight tilt, a hard shadow without blur. The tilt is the separate `rotate`, so a press (`scale` /
   `translate`) and a stamp or shake (`transform`) still work. The round leaderboard rows stay straight boxes:
   reveal-results.js measures them to slide overtakes (a tilted row measures taller and jumps, Black#722), so their
   card is a ::before. Never tilt an element reveal-results.js measures.

   A game sets only its colours, on [data-rp-game="<game>"] in its theme:
     --paper-gold          the /tv/ «gold» of the game: the pick, the leader, the round scores (required)
     --paper-surface       the leaderboard card            (default: a light veil)
     --paper-line          its edge                        (default: white 10 %)
     --paper-line-width    its edge width                  (default: 1px)
     --paper-lead-surface  the leader's card               (default: --paper-surface)
     --paper-lead-line     the leader's edge               (default: --paper-gold)
     --paper-lead-shadow   the pick's / leader's shadow    (default: --paper-gold darkened)
     --cut-shadow          the plain card's shadow         (default: black 34 %)
   Game-only pieces (the board of «100 к 1», «VS» of «Смехлыст», the sides of «Что бы ты выбрал?») stay in the
   game's theme and use the tokens below; an override there needs `body[data-rp-game="…"]` to win over this file.

   Dealing: shared/client/tv-look.ts `deal()` puts `.rp-dealing` on a container for a moment; its children drop in
   one by one. */
[data-rp-paper] {
  /* The /tv/ display font (tv/style.css --font-display): letters, numbers, stamps. */
  --font-display: 'Unbounded', 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --cut-1: 18px 9px 16px 11px / 11px 17px 9px 15px;
  --cut-2: 10px 17px 10px 18px / 17px 10px 16px 9px;
  --cut-3: 16px 11px 19px 9px / 9px 15px 11px 18px;
  --cut-4: 9px 18px 11px 16px / 16px 9px 18px 11px;
  --cut-shadow: 4px 5px 0 rgb(0 0 0 / 34%);
  --paper-lead-shadow: 5px 6px 0 color-mix(in srgb, var(--paper-gold, #ffd43a) 65%, #000);
}

/* Cards: answers, the reveal's answers, the final boards (also the shared game-end board, .leader-row). */
[data-rp-paper] :is(.quiz-option, .rr-option, .score-item, .leader-row) { border-radius: var(--cut-1); box-shadow: var(--cut-shadow); rotate: -.6deg; }
[data-rp-paper] :is(.quiz-option, .rr-option, .score-item, .leader-row):nth-child(4n + 2) { border-radius: var(--cut-2); rotate: .7deg; }
[data-rp-paper] :is(.quiz-option, .rr-option, .score-item, .leader-row):nth-child(4n + 3) { border-radius: var(--cut-3); rotate: -.35deg; }
[data-rp-paper] :is(.quiz-option, .rr-option, .score-item, .leader-row):nth-child(4n + 4) { border-radius: var(--cut-4); rotate: .45deg; }
/* Board rows turn half as much as answer cards (owner 2026-10-29: «расброс наклона меньше»; /tv/ the same). */
[data-rp-paper] :is(.score-item, .leader-row) { rotate: -.3deg; }
[data-rp-paper] :is(.score-item, .leader-row):nth-child(4n + 2) { rotate: .35deg; }
[data-rp-paper] :is(.score-item, .leader-row):nth-child(4n + 3) { rotate: -.18deg; }
[data-rp-paper] :is(.score-item, .leader-row):nth-child(4n + 4) { rotate: .22deg; }
[data-rp-paper] .quiz-option.selected { box-shadow: var(--paper-lead-shadow); }
[data-rp-paper] :is(.quiz-option.correct, .rr-option.rr-type-correct) { box-shadow: 5px 6px 0 color-mix(in srgb, var(--rp-correct, #4ade80) 50%, #000); }
[data-rp-paper] .quiz-option.wrong { box-shadow: 4px 5px 0 color-mix(in srgb, var(--rp-wrong, #f87171) 45%, #000); }
/* The answer letter: a stamp, cut too and turned the other way (tv .tv-option-letter). */
[data-rp-paper] .option-letter {
  border-radius: 46% 54% 50% 50% / 54% 46% 54% 46%; rotate: -6deg;
  box-shadow: 2px 3px 0 rgb(0 0 0 / 30%); font-family: var(--font-display); font-weight: 800;
}
[data-rp-paper] .quiz-option:nth-child(even) .option-letter { rotate: 5deg; border-radius: 54% 46% 46% 54% / 46% 54% 50% 50%; }
/* Final board: the winner leans out with the game's gold shadow. */
[data-rp-paper] :is(.score-item, .leader-row):first-child { rotate: -.6deg; box-shadow: var(--paper-lead-shadow); }
/* The game-end board scrolls (game-end.css: overflow-y auto), which clips the tilted rows and their shadows: room for
   them inside the list (--cut-room, as in question-stage.css), taken back from the card's padding so nothing moves. */
[data-rp-paper] .leaderboard {
  margin: calc(-1 * var(--cut-room, 10px));
  padding: var(--cut-room, 10px);
}

/* Dealing: each card drops from a little above with a turn and settles with a bounce, 80 ms apart. */
[data-rp-paper] .rp-dealing > * {
  animation: rp-cut-in .5s cubic-bezier(.3, 1.45, .5, 1) backwards;
  animation-delay: calc(60ms + var(--deal, 0) * 80ms);
}
[data-rp-paper] .rp-dealing > :nth-child(2) { --deal: 1; }
[data-rp-paper] .rp-dealing > :nth-child(3) { --deal: 2; }
[data-rp-paper] .rp-dealing > :nth-child(4) { --deal: 3; }
[data-rp-paper] .rp-dealing > :nth-child(5) { --deal: 4; }
[data-rp-paper] .rp-dealing > :nth-child(6) { --deal: 5; }
[data-rp-paper] .rp-dealing > :nth-child(n + 7) { --deal: 6; }
@keyframes rp-cut-in { from { opacity: 0; transform: translateY(-18px) rotate(-4deg) scale(1.04); } }

/* Round leaderboard: the row box stays straight, its cut-paper card behind the content turns and shifts; the
   leader leans out with the gold edge and shadow (tv .rr-lb-row). */
[data-rp-paper] .rr-lb-row {
  --paper-row-bg: var(--paper-surface, rgb(255 255 255 / 6%)); --paper-row-line: var(--paper-line, rgb(255 255 255 / 10%));
  --paper-tilt: -.3deg; --paper-shift: -1.5px 0; --paper-cut: var(--cut-1); --paper-row-shadow: var(--cut-shadow);
  isolation: isolate; background: none; border-color: transparent;
}
[data-rp-paper] .rr-lb-row:nth-child(4n + 2) { --paper-tilt: .35deg; --paper-shift: 2px .5px; --paper-cut: var(--cut-2); }
[data-rp-paper] .rr-lb-row:nth-child(4n + 3) { --paper-tilt: -.18deg; --paper-shift: 1px -.5px; --paper-cut: var(--cut-3); }
[data-rp-paper] .rr-lb-row:nth-child(4n + 4) { --paper-tilt: .22deg; --paper-shift: -2px .5px; --paper-cut: var(--cut-4); }
[data-rp-paper] .rr-lb-row.rr-leading {
  border-color: transparent; background: none;
  --paper-row-bg: var(--paper-lead-surface, var(--paper-surface, rgb(255 255 255 / 10%)));
  --paper-row-line: var(--paper-lead-line, var(--paper-gold));
  --paper-tilt: -.6deg; --paper-shift: -2.5px -.5px; --paper-row-shadow: var(--paper-lead-shadow);
}
[data-rp-paper] .rr-lb-row::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  border-radius: var(--paper-cut); background: var(--paper-row-bg);
  border: var(--paper-line-width, 1px) solid var(--paper-row-line); box-shadow: var(--paper-row-shadow);
  rotate: var(--paper-tilt); translate: var(--paper-shift);
  transition: rotate .5s cubic-bezier(.3, 1.4, .5, 1), translate .5s ease, border-radius .5s ease, box-shadow .4s ease, border-color .3s ease, background-color .3s ease;
}
/* The round's scores in the game's gold, as on /tv/ (tv/style.css .rr-lb-score). */
[data-rp-paper] .rr-lb-score { color: var(--paper-gold); }

@media (prefers-reduced-motion: reduce) {
  [data-rp-paper] .rp-dealing > * { animation: none; }
  [data-rp-paper] .rr-lb-row::before { transition: none; }
}
/* /geo-stage.css */
/* «Геоугадайка» on the big screen, one look on the shared screen (/tv/) and on a PC player's stage (owner 2026-10-29:
   «версии некоторых экранов в ПК и ТВ почти не отличаются» → one code for both, after wml-stage.css and the others).
   The markup and the moving part are shared/client/geo-stage.ts. The page supplies the palette (--geo-green,
   --geo-red, --geo-surface, --geo-ink, --tv-line, --text-secondary, --rp-wrong) and the cuts (--cut-1…4, --cut-shadow).

   The map is a cut-paper picture with a white frame and the globe-green shadow (no Street View: billed per load).
   play / vote: the map left, «Где это?» or «Кто импостер?» and the hint right («На выбывание»: everyone's hearts).
   reveal: the flag and the avatar pins with dashed lines on the map; the place on a white cut card, a row per player
   (distance, points or hearts) dealt in the pins' order, then the round's board (reveal-results.js) in their place.
   The pins are also the phone's results map (drawGeoGuesses). */
@keyframes gss-cut-in { from { opacity: 0; transform: translateY(-26px) rotate(-5deg) scale(1.06); } }
@keyframes gss-row-in { from { opacity: 0; transform: translateX(30px) rotate(1.5deg); } }
@keyframes gss-drop { 0% { opacity: 0; transform: translateY(-46px) scale(1.25); } 60% { opacity: 1; transform: translateY(4px) scale(.95); } 100% { transform: none; } }
@keyframes gss-wave { 0%, 100% { transform: skewY(0); } 50% { transform: skewY(-7deg); } }
@keyframes gss-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--geo-green, #9bcb31) 70%, transparent); } 100% { box-shadow: 0 0 0 22px transparent; } }
@keyframes gss-heart { 0% { transform: scale(1); } 40% { transform: scale(1.5); } 100% { transform: scale(1); opacity: .3; } }

.gss-root { flex: 1; min-height: 0; display: flex; align-items: stretch; gap: 34px; padding: 4px 6px 12px; }
.gss-map-card {
    flex: 0 0 61%; min-width: 0; position: relative; padding: 10px; background: #fff;
    border-radius: var(--cut-1); box-shadow: 9px 11px 0 color-mix(in srgb, var(--geo-green, #9bcb31) 55%, transparent);
    rotate: -.6deg; animation: gss-cut-in .7s cubic-bezier(.3, 1.45, .5, 1) both;
}
.gss-map { position: relative; width: 100%; height: 100%; overflow: hidden; border-radius: var(--cut-2); background: #aad3df; }
.gss-map .leaflet-control-attribution { font-size: 10px; }
.gss-map .geo-map-error { position: absolute; inset: 0; display: grid; place-content: center; gap: 14px; text-align: center; color: #fff; background: var(--geo-surface, #211c54); }
.gss-map .geo-map-error p { margin: 0; font-size: 22px; font-weight: 700; }
.gss-map .geo-map-retry { justify-self: center; padding: 12px 26px; font-size: 18px; font-weight: 800; border: 0; border-radius: 999px; color: #fff; background: var(--geo-red, #d63037); }

.gss-side { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; justify-content: center; gap: 16px; }
.gss-root :is(.gss-place, .gss-note, .gss-rows, .gss-board) { display: none; }
.gss-root[data-step="reveal"] .gss-ask { display: none; }
.gss-root[data-step="reveal"] :is(.gss-place, .gss-rows) { display: flex; }
.gss-root[data-step="reveal"] .gss-note:not(:empty) { display: block; }
.gss-root[data-step="reveal"][data-phase="board"] .gss-rows { display: none; }
.gss-root[data-step="reveal"][data-phase="board"] .gss-board { display: block; }

/* play / vote */
.gss-ask { display: flex; flex-direction: column; gap: 14px; animation: gss-row-in .5s ease both .15s; }
.gss-kicker { margin: 0; font-size: 20px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--geo-green, #9bcb31); }
.gss-title { margin: 0; font-family: var(--font-display, 'Unbounded', sans-serif); font-size: 58px; font-weight: 800; line-height: 1.05; letter-spacing: -.02em; color: #fff; }
.gss-hint { margin: 0; font-size: 23px; font-weight: 600; line-height: 1.35; color: var(--text-secondary, #c9c4f0); text-wrap: pretty; }
.gss-lives { display: flex; flex-direction: column; gap: 8px; margin: 6px 0 0; padding: 0; list-style: none; max-height: 300px; overflow: hidden; }
.gss-lives:empty { display: none; }
.gss-life { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 20px; }
.gss-life.is-out { opacity: .45; }

/* Hearts: «На выбывание» */
.gss-hearts { display: inline-flex; gap: 2px; flex: none; }
.gss-heart { font-size: 20px; color: var(--rp-wrong, #fe726d); }
.gss-row .gss-heart { font-size: 17px; }
.gss-tag:empty { display: none; }
.gss-heart.is-empty { color: rgb(255 255 255 / 22%); }
.gss-heart.is-losing { color: rgb(255 255 255 / 22%); animation: gss-heart .9s ease both calc(1s + var(--gss-deal, 0) * .52s); }

/* reveal: the place */
.gss-place {
    flex-direction: column; gap: 4px; padding: 20px 26px; color: var(--geo-ink, #17191f); background: #fff;
    border-radius: var(--cut-3); box-shadow: 7px 9px 0 color-mix(in srgb, var(--geo-green, #9bcb31) 60%, transparent);
    rotate: .8deg; animation: gss-cut-in .6s cubic-bezier(.3, 1.45, .5, 1) both .2s;
}
.gss-place-label { margin: 0; font-size: 15px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: #5a5480; }
.gss-place-name { margin: 0; font-family: var(--font-display, 'Unbounded', sans-serif); font-size: 30px; font-weight: 800; line-height: 1.15; letter-spacing: -.01em; text-wrap: balance; overflow-wrap: anywhere; }
.gss-note { margin: 0; padding: 12px 18px; font-size: 19px; font-weight: 700; line-height: 1.35; border-radius: var(--cut-2); background: var(--geo-surface, #211c54); border: 2px solid var(--tv-line, rgb(255 255 255 / 14%)); }
.gss-note.is-caught { border-color: var(--geo-green, #9bcb31); }
.gss-note.is-escaped { border-color: #c084fc; }

/* reveal: a row per player, dealt in the pins' order (farthest first); the clipping list keeps room for the cut cards. */
.gss-rows {
    flex: 1 1 auto; min-height: 0; flex-direction: column; justify-content: safe center; gap: 8px; margin: 0;
    padding: var(--cut-room, 14px); list-style: none; overflow: hidden;
}
.gss-row {
    display: flex; align-items: center; gap: 9px; min-height: 0; padding: 0 12px;
    height: min(58px, calc((420px - (var(--gss-rows, 1) - 1) * 8px) / var(--gss-rows, 1)));
    background: var(--geo-surface, #211c54); border: 1.5px solid var(--tv-line, rgb(255 255 255 / 14%));
    border-radius: var(--cut-1); box-shadow: var(--cut-shadow, 5px 6px 0 rgb(0 0 0 / 34%)); rotate: -.5deg; font-size: 20px;
}
.gss-row:nth-child(4n + 2) { border-radius: var(--cut-2); rotate: .6deg; }
.gss-row:nth-child(4n + 3) { border-radius: var(--cut-3); rotate: -.3deg; }
.gss-row:nth-child(4n + 4) { border-radius: var(--cut-4); rotate: .4deg; }
.gss-row:first-child { border-color: var(--geo-green, #9bcb31); box-shadow: 6px 7px 0 color-mix(in srgb, var(--geo-green, #9bcb31) 55%, #000); }
.gss-rows.is-dealing .gss-row { animation: gss-row-in .5s cubic-bezier(.3, 1.4, .5, 1) both; animation-delay: calc(1s + var(--gss-deal, 0) * .52s); }
.gss-rank {
    flex: none; display: grid; place-items: center; width: 34px; height: 34px; font-family: var(--font-display, 'Unbounded', sans-serif);
    font-size: 16px; font-weight: 800; color: var(--geo-ink, #17191f); background: var(--geo-green, #9bcb31);
    border-radius: 46% 54% 50% 50% / 54% 46% 54% 46%; rotate: -6deg; box-shadow: 2px 3px 0 rgb(0 0 0 / 30%);
}
.gss-row > :nth-child(2) { min-width: 96px; flex: 1 1 auto; overflow: hidden; }
.gss-distance { flex: none; margin-left: auto; font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }
.gss-points { flex: none; min-width: 66px; text-align: right; font-weight: 800; color: var(--geo-green, #9bcb31); font-variant-numeric: tabular-nums; }
.gss-tag { flex: none; padding: 3px 9px; font-size: 13px; font-weight: 800; border-radius: 999px; color: var(--geo-ink, #17191f); background: var(--rp-wrong, #fe726d); }
.gss-row.is-impostor .gss-tag { color: #fff; background: #8b4fd8; }
.gss-row.is-losing { border-color: var(--rp-wrong, #fe726d); }

/* reveal: the round's board (reveal-results.js) in the rows' place */
.gss-board { flex: 1 1 auto; position: relative; min-height: 0; }
.gss-board .rr-container.rr-dashboard .rr-screen2 { padding: var(--cut-room, 14px); justify-content: safe center; }
.gss-board .rr-leaderboard { width: 100%; gap: 8px; }
.gss-board .rr-leaderboard-title { font-size: 18px; margin-bottom: 10px; }
.gss-board .rr-lb-row { padding: 0 16px; gap: 12px; height: min(58px, calc((470px - (var(--tv-rows, 1) - 1) * 8px) / var(--tv-rows, 1))); }
.gss-board .rr-lb-pos { width: 34px; height: 34px; font-size: 16px; }
.gss-board .rr-lb-avatar { width: 36px; height: 36px; }
.gss-board .rr-lb-name { font-size: 21px; }
.gss-board .rr-lb-score { font-size: 22px; min-width: 60px; color: var(--geo-green, #9bcb31); }
.gss-board .rr-lb-delta { font-size: 17px; }

/* The map's pins (also the phone's results map: .gss-pin--small) */
.gss-pin-wrap { background: none; border: 0; }
.gss-pin {
    width: 100%; height: 100%; border-radius: 50%; border: 3px solid #fff; overflow: hidden; box-sizing: border-box;
    background: var(--geo-green, #9bcb31); box-shadow: 0 4px 10px rgb(0 0 0 / 40%); animation: gss-drop .5s cubic-bezier(.3, 1.4, .5, 1) both;
}
.gss-pin--impostor { border-color: #c084fc; box-shadow: 0 0 0 3px #8b4fd8, 0 4px 10px rgb(0 0 0 / 40%); }
.gss-pin .gss-pin-avatar { position: relative; overflow: hidden; display: grid; place-items: center; width: 100%; height: 100%; min-width: 0; margin: 0; border: 0; border-radius: 50%; font-size: 15px; font-weight: 800; color: var(--geo-ink, #17191f); background: var(--geo-green, #9bcb31); box-shadow: none; }
.gss-pin .gss-pin-avatar :is(img, video) { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 50%; }
.gss-flag { position: relative; width: 100%; height: 100%; animation: gss-drop .6s cubic-bezier(.3, 1.4, .5, 1) both; }
.gss-flag-pole { position: absolute; left: 6px; bottom: 2px; width: 4px; height: 48px; border-radius: 2px; background: var(--geo-ink, #17191f); }
.gss-flag-cloth {
    position: absolute; left: 10px; top: 2px; width: 32px; height: 22px; transform-origin: left center;
    background: var(--geo-red, #d63037); border: 2px solid #fff; border-left: 0; border-radius: 0 6px 6px 0; animation: gss-wave 1.6s ease-in-out infinite;
}
.gss-flag-dot { position: absolute; left: 1px; bottom: -3px; width: 14px; height: 14px; border-radius: 50%; background: var(--geo-green, #9bcb31); border: 2px solid #fff; animation: gss-pulse 1.4s ease-out infinite; }
.gss-line { stroke: var(--geo-red, #d63037); stroke-opacity: .9; }
.gss-line--impostor { stroke: #8b4fd8; }
.leaflet-tooltip.gss-tooltip {
    padding: 4px 10px; font-size: 15px; font-weight: 800; color: var(--geo-ink, #17191f); background: #fff;
    border: 0; border-radius: 10px 6px 11px 7px / 7px 11px 6px 10px; box-shadow: 3px 4px 0 rgb(0 0 0 / 30%); white-space: nowrap;
}
.leaflet-tooltip.gss-tooltip::before { display: none; }

@media (prefers-reduced-motion: reduce) {
    .gss-root *, .gss-root *::before, .gss-root *::after, .gss-pin, .gss-flag, .gss-flag * { animation-duration: .01ms !important; animation-iteration-count: 1 !important; animation-delay: 0s !important; }
}
/* /game-header.css */
/*
 * «Шапка игры» (shared/client/game-header.ts, bundle /game-header.js): one top bar in every game.
 *   [menu]   [cube + roomplay]   [timer]
 * Fixed at the top; on its screens the game's own back arrow, pause button and «Ещё игры» cube are
 * hidden ([data-rp-gh-hidden]). A game theme sets only tokens, never the classes:
 *   --rp-gh-ink         icons, logo text, timer text (default: the page's --text-primary, else white)
 *   --rp-gh-chip        button and timer background (default: the ink at 14 %)
 *   --rp-gh-line        button border (default: the ink at 24 %)
 *   --rp-gh-timer-bg / --rp-gh-timer-ink   the timer chip (default: chip / ink)
 *   --rp-gh-low         the timer at 5 s and less (default: #ff4d5e)
 *   --rp-gh-space       where the header's screens start (padding-top), under the bar
 * The menu card and the actions it adds to a pause card use the pause screen's fixed dark palette
 * (pause-overlay.css).
 */
:root {
    --rp-gh-space: calc(80px + env(safe-area-inset-top, 0px));
}

.rp-game-header {
    --rp-gh-ink-v: var(--rp-gh-ink, var(--text-primary, #ffffff));
    position: fixed;
    z-index: 70;
    top: calc(12px + env(safe-area-inset-top, 0px));
    left: 50%;
    transform: translateX(-50%);
    width: min(100%, 560px);
    box-sizing: border-box;
    padding: 0 16px;
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) minmax(44px, auto);
    align-items: center;
    gap: 8px;
    height: 48px;
    color: var(--rp-gh-ink-v);
    font-family: 'Manrope', var(--font-body, system-ui), sans-serif;
    pointer-events: none;
}
.rp-game-header[hidden] { display: none; }
.rp-game-header > * { pointer-events: auto; }

.rp-gh-btn {
    width: 44px;
    height: 44px;
    padding: 0;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.24);
    border-color: var(--rp-gh-line, color-mix(in srgb, var(--rp-gh-ink-v) 24%, transparent));
    background: rgba(255, 255, 255, 0.14);
    background: var(--rp-gh-chip, color-mix(in srgb, var(--rp-gh-ink-v) 14%, transparent));
    color: inherit;
    display: grid;
    place-items: center;
    font-size: 22px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    transition: transform 0.15s ease;
}
.rp-gh-btn:active { transform: scale(0.9); }

.rp-gh-brand {
    /* Centred on the screen whatever the timer's width. */
    position: absolute;
    left: 50%;
    top: 2px;
    transform: translateX(-50%);
    max-width: calc(100% - 2 * (16px + 44px + 12px));
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 44px;
    padding: 0 10px 0 4px;
    border: 0;
    border-radius: 22px;
    background: transparent;
    color: inherit;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.15s ease;
}
.rp-gh-brand:active { transform: translateX(-50%) scale(0.94); }
.rp-gh-cube {
    width: 34px;
    height: 34px;
    object-fit: contain;
    flex: none;
    filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.3));
}
.rp-gh-word {
    font-family: 'Unbounded', 'Manrope', system-ui, sans-serif;
    font-size: 17px;
    font-weight: 700;
    letter-spacing: 0.01em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.rp-gh-timer {
    grid-column: 3;
    justify-self: end;
    min-width: 44px;
    height: 44px;
    box-sizing: border-box;
    padding: 0 10px;
    border-radius: 22px;
    display: grid;
    place-items: center;
    background: rgba(255, 255, 255, 0.14);
    background: var(--rp-gh-timer-bg, var(--rp-gh-chip, color-mix(in srgb, var(--rp-gh-ink-v) 14%, transparent)));
    color: var(--rp-gh-timer-ink, inherit);
    font-size: 18px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}
.rp-gh-timer[hidden] { display: none; }
.rp-gh-timer--low {
    background: var(--rp-gh-low, #ff4d5e);
    color: #ffffff;
    animation: rp-gh-low 1s ease-in-out infinite;
}
@keyframes rp-gh-low {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.08); }
}

/* The header's screens start under the bar, the same distance in every game (it replaces the room
   each game kept for its own back arrow). */
html.rp-has-game-header .screen.rp-gh-screen { padding-top: var(--rp-gh-space) !important; }
/* Online games pad their .screen-content instead; the round reveal (reveal-results.css) covers the
   screen absolutely. Both start under the bar too. */
html.rp-has-game-header .screen.rp-gh-screen > .screen-content { padding-top: 0 !important; }
html.rp-has-game-header .screen.rp-gh-screen .rr-container { top: var(--rp-gh-space); }
/* An in-flow reveal (.rr-flow) already sits under the bar with the content above it. */
html.rp-has-game-header .screen.rp-gh-screen .rr-flow > .rr-container { top: auto; }
/* The round row of the game template (.game-header: round badge, timer) kept room for the old back
   arrow on the left; the arrow is gone. */
html.rp-has-game-header .screen.rp-gh-screen .game-header { padding-left: 0 !important; }

/* What the header replaces on its screens. */
[data-rp-gh-hidden] { display: none !important; }

/* The menu card (guests, games without a pause) and the actions on every pause card. */
.rp-gh-menu-overlay.active { cursor: default; }
.rp-gh-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    margin-top: 2px;
}
.rp-gh-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: 52px;
    padding: 0 18px;
    border-radius: 30px;
    border: 2px solid var(--rp-pause-line, rgba(255, 255, 255, 0.26));
    background: transparent;
    color: var(--rp-pause-ink, #ffffff);
    font: inherit;
    font-size: 16px;
    font-weight: 700;
    cursor: pointer;
}
.rp-gh-exit {
    border-color: transparent;
    color: var(--rp-pause-muted, rgba(255, 255, 255, 0.74));
}
/* «Сообщить об ошибке»: a quiet link under the card's actions, not a third big button. */
.rp-gh-report {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    align-self: center;
    min-height: 40px;
    padding: 6px 12px;
    background: none;
    border: none;
    color: var(--rp-pause-muted, rgba(255, 255, 255, 0.74));
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    opacity: 0.8;
    cursor: pointer;
}
.rp-gh-report .rp-icon { font-size: 16px; }

/* The bug report form over the pause card (shared/client/bug-report.ts): the pause palette, above it. */
.rp-bug-overlay {
    --rp-pause-ink: #ffffff;
    --rp-pause-muted: rgba(255, 255, 255, 0.74);
    --rp-pause-chip: rgba(255, 255, 255, 0.12);
    --rp-pause-line: rgba(255, 255, 255, 0.26);
    position: fixed;
    inset: 0;
    z-index: 990;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: max(24px, env(safe-area-inset-top)) 16px max(24px, env(safe-area-inset-bottom));
    box-sizing: border-box;
    overflow-y: auto;
    background: rgba(9, 11, 20, 0.94);
    color: var(--rp-pause-ink);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    animation: rp-pause-in 220ms ease-out;
}
.rp-bug-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    width: 100%;
    max-width: 360px;
    margin: auto;
    text-align: center;
}
.rp-bug-card [hidden] { display: none !important; }
.rp-bug-title { margin: 0; font-size: 22px; font-weight: 800; line-height: 1.25; color: var(--rp-pause-ink); }
.rp-bug-text {
    width: 100%;
    box-sizing: border-box;
    min-height: 104px;
    padding: 12px 14px;
    border-radius: 16px;
    border: 1px solid var(--rp-pause-line);
    background: var(--rp-pause-chip);
    color: var(--rp-pause-ink);
    font: inherit;
    font-size: 16px;
    line-height: 1.4;
    resize: vertical;
}
.rp-bug-text::placeholder { color: var(--rp-pause-muted); opacity: 0.8; }
.rp-bug-text:focus { outline: 2px solid var(--rp-pause-ink); outline-offset: 1px; }
.rp-bug-attach {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: 48px;
    padding: 0 16px;
    border-radius: 30px;
    border: 2px dashed var(--rp-pause-line);
    background: transparent;
    color: var(--rp-pause-ink);
    font: inherit;
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
}
.rp-bug-preview { position: relative; align-self: center; }
.rp-bug-thumb {
    display: block;
    max-width: 160px;
    max-height: 160px;
    border-radius: 12px;
    border: 1px solid var(--rp-pause-line);
}
.rp-bug-remove {
    position: absolute;
    top: -10px;
    right: -10px;
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1px solid var(--rp-pause-line);
    background: #12131a;
    color: var(--rp-pause-ink);
    cursor: pointer;
}
.rp-bug-status { margin: 0; font-size: 14px; color: #ffb4b4; }
.rp-bug-overlay .rp-bug-send {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    margin-top: 4px;
    background: var(--rp-pause-ink);
    color: #12131a;
    border: none;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.rp-bug-overlay .rp-bug-send:disabled { opacity: 0.45; cursor: default; box-shadow: none; }

/* The header's «Выйти из игры» replaces the online pause's own exit link. */
.rp-pause-card:has(> .rp-gh-actions) > .rp-pause-exit { display: none; }

@media (prefers-reduced-motion: reduce) {
    .rp-gh-timer--low { animation: none; }
}
/* /pc-stage.css */
/*
 * «Игра с ПК» (owner 2026-10-29: «почему бы не сделать tv играбельным?» → «делай»). Whoever opens the site with a
 * mouse in a wide window gets the /tv/ look and plays from there: the same pages and the same logic as on a phone,
 * laid out on a 1280×720 stage that pwa-overrides.js scales to the window with CSS zoom (html.rp-stage,
 * html[data-stage-page] = the page's <meta name="rp-stage">). A narrow window or a touch screen keeps the phone
 * column. Mockups: /mnt/project-files/tv-play-from-pc/.
 *
 * Rules kept from /tv/: the shared components keep their looks (game header, packs, reveal-results, PlayerAvatar,
 * game-end), only their size and place change; cut-paper cards (uneven corners, a small tilt through `rotate` /
 * `translate`, a hard shadow) for cards and rows, never for buttons, and never on rows reveal-results.js measures
 * (their card is a ::before); text that sits over the background spheres gets a backing.
 * Everything here is under html.rp-stage, so the phone layout cannot change.
 */
html.rp-stage {
    --st-bg: #100f36;
    --st-bg-end: #0b0a28;
    --st-panel: #1d1752;
    --st-card: #241b62;
    --st-line: rgb(255 255 255 / 14%);
    --st-text: #fff;
    --st-muted: #cbc4e6;
    --st-accent: #6640ba;
    --st-gold: #d5ae58;
    --st-display: 'Unbounded', 'Manrope', system-ui, sans-serif;
    --cut-1: 26px 12px 22px 16px / 16px 24px 12px 22px;
    --cut-2: 14px 24px 14px 26px / 24px 14px 22px 12px;
    --cut-3: 22px 15px 27px 12px / 12px 21px 15px 26px;
    --cut-4: 12px 26px 15px 22px / 22px 12px 26px 15px;
    --cut-shadow: 5px 6px 0 rgb(0 0 0 / 34%);
    overflow-x: hidden;
}
/* The spheres are sized in vmin of the real window, so their layer cancels the stage zoom. */
html.rp-stage .particles { zoom: calc(1 / var(--rp-stage-zoom, 1)); }
/* The brand colours where no game is picked yet; a room with a game takes the game's (particles.js). */
html.rp-stage:is([data-stage-page="catalog"], [data-stage-page="room"], [data-stage-page="join"]):not([data-room-game]) {
    --rp-sphere-1: #8f6ae0;
    --rp-sphere-2: #63b0fc;
    --rp-sphere-3: #f77cb0;
    --rp-sphere-4: #d5ae58;
}
html.rp-stage:is([data-stage-page="catalog"], [data-stage-page="room"], [data-stage-page="join"]) body {
    background: linear-gradient(180deg, var(--st-bg) 0%, var(--st-bg-end) 100%);
}
/* Owner 2026-10-29 «палитры втф»: a room with a game wears that game's palette on the stage, as on the phone. The dark
   stage background stayed under the light palettes (Имаджинариум, Что за мем?, Рисовач, Joking Hazard…), whose text is
   dark, so the game card, the players and the buttons went dark on dark. The room's own tokens (room-themes.css) give
   the background and the panels, so every palette keeps its contrast. */
html.rp-stage:is([data-stage-page="room"], [data-stage-page="join"])[data-room-game] {
    --st-panel: var(--room-menu);
    --st-line: var(--room-line);
}
html.rp-stage:is([data-stage-page="room"], [data-stage-page="join"])[data-room-game] body {
    background: linear-gradient(180deg, var(--room-bg) 0%, var(--room-bg-deep) 100%);
}

/* ── Game header (shared/client/game-header.ts): across the stage, bigger, like the /tv/ top row ── */
html.rp-stage .rp-game-header {
    width: 100%; max-width: none; padding: 0 44px; height: 64px; top: 18px;
    grid-template-columns: 60px minmax(0, 1fr) minmax(60px, auto);
}
html.rp-stage { --rp-gh-space: 104px; }
html.rp-stage .rp-game-header :is(.rp-gh-cube) { width: 46px; height: 46px; }
html.rp-stage .rp-game-header :is(.rp-gh-word) { font-size: 25px; }
html.rp-stage .rp-game-header :is(.rp-gh-menu, .rp-gh-timer) { width: 58px; min-width: 58px; height: 58px; border-radius: 29px; font-size: 24px; }

/* ── Common: the app takes the whole stage, screens lay out their own columns ── */
html.rp-stage .app { max-width: none; width: 100%; }
/* pwa-overrides.js: the first screen waits for Unbounded and Manrope (no reflow from the fallback font), at most 1.2 s. */
html.rp-stage.rp-fonts-pending .screen.active { visibility: hidden; }
html.rp-stage .btn-back { left: 40px; top: 28px; width: 52px; height: 52px; font-size: 22px; }
html.rp-stage :is(.btn-play, .btn-create, .btn-connect, .btn-next-slide, .btn-skip, .btn-additional-settings) {
    min-height: 60px; font-size: 19px; border-radius: 30px; padding: 0 34px; width: auto; white-space: nowrap;
}
html.rp-stage .title { font-family: var(--st-display); letter-spacing: -.02em; }

/* ════════════════════ Catalog (client/games/index.html) ════════════════════
   No zoom here (data-zoom="off" on the meta): owner 2026-10-29 «всё очень крупное, информативности меньше, нет
   описания, занято всё по ширине». Owner 2026-10-29 «каталог выглядит убого на пк» → mockup
   /mnt/project-files/catalog-pc/ → «го»: a wider column (up to 1600 px), the header in one row (brand, search, sort,
   filter and favourites, language, settings), the top row of catalog-showcase.js, then rows by mood in tiles
   (big art, name, two lines of description, players and mode). A search, a filter, favourites or another sort show
   the plain list in the same tiles. No spheres here (owner «шары лучше там убрать и так много элементов»).
   Owner 2026-10-30 «сделай /games/ для ПК в дизайне главной»: the landing's look (landing.css) instead of the /tv/
   cut-paper one: its navy, faint grid and blue/red corner light, Manrope text and Unbounded headings (fonts.css),
   calm rounded cards with a soft shadow and a pink border on hover, a sticky header bar, pill buttons, mint eyebrows. */
html.rp-stage[data-stage-page="catalog"] {
    --lp-bg: #0d1329;
    --lp-bg-deep: #0a0f1f;
    --lp-surface: #1e2643;
    --lp-card: #252b4a;
    --lp-line: rgb(255 255 255 / 13%);
    --lp-line-strong: rgb(255 255 255 / 22%);
    --lp-accent: #ec494f;
    --lp-pink: #ff3b6f;
    --lp-blue: #4a6cf7;
    --lp-mint: #2ee6a6;
    --lp-text-2: #aeb7d3;
    --lp-muted: #8892b0;
    --lp-body: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
    --lp-display: 'Unbounded', 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --lp-ease: cubic-bezier(.16, 1, .3, 1);
}
html.rp-stage[data-stage-page="catalog"]:not([data-room-game]) body {
    font-family: var(--lp-body);
    background:
        linear-gradient(115deg, rgb(74 108 247 / 12%) 0%, transparent 32%),
        linear-gradient(245deg, rgb(236 73 79 / 12%) 0%, transparent 34%),
        linear-gradient(180deg, rgb(13 19 41 / 94%) 0%, var(--lp-bg-deep) 48%, var(--lp-bg) 100%),
        var(--lp-bg);
    background-attachment: fixed;
}
html.rp-stage[data-stage-page="catalog"]:not([data-room-game]) .particles { display: none; }
/* No «Установите приложение» on a computer (owner 2026-10-30 «на пк скрой»). install-prompt.js counts the offer as shown
   only when its card has a box, so a hidden banner sends no install_prompt_shown. */
html.rp-stage .install-prompt-banner { display: none; }
html.rp-stage[data-stage-page="catalog"] .menu-screen {
    /* The scroller spans the window (so the grid and the header bar reach its edges); the padding keeps the landing's
       1180 px column (owner 2026-10-30 «по ширине отличается»). */
    max-width: none; margin: 0; padding: 0 max(56px, calc((100% - 1180px) / 2)) 56px; min-height: var(--app-height, 720px);
    background-image: linear-gradient(rgb(255 255 255 / 3.5%) 1px, transparent 1px), linear-gradient(90deg, rgb(255 255 255 / 2.8%) 1px, transparent 1px);
    background-size: 44px 44px; background-attachment: local;
    -webkit-mask-image: none;
}
html.rp-stage[data-stage-page="catalog"] .menu-screen::before { display: none; }
/* Header: one sticky bar like the landing's site header. The topbar, the controls and the summary give their
   children to the header grid; the bar's backing reaches the window edges through its shadow. */
html.rp-stage[data-stage-page="catalog"] .menu-header {
    position: sticky; top: 0; z-index: 20;
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto auto;
    grid-template-areas: "brand search tools lang settings" "filters filters filters filters filters" "summary summary sort sort sort";
    gap: 0 10px; align-items: center; margin: 0 0 28px; padding: 14px 0;
}
/* The bar's backing reaches the window edges; a pseudo-element, so nothing clips the language list under the bar. */
html.rp-stage[data-stage-page="catalog"] .menu-header::before {
    content: ''; position: absolute; inset: 0 -100vmax; z-index: -1; pointer-events: none;
    background: rgb(13 19 41 / 90%); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); border-bottom: 1px solid var(--lp-line);
}
html.rp-stage[data-stage-page="catalog"] :is(.roomplay-menu-topbar, .ru-catalog-controls, .ru-catalog-summary) { display: contents; }
html.rp-stage[data-stage-page="catalog"] .ru-catalog-controls[hidden] { display: none; }
html.rp-stage[data-stage-page="catalog"] .menu-language-picker { grid-area: lang; position: relative; }
html.rp-stage[data-stage-page="catalog"] .menu-language-popover { left: auto; right: 0; transform-origin: calc(100% - 23px) 0; }
html.rp-stage[data-stage-page="catalog"] .menu-settings-button { grid-area: settings; }
html.rp-stage[data-stage-page="catalog"] :is(.menu-language-button, .menu-settings-button, .ru-control-chip) {
    width: 46px; height: 46px; min-height: 46px; padding: 0; display: grid; place-items: center; border-radius: 999px;
    border: 1px solid var(--lp-line-strong); background: rgb(255 255 255 / 6.5%); color: #fff;
}
html.rp-stage[data-stage-page="catalog"] :is(.menu-language-button, .menu-settings-button, .ru-control-chip):hover { background: rgb(255 255 255 / 10%); border-color: rgb(255 255 255 / 34%); }
html.rp-stage[data-stage-page="catalog"] .ru-control-chip.active { border-color: var(--lp-pink); background: rgb(255 59 111 / 18%); }
html.rp-stage[data-stage-page="catalog"] .menu-title {
    grid-area: brand; display: grid; grid-template-columns: auto auto; justify-content: start; align-items: center;
    gap: 0 10px; margin: 0; font-family: var(--lp-display); font-size: 22px; letter-spacing: 0; text-align: left;
}
html.rp-stage[data-stage-page="catalog"] .menu-brand-lockup { display: contents; }
html.rp-stage[data-stage-page="catalog"] .menu-title--brand { cursor: pointer; }
html.rp-stage[data-stage-page="catalog"] .menu-title--brand:active { transform: scale(.98); }
html.rp-stage[data-stage-page="catalog"] .menu-brand-cube { grid-row: 1 / 3; width: 40px; height: 40px; }
html.rp-stage[data-stage-page="catalog"] .menu-brand-word { align-self: end; font-size: 22px; letter-spacing: -.01em; }
html.rp-stage[data-stage-page="catalog"] .menu-brand-tagline { align-self: start; margin-top: 3px; font-family: var(--lp-body); font-size: 12px; font-weight: 700; color: var(--lp-text-2); }
html.rp-stage[data-stage-page="catalog"] .ru-search-wrap {
    grid-area: search; justify-self: center; width: min(620px, 100%); min-height: 48px; padding: 0 20px; gap: 12px;
    border-radius: 999px; background: rgb(255 255 255 / 6.5%); border: 1px solid var(--lp-line-strong); color: var(--lp-text-2);
}
html.rp-stage[data-stage-page="catalog"] .ru-search-wrap:focus-within { border-color: rgb(255 59 111 / 60%); }
html.rp-stage[data-stage-page="catalog"] .ru-search-wrap input { font-family: var(--lp-body); font-weight: 600; }
html.rp-stage[data-stage-page="catalog"] .ru-control-row { grid-area: tools; display: flex; gap: 8px; margin: 0; overflow: visible; }
html.rp-stage[data-stage-page="catalog"] .ru-active-filters { grid-area: filters; margin-top: 12px; }
html.rp-stage[data-stage-page="catalog"] .ru-active-filters:empty { display: none; }
/* The sort list sits under the bar, on the summary line, only over the plain list: a search, a filter, favourites or
   another sort; the rows have none (owner 2026-10-30 «показывай ниже только если фильтр применен»). */
html.rp-stage[data-stage-page="catalog"] .ru-sort-control { grid-area: sort; justify-self: end; min-width: 0; margin-top: 14px; }
html.rp-stage[data-stage-page="catalog"].rp-catalog-rows .ru-sort-control { display: none; }
html.rp-stage[data-stage-page="catalog"] .ru-sort-control select { max-width: none; width: auto; font-family: var(--lp-body); color: var(--lp-text-2); color-scheme: dark; }
/* The open list of the native select: dark like the bar, readable text (it was light grey on white). */
html.rp-stage[data-stage-page="catalog"] .ru-sort-control option { background: var(--lp-surface); color: #fff; }
/* The summary («Все игры · N») heads the plain list from the bar's last line; the rows have their own heads. */
html.rp-stage[data-stage-page="catalog"] .ru-catalog-summary > p { grid-area: summary; margin: 14px 0 0; }
html.rp-stage[data-stage-page="catalog"].rp-catalog-rows .ru-catalog-summary > p { display: none; }
html.rp-stage[data-stage-page="catalog"] .ru-catalog-summary strong { font-family: var(--lp-display); font-size: 26px; font-weight: 800; letter-spacing: 0; margin-right: 6px; }
html.rp-stage[data-stage-page="catalog"] :is(.catalog-room-hit, .ru-favorite-spotlight, .catalog-search-intent, .premium-paused-slot > *) { max-width: none; }
/* The season and room pills: one thin card line. */
html.rp-stage[data-stage-page="catalog"] .catalog-room-hit {
    margin-bottom: 26px; padding-top: 12px; padding-bottom: 12px; border-radius: 16px;
    background: var(--lp-surface); border: 1.5px solid rgb(255 255 255 / 10%); box-shadow: 0 14px 32px rgb(0 0 0 / 18%);
}
html.rp-stage[data-stage-page="catalog"] .catalog-room-hit-text { flex-direction: row; align-items: baseline; gap: 14px; }
html.rp-stage[data-stage-page="catalog"] .catalog-room-hit-text small { color: var(--lp-text-2); }

/* Tiles: the list card (.game-card) and its copy in a row (.catalog-tile) share the landing's game card look;
   four a row as on the landing (owner 2026-10-30 «плашки в 1.5 раза шире бы чтобы текст помещался», then «оставить 4
   в ряд», then «шире в 1.5 раза, НО НЕ ВЫШЕ», «уменьши пикчи»): a small square icon on the left, the name and two lines
   beside it, the players pill under them, so a tile is low. Names in sentence case, as on the landing. */
html.rp-stage[data-stage-page="catalog"] :is(.games-list, .catalog-row-grid) {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px;
}
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile) {
    position: relative; display: grid; grid-template-columns: 88px minmax(0, 1fr); grid-template-areas: "art content" "art tags";
    grid-template-rows: auto 1fr; align-items: start; gap: 8px 14px;
    width: auto; height: 100%; margin: 0; padding: 14px; text-align: left; color: #fff; text-decoration: none;
    background: var(--lp-surface); border: 1.5px solid rgb(255 255 255 / 10%); border-radius: 16px;
    box-shadow: 0 14px 32px rgb(0 0 0 / 18%);
    transition: transform .18s var(--lp-ease), border-color .18s var(--lp-ease), background .18s var(--lp-ease), box-shadow .18s var(--lp-ease);
}
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile):hover {
    transform: translateY(-4px); border-color: rgb(255 59 111 / 60%); background: var(--lp-card); box-shadow: 0 18px 42px rgb(0 0 0 / 26%);
}
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile):active { transform: translateY(1px) scale(.99); }
html.rp-stage[data-stage-page="catalog"] .games-list .game-card.hidden { display: none; }
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile) .card-image {
    grid-area: art; width: 88px; height: 88px; margin: 0; border-radius: 12px;
}
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile) .card-icon { border-radius: 12px; }
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile) .card-content { grid-area: content; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile) .card-header { margin: 2px 0 0; padding: 0; }
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile) .card-title {
    font-family: var(--lp-body); font-size: 16px; font-weight: 850; letter-spacing: 0; line-height: 1.2; color: #fff; text-transform: lowercase;
}
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile) .card-title::first-letter { text-transform: uppercase; }
html.rp-stage[data-stage-page="catalog"] .card-title :is(.ru-new-badge, .game-public-rating) { text-transform: uppercase; }
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile) .card-description {
    min-height: 4.2em; font-size: 13px; font-weight: 500; line-height: 1.4; color: var(--lp-text-2);
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile) .card-tags {
    grid-area: tags; align-self: end; flex-wrap: nowrap; gap: 6px; margin: 0; padding: 0; overflow: hidden;
}
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile) :is(.player-badge, .mode-badge) {
    flex: none; padding: 5px 10px; font-size: 12px; font-weight: 800; color: var(--lp-text-2); white-space: nowrap;
    background: transparent; border: 1px solid var(--lp-line-strong); border-radius: 999px;
}
/* No mode pill («Каждый со своего», «На одном телефоне») on the tiles (owner 2026-10-30 «скрой такие плашки»). */
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile) .mode-badge { display: none; }
html.rp-stage[data-stage-page="catalog"] .card-title .ru-new-badge { padding: 3px 7px; font-size: 10px; background: var(--lp-blue); }
html.rp-stage[data-stage-page="catalog"] .card-title .ru-beta-badge { background: var(--lp-accent); }
/* The heart sits on the icon's corner in a round backing. */
html.rp-stage[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile) .card-favorite {
    top: 6px; left: 72px; right: auto; display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border-radius: 50%;
    background: rgb(13 19 41 / 72%); border: 1px solid var(--lp-line);
}
html.rp-stage[data-stage-page="catalog"] .card-favorite:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* «Витрина» (catalog-showcase.js): the most opened game big with «Играть», the two newest games beside it, then the
   rows. Owner 2026-10-29 chose «Витрина сверху + сетка», then the rows. Phones never see it. */
html:not(.rp-stage) .catalog-showcase, html:not(.rp-stage) .catalog-showcase[hidden], .catalog-showcase[hidden] { display: none; }
html.rp-stage[data-stage-page="catalog"].rp-catalog-rows .games-list:not(.catalog-search-popular) { display: none; }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-top {
    display: grid; grid-template-columns: 1.7fr 1fr; grid-template-rows: 1fr 1fr; gap: 18px; height: 420px; margin: 0 0 56px;
}
/* Three most opened games as side-style cards over the top row, in place of the «Для вашей компании» block, which the
   stage hides while the rows show (owner 2026-10-30 «вместо», «сделай 3 плашки типа … с самыми поп-ными играми»). */
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-trio { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; height: 200px; margin: 0 0 48px; }
html.rp-stage[data-stage-page="catalog"].rp-catalog-rows .ru-favorite-spotlight { display: none; }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-card {
    position: relative; isolation: isolate; overflow: hidden; display: flex; align-items: center; color: #fff;
    text-decoration: none; border-radius: 24px; border: 1.5px solid rgb(255 255 255 / 10%); box-shadow: 0 20px 48px rgb(0 0 0 / 28%);
    transition: transform .18s var(--lp-ease), border-color .18s var(--lp-ease), box-shadow .18s var(--lp-ease);
}
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-card:hover { transform: translateY(-4px); border-color: rgb(255 59 111 / 60%); box-shadow: 0 24px 52px rgb(0 0 0 / 34%); }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-card:active { transform: translateY(1px) scale(.99); }
/* The game's own icon, blurred, tints the card in its colours; the navy wash keeps the text readable. */
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-bg {
    position: absolute; inset: -30px; z-index: -2; background: center / cover no-repeat; filter: blur(34px) saturate(1.3); opacity: .6;
}
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-card::after {
    content: ''; position: absolute; inset: 0; z-index: -1;
    background: linear-gradient(90deg, rgb(13 19 41 / 94%) 0%, rgb(13 19 41 / 74%) 45%, rgb(13 19 41 / 28%) 100%);
}
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-icon { flex: none; order: 2; object-fit: cover; }
/* Pills as the landing's eyebrows: mint for «Популярное сейчас», blue for «Новинка». */
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-pill {
    align-self: flex-start; padding: 0; font-size: 12.5px; font-weight: 900; line-height: 1;
    letter-spacing: 0; text-transform: uppercase; background: none; color: var(--lp-mint);
}
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-pill.is-new { color: #8ea2ff; }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-title { font-family: var(--lp-display); font-weight: 900; letter-spacing: 0; line-height: 1.08; text-transform: lowercase; }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-title::first-letter { text-transform: uppercase; }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-desc { line-height: 1.5; font-weight: 500; color: var(--lp-text-2); }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-tags { display: flex; flex-wrap: wrap; gap: 8px; }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-tags span { padding: 6px 12px; border-radius: 999px; font-size: 13px; font-weight: 800; color: var(--lp-text-2); border: 1px solid var(--lp-line-strong); }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-hero { grid-row: 1 / 3; gap: 26px; padding: 40px; }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-hero .catalog-showcase-text { gap: 14px; }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-hero .catalog-showcase-icon { width: 230px; height: 230px; border-radius: 32px; box-shadow: 0 20px 48px rgb(0 0 0 / 40%); }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-hero .catalog-showcase-title { font-size: 44px; }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-hero .catalog-showcase-desc { max-width: 520px; font-size: 17px; }
/* «Играть»: the landing's primary button. */
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-play {
    align-self: flex-start; margin-top: 8px; padding: 0 30px; min-height: 52px; display: inline-flex; align-items: center;
    border-radius: 999px; font-size: 17px; font-weight: 800; color: #fff;
    background: linear-gradient(135deg, var(--lp-accent), var(--lp-pink)); box-shadow: 0 12px 34px rgb(255 59 111 / 28%);
}
html.rp-stage[data-stage-page="catalog"] :is(.catalog-showcase-new, .catalog-showcase-side) { gap: 16px; padding: 22px 24px; }
html.rp-stage[data-stage-page="catalog"] :is(.catalog-showcase-new, .catalog-showcase-side) .catalog-showcase-icon { width: 104px; height: 104px; border-radius: 22px; box-shadow: 0 14px 30px rgb(0 0 0 / 36%); }
html.rp-stage[data-stage-page="catalog"] :is(.catalog-showcase-new, .catalog-showcase-side) .catalog-showcase-title { font-size: 22px; }
html.rp-stage[data-stage-page="catalog"] :is(.catalog-showcase-new, .catalog-showcase-side) .catalog-showcase-desc {
    font-size: 14px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
html.rp-stage[data-stage-page="catalog"] :is(.catalog-showcase-new, .catalog-showcase-side) .catalog-showcase-tags span:nth-child(n + 2) { display: none; }
@media (max-width: 1299px) {
    html.rp-stage[data-stage-page="catalog"] .catalog-showcase-hero .catalog-showcase-icon { width: 180px; height: 180px; }
    html.rp-stage[data-stage-page="catalog"] .catalog-showcase-hero .catalog-showcase-title { font-size: 36px; }
}
/* Rows: a landing section head (Unbounded) with «N игр» as its secondary pill button, then the tiles. */
html.rp-stage[data-stage-page="catalog"] .catalog-row { margin: 0 0 52px; }
html.rp-stage[data-stage-page="catalog"] .catalog-row-head { display: flex; align-items: center; gap: 16px; margin: 0 0 20px; }
html.rp-stage[data-stage-page="catalog"] .catalog-showcase-heading { margin: 0; font-family: var(--lp-display); font-size: 30px; font-weight: 800; letter-spacing: 0; line-height: 1.1; }
html.rp-stage[data-stage-page="catalog"] .catalog-row-more {
    margin-left: auto; min-height: 44px; padding: 0 20px; border-radius: 999px; border: 1px solid var(--lp-line-strong); background: rgb(255 255 255 / 6.5%);
    color: #fff; font: inherit; font-size: 14px; font-weight: 800; cursor: pointer;
    transition: transform .18s var(--lp-ease), background .18s var(--lp-ease), border-color .18s var(--lp-ease);
}
html.rp-stage[data-stage-page="catalog"] .catalog-row-count { display: inline-flex; align-items: center; cursor: default; }
html.rp-stage[data-stage-page="catalog"] .catalog-row-more:not(.catalog-row-count):hover { transform: translateY(-2px); background: rgb(255 255 255 / 10%); border-color: rgb(255 255 255 / 34%); }
html.rp-stage[data-stage-page="catalog"] .catalog-row-more:not(.catalog-row-count):active { transform: translateY(1px) scale(.97); }
/* «Есть код комнаты? [ABCD] Войти» on a computer: a narrow tall card with the code field (shared room-code-entry
   component, #catalog-room-entry) under the season banner (owner 2026-10-30 «ниже хэллоуина и прямоугольным блоком
   уже, выше и сразу полем ввода кода»). The bottom bar (#ru-room-control) is moved right before it by /games/: hidden
   while there is no room; in a room its card («Комната ABCD», «Другая») replaces the code field. */
.catalog-room-entry[hidden] { display: none; }
html.rp-stage[data-stage-page="catalog"] .catalog-room-entry {
    max-width: 440px; margin: 0 0 30px; padding: 26px 26px 28px; gap: 16px; border-radius: 20px;
    background: var(--lp-surface); border: 1.5px solid rgb(255 255 255 / 10%); box-shadow: 0 14px 32px rgb(0 0 0 / 18%);
}
html.rp-stage[data-stage-page="catalog"] .catalog-room-entry .room-code-entry-prompt { color: #fff; font-family: var(--lp-display); font-size: 20px; font-weight: 800; }
html.rp-stage[data-stage-page="catalog"] .catalog-room-entry .room-code-entry-row { gap: 10px; }
html.rp-stage[data-stage-page="catalog"] .catalog-room-entry :is(.room-code-entry-input, .room-code-entry-btn) { height: 56px; font-family: var(--lp-body); }
html.rp-stage[data-stage-page="catalog"] .catalog-room-entry .room-code-entry-input { font-size: 22px; }
html.rp-stage[data-stage-page="catalog"] .catalog-room-entry .room-code-entry-btn { min-width: 116px; font-size: 16px; }
html.rp-stage[data-stage-page="catalog"] .ru-room-control:has(+ .catalog-room-entry).ru-room-empty { display: none; }
html.rp-stage[data-stage-page="catalog"] .ru-room-control:not(.ru-room-empty) + .catalog-room-entry { display: none; }
html.rp-stage[data-stage-page="catalog"] .ru-room-control:has(+ .catalog-room-entry) {
    position: static; display: flex; align-items: center; gap: 14px; width: auto; max-width: 440px; margin: 0 0 30px; padding: 14px;
    transform: none; border-radius: 20px; background: var(--lp-surface); border: 1.5px solid rgb(255 255 255 / 10%); box-shadow: 0 14px 32px rgb(0 0 0 / 18%);
}
html.rp-stage[data-stage-page="catalog"] .ru-room-control:has(+ .catalog-room-entry)[hidden] { display: none; }
html.rp-stage[data-stage-page="catalog"] .ru-room-control:has(+ .catalog-room-entry) :is(.ru-room-main, .ru-room-qr) {
    min-height: 56px; border-radius: 16px; color: #fff; font-family: var(--lp-body); font-size: 16px; font-weight: 800;
}
html.rp-stage[data-stage-page="catalog"] .ru-room-control:has(+ .catalog-room-entry) .ru-room-main { flex: 1; padding: 0 18px; }
html.rp-stage[data-stage-page="catalog"] .ru-room-control:has(+ .catalog-room-entry) .ru-room-qr {
    flex: none; width: auto; padding: 0 22px; border: 1px solid var(--lp-line-strong); background: rgb(255 255 255 / 6.5%);
}
html.rp-stage[data-stage-page="catalog"] .ru-room-control:has(+ .catalog-room-entry) :is(.ru-room-main, .ru-room-qr):hover { transform: translateY(-2px); }

/* Halloween on a computer (until 2026-11-01, html.season-halloween from /games/; owner 2026-10-30 «а где оформление
   хэллоуин как на тел»): the phone's night purple and pumpkin orange in the landing look. The phone rules in styles.css
   draw the web in the header corner, which the stage repeats in the window corner. Decoration only. */
html.rp-stage.season-halloween[data-stage-page="catalog"] {
    --lp-bg: #150d26;
    --lp-bg-deep: #0c0717;
    --lp-surface: #23163a;
    --lp-card: #2e1d4a;
    --lp-pink: #ff8a1f;
}
html.rp-stage.season-halloween[data-stage-page="catalog"]:not([data-room-game]) body {
    background:
        radial-gradient(120% 60% at 50% 110%, rgb(242 138 30 / 22%), transparent 60%),
        linear-gradient(245deg, rgb(242 138 30 / 10%) 0%, transparent 34%),
        linear-gradient(180deg, #1b0f30 0%, var(--lp-bg-deep) 100%),
        var(--lp-bg);
    background-attachment: fixed;
}
html.rp-stage.season-halloween[data-stage-page="catalog"] .menu-header::before { background-color: rgb(21 13 38 / 90%); }
/* The phone's corner web (styles.css) sits under the bar's backing here, so the stage draws it in the window's top
   right corner, larger (owner «паутина в углу есть?»). */
html.rp-stage.season-halloween[data-stage-page="catalog"] .menu-header::after {
    content: ''; position: fixed; top: 0; right: 0; width: 170px; height: 170px; pointer-events: none;
    background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMTAnIGhlaWdodD0nMTEwJyB2aWV3Qm94PScwIDAgMTEwIDExMCcgZmlsbD0nbm9uZScgc3Ryb2tlPScjZDhjOGZmJyBzdHJva2Utb3BhY2l0eT0nLjE4JyBzdHJva2Utd2lkdGg9JzEuMic+PHBhdGggZD0nTTExMCAwTDAgMzZNMTEwIDBMMjggODJNMTEwIDBMNzQgMTEwJy8+PHBhdGggZD0nTTgyIDlRODggMjAgOTAgMjhROTcgMjQgMTAzIDI4TTU2IDE4UTY2IDM4IDcwIDU2UTg2IDQ4IDk4IDU2TTI4IDI4UTQ0IDU0IDUwIDg0UTcyIDcyIDkwIDg0Jy8+PC9zdmc+) no-repeat right top / 170px 170px;
}
html.rp-stage.season-halloween[data-stage-page="catalog"] :is(.games-list .game-card, .catalog-tile, .catalog-showcase-card) { border-color: rgb(242 138 30 / 22%); }
/* No «Игры на Хэллоуин» pill on a computer (owner 2026-10-30 «скрой»); the season look stays. */
html.rp-stage[data-stage-page="catalog"] .catalog-season-hit { display: none; }
html.rp-stage.season-halloween[data-stage-page="catalog"] .catalog-season-hit {
    border-color: rgb(242 138 30 / 55%); background: linear-gradient(135deg, rgb(242 138 30 / 26%), rgb(139 92 246 / 14%));
}
html.rp-stage.season-halloween[data-stage-page="catalog"] :is(.catalog-search-intent h2, .catalog-showcase-heading) { color: #ff8a1f; }

/* ════════════════════ Room: name and lobby (client/create-room/) ════════════════════ */
html.rp-stage[data-stage-page="room"] .screen { height: var(--app-height, 720px); }
html.rp-stage[data-stage-page="room"] #create-screen.active { align-items: center; justify-content: center; }
html.rp-stage[data-stage-page="room"] .create-content {
    flex: none; width: 600px; max-width: none; padding: 40px 48px 36px; gap: 14px;
    background: var(--st-panel); border: 1px solid var(--st-line); border-radius: var(--cut-1); box-shadow: 8px 10px 0 rgb(0 0 0 / 30%);
    rotate: -.5deg;
}
html.rp-stage[data-stage-page="room"] .create-content > * { rotate: .5deg; }
html.rp-stage[data-stage-page="room"] .create-content .game-logo { width: 260px; height: 150px; }
html.rp-stage[data-stage-page="room"] .create-content .title { font-size: 36px; }
html.rp-stage[data-stage-page="room"] .create-content .subtitle { font-size: 18px; }
html.rp-stage[data-stage-page="room"] .player-entry-row .input { height: 62px; font-size: 22px; border-radius: 18px; }
html.rp-stage[data-stage-page="room"] .player-gender-selector { height: 62px; }
html.rp-stage[data-stage-page="room"] .btn-create { width: 100%; }
html.rp-stage[data-stage-page="room"] .direct-game { width: 100%; }

/* Lobby: the invite on the left (big QR, the code, «Пригласить»), the room on the right. */
html.rp-stage[data-stage-page="room"] #lobby-screen.active { align-items: center; justify-content: center; }
html.rp-stage[data-stage-page="room"] .lobby-content {
    width: 1180px; max-width: none; height: 620px; margin: 0; padding: 0;
    display: grid; grid-template-columns: 400px minmax(0, 1fr); grid-template-rows: auto auto auto minmax(0, 1fr) auto;
    column-gap: 48px; row-gap: 14px; align-items: start;
}
html.rp-stage[data-stage-page="room"] .lobby-content > * { grid-column: 2; margin: 0; width: auto; max-width: none; }
html.rp-stage[data-stage-page="room"] .lobby-content > .invite-card {
    grid-column: 1; grid-row: 1 / 5; align-self: center; display: flex; flex-direction: column; align-items: center; gap: 18px;
    padding: 30px 28px; background: var(--st-panel); border: 1px solid var(--st-line); border-radius: var(--cut-3);
    box-shadow: 8px 10px 0 rgb(0 0 0 / 30%); rotate: -1deg;
}
html.rp-stage[data-stage-page="room"] .invite-card .qr-code-img {
    order: -1; width: 260px; height: 260px; padding: 14px; background: #fff; border-radius: var(--cut-2); box-shadow: var(--cut-shadow); rotate: 1.5deg;
}
html.rp-stage[data-stage-page="room"] .invite-side { align-items: center; text-align: center; gap: 10px; width: 100%; }
html.rp-stage[data-stage-page="room"] .room-code-label { font-size: 15px; letter-spacing: .1em; }
html.rp-stage[data-stage-page="room"] .room-code-btn { font-size: 56px; letter-spacing: .14em; }
html.rp-stage[data-stage-page="room"] .invite-card .btn-invite { min-height: 52px; font-size: 18px; padding: 0 28px; }
/* «Пригласить» and «Позвонить» one under the other on the stage card (call pilot 2026-11-02). */
html.rp-stage[data-stage-page="room"] .invite-actions { flex: none; width: 100%; flex-direction: column; gap: 10px; }
html.rp-stage[data-stage-page="room"] .lobby-content > .qr-invite-note {
    grid-column: 1; grid-row: 5; justify-self: center; padding: 8px 16px; text-align: center; font-size: 16px;
    background: var(--st-panel); border: 1px solid var(--st-line); border-radius: 14px;
}
html.rp-stage[data-stage-page="room"] .lobby-content > .game-dropdown { grid-row: 1; }
html.rp-stage[data-stage-page="room"] .lobby-content > .btn-vote { grid-row: 2; justify-self: start; }
html.rp-stage[data-stage-page="room"] .lobby-content > .players-head { grid-row: 3; }
html.rp-stage[data-stage-page="room"] .players-title { font-size: 22px; }
html.rp-stage[data-stage-page="room"] .lobby-content > .players-list {
    grid-row: 4; align-self: stretch; overflow-y: auto; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    align-content: start; gap: 12px 16px; padding: 4px 14px 14px 4px;
}
html.rp-stage[data-stage-page="room"] .players-list > * {
    margin: 0; min-height: 64px; font-size: 19px; border-radius: var(--cut-1); box-shadow: var(--cut-shadow); rotate: -.5deg;
}
html.rp-stage[data-stage-page="room"] .players-list > :nth-child(4n + 2) { border-radius: var(--cut-2); rotate: .5deg; }
html.rp-stage[data-stage-page="room"] .players-list > :nth-child(4n + 3) { border-radius: var(--cut-3); rotate: .3deg; }
html.rp-stage[data-stage-page="room"] .players-list > :nth-child(4n + 4) { border-radius: var(--cut-4); rotate: -.3deg; }
html.rp-stage[data-stage-page="room"] .lobby-content > .bottom-section {
    grid-row: 5; position: static; display: flex; flex-direction: row-reverse; justify-content: flex-end; align-items: center; gap: 22px; padding: 0;
    background: none;
}
html.rp-stage[data-stage-page="room"] .bottom-section .lobby-status { font-size: 17px; margin: 0; }

/* «Во что играем?» (game-vote.css): owner 2026-10-29 «голосов - на весь экр». The phone's 420 px sheet becomes the whole
   stage: the games four a row in a centred 1120 px column, bigger icons and names, the buttons centred under them. The
   «Об игре» sheet over it is a centred card instead of a bottom sheet. */
html.rp-stage[data-stage-page="room"] .gv { max-width: none; }
html.rp-stage[data-stage-page="room"] .gv-back { top: 28px; left: 40px; width: 52px; height: 52px; font-size: 22px; }
html.rp-stage[data-stage-page="room"] .gv-head { padding: 30px 120px 10px; }
html.rp-stage[data-stage-page="room"] .gv-head h2 { font-family: var(--st-display); font-size: 36px; letter-spacing: -.02em; }
html.rp-stage[data-stage-page="room"] .gv-hint { margin-top: 6px; font-size: 18px; }
html.rp-stage[data-stage-page="room"] .gv-left { margin-top: 12px; padding: 6px 16px; font-size: 16px; }
html.rp-stage[data-stage-page="room"] .gv-pips i { width: 12px; height: 12px; }
html.rp-stage[data-stage-page="room"] .gv-grid {
    width: 100%; max-width: 1120px; margin: 0 auto; grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: 92px;
    gap: 14px; padding: 16px 24px 14px;
}
html.rp-stage[data-stage-page="room"] .gv-tile { gap: 12px; padding: 8px 12px 8px 10px; border-radius: var(--cut-1); }
html.rp-stage[data-stage-page="room"] .gv-cell:nth-child(4n + 2) .gv-tile { border-radius: var(--cut-2); }
html.rp-stage[data-stage-page="room"] .gv-cell:nth-child(4n + 3) .gv-tile { border-radius: var(--cut-3); }
html.rp-stage[data-stage-page="room"] .gv-cell:nth-child(4n + 4) .gv-tile { border-radius: var(--cut-4); }
html.rp-stage[data-stage-page="room"] :is(.gv-icon, .gv-tile .game-dropdown-item-icon-emoji) { width: 64px; height: 64px; border-radius: 12px; font-size: 42px; }
html.rp-stage[data-stage-page="room"] .gv-name { font-size: 17px; }
html.rp-stage[data-stage-page="room"] :is(.gv-need, .gv-suggested, .gv-phone) { font-size: 14px; }
html.rp-stage[data-stage-page="room"] .gv-face { width: 28px; height: 28px; font-size: 12px; }
html.rp-stage[data-stage-page="room"] .gv-count { height: 24px; font-size: 14px; }
html.rp-stage[data-stage-page="room"] .gv-info { top: 6px; right: 6px; width: 24px; height: 24px; font-size: 19px; }
html.rp-stage[data-stage-page="room"] .gv-minus { top: 4px; left: 4px; width: 26px; height: 26px; }
html.rp-stage[data-stage-page="room"] .gv-bottom { width: 100%; max-width: 520px; margin: 0 auto; padding: 10px 24px 22px; }
html.rp-stage[data-stage-page="room"] .gv-bottom .btn-play { width: 100%; }
html.rp-stage[data-stage-page="room"] .gv-status { font-size: 16px; margin-bottom: 10px; }
html.rp-stage[data-stage-page="room"] .gv-alt { font-size: 16px; }
html.rp-stage[data-stage-page="room"] .gv-result { padding-top: 24px; }
html.rp-stage[data-stage-page="room"] .gv-winner-icon,
html.rp-stage[data-stage-page="room"] .gv-winner .game-dropdown-item-icon-emoji { width: 160px; height: 160px; border-radius: 32px; }
html.rp-stage[data-stage-page="room"] .gv-winner-name { font-family: var(--st-display); font-size: 38px; }
html.rp-stage[data-stage-page="room"] .gv-winner-votes { font-size: 19px; }
html.rp-stage[data-stage-page="room"] .gv-runners { max-width: 420px; }
html.rp-stage[data-stage-page="room"] .gv-runners li { padding: 12px 18px; font-size: 17px; }
html.rp-stage[data-stage-page="room"] .gv-sheet { align-items: center; justify-content: center; }
html.rp-stage[data-stage-page="room"] .gv-sheet.is-page { max-width: none; }
html.rp-stage[data-stage-page="room"] .gv-sheet-panel { width: 520px; max-height: 86%; padding: 30px 32px 26px; border: 1px solid var(--room-line); border-radius: var(--cut-2); }

/* ════════════════════ Join by code / invite (client/join-any/) ════════════════════ */
html.rp-stage[data-stage-page="join"] body { min-height: var(--app-height, 720px); }
html.rp-stage[data-stage-page="join"] .app {
    flex: none; height: auto; min-height: 0; width: 600px; max-width: none; padding: 40px 48px 36px; display: flex; flex-direction: column; align-items: stretch; gap: 14px;
    background: var(--st-panel); border: 1px solid var(--st-line); border-radius: var(--cut-1); box-shadow: 8px 10px 0 rgb(0 0 0 / 30%);
}
html.rp-stage[data-stage-page="join"] .app > * { margin-left: 0; margin-right: 0; }
html.rp-stage[data-stage-page="join"] .app .title { font-size: 32px; }
html.rp-stage[data-stage-page="join"] .app .subtitle { font-size: 17px; }
html.rp-stage[data-stage-page="join"] .app .input { height: 60px; font-size: 21px; border-radius: 18px; }
html.rp-stage[data-stage-page="join"] .app .player-gender-selector { height: 60px; }

/* «Как играете с этого компьютера?»: the shared «Выбор режима» (shared/client/ui/mode-choice.ts) as two big
   cards in the middle of the stage instead of a bottom sheet. */
html.rp-stage .rp-mode-sheet { display: grid; place-items: center; }
html.rp-stage .rp-mode-sheet[hidden] { display: none; }
html.rp-stage .rp-mode-panel {
    position: relative; inset: auto; left: auto; bottom: auto; width: 1000px; max-width: none; padding: 40px 48px 48px; border-radius: var(--cut-1);
    color: #fff; background: var(--st-panel); border: 1px solid var(--st-line);
    transform: none; animation: none; box-shadow: 10px 12px 0 rgb(0 0 0 / 34%);
}
html.rp-stage .rp-mode-handle { display: none; }
html.rp-stage .rp-mode-panel header h2 { font-family: var(--st-display); font-size: 38px; letter-spacing: -.02em; }
html.rp-stage .rp-mode-options { grid-template-columns: 1fr 1fr; gap: 28px; }
html.rp-stage .rp-mode-option {
    flex-direction: column; justify-content: center; min-height: 230px; padding: 30px; gap: 20px; border-radius: var(--cut-2);
    background: var(--st-card); border-color: var(--st-line); box-shadow: var(--cut-shadow); rotate: -.8deg;
}
html.rp-stage .rp-mode-option strong { font-family: var(--st-display); font-size: 28px; letter-spacing: -.01em; }
html.rp-stage .rp-mode-option:hover { background: color-mix(in srgb, var(--st-card) 80%, #fff); }
html.rp-stage .rp-mode-option[data-mode="play"] { border: 2px solid var(--st-gold); }
html.rp-stage .rp-mode-option + .rp-mode-option { border-radius: var(--cut-3); rotate: .8deg; translate: 0 6px; }
html.rp-stage .rp-mode-option-icon { width: 96px; height: 96px; margin: 0; border-radius: 28px; }
html.rp-stage .rp-mode-option-icon svg { width: 60px; height: 60px; }

/* ════════════════════ «Комната» inside a game (#lobby-screen of every stage game) ════════════════════
   Owner 2026-10-30 on Рисовач: «начать игру хз где». The game pages' own room (the host's start after the preview, the
   guests' «Ожидание других игроков…») kept the phone column stretched to the stage: player rows 1750 px wide off the
   right edge, «Начать игру» alone in the bottom-left corner. On the stage it is one centred column like the packs
   screen: the title over a 3-a-row grid of player chips, the buttons centred in one row under them, the status under
   the buttons; owner 2026-10-30 «а это к низу спустить бы»: the buttons' row at the stage's bottom. The create-room page («room») has its own two-column lobby above. */
html.rp-stage:not([data-stage-page="room"]) #lobby-screen.active { align-items: center; }
html.rp-stage:not([data-stage-page="room"]) #lobby-screen > .lobby-content {
    flex: 1 1 auto; width: 100%; max-width: 1060px; min-height: 0; height: 100%; margin: 0 auto; padding: 56px 0 44px;
    justify-content: flex-start; align-items: center; gap: 0;
}
html.rp-stage:not([data-stage-page="room"]) #lobby-screen .lobby-content > .title { align-self: center; text-align: center; justify-content: center; margin: 0 0 22px; }
html.rp-stage:not([data-stage-page="room"]) #lobby-screen .lobby-content > .players-list {
    flex: 0 1 auto; align-self: stretch; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-content: start;
    gap: 12px 16px; min-height: 0; padding: 4px 6px 10px; overflow-y: auto;
}
html.rp-stage:not([data-stage-page="room"]) #lobby-screen .players-list > * { margin: 0; min-width: 0; min-height: 64px; font-size: 19px; }
html.rp-stage:not([data-stage-page="room"]) #lobby-screen .lobby-content > :is(.rounds-selector, .mode-toggle) { align-self: center; margin: 18px 0 0; }
html.rp-stage:not([data-stage-page="room"]) #lobby-screen .lobby-content > .bottom-section {
    position: static; flex: none; align-self: stretch; display: flex; flex-flow: row wrap; align-items: center; justify-content: center;
    gap: 14px 16px; margin: auto 0 0; padding: 30px 0 0; background: none;
}
html.rp-stage:not([data-stage-page="room"]) #lobby-screen .lobby-content > .bottom-section > button { flex: none; width: auto; min-width: 240px; margin: 0; }
html.rp-stage:not([data-stage-page="room"]) #lobby-screen .lobby-content > .bottom-section > :is(.lobby-status, p) { flex: 1 1 100%; margin: 0; text-align: center; font-size: 18px; }
html.rp-stage:not([data-stage-page="room"]) #lobby-screen .lobby-content > .bottom-section > :is(.lobby-status, p):empty { display: none; }
/* «Правила» (game-preview.ts addRulesButton puts it into this row on the stage): first in the row at the buttons' height. */
html.rp-stage:not([data-stage-page="room"]) #lobby-screen .bottom-section > .rules-again-wrap { order: -1; flex: none; width: auto; align-self: stretch; font-size: 19px; }
html.rp-stage:not([data-stage-page="room"]) #lobby-screen .bottom-section > :is(.lobby-status, p) { order: 2; }
html.rp-stage:not([data-stage-page="room"]) #lobby-screen .bottom-section .rules-again { height: 100%; min-height: 54px; min-width: 160px; margin: 0; padding: 0 28px; border-width: 2px; border-radius: 999px; font-size: inherit; font-weight: 600; opacity: 1; }

/* ════════════════════ Квиз (client/mini-games/quiz/) ════════════════════ */
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"], [data-stage-page="draw"]) .screen-content { max-width: none; width: 100%; padding-left: 56px; padding-right: 56px; }
/* Onboarding: the picture left, the text right, the buttons under the text. */
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="pv"], [data-stage-page="bunker"], [data-stage-page="draw"]) .onboarding-container { max-width: 1060px; margin: 0 auto; width: 100%; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="pv"], [data-stage-page="bunker"], [data-stage-page="draw"]) .slide-icon img { width: 300px; height: 300px; }
/* Owner 2026-10-30 «на пк строки онб скачут»: art drawn past its box (img[data-art-bleed], 115% with -7.5% margins of the
   phone's 240px icon) was smaller than the plain 300px art, so the title and the text moved on every other slide. Every
   picture keeps one 300px box: the plain one 300px, the bleeding one 345px with -22.5px margins. */
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="pv"], [data-stage-page="bunker"], [data-stage-page="draw"]) #onboarding-screen .slide-icon:has(> picture > img, > img) { width: 300px; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="pv"], [data-stage-page="bunker"], [data-stage-page="draw"]) #onboarding-screen .slide-icon img[data-art-bleed] { width: 345px; height: 345px; margin: -22.5px; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="pv"], [data-stage-page="bunker"], [data-stage-page="draw"]) .slide-title { font-size: 44px; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="pv"], [data-stage-page="bunker"], [data-stage-page="draw"]) .slide-text { font-size: 22px; max-width: 640px; margin-left: auto; margin-right: auto; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="pv"], [data-stage-page="bunker"], [data-stage-page="draw"]) .onboarding-buttons { justify-content: center; gap: 16px; }
/* Owner 2026-10-30 «втф» (Joking Hazard start screen on PC): the phone's narrow rule-animated onboarding (360px slide,
   340px title and text, a 94px text floor, slides stretched to the screen, the h2's own top margin) wrapped the 44px
   title onto two lines and pushed the text and the buttons off the screen. On the stage it is the same slide as the
   other games: wide title and text, slide centred, buttons in view. */
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="pv"], [data-stage-page="bunker"], [data-stage-page="draw"]) .rule-animated-onboarding .onboarding-slides { align-items: flex-start; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="pv"], [data-stage-page="bunker"], [data-stage-page="draw"]) .rule-animated-onboarding .onboarding-slide { max-width: none; padding: 20px; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="pv"], [data-stage-page="bunker"], [data-stage-page="draw"]) .rule-animated-onboarding .slide-title { max-width: none; margin-top: 0; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="pv"], [data-stage-page="bunker"], [data-stage-page="draw"]) .rule-animated-onboarding .slide-text { min-height: 0; }
/* Owner 2026-10-30 «починил?» («Кто из нас» start screen on PC): every stage onboarding is one screen. The phone's 5vh
   gap above the slide (36 stage px under zoom) pushed «Пропустить / Далее» below the window whenever the text took three
   lines (Детектор правды, Как хорошо ты меня знаешь?, Бредовуха, Рисовач, Кто из нас, Я никогда не); without it the
   buttons stay at the bottom edge (the slide's own 20px top padding goes too: 4 lines of German fit 1280×720). «Что бы ты выбрал?» sized its onboarding by 100dvh, which the stage zoom made 1.6×
   the window: it takes the window height and the shared paddings like the others. */
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="pv"], [data-stage-page="bunker"], [data-stage-page="draw"]) .onboarding-slides, html.rp-stage #onboarding-screen .onboarding-slides > .onboarding-slide { padding-top: 0; }
html.rp-stage[data-stage-page="wyr"] #onboarding-screen { height: var(--app-height, 100dvh); overflow: hidden; }
html.rp-stage[data-stage-page="wyr"] #onboarding-screen .onboarding-container { min-height: 0; height: 100%; padding: 40px 0 0; }
html.rp-stage[data-stage-page="wyr"] #onboarding-screen .onboarding-dots { margin-top: 0; }
/* Owner 2026-10-30 «а башня», «ну епрст» (Микс): the catalog's preview (?preview=1, the rules alone) of every game
   not on the stage yet (Микс, Башня, Детектив, Кодовые имена, Секретный Гитлер, Декодер, Табу, Слово волка, Alias,
   Крокодил, 5 секунд, Имаджинариум-like word games…) is html.rp-stage[data-stage-page="pv"]: the page adds the meta only
   for ?preview=1, so the game itself keeps its own layout. Their phone onboardings differ (a 100dvh column, a 360px
   grid with the art in half the screen, absolute slides), so here the screen is the window, the slide one centred
   column as in the other games, the shared onboarding rules above do the rest. */
html.rp-stage[data-stage-page="pv"] #onboarding-screen { height: var(--app-height, 100dvh); min-height: 0; padding: 0; overflow: hidden; }
html.rp-stage[data-stage-page="pv"] #onboarding-screen .onboarding-container:not([hidden]) { display: flex; flex-direction: column; min-height: 0; height: 100%; padding: 40px 0 0; box-sizing: border-box; }
html.rp-stage[data-stage-page="pv"] #onboarding-screen .onboarding-container:not([hidden]) { width: 100%; max-width: 1060px; margin: 0 auto; }
html.rp-stage[data-stage-page="pv"] #onboarding-screen :is(.onboarding-slides, .decoder-pages, .ww-pages) { flex: 1 1 0; min-height: 0; align-items: flex-start; padding-top: 0; }
html.rp-stage[data-stage-page="pv"] #onboarding-screen :is(.onboarding-slide, .decoder-page, .ww-page) { width: 100%; max-width: none; height: auto; padding: 0 20px; }
html.rp-stage[data-stage-page="pv"] #onboarding-screen :is(.onboarding-slide, .decoder-page, .ww-page).active { display: flex; flex-direction: column; align-items: center; grid-template-rows: none; margin-top: 0; margin-bottom: 0; }
html.rp-stage[data-stage-page="pv"] #onboarding-screen .slide-icon:has(> picture > img, > img), html.rp-stage[data-stage-page="pv"] #onboarding-screen .slide-icon img { width: 300px; height: 300px; margin-left: auto; margin-right: auto; }
html.rp-stage[data-stage-page="pv"] #onboarding-screen :is(.decoder-art, .ww-art) { width: 300px; height: 300px; align-self: center; transform: none; margin: 0 auto 18px; }
html.rp-stage[data-stage-page="pv"] #onboarding-screen .slide-title { max-width: none; min-height: 0; margin: 0 auto 20px; font-size: 44px; line-height: 1.12; }
html.rp-stage[data-stage-page="pv"] #onboarding-screen .slide-text { min-height: 0; max-width: 640px; margin-left: auto; margin-right: auto; font-size: 22px; line-height: 1.55; }

/* Packs: four a row, the summary on a backing (it sits over a sphere), settings and start on the right. */
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-content { padding-top: 34px; padding-bottom: 0; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-content > .title { font-size: 40px; justify-content: flex-start; text-align: left; align-self: stretch; margin: 0 0 4px !important; padding: 0 0 0 72px !important; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-content > .subtitle { text-align: left; align-self: stretch; font-size: 18px; padding: 0 0 0 72px !important; margin: 0 0 14px !important; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-illustrated-grid { grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 18px; padding: 4px 8px 8px 4px; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-illustrated-grid .packs-section-title { grid-column: 1 / -1; font-size: 17px; margin: 6px 0 0; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-illustrated-grid .pack-card { border-radius: var(--cut-1); box-shadow: var(--cut-shadow); rotate: -.6deg; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-illustrated-grid .pack-card:nth-of-type(4n + 2) { border-radius: var(--cut-2); rotate: .6deg; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-illustrated-grid .pack-card:nth-of-type(4n + 3) { border-radius: var(--cut-3); rotate: -.3deg; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-illustrated-grid .pack-card:nth-of-type(4n + 4) { border-radius: var(--cut-4); rotate: .4deg; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-illustrated-grid .pack-name { font-size: 17px; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-illustrated-grid .pack-count { font-size: 13px; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-content > .bottom-section {
    position: static; display: flex; align-items: center; justify-content: flex-end; gap: 16px; padding: 16px 0 26px; background: none;
}
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-content > .bottom-section > button { flex: none; width: auto; min-width: 240px; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-content > .bottom-section .packs-summary {
    margin-right: auto; padding: 12px 20px; font-size: 17px; background: var(--st-panel); border: 1px solid var(--st-line); border-radius: 16px;
}
/* Owner 2026-10-29 «сдвиги корявые» (100 к 1: two small tiles in the top-left corner, the buttons in the bottom-right
   one, the stage empty between them): the packs block sits in the middle of the stage, the title over it, the tiles
   centred in rows (bigger when a game has four packs or fewer), the buttons right under the tiles. `safe` keeps a long
   list (Квиз) starting at the top. */
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-content { justify-content: safe center; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-content > :is(.title, .subtitle) { justify-content: center; text-align: center; padding: 0 72px !important; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-content > .packs-container { flex: 0 1 auto; min-height: 0; width: 100%; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-illustrated-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 160px)); justify-content: center; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-illustrated-grid:not(:has(> .pack-card:nth-of-type(5))) { grid-template-columns: repeat(auto-fit, 230px); gap: 26px; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-illustrated-grid:not(:has(> .pack-card:nth-of-type(5))) .pack-name { font-size: 21px; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-illustrated-grid:not(:has(> .pack-card:nth-of-type(5))) .pack-count { font-size: 15px; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-content > .bottom-section { justify-content: center; padding-top: 44px; min-height: 130px; box-sizing: border-box; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) .packs-content > .bottom-section .packs-summary { margin-right: 0; }
/* Owner 2026-10-30 «чзх низ не виден и не скроллится» (Квиз, Угадай мелодию: two sections of packs): `flex: none` let the
   tile list grow past the 720px stage, and .packs-content clips, so the last row and the buttons were cut off with no
   scroll. The list now shrinks to the room left under the title and above the buttons and scrolls itself
   (.packs-illustrated-scroll), the buttons stay on screen; a short list still sits in the middle. */
/* Owner 2026-10-30 «для янн (и мб др игр) экран паков не адаптирован под пк» / «кнопка назад то ближе к центру, то слева
   в углу»: «Я никогда не» and «Кто из нас» have no .packs-content (title, tiles and buttons sit straight in #packs-screen),
   so the phone's 520px column stayed: two tiles a row, the back arrow inside the column, the buttons overlapping. The
   same layout as the other games: the block in the middle of the stage, the arrow in the corner, the buttons in one row
   right under the tiles. */
html.rp-stage:is([data-stage-page="nhie"], [data-stage-page="wml"]) #packs-screen { max-width: none; justify-content: safe center; overflow-y: auto; padding-left: 56px; padding-right: 56px; }
html.rp-stage:is([data-stage-page="nhie"], [data-stage-page="wml"]) #packs-screen > .title { font-size: 40px; margin: 0 0 4px; }
html.rp-stage:is([data-stage-page="nhie"], [data-stage-page="wml"]) #packs-screen > .subtitle { font-size: 18px; margin: 0 0 14px; }
html.rp-stage:is([data-stage-page="nhie"], [data-stage-page="wml"]) #packs-screen > .packs-container { flex: none; width: 100%; overflow: visible; }
html.rp-stage:is([data-stage-page="nhie"], [data-stage-page="wml"]) #packs-screen > .bottom-section { display: flex; flex-flow: row wrap; align-items: center; justify-content: center; gap: 16px; padding: 44px 0 0; min-height: 130px; box-sizing: border-box; background: none; }
html.rp-stage:is([data-stage-page="nhie"], [data-stage-page="wml"]) #packs-screen > .bottom-section > button { flex: none; width: auto; min-width: 240px; margin: 0; }
html.rp-stage:is([data-stage-page="nhie"], [data-stage-page="wml"]) #packs-screen > .bottom-section > :is(.packs-room-error, #packs-room-status) { flex: 1 1 100%; order: 2; text-align: center; }
html.rp-stage:is([data-stage-page="nhie"], [data-stage-page="wml"]) #packs-screen > .bottom-section > :is(.packs-room-error, #packs-room-status):empty { display: none; }
/* Owner 2026-10-30 (Детектор лжи on a PC): «кнопки спустить бы и в 1 ряд». «Правила» (game-preview.ts addRulesButton puts
   it into the packs' button row) stands first in the row at the buttons' height instead of alone at the stage's bottom;
   the row sits a little lower under the tiles (44px). The `.screen` in the second rule beats packs.css
   `.screen .bottom-section.packs-compact-actions > *`. */
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) #packs-screen .bottom-section > .rules-again-wrap { order: -1; width: auto; }
html.rp-stage .screen#packs-screen .bottom-section > .rules-again-wrap { flex: none; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="wml"], [data-stage-page="nhie"], [data-stage-page="meme"], [data-stage-page="im"], [data-stage-page="geo"], [data-stage-page="jh"], [data-stage-page="bunker"]) #packs-screen .bottom-section .rules-again { height: 54px; min-height: 54px; min-width: 160px; margin: 0; padding: 0 28px; border-width: 2px; border-radius: 999px; font-size: 16px; opacity: 1; }

/* The question: big text in the middle, the answers two by two, a keys hint, who answered at the bottom. */
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"]) .game-content { justify-content: safe center; gap: 26px; padding-bottom: 96px; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"]) .game-content > .game-header { display: none; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"]) .question-text { font-size: 46px; font-weight: 800; line-height: 1.25; max-width: 1100px; margin: 0 auto; text-wrap: balance; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"]) .quiz-options { display: grid; grid-template-columns: 1fr 1fr; gap: 20px 26px; width: 100%; max-width: 1140px; margin: 0 auto; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"]) .quiz-options.two-options { grid-template-columns: 1fr 1fr; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"]) .quiz-option { min-height: 100px; padding: 18px 28px; gap: 22px; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"]) .quiz-option .option-text { font-size: 28px; line-height: 1.25; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"]) .quiz-option .option-letter { width: 54px; height: 54px; font-size: 24px; flex: none; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="draw"]) .stage-keys-hint { display: flex; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"]) .movie-frame-container { max-width: 620px; margin: 0 auto; }
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"]) .answer-feedback { font-size: 20px; min-height: 28px; text-align: center; }
html.rp-stage .mini-scoreboard { position: fixed; left: 56px; right: 56px; bottom: 26px; justify-content: flex-start; gap: 12px; margin: 0; overflow: visible; background: none; }
html.rp-stage .mini-score-item { gap: 10px; padding: 7px 18px 7px 8px; font-size: 20px; border-radius: 999px; background: rgb(255 255 255 / 8%); border: 1.5px solid var(--st-line); }
html.rp-stage .mini-score-avatar { width: 42px; height: 42px; font-size: 18px; }
html.rp-stage .mini-score-name { font-size: 20px; max-width: 200px; }
html.rp-stage .mini-score-value { font-size: 20px; }
/* «Полоска очков» (shared/client/score-strip.ts, owner 2026-11-02 «смотри, чтобы ничего ни на что не наложилось»):
   the play screens that got the strip keep its band (bottom 26 px + a 56 px chip row) free, as Квиз does with its
   padding-bottom: 88px. The games' own stage rules set a smaller padding (meme 20 px, knowme 40 px), hence !important. */
html.rp-stage :is(.screen-content, .shell):has(> .rp-score-strip) { padding-bottom: 96px !important; }
/* Детектор правды is a yellow page: its own dark chips (td-theme.css), not the translucent stage chip with white text.
   The shared gradient under the bar (game-ui.css) is dropped above: on the stage the bar is fixed over the spheres,
   and on yellow it showed as a solid band. */
html.rp-stage[data-stage-page="truth"] .mini-score-item { background: var(--td-surface); border-color: var(--td-surface); }
/* Avatar picker (avatar-capture.css, «GIF | Фото»): on the phone a bottom sheet of 70vh; on the stage its inline
   heights (avatar-capture.js, window pixels) ran past the bottom edge of the zoomed page and the sheet sat low. Owner 2026-10-29: «на пк открытие попапа с гиф не по
   центру» → a centred dialog that fits the stage. */
html.rp-stage .avatar-capture-overlay { align-items: center; }
html.rp-stage .avatar-capture-modal {
    max-width: 560px; height: min(680px, calc(100vh / var(--rp-stage-zoom, 1) - 80px)); border-radius: 24px;
    padding-bottom: 20px; box-shadow: 0 24px 60px rgb(0 0 0 / 50%);
}

/* Мелодия: the /tv/ question view itself (question-stage.css, mounted by main.ts under the phone's answers, which the
   stage hides; the record player moves into it): the record on the left, the four songs as cut-paper buttons on the
   right; the mode line above, the keys hint and the answer line under the songs, the scores along the bottom. The
   palette is the /tv/ melody one (tv/style.css body[data-tv-game="melody"]). */
html:not(.rp-stage) .game-content > .qs-root { display: none; }
html.rp-stage[data-stage-page="melody"] :is(.qs-root, .qs-reveal) {
    --tv-surface: #2a1758; --tv-line: rgb(255 255 255 / 12%); --bg-secondary: #2a1758;
    --accent: #a677ef; --accent-ink: #17191f; --gold: #edc945;
    --text-primary: #fff; --text-secondary: #d9ccf5; --rp-correct: #30c883; --rp-wrong: #fe7b90;
}
html.rp-stage[data-stage-page="melody"] .game-content > .quiz-options { display: none; }
/* The record's glow (music-player.css .vinyl-container::before) reaches past this 1200 px column: the phone's scroll
   box would cut it into a rectangle (owner 2026-10-30: «видны края сияния вокруг пластинки»); the stage fits 720 px. */
html.rp-stage[data-stage-page="melody"] #game-screen .game-content { justify-content: safe center; gap: 14px; max-width: 1200px; margin: 0 auto; width: 100%; padding-bottom: 88px; overflow: visible; }
html.rp-stage[data-stage-page="melody"] .game-content > .qs-root { flex: 1 1 auto; width: 100%; }
html.rp-stage[data-stage-page="melody"] .qs-root .vinyl-base { box-shadow: 0 0 0 8px rgb(166 119 239 / 40%); }
html.rp-stage[data-stage-page="melody"] .qs-root .audio-player-bar { background: var(--bg-secondary); border: 1px solid var(--tv-line); }
/* The keys hint and the answer line under the songs (main.ts moves them into the view's right column). */
html.rp-stage[data-stage-page="melody"] .qs-root .stage-keys-hint { justify-content: flex-start; padding-left: 8px; margin: -10px 0 0; }
html.rp-stage[data-stage-page="melody"] .qs-root .answer-feedback { text-align: left; padding-left: 8px; margin: -14px 0 0; }
html.rp-stage[data-stage-page="melody"] .qs-root .answer-feedback:empty { display: none; }
/* Round results: the /tv/ layout (question-stage.css .qs-reveal) in the /tv/ view's box under the top bar. */
html.rp-stage[data-stage-page="melody"] #reveal-container.qs-reveal .rr-container { inset: 92px 40px 0; }

/* Квиз: the /tv/ question view itself (question-stage.css, mounted by main.ts under the phone's answers, which the
   stage hides): the picture, the record or the four photos on the left, the topic, the question and the answers as
   cut-paper buttons on the right (two by two without media); the keys hint and the answer line under the answers, the
   scores along the bottom. The record player and the 4photo cells and keyboard move into it (main.ts placeStageNodes).
   The palette is the /tv/ quiz one (tv/style.css body[data-tv-game="quiz"]). */
html.rp-stage[data-stage-page="quiz"] :is(.qs-root, .qs-reveal) {
    --tv-surface: #100f36; --tv-line: rgb(255 255 255 / 16%); --bg-secondary: #211759;
    --accent: #6640ba; --accent-ink: #fff; --gold: #d5ae58;
    --text-primary: #fff; --text-secondary: #d6cfe8; --rp-correct: #30c883; --rp-wrong: #fe7b90;
}
html.rp-stage[data-stage-page="quiz"] .game-content > :is(.ai-topic-line, .movie-frame-container, .music-player, .question-text, .fourphoto-grid, .fourphoto-cells, .fourphoto-keyboard, .quiz-options) { display: none; }
html.rp-stage[data-stage-page="quiz"] #game-screen .game-content { justify-content: safe center; gap: 14px; max-width: 1200px; margin: 0 auto; width: 100%; padding-bottom: 88px; overflow: visible; }
html.rp-stage[data-stage-page="quiz"] .game-content > .qs-root { flex: 1 1 auto; width: 100%; }
html.rp-stage[data-stage-page="quiz"] .qs-root .vinyl-base { box-shadow: 0 0 0 8px rgb(102 64 186 / 38%); }
html.rp-stage[data-stage-page="quiz"] .qs-root .audio-player-bar { background: var(--bg-secondary); border: 1px solid var(--tv-line); }
html.rp-stage[data-stage-page="quiz"] .qs-root .audio-progress-fill { background: linear-gradient(90deg, #8f6ae0, var(--gold)); }
/* 4photo: the phone's letter cells and keyboard in place of the screen's empty cells. */
html.rp-stage[data-stage-page="quiz"] .qs-four-input { display: flex; flex-direction: column; align-items: center; gap: 22px; width: 100%; }
html.rp-stage[data-stage-page="quiz"] .qs-four-input .fourphoto-keyboard { max-width: 560px; }
/* The keys hint and the answer line under the answers (main.ts moves them into the view's right column). */
html.rp-stage[data-stage-page="quiz"] .qs-root .stage-keys-hint { margin: -10px 0 0; }
html.rp-stage[data-stage-page="quiz"] .qs-root.has-media .stage-keys-hint { justify-content: flex-start; padding-left: 8px; }
html.rp-stage[data-stage-page="quiz"] .qs-root:has(.tv-options.is-four) .stage-keys-hint { display: none; }
html.rp-stage[data-stage-page="quiz"] .qs-root .answer-feedback { margin: -14px 0 0; }
html.rp-stage[data-stage-page="quiz"] .qs-root.has-media .answer-feedback { text-align: left; padding-left: 8px; }
html.rp-stage[data-stage-page="quiz"] .qs-root .answer-feedback:empty { display: none; }
/* Round results: the /tv/ layout (question-stage.css .qs-reveal) in the /tv/ view's box under the top bar. */
/* The bottom stops over the host's pinned «Дальше», so the answers never go under it. Kept for everyone and from the
   start: the button comes up mid-reveal, and a box that shrank then would move the question. */
html.rp-stage[data-stage-page="quiz"] #reveal-container.qs-reveal .rr-container { inset: 92px 40px 80px; }

/* Смехлыст: each prompt on its own paper card with the answer field on it (prompts side by side), the matchup as
   two big cards with «VS» between them, keys A/B. */
html.rp-stage[data-stage-page="quiplash"] :is(#answering-screen, #voting-screen) .game-header { display: none; }
html.rp-stage[data-stage-page="quiplash"] .answering-content { justify-content: safe center; padding-bottom: 48px; }
html.rp-stage[data-stage-page="quiplash"] .answering-content > .title { font-size: 26px; font-family: inherit; font-weight: 700; opacity: .8; margin: 0 0 26px; }
html.rp-stage[data-stage-page="quiplash"] .answering-wrapper { flex: none; width: 100%; max-width: 1180px; align-items: center; }
html.rp-stage[data-stage-page="quiplash"] .prompts-list { flex: none; flex-direction: row; gap: 36px; overflow: visible; margin: 0 0 30px; align-self: stretch; }
html.rp-stage[data-stage-page="quiplash"] .prompt-card { flex: 1 1 0; display: flex; flex-direction: column; justify-content: space-between; min-height: 300px; padding: 36px 34px 30px; border-radius: var(--cut-1); box-shadow: var(--cut-shadow); rotate: -.8deg; }
html.rp-stage[data-stage-page="quiplash"] .prompt-card:nth-child(2n) { border-radius: var(--cut-2); rotate: .7deg; }
html.rp-stage[data-stage-page="quiplash"] .prompt-text { font-family: var(--st-display); font-size: 32px; font-weight: 800; line-height: 1.2; margin: 0 0 26px; text-wrap: balance; }
html.rp-stage[data-stage-page="quiplash"] .prompt-card .input { height: 68px; padding: 0 22px; font-size: 24px; border-radius: 16px; }
html.rp-stage[data-stage-page="quiplash"] #btn-submit-answers { flex: none; width: auto; min-width: 320px; }
html.rp-stage[data-stage-page="quiplash"] .submitted-overlay { inset: -20px; border-radius: 28px; }
html.rp-stage[data-stage-page="quiplash"] .submitted-icon { font-size: 72px; }
html.rp-stage[data-stage-page="quiplash"] .submitted-text { font-size: 32px; }
html.rp-stage[data-stage-page="quiplash"] .submitted-hint { font-size: 20px; }

/* The matchup: the /tv/ one itself (quiplash-matchup.css, mounted by main.ts under the phone's prompt card, which the
   stage hides with the phone's answer cards): the prompt's joke card, the two answers as buttons with «VS» between
   them; the hint, the keys and the author's line under them, the scores along the bottom. The palette is the /tv/
   quiplash one (tv/style.css body[data-tv-game="quiplash"]). */
html:not(.rp-stage) .voting-content > .qpm-root { display: none; }
html.rp-stage[data-stage-page="quiplash"] :is(.qpm-root, .qs-reveal) {
    --tv-surface: #3c1a5e; --tv-line: rgb(255 255 255 / 14%); --bg-secondary: #3c1a5e;
    --accent: #743cae; --accent-ink: #fff; --gold: #73c3b6;
    --text-primary: #fff; --text-secondary: #d8c8e8; --rp-correct: #30c883; --rp-wrong: #fd8295;
    --qp-paper: #f4eff8; --qp-ink: #17191f; --qp-ink-accent: #5e3a86;
}
html.rp-stage[data-stage-page="quiplash"] .voting-content > :is(.voting-prompt-card, .player-answers) { display: none; }
html.rp-stage[data-stage-page="quiplash"] .voting-content { justify-content: safe center; gap: 0; max-width: 1200px; margin: 0 auto; width: 100%; padding-bottom: 88px; }
html.rp-stage[data-stage-page="quiplash"] .voting-content > .qpm-root { flex: none; width: 100%; margin-bottom: 30px; }
/* The thumbs and the flag on the prompt's card after the vote (main.ts puts them there on the stage). */
html.rp-stage[data-stage-page="quiplash"] .qpm-root .tv-qp-prompt:has(> .quiplash-card-vote:not([hidden])) { padding-bottom: 64px; }
html.rp-stage[data-stage-page="quiplash"] :is(.voting-hint, .author-notice) { font-size: 22px; }
html.rp-stage[data-stage-page="quiplash"] #voting-screen .stage-keys-hint { margin-top: 14px; }
html.rp-stage[data-stage-page="quiplash"] #voting-screen:not(:has(.player-answer-card.votable)) .stage-keys-hint { visibility: hidden; }
/* Round results: the /tv/ layout (question-stage.css .qs-reveal) in the /tv/ view's box under the top bar; the prompt's
   card keeps room for the thumbs and the flag. */
html.rp-stage[data-stage-page="quiplash"] #reveal-container.qs-reveal .rr-container { inset: 92px 40px 0; }
html.rp-stage[data-stage-page="quiplash"] #reveal-container.qs-reveal .rr-context.quiplash-reveal-prompt { padding: 28px 32px 64px; border-radius: var(--cut-2); box-shadow: 8px 10px 0 rgb(0 0 0 / 30%); background: var(--qp-paper); }

/* Бредовуха: the /tv/ round itself (fibbage-stage.css, mounted by main.ts next to the phone's card and answers, which
   the stage hides): the fact on its cream card over two notes with the lie field, «Отправить» and the hint on the card
   (main.ts moves them there), then the fact on a smaller card and the answers as cut cards, two by two (three across
   past four), keys A–H; your own lie stays dimmed. The palette is the page's (fb-theme.css --fb-*). */
html:not(.rp-stage) :is(.writing-content > .fbs-lie, #voting-screen .fbs-pick) { display: none; }
html.rp-stage[data-stage-page="fibbage"] :is(.fbs-root, .qs-reveal) {
    --tv-surface: #4e1a1d; --tv-line: rgb(240 229 198 / 16%); --accent: #eba332; --accent-ink: #17191f; --gold: #eba332;
}
html.rp-stage[data-stage-page="fibbage"] :is(#writing-screen, #voting-screen) .game-header,
html.rp-stage[data-stage-page="fibbage"] :is(#writing-screen, #voting-screen) .title,
html.rp-stage[data-stage-page="fibbage"] .writing-content > .fb-card-stack,
html.rp-stage[data-stage-page="fibbage"] #voting-screen > .screen-content > :is(#voting-question-card, .subtitle, .vote-options) { display: none; }
html.rp-stage[data-stage-page="fibbage"] :is(.writing-content, #voting-screen > .screen-content) { justify-content: safe center; align-items: center; padding-bottom: 88px; }
html.rp-stage[data-stage-page="fibbage"] .writing-content > .fbs-lie { flex: none; width: 100%; max-width: 1100px; margin: 0 auto; }
html.rp-stage[data-stage-page="fibbage"] #voting-screen .fbs-pick { flex: none; width: 100%; max-width: 1200px; margin: 0 auto; }
/* The card's slot: the lie in one row with «Отправить», the hint under it; once sent, the line in ink. */
html.rp-stage[data-stage-page="fibbage"] .fbs-lie .tv-fb-slot { display: flex; flex-direction: column; align-items: center; gap: 16px; }
html.rp-stage[data-stage-page="fibbage"] .fbs-lie .fake-input-section { display: flex; flex-wrap: wrap; gap: 18px; width: 100%; max-width: 820px; }
html.rp-stage[data-stage-page="fibbage"] .fbs-lie .fake-input-section .input { flex: 1 1 0; min-width: 0; height: 68px; padding: 0 24px; font-size: 26px; border-radius: 16px; background: #fff; border: 2px solid var(--fb-maroon); }
html.rp-stage[data-stage-page="fibbage"] .fbs-lie .fake-input-section .btn-play { flex: none; width: auto; min-width: 220px; height: 68px; margin: 0; }
html.rp-stage[data-stage-page="fibbage"] .fbs-lie .fake-input-section .error-text { flex-basis: 100%; font-size: 18px; }
html.rp-stage[data-stage-page="fibbage"] .fbs-lie .subtitle { margin: 0; font-size: 22px; font-weight: 600; color: var(--fb-ink-muted); }
html.rp-stage[data-stage-page="fibbage"] .fbs-lie .submitted-overlay.visible { position: static; flex-direction: row; flex-wrap: wrap; gap: 6px 14px; background: none; }
html.rp-stage[data-stage-page="fibbage"] .fbs-lie .submitted-icon { font-size: 40px; color: #3f8a2a; }
html.rp-stage[data-stage-page="fibbage"] .fbs-lie .submitted-text { font-size: 30px; color: var(--fb-ink); }
html.rp-stage[data-stage-page="fibbage"] .fbs-lie .submitted-hint { flex-basis: 100%; text-align: center; font-size: 20px; color: var(--fb-ink-muted); }
html.rp-stage[data-stage-page="fibbage"] .fbs-lie .submitted-overlay.visible ~ .subtitle { display: none; }
/* The thumbs and the flag on the fact's card after the vote (main.ts puts them there on the stage). */
html.rp-stage[data-stage-page="fibbage"] .fbs-pick .tv-fb-card:has(> .fibbage-card-vote:not([hidden])) { padding-bottom: 60px; }
html.rp-stage[data-stage-page="fibbage"] .vote-confirmed { font-size: 22px; margin-top: 18px; }
html.rp-stage[data-stage-page="fibbage"] #voting-screen .stage-keys-hint { margin-top: 18px; }
html.rp-stage[data-stage-page="fibbage"] #voting-screen:has(.fbs-pick.is-locked) .stage-keys-hint { display: none; }
/* Round results: the /tv/ layout (question-stage.css .qs-reveal) in the /tv/ view's box under the top bar; the fact's
   card keeps room for the thumbs and the flag. */
html.rp-stage[data-stage-page="fibbage"] #reveal-container.qs-reveal .rr-container { inset: 92px 40px 0; }
html.rp-stage[data-stage-page="fibbage"] #reveal-container.qs-reveal .rr-context.fibbage-reveal-question { padding: 26px 32px 64px; }

/* «100 к 1»: the /tv/ board itself (hundred-board.css, mounted by main.ts under the phone's table, which the stage
   hides), the answer typed in one row under it, the scores along the bottom as the /tv/ footer. */
html:not(.rp-stage) .game-content > .hk-board-root { display: none; }
html.rp-stage[data-stage-page="hundred"] .game-content > :is(.question-text, .answer-table) { display: none; }
html.rp-stage[data-stage-page="hundred"] #game-screen .game-content { justify-content: flex-start; gap: 18px; padding-top: 34px; padding-bottom: 100px; }
html.rp-stage[data-stage-page="hundred"] .game-content > .hk-board-root { width: 100%; max-width: 1220px; margin: 0 auto; flex: 1 1 auto; }
html.rp-stage[data-stage-page="hundred"] .answer-input-section { width: 100%; max-width: 940px; gap: 18px; margin: 6px auto 0; }
html.rp-stage[data-stage-page="hundred"] .answer-input { flex: 1 1 0; min-width: 0; height: 70px; padding: 0 24px; font-size: 26px; border-radius: 18px; }
html.rp-stage[data-stage-page="hundred"] .btn-send { flex: none; width: 120px; height: 70px; border-radius: 35px; font-size: 30px; }
html.rp-stage[data-stage-page="hundred"] .answer-feedback { margin: 0; }

/* Детектор правды: the /tv/ step itself (truth-detect.css, mounted by main.ts before the phone's phases, which the stage
   hides but for the keys hint): the statement in ink, the polygraph, «Да» / «Нет» or the numbers as cut cards (keys
   ←/→ (1/2) and the digits), the scores along the bottom. The palette is the page's (td-theme.css --td-*). */
html:not(.rp-stage) .game-content > .tdd-root { display: none; }
html.rp-stage[data-stage-page="truth"] :is(.tdd-root, .qs-reveal) {
    --tv-surface: #272723; --tv-line: rgb(255 255 255 / 12%); --accent: #272723; --accent-ink: #fff; --gold: #e88629;
}
html.rp-stage[data-stage-page="truth"] .game-content > .question-text,
html.rp-stage[data-stage-page="truth"] :is(#answer-phase, #guess-phase) > :not(.stage-keys-hint) { display: none; }
html.rp-stage[data-stage-page="truth"] .game-content > .tdd-root { flex: none; width: 100%; max-width: 1200px; margin: 0 auto; }
html.rp-stage[data-stage-page="truth"] .phase-container { display: flex; flex-direction: column; align-items: center; gap: 26px; }
html.rp-stage[data-stage-page="truth"] .waiting-text { font-size: 26px; font-weight: 700; }
html.rp-stage[data-stage-page="truth"] .answer-feedback:not(:empty) { align-self: center; width: auto; padding: 8px 30px; border-radius: 999px; font-size: 22px; }
html.rp-stage[data-stage-page="truth"] .stage-keys-hint { margin: 0; }
/* Once a pick is taken the scores pinned along the bottom used to cover «Принято!» (owner 2026-10-30): «Ответьте честно!»
   gives way to the waiting line, «Принято!» sits right under it, and the gaps tighten so both stay above the chips. */
html.rp-stage[data-stage-page="truth"] .game-content:has(> #waiting-phase:not([style*="none"])) { gap: 12px; }
html.rp-stage[data-stage-page="truth"] .game-content:has(> #waiting-phase:not([style*="none"])) .tv-td-hint { display: none; }
html.rp-stage[data-stage-page="truth"] .game-content:has(> #waiting-phase:not([style*="none"])) .tdd-root { margin-bottom: 14px; }
html.rp-stage[data-stage-page="truth"] .waiting-text { margin: 0; }
html.rp-stage[data-stage-page="truth"] .answer-feedback { margin: 0; }
html.rp-stage[data-stage-page="truth"] :is(#answer-phase:has(.yesno-btn:disabled), #guess-phase:has(.number-btn:disabled)) .stage-keys-hint { visibility: hidden; }
/* Round results: the /tv/ layout (question-stage.css .qs-reveal) in the /tv/ view's box under the top bar. */
/* The bottom stops over the pinned «Кто как ответил?» button, so the last answers never go under it. */
html.rp-stage[data-stage-page="truth"] #reveal-container.qs-reveal .rr-container { inset: 92px 40px 80px; }

/* «Что бы ты выбрал?»: the /tv/ dilemma itself (wyr-choice.css, mounted by main.ts under the swipe card, which the stage
   hides with the phone's buttons): what is asked on top, the two sides as big cut-card buttons with «или» (a click,
   ←/→, 1/2 or A/B), the thumbs and the flag under them once answered, the keys hint or «Ответ принят» under that.
   The palette is the /tv/ one (tv/style.css body[data-tv-game="wouldyourather"]); the round results take the /tv/
   layout (question-stage.css .qs-reveal). */
html:not(.rp-stage) .decision-layout > .wyc-root { display: none; }
html.rp-stage[data-stage-page="wyr"] :is(.wyc-root, .qs-reveal) {
    --tv-surface: #004e99; --tv-line: rgb(255 255 255 / 22%); --bg-secondary: #004e99;
    --accent: #ca003d; --accent-ink: #fff; --gold: #00bce9;
    --text-primary: #fff; --text-secondary: #e8f3ff; --rp-correct: #72feb5; --rp-wrong: #fdd2d3;
    --wyr-ink: #17191f; --wyr-a: #00bce9; --wyr-b: #ca003d;
}
html.rp-stage[data-stage-page="wyr"] .decision-layout {
    max-width: 1200px; width: 100%; margin: 0 auto; min-height: calc(var(--app-height, 720px) - 110px);
    justify-content: safe center; gap: 18px; padding: 0 40px 10px;
}
html.rp-stage[data-stage-page="wyr"] .decision-layout > :is(.decision-heading, .choice-card, .choice-buttons) { display: none; }
html.rp-stage[data-stage-page="wyr"] .decision-layout > .phase-line { justify-content: center; gap: 28px; font-size: 16px; }
html.rp-stage[data-stage-page="wyr"] .decision-layout > .wyc-root { position: relative; flex: none; padding: 8px 0; }
html.rp-stage[data-stage-page="wyr"] .wyc-root > .wyr-card-vote { position: static; transform: none; align-self: center; margin-top: 4px; }
html.rp-stage[data-stage-page="wyr"] .wyc-root > .wyr-report-flag { position: absolute; right: 8px; bottom: 0; color: #fff; }
html.rp-stage[data-stage-page="wyr"] .decision-layout > .wyr-teaser-chip { margin: 0 auto; }
html.rp-stage[data-stage-page="wyr"] .decision-layout > .wyr-teaser-cta { width: auto; min-width: 320px; align-self: center; }
html.rp-stage[data-stage-page="wyr"] #swipe-hint { margin: 0; font-size: 22px; text-align: center; }
html.rp-stage[data-stage-page="wyr"] .decision-layout:not(:has(.wyc-root.is-locked)) #swipe-hint,
html.rp-stage[data-stage-page="wyr"] .decision-layout:has(.wyc-root.is-locked) .stage-keys-hint { display: none; }
/* The role, the impostor vote and its reveal: the phone's panels, a wider column in the middle. */
html.rp-stage[data-stage-page="wyr"] :is(.role-panel, .vote-scroll, .reveal-scroll) { max-width: 900px; width: 100%; margin: 0 auto; }
html.rp-stage[data-stage-page="wyr"] .candidate-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* Round results: the /tv/ layout (question-stage.css .qs-reveal) in the /tv/ view's box under the top bar. */
html.rp-stage[data-stage-page="wyr"] #wyr-reveal-container.qs-reveal .rr-container { inset: 92px 40px 0; }
html.rp-stage[data-stage-page="wyr"] #wyr-reveal-container.qs-reveal .rr-badge.majority { color: var(--wyr-ink); background: var(--wyr-a); }
html.rp-stage[data-stage-page="wyr"] #wyr-reveal-container.qs-reveal .rr-lb-score { color: var(--wyr-a); }
/* The phone's small caps title (styles.css .wyr-round-reveal) becomes the /tv/ question; voters as chips, as on /tv/. */
html.rp-stage[data-stage-page="wyr"] #wyr-reveal-container.qs-reveal .rr-context-text { color: #fff; font-size: 30px; font-weight: 700; text-transform: none; letter-spacing: 0; }
html.rp-stage[data-stage-page="wyr"] #wyr-reveal-container.qs-reveal .rr-voter { color: #fff; background: rgb(255 255 255 / 12%); }

/* «Как хорошо ты меня знаешь?»: the /tv/ step itself (knowme-stage.css, mounted by main.ts after the question card, which
   the stage hides with the phone's badge and phases): who answers on the navy label, the question, the hint, the
   options as cream cut-card buttons (a click, A–D or 1–4; ←/→ for two), the keys hint under them while this player may
   pick. The palette is the /tv/ one (tv/style.css body[data-tv-game="knowme"]); the round results take the /tv/
   layout (question-stage.css .qs-reveal). */
html:not(.rp-stage) .game-content > .kms-root { display: none; }
html.rp-stage[data-stage-page="knowme"] :is(.kms-root, .qs-reveal) {
    --tv-surface: #313555; --tv-line: rgb(255 242 220 / 18%); --accent: #822d29; --accent-ink: #fff; --gold: #fff2dc;
    --text-primary: #fff; --text-secondary: #fff2dc;
}
html.rp-stage[data-stage-page="knowme"] #onboarding-screen .slide-icon { width: 300px; }
html.rp-stage[data-stage-page="knowme"] #game-screen .game-content {
    display: flex; flex-direction: column; justify-content: safe center; gap: 20px;
    min-height: var(--app-height, 720px); padding-top: 104px; padding-bottom: 40px;
}
html.rp-stage[data-stage-page="knowme"] .game-content > :is(.game-header, .respondent-badge, .km-question-card, .phase-container) { display: none !important; }
html.rp-stage[data-stage-page="knowme"] .game-content > .kms-root { flex: none; width: 100%; max-width: 1200px; margin: 0 auto; }
html.rp-stage[data-stage-page="knowme"] .kms-root > .km-teaser-chip { margin: 0 auto; }
html.rp-stage[data-stage-page="knowme"] .game-content > .km-teaser-cta { width: auto; min-width: 320px; align-self: center; margin: 0 auto; }
html.rp-stage[data-stage-page="knowme"] .game-content > .knowme-card-vote { align-self: center; margin: 0; }
html.rp-stage[data-stage-page="knowme"] #km-keys-hint { margin: 0; }
html.rp-stage[data-stage-page="knowme"] .game-content:not(:has(.tv-km-options.is-votable)) #km-keys-hint { visibility: hidden; }
html.rp-stage[data-stage-page="knowme"] .game-content:has(.tv-km-options.is-two) #km-keys-hint kbd:nth-of-type(n + 3) { display: none; }
/* Round results: the /tv/ layout (question-stage.css .qs-reveal) in the /tv/ view's box under the top bar. */
html.rp-stage[data-stage-page="knowme"] #reveal-container.qs-reveal .rr-container { inset: 92px 40px 0; }
html.rp-stage[data-stage-page="knowme"] #reveal-container.qs-reveal .rr-context-text { color: #fff; font-weight: 700; }
html.rp-stage[data-stage-page="knowme"] #reveal-container.qs-reveal .rr-context-subtext { font-size: 21px; font-weight: 600; }
html.rp-stage[data-stage-page="knowme"] #reveal-container.qs-reveal .rr-context .knowme-card-vote { justify-content: center; margin: 18px 0 0; }

/* «Кто из нас» (only in a room: the page adds its meta for ?room=, the one-phone game keeps the phone column): each
   step is the /tv/ one (wml-stage.css, mounted by multiplayer.ts before the phone's card, statement and punishment
   kicker, which the stage hides with the rest of the phone's step): the statement on the dark cut card with the
   players as cut-card buttons (a click or 1–9), the votes as the screen's tally rows, the punishments on its cards.
   The phone's top bar, round line, countdowns and «Выполнено» stay. The palette is the /tv/ one
   (tv/style.css body[data-tv-game="whosmostlikelyto"]). */
html:not(.rp-stage) .wms-root { display: none; }
html.rp-stage[data-stage-page="wml"] .wms-root { --tv-surface: #262629; --tv-line: rgb(228 227 229 / 14%); --text-secondary: #b4b3b8; flex: 1 0 auto; display: flex; flex-direction: column; min-height: 0; }
html.rp-stage[data-stage-page="wml"] .screen.multiplayer-screen { max-width: none; padding: 20px 56px 28px; }
html.rp-stage[data-stage-page="wml"] :is(#onboarding-screen, #packs-screen, #multiplayer-waiting-screen) { padding-top: 34px; }
html.rp-stage[data-stage-page="wml"] #multiplayer-waiting-screen .screen-content,
html.rp-stage[data-stage-page="wml"] #multiplayer-ended-screen .multiplayer-center { width: 100%; max-width: 640px; margin: 0 auto; }
html.rp-stage[data-stage-page="wml"] .multiplayer-topbar { min-height: 64px; }
html.rp-stage[data-stage-page="wml"] .multiplayer-brand-mark { font-size: 14px; }
html.rp-stage[data-stage-page="wml"] .multiplayer-topline { margin: 0 0 8px; }
html.rp-stage[data-stage-page="wml"] :is(.round-pill, .answer-progress, .next-round-label) { font-size: 17px; }
html.rp-stage[data-stage-page="wml"] #multiplayer-game-screen > :is(.wm-question-card, .wm-guess-banner, .wm-vote-hint, .wm-vote-grid),
html.rp-stage[data-stage-page="wml"] #multiplayer-reveal-screen > :is(.reveal-statement, .wm-reveal-summary, .wm-tally, .wm-leaderboard),
html.rp-stage[data-stage-page="wml"] .punishment-phase-content > :is(.punishment-phase-kicker, h1, .punishment-phase-copy, .punishment-phase-list, .punishment-phase-status) { display: none !important; }
html.rp-stage[data-stage-page="wml"] #multiplayer-game-screen > .wm-teaser-cta { align-self: center; width: auto; min-width: 320px; }
html.rp-stage[data-stage-page="wml"] .wms-root .wm-teaser-chip { align-self: center; margin: 0; }
/* The question card's thumbs and flag, moved onto the stage's card (multiplayer.ts placeCardExtras). */
html.rp-stage[data-stage-page="wml"] .tv-wml-card .wm-online-card-vote { position: static; margin-top: 8px; }
html.rp-stage[data-stage-page="wml"] .tv-wml-card .wm-online-report-flag { position: absolute; right: 14px; bottom: 12px; }
html.rp-stage[data-stage-page="wml"] .tv-wml-card { position: relative; }
html.rp-stage[data-stage-page="wml"] .next-round-track { width: 100%; max-width: 760px; margin: 18px auto 0; height: 6px; }
html.rp-stage[data-stage-page="wml"] .punishment-phase-content { max-width: none; }
html.rp-stage[data-stage-page="wml"] .punishment-phase-content > :is(.punishment-complete-button, .punishment-waiting, .punishment-timebar, .punishment-time-label, .wm-punishment-cta) { width: 100%; max-width: 480px; margin-left: auto; margin-right: auto; }
html.rp-stage[data-stage-page="wml"] .punishment-complete-button { min-height: 60px; font-size: 19px; }
html.rp-stage[data-stage-page="wml"] .punishment-time-label { font-size: 16px; }

/* «Я никогда не» (only in a room, as «Кто из нас»): each step is the /tv/ one (nhie-stage.css on wml-stage.css, mounted
   by multiplayer.ts before the phone's swipe card, statement and punishment kicker, which the stage hides with the rest
   of the phone's step): the statement on the dark cut card with «Не было» / «Было» as two cut-card buttons (a click,
   1/2 or ←/→), the answers as the screen's two columns with the ring, the punishments on its cards. The phone's top
   bar, round line, countdowns and «Выполнено» stay. The palette is the /tv/ one
   (tv/style.css body[data-tv-game="neverhaveiever"]). */
html.rp-stage[data-stage-page="nhie"] .nhs-root {
    --tv-surface: #2a1d24; --tv-line: rgb(241 218 221 / 14%); --text-secondary: #c9b4b8; --bg-primary: #171316; --bg-secondary: #2a1d24;
    --wm-rose: #e04a5e; --wm-rose-text: #f7a1ac; --wm-crimson: #bc2438; --rp-correct: #75c259;
    flex: 1 0 auto; display: flex; flex-direction: column; min-height: 0;
}
html.rp-stage[data-stage-page="nhie"] .screen.multiplayer-screen { width: 100%; max-width: none; padding: 20px 56px 28px; }
html.rp-stage[data-stage-page="nhie"] :is(#onboarding-screen, #packs-screen, #multiplayer-waiting-screen) { padding-top: 34px; }
html.rp-stage[data-stage-page="nhie"] #multiplayer-waiting-screen .screen-content,
html.rp-stage[data-stage-page="nhie"] #multiplayer-ended-screen .multiplayer-center { width: 100%; max-width: 640px; margin: 0 auto; }
html.rp-stage[data-stage-page="nhie"] .multiplayer-topbar { min-height: 64px; }
html.rp-stage[data-stage-page="nhie"] .multiplayer-topline { margin: 0 0 8px; }
html.rp-stage[data-stage-page="nhie"] :is(.round-pill, .answer-progress, .next-round-label) { font-size: 17px; }
html.rp-stage[data-stage-page="nhie"] #multiplayer-game-screen > :is(.multiplayer-lives, .split-statement-card, .multiplayer-answer-area),
html.rp-stage[data-stage-page="nhie"] #multiplayer-reveal-screen > :is(.reveal-statement, .choice-columns),
html.rp-stage[data-stage-page="nhie"] .punishment-phase-content > :is(.punishment-phase-kicker, h1, .punishment-phase-copy, .punishment-phase-list, .punishment-phase-status) { display: none !important; }
html.rp-stage[data-stage-page="nhie"] #multiplayer-game-screen > .nhie-upgrade { align-self: center; width: auto; min-width: 320px; }
html.rp-stage[data-stage-page="nhie"] .nhs-root .nhie-card-teaser { align-self: center; margin: 0; }
/* The card's thumbs, flag and refresh, moved onto the stage's card (multiplayer.ts placeCardExtras). */
html.rp-stage[data-stage-page="nhie"] .tv-wml-card { position: relative; }
html.rp-stage[data-stage-page="nhie"] .tv-wml-card .nhie-online-card-vote { position: static; margin-top: 8px; }
html.rp-stage[data-stage-page="nhie"] .tv-wml-card .nhie-report-flag { position: absolute; right: 14px; bottom: 12px; }
html.rp-stage[data-stage-page="nhie"] .tv-wml-card .nhie-refresh-card { position: absolute; right: 14px; top: 12px; }
html.rp-stage[data-stage-page="nhie"] .next-round-track { width: 100%; max-width: 760px; margin: 18px auto 0; height: 6px; }
html.rp-stage[data-stage-page="nhie"] .punishment-phase-content { width: 100%; max-width: none; }
html.rp-stage[data-stage-page="nhie"] .punishment-phase-content > :is(.punishment-complete-button, .punishment-waiting, .punishment-timebar, .punishment-time-label, .rp-premium-cta) { width: 100%; max-width: 480px; margin-left: auto; margin-right: auto; }
html.rp-stage[data-stage-page="nhie"] .punishment-complete-button { min-height: 60px; font-size: 19px; }
html.rp-stage[data-stage-page="nhie"] .punishment-time-label { font-size: 16px; }

/* «Что за мем?»: each step is the /tv/ one (meme-stage.css, mounted by main.ts after the round screen's prompt card,
   which the stage hides with the phone's subtitle, hand, table and «Карта выбрана» overlay): the prompt on the white
   cut card on the left, the cards on the right as cut-card buttons (the hand while choosing, the table while voting;
   a click, 1–9 or the letter), the pick with the purple edge. «Обновить руку» stays under the cards. The round results
   take the /tv/ layout (question-stage.css .qs-reveal + meme-stage.css .mms-reveal). The palette is the /tv/ one
   (tv/style.css body[data-tv-game="whatdoyoumeme"]): a light page, ink on white cards. */
html:not(.rp-stage) .game-content > .mms-root { display: none; }
html.rp-stage[data-stage-page="meme"] :is(.mms-root, .mms-reveal) {
    --tv-surface: #fff; --tv-line: #dddbe6; --accent: #267c86; --accent-ink: #fff; --gold: #7e3c9b;
    --text-primary: #17191f; --text-secondary: #4a4d57; --light-ink: #17191f; --light-card: #fff;
    --cut-shadow: 5px 6px 0 rgb(23 25 31 / 14%);
}
html.rp-stage[data-stage-page="meme"] :is(#choosing-screen, #voting-screen) .game-content {
    display: flex; flex-direction: column; justify-content: safe center; gap: 16px; max-width: 1240px; margin: 0 auto; width: 100%;
    min-height: var(--app-height, 720px); padding-top: 88px; padding-bottom: 20px;
}
html.rp-stage[data-stage-page="meme"] .game-content > :is(.game-header, .prompt-card, .choosing-subtitle, .voting-subtitle, .cards-grid, .table-grid, .submitted-overlay) { display: none !important; }
html.rp-stage[data-stage-page="meme"] .game-content > .mms-root { flex: none; width: 100%; }
html.rp-stage[data-stage-page="meme"] .mms-root.is-voting .tv-meme-table:not(.is-captions) { flex: none; height: 480px; }
html.rp-stage[data-stage-page="meme"] .mms-root .tv-meme-table.is-captions { flex: none; height: auto; max-height: 500px; }
/* The hand leaves room for «Обновить руку» under it. */
html.rp-stage[data-stage-page="meme"] #choosing-screen .mms-root .tv-meme-table:not(.is-captions) { flex: none; height: 410px; }
html.rp-stage[data-stage-page="meme"] #choosing-screen .mms-root .tv-meme-table.is-captions { max-height: 410px; }
html.rp-stage[data-stage-page="meme"] .game-content > .btn-refresh-hand { align-self: center; width: auto; min-height: 46px; padding: 0 28px; font-size: 17px; margin: 0; }
/* Round results: the /tv/ layout in the /tv/ view's box under the top bar; light tokens and the prompt as on /tv/. */
html.rp-stage[data-stage-page="meme"] #reveal-container.mms-reveal { overflow: visible; }
html.rp-stage[data-stage-page="meme"] #reveal-container.mms-reveal .rr-container {
    inset: 92px 40px 0;
    --rr-ink: var(--light-ink); --rr-muted: var(--text-secondary);
    --rr-surface: var(--light-card); --rr-border: var(--tv-line);
    --rr-leading-surface: var(--light-card); --rr-leading-border: var(--gold);
    --rr-wrong-surface: var(--light-card); --rr-correct-surface: var(--light-card);
}
html.rp-stage[data-stage-page="meme"] #reveal-container.mms-reveal .rr-context { position: relative; padding: 24px 28px 56px; background: var(--light-card); border: 2px solid var(--tv-line); border-radius: var(--cut-2); rotate: -1deg; box-shadow: var(--cut-shadow); }
html.rp-stage[data-stage-page="meme"] #reveal-container.mms-reveal .rr-context-text { color: var(--light-ink); font-weight: 700; }
html.rp-stage[data-stage-page="meme"] #reveal-container.mms-reveal .rr-option.rr-type-correct { border-color: var(--rp-correct); }
html.rp-stage[data-stage-page="meme"] #reveal-container.mms-reveal .rr-author-name { color: var(--gold); font-weight: 700; }
html.rp-stage[data-stage-page="meme"] #reveal-container.mms-reveal .rr-voter { color: var(--light-ink); background: rgb(23 25 31 / 7%); }
html.rp-stage[data-stage-page="meme"] #reveal-container.mms-reveal .rr-lb-pos { color: var(--text-secondary); background: rgb(23 25 31 / 7%); }
html.rp-stage[data-stage-page="meme"] #reveal-container.mms-reveal .rr-lb-score { color: var(--gold); }

/* «Имаджинариум»: each step is the /tv/ one (meme-stage.css + im-stage.css, shared/client/im-stage.ts, mounted by
   main.ts at the top of the round screen, which the stage hides with the phone's labels, hand, table, waiting line and
   «Карта выбрана» overlay): the storyteller and the association on a cream cut strip on top, the cards upright under it
   across the whole width (one row when that is biggest) as cut-card buttons (the storyteller's hand to pick for the association, the others' hand to play, the
   table to vote on; a click, 1–9 or the letter). The storyteller's field and «Отправить» stay under the hand. The round
   results take the /tv/ layout (question-stage.css .qs-reveal + meme-stage.css .mms-reveal). The palette is the /tv/
   one (tv/style.css body[data-tv-game="imaginarium"]): the amber page, cream cards with ink, ink panels with white. */
html:not(.rp-stage) .game-content > .mms-root.ims { display: none; }
html.rp-stage[data-stage-page="im"] :is(.mms-root, .mms-reveal) {
    --tv-surface: #422c35; --tv-line: rgb(66 44 53 / 22%); --accent: #422c35; --accent-ink: #fff; --gold: #72b3d9;
    --text-primary: #17191f; --text-secondary: #2b1e14; --light-ink: #17191f; --light-card: #fff0ca;
    --cut-shadow: 5px 6px 0 rgb(66 44 53 / 30%);
}
html.rp-stage[data-stage-page="im"] :is(#association-screen, #choosing-screen, #voting-screen) .game-content {
    display: flex; flex-direction: column; justify-content: safe center; gap: 16px; max-width: 1240px; margin: 0 auto; width: 100%;
    min-height: calc(720px - var(--rp-gh-space, 104px)); padding-top: 0; padding-bottom: 16px;
}
html.rp-stage[data-stage-page="im"] .game-content > :is(.game-header, .association-card, .cards-grid, .table-grid, .submitted-overlay, #waiting-view, #storyteller-notice) { display: none !important; }
html.rp-stage[data-stage-page="im"] #storyteller-view > :is(.storyteller-label, .subtitle, .cards-grid) { display: none !important; }
html.rp-stage[data-stage-page="im"] .game-content > .mms-root { flex: none; width: 100%; }
html.rp-stage[data-stage-page="im"] .mms-root.is-voting .tv-meme-table { flex: none; height: 440px; }
html.rp-stage[data-stage-page="im"] .mms-root:not(.is-voting) .tv-meme-hint { font-size: 25px; }
/* The storyteller's hand leaves room for the association field under it. */
html.rp-stage[data-stage-page="im"] #association-screen .mms-root.is-voting .tv-meme-table { height: 370px; }
html.rp-stage[data-stage-page="im"] #storyteller-view .association-input-area { display: flex; gap: 14px; max-width: 900px; margin: 0 auto; }
html.rp-stage[data-stage-page="im"] #storyteller-view .association-input-area .input { flex: 1; min-height: 56px; font-size: 20px; border-radius: var(--cut-2); }
html.rp-stage[data-stage-page="im"] #storyteller-view .association-input-area .btn-play { flex: none; width: auto; min-width: 200px; min-height: 56px; font-size: 19px; margin: 0; }
/* Round results: the /tv/ layout in the /tv/ view's box under the top bar; the cream cards and the ink rows as on /tv/. */
html.rp-stage[data-stage-page="im"] #reveal-container.mms-reveal { overflow: visible; }
html.rp-stage[data-stage-page="im"] #reveal-container.mms-reveal .rr-container {
    inset: 92px 40px 0;
    --rr-ink: var(--light-ink); --rr-muted: #5a4636;
    --rr-surface: var(--light-card); --rr-border: transparent;
    --rr-wrong-surface: var(--light-card); --rr-correct-surface: var(--light-card);
}
html.rp-stage[data-stage-page="im"] #reveal-container.mms-reveal .rr-context { position: relative; padding: 24px 28px 56px; background: var(--light-card); border-radius: var(--cut-2); rotate: -1deg; box-shadow: var(--cut-shadow); }
html.rp-stage[data-stage-page="im"] #reveal-container.mms-reveal .rr-context-text { color: var(--light-ink); font-weight: 700; }
html.rp-stage[data-stage-page="im"] #reveal-container.mms-reveal .rr-context-subtext { color: var(--im-cream); background: var(--im-ink); }
html.rp-stage[data-stage-page="im"] #reveal-container.mms-reveal .rr-option-image-card { background: var(--light-card); border-color: transparent; }
html.rp-stage[data-stage-page="im"] #reveal-container.mms-reveal .rr-option-image-card.rr-type-correct { border-color: var(--rp-correct); }
html.rp-stage[data-stage-page="im"] #reveal-container.mms-reveal .rr-option-image-owner { color: var(--light-ink); }
html.rp-stage[data-stage-page="im"] #reveal-container.mms-reveal .rr-option-image-voters { color: #5a4636; }
html.rp-stage[data-stage-page="im"] #reveal-container.mms-reveal .rr-voter { color: var(--light-ink); background: rgb(66 44 53 / 10%); }
html.rp-stage[data-stage-page="im"] #reveal-container.mms-reveal .rr-lb-score { color: var(--gold); }
/* «Joking Hazard»: each step is the /tv/ one (jh-stage.css, mounted by main.ts before the round screen's copy, which the
   stage hides with the phone's top bar, strip, comics list and «Голос принят» card): the round's comic as three cut
   cards with the phone's kicker, title and hint; the hand stays the phone's (a row of seven cut cards under it) with
   its buttons («До стартовой» / «После стартовой», «Готово», the exchange, the line for a blank panel); while voting
   the table as cut-card buttons (a click, 1–9 or the letter), the pick with the green edge. The round results take
   the /tv/ layout (question-stage.css .qs-reveal + jh-stage.css .jhs-reveal). The palette is the /tv/ one
   (tv/style.css body[data-tv-game="jokinghazard"]): a white comic page, ink on white cards. */
html:not(.rp-stage) .shell > .jhs-root { display: none; }
html.rp-stage[data-stage-page="jh"] :is(.jhs-root, .jhs-reveal) {
    --tv-surface: #fff; --tv-line: #dcdcd4; --accent: #236b92; --accent-ink: #fff; --gold: #4f7a1e;
    --text-primary: #17191f; --text-secondary: #4a4d55; --light-ink: #17191f; --light-card: #fff; --jh-red: #e53945;
    --cut-shadow: 5px 6px 0 rgb(23 25 31 / 14%);
}
html.rp-stage[data-stage-page="jh"] :is(.game-shell, .vote-shell) {
    display: flex; flex-direction: column; align-items: center; justify-content: safe center; gap: 12px;
    max-width: 1240px; width: 100%; margin: 0 auto; min-height: calc(var(--app-height, 720px) - var(--rp-gh-space, 0px)); padding-top: 0; padding-bottom: 12px;
}
html.rp-stage[data-stage-page="jh"] :is(.game-shell, .vote-shell) > :is(.game-topbar, .phase-copy, .comic-stage, .comics-list, #vote-waiting) { display: none !important; }
html.rp-stage[data-stage-page="jh"] :is(.game-shell, .vote-shell) > .jhs-root { flex: none; width: 100%; gap: 10px; }
/* The round: the strip smaller while the hand is on screen, bigger while this player waits. */
html.rp-stage[data-stage-page="jh"] .game-shell .jhs-title { font-size: 28px; }
html.rp-stage[data-stage-page="jh"] .game-shell .jhs-hint { font-size: 18px; }
html.rp-stage[data-stage-page="jh"] .game-shell .jhs-strip { height: 180px; gap: 16px; }
html.rp-stage[data-stage-page="jh"] .game-shell:has(#hand:empty) .jhs-strip { height: 320px; }
html.rp-stage[data-stage-page="jh"] .game-shell > :is(.order-controls, .selection-bar, .waiting-card, .caption-editor) { width: 100%; max-width: 560px; margin: 0; }
html.rp-stage[data-stage-page="jh"] .order-controls .btn-join { min-height: 48px; font-size: 16px; }
html.rp-stage[data-stage-page="jh"] .selection-bar { font-size: 16px; border-radius: var(--cut-2); }
html.rp-stage[data-stage-page="jh"] .selection-bar .btn-play { min-height: 46px; font-size: 16px; }
html.rp-stage[data-stage-page="jh"] .waiting-card { border-radius: var(--cut-2); }
html.rp-stage[data-stage-page="jh"] .hand {
    display: flex; justify-content: center; gap: 14px; width: 100%; margin: 0; padding: 4px 6px 8px; overflow: visible; scroll-snap-type: none;
}
html.rp-stage[data-stage-page="jh"] .hand:empty { display: none; }
html.rp-stage[data-stage-page="jh"] .hand-card { flex: 0 0 118px; cursor: pointer; }
html.rp-stage[data-stage-page="jh"] .hand-card:hover:not(:disabled):not(.selected) .panel { translate: 0 -4px; box-shadow: 6px 8px 0 color-mix(in srgb, #236b92 30%, transparent); }
/* Voting: the table's line reads as the step's title. */
html.rp-stage[data-stage-page="jh"] .vote-shell .jhs-hint { font-size: 22px; color: var(--text-primary); }
/* Round results: the /tv/ layout in the /tv/ view's box under the top bar, light tokens as on /tv/. */
html.rp-stage[data-stage-page="jh"] #reveal-container.qs-reveal { overflow: visible; }
html.rp-stage[data-stage-page="jh"] #reveal-container.qs-reveal .rr-container {
    inset: 92px 40px 0;
    --rr-ink: var(--light-ink); --rr-muted: var(--text-secondary);
    --rr-surface: var(--light-card); --rr-border: var(--tv-line);
    --rr-leading-surface: var(--light-card); --rr-leading-border: var(--gold);
    --rr-wrong-surface: var(--light-card); --rr-correct-surface: var(--light-card);
}
html.rp-stage[data-stage-page="jh"] #reveal-container.qs-reveal .rr-voter { color: var(--light-ink); background: rgb(23 25 31 / 7%); }
html.rp-stage[data-stage-page="jh"] #reveal-container.qs-reveal .rr-lb-pos { color: var(--text-secondary); background: rgb(23 25 31 / 7%); }
html.rp-stage[data-stage-page="jh"] #reveal-container.qs-reveal .rr-lb-score { color: var(--gold); }
/* Геоугадайка: the round keeps the phone's Street View sphere over the whole stage (one panorama per page: billed per
   load), the guess map a bigger corner preview that opens wide on a click (Enter or Space confirms the pin). The round
   results are the /tv/ ones (geo-stage.css, mounted by main.ts in the round results screen, which the stage shows
   instead of the phone's map, note and reveal): the big map with the flag and the avatar pins, the place, the rows,
   then the board. The palette is the page's (geo-theme.css --geo-*). */
html.rp-stage[data-stage-page="geo"] #game-screen.geo-sphere .map-guess-container { right: 28px; bottom: 34px; width: 340px; }
html.rp-stage[data-stage-page="geo"] #game-screen.geo-sphere .guess-map { height: 220px; }
html.rp-stage[data-stage-page="geo"] #game-screen.geo-sphere .map-guess-container.is-open { width: 720px; }
html.rp-stage[data-stage-page="geo"] #game-screen.geo-sphere .map-guess-container.is-open .guess-map { height: 470px; }
html.rp-stage[data-stage-page="geo"] #game-screen.geo-sphere .map-guess-container:not(.is-open) .btn-confirm-guess { padding: 12px; font-size: 18px; }
html.rp-stage[data-stage-page="geo"] .btn-confirm-guess { min-height: 56px; font-size: 20px; border-radius: 28px; }
html.rp-stage[data-stage-page="geo"] #game-screen:not(.geo-sphere) .game-content { max-width: 1100px; margin: 0 auto; width: 100%; }
html.rp-stage[data-stage-page="geo"] #game-screen:not(.geo-sphere) .guess-map { height: 360px; }
html.rp-stage[data-stage-page="geo"] .geo-role { max-width: 760px; margin-left: auto; margin-right: auto; font-size: 18px; }
html.rp-stage[data-stage-page="geo"] #round-results-screen > :is(.results-map-container, .geo-round-note, #reveal-container) { display: none !important; }
html.rp-stage[data-stage-page="geo"] #round-results-screen.active { display: flex; flex-direction: column; overflow: hidden; }
html.rp-stage[data-stage-page="geo"] #round-results-screen > .gss-root {
    --geo-ink: #17191f; --tv-line: var(--geo-line); --text-secondary: #c9c4f0;
    position: absolute; inset: 92px 40px 24px; padding: 4px 6px 0;
}
html.rp-stage[data-stage-page="geo"] .gss-board .rr-container.rr-dashboard .rr-screen1 { padding: var(--cut-room, 14px); }
html.rp-stage[data-stage-page="geo"] .gss-board .rr-context-text { font-size: 22px; }
html.rp-stage[data-stage-page="geo"] .gss-board .rr-option { padding: 12px 16px; }
/* The vote and the final screen: the phone's, a wider column in the middle. */
html.rp-stage[data-stage-page="geo"] .vote-content { max-width: 900px; margin: 0 auto; width: 100%; }
html.rp-stage[data-stage-page="geo"] .geo-candidates { max-width: 860px; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }

/* «Рисовач»: drawing is the phone's canvas laid out on the stage: the word on the white cut card on the left (tv
   .tv-draw-card) with «Отправить рисунок» under it, the sheet with its tools on the right. Then each step is the /tv/
   one (draw-stage.css, mounted by main.ts after the phone's drawing, which the stage hides with the phone's title and
   buttons): the drawing big on its sheet with the artist and the title field under it, then the drawing on the left
   and the titles on the right as cut-card buttons (a click or the letter). The round results take the /tv/ layout
   (question-stage.css .qs-reveal + draw-stage.css). The palette is the /tv/ one (tv/style.css
   body[data-tv-game="drawful"]): a light page, ink on white cards, pink for actions. */
html:not(.rp-stage) .screen-content > .dws-root { display: none; }
html.rp-stage[data-stage-page="draw"] :is(.dws-root, .qs-reveal) {
    --tv-surface: #fff; --tv-line: #e4e1dd; --accent: #c61d76; --accent-ink: #fff; --gold: #c61d76;
    --text-primary: #17191f; --text-secondary: #5a5650; --light-ink: #17191f; --light-card: #fff;
}
html.rp-stage[data-stage-page="draw"] .stage-keys-hint { --text-secondary: #5a5650; --text-primary: #17191f; }
/* Drawing. */
html.rp-stage[data-stage-page="draw"] #drawing-screen.active {
    display: grid; grid-template-columns: 380px 700px; grid-template-rows: 1fr auto 1fr; column-gap: 56px;
    justify-content: center; align-content: center; padding: 96px 40px 24px;
}
html.rp-stage[data-stage-page="draw"] #drawing-screen > .game-header { display: none; }
html.rp-stage[data-stage-page="draw"] #drawing-screen .drawing-prompt {
    grid-column: 1; grid-row: 2; align-self: center; margin: 0; padding: 40px 32px 36px;
    border-radius: 30px 18px 34px 20px / 20px 32px 18px 30px; rotate: -1.4deg;
    box-shadow: 9px 11px 0 color-mix(in srgb, var(--accent-pink) 28%, transparent);
}
html.rp-stage[data-stage-page="draw"] #drawing-screen .drawing-prompt:has(> .df-card-vote:not([hidden])) { padding-bottom: 64px; }
html.rp-stage[data-stage-page="draw"] .drawing-prompt-label { font-size: 22px; font-weight: 600; margin-bottom: 10px; }
html.rp-stage[data-stage-page="draw"] .drawing-prompt-word { font-size: 40px; line-height: 1.15; text-wrap: balance; overflow-wrap: anywhere; }
html.rp-stage[data-stage-page="draw"] #drawing-screen .canvas-area { display: contents; }
html.rp-stage[data-stage-page="draw"] #drawing-screen .canvas-toolbar { grid-column: 2; grid-row: 1; align-self: end; gap: 10px; padding: 0 0 14px; }
html.rp-stage[data-stage-page="draw"] #drawing-screen .canvas-container { grid-column: 2; grid-row: 2; flex: none; width: 700px; height: 440px; min-height: 0; }
html.rp-stage[data-stage-page="draw"] #drawing-screen .canvas-actions { grid-column: 1; grid-row: 3; align-self: start; justify-content: center; padding: 28px 0 0; }
html.rp-stage[data-stage-page="draw"] #drawing-screen .canvas-actions .btn-play { flex: none; }
html.rp-stage[data-stage-page="draw"] .color-btn { width: 34px; height: 34px; }
html.rp-stage[data-stage-page="draw"] .brush-size-btn { width: 40px; height: 40px; }
html.rp-stage[data-stage-page="draw"] .tool-btn { height: 40px; padding: 0 16px; font-size: 16px; }
html.rp-stage[data-stage-page="draw"] .submitted-text { font-size: 28px; }
html.rp-stage[data-stage-page="draw"] .submitted-hint { font-size: 19px; }
/* Presenting and voting: the /tv/ step in place of the phone's title, drawing and buttons. */
html.rp-stage[data-stage-page="draw"] :is(#presenting-screen, #voting-screen) > .screen-content {
    max-width: none; justify-content: safe center; align-items: center; min-height: 100%; padding-top: 96px; padding-bottom: 32px;
}
html.rp-stage[data-stage-page="draw"] :is(#presenting-screen, #voting-screen) > .screen-content > :is(.game-header, .title, .subtitle, .drawing-display, .vote-options, .artist-notice) { display: none !important; }
html.rp-stage[data-stage-page="draw"] .screen-content > .dws-root { flex: none; width: 100%; max-width: 1180px; margin: 0 auto; }
html.rp-stage[data-stage-page="draw"] .dws-root.is-presenting .tv-draw-slot:not(:empty) { display: flex; flex-direction: column; align-items: center; gap: 14px; }
html.rp-stage[data-stage-page="draw"] .dws-root .fake-input-section { gap: 18px; width: 820px; max-width: 100%; margin: 0; }
html.rp-stage[data-stage-page="draw"] .dws-root .fake-input-section .input { flex: 1 1 0; min-width: 0; height: 64px; padding: 0 24px; font-size: 24px; border-radius: 16px; border: 2px solid var(--accent-pink); }
html.rp-stage[data-stage-page="draw"] .dws-root .fake-input-section .btn-join { flex: none; width: auto; min-width: 200px; height: 64px; margin: 0; font-size: 19px; border-radius: 32px; color: #fff; background: var(--accent-pink); border-color: transparent; }
html.rp-stage[data-stage-page="draw"] .dws-root .fake-input-section .btn-join:disabled { color: var(--text-secondary); background: var(--df-line); }
html.rp-stage[data-stage-page="draw"] .dws-root #presenting-status:not(:empty) { margin: 0; font-size: 20px; padding: 8px 20px; }
html.rp-stage[data-stage-page="draw"] #voting-screen .stage-keys-hint { margin-top: 18px; }
html.rp-stage[data-stage-page="draw"] #voting-screen:has(.dws-root:is(.is-locked, :not(.is-votable))) .stage-keys-hint { visibility: hidden; }
/* Round results: the /tv/ layout in the /tv/ view's box under the top bar. */
html.rp-stage[data-stage-page="draw"] #reveal-container.qs-reveal { overflow: visible; }
html.rp-stage[data-stage-page="draw"] #reveal-container.qs-reveal .rr-container { inset: 92px 40px 0; }
html.rp-stage[data-stage-page="draw"] #reveal-container.qs-reveal .rr-context.df-reveal-prompt {
    padding: 18px 18px 60px; border-radius: var(--cut-2); rotate: -1deg; box-shadow: 8px 10px 0 rgb(23 25 31 / 10%);
}

/* Round results (reveal-results.js): a wider column. */
/* .rr-container is absolute over the whole screen, so the column is set on its screens. */
html.rp-stage[data-stage-page="hundred"] #reveal-container .rr-container { zoom: 1.35; }
html.rp-stage[data-stage-page="hundred"] #reveal-container :is(.rr-screen1, .rr-screen2) { padding-left: max(20px, calc(50% - 330px)); padding-right: max(20px, calc(50% - 330px)); padding-top: 64px; }
/* Final results: the shared game-end board and buttons, bigger, in the middle. */
html.rp-stage:is([data-stage-page="quiz"], [data-stage-page="melody"], [data-stage-page="hundred"], [data-stage-page="truth"], [data-stage-page="quiplash"], [data-stage-page="fibbage"], [data-stage-page="wyr"], [data-stage-page="knowme"], [data-stage-page="geo"], [data-stage-page="draw"]) .results-content { zoom: 1.3; width: 520px; max-width: none; margin: 0 auto; padding-left: 0; padding-right: 0; }

/* The keys hint under the answers (stage only; main.ts takes A–D, 1–4 and the Russian ФИСВ). */
.stage-keys-hint { display: none; align-items: center; justify-content: center; gap: 8px; color: var(--text-secondary, #cbc4e6); font-size: 18px; }
.stage-keys-hint kbd {
    display: inline-grid; place-items: center; min-width: 34px; height: 34px; padding: 0 6px; font: 800 16px/1 var(--st-display, system-ui);
    color: var(--text-primary, #fff); border: 1.5px solid currentColor; border-radius: 9px; box-shadow: 0 3px 0 rgb(0 0 0 / 30%);
}

/* ════════════════════ Бункер (client/mini-games/bunker/) ════════════════════
   Owner 2026-10-30 «бункер онб пк - не тот формат», «наборы не тот формат»: the onboarding and the packs in the stage
   look of the other games (the shared lists above include [data-stage-page="bunker"]); the round screens keep the
   phone's column in the middle of the stage. The page sizes its screens in 100dvh, which under the stage zoom is taller
   than the window (the buttons fell under the bottom edge): --app-height is the window in stage px. */
html.rp-stage[data-stage-page="bunker"] main,
html.rp-stage[data-stage-page="bunker"] #onboarding-screen,
html.rp-stage[data-stage-page="bunker"] #onboarding-screen .onboarding-container { min-height: var(--app-height, 100dvh); }
/* A 16:9 window has a 720px stage: the rules' 3–4 line texts need the picture at 260px and tighter gaps, or «Пропустить» /
   «Далее» fell under the bottom edge (1920×1080, 1366×768). */
html.rp-stage[data-stage-page="bunker"] #onboarding-screen .onboarding-container { padding-top: 8px; padding-bottom: 16px; box-sizing: border-box; }
html.rp-stage[data-stage-page="bunker"] #onboarding-screen .slide-icon:has(> picture > img, > img),
html.rp-stage[data-stage-page="bunker"] #onboarding-screen .slide-icon img { width: 260px; height: 260px; }
html.rp-stage[data-stage-page="bunker"] #onboarding-screen .slide-title { margin-top: 12px; }
html.rp-stage[data-stage-page="bunker"] #onboarding-screen .onboarding-dots { margin-bottom: 16px; }
html.rp-stage[data-stage-page="bunker"] #onboarding-screen .onboarding-slides { padding-top: 0; }
html.rp-stage[data-stage-page="bunker"] #onboarding-screen .onboarding-dots { margin-top: 12px; }
html.rp-stage[data-stage-page="bunker"] .screen .bottom-section.packs-compact-actions > .btn-additional-settings { flex-grow: 0; padding-inline: 12px; font-size: 14px; }
html.rp-stage[data-stage-page="bunker"] .screen:not(#onboarding-screen):not(#packs-screen) { width: 100%; max-width: 560px; margin-left: auto; margin-right: auto; }
html.rp-stage[data-stage-page="bunker"] .screen:not(#onboarding-screen):not(#packs-screen) :is(.btn-play, .btn-additional-settings) { width: 100%; white-space: normal; }

/* «Полоска очков» on the stage (see the strip rules above): the layouts with fixed heights give the strip its band by shrinking their tallest block by ~70 px. */
html.rp-stage[data-stage-page="im"] .mms-root.is-voting .tv-meme-table { height: 370px; }
html.rp-stage[data-stage-page="im"] #association-screen .mms-root.is-voting .tv-meme-table { height: 300px; }
html.rp-stage[data-stage-page="meme"] #choosing-screen .mms-root .tv-meme-table:not(.is-captions) { height: 340px; }
html.rp-stage[data-stage-page="meme"] #choosing-screen .mms-root .tv-meme-table.is-captions { max-height: 340px; grid-auto-rows: minmax(84px, auto); }
/* «Обновить руку» goes to the free corner under the prompt (left column), above the strip, so the hand keeps its size. */
html.rp-stage[data-stage-page="meme"] #choosing-screen .game-content:has(> .rp-score-strip) > .btn-refresh-hand { position: fixed; left: 96px; bottom: 112px; z-index: 6; }
html.rp-stage[data-stage-page="meme"] .mms-root.is-voting .tv-meme-table:not(.is-captions) { height: 420px; }
html.rp-stage[data-stage-page="meme"] .mms-root .tv-meme-table.is-captions { max-height: 440px; }
html.rp-stage[data-stage-page="jh"] .game-shell .jhs-strip { height: 150px; }
html.rp-stage[data-stage-page="jh"] .game-shell:has(#hand:empty) .jhs-strip { height: 220px; }
html.rp-stage[data-stage-page="jh"] .game-shell:has(> .rp-score-strip) .waiting-card { padding-top: 12px; padding-bottom: 12px; }
html.rp-stage[data-stage-page="jh"] .hand-card { flex-basis: 100px; }
html.rp-stage[data-stage-page="draw"] .dws-root.is-presenting .tv-draw-frame > img { height: 270px; }
