/*
Textarea

A native <textarea> in the control chrome that grows with its content
(field-sizing: content, with a script fallback where the browser lacks
it). rows sets the minimum height, maxRows the height where it stops
growing and scrolls. Focus and invalid states are box-shadow and border
color, never size.

  .textarea                  the control
  .textarea.is-sm | is-lg    type size and padding
  .textarea.is-autosize      grows with content
  .textarea.is-invalid       also [aria-invalid="true"]
  [data-resize]              none | vertical | both (the user's handle)
*/

@layer components {

.textarea {
  --textarea-pad-y: calc((var(--control-height) - 1lh) / 2 - var(--control-border-width));

  display:        block;
  width:          100%;
  min-width:      0;
  height:         auto;
  min-height:     calc(var(--textarea-rows, 3) * 1lh + 2 * var(--textarea-pad-y) + 2 * var(--control-border-width));
  margin:         0;
  padding:        var(--textarea-pad-y) var(--control-padding-x);
  border:         var(--control-border-width) solid var(--control-border);
  border-radius:  var(--radius-control);
  background:     var(--control-bg);
  box-shadow:     var(--control-shadow);
  color:          var(--ink);
  font-family:    var(--font-ui);
  font-size:      var(--text-ui);
  font-weight:    var(--weight-body);
  letter-spacing: var(--tracking-ui);
  line-height:    var(--leading-body);
  resize:         vertical;
  transition:     border-color var(--duration-fast) var(--ease-out),
                  box-shadow var(--duration-fast) var(--ease-out);
}

.textarea.is-autosize {
  field-sizing: content;
}

.textarea[data-max-rows] {
  max-height: calc(var(--textarea-max-rows) * 1lh + 2 * var(--textarea-pad-y) + 2 * var(--control-border-width));
}

.textarea[data-resize="none"]     { resize: none; }
.textarea[data-resize="vertical"] { resize: vertical; }
.textarea[data-resize="both"]     { resize: both; }

.textarea::placeholder {
  color:   var(--ink-dim);
  opacity: 1;
}

/* Hover sits at the family's own specificity, so a later focus, checked or
   invalid rule keeps its border while the pointer is over the control. */
.textarea:where(:hover:not(:disabled)) {
  border-color: var(--rule-strong);
}

.textarea:focus-visible {
  outline:      none;
  border-color: var(--focus);
  box-shadow:   var(--focus-ring);
}

.textarea.is-sm {
  --textarea-pad-y: calc((var(--control-height-sm) - 1lh) / 2 - var(--control-border-width));
  padding-inline:   var(--control-padding-x-sm);
  font-size:        var(--text-ui-sm);
}

.textarea.is-lg {
  --textarea-pad-y: calc((var(--control-height-lg) - 1lh) / 2 - var(--control-border-width));
  padding-inline:   var(--control-padding-x-lg);
  font-size:        var(--text-ui-lg);
}

.textarea:disabled {
  cursor:     not-allowed;
  opacity:    var(--opacity-disabled);
  background: var(--bg-soft);
}

.textarea[readonly] {
  background: var(--bg-soft);
  color:      var(--ink-soft);
}

.textarea.is-invalid,
.textarea[aria-invalid="true"] {
  border-color: var(--danger);
}

.textarea.is-invalid:focus-visible,
.textarea[aria-invalid="true"]:focus-visible {
  border-color: var(--danger);
  box-shadow:   var(--focus-ring-danger);
}

}
