.task-description-textarea {
  height: 66vh;
  min-height: 300px;
  resize: vertical;
  width: 100%;
}

/* «Ссылки на размещение» — cap the loaded rows at ~10 visible (each row is
   roughly 42px at py-1) before scrolling internally, so a long list doesn't
   push the card (and the add-link field below it) further down the page. */
.links-scroll-list {
  max-height: 420px;
  overflow-y: auto;
}

.link-dropzone {
  border: 1px dashed transparent;
  border-radius: 0.375rem;
  transition: border-color 0.15s, background-color 0.15s;
}

.link-dropzone-active {
  border-color: #0d6efd;
  background-color: rgba(13, 110, 253, 0.06);
}

.toast-stack {
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 4000;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-width: 360px;
}

.toast-item {
  padding: 0.6rem 0.9rem;
  border-radius: 0.375rem;
  color: #fff;
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.2);
  font-size: 0.9rem;
  cursor: pointer;
  animation: toast-in 0.2s ease-out;
}

.toast-success { background: #198754; }
.toast-error { background: #dc3545; }
.toast-warning { background: #fd7e14; }
.toast-info,
.toast-debug { background: #0d6efd; }

.toast-item.toast-hiding {
  opacity: 0;
  transition: opacity 0.4s ease;
}

@keyframes toast-in {
  from { opacity: 0; transform: translateX(1rem); }
  to { opacity: 1; transform: none; }
}

/* Комментарии/Переназначить's text fields — grow with typed content up to
   500px, then scroll inside the field itself rather than pushing the card
   (and the whole page) taller. */
.capped-textarea {
  max-height: 500px;
  overflow-y: auto;
  min-height: 90px;
}

.rubric-picker {
  position: relative;
}

/* «Настройки инфоповода» gives every other field's label class="form-label
   small mb-1" — the rubric picker is a shared widget (also used unstyled on
   task creation) so its own label keeps Bootstrap's default form-label size
   there; scoped to just this one context instead of touching the shared
   widget or task_form.html's matching plain labels. */
.infopovod-settings-form .rubric-picker .form-label {
  font-size: 0.875em;
  margin-bottom: 0.25rem;
}

/* Same shared-widget scoping as above — the "Можно выбрать несколько
   рубрик." hint is redundant clutter in this compact settings card
   specifically; task_form.html's own roomier layout keeps it. */
.infopovod-settings-form .rubric-picker .form-text {
  display: none;
}

.rubric-toggle {
  width: 100%;
  cursor: pointer;
  background-color: var(--bs-body-bg);
}

.rubric-options {
  max-height: 220px;
  overflow-y: auto;
}

.rubric-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 3500;
  display: flex;
  align-items: center;
  justify-content: center;
}

.rubric-modal-overlay.d-none {
  display: none;
}

.rubric-modal {
  background: var(--bs-body-bg);
  border-radius: 0.5rem;
  padding: 1rem;
  width: 90%;
  max-width: 420px;
  max-height: 80vh;
  overflow-y: auto;
  box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.3);
}

.rubric-modal-list {
  max-height: 50vh;
  overflow-y: auto;
}

.mention-dropdown {
  position: absolute;
  z-index: 1000;
  bottom: 100%;
  left: 0;
  margin-bottom: 4px;
  width: 320px;
  max-width: 90%;
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: 0.375rem;
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
  max-height: 220px;
  overflow-y: auto;
}

.mention-dropdown-item {
  padding: 0.4rem 0.6rem;
  cursor: pointer;
  font-size: 0.9rem;
}

.mention-dropdown-item:hover,
.mention-dropdown-item.active {
  background: var(--bs-tertiary-bg);
}

.task-description-view p {
  margin-bottom: 0.5rem;
}

.task-description-view ol,
.task-description-view ul {
  margin-bottom: 0.5rem;
}

/* Read-only rich text is wrapped in .ql-editor so Quill's own format classes
   (ql-size-*, ql-align-*) render correctly outside the editor — but reset
   the editor-chrome parts of that class (padding/height/scroll/cursor) since
   this is plain display, not an editable surface. Quill's own vendor CSS
   also sets line-height: 1.42 directly on .ql-editor — a rule applied right
   on this element beats anything inherited from an ancestor (e.g. the
   .task-detail page wrapper's denser 1.35), no matter that ancestor's
   specificity, so it has to be reset here too. */
.task-description-view.ql-editor {
  padding: 0;
  height: auto;
  overflow: visible;
  line-height: 1.35;
}

/* Размещение renders these blocks full-width, so the same line-height reads
   airier than it does at half-width (fewer, longer wrapped lines) — tighter
   still, scoped to just this role. */
.task-detail-placement .task-description-view.ql-editor {
  line-height: 1.2;
}

.task-description-view.ql-editor > * {
  cursor: auto;
}

/* Every card-header should read as the same height regardless of content —
   a plain text label vs. one carrying buttons (e.g. «Вложения») shouldn't
   make some cards start their body lower than their neighbors. 41px matches
   the tallest existing header (buttons + py-1 padding); flex+align-items
   centers plain-text headers within that same height instead of leaving
   them top-aligned with slack below. Headers that already set their own
   flex layout (d-flex justify-content-between, a Bootstrap !important
   utility) keep that — this only supplies the height and vertical centering. */
.card-header {
  min-height: 41px;
  display: flex;
  align-items: center;
}

/* Denser layout for the task detail page — default Bootstrap spacing between
   headings/cards/list items reads too airy once several stacked blocks
   (status panel, attachments, comments, history) are all on one page. */
.task-detail {
  line-height: 1.35;
}

.task-detail h3,
.task-detail h5 {
  line-height: 1.25;
}

.task-detail .list-group-item {
  padding-top: 0.4rem;
  padding-bottom: 0.4rem;
}

.task-detail .card-body {
  line-height: 1.35;
}

.task-detail .form-label.small {
  font-size: 0.8rem;
}

/* Border goes on the wrapper, not .richtext-editor — after Quill init that
   element is also .ql-container.ql-snow, whose border:none rule below is more
   specific and would otherwise cancel a border set here. */
.richtext-wrapper {
  /* без внешней рамки: панель инструментов и «лист» оформлены в richtext_widget.css */
  border: 0;
  overflow: visible;
}

.richtext-wrapper .ql-toolbar.ql-snow {
  border: none;
}

.richtext-wrapper .ql-container.ql-snow {
  border: none;
}

.richtext-wrapper .ql-editor {
  height: 66vh;
  min-height: 300px;
  resize: vertical;
  overflow-y: auto;
}
/* к описанию добавлен документ (PDF/Word, см. description_docs.js) — само поле описания низкое */
.desc-has-docs .richtext-wrapper .ql-editor { height: 160px; min-height: 160px; }

.assignee-picker {
  position: relative;
}

.assignee-picker-toggle {
  width: 100%;
  cursor: pointer;
  background-color: var(--bs-body-bg);
}

.assignee-picker-panel {
  position: absolute;
  z-index: 1000;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 2px;
  background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color);
  border-radius: 0.375rem;
  max-height: 340px;
  display: flex;
  flex-direction: column;
  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}

.assignee-picker-panel.d-none {
  display: none;
}

.assignee-picker-search {
  margin: 0.5rem;
  width: calc(100% - 1rem);
}

.assignee-picker-groups {
  overflow-y: auto;
  padding: 0 0.5rem 0.5rem;
}

/* Заголовок блока отработки — фоновая полоса во всю ширину, чтобы блоки было легко различить в длинном списке */
.assignee-picker-group-title {
  font-weight: 600;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: .02em;
  color: var(--bs-emphasis-color);
  background: var(--bs-secondary-bg);
  border-radius: 0.3rem;
  margin: 0.6rem 0 0.2rem;
  padding: 0.35rem 0.5rem;
}
.assignee-picker-group:first-child .assignee-picker-group-title { margin-top: 0.3rem; }
.assignee-picker-all-toggle { display: flex; align-items: center; gap: 0.4rem; cursor: pointer; margin: 0.4rem 0.5rem 0; }
.assignee-picker-role { color: var(--bs-secondary-color); margin-left: auto; text-align: right; }

/* The block header doubles as a "select the whole block" checkbox. */
.assignee-picker-block-toggle {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
  margin-bottom: 0.15rem;
}

.assignee-picker-block-toggle input {
  margin: 0;
}

.assignee-picker-item {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem;
  border-radius: 0.25rem;
  cursor: pointer;
  font-size: 0.9rem;
  margin-bottom: 0;
}

.assignee-picker-item:hover {
  background: var(--bs-tertiary-bg);
}

.assignee-picker-item input {
  margin: 0;
}

.assignee-picker-item.is-hidden {
  display: none;
}

/* Picked at your own risk — submitting with one of these still selected gets
   hard-rejected server-side (see forms.AvailabilityCheckMixin), this is just
   the early warning. */
.assignee-picker-item-away {
  color: #997404;
}

.assignee-picker-group.is-hidden {
  display: none;
}

/* «Все сотрудники» под блоками и уточняющие поля для выбранных оттуда (роль — только в этом инфоповоде). */
.assignee-picker-guest-group {
  border-top: 1px solid var(--bs-border-color);
  margin-top: 0.5rem;
}

.assignee-picker-guest-item small {
  margin-left: auto;
  max-width: 50%;
}

.assignee-picker-guest-details:empty {
  display: none;
}

.assignee-guest-card {
  border: 1px solid var(--bs-border-color);
  border-radius: 0.375rem;
  padding: 0.5rem 0.75rem;
  margin-top: 0.5rem;
  background: var(--bs-tertiary-bg);
}

.assignee-guest-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
}

.assignee-guest-label {
  font-size: 0.8rem;
  color: var(--bs-secondary-color);
  margin: 0.25rem 0 0.15rem;
}

.assignee-guest-options {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.75rem;
}

.assignee-guest-options label {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.875rem;
  margin: 0;
  cursor: pointer;
}

.assignee-guest-card.is-incomplete {
  border-color: var(--bs-warning);
}

.attachment-strip {
  display: flex;
  gap: 0.5rem;
  height: 250px;
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: 0.25rem;
}

.attachment-strip-loading {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  height: 250px;
  color: var(--bs-secondary-color);
}

.attachment-strip-loading.d-none {
  display: none;
}

.attachment-thumb {
  position: relative;
  flex: 0 0 auto;
  height: 100%;
  border-radius: 0.375rem;
  overflow: hidden;
  cursor: pointer;
  background: var(--bs-tertiary-bg);
  border: 1px solid var(--bs-border-color);
}

.attachment-thumb img,
.attachment-thumb video {
  height: 100%;
  width: auto;
  max-width: 420px;
  object-fit: cover;
  display: block;
  pointer-events: none;
}

.attachment-thumb[draggable="true"] {
  cursor: grab;
}

.attachment-thumb.dragging {
  opacity: 0.4;
}

/* Keep the thumb itself the drag source — don't let the browser start a
   native image/link drag from inside it. */
.attachment-thumb-file-link,
.attachment-thumb-icon {
  -webkit-user-drag: none;
  user-select: none;
}

.attachment-drop-target {
  position: relative;
  transition: background-color 0.15s ease;
}

.attachment-drop-target.attachment-dropzone-active {
  background-color: rgba(13, 110, 253, 0.06);
}

.attachment-dropzone-overlay {
  position: absolute;
  inset: 0.25rem;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px dashed #0d6efd;
  border-radius: 0.375rem;
  background: rgba(13, 110, 253, 0.06);
  pointer-events: none;
}

.attachment-dropzone-message {
  font-weight: 600;
  color: #0d6efd;
}

.page-dropzone-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 4px dashed #0d6efd;
  background: rgba(13, 110, 253, 0.1);
  pointer-events: none;
}

.page-dropzone-overlay.d-none {
  display: none;
}

.page-dropzone-message {
  padding: 1rem 2rem;
  border-radius: 0.5rem;
  background: var(--bs-body-bg);
  box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.2);
  font-size: 1.25rem;
  font-weight: 600;
  color: #0d6efd;
}

.attachment-thumb-uploading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 160px;
  padding: 0.5rem;
  font-size: 0.8rem;
  text-align: center;
  color: var(--bs-secondary-color);
  word-break: break-word;
  line-height: 1.3;
}

.attachment-thumb-uploading .spinner-border {
  color: #0d6efd;
}

.attachment-uploading-filename {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.attachment-thumb-video::after {
  content: "▶";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 1.5rem;
  color: #fff;
  text-shadow: 0 0 4px rgba(0, 0, 0, 0.7);
  pointer-events: none;
}

.attachment-thumb-file,
.attachment-thumb-pending,
.attachment-thumb-failed {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 220px;
  padding: 0.5rem;
  font-size: 0.85rem;
  text-align: center;
  color: var(--bs-secondary-color);
  text-decoration: none;
  word-break: break-word;
  cursor: default;
  line-height: 1.3;
}

.attachment-thumb-icon {
  font-size: 2.5rem;
  line-height: 1;
  display: block;
  margin-bottom: 0.4rem;
}

.btn-icon {
  font-size: 1.25rem;
  line-height: 1;
  padding-top: 0.15rem;
  padding-bottom: 0.15rem;
}

a.attachment-thumb-file {
  cursor: pointer;
  color: var(--bs-secondary-color);
}

.attachment-thumb-file-link {
  color: inherit;
  text-decoration: none;
  display: block;
  cursor: pointer;
}

.attachment-lightbox {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.85);
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3rem 2rem;
}

.attachment-lightbox.d-none {
  display: none;
}

.attachment-lightbox-body {
  max-width: 100%;
  max-height: 100%;
}

.attachment-lightbox-media {
  max-width: 100%;
  max-height: calc(100vh - 6rem);
  display: block;
  margin: 0 auto;
  border-radius: 0.25rem;
}

.attachment-lightbox-iframe {
  width: 85vw;
  height: calc(100vh - 6rem);
  max-width: 1100px;
  border: none;
  background: #fff;
}

.attachment-lightbox-close {
  position: absolute;
  top: 1rem;
  right: 1.5rem;
  font-size: 2rem;
  color: #fff;
  background: none;
  border: none;
  cursor: pointer;
  line-height: 1;
  /* Above .attachment-lightbox-nav (z-index: 1) — on narrow screens the
     next/prev strips span the full height up to the edge and would
     otherwise swallow taps meant for the close button in the corner. */
  z-index: 2;
}

.attachment-lightbox-nav {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 90px;
  max-width: 12vw;
  background: none;
  border: none;
  color: rgba(255, 255, 255, 0.65);
  font-size: 3rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.15s, color 0.15s;
  z-index: 1;
}

.attachment-lightbox-nav:hover {
  background-color: rgba(255, 255, 255, 0.08);
  color: #fff;
}

.attachment-lightbox-nav.d-none {
  display: none;
}

.attachment-lightbox-prev {
  left: 0;
}

.attachment-lightbox-next {
  right: 0;
}

.attachment-lightbox-counter {
  position: absolute;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  color: #fff;
  background: rgba(0, 0, 0, 0.55);
  padding: 0.25rem 0.9rem;
  border-radius: 1rem;
  font-size: 0.85rem;
  z-index: 1;
}

.attachment-lightbox-counter.d-none {
  display: none;
}

.edit-lock-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.edit-lock-modal-overlay.d-none {
  display: none;
}

.edit-lock-modal {
  background: var(--bs-body-bg);
  border-radius: 0.5rem;
  padding: 1.25rem;
  max-width: 380px;
  width: 90%;
  box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.3);
}

.attachment-thumb-remove {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 20px;
  height: 20px;
  line-height: 18px;
  text-align: center;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  font-size: 0.8rem;
  border: none;
  cursor: pointer;
  padding: 0;
}

.attachment-thumb-remove:hover {
  background: rgba(220, 53, 69, 0.9);
}

/* Ссылки на размещение — invalid rows stay reddish; the row the error banner
   was clicked into (browser's native #anchor scroll, via :target) gets a
   brief extra flash so it's unmistakable which one you landed on. */
.link-row-invalid,
.link-row-duplicate {
  background: rgba(220, 53, 69, 0.12);
}

.link-row:target {
  animation: link-row-flash 1.6s ease;
}

@keyframes link-row-flash {
  from { background: rgba(220, 53, 69, 0.4); }
  to { background: inherit; }
}

/* infopovod_list row backgrounds — see _infopovod_row_highlight in
   views.py for the priority these are applied in (archived > overdue >
   due-soon > assigned-to-me). Bootstrap's .table paints background-color
   on each <td> individually (via var(--bs-table-bg)), which occludes any
   background set directly on the <tr> -- so, same as Bootstrap's own
   .table-success/.table-danger/etc., these set the --bs-table-* custom
   properties instead and let the cells' own var() lookups pick them up.
   --bs-table-hover-bg/-color are set too so .table-hover's hover tint
   doesn't just flash back to the untinted default on mouseover. */
.row-archived {
  --bs-table-color: var(--bs-secondary-color);
  --bs-table-bg: rgba(108, 117, 125, 0.1);
  --bs-table-hover-bg: rgba(108, 117, 125, 0.18);
  --bs-table-hover-color: var(--bs-secondary-color);
}

.row-assigned-to-me {
  --bs-table-bg: rgba(25, 135, 84, 0.12);
  --bs-table-hover-bg: rgba(25, 135, 84, 0.2);
}

.row-overdue {
  --bs-table-bg: rgba(220, 53, 69, 0.12);
  --bs-table-hover-bg: rgba(220, 53, 69, 0.2);
}

.row-due-soon {
  --bs-table-bg: rgba(255, 193, 7, 0.15);
  --bs-table-hover-bg: rgba(255, 193, 7, 0.25);
}

/* A block is sitting at "На проверке" (director approval) — blinking, not
   just tinted, since this is a bottleneck someone needs to actively clear
   rather than a passive status like row-due-soon. Steps (not a smooth
   fade) between two --bs-table-bg values so it reads as a blink even
   without registering the custom property via @property. */
.row-pending-approval {
  animation: row-pending-approval-blink 1.2s step-end infinite;
}

@keyframes row-pending-approval-blink {
  0%, 49% {
    --bs-table-bg: rgba(255, 193, 7, 0.35);
    --bs-table-hover-bg: rgba(255, 193, 7, 0.45);
  }
  50%, 100% {
    --bs-table-bg: rgba(255, 193, 7, 0.08);
    --bs-table-hover-bg: rgba(255, 193, 7, 0.18);
  }
}

/* Комментарии — linebreaks-filtered text wraps every paragraph in its own
   <p>, which carries Bootstrap's Reboot default bottom margin (1rem); left
   as-is that reads as a whole blank line between the comment text and its
   «Ответить»/«Редактировать»/«Удалить» row right below it. */
.comment-text-view p:last-child {
  margin-bottom: 0.25rem;
}

/* Cap the thread at roughly 5 comments' worth of height before scrolling
   internally — same idea as .links-scroll-list above, applied here so a
   long-running thread doesn't push the compose box further down the page. */
.comments-scroll-list {
  max-height: 400px;
  overflow-y: auto;
}

/* Непрочитанные комментарии — светло-зелёная подсветка, стираемая один раз
   при первом наведении (см. comments_panel.js). transition живёт на базовом
   классе, а не на модификаторе — иначе снятие .comment-unread убирало бы и
   саму transition-декларацию, и цвет пропадал бы мгновенно вместо плавного
   затухания. */
.comment-row {
  transition: background-color 0.6s ease;
}

.comment-row.comment-unread {
  background-color: rgba(25, 135, 84, 0.18);
}

/* «Продолжить работу» (see _links_block.html/_post_text_block.html/
   _attachments_block.html) is deliberately NOT green: green is reserved
   for the most logical next click — advancing to another stage (see
   _action_button.html/_content_section_button.html's action_label
   buttons, still btn-success). Reclaiming/resuming work on the CURRENT
   stage is a different kind of action, so it gets its own color. «Начать
   работу» (first-ever claim, same button/different label) stays green —
   only the "resuming" wording gets orange. */
.btn-tsur-orange {
  background-color: #fd7e14;
  border-color: #fd7e14;
  color: #fff;
}

.btn-tsur-orange:hover,
.btn-tsur-orange:focus {
  background-color: #e56b0a;
  border-color: #e56b0a;
  color: #fff;
}

/* Статус загрузки в ПОСЕВ (templates/tasks/_posev_status.html) */
.posev-status-uploaded { color: #c28a00; font-weight: 600; }
.posev-status-verified { color: #198754; font-weight: 600; }
.posev-status-error { color: #dc3545; }
.posev-status-mismatch { color: #fd7e14; font-weight: 600; }
.posev-status-busy { color: #6c757d; }
.posev-status-idle { color: #6c757d; }
.posev-status .spinner-border { width: 0.85rem; height: 0.85rem; border-width: 0.15em; }

/* ── Кнопки по всему ERP — как в «Базе данных»: контурные залиты цветом сразу, при наведении подсвечиваются ──
   (Bootstrap-кнопки живут на переменных --bs-btn-*, поэтому достаточно переопределить их; шапка — .navbar — не трогаем) */
.btn-outline-primary {
  --bs-btn-color: #fff; --bs-btn-bg: #0d6efd; --bs-btn-border-color: #0d6efd;
  --bs-btn-hover-color: #fff; --bs-btn-hover-bg: #0d6efd; --bs-btn-hover-border-color: #0d6efd;
  --bs-btn-focus-shadow-rgb: 49, 132, 253;
  --bs-btn-active-color: #fff; --bs-btn-active-bg: #0a58ca; --bs-btn-active-border-color: #0a58ca;
  --bs-btn-disabled-color: #fff; --bs-btn-disabled-bg: #0d6efd; --bs-btn-disabled-border-color: #0d6efd;
}
.btn-outline-secondary {
  --bs-btn-color: #fff; --bs-btn-bg: #6c757d; --bs-btn-border-color: #6c757d;
  --bs-btn-hover-color: #fff; --bs-btn-hover-bg: #6c757d; --bs-btn-hover-border-color: #6c757d;
  --bs-btn-focus-shadow-rgb: 130, 138, 145;
  --bs-btn-active-color: #fff; --bs-btn-active-bg: #565e64; --bs-btn-active-border-color: #565e64;
  --bs-btn-disabled-color: #fff; --bs-btn-disabled-bg: #6c757d; --bs-btn-disabled-border-color: #6c757d;
}
.btn-outline-success {
  --bs-btn-color: #fff; --bs-btn-bg: #198754; --bs-btn-border-color: #198754;
  --bs-btn-hover-color: #fff; --bs-btn-hover-bg: #198754; --bs-btn-hover-border-color: #198754;
  --bs-btn-focus-shadow-rgb: 60, 153, 110;
  --bs-btn-active-color: #fff; --bs-btn-active-bg: #146c43; --bs-btn-active-border-color: #146c43;
  --bs-btn-disabled-color: #fff; --bs-btn-disabled-bg: #198754; --bs-btn-disabled-border-color: #198754;
}
.btn-outline-danger {
  --bs-btn-color: #fff; --bs-btn-bg: #dc3545; --bs-btn-border-color: #dc3545;
  --bs-btn-hover-color: #fff; --bs-btn-hover-bg: #dc3545; --bs-btn-hover-border-color: #dc3545;
  --bs-btn-focus-shadow-rgb: 225, 83, 97;
  --bs-btn-active-color: #fff; --bs-btn-active-bg: #b02a37; --bs-btn-active-border-color: #b02a37;
  --bs-btn-disabled-color: #fff; --bs-btn-disabled-bg: #dc3545; --bs-btn-disabled-border-color: #dc3545;
}
.btn-outline-warning {
  --bs-btn-color: #000; --bs-btn-bg: #ffc107; --bs-btn-border-color: #ffc107;
  --bs-btn-hover-color: #000; --bs-btn-hover-bg: #ffc107; --bs-btn-hover-border-color: #ffc107;
  --bs-btn-focus-shadow-rgb: 217, 164, 6;
  --bs-btn-active-color: #000; --bs-btn-active-bg: #e0a800; --bs-btn-active-border-color: #e0a800;
  --bs-btn-disabled-color: #000; --bs-btn-disabled-bg: #ffc107; --bs-btn-disabled-border-color: #ffc107;
}
/* выбранная кнопка группы (вкладки, переключатели) — темнее и с белым кольцом внутри */
.btn-outline-primary.active, .btn-outline-secondary.active, .btn-outline-success.active,
.btn-outline-danger.active, .btn-outline-warning.active {
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.6);
}
/* подсветка при наведении — для всех кнопок страницы, кроме шапки и ссылок-кнопок */
.btn:not(.btn-link):not(:disabled):not(.disabled) { transition: filter .12s, box-shadow .12s, transform .12s; }
.btn:not(.btn-link):not(:disabled):not(.disabled):hover { filter: brightness(1.12); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25); transform: translateY(-1px); }
.btn:not(.btn-link):not(:disabled):not(.disabled):active { transform: none; box-shadow: none; }
.btn-outline-primary.active:hover, .btn-outline-secondary.active:hover, .btn-outline-success.active:hover,
.btn-outline-danger.active:hover, .btn-outline-warning.active:hover { box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.6), 0 2px 6px rgba(0, 0, 0, 0.25); }
.navbar .btn:hover { filter: none; box-shadow: none; transform: none; }

/* Список инфоповодов: выполненные не пропадают сразу — тусклые, под горизонтальным разделителем */
.row-done > td { opacity: 0.5; }
.row-done:hover > td { opacity: 0.85; }
.list-done-divider > td {
  padding: 0.35rem 0.5rem 0.15rem; border-top: 1px solid var(--bs-border-color); background: transparent;
}

/* Шапка: имя и роль — единый блок-кнопка (клик открывает список ролей) */
.erp-user-role-btn {
  display: flex; flex-direction: row; align-items: center; gap: .5rem; line-height: 1.15; text-align: left;
  background: none; border: 0; padding: 0.1rem 0.25rem; color: #f8f9fa; cursor: pointer; border-radius: 0.375rem;
}
.erp-user-text { display: flex; flex-direction: column; }
.erp-user-role-btn:hover { background: rgba(255, 255, 255, 0.12); }
.erp-user-name { font-size: 0.875rem; }
.erp-user-role-label { font-size: 0.72rem; color: #adb5bd; }

/* Вид «Размещение»: описание и текст вдвое короче, блок ссылок вдвое выше (список строк до ~20 вместо 10) */
.task-detail-placement .richtext-wrapper .ql-editor { height: 33vh; min-height: 150px; }
.task-detail-placement .links-scroll-list { max-height: 840px; }



/* Фото пользователя (templates/accounts/_avatar.html): квадрат со скруглёнными углами, без фото — цветной квадрат с инициалами */
.erp-avatar { border-radius: 22%; object-fit: cover; flex: none; display: inline-block; }
.erp-avatar-initials { display: inline-flex; align-items: center; justify-content: center; color: #fff; font-weight: 600; line-height: 1; user-select: none; }

/* Список инфоповодов блоками (templates/tasks/_infopovod_cards.html) */
.ip-card { border-left: 4px solid var(--bs-border-color); transition: box-shadow .15s; }
.ip-card:hover { box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .12); }
.ip-card.row-assigned-to-me { border-left-color: var(--bs-success); background: rgba(25, 135, 84, .06); }
.ip-card.row-due-soon { border-left-color: var(--bs-warning); background: rgba(255, 193, 7, .08); }
.ip-card.row-overdue { border-left-color: var(--bs-danger); background: rgba(220, 53, 69, .08); }
.ip-card.row-pending-approval { animation: ip-card-blink 1.2s step-end infinite; }
.ip-card.row-archived { background: rgba(108, 117, 125, .08); }
@keyframes ip-card-blink { 0%, 49% { border-left-color: var(--bs-warning); } 50%, 100% { border-left-color: var(--bs-border-color); } }
.ip-card.ip-done { opacity: .5; }
.ip-card.ip-done:hover { opacity: .9; }
.ip-title { font-weight: 600; color: var(--bs-body-color); text-decoration: none; line-height: 1.25; overflow-wrap: anywhere; }
.ip-title:hover { text-decoration: underline; }
.ip-section-title { font-size: .8rem; font-weight: 600; letter-spacing: .02em; text-transform: uppercase; color: var(--bs-secondary-color); margin-top: .25rem; }
.ip-done-divider { border-top: 1px solid var(--bs-border-color); padding-top: .5rem; margin-top: .75rem; }
/* карточка на всю ширину — сетка 2×2: название | постановщик, направления | срок и кнопки; в каждой строке высота 40 px */
.ip-body { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 1.5rem; row-gap: .4rem; align-items: start; padding-top: .6rem; padding-bottom: .6rem; }
.ip-cell { min-height: 40px; display: flex; align-items: center; gap: .5rem; min-width: 0; }
.ip-chips-cell { align-items: flex-start; }
.ip-end { justify-content: flex-end; }
.ip-time-cell { gap: .5rem; }
.ip-time-cell form { margin: 0; }
.ip-time-cell .ip-deadline { font-size: .875rem; white-space: nowrap; margin-right: .5rem; }
.ip-creator { max-width: 18rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .9rem; }
@media (max-width: 767px) { .ip-body { grid-template-columns: 1fr; } .ip-end { justify-content: flex-start; } }
/* кнопки без цветного фона — только смайл по центру; размер как у фото пользователя (40 px) */
.ip-icon-btn { width: 40px; height: 40px; display: grid; place-items: center; padding: 0; background: transparent;
  border: 1px solid var(--bs-border-color); border-radius: .5rem; line-height: 1; font-size: 1.25rem; cursor: pointer; }
.ip-icon-btn:hover { background: var(--bs-tertiary-bg); }
/* направления — кнопки одной ширины (по самому широкому названию блока на странице; ширину выставляет infopovod_filter.js в --chip-w),
   без тени и контура — как «+ Новый инфоповод» */
.ip-chips { width: 100%; display: grid; grid-template-columns: repeat(auto-fill, min(var(--chip-w, 14rem), 100%)); gap: .4rem; font-size: .875rem; }
.ip-chips .ip-none { grid-column: 1 / -1; }
.ip-chip { width: 100%; height: 40px; display: flex; align-items: center; justify-content: center; font-size: inherit; padding: 0 .75rem; border-radius: var(--bs-btn-border-radius, .375rem); text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; box-shadow: none; border: 1px solid var(--st); background: var(--st); color: var(--st-fg); }
/* при наведении — тот же эффект, что у «+ Новый инфоповод» (глобальное правило .btn:hover: тень и подъём), цвет статуса сохраняется */
.ip-chip.btn:hover, .ip-chip.btn:focus-visible, .ip-chip.btn:active { background: var(--st); border-color: var(--st); color: var(--st-fg); }
.min-w-0 { min-width: 0; }
.flex-none { flex: none; }
/* цвета статусов (кнопки направлений и легенда); ключ — status_color() во views.py:
   синий — новый и просмотр инфоповода; жёлтый — в работе (написание, креативы, коррекция, размещение) и утверждено;
   красный — утверждение не дано (идёт утверждение); зелёный — выполнено */
.st-new, .st-view { --st: var(--bs-primary); --st-fg: #fff; }
.st-write, .st-create, .st-correct, .st-approved, .st-place { --st: var(--bs-warning); --st-fg: #212529; }
.st-approve { --st: var(--bs-danger); --st-fg: #fff; }
.st-done { --st: var(--bs-success); --st-fg: #fff; }
.st-late { --st: var(--bs-danger); --st-fg: #fff; }      /* блок не отработан, до срока меньше часа */
/* блок, где человека нет в исполнителях: пустая кнопка с окантовкой цвета статуса (свои — сплошные) */
.ip-chip.ip-chip-outline, .ip-chip.ip-chip-outline.btn:hover, .ip-chip.ip-chip-outline.btn:focus-visible {
  background: transparent; color: var(--bs-body-color); border: 2px solid var(--st); }
.st-deleted { --st: #adb5bd; --st-fg: #fff; text-decoration: line-through; }

/* Статус и кнопки в шапках инфоповода и задачи — тот же вид, что в списке инфоповодов */
.ip-status { display: inline-flex; align-items: center; height: 40px; padding: 0 1rem; border-radius: .375rem; font-size: .875rem;
  background: var(--st); color: var(--st-fg); border: 1px solid var(--st); white-space: nowrap; }
.ip-text-btn { display: inline-flex; align-items: center; height: 40px; padding: 0 .9rem; background: transparent; color: var(--bs-body-color);
  border: 1px solid var(--bs-border-color); border-radius: .5rem; font-size: .875rem; text-decoration: none; }
.ip-text-btn:hover { background: var(--bs-tertiary-bg); color: var(--bs-body-color); }

/* Шапка страниц инфоповода и задачи — блоком: заголовок (название и кнопки), данные, кнопки направлений и «Общий вид» */
.ip-head .card-header { padding: .6rem 1rem; }
.ip-head-title { font-size: 1.25rem; font-weight: 600; overflow-wrap: anywhere; }
/* кнопки действий в шапке («Завершить задачу», «Вернуть в работу») — той же высоты, что статус и «Редактировать» */
.ip-action-btn { display: inline-flex; align-items: center; height: 40px; padding: 0 1rem; font-size: .875rem; border-radius: .5rem; }
.ip-head-meta { display: flex; flex-wrap: wrap; gap: .25rem 1.5rem; font-size: .875rem; color: var(--bs-secondary-color); }
.ip-head-meta b { font-weight: 600; color: var(--bs-body-color); }
.ip-head-chips { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin-top: .6rem; }
.ip-head-chip { width: auto; min-width: 9rem; padding: 0 1rem; }
.ip-head-chip.is-current { box-shadow: 0 0 0 2px var(--bs-body-bg), 0 0 0 4px var(--st); }
.ip-text-btn.is-current { background: var(--bs-tertiary-bg); font-weight: 600; }

/* Уведомления блоками (templates/notifications/_group.html и колокольчик в шапке) */
.nt-menu { width: 400px; max-width: 94vw; }
.nt-group { display: block; text-decoration: none; color: var(--bs-body-color); border: 1px solid var(--bs-border-color); border-radius: .5rem;
  background: var(--erp-surface, var(--bs-body-bg)); padding: .5rem .75rem; margin-bottom: .5rem; }
.nt-group:hover { box-shadow: 0 2px 6px rgba(0, 0, 0, .18); color: var(--bs-body-color); }
.nt-group.is-unread { border-left: 4px solid var(--bs-primary); }
.nt-head { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-bottom: .25rem; }
.nt-title { font-weight: 600; overflow-wrap: anywhere; }
.nt-block { font-size: .75rem; padding: .05rem .5rem; border-radius: 1rem; background: var(--bs-tertiary-bg); border: 1px solid var(--bs-border-color); color: var(--bs-secondary-color); }
.nt-new { margin-left: auto; font-size: .7rem; background: var(--bs-danger); color: #fff; border-radius: 1rem; padding: .05rem .45rem; }
.nt-items { list-style: none; margin: 0; padding: 0; font-size: .85rem; }
.nt-item { display: flex; justify-content: space-between; gap: .75rem; padding: .1rem 0 .1rem .9rem; position: relative; color: var(--bs-secondary-color); }
.nt-item::before { content: ""; position: absolute; left: .15rem; top: .55rem; width: .45rem; height: .45rem; border-radius: 50%; background: var(--bs-secondary-color); }
.nt-item.is-unread { color: var(--bs-body-color); font-weight: 600; }
.nt-item.nt-k-assigned::before { background: var(--bs-primary); } .nt-item.nt-k-approved::before { background: var(--bs-success); }
.nt-item.nt-k-changed::before { background: var(--bs-warning); } .nt-item.nt-k-placement::before { background: var(--bs-info); }
.nt-item.nt-k-failure::before, .nt-item.nt-k-urgent::before, .nt-item.nt-k-f1new::before, .nt-item.nt-k-mediaplan::before { background: var(--bs-danger); } .nt-item.nt-k-archived::before { background: var(--bs-secondary); }
.nt-time { white-space: nowrap; font-size: .75rem; font-weight: 400; color: var(--bs-secondary-color); }
.nt-more { font-size: .75rem; color: var(--bs-secondary-color); padding-left: .9rem; }

/* Вид «Посредник»: сообщение исполнителям и текст — вдвое ниже обычного поля текста */
.task-detail-mediator .richtext-wrapper .ql-editor { height: 33vh; min-height: 150px; }

/* Публичная страница: текст описания, сообщения и текста поста — на белом листе в любой теме */
.task-description-view.ql-editor.pub-sheet { background: #fff; color: #212529; padding: 1.1rem 1.4rem; border-radius: .5rem; border: 1px solid rgba(0, 0, 0, .12); }
.task-description-view.ql-editor.pub-sheet a { color: #0d6efd; }

/* белый лист занимает всю высоту блока */
.pub-card > .card-body { display: flex; flex-direction: column; padding: .5rem; }
.pub-card .task-description-view.ql-editor.pub-sheet { flex: 1 0 auto; }

/* Завершённая посредником задача: блок контента приглушён (у посредника и на публичной странице) */
.mediator-finished > .row, .mediator-finished > .card:not(.ip-head), .pub-finished { opacity: .55; }
.mediator-finished > .row, .mediator-finished > .card:not(.ip-head) { filter: grayscale(.4); }
/* ссылки, уже попавшие в базу, с публичной страницы не удаляются */
.pub-link-inbase { opacity: .55; }
.pub-link-inbase .pub-link-check { cursor: not-allowed; }

/* блок «Медиаплан» в списке инфоповодов: блоки карточки пока недоступны */
.ip-chip-muted { opacity: .45; pointer-events: none; background: rgba(0, 0, 0, .08); color: inherit; border-color: rgba(0, 0, 0, .12); }
.ip-chip-muted.ip-chip-mine { opacity: .7; border-style: dashed; }

/* Тема инфоповода — несколько тем «балунами» (static/js/theme_multi.js) */
.th-multi { position: relative; }
.th-field { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 4px; min-height: 38px; height: auto; cursor: text; padding: .25rem .5rem; }
.th-chips { display: contents; }
.th-chip { display: inline-flex; align-items: center; gap: 2px; background: var(--bs-secondary-bg); border: 1px solid var(--bs-border-color); border-radius: 14px; padding: 0 4px 0 10px; font-size: .85rem; line-height: 1.7; }
.th-x { border: 0; background: transparent; padding: 0 5px; font-size: 1rem; line-height: 1; color: var(--bs-secondary-color); cursor: pointer; border-radius: 50%; }
.th-x:hover { color: var(--bs-danger); }
.th-search { flex: 1 1 80px; min-width: 60px; border: 0; outline: 0; background: transparent; color: inherit; padding: 2px; }
.th-menu { position: absolute; left: 0; right: 0; top: 100%; z-index: 30; max-height: 260px; overflow-y: auto; margin-top: 2px; background: var(--bs-body-bg);
  border: 1px solid var(--bs-border-color); border-radius: .375rem; box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .18); }
.th-opt, .th-empty { padding: .35rem .6rem; font-size: .9rem; }
.th-opt { cursor: pointer; }
.th-opt:hover { background: var(--bs-secondary-bg); }
.th-empty { color: var(--bs-secondary-color); }
.ip-take { width: auto; flex: none; white-space: nowrap; height: 34px; }   /* «Взять в работу» — рядом со сроком */

/* «Дополнительно» — плитки сервисов: как карточки инфоповодов, по три в ряд */
.ex-tile { border-left: 4px solid var(--bs-border-color); transition: box-shadow .15s, border-color .15s; }
.ex-tile:hover { box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .12); border-left-color: var(--bs-primary); }
.ex-tile-body { display: flex; align-items: flex-start; gap: .75rem; padding-top: .75rem; padding-bottom: .75rem; }
.ex-tile-icon { flex: 0 0 auto; border-radius: 8px; }
.ex-tile-text { min-width: 0; }
