/*
Input

A native <input> in the control tier's chrome. Builds on @elements/style's
bare input (which sets height, border and the caret) and moves it onto the
contract tokens: control height, padding, border, radius, font, and a
box-shadow focus ring, so a focused or invalid input never changes size.

  .input                     the control
  .input.is-sm | is-lg       size (md has no class)
  .input.is-invalid          also [aria-invalid="true"]: danger border and ring
  .input[type="file"]        the picker button drawn as a small ghost button
*/

@layer components {

.input {
  display:        block;
  width:          100%;
  min-width:      0;
  height:         var(--control-height);
  margin:         0;
  padding:        0 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-snug);
  transition:     border-color var(--duration-fast) var(--ease-out),
                  box-shadow var(--duration-fast) var(--ease-out);
}

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

.input::selection {
  background: var(--accent);
  color:      var(--accent-ink);
}

/* 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. */
.input:where(:hover:not(:disabled)) {
  border-color: var(--rule-strong);
}

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

.input.is-sm {
  height:    var(--control-height-sm);
  padding:   0 var(--control-padding-x-sm);
  font-size: var(--text-ui-sm);
}

.input.is-lg {
  height:    var(--control-height-lg);
  padding:   0 var(--control-padding-x-lg);
  font-size: var(--text-ui-lg);
}

/* States */

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

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

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

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

/* File */

.input[type="file"] {
  display:     flex;
  align-items: center;
  padding-inline-start: var(--space-1);
  color:       var(--ink-soft);
  cursor:      pointer;
}

.input[type="file"]::file-selector-button {
  height:         auto;
  margin-block:   0;
  margin-inline:  0 var(--control-gap);
  padding:        0 var(--control-padding-x-sm);
  line-height:    calc(var(--control-height) - 2 * var(--space-1) - 2 * var(--control-border-width));
  border:         0;
  border-radius:  var(--radius-control);
  background:     var(--secondary);
  color:          var(--secondary-ink);
  font-family:    var(--font-ui);
  font-size:      var(--text-ui-sm);
  font-weight:    var(--weight-ui);
  letter-spacing: var(--tracking-ui);
  text-transform: var(--case-ui);
  cursor:         pointer;
}

.input[type="file"]:hover::file-selector-button {
  background: var(--secondary-hover);
}

/* Native pickers (date, time) and the search clear button follow the mode. */
.input::-webkit-calendar-picker-indicator {
  opacity: 0.6;
  cursor:  pointer;
}

}
