/* Kai's app, drawn like Telegram itself.
   Colours come from Telegram's theme (native.js copies themeParams into --tg-theme-*); outside
   Telegram the fallbacks are Telegram's own default palettes. Two platform skins, like Telegram's
   own apps and its Mini Apps UI kit: .ios (iOS, macOS) — inset rounded groups, grey uppercase
   section headers, a floating glass tab bar; .android (Android, desktop, web) — full-width
   sections with accent headers and a Material bottom bar. */

:root {
  color-scheme: light;
  --bg: var(--tg-theme-bg-color, #ffffff);
  --page: var(--tg-theme-secondary-bg-color, #efeff4);
  --section: var(--tg-theme-section-bg-color, var(--tg-theme-bg-color, #ffffff));
  --text: var(--tg-theme-text-color, #000000);
  --hint: var(--tg-theme-hint-color, #8e8e93);
  --subtitle: var(--tg-theme-subtitle-text-color, var(--hint));
  --link: var(--tg-theme-link-color, #007aff);
  --accent: var(--tg-theme-accent-text-color, var(--link));
  --button: var(--tg-theme-button-color, #007aff);
  --button-text: var(--tg-theme-button-text-color, #ffffff);
  --section-header: var(--tg-theme-section-header-text-color, #6d6d72);
  --destructive: var(--tg-theme-destructive-text-color, #ff3b30);
  --separator: var(--tg-theme-section-separator-color, rgba(60, 60, 67, 0.2));
  --bar: var(--tg-theme-bottom-bar-bg-color, var(--section));
  --fill: rgba(118, 118, 128, 0.12);
  --fill-strong: rgba(118, 118, 128, 0.2);
  --pressed: rgba(0, 0, 0, 0.06);
  --tint: rgba(0, 122, 255, 0.1);
  --tint: color-mix(in srgb, var(--accent) 12%, transparent);
  --green: #34c759;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
  --float-shadow: 0 10px 30px rgba(0, 0, 0, 0.12), 0 1px 3px rgba(0, 0, 0, 0.08);
  --scrim: rgba(0, 0, 0, 0.36);
  /* Kai's own colours (the intro film): mascot, brand tile, illustrations. */
  --kai-teal: #0e9e9a;
  --kai-mint: #8fdcc6;
  --kai-face: #e3f6ef;
  --kai-ink: #1f2a33;
  --kai-coral: #ff7a5c;
  --kai-sun: #ffc93f;
  --kai-sky: #8db6ff;
  --kai-lilac: #b79bff;

  --safe-top: max(env(safe-area-inset-top, 0px), var(--tg-safe-area-inset-top, 0px));
  --safe-bottom: max(env(safe-area-inset-bottom, 0px), var(--tg-safe-area-inset-bottom, 0px));
  --content-top: calc(var(--safe-top) + var(--tg-content-safe-area-inset-top, 0px));
  --content-bottom: calc(var(--safe-bottom) + var(--tg-content-safe-area-inset-bottom, 0px));
  --gutter: 16px;
  --radius: 12px;
  --cell-pad: 16px;
  --cell-gap: 14px;
  --cell-y: 11px;
  --tile: 30px;
  --tile-radius: 8px;
  --title-size: 17px;
  --subtitle-size: 15px;
  --tabbar-h: 64px;
  --ease: cubic-bezier(0.2, 0.9, 0.25, 1);
  --spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  font-family: system-ui, -apple-system, BlinkMacSystemFont, "SF Pro Text", Roboto, "Helvetica Neue", "Segoe UI", sans-serif;
  font-size: 17px;
  line-height: 1.3;
  background: var(--page);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
:root.android {
  --gutter: 0px;
  --radius: 0px;
  --cell-pad: 20px;
  --cell-gap: 20px;
  --cell-y: 12px;
  --tile: 32px;
  --tile-radius: 10px;
  --title-size: 16px;
  --subtitle-size: 14px;
  --page: var(--tg-theme-secondary-bg-color, #f0f0f0);
  --hint: var(--tg-theme-hint-color, #707579);
  --section-header: var(--tg-theme-accent-text-color, var(--tg-theme-link-color, #3390ec));
  --link: var(--tg-theme-link-color, #3390ec);
  --button: var(--tg-theme-button-color, #3390ec);
  --destructive: var(--tg-theme-destructive-text-color, #e53935);
  --green: #31b545;
  font-family: Roboto, system-ui, "Segoe UI", "Helvetica Neue", sans-serif;
  font-size: 16px;
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: var(--tg-theme-bg-color, #1c1c1d);
  --page: var(--tg-theme-secondary-bg-color, #000000);
  --section: var(--tg-theme-section-bg-color, var(--tg-theme-bg-color, #1c1c1d));
  --text: var(--tg-theme-text-color, #ffffff);
  --hint: var(--tg-theme-hint-color, #98989e);
  --section-header: var(--tg-theme-section-header-text-color, #8d8e93);
  --separator: var(--tg-theme-section-separator-color, rgba(84, 84, 88, 0.6));
  --fill: rgba(118, 118, 128, 0.24);
  --fill-strong: rgba(118, 118, 128, 0.34);
  --pressed: rgba(255, 255, 255, 0.07);
  --shadow: none;
  --float-shadow: 0 10px 30px rgba(0, 0, 0, 0.5), 0 0 0 0.5px rgba(255, 255, 255, 0.1);
  --scrim: rgba(0, 0, 0, 0.55);
  --green: #30d158;
  --kai-face: #d9f2ea;
}
:root.android[data-theme="dark"] {
  --bg: var(--tg-theme-bg-color, #212121);
  --page: var(--tg-theme-secondary-bg-color, #0f0f0f);
  --section: var(--tg-theme-section-bg-color, var(--tg-theme-bg-color, #212121));
  --hint: var(--tg-theme-hint-color, #aaaaaa);
  --section-header: var(--tg-theme-accent-text-color, var(--tg-theme-link-color, #8774e1));
  --link: var(--tg-theme-link-color, #8774e1);
  --button: var(--tg-theme-button-color, #8774e1);
}

* { box-sizing: border-box; }
body { margin: 0; min-height: 100vh; min-height: 100dvh; background: var(--page); overscroll-behavior-y: none; }
button, input, textarea, select { font: inherit; color: inherit; letter-spacing: inherit; }
button, a, input, select, textarea, label, [role="button"] { -webkit-tap-highlight-color: transparent; }
button { cursor: pointer; }
button:disabled { cursor: default; }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
/* Fields show the caret, sheets their own edge: no ring on either. */
dialog:focus-visible, .search input:focus-visible, .input-group :is(input, textarea, select):focus-visible, .input-row :is(input, select):focus-visible { outline: none; }
[hidden] { display: none !important; }
p { margin: 0; }
h1, h2, h3 { margin: 0; font-weight: 700; }
a { color: var(--link); text-decoration: none; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ---- the frame ------------------------------------------------------------------------ */
.app {
  max-width: 640px;
  margin: 0 auto;
  min-height: 100vh;
  min-height: 100dvh;
  padding-top: var(--content-top);
  padding-bottom: calc(var(--tabbar-h) + 28px + var(--content-bottom));
}
.app.no-tabs { padding-bottom: calc(24px + var(--content-bottom)); }
#view { position: relative; }
.screen { padding: 0 var(--gutter) 8px; }
.screen.leaving { position: absolute; inset: 0 0 auto 0; pointer-events: none; }

/* The app bar: a compact title that appears when the large one scrolls away, and a back button
   where Telegram gives none (a browser, an installed app). */
.appbar {
  position: sticky;
  top: 0;
  z-index: 8;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  min-height: 44px;
  padding: calc(var(--content-top) * 0) 8px 0;
  margin-top: calc(-1 * var(--content-top));
  padding-top: var(--content-top);
  background: transparent;
  transition: background 0.2s ease, box-shadow 0.2s ease;
}
.appbar.solid {
  background: color-mix(in srgb, var(--page) 86%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  box-shadow: 0 0.5px 0 var(--separator);
}
.appbar-title {
  grid-column: 2;
  max-width: 60vw;
  font-size: 17px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.appbar.solid .appbar-title { opacity: 1; transform: none; }
.appbar-back {
  grid-column: 1;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  min-height: 44px;
  padding: 0 10px 0 4px;
  border: 0;
  background: none;
  color: var(--link);
  font-size: 17px;
}
.appbar-back .i { --i: 26px; }
.appbar-end { grid-column: 3; justify-self: end; display: flex; gap: 4px; }
.in-telegram .appbar-back { display: none; }
/* Android outside Telegram: a bare ← in a 48px target, the title (once the large one scrolls
   away) beside it on the left, like Telegram for Android. */
.android:not(.in-telegram) .appbar { grid-template-columns: auto minmax(0, 1fr) auto; padding: var(--content-top) 4px 0; min-height: 56px; }
.android .appbar-back { justify-content: center; width: 48px; min-height: 48px; padding: 0; border-radius: 50%; color: var(--text); }
.android .appbar-back span { display: none; }
.android .appbar-back .i { --i: 24px; stroke-width: 2; }
.android:not(.in-telegram) .appbar-title { justify-self: start; max-width: 100%; padding: 0 12px; font-size: 19px; font-weight: 500; }
.android .appbar-back:not([hidden]) + .appbar-title { padding-left: 8px; }
/* A heading that takes focus after a navigation (for screen readers) shows no ring. */
.screen h1[tabindex="-1"]:focus, #view:focus { outline: none; }

/* Large title, like Telegram's settings and Wallet: big on top, compact in the bar on scroll. */
.title-block { padding: 6px calc(var(--cell-pad) - var(--gutter) + 4px) 14px; }
.ios .title-block { padding-left: 4px; padding-right: 4px; }
.title-block h1 { font-size: 34px; line-height: 41px; letter-spacing: -0.4px; }
.android .title-block { padding: 10px 20px 12px; }
.android .title-block h1 { font-size: 26px; line-height: 32px; font-weight: 600; letter-spacing: 0; }
.title-block p { margin-top: 4px; color: var(--hint); font-size: 15px; line-height: 20px; }
.sub .title-block h1 { font-size: 28px; line-height: 34px; }
.android.sub .title-block h1, .android .sub .title-block h1 { font-size: 22px; line-height: 28px; }

/* ---- sections: a header, a body of cells, a footer ------------------------------------- */
.section { margin-top: 24px; }
.section:first-child, .title-block + .section { margin-top: 4px; }
.section-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 0 16px 7px;
  color: var(--section-header);
  font-size: 13px;
  line-height: 16px;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.1px;
}
.section-header .section-more {
  border: 0;
  background: none;
  padding: 10px 0 10px 12px;
  margin: -10px 0;
  color: var(--link);
  font-size: 15px;
  text-transform: none;
  letter-spacing: 0;
}
.section-header.large {
  padding: 0 4px 10px;
  color: var(--text);
  font-size: 22px;
  line-height: 28px;
  font-weight: 700;
  text-transform: none;
  letter-spacing: -0.3px;
}
.section-body {
  background: var(--section);
  border-radius: var(--radius);
  overflow: hidden;
  isolation: isolate;
}
.section-body.plain { background: none; border-radius: 0; overflow: visible; }
.section-footer { padding: 7px 16px 0; color: var(--section-header); font-size: 13px; line-height: 17px; }
.section-footer a, .section-footer button.link { color: var(--link); }
.ios .section-footer { color: var(--hint); }

.android .section { margin-top: 12px; }
.android .section:first-child, .android .title-block + .section { margin-top: 0; }
.android .section:has(> .section-header:not(.large)) .section-body,
.android .section > .section-body { box-shadow: var(--shadow); }
.android .section-header:not(.large) {
  padding: 16px 20px 6px;
  margin-bottom: 0;
  background: var(--section);
  color: var(--section-header);
  font-size: 15px;
  line-height: 20px;
  font-weight: 500;
  text-transform: none;
}
.android .section:has(> .section-header:not(.large)) > .section-body { border-radius: 0; }
.android .section-footer { padding: 10px 20px 4px; font-size: 14px; line-height: 18px; color: var(--hint); }
.android .section-header.large { padding: 8px 20px 10px; }

/* ---- cells ---------------------------------------------------------------------------- */
.cell {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--cell-gap);
  width: 100%;
  min-height: 44px;
  padding: 0 var(--cell-pad);
  border: 0;
  background: none;
  color: var(--text);
  text-align: left;
  font-size: var(--title-size);
  line-height: 22px;
  -webkit-user-select: none;
  user-select: none;
}
.android .cell { min-height: 48px; }
.cell-main { flex: 1; min-width: 0; display: grid; gap: 1px; padding: var(--cell-y) 0; }
.cell-title { display: flex; align-items: center; gap: 6px; min-width: 0; font-weight: 400; }
.cell-title > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cell.multiline .cell-title > span:first-child { white-space: normal; overflow-wrap: break-word; }
.cell-subtitle, .cell-description {
  color: var(--subtitle);
  font-size: var(--subtitle-size);
  line-height: 20px;
  overflow-wrap: break-word;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cell-description { -webkit-line-clamp: 4; }
.cell.multiline .cell-subtitle, .cell.multiline .cell-description { display: block; overflow: visible; }
.cell-subtitle.danger { color: var(--destructive); }
.cell-subtitle.accent { color: var(--accent); }
.cell-subtitle.ok { color: var(--green); }
.cell-before { flex-shrink: 0; display: flex; align-items: center; justify-content: center; min-width: var(--tile); }
.avatar-cell .cell-before { min-width: 0; }
.cell-after {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 48%;
  color: var(--hint);
  font-size: var(--title-size);
}
.cell-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cell .chev { --i: 20px; color: var(--hint); opacity: 0.55; margin-right: -6px; }
.android .cell .chev { display: none; }
.cell.accent .cell-title, .cell.accent .cell-before .i:not(.tile .i) { color: var(--link); }
.cell.danger .cell-title { color: var(--destructive); }
.cell.muted .cell-title { color: var(--hint); }
button.cell:active, .cell-tap:active, .cell.pressable:active { background: var(--pressed); }
@media (hover: hover) and (pointer: fine) {
  button.cell:hover, .cell-tap:hover { background: var(--pressed); }
}
/* Hairlines start after the icon, like Telegram's lists. */
.cell + .cell::before, .cell + .cell-wrap::before, .cell-wrap + .cell::before, .cell-wrap + .cell-wrap::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: var(--cell-pad);
  height: 0.5px;
  background: var(--separator);
  z-index: 1;
}
.cell:has(> .cell-before) + .cell::before,
.cell-wrap:has(.cell-before) + .cell-wrap::before,
.cell:has(> .cell-before) + .cell-wrap::before,
.cell-wrap:has(.cell-before) + .cell::before { left: calc(var(--cell-pad) + var(--tile) + var(--cell-gap)); }
.cell.avatar-cell:has(> .cell-before) + .cell::before { left: calc(var(--cell-pad) + 40px + var(--cell-gap)); }
.android .cell + .cell::before, .android .cell-wrap + .cell-wrap::before { opacity: 0.8; }
/* A row with its own control (a switch): the text part is the button, the control sits beside. */
.cell-wrap { position: relative; display: flex; align-items: center; padding-right: var(--cell-pad); }
.cell-wrap > .cell { flex: 1; padding-right: 8px; }
.cell-wrap > .cell::before { display: none; }
.cell.highlight, .cell-wrap.highlight { animation: highlight 1.6s ease; }
@keyframes highlight { 0%, 60% { background: var(--tint); } 100% { background: transparent; } }
.cell.big { min-height: 60px; }
.cell.big .cell-main { padding: 10px 0; }

/* Icon tiles: white glyphs on coloured rounded squares, like Telegram's settings. */
.tile {
  position: relative;
  display: grid;
  place-items: center;
  flex: 0 0 var(--tile);
  width: var(--tile);
  height: var(--tile);
  border-radius: var(--tile-radius);
  color: #fff;
  background: var(--tone, #8e8e93);
  background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0) 60%);
}
.tile .i { --i: calc(var(--tile) * 0.66); stroke-width: 2; }
.tile.big { --tile: 44px; --tile-radius: 12px; }
.tile.huge { --tile: 72px; --tile-radius: 20px; }
.tile.letter { font-size: calc(var(--tile) * 0.48); font-weight: 600; line-height: 1; }
.tile.round { border-radius: 50%; }
.tone-blue { --tone: #007aff; }
.tone-sky { --tone: #32ade6; }
.tone-teal { --tone: #0e9e9a; }
.tone-green { --tone: #34c759; }
.tone-mint { --tone: #00c7be; }
.tone-yellow { --tone: #ffb800; }
.tone-orange { --tone: #ff9500; }
.tone-red { --tone: #ff3b30; }
.tone-pink { --tone: #ff2d55; }
.tone-purple { --tone: #af52de; }
.tone-indigo { --tone: #5856d6; }
.tone-gray { --tone: #8e8e93; }
.tone-brown { --tone: #a2845e; }
.android .tone-blue { --tone: #3390ec; }
/* Round avatars for people, groups and apps, with Telegram's peer gradients. */
.avatar {
  display: grid;
  place-items: center;
  flex: 0 0 var(--size, 40px);
  width: var(--size, 40px);
  height: var(--size, 40px);
  border-radius: 50%;
  color: #fff;
  font-size: calc(var(--size, 40px) * 0.42);
  font-weight: 600;
  line-height: 1;
  background: linear-gradient(180deg, var(--a1, #72d5fd), var(--a2, #2a9ef1));
  overflow: hidden;
}
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.peer-0 { --a1: #ff885e; --a2: #ff516a; }
.peer-1 { --a1: #ffcd6a; --a2: #ffa85c; }
.peer-2 { --a1: #82b1ff; --a2: #665fff; }
.peer-3 { --a1: #a0de7e; --a2: #54cb68; }
.peer-4 { --a1: #53edd6; --a2: #28c9b7; }
.peer-5 { --a1: #72d5fd; --a2: #2a9ef1; }
.peer-6 { --a1: #e0a2f3; --a2: #d669ed; }

/* ---- icons ---------------------------------------------------------------------------- */
.i {
  --i: 24px;
  width: var(--i);
  height: var(--i);
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
}
.i .fill { fill: currentColor; stroke: none; }
.i .i-g, .i path, .i circle { transform-box: fill-box; transform-origin: center; }
.i .i-g { transform-box: view-box; transform-origin: 12px 12px; }

/* Motions, each played once (class .play from Icons.play): the timing of Telegram's tab icons. */
.i.play[data-motion="bounce"] .i-g { animation: m-bounce 0.62s var(--ease); }
.i.play[data-motion="bounce"] .p-roof { animation: m-roof 0.62s var(--ease); }
.i.play[data-motion="flip"] .i-g { animation: m-flip 0.6s var(--ease); }
.i.play[data-motion="flip"] .p-dot { animation: m-pop 0.5s 0.15s var(--spring) backwards; }
.i.play[data-motion="pop4"] .p-a { animation: m-pop 0.45s var(--spring); }
.i.play[data-motion="pop4"] .p-b { animation: m-pop 0.45s 0.07s var(--spring) backwards; }
.i.play[data-motion="pop4"] .p-c { animation: m-pop 0.45s 0.14s var(--spring) backwards; }
.i.play[data-motion="pop4"] .p-d { animation: m-turn 0.55s 0.2s var(--spring) backwards; }
.i.play[data-motion="spin"] .i-g { animation: m-spin 0.75s var(--ease); }
.i.play[data-motion="ring"] .p-body { animation: m-ring 0.8s ease; transform-origin: 50% 8%; }
.i.play[data-motion="ring"] .p-clapper { animation: m-clapper 0.8s ease; }
.i.play[data-motion="tick"] .p-hand { animation: m-hand 0.8s var(--ease); transform-box: view-box; transform-origin: 12px 12px; }
.i.play[data-motion="tick"] .p-hand2 { animation: m-hand2 0.8s var(--ease); transform-box: view-box; transform-origin: 12px 12px; }
.i.play[data-motion="twinkle"] .p-big { animation: m-twinkle 0.7s var(--spring); }
.i.play[data-motion="twinkle"] .p-small { animation: m-twinkle 0.6s 0.18s var(--spring) backwards; }
.i.play[data-motion="typing"] .p-d1 { animation: m-dot 0.5s ease; }
.i.play[data-motion="typing"] .p-d2 { animation: m-dot 0.5s 0.1s ease; }
.i.play[data-motion="typing"] .p-d3 { animation: m-dot 0.5s 0.2s ease; }
.i.play[data-motion="fly"] .i-g { animation: m-fly 0.7s var(--ease); }
.i.play[data-motion="flash"] .i-g { animation: m-flash 0.6s ease; }
.i.play[data-motion="flipv"] .i-g { animation: m-flipv 0.8s var(--ease); }
.i.play[data-motion="wiggle"] .i-g { animation: m-wiggle 0.6s ease; }
.i.play[data-motion="draw"] .p-body, .i.play[data-motion="draw"] .p-checks, .i.play[data-motion="draw"] .p-check {
  stroke-dasharray: 1;
  animation: m-draw 0.55s 0.05s var(--ease) backwards;
}
.i.play[data-motion="draw"] .p-lines { animation: m-fade 0.4s 0.2s ease backwards; }
.i.play[data-motion="pulse"] .i-g { animation: m-pulse 0.6s ease; }
.i.play[data-motion="pop"] .i-g { animation: m-pop 0.5s var(--spring); }
.i.play[data-motion="slide"] .p-second, .i.play[data-motion="slide"] .p-arrow, .i.play[data-motion="slide"] .p-body:not(:only-child) { animation: m-nudge 0.55s var(--ease); }
.i.play[data-motion="slide"] .p-b { animation: m-nudge 0.55s 0.08s var(--ease); }
.i.play[data-motion="lid"] .p-lid { animation: m-lid 0.65s var(--ease); transform-origin: 0% 100%; }
.i.play[data-motion="scribble"] .i-g { animation: m-scribble 0.65s ease; }
.i.play[data-motion="turn"] .i-g { animation: m-turn 0.5s var(--spring); }
.i.play[data-motion="scan"] .i-g { animation: m-scan 0.8s ease; }
.i.play[data-motion="blink"] .p-eyes, .i.play[data-motion="blink"] .p-pupil { animation: m-blink 0.5s ease; }
.i.play[data-motion="grow"] .p-a, .i.play[data-motion="grow"] .p-lines { animation: m-grow 0.5s var(--spring) backwards; transform-origin: 50% 100%; }
.i.play[data-motion="grow"] .p-b { animation: m-grow 0.5s 0.07s var(--spring) backwards; transform-origin: 50% 100%; }
.i.play[data-motion="grow"] .p-c { animation: m-grow 0.5s 0.14s var(--spring) backwards; transform-origin: 50% 100%; }
.i.play[data-motion="grow"] .p-d { animation: m-grow 0.5s 0.21s var(--spring) backwards; transform-origin: 50% 100%; }
.i.play[data-motion="float"] .p-z { animation: m-float 0.9s ease; }
.i.play[data-motion="float"] .p-body { animation: m-wiggle 0.9s ease; }
.i.play[data-motion="launch"] .i-g { animation: m-launch 0.8s var(--ease); }
.i.play[data-motion="launch"] .p-flame { animation: m-flash 0.4s 2 ease; }
.i.play[data-motion="open"] .p-flap { animation: m-flap 0.7s var(--ease); transform-origin: 50% 0%; }
.i.play[data-motion="drop"] .p-arrow { animation: m-drop 0.6s var(--ease); }
.i.play[data-motion="lift"] .i-g { animation: m-lift 0.6s var(--ease); }
.i.play[data-motion="lift"] .p-arrow, .i.play[data-motion="lift"] .p-plus { animation: m-rise 0.6s var(--ease); }
.i.play[data-motion="connect"] .p-prongs, .i.play[data-motion="connect"] .p-a { animation: m-plug 0.6s var(--ease); }
.i.play[data-motion="connect"] .p-b { animation: m-plug-b 0.6s var(--ease); }
.i.play[data-motion="shake"] .i-g { animation: m-shake 0.5s ease; }
.i.play[data-motion="play"] .p-play { animation: m-pop 0.5s var(--spring); }
@keyframes m-bounce { 0% { transform: none; } 30% { transform: translateY(1.5px) scale(1.06, 0.92); } 60% { transform: translateY(-2px) scale(0.97, 1.04); } 100% { transform: none; } }
@keyframes m-roof { 0%, 20% { transform: none; } 55% { transform: translateY(-2.5px); } 100% { transform: none; } }
@keyframes m-flip { 0% { transform: none; } 35% { transform: scale(1, 0.72) translateY(1px); } 70% { transform: scale(1, 1.08); } 100% { transform: none; } }
@keyframes m-pop { 0% { transform: scale(0.4); opacity: 0.3; } 60% { transform: scale(1.12); opacity: 1; } 100% { transform: none; } }
@keyframes m-spin { 0% { transform: rotate(0); } 80% { transform: rotate(100deg); } 100% { transform: rotate(90deg); } }
@keyframes m-ring { 0%, 100% { transform: rotate(0); } 15% { transform: rotate(16deg); } 30% { transform: rotate(-14deg); } 45% { transform: rotate(10deg); } 60% { transform: rotate(-6deg); } 75% { transform: rotate(3deg); } }
@keyframes m-clapper { 0%, 100% { transform: none; } 15% { transform: translateX(-1.5px); } 30% { transform: translateX(1.5px); } 45% { transform: translateX(-1px); } 60% { transform: translateX(0.6px); } }
@keyframes m-hand { 0% { transform: rotate(0); } 100% { transform: rotate(360deg); } }
@keyframes m-hand2 { 0% { transform: rotate(0); } 100% { transform: rotate(30deg); } }
@keyframes m-twinkle { 0% { transform: scale(0.3) rotate(-40deg); opacity: 0.2; } 60% { transform: scale(1.18) rotate(8deg); opacity: 1; } 100% { transform: none; } }
@keyframes m-dot { 0%, 100% { transform: none; } 40% { transform: translateY(-2.2px); } }
@keyframes m-fly { 0% { transform: none; opacity: 1; } 40% { transform: translate(7px, -7px) scale(0.8); opacity: 0; } 41% { transform: translate(-7px, 7px) scale(0.8); opacity: 0; } 100% { transform: none; opacity: 1; } }
@keyframes m-flash { 0%, 100% { opacity: 1; transform: none; } 25% { opacity: 0.35; transform: scale(0.9); } 55% { opacity: 1; transform: scale(1.12); } }
@keyframes m-flipv { 0% { transform: rotate(0); } 100% { transform: rotate(180deg); } }
@keyframes m-wiggle { 0%, 100% { transform: rotate(0); } 20% { transform: rotate(-12deg); } 40% { transform: rotate(10deg); } 60% { transform: rotate(-6deg); } 80% { transform: rotate(3deg); } }
@keyframes m-draw { 0% { stroke-dashoffset: 1; } 100% { stroke-dashoffset: 0; } }
@keyframes m-fade { 0% { opacity: 0; } 100% { opacity: 1; } }
@keyframes m-pulse { 0%, 100% { transform: none; } 40% { transform: scale(1.18); } 70% { transform: scale(0.95); } }
@keyframes m-nudge { 0%, 100% { transform: none; } 45% { transform: translateX(3px); } }
@keyframes m-lid { 0%, 100% { transform: none; } 35%, 60% { transform: translateY(-1.5px) rotate(-16deg); } }
@keyframes m-scribble { 0%, 100% { transform: none; } 25% { transform: translate(-1.5px, 1px) rotate(-10deg); } 50% { transform: translate(1.5px, -1px) rotate(6deg); } 75% { transform: translate(-0.8px, 0.5px) rotate(-4deg); } }
@keyframes m-turn { 0% { transform: rotate(-90deg) scale(0.6); } 100% { transform: none; } }
@keyframes m-scan { 0%, 100% { transform: none; } 25% { transform: translate(-1.5px, -1px); } 50% { transform: translate(1.5px, -1.5px); } 75% { transform: translate(1px, 1px); } }
@keyframes m-blink { 0%, 100% { transform: none; } 45% { transform: scaleY(0.1); } }
@keyframes m-grow { 0% { transform: scaleY(0.1); } 100% { transform: none; } }
@keyframes m-float { 0% { transform: none; opacity: 1; } 60% { transform: translate(2px, -4px); opacity: 0; } 61% { transform: translate(-1px, 2px); opacity: 0; } 100% { transform: none; opacity: 1; } }
@keyframes m-launch { 0% { transform: none; } 30% { transform: translateY(1.5px) scale(1.04, 0.94); } 60% { transform: translateY(-5px); } 100% { transform: none; } }
@keyframes m-flap { 0%, 100% { transform: none; } 40%, 60% { transform: scaleY(-1); } }
@keyframes m-drop { 0% { transform: translateY(-5px); opacity: 0; } 60% { transform: translateY(1.5px); opacity: 1; } 100% { transform: none; } }
@keyframes m-lift { 0%, 100% { transform: none; } 45% { transform: translateY(-2.5px); } }
@keyframes m-rise { 0% { transform: translateY(4px); opacity: 0; } 100% { transform: none; opacity: 1; } }
@keyframes m-plug { 0%, 100% { transform: none; } 40% { transform: translate(-1.5px, 1.5px); } 60% { transform: none; } }
@keyframes m-plug-b { 0%, 100% { transform: none; } 40% { transform: translate(1.5px, -1.5px); } 60% { transform: none; } }
@keyframes m-shake { 0%, 100% { transform: none; } 20% { transform: translateX(-2px); } 40% { transform: translateX(2px); } 60% { transform: translateX(-1.2px); } 80% { transform: translateX(0.8px); } }

/* ---- Kai, the mascot ------------------------------------------------------------------- */
/* «Слушаю» (icons.js): the felt body is a picture; the eyes, the smile and the open mouth are
   layers over it. Every layer is the whole square, so a shift in percent is a share of the
   frame: the rig's poses (anim/states.py, px on its 880 frame) over 8.8. The body moves about
   its bottom centre (50% 88.64%), its shadow lies on the ground (89.32%). Nothing is recoloured:
   the dark theme shows the same felt. */
.kai { position: relative; display: inline-block; width: var(--kai, 96px); height: var(--kai, 96px); flex-shrink: 0; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.kai span, .kai img, .kai i, .kai svg { position: absolute; display: block; max-width: none; margin: 0; pointer-events: none; }
.kai-shadow, .kai-waves, .kai-body, .kai-breath, .kai-felt, .kai-eyes, .kai-eye, .kai-mouth, .kai-d { left: 0; top: 0; width: 100%; height: 100%; }
.kai-body, .kai-breath { transform-origin: 50% 88.64%; }
/* The rig's ground shadow: an ellipse 61% × 6% of the frame, softly blurred. */
.kai-shadow { background: radial-gradient(36% 8% at 50% 89.32%, rgba(10, 50, 46, 0.22), rgba(10, 50, 46, 0.16) 45%, rgba(10, 50, 46, 0.05) 78%, rgba(10, 50, 46, 0)); transform-origin: 50% 89.32%; }
/* Eyes: the render's glossy beads. Shut, the smile's own thread at 0.6 × 0.42, a little lower (‿);
   a blink squashes the bead towards a point under its centre, as the rig does. */
.kai-eye.l { transform-origin: 37.05% 54.83%; }
.kai-eye.r { transform-origin: 63.24% 54.77%; }
.kai-open { transform-origin: 50% 61%; }
.kai-eye.l .kai-open { left: 33.08%; top: 50.68%; width: 7.95%; height: 8.3%; }
.kai-eye.r .kai-open { left: 59.21%; top: 50.57%; width: 8.07%; height: 8.41%; }
.kai-shut { width: 7.64%; height: 2.44%; opacity: 0; }
.kai-eye.l .kai-shut { left: 33.23%; top: 54.29%; }
.kai-eye.r .kai-shut { left: 59.42%; top: 54.23%; }
.kai-smile { left: 43.64%; top: 55.68%; width: 12.73%; height: 5.8%; }
/* The open mouth, a «D»: a stadium of thread on top, a white bowl, its dark hollow inside. Drawn
   as wide as at 0.55 and as deep as wide open; each part is scaled from its top (Icons.talk). */
.kai-d { opacity: 0; }
.kai-d-rim, .kai-d-bowl { left: 44.59%; width: 10.82%; }
.kai-d-rim { top: 56.14%; height: 1.48%; border-radius: 999px; background: #fafbfa; }
.kai-d-bowl, .kai-d-hollow { border-radius: 0 0 50% 50% / 0 0 100% 100%; transform-origin: 50% 0; }
.kai-d-bowl { top: 56.88%; height: 7.78%; background: linear-gradient(#fbfcfb, #dfe3e0); }
.kai-d-hollow { left: 46.07%; top: 57.61%; width: 7.87%; height: 5.57%; background: #123e3a; }
/* A drawn thread casts a soft shadow on the felt, as in the rig. */
.kai-shut, .kai-d { filter: drop-shadow(0 calc(var(--kai, 96px) * 0.0045) calc(var(--kai, 96px) * 0.0068) rgba(8, 40, 38, 0.28)); }
/* Sound beside the ear cups (listen, connect): faint mint arcs. */
.kai-waves { overflow: visible; opacity: 0; }
.kai-wave { fill: none; stroke: #cdece2; stroke-width: 14; stroke-linecap: round; transform-box: view-box; transform: scale(0.75); }
.kai-wave.l { transform-origin: 78px 500px; }
.kai-wave.r { transform-origin: 802px 500px; }
.kai-wave.b { opacity: 0; }
.kai-z { left: 74%; top: 10%; color: var(--kai-teal); font: 700 calc(var(--kai, 96px) * 0.17)/1 system-ui, sans-serif; opacity: 0; }
/* Moods as a still face (live:false, reduced motion); the motion below starts from these. */
.kai-happy .kai-open, .kai-sleep .kai-open { opacity: 0; }
.kai-happy .kai-shut, .kai-sleep .kai-shut { opacity: 1; }
/* ∩ ∩: the thread turned over, 0.6 × 0.55, a little higher than ‿. */
.kai-happy .kai-shut { transform: translateY(-9.33%) scaleY(-1.31); }
.kai-happy .kai-smile, .kai-speak .kai-smile { opacity: 0; }
.kai-happy .kai-d, .kai-speak .kai-d { opacity: 1; }
.kai-happy .kai-d-bowl { transform: scale(1, 0.698); }
.kai-happy .kai-d-hollow { transform: scale(1, 0.578); }
.kai-speak .kai-d-bowl { transform: scale(1, 0.564); }
.kai-speak .kai-d-hollow { transform: scale(1, 0.39); }
.kai-think .kai-eyes { transform: translate(1.82%, -1.59%); }
.kai-think .kai-mouth { transform: translate(1.82%, -0.64%); }
.kai-think .kai-smile { transform: scale(0.7, 0.5); }
.kai-sleep .kai-z { opacity: 1; }
/* The z is drawn, not text: it stays out of the page's text («z Вход»). */
.kai-z::after { content: "z"; }
.kai-listen .kai-eye { transform: scale(1.05); }
.kai-listen .kai-waves { opacity: 0.9; }
.kai-connect .kai-waves { opacity: 0.45; }
@media (prefers-reduced-motion: no-preference) {
  /* Blinks now and then: the bead squashes, the thread shows for a frame or two, the bead comes back. */
  .kai.live:not(.kai-happy):not(.kai-sleep) .kai-open { animation: kai-blink 4s var(--kai-blink, 0s) infinite; }
  .kai.live:not(.kai-happy):not(.kai-sleep) .kai-shut { animation: kai-blink-shut 4s var(--kai-blink, 0s) infinite; }
  /* idle: breathes and leans a little, a quarter of a breath behind it */
  .kai.live.kai-idle .kai-body { animation: kai-tilt 2s ease-in-out infinite alternate; }
  .kai.live.kai-idle .kai-breath, .kai.live.kai-think .kai-breath { animation: kai-breathe 2s ease-in-out -1s infinite alternate; }
  /* think: looks up to the right, then up to the left, leaning after the eyes */
  .kai.live.kai-think .kai-body { animation: kai-think-tilt 4s ease-in-out infinite; }
  .kai.live.kai-think .kai-eyes { animation: kai-think-look 4s ease-in-out infinite; }
  .kai.live.kai-think .kai-mouth { animation: kai-think-mouth 4s ease-in-out infinite; }
  /* sleep: a slower, deeper breath; a z drifts up */
  .kai.live.kai-sleep .kai-breath { animation: kai-breathe-deep 3s ease-in-out infinite alternate; }
  .kai.live.kai-sleep .kai-z { animation: kai-z 3s ease-in-out infinite; }
  /* happy: hops — a squat before, a little settle after — turning one way, then the other */
  .kai.live.kai-happy .kai-body { animation: kai-hop 1s infinite; }
  .kai.live.kai-happy .kai-breath { animation: kai-hop-turn 2s ease-in-out infinite; }
  .kai.live.kai-happy .kai-shadow { animation: kai-hop-shadow 1s infinite; }
  /* listen: nods on the beat while sound runs out of the ear cups */
  .kai.live.kai-listen .kai-body { animation: kai-nod 1.2s infinite; }
  .kai.live.kai-listen .kai-wave, .kai.live.kai-connect .kai-wave { animation: kai-wave 0.8s linear infinite; }
  .kai.live.kai-listen .kai-wave.b, .kai.live.kai-connect .kai-wave.b { animation-delay: -0.4s; }
  /* speak: a phrase of syllables and a pause, the body rising with each... */
  .kai.live.kai-speak .kai-body { animation: kai-say 1.75s ease-in-out infinite; }
  .kai.live.kai-speak .kai-breath { animation: kai-say-sway 0.8s ease-in-out infinite alternate; }
  .kai.live.kai-speak .kai-d { animation: kai-say-d 1.75s infinite; }
  .kai.live.kai-speak .kai-smile { animation: kai-say-smile 1.75s infinite; }
  .kai.live.kai-speak .kai-d-bowl { animation: kai-say-bowl 1.75s ease-in-out infinite; }
  .kai.live.kai-speak .kai-d-hollow { animation: kai-say-hollow 1.75s ease-in-out infinite; }
  /* ...unless a voice opens the mouth itself (Icons.talk): then its transforms hold. */
  .kai.live.kai-speak.kai-lip .kai-body, .kai.live.kai-speak.kai-lip .kai-d, .kai.live.kai-speak.kai-lip .kai-smile,
  .kai.live.kai-speak.kai-lip .kai-d-bowl, .kai.live.kai-speak.kai-lip .kai-d-hollow { animation: none; }
  /* connect: sways side to side, the eyes searching */
  .kai.live.kai-connect .kai-body { animation: kai-sway 1.2s ease-in-out infinite alternate; }
  .kai.live.kai-connect .kai-breath { animation: kai-breathe 1.2s ease-in-out infinite alternate; }
  .kai.live.kai-connect .kai-eyes { animation: kai-search 1.2s ease-in-out infinite alternate; }
  .kai.live.kai-connect .kai-mouth { animation: kai-search-mouth 1.2s ease-in-out infinite alternate; }
  .kai.live.kai-connect .kai-shadow { animation: kai-sway-shadow 1.2s ease-in-out infinite alternate; }
  .kai.pop { animation: kai-pop 0.7s var(--spring); }
}
/* Blinks at 1.3, 3.1 and 3.35 s of 4, 0.18 s each; the thread shows while the bead is under 0.12. */
@keyframes kai-blink {
  0%, 32.5%, 37%, 77.5%, 82%, 83.75%, 88.25%, 100% { transform: scaleY(1); opacity: 1; }
  34.25%, 35.25%, 79.25%, 80.25%, 85.5%, 86.5% { transform: scaleY(0.12); opacity: 1; }
  34.3%, 35.2%, 79.3%, 80.2%, 85.55%, 86.45% { transform: scaleY(0.12); opacity: 0; }
}
@keyframes kai-blink-shut {
  0%, 34.25%, 35.25%, 79.25%, 80.25%, 85.5%, 86.5%, 100% { opacity: 0; }
  34.3%, 35.2%, 79.3%, 80.2%, 85.55%, 86.45% { opacity: 1; }
}
@keyframes kai-tilt { from { transform: rotate(-0.8deg); } to { transform: rotate(0.8deg); } }
@keyframes kai-breathe { from { transform: scale(1.008, 0.988); } to { transform: scale(0.992, 1.012); } }
@keyframes kai-breathe-deep { from { transform: scale(1.016, 0.976); } to { transform: scale(0.984, 1.024); } }
@keyframes kai-think-tilt { 0%, 92.5%, 100% { transform: rotate(0deg); } 10%, 40% { transform: rotate(3deg); } 52.5%, 80% { transform: rotate(-3deg); } }
@keyframes kai-think-look { 0%, 92.5%, 100% { transform: translate(0, 0); } 10%, 40% { transform: translate(1.82%, -1.59%); } 52.5%, 80% { transform: translate(-1.82%, -1.59%); } }
@keyframes kai-think-mouth { 0%, 92.5%, 100% { transform: translate(0, 0); } 10%, 40% { transform: translate(1.82%, -0.64%); } 52.5%, 80% { transform: translate(-1.82%, -0.64%); } }
/* One hop a second: squat (0–15%), up 80/880 of the frame (40%), land squashed (65%), settle. */
@keyframes kai-hop {
  0%, 100% { transform: translateY(0) scale(1, 1); animation-timing-function: ease-in-out; }
  15% { transform: translateY(0) scale(1.07, 0.91); animation-timing-function: linear; }
  17% { transform: translateY(-1.1%) scale(0.995, 1.008); animation-timing-function: ease-out; }
  40% { transform: translateY(-9.09%) scale(0.96, 1.06); animation-timing-function: ease-in; }
  64% { transform: translateY(-0.6%) scale(0.998, 1.004); animation-timing-function: linear; }
  65% { transform: translateY(0) scale(1.06, 0.92); animation-timing-function: ease-in-out; }
  76.7% { transform: translateY(0) scale(0.989, 1.015); }
  88.3% { transform: translateY(0) scale(1.002, 0.997); }
}
@keyframes kai-hop-turn {
  0%, 7.5%, 20%, 32.5%, 57.5%, 70%, 82.5%, 100% { transform: rotate(0deg); }
  13.75%, 76.25% { transform: rotate(4deg); }
  26.25%, 63.75% { transform: rotate(-4deg); }
}
/* The shadow stays on the ground: narrower and paler while he is up. */
@keyframes kai-hop-shadow {
  0%, 100% { transform: scaleX(1); opacity: 1; animation-timing-function: ease-in-out; }
  15% { transform: scaleX(1.07); opacity: 1; animation-timing-function: linear; }
  17% { transform: scaleX(0.995); opacity: 0.94; animation-timing-function: ease-out; }
  40% { transform: scaleX(0.96); opacity: 0.5; animation-timing-function: ease-in; }
  64% { transform: scaleX(0.998); opacity: 0.97; animation-timing-function: linear; }
  65% { transform: scaleX(1.06); opacity: 1; animation-timing-function: ease-in-out; }
  76.7% { transform: scaleX(0.989); }
  88.3% { transform: scaleX(1.002); }
}
@keyframes kai-nod {
  0%, 50%, 100% { transform: translateY(0) rotate(0deg) scale(1, 1); animation-timing-function: ease-out; }
  25% { transform: translateY(-0.8%) rotate(3.2deg) scale(0.99, 1.015); animation-timing-function: ease-in; }
  75% { transform: translateY(-0.8%) rotate(-3.2deg) scale(0.99, 1.015); animation-timing-function: ease-in; }
}
@keyframes kai-wave { 0% { transform: scale(0.5); opacity: 0; } 25%, 75% { opacity: 0.66; } 50% { opacity: 1; } 100% { transform: scale(1); opacity: 0; } }
/* The first phrase of the rig's syllables (states.py, govorit) as the mouth's peaks and troughs,
   open from 0.05 to 1.4 s of 1.75; the hollow keeps the thread 13/880 thick all round. */
@keyframes kai-say-d { 0%, 2.8% { opacity: 0; } 2.9%, 79.9% { opacity: 1; } 80%, 100% { opacity: 0; } }
@keyframes kai-say-smile { 0%, 2.8% { opacity: 1; } 2.9%, 79.9% { opacity: 0; } 80%, 100% { opacity: 1; } }
@keyframes kai-say-bowl {
  0%, 100% { transform: scale(1, 0.329); }
  2.86%, 80% { transform: scale(1, 0.355); }
  7.69% { transform: scale(1, 0.658); }
  13.37%, 23.83%, 33.66%, 43.66%, 53.14%, 63.43%, 76% { transform: scale(1, 0.423); }
  18.63% { transform: scale(1, 0.812); }
  29% { transform: scale(1, 0.799); }
  38.91% { transform: scale(1, 0.624); }
  48.37% { transform: scale(1, 0.933); }
  57.57% { transform: scale(1, 0.852); }
  70.6% { transform: scale(1, 0.758); }
}
@keyframes kai-say-hollow {
  0%, 100% { transform: scale(1, 0.061); }
  2.86%, 80% { transform: scale(1, 0.099); }
  7.69% { transform: scale(1, 0.521); }
  13.37%, 23.83%, 33.66%, 43.66%, 53.14%, 63.43%, 76% { transform: scale(1, 0.193); }
  18.63% { transform: scale(1, 0.737); }
  29% { transform: scale(1, 0.718); }
  38.91% { transform: scale(1, 0.474); }
  48.37% { transform: scale(1, 0.906); }
  57.57% { transform: scale(1, 0.794); }
  70.6% { transform: scale(1, 0.662); }
}
@keyframes kai-say {
  0%, 100% { transform: translateY(0) scale(1, 1); }
  2.86%, 80% { transform: translateY(-0.036%) scale(1, 1.001); }
  7.69% { transform: translateY(-0.445%) scale(1, 1.01); }
  13.37%, 23.83%, 33.66%, 43.66%, 53.14%, 63.43%, 76% { transform: translateY(-0.127%) scale(1, 1.003); }
  18.63% { transform: translateY(-0.654%) scale(1, 1.014); }
  29% { transform: translateY(-0.636%) scale(1, 1.014); }
  38.91% { transform: translateY(-0.4%) scale(1, 1.009); }
  48.37% { transform: translateY(-0.818%) scale(1, 1.018); }
  57.57% { transform: translateY(-0.709%) scale(1, 1.016); }
  70.6% { transform: translateY(-0.582%) scale(1, 1.013); }
}
@keyframes kai-say-sway { from { transform: rotate(-1.2deg); } to { transform: rotate(1.2deg); } }
@keyframes kai-sway { from { transform: translateX(-1.14%) rotate(-5deg); } to { transform: translateX(1.14%) rotate(5deg); } }
@keyframes kai-sway-shadow { from { transform: translateX(-1.14%); } to { transform: translateX(1.14%); } }
@keyframes kai-search { from { transform: translate(1.36%, -0.45%); } to { transform: translate(-1.36%, -0.45%); } }
@keyframes kai-search-mouth { from { transform: translate(0.68%, -0.18%); } to { transform: translate(-0.68%, -0.18%); } }
@keyframes kai-z { 0% { opacity: 0; transform: translate(0, 30%) scale(0.7); } 30%, 70% { opacity: 1; } 100% { opacity: 0; transform: translate(60%, -90%) scale(1.1); } }
/* Also the typing dots of the home header and the login screen. */
@keyframes kai-dots { 0%, 100% { opacity: 0.35; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-3px); } }
@keyframes kai-pop { 0% { transform: scale(0.6); opacity: 0; } 60% { transform: scale(1.06); opacity: 1; } 100% { transform: none; } }

/* ---- buttons -------------------------------------------------------------------------- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: 44px;
  max-width: 100%;
  height: 42px;
  padding: 0 16px;
  border: 0;
  border-radius: 12px;
  font-size: 16px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  transition: transform 0.12s ease, opacity 0.12s ease, background 0.2s ease;
}
.btn > span { overflow: hidden; text-overflow: ellipsis; }
.btn .i { --i: 20px; }
.btn-s { height: 34px; padding: 0 12px; border-radius: 17px; font-size: 14px; }
.btn-l { height: 50px; padding: 0 20px; font-size: 17px; border-radius: 12px; }
.android .btn { border-radius: 10px; font-weight: 500; }
.android .btn-s { border-radius: 17px; }
.btn-stretched { width: 100%; }
.btn-filled { background: var(--button); color: var(--button-text); }
.btn-bezeled { background: var(--tint); color: var(--link); }
/* On black the 12 % tint reads as no button at all (the login's «Войти с VK ID»). */
[data-theme="dark"] .btn-bezeled { background: color-mix(in srgb, var(--accent) 24%, transparent); }
.btn-plain { background: none; color: var(--link); }
.btn-gray { background: var(--fill); color: var(--text); }
.btn-danger { background: color-mix(in srgb, var(--destructive) 12%, transparent); color: var(--destructive); }
.btn-white { background: #fff; color: #000; }
.btn:active:not(:disabled) { transform: scale(0.97); opacity: 0.8; }
.btn:disabled { opacity: 0.45; }
.btn.busy { color: transparent !important; }
.btn.busy::after {
  content: "";
  position: absolute;
  inset: calc(50% - 9px) auto auto calc(50% - 9px);
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-color: var(--button-text) transparent var(--button-text) var(--button-text);
  animation: spin 0.8s linear infinite;
}
.btn-bezeled.busy::after, .btn-plain.busy::after, .btn-gray.busy::after { border-color: var(--link) transparent var(--link) var(--link); }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; }
.btn-row > .btn { flex: 1 1 0; min-width: 0; }
.link-button { border: 0; background: none; padding: 0; color: var(--link); font: inherit; }
@keyframes spin { to { transform: rotate(360deg); } }

/* The in-page submit of a form; hidden where Telegram's own main button takes its place. */
.form-actions { margin-top: 20px; padding: 0 calc(16px - var(--gutter)); }
.native-form .form-actions [type="submit"] { display: none; }

/* iOS / Material switch; the button keeps role="switch" and aria-checked. */
.switch {
  position: relative;
  flex: 0 0 51px;
  width: 51px;
  height: 31px;
  padding: 0;
  border: 0;
  border-radius: 16px;
  background: var(--fill-strong);
  transition: background 0.2s ease;
}
.switch::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 27px;
  height: 27px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15), 0 3px 1px rgba(0, 0, 0, 0.06);
  transition: transform 0.25s cubic-bezier(0.36, -0.24, 0.26, 1.32);
}
.switch[aria-checked="true"] { background: var(--green); }
.switch[aria-checked="true"]::after { transform: translateX(20px); }
.android .switch { flex-basis: 40px; width: 40px; height: 24px; border-radius: 12px; background: transparent; box-shadow: inset 0 0 0 2px var(--hint); }
.android .switch::after { top: 6px; left: 6px; width: 12px; height: 12px; background: var(--hint); box-shadow: none; transition: transform 0.3s var(--spring), width 0.2s, height 0.2s, top 0.2s, left 0.2s; }
.android .switch[aria-checked="true"] { background: var(--button); box-shadow: none; }
.android .switch[aria-checked="true"]::after { top: 3px; left: 3px; width: 18px; height: 18px; background: #fff; transform: translateX(16px); }
.switch:disabled { opacity: 0.5; }

/* Radio-like check at the end of a choice row. */
.check-mark { --i: 22px; color: var(--link); stroke-width: 2.4; }

/* ---- badges and chips ----------------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  height: 20px;
  min-width: 20px;
  padding: 0 7px;
  border-radius: 10px;
  background: var(--button);
  color: var(--button-text);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  justify-content: center;
}
.badge.gray { background: var(--fill-strong); color: var(--hint); }
.badge.soft { background: var(--tint); color: var(--link); }
.badge.danger { background: var(--destructive); color: #fff; }
.badge.ok { background: color-mix(in srgb, var(--green) 16%, transparent); color: var(--green); }
.badge.warn { background: color-mix(in srgb, #ff9500 18%, transparent); color: #d97a00; }
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--hint); flex-shrink: 0; }
.dot.ok { background: var(--green); box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 22%, transparent); }
.dot.warn { background: #ff9500; }
.dot.danger { background: var(--destructive); }
.dot.sleep { background: var(--kai-lilac); }
.chips { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding: 2px calc(16px - var(--gutter)) 4px; margin: 0 calc(-1 * var(--gutter)); scroll-padding: 16px; }
.chips::-webkit-scrollbar { display: none; }
.chip {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 14px;
  border: 0;
  border-radius: 18px;
  background: var(--section);
  color: var(--text);
  font-size: 15px;
  font-weight: 500;
  box-shadow: var(--shadow);
}
.chip .i { --i: 18px; color: var(--link); }
.chip[aria-pressed="true"] { background: var(--button); color: var(--button-text); }
.chip[aria-pressed="true"] .i { color: inherit; }
.chip:active { opacity: 0.7; }

/* Progress: a bar and a ring. */
.progress { height: 6px; border-radius: 3px; background: var(--fill); overflow: hidden; }
.progress > span { display: block; height: 100%; border-radius: inherit; background: var(--button); transition: width 0.6s var(--ease); }
.ring { --size: 44px; width: var(--size); height: var(--size); transform: rotate(-90deg); }
.ring circle { fill: none; stroke-width: 4; }
.ring .track { stroke: var(--fill); }
.ring .value { stroke: var(--button); stroke-linecap: round; transition: stroke-dashoffset 0.8s var(--ease); }

/* ---- cards ---------------------------------------------------------------------------- */
.card { background: var(--section); border-radius: var(--radius); padding: 14px 16px; overflow-wrap: break-word; }
.android .card { padding: 16px 20px; box-shadow: var(--shadow); }
.card + .card { margin-top: 10px; }
.android .card + .card { margin-top: 8px; }
.card-head { display: flex; align-items: flex-start; gap: 12px; }
.card-title { font-size: 17px; font-weight: 600; line-height: 22px; }
.card-meta { margin-top: 2px; color: var(--hint); font-size: 14px; line-height: 18px; }
.card .btn-row { margin-top: 12px; }
.quote {
  margin: 10px 0 0;
  padding: 8px 12px;
  border-left: 3px solid var(--accent);
  border-radius: 4px 10px 10px 4px;
  background: var(--tint);
  font-size: 15px;
  line-height: 20px;
  white-space: pre-wrap;
  overflow-wrap: break-word;
  max-height: 8.2em;
  overflow: hidden;
}

/* A banner: an invitation or a notice with a picture and a button. */
.banner {
  position: relative;
  display: flex;
  gap: 14px;
  align-items: center;
  padding: 14px 16px;
  border-radius: var(--radius);
  background: var(--section);
  overflow: hidden;
}
.android .banner { border-radius: 0; box-shadow: var(--shadow); padding: 16px 20px; }
.banner-text { flex: 1; min-width: 0; display: grid; gap: 2px; }
.banner-title { font-size: 16px; font-weight: 600; line-height: 21px; }
.banner-text p { color: var(--hint); font-size: 14px; line-height: 19px; }
.banner .btn { margin-top: 8px; justify-self: start; }
.banner.brand { background: linear-gradient(135deg, color-mix(in srgb, var(--kai-teal) 16%, var(--section)), var(--section) 70%); }

/* ---- the home header: Kai as a Telegram profile ---------------------------------------- */
.profile { display: grid; justify-items: center; text-align: center; padding: 8px 16px 18px; }
.profile .kai { margin-bottom: 6px; }
.profile h1 { font-size: 26px; line-height: 32px; font-weight: 700; letter-spacing: -0.3px; }
.android .profile h1 { font-size: 24px; font-weight: 600; }
.profile-status { display: inline-flex; align-items: center; gap: 6px; margin-top: 2px; color: var(--hint); font-size: 15px; }
.profile-status.busy { color: var(--accent); }
.profile-status .typing { display: inline-flex; gap: 3px; }
.profile-status .typing i { width: 4px; height: 4px; border-radius: 50%; background: currentColor; animation: kai-dots 1.2s ease-in-out infinite; }
.profile-status .typing i:nth-child(2) { animation-delay: 0.15s; }
.profile-status .typing i:nth-child(3) { animation-delay: 0.3s; }

/* ---- placeholders (empty states), stickers -------------------------------------------- */
.placeholder { display: grid; justify-items: center; gap: 6px; padding: 28px 24px 24px; text-align: center; }
.placeholder .sticker, .placeholder .kai { margin-bottom: 8px; }
.placeholder-title { font-size: 19px; font-weight: 600; line-height: 24px; }
.placeholder p { max-width: 320px; color: var(--hint); font-size: 15px; line-height: 20px; }
.placeholder .btn { margin-top: 12px; }
.section-body > .placeholder { padding: 22px 20px; }
.sticker { width: var(--s, 120px); height: var(--s, 120px); display: grid; place-items: center; }
.sticker svg { width: 100%; height: 100%; overflow: visible; }

/* ---- setup checklist and steps --------------------------------------------------------- */
.setup-head { display: flex; align-items: center; gap: 14px; padding: 14px 16px 12px; }
.android .setup-head { padding: 16px 20px 12px; }
.setup-head .ring { flex-shrink: 0; }
.setup-head-text { flex: 1; min-width: 0; }
.setup-head-text strong { display: block; font-size: 17px; font-weight: 600; line-height: 22px; }
.setup-head-text span { color: var(--hint); font-size: 14px; }
.step-state { --i: 22px; color: var(--hint); opacity: 0.5; }
.step-done .step-state { color: var(--green); opacity: 1; stroke-width: 2.4; }
.step-done .cell-title { color: var(--hint); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--hint) 60%, transparent); }

/* Numbered how-to steps. */
.howto { counter-reset: step; display: grid; gap: 14px; padding: 14px 16px; }
.android .howto { padding: 16px 20px; }
.howto li { list-style: none; counter-increment: step; display: grid; grid-template-columns: 28px 1fr; gap: 12px; align-items: start; font-size: 16px; line-height: 21px; }
.howto li::before { content: counter(step); display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--tint); color: var(--link); font-size: 14px; font-weight: 700; }
.howto { margin: 0; }
.howto b { font-weight: 600; }

/* ---- skeletons ------------------------------------------------------------------------ */
.skeleton { display: grid; gap: 0; }
.skeleton .sk-row { display: flex; align-items: center; gap: var(--cell-gap); padding: 12px var(--cell-pad); }
.sk { border-radius: 6px; background: var(--fill); position: relative; overflow: hidden; }
.sk::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.35), transparent);
  animation: shimmer 1.4s infinite;
}
[data-theme="dark"] .sk::after { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.06), transparent); }
.sk-tile { width: var(--tile); height: var(--tile); border-radius: var(--tile-radius); flex-shrink: 0; }
.sk-lines { flex: 1; display: grid; gap: 7px; }
.sk-line { height: 11px; }
.sk-title { width: 34%; height: 28px; margin: 10px 4px 18px; border-radius: 8px; }
@keyframes shimmer { to { transform: translateX(100%); } }

/* ---- forms ---------------------------------------------------------------------------- */
.form-section { margin-top: 20px; }
.form-section:first-child { margin-top: 4px; }
.field-label { display: block; padding: 0 16px 7px; color: var(--section-header); font-size: 13px; line-height: 16px; text-transform: uppercase; }
.android .field-label { padding: 0 20px 6px; color: var(--section-header); font-size: 15px; font-weight: 500; text-transform: none; }
.field-hint { padding: 7px 16px 0; color: var(--hint); font-size: 13px; line-height: 17px; }
.android .field-hint { padding: 8px 20px 0; font-size: 14px; }
.input-group { background: var(--section); border-radius: var(--radius); overflow: hidden; }
.android .input-group { box-shadow: var(--shadow); }
.input, .input-group input, .input-group textarea, .input-group select {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: 11px 16px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font-size: var(--title-size);
  line-height: 22px;
  -webkit-appearance: none;
  appearance: none;
}
.android .input-group input, .android .input-group textarea, .android .input-group select { padding: 13px 20px; min-height: 50px; }
.input-group > * + * { box-shadow: inset 0 0.5px 0 var(--separator); }
.input-group textarea { min-height: 96px; resize: none; }
.input-group textarea.tall { min-height: 160px; }
.input-group select { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%238e8e93' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1.5 1.5 6 6l4.5-4.5'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 16px center; padding-right: 40px; }
input::placeholder, textarea::placeholder { color: var(--hint); opacity: 0.8; }
input[type="datetime-local"], input[type="date"], input[type="time"] { min-width: 0; max-width: 100%; }
.input-row { display: flex; align-items: center; gap: 12px; min-height: 44px; padding: 0 16px; }
.android .input-row { padding: 0 20px; min-height: 50px; }
.input-row > span:first-child { flex-shrink: 0; }
.input-row input, .input-row select { flex: 1; min-width: 0; padding: 11px 0; text-align: right; color: var(--hint); }
.input-row select { background-position: right 0 center; padding-right: 22px; direction: rtl; }
.input-row select option { direction: ltr; }
.form-error { color: var(--destructive); font-size: 14px; line-height: 19px; padding: 10px 16px 0; }
.form-error:empty { display: none; }
.counter { padding: 6px 16px 0; text-align: right; color: var(--hint); font-size: 13px; }
.counter:empty { display: none; }
.search {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  margin: 0 0 12px;
  padding: 0 10px;
  border-radius: 10px;
  background: var(--fill);
  color: var(--hint);
}
.android .search { height: 44px; margin: 0 0 8px; padding: 0 20px; border-radius: 0; background: var(--section); box-shadow: var(--shadow); }
.search .i { --i: 18px; }
.search input { flex: 1; min-width: 0; height: 100%; padding: 0; border: 0; background: none; color: var(--text); font-size: 17px; -webkit-appearance: none; appearance: none; }
.search input::-webkit-search-cancel-button { -webkit-appearance: none; }
/* Telegram's round ✕ in a search field with text. */
.search-clear { position: relative; flex-shrink: 0; display: grid; place-items: center; width: 36px; height: 36px; margin-right: -10px; padding: 0; border: 0; background: none; color: var(--hint); }
.search-clear::before { content: ""; position: absolute; width: 17px; height: 17px; border-radius: 50%; background: var(--hint); opacity: 0.55; }
.search-clear .i { --i: 11px; position: relative; color: var(--section); stroke-width: 3; }
.android .search-clear { width: 44px; height: 44px; margin-right: -14px; }
.android .search-clear::before { display: none; }
.android .search-clear .i { --i: 20px; color: var(--hint); stroke-width: 2; }
.secret-value { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 15px; -webkit-text-security: disc; }
.picker { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%; min-height: 44px; padding: 0 16px; border: 0; background: none; color: var(--text); font-size: var(--title-size); text-align: left; }
.android .picker { min-height: 50px; padding: 0 20px; }
.picker > span:first-child { flex-shrink: 0; }
.picker-value { min-width: 0; color: var(--hint); display: inline-flex; align-items: center; justify-content: flex-end; gap: 2px; text-align: right; }
.picker-text { white-space: normal; overflow-wrap: break-word; }
.android .picker-value .i { display: none; }
.picker-value .i { --i: 18px; opacity: 0.6; }

/* ---- sheets: dialogs rise from the bottom, drag down to close ------------------------- */
dialog {
  position: fixed;
  inset: auto 0 0 0;
  width: 100%;
  max-width: 640px;
  max-height: calc(100dvh - var(--safe-top) - 40px);
  margin: 0 auto;
  padding: 0 0 calc(20px + var(--content-bottom));
  border: 0;
  border-radius: 14px 14px 0 0;
  background: var(--page);
  color: var(--text);
  overflow: hidden auto;
  overscroll-behavior: contain;
  box-shadow: 0 -1px 0 rgba(0, 0, 0, 0.04);
}
.android dialog { border-radius: 16px 16px 0 0; }
dialog::backdrop { background: var(--scrim); }
[data-theme="dark"] dialog, [data-theme="dark"] dialog .sheet-head { background: var(--section); }
[data-theme="dark"] dialog :is(.section-body:not(.plain), .input-group, .card, .banner, .prose, .search, .chip:not([aria-pressed="true"])) { background: color-mix(in srgb, var(--section) 90%, #fff 10%); }
dialog.closing { animation: sheet-down 0.22s ease forwards; }
dialog.closing::backdrop { animation: fade-out 0.22s ease forwards; }
dialog.dragging { transition: none; }
.sheet-grabber { display: grid; place-items: center; height: 20px; touch-action: none; cursor: grab; }
.sheet-grabber::before { content: ""; width: 36px; height: 5px; border-radius: 3px; background: var(--hint); opacity: 0.35; }
.sheet-head { position: sticky; top: 0; z-index: 2; display: grid; grid-template-columns: 44px 1fr 44px; align-items: center; min-height: 44px; padding: 0 8px; background: inherit; touch-action: none; }
.sheet-head h2 { grid-column: 2; text-align: center; font-size: 17px; font-weight: 600; line-height: 22px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sheet-close { grid-column: 3; justify-self: end; display: grid; place-items: center; width: 44px; height: 44px; border: 0; background: none; color: var(--hint); }
.sheet-close::before { content: ""; position: absolute; width: 30px; height: 30px; border-radius: 50%; background: var(--fill); }
.sheet-close .i { --i: 16px; position: relative; stroke-width: 2.4; }
.sheet-body { padding: 4px var(--gutter) 0; }
.sheet-body > .section:first-child { margin-top: 8px; }
/* One column that never grows past the sheet: a long file, key or server name wraps. */
.sheet-hero { display: grid; grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 8px; padding: 6px 24px 16px; text-align: center; }
.sheet-hero > * { max-width: 100%; min-width: 0; }
.sheet-hero h3 { font-size: 22px; line-height: 28px; font-weight: 700; overflow-wrap: anywhere; }
.sheet-hero p { color: var(--hint); font-size: 15px; line-height: 20px; white-space: pre-line; overflow-wrap: anywhere; }
/* A question (outside Telegram): the question bold, the explanation under it, two buttons. */
.sheet.confirm .sheet-hero h3 { font-size: 20px; line-height: 25px; font-weight: 600; }
.confirm-buttons { padding: 0 16px; }
.android .confirm-buttons { padding: 0 20px; }
.sheet-hero .tile { margin-bottom: 4px; }
.sheet-body .form-actions { padding: 0 16px; }
.android .sheet-body .form-actions { padding: 0 20px; }
@media (prefers-reduced-motion: no-preference) {
  dialog[open]:not(.closing) { animation: sheet-up 0.34s var(--ease); }
  dialog[open]:not(.closing)::backdrop { animation: fade-in 0.25s ease; }
}
@keyframes sheet-up { from { transform: translateY(100%); } to { transform: none; } }
@keyframes sheet-down { to { transform: translateY(100%); } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade-out { to { opacity: 0; } }

/* ---- tab bar -------------------------------------------------------------------------- */
.tabbar {
  position: fixed;
  z-index: 9;
  left: 0;
  right: 0;
  bottom: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.tabbar button {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-width: 0;
  border: 0;
  background: none;
  color: var(--hint);
  font-size: clamp(10px, 2.8vw, 10.5px);
  font-weight: 500;
  line-height: 12px;
}
.tabbar button span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; letter-spacing: -0.1px; }
/* The browser's own button padding would eat 12px of every label. */
.tabbar button { padding: 0 2px; }
.tabbar button[aria-current="page"] { color: var(--link); }
.tabbar .i { --i: 28px; stroke-width: 1.7; }
.tabbar .badge { position: absolute; top: 4px; left: calc(50% + 6px); height: 18px; min-width: 18px; padding: 0 5px; font-size: 12px; background: var(--destructive); color: #fff; }
/* iOS: a floating glass capsule with a lens under the chosen tab (Telegram on iOS 26). */
.ios .tabbar {
  left: 50%;
  right: auto;
  bottom: calc(8px + var(--content-bottom));
  transform: translateX(-50%);
  width: min(calc(100% - 32px), 420px);
  height: var(--tabbar-h);
  padding: 4px;
  border-radius: 32px;
  background: color-mix(in srgb, var(--bar) 78%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(24px);
  backdrop-filter: saturate(180%) blur(24px);
  box-shadow: var(--float-shadow), inset 0 0 0 0.5px rgba(255, 255, 255, 0.3);
}
.ios .tabbar::before {
  content: "";
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 4px;
  width: calc((100% - 8px) / 4);
  border-radius: 28px;
  background: var(--fill);
  transform: translateX(calc(var(--tab, 0) * 100%));
  transition: transform 0.45s var(--spring);
}
.ios .tabbar button { border-radius: 28px; }
/* Android: a full-width bar with a pill behind the chosen icon (Material, like Telegram). */
.android .tabbar {
  height: calc(var(--tabbar-h) + 8px + var(--content-bottom));
  padding: 6px 8px var(--content-bottom);
  background: var(--bar);
  box-shadow: 0 -0.5px 0 var(--separator);
}
.android .tabbar button { gap: 4px; font-size: clamp(10.5px, 3vw, 12px); line-height: 14px; letter-spacing: -0.1px; }
.android .tabbar .i { --i: 24px; stroke-width: 1.9; }
.android .tabbar .tab-icon { display: grid; place-items: center; width: 60px; height: 30px; border-radius: 15px; transition: background 0.25s ease; }
.android .tabbar button[aria-current="page"] .tab-icon { background: var(--tint); }
/* The chosen tab differs by colour only (the lens, the pill): a bolder label would not fit. */
@media (max-width: 400px) {
  .ios .tabbar { width: calc(100% - 16px); }
  .android .tabbar { padding-inline: 2px; }
  .tabbar button span { letter-spacing: -0.2px; }
}
@media (max-width: 340px) {
  .tabbar button, .android .tabbar button { font-size: 9.5px; }
  .tabbar button span { letter-spacing: -0.15px; }
}
.tabbar button:active .tab-icon { transform: scale(0.92); }
.native-modal .tabbar, .no-tabs .tabbar { display: none; }

/* ---- toast (Telegram's «undo» bar) --------------------------------------------------- */
.toast {
  position: fixed;
  z-index: 20;
  left: 50%;
  bottom: calc(var(--tabbar-h) + 20px + var(--content-bottom));
  display: flex;
  align-items: center;
  gap: 10px;
  width: min(calc(100% - 24px), 480px);
  padding: 10px 14px;
  border-radius: 14px;
  background: rgba(40, 40, 42, 0.94);
  color: #fff;
  font-size: 15px;
  line-height: 20px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  transform: translate(-50%, 16px);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.3s var(--ease), opacity 0.2s ease;
}
.toast.show { transform: translate(-50%, 0); opacity: 1; pointer-events: auto; }
.no-tabs .toast, dialog .toast { bottom: calc(20px + var(--content-bottom)); }
.toast .i { --i: 22px; color: #6fd3a5; }
.toast.error .i { color: #ff6961; }
.toast-text { flex: 1; min-width: 0; }
.toast button { border: 0; background: none; color: #6ab3f3; font-weight: 600; padding: 6px 0 6px 8px; }

/* ---- onboarding pages ----------------------------------------------------------------- */
.tour { position: fixed; inset: 0; z-index: 30; display: flex; flex-direction: column; background: var(--bg); padding: calc(var(--content-top) + 8px) 0 calc(16px + var(--content-bottom)); }
.tour-skip { align-self: flex-end; margin-right: 8px; min-height: 44px; padding: 0 14px; border: 0; background: none; color: var(--link); font-size: 16px; }
.tour-track { flex: 1; display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain; }
.tour-track::-webkit-scrollbar { display: none; }
.tour-page { flex: 0 0 100%; scroll-snap-align: center; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 0 28px; text-align: center; }
.tour-page h2 { font-size: 26px; line-height: 32px; letter-spacing: -0.3px; }
.tour-page p { max-width: 340px; color: var(--hint); font-size: 16px; line-height: 22px; }
.tour-page .sticker { --s: min(56vw, 240px); margin-bottom: 14px; }
.tour-dots { display: flex; justify-content: center; gap: 7px; padding: 14px 0 16px; }
.tour-dots i { width: 7px; height: 7px; border-radius: 4px; background: var(--fill-strong); transition: width 0.3s var(--ease), background 0.3s; }
.tour-dots i.on { width: 20px; background: var(--button); }
.tour-foot { padding: 0 20px; }

/* ---- screen transitions --------------------------------------------------------------- */
@media (prefers-reduced-motion: no-preference) {
  .screen.enter-push { animation: push-in 0.36s var(--ease); }
  .screen.enter-pop { animation: pop-in 0.32s var(--ease); }
  .screen.enter-tab { animation: tab-in 0.24s ease; }
  .screen.leaving.leave-push { animation: push-out 0.36s var(--ease) forwards; }
  .screen.leaving.leave-pop { animation: pop-out 0.3s var(--ease) forwards; }
  .screen.leaving.leave-tab { animation: fade-out 0.14s ease forwards; }
  .android .screen.enter-push { animation: md-in 0.3s var(--ease); }
  .android .screen.leaving.leave-push { animation: fade-out 0.2s ease forwards; }
  .reveal > * { animation: rise-in 0.42s var(--ease) backwards; }
  .reveal > :nth-child(2) { animation-delay: 0.03s; }
  .reveal > :nth-child(3) { animation-delay: 0.06s; }
  .reveal > :nth-child(4) { animation-delay: 0.09s; }
  .reveal > :nth-child(5) { animation-delay: 0.12s; }
  .reveal > :nth-child(n + 6) { animation-delay: 0.15s; }
}
@keyframes push-in { from { transform: translateX(28%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes push-out { to { transform: translateX(-12%); opacity: 0; } }
@keyframes pop-in { from { transform: translateX(-12%); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes pop-out { to { transform: translateX(28%); opacity: 0; } }
@keyframes tab-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes md-in { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
@keyframes rise-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ---- results and long text ------------------------------------------------------------ */
.prose { background: var(--section); border-radius: var(--radius); padding: 14px 16px; font-size: 16px; line-height: 23px; overflow-wrap: break-word; }
.android .prose { padding: 16px 20px; box-shadow: var(--shadow); }
.prose p, .prose ul, .prose ol, .prose blockquote { margin: 0 0 12px; }
.prose > :last-child { margin-bottom: 0; }
.prose h1, .prose h2, .prose h3 { font-size: 18px; line-height: 24px; margin: 18px 0 8px; }
.prose table { width: 100%; border-collapse: collapse; margin: 12px 0; font-size: 14px; display: block; overflow-x: auto; }
.prose th, .prose td { text-align: left; padding: 8px; border-bottom: 0.5px solid var(--separator); }
.prose th { color: var(--hint); font-weight: 500; }
.prose pre { overflow-x: auto; max-width: 100%; padding: 12px; border-radius: 10px; background: var(--fill); }
.prose code { font-size: 13px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.prose blockquote { padding-left: 12px; border-left: 3px solid var(--accent); }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 15px; }
.clamp-6 { display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden; }

/* ---- the boot screen ------------------------------------------------------------------ */
.boot { display: grid; place-items: center; min-height: 70vh; }
.boot .kai { --kai: 88px; }
.boot { align-content: center; }
.boot .boot-wait { padding: 8px 24px 0; }

@media (min-width: 700px) {
  .app { padding-top: calc(12px + var(--content-top)); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; scroll-behavior: auto !important; }
  .sk::after { display: none; }
}
.low-motion *, .low-motion *::before, .low-motion *::after { animation: none !important; transition: none !important; }

/* ======== screen blocks: each owner edits only its own block ================================ */
/* ---- schedule ---- */
/* Rows: a title in up to two lines; a failed or running last run on a line of its own. */
.sched-row .cell-title > span:first-child { white-space: normal; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: break-word; }
.sched-row .cell-description { display: block; overflow: visible; }
.sched-row .cell-description.sched-failed { color: var(--destructive); }
.sched-row .cell-description.sched-running { color: var(--accent); }
.sched-off .cell-before .tile { opacity: 0.45; }
.sched-glyph .cell-before { width: var(--tile); justify-content: center; }
.sched-add .cell-before .i { --i: 26px; stroke-width: 2; }
/* The card: a long title keeps to four lines (the whole text is in the details). */
.sched-sheet .sheet-hero h3 { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: break-word; }
.sched-detail .cell-title { font-size: var(--title-size); }
.sched-detail .cell-before { align-self: flex-start; padding-top: 12px; }
/* The form: quick chips wrap under their label; dates and times as values on the right —
   iOS draws them as grey pills like its compact date picker. */
.sched-quick { flex-wrap: wrap; overflow: visible; margin: 0; padding: 0 0 10px; }
.android .sched-quick { padding: 2px 20px 10px; }
.sched-quick .chip { height: 36px; padding: 0 12px; }
.sched-when input { flex: 0 1 auto; width: auto; min-width: 0; color: var(--text); }
.sched-when input[type="date"] { min-width: 8.4em; }
.sched-when input[type="time"] { min-width: 4.8em; }
.sched-when input::-webkit-date-and-time-value { text-align: right; }
.ios .sched-when input { min-height: 34px; margin: 5px 0; padding: 6px 11px; border-radius: 8px; background: var(--fill); text-align: center; }
.ios .sched-when input::-webkit-date-and-time-value { text-align: center; }
.android .sched-when input { color: var(--link); padding: 13px 0; }
.sched-when input::-webkit-calendar-picker-indicator { opacity: 0.55; margin-left: 4px; cursor: pointer; }
.sched-when { justify-content: space-between; cursor: pointer; }
.sched-form .picker > span:first-child { flex-shrink: 0; }
.sched-form .input-group > .cell { box-shadow: none; }
.sched-form .picker-value { min-width: 0; text-align: right; }
.sched-form .picker-text { white-space: normal; overflow-wrap: break-word; }
.sched-sheet:focus-visible, .sched-form:focus-visible, .zone-sheet:focus-visible { outline: none; }
/* The zone picker keeps its full height, as Telegram's search sheets do: typing changes the list,
   never where the search field is. The search stays under the sheet's head while the list
   scrolls, on the sheet's own colour in either theme (inherited through the body). */
.zone-sheet { height: calc(100vh - var(--safe-top) - 40px); height: calc(100dvh - var(--safe-top) - 40px); }
.zone-sheet .sheet-body { background: inherit; }
.zone-search { position: sticky; top: 44px; z-index: 2; margin: 0 calc(-1 * var(--gutter)); padding: 0 var(--gutter) 2px; background: inherit; }
.zone-search .search { margin-bottom: 8px; }
.zone-search .search input:focus-visible { outline: none; }
.zone-results .section:first-child { margin-top: 4px; }
/* ---- connections ---- */
/* «Подключения», services, files, keys, own servers, apps and the key request page (kc-*). */
.tone-lilac { --tone: #a98bf5; }
/* Link-like rows («+ Добавить…», «Открыть»): the bare glyph sits in the tiles' column. */
.kc-glyph .cell-before { width: var(--tile); justify-content: center; }
.kc-glyph .cell-before .i { --i: 26px; stroke-width: 2; }
/* A catalogue app not connected yet: a small tinted «+» at the end of the row. */
.kc-plus { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--tint); color: var(--link); }
.kc-plus .i { --i: 18px; stroke-width: 2.4; }
.cell-after > svg.i-copy { --i: 20px; color: var(--link); }
.kc-service .cell-title { flex-wrap: wrap; row-gap: 3px; }
/* A masked key with «Показать» under it. */
.secret-value.kc-shown { -webkit-text-security: none; }
.secret-value::placeholder { font-family: system-ui, -apple-system, Roboto, sans-serif; font-size: var(--title-size); }
.kc-reveal { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 44px; padding: 0 16px; border: 0; background: none; color: var(--link); font-size: 15px; text-align: left; }
.android .kc-reveal { padding: 0 20px; min-height: 48px; }
.kc-reveal .i { --i: 20px; }
/* A choice list inside a form (the sign-in of an own server): rows with a check at the chosen one. */
.kc-choices { display: grid; }
.kc-choice { position: relative; display: flex; align-items: center; gap: 12px; width: 100%; min-height: 52px; padding: 8px 16px; border: 0; background: none; color: var(--text); text-align: left; }
.android .kc-choice { padding: 8px 20px; min-height: 56px; }
.kc-choice:active { background: var(--pressed); }
.kc-choice + .kc-choice::before { content: ""; position: absolute; top: 0; right: 0; left: 16px; height: 0.5px; background: var(--separator); }
.android .kc-choice + .kc-choice::before { left: 20px; }
.kc-choice-text { flex: 1; min-width: 0; display: grid; gap: 1px; }
.kc-choice-text > span { font-size: var(--title-size); line-height: 22px; }
.kc-choice-text > small { color: var(--hint); font-size: 14px; line-height: 18px; }
.kc-choice[aria-checked="false"] .check-mark { visibility: hidden; }
/* A yes/no setting of an app event: the row's own switch (a real checkbox, so the form sees it). */
.input-group .kc-toggle { cursor: pointer; }
.input-group .kc-toggle > span:first-child { flex: 1 1 auto; min-width: 0; padding: 11px 0; font-size: var(--title-size); line-height: 22px; }
.input-group .kc-toggle input.kc-switch {
  position: relative;
  flex: 0 0 51px;
  width: 51px;
  min-width: 0;
  height: 31px;
  min-height: 0;
  margin: 0;
  padding: 0;
  border-radius: 16px;
  background: var(--fill-strong);
  box-shadow: none;
  cursor: pointer;
  transition: background 0.2s ease;
}
.input-group .kc-toggle input.kc-switch::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 27px;
  height: 27px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15), 0 3px 1px rgba(0, 0, 0, 0.06);
  transition: transform 0.25s cubic-bezier(0.36, -0.24, 0.26, 1.32);
}
.input-group .kc-toggle input.kc-switch:checked { background: var(--green); }
.input-group .kc-toggle input.kc-switch:checked::after { transform: translateX(20px); }
.android .input-group .kc-toggle input.kc-switch { flex-basis: 40px; width: 40px; height: 24px; border-radius: 12px; background: transparent; box-shadow: inset 0 0 0 2px var(--hint); }
.android .input-group .kc-toggle input.kc-switch::after { top: 6px; left: 6px; width: 12px; height: 12px; background: var(--hint); box-shadow: none; transition: transform 0.3s var(--spring), width 0.2s, height 0.2s, top 0.2s, left 0.2s; }
.android .input-group .kc-toggle input.kc-switch:checked { background: var(--button); box-shadow: none; }
.android .input-group .kc-toggle input.kc-switch:checked::after { top: 3px; left: 3px; width: 18px; height: 18px; background: #fff; transform: translateX(16px); }
/* The key request page: Kai's sticker, the request, the value. */
.kc-standalone { padding-top: 8px; }
.kc-standalone > .placeholder:only-child { padding-top: max(40px, 14vh); }
.kc-request-hero { padding: 12px 24px 8px; }
.kc-request-hero .placeholder-title { font-size: 26px; line-height: 32px; font-weight: 700; letter-spacing: -0.3px; }
.android .kc-request-hero .placeholder-title { font-size: 24px; font-weight: 600; }
.kc-standalone .section { margin-top: 20px; }
.kc-request-form { margin-top: 20px; }
.kc-standalone .cell .mono { white-space: normal; overflow-wrap: anywhere; }
/* «Показать ещё»: the chevron turned down; while the next page loads a spinner takes its place. */
.kc-more .cell-before .i { transform: rotate(90deg); }
.kc-more[aria-busy="true"] .cell-before { position: relative; }
.kc-more[aria-busy="true"] .cell-before .i { visibility: hidden; }
.kc-more[aria-busy="true"] .cell-before::after {
  content: "";
  position: absolute;
  inset: calc(50% - 9px) auto auto calc(50% - 9px);
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid var(--link);
  border-right-color: transparent;
  animation: spin 0.8s linear infinite;
}
.kc-more[aria-busy="true"] .cell-title { color: var(--hint); }
/* A key name that will not do, or one that is already there. */
.field-hint.kc-warn { color: var(--destructive); }
/* «Дополнительно» in an app event's form: settings that already have a value, folded. */
.kc-extra { margin-top: 20px; }
.kc-extra > summary { display: flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 16px; color: var(--link); font-size: 15px; list-style: none; cursor: pointer; }
.android .kc-extra > summary { padding: 0 20px; }
.kc-extra > summary::-webkit-details-marker { display: none; }
.kc-extra > summary .i { --i: 16px; transform: rotate(90deg); transition: transform 0.2s ease; }
.kc-extra[open] > summary .i { transform: rotate(-90deg); }
.kc-extra > .form-section:first-of-type { margin-top: 4px; }
/* ---- settings ---- */
/* «Настройки», quiet like Claude's: the invite card on top — the one bright thing on the page —
   and grey glyphs below; the build in small type at the bottom. */
.invite-card {
  display: grid;
  gap: 12px;
  padding: 16px;
  border-radius: var(--radius);
  background: var(--tint);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 24%, transparent);
}
.android .invite-card { margin: 0 12px; border-radius: 16px; }
.invite-head { display: flex; align-items: center; gap: 12px; min-width: 0; }
.invite-icon { flex-shrink: 0; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: var(--button); color: var(--button-text); }
.invite-icon .i { --i: 22px; stroke-width: 1.9; }
.invite-head h2 { font-size: 17px; line-height: 22px; font-weight: 600; }
.invite-head p { color: var(--hint); font-size: 14px; line-height: 18px; }
.invite-link {
  display: flex;
  align-items: center;
  min-width: 0;
  height: 44px;
  padding-left: 12px;
  border-radius: 10px;
  background: var(--section);
  font-size: 15px;
  white-space: nowrap;
}
.invite-url { display: flex; min-width: 0; -webkit-user-select: all; user-select: all; }
.invite-host { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--hint); }
.invite-code { flex-shrink: 0; color: var(--text); font-weight: 500; }
.invite-copy { flex-shrink: 0; display: grid; place-items: center; width: 44px; height: 44px; margin-left: auto; border: 0; background: none; color: var(--link); }
.invite-copy .i { --i: 22px; }
/* «Пожелания к Каю»: a field the size of the page, growing with the text, not a box in a sheet. */
.rules-text {
  display: block;
  width: 100%;
  min-height: 50vh;
  min-height: max(220px, calc(100dvh - 330px));
  padding: 14px 16px;
  border: 0;
  border-radius: var(--radius);
  background: var(--section);
  font-size: 17px;
  line-height: 23px;
  resize: none;
  overflow: hidden;
}
.android .rules-text { width: calc(100% - 24px); margin: 0 12px; border-radius: 16px; }
/* Choice rows (a mode, a pause): the check shows on the chosen one only. */
.set-choice:not([aria-checked="true"]) .check-mark { visibility: hidden; }
.set-choices .input-group > .cell + .cell { box-shadow: none; }
/* «Добавить в другую группу»: the plus stands where the avatars are. */
.set-add > .cell-before { width: 40px; justify-content: center; }
/* A text field shows its caret, not a focus ring (the global :focus-visible rings every field). */
.set-form :is(input, textarea):focus-visible { outline: none; }
/* «Личные переписки»: what Kai sent, drawn as the person's own messages. */
.biz-pending { cursor: pointer; }
.biz-entry { position: relative; padding: 12px var(--cell-pad) 8px; }
.biz-entry + .biz-entry::before { content: ""; position: absolute; top: 0; left: var(--cell-pad); right: 0; height: 0.5px; background: var(--separator); }
.biz-entry-head { display: flex; align-items: center; gap: 8px; min-width: 0; font-size: 15px; line-height: 20px; }
.biz-entry-head b { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.biz-entry-head time { flex-shrink: 0; color: var(--hint); font-size: 13px; }
.biz-thread { display: flex; justify-content: flex-end; padding: 8px 0 4px; }
.sheet-body > .biz-thread, .form-section > .biz-thread { padding: 4px 16px 8px; }
.biz-bubble {
  max-width: 86%;
  padding: 7px 12px 8px;
  border: 0;
  border-radius: 18px 18px 6px 18px;
  background: color-mix(in srgb, var(--button) 15%, var(--section));
  color: var(--text);
  font-size: 16px;
  line-height: 21px;
  text-align: left;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.sheet-body .biz-bubble { background: color-mix(in srgb, var(--button) 18%, var(--section)); }
.biz-bubble.clamp > span { display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }
.biz-entry-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.biz-kind { display: inline-flex; align-items: center; gap: 4px; min-width: 0; color: var(--hint); font-size: 13px; line-height: 17px; text-align: right; }
.biz-kind .i { --i: 15px; flex-shrink: 0; }
.biz-wrong { display: inline-flex; flex-shrink: 0; align-items: center; gap: 5px; min-height: 44px; margin: -6px 0 -8px; padding: 0 8px 0 0; border: 0; background: none; color: var(--link); font-size: 15px; font-weight: 500; }
.biz-wrong .i { --i: 18px; }
.biz-wrong:active { opacity: 0.6; }
/* A chat's form: the name leaves the hero for the header once it scrolls under it (business.js). */
.biz-head h2 { opacity: 0; transition: opacity 0.18s ease; }
.biz-head.titled h2 { opacity: 1; }
/* ---- pwa ---- */
/* Login outside Telegram: Kai, the number to press in the chat, one button, a quiet status. */
.login { display: flex; flex-direction: column; min-height: calc(100vh - 68px - var(--content-top) - var(--content-bottom)); min-height: calc(100dvh - 68px - var(--content-top) - var(--content-bottom)); padding: 0 24px; }
.login-main { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; max-width: 400px; margin: 0 auto; padding: 4px 0 12px; text-align: center; }
.login-hero { display: grid; place-items: center; min-height: 124px; margin-bottom: 16px; }
.login-hero .tile.huge { --tile: 88px; --tile-radius: 26px; }
.login-title { font-size: 28px; line-height: 34px; letter-spacing: -0.4px; overflow-wrap: break-word; }
.android .login-title { font-size: 24px; line-height: 30px; font-weight: 600; letter-spacing: 0; }
.login-lead { margin-top: 8px; max-width: 320px; color: var(--hint); font-size: 16px; line-height: 21px; }
.login-note { display: flex; align-items: center; gap: 10px; width: 100%; margin-bottom: 20px; padding: 10px 14px; border-radius: 12px; background: color-mix(in srgb, #ff9500 14%, var(--section)); font-size: 14px; line-height: 19px; text-align: left; }
.login-note .i { --i: 22px; color: #ff9500; }
.login-code { display: flex; justify-content: center; gap: 12px; margin-top: 26px; }
.login-digit { display: grid; place-items: center; width: 78px; height: 96px; border-radius: 20px; background: var(--section); color: var(--text); font-size: 60px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: -1px; box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--accent) 38%, transparent), 0 6px 18px color-mix(in srgb, var(--accent) 12%, transparent); }
.login-digit.sk { background: var(--fill); box-shadow: none; border-radius: 20px; }
.login-hint { margin-top: 16px; max-width: 290px; font-size: 16px; line-height: 21px; font-weight: 500; }
.login-actions { display: grid; gap: 6px; width: 100%; margin-top: 24px; }
.login-status { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 22px; margin-top: 12px; color: var(--hint); font-size: 15px; line-height: 20px; }
.login-status .i { --i: 18px; }
.login-status.trouble { color: #b36b00; }
[data-theme="dark"] .login-status.trouble { color: #ffb340; }
.login-status .typing { display: inline-flex; gap: 3px; margin-left: -2px; }
.login-status .typing i { width: 4px; height: 4px; border-radius: 50%; background: currentColor; animation: kai-dots 1.2s ease-in-out infinite; }
.login-status .typing i:nth-child(2) { animation-delay: 0.15s; }
.login-status .typing i:nth-child(3) { animation-delay: 0.3s; }
/* The number and, on a computer, the QR code of the same bot link for the phone's camera. */
.login-pair { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 18px 28px; margin-top: 26px; }
.login-pair .login-code { margin-top: 0; }
.login.with-qr .login-hint { max-width: 360px; }
.qr-card { display: flex; flex-direction: column; align-items: center; gap: 8px; margin: 0; }
.qr-frame { padding: 6px; border-radius: 16px; background: #fff; box-shadow: 0 0 0 1px var(--separator), 0 6px 18px rgba(0, 0, 0, 0.06); }
.qr-img { display: block; width: 136px; height: 136px; }
.qr-card figcaption { max-width: 180px; color: var(--hint); font-size: 13px; line-height: 17px; text-align: center; }
/* iOS from «Открыть в браузере»: the steps to the home screen are the page itself. */
.login-steps { width: 100%; margin-top: 22px; border-radius: 14px; background: var(--section); text-align: left; }
.device-qr { display: flex; justify-content: center; padding: 14px 0 22px; }
.add-device-sheet .copy-mark { display: grid; color: var(--link); }
.add-device-sheet .copy-mark .i { --i: 20px; }
@media (prefers-reduced-motion: no-preference) {
  .login-digit:not(.sk) { animation: login-digit 0.55s var(--spring) backwards; animation-delay: calc(var(--n, 0) * 90ms + 60ms); }
  .login-hero > * { animation: kai-pop 0.6s var(--spring); }
}
@keyframes login-digit { from { transform: translateY(12px) scale(0.6); opacity: 0; } to { transform: none; opacity: 1; } }
@media (max-width: 340px) {
  .login { padding: 0 16px; }
  .login-digit { width: 68px; height: 84px; font-size: 52px; border-radius: 18px; }
  .login-title { font-size: 25px; line-height: 31px; }
}
/* «Кай на главном экране»: two ways inside Telegram, the browser's own steps outside. */
.install-options { display: grid; gap: 10px; }
.android .install-options { gap: 8px; }
.install-option .card-head { align-items: center; }
.install-text { flex: 1; min-width: 0; }
.install-option .card-meta { margin-top: 3px; font-size: 15px; line-height: 20px; }
.install-foot { display: flex; margin-top: 14px; }
.install-foot > .btn { flex: 1; }
.install-done { display: flex; flex: 1; align-items: center; justify-content: center; gap: 6px; height: 42px; border-radius: 12px; background: color-mix(in srgb, var(--green) 13%, transparent); color: var(--green); font-size: 16px; font-weight: 600; }
.install-done .check-mark { --i: 20px; color: inherit; }
.install-cta { padding: 4px calc(16px - var(--gutter)) 0; }
.android .install-cta { padding: 4px 20px 0; }
.install-howto li { grid-template-columns: 28px 1fr auto; align-items: center; }
/* A short screen keeps the choices in view: a smaller picture on top (the sticker sets --s inline). */
@media (max-height: 720px) {
  .install-sheet .sheet-hero .sticker { --s: 92px !important; }
  .install-sheet .sheet-hero .kai { --kai: 80px !important; }
  .install-sheet .sheet-hero { padding-bottom: 12px; }
}
.howto-glyph { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 8px; background: var(--fill); color: var(--link); }
.howto-glyph .i { --i: 19px; stroke-width: 2; }
/* Devices: a phone is just a phone here (the glyph's «+» is for adding to the home screen). */
.devices-list .i-phone .p-plus, .device-sheet .i-phone .p-plus { display: none; }
.devices-list .cell-subtitle .badge { height: 18px; margin-right: 2px; padding: 0 6px; font-size: 12px; vertical-align: 1px; }
/* Result and service pages. */
.result-text.plain p { white-space: pre-line; }
.result-text ul, .result-text ol { padding-left: 22px; }
.result-text li + li { margin-top: 4px; }
.result-text hr { height: 0; margin: 16px 0; border: 0; border-top: 0.5px solid var(--separator); }
.result-text h4, .result-text h5, .result-text h6 { margin: 14px 0 6px; font-size: 16px; line-height: 22px; }
.result-text > :first-child { margin-top: 0; }
.result-text a { overflow-wrap: anywhere; }
.result-text :not(pre) > code { padding: 1px 5px; border-radius: 5px; background: var(--fill); }
.result-text pre code { padding: 0; background: none; }
.result-text pre { white-space: pre-wrap; overflow-wrap: anywhere; }
.result-text .result-table { margin: 12px 0; overflow-x: auto; }
.result-text .result-table table { display: table; width: 100%; margin: 0; }
.result-text .result-table tr:last-child td { border-bottom: 0; }
.result-text .result-table th:first-child, .result-text .result-table td:first-child { padding-left: 0; }
.result-text .result-table th:last-child, .result-text .result-table td:last-child { padding-right: 0; }
.result-text .md-image { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 2px 10px 2px 6px; border-radius: 8px; background: var(--fill); color: var(--hint); font-size: 14px; line-height: 20px; vertical-align: middle; }
.result-text .md-image .i { --i: 16px; }
.result-file-mark { --i: 22px; color: var(--link); }
.result-share { margin-top: 24px; padding: 0 calc(16px - var(--gutter)); }
.android .result-share { padding: 0 20px; }
/* ---- onboarding ---- */
/* The tour: the film's dotted paper, its yellow marker under the key words. */
html.tour-open, html.tour-open body { overflow: hidden; }
.tour {
  background-color: var(--bg);
  background-image: radial-gradient(circle, color-mix(in srgb, var(--hint) 22%, transparent) 1.1px, transparent 1.7px);
  background-size: 22px 22px;
  background-position: center;
  outline: none;
}
.tour-top { display: flex; justify-content: flex-end; min-height: 44px; padding: 0 4px; }
.tour-skip { margin-right: 4px; font-weight: 500; }
.tour-skip.gone { visibility: hidden; }
.tour-page { gap: 12px; }
.tour-page .sticker { --s: min(64vw, 36vh, 260px); margin-bottom: 16px; }
.tour-page h2 { max-width: 340px; text-wrap: balance; }
.android .tour-page h2 { font-size: 24px; line-height: 30px; font-weight: 600; letter-spacing: 0; }
.tour-page p { text-wrap: pretty; }
.tour-page mark {
  color: inherit;
  padding: 0 3px;
  margin: 0 -1px;
  border-radius: 4px;
  background: linear-gradient(transparent 56%, color-mix(in srgb, var(--kai-sun) 80%, transparent) 56%, color-mix(in srgb, var(--kai-sun) 80%, transparent) 94%, transparent 94%);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
[data-theme="dark"] .tour-page mark { background: none; color: var(--kai-sun); padding: 0; margin: 0; }
.tour-dots { padding: 12px 0 18px; }
.tour.native .tour-foot { display: none; }
.tour.native { padding-bottom: calc(8px + var(--content-bottom)); }
.tour-foot { width: 100%; max-width: 480px; margin: 0 auto; }
@media (prefers-reduced-motion: no-preference) {
  .tour { animation: tour-in 0.36s var(--ease); }
  .tour.leaving { animation: tour-out 0.28s ease forwards; pointer-events: none; }
  .tour-page.current h2 { animation: rise-in 0.5s var(--ease) 0.06s backwards; }
  .tour-page.current p { animation: rise-in 0.5s var(--ease) 0.14s backwards; }
}
@keyframes tour-in { from { opacity: 0; transform: scale(1.04); } to { opacity: 1; transform: none; } }
@keyframes tour-out { to { opacity: 0; transform: scale(0.98); } }
/* The setup checklist on «Главная»: Kai in the progress ring, done steps crossed out. */
.setup-ring { position: relative; display: grid; place-items: center; width: 44px; height: 44px; flex-shrink: 0; }
.setup-ring .ring { position: absolute; inset: 0; }
.setup-ring .ring .value { stroke: var(--green); }
.setup-head { border-bottom: 0.5px solid var(--separator); }
.setup-head-text span { display: block; margin-top: 1px; }
.step-done .tile { filter: saturate(0.5); opacity: 0.6; }
.step-done .step-state { margin-right: -2px; }
.section.setup-leaving { overflow: hidden; opacity: 0; margin-top: 0 !important; pointer-events: none; transition: height 0.32s var(--ease), opacity 0.22s ease, margin-top 0.32s var(--ease); }
@media (prefers-reduced-motion: no-preference) {
  .section.setup-flash .section-body { animation: setup-flash 1.5s ease; }
}
@keyframes setup-flash { 0%, 50% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 40%, transparent); } 100% { box-shadow: 0 0 0 3px transparent; } }
/* «Что умеет Кай»: the brand card on top, capability sheets with phrases, facts and a button. */
.cap-hero { margin: 2px 0 0; }
.android .cap-hero { margin: 0; }
.cap-hero .banner { padding-top: 16px; padding-bottom: 16px; }
.cap-hero + .section { margin-top: 24px; }
.android .cap-hero + .section { margin-top: 12px; }
.cap-fact.cell { min-height: 40px; cursor: default; }
.cap-fact .cell-main { padding: 9px 0; }
.cap-fact .cell-title { font-size: 15px; line-height: 20px; }
.cap-fact .cell-before { align-self: flex-start; padding-top: 16px; }
.cap-bullet { display: block; width: 6px; height: 6px; border-radius: 50%; background: var(--kai-teal); }
.cap-fact:has(> .cell-before) + .cap-fact::before { left: calc(var(--cell-pad) + 6px + var(--cell-gap)); }
.cap-cta { display: grid; gap: 4px; padding: 22px 16px 4px; }
.android .cap-cta { padding: 20px 20px 4px; }
.cap-cta .btn-plain { height: 44px; }
/* A step finished while the checklist is on screen folds away. */
.setup .cell.step-leaving { min-height: 0; overflow: hidden; opacity: 0; pointer-events: none; transition: height 0.3s var(--ease), opacity 0.2s ease; }
/* A toast in a guide or capability sheet stays above the sheet's buttons while they are on
   screen (--cta-clear, onboarding.js keepToastClear) instead of covering them. */
dialog.cap-sheet .toast { bottom: max(calc(20px + var(--content-bottom)), var(--cta-clear, 0px)); transition: transform 0.3s var(--ease), opacity 0.2s ease, bottom 0.2s ease; }
/* ---- stickers ---- */
/* Kai's stickers (stickers.js): ink lines and pastel fills of the intro film. Parts enter once
   (.st-in, delay --d) and then move in a gentle loop (.st-a, cycle --t, delay --ad); a sticker
   with loop:false plays --once of the loop and rests. Motion runs only while .run (on screen). */
.sticker { position: relative; flex-shrink: 0; --t: 3.6s; --st-ink: var(--kai-ink); --st-card: #fff; --st-dev: #2b3945; --st-soft: #c9d1d8; --st-faint: #ebe5d8; --st-shade: rgba(31, 42, 51, 0.1); }
[data-theme="dark"] .sticker { --st-card: #f6f3ec; --st-dev: #4b5965; --st-soft: #b3bdc6; --st-faint: #ddd6c7; --st-shade: rgba(255, 255, 255, 0.08); }
.sticker > .st-l { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.st-l * { fill: none; stroke: none; transform-box: fill-box; transform-origin: center; }
.st-l text { fill: var(--st-ink); stroke: none; font-family: ui-rounded, "SF Pro Rounded", system-ui, -apple-system, Roboto, sans-serif; font-weight: 800; letter-spacing: -0.2px; }
.st-l .w { fill: var(--st-card); }
.st-l .t { fill: var(--kai-teal); }
.st-l .m { fill: var(--kai-mint); }
.st-l .c { fill: var(--kai-coral); }
.st-l .s { fill: var(--kai-sun); }
.st-l .k { fill: var(--kai-sky); }
.st-l .l { fill: var(--kai-lilac); }
.st-l .p { fill: #f59cc0; }
.st-l .f { fill: var(--kai-face); }
.st-l .i { fill: var(--st-ink); }
.st-l .d { fill: var(--st-dev); }
.st-l .g { fill: var(--st-soft); }
.st-l .z { fill: var(--st-faint); }
.st-l .wf { fill: #fff; }
.st-l .dn { fill: rgba(255, 255, 255, 0.22); }
.st-l .shade { fill: var(--st-shade); }
.st-l .slot { fill: rgba(14, 158, 154, 0.1); stroke: rgba(14, 158, 154, 0.35); stroke-width: 1.6; stroke-dasharray: 3 3; }
.st-l .dock { fill: rgba(255, 255, 255, 0.7); }
.st-l .o, .st-l .o2, .st-l .o4, .st-l .gl, .st-l .ln, .st-l .ln2, .st-l .ot, .st-l .ot3, .st-l .oc, .st-l .oc5, .st-l .ob, .st-l .halo, .st-l .ck, .st-l .dash, .st-l .trail, .st-l .shk, .st-l .shk2, .st-l .rim, .st-l [class^="sq-"] {
  stroke-linecap: round;
  stroke-linejoin: round;
}
.st-l .o { stroke: var(--st-ink); stroke-width: 3; }
.st-l .o2 { stroke: var(--st-ink); stroke-width: 2.2; }
.st-l .o4 { stroke: var(--st-ink); stroke-width: 4; }
[data-theme="dark"] .st-l .leg { stroke: #6f7d89; }
.st-l .gl { stroke: var(--st-ink); stroke-width: 2.3; }
.st-l .ln { stroke: var(--st-soft); stroke-width: 3; }
.st-l .ln2 { stroke: var(--st-ink); stroke-width: 1.4; opacity: 0.7; }
.st-l .ot { stroke: var(--kai-teal); stroke-width: 3.2; }
.st-l .ot3 { stroke: var(--kai-teal); stroke-width: 3; }
.st-l .oc { stroke: var(--kai-coral); stroke-width: 3.4; }
.st-l .oc5 { stroke: var(--kai-coral); stroke-width: 5.5; }
.st-l .halo { stroke: var(--st-card); stroke-width: 10; }
.st-l .ob { stroke: var(--kai-coral); stroke-width: 2.8; }
.st-l .ck { stroke: #fff; stroke-width: 4; }
.st-l .rim { stroke: var(--st-faint); stroke-width: 2; }
.st-l .dash { stroke: var(--kai-teal); stroke-width: 2.6; stroke-dasharray: 3 5; }
.st-l .trail { stroke: var(--kai-teal); stroke-width: 2.6; stroke-dasharray: 3 6; opacity: 0.8; }
.st-l .shk { stroke: var(--st-ink); stroke-width: 11; }
.st-l .shk2 { stroke: #d4dbe1; stroke-width: 5; }
.st-l .sq-t { stroke: var(--kai-teal); stroke-width: 2.6; }
.st-l .sq-l { stroke: var(--kai-lilac); stroke-width: 2.6; }
.st-l .sq-c { stroke: var(--kai-coral); stroke-width: 2.6; }
.st-l .tt { fill: var(--kai-teal); }
.st-l .tw { fill: #fff; }
.st-l .zz { fill: var(--kai-teal); }
.st-l .zz2 { fill: var(--kai-lilac); }
.st-l .dr { stroke-dasharray: 1; }
.st-dots { opacity: 0; }
/* Kai inside a sticker: the live mascot, placed in percent of the box. */
.st-k { position: absolute; }
.st-k > .kai { display: block; width: 100%; height: 100%; }
.sticker .kai-z { display: none; }
.st-k.k-left .kai-eyes { transform: translate(-2.3%, 0.9%); }
.st-k.k-left .kai-mouth { transform: translate(-1.15%, 0.36%); }
/* The sticker moves Kai itself (a-hop, a-nod, a-pulse…): a happy face only breathes in it, and
   a hop of its own would leave a tile. */
@media (prefers-reduced-motion: no-preference) {
  .sticker .kai.live.kai-happy .kai-body, .sticker .kai.live.kai-happy .kai-shadow { animation: none; }
  .sticker .kai.live.kai-happy .kai-breath { animation: kai-breathe 2s ease-in-out infinite alternate; }
}
.st-tile { padding: 0; overflow: hidden; border-radius: 24%; background: linear-gradient(160deg, #f1fbf7, #bfe9da); box-shadow: 0 0 0 calc(var(--s, 120px) * 0.014) var(--kai-ink), 0 calc(var(--s, 120px) * 0.02) calc(var(--s, 120px) * 0.05) rgba(14, 90, 88, 0.25); }
/* Before a sticker is first seen its entering parts wait hidden. */
.sticker:not(.run) .st-in { opacity: 0; }
.sticker.paused, .sticker.paused * { animation-play-state: paused !important; }
/* Entrances. */
.sticker.run .in-pop { animation: st-pop 0.6s var(--ease) var(--d, 0s) both; }
.sticker.run .in-fade { animation: st-fade 0.5s ease var(--d, 0s) both; }
.sticker.run .in-l { animation: st-in-l 0.7s var(--ease) var(--d, 0s) both; }
.sticker.run .in-r { animation: st-in-r 0.7s var(--ease) var(--d, 0s) both; }
.sticker.run .in-b { animation: st-in-b 0.6s var(--ease) var(--d, 0s) both; }
.sticker.run .in-gx { transform-origin: 0 50%; animation: st-gx 0.5s var(--ease) var(--d, 0s) both; }
.sticker.run .in-gy { transform-origin: 50% 100%; animation: st-gy 0.55s var(--spring) var(--d, 0s) both; }
.sticker.run .in-draw { animation: st-draw 0.55s ease-out var(--d, 0s) both; }
.sticker.run .in-orbit { animation: st-orbit 0.95s var(--ease) var(--d, 0s) both; }
.sticker.run .in-drop { animation: st-drop 0.85s ease-out var(--d, 0s) both; }
.sticker.run .in-jump { animation: st-jump 0.7s var(--ease) var(--d, 0s) both; }
.sticker.run .in-key { animation: st-key 0.65s var(--ease) var(--d, 0s) both; }
/* Loops. */
.sticker.run .a-bob { animation: st-bob var(--t) ease-in-out var(--ad, 0s) infinite both; }
.sticker.run .a-bob2 { animation: st-bob2 calc(var(--t) * 1.2) ease-in-out var(--ad, 0s) infinite both; }
.sticker.run .a-twinkle { animation: st-twinkle calc(var(--t) * 0.7) ease-in-out var(--ad, 0s) infinite both; }
.sticker.run .a-nod { animation: st-nod var(--t) ease-in-out var(--ad, 0s) infinite both; }
.sticker.run .a-nod2 { animation: st-nod2 var(--t) ease-in-out var(--ad, 0s) infinite both; }
.sticker.run .a-eq { animation: st-eq 0.9s ease-in-out var(--ad, 0s) infinite both; }
.sticker.run .a-ring { animation: st-ring var(--t) ease-in-out var(--ad, 0s) infinite both; }
.sticker.run .a-buzz { animation: st-buzz var(--t) ease var(--ad, 0s) infinite both; }
.sticker.run .a-spin { animation: st-spin var(--t) cubic-bezier(0.5, 0, 0.3, 1) var(--ad, 0s) infinite both; }
.sticker.run .a-hour { animation: st-hour var(--t) cubic-bezier(0.5, 0, 0.3, 1) var(--ad, 0s) infinite both; }
.sticker.run .a-nudge { animation: st-nudge var(--t) ease var(--ad, 0s) infinite both; }
.sticker.run .a-flow { animation: st-fade 0.5s ease var(--d, 0s) both, st-flow 1.1s linear var(--ad, 0s) infinite; }
.sticker.run .a-snap { animation: st-snap var(--t) ease-in-out var(--ad, 0s) infinite both; }
.sticker.run .a-typing { animation: st-typing var(--t) ease var(--ad, 0s) infinite both; }
.sticker.run .a-typing .dt { animation: st-dot 0.9s ease-in-out infinite; }
.sticker.run .a-typing .dt:nth-child(2) { animation-delay: 0.15s; }
.sticker.run .a-typing .dt:nth-child(3) { animation-delay: 0.3s; }
.sticker.run .a-answer { animation: st-answer var(--t) ease var(--ad, 0s) infinite both; }
.sticker.run .a-tilt { animation: st-tilt calc(var(--t) * 1.1) ease-in-out var(--ad, 0s) infinite both; }
.sticker.run .a-tilt2 { animation: st-tilt2 calc(var(--t) * 1.3) ease-in-out var(--ad, 0s) infinite both; }
.sticker.run .a-grow { transform-origin: 50% 100%; animation: st-regrow var(--t) var(--spring) var(--ad, 0s) infinite both; }
.sticker.run .a-pulse { animation: st-pulse var(--t) ease var(--ad, 0s) infinite both; }
.sticker.run .a-fly { animation: st-fly var(--t) cubic-bezier(0.45, 0.05, 0.4, 1) var(--ad, 0s) infinite both; }
.sticker.run .a-burst { animation: st-burst var(--t) cubic-bezier(0.15, 0.8, 0.3, 1) var(--ad, 0s) infinite both; }
.sticker.run .a-hop { animation: st-hop var(--t) ease-out var(--ad, 0s) infinite both; }
.sticker.run .a-sway { animation: st-sway calc(var(--t) * 1.2) ease-in-out var(--ad, 0s) infinite both; }
.sticker.run .a-z { animation: st-z 3.3s ease-in-out var(--ad, 0s) infinite both; }
.sticker.run .a-no { animation: st-no var(--t) ease var(--ad, 0s) infinite both; }
.sticker.run .a-turn { transform-origin: 50% 50%; animation: st-turn var(--t) ease-in-out var(--ad, 0s) infinite both; }
.sticker.run .a-shackle { animation: st-shackle var(--t) var(--ease) var(--ad, 0s) infinite both; }
.sticker.run .a-lock { animation: st-lock var(--t) ease var(--ad, 0s) infinite both; }
.sticker.run .k-look .kai-eyes { animation: st-look var(--t) ease-in-out 0.6s infinite both; }
/* A once-sticker plays its loop one time (or the part --once of it) and rests there. */
.sticker.once.run .st-a, .sticker.once.run .st-a .dt, .sticker.once.run .k-look .kai-eyes { animation-iteration-count: var(--once, 1); }
.st-success { --t: 3.4s; }
.st-login { --t: 3.2s; }
.st-together, .st-remember { --t: 4s; }
@keyframes st-pop { 0% { opacity: 0; transform: scale(0.3); } 55% { opacity: 1; transform: scale(1.1); } 78% { transform: scale(0.96); } 100% { opacity: 1; transform: none; } }
@keyframes st-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes st-in-l { 0% { opacity: 0; transform: translateX(-26px) rotate(-10deg); } 65% { opacity: 1; transform: translateX(3px) rotate(2deg); } 100% { opacity: 1; transform: none; } }
@keyframes st-in-r { 0% { opacity: 0; transform: translateX(26px) rotate(10deg); } 65% { opacity: 1; transform: translateX(-3px) rotate(-2deg); } 100% { opacity: 1; transform: none; } }
@keyframes st-in-b { 0% { opacity: 0; transform: translateY(18px) scale(0.94); } 100% { opacity: 1; transform: none; } }
@keyframes st-gx { from { transform: scaleX(0); } to { transform: none; } }
@keyframes st-gy { from { transform: scaleY(0); } to { transform: none; } }
@keyframes st-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes st-orbit { 0% { opacity: 0; transform: rotate(-150deg) scale(1.45); } 65% { opacity: 1; transform: rotate(9deg) scale(0.97); } 100% { opacity: 1; transform: none; } }
@keyframes st-drop { 0% { opacity: 0; transform: translateY(-230%) scale(0.7); } 20% { opacity: 1; } 48% { transform: translateY(0) scale(1.12, 0.86); } 64% { transform: translateY(-14%) scale(0.96, 1.05); } 82% { transform: translateY(0) scale(1.03, 0.97); } 100% { opacity: 1; transform: none; } }
@keyframes st-jump { 0% { opacity: 0; transform: translateY(16%) scale(0.5); } 55% { opacity: 1; transform: translateY(-6%) scale(1.05); } 78% { transform: translateY(1%) scale(0.98, 1.02); } 100% { opacity: 1; transform: none; } }
@keyframes st-key { 0% { opacity: 0; transform: translateX(-30px); } 70% { opacity: 1; transform: translateX(3px); } 100% { opacity: 1; transform: none; } }
@keyframes st-bob { 0%, 100% { transform: none; } 50% { transform: translateY(-3px); } }
@keyframes st-bob2 { 0%, 100% { transform: none; } 50% { transform: translateY(-1.8px); } }
@keyframes st-twinkle { 0%, 100% { transform: none; opacity: 1; } 50% { transform: scale(0.72) rotate(22deg); opacity: 0.85; } }
@keyframes st-nod { 0%, 30%, 100% { transform: none; } 8% { transform: rotate(-7deg); } 16% { transform: rotate(6deg); } 23% { transform: rotate(-2deg); } }
@keyframes st-nod2 { 0%, 34%, 100% { transform: none; } 10% { transform: rotate(4deg) scale(1.04); } 20% { transform: rotate(-3deg); } }
@keyframes st-eq { 0%, 100% { transform: none; } 25% { transform: scaleY(0.35); } 50% { transform: scaleY(1.15); } 75% { transform: scaleY(0.6); } }
@keyframes st-ring { 0%, 28%, 100% { transform: none; } 3% { transform: rotate(12deg); } 6% { transform: rotate(-12deg); } 9% { transform: rotate(10deg); } 12% { transform: rotate(-10deg); } 15% { transform: rotate(7deg); } 18% { transform: rotate(-5deg); } 21% { transform: rotate(3deg); } 24% { transform: rotate(-1deg); } }
@keyframes st-buzz { 0% { opacity: 0; } 3%, 22% { opacity: 1; } 28%, 100% { opacity: 0; } }
@keyframes st-spin { 0%, 30% { transform: rotate(0); } 100% { transform: rotate(360deg); } }
@keyframes st-hour { 0%, 30% { transform: rotate(0); } 100% { transform: rotate(30deg); } }
@keyframes st-nudge { 0%, 26%, 100% { transform: none; } 5% { transform: translateX(-4px); } 10% { transform: translateX(3px); } 15% { transform: translateX(-1.5px); } 20% { transform: none; } }
@keyframes st-flow { to { stroke-dashoffset: -16; } }
@keyframes st-snap { 0%, 18%, 100% { transform: none; } 7% { transform: translate(var(--sx), var(--sy)) scale(0.92); } 12% { transform: scale(1.04); } }
@keyframes st-typing { 0% { opacity: 0; } 5%, 40% { opacity: 1; } 46%, 100% { opacity: 0; } }
@keyframes st-dot { 0%, 60%, 100% { transform: none; } 30% { transform: translateY(-3px); } }
@keyframes st-answer { 0%, 44% { opacity: 0; transform: translateY(3px); } 54%, 92% { opacity: 1; transform: none; } 100% { opacity: 0; } }
@keyframes st-tilt { 0%, 100% { transform: none; } 50% { transform: rotate(-3deg); } }
@keyframes st-tilt2 { 0%, 100% { transform: none; } 50% { transform: rotate(-1.5deg); } }
@keyframes st-regrow { 0%, 60%, 100% { transform: none; } 70% { transform: scaleY(1.14); } 80% { transform: scaleY(0.97); } }
@keyframes st-pulse { 0%, 70%, 100% { transform: none; } 76% { transform: scale(1.14); } 84% { transform: scale(0.97); } 90% { transform: none; } }
@keyframes st-fly { 0% { opacity: 0; transform: translate(-26px, 22px) scale(0.45); } 10% { opacity: 1; } 32% { transform: translate(-10px, 8px) scale(0.85); } 52% { opacity: 1; transform: none; } 68% { opacity: 1; transform: translate(20px, -16px) scale(0.75); } 74%, 100% { opacity: 0; transform: translate(28px, -24px) scale(0.35); } }
@keyframes st-burst { 0% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(0.2); } 6% { opacity: 1; } 30% { transform: none; } 70% { opacity: 1; transform: translateY(10px) rotate(90deg); } 86%, 100% { opacity: 0; transform: translateY(16px) rotate(130deg); } }
@keyframes st-hop { 0%, 30%, 100% { transform: none; } 6% { transform: translateY(3%) scale(1.05, 0.94); } 14% { transform: translateY(-7%) scale(0.97, 1.04); } 23% { transform: translateY(0) scale(1.02, 0.98); } }
@keyframes st-sway { 0%, 100% { transform: none; } 50% { transform: rotate(-9deg); } }
@keyframes st-z { 0% { opacity: 0; transform: translate(-7px, 9px) scale(0.5); } 22% { opacity: 1; } 72% { opacity: 1; } 100% { opacity: 0; transform: translate(7px, -11px) scale(1.1); } }
@keyframes st-no { 0%, 28%, 100% { transform: none; } 6% { transform: translateX(-3px); } 12% { transform: translateX(3px); } 18% { transform: translateX(-1.5px); } 24% { transform: none; } }
@keyframes st-turn { 0%, 30%, 100% { transform: none; } 9% { transform: scaleY(0.3); } 18% { transform: none; } }
@keyframes st-shackle { 0%, 16% { transform: translateY(-8px); } 22% { transform: translateY(1.5px); } 27%, 86% { transform: none; } 95%, 100% { transform: translateY(-8px); } }
@keyframes st-lock { 0%, 20%, 100% { transform: none; } 24% { transform: scale(1.06); } 30% { transform: none; } }
/* Kai's eyes around the room, in shares of his frame. */
@keyframes st-look { 0%, 100% { transform: none; } 12%, 24% { transform: translate(-2.1%, -1.5%); } 36%, 48% { transform: translate(2.1%, -1.5%); } 60%, 72% { transform: translate(-1.8%, 1.5%); } 84% { transform: translate(1.8%, 1.2%); } }
/* No motion: the finished picture at once. */
@media (prefers-reduced-motion: reduce) {
  .sticker *, .sticker { animation: none !important; }
  .sticker .st-in { opacity: 1 !important; }
}
.low-motion .sticker .st-in { opacity: 1; }

/* ---- the paywall's screens (settings.js «plans», plan_offers.py), as drawn on 27.10.2026 ---- */
.pw {
  --pw-ink: var(--text);
  --pw-soft: var(--fill);
  --pw-line: var(--separator);
  --pw-on: var(--kai-teal);
  --pw-on-bg: color-mix(in srgb, var(--kai-teal) 9%, var(--bg));
  --pw-sale: #e0a800;
  --pw-sale-bg: color-mix(in srgb, var(--kai-sun) 16%, var(--bg));
  display: flex; flex-direction: column; align-items: stretch; gap: 0;
  min-height: calc(100dvh - var(--content-top) - var(--content-bottom) - var(--tabbar-h) - 24px);
  padding: 12px var(--gutter) 16px; box-sizing: border-box; color: var(--pw-ink);
}
.pw-hero { position: relative; align-self: center; width: 190px; height: 150px; display: flex; align-items: center; justify-content: center; flex: none; }
.pw-halo { position: absolute; left: 27px; top: 0; width: 136px; height: 136px; border-radius: 50%; background: var(--kai-face); }
.pw-hero .kai { position: relative; margin-top: -8px; }
.pw-title { margin: 6px 0 4px; font: 700 28px/1.1 ui-rounded, "SF Pro Rounded", system-ui, -apple-system, Roboto, sans-serif; text-align: center; }
.pw-ticker { align-self: center; height: 26px; overflow: hidden; flex: none; }
.pw-ticker-run { display: flex; flex-direction: column; align-items: center; animation: pwTicker 10s cubic-bezier(.65, 0, .35, 1) infinite; }
.pw-ticker-run span { height: 26px; line-height: 26px; font-size: 17px; font-weight: 600; color: var(--kai-teal); white-space: nowrap; }
@keyframes pwTicker { 0%, 18% { transform: translateY(0); } 25%, 43% { transform: translateY(-26px); } 50%, 68% { transform: translateY(-52px); } 75%, 93% { transform: translateY(-78px); } 100% { transform: translateY(-104px); } }
.pw-facts { display: flex; flex-direction: column; gap: 6px; margin-top: 16px; padding: 12px 14px; border-radius: 18px; background: var(--pw-soft); }
.pw-facts-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.pw-facts-row div { display: flex; flex-direction: column; align-items: center; text-align: center; }
.pw-facts-row b { font: 700 22px ui-rounded, "SF Pro Rounded", system-ui, sans-serif; }
.pw-facts-row span { font-size: 12px; color: var(--hint); }
.pw-facts-note { font-size: 13px; color: var(--subtitle); text-align: center; }
.pw-trust { align-self: center; margin-top: 14px; padding: 8px 16px; border-radius: 16px; background: var(--pw-soft); font-size: 15px; font-weight: 600; text-align: center; }
.pw-sale-note { margin-top: 8px; font-size: 13px; color: var(--subtitle); }
.pw-first .pw-more { margin-top: 4px; padding: 6px; }
.pw-grow { flex: 1 1 16px; min-height: 16px; }
.pw-options { position: relative; display: flex; flex-direction: column; gap: 10px; }
.pw-options > .pw-card { z-index: 1; }
.pw-card {
  display: flex; justify-content: space-between; align-items: center; gap: 12px; width: 100%; box-sizing: border-box;
  padding: 15px 18px; border-radius: 22px; border: 2px solid var(--pw-line); background: var(--bg);
  font: inherit; color: var(--pw-ink); text-align: left; cursor: pointer;
  transition: border-color .3s var(--ease), background-color .3s var(--ease), box-shadow .3s var(--ease), transform .45s var(--spring);
}
.pw-card:active { transform: scale(.97); transition-duration: .12s; }
.pw-card.on { border-color: var(--pw-on); background: var(--pw-on-bg); transform: scale(1.015); box-shadow: 0 8px 24px -14px rgba(11, 127, 124, .6); }
.pw-card-text { display: flex; flex-direction: column; gap: 3px; align-items: flex-start; min-width: 0; padding-right: 4px; }
.pw-card-text b { font: 700 19px ui-rounded, "SF Pro Rounded", system-ui, sans-serif; }
.pw-card-text > span:not(.pw-name) { font-size: 13px; color: var(--hint); }
.pw-name { display: flex; align-items: center; gap: 8px; }
.pw-name b { font-size: 20px; }
.pw-badge { padding: 2px 8px; border-radius: 8px; background: color-mix(in srgb, var(--kai-mint) 55%, var(--bg)); font-size: 12px; font-weight: 600; color: var(--kai-ink); }
.pw-price { display: flex; flex-direction: column; align-items: flex-end; gap: 1px; flex: none; }
.pw-price s { font-size: 13px; color: var(--hint); }
.pw-price b { font: 700 21px ui-rounded, "SF Pro Rounded", system-ui, sans-serif; white-space: nowrap; }
.pw-price small { font-size: 12px; color: var(--hint); white-space: nowrap; }
.pw-sale { flex-direction: column; align-items: stretch; padding: 14px 16px 16px; cursor: default; }
.pw-sale.on { border-color: var(--pw-sale); background: var(--pw-sale-bg); }
.pw-sale-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; width: 100%; padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.pw-now { padding: 3px 9px; border-radius: 9px; background: var(--kai-sun); color: var(--kai-ink); font-size: 12px !important; font-weight: 700; animation: pwGlow 2.4s ease-in-out infinite; }
@keyframes pwGlow { 0%, 100% { box-shadow: 0 0 0 0 rgba(255, 201, 63, 0); } 50% { box-shadow: 0 0 0 5px rgba(255, 201, 63, .3); } }
.pw-pills { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin-top: 12px; }
.pw-pill { display: flex; flex-direction: column; align-items: center; gap: 1px; padding: 8px 4px; border-radius: 14px; border: 2px solid var(--pw-line); background: var(--pw-soft); font: inherit; color: var(--pw-ink); cursor: pointer; }
.pw-pill b { font-size: 15px; }
.pw-pill span { font-size: 12px; font-weight: 600; }
.pw-pill.on { border-color: var(--pw-sale); background: var(--bg); }
.pw-cta { margin-top: 14px; width: 100%; height: 56px; flex: none; border: 0; border-radius: 28px; background: var(--text); color: var(--bg); font: 600 17px system-ui, -apple-system, Roboto, sans-serif; cursor: pointer; }
.pw-cta:disabled { opacity: .55; }
.pw-talk { display: flex; align-items: flex-end; gap: 10px; margin-top: 4px; }
.pw-talk .kai { flex: none; }
.pw-bubble { display: flex; flex-direction: column; gap: 4px; padding: 12px 14px; margin-bottom: 18px; border-radius: 20px 20px 20px 6px; background: var(--kai-face); color: var(--kai-ink); }
.pw-bubble b { font-size: 16px; line-height: 1.35; }
.pw-bubble span { font-size: 14px; line-height: 1.35; opacity: .8; }
.pw-timer { align-self: center; display: flex; align-items: center; gap: 8px; margin-top: 18px; padding: 8px 14px; border-radius: 14px; background: #fff0eb; color: #9a3412; font-size: 14px; }
.pw-only { background: color-mix(in srgb, var(--kai-sun) 18%, var(--bg)); color: var(--text); }
.pw-only .pw-now { font-size: 12px; }
.pw-timer svg { width: 16px; height: 16px; }
.pw-clock { font: 700 16px ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .5px; }
.pw-segment { align-self: center; display: flex; gap: 4px; padding: 4px; margin-bottom: 12px; background: var(--pw-soft); border-radius: 14px; }
.pw-segment { position: relative; display: grid; grid-template-columns: 1fr 1fr; }
.pw-seg { position: relative; z-index: 1; height: 38px; padding: 0 16px; border: 0; border-radius: 10px; font-size: 14px; background: transparent; color: var(--subtitle); white-space: nowrap; cursor: pointer; transition: color .3s var(--ease); }
.pw-seg.on { color: var(--pw-ink); font-weight: 600; }
/* The pill under the period chosen slides across. */
.pw-seg-thumb { position: absolute; top: 4px; bottom: 4px; left: 4px; width: calc(50% - 6px); border-radius: 10px; background: var(--bg); box-shadow: 0 1px 3px rgba(31, 42, 51, .14); transition: transform .45s var(--spring); }
.pw-segment.year .pw-seg-thumb { transform: translateX(calc(100% + 4px)); }
/* The plan running (plan_offers.offer → current): its card is not a choice, the higher ones cost the rest. */
.pw-card.pw-current { cursor: default; border-style: dashed; background: var(--pw-soft); }
.pw-card.pw-current:active { transform: none; }
.pw-mine b { font-size: 15px; color: var(--kai-teal); }
/* The renewal: when, how much, which card, «Отключить». */
.pw-autorenew { display: flex; align-items: center; justify-content: center; gap: 6px; margin-top: 14px; padding: 2px 4px; font-size: 12.5px; color: var(--hint); text-align: center; animation: pwFadeUp .5s var(--ease) .25s both; }
.pw-autorenew svg { flex: none; width: 16px; height: 16px; }
.pw-autorenew span { min-width: 0; }
.pw-autorenew-off { flex: none; padding: 6px 4px; border: 0; background: none; color: var(--danger, #d64545); font: 600 13px system-ui, -apple-system, Roboto, sans-serif; cursor: pointer; }
.pw-autorenew-off:disabled { opacity: .5; }
/* A friend who pays is a month of «Супер» (referral_reward.py). */
.pw-friend { position: relative; display: flex; align-items: center; gap: 12px; margin-top: 12px; padding: 12px 12px 12px 14px; border-radius: 20px; overflow: hidden;
  background: linear-gradient(120deg, color-mix(in srgb, #ffc93f 22%, var(--bg)), color-mix(in srgb, #b79bff 22%, var(--bg)) 55%, color-mix(in srgb, #8fdcc6 26%, var(--bg)));
  animation: pwFadeUp .5s var(--ease) .35s both; }
.pw-friend-icon { flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 14px; background: var(--bg); color: var(--kai-teal); }
.pw-friend-icon svg { width: 22px; height: 22px; }
.pw-friend-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pw-friend-text b { font-size: 15px; }
.pw-friend-text span { font-size: 12.5px; line-height: 1.35; color: var(--subtitle); }
.pw-friend-go { flex: none; height: 36px; padding: 0 14px; border: 0; border-radius: 18px; background: var(--text); color: var(--bg); font: 600 14px system-ui, -apple-system, Roboto, sans-serif; cursor: pointer; transition: transform .2s var(--spring); }
.pw-friend-go:active { transform: scale(.94); }
.pw-friend-section { padding: 0 var(--gutter, 16px); }
.pw-friend-section .pw-friend { margin-top: 0; }
.pw-foot { position: sticky; bottom: 0; z-index: 3; margin: 0 calc(-1 * var(--gutter)) -16px; padding: 6px var(--gutter) calc(14px + var(--content-bottom, 0px)); background: linear-gradient(to bottom, transparent, var(--page) 22px); }
.pw-foot .pw-cta { margin-top: 8px; }
.pw-foot .pw-autorenew { margin-top: 8px; }
@keyframes pwFadeUp { from { opacity: 0; transform: translateY(8px); } }
@media (prefers-reduced-motion: reduce) { .pw-autorenew, .pw-friend { animation: none; } }
.pw-more { align-self: center; margin-top: 12px; padding: 10px; border: 0; background: none; color: var(--kai-teal); font-size: 14px; font-weight: 600; cursor: pointer; }
.pw-limits { padding: 4px 4px 0; font-size: 13px; line-height: 1.45; color: var(--subtitle); }
.pw-limits p { margin: 0 0 8px; }
.pw-limits b { color: var(--pw-ink); }
@media (prefers-color-scheme: dark) {
  .pw-timer { background: #3a1f14; color: #ffb592; }
}
@media (prefers-reduced-motion: reduce) {
  .pw-ticker-run, .pw-now { animation: none; }
}
/* «Супер» runs a rainbow round its border (the owner, 28.10.2026): a turning conic gradient under a
   plain fill. Without @property (old web views) the border stays still. */
@property --pw-turn { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
.pw-super {
  border-color: transparent !important;
  background:
    linear-gradient(var(--pw-fill, var(--bg)), var(--pw-fill, var(--bg))) padding-box,
    conic-gradient(from var(--pw-turn), #ffc93f, #ff7a5c, #b79bff, #8db6ff, #8fdcc6, #ffc93f) border-box !important;
  animation: pwTurn 4s linear infinite;
  box-shadow: 0 6px 22px -10px rgba(183, 155, 255, .55);
}
.pw-card.pw-super.on { --pw-fill: var(--pw-on-bg); border-width: 2.5px; }
/* The fill under the rainbow must be opaque: a see-through one lets the gradient flood the pill. */
.pw-pill.pw-super { --pw-fill: color-mix(in srgb, var(--text) 6%, var(--bg)); }
.pw-pill.pw-super.on { --pw-fill: var(--bg); }
@keyframes pwTurn { to { --pw-turn: 360deg; } }
.pw-sheet { position: fixed; inset: 0; z-index: 50; display: flex; align-items: flex-end; justify-content: center; background: var(--scrim); animation: pwFade .2s ease; }
.pw-sheet-card { width: 100%; max-width: 520px; max-height: 86dvh; overflow: auto; box-sizing: border-box; padding: 16px var(--gutter) calc(20px + var(--content-bottom)); border-radius: 22px 22px 0 0; background: var(--bg); display: flex; flex-direction: column; gap: 10px; animation: pwRise .28s var(--ease); }
.pw-sheet-head { display: flex; align-items: center; justify-content: space-between; padding: 2px 2px 6px; }
.pw-sheet-head b { font: 700 20px ui-rounded, "SF Pro Rounded", system-ui, sans-serif; }
.pw-sheet-close { width: 36px; height: 36px; border: 0; border-radius: 50%; background: var(--fill); color: var(--text); display: flex; align-items: center; justify-content: center; cursor: pointer; }
.pw-sheet-close svg { width: 16px; height: 16px; }
.pw-plan { padding: 14px 16px; border-radius: 18px; border: 2px solid var(--pw-line); }
.pw-plan .pw-name b { font: 700 18px ui-rounded, "SF Pro Rounded", system-ui, sans-serif; }
.pw-plan ul { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.pw-plan li { position: relative; padding-left: 24px; font-size: 14px; line-height: 1.35; }
.pw-plan li::before { content: ""; position: absolute; left: 2px; top: 3px; width: 14px; height: 14px; border-radius: 50%; background: var(--kai-teal) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M3.5 7.2l2.3 2.3 4.7-4.9' fill='none' stroke='white' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/14px no-repeat; }
@keyframes pwFade { from { opacity: 0; } }
@keyframes pwRise { from { transform: translateY(40px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .pw-super, .pw-sheet, .pw-sheet-card { animation: none; } }

/* ---- the paywall in motion (the owner, 28.10.2026: «всё плавненько») ---- */
/* The screen comes in piece by piece. */
.pw > * { animation: pwIn .55s var(--ease) both; }
.pw > *:nth-child(1) { animation-delay: .02s; } .pw > *:nth-child(2) { animation-delay: .08s; }
.pw > *:nth-child(3) { animation-delay: .14s; } .pw > *:nth-child(4) { animation-delay: .18s; }
.pw > *:nth-child(5) { animation-delay: .22s; } .pw > *:nth-child(6) { animation-delay: .28s; }
.pw > *:nth-child(7) { animation-delay: .32s; }
.pw-options > .pw-card { animation: pwIn .5s var(--ease) both; }
.pw-options > .pw-card:nth-child(2) { animation-delay: .22s; } .pw-options > .pw-card:nth-child(3) { animation-delay: .27s; }
.pw-options > .pw-card:nth-child(4) { animation-delay: .32s; }
@keyframes pwIn { from { opacity: 0; transform: translateY(14px); } }
.pw-bubble { transform-origin: 0 100%; animation: pwBubble .6s var(--spring) .15s both; }
@keyframes pwBubble { from { opacity: 0; transform: scale(.85); } }
/* A text that changes cross-fades upward. */
.pw-swap { display: inline-block; animation: pwSwap .35s var(--ease); }
@keyframes pwSwap { from { opacity: 0; transform: translateY(8px); filter: blur(2px); } }
.pw-cta { position: relative; overflow: hidden; transition: transform .2s var(--ease), background .4s var(--ease), color .4s var(--ease), box-shadow .4s var(--ease); }
.pw-cta:active { transform: scale(.97); }
.pw-cta-label { display: inline-block; position: relative; z-index: 1; }
/* «Купить» for «Супер»: a moving rainbow and a glow. */
/* The rainbow is a layer of its own that fades in and out: a gradient background cannot cross-fade. */
.pw-cta::before {
  content: ""; position: absolute; inset: 0; opacity: 0; transition: opacity .45s var(--ease);
  background: linear-gradient(110deg, #ffc93f, #ff7a5c, #b79bff, #8db6ff, #8fdcc6, #ffc93f) 0 0 / 300% 100%;
  animation: pwFlow 3s linear infinite;
}
.pw-cta-super { color: #1f2a33; box-shadow: 0 10px 30px -10px rgba(183, 155, 255, .8); }
.pw-cta-super::before { opacity: 1; }
@keyframes pwFlow { to { background-position: 300% 0; } }
/* «Супер» chosen: the border spins up and glows, a shine runs across. */
.pw-super.pw-boost { animation: pwTurn .6s linear 2, pwPop .7s var(--spring); box-shadow: 0 0 0 6px rgba(183, 155, 255, .25), 0 14px 40px -10px rgba(255, 122, 92, .55); }
.pw-super.pw-boost::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: linear-gradient(105deg, transparent 30%, rgba(255, 255, 255, .75) 50%, transparent 70%) -150% 0 / 60% 100% no-repeat;
  animation: pwShine .9s var(--ease) .1s both;
}
.pw-card { position: relative; }
@keyframes pwPop { 0% { transform: scale(1); } 35% { transform: scale(1.05); } 100% { transform: scale(1.015); } }
@keyframes pwShine { to { background-position: 250% 0; } }
.pw-burst { position: fixed; z-index: 60; width: 0; height: 0; pointer-events: none; }
.pw-ring {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); border-radius: 26px;
  border: 3px solid transparent;
  background: conic-gradient(#ffc93f, #ff7a5c, #b79bff, #8db6ff, #8fdcc6, #ffc93f) border-box;
  -webkit-mask: linear-gradient(#000 0 0) padding-box exclude, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) padding-box exclude, linear-gradient(#000 0 0);
  border-width: 5px; filter: drop-shadow(0 0 8px rgba(183, 155, 255, .9));
  animation: pwRing 1s var(--ease) forwards;
}
.pw-ring.late { border-width: 3px; animation-delay: .16s; opacity: 0; animation-fill-mode: both; }
/* A rainbow glow blooms behind the card and fades. */
.pw-bloom {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); border-radius: 30px;
  background: conic-gradient(#ffc93f, #ff7a5c, #b79bff, #8db6ff, #8fdcc6, #ffc93f);
  filter: blur(26px); opacity: 0; animation: pwBloom 1.2s var(--ease) forwards;
}
@keyframes pwBloom { 0% { opacity: 0; transform: translate(-50%, -50%) scale(.9); } 25% { opacity: .9; } 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.3); } }
@keyframes pwRing { from { opacity: 1; transform: translate(-50%, -50%) scale(1); } to { opacity: 0; transform: translate(-50%, -50%) scale(1.35, 1.9); } }
.pw-spark { position: absolute; left: -5px; top: -5px; width: 10px; height: 10px; border-radius: 50%; background: var(--c); box-shadow: 0 0 14px 2px var(--c); animation: pwSpark 1.15s cubic-bezier(.15, .8, .3, 1) both; }
.pw-spark.star { width: 16px; height: 16px; left: -8px; top: -8px; border-radius: 1px; clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%); }
@keyframes pwSpark { 0% { opacity: 0; transform: translate(0, 0) scale(.4); } 15% { opacity: 1; } 100% { opacity: 0; transform: translate(var(--x), var(--y)) scale(1) rotate(180deg); } }
.pw-sheet.closing { animation: pwFade .22s var(--ease) reverse forwards; }
.pw-sheet.closing .pw-sheet-card { animation: pwRise .22s var(--ease) reverse forwards; }
.pw-sheet-card .pw-plan { animation: pwIn .45s var(--ease) both; }
.pw-sheet-card .pw-plan:nth-of-type(2) { animation-delay: .06s; } .pw-sheet-card .pw-plan:nth-of-type(3) { animation-delay: .12s; }
/* The rainbow keeps turning under the entry; once the screen is in (.ready), only it moves. */
.pw-options > .pw-card.pw-super { animation: pwIn .5s var(--ease) both, pwTurn 4s linear infinite; }
.pw-sheet-card .pw-plan.pw-super { animation: pwIn .45s var(--ease) .12s both, pwTurn 4s linear infinite; }
.pw.ready > *, .pw.ready .pw-options > .pw-card { animation: none; }
.pw.ready .pw-options > .pw-card.pw-super { animation: pwTurn 4s linear infinite; }
.pw.ready .pw-options > .pw-super.pw-boost { animation: pwTurn .6s linear 2, pwPop .7s var(--spring); }
@media (prefers-reduced-motion: reduce) {
  .pw > *, .pw-options > .pw-card, .pw-bubble, .pw-swap, .pw-cta::before, .pw-super.pw-boost, .pw-sheet-card .pw-plan { animation: none; }
}

/* ---- after YooKassa's page (settings.js «paid») ---- */
.pw-result-box { display: contents; }
.pw-result { align-items: center; text-align: center; padding-top: 28px; }
.pw-result > * { max-width: 420px; width: 100%; }
.pw-result .pw-hero { width: 190px; }
.pw-result .pw-title { font-size: 32px; margin-top: 10px; }
.pw-result-plan { margin: 6px 0 0; font-size: 18px; line-height: 1.35; color: var(--text); }
.pw-result-note { margin: 6px 0 0; font-size: 15px; color: var(--hint); }
.pw-result .pw-plan { margin-top: 22px; text-align: left; }
.pw-result .pw-more { margin-top: 6px; }
.pw-result.ok .pw-halo { background: radial-gradient(circle, color-mix(in srgb, var(--kai-mint) 70%, var(--bg)) 0%, var(--kai-face) 70%); animation: pwHalo 2.4s var(--ease) infinite; }
.pw-result.super .pw-halo { background: conic-gradient(from var(--pw-turn), #ffc93f55, #ff7a5c55, #b79bff55, #8db6ff55, #8fdcc655, #ffc93f55); animation: pwTurn 4s linear infinite, pwHalo 2.4s var(--ease) infinite; }
@keyframes pwHalo { 50% { transform: scale(1.06); } }
.pw-result.ok .pw-title { animation: pwPopIn .7s var(--spring) .1s both; }
@keyframes pwPopIn { from { opacity: 0; transform: scale(.6); } }
.pw-result.super .pw-plan-name {
  background: linear-gradient(90deg, #ff7a5c, #b79bff, #8db6ff, #0e9e9a, #ffc93f, #ff7a5c) 0 0 / 300% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent; animation: pwFlow 4s linear infinite;
}
.pw-result.fail .pw-halo { background: color-mix(in srgb, var(--kai-coral) 16%, var(--bg)); }
.pw-result.fail .pw-title { animation: pwShake .5s var(--ease) .2s both; }
@keyframes pwShake { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-8px); } 40% { transform: translateX(7px); } 60% { transform: translateX(-4px); } 80% { transform: translateX(2px); } }
.pw-dots::after { content: ""; display: inline-block; width: 1.2em; text-align: left; animation: pwDots 1.4s steps(4) infinite; }
@keyframes pwDots { 0% { content: ""; } 25% { content: "."; } 50% { content: ".."; } 75% { content: "..."; } }
.pw-confetti { position: fixed; inset: 0; z-index: 60; pointer-events: none; overflow: hidden; }
.pw-bit { position: absolute; left: var(--x); top: -20px; width: 8px; height: 14px; border-radius: 2px; background: var(--c); animation: pwFall 3s cubic-bezier(.25, .6, .4, 1) both; }
.pw-bit.round { width: 10px; height: 10px; border-radius: 50%; }
@keyframes pwFall { 0% { opacity: 1; transform: translate(0, 0) rotate(0); } 85% { opacity: 1; } 100% { opacity: 0; transform: translate(var(--drift), 105vh) rotate(var(--spin)); } }
@media (prefers-reduced-motion: reduce) { .pw-result .pw-halo, .pw-result .pw-title, .pw-plan-name, .pw-dots::after { animation: none; } }

/* ---- the trial's card (settings.js «bind») ---- */
.pw-card-art {
  position: relative; align-self: center; width: 260px; height: 156px; margin: 18px 0 6px; border-radius: 18px;
  background: linear-gradient(135deg, #1f2a33, #0b7f7c 60%, #8fdcc6);
  box-shadow: 0 18px 40px -18px rgba(11, 127, 124, .7); animation: pwCardIn .8s var(--spring) .15s both, pwFloat 4s var(--ease) 1s infinite;
}
.pw-card-art::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: linear-gradient(105deg, transparent 35%, rgba(255, 255, 255, .35) 50%, transparent 65%) -150% 0 / 60% 100% no-repeat; animation: pwShine 2.6s var(--ease) 1s infinite; }
.pw-chip { position: absolute; left: 22px; top: 44px; width: 38px; height: 28px; border-radius: 6px; background: linear-gradient(135deg, #ffd978, #c99a2e); }
.pw-card-dots { position: absolute; left: 22px; bottom: 24px; color: rgba(255, 255, 255, .9); font: 600 17px ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 1px; }
@keyframes pwCardIn { from { opacity: 0; transform: translateY(18px) rotate(-6deg) scale(.9); } }
@keyframes pwFloat { 50% { transform: translateY(-5px); } }
.pw-bind-points { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.pw-bind-point { display: flex; gap: 12px; align-items: flex-start; }
.pw-bind-point > span:last-child { display: flex; flex-direction: column; gap: 2px; }
.pw-bind-point b { font-size: 15px; }
.pw-bind-point span span { font-size: 13px; color: var(--subtitle); }
.pw-bind-icon { flex: none; width: 32px; height: 32px; border-radius: 10px; display: flex; align-items: center; justify-content: center; background: var(--pw-on-bg, var(--fill)); color: var(--kai-teal); }
.pw-bind-icon svg { width: 18px; height: 18px; }
.pw-fine { margin: 10px 0 0; font-size: 12px; color: var(--hint); text-align: center; }
.pw-renew { display: flex; gap: 10px; align-items: flex-start; margin-top: 16px; padding: 12px 14px; border-radius: 16px; background: var(--pw-soft, var(--fill)); text-align: left; font-size: 14px; line-height: 1.4; color: var(--subtitle); }
.pw-renew svg { flex: none; width: 18px; height: 18px; color: var(--kai-teal); margin-top: 1px; }
.pw-renew b { color: var(--text); font-weight: 600; }
@media (prefers-reduced-motion: reduce) { .pw-card-art, .pw-card-art::after { animation: none; } }

/* ---- a promo code on the paywall's screens ---- */
.pw-links { display: flex; justify-content: center; flex-wrap: wrap; gap: 4px 18px; margin-top: 8px; }
.pw-links .pw-more { margin-top: 0; }
.pw-code-hint { margin: 0; font-size: 14px; color: var(--subtitle); }
.pw-code {
  width: 100%; box-sizing: border-box; height: 54px; padding: 0 16px; border-radius: 16px; border: 2px solid var(--pw-line, var(--separator));
  background: var(--bg); color: var(--text); font: 600 20px ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 2px; text-transform: uppercase;
  transition: border-color .2s var(--ease);
}
.pw-code:focus { outline: none; border-color: var(--kai-teal); }
.pw-code-note { margin: 0; min-height: 18px; font-size: 13px; color: var(--destructive); }
.pw-shake { animation: pwShake .45s var(--ease); border-color: var(--destructive); }
.pw-code::placeholder { text-transform: none; letter-spacing: 0; font-weight: 400; font-family: system-ui, -apple-system, Roboto, sans-serif; font-size: 17px; }
