/* ══════════════════════════════════════════════════════════════
   Catálogo público — El polígono

   El kiosco es de un cuartel: el catálogo pasa en un polígono de
   tiro. Pasto, arboleda a los costados, el sol arriba, y las
   líneas de tiro marcadas con cinta de peligro yendo al fondo,
   con las siluetas de blanco al final de cada una.

   Cada rubro del catálogo es una LÍNEA DE TIRO: tiene su cartel
   de puesto, su cinta, y su silueta al fondo.

   Cómo está hecho:
   - El pasto y la arboleda son una FOTO real (Commons, CC BY-SA
     2.0, Keith Evans). Dibujar árboles a mano se nota.
   - Las cintas, los carriles y la perspectiva son CSS: son
     elementos gráficos, corresponden a gráfica.
   - Las siluetas son SVG. Un blanco de tiro ES una silueta plana
     negra: dibujarla es fiel, no una simplificación.

   Y la regla que no cambia: cada burbuja es un producto REAL de
   la base. Cambia la foto en el catálogo y cambia acá.
   ══════════════════════════════════════════════════════════════ */

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

html { -webkit-text-size-adjust: 100%; }
body { margin: 0; background: #1D2A16; }

.cat-root {
  --cielo-alto: #4E86B4;
  --cielo-bajo: #A9CFE4;
  --sol:        #FFF3C4;
  --pasto:      #3E5C25;
  --pasto-osc:  #22331338;
  --cinta:      #F2C400;
  --cinta-osc:  #191919;
  --tierra:     #6E5433;
  --crema:      #FFF8EA;
  --oliva:      #2F3A22;
  --fire:       #e8534f;

  --ancho: 1180px;

  min-height: 100vh;
  color: var(--crema);
  font-family: 'Inter', -apple-system, system-ui, sans-serif;
  overflow-x: hidden;
  background: var(--pasto);
}

.cat-cargando,
/* Mientras se espera al servidor. El catálogo tarda más de un segundo
   en contestar -- las fotos viajan adentro de la respuesta -- y hasta
   ahora en ese rato no se mostraba NADA: se veía una página en blanco
   y parecía que no andaba. */
.cat-cargando {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 40px; text-align: center;
  background: #1D2A16; color: #FFF8EA;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: .95rem; letter-spacing: .04em;
}
/* El texto arranca invisible: los primeros dos segundos y medio es una
   pantalla oscura y muda, para no pisarle la entrada al kiosco. Si
   pasado ese rato todavía no llegaron los precios, ahí sí aparece. */
.cat-cargando span { opacity: 0; transition: opacity .5s ease; }
.cat-cargando.tarda span { opacity: 1; animation: catLatido 1.4s ease-in-out infinite; }
@keyframes catLatido { 0%,100% { opacity: .55 } 50% { opacity: 1 } }

.cat-vacio {
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: 40px; text-align: center;
  background: #1D2A16; color: #FFF8EA;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: .95rem; line-height: 1.6;
}

/* ══════════════════════════════════════════════════════════════
   LA ESCENA — el fondo, fijo detrás de todo
   ══════════════════════════════════════════════════════════════ */
.escena {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

/* El polígono. Una FOTO de un campo de tiro militar de verdad
   (Commons, dominio público): pasto verde, las calles marcadas con
   estacas blancas que convergen al fondo, los blancos al final y
   arboleda a los dos costados.

   Antes esto era un pasto genérico con los carriles dibujados en
   CSS por encima. Se notaba: la perspectiva de un polígono real no
   se simula con un trapecio y unas rayas. La foto trae la
   profundidad, las estacas y los blancos de una. */
.escena-campo {
  position: absolute;
  inset: 0;
  /* La imagen ya está tomada de frente y con el punto de fuga
     centrado, así que no hace falta reencuadrarla: va derecha.
     Antes había una foto tomada en diagonal y se compensaba
     corriendo el recorte, que acercaba pero no alcanzaba. */
  background: url('../assets/escena/poligono.jpg') no-repeat center 30% / cover;
}

/* Neblina: el fondo se va oscureciendo hacia abajo para que los
   productos se despeguen. Arriba queda limpio, porque ahí es donde
   se tiene que ver el polígono. */
.escena-aire {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom,
      rgba(20, 26, 14, .02) 0,
      rgba(20, 26, 14, .16) 38vh,
      rgba(20, 26, 14, .72) 80vh,
      rgba(20, 26, 14, .90) 100%);
}

/* ══════════════════════════════════════════════════════════════
   LA TAPA — el puesto de comando
   ══════════════════════════════════════════════════════════════ */
.tapa {
  position: relative;
  z-index: 2;
  padding: 40px 20px 26px;
  text-align: center;
  /* Apenas una sombra: el nombre ya tiene su propio cartel de
     chapa, así que no hace falta tapar el cielo para que se lea.
     Antes iba mucho más oscuro porque el título era texto suelto
     sobre las nubes. */
  background: linear-gradient(to bottom,
    rgba(20, 26, 14, .34) 0,
    rgba(20, 26, 14, .18) 60%,
    transparent 100%);
}
/* Cada pieza en su propio renglón. Como el escudo, la cinta y el
   cartel son inline-block, sin esto se acomodaban los tres en una
   misma fila, uno al lado del otro. */
.tapa > * {
  display: block;
  width: fit-content;
  max-width: min(var(--ancho), 100%);
  margin-left: auto;
  margin-right: auto;
}

/* Los blancos, al fondo del polígono. Un blanco de tiro es una
   silueta plana: dibujarla es fiel, no una simplificación. */
.blancos {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: clamp(14px, 5vw, 54px);
  margin-bottom: 6px;
  height: 74px;
}
.blanco {
  height: 100%;
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, .45));
  opacity: .95;
}
/* Ni verde ni camuflado: sobre el pasto tienen que verse. */
.blanco.b1 { color: #F2F2F2; }
.blanco.b2 { color: #C4321F; }
.blanco.b3 { color: #2C4C86; }
.blanco.b4 { color: #F2F2F2; }
.blanco.b5 { color: #C4321F; }

.tapa-logo {
  width: 96px; height: 96px;
  object-fit: contain;
  margin-bottom: 12px;
  filter: drop-shadow(0 8px 20px rgba(0, 0, 0, .55));
}

/* En el polígono el logo va del ancho de la cinta de peligro, pedido por
   Canu. La cinta mide 197px y NO cambia con el ancho de pantalla --el
   texto no escala--, así que un número fijo sirve para todos; el `min`
   con vw es sólo para que en un teléfono muy angosto no se coma media
   portada. Va sólo en este modelo: es el del Kiosko Cazador, y los otros
   ocho tienen su propia escena donde el logo grande no corresponde. */
[data-modelo="poligono"] .tapa-logo {
  width: min(190px, 52vw);
  height: min(190px, 52vw);
  margin-bottom: 16px;
}

.tapa-cinta {
  /* block + fit-content, no inline-block: la regla general de
     `.tapa > *` la pisaba la propia del elemento y la cinta
     terminaba al costado del cartel en vez de arriba. */
  display: block;
  width: fit-content;
  margin: 0 auto 14px;
  padding: 7px 22px;
  border-radius: 3px;
  color: var(--cinta-osc);
  font-size: .66rem;
  font-weight: 800;
  letter-spacing: .22em;
  text-transform: uppercase;
  transform: rotate(-1.2deg);
  /* Cinta de peligro de verdad: rayas diagonales amarillo y negro. */
  background: repeating-linear-gradient(45deg,
    var(--cinta) 0 12px, var(--cinta-osc) 12px 24px);
  box-shadow: 0 5px 0 rgba(0, 0, 0, .3);
}
.tapa-cinta span {
  background: var(--cinta);
  padding: 3px 10px;
  border-radius: 2px;
}

/* El nombre va en una chapa OXIDADA con las letras RECORTADAS:
   alguien agarró una plancha de acero, la caló con el nombre, y
   por los huecos pasa la luz del polígono. Los cuatro remaches
   son cuatro impactos de bala.

   Cómo se hace el calado: la chapa es el fondo del contenedor y el
   texto se pinta con `background-clip: text` sobre una capa
   luminosa, así las letras no están PINTADAS encima sino que son
   el agujero por donde se ve la luz. */
.tapa-cartel {
  display: block;
  width: fit-content;
  max-width: 100%;
  margin: 4px auto 0;
  padding: 20px clamp(26px, 6vw, 58px) 22px;
  position: relative;
  border-radius: 3px;
  /* Óxido: manchas irregulares de herrumbre sobre acero gastado.
     Varias capas de radiales a distinto tamaño para que no se lea
     el patrón. */
  background:
    radial-gradient(ellipse 30% 60% at 12% 22%, rgba(138, 74, 32, .55), transparent 70%),
    radial-gradient(ellipse 22% 45% at 88% 74%, rgba(122, 62, 26, .5), transparent 70%),
    radial-gradient(ellipse 40% 30% at 62% 8%, rgba(96, 52, 24, .38), transparent 72%),
    radial-gradient(ellipse 18% 40% at 38% 92%, rgba(150, 88, 40, .34), transparent 70%),
    linear-gradient(168deg, #6E6659 0%, #4A443A 46%, #5C5348 78%, #3E3830 100%);
  box-shadow:
    inset 0 0 0 2px rgba(28, 24, 18, .55),
    inset 0 2px 3px rgba(255, 248, 234, .12),
    inset 0 -3px 8px rgba(0, 0, 0, .5),
    0 14px 34px rgba(0, 0, 0, .7);
  /* Borde cortado a mano: no es una plancha prolija de fábrica. */
  clip-path: polygon(
    0.4% 3%, 3% 0%, 40% 1.5%, 62% 0%, 97% 2%, 100% 6%,
    99.3% 48%, 100% 94%, 96% 100%, 58% 98.5%, 34% 100%, 3% 98%, 0% 92%, 1% 40%);
}

/* Los cuatro impactos. Cada uno: el agujero negro, el metal
   desgarrado y brillante alrededor, y el óxido que chorrea. */
.tapa-cartel::before,
.tapa-cartel::after {
  content: '';
  position: absolute;
  top: 11px; bottom: 11px;
  width: 15px;
  background-repeat: no-repeat;
  background-size: 100% 15px;
  background-position: top, top, bottom, bottom;
  background-image:
    radial-gradient(circle 5px at 50% 50%, #0B0906 0 42%, #1A1611 52%, transparent 60%),
    radial-gradient(circle 7.5px at 50% 50%, transparent 42%, rgba(214, 205, 186, .75) 50%, rgba(120, 70, 34, .6) 62%, transparent 78%),
    radial-gradient(circle 5px at 50% 50%, #0B0906 0 42%, #1A1611 52%, transparent 60%),
    radial-gradient(circle 7.5px at 50% 50%, transparent 42%, rgba(214, 205, 186, .75) 50%, rgba(120, 70, 34, .6) 62%, transparent 78%);
}
.tapa-cartel::before { left: 11px; }
.tapa-cartel::after  { right: 11px; }

.tapa-nombre {
  position: relative;
  margin: 0;
  font-family: 'Stardos Stencil', 'Archivo Black', Impact, sans-serif;
  font-weight: 700;
  font-size: clamp(1.9rem, 7vw, 4rem);
  line-height: 1;
  letter-spacing: .03em;
  text-transform: uppercase;
  text-wrap: balance;
  /* El calado: por el hueco de cada letra entra la luz del día.
     El borde oscuro de abajo es el canto de la chapa cortada. */
  background:
    radial-gradient(ellipse 120% 150% at 50% 40%, #FFFDF4 0%, #FFE9B8 45%, #E8B25E 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  filter:
    drop-shadow(0 1px 0 rgba(12, 10, 6, .95))
    drop-shadow(0 -1px 0 rgba(12, 10, 6, .6))
    drop-shadow(0 0 16px rgba(255, 226, 150, .55));
}

.tapa-bajada {
  margin: 14px auto 0;
  max-width: 42ch;
  color: rgba(255, 248, 234, .9);
  font-size: 1rem;
  line-height: 1.55;
  text-shadow: 0 2px 8px rgba(0, 0, 0, .7);
}

/* ══════════════════════════════════════════════════════════════
   LAS LÍNEAS DE TIRO — un rubro por línea
   ══════════════════════════════════════════════════════════════ */
.rubro {
  position: relative;
  z-index: 2;
  margin-top: 30px;
  padding-top: 10px;
}

/* La cinta que separa una línea de la otra. */
.rubro::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 11px;
  background: repeating-linear-gradient(45deg,
    var(--cinta) 0 10px, var(--cinta-osc) 10px 20px);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .5);
}

.rubro-tit {
  max-width: var(--ancho);
  margin: 0 auto 4px;
  padding: 0 20px;
  display: flex;
  align-items: center;
  gap: 12px;
}
/* Cartel de puesto, como el número de cada línea de tiro. */
.rubro-tit b {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 16px;
  background: var(--oliva);
  border: 2px solid var(--crema);
  border-radius: 3px;
  color: var(--crema);
  font-family: 'Archivo Black', 'Inter', sans-serif;
  font-size: 1rem;
  letter-spacing: .02em;
  text-transform: uppercase;
  box-shadow: 0 5px 0 rgba(0, 0, 0, .35);
}
.rubro-tit b i {
  font-style: normal;
  padding: 1px 7px;
  background: var(--cinta);
  color: var(--cinta-osc);
  border-radius: 2px;
  font-size: .8rem;
}
.rubro-tit span {
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: rgba(255, 248, 234, .8);
  text-shadow: 0 1px 5px rgba(0, 0, 0, .8);
}

/* ══════════════════════════════════════════════════════════════
   EL COLLAGE
   Grilla de base, pero cada burbuja se sale de su celda: crece,
   se corre y se inclina. Así se amontonan sin acomodarlas a mano
   y sin que se desarmen al cambiar el ancho.
   ══════════════════════════════════════════════════════════════ */
.pila {
  position: relative;
  max-width: var(--ancho);
  margin: 0 auto;
  /* El aire de arriba NO es margen decorativo: con el nombre arriba de
     la foto, la primera fila le caia encima al cartel del rubro. Medido
     el 27/08 en el catalogo del Cazador: 9 nombres pisando el titulo,
     que bajan a 1. Cuesta 5% de alto de pagina. */
  padding: 34px 14px 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 0;
}

.burbuja {
  position: relative;
  /*  LAS BURBUJAS YA NO SE PISAN. Elegido por Canu el 27/08 mirando las
      seis opciones, con el numero de cada una a la vista.

      Se pisaban -9% de costado a proposito: era lo que hacia el
      collage. El costo era que los nombres no tenian donde caer.
      Medido sobre el catalogo del Cazador, contando cuantos textos se
      superponen (el abanico de sabores no cuenta: sus fichas se pisan
      a proposito):

          se pisan -9%, nombre abajo  .... 24
          se pisan -9%, nombre arriba .... 17
          se pisan -4%, nombre arriba .... 13
          NO se pisan, nombre arriba  .... 10   <- esto

      Se probaron tambien las dos formas de meter el nombre DENTRO del
      marco, como ya esta el precio. La ancha da 42 --peor que todo-- y
      la angosta 15, pero de un solo renglon: "AGUA SABORIZADA PLACER
      500 ML" sale cortado, y en una lista de precios eso no sirve.

      La leccion, que vale para cualquier modelo nuevo: lo que hace que
      los nombres choquen NO es donde se pone el nombre, es que los
      productos se pisen. El precio no choca nunca porque es corto y va
      al medio del marco; un nombre no puede ser ninguna de las dos
      cosas.

      El giro, la escala y el corrimiento de cada burbuja se conservan:
      siguen desparejas, siguen sin estar en una grilla prolija. Lo
      unico que se saca es que se monten una encima de otra. */
  margin: 0 0 6px;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  transform: rotate(var(--r, 0deg)) scale(var(--s, 1)) translate(var(--dx, 0), var(--dy, 0));
  z-index: var(--z, 1);
}

/* La caja de la foto. El precio, el "se acabó" y la estrella se cuelgan
   de ACÁ y no de la tarjeta entera: con el abanico de sabores abajo la
   tarjeta crece, y un precio colocado desde abajo terminaba cayendo
   encima del nombre del producto. */
.b-marco {
  position: relative;
  width: 100%;
  line-height: 0;
}

.b-foto {
  width: 100%;
  aspect-ratio: 1;
  /* `contain` y no `cover`: con cover la foto se recorta a un
     círculo perfecto y el producto queda cortado por una galleta
     geométrica. Con contain se ve el producto entero y lo que se
     desvanece es el fondo de la foto. */
  object-fit: contain;
  /* Máscara muy abierta: casi no recorta, sólo apaga los cuatro
     rincones. Las fotos generadas ya vienen recortadas con fondo
     transparente y una elipse cerrada les comía los bordes (los
     envases quedaban cortados al medio). Las viejas, que todavía
     traen fondo, igual se funden gracias a este desvanecido. */
  -webkit-mask-image: radial-gradient(ellipse 72% 68% at 50% 50%,
    #000 56%, rgba(0, 0, 0, .55) 80%, transparent 100%);
  mask-image: radial-gradient(ellipse 72% 68% at 50% 50%,
    #000 56%, rgba(0, 0, 0, .55) 80%, transparent 100%);
  filter: saturate(1.06) contrast(1.03) drop-shadow(0 14px 16px rgba(0, 0, 0, .55));
  transition: transform .4s cubic-bezier(.16, 1, .3, 1);
}
.burbuja:hover .b-foto { transform: scale(1.07); }

/* Sin foto: una mancha con la inicial. Un hueco vacío rompe el
   amontonamiento más que una mancha. */
.b-mancha {
  width: 76%;
  aspect-ratio: 1;
  margin: 12% auto;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: radial-gradient(circle at 38% 32%, #8A9A6B, var(--oliva) 74%);
  color: var(--crema);
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 2.1rem;
  box-shadow: 0 14px 22px rgba(0, 0, 0, .5);
}

/* ── El sticker de precio ─────────────────────────────────────
   Centrado y dentro del ancho de su propia burbuja: contra el
   costado quedaba tapado por la burbuja de al lado, porque el
   z-index de un hijo no le gana al de un hermano que está más
   arriba en la pila.
   ────────────────────────────────────────────────────────────── */
/* El precio como el marcado de una caja de munición: chapa de
   lata gastada con el número en esténcil. Antes era un sticker
   amarillo torcido 6 grados y quedaba de joda -- acá son todos
   militares y eso le sacaba seriedad al catálogo.
   Queda apenas 1 grado fuera de escuadra: en un cuartel las cosas
   están derechas, pero pintadas a mano. */
.b-precio {
  position: absolute;
  left: 50%;
  /* Un poco por debajo del borde de la foto: monta sobre el producto,
     que es el efecto de tarjetita apoyada, sin llegar al nombre. */
  bottom: 6%;
  translate: -50% 0;
  z-index: 3;
  display: grid;
  place-items: center;
  padding: 5px 12px 6px;
  border-radius: 2px;
  background:
    linear-gradient(172deg, rgba(255, 248, 234, .1), transparent 38%),
    linear-gradient(#59533F, #3B3629);
  border: 1px solid rgba(255, 248, 234, .42);
  color: var(--crema);
  font-family: 'Stardos Stencil', 'Archivo Black', sans-serif;
  font-weight: 700;
  font-size: .84rem;
  letter-spacing: .02em;
  white-space: nowrap;
  transform: rotate(-1deg);
  box-shadow:
    inset 0 1px 0 rgba(255, 248, 234, .16),
    0 3px 0 rgba(0, 0, 0, .42),
    0 7px 16px rgba(0, 0, 0, .55);
}
/* Lo que más sale va en rojo de marca: es el único color fuerte
   de la página, y así se nota cuál es cuál de un vistazo. */
.burbuja.destacada .b-precio {
  background: linear-gradient(#8E2117, #6B1710);
  border-color: rgba(255, 190, 180, .55);
  font-size: 1rem;
  padding: 7px 15px 8px;
}

.b-nom {
  position: relative;
  z-index: 2;
  /* ARRIBA de la foto, igual que en los otros ocho modelos (ver el
     comentario de .ct-nom en catalogo-modelos.css). El poligono se
     habia quedado abajo porque arma su propia pieza en vez de usar
     tarjeta().

     Con `order` y no moviendo el renglon: la pieza del poligono se
     arma en js/catalogo-modelos.js y este archivo ya decide todo lo
     demas de como se ve. */
  order: -1;
  margin-bottom: 2px;
  max-width: 100%;
  text-align: center;
  font-size: .78rem;
  font-weight: 700;
  line-height: 1.2;
  text-wrap: balance;
  color: var(--crema);
  /* Los nombres caen sobre fotos de comida claras y con mucho
     detalle: sin un halo oscuro cerrado alrededor no se leen. */
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 1), 0 2px 6px rgba(0, 0, 0, .95),
    0 0 14px rgba(0, 0, 0, .9), 0 0 26px rgba(0, 0, 0, .7);
}
.burbuja.destacada .b-nom { font-size: .9rem; }

.burbuja.agotada .b-foto { filter: grayscale(1) brightness(.65); }
.burbuja.agotada .b-precio { background: #9A9A8E; }

.b-agotado {
  position: absolute;
  top: 12%; left: 50%;
  z-index: 4;
  transform: translateX(-50%) rotate(-8deg);
  padding: 3px 10px;
  border: 2px solid var(--fire);
  border-radius: 3px;
  color: var(--fire);
  background: rgba(20, 26, 14, .85);
  font-size: .56rem;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
}

/* Al que más sale se le pone un blanco de tiro, no una medalla. */
.b-estrella {
  position: absolute;
  top: 3%; left: 2%;
  z-index: 4;
  padding: 4px 11px;
  border-radius: 3px;
  background: var(--crema);
  color: var(--oliva);
  font-size: .56rem;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  transform: rotate(-6deg);
  box-shadow: 0 4px 0 rgba(0, 0, 0, .3);
}

/* ── Los sabores, en abanico ─────────────────────────────────── */
.abanico {
  position: relative;
  z-index: 3;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  /* Se dobla en vez de irse de costado. Sin esto, seis sabores en una
     casilla de 150px se salían encima del producto de al lado -- y en
     este modelo las casillas ya se pisan a propósito, así que lo que
     sobra cae justo arriba del vecino. Doblado crece hacia abajo, que
     es espacio propio. */
  flex-wrap: wrap;
  row-gap: 3px;
  max-width: 100%;
  margin-top: 4px;
}
.sabor {
  /* Flex con margen negativo: cada naipe se corre según su propio
     ancho. Con posición absoluta hay que adivinar un paso fijo y
     los nombres largos terminan uno encima del otro. */
  margin: 0 -4px;
  transform-origin: 50% 300%;
  transform: rotate(calc((var(--i) - (var(--n) - 1) / 2) * 9deg));
  /* Chicos a propósito: la casilla del producto mide unos 150px y un
     naipe de 100px entra uno solo por renglón, así que el abanico se
     convertía en una columna. Achicados entran de a dos. */
  padding: 3px 6px;
  border-radius: 3px;
  background: var(--crema);
  color: var(--oliva);
  font-size: .56rem;
  letter-spacing: -.01em;
  font-weight: 700;
  white-space: nowrap;
  /* Un sabor de nombre largo no puede estirar la fila entera. */
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  box-shadow: 0 3px 8px rgba(0, 0, 0, .6);
}
.sabor.agotado { opacity: .45; text-decoration: line-through; }
.sabor.mas { background: var(--cinta); }

/* ══════════════════════════════════════════════════════════════
   ENTRADA
   ══════════════════════════════════════════════════════════════ */
.entra {
  opacity: 0;
  transform: translateY(20px) rotate(var(--r, 0deg)) scale(var(--s, 1));
  transition: opacity .6s ease, transform .6s cubic-bezier(.16, 1, .3, 1);
}
.entra.visible {
  opacity: 1;
  transform: rotate(var(--r, 0deg)) scale(var(--s, 1)) translate(var(--dx, 0), var(--dy, 0));
}

/* ══════════════════════════════════════════════════════════════
   EL PIE
   ══════════════════════════════════════════════════════════════ */
/* El pie es COMPARTIDO por todos los modelos, así que acá va sólo
   la caja: nada de color de mundo. La cinta de peligro amarilla y
   negra que estaba en este borde es del polígono, y se veía abajo de
   la heladera, del toldo y de todos los demás -- un cartel de obra
   colgado en una vidriera. Cada modelo pinta su propio pie. */
.cat-pie {
  position: relative;
  z-index: 2;
  margin-top: 44px;
  padding: 26px 20px 54px;
  text-align: center;
  font-size: .78rem;
  line-height: 1.7;
}
.cat-pie strong { font-weight: 700; }

/* El del polígono, que es de donde salía la cinta. */
.cat-root[data-modelo="poligono"] .cat-pie,
.cat-root:not([data-modelo]) .cat-pie {
  color: rgba(255, 248, 234, .85);
  background: rgba(20, 26, 14, .72);
  border-top: 11px solid transparent;
  border-image: repeating-linear-gradient(45deg,
    var(--cinta) 0 10px, var(--cinta-osc) 10px 20px) 11;
}
.cat-root[data-modelo="poligono"] .cat-pie strong,
.cat-root:not([data-modelo]) .cat-pie strong { color: var(--crema); }

.cat-kfb {
  display: flex;
  width: fit-content;
  margin: 20px auto 0;
  align-items: center;
  gap: 12px;
  color: inherit;
  text-decoration: none;
}
.cat-kfb .kfb-txt { display: flex; align-items: baseline; gap: 7px; }

/* La llama. El video es fuego sobre negro, así que con
   mix-blend-mode:screen el negro desaparece solo y queda ardiendo
   sobre el fondo, sin recortes ni canal alfa.
   Arranca invisible: si el navegador no puede reproducirlo, el JS
   lo saca y nadie ve un rectángulo negro. */
.kfb-llama {
  /* Más grande: es la marca, y al pie del catálogo es lo único que
     queda de KFB. Con 52px pasaba desapercibida. */
  width: 76px; height: 76px;
  /* El logo es vertical y el cuchillo con el cerebro caen a dos
     tercios del cuadro; arriba hay puro fuego. Con `contain` entra
     entero pero flaquito, con dos franjas oscuras al costado; con
     `cover` llena el círculo, y el encuadre en 78% es el que deja la
     marca centrada. En 28% se veía sólo la llama de arriba. */
  object-fit: cover;
  object-position: center 78%;
  background: #2b2625;
  border-radius: 50%;
  /* El aro, fino. Grueso parecía un sticker pegado encima. */
  border: 1px solid rgba(242, 196, 0, .55);
  flex: none;
  /* ── La llama se mueve SIEMPRE ──────────────────────────────
     Dos animaciones: el resplandor de alrededor y el temblor de la
     imagen. Las dos van sobre la foto fija, no sobre el video.
     Es a propósito: el video puede no llegar nunca. En la vista
     previa publicada los archivos externos están bloqueados, y en un
     celular con datos flojos 6MB tardan. Un logo que sólo se mueve si
     el video llega es un logo que la mayoría ve quieto -- y el
     usuario lo dijo así: "ahora sí se ve mi logo abajo, pero está
     sin animación".
     Con el video andando, el temblor se apaga: la llama de verdad ya
     se mueve sola y encimarle otro temblor la haría vibrar. */
  animation: llamaLate 3.4s ease-in-out infinite,
             llamaTiembla 2.3s ease-in-out infinite;
}
.kfb-llama.viva { animation: llamaLate 3.4s ease-in-out infinite; }
@keyframes llamaLate {
  0%, 100% { box-shadow: 0 0 12px rgba(242, 150, 40, .35), 0 0 0 rgba(255, 120, 40, 0); }
  50%      { box-shadow: 0 0 26px rgba(255, 150, 50, .75), 0 0 46px rgba(255, 90, 30, .3); }
}
/* El temblor: el fuego cambia de brillo y de color, no de tamaño.
   Con escala se ve un logo que late; con brillo se ve fuego. Los
   tiempos son irregulares a propósito -- una llama no parpadea a
   compás. */
@keyframes llamaTiembla {
  0%   { filter: brightness(1)    saturate(1)    contrast(1); }
  17%  { filter: brightness(1.14) saturate(1.12) contrast(1.05); }
  31%  { filter: brightness(.94)  saturate(.97)  contrast(1); }
  48%  { filter: brightness(1.2)  saturate(1.18) contrast(1.07); }
  63%  { filter: brightness(1.02) saturate(1.04) contrast(1); }
  79%  { filter: brightness(1.16) saturate(1.1)  contrast(1.04); }
  100% { filter: brightness(1)    saturate(1)    contrast(1); }
}

.cat-kfb:hover .cat-kfb-marca { text-decoration: underline; }
.cat-kfb:focus-visible { outline: 2px solid var(--cinta); outline-offset: 4px; }

.cat-kfb-hecho { font-size: .68rem; opacity: .8; }

.cat-kfb-marca {
  font-family: 'Playfair Display', Georgia, serif;
  font-weight: 600;
  font-size: .98rem;
  color: var(--crema);
  background: linear-gradient(115deg, var(--crema) 20%, var(--cinta) 46%, var(--crema) 72%);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: kfbBrillo 5s ease-in-out infinite;
}
@keyframes kfbBrillo {
  0%, 100% { background-position: 130% 0; }
  50%      { background-position: -30% 0; }
}

/* "Fire" se planta afuera del degradé con su rojo de marca:
   text-fill-color propio le gana al transparent del padre. */
.cat-kfb-marca em {
  font-style: italic;
  font-weight: 400;
  color: var(--fire);
  -webkit-text-fill-color: var(--fire);
  animation: kfbBrasa 2.4s ease-in-out infinite;
}
/* La brasa late con COLOR y brillo, nunca con escala: con transform,
   Chrome repinta el degradado del padre (background-clip:text) en el
   lugar equivocado y aparece un "Fire" fantasma encima -- ya pasó y
   costó tres explicaciones equivocadas encontrarlo.
   Antes latía sólo con una sombra de 6 a 13px al 30-70%: sobre una
   chapa oscura eso no se ve. El usuario lo marcó -- "no está latiendo
   como tiene que latir" -- y tenía razón. Ahora el rojo se abre hacia
   el naranja de la brasa y el halo crece de verdad. */
@keyframes kfbBrasa {
  0%, 100% {
    color: var(--fire); -webkit-text-fill-color: var(--fire);
    text-shadow: 0 0 5px rgba(255, 77, 77, .35);
  }
  45% {
    color: #ff9147; -webkit-text-fill-color: #ff9147;
    text-shadow: 0 0 16px rgba(255, 140, 60, .95), 0 0 32px rgba(255, 90, 30, .5);
  }
}

/* "Kiosco" va gris y chiquita, igual que en toda la marca. Estaba
   con var(--cinta), que es el amarillo de la cinta de peligro del
   polígono: chillón y ajeno a los otros modelos. */
/* "Kiosco": arriba y a la derecha del nombre, con la K mayuscula y
   el resto minuscula -- igual que en el resto de la marca. Estaba
   TODO EN MAYUSCULAS y a la par porque era hermano del nombre dentro
   de un flex con align-items:baseline. */
.cat-kfb-prod {
  display: inline-block;
  font-family: 'Inter', system-ui, sans-serif;
  font-style: normal;
  font-size: .6rem;
  font-weight: 600;
  letter-spacing: .1em;
  vertical-align: super;
  margin-left: 3px;
  color: currentColor;
  -webkit-text-fill-color: currentColor;
  opacity: .5;
}

/* ══════════════════════════════════════════════════════════════
   CELULAR — es donde se abre casi siempre, entra por un QR
   ══════════════════════════════════════════════════════════════ */
@media (max-width: 720px) {
  .tapa { padding: 24px 16px 0; }
  .blancos { height: 52px; gap: 12px; }
  .pila { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); padding: 0 8px; }
  .b-precio { padding: 5px 8px; font-size: .72rem; }
  .burbuja.destacada .b-precio { font-size: .88rem; padding: 7px 11px; }
  .b-nom { font-size: .68rem; }
  .sabor { font-size: .58rem; padding: 3px 7px; }
  /* En pantalla angosta la perspectiva se cierra demasiado y los
     carriles se vuelven un rayado. */
  .escena-piso { perspective: 200px; }
}

@media (prefers-reduced-motion: reduce) {
  .cat-kfb-marca, .cat-kfb-marca em, .kfb-llama { animation: none; }
  .entra { opacity: 1; transition: none; }
  .b-foto { transition: none; }
}

/* ══════════════════════════════════════════════════════════════
   PAPEL
   El polígono no se imprime: es atmósfera de pantalla y se come
   un cartucho. En papel va la misma información como lista.
   ══════════════════════════════════════════════════════════════ */
@media print {
  @page { size: A4; margin: 11mm; }

  body, .cat-root { background: #fff !important; }
  .cat-root { color: #000; }
  .escena { display: none !important; }

  .tapa { padding: 0 0 10px; }
  .blancos { display: none; }
  .tapa-nombre { font-size: 2rem; color: #000; text-shadow: none; }
  .tapa-cinta { background: none; color: #000; box-shadow: none; transform: none; padding: 0; }
  .tapa-cinta span { background: none; padding: 0; }
  .tapa-bajada { color: #444; text-shadow: none; }
  .tapa-logo { width: 48px; height: 48px; filter: none; }

  .entra { opacity: 1 !important; transform: none !important; }

  /* De collage a lista: en papel lo que importa es encontrar el
     precio, no la atmósfera. */
  .rubro { margin-top: 8px; padding-top: 0; }
  .rubro::before { display: none; }
  .rubro-tit { padding: 0; }
  .rubro-tit b {
    background: none; border: 0; color: #000; box-shadow: none;
    padding: 0; font-size: 1rem;
  }
  .rubro-tit b i { background: none; color: #000; padding: 0; }
  .rubro-tit span { color: #666; text-shadow: none; }

  .pila { display: block; columns: 2; column-gap: 12mm; padding: 0; }
  .burbuja {
    break-inside: avoid;
    display: flex; flex-direction: row; align-items: baseline;
    justify-content: space-between; gap: 8px;
    margin: 0 0 4px; padding-bottom: 3px;
    border-bottom: 1px dotted #ccc;
    transform: none !important;
  }
  .b-foto, .b-mancha, .b-estrella, .b-agotado { display: none; }
  .b-nom {
    margin: 0; max-width: none; text-align: left;
    font-size: .88rem; font-weight: 500; color: #000; text-shadow: none;
  }
  .b-precio {
    position: static; transform: none; translate: none; background: none;
    box-shadow: none; padding: 0; color: #000; font-size: .88rem;
  }
  .abanico { flex-wrap: wrap; justify-content: flex-start; margin: 0 0 4px; }
  .sabor { background: none; box-shadow: none; transform: none; margin: 0 4px 2px 0; color: #444; }

  .cat-pie { background: none; border: 0; border-top: 1px solid #ccc; color: #444; margin-top: 14px; }
  /* Sin esto el wordmark sale EN BLANCO: el relleno es transparente
     y las letras se ven por el degradé de fondo, que muchas
     impresoras descartan. */
  .cat-kfb-marca {
    background: none; -webkit-text-fill-color: #000; color: #000; animation: none;
  }
  .cat-kfb-marca em { -webkit-text-fill-color: var(--fire); text-shadow: none; animation: none; }
}


/* El polígono, angosto para teléfonos. Ver el porqué en
   catalogo-modelos.css. */
@media (max-width: 860px) {
  .escena-campo { background-image: url('../assets/escena/poligono-800.jpg'); }
}
