$prefix: null;

@if setting-exists($settings, "prefix") {
  $prefix: "#{settings($settings,"prefix")}-";
}

@mixin darkMode {
  --#{$prefix}foreground: #{value(light)};
  --#{$prefix}foreground-accent: #{value(
      lightAccent,
      darken(map-get($color-palette, "light"), 5%)
    )};
  --#{$prefix}background: #{value(dark)};
  --#{$prefix}background-accent: #{value(
      darkAccent,
      lighten(map-get($color-palette, "dark"), 5%)
    )};
  --#{$prefix}code-lightness: 75;
  --#{$prefix}code-saturation: 50;
}
@mixin lightMode {
  --#{$prefix}foreground: #{value(dark)};
  --#{$prefix}foreground-accent: #{value(
      darkAccent,
      lighten(map-get($color-palette, "dark"), 10%)
    )};
  --#{$prefix}background: #{value(light)};
  --#{$prefix}background-accent: #{value(
      lightAccent,
      darken(map-get($color-palette, "light"), 5%)
    )};
  --#{$prefix}code-lightness: 45;
  --#{$prefix}code-saturation: 50;
}

@mixin colormode() {
  $colorMode: settings($settings, "define.colormode.class");

  body {
    background-color: value(background);
    color: value(foreground);
  }
  @media (prefers-color-scheme: dark) {
    body {
      @include darkMode;
    }
  }

  @media (prefers-color-scheme: light) {
    body {
      @include lightMode;
    }
  }
  body[color-mode="dark"] {
    @include darkMode;
  }
  body[color-mode="light"] {
    @include lightMode;
  }

  #{$colorMode} {
    --#{$prefix}switch-stroke: calc(#{value(space)} * 0.1);
    --#{$prefix}switch-color: #{value(foreground, currentColor)};
    --#{$prefix}switch-margin: calc((#{value(switch-stroke)} * 4));
    --#{$prefix}switch-dot-size: calc(
      #{value(space)} - #{value(switch-margin)}
    );
    border: value(switch-stroke) solid value(switch-color);
    width: calc(#{value(space)} * 1.5);
    height: value(space);
    display: block;
    background-color: transparent;
    border-radius: value(space);
    position: relative;
    text-indent: -999em;
    transition: opacity value(transition);
    opacity: 0.5;
    &:hover {
      opacity: 1;
    }
    &:focus {
      outline: none;
      box-shadow: 0 0 10px 0 value(primary);
    }
    &::before {
      content: "";
      display: block;
      position: absolute;
      left: 0;
      top: 50%;
      transition: transform 0.3s ease-in-out,
        background-position 0.3s ease-in-out, background-size 0.3s ease-in-out;
      transform: translate(calc(0% + #{value(switch-stroke)}), -50%);
      background-color: currentColor;
      border-radius: 50%;
      width: value(switch-dot-size);
      height: value(switch-dot-size);
      background: radial-gradient(
        circle at 50%,
        transparent,
        transparent 33.33%,
        #{value(switch-color)} 33.33%
      );

      background-repeat: no-repeat;
      background-size: calc(#{value(space)} * 2) 100%;
      background-position: -0% 50%;
    }
    // The after is a label shown to display the current mode. By default this doesn't show because the after does not have a content.
    // The after can be shown by adding a content in custom css.
    &::after {
      background-color: value(text);
      color: value(background);
      position: absolute;
      left: 50%;
      top: 100%;
      transform: translate(-50%, calc(#{value(switch-stroke)} * 2)) scale(0);
      font-size: 0.8em;
      padding: 0.5em 1em;
      border-radius: value(border-radius);
      display: block;
      text-indent: 0;
      opacity: 0;
      transition: transform value(transition);
    }
    &:hover::after {
      transform: translate(-50%, calc(#{value(switch-stroke)} * 2)) scale(1);
      opacity: 1;
    }
  }
  [color-mode="dark"] {
    #{$colorMode}::before {
      transform: translate(calc(100%), -50%) rotate(180deg);
      background-position: 25% 50%;
    }
  }
}
