/* ============================================================================
   Всё, что про время: полоса дня в шапке, список дня, недельная сетка,
   окно выбора времени касания и плавающая панель «Текущие события».

   Вынесено отдельным файлом, потому что это единственная часть консоли со
   своей геометрией: сетка суток считается в минутах, а не в отступах шкалы.
   ============================================================================ */

/* ============================================================= полоса дня
   Живёт под шапкой и видна на любой странице, поэтому обязана быть узкой и
   молчаливой: дата, часы, число событий, просрочка. Всё подробное — в разделе
   «Задачи». Каждая лишняя строка здесь прочитывается по десять раз на дню. */
.daybar {
  border-bottom: 1px solid var(--line);
  background: var(--bg-surface);
}
.daybar__inner {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  min-height: 38px;
  /* Только вертикальный отступ: боковые приходят от .wrap, и сокращённая запись
     `padding: … 0` их обнуляла — дата упиралась в левый край окна. */
  padding-block: var(--space-2);
  font-size: var(--text-xs);
  flex-wrap: wrap;
}
/* Есть просроченное — полоса окрашивается целиком: забытый лид важнее всего
   остального, что на ней написано. */
.daybar--late { background: var(--danger-soft); border-bottom-color: transparent; }

.daybar__now {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-3);
  color: var(--fg-soft);
  font-weight: var(--weight-medium);
}
.daybar__now:hover { color: var(--accent-fg); }
.daybar__date { text-transform: lowercase; }
.daybar__clock {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  letter-spacing: 0.02em;
}
.daybar__late {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 2px var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--danger);
  color: var(--danger-on);
  font-weight: var(--weight-semi);
}
.daybar__late:hover { color: var(--danger-on); filter: brightness(1.08); }
.daybar__empty { color: var(--fg-muted); }
/* Число событий — кнопка: она же открывает плавающую панель. */
.daybar__count {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 2px var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-full);
  background: var(--bg-surface);
  color: var(--fg-soft);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  cursor: pointer;
}
.daybar__count:hover { border-color: var(--accent); color: var(--accent-fg); }
.daybar__count[aria-expanded="true"] {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-fg);
}

/* ============================================================== список дня
   День сейлза — список, а не сетка часов: сетка отвечает на вопрос «как
   выглядит неделя», а утром нужен порядок дел. Касание длится 15 минут, а
   встреча растянута буферами на три часа — в часовой сетке это читается хуже. */
.tasklist { display: grid; gap: var(--space-3); }
.taskitem {
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr) auto;
  gap: var(--space-5);
  align-items: center;
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-strong);
  border-radius: var(--radius-lg);
  background: var(--bg-surface);
  color: var(--fg);
  transition:
    border-color var(--motion-fast) var(--ease-out),
    background-color var(--motion-fast) var(--ease-out);
}
.taskitem:hover { border-color: var(--line-strong); background: var(--bg-hover); color: var(--fg); }
.taskitem--current { border-color: var(--accent); border-left-color: var(--accent); background: var(--accent-soft); }
.taskitem--clash { background: var(--warn-soft); }
.taskitem--late { border-left-color: var(--danger); }
/* Прошедшее не прячем — по нему видно, что день идёт, — но приглушаем. */
.taskitem--past { opacity: 0.55; }
.taskitem--past:hover { opacity: 1; }

.taskitem__when { display: grid; gap: 1px; }
.taskitem__time {
  font-family: var(--font-mono);
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
}
.taskitem__span { font-size: var(--text-xs); color: var(--fg-muted); }
.taskitem--late .taskitem__span { color: var(--danger-fg); font-weight: var(--weight-semi); }
.taskitem__body { display: grid; gap: var(--space-2); min-width: 0; }
.taskitem__name { font-weight: var(--weight-semi); line-height: var(--leading-snug); overflow-wrap: anywhere; }
.taskitem__meta { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; }
.taskitem__go {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--fg-muted);
  font-size: var(--text-xs);
  white-space: nowrap;
}
.taskitem:hover .taskitem__go { color: var(--accent-fg); }
@media (max-width: 640px) {
  .taskitem { grid-template-columns: 72px minmax(0, 1fr); }
  .taskitem__go { display: none; }
}

/* Черта «сейчас»: где в списке проходит текущий момент. Без неё не видно,
   где кончилось прошедшее и начинается то, к чему готовиться. */
.nowline {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin: var(--space-2) 0;
  color: var(--danger);
  font-size: var(--text-xs);
  font-weight: var(--weight-semi);
}
.nowline::after { content: ""; flex: 1; height: 1px; background: currentColor; opacity: 0.4; }
.nowline b { font-family: var(--font-mono); }

/* Вид касания той же палитрой, что полоски в недельной сетке, — цвет означает
   одно и то же на обоих экранах. */
.pill--kind-meeting { background: var(--accent-soft); color: var(--accent-fg); }
.pill--kind-call { background: var(--ok-soft); color: var(--ok-fg); }
.pill--kind-email, .pill--kind-message { background: var(--info-soft); color: var(--info-fg); }
.pill--kind-telegram, .pill--kind-whatsapp { background: var(--warn-soft); color: var(--warn-fg); }

/* ======================================================= сетка календаря
   Неделя (или день) по времени, а не списком: планируют по свободным окнам,
   а окно между звонком в 11:00 и встречей в 14:00 в списке не видно вовсе.

   Геометрия приходит из шаблона В МИНУТАХ, пиксели считает только множитель
   --grid-pxmin. Плотность сетки меняется здесь одним числом, без правки Python.

   0.9px на минуту: час — 54px. Плотнее, чем в окне выбора времени (там 1.2),
   потому что здесь на экране семь дней и вся неделя должна читаться разом. */
.calendar {
  --grid-pxmin: 0.9px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--rail-width);
  gap: var(--space-5);
  align-items: start;
}
.calendar__side { display: grid; gap: var(--space-5); min-width: 0; }
@media (max-width: 1200px) {
  .calendar { grid-template-columns: minmax(0, 1fr); }
}

.grid-scroll {
  overflow: auto;
  max-height: min(72vh, 780px);
  border-bottom: 1px solid var(--line);
}
.grid {
  display: grid;
  grid-template-columns: 56px repeat(var(--grid-days), minmax(0, 1fr));
  grid-template-rows: auto 1fr;
  position: relative;
  min-width: 0;
}

/* Шапка с днями и левая ось липнут к краям прокрутки. */
.grid__corner {
  position: sticky;
  top: 0;
  left: 0;
  z-index: 7;
  background: var(--bg-surface);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line-strong);
}
.grid__dayhead {
  position: sticky;
  top: 0;
  z-index: 6;
  display: grid;
  justify-items: center;
  gap: 1px;
  padding: var(--space-3) var(--space-2);
  background: var(--bg-surface);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line-strong);
  color: var(--fg-soft);
}
.grid__dayhead:hover { background: var(--bg-hover); color: var(--fg); }
.grid__dayhead--today { background: var(--accent-soft); }
/* Выбранный день — тот, чья повестка открыта справа. Подчёркнут, а не залит:
   заливка спорила бы с «сегодня». */
.grid__dayhead--picked { box-shadow: inset 0 -2px 0 var(--accent); color: var(--accent-fg); }
.grid__dow {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--fg-muted);
}
.grid__dayhead--today .grid__dow { color: var(--accent-fg); }
.grid__date { font-size: var(--text-sm); font-weight: var(--weight-semi); }
.grid__count {
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  background: var(--bg-hover);
  color: var(--fg-muted);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semi);
}

.grid__axis {
  position: sticky;
  left: 0;
  z-index: 3;
  background: var(--bg-surface);
  border-right: 1px solid var(--line);
}
.grid__hour { height: calc(60 * var(--grid-pxmin)); position: relative; }
.grid__hour span {
  position: absolute;
  top: -7px;
  right: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--fg-muted);
}
.grid__hour:first-child span { top: 2px; }

.grid__day { position: relative; border-right: 1px solid var(--line); min-width: 0; }
.grid__day--today { background: color-mix(in srgb, var(--accent-soft) 30%, transparent); }
.grid__slot {
  height: calc(60 * var(--grid-pxmin));
  border-bottom: 1px solid var(--line);
}
/* Нерабочий час приглушён: сутки видно целиком — касание бывает и в семь
   утра, — но глаз сразу отделяет рабочее время от ночи. */
.grid__slot--off { background: color-mix(in srgb, var(--bg-sunken) 70%, transparent); }

.grid__now {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--at) * var(--grid-pxmin));
  height: 0;
  border-top: 2px solid var(--danger);
  z-index: 4;
  pointer-events: none;
}
.grid__now span {
  position: absolute;
  top: -9px;
  left: 2px;
  padding: 1px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--danger);
  color: var(--danger-on);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
}

/* Пересекающиеся касания делят ширину дня и встают колонками: спрятанное под
   соседом касание — это забытое касание. Колонку считает Python
   (presenters.lay_out_day), здесь только перевод в проценты. */
.grid__event {
  position: absolute;
  top: calc(var(--top) * var(--grid-pxmin));
  height: calc(var(--span) * var(--grid-pxmin));
  min-height: calc(15 * var(--grid-pxmin));
  left: calc(var(--col, 0) * (100% - 6px) / var(--cols, 1) + 3px);
  width: calc((100% - 6px) / var(--cols, 1) - 2px);
  overflow: hidden;
  display: grid;
  gap: 1px;
  align-content: start;
  padding: 3px var(--space-3);
  border: 1px solid var(--line-strong);
  border-left: 3px solid var(--slate-400);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  color: var(--fg);
  z-index: 2;
  transition: box-shadow var(--motion-fast) var(--ease-out);
}
.grid__event:hover { box-shadow: var(--shadow-md); z-index: 5; color: var(--fg); }
/* Свой блок можно перетащить прямо в этой сетке (js/calendar.js). Курсор-рука
   отличает его от чужих, которые остаются просто ссылками. touch-action
   обязателен: без него палец на сенсорном экране прокручивал бы сетку вместо
   переноса блока. */
.grid__event[data-mine] { cursor: grab; touch-action: none; }
/* Во время переноса — только transform (см. пояснение у .picker__event):
   переход по top превратил бы каждое движение мыши в анимацию с рывками. */
.grid__event.is-dragging {
  cursor: grabbing;
  opacity: 0.9;
  box-shadow: var(--shadow-lg);
  z-index: 20;
  will-change: transform;
  transition: none;
  pointer-events: none;
}
.grid__event--picked { border-color: var(--accent); background: var(--accent-soft); z-index: 6; }
.grid__event--clash { background: var(--warn-soft); }
/* Буферы встречи: видно, что блок шире самого касания. */
.grid__event--buffered { border-left-style: double; border-left-width: 5px; }
/* Цвет полосы = вид касания. Тот же набор, что в списке дня и в легенде: один
   цвет означает одно и то же на всех экранах. */
.grid__event--call { border-left-color: var(--ok); }
.grid__event--meeting { border-left-color: var(--accent); }
.grid__event--email, .grid__event--message { border-left-color: var(--info); }
.grid__event--telegram { border-left-color: var(--blue-500); }
.grid__event--whatsapp { border-left-color: var(--warn); }

.grid__event-time {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
}
.grid__event-len { color: var(--fg-muted); font-weight: var(--weight-normal); }
.grid__event-name {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semi);
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.grid__event-owner { font-size: var(--text-2xs); color: var(--accent-fg); }
/* 15–30 минут — это 14–27 пикселей: столбик подписей туда не влезает. */
.grid__event--short { display: flex; align-items: center; gap: var(--space-2); padding: 1px var(--space-2); }
.grid__event--short .grid__event-name { flex: 1; min-width: 0; }
.grid__event--short .grid__event-len,
.grid__event--short .grid__event-owner { display: none; }

/* Пустой день: подпись стоит в рабочих часах, а не посреди суток. */
.grid__free {
  position: absolute;
  top: calc(11 * 60 * var(--grid-pxmin));
  left: 0;
  right: 0;
  text-align: center;
  color: var(--fg-muted);
  font-size: var(--text-xs);
  pointer-events: none;
}

/* --------------------------------------------------------------- легенда */
.legend {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  flex-wrap: wrap;
  padding: var(--space-4) var(--space-6);
  font-size: var(--text-xs);
}
.legend__item { display: inline-flex; align-items: center; gap: var(--space-2); }
.legend__dot { width: 10px; height: 3px; border-radius: 2px; background: var(--slate-400); }
.legend__dot--call { background: var(--ok); }
.legend__dot--meeting { background: var(--accent); }
.legend__dot--email, .legend__dot--message { background: var(--info); }
.legend__dot--telegram { background: var(--blue-500); }
.legend__dot--whatsapp { background: var(--warn); }
.legend__dot--clash { background: var(--warn-soft); box-shadow: inset 0 0 0 1px var(--warn); height: 10px; width: 10px; border-radius: var(--radius-sm); }

/* ------------------------------------------------------- быстрый перенос
   Ряд коротких кнопок под планом. Каждая — своя форма (сервер считает время
   от «сейчас»), поэтому нужен flex-контейнер: формы иначе встают друг под
   другом блоками. */
.quick-plan {
  display: grid;
  gap: var(--space-3);
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}
.quick-plan__row { display: flex; gap: var(--space-2); flex-wrap: wrap; }

/* --------------------------------------------------------------- повестка */
.agenda__item {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr) auto;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  color: var(--fg);
}
.agenda__item:hover { background: var(--bg-hover); color: var(--fg); }
.agenda__item--picked { border-color: var(--accent); background: var(--accent-soft); }
.agenda__time {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--fg-soft);
}
.agenda__body { min-width: 0; display: grid; }
.agenda__name {
  font-size: var(--text-sm);
  font-weight: var(--weight-semi);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.agenda__item .icon { color: var(--warn); }

/* Правка времени начала в «Деталях касания»: поле и кнопка в одну строку,
   пояснение про автоматический конец — строкой ниже. */
.replan { display: flex; align-items: flex-end; gap: var(--space-2); margin-top: var(--space-4); }
.replan__field { flex: 1; min-width: 0; }
.replan__hint { margin-top: var(--space-2); font-size: var(--text-xs); }

/* ============================================================ неделя целиком */
.week {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: var(--space-3);
}
@media (max-width: 1000px) { .week { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .week { grid-template-columns: minmax(0, 1fr); } }

/* min-width: 0 обязателен: без него длинное название компании распирает
   колонку и вся неделя вылезает за карточку. */
.weekday {
  display: grid;
  gap: var(--space-2);
  align-content: start;
  min-height: 96px;
  min-width: 0;
  padding: var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--bg-sunken);
}
.weekday--empty { background: transparent; }
.weekday--today { border-color: var(--accent); background: var(--accent-soft); }
.weekday__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}
.weekday__dow {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semi);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--fg-muted);
}
.weekday--today .weekday__dow { color: var(--accent-fg); }
.weekday__date { font-size: var(--text-xs); color: var(--fg-muted); }

.weekitem {
  display: grid;
  gap: 1px;
  min-width: 0;
  padding: var(--space-3);
  border: 1px solid var(--line);
  /* Цвет полосы = вид касания: встречу видно среди писем, не читая. */
  border-left: 3px solid var(--line-strong);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  color: var(--fg);
}
.weekitem:hover { border-color: var(--line-strong); color: var(--fg); }
.weekitem--meeting { border-left-color: var(--accent); }
.weekitem--call { border-left-color: var(--ok); }
.weekitem--email, .weekitem--message { border-left-color: var(--info); }
.weekitem--telegram, .weekitem--whatsapp { border-left-color: var(--warn); }
.weekitem--clash { background: var(--warn-soft); }
.weekitem__time {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--fg-soft);
}
.weekitem__name { font-size: var(--text-xs); font-weight: var(--weight-semi); line-height: 1.35; overflow-wrap: anywhere; }
.weekitem__meta { display: flex; gap: var(--space-2); flex-wrap: wrap; font-size: var(--text-2xs); color: var(--fg-muted); }

/* ======================================================= выбор времени касания
   Сетка недели во всплывающем окне. Геометрия приходит из шаблона В МИНУТАХ,
   пиксели считает только множитель --picker-pxmin — поменять плотность можно
   здесь одним числом, не трогая Python.

   1.2 пикселя на минуту: час — 72px, как в календарях общего назначения, и при
   этом самое короткое касание в 15 минут остаётся читаемым без обмана
   с высотой. */
.picker {
  --picker-pxmin: 1.2px;
  width: min(1180px, 94vw);
  max-width: none;
  max-height: 90vh;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-xl);
  background: var(--bg-surface);
  color: var(--fg);
  box-shadow: var(--shadow-xl);
}
/* Колонка на всю высоту окна: сетка недели забирает свободное место, а подвал
   с «Отменить правки» и «Готово» всегда виден — растущее содержимое сжимает
   именно прокручиваемую сетку, а не выталкивает кнопки за край диалога.

   Высота задана ЯВНО, а не «по содержимому»: в Safari флекс-потомок с flex:1
   внутри диалога с высотой fit-content считается от базиса 0 и схлопывает окно
   до одной шапки (наблюдалось на живой консоли). Явная высота убирает сам
   расчёт «сколько занял контент» — сетка просто заполняет отведённое.
   flex-basis везде auto по той же причине. */
.picker[open] {
  display: flex;
  flex-direction: column;
  height: min(90vh, 980px);
}
.picker > #picker-host { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.picker__body { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.picker::backdrop {
  background: rgb(15 23 42 / 0.45);
  backdrop-filter: blur(2px);
}
.picker__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-5);
  padding: var(--space-5) var(--space-6);
  border-bottom: 1px solid var(--line);
}
.picker__head b { font-size: var(--text-md); }
.picker__sub { display: block; margin-top: 2px; font-size: var(--text-xs); color: var(--fg-muted); }

.picker__bar {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: 0 var(--space-6) var(--space-4);
}

/* Полоска дней недели: выбор дня одним нажатием, без листания сетки. */
.picker__days { display: flex; gap: var(--space-2); flex: 1; }
.picker__day-pick {
  flex: 1;
  display: grid;
  justify-items: center;
  gap: 1px;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  color: var(--fg-soft);
  cursor: pointer;
}
.picker__day-pick:hover { border-color: var(--line-strong); background: var(--bg-hover); }
.picker__day-pick.is-selected {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-fg);
}
.picker__day-pick--today .picker__date { color: var(--accent-fg); }
/* Точка «в этот день уже что-то есть»: без неё пустой и занятый день
   на полоске неразличимы. Место занимает всегда, чтобы дни не прыгали. */
.picker__day-dot { width: 4px; height: 4px; border-radius: 50%; background: transparent; }
.picker__day-dot.is-busy { background: var(--accent); }

/* ---------------------------------------------------------- лучшие слоты */
.picker__slots {
  display: grid;
  gap: var(--space-3);
  padding: 0 var(--space-6) var(--space-4);
}
.picker__slots-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  font-size: var(--text-sm);
}
.picker__slot-row { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.picker__slot { font-variant-numeric: tabular-nums; }

.picker__kinds { display: flex; gap: var(--space-2); flex-wrap: wrap; padding: var(--space-4) var(--space-6); }
.picker__kind {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--line);
  border-radius: var(--radius-full);
  background: var(--bg-sunken);
  color: var(--fg-soft);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  cursor: pointer;
}
.picker__kind:hover { border-color: var(--line-strong); }
.picker__kind.is-selected {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-fg);
}
.picker__kind-min { font-family: var(--font-mono); font-size: var(--text-2xs); color: var(--fg-muted); }

.picker__scroll {
  overflow: auto;
  /* Высоту диктует само окно (у него она явная): сетка забирает всё свободное
     место между слотами и подвалом. Свой потолок ей не нужен — он оставлял бы
     пустую полосу над кнопками на высоких экранах. */
  flex: 1 1 auto;
  min-height: 180px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.picker__grid {
  display: grid;
  grid-template-columns: 56px repeat(7, minmax(0, 1fr));
  grid-template-rows: auto 1fr;
  position: relative;
}

/* Шапка с днями и левая ось липнут к краям прокрутки: сутки высотой 1440px,
   без этого через экран прокрутки непонятно ни который час, ни который день. */
.picker__corner {
  position: sticky;
  top: 0;
  left: 0;
  z-index: 7;
  background: var(--bg-surface);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line-strong);
}
.picker__dayhead {
  position: sticky;
  top: 0;
  z-index: 6;
  display: grid;
  justify-items: center;
  gap: 1px;
  padding: var(--space-3) var(--space-2);
  background: var(--bg-surface);
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line-strong);
}
.picker__dayhead--today { background: var(--accent-soft); }
/* День, для которого посчитаны свободные слоты. Подчёркнут, а не залит:
   заливка спорила бы с «сегодня». */
.picker__dayhead--picked { box-shadow: inset 0 -2px 0 var(--accent); }
.picker__dow {
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--fg-muted);
}
.picker__dayhead--today .picker__dow { color: var(--accent-fg); }
.picker__date { font-size: var(--text-xs); font-weight: var(--weight-semi); }

.picker__axis {
  position: sticky;
  left: 0;
  z-index: 3;
  background: var(--bg-surface);
  border-right: 1px solid var(--line);
}
.picker__hour { height: calc(60 * var(--picker-pxmin)); position: relative; }
.picker__hour span {
  position: absolute;
  top: -7px;
  right: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  color: var(--fg-muted);
}
.picker__hour:first-child span { top: 2px; }

.picker__day { position: relative; border-right: 1px solid var(--line); min-width: 0; }
.picker__day--today { background: color-mix(in srgb, var(--accent-soft) 40%, transparent); }
/* Получасовая засечка — глазу нужна опора, но она не должна спорить с часовой. */
.picker__slot-cell {
  height: calc(60 * var(--picker-pxmin));
  border-bottom: 1px solid var(--line);
  background-image: linear-gradient(
    to bottom,
    transparent calc(50% - 1px),
    var(--line) 50%,
    transparent calc(50% + 1px)
  );
  background-repeat: no-repeat;
}
/* Нерабочий час приглушён: сутки видно целиком, но глаз сразу отделяет
   рабочее время от ночи — и понимает, почему слоты предлагаются не везде. */
.picker__slot-cell--off { background-color: color-mix(in srgb, var(--bg-sunken) 70%, transparent); }

.picker__now {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--picker-at) * var(--picker-pxmin));
  height: 0;
  border-top: 2px solid var(--danger);
  z-index: 4;
  pointer-events: none;
}
.picker__now span {
  position: absolute;
  top: -9px;
  left: 2px;
  padding: 1px var(--space-2);
  border-radius: var(--radius-full);
  background: var(--danger);
  color: var(--danger-on);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
}

/* Пересекающиеся касания делят ширину дня поровну и встают колонками:
   спрятанное под соседом касание — это забытое касание. Колонку считает Python
   (presenters.lay_out_day), здесь только перевод в проценты. */
.picker__event {
  position: absolute;
  top: calc(var(--picker-top) * var(--picker-pxmin));
  height: calc(var(--picker-span) * var(--picker-pxmin));
  min-height: calc(15 * var(--picker-pxmin));
  left: calc(var(--picker-col, 0) * (100% - 6px) / var(--picker-cols, 1) + 3px);
  width: calc((100% - 6px) / var(--picker-cols, 1) - 2px);
  overflow: hidden;
  display: grid;
  gap: 1px;
  align-content: start;
  padding: 3px var(--space-3);
  border: 1px solid var(--line-strong);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  cursor: grab;
  z-index: 2;
  touch-action: none;
}
.picker__event:hover { border-color: var(--accent); z-index: 5; }
/* Во время переноса блок двигается только transform-ом: браузер выполняет это
   на композиторе, не пересчитывая вёрстку. Любой переход по top/left здесь
   запрещён — он превратил бы каждое движение мыши в анимацию и дал бы рывки. */
.picker__event.is-dragging {
  cursor: grabbing;
  opacity: 0.9;
  box-shadow: var(--shadow-lg);
  z-index: 20;
  will-change: transform;
  transition: none;
  pointer-events: none;
}
.picker__event.is-removing { opacity: 0.35; pointer-events: none; }
/* Тот самый лид, ради которого открыли окно, — чтобы не перепутать с соседними. */
.picker__event--target { border-color: var(--accent); background: var(--accent-soft); }
.picker__event--clash { background: var(--warn-soft); border-left-color: var(--warn); }
/* Блок, нарисованный сразу по двойному клику, пока ответ сервера не пришёл.
   Без него клик выглядел бы как «ничего не произошло». */
.picker__event.is-pending { opacity: 0.7; border-style: dashed; }
/* Буферы встречи: видно, что блок шире самого касания. */
.picker__event--buffered { border-left-style: double; border-left-width: 5px; }
.picker__event-time {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
}
.picker__event-name {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semi);
  line-height: 1.25;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* 15–30 минут — это 18–36 пикселей: столбик подписей туда не влезает. */
.picker__event--short { display: flex; align-items: center; gap: var(--space-3); padding: 2px var(--space-3); }
.picker__event--short .picker__event-name { flex: 1; min-width: 0; }

/* Крестик удаления: проявляется при наведении и с клавиатуры. */
.picker__remove {
  position: absolute;
  top: 2px;
  right: 2px;
  z-index: 3;
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  color: var(--fg-muted);
  box-shadow: 0 0 0 1px var(--line);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--motion-fast) var(--ease-out);
}
.picker__event:hover .picker__remove,
.picker__event:focus-within .picker__remove { opacity: 1; }
.picker__remove:hover { background: var(--danger); color: var(--danger-on); box-shadow: none; }
.picker__event.is-dragging .picker__remove { opacity: 0; }

.picker__foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-4);
  padding: var(--space-4) var(--space-6) var(--space-5);
}

@media (max-width: 900px) {
  .picker { --picker-pxmin: 1px; }
  .picker__grid { grid-template-columns: 46px repeat(7, minmax(48px, 1fr)); }
}

/* ==================================================== плавающая панель дня
   Висит поверх работы, а не в потоке страницы: её смысл — быть на глазах, на
   какой бы странице сейлз ни находился.

   Положение задаётся transform-ом, а не left/top: при перетаскивании браузер
   отдаёт transform композитору и вёрстку не трогает — от этого и плавность. */
.daypanel {
  position: fixed;
  left: 0;
  top: 0;
  z-index: var(--z-widget);
  width: 344px;
  max-width: calc(100vw - 24px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-xl);
  background: color-mix(in srgb, var(--bg-surface) 94%, transparent);
  backdrop-filter: blur(12px) saturate(1.4);
  box-shadow: var(--shadow-xl);
  color: var(--fg);
}
.daypanel[hidden] { display: none; }

/* Шапка — она же ручка для переноса. touch-action, чтобы палец на телефоне
   двигал панель, а не прокручивал под ней страницу. */
.daypanel__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-5);
  cursor: grab;
  user-select: none;
  touch-action: none;
  border-bottom: 1px solid var(--line);
}
.daypanel.is-dragging .daypanel__head { cursor: grabbing; }
.daypanel.is-dragging { transition: none; will-change: transform; }
.daypanel__title { font-size: var(--text-xs); font-weight: var(--weight-semi); }
.daypanel__tools { margin-left: auto; display: flex; gap: 2px; }
.daypanel__body { overflow: auto; max-height: min(52vh, 460px); overscroll-behavior: contain; }

/* Свёрнутый вид — значок-таблетка. Тот же узел, другая одежда: так не теряются
   ни положение, ни содержимое, ни обработчики. */
.daypanel.is-mini { width: auto; border-radius: var(--radius-full); }
.daypanel.is-mini .daypanel__head { border-bottom: 0; padding: var(--space-2) var(--space-2) var(--space-2) var(--space-5); }
.daypanel.is-mini .daypanel__body { display: none; }

.daypanel__item {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--line);
  color: var(--fg);
}
.daypanel__item:last-child { border-bottom: 0; }
.daypanel__item:hover { background: var(--bg-hover); color: var(--fg); }
.daypanel__time {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--fg-soft);
}
.daypanel__body-cell { min-width: 0; display: grid; gap: 1px; }
.daypanel__name { font-size: var(--text-sm); font-weight: var(--weight-semi); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.daypanel__kind { font-size: var(--text-xs); color: var(--fg-muted); }
.daypanel__item--past { opacity: 0.5; }
.daypanel__item--current { background: var(--accent-soft); }
.daypanel__item--current .daypanel__time { color: var(--accent-fg); }

/* Черта «сейчас» — собственный ряд списка: таблетка со временем и линия к
   правому краю. Раньше это был ряд нулевой высоты с бейджем на −9px сверху:
   первым элементом списка бейдж въезжал под шапку и обрезался. */
.daypanel__now {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-5);
}
.daypanel__now span {
  flex: none;
  padding: 1px var(--space-3);
  border-radius: var(--radius-full);
  background: var(--danger);
  color: var(--danger-on);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
}
.daypanel__now::after {
  content: "";
  flex: 1;
  border-top: 2px solid var(--danger);
  border-radius: 1px;
}
.daypanel__now--done span { background: var(--line-strong); color: var(--fg-soft); font-family: var(--font-sans); }
.daypanel__now--done::after { border-top-color: var(--line-strong); }

.daypanel__empty { padding: var(--space-6) var(--space-5); color: var(--fg-muted); font-size: var(--text-xs); }
.daypanel__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-5);
  border-top: 1px solid var(--line);
  background: var(--bg-sunken);
  font-size: var(--text-xs);
  color: var(--fg-muted);
}
.daypanel__foot-date { text-transform: lowercase; }

@media (max-width: 620px) {
  .daypanel { width: calc(100vw - 24px); }
}

/* ================================================================== воронка */
.funnel { display: grid; gap: var(--space-3); }
.funnel__stage {
  display: grid;
  grid-template-columns: 190px minmax(0, 1fr) 108px;
  gap: var(--space-5);
  align-items: center;
}
.funnel__label { display: grid; gap: 1px; min-width: 0; }
.funnel__name { font-size: var(--text-sm); font-weight: var(--weight-semi); }
.funnel__detail { font-size: var(--text-xs); color: var(--fg-muted); }
.funnel__conv { display: grid; justify-items: end; gap: 1px; text-align: right; }
.funnel__pct { font-size: var(--text-md); font-weight: var(--weight-semi); color: var(--fg-soft); }
.funnel__pct--gate { color: var(--accent-fg); }
.funnel__lost { font-size: var(--text-xs); color: var(--fg-muted); }
.funnel__lost--up { color: var(--ok-fg); }
/* Стадия без своего хранилища: показываем штриховкой, чтобы воронка была ещё и
   картой готовности пайплайна, а не молча врала нулём. */
.funnel__stage--off .funnel__name { color: var(--fg-muted); }
.funnel__stage--off .bar {
  background: repeating-linear-gradient(
    45deg,
    var(--bg-hover),
    var(--bg-hover) 6px,
    transparent 6px,
    transparent 12px
  );
}
.funnel__stage--gate .bar { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent); }

@media (max-width: 900px) {
  .funnel__stage { grid-template-columns: 130px minmax(0, 1fr) 70px; }
}

/* Разрез по тирам. */
.tierbars { display: grid; gap: var(--space-3); }
.tierbar {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) 44px;
  gap: var(--space-4);
  align-items: center;
}
.tierbar__count { font-family: var(--font-mono); font-size: var(--text-sm); text-align: right; }
