/* Componentes del concurso.
 *
 * Implementacion de DESIGN.md ("Pa'lais - Dia de Muertos Edition") sobre CSS
 * propio: no hay framework. Dos decisiones atraviesan todo el archivo.
 *
 * 1. MOVIL PRIMERO. Los estilos base son los de 360 px y las media queries solo
 *    ANADEN cosas. Escribir al reves (escritorio por defecto y `max-width` para
 *    arreglar) deja siempre un estado intermedio roto que nadie ve porque se
 *    probó en los dos extremos.
 *
 * 2. UNA REGLA DE COLOR. El cempasuchil (#e85d04) es el unico color que
 *    rellena un boton o un enlace. El rosa mexicano y el morado luto decoran:
 *    blobs, papel picado, el CTA final. Si dos colores se pelean por ser la
 *    accion, el sistema se rompio y la pagina se vuelve un carnaval.
 *
 * Las classes que ya usaban las vistas se conservan: `.envoltura`, `.tarjeta`,
 * `.obra__marco`, `.cifra__numero` y demas. Lo que cambia es como se ven.
 */

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

/* `hidden` tiene que ganar, y por eso lleva `!important`.
 *
 * Sin esto el atributo `hidden` NO oculta nada en cuanto un componente le pone su
 * propio `display`: los dos selectores valen lo mismo (0,1,0), asi que gana el que
 * va despues en la cascada, y `.boton { display: inline-flex }` esta despues que
 * el estilo del navegador. Se vio en compartir: los botones que Stimulus deberia
 * enseñar al conectarse salian a la vista desde el principio, asi que sin
 * JavaScript ofrecian Instagram y copiar sin que ninguna de las dos cosas
 * hiciera nada. */
[hidden] { display: none !important; }

/* -------------------------------------------------------------------- base */

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* El borde de foco de un enlace no debe quedar bajo la cabecera fija. */
  scroll-padding-top: 5rem;
}

body {
  margin: 0;
  min-height: 100dvh;
  font-family: var(--f-texto);
  font-size: var(--t-body);
  line-height: var(--t-body-lh);
  letter-spacing: var(--t-body-tr);
  color: var(--c-niebla);
  /* El fondo (foto + velo) lo pone `fondos.css` segun la pagina. */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* El salto al contenido es lo primero que recibe el foco: sin el, quien navega
 * con teclado tiene que recorrer el menu en cada pagina. */
.salta-contenido {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.salta-contenido:focus {
  position: fixed;
  top: 0.75rem; left: 0.75rem;
  z-index: 100;
  width: auto; height: auto;
  margin: 0;
  padding: 0.75rem 1.25rem;
  clip-path: none;
  background: var(--c-cempasuchil);
  color: var(--c-negro-humo);
  font-family: var(--f-texto);
  font-size: var(--t-body-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  text-decoration: none;
  border-radius: var(--r-pill);
}

/* Texto que existe para el lector de pantalla y no se ve. Es lo que hace que un
 * boton de solo icono se pueda identificar.
 *
 * No es lo mismo que `hidden` ni que `display: none`: un elemento con `display:
 * none` NO esta en el arbol de accesibilidad, asi que un boton de icono al que
 * solo se le pone `aria-label` se anuncia con el nombre del icono y nada mas --
 * "boton" a secas, y en dos botones de la misma fila no hay forma de saber cual
 * es cual. Con el texto oculto dentro, el nombre sale entero.
 *
 * El texto se recorta con `clip-path` en vez de con `overflow: hidden` a secas
 * porque este no lo esconde de verdad si el elemento no tiene tamano: `clip-path`
 * si recorta el pintado, que es lo que hace falta para que no se reserve hueco. */
.solo-lectores {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Tipografia. La display es condensada y mayusculas: solo desde 24px, nunca en
 * texto corrido (la regla de DESIGN.md que mas se viola por costumbre). */
h1, h2, h3, h4 {
  font-family: var(--f-display);
  font-weight: 400;
  line-height: 1.0;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin: 0;
  /* Bebas Neue es alta y angosta; sin esto los titulares se cortan en iOS. */
  padding-block: 0.08em;
}

h1 { font-size: clamp(2rem, 8vw, var(--t-display)); }
h2 { font-size: clamp(1.5rem, 5.5vw, var(--t-heading)); }
h3 { font-size: clamp(1.25rem, 4vw, var(--t-heading-sm)); }
h4 { font-size: clamp(1.125rem, 3.5vw, var(--t-subheading)); }

p { margin: 0 0 var(--e-4); }
p:last-child { margin-bottom: 0; }

a { color: var(--c-cempasuchil); text-underline-offset: 3px; }
a:hover { color: var(--c-ambar); }

img { max-width: 100%; height: auto; display: block; }

/* El foco tiene que verse sobre crema Y sobre negro. El anillo doble hace las
 * dos cosas: el cempasuchil se ve en las tres superficies. */
:focus-visible {
  outline: 3px solid var(--c-cempasuchil);
  outline-offset: 3px;
  border-radius: var(--r-chico);
}

/* ---------------------------------------------------------------- estructura */

.envoltura { width: min(100% - 2rem, var(--ancho-max)); margin-inline: auto; }

.seccion { padding-block: var(--e-7); }
.seccion--apretada { padding-block: var(--e-6); }

/* Los saltos de espaciado salen de la escala, nunca de un numero suelto. */
.salto { margin-top: var(--e-6); }
.salto--chico { margin-top: var(--e-4); }

.tenue { color: var(--c-niebla-tenue); }
.pequeno { font-size: var(--t-body-sm); }
.centrado { text-align: center; }

/* ------------------------------------------------------------- medidas
 *
 * Antes de la limpieza esto vivia en `style="max-width: 34rem"` pegado en cinco
 * vistas, con tres anchos distintos y solo dos de los cinco centrados. Un
 * formulario de la mitad de ancho que no esta centrado en una pantalla de
 * escritorio se ve como un error de maquetacion, no como una decision.
 *
 * Estas tres clases sustituyen a los cinco estilos sueltos: una medida, y el
 * centrado como algo explicito y no como un accidente del ancho. */

.formulario { max-width: 34rem; margin-inline: auto; }
.formulario--ancho { max-width: 42rem; }
.formulario--angosto { max-width: 28rem; }

/* Separador. Reemplaza cuatro `<hr style="...">` distintos. */
.separador {
  border: 0;
  border-top: 1px solid var(--s-hueso-hondo);
  margin-block: var(--e-6);
}

/* Un titulo de seccion que no compite con el `h1` de la pagina. */
.seccion__subtitulo {
  font-family: var(--f-texto);
  font-size: var(--t-body-sm);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-niebla-tenue);
}

/* Banda: una seccion con su propio fondo, para separar bloques sin que el ojo
 * tenga que confiar solo en el margen. El velo negro al 20% es lo que hace el
 * efecto sobre la foto, sin tapestryarla. */
.seccion--banda { background: rgb(0 0 0 / 0.2); }

/* Salto grande: para separar un bloque del anterior cuando los dos son
 * secciones completas y el ritmo normal se queda corto. */
.salto--seccion { margin-top: var(--e-8); }

/* Rotulo con aire vertical, para partir un formulario en dos (por ejemplo
 * "o con tu correo" en medio de las dos formas de entrar). */
.rotulo--separado { margin-block: var(--e-5); }

/* El rotulo es la voz de UI en mayusculas con tracking amplio: es lo que da el
 * aire editorial del sistema. */
.rotulo {
  font-family: var(--f-texto);
  font-size: var(--t-caption);
  font-weight: 600;
  line-height: var(--t-caption-lh);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--c-cempasuchil);
  margin: 0 0 var(--e-2);
}

/* ------------------------------------------------------------- tipografia */

/* El texto de la obra. Esto es solo tipografia: el recorte a renglones vive mas
 * abajo, acotado a `.tarjeta--obra`, porque la ficha de /calaveritas/:id usa
 * esta misma clase para el texto ENTERO y ahi no se recorta nada. */
.obra__texto {
  font-family: var(--f-serif);
  font-size: var(--t-serif-body);
  line-height: var(--t-serif-body-lh);
  white-space: pre-wrap;
  overflow-wrap: break-word;
  padding: var(--e-4);
}

/* Quien escribio la calaverita, en script.
 *
 * Dos clases y no una porque el peso cambia con el contexto: en la ficha de la
 * obra el nombre es el cierre y va en cempasuchil; en la rejilla de la galeria
 * compite con el texto de otras quince calaveritas y se apaga a rosa mexicano.
 * Antes las dos eran el mismo selector y la ficha necesitaba un
 * `style="color: ..."` para distinguirse. */
.obra__firma {
  font-family: var(--f-mano);
  font-size: var(--t-script);
  line-height: var(--t-script-lh);
  color: var(--c-cempasuchil);
}

.tarjeta__autor {
  font-family: var(--f-mano);
  font-size: var(--t-script);
  line-height: var(--t-script-lh);
  color: var(--c-rosa-mexicano);
}

.ayuda { font-size: var(--t-body-sm); color: var(--c-tinta-media); font-weight: 400; }
.pista { font-size: var(--t-body-sm); color: var(--c-niebla-tenue); }

/* ---------------------------------------------------------------- cabecera */

.cabecera {
  position: sticky; top: 0; z-index: 40;
  background: rgba(26, 26, 26, 0.92);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid rgb(232 93 4 / 0.2);
  /* Con notch en landscape, el contenido se meteria debajo. */
  padding-top: env(safe-area-inset-top);
}

.cabecera__fila {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--e-3);
  min-height: 60px;
}

.marca {
  display: inline-flex; align-items: center; gap: var(--e-2);
  color: var(--c-blanco-calavera);
  text-decoration: none;
  min-width: 0;
}
.marca:hover { color: var(--c-blanco-calavera); }

/* El logo de la panaderia. El SVG de cempasuchil que estaba antes se sustituyo
 * por el archivo real: `width` y `height` explicitos para que no salte el
 * layout al cargar (CLS). */
.marca__logo {
  width: 36px; height: 36px;
  object-fit: contain;
  flex: none;
}
.marca__nombre {
  font-family: var(--f-display);
  font-size: 1.125rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-cempasuchil);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Navegacion. En movil no cabe en una fila: los enlaces se-develop en un bloque
 * debajo de la marca, y la fila conserva marca + cuenta. */
.nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e-1) var(--e-4);
}

.nav a,
.nav__boton {
  display: inline-flex;
  align-items: center;
  min-height: 44px;              /* target tactil minimo */
  padding: var(--e-2) 0;
  color: var(--c-blanco-calavera);
  background: none;
  border: 0;
  font-family: var(--f-texto);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color var(--mov-rapido), border-color var(--mov-rapido);
}
.nav a:hover,
.nav__boton:hover {
  color: var(--c-ambar);
  border-bottom-color: var(--c-ambar);
}

.nav__enlace--activo {
  color: var(--c-ambar);
  border-bottom-color: var(--c-ambar);
}

/* "Salir" es un boton (DELETE) dentro del menu, no un enlace. Sin esto se ve
 * como un bloque gris entre los enlaces y el menu deja de leerse como una fila
 * de opciones iguales. El estilo se copia del de `.nav a` punto por punto. */
.nav__salir { margin: 0; display: flex; }

/* La accion de cuenta es el unico boton relleno del menu, porque es la unica
 * accion de la cabecera. */
.nav__cuenta {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: var(--e-2) var(--e-4);
  border-radius: var(--r-pill);
  background: var(--c-cempasuchil);
  color: var(--c-negro-humo);
  font-family: var(--f-texto);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--mov-rapido);
}
.nav__cuenta:hover { background: var(--c-ambar); color: var(--c-negro-humo); }

/* ------------------------------------------------------------------ botones
 *
 * Pastilla de 32px, la forma de DESIGN.md. El relleno es cempasuchil y nada
 * mas. El outline rosa es para acciones secundarias y jamas compite con el
 * relleno.
 */

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  /* 48px: por debajo de 44px el dedo la falla. */
  min-height: 48px;
  padding: var(--e-3) var(--e-5);
  font-family: var(--f-texto);
  font-size: var(--t-body-sm);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  border: 2px solid transparent;
  border-radius: var(--r-pill);
  transition: background-color var(--mov-medio), color var(--mov-medio),
              border-color var(--mov-medio), transform var(--mov-rapido);
}

.boton:active { transform: translateY(1px); }

.boton--principal { background: var(--c-cempasuchil); color: var(--c-negro-humo); }
.boton--principal:hover { background: var(--c-ambar); color: var(--c-negro-humo); }

/* Accion secundaria: el borde de rosa mexicano que DESIGN.md reserva para
 * "VER CALAVERITAS" e "INICIAR SESION".
 *
 * El texto NO puede ser el mismo rosa. Medido: rosa mexicano sobre negro de humo
 * da 3.84:1, y la etiqueta de un boton son 12-13 px en mayusculas, que es texto
 * pequeno y necesita 4.5:1. Con un unico color el componente queda por debajo de
 * AA. Asi que el color se parte en dos, que es lo que hace la especificacion sin
 * decirlo:
 *
 *   - el borde se queda en rosa mexicano (3.84:1). Es un componente de
 *     interfaz, y para eso el umbral es 3:1 (WCAG 1.4.11), que si cumple.
 *   - la etiqueta pasa a rosa chicle (#ff85a1, 7.56:1), que es el mismo rosa
 *     un paso mas claro y si llega a texto pequeno.
 *
 * El resultado se sigue leyendo como el boton rosado de DESIGN.md, pero ahora
 * se puede leer. */
.boton--contorno {
  background: transparent;
  border-color: var(--c-rosa-mexicano);
  color: var(--c-rosa-chicle);
}
.boton--contorno:hover {
  background: rgb(229 0 125 / 0.16);
  border-color: var(--c-rosa-chicle);
  color: var(--c-rosa-chicle);
}

/* Accion terciaria sobre fondo oscuro: sin borde, el texto cambia de color. */
.boton--fantasma {
  background: transparent;
  color: var(--c-blanco-calavera);
  border-color: rgba(255, 245, 230, 0.35);
}
.boton--fantasma:hover { background: rgb(255 245 230 / 0.08); color: var(--c-blanco-calavera); }

.boton--peligro { background: var(--c-alerta); color: var(--c-blanco-calavera); }
.boton--peligro:hover { background: #c9503d; color: var(--c-blanco-calavera); }

/* Accion sobre superficie clara: el mismo cempasuchil, pero con texto oscuro,
 * que es el unico par que pasa contraste AA a tamano pequeno. */
.boton--chico { min-height: 40px; padding: var(--e-2) var(--e-4); font-size: 0.75rem; }
.boton--ancho { width: 100%; }

.boton[disabled],
.boton[aria-disabled="true"] { opacity: 0.55; pointer-events: none; }

/* ------------------------------------------------------------------ tarjetas
 *
 * La tarjeta de calaverita: #fff5e6, radio 12px, borde de 1px de cempasuchil al
 * 20%. Sin sombra: la separacion viene del borde y del contraste de superficie.
 * La sombra calida solo aparece al pasar encima.
 */

.tarjeta {
  background: var(--c-blanco-calavera);
  color: var(--c-tinta);
  border: 1px solid rgb(232 93 4 / 0.2);
  border-radius: var(--r-medio);
  padding: var(--card-padding);
  /* La categoria se identifica con una linea de papel picado arriba: color sin
   * necesidad de etiqueta de texto.
   *
   * El color lo pone la vista en `--borde-categoria` (helper `color_de_categoria`:
   * rosa mexicano para literarias, rosa chicle para infantiles). El fallback es
   * TRANSPARENTE y no cempasuchil a proposito: sin el, una tarjeta que no es de
   * ninguna categoria -un formulario, un aviso, una tarjeta de la portada-
   * heredaria una barra naranja que nadie pidio, y el acierto se vuelve ruido.
   * Todas las tarjetas reservan los 4px de igual manera, asi que no hay salto
   * entre unas y otras. */
  border-top: 4px solid var(--borde-categoria, transparent);
}

/* Superficie elevada sobre el fondo oscuro: un paso por encima de la base, con
 * el mismo borde de 1px. Sin sombra dura. */
.tarjeta--oscura {
  background: var(--s-noche-alta);
  color: var(--c-niebla);
  border: 1px solid rgb(232 93 4 / 0.2);
}

/* La tarjeta infantil necesita la paleta suave: rosa chicle en borde punteado y
 * el titulo en script, como pide DESIGN.md para la seccion de ninos. */
.tarjeta--infantil {
  background: var(--c-crema-papel);
  border: 2px dashed var(--c-rosa-chicle);
  border-radius: var(--r-grande);
  padding: var(--e-4);
}
.tarjeta--infantil h3 {
  font-family: var(--f-mano);
  text-transform: none;
  letter-spacing: normal;
  font-size: 1.5rem;
  color: var(--c-rosa-mexicano);
}

/* La seccion infantil baja el rigor de la tipografia: el titular de la pagina va
 * en script, como el resto de las voces del sistema que hablan de las personas
 * y no de la mecanica del concurso. El h1 es el unico que cambia; los h2 de
 * dentro (el formulario) siguen siendo display, porque son acciones. */
.seccion--infantil h1 {
  font-family: var(--f-mano);
  text-transform: none;
  letter-spacing: normal;
  color: var(--c-rosa-chicle);
}

/* Rejillas. `minmax(min(100%, X), 1fr)` es el truco que evita el desborde en
 * movil: sin ese `min(100%, ...)` una columna de 260px no baja de 260px y
 * empuja el scroll horizontal en una pantalla de 360. */
.rejilla { display: grid; gap: var(--e-4); }
/* La galeria no reparte columnas sola: las cuenta el diseno (1 en movil, 2 en
 * tablet, 3 en escritorio) porque el formato de la tarjeta depende de cuantas
 * caben. Con `auto-fill` el numero dependia del tamano del track y la rejilla
 * perdia una columna justo al ensanchar. Ver la seccion "carta de obra
 * apaisada" mas abajo. */
.rejilla--obra { grid-template-columns: minmax(0, 1fr); }
.rejilla--dos { grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); }
.rejilla--tres { grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }

/* -------------------------------------------------------------- calaverita */

/* Las tres filas de la galeria (foto, video y texto) tienen la misma caja, asi
 * que la comparacion es entre obras y no entre formatos. El padding va aparte
 * porque la foto y la portada llegan al borde y el texto necesita aire. */
.tarjeta--obra { --card-padding: 0; overflow: hidden; }
.tarjeta--obra > p { padding-inline: var(--e-4); }
.tarjeta--obra .tarjeta__firma { padding: var(--e-3) var(--e-4) 0; margin-top: 0; }
.tarjeta--obra .tarjeta__autor { padding: 0 var(--e-4); }
.tarjeta--obra .votos { padding: 0 var(--e-4) var(--e-4); }

.obra__marco {
  aspect-ratio: 3 / 4;
  background: var(--s-noche-media);
  overflow: hidden;
  display: grid;
  place-items: center;
  position: relative;
}
.obra__marco img { width: 100%; height: 100%; object-fit: cover; }

/* La imagen de la ficha se abre a pantalla completa al pulsarla. El enlace se
 * comporta como parte del marco --sin subrayado ni color de enlace-- y el cursor
 * de lupa es lo unico que avisa de que ahi se puede pulsar. */
.obra__zoom { display: block; width: 100%; height: 100%; cursor: zoom-in; }

/* El visor de pantalla completa.
 *
 * `showModal()` lo pinta en la capa superior, asi que ocupa la pantalla sin tocar
 * la rejilla de la ficha (por eso vive dentro de la columna y no pasa nada). Los
 * valores que el navegador trae para `<dialog>` --margen automatico y ancho
 * ajustado al contenido-- se reescriben para que llene. */
.visor {
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: rgb(26 26 26 / 0.94);
}

.visor::backdrop { background: rgb(26 26 26 / 0.94); }

.visor__imagen { width: 100%; height: 100%; object-fit: contain; }

/* Cerrar. El area de 44 px es la minima que se puede tocar con el dedo sin
 * fallar, y va arriba a la derecha, que es donde se busca. */
.visor__cerrar {
  position: absolute;
  top: var(--e-4);
  right: var(--e-4);
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: rgb(26 26 26 / 0.6);
  color: var(--c-niebla);
  cursor: pointer;
}
.visor__cerrar:hover { background: rgb(26 26 26 / 0.85); }
.visor__cerrar svg { width: 24px; height: 24px; stroke: currentColor; stroke-width: 2; fill: none; }

/* Aparece con un fundido corto, y solo para quien no pidio menos movimiento. En
 * un navegador sin `@starting-style` la regla se ignora y sale de golpe, que
 * sigue estando bien. */
@media (prefers-reduced-motion: no-preference) {
  .visor[open] { transition: opacity 150ms ease-out; }

  @starting-style {
    .visor[open] { opacity: 0; }
  }
}

/* El embed de YouTube es 16:9 fijo y no se puede forzar a 3:4: se deformaria o
 * dejaria bandas negras. El margen lo pone el marco, no el iframe. */
.obra__marco--video { aspect-ratio: 16 / 9; position: relative; }
.obra__video { width: 100%; height: 100%; border: 0; }
.obra__miniatura-video { display: block; }

/* El triangulo del video va CENTRADO sobre la portada: la foto es 4:3 y el marco
 * 16:9, asi que un triangulo pegado a una esquina caeria sobre una zona distinta
 * en cada tarjeta. `currentColor` lo tiñe de crema, que es el color del marco. */
.obra__play {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 2.75rem;
  height: 2.75rem;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgb(26 26 26 / 0.55);
  box-shadow: 0 0 0 1px rgb(255 245 230 / 0.5);
  /* Por encima del difuminado de abajo: si no, la mitad inferior del boton
   * queda lavada por el crema de la tarjeta. */
  z-index: 1;
}
.obra__play::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  transform: translate(-40%, -50%);
  border-block: 0.45rem solid transparent;
  border-inline-start: 0.7rem solid var(--c-crema-papel);
}

/* El recorte va por CSS y no solo por el helper: `-webkit-line-clamp` es lo que
 * garante el alto, porque el texto trae saltos de linea reales (`pre-wrap`) y un
 * corte por caracteres deja renglones a medio salir. El helper recorta igual para
 * que lo que llega al navegador no sea la obra entera.
 *
 * El recorte va acotado a la TARJETA y no a `.obra__texto` a secas: la ficha de
 * la obra usa la misma clase para el texto entero, y si el recorte viviera en la
 * clase base la ficha mostraria nueve renglones de una calaverita que cabe en
 * cuarenta. Alla se lee completa; aqui se decide si interesa. */
.obra__marco--texto {
  aspect-ratio: 3 / 4;
  background: var(--c-crema-papel);
  align-items: stretch;
}
.tarjeta--obra .obra__marco--texto .obra__texto {
  display: -webkit-box;
  -webkit-line-clamp: 9;
  line-clamp: 9;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.votos { font-family: var(--f-texto); font-weight: 600; color: var(--c-cempasuchil-osc); }

/* La firma va debajo del texto de la calaverita, antes que el nombre de quien
 * la escribio. Es el cierre de la poema, no un pie de foto: por eso script y en
 * rosa, y por eso lleva margen arriba para separarse del texto. */
.tarjeta__firma { margin-top: var(--e-3); }

/* ============================================================================
 * CARTA DE OBRA APASADA
 *
 * Con una sola columna la calaverita se lee como un retrato: la foto va en 3:4
 * y el texto deja nueve renglones. En cuanto caben dos columnas la tarjeta se
 * vuelve apaisada, porque a lo ancho hay sitio para menos letra: la media pasa
 * a una banda 16:9 —la misma para foto, video y texto, para que las tres filas
 * sigan alineadas— y el texto se recorta a cuatro renglones. La banda de la
 * imagen y la del video se difuminan hacia abajo para fundirse con el papel de
 * la tarjeta; la de texto no, porque no hay imagen que disolver.
 *
 * El corte va en 480px porque ahi es exactamente donde la rejilla pasa a dos
 * columnas, y es el complemento del bloque `max-width: 480px` de mas abajo: si
 * se moviera uno de los dos, habia anchos con dos cartas verticales o con una
 * carta apaisada sola.
 *
 * Todo lo de aqui va con `.tarjeta--obra` delante a proposito. La ficha de
 * /calaveritas/:id reutiliza `.obra__marco` y `.obra__texto` para la obra
 * entera, y ahi la carta tiene que seguir en vertical y con el texto completo:
 * es la unica pagina donde la calaverita se lee de principio a fin.
 * ========================================================================== */
@media (min-width: 480px) {
  .rejilla--obra { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .tarjeta--obra .obra__marco,
  .tarjeta--obra .obra__marco--video,
  .tarjeta--obra .obra__marco--texto { aspect-ratio: 16 / 9; }

  .tarjeta--obra .obra__marco:not(.obra__marco--texto)::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    height: 40%;
    background: linear-gradient(to bottom, transparent, var(--c-blanco-calavera));
    pointer-events: none;
  }

  .tarjeta--obra .obra__marco--texto .obra__texto {
    -webkit-line-clamp: 4;
    line-clamp: 4;
  }

  .tarjeta--obra .tarjeta__firma {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}

/* Fila de acciones al pie de un formulario o de una tarjeta.
 *
 * En movil se apilan a ancho completo (un boton de 44 px de ancho no se pulsa)
 * y en tablet se alinean a la derecha, que es donde el ojo ya espera el final
 * de una accion. */
.acciones,
.acciones-obra {
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
  margin-top: var(--e-5);
}

/* -------------------------------------------------------------- zona de voto */

.zona-voto { display: grid; gap: var(--e-2); margin-top: var(--e-3); }

.zona-voto__hecho {
  display: flex; align-items: center; gap: var(--e-2);
  font-weight: 600; font-size: var(--t-body-sm);
  color: var(--c-exito);
}
.zona-voto__espera { color: var(--c-aviso); }
.zona-voto__mal { color: var(--c-alerta); font-size: var(--t-body-sm); }

.pide-correo {
  display: grid; gap: var(--e-2);
  padding: var(--e-3);
  background: var(--s-noche-media);
  border: 1px dashed rgba(232, 93, 4, 0.45);
  border-radius: var(--r-chico);
}
.pide-correo p { margin: 0; font-size: var(--t-caption); color: var(--c-niebla-tenue); }
.pide-correo__fila { display: flex; gap: var(--e-2); }
.pide-correo input { flex: 1 1 auto; min-width: 0; }

/* El campo vive dentro de una fila con el boton al lado, asi que no puede heredar
 * el `width: 100%` del input generico: sin `min-width: 0` el flex lo empuja y la
 * fila desborda en movil. */
.zona-voto__campo { width: auto; min-width: 0; flex: 1 1 auto; }

/* Aviso de "esta obra se modifico despues de salir".
 *
 * `.piquete` (panel de quien participo) y `.modificacion` (quien la lee) son el
 * mismo dato con dos nombres. Se estilizan juntos a proposito: si un dia se
 * separan, es porque de verdad significan cosas distintas, y ese cambio tiene que
 * ser deliberado.
 *
 * En un concurso de libre expresion este aviso no es un tecnicismo: quien lee una
 * version corregida creeria que siempre fue asi. Por eso lleva borde, no solo
 * texto gris, y por eso la tinta es mas fuerte que un `.tenue` normal. */
.piquete,
.modificacion {
  margin-block: var(--e-3);
  padding: var(--e-3);
  border-left: 3px solid var(--c-ambar);
  background: rgb(255 158 0 / 0.1);
  color: var(--c-ambar);
  font-size: var(--t-body-sm);
}

/* ------------------------------------------------------------------ avisos
 *
 * El color de un aviso es el unico color del sistema que puede ser rojo o verde:
 * comunica estado, y esa es su unica funcion. */
.aviso {
  padding: var(--e-3) var(--e-4);
  border-radius: var(--r-chico);
  border-left: 4px solid;
  margin-bottom: var(--e-4);
  font-size: var(--t-body-sm);
}
.aviso--ok    { background: var(--c-exito-claro);  color: #1d3b26; border-color: var(--c-exito); }
.aviso--mal   { background: var(--c-alerta-claro); color: #6d2114; border-color: var(--c-alerta); }
.aviso--info  { background: var(--c-aviso-claro);  color: #5c4808; border-color: var(--c-aviso); }

/* ---------------------------------------------------------------- formulario
 *
 * Inputs: fondo crema, borde de 1px, radio 8px, min-height 48px para el dedo.
 */

.campo { display: grid; gap: var(--e-2); margin-bottom: var(--e-4); }

.etiqueta {
  font-size: var(--t-caption);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-cempasuchil);
}

input[type="text"], input[type="email"], input[type="password"], input[type="number"],
input[type="url"], input[type="search"], textarea, select {
  font-family: var(--f-texto);
  font-size: 1rem;               /* 16px: por debajo iOS hace zoom al enfocar */
  line-height: 1.5;
  width: 100%;
  min-height: 48px;
  padding: var(--e-3);
  background: var(--c-crema-papel);
  color: var(--c-tinta);
  border: 1px solid var(--s-hueso-hondo);
  border-radius: var(--r-chico);
  transition: border-color var(--mov-rapido), box-shadow var(--mov-rapido);
}
input:focus, textarea:focus, select:focus {
  border-color: var(--c-cempasuchil);
  box-shadow: 0 0 0 3px rgb(232 93 4 / 0.22);
  outline: none;
}

input[type="file"] {
  font-family: var(--f-texto);
  font-size: var(--t-body-sm);
  padding: var(--e-3);
  width: 100%;
  background: var(--c-hueso-tenue, var(--c-crema-papel));
  color: var(--c-tinta);
  border: 1px dashed var(--s-hueso-hondo);
  border-radius: var(--r-chico);
}

textarea { min-height: 9rem; resize: vertical; line-height: 1.6; }

.contador { font-size: var(--t-caption); color: var(--c-tinta-media); text-align: right; }

/* Casilla de consentimiento: grande, porque legalmente tiene que poder leerse. */
.consentimiento {
  display: flex;
  gap: var(--e-3);
  align-items: flex-start;
  padding: var(--e-3);
  background: var(--c-crema-papel);
  border: 1px solid var(--s-hueso-hondo);
  border-radius: var(--r-chico);
  margin-bottom: var(--e-3);
}
.consentimiento input {
  width: 1.5rem; height: 1.5rem;
  flex: none;
  margin-top: 0.1rem;
  accent-color: var(--c-cempasuchil);
}
.consentimiento label { font-size: var(--t-body-sm); line-height: 1.5; }

/* Asentamiento pendiente: el bloque de casillas vive DENTRO de la tarjeta del
   niño que lo necesita, no en una pantalla aparte. El margen superior separa
   la ficha del formulario que la desbloquea. */
.consentimiento-pendiente {
  margin-top: var(--e-4);
  padding-top: var(--e-4);
  border-top: 1px dashed var(--s-hueso-hondo);
}
.consentimiento-pendiente .ayuda { margin-bottom: var(--e-3); }

/* Campo trampa: fuera de pantalla, no `display: none` (los bots lo saltan). */
.trampa {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* -------------------------------------------------------------------- hero
 *
 * "Debe sentirse como entrar a un altar": negro de humo, titular display en
 * cempasuchil, y la bajada en script. El fondo ya lo pone `fondos.css`.
 */

.hero {
  padding-block: var(--e-8) var(--e-7);
  position: relative;
  overflow: hidden;
}

.hero__titulo {
  margin-block: var(--e-3) var(--e-4);
  max-width: 18ch;
  color: var(--c-cempasuchil);
}

/* La bajada lleva la script: es la voz humana del sistema, la que susurra. */
.hero__bajada {
  font-family: var(--f-mano);
  font-size: clamp(1.375rem, 5vw, 2.25rem);
  line-height: 1.25;
  color: var(--c-ambar);
  max-width: 34ch;
}

.hero__acciones {
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
  margin-top: var(--e-5);
}

/* Cifras: numero display en cempasuchil, etiqueta en sans tracking amplio. */
.cifras {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--e-5) var(--e-4);
  margin-top: var(--e-7);
}
.cifra__numero {
  font-family: var(--f-display);
  font-size: clamp(2rem, 8vw, 2.75rem);
  line-height: 1;
  letter-spacing: 0.04em;
  color: var(--c-cempasuchil);
}
.cifra__texto {
  font-size: var(--t-caption);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-niebla-tenue);
  margin-top: var(--e-1);
}

/* Cuenta regresiva: el lenguaje de las cifras del hero, pero con su propio marco.
 * Una sola cuenta a la vez y la decide el servidor segun la fecha; ver
 * `ConcursoHelper#cuenta_regresiva_del_concurso`. */
.cuenta {
  display: inline-flex;
  flex-direction: column;
  gap: var(--e-2);
  margin-top: var(--e-6);
  padding: var(--e-4) var(--e-5);
  border: 1px solid rgba(255, 245, 230, 0.18);
  border-radius: var(--r-medio);
}
.cuenta__rotulo {
  font-size: var(--t-caption);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-niebla-tenue);
}
.cuenta__fallback {
  font-family: var(--f-display);
  font-size: clamp(1.5rem, 6vw, 2rem);
  line-height: 1;
  color: var(--c-cempasuchil);
}
.cuenta__reloj { display: flex; gap: var(--e-4); }
.cuenta__bloque {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 2.5ch;
}
.cuenta__numero {
  font-family: var(--f-display);
  font-size: clamp(1.75rem, 7vw, 2.5rem);
  line-height: 1;
  letter-spacing: 0.04em;
  color: var(--c-cempasuchil);
  font-variant-numeric: tabular-nums;
}
.cuenta__unidad {
  font-size: var(--t-caption);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-niebla-tenue);
  margin-top: var(--e-1);
}

/* ------------------------------------------------------------------- filtros
 *
 * Pastillas con el mismo lenguaje del boton: relleno cempasuchil para el activo.
 */

.filtros { display: flex; gap: var(--e-2); flex-wrap: wrap; margin-bottom: var(--e-6); }
.filtro {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--e-2) var(--e-4);
  border-radius: var(--r-pill);
  border: 1px solid rgba(255, 245, 230, 0.28);
  color: var(--c-niebla);
  font-size: var(--t-body-sm);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-decoration: none;
  transition: background-color var(--mov-rapido), border-color var(--mov-rapido), color var(--mov-rapido);
}
.filtro:hover { background: rgb(255 245 230 / 0.08); color: var(--c-blanco-calavera); }
.filtro--activo {
  background: var(--c-cempasuchil);
  border-color: var(--c-cempasuchil);
  color: var(--c-negro-humo);
}

.paginacion {
  display: flex;
  gap: var(--e-3);
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  margin-top: var(--e-7);
}

/* ------------------------------------------------------------------ tablas */

.tabla { width: 100%; border-collapse: collapse; font-size: var(--t-body-sm); }

/* Una tabla de tres columnas no cabe en 360 px. En movil se convierte en filas
 * apiladas: la cabecera se oculta y cada celda ocupa el ancho completo. Es
 * mejor que un scroll horizontal, que esconde informacion sin avisar. */
.tabla thead { display: none; }
.tabla tbody { display: block; }
.tabla tr {
  display: block;
  padding: var(--e-3) 0;
  border-bottom: 1px solid rgb(255 245 230 / 0.12);
}
.tabla td {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--e-4);
  padding: var(--e-1) 0;
  border: 0;
  text-align: left;
}
.tabla td::before {
  content: attr(data-etiqueta);
  flex: none;
  font-size: var(--t-caption);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-cempasuchil);
}
.tabla tr:hover td { background: rgb(255 245 230 / 0.04); }
.tabla__vacia { color: var(--c-niebla-tenue); font-style: italic; }

/* -------------------------------------------------------------------- legal */

.legal { max-width: 72ch; }
.legal h2 { margin-top: var(--e-6); }
.legal h3 { margin-top: var(--e-5); }
.legal ul { padding-left: 1.25rem; }
.legal li { margin-bottom: var(--e-2); }

.marca-legal {
  padding: var(--e-4);
  background: var(--c-aviso-claro);
  color: #5c4808;
  border-left: 4px solid var(--c-aviso);
  border-radius: var(--r-chico);
  margin-bottom: var(--e-5);
}

/* -------------------------------------------------------------------- admin */

.admin { font-size: var(--t-body-sm); }
.admin__barra {
  display: flex;
  gap: var(--e-4);
  align-items: center;
  flex-wrap: wrap;
  padding-block: var(--e-3);
  border-bottom: 1px solid rgb(232 93 4 / 0.2);
  margin-bottom: var(--e-6);
}
.admin h1 { font-size: var(--t-heading-sm); }

.estados { display: inline-flex; gap: var(--e-2); flex-wrap: wrap; margin-bottom: var(--e-5); }
.estado {
  font-size: var(--t-caption);
  padding: var(--e-1) var(--e-3);
  border-radius: var(--r-pill);
  background: rgb(255 245 230 / 0.1);
}
/* Los tres estados que la app usa de verdad. En `admin/raiz/show` el estado
 * crudo se mapea a uno de estos tres: `aprobada` -> publicada y `en_revision` ->
 * revision, porque "aprobada" y "en_revision" son nombres de base de datos y
 * quien administra el concurso lee "publicada". */
.estado--revision   { background: var(--c-aviso-claro);  color: #5c4808; }
.estado--publicada { background: var(--c-exito-claro);  color: #1d3b26; }
.estado--rechazada { background: var(--c-alerta-claro); color: #6d2114; }

/* Nombre de quien esta operando, al final de la barra de la consola. En movil
 * no compite por el espacio: la barra envuelve y esto baja a su propia fila. */
.admin__quien { margin-left: auto; }

/* Formulario que aparece "dentro" de otra cosa: el desplegable de denuncia y el
 * reenvio del formulario expirado.
 *
 * El nombre viene de una idea que ya no aplica -el codigo de participacion se
 * elimino con la regla 6, porque se entra con correo y no con codigo- pero
 * renombrar la clase en las dos vistas que la usan no aporta nada y ensucia el
 * historial. Lo que si importa es que NO lleva superficie: se usa igual dentro
 * de una tarjeta clara (el formulario expirado) y sobre el fondo oscuro (la
 * denuncia), y una caja oscura dentro de una tarjeta crema se ve como un error.
 * Quien necesite superficie pide `--oscura`. */
/* Compartir va debajo del titulo, como dos iconos y nada mas.
 *
 * Que sean dos iconos y no cuatro botones con texto no es solo estetica: es la
 * unica disposicion que sobrevive a 360 px. Con los textos, esta fila ocupa dos o
 * tres lineas y empuja hacia abajo la firma de la obra, que es justo lo que hay
 * que ver ahi. Con dos iconos ocupa 96 px y se queda pegada al nombre.
 *
 * El texto NO se borra, se oculta (`.solo-lectores`): sin el, los dos botones se
 * anuncian como "boton" a secas y en una fila de dos no hay forma de saber cual
 * es cual. Ver `.solo-lectores`.
 *
 * Ni `boton` ni `boton--contorno` a proposito. El borde y el relleno de `.boton`
 * estan medidos para mayusculas de 12-13 px, que necesitan 4.5:1; aqui no hay
 * etiqueta, y un borde de rosa mexicano ademas esta reservado por DESIGN.md para
 * "VER CALAVERITAS" e "INICIAR SESION". Se toma el patron de `.boton--fantasma`,
 * que ya esta medido sobre este fondo oscuro.
 *
 * Los 44 px del ancho son el minimo del dedo (WCAG 2.5.8 / Material), no un
 * capricho: por debajo de eso no se pulso con seguridad. */
.compartir {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e-2);
  /* El aire de arriba va aqui y no en el titulo. Los `h1` traen `margin: 0` y el
   * de la ficha solo lleva el `salto--chico` de arriba, asi que sin esto la fila se
   * pegaba al rotulo: medido en Chrome, el borde inferior del `h1` y el borde
   * superior del primer boton caian en el MISMO pixel (321 en una ventana de 360),
   * y los iconos parecian parte de la letra. */
  margin-block-start: var(--e-4);
}

.compartir__boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* 44px exactos: es el minimo y ademas deja los dos botones en una fila limpia
   * (44 + 8 + 44 = 96 px) sin depender de que el glifo traiga la caja justa. */
  width: 44px;
  height: 44px;
  padding: 0;
  background: transparent;
  border: 1.5px solid rgb(255 245 230 / 0.35);
  border-radius: var(--r-pill);
  color: var(--c-blanco-calavera);
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--mov-medio), border-color var(--mov-medio),
              transform var(--mov-rapido);
}

/* El estado hover no es adorno en un boton de icono: es lo unico que dice que hay
 * algo pulsable ahi, porque no hay etiqueta que lo diga. Por eso el relleno es de
 * cempasuchil y no el `--c-blanco-calvera` tenue de `.boton--fantasma`: este
 * boton no lleva texto que se pueda leer, y el cempasuchil es el unico color que
 * la regla de color de DESIGN.md permite como relleno de accion. */
.compartir__boton:hover {
  background: rgb(232 93 4 / 0.22);
  border-color: var(--c-cempasuchil);
  color: var(--c-blanco-calavera);
}

.compartir__boton:active { transform: translateY(1px); }

/* Foco visible y con contraste: sin esto, quien navega con teclado no sabe donde
 * esta. El anillo va por fuera del borde, no por dentro, para que los 44 px del
 * boton no se encogan cuando aparece. */
.compartir__boton:focus-visible {
  outline: 2px solid var(--c-ambar);
  outline-offset: 3px;
}

/* 24 px de glifo en una caja de 44 px dejan 10 px de aire por lado. Es el tamano
 * que miden los dos iconos del sitio y lo que hace que se vean iguales aunque
 * vengan de familias distintas: el de WhatsApp es relleno y ocupa el 100% de su
 * caja, el de copiar es de linea y el 92%. A igual tamano de dibujo la fila se
 * equilibra; si uno se dibuja mas pequeno que el otro, se ve torcido. */
.icono {
  width: 24px;
  height: 24px;
  display: block;
  flex: none;
  pointer-events: none;
}

/* El aviso que escribe el controlador. Vacio no ocupa nada -- ni hueco, ni
 * padding, ni alto: es texto que solo existe cuando algo paso, y un hueco con
 * padding debajo de los iconos se lee como algo roto. */
.compartir__aviso {
  flex-basis: 100%;
  margin-block-start: var(--e-2);
  font-size: var(--t-body-sm);
  color: var(--c-niebla);
}
.compartir__aviso:empty { display: none; }

.caja-codigo {
  display: grid;
  gap: var(--e-3);
  margin-block: var(--e-4);
}
.caja-codigo--oscura {
  padding: var(--e-4);
  background: var(--s-noche-media);
  border: 1px solid rgb(232 93 4 / 0.35);
  border-radius: var(--r-chico);
}

/* El `summary` de un `<details>` es un control, no un texto: necesita la misma
 * altura minima y el mismo cursor que un boton, o parece un enlace que no hace
 * nada. */
summary {
  cursor: pointer;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: var(--e-2);
  border-radius: var(--r-chico);
  list-style-position: inside;
}
summary:hover { color: var(--c-ambar); }
summary:focus-visible { outline: 3px solid var(--c-cempasuchil); outline-offset: 3px; }

/* ============================================================================
 * PUNTOS DE CORTE
 *
 * Todo lo de arriba es movil (360 px). Esto solo ANADE. Los cortes estan en 768
 * (tablet) y 1024 (escritorio), que son donde el contenido empieza a repartirse
 * en mas de una columna.
 * ============================================================================ */

/* --- tablet: el hero pasa a dos tiempos y las cifras a cuatro columnas --- */
@media (min-width: 768px) {
  .seccion { padding-block: var(--e-8); }
  .hero { padding-block: var(--e-9) var(--e-8); }

  .hero__acciones { flex-direction: row; flex-wrap: wrap; }
  .cifras { grid-template-columns: repeat(4, minmax(0, 1fr)); }

  /* Hay ancho de sobra: los botones vuelven a ser botones y no bloques. */
  .acciones,
  .acciones-obra { flex-direction: row; flex-wrap: wrap; }

  .rejilla { gap: var(--e-5); }

  /* La tabla vuelve a ser tabla: a partir de 768 hay ancho de sobra. */
  .tabla thead { display: table-header-group; }
  .tabla tbody { display: table-row-group; }
  .tabla tr { display: table-row; padding: 0; }
  .tabla td { display: table-cell; padding: var(--e-3); border-bottom: 1px solid rgb(255 245 230 / 0.12); }
  .tabla td::before { content: none; }
  .tabla th {
    padding: var(--e-3);
    text-align: left;
    font-size: var(--t-caption);
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--c-cempasuchil);
    border-bottom: 1px solid rgb(232 93 4 / 0.3);
  }
}

/* --- escritorio: el hero respira y el aire de las secciones sube ---
 * La rejilla de obras NO se toca aqui. Un solo tamano de track para todo el
 * rango deja que el numero de columnas solo pueda subir al ensanchar la
 * pantalla; cambiarlo en un breakpoint lo hacia bajar, y las tarjetas se
 * ensanchaban de golpe justo cuando ya no cabia mas. */
@media (min-width: 1024px) {
  .cabecera__fila { min-height: 68px; }
  .marca__logo { width: 40px; height: 40px; }
  .marca__nombre { font-size: 1.25rem; }

  .hero__titulo { max-width: 16ch; }
  .rejilla--tres { grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); }
  /* Tres columnas: la tarjeta apaisada ya respira y no necesita mas angulo. */
  .rejilla--obra { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* --- escritorio grande: el aire sube --- */
@media (min-width: 1280px) {
  .seccion { padding-block: var(--e-9); }
}

/* ============================================================================
 * MOVIL
 *
 * Lo que no cabe, se envuelve o se apila. Nunca se deja que algo desborde: un
 * scroll horizontal en el cuerpo es el sintoma de que la rejilla no bajo de
 * ancho, y `overflow-x: clip` en el body lo oculta sin arreglarlo.
 * ============================================================================ */

@media (max-width: 480px) {
  /* Los botones a ancho completo: un boton de 40 px de ancho no se pulsa. */
  .hero__acciones .boton,
  .boton--ancho { width: 100%; }

  /* El menu se apila bajo la marca y cada enlace ocupa una fila entera: con
   * dos enlaces a la vez, el pulgar tapa el segundo. */
  .cabecera__fila { flex-wrap: wrap; padding-block: var(--e-2); }
  .nav { width: 100%; justify-content: space-between; gap: 0; }
  .nav a, .nav__boton { flex: 1 1 0; justify-content: center; text-align: center; }

  .pide-correo__fila { flex-direction: column; }
  .pide-correo__fila .boton { width: 100%; }

  .filtros { gap: var(--e-1); }
  .filtro { flex: 1 1 auto; justify-content: center; text-align: center; }

  .legal ul { padding-left: 1rem; }
}

/* En horizontal en un telefono, el hero se apila y las cifras bajan a cuatro
 * columnas para no empujar la pagina hacia abajo de mas. */
@media (max-width: 932px) and (orientation: landscape) {
  .hero { padding-block: var(--e-6) var(--e-5); }
  .cifras { grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: var(--e-5); }
}

/* El pie respeta el notch en la parte de abajo del telefono. */
.pie {
  /* El aire de arriba estaba en un `style` del <footer>. Va aqui con el resto
   * del pie, que es donde se busca cuando hay que cambiarlo. */
  margin-top: var(--e-8);
  /* El notch del telefono esta abajo: sin esto, el aviso de "una obra fue
   * corregida" queda debajo del gesto de inicio. */
  padding-bottom: calc(var(--e-6) + env(safe-area-inset-bottom));
}

/* -------------------------------------------------------------------- el mapa
 *
 * El mapa del pie es el `iframe` de Google, interactivo: se arrastra, se acerca
 * con el dedo y trae los controles de zoom. No hay fachada ni boton delante, y no
 * hace falta: el `loading="lazy"` del `iframe` ya hace que Google no se pida hasta
 * que el pie esta cerca de la pantalla.
 *
 * El alto lo fija el `aspect-ratio` del contenedor y no el del `iframe`. Con el
 * `height: auto` que traen los reemplazos de elemento, un `iframe` sin alto se
 * remata en 150px --la altura por defecto-- y el mapa sale cortado por la mitad;
 * con `100%` dentro de una caja con proporcion fija, ocupa justo lo que toca y el
 * pie no salta cuando carga.
 *
 * El 3:2 es mas alto que el 16:9 de los mapas de television a proposito: en una
 * caja tan angosta, a 16:9 el pin cae en el borde y no se ve la calle.
 */
.mapa {
  aspect-ratio: 3 / 2;
  margin-top: var(--e-3);
  border-radius: var(--r-chico);
  overflow: hidden;
  /* Un pixel de borde, para que el mapa de Google no se coma el radio. */
  border: 1px solid rgb(232 93 4 / 0.35);
}

.mapa > iframe {
  display: block;
  width: 100%;
  height: 100%;
  /* El marco de Google trae su propio borde y su sombra: sin esto se ven los dos
   * bordes, el del `iframe` y el de la caja de alrededor. */
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
