/* ==================================================================================================
   Controls — owner: design-system agent

   Buttons   .btn + --primary | --secondary (default) | --tinted | --ghost | --plain | --danger
             | --danger-soft · sizes --sm | --lg · --icon (square/circle) · --block
             Loading: .is-loading, or automatically while htmx is busy (.htmx-request on the button,
             or a submit button inside a form.htmx-request). Use <span class="btn__label"> for text
             that may be long (it truncates).
   Inputs    .input (input/select/textarea) · --sm | --lg · textarea[data-autosize]
             .input-icon wrapper (leading icon) · .search-field (iOS search bar)
   Choice    native checkbox & radio are styled globally · .switch (iOS) · .check-circle (task done)
             .segmented (+ __item, sliding thumb positioned by app.js) · --sm | --block
   Forms     .field (__label, __help, __error) — rendered by components/field.html · .form-grid
             .form-actions · .form-errors
   Pickers   .swatches/.swatch (palette radio group) · .icon-picker/.icon-option
   ================================================================================================== */

:root {
  --input-bg: light-dark(#ffffff, rgb(118 118 128 / 0.14));
  --input-border: light-dark(rgb(0 0 0 / 0.14), rgb(255 255 255 / 0.1));
  --input-border-hover: light-dark(rgb(0 0 0 / 0.24), rgb(255 255 255 / 0.2));
  --control-border: light-dark(rgb(0 0 0 / 0.26), rgb(255 255 255 / 0.3));
  --segmented-bg: light-dark(rgb(118 118 128 / 0.12), rgb(118 118 128 / 0.24));
  --segmented-thumb: light-dark(#ffffff, #636366);
  --select-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238e8e93' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7 15 5 5 5-5'/%3E%3Cpath d='m7 9 5-5 5 5'/%3E%3C/svg%3E");
}

/* -- Buttons ------------------------------------------------------------------------------------- */
.btn {
  --btn-h: var(--control-h);
  --btn-px: 15px;
  --btn-bg: var(--fill-2);
  --btn-bg-hover: var(--fill-3);
  --btn-fg: var(--text);
  --btn-border: transparent;
  --btn-shadow: none;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 0;
  height: var(--btn-h);
  padding: 0 var(--btn-px);
  border: 1px solid var(--btn-border);
  border-radius: var(--radius-full);
  background: var(--btn-bg);
  box-shadow: var(--btn-shadow);
  color: var(--btn-fg);
  font-size: var(--fs-md);
  font-weight: var(--fw-medium);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  vertical-align: middle;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  transition:
    background-color var(--dur-1) ease,
    border-color var(--dur-1) ease,
    color var(--dur-1) ease,
    box-shadow var(--dur-1) ease,
    opacity var(--dur-1) ease,
    transform var(--dur-1) var(--ease-out);
}
.btn:hover {
  background: var(--btn-bg-hover);
}
.btn:active {
  transform: scale(0.97);
}
.btn > .icon {
  margin-inline: -2px;
}
.btn__label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.btn .kbd {
  margin-right: -6px;
}
.btn--primary {
  --btn-bg: var(--accent);
  --btn-bg-hover: var(--accent-hover);
  --btn-fg: var(--text-on-accent);
  --btn-shadow: 0 1px 2px color-mix(in srgb, var(--accent) 28%, transparent), inset 0 1px 0 rgb(255 255 255 / 0.14);
}
.btn--primary:active {
  background: var(--accent-pressed);
}
.btn--primary .kbd {
  border-color: rgb(255 255 255 / 0.25);
  background: rgb(255 255 255 / 0.16);
  color: inherit;
  box-shadow: none;
}
.btn--secondary {
  --btn-bg: var(--fill-2);
}
.btn--tinted {
  --btn-bg: var(--accent-soft);
  --btn-bg-hover: color-mix(in srgb, var(--accent) 18%, transparent);
  --btn-fg: var(--accent-ink);
}
.btn--ghost {
  --btn-bg: transparent;
  --btn-bg-hover: var(--fill-1);
  --btn-border: var(--line-strong);
}
.btn--plain {
  --btn-bg: transparent;
  --btn-bg-hover: var(--fill-1);
  --btn-fg: var(--text-2);
}
.btn--plain:hover {
  color: var(--text);
}
.btn--plain[aria-haspopup][aria-expanded="true"],
.btn--plain[aria-pressed="true"] {
  background: var(--fill-2);
  color: var(--text);
}
.btn--danger {
  --btn-bg: var(--danger);
  --btn-bg-hover: color-mix(in srgb, var(--danger) 88%, black);
  --btn-fg: #ffffff;
  --btn-shadow: 0 1px 2px color-mix(in srgb, var(--danger) 28%, transparent);
}
.btn--danger-soft {
  --btn-bg: color-mix(in srgb, var(--danger) 12%, transparent);
  --btn-bg-hover: color-mix(in srgb, var(--danger) 18%, transparent);
  --btn-fg: var(--danger-ink);
}
.btn--sm {
  --btn-h: var(--control-h-sm);
  --btn-px: 11px;
  gap: 5px;
  font-size: var(--fs-sm);
}
.btn--lg {
  --btn-h: var(--control-h-lg);
  --btn-px: 22px;
  gap: 8px;
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
}
.btn--icon {
  width: var(--btn-h);
  padding: 0;
}
.btn--icon > .icon {
  margin: 0;
}
.btn--block {
  display: flex;
  width: 100%;
}
.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.42;
  cursor: not-allowed;
  transform: none;
}
a.btn[aria-disabled="true"] {
  pointer-events: none;
}

/* Loading: text/icons fade out and a ring spinner appears (after a short delay to avoid flicker). */
.btn.is-loading,
.btn.htmx-request,
form.htmx-request .btn[type="submit"]:not(.no-loading) {
  color: transparent;
  pointer-events: none;
  transition-delay: 0s, 0s, 120ms, 0s, 0s, 0s;
}
.btn.is-loading::after,
.btn.htmx-request::after,
form.htmx-request .btn[type="submit"]:not(.no-loading)::after {
  content: "";
  position: absolute;
  inset: 0;
  width: 16px;
  height: 16px;
  margin: auto;
  border-radius: 50%;
  background: conic-gradient(from 90deg, transparent 10%, var(--btn-fg));
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2.2px), #000 calc(100% - 2px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2.2px), #000 calc(100% - 2px));
  animation:
    fade-in 160ms ease 120ms both,
    spin 0.75s linear infinite;
}

/* Icon-only buttons need an accessible name: aria-label (or a .sr-only span). */

/* -- Inputs -------------------------------------------------------------------------------------- */
.input {
  --input-h: var(--control-h);
  display: block;
  width: 100%;
  min-width: 0;
  height: var(--input-h);
  padding: 0 12px;
  border: 1px solid var(--input-border);
  border-radius: var(--radius-md);
  background-color: var(--input-bg);
  color: var(--text);
  font-size: var(--fs-md);
  line-height: 1.4;
  appearance: none;
  -webkit-appearance: none;
  transition:
    border-color var(--dur-1) ease,
    box-shadow var(--dur-2) ease,
    background-color var(--dur-1) ease;
}
.input::placeholder {
  color: var(--text-3);
  opacity: 1;
}
.input:hover {
  border-color: var(--input-border-hover);
}
.input:focus,
.input:focus-visible {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3.5px var(--focus-ring);
}
.input[aria-invalid="true"],
.field--invalid .input {
  border-color: var(--danger);
}
.input[aria-invalid="true"]:focus,
.field--invalid .input:focus {
  box-shadow: 0 0 0 3.5px color-mix(in srgb, var(--danger) 30%, transparent);
}
.input:disabled,
.input[readonly] {
  background-color: var(--fill-1);
  color: var(--text-2);
}
.input:disabled {
  cursor: not-allowed;
  opacity: 0.7;
}
.input--sm {
  --input-h: var(--control-h-sm);
  padding-inline: 10px;
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
}
.input--lg {
  --input-h: var(--control-h-lg);
  padding-inline: 14px;
  border-radius: 12px;
  font-size: var(--fs-lg);
}
textarea.input {
  height: auto;
  min-height: 92px;
  padding: 9px 12px;
  line-height: 1.5;
  resize: vertical;
}
textarea.input[data-autosize] {
  min-height: 64px;
  max-height: 60vh;
  resize: none;
  field-sizing: content;
}
select.input {
  padding-right: 34px;
  background-image: var(--select-chevron);
  background-position: right 10px center;
  background-repeat: no-repeat;
  background-size: 15px;
  text-overflow: ellipsis;
  cursor: pointer;
}
select.input[multiple],
select.input[size] {
  height: auto;
  padding: 6px;
  background-image: none;
}
input[type="date"].input,
input[type="time"].input,
input[type="datetime-local"].input {
  min-width: 0;
}
input[type="file"].input {
  height: auto;
  padding: 7px;
  font-size: var(--fs-sm);
}
input[type="file"].input::file-selector-button {
  margin-right: 10px;
  padding: 6px 12px;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--fill-2);
  color: var(--text);
  font: inherit;
  font-weight: var(--fw-medium);
  cursor: pointer;
}
/* Prevent iOS zoom-on-focus: inputs must be ≥ 16px on touch screens. */
@media (pointer: coarse), (max-width: 767px) {
  .input,
  .input--sm {
    font-size: 16px;
  }
}

/* Leading-icon wrapper: <div class="input-icon">{% icon "search" %}<input class="input"></div> */
.input-icon {
  position: relative;
  display: block;
  min-width: 0;
}
.input-icon > .icon {
  position: absolute;
  top: 50%;
  left: 11px;
  color: var(--text-3);
  pointer-events: none;
  translate: 0 -50%;
}
.input-icon > .input {
  padding-left: 34px;
}
.input-icon > .kbd,
.input-icon > .input-icon__trail {
  position: absolute;
  top: 50%;
  right: 8px;
  translate: 0 -50%;
}
.input-icon:has(> .input--lg) > .icon {
  left: 14px;
}
.input-icon > .input--lg {
  padding-left: 40px;
}
.input-icon:has(> .input-icon__trail) > .input {
  padding-right: 44px;
}
.input-icon > .input-icon__trail.btn--icon {
  right: 6px;
}

/* Search field (iOS search bar look) */
.search-field {
  position: relative;
  display: block;
  min-width: 0;
}
.search-field > .icon {
  position: absolute;
  top: 50%;
  left: 11px;
  color: var(--text-3);
  pointer-events: none;
  translate: 0 -50%;
}
.search-field > .input {
  padding-left: 34px;
  border-color: transparent;
  border-radius: var(--radius-full);
  background-color: var(--fill-1);
}
.search-field > .input:hover {
  background-color: var(--fill-2);
}
.search-field > .input:focus {
  border-color: var(--accent);
  background-color: var(--input-bg);
}
.search-field > .input::-webkit-search-cancel-button {
  -webkit-appearance: none;
}
.search-field > .kbd {
  position: absolute;
  top: 50%;
  right: 10px;
  translate: 0 -50%;
  pointer-events: none;
}

/* -- Checkbox & radio (styled globally; low specificity so components can override) -------------- */
:where(input[type="checkbox"]:not(.switch)),
:where(input[type="radio"]) {
  position: relative;
  display: inline-grid;
  flex-shrink: 0;
  place-content: center;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 1.5px solid var(--control-border);
  border-radius: 5px;
  background: var(--input-bg);
  vertical-align: middle;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  transition:
    background-color var(--dur-1) ease,
    border-color var(--dur-1) ease,
    box-shadow var(--dur-1) ease;
}
:where(input[type="radio"]) {
  border-radius: 50%;
}
:where(input[type="checkbox"]:not(.switch))::before {
  content: "";
  width: 12px;
  height: 12px;
  background: #ffffff;
  -webkit-mask: var(--check-mask) center / contain no-repeat;
  mask: var(--check-mask) center / contain no-repeat;
  transform: scale(0);
  transition: transform var(--dur-2) var(--ease-spring);
}
:where(input[type="radio"])::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #ffffff;
  transform: scale(0);
  transition: transform var(--dur-2) var(--ease-spring);
}
:where(input[type="checkbox"]:not(.switch)):checked,
:where(input[type="checkbox"]:not(.switch)):indeterminate,
:where(input[type="radio"]):checked {
  border-color: var(--accent);
  background: var(--accent);
}
:where(input[type="checkbox"]:not(.switch)):checked::before,
:where(input[type="radio"]):checked::before {
  transform: scale(1);
}
:where(input[type="checkbox"]:not(.switch)):indeterminate::before {
  width: 9px;
  height: 2px;
  border-radius: 1px;
  -webkit-mask: none;
  mask: none;
  transform: scale(1);
}
:where(input[type="checkbox"], input[type="radio"]):hover:not(:checked, :disabled) {
  border-color: color-mix(in srgb, var(--accent) 60%, var(--control-border));
}
:where(input[type="checkbox"], input[type="radio"]):disabled {
  cursor: not-allowed;
  opacity: 0.5;
}
:where(input[type="checkbox"], input[type="radio"]):focus-visible {
  outline: none;
  box-shadow: 0 0 0 3.5px var(--focus-ring);
}

/* -- iOS switch: <input type="checkbox" class="switch" role="switch"> --------------------------- */
.switch {
  position: relative;
  flex-shrink: 0;
  width: 44px;
  height: 26px;
  margin: 0;
  border: 0;
  border-radius: var(--radius-full);
  background: var(--fill-3);
  vertical-align: middle;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  transition: background-color var(--dur-2) ease;
}
.switch::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-full);
  background: #ffffff;
  box-shadow:
    0 2px 5px rgb(0 0 0 / 0.18),
    0 0 0 0.5px rgb(0 0 0 / 0.05);
  transition:
    transform var(--dur-3) var(--ease-spring),
    width var(--dur-2) var(--ease-out);
}
.switch:checked {
  background: var(--c-green);
}
.switch:checked::before {
  transform: translateX(18px);
}
.switch:active::before {
  width: 27px;
}
.switch:checked:active::before {
  transform: translateX(13px);
}
.switch:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}
.switch:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3.5px var(--focus-ring);
}

/* -- Task completion check-circle -----------------------------------------------------------------
   Markup (components/check_circle.html):
     <button class="check-circle" role="checkbox" aria-checked="false" aria-label="…">
       <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="m7.5 12.4 3 3 6-6.4" pathLength="1"/></svg>
     </button>
   or <label class="check-circle"><input type="checkbox" class="sr-only">svg…</label>.
   app.js adds .is-animating for the "pop" when it becomes checked. */
.check-circle {
  --size: 20px;
  --check-color: var(--success);
  position: relative;
  display: inline-grid;
  flex-shrink: 0;
  place-items: center;
  width: var(--size);
  height: var(--size);
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--control-border);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.check-circle::after {
  content: "";
  position: absolute;
  inset: -10px;
}
.check-circle svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}
.check-circle circle {
  fill: transparent;
  stroke: currentColor;
  stroke-width: 1.7;
  transition:
    fill var(--dur-2) ease,
    stroke var(--dur-2) ease;
}
.check-circle path {
  fill: none;
  stroke: var(--check-color);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  opacity: 0;
  transition:
    stroke-dashoffset var(--dur-3) var(--ease-out),
    opacity var(--dur-1) ease,
    stroke var(--dur-1) ease;
}
@media (hover: hover) {
  .check-circle:hover {
    color: var(--check-color);
  }
  .check-circle:hover path {
    stroke-dashoffset: 0;
    opacity: 0.55;
  }
}
.check-circle[aria-checked="true"],
.check-circle:has(input:checked) {
  color: var(--check-color);
}
.check-circle[aria-checked="true"] circle,
.check-circle:has(input:checked) circle {
  fill: var(--check-color);
}
.check-circle[aria-checked="true"] path,
.check-circle:has(input:checked) path {
  stroke: #ffffff;
  stroke-dashoffset: 0;
  opacity: 1;
}
.check-circle:focus-visible,
.check-circle:has(input:focus-visible) {
  outline: none;
  box-shadow: 0 0 0 3.5px var(--focus-ring);
}
.check-circle--lg {
  --size: 24px;
}
@media (pointer: coarse) {
  .check-circle {
    --size: 22px;
  }
}
@media (prefers-reduced-motion: no-preference) {
  .check-circle.is-animating {
    animation: pop 360ms var(--ease-spring);
  }
}

/* -- Segmented control ----------------------------------------------------------------------------
   <div class="segmented" role="radiogroup" aria-label="…">
     <label class="segmented__item"><input type="radio" name="x" value="a" checked><span>A</span></label> …
   </div>
   Also works with buttons ([aria-pressed]/[aria-selected]) or links (.is-active/[aria-current]).
   app.js adds the sliding .segmented__thumb and keeps it in place. */
.segmented {
  position: relative;
  display: inline-flex;
  align-items: stretch;
  max-width: 100%;
  padding: 2px;
  border-radius: var(--radius-full);
  background: var(--segmented-bg);
  isolation: isolate;
  vertical-align: middle;
}
.segmented__item {
  position: relative;
  z-index: 1;
  display: inline-flex;
  flex: 0 1 auto;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 0;
  height: calc(var(--control-h) - 4px);
  padding: 0 14px;
  border: 0;
  border-radius: var(--radius-full);
  background: none;
  color: var(--text-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--dur-2) ease;
}
.segmented__item > span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.segmented__item:hover {
  color: var(--text);
}
.segmented__item input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  border: 0;
  border-radius: inherit;
  background: none;
  opacity: 0;
  cursor: pointer;
}
.segmented__item:has(input:checked),
.segmented__item[aria-pressed="true"],
.segmented__item[aria-selected="true"],
.segmented__item[aria-current="page"],
.segmented__item.is-active {
  color: var(--text);
}
.segmented__item:has(input:focus-visible) {
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.segmented__thumb {
  position: absolute;
  z-index: 0;
  top: 2px;
  bottom: 2px;
  left: 0;
  width: var(--thumb-w, 0px);
  border-radius: var(--radius-full);
  background: var(--segmented-thumb);
  box-shadow:
    0 1px 3px rgb(0 0 0 / 0.12),
    0 0 0 0.5px rgb(0 0 0 / 0.04);
  transform: translateX(var(--thumb-x, 0px));
  transition:
    transform var(--dur-3) var(--ease-spring),
    width var(--dur-3) var(--ease-spring);
}
.segmented.no-anim .segmented__thumb {
  transition: none;
}
/* Without JS (or before it runs) the active item paints its own background. */
.segmented:not(.is-ready) :is(.segmented__item:has(input:checked), .segmented__item[aria-pressed="true"], .segmented__item[aria-selected="true"], .segmented__item[aria-current="page"], .segmented__item.is-active) {
  background: var(--segmented-thumb);
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.12);
}
.segmented--sm .segmented__item {
  height: calc(var(--control-h-sm) - 4px);
  padding: 0 10px;
  font-size: var(--fs-xs);
}
.segmented--block {
  display: flex;
  width: 100%;
}
.segmented--block .segmented__item {
  flex: 1 1 0;
}

/* -- Form fields ----------------------------------------------------------------------------------- */
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.field__label {
  display: flex;
  align-items: baseline;
  gap: 6px;
  color: var(--text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}
.field__optional {
  color: var(--text-3);
  font-weight: var(--fw-regular);
}
.field__help {
  color: var(--text-2);
  font-size: var(--fs-sm);
  line-height: 1.4;
}
.field__error {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  color: var(--danger-ink);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  line-height: 1.4;
}
.field__error .icon {
  margin-top: 1px;
}
@media (prefers-reduced-motion: no-preference) {
  .field__error {
    animation: fade-up var(--dur-3) var(--ease-out) both;
  }
}
.field__check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  cursor: pointer;
}
.field__check > input {
  margin-top: 1px;
}
.field__check-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  font-weight: var(--fw-medium);
}
.field__check-text .field__help {
  font-weight: var(--fw-regular);
}
.field--switch .field__check {
  align-items: center;
  justify-content: space-between;
}
.field--switch .field__check > input {
  order: 2;
  margin-top: 0;
}
/* Django renders RadioSelect / CheckboxSelectMultiple as nested divs with labels. */
.field__choices > div {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.field__choices label {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}
.form-grid {
  display: grid;
  gap: var(--space-4);
}
.form-grid--2 {
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
}
.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
}
.form-errors {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--danger) 10%, transparent);
  color: var(--danger-ink);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
}
.form-errors ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* -- Color swatches (palette radio group) -------------------------------------------------------- */
.swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
  padding: 0;
  border: 0;
}
.swatch {
  position: relative;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  cursor: pointer;
}
.swatch input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  opacity: 0;
  cursor: pointer;
}
.swatch__dot {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: linear-gradient(150deg, color-mix(in oklab, var(--tone) 80%, white), var(--tone));
  box-shadow: inset 0 0 0 0.5px rgb(0 0 0 / 0.12);
  pointer-events: none;
  transition:
    transform var(--dur-2) var(--ease-spring),
    box-shadow var(--dur-2) ease;
}
.swatch__dot::after {
  content: "";
  width: 12px;
  height: 12px;
  background: var(--tone-on);
  -webkit-mask: var(--check-mask) center / contain no-repeat;
  mask: var(--check-mask) center / contain no-repeat;
  transform: scale(0);
  transition: transform var(--dur-2) var(--ease-spring);
}
.swatch:hover .swatch__dot {
  transform: scale(1.1);
}
.swatch:has(input:checked) .swatch__dot {
  box-shadow:
    0 0 0 2px var(--surface-elevated),
    0 0 0 4px var(--tone);
}
.swatch:has(input:checked) .swatch__dot::after {
  transform: scale(1);
}
.swatch:has(input:focus-visible) {
  box-shadow: 0 0 0 3px var(--focus-ring);
}

/* -- Icon picker --------------------------------------------------------------------------------- */
.icon-picker {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(40px, 1fr));
  gap: 4px;
  margin: 0;
  padding: 0;
  border: 0;
}
.icon-option {
  position: relative;
  display: grid;
  place-items: center;
  height: 40px;
  border-radius: var(--radius-md);
  color: var(--text-2);
  cursor: pointer;
  transition:
    background-color var(--dur-1) ease,
    color var(--dur-1) ease,
    box-shadow var(--dur-1) ease;
}
.icon-option input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  border: 0;
  border-radius: inherit;
  background: none;
  opacity: 0;
  cursor: pointer;
}
.icon-option .icon {
  pointer-events: none;
}
.icon-option:hover {
  background: var(--fill-1);
  color: var(--text);
}
.icon-option:has(input:checked) {
  background: var(--tone-soft);
  color: var(--tone-ink);
  box-shadow: inset 0 0 0 1.5px var(--tone);
}
.icon-option:has(input:focus-visible) {
  box-shadow: 0 0 0 3px var(--focus-ring);
}
