@import url("/assets/subscription/purchase.css");
@import url("/assets/subscription/profile.css");

:root {
  color-scheme: dark;
  --bg: #111111;
  --panel: #161616;
  --panel-2: #242424;
  --panel-3: #313131;
  --text: #f6f6f6;
  --muted: #8f8f8f;
  --accent: #01bdb7;
  --accent-strong: #0ec2c7;
  --shadow: 0 24px 60px rgba(0, 0, 0, 0.32);
  --radius-xl: 28px;
  --radius-lg: 22px;
  --radius-md: 18px;
  --radius-pill: 999px;
  --page-padding: 24px;
  --card-padding: 32px;
  font-family: "Segoe UI", system-ui, sans-serif;
}

* {
  box-sizing: border-box;
}

/* ── Splash loader ── */

.splash {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: grid;
  place-items: center;
  background: var(--bg);
  transition: opacity 0.4s ease, visibility 0.4s ease;
}

.splash.is-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.splash-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 28px;
}

.splash-icon {
  width: 64px;
  height: 64px;
  animation: splashPulse 1.6s ease-in-out infinite;
  filter: drop-shadow(0 0 18px rgba(1, 189, 183, 0.35));
}

.splash-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid rgba(1, 189, 183, 0.15);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: splashSpin 0.8s linear infinite;
}

@keyframes splashPulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.08); opacity: 0.85; }
}

@keyframes splashSpin {
  to { transform: rotate(360deg); }
}

/* ── App reveal ── */

.app-shell.is-revealed {
  opacity: 1 !important;
  animation: appReveal 0.5s ease-out;
}

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

html,
body {
  margin: 0;
  min-height: 100%;
  background: var(--bg);
  color: var(--text);
  /* Запрет pinch-zoom и double-tap-zoom — мини-апп должен ощущаться
     как нативное приложение, не как веб-страница. */
  touch-action: manipulation;
  -ms-content-zooming: none;
  -webkit-text-size-adjust: 100%;
}

body {
  min-height: 100vh;
  position: relative;
  overflow-x: hidden;
}

body::before {
  content: "";
  position: fixed;
  inset: auto;
  pointer-events: none;
  z-index: 0;
  border-radius: 50%;
  filter: blur(36px);
  opacity: 0.65;
  will-change: transform;
  width: min(76vw, 980px);
  height: min(76vw, 980px);
  left: 50%;
  top: -34%;
  transform: translateX(-50%);
  background:
    radial-gradient(
      circle,
      rgba(1, 189, 183, 0.2) 0%,
      rgba(1, 189, 183, 0.12) 28%,
      rgba(1, 189, 183, 0.07) 46%,
      rgba(1, 189, 183, 0.03) 62%,
      rgba(1, 189, 183, 0.01) 74%,
      transparent 86%
    );
  animation: centerFlow 18s ease-in-out infinite alternate;
}

button {
  font: inherit;
}

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
  filter: none;
}

.app-shell {
  min-height: 100vh;
  padding: max(16px, env(safe-area-inset-top))
    var(--page-padding) max(16px, env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  z-index: 1;
}

/* Telegram Desktop renders its own chat-title bar above the WebApp
   window, so our 16px top padding (calibrated for iPhone notch on
   mobile fullscreen) shows up as a wasted gap under that bar. Drop the
   top padding entirely on desktop — content sits flush under the
   Telegram-rendered title. The .is-tg-desktop class is set in
   initTelegram() based on tg.platform. */
.is-tg-desktop .app-shell {
  padding-top: 0;
}

/* .top-bar carries 54px of top padding to clear the iPhone notch /
   Android status bar on mobile fullscreen. Desktop has neither, so
   that 54px is pure waste — collapse it. */
.is-tg-desktop .top-bar {
  padding-top: 8px;
}

/* ── Floating flowers ── */

.floating-flowers {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}

.floating-flower {
  position: absolute;
  width: 58px;
  height: 58px;
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
  opacity: 0.18;
  filter: blur(0.2px);
  will-change: transform, opacity;
  background-image: url("data:image/svg+xml,%3Csvg width='58' height='58' viewBox='0 0 58 58' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M46.9528 42.8022H44.1978V45.5753H41.4247V48.3303H38.6697V51.1034H35.8965V53.8584H44.1978V51.1034H46.9528V48.3303H49.7078V40.0472H46.9528V42.8022ZM44.1978 23.4809H46.9528V1.38657H41.4247V4.14157H44.1978V23.4809ZM41.4247 23.4809H44.1978V26.2359H41.4247V23.4809ZM38.6697 4.14157H41.4247V6.91469H38.6697V4.14157Z' fill='%2301BDB7'/%3E%3Cpath d='M38.6697 48.3303V45.5753H41.4247V42.8022H44.1978V40.0472H46.9528V37.2922H38.6697V40.0472H35.8965V42.8022H33.1415V51.1034H35.8965V48.3303H38.6697ZM35.8965 26.2359H41.4247V29.009H35.8965V26.2359ZM35.8965 6.91467H38.6697V9.66967H35.8965V6.91467Z' fill='%2301BDB7'/%3E%3Cpath d='M35.8966 29.0091H22.1035V31.7641H27.6135V56.6134H30.3866V31.7641H35.8966V29.0091ZM33.1416 4.14157H35.8966V6.91469H33.1416V4.14157ZM24.8585 1.38657H33.1416V4.14157H24.8585V1.38657ZM22.1035 4.14157H24.8585V6.91469H22.1035V4.14157Z' fill='%2301BDB7'/%3E%3Cpath d='M22.1034 40.0472H19.3303V37.2922H11.0472V40.0472H13.8022V42.8022H16.5753V45.5753H19.3303V48.3303H22.1034V51.1034H24.8584V42.8022H22.1034V40.0472ZM16.5753 26.2359H22.1034V29.0091H16.5753V26.2359ZM19.3303 6.91469H22.1034V9.66969H19.3303V6.91469ZM19.3303 48.3303H16.5753V45.5753H13.8022V42.8022H11.0472V40.0472H8.29218V48.3303H11.0472V51.1034H13.8022V53.8584H22.1034V51.1034H19.3303V48.3303ZM16.5753 4.14157H19.3303V6.91469H16.5753V4.14157ZM13.8022 23.4809H16.5753V26.2359H13.8022V23.4809ZM13.8022 4.14157H16.5753V1.38657H11.0472V23.4809H13.8022V4.14157Z' fill='%2301BDB7'/%3E%3C/svg%3E");
}

.floating-flower-1 {
  top: 11%;
  left: 8%;
  opacity: 0.1;
  animation: floatFlowerA 13s ease-in-out infinite alternate;
}

.floating-flower-2 {
  top: 18%;
  right: 13%;
  opacity: 0.26;
  animation: floatFlowerB 16s ease-in-out infinite alternate;
}

.floating-flower-3 {
  top: 39%;
  left: 5%;
  opacity: 0.14;
  animation: floatFlowerC 14s ease-in-out infinite alternate;
}

.floating-flower-4 {
  top: 54%;
  right: 7%;
  opacity: 0.08;
  animation: floatFlowerD 18s ease-in-out infinite alternate;
}

.floating-flower-5 {
  top: 68%;
  left: 11%;
  opacity: 0.22;
  animation: floatFlowerE 15s ease-in-out infinite alternate;
}

.floating-flower-6 {
  top: 76%;
  right: 18%;
  opacity: 0.12;
  animation: floatFlowerF 12s ease-in-out infinite alternate;
}

.floating-flower-7 {
  top: 6%;
  left: 50%;
  opacity: 0.07;
  animation: floatFlowerG 20s ease-in-out infinite alternate;
}

.floating-flower-8 {
  top: 23%;
  left: 29%;
  opacity: 0.12;
  animation: floatFlowerH 17s ease-in-out infinite alternate;
}

.floating-flower-9 {
  top: 30%;
  right: 28%;
  opacity: 0.18;
  animation: floatFlowerI 14s ease-in-out infinite alternate;
}

.floating-flower-10 {
  top: 58%;
  left: 24%;
  opacity: 0.09;
  animation: floatFlowerJ 19s ease-in-out infinite alternate;
}

.floating-flower-11 {
  top: 82%;
  left: 42%;
  opacity: 0.16;
  animation: floatFlowerK 16s ease-in-out infinite alternate;
}

.floating-flower-12 {
  top: 72%;
  right: 33%;
  opacity: 0.11;
  animation: floatFlowerL 15s ease-in-out infinite alternate;
}

/* ── Content shell ── */

.content {
  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  position: relative;
}

.screen {
  display: none;
}

.screen.is-active {
  display: block;
  max-width: 480px;
  margin: 0 auto;
  width: 100%;
}

/* ── Top bar (EDGE-style: avatar+name left, balance right) ── */

.top-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 22px;
  padding: 54px 0 4px;
}

.top-bar-user {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  cursor: pointer;
  border: none;
  background: none;
  padding: 0;
  color: inherit;
}

.top-bar-avatar {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  background: linear-gradient(180deg, rgba(1, 189, 183, 0.92) 0%, rgba(1, 189, 183, 0.74) 100%);
  color: #041414;
  font-size: 0.95rem;
  font-weight: 800;
  overflow: hidden;
}

.top-bar-name {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.top-bar-chevron {
  flex-shrink: 0;
  width: 8px;
  height: 12px;
  color: var(--muted);
}

.top-bar-balance {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 8px 14px;
  border: 1px solid rgba(1, 189, 183, 0.28);
  border-radius: var(--radius-pill);
  background: rgba(1, 189, 183, 0.1);
  color: var(--accent);
  font-size: 0.88rem;
  font-weight: 700;
  cursor: pointer;
  transition: transform 120ms ease, background 120ms ease;
}

.top-bar-balance-plus {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--accent);
  color: #041414;
  font-size: 0.75rem;
  font-weight: 800;
  line-height: 1;
}

.top-bar-balance:hover {
  transform: translateY(-1px);
  background: rgba(1, 189, 183, 0.16);
}

.top-bar-balance:active {
  transform: translateY(0);
}

/* ── Brand header (used in install screen) ── */

.brand {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 14px;
  margin-bottom: 28px;
}

.brand-mark {
  width: 58px;
  height: 58px;
  flex: none;
}

.brand-icon {
  display: block;
  width: 58px;
  height: 58px;
}

.brand-text {
  display: flex;
  align-items: center;
  gap: 14px;
}

.brand-title {
  width: 152px;
  height: 58px;
  font-family: "Pixelify Sans", sans-serif;
  font-weight: 700;
  font-size: 48px;
  line-height: 58px;
  text-align: center;
  color: #ffffff;
  flex: none;
}

.brand-pill {
  width: 121px;
  height: 58px;
  display: inline-block;
  flex: none;
}

.brand-pill-icon {
  display: block;
  width: 121px;
  height: 58px;
}

/* ── Trial banner ── */

.trial-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 20px;
  border-radius: var(--radius-pill);
  background: rgba(1, 189, 183, 0.06);
  border: 1px solid rgba(1, 189, 183, 0.12);
  margin-bottom: 26px;
}

.trial-banner-left {
  min-width: 0;
}

.trial-banner-title {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--text);
  line-height: 1.3;
}

.trial-banner-subtitle {
  margin: 0;
  font-size: 0.85rem;
  color: var(--accent);
  line-height: 1.3;
}

.trial-banner.is-missing .trial-banner-title { color: #ff4d5e; }
.trial-banner.is-missing .trial-banner-subtitle { color: #ff4d5e; }
.trial-banner.is-expired .trial-banner-title { color: #ff7f44; }
.trial-banner.is-expired .trial-banner-subtitle { color: #ff7f44; }

.trial-banner-action {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px 14px;
  border: none;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: #041414;
  font-size: 0.84rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  transition: transform 120ms ease;
}

.trial-banner-action:hover {
  transform: translateY(-1px);
}

.trial-banner-action:active {
  transform: translateY(0);
}

/* Expired / no-active-sub: button is informational only (tariff builder is
   shown below) — dimmed + non-interactive. */
.trial-banner-action:disabled {
  opacity: 0.45;
  cursor: default;
  pointer-events: none;
}
.trial-banner-action:disabled:hover { transform: none; }

/* ── Server panel (shown on home when subscription active) ── */

.server-panel {
  margin-top: 24px;
  background: rgba(24, 24, 24, 0.72);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: var(--radius-xl);
  padding: 20px;
}

.server-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

.server-panel-title {
  margin: 0;
  font-size: 1.1rem;
}

.server-count {
  color: var(--muted);
  font-size: 0.94rem;
}

.server-list {
  display: grid;
  gap: 12px;
}

.server-item {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 14px;
  align-items: center;
  padding: 14px 16px;
  border-radius: var(--radius-lg);
  background: rgba(49, 49, 49, 0.9);
}

/* Green "server is up" indicator on the right side of each row.
   Soft outer glow mirrors the accent color so the dot reads as
   alive even on the dark card background. The --off variant is
   reserved for future health-probe failures. */
.server-item-status {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #2ED9C3;
  box-shadow: 0 0 0 3px rgba(46, 217, 195, 0.18), 0 0 8px rgba(46, 217, 195, 0.45);
  flex-shrink: 0;
}

.server-item-status--off {
  background: #8a3535;
  box-shadow: 0 0 0 3px rgba(138, 53, 53, 0.2);
}

.server-item-copy {
  min-width: 0;
}

.server-item-name,
.server-item-desc,
.server-item-endpoint {
  margin: 0;
}

.server-item-name {
  font-size: 1rem;
}

.server-item-desc {
  margin-top: 6px;
  color: var(--text);
  opacity: 0.78;
}

.server-item-endpoint {
  margin-top: 8px;
  color: var(--muted);
  font-size: 0.9rem;
}

.server-copy {
  border: none;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: #081212;
  padding: 10px 14px;
  cursor: pointer;
  font-weight: 700;
}

.server-empty {
  margin: 0;
  padding: 16px;
  border-radius: var(--radius-lg);
  background: rgba(49, 49, 49, 0.62);
  color: var(--muted);
}

/* ── Quick links row ── */

.quick-links {
  display: flex;
  justify-content: center;
  gap: 24px;
  margin-top: 18px;
}

.quick-link-btn {
  border: none;
  background: none;
  color: var(--muted);
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
  padding: 6px 0;
  transition: color 120ms ease;
}

.quick-link-btn:hover {
  color: var(--accent);
}

/* ── Install screen (EDGE-style) ── */

.install-hero {
  text-align: center;
  padding: 16px 0 24px;
}

.install-hero-icon {
  width: 80px;
  height: 80px;
  margin: 0 auto 16px;
  border-radius: 50%;
  background: linear-gradient(135deg, rgba(1,189,183,0.22) 0%, rgba(1,189,183,0.08) 100%);
  display: grid;
  place-items: center;
  box-shadow: 0 10px 32px rgba(1,189,183,0.2);
}

.install-hero-title {
  margin: 0 0 8px;
  font-size: 1.5rem;
  font-weight: 800;
}

.install-hero-desc {
  margin: 0;
  color: var(--muted);
  font-size: 0.92rem;
  line-height: 1.45;
}

/* Legacy pill styles — kept so any existing markup with this class still
   renders correctly, but the new install screen uses .install-platforms-row
   below (a single dropdown). */
.install-platforms {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 18px;
}

.install-platform-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1.5px solid rgba(255,255,255,0.1);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text);
  font-size: 0.84rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 120ms, background 120ms;
}

.install-platform-pill.is-active {
  border-color: var(--accent);
  background: rgba(1,189,183,0.12);
  color: var(--accent);
}

.install-platform-tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 18px;
  padding: 0 4px;
  border-radius: 4px;
  background: rgba(255,255,255,0.08);
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.install-platform-pill.is-active .install-platform-tag {
  background: rgba(1,189,183,0.2);
  color: var(--accent);
}

/* New compact picker row — replaces the 7-pill grid.
   Uses the SAME 2-column grid template as .install-apps so the cluster
   in the right column lines up pixel-for-pixel with the INCY card
   directly below. Label sits in the left column, vertically centered. */
.install-platforms-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  align-items: center;
  margin-bottom: 18px;
}

.install-platforms-label {
  /* Solid teal pill — same look as the "Добавить" CTA button. Overrides
     the muted grey colour from .section-label. justify-self prevents the
     pill from stretching to fill the grid column; it hugs its text. */
  margin: 0;
  justify-self: start;
  display: inline-block;
  padding: 7px 18px;
  border-radius: 999px;
  background: var(--accent);
  color: #0b0b0b;
  letter-spacing: 0.08em;
}

.install-platforms-row-actions {
  /* Right column of the grid — exactly one app-card width by definition.
     QR button fixed 46px, dropdown fills the rest. */
  display: flex;
  align-items: stretch;
  gap: 8px;
  min-width: 0;
}

.install-platforms-row-actions .install-platform-select-wrap {
  flex: 1 1 auto;
  min-width: 0;
}

.install-platforms-row-actions .install-platform-select {
  width: 100%;
  padding-right: 32px;
}

.install-platforms-row-actions {
  display: flex;
  flex: 1;
  align-items: stretch;
  gap: 8px;
}

/* Select wrapper grows to fill remaining width (after the QR button). */
.install-platforms-row-actions .install-platform-select-wrap {
  flex: 1;
  min-width: 0;       /* allow shrinking to fit narrow container */
}

.install-platforms-row-actions .install-platform-select {
  width: 100%;        /* fill the wrapper */
  padding-right: 32px; /* tighter chevron padding so iOS / macOS labels fit */
}

/* QR icon button — square, dark, rounded; opens device-bind modal. */
.install-qr-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  padding: 0;
  border: 1.5px solid rgba(255,255,255,0.08);
  border-radius: 14px;
  background: rgba(255,255,255,0.03);
  color: var(--text);
  cursor: pointer;
  transition: border-color 120ms, background 120ms, color 120ms;
}

.install-qr-btn:hover,
.install-qr-btn:focus {
  border-color: var(--accent);
  background: rgba(1,189,183,0.08);
  color: var(--accent);
  outline: none;
}

.install-qr-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.install-platform-select-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 46px;
}

/* Custom dropdown trigger button — visually matches the QR icon button
   style (rounded, dark) but wider, with icon + label + chevron. Tight
   padding/gap so longer labels like "Android TV" fit inside the
   column-sized container without truncating. */
.install-platform-button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  height: 46px;
  padding: 0 8px 0 10px;
  border: 1.5px solid rgba(255,255,255,0.08);
  border-radius: 14px;
  background: rgba(255,255,255,0.03);
  color: var(--text);
  font-family: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 120ms, background 120ms, color 120ms;
  outline: none;
}

.install-platform-button:hover,
.install-platform-button:focus,
.install-platform-button[aria-expanded="true"] {
  border-color: var(--accent);
  background: rgba(1,189,183,0.08);
}

.install-platform-button-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--text);
}

.install-platform-button-icon svg {
  width: 100%;
  height: 100%;
}

.install-platform-button-label {
  flex: 1;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.install-platform-button-chevron {
  flex-shrink: 0;
  color: var(--muted);
  transition: transform 150ms;
}

.install-platform-button[aria-expanded="true"] .install-platform-button-chevron {
  transform: rotate(180deg);
}

/* Popup list — absolutely positioned under the button, opens downward. */
.install-platform-popup {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 50;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: #1a1a1a;
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 14px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.55);
  max-height: 320px;
  overflow-y: auto;
}

.install-platform-popup[hidden] {
  display: none;
}

.install-platform-option {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 10px;
  border: none;
  border-radius: 10px;
  background: transparent;
  color: var(--text);
  font-family: inherit;
  font-size: 0.94rem;
  font-weight: 600;
  cursor: pointer;
  text-align: left;
  transition: background 100ms, color 100ms;
}

.install-platform-option:hover,
.install-platform-option:focus {
  background: rgba(255,255,255,0.06);
  outline: none;
}

.install-platform-option.is-selected {
  background: rgba(1,189,183,0.12);
  color: var(--accent);
}

.install-platform-option-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  flex-shrink: 0;
}

.install-platform-option-icon svg {
  width: 100%;
  height: 100%;
}

.install-apps {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-bottom: 18px;
}

.install-apps .install-app-btn:nth-child(odd):last-child {
  grid-column: 1;
}

.install-app-btn {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border: 1.5px solid rgba(255,255,255,0.08);
  border-radius: 16px;
  background: rgba(36,36,36,0.7);
  color: var(--text);
  font-size: 0.92rem;
  font-weight: 700;
  cursor: pointer;
  transition: border-color 120ms, background 120ms;
}

.install-app-btn.is-selected {
  border-color: var(--accent);
  background: linear-gradient(180deg, rgba(1,189,183,0.16) 0%, rgba(1,189,183,0.06) 100%);
  color: var(--accent);
}

.install-app-tag {
  width: 32px;
  height: 32px;
  border-radius: 10px;
  background: rgba(1,189,183,0.12);
  color: var(--accent);
  display: grid;
  place-items: center;
  font-size: 0.72rem;
  font-weight: 800;
  flex-shrink: 0;
}

.install-app-badge {
  position: absolute;
  top: 8px;
  right: 10px;
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.4px;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(1, 189, 183, 0.10);
  color: var(--accent);
  border: 1px solid rgba(1, 189, 183, 0.45);
  white-space: nowrap;
  pointer-events: none;
}

.install-key-card {
  padding: 16px;
  border-radius: 18px;
  background: rgba(36,36,36,0.7);
  border: 1px solid rgba(255,255,255,0.06);
  margin-bottom: 18px;
}

.install-key-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}

.install-key-copy {
  border: none;
  background: none;
  color: var(--accent);
  font-size: 0.82rem;
  font-weight: 700;
  cursor: pointer;
  padding: 0;
}

.install-key-url {
  margin: 0;
  padding: 12px 14px;
  border-radius: 12px;
  background: rgba(22,22,22,0.8);
  border: 1px solid rgba(255,255,255,0.06);
  color: var(--muted);
  font-size: 0.82rem;
  word-break: break-all;
}

.install-steps {
  display: grid;
  gap: 14px;
  margin-bottom: 20px;
}

.install-step-card {
  display: flex;
  gap: 16px;
  padding: 20px;
  border-radius: 20px;
  background: rgba(36,36,36,0.6);
  border: 1px solid rgba(255,255,255,0.06);
}

.install-step-badge {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--accent);
  color: #0b0b0b;
  display: grid;
  place-items: center;
  font-size: 1rem;
  font-weight: 800;
}

/* Step 4 ("Если подписка не добавилась") is a troubleshooting card — not
 * part of the main happy path. Subdued styling keeps it from competing
 * with the numbered 1/2/3 steps visually: muted accent gear icon instead
 * of a bold numbered disc, and a slightly different background tint. */
.install-step-card--manual {
  background: rgba(36,36,36,0.4);
  border-color: rgba(255,255,255,0.04);
}
.install-step-badge--manual {
  background: rgba(1,189,183,0.15);
  color: var(--accent);
}

.install-step-body {
  flex: 1;
  min-width: 0;
}

.install-step-title {
  margin: 0 0 8px;
  font-size: 1rem;
  font-weight: 700;
}

.install-step-desc {
  margin: 0;
  color: var(--muted);
  font-size: 0.88rem;
  line-height: 1.5;
}

/* Numbered list rendered inside a Step-4 card — used by TV platforms
 * where the instructions are a multi-step sequence ("open Happ on your
 * phone, scan the QR, pick what to send, done"). Resets the browser's
 * default left indent so numbers align with the rest of the card's
 * body text, and tightens per-item spacing for a compact look. */
.install-step-steps {
  margin: 0;
  padding-left: 1.25rem;
  color: var(--muted);
  font-size: 0.88rem;
  line-height: 1.55;
}

.install-step-steps li {
  margin: 0 0 0.35rem 0;
}

.install-step-steps li:last-child {
  margin-bottom: 0;
}

.install-step-actions {
  display: flex;
  gap: 10px;
  margin-top: 14px;
  flex-wrap: wrap;
}

.install-step-btn {
  padding: 10px 20px;
  border: 1px solid rgba(1,189,183,0.3);
  border-radius: var(--radius-pill);
  background: rgba(1,189,183,0.1);
  color: var(--accent);
  font-size: 0.88rem;
  font-weight: 700;
  cursor: pointer;
  transition: transform 120ms, background 120ms;
}

.install-step-btn.is-primary {
  background: var(--accent);
  color: #041414;
  border-color: transparent;
}

.install-step-btn:hover { transform: translateY(-1px); }
.install-step-btn:active { transform: translateY(0); }

/* Grid variant for step 2 — two buttons side by side ("Вручную" /
   "Сканировать QR-код"). Collapses to a single column on narrow
   viewports so both remain tappable on compact phones. */
.install-step-actions.install-step-actions--grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
@media (max-width: 360px) {
  .install-step-actions.install-step-actions--grid {
    grid-template-columns: 1fr;
  }
}
.install-step-actions.install-step-actions--grid .install-step-btn {
  padding: 12px 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
}

/* Secondary "Сканировать QR-код" button: outlined, slightly dimmer
   than primary so "Вручную" stays the default CTA. Same interaction
   semantics (hover/active lift) as the primary. */
.install-step-btn--secondary {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.1);
  color: var(--text);
}
.install-step-btn--secondary:hover {
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(255, 255, 255, 0.18);
}
.install-step-btn--secondary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.cta-back {
  position: fixed;
  bottom: max(14px, env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  width: calc(100% - 48px);
  max-width: 420px;
  margin: 0;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, #017a76 0%, #01bdb7 50%, #3de8e0 100%);
  color: #041414;
  box-shadow: 0 6px 28px rgba(0,0,0,0.4);
}

.cta-back:hover { filter: brightness(1.05); transform: translateX(-50%) !important; }
.cta-back:active { filter: brightness(0.95); transform: translateX(-50%) !important; }

.screen-install { padding-bottom: 90px; }

/* legacy compat — hide old elements */
.platforms, .platforms-row, .platform-switcher, .platform-menu,
.steps, .step, .fallback, .support-button,
.brand { display: none; }

.platforms-row {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.section-title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 500;
}

.tabs {
  display: flex;
  align-items: center;
  gap: 10px;
}

.platform-switcher {
  position: relative;
  display: flex;
  align-items: center;
}

.tab {
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: var(--panel-3);
  color: var(--text);
  border-radius: var(--radius-pill);
  padding: 10px 18px;
  min-width: 74px;
  cursor: pointer;
  transition: transform 120ms ease, background 120ms ease, opacity 120ms ease;
}

.tab.is-active {
  background: var(--accent);
  color: #0b0b0b;
  border-color: transparent;
}

.tab-more {
  min-width: 0;
  width: 40px;
  padding-inline: 0;
}

.platform-menu {
  position: absolute;
  top: calc(100% + 12px);
  right: 0;
  width: min(272px, calc(100vw - 56px));
  padding: 16px 14px 14px;
  border-radius: 24px;
  background: rgba(22, 22, 22, 0.98);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
  opacity: 0;
  transform: translateY(-16px) scale(0.88);
  transform-origin: top right;
  pointer-events: none;
  transition:
    opacity 180ms ease,
    transform 240ms cubic-bezier(0.2, 0.8, 0.2, 1);
  z-index: 10;
}

.platform-menu.is-open {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

.platform-menu-hint,
.platform-menu-subhint {
  margin: 0;
  color: #3d3d3d;
  font-size: 0.82rem;
  line-height: 1.25;
}

.platform-menu-list {
  display: grid;
  gap: 14px;
  margin: 16px 0 18px;
}

.platform-menu-item {
  padding: 0;
  border: none;
  background: none;
  color: #ffffff;
  text-align: left;
  font-size: clamp(1rem, 2vw, 1.55rem);
  line-height: 1;
  cursor: pointer;
}

.platform-menu-copy {
  width: 100%;
  min-height: 48px;
  margin-top: 12px;
  border: none;
  border-radius: 999px;
  background: #16c1c4;
  color: #050505;
  font-size: clamp(0.95rem, 2.2vw, 1.2rem);
  line-height: 1;
  cursor: pointer;
}

.platform-hint {
  margin: 16px 0 0;
  text-align: center;
  color: var(--muted);
  font-size: 0.95rem;
}

.steps {
  display: grid;
  gap: 16px;
}

.step {
  background: var(--panel-2);
  border-radius: var(--radius-lg);
  padding: 15px 15px 15px 14px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 14px;
  align-items: center;
}

.step-badge {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--accent);
  color: #101010;
  font-weight: 700;
  font-size: 1.2rem;
}

.step-title {
  margin: 0;
  font-size: 1rem;
  font-weight: 500;
}

.step-action,
.support-button {
  border: none;
  background: var(--accent);
  color: #0b0b0b;
  cursor: pointer;
  transition: transform 120ms ease, filter 120ms ease;
}

.step-action {
  border-radius: var(--radius-pill);
  min-width: 112px;
  padding: 12px 18px;
  font-weight: 600;
}

.step-selector {
  position: relative;
}

.step-select-trigger {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  justify-content: center;
}

.step-select-chevron {
  width: 9px;
  height: 9px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-1px);
  transition: transform 160ms ease;
}

.step-select-trigger[aria-expanded="true"] .step-select-chevron {
  transform: rotate(-135deg) translateY(-1px);
}

.step-select-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 132px;
  padding: 8px;
  border-radius: 18px;
  background: rgba(36, 36, 36, 0.98);
  box-shadow: 0 14px 36px rgba(0, 0, 0, 0.28);
  opacity: 0;
  transform: translateY(-8px) scale(0.96);
  transform-origin: top right;
  pointer-events: none;
  transition:
    opacity 160ms ease,
    transform 180ms ease;
  z-index: 8;
}

.step-select-menu.is-open {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

.step-select-option {
  width: 100%;
  padding: 10px 12px;
  border: none;
  border-radius: 12px;
  background: transparent;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.step-select-option[hidden] {
  display: none;
}

.step-select-option.is-selected {
  background: rgba(1, 189, 183, 0.14);
  color: var(--accent);
}

.fallback {
  text-align: center;
  padding-top: 20px;
}

.fallback-copy {
  margin: 0 0 20px;
  color: var(--text);
  font-size: 1rem;
  line-height: 1.45;
}

.fallback-copy--compact {
  margin-bottom: 14px;
}

.link-button {
  background: none;
  border: none;
  padding: 0;
  color: var(--accent);
  font-weight: 700;
  cursor: pointer;
}

.support-button {
  background: var(--panel-3);
  color: var(--text);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--radius-pill);
  padding: 14px 26px;
  min-width: 232px;
}

.support-button--compact {
  margin-top: 0;
}

.status-message {
  min-height: 1.5em;
  margin: 14px 0 0;
  color: var(--muted);
  font-size: 0.95rem;
  text-align: center;
  position: relative;
  z-index: 2;
}

.screen-actions {
  display: none;
}

.screen-actions.is-active {
  display: block;
  margin-top: 20px;
  text-align: center;
}

.back-button {
  border: 1px solid rgba(1, 189, 183, 0.32);
  border-radius: 22px;
  background:
    linear-gradient(180deg, rgba(1, 189, 183, 0.2) 0%, rgba(1, 189, 183, 0.12) 100%),
    #1c2426;
  color: #ffffff;
  box-shadow:
    0 0 0 1px rgba(1, 189, 183, 0.16) inset,
    0 10px 28px rgba(1, 189, 183, 0.12);
  cursor: pointer;
  min-height: 62px;
  padding: 0 18px;
  font-size: 1rem;
  font-weight: 700;
  min-width: 160px;
}

/* ── Hover / active states ── */

.step-action:hover,
.back-button:hover,
.support-button:hover,
.tab:hover,
.link-button:hover,
.step-select-option:hover,
.platform-menu-item:hover,
.platform-menu-copy:hover,
.server-copy:hover,
.quick-link-btn:hover {
  transform: translateY(-1px);
}

.step-action:active,
.back-button:active,
.support-button:active,
.tab:active,
.link-button:active,
.step-select-option:active,
.platform-menu-item:active,
.platform-menu-copy:active,
.server-copy:active,
.quick-link-btn:active {
  transform: translateY(0);
  filter: brightness(0.97);
}

/* ── Keyframes ── */

@keyframes centerFlow {
  0% {
    transform: translateX(-50%) scale(0.96);
  }
  50% {
    transform: translateX(-50%) scale(1.03);
  }
  100% {
    transform: translateX(-50%) scale(1);
  }
}

@keyframes floatFlowerA {
  0% { transform: translate3d(-6px, 8px, 0) scale(0.72) rotate(-10deg); }
  100% { transform: translate3d(10px, -14px, 0) scale(0.79) rotate(-2deg); }
}

@keyframes floatFlowerB {
  0% { transform: translate3d(9px, -4px, 0) scale(0.92) rotate(8deg); }
  100% { transform: translate3d(-12px, 12px, 0) scale(0.98) rotate(16deg); }
}

@keyframes floatFlowerC {
  0% { transform: translate3d(-8px, 10px, 0) scale(0.58) rotate(-16deg); }
  100% { transform: translate3d(9px, -8px, 0) scale(0.66) rotate(-4deg); }
}

@keyframes floatFlowerD {
  0% { transform: translate3d(-10px, 6px, 0) scale(1) rotate(2deg); }
  100% { transform: translate3d(8px, -12px, 0) scale(1.08) rotate(10deg); }
}

@keyframes floatFlowerE {
  0% { transform: translate3d(6px, 8px, 0) scale(0.78) rotate(12deg); }
  100% { transform: translate3d(-10px, -10px, 0) scale(0.86) rotate(22deg); }
}

@keyframes floatFlowerF {
  0% { transform: translate3d(-4px, 12px, 0) scale(0.62) rotate(-14deg); }
  100% { transform: translate3d(10px, -6px, 0) scale(0.69) rotate(-4deg); }
}

@keyframes floatFlowerG {
  0% { transform: translate3d(-50%, 10px, 0) scale(1.12) rotate(0deg); }
  100% { transform: translate3d(-50%, -12px, 0) scale(1.2) rotate(6deg); }
}

@keyframes floatFlowerH {
  0% { transform: translate3d(4px, 6px, 0) scale(0.7) rotate(-6deg); }
  100% { transform: translate3d(-10px, -12px, 0) scale(0.76) rotate(4deg); }
}

@keyframes floatFlowerI {
  0% { transform: translate3d(-6px, 10px, 0) scale(0.88) rotate(14deg); }
  100% { transform: translate3d(12px, -8px, 0) scale(0.95) rotate(22deg); }
}

@keyframes floatFlowerJ {
  0% { transform: translate3d(6px, -6px, 0) scale(0.74) rotate(-12deg); }
  100% { transform: translate3d(-12px, 10px, 0) scale(0.82) rotate(-20deg); }
}

@keyframes floatFlowerK {
  0% { transform: translate3d(-8px, 8px, 0) scale(0.68) rotate(8deg); }
  100% { transform: translate3d(10px, -12px, 0) scale(0.74) rotate(16deg); }
}

@keyframes floatFlowerL {
  0% { transform: translate3d(8px, 10px, 0) scale(0.72) rotate(-8deg); }
  100% { transform: translate3d(-10px, -8px, 0) scale(0.79) rotate(2deg); }
}

/* ── Responsive ── */

@media (max-width: 680px) {
  :root {
    --page-padding: 14px;
    --card-padding: 22px;
  }

  .brand {
    margin-bottom: 22px;
  }

  .brand-text {
    gap: 10px;
  }

  .step {
    grid-template-columns: auto 1fr;
  }

  .step-action,
  .step-selector {
    grid-column: 2;
    justify-self: start;
  }

  .server-item {
    /* Keep status dot in its own right-side column on mobile so the
       row stays "name left / status right", vertically centered via
       the base rule's align-items: center. Was previously 1fr (single
       column) which collapsed the layout and stacked the dot under
       the name. */
    grid-template-columns: 1fr auto auto;
  }

  .server-copy {
    justify-self: start;
  }
}

@media (max-width: 420px) {
  .section-title,
  .platforms-row {
    text-align: center;
  }

  .tabs {
    width: 100%;
    justify-content: center;
    flex-wrap: wrap;
  }

  .platform-switcher {
    width: 100%;
    justify-content: center;
  }

  .platform-menu {
    right: 50%;
    transform: translate(50%, -16px) scale(0.88);
    transform-origin: top center;
    width: min(272px, calc(100vw - 28px));
    padding: 16px 14px 14px;
  }

  .platform-menu.is-open {
    transform: translate(50%, 0) scale(1);
  }

  .brand {
    align-items: center;
  }

  body::before {
    width: min(110vw, 620px);
    height: min(110vw, 620px);
    top: -18%;
  }

  .floating-flower-1,
  .floating-flower-2,
  .floating-flower-3,
  .floating-flower-4,
  .floating-flower-5,
  .floating-flower-6,
  .floating-flower-7,
  .floating-flower-8,
  .floating-flower-9,
  .floating-flower-10,
  .floating-flower-11,
  .floating-flower-12 {
    width: 42px;
    height: 42px;
  }

  .brand-title {
    width: auto;
    height: auto;
    font-size: 36px;
    line-height: 1;
  }

  .brand-pill {
    width: auto;
    min-width: 92px;
    height: 44px;
  }

  .brand-pill-icon {
    width: 92px;
    height: 44px;
  }

  .step-title {
    font-size: 0.95rem;
  }

  .support-button {
    width: 100%;
  }

  .top-bar {
    flex-wrap: wrap;
  }
}

/* ──────────────────────────────────────────────────────────────────
 * Gesture tutorial overlay
 *
 * Plays ONCE ever per install — counter in localStorage under
 * `flwr_tutorial_views`. Two steps; performing the actual gesture OR
 * tapping anywhere advances to the next step. When the taught gesture
 * fires inside the overlay it does *not* execute its normal effect
 * (pull-to-refresh does not reload the page during the tutorial) so
 * users can see both steps in one session.
 *
 * Design notes:
 *  - Backdrop blur is intentionally mild (6px) so the app stays
 *    readable behind the overlay — stronger blur felt "modal"-heavy.
 *  - Arrows live in fixed positions (near the motion start point) to
 *    spatially anchor the gesture. A translucent hand mimics the
 *    finger motion on the same animation cycle.
 *  - Brand accent (#01BDB7 "Flower teal") on arrows matches the
 *    splash/logo color palette — the overlay feels like part of the
 *    app, not a third-party tutorial popup.
 * ────────────────────────────────────────────────────────────────── */
.gesture-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: auto;
}

.gesture-overlay[hidden] {
  display: none;
}

.gesture-overlay.is-leaving {
  animation: gesture-overlay-fade-out 320ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

.gesture-overlay__backdrop {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    circle at 50% 40%,
    rgba(1, 189, 183, 0.08) 0%,
    rgba(5, 8, 18, 0.45) 60%,
    rgba(5, 8, 18, 0.60) 100%
  );
  backdrop-filter: blur(3px) saturate(110%);
  -webkit-backdrop-filter: blur(3px) saturate(110%);
  animation: gesture-backdrop-fade-in 380ms cubic-bezier(0.4, 0, 0.2, 1) both;
}

/* ── Step container ── each step is absolute-positioned so we can place
   the arrow near the motion start (top-center for pull, left-middle for
   swipe) instead of stacking everything mid-screen. */
.gesture-step {
  position: absolute;
  inset: 0;
  pointer-events: none; /* taps propagate to the overlay for "advance" */
  animation: gesture-step-fade-in 380ms cubic-bezier(0.25, 0.1, 0.25, 1) both;
}

.gesture-step[hidden] {
  display: none;
}

/* ── Arrow — animates along the gesture axis. */
.gesture-step__arrow {
  position: absolute;
  color: #01BDB7;
  filter: drop-shadow(0 0 10px rgba(1, 189, 183, 0.55));
}

/* Pull arrow sits in the top quarter of the screen, centered
   horizontally, pointing down. */
.gesture-step__arrow--pull {
  top: 18%;
  left: 50%;
  transform: translateX(-50%);
  animation: gesture-arrow-pull 1.6s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}

/* Swipe arrow sits near the left edge at mid-height, pointing right. */
.gesture-step__arrow--swipe {
  top: 46%;
  left: 22px;
  animation: gesture-arrow-swipe 1.6s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}

/* ── Translucent hand — floats behind the arrow on its own offset so
   the animation reads as "hand holding the screen, moving together".
   Slightly delayed relative to the arrow for visual depth. */
.gesture-step__hand {
  position: absolute;
  opacity: 0.75;
  filter: drop-shadow(0 4px 18px rgba(0, 0, 0, 0.45));
}

.gesture-step__hand--pull {
  top: 28%;
  left: 50%;
  transform: translate(-50%, 0);
  animation: gesture-hand-pull 1.6s cubic-bezier(0.45, 0, 0.55, 1) infinite;
  animation-delay: 120ms;
}

.gesture-step__hand--swipe {
  top: 46%;
  left: 16px;
  animation: gesture-hand-swipe 1.6s cubic-bezier(0.45, 0, 0.55, 1) infinite;
  animation-delay: 120ms;
}

/* ── Caption text — dropped in the lower third so it doesn't crowd
   the gesture animation. Soft drop-shadow keeps it readable over
   the blurred app. */
.gesture-step__text {
  position: absolute;
  bottom: 20%;
  /* Width-constrained box that NEVER exceeds the viewport. Earlier
     revision used `left: 50%; transform: translateX(-50%)` with a
     fixed 280px width which clipped on narrow phones (cut off at
     right edge on 360-wide devices). Anchoring to both sides with a
     small horizontal inset + auto margins centers the text while
     guaranteeing no overflow. */
  left: 16px;
  right: 16px;
  text-align: center;
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.45);
  /* Slightly softer / more typographic feel — iOS/Mac pick SF, Android
     picks Roboto, everything else falls back gracefully. ui-rounded
     nudges Safari/Chrome on Apple toward SF Rounded, which matches
     Telegram's own UI. */
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
    ui-rounded, "Inter", "Segoe UI", Roboto, system-ui, sans-serif;
}

.gesture-step__title {
  margin: 0 0 6px 0;
  font-size: 1.25rem;
  font-weight: 500; /* lighter than 600 — airier, more Apple-y */
  letter-spacing: -0.01em;
  color: rgba(255, 255, 255, 0.78); /* toned down from fully opaque */
  word-break: break-word;
}

.gesture-step__hint {
  margin: 0;
  color: rgba(255, 255, 255, 0.55);
  font-size: 0.88rem;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0.01em;
  word-break: break-word;
}

.gesture-overlay__skip {
  position: absolute;
  bottom: 26px;
  left: 0;
  right: 0;
  margin: 0;
  padding: 8px 14px;
  color: rgba(255, 255, 255, 0.38);
  font-size: 0.78rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  text-align: center;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
  animation: gesture-step-fade-in 600ms 400ms ease-out both;
}

/* ── Animations ── */
@keyframes gesture-arrow-pull {
  0%   { transform: translate(-50%, -12px); opacity: 0.3; }
  40%  { opacity: 1; }
  60%  { opacity: 1; }
  100% { transform: translate(-50%, 20px); opacity: 0.3; }
}

@keyframes gesture-hand-pull {
  0%   { transform: translate(-50%, -16px); opacity: 0.4; }
  40%  { opacity: 0.85; }
  60%  { opacity: 0.85; }
  100% { transform: translate(-50%, 24px); opacity: 0.4; }
}

@keyframes gesture-arrow-swipe {
  0%   { transform: translateX(-8px); opacity: 0.3; }
  40%  { opacity: 1; }
  60%  { opacity: 1; }
  100% { transform: translateX(18px); opacity: 0.3; }
}

@keyframes gesture-hand-swipe {
  0%   { transform: translateX(-12px); opacity: 0.4; }
  40%  { opacity: 0.85; }
  60%  { opacity: 0.85; }
  100% { transform: translateX(22px); opacity: 0.4; }
}

@keyframes gesture-step-fade-in {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

.gesture-step__text { animation: gesture-step-fade-in 520ms 120ms cubic-bezier(0.25, 0.1, 0.25, 1) both; }

@keyframes gesture-backdrop-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes gesture-overlay-fade-out {
  to { opacity: 0; }
}

/* ──────────────────────────────────────────────────────────────────
 * Pull-to-refresh indicator
 *
 * A 40-px circle that holds our Flower-VPN mono-logo and rotates on
 * release. The rotation is 360° continuous while the actual refresh
 * runs, and a spring-eased translate when the finger is still on the
 * screen (the circle "follows" the drag). Brand-teal background +
 * subtle glow so it feels part of the app, not a generic spinner.
 * ────────────────────────────────────────────────────────────────── */
.pull-indicator {
  position: fixed;
  top: 0;
  left: 50%;
  transform: translate(-50%, -100%);
  z-index: 10000;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(circle at 50% 40%, rgba(1, 189, 183, 0.18) 0%, rgba(15, 20, 35, 0.92) 70%);
  border: 1px solid rgba(1, 189, 183, 0.35);
  border-radius: 50%;
  box-shadow: 0 8px 28px rgba(1, 189, 183, 0.22), 0 2px 10px rgba(0, 0, 0, 0.35);
  transition: transform 220ms cubic-bezier(0.25, 0.8, 0.25, 1.3), opacity 180ms ease-out;
  opacity: 0;
  pointer-events: none;
}

.pull-indicator.is-visible {
  opacity: 1;
}

.pull-indicator__logo {
  width: 22px;
  height: 22px;
  color: #01BDB7;
  display: flex;
  align-items: center;
  justify-content: center;
}

.pull-indicator__logo svg {
  width: 100%;
  height: 100%;
  display: block;
}

.pull-indicator.is-refreshing .pull-indicator__logo {
  animation: pull-indicator-spin 900ms cubic-bezier(0.45, 0, 0.55, 1) infinite;
}

@keyframes pull-indicator-spin {
  to { transform: rotate(360deg); }
}

/* Screen-transition animations removed 2026-04-22.
 * Users reported the push/pop + pre-reload dim felt "sluggish" on their
 * phone — the 260-300 ms wait before the actual action fired made the
 * gestures feel unresponsive. Reverted to instant navigation + instant
 * soft-refresh; re-introduce with shorter durations (≤120 ms) only if
 * we can confirm a genuine responsiveness win. */

/* ── Subscription hub (owner preview) — ported from flowervpn.pro cabinet ── */
.subhub {
  display: flex;
  flex-direction: column;
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Inter", sans-serif;
}
.subhub-ico-svg { width: 19px; height: 19px; flex: 0 0 auto; }
.subhub-title .subhub-ico-svg { width: 24px; height: 24px; }
.subhub-screen-title {
  text-align: center;
  font-size: 30px;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--text);
  margin: 4px 0 22px;
}

/* ── Subscription hub header: top back-link + iconed title + dotted subtitle
   (mirrors the tariff-builder header, adapted to the hub content) ── */
#subHubView > .subhub-backlink { margin: 2px auto 12px; }
.subhub-header { text-align: center; margin: 0 0 22px; }
.subhub-header .subhub-screen-title {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 11px;
  margin: 0 0 8px;
}
.subhub-title-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
}
.subhub-title-ico svg { width: 28px; height: 28px; }
.subhub-screen-sub {
  margin: 0;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--muted);
}
.subhub-card {
  background: var(--panel);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: var(--radius-xl);
  padding: 22px;
}
.subhub-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.subhub-plan { display: inline-flex; align-items: center; gap: 9px; }
.subhub-dot {
  width: 10px; height: 10px; border-radius: 999px;
  background: #34d399;
  box-shadow: 0 0 8px rgba(52, 211, 153, 0.8);
}
.subhub-plan-label {
  font-size: 14px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.04em;
  color: #34d399;
}
.subhub-state {
  font-size: 12px; font-weight: 700;
  color: #34d399;
  background: rgba(52, 211, 153, 0.12);
  padding: 5px 13px; border-radius: var(--radius-pill);
}
.subhub-title {
  display: flex; align-items: center; gap: 9px;
  margin: 14px 0 4px;
  font-size: 26px; font-weight: 800; letter-spacing: -0.01em;
  color: var(--text);
}
.subhub-sparkle { color: var(--accent); font-size: 22px; line-height: 1; }
.subhub-meta { margin: 0; font-size: 14px; color: var(--muted); }
.subhub-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 18px; }
.subhub-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%; padding: 15px 20px;
  border-radius: var(--radius-pill);
  font-size: 16px; font-weight: 600;
  cursor: pointer; border: 1px solid transparent;
  transition: filter .15s ease, background .15s ease, border-color .15s ease, transform .05s ease;
}
.subhub-btn:active { transform: scale(0.99); }
.subhub-btn-primary {
  /* same bright teal as "Вернуться назад"; dark text + icon (via currentColor) */
  background: linear-gradient(180deg, var(--accent-strong), var(--accent));
  color: #04201f;
  box-shadow: 0 10px 30px rgba(1, 189, 183, 0.28);
}
.subhub-btn-primary:hover { filter: brightness(1.05); }
.subhub-btn-outline {
  background: transparent;
  color: var(--accent-strong);
  border-color: rgba(1, 189, 183, 0.45);
}
.subhub-btn-outline:hover { background: rgba(1, 189, 183, 0.08); }
.subhub-btn-ico { font-size: 16px; line-height: 1; }

/* ── Subscription hub mode: hide the tariff-builder footer/leftovers that the
   purchase.css `.active-sub:not([hidden]) ~ …` rules stop hiding once the
   active-sub view is hidden. Symmetric to body.tariff-mode. ── */
body.subhub-mode .trial-banner,
body.subhub-mode .back-to-sub,
body.subhub-mode #priceCard,
body.subhub-mode .payment-icons,
body.subhub-mode #purchaseSubmitButton,
body.subhub-mode #promoRow,
body.subhub-mode .tariff-header,
body.subhub-mode #durationSection,
body.subhub-mode #deviceSliderRow,
body.subhub-mode #tariffFlowers,
body.subhub-mode #quickLinks,
body.subhub-mode .status-message { display: none !important; }

/* "Вернуться назад" — teal pill at the bottom of the hub (matches site) */
.subhub-back {
  display: block;
  align-self: center;
  width: calc(100% - 44px);
  margin: 22px auto 8px;
  padding: 16px 20px;
  border: none;
  border-radius: var(--radius-pill);
  background: linear-gradient(180deg, var(--accent-strong), var(--accent));
  color: #04201f;
  font-size: 17px;
  font-weight: 800;
  cursor: pointer;
  box-shadow: 0 14px 36px rgba(1, 189, 183, 0.35);
  transition: filter .15s ease, transform .05s ease;
}
.subhub-back:hover { filter: brightness(1.05); }
.subhub-back:active { transform: scale(0.99); }

/* ── Subscription hub: "gift a subscription" mini-section ── */
.subhub-gift {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  margin-top: 14px;
  padding: 16px 18px;
  background: var(--panel);
  border: 1px solid rgba(1, 189, 183, 0.16);
  border-radius: var(--radius-lg);
  cursor: pointer;
  text-align: left;
  transition: background .15s ease, border-color .15s ease, transform .05s ease;
}
.subhub-gift:hover { background: rgba(1, 189, 183, 0.05); border-color: rgba(1, 189, 183, 0.3); }
.subhub-gift:active { transform: scale(0.995); }
.subhub-gift-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; flex: 0 0 auto;
  border-radius: 13px;
  background: rgba(1, 189, 183, 0.12);
  color: var(--accent);
}
.subhub-gift-ico svg { width: 22px; height: 22px; }
.subhub-gift-text { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-width: 0; }
.subhub-gift-title { font-size: 16px; font-weight: 700; color: var(--text); }
.subhub-gift-sub { font-size: 13px; color: var(--muted); }
.subhub-gift-chev { color: var(--muted); display: inline-flex; flex: 0 0 auto; }
.subhub-gift-chev svg { width: 20px; height: 20px; }

/* ── Subscription hub: "add devices" screen (reuses the dark tariff-builder design) ── */
/* Add-device slots: owned slots are checkmarked + locked (already paid for) */
.device-chip.is-owned {
  position: relative;
  cursor: default;
  border-color: rgba(1, 189, 183, 0.35);
  background: linear-gradient(180deg, rgba(1, 189, 183, 0.10), transparent);
}
.device-chip.is-owned:hover { border-color: rgba(1, 189, 183, 0.35); }
.device-chip.is-owned .device-chip-label { color: var(--accent); }
.device-chip-check {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 15px;
  height: 15px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--accent);
  color: #04201f;
}
.device-chip-check svg { width: 10px; height: 10px; }

/* Gated pay button — dim + non-clickable for trial / admin-grant / max */
.subhub-btn-primary.is-disabled,
.subhub-btn-primary:disabled {
  background: rgba(1, 189, 183, 0.18);
  color: rgba(230, 255, 253, 0.55);
  box-shadow: none;
  filter: none;
  cursor: not-allowed;
}
.subhub-btn-primary.is-disabled:hover,
.subhub-btn-primary:disabled:hover { filter: none; }
.add-block-hint {
  margin: 12px 2px 0;
  text-align: center;
  font-size: 13px;
  line-height: 1.45;
  color: var(--muted);
}

#subHubAddView .subhub-add-sub {
  margin: -8px 0 22px;
  text-align: center;
  font-size: 14px;
  line-height: 1.45;
  color: var(--muted);
}
#subHubAddView .tariff-section { display: block; margin-bottom: 20px; }
#subHubAddView .tariff-section[hidden] { display: block; }
#subHubAddView .promo-row { display: block; margin-bottom: 4px; }
#subHubAddView .price-card { display: flex !important; margin: 0 0 14px; }
#subHubAddView .subhub-btn-primary { margin-top: 2px; }
#subHubAddView .subhub-back { margin-top: 16px; }

/* "← Вернуться назад" link (mirrors .back-to-sub, used in hub sub-screens) */
.subhub-backlink {
  display: block;
  align-self: center;
  margin: 0 auto 14px;
  padding: 6px 4px;
  border: none;
  background: none;
  color: var(--accent);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 120ms;
}
.subhub-backlink:hover { opacity: 0.8; }

/* ── Gift VPN: instruction card + actions ── */
.gift-info {
  background: rgba(1, 189, 183, 0.06);
  border: 1px solid rgba(1, 189, 183, 0.18);
  border-radius: var(--radius-lg);
  padding: 18px 18px 16px;
  margin-bottom: 18px;
}
.gift-info-title {
  display: flex; align-items: center; gap: 9px;
  margin: 0 0 13px;
  font-size: 16px; font-weight: 700; color: var(--text);
}
.gift-info-ico { display: inline-flex; color: var(--accent); }
.gift-info-ico svg { width: 20px; height: 20px; }
.gift-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 11px; }
.gift-steps li { display: flex; align-items: flex-start; gap: 11px; font-size: 14px; line-height: 1.4; color: var(--muted); }
.gift-step-n {
  flex: 0 0 auto; width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: rgba(1, 189, 183, 0.14); color: var(--accent-strong);
  font-size: 12px; font-weight: 800;
}
/* ── My gifts: list rows with status ── */
.gift-row {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px;
  background: var(--panel);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: var(--radius-md);
  margin-bottom: 10px;
}
.gift-row-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.gift-row-code { font-size: 15px; font-weight: 700; color: var(--text); }
.gift-row-meta { font-size: 12.5px; color: var(--muted); }
.gift-row-status {
  display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto;
  font-size: 12px; font-weight: 700; padding: 5px 11px; border-radius: 999px;
}
.gift-row-status svg { width: 14px; height: 14px; }
.gift-row-status.is-used { color: #34d399; background: rgba(52, 211, 153, 0.12); }
.gift-row-status.is-pending { color: var(--muted); background: rgba(255, 255, 255, 0.05); }
.gift-empty { text-align: center; color: var(--muted); font-size: 14px; padding: 34px 10px; }

/* ── My gifts: truncated share link + copy button ── */
.gift-row-linkrow { display: flex; align-items: center; gap: 8px; }
.gift-row-link {
  font-size: 15px; font-weight: 700; color: var(--text);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  letter-spacing: 0.02em;
}
.gift-copy {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0; flex: 0 0 auto;
  border: 1px solid rgba(1, 189, 183, 0.3);
  background: rgba(1, 189, 183, 0.08);
  color: var(--accent);
  border-radius: 8px; cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.gift-copy:hover { background: rgba(1, 189, 183, 0.16); }
.gift-copy svg { width: 15px; height: 15px; }
.gift-copy.is-copied { color: #34d399; border-color: rgba(52, 211, 153, 0.4); background: rgba(52, 211, 153, 0.12); }
