/* Text field
 *
 * Always: <label> + control + optional hint + optional error.
 * A placeholder is never a label — it disappears on focus and fails everyone
 * relying on it as the accessible name.
 *
 * Error is announced, not just coloured: role="alert" on the message, plus
 * aria-invalid and aria-describedby on the control.
 */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  /* No fixed width — the container decides. */
  inline-size: 100%;
}

.field__label {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  line-height: var(--leading-snug);
  color: var(--color-text);
}

/* Required marker. The asterisk is decorative — the accessible name comes from
 * the `required` attribute, so it is hidden from assistive tech. */
.field__required {
  color: var(--color-danger);
  margin-inline-start: var(--space-1);
}

.field__control {
  inline-size: 100%;
  min-block-size: var(--target-min);
  padding-inline: var(--space-3);
  padding-block: var(--space-2);

  font-family: inherit;
  font-size: var(--text-base);
  line-height: var(--leading-snug);
  color: var(--color-text);

  background-color: var(--color-surface-raised);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);

  transition:
    border-color var(--duration-fast) var(--ease-out),
    background-color var(--duration-fast) var(--ease-out);
}

/* textarea variant — grows, never fixed height around text. */
textarea.field__control {
  min-block-size: 6rem;
  resize: vertical;
  line-height: var(--leading-normal);
}

.field__control::placeholder {
  color: var(--color-text-muted);
}

.field__control:hover:not(:disabled):not([readonly]) {
  border-color: var(--color-text-muted);
}

.field__control:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus-ring);
  outline-offset: var(--focus-ring-offset);
  border-color: var(--color-accent);
}

/* ---- states ------------------------------------------------------------ */

.field__control:disabled {
  background-color: var(--color-disabled-bg);
  color: var(--color-disabled-text);
  border-color: transparent;
  cursor: not-allowed;
}

.field__control[readonly] {
  background-color: var(--color-surface-sunken);
  border-color: var(--color-border);
}

/* Error. Border colour is reinforcement, never the signal itself — the message
 * below carries the meaning, per design.md's colour rule. */
.field__control[aria-invalid="true"] {
  border-color: var(--color-danger);
}
.field__control[aria-invalid="true"]:focus-visible {
  outline-color: var(--color-danger);
}

.field__hint,
.field__error {
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  margin: 0;
}

.field__hint {
  color: var(--color-text-muted);
}

.field__error {
  color: var(--color-danger);
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-weight: var(--weight-medium);
}

/* Icon paired with the colour so the error is not colour-only. */
.field__error::before {
  content: "!";
  flex: none;
  inline-size: 1.05rem;
  block-size: 1.05rem;
  border-radius: var(--radius-full);
  background-color: var(--color-danger);
  color: var(--color-surface);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  line-height: 1.05rem;
  text-align: center;
}

/* ---- affixes ----------------------------------------------------------- */

/* For a currency code, a domain suffix, or a unit. Logical properties so the
 * affix lands on the correct side under RTL automatically. */
.field__group {
  display: flex;
  align-items: stretch;
}

.field__group .field__control {
  border-start-end-radius: 0;
  border-end-end-radius: 0;
}

.field__affix {
  display: flex;
  align-items: center;
  padding-inline: var(--space-3);
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border-strong);
  border-inline-start: 0;
  border-start-end-radius: var(--radius-md);
  border-end-end-radius: var(--radius-md);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
  white-space: nowrap;
}

/* An action attached to the control — "add a new one" beside a picker, most
 * often. A real <button> sitting next to the field, not an option inside it:
 * an "+ Add new…" entry in a <select> is a command disguised as a value, which
 * screen readers announce as a choosable item and keyboard users select by
 * accident while arrowing through the list.
 *
 * It needs a visible label or an aria-label. A bare "+" has no accessible name. */
.field__action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  flex: none;

  min-block-size: var(--target-min);
  min-inline-size: var(--target-min);
  padding-inline: var(--space-3);

  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--color-text);
  white-space: nowrap;

  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border-strong);
  border-inline-start: 0;
  border-start-end-radius: var(--radius-md);
  border-end-end-radius: var(--radius-md);
  cursor: pointer;

  transition: background-color var(--duration-fast) var(--ease-out);
}

.field__action:hover { background-color: var(--color-surface-raised); }

.field__action:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus-ring);
  outline-offset: var(--focus-ring-offset);
  /* Lift above the adjacent control so the ring is not clipped by its border. */
  position: relative;
  z-index: 1;
}

.field__action:disabled {
  background-color: var(--color-disabled-bg);
  color: var(--color-disabled-text);
  cursor: not-allowed;
}
