/* ARCHIVO GENERADO POR scripts/traer-editor.mjs -- NO EDITAR A MANO.
 *
 * Son las cinco hojas del editor, en su orden, envueltas en una capa propia.
 * La capa se declara en app/globals.css (primera linea) para que quede POR DEBAJO del estilo
 * de la web. Sin eso, el reinicio de nucleo.css le borra los margenes a la pagina entera.
 *
 * Si hay que cambiar algo de aca, se cambia en D:\int\int-sampler y se corre: npm run editor
 */

@layer editor {

/* ========================================================================================
   src/estilos/nucleo.css
   ======================================================================================== */

/* ============================================================================
   El núcleo: las fichas de la marca, el reinicio y el foco.

   Acá y en ningún otro lado se decide un color, un tamaño de letra, un redondeo
   o una separación. Todo lo demás usa estas fichas. `tests/estilo.test.js` lo
   hace cumplir: si alguien escribe un color o un tamaño a mano, la prueba falla.

   Los colores NO se eligen acá: son una copia de
   D:\int\int plugins\shared\brand\colors.h, que es la paleta que comparten el
   pack de plugins de audio y el visualizador INT-Halo. Es el mismo sello.

   Si esa paleta cambia allá, se copia acá A MANO. No hay enganche automático
   entre los dos repos, y está bien que no lo haya: son proyectos distintos.
   ========================================================================= */

:root {
  /* --- Paleta base (colors.h, namespace palette) --- */
  --fondo:            #0E0E12;
  --superficie:       #1A1A22;
  --superficie-alta:  #22222C;
  --borde-suave:      #2A2A35;
  --borde-fuerte:     #3A3A47;

  --texto:            #F5F5F7;
  --texto-2:          #A0A0AA;
  --texto-apagado:    #5A5A65;

  /* --- El gris de lo chiquito, y por qué no es el de la paleta ---
     MEDIDO el 2026-08-31. `--texto-apagado` (#5A5A65) da 2,83 de contraste
     contra el fondo, 2,54 contra las cajas y 2,31 contra las cajas claras. El
     mínimo para poder leer es 4,5. Es el ÚNICO color de la paleta que no llega
     —el acento da 9,45— y estaba usado en 26 lugares, todos texto: las notas
     que explican qué hace cada cosa, los rótulos de los deslizadores, la letra
     de cada pad, la regla de tiempo.

     Éste da 5,66 / 5,08 / 4,63: llega en los tres fondos y todavía se
     distingue de --texto-2, así que la jerarquía no se pierde.

     `--texto-apagado` NO se toca y sigue existiendo: es de la paleta de la
     marca, la misma que usan los seis plugins de audio y INT-Halo. Se queda
     para lo que no se lee (el puntito del estado, un botón apagado).

     OJO: el mismo problema está en los plugins y en INT-Halo, que tienen el
     mismo fondo oscuro. Arreglarlo allá obliga a recompilar y republicar, y ahí
     sí hay gente con los plugins puestos. Es decisión de Lucio y está anotado. */
  --texto-3:          #8A8A98;

  --error:            #FF6B6B;
  --aviso:            #FFB84D;
  --ok:               #7DDC8F;

  /* --- El color firma del sampler ---
     DECIDIDO por Lucio el 2026-08-30. Se eligió para no chocar con ninguno de
     los diez plugins del pack (el más cercano es INT-Loop #FF8C42, y por eso
     este va más claro y más amarillo). Cada producto de la casa tiene el suyo:
     los plugins van en cyan #00E5FF y el sello en blanco hueso #E6E6EA.
     Si algún día cambia, se cambia acá y en ningún otro lado. */
  --acento:           #FF9F45;
  --acento-suave:     #FF9F4522;
  --acento-borde:     #FF9F4555;

  /* --- Espaciado. Una sola escala, para que todo caiga en la misma grilla --- */
  --e1: 4px;
  --e2: 8px;
  --e3: 12px;
  --e4: 16px;
  --e5: 24px;
  --e6: 32px;
  --e7: 48px;
  --e8: 64px;

  /* ------------------------------------------------------------ la letra ---
     CINCO tamaños, con nombre por el trabajo que hacen.

     Antes había DIEZ, seis de ellos apretados entre 10,5 y 13 píxeles. Nadie
     los eligió: fueron apareciendo de a uno, cada vez que alguien necesitó algo
     "un poquito más chico". Medio píxel de diferencia no se lee como jerarquía,
     se lee como descuido.

     Si hace falta un sexto, casi nunca el problema es el tamaño: es que ese
     elemento está mal jerarquizado. Por eso son cinco y la prueba lo cuenta. */
  --t-pie:     11px;   /* la nota al pie, el largo del pad, el pie del globito */
  --t-dato:    12px;   /* rótulos, números, fichas, ayudas */
  --t-cuerpo:  14px;   /* lo que se lee y lo que se toca */
  --t-titulo:  18px;   /* el tema que estás editando */
  --t-portada: 26px;   /* el título de la pantalla. Uno por vista, nunca dos */

  /* ----------------------------------------------------------- el redondeo -
     También es una regla, no una elección por elemento: cuanto más grande la
     caja, más redondo el borde. Mezclarlos es lo que hace que una pantalla se
     vea armada de partes que no son de la misma familia. */
  --radio-pastilla: 999px;  /* píldoras: el estado, el riel de avance, los presets */
  --radio-chico:      6px;  /* lo mínimo: código, cajas de texto crudo */
  --radio-control:    8px;  /* lo que se aprieta: teclas, campos, numeritos */
  --radio-pad:       10px;  /* los dieciséis pads */
  --radio-panel:     14px;  /* las cajas grandes: paneles, tarjetas, la onda */

  /* Una sola curva de animación para todo: es lo que hace que se sienta de
     una pieza y no como cinco cosas pegadas. */
  --curva: cubic-bezier(0.22, 0.61, 0.36, 1);
  --rapido: 120ms var(--curva);
  --normal: 220ms var(--curva);
  --lento:  380ms var(--curva);

  --tipo: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --tipo-num: "SF Mono", "Cascadia Mono", Consolas, monospace;

  /* El alto del encabezado. Es una ficha porque el transporte del editor se
     pega justo abajo, y si los dos números no son el mismo, uno tapa al otro. */
  --alto-barra: 56px;

  /* El alto de la onda. Cambia por ancho de pantalla, en `anchos.css`. */
  --onda-alto: 200px;
}

/* Quien pida menos movimiento, que no lo tenga. */
@media (prefers-reduced-motion: reduce) {
  :root { --rapido: 1ms; --normal: 1ms; --lento: 1ms; }
  *, *::before, *::after { animation-duration: 1ms !important; transition-duration: 1ms !important; }
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  /* `min-height`, NO `height`.
     Con `height: 100%` el cuerpo de la página mide exactamente lo que la
     ventana, aunque adentro haya más contenido. Y lo que se pega —la barra de
     arriba y el transporte del editor— se pega DENTRO de su contenedor: cuando
     el contenedor mide 900 y la página 1128, al pasar los 900 la barra se va
     con el scroll y deja de estar.
     Lo encontró la prueba de `tests/extension/pantallas.mjs`, midiendo: la barra
     terminaba en -296, o sea trescientos píxeles arriba del borde de la pantalla. */
  min-height: 100%;
  background: var(--fondo);
  color: var(--texto);
  font-family: var(--tipo);
  font-size: var(--t-cuerpo);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* El foco se ve siempre: se navega con teclado o no se navega. */
:focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: 2px;
  border-radius: var(--radio-control);
}
:focus:not(:focus-visible) { outline: none; }

[hidden] { display: none !important; }

.solo-lectores {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}


/* ========================================================================================
   src/estilos/piezas.css
   ======================================================================================== */

/* ============================================================================
   Las piezas que comparten LAS DOS pantallas: la pestaña y el globito.

   Si algo se usa en un solo lado, no va acá: va en `pantallas.css` (la pestaña),
   `editor.css` (el editor) o `popup.css` (el globito). El globito se abre y se
   cierra cien veces por día; no tiene por qué cargar el estilo de un editor que
   nunca va a mostrar.
   ========================================================================= */

/* ---------------------------------------------------------------- barra ---- */

.barra {
  display: flex;
  align-items: center;
  gap: var(--e3);
  min-height: var(--alto-barra);
  padding: 0 var(--e5);
  border-bottom: 1px solid var(--borde-suave);
  background: var(--fondo);
  position: sticky;
  top: 0;
  z-index: 20;
}

.barra__logo {
  width: 34px;
  color: var(--texto);
  flex-shrink: 0;
}
.barra__logo svg { display: block; width: 100%; height: auto; }

/* El logo YA son las letras "int": es un logotipo, no un símbolo. Al lado va el
   PRODUCTO, no la marca otra vez. Hay una prueba que lo vigila. */
.barra__nombre {
  font-size: var(--t-dato);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--texto-2);
}
.barra__derecha { margin-left: auto; }

/* --------------------------------------------------- estado del ayudante ---- */

.ayudante {
  display: flex;
  align-items: center;
  gap: var(--e2);
  padding: var(--e2) var(--e3);
  border: 1px solid var(--borde-suave);
  border-radius: var(--radio-pastilla);
  background: var(--superficie);
  font-size: var(--t-dato);
  color: var(--texto-2);
  transition: border-color var(--normal), color var(--normal);
}
.ayudante__punto {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--texto-apagado);
  flex-shrink: 0;
  transition: background var(--normal), box-shadow var(--normal);
}
.ayudante[data-estado="listo"]     { color: var(--texto); }
.ayudante[data-estado="listo"] .ayudante__punto {
  background: var(--ok);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 18%, transparent);
}
.ayudante[data-estado="falta"]     { color: var(--aviso); border-color: color-mix(in srgb, var(--aviso) 35%, transparent); }
.ayudante[data-estado="falta"] .ayudante__punto { background: var(--aviso); }
.ayudante[data-estado="buscando"] .ayudante__punto { animation: latir 1.1s ease-in-out infinite; }

@keyframes latir { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }

/* ---------------------------------------------------------------- campos ---- */

.etiqueta {
  display: block;
  font-size: var(--t-dato);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--texto-2);
  margin-bottom: var(--e3);
}

.campo {
  width: 100%;
  padding: var(--e4);
  font-family: var(--tipo);
  font-size: var(--t-cuerpo);
  color: var(--texto);
  background: var(--superficie);
  border: 1px solid var(--borde-suave);
  border-radius: var(--radio-control);
  transition: border-color var(--rapido), background var(--rapido);
}
.campo::placeholder { color: var(--texto-3); }
.campo:hover  { border-color: var(--borde-fuerte); }
.campo:focus  { outline: none; border-color: var(--acento); background: var(--superficie-alta); }
.campo[aria-invalid="true"] { border-color: var(--error); }

/* La pista de abajo del campo: dice qué reconoció, o qué está mal. */
.pista {
  display: flex;
  align-items: center;
  gap: var(--e2);
  min-height: 20px;
  margin-top: var(--e3);
  font-size: var(--t-dato);
  color: var(--texto-3);
  transition: color var(--rapido);
}
/* Vacía no ocupa lugar. Antes reservaba su alto siempre, y abajo de la calidad
   —donde casi nunca dice nada— eso dejaba treinta y dos píxeles de aire muerto
   entre la última tarjeta y el botón principal. El hueco se reserva sólo donde
   el texto aparece y desaparece seguido (el del link), no en todos lados. */
.pista:empty { display: none; }
.pista[data-tono="ok"]    { color: var(--ok); }
.pista[data-tono="error"] { color: var(--error); }

/* ==========================================================================
   LOS BOTONES, EN TRES NIVELES

   Antes había veintisiete rectángulos exactamente iguales: mismo alto, mismo
   fondo, mismo borde, misma letra. Nada distinguía "Reiniciar" —que te borra el
   trabajo— de "440 Hz" —que es un atajo— de "Medir tono y BPM" —que calcula—.
   Cuando todo pesa lo mismo, no hay nada que mirar primero.

     1. `.boton`            la acción de la pantalla. Llena, del color de la casa.
     2. `.tecla`            un interruptor: se prende y se apaga, y se nota cuál.
     3. `.tecla--preset`    un atajo: más chico, redondo, callado.
     4. `.tecla--peligro`   lo que deshace trabajo. Se ve distinto y avisa al pasar.
   ========================================================================== */

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e2);
  min-height: 44px;
  padding: var(--e3) var(--e6);
  font-family: var(--tipo);
  font-size: var(--t-cuerpo);
  font-weight: 600;
  color: var(--fondo);
  background: var(--acento);
  border: none;
  border-radius: var(--radio-control);
  cursor: pointer;
  transition: filter var(--rapido), transform var(--rapido), box-shadow var(--rapido);
}
.boton:hover:not(:disabled)  { filter: brightness(1.08); }
/* Se hunde al apretarlo: es la única señal de que el clic entró. */
.boton:active:not(:disabled) { transform: translateY(1px); filter: brightness(0.96); }
.boton:disabled {
  background: var(--superficie-alta);
  color: var(--texto-3);
  cursor: not-allowed;
}
.boton--ancho { width: 100%; }

.boton--fantasma {
  background: transparent;
  color: var(--texto-2);
  border: 1px solid var(--borde-suave);
  font-weight: 500;
}
.boton--fantasma:hover:not(:disabled) {
  filter: none;
  border-color: var(--borde-fuerte);
  color: var(--texto);
  background: var(--superficie);
}

.tecla {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e2);
  min-width: 40px;
  min-height: 36px;
  padding: 0 var(--e3);
  font-family: var(--tipo);
  font-size: var(--t-dato);
  font-weight: 500;
  color: var(--texto-2);
  background: var(--superficie-alta);
  border: 1px solid var(--borde-suave);
  border-radius: var(--radio-control);
  cursor: pointer;
  transition: color var(--rapido), background var(--rapido),
              border-color var(--rapido), transform var(--rapido);
}
/* El `:not([aria-pressed="true"])` NO sobra, y su falta era un defecto de
   verdad: una tecla encendida tiene el fondo del acento (naranja) con la letra
   del color del fondo (casi negra), y esta regla le ponía la letra CLARA al
   pasarle el mouse por encima. Blanco sobre naranja da 1,87 de contraste — el
   mínimo es 4,5 —, así que el control que estabas usando era justo el que no
   se podía leer, y sólo mientras lo apuntabas.
   Lo encontró `npm run auditar` el 2026-09-02, la primera vez que se corrió:
   el puntero se queda encima después de un clic, así que la auditoría midió
   exactamente lo que ve una persona. `.tecla--principal` ya tenía su parche
   propio dos reglas más abajo; el caso general no. */
.tecla:hover:not(:disabled):not([aria-pressed="true"]) {
  color: var(--texto);
  border-color: var(--borde-fuerte);
}
.tecla[aria-pressed="true"]:hover:not(:disabled) { filter: brightness(1.06); }
.tecla:active:not(:disabled) { transform: translateY(1px); }
.tecla:disabled { opacity: 0.4; cursor: not-allowed; }
.tecla[aria-pressed="true"] {
  color: var(--fondo);
  background: var(--acento);
  border-color: var(--acento);
  font-weight: 600;
}

/* Un atajo, no un estado: más chico, redondo y callado. No compite con los
   interruptores que sí guardan una decisión. */
.tecla--preset {
  min-height: 32px;
  padding: 0 var(--e3);
  border-radius: var(--radio-pastilla);
  background: transparent;
  color: var(--texto-3);
  font-size: var(--t-pie);
  font-variant-numeric: tabular-nums;
}
.tecla--preset:hover:not(:disabled) {
  background: var(--superficie-alta);
  color: var(--texto);
}

/* Lo que deshace trabajo no puede verse igual que lo que lo hace. Va callado
   —para no invitar— y al pasarle por encima avisa de qué color es. */
.tecla--peligro { color: var(--texto-3); background: transparent; }
.tecla--peligro:hover:not(:disabled) {
  color: var(--error);
  border-color: color-mix(in srgb, var(--error) 45%, transparent);
  background: color-mix(in srgb, var(--error) 10%, transparent);
}

.tecla--principal {
  background: var(--acento);
  border-color: var(--acento);
  color: var(--fondo);
  min-width: 48px;
  font-size: var(--t-cuerpo);
}
.tecla--principal:hover:not(:disabled) { filter: brightness(1.08); color: var(--fondo); }

/* ------------------------------------------------------------- carteles ---- */

.cartel {
  padding: var(--e5);
  border: 1px solid var(--borde-suave);
  border-left: 3px solid var(--aviso);
  border-radius: var(--radio-panel);
  background: var(--superficie);
}
.cartel__titulo { font-weight: 600; margin-bottom: var(--e2); }
.cartel p { color: var(--texto-2); font-size: var(--t-dato); }
.cartel p + p { margin-top: var(--e2); }
.cartel code {
  font-family: var(--tipo-num);
  font-size: var(--t-dato);
  padding: 2px 6px;
  background: var(--fondo);
  border: 1px solid var(--borde-suave);
  border-radius: var(--radio-chico);
  color: var(--texto);
}
.cartel__flojo { color: var(--texto-3); font-size: var(--t-dato); }

/* --------------------------------------------------- el detalle escondido -- */

/* Lo que dijo el ayudante, tal cual. Va cerrado: es útil cuando hace falta y
   ruido cuando no. Nadie tiene que leer una salida de programa para entender
   qué pasó — para eso está el motivo escrito arriba, en castellano. */
.detalle {
  font-size: var(--t-dato);
  color: var(--texto-3);
}
.detalle summary {
  cursor: pointer;
  padding: var(--e2) 0;
  user-select: none;
}
.detalle summary:hover { color: var(--texto-2); }
.detalle pre {
  margin-top: var(--e2);
  padding: var(--e3);
  border: 1px solid var(--borde-suave);
  border-radius: var(--radio-chico);
  background: var(--fondo);
  color: var(--texto-2);
  font-family: var(--tipo-num);
  font-size: var(--t-pie);
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 220px;
  overflow: auto;
}


/* ========================================================================================
   src/estilos/pantallas.css
   ======================================================================================== */

/* ============================================================================
   Las pantallas de la pestaña: traer, trabajando, fallo, falta el ayudante.

   EL AIRE SALE DEL CONTENEDOR, NO DE LOS MÁRGENES.

   Antes la separación entre bloques la ponía una regla de "hermano de al lado"
   (`.bloque + .bloque`). Eso funciona hasta que alguien mete un elemento nuevo
   en el medio, o hasta que dos cosas quedan juntas sin ser hermanas — y ahí no
   hay separación y nadie entiende por qué. Pasó en dos lugares, y uno era el
   botón "Cancelar" pegado al riel de carga: justo la pantalla que mirás mientras
   esperás. Ahora el aire lo pone `gap`, que no se puede olvidar.
   ========================================================================= */

.hoja {
  width: 100%;
  max-width: 980px;
  margin: 0 auto;
  padding: var(--e6) var(--e5) var(--e7);
}

/* Cada vista es una columna con su aire. Nada de márgenes sueltos. */
.vista {
  display: flex;
  flex-direction: column;
  gap: var(--e6);
}

/* El título y su bajada son UNA cosa: van juntos y respiran aparte del resto. */
.vista__cabeza {
  display: flex;
  flex-direction: column;
  gap: var(--e2);
}

/* Las pantallas que son una sola columna de texto y un botón no tienen por qué
   estirarse a 980 px: leer un renglón de esa medida cansa. Sólo el editor usa
   todo el ancho, porque el editor lo necesita. */
.vista--angosta {
  width: 100%;
  max-width: 680px;
  margin: 0 auto;
}

.titulo {
  font-size: var(--t-portada);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.15;
}
.bajada {
  color: var(--texto-2);
  font-size: var(--t-cuerpo);
}

.bloque { display: flex; flex-direction: column; }
.bloque--fila { flex-direction: row; flex-wrap: wrap; gap: var(--e3); }

/* ---------------------------------------------------------------- calidad --- */

.calidades {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--e3);
}

.calidad {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--e1);
  padding: var(--e4);
  text-align: left;
  cursor: pointer;
  background: var(--superficie);
  border: 1px solid var(--borde-suave);
  border-radius: var(--radio-panel);
  color: var(--texto-2);
  font-family: var(--tipo);
  transition: border-color var(--rapido), background var(--rapido),
              color var(--rapido), transform var(--rapido);
}
.calidad:hover { border-color: var(--borde-fuerte); background: var(--superficie-alta); }
.calidad:active { transform: translateY(1px); }
.calidad[aria-pressed="true"] {
  border-color: var(--acento);
  background: var(--acento-suave);
  color: var(--texto);
}
.calidad__nombre { font-size: var(--t-cuerpo); font-weight: 600; }
.calidad__dato   { font-family: var(--tipo-num); font-size: var(--t-dato); color: var(--texto-3); }
.calidad[aria-pressed="true"] .calidad__dato { color: var(--acento); }
.calidad__nota   { font-size: var(--t-pie); color: var(--texto-3); line-height: 1.35; }

/* ----------------------------------------------------- arrastrar un audio -- */

/* Va apagado a propósito: lo primero es pegar el link. Esto es la otra puerta,
   la de cuando el audio ya lo tenés, y no tiene que competir con la principal. */
.soltar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e3);
  padding: var(--e5);
  border: 1px dashed var(--borde-suave);
  border-radius: var(--radio-panel);
  text-align: center;
  transition: border-color var(--normal), background var(--normal);
}
.soltar__texto { font-size: var(--t-dato); color: var(--texto-3); }
.soltar__texto b { color: var(--texto-2); font-weight: 600; }

/* Mientras tenés el archivo agarrado encima. Sin esto no se sabe si el
   navegador te lo va a aceptar o te lo va a abrir en otra pestaña. */
.soltar[data-encima="si"] {
  border-color: var(--acento);
  border-style: solid;
  background: var(--acento-suave);
}
.soltar[data-encima="si"] .soltar__texto b { color: var(--acento); }

.separador {
  height: 1px;
  background: var(--borde-suave);
  border: none;
}

/* ============================================================================
   EL RIEL DE CARGA

   Estaba roto, y era lo que Lucio veía "buguearse". Tres defectos encima:

   1. Se reiniciaba TRES veces en una sola descarga. El ayudante manda cuatro
      etapas —preguntar, traer, grabar el MP3, pasártelo— y dos de ellas van de
      0 a 100 sobre el MISMO riel. O sea: llegaba al final y volvía a empezar.
   2. Al pasar de "no sé cuánto falta" a "voy por el 4 %", la barra se ACHICABA
      de 35 % a 0 % durante 220 milésimas. Iba para atrás, a la vista.
   3. Lo que paseaba cuando no se sabía cuánto falta era la barra misma, así que
      su ancho quedaba pisado y había que acordarse de borrarlo.

   Arreglado en tres partes:

   - El riel es UNO SOLO y va de 0 a 100 en toda la descarga. Cada etapa tiene
     su pedazo: traer el audio ocupa del 0 al 70, pasártelo del 70 al 100.
   - Lo que pasea cuando no se sabe cuánto falta es un REFLEJO aparte, encima.
     La barra se queda quieta donde está y nunca vuelve para atrás.
   - Del lado del código, además, la barra no puede achicarse nunca: si un aviso
     llega desordenado, se ignora.
   ========================================================================= */

.avance { display: flex; flex-direction: column; gap: var(--e3); }
.avance__linea {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--e3);
  font-size: var(--t-dato);
  color: var(--texto-2);
}
.avance__num {
  font-family: var(--tipo-num);
  color: var(--texto);
  font-variant-numeric: tabular-nums;
}

.avance__riel {
  position: relative;
  height: 6px;
  background: var(--superficie-alta);
  border-radius: var(--radio-pastilla);
  overflow: hidden;
}
.avance__barra {
  height: 100%;
  width: 0%;
  background: var(--acento);
  border-radius: var(--radio-pastilla);
  transition: width var(--normal);
}

/* El reflejo: sólo aparece mientras no se sabe cuánto falta. Entra por la
   izquierda y sale por la derecha, sin tocar la barra. */
.avance__riel::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: 34%;
  border-radius: var(--radio-pastilla);
  background: linear-gradient(90deg,
              transparent,
              color-mix(in srgb, var(--acento) 70%, transparent),
              transparent);
  opacity: 0;
  transform: translateX(-110%);
  pointer-events: none;
  transition: opacity var(--rapido);
}
.avance[data-sabe="no"] .avance__riel::after {
  opacity: 1;
  animation: pasear 1.5s var(--curva) infinite;
}
@keyframes pasear {
  0%   { transform: translateX(-110%); }
  100% { transform: translateX(400%); }
}

/* -------------------------------------------------------------- privacidad -- */

.privacidad {
  display: flex;
  align-items: center;
  gap: var(--e2);
  max-width: 680px;
  margin: var(--e6) auto 0;
  padding-top: var(--e4);
  border-top: 1px solid var(--borde-suave);
  font-size: var(--t-dato);
  color: var(--texto-3);
}


/* ========================================================================================
   src/estilos/editor.css
   ======================================================================================== */

/* ============================================================================
   EL EDITOR

   La idea de fondo: esto no es un formulario, es un instrumento. Un instrumento
   tiene la parte que mirás siempre —la onda y el transporte— y la parte que
   cambiás de vez en cuando. Antes estaban las dos juntas: treinta y cuatro
   controles a la vista al mismo tiempo, en dos columnas donde uno quedaba
   huérfano y al lado suyo un hueco vacío.

   Ahora: la onda arriba, el transporte pegado abajo de la barra, y los controles
   detrás de cinco solapas de las que se ve UNA. De treinta y cuatro a diez.
   ========================================================================= */

/* El aire entre las partes del editor es --e3 y no --e4 a propósito: son seis
   filas, así que cada cuatro píxeles de más son veinticuatro de página. Y lo que
   se gana es que la onda, el transporte y los controles entren en una pantalla
   —que es todo el punto de haber puesto las solapas—. Medido: terminan en 887
   sobre una ventana de 900. */
.editor {
  display: flex;
  flex-direction: column;
  gap: var(--e3);
}

.editor__cabeza { display: flex; flex-direction: column; gap: var(--e1); }

.editor__titulo {
  font-size: var(--t-titulo);
  font-weight: 600;
  letter-spacing: -0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.editor__ficha {
  font-family: var(--tipo-num);
  font-size: var(--t-dato);
  color: var(--texto-3);
}

/* ------------------------------------------------------------------ onda --- */

.onda {
  position: relative;
  width: 100%;
  height: var(--onda-alto);
  border: 1px solid var(--borde-suave);
  border-radius: var(--radio-panel);
  overflow: hidden;
  background: var(--fondo);
}
.onda canvas { display: block; width: 100%; height: 100%; touch-action: none; }

.onda__ayuda {
  margin-top: calc(var(--e2) - var(--e4));  /* pegada a su onda, no al aire de la columna */
  font-size: var(--t-pie);
  color: var(--texto-3);
  display: flex;
  justify-content: space-between;
  gap: var(--e3);
}
.onda__ayuda b { color: var(--texto-2); font-weight: 600; }
.onda__ayuda-corta { display: none; }

/* Cada indicación de la ayuda va entera: si no entra todo en un renglón, se
   corta ENTRE una y otra, nunca en el medio. Antes se cortaba donde tocara, y en
   una pantalla común quedaba "Esc vuelve a" arriba y "todo" solo abajo. */
.onda__ayuda-larga > span { white-space: nowrap; }

/* Y el tramo que se está viendo ("0:00.0 → 0:06.0") tampoco se parte: con la
   ayuda más larga quedaba apretado contra el borde y se cortaba en la flecha. */
#onda-largo { white-space: nowrap; }

/* ============================================================== transporte ==
   Se pega justo abajo del encabezado, como en cualquier programa de música: el
   play y el reloj no se van de la pantalla nunca.

   OJO: `position: sticky` se muere EN SILENCIO si cualquier elemento que lo
   contenga tiene `overflow` distinto de `visible`. No tira error, no avisa:
   simplemente deja de pegarse. El día que alguien escriba `overflow-x: hidden`
   en el `body` para tapar un desborde de tres píxeles, esto deja de funcionar y
   nadie se entera. Hay una prueba que hace scroll hasta el fondo y comprueba
   que el botón de tocar sigue justo abajo de la barra.
   ========================================================================== */

.transporte {
  position: sticky;
  top: var(--alto-barra);
  z-index: 10;                 /* por debajo de la barra, que va en 20 */
  display: flex;
  align-items: center;
  gap: var(--e3);
  padding: var(--e2) var(--e3);
  background: var(--superficie);
  border: 1px solid var(--borde-suave);
  border-radius: var(--radio-panel);
}

.reloj {
  font-family: var(--tipo-num);
  font-size: var(--t-cuerpo);
  color: var(--texto);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.reloj span { color: var(--texto-3); }

.transporte__derecha { margin-left: auto; display: flex; gap: var(--e2); }

/* ================================================================ solapas ===
   Cinco lugares, se ve uno.

   REGLA DURA: nada que una prueba apriete puede vivir adentro de una solapa. El
   transporte y la barra de bajar quedan afuera, siempre a la vista. Está escrito
   también al lado del `role="tablist"` en app.html.

   Y los paneles NUNCA se sacan del DOM, sólo se ocultan. `editor.js` guarda
   cincuenta y cinco referencias a elementos que toma una sola vez al abrir el
   tema: un panel desmontado le deja la mano vacía y revienta mucho después, en
   otro lado. Hay una prueba que arrastra sobre la onda con la solapa de Recorte
   escondida y comprueba que el valor se actualizó igual.
   ========================================================================== */

.solapas {
  display: flex;
  gap: var(--e1);
  padding: var(--e1);
  background: var(--superficie);
  border: 1px solid var(--borde-suave);
  border-radius: var(--radio-pastilla);
  overflow-x: auto;
  scrollbar-width: none;
}
.solapas::-webkit-scrollbar { display: none; }

/* Las solapas se miden por su texto y quedan a la izquierda, como en cualquier
   programa de música. Estiradas a todo el ancho parecerían el selector de una
   aplicación de teléfono, que es justo lo que esto no es. */
.solapa {
  flex: 0 0 auto;
  min-height: 36px;
  padding: 0 var(--e4);
  font-family: var(--tipo);
  font-size: var(--t-dato);
  font-weight: 500;
  color: var(--texto-3);
  background: transparent;
  border: none;
  border-radius: var(--radio-pastilla);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--rapido), background var(--rapido);
}
.solapa:hover { color: var(--texto-2); }
.solapa[aria-selected="true"] {
  color: var(--texto);
  background: var(--superficie-alta);
  font-weight: 600;
  box-shadow: inset 0 0 0 1px var(--borde-suave);
}

/* Un puntito al lado del nombre cuando esa solapa tiene algo cambiado. Es lo
   que evita tener que abrir las cinco para saber dónde tocaste. */
.solapa[data-tocada="si"]::after {
  content: '';
  display: inline-block;
  width: 5px; height: 5px;
  margin-left: var(--e2);
  border-radius: 50%;
  background: var(--acento);
  vertical-align: middle;
}

.solapa-hoja {
  padding: var(--e5);
  background: var(--superficie);
  border: 1px solid var(--borde-suave);
  border-radius: var(--radio-panel);
}

/* -------------------------------------------------------------- controles -- */

/* El panel ya no dibuja su propia caja: la caja es la hoja de la solapa. Dos
   paneles adentro de la misma hoja se separan con una línea, no con dos marcos
   uno adentro del otro. */
.panel { display: flex; flex-direction: column; gap: var(--e3); }
.panel + .panel {
  margin-top: var(--e5);
  padding-top: var(--e5);
  border-top: 1px solid var(--borde-suave);
}

.panel__titulo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e2);
  font-size: var(--t-pie);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--texto-2);
}
.panel__valor {
  font-family: var(--tipo-num);
  font-size: var(--t-dato);
  color: var(--acento);
  text-transform: none;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

/* Deslizador */
.dial { display: flex; align-items: center; gap: var(--e3); }
.dial__rotulo {
  min-width: 56px;
  font-size: var(--t-pie);
  color: var(--texto-3);
}
/* El deslizador es alto aunque el riel se vea finito: la línea de 4 píxeles es
   lo que se DIBUJA, y los 26 de alto son lo que se puede AGARRAR. Antes el
   elemento entero medía 4 píxeles, o sea que había que acertarle con el mouse a
   una línea — con el dedo, imposible. */
.dial input[type="range"] {
  flex: 1;
  min-width: 0;
  -webkit-appearance: none;
  appearance: none;
  height: 26px;
  background: transparent;
  outline: none;
  cursor: pointer;
}
.dial input[type="range"]::-webkit-slider-runnable-track {
  height: 4px;
  background: var(--superficie-alta);
  border-radius: var(--radio-pastilla);
}
.dial input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px; height: 18px;
  margin-top: -7px;              /* centra el tirador sobre el riel de 4 px */
  background: var(--acento);
  border-radius: 50%;
  cursor: grab;
  border: 2px solid var(--fondo);
  box-shadow: 0 1px 4px color-mix(in srgb, var(--fondo) 80%, transparent);
  transition: transform var(--rapido);
}
.dial input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.15); }
.dial input[type="range"]:active::-webkit-slider-thumb { cursor: grabbing; transform: scale(1.2); }

.numerito {
  width: 72px;
  min-height: 36px;
  padding: var(--e2);
  font-family: var(--tipo-num);
  font-size: var(--t-dato);
  text-align: right;
  color: var(--texto);
  background: var(--fondo);
  border: 1px solid var(--borde-suave);
  border-radius: var(--radio-control);
  font-variant-numeric: tabular-nums;
}
.numerito:focus { outline: none; border-color: var(--acento); }

.fila { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e2); }

.nota {
  font-size: var(--t-pie);
  line-height: 1.45;
  color: var(--texto-3);
}

/* ============================================================== LOS PADS ====
   Dieciséis cuadrados, como en cualquier sampler.

   Hasta hoy NO TENÍAN UNA SOLA LÍNEA DE ESTILO: `editor.js` los venía armando
   con sus clases desde siempre y ninguna hoja las nombraba, así que salían como
   dieciséis botones grises del navegador, uno al lado del otro. La función que
   convierte esto en un instrumento estaba, literalmente, sin dibujar.

   Y el destello del que suena —que el código sí marca— no se veía.
   ========================================================================== */

/* Cuatro columnas, siempre: son cuatro porque las dieciséis teclas del teclado
   que las tocan están en cuatro filas de cuatro. Pero con tope de tamaño y
   centrados — estirados a todo el ancho de un monitor grande, un pad mide
   doscientos píxeles y deja de parecer un instrumento. */
.pads {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 124px));
  justify-content: center;
  gap: var(--e2);
}

.pad {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  aspect-ratio: 1;
  min-height: 56px;
  padding: var(--e2);
  background: var(--superficie-alta);
  border: 1px solid var(--borde-suave);
  border-radius: var(--radio-pad);
  color: var(--texto-2);
  font-family: var(--tipo);
  text-align: left;
  cursor: pointer;
  overflow: hidden;
  transition: border-color var(--rapido), background var(--rapido),
              color var(--rapido), transform var(--rapido);
}
.pad:hover:not(:disabled) {
  border-color: var(--acento-borde);
  background: var(--acento-suave);
  color: var(--texto);
}
.pad:active:not(:disabled) { transform: scale(0.97); }

/* Un lugar vacío del banco: se ve que está y que no tiene nada. No se esconde,
   porque su tecla del teclado sigue siendo esa aunque no suene, y una fila que
   desaparece se lee como un error de dibujo. */
.pad:disabled {
  background: transparent;
  border-style: dashed;
  border-color: var(--borde-suave);
  color: var(--texto-3);
  cursor: default;
}

/* La tecla del teclado, arriba a la izquierda, en cifras de máquina de escribir
   para que se lea como lo que es: una tecla. */
.pad__tecla {
  font-family: var(--tipo-num);
  font-size: var(--t-pie);
  font-weight: 600;
  color: var(--texto-3);
  letter-spacing: 0.04em;
}
/* El número del pedazo, grande y en el medio: es lo que mirás al tocar. */
.pad__num {
  margin: auto;
  font-size: var(--t-titulo);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
/* Cuánto dura, abajo. Chiquito: sirve para comparar de un vistazo, no para leer. */
.pad__largo {
  font-family: var(--tipo-num);
  font-size: var(--t-pie);
  color: var(--texto-3);
  align-self: flex-end;
}
.pad:hover:not(:disabled) .pad__tecla,
.pad:hover:not(:disabled) .pad__largo { color: var(--texto-2); }

/* El que está sonando. Prende del color de la casa y se apaga solo: entre
   dieciséis cuadrados iguales, es lo único que dice cuál sonó. */
.pad[data-sonando="si"] { animation: destello 620ms var(--curva); }
@keyframes destello {
  0%   { background: var(--acento);       border-color: var(--acento);       color: var(--fondo); }
  50%  { background: var(--acento-suave); border-color: var(--acento-borde); color: var(--texto); }
  100% { background: var(--superficie-alta); border-color: var(--borde-suave); color: var(--texto-2); }
}

.banco {
  font-size: var(--t-pie);
  color: var(--texto-3);
  font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------- descargar --- */

.salida {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e3);
  padding-top: var(--e5);
  border-top: 1px solid var(--borde-suave);
}
.salida__nombre {
  flex: 1;
  min-width: 200px;
  font-family: var(--tipo-num);
  font-size: var(--t-dato);
  color: var(--texto-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}


/* ========================================================================================
   src/estilos/anchos.css
   ======================================================================================== */

/* ============================================================================
   LOS TRES ANCHOS DE PANTALLA

   Hasta hoy no había NINGUNO: la única `@media` de todo el proyecto era la de
   "menos movimiento". En una ventana angosta el editor se desbordaba y no había
   forma de tocar nada con el dedo.

   POR QUÉ ESTÁN TODOS ACÁ Y NO AL PIE DE CADA PIEZA
   -------------------------------------------------
   CSS no deja escribir `@media (max-width: var(--corte))`. Los números 1100,
   780 y 520 se van a repetir como números pelados sí o sí. Si están
   desparramados por seis archivos, dentro de seis meses hay un cuarto corte en
   900 que nadie decidió — que es exactamente como aparecieron los diez tamaños
   de letra. Juntos, se ven de un vistazo, y `tests/estilo.test.js` los cuenta.

   POR QUÉ EXISTE EL ANCHO DE CELULAR SI EN EL CELULAR NO HAY EXTENSIONES
   ---------------------------------------------------------------------
   Chrome en Android no soporta extensiones y no lo va a soportar. Pero este
   mismo editor es el que va a ser la herramienta en la web, y una ventana
   angosta en la computadora tiene exactamente el mismo problema. Se escribe una
   vez y sirve dos veces.
   ========================================================================= */

/* ------------------------------------------------- menos de 1100: una columna */

@media (max-width: 1100px) {
  .hoja { padding: var(--e5) var(--e4) var(--e6); }
  :root { --onda-alto: 180px; }
}

/* --------------------------------------- menos de 780: se acomoda el editor -- */

@media (max-width: 780px) {
  :root { --onda-alto: 160px; }

  /* La ayuda de la onda en dos renglones: en una línea se corta y no se lee. */
  .onda__ayuda { flex-direction: column; gap: var(--e1); }

  .solapa-hoja { padding: var(--e4); }
  .solapa { padding: 0 var(--e3); }
  .calidades { grid-template-columns: repeat(2, 1fr); }
  .calidad__nota { display: none; }
}

/* ---------------------------------------------- menos de 520: con el dedo ---- */

@media (max-width: 520px) {
  /* La letra sube en pantalla chica. Y hay un motivo que no es estético: si un
     campo de texto tiene menos de 16 píxeles, el celular hace zoom solo al
     tocarlo y te deja la pantalla corrida. */
  :root {
    --t-pie:     12px;
    --t-dato:    13px;
    --t-cuerpo:  16px;
    --t-titulo:  18px;
    --t-portada: 24px;
    --onda-alto: 150px;
  }

  .hoja { padding: var(--e4) var(--e3) var(--e5); }
  .calidades { grid-template-columns: 1fr; }
  .calidad__nota { display: block; }

  /* Todo lo que se toca llega al mínimo de 44 píxeles, que es lo que mide la
     yema de un dedo. Antes lo cumplían tres controles de cuarenta.

     Y DE ANCHO TAMBIÉN, no sólo de alto. Un botón de 44 de alto y 40 de ancho
     es igual de difícil de acertar, y son justo los cortitos —"1×", "2×",
     "A"— los que quedaban abajo. Lo encontró `npm run auditar` el 2026-09-02,
     la primera vez que se corrió: `pantallas.mjs` sólo miraba el alto. */
  .tecla, .solapa, .boton, .numerito, .pad { min-height: 44px; }
  .tecla, .tecla--preset { min-width: 44px; }
  /* Los pads pasan a ocupar el ancho de la pantalla: en un teléfono los
     dieciséis tienen que caber y tocarse con el pulgar. */
  .pads { grid-template-columns: repeat(4, 1fr); }
  .numerito { width: 84px; font-size: var(--t-cuerpo); }
  .dial input[type="range"] { height: 44px; }

  /* El transporte se va abajo del todo, donde llega el pulgar, y se queda ahí:
     no cuando el scroll lo alcanza, sino siempre. Por eso acá es `fixed` y no
     `sticky`. */
  .transporte {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 10;
    border-radius: var(--radio-panel) var(--radio-panel) 0 0;
    border-bottom: none;
    padding: var(--e2) var(--e3);
    padding-bottom: calc(var(--e2) + env(safe-area-inset-bottom));
    box-shadow: 0 -8px 24px color-mix(in srgb, var(--fondo) 85%, transparent);
  }
  /* Sin esto, el último control del editor queda debajo de la barra de abajo y
     no se puede apretar nunca. */
  .editor { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }

  /* "Reiniciar" no entra al lado de los otros cinco. Se vuelve un icono POR
     ESTILO, sin tocar el marcado: el texto sigue estando para quien navega con
     un lector de pantalla. */
  #limpiar { font-size: 0; min-width: 44px; }
  #limpiar::after { content: '↺'; font-size: var(--t-cuerpo); }

  /* Los botones de bajar van UNO POR RENGLÓN, no todos apretados.
     Apretados, "Descargar WAV" y "Traer otro" se partían en dos líneas cada uno
     —"Descargar / WAV"— que es la forma más rápida de que algo se vea mal hecho.

     EL `nowrap` NO SOBRA, aunque acá ya sea una columna. `.salida` viene con
     `flex-wrap: wrap`, y una columna que además envuelve arma VARIAS columnas:
     entonces el ancho de cada una lo fija el elemento más ancho de esa columna,
     y `align-items: stretch` estira hasta ESE ancho, no hasta el de la
     pantalla. Resultado: el nombre del archivo, que es `nowrap` con puntos
     suspensivos, deja de recortarse y se desborda de costado.
     Se vio de verdad el 2026-09-02: al medir el BPM solo, el nombre pasó a
     llevar `[200BPM Am]` adentro, creció a 449 píxeles y se salió de una
     pantalla de 420. El nombre era más largo, pero el defecto estaba desde
     antes esperando un texto que no entrara. */
  .salida { flex-direction: column; flex-wrap: nowrap; align-items: stretch; }
  .salida .boton { width: 100%; }
  .salida__nombre { min-width: 0; text-align: center; }

  /* Con el dedo no hay rueda ni doble clic: se muestra la ayuda que sí sirve. */
  .onda__ayuda-larga { display: none; }
  .onda__ayuda-corta { display: block; }

  /* En 390 píxeles los seis controles del transporte no entran de ninguna
     manera. Lo que sobra es la duración total, que ya está escrita arriba, en
     la ficha del tema. El elemento sigue existiendo para quien navega con un
     lector de pantalla y para las pruebas. */
  .reloj__resto { display: none; }
  .transporte { gap: var(--e2); }
  .transporte .tecla { min-width: 44px; padding: 0 var(--e2); }
}


}
