Newer
Older
gnexus-tasks / frontend / src / kit-overrides.css
/* Точечные переопределения кита (публичные классы .chip/.badge/.tag-input):
   аперкейс кит ставит всем бейджам/чипам глобально, но теги должны читаться
   в оригинальном регистре (имена тегов регистрозависимы по смыслу). Прочие
   бейджи (статус/приоритет/проект/время) остаются как в ките. */
.tag-input .chip,
.tag-suggest .chip,
.tag-badge {
  text-transform: none;
}

/* Спиннер обновления данных: под топбаром в правом углу, контент не сдвигает */
.refresh-loader {
  position: fixed;
  top: 66px;
  right: 18px;
  z-index: 500;
}
/* --- iOS Safari (типовые проблемы, 2026-09-23) --- */

/* Зум полей при фокусе: iOS Safari автоматически зумит страницу, если у поля
   font-size < 16px, и зум застревает после blur (ломает весь layout). У кита
   поля/селекты 15px (наследуют body), поле тегов 13px — на touch-устройствах
   поднимаем до 16px; на десктопе вид не меняется. */
@media (hover: none) and (pointer: coarse) {
  .form-group .label .input,
  .form-group .label .select-wrap .select,
  .tag-input .tag-input-field {
    font-size: 16px;
  }
}

/* 100vh в iOS Safari выше видимой области (учитывает свёрнутую панель) — низ
   drawer'ов/модалок уезжает под панель браузера и индикатор «домой». dvh —
   фактическая высота (Safari 15.4+); на старых Safari невалидное значение
   игнорируется и остаётся китовский 100vh. */
.drawer .drawer-panel {
  min-height: 100dvh;
}
.nav-drawer {
  max-height: 100dvh;
  padding-bottom: env(safe-area-inset-bottom);
}
.modal .modal-dialog {
  max-height: calc(100dvh - 48px);
}

/* viewport-fit=cover: контент уходит под жест-индикатор «домой» и «чёлку».
   Тосты прижаты к bottom:15px кита — поднимаем на safe-area; в браузерном
   Safari inset снизу = 0, поведение не меняется. */
.toast.a-show {
  bottom: calc(15px + env(safe-area-inset-bottom));
}
/* контент drawer'а не упирается в индикатор «домой» */
.drawer .drawer-body {
  padding-bottom: calc(18px + env(safe-area-inset-bottom));
}
/* в PWA (standalone) верх страницы уходит под статус-бар: топбар отступает
   (в браузере inset = 0) */
.nav-topbar {
  padding-top: env(safe-area-inset-top);
}
/* спиннер обновления держится ниже топбара, который в PWA становится выше */
.refresh-loader {
  top: calc(66px + env(safe-area-inset-top));
}

/* Серая тап-подсветка WebKit поверх кнопок/чипов/ссылок — не в стиле кита.
   Активное состояние у кита есть (media hover:none) — подсветка не нужна. */
a,
button,
.chip,
.badge,
.tag-input-wrap {
  -webkit-tap-highlight-color: transparent;
}

/* iOS иногда раздувает текст при повороте в landscape — запрещаем */
html {
  -webkit-text-size-adjust: 100%;
}

/* --- Скругление полос прокрутки (0.76, пересмотрено 0.79) --- */
/* Толщину и цвета оставляем китовыми: 10px, дорожка #16161e, бегунок #414868,
   кнопок нет (у кита это глобальное правило; своя полоса — только у
   .nav-drawer-body: 8px, #7aa2f7 по #1f2335). Просили «цвет оставить как было,
   просто скруглить» — здесь только радиус и ничего больше.
   `scrollbar-width` / `scrollbar-color` НЕ выставляем: как только они заданы,
   Chromium игнорирует `::-webkit-scrollbar-*` целиком, и скругление пропадает
   (в 0.76 так и вышло: тонкая полоса акцентного цвета с прозрачной дорожкой —
   акцентный бегунок читался поверх шапки). У `.tabs-list` и `.nav-drawer-body`
   эти свойства уже стоят у кита, там полосы остаются как были. */
::-webkit-scrollbar-thumb {
  border-radius: 999px;
}

/* --- Подвал карточки (0.76, отступы выровнены в 0.81) --- */
/* У кита `.card .card-footer` — просто полоса с отступами: ни границы, ни
   раскладки, ни своего размера (flex/13px есть только у горизонтального
   варианта), да ещё и отступы несимметричны — 8px сверху против 15px снизу,
   из-за чего строка подвала висела на 3.5px выше середины полосы. Здесь общий
   вид подвала для карточек задач и проектов: черта-разделитель во всю ширину
   карточки (1px — как у прочих внутренних разделителей в приложении; рамка
   самой карточки 2px и с ней не спорит), мягкий текст мельче основного и равные
   отступы сверху и снизу, поэтому строка стоит ровно по центру полосы.
   12px, а не точные 11.5px — округление; полоса от этого выше прежней ровно на
   пиксель (43px → 44px).
   min-height держит полосу одной строкой: у проекта без задач и без срока она
   пустая и иначе схлопнулась бы в 25px (отступы + черта), а черта встала бы на
   разной высоте у соседей по ряду. 25px — это те же 12px сверху и снизу плюс
   черта: min-height у рамки, а не у содержимого (кит ставит box-sizing:border-box) */
.card .card-footer {
  padding: 12px 15px;
  min-height: calc(1.6em + 25px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  border-top: 1px solid var(--gn-border-color-muted, rgba(192, 202, 245, 0.24));
  color: var(--gn-color-text-medium, #a9b1d6);
  font-size: 0.85em;
}

/* --- Дропдауны на мобильных: шторка снизу (0.77) --- */
/* Кит позиционирует меню от левого края триггера (position:absolute; left:0,
   min-width:220px) — на телефоне у триггеров у правого края меню уезжало за
   вьюпорт, и координаты приходилось клампить инлайном на каждый клик
   (dropdownClamp.ts). До 767px меню вместо этого становится шторкой снизу:
   панель во всю ширину + затемнение под ней. Это штатная мобильная замена
   выпадашки (так делают и нативные листы действий), и заодно снимает всю
   возню с координатами. Затемняющий слой — статичный div в index.html. */
.dropdown-backdrop {
  display: none;
}
@media (max-width: 767px) {
  /* Затемнение. Слой в body (вне .dropdown) — поэтому клик по нему для китового
     обработчика «вне меню», и меню закрывается само; показан ровно тогда, когда
     где-то открыт дропдаун */
  body:has(.dropdown.is-open) .dropdown-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 1090;
    background: var(--gn-color-black, #16161e);
    opacity: 0.72;
  }
  /* Китовый panel_boot оставляет у шапки transform (заливка both), а transform
     делает элемент содержащим блоком для position:fixed: шторка «⋯» из шапки
     раскладывалась бы по шапке, а не по экрану. Снимаем анимацию только на
     мобильных — на десктопе она нужна как есть */
  .app-content .page-header {
    animation: none;
  }
  .dropdown.is-open .dropdown-menu {
    position: fixed;
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1100;
    min-width: 0;
    max-width: none;
    max-height: 70vh;
    /* dvh — фактическая высота (Safari 15.4+); старые браузеры оставляют 70vh */
    max-height: 70dvh;
    overflow-y: auto;
    /* прокрутка шторки не «протекает» в страницу под ней */
    overscroll-behavior: contain;
    /* панель прижата к низу экрана — нижняя рамка ушла бы под край */
    border-bottom: 0;
    /* акцентная полоса слева (6px) у панели во всю ширину читается обрубком */
    border-left-width: var(--gn-border-width-base, 2px);
    border-radius: 12px 12px 0 0;
    /* снизу — запас под жест-индикатор «домой»; в браузере inset = 0. 12px, а не
       китовые 5px: последний пункт у самого края экрана читается обрезанным */
    padding: 6px 5px calc(12px + env(safe-area-inset-bottom, 0px));
    animation: gn-dropdown-sheet 0.22s ease both;
  }
  /* «ручка» — примета листа снизу: без неё панель читается просто выпадашкой,
     зачем-то прилипшей к низу */
  .dropdown.is-open .dropdown-menu::before {
    content: '';
    display: block;
    width: 36px;
    height: 4px;
    margin: 2px auto 6px;
    border-radius: 999px;
    background: var(--gn-border-color-muted, rgba(192, 202, 245, 0.24));
  }
  /* Под палец: китовые 34px и 13px мелковаты для шторки во всю ширину */
  .dropdown.is-open .dropdown-menu .dropdown-item {
    min-height: 44px;
    padding: 12px 15px;
    font-size: 14px;
  }
  @keyframes gn-dropdown-sheet {
    from {
      opacity: 0;
      transform: translateY(100%);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }
}