/* РУСФЛОУ · розыгрыш iPhone 18 - страница участника.
 *
 * Цвета, шрифты и прочие токены лежат в tokens.css: их делят страница
 * участника и админка, и расходиться им нельзя.
 */

/* --- Основа --- */

*, *::before, *::after { box-sizing: border-box; }

* { -webkit-tap-highlight-color: transparent; }

html {
  -webkit-text-size-adjust: 100%;
  background: var(--bg);
}

html[data-tone="deep"],
html[data-tone="deep"] body { background: var(--deep); }

body {
  margin: 0;
  min-height: 100vh;
  /* svh, а не dvh: это высота с показанной адресной строкой, то есть та,
     которая видна всегда. С dvh страница растёт, когда строка прячется, и
     тянущийся блок съедает новое место - нижняя строка так и не доезжает. */
  min-height: 100svh;
  background: var(--bg);
  color: var(--ink);
  font: 400 16px/1.5 var(--font-text);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
  transition: background-color .3s ease;
}

a { color: var(--link); text-underline-offset: 3px; }
a:hover { color: var(--link-hover); }

/* Кольцо фокуса - только для клавиатуры. От пальца и мыши ничего не остаётся. */
:focus { outline: none; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
[tabindex="-1"]:focus-visible { outline: none; }

[hidden] { display: none !important; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.mono { font-family: var(--font-mono); }

@keyframes rf-shimmer { 0% { background-position: -200px 0; } 100% { background-position: 400px 0; } }
@keyframes rf-spin { to { transform: rotate(360deg); } }
@keyframes rf-rotate { to { --rf-angle: 360deg; } }
@keyframes rf-enter-forward { from { opacity: 0; transform: translateX(28px); } to { opacity: 1; transform: none; } }
@keyframes rf-enter-back { from { opacity: 0; transform: translateX(-28px); } to { opacity: 1; transform: none; } }
@keyframes rf-enter-fade { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes rf-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes rf-pop { 0% { transform: scale(.6); opacity: 0; } 60% { transform: scale(1.08); opacity: 1; } 100% { transform: scale(1); } }
@keyframes rf-found { 0% { transform: scale(1); } 40% { transform: scale(.9); } 100% { transform: scale(.94); } }

/* --- Экран --- */

.screen {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 480px;
  min-height: 100vh;
  min-height: 100svh;
  margin: 0 auto;
  padding-top: env(safe-area-inset-top);
  color: var(--ink);
}
/* «Продолжить» стоит внизу экрана, а клавиатура не двигает страницу,
   а накрывает её: без этого кнопка уезжает под клавиатуру, а шапка -
   за верхний край. Высоту видимой части меряет app.js. */
:root.is-keyboard .screen { min-height: var(--vvh); }

.screen.is-enter-forward { animation: rf-enter-forward .34s var(--ease-out) both; }
.screen.is-enter-back { animation: rf-enter-back .34s var(--ease-out) both; }
.screen.is-enter-fade { animation: rf-enter-fade .3s var(--ease-out) both; }

.screen--deep { color: var(--on-deep); }
.screen--deep a { color: var(--gold); }

.screen__form { display: flex; flex-direction: column; flex: 1; }

.screen__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 26px var(--pad-x) 0;
}
.screen__body--form { display: block; }
.screen__body--list { display: block; padding-top: 8px; }
.screen__body--center { align-items: center; justify-content: center; text-align: center; }

.screen--deep .screen__body { padding: 28px 22px 0; }

.screen__actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px var(--pad-x) max(26px, env(safe-area-inset-bottom));
}

.topbar { display: flex; align-items: center; padding: 14px var(--pad-x) 0; }
.topbar + .screen__body, .topbar + .screen__form .screen__body { padding-top: 10px; }
.topbar--split { justify-content: space-between; }
.topbar__step { font-size: 14px; color: var(--ink-3); font-variant-numeric: tabular-nums; }

/* Полоса шагов анкеты. */
.progress { height: 3px; margin: 8px var(--pad-x) 0; border-radius: 999px; background: var(--line); overflow: hidden; }
.progress__bar {
  display: block; height: 100%; width: 0;
  border-radius: 999px;
  background: var(--check);
  transition: width .34s var(--ease-out);
}
.progress + .screen__form .screen__body { padding-top: 18px; }

.back {
  display: inline-flex; align-items: center;
  min-width: 44px; min-height: 44px;
  font-size: 15px; text-decoration: none;
}

.headbar {
  position: sticky; top: 0; z-index: 10;
  display: flex; justify-content: space-between; align-items: center;
  padding: 12px 12px 8px var(--pad-x);
  background: var(--bg);
}
.headbar__title { font: 600 27px var(--font-display); }
/* Шапка главной: фон общий, поэтому задаём только отступ под логотип. */
.headbar--hero { padding-left: 22px; }
.headbar--hero + .screen__body { padding-top: 10px; }
.headbar--deep { background: var(--deep); padding-left: 22px; }
.headbar--deep + .screen__body { padding-top: 10px; }

/* --- Типографика --- */

.display {
  margin: 0 0 8px;
  font: 700 31px/1.08 var(--font-display);
  text-wrap: balance;
}
.display--sm { font-size: 29px; margin-bottom: 14px; }
.display--hero { font-size: 44px; line-height: 1.02; margin: 6px 0 14px; }
.display--center { margin-top: 18px; text-align: center; }

.wordmark { font: 700 21px var(--font-display); letter-spacing: .06em; color: var(--accent); }

.lead { margin: 0 0 6px; font-size: 17px; line-height: 1.5; color: var(--on-deep-2); }

.text { margin: 0 0 22px; font-size: 16px; line-height: 1.5; color: var(--ink-2); max-width: 60ch; }
.text--tight { margin-bottom: 6px; }
.text--small { font-size: 15px; margin-bottom: 0; }
.text--muted { color: var(--ink-3); margin-top: 18px; }
.text--center { text-align: center; margin-left: auto; margin-right: auto; }
.text--nums, .input--nums { font-variant-numeric: tabular-nums; }

.hint { margin: 6px 0 0; font-size: 14px; color: var(--ink-3); }
.hint--center { text-align: center; margin-top: 0; }

.label { display: block; margin-bottom: 6px; font-size: 14px; color: var(--ink-2); }
.label--spaced { margin-top: 20px; }
.label__hint { color: var(--ink-4); }

/* --- Кнопки --- */

.btn {
  position: relative;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%;
  min-height: 56px;
  padding: 0 18px;
  border: none;
  border-radius: var(--radius-control);
  background: var(--btn);
  color: var(--btn-ink);
  font: 600 18px/1.2 var(--font-accent);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  user-select: none;
  transition: transform .16s var(--ease-out), background-color .2s ease, color .2s ease, opacity .2s ease;
}
a.btn { color: var(--btn-ink); }
.btn:hover, a.btn:hover { background: var(--btn-hover); color: var(--btn-ink); }
.btn:active { transform: scale(.97); }
.btn:disabled {
  background: var(--btn-disabled);
  color: var(--btn-disabled-ink);
  cursor: not-allowed;
  transform: none;
}

.btn--gold, a.btn--gold { background: var(--gold); color: #14251a; }
.btn--gold:hover, a.btn--gold:hover { background: var(--gold-hover); color: #14251a; }

.btn--outline, a.btn--outline {
  min-height: 52px; font-size: 17px;
  background: transparent; color: var(--link);
  box-shadow: inset 0 0 0 1.5px var(--link);
}
.btn--outline:hover, a.btn--outline:hover { background: var(--neutral-bg); color: var(--link); }

.btn--soft { min-height: 52px; font-size: 16px; background: var(--btn-soft); color: var(--btn-soft-ink); }
.btn--soft:hover { background: var(--line); color: var(--btn-soft-ink); }

.btn--slim, a.btn--slim { min-height: 46px; font-size: 16px; }
.btn--spaced { margin-top: 18px; }

.btn--light, a.btn--light { min-height: 52px; font-size: 17px; background: #ffffff; color: #14251a; }
.btn--light:hover, a.btn--light:hover { background: #f2efe9; color: #14251a; }

.btn--ghost, a.btn--ghost {
  min-height: 52px; font-size: 17px;
  background: none; color: #ffffff;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .35);
}
.btn--ghost:hover, a.btn--ghost:hover { background: rgba(255, 255, 255, .08); color: #ffffff; }

.btn[aria-busy="true"]::before {
  content: "";
  width: 18px; height: 18px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  opacity: .7;
  animation: rf-spin .8s linear infinite;
}

.btn-row { display: flex; gap: 10px; padding-top: 10px; }
.btn-row .btn { flex: 1; }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border: none; border-radius: 50%;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: background-color .2s ease, transform .16s var(--ease-out);
}
.icon-btn svg { width: 22px; height: 22px; fill: currentColor; }
.icon-btn:hover, .icon-btn[aria-expanded="true"] { background: var(--neutral-bg); }
.icon-btn:active { transform: scale(.92); }
.icon-btn .icon-stroke { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; }
.icon-btn--tiny { width: 36px; height: 36px; color: var(--ink-3); }
.icon-btn--tiny svg { width: 17px; height: 17px; }

.icon-btn--on-deep, a.icon-btn--on-deep { color: #ffffff; background: rgba(255, 255, 255, .12); }
.icon-btn--on-deep:hover, a.icon-btn--on-deep:hover { color: #ffffff; background: rgba(255, 255, 255, .2); }

.links { display: flex; gap: 18px; font-size: 15px; }
.links--center { justify-content: center; margin-top: 4px; }

/* --- Меню --- */

.menu { position: relative; }
.menu__panel {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 20;
  display: flex; flex-direction: column;
  min-width: 248px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--surface);
  box-shadow: var(--shadow-float);
  transform-origin: top right;
  opacity: 0;
  transform: scale(.9) translateY(-6px);
  transition: opacity .18s ease, transform .24s var(--ease-out);
}
.menu__panel.is-open { opacity: 1; transform: none; }
.menu__who {
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 12px 10px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 4px;
}
.menu__name { font: 600 16px var(--font-accent); color: var(--ink); }
.menu__name:empty { display: none; }
.menu__phone { font-size: 14px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.menu__item {
  display: flex; align-items: center;
  min-height: 46px;
  padding: 0 12px;
  border: none; border-radius: 12px;
  background: none;
  color: var(--ink);
  font: 400 16px var(--font-text);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .15s ease;
}
a.menu__item { color: var(--ink); }
.menu__item:hover, a.menu__item:hover { background: var(--neutral-bg); color: var(--ink); }
.menu__item--danger, .menu__item--danger:hover { color: var(--fail); }

/* --- Поля --- */

.input {
  width: 100%;
  min-height: 56px;
  padding: 0 15px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--ink);
  font: 400 18px var(--font-text);
  transition: border-color .2s ease, box-shadow .2s ease;
}
.input::placeholder { color: var(--ink-4); }
.input:focus, .input:focus-visible { outline: none; border-color: var(--link); box-shadow: inset 0 0 0 1px var(--link); }
.input--phone { font-variant-numeric: tabular-nums; }
.input--mono { font-family: var(--font-mono); }
.input[aria-invalid="true"] {
  border-color: var(--fail);
  box-shadow: inset 0 0 0 1px var(--fail);
  background: var(--fail-field);
}

.field-error { margin: 6px 0 0; font-size: 14px; color: var(--fail); }

/* Галочки: круг, золото в тёмной теме и зелёный в светлой, галка прорисовывается. */
.checks { display: flex; flex-direction: column; gap: 14px; margin-top: 24px; }
.hint--consents { margin: 12px 0 0; color: var(--on-deep-2); opacity: .85; }

.checks--optional { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--line); }

.check {
  position: relative;
  display: flex; gap: 12px; align-items: flex-start;
  font-size: 16px; line-height: 1.45;
  cursor: pointer;
}
.check--muted { color: var(--ink-2); }
.check__input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.check__box {
  flex: none;
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  margin-top: -1px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 2px var(--line-strong);
  transition: background-color .22s ease, box-shadow .22s ease, transform .22s var(--ease-out);
}
.check__box svg { width: 18px; height: 18px; fill: none; stroke: var(--check-ink); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.check__box path { stroke-dasharray: 20; stroke-dashoffset: 20; transition: stroke-dashoffset .28s ease .05s; }
.check__input:checked + .check__box { background: var(--check); box-shadow: inset 0 0 0 2px var(--check); animation: rf-pop .34s var(--ease-pop); }
.check__input:checked + .check__box path { stroke-dashoffset: 0; }
.check:active .check__box { transform: scale(.9); }
.check__input:focus-visible + .check__box { outline: 3px solid var(--focus); outline-offset: 2px; }

/* Раскрывающийся блок без скачка высоты. */
.reveal {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows .32s var(--ease-out), opacity .24s ease;
}
.reveal.is-open { grid-template-rows: 1fr; opacity: 1; }
.reveal__inner { min-height: 0; overflow: hidden; }
/* Раскрылся до конца - выпадающий список внутри может выйти за край. */
.reveal.is-settled .reveal__inner { overflow: visible; }
.reveal:not(.is-open) .reveal__inner { visibility: hidden; }

/* Место под капчу. Виджет невидимый, поэтому пусто он не занимает. */
.captcha { margin-top: 18px; }
.captcha:empty { display: none; }

/* Окно задания капчи. Его рисует Яндекс: затемнение - в нашей странице,
   а во фрейм кладёт свою страницу во весь экран. Фрейм подрезаем до окна
   по центру: вокруг остаётся затемнение, сквозь которое виден сайт.

   Внутри фрейма их подложка - белый лист с «ручкой» сверху, и покрасить
   её нечем: цвет зашит в их CSS. Зато карточку задания она раскладывает
   сама, любой высоты и с полями по краям. Поэтому подрезаем второй раз,
   уже внутри фрейма, ровно по карточке - белого не остаётся вовсе.

   Режем с запасом: под срез попадают и поля самой карточки, но они того
   же цвета, так что лишние пара пикселей незаметны, а белая кромка от
   задания чуть другой высоты - заметна.

   Имена классов чужие. Если Яндекс их поменяет, окно просто вернётся к
   своему виду во весь экран - сломаться тут нечему. */
.SmartCaptcha-Overlay { background: var(--scrim) !important; }
/* important здесь обязателен: размеры фрейма Яндекс ставит инлайном,
   а инлайн сильнее обычного правила. */
.SmartCaptcha-Overlay > iframe {
  position: absolute !important;
  left: 50% !important;
  top: 50% !important;
  transform: translate(-50%, -50%) !important;
  width: min(92vw, 380px) !important;
  /* Высота постоянная не случайно: их карточка задания всегда одной
     высоты и прижата к низу подложки, так что от высоты фрейма зависит
     только белое поле сверху - то самое, которое мы срезаем. */
  height: min(96vh, 440px) !important;
  clip-path: inset(46px 8px 14px 8px round 18px) !important;
}

/* --- Анкета --- */

.step { animation: rf-enter-fade .3s var(--ease-out); }
.step--done { display: flex; flex-direction: column; align-items: center; padding-top: 30px; }

/* Выбор одного варианта: тот же круглый знак, что у галочек. */
.options { display: flex; flex-direction: column; gap: 8px; }

.option {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  min-height: 54px;
  padding: 10px 15px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--ink);
  font: 400 17px/1.35 var(--font-text);
  text-align: left;
  cursor: pointer;
  transition: border-color .2s ease, background-color .2s ease, transform .16s var(--ease-out);
}
.option:active { transform: scale(.985); }
.option__mark {
  flex: none;
  width: 24px; height: 24px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 2px var(--line-strong);
  transition: background-color .22s ease, box-shadow .22s ease;
}
.option[aria-checked="true"] { border-color: var(--check); background: var(--neutral-bg); }
.option[aria-checked="true"] .option__mark {
  background: var(--check);
  box-shadow: inset 0 0 0 2px var(--check), inset 0 0 0 6px var(--surface);
  animation: rf-pop .34s var(--ease-pop);
}

/* Свой список вместо системного: тот же стиль, что у остальных полей. */
.picker { position: relative; flex: 1; min-width: 0; }

.picker__button {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%;
  min-height: 56px;
  padding: 0 12px 0 15px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-control);
  background: var(--surface);
  color: var(--ink);
  font: 400 17px var(--font-text);
  text-align: left;
  cursor: pointer;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.picker__button[aria-expanded="true"] { border-color: var(--link); box-shadow: inset 0 0 0 1px var(--link); }
.picker__value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picker__value--empty { color: var(--ink-4); }
.picker__chevron {
  flex: none; width: 20px; height: 20px;
  fill: none; stroke: var(--ink-4); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round;
  transition: transform .24s var(--ease-out);
}
.picker__button[aria-expanded="true"] .picker__chevron { transform: rotate(180deg); }

.picker__panel {
  position: absolute; z-index: 20;
  left: 0; right: 0; top: calc(100% + 6px);
  max-height: 258px;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface);
  box-shadow: var(--shadow-float);
  opacity: 0;
  transform: translateY(-6px) scale(.98);
  transform-origin: top center;
  transition: opacity .18s ease, transform .22s var(--ease-out);
}
.picker__panel--up { top: auto; bottom: calc(100% + 6px); transform-origin: bottom center; }
.picker__panel.is-open { opacity: 1; transform: none; }

.picker__item {
  display: block;
  width: 100%;
  min-height: 46px;
  padding: 0 12px;
  border: none;
  border-radius: 10px;
  background: none;
  color: var(--ink);
  font: 400 17px/46px var(--font-text);
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}
.picker__item:hover { background: var(--neutral-bg); }
.picker__item[aria-checked="true"] { background: var(--neutral-bg); color: var(--link); font-weight: 600; }

.picker--day { flex: none; width: 116px; }
.picker--day .picker__button, .picker--day .picker__item { font-variant-numeric: tabular-nums; }

.dates { display: flex; flex-direction: column; gap: 14px; margin-bottom: 14px; }
.dates:empty { display: none; }
.date-row {
  display: flex; flex-direction: column; gap: 8px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--surface-muted);
  animation: rf-rise .3s var(--ease-out);
}
.date-row__when { display: flex; align-items: center; gap: 8px; }

.checks--tight { margin-top: 16px; }

.otp-field { min-width: 0; margin: 16px 0 0; padding: 0; border: 0; }
.otp { display: flex; gap: 10px; justify-content: space-between; }
.otp__cell {
  flex: 1 1 0; min-width: 0; width: 100%;
  height: 80px;
  border: 1px solid var(--line-strong);
  border-radius: 16px;
  background: var(--surface);
  color: var(--ink);
  font: 600 32px var(--font-accent);
  text-align: center;
  font-variant-numeric: tabular-nums;
  caret-color: var(--link);
  transition: border-color .2s ease, box-shadow .2s ease, transform .16s var(--ease-out);
}
.otp__cell:focus, .otp__cell:focus-visible { outline: none; border-color: var(--link); box-shadow: inset 0 0 0 1px var(--link); }
.otp[aria-invalid="true"] .otp__cell { border-color: var(--fail); }
.otp.is-shaking { animation: rf-shake .36s ease; }
@keyframes rf-shake { 20%, 60% { transform: translateX(-6px); } 40%, 80% { transform: translateX(6px); } }

/* --- Плашки и уведомления --- */

.plaque {
  margin-top: 16px;
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--fail-bg);
  color: var(--fail);
  font-size: 15px;
  line-height: 1.45;
  animation: rf-rise .28s var(--ease-out);
}
.plaque--fail { background: var(--fail-bg); color: var(--fail); }
.plaque--wait { background: var(--wait-bg); color: var(--wait); }
.plaque--ok { background: var(--ok-bg); color: var(--ok); }
.plaque--top { margin: 0 0 18px; }
.plaque--neutral { background: var(--neutral-bg); color: var(--ink); }
.plaque--dock { margin: 0; text-align: center; }

.offline {
  position: sticky; top: 0; z-index: 40;
  max-width: 480px; margin: 0 auto;
  padding: calc(12px + env(safe-area-inset-top)) 16px 12px;
  background: var(--neutral-bg);
  color: var(--ink);
  font-size: 15px; line-height: 1.45;
}

.toast {
  position: fixed; left: 50%; bottom: calc(96px + env(safe-area-inset-bottom)); z-index: 50;
  width: min(440px, calc(100% - 32px));
  padding: 14px 16px;
  border-radius: 14px;
  background: var(--ink);
  color: var(--bg);
  font-size: 15px; line-height: 1.45;
  box-shadow: var(--shadow-float);
  opacity: 0;
  transform: translate(-50%, 16px);
  transition: opacity .22s ease, transform .3s var(--ease-out);
}
.toast.is-open { opacity: 1; transform: translate(-50%, 0); }

/* --- Лендинг: витрина трёх призов --- */

/* Главная живёт в общей теме: на тёмной это тот же глубокий зелёный,
   что и раньше, на светлой - тот же фон, что у входа и кабинета. Иначе
   переход с главной на вход выглядит разрывом: зелёный экран, потом белый. */
.screen[data-screen="landing"] {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(120% 55% at 50% -8%, var(--hero-halo), transparent 62%),
    var(--bg);
}

/* Лепестки падают по всему экрану: те же, что вылетают из-за картинки,
   только мелкие и далёкие. Их четыре, они медленные и полупрозрачные -
   фон дышит, но не отвлекает от кнопки. */
.petals { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.petals i {
  position: absolute;
  top: -20px;
  background: center / contain no-repeat;
  opacity: 0;
  animation: rf-fall 15s linear infinite;
}
.petals i:nth-child(1) { left: 12%; width: 13px; height: 13px; background-image: url("/static/img/petal-1.webp"); animation-duration: 13s; }
.petals i:nth-child(2) { left: 38%; width: 10px; height: 10px; background-image: url("/static/img/petal-2.webp"); animation-duration: 17s; animation-delay: 3s; }
.petals i:nth-child(3) { left: 64%; width: 14px; height: 14px; background-image: url("/static/img/petal-3.webp"); animation-duration: 15s; animation-delay: 6s; }
.petals i:nth-child(4) { left: 86%; width: 9px; height: 9px; background-image: url("/static/img/petal-2.webp"); animation-duration: 19s; animation-delay: 9s; }
@keyframes rf-fall {
  0% { transform: translateY(0) rotate(0); opacity: 0; }
  12% { opacity: .55; }
  100% { transform: translateY(105vh) rotate(220deg); opacity: 0; }
}

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

.screen__body--hero { gap: 0; overflow: hidden; }
.display--hero { font-size: clamp(24px, 7.4vw, 30px); margin: 4px 0 0; line-height: 1.1; }

.eyebrow { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.eyebrow > span:first-child {
  font: 600 11px var(--font-mono);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-4);
}
.eyebrow__rule { flex: 1; height: 1px; background: linear-gradient(90deg, var(--hero-rule), transparent); }

/* Общая картинка всех призов. Фон у неё прозрачный (scripts/make_hero.py
   проверяет), за ней круглое бордовое свечение, как у призов в обзоре.

   Сам блок от края до края экрана: свечению и лепесткам есть где
   развернуться. Картинка - по колонке страницы, вровень с плашками и
   кнопкой: вплотную к краям экрана она упиралась в них. */
.hero {
  position: relative;
  z-index: 0;
  flex: 1 1 0;
  min-height: 150px;
  margin: 8px calc(-1 * var(--hero-bleed, 22px)) 0;
  display: flex; align-items: center; justify-content: center;
  /* Рамка картинки вписывается в свободное место целиком, как object-fit:
     contain, - по ширине или по высоте, смотря что кончится раньше. */
  container-type: size;
  --hero-ratio: 1;
  /* Размер картинки: не шире колонки, не выше свободного места. Считается
     у детей, поэтому cqw и cqh здесь - от самого блока. */
  --hero-w: min(calc(100cqw - 2 * var(--hero-bleed, 22px)), calc(94cqh * var(--hero-ratio)));
}
/* Заголовок выше свечения и лепестков: они могут до него долететь. */
.display--hero, .eyebrow { position: relative; z-index: 1; }

/* Рамка ровно по картинке: подсказка считается от неё, а не от всего
   свободного места. Это кнопка: нажатие запускает обзор призов. */
.hero__frame {
  position: relative;
  width: 100%;
  width: var(--hero-w);
  aspect-ratio: var(--hero-ratio);
  padding: 0;
  border: none;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.hero__frame:focus-visible { outline-offset: -3px; border-radius: 16px; }
/* Свечение - круг по центру картинки, не шире свободного места: иначе на
   широком экране его срезала бы колонка страницы. */
.hero__frame::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: 50%; top: 50%;
  width: min(100cqw, 100cqh);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  /* Радиусы ровно 50% коробки: цвет гаснет прямо на её краю, обрыва нет. */
  background: radial-gradient(50% 50% at 50% 50%,
    var(--hero-glow) 0%,
    var(--hero-glow-2) 55%,
    transparent 100%);
  opacity: 0;
  transition: opacity .8s ease;
}
.hero.is-ready .hero__frame::before { opacity: 1; }
.hero__photo {
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity .6s ease;
}
/* Спокойное дыхание: картинка чуть приближается и отходит, заметно
   боковым зрением и не мешает смотреть. */
.hero.is-ready .hero__photo { opacity: 1; animation: rf-breath 14s ease-in-out infinite alternate; }
@keyframes rf-breath { from { transform: scale(1); } to { transform: scale(1.05); } }
.hero__frame:active .hero__photo { transform: scale(.98); transition: transform .15s ease; }

/* Лепестки: вылетают из-за картинки и летят на смотрящего - растут,
   разгоняются, поворачиваются и гаснут у края. Маршрут у каждого полёта
   свой, случайный, его задаёт app.js. Сначала лепесток позади картинки,
   потом выходит вперёд - когда уже вылетел из-за неё, поэтому незаметно.

   Слой ровно по картинке: точка вылета на любом экране приходится на неё. */
.hero__petals {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 100%;
  height: 100%;
  width: var(--hero-w);
  height: calc(var(--hero-w) / var(--hero-ratio));
  pointer-events: none;
}
.hero__petals i {
  position: absolute;
  width: 30px; height: 30px;
  margin: -15px 0 0 -15px;
  background: center / contain no-repeat;
  opacity: 0;
  z-index: -1;
}

/* Подсказка, что картинку можно нажать. Не подпись к призам, а знак
   «здесь есть ещё»: маленькая, внизу, появляется вместе с картинкой. */
.hero__hint {
  position: absolute;
  left: 50%; bottom: 2%;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--hero-hint);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  font: 600 12px var(--font-accent);
  letter-spacing: .02em;
  color: var(--ink);
  white-space: nowrap;
  opacity: 0;
  transform: translate(-50%, 6px);
  transition: opacity .6s ease .5s, transform .6s ease .5s;
}
.hero__hint::after {
  content: "";
  width: 6px; height: 6px;
  border-top: 1.5px solid var(--accent);
  border-right: 1.5px solid var(--accent);
  transform: rotate(45deg);
  margin-left: -1px;
}
.hero.is-ready .hero__hint { opacity: 1; transform: translate(-50%, 0); }

/* Смена «общая картинка - обзор» идёт мягким проявлением, а не рывком. */
.hero, .stage, .showcase { animation: rf-appear .45s ease both; }
@keyframes rf-appear { from { opacity: 0; } to { opacity: 1; } }

/* Сцена: карточки призов лежат друг на друге, видна одна. */
.stage { position: relative; flex: 1 1 0; min-height: 132px; margin-top: 6px; cursor: pointer; }
/* Свечение за призом. Эллипс гаснет ровно на границе своей коробки: если он
   шире её, у краёв остаётся цвет и получается прямоугольный обрубок. */
.stage__glow {
  position: absolute; inset: -8% -12%;
  opacity: 0;
  transition: opacity .8s ease;
}
.stage__card {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  opacity: 0;
  transform: scale(.92) translateY(14px);
  transition: opacity .7s ease, transform .7s cubic-bezier(.22, .8, .3, 1);
  pointer-events: none;
}
.stage__card.is-on, .stage__glow.is-on { opacity: 1; }
.stage__card.is-on { transform: none; pointer-events: auto; }
.stage__photo {
  max-width: min(62vw, 230px);
  max-height: 100%;
  width: auto; height: auto;
  filter: drop-shadow(0 22px 36px var(--hero-shadow));
  animation: rf-float 6s ease-in-out infinite;
}
/* Фото ещё нет - на сцене рамка с названием, а не пустота. */
.stage__slot {
  display: flex; align-items: center; justify-content: center;
  width: 196px; max-width: 62vw; height: min(250px, 100%);
  padding: 18px;
  border: 1px dashed var(--line-strong);
  border-radius: 18px;
  background: var(--surface-muted);
  color: var(--ink-3);
  font-size: 13px; line-height: 1.45; text-align: center;
  animation: rf-float 6s ease-in-out infinite;
}
@keyframes rf-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }

.showcase { margin-top: 10px; }
.showcase__label { min-height: 16px; font: 600 12px var(--font-accent); letter-spacing: .09em; color: var(--accent); }
.showcase__name { margin-top: 4px; font: 400 clamp(24px, 8vw, 31px)/1.12 var(--font-display); text-wrap: balance; }
.showcase__note { margin-top: 4px; font-size: 15px; color: var(--ink-2); }

.showcase__foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 14px; }
.dots { display: flex; gap: 7px; }
.dots button {
  width: 8px; height: 8px;
  padding: 0;
  border: none; border-radius: 99px;
  background: var(--line-strong);
  cursor: pointer;
  transition: width .4s ease, background-color .4s ease;
}
.dots button.is-on { width: 26px; background: var(--accent); }
/* Из обзора обратно к общей картинке раньше, чем он кончится сам. */
.showcase__back {
  padding: 6px 2px;
  border: none;
  background: none;
  color: var(--ink-3);
  font: 600 13px var(--font-accent);
  cursor: pointer;
}
.showcase__back:hover { color: var(--ink); }

/* Правило билетов: две плашки, значение золотом, подпись под ним.
   Свои имена классов: .chip - это номер билета в кабинете, и общие имена
   растягивали там номера на полстроки. */
.rule-chips { display: flex; gap: 8px; margin-top: 16px; }
.rule-chip {
  flex: 1;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
}
.rule-chip__amount { display: block; font: 600 17px var(--font-accent); color: var(--accent); font-variant-numeric: tabular-nums; }
.rule-chip__gives { display: block; margin-top: 2px; font-size: 13px; color: var(--ink-2); }

/* Блик по кнопке: движение там, где ждут нажатия.

   Двигаем сам градиент, а не полоску: полоска без заданного левого края
   начинает путь оттуда, где кончился текст, то есть из середины кнопки.
   Так блик всегда проходит её целиком, от края до края. */
.btn--shine { position: relative; overflow: hidden; }
.btn--shine::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg,
    rgba(255, 255, 255, 0) 42%,
    rgba(255, 255, 255, .6) 50%,
    rgba(255, 255, 255, 0) 58%);
  background-size: 250% 100%;
  background-repeat: no-repeat;
  animation: rf-sweep 3.6s ease-in-out infinite;
  pointer-events: none;
}
@keyframes rf-sweep {
  0% { background-position: -70% 0; }
  /* Дальше блик стоит за краем: пауза между проходами, а не рывок.
     Возврат в начало происходит, когда его не видно ни с той, ни с другой
     стороны, - поэтому шва нет. */
  40%, 100% { background-position: 170% 0; }
}

.when { margin: 10px 0 0; text-align: center; font-size: 14px; color: var(--ink-2); }
.when b { color: var(--accent); font-weight: 600; }

/* --- Правила и честность --- */

/* Правила читают глазами по диагонали: заголовок пункта отдельной строкой,
   а не в начале абзаца, иначе весь экран сливается в один серый кирпич. */
.rules { display: flex; flex-direction: column; gap: 18px; margin-top: 8px; font-size: 16px; line-height: 1.5; color: var(--ink-2); max-width: 60ch; }
.rules p { margin: 0; }
.rules b {
  display: block;
  margin-bottom: 3px;
  color: var(--ink);
  font: 600 15px/1.3 var(--font-accent);
}
.rules p::before {
  content: "";
  display: block;
  width: 22px;
  height: 2px;
  margin-bottom: 9px;
  border-radius: 2px;
  background: var(--gold);
  opacity: .8;
}

.note-box { margin: 20px 0 0; padding: 16px; border-radius: 14px; background: var(--neutral-bg); color: var(--ink); font-size: 15px; line-height: 1.5; }
.note-box__link { margin-top: 10px; }

.steps { display: flex; flex-direction: column; gap: 12px; margin: 0; padding: 0; list-style: none; }

.card { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px; font-size: 15px; line-height: 1.5; }
.card__title { font: 600 15px/1.5 var(--font-accent); margin-bottom: 4px; }
.card__text { color: var(--ink-2); }

.hash {
  margin-top: 10px; padding: 8px 10px;
  border-radius: 8px;
  background: var(--canvas);
  color: var(--ink);
  font: 400 13px/1.45 var(--font-mono);
  word-break: break-all;
}

.hash__value { margin: 6px 0; }

/* Вкладки: свои чеки в кабинете и билеты в общем списке. Подписи разной
   длины, поэтому не равные плашки, а строка с подчёркиванием активной. */
.tabs {
  display: flex; gap: 20px;
  margin: 16px 0 14px;
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs__tab {
  position: relative;
  flex: none;
  padding: 6px 0 10px;
  border: none;
  background: none;
  color: var(--ink-3);
  font: 600 15px var(--font-accent);
  white-space: nowrap;
  cursor: pointer;
  transition: color .2s ease;
}
.tabs__tab.is-on { color: var(--ink); }
.tabs__tab.is-on::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -1px;
  height: 2px; border-radius: 2px;
  background: var(--check);
}
.tabs__count { margin-left: 5px; color: var(--ink-4); font-variant-numeric: tabular-nums; }
.tabs__tab.is-on .tabs__count { color: var(--ink-3); }

/* Список билетов: строка на билет, как в файле. */
.input--search { margin-bottom: 12px; }
.check--mine { margin-bottom: 14px; }

.tickets { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.ticket {
  display: flex; align-items: baseline; gap: 10px;
  padding: 9px 12px;
  border-radius: 10px;
  background: var(--surface);
}
.ticket:nth-child(odd) { background: var(--neutral-bg); }
.ticket__code { flex: none; font: 400 14px var(--font-mono); letter-spacing: .02em; color: var(--ink); }
.ticket__who { min-width: 0; font-size: 14px; color: var(--ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ticket--annulled .ticket__code { color: var(--ink-4); text-decoration: line-through; }
/* Свои билеты видно сразу: на них и приходят смотреть. */
.ticket--mine, .ticket--mine:nth-child(odd) { background: var(--ok-bg); box-shadow: inset 2px 0 0 var(--ok); }
.ticket--mine .ticket__code { font-weight: 600; }

.steps--registry { margin-top: 20px; }

.consent { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line); }
.consent__title { margin: 0 0 6px; font: 600 16px var(--font-accent); }

/* --- Кабинет --- */

.summary {
  padding: 20px;
  border-radius: 20px;
  background: var(--summary);
  color: var(--summary-ink);
}
.summary.is-new { animation: rf-rise .4s var(--ease-out); }
.summary__count { font: 600 48px/1.05 var(--font-accent); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.summary__sub { margin-top: 8px; font-size: 15px; line-height: 1.45; color: var(--summary-ink-2); }

/* Приглашение в анкету: живёт над списком чеков, закрывается крестиком. */
.invite {
  position: relative;
  margin-top: 14px;
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--surface);
  animation: rf-rise .4s var(--ease-out);
}
.invite__close { position: absolute; top: 6px; right: 6px; }
.invite__title { font: 600 18px var(--font-accent); padding-right: 36px; }
.invite__text { margin: 6px 0 12px; font-size: 15px; line-height: 1.45; color: var(--ink-2); }

.claims { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }

.claim {
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--surface);
}
.claim.is-new {
  animation: rf-rise .38s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 45ms + 60ms);
}
.claim--fail { background: var(--surface-muted); }
.claim__head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.claim__amount { font: 600 19px var(--font-accent); font-variant-numeric: tabular-nums; }
.claim--fail .claim__amount { color: var(--ink-amount-muted); }
.claim__meta { margin-top: 4px; font-size: 14px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.claim__note { margin-top: 8px; font-size: 14px; color: var(--ink-2); }
.claim__note:empty, .chips:empty { display: none; }

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  flex: none;
  padding: 5px 10px;
  border-radius: 999px;
  font: 600 13px var(--font-accent);
  white-space: nowrap;
}
.pill__mark { display: block; }
/* Плашка статуса - кнопка: по ней разворачивается расчёт по чеку. */
.pill { border: none; cursor: pointer; }
.pill:disabled { cursor: default; }
.pill__chevron {
  width: 13px; height: 13px;
  fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
  transition: transform .2s var(--ease-out);
}
.pill[aria-expanded="true"] .pill__chevron { transform: rotate(180deg); }
.pill:disabled .pill__chevron { display: none; }

/* Расчёт по чеку: откуда взялась сумма в счёт и сколько вышло билетов. */
.calc {
  display: grid; grid-template-columns: 1fr auto; gap: 6px 14px;
  margin: 12px 0 0; padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 14px;
}
.calc__label { margin: 0; color: var(--ink-3); }
.calc__value { margin: 0; color: var(--ink); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.pill--success { background: var(--ok-bg); color: var(--ok); }
.pill--success .pill__mark { width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.pill--wait { background: var(--wait-bg); color: var(--wait); }
.pill--wait .pill__mark { width: 8px; height: 8px; border-radius: 2px; background: currentColor; }
.pill--fail { background: var(--fail-bg); color: var(--fail); }
.pill--fail .pill__mark { width: 8px; height: 2px; background: currentColor; }

.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; font: 400 14px var(--font-mono); }
.chip { padding: 4px 8px; border-radius: 8px; background: var(--canvas); color: var(--ink); }
.chip--annulled { color: var(--ink-4); text-decoration: line-through; }
.chips__more {
  align-self: center;
  min-height: 32px; padding: 0 6px;
  border: none; background: none;
  color: var(--link);
  font: 600 14px var(--font-accent);
  cursor: pointer;
}
.chips--large { font-size: 15px; margin: 0 0 22px; }
.chips--large .chip { padding: 5px 9px; animation: rf-pop .36s var(--ease-pop) both; animation-delay: calc(var(--i, 0) * 60ms + 180ms); }

.empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: calc(100dvh - 240px);
  padding: 20px 12px;
  text-align: center;
  animation: rf-rise .4s var(--ease-out);
}
.empty__icon {
  display: flex; align-items: center; justify-content: center;
  width: 88px; height: 88px;
  margin-bottom: 18px;
  border-radius: 50%;
  background: var(--neutral-bg);
}
.empty__icon svg { width: 44px; height: 44px; fill: none; stroke: var(--link); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.empty__title { margin-bottom: 8px; font: 700 27px var(--font-display); }
.empty .text { margin: 0; }

/* Нижняя панель: кнопка «Добавить чек» всегда на одном месте. */
.dock {
  position: sticky; bottom: 0; z-index: 5;
  margin-top: auto;
  padding: 18px var(--pad-x) max(20px, env(safe-area-inset-bottom));
  background: linear-gradient(to top, var(--bg) 72%, transparent);
}

.skeleton { display: flex; flex-direction: column; gap: 10px; padding-top: 4px; }
.skeleton__block {
  height: 92px;
  border-radius: 16px;
  background: linear-gradient(90deg, var(--shimmer-a) 0, var(--shimmer-b) 40%, var(--shimmer-a) 80%);
  background-size: 400px 100%;
  animation: rf-shimmer 1.4s linear infinite;
}
.skeleton__block--tall { height: 116px; border-radius: 20px; }

.final {
  margin-bottom: 14px; padding: 22px;
  border-radius: 20px;
  background: #1a4126;
  color: #ffffff;
  animation: rf-rise .4s var(--ease-out);
}
.final__eyebrow { margin-bottom: 8px; font-size: 14px; color: #ffc174; }
.final__title { margin-bottom: 6px; font: 700 33px/1.05 var(--font-display); }
.final__prize { margin-bottom: 10px; font: 600 19px var(--font-accent); color: #ffc174; }
.final__prize:empty { display: none; }
.final__ticket { display: inline-block; margin-bottom: 12px; padding: 8px 10px; border-radius: 8px; background: rgba(255, 255, 255, .12); font-size: 16px; }
.final__text { margin: 0 0 16px; font-size: 15px; line-height: 1.5; color: #d6e3d9; }

.finished { display: flex; flex-direction: column; gap: 10px; margin-bottom: 14px; }
.finished .text { margin: 0; }
.finished__title { font: 700 27px var(--font-display); }

/* --- Сканер --- */

.screen--scan { overflow: hidden; }
.scan__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .4s ease; }
.screen--scan.is-live .scan__video { opacity: 1; }
.scan__body { position: relative; align-items: center; justify-content: center; gap: 22px; padding: 20px; }
.screen--scan .screen__actions { position: relative; }
.scan__top { position: relative; z-index: 2; display: flex; justify-content: flex-end; padding: 12px 14px 0; }
.scan__prompt { margin: 0; max-width: 26ch; font-size: 17px; line-height: 1.45; color: #ffffff; text-align: center; }
.scan__tip {
  max-width: 300px;
  padding: 12px 14px;
  border-radius: 12px;
  background: rgba(20, 37, 26, .72);
  color: #e8eee9;
  font-size: 15px; line-height: 1.45;
  text-align: center;
  transition: background-color .25s ease;
}
.scan__tip--alert { background: rgba(124, 59, 51, .92); color: #ffffff; }

/* Рамка из золота, по которой медленно бежит перелив. */
.viewfinder {
  position: relative;
  width: 244px; height: 244px;
  border-radius: 26px;
  background: rgba(255, 255, 255, .03);
}
.screen--scan.is-live .viewfinder { background: transparent; box-shadow: 0 0 0 100vmax rgba(10, 20, 14, .6); }
.viewfinder::before {
  content: "";
  position: absolute; inset: 0;
  padding: 3px;
  border-radius: inherit;
  background: conic-gradient(from var(--rf-angle), #c98b3f, #ffc174 18%, #fff3dc 26%, #ffc174 34%, #c98b3f 52%, #ffc174 70%, #ffe7bf 78%, #ffc174 86%, #c98b3f);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  animation: rf-rotate 5s linear infinite;
}
.viewfinder__glow {
  position: absolute; inset: -14px;
  border-radius: 38px;
  background: radial-gradient(closest-side, rgba(255, 193, 116, .18), transparent);
  pointer-events: none;
}
.viewfinder.is-found { animation: rf-found .4s var(--ease-out) forwards; }
/* Код в рамке виден, ждём второе чтение: рамка светится ровно и ярче. */
.viewfinder.is-seeing::before { animation-play-state: paused; filter: brightness(1.25) saturate(1.2); }
.viewfinder.is-seeing .viewfinder__glow { background: radial-gradient(closest-side, rgba(255, 193, 116, .38), transparent); }

/* --- Ручной ввод --- */

.receipt-help {
  display: flex; gap: 12px; align-items: stretch;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--surface);
}
.receipt {
  display: flex; flex-direction: column; gap: 5px;
  flex: none; width: 118px;
  padding: 10px 8px;
  border-radius: 8px;
  background: #f2efe9;
  color: #7b8580;
  font: 400 9px/1.3 var(--font-mono);
}
.receipt__rule { height: 1px; background: #dcd7cd; }
.receipt__mark { padding: 2px 3px; border-radius: 3px; background: #ffc174; color: #14251a; }
.receipt__qr { height: 30px; margin-top: 4px; border-radius: 3px; background: #dcd7cd; }
.receipt-help__text { align-self: center; font-size: 14px; line-height: 1.5; color: var(--ink-2); }

/* --- Шторки --- */

/* Шторка стоит над клавиатурой: --kb ставит app.js, без клавиатуры он ноль.
   Иначе поле для почты открывает клавиатуру, а сама шторка остаётся под
   ней - человек печатает вслепую. */
.sheet { position: fixed; inset: 0 0 var(--kb, 0px); z-index: 30; display: flex; flex-direction: column; justify-content: flex-end; }
.sheet__backdrop { position: absolute; inset: 0; background: var(--scrim); opacity: 0; transition: opacity .3s ease; }
.sheet__panel {
  position: relative;
  width: 100%; max-width: 480px;
  max-height: calc(var(--vvh, 100dvh) - 40px);
  overflow-y: auto;
  margin: 0 auto;
  padding: 10px 22px max(24px, env(safe-area-inset-bottom));
  border-radius: 24px 24px 0 0;
  background: var(--surface);
  box-shadow: var(--shadow-float);
  transform: translateY(105%);
  transition: transform .42s var(--ease-sheet);
}
.sheet.is-open .sheet__backdrop { opacity: 1; }
.sheet.is-open .sheet__panel { transform: none; }
.sheet__grip { width: 40px; height: 5px; margin: 0 auto 18px; border-radius: 3px; background: var(--line-strong); }
.sheet__icon {
  display: flex; align-items: center; justify-content: center;
  width: 52px; height: 52px;
  margin-bottom: 14px;
  border-radius: 50%;
}
.sheet.is-open .sheet__icon { animation: rf-pop .42s var(--ease-pop) .12s both; }
.sheet__icon span { display: block; }
.sheet__icon--success, .sheet__icon--repeat { background: var(--ok-bg); }
.sheet__icon--success span, .sheet__icon--repeat span { width: 17px; height: 9px; margin-top: -4px; border-left: 3px solid var(--ok); border-bottom: 3px solid var(--ok); transform: rotate(-45deg); }
.sheet__icon--wait { background: var(--wait-bg); }
.sheet__icon--wait span { width: 14px; height: 14px; border-radius: 4px; border: 3px solid var(--wait); }
.sheet__icon--fail { background: var(--fail-bg); }
.sheet__icon--fail span { width: 16px; height: 3px; background: var(--fail); }
.sheet__title { margin: 0 0 10px; font: 700 35px/1.05 var(--font-display); text-wrap: balance; }
.sheet__title--sm { font-size: 29px; }
.sheet__text { margin: 0 0 20px; font-size: 16px; line-height: 1.5; color: var(--ink-2); }
.sheet__text--tight { margin-bottom: 16px; }
.sheet__text + .chips--large:empty { display: none; }
.sheet__button { margin-top: 16px; }
.sheet__button + .sheet__button { margin-top: 10px; }

.install-steps { margin: 4px 0 8px; padding-left: 22px; font-size: 16px; line-height: 1.9; color: var(--ink-2); }
.install-steps b { color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .check__box path { stroke-dashoffset: 0; }
  .check__input:not(:checked) + .check__box path { stroke-dashoffset: 20; }
}
