/* ================================================================
   cabinet-overrides.css
   ================================================================
   Cabinet-specific visual overrides.

   ПРАВИЛО: все правки специфичные для кабинета (/dashboard,
   /settings, /editor и т.д.) добавляются СЮДА, а не в
   components.css (минифицирован, ручная правка опасна).

   Порядок загрузки: combined.css → components.css →
                     tailwind.min.css → cabinet-overrides.css
   Последний в цепочке — побеждает при равной специфичности.
   ================================================================ */


/* ── 0. DESIGN TOKENS ───────────────────────────────────────────
   Единые переменные масштаба — все компоненты кабинета должны
   ссылаться на эти токены вместо hardcoded значений.
   ──────────────────────────────────────────────────────────────── */

:root {
  /* Border-radius scale */
  --radius-sm: 0.25rem;   /* 4px  — badge, kbd, status-pill */
  --radius-md: 0.5rem;    /* 8px  — input, form-field */
  --radius-lg: 0.75rem;   /* 12px — button, card, modal-inner */
  --radius-xl: 1rem;      /* 16px — modal dialog, featured card */
}

/* Typography micro-scale — replaces Tailwind arbitrary text-[Npx].
   Использует rem чтобы уважать browser base font (accessibility). */
.text-8   { font-size: 0.5rem;      line-height: 1.2; }
.text-9   { font-size: 0.5625rem;  line-height: 1.2; }
.text-10  { font-size: 0.625rem;   line-height: 1.3; }
.text-105 { font-size: 0.65625rem; line-height: 1.3; }
.text-11  { font-size: 0.6875rem;  line-height: 1.3; }
.text-115 { font-size: 0.71875rem; line-height: 1.35; }
.text-13  { font-size: 0.8125rem;  line-height: 1.4; }
.text-15  { font-size: 0.9375rem;  line-height: 1.4; }
.text-17  { font-size: 1.0625rem;  line-height: 1.4; }
.text-26  { font-size: 1.625rem;   line-height: 1; }


/* ── 1. GRADIENT BACKGROUND ─────────────────────────────────────
   Источник градиента — ТОЛЬКО mesh-bg (base.html).
   mesh-bg: position:fixed; inset:0 → покрывает весь viewport (0,0)
   без обрезки, включая область хедера.

   cabinet-main начинается на top:56px — если бы градиент был там,
   получался бы видимый шов между хедером и кабинетом.

   Решение:
   1. Усиленные значения opacity у mesh-bg (раньше были слишком
      слабыми — 0.07/0.03, желтый на бежевом был незаметен)
   2. cabinet-content-area прозрачен — mesh-bg виден в зазорах
   3. surface-card в кабинете полупрозрачный (glass-эффект) —
      mesh-bg просвечивает сквозь карточки

   Desktop/mobile разбиты по @media — разные размеры градиентов:
   • Mobile (≤767px): нет sidebar → градиент во весь экран, сильнее
   • Desktop (≥768px): sidebar перекрывает 256px слева, контент правее
   ──────────────────────────────────────────────────────────────── */

/* Light — desktop */
.mesh-bg {
  background:
    radial-gradient(1200px 800px at 0%   0%,   rgba(255, 214,  10, 0.22), transparent 55%),
    radial-gradient(1200px 800px at 100% 0%,   rgba(175,  82, 222, 0.12), transparent 55%),
    radial-gradient(1000px 600px at 50%  100%, rgba( 52, 199,  89, 0.08), transparent 45%),
    radial-gradient( 800px 600px at 10%  80%,  rgba(255, 159,  10, 0.06), transparent 45%),
    var(--color-bg);
}

/* Light — mobile (сильнее: нет sidebar → градиент занимает весь экран) */
@media (max-width: 767px) {
  .mesh-bg {
    background:
      radial-gradient(100vw 60vh at 0%   0%,   rgba(255, 214,  10, 0.30), transparent 65%),
      radial-gradient(100vw 60vh at 100% 0%,   rgba(175,  82, 222, 0.18), transparent 65%),
      radial-gradient(100vw 55vh at 50%  100%, rgba( 52, 199,  89, 0.10), transparent 55%),
      var(--color-bg);
  }
}

/* Dark — desktop */
.dark .mesh-bg {
  background:
    radial-gradient(ellipse 140% 110% at 0%   0%,  rgba(255, 214,  10, 0.16), transparent 100%),
    radial-gradient(ellipse 140% 110% at 100% 0%,  rgba(175,  82, 222, 0.12), transparent 100%),
    radial-gradient(ellipse 160%  70% at 50%  0%,  rgba(120,  60, 200, 0.06), transparent 100%),
    radial-gradient(ellipse 120%  90% at 50%  100%, rgba( 48, 209,  88, 0.06), transparent 100%),
    #121214;
}

/* Dark — mobile (сильнее) */
@media (max-width: 767px) {
  .dark .mesh-bg {
    background:
      radial-gradient(ellipse 140% 65% at 0%   0%,  rgba(255, 214,  10, 0.22), transparent 100%),
      radial-gradient(ellipse 140% 65% at 100% 0%,  rgba(175,  82, 222, 0.18), transparent 100%),
      radial-gradient(ellipse 100% 55% at 50%  100%, rgba( 48, 209,  88, 0.08), transparent 100%),
      #121214;
  }
}


/* ── 2. GLASS CARDS IN CONTENT AREA ─────────────────────────────
   surface-card в кабинете полупрозрачен → mesh-bg просвечивает
   сквозь карточки (glass morphism). Специфичность (0,2,0) >
   :where()-нулевая из components.css → всегда побеждает.
   ──────────────────────────────────────────────────────────────── */

/* Light */
.cabinet-content-area .surface-card {
  background: rgba(255, 255, 255, 0.72);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

/* Dark */
.dark .cabinet-content-area .surface-card {
  background: rgba(18, 18, 20, 0.78);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}


/* ── 3. CONTENT AREA ────────────────────────────────────────────
   Прозрачный — mesh-bg виден в зазорах вокруг карточек.
   ──────────────────────────────────────────────────────────────── */

.cabinet-content-area {
  background: transparent;
}


/* ── 3.1 FIX: ::before GRADIENT SEAM AT SIDEBAR EDGE ────────────
   В components.css `.cabinet-content-area::before` имеет
   `left: clamp(0px,14vw,240px); top: 3.5rem` — градиент начинается
   от правого края сайдбара, отсюда видимый шов между сайдбаром и
   контентом (две гарантированно разные «зоны» с цветом).

   Фикс: extend ::before на весь viewport (left:0; top:0). Пик
   жёлтого "at 15% 20%" окажется внутри области сайдбара (~15vw),
   и к правому краю сайдбара градиент уже сходит на нет — плавный
   переход без шва. Сайдбар (z:130) остаётся непрозрачным сверху,
   но цветной шов исчезает.
   ──────────────────────────────────────────────────────────────── */

.cabinet-content-area::before {
  left: 0;
  top: 0;
}



/* ── 5. SIDEBAR DESKTOP COLLAPSE ────────────────────────────────
   JS (header_app.html) добавляет .sidebar-collapsed на desktop (lg+)
   вместо -translate-x-full (mobile-drawer поведение).
   ──────────────────────────────────────────────────────────────── */

@media (min-width: 1024px) {
  #cabinetSidebar.sidebar-collapsed {
    display: none;
  }
}


/* ── 6. TASK ROW SEPARATION ─────────────────────────────────────
   В components.css `.task-row` имеет border opacity 5-7% — карточки
   почти сливаются. Усиливаем разделение на обеих темах:
   • opacity бордера ×3 (light .07→.18, dark .05→.20)
   • gap между рядами 4px → 8px
   • subtle shadow для depth
   Левый source-цвет (зелёный/красный/синий) — НЕ трогаем.
   ──────────────────────────────────────────────────────────────── */

#tasksListInner {
  gap: 8px;
  padding: 6px 0 8px;
}

/* Light — НЕ трогаем border-left (это source-цвет) */
.task-row {
  border-top-color: rgba(60, 50, 30, 0.18);
  border-right-color: rgba(60, 50, 30, 0.18);
  border-bottom-color: rgba(60, 50, 30, 0.18);
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 1px 2px rgba(47, 42, 35, 0.04), 0 4px 12px -4px rgba(47, 42, 35, 0.06);
}

.task-row:hover {
  border-top-color: rgba(60, 50, 30, 0.28);
  border-right-color: rgba(60, 50, 30, 0.28);
  border-bottom-color: rgba(60, 50, 30, 0.28);
  box-shadow: 0 2px 4px rgba(47, 42, 35, 0.08), 0 8px 20px -6px rgba(47, 42, 35, 0.12);
}

/* Dark */
html.dark .task-row {
  border-top-color: rgba(255, 255, 255, 0.20);
  border-right-color: rgba(255, 255, 255, 0.20);
  border-bottom-color: rgba(255, 255, 255, 0.20);
  background: rgba(255, 255, 255, 0.05);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.30), 0 4px 12px -4px rgba(0, 0, 0, 0.35);
}

html.dark .task-row:hover {
  border-top-color: rgba(255, 255, 255, 0.32);
  border-right-color: rgba(255, 255, 255, 0.32);
  border-bottom-color: rgba(255, 255, 255, 0.32);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.40), 0 8px 20px -6px rgba(255, 214, 10, 0.10);
}


/* ── 5. STICKY FILTER PANEL ─────────────────────────────────────
   Полное определение .ws-sticky-panel — в components.css.
   ПОЧЕМУ отрицательные top: position:sticky внутри overflow-y:auto
   считает top от content-edge (внутри padding), а не padding-edge.
   top:-N, где N = padding-top контейнера → прилипание без зазора.
   ──────────────────────────────────────────────────────────────── */
/* правила .ws-sticky-panel уже в components.css, не дублировать */


/* ================================================================
   СЮДА добавлять новые cabinet-overrides:
   ─ состояния/модификаторы cabinet-main, sidebar, bottom-nav
   ─ анимации специфичные для кабинета
   ─ responsive tweaks для экранов кабинета
   НЕ редактировать components.css вручную.
   ================================================================ */


/* ================================================================
   MOBILE TOUCH TARGET FIXES (2026-05-08 mobile audit P1)
   Apple HIG / Material требуют минимум 44×44px для тач-таргетов.
   На <md экранах увеличиваем pills и pseudo-touch-area для checkbox.
   ================================================================ */

@media (max-width: 767px) {
  /* Фильтр-табы (Все / Файлы / Встречи / Заметки / API) — 44px высота */
  .ws-filter-tab {
    padding: 11px 13px;
    min-height: 44px;
    font-size: 0.8125rem;
  }

  /* Статус-дропдаун кнопка — 40px высота */
  .ws-status-dropdown-btn {
    padding: 10px 12px;
    min-height: 40px;
    font-size: 0.75rem;
  }

  /* Voice-pill (Запись/Голосовой блокнот) — 40px высота */
  .ws-voice-pill {
    padding: 10px 14px !important;
    min-height: 40px !important;
    font-size: 0.75rem;
  }

  /* Чекбокс выбора задачи — invisible pseudo-touch-area 44×44 вокруг 18×18 box.
     Сам чекбокс остаётся компактным визуально, но кликабельная область большая.
     Visually unchanged, тач-таргет ≥44px. */
  .task-select-cb {
    position: relative;
  }
  .task-select-cb::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 44px;
    height: 44px;
    z-index: 1;
  }
}


/* ================================================================
   FILTER TABS FADE INDICATOR (2026-05-08 mobile audit P1)
   .ws-filter-tabs-scroll уже имеет mask-image с gradient справа,
   но subtle и не работает в parallax с background. Добавляем
   явный pseudo-element fade поверх — visible visual cue.
   JS в dashboard.js (initTabsScrollHint) выставляет класс
   .tabs-no-overflow когда нет overflow; используем :not() для
   обратной логики: fade виден когда есть скролл.
   ================================================================ */

.ws-sticky-panel .ws-filter-tabs-scroll {
  position: relative;
}

/* Fade на правом крае только когда есть overflow */
.ws-sticky-panel .ws-filter-tabs-scroll:not(.tabs-no-overflow)::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  width: 36px;
  pointer-events: none;
  z-index: 2;
  background: linear-gradient(
    to right,
    rgba(255, 255, 254, 0) 0%,
    rgba(255, 255, 254, 0.95) 100%
  );
}

html.dark .ws-sticky-panel .ws-filter-tabs-scroll:not(.tabs-no-overflow)::after {
  background: linear-gradient(
    to right,
    rgba(10, 10, 12, 0) 0%,
    rgba(10, 10, 12, 0.95) 100%
  );
}


/* ================================================================
   HEADER OPTIMIZATION FOR EXTREME NARROW (≤359px)
   На iPhone SE 1-го поколения (320px) avatar обрезался справа.
   Скрываем «Профи»-pill (план) на ультра-узких экранах —
   план виден в /settings и в /pricing, на header-е дублирование
   отъедает критичные пиксели. Burger + logo + bell + avatar остаются.
   themeBtn уже `hidden lg:flex` — не виден на mobile, не трогаем.
   ================================================================ */

@media (max-width: 359px) {
  /* Скрыть pill «План» (ссылка /pricing в header) на extreme small */
  header a[href="/pricing"] {
    display: none !important;
  }
}


/* ================================================================
   PREMIUM-FEEL POLISH PASS (light-theme audit 2026-05-08)

   Цель: выровнять кабинет под уровень Linear / Stripe / Notion.
   Все правки — light-only переопределения tailwind/components.css.
   Dark-тема не трогается (отдельный pass).

   Структура:
   ─ A) Form controls: rounded inputs, focus visible
   ─ B) Sidebar plan-card: 10px → 11px, breathing room
   ─ C) Editor: h1 size, body line-height, download CTA
   ─ D) Filter tabs (dashboard) + Settings tabs: stronger active state
   ─ E) Task-row: primary/secondary action hierarchy
   ─ F) Header: ослабить yellow-mesh в зоне 0..56px
   ─ G) Numbers: tabular-nums везде где числа
   ─ H) Status pills: semantic colors (success/warning/error/neutral)
   ─ I) Voice-pill: убрать purple (out-of-palette)
   ─ J) Chat-widget: invert (dark bubble, yellow icon)
   ─ K) Mobile: filename truncate, hero highlight tone-down
   ─ L) Section titles, secondary text contrast
   ================================================================ */


/* ── A) FORM CONTROLS — round inputs ─────────────────────────────
   components.css задаёт border-radius:0 для input/select/textarea.
   На warm-beige фоне квадратные углы выглядят дёшево; premium SaaS
   все используют 6-8px. */

.cabinet-content-area input[type="text"],
.cabinet-content-area input[type="email"],
.cabinet-content-area input[type="password"],
.cabinet-content-area input[type="search"],
.cabinet-content-area input[type="url"],
.cabinet-content-area input[type="tel"],
.cabinet-content-area input[type="number"],
.cabinet-content-area input[type="date"],
.cabinet-content-area select,
.cabinet-content-area textarea,
.cabinet-content-area .form-input,
.cabinet-content-area .form-select,
.cabinet-content-area .form-textarea,
/* Модалки */
[role="dialog"] input[type="text"],
[role="dialog"] input[type="email"],
[role="dialog"] input[type="password"],
[role="dialog"] input[type="search"],
[role="dialog"] input[type="url"],
[role="dialog"] textarea,
[role="dialog"] select,
[role="dialog"] .form-input,
[role="dialog"] .form-select,
[role="dialog"] .form-textarea,
.modal input[type="text"],
.modal input[type="email"],
.modal input[type="password"],
.modal input[type="search"],
.modal textarea {
  border-radius: 8px;
}

/* Focus-ring — visible на keyboard, но subtle на mouse */
.cabinet-content-area input:focus-visible,
.cabinet-content-area select:focus-visible,
.cabinet-content-area textarea:focus-visible {
  outline: 2px solid rgba(255, 214, 10, 0.5);
  outline-offset: 1px;
  border-color: rgba(255, 214, 10, 0.65);
}


/* ── B) SIDEBAR plan-card: 10px → 11px ───────────────────────────
   В cabinet_minutes_widget.html используется text-[10px] для:
   • plan label (eyebrow «ПРОФИ»)
   • «Тарифы» link
   • «Осталось N дней до обновления»
   10px ниже WCAG-floor для secondary text — поднимаем до 11px
   с tracking 0.04em для читабельности. */

aside#cabinetSidebar .text-\[10px\] {
  font-size: 0.6875rem;
  letter-spacing: 0.02em;
}
aside#cabinetSidebar .uppercase.text-\[10px\] {
  letter-spacing: 0.06em;
}
/* Мелочёвка: «MP3, MP4, YouTube, Zoom…» в dropdown-меню «Расшифровать» — 10.5px тоже поднять */
aside#cabinetSidebar .text-\[10\.5px\] {
  font-size: 0.6875rem;
}

/* Plan-card breathing: добавить vertical-rhythm */
aside#cabinetSidebar [class*="rounded-2xl"][class*="border"][class*="p-3"] {
  padding: 14px;
}


/* ── C) EDITOR ────────────────────────────────────────────────── */

/* Filename h1 в editor (result.html:1255) — weight/rhythm override */
#resultTitle {
  font-weight: 700 !important;
  line-height: 1.3 !important;
  letter-spacing: -0.01em;
}

/* Body line-height в transcript-сегментах (≥1.5 для read-heavy UI) */
.transcript-segment,
.transcript-segment p,
[data-segment] p,
.editor-content p,
.result-segment-text {
  line-height: 1.55;
}

/* Download/Export CTA в editor toolbar — увеличить размер с 12/7px до 14/9px */
.editor-toolbar [data-action="export"],
.editor-toolbar .export-btn,
.editor-toolbar a[href*="/api/download/"],
[data-editor-toolbar] .btn-primary {
  font-size: 0.875rem;
  padding: 9px 16px;
  font-weight: 600;
}


/* ── D) FILTER TABS (dashboard) — stronger active state ─────────
   Сейчас active = только border-bottom 1px yellow + 12.5px / weight 700.
   Усиливаем: solid bg-tint + bottom-border 2px + чуть больше size. */

/* SCOPE: только dashboard filter tabs (.ws-filter-tab + .dashboard-filter-tabs).
   НЕ применять к .admin-group-trigger (admin panel) — у него свой native bg-yellow-400. */
.dashboard-filter-tabs button[aria-selected="true"]:not(.admin-group-trigger),
.dashboard-filter-tabs button.is-active:not(.admin-group-trigger),
.dashboard-filter-tabs a[aria-selected="true"],
.dashboard-filter-tabs a.is-active,
.ws-filter-tab[aria-selected="true"],
.ws-filter-tab.is-active,
.ws-filter-tab.active {
  background: rgba(255, 214, 10, 0.18);
  border-bottom-color: #FFD60A !important;
  border-bottom-width: 2px !important;
  color: rgb(74, 45, 0);
}
.ws-filter-tab:hover:not([aria-selected="true"]):not(.is-active):not(.active) {
  background: rgba(47, 42, 35, 0.05);
}

/* Числа-счётчики в filter-tabs (Все 851 / Файлы 851 ...) — pill-стиль */
.ws-filter-tab .count,
.ws-filter-tab [class*="text-gray"],
.ws-filter-tab .filter-count {
  font-variant-numeric: tabular-nums;
}


/* ── D2) SETTINGS TABS — stronger active state ───────────────────
   activeClass из settings.html:643 — bg-yellow-50 (#FEFCE8) + border opacity 0.3.
   Усиливаем: bg opacity 0.18 + border opacity 0.45 + субтильная тень. */

.settings-tab.active,
.settings-tab[aria-selected="true"] {
  background: rgba(255, 214, 10, 0.20) !important;
  border-color: rgba(255, 214, 10, 0.50) !important;
  color: rgb(120, 53, 15) !important;
  box-shadow: 0 1px 2px rgba(255, 214, 10, 0.18);
}

/* Hover на inactive settings-tab — плавная подсветка */
.settings-tab:not(.active):not([aria-selected="true"]):hover {
  background: rgba(47, 42, 35, 0.06) !important;
  color: rgb(60, 50, 30) !important;
}


/* ── E) TASK-ROW: primary/secondary hierarchy ───────────────────
   В task_row.html:121 «Открыть» (action button) = bg-gray-100 (равный весу с «Саммари»).
   Делаем action-«Открыть» primary (solid dark на бежевом).

   ВАЖНО: ТОЛЬКО кнопки внутри `.task-actions-wrap`, НЕ .task-row-title-link
   (filename — тоже <a href="/result/..."> но это не CTA). */

.task-actions-wrap a[href^="/result/"]:not(.retry-task-btn):not([class*="rose"]):not(.task-row-title-link) {
  background: rgb(26, 24, 20) !important;
  color: rgb(255, 255, 255) !important;
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(47, 42, 35, 0.15);
}
.task-actions-wrap a[href^="/result/"]:not(.task-row-title-link):hover {
  background: rgb(47, 42, 35) !important;
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(47, 42, 35, 0.20);
}

/* Саммари-кнопка — secondary ghost */
.task-row-summary-btn {
  background: rgba(255, 255, 255, 0.5) !important;
  border-color: rgba(60, 50, 30, 0.18) !important;
  color: rgb(82, 70, 32) !important;
}
.task-row-summary-btn:hover {
  background: rgba(255, 214, 10, 0.14) !important;
  border-color: rgba(255, 214, 10, 0.4) !important;
}


/* ── F) HEADER: ослабить yellow-mesh в зоне header ──────────────
   header.app-header полупрозрачный → mesh-bg просвечивает наверху.
   Это создаёт визуальный вес, конкурирующий с primary CTA.
   Решение: усилить opacity header'а до 0.92 + mesh-bg сместить
   пиковую яркость вниз (на 20vh от top вместо 0vh). */

header.app-header,
header.app-header-cabinet,
.app-header,
.cabinet-app-header {
  background: rgba(255, 255, 252, 0.92) !important;
  backdrop-filter: blur(14px) saturate(115%);
  -webkit-backdrop-filter: blur(14px) saturate(115%);
}

/* Mesh-bg: сместить пик жёлтого на 25% вниз чтобы не светило в header */
.mesh-bg {
  background:
    radial-gradient(1200px 800px at 0%   25%, rgba(255, 214, 10, 0.20), transparent 55%),
    radial-gradient(1200px 800px at 100% 25%, rgba(175,  82, 222, 0.10), transparent 55%),
    radial-gradient(1000px 600px at 50%  100%, rgba( 52, 199,  89, 0.08), transparent 45%),
    radial-gradient( 800px 600px at 10%  80%,  rgba(255, 159,  10, 0.06), transparent 45%),
    var(--color-bg);
}
@media (max-width: 767px) {
  .mesh-bg {
    background:
      radial-gradient(100vw 60vh at 0%   30%, rgba(255, 214, 10, 0.26), transparent 65%),
      radial-gradient(100vw 60vh at 100% 30%, rgba(175,  82, 222, 0.16), transparent 65%),
      radial-gradient(100vw 55vh at 50%  100%, rgba( 52, 199,  89, 0.10), transparent 55%),
      var(--color-bg);
  }
}


/* ── G) TABULAR NUMS везде где значения ─────────────────────────
   Финансовые / usage / time / counter числа — tabular-nums для
   ровного выравнивания (Stripe/Linear best practice). */

.task-row,
.cabinet-content-area .stat-value,
.cabinet-content-area [data-stat-value],
.cabinet-content-area .number-display,
.cabinet-content-area .currency,
.cabinet-content-area .amount,
.cabinet-content-area td,
.cabinet-content-area .text-lg.font-bold,
.cabinet-content-area .text-2xl.font-bold,
.cabinet-content-area .text-3xl.font-bold,
.minutes-counter,
.task-duration {
  font-variant-numeric: tabular-nums;
}


/* ── H) STATUS PILLS — semantic colors ──────────────────────────
   В payment table «Оплачено» green / «Отменено» yellow → должно
   быть neutral-grey. Также team-member status «Активен» yellow → green. */

/* Successful payment / active member */
.status-paid, .status-success,
.payment-status-completed,
.team-member-active,
[data-status="active"]:not(.task-row),
[data-status="completed"]:not(.task-row),
[data-status="paid"] {
  background: rgba(22, 163, 74, 0.12) !important;
  color: rgb(21, 128, 61) !important;
  border-color: rgba(22, 163, 74, 0.30) !important;
}

/* Cancelled / neutral */
.status-cancelled, .status-canceled, .status-refunded-pending,
.payment-status-cancelled,
[data-status="cancelled"]:not(.task-row),
[data-status="canceled"]:not(.task-row) {
  background: rgba(82, 92, 107, 0.10) !important;
  color: rgb(82, 92, 107) !important;
  border-color: rgba(82, 92, 107, 0.20) !important;
}

/* Failed / refunded */
.status-failed, .status-refunded,
.payment-status-failed,
[data-status="failed"]:not(.task-row),
[data-status="refunded"]:not(.task-row) {
  background: rgba(239, 68, 68, 0.10) !important;
  color: rgb(185, 28, 28) !important;
  border-color: rgba(239, 68, 68, 0.25) !important;
}


/* ── I) VOICE-PILL: убрать purple (out-of-palette) ──────────────
   Sidebar dropdown «Голосовой блокнот» имеет bg-purple-100 + text-purple-600.
   Перекрашиваем в brand yellow для консистентности. */

aside#cabinetSidebar [class*="bg-purple-100"][class*="text-purple"] {
  background: rgba(255, 214, 10, 0.18) !important;
  color: rgb(120, 53, 15) !important;
}

/* «Голосовой блокнот» pill в filter row dashboard — если purple → yellow */
.ws-voice-pill[class*="purple"],
.ws-voice-pill {
  background: rgba(255, 214, 10, 0.16) !important;
  border-color: rgba(255, 214, 10, 0.40) !important;
  color: rgb(120, 53, 15) !important;
}


/* ── J) CHAT-WIDGET: invert (dark bubble, yellow icon) ──────────
   Yellow-on-yellow при scroll вверх — низкий контраст. Инвертируем:
   dark bubble с yellow icon → видно на любом фоне. */

#chatWidgetTrigger,
.chat-widget-trigger,
[data-chat-trigger],
button[aria-label*="чат"] {
  background: rgb(26, 24, 20) !important;
  color: rgb(255, 214, 10) !important;
  border: 2px solid rgba(255, 214, 10, 0.55) !important;
}
#chatWidgetTrigger:hover,
.chat-widget-trigger:hover,
[data-chat-trigger]:hover,
button[aria-label*="чат"]:hover {
  background: rgb(47, 42, 35) !important;
  transform: scale(1.06);
  box-shadow: 0 8px 24px rgba(47, 42, 35, 0.25), 0 0 0 4px rgba(255, 214, 10, 0.20) !important;
}


/* ── K) MOBILE FIXES ────────────────────────────────────────────
   K1) Filename truncate в task-row — сохранить начало, ellipsis в конце.
   K2) Cookie banner: bottom-padding на cabinet-content-area если виден. */

@media (max-width: 640px) {
  .task-row .task-filename,
  .task-row [class*="truncate"]:has(> a),
  .task-row a[class*="truncate"],
  .task-row .file-name {
    direction: ltr;
    text-overflow: ellipsis;
    overflow: hidden;
    white-space: nowrap;
    text-align: left;
  }
}

/* Cookie banner reserve-space (banner sticks bottom @ ~56px)
   Был баг: ID был #cookieBanner, но реальный элемент — #cookieConsent */
body:has(#cookieConsent:not(.hidden)) .cabinet-content-area {
  padding-bottom: 88px;
}


/* ── L) SECTION TITLES + secondary text contrast ────────────────
   ds-title-card в settings — 14px / 600 (мелковато для section header).
   Поднимаем до 16px / 700. */

.cabinet-content-area .ds-title-card,
.cabinet-content-area section h2:not(.ds-title-app),
.cabinet-content-area section h3:not(.ds-title-app) {
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin-bottom: 12px;
}


/* ── M) HERO HIGHLIGHT (yellow marker on public hero) ───────────
   На /login, /features/*, /usecases/*, /about, /faq используется
   .wsd-h1-accent (login) или <mark class="hero-highlight"> (другие).
   Меняем full-bg на gradient-underline (только нижняя 45% символа). */

.hero-highlight,
mark.hero-highlight,
.hero-mark,
mark.hero-mark,
.public-hero mark,
.wsd-h1-accent,
span.wsd-h1-accent,
.wsd-hero-accent,
.ds-hero-accent,
/* generic <mark> в hero h1/h2 на public-страницах */
h1 mark,
h2 mark,
section h1 mark,
.hero h1 mark,
.hero mark {
  /* Audit 2026-05-08 (revised): возвращаем solid yellow bg + dark text для consistency
     с эталонным дизайном «с первой минуты.». box-decoration-break: clone обязателен —
     иначе на multi-line h1 (mobile) yellow bg рисуется как full bbox rectangle
     с пустым пространством между текстом и краями. С clone каждая строка получает
     свой собственный yellow box, плотно обтекающий текст. */
  background: #FFD60A !important;
  color: rgb(26, 24, 20) !important;
  padding: 0.05em 0.25em !important;
  border-radius: 4px;
  display: inline !important;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  /* Декоративные тени убираем чтобы highlight оставался "плоским" maker-стилем */
  box-shadow: none !important;
}


/* ── N) MEMBER STATUS «Активен» в Settings#team ─────────────────
   В team-tab используется amber/yellow для «Активен» — semantic green правильнее. */

.cabinet-content-area .text-yellow-600.font-medium:where(:not(:has(*))),
.cabinet-content-area [data-status="member-active"],
[data-team-member-status="active"] {
  color: rgb(21, 128, 61);
}


/* ── O) «осталось N дн.» в settings — нейтральный, не amber ─────
   amber говорит «warning», но план auto-renews → должен быть info-grey. */

.cabinet-content-area .text-amber-500:has-text("осталось"),
.cabinet-content-area .plan-expires-warning {
  color: rgb(82, 92, 107) !important;
  font-weight: 400 !important;
}


/* ── P) RIPPLES: subtle hover на task-row + cards ───────────────
   .task-row:hover уже подсвечен (cabinet-overrides:165-169).
   Добавляем subtle transform для kinetic feel. */

.task-row {
  transition: transform 180ms ease-out, box-shadow 180ms ease-out, border-color 180ms ease-out;
}
.task-row:hover {
  transform: translateY(-1px);
}


/* ── Q) BONUSES PAGE — yellow eyebrow softer ────────────────────
   На /bonuses heading использует bg yellow-300 — слишком ярко. */

.cabinet-content-area .bonuses-eyebrow,
.cabinet-content-area section [class*="bg-yellow-300"]:not(button):not(a) {
  background: linear-gradient(180deg, transparent 55%, rgba(255, 214, 10, 0.50) 55%) !important;
}


/* ── R) FAILED PAYMENTS BANNER — softer + compact ───────────────
   На /settings#payments длинная red banner растягивается на всю ширину.
   Делаем компактнее (max-width + меньший vertical padding). */

.cabinet-content-area [class*="bg-red"][class*="border-red"]:has(> *:contains("Неудачных")),
.cabinet-content-area .failed-payments-banner {
  max-width: 720px;
  padding: 10px 14px !important;
  font-size: 0.8125rem;
  border-radius: 10px !important;
}


/* ── S) EMPTY STATE — общие стили для bonuses/referrals ─────────
   Даём empty-state'ам breathing room + соблюдение vertical rhythm. */

.cabinet-content-area .empty-state,
.cabinet-content-area [data-empty-state] {
  text-align: center;
  padding: 32px 16px;
  color: rgb(82, 92, 107);
}
.cabinet-content-area .empty-state i,
.cabinet-content-area .empty-state svg,
.cabinet-content-area [data-empty-state] i {
  font-size: 2rem;
  color: rgb(180, 178, 168);
  margin-bottom: 10px;
}


/* ── T) PUBLIC PAGES — input rounded (auth/login/register) ──────
   Login/register тоже используют form-input с radius:0.
   Вне cabinet-content-area нужно покрыть формы аутентификации. */

.auth-form input[type="text"],
.auth-form input[type="email"],
.auth-form input[type="password"],
.auth-form input[type="tel"],
.auth-card input[type="text"],
.auth-card input[type="email"],
.auth-card input[type="password"],
form[action*="login"] input,
form[action*="register"] input,
form[action*="reset"] input,
.public-page input[type="text"],
.public-page input[type="email"],
.public-page input[type="password"],
.public-page input[type="tel"],
.public-page input[type="search"],
.public-page textarea {
  border-radius: 8px;
}


/* ================================================================
   iOS INPUT ZOOM PREVENTION (2026-05-08 mobile audit wave 2)

   Safari на iOS зумит viewport если font-size < 16px при focus в input.
   Это ломает layout: страница масштабируется, кнопки уезжают за viewport.
   Стандартный fix: font-size: 16px на всех text-input полях на мобиле.
   На десктопе зум не применяется — правило в @media max-width:767px.

   Применяем ко всем text/email/password/number/tel/url/search/date inputs,
   select и textarea. Исключаем range/checkbox/radio (другая семантика).
   ================================================================ */

@media (max-width: 767px) {
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="number"],
  input[type="tel"],
  input[type="url"],
  input[type="search"],
  input[type="date"],
  input[type="datetime-local"],
  input[type="time"],
  input[type="month"],
  input[type="week"],
  input:not([type]),
  select,
  textarea {
    font-size: 1rem !important;
  }
}


/* ================================================================
   TACTILE FEEDBACK — ACTIVE STATES (2026-05-08 mobile audit wave 2)

   На мобиле tap без визуального отклика воспринимается как «ничего
   не произошло» — особенно на медленных GPU/сетях. Добавляем тонкую
   обратную связь через scale/opacity на active state. На desktop
   работает на mousedown — приятный bounce при клике.
   ================================================================ */

/* Primary/Secondary CTA — лёгкий scale-down */
.btn-primary:active:not(:disabled),
.btn-secondary:active:not(:disabled),
.btn-danger:active:not(:disabled) {
  transform: scale(0.97);
  transition: transform 0.08s ease-out;
}

/* Icon-buttons и pills — opacity dim */
.ico-btn:active:not(:disabled),
.task-row-summary-btn:active:not(:disabled),
.task-kebab-btn:active:not(:disabled),
.ws-status-dropdown-btn:active:not(:disabled),
.ws-voice-pill:active:not(:disabled),
.task-action-row:active:not(:disabled) {
  opacity: 0.65;
  transition: opacity 0.08s ease-out;
}

/* Filter tabs — лёгкий dim */
.ws-filter-tab:active {
  opacity: 0.7;
  transition: opacity 0.08s ease-out;
}

/* Task-row — subtle background dim */
.task-row:active {
  background: rgba(60, 50, 30, 0.06);
  transition: background 0.08s ease-out;
}

html.dark .task-row:active {
  background: rgba(255, 255, 255, 0.10);
}

/* Sidebar nav items — dim */
#cabinetSidebar a:active,
#cabinetSidebar button:active {
  opacity: 0.7;
}

/* Bottom-nav items — scale + opacity */
#cabinetBottomNav a:active,
#cabinetBottomNav button:active {
  transform: scale(0.92);
  opacity: 0.75;
  transition: transform 0.08s ease-out, opacity 0.08s ease-out;
}

/* Modal close + settings/payment tabs */
[id$="ModalClose"]:active,
.settings-tab:active,
[data-payment-tab]:active {
  opacity: 0.65;
  transform: scale(0.95);
  transition: transform 0.08s ease-out, opacity 0.08s ease-out;
}

/* Reduced motion: убрать transform, оставить только opacity */
@media (prefers-reduced-motion: reduce) {
  .btn-primary:active:not(:disabled),
  .btn-secondary:active:not(:disabled),
  .btn-danger:active:not(:disabled),
  #cabinetBottomNav a:active,
  #cabinetBottomNav button:active,
  [id$="ModalClose"]:active,
  .settings-tab:active,
  [data-payment-tab]:active {
    transform: none;
  }
}


/* ================================================================
   /result EDITOR PER-TURN ACTIONS (2026-05-08 mobile audit wave 2)

   В editor.js рендерятся 6 inline action buttons на каждую реплику
   (edit-speaker / loop / copy / split / merge / delete) с паттерном
   `opacity-0 group-hover:opacity-100` — desktop hover-reveal.

   На мобиле hover не работает: кнопки остаются opacity:0 (НЕ видны),
   но всё ещё занимают место (28×28×6 = 168px на каждую реплику) и
   кликабельны → юзер случайно тапает «удалить» или «разделить».

   Фикс: на <sm полностью скрыть эти кнопки. Спикер-лейбл (с
   data-speaker) и таймкод-кнопка остаются тапабельными — основные
   действия на мобиле (переименовать спикер, прыгнуть на момент)
   работают через них. Edit/split/merge/delete — desktop-only.
   ================================================================ */

@media (max-width: 767px) {
  .segment-block .edit-speaker-btn,
  .segment-block .loop-segment-btn,
  .segment-block .copy-segment-btn,
  .segment-block .split-segment-btn,
  .segment-block .merge-segment-btn,
  .segment-block .delete-segment-btn,
  .segment-block .delete-segment-item-btn {
    display: none !important;
  }

  /* Гарантируем что speaker-label остаётся прокачанной touch-target
     (он уже cursor-pointer + click handler — переименовать спикера). */
  .segment-block .speaker-label {
    min-height: 32px;
    padding: 6px 10px;
    display: inline-flex;
    align-items: center;
  }

  /* Таймкод-кнопка тоже обязана быть touch-friendly. */
  .segment-block .segment-timecode {
    min-height: 36px;
  }
}


/* ================================================================
   VOICE-FAB MODAL — premium redesign 2026-05-08
   ================================================================
   Replaces emoji-chips, rose idle-button, wrapped chip layout.
   Все стили под префиксом .vfab-* чтобы не пересекаться
   с глобальными правилами кабинета.
   ================================================================ */

/* ── Modal card: enter-transition (220ms scale + fade) ─────── */
#voiceFabOverlay .vfab-card {
  animation: vfabCardEnter 220ms ease-out both;
  box-shadow:
    0 24px 60px -16px rgba(47, 42, 35, 0.24),
    0 6px 20px -8px rgba(47, 42, 35, 0.12);
}
html.dark #voiceFabOverlay .vfab-card {
  box-shadow:
    0 24px 60px -16px rgba(0, 0, 0, 0.65),
    0 6px 20px -8px rgba(0, 0, 0, 0.55);
}
@keyframes vfabCardEnter {
  from { opacity: 0; transform: translateY(8px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0)   scale(1);    }
}
@media (prefers-reduced-motion: reduce) {
  #voiceFabOverlay .vfab-card { animation: none; }
}

/* ── Template chips ──────────────────────────────────────────
   Desktop: 5×1 grid, equal width.
   Mobile (<480px): horizontal scroll-snap, fixed min-width.
   ──────────────────────────────────────────────────────────── */
.vfab-tpl-row {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 6px;
}
@media (max-width: 480px) {
  .vfab-tpl-row {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    gap: 6px;
    padding-bottom: 4px;
    margin-left: -2px;
    margin-right: -2px;
    scrollbar-width: none;
  }
  .vfab-tpl-row::-webkit-scrollbar { display: none; }
  .vfab-tpl-chip {
    scroll-snap-align: start;
    flex: 0 0 auto;
    min-width: 96px;
  }
}

.vfab-tpl-chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 8px 6px;
  border-radius: 12px;
  /* 1.5px чтобы не было layout-jitter при toggle is-active */
  border: 1.5px solid rgba(228, 226, 219, 0.9);
  background: rgba(255, 255, 255, 0.7);
  color: rgb(82, 76, 64);
  font-size: 0.71875rem;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.08s, box-shadow 0.15s;
  -webkit-tap-highlight-color: transparent;
}
.vfab-tpl-chip > i {
  font-size: 0.875rem;
  color: rgb(132, 124, 110);
  transition: color 0.15s;
}
.vfab-tpl-chip > span {
  font-size: 0.6875rem;
  letter-spacing: -0.01em;
}
.vfab-tpl-chip:hover {
  background: rgba(255, 245, 200, 0.6);
  border-color: rgba(255, 214, 10, 0.45);
  color: rgb(60, 55, 45);
}
.vfab-tpl-chip:hover > i { color: rgb(180, 130, 0); }
.vfab-tpl-chip:active { transform: scale(0.96); }

/* Active state: tinted accent + yellow border + subtle glow.
   Premium look (Linear/Stripe-tier), а не "наклейка-стикер".
   Light: лёгкий yellow tint, читаемый текст. Dark: ниже, ещё subtle. */
.vfab-tpl-chip.is-active {
  background: rgba(255, 214, 10, 0.18);
  border-color: rgb(255, 196, 0);
  color: rgb(120, 84, 0);
  box-shadow: 0 1px 6px -1px rgba(255, 196, 0, 0.35);
  font-weight: 600;
}
.vfab-tpl-chip.is-active > i { color: rgb(180, 130, 0); }

html.dark .vfab-tpl-chip {
  background: rgba(38, 36, 32, 0.6);
  border-color: rgba(78, 74, 66, 0.7);
  color: rgb(210, 205, 195);
}
html.dark .vfab-tpl-chip > i { color: rgb(170, 165, 155); }
html.dark .vfab-tpl-chip:hover {
  background: rgba(255, 214, 10, 0.10);
  border-color: rgba(255, 214, 10, 0.45);
  color: rgb(255, 232, 130);
}
html.dark .vfab-tpl-chip:hover > i { color: rgb(255, 220, 110); }
html.dark .vfab-tpl-chip.is-active {
  background: rgba(255, 214, 10, 0.13);
  border-color: rgba(255, 214, 10, 0.75);
  color: rgb(255, 220, 100);
  box-shadow: 0 1px 8px -2px rgba(255, 214, 10, 0.35), inset 0 0 0 1px rgba(255, 214, 10, 0.08);
  font-weight: 600;
}
html.dark .vfab-tpl-chip.is-active > i { color: rgb(255, 214, 10); }


/* ── Idle mic button ─────────────────────────────────────────
   Brand yellow (#FFD60A) с pulsing soft-ring. НЕ красный.
   Красный остаётся только для STOP в recording state.
   ──────────────────────────────────────────────────────────── */
/* !important здесь намеренно: cabinet-overrides выше выставляет
   `button[aria-label*="чат"] { background: rgb(26,24,20) !important }`
   для chat-widget. Любая строка с подстрокой "чат" подпадает (например
   "Запись с **чат**ом" — ловушка). Защищаемся. */
#voiceFabOverlay .vfab-mic-idle {
  position: relative;
  width: 88px;
  height: 88px;
  border-radius: 50%;
  background: linear-gradient(180deg, rgb(255, 220, 60) 0%, rgb(255, 196, 0) 100%) !important;
  color: rgb(40, 30, 0) !important;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border: none !important;
  box-shadow:
    0 8px 24px -6px rgba(255, 196, 0, 0.55),
    inset 0 0 0 1px rgba(255, 255, 255, 0.5);
  transition: transform 0.15s ease-out, box-shadow 0.2s;
  -webkit-tap-highlight-color: transparent;
}
#voiceFabOverlay .vfab-mic-idle:hover {
  transform: scale(1.04);
  box-shadow:
    0 12px 30px -6px rgba(255, 196, 0, 0.65),
    inset 0 0 0 1px rgba(255, 255, 255, 0.55);
}
#voiceFabOverlay .vfab-mic-idle:active { transform: scale(0.97); }
#voiceFabOverlay .vfab-mic-idle:focus-visible {
  outline: 3px solid rgba(255, 196, 0, 0.4);
  outline-offset: 4px;
}

.vfab-mic-idle-ring {
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 2px solid rgba(255, 196, 0, 0.35);
  animation: vfabIdleRing 2.4s ease-out infinite;
  pointer-events: none;
}
@keyframes vfabIdleRing {
  0%   { transform: scale(0.95); opacity: 0;   }
  35%  {                          opacity: 0.6; }
  100% { transform: scale(1.25); opacity: 0;   }
}
@media (prefers-reduced-motion: reduce) {
  .vfab-mic-idle-ring { animation: none; opacity: 0.3; }
}

html.dark #voiceFabOverlay .vfab-mic-idle {
  background: linear-gradient(180deg, rgb(255, 214, 10) 0%, rgb(220, 170, 0) 100%) !important;
  color: rgb(30, 20, 0) !important;
}
html.dark .vfab-mic-idle-ring {
  border-color: rgba(255, 214, 10, 0.45);
}


/* ── Card-wide drag-over visual ──────────────────────────────
   Drop работает на любую часть card (см. voice_fab.js).
   При dragover — yellow dashed outline + visible #voiceFabDragHint
   overlay поверх idle-content. */
#voiceFabCard.vfab-card-dragover {
  outline: 2px dashed rgb(255, 196, 0);
  outline-offset: -8px;
  background: rgba(255, 245, 200, 0.45);
}
html.dark #voiceFabCard.vfab-card-dragover {
  outline-color: rgb(255, 214, 10);
  background: rgba(255, 214, 10, 0.06);
}
/* Default: drag-hint скрыт. Класс vfab-drag-hint вместо Tailwind .hidden
   чтобы CSS-rule ниже мог его перебить без !important. */
.vfab-drag-hint { display: none; }
#voiceFabCard.vfab-card-dragover .vfab-drag-hint {
  display: flex;
  background: rgba(255, 245, 200, 0.85);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  z-index: 5;
}
html.dark #voiceFabCard.vfab-card-dragover .vfab-drag-hint {
  background: rgba(35, 30, 18, 0.85);
}

/* ── Chips fade-edge на mobile (scroll-indicator) ─────────────
   Добавляет легкий fade с правой стороны row → юзер видит что
   chips прокручиваемые. */
@media (max-width: 480px) {
  .vfab-tpl-row {
    -webkit-mask-image: linear-gradient(to right, black 0%, black calc(100% - 24px), transparent 100%);
    mask-image: linear-gradient(to right, black 0%, black calc(100% - 24px), transparent 100%);
  }
}


/* ── Keyboard-hint pill ──────────────────────────────────── */
.vfab-kbd {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.625rem;
  font-weight: 600;
  color: rgb(82, 76, 64);
  background: rgba(228, 226, 219, 0.7);
  border: 1px solid rgba(190, 186, 175, 0.5);
  border-bottom-width: 2px;
  line-height: 1.2;
  vertical-align: middle;
}
html.dark .vfab-kbd {
  color: rgb(210, 205, 195);
  background: rgba(58, 55, 50, 0.7);
  border-color: rgba(95, 90, 82, 0.6);
}


/* ── Waveform: recording state (red glow) ───────────────── */
.vfab-wave {
  background: rgba(254, 242, 242, 0.7);
}
html.dark .vfab-wave {
  background: rgba(127, 29, 29, 0.18);
}
.vfab-wave-glow {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 60% 80% at 50% 50%, rgba(244, 63, 94, 0.18), transparent 75%);
  pointer-events: none;
  animation: vfabWaveGlow 2s ease-in-out infinite;
}
@keyframes vfabWaveGlow {
  0%, 100% { opacity: 0.5; }
  50%      { opacity: 1;   }
}
@media (prefers-reduced-motion: reduce) {
  .vfab-wave-glow { animation: none; opacity: 0.7; }
}

.vfab-bar {
  width: 4px;
  height: 12px;
  border-radius: 2px;
  background: linear-gradient(180deg, rgb(244, 63, 94) 0%, rgb(225, 29, 72) 100%);
  transition: height 0.08s ease-out;
}
html.dark .vfab-bar {
  background: linear-gradient(180deg, rgb(251, 113, 133) 0%, rgb(244, 63, 94) 100%);
}

/* Paused state — frozen amber */
.vfab-wave-paused {
  background: rgba(255, 248, 220, 0.7);
}
html.dark .vfab-wave-paused {
  background: rgba(146, 100, 0, 0.18);
}


/* ── Low-volume coaching hint ─────────────────────────── */
#voiceFabSubtitle.vfab-subtitle-warn {
  color: rgb(180, 100, 0);
}
html.dark #voiceFabSubtitle.vfab-subtitle-warn {
  color: rgb(252, 196, 25);
}


/* ================================================================
   DARK-THEME COUNTER-FIXES (light-audit 2026-05-08)

   Цель: исправить регрессии, возникшие после light-theme правок,
   когда селекторы без `.dark` префикса применились ко всем темам.
   Все правки ниже ОБЯЗАТЕЛЬНО имеют `html.dark` префикс — никаких
   глобальных переопределений, чтобы не сломать light повторно.

   Строгое правило scope:
   ─ html.dark .X — для overрайдов в .dark
   ─ Никогда не использовать `.X` без `.dark` если правило цвет/фон
   ─ Селекторы task-row уточнять `:not(.task-row-title-link)` или scope `.task-actions-wrap`
   ================================================================ */


/* ── DA) TASK-ROW «Открыть» — invert для dark ───────────────────
   В light: bg #1A1814 (almost black) + white text → contrast OK на бежевом
   В dark: тот же bg = invisible на dark theme background #0A0A0C
   Решение: light cream bg + dark text для max contrast in dark. */

html.dark .task-actions-wrap a[href^="/result/"]:not(.retry-task-btn):not([class*="rose"]):not(.task-row-title-link) {
  background: rgb(255, 214, 10) !important;
  color: rgb(26, 24, 20) !important;
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
}
html.dark .task-actions-wrap a[href^="/result/"]:not(.task-row-title-link):hover {
  background: rgb(245, 200, 0) !important;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(255, 214, 10, 0.30);
}


/* ── DB) TASK-ROW «Саммари» — для dark ──────────────────────────
   Light fix дал bg rgba(255,255,255,0.5) + brown text → broken на dark.
   Делаем dark-glass с light yellow text. */

html.dark .task-row-summary-btn {
  background: rgba(255, 255, 255, 0.06) !important;
  border-color: rgba(255, 214, 10, 0.30) !important;
  color: rgb(252, 196, 25) !important;
}
html.dark .task-row-summary-btn:hover {
  background: rgba(255, 214, 10, 0.12) !important;
  border-color: rgba(255, 214, 10, 0.55) !important;
}


/* ── DC) SETTINGS TABS active — для dark ────────────────────────
   Light fix дал color #783310 (dark brown) — на dark theme не читается.
   Делаем light yellow text + сильнее bg-yellow-tint. */

html.dark .settings-tab.active,
html.dark .settings-tab[aria-selected="true"] {
  background: rgba(255, 214, 10, 0.16) !important;
  border-color: rgba(255, 214, 10, 0.45) !important;
  color: rgb(252, 196, 25) !important;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.30);
}
html.dark .settings-tab:not(.active):not([aria-selected="true"]):hover {
  background: rgba(255, 255, 255, 0.06) !important;
  color: rgb(243, 244, 246) !important;
}


/* ── DD) FILTER TABS active — для dark ──────────────────────────
   В dashboard light fix задал bg rgba(255,214,10,0.18) + color rgb(74,45,0).
   Brown #4A2D00 нечитаем на dark — light yellow text. */

/* SCOPE: только dashboard filter tabs. .admin-group-trigger — не трогать. */
html.dark .dashboard-filter-tabs button[aria-selected="true"]:not(.admin-group-trigger),
html.dark .dashboard-filter-tabs button.is-active:not(.admin-group-trigger),
html.dark .ws-filter-tab[aria-selected="true"],
html.dark .ws-filter-tab.is-active,
html.dark .ws-filter-tab.active {
  background: rgba(255, 214, 10, 0.16) !important;
  border-bottom-color: #FFD60A !important;
  color: rgb(252, 196, 25) !important;
}
html.dark .ws-filter-tab:hover:not([aria-selected="true"]):not(.is-active):not(.active) {
  background: rgba(255, 255, 255, 0.05);
  color: rgb(243, 244, 246);
}


/* ── DE) VOICE-PILL — для dark ──────────────────────────────────
   Light fix: bg rgba(255,214,10,0.16) + brown text 120,53,15.
   Brown на dark → invert text to light yellow. */

html.dark aside#cabinetSidebar [class*="bg-purple-100"][class*="text-purple"],
html.dark .ws-voice-pill[class*="purple"],
html.dark .ws-voice-pill {
  background: rgba(255, 214, 10, 0.14) !important;
  border-color: rgba(255, 214, 10, 0.35) !important;
  color: rgb(252, 196, 25) !important;
}


/* ── DF) HERO HIGHLIGHT — унифицировано (revised 2026-05-08) ─────
   Solid yellow bg + dark text работает идентично в обоих темах
   (yellow на light beige И на dark — оба читаются с dark text внутри).
   Dark-override больше не нужен — основное правило самодостаточно. */


/* ── M2) HERO H1 — типографика без висячих предлогов и разрыва слов
   ─ overflow-wrap: normal (не ломать «часы» на «час»+«ы.»)
   ─ text-wrap: balance — браузер балансирует длину строк (Chrome 114+, Safari 17.4+)
   ─ hyphens: none — на mobile мог быть hyphen-fallback
   ─ word-break: keep-all для русского (не разрывать кириллические слова) */

.wsd-h1,
.wsd-h1-accent,
section h1.wsd-h1,
.public-page h1,
.hero h1,
.public-hero h1 {
  overflow-wrap: normal !important;
  word-break: normal;
  hyphens: none;
  text-wrap: balance;
}
/* fallback для браузеров без text-wrap: balance */
@supports not (text-wrap: balance) {
  .wsd-h1, .public-page h1, .hero h1 { text-wrap: pretty; }
}


/* ── DG) STATUS PILLS — для dark ────────────────────────────────
   Light fix через [data-status="..."] не имел dark-вариантов.
   В payment-table статусы рендерятся через классы bg-emerald-100/dark:bg-emerald-900/30
   уже в шаблоне settings.html — это уже OK, но универсальные fallback'ы для других мест: */

html.dark .status-paid, html.dark .status-success,
html.dark .payment-status-completed,
html.dark [data-status="active"]:not(.task-row),
html.dark [data-status="completed"]:not(.task-row),
html.dark [data-status="paid"] {
  background: rgba(22, 163, 74, 0.18) !important;
  color: rgb(74, 222, 128) !important;
  border-color: rgba(22, 163, 74, 0.40) !important;
}

html.dark .status-cancelled, html.dark .status-canceled,
html.dark .payment-status-cancelled,
html.dark [data-status="cancelled"]:not(.task-row),
html.dark [data-status="canceled"]:not(.task-row) {
  background: rgba(255, 255, 255, 0.06) !important;
  color: rgb(156, 163, 175) !important;
  border-color: rgba(255, 255, 255, 0.10) !important;
}

html.dark .status-failed, html.dark .status-refunded,
html.dark .payment-status-failed,
html.dark [data-status="failed"]:not(.task-row),
html.dark [data-status="refunded"]:not(.task-row) {
  background: rgba(239, 68, 68, 0.15) !important;
  color: rgb(252, 165, 165) !important;
  border-color: rgba(239, 68, 68, 0.35) !important;
}


/* ── DH) FORM INPUTS — focus-ring для dark (light fix добавил) ──
   Light: outline rgba(255,214,10,0.5) на yellow→white border-color.
   Это работает в dark тоже (yellow on dark background). Оставляем как есть.
   НО: input bg на dark должен быть тёмный — проверим через override. */

html.dark .cabinet-content-area input[type="text"],
html.dark .cabinet-content-area input[type="email"],
html.dark .cabinet-content-area input[type="password"],
html.dark .cabinet-content-area input[type="search"],
html.dark .cabinet-content-area input[type="url"],
html.dark .cabinet-content-area input[type="tel"],
html.dark .cabinet-content-area input[type="number"],
html.dark .cabinet-content-area input[type="date"],
html.dark .cabinet-content-area select,
html.dark .cabinet-content-area textarea,
html.dark .cabinet-content-area .form-input,
html.dark .cabinet-content-area .form-select,
html.dark .cabinet-content-area .form-textarea {
  /* border-radius уже задан в light section — наследуется */
  /* в dark: убедимся что bg достаточно тёмный + бордер не свет */
  background-color: rgba(30, 32, 44, 0.85);
  border-color: rgba(255, 255, 255, 0.14);
  color: rgb(243, 244, 246);
}
html.dark .cabinet-content-area input::placeholder,
html.dark .cabinet-content-area textarea::placeholder {
  color: rgba(243, 244, 246, 0.40);
}


/* ── DI) EMPTY STATE — icon color для dark ──────────────────────
   Light icon = gray-300. На dark theme нужен gray-600 (subtle). */

html.dark .cabinet-content-area .empty-state i,
html.dark .cabinet-content-area .empty-state svg,
html.dark .cabinet-content-area [data-empty-state] i {
  color: rgb(107, 114, 128);
}
html.dark .cabinet-content-area .empty-state {
  color: rgb(156, 163, 175);
}


/* ── DJ) HEADER — opacity для dark ──────────────────────────────
   Light fix задал bg rgba(255,255,252,0.92) — для dark нужен dark bg.
   .dark .app-header в base.html уже определён, но light override
   мог затереть. Восстанавливаем dark-aware значение. */

html.dark header.app-header,
html.dark header.app-header-cabinet,
html.dark .app-header,
html.dark .cabinet-app-header {
  background: rgba(15, 15, 18, 0.85) !important;
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}


/* ── DK) BONUSES PAGE eyebrow — для dark ────────────────────────
   Light fix дал gradient yellow 0.50 — на dark тоже работает,
   но усилим до 0.65 для visibility. */

html.dark .cabinet-content-area .bonuses-eyebrow,
html.dark .cabinet-content-area section [class*="bg-yellow-300"]:not(button):not(a) {
  background: linear-gradient(180deg, transparent 55%, rgba(255, 214, 10, 0.65) 55%) !important;
}


/* ── DL) FAILED-PAYMENTS BANNER compact — для dark ──────────────
   Banner в settings.html: bg-rose-50 dark:bg-rose-900/20 — уже dark-ready
   через template. Но если останется rose-50 в dark — fallback: */

html.dark .cabinet-content-area .failed-payments-banner {
  background: rgba(239, 68, 68, 0.10) !important;
  border-color: rgba(239, 68, 68, 0.30) !important;
}


/* ── DM) MEMBER STATUS «Активен» в team — для dark ──────────────
   JS settings.js рендерит text-emerald-600 dark:text-emerald-400 —
   уже dark-ready. Никаких overрайдов не нужно. */


/* ── DN) PUBLIC AUTH FORMS — focus border для dark ──────────────
   Login/register forms имеют border-radius: 8px (light fix).
   В dark убедимся что bg input тёмный + border слабый. */

html.dark .auth-form input,
html.dark .auth-card input,
html.dark form[action*="login"] input,
html.dark form[action*="register"] input,
html.dark form[action*="reset"] input,
html.dark .public-page input,
html.dark .public-page textarea {
  background-color: rgba(30, 32, 44, 0.85);
  border-color: rgba(255, 255, 255, 0.14);
  color: rgb(243, 244, 246);
}


/* ── DO) SECTION TITLES в cabinet — для dark ────────────────────
   Light fix `.cabinet-content-area .ds-title-card` поднял до 16px / 700.
   В dark наследуется, но color должен быть white-ish. */

html.dark .cabinet-content-area .ds-title-card,
html.dark .cabinet-content-area section h2:not(.ds-title-app),
html.dark .cabinet-content-area section h3:not(.ds-title-app) {
  color: rgb(243, 244, 246);
}


/* ── PRICING MOBILE SWIPE (P0-8) ────────────────────────────────
   На 390px только первая карточка (Старт) видна выше fold.
   Делаем горизонтальный scroll-snap carousel — Базовый+Профи
   видны краем следующей карточки.
   CSS-only, не трогаем template.
   ──────────────────────────────────────────────────────────────── */
@media (max-width: 767px) {
  [data-billing-section] .grid {
    display: flex !important;
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: 0.75rem !important;
    margin-left: -1rem;
    margin-right: -1rem;
    padding-left: 1rem;
    padding-right: 1rem;
    padding-bottom: 0.5rem;
  }
  [data-billing-section] .grid::-webkit-scrollbar { display: none; }
  [data-billing-section] .grid > article {
    scroll-snap-align: start;
    flex: 0 0 calc(88% - 0.75rem);
    width: calc(88% - 0.75rem);
    min-width: 220px;
  }
}


/* ── AUTH PAGE — UX fixes (PR-2) ────────────────────────────────
   P0-2: Overlap between cookie consent bar and auth CTA on 390px
   P0-3: btn--rounded removed in template → pills → standard 12px (var(--radius-lg))
   P1-8: OAuth buttons min-height 44px (WCAG 2.5.8 touch target)
   P2-2: Auth divider contrast in dark mode
   ──────────────────────────────────────────────────────────────── */

/* P0-2: On narrow mobile, fixed cookie banner can cover auth submit */
@media (max-width: 480px) {
  body:has(#cookieConsent:not(.hidden)) .wsd-auth-card {
    padding-bottom: 80px;
  }
}

/* P1-8: WCAG 2.5.8 — 44px minimum touch target */
.wsd-auth-oauth-btn {
  min-height: 44px;
}

/* P2-2: Divider line + text in dark mode */
html.dark .wsd-auth-divider {
  color: rgba(255, 255, 255, 0.5);
}
html.dark .wsd-auth-divider::before,
html.dark .wsd-auth-divider::after {
  background: rgba(255, 255, 255, 0.12);
}

/* Auth H1 single-line fix: на desktop clamp(32px,5vw,44px) → "Начните бесплатно"
   рвётся на 2 строки (17 chars × 44px > 424px column). Снижаем до 32px max. */
@media (min-width: 769px) {
  .wsd-auth-h1 {
    font-size: clamp(24px, 2.5vw, 32px) !important;
  }
}


/* ── ACCESSIBILITY — prefers-reduced-motion (P0-6) ──────────────
   Пользователи с вестибулярными нарушениями (WCAG 2.3.3 AAA).
   Если OS запрашивает отключение анимаций — убираем все duration.
   CSS transitions и keyframe animations сводятся к 0.01ms. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
