/*
  Piel «Macizo» del aviso y el panel de consentimiento: papel claro, borde de tinta de 4px, canto
  inferior que se hunde al pulsar.

  UNA SOLA HOJA PARA LAS DOS SUPERFICIES. La carga el escaparate (`/estilos/consentimiento.css`,
  copiada por `publico/generar.mjs`) y la importa el aula desde `main.jsx`. Por eso NO usa ni un
  alias de `publico.css` (`--tinta`, `--hueso`, `--ocre`…) ni uno del aula: solo los nombres POR
  PAPEL (`superficie-*`, `papel-*`, `acento-*`, `semantico-*`) y las familias `cuerpo`, `radio`,
  `tactil` y `movimiento` de packages/design-tokens/tokens.json.

  No es purismo. `.aula-clara` (apps/web/src/estilos/index.css) REDEFINE los alias legado dentro del
  aula: `--color-tinta` pasa a #F3F7F4 ahí. Una hoja compartida escrita con alias se vería de un
  color en el escaparate y del contrario en el aula. Los nombres por papel son justo los que
  `.aula-clara` deja sin tocar, y por eso son los únicos que garantizan el mismo píxel en las dos.

  Ni un grosor ni un radio ni una duración a mano: todo sale de las variables. El 44px del objetivo
  táctil es `--tactil-objetivo-minimo`, que es un suelo LEGAL (WCAG 2.5.5 · EN 301 549 · RD
  1112/2018), no una preferencia — se emite desde el token justo para que no se pueda bajar aquí.
*/

/* ─── el aviso (capa 1): informa, no bloquea ─────────────────────────────────────────────────── */
/*
  Está FIJO abajo, nunca centrado ni a pantalla completa: no oscurece la página, no atrapa el foco y
  no impide leer ni usar nada. Un muro que obliga a decidir para poder leer es el patrón que las
  directrices del CEPD tratan como vicio del consentimiento.
*/
/*
  `--consentimiento-hueco-inferior` ES UNA COSTURA, y existe por un choque real entre las dos
  superficies. El escaparate no tiene nada fijo abajo (publico.css solo usa `sticky` arriba), así que
  ahí el hueco vale 0 y el aviso se apoya en el borde de la pantalla. El AULA sí: `App.jsx` pinta en
  móvil una navegación `fixed bottom-0 z-30` con las tres secciones del producto. Con z-index 60, el
  aviso se le pone encima y tapa la navegación principal entera mientras se lee — y un aviso que
  esconde por dónde se sigue es justo lo que las directrices del CEPD tratan como coacción, aunque
  aquí sea sin querer.

  La altura de esa barra la sabe quien la declara, no esta hoja: el número no se adivina aquí. Quien
  monte una superficie con algo fijo abajo declara el hueco en su propia raíz y el aviso se coloca
  encima. Ver el informe: en el aula es una línea en `estilos/index.css`.
*/
.consentimiento-aviso {
  position: fixed;
  inset: auto 0 var(--consentimiento-hueco-inferior, 0px) 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-height: 60vh;
  overflow-y: auto;
  padding: 18px 20px calc(18px + env(safe-area-inset-bottom, 0px));
  background: var(--color-papel-claro);
  color: var(--color-superficie-base);
  border-top: var(--cuerpo-borde) solid var(--color-superficie-base);
  animation: consentimiento-entrar var(--duration-entrada) var(--ease-paso) both;
}

/*
  A partir de 900px de ancho el aviso reparte texto y acciones en dos columnas: en un portátil, una
  franja de borde a borde con el texto a 120 caracteres no se lee, y la prosa del sitio ya está
  limitada por la misma razón.
*/
@media (min-width: 900px) {
  .consentimiento-aviso {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: 28px;
    padding: 20px 32px;
  }
  .consentimiento-aviso__texto { max-width: 68ch; }
}

/*
  CON POCA ALTURA DEJA DE ESTAR FIJO. A 400% de zoom —o en un móvil apaisado— una franja fija abajo
  se come la pantalla y deja contenido inalcanzable (WCAG 1.4.10, reflujo). Como el aviso se inserta
  al final de `<body>`, quitarle la posición fija lo deja después del pie: sigue siendo lo último que
  se lee y ya no tapa nada.
*/
@media (max-height: 480px) {
  .consentimiento-aviso {
    position: static;
    max-height: none;
    animation: none;
  }
}

.consentimiento-aviso__titulo {
  margin: 0 0 6px;
  font-size: var(--text-guia);
  line-height: var(--text-guia--line-height);
  font-weight: 800;
}

.consentimiento-aviso__cuerpo {
  margin: 0;
  max-width: 68ch;
  font-size: var(--text-apoyo);
  line-height: var(--text-apoyo--line-height);
}

.consentimiento-aviso__acciones,
.consentimiento-panel__acciones {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

.consentimiento-aviso__enlace,
.consentimiento-panel__enlace {
  display: inline-flex;
  align-items: center;
  min-height: var(--tactil-objetivo-minimo);
  padding: 0 6px;
  color: var(--color-superficie-base);
  font-size: var(--text-apoyo);
  font-weight: 700;
}

/* ─── botones «Macizo» ───────────────────────────────────────────────────────────────────────── */
/*
  MISMA CLASE PARA ACEPTAR Y PARA RECHAZAR. `--decision` es la única variante de los dos botones que
  toman la decisión: mismo relleno, mismo borde, mismo canto, mismo tamaño, un clic cada uno. La
  AEPD sanciona exactamente lo contrario —un «Aceptar» grande y un «Configurar» en gris—, y la forma
  de que eso no vuelva a pasar por descuido es que no exista una segunda clase que retocar.
*/
.consentimiento-boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tactil-objetivo-minimo);
  min-width: var(--tactil-objetivo-minimo);
  padding: 12px 20px;
  border-radius: var(--radius-boton);
  border: var(--cuerpo-borde) solid var(--consentimiento-canto);
  box-shadow: 0 var(--cuerpo-canto) 0 0 var(--consentimiento-canto);
  font: inherit;
  font-size: var(--text-apoyo);
  font-weight: 700;
  cursor: pointer;
  transition:
    transform var(--duration-instante) var(--ease-paso),
    box-shadow var(--duration-instante) var(--ease-paso);
}

/*
  El canto que se hunde: el gesto físico de «Macizo». Mismo mecanismo que `.boton` de publico.css.

  LO QUE QUEDA DE CANTO SE RESTA, NO SE ESCRIBE. El botón baja `--cuerpo-hundido` y el canto tiene
  que encoger exactamente eso, o el borde inferior se despega del suelo mientras está pulsado. Con
  los tokens de hoy (canto 7, hundido 5) da los mismos 2px que había escritos a mano aquí y en
  `publico.css`; la diferencia es que el día que el dueño engorde el canto —que es LA medida de la
  piel Macizo— el gesto sigue cuadrando solo en vez de romperse en silencio.
*/
.consentimiento-boton:active {
  transform: translateY(var(--cuerpo-hundido));
  box-shadow: 0 calc(var(--cuerpo-canto) - var(--cuerpo-hundido)) 0 0 var(--consentimiento-canto);
}

/*
  Blanco puro sobre `acento-relleno` (#b94e20) da 5,03:1, por encima del 4,5:1 que exige un botón de
  acción. Es el único literal de color de la hoja y es el mismo par ya medido en `.boton-ocre`
  (publico.css): `acento-decoracion` (#e4632b), el naranja vivo, se queda en 3,05:1 y por eso no se
  usa detrás de texto. No hay token de «blanco» en tokens.json — el modelo es de papeles, y este
  blanco no es un papel sino la tinta de un botón relleno. La prueba de contraste del escaparate lo
  mide igualmente, literal incluido.
*/
.consentimiento-boton--decision {
  --consentimiento-canto: var(--color-acento-relleno);
  background: var(--color-acento-relleno);
  color: #ffffff;
}

.consentimiento-boton--secundario {
  --consentimiento-canto: var(--color-superficie-base);
  background: var(--color-papel-apagado);
  color: var(--color-superficie-base);
}

/* ─── el panel (capa 2): se abre a petición, y sí es modal ───────────────────────────────────── */
.consentimiento-fondo {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  /* Derivado del token, no un hex a mano. Si el navegador no entiende `color-mix` se queda sin velo:
     el diálogo sigue siendo usable, que es lo que importa. */
  background: color-mix(in srgb, var(--color-superficie-base) 62%, transparent);
}

.consentimiento-panel {
  display: flex;
  flex-direction: column;
  gap: 18px;
  width: min(100%, 640px);
  max-height: min(88vh, 760px);
  overflow-y: auto;
  padding: 22px;
  background: var(--color-papel-claro);
  color: var(--color-superficie-base);
  border: var(--cuerpo-borde) solid var(--color-superficie-base);
  border-radius: var(--radius-panel);
  box-shadow: 0 var(--cuerpo-canto) 0 0 var(--color-superficie-base);
}

.consentimiento-panel__cabecera {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.consentimiento-panel__titulo {
  margin: 0;
  font-size: var(--text-guia);
  line-height: var(--text-guia--line-height);
  font-weight: 800;
}

.consentimiento-panel__cerrar {
  flex: none;
  min-height: var(--tactil-objetivo-minimo);
  min-width: var(--tactil-objetivo-minimo);
  border: var(--cuerpo-borde-fino) solid var(--color-superficie-base);
  border-radius: var(--radius-control);
  background: var(--color-papel-apagado);
  color: var(--color-superficie-base);
  font: inherit;
  font-size: var(--text-guia);
  line-height: 1;
  cursor: pointer;
}

.consentimiento-panel__intro,
.consentimiento-panel__registro {
  margin: 0;
  font-size: var(--text-apoyo);
  line-height: var(--text-apoyo--line-height);
}

.consentimiento-panel__registro {
  padding-top: 14px;
  border-top: var(--cuerpo-borde-fino) solid var(--color-papel-apagado);
  color: var(--color-macizo-futura-tenue);
}

.consentimiento-panel__cuerpo {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ─── una finalidad ──────────────────────────────────────────────────────────────────────────── */
.consentimiento-finalidad {
  padding: 16px;
  background: var(--color-papel-apagado);
  color: var(--color-superficie-base);
  border: var(--cuerpo-borde-fino) solid var(--color-superficie-base);
  border-radius: var(--radius-control);
}

/*
 * `flex-wrap` NO es decoración: sin él, la etiqueta «No necesita tu consentimiento» se salía de su
 * tarjeta en un móvil de 390 px y quedaba cortada por el borde del panel (medido en Chromium). Un
 * texto recortado en el sitio donde se explica la base legal es información perdida, no un desliz
 * visual. Con `wrap` la etiqueta baja a su propia línea en cuanto no cabe, y `min-width: 0` deja que
 * el título se estreche en vez de empujarla fuera.
 */
.consentimiento-finalidad__cabecera {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}

.consentimiento-finalidad__nombre {
  min-width: 0;
  margin: 0;
  font-size: var(--text-cuerpo);
  line-height: var(--text-cuerpo--line-height);
  font-weight: 800;
}

.consentimiento-finalidad__resumen {
  margin: 0 0 8px;
  font-size: var(--text-apoyo);
  line-height: var(--text-apoyo--line-height);
}

.consentimiento-finalidad__base,
.consentimiento-olvido__nota {
  margin: 0;
  font-size: var(--text-nota);
  line-height: var(--text-nota--line-height);
  color: var(--color-macizo-futura-tenue);
}

/*
  La etiqueta de «no necesita tu consentimiento» / «siempre activa» ocupa el hueco del interruptor
  que NO se pinta. Es texto, no un mando apagado: un interruptor que no gobierna nada hace creer que
  se ha apagado algo.
*/
.consentimiento-etiqueta {
  flex: none;
  padding: 6px 10px;
  border: var(--cuerpo-borde-fino) solid var(--color-superficie-base);
  border-radius: var(--radius-control);
  background: var(--color-papel-claro);
  color: var(--color-superficie-base);
  font-size: var(--text-nota);
  font-weight: 700;
}

/* ─── el interruptor de una finalidad negociable ─────────────────────────────────────────────── */
.consentimiento-interruptor {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: var(--tactil-objetivo-minimo);
  min-width: var(--tactil-objetivo-minimo);
  padding: 0 4px;
  cursor: pointer;
}

/*
  La casilla real NO se esconde con `display: none` (dejaría de recibir foco y de existir para un
  lector de pantalla): se hace transparente y se deja encima de su pista, así que el teclado, el
  puntero y la tecnología de apoyo siguen tratándola como la casilla nativa que es.
*/
.consentimiento-interruptor__casilla {
  position: absolute;
  inset: 0;
  /*
   * `z-index` porque la pista de debajo también está posicionada y, al ir después en el marcado,
   * se pintaba ENCIMA de la casilla: el objetivo que recibía el clic era el adorno, no el control.
   * Con el `<label>` alrededor seguía funcionando de rebote, pero el objetivo pulsable de 44 px que
   * declara esta hoja no era el que de verdad se tocaba, y eso solo se sostiene hasta el primer día
   * que alguien reordene el marcado.
   */
  z-index: 1;
  width: 100%;
  height: 100%;
  min-width: var(--tactil-objetivo-minimo);
  min-height: var(--tactil-objetivo-minimo);
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.consentimiento-interruptor__pista {
  position: relative;
  flex: none;
  width: 56px;
  height: 32px;
  border: var(--cuerpo-borde-fino) solid var(--color-superficie-base);
  border-radius: var(--radius-boton);
  background: var(--color-papel-claro);
  transition: background var(--duration-instante) var(--ease-paso);
}

.consentimiento-interruptor__pista::after {
  content: "";
  position: absolute;
  inset: 3px auto 3px 3px;
  width: 20px;
  border-radius: 50%;
  background: var(--color-superficie-base);
  transition: transform var(--duration-instante) var(--ease-paso);
}

.consentimiento-interruptor__casilla:checked + .consentimiento-interruptor__pista {
  background: var(--color-semantico-normal-relleno);
}

.consentimiento-interruptor__casilla:checked + .consentimiento-interruptor__pista::after {
  transform: translateX(24px);
  background: var(--color-papel-claro);
}

/* El foco se dibuja sobre la pista porque la casilla real es transparente. */
.consentimiento-interruptor__casilla:focus-visible + .consentimiento-interruptor__pista {
  outline: 3px solid var(--color-acento-relleno);
  outline-offset: 3px;
}

/* El nombre ya está en el `<h3>` de al lado: repetirlo en voz alta sobra, pero la casilla necesita
   una etiqueta accesible propia. Se conserva para la tecnología de apoyo y se oculta a la vista. */
.consentimiento-interruptor__texto {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ─── borrar lo guardado ─────────────────────────────────────────────────────────────────────── */
.consentimiento-olvido {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding-top: 16px;
  border-top: var(--cuerpo-borde-fino) solid var(--color-papel-apagado);
}

.consentimiento-olvido__titulo {
  margin: 0;
  font-size: var(--text-cuerpo);
  font-weight: 800;
}

.consentimiento-olvido__aviso:empty { display: none; }

.consentimiento-olvido__aviso {
  margin: 0;
  font-size: var(--text-nota);
  font-weight: 700;
  color: var(--color-semantico-normal-relleno);
}

/* ─── el disparador permanente del pie ───────────────────────────────────────────────────────── */
/*
  Se sirve con `hidden` en el HTML y lo destapa el script (ver index.js): sin JavaScript no hay panel
  que abrir, así que un botón visible sería un botón muerto. El enlace a la política que va a su lado
  sí es HTML de verdad y cumple el deber de información sin JavaScript.
*/
.consentimiento-disparador {
  display: none;
  align-items: center;
  min-height: var(--tactil-objetivo-minimo);
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}

/*
 * La marca la pone `index.js` al montar. Hace falta ADEMÁS de quitar el `hidden` porque el pie del
 * aula lo pinta React DESPUÉS de que este código se ejecute: a esos botones no llega a quitarles
 * nada, y con esta regla aparecen igual en cuanto existen.
 */
:root[data-consentimiento="listo"] .consentimiento-disparador { display: inline-flex; }

/* ─── el anuncio para lectores de pantalla ───────────────────────────────────────────────────── */
/*
  Invisible pero presente en el árbol de accesibilidad. `display:none` o `visibility:hidden` lo
  sacarían de ese árbol y no se anunciaría nada, que es justo lo contrario de lo que hace falta.
*/
.consentimiento-anuncio {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@keyframes consentimiento-entrar {
  from { transform: translateY(100%); }
  to { transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  .consentimiento-aviso { animation: none; }
  .consentimiento-boton,
  .consentimiento-interruptor__pista,
  .consentimiento-interruptor__pista::after { transition: none; }
}
