/*
InputGroup

One control-tier box holding an <Input> or <Textarea> and addons: icons,
text, buttons, keyboard hints. The group draws the border, background,
focus ring and invalid state; the control inside drops its own chrome.
Addons are placed by data-align with CSS order, so they can follow the
control in the DOM (focus order stays: control first, then its buttons).

  .input-group                         the box (role=group)
  .input-group-addon[data-align]       inline-start | inline-end | block-start | block-end
  .input-group-text                    muted text or icon
  .input-group-button[data-size]       xs | sm | icon-xs | icon-sm
  .input-group > .input / .textarea / [data-slot=input-group-control]
*/

@layer components {

.input-group {
  position:      relative;
  display:       flex;
  align-items:   center;
  width:         100%;
  min-width:     0;
  height:        var(--control-height);
  border:        var(--control-border-width) solid var(--control-border);
  border-radius: var(--radius-control);
  background:    var(--control-bg);
  box-shadow:    var(--control-shadow);
  transition:    border-color var(--duration-fast) var(--ease-out),
                 box-shadow var(--duration-fast) var(--ease-out);
}

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

.input-group:has(> :is(.input, .textarea, [data-slot="input-group-control"]):focus-visible) {
  border-color: var(--focus);
  box-shadow:   var(--focus-ring);
}

.input-group:has(> .textarea),
.input-group:has(> textarea[data-slot="input-group-control"]),
.input-group:has(> [data-align="block-start"]),
.input-group:has(> [data-align="block-end"]) {
  height: auto;
}

.input-group:has(> [data-align="block-start"]),
.input-group:has(> [data-align="block-end"]) {
  flex-direction: column;
  align-items:    stretch;
}

/* The control inside gives up its chrome to the group. */
.input-group > :is(.input, .textarea, [data-slot="input-group-control"]) {
  flex:          1 1 auto;
  min-width:     0;
  height:        100%;
  border:        0;
  border-radius: 0;
  background:    transparent;
  box-shadow:    none;
}

.input-group > :is(.input, .textarea, [data-slot="input-group-control"]):focus-visible {
  outline:    none;
  box-shadow: none;
}

.input-group > .textarea[data-resize] {
  resize: none;
}

.input-group:has(> [data-align="inline-start"]) > .input {
  padding-inline-start: var(--space-2);
}

.input-group:has(> [data-align="inline-end"]) > .input {
  padding-inline-end: var(--space-2);
}

/* States */

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

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

.input-group[data-disabled],
.input-group:has(> :is(.input, .textarea):disabled) {
  background: var(--bg-soft);
  cursor:     not-allowed;
}

.input-group[data-disabled] > .input-group-addon,
.input-group:has(> :is(.input, .textarea):disabled) > .input-group-addon {
  opacity: var(--opacity-disabled);
}

/* Addons */

.input-group-addon {
  display:        flex;
  flex:           none;
  align-items:    center;
  justify-content: center;
  gap:            var(--control-gap);
  height:         100%;
  color:          var(--ink-soft);
  font-family:    var(--font-ui);
  font-size:      var(--text-ui);
  font-weight:    var(--weight-ui);
  letter-spacing: var(--tracking-ui);
  cursor:         text;
  user-select:    none;
}

.input-group-addon svg {
  width:  var(--icon-size);
  height: var(--icon-size);
}

.input-group-addon[data-align="inline-start"] {
  order:        -1;
  padding-inline-start: var(--control-padding-x-sm);
}

.input-group-addon[data-align="inline-end"] {
  order:         1;
  padding-inline-end: var(--control-padding-x-sm);
}

/* A button wrapped in a Tooltip, Popover or DropdownMenu trigger counts the same. */
.input-group-addon[data-align="inline-start"]:has(> .input-group-button, > :is(.tooltip-root, .popover-root, .dropdown-menu-root) > :is(.tooltip-trigger, .popover-trigger, .dropdown-menu-trigger) > .input-group-button) {
  padding-inline-start: var(--space-1);
}

.input-group-addon[data-align="inline-end"]:has(> .input-group-button, > :is(.tooltip-root, .popover-root, .dropdown-menu-root) > :is(.tooltip-trigger, .popover-trigger, .dropdown-menu-trigger) > .input-group-button) {
  padding-inline-end: var(--space-1);
}

.input-group-addon[data-align="block-start"],
.input-group-addon[data-align="block-end"] {
  justify-content: flex-start;
  width:           100%;
  height:          auto;
  padding:         var(--space-2) var(--control-padding-x);
}

.input-group-addon[data-align="block-start"] {
  order: -1;
}

.input-group-addon[data-align="block-end"] {
  order: 1;
}

.input-group-addon.is-bordered[data-align="block-start"] {
  border-bottom: var(--control-border-width) solid var(--rule);
}

.input-group-addon.is-bordered[data-align="block-end"] {
  border-top: var(--control-border-width) solid var(--rule);
}

.input-group:has(> [data-align="block-start"]) > .input,
.input-group:has(> [data-align="block-end"]) > .input {
  height: var(--control-height);
}

.input-group-addon > kbd {
  border-radius: var(--radius-tag);
}

.input-group-text {
  display:     inline-flex;
  align-items: center;
  gap:         var(--control-gap);
  color:       var(--ink-soft);
  font-family: var(--font-ui);
  font-size:   var(--text-ui);
  white-space: nowrap;
}

.input-group-text svg {
  width:          var(--icon-size);
  height:         var(--icon-size);
  pointer-events: none;
}

/* BUTTONS: a Button sized to sit inside the box. */

.input-group .button.input-group-button {
  height:    calc(var(--control-height) - 2 * var(--space-1) - 2 * var(--control-border-width));
  padding:   0 var(--control-padding-x-sm);
  font-size: var(--text-ui-sm);
  box-shadow: none;
}

/* The rule above clears box-shadow at (0,3,0), which beats
   .button:focus-visible: give every variant its ring back. */
.input-group .button.input-group-button:focus-visible,
.input-group .button.input-group-button:has(> input:focus-visible) {
  box-shadow: var(--focus-ring);
}

.input-group .button.input-group-button.is-danger:focus-visible {
  box-shadow: var(--focus-ring-danger);
}

.input-group .button.input-group-button[data-size="xs"] {
  height: calc(var(--control-height-sm) - 2 * var(--space-1));
  padding: 0 var(--space-2);
}

.input-group .button.input-group-button[data-size="icon-xs"] {
  width:   calc(var(--control-height-sm) - 2 * var(--space-1));
  height:  calc(var(--control-height-sm) - 2 * var(--space-1));
  padding: 0;
}

.input-group .button.input-group-button[data-size="icon-sm"] {
  width:   calc(var(--control-height) - 2 * var(--space-1) - 2 * var(--control-border-width));
  padding: 0;
}

.input-group .button.input-group-button svg {
  width:  var(--icon-size-sm);
  height: var(--icon-size-sm);
}

}
