/* campspace-ui.css — общие CSS-компоненты для ЛК персонала/владельца/родителя.
   ROADMAP 5.7 (компонентная библиотека). Требует /tokens.css (переменные --green,
   --r-sm и т.д.) — подключать после tokens.css.
   Классы извлечены из web/crm_scan.html (единственный экран, где паттерны уже
   были явно вынесены в CSS-класс, а не разбросаны инлайн по каждому экрану).
   Канон: docs/DESIGN_TOKENS_BIRCH.md. */

/* ── Badge ── */
.badge{display:inline-flex;align-items:center;padding:3px 10px;border-radius:20px;font-size:12px;font-weight:600;}
.badge.green{background:var(--green-light);color:var(--green);}
.badge.amber{background:var(--amber-light);color:var(--text);}
.badge.rose{background:var(--rose-light);color:var(--rose);}
.badge.sky{background:var(--sky-light);color:var(--sky);}
.badge.dim{background:var(--bg-input);color:var(--text-dim);}
.badge.accent{background:var(--green-light);color:var(--green);}

/* ── Chips (выбор одного из нескольких значений) ── */
.chips{display:flex;gap:8px;flex-wrap:wrap;}
.chip{
  padding:9px 14px;border-radius:var(--r-sm);border:1.5px solid var(--line-mid);
  font-size:13.5px;font-weight:600;color:var(--text-dim);background:var(--bg-card);
  /* Было `transition:all .12s` — `all` анимирует в т.ч. layout-свойства (padding,
     border-width) и заставляет браузер пересчитывать вёрстку каждый кадр.
     Перечисляем только композитные/цветовые свойства (ANIMATION_GUIDELINES.md §4). */
  transition:background-color var(--dur-fast,.16s) linear,
             border-color var(--dur-fast,.16s) linear,
             color var(--dur-fast,.16s) linear,
             transform var(--dur-fast,.16s) var(--ease-out,cubic-bezier(.16,1,.3,1));
  touch-action:manipulation;-webkit-tap-highlight-color:transparent;
}
.chip.active{background:var(--green);border-color:var(--green);color:#fff;}
/* Тактильный отклик на тап (не путать с `.chip.active` — это состояние ВЫБРАН). */
.chip:active{transform:scale(.97);}
@media (prefers-reduced-motion: reduce){ .chip:active{transform:none;} }

/* ── Table (cs-table — безопасный табличный рендер CampUI.renderTable) ── */
.cs-table{width:100%;border-collapse:collapse;font-size:13.5px;}
.cs-table th{
  text-align:left;font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--text-dim);padding:8px 10px;border-bottom:1.5px solid var(--line-mid);
}
.cs-table td{padding:9px 10px;border-bottom:1px solid var(--line);vertical-align:middle;}
.cs-table tbody tr:last-child td{border-bottom:none;}
.cs-table tbody tr:hover{background:var(--bg-card-2);}

/* ── Floating safe-zone (плавающие кнопки не перекрывают контент, UI_DESIGN_GUIDELINES.md §4) ──
   Паттерн для НОВЫХ position:fixed элементов (FAB и т.п.). Скролл-контейнер получает
   .fab-safe-bottom, а --fab-safe-h задаётся под конкретную кнопку (высота + отступ),
   обычно только в мобильном медиа-запросе — на десктопе места обычно достаточно.
   Готовый пример уже отдельно встроен в web/js/campspace_support.js (кнопка «Поддержка»
   не подключает этот файл, стили у неё свои scoped) — если появится второй floating-
   компонент вне campspace_support.js, использовать именно этот класс, а не копировать
   точечный !important-фикс заново. */
.fab-safe-bottom{padding-bottom:var(--fab-safe-h,76px)!important;}

/* ── Child card (аватар + имя + мета + статус-бейдж) ── */
.cs-child-card{display:flex;align-items:center;gap:14px;}
.cs-child-card .cs-avatar{
  width:52px;height:52px;border-radius:var(--r);background:var(--green);color:#fff;
  display:flex;align-items:center;justify-content:center;font-family:var(--disp);font-weight:700;font-size:20px;flex-shrink:0;
}
.cs-child-card .cs-cc-body{flex:1;min-width:0;}
.cs-child-card .cs-cc-name{font-family:var(--disp);font-size:19px;font-weight:700;}
.cs-child-card .cs-cc-meta{font-size:13px;color:var(--text-dim);margin-top:2px;}

/* ── Ряд действий, пригодный для телефона (UI_DESIGN_GUIDELINES.md §9.3) ──
   Заведён 2026-09-10 (task_20260909_123734_scoping_axes_implementation) по факту
   ЖИВОГО замера, а не по ощущению: раздел «Структура лагеря» на 320px давал
   горизонтальный скролл (scrollWidth 330 при docWidth 320) — единственная длинная
   кнопка не помещалась в строку и не переносилась, а тач-высота кнопок в этом ЛК
   40px при норме §3 в 44px.
   ОПТ-ИН НАМЕРЕННО: .btn скопирован в 7 CRM-файлов, и глобальное правило по .btn
   поехало бы во всех сразу — это отдельная работа по сведению кнопки к канону,
   а не побочный эффект чужой задачи. Ставится на КОНТЕЙНЕР ряда действий. */
.cs-actions{display:flex;gap:12px;flex-wrap:wrap;}
.cs-actions > .btn{max-width:100%;}
@media (max-width:768px){
  .cs-actions > .btn{min-height:44px;white-space:normal;text-align:left;}
  .cs-field-44 .form-ctrl,
  .cs-field-44.form-ctrl{min-height:44px;}
}

/* ── Поле ввода: input / select / textarea (КАНОН docs/UI_DESIGN_GUIDELINES.md §9.2) ──
   Поднято сюда 2026-09-12 (task_20260909_213823_5d8f67) из web/crm_vrach.html, где
   канон лежал локальной копией вместе с тремя другими ЛК (§9.1.1). До этого правил
   у .form-ctrl не было НИ ОДНОГО ни в одном общем файле — класс на поле стоял, а
   стиля не нёс, и поле рисовалось дефолтом браузера («сырые прямоугольники», §9.1).

   Два сознательных отличия от печатного текста §9.2:
   1. у :disabled фон var(--bg-card), а не --bg-panel: токена --bg-panel в
      web/tokens.css НЕТ (легаси тёмной палитры v1, запрещён гвардом
      test_birch_migration_*), var() без фолбэка обнулил бы фон в прозрачный;
   2. медиа-запрос min-height:44px — по ЗАМЕРУ (§9.1.1 п.2): padding 8/10 при
      font-size 13px даёт 36px, до tap-target §3 сам по себе не дотягивает.

   ГЛОБАЛЬНОЕ (не опт-ин, в отличие от .cs-actions ниже): опасение «width:100%
   сдвинет соседние поля с инлайновой геометрией» проверено живьём при раскатке
   на 4 ЛК и не подтвердилось — у полей во flex-ряду flex-basis перебивает width,
   поля с инлайновым width/max-width не изменились (§9.1.1, таблица замеров).
   У crm_v2/crm_hr/crm_director есть СВОИ локальные полные определения; они лежат
   в <style> ПОСЛЕ этого <link> и продолжают выигрывать каскад — сведение их к
   общему компоненту остаётся отдельным звеном (§9.1.1, «осталось незакрытым»). */
.form-ctrl{
  width:100%; min-width:0;
  background:var(--bg-input);
  border:1px solid var(--line);
  color:var(--text);
  padding:8px 10px;
  border-radius:var(--r-sm);
  font-size:13px;
  font-family:var(--body);
  outline:none;
  transition:border-color .15s, box-shadow .15s;
}
.form-ctrl:focus{border-color:var(--green);box-shadow:0 0 0 2px var(--green-light);}
.form-ctrl[aria-invalid="true"],.form-ctrl.is-error{border-color:var(--rose);}
.form-ctrl.is-error:focus{box-shadow:0 0 0 2px var(--rose-light);}
.form-ctrl:disabled,.form-ctrl[readonly]{opacity:.55;cursor:not-allowed;background:var(--bg-card);}
.form-ctrl[type="number"]{font-family:var(--mono);}
textarea.form-ctrl{resize:vertical;min-height:72px;}
@media (max-width:768px){.form-ctrl{min-height:44px;}textarea.form-ctrl{min-height:88px;}}

/* ── Строка списка: имя + мета + действия (UI_DESIGN_GUIDELINES.md §9.6) ──
   Обобщено 2026-09-12 (task_20260909_213823_5d8f67) из .iso-row/.iso-name/.iso-meta/
   .iso-acts панели изолятора в web/crm_vrach.html. Имя НАМЕРЕННО нейтральное: тот же
   ряд «кто — чем характеризуется — что с ним можно сделать» продублирован в соседних
   ЛК (кухня, вожатый, директор) под своими локальными именами.

   Мобильная часть — не украшение: ряд обязан ПЕРЕНОСИТЬСЯ (flex-wrap), мета —
   переноситься внутри себя (overflow-wrap:anywhere, иначе длинная причина/название
   койки даёт горизонтальный скролл, §7), а кнопки действий на <=768px обязаны брать
   44px (§3 tap-target) — на десктопе 36px, чтобы ряд оставался плотным.
   margin-left:auto прижимает действия вправо только когда ряд НЕ перенесён; после
   переноса он бы оставил кнопки висеть у правого края отдельной строкой, поэтому
   на мобильной ширине снимается. */
.cs-listrow{display:flex;flex-wrap:wrap;align-items:center;gap:8px;width:100%;}
.cs-listrow .cs-listrow-name{font-weight:600;font-size:13px;}
.cs-listrow .cs-listrow-meta{font-size:11px;color:var(--text-dim);min-width:0;overflow-wrap:anywhere;}
.cs-listrow-acts{display:inline-flex;gap:6px;margin-left:auto;}
.cs-listrow-acts .btn{display:inline-flex;align-items:center;justify-content:center;min-width:36px;min-height:36px;padding:4px 8px;font-size:12px;}
@media (max-width:768px){
  .cs-listrow-acts{margin-left:0;}
  .cs-listrow-acts .btn{min-width:44px;min-height:44px;}
}

/* ── Ошибка поля ввода (единый слой валидации, web/js/field_validation.js) ──
   Канон docs/UI_DESIGN_GUIDELINES.md §9.2 п.4: состояние ошибки живёт на
   aria-invalid самого поля (это и стиль, и доступность одним атрибутом), текст
   подсказки — СОСЕДНИЙ элемент, а не title (title не читается с телефона вообще).
   Заведено 2026-09-10, task_20260909_132233_input_validation_unification.

   ⚠️ Селектор НАМЕРЕННО привязан к [data-csv-type] (атрибут ставит валидатор),
   а не к .form-ctrl. Исходная причина (2026-09-10) — «правил .form-ctrl в этом
   файле ещё нет» — снята 2026-09-12 (task_20260909_213823_5d8f67 подняла канон,
   см. секцию выше), но привязка остаётся ОСОЗНАННО: валидатор работает и на полях
   БЕЗ класса .form-ctrl, а !important здесь нужен, чтобы перебить локальные
   определения .form-ctrl в <style> страницы (они идут в каскаде ПОЗЖЕ этого файла
   и иначе вернули бы обычную рамку полю с ошибкой). */
input[data-csv-type][aria-invalid="true"]{
  border-color:var(--rose)!important;
  box-shadow:0 0 0 2px var(--tint-rose);
}
.cs-field-err{
  display:block;
  margin-top:4px;
  font-family:var(--body);
  font-size:12px;
  line-height:1.35;
  color:var(--rose);
  overflow-wrap:anywhere;   /* §7: длинная подсказка переносится, а не режется */
}
@media (max-width:768px){
  /* На телефоне подсказка — единственный канал объяснения ошибки: не мельчим
     ниже 12px (§7.4) и оставляем воздух, чтобы она не липла к следующему полю. */
  .cs-field-err{font-size:12px;margin-bottom:2px;}
}
