/* ─────────────────────────────────────────────────────────────────────────
   MOTION, FOCUS AND PENDING STATE

   Where "consumer-grade smooth" is actually delivered. Inconsistent
   transition timing is the single biggest tell of a hand-built UI, and the
   fix is not more animation — it is the same two easings and three durations
   everywhere. specs/design-system.md §5 phase 5.
   ───────────────────────────────────────────────────────────────────────── */

@layer components {
  /* ── Focus ─────────────────────────────────────────────────────────
     An accessibility win and a polish win at once. :focus-visible only
     shows for keyboard users, so pointer users never see a ring they did
     not ask for. --focus-ring is accent-derived, so it re-colours per app.
     :where() keeps specificity at zero, so any component can override it
     without an escalation fight. */
  :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: var(--focus-ring-width) solid var(--focus-ring);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
  }

  /* A focus ring should never be clipped away by an overflow container. */
  :where(a, button):focus-visible { position: relative; z-index: 1; }

  /* ── HTMX pending state ────────────────────────────────────────────
     HTMX adds .htmx-request to the element issuing a request (or its
     hx-indicator target) for the life of that request. Fading the element
     it is about to replace is what makes a swap read as "loading" rather
     than "frozen". */
  .htmx-request {
    opacity: 0.55;
    transition: opacity var(--dur-fast) var(--ease-out);
  }

  .htmx-request :where(button, input, select, textarea) {
    pointer-events: none;
  }

  /* Opt-in skeleton for a region that renders empty while it loads. */
  .skeleton {
    background: linear-gradient(
      90deg,
      var(--color-surface-2) 25%,
      var(--color-border-light) 37%,
      var(--color-surface-2) 63%
    );
    background-size: 400% 100%;
    border-radius: var(--radius-sm);
    color: transparent;
    animation: skeleton-sweep 1.2s var(--ease-in-out) infinite;
  }

  @keyframes skeleton-sweep {
    from { background-position: 100% 50%; }
    to   { background-position: 0 50%; }
  }

  /* ── Container queries ─────────────────────────────────────────────
     A card in a narrow column should lay out for its column, not for the
     viewport — a sidebar card at 1600px wide is still a narrow card. */
  .card { container-type: inline-size; }

  @container (max-width: 22rem) {
    .card__header,
    .card__footer {
      flex-wrap: wrap;
      gap: var(--space-1);
    }

    .card__body { padding: var(--space-3); }
  }

  /* ── Reduced motion ────────────────────────────────────────────────
     Honour the OS setting. Transitions collapse to instant rather than
     being removed, so nothing depending on transitionend breaks. */
  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      animation-duration: 1ms;
      animation-iteration-count: 1;
      transition-duration: 1ms;
      scroll-behavior: auto;
    }
  }
}

/* ── View Transitions on HTMX swaps ──────────────────────────────────
   Enabled globally in crm/js/htmx_config.js. Baseline newly available
   (2025-10) and degrades to an instant swap where unsupported, so it costs
   nothing on older browsers. Kept out of a layer: ::view-transition
   pseudo-elements live on the document root, not in the page's cascade. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: var(--dur-fast);
  animation-timing-function: var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none;
  }
}
