@use './variables';
@use './mixins/forms';
@use './mixins/clearfix';
@use './mixins/grid';
@use 'sass:color';
@use 'sass:math';
//
// Forms
// --------------------------------------------------

// Normalize non-controls
//
// Restyle and baseline non-control form elements.

fieldset {
    padding: 0;
    margin: 0;
    border: 0;
    // Chrome and Firefox set a `min-width: min-content;` on fieldsets,
    // so we reset that to ensure it behaves more like a standard block element.
    // See https://github.com/twbs/bootstrap/issues/12359.
    min-width: 0;
}

legend {
    display: block;
    width: 100%;
    padding: 0;
    margin-bottom: variables.$line-height-computed;
    font-size: (variables.$font-size-base * 1.5);
    line-height: inherit;
    color: variables.$legend-color;
    border: 0;
    border-bottom: 1px solid variables.$legend-border-color;
}

label {
    font-size: 14px;
    display: inline-block;
    max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)
    margin-bottom: 4px;
    font-weight: normal;
    color: variables.$text-color;
}

// Normalize form controls
//
// While most of our form styles require extra classes, some basic normalization
// is required to ensure optimum display with or without those classes to better
// address browser inconsistencies.

// Override content-box in Normalize (* isn't specific enough)
input[type='search'] {
    box-sizing: border-box;
}

// Position radios and checkboxes better
input[type='radio'],
input[type='checkbox'] {
    margin: 4px 0 0;
    margin-top: 1px \9; // IE8-9
    line-height: normal;
}

input[type='file'] {
    display: block;
}

// Make range inputs behave like textual form controls
input[type='range'] {
    display: block;
    width: 100%;
}

// Make multiple select elements height not fixed
select[multiple],
select[size] {
    height: auto;
}

// Focus for file, radio, and checkbox
input[type='file']:focus,
input[type='radio']:focus,
input[type='checkbox']:focus {
    @include forms.form-control-focus;
}

// Adjust output element
output {
    display: block;
    padding-top: (variables.$padding-base-vertical + 1);
    font-size: variables.$font-size-base;
    line-height: variables.$line-height-base;
    color: variables.$input-color;
}

// Common form controls
//
// Shared size and type resets for form controls. Apply `.form-control` to any
// of the following form controls:
//
// select
// textarea
// input[type="text"]
// input[type="password"]
// input[type="datetime"]
// input[type="datetime-local"]
// input[type="date"]
// input[type="month"]
// input[type="time"]
// input[type="week"]
// input[type="number"]
// input[type="email"]
// input[type="url"]
// input[type="search"]
// input[type="tel"]
// input[type="color"]

.form-control {
    display: block;
    width: 100%;
    height: 32px; // Make inputs at least the height of their button counterpart (base line-height + padding + border)
    padding: variables.$padding-base-vertical variables.$padding-base-horizontal;
    font-size: 14px;
    line-height: variables.$line-height-base;
    color: variables.$input-color;
    background-color: variables.$input-bg;
    background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
    border: 1px solid variables.$input-border;
    border-radius: variables.$input-border-radius; // Note: This has no effect on <select>s in some browsers, due to the limited stylability of <select>s in CSS.
    transition:
        border-color ease-in-out 0.15s,
        box-shadow ease-in-out 0.15s;

    &::placeholder {
        color: variables.$input-color-placeholder;
    }

    // Unstyle the caret on `<select>`s in IE10+.
    &::-ms-expand {
        border: 0;
        background-color: transparent;
    }

    // Disabled and read-only inputs
    //
    // HTML5 says that controls under a fieldset > legend:first-child won't be
    // disabled if the fieldset is disabled. Due to implementation difficulty, we
    // don't honor that edge case; we style them as disabled anyway.
    &[disabled],
    &[readonly],
    fieldset[disabled] & {
        opacity: 0.5;
    }

    &[disabled],
    fieldset[disabled] & {
        cursor: variables.$cursor-disabled;
    }

    &:focus {
        // Customize the `:focus` state to imitate native WebKit styles.
        @include forms.form-control-focus;
    }
    // [converter] extracted textarea& to textarea.form-control
}

// Reset height for `textarea`s
textarea.form-control {
    height: auto;
    resize: vertical;
    line-height: 1.4;
}

// Search inputs in iOS
//
// This overrides the extra rounded corners on search inputs in iOS so that our
// `.form-control` class can properly style them. Note that this cannot simply
// be added to `.form-control` as it's not specific enough. For details, see
// https://github.com/twbs/bootstrap/issues/11586.

input[type='search'] {
    -webkit-appearance: none;
}

// Special styles for iOS temporal inputs
//
// In Mobile Safari, setting `display: block` on temporal inputs causes the
// text within the input to become vertically misaligned. As a workaround, we
// set a pixel line-height that matches the given height of the input, but only
// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848
//
// Note that as of 9.3, iOS doesn't support `week`.

@media screen and (-webkit-min-device-pixel-ratio: 0) {
    input[type='date'],
    input[type='time'],
    input[type='datetime-local'],
    input[type='month'] {
        &.form-control {
            line-height: variables.$input-height-base;
        }

        &.input-sm,
        .input-group-sm & {
            line-height: variables.$input-height-small;
        }

        &.input-lg,
        .input-group-lg & {
            line-height: variables.$input-height-large;
        }
    }
}

// Form groups
//
// Designed to help with the organization and spacing of vertical forms. For
// horizontal forms, use the predefined grid classes.

.form-group {
    margin-bottom: variables.$form-group-margin-bottom;
}

// Checkboxes and radios
//
// Indent the labels to position radios/checkboxes as hanging controls.

.radio,
.radio-inline,
.checkbox,
.checkbox-inline {
    position: relative;
    display: block;
    margin-bottom: 8px;

    label {
        font-weight: normal;
        cursor: pointer;
        line-height: 12px;
        padding-left: 0;
        margin-bottom: 0;
        display: inline-flex;
        align-items: center;
        color: variables.$text-color-secondary;

        &:before {
            font: var(--fa-font-solid);
            font-weight: 900;
            content: '\f00c';
            position: relative;
            background-color: variables.$text-color;
            color: transparent;
            width: 16px;
            min-width: 16px;
            height: 16px;
            padding-top: 1px;
            margin-right: 8px;
            border-radius: variables.$border-radius-base;
            font-size: 10px;
            text-align: center;
            transition-property: background;
            transition-timing-function: ease-in-out;
            transition-duration: 100ms;
        }
    }
    input[type='radio'],
    input[type='checkbox'] {
        position: absolute;
        opacity: 0;

        &:checked {
            ~ label {
                &:before {
                    background-color: variables.get-color('primary', base);
                    color: variables.$text-color;
                }
            }
        }
        &:disabled {
            ~ label {
                cursor: not-allowed;
                opacity: 0.5;
            }
        }
        &:focus {
            ~ label:before {
                @include forms.form-control-focus(variables.$input-border-focus, 2px);
            }
        }
    }
}

.checkbox,
.checkbox-inline {
    label {
        &:before {
            border: 1px solid variables.$input-border;
        }
    }
    input:checked {
        ~ label {
            &:before {
                border: 1px solid transparent;
            }
        }
    }
    &.checkbox-exclusion {
        label {
            &:before {
                content: '\f00d';
            }
        }
        input[type='checkbox']:checked {
            ~ label {
                &:before {
                    background: variables.get-color('tertiary', base);
                }
            }
        }
    }
    &.checkbox-placeholder {
        input[type='checkbox']:not(:checked) {
            ~ label:before {
                color: rgba(variables.$level0, 0.4);
            }
        }
    }
}

.radio,
.radio-inline {
    label:before {
        content: ' ';
        border: 6px solid variables.$divider-color-secondary;
        border-radius: 50%;
        transition-property: border-color;
        transition-timing-function: ease-in-out;
        transition-duration: 300ms;
    }
    input[type='radio']:checked {
        ~ label:before {
            border-color: variables.get-color('primary', base);
            background: variables.$text-color;
        }
    }
}

// Radios and checkboxes on same line
.radio-inline,
.checkbox-inline {
    position: relative;
    display: inline-block;
    padding-left: 20px;
    margin-bottom: 0;
    vertical-align: middle;
    font-weight: normal;
    cursor: pointer;
}
.radio-inline + .radio-inline,
.checkbox-inline + .checkbox-inline {
    margin-top: 0;
    margin-left: 10px; // space out consecutive inline controls
}

// Apply same disabled cursor tweak as for inputs
// Some special care is needed because <label>s don't inherit their parent's `cursor`.
//
// Note: Neither radios nor checkboxes can be readonly.
input[type='radio'],
input[type='checkbox'] {
    &[disabled],
    &.disabled,
    fieldset[disabled] & {
        cursor: variables.$cursor-disabled;
    }
}
// These classes are used directly on <label>s
.radio-inline,
.checkbox-inline {
    &.disabled,
    fieldset[disabled] & {
        cursor: variables.$cursor-disabled;
    }
}
// These classes are used on elements with <label> descendants
.radio,
.checkbox {
    &.disabled,
    fieldset[disabled] & {
        label {
            cursor: variables.$cursor-disabled;
        }
    }
}

// Static form control text
//
// Apply class to a `p` element to make any string of text align with labels in
// a horizontal form layout.

.form-control-static {
    // Size it appropriately next to real form controls
    padding-top: (variables.$padding-base-vertical + 1);
    padding-bottom: (variables.$padding-base-vertical + 1);
    // Remove default margin from `p`
    margin-bottom: 0;
    min-height: (variables.$line-height-computed + variables.$font-size-base);

    &.input-lg,
    &.input-sm {
        padding-left: 0;
        padding-right: 0;
    }
}

// Form control sizing
//
// Build on `.form-control` with modifier classes to decrease or increase the
// height and font-size of form controls.
//
// The `.form-group-* form-control` variations are sadly duplicated to avoid the
// issue documented in https://github.com/twbs/bootstrap/issues/15074.

@include forms.input-size(
    '.input-sm',
    variables.$input-height-small,
    variables.$padding-small-vertical,
    variables.$padding-small-horizontal,
    variables.$font-size-small,
    variables.$line-height-small,
    variables.$input-border-radius-small
);
.form-group-sm {
    .form-control {
        height: variables.$input-height-small;
        padding: variables.$padding-small-vertical variables.$padding-small-horizontal;
        font-size: variables.$font-size-small;
        line-height: variables.$line-height-small;
        border-radius: variables.$input-border-radius-small;
    }
    select.form-control {
        height: variables.$input-height-small;
        line-height: variables.$input-height-small;
    }
    textarea.form-control,
    select[multiple].form-control {
        height: auto;
    }
    .form-control-static {
        height: variables.$input-height-small;
        min-height: (variables.$line-height-computed + variables.$font-size-small);
        padding: (variables.$padding-small-vertical + 1) variables.$padding-small-horizontal;
        font-size: variables.$font-size-small;
        line-height: variables.$line-height-small;
    }
}

@include forms.input-size(
    '.input-lg',
    variables.$input-height-large,
    variables.$padding-large-vertical,
    variables.$padding-base-horizontal,
    variables.$font-size-large,
    variables.$line-height-large,
    variables.$input-border-radius-large
);
.form-group-lg {
    .form-control {
        height: variables.$input-height-large;
        padding: variables.$padding-large-vertical variables.$padding-base-horizontal;
        font-size: variables.$font-size-large;
        line-height: variables.$line-height-large;
        border-radius: variables.$input-border-radius-large;
    }
    select.form-control {
        height: variables.$input-height-large;
        line-height: variables.$input-height-large;
    }
    textarea.form-control,
    select[multiple].form-control {
        height: auto;
    }
    .form-control-static {
        height: variables.$input-height-large;
        min-height: (variables.$line-height-computed + variables.$font-size-large);
        padding: (variables.$padding-large-vertical + 1) variables.$padding-base-horizontal;
        font-size: variables.$font-size-large;
        line-height: variables.$line-height-large;
    }
}

// Form control feedback states
//
// Apply contextual and semantic states to individual form controls.

.has-feedback {
    // Enable absolute positioning
    position: relative;

    // Ensure icons don't overlap text
    .form-control {
        padding-right: (variables.$input-height-base * 1.25);
    }
}
// Feedback icon (requires .glyphicon classes)
.form-control-feedback {
    position: absolute;
    top: 0;
    right: 0;
    z-index: 2; // Ensure icon is above input groups
    display: block;
    width: variables.$input-height-base;
    height: variables.$input-height-base;
    line-height: variables.$input-height-base;
    text-align: center;
    pointer-events: none;
}
.input-lg + .form-control-feedback,
.input-group-lg + .form-control-feedback,
.form-group-lg .form-control + .form-control-feedback {
    width: variables.$input-height-large;
    height: variables.$input-height-large;
    line-height: variables.$input-height-large;
}
.input-sm + .form-control-feedback,
.input-group-sm + .form-control-feedback,
.form-group-sm .form-control + .form-control-feedback {
    width: variables.$input-height-small;
    height: variables.$input-height-small;
    line-height: variables.$input-height-small;
}

// Feedback states
.has-success {
    @include forms.form-control-validation(
        variables.$state-success-text,
        variables.$state-success-border,
        variables.$state-success-bg
    );
}
.has-warning {
    @include forms.form-control-validation(
        variables.$state-warning-text,
        variables.$state-warning-border,
        variables.$state-warning-bg
    );
}
.has-error {
    @include forms.form-control-validation(
        variables.$state-danger-text,
        variables.$state-danger-border,
        variables.$state-danger-bg
    );
}

// Reposition feedback icon if input has visible label above
.has-feedback label {
    & ~ .form-control-feedback {
        top: (variables.$line-height-computed + 5); // Height of the `label` and its margin
    }
    &.sr-only ~ .form-control-feedback {
        top: 0;
    }
}

// Help text
//
// Apply to any element you wish to create light text for placement immediately
// below a form control. Use for general help, formatting, or instructional text.

.help-block {
    display: block; // account for any element using help-block
    margin-top: 5px;
    margin-bottom: 10px;
    color: color.adjust(variables.$text-color, $lightness: 25%); // lighten the text some for contrast
    font-size: 12px;
}
// [converter] extracted as `@mixin form-inline` for libsass compatibility
.form-inline {
    @include forms.form-inline;
}

// Horizontal forms
//
// Horizontal forms are built on grid classes and allow you to create forms with
// labels on the left and inputs on the right.

.form-horizontal {
    // Consistent vertical alignment of radios and checkboxes
    //
    // Labels also get some reset styles, but that is scoped to a media query below.
    .radio,
    .checkbox,
    .radio-inline,
    .checkbox-inline {
        margin-top: 0;
        margin-bottom: 0;
        padding-top: (variables.$padding-base-vertical + 1); // Default padding plus a border
    }
    // Account for padding we're adding to ensure the alignment and of help text
    // and other content below items
    .radio,
    .checkbox {
        min-height: (variables.$line-height-computed + (variables.$padding-base-vertical + 1));
    }

    // Make form groups behave like rows
    .form-group {
        @include grid.make-row;
    }

    // Reset spacing and right align labels, but scope to media queries so that
    // labels on narrow viewports stack the same as a default form example.
    @media (min-width: variables.$screen-sm-min) {
        .control-label {
            text-align: right;
            margin-bottom: 0;
            padding-top: (variables.$padding-base-vertical + 1); // Default padding plus a border
        }
    }

    // Validation states
    //
    // Reposition the icon because it's now within a grid column and columns have
    // `position: relative;` on them. Also accounts for the grid gutter padding.
    .has-feedback .form-control-feedback {
        right: math.floor((variables.$grid-gutter-width * 0.5));
    }

    // Form group sizes
    //
    // Quick utility class for applying `.input-lg` and `.input-sm` styles to the
    // inputs and labels within a `.form-group`.
    .form-group-lg {
        @media (min-width: variables.$screen-sm-min) {
            .control-label {
                padding-top: (variables.$padding-large-vertical + 1);
                font-size: variables.$font-size-large;
            }
        }
    }
    .form-group-sm {
        @media (min-width: variables.$screen-sm-min) {
            .control-label {
                padding-top: (variables.$padding-small-vertical + 1);
                font-size: variables.$font-size-small;
            }
        }
    }
}

.switch {
    @include clearfix.clearfix;

    label {
        float: left;
        line-height: 32px;
        cursor: pointer;
        margin-bottom: 0;
        color: rgba(variables.$text-color, 0.8);

        &.switch-toggle {
            position: relative;
            content: ' ';
            display: inline-block;
            background-color: rgba(variables.$text-color, 0.15);
            height: 32px;
            width: 65px;
            border-radius: 16px;
            font-size: 16px;
            font-weight: lighter;
            color: variables.$text-color;
            overflow: hidden;
            margin-right: 10px;
            transition-property: background-color;
            transition-timing-function: ease-in-out;
            transition-duration: 300ms;

            .on-off {
                display: inline-block;
                position: absolute;
                top: 3px;
                left: 3px;
                background-color: variables.$text-color;
                height: 26px;
                width: 26px;
                line-height: 28px;
                border-radius: 50%;
                transition-property: left;
                transition-timing-function: ease-in-out;
                transition-duration: 300ms;
                box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3);

                &::before,
                &:after {
                    width: 30px;
                    display: block;
                    position: absolute;
                }
                &:before {
                    content: 'On';
                    margin-left: -28px;
                }
                &:after {
                    content: 'Off';
                    margin-left: 32px;
                }
                &.no-text {
                    &:before,
                    &:after {
                        content: '';
                    }
                }
            }
        }
    }
    input {
        position: absolute;
        width: 0;
        height: 0;
        opacity: 0;

        &:checked {
            ~ label.switch-toggle {
                background-color: variables.get-color('secondary', base);

                .on-off {
                    left: 36px;
                }
            }
        }
        &:disabled {
            ~ label {
                cursor: not-allowed;
                opacity: 0.5;
            }
        }
        &:focus {
            ~ label.switch-toggle {
                @include forms.form-control-focus(variables.$input-border-focus, 2px);
            }
        }
    }
    &.switch-sm {
        @include forms.switch(24px);
    }
    &.switch-xs {
        @include forms.switch(18px);
    }
    &.switch-pause {
        .switch-toggle {
            background-color: variables.get-color('alt', base);
        }
    }
}
