/* ==========================================================================
   El Camino DT — LOS CONTROLES DEL JUEGO
   --------------------------------------------------------------------------
   Lo que dibuja `controles.js`: la lista desplegable y el globo de ayuda, en
   la paleta del juego y no en la del sistema operativo.

   Cero tokens nuevos. Las dos superficies flotantes usan exactamente los
   mismos que el diálogo de `preguntar()` —`--bg-panel`, `--line`, `--r-md`,
   la sombra de elevación— porque son la misma clase de cosa: algo que se abre
   por encima de la pantalla y tiene que pertenecerle.
   ========================================================================== */

/* --------------------------------------------------------------------------
   EL DESPLEGABLE
   -------------------------------------------------------------------------- */

.desp { position: relative; display: block; min-width: 0; }

/* El `<select>` de verdad sigue ahí y sigue mandando; lo que no hace es
   ocuparse de dibujarse. No se usa `display: none` porque un control oculto
   así deja de reportar su valor a algunas ayudas técnicas: se lo saca de la
   vista y del orden de tabulación, que es lo mismo sin ese efecto. */
.desp__nativo {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  pointer-events: none;
}

/* El botón hereda la clase del `<select>` al que reemplaza —`.entreno__sel`,
   `.mesa__lista`— así que el tamaño, el borde y el fondo ya se los pone la
   pantalla. Acá va sólo lo que el botón necesita por ser un botón. */
.desp__btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  width: 100%;
  text-align: left;
  cursor: pointer;
}

.desp__valor {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
}

/* El texto sigue recortando con puntos suspensivos, pero ahora recorta ÉL y no
   la caja: con el icono adentro, un `text-overflow` en el padre se comía la
   bandera antes que la última letra del nombre. */
.desp__valor-txt {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.desp__flecha { display: flex; flex: none; color: var(--icon-quiet); }
.desp__btn[aria-expanded='true'] .desp__flecha { color: var(--accent); transform: rotate(180deg); }
.desp__flecha { transition: transform var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease); }

.desp__btn[aria-expanded='true'] { border-color: var(--accent); color: var(--text-primary); }
.desp__btn[disabled] { opacity: 0.45; cursor: not-allowed; }

/* --------------------------------------------------------------------------
   EL PANEL
   --------------------------------------------------------------------------
   Fijo y colgado del `<body>`: es lo que le permite salir de la tabla del
   plantel, que es un contenedor con scroll y lo recortaría. El `z-index` está
   por encima del diálogo de la mesa de negociación, porque ahí adentro hay una
   lista de ciento cincuenta y tres clubes que tiene que poder abrirse.
   -------------------------------------------------------------------------- */

.desp__panel {
  position: fixed;
  z-index: var(--z-desplegable);
  display: flex;
  flex-direction: column;
  min-width: 11rem;
  max-width: min(26rem, calc(100vw - 16px));
  overflow: hidden;
  background: var(--bg-panel);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  box-shadow: 0 18px 40px rgb(0 0 0 / 55%), 0 2px 6px rgb(0 0 0 / 40%);
  animation: desp-entra var(--dur-fast) var(--ease-entrada);
  transform-origin: var(--desp-ancla, top left);
}

/* --------------------------------------------------------------------------
   CÓMO NACE Y CÓMO SE VA
   --------------------------------------------------------------------------
   Era un fundido de cuatro píxeles hacia abajo, siempre el mismo, y el panel
   se BORRABA del DOM al cerrar. Dos cosas mal en el control que más se toca
   del juego —hay un desplegable mejorado en casi todas las pantallas—:

   1. APARECÍA AL LADO DEL BOTÓN EN VEZ DE SALIR DE ÉL. Sin ancla, un panel de
      cuatrocientos píxeles de alto crece desde su propio centro, así que el
      borde de arriba —el que está pegado al botón que acabás de apretar— es
      justo el que más se mueve. Con el ancla en la esquina que toca el botón,
      el panel se despliega DESDE el control: el borde pegado se queda quieto y
      lo que crece es el resto. Es la misma idea del punto 1 de
      `movimiento.css` —lo que no cambió, no se repinta— a escala de un panel.

   2. Y LA DIRECCIÓN ES UN DATO, que también es una regla que el sistema ya
      tenía y que este control no usaba. `colocarPanel()` YA decide de qué lado
      del botón hay sitio y abre para arriba o para abajo; lo único que faltaba
      era que el gesto se enterara. Un panel que se abre hacia arriba y entra
      bajando contradice con el movimiento lo que hace con la posición.

      EL EJEMPLAR QUE CUBRE LA RAMA DE ARRIBA es `pretemporada.html`, y queda
      anotado porque no es fácil de encontrar a mano: el desplegable del plantel
      —el que uno abre por reflejo para probar esto— está en la parte alta de la
      pantalla y cae SIEMPRE del lado `abajo`, así que medirlo ahí deja la mitad
      del gesto sin ejercitar y en verde. El de la pretemporada está lo bastante
      abajo como para no tener sitio: da `data-lado="arriba"` y el ancla en
      `0px 170,7px`, o sea el borde de abajo del panel. Es la regla de la muestra
      que se elige por dónde puede romperse y no por dónde es cómodo mirar.

   3. Y NO SE IBA. Con `.remove()` el panel desaparecía entre dos fotogramas
      mientras la lista más larga del juego —ciento cincuenta y tres clubes—
      llegaba con calma. La salida es la de entrada al revés y más corta, con
      `--ease-salida`: lo que se va no frena. Ver `movimiento.css`, punto 4.

   El 0,96 de la entrada es más que el 0,98 de los modales a propósito: un
   modal ya está en el centro de la pantalla y sólo se apoya, un panel viene
   de un botón de 26px de alto y tiene que leerse como que salió de ahí. El de
   la salida vuelve a 0,98 — irse se cuenta más bajo que llegar.
   -------------------------------------------------------------------------- */

.desp__panel[data-lado='arriba'] {
  --desp-ancla: bottom left;
  --desp-viaje: 4px;
}

@keyframes desp-entra {
  from { opacity: 0; transform: translateY(var(--desp-viaje, -4px)) scale(0.96); }
  to   { opacity: 1; transform: none; }
}

/* Se va: `controles.js` pone la marca, espera lo que dura esto y recién ahí lo
   saca del DOM. Deja de recibir clics en el mismo instante en que empieza a
   irse — un panel que se está yendo ya no es un control. */
.desp__panel[data-yendose] {
  animation: desp-sale var(--dur-fast) var(--ease-salida) forwards;
  pointer-events: none;
}

@keyframes desp-sale {
  to { opacity: 0; transform: translateY(var(--desp-viaje, -4px)) scale(0.98); }
}

@media (prefers-reduced-motion: reduce) {
  .desp__panel { animation: none; }
  .desp__flecha { transition: none; }
  /* La salida NO se apaga con `animation: none`, se acorta: la regla global de
     `app.css` la deja en 1ms, y hace falta que corra porque su `forwards` es lo
     que mantiene el panel invisible hasta que el guion lo saca. Con `none`, el
     panel se quedaría a la vista los 140ms de la espera. */
  .desp__panel[data-yendose] { animation-duration: 1ms; }
}

.desp__buscar { padding: var(--sp-2); border-bottom: 1px solid var(--line-hairline); }

.desp__campo {
  width: 100%;
  padding: var(--sp-2) var(--sp-3);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--text-primary);
  font: inherit;
  font-size: var(--fs-xs);
}

.desp__campo:focus-visible { outline: var(--focus-ring); outline-offset: 1px; }

.desp__lista {
  list-style: none;
  margin: 0;
  padding: var(--sp-1);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--ink-700) transparent;
}

.desp__lista:focus-visible { outline: none; }

.desp__op {
  display: grid;
  grid-template-columns: 1rem minmax(0, 1fr);
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  font-size: var(--fs-xs);
  color: var(--text-secondary);
  cursor: pointer;
}

/* La opción bajo el cursor o bajo las flechas es UNA sola y se pinta igual con
   los dos: si el ratón resaltara distinto que el teclado, una lista de ciento
   cincuenta y tres clubes tendría dos selecciones a la vista al mismo tiempo. */
.desp__op[data-activa] { background: var(--bg-selected); color: var(--text-primary); }
.desp__op[aria-selected='true'] { color: var(--text-primary); font-weight: 600; }
.desp__op[aria-disabled='true'] { color: var(--text-disabled); cursor: not-allowed; }

.desp__tilde { color: var(--accent); font-size: var(--fs-2xs); text-align: center; }
.desp__texto {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  overflow: hidden;
  white-space: nowrap;
}

/* El icono de una opción —una bandera, un escudo—. Lleva FILO y no plata: una
   bandera no desaparece por dentro, que tiene colores, sino por el borde, donde
   una franja oscura toca el canto del rectángulo. Es la misma regla del
   sistema, y sobre la bandera de Japón no se ve, que es lo correcto: ahí el
   canto lo dibuja la bandera. */
.desp__icono {
  flex: none;
  border-radius: var(--r-hair);
  box-shadow: inset 0 0 0 1px rgb(255 255 255 / 0.28);
}

.desp__grupo {
  padding: var(--sp-3) var(--sp-3) var(--sp-1);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-muted);
}

.desp__nada { padding: var(--sp-4) var(--sp-3); font-size: var(--fs-xs); color: var(--text-muted); }

/* La lista larga de la mesa merece más ancho que un control de tabla. */
.desp--ancho .desp__panel { min-width: 18rem; }

/* --------------------------------------------------------------------------
   EL GLOBO DE AYUDA
   --------------------------------------------------------------------------
   Aparece sin retardo, a diferencia del globo del sistema. El retardo del
   sistema existe para no molestar a quien pasa el ratón por encima de camino a
   otra cosa; acá los `title` están en cifras y en pastillas que se miran a
   propósito, y medio segundo de espera sobre un dato es medio segundo de duda.
   -------------------------------------------------------------------------- */

.globo {
  position: fixed;
  z-index: var(--z-globo);
  max-width: 22rem;
  padding: var(--sp-2) var(--sp-3);
  background: var(--ink-950);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  box-shadow: 0 10px 24px rgb(0 0 0 / 50%);
  font-size: var(--fs-2xs);
  line-height: var(--lh-snug);
  color: var(--text-secondary);
  pointer-events: none;
  animation: desp-entra var(--dur-fast) var(--ease);
}

@media (prefers-reduced-motion: reduce) {
  .globo { animation: none; }
}

/* --------------------------------------------------------------------------
   4. DÓNDE SE BUSCA
   --------------------------------------------------------------------------
   El mando de `donde.js`: país y división. Vive en esta hoja y no en la del
   mercado porque lo usan DOS pantallas —el Mercado de pases y el Buscador— y
   la segunda no carga `mercado.css`; y porque es lo que este archivo es, un
   control del juego.

   Los dos desplegables van pegados entre sí y separados del resto: país y
   división son UNA decisión leída de izquierda a derecha —«España, la
   segunda»— y con un hueco en el medio se leen como dos filtros sueltos que
   podrían no hablar del mismo sitio.

   El `<select>` es nativo por lo mismo que en el entrenamiento y en la mesa:
   trae su teclado y su lista larga, y este archivo le pone encima el panel del
   juego —con buscador, porque son diecinueve países—.
   -------------------------------------------------------------------------- */

.donde { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.donde[hidden] { display: none; }

.donde__sel {
  max-width: 12rem;
  padding: var(--sp-1) var(--sp-3);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--fs-xs);
  cursor: pointer;
}

.donde__sel:hover { border-color: var(--line-strong); color: var(--text-primary); }
.donde__sel:focus-visible { outline: var(--focus-ring); outline-offset: 1px; }
.donde__sel:disabled { opacity: 0.45; cursor: not-allowed; }

/* ==========================================================================
   EL DIAL
   --------------------------------------------------------------------------
   La barra que se agarra entera. El `<input type=range>` sigue ahí —invisible,
   estirado a todo el ancho y a treinta píxeles de alto— y encima se pinta la
   pista: el navegador se ocupa del arrastre, del teclado y de lo que anuncia, y
   esta hoja sólo dibuja. Ver `mejorarRango()` en `controles.js`.

   TRES COSAS QUE LO SEPARAN DE UNA BARRA DE PROGRESO, y las tres hicieron falta
   porque la primera versión se leía justo como eso —un bloque de color con un
   borde recto— y no como algo que se pueda mover:

     · LA PÍLDORA. Pista y relleno con las puntas redondeadas. Un rectángulo con
       esquinas vivas es una barra que se llena sola; una píldora es un mando.
     · EL TIRADOR. Una barrita clara al final del relleno. No hace falta para
       arrastrar —se arrastra desde cualquier punto— pero es lo que dice DÓNDE
       ESTÁS y que eso se puede mover. Sin él, el borde entre lleno y vacío es
       un límite, no una posición.
     · EL AIRE ALREDEDOR. Los rótulos de referencia se fueron de la pista al pie:
       encima quedaban tapados por el relleno en cuanto el valor los pasaba.

   Por qué no el pulgar del sistema: mide veinte píxeles sobre una línea de
   cuatro, y para mover el valor hay que agarrar ESE punto. Acá la superficie de
   agarre es el control entero.
   ========================================================================== */

.dial { position: relative; display: grid; gap: var(--sp-2); }

.dial__pista {
  position: relative;
  isolation: isolate;
  height: 14px;
  border-radius: 999px;
  background: var(--ink-850);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 4%);
  transition: background var(--dur-fast) var(--ease);
}
.dial:hover .dial__pista { background: var(--ink-800); }

/* EL RELLENO SE MUEVE SUAVE, Y ESE ES EL PUNTO.
   --------------------------------------------------------------------------
   La primera versión no tenía transición ninguna, con el argumento de que
   arrastrando tiene que ir pegado al dedo. Es cierto y no alcanza: sin nada, un
   clic en el otro extremo de la pista teletransporta la barra y el control se
   siente duro, de tabla de datos y no de mando.

   Noventa milisegundos con salida exponencial es el punto donde las dos cosas
   conviven: arrastrando, la barra llega tan rápido que el retraso no se
   percibe —lo que sí se percibe es que el borde deja de saltar píxel a píxel—;
   y al apretar en un punto lejano, recorre el camino en vez de aparecer ahí.

   Más que eso se siente elástico, que en un control de precisión se lee como
   lentitud. Se probaron 200 y la barra «perseguía» al dedo. */
.dial__lleno {
  width: var(--llenado, 0%);
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent-dim), var(--accent-strong));
  transition:
    width 90ms var(--ease-entrada),
    background var(--dur-fast) var(--ease);
}

/* El brillo del borde de ataque. Es lo único decorativo del control y hace un
   trabajo: sin él, el final del relleno es un corte recto contra la pista y el
   conjunto se lee como una barra de progreso llena hasta ahí. Con el halo, el
   borde es una POSICIÓN. */
.dial__lleno::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--llenado, 0%);
  width: 26px;
  margin-left: -26px;
  border-radius: 999px;
  background: linear-gradient(90deg, transparent, rgb(255 255 255 / 22%));
  transition: left 90ms var(--ease-entrada);
  pointer-events: none;
}

/* EL TIRADOR. Va donde termina el relleno y se agranda al pasar por encima: es
   la única parte del control que se mueve sola con el puntero, y ese movimiento
   es lo que anuncia que el conjunto se puede mover. */
.dial__tirador {
  position: absolute;
  top: 50%;
  left: var(--llenado, 0%);
  width: 6px;
  height: 22px;
  margin-left: -3px;
  border-radius: 999px;
  background: var(--ink-100);
  box-shadow: 0 1px 3px rgb(0 0 0 / 55%);
  transform: translateY(-50%);
  /* El tirador viaja con la misma curva y la misma duración que el relleno: si
     fueran distintas, en cada movimiento se vería al tirador separarse del
     borde de lo lleno y volver. */
  transition:
    left 90ms var(--ease-entrada),
    height var(--dur-fast) var(--ease),
    width var(--dur-fast) var(--ease),
    box-shadow var(--dur-fast) var(--ease);
  pointer-events: none;
}
.dial:hover .dial__tirador { width: 8px; height: 26px; margin-left: -4px; }

/* El tono lo pone quien usa el control, con `data-r` en el `<input>`: la barra
   de una negociación se pinta de la respuesta y la de unos días no se pinta de
   nada. Es el mismo vocabulario de la franja del veredicto, y arrastrando vale
   más que ella porque el ojo está en la barra. */
.dial[data-r='si'] .dial__lleno    { background: linear-gradient(90deg, var(--verde-700), var(--verde-500)); }
.dial[data-r='quiza'] .dial__lleno { background: linear-gradient(90deg, var(--amber-500), var(--amber-300)); }
.dial[data-r='no'] .dial__lleno    { background: linear-gradient(90deg, var(--clay-500), var(--clay-300)); }

/* La referencia: un tick fino sobre la pista y su rótulo abajo. Lo que NO se
   dibuja nunca es el techo de lo que aceptan — esa frontera no se marca en
   ninguna negociación de este juego. */
.dial__tick {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 2px;
  margin-left: -1px;
  border-radius: 999px;
  background: var(--ink-500);
  pointer-events: none;
}

/* EL `<input>` INVISIBLE, ENCIMA DE TODO. Cubre la pista y algo más para que el
   arrastre nativo funcione en cualquier punto sin obligar a apuntar a catorce
   píxeles. `opacity: 0` y no `visibility` ni `display`: tiene que seguir
   recibiendo el puntero y el foco. */
.dial__nativo {
  position: absolute;
  top: -8px;
  left: 0;
  width: 100%;
  height: 30px;
  margin: 0;
  padding: 0;
  opacity: 0;
  cursor: ew-resize;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
}
.dial__nativo::-webkit-slider-thumb { -webkit-appearance: none; width: 30px; height: 30px; }
.dial__nativo::-moz-range-thumb { width: 30px; height: 30px; border: 0; }
.dial__nativo:disabled { cursor: default; }
.dial:has(.dial__nativo:disabled) { opacity: 0.45; }
.dial:has(.dial__nativo:disabled) .dial__tirador { display: none; }

/* El foco se ve en el tirador y no en una caja alrededor de todo: es el punto
   que el teclado mueve. */
.dial:has(.dial__nativo:focus-visible) .dial__tirador {
  width: 8px;
  height: 26px;
  margin-left: -4px;
  box-shadow: 0 0 0 2px var(--accent), 0 1px 3px rgb(0 0 0 / 55%);
}

.dial__pie {
  position: relative;
  display: flex;
  justify-content: space-between;
  min-height: 14px;
  font-size: var(--fs-2xs);
  font-variant-numeric: tabular-nums;
  color: var(--text-disabled);
}
.dial__tope { position: relative; z-index: 1; }

/* LA MARCA BAJA UN RENGLÓN CUANDO HAY MARCA, y no siempre.
   Estaban las tres cosas en la misma línea —el mínimo a la izquierda, el máximo
   a la derecha y la referencia flotando donde cae su valor— y funciona mientras
   la referencia caiga en el medio. «Lo normal» de la pretemporada cae en el 22 %
   del recorrido, así que en una ventana de 1280 el rótulo aterrizaba encima del
   mínimo y se leía «10 díaslo normal». El `z-index` del tope no lo arreglaba:
   sólo decidía cuál de los dos textos tapaba al otro.

   El `:has()` es para no cobrarle los catorce píxeles a los diales sin
   referencia, que son la mayoría y no tienen con qué chocar. */
.dial__pie:has(.dial__marca) { min-height: 32px; align-items: flex-start; }
.dial__marca {
  position: absolute;
  /* 18 y no 15: la caja del tope mide dieciocho de alto por su interlineado,
     así que a quince los dos rectángulos todavía se solapaban dos píxeles. */
  top: 18px;
  transform: translateX(-50%);
  white-space: nowrap;
  font-weight: 600;
  color: var(--text-muted);
}
/* Y en los bordes no se sale de la pista: pegada al 0 % o al 100 %, el
   `translateX(-50%)` se lleva media palabra fuera del control. */
.dial__marca[style*='left: 0%'],
.dial__marca[style*='left: 100%'] { transform: none; }
.dial__marca[style*='left: 100%'] { translate: -100%; }
