/* SUMMY · Кабинет мастера — дизайн-токены из концепта */
:root {
  --bg: #ffffff;             /* белый фон */
  --card: #f4f5f1;           /* «окошки» — слегка серый */
  --plum: #50603a;           /* акцент — болотный/оливковый (имя legacy) */
  --plum-dark: #404d2e;
  --plum-deep: #323d24;
  --ink: #23271f;
  --muted: #5c6155;
  --line: #e8eae3;
  --chip-bg: #eceee3;
  --pill-bg: #eef0e8;
  --ok-bg: #e6efe0;
  --ok-text: #46662e;
  --warn-bg: #f4eeda;
  --warn-text: #87692a;
  --gold: #c79a34;
  --radius: 20px;
  --radius-lg: 24px;
  --radius-sm: 14px;
  --radius-xs: 12px;
  /* Единая шкала теней — оливковый ink-тон (раньше тени были магентовыми, legacy #4a1b36) */
  --shadow-ink: 50 61 36;
  --shadow-1: 0 1px 2px rgb(var(--shadow-ink) / .06);
  --shadow-2: 0 6px 18px -6px rgb(var(--shadow-ink) / .16);
  --shadow-3: 0 16px 34px -14px rgb(var(--shadow-ink) / .34);
  --font-display: Georgia, 'Times New Roman', serif;
  --font-body: 'Segoe UI', system-ui, -apple-system, sans-serif;
  /* Нижний плавающий док: высота стеклянного навбара + отступ от края экрана.
     Одним токеном пользуются и позиционирование ленты дней, и запас снизу под
     контентом (иначе пришлось бы дублировать магические числа). */
  --tabbar-h: 62px;
  --tabbar-gap: 14px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* Всегда резервируем место под вертикальный скроллбар — иначе при переходе между
   страницами с/без скролла вьюпорт меняет ширину и центрированный контент + фиксированный
   навбар «уезжают» вбок. */
html { scrollbar-gutter: stable; overflow-y: scroll; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.4;
}

.app {
  max-width: 560px;
  margin: 0 auto;
  padding: 20px 16px 104px;
}

/* ── Шапка мастера ─────────────────────────────── */
.master-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 18px;
}

.avatar-link { display: contents; }
.avatar-link .avatar { cursor: pointer; }
.avatar {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: var(--plum-deep);
  color: #f5e9df;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  object-fit: cover;
}

/* Имя приходит уже сокращённым — «Имя Ф.» (User.short_name), и на 320–560px
   помещается целиком. Многоточие оставлено страховкой на случай очень длинного
   имени: обрезать хвост лучше, чем ломать строку шапки. */
.master-name {
  font-family: var(--font-body);
  font-size: 18px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.master-meta {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 6px;
  margin-top: 4px;
}
/* Бейджи услуг в шапке — чуть компактнее */
.master-meta .badge { padding: 4px 10px; font-size: 12px; }

.rating { font-size: 14px; }

/* Шапка: рейтинг → категория-звёзды → кольцо уровня в один ряд.
   Рейтинг и категория жмутся к имени, кольцо — к правому краю. */
.master-head-info { flex: 1; min-width: 0; }
.head-stat { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; flex-shrink: 0; }
.head-stat-val {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 20px;                 /* общая высота строки-значения для рейтинга и звёзд */
  font-weight: 800;
  font-size: 16.5px;
  line-height: 1;
  letter-spacing: -0.2px;
  color: var(--ink);
}
.head-star { width: 14px; height: 14px; }
/* Индикатор перехода к грейду: стопка шевронов (N засвечены) или галочка */
.head-promo {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  background: var(--chip-bg);
  border-radius: 12px;
  padding: 4px 6px;
}
.head-promo--chev { flex-direction: column; gap: 1.5px; }
.head-promo--chev .chev { width: 14px; height: 7px; color: #b9bdb0; }   /* невыполненные — серые */
.head-promo--up .chev.is-on { color: #5b8f3f; }    /* зелёный — движение вверх */
.head-promo--down .chev.is-on { color: #c0504e; }  /* красный — вниз */
.head-promo--ok svg { width: 18px; height: 18px; color: var(--ok-text); }
.head-stat-lbl { color: var(--muted); font-size: 12px; line-height: 1; white-space: nowrap; }
/* Рейтинг на фоне — чип со скруглением */
.head-chip {
  background: var(--chip-bg);
  border-radius: 14px;
  padding: 5px 9px;
}
.head-stat--link { text-decoration: none; color: inherit; cursor: pointer; transition: transform .16s cubic-bezier(.16,1,.3,1); }
@media (hover: hover) { .head-stat--link:hover { transform: scale(1.04); } }
.head-stat--link:active { transform: scale(.96); }

/* Категория-звёзды = уровень мастера (без слов), та же высота строки, что у рейтинга */
.head-cat-stars {
  display: inline-flex;
  align-items: center;
  height: 20px;
  font-size: 15px;
  line-height: 1;
  letter-spacing: 1px;
  color: var(--line);
  white-space: nowrap;
}
.head-cat-stars .is-on { color: var(--gold); }

/* Категория = схема оплаты: единый блок, уезжает вправо */
.head-pay {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 9px;
  flex-shrink: 0;
}

/* Узкие экраны (обычные телефоны, 340–430px): шапка ОДНОЙ строкой — правый
   блок ужимается, а не переносится. Прежний перенос на вторую строку выглядел
   «съехавшим» (слово владельца 22.07): блок повисал справа под пустотой.
   Бейджи услуг при нехватке места переносятся внутри СВОЕЙ колонки под именем. */
@media (max-width: 430px) {
  .master-header { gap: 8px; }
  .master-meta { flex-wrap: wrap; }
  .head-pay { gap: 6px; }
  .head-stat { gap: 4px; }
  .head-stat-val { font-size: 15px; height: 18px; }
  .head-cat-stars { font-size: 13px; height: 18px; letter-spacing: .6px; }
  .head-star { width: 12px; height: 12px; }
  .head-chip { padding: 4px 8px; border-radius: 12px; }
  .head-stat-lbl { font-size: 11px; }
  .head-promo { padding: 3px 5px; }
  .head-promo--chev .chev { width: 12px; height: 6px; }
}

/* Совсем узкие экраны (старые SE и мельче): одной строкой уже не уместиться —
   переносим, но осознанно: блок растянут по всей ширине через space-between,
   а не свален к правому краю. */
@media (max-width: 339px) {
  .master-header { flex-wrap: wrap; column-gap: 12px; row-gap: 10px; }
  .master-head-info { flex: 1 1 auto; }
  .head-pay { flex-basis: 100%; margin-left: 0; justify-content: space-between; }
}

/* ── Отзывы клиентов ─────────────────────────────── */
.reviews-summary { display: flex; align-items: center; gap: 16px; }
.reviews-avg {
  font-size: 40px;
  font-weight: 800;
  letter-spacing: -1px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.reviews-stars { color: var(--gold); font-size: 17px; letter-spacing: 1px; }
.reviews-stars .is-on { color: var(--gold); }
.reviews-count { color: var(--muted); font-size: 13px; margin-top: 3px; }

.review-item { display: flex; flex-direction: column; gap: 6px; }
.review-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.review-name { font-weight: 700; }
.review-stars { font-size: 13px; letter-spacing: 1px; color: var(--line); white-space: nowrap; }
.review-stars .is-on { color: var(--gold); }
.review-text { font-size: 14px; line-height: 1.45; }
.review-date { color: var(--muted); font-size: 12.5px; }

/* Кнопка «Выйти из профиля» (на экране Профиль) */
.profile-logout { margin-top: 18px; }
.btn-logout {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: var(--card);
  color: var(--muted);
  border: 1.5px solid var(--line);
  border-radius: 14px;
  padding: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: transform 160ms cubic-bezier(0.23, 1, 0.32, 1);
}
.btn-logout svg { width: 18px; height: 18px; }
.btn-logout:active { transform: scale(0.97); }
@media (prefers-reduced-motion: reduce) {
  .btn-logout { transition: none; }
  .btn-logout:active { transform: none; }
}

/* ── Карточки ──────────────────────────────────── */
.card {
  background: var(--card);
  border-radius: var(--radius);
  padding: 18px;
  margin-bottom: 12px;
  box-shadow: var(--shadow-1);
}

/* ── Смена ─────────────────────────────────────── */
.shift-flow-card { padding: 18px; }
.shift-flow-card h2 {
  margin: 0;
  font-size: 17px;
  letter-spacing: 0;
}
.shift-flow-action { width: 100%; }
.shift-flow-action:disabled {
  opacity: .45;
  cursor: default;
}
.shift-flow-status {
  min-height: 42px;
  margin: 12px 0;
  color: var(--muted);
  font-size: 14px;
  text-align: center;
}
.shift-problem-link {
  display: block;
  width: 100%;
  margin-bottom: 24px;
}
.qr-scanner {
  position: relative;
  width: min(100%, 360px);
  aspect-ratio: 4 / 5;
  margin: 0 auto;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: #20231f;
}
.qr-scanner video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.qr-frame {
  position: absolute;
  inset: 50% auto auto 50%;
  width: min(68%, 240px);
  aspect-ratio: 1;
  border: 2px solid #fff;
  border-radius: 8px;
  transform: translate(-50%, -50%);
}
/* Полноэкранный сканер открытия смены: камера на весь экран, управление поверх. */
.shift-scan-full {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: #000;
}
.shift-scan-full video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.shift-scan-close {
  position: absolute;
  top: calc(14px + env(safe-area-inset-top, 0px));
  right: 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
}
.shift-scan-close svg { width: 20px; height: 20px; }
.shift-scan-bottom {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 16px 20px calc(20px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.55) 40%);
}
.shift-scan-bottom .shift-flow-status {
  margin: 0;
  color: #fff;
  text-align: center;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}
.shift-scan-bottom .form-error {
  width: 100%;
  text-align: center;
}
.shift-scan-problem {
  color: rgba(255, 255, 255, 0.85);
  font-size: 14px;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.shift-flow-step {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 14px;
}
.shift-step-number,
.shift-photo-title > span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  border-radius: 50%;
  background: var(--chip-bg);
  color: var(--plum);
  font-size: 13px;
  font-weight: 700;
}
.shift-checklist-form {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.shift-check-item {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
}
.shift-check-item input {
  width: 21px;
  height: 21px;
  flex: 0 0 21px;
  accent-color: var(--plum);
}
.shift-checklist-form .shift-flow-action { margin-top: 14px; }
.shift-checklist-summary {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.shift-checklist-summary li {
  display: flex;
  align-items: center;
  gap: 9px;
  color: var(--muted);
  font-size: 14px;
}
.shift-checklist-summary span {
  color: var(--plum);
  font-weight: 700;
}
.shift-photo-list {
  display: flex;
  flex-direction: column;
}
.shift-photo-item {
  min-width: 0;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}
.shift-photo-item:last-child { border-bottom: 0; }
.shift-photo-title {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  font-size: 14px;
  font-weight: 600;
}
.shift-photo-item.is-uploaded {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.shift-photo-state {
  color: var(--plum);
  font-size: 12px;
  font-weight: 600;
}
.shift-photo-form { margin-top: 10px; }
.shift-finish-form { margin-top: 14px; }

/* ── Живая камера (снимок в приложении, без галереи) ── */
.shift-camera { display: flex; flex-direction: column; gap: 10px; }
.shift-camera-view {
  width: 100%;
  max-height: 260px;
  border-radius: 12px;
  background: var(--line);
  object-fit: cover;
}
.shift-camera-error { margin: 0; }
.shift-camera-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.shift-camera-controls .btn { padding: 10px 16px; }

@media (max-width: 390px) {
  .shift-camera-controls .btn { flex: 1 1 auto; }
}

/* ── Смена открыта: окно подтверждения с «ОК» ──── */

/* Нативный <dialog>: закрытый он display:none по умолчанию — тапы по плашкам
   под собой не перехватывает. Поэтому display здесь НЕ задаём (иначе окно после
   «ОК» осталось бы невидимой подложкой — так 21.07 ломался переход в «Тариф»).
   Раскладку строк держит внутренний .shift-open-confirm. */
.shift-open-dialog {
  width: min(340px, calc(100vw - 40px));
  /* Центровку модалке даёт `margin: auto` браузера, но её сбивает общий сброс
     `* { margin: 0 }` в начале файла — возвращаем явно, иначе окно прилипает
     к левому верхнему углу. */
  margin: auto;
  border: 0;
  border-radius: var(--radius-lg);
  padding: 0;
  color: var(--ink);
  background: #fff;
  box-shadow: 0 24px 80px rgb(28 34 25 / .28);
}
.shift-open-dialog::backdrop { background: rgb(22 27 20 / .55); }

/* Страница подтверждения открывается сразу после чёрного экрана сканера —
   фон держим тёмным в тон, чтобы переход читался непрерывно, без белой
   вспышки (слово владельца 22.07). */
body:has(.shift-open-dialog) { background: #10130e; }

/* Автофокус showModal принимает контейнер, а не кнопка «ОК»: синего
   браузерного кольца на кнопке нет (слово владельца 22.07). Клавиатуре
   оставляем фирменную обводку по Tab. */
.shift-open-confirm:focus { outline: none; }
.shift-open-confirm-actions .btn:focus { outline: none; }
.shift-open-confirm-actions .btn:focus-visible { outline: 2px solid var(--plum); outline-offset: 2px; }

.shift-open-confirm {
  display: grid;
  justify-items: center;
  gap: 4px;
  padding: 26px 22px 22px;
  text-align: center;
}
.shift-open-confirm-ic {
  width: 52px;
  height: 52px;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--ok-bg);
  color: var(--ok-text);
}
.shift-open-confirm-ic svg { width: 26px; height: 26px; }
.shift-open-confirm-lead { font-size: 14px; color: var(--muted); }
/* Название места приходит дословно из справочника — длинное («Маникюрный стол
   №1») переносим, а не режем. */
.shift-open-confirm-place {
  font-size: 21px;
  font-weight: 700;
  line-height: 1.25;
  overflow-wrap: anywhere;
}
.shift-open-confirm-state { font-size: 15px; color: var(--muted); line-height: 1.4; }
/* «ОК» и «Отмена» одной колонкой во всю ширину окна — попасть мимо на телефоне
   сложнее, чем по паре кнопок в ряд. */
.shift-open-confirm-actions {
  display: grid;
  gap: 8px;
  width: 100%;
  margin-top: 18px;
}

@media (prefers-reduced-motion: no-preference) {
  /* Мягче, чем было (.24s и только подъём): затемнение проявляется, окно
     всплывает с лёгким масштабом — переход со сканера не «щёлкает»
     (слово владельца 22.07). */
  .shift-open-dialog[open] { animation: shift-open-rise .32s cubic-bezier(.16, 1, .3, 1); }
  .shift-open-dialog[open]::backdrop { animation: shift-open-fade .32s ease-out; }
  @keyframes shift-open-rise {
    from { transform: translateY(16px) scale(.97); opacity: 0; }
  }
  @keyframes shift-open-fade {
    from { opacity: 0; }
  }
}

/* ── Кнопки ────────────────────────────────────── */
.btn {
  font-family: var(--font-body);
  font-size: 14.5px;
  font-weight: 600;
  border: none;
  border-radius: 16px;
  padding: 12px 20px;
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
  text-align: center;
}

.btn-primary {
  background: var(--plum);
  color: #fff;
  padding: 16px 24px;
}
.btn-primary:hover { background: var(--plum-dark); }

.btn-danger {
  background: #8a3434;
  color: #fff;
}
.btn-danger:hover { background: #702929; }

.btn-outline {
  background: none;
  border: 1.5px solid var(--plum);
  color: var(--plum);
  padding: 14px 22px;
}
.btn-outline:hover { background: var(--chip-bg); }

.btn-pill {
  background: var(--pill-bg);
  color: var(--ink);
  border-radius: 999px;
  padding: 10px 18px;
  font-size: 13.5px;
}
.btn-pill:hover:not(:disabled) { background: #e2d8cf; }
.btn-pill:disabled {
  color: var(--muted);
  cursor: default;
}

.btn-light {
  background: #fff;
  color: var(--ink);
  border-radius: 14px;
  font-size: 14px;
  box-shadow: 0 1px 2px rgb(34 39 31 / .12);
  transition: transform 160ms cubic-bezier(0.23, 1, 0.32, 1), box-shadow 160ms ease;
}
.btn-light:active:not(:disabled) { transform: scale(0.97); }
.btn-light:disabled { opacity: 0.6; cursor: default; box-shadow: none; }

.btn-wide { width: 100%; }

/* ── Заголовки секций ──────────────────────────── */
.section-head {
  color: var(--ink);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.2px;
  text-transform: none;
  margin: 24px 4px 11px;
}

.section-head-split {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

/* Статус грейда (слот): доступен новый / риск понижения / стабильно */
.grade-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  text-transform: none;
  letter-spacing: 0;
  font-size: 11.5px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 999px;
}
.grade-status svg { width: 13px; height: 13px; }
.grade-status--stable { background: var(--pill-bg); color: var(--muted); }
.grade-status--up { background: var(--ok-bg); color: var(--ok-text); }
.grade-status--down { background: #f4dddd; color: #8b3434; }
/* Шевроны-«ёлочки» стопкой: кол-во = насколько движется грейд */
.grade-status--arrows { flex-direction: column; gap: 1px; padding: 4px 12px; }
.grade-status--arrows svg { width: 16px; height: 8px; }

.messages {
  display: grid;
  gap: 8px;
  margin: 0 0 14px;
}

.message {
  border-radius: 14px;
  padding: 12px 14px;
  font-size: 13.5px;
  font-weight: 600;
}

.message-success {
  background: var(--ok-bg);
  color: var(--ok-text);
}

.message-error {
  background: #f4dddd;
  color: #8b3434;
}

.add-link {
  color: var(--plum);
  font-weight: 700;
  text-decoration: none;
  text-transform: none;
  font-size: 14px;
  letter-spacing: 0;
}

/* ── Бейджи и чипы ─────────────────────────────── */
.badge {
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
}

.badge-grade { background: var(--chip-bg); color: var(--ink); }
.badge-ok { background: var(--ok-bg); color: var(--ok-text); }
.badge-warn { background: var(--warn-bg); color: var(--warn-text); }
.badge-muted { background: var(--pill-bg); color: var(--muted); }

/* ── Прогресс-бар показателей (Финансы) ───────────── */
.metric-card {
  display: flex;
  flex-direction: column;
  padding: 14px 16px;            /* компактнее дефолтных 18px */
  /* акценты по состоянию (дефолт — бренд) */
  --metric-fill: var(--plum);
  --metric-track: var(--pill-bg);
  --metric-accent: var(--muted);
  transition: transform .18s cubic-bezier(.16, 1, .3, 1), box-shadow .2s ease;
}
/* Цвета баров по позиции — 3 оттенка, производные оливковой палитры --plum:
   первые 2 бара зелёные (c1), последние 2 — охра (c2) и бронза (c3). */
.metric--c1 { --metric-fill: #7A9456; --metric-accent: #4f6a33; }   /* зелёный — Повторные/Активность */
.metric--c2 { --metric-fill: #F7E7B4; --metric-accent: #9a7b2e; }   /* бледно-жёлтый — Лояльность */
.metric--c3 { --metric-fill: #D0E1F4; --metric-accent: #4674a3; }   /* бледно-голубой — Командный бонус */

/* Наведение — лёгкое увеличение с подъёмом тени (как у вкладок навбара) */
@media (hover: hover) {
  .metric-card:hover { transform: scale(1.02); box-shadow: var(--shadow-2); }
}
.metric-card:active { transform: scale(.99); }

.metric-head { display: flex; align-items: baseline; gap: 8px; }
.metric-title { font-weight: 600; color: var(--ink); }
.metric-pct {
  font-size: 13px;
  font-weight: 600;
  color: var(--metric-accent);
  font-variant-numeric: tabular-nums;
}
.metric-value {
  margin-left: auto;
  font-weight: 700;
  font-size: 17px;
  color: var(--ink);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.metric-goal { color: var(--muted); font-weight: 500; font-size: 13.5px; }
.metric-card .progress { margin-top: 11px; }

.speed-progress {
  width: 100%;
  height: 12px;
  margin-top: 11px;
  border: 0;
  border-radius: 999px;
  overflow: hidden;
  appearance: none;
  background: var(--metric-track);
}
.speed-progress::-webkit-progress-bar { background: var(--metric-track); }
.speed-progress::-webkit-progress-value { background: var(--metric-fill); border-radius: 999px; }
.speed-progress::-moz-progress-bar { background: var(--metric-fill); border-radius: 999px; }
.speed-details {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 4px 12px;
  margin-top: 7px;
  color: var(--muted);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}

/* Круговые метрики (Активность / Повторные) — две рядом */
.metric-rings { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 12px; }
.ring-metric {
  position: relative;   /* якорь для галочки «норма взята» (.ring-check) */
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  padding: 20px 10px 18px;
  text-decoration: none;
  color: inherit;
  min-width: 0;   /* позволяем grid-колонке 1fr сжимать карточку (иначе SVG распирает её до 184px+) */
}
/* Кольцо подстраивается под ширину карточки, но не больше 184px (как в референсе).
   aspect-ratio держит круг, viewBox 36×36 масштабируется без потерь. */
.ring.ring-metric-circle { width: 100%; max-width: 184px; height: auto; aspect-ratio: 1; }
.ring-metric .ring-track {
  stroke: #e6ebdd;                                            /* фолбэк — бледный оттенок */
  stroke: color-mix(in srgb, var(--metric-fill) 16%, #fff);  /* бледная производная цвета дуги */
  stroke-width: 2.1;
}
.ring-metric .ring-fill {
  stroke: var(--metric-fill);
  stroke-width: 2.1;
  stroke-linecap: round;
  filter: drop-shadow(0 1px 2px color-mix(in srgb, var(--metric-fill) 45%, transparent));
  animation: ring-grow 1.1s cubic-bezier(.16, 1, .3, 1) both;
}
.metric-rings .ring-metric:nth-child(2) .ring-fill { animation-delay: .12s; }
@keyframes ring-grow { from { stroke-dasharray: 0, 100; } }
@media (prefers-reduced-motion: reduce) { .ring-metric .ring-fill { animation: none; } }
/* Главный акцент — процент, под ним часы из нормы. Пара стоит ровно по центру
   кольца, поэтому у «Активности» и «Повторных клиентов» цифры на одной высоте. */
.ring-metric .ring-num { flex-direction: column; gap: 4px; }
.ring-metric .ring-pct { font-size: clamp(19px, 5.6vw, 24px); font-weight: 800; letter-spacing: -0.4px; color: var(--ink); line-height: 1; }
.ring-metric .ring-pct small { font-size: 0.6em; font-weight: 700; opacity: 0.7; margin-left: 1px; }
.ring-metric-sub { font-size: clamp(11.5px, 3.3vw, 13px); font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; line-height: 1; }
.ring-metric-title { font-weight: 700; font-size: 16px; }
.ring-metric--link { transition: transform .16s cubic-bezier(.16,1,.3,1); }
@media (hover: hover) { .ring-metric--link:hover { transform: scale(1.02); } }
.ring-metric--link:active { transform: scale(.98); }
/* Подпись под заголовком раздела: лид истории и «показатели ещё считаются». */
.returning-lead,
.metrics-pending { color: var(--muted); font-size: 13.5px; margin: 0 4px 12px; line-height: 1.4; }

/* Примечание показателя.
   На тач (по умолчанию) — видно всегда, чтобы инфо не терялась.
   На устройствах с мышью — скрыто, раскрывается по наведению (компактнее). */
.metric-note { color: var(--muted); font-size: 12.5px; margin-top: 8px; line-height: 1.35; }
@media (hover: hover) {
  .metric-note {
    margin-top: 0;
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    transition:
      grid-template-rows .28s cubic-bezier(.16, 1, .3, 1),
      opacity .2s ease,
      margin-top .28s ease;
  }
  .metric-note > span { overflow: hidden; }
  .metric-card:hover .metric-note { grid-template-rows: 1fr; opacity: 1; margin-top: 8px; }
  .speed-card .metric-note { display: block; opacity: 1; margin-top: 8px; }
}

/* «Гарантированный минимум»: тускло, пока не набрана норма часов; загорается
   (акцент + зелёный фон) при достижении 180ч+ по всем филиалам. */
.guarantee-card { opacity: .62; transition: opacity .2s ease, border-color .2s ease, background .2s ease; }
.guarantee-card.is-on { opacity: 1; border: 1.5px solid var(--plum); background: var(--ok-bg); }
.guarantee-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.guarantee-title { font-weight: 600; }
.guarantee-card.is-on .guarantee-title { color: var(--plum-deep); }
.guarantee-amount { margin-left: auto; font-weight: 700; white-space: nowrap; }
.guarantee-note { color: var(--muted); font-size: 12.5px; margin-top: 8px; line-height: 1.35; }
.guarantee-card.is-on .guarantee-note { color: var(--plum-deep); }
.guarantee-mark { font-weight: 800; font-size: 15px; line-height: 1; }
.guarantee-mark.is-done { color: var(--ok-text); }
.guarantee-mark.is-miss { color: #8b3434; }

.progress {
  position: relative;
  height: 12px;
  border-radius: 999px;
  background: var(--metric-track);
}
/* Декоративные точки-чекпоинты вдоль бара (чтобы не выглядел скучно) */
.progress::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background-image: radial-gradient(circle, rgb(35 39 31 / .16) 1.7px, transparent 2px);
  background-size: 25% 100%;
  background-position: center;
}
.progress-fill {
  position: relative;
  height: 100%;
  border-radius: 999px;
  background: var(--metric-fill);
  width: var(--target, 0%);
  /* разовая анимация при первом показе экрана — сильная ease-out + стаггер */
  animation: progress-grow 820ms cubic-bezier(0.23, 1, 0.32, 1) var(--fill-delay, 0ms) both;
}
/* «бегунок» на ведущем крае заливки */
.progress-fill::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 0;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--metric-fill);
  transform: translate(50%, -50%);
  box-shadow: 0 0 0 3px var(--card), 0 1px 3px rgb(34 39 31 / .22);
}
@keyframes progress-grow {
  from { width: 0%; }
  to   { width: var(--target, 0%); }
}
@media (prefers-reduced-motion: reduce) {
  .progress-fill { animation: none; }
}

/* ── Календарь расписания (заполненность дня) ─────── */
.cal-month-block { margin-bottom: 24px; scroll-margin-top: 14px; }
.cal-month {
  font-size: 20px;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 14px;
  text-transform: capitalize;
}
.cal {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 12px;
}
.cal-weekdays, .cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.cal-weekdays { margin-bottom: 8px; }
.cal-weekdays span { text-align: center; font-size: 11px; color: var(--muted); }
.cal-grid { row-gap: 8px; }
.cal-blank { aspect-ratio: 1 / 1; }
.cal-day {
  /* Бледно-серый «свободного времени»: им в кольце закрашен незанятый остаток.
     Вынесен в токен, потому что этим же цветом на заливке выбранного дня
     рисуются дуга заполненности и цифра — это должен быть буквально тот же
     цвет, а не второй такой же хекс. Живёт на .cal-day: его берут и .cal-ring,
     и .cal-num-bare (соседи, не вложены друг в друга). */
  --free: #e3e5dd;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  color: inherit;
  text-decoration: none !important;
  outline: none;
  cursor: pointer;
}
.cal-day:hover { background: rgba(80, 96, 58, .08); }
.cal-day:focus-visible { box-shadow: 0 0 0 3px rgba(80, 96, 58, .22); }
.cal-ring {
  --pct: 0;
  --track: var(--free);
  --c: var(--track);
  width: min(40px, 100%);
  height: auto;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: conic-gradient(var(--c) calc(var(--pct) * 1%), var(--track) 0);
}
.cal-ring .cal-num {
  width: 80%;
  height: auto;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: var(--card);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--ink);
}
.cal-num-bare {
  width: min(40px, 100%);
  height: auto;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: var(--muted);
}
.tier-low { --c: #3fae5a; }   /* зелёный — мало записей */
.tier-mid { --c: #e8a72e; }   /* жёлтый — наполовину */
.tier-high { --c: #d6453b; }  /* красный — заполнен */
.tier-empty { --c: var(--track); }  /* смена открыта, записей нет */
/* Сегодня — только акцент на цифре, круг не трогаем. */
.cal-day.is-today .cal-num,
.cal-day.is-today .cal-num-bare { color: var(--plum); font-weight: 700; }

.cal-day.is-past { opacity: .5; }

/* Выбранный день — ИНВЕРСИЯ кольца (слово владельца 22.07): у соседних дней
   обычные кольца заполненности, а у выбранного круг залит, и всё, что было
   цветным, становится белым. До этого (0.42.5) выбранный день получал то же
   кольцо, только ярче, — владелец попросил реверсивный вариант по цвету.
   Диаметр и сетка не меняются: заливка занимает ровно место кольца (40px).
   Блок идёт последним: перекрывает is-past/is-today. */
.cal-day.is-selected { opacity: 1; }
/* Прошедший выбранный день не приглушаем: при opacity .5 заливка выцветает в
   фон и цифра перестаёт читаться. У .is-past та же специфичность, поэтому
   нужен явный парный селектор. */
.cal-day.is-past.is-selected { opacity: 1; }
/* Заливка — ОДИН нейтральный цвет, фирменный оливковый, одинаковый для любого
   тира (слово владельца 22.07). Цветом тира выбранный день больше не красится,
   зато заполненность видно: кусочек прогресса, который на невыбранном дне
   рисуется цветом тира (--c), на заливке становится бледно-серым — тем самым
   --free, которым в обычном кольце показано свободное время (слово владельца
   22.07: «не белым, а бледно серым»). Контраст один на все случаи: бледно-серое
   по оливковому — 5.4:1 и для дуги, и для цифры. */
.cal-day.is-selected .cal-ring { --track: var(--plum); --c: var(--free); }
.cal-day.is-selected .cal-ring .cal-num { background: var(--plum); }
/* День без графика: прогресса нет, остаётся та же оливковая заливка. */
.cal-day.is-selected .cal-num-bare {
  border-radius: 50%;
  background: var(--plum);
}
.cal-day.is-selected .cal-num,
.cal-day.is-selected .cal-num-bare { color: var(--free); font-weight: 700; }

/* ── Пометки филиалов на экране дня (мастер в 2+ филиалах) ────────
   Цвет точки — слот филиала (порядок стабилен по названию), не тир заполненности.
   В календаре «Расписания» пометок нет (слово владельца 21.07). */
.branch-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--muted);
}
.branch-dot.slot-0 { background: var(--plum); }
.branch-dot.slot-1 { background: var(--gold); }
.branch-dot.slot-2 { background: #7f8ba0; }
.branch-dot.slot-3 { background: #a06a50; }
.day-branch-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.day-branch-note {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 10px;
  font-size: 12.5px;
  color: var(--muted);
}
.badge-new { background: var(--warn-bg); color: var(--warn-text); }

.chip {
  background: var(--chip-bg);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 12.5px;
  font-weight: 600;
}

/* ── Лента дней — второй плавающий ряд над навбаром ──────────
   Светлая «стеклянная» пилюля над стеклянным навбаром: две строки плавающего
   меню (как в YClients). Ширина/центровка — как у .tabbar; материал чуть
   теплее навбара, чтобы ряды не сливались (тёмный вариант владелец снял
   16.07.2026 как «тяжёлый»). */
.day-dock {
  position: fixed;
  left: 50%;
  bottom: calc(var(--tabbar-gap) + env(safe-area-inset-bottom) + var(--tabbar-h) + 16px);
  transform: translateX(-50%);
  width: calc(100% - 28px);
  max-width: 532px;
  z-index: 39;                       /* под навбаром (40): центральная «+» перекрывает край дока */
  padding: 6px;
  border-radius: 22px;
  border: 1px solid rgb(35 39 31 / .08);
  background:
    linear-gradient(135deg, rgb(255 255 255 / .86), rgb(245 246 241 / .78)),
    rgb(245 246 241 / .72);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / .65),
    0 12px 34px rgb(34 39 31 / .16);
}

/* min-width:0 — чтобы лента сжималась и включался overflow-x. */
.day-strip-wrap { position: relative; min-width: 0; }

.day-strip {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scroll-padding-inline: 6px;
  padding: 2px 6px;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;            /* скрыть скроллбар (Firefox) */
}
.day-strip::-webkit-scrollbar { display: none; }  /* … и в WebKit/Blink */

/* Запас справа, чтобы последние дни не прятались под кнопкой «Сегодня». */
.day-strip-wrap.has-jump .day-strip { padding-right: 88px; }

.day-chip {
  flex: 0 0 auto;
  scroll-snap-align: center;
  display: grid;
  justify-items: center;
  gap: 2px;
  min-width: 44px;
  padding: 6px 8px 5px;
  border-radius: 14px;
  background: rgb(35 39 31 / .045);
  border: 1px solid transparent;
  color: var(--ink);
  line-height: 1;
  text-decoration: none !important;
}
.day-chip:focus-visible { outline: 3px solid rgb(80 96 58 / .45); outline-offset: 1px; }

/* Буквы дней — чёрные и одинаковые у всех, включая сб/вс (слово владельца 21.07). */
.day-chip-dow { font-size: 11px; font-weight: 600; color: var(--ink); }
.day-chip-num { font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; }
.day-chip-dot { width: 5px; height: 5px; margin-top: 1px; border-radius: 50%; background: transparent; }
.day-chip-dot.is-on { background: var(--ink); }  /* чёрная точка рабочего дня (слово владельца 20.07); на выбранной тёмной пилюле остаётся белой */


/* Дни без установленного расписания — приглушены (слово владельца 21.07). */
.day-chip.is-off { opacity: .45; }

/* Прошедшие дни приглушаем, но оставляем кликабельными. */
.day-chip.is-past { opacity: .45; }

/* Сегодня (когда открыт другой день) — оливковый контур-подсказка. */
.day-chip.is-today { border-color: rgb(80 96 58 / .45); }

/* Выбранный день — тёмная «пилюля» (инверсия на светлом доке, как выбранный
   день в календаре «Расписания»). Идёт последним: перекрывает is-past/is-today. */
.day-chip.is-selected {
  opacity: 1;
  background: var(--plum);
  border-color: var(--plum);
  box-shadow: 0 4px 12px -4px rgb(50 61 36 / .55);
}
.day-chip.is-selected .day-chip-dow { color: rgb(255 255 255 / .72); }
.day-chip.is-selected .day-chip-num { color: #fff; }
.day-chip.is-selected .day-chip-dot.is-on { background: #fff; }


/* ── Лента месяцев («Расписание») ────────────────────────────
   Тот же док и та же лента, что и дни на «Сегодня» (.day-dock/.day-strip):
   чип несёт классы .day-chip, а .month-chip только расширяет его под название
   месяца с годом под ним (референс владельца — полоса месяцев в YClients). */
.month-chip { min-width: 56px; padding: 6px 10px; }
.month-chip-name { font-size: 15px; font-weight: 700; }
.month-chip-year {
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* Текущий месяц (когда открыт другой) — оливковый контур, как «сегодня» в ленте дней. */
.month-chip.is-current { border-color: rgb(80 96 58 / .45); }

/* Выбранный месяц — тёмная пилюля от .day-chip.is-selected; здесь только текст
   и контур поверх is-current/is-past. */
.month-chip.is-selected { border-color: var(--plum); }
.month-chip.is-selected .month-chip-name { color: #fff; }
.month-chip.is-selected .month-chip-year { color: rgb(255 255 255 / .72); }


.day-timeline { display: grid; gap: 14px; }

.day-timeline-section {
  /* Высота одной 15-мин строки фиксирована — высота записи пропорциональна её
     длительности (30-мин запись ровно вдвое ниже часовой). */
  --timeline-row-h: 30px;
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr);
  grid-template-rows: repeat(var(--timeline-rows), var(--timeline-row-h)) 1px;
  position: relative;
  min-width: 0;
}

.timeline-time {
  grid-column: 1;
  grid-row: var(--timeline-row);
  align-self: start;
  padding-right: 8px;
  color: var(--muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  text-align: right;
}

.timeline-time.is-end { align-self: end; }

.timeline-line {
  grid-column: 2;
  grid-row: var(--timeline-row);
  align-self: start;
  border-top: 1px solid var(--line);
  pointer-events: none;
}

.timeline-appointment {
  grid-column: 2;
  grid-row: var(--timeline-row) / span var(--timeline-span);
  z-index: 1;
  align-self: stretch;
  margin: 1px 0;
  padding: 6px 12px;
  /* Короткая запись занимает мало строк — лишний контент прячем, а не тянем
     карточку. Приоритет — верхняя строка (время и имя клиента). */
  overflow: hidden;
  align-items: stretch;
  gap: 6px;
}
/* Компактная верхняя строка — влезает даже в 15-мин запись; нижняя строка
   (услуга и деньги) обрезается overflow:hidden выше на короткой карточке. */
.timeline-appointment .appt-head { font-size: 14.5px; gap: 6px; }
.timeline-appointment .appt-head .chip { padding: 1px 7px; font-size: 11px; }
.timeline-appointment .appt-name { font-size: 13px; }
.timeline-appointment .appt-price { font-size: 13.5px; }
.timeline-appointment .appt-open-chevron { width: 14px; height: 14px; }
.timeline-appointment .appt-body { gap: 8px; }
/* Компактная кнопка/бейдж — помещается в короткую карточку. */
.timeline-appointment .appt-action .btn-pill,
.timeline-appointment .appt-action .badge {
  padding: 6px 12px;
  font-size: 12.5px;
}

.appointment {
  display: flex;
  flex-direction: column;
  gap: 6px;
  position: relative;
  transition: transform 0.16s ease, box-shadow 0.16s ease, background-color 0.16s ease;
}

.appointment:has(.appointment-link:hover),
.appointment:has(.appointment-link:focus-visible) {
  background: #fffaf5;
  box-shadow: 0 8px 22px rgba(74, 27, 54, 0.12);
  transform: translateY(-1px);
}

/* Верхняя строка карточки: время · длительность · статус, имя клиента (растёт на
   остаток строки, прижато вправо, обрезается многоточием) и кружок клиента. */
.appt-head {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 17px;
}
.appt-head > strong,
.appt-head > .chip,
.appt-head > .appt-status { flex-shrink: 0; }
.appt-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: right;
  font-size: 15px;
  font-weight: 600;
}
/* Имя-кнопка (у записи с привязанным клиентом) открывает шторку клиента, как и
   кружок. Внешне — то же имя (.appt-name задаёт размер/вес/обрезку), поэтому тут
   только сброс кнопки, подъём над подложкой-ссылкой (z-index — чтобы тап по имени
   вёл в шторку, а не в запись) и цвет наведения. У записи без клиента имя
   остаётся ссылкой .appointment-link в запись. */
.appt-name-btn {
  position: relative;
  z-index: 1;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  line-height: inherit;
  color: inherit;
  cursor: pointer;
}
.appt-name-btn:hover { color: var(--plum); }
.appt-name-btn:focus-visible {
  outline: 2px solid var(--plum);
  outline-offset: 2px;
  border-radius: 6px;
}

/* Нижняя строка: услуга (слева) и деньги/состояние закрытия (справа). Цена
   выровнена по ПЕРВОЙ строке услуги (align-items: flex-start): у двухстрочного
   названия цена держится верха и не уезжает в середину (слово владельца 23.07). */
.appt-body {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.appt-main { min-width: 0; flex: 1; }

.appointment-link {
  color: inherit;
  text-decoration: none;
  border-radius: 14px;
  cursor: pointer;
  outline: none;
  padding: 2px 0;
}

/* Ссылка висит на имени клиента, но растянута на всю карточку (.appointment —
   position: relative): тапается любое место, а кружок клиента и кнопка закрытия
   поднимаются над ней (z-index) и перехватывают свой тап. Вложить их в <a> нельзя. */
.appointment-link::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 16px;
}

.appointment-link:hover {
  color: var(--plum);
}

.appointment-link:focus-visible {
  box-shadow: 0 0 0 3px rgba(122, 46, 88, 0.18);
}

/* Состояние записи в YClients — тонкая контурная иконка у времени. Цвета только
   из существующих семантических: пришёл — «ок», подтверждена — акцент,
   ожидание — приглушённый, не пришёл — тот же красный, что у btn-danger. */
.appt-status {
  display: inline-flex;
  align-items: center;
  color: var(--muted);
}
.appt-status svg { width: 18px; height: 18px; }
.appt-status--came { color: var(--ok-text); }
.appt-status--confirmed { color: var(--plum); }
.appt-status--no-show { color: #8a3434; }

/* Строка времени экранов «Подробности» и «Закрытие» (на карточке дня — .appt-head). */
.appt-time {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 17px;
}

.appt-client {
  font-weight: 700;
  margin-top: 6px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.visit-categories {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 7px;
}

.appt-client .visit-categories { margin-top: 0; }

.visit-category {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 26px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--chip-bg);
  color: var(--muted);
  font-size: 12px;
  line-height: 1.2;
  white-space: nowrap;
}

.visit-category strong { color: var(--plum-deep); font-size: 13px; }
.visit-categories-pending {
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
}

.appt-services {
  color: var(--muted);
  font-size: 13.5px;
  margin-top: 2px;
}

/* Правая часть нижней строки: деньги и состояние закрытия. Кнопка/бейдж подняты
   над растянутой ссылкой-именем (z-index), поэтому «Закрыть запись» ловит свой
   тап, а не уводит на подробности. */
.appt-action {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
}
.appt-action .btn,
.appt-action .badge { position: relative; z-index: 1; }
.appt-price { font-weight: 700; white-space: nowrap; }
/* Цена и шеврон «открыть запись» в одну строку. Шеврон — видимый намёк, что вся
   карточка ведёт в запись (как плашки Финансов), и заменяет прежнее слово
   «Просмотр». Намеренно НЕ поднят над подложкой (нет z-index): тап по нему, как и
   по цене, уходит в запись через растянутую .appointment-link. */
.appt-open {
  display: flex;
  align-items: center;
  gap: 6px;
}
.appt-open-chevron {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--muted);
}

.appointment-detail {
  display: grid;
  gap: 14px;
  position: relative;
  padding-right: 54px;
}

.detail-close-link {
  white-space: nowrap;
}

.detail-close-button {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--pill-bg);
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  line-height: 1;
  text-decoration: none;
}

.detail-close-button:hover {
  background: #e2d8cf;
}

.detail-list {
  display: grid;
  gap: 10px;
}

.detail-list div {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  border-top: 1px solid var(--line);
  padding-top: 10px;
}

.detail-list span,
.detail-comment span {
  color: var(--muted);
  font-size: 12.5px;
  font-weight: 700;
}

.detail-list strong {
  text-align: right;
  font-size: 14px;
}

.detail-comment {
  border-top: 1px solid var(--line);
  padding-top: 10px;
}

.detail-comment div {
  margin-top: 4px;
}

.detail-actions {
  margin-top: 0;
}

.closure-details {
  padding: 0;
  overflow: hidden;
}

.closure-details summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 18px;
  cursor: pointer;
  list-style: none;
}

.closure-details summary::-webkit-details-marker {
  display: none;
}

.closure-details summary:hover {
  background: #fffaf5;
}

.closure-details .notes-title {
  display: block;
  margin-bottom: 3px;
}

.closure-summary {
  color: var(--muted);
  font-size: 13.5px;
  font-weight: 600;
}

.closure-toggle {
  color: var(--plum);
  font-size: 13px;
  font-weight: 800;
  white-space: nowrap;
}

.closure-details[open] .closure-toggle {
  font-size: 0;
}

.closure-details[open] .closure-toggle::after {
  content: "Свернуть";
  font-size: 13px;
}

.closure-detail-list {
  padding: 0 18px 18px;
}

.notes-title {
  font-weight: 800;
  margin-bottom: 12px;
}

.notes-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.client-note {
  border-top: 1px solid var(--line);
  padding-top: 12px;
  margin-top: 12px;
}

.client-note:first-of-type {
  border-top: 0;
  padding-top: 0;
  margin-top: 0;
}

.note-meta {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  color: var(--muted);
  font-size: 12.5px;
  font-weight: 700;
  margin-bottom: 6px;
}

.note-text {
  white-space: normal;
}

.hint-center {
  text-align: center;
  color: var(--muted);
  font-size: 13.5px;
  margin-top: 18px;
}

/* ── Рабочие дни ───────────────────────────────── */
.work-schedule-page { padding-top: 10px; }
.work-schedule-page a { text-decoration: none !important; }

.schedule-title {
  margin-top: 26px;
  margin-bottom: 16px;
}

.calendar-weekdays {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 6px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 800;
  text-align: center;
}

.work-days-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 8px;
}

.work-day-placeholder {
  min-height: 86px;
}

.work-day {
  min-height: 86px;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: #fff;
  color: var(--ink);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  cursor: pointer;
  font-family: inherit;
  box-shadow: 0 1px 2px rgba(74, 27, 54, 0.04);
}

.work-day-weekday,
.work-day-month {
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
}

.work-day strong {
  font-size: 22px;
  line-height: 1;
}

.work-day-slots {
  display: flex;
  flex-direction: row;
  justify-content: center;
  flex-wrap: wrap;
  align-items: center;
  gap: 3px;
  min-height: 18px;
  max-width: 34px;
  margin-top: 2px;
}

.work-day-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: #2f7d58;
}

.slot-data { display: none; }

.work-day.selected {
  background: #2f7d58;
  border-color: #2f7d58;
  color: #fff;
  box-shadow: 0 10px 22px rgba(47, 125, 88, 0.22);
}

.work-day.past {
  background: #eee9e3;
  border-color: #e1d8ce;
  color: #aaa0a5;
  cursor: default;
  box-shadow: none;
}

.work-day.past .work-day-weekday,
.work-day.past .work-day-month {
  color: #b8afb4;
}

.work-day.past .work-day-dot {
  background: #b8afb4;
}

.work-day.past.selected {
  background: #e5ded6;
  border-color: #d8cec4;
  color: #9f969b;
}

.work-day.active {
  outline: 3px solid rgba(122, 46, 88, 0.22);
  outline-offset: 2px;
}

.work-day.selected .work-day-weekday,
.work-day.selected .work-day-month {
  color: rgba(255, 255, 255, 0.78);
}

.work-day.selected .work-day-dot {
  background: rgba(255, 255, 255, 0.92);
}

.schedule-editor {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 16px;
  margin-top: 16px;
  box-shadow: 0 1px 3px rgba(74, 27, 54, 0.05);
}

.schedule-editor-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.schedule-editor-head strong {
  display: block;
  margin-top: 2px;
  font-size: 18px;
}

.schedule-add-slot {
  border: none;
  border-radius: 12px;
  background: var(--chip-bg);
  color: var(--plum-dark);
  font-weight: 800;
  padding: 11px 12px;
  cursor: pointer;
  white-space: nowrap;
}

.schedule-slot-list {
  display: grid;
  gap: 10px;
}

.schedule-slot-row {
  display: grid;
  grid-template-columns: 1fr 1fr 40px;
  gap: 8px;
  align-items: end;
}

.schedule-slot-row label {
  display: grid;
  gap: 4px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
}

.schedule-slot-row select {
  width: 100%;
  min-height: 42px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #fbf8f4;
  color: var(--ink);
  font: inherit;
  font-weight: 700;
  padding: 0 10px;
}

.slot-remove {
  width: 40px;
  height: 42px;
  border: none;
  border-radius: 12px;
  background: #f7e6e6;
  color: #9a3c3c;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}

.schedule-empty {
  min-height: 42px;
  border: 1px dashed var(--line);
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-weight: 700;
}

.schedule-hint {
  color: var(--muted);
  font-size: 15px;
  margin: 18px 4px 24px;
}

.schedule-actions {
  display: grid;
  gap: 12px;
}

.schedule-save {
  background: #2f7d58;
  border-radius: 16px;
  box-shadow: 0 8px 18px rgba(47, 125, 88, 0.22);
}

.schedule-save:hover { background: #286c4c; }

.schedule-back {
  color: #2f7d58;
  background: #eaf4ef;
  padding: 16px 24px;
  font-weight: 800;
}

/* ── Строчные карточки (профиль, операции) ─────── */
.row-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.row-title { font-weight: 700; }
.row-sub {
  color: var(--muted);
  font-size: 13.5px;
  margin-top: 3px;
}

.profile-link-card {
  color: var(--ink);
  text-decoration: none;
}
.profile-link-arrow {
  color: var(--muted);
  font-size: 30px;
  line-height: 1;
}

/* ── Чёрный список клиентов ───────────────────── */
.blacklist-action,
.blacklist-state {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.blacklist-intro {
  color: var(--muted);
  font-size: 14px;
  line-height: 1.5;
  margin: -2px 4px 16px;
}

.blacklist-list {
  display: grid;
  gap: 12px;
}

.blacklist-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
}

.blacklist-card-main { min-width: 0; }
.blacklist-reason {
  color: var(--ink);
  font-size: 14px;
  font-weight: 650;
  margin-top: 12px;
}
.blacklist-comment {
  color: var(--muted);
  font-size: 13.5px;
  line-height: 1.45;
  margin-top: 5px;
  overflow-wrap: anywhere;
}

.block-dialog {
  width: min(520px, calc(100vw - 28px));
  max-height: calc(100vh - 28px);
  border: 0;
  border-radius: 24px;
  padding: 0;
  color: var(--ink);
  box-shadow: 0 24px 80px rgb(28 34 25 / .28);
}
.block-dialog::backdrop { background: rgb(22 27 20 / .55); }
.block-dialog-form { padding: 22px; }
.block-dialog-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}
.block-dialog-head p {
  color: var(--muted);
  font-size: 14px;
  line-height: 1.45;
  margin: 7px 0 0;
}
.dialog-close {
  width: 36px;
  height: 36px;
  flex: 0 0 36px;
  border: 0;
  border-radius: 50%;
  background: var(--pill-bg);
  color: var(--ink);
  font-size: 25px;
  line-height: 1;
  cursor: pointer;
}
.block-reasons {
  border: 0;
  padding: 0;
  margin: 20px 0 16px;
}
.block-reasons legend {
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 6px;
}
.block-reasons > div > div { border-bottom: 1px solid var(--line); }
.block-reasons > div > div:last-child { border-bottom: 0; }
.block-reasons label {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 2px;
  font-size: 14px;
  line-height: 1.35;
  cursor: pointer;
}
.block-reasons input[type="radio"] {
  width: 19px;
  height: 19px;
  flex: 0 0 19px;
  margin: 0;
  accent-color: var(--plum);
}
.block-comment[hidden] { display: none; }
.block-dialog-actions { margin-top: 18px; }

@media (max-width: 520px) {
  .blacklist-action,
  .blacklist-state,
  .blacklist-card {
    align-items: stretch;
    flex-direction: column;
  }
  .blacklist-action .btn,
  .blacklist-state .btn,
  .blacklist-card .btn { width: 100%; }
  .block-dialog-actions { display: grid; }
}

.empty-card {
  color: var(--muted);
  text-align: center;
}

/* Единая заглушка «Скоро: …» (_coming_soon.html) — блок без реального источника данных. */
.coming-soon { display: flex; flex-direction: column; gap: 4px; }
.coming-soon-what { font-weight: 600; }
.coming-soon-note { font-size: 13.5px; }

/* Пустой день с кнопкой «Открыть график»: текст и действие в столбик. */
.empty-day {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.master-profile-card {
  display: flex;
  gap: 14px;
  align-items: flex-start;
}

.master-photo {
  width: 96px;
  height: 112px;
  border-radius: 16px;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--plum-deep);
  color: #f5e9df;
}

.master-photo-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  font-weight: 800;
}

.master-profile-info {
  min-width: 0;
}

/* ── Портфолио ─────────────────────────────────── */
.portfolio-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.work {
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  aspect-ratio: 9 / 10;
}

.work img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.work figcaption {
  position: absolute;
  inset: auto 0 0 0;
  background: rgba(40, 25, 35, 0.65);
  color: #fff;
  font-size: 12px;
  padding: 6px 8px;
}

.add-form .field { margin-bottom: 12px; }
.form-actions { display: flex; gap: 10px; }

/* Выбор грейда мастером (в профиле) */
.grade-card-now { padding-bottom: 14px; margin-bottom: 14px; border-bottom: 1px solid var(--line); }
.grade-form .field { margin-bottom: 12px; }
.grade-form .btn-primary { width: 100%; }

/* ── Финансы ───────────────────────────────────── */
.balance-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  background: linear-gradient(135deg, var(--plum) 0%, var(--plum-dark) 100%);
  color: #fff;
  padding: 16px 20px;
  box-shadow: var(--shadow-3);
}

.balance-main { min-width: 0; }
.balance-label { font-size: 13px; opacity: 0.85; }

.balance-amount {
  font-size: 28px;
  font-weight: 800;
  margin-top: 3px;
  letter-spacing: -0.5px;
  font-variant-numeric: tabular-nums;
}

/* «Заработано» за выбранный месяц: подпись и селект месяца одной строкой.
   Селект — тот же «пилюльный» контрол, что в шапке «Тарифа» (.hero-month-select). */
.earn-pick { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.earn-pick .hero-month-select {
  font-size: 13px;
  padding: 3px 25px 3px 10px;
  background-size: 13px;
  background-position: right 8px center;
}
.earn-pick-go { padding: 4px 12px; font-size: 13px; }

/* «Заработано» — карточка-ссылка на детализацию дохода (/finance/earnings/):
   тап по всей карточке ведёт на новый экран, тем же жестом, что кольца ведут на
   свою историю. Селект месяца поднят над ссылкой-оверлеем и остаётся кликабельным. */
.balance-card { position: relative; transition: transform .16s cubic-bezier(.16, 1, .3, 1); }
@media (hover: hover) { .balance-card:hover { transform: scale(1.01); } }
.balance-card:active { transform: scale(.985); }
.balance-card .stretched-link { position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
.balance-card .earn-pick { position: relative; z-index: 2; }
.balance-chevron { width: 22px; height: 22px; flex-shrink: 0; color: #fff; opacity: 0.85; }

/* Значок «норма взята» в углу кольца. У «Активности» это условия
   гарантированного минимума (сколько осталось — в плашке минимума в
   «Бонусах»), у «Повторных клиентов» — шаг к следующей категории. Слот есть
   всегда и одинаковый у обоих колец: пока норма не набрана — пустой контурный
   кружок (видно, что галочка сюда встанет), набрана — зелёная галочка. */
.ring-check {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ring-check.is-on {
  background: var(--ok-text);
  color: #fff;
  box-shadow: 0 1px 3px rgb(34 39 31 / .25);
}
.ring-check.is-off {
  border: 1.6px solid rgb(92 97 85 / .28);                        /* фолбэк */
  border-color: color-mix(in srgb, var(--muted) 28%, transparent);
}
.ring-check svg { width: 15px; height: 15px; }
/* Тот же значок в строке помесячной «Активности»: не в углу кольца, а встроен в
   строку — без абсолютной привязки, мельче и по центру строки. Крестик
   (is-miss) — красный (тот же бренд-красный #8b3434, что у метки
   «гарантированного минимума»): норма часов месяца не набрана. */
.ring-check--row {
  position: static;
  top: auto;
  right: auto;
  width: 22px;
  height: 22px;
  align-self: center;
  flex: none;
}
.ring-check--row svg { width: 13px; height: 13px; }
.ring-check.is-miss {
  background: #8b3434;
  color: #fff;
  box-shadow: 0 1px 3px rgb(34 39 31 / .25);
}

/* Строка-пояснение внутри тёмной карточки (экран закрытия смены) */
.pay-prev {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgb(255 255 255 / .25);
  font-size: 13px;
  opacity: 0.85;
}

.balance-action { flex-shrink: 0; margin: 0; }
.balance-action .btn-light { padding: 15px 30px; font-size: 15.5px; font-weight: 700; min-width: 168px; }
/* «Вывести» — всегда чистый белый фон с читаемым текстом, даже при нулевом балансе */
.balance-action .btn-light:disabled {
  opacity: 1;
  background: #fff;
  color: var(--muted);
  box-shadow: 0 1px 2px rgb(34 39 31 / .12);
}

/* Бонусные задания внутри «Финансов» */
.bonus-link { align-items: center; }
.bonus-link-ic { background: #e9eedf; color: var(--plum); }
.bonus-link-meta { color: var(--muted); font-size: 12.5px; margin-top: 2px; }
.bonus-link-earned {
  color: var(--ok-text);
  font-weight: 800;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.bonus-page-head { margin-top: 0; }
.bonus-hero {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  padding: 18px 20px;
  color: #fff;
  background: linear-gradient(135deg, var(--plum) 0%, var(--plum-dark) 100%);
  box-shadow: var(--shadow-3);
}
.bonus-hero-label { font-size: 13px; opacity: .82; }
.bonus-hero-value { margin-top: 2px; font-size: 28px; font-weight: 800; font-variant-numeric: tabular-nums; }
.bonus-hero-earned { display: flex; flex-direction: column; align-items: flex-end; font-size: 12px; opacity: .9; }
.bonus-hero-earned strong { margin-top: 3px; font-size: 17px; font-variant-numeric: tabular-nums; }

.bonus-list { display: flex; flex-direction: column; gap: 12px; margin-top: 14px; }
.bonus-task-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 86px;
  gap: 6px;
}
.bonus-task-main,
.bonus-task-reward {
  background: var(--card);
  border-radius: var(--radius);
}
.bonus-task-main { min-width: 0; padding: 16px; }
.bonus-task-reward {
  display: flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  color: var(--plum-deep);
  font-size: 22px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.bonus-task-reward span { color: var(--ok-text); margin-right: 1px; }
.bonus-task-reward small { margin-left: 3px; font-size: 14px; }
.bonus-task-card.is-paid .bonus-task-main,
.bonus-task-card.is-paid .bonus-task-reward { background: var(--ok-bg); }
.bonus-task-heading { display: flex; align-items: flex-start; gap: 11px; }
.bonus-task-heading h2 { font-size: 16px; line-height: 1.25; }
.bonus-task-heading p { margin-top: 4px; color: var(--muted); font-size: 13.5px; line-height: 1.35; }
.bonus-task-icon {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex: 0 0 34px;
  background: #e6eadc;
  color: var(--plum);
}
.bonus-task-icon svg { width: 20px; height: 20px; }
.bonus-task-icon--rating { background: #f4ead0; color: #a57818; }
.bonus-task-icon--review { background: #e5eceb; color: #3f746a; }

.bonus-progress { display: flex; align-items: center; gap: 9px; margin-top: 13px; color: var(--muted); font-size: 12px; }
.bonus-progress-segments { display: flex; flex: 1; gap: 4px; min-width: 0; }
.bonus-progress-segments span { height: 6px; flex: 1; border-radius: 999px; background: #dfe2db; }
.bonus-progress-segments span.is-filled { background: #68bc75; }
.bonus-task-footer { margin-top: 12px; }
.bonus-task-state { display: flex; align-items: center; gap: 8px; }
.bonus-days { color: var(--muted); font-size: 12px; }
.bonus-manager-comment { margin-top: 8px; color: var(--warn-text); font-size: 13px; }
.bonus-submit { width: 100%; margin-top: 10px; padding-block: 9px; }
.bonus-verification { margin-top: 10px; color: var(--muted); font-size: 11.5px; line-height: 1.35; }
.bonus-footnote { margin: 14px 4px 0; color: var(--muted); font-size: 12.5px; text-align: center; }

@media (max-width: 390px) {
  .bonus-task-card { grid-template-columns: minmax(0, 1fr) 72px; }
  .bonus-task-main { padding: 14px; }
  .bonus-task-reward { font-size: 18px; }
  .bonus-link-earned { display: none; }
}

.amount { font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }
.amount-plus { color: var(--ok-text); }
.amount-minus { color: var(--ink); }

.amount { font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }
.amount-plus { color: var(--ok-text); }
.amount-minus { color: var(--ink); }

/* ── Детализация операций ──────────────────────────── */
.op-card { display: flex; flex-direction: column; gap: 8px; }
.op-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.op-title { font-weight: 700; }
.op-meta { display: flex; align-items: center; gap: 10px; }
.op-date { color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }

/* ── Верхние стат-карточки (Рейтинг / Категория / Достижения) ── */
.stat-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 12px;
}

.stat-card {
  position: relative;
  background: var(--card);
  border-radius: 16px;
  padding: 12px 12px 11px;
  min-height: 74px;
  overflow: hidden;
  box-shadow: var(--shadow-1);
}

.stat-value {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.3px;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

.stat-stars {
  display: flex;
  gap: 1px;
  font-size: 15px;
  line-height: 1;
  color: var(--line);
}
.stat-stars .is-on { color: var(--gold); }

.stat-label {
  color: var(--muted);
  font-size: 12.5px;
  margin-top: 3px;
}

.stat-icon {
  position: absolute;
  right: 9px;
  bottom: 9px;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.92;
}
.stat-icon svg { width: 100%; height: 100%; }

/* Ряд из двух карточек (Категория + Уровень) */
.stat-row--2 { grid-template-columns: repeat(2, 1fr); }

/* «Уровень» — кольцевой прогресс по 5 уровням */
.stat-card--ring { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.ring { position: relative; width: 46px; height: 46px; }
.ring-svg { width: 100%; height: 100%; }
.ring-track { fill: none; stroke: var(--pill-bg); stroke-width: 3.4; }
.ring-fill {
  fill: none;
  stroke: var(--plum);
  stroke-width: 3.4;
  stroke-linecap: round;
  transition: stroke-dasharray .7s cubic-bezier(.16, 1, .3, 1);
}
.ring-num {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 14px;
  color: var(--ink);
}
.ring-num small { font-weight: 600; font-size: 10px; color: var(--muted); }
@media (prefers-reduced-motion: reduce) {
  .ring-fill { transition: none; }
}

/* ── Строка-ссылка «Мой тариф» ───────────────────── */
/* Строка-плашка: ссылка (.tariff-link) и не-ссылка (.tariff-row) выглядят
   одинаково — весь экран «Финансов» собран из них. */
.tariff-link,
.tariff-row {
  display: flex;
  align-items: center;
  gap: 14px;
  color: inherit;
  text-decoration: none;
  margin-top: 4px;
  padding: 13px 16px;            /* компактнее дефолтных 18px */
}
.tariff-link {
  transition:
    transform 160ms cubic-bezier(0.23, 1, 0.32, 1),
    box-shadow .2s ease;
}
/* Наведение — увеличение + инверсия цвета иконки (как акцент капсулы навбара) */
@media (hover: hover) {
  .tariff-link:hover { transform: scale(1.02); box-shadow: var(--shadow-2); }
  .tariff-link:hover .tariff-ic { background: var(--plum); color: #fff; }
}
.tariff-link:active { transform: scale(0.97); }

.tariff-ic {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  background: var(--chip-bg);
  color: var(--plum);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 19px;
  font-weight: 700;
  line-height: 1;
  transition: background .2s ease, color .2s ease;
}
.tariff-ic svg { width: 20px; height: 20px; }

.tariff-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.tariff-title { font-weight: 700; }
/* Сумма/счёт справа в строке-плашке (бонусы, штрафы) */
.tariff-val {
  margin-left: auto;
  padding-left: 8px;
  font-weight: 800;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* «Гарантированный минимум» загорается зелёной иконкой при наборе нормы часов */
.gm-row.is-on .tariff-ic { background: var(--ok-bg); color: var(--ok-text); }
.tariff-sub {
  color: var(--muted);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.tariff-link .setting-chevron { margin-left: auto; }

/* ── Страница тарифа ─────────────────────────────── */
.tariff-hero {
  background: linear-gradient(135deg, var(--plum) 0%, var(--plum-dark) 100%);
  color: #fff;
  padding: 18px 20px;
  box-shadow: 0 10px 30px -10px rgb(50 61 36 / .45);
}
.tariff-hero-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.hero-income-pick { display: flex; align-items: center; gap: 8px; min-width: 0; }
.hero-income-label { font-size: 15px; opacity: 0.88; }
.hero-month-select {
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  color: #fff;
  background-color: rgb(255 255 255 / .14);
  border: 1px solid rgb(255 255 255 / .3);
  border-radius: 999px;
  padding: 5px 30px 5px 12px;
  cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 9px center;
  background-size: 14px;
}
.hero-month-select option { color: #23271f; background: #fff; }
.tariff-hero-income-val {
  font-size: 22px;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.5px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.tariff-hero-balance {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid rgb(255 255 255 / .22);
}
.tariff-hero-balance-label { font-size: 14px; opacity: 0.88; }
.tariff-hero-balance-val {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.4px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.payout-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.payout-amt { font-weight: 700; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Сумма уже выведенного — рядом с заголовком «Выводы», до счётчика операций. */
.payout-total { margin-left: auto; font-weight: 700; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.hero-chart[hidden] { display: none; }

/* Доход по дням — отдельная белая карточка с горизонтальной прокруткой */
.income-card { padding: 0; overflow: hidden; }
.income-scroll {
  display: flex;
  align-items: flex-end;
  gap: 18px;
  overflow-x: auto;
  padding: 30px 16px 12px;
  -webkit-overflow-scrolling: touch;
}
.income-col { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.income-col-track { height: 100px; display: flex; align-items: flex-end; }
.income-col-bar {
  position: relative;
  width: 22px;
  height: var(--h, 8%);
  min-height: 4px;
  background: #7A9456;
  border-radius: 5px 5px 3px 3px;
}
/* дни без начислений — бледный пенёк, без подписи суммы */
.income-col-bar--zero { height: 3px; min-height: 3px; background: rgb(35 39 31 / .12); }
.income-col-amt {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-bottom: 5px;
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.income-col-day {
  font-size: 10px;
  color: var(--muted);
  text-transform: uppercase;
  text-align: center;
  line-height: 1.3;
}
.income-col-day b { display: block; font-size: 13px; color: var(--ink); }

.income-days {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 84px;
  padding: 10px 0 6px;
}
.income-day {
  flex: 1;
  min-width: 0;
  align-self: stretch;
  display: flex;
  align-items: flex-end;
}
.income-bar {
  width: 100%;
  height: var(--h, 10%);
  background: rgb(255 255 255 / .5);
  border-radius: 3px 3px 2px 2px;
  transition: background .15s ease;
}
@media (hover: hover) {
  .income-day:hover .income-bar { background: #fff; }
}

/* Аккордеоны «Тарифа» («Выводы» / «Оплата») */
.accordion { padding: 0; overflow: hidden; }
.accordion-sum {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 18px;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.accordion-sum::-webkit-details-marker { display: none; }
.accordion-title { font-weight: 700; font-size: 15.5px; flex: 1; }
.accordion-caret { width: 18px; height: 18px; flex-shrink: 0; color: var(--muted); transition: transform .22s cubic-bezier(.16, 1, .3, 1); }
.accordion[open] .accordion-caret { transform: rotate(180deg); }
@media (hover: hover) { .accordion-sum:hover { background: rgb(80 96 58 / .04); } }
.accordion-body { padding: 0 0 8px; }

/* Счётчик в заголовке аккордеона (формат как у кольца) */
.level-plus {
  flex-shrink: 0;
  background: var(--ok-bg);
  color: var(--ok-text);
  font-size: 12.5px;
  font-weight: 800;
  padding: 2px 8px;
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
}
.level-plus small { font-weight: 600; opacity: 0.7; }
.level-plus--plum { background: var(--chip-bg); color: var(--plum); }

/* Подзаголовок вида баллов (Брак / Сервис / Стандарты) */
.claim-cat {
  padding: 12px 18px 4px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .4px;
  color: #9a4f60;
}

/* Рекламации (Финансы) и «Баллы» (Тариф) — бледно-розовая палитра */
.claims-card { padding: 4px 18px; }
.claim-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
}
.claim-row:last-child { border-bottom: none; }
.accordion-body .claim-item { background: transparent; box-shadow: none; }
.accordion-body .claim-item + .claim-item { border-top: 1px solid var(--line); }

/* Бар баллов: середина (50%) = лимит; перебор за серединой — красным */
.claims-bar-card { display: flex; flex-direction: column; gap: 12px; padding: 14px 16px; }
.claims-over-txt { color: #c0504e; }
.claims-progress {
  position: relative;
  height: 12px;
  border-radius: 999px;
  background: var(--pill-bg);
  overflow: hidden;
}
.claims-fill { position: absolute; top: 0; height: 100%; }
.claims-fill--free { left: 0; background: #d49fb0; border-radius: 999px; }
.claims-fill--over { left: 50%; background: #cf5b5b; }
.claims-mid {
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
  width: 2px;
  background: rgb(255 255 255 / .85);
  transform: translateX(-50%);
  z-index: 2;
}

/* Строка списка внутри аккордеона («Выводы» на «Тарифе») */
.level-month {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
  font-size: 13.5px;
}
.level-month:last-child { border-bottom: none; }
.level-month-name { min-width: 72px; }   /* фикс. колонка месяца — значения выровнены */

/* Таблица цен услуг («Оплата» на «Тарифе») */
.price-tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.price-tbl th {
  text-align: right;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .4px;
  color: var(--muted);
  padding: 6px 0 8px;
  border-bottom: 1px solid var(--line);
}
.price-tbl th:first-child { text-align: left; }
.price-cat td {
  padding: 10px 0 4px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .4px;
  color: var(--plum);
}
.price-tbl tbody tr:not(.price-cat) td { padding: 7px 0; border-bottom: 1px solid var(--line); }
.price-tbl tbody tr:last-child td { border-bottom: none; }
.price-name { color: var(--ink); padding-right: 10px; }
.price-num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--muted); }
.price-pay { color: var(--ink); font-weight: 700; }
.grade-prices-empty { color: var(--muted); font-size: 13px; padding: 6px 0; }
.tariff-role-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 4px; }
.tariff-role-name { font-weight: 700; font-size: 15px; color: var(--ink); }

.tariff-note { text-align: left; font-size: 13px; line-height: 1.5; }

/* Страница «Убрать смену» */
.remove-shift-lead { font-weight: 600; margin-bottom: 12px; }
.remove-shift-rules { list-style: none; display: flex; flex-direction: column; gap: 10px; }
.remove-shift-rules li {
  position: relative;
  padding-left: 22px;
  color: var(--muted);
  font-size: 13.5px;
  line-height: 1.45;
}
.remove-shift-rules li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 7px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--plum);
}
.remove-shift-cancel { margin-top: 10px; text-align: center; }

@media (prefers-reduced-motion: reduce) {
  .tariff-link, .metric-card { transition: none; }
  .tariff-link:active, .tariff-link:hover,
  .metric-card:active, .metric-card:hover { transform: none; }
  .metric-note { transition: none; }
}

.setting-chevron {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  color: var(--muted);
}

/* ── Нижняя навигация: liquid-glass approximation ──── */
/* «Liquid glass» — это веб-аппроксимация (backdrop-filter + слои/блики),
   не нативный Apple-материал. Есть твёрдый фолбэк ниже. */
.tabbar {
  position: fixed;
  left: 50%;
  bottom: calc(var(--tabbar-gap) + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  width: calc(100% - 28px);
  max-width: 532px;
  z-index: 40;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  align-items: center;
  padding: 6px 10px;
  border-radius: 24px;
  border: 1px solid rgb(255 255 255 / .55);
  background:
    linear-gradient(135deg, rgb(255 255 255 / .72), rgb(255 255 255 / .40)),
    rgb(255 255 255 / .55);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / .7),
    0 12px 34px rgb(34 39 31 / .14);
}

/* Экраны с лентой в нижнем доке («Сегодня» — дни, «Расписание» — месяцы) несут
   второй плавающий ряд над навбаром: добавляем запас снизу, чтобы последние
   карточки не прятались под доком. Условие — сам док, а не вкладка: у правки
   графика вкладка тоже «schedule», но ленты там нет. */
body:has(.day-dock) main { padding-bottom: 84px; }

.tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  font-size: 10.5px;
  color: var(--muted);
  text-decoration: none;
  padding: 6px 2px;
  /* лёгкий инсет внутрь ячейки — чтобы капсулы активных вкладок не слипались */
  margin: 0 4px;
  border-radius: 16px;
  transition:
    color .2s ease,
    background .25s cubic-bezier(.16, 1, .3, 1),
    transform .2s cubic-bezier(.16, 1, .3, 1),
    box-shadow .25s ease;
}

.tab-icon {
  width: 20px;
  height: 20px;
  transition: transform .2s cubic-bezier(.16, 1, .3, 1);
}

/* Наведение курсора — лёгкое увеличение + мягкая подсветка (на устройствах с мышью) */
@media (hover: hover) {
  .tab:hover { transform: scale(1.04); }
  .tab:hover:not(.active) { color: var(--plum); background: rgb(80 96 58 / .08); }
}
/* Тач/нажатие — короткий «вдавливающий» отклик */
.tab:active { transform: scale(.94); }

/* Активная вкладка — капсула с инверсией цвета (заливка бренда, светлые иконка/подпись).
   Без анимации появления — спокойно, статично; анимируется только нажатие. */
.tab.active {
  color: #fff;
  font-weight: 700;
  background: var(--plum);
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / .2),
    0 5px 14px -4px rgb(80 96 58 / .55);
}

@media (prefers-reduced-motion: reduce) {
  .tab:hover, .tab:active { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .tab .tab-icon { animation: none; transition: none; }
}
@media (prefers-reduced-transparency: reduce) {
  .tabbar {
    background: #fff;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

/* Плавающая «+» с панелью действий — в правом нижнем углу над навбаром (как
   «Записать» в DIKIDI), отдельно от вкладок. Док держит позицию за обоих:
   панель раскрывается вверх от кнопки, поэтому лента дней (.day-dock) и
   навбар (.tabbar) остаются нетронутыми. */
.fab-dock {
  position: fixed;
  right: max(18px, calc(50% - 258px));
  bottom: calc(84px + env(safe-area-inset-bottom));
  z-index: 46;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
  /* Док — только рамка для «+» и панели: сам он тапы не ловит, иначе его
     невидимая колонка накрывает контент под собой и нажатия туда не доходят
     (21.07 так «сломался переход» с «Финансов» в «Тариф»). Ловят только
     видимые дети. */
  pointer-events: none;
}
.fab-dock .fab,
.fab-dock .fab-panel.is-open { pointer-events: auto; }
/* Закрытая панель остаётся в разметке (для анимации) — тапы сквозь неё. */
.fab-dock .fab-panel { pointer-events: none; }
/* Там, где есть лента в нижнем доке (дни на «Сегодня», месяцы на «Расписании»),
   док «+» поднимается над ней — иначе кнопка садится на ленту. */
body:has(.day-dock) .fab-dock {
  bottom: calc(var(--tabbar-gap) + env(safe-area-inset-bottom) + var(--tabbar-h) + 96px);
}

/* Синее браузерное кольцо фокуса на «+» (скрин владельца 23.07): закрытие
   панели возвращает фокус кнопке программно, и дефолтный outline остаётся
   висеть. Свой рисуем только клавиатуре — фирменный, со смещением. */
.fab:focus { outline: none; }
.fab:focus-visible { outline: 2px solid var(--plum); outline-offset: 3px; }

.fab {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  cursor: pointer;
  /* градиент центрирован по горизонтали (50%) — иначе блик уводит форму в «яйцо» */
  background: radial-gradient(135% 135% at 50% 22%, var(--plum), var(--plum-deep));
  border: none;
  box-shadow:
    inset 0 1px 0 rgb(255 255 255 / .22),
    0 8px 20px -3px rgb(80 96 58 / .5);
  transition:
    transform .2s cubic-bezier(.16, 1, .3, 1),
    background .25s ease,
    box-shadow .25s ease;
}
.fab svg { width: 26px; height: 26px; }

@media (hover: hover) {
  .fab:hover {
    transform: scale(1.05);
    background: radial-gradient(135% 135% at 50% 22%, #6a7c4a, var(--plum));
    box-shadow:
      inset 0 1px 0 rgb(255 255 255 / .35),
      0 11px 26px -3px rgb(80 96 58 / .55);
  }
}
.fab:active { transform: scale(.94); }
/* Раскрытая панель → тот же «+», повёрнутый в крестик. Правило идёт после
   hover/active, поэтому перебивает их при равной специфичности. */
.fab.is-open { transform: rotate(45deg); }
.fab.is-open:active { transform: rotate(45deg) scale(.94); }

/* Полупрозрачная подложка: ловит клик мимо панели и приглушает фон. */
.fab-scrim {
  position: fixed;
  inset: 0;
  z-index: 45;
  background: rgb(34 39 31 / .3);
  opacity: 0;
  visibility: hidden;
  transition: opacity .22s ease, visibility 0s linear .22s;
}
.fab-scrim.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity .22s ease, visibility 0s linear 0s;
}

/* Панель действий — цельный «стеклянный» блок над кнопкой. Раскрытие 280 мс,
   строки подхватываются снизу вверх с шагом 50 мс. Скрытая панель прячется
   через visibility — она же убирает строки из таб-порядка и из скринридера. */
.fab-panel {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: min(272px, calc(100vw - 36px));
  padding: 6px;
  border-radius: 22px;
  border: 1px solid rgb(255 255 255 / .5);
  background:
    linear-gradient(135deg, rgb(255 255 255 / .85), rgb(255 255 255 / .62)),
    rgb(255 255 255 / .72);
  backdrop-filter: blur(24px) saturate(170%);
  -webkit-backdrop-filter: blur(24px) saturate(170%);
  box-shadow: 0 14px 40px rgb(34 39 31 / .2);
  transform-origin: bottom right;
  opacity: 0;
  visibility: hidden;
  transform: translateY(12px) scale(.94);
  transition:
    opacity .2s ease,
    transform .28s cubic-bezier(.16, 1, .3, 1),
    visibility 0s linear .28s;
}
.fab-panel.is-open {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition:
    opacity .2s ease,
    transform .28s cubic-bezier(.16, 1, .3, 1),
    visibility 0s linear 0s;
}

.fab-action {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;              /* область нажатия строки — не меньше 44px */
  padding: 8px 14px;
  border-radius: 16px;
  background: var(--card);
  border: 1px solid var(--line);
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  font-size: 15px;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity .2s ease,
    transform .24s cubic-bezier(.16, 1, .3, 1);
}
.fab-panel.is-open .fab-action { opacity: 1; transform: none; }
/* Снизу вверх: нижняя строка первой, дальше по 50 мс. */
.fab-panel.is-open .fab-action:nth-last-child(1) { transition-delay: .04s; }
.fab-panel.is-open .fab-action:nth-last-child(2) { transition-delay: .09s; }
.fab-panel.is-open .fab-action:nth-last-child(3) { transition-delay: .14s; }
.fab-panel.is-open .fab-action:nth-last-child(4) { transition-delay: .19s; }
.fab-panel.is-open .fab-action:nth-last-child(n+5) { transition-delay: .24s; }
.fab-action:active { transform: scale(.99); }
.fab-action:focus-visible { outline: 2px solid var(--plum); outline-offset: 2px; }
.fab-action-ic {
  width: 34px;
  height: 34px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 11px;
  background: var(--chip-bg);
  color: var(--plum);
}
.fab-action-ic svg { width: 20px; height: 20px; }

/* Полоска-«ручка» шторки: осталась у шторки закрытия времени на «Сегодня». */
.sheet-handle {
  width: 38px;
  height: 4px;
  border-radius: 999px;
  background: var(--line);
  margin: 2px auto 6px;
}

@media (prefers-reduced-motion: reduce) {
  .fab, .fab-scrim, .fab-panel, .fab-action { transition: none; }
  .fab:hover:not(.is-open), .fab:active:not(.is-open) { transform: none; }
  .fab-panel.is-open .fab-action { transition-delay: 0s; }
}
@media (prefers-reduced-transparency: reduce) {
  .fab-panel {
    background: #fff;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

/* ── Формы и вход ──────────────────────────────── */
.field { display: block; margin-bottom: 14px; }

.field-label {
  display: block;
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 6px;
}

.field input,
.field select,
.field textarea {
  width: 100%;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  padding: 12px 14px;
  font-size: 15px;
  font-family: var(--font-body);
  background: #fff;
  resize: vertical;
}

.field input[type="file"] {
  padding: 10px 12px;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--plum);
}

/* Чипы выбранных категорий */
.chip-row { display: flex; flex-wrap: wrap; gap: 8px; }

/* Список чекбоксов (выбор категорий) */
.check-list ul { list-style: none; display: flex; flex-direction: column; gap: 2px; }
.check-list li { margin: 0; }
.check-list label {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 4px;
  font-size: 15px;
  cursor: pointer;
  border-bottom: 1px solid var(--line);
}
.check-list li:last-child label { border-bottom: none; }
.check-list input[type="checkbox"] {
  width: 20px;
  height: 20px;
  accent-color: var(--plum);
  flex-shrink: 0;
}

.service-timing-field,
.service-timing-summary {
  min-width: 0;
  margin-top: 12px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.service-timing-field[hidden] { display: none; }
.service-timing-field .field { margin-bottom: 0; }
.service-timing-summary .row-title { overflow-wrap: anywhere; }

.close-form .errorlist,
.add-form .errorlist {
  color: #b03050;
  font-size: 13px;
  list-style: none;
  margin: -4px 0 10px;
}

.appointment-summary {
  margin-bottom: 14px;
}

.checkbox-field {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  color: var(--ink);
  font-size: 14px;
  margin: 4px 0 16px;
}

.checkbox-input {
  margin-top: 3px;
  accent-color: var(--plum);
}

.login-page {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 100vh;
  padding-bottom: 20px;
}

.login-brand { text-align: center; margin-bottom: 24px; }

.login-logo {
  font-family: var(--font-display);
  font-size: 36px;
  letter-spacing: 4px;
  color: var(--plum-deep);
}

.login-sub {
  color: var(--muted);
  font-size: 13px;
  letter-spacing: 1px;
}

.login-card { padding: 24px; }

.login-alt-link {
  display: block;
  margin-top: 14px;
  color: var(--plum-deep);
  font-size: 14px;
  text-align: center;
  text-decoration: none;
}

.form-error {
  color: #b03050;
  font-size: 13.5px;
  margin-bottom: 12px;
}

/* ── Глазик показа пароля (см. static/js/password-eye.js) ──
   Кнопка скрыта по умолчанию; класс pw-ready ставит только скрипт, поэтому без
   JS поле остаётся обычным паролем без «мёртвой» кнопки. */
.password-field { position: relative; }

.password-toggle {
  display: none;
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: 44px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  background: none;
  color: var(--muted);
  cursor: pointer;
  border-radius: 12px;
}
.password-field.pw-ready .password-toggle { display: flex; }
.password-field.pw-ready input { padding-right: 46px; }

.password-toggle:hover { color: var(--plum); }
.password-toggle:focus { outline: none; }
.password-toggle:focus-visible {
  outline: none;
  color: var(--plum);
  box-shadow: 0 0 0 3px rgba(80, 96, 58, .22);
}

.password-toggle svg { width: 22px; height: 22px; }
.password-eye--hide { display: none; }
.password-field.pw-shown .password-eye--show { display: none; }
.password-field.pw-shown .password-eye--hide { display: block; }

/* ── Motion: появление блоков финансов (vanilla JS, см. static/js/finance-anim.js) ──
   Прячем reveal-цели до анимации, чтобы не было «вспышки». Селектор бьёт по уже
   существующему DOM экрана финансов — разметку карточек трогать не нужно.
   Класс .js-motion ставится в <head> только когда reduced-motion НЕ запрошен,
   поэтому при reduced-motion блоки сразу видимы и JS-анимации не запускаются. */
.js-motion main[data-tab="finance"] > .section-head,
.js-motion main[data-tab="finance"] > .card,
.js-motion main[data-tab="finance"] > .metric-rings {
  opacity: 0;
  will-change: opacity, transform;
}

/* ── Самостоятельная правка графика дня (флаг SCHEDULE_SELF_EDIT_ENABLED) ── */



.day-edit-page { display: grid; gap: 14px; }

.day-edit-back {
  color: var(--muted);
  font-size: 14px;
  text-decoration: none;
}

.day-edit-title { margin: 0; font-size: 22px; }

.day-edit-card { display: grid; gap: 14px; }

.day-edit-times { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

/* Перерывов может быть несколько: строка = пара полей + свой крестик. Пустой
   список схлопываем, иначе он съедал бы отступ формы впустую. */
.day-edit-breaks { display: grid; gap: 10px; }
.day-edit-breaks:empty { display: none; }

.day-edit-break { display: grid; grid-template-columns: 1fr auto; gap: 8px; align-items: end; }

.day-edit-break-remove {
  width: 44px;
  min-height: 44px;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: #fff;
  color: var(--muted);
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}

.day-edit-break-remove:active { background: var(--card); }

/* Подпись «с»/«до» живёт ВНУТРИ поля слева (слово владельца 21.07): рамка
   одна на подпись и значение, поэтому рамку рисует сам label, а select внутри
   идёт без своей. */
.day-edit-field {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 12px 0 14px;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: #fff;
}

.day-edit-field .field-label {
  display: inline;
  margin: 0;
  font-size: 13px;
  color: var(--muted);
  flex: none;
}

.day-edit-field select {
  flex: 1;
  min-width: 0;
  min-height: 42px;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: inherit;
  font-weight: 700;
  text-align: center;
  padding: 0;
}

.day-edit-field select:focus { outline: none; }
.day-edit-field:focus-within { border-color: var(--plum); }


/* Про Аспро говорим только в дне с записями — значит, это не сноска, а
   предупреждение: правку такого дня сервис не пропустит. */
.day-edit-aspro {
  margin: 0;
  padding: 12px 14px;
  border-radius: var(--radius-xs);
  background: var(--warn-bg);
  color: var(--warn-text);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
}

/* ── «Сегодня»: тап по свободному времени → закрыть промежуток дня ──── */

/* Курсор-подсказка только там, где жест включён (мобайл её не увидит — там
   ориентир текстовая подсказка под сеткой). */
.day-timeline-section.is-tappable { cursor: pointer; }
.day-timeline-section.is-tappable .timeline-appointment { cursor: auto; }

/* Шторки поверх дня: «Закрыть время» и карточка клиента — одна механика и одно
   оформление, отличается только содержимое панели. */
.day-close-sheet,
.client-sheet { position: fixed; inset: 0; z-index: 45; }
.day-close-sheet[hidden],
.client-sheet[hidden] { display: none; }

.day-close-overlay,
.client-sheet-overlay {
  position: absolute;
  inset: 0;
  background: rgb(34 39 31 / .38);
}

.day-close-panel,
.client-sheet-panel {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: calc(100% - 20px);
  max-width: 540px;
  display: grid;
  gap: 12px;
  justify-items: center;
  margin-bottom: 10px;
  padding: 8px 16px calc(16px + env(safe-area-inset-bottom));
  border-radius: 28px;
  border: 1px solid rgb(255 255 255 / .5);
  background:
    linear-gradient(135deg, rgb(255 255 255 / .92), rgb(255 255 255 / .78)),
    rgb(255 255 255 / .85);
  backdrop-filter: blur(24px) saturate(170%);
  -webkit-backdrop-filter: blur(24px) saturate(170%);
  box-shadow: 0 -10px 40px rgb(34 39 31 / .18);
}
@media (prefers-reduced-transparency: reduce) {
  .day-close-panel,
  .client-sheet-panel { background: #fff; backdrop-filter: none; -webkit-backdrop-filter: none; }
}
@media (prefers-reduced-motion: no-preference) {
  .day-close-panel,
  .client-sheet-panel { animation: day-close-rise .24s cubic-bezier(.16, 1, .3, 1); }
  @keyframes day-close-rise {
    from { transform: translate(-50%, 24px); opacity: 0; }
  }
}

.day-close-panel .day-edit-times,
.day-close-panel .btn { width: 100%; }
.day-close-title { margin: 0; font-size: 17px; font-weight: 700; }
.day-close-hint { margin: 0; color: var(--muted); font-size: 13px; line-height: 1.45; }
.day-close-panel .btn[disabled] { opacity: .55; }

/* ── Шторка «карточка клиента» ─────────────────────────────────────── */
/* Панель высокая и содержательная, поэтому поднимаем её над плавающей «+»
   (.fab-dock, 46) — иначе кнопка ложится поверх комментариев. */
.client-sheet { z-index: 47; }

.client-sheet-panel {
  justify-items: stretch;
  gap: 14px;
  max-height: 82vh;
  overflow-y: auto;
  outline: none;
}
.client-sheet-panel .sheet-handle { justify-self: center; }
.client-sheet-panel .btn { width: 100%; }

.client-sheet-head { display: flex; align-items: center; gap: 12px; }
.client-sheet-avatar {
  width: 42px;
  height: 42px;
  flex: 0 0 42px;
  border-radius: 50%;
  background: var(--plum-deep);
  color: #f5e9df;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.client-sheet-titles { min-width: 0; flex: 1; }
.client-sheet-name { margin: 0; font-size: 17px; font-weight: 700; }
.client-sheet-phone { color: var(--plum); font-size: 14px; text-decoration: none; }
.client-sheet-phone.is-empty { color: var(--muted); }

.client-sheet-block {
  display: grid;
  gap: 2px;
  padding: 10px 12px;
  border-radius: var(--radius-xs);
  background: var(--warn-bg);
  color: var(--warn-text);
  font-size: 13px;
}

.client-sheet-section { display: grid; gap: 8px; }
.client-sheet-label { margin: 0; color: var(--muted); font-size: 12.5px; font-weight: 600; }
.client-sheet-rows { display: grid; gap: 6px; }
.client-sheet-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-size: 14px;
}
.client-sheet-row strong { font-size: 13.5px; white-space: nowrap; }
/* Визиты по категориям — заметные чипы в шапке карточки клиента (перенесены с
   карточки записи 23.07, с полными названиями категорий). Категория
   сегодняшней записи выделена акцентом. Блок «по всей сети» ниже — прежними
   строками (.client-sheet-row), его не трогаем. */
.client-sheet-visits { display: flex; flex-wrap: wrap; gap: 8px; }
.client-sheet-visit {
  display: inline-flex;
  align-items: center;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--chip-bg);
  color: var(--plum-deep);
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.25;
}
.client-sheet-visit.is-current { background: var(--plum-deep); color: #f5e9df; }
.client-sheet-segment {
  justify-self: start;
  margin: 0;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--card);
  color: var(--plum);
  font-size: 12.5px;
  font-weight: 600;
}
.client-sheet-text { margin: 0; font-size: 14px; line-height: 1.45; }
.client-sheet-empty,
.client-sheet-hint { margin: 0; color: var(--muted); font-size: 12.5px; line-height: 1.4; }
.client-sheet-note {
  display: grid;
  gap: 4px;
  padding: 10px 12px;
  border-radius: var(--radius-xs);
  background: var(--card);
}
