:root {
  --tg-bg: #1e1e2e;
  --tg-text: #ffffff;
  --tg-hint: #a0a0b0;
  --tg-link: #6ab7ff;
  --tg-button: #2ea6ff;
  --tg-button-text: #ffffff;
  --tg-secondary-bg: #26263a;

  /* Игровая палитра не зависит от темы Telegram — держим её неоновой всегда. */
  --paddle-color: #00e5ff;
  --paddle-color-2: #0066ff;
  --ball-color: #ffffff;
  --ball-glow-color: #7df9ff;
  --brick-1-color: #39ff88;
  --brick-2-color: #ffb020;
  --brick-3-color: #ff2fb3;
  --brick-steel-color: #8a97a8;
  --brick-tnt-color: #ff3b30;
  --brick-boss-color: #9d4edd;
  --crystal-glow-color: #ff2fb3;
  --sticky-color: #ffb020;

  --neon-accent-a: #00e5ff;
  --neon-accent-b: #ff2fb3;
  --stage-bg-1: #150f2e;
  --stage-bg-2: #050308;
}

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  background: var(--tg-bg);
  color: var(--tg-text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

#app {
  display: flex;
  flex-direction: column;
  height: 100%;
  height: 100dvh;
  /* Device notch/home-indicator (env(safe-area-inset-*)) plus Telegram's own fullscreen-mode
     chrome only (--tg-extra-safe-*, set from webApp.contentSafeAreaInset alone in telegram.js
     — NOT webApp.safeAreaInset, which is the same notch env() already covers) — falls back
     to 0px outside Telegram so this is a no-op in a plain browser. */
  padding-top: calc(env(safe-area-inset-top) + var(--tg-extra-safe-top, 0px));
  padding-bottom: calc(env(safe-area-inset-bottom) + var(--tg-extra-safe-bottom, 0px));
  padding-left: calc(env(safe-area-inset-left) + var(--tg-extra-safe-left, 0px));
  padding-right: calc(env(safe-area-inset-right) + var(--tg-extra-safe-right, 0px));
}

#hud {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  background: var(--tg-secondary-bg);
  border-bottom: 1px solid rgba(0, 229, 255, 0.25);
  font-size: 14px;
  font-weight: 600;
  flex-shrink: 0;
  /* With several optional badges visible at once (banked + active charges for multiple
     power-ups, plus combo and a large score) content can exceed even a normal phone width —
     none of these items wrap, so without this the mute/pause/shop/upgrades buttons at the
     end get pushed off-screen and become completely unreachable (verified: pause button
     included). Horizontal scroll is a minimal safety net so nothing is ever truly stuck out
     of reach; it's invisible in the common case where everything already fits. */
  overflow-x: auto;
  scrollbar-width: none;
}

#hud::-webkit-scrollbar {
  display: none;
}

#hud-lives,
#hud-score,
#hud-level {
  white-space: nowrap;
}

#hud-score-value {
  color: var(--neon-accent-a);
  text-shadow: 0 0 8px rgba(0, 229, 255, 0.6);
}

#hud-lives-value {
  color: var(--neon-accent-b);
  text-shadow: 0 0 8px rgba(255, 47, 179, 0.6);
}

/* Cyan pairs with score — both are progress stats, distinct from lives' magenta danger cue. */
#hud-level-value {
  color: var(--neon-accent-a);
  text-shadow: 0 0 8px rgba(0, 229, 255, 0.6);
}

#hud-combo-value {
  color: var(--neon-accent-b);
  text-shadow: 0 0 8px rgba(255, 47, 179, 0.6);
}

#hud-combo.hidden {
  display: none;
}

/* Supplementary purchase/timer info — smaller and undimmed relative to the primary
   score/lives/level stats above so it doesn't compete for attention. */
#hud-extra-lives,
#hud-sticky-charges,
#hud-laser-charges,
#hud-expand-timer,
#hud-sticky-timer,
#hud-laser-timer {
  white-space: nowrap;
  font-size: 12px;
  opacity: 0.85;
}

#hud-extra-lives.hidden,
#hud-sticky-charges.hidden,
#hud-laser-charges.hidden,
#hud-expand-timer.hidden,
#hud-sticky-timer.hidden,
#hud-laser-timer.hidden {
  display: none;
}

#hud-extra-lives-value,
#hud-sticky-charges-value,
#hud-laser-charges-value {
  color: var(--neon-accent-b);
}

#hud-expand-timer-value,
#hud-sticky-timer-value,
#hud-laser-timer-value {
  color: var(--neon-accent-a);
}

#hud-mute-btn {
  margin-left: auto;
}

#hud-mute-btn,
#hud-pause-btn,
#hud-shop-btn,
#hud-upgrades-btn {
  padding: 8px 10px;
}

#stage {
  /* Positioning context for .overlay and .panel's inset:0 (both now live inside #stage in the
     markup) — #stage sits below #hud in normal flow already, so anything absolutely positioned
     against it starts right under the HUD instead of overlapping it. */
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(ellipse at 50% 0%, var(--stage-bg-1) 0%, var(--stage-bg-2) 70%);
}

/* Оборачивает canvas + crystal-layer, чтобы оба центрировались во #stage как единое целое —
   crystal-layer позиционируется inset:0 относительно этого контейнера, а не всего #stage,
   иначе на широком (десктопном) экране оверлеи кристальных кирпичей разъедутся с canvas. */
#playfield {
  position: relative;
  line-height: 0;
}

#game-canvas {
  display: block;
  touch-action: none;
}

/* Container for crystal-brick glow overlays; positioned to match canvas coordinate space */
#crystal-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.brick-crystal {
  position: absolute;
  border-radius: 6px;
  background: linear-gradient(160deg, #ff7fd4, var(--brick-3-color));
  box-shadow: 0 0 8px 3px var(--crystal-glow-color);
  animation: crystal-pulse 1.4s ease-in-out infinite;
  will-change: filter, box-shadow;
}

@keyframes crystal-pulse {
  0%, 100% {
    filter: brightness(1);
    box-shadow: 0 0 8px 3px var(--crystal-glow-color);
  }
  50% {
    filter: brightness(1.6);
    box-shadow: 0 0 22px 8px var(--crystal-glow-color);
  }
}

.boss-health-bar {
  position: absolute;
  height: 8px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(157, 78, 221, 0.5);
  overflow: hidden;
}

.boss-health-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--brick-boss-color), var(--brick-3-color));
  transition: width 0.15s ease;
}

button {
  font: inherit;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 12px 20px;
  border: none;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--neon-accent-a), var(--neon-accent-b));
  color: #0a0a12;
  cursor: pointer;
  box-shadow:
    0 0 14px rgba(0, 229, 255, 0.45),
    0 0 28px rgba(255, 47, 179, 0.25);
  transition: filter 0.15s ease, transform 0.1s ease;
}

button:active {
  filter: brightness(0.9);
  transform: scale(0.97);
}

.overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  background: radial-gradient(ellipse at 50% 40%, rgba(21, 15, 46, 0.85) 0%, rgba(2, 1, 6, 0.92) 100%);
  text-align: center;
  padding: 24px;
}

.overlay.hidden {
  display: none;
}

#onboarding-hint {
  color: var(--tg-hint);
  font-size: 14px;
  line-height: 1.4;
}

#onboarding-hint p {
  margin: 0;
}

#referral-count {
  color: var(--tg-hint);
  font-size: 13px;
  margin: 0;
}

#referral-count.hidden {
  display: none;
}

#onboarding-hint.hidden {
  display: none;
}

#daily-reward {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  background: var(--tg-secondary-bg);
  border: 1px solid rgba(0, 229, 255, 0.25);
  border-radius: 12px;
  box-shadow: 0 0 10px rgba(0, 229, 255, 0.12) inset;
}

#daily-reward-text {
  margin: 0;
  color: var(--tg-hint);
  font-size: 14px;
}

#daily-reward.hidden {
  display: none;
}

/* Raised from the default vertically-centered .overlay position per user request — sat with
   too much empty space above it. Scoped to the main menu only, not gameover/pause, which
   still read fine centered. */
#overlay-start {
  justify-content: flex-start;
  padding-top: 15%;
}

#menu-actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 16px;
}

.overlay h1 {
  margin: 0;
  font-size: 30px;
  font-weight: 800;
  letter-spacing: 0.03em;
  background: linear-gradient(135deg, var(--neon-accent-a), var(--neon-accent-b));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 0 12px rgba(0, 229, 255, 0.45));
}

.panel {
  position: absolute;
  inset: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  background: var(--tg-bg);
  overflow-y: auto;
}

/* The 227px extra top padding this rule used to carry is gone: it was compensating for the
   .panel-outside-#stage positioning bug (see the comment on #stage) — once panels moved
   inside #stage, that padding became pure extra offset, pushing the leaderboard ~211px
   below where every other panel's heading starts (confirmed by measuring both). Removed so
   the leaderboard aligns with shop/upgrades/levels "at the same level as the HUD", which was
   the actual original ask. */

.panel.hidden {
  display: none;
}

.panel h2 {
  margin: 0;
  color: var(--neon-accent-a);
  text-shadow: 0 0 10px rgba(0, 229, 255, 0.5);
}

/* Тот же "callout box" язык, что у #daily-reward, но акцент на magenta — тёплый
   праздничный тон лучше подходит для позитивного сообщения "это бесплатно", чем
   нейтральный cyan, уже занятый у #daily-reward под обычную информационную плашку. */
#shop-free-banner {
  margin: 0;
  padding: 10px 14px;
  background: var(--tg-secondary-bg);
  border: 1px solid rgba(255, 47, 179, 0.35);
  border-radius: 12px;
  box-shadow: 0 0 10px rgba(255, 47, 179, 0.15) inset;
  color: var(--neon-accent-b);
  font-size: 14px;
  font-weight: 700;
  text-align: center;
}

#shop-free-banner.hidden {
  display: none;
}

#shop-items {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

#levels-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(52px, 1fr));
  gap: 10px;
}

#levels-grid button {
  aspect-ratio: 1;
  padding: 0;
}

.shop-item {
  display: flex;
  /* Longer RU labels ("Ширина платформы (0/3)") paired with longer RU button text
     ("Купить (100 монет)") don't both fit on one line at ~360px content width — without
     wrap, the button's own text broke mid-word onto 2 lines while still stuck inline next
     to the label, reading as a cramped, oddly-tall row. Wrapping the row lets the button
     drop to its own line (nowrap keeps ITS text on one line) instead of visibly breaking
     inside the button; still a single line for every row that does fit (the common case,
     e.g. all EN rows and most RU shop rows). */
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  padding: 10px 14px;
  background: var(--tg-secondary-bg);
  border: 1px solid rgba(0, 229, 255, 0.25);
  border-radius: 12px;
  box-shadow: 0 0 10px rgba(0, 229, 255, 0.12) inset;
}

.shop-item button {
  white-space: nowrap;
  margin-left: auto;
}

#leaderboard-list {
  padding-left: 24px;
}

#leaderboard-list li {
  padding: 4px 0;
}

#leaderboard-list li::marker {
  color: var(--neon-accent-b);
  font-weight: 700;
}

.own-entry {
  color: var(--neon-accent-a);
  font-weight: 700;
}

#leaderboard-best {
  color: var(--neon-accent-a);
}

/* Магента, как у #hud-lives-value/#hud-combo-value — рядом с заголовком #overlay-gameover
   h1, уже использующим цианово-магентовый градиент, магента лучше читается как отдельный
   акцент "почти получилось", не сливаясь с общим glow заголовка. */
#gameover-message {
  margin: 0;
  color: var(--neon-accent-b);
  text-shadow: 0 0 8px rgba(255, 47, 179, 0.6);
  font-weight: 700;
}

#gameover-message.hidden {
  display: none;
}
