:root {
  --bg: #F6F7FA;
  --surface: #FFFFFF;
  --surface-2: #F0F2F7;
  --surface-3: #E7EAF1;
  --border: #E1E5EE;
  --border-strong: #C9D0DD;
  --text: #12161C;
  --muted: #59636F;
  --dim: #646D79;
  --accent: #2F5D96;
  --accent-h: #254E82;
  --accent-tint: #E9EFF8;
  --on-accent: #FFFFFF;
  --ok: #1E7A4D;
  --ok-tint: #E6F2EB;
  --warn: #9C6608;
  --warn-tint: #F9F0DD;
  --err: #B23429;
  --err-tint: #FAE9E6;
  --shadow-1: 0 1px 2px rgba(16,24,40,.05);
  --shadow-2: 0 8px 24px -8px rgba(16,24,40,.16);
  --shadow-3: 0 24px 60px -20px rgba(16,24,40,.28);
}
:root[data-theme="dark"] {
  --bg: #0D1116;
  --surface: #141922;
  --surface-2: #1B212B;
  --surface-3: #232B37;
  --border: #252D39;
  --border-strong: #39434F;
  --text: #E6EAF1;
  --muted: #9AA4B2;
  --dim: #99A3AF;
  --accent: #7099D2;
  --accent-h: #8CADDE;
  --accent-tint: #16243A;
  --on-accent: #0B0F14;
  --ok: #4FAE7C;
  --ok-tint: #122318;
  --warn: #CE9A3C;
  --warn-tint: #251E10;
  --err: #DB6A5D;
  --err-tint: #271513;
  --shadow-1: 0 1px 2px rgba(0,0,0,.4);
  --shadow-2: 0 8px 24px -8px rgba(0,0,0,.6);
  --shadow-3: 0 24px 60px -20px rgba(0,0,0,.75);
}
* { box-sizing: border-box; }
/* Кусок Tailwind preflight, который у нас выключен (corePlugins.preflight:false).
   Утилита tw-border-solid задаёт border-style на ВСЕ четыре стороны, а ширину ставит
   только направленная утилита (tw-border-b — лишь снизу). Без этого сброса остальным
   сторонам достаётся initial `border-width: medium` = 3px, и вместо хайрлайна снизу
   элемент получает рамку-прямоугольник. Затронуто был 121 элемент в 14 шаблонах.
   Ни одно правило в проекте не рассчитывает на дефолтную ширину — проверено. */
*, ::before, ::after { border-width: 0; }
[hidden] { display: none !important; }
button, input, select, textarea { font-family: inherit; font-variant-numeric: inherit; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }


/* input[type=file]: dashed drop-zone вместо голого системного виджета */
input[type=file] {
  width: 100%; padding: 11px 12px; border-radius: 10px;
  border: 1px dashed var(--border); background: var(--surface-2); color: var(--muted); font: inherit; font-size: 13px;
}
input[type=file]:hover { border-color: #ccd5e6; }
input[type=file]:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); }
input[type=file]::file-selector-button {
  margin-right: 12px; padding: 7px 14px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--accent); border-color: var(--accent); color: var(--on-accent); font: inherit; font-weight: 600; font-size: 13px;
  cursor: pointer; transition: background .15s;
}
input[type=file]::file-selector-button:hover { background: var(--accent-h); }

.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); box-shadow: 0 4px 14px rgba(59,130,246,.25); }
.btn-primary:hover { background: var(--accent-h); border-color: var(--accent-h); }
.btn-danger { background: var(--surface); border-color: #f0c9c9; color: #c0362f; }
.btn-danger:hover { background: #fdf1f1; border-color: #e6b0b0; }

/* индикация загрузки (спиннер, читаемый на светлом) */
@keyframes cf-spin { to { transform: rotate(360deg); } }
.btn.is-loading, .btn.htmx-request, .btn-big-primary.is-loading, .btn-big-primary.htmx-request { position: relative; color: transparent !important; pointer-events: none; }
.btn.is-loading::after, .btn.htmx-request::after, .btn-big-primary.is-loading::after, .btn-big-primary.htmx-request::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 15px; height: 15px;
  margin: -8px 0 0 -8px; border-radius: 50%;
  border: 2px solid rgba(80,100,140,.25); border-top-color: var(--accent); animation: cf-spin .6s linear infinite;
}
.btn-primary.is-loading::after, .btn-primary.htmx-request::after, .btn-big-primary.is-loading::after, .btn-big-primary.htmx-request::after { border-color: rgba(255,255,255,.45); border-top-color: var(--on-accent); }
.btn:disabled { opacity: .6; cursor: default; }

.tab.active { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

/* ===== индикация «воркер сейчас занят этой задачей» =====
   Цвет — амбер (--warn), тот же, что у метки «Идёт»; зелёный в этой системе
   уже занят под «Готово», крутящееся зелёное кольцо противоречило бы статусу. */
@keyframes rd-spin { to { transform: rotate(1turn); } }
@keyframes rd-blink { 50% { opacity: .3; } }
/* кольцо-комета вокруг № строки */
.rd-idx.working::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 40deg, var(--warn) 330deg);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 1.5px), #000 calc(100% - 1.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 1.5px), #000 calc(100% - 1.5px));
  animation: rd-spin 1s linear infinite;
}
/* пульс квадратика статуса — единственный «живой» сигнал на мобильном,
   где колонка № скрыта целиком */
.mark.run .sq { animation: rd-blink 1.4s ease-in-out infinite; }

/* «Дополнительно» — прогрессивное раскрытие формы
   ВАЖНО: класс намеренно не содержит "adv" — рекламные блокировщики (EasyList и
   аналоги) генерик-правилом ##.adv скрывают любой элемент с таким классом,
   независимо от контекста; блок выше пропадал у части пользователей после
   перезагрузки страницы именно по этой причине. */
details.disclosure > summary::-webkit-details-marker { display: none; }
details.disclosure > summary::before { content: "▸"; color: var(--muted); margin-right: 8px; font-size: 11px; }
details.disclosure[open] > summary::before { content: "▾"; }

/* Кольцо-комета вокруг текущего кружка, пока воркер реально занят этой
   задачей — тот же приём (conic-gradient + radial-mask) и цвет, что уже
   использует .rd-idx.working::before в списке задач, только крупнее под
   30px-кружок. node-live добавляется в шаблоне ТОЛЬКО когда c.state=='active'
   И is_processing — на гейтах (ожидание пользователя) карточка тоже 'active',
   но воркер не работает, крутящееся кольцо там было бы обманом. */
.node.cur.node-live .bead::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 40px; height: 40px; margin: -20px 0 0 -20px; border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 40deg, var(--warn) 330deg);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
  animation: rd-spin 1s linear infinite;
}

/* уважаем системную настройку «меньше движения»: кольца/квадратики остаются
   статичными, пульсации выключаются — индикация не теряется, движение уходит */
@media (prefers-reduced-motion: reduce) {
  .rd-idx.working::before, .mark.run .sq, .node.cur.node-live .bead::before { animation: none; }
}

video { max-width: 100%; border-radius: 12px; border: 1px solid var(--border); background: #000; }

/* ползунки микшера */
input[type=range] { -webkit-appearance: none; appearance: none; width: 100%; height: 5px; border-radius: 5px; background: var(--border); outline: none; margin: 10px 0; }
input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 17px; height: 17px; border-radius: 50%; background: #fff; border: 3px solid var(--accent); cursor: pointer; box-shadow: 0 1px 4px rgba(30,40,60,.2); }
input[type=range]::-moz-range-thumb { width: 17px; height: 17px; border-radius: 50%; background: #fff; border: 3px solid var(--accent); cursor: pointer; }

/* editorial mode-tabs (подчёркивание вместо пилюль) — форма создания и верхний уровень (напр. Настройки) */
.tabs-underline .tab.active { background: transparent; color: var(--accent); border-bottom-color: var(--accent); }


/* --- шаблоны наложения --- */
.template-card > summary::-webkit-details-marker { display: none; }
.edit-rect .handle::before {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: 44px; height: 44px; transform: translate(-50%, -50%);
}

/* превью вписывания внутри нарисованной рамки: два вложенных кадрирования
   (обёртка + object-fit) математически сводятся ровно к тому же смещению
   fy*(Sh-bh), что и обрезка в ffmpeg, — поэтому формулу не дублируем;
   клиппинг вынесен в .fit-clip, а не на .frame-rect, чтобы не резать
   хит-тестинг ручки ресайза и маркера фокуса, которые стоят на краях рамки */
.focus-dot {
  position: absolute; width: 14px; height: 14px; margin: -7px 0 0 -7px;
  border-radius: 50%; border: 2px solid #fff; background: var(--accent);
  box-shadow: 0 1px 6px rgba(0,0,0,.45); cursor: grab; z-index: 3; touch-action: none;
}


/* Coloris color-picker: свотч-поля в панели субтитров */
/* .clr-field — DOM генерируется вендорной библиотекой Coloris в рантайме, недостижим из шаблонов; постоянный vendor override, не подлежит Tailwind-миграции */
.clr-field button { border-radius: 5px; }



/* сегмент-контрол источника: Ссылка | Файл */
.seg button.on { background: var(--surface); color: var(--text); box-shadow: 0 1px 3px rgba(30,40,60,.12); }

/* плавающая панель массовых действий — прижата к низу экрана, появляется когда
   отмечена хотя бы одна задача (иначе занимала бы место впустую весь остальной раздел) */
.bulk-bar {
  position: fixed; left: 50%; bottom: 18px; transform: translate(-50%, 140%);
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 14px 34px rgba(20,30,55,.18); padding: 10px 14px;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  max-width: calc(100vw - 32px); z-index: 35;
  transition: transform .22s cubic-bezier(.4,0,.15,1);
}
.bulk-bar.visible { transform: translate(-50%, 0); }

/* ненавязчивые уведомления вместо alert() — сверху по центру, чтобы не пересекаться
   с .bulk-bar (тот прижат к низу) */
#toast-stack { position: fixed; top: 14px; left: 50%; transform: translateX(-50%); z-index: 60; display: flex; flex-direction: column; gap: 8px; align-items: center; pointer-events: none; }
.toast {
  background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: 10px; box-shadow: 0 14px 34px rgba(20,30,55,.18); padding: 10px 16px;
  font-size: 13.5px; color: var(--text); max-width: min(420px, calc(100vw - 32px));
  cursor: pointer; pointer-events: auto;
  opacity: 0; transform: translateY(-8px); transition: opacity .18s, transform .18s;
}
.toast.visible { opacity: 1; transform: translateY(0); }
.toast-error { border-left-color: var(--err); }

/* модалка подтверждения взамен confirm() — оболочка (id-правило display:grid ниже)
   остаётся здесь; косметика (.confirm-backdrop/.confirm-box/.pcm-*) переехала на
   tw-* в base.html — см. docs/superpowers/specs/2026-08-11-tailwind-modals-migration-design.md */
body.modal-open { overflow: hidden; }
#confirm-modal, #project-create-modal, #client-create-modal { position: fixed; inset: 0; z-index: 70; display: grid; place-items: center; padding: 16px; }

/* ===== мобильная раскладка (≤768px) ===== */
@media (max-width: 768px) {
  /* плавающий bulk-dock: над bottom-nav (54px incl. safe-area), не под ним */
  .bulk-bar { left: 12px; right: 12px; bottom: calc(66px + env(safe-area-inset-bottom, 0px)); transform: translateY(140%); max-width: none; }
  .bulk-bar.visible { transform: translateY(0); }
}



@media (max-width: 768px) {
  .nav-tree {
    position: fixed; top: 0; left: 0; bottom: 0; width: 80vw; max-width: 300px;
    background: var(--surface); z-index: 50; padding: 12px;
    transform: translateX(-100%); transition: transform .2s ease; overflow-y: auto;
    box-shadow: 2px 0 16px rgba(0,0,0,.2);
  }
  .nav-tree.open { transform: translateX(0); }
  .nav-tree-backdrop {
    display: none; position: fixed; inset: 0; background: rgba(0,0,0,.3); z-index: 40;
  }
  .nav-tree-backdrop.open { display: block; }
}

@media (min-width: 769px) {
  .as-switcher.open .as-switcher-chev { transform: rotate(180deg); }

  .as-switcher.open .as-switcher-menu { display: block; }

  html.sidebar-collapsed .app-sidebar { width: 60px; align-items: center; padding: 16px 8px; overflow: visible; }
  html.sidebar-collapsed .as-top { flex-direction: column; gap: 10px; }
  html.sidebar-collapsed .as-client { display: none; }
  html.sidebar-collapsed .as-collapse-btn svg { transform: rotate(180deg); }
  html.sidebar-collapsed .as-switcher-trigger { justify-content: center; padding: 8px; }
  html.sidebar-collapsed .as-switcher-label,
  html.sidebar-collapsed .as-switcher-chev { display: none; }
  html.sidebar-collapsed .as-switcher-menu { left: 100%; top: 0; margin-left: 8px; width: 220px; right: auto; }
  html.sidebar-collapsed .as-menu-item { justify-content: center; padding: 9px; }
  html.sidebar-collapsed .as-menu-label { display: none; }
}

