/* ========================================
   EASYKAWA DESIGN SYSTEM - COMPONENTS
   Version: 1.0.0
   ======================================== */

/* ===================================
   BUTTONS
   =================================== */

.btn {
    position: relative; /* Required for tooltip positioning */
    font-family: var(--font-family);
    font-size: 0.9rem;
    font-weight: var(--font-weight-medium);
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    cursor: pointer;
    /* [2026-09-18] Д1: перечень вместо прежнего `all`. Тот анимировал ЛЮБОЕ изменившееся
       свойство, включая размеры и положение, на которых браузер пересчитывает раскладку, и
       навязывал одну длительность всему. Из-за этого добавленный в тот же день отклик на
       нажатие (`transform: scale(0.97)`) ехал 200 мс вместо канонных для частого действия ~160:
       подтверждение опаздывало ровно там, где важна мгновенность. Теперь у движения своя,
       более короткая длительность, у цветов — прежняя.
       Перечень собран по фактическим состояниям `.btn` в этом файле: background-color,
       border-color, color, box-shadow (`:hover` вариантов), transform (`:hover`/`:active`),
       opacity (`:disabled`).
       Ref: docs/AUDIT_UI_MOTION_2026-09-17.md Д1. Chat: ui-motion-fixes-2026-09-17. */
    transition:
        background-color var(--transition-base),
        border-color var(--transition-base),
        color var(--transition-base),
        box-shadow var(--transition-base),
        opacity var(--transition-base),
        transform 160ms ease-out;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    height: 38px;
    box-sizing: border-box;
    text-decoration: none;
    white-space: nowrap;
}

/* [2026-09-18] ОТКЛИК НА НАЖАТИЕ (аудит Д2/Д3).
   Снято по коду продукта: 1059 правил `:hover` против 70 `:active`, и 70 файлов отвечают на
   наведение, не отвечая на нажатие ни разу. Канонические кнопки не подтверждали нажатие вовсе —
   интерфейс охотнее реагировал на проезд мышью, чем на само действие пользователя.
   Величина нарочно мелкая: кнопки нажимают десятки раз в день, и здесь уместно движение,
   заметное телу, а не глазу. Больше — и интерфейс начнёт казаться медленным ровно там, где
   важна мгновенность. Двигается только `transform`.
   Ref: docs/AUDIT_UI_MOTION_2026-09-17.md Д2, Д3; навык emil-skills:find-animation-opportunities
   (тир «tens/day»). Chat: ui-motion-fixes-2026-09-17. */
.btn:active:not(:disabled) {
    transform: scale(0.97);
}

.btn-icon:active:not(:disabled) {
    transform: scale(0.97);
}

.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

/* ===================================
   BUTTON VARIANTS - Color Usage Guide
   ===================================

   .btn-primary (Blue/Indigo)
   USE FOR: Primary actions on page
   - Save, Submit, Create, Add
   - Main call-to-action buttons
   - Form submissions
   Examples: "Save Changes", "Add Tag", "Create Collection"

   .btn-secondary (Gray/Transparent)
   USE FOR: Secondary/Cancel actions
   - Cancel, Close, Back
   - Dismissive actions
   - Alternative options
   Examples: "Cancel", "Go Back", "Close"

   .btn-success (Green)
   USE FOR: Confirmation/Success actions
   - Confirm, Accept, Approve
   - Positive confirmations
   - Success indicators
   Examples: "Confirm Delete", "Accept", "Yes, proceed"

   .btn-warning (Yellow/Orange)
   USE FOR: Warning/Caution actions
   - Actions that need attention
   - Potentially risky but not destructive
   Examples: "Archive", "Disable", "Pause"

   .btn-danger (Red)
   USE FOR: Destructive/Delete actions
   - Delete, Remove, Destroy
   - Irreversible actions
   - Critical confirmations
   Examples: "Delete", "Remove Forever", "Reset"

   .btn-info (Blue)
   USE FOR: Informational actions
   - View details, Learn more
   - Non-critical actions
   Examples: "View Details", "Learn More"

   .btn-ghost (Transparent)
   USE FOR: Subtle/Tertiary actions
   - Less important actions
   - Inline actions
   Examples: "Skip", "Maybe Later"
   =================================== */

/* Primary Button - Main actions (Save, Add, Create, Submit) */
.btn-primary {
    background-color: var(--brand-primary);
    color: var(--text-inverse);
    border-color: var(--brand-primary);
}

/* [2026-09-18] Д2: наведение — только там, где указатель точный. На устройстве без него
   браузер применяет `:hover` по касанию и держит до следующего тапа в другом месте: кнопка
   выглядит «наведённой», когда палец уже убран. Отклик на нажатие (`:active` выше) в гейт НЕ
   убран намеренно — на таком устройстве он остаётся единственным подтверждением действия.
   Правила обёрнуты НА МЕСТЕ, а не собраны в общий блок в конце файла: перенос изменил бы
   порядок каскада между вариантами кнопок.
   Ref: docs/AUDIT_UI_MOTION_2026-09-17.md Д2. Chat: ui-motion-fixes-2026-09-17. */
@media (hover: hover) and (pointer: fine) {
    .btn-primary:hover:not(:disabled) {
        background-color: var(--brand-primary-hover);
        border-color: var(--brand-primary-hover);
        transform: translateY(-1px);
        box-shadow: var(--shadow-md);
    }
}

/* Secondary Button - Cancel/Dismiss actions */
.btn-secondary {
    background-color: transparent;
    color: var(--text-secondary);
    border-color: var(--border-primary);
}

@media (hover: hover) and (pointer: fine) {
    .btn-secondary:hover:not(:disabled) {
        background-color: var(--bg-tertiary);
        color: var(--text-primary);
        border-color: var(--border-secondary);
    }
}

/* Success Button - Confirm/Accept actions */
.btn-success {
    background-color: var(--color-success);
    color: var(--text-inverse);
    border-color: var(--color-success);
}

@media (hover: hover) and (pointer: fine) {
    .btn-success:hover:not(:disabled) {
        background-color: var(--color-success-hover);
        border-color: var(--color-success-hover);
    }
}

/* Warning Button - Caution actions */
.btn-warning {
    background-color: var(--color-warning);
    color: var(--text-inverse);
    border-color: var(--color-warning);
}

@media (hover: hover) and (pointer: fine) {
    .btn-warning:hover:not(:disabled) {
        background-color: var(--color-warning-hover);
        border-color: var(--color-warning-hover);
    }
}

/* Danger Button - Destructive actions */
.btn-danger {
    background-color: var(--color-error);
    color: var(--text-inverse);
    border-color: var(--color-error);
}

@media (hover: hover) and (pointer: fine) {
    .btn-danger:hover:not(:disabled) {
        background-color: var(--color-error-hover);
        border-color: var(--color-error-hover);
    }
}

/* Info Button - Informational actions */
.btn-info {
    background-color: var(--color-info);
    color: var(--text-inverse);
    border-color: var(--color-info);
}

@media (hover: hover) and (pointer: fine) {
    .btn-info:hover:not(:disabled) {
        background-color: var(--color-info-hover);
        border-color: var(--color-info-hover);
    }
}

/* Purple Button - Accent actions */
.btn-purple {
    background-color: var(--color-purple);
    color: var(--text-inverse);
    border-color: var(--color-purple);
}

@media (hover: hover) and (pointer: fine) {
    .btn-purple:hover:not(:disabled) {
        background-color: var(--color-purple-hover);
        border-color: var(--color-purple-hover);
    }
}

/* Ghost button */
.btn-ghost {
    background-color: transparent;
    color: var(--text-primary);
    border-color: transparent;
}

@media (hover: hover) and (pointer: fine) {
    .btn-ghost:hover:not(:disabled) {
        background-color: var(--bg-hover);
    }
}

/* Button Sizes */
.btn-xs {
    height: 28px;
    padding: var(--space-1) var(--space-2);
    font-size: var(--font-size-xs);
}

.btn-sm {
    height: 32px;
    padding: var(--space-1) var(--space-3);
    font-size: var(--font-size-xs);
}

.btn-md {
    height: 38px;
    padding: var(--space-2) var(--space-4);
    font-size: var(--font-size-sm);
}

.btn-lg {
    height: 44px;
    padding: var(--space-3) var(--space-6);
    font-size: var(--font-size-base);
}

.btn-xl {
    height: 52px;
    padding: var(--space-4) var(--space-8);
    font-size: var(--font-size-lg);
}

/* Split button group */
.btn-group {
    display: inline-flex;
    position: relative;
}

.btn-group .btn:not(:last-child) {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.btn-group .btn:not(:first-child) {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    border-left: 1px solid var(--border-secondary);
}

/* Button with icon */
.btn .material-icons {
    font-size: 18px;
}

/* Icon button */
.btn-icon {
    width: 38px;
    padding: 0;
    background-color: transparent;
    border-color: transparent;
}

@media (hover: hover) and (pointer: fine) {
    .btn-icon:hover:not(:disabled) {
        background-color: var(--bg-hover);
    }
}

.btn-icon.btn-sm {
    width: 32px;
}

.btn-icon.btn-lg {
    width: 44px;
}

/* ===================================
   INPUTS & FORMS
   =================================== */

.form-group {
    margin-bottom: var(--space-4);
}

.form-label {
    display: block;
    font-size: 0.8rem;
    font-weight: var(--font-weight-medium);
    color: var(--text-secondary);
    margin-bottom: var(--space-2);
}

.form-label.required::after {
    content: ' *';
    color: var(--color-error);
}

.input {
    width: 100%;
    height: 38px;
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--border-primary);
    border-radius: var(--radius-md);
    font-family: var(--font-family);
    font-size: var(--font-size-sm);
    background-color: var(--bg-secondary);
    color: var(--text-primary);
    /* [2026-09-18] Д1: перечень вместо `all`. Поле ввода меняет в состояниях border-color и
       box-shadow (`:focus`), background-color и opacity (`:disabled`) — их и анимируем; размеры
       поля не трогаются и анимировать их не нужно.
       Ref: docs/AUDIT_UI_MOTION_2026-09-17.md Д1. Chat: ui-motion-fixes-2026-09-17. */
    /* outline-color в перечне не случайно: поле с ошибкой меняет цвет контура в фокусе
       (`.input.input-error:focus`). Это состояние легко потерять вместе с прежним `all` —
       здесь его и поймал сторож перечня. */
    transition:
        border-color var(--transition-base),
        box-shadow var(--transition-base),
        background-color var(--transition-base),
        outline-color var(--transition-base),
        opacity var(--transition-base);
    box-sizing: border-box;
}

.input:focus {
    outline: none;
    border-color: var(--brand-primary);
    box-shadow: 0 0 0 3px rgba(var(--brand-primary-rgb, 66, 153, 225), 0.2);
}

.input::placeholder {
    color: var(--text-tertiary);
}

.input:disabled {
    background-color: var(--bg-tertiary);
    cursor: not-allowed;
    opacity: 0.6;
}

.input.input-error {
    border-color: var(--color-error);
}

.input.input-error:focus {
    outline-color: var(--color-error);
}

/* Search input — differs from base .input */
.input-search {
    min-width: 200px;
    max-width: 300px;
    background-color: var(--bg-primary);
    border-color: var(--border-secondary);
    padding-left: 36px;
    position: relative;
}

/* Textarea */
.textarea {
    min-height: 100px;
    resize: vertical;
    padding: var(--space-3);
    line-height: var(--line-height-relaxed);
}

/* Select */
.select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M6 9L1 4h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--space-3) center;
    padding-right: var(--space-8);
}

/* Checkbox & Radio */
.checkbox,
.radio {
    width: 18px;
    height: 18px;
    cursor: pointer;
}

/* Form helper text */
.form-helper {
    font-size: var(--font-size-xs);
    color: var(--text-tertiary);
    margin-top: var(--space-1);
}

.form-error {
    font-size: var(--font-size-xs);
    color: var(--color-error);
    margin-top: var(--space-1);
}

/* ===================================
   CARDS
   =================================== */

.card {
    background-color: var(--bg-secondary);
    border: 1px solid var(--border-primary);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}

/* [2026-09-18] `.card-hover` и `.card-hover:hover` УДАЛЕНЫ по решению PO («удали если не
   применяется»). Класс объявлял подъём карточки при наведении, но в разметке и коде продукта не
   встречался НИ РАЗУ — ни буквально, ни собранным из кусков (`'card-' +`, `card-${…}`,
   `classList.add/toggle` с `hover`); проверено по всему репозиторию, кроме node_modules,
   стороннего «ECMS connection» и отдельного проекта cold-eye-viewer. Родительский `.card` живой
   (его ставит modules/assessments/components/CompetencyManager.js), поэтому удалена ровно
   мёртвая часть.
   Мёртвый стиль приходится сопровождать и он врёт про возможности системы: выглядит как готовый
   приём, которого на экране нет. Возврат класса стережёт __tests__/canonicalTransitions.test.js
   — если правило появится снова, оно обязано применяться в разметке.
   Ref: docs/AUDIT_UI_MOTION_2026-09-17.md Д1. Chat: ui-motion-fixes-2026-09-17. */

.card-header {
    padding: var(--space-3) var(--space-6); /* Оставим уменьшенный padding */
    border-bottom: 1px solid var(--border-primary);
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: nowrap; /* <<< ДОБАВИТЬ ЭТО */
}

.card-header h2,
.card-header h3 {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
    flex-grow: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 1.3;
}

/* --- Стили для иконки сворачивания в card-header --- */
.card-header .toggle-icon {
    flex-shrink: 0;
    line-height: 1; /* <<< ДОБАВИТЬ ЭТО (для иконки обычно 1) */
}

.card-body {
    padding: var(--space-6);
}

.card-footer {
    padding: var(--space-4) var(--space-6);
    border-top: 1px solid var(--border-primary);
    background-color: var(--bg-secondary);
}

/* ===================================
   BADGES & TAGS
   =================================== */

.badge {
    display: inline-flex;
    align-items: center;
    padding: var(--space-1) var(--space-2);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    border-radius: var(--radius-full);
    white-space: nowrap;
}

.badge-primary {
    background-color: var(--brand-primary-light);
    color: var(--brand-primary-dark);
}

.badge-success {
    background-color: var(--color-success-bg);
    color: var(--color-success);
}

.badge-warning {
    background-color: var(--color-warning-bg);
    color: var(--color-warning);
}

.badge-error {
    background-color: var(--color-error-bg);
    color: var(--color-error);
}

.badge-info {
    background-color: var(--color-info-bg);
    color: var(--color-info);
}

.badge-neutral {
    background-color: var(--bg-tertiary);
    color: var(--text-secondary);
}

/* ===================================
   ALERTS & NOTIFICATIONS
   =================================== */

.alert {
    padding: var(--space-4);
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
}

.alert-success {
    background-color: var(--color-success-bg);
    border-color: var(--color-success-light);
    color: var(--color-success);
}

.alert-warning {
    background-color: var(--color-warning-bg);
    border-color: var(--color-warning-light);
    color: var(--color-warning);
}

.alert-error {
    background-color: var(--color-error-bg);
    border-color: var(--color-error-light);
    color: var(--color-error);
}

.alert-info {
    background-color: var(--color-info-bg);
    border-color: var(--color-info-light);
    color: var(--color-info);
}

/* ===================================
   MODALS
   =================================== */

.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: var(--bg-overlay);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: var(--z-modal-backdrop);
    opacity: 1;
    transition: opacity var(--transition-base);
}

.modal-overlay.hidden {
    opacity: 0;
    pointer-events: none;
}

.modal-container {
    background-color: var(--bg-secondary);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-2xl);
    width: 90%;
    max-width: 780px;
    min-height: 70vh;
    max-height: 90vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    position: relative;
    z-index: var(--z-modal);
}

.modal-header {
    padding: var(--space-6);
    border-bottom: 1px solid var(--border-primary);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.modal-header h3 {
    margin: 0;
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    color: var(--text-primary);
}

.modal-close {
    background: transparent;
    border: none;
    cursor: pointer;
    padding: var(--space-2);
    color: var(--text-tertiary);
    transition: color var(--transition-base);
}

.modal-close:hover {
    color: var(--text-primary);
}

.modal-body {
    padding: var(--space-6);
    overflow-y: auto;
    flex: 1;
}

.modal-footer {
    padding: var(--space-4) var(--space-6);
    border-top: 1px solid var(--border-primary);
    display: flex;
    gap: var(--space-3);
    justify-content: flex-end;
}

/* ===================================
   TABLES
   =================================== */

.table-container {
    width: 100%;
    overflow-x: auto;
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-primary);
}

.table {
    width: 100%;
    border-collapse: collapse;
    background-color: var(--bg-primary);
}

.table thead {
    background-color: var(--bg-secondary);
}

.table th {
    padding: var(--space-3) var(--space-4);
    text-align: left;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--text-secondary);
    border-bottom: 1px solid var(--border-primary);
}

.table td {
    padding: var(--space-3) var(--space-4);
    font-size: var(--font-size-sm);
    color: var(--text-primary);
    border-bottom: 1px solid var(--border-primary);
}

.table tbody tr:last-child td {
    border-bottom: none;
}

.table tbody tr:hover {
    background-color: var(--bg-hover);
}

/* ===================================
   UTILITY CLASSES
   =================================== */

/* Typography */
.text-xs {
    font-size: var(--font-size-xs);
}
.text-sm {
    font-size: var(--font-size-sm);
}
.text-base {
    font-size: var(--font-size-base);
}
.text-lg {
    font-size: var(--font-size-lg);
}
.text-xl {
    font-size: var(--font-size-xl);
}
.text-2xl {
    font-size: var(--font-size-2xl);
}
.text-3xl {
    font-size: var(--font-size-3xl);
}

.font-light {
    font-weight: var(--font-weight-light);
}
.font-normal {
    font-weight: var(--font-weight-normal);
}
.font-medium {
    font-weight: var(--font-weight-medium);
}
.font-semibold {
    font-weight: var(--font-weight-semibold);
}
.font-bold {
    font-weight: var(--font-weight-bold);
}

.text-primary {
    color: var(--text-primary);
}
.text-secondary {
    color: var(--text-secondary);
}
.text-tertiary {
    color: var(--text-tertiary);
}

.text-left {
    text-align: left;
}
.text-center {
    text-align: center;
}
.text-right {
    text-align: right;
}

/* Display */
.flex {
    display: flex;
}
.inline-flex {
    display: inline-flex;
}
.grid {
    display: grid;
}
.hidden {
    display: none;
}

/* Flex utilities */
.flex-row {
    flex-direction: row;
}
.flex-col {
    flex-direction: column;
}
.flex-1 {
    flex: 1;
}
.flex-grow {
    flex: 1 1 0%;
}
.items-center {
    align-items: center;
}
.items-start {
    align-items: flex-start;
}
.items-end {
    align-items: flex-end;
}
.justify-center {
    justify-content: center;
}
.justify-between {
    justify-content: space-between;
}
.justify-end {
    justify-content: flex-end;
}
.gap-1 {
    gap: var(--space-1);
}
.gap-2 {
    gap: var(--space-2);
}
.gap-3 {
    gap: var(--space-3);
}
.gap-4 {
    gap: var(--space-4);
}
.gap-6 {
    gap: var(--space-6);
}

/* Position utilities */
.relative {
    position: relative;
}
.absolute {
    position: absolute;
}
.fixed {
    position: fixed;
}

/* Spacing */
.p-0 {
    padding: var(--space-0);
}
.p-1 {
    padding: var(--space-1);
}
.p-2 {
    padding: var(--space-2);
}
.p-3 {
    padding: var(--space-3);
}
.p-4 {
    padding: var(--space-4);
}
.p-6 {
    padding: var(--space-6);
}
.p-8 {
    padding: var(--space-8);
}

.m-0 {
    margin: var(--space-0);
}
.m-1 {
    margin: var(--space-1);
}
.m-2 {
    margin: var(--space-2);
}
.m-3 {
    margin: var(--space-3);
}
.m-4 {
    margin: var(--space-4);
}
.m-6 {
    margin: var(--space-6);
}
.m-8 {
    margin: var(--space-8);
}

.mt-0 {
    margin-top: var(--space-0);
}
.mt-1 {
    margin-top: var(--space-1);
}
.mt-2 {
    margin-top: var(--space-2);
}
.mt-3 {
    margin-top: var(--space-3);
}
.mt-4 {
    margin-top: var(--space-4);
}
.mt-6 {
    margin-top: var(--space-6);
}
.mt-8 {
    margin-top: var(--space-8);
}

/* Width utilities */
.w-full {
    width: 100%;
}

/* Border radius */
.rounded-sm {
    border-radius: var(--radius-sm);
}
.rounded-md {
    border-radius: var(--radius-md);
}
.rounded-lg {
    border-radius: var(--radius-lg);
}
.rounded-xl {
    border-radius: var(--radius-xl);
}
.rounded-full {
    border-radius: var(--radius-full);
}

/* Shadows */
.shadow-sm {
    box-shadow: var(--shadow-sm);
}
.shadow-md {
    box-shadow: var(--shadow-md);
}
.shadow-lg {
    box-shadow: var(--shadow-lg);
}
.shadow-xl {
    box-shadow: var(--shadow-xl);
}

/* ==========================================================================
   Universal avatar photo (AvatarHelpers.renderAvatar / AvatarPhotoCache).
   `ek-avatar` marks every avatar; `ek-avatar-img` is added when a real uploaded
   photo replaces the initials. The <img> fills whatever avatar circle/square the
   base class (.user-avatar-mini, .fa-avatar, .frame-avatar, …) already sizes, so
   ONE rule styles real photos everywhere. (Goal 2026-06-16.)
   ========================================================================== */
.ek-avatar-img {
    overflow: hidden;
    padding: 0 !important;
    /* photo fills the bubble — no initials background showing through */
    background: none !important;
}
.ek-avatar-img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    border-radius: inherit;
}

/* [2026-09-18] ЗАТУХАНИЕ КРАЯ ПРОКРУЧИВАЕМОГО СПИСКА (аудит Д9).
   В продукте 49 объявлений `position: sticky` и ни одного затухания края: содержимое обрезалось
   под липкой шапкой резко, и не было видно, что список продолжается.
   Затухание ЧЕСТНОЕ — рисуется только там, где содержимое действительно скрыто. Признак
   (`data-scroll-edge`) ставит services/ScrollEdgeFade.js по фактическому положению прокрутки;
   статичный градиент врал бы на коротком списке и на прокрученном до конца.
   Маска, а не наложенный градиент: она не зависит от фона под списком и ничего не перекрывает,
   поэтому работает в обеих темах и не мешает нажатиям.
   Ref: docs/AUDIT_UI_MOTION_2026-09-17.md Д9. Chat: ui-motion-fixes-2026-09-17. */
[data-scroll-edge='bottom'] {
    mask-image: linear-gradient(to bottom, #000 calc(100% - 24px), transparent 100%);
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 24px), transparent 100%);
}

[data-scroll-edge='top'] {
    mask-image: linear-gradient(to bottom, transparent 0, #000 24px);
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 24px);
}

[data-scroll-edge='both'] {
    mask-image: linear-gradient(to bottom, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);
    -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);
}

/* [2026-09-18] Системная настройка «меньше движения» (аудит Д6). В общих стилях продукта этого
   запроса не было ВООБЩЕ — то есть пользователь, выключивший анимации в системе, всё равно
   получал их везде. Здесь снимается только что добавленный отклик на нажатие: сама кнопка
   остаётся рабочей и по-прежнему подсвечивается, исчезает лишь масштабирование.
   Ref: docs/AUDIT_UI_MOTION_2026-09-17.md Д2, Д3, Д6. Chat: ui-motion-fixes-2026-09-17. */
@media (prefers-reduced-motion: reduce) {
    .btn:active:not(:disabled),
    .btn-icon:active:not(:disabled) {
        transform: none;
    }
}
