@font-face { font-family: "Radiance"; src: url("assets/fonts/radiance_regular.otf") format("opentype"); font-weight: 400; font-display: swap; }
@font-face { font-family: "RadianceM"; src: url("assets/fonts/radiancem_regular.otf") format("opentype"); font-weight: 400; font-display: swap; }
@font-face { font-family: "RadianceM"; src: url("assets/fonts/radiancem_bold.otf") format("opentype"); font-weight: 700; font-display: swap; }
@font-face { font-family: "Reaver"; src: url("assets/fonts/reaver-regular.otf") format("opentype"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Reaver"; src: url("assets/fonts/reaver-semibold.otf") format("opentype"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Reaver"; src: url("assets/fonts/reaver-bold.otf") format("opentype"); font-weight: 700; font-display: swap; }

:root {
	color-scheme: dark;
	font-family: Radiance, "Segoe UI", sans-serif;
	background: #07132a;
	/* Заполняются из tg.js только внутри Telegram Mini App; вне него остаются
	   нулевыми и ни на что не влияют. */
	--tg-content-top: 0px;
	--tg-safe-bottom: 0px;
	--tg-viewport: 100dvh;
}
* { box-sizing: border-box; }
body { margin: 0; min-width: 320px; overflow-x: hidden; background: radial-gradient(circle at 50% 10%, #253e72, #07132a 65%); }
button, kbd { font: inherit; }
.page { min-height: 100vh; padding: 22px; display: grid; place-items: center; gap: 12px; }
.blimp-jump { width: min(96vw, 1100px); }
.game-shell {
	position: relative; width: min(100%, 1040px); min-height: 710px; aspect-ratio: 1.45;
	overflow: hidden; border: 2px solid #c9974d; border-radius: 12px;
	box-shadow: 0 25px 90px #0009, inset 0 0 40px #1d0e07;
	background: #122b55;
}
.hint { margin: 0; color: #cbd6ea; text-align: center; font-size: 14px; }
/* На тач-устройствах показываем подсказку про пальцы вместо клавиатурной (см. TouchInput в shim.js). */
.hint-touch { display: none; }
.TouchInput .hint-keyboard { display: none; }
.TouchInput .hint-touch { display: block; }
kbd { display: inline-block; min-width: 22px; padding: 2px 6px; border: 1px solid #a2b2c9; border-bottom-width: 3px; border-radius: 4px; color: #eff6ff; background: #1b2c4b; font-weight: 700; text-align: center; }

/* Игровое поле и камера */
.game-screen { position: absolute; inset: 0; display: none; overflow: hidden; background: transparent; }
.GameRunning .game-screen, .IsPaused .game-screen, .GameFinished .game-screen,
.GameRunning .progress-container, .IsPaused .progress-container, .GameFinished .progress-container { display: block; }
/* Скролл фона двигаем через transform на внутреннем .backdrop-image, а не через
   background-position на самом .backdrop: смена background-position каждый кадр
   заставляет браузер перерисовывать (paint) весь слой заново, а смена transform
   на GPU-слое — это чистый композитинг без перерисовки. На айфонах с их более
   тонким бюджетом на растеризацию это и есть основной источник подтормаживаний
   при подъёме персонажа: 3-4 полноэкранных слоя перерисовывались 60 раз/сек. */
.backdrop { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.backdrop-image { position: absolute; inset: 0; will-change: transform; }
.backdrop-normal .backdrop-image { background: linear-gradient(#2b75b5 0%, #80c4e8 45%, #d2ebdf 100%); background-size: 100% 900px; }
.backdrop-repeating { opacity: .28; }
.backdrop-repeating .backdrop-image { background-image: radial-gradient(ellipse at 15% 22%, #fff9 0 3%, transparent 4%), radial-gradient(ellipse at 80% 54%, #fff9 0 2%, transparent 3%); background-size: 350px 260px; }
.backdrop-left, .backdrop-right { width: 25%; opacity: .4; }
.backdrop-left .backdrop-image, .backdrop-right .backdrop-image { background: linear-gradient(90deg, #16446eaa, transparent); }
.backdrop-right { right: 0; left: auto; transform: scaleX(-1); }
.game-container { position: absolute; inset: 0; overflow: hidden; }
.game-container > div:not(.rocket-effect) { position: absolute; pointer-events: none; }
/* Сларк рисуется поверх мира. Порядок отрисовки в вебе задаёт порядок в DOM, а
   платформы, препятствия и враги создаются уже после игрока — без z-index
   моделька проскакивала за ними. Селектор со `.game-container` нужен, чтобы не
   задеть того же Сларка в главном меню (он лежит в своём контейнере). */
.game-container > .Player { z-index: 3; }
.rocket-effect { position: absolute; width: 120px; height: 110px; display: none; pointer-events: none; background: radial-gradient(ellipse at 50% 100%, #fff 0 7%, #ffbc45 10%, #f75d23 34%, transparent 68%); filter: blur(1px); }
.in-game-score { position: absolute; z-index: 4; left: 24px; top: 18px; color: #fff4c6; font-size: 38px; font-weight: 900; text-shadow: 0 3px 0 #5c3519, 0 0 14px #ffae3d; }
.progress-container { display: none; position: absolute; z-index: 4; right: 18px; top: 40px; bottom: 40px; width: 18px; padding: 3px; border: 2px solid #f3d180; border-radius: 12px; background: #15182a99; }
.progress-bar-empty { position: relative; width: 100%; height: 100%; overflow: hidden; border-radius: 8px; background: #0a1e38; }
/* Шкала всегда полной высоты, а заполнение задаётся scaleY от низа: менять height каждый
   кадр значило бы layout на каждый кадр, тогда как transform уходит в композитинг. Градиент
   при этом выглядит как раньше — он рисуется по всей высоте и сжимается вместе со слоем. */
.progress-bar-full { position: absolute; bottom: 0; width: 100%; height: 100%; transform-origin: 50% 100%; transform: scaleY(0); will-change: transform; background: linear-gradient(#fff194, #f29b33 50%, #c94721); box-shadow: 0 0 10px #ffd55e; }

/* Объекты, которые динамически создаёт game.js */
.Platform { border-radius: 4px; overflow: visible; filter: drop-shadow(0 3px 2px #0007); }
.PlatformColor { position: absolute; inset: 4px 0 0; border-radius: 5px; background: linear-gradient(#f8e47c, #be722c 45%, #693718 48%); }
.PlatformBorder { position: absolute; inset: 0; border: 3px solid #4b2818; border-radius: 5px; }
.PlatformBorder2 { position: absolute; left: 6px; right: 6px; top: 3px; height: 3px; background: #fff0a0; }
.Platform.Moving .PlatformColor, .Platform.Vertical .PlatformColor { background: linear-gradient(#75e7ff, #2777bc 50%, #193c75 54%); }
.Platform.Vanishing .PlatformColor { background: linear-gradient(#df9bff, #794098); }
.Platform.Breakable .PlatformColor { background: repeating-linear-gradient(120deg, #bd803d 0 14px, #7b3f22 15px 18px); }
.Platform.WallJump .PlatformColor { background: repeating-linear-gradient(#d8e6f2 0 16px, #5e7e9b 17px 21px); }
.Platform.Balloon { border-radius: 50%; background: radial-gradient(circle at 34% 28%, #fff8 0 8%, transparent 9%), linear-gradient(130deg, #ee647a, #8b2e99); box-shadow: inset -12px -10px 20px #3e154f88, 0 4px 4px #0006; }
.Platform.Balloon > * { display: none; }
.Platform.Finish { background: linear-gradient(#ffe47d, #bf6f25); border: 3px solid #5d351d; border-radius: 8px; }
.Platform.Tutorial { background: linear-gradient(#77c8e8, #24548f); border: 2px solid #e7f9ff; }
.Platform.Vanish { animation: vanish .38s forwards; }
/* Bounce не должен перебивать Vanish: оба задают `animation`, и правило Bounce
   шло ниже — тучка отыгрывала подпрыгивание и оставалась на месте. */
.Platform.Bounce:not(.Vanish) { animation: platform-bounce .16s ease-out; }

.Player { overflow: visible; }
.PlayerImage { position: absolute; inset: 0; border-radius: 46% 44% 42% 48%; background: radial-gradient(circle at 35% 25%, #c7ffff 0 7%, transparent 8%), linear-gradient(145deg, #4fc6d2 0 44%, #174d75 46% 75%, #7b2967 77%); box-shadow: inset -10px -10px 14px #061b38aa, 0 4px 6px #0007; }
.PlayerImage::after { content: ""; position: absolute; right: 13%; top: 38%; width: 32%; height: 10%; border-radius: 50%; background: #ecf7ff; box-shadow: 0 0 0 3px #143358; }
.PlayerRocket, .PlayerOof, .PlayerOof2, .PlayerFalling { display: none; }
.Player.Falling .PlayerJumping, .Player.Oof .PlayerJumping, .Player.Oof2 .PlayerJumping, .Player.Rocketing .PlayerJumping { display: none; }
.Player.Falling .PlayerFalling, .Player.Oof .PlayerOof, .Player.Oof2 .PlayerOof2, .Player.Rocketing .PlayerRocket { display: block; }
.PlayerFalling { filter: hue-rotate(25deg) brightness(.85); }
.PlayerOof, .PlayerOof2 { filter: sepia(.8) saturate(1.8) hue-rotate(315deg); transform: rotate(70deg); }
.PlayerRocket { background: radial-gradient(ellipse at 50% 110%, #fff 0 7%, #ffcf3f 8% 21%, #e44c25 23% 38%, transparent 62%), linear-gradient(145deg, #54d5df 0 48%, #193d74 50%); }
.Player.FacingLeft { transform: scaleX(-1); }
.Player.BigJump { animation: player-big-jump .25s ease-out; }

.Projectile { border-radius: 50% 50% 15% 15%; background: linear-gradient(90deg, #8b5236, #f2e2b1 45%, #593126 48%); box-shadow: 0 0 3px #fff, 0 1px 2px #000; }
.Enemy { overflow: hidden; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff9 0 6%, transparent 7%), linear-gradient(145deg, #ee5a55, #7c173c 60%, #351735); border: 3px solid #3e1832; }
.Enemy.FloatEnemy { background: radial-gradient(circle at 70% 27%, #ffef8a 0 7%, transparent 8%), linear-gradient(145deg, #75d0e4, #2c4389 65%, #291d54); }
.EnemyFrame2, .EnemyFrame3 { display: none; }.Enemy.Frame2 .EnemyFrame1, .Enemy.Frame3 .EnemyFrame1 { display: none; }.Enemy.Frame2 .EnemyFrame2, .Enemy.Frame3 .EnemyFrame3 { display: block; }
.PlatformAttachment { overflow: visible; }
.PlatformAttachment.Spring { border: 4px solid #d2e8ef; border-radius: 2px; background: repeating-linear-gradient(135deg, transparent 0 4px, #496a84 5px 8px); }
.PlatformAttachment.Trampoline { border: 4px solid #f0d36e; border-radius: 50% 50% 18% 18%; background: repeating-linear-gradient(90deg, #f6b057 0 6px, #8d3732 7px 12px); }
.PlatformAttachment.Spikes { background: conic-gradient(from 45deg at 50% 100%, #d9e5eb 0 25%, transparent 0 50%, #d9e5eb 0 75%, transparent 0); background-size: 50% 100%; }
.PlatformAttachment.Rocket { border-radius: 50% 50% 18% 18%; background: linear-gradient(#e4e5ec 0 35%, #c7462e 37% 75%, #f4b83f 77%); }
.PlatformAttachment.Bounce { animation: platform-bounce .2s ease-out; }
.Blimp { border-radius: 50% 50% 38% 38%; background: radial-gradient(ellipse at 35% 30%, #fff9, transparent 20%), linear-gradient(#e1c68a 0 20%, #987140 21% 42%, #563222 43%); border: 4px solid #512d20; box-shadow: inset -24px -12px 30px #23120b99, 0 6px 9px #0008; }
.Blimp::after { content: ""; position: absolute; left: 30%; right: 30%; bottom: -9%; height: 18%; border: 3px solid #542e20; background: #85502d; }
.SmeltingCar { overflow: hidden; border-radius: 45% 45% 15% 15%; background: radial-gradient(circle at 50% 34%, #ffe368 0 5%, #f46924 8%, #681a1c 35%, #2b1b25 70%); border: 5px solid #34202a; }
.SmokeCloud { border-radius: 50%; background: radial-gradient(circle, #dfedf0cc, #8996a1aa 42%, transparent 70%); }
.FallExplosion { border-radius: 50%; background: radial-gradient(circle, #fff 0 9%, #ffdc55 12% 27%, #e45224 38%, transparent 65%); }
.WhooshLine { background: linear-gradient(transparent, #ffffffc4, transparent); }

/* Меню */
.main-menu-background { position: absolute; inset: 0; background: radial-gradient(ellipse at 80% 15%, #ffdf78bb, transparent 34%), linear-gradient(115deg, #2a1c25, #5c2a28 49%, #1c2544); }
.menu { position: absolute; z-index: 5; inset: 8%; border: 2px solid #d4a253; border-radius: 10px; overflow: hidden; color: #f9edcd; background: linear-gradient(135deg, #182341ed, #56312deb); box-shadow: 0 10px 45px #0009; }
.menu::before { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .2; background: repeating-linear-gradient(135deg, transparent 0 18px, #f8d78f 19px 20px); }
.menu-body, .menu-actions { position: relative; z-index: 1; }
.GameRunning .main-menu-container, .IsPaused .main-menu-container, .GameFinished .main-menu-container,
.GameRunning .main-menu-background, .IsPaused .main-menu-background, .GameFinished .main-menu-background,
.GameRunning .main-menu-slark-container, .IsPaused .main-menu-slark-container, .GameFinished .main-menu-slark-container { display: none; }
.menu-body { padding: clamp(24px, 4vw, 50px); }
.menu-header { text-align: center; }
.menu-header h1 { margin: 0; color: #ffe298; font-size: clamp(28px, 4vw, 52px); text-shadow: 0 3px #5c3218; }
.menu-header p { margin: 7px 0 26px; color: #e6cdb1; font-size: clamp(15px, 2vw, 20px); }
.menu-columns { display: flex; justify-content: center; }
.menu section { margin: 0 0 22px; }.menu h2 { margin: 0 0 11px; color: #f0bd6d; font-size: 18px; text-transform: uppercase; letter-spacing: .07em; }.menu h3 { margin: 10px 0 2px; font-size: 16px; color: #ffe5ad; }.menu p { margin: 0; color: #e5d6c2; font-size: 14px; line-height: 1.35; }.scores strong { float: right; color: #ffe18b; }
.menu-actions { display: flex; justify-content: center; flex-wrap: wrap; gap: 14px; padding: 0 22px 28px; }
.game-button {
	position: relative;
	isolation: isolate;
	cursor: pointer;
	min-width: 150px;
	height: 50px;
	padding: 12px 40px 16px;
	border: 0;
	border-radius: 8px;
	overflow: visible;
	color: #f0c988;
	background:
		radial-gradient(ellipse at 50% 0%, #ffffffb8 0%, #ffffff40 48%, #ffffff05 100%),
		url("assets/images/panorama/images/events/dark_carnival/textures/wood_png.png") center / 100px 100px,
		linear-gradient(#272a4f, #101123);
	background-blend-mode: screen, multiply, normal;
	box-shadow: 0 6px 32px -4px #000a;
	font-weight: 900;
	text-transform: uppercase;
	letter-spacing: .06em;
	text-shadow: 0 2px 8px #000d;
	filter: saturate(1.3) contrast(1.02);
	transition: filter .1s, transform .05s, color .1s, text-shadow .1s;
}
.game-button::before {
	content: "";
	position: absolute;
	z-index: 1;
	inset: -10px -18px;
	pointer-events: none;
	/* border-image, а не background/100% 100%: у широкой кнопки «Поделиться
	   рекордом» (grid-column: 1/-1) соотношение сторон сильно отличается от
	   двухколоночных кнопок, и растяжение по обеим осям расплющивало заклёпки
	   по углам в эллипсы. border-image со слайсами только по горизонтали
	   держит угловые заклёпки нерастянутыми и тянет лишь тонкую полосу между
	   ними, независимо от ширины кнопки. */
	border: 0 solid transparent;
	border-width: 0 40px;
	border-image: url("assets/images/panorama/images/events/dark_carnival/buttons/button_border_png.png") 0 58 fill / 0 40px stretch;
	transition: filter .05s;
}
.game-button:hover {
	color: #fff;
	text-shadow: 0 0 12px #ffd89e33, 0 2px 8px #000d;
	filter: brightness(1.35) saturate(1.3) contrast(1.02);
}
.game-button:hover::before { filter: brightness(1.15); }
.game-button:active {
	transform: scale(.96);
	filter: brightness(.55) saturate(1.3) contrast(1.02);
}
.text-button { cursor: pointer; border: 0; background: none; color: #ffe7ad; text-decoration: underline; padding: 8px 14px; font-weight: 700; }
.main-menu-slark-container { position: absolute; z-index: 4; right: 3%; bottom: 5%; width: 18%; height: 42%; pointer-events: none; }.main-menu-platform { position: absolute; bottom: 0; width: 100%; height: 7%; border-radius: 8px; background: linear-gradient(#f0d276, #704122); }.main-menu-slark { position: absolute; left: 20%; bottom: 7%; width: 60%; aspect-ratio: 1; }

.overlay-panel, .post-game-menu-container { display: none; }
.IsPaused .paused-menu-container { position: absolute; z-index: 12; top: 50%; left: 50%; display: grid; gap: 20px; place-items: center; min-width: 300px; padding: 35px; border: 2px solid #dba553; border-radius: 10px; transform: translate(-50%, -50%); background: #19223df3; box-shadow: 0 20px 60px #000b; }.paused-menu-container h1 { margin: 0; color: #ffe198; }
/* Колонка: тело результата (со скроллом, если топ игроков не влез) + кнопки. */
.GameFinished .post-game-menu-container { display: flex; }.post-game-menu-container { inset: 16% 20%; flex-direction: column; }.post-game-menu-container .menu-body { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; justify-content: safe center; }.post-game-menu-container .menu-actions { flex-shrink: 0; }.post-game-menu-container .result { text-align: center; }.post-game-menu-container .total-score { margin-top: 35px; font-size: 20px; }.post-game-menu-container .total-score strong { display: block; margin-top: 6px; color: #ffe08b; font-size: 42px; }.new-high-score { color: #ffe15e !important; font-weight: 900; font-size: 20px !important; }.HidePostGameScore #PostGameScore, .HidePostGameScore .total-score, .HidePostGameScore .new-high-score { display: none; }
.win-confetti { position: absolute; z-index: 20; inset: 0; overflow: hidden; pointer-events: none; }.confetti { position: absolute; top: -18px; width: 9px; height: 14px; background: hsl(var(--hue, 50) 90% 62%); animation: confetti-fall 2.2s ease-in forwards; }.confetti:nth-child(3n) { background: #fc6b70; }.confetti:nth-child(3n + 1) { background: #70dbff; }.confetti:nth-child(4n) { background: #a4eb64; }

@keyframes platform-bounce { 50% { transform: scaleY(.7) translateY(7px); } }
@keyframes player-big-jump { 50% { transform: scale(.8, 1.3); } }
@keyframes vanish { to { opacity: 0; transform: scaleX(.2); } }
@keyframes confetti-fall { to { transform: translate(var(--drift), 760px) rotate(680deg); opacity: .3; } }
@media (max-width: 720px) {
	.page { padding: 8px; }.game-shell { min-height: 600px; aspect-ratio: .78; }.menu { inset: 3%; }.main-menu-slark-container { display: none; }.menu-body { padding: 22px; }.menu h2 { font-size: 15px; }.menu h3, .menu p { font-size: 13px; }.post-game-menu-container { inset: 15% 5%; }
}

/* Оригинальные текстуры Blimp Jump, экспортированные локально из pak01_dir.vpk. */
/* Небо повторяется по вертикали, и раньше его прокручивал background-position; теперь слой
   едет через transform, поэтому он должен быть выше поля — иначе при сдвиге на тысячи
   пикселей уезжает за границы .backdrop целиком и небо просто исчезает. Держим слой ровно
   в два тайла (aspect-ratio задаёт высоту от ширины поля, background-size: 100% 50% делает
   тайл равным половине слоя) и сдвигаем по модулю тайла — см. backdropLayers в game.js.
   Тайл при этом остаётся той же высоты, что давал прежний background-size: cover, так что
   картинка выглядит как раньше. */
.backdrop-normal .backdrop-image { bottom: auto; height: auto; aspect-ratio: 1042 / 14000; background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/sky_backdrop_edgeson_png.webp"); background-color: transparent; background-position: 70% 0; background-size: 100% 50%; background-repeat: repeat; }
.backdrop-repeating { opacity: 1; }
.backdrop-repeating .backdrop-image { bottom: auto; height: auto; aspect-ratio: 1042 / 12000; background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/sky_backdrop_repeat_edgeson_png.webp"); background-position: 70% 0; background-size: 100% 50%; background-repeat: repeat; }
/* Боковые кромки — одна неповторяющаяся текстура на весь подъём, поэтому слой берёт её
   натуральную высоту и едет вместе с фоном без приведения по модулю. */
.backdrop-left { width: 50px; margin-left: 156px; opacity: 1; filter: drop-shadow(-10px 0 15px #0009); }
.backdrop-left .backdrop-image { bottom: auto; height: 7000px; background: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/sky_backdrop_l_png.webp") 0 0 / auto 7000px no-repeat; }
.backdrop-right { width: 50px; margin-right: 157px; opacity: 1; transform: none; filter: drop-shadow(10px 0 15px #0009); }
.backdrop-right .backdrop-image { bottom: auto; height: 7000px; background: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/sky_backdrop_r_png.webp") 0 0 / auto 7000px no-repeat; }
.in-game-score { left: 50%; top: 12px; width: 240px; height: 48px; padding: 8px 12px; transform: translateX(-50%); color: #ffcd45; font-family: RadianceM, monospace; font-weight: 700; font-size: 24px; text-align: center; background: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/score_background_png.webp") center / 100% 100% no-repeat; text-shadow: 0 2px 8px #000; }
/* От оригинальной шкалы оставляем только центральную линию заполнения: в текстурах
   progressbar_*_png широкие плашки под пушку и дирижабль, и вместе с иконками они занимали
   ~30% ширины узкого мобильного поля, перекрывая платформы. Линию рисуем в CSS, потому что
   вырезать центр из текстуры всё равно нечем — плашки в неё вшиты. */
.progress-container { width: 14px; padding: 2px; border: 1px solid #6d5a3fcc; border-radius: 999px; background: #0e0b14b3; }
.progress-bar-empty { overflow: hidden; border-radius: 999px; background: #241d2ecc; box-shadow: inset 0 0 4px #0009; }
.progress-bar-full { border-radius: 999px; background: linear-gradient(#fff194, #f29b33 55%, #c94721); box-shadow: 0 0 8px #ffbe4d99; }

.Platform { filter: none; overflow: visible; background: none; }
.PlatformColor, .PlatformBorder, .PlatformBorder2 { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; border-radius: 0; background-position: center; background-repeat: no-repeat; background-size: 100% 100%; }
.PlatformColor { inset: 8% 2.5%; width: 95%; height: 83%; background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_color_png.webp"); }
.PlatformBorder { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_border2_png.webp"); filter: drop-shadow(0 2px 1px #0009); }
.PlatformBorder2 { opacity: 0; }
.Platform.Normal .PlatformColor { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_color_png.webp"); filter: sepia(.15) saturate(1.8) hue-rotate(92deg); }
.Platform.Finish .PlatformBorder { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/end_platform_png.webp"); }
.Platform.Finish .PlatformColor { display: none; }
.Platform.Breakable .PlatformBorder { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_border_broken_png.webp"); }
.Platform.Breakable .PlatformColor { filter: sepia(.7) saturate(1.5); }
.Platform.WallJump .PlatformBorder { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_walljump2_png.webp"); }
.Platform.WallJump .PlatformColor { opacity: 0; }
.Platform.Moving .PlatformBorder, .Platform.Vertical .PlatformBorder { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_flying1_png.webp"); }
.Platform.Moving .PlatformBorder2, .Platform.Vertical .PlatformBorder2 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_flying2_png.webp"); }
.Platform.Moving.Frame2 .PlatformBorder, .Platform.Vertical.Frame2 .PlatformBorder { opacity: 0; }
.Platform.Moving.Frame2 .PlatformBorder2, .Platform.Vertical.Frame2 .PlatformBorder2 { opacity: 1; }
.Platform.Moving .PlatformColor { height: 34%; top: 2px; inset-inline: 2.5%; background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_color_png.webp"); filter: sepia(.2) saturate(2) hue-rotate(125deg); }
.Platform.Vertical .PlatformColor { height: 34%; top: 2px; inset-inline: 2.5%; background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_color_png.webp"); filter: sepia(.6) saturate(3) hue-rotate(195deg); }
.Platform.Vanishing .PlatformBorder { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_cloud1_png.webp"); }
.Platform.Vanishing .PlatformColor, .Platform.Vanishing .PlatformBorder2 { display: none; }
.Platform.Balloon { background: none; box-shadow: none; border-radius: 0; }
/* `display: block` обязателен: текстуру шарика несёт `.PlatformBorder`, а в блоке без
   ассетов дети скрыты (`.Platform.Balloon > *`) — там шарик рисуется градиентом. */
.Platform.Balloon .PlatformBorder { display: block; isolation: isolate; background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_balloon_png.webp"); filter: none; }
/* Panorama красит серую текстуру через `wash-color` (умножение на цвет), в CSS такого
   свойства нет — умножаем сами слоем цвета по маске из той же картинки. */
.Platform.Balloon .PlatformBorder::after { content: ""; position: absolute; inset: 0; background-color: var(--wash-color, rgb(128, 46, 192)); mix-blend-mode: multiply; mask: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_balloon_png.webp") center / 100% 100% no-repeat; -webkit-mask: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_balloon_png.webp") center / 100% 100% no-repeat; }
.Platform.Balloon .PlatformColor, .Platform.Balloon .PlatformBorder2 { display: none; }
.Platform.Tutorial .PlatformColor { opacity: 0; }
.Platform.Tutorial.AttackTutorial .PlatformBorder { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_tutorial_attack_png.webp"); }
.Platform.Tutorial.JumpTutorial .PlatformBorder { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_tutorial_yesjump_png.webp"); }
.Platform.Tutorial.SpikeTutorial .PlatformBorder { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_tutorial_nojump_png.webp"); }

.PlatformAttachment { background-position: center; background-size: 100% 100%; background-repeat: no-repeat; box-shadow: none; border: 0; border-radius: 0; }
.PlatformAttachment.Spring { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/spring_png.webp?v=5"); }
.PlatformAttachment.Trampoline { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/testyourstrength_png.webp?v=5"); }
.PlatformAttachment.Rocket { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/rocket_png.webp?v=5"); }
.PlatformAttachment.Spikes { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_spike_png.webp"); filter: brightness(1.5) contrast(1.2); }
.Projectile { border-radius: 0; background: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/shiv_png.webp") center / 100% 100% no-repeat; box-shadow: none; }

.Player { overflow: visible; }
.Player .PlayerImage { display: block; inset: 0; border-radius: 0; opacity: 0; background-color: transparent; background-position: center; background-repeat: no-repeat; background-size: 100% 100%; box-shadow: none; filter: none; }
.Player .PlayerImage::after { content: none; }
.Player .PlayerJumping { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/slark_jump_png.webp"); }
.Player .PlayerFalling { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/slark_stand_png.webp"); }
.Player .PlayerOof { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/slark_oof_png.webp"); transform: none; }
.Player .PlayerOof2 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/slark_oof2_png.webp"); transform: none; }
.Player .PlayerRocket { inset: auto; left: 27%; bottom: 67%; width: 53%; height: 190%; background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/rocket_back_png.webp"); }
.Player.Jumping .PlayerJumping { display: block; opacity: 1; }
.Player.Falling .PlayerFalling, .Player.Oof .PlayerOof, .Player.Oof2 .PlayerOof2, .Player.Rocketing .PlayerRocket { display: block; opacity: 1; }
.Player.FacingLeft { transform: none; }
.Player.FacingRight { transform: scaleX(-1); }

.Enemy { border: 0; border-radius: 0; overflow: visible; background: none; }
.Enemy .EnemyFrame1, .Enemy .EnemyFrame2, .Enemy .EnemyFrame3 { position: absolute; inset: 0; display: block; opacity: 0; background-position: center; background-size: 100% 100%; background-repeat: no-repeat; }
.Enemy.PlatformEnemy .EnemyFrame1 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/enemy_jester_1_png.webp"); }
.Enemy.PlatformEnemy .EnemyFrame2 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/enemy_jester_2_png.webp"); }
.Enemy.FlyEnemy .EnemyFrame1 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/enemy_bird_1_png.webp"); }
.Enemy.FlyEnemy .EnemyFrame2 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/enemy_bird_2_png.webp"); }
.Enemy.FlyEnemy .EnemyFrame3 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/enemy_bird_3_png.webp"); }
.Enemy.Frame1 .EnemyFrame1, .Enemy.Frame2 .EnemyFrame2, .Enemy.Frame3 .EnemyFrame3 { opacity: 1; }
.Enemy.FacingLeft { transform: scaleX(-1); }

.Blimp { border: 0; border-radius: 0; background: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/end_blimp_png.webp") center / 100% 100% no-repeat; box-shadow: none; }
.Blimp::after { content: none; }
.SmeltingCar { overflow: visible; border: 0; border-radius: 0; background: none; filter: brightness(1.4); }
.SmeltingCar .SmeltingCarImage, .SmokeCloud .SmokeCloudImage, .FallExplosion .FallExplosionImage { position: absolute; inset: 0; opacity: 0; background-position: center; background-size: 100% 100%; background-repeat: no-repeat; }
.SmeltingCar .SmeltingCarFrame1 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/start_smelter_png.webp"); }
.SmeltingCar .SmeltingCarFrame2 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/start_smelter_2_png.webp"); }
.SmeltingCar .SmeltingCarFrame3 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/start_smelter_3_png.webp"); }
.SmeltingCar .SmeltingCarFrame4 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/start_smelter_4_png.webp"); }
.SmeltingCar .SmeltingCarFrame5 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/start_smelter_5_png.webp"); }
.SmeltingCar.Show1 .SmeltingCarFrame1, .SmeltingCar.Show2 .SmeltingCarFrame2, .SmeltingCar.Show3 .SmeltingCarFrame3, .SmeltingCar.Show4 .SmeltingCarFrame4, .SmeltingCar.Show5 .SmeltingCarFrame5 { opacity: 1; }
.SmokeCloud { background: none; }
.SmokeCloud .SmokeCloud1 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/smoke_1_png.webp"); }
.SmokeCloud .SmokeCloud2 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/smoke_2_png.webp"); }
.SmokeCloud .SmokeCloud3 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/smoke_3_png.webp"); }
.SmokeCloud .SmokeCloud4 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/smoke_4_png.webp"); }
.SmokeCloud.Show1 .SmokeCloud1, .SmokeCloud.Show2 .SmokeCloud2, .SmokeCloud.Show3 .SmokeCloud3, .SmokeCloud.Show4 .SmokeCloud4 { opacity: 1; }
.WhooshLine { background: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/falldeath_whoosh_png.webp") center / 100% 100% no-repeat; }
.FallExplosion { background: none; }
.FallExplosion .FallExplosion1 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/falldeath_1_png.webp"); }
.FallExplosion .FallExplosion2 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/falldeath_2_png.webp"); }
.FallExplosion .FallExplosion3 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/falldeath_3_png.webp"); }
.FallExplosion .FallExplosion4 { background-image: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/falldeath_4_png.webp"); }
.FallExplosion.Show1 .FallExplosion1, .FallExplosion.Show2 .FallExplosion2, .FallExplosion.Show3 .FallExplosion3, .FallExplosion.Show4 .FallExplosion4 { opacity: 1; }

.main-menu-background { background: #111d36 url("assets/images/panorama/images/events/dark_carnival/blimp_jump/sky_backdrop_png.webp") 70% -6000px / cover no-repeat; }
.main-menu-platform { border: 0; border-radius: 0; background: url("assets/images/panorama/images/events/dark_carnival/blimp_jump/platform_border2_png.webp") center / 100% 100% no-repeat; }

/* Геометрия исходного попапа: 1000×1000 с игровым полотном шириной 600px.
   Ширину боковой колонки под шкалу прогресса резервируем здесь, до расчёта размеров поля:
   .game-shell — грид из колонки HUD и колонки игры, поэтому #GameScreen физически начинается
   после шкалы. Игровая логика берёт размеры мира у #GameContainer, так что генерация платформ,
   спавн Сларка и границы камеры автоматически считаются только внутри игровой колонки —
   объекты не могут оказаться под HUD (одного z-index для этого не хватило бы). */
#BlimpJump { --hud-column: 30px; }
/* min-width: 0 обязателен: .blimp-jump — grid-элемент внутри .page, а по умолчанию у
   grid/flex-элементов min-width:auto, который считается по content-based минимуму. Внутри
   лежит .game-shell с aspect-ratio, заданным через высоту (min(88vh,850px) на мобильных) —
   его "предпочитаемая" ширина от аспекта (высота×0.78) становится содержимым-минимумом
   родителя и раздувает .blimp-jump шире экрана на узких и высоких мобильных вьюпортах,
   вызывая горизонтальный скролл всей страницы. */
.blimp-jump { width: min(100%, 1000px); min-width: 0; }
.game-shell {
	display: grid;
	grid-template-columns: var(--hud-column) minmax(0, 1fr);
	width: 100%;
	height: min(96vh, 1000px);
	min-height: 0;
	aspect-ratio: 1;
	border: 3px solid #6d5a3f;
	border-radius: 0;
	background-color: #201725;
	background-image: radial-gradient(ellipse at 50% 115%, #74562888, transparent 60%), url("assets/images/panorama/images/events/dark_carnival/overworld/rewards_panel/wood_panel_png.png");
	background-size: 100% 100%, auto 100%;
	background-repeat: no-repeat, repeat-x;
	box-shadow: 0 0 0 12px #101118, 0 25px 90px #000b;
}
/* Игровая колонка грида: поле центрируем в остатке ширины после колонки HUD. */
.game-screen {
	position: relative;
	/* Строку задаём явно: при авторазмещении шкала прогресса (идёт в разметке следом, но левее
	   по гриду) уехала бы во вторую строку и обрезала поле по высоте вдвое. */
	grid-area: 1 / 2;
	inset: auto;
	justify-self: center;
	width: min(600px, 100%);
	transform: none;
	box-shadow: 0 0 16px #000b;
}
/* Игровой слой ровно накрывает поле, а его размер в единицах мира задаёт --world-scale из
   shim.js: делённые на масштаб ширина и высота — это те самые единицы, в которых игровая
   логика считает координаты (она читает размеры этого слоя через actuallayoutwidth/ui-scale). */
.game-container {
	inset: 0 auto auto 0;
	width: calc(100% / var(--world-scale, 1));
	height: calc(100% / var(--world-scale, 1));
	transform-origin: 0 0;
	transform: scale(var(--world-scale, 1));
}
/* Шкала прогресса — единственный житель колонки HUD. */
.progress-container {
	position: relative;
	grid-area: 1 / 1;
	inset: auto;
	justify-self: center;
	margin: 26px 0;
}
/* В бесконечном режиме шкалы нет, поэтому колонку не резервируем — поле забирает всю ширину. */
#BlimpJump.BlimpJump_Infinite { --hud-column: 0px; }
.BlimpJump_Infinite .progress-container { display: none; }
.IsPaused .game-screen, .GameFinished .game-screen { filter: blur(4px) saturate(0) brightness(.14); }
.close-button {
	position: absolute;
	z-index: 30;
	top: 10px;
	right: 10px;
	width: 38px;
	height: 38px;
	border: 2px solid #806642;
	border-radius: 50%;
	color: #e9cf99;
	background: radial-gradient(circle at 35% 30%, #333253, #171420);
	box-shadow: 0 2px 5px #0009;
	cursor: pointer;
	font-size: 28px;
	line-height: 28px;
}
.close-button:hover { filter: brightness(1.25); }
.mute-button { right: 58px; font-size: 18px; }

@media (max-width: 720px) {
	.game-shell { height: min(88vh, 850px); aspect-ratio: .78; box-shadow: 0 0 0 4px #120f13, 0 20px 55px #000b; }
	.game-screen { width: 100%; }
	/* Колонку HUD на узком экране делаем настолько узкой, насколько позволяет сама шкала:
	   каждый её пиксель отнимается у игрового поля. */
	#BlimpJump { --hud-column: 20px; }
	.progress-container { width: 12px; margin: 16px 0; }
	.close-button { top: 6px; right: 6px; width: 32px; height: 32px; font-size: 23px; line-height: 22px; }
	.mute-button { right: 44px; font-size: 15px; }
}

/* У вложений платформ прозрачные зоны текстур не должны наследовать подложку.
   Старые правила-заглушки (.PlatformAttachment.Spring и т.д.) были специфичнее общего
   сброса ниже по файлу и продолжали навязывать свою рамку/скругление/тайлинг поверх
   настоящих текстур — отсюда белая/цветная подложка у пружины, трамплина и движ. платформ.
   !important гарантированно перебивает все унаследованные объявления. */
.PlatformAttachment,
.PlatformAttachment.Spring,
.PlatformAttachment.Trampoline,
.PlatformAttachment.Rocket,
.PlatformAttachment.Spikes {
	background-color: transparent !important;
	background-position: center !important;
	background-size: 100% 100% !important;
	background-repeat: no-repeat !important;
	background-clip: padding-box;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
}

/* То же самое для слоёв платформы: устаревшие цветовые правила (.Platform.Moving .PlatformColor
   и т.п.) специфичнее общего сброса и оставляли настоящим PNG-текстурам блёклую подложку
   (#fff0a0 у PlatformBorder2) и неверные размер/позицию/повтор фона (auto + repeat вместо
   100% 100% + no-repeat), из-за чего движущиеся платформы мигали белым на второй фазе анимации. */
.PlatformColor, .PlatformBorder, .PlatformBorder2 {
	background-color: transparent !important;
	background-position: center !important;
	background-size: 100% 100% !important;
	background-repeat: no-repeat !important;
}
/* .Platform.Finish и .Platform.Tutorial ещё сохраняли собственную рамку/градиент
   от старой цветовой заглушки (коричневую и бело-голубую соответственно) поверх текстуры. */
.Platform.Finish, .Platform.Tutorial {
	background: none !important;
	border: 0 !important;
	border-radius: 0 !important;
}

/* Центральное меню в стилистике оригинальной мини-игры. */
.main-menu-container {
	inset: 4.5% auto auto 50%;
	width: min(660px, calc(100% - 88px));
	height: min(830px, calc(100% - 90px));
	transform: translateX(-50%);
	border: 1px solid #756244;
	border-radius: 0;
	color: #d8c8c3;
	display: flex;
	flex-direction: column;
	background:
		radial-gradient(ellipse at 58% 10%, #252a5a 0%, transparent 56%),
		linear-gradient(90deg, #10111f 0%, #1a1d3d 56%, #10111f 100%);
	box-shadow: 0 14px 50px #000b, inset 0 0 0 1px #00000080;
}
.main-menu-container.menu { overflow: hidden; }
.main-menu-container::before { display: none; }
.main-menu-container .menu-body {
	display: flex;
	flex-direction: column;
	flex: 1;
	min-height: 0;
	height: auto;
	padding: 36px 56px 0;
	overflow: hidden;
}
.main-menu-container .menu-columns {
	flex: 1;
	min-height: 0;
	overflow-y: auto;
	padding-right: 4px;
}
.main-menu-container .rewards-preview {
	flex-shrink: 0;
	padding: 10px 0 14px;
}
.main-menu-container .menu-header { padding-bottom: 28px; border-bottom: 1px solid #e0b06c22; }
.main-menu-container .menu-header h1 {
	color: #e8d9a4;
	background: linear-gradient(180deg, #fff1bf 0%, #d6c88d 44%, #6f88f0 100%);
	-webkit-background-clip: text;
	background-clip: text;
	-webkit-text-fill-color: transparent;
	font-family: Reaver, Georgia, "Times New Roman", serif;
	font-weight: 600;
	font-size: clamp(31px, 4.1vw, 44px);
	letter-spacing: 1px;
	text-transform: uppercase;
	text-shadow: none;
	filter: drop-shadow(0 3px 3px #000d) drop-shadow(0 0 7px #4259b488);
}
.main-menu-container .menu-header p { margin-bottom: 0; color: #ecddd8; font-size: 18px; }
.main-menu-container .menu-column { width: 100%; max-width: 380px; }
.main-menu-container .menu-column section { padding-bottom: 17px; margin-bottom: 17px; border-bottom: 1px solid #e0b06c1f; }
.main-menu-container .menu-column h2 {
	margin-bottom: 12px;
	color: #f0c988;
	font-size: 16px;
	letter-spacing: .08em;
	text-align: center;
}
.main-menu-container .scores { padding-left: 0; }
.main-menu-container .record-row { display: flex; justify-content: space-between; gap: 12px; padding: 5px 0; color: #ddd1ce; }
.main-menu-container .record-row strong { float: none; color: #f7d99e; text-align: right; }
.main-menu-container .menu-actions {
	display: grid;
	grid-template-columns: 1fr 1fr;
	align-items: center;
	flex-shrink: 0;
	position: relative;
	z-index: 2;
	column-gap: 36px;
	row-gap: 14px;
	width: min(100%, 560px);
	margin: 0 auto;
	height: auto;
	min-height: 82px;
	padding: 12px 32px 32px;
	border-top: 1px solid #e0b06c22;
}
.main-menu-container .game-button {
	width: 100%;
	min-width: 0;
	max-width: none;
	height: 50px;
	padding: 12px 16px 16px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	text-align: center;
	font-size: 13px;
	line-height: 1.15;
	white-space: normal;
}
/* Второй ряд меню — ссылки на сайт (рейтинг и маркет): те же кнопки, но
   пониже и потише, чтобы не спорить с выбором режима игры. */
.main-menu-container .link-button {
	height: 42px;
	padding: 10px 12px 14px;
	font-size: 12px;
	text-decoration: none;
	color: #d9b789;
}

/* Топ-5 глобального рейтинга в колонке рекордов. */
.global-top-list { margin: 0; padding: 0; list-style: none; }
.global-top-list li {
	display: grid;
	grid-template-columns: 18px 1fr auto;
	gap: 8px;
	align-items: center;
	padding: 4px 0;
	border-bottom: 1px solid #e0b06c1a;
	color: #ddd1ce;
	font-size: 13px;
}
.global-top-list li:last-child { border-bottom: 0; }
.global-top-list b { color: #f0bd6d; font-size: 12px; text-align: right; }
.global-top-list span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.global-top-list i { color: #f7d99e; font-style: normal; font-variant-numeric: tabular-nums; }
.global-top-list li:nth-child(1) b { color: #ffe15e; }
.global-top-empty { color: #a99a92 !important; font-size: 12px !important; grid-template-columns: 1fr !important; }
.global-top-link {
	display: inline-block;
	margin-top: 8px;
	color: #f0bd6d;
	font-size: 12px;
	font-weight: 700;
	text-decoration: none;
}
.global-top-link:hover { color: #fff; }

/* Топ игроков на экране результатов: та же таблица, что в главном меню. Ссылка
   на полный рейтинг живёт здесь же — отдельной кнопки в футере больше нет. */
.post-game-menu-container .post-game-top { max-width: 320px; margin: 24px auto 0; text-align: left; }
.post-game-top h2 { text-align: center; }
.post-game-top .global-top-link {
	display: block;
	width: fit-content;
	margin: 12px auto 0;
	padding: 8px 14px;
	border: 1px solid #e0b06c55;
	border-radius: 8px;
}
.global-top-list li.is-me { color: #fff6e2; }
.global-top-list li.is-me b, .global-top-list li.is-me i { color: #9fe3ff; }
/* Своя строка ниже топа, если игрок в него не попал. */
.global-top-list li.is-outside { margin-top: 4px; border-top: 1px dashed #e0b06c40; }

/* Место в рейтинге на экране результатов: заполняется из leaderboard.js после
   успешной отправки счёта. */
.global-rank { display: none; margin-top: 10px !important; color: #9fe3ff !important; font-weight: 700; }
.global-rank.is-visible { display: block; }
.HidePostGameScore .global-rank { display: none; }

/* «Поделиться рекордом». В главном меню занимает всю ширину сетки: это
   отдельный ряд между выбором режима и ссылками на сайт, а не третья ссылка. */
.main-menu-container .share-button { grid-column: 1 / -1; color: #9fe3ff; }
.share-button:disabled { cursor: default; filter: brightness(.7) saturate(.6); }
.share-button[hidden] { display: none; }

/* Тост шарилки: подтверждение копирования и ошибки. Поверх меню, по центру
   снизу, кликов не перехватывает. */
.share-toast {
	position: absolute;
	z-index: 30;
	bottom: 12%;
	left: 50%;
	max-width: 80%;
	padding: 10px 18px;
	border: 1px solid #e0b06c66;
	border-radius: 10px;
	background: #19223df5;
	color: #ffe7ad;
	font-size: 13px;
	font-weight: 700;
	text-align: center;
	text-shadow: 0 2px 8px #000d;
	box-shadow: 0 12px 40px #000b;
	opacity: 0;
	transform: translate(-50%, 10px);
	pointer-events: none;
	transition: opacity .18s, transform .18s;
}
.share-toast.is-visible { opacity: 1; transform: translate(-50%, 0); }

@media (max-width: 720px) {
	/* На телефоне итоги вместе с топом не влезали в панель на 70% высоты поля:
	   расширяем её и поджимаем отступы, чтобы ссылка на рейтинг была видна без
	   прокрутки. */
	.post-game-menu-container { inset: 8% 4%; }
	.post-game-menu-container .menu-body { padding: 22px 18px; }
	.post-game-menu-container .total-score { margin-top: 16px; font-size: 17px; }
	.post-game-menu-container .total-score strong { font-size: 34px; }
	.post-game-menu-container .post-game-top { margin-top: 16px; }
	.main-menu-container { inset: 3% auto auto 50%; width: calc(100% - 26px); height: calc(100% - 26px); }
	.main-menu-container .menu-body { padding: 20px 22px 0; overflow: hidden; }
	.main-menu-container .menu-header { padding-bottom: 15px; }
	.main-menu-container .menu-header p { font-size: 14px; }
	.main-menu-container .menu-columns { overflow-y: auto; }
	.main-menu-container .scores { padding-bottom: 10px; }
	.main-menu-container .scores section { margin-bottom: 10px; padding-bottom: 10px; }
	.main-menu-container .global-top-list { max-height: 185px; overflow-y: auto; padding-right: 4px; }
	.main-menu-container .menu-actions { width: calc(100% - 24px); gap: 14px; padding: 10px 12px 22px; }
	.main-menu-container .game-button { font-size: 11px; padding: 10px 8px 14px; height: 48px; }
	.main-menu-container .link-button { height: 40px; padding: 8px 6px 12px; font-size: 10px; }
	.global-top-list li { font-size: 12px; }
}

/* На экранах ниже исходного 1000px-попапа чуть уменьшаем контент без scale (scale обрезал блок наград). */
@media (min-width: 721px) and (max-height: 920px) {
	.main-menu-container .menu-body { padding: 28px 44px 0; }
	.main-menu-container .menu-header h1 { font-size: clamp(28px, 3.5vw, 38px); }
	.main-menu-container .menu-column section { margin-bottom: 12px; padding-bottom: 12px; }
}

/* Тач-управление (см. shim.js): по образцу веб-клонов Doodle Jump (сам оригинал использует
   акселерометр телефона, но в браузере это ненадёжно и требует запроса разрешения на iOS,
   поэтому используется тот же приём, что и в большинстве HTML5-клонов — держим левую половину
   игрового поля для движения влево, правую половину — вправо). Заточку (KEY_UP/KEY_W, в самом
   Doodle Jump атаки нет) кидает треугольная зона в центре снизу: она расширяется к низу экрана,
   где лежат большие пальцы, но не отнимает боковые зоны движения на уровне персонажа.
   Блок показываем только на тач-устройствах (класс TouchInput на <html>, выставляется в shim.js)
   и только во время реальной игры (BlimpJumpState2 == GameRunning), иначе кнопки перекрывали бы меню. */
.touch-controls { display: none; }
/* .TouchInput стоит на <html>, .GameRunning — на #BlimpJump, поэтому пробел (потомок),
   а не compound-селектор: это два разных элемента в цепочке предков .touch-controls. */
.TouchInput .GameRunning .touch-controls {
	display: block;
	position: absolute;
	inset: 0;
	z-index: 6;
	-webkit-tap-highlight-color: transparent;
}
.touch-zone {
	position: absolute;
	inset-block: 0;
	width: 50%;
	touch-action: none;
	-webkit-user-select: none;
	user-select: none;
	-webkit-touch-callout: none;
	background: transparent;
}
/* Зоны влево/вправо остаются невидимыми: стрелки и подсветка при нажатии только
   моргали и мешали, а управление и так понятно (половина экрана). */
.touch-zone-left { left: 0; }
.touch-zone-right { right: 0; }
.touch-zone-arrow { display: none; }
/* clip-path режет не только отрисовку, но и попадания указателя, поэтому вершина
   треугольника не мешает управлению: тапы выше и по бокам от него достаются зонам движения. */
.touch-attack {
	position: absolute;
	z-index: 7;
	left: 50%;
	bottom: 0;
	width: min(86%, 460px);
	height: 48%;
	transform: translateX(-50%);
	display: flex;
	align-items: flex-end;
	justify-content: center;
	padding-bottom: max(16px, env(safe-area-inset-bottom));
	border: 0;
	background: transparent;
	clip-path: polygon(50% 0, 100% 100%, 0 100%);
	touch-action: none;
	-webkit-user-select: none;
	user-select: none;
	-webkit-touch-callout: none;
	transition: background .12s;
}
.touch-attack.is-pressed { background: linear-gradient(#ffffff00, #ffffff1f); }
/* Значок только помечает зону, поэтому держим его полупрозрачным: он лежит поверх поля,
   и в непрозрачном виде прятал бы Сларка на низких платформах. */
.touch-attack-badge {
	width: 93px;
	height: 93px;
	display: grid;
	place-items: center;
	border: 2px solid #806642;
	border-radius: 50%;
	color: #e9cf99;
	background: radial-gradient(circle at 35% 30%, #333253, #171420);
	box-shadow: 0 4px 14px #0009;
	font-size: 39px;
	opacity: .72;
	transition: filter .1s, transform .1s, opacity .1s;
}
.touch-attack.is-pressed .touch-attack-badge { filter: brightness(1.4); transform: scale(.92); opacity: 1; }
@media (max-width: 480px) {
	.touch-attack-badge { width: 81px; height: 81px; font-size: 33px; }
}

/* ------------------------------------------------------------------------- */
/* Telegram Mini App. Класс .tg-mini-app ставит tg.js на <html> только когда   */
/* страница открыта внутри Telegram — вне него ни одно правило не применяется. */

/* Игра занимает весь вьюпорт: рамка «попапа», отступы страницы и клавиатурные
   подсказки в мини-аппе только отнимают место. */
.tg-mini-app body { overflow: hidden; overscroll-behavior: none; }
.tg-mini-app .page {
	min-height: 0;
	height: var(--tg-viewport, 100dvh);
	padding: 0;
	gap: 0;
	align-content: start;
}
.tg-mini-app .hint { display: none; }
.tg-mini-app .blimp-jump { width: 100%; }
.tg-mini-app .game-shell {
	width: 100%;
	/* Игровое поле начинается ПОД контролами Telegram (крестик/меню/часы в
	   fullscreen рисуются поверх веб-вью). */
	height: calc(var(--tg-viewport, 100dvh) - var(--tg-content-top, 0px));
	margin-top: var(--tg-content-top, 0px);
	aspect-ratio: auto;
	border: 0;
	border-radius: 0;
	box-shadow: none;
}
/* Свои кнопки уводим налево: справа сверху Telegram держит крестик и меню. */
.tg-mini-app .close-button { right: auto; left: 10px; }
.tg-mini-app .mute-button { right: auto; left: 58px; }
@media (max-width: 720px) {
	.tg-mini-app .close-button { right: auto; left: 6px; }
	.tg-mini-app .mute-button { right: auto; left: 44px; }
}
/* Свои кнопки лежат поверх верха колонки HUD (справа их держит Telegram) — начинаем шкалу ниже. */
.tg-mini-app .progress-container { margin-top: 52px; }
/* Значок атаки поднимаем над домашним индикатором/жестовой полосой. */
.tg-mini-app .touch-attack { padding-bottom: calc(16px + var(--tg-safe-bottom, 0px)); }

/* Имя игрока из Telegram под заголовком меню (заполняется после автологина). */
.tg-player { min-height: 0; margin: 0; }
.tg-player > span[hidden] { display: none; }
.tg-player > span {
	display: inline-block;
	margin-top: -14px;
	padding: 3px 12px;
	border: 1px solid #e0b06c55;
	border-radius: 999px;
	color: #ffe298;
	background: #0000004d;
	font-size: 14px;
}
