/*
Checkbox

A native <input type="checkbox"> drawn as a box, with the check and the
indeterminate dash as icons stacked over it. The input stays the real
control: forms, labels, Space and the mixed state are the browser's.

  .checkbox                     wrapper (inline-grid; input and indicator stack)
  .checkbox-input               the <input type="checkbox">
  .checkbox-indicator           the check or dash, pointer-events: none
  .checkbox[data-state]         checked | unchecked | indeterminate

Size is the contract's --check-size; the unchecked edge is
--control-outline (3:1 against the page in every theme).
*/

@layer components {

.checkbox {

  position:       relative;
  display:        inline-grid;
  flex:           none;
  width:          var(--check-size);
  height:         var(--check-size);
  vertical-align: middle;
}

.checkbox > * {
  grid-area: 1 / 1;
}

.checkbox-input {
  appearance:         none;
  -webkit-appearance: none;
  display:            block;
  width:              100%;
  height:             100%;
  margin:             0;
  border:             var(--control-border-width) solid var(--control-outline);
  border-radius:      var(--radius-check);
  background:         var(--control-bg);
  background-image:   none;
  box-shadow:         var(--control-shadow);
  cursor:             pointer;
  transition:         background-color var(--duration-fast) var(--ease-out),
                      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. */
.checkbox-input:where(:hover:not(:disabled)) {
  border-color: var(--accent);
}

.checkbox-input:checked,
.checkbox-input:indeterminate {
  border-color:     var(--accent);
  background-color: var(--accent);
  background-image: none;
}

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

.checkbox-indicator {
  display:         flex;
  align-items:     center;
  justify-content: center;
  color:           var(--accent-ink);
  pointer-events:  none;
  visibility:      hidden;
}

.checkbox-indicator svg {
  width:        calc(var(--check-size) * 0.75);
  height:       calc(var(--check-size) * 0.75);
  stroke-width: calc(var(--icon-stroke) * 1.5);
}

.checkbox-indicator .icon[data-icon="minus"] {
  display: none;
}

.checkbox[data-state="checked"] > .checkbox-indicator,
.checkbox[data-state="indeterminate"] > .checkbox-indicator {
  visibility: visible;
}

.checkbox[data-state="indeterminate"] > .checkbox-indicator .icon[data-icon="check"] {
  display: none;
}

.checkbox[data-state="indeterminate"] > .checkbox-indicator .icon[data-icon="minus"] {
  display: block;
}

/* States */

.checkbox-input:disabled {
  cursor: not-allowed;
}

/* Dimmed by the effective disabled state: its own prop, a disabled Field
   (which disables the input) or a native <fieldset disabled>. */
.checkbox:is([data-disabled], :has(> .checkbox-input:disabled)) {
  opacity: var(--opacity-disabled);
}

/* Disabled dims once: the wrapper does it, so the input does not repeat the
   base input rule, and a label or Field that already dims the control's
   whole row leaves the wrapper at full opacity. */
.checkbox-input:disabled {
  opacity: 1;
}

:is(.label:has(:disabled), .label[data-disabled], .field-label:has(:disabled), .field:is([data-disabled], fieldset:disabled .field) > :is(.field-label, .field-content)) .checkbox {
  opacity: 1;
}

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

.checkbox-input[aria-invalid="true"]:checked,
.checkbox-input[aria-invalid="true"]:indeterminate {
  background-color: var(--danger);
}

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

/* CheckboxGroup: a column of boxes and their labels. */
.checkbox-group {
  display:        flex;
  flex-direction: column;
  align-items:    flex-start;
  gap:            var(--space-2);
}

}
