/* ═══════════════════════════════════════════════════════════════════════════════
   ▓ COMPONENTE · Botón descarga ⇄ espera (morph) — GEMELO VANILLA ▓
   v0.1 · 2026-09-05. Ficha: `design-system/COMPONENTE_BOTON_DESCARGA_MORPH.md`.
   Kit React hermano: `design-system/catalogo-cd/components/BotonDescargaMorph.jsx`.
   Handoff: `plans/design_handoff_boton_morph/Boton-descarga-morph.html`.

   REQUISITOS DEL ANFITRIÓN — los tres, o se ve mal en silencio:
     1. Los tokens del canon (`design-system/colors_and_type.css`).
     2. `componentes/button/button.css` — la pieza que este compuesto MONTA. Esta hoja
        no vuelve a declarar ni el fondo, ni el hover, ni el foco, ni el tamaño, ni la
        forma: todo eso es del `Button` (`data-icon-only`). Lo único que hay aquí es lo
        que el morph añade — el host del ícono y el bloqueo de puntero mientras trabaja.
     3. Un reinicio con `box-sizing: border-box`.

   ⛔ QUÉ ES ESTA PIEZA Y QUÉ NO. No es un botón nuevo: es un `Button` `data-icon-only`
   con un ícono que SE DESDOBLA — el trazo de `download` de lucide interpola, curva por
   curva, en el trazo de `loader-circle` de lucide, y de vuelta. No hay dos íconos que se
   crucen (eso sería `.exds-iswap`, ver `COMPONENTE_ICONO.md`): hay un solo trazo con 9
   curvas cúbicas que cambia sus puntos de control. La interpolación NO se puede hacer en
   CSS —no hay forma de animar un atributo `d` de SVG por CSS—, así que vive en
   `boton-descarga-morph.js`; esta hoja sólo aloja el ícono y bloquea el puntero.

   ⛔ EL ANILLO DE LLEGADA NO ES EL SPINNER DEL CATÁLOGO, Y ES DECISIÓN TOMADA
   (Ricardo, 2026-09-05 — opciones «B» y «2» de
   `plans/decisiones/_decision_grosor_anillo_2026-09-05.html`). El `Spinner`
   (`COMPONENTE_SPINNER.md`) es un `<span>` con BORDE de caja: 2px sobre un lienzo de 16,
   sin remates, cuarto transparente de 90°. Este anillo es el ícono `loader-circle` de
   lucide en su lienzo de 24: `stroke-width: 2` (1.33px reales — el mismo peso que
   cualquier ícono lucide de al lado), remates `round`, hueco de 72° (el de
   `loader-circle`, no el cuarto de `Spinner`). Las dos piezas SIGUEN EXISTIENDO por
   separado, cada una con su propia razón: el anillo del morph pesa lo que pesa el ícono
   porque NACE de un ícono; el `Spinner` no nace de ningún ícono, así que su anillo de
   caja sigue siendo la elección correcta para todo lo que no sea este morph. *Dos piezas
   no divergen cuando cada una tiene una razón distinta: divergen cuando comparten la
   razón y no el valor.* Ver la nota espejo en `COMPONENTE_SPINNER.md`.

   ⛔ SIN `disabled` Y SIN LA PROP `loading` DEL BOTÓN (regla de la ficha). Mientras
   trabaja el botón CONSERVA su color — sólo bloquea el puntero con `[data-busy]`. El
   anillo de `loading` del `Button` (`.exds-btn-spinner`) pinta un círculo AL LADO de la
   etiqueta; aquí no hay etiqueta ni segundo círculo: el anillo ES el ícono.

   ⛔ SIN COMILLAS INVERTIDAS EN ESTA HOJA — no hace falta declarar la regla del kit aquí
   (esta hoja no viaja dentro de una plantilla de JavaScript), pero se respeta el hábito
   para que copiar bloques entre kit y gemelo nunca sea la primera vez que se rompe.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════════════
   ▓ 1 · EL HOST DEL ÍCONO ▓
   Un `<span>` del tamaño exacto del ícono, centrado. El `Button` ya centra su único
   hijo (`display:inline-flex; align-items:center; justify-content:center`); este host
   sólo fija el LIENZO real (16 o 20px según el tamaño del botón, ver README) para que
   el SVG no herede un tamaño arbitrario del navegador.
   ═══════════════════════════════════════════════════════════════════════════════ */
.exds-morph-ic {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  /* El tamaño del lienzo lo fija esta hoja, no un estilo en línea: el marcado pasa
     --exds-morph-size sólo cuando el ícono se aparta del defecto (20 en md, 16 en sm),
     igual que el kit React. Sin esta regla el host quedaba sin medida y el SVG al 100%
     se expandía a 300px (regresión de a5cebf52, 2026-09-08). */
  width: var(--exds-morph-size, 20px);
  height: var(--exds-morph-size, 20px);
}
.exds-btn[data-size="sm"] .exds-morph-ic {
  width: var(--exds-morph-size, 16px);
  height: var(--exds-morph-size, 16px);
}
.exds-morph-ic svg {
  display: block;
}

/* ═══════════════════════════════════════════════════════════════════════════════
   ▓ 2 · EL BOTÓN OCUPADO — SIN `disabled` ▓
   `[data-busy]` es de ESTA pieza, no del `Button`: el catálogo del botón no sabe nada
   de "trabajando en una descarga". Conserva su color (nada de gris) y sólo bloquea el
   puntero — el clic repetido durante el morph no debe re-disparar la descarga.
   ═══════════════════════════════════════════════════════════════════════════════ */
.exds-btn[data-busy] {
  pointer-events: none;
}

/* ⛔ MOVIMIENTO REDUCIDO: la interpolación y el giro se apagan por completo en el JS
   (el `d` salta directo al extremo, sin RAF); aquí sólo se asegura que ninguna
   transición CSS que un uso futuro añadiera a `.exds-morph-ic` anime bajo la
   preferencia. Hoy esta hoja no declara ninguna transición — la interpolación va por
   JS — así que esta regla es una guarda, no una corrección de un defecto medido. */
@media (prefers-reduced-motion: reduce) {
  .exds-morph-ic,
  .exds-morph-ic svg,
  .exds-morph-ic svg * {
    transition: none !important;
    animation: none !important;
  }
}
