/* ── Variables ──────────────────────────────────────────────────────────────
   Theme: dark (default) or light. Перемикається через document.documentElement.dataset.theme.
   Юзер вибір зберігається у localStorage; за замовчуванням — system preference.

   Commit 1 of frontend-cosmetic-redesign sprint:
   Adopted CodeTime (Skills Kiln) design tokens. The reference token names
   live alongside the existing names so unchanged component CSS (~2000 LOC)
   continues to compile by aliasing to new values. Per-view migration of
   selectors happens in commits 4-8.

   Reference token group hierarchy:
     bg:     --bg-base (canvas) → --bg-elevated (cards) → --bg-sunken (inputs)
     border: --border-strong → --border-subtle
     text:   --text-primary → --text-secondary → --text-tertiary
     accent: --accent (lime) → --accent-soft → --accent-glow
     system: --warning (amber) / --danger (red)
     domain: --green / --yellow / --red — preserved for recruitment verdict
             badges (Підходить / Частково / Відхилено); parallel to system
             semantics, NOT collapsed.

   Old GitHub-Primer values kept as-is for verdict colors only. All other
   chrome (backgrounds, borders, text, accent) shifts to reference values.
*/
:root, [data-theme="dark"] {
  /* ─── Reference tokens (the new system) ──────────────────────────────── */
  --bg-base:         #0a0a0c;                /* canvas base, darker than GH */
  --bg-elevated:     #131316;                /* cards, modals, header */
  --bg-sunken:       #08080a;                /* inputs, code, seg-control track */

  --border-strong:   #2a2a30;
  --border-subtle:   #1f1f24;

  --text-primary:    #ededf0;                /* warmer than GH #e6edf3 */
  --text-secondary:  #8b8b94;                /* warmer than GH #8b949e */
  --text-tertiary:   #5a5a63;                /* NEW — kbd, micro-labels */

  --accent:          #2f81f7;                /* WAS GitHub blue #2f81f7 → LIME */
  --accent-soft:     #58a6ff;                /* lighter lime — hover */
  --accent-glow:     #2f81f733;              /* lime + 20% alpha — focus ring */

  --warning:         #f59e0b;                /* amber — system-level warning */
  --danger:          #ef4444;                /* red — system-level danger (errors, destroy) */

  --font-ui:         'Geist', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-mono:       'Roboto Mono', ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  --radius-card:     16px;
  --radius-btn:      10px;
  --radius-sm:       6px;                    /* chips, small inputs */

  --ease-out:        cubic-bezier(0.2, 0, 0, 1);
  --ease-overshoot:  cubic-bezier(0.34, 1.56, 0.64, 1);

  /* ─── Task 3: playful animation tokens (Stripe-style spring physics) ─── */
  --ease-spring:     cubic-bezier(0.34, 1.56, 0.64, 1);  /* overshoot — same curve as --ease-overshoot, named for intent */
  --ease-snap:       cubic-bezier(0.4, 0, 0.2, 1);       /* Material standard */
  --ease-out-quart:  cubic-bezier(0.25, 1, 0.5, 1);      /* deceleration */
  --duration-fast:   150ms;
  --duration-base:   250ms;
  --duration-slow:   400ms;

  /* ─── Legacy aliases — point at new values so old selectors keep working ── */
  --bg-main:         var(--bg-base);
  --bg-sidebar:      var(--bg-base);         /* same as main — no level drop */
  --bg-card:         var(--bg-elevated);
  --bg-card-hover:   #1c1c20;                /* elevated + slight lift */
  --bg-header:       var(--bg-elevated);
  --bg-modal:        var(--bg-elevated);
  --border:          var(--border-strong);

  --accent-hover:    var(--accent-soft);

  /* ─── Domain (verdict) colors — preserved exactly, parallel to system ── */
  --green:           #3fb950;                /* Підходить */
  --red:             #f85149;                /* Відхилено */
  --yellow:          #d29922;                /* Частково / error filter */

  /* ─── Gender filter sprint: card gender-symbol colors ──────────────────
     Role-named (not hue-named) so future visual refreshes can re-map the
     hex without code changes. Applied via the inline-SVG glyphs in
     .card-gender-sym, painted through stroke=currentColor.
     Phase 6 picks (locked): A+B combo. Female = mid-pink (rose, not
     coral — must not read as warning/error). Male = lighter blue
     (Tailwind blue-300 family), distinct from --accent. Unknown uses
     the existing --text-tertiary muted token. */
  --gender-female-fg: #ec7eb4;
  --gender-male-fg:   #93c5fd;

  /* ─── Selection tint (sidebar active row) — preserved ──────────────── */
  --selected:        #1f3a5f;
  --selected-hover:  #2a4d7a;

  --text:            var(--text-primary);
  --bg:              var(--bg-main);
}

[data-theme="light"] {
  /* Light theme re-derived from the new dark palette — not a flat inversion.
     Lime accent shifted down to lime-700 (#2563eb) so it stays readable on
     near-white backgrounds. Verdict greens stay GitHub-style for legibility. */

  --bg-base:         #f5f7fa;                /* soft off-white canvas */
  --bg-elevated:     #ffffff;                /* cards on canvas */
  --bg-sunken:       #eceff3;                /* inputs darker than elevated */

  --border-strong:   #d0d5db;
  --border-subtle:   rgba(0,0,0,0.08);

  --text-primary:    #0f1721;                /* near-black for contrast on white */
  --text-secondary:  #475260;
  --text-tertiary:   #6b7280;                /* slate-500 mid tone */

  --accent:          #2563eb;                /* lime-700 — readable on white */
  --accent-soft:     #1d4ed8;                /* lime-800 — hover */
  --accent-glow:     #2563eb22;

  --warning:         #d97706;
  --danger:          #dc2626;

  /* Legacy aliases */
  --bg-main:         var(--bg-base);
  --bg-sidebar:      #eceff3;                /* slightly darker than canvas for sidebar separation */
  --bg-card:         var(--bg-elevated);
  --bg-card-hover:   #f8fafc;
  --bg-header:       var(--bg-elevated);
  --bg-modal:        var(--bg-elevated);
  --border:          var(--border-strong);

  --accent-hover:    var(--accent-soft);

  /* Verdict — light theme tuned to GitHub light values (already legible) */
  --green:           #16a34a;
  --red:             #dc2626;
  --yellow:          #d97706;

  /* Gender filter — light-theme analogs of the dark A+B picks. Deeper
     saturation per CodeTime convention (the same shift the verdict
     palette uses). Pink-700-ish for female stays clearly rose, not red
     (won't collide with --red #dc2626). Blue-800 for male sits distinct
     from --accent #2563eb AND from --accent-soft #1d4ed8 (the card-position
     color in light theme), so the gender symbol never visually blends
     into adjacent card elements. */
  --gender-female-fg: #be185d;
  --gender-male-fg:   #1e40af;

  --selected:        #c9dffd;
  --selected-hover:  #b3d2fb;

  --text:            var(--text-primary);
  --bg:              var(--bg-main);
}

/* light theme: інверсія hover-ефектів і м'яка тінь на картках */
[data-theme="light"] body {
  background: var(--bg-main);
  color: var(--text-primary);
}
[data-theme="light"] .btn-icon:hover {
  background: rgba(0,0,0,0.06);
}

/* hover-стани, які в темній темі юзають білий полупрозорий — у світлій інвертуємо на чорний */
[data-theme="light"] .vacancy-item:hover {
  background: rgba(0,0,0,0.04);
}

/* картки — м'яка тінь + межа, щоб виділялись на сірому фоні */
[data-theme="light"] .resume-card {
  border: 1px solid var(--border);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.04),
              0 1px 2px rgba(15, 23, 42, 0.03);
}
[data-theme="light"] .resume-card:hover {
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.06),
              0 1px 3px rgba(15, 23, 42, 0.04);
  border-color: #c0c6cd;
}

/* картка-rejected у світлій темі — нейтральний сірий лівий border */
[data-theme="light"] .resume-card.rejected {
  border-left-color: #94a3b8;
}

/* sidebar у світлій темі — чітка межа справа */
[data-theme="light"] .sidebar {
  border-right-color: #d8dde3;
}

/* фільтр-бар і header теж відокремимо межею у світлій темі */
[data-theme="light"] .filter-bar,
[data-theme="light"] .vacancy-header {
  border-bottom-color: #e2e6eb;
}

/* кнопки secondary, фільтри, link — у світлій темі замість прозоро-білого
   беремо м'який сірий, інакше їх не видно */
[data-theme="light"] .btn-secondary {
  background: #ffffff;
  border-color: var(--border);
}
[data-theme="light"] .btn-secondary:hover {
  background: #eef1f5;
}
[data-theme="light"] .filter-btn:hover {
  background: rgba(0,0,0,0.05);
  color: var(--text-primary);
}
[data-theme="light"] .card-btn-link {
  background: #f0f3f7;
  color: var(--text-secondary);
  border-color: var(--border);
}
[data-theme="light"] .card-btn-link:hover {
  background: #e2e7ed;
  color: var(--text-primary);
}
[data-theme="light"] .card-divider {
  background: rgba(0,0,0,0.06);
}
[data-theme="light"] .monitor-panel {
  background: rgba(0,0,0,0.02);
}

/* form-group inputs — у світлій темі мають білий бг + чітку межу
   (на сірому фоні модалу-секції) */
[data-theme="light"] .form-group input[type="text"],
[data-theme="light"] .form-group input[type="url"],
[data-theme="light"] .form-group input[type="date"],
[data-theme="light"] .form-group input[type="password"],
[data-theme="light"] .form-group textarea {
  background: #ffffff;
  border-color: #c4cad2;
  color: var(--text-primary);
}
[data-theme="light"] .form-group input:focus,
[data-theme="light"] .form-group textarea:focus {
  background: #ffffff;
  border-color: var(--accent);
  /* Commit 3: focus halo retuned to lime-700 alpha (was old GH blue rgba) */
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}
[data-theme="light"] .form-group input::placeholder,
[data-theme="light"] .form-group textarea::placeholder {
  color: #94a0ac;
}

/* === Resume card text у світлій темі ===
   Commit 3 of redesign: --accent shifted from GitHub blue → lime, but the
   "nice-to-have" tag and the position-name color are intentionally KEPT
   blue. They're semantic info colors (not action-accent), so they stay
   blue regardless of which hue the accent moves to. Verdict greens/reds
   tuned to darker shades that read well on near-white backgrounds. */
[data-theme="light"] .card-summary {
  color: #1f2937;          /* основний текст резюме — майже-чорний */
}
[data-theme="light"] .card-position {
  color: #1d4ed8;          /* назва позиції — насичений blue (info, NOT action) */
  font-weight: 500;
}
[data-theme="light"] .rejected-reason {
  color: #b91c1c;          /* темний red */
}

/* Тегі вимог (✓/✗/★) — насиченіший фон + темний текст */
[data-theme="light"] .req-tag.match {
  background: rgba(22, 163, 74, 0.13);
  color: #15803d;
}
[data-theme="light"] .req-tag.missing {
  background: rgba(220, 38, 38, 0.10);
  color: #b91c1c;
}
[data-theme="light"] .req-tag.nice {
  background: rgba(37, 99, 235, 0.10);
  color: #1d4ed8;
}

/* Verdict-badge (Підходить / Частково / Відхилено) */
[data-theme="light"] .verdict-badge.relevant {
  background: rgba(22, 163, 74, 0.12);
  color: #15803d;
  border-color: rgba(22, 163, 74, 0.25);
}
[data-theme="light"] .verdict-badge.partial {
  background: rgba(217, 119, 6, 0.13);
  color: #b45309;
  border-color: rgba(217, 119, 6, 0.28);
}
[data-theme="light"] .verdict-badge.rejected {
  background: rgba(220, 38, 38, 0.10);
  color: #b91c1c;
  border-color: rgba(220, 38, 38, 0.22);
}

/* card-buttons зелений (зберегти) і червоний (відхилити) */
[data-theme="light"] .card-btn-save {
  background: rgba(22, 163, 74, 0.12);
  color: #15803d;
  border-color: rgba(22, 163, 74, 0.28);
}
[data-theme="light"] .card-btn-save:hover:not(:disabled) {
  background: rgba(22, 163, 74, 0.22);
}
[data-theme="light"] .card-btn-skip {
  background: rgba(220, 38, 38, 0.09);
  color: #b91c1c;
  border-color: rgba(220, 38, 38, 0.22);
}

/* Btn-danger у світлій темі */
[data-theme="light"] .btn-danger {
  background: rgba(220, 38, 38, 0.10);
  color: #b91c1c;
  border-color: rgba(220, 38, 38, 0.25);
}

/* scrollbar у світлій темі */
[data-theme="light"] ::-webkit-scrollbar-thumb {
  background: rgba(0,0,0,0.18);
}
[data-theme="light"] ::-webkit-scrollbar-thumb:hover {
  background: rgba(0,0,0,0.28);
}

/* ── Reset ───────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  /* Commit 2: adopt Geist (UI) + Roboto Mono (numbers/dates) from CodeTime.
     Fallback chain covers the case where Google Fonts fails to load —
     -apple-system / BlinkMacSystemFont on mac, Segoe UI on Windows. Cyrillic
     coverage verified in both Geist v2.x and Roboto Mono. */
  font-family: var(--font-ui);
  background: var(--bg-main);
  color: var(--text-primary);
  height: 100vh;
  overflow: hidden;
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

button { font-family: inherit; cursor: pointer; }
textarea, input { font-family: inherit; }
a { color: var(--accent); }

/* ── Emoji-in-button alignment ──────────────────────────────────────────────
   Task 1 of frontend-polish-batch sprint: emojis sitting inside button
   labels (▶/⏸/📁/📂/⚙/etc.) have intrinsic vertical metrics that don't
   align with the surrounding text baseline — gear hovers above the
   "Налаштування" caption, etc.

   Fix: wrap the leading emoji in <span class="btn-emoji"> so it becomes
   a separate flex child of the inline-flex+gap button parent (set up
   in R4). The span enforces line-height:1 + flex centering, so the
   emoji draws within a tight box that vertically centers cleanly
   against the adjacent text flex child.

   Used in: index.html action buttons, modal-section-title headers,
   run-all "▶▶ Запустити всі вакансії", sidebar-mode-header. Same
   treatment will roll into admin / compare buttons when their
   respective restyle commits land (5 and 6). */
.btn-emoji {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  flex-shrink: 0;
  /* Keep relative font-size so the emoji scales with the button label */
  font-size: 1em;
}

/* ── Native <select> — intentional styling ──────────────────────────────────
   Refinement 1 (commit 4.1 of redesign): apply across ALL native selects
   in the app (sort, monitor interval, support category, usage period,
   invite expires, run selector). Replaces "browser default on dark theme"
   with a token-driven control that matches the styled-input pattern from
   the auth pages. Per-selector classes (.sort-select, .monitor-interval-
   select, etc.) still override font-size / padding / width for their
   contexts; this rule supplies the chrome (chevron, bg, border, focus). */
select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  font-family: var(--font-ui);
  background: var(--bg-sunken);
  color: var(--text-primary);
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  padding: 8px 30px 8px 12px;     /* extra right padding for chevron */
  cursor: pointer;
  /* Chevron — Lucide-style, stroke #8b8b94 (--text-secondary), 1.5px stroke. */
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' fill='none' stroke='%238b8b94' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M1 1l4 4 4-4'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
  transition: border-color 150ms ease, background-color 150ms ease, box-shadow 150ms ease;
}
select:hover { border-color: var(--border-strong); }
select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-glow);
}
/* Option styling — limited cross-browser; works in Chrome/Edge/Firefox. */
select option {
  background: var(--bg-elevated);
  color: var(--text-primary);
}
/* Light theme — sunken bg darker than canvas; chevron stroke adapts. */
[data-theme="light"] select {
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' fill='none' stroke='%23475260' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><path d='M1 1l4 4 4-4'/></svg>");
}

/* ── Layout ──────────────────────────────────────────────────────────────── */
.app {
  display: flex;
  height: 100vh;
}

/* ── Sidebar ─────────────────────────────────────────────────────────────── */
.sidebar {
  width: 280px;
  min-width: 280px;
  background: var(--bg-sidebar);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.sidebar-header {
  display: flex;
  align-items: center;
  padding: 14px 12px 14px 16px;
  border-bottom: 1px solid var(--border);
  gap: 4px;
}

.app-title {
  font-size: 16px;
  font-weight: 700;
  flex: 1;
  color: var(--text-primary);
  letter-spacing: 0.2px;
}

.btn-icon {
  background: none;
  border: none;
  color: var(--text-secondary);
  padding: 6px 8px;
  border-radius: 6px;
  font-size: 15px;
  line-height: 1;
  transition: background 0.15s, color 0.15s;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.btn-icon:hover {
  background: rgba(255,255,255,0.07);
  color: var(--text-primary);
}
.btn-icon svg {
  width: 17px;
  height: 17px;
  display: block;
}

.vacancy-list {
  flex: 1;
  overflow-y: auto;
  padding: 4px 0;
}

.vacancy-item {
  display: flex;
  align-items: center;
  padding: 10px 12px 10px 16px;
  cursor: pointer;
  /* R5 refinement: snappy hover (was 120ms, kept) with ease-out token */
  transition: background 120ms var(--ease-out);
  gap: 11px;
  position: relative;
}
.vacancy-item:hover  { background: rgba(255,255,255,0.04); }
.vacancy-item.active { background: var(--selected); }
.vacancy-item.active:hover { background: var(--selected-hover); }

.vacancy-avatar {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(82,136,193,0.18);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 19px;
  flex-shrink: 0;
}

.vacancy-info { flex: 1; min-width: 0; }

.vacancy-name {
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text-primary);
}

.vacancy-sub {
  font-size: 12px;
  color: var(--text-secondary);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.vacancy-badge {
  background: var(--red);
  color: white;
  font-size: 11px;
  font-weight: 700;
  min-width: 20px;
  height: 20px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 5px;
  flex-shrink: 0;
}

.running-dot {
  width: 8px;
  height: 8px;
  background: var(--yellow);
  border-radius: 50%;
  flex-shrink: 0;
  animation: pulse 1.2s ease-in-out infinite;
}

/* search_since_date — блок з date input під checkbox.
   Сlightly відступ від checkbox щоб візуально групувалось */
.form-group.form-group-since {
  padding-left: 24px;
  margin-top: -4px;
  margin-bottom: 12px;
}
.form-group.form-group-since input[type="date"] {
  padding: 6px 10px;
  font-size: 14px;
  width: auto;
}
.form-group.form-group-since small {
  display: block;
  margin-top: 6px;
  font-size: 12px;
  color: var(--text-secondary, #888);
  line-height: 1.4;
  font-style: italic;
}

/* URL auto-fill блок — на самому верху форми вакансії.
   Виділяємо м'яким bg щоб привертало увагу. */
.form-group.url-import {
  background: rgba(33, 150, 243, 0.06);
  border: 1px dashed rgba(33, 150, 243, 0.3);
  border-radius: 8px;
  padding: 14px 16px;
  margin-bottom: 18px;
}
.form-group.url-import label {
  font-weight: 600;
  margin-bottom: 8px;
  display: block;
}
.url-import-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}
.url-import-row input {
  flex: 1;
  padding: 8px 12px;
  font-family: var(--font-mono);
  font-size: 13px;
  /* Явний background щоб field не зливався з блоком url-import при focus.
     Раніше успадковував transparent + browser default → текст невидимий. */
  background: var(--bg-card) !important;
  border: 1px solid var(--border-subtle);
  color: var(--text-primary);
  border-radius: 6px;
}
.url-import-row input:focus {
  outline: none;
  border-color: var(--accent);
  background: var(--bg-card) !important;
  /* R6: focus halo matched with .form-group input pattern */
  box-shadow: 0 0 0 3px rgba(47, 129, 247, 0.18);
}
.url-import-row .btn-generate {
  white-space: nowrap;
  padding: 8px 14px;
}
.form-group.url-import small {
  display: block;
  margin-top: 8px;
  font-size: 12px;
  color: var(--text-secondary, #888);
  line-height: 1.4;
}

/* hotfix/import-autodetect PART A — "Посилання на вакансію" edit-mode row.
   Близький до .url-import-row, але без виділеного блока: інпут + 📋 кнопка
   у одну лінію. Кнопка — .btn-secondary (нейтральний accent), не purple.
   На вузьких modal'ах flex переноситься природно через flex-wrap. */
.url-edit-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
  flex-wrap: wrap;
}
.url-edit-row input {
  flex: 1;
  min-width: 0;                  /* дозволяє shrink нижче content size */
  font-family: var(--font-mono);
  font-size: 13px;
}
.url-edit-row .btn-secondary {
  white-space: nowrap;
  /* трохи компактніше від default padding щоб висота match'илась з input'ом */
  padding: 7px 12px;
  font-size: 14px;               /* щоб 📋 не виглядав крихітним */
}

/* UX refinement (gender-filter sprint) — top-slot edit-mode URL block.
   Same horizontal-rhythm cues as .url-import above (consistent visual
   weight in the top slot between create and edit), but neutral accent
   since this is "view + edit" not "import → autofill". */
/* Same accent treatment as .form-group.url-import — blue-tinted background +
   accent border so the top slot reads as the same component family in both
   modes. Border is SOLID here (not dashed): dashed signals a drop-zone /
   action invitation on the create side; the edit-mode block is showing
   stored state, so solid reads as "labelled container" without the
   drop-zone cue. Same blue token (rgba(33,150,243,…)) in both themes —
   no light-theme override needed since the tint reads on both. */
.form-group.url-edit-block {
  background: rgba(33, 150, 243, 0.06);
  border: 1px solid rgba(33, 150, 243, 0.3);
  border-radius: 8px;
  padding: 14px 16px;
  margin-bottom: 18px;
}
.form-group.url-edit-block > label {
  font-weight: 600;
  margin-bottom: 8px;
  display: block;
}
.url-edit-actions {
  display: flex;
  gap: 8px;
  margin-top: 10px;
  flex-wrap: wrap;
}
.url-edit-actions .btn-secondary {
  flex: 1 1 auto;
  min-width: 140px;
  white-space: nowrap;
}
.hint-muted {
  display: block;
  margin-top: 6px;
  font-size: 12px;
  color: var(--text-secondary, #888);
  font-style: italic;
}

/* Regenerate-from-URL CONFIRM modal — destructive-action gate. Reuses
   .modal-narrow shell (used by review modal + continue-options modal). */
.regen-fields-list {
  margin: 6px 0 12px;
  padding-left: 22px;
  font-size: 13px;
  color: var(--text-primary);
  line-height: 1.5;
}
.regen-fields-list li {
  margin: 2px 0;
}
.regen-warning {
  background: rgba(245, 166, 35, 0.10);
  border-left: 3px solid #f5a623;
  padding: 10px 12px;
  margin: 12px 0 16px;
  font-size: 13px;
  line-height: 1.5;
  border-radius: 4px;
}
[data-theme="light"] .regen-warning {
  background: rgba(245, 166, 35, 0.15);
}
.regen-confirm-label {
  display: block;
  margin: 12px 0 6px;
  font-size: 13px;
  color: var(--text-primary);
}
.regen-confirm-label code {
  background: var(--bg-card);
  border: 1px solid var(--border-subtle);
  border-radius: 3px;
  padding: 1px 6px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.5px;
}
#regen-confirm-input {
  width: 100%;
  padding: 8px 12px;
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 1px;
  border: 1px solid var(--border-subtle);
  background: var(--bg-card);
  color: var(--text-primary);
  border-radius: 6px;
  box-sizing: border-box;
}
#regen-confirm-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(47, 129, 247, 0.18);
}

/* Phase 9 — post-save scrape-offer dialog (gender transition). Reuses
   .modal-narrow shell. Body content (lead + since-date + optional busy
   notice) is rendered by _openGenderScrapeOffer in app.js. */
.gender-offer-since {
  display: block;
  margin: 12px 0 0;
  font-size: 13px;
  color: var(--text-secondary, #888);
  line-height: 1.5;
}
.gender-offer-busy {
  margin: 14px 0 0;
  padding: 10px 12px;
  background: rgba(245, 166, 35, 0.10);
  border-left: 3px solid #f5a623;
  border-radius: 4px;
  font-size: 13px;
  line-height: 1.45;
}
[data-theme="light"] .gender-offer-busy {
  background: rgba(245, 166, 35, 0.15);
}
#gender-offer-lead strong {
  color: var(--text-primary);
}
#gender-offer-lead em {
  font-style: normal;
  color: var(--accent);
  font-weight: 600;
}

/* Sidebar header — username + actions + run-all */
.sidebar-header {
  flex-direction: column;
  align-items: stretch !important;
  gap: 10px !important;
}
.user-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
}
.user-bar .user-icon {
  font-size: 16px;
  color: var(--text-secondary);
}
.user-bar .user-name {
  flex: 1;
  font-weight: 600;
  color: var(--text-primary);
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.user-bar .header-actions {
  display: flex;
  gap: 2px;
}
.btn-icon-danger:hover {
  background: rgba(229, 57, 53, 0.15) !important;
  color: var(--red) !important;
}

/* Запустити всі вакансії — повна-ширина кнопка під user-bar */
.btn-run-all {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  background: var(--accent);
  color: white;
  border: none;
  border-radius: 8px;
  padding: 9px 12px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.10);
  /* Softened 50% per owner feedback */
  transition:
    background var(--duration-fast) var(--ease-snap),
    transform var(--duration-fast) var(--ease-snap),
    box-shadow var(--duration-fast) var(--ease-snap);
}
.btn-run-all:hover:not(:disabled) {
  background: var(--accent-hover);
  transform: translateY(-1px) scale(1.01);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.15),
    0 3px 12px -6px rgba(47, 129, 247, 0.35);
}
.btn-run-all:active:not(:disabled) {
  transform: translateY(0) scale(0.98);
  transition-duration: 60ms;
  transition-timing-function: var(--ease-snap);
}
.btn-run-all:disabled { opacity: 0.5; cursor: not-allowed; transform: none; }

/* Progress card у empty state — показує що зараз робить пошук */
.progress-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 40px 20px !important;
  gap: 12px;
}
.prog-spinner {
  width: 36px;
  height: 36px;
  border: 3px solid #e0e0e0;
  border-top-color: #2196f3;
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}
@keyframes spin {
  to { transform: rotate(360deg); }
}
.prog-title {
  font-size: 15px;
  font-weight: 500;
  color: var(--text, #333);
  text-align: center;
}
.prog-sub {
  font-size: 12px;
  color: var(--text-secondary, #888);
  text-align: center;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.prog-sub .batch-eta b {
  color: var(--text-primary);
  font-weight: 600;
}
.prog-sub .batch-sep { opacity: 0.5; }

/* Phase 7c: sticky muted sub-line on the scan progress card. Used for
   "Відфільтровано за статтю: N" — informational, not the primary action. */
.prog-extra {
  font-size: 11px;
  color: var(--text-tertiary);
  text-align: center;
  margin-top: 4px;
  letter-spacing: 0.02em;
}
.prog-hint {
  font-size: 11px;
  color: var(--text-secondary);
  text-align: center;
  margin-top: 6px;
  max-width: 380px;
  line-height: 1.45;
  opacity: 0.8;
}

/* Batch indicator — 📦 + кількість резюме в обробці Anthropic batch'у.
   Помаранчева пульсація — щоб виділяти серед звичайних бейджів. */
.batch-badge {
  background: rgba(255, 165, 0, 0.18);
  color: #d97706;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 10px;
  white-space: nowrap;
  flex-shrink: 0;
  border: 1px solid rgba(255, 165, 0, 0.35);
  animation: pulseBatch 2s ease-in-out infinite;
}

@keyframes pulseBatch {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.65; }
}

/* ── Monitor panel ───────────────────────────────────────────────────────── */
.monitor-panel {
  padding: 10px 12px 8px;
  border-top: 1px solid var(--border);
  background: rgba(255,255,255,0.02);
}

.monitor-row {
  display: flex;
  align-items: center;
  gap: 6px;
}

.monitor-icon { font-size: 13px; }

.monitor-title {
  flex: 1;
  font-size: 12px;
  color: var(--text-secondary);
  font-weight: 500;
}

.monitor-toggle {
  padding: 3px 10px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
  border: 1px solid;
  transition: all 0.15s;
  cursor: pointer;
}
.monitor-toggle.off {
  background: transparent;
  border-color: var(--text-muted, #666);
  color: var(--text-secondary);
}
.monitor-toggle.off:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.monitor-toggle.on {
  background: var(--green, #22c55e);
  border-color: var(--green, #22c55e);
  color: white;
}
.monitor-toggle.on:hover { opacity: 0.85; }

.monitor-settings {
  margin-top: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.monitor-interval-select {
  /* Compact override for the monitor settings row. Global `select` rule
     supplies background / border / chevron / focus glow. */
  font-size: 12px;
  padding: 4px 26px 4px 8px;
  border-radius: 6px;
  width: 100%;
}

.monitor-countdown {
  font-size: 11px;
  color: var(--text-secondary);
  text-align: center;
  padding: 2px 0;
}

.sidebar-footer {
  padding: 10px 12px;
  border-top: 1px solid var(--border);
}

.btn-new-vacancy {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  padding: 9px 0;
  background: var(--accent);
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.10);
  /* Softened 50% per owner feedback */
  transition:
    background var(--duration-fast) var(--ease-snap),
    transform var(--duration-fast) var(--ease-snap),
    box-shadow var(--duration-fast) var(--ease-snap);
}
.btn-new-vacancy:hover {
  background: var(--accent-hover);
  transform: translateY(-1px) scale(1.01);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.15),
    0 3px 12px -6px rgba(47, 129, 247, 0.35);
}
.btn-new-vacancy:active {
  transform: translateY(0) scale(0.98);
  transition-duration: 60ms;
  transition-timing-function: var(--ease-snap);
}

/* ── Main area ───────────────────────────────────────────────────────────── */
.main-area {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
}

.empty-state {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  gap: 14px;
}
.empty-icon  { font-size: 52px; opacity: 0.3; }
.empty-state p { font-size: 15px; }

/* ── Vacancy view ────────────────────────────────────────────────────────── */
.vacancy-view {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.vacancy-header {
  display: flex;
  align-items: center;
  padding: 11px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-header);
  gap: 14px;
  flex-shrink: 0;
}

.vacancy-header-info { flex: 1; min-width: 0; }

.vacancy-header-info h2 {
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.vacancy-header-meta {
  font-size: 12px;
  color: var(--text-secondary);
  margin-top: 2px;
}

.vacancy-header-actions {
  display: flex;
  gap: 7px;
  flex-shrink: 0;
}

/* ── Buttons ───────────────────────────────────────────────────────────────
   R4 + Task 3 (playful animations).
   Inline-flex + gap centers icon+text mechanically. Spring physics on
   hover (translateY(-2px) + subtle scale(1.02) with --ease-spring
   overshoot) for tactile "live" feel. Active state snaps back to
   scale(0.96) immediately (no transition on press, only on release).
   Shadow grows on hover from inset-only to inset + ambient glow tinted
   to the accent. */
.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 7px 14px;
  background: var(--accent);
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.10);
  /* Softened to ~50% of Task 3's playful intensity per owner feedback —
     no overshoot, smaller transforms, tighter shadow halo. Easing flipped
     from --ease-spring to --ease-snap (Material standard, no bounce). */
  transition:
    background var(--duration-fast) var(--ease-snap),
    transform var(--duration-fast) var(--ease-snap),
    box-shadow var(--duration-fast) var(--ease-snap),
    border-color var(--duration-fast) var(--ease-snap);
}
.btn-primary:hover:not(:disabled) {
  background: var(--accent-hover);
  transform: translateY(-1px) scale(1.01);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.15),
    0 3px 12px -6px rgba(47, 129, 247, 0.35);
}
.btn-primary:active:not(:disabled) {
  transform: translateY(0) scale(0.98);
  transition-duration: 60ms;
  transition-timing-function: var(--ease-snap);
}
.btn-primary:disabled {
  background: var(--border);
  color: var(--text-tertiary);
  cursor: not-allowed;
  opacity: 0.7;
  transform: none;
}

.btn-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 7px 13px;
  background: rgba(255,255,255,0.06);
  color: var(--text-primary);
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
  /* Softened 50% per owner feedback — see .btn-primary comment */
  transition:
    background var(--duration-fast) var(--ease-snap),
    border-color var(--duration-fast) var(--ease-snap),
    transform var(--duration-fast) var(--ease-snap);
}
.btn-secondary:hover:not(:disabled) {
  background: rgba(255,255,255,0.1);
  border-color: var(--border-strong);
  transform: translateY(-1px) scale(1.01);
}
.btn-secondary:active:not(:disabled) {
  transform: translateY(0) scale(0.98);
  transition-duration: 60ms;
  transition-timing-function: var(--ease-snap);
}
.btn-secondary:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

.btn-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 7px 12px;
  background: rgba(248, 81, 73, 0.10);
  color: var(--red);
  border: 1px solid rgba(248, 81, 73, 0.22);
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  /* Softened 50% per owner feedback */
  transition:
    background var(--duration-fast) var(--ease-snap),
    border-color var(--duration-fast) var(--ease-snap),
    transform var(--duration-fast) var(--ease-snap);
}
.btn-danger:hover:not(:disabled) {
  background: rgba(248, 81, 73, 0.18);
  border-color: rgba(248, 81, 73, 0.40);
  transform: translateY(-1px) scale(1.01);
}
.btn-danger:active:not(:disabled) {
  transform: translateY(0) scale(0.98);
  transition-duration: 60ms;
  transition-timing-function: var(--ease-snap);
}
.btn-danger:disabled { opacity: 0.6; cursor: not-allowed; transform: none; }

/* Pause button — yellow when search is running */
.btn-pause {
  padding: 7px 14px;
  background: rgba(245,166,35,0.12);
  color: var(--yellow);
  border: 1px solid rgba(245,166,35,0.25);
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.btn-pause:hover { background: rgba(245,166,35,0.22); }

/* Green "Resume" state */
.btn-pause.paused {
  background: rgba(79,174,78,0.12);
  color: var(--green);
  border-color: rgba(79,174,78,0.25);
}
.btn-pause.paused:hover { background: rgba(79,174,78,0.22); }

/* Queue badge — shown in header when vacancies are waiting */
.queue-badge {
  display: inline-flex;
  align-items: center;
  padding: 5px 10px;
  border-radius: 6px;
  border: 1px solid rgba(82,136,193,0.3);
  background: rgba(82,136,193,0.1);
  color: var(--accent);
  font-size: 12px;
  white-space: nowrap;
}

/* ── Status bar ──────────────────────────────────────────────────────────── */
.status-bar {
  display: flex;
  align-items: center;
  padding: 7px 20px;
  background: rgba(82,136,193,0.09);
  border-bottom: 1px solid rgba(82,136,193,0.18);
  gap: 10px;
  font-size: 13px;
  color: #7eb4d8;
  flex-shrink: 0;
}

.status-spinner {
  width: 13px;
  height: 13px;
  border: 2px solid rgba(82,136,193,0.3);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.75s linear infinite;
  flex-shrink: 0;
}

/* ── Filter bar ──────────────────────────────────────────────────────────── */
.filter-bar {
  display: flex;
  align-items: center;
  padding: 8px 20px;
  gap: 6px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-header);
  flex-shrink: 0;
}

.filter-btn {
  padding: 4px 14px;
  border: 1px solid var(--border-subtle);
  border-radius: 20px;
  background: none;
  color: var(--text-secondary);
  font-size: 12px;
  transition: background 150ms ease, border-color 150ms ease, color 150ms ease;
}
.filter-btn:hover  { background: rgba(255,255,255,0.06); color: var(--text-primary); }

/* Refinement R2: filter tab active states are SEMANTIC, not accent-tied.
   Previously ALL tabs lit up in --accent (lime), including "Відхилені"
   which is a negative bucket — confusing. Now each tab uses a muted
   tint matched to its domain meaning:

     [data-filter="relevant"]  → green   (positive — "Підходять")
     [data-filter="rejected"]  → red     (negative — "Відхилені")
     [data-filter="error"]     → yellow  (warning — handled by --error class)
     [data-filter="all"]       → neutral (no semantic — text-only emphasis)
     [filter-btn--reviewed]    → green   (completed bucket — handled below)

   Default .filter-btn.active falls back to NEUTRAL (covers "Всі" and any
   future non-semantic tab). Subtle/professional alphas, not loud. */
.filter-btn.active {
  background: rgba(255, 255, 255, 0.06);
  border-color: var(--border-strong);
  color: var(--text-primary);
  /* Task 3: brief accent pulse when tab becomes active — animation runs
     once per class-add event. Keyframe defined at the end of this file. */
  animation: filter-tab-flash 360ms var(--ease-out-quart);
}
.filter-btn[data-filter="relevant"].active {
  background: rgba(63, 185, 80, 0.12);
  border-color: rgba(63, 185, 80, 0.45);
  color: var(--green);
}
.filter-btn[data-filter="rejected"].active {
  background: rgba(248, 81, 73, 0.10);
  border-color: rgba(248, 81, 73, 0.35);
  color: var(--red);
}
/* "Всі" stays at the neutral default. Explicit no-op rule for clarity. */
.filter-btn[data-filter="all"].active {
  background: rgba(255, 255, 255, 0.06);
  border-color: var(--border-strong);
  color: var(--text-primary);
}

/* Лічильник всередині filter-btn — показує реальну кількість в кожній групі */
.filter-btn-count {
  display: inline-block;
  margin-left: 5px;
  padding: 1px 7px;
  font-size: 11px;
  font-weight: 600;
  background: rgba(255, 255, 255, 0.10);
  border-radius: 10px;
  min-width: 18px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
/* Active-tab counts inherit the tab's hue at higher alpha — subtle but
   reinforces the semantic. */
.filter-btn.active .filter-btn-count {
  background: rgba(255, 255, 255, 0.15);
  color: var(--text-primary);
}
.filter-btn[data-filter="relevant"].active .filter-btn-count {
  background: rgba(63, 185, 80, 0.20);
  color: var(--green);
}
.filter-btn[data-filter="rejected"].active .filter-btn-count {
  background: rgba(248, 81, 73, 0.18);
  color: var(--red);
}
[data-theme="light"] .filter-btn-count {
  background: rgba(0, 0, 0, 0.07);
}
[data-theme="light"] .filter-btn.active .filter-btn-count {
  background: rgba(0, 0, 0, 0.10);
  color: var(--text-primary);
}
[data-theme="light"] .filter-btn[data-filter="relevant"].active .filter-btn-count {
  background: rgba(22, 163, 74, 0.18);
  color: var(--green);
}
[data-theme="light"] .filter-btn[data-filter="rejected"].active .filter-btn-count {
  background: rgba(220, 38, 38, 0.15);
  color: var(--red);
}

.filter-spacer { flex: 1; }

.filter-count {
  font-size: 12px;
  color: var(--text-secondary);
}

.sort-label {
  font-size: 12px;
  color: var(--text-secondary);
  white-space: nowrap;
  margin-right: 4px;
}

.sort-select {
  /* Compact filter-bar override. Global `select` rule handles the rest. */
  font-size: 12px;
  padding: 5px 26px 5px 10px;
  border-radius: 6px;
  margin-right: 12px;
}

/* ── New / seen divider ─────────────────────────────────────────────────── */
.new-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 18px 0 12px;
  color: var(--red);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.new-divider::before,
.new-divider::after {
  content: '';
  flex: 1;
  height: 2px;
  background: var(--red);
}

/* ── Resume stream ───────────────────────────────────────────────────────── */
.resume-stream {
  flex: 1;
  overflow-y: auto;
  padding: 14px 18px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}

.stream-empty {
  text-align: center;
  color: var(--text-secondary);
  padding: 50px 20px;
  font-size: 14px;
}

/* ── Resume card ─────────────────────────────────────────────────────────── */
.resume-card {
  background: var(--bg-card);
  border: 1px solid transparent;
  border-left: 3px solid transparent;
  border-radius: 10px;
  padding: 13px 15px 11px;
  /* R5 refinement: snappy hover transitions on the 3 attrs that change.
     `transform: translateY(-1px)` adds a subtle "lift" — feels alive
     without being floaty (120ms is below human perception threshold
     for lag but visible enough to register as motion). */
  transition:
    background 150ms var(--ease-out),
    border-color 150ms ease,
    transform 120ms var(--ease-out),
    opacity 200ms ease;
  animation: fadeIn 180ms var(--ease-out);
}
.resume-card:hover {
  background: var(--bg-card-hover);
  /* Task 3: hover border tint shifts to accent at low alpha — subtle
     "this is interactive" cue without competing with the verdict-color
     left border. */
  border-color: rgba(47, 129, 247, 0.25);
  transform: translateY(-1px);
}

/* Sprint 2.9: уніфікований vertical spacing між major sections.
   Раніше було inconsistent — .card-position mb:10, .card-summary mb:7,
   .review-comment-quote mt:6 mb:0 → виглядало нерівно особливо на reviewed
   cards де summary міг бути відсутній. Тепер 10px gap між кожним sibling. */
.resume-card > * {
  margin-bottom: 10px;
}
.resume-card > *:last-child {
  margin-bottom: 0;
}

.resume-card.relevant { border-left-color: var(--green); }
.resume-card.partial  { border-left-color: var(--yellow); }
.resume-card.rejected {
  border-left-color: var(--border);   /* нейтральний — як GitHub disabled state */
  opacity: 0.72;
}
.resume-card.rejected:hover { opacity: 0.9; }
.resume-card.actioned { opacity: 0.45; }

/* Card header row */
.card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 9px;
}

.verdict-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: 11px;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}
/* Verdict badges — використовуємо GitHub-стиль колірних токенів.
   Background: success-subtle / attention-subtle / danger-subtle.
   Color:     success-fg     / attention-fg     / danger-fg. */
.verdict-badge.relevant {
  background: rgba(63, 185, 80, 0.15);
  color: var(--green);
  border: 1px solid rgba(63, 185, 80, 0.30);
}
.verdict-badge.partial {
  background: rgba(210, 153, 34, 0.15);
  color: var(--yellow);
  border: 1px solid rgba(210, 153, 34, 0.30);
}
.verdict-badge.rejected {
  background: rgba(248, 81, 73, 0.13);
  color: var(--red);
  border: 1px solid rgba(248, 81, 73, 0.28);
}
/* Pre-deploy Issue 2: analyzer-error verdict badge — orange/amber to read
   as "needs human attention", not "match" or "rejection". */
.verdict-badge.error {
  background: rgba(210, 153, 34, 0.18);
  color: var(--yellow);
  border: 1px solid rgba(210, 153, 34, 0.45);
}
.resume-card.error {
  border-left: 3px solid var(--yellow);
}
/* Pre-deploy Issue 2: filter pill for "Помилки" bucket.
   Refinement R2: count badge also gets yellow tint when tab is active. */
.filter-btn--error {
  /* Inherits .filter-btn base; tint to match the badge. */
  border-color: rgba(210, 153, 34, 0.35);
}
.filter-btn--error:hover {
  background: rgba(210, 153, 34, 0.08);
}
.filter-btn--error.active {
  background: rgba(210, 153, 34, 0.14);
  border-color: rgba(210, 153, 34, 0.45);
  color: var(--yellow);
}
.filter-btn--error.active .filter-btn-count {
  background: rgba(210, 153, 34, 0.20);
  color: var(--yellow);
}

.match-bar {
  font-size: 12px;
  color: var(--text-secondary);
  align-self: center;
}

/* Identity */
.card-identity {
  display: flex;
  /* Phase 6 v4 — was align-items: baseline; the SVG symbol's baseline is
     at the SVG's bottom edge, which pushed the glyph above the name's
     x-height. Switching to center aligns name / symbol / meta against
     the row's cross axis — symbol now sits optically centered against
     the larger name text, and the smaller meta also reads more centered
     against the name's cap-height. */
  align-items: center;
  gap: 8px;
  margin-bottom: 3px;
  flex-wrap: wrap;
}
.card-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
}
.card-meta {
  font-size: 12px;
  color: var(--text-secondary);
  /* Phase 6 iteration v3: pull the "·" separators apart by ~3px each side
     without touching the JS string concatenation. `word-spacing` adds
     space between space-delimited tokens; the meta string is
     "· 32 р. · Київ · 📅 18 трав", so this widens every gap around the
     dots consistently. Letter-spacing would also affect inside-word
     kerning — word-spacing is the surgical choice. */
  word-spacing: 3px;
}
.card-position {
  font-size: 13px;
  color: var(--accent-hover);
  margin-bottom: 10px;
}
/* feat/expected-salary: muted "Зарплата не вказана" fallback rendered when
   the source page didn't list a salary. Override the parent .card-position
   accent color with the existing --text-secondary token + normal weight
   so the absence-of-data text visually steps back versus actual amounts.
   No new theme token introduced — both light and dark themes already
   render --text-secondary as the muted body color. */
.card-position .card-salary-empty {
  color: var(--text-secondary);
  font-weight: normal;
}

/* ─── Gender filter sprint: card gender indicator ───────────────────────
   Two variants live in app.js (toggled via GENDER_VARIANT const):
     • 'symbol' (current iteration) — inline ♀/♂ glyph after the candidate
       name in .card-identity. Compact, one glyph per card. CSS class
       .card-gender-sym.
     • 'word'   (revert path)       — standalone "Стать: жінка/чоловік/
       невизначена" line between identity row and position row. CSS class
       .card-gender. Kept in CSS so the revert flag flips with no styling
       drift.

   Color tokens (--gender-female-fg, --gender-male-fg) are defined in the
   :root theme block below — DO NOT hardcode hex here. */

/* ─── Variant A: inline SVG symbol ─────────────────────────────────────
   We use inline SVG (not the Unicode ♀/♂ glyphs) because Chromium paints
   those codepoints from the system emoji palette even with U+FE0E + the
   font-variant-emoji: text hint + an emoji-less font-family — verified in
   Phase 6 iteration preview. SVG paths painted via stroke=currentColor
   flow CSS color cleanly across all platforms.

   The wrapper span owns the color; the SVG inside inherits via
   currentColor. Vertical-align nudges the glyph onto the text baseline
   (default `baseline` sits slightly low for these particular paths). */
.card-gender-sym {
  /* Direct flex child of .card-identity (Phase 6 v4). Cross-axis centering
     comes from the parent's `align-items: center` — no vertical-align
     gymnastics needed here.

     Negative margin-left pulls the symbol closer to the name than the
     parent's 8px flex gap (the meta line on the other side keeps the
     full gap, so name→symbol is tight while symbol→meta breathes).

     position+top nudge (v5, locked): dead-center reads slightly high
     against the heavier name text — Stas wanted a one-pixel drop. Same
     offset for ♀ and ♂ (single rule on the wrapper). */
  display: inline-flex;
  margin-left: -4px;
  position: relative;
  top: 1px;
}
.card-gender-sym--female  { color: var(--gender-female-fg); }
.card-gender-sym--male    { color: var(--gender-male-fg); }
/* Phase ctr (gender-contrib): ⊘ undetermined glyph. Muted/tertiary token
   so it reads as "we don't know, please tell us" — not as a competing
   verdict like ♀/♂. text-secondary token is the closest existing muted
   color on both themes; opacity nudges it further back so the glyph
   doesn't fight the name beside it. */
.card-gender-sym--unknown {
  color: var(--text-secondary, #888);
  opacity: 0.65;
}
.card-gender-sym svg     { display: block; }

/* Phase ctr (gender-contrib): top-right "Визначити стать" button. Absolute
   over the card so the existing card-header / card-identity / actions
   layout stays untouched. Shown ONLY on unknown rows (the JS skips the
   button entirely for ♀/♂ cards — no DOM emitted). Click opens the
   3-option picker modal. */
.resume-card { position: relative; }   /* anchor for the absolute button */
.card-contrib-gender {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 2;
  background: var(--accent);
  color: #fff;
  border: 1px solid var(--accent);
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.2px;
  cursor: pointer;
  transition: background 120ms ease, transform 120ms ease, box-shadow 120ms ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}
.card-contrib-gender:hover  { background: var(--accent-hover, var(--accent)); transform: translateY(-1px); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); }
.card-contrib-gender:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); }

/* Phase ctr — contribute-gender picker modal. Reuses .modal-narrow shell. */
.contrib-help {
  font-size: 12px;
  color: var(--text-secondary, #888);
  line-height: 1.5;
  margin: 8px 0 14px;
}
.contrib-options {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.btn-contrib-opt {
  padding: 10px 14px;
  border: 1px solid var(--border-subtle);
  background: var(--bg-card);
  color: var(--text-primary);
  border-radius: 8px;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
  text-align: left;
}
.btn-contrib-opt:hover {
  background: rgba(47, 129, 247, 0.08);
  border-color: var(--accent);
}
.btn-contrib-opt--male:hover {
  background: rgba(33, 150, 243, 0.10);
  border-color: var(--gender-male-fg);
  color: var(--gender-male-fg);
}
.btn-contrib-opt--female:hover {
  background: rgba(236, 126, 180, 0.10);
  border-color: var(--gender-female-fg);
  color: var(--gender-female-fg);
}
.btn-contrib-opt--unknown {
  color: var(--text-secondary, #888);
  font-style: italic;
}
.btn-contrib-opt--unknown:hover {
  background: rgba(255, 255, 255, 0.04);
  border-color: var(--border-subtle);
}
[data-theme="light"] .btn-contrib-opt--unknown:hover {
  background: rgba(0, 0, 0, 0.03);
}
/* CTR iteration: selected state. Accent border + subtle accent-tinted bg
   so the picker reads as radio-style (one-of-three) before Save commits.
   Variant-specific selected colors so the chosen option's identity stays
   visible (Чоловік = blue, Жінка = pink, Невизначено = neutral muted). */
.btn-contrib-opt.selected {
  background: rgba(47, 129, 247, 0.12);
  border-color: var(--accent);
  color: var(--text-primary);
  font-style: normal;
}
.btn-contrib-opt--male.selected {
  background: rgba(33, 150, 243, 0.14);
  border-color: var(--gender-male-fg);
  color: var(--gender-male-fg);
}
.btn-contrib-opt--female.selected {
  background: rgba(236, 126, 180, 0.14);
  border-color: var(--gender-female-fg);
  color: var(--gender-female-fg);
}
.btn-contrib-opt--unknown.selected {
  background: rgba(150, 150, 150, 0.10);
  border-color: var(--text-secondary, #888);
  color: var(--text-primary);
  font-style: italic;
}

/* CTR iteration: inline "Дякую!" confirmation shown briefly post-save
   before the picker closes (~2s). Subtle, not screaming — accent color
   on a slim line, no box around it. */
.contrib-confirmation {
  margin-top: 14px;
  padding: 8px 12px;
  text-align: center;
  font-size: 14px;
  font-weight: 500;
  color: var(--green, #2ea043);
  background: rgba(46, 160, 67, 0.08);
  border-radius: 6px;
  letter-spacing: 0.2px;
  animation: contribFadeIn 180ms ease-out;
}
@keyframes contribFadeIn {
  from { opacity: 0; transform: translateY(-3px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ─── Variant B: standalone word line (revert path) ────────────────────── */
.card-gender {
  font-size: 12px;
  font-weight: 500;
  margin-bottom: 3px;
}
.card-gender--female  { color: var(--gender-female-fg); }
.card-gender--male    { color: var(--gender-male-fg); }
.card-gender--unknown { color: var(--text-tertiary); }

/* Divider */
.card-divider {
  height: 1px;
  background: rgba(255,255,255,0.05);
  /* Sprint 2.9: margin: 0 — universal .resume-card > * rule дає mb:10.
     mt дефолтний 0; gap above the divider = prior sibling's mb. */
  margin: 0;
}

/* Requirement tags */
.card-requirements {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-bottom: 10px;
}
.req-tag {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 4px;
}
.req-tag.match   { background: rgba(63, 185, 80, 0.12);  color: var(--green); }
.req-tag.missing { background: rgba(248, 81, 73, 0.12);  color: var(--red); }
/* Commit 3: nice-to-have stays blue (semantic: info, NOT action). Decoupled
   from --accent so it doesn't accidentally inherit the new lime accent. */
.req-tag.nice    { background: rgba(47, 129, 247, 0.13); color: #58a6ff; }

/* Rejected: show only reason */
.rejected-reason {
  font-size: 12px;
  color: var(--red);
  margin: 5px 0 9px;
  line-height: 1.4;
}

/* Summary — body text для опису кандидата.
   У GitHub fg-default (#e6edf3) — основний; для блоків опису часто
   використовують fg-default напряму (бо --text-secondary занадто блідий
   для довгого читання). */
.card-summary {
  font-size: 13px;
  color: var(--text-primary);
  line-height: 1.55;
  margin-bottom: 7px;
}

/* Recommendation — accent-tinted block (як GitHub PR review note).
   Commit 3: rgba retuned to lime to match the new accent. */
.card-recommendation {
  font-size: 12px;
  color: var(--accent-hover);
  line-height: 1.5;
  background: rgba(47, 129, 247, 0.08);
  border-left: 2px solid rgba(47, 129, 247, 0.30);
  padding: 6px 10px;
  border-radius: 0 5px 5px 0;
  margin-bottom: 10px;
}

/* Card actions */
.card-actions {
  display: flex;
  gap: 7px;
  flex-wrap: wrap;
}

.card-btn {
  padding: 5px 12px;
  border-radius: 5px;
  font-size: 12px;
  font-weight: 500;
  transition: all 0.15s;
  border: 1px solid transparent;
}
.card-btn:disabled { opacity: 0.38; cursor: not-allowed; }

.card-btn-link {
  background: rgba(255,255,255,0.05);
  color: var(--text-secondary);
  border-color: var(--border-subtle);
}
.card-btn-link:hover { background: rgba(255,255,255,0.09); color: var(--text-primary); }

.card-btn-save {
  background: rgba(63, 185, 80, 0.12);
  color: var(--green);
  border-color: rgba(63, 185, 80, 0.25);
}
.card-btn-save:hover:not(:disabled) { background: rgba(63, 185, 80, 0.22); }

.card-btn-skip {
  background: rgba(248, 81, 73, 0.10);
  color: var(--red);
  border-color: rgba(248, 81, 73, 0.20);
}
.card-btn-skip:hover:not(:disabled) { background: rgba(248, 81, 73, 0.20); }

/* Sprint 2 Pillar 2: review / unreview buttons */
.card-btn-review {
  background: rgba(88, 166, 255, 0.10);
  color: var(--accent, #2f81f7);
  border-color: rgba(88, 166, 255, 0.22);
}
.card-btn-review:hover:not(:disabled) { background: rgba(88, 166, 255, 0.20); }
.card-btn-unreview {
  background: rgba(255, 255, 255, 0.04);
  color: var(--text-secondary);
  border-color: var(--border-subtle);
}
.card-btn-unreview:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.09);
  color: var(--text-primary);
}

/* ── Modal ───────────────────────────────────────────────────────────────── */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(4px) saturate(140%);
  -webkit-backdrop-filter: blur(4px) saturate(140%);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 16px;
  /* R5 refinement: fade in the backdrop. The .hidden class on the
     overlay short-circuits the animation (display:none), so it only
     plays when the overlay becomes visible. */
  animation: backdrop-in 200ms var(--ease-out);
}
@keyframes backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.modal {
  background: var(--bg-modal);
  border-radius: 16px;          /* R6: standardized modal radius (was 14px) */
  width: 720px;
  max-width: 100%;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.04),
    0 24px 64px rgba(0,0,0,0.55);
  /* Softened ~50% per owner feedback — modal pop-in was too bouncy.
     Smaller starting scale + --ease-snap (no overshoot) = gentle
     deceleration into place. Duration stays at --duration-base. */
  animation: modal-in var(--duration-base) var(--ease-snap);
}
@keyframes modal-in {
  from { opacity: 0; transform: scale(0.97); }
  to   { opacity: 1; transform: scale(1);    }
}

/* Modal sections — групують field'и логічно з заголовком */
.modal-section {
  border: 1px solid var(--border-subtle);
  border-radius: 10px;
  padding: 14px 16px 12px;
  background: rgba(255,255,255,0.02);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
[data-theme="light"] .modal-section {
  background: #eef1f5;       /* помітно сіріший за модал → білі інпути всередині попадають */
  border-color: #d8dde3;
}
.modal-section-title {
  font-size: 12px;
  font-weight: 700;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 2px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border-subtle);
}
.modal-section-danger {
  border-color: rgba(229, 57, 53, 0.4);
  background: rgba(229, 57, 53, 0.04);
}
.modal-section-danger .modal-section-title {
  color: var(--red);
}
.section-hint {
  font-size: 12px;
  color: var(--text-secondary);
  line-height: 1.5;
  margin: 0;
}
.btn-danger-soft {
  background: rgba(229, 57, 53, 0.08);
  border: 1px solid rgba(229, 57, 53, 0.3);
  color: var(--red);
  border-radius: 7px;
  padding: 9px 14px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  align-self: flex-start;
  transition: background 0.15s;
}
.btn-danger-soft:hover {
  background: rgba(229, 57, 53, 0.18);
}
.btn-danger-soft:disabled { opacity: 0.5; cursor: not-allowed; }

.modal-header {
  display: flex;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border-subtle);
}
.modal-header h3 { flex: 1; font-size: 16px; font-weight: 600; }

.modal-body {
  flex: 1;
  overflow-y: auto;
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 13px;
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.form-group > label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.4px;
}
.form-group input[type="text"],
.form-group input[type="password"],
.form-group input[type="url"],
.form-group input[type="date"],
.form-group textarea {
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(255,255,255,0.1);
  border-radius: 8px;                  /* R6: standardized input radius */
  color: var(--text-primary);
  padding: 9px 11px;
  font-size: 14px;
  resize: none;
  overflow: hidden;
  /* R6: smoother transition stack so focus halo + background animate together */
  transition:
    border-color 150ms var(--ease-out),
    background 150ms var(--ease-out),
    box-shadow 150ms var(--ease-out);
  line-height: 1.5;
  caret-color: var(--accent);
}
.form-group input:hover,
.form-group textarea:hover {
  border-color: rgba(255,255,255,0.18);
}

/* field-stack — вертикальний стек інпутів з гепом (для зміни пароля) */
.field-stack {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.form-group input:focus,
.form-group textarea:focus {
  outline: none;
  border-color: var(--accent);
  background: rgba(255,255,255,0.07);
  /* R6: focus halo matches the auth-page pattern (rgba 3px ring).
     Using a fixed blue rgba since --accent-glow is the same hue. */
  box-shadow: 0 0 0 3px rgba(47, 129, 247, 0.18);
}
.form-group small {
  font-size: 11px;
  color: var(--text-secondary);
}
/* Label row with inline generate button */
.form-group-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 1px;
}
.form-group-header label {
  margin-bottom: 0;
}

/* Generate keywords button */
.btn-generate {
  padding: 3px 10px;
  background: rgba(82,136,193,0.12);
  color: var(--accent);
  border: 1px solid rgba(82,136,193,0.25);
  border-radius: 5px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, opacity 0.15s;
  white-space: nowrap;
  flex-shrink: 0;
}
.btn-generate:hover    { background: rgba(82,136,193,0.22); }
.btn-generate:disabled { opacity: 0.45; cursor: not-allowed; }

/* Chips container */
.keyword-chips-container {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  margin-top: 6px;
  min-height: 0;
}
.keyword-chips-container:empty { margin-top: 0; }

/* Chip semantic:
     · неselected (default) — нейтральний сірий вигляд "не додано"
     · selected — м'який зелений з ✓, означає "додано в textarea"
   Раніше було інвертовано: блакитний за замовчуванням виглядав як "натиснуто",
   що збивало юзера. */
.keyword-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 11px;
  margin: 3px;
  border-radius: 12px;
  cursor: pointer;
  font-size: 12px;
  background: rgba(139, 148, 158, 0.10);   /* нейтральний сірий tint */
  color: var(--text-secondary);
  border: 1px solid var(--border);
  transition: background 0.12s, border-color 0.12s, color 0.12s;
  user-select: none;
}
.keyword-chip:hover {
  background: rgba(139, 148, 158, 0.18);
  color: var(--text-primary);
}
.keyword-chip.selected {
  background: rgba(63, 185, 80, 0.18);     /* soft green = "обрано/додано" */
  color: var(--green);
  border-color: rgba(63, 185, 80, 0.45);
  font-weight: 500;
}
.keyword-chip.selected::before {
  content: "✓";
  font-weight: 700;
}
.keyword-chip.selected:hover {
  background: rgba(63, 185, 80, 0.28);
}

/* Light theme — інші відтінки green (більш насичені на світлому фоні) */
[data-theme="light"] .keyword-chip {
  background: rgba(0, 0, 0, 0.04);
  color: var(--text-secondary);
  border-color: var(--border);
}
[data-theme="light"] .keyword-chip:hover {
  background: rgba(0, 0, 0, 0.07);
}
[data-theme="light"] .keyword-chip.selected {
  background: rgba(22, 163, 74, 0.12);
  color: #15803d;
  border-color: rgba(22, 163, 74, 0.40);
}
[data-theme="light"] .keyword-chip.selected:hover {
  background: rgba(22, 163, 74, 0.20);
}

.form-group-inline {
  flex-direction: row;
  align-items: center;
  gap: 10px;
}
.form-group-inline label {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-size: 14px;
  color: var(--text-primary);
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}
.form-group-inline input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
  cursor: pointer;
}

/* ─── Gender filter sprint: radio group inside the vacancy modal ────────────
   Horizontal row of three labeled radios (Будь-яка / Жінка / Чоловік).
   Vertical-collapse on narrow viewports via flex-wrap. Uses the modal's
   existing typographic tokens — no new vocabulary. */
.radio-group {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 6px;
}
.radio-option {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  cursor: pointer;
  font-size: 14px;
  color: var(--text-primary);
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}
.radio-option input[type="radio"] {
  width: 16px;
  height: 16px;
  accent-color: var(--accent);
  cursor: pointer;
  margin: 0;
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 9px;
  padding: 13px 20px;
  border-top: 1px solid var(--border-subtle);
}

/* ── Toast ───────────────────────────────────────────────────────────────── */
.toast-container {
  position: fixed;
  bottom: 24px;
  right: 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 200;
  pointer-events: none;
}

.toast {
  padding: 12px 16px;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.45;
  background: var(--bg-modal);
  color: var(--text-primary);
  border: 1px solid var(--border-subtle);
  border-left: 3px solid var(--accent);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.04),
    0 6px 20px rgba(0,0,0,0.40);
  /* R5: slide up from below + fade in. Snappy at 240ms, slight overshoot. */
  animation: toast-in 240ms var(--ease-overshoot);
  max-width: 420px;
  min-width: 240px;
  pointer-events: auto;
  backdrop-filter: blur(6px) saturate(140%);
  -webkit-backdrop-filter: blur(6px) saturate(140%);
}
@keyframes toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
[data-theme="light"] .toast {
  background: #ffffff;
  border-color: #d8dde3;
  box-shadow: 0 4px 14px rgba(15, 23, 42, 0.10);
}
.toast.success { border-left-color: var(--green); }
.toast.error   { border-left-color: var(--red); }
.toast.info    { border-left-color: var(--text-secondary); }
.toast.warning { border-left-color: #f5a623; }

/* ── Sprint 1: scan state machine UI ─────────────────────────────────────── */

/* Sprint 1.9: .paused-banner видалено — queue size показуємо inline
   у vacancy-meta subline ("⏸ На паузі · 215 у черзі"), pause duration
   у sidebar subtitle ("⏸ 215 у черзі · 3 хв тому"). */

/* ── Sprint 2.5 Feature 3 + Sprint 2.6 Feature A: active resume card highlight
   Юзер відкриває resume → переходить на work.ua → повертається. Active
   highlight показує "ось де я був". Sprint 2.6: TOGGLE semantics — click
   на ту саму card → deactivate. Link click → SET (no toggle).
   Per-vacancy localStorage persistence через restoreActiveResume().

   Чому outline а не border: outline не змінює layout, тому при toggle
   on/off карточка не "стрибає" по pixel'ах. outline-offset: -2px тримає
   outline ВСЕРЕДИНІ card boundary, не "наповзає" на сусідні елементи.
   Background tint видалили per Sprint 2.6 feedback — карточка більше не
   виглядає "alarming". */
.resume-card.user-active {
  outline: 2px solid #dc2626;                /* red-600 */
  outline-offset: -2px;
}

/* ── Sprint 2.5: tab reorder + separator ───────────────────────────────────── */
.tabs-separator {
  display: inline-block;
  width: 1px;
  height: 22px;
  background: var(--border, #30363d);
  margin: 0 6px;
  vertical-align: middle;
  flex-shrink: 0;
}
/* Перевірені tab — neutral with subtle green hint (completed bucket).
   Refinement R2: deliberately MORE muted than the "relevant" tab — same
   green hue but less saturation, since "completed" is a workflow state
   not a verdict. Text stays neutral (not green) for the same reason. */
.filter-btn--reviewed {
  border-color: rgba(63, 185, 80, 0.18);
}
.filter-btn--reviewed:hover {
  background: rgba(63, 185, 80, 0.06);
}
.filter-btn--reviewed.active {
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(63, 185, 80, 0.35);
  color: var(--text-primary);
}
.filter-btn--reviewed.active .filter-btn-count {
  background: rgba(63, 185, 80, 0.14);
  color: var(--text-primary);
}

/* ── Sprint 2.5: Review modal (outcome + comment) ─────────────────────────── */
.review-options {
  display: flex;
  gap: 10px;
  margin: 12px 0 18px;
}
.btn-outcome {
  flex: 1;
  padding: 10px 14px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.04);
  color: var(--text-primary);
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: background 0.15s, border-color 0.15s;
}
.btn-outcome:hover {
  background: rgba(255, 255, 255, 0.08);
}
.btn-outcome.selected.btn-outcome-matched {
  background: rgba(63, 185, 80, 0.18);
  border-color: rgba(63, 185, 80, 0.55);
  color: var(--green);
}
.btn-outcome.selected.btn-outcome-not-matched {
  background: rgba(248, 81, 73, 0.18);
  border-color: rgba(248, 81, 73, 0.55);
  color: var(--red);
}
.comment-label {
  display: block;
  font-size: 13px;
  color: var(--text-secondary);
  margin-bottom: 6px;
}
#review-comment {
  width: 100%;
  padding: 8px 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 13px;
  resize: vertical;
  min-height: 60px;
}

/* Outcome badge на reviewed cards */
.review-outcome-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  margin-left: 8px;
}
.review-outcome-badge--matched {
  background: rgba(63, 185, 80, 0.18);
  color: var(--green);
}
.review-outcome-badge--not-matched {
  background: rgba(248, 81, 73, 0.18);
  color: var(--red);
}
.review-comment-quote {
  /* Sprint 2.9: margin-top видалено — universal .resume-card > * rule
     дає 10px gap від prior sibling. Bottom margin теж з universal rule. */
  padding: 6px 10px;
  border-left: 2px solid var(--border);
  font-style: italic;
  font-size: 13px;
  color: var(--text-secondary);
}

/* Sprint 2.9: change-mark dropdown (replaces single "Зняти позначку").
   Toggle popover з 2 options: move до opposite outcome, або clear до загального
   пулу. Position: fixed (виходить за межі card overflow). */
.change-mark-dropdown {
  background: var(--bg-modal);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.40);
  padding: 4px 0;
  z-index: 1000;
  min-width: 240px;
  animation: fadeIn 0.12s ease;
}
.change-mark-option {
  display: block;
  width: 100%;
  padding: 9px 14px;
  background: transparent;
  border: none;
  color: var(--text-primary);
  font-size: 13px;
  text-align: left;
  cursor: pointer;
  transition: background 0.1s;
}
.change-mark-option:hover {
  background: rgba(255, 255, 255, 0.07);
}
[data-theme="light"] .change-mark-option:hover {
  background: rgba(0, 0, 0, 0.05);
}

/* ── Sprint 2.8: Перевірені tab — sub-tabs UX ─────────────────────────────────
   Замінює Sprint 2.6 sections. Toggle bar з 2 buttons (Підійшли / Не підійшли),
   кожна показує counter + одна "active" за раз. Default → matched (позитивні
   зверху). Resume cards renderяться під bar, тільки visible subtab cards. */
.reviewed-subtabs {
  display: flex;
  gap: 8px;
  padding: 0 0 12px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--border-subtle);
}
.reviewed-subtab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px;
  background: transparent;
  color: var(--text-secondary);
  border: 1px solid var(--border-subtle);
  border-radius: 7px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.reviewed-subtab:hover {
  background: rgba(255,255,255,0.05);
  color: var(--text-primary);
}
.reviewed-subtab.active {
  /* default (matched) active — green tint */
  background: rgba(63, 185, 80, 0.13);
  border-color: rgba(63, 185, 80, 0.50);
  color: var(--green);
}
.reviewed-subtab[data-subtab="not_matched"].active {
  background: rgba(248, 81, 73, 0.13);
  border-color: rgba(248, 81, 73, 0.50);
  color: var(--red);
}
.reviewed-subtab-badge {
  background: rgba(255,255,255,0.08);
  padding: 1px 8px;
  border-radius: 11px;
  font-size: 11px;
  font-weight: 600;
  min-width: 22px;
  text-align: center;
}
.reviewed-subtab.active .reviewed-subtab-badge {
  background: rgba(255,255,255,0.18);
}

/* Light theme — інші відтінки */
[data-theme="light"] .reviewed-subtab {
  background: #ffffff;
  border-color: var(--border);
}
[data-theme="light"] .reviewed-subtab:hover {
  background: #f1f5f9;
}
[data-theme="light"] .reviewed-subtab.active {
  background: rgba(22, 163, 74, 0.12);
  border-color: rgba(22, 163, 74, 0.45);
  color: #15803d;
}
[data-theme="light"] .reviewed-subtab[data-subtab="not_matched"].active {
  background: rgba(220, 38, 38, 0.10);
  border-color: rgba(220, 38, 38, 0.45);
  color: #b91c1c;
}
[data-theme="light"] .reviewed-subtab-badge {
  background: rgba(0,0,0,0.07);
}
[data-theme="light"] .reviewed-subtab.active .reviewed-subtab-badge {
  background: rgba(255,255,255,0.55);
  color: inherit;
}

.reviewed-content {
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.reviewed-empty-sub {
  text-align: center;
  color: var(--text-secondary);
  padding: 40px 20px;
  font-size: 14px;
  font-style: italic;
}

/* Sprint 2 Pillar 3: countdown timer на vacancy detail. Muted, нижче subline. */
.vacancy-countdown {
  margin-top: 3px;
  font-size: 12px;
  color: var(--text-secondary);
  font-feature-settings: "tnum";   /* tabular nums — minutes/seconds не jumpа */
}

/* Sprint 1.7: .archived-banner видалено — використовуємо inline "📁 Архівовано"
   у vacancy-meta subline + actual "📂 Розархівувати" CTA button. */

/* Sidebar state badges */
.vacancy-state-badge {
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: 6px;
}
.vacancy-state-badge--scanning { background: rgba(80, 120, 200, 0.18); color: #5078c8; }
.vacancy-state-badge--paused   { background: rgba(245, 166, 35, 0.18); color: #f5a623; }

/* Sprint 1.6: pinned tile renders as full vacancy-card (inherits .vacancy-item
   shape — same padding/gap/avatar circle/hover). Тільки accent кольори
   на avatar + separator відділяють як navigation елемент. */
.pinned-tile {
  /* Inherits .vacancy-item base. Add bottom separator щоб відокремити
     навігаційний елемент від списку vacancies. */
  border-bottom: 1px solid var(--border);
  margin-bottom: 4px;
}
.pinned-tile-avatar {
  /* Інший accent для avatar — blue tint щоб відрізнити "navigation" від
     vacancy avatars (greenish-grey). */
  background: rgba(88, 166, 255, 0.16) !important;
  color: var(--accent, #2f81f7);
}
/* Archive-view active state — bolder accent на avatar + tile background.
   Юзер бачить що "ти зараз у архіві" на pinned-tile навіть коли gaze на
   список нижче. */
.pinned-tile--archive-active {
  background: rgba(88, 166, 255, 0.06);
}
.pinned-tile--archive-active:hover {
  background: rgba(88, 166, 255, 0.12);
}
.pinned-tile--archive-active .pinned-tile-avatar {
  background: rgba(88, 166, 255, 0.28) !important;
  color: var(--accent, #2f81f7);
}

/* Hide run-all button у archive mode (через class на sidebar parent) */
.sidebar.archive-mode .btn-run-all {
  display: none;
}

/* Sprint 1.8: static "Архів" header у archive mode.
   ВАЖЛИВО: explicit fixed height + flex centering щоб box був ідентичного
   розміру з btn-run-all (~36-38px) незалежно від font-size всередині.
   Це гарантує що pinned tile під ним не зміщується між modes.
   line-height: 1 — щоб high-font icon/text не розпухала контейнер. */
.sidebar-mode-header {
  display: none;                /* hidden у working mode */
  box-sizing: border-box;
  height: 36px;                 /* match btn-run-all rendered height */
  padding: 0 12px;
  align-items: center;
  justify-content: center;
  line-height: 1;
  font-size: 17px;
  font-weight: 700;
  color: var(--text-primary);
  user-select: none;
  /* НЕ interactive — no cursor, no hover */
}
.sidebar-mode-header-icon {
  font-size: 18px;
  margin-right: 8px;
  line-height: 1;
}
.sidebar.archive-mode .sidebar-mode-header {
  display: flex;                /* unhide + use flex для centering */
}

/* Empty archive list message */
.archive-empty {
  padding: 24px 16px;
  color: var(--text-secondary);
  font-size: 13px;
  text-align: center;
}

.vacancy-item--archived {
  opacity: 0.7;   /* було 0.55 — менше grey, бо ці зараз primary content у архіві */
}

/* Continue Options modal — narrower */
.modal-narrow { max-width: 440px; }
/* v2.2 changelog modal — wider so highlight bullets read in a single column */
.modal-wide { max-width: 600px; }
.modal-lead { color: var(--text-secondary); margin-bottom: 16px; font-size: 14px; }

/* ── v2.2: "Що нового" changelog modal ─────────────────────────────────────
   Each entry is a bordered block: title + version-tag + bullet list.
   Bullets carry highlight strings verbatim from changelog.json (emojis are
   already in the source strings; CSS just spaces them out).
   Last entry has no bottom border so the divider doesn't bleed into the
   modal footer. */
.changelog-entry {
  margin-bottom: 22px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border);
}
.changelog-entry:last-child {
  border-bottom: none;
  margin-bottom: 6px;
  padding-bottom: 4px;
}
.changelog-entry-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 10px;
  flex-wrap: wrap;
}
.changelog-entry-header h4 {
  margin: 0;
  font-size: 16px;
  color: var(--text-primary);
  font-weight: 600;
}
.changelog-version {
  font-size: 12px;
  color: var(--text-secondary);
  font-family: var(--font-mono);
  white-space: nowrap;
}
.changelog-highlights {
  list-style: none;
  padding: 0;
  margin: 0;
}
.changelog-highlights li {
  padding: 5px 0;
  color: var(--text-primary);
  line-height: 1.5;
  font-size: 14px;
}
.continue-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.continue-option-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.15s;
}
.continue-option-row:hover { background: rgba(80, 120, 200, 0.04); }
.continue-option-row input[type=radio]:checked + label { font-weight: 600; }
.continue-option-row label { flex: 1; cursor: pointer; }
.continue-option-row .period-select {
  padding: 4px 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-primary);
  font-size: 13px;
}
.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 16px;
  border-top: 1px solid var(--border);
}

/* ── Duplicate vacancy banner (Sprint 5) ────────────────────────────────── */
/* Над URL input у "Нова Вакансія" модалі. Showed коли check_duplicate
   повертає found=true. Дві варіації — own (info) і shared (action). */
.dup-banner {
  margin-bottom: 10px;
  padding: 10px 12px;
  border-radius: 6px;
  font-size: 13px;
  line-height: 1.45;
  border-left: 3px solid var(--text-secondary);
  background: rgba(80, 120, 200, 0.08);
}
.dup-banner--self {
  border-left-color: var(--text-secondary);
  background: rgba(80, 120, 200, 0.08);
}
.dup-banner--shared {
  border-left-color: var(--green, #34c759);
  background: rgba(52, 199, 89, 0.08);
}
/* Hotfix v2.2.1 Bug B: multi-owner picker variant. Same shared green
   border, but the body holds a radio list. Subtle visual delta vs
   single-shared so the user sees "this is a choice, not a single CTA". */
.dup-banner--picker {
  border-left-color: var(--green, #34c759);
  background: rgba(52, 199, 89, 0.06);
}
.dup-picker-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 8px 0 4px;
}
.dup-picker-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.12s;
}
.dup-picker-row:hover {
  background: rgba(52, 199, 89, 0.08);
}
.dup-picker-row input[type="radio"] {
  margin-top: 3px;
}
.dup-picker-row-body {
  flex: 1;
  display: block;
}
.dup-picker-row-body small {
  display: block;
  color: var(--text-secondary);
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.4;
}
/* Hotfix v2.2.1: .dup-picker-badge removed (was the "найкраще" tag).
   Recruiter now picks by the per-row data (counts + city + since_date +
   keywords_count + last scan), no opinionated heuristic. */
.dup-banner b   { color: var(--text-primary); }
.dup-banner small { display: block; color: var(--text-secondary); margin-top: 4px; }
.dup-banner-actions {
  margin-top: 8px;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.dup-banner-actions button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 6px 14px;
  font-size: 13px;
  font-family: var(--font-ui);
  font-weight: 500;
  border-radius: 8px;                  /* R6: matched to other small buttons */
  cursor: pointer;
  background: var(--accent);
  color: white;
  border: none;
  transition:
    background 150ms var(--ease-out),
    transform 120ms var(--ease-out);
}
.dup-banner-actions button:hover {
  background: var(--accent-hover);
  transform: translateY(-1px);
}
.dup-banner-actions button:active { transform: translateY(0); transition-duration: 60ms; }
.dup-banner-actions button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}
.dup-banner-actions button.secondary {
  background: transparent;
  color: var(--text-primary);
  border: 1px solid var(--border);
}

/* Undo toast — з кнопкою "Скасувати" */
.toast.undo-toast {
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: 360px;
}
.toast.undo-toast .undo-msg { flex: 1; }
.toast.undo-toast .undo-btn {
  background: transparent;
  border: 1px solid var(--accent);
  color: var(--accent);
  border-radius: 6px;
  padding: 4px 10px;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
}
.toast.undo-toast .undo-btn:hover {
  background: var(--accent);
  color: white;
}

/* ── Animations ──────────────────────────────────────────────────────────── */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes slideIn {
  from { transform: translateX(110%); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}
@keyframes slideOut {
  from { transform: translateX(0);    opacity: 1; }
  to   { transform: translateX(110%); opacity: 0; }
}
@keyframes spin {
  to { transform: rotate(360deg); }
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.25; }
}

/* ── v2.1: Support / feedback modal ──────────────────────────────────────── */
.support-field {
  display: block;
  margin-bottom: 16px;
  font-size: 13px;
  color: var(--text-secondary);
}
.support-field select,
.support-field textarea {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 8px 10px;
  background: var(--bg-input);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: inherit;
  font-size: 14px;
  box-sizing: border-box;
}
.support-field textarea {
  resize: vertical;
  min-height: 120px;
  line-height: 1.45;
}
.support-required {
  color: var(--red);
  margin-left: 2px;
}
.support-char-counter {
  display: block;
  text-align: right;
  margin-top: 4px;
  font-size: 11px;
  color: var(--text-secondary);
  opacity: 0.7;
}
.support-char-counter.over-limit { color: var(--red); opacity: 1; }
/* Native <select> dropdown opens with the OS picker, which uses its own
   white background for the option list. Without explicit option colors,
   the dark-theme `color: var(--text)` (≈ white) bleeds through →
   white-on-white invisible options. Force black-on-white inside the
   dropdown list to ensure readability across themes.
   Browser support note: Chrome/Edge respect option { color, background }.
   Firefox partially. Safari ignores. Owner is on Chrome — verified path. */
#support-category option {
  color: #000;
  background: #fff;
}
#support-category option:checked,
#support-category option:hover {
  color: #fff;
  background: #3b82f6;
}
.support-success {
  margin-top: 16px;
  padding: 12px 14px;
  background: rgba(63, 185, 80, 0.12);
  border: 1px solid rgba(63, 185, 80, 0.32);
  border-radius: 6px;
  color: var(--green);
  font-size: 14px;
  text-align: center;
}

/* ── Utilities ───────────────────────────────────────────────────────────── */
.hidden { display: none !important; }

/* Scrollbars */
::-webkit-scrollbar       { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.18); }

/* ── Task 3: filter tab activation flash ─────────────────────────────────
   Brief accent-glow burst when a filter tab becomes .active. Animation
   runs once per class addition (browser re-triggers when the class
   transitions off→on). Subtle: 360ms, peaks at ~150ms then fades. */
@keyframes filter-tab-flash {
  0%   { box-shadow: 0 0 0 0 rgba(47, 129, 247, 0);    }
  25%  { box-shadow: 0 0 0 4px rgba(47, 129, 247, 0.22); }
  100% { box-shadow: 0 0 0 0 rgba(47, 129, 247, 0);    }
}

/* ── Task 3: accessibility — prefers-reduced-motion ───────────────────────
   Required for accessibility per WCAG 2.3.3. Disables all animations and
   shortens transitions to near-instant for users who've asked the OS to
   reduce motion. Animation/transition durations forced via !important
   override the spring tokens. */
@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;
  }
}
