/* ═══════════════════════════════════════════════════════════════════════════
   Shared drag-and-drop feedback
   Reflects the DnD state contract from `@42/core` (shared/dnd.ts) onto visuals,
   shared by every component of this type (kanban, sortable-table, …).

   State attributes (set by the controllers):
     [data-dragging]    the element being dragged
     [data-drop-target] a drop target the drag is currently over
     [data-drop-edge]   where the item will land: top | bottom | left | right
     [data-dropped]     briefly set right after a successful drop

   Everything is driven by `--c42-dnd-*` custom properties and wrapped in
   `:where()` (zero specificity) so consumers and per-component themes can
   override it effortlessly — a single real selector (e.g. a component theme or
   a `[data-c42-kanban-item]` rule) always wins. Add new draggable element
   types to the selector lists below.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Grab affordance — cursor over draggable elements / handles */
  --c42-dnd-grab-cursor: grab;
  --c42-dnd-grabbing-cursor: grabbing;

  /* Dragged source (the element left in place while it is being moved) */
  --c42-dnd-drag-opacity: 0.5;
  /* Optional dashed "gap/placeholder" outline on the source. Transparent by
     default so the source just fades; set a color to show a placeholder. */
  --c42-dnd-drag-outline-color: transparent;
  --c42-dnd-drag-outline-width: 1px;

  /* Active drop target */
  --c42-dnd-drop-bg: color-mix(in srgb, var(--c42-color-accent, #4f46e5) 8%, transparent);
  --c42-dnd-drop-ring: var(--c42-color-accent, #4f46e5);
  --c42-dnd-drop-ring-width: 2px;

  /* Closest-edge indicator — the line marking where the item will land */
  --c42-dnd-edge-size: 2px;
  --c42-dnd-edge-color: var(--c42-color-accent, #4f46e5);
  --c42-dnd-edge-radius: var(--c42-dnd-edge-size);
  /* Soft glow around the edge line; set to `none` to disable. */
  --c42-dnd-edge-glow: 0 0 0 1px
    color-mix(in srgb, var(--c42-dnd-edge-color) 35%, transparent);

  --c42-dnd-transition: var(--c42-transition, 200ms ease);
}

/* ─── Grab affordance ─────────────────────────────────────────────────────
   Items dragged directly, plus the dedicated reorder handles. */
:where(
  [data-c42-kanban-item],
  [data-c42-sortable-row-handle],
  [data-c42-sortable-col-handle]
) {
  cursor: var(--c42-dnd-grab-cursor);
  touch-action: none;
}

/* ─── Dragged source ──────────────────────────────────────────────────────
   Element types that participate in drag-and-drop. */
:where(
  [data-c42-kanban-item],
  [data-c42-sortable-row],
  [data-c42-sortable-col]
)[data-dragging] {
  cursor: var(--c42-dnd-grabbing-cursor);
  opacity: var(--c42-dnd-drag-opacity);
  outline: var(--c42-dnd-drag-outline-width) dashed var(--c42-dnd-drag-outline-color);
  outline-offset: calc(-1 * var(--c42-dnd-drag-outline-width));
}

/* ─── Active drop target (item, list/column, row, header cell) ────────────
   `outline` follows `border-radius` in modern browsers, so rounded targets
   get a rounded ring for free. The transition softens enter/leave. */
:where(
  [data-c42-kanban-item],
  [data-c42-kanban-list],
  [data-c42-sortable-row],
  [data-c42-sortable-col]
)[data-drop-target] {
  background: var(--c42-dnd-drop-bg);
  outline: var(--c42-dnd-drop-ring-width) solid var(--c42-dnd-drop-ring);
  outline-offset: calc(-1 * var(--c42-dnd-drop-ring-width));
  transition:
    background var(--c42-dnd-transition),
    outline-color var(--c42-dnd-transition);
}

/* ─── Closest-edge indicator — a line on the side where the item will drop ── */
:where(
  [data-c42-kanban-item],
  [data-c42-sortable-row],
  [data-c42-sortable-col]
)[data-drop-edge] {
  position: relative;
}

:where(
  [data-c42-kanban-item],
  [data-c42-sortable-row],
  [data-c42-sortable-col]
)[data-drop-edge]::after {
  content: '';
  position: absolute;
  background: var(--c42-dnd-edge-color);
  border-radius: var(--c42-dnd-edge-radius);
  box-shadow: var(--c42-dnd-edge-glow);
  pointer-events: none;
  z-index: 1;
}

:where([data-drop-edge='top'])::after {
  inset-inline: 0;
  inset-block-start: calc(var(--c42-dnd-edge-size) / -2);
  block-size: var(--c42-dnd-edge-size);
}

:where([data-drop-edge='bottom'])::after {
  inset-inline: 0;
  inset-block-end: calc(var(--c42-dnd-edge-size) / -2);
  block-size: var(--c42-dnd-edge-size);
}

:where([data-drop-edge='left'])::after {
  inset-block: 0;
  inset-inline-start: calc(var(--c42-dnd-edge-size) / -2);
  inline-size: var(--c42-dnd-edge-size);
}

:where([data-drop-edge='right'])::after {
  inset-block: 0;
  inset-inline-end: calc(var(--c42-dnd-edge-size) / -2);
  inline-size: var(--c42-dnd-edge-size);
}

/* ─── Settle feedback right after dropping ────────────────────────────────── */
@keyframes c42-dnd-dropped {
  from {
    background: var(--c42-dnd-drop-bg);
  }
  to {
    background: transparent;
  }
}

:where(
  [data-c42-kanban-item],
  [data-c42-sortable-row],
  [data-c42-sortable-col]
)[data-dropped] {
  animation: c42-dnd-dropped var(--c42-dnd-transition);
}

/* ─── Respect reduced-motion: drop all DnD transitions/animations ─────────── */
@media (prefers-reduced-motion: reduce) {
  :where(
    [data-c42-kanban-item],
    [data-c42-kanban-list],
    [data-c42-sortable-row],
    [data-c42-sortable-col]
  )[data-drop-target] {
    transition: none;
  }

  :where([data-dropped])::after,
  :where([data-dropped]) {
    animation: none;
  }
}
