/*
 * FM-01…FM-05 form controls — shared shell owned by this file.
 *
 * `.fm-control` is the 44px input shell (textarea is exempt from the fixed
 * height) used by Ui::TextInputComponent, Ui::TextareaComponent,
 * Ui::PasswordInputComponent and Ui::SearchInputComponent. Any future form
 * control component reuses this class rather than re-declaring the shell.
 * Token vars only — enforced by test/lint/css_token_lint_test.rb.
 *
 * `.fm-affix` wraps a `.fm-control` plus a leading icon and/or trailing
 * slot (icon, unit text, character count, spinner, clear button) so the
 * affixes sit visually inside the control without the input itself
 * needing asymmetric padding logic baked into every component.
 *
 * Forced-state classes (.is-hover / .is-focus / .is-disabled / …) share
 * their declarations with the real pseudo-classes via compound selectors,
 * so the styleguide can show every state without requiring interaction.
 */

:root {
  /* Textarea rest/auto-grow bounds — component-scoped, not part of the
     shared token set, so they live here rather than in tokens.css. */
  --textarea-min-h: 112px;
  --textarea-max-h: 320px;

  /* Rest fill for every `.fm-control`. The inset tint is designed to sit on
     a white/glass card; on the bare page canvas it is the same colour as the
     page and the field disappears. A canvas context sets this to the solid
     surface (see `.referrer-content` in shell.css) and the card, dialog and
     popover surfaces below reset it, so the fill follows the nearest surface
     by inheritance rather than per view. A new white surface that can hold
     fields belongs in that list. */
  --fm-control-bg: var(--color-surface-inset);
}

.surface-glass,
.ui-card,
dialog,
.ui-popover__panel,
.ui-listbox__panel,
.ui-daterange__panel {
  --fm-control-bg: var(--color-surface-inset);
}

/* ---------------------------------------------------------------------- */
/* FM-01 Field wrapper                                                    */
/* ---------------------------------------------------------------------- */

.fm-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.fm-field__label-row {
  display: flex;
  align-items: baseline;
  gap: var(--space-1);
}

.fm-field__label {
  font-size: var(--text-sm);
  line-height: var(--text-sm--line-height);
  font-weight: 500;
  color: var(--color-ink);
}

.fm-field__required {
  color: var(--color-danger-ink);
}

.fm-field__hint {
  font-size: var(--text-xs);
  line-height: var(--text-xs--line-height);
  color: var(--color-ink-muted);
}

.fm-field__error {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  line-height: var(--text-xs--line-height);
  color: var(--color-danger-ink);
}

.fm-field__error svg {
  flex-shrink: 0;
  display: block;
}

/* Inline (admin) — label left of control, single row */
.fm-field--inline {
  flex-direction: row;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
}

.fm-field--inline .fm-field__label-row {
  flex: 0 0 auto;
}

.fm-field--inline .fm-field__control-column {
  flex: 1 1 auto;
  min-width: 0;
}

/* Horizontal (settings, >= --bp-lg) — label left, wider gutter */
@media (min-width: 1024px) {
  .fm-field--horizontal {
    flex-direction: row;
    align-items: flex-start;
    gap: var(--space-4);
  }

  .fm-field--horizontal .fm-field__label-row {
    flex: 0 0 200px;
    padding-block-start: var(--space-2);
  }

  .fm-field--horizontal .fm-field__control-column {
    flex: 1 1 auto;
    min-width: 0;
  }
}

/* ---------------------------------------------------------------------- */
/* FM-02…FM-05 control shell                                              */
/* ---------------------------------------------------------------------- */

.fm-control {
  display: block;
  width: 100%;
  height: var(--control-h);
  border: none;
  border-radius: var(--radius-lg);
  background: var(--fm-control-bg);
  padding-inline: var(--space-4);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  line-height: var(--text-sm--line-height);
  color: var(--color-ink);
  transition: background-color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}

.fm-control::placeholder {
  font-size: var(--text-sm-light);
  font-weight: 300;
  color: var(--color-ink-muted);
}

.fm-control:hover,
.fm-control.is-hover {
  background: var(--color-surface-hover);
}

.fm-control:focus-visible,
.fm-control.is-focus {
  outline: none;
  background: var(--color-surface-solid);
  box-shadow: var(--focus-halo);
}

.fm-control:disabled,
.fm-control.is-disabled {
  background: var(--color-surface-sunken);
  color: var(--color-ink-disabled);
  cursor: not-allowed;
}

.fm-control:disabled::placeholder,
.fm-control.is-disabled::placeholder {
  color: var(--color-ink-disabled);
}

.fm-control[readonly],
.fm-control.is-readonly {
  background: transparent;
  color: var(--color-ink);
}

.fm-control--error,
.fm-control[aria-invalid="true"] {
  border: 1.5px solid var(--color-danger-strong);
  background: var(--color-danger-subtle);
}

/* Textarea — exempt from the fixed height, min/max instead */
textarea.fm-control {
  height: auto;
  min-height: var(--textarea-min-h);
  max-height: var(--textarea-max-h);
  padding-block: var(--space-3);
  resize: none;
  overflow-y: auto;
}

/* ---------------------------------------------------------------------- */
/* Affix wrapper — leading icon / trailing slot inside the control        */
/* ---------------------------------------------------------------------- */

.fm-affix {
  position: relative;
  display: flex;
  align-items: center;
}

.fm-affix .fm-control {
  width: 100%;
}

.fm-affix--leading .fm-control {
  padding-inline-start: calc(var(--icon-md) + var(--space-4) + var(--space-2));
}

.fm-affix--trailing .fm-control {
  padding-inline-end: calc(var(--icon-md) + var(--space-4) + var(--space-2));
}

/* Trailing 36px control (FM-04 reveal toggle) needs more clearance than a
   bare icon slot. */
.fm-affix--trailing-control .fm-control {
  padding-inline-end: calc(36px + var(--space-2));
}

.fm-affix__leading {
  position: absolute;
  inset-inline-start: var(--space-4);
  display: flex;
  align-items: center;
  pointer-events: none;
  color: var(--color-ink-muted);
}

.fm-affix__leading svg {
  display: block;
}

.fm-affix__trailing {
  position: absolute;
  inset-inline-end: var(--space-4);
  display: flex;
  align-items: center;
  gap: var(--space-1);
  color: var(--color-ink-muted);
  font-size: var(--text-xs);
}

.fm-affix__trailing svg {
  display: block;
}

/* Trailing slot that must be interactive (clear button, reveal toggle)
   sits above the pointer-events-none control padding by being its own
   element outside .fm-control. */
.fm-affix__trailing-action {
  pointer-events: auto;
}

/* ---------------------------------------------------------------------- */
/* FM-04 Password reveal toggle                                           */
/* ---------------------------------------------------------------------- */

.fm-reveal-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: none;
  border-radius: var(--radius-round);
  background: transparent;
  color: var(--color-ink-muted);
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}

.fm-reveal-toggle:hover {
  background: var(--color-surface-hover);
  color: var(--color-ink);
}

.fm-reveal-toggle:focus-visible {
  box-shadow: var(--focus-halo);
}

.fm-reveal-toggle svg {
  display: block;
}

.fm-reveal-toggle__icon--hide {
  display: none;
}

.fm-reveal-toggle.is-revealed .fm-reveal-toggle__icon--show {
  display: none;
}

.fm-reveal-toggle.is-revealed .fm-reveal-toggle__icon--hide {
  display: block;
}

/* ---------------------------------------------------------------------- */
/* FM-04 Password strength meter                                          */
/* ---------------------------------------------------------------------- */

.fm-strength {
  display: flex;
  gap: var(--space-1);
}

.fm-strength__segment {
  flex: 1 1 0;
  height: var(--space-1);
  border-radius: var(--radius-pill);
  background: var(--color-surface-sunken);
  transition: background-color var(--duration-fast) var(--ease-out);
}

.fm-strength__segment.is-filled[data-score="1"] {
  background: var(--color-danger);
}

.fm-strength__segment.is-filled[data-score="2"],
.fm-strength__segment.is-filled[data-score="3"] {
  background: var(--color-warning);
}

.fm-strength__segment.is-filled[data-score="4"] {
  background: var(--color-success);
}

/* ---------------------------------------------------------------------- */
/* FM-05 Search input                                                     */
/* ---------------------------------------------------------------------- */

.fm-control--search {
  border-radius: var(--radius-pill);
  padding-inline-start: calc(var(--icon-md) + var(--space-4) + var(--space-2));
}

.fm-control--search::-webkit-search-cancel-button {
  display: none;
}

.fm-search__clear {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  color: var(--color-ink-muted);
  cursor: pointer;
  padding: 0;
}

.fm-search__clear:hover {
  color: var(--color-ink);
}

.fm-search__spinner {
  display: none;
  width: var(--icon-sm);
  height: var(--icon-sm);
  animation: ui-spin var(--duration-spin) linear infinite;
}

.fm-affix--search.is-loading .fm-search__spinner {
  display: block;
}

.fm-affix--search.is-loading .fm-search__clear {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .fm-search__spinner {
    animation: none;
  }
}
