/*
 * Оформление кабинета по прототипу заказчика: золотой акцент, вкладки сверху.
 * Прототип заказчика тёмный, отсюда и основная тема кабинета.
 *
 * Тем две, и выбираем не мы. Telegram отдаёт свою в colorScheme и шлёт событие
 * при переключении, а сама она следует за настройкой приложения и ОС. Вне
 * мессенджера остаётся prefers-color-scheme. Поэтому набор токенов один, а
 * значения переопределяются в трёх местах: системная тёмная, явная тёмная,
 * явная светлая. Атрибут data-theme ставит скрипт из шапки.
 *
 * Золото — бренд, оно одинаковое в обеих темах. Но золото как текст на белом
 * нечитаемо, поэтому у акцента два токена: фон кнопки и цвет надписи.
 */

:root {
    /*
     * Курсор в поле и подсветка выделения берутся не из наших токенов, а из темы,
     * которую браузер считает используемой. В мессенджере она приходит от приложения:
     * Telegram в тёмном режиме — и WebKit красит курсор белым, а наш светлый кабинет
     * оставался с невидимой кареткой и невидимым выделением. Поэтому тема объявляется
     * вместе с токенами, а не только цветами.
     */
    color-scheme: light;

    --bg: #ffffff;
    --surface: #f4f4f7;
    --surface-sunken: #ebebf0;
    --line: #e0e0e6;
    --text: #16161a;
    --text-muted: #6a6a72;
    --text-dim: #8a8a94;

    --accent: #ffc107;
    --accent-text: #8a6508;
    --accent-bg: #fff8e1;
    --accent-line: #ffe082;
    --accent-dim: #8a6508;

    --danger: #dc2626;
    --danger-bg: #fef2f2;
    --danger-line: #fecaca;
    --success: #16a34a;
    --success-bg: #f0fdf4;
    --success-line: #bbf7d0;
    /* Синий — про «идёт сейчас»: он не тревожит, как красный, и не поздравляет, как
       зелёный. Свой токен, потому что бренд золотой и акцентом это не сказать. */
    --info: #2563eb;
    --info-bg: #eff6ff;
    --info-line: #bfdbfe;

    --radius: 14px;
    --radius-sm: 12px;

    /*
     * Место, занятое системой и шапкой мессенджера. По умолчанию — то, что сообщает
     * браузер про вырезы экрана; в полноэкранном режиме поверх этого пишет точные
     * числа assets/safearea.js: про свою шапку браузер не знает ничего.
     */
    --safe-top: env(safe-area-inset-top, 0px);
    --safe-bottom: env(safe-area-inset-bottom, 0px);
}

/* Тёмные значения задаются один раз и подключаются двумя условиями:
   системная тема, если явного выбора нет, и явный выбор мессенджера. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;

        --bg: #16161a;
        --surface: #1e1e24;
        --surface-sunken: #121216;
        --line: #2a2a32;
        --text: #f4f4f7;
        --text-muted: #6a6a72;
        --text-dim: #5a5a64;

        --accent-text: #ffc107;
        --accent-bg: #2a2200;
        --accent-line: #3a2e00;
        --accent-dim: #b58a14;

        --danger: #ef4444;
        --danger-bg: #1e1212;
        --danger-line: #4a1a1a;
        --info: #60a5fa;
        --info-bg: #10203a;
        --info-line: #1e3a5f;
        --success: #4ade80;
        --success-bg: #1a2e1a;
        --success-line: #1f4a1f;
    }
}

:root[data-theme="dark"] {
    color-scheme: dark;

    --bg: #16161a;
    --surface: #1e1e24;
    --surface-sunken: #121216;
    --line: #2a2a32;
    --text: #f4f4f7;
    --text-muted: #6a6a72;
    --text-dim: #5a5a64;

    --accent-text: #ffc107;
    --accent-bg: #2a2200;
    --accent-line: #3a2e00;
    --accent-dim: #b58a14;

    --danger: #ef4444;
    --danger-bg: #1e1212;
    --danger-line: #4a1a1a;
    --info: #60a5fa;
    --info-bg: #10203a;
    --info-line: #1e3a5f;
    --success: #4ade80;
    --success-bg: #1a2e1a;
    --success-line: #1f4a1f;
}

/*
 * Каретка в полях ввода.
 *
 * На iOS её рисует не движок, а UIKit: цвет берётся из tintColor приложения-хозяина,
 * и CSS `color` на него не влияет вовсе. Telegram задаёт тинт один раз при создании
 * окна из своей темы — в тёмной это чистый белый, — и наружу его не отдаёт: в SDK
 * мини-приложений есть цвет шапки, фона и нижней панели, тинта среди них нет. Значит
 * подстроиться под него нельзя, можно только перебить, и перебивает его единственная
 * вещь — явный `caret-color`. Он же красит подсветку выделения внутри полей: её iOS
 * тоже рисует тинтом, а не `::selection`.
 *
 * Цвет записан числом, а не токеном, и с `!important` — по тем же причинам, что и в
 * `::selection` ниже: значение из переменной WebKit в этом свойстве не принимает, а
 * поверх страницы лежат стили самого мессенджера.
 *
 * Правило статическое: смена `caret-color` у поля, уже получившего фокус, на iOS не
 * срабатывает, поэтому цвет темы задаётся заранее, а не при фокусе.
 */
input,
textarea,
select,
[contenteditable] {
    caret-color: #16161a !important;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) input,
    :root:not([data-theme="light"]) textarea,
    :root:not([data-theme="light"]) select,
    :root:not([data-theme="light"]) [contenteditable] {
        caret-color: #f4f4f7 !important;
    }
}

:root[data-theme="dark"] input,
:root[data-theme="dark"] textarea,
:root[data-theme="dark"] select,
:root[data-theme="dark"] [contenteditable] {
    caret-color: #f4f4f7 !important;
}

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    -webkit-tap-highlight-color: transparent;
}

/* Alpine снимает атрибут, когда просыпается: без этого правила блоки с x-show
   успевают моргнуть до инициализации. */
[x-cloak] {
    display: none !important;
}

body {
    min-height: 100vh;
    overflow-x: hidden;
    background: var(--bg);
    color: var(--text);
    font: 14px/1.5 -apple-system, BlinkMacSystemFont, 'Segoe UI', Manrope, sans-serif;
}

input,
textarea,
button,
select {
    font-family: inherit;
    outline: none;
}

/* Вкладки сверху и липкие: в прототипе они же и на том же месте. */
.tabs {
    position: sticky;
    top: 0;
    z-index: 50;
    display: flex;
    padding-top: var(--safe-top);
    background: var(--surface);
    border-bottom: 1px solid var(--line);
}

.tabs__item {
    display: flex;
    /* Значок и подпись в строку и по центру: раньше их держал пробел между эмодзи и
       словом, и на переносе строки подпись уезжала под значок. */
    align-items: center;
    justify-content: center;
    gap: 6px;
    flex: 1;
    padding: 14px 4px;
    border-bottom: 2px solid transparent;
    color: var(--text-dim);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-align: center;
    text-decoration: none;
    text-transform: uppercase;
    transition: 0.15s;
}

.tabs__item--active {
    border-bottom-color: var(--accent-text);
    color: var(--accent-text);
}

.screen {
    padding: 14px 16px calc(30px + var(--safe-bottom));
}

/* Экран без вкладок — вход: отступ сверху держать больше некому. */
body:not(:has(.tabs)) .screen {
    padding-top: calc(14px + var(--safe-top));
}

.screen__title {
    margin-bottom: 14px;
    font-size: 17px;
    font-weight: 800;
    letter-spacing: -0.02em;
}

.card {
    margin-bottom: 10px;
    padding: 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
}

.card__title {
    margin-bottom: 4px;
    font-size: 15px;
    font-weight: 800;
}

/* Подпись над значением: заглавные, мелкие, приглушённые — как в прототипе. */
.label {
    display: block;
    margin-bottom: 6px;
    color: var(--text-muted);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.muted {
    color: var(--text-muted);
    font-size: 13px;
}

.stack > * + * {
    margin-top: 8px;
}

.button {
    display: flex;
    gap: 8px;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 16px;
    border: 0;
    border-radius: var(--radius);
    background: linear-gradient(135deg, #ffc831, #ffb000);
    box-shadow: 0 6px 20px rgba(255, 184, 0, 0.25);
    /* Надпись на золотом всегда тёмная: сама кнопка в обеих темах одинаковая. */
    color: #16161a;
    font-size: 15px;
    font-weight: 800;
    /* Кнопкой бывает и ссылка: подчёркивание от неё здесь ни к чему. */
    text-decoration: none;
    cursor: pointer;
}

.button:active {
    transform: scale(0.98);
}

/*
 * Кнопка над списком: заказы размещают редко, а список листают каждый день. Стоя в
 * начале списка, она отодвигала бы заявки вниз на каждом открытии.
 *
 * Ширина по надписи, а не во весь экран: под ней живой список, и перекрывать его
 * полосой во всю ширину незачем.
 */
.button--floating {
    position: fixed;
    right: 16px;
    bottom: calc(16px + var(--safe-bottom));
    z-index: 40;
    width: auto;
    padding: 14px 20px;
    border-radius: 999px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}

/* Место под кнопкой: последняя заявка не должна прятаться за ней. */
.orders {
    padding-bottom: 76px;
}

.button:disabled {
    opacity: 0.6;
}

.button--quiet {
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    box-shadow: none;
    color: var(--text);
    font-size: 13px;
    font-weight: 700;
}

.button--quiet:active {
    background: var(--line);
}

.badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 9px;
    border: 1px solid var(--accent-line);
    border-radius: 999px;
    background: var(--accent-bg);
    color: var(--accent-text);
    font-size: 10px;
    font-weight: 700;
}

.avatar {
    position: relative;
    display: flex;
    overflow: hidden;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 58px;
    height: 58px;
    border: 2px solid var(--accent-line);
    border-radius: 16px;
    background: var(--accent-bg);
    color: var(--accent-text);
    font-size: 22px;
    font-weight: 800;
}

.row {
    display: flex;
    gap: 12px;
    align-items: center;
}

/*
 * Сообщение над экраном стоит в общем ряду карточек, поэтому и отступ под ним такой
 * же: без него сверху было четырнадцать точек, снизу ноль, и сообщение липло к первой
 * карточке.
 */
/* Отметка «сохранено»: зелёная галочка у самого значения, уходит сама. */
.saved {
    display: inline-flex;
    color: var(--success);
}

.note--screen {
    margin-bottom: 10px;
}

.note {
    padding: 9px 12px;
    border: 1px solid var(--accent-line);
    border-radius: 10px;
    background: var(--accent-bg);
    color: var(--accent-dim);
    font-size: 11px;
    line-height: 1.5;
}

/*
 * Кошелёк. Баланс — самое крупное число на экране: за ним человек сюда и заходит.
 * Суммы операций моноширинные, чтобы столбик читался как столбик, а не как разнобой.
 */
.wallet__balance {
    font-size: 2rem;
    font-weight: 600;
    color: var(--accent);
}

.wallet__amount {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.row--between {
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
}

/*
 * Заголовок раздела внутри экрана: те же кегль и начертание, что у заголовка экрана.
 * Разные размеры читались как разная важность, хотя «Мои заказы» и «Заявки» — одно и
 * то же место в своей вкладке.
 *
 * Первый заголовок стоит там же, где заголовок экрана: на вкладке «Работать» своего
 * заголовка нет, и без этого правила её первая строка начиналась ниже соседних вкладок.
 */
.screen__subtitle {
    margin: 20px 0 14px;
    font-size: 17px;
    font-weight: 800;
    letter-spacing: -0.02em;
}

.screen__subtitle:first-of-type {
    margin-top: 0;
}

/*
 * Форма заказа. Поля крупные и в один столбец: кабинет открывается в мессенджере на
 * телефоне, и всё, во что нужно попасть пальцем, начинается от 44 точек.
 */
.field + .field {
    margin-top: 14px;
}

/* Шрифт полей не меньше 16 пикселей, и это не про читаемость: Safari на iPhone
   приближает страницу, когда человек становится в поле с более мелким шрифтом, и
   обратно уже не отдаляет — форма заказа после первого касания оставалась увеличенной
   и уезжала за край экрана. */
.input {
    width: 100%;
    padding: 13px 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--bg);
    color: var(--text);
    font-size: 16px;
}

.input:focus {
    border-color: var(--accent-line);
}

/*
 * Поле даты на iOS.
 *
 * Две беды сразу, и обе от того, что поле рисует система, а не движок.
 *
 * Ширина: у поля своя внутренняя — под «дд.мм.гггг» с системными частями, — и она
 * сильнее `width: 100%`, край уезжал за карточку. Снимаем родной вид и разрешаем полю
 * сжиматься.
 *
 * Цвет: сами части даты — день, месяц, год и точки между ними — красятся системным
 * цветом, тем же тинтом мессенджера, что и каретка. В тёмном Telegram он белый, и в
 * светлом кабинете пустое поле выглядело просто пустым: «дд.мм.гггг» было написано
 * белым по белому. Поэтому цвет каждой части задаём сами — числом и с `!important`,
 * по тем же причинам, что и у каретки.
 */
.input[type="date"] {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    min-width: 0;
    max-width: 100%;
}

.input[type="date"]::-webkit-date-and-time-value,
.input[type="date"]::-webkit-datetime-edit,
.input[type="date"]::-webkit-datetime-edit-text,
.input[type="date"]::-webkit-datetime-edit-day-field,
.input[type="date"]::-webkit-datetime-edit-month-field,
.input[type="date"]::-webkit-datetime-edit-year-field {
    color: #16161a !important;
    /* Части выравниваем по левому краю: без родного вида поле растягивает их на всю
       ширину, и дата уезжала в середину. */
    text-align: left;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .input[type="date"]::-webkit-date-and-time-value,
    :root:not([data-theme="light"]) .input[type="date"]::-webkit-datetime-edit,
    :root:not([data-theme="light"]) .input[type="date"]::-webkit-datetime-edit-text,
    :root:not([data-theme="light"]) .input[type="date"]::-webkit-datetime-edit-day-field,
    :root:not([data-theme="light"]) .input[type="date"]::-webkit-datetime-edit-month-field,
    :root:not([data-theme="light"]) .input[type="date"]::-webkit-datetime-edit-year-field {
        color: #f4f4f7 !important;
    }
}

:root[data-theme="dark"] .input[type="date"]::-webkit-date-and-time-value,
:root[data-theme="dark"] .input[type="date"]::-webkit-datetime-edit,
:root[data-theme="dark"] .input[type="date"]::-webkit-datetime-edit-text,
:root[data-theme="dark"] .input[type="date"]::-webkit-datetime-edit-day-field,
:root[data-theme="dark"] .input[type="date"]::-webkit-datetime-edit-month-field,
:root[data-theme="dark"] .input[type="date"]::-webkit-datetime-edit-year-field {
    color: #f4f4f7 !important;
}

/* Списки даты рождения стоят в строку и делят её поровну. */
select.input {
    min-width: 0;
    flex: 1 1 0;
}

.input--multiline {
    resize: none;
    line-height: 1.5;
}

/* Ошибку поля видно по рамке, а не только по подписи под ним: на длинной форме
   подпись уезжает за край экрана, рамка — нет. */
.field--invalid .input {
    border-color: var(--danger-line);
}

.input__suffix {
    flex: 0 0 auto;
    color: var(--accent-dim);
    font-size: 13px;
    font-weight: 700;
}

.row--tight {
    gap: 8px;
}

/* Выбор одного из нескольких: тип найма, способ оплаты, способ назначения цены. */
.segmented {
    display: flex;
    gap: 4px;
    padding: 4px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface-sunken);
}

.segmented__item {
    flex: 1;
    padding: 10px 8px;
    border: 0;
    border-radius: 9px;
    background: transparent;
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
}

.segmented__item--active {
    background: var(--accent-bg);
    color: var(--accent-text);
}

/* Людей выбирают штуками, а не печатают: счётчик проще и не даёт ввести ерунду. */
.stepper {
    display: flex;
    gap: 12px;
    align-items: center;
    justify-content: space-between;
    padding: 6px 10px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--bg);
}

.stepper__button {
    width: 38px;
    height: 38px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--surface);
    color: var(--text);
    font-size: 18px;
    font-weight: 800;
    cursor: pointer;
}

.stepper__value {
    font-size: 17px;
    font-weight: 800;
}

/* Подсказка городов: справочник чужой, и выбирать в нём надо из списка, а не наугад. */
.options {
    margin-top: 6px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--bg);
    overflow: hidden;
}

.options__item {
    display: block;
    width: 100%;
    padding: 12px 14px;
    border: 0;
    background: transparent;
    color: var(--text);
    font-size: 14px;
    text-align: left;
    cursor: pointer;
}

.options__item + .options__item {
    border-top: 1px solid var(--line);
}

.options__item:active {
    background: var(--surface);
}

.options__empty {
    padding: 12px 14px;
}

/*
 * Сообщения об итоге. Отказ и удача отличаются цветом, а не только словами: человек
 * читает цвет раньше текста.
 */
/* Ошибка поля: строка под ним. Коробку с рамкой поле уже собой и рисует. */
.field__error {
    color: var(--danger);
    font-size: 12px;
    line-height: 1.4;
}

.note--error {
    border-color: var(--danger-line);
    background: var(--danger-bg);
    color: var(--danger);
}

.note--success {
    border-color: var(--success-line);
    background: var(--success-bg);
    color: var(--success);
}

.badge--action {
    border-color: var(--danger-line);
    background: var(--danger-bg);
    color: var(--danger);
}

/* Значок в кружке мельче обычного: он подпись, а не кнопка. */
.badge .icon {
    width: 12px;
    height: 12px;
}

.badge--live {
    border-color: var(--info-line);
    background: var(--info-bg);
    color: var(--info);
}

.badge--cancelled {
    border-color: var(--line);
    background: var(--surface-sunken);
    color: var(--text-dim);
}

.badge--broken {
    border-color: var(--danger-line);
    background: var(--danger-bg);
    color: var(--danger);
}

.badge--done {
    border-color: var(--success-line);
    background: var(--success-bg);
    color: var(--success);
}

.badge--muted {
    border-color: var(--line);
    background: var(--surface-sunken);
    color: var(--text-dim);
}

/* Телефон второй стороны: ссылка-звонок, а не украшение — по ней и звонят. */
.contact {
    color: var(--accent-text);
    font-weight: 700;
    text-decoration: none;
}

.card--link {
    display: block;
    color: inherit;
    text-decoration: none;
}

.back {
    display: inline-block;
    margin-bottom: 12px;
    color: var(--text-muted);
    font-size: 13px;
    text-decoration: none;
}

.order__description {
    white-space: pre-line;
}

.response + .response {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--line);
}

/*
 * Дата и время: наше поле видно, родное лежит поверх прозрачным. Касание попадает в
 * родное и открывает привычный выбор даты, а показываем мы своё — родное рисует
 * значение по языку системы, и на английской локали получается 08/29/2026 и 12:30 PM.
 */
.moment {
    position: relative;
}

.moment__native {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    padding: 13px 14px;
    border: 0;
    /* Тот же размер, что и у видимых полей: приближает Safari и родное поле тоже. */
    font-size: 16px;
    background: transparent;
    /* Прозрачный текст, а не opacity и не display:none: скрытое поле не открывает
       выбор даты, а прозрачность целиком забрала бы с собой и значок календаря. */
    color: transparent;
    cursor: pointer;
}

.moment__native::-webkit-datetime-edit {
    color: transparent;
}

.moment__native::-webkit-calendar-picker-indicator {
    cursor: pointer;
}

/* Набранные города: видно, что выбрано, и можно убрать не открывая поиск заново. */
.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.chip {
    padding: 7px 11px;
    border: 1px solid var(--accent-line);
    border-radius: 999px;
    background: var(--accent-bg);
    color: var(--accent-text);
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
}

.options__item--chosen {
    background: var(--accent-bg);
    color: var(--accent-text);
    font-weight: 700;
}

/* Фотография из мессенджера на месте буквы имени: приходит не всегда, поэтому буква
   остаётся разметкой, а картинка её заменяет. */
.avatar img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/*
 * Балл лицом и цветом.
 *
 * «4,6» и «3,2» на глаз почти одинаковы, а означают разное: берут охотно или берут с
 * оглядкой. Лицо и цвет говорят это до чтения числа, само число остаётся рядом —
 * лицо без числа было бы оценкой без оснований.
 */
.score {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border: 1px solid;
    border-radius: 999px;
    font-size: 14px;
    font-weight: 700;
}

.score__count {
    font-size: 12px;
    font-weight: 400;
}

.score--great {
    border-color: var(--success-line);
    background: var(--success-bg);
    color: var(--success);
}

.score--good {
    border-color: var(--accent-line);
    background: var(--accent-bg);
    color: var(--accent-text);
}

.score--poor {
    border-color: var(--danger-line);
    background: var(--danger-bg);
    color: var(--danger);
}

/* Чего ждёт заявка: строка, ради которой список и открывают. */
.order__waiting {
    color: var(--accent-text);
    font-weight: 700;
}

/*
 * Полоса шагов: кружок с чертой вниз, справа название и время.
 *
 * Пройденное золотом, текущее золотом и жирнее, будущее серым, несостоявшееся —
 * красным: разницу между «уже было» и «ещё будет» человек должен видеть, не читая.
 */
.stages {
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0;
    list-style: none;
}

.stages__step {
    position: relative;
    display: flex;
    gap: 10px;
    min-height: 38px;
}

.stages__step:last-child {
    min-height: auto;
}

/*
 * Линию ведём по самому шагу, а не от кружка: высота шага разная — у события это имя,
 * название и время, у ступени одна строка, — и линия заданной высоты не дотягивалась
 * до следующего кружка. Растянутая от края до края она подходит к любому шагу.
 */
.stages__step:not(:last-child)::before {
    position: absolute;
    top: 20px;
    bottom: -4px;
    left: 5px;
    width: 2px;
    background: var(--line);
    content: '';
}

/* Кружок шага. */
.stages__mark {
    position: relative;
    flex: 0 0 auto;
    width: 12px;
    height: 12px;
    margin-top: 4px;
    border: 2px solid var(--line);
    border-radius: 50%;
    background: var(--bg);
}

.stages__title {
    color: var(--text-muted);
}

.stages__step--done .stages__mark {
    border-color: var(--accent-line);
    background: var(--accent);
}

.stages__step--done .stages__title {
    color: var(--text);
}

.stages__step--now .stages__mark {
    border-color: var(--accent);
    background: var(--accent-bg);
}

.stages__step--now .stages__title {
    color: var(--accent-text);
    font-weight: 700;
}

.stages__step--failed .stages__mark {
    border-color: var(--danger-line);
    background: var(--danger-bg);
}

.stages__step--failed .stages__title {
    color: var(--danger);
}

/* Мелкое действие рядом с показанным: скопировать, открыть в картах. */
.action {
    padding: 4px 10px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface-sunken);
    color: var(--text-muted);
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
}

.action:active {
    border-color: var(--accent-line);
    color: var(--accent-text);
}

/* Строка действий под тем, к чему они относятся. */
.actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/*
 * Скелет на месте содержимого, пока оно едет.
 *
 * Появляется не сразу: быстрый ответ приходит раньше, и мелькнувший скелет читался бы
 * как сбой. Задержка в четверть секунды — примерно та граница, за которой человек
 * начинает думать, что нажатие не услышали.
 */
/*
 * Оттягивание сверху: полоска растёт под пальцем, в ней крутится колесо.
 *
 * Высотой управляет скрипт, здесь — только вид и то, как она возвращается на место:
 * во время жеста высота меняется без перехода, иначе полоска отстаёт от пальца, а на
 * отпускании переход включается — так возврат выглядит движением, а не рывком.
 */
.refresh {
    height: 0;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: height 0.2s ease;
}

.refresh__wheel {
    width: 18px;
    height: 18px;
    border: 2px solid var(--line);
    border-top-color: var(--accent);
    border-radius: 50%;
}

.refresh--working .refresh__wheel {
    animation: search-spins 0.8s linear infinite;
}

.skeleton {
    display: none;
    flex-direction: column;
    gap: 10px;
}

.screen.htmx-request .skeleton {
    display: flex;
    animation: skeleton-appears 0.2s ease-out 0.25s both;
}

.screen.htmx-request #screen-content {
    display: none;
}

@keyframes skeleton-appears {
    from { opacity: 0; }
    to { opacity: 1; }
}

.skeleton__line,
.skeleton__card {
    border-radius: var(--radius-sm);
    background: linear-gradient(90deg, var(--surface) 25%, var(--surface-sunken) 37%, var(--surface) 63%);
    background-size: 400% 100%;
    animation: skeleton-runs 1.4s ease-in-out infinite;
}

.skeleton__line {
    height: 14px;
}

.skeleton__line--title {
    width: 45%;
    height: 20px;
}

.skeleton__card {
    height: 110px;
    border-radius: var(--radius);
}

@keyframes skeleton-runs {
    from { background-position: 100% 50%; }
    to { background-position: 0 50%; }
}

/*
 * Выделение текста пальцем.
 *
 * Своего запрета у нас нет, но вебвью Telegram на iPhone гасит выделение и меню по
 * долгому нажатию: так мини-приложение ведёт себя «как родное», и длинное нажатие
 * остаётся жестом самого мессенджера. Человеку от этого хуже — код заказа, адрес и
 * телефон он переносит в другие приложения.
 *
 * Возвращаем выделение там, где есть что переносить, и оставляем запрет на том, что
 * нажимают: подсветившаяся кнопка выглядит сломанной. Кнопки копирования рядом
 * остаются: где выделение всё же не вернуть, работают они.
 */
#screen-content,
#screen-content p,
#screen-content span,
#screen-content time,
#screen-content a {
    -webkit-user-select: text;
    user-select: text;
    -webkit-touch-callout: default;
}

.button,
.action,
.segmented__item,
.stepper__button,
.chip,
.tabs__item,
.badge {
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

/*
 * Выделение видно в обеих темах.
 *
 * Системная подсветка светло-голубая и на нашем светлом фоне почти не читается:
 * человек ведёт палец и не понимает, что уже выделил. Берём тот же акцент, что и
 * везде, — на нём текст остаётся тёмным и в светлой теме, и в тёмной.
 *
 * Правило работает только вне полей ввода: внутри `input` и `textarea` на iOS
 * подсветку рисует UIKit тинтом приложения, и там за неё отвечает `caret-color`.
 */
::selection {
    /*
     * Цвет записан числом, а не токеном: WebKit не разрешает переменные внутри
     * `::selection` — правило с `var()` он пропускает целиком. Он же принимает только
     * `background-color`, но не сокращённое `background`.
     *
     * `!important` не для веса среди своих правил: у мини-приложения поверх страницы
     * лежат стили самого мессенджера, и без него выделение остаётся системным —
     * светло-голубым, на нашем светлом фоне невидимым.
     *
     * Цвет насыщенный намеренно: WebKit подмешивает к заданному белый, и бледный
     * оттенок после этого не виден вовсе.
     */
    background-color: #ffc107 !important;
    color: #16161a !important;
}

/*
 * Кнопка-значок рядом со значением: скопировать, открыть в картах.
 *
 * Стоит вплотную к тому, к чему относится, поэтому без подписи: «Скопировать код
 * заказа» рядом с самим кодом заняло бы больше места, чем код. Что она делает, знают
 * `aria-label` и долгое нажатие.
 */
/*
 * Код заказа и кнопка копирования — одно целое: кнопка относится к коду, а не к
 * строке. Без этого узкая колонка рядом с широким кружком статуса переносила её на
 * следующую строку, и она повисала под кодом сама по себе.
 */
.unbreakable {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    white-space: nowrap;
}

.action--icon {
    display: inline-flex;
    padding: 4px;
    margin-left: 6px;
    vertical-align: middle;
}

.icon {
    width: 15px;
    height: 15px;
}

/* Подвес, который тянет следующую страницу: на его месте едет скелет карточки. */
.more {
    display: block;
    margin-bottom: 10px;
}

/*
 * Поиск с колечком.
 *
 * Список городов приходит с сервера, а сеть в мессенджере бывает любой: без ответа на
 * ввод набранные три буквы выглядят как «ничего не нашлось», хотя подсказка ещё в
 * пути.
 */
.search {
    position: relative;
}

.search__clear {
    position: absolute;
    top: 50%;
    right: 8px;
    display: flex;
    padding: 4px;
    margin-top: -12px;
    border: 0;
    background: none;
    color: var(--text-dim);
    cursor: pointer;
}

/* Пустое поле стирать нечем: у поля с подсказкой это видно самому браузеру. */
.search input:placeholder-shown ~ .search__clear {
    display: none;
}

/* Пока подсказка едет, на этом месте крутится колечко. */
.search.htmx-request .search__clear {
    display: none;
}

.search__spinner {
    position: absolute;
    top: 50%;
    right: 12px;
    width: 16px;
    height: 16px;
    margin-top: -8px;
    border: 2px solid var(--line);
    border-top-color: var(--accent);
    border-radius: 50%;
    opacity: 0;
    transition: opacity 0.15s;
}

.search.htmx-request .search__spinner {
    opacity: 1;
    animation: search-spins 0.7s linear infinite;
}

@keyframes search-spins {
    to { transform: rotate(360deg); }
}

/*
 * Ожидание сети видно на самой кнопке.
 *
 * Сеть в мессенджере бывает любой, а нажатие без ответа читается как несработавшее:
 * человек жмёт второй раз, и заказ уходит дважды. HTMX сам вешает `htmx-request` на
 * того, кто ждёт ответа, — на кнопку или на форму, если отправляли её. Значит одно
 * правило закрывает все кнопки кабинета разом, а не расставляется руками у каждой.
 *
 * Кружок рисуем на месте самой кнопки, а не рядом: подпись остаётся, но гаснет, и
 * ширина кнопки не прыгает.
 */
.button.htmx-request,
.button--sending,
.action.htmx-request {
    position: relative;
    color: transparent;
    pointer-events: none;
}

.button.htmx-request::after,
.button--sending::after,
.action.htmx-request::after {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 18px;
    height: 18px;
    margin: -9px 0 0 -9px;
    border: 2px solid rgba(0, 0, 0, 0.2);
    /* Цвет подписи кнопки, а не текста страницы: на золотой кнопке текст тёмный. */
    border-top-color: var(--accent-text);
    border-radius: 50%;
    content: "";
    animation: search-spins 0.7s linear infinite;
}

/* Тихая кнопка и значок стоят на фоне карточки: там кружок берёт обычный цвет текста. */
.button--quiet.htmx-request::after,
.action.htmx-request::after {
    border-color: var(--line);
    border-top-color: var(--text-muted);
}

/* Города работы строкой над лентой: они объясняют её состав, а не настраиваются каждый день. */
.cities {
    margin-bottom: 10px;
}

.cities__chosen {
    color: var(--text-muted);
    font-size: 13px;
}
