/* ==========================================================================
   GROOVEDEALER — SISTEMA VISUAL
   Documento unico. Sin build step. Sin dependencias.

   DOS CAPAS
   ---------
   .escucha  · la home y el 404. Una columna centrada y angosta, logo chico,
               lista de tracks y reproductor fijo. Poco de todo.
   .tienda   · el catalogo de repuestos. Banda de marca, marco de documento,
               grilla, ficha de homologacion. Aca vive la ficcion.

   REGLAS DURAS (las verifica el CI, por eso no se nombran aca literalmente):
   - cero degrades, cero desenfoques, cero efectos de capa sobre el fondo
   - maximo 7 colores hex distintos en todo el archivo
   - el amarillo del logo SOLO sobre superficies oscuras: sobre el blanco calido
     da 1.09:1 y es literalmente invisible
   - un solo acento por pantalla, y es el rojo del logo
   - border-radius maximo 2px

   QUE SIGNIFICA CADA COLOR (si no significa nada, no se aplica)
   ------------------------------------------------------------
   ROJO      · "esto es lo que esta activo AHORA": la fila que suena, el
               playhead, el boton de play, el foco y la cabeza de lectura de los
               rieles (un toque, no la traza entera). NUNCA como color de
               texto: 3.71:1 sobre el blanco calido alcanza para graficos y
               controles (3:1) pero no para texto (4.5:1), ni siquiera a 14px.
               Donde antes habia texto rojo ahora hay un filete rojo y el texto
               queda en grafito.
   AMARILLO  · el reloj del reproductor, y NADA MAS. Vive unicamente sobre el
               negro del reproductor (15.73:1). Sobre el blanco calido da 1.09:1
               y desaparece: por eso NO esta en los rieles, que van sobre blanco.
   GRIS/ALUM · la traza de los rieles. Es una anotacion al margen, no un panel.
   ALUMINIO  · superficies y filetes. GRIS · secundario. GRAFITO · texto.
   ========================================================================== */

/* --------------------------------------------------------------------------
   TIPOGRAFIA — dos familias, ninguna mas.

   Por ahora corren stacks del sistema. Cuando lleguen las woff2 propias van a
   sitio/fuentes/ y se descomentan estos bloques; los stacks de abajo quedan
   como fallback dentro de la misma declaracion --gd-display / --gd-tecnica.

   @font-face {
     font-family: 'GD Display';
     src: url('/fuentes/gd-display.woff2') format('woff2');
     font-weight: 700;
     font-style: oblique 6deg;
     font-display: swap;
   }
   @font-face {
     font-family: 'GD Tecnica';
     src: url('/fuentes/gd-tecnica.woff2') format('woff2');
     font-weight: 400;
     font-display: swap;
   }
   -------------------------------------------------------------------------- */

:root {
  /* PALETA — siete valores, ni uno mas -------------------------------------
     El rojo y el amarillo son los del logo, muestreados del PNG pixel por
     pixel para que sean exactamente los mismos y no "parecidos".

     REGLA DE CONTRASTE, medida y no estimada, sobre el blanco calido:
       rojo    #f90001  3.71:1 -> texto GRANDE y graficos si; texto chico NO
       amarillo #feeb03 1.09:1 -> INVISIBLE. Nunca sobre fondo claro.
     Sobre negro el amarillo da 15.73:1: su unico lugar es el reproductor
     fijo. Fuera de una superficie oscura, no se usa NUNCA.                */
  --gd-blanco: #f4f1ec;      /* blanco calido — fondo primario              */
  --gd-grafito: #1a1a18;     /* grafito — tipografia y UI                   */
  --gd-gris: #6b6b67;                /* 4.75:1 sobre el papel — AA */
  --gd-aluminio: #dedbd4;    /* aluminio cepillado — superficies, filetes   */
  --gd-rojo: #f90001;        /* rojo del logo — acento primario             */
  --gd-amarillo: #feeb03;    /* amarillo del logo — SOLO sobre fondo oscuro */
  --gd-negro: #0e0e0c;       /* banda de marca y reproductor fijo           */

  /* TIPOS ----------------------------------------------------------------- */
  --gd-display: Impact, 'Arial Narrow Bold', 'Haettenschweiler',
    'Franklin Gothic Heavy', 'Helvetica Neue', sans-serif;
  --gd-tecnica: ui-monospace, 'SF Mono', 'SFMono-Regular', Menlo, Consolas,
    'Liberation Mono', monospace;

  /* GRILLA DE INGENIERIA --------------------------------------------------- */
  --gd-filete: 1px;
  --gd-u: 8px;                       /* unidad base                          */
  --gd-margen: clamp(20px, 5vw, 72px);
  --gd-ancho: 1440px;
  --gd-columna: 640px;               /* la columna de la capa de escucha     */
  --gd-reproductor: 104px;           /* alto reservado al reproductor fijo   */
  /* La barra de total es la SEGUNDA superficie fija de AUDICION y no mide lo
     mismo que el reproductor. El padding del <body> se calculaba como
     `--gd-reproductor * 2`, o sea suponiendo que si: con la barra puesta la
     ultima fila quedaba tapada o sobraba aire, segun el caso. Medido en
     escritorio: 62px con el empujon puesto, que es el caso mas alto. Se reserva
     66 para no quedar al ras si el texto del empujon crece. En telefono la
     barra envuelve en dos lineas y mide mas: esta anotado abajo, en el corte
     de 560px.                                                               */
  --gd-totalbar: 66px;               /* alto real de la barra de total       */

  /* MOVIMIENTO — instrumento que conmuta, no animacion web ----------------- */
  --gd-motion: 140ms;
  --gd-ease: cubic-bezier(0.2, 0, 0, 1);
}

/* --------------------------------------------------------------------------
   BASE
   -------------------------------------------------------------------------- */

*,
*::before,
*::after { box-sizing: border-box; }

/* EL BUG QUE ESTO ARREGLA.
   `hidden` es un atributo, y el navegador lo aplica con `display: none` desde
   SU hoja de estilos. Cualquier `display` que escriba yo —`.totalbar` es flex,
   `.selector` tambien— le gana, porque el estilo de autor siempre le gana al
   del navegador. Resultado: `nodo.hidden = true` desde JavaScript no ocultaba
   nada. La barra de total aparecia en FICHAS —donde no va— y encima vacia,
   porque `pintarBarra` la marca oculta y sale sin escribir los numeros.

   Va con `!important` a proposito: tiene que ganarle a cualquier `display` de
   componente, presente o futuro. Es la unica excepcion de la hoja. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: auto;
}

body {
  margin: 0;
  background: var(--gd-blanco);
  color: var(--gd-grafito);
  font-family: var(--gd-tecnica);
  font-size: 13px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* El reproductor fijo no puede tapar la ultima fila de la lista. */
.con-reproductor { padding-bottom: var(--gd-reproductor); }

img, svg { display: block; max-width: 100%; }

a { color: inherit; text-decoration: none; }

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

:focus-visible {
  outline: 2px solid var(--gd-rojo);
  outline-offset: 2px;
}

/* MENOS EL CONTENEDOR DE LA PAGINA.
   navegar.js le pone tabindex="-1" a #principal y le manda el foco despues de
   cada navegacion blanda: es lo que hace que el lector de pantalla anuncie la
   pantalla nueva en vez de quedarse callado. Pero el anillo dibujaba un marco
   rojo alrededor de TODO el contenido, que parecia la pagina entera
   seleccionada y no informaba nada: el foco esta en un contenedor, no en un
   control. Se saca el dibujo, no el foco. */
#principal:focus,
#principal:focus-visible { outline: none; }

::selection { background: var(--gd-rojo); color: var(--gd-blanco); }

/* LA TRANSICION DE PANTALLA — la navegacion blanda de navegar.js.
   Sin esto el reemplazo del DOM es un corte seco: la pantalla vieja desaparece
   y la nueva ya esta ahi, sin nada que diga que hubo una navegacion.

   SALIDA. La pantalla que se deja se va hacia ARRIBA y la que entra viene DESDE
   ABAJO: las dos en la misma direccion, como una cinta que corre. Si salieran
   para el mismo lado del que entra la nueva, se cruzarian y el movimiento se
   leeria como un rebote. */
.gd-sale .banda,
.gd-sale .menu,
.gd-sale .sistema,
.gd-sale .hoja-simple,
.gd-sale .pie-simple {
  opacity: 0;
  transform: translateY(-14px);
  transition: opacity 140ms linear, transform 140ms linear;
}

/* La ENTRADA.

   Entran las DOS piezas del documento y no el <body> entero, porque el
   reproductor es el nodo que sobrevive: si animara, lo unico que se mantiene
   entre pantallas parpadearia en cada clic. La banda entra primero y el
   contenido 120ms despues —el encabezado se planta y despues aterriza la hoja—,
   que es lo que le da direccion al movimiento en vez de un fundido plano.

   `both` deja el estado inicial aplicado antes del primer cuadro: sin el, se
   ve un destello de la pantalla ya puesta antes de que arranque la animacion.
   La regla de prefers-reduced-motion de abajo lo reduce a 1ms. */
@keyframes gd-entrada {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: none; }
}

.gd-entra .banda,
.gd-entra .menu,
.gd-entra .sistema,
.gd-entra .hoja-simple,
.gd-entra .pie-simple {
  animation: gd-entrada 460ms cubic-bezier(0.2, 0, 0, 1) both;
}

/* La navegacion primero, el contenido despues. Las dos capas tienen contenedores
   distintos —.banda + .sistema en la tienda, .menu + .hoja-simple + .pie-simple
   en la escucha—, asi que van nombrados: un selector de hijos directos del
   <body> tomaria tambien el riel a cuadros y el salto al contenido. */
.gd-entra .sistema,
.gd-entra .hoja-simple,
.gd-entra .pie-simple { animation-delay: 120ms; }

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 1ms !important; animation-duration: 1ms !important; }
}

/* --------------------------------------------------------------------------
   PRIMITIVAS TIPOGRAFICAS
   -------------------------------------------------------------------------- */

/* Rotulo tecnico: TODO dato, etiqueta, spec y microcopy de la tienda. */
.rot {
  font-family: var(--gd-tecnica);
  font-size: 10px;
  line-height: 1.4;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gd-grafito);
}

.rot--gris { color: var(--gd-gris); }
.rot--rojo { color: var(--gd-rojo); }
.rot--xs { font-size: 9px; letter-spacing: 0.22em; }

/* Display: la que se imprime en la puerta de un auto de carrera. */
.disp {
  font-family: var(--gd-display);
  font-weight: 700;
  font-style: oblique 4deg;
  letter-spacing: -0.02em;
  line-height: 0.86;
  text-transform: uppercase;
  margin: 0;
}

.disp--xl { font-size: clamp(48px, 11vw, 148px); }
.disp--l  { font-size: clamp(34px, 6vw, 76px); }
.disp--m  { font-size: clamp(26px, 3.4vw, 44px); }
.disp--s  { font-size: clamp(20px, 2.2vw, 28px); }

/* ==========================================================================
   CAPA DE ESCUCHA — el que llega de Instagram.

   Una sola columna angosta y centrada. Cero metadata en las esquinas, cero
   marcas de registro, cero banda negra: el logo va chico y centrado, porque
   el protagonista es el sistema y no la marca.
   ========================================================================== */

.hoja-simple {
  max-width: var(--gd-columna);
  margin: 0 auto;
  padding: 0 var(--gd-margen) calc(var(--gd-u) * 4);
}

.menu {
  max-width: var(--gd-columna);
  margin: 0 auto;
  padding: 18px var(--gd-margen) 0;
  display: flex;
  gap: calc(var(--gd-u) * 3);
  justify-content: center;
  font-size: 12px;
  letter-spacing: 0.04em;
}

.menu a {
  padding-bottom: 2px;
  border-bottom: var(--gd-filete) solid transparent;
  transition: color var(--gd-motion) linear, border-color var(--gd-motion) linear;
}

/* El filete rojo marca la pagina activa; el texto queda en grafito. A 12px el
   rojo del logo da 3.71:1 sobre el blanco calido y no llega al 4.5:1 que pide
   el texto — el color senala igual, sin pagar contraste. */
.menu a:hover,
.menu a[aria-current='page'] {
  color: var(--gd-grafito);
  border-bottom-color: var(--gd-rojo);
}

/* home_image: el logo, centrado. Sin sinopsis debajo, es lo unico que hay entre
   el borde de la pagina y la primera pista, asi que puede respirar. Se escala
   con el viewport pero nunca pasa del ancho de la columna. */
/* Centrado con flex y no con margin:auto sobre la imagen: asi no depende de que
   el <img> sea block ni de que el contenedor tenga un ancho definido, que son
   las dos formas en que un centrado con margenes se rompe en silencio. */
.marca-chica {
  display: flex;
  justify-content: center;
  margin: calc(var(--gd-u) * 4) 0;
}

.marca-chica img {
  width: clamp(240px, 46vw, 420px);
  max-width: 100%;
  height: auto;
}

.titulo-simple {
  font-family: var(--gd-tecnica);
  font-size: 16px;
  font-weight: 400;
  letter-spacing: 0.04em;
  text-align: center;
  margin: calc(var(--gd-u) * 8) 0 calc(var(--gd-u) * 3);
}

/* --------------------------------------------------------------------------
   LISTA DE TRACKS — una fila por track, mas nuevo primero.
   La fila entera ES el boton de play: un solo tab stop y un area de toque
   grande en telefono.
   -------------------------------------------------------------------------- */

/* La regla de cabecera va en negro y en 2px. Es la unica linea gruesa de la
   pagina y marca donde empieza el listado — que esta ordenado de mas nuevo a
   mas viejo, asi que la primera fila que hay debajo es la ultima publicada.
   En negro y no en rojo: el rojo de la home quedo para lo que esta sonando y
   para el boton de la tienda, que son las dos cosas que piden atencion. Una
   linea estructural no compite con ellas. */
.pistas {
  list-style: none;
  margin: 0;
  /* Aire debajo de la regla. La primera fila arrancaba pegada a la linea y las
     dos cosas se leian como una sola: la regla es el encabezado del listado, no
     el borde de arriba del primer track. */
  padding: calc(var(--gd-u) * 3) 0 0;
  border-top: 2px solid var(--gd-negro);
}

.pista {
  position: relative;
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: calc(var(--gd-u) * 1.5);
  width: 100%;
  padding: 10px 0;
  text-align: left;
  border-bottom: var(--gd-filete) solid var(--gd-aluminio);
}

/* Cota roja al margen: aparece solo en la fila que esta sonando. Vive dentro
   del margen de la hoja, asi que no corre ni un pixel del contenido. */
.pista::before {
  content: '';
  position: absolute;
  left: -10px;
  top: 8px;
  bottom: 8px;
  width: 3px;
  background: var(--gd-rojo);
  transform: scaleY(0);
  transform-origin: center top;
  transition: transform var(--gd-motion) var(--gd-ease);
}

/* LA MINIATURA ES UNA VENTANA, NO UNA FOTO.
   El recuadro es cuadrado y no se mueve. Lo que se mueve es la onda: el SVG es
   una tira con los 90 segundos enteros y aca se ve una ventana de ~6. Al dar
   play la tira se desplaza y la forma de onda VA PASANDO, segundo a segundo,
   como en el software de DJ.
   Mostrar los 90 s completos en 72 px daba barras de dos pixeles: no se lucia
   y dos temas distintos se veian iguales. */
.pista__arte {
  --arte: 72px;
  position: relative;
  width: var(--arte);
  height: var(--arte);
  border: var(--gd-filete) solid var(--gd-aluminio);
  background: var(--gd-blanco);
  overflow: hidden;
  transition: border-color var(--gd-motion) linear;
}

.pista__onda {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: auto;
  max-width: none;
  /* El 100% es el ancho de la TIRA. El recorrido total es esa tira menos la
     ventana, asi que a --avance = 1 se ve el final del tema y nunca hay vacio. */
  transform: translateX(calc(-1 * var(--avance, 0) * (100% - var(--arte))));
  /* `timeupdate` llega ~4 veces por segundo; la transicion rellena el resto y
     el desplazamiento se ve continuo en vez de a saltos. */
  transition: transform 280ms linear;
}

/* Sin animacion: la ventana se queda en el arranque del tema, quieta. */
@media (prefers-reduced-motion: reduce) {
  .pista__onda { transition: none; transform: none; }
}

.pista__texto { display: grid; gap: 3px; min-width: 0; }

.pista__titulo {
  font-size: 14px;
  letter-spacing: 0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Debajo del titulo va el artista: es el dato que le dice al oyente de que
   tema se trata. El codigo GD-XXX ya esta impreso enorme sobre la miniatura,
   asi que repetirlo aca gastaba la unica linea util de la fila. */
.pista__artista {
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--gd-gris);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Solo la duracion, alineada a la derecha en el registro tecnico. El codigo
   GD-XXX salio de aca: ya esta impreso sobre la miniatura. */
.pista__meta {
  display: grid;
  gap: 3px;
  justify-items: end;
  text-align: right;
}

.pista__dur {
  font-size: 11px;
  color: var(--gd-gris);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.pista__icono {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: var(--gd-filete) solid var(--gd-grafito);
  border-radius: 2px;
  transition: background-color var(--gd-motion) linear, border-color var(--gd-motion) linear,
    color var(--gd-motion) linear;
}

.pista__icono .icono--pausa { display: none; }

.pista:hover .pista__icono { border-color: var(--gd-rojo); }

/* TRES ESTADOS, TRES SEÑALES DISTINTAS
   ------------------------------------
   normal   · filete aluminio, duracion en gris
   cargada  · la pista que el reproductor tiene en el cargador pero en pausa:
              sube a grafito. Es un matiz, no un anuncio.
   sonando  · el estado mas importante de la pagina. Cota roja al margen,
              portada enmarcada en rojo, el cuadro del icono lleno de rojo y el
              glifo cambiado a pausa. Todo señal grafica: el rojo del logo da
              3.71:1 sobre el blanco calido, que alcanza para graficos pero no
              para texto, asi que la tipografia NO se pinta nunca de rojo.

   La marca de "sonando" sale de data-sonando, que player.js pone solo cuando el
   audio esta efectivamente corriendo; aria-current marca la pista cargada. */
.pista[aria-current='true'] .pista__dur { color: var(--gd-grafito); }
.pista[aria-current='true'] .pista__arte { border-color: var(--gd-grafito); }

.pista[data-sonando='1']::before { transform: scaleY(1); }
.pista[data-sonando='1'] .pista__arte { border-color: var(--gd-rojo); }
.pista[data-sonando='1'] .pista__icono {
  border-color: var(--gd-rojo);
  background: var(--gd-rojo);
  color: var(--gd-blanco);
}
.pista[data-sonando='1'] .pista__icono .icono--play { display: none; }
.pista[data-sonando='1'] .pista__icono .icono--pausa { display: block; }

.nota,
.salida {
  margin: calc(var(--gd-u) * 2) 0 0;
  font-size: 11px;
  color: var(--gd-gris);
}

/* La salida de texto: la usa el 404 para volver al inicio. Lleva el subrayado
   rojo —el color dice "por aca se sale"— y el texto en grafito, no en rojo: a
   11px el rojo daria 3.71:1 y no llega al 4.5:1 que pide el texto. */
.salida { margin-top: calc(var(--gd-u) * 3); }

.salida a {
  color: var(--gd-grafito);
  border-bottom: 2px solid var(--gd-rojo);
  padding: 1px 3px;
  transition: background-color var(--gd-motion) linear;
}

.salida a:hover { background: var(--gd-aluminio); }

/* LA CALCOMANIA — la unica salida de la home hacia la tienda.
   -------------------------------------------------------------------------
   Es texto, no una imagen: se dibuja con CSS imitando la pieza de arte de la
   marca. Que sea texto no es un detalle tecnico —pesa 0 KB en vez de 338, se
   lee con un lector de pantalla, escala sin pixelarse y el dia que cambie la
   palabra se cambia en vocabulario.json y no en un editor de imagenes—.

   LOS TRES ANILLOS, de adentro hacia afuera: campo rojo, filete blanco, filete
   negro. El blanco es el `border` y el negro el `outline`, que se dibuja por
   fuera del borde: dos anillos concentricos en un solo elemento. Es el remate
   de calcomania —la pieza recortada con su margen blanco— y ademas es lo que
   despega el rojo del crema de la pagina, que si no se tocan sin separacion.

   LA LETRA en la tipografia display, que ya viene inclinada 4 grados: es la
   misma inclinacion del lettering de la pieza original, asi que no hay que
   agregarle ningun sesgo aparte.

   MEDIDO: amarillo #FEEB03 sobre rojo #F90001 da 3.41:1. Eso NO alcanza para
   texto normal —hacen falta 4.5:1— pero si para texto grande, que pide 3:1, y
   de ahi salen los 22px en negrita: es el TAMANO el que hace que este par pase
   AA. Si alguna vez se achica esta letra, hay que cambiarle el color.

   EL HOVER LA LEVANTA: sube 5px y le aparece una sombra dura, sin desenfoque
   —el recurso de la impresion industrial, una pieza pegada que proyecta—. Al
   apretar aterriza y la sombra desaparece. La sombra esta siempre declarada,
   con desplazamiento cero en reposo: interpolar entre `none` y una sombra
   obliga al navegador a inventar el estado intermedio y ahi es donde salia
   entrecortada; entre dos sombras de la misma forma es solo aritmetica.

   EL AIRE DE ARRIBA ES MENOR QUE EL DE ABAJO, A PROPOSITO. Debajo hay 80px
   puestos por el layout de la pagina —32 del padding inferior de .hoja-simple
   mas 48 del margen superior de .pie-simple— que no se ven pero ocupan. Poner
   esos mismos 80 arriba daba dos huecos iguales y aun asi el de arriba se veia
   mas grande: el de abajo termina en el filete del pie, que lo cierra, y el de
   arriba queda abierto contra el final de la lista. Un hueco cerrado se lee mas
   chico que uno abierto del mismo tamano, asi que el de arriba se recorta hasta
   que los dos PARECEN iguales, que es lo unico que importa. */
.calco {
  margin: 0;
  padding: calc(var(--gd-u) * 6) 0 0;
  text-align: center;
}

/* `display: block` con `margin: 0 auto` y no un inline-block centrado por
   `text-align`: el enlace se centra por su propia caja, sin depender de que la
   alineacion del parrafo le llegue heredada. */
.calco__enlace {
  display: block;
  width: fit-content;
  margin: 0 auto;
  padding: 14px 34px;
  border: 3px solid var(--gd-blanco);
  outline: 2px solid var(--gd-negro);
  border-radius: 4px;
  background: var(--gd-rojo);
  color: var(--gd-amarillo);
  font-family: var(--gd-display);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
  box-shadow: 0 0 0 var(--gd-negro);
  transform: translate(0, 0);
  transition: transform 180ms cubic-bezier(0.2, 0, 0, 1),
              box-shadow 180ms cubic-bezier(0.2, 0, 0, 1);
}

.calco__enlace:hover,
.calco__enlace:focus-visible {
  transform: translateY(-5px);
  box-shadow: 5px 7px 0 var(--gd-negro);
}

/* Apretada: aterriza y la sombra se mete debajo. */
.calco__enlace:active {
  transform: translateY(0);
  box-shadow: 0 0 0 var(--gd-negro);
}

/* Sin movimiento, la sombra sola alcanza para decir que se puede apretar. */
@media (prefers-reduced-motion: reduce) {
  .calco__enlace:hover,
  .calco__enlace:focus-visible,
  .calco__enlace:active {
    transform: none;
    box-shadow: 4px 5px 0 var(--gd-negro);
  }
}


.pie-simple {
  max-width: var(--gd-columna);
  margin: calc(var(--gd-u) * 6) auto 0;
  padding: var(--gd-u) var(--gd-margen) calc(var(--gd-u) * 4);
  border-top: var(--gd-filete) solid var(--gd-aluminio);
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--gd-gris);
  text-align: center;
}

.pie-simple__lema { display: block; margin-top: calc(var(--gd-u) * 2); }

/* LAS PLATAFORMAS — Instagram, SoundCloud y YouTube, en el pie de la home.
   El que llego de Instagram y no compra nada igual tiene adonde seguir. Los
   temas completos estan en YouTube y la nota de abajo lo dice: aca hay
   muestras de 90 segundos y esa regla no se toca.

   Mientras una URL diga PENDIENTE en vocabulario.json, construir.mjs no emite
   ese link: mejor un pie con dos plataformas que un link roto. */
.plataformas {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--gd-u) calc(var(--gd-u) * 2);
}

/* El que cae al nombre en texto —una plataforma sin logo dibujado— conserva el
   subrayado de siempre. */
.plataformas a {
  color: var(--gd-grafito);
  border-bottom: var(--gd-filete) solid var(--gd-aluminio);
  padding-bottom: 2px;
  transition: border-color var(--gd-motion) linear, color var(--gd-motion) linear;
}

.plataformas a:hover { border-bottom-color: var(--gd-rojo); }

/* EL ICONO NO LLEVA SUBRAYADO: un dibujo con una linea abajo no se lee como un
   enlace, se lee como un dibujo mal alineado. Lo que dice que se puede tocar es
   el area de 44px —el minimo para un dedo— y el rojo al pasar el mouse.
   En gris en reposo para que no le compita a la lista de tracks, que es lo que
   la home tiene que hacer mirar. */
/* Va con el contenedor adelante —`.plataformas a.plataformas__icono`— porque
   `.plataformas a` de arriba es una clase MAS un elemento y le gana a una clase
   sola: sin esto el subrayado del enlace de texto seguia dibujandose debajo del
   icono. */
.plataformas a.plataformas__icono {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border-bottom: 0;
  color: var(--gd-gris);
}

.plataformas a.plataformas__icono:hover {
  color: var(--gd-rojo);
  border-bottom-color: transparent;
}

.icono--marca { width: 22px; height: 22px; }

/* --------------------------------------------------------------------------
   LA BANDERA A CUADROS — el unico riel.

   Hubo una traza de telemetria en el borde izquierdo con la envolvente del tema
   sonando. Se elimino: sobre el blanco calido quedaba tan tenue que no se leia,
   y al subirle el peso competia con la lista. El avance de reproduccion se ve
   ahora donde de verdad sirve, en la miniatura de la fila que suena.

   Queda la bandera, pegada al borde derecho. El damero ya esta en el logo y en
   las portadas, asi que no introduce lenguaje visual nuevo.

   SOLO ESCRITORIO, Y ES LITERAL. Abajo de 1200px no existe: display:none, no
   "se achica". La mayoria del trafico entra de Instagram desde el telefono y
   ahi la home tiene que quedar exactamente como estaba.

   Es decoracion: aria-hidden en el HTML, pointer-events:none aca, y nada
   enfocable adentro.
   -------------------------------------------------------------------------- */

.rieles { display: none; }

@media (min-width: 1200px) {
  .rieles { display: block; }

  /* La bandera va PEGADA al borde derecho y angosta: 36px, el ancho de dos
     cuadros. Ocupa el margen muerto que deja la columna central sin acercarse
     a la lista. Antes media hasta 148px y el SVG se estiraba para llenarla,
     que es por que los cuadros salian rectangulos deformes. */
  .riel {
    position: fixed;
    top: 0;
    bottom: 0;
    right: 0;
    z-index: 0;
    width: 36px;
    pointer-events: none;
  }

  .riel__svg { width: 100%; height: 100%; }
}

/* Negro pleno, sin opacidad. Una bandera a cuadros descolorida no es una
   bandera a cuadros: el contraste ES el motivo. */
.riel__cuadros { fill: var(--gd-negro); }

/* La explicacion de la seccion, antes del selector. Dos renglones: que es cada
   vista y para que sirve. Sin esto el selector es un par de palabras sueltas y
   nadie prueba la segunda vista. */
/* La invitacion a cambiar de vista. Va AL PIE de la lista, como el cierre de la
   pantalla: quien termino de recorrer los tracks es el que puede querer la otra
   vista. Es una banda entre dos filetes, con el mismo aire arriba y abajo. */
.invita {
  margin: calc(var(--gd-u) * 4) 0 0;
  padding: calc(var(--gd-u) * 2) 0;
  border-top: var(--gd-filete) solid var(--gd-aluminio);
  border-bottom: var(--gd-filete) solid var(--gd-aluminio);
  text-align: center;
}

.invita__texto {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.4;
  color: var(--gd-grafito);
}

/* El enlace es la palabra, no un boton aparte: hereda la tipografia de la
   frase y se distingue solo por el filete rojo abajo. */
.invita__enlace {
  display: inline-block;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  color: inherit;
  border-bottom: 2px solid var(--gd-rojo);
  cursor: pointer;
}

/* EL LATIDO. Dos pulsos y descanso, como un corazon: el ojo lo registra sin
   que la pagina parezca estar parpadeando.
   Late la ESCALA, no el color: en rojo el texto daria 3.71:1 y la regla 7 no
   deja texto chico en rojo. El rojo se queda donde ya estaba, en el filete.
   La regla global de prefers-reduced-motion lo apaga, no hay que repetirla. */
@keyframes gd-latido {
  0%, 34%, 100% { transform: scale(1); }
  8%            { transform: scale(1.09); }
  17%           { transform: scale(1); }
  25%           { transform: scale(1.06); }
}

.invita__enlace--late {
  transform-origin: 50% 100%;
  animation: gd-latido 3.2s ease-in-out infinite;
}


/* --------------------------------------------------------------------------
   REPRODUCTOR FIJO — el mismo en las dos capas.
   Dos lineas: mandos + lo que suena + reloj arriba, recorrido abajo. Asi
   entra a 375px sin apretar nada.

   Va en negro a proposito. Es el unico bloque de la home que es una maquina y
   no una hoja, y ademas es la unica superficie oscura que existe en telefono:
   por eso es el lugar legitimo del amarillo del logo, que sobre el negro da
   15.73:1 y sobre el blanco calido daria 1.09:1. Arriba lleva el filete rojo
   de 2px que hace juego con la regla de cabecera del listado: entre las dos
   encuadran la pagina.
   -------------------------------------------------------------------------- */

/* EL REPRODUCTOR NO SE VE EN LA CAPA DE ESCUCHA.
   En `/` cada fila YA es su propio control: el boton alterna play/pausa con
   `data-sonando` y la miniatura se va llenando con el avance. Una barra fija
   encima repetia lo mismo y se comia el 13 % del alto de un telefono.

   Se apaga con `display`, NO se saca del DOM ni se pone `hidden`: `navegar.js`
   mantiene vivo ese nodo entre paginas y `GD_PLAYER.rearmar()` conserva lo que
   suena. Asi el audio no se corta, y al pasar a `/tienda/` —donde el body deja
   de ser `.escucha`— el reproductor reaparece con el tema todavia sonando. */
/* EL AVISO DE QUE LA LISTA SIGUE.
   Misma regla de 2px que encabeza el listado, ahora abajo: cierra la caja y
   dice que hay mas. Se prende desde player.js SOLO si la lista realmente
   desborda, y se apaga al llegar al final — un cartel que dice "segui bajando"
   cuando ya no hay nada abajo miente. Nace con `hidden`, asi que sin JS no
   aparece nunca. */
.pistas__mas {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--gd-u) * 0.75);
  margin: 0;
  padding: calc(var(--gd-u) * 1.5) 0 0;
  border-top: 2px solid var(--gd-negro);
  font-family: var(--gd-mono);
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gd-grafito);
}
.pistas__mas .icono { width: 11px; height: 11px; }

body.escucha .reproductor { display: none; }
body.escucha.con-reproductor { padding-bottom: 0; }

.reproductor {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 50;
  background: var(--gd-negro);
  color: var(--gd-blanco);
  /* Sin filete arriba. Llevaba uno amarillo de 2px; el corte entre el crema de
     la pagina y el negro del reproductor ya es el borde mas duro que hay en
     pantalla, y subrayarlo con un tercer color solo agregaba una linea. */
  padding: 10px var(--gd-margen) 12px;
}

/* Sobre el negro el foco va en amarillo (15.73:1). El rojo sobre negro da 4.63:1:
   pasa como grafico, pero un anillo de foco merece el mejor contraste que haya. */
.reproductor :focus-visible { outline-color: var(--gd-amarillo); }

.reproductor__caja {
  max-width: var(--gd-columna);
  margin: 0 auto;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    'mandos ahora tiempo'
    'barra  barra barra';
  align-items: center;
  gap: 6px calc(var(--gd-u) * 1.5);
}

.reproductor__mandos {
  grid-area: mandos;
  display: flex;
  gap: 6px;
}

.mando {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: var(--gd-filete) solid var(--gd-gris);
  border-radius: 2px;
  color: var(--gd-blanco);
  transition: background-color var(--gd-motion) linear, color var(--gd-motion) linear,
    border-color var(--gd-motion) linear;
}

.mando:hover {
  background: var(--gd-blanco);
  border-color: var(--gd-blanco);
  color: var(--gd-negro);
}

/* El boton de play es el rojo del logo, lleno. Es el unico boton primario que
   tiene la pagina. */
.mando--play {
  background: var(--gd-rojo);
  border-color: var(--gd-rojo);
  color: var(--gd-blanco);
}

.mando--play:hover {
  background: var(--gd-blanco);
  border-color: var(--gd-blanco);
  color: var(--gd-rojo);
}

.mando .icono--pausa { display: none; }
.mando[aria-pressed='true'] .icono--play { display: none; }
.mando[aria-pressed='true'] .icono--pausa { display: block; }

.reproductor__ahora {
  grid-area: ahora;
  margin: 0;
  min-width: 0;
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--gd-blanco);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* El reloj es el unico texto amarillo del sistema. Es una lectura de
   instrumento y esta sobre negro: 15.73:1. */
.reproductor__tiempo {
  grid-area: tiempo;
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--gd-amarillo);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Barra de recorrido fina, un solo playhead rojo. */
.barra {
  grid-area: barra;
  position: relative;
  height: 20px;
  cursor: pointer;
  touch-action: none;
}

.barra__linea {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: var(--gd-filete);
  background: var(--gd-gris);
}

.barra__avance {
  position: absolute;
  left: 0;
  top: 50%;
  height: var(--gd-filete);
  width: 0;
  background: var(--gd-aluminio);
}

.barra__cabeza {
  position: absolute;
  top: 2px;
  bottom: 2px;
  left: 0;
  width: 2px;
  background: var(--gd-rojo);
}

/* ==========================================================================
   CAPA DE COMPRA — el catalogo de repuestos.
   ========================================================================== */

/* --------------------------------------------------------------------------
   BANDA DE MARCA — a sangre, plano negro. Solo en la tienda: en la home el
   logo va chico y sin banda. Debajo empieza el sistema suizo sobre blanco
   calido, corte duro, sin transicion ni degradado.
   -------------------------------------------------------------------------- */

/* La banda de la tienda: fina. Es el calco del equipo, no una portada. Cuanto
   mas alta, mas lejos queda la primera pieza del catalogo. */
.banda {
  /* El aire alrededor del texto del pie de la banda. Se usa DOS veces: como
     padding inferior de la banda y, sumado al alto del damero, como padding
     superior del pie. Asi el texto queda a la misma distancia del damero que
     del borde de abajo por construccion, y no por dos numeros que alguien
     ajusta a ojo y se desincronizan al primer cambio. */
  --gd-banda-aire: 14px;
  --gd-banda-damero: 16px;

  background: var(--gd-negro);
  padding: clamp(10px, 1.4vw, 16px) var(--gd-margen) var(--gd-banda-aire);
  border-bottom: var(--gd-filete) solid var(--gd-negro);
}

.banda__caja {
  max-width: calc(var(--gd-ancho) - var(--gd-margen) * 2);
  margin: 0 auto;
  display: flex;
  justify-content: center;
}

/* El ancho lo lleva el ENLACE, no la imagen.
   Antes `min(100%, 360px)` estaba sobre el <img>. Como el <a> es el item flex,
   su tamano base sale del max-content de la imagen —900px—, asi que el enlace
   ocupaba todo y la imagen de 360px quedaba pegada a su borde izquierdo: el
   logo aparecia a la izquierda del centro aunque el contenedor estuviera
   perfectamente centrado. Con el ancho en el <a>, el item flex mide lo que mide
   el logo y `justify-content: center` recien entonces tiene algo que centrar. */
.banda__caja a {
  display: block;
  width: min(100%, 360px);
}

.banda__logo {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
}

/* Debajo del logo iban dos rotulos —division y lema—; ahora va la navegacion.
   Los rotulos bajaron al pie: ver .pie__marca.

   La banda vive a sangre pero su CONTENIDO tiene que alinear con el del
   sistema, que es `--gd-ancho` CON el margen adentro (box-sizing: border-box).
   Como `.banda` ya aporta ese margen por fuera, aca hay que descontarlo o la
   banda queda 2x margen mas ancha —144px en escritorio— y los textos no caen
   sobre la misma linea que el contenido de abajo. */
.banda .cabecera {
  max-width: calc(var(--gd-ancho) - var(--gd-margen) * 2);
  margin: clamp(12px, 2vw, 20px) auto 0;
  padding: var(--gd-banda-aire) 0 0;
  border-top: var(--gd-filete) solid var(--gd-gris);
  border-bottom: 0;
}

/* Sobre el negro, el texto de la navegacion va en aluminio y la pagina actual
   en blanco calido: 14.19:1 y 15.4:1. El rojo se queda en el filete, como
   grafico, que es su lugar (regla 7) y ademas lo unico que distingue la solapa
   actual sin cambiarle el peso al texto. */
.banda .cabecera__nav a,
.banda .cabecera__carrito { color: var(--gd-aluminio); }

.banda .cabecera__nav a:hover,
.banda .cabecera__carrito:hover { color: var(--gd-blanco); }

.banda .cabecera__nav a[aria-current='page'] {
  color: var(--gd-blanco);
  border-bottom-color: var(--gd-rojo);
}

.banda .cabecera__carrito[aria-expanded='true'] { border-color: var(--gd-aluminio); }

/* La cruz de la marca. Hereda el color por currentColor. */
.banda__cruz {
  display: block;
  color: var(--gd-rojo);
  line-height: 0;
}

.banda__cruz svg { width: 18px; height: 18px; overflow: visible; }

/* --------------------------------------------------------------------------
   ENCABEZADO DEL SISTEMA
   -------------------------------------------------------------------------- */

.sistema {
  max-width: var(--gd-ancho);
  margin: 0 auto;
  padding: 0 var(--gd-margen);
}

/* Solo la navegacion, centrada. Antes compartia la fila con un rotulo de
   TEMPORADA / PIEZAS EN ARCHIVO que repetia datos visibles en otro lado. */
.cabecera {
  /* Ancla del popup del carrito, que se posiciona contra este borde. */
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: var(--gd-u) calc(var(--gd-u) * 3);
  padding: 14px 0;
  border-bottom: var(--gd-filete) solid var(--gd-grafito);
}

/* La fila entera: los enlaces a la izquierda y el carrito contra el margen
   derecho. `align-items: center` es lo que los deja a la misma altura — sin el,
   las cajas se estiran y el boton, que tiene padding propio, baja su texto
   respecto del de los enlaces. */
.cabecera__nav {
  display: flex;
  flex: 1;
  flex-wrap: wrap;
  align-items: center;
  gap: calc(var(--gd-u) * 3);
  justify-content: flex-start;
}

.cabecera__carrito { margin-left: auto; }

.cabecera__nav a {
  position: relative;
  padding-bottom: 2px;
  border-bottom: var(--gd-filete) solid transparent;
  transition: color var(--gd-motion) linear,
              border-color var(--gd-motion) linear;
}

.cabecera__nav a:hover,
.cabecera__nav a[aria-current='page'] {
  color: var(--gd-rojo);
  border-bottom-color: var(--gd-rojo);
}

/* --------------------------------------------------------------------------
   EL CARRITO DEL NAV — boton con icono, y el popup que abre.

   Es un <button> y no un enlace porque abre algo que ya esta en la pagina. El
   <a href="/carrito"> vive adentro del popup: sin JavaScript el <noscript> lo
   muestra igual y la pagina completa la sirve el Worker.
   -------------------------------------------------------------------------- */

.cabecera__carrito {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border: var(--gd-filete) solid transparent;
  border-radius: 2px;
  background: none;
  color: var(--gd-grafito);
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
  transition: color var(--gd-motion) linear, border-color var(--gd-motion) linear;
}

.cabecera__carrito:hover { color: var(--gd-rojo); }
.cabecera__carrito[aria-expanded='true'] { border-color: var(--gd-grafito); }
.cabecera__carrito .icono { width: 14px; height: 14px; }

/* El conteo solo existe cuando hay algo: vacio, el numero seria ruido. Rojo
   macizo con la cifra en blanco calido —12.4:1—, que es como se usa el rojo en
   todo el sistema: como superficie, nunca como color de texto chico. */
.cabecera__conteo {
  display: none;
  min-width: 18px;
  padding: 2px 5px;
  border-radius: 2px;
  background: var(--gd-rojo);
  color: var(--gd-blanco);
  font-size: 10px;
  line-height: 1.2;
  text-align: center;
}

.cabecera__carrito[data-lleno='1'] .cabecera__conteo { display: inline-block; }

/* Se ancla contra el borde derecho de la cabecera, que desde que la navegacion
   vive adentro de la banda ya esta metida su propio margen: con un `right`
   distinto de cero el popup quedaba desalineado del boton que lo abre. */
.carritopop {
  position: absolute;
  right: 0;
  top: 100%;
  z-index: 60;
  width: min(360px, calc(100vw - var(--gd-margen) * 2));
  margin-top: 6px;
  padding: calc(var(--gd-u) * 2);
  border: 2px solid var(--gd-grafito);
  border-radius: 2px;
  background: var(--gd-blanco);
  text-align: left;
}

.carritopop__cabeza {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--gd-u);
  padding-bottom: var(--gd-u);
  border-bottom: var(--gd-filete) solid var(--gd-grafito);
}

.carritopop__cerrar {
  appearance: none;
  padding: 0 4px;
  border: 0;
  background: none;
  color: var(--gd-grafito);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

.carritopop__cerrar:hover { color: var(--gd-rojo); }

.carritopop__vacio { margin: calc(var(--gd-u) * 2) 0; }

.carritopop__lista { list-style: none; margin: 0; padding: 0; }

.carritopop__item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--gd-u);
  padding: 10px 0;
  border-bottom: var(--gd-filete) solid var(--gd-aluminio);
}

.carritopop__texto { display: grid; gap: 2px; min-width: 0; }

.carritopop__titulo {
  font-size: 12px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.carritopop__precio { white-space: nowrap; font-variant-numeric: tabular-nums; }

.carritopop__quitar {
  appearance: none;
  width: 24px;
  height: 24px;
  padding: 0;
  border: var(--gd-filete) solid var(--gd-aluminio);
  border-radius: 2px;
  background: none;
  color: var(--gd-gris);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: color var(--gd-motion) linear, border-color var(--gd-motion) linear;
}

.carritopop__quitar:hover { color: var(--gd-rojo); border-color: var(--gd-rojo); }

.carritopop__pie { margin-top: calc(var(--gd-u) * 2); }

.carritopop__linea {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--gd-u);
  padding: 4px 0;
}

.carritopop__linea--total {
  margin-top: 4px;
  padding-top: var(--gd-u);
  border-top: var(--gd-filete) solid var(--gd-grafito);
}

.carritopop__cifra { font-size: 24px; color: var(--gd-rojo); line-height: 1; }

.carritopop .boton {
  display: flex;
  width: 100%;
  margin-top: calc(var(--gd-u) * 2);
  border-color: var(--gd-negro);
  background: var(--gd-amarillo);
  color: var(--gd-negro);
  font-weight: 700;
  box-shadow: none;
  transform: none;
}

/* Mismo caso que el boton de la ficha: en iOS el :hover se queda pegado y deja
   la letra amarilla sobre rojo (3.40:1). Solo donde hay mouse. */
@media (hover: hover) {
  .carritopop .boton:hover { background: var(--gd-rojo); color: var(--gd-amarillo); }
}

/* --------------------------------------------------------------------------
   HOJA — contenedor de documento con metadata en las esquinas y marcas de
   registro reales, no decorativas.
   -------------------------------------------------------------------------- */

.hoja {
  position: relative;
  padding: calc(var(--gd-u) * 5) 0 calc(var(--gd-u) * 9);
}

.marco {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--gd-u) calc(var(--gd-u) * 2);
  padding: 8px 0;
  border-bottom: var(--gd-filete) solid var(--gd-aluminio);
}

.marco--pie {
  border-bottom: 0;
  border-top: var(--gd-filete) solid var(--gd-aluminio);
  margin-top: calc(var(--gd-u) * 6);
}

.marco__celda { display: flex; flex-direction: column; gap: 3px; }
.marco__celda:nth-child(3) { text-align: right; }
.marco__celda:nth-child(4) { text-align: right; }

.registro { color: var(--gd-gris); }

/* Regla de medicion: ticks reales como elemento estructural. */
.regla {
  height: 12px;
  border-top: var(--gd-filete) solid var(--gd-grafito);
  display: flex;
  align-items: flex-start;
  overflow: hidden;
  margin: calc(var(--gd-u) * 2) 0;
}

.regla span {
  flex: 1 0 auto;
  width: 12px;
  height: 4px;
  border-left: var(--gd-filete) solid var(--gd-gris);
}

.regla span:nth-child(5n + 1) { height: 9px; border-left-color: var(--gd-grafito); }

/* --------------------------------------------------------------------------
   PORTADA — composicion asimetrica, espacio negativo enorme.
   -------------------------------------------------------------------------- */

.portada {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 5fr) minmax(0, 2fr);
  gap: calc(var(--gd-u) * 4);
  padding: calc(var(--gd-u) * 6) 0 calc(var(--gd-u) * 10);
  align-items: start;
}

/* Encabezado de indice (catalogo, divisiones, una division).
   Solo el titulo. La ceremonia de documento —codigo, revision, emision,
   clasificacion, hoja 01/01— quedo unicamente en la ficha de una pieza, que es
   donde esos campos describen algo real. En un listado empujaban la primera
   pieza fuera de la primera pantalla, que es justo lo que un catalogo no puede
   hacer. */
/* El encabezado de la ficha vive EN LA COLUMNA DE DATOS, al lado del arte: el
   tema y el artista son lo primero que se lee, y la especificacion viene
   despues como el detalle que es. */
.ficha__titulo {
  margin: 0;
}

.ficha__artista {
  margin: 10px 0 0;
  font-family: var(--gd-tecnica);
  font-size: 15px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gd-gris);
}

/* El cuadradito a cuadros que abre el titulo de seccion. Se mide en `em`, asi
   que sigue al clamp del display sin una sola media query. `baseline` lo apoya
   sobre la linea de base del titulo, y 0.72em —la altura de una mayuscula— lo
   deja exactamente a la altura de las letras.

   El <h1> es flex y no un bloque con la bandera en linea: en linea, un titulo
   largo no entraba al lado del cuadrado y la bandera se quedaba sola en el
   renglon de arriba. Como item flex, el texto es una caja aparte que envuelve
   por su cuenta y la bandera no se despega nunca de su izquierda.

   SIN OBLICUA. El titulo de seccion es lo unico del sistema que va derecho: al
   lado de una bandera a cuadros, la inclinacion pelea con la cuadricula —los
   cuadrados son rectos y las letras no— y el conjunto se lee desalineado por
   mas que el borde este a plomo. El resto del display conserva su
   `oblique 4deg`. */
.portada--indice h1 {
  display: flex;
  align-items: baseline;
  gap: 0.24em;
  font-style: normal;
}

.damero {
  flex: none;
  width: 0.72em;
  height: 0.72em;
  fill: var(--gd-negro);
}

.portada--indice {
  display: block;
  padding: calc(var(--gd-u) * 3) 0 calc(var(--gd-u) * 4);
}

/* El encabezado del catalogo comparte renglon con las solapas: el titulo a la
   izquierda y el tablist contra el borde derecho, apoyados en la misma linea de
   base. `flex-wrap` es lo que salva el telefono: cuando no entran, las solapas
   bajan a su propio renglon en vez de espachurrar el titulo. */
.portada--consolapas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--gd-u) calc(var(--gd-u) * 3);
  /* El filete que separa el encabezado de las portadas. Sin el, el titulo y la
     primera fila de la grilla se leen como una sola mancha. El margen de abajo
     es el aire entre el filete y las portadas: pegadas, la linea parece el
     borde superior de la grilla y no el cierre del encabezado. */
  border-bottom: var(--gd-filete) solid var(--gd-grafito);
  margin-bottom: calc(var(--gd-u) * 5);
}

.portada__izq { border-right: var(--gd-filete) solid var(--gd-aluminio); padding-right: calc(var(--gd-u) * 3); }
.portada__centro { grid-column: 2 / 4; }
.portada__bajada { max-width: 46ch; margin-top: calc(var(--gd-u) * 4); }

.dato { display: grid; grid-template-columns: 1fr; gap: 2px; margin-bottom: calc(var(--gd-u) * 3); }

.volver { margin-top: calc(var(--gd-u) * 4); }

/* --------------------------------------------------------------------------
   GRILLA DE CATALOGO — documentos, no tiles. La belleza sale de la
   repeticion y la alineacion.
   -------------------------------------------------------------------------- */

.grilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: calc(var(--gd-u) * 5) calc(var(--gd-u) * 4);
  list-style: none;
  margin: 0;
  padding: 0;
}

.doc { display: block; }
.doc__enlace { display: block; }

.doc__arte {
  position: relative;
  display: block;
  border: var(--gd-filete) solid var(--gd-grafito);
  background: var(--gd-blanco);
  aspect-ratio: 1 / 1;
  overflow: hidden;
}

/* La tapa cubre todo el cuadro: el play se apoya encima con z-index y sigue
   ganando el clic en su propio recuadro. */
.doc__tapa { display: block; width: 100%; height: 100%; }

.doc__arte img { width: 100%; height: 100%; object-fit: cover; }

/* Play sobre la portada: escuchar sin entrar a la ficha.
   Con mouse aparece al pasar por encima; sin mouse (telefono) esta siempre,
   porque ahi no existe el hover y un boton invisible es un boton que no
   existe. Y con foco de teclado tambien, o seria inalcanzable tabulando. */
/* El play es una superficie oscura con el glifo en amarillo: 14.19:1, y es de
   los pocos lugares donde el amarillo del logo puede existir. Sobre el blanco
   calido daria 1.09:1 y no se veria. */
.doc__play {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 68px;
  height: 68px;
  border: 2px solid var(--gd-negro);
  border-radius: 2px;
  background: var(--gd-negro);
  color: var(--gd-amarillo);
  opacity: 0;
  transition: opacity var(--gd-motion) linear,
              background-color var(--gd-motion) linear,
              color var(--gd-motion) linear;
}

.doc__arte:hover .doc__play,
.doc__play:focus-visible { opacity: 1; }

@media (hover: none) {
  .doc__play { opacity: 1; }
}

.doc__play:hover { background: var(--gd-rojo); border-color: var(--gd-rojo); color: var(--gd-blanco); }
.doc__play[data-sonando='1'] { color: var(--gd-blanco); }

/* Sonando: el boton se queda fijo y muestra la pausa. */
.doc__play .icono { width: 20px; height: 20px; }

.doc__play[data-sonando='1'] {
  opacity: 1;
  background: var(--gd-rojo);
  border-color: var(--gd-rojo);
  color: var(--gd-blanco);
}

.doc__play .icono--pausa { display: none; }
.doc__play[data-sonando='1'] .icono--play { display: none; }
.doc__play[data-sonando='1'] .icono--pausa { display: inline; }

.doc__titulo {
  display: block;
  margin-top: 10px;
  font-size: 14px;
  letter-spacing: 0.01em;
}

.doc__artista {
  display: block;
  margin-top: 2px;
  color: var(--gd-gris);
}

/* La tira de datos. En hover pasa a rojo y NADA MAS: sin escala, sin sombra,
   sin tilt. */
.doc__tira {
  margin-top: 8px;
  padding-top: 6px;
  border-top: var(--gd-filete) solid var(--gd-aluminio);
  display: block;
  color: var(--gd-grafito);
  transition: color var(--gd-motion) linear,
              border-color var(--gd-motion) linear;
}

.doc:hover .doc__tira,
.doc:focus-visible .doc__tira {
  color: var(--gd-rojo);
  border-top-color: var(--gd-rojo);
}

.doc__tira b { font-weight: 400; }

/* --------------------------------------------------------------------------
   FICHA DE HOMOLOGACION — la pagina mas importante de la tienda.
   Artwork de un lado, bloque de datos del otro, filete duro entre los dos.
   -------------------------------------------------------------------------- */

/* Sin filete arriba: la cabecera ya cierra con el suyo a treinta pixeles, y dos
   lineas paralelas sin nada entre medio leen como un error de impresion, no
   como estructura. El filete vertical entre las dos columnas alcanza para decir
   que esto es un documento de dos campos. */
.ficha {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: 0;
  /* El aire de arriba lo pone la ficha entera y NO el padding de las columnas:
     el filete vertical se dibuja sobre la columna completa, padding incluido,
     asi que con el aire adentro la linea arrancaba cuatro unidades mas arriba
     que la portada. Aca arranca exactamente donde arranca el arte. */
  /* Poco aire arriba: la hoja ya pone su propio padding debajo del menu, y las
     dos separaciones sumadas dejaban media pantalla vacia antes del titulo. */
  margin-top: calc(var(--gd-u) * 2);
  margin-bottom: calc(var(--gd-u) * 6);
}

/* Sin padding abajo: la columna termina EXACTAMENTE donde termina la portada.
   Es lo que hace que la linea de compra —empujada al fondo de la otra columna—
   cierre a la misma altura que el pie negro del arte. Cualquier cosa debajo del
   arte (antes iba el codigo GD-ARCHIVE-XXX) rompe esa alineacion. */
.ficha__arte {
  position: relative;
  padding: 0 calc(var(--gd-u) * 6) 0 0;
  border-right: var(--gd-filete) solid var(--gd-grafito);
}

.ficha__arte-caja {
  border: var(--gd-filete) solid var(--gd-grafito);
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--gd-blanco);
}

.ficha__arte-caja img { width: 100%; height: 100%; object-fit: cover; }

/* GROOVE APROBADO no es un dato mas de la tabla: es el visto bueno, y un visto
   bueno se estampa. Recuadro rojo, levemente torcido, como un sello de goma
   apoyado a mano sobre la ficha. El resto de la especificacion queda en texto
   plano justamente para que este resalte. */
.sello-estado {
  display: inline-block;
  padding: 5px 12px 4px;
  border: 2px solid var(--gd-rojo);
  color: var(--gd-rojo);
  font-weight: 700;
  letter-spacing: 0.16em;
  transform: rotate(-2.5deg);
  transform-origin: left center;
}

/* Columna en flex para que la linea de compra se pueda empujar al fondo: asi el
   boton queda a la altura del pie de la caratula y las dos columnas cierran
   juntas, en vez de terminar cada una donde le toco. */
.ficha__datos {
  display: flex;
  flex-direction: column;
  padding: 0 0 0 calc(var(--gd-u) * 6);
}

/* El bloque de nueve campos. Se lee como un documento de ingenieria. */
.especificacion {
  margin: calc(var(--gd-u) * 3) 0 0;
  border-top: var(--gd-filete) solid var(--gd-grafito);
}

.especificacion > div {
  display: grid;
  grid-template-columns: minmax(120px, 15ch) minmax(0, 1fr);
  gap: var(--gd-u) calc(var(--gd-u) * 3);
  padding: 9px 0;
  border-bottom: var(--gd-filete) solid var(--gd-aluminio);
}

.especificacion dt { color: var(--gd-gris); margin: 0; }
.especificacion dd { margin: 0; letter-spacing: 0.1em; }

/* El precio se lee como el renglon final de la especificacion, no como un
   cartel: etiqueta a la izquierda, cifra alineada a la derecha con el resto de
   los valores. A 76px competia con el titulo del tema y se comia la columna. */
.precio__cifra {
  color: var(--gd-rojo);
  font-size: clamp(26px, 3vw, 38px);
  text-align: right;
}

.acciones {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--gd-u) * 2);
  margin-top: calc(var(--gd-u) * 3);
}

/* La linea de compra: el boton a la izquierda y el precio contra el borde
   derecho, alineados por la base para que el numero se apoye en el mismo
   renglon que el texto del boton. En telefono se doblan y el precio queda
   arriba, que es el orden de lectura correcto cuando no entran juntos. */
.compra {
  display: flex;
  flex-wrap: wrap-reverse;
  align-items: center;
  justify-content: space-between;
  gap: var(--gd-u) calc(var(--gd-u) * 3);
  /* Al fondo de la columna, que ahora mide lo mismo que la portada: asi el
     boton y el precio cierran a la altura del pie negro del arte. */
  margin-top: auto;
  padding-top: calc(var(--gd-u) * 3);
}

/* La cifra se centra contra el boton, no contra la linea de base: son dos
   tipografias de tamano muy distinto y alinear sus bases era lo que se veia
   torcido.

   El translate es optico y esta puesto a proposito: la display es una grotesca
   condensada (Impact y familia) con un descendente enorme y sin descendentes
   reales en "ARS 5.000", asi que su caja de linea reserva abajo un espacio que
   ningun glifo usa y la mancha queda mas baja que el centro. Medio punto de eme
   la sube a donde el ojo la espera. */
/* El precio que viaja adentro del boton es SOLO para el telefono: en
   escritorio manda la cifra grande de al lado. */
.boton__precio { display: none; }

.compra .precio__cifra {
  display: block;
  line-height: 1;
  transform: translateY(-0.05em);
}

/* EL BOTON DE COMPRA — los tres colores del logo y nada mas.
   Sin el bloque rojo desplazado que llevan los demas botones: aca abajo compite
   con el precio, que ya es rojo y grande.

   MEDIDO: negro #0E0E0C sobre amarillo #FEEB03 da 15.7:1. La primera version
   tenia la letra en rojo y daba 3.40:1 — alcanza para texto grande, pero no
   para los 11px de esta etiqueta, que piden 4.5:1. El negro conserva el boton
   amarillo y ademas pasa AA con margen. */
.compra .boton {
  flex: 0 1 auto;
  border-color: var(--gd-negro);
  background: var(--gd-amarillo);
  color: var(--gd-negro);
  font-weight: 700;
  box-shadow: none;
  transform: none;
}

/* EL HOVER SOLO DONDE HAY MOUSE.
   En iOS el :hover queda PEGADO despues de tocar: el navegador se lo aplica al
   ultimo elemento tocado y no lo suelta hasta que se toca otra cosa. O sea que
   el boton de compra —el unico primario de la ficha— se quedaba en rojo con la
   letra amarilla, que da 3.40:1 y no llega al 4.5:1 que piden sus 11px. El
   estado de reposo, negro sobre amarillo, da 15.7:1. Con la consulta de medio,
   en un telefono el hover directamente no existe y el boton no se despinta. */
@media (hover: hover) {
  .compra .boton:hover {
    background: var(--gd-rojo);
    color: var(--gd-amarillo);
    border-color: var(--gd-negro);
    box-shadow: none;
    transform: none;
  }
}

/* Boton: rectangulo plano. Sin icono. Sin esquinas mas alla de 2px. */
/* LOS BOTONES TIENEN QUE PARECER BOTONES.
   Antes eran un rectangulo plano con filete de 1px: en un sistema donde TODO
   tiene filetes de 1px, un boton no se distinguia de una celda de tabla.
   Ahora tienen tres senales que ningun otro elemento del sistema usa:
   area de toque de 48px, filete de 2px, y una sombra dura y desplazada.
   La sombra no lleva desenfoque: es el recurso de la impresion industrial —una
   pieza pegada que proyecta— y ademas es lo unico que hace que se lea como algo
   que se puede APRETAR. Al pasar el mouse se hunde a la mitad; al apretar,
   aterriza. El movimiento es el que dice "esto es un boton". */
.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0 30px;
  border: 2px solid var(--gd-grafito);
  border-radius: 2px;
  background: var(--gd-grafito);
  color: var(--gd-blanco);
  font-family: var(--gd-tecnica);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  box-shadow: 4px 4px 0 var(--gd-rojo);
  transform: translate(0, 0);
  transition: transform var(--gd-motion) linear,
              box-shadow var(--gd-motion) linear,
              background-color var(--gd-motion) linear,
              color var(--gd-motion) linear,
              border-color var(--gd-motion) linear;
}

.boton:hover {
  transform: translate(2px, 2px);
  box-shadow: 2px 2px 0 var(--gd-rojo);
}

/* Apretado: la pieza aterriza y la sombra desaparece. */
.boton:active {
  transform: translate(4px, 4px);
  box-shadow: 0 0 0 var(--gd-rojo);
}

/* El secundario es el mismo boton en negativo: mismo peso, misma sombra, misma
   caida. Lo que cambia es el relleno, no la jerarquia de "esto se aprieta". */
.boton--fantasma {
  background: transparent;
  color: var(--gd-grafito);
}

.boton--fantasma:hover {
  background: var(--gd-grafito);
  color: var(--gd-blanco);
}

/* Ya agregado al BOX: el rojo pasa al relleno y la sombra se apaga, porque el
   boton dejo de ser una accion pendiente y paso a ser un estado. */
.boton[aria-pressed='true'] {
  background: var(--gd-rojo);
  border-color: var(--gd-rojo);
  color: var(--gd-blanco);
  box-shadow: none;
  transform: translate(4px, 4px);
}

.boton[disabled] {
  background: transparent;
  color: var(--gd-gris);
  border-color: var(--gd-gris);
  box-shadow: none;
  transform: none;
  cursor: not-allowed;
}

@media (prefers-reduced-motion: reduce) {
  .boton,
  .boton:hover,
  .boton:active { transform: none; }
}


/* La muestra de la ficha: la misma fila de track de la home, mas la
   telemetria de la pieza. */
.muestra {
  margin-top: calc(var(--gd-u) * 6);
  border-top: var(--gd-filete) solid var(--gd-grafito);
  padding-top: var(--gd-u);
}

/* La misma fila de ESCUCHA, pero de dos columnas y alta: en la ficha hay un
   solo tema y sobra ancho, asi que la onda se lee como el documento tecnico que
   es y no como la tira de 30px de una lista de veinte.

   Se escribe `.aud.muestra__banda` y no `.muestra__banda` a secas porque el
   bloque de `.aud` esta MAS ABAJO en esta hoja: con la misma especificidad
   ganaba el ultimo, y el `gap` y las seis columnas de la lista volvian a
   aplicarse — que es exactamente lo que separaba el play de la onda. Con las
   dos clases juntas el orden de la hoja deja de importar. */
.aud.muestra__banda {
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0;
  align-items: stretch;
  margin-top: var(--gd-u);
  padding: var(--gd-u) 0;
  border-bottom: 0;
}

/* Play y onda son UNA sola pieza: mismo alto, pegados, y el filete del medio
   compartido —el boton no lo dibuja a la derecha porque ya lo pone la onda—.
   Separados se leian como dos controles distintos para lo mismo. */
.aud.muestra__banda .aud__play {
  width: 72px;
  height: auto;
  align-self: stretch;
  border-radius: 0;
  border-right: 0;
}

.aud.muestra__banda .aud__onda {
  height: 96px;
  border-color: var(--gd-negro);
}

/* Sin el resaltado de la lista: aca la fila es la unica de la pantalla, asi que
   marcarla no distingue nada — solo mete un rectangulo gris. */
.aud.muestra__banda:hover,
.aud.muestra__banda:focus-within { background: none; }

.muestra .rot--gris { margin: var(--gd-u) 0 0; }

/* SOPORTE EN PISTA — el feedback de los promos, ya aprobado a mano.
   Es prueba social, no decoracion: por eso va en el registro tecnico de la
   ficha y no en una tarjeta. Sin JavaScript la seccion no aparece, y esta
   bien: es un agregado, no un dato de la homologacion. */
.soporte {
  margin-top: calc(var(--gd-u) * 6);
  border-top: var(--gd-filete) solid var(--gd-grafito);
  padding-top: var(--gd-u);
}

.soporte__lista { list-style: none; margin: var(--gd-u) 0 0; padding: 0; }

.soporte__lista li {
  border-left: 2px solid var(--gd-rojo);
  padding: 0 0 0 var(--gd-u);
  margin-bottom: var(--gd-u);
}

.soporte__texto { display: block; }
.soporte__quien { display: block; margin-top: 4px; }

/* --------------------------------------------------------------------------
   BOX — contador flotante. Se apoya arriba del reproductor cuando hay uno.
   -------------------------------------------------------------------------- */

.box-flotante {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 40;
  display: none;
  padding: 12px 18px;
  border: var(--gd-filete) solid var(--gd-grafito);
  border-radius: 2px;
  background: var(--gd-grafito);
  color: var(--gd-blanco);
  font-family: var(--gd-tecnica);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  box-shadow: 0 1px 2px rgb(14 14 12 / 22%);
  transition: background-color var(--gd-motion) linear;
}

.con-reproductor .box-flotante { bottom: calc(var(--gd-reproductor) + 8px); }

.box-flotante[data-visible='1'] { display: block; }
.box-flotante:hover { background: var(--gd-rojo); border-color: var(--gd-rojo); }

.box-lista { list-style: none; margin: calc(var(--gd-u) * 3) 0 0; padding: 0; }

.box-lista li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--gd-u) calc(var(--gd-u) * 3);
  align-items: center;
  padding: 12px 0;
  border-bottom: var(--gd-filete) solid var(--gd-aluminio);
}

/* --------------------------------------------------------------------------
   BRIEFING DE EQUIPO — la captura de correo, al pie del indice de /tienda/.

   No esta en la home a proposito: la home es para escuchar. Aca abajo lo lee
   alguien que ya recorrio el catalogo, asi que puede ocupar el ancho de un
   documento y hablar en el registro tecnico de esta capa.

   Ni un color nuevo: filete de aluminio, texto en grafito, rotulos en gris y
   el rojo unicamente donde ya vive —el foco y el hover del boton—. La paleta
   sigue teniendo siete valores.
   -------------------------------------------------------------------------- */

.briefing {
  margin-top: calc(var(--gd-u) * 10);
  padding-top: calc(var(--gd-u) * 3);
  border-top: var(--gd-filete) solid var(--gd-grafito);
  max-width: 62ch;
}

.briefing__bajada {
  margin: calc(var(--gd-u) * 2) 0 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--gd-grafito);
}

.briefing__etiqueta { display: block; margin-top: calc(var(--gd-u) * 3); }

.briefing__linea {
  display: flex;
  flex-wrap: wrap;
  gap: var(--gd-u);
  align-items: stretch;
  margin-top: var(--gd-u);
}

/* Campo de texto: la misma caja plana que todo lo demas. */
.campo {
  flex: 1 1 24ch;
  min-width: 0;
  padding: 13px 12px;
  border: var(--gd-filete) solid var(--gd-grafito);
  border-radius: 2px;
  background: var(--gd-blanco);
  color: var(--gd-grafito);
  font-family: var(--gd-tecnica);
  font-size: 12px;
  letter-spacing: 0.08em;
}

.campo::placeholder { color: var(--gd-gris); }

.campo:focus-visible { outline: 2px solid var(--gd-rojo); outline-offset: 2px; }

.briefing__linea .boton { flex: 0 0 auto; cursor: pointer; }

/* EL CAMPO TRAMPA.
   Fuera de pantalla, no oculto: `display:none` y `visibility:hidden` son las
   dos cosas que un bot moderno chequea antes de completar un campo. Esto se
   ve exactamente igual —o sea, nada— y ademas no es enfocable ni autocompleta,
   asi que una persona no lo puede llenar sin querer. */
.briefing__trampa {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.briefing__aviso:empty { display: none; }

.briefing__aviso {
  margin: calc(var(--gd-u) * 2) 0 0;
  padding-left: calc(var(--gd-u) * 2);
  border-left: 2px solid var(--gd-rojo);
  color: var(--gd-grafito);
  line-height: 1.6;
}

.briefing__aviso a {
  border-bottom: var(--gd-filete) solid var(--gd-grafito);
  padding-bottom: 1px;
}

.briefing__nota { margin: calc(var(--gd-u) * 2) 0 0; }

/* --------------------------------------------------------------------------
   PIE DE LA TIENDA
   -------------------------------------------------------------------------- */

/* EL PIE ES UN RENGLON: la firma de la division a la izquierda y las
   plataformas a la derecha. Antes eran cuatro lineas de ficcion apiladas donde
   nadie se detiene. `space-between` y no una grilla de dos columnas porque los
   dos bloques miden lo que miden y no hay tercero que alinear. */
.pie {
  border-top: var(--gd-filete) solid var(--gd-grafito);
  margin-top: calc(var(--gd-u) * 10);
  padding: calc(var(--gd-u) * 3) 0 calc(var(--gd-u) * 6);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--gd-u) calc(var(--gd-u) * 3);
}

/* Los iconos, del tamano que ya tienen en el pie del home. El area de toque la
   da el propio enlace: 44px de alto, que es el minimo, sin agrandar el dibujo. */
/* LA FIRMA EN NEGRITA. Se probo con una tira a cuadros debajo —la bandera del
   equipo— y pesaba mas que el propio pie: un pie es una firma, no un cartel.
   La negrita alcanza para que la division se lea como marca y no como letra
   chica, y no agrega un elemento nuevo a la pantalla. */
.pie__firma { font-weight: 700; color: var(--gd-negro); }

/* `row-reverse` y no dar vuelta la lista del vocabulario: el orden del
   documento sigue siendo el del pie del home —Instagram primero—, que es el que
   recorren el teclado y un lector de pantalla. Lo que cambia es donde caen:
   YouTube a la izquierda del grupo, Instagram contra el margen. */
.pie__redes {
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
  gap: calc(var(--gd-u) * 2);
}
.pie__redes a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  color: var(--gd-grafito);
}
.pie__redes .icono--marca { width: 20px; height: 20px; }

.pie__redes a:hover { color: var(--gd-rojo); }
.pie__redes .icono--marca { width: 20px; height: 20px; }

/* La division y el lema, que antes iban debajo del logo. Ocupan el ancho
   entero del pie: tres columnas con la cruz al medio, para que caiga en el eje
   sin importar cuanto midan los dos textos. */
.pie__marca {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--gd-u) calc(var(--gd-u) * 3);
  margin-bottom: calc(var(--gd-u) * 2);
}

.pie__marca > :last-child { text-align: right; }

/* --------------------------------------------------------------------------
   DIRECCION DE CARRERA — la pagina de contacto.

   Reemplaza a DIVISIONES, que era un indice de una taxonomia que nadie iba a
   usar para buscar un tema. Misma gramatica que la ficha: rotulos en gris,
   valores en grafito, filetes de una linea. Ni un color nuevo.
   -------------------------------------------------------------------------- */

.contacto__bajada {
  margin: calc(var(--gd-u) * 2) 0 0;
  max-width: 52ch;
  line-height: 1.6;
}

.contacto {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: calc(var(--gd-u) * 3) calc(var(--gd-u) * 6);
  margin-top: calc(var(--gd-u) * 5);
}

.contacto__bloque .especificacion { margin-top: var(--gd-u); }

.contacto__bloque a {
  border-bottom: var(--gd-filete) solid var(--gd-grafito);
  padding-bottom: 1px;
}

.contacto__bloque a:hover { color: var(--gd-rojo); border-color: var(--gd-rojo); }

.contacto__motivos {
  list-style: none;
  margin: var(--gd-u) 0 0;
  padding: 0;
  border-top: var(--gd-filete) solid var(--gd-grafito);
}

.contacto__motivos li {
  padding: 12px 0;
  border-bottom: var(--gd-filete) solid var(--gd-aluminio);
  line-height: 1.5;
}

.contacto__orden {
  margin-top: calc(var(--gd-u) * 6);
  padding-top: calc(var(--gd-u) * 2);
  border-top: var(--gd-filete) solid var(--gd-grafito);
  max-width: 62ch;
}

.contacto__orden p { margin: var(--gd-u) 0 0; line-height: 1.6; }

/* ==========================================================================
   LAS DOS VISTAS DEL CATALOGO — FICHAS y AUDICION
   ==========================================================================

   FICHAS es la grilla de documentos de arriba. AUDICION es una lista densa, una
   fila por track, para escuchar mucho y elegir rapido: play, titulo, onda,
   duracion, precio y toggle del BOX, todo en la misma linea y sin navegar.

   Ni un color nuevo: la paleta sigue teniendo siete valores. El amarillo
   aparece una sola vez y sobre grafito —el empujon por volumen de la barra de
   total, a 14.19:1—, que es exactamente la superficie oscura donde la regla 7
   lo permite. El rojo se usa como grafico (filetes, rellenos, la cabeza de
   lectura) y nunca coloreando texto chico.
   -------------------------------------------------------------------------- */

/* EL SELECTOR DE VISTA — una llave de dos posiciones, no dos pestanas.
   -------------------------------------------------------------------------
   Vive en el renglon del titulo, contra el borde derecho (.portada--consolapas).

   Un solo bloque AMARILLO se DESLIZA entre las dos posiciones. Dos fondos que
   prenden y apagan se leen como dos cosas; un bloque que se mueve se lee como
   una sola, que es lo que es: una vista o la otra.

   Es el mismo amarillo del boton de compra, y por el mismo motivo: negro
   #0E0E0C sobre amarillo #FEEB03 da 15.7:1. La regla 7 prohibe el amarillo como
   COLOR DE TEXTO sobre fondo claro —ahi da 1.09:1 y desaparece—; de superficie
   con la letra en negro es al reves, es lo mas legible del sistema. Lo que lo
   sostiene contra el fondo crema es el filete negro de 2px, sin el cual el
   bloque amarillo flotaria sin borde.

   Las dos columnas miden IGUAL. De eso depende que `translateX(100%)` caiga
   exacto sobre la segunda: con columnas de ancho distinto habria que medir en
   JavaScript. */
.selector {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: 0;
  /* Filete de 2px y esquina de 2px: las mismas senales que .boton. En un
     sistema donde todo tiene filetes de 1px, el de 2px es lo que dice
     "esto se aprieta". */
  border: 2px solid var(--gd-negro);
  border-radius: 2px;
}

/* Lo mueve `body[data-vista]`, que ya escribe vista.js. `inset` con 50% a la
   derecha le da exactamente media llave de ancho. */
.selector__marca {
  position: absolute;
  inset: 0 50% 0 0;
  border-radius: 1px;
  background: var(--gd-amarillo);
  transition: transform var(--gd-motion) cubic-bezier(0.2, 0, 0, 1);
}

body[data-vista='audicion'] .selector__marca { transform: translateX(100%); }

.selector__solapa {
  appearance: none;
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 9px 18px;
  border: 0;
  background: none;
  color: var(--gd-gris);
  font-family: var(--gd-tecnica);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--gd-motion) linear;
}

.selector__solapa:hover { color: var(--gd-grafito); }

.selector__solapa[aria-selected='true'] {
  color: var(--gd-negro);
  font-weight: 700;
}

/* EL LLAMADO — un vumetro de tres barras rojas al lado de la palabra.
   -------------------------------------------------------------------------
   Titila en rojo, que es donde el rojo funciona: como GRAFICO. La palabra
   misma no cambia de color —10px en rojo sobre crema da 3.71:1 y no llega a
   AA, que es la regla 7— asi que el que titila es el dibujo, no el texto.

   Tres barras, tres duraciones primas entre si (740 / 910 / 1130 ms): nunca
   vuelven a coincidir, asi que el movimiento no se repite a la vista y parece
   una senal, no un loop. Se apagan solas cuando ESCUCHA pasa a ser la vista
   activa —ya llego, no hay a donde llamar— y la regla global de
   prefers-reduced-motion las deja quietas. */
.vu {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 9px;
}

.vu i {
  width: 2px;
  height: 100%;
  background: var(--gd-rojo);
  transform-origin: 50% 100%;
  animation: gd-vu 740ms ease-in-out infinite alternate;
}

.vu i:nth-child(2) { animation-duration: 910ms; }
.vu i:nth-child(3) { animation-duration: 1130ms; }

@keyframes gd-vu {
  from { transform: scaleY(0.25); }
  to   { transform: scaleY(1); }
}

/* Llego: el vumetro se apaga y la solapa queda quieta. */
.selector__solapa[aria-selected='true'] .vu { display: none; }

.aud__nota { margin: calc(var(--gd-u) * 2) 0 0; }

/* EL CARRIL NO EXISTE EN ESCRITORIO. `display: contents` lo borra del
   layout y las paginas quedan una debajo de otra: la misma lista de siempre,
   con el mismo filete entre filas. Es el mismo truco que usa `.grilla__pagina`. */
.aud-carril { display: contents; }

.aud-lista {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Fila compacta: que entren muchas en pantalla. La onda se lleva el ancho
   sobrante, que es el unico elemento que gana algo con el. */
/* El play va PEGADO a la onda, no en el extremo de la fila: son el mismo
   control partido en dos —uno arranca, la otra busca— y con el titulo en el
   medio se leian como dos cosas distintas. */
.aud {
  display: grid;
  grid-template-columns: minmax(120px, 1.2fr) auto minmax(0, 2fr) auto auto auto;
  align-items: center;
  gap: calc(var(--gd-u) * 2);
  padding: 5px 0;
  border-bottom: var(--gd-filete) solid var(--gd-aluminio);
  transition: background-color var(--gd-motion) linear;
}

.aud:hover,
.aud:focus-within { background: var(--gd-aluminio); }

.aud__play {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: var(--gd-filete) solid var(--gd-negro);
  border-radius: 2px;
  /* Negro con el glifo en amarillo: la unica forma de que el amarillo del logo
     exista en una lista sobre blanco calido. Sobre el fondo claro daria 1.09:1;
     aca da 14.19:1. */
  background: var(--gd-negro);
  color: var(--gd-amarillo);
  cursor: pointer;
  transition: background-color var(--gd-motion) linear,
              border-color var(--gd-motion) linear,
              color var(--gd-motion) linear;
}

.aud__play:hover { background: var(--gd-rojo); border-color: var(--gd-rojo); color: var(--gd-blanco); }
.aud__play .icono--pausa { display: none; }

.aud__play[data-sonando='1'] {
  background: var(--gd-rojo);
  border-color: var(--gd-rojo);
  color: var(--gd-blanco);
}

.aud__play[data-sonando='1'] .icono--play { display: none; }
.aud__play[data-sonando='1'] .icono--pausa { display: inline; }

.aud__texto { display: grid; gap: 2px; min-width: 0; }

.aud__titulo {
  font-size: 13px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.aud__artista {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* LA ONDA. Es la del TEASER: los 90 segundos que se previsualizan, no el track
   entero. `object-fit: fill` a proposito —no `cover`— porque el mapa entre el
   pixel y el segundo tiene que ser exacto: donde se hace clic es donde salta. */
.aud__onda {
  position: relative;
  display: block;
  height: 30px;
  overflow: hidden;
  border: var(--gd-filete) solid var(--gd-aluminio);
  background: var(--gd-blanco);
  cursor: pointer;
  /* ARRASTRAR PARA BUSCAR, SIN PERDER EL SCROLL.
     `pan-y` le deja al navegador el desplazamiento vertical —bajar la pagina
     con el dedo apoyado sobre una onda tiene que seguir bajando la pagina— y
     nos entrega el horizontal, que es el unico eje que la onda usa. Con
     `none` el arrastre andaria igual pero la lista quedaria trabada; sin nada,
     el navegador se queda con los dos y el arrastre no existe en telefono. */
  touch-action: pan-y;
}

.aud__onda img { display: block; width: 100%; height: 100%; object-fit: fill; }

/* La cabeza de lectura. El valor por defecto la deja en -2%, o sea afuera del
   recuadro, que es como se esconde en las filas que no suenan sin depender de
   un selector de padre. player.js escribe --avance solo en la fila actual. */
.aud__cabeza {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--gd-rojo);
  left: calc(var(--avance, -0.02) * 100%);
}

.aud__dur,
.aud__precio {
  color: var(--gd-grafito);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.aud__precio { letter-spacing: 0.12em; }

/* El toggle del BOX de la fila. Es chico, asi que el estado NO se dice con
   texto rojo ni con relleno rojo: se dice con relleno grafito (14.19:1) y un
   filete rojo adentro, que es grafico y no texto. */
/* EL BOTON DE SUMAR ES LA CRUZ DE LA MARCA.
   La cruz del logo ya es un signo mas: usarla de boton de agregar no es un
   adorno, es el significado que la forma tenia desde el principio. Sin texto:
   el nombre accesible va en aria-label, asi la fila queda mas corta y entran
   mas temas en pantalla, que es el punto de esta vista. */
.aud__box {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 2px solid var(--gd-negro);
  border-radius: 2px;
  /* Fondo rojo, cruz amarilla, borde negro: los tres colores del logo en la
     misma pieza. Es el unico boton de la lista que le suma plata al total del
     comprador, asi que que grite un poco esta bien. */
  background: var(--gd-rojo);
  color: var(--gd-amarillo);
  cursor: pointer;
  transition: background-color var(--gd-motion) linear,
              border-color var(--gd-motion) linear,
              color var(--gd-motion) linear;
}

.aud__box svg { width: 17px; height: 17px; overflow: visible; }

.aud__box:hover { background: var(--gd-negro); }

/* YA SUMADO: CAMBIA DE COLOR, NO DE ANGULO.
   La version anterior giraba la cruz 45 grados para que la misma pieza dijera
   "sumar" y "sacar" segun su rotacion. Es ingenioso y no se entiende: una cruz
   torcida se lee como una equis de cerrar, y en una fila donde el mismo boton
   acaba de sumar algo, eso confunde. El estado se dice con el color —rojo que
   grita cuando falta, grafito apagado cuando ya esta— que es lo que el resto de
   la lista tambien hace. */
.aud__box[aria-pressed='true'] {
  background: var(--gd-negro);
  color: var(--gd-amarillo);
}

.aud__box:hover { border-color: var(--gd-rojo); }

.aud__box[aria-pressed='true'] {
  background: var(--gd-grafito);
  color: var(--gd-blanco);
  box-shadow: inset 3px 0 0 var(--gd-rojo);
}

/* La marca de FICHAS: la tarjeta dice que la pieza ya esta en el BOX, para que
   las dos vistas cuenten lo mismo en el mismo instante. No agrega ni saca. */
.doc__enbox {
  position: absolute;
  left: 0;
  bottom: 0;
  z-index: 2;
  display: none;
  padding: 5px 9px;
  background: var(--gd-grafito);
  color: var(--gd-blanco);
  font-size: 9px;
  letter-spacing: 0.2em;
}

.doc[data-en-box='1'] .doc__enbox { display: block; }

/* --------------------------------------------------------------------------
   LA BARRA DE TOTAL — el empujon por volumen, mientras elige.

   Fija, arriba del reproductor. Todos los numeros vienen de /api/cotizar: el
   navegador no calcula plata (regla 5). Sobre grafito, que es donde el amarillo
   del logo vive.
   -------------------------------------------------------------------------- */

.totalbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 45;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(var(--gd-u) * 3);
  padding: 10px var(--gd-margen);
  border-top: 2px solid var(--gd-rojo);
  background: var(--gd-grafito);
  color: var(--gd-blanco);
}

.con-reproductor .totalbar { bottom: var(--gd-reproductor); }

/* Sobre grafito el foco va en amarillo, como en el reproductor. */
.totalbar :focus-visible { outline-color: var(--gd-amarillo); }

.totalbar__linea {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--gd-u) calc(var(--gd-u) * 3);
  margin: 0;
  min-width: 0;
}

.totalbar__piezas,
.totalbar__ajuste { color: var(--gd-aluminio); }

.totalbar__cifra {
  font-family: var(--gd-display);
  font-size: 22px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* EL EMPUJON. Amarillo sobre grafito: 14.19:1. Es el unico texto amarillo del
   sistema y su fondo oscuro esta a dos reglas de distancia, aca arriba. */
.totalbar__guino {
  display: grid;
  gap: 2px;
}

/* El guiño va SIN mayusculas y sin letter-spacing: es la unica linea de toda la
   tienda que habla como una persona y no como un parte tecnico. En VERSALITA y
   espaciada sonaria a aviso de sistema, que es justo lo contrario. */
.totalbar__empuje {
  font-family: var(--gd-tecnica);
  font-size: 13px;
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--gd-amarillo);
}

.totalbar__detalle {
  font-size: 10px;
  color: var(--gd-aluminio);
}

.totalbar__empuje:empty,
.totalbar__ajuste:empty,
.totalbar__cifra:empty { display: none; }

.totalbar .boton {
  flex: 0 0 auto;
  min-height: 40px;
  padding: 0 20px;
  border-color: var(--gd-blanco);
  background: var(--gd-blanco);
  color: var(--gd-grafito);
}

/* Con la barra de total puesta hay dos superficies fijas abajo: la ultima fila
   no puede quedar debajo de las dos. */
body[data-vista='audicion'].con-reproductor {
  padding-bottom: calc(var(--gd-reproductor) + var(--gd-totalbar));
}

/* El contador flotante del BOX diria lo mismo que la barra, y encima arriba.
   En AUDICION manda la barra. */
body[data-vista='audicion'] .box-flotante { display: none; }

/* --------------------------------------------------------------------------
   RESPONSIVE — el sistema colapsa a una columna, nunca se centra.
   La capa de escucha ya nace centrada y angosta: a 375px no cambia nada.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .ficha { grid-template-columns: minmax(0, 1fr); }
  .ficha__arte { border-right: 0; padding-right: 0; border-bottom: var(--gd-filete) solid var(--gd-grafito); }
  .ficha__datos { padding-left: 0; }
  .portada { grid-template-columns: minmax(0, 1fr); }
  .portada__izq { border-right: 0; padding-right: 0; }
  .portada__centro { grid-column: 1 / 2; }
  .marco { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cabecera { grid-template-columns: minmax(0, 1fr); }
  .cabecera__nav { justify-content: flex-start; }
}

@media (max-width: 560px) {
  .marco__celda:nth-child(3),
  .marco__celda:nth-child(4) { text-align: left; }
  .pie { grid-template-columns: minmax(0, 1fr); }
  .pista { grid-template-columns: 56px minmax(0, 1fr) auto auto; gap: var(--gd-u); }
  .pista__arte { --arte: 56px; }
  .pista__titulo { font-size: 13px; }
  .menu { gap: calc(var(--gd-u) * 2); }

  /* En telefono no entra todo en una linea: la fila se dobla en dos y la onda
     cruza el ancho abajo, con la duracion y el precio a su derecha. Sigue
     siendo una fila por track, y no se pierde ningun dato. */
  .aud {
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    grid-template-areas:
      'texto texto texto box'
      'play  onda  dur   precio';
    gap: var(--gd-u);
    padding: 8px 0;
  }

  .aud__play { grid-area: play; }
  .aud__texto { grid-area: texto; }
  .aud__onda { grid-area: onda; }
  .aud__dur { grid-area: dur; }
  .aud__precio { grid-area: precio; }
  .aud__box { grid-area: box; }
  .totalbar { flex-wrap: wrap; }

  /* AUDICION EN TELEFONO — la pantalla que la herramienta de auditoria no ve.
     `capturar.mjs` mide la pagina como llega, y AUDICION solo aparece si
     alguien toca la solapa: por eso sus blancos de toque nunca figuraron en el
     informe. Medidos a mano: play 30x30, BOX 38x38, onda 120x30.

     Cuatro columnas no entran en 320px con todo a 44. Con tres —el precio
     arriba a la derecha, los controles abajo— el play y el BOX llegan a 44 y la
     onda pasa de 120x30 a 148x44, que es la unica superficie de esta vista que
     de verdad se arrastra.

     La DURACION se va, por el mismo motivo que se fue de la lista de la home:
     esta en la ficha y en el reloj del reproductor mientras el tema suena. */
  .aud {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      'texto texto precio'
      'play  onda  box';
    padding: 10px 0;
  }

  .aud__dur { display: none; }
  .aud__play { width: 44px; height: 44px; }
  .aud__box { width: 44px; height: 44px; }
  /* La banda de la ficha usa el mismo componente y NO se toca: sus reglas
     llevan las dos clases (`.aud.muestra__banda .aud__onda`) y le ganan a
     estas de una sola. Ahi la onda ya mide 96px y el play 72. */
  .aud__onda { height: 44px; }
}

/* ==========================================================================
   TELEFONO — el encargo: «limpio y simple».
   ==========================================================================

   Lo de arriba ya colapsaba el sistema a una columna. Esto es otra cosa: es la
   pantalla chica tratada como su propio caso, con tres criterios y no con
   ajustes sueltos.

   1. TODO LO QUE SE TOCA MIDE 44px. Es el minimo de Apple y no es una opinion:
      la navegacion entera media 17px de alto. No se agranda la letra hasta que
      la caja llegue —eso rompe la tipografia del sistema—: se le da altura a la
      caja y el texto se centra adentro.
   2. MENOS ELEMENTOS, NO ELEMENTOS MAS CHICOS. En telefono se van la duracion
      de la lista de la home y la frase que invita a cambiar de vista: la
      primera esta impresa en la portada de cada fila, la segunda repite lo que
      ya hacen las solapas, que estan tres centimetros mas arriba.
   3. NADA DE ESTO EXISTE EN ESCRITORIO. Todo va adentro de la consulta de
      medio: el escritorio queda pixel por pixel como estaba.
   ========================================================================== */

@media (max-width: 560px) {
  /* LA LISTA DE ESCUCHA SCROLLEA POR DENTRO.
     La cola tiene los 20 temas del catalogo —quien pone play y deja el
     telefono escucha un rato largo—, pero en pantalla se ven solo los que
     entran SIN hundir el boton de la tienda.

     El alto no es un numero de filas fijo: es lo que sobra despues de la
     cabecera, el logo y el boton. Medido, eso da ~4 filas en un iPhone 13 y
     ~3 en un SE, que es lo correcto: "las que entran".

     `dvh` y no `vh`: en Safari de iOS `100vh` es el viewport GRANDE, el que
     ignora la barra de herramientas, asi que con `vh` la lista se pasaba de
     largo justo en el aparato que menos espacio tiene. La linea de `vh` queda
     como respaldo para navegadores sin `dvh`.

     `overscroll-behavior: contain` evita el encadenado: al llegar al final de
     la lista el gesto NO sigue scrolleando la pagina. */
  .pistas {
    max-height: calc(100vh - 360px);
    max-height: calc(100dvh - 360px);
    min-height: 154px;              /* dos filas: nunca colapsa */
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }

  /* El boton de la tienda, mas chico. El PISO es 18.66px en negrita: el
     amarillo sobre rojo da 3.40:1 y eso pasa AA solo como texto grande. Por
     debajo de ese cuerpo habria que cambiarle el color, y un color nuevo no
     entra en los 7 hex. 19px deja margen. El alto no baja de 44 porque es
     blanco de toque. */
  .calco__enlace { font-size: 19px; padding: 12px 24px; }

  /* ------------------------------------------------------------------------
     NAVEGACION — el problema mas grande que tenia el telefono.
     Los tres enlaces median 32x17, 144x17 y 64x17, y el boton del carrito
     99x28. La caja crece a 44 con `min-height` y el texto se centra: la
     tipografia no cambia de escala, cambia el area. Sube de 10px a 12px, que
     es el minimo para leer una version en un telefono sin acercar.

     EL FILETE DE LA PAGINA ACTIVA SE QUEDA. Se propuso esconder el enlace de
     la pagina en la que uno esta para ganar ancho: con 44px de alto los tres
     entran igual, y perder el «estas aca» a cambio de nada no es un negocio.
     ------------------------------------------------------------------------ */
  /* `min-width` y no `padding`: 44px es un cuadrado, y HOME mide 30 de ancho.
     Con padding el filete de la pagina activa se estiraria mas alla de la
     palabra; con min-width + centrado el texto queda en el medio de su celda y
     el filete la subraya entera, que es como se lee una solapa. */
  .cabecera__nav a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding-bottom: 0;
    border-bottom-width: 2px;
    font-size: 12px;
    letter-spacing: 0.1em;
  }

  .cabecera__carrito {
    min-height: 44px;
    padding: 0 6px;
    font-size: 12px;
  }

  /* El nav de la capa de escucha es otro selector —.menu, no .cabecera__nav—
     pero el problema es el mismo: 21px de alto y 12px de letra. */
  .menu {
    gap: calc(var(--gd-u) * 2);
    font-size: 13px;
    padding-top: var(--gd-u);
  }

  .menu a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding-bottom: 0;
  }

  /* ------------------------------------------------------------------------
     REPRODUCTOR — los mandos a 44 y la variable que por fin dice la verdad.

     Los tres botones median 34x34. A 44 el reproductor pasa a medir
     10 + 44 + 6 + 20 + 8 = 88px, y `--gd-reproductor` vale exactamente eso:
     hasta ahora reservaba 104 para una barra de 82, o sea 22px de aire que
     nadie pidio y que en una pantalla de 667px es el 3 %.
     ------------------------------------------------------------------------ */
  :root {
    /* 62px MEDIDOS, no calculados. La cuenta de arriba —10+44+6+20+8=88— era
       correcta cuando el reloj vivia en su propio renglon; en este mismo bloque
       el reloj bajo al renglon de los mandos y nadie volvio a medir la barra.
       Quedaban 26px de reserva fantasma en TODA la tienda: la barra de total y
       el cartel del carrito flotaban esa distancia arriba del reproductor, y el
       pie de la segunda pantalla tambien. */
    --gd-reproductor: 62px;
    /* La barra de total envuelve en dos lineas abajo de 560px (`flex-wrap`
       arriba), asi que mide mas que en escritorio. Medido en iPhone SE: 100px. */
    --gd-totalbar: 100px;
  }

  .reproductor { padding: 10px var(--gd-margen) 8px; }
  .mando { width: 44px; height: 44px; }

  /* EL RELOJ BAJA AL RENGLON DE LA BARRA. Y no es cosmetico: MEDIDO en 320px,
     con los mandos a 44 la fila de arriba queda con 144px de botones + 85 de
     reloj + 24 de separaciones, y al titulo de lo que suena le sobraban 27px.
     El reproductor decia «A…». Un reproductor que no dice que tema esta
     sonando no cumple la unica regla de esta pantalla.

     Con el reloj abajo, a la derecha de la barra:
       renglon 1 · mandos (144) + titulo (124)
       renglon 2 · barra (183) + reloj (85)
     y el alto sigue siendo 10 + 44 + 6 + 20 + 8 = 88, o sea el valor exacto de
     --gd-reproductor. La barra pierde 97px de recorrido y el titulo gana 97:
     el recorrido de un teaser de 90 segundos sigue teniendo 183px, medio
     segundo por pixel. */
  .reproductor__caja {
    grid-template-areas:
      'mandos ahora ahora'
      'barra  barra tiempo';
  }

  /* Partido en dos nodos desde construir.mjs: el total se pone en aluminio para
     que el corriente —lo unico que cambia— sea lo que se lee. */
  .reproductor__total { color: var(--gd-aluminio); }

  /* ------------------------------------------------------------------------
     LA LISTA DE LA HOME — dos cambios, los dos de sustraccion.
     ------------------------------------------------------------------------ */

  /* La duracion se va. Ya esta impresa sobre la portada de cada fila, que es
     donde funciona como textura, y en el reloj del reproductor cuando el tema
     suena. En 320px de ancho era la columna que apretaba el titulo. */
  .pista__meta { display: none; }
  .pista { grid-template-columns: 56px minmax(0, 1fr) auto; }

  /* El artista pasa a grafito. En gris industrial sobre el blanco calido da
     2.94:1 y no llega a AA para 11px; es el dato que dice de que tema se
     trata, asi que no puede ser el que peor se lee de la fila. */
  .pista__artista { color: var(--gd-grafito); }
  .doc__artista { color: var(--gd-grafito); }

  /* El pie de la home sube de 10px a 11px. */
  .pie-simple { font-size: 11px; }

  /* ------------------------------------------------------------------------
     GRILLA DEL CATALOGO — dos columnas.
     Con `auto-fill minmax(240px)` a 375px entra UNA sola: seis piezas son seis
     pantallas de scroll para ver un catalogo que se entiende de un vistazo. A
     dos columnas la portada mide ~160px, que sigue siendo una portada.
     ------------------------------------------------------------------------ */
  .grilla {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: calc(var(--gd-u) * 3) calc(var(--gd-u) * 2);
  }

  /* El play sobre la portada media 68px sobre un cuadro de 335: sobre uno de
     160 tapaba la mitad del arte. */
  .doc__play { width: 48px; height: 48px; }
  .doc__play .icono { width: 16px; height: 16px; }

  /* El bloque de titulo + artista media 37px de alto y es un enlace. */
  .doc__enlace { padding-bottom: calc(var(--gd-u) * 1.5); }
  .doc__titulo { font-size: 13px; }

  /* Las dos solapas median 113x32. */
  .selector__solapa { min-height: 44px; }

  /* LA FRASE QUE INVITA A CAMBIAR DE VISTA SE VA.
     Dice lo mismo que las dos solapas, que estan arriba de la lista y siempre
     a la vista. En escritorio es el cierre de la pantalla y ahi se queda; en
     telefono es una banda entre dos filetes al final de un scroll largo, con
     un boton de 61x22 adentro. No se pierde ningun camino: el tablist sigue. */
  .invita { display: none; }

  /* ------------------------------------------------------------------------
     FICHA — comprimida, no achicada.
     A 900px ya colapsa a una columna. Lo que sobra en telefono es AIRE: entre
     el arte y los datos habia 48px, la especificacion reservaba 15ch fijos
     para el rotulo y cada renglon tenia 18px de padding vertical.
     ------------------------------------------------------------------------ */
  .ficha {
    margin-top: var(--gd-u);
    margin-bottom: calc(var(--gd-u) * 3);
  }

  .ficha__arte { padding-bottom: calc(var(--gd-u) * 2); }
  .ficha__datos { padding-top: calc(var(--gd-u) * 2); }

  .especificacion { margin-top: calc(var(--gd-u) * 2); }

  .especificacion > div {
    grid-template-columns: minmax(88px, 11ch) minmax(0, 1fr);
    gap: 4px calc(var(--gd-u) * 2);
    padding: 7px 0;
  }

  /* LA LINEA DE COMPRA SE APILA, Y EL BOTON VA ABAJO Y ANCHO.
     `wrap-reverse` ya dejaba el precio arriba, pero el boton quedaba del ancho
     de su texto y contra el borde izquierdo. En telefono el unico primario de
     la pantalla ocupa el ancho: es el gesto mas facil que existe con el pulgar
     y ademas es lo ultimo que se lee antes de decidir. */
  .compra {
    flex-direction: column-reverse;
    align-items: stretch;
    gap: calc(var(--gd-u) * 2);
  }

  .compra .boton { width: 100%; }
  .compra .precio__cifra { text-align: left; }

  /* El «← CATÁLOGO» del pie de la ficha medía 239x12. */
  .volver a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* ------------------------------------------------------------------------
     CARRITO — de globo colgado del boton a hoja pegada abajo.
     Como `position: absolute` colgaba de la cabecera, con tres piezas adentro
     el popup se iba hacia abajo de la pantalla y el boton de PAGAR quedaba
     fuera de vista, sin forma de llegar salvo scrollear la pagina de atras.
     Anclado abajo: la lista scrollea sola y el total y el boton no se mueven.
     ------------------------------------------------------------------------ */
  .carritopop {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    top: auto;
    z-index: 60;
    width: auto;
    max-height: 82vh;
    margin: 0;
    display: flex;
    flex-direction: column;
    border-width: 2px 0 0;
  }

  .carritopop__lista {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }

  .carritopop__pie { flex: 0 0 auto; }

  .carritopop__cerrar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0;
  }

  .carritopop__quitar { width: 44px; height: 44px; }

  /* ------------------------------------------------------------------------
     FORMULARIO Y ENLACES SUELTOS
     ------------------------------------------------------------------------ */

  /* 16px NO ES ESTETICA: abajo de 16 iOS hace zoom solo al enfocar un campo, y
     al volver la pagina queda corrida. Con 16 no pasa nada. De paso el campo
     llega a 44 de alto, que medía 43. */
  .campo {
    font-size: 16px;
    min-height: 44px;
    letter-spacing: 0.04em;
  }

  /* El mail de contacto medía 151x14 y los enlaces de redes 65x14 y 50x14.
     `flex-end` y no `center`: estos enlaces llevan el subrayado como unica
     senal de que se pueden tocar, y centrados en una caja de 44px el filete
     quedaba diez pixeles abajo del texto, leyendose como una linea suelta. Con
     el texto apoyado en el piso de la caja el subrayado vuelve a pegarse a la
     palabra y los 44px crecen hacia arriba, donde no hay nada. */
  .contacto__bloque a,
  .salida a {
    display: inline-flex;
    align-items: flex-end;
    min-height: 44px;
  }

  .contacto__bloque a { word-break: break-word; }

  /* ------------------------------------------------------------------------
     EL AIRE DEL FINAL. La hoja reservaba 72px abajo y el pie sumaba 80 mas de
     margen: 152px de blanco entre el ultimo dato y la letra chica de la marca,
     que en una pantalla de 568px es un cuarto de pantalla de nada. En
     escritorio ese aire es el margen de un documento y se queda.
     ------------------------------------------------------------------------ */
  .hoja { padding: calc(var(--gd-u) * 3) 0 calc(var(--gd-u) * 4); }
  .pie { margin-top: calc(var(--gd-u) * 5); padding-bottom: calc(var(--gd-u) * 4); }
  .briefing { margin-top: calc(var(--gd-u) * 6); }
}

/* --------------------------------------------------------------------------
   320px — el iPhone SE, que sigue siendo el piso.
   A 12px y con `gap: 24px` los cuatro elementos del nav de la tienda no entran
   en un renglon y el carrito se cae solo a la segunda linea. Un punto menos de
   cuerpo y la mitad del gap lo resuelven sin sacar nada.
   -------------------------------------------------------------------------- */
@media (max-width: 380px) {
  /* MEDIDO: los cuatro elementos suman 245px y la fila mide 280. Con `gap: 12`
     dan 281 y el carrito se cae solo a un segundo renglon — por un pixel. Con 8
     sobran once y la navegacion entra entera en una linea. */
  .cabecera__nav {
    gap: var(--gd-u);
  }

  .cabecera__nav a,
  .cabecera__carrito {
    font-size: 11px;
    letter-spacing: 0.06em;
  }

  .cabecera__carrito { gap: 5px; padding: 0 4px; }
}

/* Accesible pero fuera de pantalla — reaparece al enfocar con teclado. */
.oculto {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.oculto:focus {
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
  clip-path: none;
  display: inline-block;
  margin: 8px var(--gd-margen);
  padding: 10px 16px;
  border: var(--gd-filete) solid var(--gd-grafito);
  border-radius: 2px;
  font-size: 10px;
  letter-spacing: 0.22em;
}

/* ---------------------------------------------------------------------------
   LOS 58 PIXELES DE LA CUARTA FILA
   Con la lista mostrando filas ENTERAS y aire parejo, en un iPhone 15 entraban
   tres. Los que faltaban para la cuarta salieron de tres lugares, ninguno de
   los cuales pierde funcion: 8px por fila en vez de 12, el logo un escalon mas
   chico, y menos aire arriba del boton de la tienda.
   Va al final del archivo a proposito: los bloques de arriba ya declaran estas
   mismas propiedades y aca tienen que ganar.
   --------------------------------------------------------------------------- */
@media (max-width: 560px) {
  .pista { padding: 8px 0; }
  .marca-chica img { width: clamp(170px, 52vw, 200px); }
  .calco { padding-top: calc(var(--gd-u) * 2); }
}

/* EL SEPARADOR DE FILAS, INVERTIDO EN TELEFONO.
   Con `border-bottom` la ultima fila visible dejaba su hairline gris justo
   arriba de la regla negra que cierra la lista: dos lineas juntas diciendo lo
   mismo. Pasandolo a `border-top` —y sacandoselo a la primera— el separador
   siempre queda ENTRE dos filas y nunca al borde de la caja, en cualquier
   posicion del scroll y sin una linea de JavaScript.
   Solo en telefono: en escritorio no hay regla de cierre, y ahi el borde de
   abajo de la ultima fila es lo que termina el listado. */
@media (max-width: 560px) {
  .pista { border-bottom: 0; border-top: var(--gd-filete) solid var(--gd-aluminio); }
  .pista:first-child { border-top: 0; }
}

/* EL HOME TERMINA EN EL BOTON.
   En telefono se van el pie y la fila de plataformas: la pagina pasa a ser UNA
   sola pantalla, sin scroll, que es lo que "limpia y simple" quiere decir acá.
   Se van con `display:none` y no del HTML: en escritorio siguen estando, y los
   enlaces siguen en el marcado para los lectores de pantalla que recorren el
   documento y para el feed.
   LO QUE SE PIERDE, y hay que saberlo: en telefono no hay forma de llegar a
   Spotify ni a YouTube desde el home. Si eso importa, el lugar donde viven
   mejor es /tienda/contacto/, que ya es la pagina de "donde encontrarme". */
@media (max-width: 560px) {
  body.escucha .pie-simple,
  body.escucha .plataformas { display: none; }
  /* Ajustado al hueso: con el aire de antes el documento medía 668 contra 659
     de pantalla y la cuarta fila se caía por NUEVE pixeles. */
  body.escucha .calco { padding-top: calc(var(--gd-u) * 1.5); padding-bottom: var(--gd-u); }
  /* Sin pie ni plataformas debajo, el relleno inferior de la hoja son 32px de
     nada que empujaban la pagina fuera de la pantalla. El aire de abajo lo pone
     el bloque del boton. */
  body.escucha .hoja-simple { padding-bottom: 0; }
}

/* EL SCROLL CAE SIEMPRE EN FILAS ENTERAS.
   Sin esto, al soltar el dedo la fila de abajo quedaba cortada por la regla que
   cierra la lista. Con snap el scroll se detiene solo en los puntos donde el
   borde de una fila coincide con el borde de la caja.
   `scroll-padding-top` tiene que valer lo mismo que el aire de arriba: si no,
   los puntos de anclaje quedan corridos por ese aire y el ultimo tramo —el que
   llega al final de la lista— no coincide con ninguno. */
@media (max-width: 560px) {
  .pistas { scroll-snap-type: y mandatory; }
  .pista { scroll-snap-align: start; }
}

/* LA REGLA Y EL AIRE SALEN DE LA CAJA QUE SCROLLEA.
   La regla era el `border-top` de la lista y el aire su `padding-top`. El
   borde no scrollea, pero el relleno SI: al bajar un poco quedaba una tira de
   14px mostrando el final de la fila anterior, cortada contra la regla.
   Pasan los dos al bloque del logo, que esta justo encima y no scrollea:
   su borde de abajo es ahora la regla, y su margen inferior el aire. */
@media (max-width: 560px) {
  .marca-chica {
    padding-bottom: calc(var(--gd-u) * 3);
    border-bottom: 2px solid var(--gd-negro);
  }
  .pistas { border-top: 0; padding-top: 0; }
}

/* ---------------------------------------------------------------------------
   LA CABECERA DE LA TIENDA EN TELEFONO
   --------------------------------------------------------------------------- */
@media (max-width: 560px) {
  /* El logo al tamaño del home: en la banda ocupaba media pantalla antes de
     que apareciera un solo track. */
  .banda { padding-top: var(--gd-u); padding-bottom: var(--gd-u); }
  .banda__caja a { width: min(100%, 200px); }

  /* Una sola fila: enlaces a la izquierda, carrito contra el margen derecho y
     a la misma altura. `flex-wrap: nowrap` es lo que impedia que el carrito
     se cayera a un renglon propio. */
  .banda .cabecera { margin-top: var(--gd-u); padding: 4px 0; }
  .cabecera { flex-wrap: nowrap; gap: 0; }
  .cabecera__nav { flex-wrap: nowrap; }

  /* El carrito queda en VECTOR SOLO. La palabra CARRITO se lleva 60px de una
     fila que no los tiene, y el pictograma dice lo mismo. El conteo sigue
     porque ese numero SI es informacion: cuantas piezas hay adentro. */
  .cabecera__carrito > span:not(.cabecera__conteo) { display: none; }
  .cabecera__carrito {
    margin-left: auto;
    min-width: 44px;
    justify-content: flex-end;
    padding: 0;
    border: 0;
  }
  .cabecera__carrito .icono { width: 18px; height: 18px; }
}

/* ---------------------------------------------------------------------------
   EL REPRODUCTOR EN TELEFONO
   Los mandos pasan a la IZQUIERDA de la linea de tiempo, ocupando las dos
   filas, y el nombre de lo que suena queda ARRIBA de la barra, desplazandose.
   --------------------------------------------------------------------------- */
@media (max-width: 560px) {
  .reproductor__caja {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      'mandos ahora ahora'
      'mandos barra tiempo';
    gap: 2px calc(var(--gd-u) * 1.5);
    align-items: center;
  }
  .reproductor__mandos { align-self: center; }
}

/* LA MARQUESINA.
   El nombre se escribe dos veces separado por `//` y la cinta se desplaza su
   propio ancho: cuando la primera copia sale por la izquierda, la segunda esta
   exactamente donde arrancaba la primera y el ciclo no se nota.
   La segunda copia la pone el `::after`, no el JS, para que el texto que leen
   los lectores de pantalla siga siendo UNO solo. */
.reproductor__cinta { display: inline-block; white-space: nowrap; }
.reproductor__ahora[data-marquesina='1'] .reproductor__cinta::after {
  content: attr(data-copia);
}
.reproductor__ahora[data-marquesina='1'] .reproductor__cinta {
  animation: gd-marquesina var(--gd-marquesina, 12s) linear infinite;
}
@keyframes gd-marquesina {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
/* Quien pidio menos movimiento no recibe una marquesina en la cara. */
@media (prefers-reduced-motion: reduce) {
  .reproductor__ahora[data-marquesina='1'] .reproductor__cinta { animation: none; }
}

/* ---------------------------------------------------------------------------
   LA GRILLA PAGINADA
   En escritorio el envoltorio de pagina es transparente —`display: contents`—
   y la grilla se comporta EXACTAMENTE como antes: una sola, con auto-fill.
   --------------------------------------------------------------------------- */
.grilla__pagina { display: contents; }

.paginas { display: none; }

@media (max-width: 560px) {
  /* En telefono cada pagina es una lamina y el contenedor un carril. El scroll
     horizontal nativo hace el trabajo: se desliza con el dedo, `scroll-snap`
     lo deja siempre sobre una lamina entera, y tocar un numero es un
     `scrollTo` suave — el mismo movimiento, disparado desde otro lado. */
  .grilla {
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    /* Aire ENTRE laminas. Sin el, al deslizar las portadas de una pagina
       tocaban las de la siguiente y las dos se leian como una sola grilla
       corrida. El paso del carrusel lo mide `paginas.js` sobre los elementos,
       asi que este numero se puede cambiar sin tocar el JavaScript. */
    gap: calc(var(--gd-margen) * 2);
    /* Sin barra visible: en telefono no aporta y roba alto. */
    scrollbar-width: none;
  }
  .grilla::-webkit-scrollbar { display: none; }

  .grilla__pagina {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: calc(var(--gd-u) * 3) var(--gd-u);
    flex: 0 0 100%;
    scroll-snap-align: start;
    list-style: none;
    margin: 0;
    padding: 0;
  }

  /* LOS NUMEROS DE PAGINA.
     Blancos de toque de 44 aunque el numero sea chico: el area la da el
     boton, no la tipografia. */
  .paginas {
    display: flex;
    justify-content: center;
    gap: var(--gd-u);
    margin-top: calc(var(--gd-u) * 3);
  }
  .paginas__n {
    appearance: none;
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    border: 0;
    background: none;
    font-family: var(--gd-mono);
    font-size: 13px;
    letter-spacing: 0.1em;
    color: var(--gd-gris);
    cursor: pointer;
  }
  .paginas__n[aria-current='true'] {
    color: var(--gd-negro);
    text-decoration: underline;
    text-decoration-color: var(--gd-rojo);
    text-underline-offset: 5px;
    text-decoration-thickness: 2px;
  }
}

/* ---------------------------------------------------------------------------
   EL BUSCADOR
   --------------------------------------------------------------------------- */
.lupa {
  appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-left: var(--gd-u);
  padding: 0;
  border: 0;
  background: none;
  color: var(--gd-grafito);
  vertical-align: middle;
  cursor: pointer;
}
.lupa .icono { width: 18px; height: 18px; }
.lupa:hover,
.lupa[aria-expanded='true'] { color: var(--gd-rojo); }

/* EL BUSCADOR OCUPA LA PANTALLA ENTERA.
   No es un panel dentro de la pagina: es una capa que la tapa. Buscar es una
   tarea completa —se entra, se escribe, se elige o se sale— y en un telefono
   competir con el catalogo de fondo solo agrega ruido.
   `position: fixed` con `inset: 0` y fondo OPACO: sin transparencias ni blur,
   que la casa no los usa. */
.buscador {
  position: fixed;
  inset: 0;
  z-index: 80;
  /* APARECE, NO SALTA. Sube 10px y se funde en 160ms: lo justo para que el ojo
     entienda que se abrio una capa encima y no que la pagina cambio de golpe.
     Se mueve la CAPA, que no es ancestro de nadie con `position: fixed`; animar
     un ancestro romperia el anclaje a la pantalla, que es el bug que ya
     aparecio con la animacion de entrada de las paginas. */
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 160ms linear, transform 160ms ease-out;
  display: flex;
  flex-direction: column;
  gap: calc(var(--gd-u) * 2);
  padding: calc(var(--gd-u) * 3) var(--gd-margen) calc(var(--gd-u) * 2);
  background: var(--gd-blanco);
  overflow: hidden;
}
/* El logo arriba y centrado, del mismo tamaño que en el home: es lo unico que
   queda en pantalla ademas del buscador, asi que dice de donde no te fuiste.
   `margin-inline: auto` Y NO `text-align: center`: la hoja pone `display:
   block` a todas las imagenes, y una imagen en bloque no la centra el texto.
   Con el `text-align` solo, el logo quedaba pegado al margen izquierdo. */
.buscador__marca { margin: 0 0 calc(var(--gd-u) * 2); }
.buscador__marca img { width: min(100%, 170px); height: auto; margin-inline: auto; }
/* LA CAJA DE ESCRITURA ES UNA CAJA.
   Un filete solo abajo dejaba la pantalla pelada: con el logo arriba y nada
   mas, no habia donde apoyar el ojo y el campo no se leia como algo para
   escribir. Ahora es un rectangulo de 2px con la lupa adentro —el mismo
   pictograma del boton que la abrio, que ademas explica para que es— y el
   texto al lado. Rectangulo de 2px es la forma que ya tiene todo lo demas:
   la ficha, el sello, los botones.
   LA CRUZ SE VA ARRIBA A LA DERECHA, fuera de la caja y fuera del flujo. Al
   costado del campo quedaba flotando contra el margen sin nada con que
   alinearse, y adentro se leia como "borrar lo escrito" y no como "cerrar".
   Arriba a la derecha es donde se cierra una capa, y ahi no compite con nada.
   Igual se esconde la crucecita nativa de `type=search`: aparece sola al
   escribir, dentro del campo, y dos cruces en una pantalla que tiene un solo
   control es una de mas. */
.buscador__caja {
  display: flex;
  align-items: center;
  gap: var(--gd-u);
  min-height: 52px;
  padding: 0 var(--gd-u);
  border: 2px solid var(--gd-grafito);
  border-radius: 2px;
  background: var(--gd-blanco);
}
.buscador__lupa { flex: 0 0 auto; width: 16px; height: 16px; color: var(--gd-gris); }
.buscador__campo::-webkit-search-cancel-button { display: none; }
/* El placeholder que pone el motor es rgb(169,169,169): 2.09:1 sobre el fondo,
   ni siquiera llega al 3:1 de texto grande. Grafito da 15.47:1 y no agrega un
   hex nuevo a la hoja (guardarrail 3). */
.buscador__campo::placeholder { color: var(--gd-grafito); opacity: 1; }

/* EL FOCO ES LA CAJA, NO UN ANILLO APARTE.
   El campo se enfoca solo al abrir la capa, y un campo de texto enfocado
   SIEMPRE cumple `:focus-visible`, asi que el anillo rojo de la casa quedaba
   dibujado permanentemente alrededor del unico control de la pantalla:
   parecia un error de validacion, y encima duplicaba el borde de la caja.
   El indicador no se saca —hace falta para el teclado—: lo toma la caja, que
   se pone roja entera. `:focus-within` y no `:focus` porque quien se enfoca es
   el input y quien se dibuja es su envoltorio. */
.buscador__campo:focus-visible { outline: none; }
.buscador__caja:focus-within { border-color: var(--gd-rojo); }
.buscador__caja:focus-within .buscador__lupa { color: var(--gd-rojo); }
.buscador__campo {
  flex: 1;
  min-width: 0;
  min-height: 48px;
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--gd-mono);
  /* 16px no es estetico: por debajo de eso iOS hace zoom solo al enfocar. */
  font-size: 16px;
  letter-spacing: 0.08em;
  color: var(--gd-grafito);
}
.buscador__cerrar {
  appearance: none;
  position: absolute;
  /* Absoluta contra la capa: el relleno de arriba NO la mueve, asi que el
     desfase del teclado hay que sumarselo aca tambien o la cruz queda fuera de
     la banda visible. */
  top: calc(var(--gd-u) + var(--gd-desfase, 0px));
  /* Medio margen: los 44px de blanco de toque ya la separan del borde, y con
     el margen entero la cruz quedaba lejos de la esquina. */
  right: calc(var(--gd-margen) / 2);
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  font-size: 24px;
  line-height: 1;
  color: var(--gd-grafito);
  cursor: pointer;
}
/* EL SCROLL ES DE LA LISTA, NO DE LA CAPA.
   Con el scroll en la capa, bajar por los resultados se llevaba puestos el
   campo de escritura y la cruz: la cruz es `absolute` contra la capa, o sea
   contra su caja de RELLENO, y en un contenedor que scrollea eso corre con el
   contenido. Medido en 393x659 con 40 resultados y 300px de scroll: la cruz en
   y=-292 y el campo en y=-166 —se seguia escribiendo a ciegas—. Ahora la
   cabecera se queda quieta y lo unico que corre es la lista.
   `min-height: 0` no es decorativo: un hijo flex no se deja achicar por debajo
   de su contenido si no se lo dicen, y sin eso la lista no scrollea, empuja. */
.buscador__lista {
  flex: 1 1 auto;
  min-height: 0;
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
.buscador__hit {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px var(--gd-u);
  border-bottom: var(--gd-filete) solid var(--gd-aluminio);
  text-decoration: none;
}
.buscador__hit-t {
  font-family: var(--gd-mono);
  font-size: 14px;
  letter-spacing: 0.06em;
  color: var(--gd-grafito);
}
.buscador__hit-a {
  font-family: var(--gd-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  color: var(--gd-grafito);
}
.buscador__vacio {
  margin: var(--gd-u) 0 0;
  font-family: var(--gd-mono);
  font-size: 12px;
  letter-spacing: 0.12em;
  color: var(--gd-gris);
}

@media (max-width: 560px) {
  /* El encabezado del catalogo, con la lupa AL LADO del titulo y no contra el
     borde derecho. El titulo se parte en dos lineas a proposito: a cuerpo
     entero es lo que le da peso al encabezado.
     El `flex: 0 1 auto` es lo que impide que el <h1> se estire y empuje la
     lupa al otro extremo del renglon; sin el, `space-between` la mandaba
     contra el margen, lejos de lo que nombra. */
  .portada--consolapas { justify-content: flex-start; gap: 0 var(--gd-u); }
  .portada--consolapas .disp--l { flex: 0 1 auto; }
  .lupa { margin-left: 0; width: 44px; height: 44px; }
  .lupa .icono { width: 20px; height: 20px; }
}

/* EL SELECTOR DE VISTA, PEGADO A LO QUE CAMBIA.
   Sale del encabezado y se apoya sobre la grilla. Y pierde la caja: dos
   rotulos con el activo subrayado en rojo, el mismo lenguaje que la
   navegacion. La caja de 2px con relleno amarillo pesaba como un boton de
   compra, y esto no compra nada: cambia como se mira. */
.vistas { display: flex; justify-content: flex-end; margin: 0 0 calc(var(--gd-u) * 2); }

@media (max-width: 560px) {
  .vistas .selector {
    width: auto;
    border: 0;
    border-radius: 0;
    grid-template-columns: auto auto;
    gap: calc(var(--gd-u) * 2);
  }
  /* La marca deslizante era el relleno amarillo de la caja; sin caja no tiene
     donde vivir. El estado lo dice el subrayado. */
  .vistas .selector__marca { display: none; }
  .vistas .selector__solapa {
    min-height: 44px;
    padding: 0 2px;
    font-size: 11px;
    color: var(--gd-gris);
    border-bottom: 2px solid transparent;
  }
  .vistas .selector__solapa[aria-selected='true'] {
    color: var(--gd-negro);
    border-bottom-color: var(--gd-rojo);
  }
}

/* ---------------------------------------------------------------------------
   LA PRIMERA PANTALLA DE LA TIENDA
   Tienen que entrar juntos el titulo, el selector, las CUATRO piezas de la
   pagina y los numeros. Medido en un iPhone 15: el contenido pedia 964px y
   habia 597. Los 367 de diferencia salieron de aca, en este orden.
   --------------------------------------------------------------------------- */
@media (max-width: 560px) {
  /* 1. La banda: el logo ya estaba chico, ahora sin aire de sobra. */
  .banda { padding: 2px 0; }
  .banda__caja a { width: min(100%, 130px); }
  .banda .cabecera { margin-top: 2px; }
  .hoja { padding-top: 4px; }

  /* 2. El encabezado, sin el aire de escritorio. El titulo sigue partiendose
        en dos lineas: eso es lo que le da peso. */
  .portada--consolapas { margin-bottom: 6px; padding-bottom: 6px; }
  .portada--consolapas .disp--l { font-size: 24px; }
  .vistas { margin-bottom: 6px; }
  .paginas { margin-top: 6px; }

  /* 3. La grilla: portadas mas chicas y juntas. */
  .grilla__pagina { gap: 8px; }
  .doc__arte { max-width: 130px; margin-inline: auto; }

  /* 4. El titulo y el artista debajo de cada portada se van de la VISTA, no
        del documento: la portada ya los trae impresos en su cabecera roja, y
        repetirlos costaba 70px por fila. Se ocultan como el salto de
        accesibilidad —fuera de pantalla, no `display:none`— para que un lector
        de pantalla siga diciendo que tema es cada tarjeta.

        EL `position: relative` DE LA TARJETA NO ES DECORATIVO. Un elemento
        absoluto sin ancestro posicionado se cuelga del documento entero, y
        adentro de un carrusel horizontal eso significa que el titulo oculto de
        una pieza de la pagina 4 queda anclado a 1300px del origen: el DOCUMENTO
        pasa a medir 1773px de ancho y toda la web se scrollea para el costado.
        Con la tarjeta posicionada, el nodo oculto queda adentro del carril, que
        es quien tiene que recortar. Medido: 1380px de scroll horizontal en
        CATALOGO y 806 en ESCUCHA, los dos a cero. */
  .doc { position: relative; }

  .doc__titulo,
  .doc__artista {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    white-space: nowrap;
    clip-path: inset(50%);
  }
}

/* ---------------------------------------------------------------------------
   LA PRIMERA PANTALLA, SEGUNDA VUELTA
   Achicar todo para que entrara rompio las proporciones: portadas de 130 en
   columnas de 172, con 84px de aire desperdiciado a los costados.
   La salida no era achicar mas, era SACAR.
   --------------------------------------------------------------------------- */
@media (max-width: 560px) {
  /* 1. EL LOGO DE LA BANDA SE VA. La pagina arranca en `CATÁLOGO DE TRACKS`.
        El logo repetia la marca que ya esta en cada portada y costaba 110px de
        la unica pantalla que importa. Se queda la fila de navegacion, que es
        de 44px y lleva HOME, CONTACTO y el carrito: sin ella no hay forma de
        salir del catalogo ni de ver lo que se sumo. */
  .banda__caja { display: none; }

  /* 2. La lupa se muda a la fila del selector, que ahora es la unica que hay
        arriba de la grilla: buscar a la izquierda, cambiar de vista a la
        derecha, en 44px de alto. */
  .vistas { justify-content: space-between; align-items: center; margin: 0 0 var(--gd-u); }
  .vistas .lupa { margin: 0; }

  /* 3. Las portadas LLENAN su columna. Era lo que el ojo pedia: una grilla de
        documentos con aire a los costados no parece una grilla. */
  .doc__arte { max-width: none; }
  .grilla__pagina { gap: var(--gd-u); }

  /* 4. EL BRIEFING SE QUEDA, ABAJO DE TODO.
        Se lo habia sacado del telefono por espacio, y estaba mal: no compite
        con nada. La primera pantalla es el catalogo —titulo, cuatro piezas y
        los numeros— y esto vive DEBAJO, en las dos vistas. Quien scrollea ya
        vio el catalogo; ofrecerle la lista ahi es el momento exacto. Lo unico
        que se recorta es el aire de escritorio. */
  .briefing { margin-top: calc(var(--gd-u) * 3); }
}

@media (max-width: 560px) {
  /* La fila de navegacion alineada con el contenido. Su `max-width` esta
     pensado para escritorio y en telefono no acota nada, asi que la barra se
     quedaba sin margen y HOME arrancaba pegado al borde de la pantalla
     mientras el catalogo respetaba 20px. */
  .banda .cabecera { padding-inline: var(--gd-margen); }
}

/* ---------------------------------------------------------------------------
   ESCUCHA EN TELEFONO — la lista tratada como la del home
   ---------------------------------------------------------------------------

   Tres cambios, y los tres salen del mismo criterio: esta pantalla es para
   ELEGIR RAPIDO, asi que cada fila tiene que costar lo menos posible en alto y
   la lista tiene que comportarse como la que ya existe en la home.

   1. TEMA Y ARTISTA EN EL MISMO RENGLON, con el precio a su derecha. Antes eran
      dos lineas apiladas y el precio flotaba al costado sin alinearse con
      ninguna: 20px por fila gastados en separar dos datos que se leen juntos.
   2. LA LISTA SCROLLEA POR DENTRO, con `scroll-snap` para que el corte caiga
      siempre en una fila entera. Cuantas entran lo mide vista.js —igual que
      player.js en la home—; lo de aca es el respaldo por si el JS no corre.
   3. LA BARRA DE TOTAL NO EXISTE EN TELEFONO. Es un cartel fijo de 66px sobre
      el reproductor, tapando la fila que uno esta por tocar. Lo que decia —
      cuantas piezas hay— ya lo dice el contador rojo del carrito en la
      navegacion, que ademas abre el carrito. Menos elementos, no elementos mas
      chicos.
   --------------------------------------------------------------------------- */
@media (max-width: 560px) {
  /* 1. UNA SOLA LINEA DE TEXTO.
        El artista cede primero: `flex-shrink: 2` hace que cuando no entra todo
        se recorte el nombre del artista y no el del tema. El punto medio va
        como `::before` del artista y no como nodo aparte para no meter un
        elemento vacio en el HTML que lee un lector de pantalla. */
  .aud__texto {
    display: flex;
    align-items: baseline;
    gap: 6px;
    min-width: 0;
  }
  /* El artista se lleva lo que SOBRA (`flex: 1 1 0`): mientras el tema entre,
     el tema entero se lee; cuando no entra, el que se recorta es el artista.
     Con dos `flex-shrink` distintos se recortaban los dos a la vez. */
  .aud__titulo { flex: 0 1 auto; min-width: 0; font-size: 12px; letter-spacing: 0; }
  .aud__artista { flex: 1 1 0; min-width: 0; }
  .aud__artista::before { content: '·'; margin-right: 6px; color: var(--gd-aluminio); }

  /* EL PRECIO NO SE MUESTRA EN LA LISTA.
     Veinte veces el mismo `ARS 5.000` no informa nada —todos los tracks valen
     igual— y era lo unico de la fila que no se podia alinear con nada: mas
     ancho que el boton, encima de el, siempre flotando. La plata aparece
     cuando importa, que es al sumar al carrito: ahi el popup muestra el precio
     de cada track, el subtotal, el ajuste por volumen y el total, y todo eso
     sale de /api/cotizar, no del navegador (regla 5).
     Se oculta FUERA DE PANTALLA y no con `display: none`: un lector de
     pantalla tiene que poder decir cuanto sale antes de que lo sumen. Es el
     mismo recurso que usan el titulo y el artista de la grilla, y viene con la
     misma trampa: sin `position: relative` en la fila, el precio oculto se
     cuelga del documento y estira el ancho de la pagina entera —una fila de la
     ultima lamina lo anclaba a 800px del origen—.
     Sin precio, el renglon de arriba es todo del tema: el texto pasa a ocupar
     las tres columnas. */
  .aud { grid-template-columns: auto minmax(0, 1fr) 44px; }
  .aud { grid-template-areas: 'texto texto texto' 'play onda box'; }
  .aud { position: relative; }
  .aud__precio {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    white-space: nowrap;
    clip-path: inset(50%);
  }

  /* LA FILA, DE 85 A 79. Con 85 entraban cuatro y sobraban 71px muertos abajo
     de los numeros; con 79 entran cinco en un telefono grande y no sobra nada.
     Los seis pixeles salen del aire de arriba y abajo (10 -> 6) y no de los
     controles: EL PLAY Y EL BOX SIGUEN EN 44, que es el minimo de Apple y lo
     unico de esta pantalla que de verdad se toca con el dedo.
     LA ONDA VA A LA MISMA ALTURA QUE EL BOTON. Se probo bajarla a 32 para
     aligerar la fila y no sirve de nada: el alto de la fila lo fija el boton,
     que es el mas alto, asi que la onda mas baja no ahorra un solo pixel y
     ademas deja una tira flotando entre dos cuadrados de 44. Play, onda y BOX
     miden lo mismo y arrancan y terminan en la misma linea: eso es lo que hace
     que la fila se lea como una pieza y no como tres cosas apiladas. */
  .aud { padding: 6px 0; gap: 6px var(--gd-u); }
  .aud__onda { height: 44px; }

  /* 2. LA LISTA SE PASA DE PAGINA, NO SE SCROLLEA.
        Se probo primero con scroll vertical por dentro y el aviso «¿querés
        más?» de la home. Anda, pero convive mal con la pantalla: arriba del
        reproductor fijo, una caja que scrollea adentro de una pagina que
        tambien scrollea deja al dedo adivinando cual de las dos va a moverse.
        El carrusel no tiene esa duda —el eje horizontal es solo de la lista— y
        ademas dice cuantos temas hay, que el scroll no decia. */
  .aud-carril {
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    /* El mismo aire entre laminas que la grilla, y por el mismo motivo: sin el,
       al deslizar se ve la fila de la pagina siguiente pegada a la ultima de
       esta. `paginas.js` mide el paso sobre los elementos, asi que este numero
       se cambia sin tocar el JavaScript. */
    gap: calc(var(--gd-margen) * 2);
    scrollbar-width: none;
  }
  .aud-carril::-webkit-scrollbar { display: none; }

  /* EL PANEL NO SE PUEDE ESTIRAR CON EL CARRIL ADENTRO.
     Los dos paneles del catalogo son items de un contenedor flex, y un item
     flex trae `min-width: auto`: no baja de su contenido minimo. Con el
     carrusel adentro ese minimo pasa a ser la suma de las laminas, asi que el
     panel media 792px en una pantalla de 393 y cada pagina salia del doble de
     ancho. Con `min-width: 0` el panel vuelve a valer lo que la pantalla, que
     es contra lo que resuelve el `100%` de cada lamina.
     Va solo en telefono: en escritorio no hay carrusel y el panel se sigue
     midiendo como siempre. */
  [data-vistas] > [data-vista] { min-width: 0; }
  .aud-carril .aud-lista { flex: 0 0 100%; scroll-snap-align: start; }

  /* La nota de los 90 segundos se va: lo mismo esta impreso en la ficha de cada
     pieza y aca costaba una fila de lista. */
  .aud__nota { display: none; }

  /* 3. LA BARRA DE TOTAL, FUERA — Y SU RESERVA TAMBIEN.
     El <body> reservaba abajo el reproductor MAS la barra de total, pero en
     telefono la barra no se dibuja: eran 100px de aire fantasma. Se veia como
     que el pie de la segunda pantalla "se subia" al pasar a ESCUCHA, porque en
     esta vista el relleno saltaba de 88 a 188. Medido: 126px de distancia entre
     el pie y el reproductor, contra los 26 que corresponden. */
  .totalbar { display: none; }
  body[data-vista='audicion'].con-reproductor {
    padding-bottom: var(--gd-reproductor);
  }

  /* EL SELECTOR A LA IZQUIERDA, LA LUPA A LA DERECHA.
     Se cambia con `order` y no invirtiendo el HTML: el orden del documento —
     buscar primero— es el que recorre el teclado, y ahi la lupa antes que las
     solapas esta bien. Lo que cambia es donde caen en la pantalla. */
  .vistas .lupa { order: 2; }
  .vistas .selector { order: 1; }
}

/* ---------------------------------------------------------------------------
   EL PLAY DE LA GRILLA, EN LA ESQUINA
   ---------------------------------------------------------------------------
   En escritorio el boton aparece al pasar el mouse y por eso puede estar en el
   medio: mientras no se lo busca, no esta. En telefono no hay hover —la hoja
   ya lo deja siempre visible— y un cuadrado negro de 68px clavado en el centro
   de la portada tapa justo lo que se vende y convierte la tarjeta en un boton
   de play: nadie deduce que tocando la portada se entra al track.
   Se va a la esquina de abajo a la izquierda, a 44px, que es el minimo de
   toque. La portada vuelve a leerse entera y quedan dos gestos distintos y
   evidentes: la esquina escucha, el resto entra.
   --------------------------------------------------------------------------- */
@media (max-width: 560px) {
  .doc__play {
    top: auto;
    bottom: 6px;
    left: 6px;
    transform: none;
    width: 44px;
    height: 44px;
  }
  .doc__play .icono { width: 16px; height: 16px; }
}

/* ---------------------------------------------------------------------------
   EL BUSCADOR SE ACOMODA AL TECLADO
   ---------------------------------------------------------------------------
   Con el teclado abierto quedaban 390px de pantalla util y el bloque de buscar
   pegado arriba de todo, con un vacio enorme entre el campo y las teclas.

   Dos piezas. Esta es la que reparte; la que mide esta en buscar.js, porque
   en iOS el teclado NO achica el viewport de CSS —ni `100dvh` se entera— y la
   unica fuente de verdad es `window.visualViewport`. El JS escribe en
   `--gd-teclado` cuanto tapan las teclas y aca se usa como relleno de abajo.

   Mientras no hay resultados, el bloque logo + caja se CENTRA en lo que queda
   libre: con el teclado arriba queda a mitad de camino entre el borde y las
   teclas, y cuando el teclado baja se vuelve a repartir solo, sin saltos.
   Apenas aparece un resultado el bloque sube: ahi la lista es lo importante y
   tiene que arrancar lo mas arriba posible.
   --------------------------------------------------------------------------- */
/* LA CAPA TAPA LA PANTALLA ENTERA, SIEMPRE.
   Se probo darle el alto del viewport visual y fue peor: con el teclado
   abierto la capa medida 390px y debajo de esos 390 volvia a verse el
   catalogo, filas de tracks incluidas. El fondo tiene que llegar hasta abajo
   de todo; lo que se achica no es la CAPA sino la zona donde se reparte el
   contenido. Por eso el teclado entra como RELLENO de abajo: el fondo sigue
   cubriendo hasta el borde y el centrado ocurre en lo que queda arriba. */
.buscador {
  padding-top: calc(var(--gd-u) * 3 + var(--gd-desfase, 0px));
  padding-bottom: calc(var(--gd-u) * 2 + var(--gd-teclado, 0px));
}
.buscador[data-hay='0'] { justify-content: center; }
.buscador[data-hay='0'] .buscador__lista { flex: 0 0 auto; }
.buscador[data-hay='1'] { justify-content: flex-start; }

/* ---------------------------------------------------------------------------
   LA CAPA DE BUSQUEDA CON EL TECLADO ARRIBA
   --------------------------------------------------------------------------- */

/* `safe` para que, cuando el contenido no entre en la banda que deja el
   teclado, el sobrante se vaya para ABAJO y no por arriba. Centrado a secas
   cortaba el logo contra el borde superior —27.7px en apaisado con el teclado
   abierto— y ese pedazo no se recupera con ningun gesto en los motores que no
   extienden la region de scroll hacia arriba. */
.buscador[data-hay='0'] { justify-content: safe center; }

/* EL LOGO SE VA CUANDO EL TECLADO ESTA ARRIBA **Y** HAY RESULTADOS.
   Las dos condiciones, no una. Con el teclado arriba el logo se lleva 93 de los
   307px utiles —el 30%— y a la lista le quedan 105, que son dos resultados de
   veinte: ahi sobra. Pero mientras todavia no se escribio nada no hay lista que
   estorbar, y esa es JUSTO la pantalla que se ve al tocar la lupa: sacarlo ahi
   deja una caja de texto flotando sola, sin decir de donde no te fuiste.
   Con `[data-teclado]` solo, el logo no aparecia nunca en telefono, porque el
   campo se enfoca al abrir y el teclado sube siempre. */
.buscador[data-teclado='1'][data-hay='1'] .buscador__marca { display: none; }

/* En escritorio la caja de escritura medía 1152px de ancho en una pantalla de
   1280: un campo de un metro para escribir cuatro letras. */
@media (min-width: 561px) {
  .buscador__marca,
  .buscador__caja,
  .buscador__lista { width: 100%; max-width: 520px; margin-inline: auto; }
}

.buscador[data-abierto='1'] { opacity: 1; transform: none; }

/* Quien pidio menos movimiento recibe la capa entera, sin recorrido y sin
   fundido: aparece y ya. La hoja no anima nada por gusto. */
@media (prefers-reduced-motion: reduce) {
  .buscador { transition: none; transform: none; }
}

/* LOS NUMEROS DE PAGINA NO EMPUJAN LA PAGINA A LO ANCHO.
   En un iPhone SE la lista de ESCUCHA entra de a tres, asi que hay SIETE
   paginas: siete botones de 44 mas los huecos dan 356px en una pantalla de
   320, y esos 18px de sobra hacian que se pudiera scrollear toda la web hacia
   el costado. Medido: `scrollWidth - clientWidth = 18`.
   Se dejan encoger en vez de partirlos en dos renglones: la segunda fila se
   comeria 44px del unico lugar donde no sobran, y ademas `repartir()` mide el
   alto de esta barra para decidir cuantas filas entran —una barra mas alta
   daria menos filas, mas paginas, y mas numeros—. El alto se queda en 44, que
   es lo que importa para el dedo; lo que cede es el ancho, y solo en la
   pantalla mas chica: de un iPhone 13 para arriba no encogen nada. */
@media (max-width: 560px) {
  .paginas { flex-wrap: nowrap; }
  .paginas__n { flex: 0 1 44px; min-width: 0; }
}

/* ---------------------------------------------------------------------------
   EL BRIEFING EMPIEZA DEBAJO DE LA PRIMERA PANTALLA
   ---------------------------------------------------------------------------
   Es una suscripcion, no catalogo: quien entra tiene que ver el catalogo, y
   esto aparece SOLO si sigue bajando. Sin separacion quedaba asomando abajo de
   los numeros de pagina, porque lo que sobra despues de las filas alcanza justo
   para su titulo.

   Un cuarto de pantalla de aire, y no un numero medido con JavaScript. Se
   intentaron las dos cosas mas listas y las dos salieron peor:

    · MIDIENDO EN JS: el valor correcto depende de la vista —el panel de
      ESCUCHA es mas bajo que la grilla— y hay que recalcularlo en cada cambio;
      la mitad de las veces medía antes de que el navegador terminara de
      acomodar y no empujaba nada.
    · CON `margin-top: auto` EN UNA COLUMNA FLEX: para eso hay que hacer flex al
      <body>, y un item flex no baja de su contenido minimo. Con el carrusel
      adentro ese minimo pasa a ser la suma de las laminas: volvio el scroll
      horizontal de toda la pagina —688px en un iPhone SE—.

   La primera pantalla es siempre del mismo alto por diseño: cuatro o cinco
   filas mas los numeros, medidos por `paginas.js`. Un cuarto de pantalla de
   distancia alcanza en todos los aparatos, no depende de ningun momento, y el
   aire de sobra separa dos cosas que no son lo mismo.
   --------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
   DOS PANTALLAS: EL CATALOGO Y EL ALTA
   ---------------------------------------------------------------------------
   La tienda en telefono son dos pantallas y se ve una o la otra. La primera es
   el catalogo entero —titulo, selector, las piezas que entren y los numeros—.
   La segunda es el alta al equipo, centrada, con el pie abajo de todo y arriba
   del reproductor.

   Antes esto era un relleno inventado para que el bloque del alta no asomara en
   la primera pantalla, y quedaba un hueco muerto de 175px que habia que
   recorrer. La diferencia entre las dos ideas: aquel numero solo empujaba, este
   define una pantalla. El aire ya no es un valor elegido, es lo que sobra
   repartido arriba y abajo del bloque.

   `mandatory` y no `proximity`: con dos anclas y una pantalla cada una, que el
   dedo caiga SIEMPRE en una de las dos es exactamente lo que se busca; con
   `proximity` el navegador no engancha si el gesto se queda a mitad de camino
   —medido: el ancla quedaba a 300px y no la tomaba— y volvia el hueco muerto.
   --------------------------------------------------------------------------- */
@media (max-width: 560px) {
  /* SIN `scroll-snap`. Se probo tres veces —`proximity`, `mandatory`, y
     `mandatory` con la geometria ya corregida— y en el telefono siempre se ve
     igual: el envion termina, la pagina se frena, y RECIEN AHI el navegador la
     corre hasta el ancla. Dos movimientos donde hay uno. No es un problema de
     configuracion: es como iOS resuelve el snap despues de un envion con
     momento. No lo reintentes.
     Lo que hace que caiga sola no es el snap: es que la pagina mida dos
     pantallas justas, y de eso se ocupan los dos `min-height` de abajo. */

  /* LA PRIMERA PANTALLA MIDE EXACTAMENTE UNA PANTALLA.
     Sin esto la pagina medía 1,87: la segunda seccion arrancaba 94px ANTES de
     que terminara la primera, asi que el salto empezaba con los numeros de
     pagina todavia a la vista y se quedaban un rato flotando mientras la
     pagina se acomodaba. Esa era la animacion rara — no era el snap, era que
     las dos secciones se pisaban.
     Con la primera en un alto exacto, la segunda empieza justo donde termina la
     primera y el movimiento es de una pantalla limpia. Los 60px son la banda de
     navegacion, que va arriba de la hoja y en el flujo. */
  /* `dvh` — y se probo `svh`, que sale peor.
     La regla que manda: las dos secciones tienen que medir lo que mide la
     pantalla AHORA. `svh` es el viewport chico, el de la barra de Safari
     desplegada; con la barra colapsada la pantalla real es mas alta, la pagina
     sigue midiendo dos pantallas chicas, y el scroll maximo queda MAS CORTO que
     el arranque de la segunda seccion: no habia forma de llevarla arriba de
     todo. Se veia como que el acomodado no andaba, y no andaba.
     `dvh` sigue a la pantalla, asi que el final del scroll y el principio de la
     segunda pantalla son siempre el mismo punto. */
  /* LA PRIMERA SECCION SE MIDE CON `svh` — el viewport CHICO, el de la barra de
     Safari desplegada— y por eso NO cambia de alto nunca. Con `dvh` crecia 60px
     cuando la barra se colapsaba, y eso pasa MIENTRAS el dedo scrollea: la
     seccion se agrandaba abajo del gesto y todo lo de la segunda pantalla se
     corria. Ese era el salto que quedaba incluso sin snap.
     La segunda seccion si va con `dvh`, y la cuenta cierra igual: la pagina
     mide `svh + dvh`, el scroll maximo es `svh`, y la segunda seccion arranca
     exactamente en `svh`. Con la barra desplegada o colapsada, el final del
     scroll y el arranque de la segunda pantalla son el mismo punto. */
  /* UNA RIGIDA Y UNA ELASTICA — y en ese orden, que es lo unico que funciona.
     La invariante que sostiene todo: el final del scroll tiene que caer EXACTO
     sobre el arranque de la segunda seccion. Si caen en el mismo punto, el
     envion frena contra el borde del documento —con goma elastica, integrado al
     momento— y no hay nada que corregir despues. Ese frenado es el unico "snap"
     que iOS hace bien.
     Se midio la aritmetica de las cuatro combinaciones en los dos estados de la
     barra de Safari (desplegada y colapsada), y el error es:

       svh + dvh   0 / 0    <- esta
       dvh + dvh   0 / 0    pero la primera cambia de alto bajo el dedo
       svh + lvh  +60 / 0
       svh + svh   0 / -60  la segunda pantalla queda INALCANZABLE

     La primera va RIGIDA (`svh`, el viewport chico): asi el borde de arriba de
     la segunda no se mueve nunca. La segunda va ELASTICA (`dvh`): crece con la
     pantalla, y por eso el final del scroll la sigue. Al reves —o las dos
     iguales— la cuenta se rompe de un lado o del otro. */
  body.tienda .hoja {
    min-height: calc(100vh - 60px);
    min-height: calc(100svh - 60px);
  }

  /* LA SEGUNDA PANTALLA. Alta arriba, pie abajo, y el reproductor descontado
     porque esta fijo encima. Solo cuando hay alta: en la ficha y en contacto
     `.cierre` lleva unicamente el pie y no tiene que ocupar una pantalla. */
  /* GRILLA DE CUATRO FILAS: aire, bloque, aire, pie.
     Los dos `1fr` valen lo mismo por construccion, asi que el bloque queda
     centrado ENTRE EL BORDE DE ARRIBA Y EL PIE — que es lo que el ojo lee como
     centrado. Centrarlo contra la pantalla entera lo dejaba con 170px arriba y
     69 hasta el pie: el pie ocupa la franja de abajo y hay que contarlo.
     Con flex no salia: `justify-content: center` centra los tres elementos como
     grupo y `margin-top: auto` en el pie empuja todo el sobrante a un lado. */
  body.tienda .cierre:has(.briefing) {
    display: grid;
    grid-template-rows: 1fr auto 1fr auto;
    /* El descuento es `--gd-reproductor`, el MISMO que el body reserva abajo, y
       no el alto real de la barra. Con el alto real la caja sobresalia 6px y la
       pagina pasaba a medir 741 en vez de 735: dejaba de ser dos pantallas
       justas, que es lo que hace que el scroll caiga solo. Seis pixeles de
       asimetria en el centrado valen menos que eso. */
    min-height: calc(100vh - var(--gd-reproductor));
    min-height: calc(100dvh - var(--gd-reproductor));
  }



  /* EL PIE SALE DEL FLUJO Y SE CLAVA ABAJO.
     Con el pie adentro de la columna, el bloque del alta se centraba entre el
     borde de arriba y el pie —no en la pantalla—: el pie le comia sus 117px de
     un solo lado y el conjunto quedaba 70px mas arriba de donde el ojo lo
     espera. Sacandolo del flujo, el alta se centra contra la pantalla entera y
     el pie queda pegado al borde de abajo, arriba del reproductor. */
  body.tienda .cierre:has(.briefing) .briefing { grid-row: 2; }
  /* El aire entre el pie y el reproductor va como relleno del pie y no como
     reserva del <body>: la reserva tiene que ser el alto REAL de la barra, o la
     cuenta de las dos pantallas deja de cerrar. Antes esos 26px venian de una
     variable mal medida y se notaban como un pie flotando. */
  body.tienda .cierre:has(.briefing) .pie {
    grid-row: 4;
    margin: 0;
    padding-bottom: calc(var(--gd-u) * 2);
  }

  /* `margin: auto 0` en el bloque y no `justify-content: center` en la caja:
     centrar la caja centraria TAMBIEN al pie, y el pie tiene que quedar abajo.
     Con margenes automaticos el sobrante se reparte arriba y abajo del alta, y
     el pie se queda donde termina la columna. */
  body.tienda .cierre:has(.briefing) .briefing {
    margin: 0;
    padding-top: 0;
    border-top: 0;
  }

  /* El titulo de la segunda pantalla se construye igual que CATALOGO DE TRACKS:
     cuadro a cuadros, cuerpo grande y el filete debajo que lo separa de su
     bajada. Son los dos titulos de las dos pantallas de la tienda. */
  body.tienda .cierre .briefing__titulo { font-size: 24px; }
  body.tienda .cierre .pie { margin-top: calc(var(--gd-u) * 2); }
}

/* ---------------------------------------------------------------------------
   LA FICHA EN TELEFONO — que la primera pantalla alcance para decidir
   ---------------------------------------------------------------------------
   Medido en un iPhone 15 (pliegue a 640px): entraban la portada de 353, el
   titulo y el artista, y nada mas. La escucha arrancaba en 716 y el boton de
   compra en 930: para oir el tema —que es lo unico que decide una compra— y
   para ver cuanto sale habia que scrollear dos pantallas.

   Dos cambios y ninguno saca informacion:

   1. LA PORTADA CEDE ALTO. Sigue siendo lo primero y lo mas grande, pero
      acotada a un tercio de la pantalla en vez de a todo el ancho. Lo que
      lleva impreso —designacion, division, revision— se sigue leyendo, y en la
      pantalla chica esa textura no es lo que decide.
   2. LA ESCUCHA SUBE, la especificacion baja. `display: contents` disuelve los
      dos envoltorios de la ficha, asi que la portada, el titulo, el artista, la
      muestra, la especificacion y la compra pasan a ser hermanos en una sola
      columna y se ordenan de a uno. Nadie pierde nada de lugar: DURACION,
      FORMATO y ESTADO quedan justo debajo, que es donde se los consulta
      DESPUES de escuchar. En escritorio no cambia un pixel.
   --------------------------------------------------------------------------- */
@media (max-width: 560px) {
  main.hoja:has(.ficha) {
    display: flex;
    flex-direction: column;
    /* Un item flex no baja de su contenido minimo si no se lo dicen. */
    min-width: 0;
  }
  main.hoja:has(.ficha) > * { min-width: 0; }

  .ficha,
  .ficha__datos { display: contents; }

  /* LA ONDA VA PEGADA A LA PORTADA. Son la misma cosa: la cara del tema y su
     forma. Con el titulo en el medio se leian como dos bloques sueltos, y ese
     hueco era espacio de la unica pantalla que decide una compra. */
  /* El relleno y el filete de la columna de escritorio no existen: en una sola
     columna no hay nada al costado que separar, y ese relleno era el hueco que
     quedaba entre la portada y su onda. */
  .ficha__arte { order: 1; padding: 0; border-right: 0; }
  .muestra { order: 2; }
  .ficha__titulo { order: 3; }
  .ficha__artista { order: 4; }
  .especificacion { order: 5; }
  .compra { order: 6; }
  .soporte { order: 7; }
  /* EL «VOLVER» VA ARRIBA DE LA PORTADA.
     En el documento esta ultimo —despues de haber leido la ficha— y en
     escritorio ahi funciona. En telefono la flecha de volver es lo que la gente
     busca arriba a la izquierda, como en cualquier aplicacion, y al fondo de la
     pagina no la encuentra nadie. Compacto: el rotulo es chico y lo que tiene
     que medir 44 es el area de toque del enlace, no el parrafo. */
  .volver { order: 0; margin: 0 0 6px; }
  .volver a {
    display: inline-flex;
    align-items: center;
    min-height: 36px;
  }

  /* LA PORTADA OCUPA EL ANCHO COMPLETO. Se probo acotarla por alto para que
     entrara todo lo demas y quedaba una estampilla centrada con la onda —que
     si iba a ancho completo— sobresaliendo a los dos costados: dos anchos
     distintos para dos mitades de la misma cosa. El alto que hacia falta salio
     de otro lado: de la nota, de los rotulos y del aire. */
  /* EL REPRODUCTOR NO SE VE EN LA FICHA.
     Es la misma decision que en el home y por el mismo motivo: la fila de la
     pieza ya tiene su play y su onda, asi que la barra fija repetia el control
     y se llevaba 82px de la unica pantalla que decide una compra —justo los
     que le faltaban al boton de compra en el aparato mas chico—.
     `display: none` NO corta el audio: el elemento sigue en el documento y
     `player.js` le habla igual. Es lo que ya hace `body.escucha`. */
  /* NI EN LA FICHA NI EN BOOKING NI EN CONTACTO.
     El nodo del reproductor sobrevive a la navegacion a proposito —es lo que
     hace que el audio no se corte al cambiar de pantalla— pero en estas tres no
     tiene nada que hacer: en la ficha la propia pieza tiene su play, y en un
     formulario una barra fija de 62px es una pantalla menos para escribir. */
  body:has(.ficha) .reproductor,
  body:has(.reserva) .reproductor,
  body:has(.contacto) .reproductor { display: none; }
  body:has(.ficha).con-reproductor,
  body:has(.reserva).con-reproductor,
  body:has(.contacto).con-reproductor { padding-bottom: 0; }

  /* ...PERO SOLO SI LO QUE SUENA ES ESTA PIEZA.
     La premisa de arriba —"la fila ya tiene su play"— se cae apenas llegas a
     una ficha con OTRO tema sonando: desde el buscador, desde otra ficha, o
     volviendo del home. Medido: cero controles de pausa en pantalla, el
     reproductor en 0px de alto, y el tema siguiendo. Un callejon sin salida.
     `player.js` ya sabia distinguir ese caso —lo llama `huerfano`— y ahora lo
     publica en el <body>. Los 62px se pagan unicamente ahi. */
  body:has(.ficha)[data-huerfano='1'] .reproductor,
  body:has(.reserva)[data-huerfano='1'] .reproductor,
  body:has(.contacto)[data-huerfano='1'] .reproductor { display: block; }
  body:has(.ficha)[data-huerfano='1'].con-reproductor,
  body:has(.reserva)[data-huerfano='1'].con-reproductor,
  body:has(.contacto)[data-huerfano='1'].con-reproductor {
    padding-bottom: var(--gd-reproductor);
  }

  .ficha__arte-caja { max-width: none; }

  /* LA ONDA OCUPA EL LUGAR DEL PIE NEGRO DE LA PORTADA.
     El pie mide 132 de los 1000 del lienzo —el numero sale de `portada.mjs`,
     no de medir una captura— y lleva la division, la duracion y los formatos:
     los tres estan dos dedos mas abajo en la especificacion, asi que en
     telefono ese pie es una franja negra que repite. Se recorta la imagen por
     abajo con `object-position: top` y la banda de escucha ocupa exactamente su
     alto, con la misma proporcion: la portada termina en la onda, no arriba de
     ella. Solo en telefono; en escritorio la portada va entera. */
  .ficha__arte-caja { aspect-ratio: 1000 / 868; }
  .ficha__arte-caja img { object-position: top; }
  .aud.muestra__banda { aspect-ratio: 1000 / 132; align-items: stretch; }

  /* LA MUESTRA, PEGADA Y COMPACTA. En escritorio se separa seis unidades del
     bloque de arriba y se abre con un filete; aca ese filete separaria la
     portada de su propia onda. La nota de los 90 segundos baja a 11px: sigue
     estando, deja de ocupar dos renglones. */
  .muestra {
    margin-top: 0;
    border-top: 0;
    padding-top: 0;
  }
  /* LA NOTA DE LOS 90 SEGUNDOS NO VA EN TELEFONO. Son tres renglones —el
     `letter-spacing` de los rotulos la estira— para decir algo que el
     reproductor ya muestra en numeros (01:30) y que la tienda explica en la
     ficha de compra. Tres renglones en la unica pantalla que decide una compra
     es el precio mas caro del proyecto. En escritorio se queda. */
  .muestra .rot--gris { display: none; }
  .aud.muestra__banda { margin-top: 0; padding: 0; }
  /* Play cuadrado del alto de la banda y la onda con el resto: las dos piezas
     estiran hasta el borde, como estiraba el pie que reemplazan. */
  .aud.muestra__banda .aud__play { width: auto; height: auto; aspect-ratio: 1 / 1; }
  .aud.muestra__banda .aud__onda { height: auto; }

  /* EL TEXTO, MAS CHICO QUE EN ESCRITORIO PERO CON AIRE.
     El titulo a 76px es para una pantalla grande; en un telefono ocupa dos
     renglones y no dice mas. Pero apretado tampoco: desde que el reproductor
     fijo no se dibuja en esta pagina sobran 82px, y el lugar donde se notan es
     alrededor del nombre del tema.

     EL AIRE SE MIDE EN ALTO DE PANTALLA, no en pixeles fijos: `clamp` le da el
     minimo a un iPhone SE —donde cada pixel esta peleado— y el maximo a un Pro
     Max, sin dos juegos de reglas ni un punto de corte mas. */
  .ficha__titulo {
    font-size: clamp(26px, 4.4vh, 38px);
    /* `calc` y no un `vh` pelado: con `3.4vh` un iPhone SE ya recibia 19px de
       aire y se pasaba tres pixeles del borde. Restando una constante, el
       minimo cae EXACTAMENTE en el aparato mas chico y el margen crece solo de
       ahi para arriba. */
    margin-top: clamp(8px, calc(9vh - 43px), 30px);
    line-height: 1.05;
  }
  .ficha__artista { margin-top: clamp(4px, 0.9vh, 10px); font-size: 14px; }

  /* ESTADO SE VA. El sello es un visto bueno que ya esta estampado sobre la
     portada, dos dedos mas arriba: repetido en la tabla es la misma frase dos
     veces y una fila entera de una pantalla que no la tiene. Se va la fila
     completa —el rotulo tambien—, no solo el sello. */
  .especificacion > div:has(.sello-estado) { display: none; }
  /* La columna de rotulos baja de 120px a 92: con 120, FORMATO —que es el valor
     mas largo del proyecto— se partia en dos renglones y esa segunda linea era
     justo lo que dejaba al boton de compra abajo del pliegue. A 92 entra
     entero, y DURACION y FORMATO siguen siendo los rotulos mas largos. */
  .especificacion { margin-top: clamp(8px, calc(6vh - 26px), 24px); }
  .especificacion > div {
    grid-template-columns: minmax(0, 92px) minmax(0, 1fr);
    gap: 4px var(--gd-u);
    padding: clamp(5px, calc(3vh - 12px), 11px) 0;
  }
  /* Y el valor con menos espaciado entre letras: `WAV 24/44.1 — AIFF 24/44.1 —
     MP3 320` es la cadena mas larga de la ficha y a 0.1em se partia igual. El
     rotulo conserva el espaciado ancho, que es lo que lo hace leer como rotulo. */
  .especificacion dd { letter-spacing: 0.04em; }

  /* EL BOTON DE SUMAR AL CARRITO ENTRA EN LA PRIMERA PANTALLA. El aire de
     arriba estaba calculado para que el boton cerrara a la altura del pie de la
     portada, que es una alineacion de la grilla de dos columnas: aca no hay dos
     columnas. */
  /* EL PRECIO VA ADENTRO DEL BOTON. Apilado con el boton eran 98px de alto; al
     lado, 48; adentro, 48 y una sola cosa que mirar. En una pantalla donde cada
     renglon se pelea, el precio y la accion son la misma decision: cuanto sale
     y sumarlo.
     La cifra de afuera se esconde pero NO se borra del documento: es la que
     lee un lector de pantalla —dentro del boton va `aria-hidden`, porque si no
     la etiqueta del boton se leeria "AGREGAR AL CARRITO ARS 5.000 ARS 5.000"—.
     En escritorio no cambia nada: la cifra grande a la derecha, el precio de
     adentro escondido. */
  .compra {
    margin-top: 0;
    padding-top: clamp(8px, calc(7vh - 32px), 26px);
    flex-wrap: nowrap;
    align-items: center;
  }
  .compra .boton { flex: 1 1 auto; }
  .compra .precio__cifra { display: none; }
  .boton__precio { display: inline; margin-left: 0.9em; }
  .boton__precio::before { content: '·'; margin-right: 0.9em; }
}

/* ---------------------------------------------------------------------------
   EL BOTON DEL ALTA, COMO EL DEL HOME
   ---------------------------------------------------------------------------
   El del home es la pieza mas visible del sitio: rojo con la letra en amarillo,
   filete blanco, y al tocarlo se levanta y proyecta su sombra dura. El del alta
   era negro con un bloque rojo corrido detras — el estilo general de los
   botones—, y en la unica pantalla donde se pide algo a cambio conviene que el
   boton se parezca al que la gente ya apreto una vez.

   El amarillo sobre rojo da 3.40:1: pasa AA SOLO como texto grande, o sea 18.66px
   en negrita. Por eso van los 22px del home y no el cuerpo chico del resto de
   los botones. Bajarlo obligaria a cambiarle el color, y un color nuevo no entra
   en los siete hex de la hoja.
   --------------------------------------------------------------------------- */
.briefing .boton {
  display: block;
  width: 100%;
  padding: 14px 34px;
  border: 3px solid var(--gd-blanco);
  outline: 2px solid var(--gd-negro);
  border-radius: 4px;
  background: var(--gd-rojo);
  color: var(--gd-amarillo);
  font-family: var(--gd-display);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
  box-shadow: 0 0 0 var(--gd-negro);
  transform: translate(0, 0);
  transition: transform 180ms cubic-bezier(0.2, 0, 0, 1),
              box-shadow 180ms cubic-bezier(0.2, 0, 0, 1);
}

/* El levantarse es del que TIENE mouse. En iOS el `:hover` queda pegado despues
   de tocar y el boton se quedaria flotando hasta que toques otra cosa. */
@media (hover: hover) {
  .briefing .boton:hover {
    transform: translateY(-5px);
    box-shadow: 5px 7px 0 var(--gd-negro);
  }
}
.briefing .boton:focus-visible {
  transform: translateY(-5px);
  box-shadow: 5px 7px 0 var(--gd-negro);
}
.briefing .boton[disabled] { opacity: 0.55; transform: none; box-shadow: none; }


/* El titulo del alta comparte la construccion del titulo de catalogo: el cuadro
   a cuadros alineado a la base de la letra y el filete que cierra el bloque. */
/* SIN INCLINACION. La display de la casa es oblicua 4 grados —es la que le da
   velocidad a los titulos del catalogo—, pero en este el pedido fue derecho:
   `UNITE AL EQUIPO` es una invitacion, no un rotulo de carrera. */
.briefing__titulo {
  font-style: normal;
  display: flex;
  align-items: baseline;
  gap: 0.24em;
  margin: 0 0 var(--gd-u);
  padding-bottom: calc(var(--gd-u) * 1.5);
  border-bottom: var(--gd-filete) solid var(--gd-negro);
}


/* EN PANTALLAS BAJAS EL PIE VUELVE AL FLUJO.
   Con el pie clavado abajo y el bloque centrado contra la pantalla entera, en un
   iPhone SE —480px utiles— el bloque del alta es tan alto que se le monta
   encima. Ahi centrar es un lujo que no entra: el pie vuelve a la columna,
   debajo del bloque, y cada cosa ocupa lo que necesita. */
@media (max-width: 560px) and (max-height: 640px) {
  /* En un iPhone SE el bloque casi llena la pantalla solo: los dos `1fr` se
     quedan en cero y no hay nada que centrar. Se les da un minimo para que el
     titulo no arranque pegado al borde. */
  body.tienda .cierre:has(.briefing) { grid-template-rows: minmax(16px, 1fr) auto minmax(16px, 1fr) auto; }
}

/* ---------------------------------------------------------------------------
   BOOKING — el bloque principal de contacto
   ---------------------------------------------------------------------------
   La pagina de contacto es sobre todo para esto: una fecha vale mas que
   cualquier otra cosa que pase por ahi. Asi que el correo de booking no es un
   renglon de una tabla de canales, es EL elemento de la pantalla: cuerpo de
   titulo, tocable entero, y lo primero que se ve despues de la bajada.
   --------------------------------------------------------------------------- */
.booking {
  margin-top: calc(var(--gd-u) * 4);
  padding: calc(var(--gd-u) * 3) 0 calc(var(--gd-u) * 4);
  border-top: 2px solid var(--gd-negro);
  border-bottom: var(--gd-filete) solid var(--gd-aluminio);
}

.booking__titulo {
  font-size: clamp(28px, 5vw, 44px);
  margin: 0;
}

.booking__bajada {
  margin: var(--gd-u) 0 calc(var(--gd-u) * 2);
  font-family: var(--gd-tecnica);
  font-size: 15px;
  color: var(--gd-grafito);
}

/* EL CORREO ES EL BOTON. No hay formulario —es una decision del proyecto, no un
   pendiente— asi que el `mailto:` carga con todo el peso de la accion. Bloque
   propio, cuerpo grande y area de toque de sobra: en un telefono se toca una
   vez y se abre el cliente de correo con la direccion puesta. */
.booking__mail {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--gd-mono);
  font-size: clamp(15px, 3.6vw, 20px);
  letter-spacing: 0.04em;
  color: var(--gd-negro);
  text-decoration-color: var(--gd-rojo);
  text-underline-offset: 6px;
  text-decoration-thickness: 2px;
}
.booking__mail:hover { color: var(--gd-rojo); }

.booking__pedido { display: block; margin: calc(var(--gd-u) * 3) 0 var(--gd-u); }

/* La lista de lo que hay que mandar, en fila numerada. No es burocracia: un
   mail que ya viene con fecha, ciudad y sala se contesta el mismo dia. */
.booking__datos {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: dato;
}
.booking__datos li {
  counter-increment: dato;
  display: grid;
  grid-template-columns: 2.2em minmax(0, 1fr);
  gap: var(--gd-u);
  padding: 9px 0;
  border-bottom: var(--gd-filete) solid var(--gd-aluminio);
  color: var(--gd-grafito);
}
.booking__datos li::before {
  content: counter(dato, decimal-leading-zero);
  color: var(--gd-rojo);
}

/* El correo de la tienda: mismo tratamiento pero un escalon abajo. */
.contacto__mail { margin: var(--gd-u) 0 0; }
.contacto__mail a {
  font-family: var(--gd-mono);
  font-size: 15px;
  letter-spacing: 0.04em;
  color: var(--gd-negro);
}
.contacto__nota { margin: var(--gd-u) 0 0; }
.contacto__redes { display: block; margin: calc(var(--gd-u) * 2) 0 0; }
.contacto__redes .rot--gris { margin-right: var(--gd-u); }

@media (max-width: 560px) {
  /* En telefono el bloque de booking abre la pagina: la bajada de la seccion y
     el titulo ya dijeron donde estas, y lo que sigue tiene que ser la accion. */
  .booking { margin-top: calc(var(--gd-u) * 2); }
  .booking__datos li { grid-template-columns: 2em minmax(0, 1fr); }
}

/* ---------------------------------------------------------------------------
   BOOKING — el formulario de pedido de fecha
   ---------------------------------------------------------------------------
   Es lo que mas plata mueve de todo lo que se completa en el sitio, asi que la
   pantalla entera esta al servicio de que alguien lo termine: campos anchos,
   rotulos legibles, y un solo boton que grita.

   Los rotulos llevan un emoji cada uno. Es una excepcion consciente a la
   direccion de arte —el sistema es plano y tecnico— y esta acotada a este
   formulario: un promotor que abre esto desde el telefono escanea, no lee, y el
   pictograma le dice de que se trata cada campo antes que la palabra.
   --------------------------------------------------------------------------- */
.reserva {
  /* Pegada a la bajada. Habia 66px entre "Fechas, festivales y salas" y "PEDIR
     UNA FECHA": el relleno de la portada (32) mas el margen y el relleno de
     esta seccion (16+16), tres aires apilados que nadie decidio juntos. El
     filete ya separa; el aire de sobra solo desconecta el titulo de la frase
     que lo introduce. */
  margin-top: 0;
  padding-top: var(--gd-u);
  border-top: 2px solid var(--gd-negro);
}

/* Y la portada de esta pagina cierra mas cerca: su bajada es la entrada al
   formulario, no el pie de una seccion. */
.portada--indice:has(+ .reserva) { padding-bottom: var(--gd-u); }

.reserva__titulo { font-size: clamp(24px, 4.4vw, 34px); margin: 0 0 var(--gd-u); }

/* CADA CAMPO EN SU RECUADRO, FINO.
   Se probo con la linea de abajo sola —mas liviana y mas cerca del lenguaje de
   la ficha tecnica— y confunde: una linea suelta no dice donde empieza ni donde
   termina la zona en la que se escribe, sobre todo con dos campos cortos uno al
   lado del otro. El recuadro lo dice sin explicar nada.
   Lo que se cuida es el peso: filete de 1px y no de 2, que es lo que hacia que
   seis campos apilados compitieran con el unico rectangulo que importa —el
   boton—, y relleno chico para no devolver los 250px de alto que costo bajar.

   OJO CON EL NOMBRE. Esto se llamaba `.campo`, que YA EXISTE en la hoja: es el
   input del formulario del briefing, con su caja de 1px y su relleno de 13.
   El envoltorio heredaba esa caja y por eso seguian dibujandose los recuadros
   despues de sacarlos. Todo lo de este formulario lleva el prefijo `reserva__`.

   Lo que NO se toca es el cuerpo de 16px: por debajo de eso iOS hace zoom al
   enfocar y te saca del formulario. */
.reserva__campo { margin: 0 0 8px; }

.reserva__rotulo {
  display: block;
  margin-bottom: 4px;
  font-family: var(--gd-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gd-grafito);
}

.reserva__caja {
  width: 100%;
  min-height: 42px;
  padding: 0 10px;
  border: var(--gd-filete) solid var(--gd-aluminio);
  border-radius: 2px;
  background: var(--gd-blanco);
  font-family: var(--gd-mono);
  font-size: 16px;
  letter-spacing: 0.04em;
  color: var(--gd-negro);
}

/* La unica que SI conserva su caja es el area de mensaje: es una superficie
   para escribir, no un renglon, y el recuadro es lo que dice cuanto espacio
   hay. Ahi el borde informa; en un campo de una linea, no. */
.reserva__caja--largo {
  min-height: 0;
  padding: 8px 10px;
  line-height: 1.45;
  resize: vertical;
}

/* EL EJEMPLO, MAS CHICO QUE LO QUE SE ESCRIBE. Asi se distingue de un valor ya
   cargado incluso antes de leerlo. Achicar el MARCADOR es seguro; achicar el
   campo no: iOS hace zoom al enfocar cualquier campo de menos de 16px y te saca
   del formulario. El zoom mira el cuerpo del input, no el del marcador. */
.reserva__caja::placeholder { color: var(--gd-gris); opacity: 1; font-size: 13px; }

/* El campo activo se marca con el rojo de la casa. Es el unico lugar de la
   pantalla donde el rojo dice "estas aca" y no "esto cuesta plata". */
/* El campo activo se marca en rojo y con el filete al doble: es el unico lugar
   de la pantalla donde el rojo dice "estas aca" y no "esto cuesta plata". */
.reserva__caja:focus-visible {
  outline: none;
  border-color: var(--gd-rojo);
  box-shadow: inset 0 0 0 1px var(--gd-rojo);
}

/* Fecha y ciudad van juntos: son la misma pregunta partida en dos. */
.reserva__par { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--gd-u); }

/* EL BOTON NO LLEVA MARCO. Los campos ahora tienen su recuadro fino, asi que
   un boton con filete blanco y contorno negro encima suma dos rectangulos mas a
   una pantalla que ya tiene seis. Rojo macizo y punto: es lo unico de la
   pantalla que se aprieta, no necesita que lo encuadren para destacarse. */
.reserva__boton {
  display: block;
  width: 100%;
  padding: 15px 24px;
  border: 0;
  border-radius: 2px;
  background: var(--gd-rojo);
  color: var(--gd-amarillo);
  font-family: var(--gd-display);
  font-size: 22px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1;
}
.reserva__boton[disabled] { opacity: 0.55; }
/* Con el marco afuera, el foco de teclado necesita su propia marca. */
.reserva__boton:focus-visible { outline: 3px solid var(--gd-negro); outline-offset: 2px; }

.reserva__aviso { display: block; margin: var(--gd-u) 0 0; min-height: 1.2em; }
.reserva__aviso[data-estado='ok'] { color: var(--gd-negro); }
.reserva__aviso[data-estado='error'] { color: var(--gd-rojo); }

.reserva__directo {
  margin: calc(var(--gd-u) * 4) 0 0;
  padding-top: calc(var(--gd-u) * 2);
  border-top: var(--gd-filete) solid var(--gd-aluminio);
}
.reserva__directo .rot--gris { display: block; margin-bottom: 4px; }

/* El desvio de CONTACTO a BOOKING: quien busca una fecha tiene que salir de ahi
   en un toque, no leer tres bloques que no le sirven. */
.contacto__desvio {
  margin-top: calc(var(--gd-u) * 4);
  padding: calc(var(--gd-u) * 3);
  border: 2px solid var(--gd-negro);
  border-radius: 2px;
}
.contacto__desvio p { margin: 0 0 var(--gd-u); }
.contacto__desvio-boton {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 20px;
  background: var(--gd-negro);
  color: var(--gd-amarillo);
  border-color: var(--gd-negro);
}
.contacto__rotulo { display: block; margin-bottom: var(--gd-u); color: var(--gd-grafito); }
.contacto__bloque--fuerte { border-left: 3px solid var(--gd-rojo); padding-left: var(--gd-u); }

@media (max-width: 560px) {
  /* En telefono los dos campos cortos vuelven a apilarse: partidos al medio
     entran ocho caracteres y el marcador se corta. */
  /* Fecha y ciudad SI van de a dos en telefono: con los marcadores cortos
     —«14 de marzo», «Buenos Aires»— entran sin cortarse, y apilarlos costaba un
     campo entero de alto en la unica pantalla que importa. */
  .reserva__par { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--gd-u); }
  .reserva { margin-top: calc(var(--gd-u) * 2); }
}

/* ---------------------------------------------------------------------------
   LA BARRA DE LA TIENDA CON CUATRO DESTINOS
   ---------------------------------------------------------------------------
   Con HOME, CATALOGO, BOOKING, CONTACTO y el carrito, la fila no entra en un
   telefono de 393px y el carrito se salia de la pantalla. Dos ajustes y ninguno
   toca el blanco de toque, que sigue en 44 de alto:

   1. HOME pasa a ser la casa. Es el unico pictograma que se lee sin leyenda, y
      libera el ancho de cuatro letras y su espaciado.
   2. El resto de los rotulos pierde espaciado entre letras, que es de donde
      sale el ancho en una tipografia monoespaciada: `0.1em` sobre ocho letras
      son ocho pixeles por palabra.
   --------------------------------------------------------------------------- */
/* LA CASA SE ALINEA CON LA LETRA, NO CON LA CAJA.
   Los dos elementos ya estaban centrados al pixel en una fila de 44px, y aun
   asi la casa se leia corrida: el centro de una linea de texto no es donde el
   ojo la ve —una mayuscula de 11px ocupa la mitad de arriba de su renglon— y el
   dibujo de 15px era casi el doble de alto que esa mayuscula.
   Se lleva el dibujo al alto de la mayuscula (12) y se lo sube un pixel, que es
   la diferencia entre el centro geometrico y el optico. */
.cabecera__casa { display: inline-flex; align-items: center; justify-content: center; }
.cabecera__casa .icono {
  width: 12px;
  height: 12px;
  transform: translateY(-1px);
}

@media (max-width: 560px) {
  /* EL MENU SE REPARTE, no se apila con rellenos sueltos. Cada rotulo tenia el
     mismo padding fijo, asi que el hueco entre dos palabras dependia del largo
     de cada una y la fila se leia torcida. Con `space-between` los cuatro
     destinos se distribuyen parejo entre la casa y el carrito, y el ancho lo
     reparte el navegador. */
  .cabecera__nav { gap: 0; justify-content: space-between; }
  .cabecera__nav a {
    min-width: 0;
    padding: 0;
    font-size: 11px;
    letter-spacing: 0.04em;
  }
  .cabecera__casa { min-width: 24px; padding: 0; }
  /* El carrito no se encoge, pero SIN `margin-left: auto`: ese margen se comia
     todo el espacio libre de la fila y dejaba los cuatro destinos pegados entre
     si con 127px de hueco antes del carrito. Con `space-between` en el
     contenedor, el reparto lo hace el navegador y sale parejo. */
  /* `margin-left: 0` pisa el `auto` de la regla base (linea 1080): ese margen
     automatico se comia TODO el espacio libre de la fila y dejaba los cuatro
     destinos pegados entre si con 127px de hueco antes del carrito. Con el
     margen en cero, `space-between` reparte parejo. */
  .cabecera__carrito { flex: 0 0 auto; margin-left: 0; }
}
