/* Our additions on top of the ported stylesheet.
   Separate file so the ported one stays a verbatim copy of the reference and a
   future re-port cannot silently drop these. */

/* ── Theme toggle ──────────────────────────────────────────────────
   Pinned to the right edge of the bar, away from the language selector — where
   the reference puts it. It sat next to the language because it was injected as
   a list item; it is a sibling of the nav lists now, positioned here.

   It was also invisible: the element had no artwork at all. Two <i> layers hold
   the sun and moon, and only the one that matches the *destination* is shown —
   sun while dark is active, because that is what clicking will do. */
.tl_page_head, .dev_page_head { position: relative; }

/* 🚨 Fixed height, not `height: 100%`. The bar's own height comes from its inner
   rows, so a percentage resolved against a box that had not been laid out yet and
   the icon ended up clipped to a sliver. sidenav.js also assigns an inline height
   here, which is why `!important` is needed to keep ours. */
/* 🚨 Every geometric property is !important, and that is not laziness. Three
   things fight over this element: the ported theme.css sets
   `position: fixed; right: 0; top: 0; height: 50px; padding: 0 16px` (it pins
   the button to the viewport corner, which is where the sliver in the
   screenshot came from), sidenav.js writes an inline height, and this rule
   wants it centred inside the bar. Same specificity as theme.css means source
   order alone decided it — and any future sheet reordering would silently
   break it again. */
.theme-toggle {
  position: absolute !important;
  right: 18px !important;
  left: auto !important;
  top: 50% !important;
  bottom: auto !important;
  transform: translateY(-50%);
  display: flex !important;
  align-items: center;
  justify-content: center;
  width: 40px !important;
  height: 40px !important;
  padding: 0 !important;
  overflow: visible;
  z-index: 5;
  opacity: 0.75;
  transition: opacity 0.15s ease;
}
.theme-toggle:hover { opacity: 1; }

.theme-icon {
  display: none;
  width: 22px;
  height: 22px;
  background-size: 22px 22px;
  background-repeat: no-repeat;
  background-position: center;
}
.theme-icon-sun  { background-image: url('../img/theme-sun.webp'); }
.theme-icon-moon { background-image: url('../img/theme-moon.webp'); }

/* Light theme → offer the moon. Dark theme → offer the sun. */
html[data-theme="light"] .theme-icon-moon { display: block; }
html[data-theme="dark"]  .theme-icon-sun  { display: block; }

/* The bar's own items must not run under the toggle. */
.tl_page_head .navbar-nav.navbar-right,
.dev_page_head .navbar-nav.navbar-right { margin-right: 44px; }

@media (max-width: 640px) {
  .theme-toggle { right: 6px; width: 36px; }
  .tl_page_head .navbar-nav.navbar-right,
  .dev_page_head .navbar-nav.navbar-right { margin-right: 34px; }
}

/* ── Hero wordmark ─────────────────────────────────────────────────
   Replaces the dump's inline SVG, whose paths spelled the reference's own name,
   and its animated sprite of the same. Live text instead of a drawing, so it
   scales and can be translated. */
.as_main_logo_mark {
  display: block;
  width: 144px;
  height: 144px;
  margin: 0 auto;
  border-radius: 32px;              /* logo.png is a hard square; the mark is not */
  /* The float the previous site had (bh-core-front global.css, `logo-float`).
     Kept identical so the hero reads the same as it did before the port. */
  animation: as-logo-float 5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  will-change: transform;
}
@keyframes as-logo-float {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-9px) rotate(2.5deg); }
}
/* Nobody should be made queasy by decoration. */
@media (prefers-reduced-motion: reduce) {
  .as_main_logo_mark { animation: none; }
}

/* 🚨 `a.tl_main_logo { line-height: 0 }` comes from the ported sheet — it was
   sized for the inline SVG wordmark it used to hold. Our wordmark is live text,
   so the line-height has to come back or the name collapses to a sliver. The
   colour too: inside an <a> it would otherwise be link-blue. */
a.tl_main_logo { line-height: normal; }
.as_main_logo_title,
a.tl_main_logo .as_main_logo_title {
  font-size: 44px;
  line-height: 1.1;
  font-weight: 400;
  letter-spacing: -0.02em;
  text-align: center;
  margin: 16px 0 6px;
  color: #222;
}
html[data-theme="dark"] .as_main_logo_title { color: #f5f5f5; }

@media (max-width: 640px) {
  .as_main_logo_mark { width: 100px; height: 100px; border-radius: 22px; }
  .as_main_logo_title,
  a.tl_main_logo .as_main_logo_title { font-size: 30px; margin-top: 12px; }
}

/* ── Пустые хлебные крошки ─────────────────────────────────────────
   🚨 48 пикселей пустоты под шапкой складывались из трёх мест, и главное из
   них невидимо: на /api, /mvsy, /apps и постах блок .dev_page_bread_crumbs
   приходит ПУСТЫМ, но theme.css даёт ему padding-top: 16px — пустой div всё
   равно занимает высоту. Дальше margin-top: 12px !important у #dev_page_title
   и padding: 20px 0 у #dev_page_content_wrap. Итого 48px, из которых 28
   ничего не разделяют.

   Схлопываем ТОЛЬКО когда списка крошек внутри действительно нет: на
   /method/…, /schema, /changes, /manifesto правило не совпадает и отступы
   остаются прежними. `:has()` уже используется портированным theme.css, так
   что поддержка браузеров та же; где его нет, правило просто отбрасывается и
   страница выглядит как раньше.

   `:empty` было бы проще, но ломается от одного перевода строки внутри div —
   а разметку генерируют три разных места. */
.dev_page_bread_crumbs:not(:has(.breadcrumb)) { display: none; }
/* !important обязателен: у #dev_page_title в theme.css стоит margin-top с
   !important, и без него правило не перебивается. */
.dev_page_bread_crumbs:not(:has(.breadcrumb)) + #dev_page_title { margin-top: 0 !important; }

/* 🚨 Отступ под несуществующую шапку.
   В site.css шапка объявлена `position: fixed`, и там же контейнеру выдан
   `margin-top: 50px` — компенсация её высоты, потому что fixed-элемент выпадает
   из потока. Но выше в этом же файле стоит `.tl_page_head, .dev_page_head
   { position: relative }` (кнопке темы нужен позиционированный предок), extra.css
   грузится последним и перебивает fixed. Шапка вернулась в поток и занимает своё
   место сама, а компенсация осталась — это и есть пустая полоса между баром и
   контентом.
   Обнулять безопасно ровно потому, что шапка НЕ fixed: если её когда-нибудь
   вернут в fixed, это правило придётся снимать вместе с ним. */
.tl_page_container, .dev_page { margin-top: 0; }

/* ── Widget cards ──────────────────────────────────────────────────
   The four illustrations on /widgets. 🚨 scripts/css-prune.mjs had neutralised
   these to `background-image: none` because the files were missing — putting the
   files back does not undo that, so the rules are restated here rather than
   patched into the pruned sheet. Same selectors, same images. */
.dev_page_widget_thumb_share    { background-image: url('../img/Widget_Share.svg'); }
.dev_page_widget_thumb_post     { background-image: url('../img/Widget_Post.svg'); }
.dev_page_widget_thumb_login    { background-image: url('../img/Widget_Login.svg'); }
.dev_page_widget_thumb_comments { background-image: url('../img/Widget_Comments.svg'); }

/* ── Layer selector ────────────────────────────────────────────────
   A pill, not a square (1122). The ported sheet styles the dropdown ITEMS with
   border-radius: 999px but leaves the button that opens them square, so hover
   painted a rectangle over a rounded menu.

   🚨 The chevron is a sprite, and it was invisible for a different reason:
   img/dropdown.png and dropdown_1x.png were WEBP files carrying a .png
   extension. nginx types them by extension, so the browser was promised a PNG,
   handed WEBP bytes, and drew nothing. Re-encoded; this rule only makes the
   size explicit so a future mix-up shows as a gap rather than as nothing. */
.dev_layer_select > li > .dropdown-toggle {
  border-radius: 999px;
  padding: 6px 14px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background-color 0.12s ease;
}
.dev_layer_select > li > .dropdown-toggle:hover,
.dev_layer_select > li.open > .dropdown-toggle {
  background-color: rgba(23, 156, 222, 0.12);
  text-decoration: none;
}
html[data-theme="dark"] .dev_layer_select > li > .dropdown-toggle:hover,
html[data-theme="dark"] .dev_layer_select > li.open > .dropdown-toggle {
  background-color: rgba(94, 176, 243, 0.18);
}
/* 🚨 Стрелка рисуется здесь, а не берётся из спрайта.
 *
 * Портированная цепочка была такая: site.css кладёт фоном `img/dropdown_1x.png`,
 * theme.css перебивает это `background-image: none` и маской из
 * `img/dropdown.webp` со смещением `-2px -5px` при `mask-size: 18px 26px`. Хватало
 * одного промаха в этой цепочке — и вместо стрелки оставалась точка: спрайт был
 * WEBP-файлом с расширением `.png`, потом смещение показывало не тот кусок.
 *
 * Инлайновый SVG в маске убирает всю цепочку: файла нет, значит нечему не
 * загрузиться, а `currentColor` красит стрелку в цвет ссылки, как в эталоне.
 * `mask` тут уместнее `background-image`, потому что данные в data-URI нельзя
 * перекрасить, а элемент должен темнеть вместе с текстом. */
.dev_layer_select .caret,
.top_lang_select .minicaret {
  width: 12px;
  height: 12px;
  flex: none;
  border: 0;
  background: currentColor !important;
  background-image: none !important;
  -webkit-mask: var(--as-caret) center / 12px 12px no-repeat !important;
  mask: var(--as-caret) center / 12px 12px no-repeat !important;
  vertical-align: middle;
  opacity: 0.85;
}
:root {
  --as-caret: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.4 4.6 6 8.2l3.6-3.6' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  /* Галочка верификации и галочка «готово» в иллюстрациях виджетов. Маской, а
     не символом: ✓ рисуется системным шрифтом и на каждой платформе выглядит
     по-своему, а в фигуре она должна совпадать с той, что в клиенте. */
  --as-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='8' fill='%23000'/%3E%3Cpath d='M4.4 8.2 6.9 10.7 11.7 5.9' fill='none' stroke='%23fff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* Открытое меню — стрелка вверх, как у эталона. */
.dev_layer_select > li.open > .dropdown-toggle .caret,
.top_lang_select.open > .dropdown-toggle .minicaret { transform: rotate(180deg); }

/* ── Schema pages ──────────────────────────────────────────────────
   The API section a method belongs to, under its one-line summary. Quiet:
   it is navigation, not content. */
.as_schema_section {
  color: #8c8c8c;
  font-size: 14px;
  margin-top: -6px;
}
html[data-theme="dark"] .as_schema_section { color: #7d8b99; }
/* Error tables run three columns of text; the type column should not wrap
   mid-identifier while the description column has room to breathe. */
#dev_page_content table code { white-space: nowrap; }

/* ── Docs illustrations ────────────────────────────────────────────
   The protocol page's diagram, which the dumps referenced but did not carry. */
.dev_page_content > .as_docs_figure { margin: 24px 0; }

/* The Bot API illustration sits beside its section in the reference (1107),
   not centred above the whole page. Floated, with the text wrapping it. */
.as_docs_figure_right {
  float: right;
  width: 190px;
  max-width: 40%;
  margin: 0 0 12px 24px;
}
.as_docs_figure_right img { width: 100%; height: auto; }
@media (max-width: 700px) {
  /* Below this the text column is too narrow to wrap around anything. */
  .as_docs_figure_right { float: none; width: auto; max-width: 280px; margin: 16px auto; }
}
.as_docs_figure img {
  max-width: 100%;
  height: auto;
  display: block;
  margin: 0 auto;
  border-radius: 8px;
}

/* ── Nine homepage cards ───────────────────────────────────────────
   The reference sizes these from its own sprite sheet, which we do not have, so
   the <picture> collapsed to a 1px box and every card showed a broken-image
   placeholder. Sized explicitly instead. */
.tl_main_card_animated,
.tl_main_card_animated img,
.tl_main_card_animated canvas {
  display: block;
  width: 160px;
  height: 160px;
  margin: 0 auto;
}
.tl_main_card_animated > div { display: none; }

/* ── Blog ──────────────────────────────────────────────────────────
   Ours is API-driven, so the cards are generated rather than ported and need a
   little sizing of their own. */
.dev_blog_card_image {
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: 10px 10px 0 0;
  display: block;
}
.dev_blog_card_title { font-weight: 600; margin-bottom: 4px; }
.tl_blog_post_meta { color: #8b8f94; font-size: 14px; margin: 6px 0 18px; }
.tl_blog_post_cover {
  width: 100%;
  height: auto;
  border-radius: 12px;
  margin: 0 0 24px;
  display: block;
}
.tl_blog_post_body h2,
.tl_blog_post_body h3 { margin: 28px 0 10px; }

/* ── Иллюстрации виджетов ──────────────────────────────────────────
   Три картинки на /widgets/post и /widgets/login собраны разметкой, а не
   нарисованы: почему именно так — в src/content/widget-figures.js.

   Свои переменные, а не --d-*: те объявлены только внутри
   html[data-theme="dark"], и в светлой теме были бы пустыми. Здесь светлые
   значения — база, тёмные приходят переопределением ниже, поэтому фигура не
   мигает при переключении и не зависит от порядка загрузки стилей. */
.as_fig, .as_demo {
  --f-bg: #fff;
  --f-surface: #f4f4f5;
  --f-text: #16191c;
  --f-muted: #8b8f94;
  --f-border: #e4e6e8;
  --f-accent: #0088cc;
  margin: 24px 0 28px;
  padding: 0;
  color: var(--f-text);
  font-size: 14px;
  line-height: 1.4;
}
html[data-theme="dark"] .as_fig,
html[data-theme="dark"] .as_demo {
  --f-bg: #1d2733;
  --f-surface: #232e3c;
  --f-text: var(--d-text);
  --f-muted: var(--d-text-muted);
  --f-border: rgba(255, 255, 255, .1);
  --f-accent: var(--d-accent-bright);
}

/* ── Фигура «встроенный пост» ───────────────────────────────────── */
.as_fig_post { max-width: 560px; }
.as_fig_card {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px 14px;
  border: 1px solid var(--f-border);
  border-radius: 12px;
  background: var(--f-bg);
}
.as_fig_ava {
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--f-accent);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.as_fig_mark { width: 30px; height: 30px; }
.as_fig_body { min-width: 0; }
.as_fig_name {
  color: var(--f-accent);
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 5px;
}
/* Галочка рисуется маской, а не символом: ✓ в шрифте выглядит по-разному
   на каждой платформе, а в фигуре она должна совпадать с той, что в клиенте. */
.as_fig_verified {
  width: 15px;
  height: 15px;
  background: var(--f-accent);
  -webkit-mask: var(--as-check) no-repeat center / contain;
  mask: var(--as-check) no-repeat center / contain;
}
.as_fig_text { margin: 3px 0 6px; word-wrap: break-word; }
.as_fig_meta {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  flex-wrap: wrap;
}
.as_fig_link { color: var(--f-accent); }
.as_fig_stat { color: var(--f-muted); }
.as_fig_actions {
  display: flex;
  gap: 10px;
  align-items: center;
  justify-content: space-between;
  margin: 16px 0;
  flex-wrap: wrap;
}
.as_fig_act {
  color: var(--f-accent);
  font-weight: 600;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .02em;
}
/* Нажатая кнопка «Встроить»: она и открыла блок с кодом ниже, поэтому в
   фигуре подсвечена — иначе непонятно, откуда взялся сниппет. */
.as_fig_act_on { text-decoration: underline; text-underline-offset: 4px; }
.as_fig_act_primary {
  background: #4dcd5e;
  color: #fff;
  border-radius: 999px;
  padding: 9px 22px;
}
.as_fig_code {
  background: color-mix(in srgb, var(--f-accent) 9%, transparent);
  border-radius: 10px;
  padding: 12px 14px;
  overflow-x: auto;
}
.as_fig_code code {
  background: none;
  border: 0;
  padding: 0;
  color: var(--f-text);
  font-size: 12.5px;
  white-space: pre-wrap;
  word-break: break-all;
}
.as_fig_copy {
  text-align: center;
  margin-top: 12px;
  color: var(--f-muted);
  font-weight: 600;
  font-size: 13px;
  text-transform: uppercase;
}

/* ── Фигура «окно подтверждения» ─────────────────────────────────── */
.as_fig_sheet { display: flex; justify-content: center; }
.as_sheet {
  width: 100%;
  max-width: 340px;
  background: var(--f-surface);
  border: 1px solid var(--f-border);
  border-radius: 22px;
  padding: 14px 16px 18px;
  text-align: center;
}
.as_sheet_top { display: flex; }
.as_sheet_close {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--f-bg);
  position: relative;
}
.as_sheet_close::before,
.as_sheet_close::after {
  content: "";
  position: absolute;
  left: 7px;
  top: 12px;
  width: 12px;
  height: 1.6px;
  background: var(--f-text);
}
.as_sheet_close::before { transform: rotate(45deg); }
.as_sheet_close::after  { transform: rotate(-45deg); }
.as_sheet_icon {
  width: 62px;
  height: 62px;
  margin: 2px auto 14px;
  border-radius: 16px;
  background: var(--f-accent);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.as_sheet_icon .as_fig_mark { width: 40px; height: 40px; }
.as_sheet_title { font-size: 19px; font-weight: 700; }
.as_sheet_title b { color: var(--f-accent); font-weight: 700; }
.as_sheet_sub { margin: 8px 0 16px; color: var(--f-text); }
.as_sheet_rows {
  background: var(--f-bg);
  border-radius: 14px;
  text-align: left;
  overflow: hidden;
}
.as_sheet_row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
}
.as_sheet_row + .as_sheet_row { border-top: 1px solid var(--f-border); }
.as_sheet_val { text-align: right; }
.as_sheet_val i { display: block; color: var(--f-muted); font-style: normal; font-size: 13px; }
.as_sheet_note {
  color: var(--f-muted);
  font-size: 13px;
  text-align: left;
  padding: 7px 14px 12px;
}
.as_sheet_switch {
  width: 42px;
  height: 25px;
  border-radius: 999px;
  background: var(--f-accent);
  position: relative;
  flex: 0 0 auto;
}
.as_sheet_switch::after {
  content: "";
  position: absolute;
  top: 2.5px;
  right: 2.5px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
}
.as_sheet_btns { display: flex; gap: 10px; margin-top: 6px; }
.as_sheet_btn {
  flex: 1;
  padding: 12px 0;
  border-radius: 999px;
  background: var(--f-bg);
  font-weight: 600;
}
.as_sheet_btn_primary { background: var(--f-accent); color: #fff; }

/* ── Демонстрация входа (первый экран /widgets/login) ──────────────
   Заменяет ролик эталона на 3.1 МБ — тот показывал сайт стороннего сервиса,
   см. src/content/widget-figures.js.

   Один цикл 12 с, три сцены по четыре: кнопка на сайте → окно подтверждения →
   возврат. Всё на CSS: на первом экране страницы лишний скрипт — это ровно та
   задержка, из-за которой её закрывают, а декоративной анимации логика не
   нужна. */
.as_demo { max-width: 600px; margin: 24px auto 28px; }
.as_demo_win {
  border: 1px solid var(--f-border);
  border-radius: 14px;
  overflow: hidden;
  background: var(--f-bg);
  box-shadow: 0 8px 28px rgba(0, 0, 0, .07);
}
html[data-theme="dark"] .as_demo_win { box-shadow: none; }
.as_demo_bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 12px;
  background: var(--f-surface);
  border-bottom: 1px solid var(--f-border);
}
.as_demo_bar i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--f-border);
  flex: 0 0 auto;
}
.as_demo_bar span {
  flex: 1;
  margin-left: 8px;
  padding: 3px 12px;
  border-radius: 999px;
  background: var(--f-bg);
  color: var(--f-muted);
  font-size: 12.5px;
  text-align: center;
}
/* Высота фиксирована: сцены лежат друг на друге, и без неё контейнер
   схлопывался бы до высоты самой короткой. */
.as_demo_stage { position: relative; height: 260px; overflow: hidden; }
.as_demo_site {
  position: absolute;
  inset: 0;
  padding: 26px 28px;
  animation: as-demo-site 12s ease-in-out infinite;
}
.as_demo_h {
  width: 58%;
  height: 15px;
  border-radius: 4px;
  background: var(--f-border);
  margin-bottom: 14px;
}
.as_demo_p {
  height: 9px;
  border-radius: 4px;
  background: var(--f-border);
  opacity: .6;
  margin-bottom: 9px;
}
.as_demo_p_short { width: 72%; }
.as_demo_btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: 22px;
  padding: 11px 22px;
  border-radius: 999px;
  background: var(--f-accent);
  color: #fff;
  font-weight: 600;
  animation: as-demo-press 12s ease-in-out infinite;
}
.as_demo_mark { width: 20px; height: 20px; flex: 0 0 auto; }
.as_demo_sheet {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 300px;
  margin-left: -150px;
  padding: 18px 20px 20px;
  border-radius: 18px 18px 0 0;
  background: var(--f-surface);
  border: 1px solid var(--f-border);
  border-bottom: 0;
  text-align: center;
  transform: translateY(100%);
  animation: as-demo-sheet 12s ease-in-out infinite;
}
.as_demo_sheet_icon {
  width: 46px;
  height: 46px;
  margin: 0 auto 10px;
  border-radius: 12px;
  background: var(--f-accent);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.as_demo_sheet_icon .as_demo_mark { width: 28px; height: 28px; }
.as_demo_sheet_title { font-weight: 700; font-size: 16px; }
.as_demo_sheet_title b { color: var(--f-accent); }
.as_demo_sheet_sub { margin: 7px 0 14px; font-size: 13px; }
.as_demo_sheet_btns { display: flex; gap: 8px; }
.as_demo_sheet_btns span {
  flex: 1;
  padding: 10px 0;
  border-radius: 999px;
  background: var(--f-bg);
  font-weight: 600;
  font-size: 13px;
}
.as_demo_sheet_ok { background: var(--f-accent) !important; color: #fff; }
.as_demo_done {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background: var(--f-bg);
  font-weight: 600;
  opacity: 0;
  animation: as-demo-done 12s ease-in-out infinite;
}
.as_demo_check {
  width: 46px;
  height: 46px;
  background: #4dcd5e;
  -webkit-mask: var(--as-check) no-repeat center / contain;
  mask: var(--as-check) no-repeat center / contain;
}

@keyframes as-demo-site {
  0%, 66%   { opacity: 1; }
  70%, 96%  { opacity: 0; }
  100%      { opacity: 1; }
}
@keyframes as-demo-press {
  0%, 24%       { transform: scale(1); }
  28%           { transform: scale(.95); }
  32%, 100%     { transform: scale(1); }
}
@keyframes as-demo-sheet {
  0%, 28%   { transform: translateY(100%); }
  36%, 62%  { transform: translateY(0); }
  70%, 100% { transform: translateY(100%); }
}
@keyframes as-demo-done {
  0%, 66%   { opacity: 0; }
  72%, 92%  { opacity: 1; }
  98%, 100% { opacity: 0; }
}

/* Первый кадр самодостаточен и читается как обычная картинка, поэтому
   остановка ничего не ломает. */
@media (prefers-reduced-motion: reduce) {
  .as_demo_site, .as_demo_btn, .as_demo_sheet, .as_demo_done { animation: none; }
  .as_demo_sheet { display: none; }
  .as_demo_done { display: none; }
}

/* ── /share/url ────────────────────────────────────────────────────
   Цель кнопки «Поделиться». Страница живёт секунду и нужна ровно для одного
   решения, поэтому на ней нет ничего, кроме ссылки и двух кнопок. */
.as_share_wrap { max-width: 520px; margin: 40px auto 80px; text-align: center; }
.as_share_wrap h1 { font-size: 26px; margin-bottom: 20px; }
.as_share_link {
  word-break: break-all;
  font-size: 15px;
  padding: 12px 16px;
  border-radius: 10px;
  background: rgba(0, 136, 204, .08);
}
.as_share_text { color: #8b8f94; }
.as_share_go {
  display: inline-block;
  margin: 14px 0 6px;
  padding: 12px 28px;
  border-radius: 999px;
  background: #0088cc;
  color: #fff !important;
  font-weight: 600;
}
html[data-theme="dark"] .as_share_go { background: var(--d-accent); }

/* Предпросмотр кнопок в конструкторах. На чужой странице их вид задаётся
   инлайновыми стилями внутри сниппета (наш CSS туда не попадёт), а здесь
   нужен только повторяющий его образец. */
.as-login-btn {
  display: inline-flex;
  align-items: center;
  padding: 10px 22px;
  border-radius: 999px;
  background: #2a7bea;
  color: #fff;
  font-weight: 600;
}
