/* Тряска для поля формы */
@keyframes mat-shake {
  0%, 100% { transform: translateX(0); }
  20%, 60% { transform: translateX(-4px); }
  40%, 80% { transform: translateX(4px); }
}

// Базовая анимация для любого элемента, на который навесили класс.
.shake-animation {
  animation: mat-shake 0.5s ease-in-out;
}

// Подсветка/рамка для строк таблиц с невалидным правилом.
// InvalidFormService добавляет `.shake-animation` именно на ближайший `.sln-invalid-rule-row`.
.sln-invalid-rule-row.shake-animation {
  outline: 2px solid var(--DANGER);
  outline-offset: 2px;
}

// Для table-row outline может отрабатывать неидеально, поэтому подсвечиваем ячейки.
.sln-invalid-rule-row.shake-animation td {
  box-shadow: 0 0 0 2px var(--DANGER) inset;
}

// Подсветка для контролов, где нет mat-form-field (например, core-field-bool).
/*.shake-animation:not(mat-form-field):not(core-file-uploader):not(core-field-combobox):not(input):not(textarea) {
  outline: 1px solid var(--DANGER);
  outline-offset: 2px;
  border-radius: 6px;
}
*/

// mat-form-field: filled — во время shake подсвечиваем border всех input внутри.
mat-form-field.shake-animation
  .mdc-text-field--filled:not(.mdc-text-field--disabled)
  .mdc-text-field__input {
  border-color: var(--DANGER) !important;
}

// date/time: видимый masked input (а не "служебный" matInput).
mat-form-field.shake-animation .sln-date-masked-input {
  border-color: var(--DANGER) !important;
}

// mat-form-field: outlined.
mat-form-field.shake-animation
  .mdc-text-field--outlined:not(.mdc-text-field--disabled)
  .mdc-notched-outline__leading,
mat-form-field.shake-animation
  .mdc-text-field--outlined:not(.mdc-text-field--disabled)
  .mdc-notched-outline__notch,
mat-form-field.shake-animation
  .mdc-text-field--outlined:not(.mdc-text-field--disabled)
  .mdc-notched-outline__trailing {
  border-color: var(--DANGER) !important;
}

// underline/filled у MDC: убираем серая линия, когда подсветка включена.
mat-form-field.shake-animation .mdc-line-ripple::before,
mat-form-field.shake-animation .mdc-line-ripple::after {
  background-color: var(--DANGER) !important;
  border-bottom-color: var(--DANGER) !important;
}

// Для datetime: во время shake-animation пусть и masked, и служебный input тоже подсвечиваются.

core-field-combobox.shake-animation mat-select,
core-field-multiple-combobox.shake-animation mat-select {
  border: 1px solid var(--DANGER) !important;
}

core-file-uploader.shake-animation .uploader-wallpaper,
core-file-uploader.shake-animation .sln-uploader-wallpaper {
  box-shadow: 0 0 0 1px var(--DANGER) inset !important;
  border-radius: 6px;
  animation: mat-shake 0.5s ease-in-out;
}

// core-field-bool: 3 режима отображения
// Options: мат-radio-group
core-field-bool.shake-animation .sln-core-field-bool-option {
  outline: 1px solid var(--DANGER);
  outline-offset: 2px;
  border-radius: 6px;
}

// Checkbox: mat-checkbox + внешний контейнер
core-field-bool.shake-animation .sln-core-field-bool-checkbox {
  outline: 1px solid var(--DANGER);
  outline-offset: 2px;
  border-radius: 6px;
}

// Slide: mat-slide-toggle
core-field-bool.shake-animation .sln-mat-slide-toggle {
  box-shadow: 0 0 0 1px var(--DANGER) inset !important;
  border-radius: 6px;
}

// Для наглядности дублируем тряску на нужных внутренних элементах:
core-field-bool.shake-animation .sln-core-field-bool-option,
core-field-bool.shake-animation .sln-core-field-bool-checkbox,
core-field-bool.shake-animation .sln-mat-slide-toggle {
  animation: mat-shake 0.5s ease-in-out;
}