/* ═══════════════════════════════════════
   ▓ COMPONENTE · Switch — gemelo vanilla ▓
   v1.0 · 2026-08-23. Ficha: `design-system/COMPONENTE_SWITCH.md`
   Kit: `catalogo-cd/components/Switch.jsx`

   La familia «switch»: **dos piezas** que eligen entre estados mutuamente excluyentes.

     · **Segmented** — 2 a 3 opciones CON ETIQUETA. Pastilla blanca que se desliza sobre una
       pista gris. Elige una VISTA o un FILTRO del mismo dato.
     · **Toggle** — sí o no, booleano puro. Pista ink en encendido.

   ⛔ EL TEST, y es de sí o no: *¿las dos posiciones necesitan nombre?*
   **Sí → Segmented. No → Toggle.** «Mensual / Anual» necesita nombre; «Recibir avisos» no.
   Un Toggle con etiqueta al lado que diga «Mensual» obliga a deducir qué significa apagado.

   ⛔ EL ACTIVO NUNCA ES VERDE NI DE COLOR. La señal del segmentado es la pastilla blanca y la
   tinta que sube de `--fg3` a `--fg1`. Un segmentado elige una vista; no declara un estado
   bueno, y el verde significa «correcto» en todo el resto del sistema.

   ⛔ VARIANTE ÚNICA desde el 2026-08-18: la «primario» (pista redonda + slider ink) la retiró
   Ricardo. No la reintroduzcas.

   PROFUNDIDAD LIGERA: una perilla blanca de 21px sólo puede recibir luz de canto y sombra de
   contacto. Nada de relieves marcados.

   REQUISITOS DEL ANFITRIÓN:
     1. Los tokens del canon (`colors_and_type.css`).
     2. `box-sizing: border-box`.
   ═══════════════════════════════════════ */

/* ── SEGMENTED · la pista ────────────────────────────────────────────────────
   Medidas verificadas contra producción (`.mc-seg` del backoffice), no supuestas.
   GATE-ALLOW: `--radius-md` en el contenedor. El radio sube por anidamiento — aloja botones
   de radio 6, y un contenedor con el mismo radio que su contenido deja esquinas que se tocan. */
.exds-seg {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-0-5, 2px);
  padding: 3px;
  background: var(--color-bg-subtle, #F2F4F6);
  border: 1px solid var(--color-border-subtle, #E5E7EB);
  /* RADIO-ALLOW: 10px con relleno de 3px (la escala pediría 6) · el radio sube por
     anidamiento — aloja botones de radio 6 (`.exds-seg-btn`), y un contenedor con el
     mismo radio que su contenido deja esquinas que se tocan (ver GATE-ALLOW arriba). */
  border-radius: var(--radius-md, 10px);
  opacity: 1;
}
.exds-seg[data-disabled="true"] { opacity: 0.55; cursor: not-allowed; }

/* ── LA PASTILLA ─────────────────────────────────────────────────────────────
   ⛔ ES UNA SOLA Y POR ESO PUEDE DESLIZARSE. La alternativa obvia —pintar de blanco el botón
   activo— parece más simple y no puede animarse: no hay nada que viaje, sólo un fondo que se
   enciende aquí y se apaga allá. El movimiento es lo que dice «es el MISMO selector en otra
   posición» en vez de «son dos cosas distintas».

   Sus dos números salen de MEDIR el botón activo (`switch.js`), porque dependen del texto de
   cada opción. Viajan en variables sobre la raíz para que haya un solo sitio donde mirar.

   El aro de medio píxel encima de la sombra no es adorno: la sombra sola no despega una
   pastilla blanca de un gris tan claro como `--color-bg-subtle`. */
.exds-seg-knob {
  position: absolute;
  top: 3px;
  bottom: 3px;
  left: var(--seg-knob-x, 3px);
  width: var(--seg-knob-ancho, 0px);
  z-index: 0;
  background: var(--color-surface, #FFFFFF);
  border-radius: var(--radius-sm, 6px);
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(15, 20, 25, 0.12)), 0 0 0 1px rgba(15, 20, 25, .05);
  transition: left var(--motion-base, 250ms) var(--ease-default, cubic-bezier(0.32, 0.72, 0, 1)),
              width var(--motion-base, 250ms) var(--ease-default, cubic-bezier(0.32, 0.72, 0, 1));
}

/* ── LOS BOTONES ─────────────────────────────────────────────────────────────
   Van POR ENCIMA de la pastilla (`z-index: 1`) y sin fondo propio. El estado lo lleva
   `aria-pressed`, que es el atributo que el lector de pantalla ya lee: así no puede existir
   un botón que se vea elegido y no lo esté. */
.exds-seg-btn {
  position: relative;
  z-index: 1;
  border: 0;
  background: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1-5, 6px);
  height: 30px;
  padding: 0 13px;
  font-size: var(--fs-button-sm, 13px);
  border-radius: var(--radius-sm, 6px);
  font-family: var(--font-sans, "Inter", -apple-system, system-ui, sans-serif);
  font-weight: 500;
  color: var(--fg3, #5C6B7A);
  cursor: pointer;
  transition: color var(--motion-fast, 120ms) var(--ease-out, cubic-bezier(0.32, 0.72, 0, 1));
  white-space: nowrap;
}
.exds-seg-btn[aria-pressed="true"] { color: var(--fg1, #0F1419); }
/* El hover sube a la misma tinta que el activo: es la promesa de lo que va a pasar al pulsar.
   `:not(:disabled)` porque insinuar respuesta en un control apagado es peor que no responder. */
.exds-seg-btn:not(:disabled):hover { color: var(--fg1, #0F1419); }
.exds-seg-btn:disabled { cursor: not-allowed; }

/* ── TOGGLE · la etiqueta ────────────────────────────────────────────────────
   Envuelve al control para que pulsar el TEXTO también lo cambie. Es lo que convierte una
   pista de 46×27 en un blanco de tamaño razonable. */
.exds-toggle-label {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  opacity: 1;
}
.exds-toggle-label[data-disabled="true"] { cursor: not-allowed; opacity: 0.55; }

/* ── LA PISTA DEL TOGGLE ─────────────────────────────────────────────────────
   Apagado va `--color-border-control` —el gris de CONTROL, no un gris de texto— y encendido
   el mismo oscuro del botón primario: encendido y acción son la misma tinta en todo el
   sistema, y así no hay que aprender un color nuevo.

   ⛔ Es un `<button role="switch">`, no un checkbox disfrazado. `aria-checked` es lo que lee
   el lector de pantalla Y lo que dispara el CSS: un solo atributo para las dos cosas, así que
   no puede verse encendido y anunciarse apagado. */
.exds-toggle {
  position: relative;
  width: 46px;
  height: 27px;
  padding: 0;
  border: 0;
  flex-shrink: 0;
  border-radius: var(--radius-pill, 999px);
  /* ⛔ VARIABLE LOCAL, no la regla repetida (mismo patrón que `--sl-*` en slider.css):
     `--color-border-control` es un token de BORDE que aquí pinta un FONDO — a propósito
     (Ricardo 2026-07-22, ver ficha). El alias local declara el rol real de esta pieza
     (pista apagada) en vez de heredar el rol de un token pensado para otra propiedad. */
  --sw-pista-off: var(--color-border-control, #8B92A1);
  background: var(--sw-pista-off);
  cursor: pointer;
  transition: background var(--motion-base, 250ms) var(--ease-default, cubic-bezier(0.32, 0.72, 0, 1));
}
.exds-toggle[aria-checked="true"] { background: var(--color-action-ink, #21272C); }
.exds-toggle:disabled { cursor: not-allowed; }

/* La perilla. `--relieve-control` es el token reservado a esta pieza (Ricardo, 2026-07-22) y
   hoy vale `none`: las tres apps llevan planas desde el 19-jul y el canon se corrigió para
   decirlo. No le pongas una sombra a mano — si algún día vuelve el relieve, vuelve por el
   token y en las tres apps a la vez.

   `pointer-events: none` — mismo patrón que el thumb del slider y el punto del checkbox
   (`.exds-slider-thumb`, `.exds-rdo-dot`): es el DIBUJO dentro de `.exds-toggle`, no un
   control aparte. Quien recibe el toque es la pista. Sin esto, `lint_movil` la contaba
   como un control clickable de 21px sin su propia zona de dedo — que no le hace falta,
   porque no es uno. */
.exds-toggle-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 21px;
  height: 21px;
  border-radius: var(--radius-pill, 999px);
  /* ⛔ VARIABLE LOCAL (mismo patrón que arriba): `--fg-inverse` es un token de TEXTO que
     aquí pinta el FONDO de la perilla, blanco sobre la pista. */
  --sw-perilla-bg: var(--fg-inverse, #FFFFFF);
  background: var(--sw-perilla-bg);
  box-shadow: var(--relieve-control, none);
  pointer-events: none;
  transition: translate var(--motion-base, 250ms) var(--ease-default, cubic-bezier(0.32, 0.72, 0, 1));
}

.exds-toggle-txt {
  font-family: var(--font-sans, "Inter", -apple-system, system-ui, sans-serif);
  font-size: var(--fs-body, 14px);
  color: var(--fg1, #0F1419);
}
.exds-toggle-label[data-disabled="true"] .exds-toggle-txt { color: var(--fg4, #B8BDC7); }

/* ── FOCO ────────────────────────────────────────────────────────────────────
   Anillo, no borde — y aquí sí, al revés que en un campo de texto: estos dos son controles
   pulsables (`COMPONENTE_FOCO.md`), y el anillo tiene que verse POR ENCIMA de la pastilla que
   se desliza por debajo. */
.exds-seg-btn:focus-visible { outline: none; box-shadow: inset 0 0 0 1px var(--color-border-focus, #6E7378); }
/* ⛔ EL INTERRUPTOR LLEVA SU LINEA DE FOCO EN BLANCO, Y ES EL UNICO COLOR QUE SIRVE EN SUS DOS
   ESTADOS (Ricardo, 2026-09-04: «si lo subimos»).

   El foco del sistema pasa a dibujarse POR DENTRO de la pieza el 2026-09-04 (ver
   COMPONENTE_FOCO.md). En este control eso lo mete sobre la pista, que cambia de color con el
   estado — y ahi el gris de foco dejaba de verse. Los tres candidatos, medidos:

   | linea            | apagado #8B92A1 | encendido #21272C |
   |------------------|-----------------|-------------------|
   | gris de foco     | 1,53 ⛔         | 3,15 ✓            |
   | tinta de accion  | 4,83 ✓          | 1,00 ⛔ invisible |
   | BLANCO           | 3,12 ✓          | 15,09 ✓           |

   ⚠ Y la propuesta que se le llevo a Ricardo era la TINTA DE ACCION: se midio solo el estado
   apagado, que es el que fallaba, y no el otro. Habria arreglado un estado dejando el contrario
   con la linea encima de su propio color — invisible. *Una medicion que solo mira el caso que
   falla no propone un arreglo: propone mover el fallo.* Se implementa el blanco, que es ademas
   el token que el sistema ya usa para el foco sobre superficie oscura.

   El 3,12 del apagado pasa el piso de 3:1 con poco margen; queda dicho para que nadie lo
   estreche despues sin medirlo. */
.exds-toggle:focus-visible { outline: none; box-shadow: inset 0 0 0 1px var(--color-ink-on-dark, #FFFFFF); }
.exds-seg-btn:focus:not(:focus-visible), .exds-toggle:focus:not(:focus-visible) { outline: none; }

/* ── LA PERILLA · DOBLE REBOTE (Ricardo, 2026-07-26) ─────────────────────────
   Se pasa, vuelve y asienta. Un interruptor que llega derecho se siente barato.

   ⛔ SIN `data-init` NO ANIMA AL CARGAR, y esa guarda es la pieza importante: el estado de
   reposo lo pone el `translate` que cuelga de `aria-checked`. Si animara al montar, una
   pantalla de ajustes con seis interruptores encendidos arrancaría con seis perillas
   corriendo a la vez — que es exactamente lo que nadie pidió ver.

   ⛔ HEREDA EL PAPEL DE LA PESTAÑA (Ricardo, 2026-08-06): 250 ms, no 400. La perilla y la
   barrita de pestañas hacen lo mismo —algo se desliza a su sitio nuevo— y tenían dos
   velocidades. A 250 además se siente más ágil, que es lo que se espera de un interruptor.
   (El respaldo decía 320 ms, de una escala que ya no existe.) */
.exds-toggle-knob { translate: 0 0; }
.exds-toggle[aria-checked="true"] .exds-toggle-knob { translate: 19px 0; }
.exds-toggle[data-init="true"][aria-checked="true"] .exds-toggle-knob { animation: exds-toggle-on var(--motion-base,250ms) var(--ease-emphasis, cubic-bezier(0.34, 1.26, 0.58, 1)) both; }
.exds-toggle[data-init="true"][aria-checked="false"] .exds-toggle-knob { animation: exds-toggle-off var(--motion-base,250ms) var(--ease-emphasis, cubic-bezier(0.34, 1.26, 0.58, 1)) both; }
@keyframes exds-toggle-on { 0%{translate:0 0} 55%{translate:20.5px 0} 80%{translate:18px 0} 100%{translate:19px 0} }
@keyframes exds-toggle-off { 0%{translate:19px 0} 55%{translate:-1.5px 0} 80%{translate:1px 0} 100%{translate:0 0} }

/* ⛔ Apagar el movimiento NO es dejar sin señal, y aquí la señal sobrevive entera: la pastilla
   y la perilla siguen EN SU SITIO —el `translate` estático no es una animación— y la pista
   sigue cambiando de color. Lo que se pierde es el viaje, nunca el estado. */
@media (prefers-reduced-motion: reduce) { .exds-seg-knob, .exds-toggle-knob { transition: none !important; animation: none !important; } }

/* ── ZONA DE TOQUE · SÓLO BAJO @media (pointer: coarse) (recogido de `button.css`, mismo
   receta, nunca reimplementada a mano) ────────────────────────────────────────────────
   TRES controles de esta hoja miden menos de 44px de alto: `.exds-seg-btn` (30), `.exds-toggle`
   (27) y `.exds-toggle-label` (la envuelve, mismo alto que el control que contiene). Con
   ratón el puntero es preciso — la zona invisible sólo se enciende para el dedo.
   ⛔ SIN `pointer-events:none` (la misma lección de `button.css`: esa línea vuelve la capa
   inalcanzable y el toque sigue de largo hasta el fondo). ⛔ EL ANCLAJE SE DECLARA AQUÍ: la
   base de estas piezas no lleva `position:relative`, y sin ancla la capa se mide contra el
   primer antepasado posicionado — la zona de dedo aterrizaría en cualquier sitio. */
@media (pointer: coarse) {
  .exds-seg-btn, .exds-toggle, .exds-toggle-label { position: relative; }
  .exds-seg-btn::after, .exds-toggle::after, .exds-toggle-label::after {
    content: "";
    position: absolute;
    left: 0; right: 0;
    top: 50%;
    transform: translateY(-50%);
    height: 44px;
  }
}
