/*
 * Copyright (c) 2010, 2025 BSI Business Systems Integration AG
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 */
#scout {

  .vendor(@property, @value) {
  -webkit-@{property}: @value;
  -moz-@{property}: @value;
  -ms-@{property}: @value;
  -o-@{property}: @value;
    @{property}: @value;
}

  .glow(@color, @radius: 5px) {
    box-shadow: 0 0 @radius @color;
  }

  .inner-glow(@color, @radius: 4px) {
    box-shadow: inset 0 0 @radius @color;
  }

  .drop-shadow(@x: 0px, @y: @drop-shadow-y, @blur: @drop-shadow-blur, @spread: 0px, @alpha: @drop-shadow-alpha) {
    box-shadow: @x @y @blur @spread rgba(0, 0, 0, @alpha);
  }

  .double-drop-shadow(@x1: 0, @y1: 0, @blur1: 0, @spread1: 0, @color1: @palette-black, @x2: 0px, @y2: 6px, @blur2: 13px, @spread2: 0px, @alpha2: @drop-shadow-alpha) {
    --box-shadow-1-x: @x1;
    --box-shadow-1-y: @y1;
    --box-shadow-1-blur: @blur1;
    --box-shadow-1-spread: @spread1;
    --box-shadow-1-color: @color1;
    --box-shadow-2-x: @x2;
    --box-shadow-2-y: @y2;
    --box-shadow-2-blur: @blur2;
    --box-shadow-2-spread: @spread2;
    --box-shadow-2-alpha: @alpha2;

    box-shadow: var(--box-shadow-1-x) var(--box-shadow-1-y) var(--box-shadow-1-blur) var(--box-shadow-1-spread) var(--box-shadow-1-color), var(--box-shadow-2-x) var(--box-shadow-2-y) var(--box-shadow-2-blur) var(--box-shadow-2-spread) rgba(0, 0, 0, var(--box-shadow-2-alpha));
  }

  .drop-shadow-large(@x: 0px, @y: @drop-shadow-large-y, @blur: @drop-shadow-large-blur, @spread: 0px, @alpha: @drop-shadow-large-alpha) {
    #scout.drop-shadow(@x, @y, @blur, @spread, @alpha);
  }

  .focus-border(@box-shadow-size: @focus-box-shadow-size, @box-shadow-color: @focus-box-shadow-color, @border-color: @focus-box-shadow-border-color) {
    #scout.focus-box-shadow(@box-shadow-size, @box-shadow-color);
    border-color: var(--focus-border-color, @border-color);
  }

  .no-focus-border() {
    outline: none;
    border: 0;
    box-shadow: 0 0 0 0;
  }

  .focus-box-shadow(@box-shadow-size: @focus-box-shadow-size, @box-shadow-color: @focus-box-shadow-color) {
    outline: none;
    box-shadow: 0 0 0 var(--focus-box-shadow-size, @box-shadow-size) var(--focus-box-shadow-color, @box-shadow-color);
  }

  .focus-inset-box-shadow(@box-shadow-size: @focus-box-shadow-size, @box-shadow-color: @focus-box-shadow-color) {
    outline: none;
    box-shadow: inset 0 0 0 var(--focus-box-shadow-size, @box-shadow-size) var(--focus-box-shadow-color, @box-shadow-color);
  }

  .focus-box-shadow-transition() {
    transition: box-shadow 0.3s ease;
  }

  .alternative-focus-border() {
    border-bottom-color: @focus-border-color;
    border-bottom-width: 2px;
    box-shadow: none;
    padding-bottom: 0;
  }

  .inverted-bottom-round-edge(@border-radius: 12px, @color: #ffffff) {
    @border-width: 5px;

    --color: @color; // Allows to change color only
    position: absolute;
    pointer-events: none;
    background-color: transparent;
    bottom: -@border-width;
    height: @border-radius;
    width: @border-radius;
    box-sizing: content-box;
    border: @border-width solid var(--color);
    border-top: none;

    &.left {
      left: -@border-radius;
      border-bottom-right-radius: @border-radius+@border-width;
      border-left: none;
    }

    &.right {
      right: -@border-radius;
      border-bottom-left-radius: @border-radius+@border-width;
      border-right: none;
    }
  }

  // noinspection CssUnknownProperty
  .transform(@args) {
    -webkit-transform: @args;
    -ms-transform: @args;
    transform: @args;
  }

  // noinspection CssUnknownProperty
  .transform-origin(@args) {
    -webkit-transform-origin: @args;
    -moz-transform-origin: @args;
    -ms-transform-origin: @args;
    transform-origin: @args;
  }

  .text-selection() {
    background: @text-selection-background-color;
    color: @text-selection-color;
  }

  .text-selection-disabled() {
    background: @text-selection-disabled-background-color;
    color: @text-selection-disabled-color;
  }

  .placeholder() {
    color: @text-field-placeholder-color;
    opacity: 1; /* necessary for firefox */
  }

  .placeholder-disabled() {
    /* Fade a little to make it distinguishable from real text. Don't use opacity here because it affects background as well (IE). */
    color: fade(@disabled-color, 50%);
  }

  .fake-placeholder() {
    /* placeholder only works for input elements -> this fake placeholder is intended for a before element*/
    #scout.placeholder();
    content: attr(placeholder);
  }

  .pseudo-overlay(@top: 0, @right: @top, @bottom: @top, @left: @top) {
    content: '';
    position: absolute;
    top: @top;
    right: @right;
    bottom: @bottom;
    left: @left;
    pointer-events: none; // Necessary when used as ::after element
  }

  /**
   * Draws an ::after element that has the focus-box-shadow.
   * An ::after element is necessary to add a little horizontal padding.
   */

  .link-focus-overlay {
    position: relative;

    &:focus {
      box-shadow: none;

      &::after {
        #scout.focus-box-shadow();
        #scout.pseudo-overlay(0, -2px, 0, -2px);
        border-radius: @border-radius;
      }
    }
  }

  /* Use dashed line instead of solid to avoid visual conflict with editable fields */
  .read-only() {
    background-color: transparent;
    border-color: transparent;
    border-bottom: dashed 1px @border-color;
    color: @read-only-color;
  }

  .value-field-with-icon(@className: ~'.icon') {

    &.focused > @{className}::before,
    &.focused > .field > @{className}::before {
      color: @text-field-icon-focus-color;
    }

    &.has-error > @{className}::before,
    &.has-error > .field > @{className}::before,
    &.has-error > .field > @{className}::before {
      color: @text-field-icon-error-color;
    }

    &.disabled > @{className},
    &.disabled > .field > @{className},
    &.compact > @{className},
    &.compact > .field > @{className} {
      display: none;
    }

    &.alternative.has-error:focus > .field > @{className}::before,
    &.alternative.has-error.focused > .field > @{className}::before {
      color: @text-field-icon-error-color;
    }
  }

  .status {
    display: flex;
    align-items: center;
    cursor: pointer;

    // Info-status is the default
    --icon: @icon-info;
    --color: @status-info-color;
    --hover-color: @status-info-hover-color;
    --active-color: @status-info-hover-color;

    &::before {
      #scout.font-icon();
      content: var(--icon);
      color: var(--color);
      font-size: @status-font-icon-size;
      border-radius: @control-border-radius;
      width: @field-status-size;
      height: @field-status-size;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    &.has-menus {
      --icon: @icon-ellipsis-v;
      --color: @status-menu-color;
      --hover-color: @status-menu-hover-color;
      --active-color: @status-menu-hover-color;
    }

    &.has-ok {
      --icon: @icon-info;
      --color: @status-ok-color;
      --hover-color: @status-ok-hover-color;
      --active-color: @status-ok-hover-color;
    }

    &.has-warning {
      --icon: @icon-exclamation-mark-circle;
      --color: @status-warning-color;
      --hover-color: @status-warning-hover-color;
      --active-color: @status-warning-hover-color;
    }

    &.has-error {
      --icon: @icon-exclamation-mark-circle;
      --color: @status-error-color;
      --hover-color: @status-error-hover-color;
      --active-color: @status-error-hover-color;
    }

    &:hover::before {
      background-color: @hover-background-color;
      color: var(--hover-color);
    }

    &:active::before,
    &.selected::before {
      background-color: @active-background-color;
      color: var(--active-color);
    }

    &:focus::before,
    &.focused::before {
      #scout.focus-box-shadow();
    }

    &.disabled,
    &:is(.has-menus, .has-ok, .has-warning, .has-error).disabled {
      cursor: default;

      &::before {
        color: @disabled-color;
        background-color: transparent;
      }
    }
  }

  .loading-indicator(@loading-animation-size: 30px, @border-width: 1px) {
    display: inline-block;
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -(@loading-animation-size / 2);
    margin-left: -(@loading-animation-size / 2);
    #scout.animation(fade-in 0.15s);
    #scout.loading-indicator-before(@loading-animation-size, @border-width);

    &.animate-remove {
      #scout.animation(fade-out-from-current 0.15s);
    }
  }

  .loading-indicator-before(@loading-animation-size: 30px, @border-width: 1px) {

    &::before {
      #scout.animation(pulsate 2s cubic-bezier(0.5, 0.1, 0.1, 0.5) infinite);
      content: '';
      display: inline-block;
      vertical-align: middle;
      border-radius: 50%;
      border: @border-width fade(@busyindicator-color, 80%) solid;
      width: @loading-animation-size;
      height: @loading-animation-size;
    }
  }

  .loading-indicator-knight-rider() {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    height: 2px;
    width: 100%;
    opacity: 0;
    animation: fade-in 1s forwards, slideout-right 1.5s ease-in-out infinite alternate;
    animation-delay: 0.5s;

    &::before {
      animation: slideout-left 1.5s ease-in-out infinite alternate;
      animation-delay: 0.5s;
      content: '';
      position: absolute;
      background: linear-gradient(to right, transparent 0%, @loading-indicator-knight-rider-color 20%, @loading-indicator-knight-rider-color 80%, transparent 100%);
      left: 0;
      width: 50px;
      height: 100%;
    }
  }

  .user-select(@mode) {
    -webkit-user-select: @mode;
    -moz-user-select: @mode;
    -ms-user-select: @mode;
    user-select: @mode;
  }

  .overflow-ellipsis() {
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .overflow-ellipsis-nowrap() {
    #scout.overflow-ellipsis();
    white-space: nowrap;
  }

  .overflow-nowrap() {
    overflow: hidden;
    white-space: nowrap;
  }

  .overflow-clip() {
    // clip is not supported for Safari < 16 -> it will be ignored and fall back to hidden
    overflow: hidden;
    overflow: clip;
  }

  .white-space-nowrap() {
    white-space: nowrap;
  }

  // Can be used in a before or after element to enlarge a text to a size it would have if it was bold
  .bold-text-enlarger() {
    content: attr(data-text);
    display: block;
    font-weight: @title-font-weight;
    visibility: hidden;
    height: 0;
  }

  .triangle-top-left(@size, @color) {
    width: 0;
    height: 0;
    border-style: solid;
    border-width: @size @size 0 0;
    #scout.triangle-top-left-color(@color);
  }

  .triangle-top-left-color(@color) {
    border-color: @color transparent transparent transparent;
  }

  .item-selection-border(@border-color: @item-selection-nonfocus-border-color) {
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    border: @item-selection-border-width solid @border-color;
    border-radius: @control-border-radius;
    pointer-events: none;
  }

  /* Font Mixins */

  .font-text-small(@font-weight: @font-weight-normal) {
    font-family: @font-default-family;
    font-weight: @font-weight;
    font-size: @font-size-small;
  }

  .font-text-normal(@font-weight: @font-weight-normal) {
    font-family: @font-default-family;
    font-weight: @font-weight;
    font-size: @font-size-normal;
  }

  .font-text-plus(@font-weight: @font-weight-normal) {
    font-family: @font-default-family;
    font-weight: @font-weight;
    font-size: @font-size-plus;
  }

  .font-text-large(@font-weight: @font-weight-normal) {
    font-family: @font-default-family;
    font-weight: @font-weight;
    font-size: @font-size-large;
  }

  .font-icon() {
    font-family: scoutIcons, @font-default-family;
    font-weight: @font-weight-normal;
    speak: none;
    font-style: normal;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }

  .submenu-icon() {
    #scout.font-icon();
    font-size: 16px;
  }

  .submenu-icon-open() {
    #scout.transform(rotateX(180deg) translateY(-1px));
  }

  /* Invisible pseudo element that enables vertical-align if container has height set */
  .vertical-align-helper(@minHeight: 0) {
    content: '';
    display: inline-block;
    vertical-align: middle;
    height: 100%;
    min-height: @minHeight;
  }

  .vertical-align-helper-before(@minHeight: 0) {
    &::before {
      #scout.vertical-align-helper(@minHeight);
    }
  }

  .vertical-align-helper-after(@minHeight: 0) {
    &::after {
      #scout.vertical-align-helper(@minHeight);
    }
  }

  //noinspection CssInvalidPropertyValue
  .cursor-grab {
    /* "grab" cursor with fallback for browsers that don't understand CSS3 cursors */
    cursor: move;
    cursor: -webkit-grab;
    cursor: -moz-grab;
    cursor: grab;
  }

  //noinspection CssInvalidPropertyValue
  .cursor-grabbing {
    /* "grabbing" cursor with fallback for browsers that don't understand CSS3 cursors */
    cursor: move;
    cursor: -webkit-grabbing;
    cursor: -moz-grabbing;
    cursor: grabbing;
  }

  /* Mixin for chooser popups as used in smart-field */

  .chooser-popup {
    position: absolute;
    overflow: hidden;
    #scout.control-popup();

    &.touch {
      background-color: @table-header-background-color;
    }
  }

  .backdrop-filter(@background-color, @backdrop-filter, @fallback-background-color) {
    background-color: @fallback-background-color; // For browsers that don't support backdrop-filter

    @supports ((-webkit-backdrop-filter: none) or (backdrop-filter: none)) {
      background-color: @background-color;
      -webkit-backdrop-filter: @backdrop-filter;
      backdrop-filter: @backdrop-filter;
    }
  }

  .popup {
    background-color: @popup-background-color;
    border: @popup-border-width solid @popup-border-color;
    border-radius: @popup-border-radius;
    #scout.drop-shadow-large();
  }

  .popup-backdrop-filter() {
    #scout.backdrop-filter(@background-color: @popup-backdrop-background-color, @backdrop-filter: @popup-backdrop-filter, @fallback-background-color: @popup-background-color);
  }

  // Second layer popups that are normally a little smaller than the other popups
  .popup-2(@border-radius: @border-radius-medium) {
    background-color: @popup-2-background-color;
    border: @popup-border-width solid @popup-border-color;
    border-radius: @border-radius;
    #scout.drop-shadow-large();
  }

  .popup-2-backdrop-filter() {
    #scout.backdrop-filter(@background-color: @popup-2-backdrop-background-color, @backdrop-filter: @popup-2-backdrop-filter, @fallback-background-color: @popup-2-background-color);
  }

  .control-popup() {
    #scout.popup-2(@control-border-radius);
    margin: @control-popup-margin;
  }

  /* Mixin for scrollbar positioning */
  .scrollbar-y-padding(@padding: @scrollbar-side-padding, @padding-hover: @scrollbar-side-padding-hover) {
    & > .scrollbar-thumb.y-axis {
      padding-left: @padding;
    }

    &:hover.y-axis > .scrollbar-thumb.y-axis,
    &.y-axis > .scrollbar-thumb.y-axis.scrollbar-thumb-move {
      padding-left: @padding-hover;
    }
  }

  .scrollbar-x-padding(@padding: @scrollbar-side-padding, @padding-hover: @scrollbar-side-padding-hover) {
    & > .scrollbar-thumb.x-axis {
      padding-top: @padding;
    }

    &:hover.x-axis > .scrollbar-thumb.x-axis,
    &.x-axis > .scrollbar-thumb.x-axis.scrollbar-thumb-move {
      padding-top: @padding-hover;
    }
  }

  /*
  * Hides the scrollbars but lets the user still scroll (e.g. using mousewheel or touch).
  * This works a bit different for every browser.
  */

  .hide-scrollbars {
    &::-webkit-scrollbar {
      display: none;
    }

    -ms-overflow-style: none;

    /* Firefox: https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-width */
    scrollbar-width: none;
  }

  /**
   * Uses the inverted colors of the scrollbars. Use this mixin in a widget that requires inverted scrollbars (e.g. a widget with white background in dark mode).
   */

  .inverted-scrollbars {
    & > .scrollbar > .scrollbar-thumb {
      & > .scrollbar-thumb-handle {
        background-color: @scrollbar-thumb-inverted-color;
      }

      &.scrollbar-thumb-move > .scrollbar-thumb-handle,
      &:hover > .scrollbar-thumb-handle {
        background-color: @scrollbar-thumb-inverted-hover-color;
      }

      &.container-too-small-for-thumb > .scrollbar-thumb-handle {
        background-color: @scrollbar-thumb-inverted-small-color;
      }

      &.container-too-small-for-thumb.scrollbar-thumb-move > .scrollbar-thumb-handle,
      &.container-too-small-for-thumb.scrollbar-thumb:hover > .scrollbar-thumb-handle {
        background-color: @scrollbar-thumb-inverted-small-hover-color;
      }
    }
  }

  /**
   * Adds a rule for a css class with the name @{edge}-resize that defines the cursor with the same name, e.g. resize-w.
   */
  .resize-cursor(@edge) {
    .@{edge}-resize,
    .@{edge}-resize * { /* NOSONAR (universal selector is okay here) */
      cursor: ~'@{edge}-resize !important'; /* NOSONAR !important is necessary to override any defined cursor on underlying components */
    }
  }
}
