@layer components {
  .sortable {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;

    /* Horizontal orientation */
    &[data-orientation="horizontal"] {
      flex-direction: row;
      flex-wrap: wrap;
    }
  }

  .sortable-item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background-color: var(--card);
    font-size: 0.875rem;
    color: var(--foreground);
    cursor: grab;
    transition: box-shadow 150ms ease, opacity 150ms ease, border-color 150ms ease;
    user-select: none;

    &:active { cursor: grabbing; }

    /* Keyboard focus (roving tabindex) */
    &:focus-visible {
      outline: 2px solid var(--ring);
      outline-offset: 2px;
    }

    /* Active descendant highlight (keyboard navigation) */
    &[data-active] {
      border-color: var(--ring);
      background-color: var(--accent);
      color: var(--accent-foreground);
    }

    /* Drag in progress */
    &[data-dragging] {
      opacity: 0.5;
      box-shadow: var(--shadow-md);
      border-style: dashed;
    }

    /* Drop target indicator */
    &[data-over="before"] {
      border-top: 2px solid var(--primary);
    }
    &[data-over="after"] {
      border-bottom: 2px solid var(--primary);
    }

    /* Horizontal drop indicators */
    .sortable[data-orientation="horizontal"] &[data-over="before"] {
      border-top: 1px solid var(--border);
      border-inline-start: 2px solid var(--primary);
    }
    .sortable[data-orientation="horizontal"] &[data-over="after"] {
      border-bottom: 1px solid var(--border);
      border-inline-end: 2px solid var(--primary);
    }

    /* Disabled */
    &[aria-disabled="true"] {
      opacity: 0.5;
      cursor: not-allowed;
      pointer-events: none;
    }
  }

  .sortable-handle {
    color: var(--muted-foreground);
    cursor: grab;
    font-size: 1rem;
    line-height: 1;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;

    &:active { cursor: grabbing; }
    & svg { width: 1rem; height: 1rem; }
  }

  /* -- Move buttons: reorder by tap / click --------------------
     Native drag-and-drop mostly never starts on touch screens, so a list
     people must reorder by tapping carries Up / Down buttons per item.
     They sit at the item's end; Up/Down disable at the list's edges. */
  .sortable-moves {
    display: inline-flex;
    gap: 0.25rem;
    flex-shrink: 0;
    margin-inline-start: auto;
  }

  .sortable-move {
    display: inline-grid;
    place-items: center;
    box-sizing: border-box;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--background);
    color: var(--foreground);
    cursor: pointer;
    transition: background-color 150ms, color 150ms;

    & svg { width: 1rem; height: 1rem; }
    &:hover { background: var(--accent); color: var(--accent-foreground); }
    &:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }

    /* legible but inert, like every disabled control (no opacity fade) */
    &:disabled {
      background: var(--muted);
      color: var(--muted-foreground);
      cursor: not-allowed;
    }

    /* a finger needs a bigger target than a pointer (WCAG 2.5.5: 44px) */
    @media (pointer: coarse) {
      width: 2.75rem;
      height: 2.75rem;
    }
  }

  /* -- Connected lists (data-group) ------------------------------
     A list that items can be dragged INTO needs a body even when empty:
     an empty grouped list is a dashed drop zone (its data-empty text, if
     any, says what goes there), and a drag over the list's own box - gap,
     padding, empty zone - marks it as "drop at the end". */
  .sortable[data-group] {
    min-height: 2.75rem;

    &:not(:has(.sortable-item)) {
      align-items: center;
      justify-content: center;
      border: 1px dashed var(--border);
      border-radius: var(--radius-md);
      color: var(--muted-foreground);
      font-size: 0.875rem;

      &::before { content: attr(data-empty); }
    }
  }

  .sortable[data-over="end"] {
    outline: 2px dashed var(--primary);
    outline-offset: 2px;
    border-radius: var(--radius-md);
  }

  /* Live region for screen reader announcements */
  .sortable-live {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }

  @media (prefers-reduced-motion: reduce) {
    .sortable-item, .sortable-move { transition: none; }
  }

  @media (prefers-contrast: more) {
    .sortable-item {
      border-width: 2px;
      &[data-active] { outline: 2px solid LinkText; }
      &[data-over="before"] { border-top-width: 3px; }
      &[data-over="after"] { border-bottom-width: 3px; }
    }
  }

  @media (forced-colors: active) {
    .sortable-item {
      border-color: ButtonBorder;
      color: ButtonText;
      background-color: ButtonFace;
      &[data-active] { border-color: Highlight; color: HighlightText; }
      &[data-dragging] { border-color: GrayText; }
      &[data-over="before"] { border-top-color: Highlight; }
      &[data-over="after"] { border-bottom-color: Highlight; }
      &[aria-disabled="true"] { color: GrayText; border-color: GrayText; }
    }
    .sortable-handle { color: GrayText; }
    .sortable-move {
      border-color: ButtonText;
      color: ButtonText;
      &:disabled { border-color: GrayText; color: GrayText; }
    }
    .sortable[data-over="end"] { outline-color: Highlight; }
  }
  /* -- Density ----------------------------------------------------
     data-density on the .sortable root scales the list gap and the item
     padding. comfortable == the unsized default. */
  .sortable:where([data-density="compact"]) {
    gap: 0.125rem;
    & .sortable-item { padding: 0.375rem 0.5rem; }
  }
  .sortable:where([data-density="comfortable"]) {
    gap: 0.25rem;
    & .sortable-item { padding: 0.5rem 0.75rem; }
  }
  .sortable:where([data-density="spacious"]) {
    gap: 0.375rem;
    & .sortable-item { padding: 0.625rem 1rem; }
  }

}
