@font-face {
  font-family: "Inter Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/fonts/inter/inter-cyrillic-ext-wght-normal.woff2")
    format("woff2");
  unicode-range:
    U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F,
    U+FE2E-FE2F;
}
@font-face {
  font-family: "Inter Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/fonts/inter/inter-cyrillic-wght-normal.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Inter Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/fonts/inter/inter-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
    U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}
@font-face {
  font-family: "Inter Variable";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("/fonts/inter/inter-latin-wght-normal.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Inter Variable";
  font-style: italic;
  font-display: swap;
  font-weight: 100 900;
  src: url("/fonts/inter/inter-cyrillic-ext-wght-italic.woff2")
    format("woff2");
  unicode-range:
    U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F,
    U+FE2E-FE2F;
}
@font-face {
  font-family: "Inter Variable";
  font-style: italic;
  font-display: swap;
  font-weight: 100 900;
  src: url("/fonts/inter/inter-cyrillic-wght-italic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Inter Variable";
  font-style: italic;
  font-display: swap;
  font-weight: 100 900;
  src: url("/fonts/inter/inter-latin-ext-wght-italic.woff2") format("woff2");
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
    U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}
@font-face {
  font-family: "Inter Variable";
  font-style: italic;
  font-display: swap;
  font-weight: 100 900;
  src: url("/fonts/inter/inter-latin-wght-italic.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
    U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
:root {
  --ui-bg: #f7d7e8;
  --ui-card: rgba(255, 255, 255, 0.62);
  --ui-card-raised: rgba(255, 255, 255, 0.78);
  --ui-text: #2b1020;
  --ui-text-2: #3f1f32;
  --ui-hint: rgba(43, 16, 32, 0.58);
  --ui-section-header: rgba(43, 16, 32, 0.52);
  --ui-separator: rgba(43, 16, 32, 0.12);
  --ui-accent: #e662a5;
  --ui-accent-strong: #d94f98;
  --ui-accent-text: #ffffff;
  --ui-accent-soft: rgba(230, 98, 165, 0.16);
  --ui-pro: #823bf5;
  --ui-destructive: #ff3b30;
  --ui-confirm: #34c759;
  --ui-switch-on: #34c759;
  --ui-switch-thumb: #fcf0f6;
  --ui-fill: rgba(120, 120, 128, 0.1);
  --ui-fill-2: rgba(120, 120, 128, 0.16);
  --ui-fill-3: rgba(120, 120, 128, 0.22);
  --ui-hover: rgba(0, 0, 0, 0.035);
  --ui-press: rgba(0, 0, 0, 0.07);
  --ui-radius-card: 22px;
  --ui-radius-field: 14px;
  --ui-radius-pill: 999px;
  --ui-font-apple:
    system-ui, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial,
    sans-serif;
  --ui-font-inter:
    "Inter Variable", "Inter", system-ui, -apple-system, BlinkMacSystemFont,
    "Roboto", "Helvetica Neue", "Segoe UI", Arial, sans-serif;
  --ui-font: var(--ui-font-apple);
  --ui-font-display: var(--ui-font);
  --ui-ease: cubic-bezier(0.25, 0.1, 0.25, 1);
  --ui-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ui-ease-nav: cubic-bezier(0.33, 1, 0.68, 1);
  --ui-dur: 0.18s;
  --ui-dur-screen: 0.42s;
  --ui-safe-top: 0px;
  --ui-safe-bottom: 0px;
  --ui-fullscreen-top: 0px;
  /* Высота верхней вуали (body:before) — ЕДИНСТВЕННАЯ ручка «выше/ниже панель».
     Пропорциональная часть с множителем 0.906 (−20%, +10%, +3%, 2026-07-28) не
     тронута: именно она подобрана под нативные кнопки Telegram (Close/⌄/⋯) и
     заголовок экрана. Множитель стоит СНАРУЖИ min(), чтобы обе ветки (обычная и
     потолок в 3×) менялись одинаково.
     Сверху добавлена АБСОЛЮТНАЯ полоса `--ui-veil-pill-row` (2026-07-30, просьба
     юзера «сделай панель чуть больше»): в ней и только в ней живёт плашка с
     токенами. Добавка абсолютная, а не процент, потому что плашка фиксированной
     высоты — при масштабировании она то не влезала бы, то болталась.
     Вынесено в переменную, потому что от низа вуали позиционируется
     .impito-token-pill. */
  /* Пропорциональная часть вуали вынесена отдельно: её переопределяет режим
     `impito-flat-top` (Telegram Desktop, где нативных инсетов нет вовсе). */
  --ui-veil-base: calc(
    min(
        var(--ui-fullscreen-top) * 1.5 + var(--ui-veil-extra, 5px) +
          var(--ui-veil-platform, 0px),
        var(--ui-fullscreen-top) * 3
      ) * 0.906
  );
  --ui-veil-pill-row: 22px;
  /* Насколько плашка залезает ВЫШЕ кромки пропорциональной части вуали
     (2026-07-30, «подними вплотную под кнопку»). Считано по скриншоту юзера
     (375pt / 3x): низ нативной кнопки ⌄⋯ на ≈97px, плашка стояла на 122 —
     зазор был 25px. Подъём на 14px оставляет ≈8px. Это единственная ручка
     зазора; если на другом устройстве плашка полезет на кнопку — уменьшать. */
  --ui-veil-pill-lift: 15px;
  --ui-veil-height: calc(var(--ui-veil-base) + var(--ui-veil-pill-row));
  --ui-keyboard: 0px;
  --ui-cta-bar-height: 84px;
}
html[data-font-platform="apple"] {
  --ui-font: var(--ui-font-apple);
  --ui-font-display: var(--ui-font);
}
html[data-font-platform="inter"] {
  --ui-font: var(--ui-font-inter);
  --ui-font-display: var(--ui-font);
  /* Android veil is 10px taller on both screens; iPhone keeps the base size. */
  --ui-veil-platform: 10px;
}
[data-theme="dark"] {
  --ui-bg: #f7d7e8;
  --ui-card: rgba(255, 255, 255, 0.62);
  --ui-card-raised: rgba(255, 255, 255, 0.78);
  --ui-text: #2b1020;
  --ui-text-2: #3f1f32;
  --ui-hint: rgba(43, 16, 32, 0.58);
  --ui-section-header: rgba(43, 16, 32, 0.52);
  --ui-separator: rgba(43, 16, 32, 0.12);
  --ui-accent: #e662a5;
  --ui-accent-strong: #d94f98;
  --ui-accent-soft: rgba(230, 98, 165, 0.16);
  --ui-destructive: #ff453a;
  --ui-fill: rgba(120, 120, 128, 0.2);
  --ui-fill-2: rgba(120, 120, 128, 0.28);
  --ui-fill-3: rgba(120, 120, 128, 0.36);
  --ui-hover: rgba(255, 255, 255, 0.06);
  --ui-press: rgba(255, 255, 255, 0.1);
}
html {
  -webkit-tap-highlight-color: transparent;
  background: var(--ui-bg);
}
.ui-page {
  width: min(100%, 560px);
  margin: 0 auto;
  padding: calc(14px + var(--ui-safe-top)) 0 calc(32px + var(--ui-safe-bottom));
  font-family: var(--ui-font);
  color: var(--ui-text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
.ui-page * {
  box-sizing: border-box;
}
/* Подложка под весь вьюпорт: если нативный фон вебвью слетел в белый
   (iOS после expand), резиновый оверскролл всё равно остаётся розовым. */
body:after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--ui-bg);
  pointer-events: none;
}
body:before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 40;
  height: var(--ui-veil-height);
  pointer-events: none;
  /* Плоская матовая шапка вместо градиентного растворения (2026-07-28, как в
     настройках iOS): ровная подложка + блюр + волосяная линия снизу.
     Подложка держит 88% непрозрачности не «на глаз»: iOS первые кадры после
     reload рисует слой ещё без backdrop-filter, и прозрачное стекло дало бы
     белую вспышку — та же причина, что у розового тумана таббара. */
  background: color-mix(in srgb, var(--ui-bg) 80%, transparent);
  -webkit-backdrop-filter: blur(6px) saturate(140%);
  backdrop-filter: blur(6px) saturate(140%);
  box-shadow: 0 0.5px 0 rgba(43, 16, 32, 0.1);
}
.ui-fade-bottom:before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -34px;
  bottom: 0;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    transparent 0%,
    color-mix(in srgb, var(--ui-bg) 30%, transparent) 30%,
    color-mix(in srgb, var(--ui-bg) 78%, transparent) 56%,
    var(--ui-bg) 80%
  );
}
.ui-page-head {
  padding: 18px 22px 14px;
}
.ui-page-title {
  margin: 0;
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.ui-page-sub {
  margin: 5px 0 0;
  color: var(--ui-hint);
  font-size: 15px;
  font-weight: 400;
  line-height: 1.35;
}
.ui-section {
  margin-bottom: 24px;
}
.ui-section-header {
  display: block;
  margin: 0 0 9px;
  padding: 0 22px;
  color: var(--ui-section-header);
  font-size: 13px;
  font-weight: 510;
  letter-spacing: 0.02em;
  line-height: 1.2;
}
.ui-section-footer {
  display: block;
  margin: 9px 0 0;
  padding: 0 22px;
  color: var(--ui-hint);
  font-size: 13px;
  line-height: 1.35;
}
.ui-section--accent .ui-section-header {
  color: var(--ui-accent);
}
.ui-section--accent .ui-card {
  background: var(--ui-accent-soft);
}
.ui-card {
  margin: 0 12px;
  overflow: visible;
  border-radius: var(--ui-radius-card);
  /* No backdrop-filter here: iOS composites backdrop-filter elements over a
     blank (white) backdrop during page-load/route animations, flashing the
     cards white. Plain translucent paint over the page gradient looks the
     same and composites correctly in every frame. */
  background: var(--ui-card);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.28) inset;
}
.ui-row {
  position: relative;
  display: flex;
  width: 100%;
  align-items: center;
  gap: 14px;
  min-height: 54px;
  padding: 13px 18px;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
}
.ui-row + .ui-row:before {
  content: "";
  position: absolute;
  top: 0;
  left: 18px;
  right: 0;
  height: 1px;
  background: var(--ui-separator);
  transform: scaleY(0.5);
  transform-origin: top;
  transition: opacity var(--ui-dur) var(--ui-ease);
}
.ui-row--interactive {
  cursor: pointer;
}
.ui-row--interactive:after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: var(--ui-press);
  opacity: 0;
  transition: opacity var(--ui-dur) var(--ui-ease);
  pointer-events: none;
}
/* The card keeps overflow: visible, so round the press highlight on the
   edge rows — otherwise its square corners poke past the card radius. */
.ui-row--interactive:first-child:after {
  border-top-left-radius: var(--ui-radius-card);
  border-top-right-radius: var(--ui-radius-card);
}
.ui-row--interactive:last-child:after {
  border-bottom-left-radius: var(--ui-radius-card);
  border-bottom-right-radius: var(--ui-radius-card);
}
@media (hover: hover) {
  .ui-row--interactive:hover:after {
    background: var(--ui-hover);
    opacity: 1;
  }
}
.ui-row--interactive:active:after {
  background: var(--ui-press);
  opacity: 1;
}
.ui-row--interactive:active:before,
.ui-row--interactive:active + .ui-row:before {
  opacity: 0;
}
@media (hover: hover) {
  .ui-row--interactive:hover:before,
  .ui-row--interactive:hover + .ui-row:before {
    opacity: 0;
  }
}
.ui-row-before,
.ui-row-body,
.ui-row-after {
  position: relative;
  z-index: 1;
}
.ui-row-press {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 0;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.ui-row--actionable > .ui-row-before,
.ui-row--actionable > .ui-row-body,
.ui-row--actionable > .ui-row-after {
  pointer-events: none;
}
.ui-row-before {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  color: var(--ui-accent);
}
.ui-row-body {
  display: flex;
  min-width: 0;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 2px;
}
.ui-row-overline {
  color: var(--ui-hint);
  font-size: 13px;
  font-weight: 400;
  line-height: 1.2;
}
.ui-row-title {
  color: var(--ui-text);
  font-size: 17px;
  font-weight: 400;
  letter-spacing: -0.01em;
  line-height: 1.3;
}
.ui-row--accent .ui-row-title {
  color: var(--ui-accent);
}
.ui-row-subtitle {
  color: var(--ui-hint);
  font-size: 13.5px;
  font-weight: 400;
  line-height: 1.3;
}
.ui-row-after {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 8px;
  color: var(--ui-hint);
  font-size: 17px;
  white-space: nowrap;
}
.ui-row-value {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--ui-text);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.ui-modelpicker-head {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.ui-row--locked {
  opacity: 0.5;
}
.ui-modelpicker-lock {
  color: var(--ui-pro);
  font-size: 13px;
  font-weight: 600;
}
.ui-modelpicker-check {
  display: inline-flex;
  color: var(--ui-accent);
}
.ui-amount {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--ui-text);
  font-size: 23px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.ui-amount svg,
.ui-row-value svg {
  color: var(--ui-accent);
  flex: 0 0 auto;
}
.ui-submit {
  padding: 8px 22px 0;
}
.ui-field {
  display: block;
  width: 100%;
  min-height: 92px;
  padding: 15px 18px;
  border: 0;
  outline: none;
  background: none;
  color: var(--ui-text);
  font-family: var(--ui-font);
  font-size: 17px;
  line-height: 1.45;
  resize: none;
}
.ui-field--short {
  min-height: 66px;
}
.ui-field--input {
  min-height: 0;
}
.ui-field::placeholder {
  color: var(--ui-hint);
  opacity: 1;
}
.ui-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 40px;
  padding: 0 20px;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: var(--ui-accent);
  color: var(--ui-accent-text);
  cursor: pointer;
  font-family: var(--ui-font);
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  transition:
    background var(--ui-dur) var(--ui-ease),
    transform var(--ui-dur) var(--ui-ease),
    opacity var(--ui-dur) var(--ui-ease);
}
@media (hover: hover) {
  .ui-button:hover:not(:disabled) {
    background: var(--ui-accent-strong);
  }
}
.ui-button:active:not(:disabled) {
  transform: scale(0.97);
}
.ui-button:disabled {
  cursor: default;
  opacity: 0.5;
}
.ui-button--large {
  width: 100%;
  height: 52px;
  font-size: 17px;
}
.ui-button--tinted {
  background: var(--ui-accent-soft);
  color: var(--ui-accent);
}
@media (hover: hover) {
  .ui-button--tinted:hover:not(:disabled) {
    background: var(--ui-accent-soft);
    filter: brightness(0.96);
  }
}
.ui-cta {
  position: relative;
  padding: 1.6px;
  border-radius: var(--ui-radius-pill);
  background: linear-gradient(
    110deg,
    #f07bb7 0%,
    #f49aca 25%,
    #f07bb7 50%,
    #f49aca 75%,
    #f07bb7 100%
  );
  background-size: 280% 100%;
  animation: ui-shimmer 5s linear infinite;
  transition: padding var(--ui-dur) var(--ui-ease);
}
.ui-cta > .ui-button {
  width: 100%;
}
.ui-cta--off {
  padding: 0;
  background: none;
  animation: none;
}
.ui-cta-spacer {
  height: calc(var(--ui-cta-bar-height, 84px) + var(--ui-keyboard));
}
.ui-cta-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  padding: 14px 12px calc(14px + var(--ui-safe-bottom));
  pointer-events: none;
  transform: translateY(
    min(0px, var(--ui-safe-bottom, 0px) - var(--ui-keyboard, 0px))
  );
  transition: transform 0.28s var(--ui-ease-nav);
  will-change: transform;
}
.ui-cta-bar-inner {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(100%, 560px);
  margin: 0 auto;
  pointer-events: auto;
}
.ui-cta-bar-inner .ui-notice {
  margin-top: 0;
  margin-bottom: 9px;
}
@keyframes ui-shimmer {
  to {
    background-position: 280% 0;
  }
}
.ui-icon-button {
  display: inline-grid;
  width: 38px;
  height: 38px;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ui-hint);
  cursor: pointer;
  transition:
    background var(--ui-dur) var(--ui-ease),
    color var(--ui-dur) var(--ui-ease),
    transform var(--ui-dur) var(--ui-ease);
}
@media (hover: hover) {
  .ui-icon-button:hover {
    background: var(--ui-hover);
  }
}
.ui-icon-button:active {
  transform: scale(0.9);
}
.ui-draglist {
  position: relative;
  margin: 0 12px 24px;
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
}
.ui-draglist-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 54px;
  padding: 13px 16px 13px 6px;
  transition: transform var(--ui-dur) var(--ui-ease);
}
.ui-draglist-row + .ui-draglist-row:before {
  content: "";
  position: absolute;
  top: 0;
  left: 46px;
  right: 0;
  height: 1px;
  background: var(--ui-separator);
  transform: scaleY(0.5);
  transform-origin: top;
  transition: opacity var(--ui-dur) var(--ui-ease);
}
.ui-draglist[data-dragging] .ui-draglist-row:before {
  opacity: 0;
}
.ui-draglist-row--lifted {
  z-index: 5;
  background: var(--ui-card-raised);
  border-radius: 14px;
  box-shadow: 0 8px 22px #00000038;
  transition: none;
}
.ui-drag-handle {
  display: inline-grid;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  margin: -2px 0;
  place-items: center;
  color: var(--ui-hint);
  cursor: grab;
  touch-action: none;
}
.ui-drag-handle:active {
  cursor: grabbing;
}
.ui-chip {
  display: inline-flex;
  max-width: 100%;
  height: 36px;
  align-items: center;
  padding: 0 15px;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: var(--ui-fill);
  color: var(--ui-text);
  cursor: pointer;
  font-family: var(--ui-font);
  font-size: 15px;
  font-weight: 500;
  white-space: nowrap;
  transition:
    background var(--ui-dur) var(--ui-ease),
    color var(--ui-dur) var(--ui-ease),
    transform var(--ui-dur) var(--ui-ease);
}
@media (hover: hover) {
  .ui-chip:hover {
    background: var(--ui-fill-2);
  }
}
.ui-chip:active {
  transform: scale(0.95);
}
.ui-chip__label {
  overflow: hidden;
  max-width: 240px;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ui-chip--active {
  background: var(--ui-accent);
  color: var(--ui-accent-text);
  font-weight: 600;
}
@media (hover: hover) {
  .ui-chip--active:hover {
    background: var(--ui-accent-strong);
  }
}
.ui-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  padding: 14px 18px 16px;
}
.ui-wheel {
  position: relative;
  overflow: hidden;
  margin: 8px 0 2px;
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    #000 26%,
    #000 74%,
    transparent 100%
  );
  mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    #000 26%,
    #000 74%,
    transparent 100%
  );
}
.ui-wheel:active {
  cursor: grabbing;
}
.ui-wheel-track {
  will-change: transform;
}
.ui-wheel-item {
  display: flex;
  align-items: center;
  justify-content: center;
  perspective: 700px;
}
.ui-wheel-item-inner {
  color: var(--ui-text);
  font-size: 26px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  backface-visibility: hidden;
  will-change: transform, opacity;
}
.ui-wheel-band {
  position: absolute;
  left: 16px;
  right: 16px;
  border-radius: 12px;
  background: var(--ui-fill);
  pointer-events: none;
}
.ui-wheel-presets {
  display: flex;
  gap: 8px;
  padding: 4px 16px 16px;
}
.ui-wheel-preset {
  display: inline-flex;
  flex: 1 1 0;
  min-width: 0;
  height: 34px;
  align-items: center;
  justify-content: center;
  padding: 0 6px;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: var(--ui-fill);
  color: var(--ui-text);
  cursor: pointer;
  font-family: var(--ui-font);
  font-size: 15px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  transition:
    background var(--ui-dur) var(--ui-ease),
    color var(--ui-dur) var(--ui-ease),
    transform var(--ui-dur) var(--ui-ease);
}
@media (hover: hover) {
  .ui-wheel-preset:hover {
    background: var(--ui-fill-2);
  }
  .ui-wheel-preset--active:hover {
    background: var(--ui-accent-soft);
    filter: brightness(0.96);
  }
}
.ui-wheel-preset:active {
  transform: scale(0.94);
}
.ui-wheel-preset--active {
  background: var(--ui-accent-soft);
  color: var(--ui-accent);
  font-weight: 600;
}
.ui-spinner {
  display: inline-block;
  width: 20px;
  height: 20px;
  color: var(--ui-hint);
  animation: ui-spin 0.85s linear infinite;
}
.ui-spinner-track {
  opacity: 0.22;
}
.ui-button .ui-spinner {
  width: 18px;
  height: 18px;
  color: inherit;
}
@keyframes ui-spin {
  to {
    transform: rotate(360deg);
  }
}
.ui-notice {
  margin: 12px 22px 0;
  color: var(--ui-hint);
  font-family: var(--ui-font);
  font-size: 14px;
  line-height: 1.4;
  text-align: center;
}
.ui-notice--error {
  color: var(--ui-destructive);
}
.ui-overlay {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: #0006;
  animation: ui-fade 0.2s var(--ui-ease);
  font-family: var(--ui-font);
  color: var(--ui-text);
}
.ui-overlay,
.ui-overlay * {
  box-sizing: border-box;
}
.ui-overlay--bottom {
  align-items: flex-end;
  padding: 0;
}
@keyframes ui-fade {
  0% {
    opacity: 0;
  }
}
.ui-modal {
  width: min(100%, 360px);
  padding: 22px;
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
  -webkit-backdrop-filter: saturate(180%) blur(18px);
  backdrop-filter: saturate(180%) blur(18px);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.28) inset;
  animation: ui-pop 0.24s var(--ui-ease-out);
}
.ui-modal-title {
  margin: 0 0 12px;
  color: var(--ui-text);
  font-size: 19px;
  font-weight: 700;
  text-align: center;
}
.ui-modal-actions {
  display: flex;
  gap: 10px;
  margin-top: 18px;
}
.ui-modal-actions > * {
  flex: 1 1 0;
}
@keyframes ui-pop {
  0% {
    opacity: 0;
    transform: scale(0.94);
  }
}
.ui-sheet {
  display: flex;
  width: 100%;
  max-height: 80vh;
  flex-direction: column;
  padding: 8px 0 calc(12px + var(--ui-safe-bottom));
  border-radius: 20px 20px 0 0;
  background: var(--ui-card);
  -webkit-backdrop-filter: saturate(180%) blur(18px);
  backdrop-filter: saturate(180%) blur(18px);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.28) inset;
  animation: ui-slide-up 0.28s var(--ui-ease-out);
}
.ui-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 20px 10px;
}
.ui-sheet-title {
  color: var(--ui-text);
  font-size: 17px;
  font-weight: 700;
}
.ui-sheet-body {
  overflow-y: auto;
  padding: 0 8px 4px;
}
@keyframes ui-slide-up {
  0% {
    transform: translateY(100%);
  }
}
.ui-checkbox {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  cursor: pointer;
}
.ui-checkbox-input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.ui-checkbox-box {
  display: inline-grid;
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  place-items: center;
  border-radius: 7px;
  background: var(--ui-fill);
  color: transparent;
  transition:
    background var(--ui-dur) var(--ui-ease),
    color var(--ui-dur) var(--ui-ease);
}
.ui-checkbox-input:checked + .ui-checkbox-box {
  background: var(--ui-accent);
  color: var(--ui-accent-text);
}
.ui-checkbox-input:disabled + .ui-checkbox-box {
  opacity: 0.5;
}
.ui-checkbox-label {
  min-width: 0;
  color: var(--ui-text);
  font-size: 16px;
  line-height: 1.3;
}
.ui-switch {
  position: relative;
  flex: 0 0 auto;
  width: 70px;
  height: 31px;
  padding: 0;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background-color: var(--ui-fill-3);
  cursor: pointer;
  transition: background-color var(--ui-dur) var(--ui-ease);
}
.ui-switch:after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 43px;
  height: 27px;
  border-radius: var(--ui-radius-pill);
  background: var(--ui-switch-thumb);
  box-shadow: 0 1px 3px #0003;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  will-change: transform;
  transition: transform var(--ui-dur) var(--ui-ease);
}
.ui-switch--on {
  background-color: var(--ui-switch-on);
}
.ui-switch--on:after {
  transform: translate3d(23px, 0, 0);
}
.ui-switch:disabled,
.ui-switch[aria-disabled="true"] {
  cursor: default;
  opacity: 0.5;
}
.ui-segmented {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  border-radius: var(--ui-radius-pill);
  background: var(--ui-fill);
}
.ui-segment {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 32px;
  padding: 0 14px;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: none;
  color: var(--ui-hint);
  cursor: pointer;
  font-family: var(--ui-font);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  transition:
    background var(--ui-dur) var(--ui-ease),
    color var(--ui-dur) var(--ui-ease);
}
.ui-segment--active {
  background: var(--ui-card);
  color: var(--ui-text);
  box-shadow: 0 1px 3px #0000001f;
}
.ui-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 8px 24px 22px;
  text-align: center;
}
.ui-hero-emoji {
  display: flex;
  width: 144px;
  height: 144px;
  align-items: center;
  justify-content: center;
  font-size: 116px;
  line-height: 1;
  animation: ui-hero-emoji-in 0.5s var(--ui-ease-out) both;
}
.ui-hero-emoji > * {
  animation: ui-hero-float 4s ease-in-out 0.5s infinite;
}
.ui-hero-emoji canvas,
.ui-hero-emoji svg,
.ui-hero-emoji img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.ui-emoji-img {
  display: block;
  object-fit: contain;
  -webkit-user-drag: none;
  -webkit-user-select: none;
  user-select: none;
  pointer-events: none;
}
.ui-hero-title {
  margin: 16px 0 0;
  color: var(--ui-text);
  font-family: var(--ui-font-display);
  font-size: 36px;
  font-weight: var(--ui-weight-bold);
  letter-spacing: var(--ui-tracking-title);
  line-height: var(--ui-leading-tight);
  animation: ui-hero-rise 0.42s var(--ui-ease-out) 0.06s both;
}
.ui-hero-sub {
  margin: 10px 0 0;
  max-width: 32ch;
  color: var(--ui-hint);
  font-size: var(--ui-size-row);
  line-height: var(--ui-leading-normal);
  animation: ui-hero-rise 0.42s var(--ui-ease-out) 0.12s both;
}
@keyframes ui-hero-emoji-in {
  0% {
    opacity: 0;
    transform: scale(0.5) translateY(10px);
  }
}
@keyframes ui-hero-float {
  0%,
  to {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-7px);
  }
}
@keyframes ui-hero-rise {
  0% {
    opacity: 0;
    transform: translateY(10px);
  }
}
.ui-screen {
  animation-duration: var(--ui-dur-screen);
  animation-timing-function: var(--ui-ease-nav);
  animation-fill-mode: both;
}
.ui-screen--fwd {
  animation-name: ui-screen-in-fwd;
}
.ui-screen--back {
  animation-name: ui-screen-in-back;
}
@keyframes ui-screen-in-fwd {
  0% {
    opacity: 0;
    transform: translate(26px);
  }
}
@keyframes ui-screen-in-back {
  0% {
    opacity: 0;
    transform: translate(-26px);
  }
}
.ui-debug-overlay {
  position: fixed;
  right: 12px;
  top: calc(12px + var(--ui-safe-top));
  z-index: 120;
  display: flex;
  box-sizing: border-box;
  width: min(260px, calc(100vw - 24px));
  flex-direction: column;
  gap: 9px;
  padding: 10px;
  border: 1px solid var(--ui-separator);
  border-radius: 16px;
  background: var(--ui-card);
  -webkit-backdrop-filter: saturate(180%) blur(18px);
  backdrop-filter: saturate(180%) blur(18px);
  box-shadow: 0 14px 36px color-mix(in srgb, var(--ui-text) 16%, transparent);
  color: var(--ui-text);
  font-family: var(--ui-font);
}
.ui-debug-overlay,
.ui-debug-overlay * {
  box-sizing: border-box;
}
.ui-debug-overlay--compact {
  width: auto;
  min-width: 148px;
  gap: 4px;
  padding: 8px 9px;
}
.ui-debug-overlay__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.ui-debug-overlay__title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.2;
}
.ui-debug-overlay__summary {
  color: var(--ui-hint);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
}
.ui-debug-overlay__body {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ui-debug-overlay__field {
  display: grid;
  gap: 4px;
  color: var(--ui-hint);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.03em;
  line-height: 1.2;
  text-transform: uppercase;
}
.ui-debug-overlay__select {
  width: 100%;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--ui-separator);
  border-radius: 10px;
  outline: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background: var(--ui-fill);
  color: var(--ui-text);
  cursor: pointer;
  font-family: var(--ui-font);
  font-size: 13px;
  font-weight: 600;
}
.ui-debug-overlay__button {
  display: inline-flex;
  min-height: 28px;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: var(--ui-fill);
  color: var(--ui-text);
  cursor: pointer;
  font-family: var(--ui-font);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  transition:
    background var(--ui-dur) var(--ui-ease),
    color var(--ui-dur) var(--ui-ease),
    opacity var(--ui-dur) var(--ui-ease),
    transform var(--ui-dur) var(--ui-ease);
}
.ui-debug-overlay__button--primary {
  width: 100%;
  background: var(--ui-accent);
  color: var(--ui-accent-text);
}
@media (hover: hover) {
  .ui-debug-overlay__button:hover:not(:disabled) {
    background: var(--ui-fill-2);
  }
  .ui-debug-overlay__button--primary:hover:not(:disabled) {
    background: var(--ui-accent-strong);
  }
}
.ui-debug-overlay__button:active:not(:disabled) {
  transform: scale(0.96);
}
.ui-debug-overlay__button:disabled {
  cursor: default;
  opacity: 0.55;
}
@media (max-width: 420px) {
  .ui-debug-overlay {
    right: 10px;
    top: calc(10px + var(--ui-safe-top));
    width: min(240px, calc(100vw - 20px));
  }
  .ui-debug-overlay--compact {
    width: auto;
    max-width: calc(100vw - 20px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .ui-cta,
  .ui-overlay,
  .ui-modal,
  .ui-sheet {
    animation: none;
  }
  .ui-hero-emoji,
  .ui-hero-emoji > *,
  .ui-hero-title,
  .ui-hero-sub,
  .ui-screen {
    animation: none !important;
  }
  .ui-cta-bar {
    transition: none;
  }
}
html,
body {
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  background: var(--ui-bg);
  font-family: var(--ui-font);
  overflow-x: hidden;
}
#root {
  min-height: 100vh;
  min-height: 100svh;
}
.ui-page {
  padding-bottom: calc(116px + var(--ui-safe-bottom));
}
.ui-cta-bar {
  bottom: calc(80px + var(--ui-safe-bottom));
}
.ui-cta-spacer {
  height: calc(var(--ui-cta-bar-height, 84px) + 88px + var(--ui-keyboard));
}
.impito-tabbar {
  position: fixed;
  left: 50%;
  bottom: calc(6px + var(--ui-safe-bottom));
  z-index: 80;
  display: flex;
  align-items: stretch;
  width: min(calc(100% - 48px), 504px);
  height: 67px;
  /* Боковые поля больше вертикальных: ползунок шире слота на 10% (THUMB_SLOT_K
     в index.html), и этот перехлёст должен помещаться у крайних вкладок. */
  padding: 5px 9px;
  border: 0;
  border-radius: 34px;
  overflow: visible;
  background: transparent;
  /* Без внешней тени (2026-07-28, просьба юзера) — остались только внутренние
     блики стекла. Панель генерации/оплаты (.impito-style-submit__inner) с
     2026-07-30 живёт по тем же правилам: своя тень убрана, обводка та же.
     Первая строка — волосяная тёмная обводка
     0.5px (на 2x/3x экранах это ровно 1 физический пиксель, тоньше не бывает);
     сделана box-shadow, а не border, чтобы не влезать в геометрию панели. */
  box-shadow:
    0 0 0 0.5px rgba(43, 16, 32, 0.22),
    inset 0 1.2px 1px -0.5px rgba(255, 255, 255, 0.5),
    inset 0 -1px 1px -0.5px rgba(255, 255, 255, 0.22),
    inset 1px 0 1px -0.5px rgba(255, 255, 255, 0.3),
    inset -1px 0 1px -0.5px rgba(255, 255, 255, 0.3),
    inset 0 0 0 0.5px rgba(255, 255, 255, 0.15);
  font-family: var(--ui-font);
  transform: translateX(-50%);
  transition: transform 0.08s var(--ui-ease);
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
}
.impito-tabbar:before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  /* Pink-tinted fog: WebKit composites backdrop-filter a few frames late
     after a reload, so the bare fog must already match the final glass
     color or the bar flashes white on iOS. */
  background: rgba(243, 227, 237, 0.9);
  -webkit-backdrop-filter: blur(1px) saturate(118%);
  backdrop-filter: blur(1px) saturate(118%);
  pointer-events: none;
}
.impito-tabbar:after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  background: #fffdff;
  opacity: var(--impito-panel-glow, 0);
  pointer-events: none;
}
.impito-tabbar,
.impito-tabbar * {
  box-sizing: border-box;
}
.impito-tabbar__thumb {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 3;
  --impito-thumb-scale: 1;
  width: 76px;
  height: 57px;
  border-radius: 999px;
  overflow: hidden;
  /* Idle: нейтрально-серая пилюля (как в таббаре Telegram) — серость даётся
     подложкой, а не десатурацией фона: thumb лежит НАД иконками (z 3 > 2),
     сильный saturate() убил бы розовый цвет активной иконки. */
  background: rgba(120, 108, 117, 0.12);
  -webkit-backdrop-filter: saturate(92%) brightness(0.99);
  backdrop-filter: saturate(92%) brightness(0.99);
  /* Без внешней тени в покое (2026-07-28) — остались только внутренние блики
     стекла; тень в захвате живёт в правиле .is-dragging и не тронута. */
  box-shadow:
    inset 0 1px 1px -0.5px rgba(255, 255, 255, 0.35),
    inset 0 -1px 1px -0.5px rgba(255, 255, 255, 0.2),
    inset 0 0 0 0.5px rgba(255, 255, 255, 0.18);
  opacity: 0;
  transform: translate3d(5px, 5px, 0) scale(var(--impito-thumb-scale, 1));
  /* Переезд ползунка по обычному нажатию медленнее на 20% (2026-07-30):
     0.4s → 0.48s. Кривые не менялись, тайминги захвата (.is-dragging) тоже. */
  transition:
    transform 0.48s cubic-bezier(0.22, 1, 0.36, 1),
    width 0.48s cubic-bezier(0.22, 1, 0.36, 1),
    height 0.48s cubic-bezier(0.3, 1.25, 0.4, 1),
    opacity 0.12s var(--ui-ease),
    background-color 0.16s var(--ui-ease),
    box-shadow 0.16s var(--ui-ease);
  will-change: transform;
  pointer-events: none;
}
.impito-tabbar__thumb:after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  box-shadow:
    inset 0 0 10px -6px rgba(43, 16, 32, 0.33),
    inset 0 1px 2px rgba(43, 16, 32, 0.12);
  opacity: 0;
  transition: opacity 0.25s var(--ui-ease);
  pointer-events: none;
}
html.impito-lg-active .impito-tabbar__thumb:after,
.impito-tabbar.is-dragging .impito-tabbar__thumb:after {
  opacity: 1;
}
.impito-tabbar__thumb.is-bounce {
  animation: impito-thumb-bounce 0.6s cubic-bezier(0.34, 1.56, 0.5, 1);
}
@keyframes impito-thumb-bounce {
  0% {
    scale: 1 0.9;
  }
  35% {
    scale: 1 1.08;
  }
  68% {
    scale: 1 0.97;
  }
  100% {
    scale: 1 1;
  }
}
.impito-tabbar:not(.is-ready) .impito-tabbar__thumb {
  visibility: hidden;
  opacity: 0;
  transition: none;
}
.impito-tabbar.is-ready .impito-tabbar__thumb {
  visibility: visible;
  opacity: 1;
}
.impito-tabbar.is-dragging {
  transform: translateX(-50%) scale(1.045);
}
.impito-tabbar.is-dragging:before {
  background: rgba(250, 247, 250, 0.92);
  -webkit-backdrop-filter: blur(1px) saturate(130%) brightness(1.03);
  backdrop-filter: blur(1px) saturate(130%) brightness(1.03);
}
.impito-tabbar.is-dragging .impito-tabbar__thumb {
  --impito-thumb-scale: 1;
  background: rgba(255, 249, 252, 0.13);
  -webkit-backdrop-filter: saturate(200%);
  backdrop-filter: saturate(200%);
  box-shadow:
    0 17px 36px rgba(43, 16, 32, 0.19),
    0 2px 7px rgba(43, 16, 32, 0.075),
    inset 0 1px 1px -0.5px rgba(255, 255, 255, 0.55),
    inset 0 -1px 1px -0.5px rgba(255, 255, 255, 0.3),
    inset 0 0 0 0.5px rgba(255, 255, 255, 0.3);
  /* Никаких width/height-транзишенов в захвате: карта преломления печётся под
     размер БОКСА, поэтому анимация бокса оставляла стекло на старом размере и
     потом резко перещёлкивала. Бокс встаёт мгновенно, рост даёт transform
     (sizeSx/sizeSy в jellyTick) — линза растёт вместе с ползунком. */
  transition:
    background-color 0.12s var(--ui-ease),
    box-shadow 0.12s var(--ui-ease),
    opacity 0.12s var(--ui-ease);
}
.impito-tabbar__item {
  position: relative;
  z-index: 2;
  display: inline-flex;
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  padding: 5px 1px 4px;
  border: 0;
  border-radius: 29px;
  background: transparent;
  color: rgba(43, 16, 32, 0.9);
  cursor: pointer;
  font: inherit;
  -webkit-tap-highlight-color: transparent;
  transition:
    color 0.2s var(--ui-ease),
    transform 0.2s var(--ui-ease),
    filter 0.18s var(--ui-ease);
}
.impito-tabbar.is-dragging .impito-tabbar__item {
  filter: brightness(calc(1.55 + var(--impito-panel-glow, 0) * 1.4));
}
.impito-tabbar.is-dragging .impito-tabbar__item.is-hot {
  color: var(--ui-accent-strong);
}
.impito-tabbar.is-dragging .impito-tabbar__item.is-active:not(.is-hot) {
  color: rgba(43, 16, 32, 0.9);
}
.impito-tabbar.is-dragging .impito-tabbar__icon,
.impito-tabbar.is-dragging .impito-tabbar__label {
  text-shadow: 0 0 8px rgba(255, 255, 255, 0.55);
}
.impito-tabbar__item.is-active {
  background: transparent;
  color: var(--ui-accent-strong);
  box-shadow: none;
}
.impito-tabbar:not(.is-dragging) .impito-tabbar__item:active {
  transform: scale(0.98);
}
.impito-tabbar__icon {
  display: block;
  /* Иконки и подписи таббара +10% (2026-07-28, просьба юзера). */
  height: 26.4px;
  font-size: 25.3px;
  font-weight: 760;
  letter-spacing: 0;
  line-height: 0.96;
  transform: translateY(2px);
}
.impito-tabbar__label {
  display: block;
  max-width: 100%;
  overflow: hidden;
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1;
  text-overflow: ellipsis;
  transform: translateY(3px);
  white-space: nowrap;
}
@media (max-width: 390px) {
  .impito-tabbar {
    width: min(calc(100% - 36px), 504px);
    height: 64px;
    padding: 4px 8px;
    border-radius: 32px;
  }
  .impito-tabbar__item {
    border-radius: 28px;
  }
  .impito-tabbar__icon {
    height: 25.3px;
    font-size: 24.2px;
  }
  .impito-tabbar__icon svg {
    width: 25.3px;
    height: 25.3px;
  }
  .impito-tabbar__label {
    font-size: 11px;
  }
}
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .impito-tabbar {
    background: rgba(255, 255, 255, 0.6);
  }
  .impito-tabbar:before {
    background: transparent;
  }
  .impito-tabbar__thumb {
    background: rgba(176, 166, 173, 0.42);
  }
}
html.impito-lg-refract .impito-tabbar:before {
  -webkit-backdrop-filter: url(#impito-lg-refraction);
  backdrop-filter: url(#impito-lg-refraction);
}
/* В ПОКОЕ url()-фильтра НЕТ (2026-07-30). Он висел всегда, а нулевой scale
   смещения гасил только результат — сама цепочка (блюр + saturate + три
   feDisplacementMap + композиты) всё равно считалась каждый кадр, пока ползунок
   едет между вкладками 0.48s. Отсюда рывки при обычном нажатии. */
html.impito-lg-refract .impito-tabbar .impito-tabbar__thumb {
  -webkit-backdrop-filter: saturate(92%) brightness(0.99);
  backdrop-filter: saturate(92%) brightness(0.99);
}
/* :not(apple) обязателен: иначе это правило перебило бы сброс фильтра у
   ползунка на apple (там своё стекло на псевдослоях). */
html.impito-lg-refract.impito-lg-active:not([data-font-platform="apple"])
  .impito-tabbar
  .impito-tabbar__thumb {
  -webkit-backdrop-filter: url(#impito-lg-thumb) saturate(92%) brightness(0.99);
  backdrop-filter: url(#impito-lg-thumb) saturate(92%) brightness(0.99);
}
html.impito-lg-refract .impito-tabbar.is-dragging .impito-tabbar__thumb {
  -webkit-backdrop-filter: url(#impito-lg-thumb);
  backdrop-filter: url(#impito-lg-thumb);
}
@media (prefers-reduced-motion: reduce) {
  .impito-tabbar,
  .impito-tabbar__thumb,
  .impito-tabbar__item {
    transition: none;
  }
}

/* Prompt styles reuse the existing page, card, row, media and button objects. */
body.impito-prompt-styles-active #root {
  display: none;
}
body.impito-prompt-styles-active .ui-cta-bar {
  display: none;
}
#impito-prompt-styles {
  min-height: 100vh;
  min-height: 100svh;
}
.impito-styles-page .ui-page-head {
  padding-top: 28px;
}
.impito-style-chips {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.impito-style-chips::-webkit-scrollbar {
  display: none;
}
.impito-style-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 0 12px;
}
.impito-style-more {
  display: block;
  min-width: 164px;
  margin: 16px auto 0;
}
.impito-style-more[hidden] {
  display: none;
}
.impito-style-card {
  position: relative;
  display: block;
  min-width: 0;
  margin: 0;
  padding: 0;
  overflow: hidden;
  border: 0;
  border-radius: var(--ui-radius-card);
  aspect-ratio: 3 / 4;
  background: var(--ui-fill);
  color: inherit;
  cursor: pointer;
  font: inherit;
  text-align: left;
  -webkit-tap-highlight-color: transparent;
  /* Внешней тени НЕТ (2026-07-31, просьба юзера) — как у таббара и нижних
     панелей действия. Осталась только внутренняя волосяная кромка: она рисует
     край карточки поверх картинки, без неё светлые снимки сливаются с фоном. */
  box-shadow: inset 0 0 0 0.5px rgba(255, 255, 255, 0.25);
  animation: impito-card-in 0.5s var(--ui-ease-out) backwards;
  transition: transform 0.18s var(--ui-ease);
}
.impito-style-card:active {
  transform: scale(0.97);
}
@keyframes impito-card-in {
  from {
    opacity: 0;
    transform: translateY(16px) scale(0.96);
  }
}
.impito-style-card__image,
.impito-style-card__placeholder {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.impito-style-card__placeholder {
  display: grid;
  place-items: center;
  background: var(--ui-fill-2);
  font-size: 46px;
}
.impito-style-card__overlay {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 36px 14px 13px;
  background: linear-gradient(
    180deg,
    rgba(43, 16, 32, 0) 0%,
    rgba(43, 16, 32, 0.52) 58%,
    rgba(43, 16, 32, 0.74) 100%
  );
}
.impito-style-card__kicker {
  overflow: hidden;
  color: rgba(255, 255, 255, 0.72);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.impito-style-card__name {
  display: -webkit-box;
  overflow: hidden;
  color: #fff;
  font-size: 16px;
  font-weight: 650;
  line-height: 1.22;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}
.impito-style-detail__head {
  display: block;
  padding: 16px 22px 18px;
}
.impito-style-detail__head .ui-page-sub {
  margin: 0 0 6px;
  font-size: 14px;
}
.impito-style-detail__head .ui-page-title {
  max-width: 100%;
  font-size: 30px;
  line-height: 1.06;
  overflow-wrap: anywhere;
  text-wrap: balance;
}
.impito-style-gallery {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 0;
}
.impito-style-gallery .impito-style-detail__image {
  height: 190px;
  border-radius: calc(var(--ui-radius-card) * 0.72);
}
.impito-style-gallery .impito-style-detail__image:first-child {
  grid-column: 1 / -1;
  height: auto;
  max-height: 520px;
  border-radius: var(--ui-radius-card);
}
.impito-style-pager {
  position: relative;
}
.impito-style-pager__track {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.impito-style-pager__track::-webkit-scrollbar {
  display: none;
}
.impito-style-pager__slide {
  flex: 0 0 100%;
  scroll-snap-align: center;
  scroll-snap-stop: always;
}
.impito-style-pager__slide .impito-style-detail__image {
  width: 100%;
  max-width: none;
  aspect-ratio: 3 / 4;
  max-height: 520px;
  object-fit: cover;
  border-radius: var(--ui-radius-card);
}
.impito-style-pager__badge {
  position: absolute;
  top: 12px;
  right: 24px;
  z-index: 2;
  padding: 5px 11px;
  border-radius: 999px;
  background: rgba(43, 16, 32, 0.45);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  backdrop-filter: blur(10px) saturate(140%);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}
.impito-style-prompt.ui-field {
  height: 220px;
  min-height: 220px;
  max-height: 220px;
  padding: 16px 18px;
  overflow-y: auto;
  font-size: 14.5px;
  line-height: 1.45;
  resize: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.impito-style-prompt-actions {
  display: flex;
  padding: 10px 12px 0;
}
.impito-style-edit.ui-button {
  height: 38px;
  padding-inline: 18px;
}
.impito-style-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.impito-style-section-head .ui-section-header:last-child {
  color: var(--ui-hint);
  font-weight: 400;
}
.impito-style-photos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 12px;
  padding: 6px 12px 0;
}
.impito-style-photo {
  position: relative;
  display: block;
}
.impito-style-photo img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  border-radius: 18px;
  object-fit: cover;
  box-shadow: inset 0 0 0 0.5px rgba(43, 16, 32, 0.08);
}
.impito-style-photo__remove {
  position: absolute;
  top: -7px;
  right: -7px;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 2px solid var(--ui-bg);
  border-radius: 50%;
  background: rgba(43, 16, 32, 0.78);
  color: #fff;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.impito-style-photo__remove svg {
  width: 11px;
  height: 11px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
}
.impito-style-photo-add {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  padding: 0;
  border: 1.5px dashed rgba(43, 16, 32, 0.22);
  border-radius: 18px;
  background: transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.impito-style-photo-add:active {
  background: var(--ui-press);
}
.impito-style-photo-add span {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid rgba(43, 16, 32, 0.25);
  border-radius: 50%;
  color: var(--ui-accent-strong);
}
.impito-style-photo-add svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}
.impito-style-photos-count.ui-section-header {
  color: var(--ui-hint);
  font-weight: 400;
  font-feature-settings: "tnum" 1;
  font-variant-numeric: tabular-nums;
}
.impito-style-upload__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.impito-style-detail.ui-page {
  padding-top: calc(62px + var(--ui-safe-top));
  padding-bottom: calc(184px + var(--ui-safe-bottom));
}
.impito-style-submit.ui-submit {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(82px + var(--ui-safe-bottom));
  z-index: 70;
  padding: 0;
  pointer-events: none;
}
.impito-style-submit__inner {
  position: relative;
  display: grid;
  grid-template-columns: max-content max-content minmax(0, 1fr);
  align-items: center;
  gap: 6px;
  width: min(calc(100% - 48px), 504px);
  height: 67px;
  margin: 0 auto;
  padding: 0 10px;
  border-radius: 34px;
  background: transparent;
  /* Внешней тени НЕТ (2026-07-30, просьба юзера) — как и у таббара, остались
     только внутренние блики стекла. Первая строка — та же волосяная тёмная
     обводка 0.5px, что у таббара: на 2x/3x это ровно 1 физический пиксель.
     Именно box-shadow, а не border — border с `box-sizing: border-box` съел бы
     внутреннюю высоту и сдвинул содержимое панели. */
  box-shadow:
    0 0 0 0.5px rgba(43, 16, 32, 0.22),
    inset 0 1.2px 1px -0.5px rgba(255, 255, 255, 0.5),
    inset 0 -1px 1px -0.5px rgba(255, 255, 255, 0.22),
    inset 1px 0 1px -0.5px rgba(255, 255, 255, 0.3),
    inset -1px 0 1px -0.5px rgba(255, 255, 255, 0.3),
    inset 0 0 0 0.5px rgba(255, 255, 255, 0.15);
  pointer-events: auto;
}
.impito-style-submit__inner:before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  /* Same pink-tinted fog as the tabbar (anti white-flash on iOS reload). */
  background: rgba(243, 227, 237, 0.9);
  -webkit-backdrop-filter: blur(1px) saturate(118%);
  backdrop-filter: blur(1px) saturate(118%);
  pointer-events: none;
}
html.impito-lg-refract .impito-style-submit__inner:before {
  -webkit-backdrop-filter: url(#impito-lg-refraction);
  backdrop-filter: url(#impito-lg-refraction);
}
.impito-style-cost,
.impito-style-quantity,
.impito-style-generate {
  position: relative;
  z-index: 1;
}
.impito-style-cost {
  display: flex;
  width: 56px;
  min-width: 56px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-left: 4px;
}
.impito-style-cost__value {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  color: var(--ui-text);
  white-space: nowrap;
}
.impito-style-cost__value strong {
  font-size: 19px;
  font-weight: 650;
  font-feature-settings: "tnum" 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1;
}
.impito-style-cost__value span {
  color: var(--ui-hint);
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
}
.impito-style-quantity {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.impito-style-count {
  display: grid;
  place-items: center;
  min-width: 44px;
  height: 40px;
  border-radius: 11px;
  background: rgba(255, 255, 255, 0.6);
  box-shadow: inset 0 0 0 0.5px rgba(43, 16, 32, 0.12);
  color: var(--ui-text);
  font-size: 16px;
  font-weight: 600;
  font-feature-settings: "tnum" 1;
  font-variant-numeric: tabular-nums;
}
.impito-style-stepper {
  display: inline-flex;
  align-items: center;
  height: 40px;
  border-radius: var(--ui-radius-pill);
  background: var(--ui-fill);
}
.impito-style-stepper__button {
  display: grid;
  place-items: center;
  width: 46px;
  height: 40px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ui-text);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.impito-style-stepper__button:first-of-type {
  border-radius: 999px 0 0 999px;
}
.impito-style-stepper__button:last-of-type {
  border-radius: 0 999px 999px 0;
}
.impito-style-stepper__button:active {
  background: rgba(43, 16, 32, 0.1);
}
.impito-style-stepper__button:disabled {
  cursor: default;
  opacity: 0.3;
}
.impito-style-stepper__button svg {
  display: block;
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
}
.impito-style-stepper__divider {
  width: 1px;
  height: 18px;
  background: var(--ui-separator);
}
.impito-style-generate {
  display: inline-flex;
  min-width: 0;
  height: 40px;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: var(--ui-accent);
  color: var(--ui-accent-text);
  font: inherit;
  font-size: clamp(11.5px, 3.3vw, 14px);
  font-weight: 600;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.15s var(--ui-ease);
}
.impito-style-generate:active {
  transform: scale(0.97);
}
.impito-style-generate span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.impito-style-generate svg {
  display: block;
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.impito-sheet {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 0 10px calc(10px + var(--ui-safe-bottom));
}
.impito-sheet[hidden] {
  display: none;
}
.impito-sheet__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(43, 16, 32, 0.28);
  opacity: 0;
  transition: opacity 0.2s var(--ui-ease);
}
.impito-sheet__panel {
  position: relative;
  display: flex;
  width: min(100%, 504px);
  flex-direction: column;
  gap: 8px;
  margin: 0 auto;
  opacity: 0;
  transform: translateY(24px);
  transition:
    transform 0.22s var(--ui-ease-out),
    opacity 0.18s var(--ui-ease);
}
.impito-sheet.is-open .impito-sheet__backdrop {
  opacity: 1;
}
.impito-sheet.is-open .impito-sheet__panel {
  opacity: 1;
  transform: translateY(0);
}
.impito-sheet__group {
  overflow: hidden;
  border-radius: var(--ui-radius-card);
  background: rgba(238, 233, 238, 0.9);
  -webkit-backdrop-filter: blur(2px) saturate(145%);
  backdrop-filter: blur(2px) saturate(145%);
  box-shadow:
    0 18px 44px rgba(43, 16, 32, 0.22),
    inset 0 0 0 0.5px rgba(255, 255, 255, 0.2);
}
.impito-sheet__option {
  display: block;
  width: 100%;
  height: 54px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ui-accent-strong);
  font: inherit;
  font-size: 17px;
  font-weight: 500;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.impito-sheet__option + .impito-sheet__option {
  border-top: 0.5px solid var(--ui-separator);
}
.impito-sheet__option:active {
  background: var(--ui-press);
}
.impito-sheet__cancel {
  display: block;
  width: 100%;
  height: 54px;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: rgba(238, 233, 238, 0.9);
  -webkit-backdrop-filter: blur(2px) saturate(145%);
  backdrop-filter: blur(2px) saturate(145%);
  /* Тот же розовый, что у вариантов выше (2026-07-31, просьба юзера): чёрный
     жирный текст выбивался из листа. */
  color: var(--ui-accent-strong);
  font: inherit;
  font-size: 17px;
  font-weight: 640;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  box-shadow:
    0 18px 44px rgba(43, 16, 32, 0.22),
    0 3px 10px rgba(43, 16, 32, 0.09),
    inset 0 1.2px 1px -0.5px rgba(255, 255, 255, 0.5),
    inset 0 -1px 1px -0.5px rgba(255, 255, 255, 0.22),
    inset 0 0 0 0.5px rgba(255, 255, 255, 0.15);
}
.impito-sheet__cancel:active {
  background: rgba(244, 240, 244, 0.95);
}
body.impito-camera-open {
  overflow: hidden;
}
.impito-camera {
  position: fixed;
  inset: 0;
  z-index: 160;
  display: flex;
  padding:
    calc(8px + var(--ui-safe-top))
    0
    calc(8px + var(--ui-safe-bottom));
  background: #000;
}
.impito-camera[hidden] {
  display: none;
}
.impito-camera__panel {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) 108px;
  width: min(100%, 504px);
  height: 100%;
  min-height: 0;
  margin: 0 auto;
}
.impito-camera__head {
  display: flex;
  min-height: 44px;
  align-items: center;
  justify-content: center;
  padding: 0 0 6px;
}
.impito-camera__title {
  color: rgba(255, 255, 255, 0.92);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.impito-camera__view {
  position: relative;
  display: grid;
  width: 100%;
  max-width: 100%;
  max-height: 100%;
  min-height: 0;
  aspect-ratio: 3 / 4;
  margin: auto;
  overflow: hidden;
  place-items: center;
  align-self: center;
  border-radius: 20px;
  background: #111;
}
.impito-camera__video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.impito-camera__video.is-mirrored {
  transform: scaleX(-1);
}
.impito-camera__video[hidden] {
  display: none;
}
.impito-camera__status {
  max-width: 280px;
  padding: 18px;
  color: rgba(255, 255, 255, 0.78);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.35;
  text-align: center;
}
.impito-camera__status[hidden] {
  display: none;
}
.impito-camera__status.is-error {
  color: #fff;
}
.impito-camera__controls {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 0 12px;
}
.impito-camera__shutter {
  display: grid;
  width: 74px;
  height: 74px;
  padding: 5px;
  place-items: center;
  border: 4px solid rgba(255, 255, 255, 0.95);
  border-radius: 50%;
  background: transparent;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
.impito-camera__shutter span {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.12s var(--ui-ease);
}
.impito-camera__shutter:active span {
  transform: scale(0.88);
}
.impito-camera__shutter:disabled {
  cursor: default;
  opacity: 0.42;
}
.impito-camera__flip {
  display: grid;
  place-items: center;
  justify-self: center;
  width: 46px;
  height: 46px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.impito-camera__flip:active {
  background: rgba(255, 255, 255, 0.24);
}
.impito-camera__flip:disabled {
  cursor: default;
  opacity: 0.35;
}
.impito-camera__flip svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
html[data-font-platform="apple"] .impito-tabbar:before,
html[data-font-platform="apple"] .impito-style-submit__inner:before {
  -webkit-backdrop-filter: blur(1.15px) saturate(120%);
  backdrop-filter: blur(1.15px) saturate(120%);
}
/* WebKit не умеет SVG-фильтры в backdrop-filter, поэтому на apple стекло у
   ползунка своё: слой размытия (:before) + слой обводки с хроматикой (:after).
   Селектор специально длиннее refract-правила (и идёт ниже по файлу): иначе
   `backdrop-filter: url(#impito-lg-thumb)` перебил бы сброс на apple.
   `isolation: isolate` — не косметика: элемент с backdrop-filter в WebKit
   уезжает в собственный композиторский слой и начинает игнорировать порядок
   z-index, из-за чего обводка и хроматика оказывались то над размытием, то под
   ним. Свой контекст наложения + промоушен обоих слоёв через translateZ(0)
   фиксируют порядок. */
/* Класс ползунка повторён намеренно: правилу нужно перебить и drag-вариант
   refract (`.is-dragging` даёт ту же специфичность), иначе на apple в захвате
   тихо возвращается url()-фильтр — в WebKit он не рисуется, но стоит денег. */
html[data-font-platform="apple"]
  .impito-tabbar
  .impito-tabbar__thumb.impito-tabbar__thumb {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  isolation: isolate;
}
/* Размытие живёт в отдельном слое с кольцевой маской: в центре пилюли она
   прозрачна (иконка остаётся резкой), к краю набирает силу. Слой отдельный,
   потому что маска нужна только размытию, а не всему ползунку. */
html[data-font-platform="apple"] .impito-tabbar__thumb:before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  transform: translateZ(0);
  /* В покое слоя нет вообще (2026-07-30): маскированный слой внутри едущей
     пилюли — это отдельная композиция с маской на каждый кадр переезда, и на
     iOS это заметно дороже, чем сам переезд. Включается вместе с фильтром. */
  display: none;
  -webkit-mask-image: radial-gradient(
    ellipse closest-side at 50% 50%,
    transparent 0 42%,
    rgba(0, 0, 0, 0.5) 72%,
    #000 100%
  );
  mask-image: radial-gradient(
    ellipse closest-side at 50% 50%,
    transparent 0 42%,
    rgba(0, 0, 0, 0.5) 72%,
    #000 100%
  );
  pointer-events: none;
}
/* Сам фильтр — только на удержании: в покое он не нужен и дорого стоит,
   подложка пересчитывается каждый кадр, пока пилюля едет. */
html[data-font-platform="apple"].impito-lg-active
  .impito-tabbar__thumb:before,
html[data-font-platform="apple"]
  .impito-tabbar.is-dragging
  .impito-tabbar__thumb:before {
  display: block;
  -webkit-backdrop-filter: blur(7px) saturate(92%);
  backdrop-filter: blur(7px) saturate(92%);
}
/* Обводка пилюли на удержании — СВОЯ и постоянная. Юзер видел её то с
   обводкой, то без: кромка размывающего слоя подхватывала то границу панели
   (пилюля выше панели на 8px), то чистый фон за её краем, и «обводка»
   появлялась только когда под ней было что размывать. Своя линия лежит выше
   размытия (:after z-index 1 против :before 0) и не зависит от того, что под
   пилюлей. Тут же хроматика: тёплая кайма слева, холодная справа — имитация
   дисперсии, которую на Android даёт SVG-линза. */
html[data-font-platform="apple"] .impito-tabbar__thumb:after {
  /* Обводка и хроматика обязаны лежать НАД размытием при любом раскладе:
     свой слой (translateZ) + z-index выше, чем у :before. */
  z-index: 2;
  transform: translateZ(0);
}
html[data-font-platform="apple"].impito-lg-active .impito-tabbar__thumb:after,
html[data-font-platform="apple"]
  .impito-tabbar.is-dragging
  .impito-tabbar__thumb:after {
  box-shadow:
    inset 0 0 0 0.5px rgba(43, 16, 32, 0.16),
    inset 0 0 10px -6px rgba(43, 16, 32, 0.33),
    inset 0 1px 2px rgba(43, 16, 32, 0.12),
    inset 2px 0 2.5px -1.5px rgba(255, 0, 132, 0.34),
    inset -2px 0 2.5px -1.5px rgba(0, 168, 255, 0.3),
    inset 0 2px 2.5px -1.5px rgba(255, 64, 160, 0.22),
    inset 0 -2px 2.5px -1.5px rgba(0, 190, 255, 0.2);
}
/* Тот же захват без стекла читался как неоновая подсветка букв: яркость 1.55
   плюс белый text-shadow на светло-розовом фоне. На apple глушим. */
/* Вкладки НЕ поднимаем над ползунком (пробовали z-index: 4 — стало «ничего не
   изменилось»): внутри панели за пилюлей лежит только плотный туман :before,
   размывать в нём нечего, и единственный контрастный объект в backdrop'е —
   как раз иконка с подписью. Они должны оставаться под ползунком, как на
   Android под линзой. */
html[data-font-platform="apple"] .impito-tabbar.is-dragging .impito-tabbar__item {
  filter: brightness(calc(1.12 + var(--impito-panel-glow, 0) * 0.5));
}
html[data-font-platform="apple"] .impito-tabbar.is-dragging .impito-tabbar__icon,
html[data-font-platform="apple"] .impito-tabbar.is-dragging .impito-tabbar__label {
  text-shadow: none;
}
.impito-style-sticky {
  position: fixed;
  top: 0;
  left: 50%;
  z-index: 60;
  width: min(100%, 560px);
  /* Верхнее поле: не меньше высоты вуали плюс просвет. Иначе поиск и чипсы
     налезали на пилюли профиля и баланса — они позиционируются от вуали, а
     шапка каталога считалась только от safe-top и про них не знала
     (2026-07-30, баг с устройства). max() оставляет старое поведение там, где
     вуаль низкая.
     Нижнее поле 30 → 12px: раньше внизу был градиентный хвост, и 30px уходили
     на растворение. У плоской панели этот запас читается как пустая полоса
     стекла под чипсами. */
  padding: max(calc(56px + var(--ui-safe-top)), calc(var(--ui-veil-height) + 8px))
    0 12px;
  /* Схлопывается вместе с панелью: при скролле вниз --ui-veil-pill-row
     обнуляется, шапка подтягивается вверх. */
  transition: padding-top 0.28s var(--ui-ease);
  /* Полупрозрачное матовое стекло — тот же рецепт, что у вуали body:before на
     главной и у тумана таббара, вместо непрозрачной розовой плашки с градиентом
     (2026-07-30, просьба юзера «как в других везде»).
     Подложка 80% не «на глаз»: iOS первые кадры после reload рисует слой ещё
     без backdrop-filter, ниже 70% будет белая вспышка. */
  background: color-mix(in srgb, var(--ui-bg) 80%, transparent);
  -webkit-backdrop-filter: blur(6px) saturate(140%);
  backdrop-filter: blur(6px) saturate(140%);
  /* Волосяная линия снизу вместо растворения: 0.5px = один физический пиксель
     на 2x/3x. Именно box-shadow, а не border — border съел бы внутреннюю
     высоту и сдвинул поиск с чипсами. */
  box-shadow: 0 0.5px 0 rgba(43, 16, 32, 0.1);
  transform: translateX(-50%);
}
/* Пока на экране шапка каталога, общая вуаль body:before выключена: они лежат
   друг на друге в верхней полосе, и две подложки по 80% давали там ~96% —
   заметно плотнее остальной панели, плюс лишний слой с backdrop-filter поверх
   скроллящегося каталога. Селектор через :has() намеренно: у экрана детали
   стиля своей шапки нет, и вуаль там нужна. Если браузер не знает :has(),
   правило просто игнорируется и остаётся прежнее поведение. */
body:has(.impito-style-sticky):before {
  display: none;
}
.impito-style-sticky__title {
  position: absolute;
  top: calc(var(--ui-safe-top) + 11px);
  left: 72px;
  right: 72px;
  text-align: center;
  /* Заголовок шапки: 19 → 15.2 → 16.4px (−20%, потом +8%), интерлиньяж следом. */
  font-size: 16.4px;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 23px;
  color: var(--ui-text);
}
.impito-style-sticky .ui-section {
  margin-bottom: 12px;
}
.impito-style-sticky .ui-section:last-child {
  margin-bottom: 0;
}
.impito-styles-page.ui-page {
  /* Значение ставит prompt_styles.js по НАСТОЯЩЕЙ высоте шапки: она зависит от
     вуали, а та — от инсетов Telegram, и константой не выражается. Фолбэк здесь
     на случай, если скрипт не успел (первый кадр) или измерение не удалось. */
  padding-top: var(--ui-catalog-top, calc(98px + var(--ui-safe-top)));
}
.impito-styles-page .ui-page-head {
  padding-top: 0;
  visibility: hidden;
}
.impito-style-search {
  position: relative;
  display: flex;
  align-items: center;
  gap: 9px;
  height: 44px;
  margin: 0 12px;
  padding: 0 16px;
  border-radius: var(--ui-radius-pill);
  /* Было rgba(243,237,243,0.97) — почти непрозрачная плашка. На стеклянной
     шапке (см. .impito-style-sticky) она читалась как наклеенный сверху блок,
     поэтому заливка тоже стала полупрозрачной. Своего backdrop-filter тут НЕТ
     намеренно: подложку уже размыла шапка, второй фильтр внутри неё — лишний
     композиторский слой поверх скроллящегося каталога, на iOS это дорого. */
  background: rgba(255, 255, 255, 0.5);
  box-shadow:
    0 0 0 0.5px rgba(43, 16, 32, 0.1),
    inset 0 1.2px 1px -0.5px rgba(255, 255, 255, 0.5),
    inset 0 -1px 1px -0.5px rgba(255, 255, 255, 0.22),
    inset 0 0 0 0.5px rgba(255, 255, 255, 0.15);
  cursor: text;
}
.impito-style-search svg {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  fill: none;
  stroke: rgba(43, 16, 32, 0.45);
  stroke-width: 1.8;
  stroke-linecap: round;
}
.impito-style-search input {
  min-width: 0;
  height: 100%;
  flex: 1;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ui-text);
  font: inherit;
  font-size: 17px;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}
.impito-style-search input::placeholder {
  color: rgba(43, 16, 32, 0.4);
}
.impito-style-search input::-webkit-search-decoration {
  display: none;
}
.impito-style-chips {
  padding: 0 12px;
}
.impito-style-empty {
  grid-column: 1 / -1;
  margin: 0;
  padding: 30px 0;
  color: var(--ui-hint);
  font-size: 15px;
  text-align: center;
}
#impito-prompt-styles main[data-anim="fade"] {
  animation: impito-page-in 0.3s var(--ui-ease-out);
}
#impito-prompt-styles main[data-anim="push"] {
  animation: impito-push-in 0.34s var(--ui-ease-nav);
}
#impito-prompt-styles main[data-anim="pop"] {
  animation: impito-pop-in 0.3s var(--ui-ease-nav);
}
@keyframes impito-page-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}
@keyframes impito-push-in {
  from {
    opacity: 0.15;
    transform: translateX(64px);
  }
}
@keyframes impito-pop-in {
  from {
    opacity: 0.15;
    transform: translateX(-48px);
  }
}
#impito-prompt-styles .ui-chip {
  transition:
    transform 0.15s var(--ui-ease),
    background-color 0.2s var(--ui-ease),
    color 0.2s var(--ui-ease);
}
#impito-prompt-styles .ui-chip:active {
  transform: scale(0.94);
}
.impito-style-submit__inner {
  animation: impito-submit-in 0.4s var(--ui-ease-out) 0.05s backwards;
}
@keyframes impito-submit-in {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
}
.impito-style-count.is-pop {
  animation: impito-count-pop 0.26s var(--ui-ease-out);
}
@keyframes impito-count-pop {
  35% {
    transform: scale(1.16);
  }
}
.impito-style-photo img {
  transition:
    opacity 0.32s var(--ui-ease),
    transform 0.32s var(--ui-ease);
}
.impito-style-photo.is-loading {
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.55);
  box-shadow: inset 0 0 0 0.5px rgba(43, 16, 32, 0.08);
}
.impito-style-photo.is-loading img {
  opacity: 0;
  transform: scale(1.05);
}
.impito-style-photo__spinner {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 -11px;
  border: 2.5px solid rgba(43, 16, 32, 0.14);
  border-radius: 50%;
  border-top-color: var(--ui-accent-strong);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s var(--ui-ease);
}
.impito-style-photo.is-loading .impito-style-photo__spinner {
  opacity: 1;
  animation: impito-spin 0.8s linear infinite;
}
@keyframes impito-spin {
  to {
    transform: rotate(360deg);
  }
}
.impito-style-photo__remove {
  transition: opacity 0.2s var(--ui-ease);
}
.impito-style-photo.is-loading .impito-style-photo__remove {
  opacity: 0;
  pointer-events: none;
}
.impito-style-photo.is-repainting {
  animation: impito-photo-repaint 0.06s linear;
}
@keyframes impito-photo-repaint {
  from {
    opacity: 0.99;
    transform: translateZ(0);
  }
  to {
    opacity: 1;
    transform: translateZ(0);
  }
}
.impito-style-photo.is-removing {
  animation: impito-tile-out 0.18s var(--ui-ease) forwards;
  pointer-events: none;
}
@keyframes impito-tile-out {
  to {
    opacity: 0;
    transform: scale(0.82);
  }
}
.impito-style-photo,
.impito-style-photo-add {
  animation: impito-tile-in 0.24s var(--ui-ease-out);
}
@keyframes impito-tile-in {
  from {
    opacity: 0;
    transform: scale(0.94);
  }
}
.impito-camera {
  opacity: 0;
  transition: opacity 0.22s var(--ui-ease);
}
.impito-camera.is-open {
  opacity: 1;
}
@media (max-width: 380px) {
  .impito-style-grid {
    gap: 10px;
  }
  .impito-style-card__name {
    font-size: 15px;
  }
  .impito-style-detail__head .ui-page-title {
    font-size: 28px;
  }
}
@media (max-width: 390px) {
  .impito-style-generate svg {
    display: none;
  }
}
/* На 375px кнопке доставалось 108px, а «генерировать» на живом размере шрифта
   (clamp даёт 12.4px) требует ~111px — подпись обрезалась многоточием. Цена и
   счётчик занимают `max-content`, поэтому единственный запас — поля самой
   кнопки. 12 → 8px хватает (замер 2026-07-31). Экраны от 390px не тронуты. */
@media (max-width: 380px) {
  .impito-style-generate {
    padding: 0 8px;
  }
}
@media (max-width: 390px) {
  .impito-style-submit__inner {
    width: min(calc(100% - 36px), 504px);
    height: 64px;
  }
}
@media (max-width: 350px) {
  .impito-style-submit__inner {
    gap: 5px;
    padding: 0 8px;
  }
  .impito-style-cost {
    width: 50px;
    min-width: 50px;
    padding-left: 2px;
  }
  .impito-style-count {
    min-width: 40px;
  }
  .impito-style-stepper__button {
    width: 40px;
  }
  .impito-style-generate {
    padding: 0 9px;
  }
  .impito-style-photos {
    grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
    gap: 10px;
  }
}
.ui-hero {
  padding: 40px 16px 26px;
}
.ui-hero-emoji {
  width: 128px;
  height: 128px;
}
.ui-hero-emoji:has(.set-hero-mascot) {
  position: relative;
  width: 288px;
  height: 288px;
  animation: none;
}
.ui-hero-emoji:has(.set-hero-mascot):before {
  content: none;
  display: none;
}
.set-hero-mascot {
  animation: none !important;
  transform: none !important;
  -webkit-user-drag: none;
  -webkit-user-select: none;
  user-select: none;
  pointer-events: none;
}
.ui-hero:has(.set-hero-mascot) {
  padding-top: 32px;
}
.ui-hero-emoji:has(.set-hero-mascot) + .ui-hero-title {
  display: none;
  margin-top: 0;
}
.ui-hero-title {
  margin: 14px 0 0;
  color: var(--ui-text);
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.2;
  text-wrap: balance;
}
.ui-hero-sub {
  margin: 8px 0 0;
  max-width: 40ch;
  color: var(--ui-hint);
  font-size: 15px;
  line-height: 1.4;
  text-align: center;
  text-wrap: pretty;
}
.set-center {
  display: flex;
  min-height: 70vh;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 0 24px;
}
.set-status {
  color: var(--ui-hint);
  font-size: var(--ui-size-row, 17px);
  text-align: center;
}
.set-trailing {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
}
.set-value {
  overflow: hidden;
  max-width: 190px;
  color: var(--ui-hint);
  text-overflow: ellipsis;
  white-space: nowrap;
}
.set-chevron {
  display: inline-flex;
  color: var(--ui-separator-strong);
}
.set-dismiss {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  margin: -4px -2px -4px 2px;
  padding: 0;
  border: 0;
  border-radius: var(--ui-radius-pill);
  background: none;
  color: var(--ui-hint);
  cursor: pointer;
  pointer-events: auto;
}
.set-dismiss:active {
  background: var(--ui-press);
}
@media (hover: hover) {
  .set-dismiss:hover {
    background: var(--ui-hover);
  }
}
.set-style-apply {
  display: block;
  width: 100%;
  margin: -13px 0;
  padding: 13px 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.set-style-apply:active {
  opacity: 0.55;
}
.set-options {
  display: flex;
  flex-direction: column;
  padding: 2px 8px 4px;
}
.set-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 50px;
  padding: 12px 14px;
  border: 0;
  border-radius: 14px;
  background: none;
  color: var(--ui-text);
  cursor: pointer;
  font-family: var(--ui-font);
  font-size: var(--ui-size-row, 17px);
  text-align: left;
  transition: background var(--ui-dur) var(--ui-ease);
}
.set-option:active {
  background: var(--ui-press);
}
.set-option-label {
  min-width: 0;
  flex: 1 1 auto;
}
.set-option-check {
  display: inline-flex;
  flex: 0 0 auto;
  color: var(--ui-accent);
}
.set-option-check--anim {
  opacity: 0;
  transform: scale(0.5);
  transition:
    opacity var(--ui-dur) var(--ui-ease),
    transform var(--ui-dur) var(--ui-ease-out);
}
.set-option-check--anim.set-option-check--on {
  opacity: 1;
  transform: scale(1);
}
@media (prefers-reduced-motion: reduce) {
  .set-option-check--anim {
    transition: none;
  }
}
.set-tz-offset {
  flex: 0 0 auto;
  color: var(--ui-hint);
  font-variant-numeric: tabular-nums;
  font-size: 14px;
}
.set-detail-desc {
  max-width: 34ch;
  margin: 6px auto 18px;
  padding: 0 22px;
  color: var(--ui-hint);
  font-size: 15px;
  line-height: 1.4;
  text-align: center;
}
.set-media {
  padding: 0 12px;
  margin-bottom: 20px;
}
.set-media-img,
.set-media-video {
  display: block;
  width: 100%;
  max-width: min(100%, 440px);
  margin-inline: auto;
  border-radius: var(--ui-radius-card);
  object-fit: cover;
}
.set-viz {
  padding: 0 12px;
  margin-bottom: 20px;
}
.set-viz-prev {
  display: block;
  width: 100%;
  max-width: min(100%, 440px);
  margin-inline: auto;
  aspect-ratio: 1080 / 504;
  overflow: hidden;
  border-radius: var(--ui-radius-card);
  background: var(--ui-fill);
}
.set-biz-item {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px 18px;
}
.set-biz-item + .set-biz-item {
  border-top: 1px solid var(--ui-separator);
}
.set-biz-label {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--ui-text);
  font-size: 17px;
  letter-spacing: -0.01em;
}
.set-biz-item .ui-segmented {
  display: flex;
  width: 100%;
}
.set-biz-item .ui-segment {
  flex: 1 1 0;
  min-width: 0;
}
.set-option-check--confirm {
  color: var(--ui-confirm);
  animation: set-tz-confirm-pop var(--ui-dur) var(--ui-ease-out) both;
}
.set-option-check--confirm svg path {
  stroke-dasharray: 24;
  animation: set-tz-confirm-draw 0.24s var(--ui-ease-out) both;
}
@keyframes set-tz-confirm-pop {
  0% {
    opacity: 0;
    transform: scale(0.6);
  }
  60% {
    transform: scale(1.08);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}
@keyframes set-tz-confirm-draw {
  0% {
    stroke-dashoffset: 24;
  }
  to {
    stroke-dashoffset: 0;
  }
}
.set-tz-picker .ui-row,
.set-tz-picker .ui-field {
  transition:
    opacity var(--ui-dur) var(--ui-ease),
    background-color var(--ui-dur) var(--ui-ease);
}
.set-tz-picker--confirming {
  pointer-events: none;
}
.set-tz-picker--confirming .ui-field,
.set-tz-picker--confirming .ui-row:not(:has(.set-option-check--confirm)) {
  opacity: 0.4;
}
.set-tz-picker--confirming .ui-row:has(.set-option-check--confirm) {
  background-color: color-mix(in srgb, var(--ui-confirm) 14%, transparent);
}
@media (prefers-reduced-motion: reduce) {
  .set-option-check--confirm {
    animation: none;
  }
  .set-option-check--confirm svg path {
    stroke-dasharray: none;
    stroke-dashoffset: 0;
    animation: none;
  }
  .set-tz-picker .ui-row,
  .set-tz-picker .ui-field {
    transition: none;
  }
}
.set-stream {
  padding: 0 12px;
  margin-bottom: 20px;
  pointer-events: none;
}
.set-stream-pair {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  max-width: min(100%, 440px);
  margin-inline: auto;
  overflow: hidden;
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
}
.set-stream-divider {
  position: absolute;
  top: 12px;
  bottom: 12px;
  left: 50%;
  width: 1px;
  background: var(--ui-separator);
  transform: translate(-50%) scaleX(0.5);
}
.set-stream-col {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding: 14px 10px;
}
.set-stream-cap {
  color: var(--ui-hint);
  font-size: 12px;
  font-weight: 590;
  text-align: center;
}
.set-stream-cap--on {
  color: var(--ui-accent);
}
.set-stream-thread {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.set-stream-msg {
  max-width: 88%;
  padding: 6px 9px;
  border-radius: 14px;
  font-size: 13px;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
.set-stream-msg--out {
  align-self: flex-end;
  border-bottom-right-radius: 5px;
  background: var(--ui-accent);
  color: var(--ui-accent-text);
}
.set-stream-msg--in {
  position: relative;
  align-self: flex-start;
  border-bottom-left-radius: 5px;
  background: var(--ui-fill-2);
  color: var(--ui-text);
  transition: background-color var(--ui-dur) var(--ui-ease);
}
.set-stream-msg--pending {
  background: transparent;
}
.set-stream-ghost {
  visibility: hidden;
}
.set-stream-live {
  position: absolute;
  top: 6px;
  right: 9px;
  bottom: 6px;
  left: 9px;
  transition: opacity var(--ui-dur) var(--ui-ease);
}
.set-stream-pair[data-phase="reset"] .set-stream-live {
  opacity: 0;
}
.set-stream-pair[data-phase="reset"] .set-stream-msg--in {
  background: transparent;
}
.set-stream-dots {
  display: inline-flex;
  height: 1.3em;
  align-items: center;
  gap: 4px;
}
.set-stream-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ui-hint);
  animation: set-stream-blink 1.2s var(--ui-ease) infinite;
}
.set-stream-dot:nth-child(2) {
  animation-delay: 0.16s;
}
.set-stream-dot:nth-child(3) {
  animation-delay: 0.32s;
}
.set-stream-delta {
  animation: set-stream-grow var(--ui-dur) var(--ui-ease-out);
}
.set-stream-cursor {
  color: currentColor;
  white-space: pre;
}
.set-stream-answer {
  display: block;
}
.set-stream-answer--dump {
  animation: set-stream-dump 0.3s var(--ui-ease-out);
}
@keyframes set-stream-blink {
  0%,
  80%,
  to {
    opacity: 0.3;
    transform: translateY(0);
  }
  40% {
    opacity: 1;
    transform: translateY(-1px);
  }
}
@keyframes set-stream-grow {
  0% {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes set-stream-dump {
  0% {
    opacity: 0;
    transform: translateY(10px) scale(0.96);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
@media (prefers-reduced-motion: reduce) {
  .set-stream-dot,
  .set-stream-delta,
  .set-stream-answer--dump {
    animation: none;
  }
  .set-stream-live {
    transition: none;
  }
}
.set-fw {
  padding: 0 12px;
  margin-bottom: 20px;
  pointer-events: none;
}
.set-fw-card {
  display: flex;
  max-width: min(100%, 440px);
  flex-direction: column;
  gap: 8px;
  margin-inline: auto;
  padding: 14px 12px;
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
}
.set-fw-thread {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.set-fw-msg {
  max-width: 88%;
  padding: 6px 9px;
  border-radius: 14px;
  font-size: 13px;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
.set-fw-msg--out {
  align-self: flex-end;
  border-bottom-right-radius: 5px;
  background: var(--ui-accent);
  color: var(--ui-accent-text);
}
.set-fw-msg--in {
  align-self: flex-start;
  border-bottom-left-radius: 5px;
  background: var(--ui-fill-2);
  color: var(--ui-text);
}
.set-fw-buttons {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin-top: 2px;
}
.set-fw-btn {
  padding: 8px 10px;
  border-radius: 10px;
  background: var(--ui-accent-soft);
  color: var(--ui-accent);
  font-size: 13px;
  font-weight: 510;
  line-height: 1.25;
  text-align: center;
}
.set-br {
  padding: 0 12px;
  margin-bottom: 20px;
  pointer-events: none;
}
.set-br-card {
  display: flex;
  max-width: min(100%, 440px);
  flex-direction: column;
  gap: 8px;
  margin-inline: auto;
  padding: 14px 12px;
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
}
.set-br-burst {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
}
.set-br-msg {
  max-width: 88%;
  padding: 6px 9px;
  border-radius: 14px;
  font-size: 13px;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
.set-br-msg--out {
  align-self: flex-end;
  border-bottom-right-radius: 5px;
  background: var(--ui-accent);
  color: var(--ui-accent-text);
}
.set-br-msg--in {
  align-self: flex-start;
  border-bottom-left-radius: 5px;
  background: var(--ui-fill-2);
  color: var(--ui-text);
}
.set-ps {
  padding: 0 12px;
  margin-bottom: 20px;
  pointer-events: none;
}
.set-ps-card {
  display: flex;
  max-width: min(100%, 440px);
  flex-direction: column;
  gap: 8px;
  margin-inline: auto;
  padding: 14px 12px;
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
}
.set-ps-pinned {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 2px;
  padding-left: 10px;
  border-left: 2px solid var(--ui-accent);
}
.set-ps-cap {
  color: var(--ui-accent);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
}
.set-ps-text {
  color: var(--ui-text);
  font-size: 13px;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.set-ps-seg {
  animation: set-ps-in var(--ui-dur) var(--ui-ease-out);
}
.set-ps-sep {
  color: var(--ui-hint);
}
.set-ps-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 10px;
  border-radius: 10px;
  background: var(--ui-accent-soft);
  color: var(--ui-accent);
  font-size: 13px;
  font-weight: 510;
  line-height: 1.25;
  animation: set-ps-in var(--ui-dur) var(--ui-ease-out);
}
@keyframes set-ps-in {
  0% {
    opacity: 0;
    transform: translateY(3px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .set-ps-seg,
  .set-ps-btn {
    animation: none;
  }
}
.set-rc {
  padding: 0 12px;
  margin-bottom: 20px;
  pointer-events: none;
}
.set-rc-card {
  display: flex;
  max-width: min(100%, 440px);
  flex-direction: column;
  gap: 6px;
  margin-inline: auto;
  padding: 14px 12px;
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
}
.set-rc-msg {
  max-width: 88%;
  padding: 6px 9px;
  border-radius: 14px;
  font-size: 13px;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
.set-rc-msg--out {
  align-self: flex-end;
  border-bottom-right-radius: 5px;
  background: var(--ui-accent);
  color: var(--ui-accent-text);
}
.set-rc-msg--in {
  align-self: flex-start;
  border-bottom-left-radius: 5px;
  background: var(--ui-fill-2);
  color: var(--ui-text);
}
.set-rc-receipt {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 3px 6px;
}
.set-rc-amount {
  font-weight: 590;
}
.set-rc-parts {
  color: var(--ui-hint);
}
:root {
  --template-color-bg: #0c0b0a;
  --template-color-sand-1: #141312;
  --template-color-sand-2: #1c1b19;
  --template-color-sand-3: #2a2825;
  --template-color-border: #2a2825;
  --template-color-border-strong: #3a3835;
  --template-color-text: #f2efe8;
  --template-color-text-muted: #c8c2b8;
  --template-color-icon: #9a9590;
  --template-color-accent: #5a5650;
  --template-color-accent-warm: #d4a853;
  --template-color-accent-olive: #c4842f;
  --template-color-overlay-55: rgba(0, 0, 0, 0.55);
  --template-color-overlay-45: rgba(0, 0, 0, 0.45);
  --template-color-overlay-35: rgba(0, 0, 0, 0.35);
  --template-color-overlay-25: rgba(0, 0, 0, 0.25);
  --template-color-surface-glass: rgba(28, 27, 25, 0.9);
  --template-color-surface-accent-soft: rgba(212, 168, 83, 0.08);
  --template-color-surface-accent: rgba(212, 168, 83, 0.15);
  --template-color-focus: rgba(212, 168, 83, 0.5);
  --template-shadow-strong: 0 12px 40px rgba(0, 0, 0, 0.6);
  --template-shadow-soft: 0 10px 24px rgba(0, 0, 0, 0.2);
  --bg-color: var(--template-color-bg);
  --text-color: var(--template-color-text);
  --text-secondary: var(--template-color-text-muted);
  --mid-gray: var(--template-color-icon);
  --light-gray: var(--template-color-border-strong);
  --separator-color: var(--template-color-border);
  --icon-color: var(--template-color-icon);
  --accent-blue: var(--template-color-accent);
  --accent-yellow: var(--template-color-accent-warm);
  --accent-green: var(--template-color-accent-olive);
  --sand-1: var(--template-color-sand-1);
  --sand-2: var(--template-color-sand-2);
  --sand-3: var(--template-color-sand-3);
  --dialog-bg: var(--template-color-bg);
  --dialog-panel: var(--template-color-sand-1);
  --bubble-out: var(--template-color-accent);
  --bubble-text: var(--template-color-text);
}
.loading-spinner {
  border-color: var(--template-color-border);
  border-top-color: var(--template-color-border-strong);
}
.media-placeholder.media-image {
  background: linear-gradient(
    135deg,
    var(--template-color-sand-1),
    var(--template-color-sand-3)
  );
}
button:focus-visible,
.dialog-item:focus-visible {
  outline: 2px solid var(--template-color-focus);
}

/* ── Profile tab (?section=profile) — reuses page/card/row/button objects ── */
.impito-tabbar__icon svg {
  /* Stroke-based icons (Lucide/Tabler) carry their presentation attributes
     inline — CSS only sizes them. */
  display: block;
  width: 26.4px;
  height: 26.4px;
  margin: 0 auto;
}
#impito-profile {
  min-height: 100vh;
  min-height: 100svh;
}
#impito-profile main[data-anim="fade"] {
  animation: impito-page-in 0.3s var(--ui-ease-out);
}
#impito-profile main[data-anim="push"] {
  animation: impito-push-in 0.34s var(--ui-ease-nav);
}
#impito-profile main[data-anim="pop"] {
  animation: impito-pop-in 0.3s var(--ui-ease-nav);
}
.impito-profile-page.ui-page {
  /* Clear the top veil (Telegram Back/⌄/⋯ live there) on fullscreen phones,
     fall back to a sane header offset elsewhere. */
  padding-top: calc(
    max(
        var(--ui-fullscreen-top) * 1.5 + var(--ui-veil-platform, 0px),
        56px + var(--ui-safe-top)
      ) + 12px
  );
  padding-bottom: calc(120px + var(--ui-safe-bottom));
}
.impito-profile-heading {
  position: fixed;
  top: calc(var(--ui-safe-top) + 11px);
  left: 72px;
  right: 72px;
  z-index: 60;
  overflow: hidden;
  color: var(--ui-text);
  /* Заголовок шапки: 19 → 15.2 → 16.4px (−20%, потом +8%), интерлиньяж следом. */
  font-size: 16.4px;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 23px;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.impito-profile-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 4px 22px 24px;
  text-align: center;
}
.impito-profile-avatar {
  position: relative;
  display: flex;
  width: 96px;
  height: 96px;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: 50%;
  background: #fff;
}
.impito-profile-avatar__img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
}
.impito-profile-avatar__initials {
  color: rgba(43, 16, 32, 0.4);
  font-size: 38px;
  font-weight: 600;
  letter-spacing: 0.01em;
  user-select: none;
}
.impito-profile-avatar__person {
  display: flex;
  color: rgba(43, 16, 32, 0.35);
}
.impito-profile-avatar__person svg {
  width: 44px;
  height: 44px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.impito-profile-name {
  margin: 12px 0 0;
  color: var(--ui-text);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.2;
  overflow-wrap: anywhere;
}
.impito-profile-id {
  /* Раньше 1px — ID подпирал строку @юзернейма. Юзернейм убрали (2026-07-31),
     ID встал прямо под именем, поэтому отступ вернули к нормальному. */
  margin: 5px 0 0;
  padding: 3px 8px;
  border: 0;
  background: none;
  color: var(--ui-hint);
  cursor: pointer;
  font-family: var(--ui-font);
  font-size: 14px;
  font-weight: 400;
  line-height: 1.35;
  font-variant-numeric: tabular-nums;
  -webkit-tap-highlight-color: transparent;
  transition: opacity var(--ui-dur) var(--ui-ease);
}
.impito-profile-id:active {
  opacity: 0.55;
}
.impito-profile-glyph {
  display: flex;
  width: 30px;
  height: 30px;
  align-items: center;
  justify-content: center;
  font-size: 23px;
  line-height: 1;
  user-select: none;
}
.impito-profile-row .ui-row-after {
  color: rgba(43, 16, 32, 0.32);
}
/* Строка с переключателем выше остальных: под заголовком идёт пояснение, и
   иконка обязана держаться по центру блока, а не прыгать к первой строке. */
.impito-profile-row--switch {
  align-items: center;
}
.impito-profile-row--switch .ui-row-body {
  padding-right: 6px;
}
/* Документ, прочитанный из профиля. Своей прокрутки у него нет — страница
   профиля скроллится целиком, поэтому это обычная карточка с текстом. */
.impito-legal-doc {
  padding: 16px;
}
.impito-legal-doc .impito-legal__h:first-of-type {
  margin-top: 0;
}
.impito-profile-chevron {
  width: 8px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.1;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.impito-profile-ext {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.impito-profile-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 58px 34px 40px;
  text-align: center;
}
.impito-profile-empty__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 56px;
  line-height: 1;
  user-select: none;
}
.impito-profile-empty__title {
  margin: 18px 0 0;
  color: var(--ui-text);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.impito-profile-empty__sub {
  margin: 7px 0 0;
  max-width: 300px;
  color: var(--ui-hint);
  font-size: 14.5px;
  line-height: 1.45;
}
.impito-profile-empty__cta {
  margin-top: 22px;
  height: 46px;
  padding: 0 26px;
  font-size: 16px;
}
.impito-profile-reflink .ui-row-title {
  overflow: hidden;
  font-size: 15.5px;
  font-variant-numeric: tabular-nums;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.impito-profile-copy {
  display: flex;
  width: 34px;
  height: 34px;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: var(--ui-accent-soft);
  color: var(--ui-accent);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    background var(--ui-dur) var(--ui-ease),
    color var(--ui-dur) var(--ui-ease),
    transform var(--ui-dur) var(--ui-ease);
}
.impito-profile-copy:active {
  transform: scale(0.92);
}
.impito-profile-copy.is-done {
  background: rgba(52, 199, 89, 0.16);
  color: var(--ui-confirm);
}
.impito-profile-copy svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.impito-profile-ref-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 2px 12px 0;
}
/* Профиль: пополнение баланса (пакеты токенов) */
.impito-profile-page[data-page="topup"],
.impito-profile-page[data-page="shop"] {
  padding-bottom: calc(196px + var(--ui-safe-bottom));
}
/* Экран генерации фото (photo.js). Верх — как у профиля (вылет из-под вуали с
   нативными кнопками Telegram), низ — запас под фиксированную панель с ценой и
   кнопкой: она стоит на 82px + safe-bottom и сама высотой 67px. */
.impito-photo-page.ui-page {
  padding-top: calc(
    max(
        var(--ui-fullscreen-top) * 1.5 + var(--ui-veil-platform, 0px),
        56px + var(--ui-safe-top)
      ) + 12px
  );
  padding-bottom: calc(184px + var(--ui-safe-bottom));
}
/* Своего правила у чипсов этого экрана нет намеренно: базовый `.ui-chips` уже
   переносит их на вторую строку (моделей шесть, в одну строку не влезают) и
   держит отступы дизайн-системы. Класс `.impito-photo-chips` оставлен как
   зацепка на будущее. */

/* ── Формат кадра карточками (2026-07-31) ──
   Вместо чипсов «1:1 / 9:16 / …» — карточки в духе каталога, и внутри каждой
   настоящий кадр этой пропорции: белое поле с пунктирным контуром. Пропорцию
   задаёт inline-стиль от значения (`aspect-ratio: 9/16` и т.д.), а какая
   сторона упирается в карточку — считает js: горизонтальные и квадратные по
   ширине, вертикальные по высоте. */
/* Форматов стало 11 (2026-07-31) — сеткой они занимали три ряда, поэтому это
   лента с горизонтальным листанием, как подборки на главной: те же зазор,
   хвост следующей карточки и привязка. Ширина карточки своя: у неё фиксированная
   пропорция 3:4, и три штуки на экран здесь были бы неоправданно крупными. */
.impito-ratio-rail {
  --ui-rail-gap: 8px;
  --ui-rail-peek: 18px;
  display: flex;
  gap: var(--ui-rail-gap);
  overflow-x: auto;
  padding: 0 12px;
  scrollbar-width: none;
  scroll-padding-right: 12px;
  scroll-padding-left: calc(var(--ui-rail-gap) + var(--ui-rail-peek));
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
.impito-ratio-rail::-webkit-scrollbar {
  display: none;
}
.impito-ratio-rail .impito-ratio {
  width: 82px;
  flex: 0 0 auto;
  scroll-snap-align: start;
}
.impito-ratio {
  display: flex;
  aspect-ratio: 3 / 4;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 10px 6px;
  border: 0;
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
  box-shadow: inset 0 0 0 0.5px rgba(43, 16, 32, 0.08);
  color: var(--ui-text);
  cursor: pointer;
  font: inherit;
  -webkit-tap-highlight-color: transparent;
  transition:
    transform 0.15s var(--ui-ease),
    background-color 0.2s var(--ui-ease),
    color 0.2s var(--ui-ease);
}
.impito-ratio:active {
  transform: scale(0.96);
}
.impito-ratio__frame {
  display: block;
  max-width: 74%;
  /* Ограничения с обеих сторон: у 16:9 ширина упирается первой, у 9:16 —
     высота, и без пары max-* кадр вылезал бы за карточку. */
  max-height: 64%;
  border: 1.5px dashed rgba(43, 16, 32, 0.38);
  border-radius: 5px;
  background: #fff;
}
.impito-ratio__label {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1;
}
.impito-ratio.is-active {
  background: var(--ui-accent);
  color: var(--ui-accent-text);
}
.impito-ratio.is-active .impito-ratio__frame {
  border-color: rgba(255, 255, 255, 0.9);
  background: rgba(255, 255, 255, 0.96);
}

/* «авто» в ленте форматов: пропорции у него нет, поэтому в кадре звёздочка —
   «какой получится». */
.impito-ratio__frame--auto {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ui-accent);
}
/* Звезда «авто». Размер 78% → 62% (−20%, 2026-07-31). Форма мягкая: лучи —
   вогнутые кубические кривые, а кончики скруглены обводкой того же цвета с
   round-соединениями — прежняя угловатая звезда юзеру не понравилась.
   Обводка здесь не контур, а инструмент скругления: цвет у неё тот же, что и
   заливка, поэтому фигура остаётся сплошной. */
.impito-ratio__frame--auto svg {
  width: 62%;
  height: 62%;
  fill: currentColor;
}
.impito-ratio.is-active .impito-ratio__frame--auto {
  color: var(--ui-accent-strong);
}

/* ── Качество ползунком (2026-07-31) ──
   Вместо трёх кнопок — шкала «меньше → больше». Дорожка, заливка и бегунок —
   СВОИ элементы, а нативный `input[type=range]` лежит поверх прозрачным: он
   по-прежнему ловит касания, тянется и работает с клавиатуры, но рисовать его
   псевдоэлементами нельзя — ни трансформировать бегунок, ни повесить на него
   слои стекла. Поэтому вид целиком на своих узлах, поведение — на нативном.
   Подложки-карточки под ползунком нет: он лежит прямо на фоне экрана. */
.impito-quality {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 22px;
}
.impito-quality__cap {
  flex: 0 0 auto;
  color: var(--ui-hint);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
/* Высота с запасом снизу: там ряд делений, он ПОД дорожкой, а не на ней. */
.impito-quality__slider {
  position: relative;
  display: block;
  min-width: 0;
  height: 34px;
  flex: 1 1 auto;
}
.impito-quality__track {
  position: absolute;
  top: 10px;
  right: 0;
  left: 0;
  overflow: hidden;
  height: 8px;
  border-radius: var(--ui-radius-pill);
  background: var(--ui-fill-2);
}
.impito-quality__fill {
  display: block;
  height: 100%;
  border-radius: var(--ui-radius-pill);
  background: var(--ui-accent);
}
/* Деления — ПОД дорожкой, отдельным рядом, как в системном слайдере. Боковые
   поля равны половине ширины бегунка (13.5px), иначе крайние точки не совпадают
   с его центром в крайних положениях. */
.impito-quality__ticks {
  position: absolute;
  top: 30px;
  right: 13.5px;
  left: 13.5px;
  display: flex;
  justify-content: space-between;
  pointer-events: none;
}
.impito-quality__ticks i {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: rgba(43, 16, 32, 0.2);
}
/* Бегунок — капсула той же формы, что кнопка переключателя (радиус пилюли, та
   же тень). Размер: 43x27 → 34x27 («менее длинным») → −20% = 27x22.
   Позицию и «желе» (растяжение по скорости, надувание при удержании) считает
   js и кладёт в transform, поэтому здесь никаких переходов на transform —
   иначе они дрались бы с покадровой анимацией. */
.impito-quality__thumb {
  position: absolute;
  top: 3px;
  left: 0;
  width: 27px;
  height: 22px;
  border-radius: var(--ui-radius-pill);
  background: var(--ui-switch-thumb);
  /* В покое — только внешняя тень и волосяная обводка 0.5px (на 2x/3x это один
     физический пиксель, тоньше не бывает). Тень ВНУТРИ СВЕРХУ здесь НЕ нужна:
     она часть стекла и появляется только на удержании (2026-07-31, просьба
     юзера — в покое она читалась как грязь на белой капсуле). */
  box-shadow:
    0 1px 3px #0003,
    inset 0 0 0 0.5px rgba(43, 16, 32, 0.14);
  pointer-events: none;
  transform-origin: 50% 50%;
  transition:
    box-shadow 0.16s var(--ui-ease),
    background-color 0.16s var(--ui-ease);
  will-change: transform;
}
/* Стекло при удержании: искусственная хроматическая аберрация ТЕМИ ЖЕ
   значениями, что у ползунка таббара на apple (розовый слева/сверху, голубой
   справа/снизу, волосяная обводка и внутреннее затенение). РАЗМЫТИЯ НЕТ
   намеренно — юзер попросил без него, и backdrop-filter здесь не заводится
   вовсе: это самая дорогая часть эффекта, а бегунок ездит покадрово. */
.impito-quality__thumb.is-holding {
  /* При удержании бегунок становится СТЕКЛОМ и подложка уходит В НОЛЬ: молочная
     полупрозрачная заливка юзеру не понравилась, нужен чистый прозрачный кадр
     (2026-07-31). Видимым бегунок остаётся за счёт слоёв ниже — это полный
     рецепт ползунка таббара на apple: волосяная обводка, внутреннее затенение
     (даёт объём стекла) и четыре хроматических слоя искусственной аберрации.
     Размытия нет намеренно — `backdrop-filter` не объявлен вовсе. */
  background: transparent;
  /* Порядок слоёв важен: сначала мягкая внешняя тень, затем та же волосяная
     обводка и тень под верхней кромкой, что в покое, и только потом четыре
     хроматических слоя аберрации. Общее затемнение середины
     (`inset 0 0 10px -6px`) выброшено — оно и давало ту самую муть. */
  box-shadow:
    0 2px 7px rgba(43, 16, 32, 0.22),
    inset 0 0 0 0.5px rgba(43, 16, 32, 0.14),
    inset 0 2.5px 3px -1.5px rgba(43, 16, 32, 0.2),
    inset 2px 0 2.5px -1.5px rgba(255, 0, 132, 0.34),
    inset -2px 0 2.5px -1.5px rgba(0, 168, 255, 0.3),
    inset 0 2px 2.5px -1.5px rgba(255, 64, 160, 0.22),
    inset 0 -2px 2.5px -1.5px rgba(0, 190, 255, 0.2);
}
/* Нативный input: прозрачный, но живой — он и есть область касания. */
.impito-quality__range {
  position: absolute;
  z-index: 2;
  top: 0;
  right: 0;
  left: 0;
  width: 100%;
  height: 28px;
  margin: 0;
  padding: 0;
  border: 0;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  cursor: pointer;
}
.impito-quality__range::-webkit-slider-runnable-track {
  height: 8px;
  background: transparent;
}
.impito-quality__range::-moz-range-track {
  height: 8px;
  background: transparent;
}
.impito-quality__range::-webkit-slider-thumb {
  width: 27px;
  height: 22px;
  margin-top: -7px;
  border: 0;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  opacity: 0;
}
.impito-quality__range::-moz-range-thumb {
  width: 27px;
  height: 22px;
  border: 0;
  background: transparent;
  opacity: 0;
}

/* Строка выбора модели — копия строки настроек бандла: эмодзи слева, название с
   подписью, значение и шеврон справа (2026-07-31, просьба юзера со скриншотом
   «модель фото · Nano 2 ›»). Сама `.ui-row` уже есть, здесь только эмодзи,
   значение и шеврон. */
/* Вместо цветного эмодзи — монохромный знак в акценте: эмодзи выбивался из
   набора (системный глиф не перекрашивается и всегда ярче остального ряда),
   2026-07-31. */
.impito-photo-row__icon {
  display: inline-flex;
  width: 26px;
  height: 26px;
  align-items: center;
  justify-content: center;
  color: var(--ui-accent);
}
.impito-photo-row__icon svg {
  width: 100%;
  height: 100%;
}
/* Тумблер на этом экране — розовый, а не системный зелёный: зелёный выбивался
   из палитры продукта (2026-07-31). Цвет тот же, что у кнопки «генерировать».
   Правило намеренно ограничено экраном генерации: тумблеры чужого бандла на
   главной трогать не стали. */
.impito-photo-page .ui-switch--on {
  background-color: var(--ui-accent);
}
.impito-photo-row__value {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--ui-hint);
  font-size: 17px;
}
/* Строка без шеврона: параметр зафиксирован моделью и не нажимается. Отступ
   справа тот же, что съедал бы шеврон, — иначе значения в карточке не
   выстраиваются в одну колонку. */
.impito-photo-row__value--static {
  padding-right: 8px;
}
/* Плитка видео-референса: та же рамка, что у фото, плюс подпись с длиной
   ролика — по ней сразу видно, уложился он в лимит или нет. */
/* Размеры задаёт сама плитка, а не ролик: у `<video>` без метаданных
   внутренний размер нулевой, и плитка схлопывалась вместе с крестиком. Здесь
   те же 1:1 и то же скругление, что у фото-превью. */
.impito-video-ref video {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  border-radius: 18px;
  background: rgba(43, 16, 32, 0.06);
  object-fit: cover;
  box-shadow: inset 0 0 0 0.5px rgba(43, 16, 32, 0.08);
}
.impito-video-ref__badge {
  position: absolute;
  bottom: 6px;
  left: 6px;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(20, 8, 15, 0.55);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
  pointer-events: none;
}
/* Модель без референсов: вместо пустой сетки — объяснение. */
.impito-style-photos-note {
  margin: 0;
  /* Тот же отступ 22px, что у заголовка секции: иначе текст висит у самого
     края экрана, а подпись над ним — с отбивкой. */
  padding: 0 22px;
  color: var(--ui-hint);
  font-size: 15px;
  line-height: 1.35;
}
.impito-photo-row__chevron {
  width: 8px;
  height: 14px;
  flex: 0 0 auto;
  color: var(--ui-hint);
  opacity: 0.7;
}
/* Выбранная модель в листе — акцентом, чтобы было видно, что уже стоит. */
.impito-sheet__option.is-active {
  color: var(--ui-accent-strong);
  font-weight: 600;
}
.impito-topup-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin: 0 12px;
}
/* Хиро-баланс в стиле iOS (Battery/Screen Time): подпись → крупное число → единица */
.impito-topup-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 6px 22px 2px;
  text-align: center;
}
.impito-topup-hero__label {
  color: var(--ui-hint);
  font-size: 13px;
  font-weight: 510;
  letter-spacing: 0.02em;
  line-height: 1.2;
}
.impito-topup-hero__value {
  margin-top: 2px;
  color: var(--ui-text);
  font-size: 44px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
  line-height: 1.05;
}
.impito-topup-hero__unit {
  margin-top: 1px;
  color: var(--ui-hint);
  font-size: 14px;
  line-height: 1.3;
}
.impito-topup-custom.ui-card {
  margin-top: 10px;
}
.impito-topup-custom__field {
  font-variant-numeric: tabular-nums;
}
.impito-topup-promo.ui-card {
  margin-top: 10px;
}
/* Экран «Медиа»: плитки 1-в-1 как карточки каталога стилей (3:4, скрим,
   белый заголовок, каскад); фото из /settings/media-tiles/, палитровый
   градиент тона — подложка на время загрузки картинки */
.impito-media-tile--photo {
  background: linear-gradient(
    160deg,
    #f6a8ce 0%,
    var(--ui-accent) 58%,
    var(--ui-accent-strong) 100%
  );
}
.impito-media-tile--video {
  background: linear-gradient(160deg, #b58cfa 0%, #9d63f8 55%, var(--ui-pro) 100%);
}
.impito-media-tile--enhance {
  background: linear-gradient(160deg, #7fe796 0%, #4bd865 55%, #2fae4c 100%);
}
.impito-topup-pack {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 13px 14px 12px;
  border: 0;
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
  color: var(--ui-text);
  cursor: pointer;
  font-family: var(--ui-font);
  text-align: left;
  -webkit-tap-highlight-color: transparent;
  transition:
    background var(--ui-dur) var(--ui-ease),
    transform var(--ui-dur) var(--ui-ease);
}
.impito-topup-pack:active {
  transform: scale(0.97);
}
.impito-topup-pack.is-active {
  background: #fff;
}
.impito-topup-pack__tag {
  position: absolute;
  top: 11px;
  right: 11px;
  max-width: calc(100% - 58px);
  overflow: hidden;
  padding: 4px 9px;
  border-radius: var(--ui-radius-pill);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.impito-topup-pack__tag--accent {
  background: var(--ui-accent);
}
.impito-topup-pack__tag--confirm {
  background: var(--ui-confirm);
}
.impito-topup-pack__off {
  color: var(--ui-accent);
  font-size: 12.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  line-height: 1.2;
}
.impito-topup-pack__tokens {
  margin-top: 10px;
  font-size: 27px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.05;
}
.impito-topup-pack__unit {
  color: var(--ui-hint);
  font-size: 12.5px;
  line-height: 1.35;
}
.impito-topup-pack__price {
  margin-top: 9px;
  font-size: 15.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}
.impito-topup-pack__per {
  margin-top: 1px;
  color: var(--ui-hint);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  line-height: 1.35;
}
.impito-topup-submit__inner .impito-topup-total {
  width: auto;
  min-width: 0;
  padding-left: 10px;
}
/* Цена в одну строку: «1 200 ₽», а не число над валютой */
.impito-topup-total .impito-style-cost__value {
  flex-direction: row;
  align-items: baseline;
  gap: 4px;
}
.impito-topup-total .impito-style-cost__value strong {
  font-size: 20px;
}
.impito-topup-total .impito-style-cost__value span {
  font-size: 15px;
}
.impito-topup-submit__inner .impito-style-generate {
  height: 38px;
  justify-self: end;
  padding: 0 18px;
  font-size: 15px;
}
.impito-topup-meta {
  position: relative;
  z-index: 1;
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 3px;
  padding: 0 4px;
}
.impito-topup-meta__tokens {
  color: var(--ui-text);
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.15;
  white-space: nowrap;
}
.impito-topup-meta__savings {
  color: var(--ui-hint);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
  white-space: nowrap;
}
.impito-topup-submit__inner .is-swap {
  animation: impito-topup-swap 0.26s var(--ui-ease-out);
}
@keyframes impito-topup-swap {
  from {
    opacity: 0.15;
    transform: translateY(5px);
  }
}

/* ── Вкладка «История» ──
   Полки как в каталоге стилей: жирный чёрный заголовок с шевроном, под ним
   три строки в колонке, дальше листается вбок и справа выглядывает следующая
   (2026-07-31, просьба юзера). Белой панели под строками нет — она визуально
   спорила с полками и «ломала» ощущение ленты. */
.impito-hist-section {
  margin-bottom: 26px;
}
/* Первый заголовок упирался в верхнюю панель — отводим его вниз. */
.impito-hist-section:first-of-type {
  margin-top: 10px;
}
.impito-hist-rail {
  /* Ручки те же, что у полок каталога и рейлов главной. */
  align-content: start;
  --ui-rail-gap: 8px;
  --ui-rail-peek: 18px;
  display: grid;
  /* Колонка шириной почти во весь экран: строка длинная, и «три в ряд» тут не
     годится — из колонки должен выглядывать только край следующей. */
  grid-auto-columns: calc(100% - var(--ui-rail-peek) - var(--ui-rail-gap));
  grid-auto-flow: column;
  grid-template-rows: repeat(3, auto);
  gap: var(--ui-rail-gap);
  overflow-x: auto;
  padding: 0 12px;
  scrollbar-width: none;
  scroll-padding-right: 12px;
  scroll-padding-left: calc(var(--ui-rail-gap) + var(--ui-rail-peek));
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}
.impito-hist-rail::-webkit-scrollbar {
  display: none;
}
.impito-hist-empty {
  margin: 0;
  padding: 2px 22px 0;
  color: var(--ui-hint);
  font-size: 14px;
}
/* Без панели-подложки: юзер попросил вместо карточек тонкие серые разделители,
   как в списках Apple Music. Строка — просто строка на фоне экрана. */
.impito-hist-row {
  --ui-hist-thumb: 64px;
  --ui-hist-gap: 12px;
  position: relative;
  display: flex;
  width: 100%;
  align-items: center;
  padding: 7px 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  gap: var(--ui-hist-gap);
  scroll-snap-align: start;
  text-align: left;
  -webkit-tap-highlight-color: transparent;
}
/* Линия идёт ТОЛЬКО под текстом, под превью её нет — как в списках Apple Music
   (2026-07-31, замечание юзера). Поэтому псевдоэлемент со сдвигом на ширину
   превью, а не border у всей строки. */
.impito-hist-row::after {
  position: absolute;
  right: 0;
  bottom: 0;
  left: calc(var(--ui-hist-thumb) + var(--ui-hist-gap));
  height: 0.5px;
  background: rgba(43, 16, 32, 0.12);
  content: "";
}
.impito-hist-row:active {
  opacity: 0.55;
}
/* Последняя строка в колонке полки и в конце списка — без линии снизу.
   В полке поток по колонкам, поэтому «последняя» — каждая третья. */
.impito-hist-rail .impito-hist-row:nth-child(3n)::after,
.impito-hist-list .impito-hist-row:last-child::after {
  display: none;
}
/* Экран «все генерации»: обычный вертикальный список. */
.impito-hist-list {
  padding: 0 16px;
}
.impito-hist-row.is-running,
.impito-hist-row.is-failed,
.impito-hist-row.is-skeleton {
  cursor: default;
}
.impito-hist-row__thumb {
  position: relative;
  display: flex;
  overflow: hidden;
  width: var(--ui-hist-thumb);
  height: var(--ui-hist-thumb);
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  border-radius: 13px;
  background: rgba(120, 108, 117, 0.12);
}
.impito-hist-row__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* «Фотка тёмная размытая и кружочек-индикатор» — просьба юзера. */
.impito-hist-row__thumb.is-running {
  background: linear-gradient(160deg, #f6a8ce 0%, var(--ui-accent) 58%, var(--ui-accent-strong) 100%);
  filter: brightness(0.62) saturate(0.9);
}
.impito-hist-row__spinner {
  width: 19px;
  height: 19px;
  border: 2.2px solid rgba(255, 255, 255, 0.35);
  border-radius: 50%;
  border-top-color: #fff;
  animation: impito-gen-spin 0.9s linear infinite;
}
@keyframes impito-gen-spin {
  to {
    transform: rotate(360deg);
  }
}
.impito-hist-row__thumb.is-failed {
  color: var(--ui-hint);
  font-size: 20px;
  font-weight: 700;
}
.impito-hist-row__body {
  display: flex;
  min-width: 0;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 3px;
}
/* Промпт — одной строкой с многоточием: юзер просил показывать только часть. */
.impito-hist-row__title {
  overflow: hidden;
  color: var(--ui-text);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.impito-hist-row__meta {
  overflow: hidden;
  color: var(--ui-hint);
  font-size: 12.5px;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.impito-hist-row__after {
  display: flex;
  width: 10px;
  height: 16px;
  flex: 0 0 auto;
  color: rgba(43, 16, 32, 0.25);
}
.impito-hist-row__after svg {
  width: 10px;
  height: 16px;
}
.impito-hist-row.is-skeleton .impito-hist-row__body {
  height: 32px;
  border-radius: 10px;
  background: rgba(120, 108, 117, 0.1);
}

/* Лист выбора формата скачивания */
.impito-gen-sheet {
  position: fixed;
  z-index: 190;
  inset: 0;
}
.impito-gen-sheet__backdrop {
  position: absolute;
  background: rgba(20, 6, 14, 0.32);
  inset: 0;
}
.impito-gen-sheet__body {
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px 14px calc(18px + var(--ui-safe-bottom));
  border-radius: var(--ui-radius-card) var(--ui-radius-card) 0 0;
  background: var(--ui-bg);
  inset: auto 0 0 0;
  animation: impito-sheet-up var(--ui-dur, 0.22s) var(--ui-ease, ease) both;
}
@keyframes impito-sheet-up {
  from {
    transform: translateY(12%);
    opacity: 0;
  }
}
.impito-gen-sheet__group {
  display: flex;
  overflow: hidden;
  flex-direction: column;
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
}
.impito-gen-sheet__index {
  padding: 10px 14px 2px;
  color: var(--ui-hint);
  font-size: 12px;
}
/* Строка листа. Раньше это была только ссылка `<a>`; с появлением отправки в
   чат часть строк стала `<button>`, и им нужен сброс — иначе браузер рисует
   свою рамку и фон. */
.impito-gen-sheet__row {
  display: flex;
  width: 100%;
  align-items: center;
  padding: 13px 14px;
  border: 0;
  background: none;
  color: var(--ui-text);
  font-family: inherit;
  font-size: 15px;
  gap: 12px;
  text-align: left;
  text-decoration: none;
}
.impito-gen-sheet__row:active {
  background: rgba(43, 16, 32, 0.05);
}
.impito-gen-sheet__icon {
  display: flex;
  width: 22px;
  height: 22px;
  color: var(--ui-accent);
}
.impito-gen-sheet__icon svg {
  width: 22px;
  height: 22px;
}

/* ── Карточка одной генерации ─────────────────────────────────────────────
   Кадр во всю ширину, под ним одно главное действие, дальше параметры и
   промпт. Порядок именно такой: на этот экран приходят посмотреть результат,
   а не читать характеристики. */
/* Поля по бокам — те же 12px, что у `.ui-card`: раньше кадр и кнопка шли от
   края до края, а карточка параметров под ними была с отступом, и экран
   выглядел собранным из разных кусков. */
/* Нижнее поле задаём ЯВНО: сокращённая запись `margin: 0 12px` обнуляла
   `margin-bottom: 24px` из `.ui-section`, и кнопка прилипала к кадру. */
.impito-gen-detail__frame {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin: 0 12px 26px;
}
/* Коробка подстраивается под кадр, а не кадр под коробку. Раньше стояло
   `width: 100%` + `max-height` + `object-fit: contain`: потолок высоты сжимал
   коробку, пропорция переставала совпадать с картинкой, и `contain` дорисовывал
   пустые поля по бокам — выглядело как кривая вёрстка. Теперь размеры
   ограничены сверху, но считаются по самому изображению: полей не бывает
   никогда, а вертикальный кадр не занимает пол-экрана. */
.impito-gen-detail__image {
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: 54vh;
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
}
/* Заявка без файла: компактная строка вместо пустого квадрата во весь экран. */
.impito-gen-detail__missing {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 12px;
  padding: 16px 18px;
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
}
.impito-gen-detail__missing-icon {
  display: flex;
  width: 26px;
  height: 26px;
  flex: 0 0 auto;
  color: var(--ui-hint);
}
.impito-gen-detail__missing-icon svg {
  width: 26px;
  height: 26px;
}
.impito-gen-detail__missing-text {
  margin: 0;
  color: var(--ui-hint);
  font-size: 14px;
  line-height: 1.35;
}
/* Заглушка на время загрузки: та же серая заливка, что у скелетона строк
   истории (.impito-hist-row.is-skeleton), чтобы два состояния загрузки на
   одном экране выглядели одинаково. */
.impito-gen-detail__image.is-skeleton {
  width: 100%;
  aspect-ratio: 1;
  background: rgba(120, 108, 117, 0.1);
}
/* Точки-переключатели кадров: у заявки на несколько картинок результат один,
   а кадров много — листаем ими, а не отдельным экраном. */
.impito-gen-detail__pager {
  display: flex;
  gap: 7px;
}
.impito-gen-detail__dot {
  width: 7px;
  height: 7px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(43, 16, 32, 0.22);
  transition: background 0.18s ease, transform 0.18s ease;
}
.impito-gen-detail__dot.is-active {
  background: var(--ui-accent);
  transform: scale(1.25);
}
.impito-gen-detail__save {
  width: calc(100% - 24px);
  margin: 0 12px;
}
.impito-gen-detail__prompt.is-empty {
  color: var(--ui-hint);
}
.impito-gen-detail__value {
  color: var(--ui-hint);
  font-size: 16px;
}
/* Правый край: у заголовка секции свои 22px внутреннего поля, а у кнопки их
   не было — текст упирался в кромку экрана и обрезался. Поле повторяем, чтобы
   «промпт» и «копировать» стояли на одинаковых отступах от краёв. */
.impito-gen-detail__copy {
  margin-bottom: 9px;
  padding: 0 22px 0 10px;
  border: 0;
  background: none;
  color: var(--ui-accent-strong);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
}
.impito-gen-detail__copy:active {
  opacity: 0.55;
}
/* Промпт бывает длинный (у стилей — под две тысячи знаков), поэтому переносим
   по словам и не режем: это единственное место, где юзер может его прочитать
   целиком. */
.impito-gen-detail__prompt {
  margin: 0;
  padding: 14px;
  color: var(--ui-text);
  font-size: 15px;
  line-height: 1.42;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}
/* Подтверждение действия. Над таббаром, живёт около двух секунд.
   Появление и уход — ОДНОЙ анимацией на всю жизнь плашки, без переключения
   классов: переход по `opacity`, навешиваемый сразу после вставки узла, в
   вебвью не всегда успевает зарегистрировать начальное состояние и застревает
   на полупрозрачности. Keyframes такого поведения не имеют. */
.impito-gen-toast {
  position: fixed;
  z-index: 210;
  bottom: calc(96px + var(--ui-safe-bottom));
  left: 50%;
  max-width: calc(100% - 48px);
  padding: 11px 18px;
  transform: translate(-50%, 0);
  border-radius: 999px;
  background: rgba(20, 6, 14, 0.88);
  color: #fff;
  font-size: 14px;
  font-weight: 500;
  animation: impito-toast 2.4s ease both;
  pointer-events: none;
}
@keyframes impito-toast {
  0% {
    transform: translate(-50%, 10px);
    opacity: 0;
  }
  8%,
  88% {
    transform: translate(-50%, 0);
    opacity: 1;
  }
  100% {
    transform: translate(-50%, 6px);
    opacity: 0;
  }
}

/* ── Замок мини-аппы (правила не приняты / открыто не из Telegram) ──
   Накладка кроет ВСЁ, включая таббар (z-index 80) — иначе по вкладкам можно
   было бы гулять мимо замка. Экран под ней остаётся отрендеренным: после
   принятия правил накладка просто снимается, без перезагрузки. */
.impito-gate {
  position: fixed;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  inset: 0;
  background: var(--ui-bg);
  /* Плавное появление: замок прилетает после ответа сервера, и без этого он
     возникал бы рывком поверх уже нарисованного экрана. */
  animation: impito-gate-in var(--ui-dur, 0.22s) var(--ui-ease, ease) both;
}
@keyframes impito-gate-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.impito-gate__card {
  display: flex;
  width: 100%;
  max-width: 340px;
  flex-direction: column;
  align-items: center;
  padding: 26px 22px 22px;
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
  box-shadow: 0 0 0 0.5px rgba(43, 16, 32, 0.14);
  text-align: center;
}
.impito-gate__icon {
  display: flex;
  width: 54px;
  height: 54px;
  align-items: center;
  justify-content: center;
  margin-bottom: 14px;
  border-radius: 50%;
  background: rgba(230, 98, 165, 0.14);
  color: var(--ui-accent);
}
.impito-gate__icon svg {
  width: 26px;
  height: 26px;
}
.impito-gate__title {
  margin: 0;
  color: var(--ui-text);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.25;
}
.impito-gate__text {
  margin: 8px 0 0;
  color: var(--ui-hint);
  font-size: 14px;
  line-height: 1.4;
}
.impito-gate__actions {
  display: flex;
  width: 100%;
  flex-direction: column;
  gap: 8px;
  margin-top: 18px;
}
/* Полная пилюля. Специфичность взята с запасом не для красоты: на главной
   действует `body.impito-home-active .ui-button` с карточным радиусом (0,2,1),
   и правило послабее проигрывало — угол читался как «полуквадрат»
   (2026-07-31, замечание юзера). */
.impito-gate .impito-gate__actions .ui-button {
  border-radius: 999px;
}
/* ── Экран принятия документов (редакция 2.0) ─────────────────────────────
   Обычный замок — короткая карточка по центру. Экран согласия длинный, и
   центрирование загоняло его верх под панель Telegram с кнопками Close/⌄/⋯.
   Поэтому здесь: прижим к верху, отступ по той же формуле, что у страниц
   приложения, и прокрутка ВСЕЙ накладки, а не карточки внутри неё —
   вложенный скролл на телефоне ловится пальцем через раз. */
.impito-gate--consent {
  align-items: stretch;
  justify-content: flex-start;
  overflow-y: auto;
  padding: calc(
      max(
          var(--ui-fullscreen-top) * 1.5 + var(--ui-veil-platform, 0px),
          56px + var(--ui-safe-top)
        ) + 12px
    )
    12px calc(28px + var(--ui-safe-bottom));
  -webkit-overflow-scrolling: touch;
}
.impito-gate__card--consent {
  width: 100%;
  max-width: 440px;
  margin: 0 auto;
  /* Единое поле со всех сторон — блоки внутри тянутся на всю ширину, поэтому
     левый и правый край у заголовка, документов, галок и кнопки совпадают. */
  padding: 20px;
  text-align: left;
}
/* `flex-shrink: 0` обязателен: карточка — колоночный флекс, и её дети по
   умолчанию ужимаются. Блок документов с `overflow: hidden` из-за этого
   обрезался на середине второй строки. */
.impito-gate__card--consent > * {
  align-self: stretch;
  flex-shrink: 0;
}
/* Документы — строки-карточки, как настройки в аппе. Открываются ДО принятия
   (ТЗ v2.0, п. 4.5): читать можно, не давая доступа к балансу и истории. */
.impito-gate__docs {
  display: flex;
  overflow: hidden;
  flex-direction: column;
  margin-top: 16px;
  border-radius: var(--ui-radius-card);
  background: rgba(255, 255, 255, 0.5);
}
.impito-gate__doc {
  display: flex;
  align-items: center;
  padding: 12px 14px;
  border: 0;
  background: none;
  gap: 12px;
  text-align: left;
}
.impito-gate__doc + .impito-gate__doc {
  box-shadow: inset 0 0.5px 0 rgba(43, 16, 32, 0.1);
}
.impito-gate__doc:active {
  background: rgba(43, 16, 32, 0.04);
}
.impito-gate__doc-icon {
  display: flex;
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  color: var(--ui-accent);
}
.impito-gate__doc-icon svg {
  width: 22px;
  height: 22px;
}
.impito-gate__doc-body {
  display: flex;
  min-width: 0;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 1px;
}
.impito-gate__doc-title {
  color: var(--ui-text);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.25;
}
.impito-gate__doc-sub {
  color: var(--ui-hint);
  font-size: 12px;
}
.impito-gate__doc-chevron {
  width: 8px;
  height: 14px;
  flex: 0 0 auto;
  color: var(--ui-hint);
  opacity: 0.7;
}
/* Два обязательных пункта. Каждый — отдельная строка с отдельной галкой,
   объединять их в одну нельзя (ТЗ v2.0, п. 1.4). */
.impito-gate__checks {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 18px;
}
.impito-gate__check {
  display: flex;
  align-items: flex-start;
  padding: 0;
  border: 0;
  background: none;
  gap: 11px;
  text-align: left;
}
.impito-gate__box {
  display: grid;
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  margin-top: 1px;
  border-radius: 7px;
  background: rgba(43, 16, 32, 0.08);
  box-shadow: inset 0 0 0 1.5px rgba(43, 16, 32, 0.16);
  color: transparent;
  place-items: center;
  transition:
    background 0.16s var(--ui-ease, ease),
    box-shadow 0.16s var(--ui-ease, ease);
}
.impito-gate__box svg {
  width: 13px;
  height: 13px;
}
.impito-gate__check.is-on .impito-gate__box {
  background: var(--ui-accent);
  box-shadow: none;
  color: #fff;
}
.impito-gate__check-text {
  color: var(--ui-text);
  font-size: 14px;
  line-height: 1.4;
}
.impito-gate__check-text b {
  font-weight: 600;
}
/* Реклама — НЕобязательна и выключена по умолчанию (ТЗ v2.0, п. 1.5).
   Визуально отделена от обязательных пунктов, чтобы её не читали как третье
   условие доступа. */
.impito-gate__optional {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 18px;
  padding: 12px 14px;
  border-radius: var(--ui-radius-card);
  background: rgba(255, 255, 255, 0.5);
}
.impito-gate__optional-body {
  display: flex;
  min-width: 0;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 2px;
}
.impito-gate__optional-title {
  color: var(--ui-text);
  font-size: 15px;
  font-weight: 500;
}
.impito-gate__optional-sub {
  color: var(--ui-hint);
  font-size: 12.5px;
  line-height: 1.35;
}
.impito-gate__error {
  margin: 14px 0 0;
  color: var(--ui-accent-strong);
  font-size: 13px;
  line-height: 1.35;
}
/* Кнопка неактивна, пока не стоят обе обязательные галки (ТЗ v2.0, п. 1.6). */
.impito-gate .impito-gate__actions .ui-button[disabled] {
  opacity: 0.4;
  pointer-events: none;
}
.impito-gate__support {
  margin-top: 12px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ui-hint);
  font-size: 13px;
  text-align: center;
}

/* ── Чтение документа прямо в приложении ──────────────────────────────────
   PDF внутри мини-аппы неудобен: он уводит во внешний просмотрщик и рвёт
   сценарий принятия. Поэтому текст показывается своим экраном — с шапкой,
   кнопкой возврата и обычной прокруткой. */
.impito-legal {
  display: flex;
  width: 100%;
  height: 100%;
  flex-direction: column;
  align-self: stretch;
}
.impito-legal__head {
  position: relative;
  display: flex;
  height: 46px;
  flex: 0 0 auto;
  align-items: center;
  gap: 10px;
  margin-top: calc(
    max(
      var(--ui-fullscreen-top) * 1.5 + var(--ui-veil-platform, 0px),
      56px + var(--ui-safe-top)
    ) - 24px
  );
}
.impito-legal__back {
  display: grid;
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.55);
  color: var(--ui-accent-strong);
  place-items: center;
}
.impito-legal__back svg {
  width: 11px;
  height: 18px;
}
.impito-legal__head-title {
  min-width: 0;
  overflow: hidden;
  color: var(--ui-text);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.impito-legal__scroll {
  overflow-y: auto;
  flex: 1 1 auto;
  margin-top: 10px;
  padding: 16px 16px calc(24px + var(--ui-safe-bottom));
  border-radius: var(--ui-radius-card);
  background: var(--ui-card);
  -webkit-overflow-scrolling: touch;
}
.impito-legal__meta {
  margin: 0 0 14px;
  color: var(--ui-hint);
  font-size: 12.5px;
  line-height: 1.35;
}
.impito-legal__h {
  margin: 20px 0 8px;
  color: var(--ui-text);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.3;
}
.impito-legal__h:first-of-type {
  margin-top: 4px;
}
.impito-legal__sub {
  margin: 16px 0 6px;
  color: var(--ui-text);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.4;
}
.impito-legal__p {
  margin: 0 0 9px;
  color: var(--ui-text);
  font-size: 14px;
  line-height: 1.5;
}
/* Маркер рисуем псевдоэлементом, а не списком: у документа встречаются
   абзацы на несколько строк, и висячий отступ должен держаться сам. */
.impito-legal__li {
  position: relative;
  margin: 0 0 9px;
  padding-left: 16px;
  color: var(--ui-text);
  font-size: 14px;
  line-height: 1.5;
}
.impito-legal__li::before {
  position: absolute;
  top: 0;
  left: 2px;
  color: var(--ui-accent);
  content: "•";
}

/* Скролл страницы под замком не нужен: он создаёт ощущение, что до контента
   всё-таки можно дотянуться. */
html.impito-gate-open,
html.impito-gate-open body {
  overflow: hidden;
}

/* ── Главная (?section отсутствует) ──
   home.js вставляет #impito-home перед #root. С 2026-07-31 чужой React-бандл
   на главной не монтируется вообще, #root пустой, поэтому вся страница — наша.
   Отсюда и нижний отступ: раньше его держала страница бандла, а у нашей стоял
   padding-bottom: 0, и без бандла последний рейл уезжал бы под таббар. */
body.impito-home-active .impito-home-page {
  /* Тот же вылет из-под верхней вуали, что у профиля: там живут нативные
     Back/⌄/⋯ Telegram. */
  padding-top: calc(
    max(
        var(--ui-fullscreen-top) * 1.5 + var(--ui-veil-platform, 0px),
        56px + var(--ui-safe-top)
      ) + 12px
  );
  padding-bottom: calc(116px + var(--ui-safe-bottom));
}

/* Ни карточки, ни маскота — только приветствие крупным заголовком экрана
   (2026-07-31, решение юзера). Панель с персонажем занимала четверть первого
   экрана и ничего не сообщала; теперь страница начинается с контента.
   Отступ слева тот же 22px, что у заголовков секций ниже, — заголовок и
   «генерировать» стоят на одной вертикали. */
.impito-home-hero.ui-section {
  margin: 0 0 30px;
  /* Верхний отступ от панели с «Главная»: при 2px заголовок вплотную подходил
     к её нижней кромке. */
  padding: 18px 22px 0;
}
/* 30px/700 — та же ступень, что у `.ui-page-title` на других экранах, и на
   треть крупнее заголовков секций (22px): иерархия «страница → раздел»
   держится размером, без второго цвета и без подложки. */
.impito-home-hero__hi {
  display: block;
  max-width: 100%;
  overflow: hidden;
  margin: 0;
  color: var(--ui-text);
  font-size: 30px;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.1;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Имя акцентом: в строке из двух слов оно и есть смысл, «привет» — служебное. */
.impito-home-hero__name {
  color: var(--ui-accent-strong);
}

.impito-home-rail-section.ui-section {
  margin-bottom: 22px;
}
.impito-home-rail__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  /* Под крупным заголовком нужно больше воздуха, чем под меткой 13px. */
  margin: 0 0 11px;
  padding: 0 22px;
}
/* Крупный тёмный заголовок секции в духе iOS (2026-07-31, «сверху чёрный жирный
   текст, сделай так же над карточками»): им подписаны «генерировать» и «стили».
   Серая метка 13px/510 осталась только у чужого бандла ниже — там
   это `.ui-section-header`, и его вид не трогаем.
   Класс намеренно СВОЙ, а не `.ui-section-header`: таббар ищет секции по ТЕКСТУ
   этого класса (labels «фото»/«видео» в index.html), и лишние заголовки в общем
   пуле — готовая ловушка. */
.impito-home-rail__title {
  min-width: 0;
  overflow: hidden;
  color: var(--ui-text);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Подзаголовок полки внутри раздела: «новые», «популярное». Раньше они были
   такими же крупными, как «генерировать», и читались как равные ему разделы —
   отсюда путаница (2026-07-31, просьба юзера). Теперь это мелкая серая метка,
   а вес держит общий заголовок «стили» над ними. */
.impito-home-rail__title--sub {
  color: var(--ui-section-header);
  font-size: 13px;
  font-weight: 510;
  letter-spacing: 0.02em;
}
/* Между заголовком раздела и первой полкой воздуха нужно меньше: подпись мелкая
   и иначе висит в пустоте. Сверху наоборот — отбивка от ленты «генерировать»,
   иначе «стили» прилипают к карточкам над ними (2026-07-31, просьба юзера). */
/* Отступ над заголовком задаётся ПАДДИНГОМ самого заголовка, а лента выше
   обнулена: два margin-а схлопываются в больший, и щель просто не уменьшалась
   бы правкой одного из них. */
.impito-home-rail-section.impito-home-create-section {
  margin-bottom: 0;
}
.impito-home-group.ui-section {
  margin-top: 0;
  padding-top: 12px;
  margin-bottom: 6px;
}
.impito-home-group .impito-home-rail__head {
  margin-bottom: 0;
}
.impito-home-rail__all {
  flex: 0 0 auto;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ui-accent-strong);
  cursor: pointer;
  font-family: var(--ui-font);
  /* 13 → 15px: рядом с меткой 13px размер совпадал, а рядом с заголовком 22px
     ссылка выглядела потерянной (2026-07-31, следствие смены заголовков). */
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.2;
  white-space: nowrap;
  -webkit-tap-highlight-color: transparent;
}
.impito-home-rail__all:active {
  opacity: 0.6;
}
/* Ширина карточки в любом рейле: три карточки влезают целиком, четвёртая
   выглядывает на --ui-rail-peek (2026-07-31, просьба юзера). Раньше стояла
   константа 132px, и на 375px кроме трёх карточек торчал почти весь кусок
   четвёртой.
   Откуда `+ 12px`: проценты в ширине считаются от СОДЕРЖИМОГО рейла, то есть
   уже без обоих его полей по 12px. А место перед первой карточкой занимает
   только левое поле — правое возвращаем обратно. Если менять `padding` рейла,
   править и эту константу.
   Формула на всю строку: 12 (левое поле) + 3 карточки + 3 зазора + хвост
   четвёртой = ширина экрана. */
:root {
  --ui-rail-card-3up: calc(
    (100% + 12px - var(--ui-rail-gap, 8px) * 3 - var(--ui-rail-peek, 18px)) / 3
  );
}
.impito-home-rail {
  /* Две ручки этого рейла, крутить только их:
     --ui-rail-gap  — зазор между карточками;
     --ui-rail-peek — ширина «хвоста» предыдущей карточки, который остаётся
                      торчать слева, когда рейл встал на карточку (2026-07-30,
                      просьба юзера «как в Apple Music»).
     Механика хвоста: `scroll-snap-align: start` прижимает левый край карточки
     не к кромке рейла, а к кромке его snapport — а её и сдвигает
     `scroll-padding-left`. Правый край предыдущей карточки оказывается на
     (padding − gap) от кромки, то есть ровно на --ui-rail-peek. Раньше
     scroll-padding был равен gap, разница выходила нулевой — и хвоста не было
     вовсе. */
  --ui-rail-gap: 8px;
  --ui-rail-peek: 18px;
  --ui-rail-card: var(--ui-rail-card-3up);
  display: flex;
  gap: var(--ui-rail-gap);
  overflow-x: auto;
  /* Боковой padding вместо margin: иначе первая и последняя карточка липнут к
     кромке экрана при скролле рейла. */
  padding: 0 12px;
  scrollbar-width: none;
  scroll-padding-right: 12px;
  scroll-padding-left: calc(var(--ui-rail-gap) + var(--ui-rail-peek));
  /* Именно mandatory, а не proximity: при proximity браузер прилипает только
     если остановились рядом с точкой, и хвост слева получался лотереей. */
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}
.impito-home-rail::-webkit-scrollbar {
  display: none;
}
.impito-home-rail__card {
  width: var(--ui-rail-card);
  flex: 0 0 auto;
  scroll-snap-align: start;
}

/* ── Витрина каталога по категориям (вкладка «все») ──
   2026-07-31, просьба юзера: вместо сплошной кучи карточек — полка на каждую
   тему, заголовок жирным с шевроном (тап = открыть категорию целиком), внутри
   ДВА ряда карточек с горизонтальным листанием.
   Полка живёт по тем же правилам, что рейлы главной (зазор, хвост предыдущей
   карточки, привязка) — отличие одно: раскладка не в строку, а в колонки по
   два ряда. */
.impito-cat-section {
  margin-bottom: 26px;
}
.impito-cat-rail__head {
  display: flex;
  align-items: center;
  gap: 4px;
  width: 100%;
  margin: 0 0 11px;
  padding: 0 22px;
  border: 0;
  background: transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.impito-cat-rail__head:active {
  opacity: 0.6;
}
.impito-cat-rail__title {
  min-width: 0;
  overflow: hidden;
  color: var(--ui-text);
  font-family: var(--ui-font);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.2;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Шеврон приглушён и мельче заголовка — как в iOS: он подсказка «тут есть
   продолжение», а не самостоятельная кнопка. */
.impito-cat-rail__chevron {
  width: 11px;
  height: 18px;
  flex: 0 0 auto;
  margin-top: 1px;
  color: var(--ui-hint);
}
.impito-cat-rail {
  /* Ручки те же, что у рейлов главной. */
  --ui-rail-gap: 8px;
  --ui-rail-peek: 18px;
  --ui-rail-card: var(--ui-rail-card-3up);
  display: grid;
  /* Два ряда, поток по колонкам: карточки заполняют сначала верх и низ одной
     колонки, потом следующую. Именно grid, а не flex-wrap — wrap в
     горизонтальном скроллере переносит по ширине вьюпорта, а не по двум рядам. */
  grid-auto-columns: var(--ui-rail-card);
  grid-auto-flow: column;
  grid-template-rows: repeat(2, auto);
  gap: var(--ui-rail-gap);
  overflow-x: auto;
  padding: 0 12px;
  scrollbar-width: none;
  scroll-padding-right: 12px;
  scroll-padding-left: calc(var(--ui-rail-gap) + var(--ui-rail-peek));
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}
/* Короткие подборки (до 4 карточек) — один ряд: два ряда из трёх карточек дают
   полторы колонки и выглядят обрубком. */
.impito-cat-rail--single {
  grid-template-rows: auto;
}
.impito-cat-rail::-webkit-scrollbar {
  display: none;
}
.impito-cat-rail .impito-style-card {
  /* Ширину задаёт колонка сетки — карточка просто занимает её целиком. */
  width: 100%;
  scroll-snap-align: start;
}
/* Карточка узкая (132px против 171px в сетке) — подписи на шаг мельче, иначе
   название в два клампа съедает половину картинки. Те же значения, что у
   рейлов главной. */
.impito-cat-rail .impito-style-card__overlay {
  padding: 28px 11px 10px;
}
.impito-cat-rail .impito-style-card__name {
  font-size: 14px;
}
/* Кикер тут выключен: в подборке категории он повторял бы её название на каждой
   из 12 карточек, прямо под заголовком с этим же словом. На главной кикер
   остаётся — там подборки смешанные, и категория действительно что-то говорит. */
.impito-cat-rail .impito-style-card__kicker {
  display: none;
}
/* Единый радиус на главной (2026-07-30, «одинаковый радиус везде, включая
   кнопки, как у менюшки настроек»). Карточки, плитки и герой уже жили на
   --ui-radius-card (22px) — из общего ряда выбивалась только кнопка. Правило
   ограничено главным экраном: на остальных экранах кнопки-пилюли остаются.
   ВАЖНО про геометрию: у кнопки высота 40px, а браузер обрезает радиус до
   половины меньшей стороны — то есть рисует 20px. Разница с пилюлей на такой
   высоте почти незаметна; чтобы угол читался как у карточки, кнопку пришлось бы
   делать выше, а этого юзер не просил. */
body.impito-home-active .ui-button {
  border-radius: var(--ui-radius-card);
}
.impito-home-rail__card .impito-style-card__overlay {
  padding: 28px 11px 10px;
}
/* Рейл «генерировать»: названия — одиночные слова, переносить их некуда, а
   самое длинное («реставрация») на 14px не влезало в карточку 103px и
   обрезалось. Замерено: 14px → 99px текста, 13px → 92px, 12px → 85px при 87px
   поля (это уже с урезанным боковым padding). Отсюда 12px + padding 8px —
   меньше не нужно, больше не влезает. */
.impito-home-create .impito-style-card__overlay {
  padding-right: 8px;
  padding-left: 8px;
}
.impito-home-create .impito-style-card__name {
  font-size: 12px;
}
/* Карточка рейла узкая (132px против 171px в каталоге) — заголовок и кикер на
   шаг мельче, иначе название в два клампа занимает половину карточки. */
.impito-home-rail__card .impito-style-card__name {
  font-size: 14px;
}
.impito-home-rail__card .impito-style-card__kicker {
  font-size: 11px;
}

/* ── Плашка с токенами в правом нижнем углу верхней вуали ──
   Живёт на всех экранах: вуаль общая, и баланс логично видеть везде.
   Прижата к НИЗУ вуали через --ui-veil-height, а не к safe-top: сверху там
   нативные кнопки Telegram (Close / ⌄ / ⋯) и заголовок экрана, плашка обязана
   оставаться под ними при любой высоте панели.
   Обводки нет намеренно (просьба юзера) — только полупрозрачная заливка и
   размытие. Свой backdrop-filter поверх вуали даёт второй фильтрованный слой,
   но он крошечный и статичный, в отличие от масок внутри едущей пилюли. */
/* Метрики сняты с нативной кнопки Telegram (⌄ ⋯) по скриншотам юзера (375pt,
   3x): ширина ≈ 74px, высота ≈ 30px, правый отступ ≈ 15px (не 12). Юзер
   сравнил вживую и сказал «длиннее и чуть уже» — плашка была 32px высотой и
   ~57px шириной, то есть на 2px выше и заметно короче кнопки. Отсюда
   `min-width` под ширину кнопки и высота 30px. */
.impito-token-pill {
  position: fixed;
  /* Отсчёт от кромки пропорциональной части вуали (= низ вуали минус
     добавленная полоса), минус подъём. Внизу под плашкой остаётся 4px вуали:
     22px полосы = 18px плашки, вылезшей ниже кромки, плюс просвет. */
  top: calc(
    var(--ui-veil-height) - var(--ui-veil-pill-row) - var(--ui-veil-pill-lift)
  );
  right: 16px;
  /* Выше вуали (40) и заголовка (60), ниже таббара (80). */
  z-index: 61;
  display: inline-flex;
  align-items: center;
  /* В потоке остаётся ТОЛЬКО число — монета и плюс выведены из потока и висят у
     кромок. За счёт этого и симметричных полей центр числа совпадает с центром
     плашки при любом значении (просьба юзера: «цифра ровно по центру панели»),
     а не центр группы «монета + число». */
  justify-content: center;
  /* min-width, а не width: с четырёхзначным балансом плашка должна растягиваться,
     а не обрезать цифры. 74 → 72px (2026-07-30, «короче на 2px») — на 2px уже
     нативной кнопки. */
  min-width: 72px;
  /* 30 → 28 → 29px (2026-07-30, «узже на 2px», затем «шире на 1px»). В словаре
     юзера «длиннее/короче» — это ширина, «шире/узже» — высота. */
  height: 29px;
  /* Поля СИММЕТРИЧНЫЕ и равны зоне монеты/плюса: только так центр числа
     совпадает с центром плашки и при этом число не может залезть ни на монету,
     ни на плюс — они оба вне потока и ширину не занимают. Растёт плашка тоже
     симметрично, число остаётся в центре. Значение = отступ фланга (7px) + его
     бокс (18px) + просвет 3px. На короткие значения не влияет: там ширину
     держит min-width. */
  padding: 0 28px;
  border: 0;
  border-radius: var(--ui-radius-pill);
  /* Темнее (просьба юзера): было rgba(255,255,255,0.42) — почти белая плашка.
     Теперь тёмная подложка цветом текста на малой альфе: поверх розовой вуали
     это даёт тот же приглушённый мокко-тон, что у нативной кнопки.
     Альфа: 0.10 → 0.12 («чуть темнее») → 0.08 («светлее на 4%») → 0.10
     («темнее на 2%», 2026-07-30). Считается не на глаз, а через композит поверх
     розовой вуали по красному каналу `247*(1-a) + 43*a`: при 0.08 это 231,
     −2% = 226.4, обратная подстановка даёт a ≈ 0.101. Заодно это ровно +2 пункта
     альфы — оба чтения «на N процентов» сходятся. Это ручка тона. */
  background: rgba(43, 16, 32, 0.1);
  /* Блюр 6 → 18px (2026-07-30, «сильнее в 3 раза»). На самой вуали разница
     сдержанная — её подложка и так 80% и уже размыта; сильнее это читается там,
     где под плашкой едет контент (шапка каталога, карточки под ней). */
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
  font-family: var(--ui-font);
  font-size: 14.5px;
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1;
  white-space: nowrap;
  /* Тап ведёт в магазин (просьба юзера 2026-07-30), поэтому плашка кликабельна.
     До этого стояло pointer-events: none, чтобы не перехватывать тапы у
     нативных кнопок Telegram — сейчас от них 8px зазора и она ниже, так что
     риск только визуальной близости. */
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    opacity 0.22s var(--ui-ease),
    transform 0.22s var(--ui-ease);
}
.impito-token-pill:active,
.impito-profile-pill:active {
  transform: scale(0.94);
}
/* Монета и плюс — оба вне потока, оба центрированы по вертикали одинаково
   (top: 50% + translateY), поэтому лежат на одном уровне с числом и друг с
   другом. Это иконки, а не глифы: у SVG нет расхождения между базовой линией и
   математической осью, из-за которого текстовый «+» казался выше цифры. */
.impito-token-pill__coin,
.impito-token-pill__plus {
  position: absolute;
  top: 50%;
  display: block;
  transform: translateY(-50%);
}
/* Одинаковые боксы и одинаковые отступы от кромок — иначе воздух слева до
   монеты и справа до плюса разъезжается. Оба SVG нарисованы так, чтобы ink
   заполнял свой viewBox почти целиком, поэтому равные отступы дают равный
   визуальный воздух. */
.impito-token-pill__coin,
.impito-token-pill__plus {
  width: 18px;
  height: 18px;
}
.impito-token-pill__coin {
  left: 7px;
  color: rgba(43, 16, 32, 0.5);
}
.impito-token-pill__plus {
  right: 7px;
  /* Акцент — тот же цвет, что у кнопки «пополнить» (.ui-button). Заливка кружка
     идёт через fill="currentColor" внутри svg. */
  color: var(--ui-accent);
}
.impito-token-pill__coin svg,
.impito-token-pill__plus svg {
  display: block;
  width: 100%;
  height: 100%;
}
.impito-token-pill__value {
  /* Серый вместо --ui-text; альфа 0.58 (--ui-hint) → 0.55 (2026-07-30,
     «светлее на 5%»): композит текста поверх плашки по красному каналу
     227*(1-a) + 43*a при 0.58 даёт 120, +5% = 126, обратная подстановка даёт
     a ≈ 0.548. Это ручка яркости текста. */
  color: rgba(43, 16, 32, 0.55);
  font-variant-numeric: tabular-nums;
}

/* ── Пилюля профиля слева на верхней вуали ──
   Аватар 32px + имя, тап ведёт в профиль. Стоит на одном уровне с плашкой
   баланса: вертикальные центры выровнены, поэтому у неё свой сдвиг −1.5px
   (высота 32 против 29 у плашки баланса). Подложка, размытие и радиус — те же,
   чтобы читались как одна пара элементов. */
.impito-profile-pill {
  position: fixed;
  /* +0.5px, чтобы вертикальный центр совпал с плашкой баланса: у неё высота 29,
     здесь 28. */
  top: calc(
    var(--ui-veil-height) - var(--ui-veil-pill-row) - var(--ui-veil-pill-lift) +
      0.5px
  );
  /* Левый край выровнен по нативной кнопке Close над ним: при 16px аватар стоял
     на 2–3px левее неё (замечено юзером на устройстве). Поля нет, поэтому
     `left` — это сразу левая кромка аватара. */
  left: 19px;
  z-index: 61;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  max-width: 46%;
  /* Высота больше визуального контента (аватар 16px): бокс держит комфортную
     цель тапа, а подложки у него нет. */
  height: 28px;
  padding: 0;
  border: 0;
  /* Ни подложки, ни размытия, ни обводки — только аватар и имя (просьба юзера). */
  background: transparent;
  cursor: pointer;
  font-family: var(--ui-font);
  -webkit-tap-highlight-color: transparent;
  transition:
    opacity 0.22s var(--ui-ease),
    transform 0.22s var(--ui-ease);
}
.impito-profile-pill__avatar {
  position: relative;
  overflow: hidden;
  /* 32 → 16px (просьба юзера «в 2 раза меньше»). */
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--ui-fill-2);
}
.impito-profile-pill__avatar img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.impito-profile-pill__avatar.is-fallback {
  display: grid;
  place-items: center;
  background: var(--ui-accent-soft);
  color: var(--ui-accent-strong);
  font-size: 9px;
  font-weight: 700;
  line-height: 1;
}
.impito-profile-pill__name {
  min-width: 0;
  overflow: hidden;
  color: rgba(43, 16, 32, 0.55);
  font-size: 14.5px;
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Схлопывание верхней панели при скролле вниз ──
   Класс ставит скролл-слушатель в index.html. Идея: вниз — панель возвращается
   в состояние «как было до плашки баланса и профиля», обе пилюли растворяются;
   вверх (и на самом верху) — возвращаются.
   Механика: обнуляется ТОЛЬКО добавленная полоса --ui-veil-pill-row, а
   пропорциональная часть вуали не трогается. За счёт этого схлопнутая панель
   байт-в-байт равна прежней, а `top` у пилюль (veil − row − lift) не меняется:
   они гаснут на месте, без рывка. Анимируется height у body:before — переход
   разовый, на переключение состояния, а не на каждый кадр скролла. */
html.impito-topbar-collapsed {
  --ui-veil-pill-row: 0px;
}
body:before {
  transition: height 0.28s var(--ui-ease);
}
html.impito-topbar-collapsed .impito-token-pill,
html.impito-topbar-collapsed .impito-profile-pill {
  opacity: 0;
  /* Небольшой подъём заодно: пилюли «испаряются» вверх, к панели. */
  transform: translateY(-4px);
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  body:before,
  .impito-style-sticky,
  .impito-token-pill,
  .impito-profile-pill {
    transition: none;
  }
}
/* ── Первый кадр: панель не «выезжает» ──
   Вся геометрия вуали считается от --ui-fullscreen-top, а его выставляет js уже
   ПОСЛЕ первой отрисовки: модули грузятся как type="module" (то есть отложенно),
   да и сами инсеты Telegram отдаёт асинхронно, отдельными событиями. До этого
   момента переменная равна 0, вуаль вырождена в тонкую полоску, и когда
   приходит настоящий инсет, `transition: height` честно анимирует рост — панель
   выезжала сверху вниз при каждом заходе на экран (2026-07-30, видео с
   устройства).
   Класс `impito-boot` ставится в <head> ДО первого кадра и снимается скриптом в
   index.html, когда высота панели перестала меняться. Внутри класса нет ничего,
   кроме подмены переходов: раскладка не трогается, поэтому на готовом экране
   поведение прежнее.
   Переходы не выключены совсем, а сведены к одному `opacity`. Так высота и
   поля в это время меняются МГНОВЕННО (панель не едет), но остаётся чем
   проявить её целиком — см. `impito-panel-hold` ниже. */
html.impito-boot body:before,
html.impito-boot .impito-style-sticky,
html.impito-boot .impito-token-pill,
html.impito-boot .impito-profile-pill,
html.impito-boot .impito-profile-heading {
  transition: opacity 0.24s var(--ui-ease);
}
@media (prefers-reduced-motion: reduce) {
  /* Должно стоять ПОСЛЕ правила выше: специфичность равная, решает порядок. */
  html.impito-boot body:before,
  html.impito-boot .impito-style-sticky,
  html.impito-boot .impito-token-pill,
  html.impito-boot .impito-profile-pill,
  html.impito-boot .impito-profile-heading {
    transition: none;
  }
}
/* ── Панель проявляется целиком, а не по кускам ──
   Стекло вуали рисуется из css сразу, а заголовок, поиск и чипсы монтирует js
   уже после загрузки модулей. Получалась лесенка: сначала пустая панель, через
   мгновение в ней появлялся текст (2026-07-30, «сначала панель загрузилась,
   потом текст по центру — не гармонично»).
   Поэтому СОДЕРЖИМОЕ панели держится прозрачным, пока оно не готово, и
   проявляется одним движением. Класс снимает скрипт в index.html, когда в DOM
   появился заголовок экрана И высота панели устоялась.
   САМО СТЕКЛО В ЭТОТ СПИСОК НЕ ВХОДИТ, И ЭТО ПРИНЦИПИАЛЬНО. Первая версия
   держала прозрачной и вуаль тоже — тогда сквозь пустое место просвечивал
   контент страницы, и юзер увидел «текст за панелью при анимации прогрузки».
   Вуаль (`body:before`) и шапка каталога (`.impito-style-sticky`) — это и есть
   подложка, она обязана быть на месте с первого кадра. Шапка каталога вдобавок
   монтируется вместе со своим содержимым, одним куском, — прятать её незачем.
   Именно opacity, а не visibility/display: элементы всё это время занимают своё
   место, поэтому проявление ничего не двигает. */
html.impito-panel-hold .impito-profile-heading,
html.impito-panel-hold .impito-token-pill,
html.impito-panel-hold .impito-profile-pill {
  opacity: 0;
}
/* Экран профиля — панель классическая: ни пилюль сверху (их там не создаёт
   скрипт), ни добавленной полосы под них. Класс ставится в index.html по
   ?section=profile. */
html.impito-topbar-plain {
  --ui-veil-pill-row: 0px;
}
/* Схлопнутая шапка каталога подтягивается ВЫШЕ низа вуали, а не на 8px ниже:
   в этом состоянии пилюль нет, и запас под них превращался в пустую полосу
   между нативными кнопками и поиском (2026-07-30, «там пиздец места есть»).
   `−14px` возвращает поиск примерно к исходному `56px + safe-top` — значению,
   с которым экран жил до появления пилюль; max() не даёт уехать выше него. */
html.impito-topbar-collapsed .impito-style-sticky {
  padding-top: max(
    calc(56px + var(--ui-safe-top)),
    calc(var(--ui-veil-height) - 14px)
  );
}

/* На Android (флаг data-font-platform="inter", ставится в <head> по
   Telegram.WebApp.platform / UA) нативные кнопки Telegram стоят ближе к правой
   кромке, чем на iOS. Из-за этого плашка баланса, подогнанная по iOS-метрикам
   (right: 16px), уходила левее кнопки ⌄⋯ над ней. Сдвиг ровно на 4px вправо,
   iOS не затронут. Это отдельная ручка: если разъедется на другом Android —
   крутить только её. */
html[data-font-platform="inter"] .impito-token-pill {
  /* 16 → 12 → 8px: после первого сдвига юзер сказал «маловато», добавили ещё 4px. */
  right: 8px;
}

/* ── Telegram Desktop: нативных инсетов нет ──
   На десктопе кнопки Close/⋯ живут в хроме окна Telegram, ВНЕ вебвью, и
   `--ui-fullscreen-top` равен 0. Пропорциональная часть вуали от него и
   считается, поэтому вырождалась в 0: панель оставалась высотой в одну
   добавленную полосу (22px), пилюли уезжали на `top: -15px` за верхнюю кромку,
   а заголовок экрана оставался без подложки прямо над контентом.
   Класс ставит скрипт в index.html, когда инсет нулевой. Мобильные значения
   при этом не затронуты вообще — правило живёт только в этом режиме.
   Числа: база 34px + полоса 22px = вуаль 56px; подъём 22px даёт пилюлям
   top 12px и низ 41px, то есть они внутри вуали, а заголовок (11..34) накрыт. */
html.impito-flat-top {
  /* База 34 → 45px: в СЖАТОМ состоянии вуаль равна ровно базе, а заголовок
     экрана занимает 11..34, то есть сверху оставалось 11px, а снизу 0 — панель
     выглядела обрезанной по тексту (2026-07-30, замечено на компе). 45 = 34 + 11
     даёт симметричные 11px сверху и снизу.
     Подъём 22 → 33px компенсирует это ровно настолько, чтобы пилюли остались на
     прежнем месте: их top = база − подъём = 12px, как и было. */
  --ui-veil-base: 45px;
  --ui-veil-pill-lift: 33px;
}
/* Полоса под пилюли на десктопе уже: 11px вместо 22. Так развёрнутая панель
   остаётся прежней высоты (45 + 11 = 56), а сжимается на меньшую величину.
   Оба `:not()` обязательны: правила схлопывания и классической панели
   (`--ui-veil-pill-row: 0`) стоят ВЫШЕ по файлу, и без исключений это правило
   перебивало бы их по специфичности — на компе панель перестала бы сжиматься,
   а в магазине и профиле оставалась бы полоса под несуществующие пилюли. */
html.impito-flat-top:not(.impito-topbar-collapsed):not(.impito-topbar-plain) {
  --ui-veil-pill-row: 11px;
}

/* Лист «не хватает токенов» и ошибки генерации — на той же основе, что лист
   скачивания в истории. */
.impito-balance-sheet__title {
  margin: 0;
  padding: 16px 16px 4px;
  color: var(--ui-text);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-align: center;
}
.impito-balance-sheet__sub {
  margin: 0;
  padding: 0 16px 16px;
  color: var(--ui-hint);
  font-size: 14px;
  line-height: 1.35;
  text-align: center;
}

/* ── Панель администратора ──
   Тот же язык, что у остальных экранов: карточки, строки, свитчи. */
.impito-admin__loading {
  padding: 24px 16px;
  color: var(--ui-hint);
  font-size: 14px;
  text-align: center;
}
.impito-admin-stat {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 11px 14px;
  gap: 12px;
}
.impito-admin-stat + .impito-admin-stat {
  border-top: 0.5px solid rgba(43, 16, 32, 0.08);
}
.impito-admin-stat--stack {
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
}
.impito-admin-stat__label {
  color: var(--ui-hint);
  font-size: 14px;
}
.impito-admin-stat__value {
  color: var(--ui-text);
  font-size: 15px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.impito-admin-stat__error {
  color: var(--ui-text);
  font-size: 12.5px;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.impito-admin-form {
  display: flex;
  flex-direction: column;
  padding: 14px;
  gap: 10px;
}
.impito-admin-form__row {
  display: flex;
  gap: 8px;
}
.impito-admin-input {
  width: 100%;
  padding: 11px 12px;
  border: 0;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.72);
  box-shadow: inset 0 0 0 0.5px rgba(43, 16, 32, 0.12);
  color: var(--ui-text);
  font-family: var(--ui-font);
  font-size: 15px;
}
.impito-admin-input:focus {
  outline: none;
  box-shadow: inset 0 0 0 1px var(--ui-accent);
}
.impito-admin-input--area {
  resize: none;
}
.impito-admin-hint {
  margin: 0;
  color: var(--ui-hint);
  font-size: 12.5px;
  line-height: 1.35;
}
.impito-admin-hint--audience {
  margin-top: -2px;
}

/* Переключатель аудитории. Два состояния, между ними пропасть по смыслу:
   «всем» — сервисное, «по согласию» — рекламное. Поэтому не выпадающий
   список, а видимый выбор с числами получателей. */
.impito-admin-seg {
  display: flex;
  padding: 3px;
  border-radius: 14px;
  background: rgba(43, 16, 32, 0.06);
  gap: 3px;
}
.impito-admin-seg__item {
  display: flex;
  flex: 1 1 0;
  align-items: center;
  justify-content: center;
  padding: 9px 8px;
  border: 0;
  border-radius: 11px;
  background: transparent;
  color: var(--ui-hint);
  font-family: var(--ui-font);
  font-size: 14px;
  font-weight: 600;
  gap: 6px;
  transition:
    background var(--ui-dur) var(--ui-ease),
    color var(--ui-dur) var(--ui-ease);
}
.impito-admin-seg__item.is-active {
  background: var(--ui-card);
  box-shadow: 0 1px 3px rgba(43, 16, 32, 0.12);
  color: var(--ui-text);
}
.impito-admin-seg__count {
  color: var(--ui-hint);
  font-size: 12.5px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.impito-admin-seg__item.is-active .impito-admin-seg__count {
  color: var(--ui-accent);
}

/* Панель оформления. Кнопки квадратные и одинаковые: они читаются как один
   инструмент, а не как разрозненные действия. */
/* Сетка, а не флекс: при флексе десятая кнопка уезжала на вторую строку одна,
   и панель читалась как сломанная. Колонки тянутся по ширине карточки. */
.impito-admin-tools {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(30px, 1fr));
  gap: 5px;
}
.impito-admin-tool {
  display: grid;
  width: 100%;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.72);
  box-shadow: inset 0 0 0 0.5px rgba(43, 16, 32, 0.12);
  color: var(--ui-text);
  font-family: var(--ui-font);
  font-size: 15px;
  place-items: center;
  transition: background var(--ui-dur) var(--ui-ease);
}
.impito-admin-tool:active {
  background: var(--ui-accent-soft, rgba(214, 51, 132, 0.14));
}

/* Предпросмотр. Показывает ровно те теги, что уйдут в Telegram — чтобы
   «жирный + курсив» проверялся глазами до отправки, а не после. */
.impito-admin-preview {
  padding: 11px 12px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.55);
  box-shadow: inset 0 0 0 0.5px rgba(43, 16, 32, 0.1);
}
.impito-admin-preview__label {
  display: block;
  margin-bottom: 5px;
  color: var(--ui-hint);
  font-size: 11px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.impito-admin-preview__body {
  color: var(--ui-text);
  font-size: 15px;
  line-height: 1.4;
  overflow-wrap: anywhere;
}
.impito-admin-preview__body code,
.impito-admin-preview__body pre {
  padding: 1px 4px;
  border-radius: 6px;
  background: rgba(43, 16, 32, 0.08);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13.5px;
}
.impito-admin-preview__body pre {
  display: block;
  margin: 6px 0;
  padding: 8px 10px;
  white-space: pre-wrap;
}
.impito-admin-preview__body blockquote {
  margin: 6px 0;
  padding-left: 10px;
  border-left: 3px solid var(--ui-accent);
}
.impito-admin-preview__link {
  color: var(--ui-accent);
  text-decoration: underline;
}
/* Скрытый текст: в Telegram он закрашен до нажатия — так и показываем. */
.impito-admin-preview__spoiler {
  border-radius: 4px;
  background: rgba(43, 16, 32, 0.55);
  color: transparent;
}

.impito-gate__diag {
  margin: 10px 0 0;
  color: var(--ui-hint);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}

/* Лист «платёж создан»: тот же лист, что у выбора модели, только с текстом. */
.impito-pay-sheet__title {
  margin: 0;
  padding: 16px 18px 4px;
  color: var(--ui-text);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-align: center;
}
.impito-pay-sheet__text {
  margin: 0;
  padding: 0 18px 16px;
  color: var(--ui-hint);
  font-size: 14px;
  line-height: 1.35;
  text-align: center;
}
