/*
 * Textarea
 *
 * Measured from Figma `Textarea` (1301:334). Three sizes x seven states, and
 * every one of them is Input's — a textarea is an input that wrapped. If the
 * two ever diverge it should be because a design said so, not because one
 * drifted; the shared vocabulary is the point.
 *
 * THE HEIGHT IS DERIVED, NOT TYPED
 *
 * Figma's frame hugs a three-line text node, so the box height falls out of
 * bound padding and a bound line-height rather than a number someone picked:
 *
 *   sm   3 x 20 + 2 x 6   =  72
 *   md   3 x 24 + 2 x 8   =  88
 *   lg   3 x 24 + 2 x 12  =  96
 *
 * `rows={3}` reproduces that in the browser for free, and it keeps working when
 * the type ramp moves. Do not replace it with a fixed `height` — that would
 * pin the box while the text inside it kept scaling.
 *
 * THE RESIZE GRIP IS THE BROWSER'S, AND THIS FILE MUST NOT DRAW ONE
 *
 * `resize: vertical` makes the browser paint the two-diagonal grip in the
 * bottom-right corner. Figma draws that grip too, at border/stronger — but as
 * documentation of a native control, not as a spec for one. The native grip
 * cannot be styled, so a custom one here would not replace it; it would sit
 * beside it and every field would have two.
 *
 * Horizontal resize is off deliberately: a field that can grow wider than its
 * container breaks the layout around it, and no design here asks for it.
 */

.ion-textarea {
  --ion-textarea-padding-x: var(--spacing-12);
  --ion-textarea-padding-y: var(--spacing-8);
  --ion-textarea-radius: var(--radius-md);
  --ion-textarea-font-size: var(--type-body);
  --ion-textarea-line-height: var(--type-body-line-height);
  --ion-textarea-border-width: var(--border-width-default);

  display: block;
  width: 100%;
  box-sizing: border-box;

  /*
   * Same correction Input makes, and for the same reason: Figma draws its
   * stroke INSIDE the frame so padding is measured from the outer edge, while a
   * CSS border sits outside the padding box. Subtracting the live border width
   * puts the text where Figma puts it.
   */
  padding: var(--ion-textarea-padding-y)
    calc(var(--ion-textarea-padding-x) - var(--ion-textarea-border-width));
  background-color: var(--surface-default);
  border-style: solid;
  border-width: var(--ion-textarea-border-width);
  border-color: var(--border-default);
  border-radius: var(--ion-textarea-radius);
  color: var(--text-secondary);
  font-family: var(--font-family-sans);
  font-size: var(--ion-textarea-font-size);
  line-height: var(--ion-textarea-line-height);
  font-weight: var(--font-weight-regular);
  resize: vertical;
  transition:
    border-color var(--ion-duration-base) var(--ion-ease-out),
    background-color var(--ion-duration-base) var(--ion-ease-out);
}

.ion-textarea--sm {
  --ion-textarea-padding-y: var(--spacing-6);
  --ion-textarea-radius: var(--radius-sm);
  --ion-textarea-font-size: var(--type-body-sm);
  --ion-textarea-line-height: var(--type-body-sm-line-height);
}

/* Large keeps Medium's radius and type ramp — only padding grows, as on Input. */
.ion-textarea--lg {
  --ion-textarea-padding-x: var(--spacing-16);
  --ion-textarea-padding-y: var(--spacing-12);
}

/*
 * Figma's Filled state differs from Default only in the value colour, which is
 * exactly the placeholder distinction — so it needs no variant, the same
 * resolution input.css reached.
 *
 * text/tertiary, and THERE IS NO LONGER A text/placeholder TO REACH FOR.
 *
 * The role read 2.38:1 in Light and 2.33:1 in Dark against the 4.5 SC 1.4.3
 * asks, and the criterion does not exempt placeholder text. Writing this file
 * against the Figma binding failed 14 contrast pairings immediately, which is
 * how the defect surfaced at all: no stylesheet had ever used the role, so
 * nothing measured it. It was retired from Figma and the export on 5 Sep 2026
 * rather than exempted, and Input's six bindings moved here too.
 *
 * Base Web makes the same call — `inputPlaceholder` points at `contentTertiary`
 * and there is no placeholder colour. Carbon keeps one, at 2.38:1, and has an
 * open issue about it.
 */
.ion-textarea::placeholder {
  color: var(--text-tertiary);
  opacity: 1;
}

/*
 * State order is deliberate and equal-specificity, so later rules win:
 * hover -> focus -> invalid -> read-only -> disabled.
 */

/*
 * Hover is declared twice, as on Input and Button. Native `:hover` latches on
 * touch until you tap elsewhere; `[data-hovered]` comes from React Aria's
 * useHover, which is pointer-aware. The media query keeps this working without
 * React.
 */
@media (hover: hover) {
  .ion-textarea:hover {
    border-color: var(--border-strong);
  }
}

.ion-textarea[data-hovered='true'] {
  border-color: var(--border-strong);
}

.ion-textarea:focus,
.ion-textarea[data-focused='true'] {
  border-color: var(--border-focus);
  outline: none;
}

/*
 * 1px, matching Input as of 0.49.0. Input's stylesheet carries the full note:
 * this width used to be 2px so the error state would not rest on hue alone,
 * which is what WCAG 1.4.1 asks. It was thinned on an explicit design call, and
 * an icon or a message is the better way to restore that cue.
 */
.ion-textarea--invalid,
.ion-textarea[data-invalid='true'] {
  border-color: var(--border-error-strong);
}

/*
 * Read-only keeps the value legible but drops the field out of the editable
 * palette — page surface, subtle border. It stays resizable, which is what the
 * browser does and what the Figma set shows.
 */
.ion-textarea--readonly,
.ion-textarea[data-readonly='true'] {
  background-color: var(--surface-page);
  border-color: var(--border-subtle);
}

/*
 * Disabled turns resize off. A disabled textarea cannot be resized in any
 * browser and none of them draw the grip on one, so `resize: none` here is
 * matching the platform rather than making a choice.
 */
.ion-textarea:disabled,
.ion-textarea[data-disabled='true'] {
  background-color: var(--surface-disabled);
  border-color: var(--border-disabled);
  color: var(--text-disabled);
  cursor: not-allowed;
  resize: none;
}

.ion-textarea:disabled::placeholder,
.ion-textarea[data-disabled='true']::placeholder {
  color: var(--text-disabled);
}

@media (prefers-reduced-motion: reduce) {
  .ion-textarea {
    transition: none;
  }
}
