/* --- Forms ------------------------------------------------------------------------------ */

/* Text fields, selects and textareas: a dark well (--bg, also inside a card), one
   control height, the 10px corner. The outline is --control-border (buttons.css: --line
   on the page, --line-strong on a raised surface). background-COLOR, never the
   shorthand: the select's arrow is a background-image.

   The base selector is (0,3,1). Its :hover and :focus-visible rules repeat it, or a
   plain `input:focus-visible` would lose the border to it (theme.test.mjs checks). */
input:not([type="range"]):not([type="checkbox"]):not([type="file"]),
select,
textarea {
  width: 100%;
  min-height: var(--control-h);
  padding: .5rem .875rem;
  background-color: var(--bg);
  color: var(--fg);
  border: 1px solid var(--control-border, var(--line));
  border-radius: var(--radius-md);
  font: inherit;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color var(--motion-fast) var(--ease), box-shadow var(--motion-fast) var(--ease);
}
input::placeholder, textarea::placeholder { color: var(--fg-muted); opacity: 1; }
input:not([type="range"]):not([type="checkbox"]):not([type="file"]):hover,
select:hover,
textarea:hover { border-color: var(--control-border-hover, var(--line-strong)); }
/* One ring: the edge turns --focus and a soft halo surrounds it. The outline stays,
   transparent, because forced-colours mode drops box-shadow and paints outlines. */
input:not([type="range"]):not([type="checkbox"]):not([type="file"]):focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 0;
  border-color: var(--focus);
  box-shadow: 0 0 0 3px rgba(143, 200, 255, .35);
}
/* Invalid: a red edge plus the .field-error line that says why (never colour alone).
   Set as the custom property so it holds on any surface and under hover. */
[aria-invalid="true"] { --control-border: var(--danger); --control-border-hover: var(--danger); }
/* Disabled: a field that cannot change here (your own username in the admin user
   dialog). Dimmed like a disabled button; its hint says why. */
input:disabled, select:disabled, textarea:disabled { opacity: .5; cursor: not-allowed; }

textarea { min-height: 5rem; resize: vertical; line-height: 1.5; }

/* The select's arrow, drawn with two gradients: an SVG would need a data: URI with
   a namespace URI in it, which the asset scan refuses. */
select {
  width: auto;
  padding-right: 2.25rem;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--fg-muted) 50%),
    linear-gradient(135deg, var(--fg-muted) 50%, transparent 50%);
  background-position: calc(100% - 1.125rem) 52%, calc(100% - .8125rem) 52%;
  background-size: .3125rem .3125rem;
  background-repeat: no-repeat;
  cursor: pointer;
}

input[type="checkbox"] { width: 1.25rem; height: 1.25rem; margin: 0; accent-color: var(--accent); }

/* A form is a column of fields; its buttons keep their own width (an auth page
   stretches its one primary, css/views/account.css). */
.stack { display: grid; gap: var(--space-4); max-width: 24rem; }
.stack > .btn { justify-self: start; }
.field { display: grid; gap: var(--space-2); }
.field-label { font-family: var(--font-chrome); font-size: var(--text-sm); font-weight: 500; color: var(--fg-muted); }
/* Between the label and the control (form.js), so the gap after the field stays even. */
.field-hint { margin-top: calc(-1 * var(--space-1)); color: var(--fg-muted); font-size: var(--text-sm); }
.field-error { color: var(--danger); font-size: var(--text-sm); }
.field-inline { display: flex; align-items: center; gap: var(--space-3); }
.check { display: flex; align-items: center; gap: var(--space-3); min-height: var(--target); font-family: var(--font-chrome); cursor: pointer; }

/* An on/off switch (form.js switchField): a button[role="switch"] whose track is the
   button and whose thumb is ::before; the state is also written beside it. Off is a
   --surface-3 track with an outlined edge and an --fg thumb; on is brass with a --bg
   thumb. ::after widens the hit area to the 44px target without moving anything. */
.switch-row { display: flex; align-items: center; gap: var(--space-3); min-height: var(--control-h); }
.switch {
  position: relative;
  flex: none;
  width: 2.5rem;
  height: 1.5rem;
  padding: 0;
  background: var(--surface-3);
  border: 1px solid var(--control-border, var(--line));
  border-radius: var(--radius-pill);
  transition: background-color var(--motion-fast) var(--ease), border-color var(--motion-fast) var(--ease);
}
.switch::before {
  content: "";
  position: absolute;
  top: 50%;
  left: .125rem;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: -.5625rem;
  border-radius: 50%;
  background: var(--fg);
  transition: transform var(--motion-fast) var(--ease);
}
.switch::after { content: ""; position: absolute; inset: -.625rem -.25rem; }
.switch[aria-checked="true"] { background: var(--accent); border-color: var(--accent); }
.switch[aria-checked="true"]::before { background: var(--bg); transform: translateX(1rem); }
.switch-state { color: var(--fg); }
.switch-field > .field-label, .switch-state { cursor: pointer; user-select: none; }

.form-result:empty { display: none; }
.form-result { margin: 0; }
.form-result.success { color: var(--fg); }

/* Range sliders. The filled part of a seek bar comes from --progress (seek-control.js
   sets it through the CSSOM); the thumb, in --fg, is what identifies the control. */
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  height: 1.5rem;
  margin: 0;
  background: transparent;
  cursor: pointer;
}
input[type="range"]:disabled { cursor: default; opacity: .5; }
input[type="range"]::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: var(--radius-pill);
  background: linear-gradient(to right, var(--accent) calc(var(--progress, 1) * 100%), var(--line) 0);
}
input[type="range"].volume::-webkit-slider-runnable-track { background: var(--line); }
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px;
  height: 14px;
  margin-top: -5px;
  border: 0;
  border-radius: 50%;
  background: var(--fg);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
}
input[type="range"]::-moz-range-track { height: 4px; border-radius: var(--radius-pill); background: var(--line); }
input[type="range"]::-moz-range-progress { height: 4px; border-radius: var(--radius-pill); background: var(--accent); }
input[type="range"]::-moz-range-thumb {
  width: 14px;
  height: 14px;
  border: 0;
  border-radius: 50%;
  background: var(--fg);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
}

progress {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 6px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  color: var(--accent);
  overflow: hidden;
}
progress::-webkit-progress-bar { background: var(--surface-3); border-radius: var(--radius-pill); }
progress::-webkit-progress-value { background: var(--accent); border-radius: var(--radius-pill); }
progress::-moz-progress-bar { background: var(--accent); border-radius: var(--radius-pill); }
