/*
 * Form controls. Bootstrap-style classes; every colour comes from the --cf-* tokens.
 *
 *   <div class="mb-3">
 *     <label class="form-label" for="email">Email</label>
 *     <input class="form-control is-invalid" id="email" type="email"
 *            aria-invalid="true" aria-describedby="email-msg">
 *     <div class="invalid-feedback" id="email-msg">Enter a valid email address</div>
 *   </div>
 *
 * Controls: form-control (inputs and textarea), form-select, form-check (+ form-switch)
 * Text:     form-label, form-text, invalid-feedback, valid-feedback
 * States:   is-invalid / is-valid on the control, the disabled attribute
 * Sizes:    form-control-sm (32px), default (40px), form-control-lg (48px)
 * Button inside a field: wrap both in input-group (e.g. the password reveal)
 *
 * Checkboxes, radios and switches are drawn in CSS, so they follow the brand
 * and look the same in every browser.
 */

.form-label {
  display: block;
  margin-bottom: 6px;
  color: var(--cf-body-color);
  font-size: var(--cf-font-size);
  font-weight: var(--cf-font-weight-semibold);
}

.form-control, .form-select,
.input, .input-content textarea {
  display: block;
  width: 100%;
  height: var(--cf-control-height);
  padding: 0 12px;
  border: 1px solid var(--cf-input-border);
  border-radius: var(--cf-radius);
  background-color: var(--cf-input-bg);
  color: var(--cf-body-color);
  font-family: var(--cf-font-sans);
  font-size: var(--cf-font-size-lg);
  line-height: 1.5;
  transition: border-color var(--cf-transition), box-shadow var(--cf-transition);
}

textarea.form-control,
.input-content textarea {
  height: auto;
  min-height: 100px;
  padding: 10px 12px;
  resize: vertical;
}

:is(.form-control, .input, .input-content textarea)::placeholder {
  color: var(--cf-muted-color);
  opacity: 1;
}

:is(.form-control, .form-select, .input, .input-content textarea):hover:not(:disabled):not(:focus) {
  border-color: var(--cf-body-color);
}

:is(.form-control, .form-select, .input, .input-content textarea):focus {
  outline: none;
  border-color: var(--cf-focus-ring);
  box-shadow: 0 0 0 1px var(--cf-focus-ring);
}

:is(.form-control, .form-select, .input, .input-content textarea):disabled {
  background-color: var(--cf-surface-2);
  opacity: var(--cf-disabled-opacity);
  cursor: not-allowed;
}

.form-control-sm, .form-select-sm { height: var(--cf-control-height-sm); font-size: var(--cf-font-size); }
.form-control-lg, .form-select-lg { height: var(--cf-control-height-lg); }

.form-select,
select.input {
  padding-right: 36px;
  appearance: none;
  /* a thin "v" (the designer's select arrow), drawn in the muted text colour so it works in every look */
  background-image:
    linear-gradient(45deg, transparent calc(50% - .75px), var(--cf-muted-color) calc(50% - .75px), var(--cf-muted-color) calc(50% + .75px), transparent calc(50% + .75px)),
    linear-gradient(-45deg, transparent calc(50% - .75px), var(--cf-muted-color) calc(50% - .75px), var(--cf-muted-color) calc(50% + .75px), transparent calc(50% + .75px));
  background-position: calc(100% - 21px) 54%, calc(100% - 16px) 54%;
  background-size: 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}

/* an empty first option works as a placeholder: muted while it is the chosen one */
.form-select:has(> option:checked:is([value=""], [disabled])) {
  color: var(--cf-muted-color);
}
.form-select option {
  color: var(--cf-body-color);
}

/* In a row of controls (header, table header, a label and its select), a select keeps the width the old
   enhanced selects had instead of filling the row. */
:is(.header-info, .table-header-left, .remember-about-payment) > .form-select,
.header-info > .input-content > .form-select {
  width: auto;
  min-width: 231px;
}

/* ---- Validation ---- */

.is-invalid,
.error-field :is(.input, textarea) {
  border-color: var(--cf-danger-text);
}

.is-invalid:focus,
.error-field :is(.input, textarea):focus {
  border-color: var(--cf-danger-text);
  box-shadow: 0 0 0 1px var(--cf-danger-text);
}

.is-valid,
.success-field :is(.input, textarea) {
  border-color: var(--cf-success-text);
}

.is-valid:focus,
.success-field :is(.input, textarea):focus {
  border-color: var(--cf-success-text);
  box-shadow: 0 0 0 1px var(--cf-success-text);
}

.invalid-feedback,
.valid-feedback {
  display: none;
  margin-top: 4px;
  font-size: var(--cf-font-size-sm);
}

.invalid-feedback { color: var(--cf-danger-text); }
.valid-feedback { color: var(--cf-success-text); }
.is-invalid ~ .invalid-feedback,
.is-valid ~ .valid-feedback { display: block; }

.error-field label,
.error-field .error { color: var(--cf-danger-text); }
.success-field label { color: var(--cf-success-text); }

.form-text {
  margin-top: 4px;
  color: var(--cf-muted-color);
  font-size: var(--cf-font-size-sm);
}

/* ---- A button inside the field (password reveal, clear, search) ---- */

.input-group {
  position: relative;
  display: flex;
  align-items: center;
}

.input-group > .form-control {
  flex: 1;
  padding-right: 44px;
}

.input-group > .btn {
  position: absolute;
  top: 50%;
  right: 4px;
  translate: 0 -50%;
}

/* ---- Checkbox, radio, switch ----
 * Every checkbox and radio in the app gets this drawing, including older markup
 * (.checkbox-container); new markup uses form-check / form-check-input. */

.form-check {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 24px;
}

.form-check-label {
  margin: 0;
  color: var(--cf-body-color);
  font-weight: var(--cf-font-weight);
  cursor: pointer;
}

input[type="checkbox"]:not(.apple-switch):not([role="switch"]),
input[type="radio"]:not(.apple-switch) {
  flex: none;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 1px solid var(--cf-input-border);
  border-radius: 4px;
  background: var(--cf-input-bg) center / 12px 12px no-repeat;
  vertical-align: middle;
  cursor: pointer;
  appearance: none;
  transition: background-color var(--cf-transition), border-color var(--cf-transition);
}

input[type="radio"]:not(.apple-switch) {
  border-radius: 50%;
}

:is(input[type="checkbox"]:not(.apple-switch):not([role="switch"]), input[type="radio"]:not(.apple-switch)):hover:not(:disabled) {
  border-color: var(--cf-primary-text);
}

:is(input[type="checkbox"]:not(.apple-switch):not([role="switch"]), input[type="radio"]:not(.apple-switch)):is(:checked, :indeterminate) {
  border-color: var(--cf-primary);
  background-color: var(--cf-primary);
}

/* the mark is white on the brand colour in every look (--cf-on-primary) */
input[type="checkbox"]:not(.apple-switch):not([role="switch"]):checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M2.5 6.2 5 8.6l4.5-5.2'/%3E%3C/svg%3E");
}

input[type="checkbox"]:not(.apple-switch):not([role="switch"]):indeterminate {
  background-image: linear-gradient(var(--cf-on-primary), var(--cf-on-primary));
  background-size: 8px 2px;
}

input[type="radio"]:not(.apple-switch):checked {
  background-image: radial-gradient(circle, var(--cf-on-primary) 0 3.5px, transparent 4px);
}

:is(input[type="checkbox"], input[type="radio"]):disabled {
  opacity: var(--cf-disabled-opacity);
  cursor: not-allowed;
}

:is(input[type="checkbox"], input[type="radio"]):disabled ~ label {
  opacity: var(--cf-disabled-opacity);
}

.form-switch .form-check-input,
input.apple-switch {
  flex: none;
  width: 36px;
  height: 20px;
  margin: 0;
  border: 1px solid var(--cf-input-border);
  border-radius: var(--cf-radius-pill);
  background: var(--cf-input-bg) radial-gradient(circle closest-side, var(--cf-input-border) 78%, transparent 84%) left 1px center / 18px 18px no-repeat;
  cursor: pointer;
  appearance: none;
  transition: background-position var(--cf-transition), background-color var(--cf-transition), border-color var(--cf-transition);
}

.form-switch .form-check-input:checked,
input.apple-switch:checked {
  border-color: var(--cf-primary);
  background-color: var(--cf-primary);
  background-image: radial-gradient(circle closest-side, var(--cf-on-primary) 78%, transparent 84%);
  background-position: right 1px center;
}

/* Text for screen readers only (Bootstrap's name) */
.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  overflow: hidden !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
}
