/* Shared custom controls and loading spinner. Each site sets the --ctl-* and
   --spinner-* variables in its own stylesheet; the rules here only carry
   layout and behaviour so nothing renders with native widget chrome. */
.ctl-select {
  position: relative;
  display: block;
  min-width: 0;
  font: var(--ctl-font, inherit);
  color: var(--ctl-ink, inherit);
}
.ctl-select__button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75em;
  width: 100%;
  min-height: var(--ctl-height, 2.75em);
  margin: 0;
  padding: var(--ctl-pad, 0.6em 0.9em);
  background: var(--ctl-bg, transparent);
  color: inherit;
  border: var(--ctl-border, 1px solid currentColor);
  border-radius: var(--ctl-radius, 4px);
  font: inherit;
  letter-spacing: inherit;
  text-align: left;
  text-transform: inherit;
  line-height: 1.3;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  box-shadow: var(--ctl-shadow, none);
}
.ctl-select__button:hover {
  border-color: var(--ctl-hover-line, var(--ctl-accent, currentColor));
}
.ctl-select__button:focus-visible {
  outline: var(--ctl-focus, 2px solid var(--ctl-accent, currentColor));
  outline-offset: 2px;
}
.ctl-select__button:disabled,
.ctl-select__button[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}
.ctl-select__label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ctl-select__caret {
  flex: none;
  width: 0.55em;
  height: 0.55em;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-20%) rotate(45deg);
  transition: transform 0.15s ease;
  opacity: 0.75;
}
.ctl-select.is-open .ctl-select__caret {
  transform: translateY(20%) rotate(-135deg);
}
.ctl-select__list {
  position: absolute;
  z-index: 60;
  top: calc(100% + 4px);
  left: 0;
  min-width: 100%;
  max-height: min(18rem, 60vh);
  overflow: auto;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: var(--ctl-menu-bg, var(--ctl-bg, #fff));
  color: var(--ctl-menu-ink, var(--ctl-ink, inherit));
  border: var(--ctl-menu-border, var(--ctl-border, 1px solid currentColor));
  border-radius: var(--ctl-radius, 4px);
  box-shadow: var(--ctl-menu-shadow, 0 14px 36px rgba(0, 0, 0, 0.22));
  text-align: left;
}
.ctl-select__list[hidden] {
  display: none;
}
.ctl-select__list.is-up {
  top: auto;
  bottom: calc(100% + 4px);
}
.ctl-select__list [role="option"] {
  padding: var(--ctl-option-pad, 0.55em 0.8em);
  border-radius: max(0px, calc(var(--ctl-radius, 4px) - 2px));
  cursor: pointer;
  white-space: nowrap;
  line-height: 1.35;
}
.ctl-select__list [role="option"].is-active {
  background: var(--ctl-hover, rgba(128, 128, 128, 0.16));
}
.ctl-select__list [role="option"][aria-selected="true"] {
  background: var(--ctl-accent, currentColor);
  color: var(--ctl-on-accent, #fff);
}
.ctl-select__list [role="option"][aria-selected="true"].is-active {
  filter: brightness(1.1);
}
.ctl-select__list [role="option"][aria-disabled="true"] {
  opacity: 0.4;
  cursor: not-allowed;
}
.ctl-select.is-disabled {
  opacity: 0.6;
}

.ctl-radio {
  display: inline-flex;
  min-width: 0;
}
.ctl-radio [role="radio"] {
  margin: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}
.ctl-radio [role="radio"]:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.ctl-switch {
  display: inline-flex;
  min-width: 0;
}
.ctl-switch__button {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}
.ctl-switch__button:focus-visible {
  outline: var(--ctl-focus, 2px solid var(--ctl-accent, currentColor));
  outline-offset: 3px;
  border-radius: 999px;
}
.ctl-switch__button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.ctl-switch__track {
  position: relative;
  flex: none;
  width: var(--ctl-switch-width, 2.4em);
  height: var(--ctl-switch-height, 1.35em);
  border-radius: 999px;
  background: var(--ctl-switch-off, rgba(128, 128, 128, 0.35));
  border: var(--ctl-switch-border, 1px solid transparent);
  transition: background 0.15s ease;
}
.ctl-switch__knob {
  position: absolute;
  top: 50%;
  left: 0.15em;
  width: calc(var(--ctl-switch-height, 1.35em) - 0.4em);
  height: calc(var(--ctl-switch-height, 1.35em) - 0.4em);
  border-radius: 50%;
  background: var(--ctl-switch-knob, #fff);
  transform: translateY(-50%);
  transition: transform 0.15s ease;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
}
.ctl-switch__button[aria-checked="true"] .ctl-switch__track {
  background: var(--ctl-switch-on, var(--ctl-accent, currentColor));
}
.ctl-switch__button[aria-checked="true"] .ctl-switch__knob {
  transform: translate(
    calc(var(--ctl-switch-width, 2.4em) - var(--ctl-switch-height, 1.35em)),
    -50%
  );
}

/* Text inputs never show native search or number chrome. */
.ctl-text,
input[type="text"].ctl-text {
  appearance: none;
  -webkit-appearance: none;
}
input::-webkit-search-cancel-button,
input::-webkit-search-decoration,
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
}

/* Loading indicator: a ring that inherits the text colour. */
.spinner {
  display: inline-block;
  flex: none;
  width: var(--spinner-size, 1.25em);
  height: var(--spinner-size, 1.25em);
  border: var(--spinner-width, 2px) solid
    var(--spinner-track, rgba(128, 128, 128, 0.25));
  border-top-color: var(--spinner-ink, currentColor);
  border-radius: 50%;
  vertical-align: middle;
  animation: spinner-turn 0.8s linear infinite;
}
.spinner--large {
  --spinner-size: 2.25rem;
  --spinner-width: 3px;
}
.spinner-box {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--spinner-box-height, 6rem);
  padding: 1.5rem;
}
@keyframes spinner-turn {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .spinner {
    animation-duration: 1.8s;
  }
}
