/* Form controls (issue 3439, design epic 3432, DS-5): the one implementation of
 * each. Figma: Search and Filter Bar 1:6803, top search 50:16264, Switch
 * 42:11868, radios 1:7217 / 1:9385 / 1:12319, Code digit 1:8654 / 1:8664.
 * Behaviour (keys, OTP typing and paste) is in ds/forms.ts. Tokens only.
 *
 *   Search (table)  .pr-search  (label > svg + input + kbd "/")
 *   Search (top)    .ui-search  (uiSearchInput)
 *   Segmented       .segmented > button, .ui-segmented > .ui-segment (uiSegmented)
 *   Select          .dd-button (dropdown.ts enhanceSelect) and a bare .select > select
 *   Filter button   details.more-filters > summary.btn-icon (+ .filter-count when applied)
 *   Text input      .field input / select / textarea, .money-input
 *   Switch          input.switch[role=switch], .switch-danger
 *   Radio           input.radio (18), .radio-m (16), .radio-s (14); .choice radios
 *   Checkbox        input.checkbox; .choice checkboxes (proposed, not in Figma)
 *   OTP digits      .otp > input.otp-digit x6 (uiOtpInput)
 *   Error           [aria-invalid="true"] on any of them, .field-error helper text
 *
 * Gallery-only forced states: .is-hover, .is-focus (a static panel cannot hover).
 */

/* Tokens this family adds (own file, so tokens.css stays untouched).
 * --input-border: a control's boundary. Light draws --border as Figma does.
 * Dark takes --border-control: Figma's dark --border is 1.2:1 on --surface,
 * invisible (issue 3435 review, WCAG 1.4.11); --border-control is 2.4:1.
 * --control-on: an on switch, a picked radio. Figma's --brand is 2.5:1 on
 * white, so light takes --primary (5.5:1); dark is --brand itself (7:1). */
:root {
  --input-border: var(--border);
  --control-on: var(--primary);
  --control-thumb-on: var(--primary-fg);
  --control-border: var(--fg-muted); /* unchecked radio and checkbox ring: Figma's --border-control is 1.5:1 on white, below 3:1 */
  --input-ring: 0 0 0 3px color-mix(in srgb, var(--brand) 20%, transparent);
  --check-fill: var(--ink);
  /* the check and the indeterminate bar: --brand-mint on --ink (light) */
  --check-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%2334d399' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 8.5l2.5 2.5L12 5.5'/%3E%3C/svg%3E");
  --check-bar: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%2334d399' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M4.5 8h7'/%3E%3C/svg%3E");
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --input-border: var(--border-control);
    --check-fill: var(--brand);
    --check-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%230b0f0e' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 8.5l2.5 2.5L12 5.5'/%3E%3C/svg%3E");
    --check-bar: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%230b0f0e' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M4.5 8h7'/%3E%3C/svg%3E");
  }
}
:root[data-theme="dark"] {
  --input-border: var(--border-control);
  --check-fill: var(--brand);
  --check-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%230b0f0e' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 8.5l2.5 2.5L12 5.5'/%3E%3C/svg%3E");
  --check-bar: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%230b0f0e' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M4.5 8h7'/%3E%3C/svg%3E");
}

/* ---- Shared: the focus look of a text control (not in Figma): the focus
 * colour as the border plus a soft brand ring; red when invalid. ---- */
.pr-search:focus-within, .ui-search:focus-within, .money-input:focus-within, .field .is-focus,
.field input:where(:not([type="checkbox"], [type="radio"], .money-input input)):focus, .field select:focus, .field textarea:focus, .pr-search.is-focus, .ui-search.is-focus {
  outline: 0; border-color: var(--focus); box-shadow: var(--input-ring);
}
.pr-search:has([aria-invalid="true"]), .money-input:has([aria-invalid="true"]),
.field input:where(:not([type="checkbox"], [type="radio"]))[aria-invalid="true"], .field select[aria-invalid="true"], .field textarea[aria-invalid="true"] { border-color: var(--danger-fg); }
.field-error { margin: 0; font: var(--type-body-sm); color: var(--danger-fg); }
.field-error:empty { display: none; }

/* ---- Search (table), 1:6806: 42 high, radius 12; the icon at 12, text at 36,
 * the "/" hint at the right. The hint hides while the field has focus. ---- */
.pr-search {
  display: flex; align-items: center; gap: 10px; height: 42px; padding: 0 15px 0 12px;
  background: var(--surface); border: 1px solid var(--input-border); border-radius: var(--radius-xl); color: var(--fg-muted);
}
.pr-search > svg { width: 14px; height: 14px; flex: none; }
.pr-search input { flex: 1; min-width: 0; height: 100%; padding: 0; border: 0; outline: 0; background: transparent; color: var(--fg); font: var(--type-input); }
.pr-search input::placeholder, .ui-search input::placeholder { color: var(--fg-muted); font: var(--type-input); opacity: 1; }
.pr-search input::-webkit-search-cancel-button { display: none; }
.pr-search kbd {
  display: inline-flex; align-items: center; justify-content: center; flex: none; padding: 3px 7px;
  border: 1px solid var(--border-card); border-radius: var(--radius-sm); font: var(--type-pill); color: var(--fg-muted);
}
.pr-search:focus-within kbd, .pr-search.is-focus kbd { visibility: hidden; }

/* ---- Search (top bar), 50:16264: sunken, no border, radius 12, 34 high. ---- */
.ui-search {
  display: flex; align-items: center; gap: 10px; width: min(256px, 26vw); height: 34px; padding: 0 16px 0 12px;
  background: var(--surface-sunken); border: 1px solid transparent; border-radius: var(--radius-xl); color: var(--fg-muted);
}
.ui-search > svg { width: 14px; height: 14px; flex: none; }
.ui-search input { flex: 1; min-width: 0; height: 100%; padding: 0; border: 0; outline: 0; background: transparent; color: var(--fg); font: var(--type-input); }

/* ---- Segmented control, 1:6815: one bordered radius-12 strip, segments
 * divided by 1px, Inter Bold 11. Selected is ink with a white label; in dark
 * the same inverse pair (--action), since ink on the dark surface vanishes. */
.segmented, .ui-segmented {
  display: inline-flex; width: max-content; max-width: 100%; padding: 0; gap: 0; overflow: hidden;
  background: var(--surface); border: 1px solid var(--input-border); border-radius: var(--radius-xl);
}
.ui-segmented { display: flex; margin: 0 auto 4px; overflow: visible; } /* centred; its tooltips hang below */
.segmented button, .ui-segment {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: auto; padding: 8px 16px;
  border: 0; border-left: 1px solid var(--input-border); border-radius: 0; background: var(--surface); color: var(--fg-muted);
  font: var(--type-label); white-space: nowrap; cursor: pointer;
  transition: background-color .12s ease, color .12s ease;
}
.segmented > button:first-child, .ui-segmented > :first-child, .ui-segmented > :first-child .ui-segment { border-left: 0; }
.ui-segmented > :first-child .ui-segment, .ui-segmented > .ui-segment:first-child { border-radius: 11px 0 0 11px; }
.ui-segmented > :last-child .ui-segment, .ui-segmented > .ui-segment:last-child { border-radius: 0 11px 11px 0; }
.segmented button:hover:not(:disabled), .ui-segment:hover:not(:disabled), .segmented button.is-hover { color: var(--fg); }
.segmented button[aria-pressed="true"], .ui-segment[aria-pressed="true"] { background: var(--action); color: var(--action-fg); }
.segmented button:focus-visible, .ui-segment:focus-visible, .segmented button.is-focus { outline: 2px solid var(--focus); outline-offset: -3px; }
.segmented button:disabled, .ui-segment:disabled { cursor: not-allowed; opacity: .55; }
.segmented button[aria-pressed="true"]:disabled { opacity: 1; }
.segmented .count { font: var(--type-meta); color: inherit; opacity: .8; font-variant-numeric: tabular-nums; }

/* ---- Select trigger, 1:6825: radius 12, 1px border, Inter Bold 11, a
 * 10px chevron 12 from the right. Open rotates the chevron (150 ms, not in
 * Figma); the list is dropdown.ts's (issue 3442 restyles the panel). ---- */
.dd-button, .select select {
  display: inline-flex; align-items: center; gap: 11px; width: 100%; height: auto; min-height: 36px; padding: 9px 12px 9px 13px;
  border: 1px solid var(--input-border); border-radius: var(--radius-xl); background-color: var(--surface); color: var(--fg);
  font: var(--type-label); text-align: left; white-space: nowrap; cursor: pointer;
  transition: border-color .15s, box-shadow .15s, background-color .15s;
}
.select select {
  width: auto; padding-right: 33px; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; background-size: 10px;
}
.dd-button:hover:not(:disabled), .select select:hover:not(:disabled), .dd-button.is-hover { border-color: var(--hover-border); }
.dd-button:focus-visible, .select select:focus-visible, .dd-button.is-focus { outline: 0; border-color: var(--focus); box-shadow: var(--input-ring); }
.dd-button:disabled, .select select:disabled { background-color: var(--surface-disabled); color: var(--fg-muted); cursor: not-allowed; }
.dd-value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.dd-chevron { width: 10px; height: 10px; flex: none; color: var(--fg-muted); transition: transform .15s ease; }
.dd.open .dd-chevron { transform: rotate(180deg); }
.dd.open .dd-button { border-color: var(--focus); box-shadow: var(--input-ring); }
.dd.is-set .dd-button, .select select.is-set { border-color: var(--primary); background-color: var(--select-tint); }
.dd-button[aria-invalid="true"], .select select[aria-invalid="true"] { border-color: var(--danger-fg); }

/* ---- Filter button, 1:6836: the issue 3438 secondary icon-only button, drawn
 * 34x34 radius 12 in the toolbar (proposed: Figma's toolbar radius, an open
 * question on issue 3439). Applied (filters set): brand border and tint, the count. */
.more-filters > summary.btn-icon { width: 34px; height: 34px; min-height: 34px; padding: 0; border: 1px solid var(--input-border); border-radius: var(--radius-xl); }
.more-filters:has(.filter-count) > summary.btn-icon { border-color: var(--primary); background: var(--select-tint); color: var(--primary-text); }

/* ---- Text input and money field (not drawn as a family in Figma: the
 * search's border, radius and focus, at 36 high). ---- */
.field input:where(:not([type="checkbox"], [type="radio"], .money-input input)), .field select, .field textarea {
  width: 100%; padding: var(--space-2) var(--space-3); border: 1px solid var(--input-border); border-radius: var(--radius-xl);
  background: var(--surface); color: var(--fg); font: inherit;
}
.field input:where(:not([type="checkbox"], [type="radio"], .money-input input)), .field select { height: 36px; }
.field textarea { resize: vertical; min-height: 140px; line-height: 1.5; }
.field input:disabled, .field select:disabled, .field textarea:disabled { background: var(--surface-disabled); color: var(--fg-muted); cursor: not-allowed; }
.money-input {
  display: flex; align-items: center; height: 36px; padding-left: var(--space-3);
  border: 1px solid var(--input-border); border-radius: var(--radius-xl); background: var(--surface); color: var(--fg-muted); font-family: var(--font-mono);
}
.money-input input, .field .money-input input {
  width: 100%; height: 100%; padding: 0 var(--space-2) 0 var(--space-1); border: 0; outline: 0; box-shadow: none; background: none;
  color: var(--fg); font: 400 13px var(--font-mono); font-variant-numeric: tabular-nums;
}

/* ---- Switch, 42:11868: 32x18 track, 14px thumb 2px in; on is the brand
 * track with a light thumb. Off (not in Figma): sunken track, control
 * border, muted thumb. The thumb slides 14px in 150 ms (not in Figma). ---- */
.switch {
  appearance: none; flex: none; position: relative; box-sizing: border-box; width: 32px; height: 18px; margin: 0;
  border: 1px solid var(--border-control); border-radius: var(--radius-pill); background: var(--surface-sunken); cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease;
}
.switch::after {
  content: ""; position: absolute; top: 1px; left: 1px; width: 14px; height: 14px; border-radius: 50%;
  background: var(--fg-muted); transition: transform .15s ease, background-color .15s ease;
}
.switch:checked { background: var(--control-on); border-color: var(--control-on); }
.switch:checked::after { transform: translateX(14px); background: var(--control-thumb-on); }
.switch-danger:checked { background: var(--danger-fg); border-color: var(--danger-fg); }
.switch:focus-visible, .switch.is-focus { outline: 2px solid var(--focus); outline-offset: 2px; }
.switch:disabled { cursor: not-allowed; opacity: .55; }

/* ---- Radio, 1:7217 (18), 1:9385 (16), 1:12319 (14): a 1px ring, picked is
 * the brand ring with a centred dot (8 at 18; 7 and 6, proposed, below). ---- */
input.radio, .choice input[type="radio"] {
  --radio-size: 18px; --radio-dot: 4px;
  appearance: none; flex: none; box-sizing: border-box; width: var(--radio-size); height: var(--radio-size); margin: 0;
  border: 1px solid var(--control-border); border-radius: 50%; background: var(--surface); cursor: pointer;
}
input.radio-m { --radio-size: 16px; --radio-dot: 3.5px; }
input.radio-s { --radio-size: 14px; --radio-dot: 3px; }
input.radio:checked, .choice input[type="radio"]:checked {
  border-color: var(--control-on);
  background: radial-gradient(circle, var(--control-on) var(--radio-dot), var(--surface) calc(var(--radio-dot) + .5px));
}
.choice input[type="radio"] { margin-top: 1px; }

/* ---- Checkbox (proposed, not in Figma): 16, radius 4; checked is ink with
 * a mint check (the primary button's pairing), brand with a dark check in
 * dark; indeterminate draws a bar. ---- */
input.checkbox, .choice input[type="checkbox"] {
  appearance: none; flex: none; box-sizing: border-box; width: 16px; height: 16px; margin: 0;
  border: 1px solid var(--control-border); border-radius: var(--radius-sm); background: var(--surface) no-repeat center / 16px; cursor: pointer;
}
.choice input[type="checkbox"] { margin-top: 2px; }
input.checkbox:checked, .choice input[type="checkbox"]:checked { border-color: var(--check-fill); background-color: var(--check-fill); background-image: var(--check-mark); }
input.checkbox:indeterminate, .choice input[type="checkbox"]:indeterminate { border-color: var(--check-fill); background-color: var(--check-fill); background-image: var(--check-bar); }
input.radio:focus-visible, input.checkbox:focus-visible, .choice input:focus-visible, input.radio.is-focus, input.checkbox.is-focus { outline: 2px solid var(--focus); outline-offset: 2px; }
input.radio:disabled, input.checkbox:disabled, .choice input:disabled { cursor: not-allowed; opacity: .55; }
input.radio[aria-invalid="true"], input.checkbox[aria-invalid="true"] { border-color: var(--danger-fg); }

/* ---- OTP code digits, 1:8654 / 1:8664: six 55x64 boxes, radius 8, Plex
 * Mono SemiBold 28. The active box has a 2px brand border (drawn inset, so
 * the box keeps its size), the tint, and a brand digit (--primary-text:
 * Figma's --brand is 2.4:1 on the tint). Gap 8 is proposed. ---- */
.otp { display: inline-flex; gap: var(--space-2); }
.otp-digit {
  box-sizing: border-box; width: 55px; height: 64px; margin: 0; padding: 0; text-align: center;
  border: 1px solid var(--border-control); border-radius: var(--radius); background: var(--surface); color: var(--fg-strong);
  font: 600 28px var(--font-mono); caret-color: var(--focus);
}
.otp-digit:focus, .otp-digit.is-focus { outline: 0; border-color: var(--focus); box-shadow: inset 0 0 0 1px var(--focus); background: var(--select-tint); color: var(--primary-text); }
.otp-digit:disabled { background: var(--surface-disabled); color: var(--fg-muted); cursor: not-allowed; }
.otp[aria-invalid="true"] .otp-digit { border-color: var(--danger-fg); }

/* ---- Calendar, 20:6218 (issue 3512; ds/calendar.ts): a month of days, Monday first.
 * Month nav: 24x24 secondary icon buttons and Inter SemiBold 13. Weekdays Plex
 * Mono 10. Days 36 tall, Inter 12. Weekdays and the days outside the month are
 * --fg-muted, not Figma's gray 400 (2.5:1 on white, under WCAG AA's 4.5:1); the range's
 * days joined in --range-fill (square, across the week); its ends brand, white
 * SemiBold (--primary-fg), radius 6; today a 1px brand outline, radius 6. ---- */
.ui-cal { display: grid; gap: var(--space-2); }
.ui-cal-nav { display: flex; align-items: center; justify-content: space-between; }
.ui-cal-title { margin: 0; font: 600 13px/16px var(--font-sans); color: var(--fg-strong); }
.ui-cal-grid { width: 100%; border-collapse: separate; border-spacing: 0 var(--space-1); table-layout: fixed; margin: calc(-1 * var(--space-1)) 0; }
.ui-cal-grid th { height: 24px; padding: 0; font: 400 10px/12px var(--font-mono); color: var(--fg-muted); text-align: center; }
.ui-cal-grid td { padding: 0; }
.ui-cal-grid td.is-between { background: var(--range-fill); }
.ui-cal-day {
  display: flex; align-items: center; justify-content: center; width: 100%; height: 36px; padding: 0;
  border: 1px solid transparent; border-radius: 6px; background: transparent; color: var(--fg-strong);
  font: 400 12px/15px var(--font-sans); cursor: pointer;
}
.ui-cal-day:hover:not(:disabled):not(.is-end) { background: var(--surface-sunken); }
.ui-cal-day:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.ui-cal-day.is-outside { color: var(--fg-muted); }
.ui-cal-day.is-today { border-color: var(--brand); }
.ui-cal-day.is-end { background: var(--brand); border-color: var(--brand); color: var(--primary-fg); font-weight: 600; }
.ui-cal-day:disabled { color: var(--fg-subtle); opacity: .5; cursor: not-allowed; }

@media (prefers-reduced-motion: reduce) {
  .switch, .switch::after, .dd-chevron, .dd-button, .select select, .segmented button, .ui-segment { transition: none; }
}
