/* form-ui.css */
/* ЕДИНЫЙ модуль «формовых» элементов: кнопка выбора файла + ЛОГИКА АЛЕРТОВ (подсветка неверно
   заполненных полей). ОДИН источник стилей — и /winner (src/winner.njk), и кабинет участника
   (/apply, /me — functions/member/cabinet.js) подключают ЭТОТ файл, поэтому валидация выглядит
   ОДИНАКОВО, а не «похоже». Раньше у каждой страницы была своя инлайн-копия и они разъезжались
   (на /me подсвечивалось только 1 верхнее поле, на /winner — сразу все).

   Поведение «подсветить СРАЗУ ВСЕ невалидные + проскроллить к первому» ведёт /assets/form-ui.js
   (window.HovForm). Перелив кнопок на hover — в /btn.css (он покрывает .file-btn и
   ::file-selector-button). Переменные (--cyan/--pink/--line) даёт :root каждой страницы; здесь —
   фолбэки, чтобы файл был самодостаточным. Несущий тест — tests/form-ui.test.mjs. */

/* --- Кнопка выбора файла: ОДИН стиль для кастомного лейбла (/me .file-btn) и нативной кнопки
   (/winner input[type=file]::file-selector-button). Градиент/каплс/жирный — как бренд-кнопки. --- */
.file-btn,
input[type="file"]::file-selector-button {
  display: inline-block;
  margin: 0;
  padding: 10px 18px;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  font: inherit;
  font-weight: 900;
  text-transform: uppercase;
  font-size: .8rem;
  letter-spacing: .03em;
  color: #0e1116;
  background: linear-gradient(90deg, var(--cyan, #3b5bff), var(--pink, #ffb020));
}
input[type="file"]::file-selector-button { margin-right: 14px; }

/* --- Алерты: невалидное обязательное поле — красная подсветка блока .field + розовый лейбл.
   Тот же вид для input/textarea/select, группы чекбоксов (.roles) и file-инпута. --- */
.field.invalid input,
.field.invalid textarea,
.field.invalid select { border-color: #ff5a7a; box-shadow: 0 0 0 3px rgba(255, 90, 122, .25); }
.field.invalid label { color: #ff8fb0; }
/* Инлайн-ошибка рядом с полем (валидатор на анфокус, assets/field-validate.js): конкретная причина. */
.field-err { margin-top: 5px; font-size: .78rem; font-weight: 600; color: #ff8fb0; line-height: 1.35; }
.field-err:empty { display: none; }
.field.invalid .roles { padding: 6px 8px; border: 1px solid #ff5a7a; border-radius: 8px; box-shadow: 0 0 0 3px rgba(255, 90, 122, .25); }
.field.invalid input[type="file"] { border-color: #ff5a7a; box-shadow: 0 0 0 3px rgba(255, 90, 122, .25); }
/* Универсальная подсветка ЛЮБОГО инпута с aria-invalid — даже БЕЗ .field-обёртки (напр. инлайн-формы
   org: claim/report/creds). HovForm ставит aria-invalid во всех путях валидации (validateRequired/
   requireFilled/highlightServerFields/markServerFields); снимает — глобальный live-clear по input. */
input[aria-invalid="true"], textarea[aria-invalid="true"], select[aria-invalid="true"] { border-color: #ff5a7a; box-shadow: 0 0 0 3px rgba(255, 90, 122, .25); }

/* --- Статус-строка формы: сообщение валидации/ошибки (и успех на /me). --- */
/* J3.4 — живая отметка состояния поля ПО МЕРЕ ВВОДА (не после анфокуса): выполненное поле подсвечивается
   зелёной кромкой, незаполненное обязательное — приглушённой. Только рамка, размеры не меняются, поэтому
   разметка не «дышит» под курсором (J4). Ошибку с текстом по-прежнему рисует blur-валидатор. */
.field.live-ok input, .field.live-ok textarea, .field.live-ok select { border-color: rgba(63, 185, 80, .55); }
.field.live-todo input, .field.live-todo textarea, .field.live-todo select { border-color: rgba(255, 255, 255, .18); }
.field.invalid.live-ok input, .field.invalid.live-ok textarea { border-color: var(--danger, #ff6b8a); }
/* ОШИБКА СИЛЬНЕЕ «ещё не заполнено». Правило .live-todo идёт ниже .invalid и при равной силе гасило
   красную рамку: поле, которое человека ПРЯМО СЕЙЧАС просят исправить, оставалось приглушённым, тогда
   как соседние невалидные краснели. Хуже всего это било по полю, из которого человек только что ушёл, —
   ровно туда его и отправляет сообщение «complete the highlighted fields». Цвет тот же, что у .invalid. */
.field.invalid.live-todo input, .field.invalid.live-todo textarea, .field.invalid.live-todo select { border-color: #ff5a7a; }

.status { margin: 6px 0 0; font-weight: 700; min-height: 1.2em; }
.status.error { color: #ff8fb0; }
.status.ok { color: #3fb950; }

/* --- Неблокирующий тост (ЕДИНАЯ замена браузерного alert() в экшен-формах: вступить/создать/одобрить/
   claim и т.п., + автосейв «✓ Saved» кабинета). Фикс. слева-центр (на мобиле — снизу-центр), авто-гаснет
   через 3с. По умолчанию зелёный успех с галочкой; .err — красный без галочки. См. HovForm.toast(). --- */
/* pointer-events:none — тост ИНФОРМАЦИОННЫЙ и живёт 3 с поверх формы (z-index 60): без этого он
   молча съедает клики по тому, что под ним (J4, владелец: «кнопки с 3-4 клика»). Образец с самого
   начала лежал рядом — .hov-bug-toast в assets/bug-report.css. */
.hov-toast { position: fixed; left: 18px; top: 50%; transform: translateY(-50%) scale(.96); z-index: 60; display: none; align-items: center; gap: 8px; padding: 10px 16px; border-radius: 999px; background: rgba(20, 40, 28, .97); border: 1px solid #2e7d52; color: #d6ffe6; font-weight: 800; box-shadow: 0 6px 24px rgba(0, 0, 0, .45); opacity: 0; pointer-events: none; transition: opacity .2s ease; }
.hov-toast.show { display: flex; opacity: 1; }
.hov-toast .chk { color: #3fb950; font-size: 1.05rem; }
.hov-toast.err { background: rgba(48, 16, 24, .97); border-color: #ff6b8a; color: #ffd6de; }
.hov-toast.err .chk { display: none; }
@media (max-width: 560px) { .hov-toast { left: 50%; top: auto; bottom: 18px; transform: translateX(-50%); } }

/* --- Стилизованный confirm-модал (HovForm.confirm) — замена браузерного window.confirm в дизайне сайта:
   затемнённый фон + Signal-карточка с двумя кнопками (подтвердить cobalt→amber / отмена). --- */
.hov-modal-overlay { position: fixed; inset: 0; z-index: 80; display: flex; align-items: center; justify-content: center; padding: 20px; background: rgba(8, 4, 16, .72); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); opacity: 0; transition: opacity .18s ease; }
.hov-modal-overlay.show { opacity: 1; }
.hov-modal { width: min(420px, 100%); border: 1px solid rgba(59, 91, 255, .4); border-radius: 14px; background: linear-gradient(180deg, rgba(22, 27, 34, .98), rgba(14, 17, 22, .98)); box-shadow: 0 24px 80px rgba(0, 0, 0, .5), 0 0 40px rgba(59, 91, 255, .12); padding: 24px; transform: translateY(8px) scale(.98); transition: transform .18s ease; }
.hov-modal-overlay.show .hov-modal { transform: none; }
.hov-modal-msg { margin: 0 0 20px; color: var(--ink, #e6edf3); font-size: 1rem; line-height: 1.5; font-weight: 600; }
.hov-modal-actions { display: flex; gap: 10px; justify-content: flex-end; flex-wrap: wrap; }
.hov-modal-actions button { min-height: 42px; padding: 0 18px; border-radius: 9px; font-weight: 800; cursor: pointer; font-size: .9rem; border: 1px solid transparent; }
.hov-modal-ok { color: #0e1116; background: linear-gradient(90deg, var(--cyan, #3b5bff), var(--pink, #ffb020)); box-shadow: 0 0 22px rgba(255, 176, 32, .3); }
.hov-modal-cancel { color: var(--ink, #e6edf3); background: rgba(255, 255, 255, .07); border-color: rgba(255, 255, 255, .18); }
.hov-modal-cancel:hover { border-color: rgba(255, 255, 255, .4); }
@media (prefers-reduced-motion: reduce) { .hov-modal-overlay, .hov-modal { transition: none; } }
.password-control { display:grid; grid-template-columns:minmax(0,1fr) auto; gap:8px; align-items:stretch; }
.password-control input { min-width:0; }
.password-control .password-toggle { margin:0; padding:0 14px; min-width:64px; background:transparent; color:var(--cyan); border:1px solid var(--line); box-shadow:none; font-size:.82rem; }
.password-control .password-toggle:hover, .password-control .password-toggle:focus-visible { border-color:var(--cyan); background:rgba(59,91,255,.12); animation:none; }
.pwr { margin:8px 0 0; }
.pwr-list { list-style:none; margin:0; padding:0; display:grid; gap:4px; }
.pwr-item { display:flex; align-items:center; gap:8px; font-size:.86rem; color:var(--muted); transition:color .15s ease; }
.pwr-mark { flex:none; width:14px; height:14px; border-radius:50%; border:1.5px solid currentColor; position:relative; }
.pwr-item[data-state="ok"] { color:#3fb950; }
.pwr-item[data-state="ok"] .pwr-mark::after, .pwr-mark-ok::after { content:"✓"; position:absolute; inset:-3px 0 0; font-size:12px; line-height:1; text-align:center; }
.pwr-item[data-state="fail"] { color:var(--danger); }
.pwr-item[data-state="fail"] .pwr-mark::after { content:"×"; position:absolute; inset:-4px 0 0; font-size:14px; line-height:1; text-align:center; }
.pwr-done { display:flex; align-items:center; gap:8px; margin:0; font-size:.86rem; font-weight:700; color:#3fb950; }
@media (prefers-reduced-motion:reduce) { .pwr-item { transition:none; } }
