// --------------------------------------------------
// Mixins used throughout the theme
// --------------------------------------------------

// Media queries
// --------------------------------------------------

@use "sass:color";
@use "sass:math";
@use "sass:string";
@use "sass:map";
@use "lib/viewport";

$breakpoints: (
  mobile-small: map.get(viewport.$breakpoints, sm),
  mobile-medium: map.get(viewport.$breakpoints, sm),
  mobile-large: map.get(viewport.$breakpoints, sm),
  mobile-extra-large: map.get(viewport.$breakpoints, sm),
  tablet: map.get(viewport.$breakpoints, md),
  medium: map.get(viewport.$breakpoints, lg),
  large: map.get(viewport.$breakpoints, lg),
  extra-large: map.get(viewport.$breakpoints, xl),
);

/* breakpoint is a legacy mixin. Use `@use "lib/viewport"` instead. */
@mixin breakpoint($bp, $rule: max-width, $type: screen, $sidebar: false) {
  /* stylelint-disable-next-line scss/no-global-function-names */
  $bp-value: map-get($breakpoints, $bp);

  @if $rule == min-width {
    $bp-value: calc(#{$bp-value} + 1px);
  }

  @media #{$type} and (#{$rule}: #{$bp-value}) {
    @content;
  }

  // if you want to consider the sidebar in your breakpoint
  // you can pass in $sidebar: true
  // note that your breakpoint will need to be at the root level
  @if $sidebar {
    // when the sidebar is shown, we want to increase the breakpoints by the width of the sidebar
    /* stylelint-disable-next-line scss/no-global-function-names */
    @media #{$type} and (#{$rule}: calc(#{map-get($breakpoints, $bp)} + #{$d-sidebar-width})) {
      .has-sidebar-page {
        @content;
      }
    }
  }
}

// CSS3 properties
// --------------------------------------------------

// Clearfix

@mixin clearfix() {
  &::before,
  &::after {
    content: "";
    display: table;
  }

  &::after {
    clear: both;
  }
}

@mixin linear-gradient($start-color, $end-color) {
  background-color: $start-color;
  background-image: linear-gradient(to bottom, $start-color, $end-color);
}

@mixin darken-background($background-color, $amt) {
  $overlay: dark-light-choose(
    rgb(var(--primary-rgb), $amt),
    rgb(var(--secondary-rgb), $amt)
  );
  background-image: linear-gradient(to bottom, $overlay 100%, $overlay 100%);
}

// Visibility
// --------------------------------------------------

// Only shows hover on non-touch devices
@mixin hover {
  .discourse-no-touch &,
  .no-ember & {
    &:hover,
    &.btn-hover {
      @content;
    }
  }
}

@mixin ellipsis {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

@mixin line-clamp($lines) {
  display: -webkit-box;
  overflow: hidden;
  text-overflow: ellipsis;
  word-wrap: break-word;
  -webkit-line-clamp: $lines;
  -moz-box-orient: vertical;
  -webkit-box-orient: vertical;
}

//
// --------------------------------------------------

$vpad: 0.5em;
$hpad: 0.65em;

// for consistent sizing across inputs, buttons and dropdowns
@mixin form-item-sizing {
  border: 1px solid transparent;
  font-size: var(--font-0);
  line-height: normal;
  box-sizing: border-box;
  padding: $vpad $hpad;
}

// Used to handle -webkit prefix, but now we have autoprefixer
// Keeping for backward-compat with plugins/themes only
@mixin user-select($mode) {
  user-select: $mode;
}

// Unselectable (avoids unwanted selections with iPad, touch laptops, etc)
@mixin unselectable {
  cursor: default;

  @include user-select(none);
}

// Stuff we repeat
@mixin post-aside {
  border-left: 5px solid var(--primary-300);
  background-color: var(--blend-primary-secondary-5);
}

@mixin float-down {
  animation: float-down ease 0.25s 1 forwards;
}

@mixin float-up {
  animation: float-up ease 0.25s 1 forwards;
}

@mixin default-focus() {
  border-color: var(--d-input-focused-color);
  outline: 2px solid var(--d-input-focused-color);
  outline-offset: -2px;
}

/// Helper function to easily use an SVG inline in CSS
/// without encoding it to base64, saving bytes.
/// It also helps with browser support, especially for IE11.
///
/// @author Jakob Eriksen
/// @link http://codepen.io/jakob-e/pen/doMoML
/// @param {String} $svg - SVG image to encode
/// @return {String} - Encoded SVG data uri
@function svg-uri($svg) {
  $encoded: "";
  $slice: 2000;
  $index: 0;
  $loops: math.ceil(math.div(string.length($svg), $slice));

  @for $i from 1 through $loops {
    $chunk: string.slice($svg, $index, $index + $slice - 1);
    $chunk: str-replace($chunk, '"', "'");
    $chunk: str-replace($chunk, "<", "%3C");
    $chunk: str-replace($chunk, ">", "%3E");
    $chunk: str-replace($chunk, "&", "%26");
    $chunk: str-replace($chunk, "#", "%23");
    $encoded: #{$encoded}#{$chunk};
    $index: $index + $slice;
  }

  @return url("data:image/svg+xml;charset=utf8,#{$encoded}");
}

/// Replace `$search` with `$replace` in `$string`
/// @author Hugo Giraudel
/// @link http://sassmeister.com/gist/1b4f2da5527830088e4d
/// @param {String} $string - Initial string
/// @param {String} $search - Substring to replace
/// @param {String} $replace ('') - New value
/// @return {String} - Updated string
@function str-replace($string, $search, $replace: "") {
  $index: string.index($string, $search);

  @if $index {
    @return string.slice($string, 1, $index - 1) + $replace +
      str-replace(
        string.slice($string, $index + string.length($search)),
        $search,
        $replace
      );
  }

  @return $string;
}

// SCSS accepts HEX or RGB colors for rgba($color, 0.5)
// CSS custom properties only accept RGB
// Example usage:

// --primary-rgb: #{hexToRGB($primary)};
// ...
// rgba(var(--primary-low-rgb), 0.5)

@function hexToRGB($hex) {
  @return color.red($hex), color.green($hex), color.blue($hex);
}

@function schemeType() {
  @if is-light-color-scheme() {
    @return "light";
  } @else {
    @return "dark";
  }
}

@function absolute-image-url($path) {
  // public_image_path is added by the stylesheet importer
  // it returns a CDN or subfolder path (if applicable).
  // SCSS will compile (and return the relative path) if public_image_path is missing.
  /* stylelint-disable-next-line scss/no-global-function-names */
  @if global-variable-exists(public_image_path) {
    @if string.index("#{$path}", "/plugins") == 1 {
      $plugin_asset_path: str-replace($public_image_path, "/images", "");

      @return url("#{$plugin_asset_path}#{$path}");
    } @else {
      @return url("#{$public_image_path}#{$path}");
    }
  } @else {
    @return url("#{$path}");
  }
}

@mixin mention() {
  // memo to self: do not make this inline-flex because it breaks text alignments and causes a whole avalance of unpleasant consequences
  display: inline-block;
  font-size: 0.93em;
  font-weight: normal;
  color: var(--primary);
  padding: 0.2em 0.34em;
  background: var(--mention-background-color);
  border-radius: 0.6em;
  text-decoration: none;
  text-wrap: nowrap;
  line-height: 1;

  &[data-valid="false"] {
    background: unset;
    padding: 0;
  }

  &.--bot {
    background: var(--success-low);
  }

  &.--wide {
    background: var(--highlight-low-or-medium);
  }

  &.--current {
    background: var(--tertiary-400);
  }
}

@mixin nav-active() {
  color: var(--d-nav-color--active);
  background: var(--d-nav-bg-color--active);

  .d-icon {
    color: var(--d-nav-color--active);
  }

  &::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    right: 0;
    height: var(--d-nav-underline-height);
    background: var(--d-nav-color--active);
  }
}

@mixin nav-hover() {
  color: var(--d-nav-color--hover);
  background: var(--d-nav-bg-color--hover);

  .d-icon {
    color: var(--d-nav-color--active);
  }
}

@mixin click-counter-badge {
  content: attr(data-clicks);
  font-weight: normal;
  background-color: var(--primary-low);
  color: var(--primary-medium);
  position: relative;
  top: -1px;
  padding: 0.21em 0.42em;
  min-width: 0.5em;
  line-height: var(--line-height-small);
  font-size: var(--font-down-2);
  text-align: center;
  border-radius: 10px;
  white-space: nowrap;
  display: inline-block;
  margin: 0.15em;
}
