/* catalogo — visor de flipbook.
 *
 * A propósito NO usa el shell compartido de la flota (tokens/base/components
 * de _shared-ui): eso es chrome de aplicación interna —sidebar, tablas, KPIs—
 * y acá la interfaz correcta es "sala oscura": el catálogo es el contenido y
 * todo lo demás se corre del medio. El único lenguaje que se hereda es el
 * oro de marca sobre fondo casi negro.
 *
 * Las medidas del libro NO están acá: las calcula catalogo.js contra el
 * viewport real y el aspecto de la página. El CSS sólo define el escenario.
 */

:root {
  --fondo: #0d0d10;
  --fondo-2: #16161b;
  --tinta: #f2f0ea;
  --tinta-baja: #8b8b95;
  --oro: #c8a24a;
  --borde: #26262e;
  --barra-h: 52px;
  --pie-h: 56px;
  --radio: 10px;
  --sombra-libro: 0 24px 70px rgba(0, 0, 0, .65);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--fondo);
  color: var(--tinta);
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  /* El visor maneja su propio gesto de arrastre; el rebote de scroll del
     documento lo pelea y en iOS dispara el pull-to-refresh a mitad de un
     drag de página. */
  overscroll-behavior: none;
}

body {
  display: flex;
  flex-direction: column;
  /* dvh y no vh: en iOS la barra de URL se retrae y con vh el pie queda
     tapado justo cuando aparece el teclado del navegador. */
  height: 100dvh;
  overflow: hidden;
  /* El texto de la UI no se selecciona — un drag largo sobre el libro
     terminaba pintando de azul el número de página. Las páginas son <img>,
     que tampoco se seleccionan. */
  user-select: none;
  -webkit-user-select: none;
}

/* ── Barra superior ───────────────────────────────────────────────────── */

.barra {
  flex: 0 0 auto;
  height: var(--barra-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 14px;
  padding-top: env(safe-area-inset-top);
  height: calc(var(--barra-h) + env(safe-area-inset-top));
  border-bottom: 1px solid var(--borde);
  background: linear-gradient(180deg, rgba(22, 22, 27, .96), rgba(13, 13, 16, .92));
  backdrop-filter: blur(8px);
  z-index: 30;
}

.barra__marca { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.barra__titulo {
  font-size: 15px; font-weight: 600; letter-spacing: -.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.barra__sep { color: var(--borde); }
.barra__sub { font-size: 13px; color: var(--oro); white-space: nowrap; }
.barra__acciones { display: flex; gap: 6px; flex: 0 0 auto; }

/* ── Botones ──────────────────────────────────────────────────────────── */

.btn {
  /* 40px: por debajo de 44 el pulgar erra, y este es el chrome que se toca
     con el catálogo abierto en la mano. */
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: rgba(255, 255, 255, .03);
  color: var(--tinta);
  cursor: pointer;
  transition: background .16s ease, border-color .16s ease, transform .1s ease;
  -webkit-tap-highlight-color: transparent;
}
.btn:hover { background: rgba(255, 255, 255, .07); border-color: #3a3a46; }
.btn:active { transform: scale(.94); }
.btn:focus-visible { outline: 2px solid var(--oro); outline-offset: 2px; }
.btn svg {
  width: 19px; height: 19px;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ── Escenario (donde vive el libro) ──────────────────────────────────── */

.escenario {
  flex: 1 1 auto;
  position: relative;
  display: grid;
  place-items: center;
  /* min-height:0 en un hijo flex que además es grid: sin esto el escenario
     se niega a achicarse por debajo del alto de su contenido y empuja el pie
     fuera de la pantalla. */
  min-height: 0;
  overflow: hidden;
  padding: 14px;
}

.libro-wrap {
  position: relative;
  /* touch-action:none le saca al browser el pan/zoom nativo sobre el libro,
     que si no compite con el drag de página del motor. El pinch se recupera
     a mano (abre la capa de zoom, ver catalogo.js). */
  touch-action: none;
}

.libro {
  box-shadow: var(--sombra-libro);
  /* Las páginas las inyecta StPageFlip; esto es sólo el sostén. */
}

/* ⚠ GOTCHA de StPageFlip. El motor mide el alto disponible con
   `distElement.offsetHeight`, y su distElement es `.stf__wrapper` — un div
   cuyos hijos son todos `position:absolute`, o sea que colapsa a 0 salvo que
   `autoSize:true` le ponga un padding-bottom porcentual.
   Acá autoSize va en FALSE a propósito (el tamaño lo calcula catalogo.js para
   encajar la página por sus dos lados, cosa que el modo `fixed` del motor no
   hace). Sin este 100%, getBlockHeight() devuelve 0 y las páginas se
   posicionan en `top: -alto/2`: medio libro dibujado arriba del escenario.
   El síntoma es puramente geométrico —el flip funciona, el conteo de páginas
   es correcto, no hay error en consola—, así que sólo se ve mirando. */
.libro > .stf__wrapper { height: 100%; }

/* Página individual dentro del flipbook (modo HTML del motor). */
.pagina {
  background: var(--fondo-2);
  overflow: hidden;
}
.pagina img {
  width: 100%;
  height: 100%;
  /* contain y no cover: una página con aspecto distinto al del libro debe
     letterboxearse, nunca recortarse — recortar un catálogo se come precios. */
  object-fit: contain;
  display: block;
  pointer-events: none;   /* el drag lo maneja el motor, no el arrastre de imagen */
  -webkit-user-drag: none;
}
/* Placeholder mientras la página todavía no entró en la ventana de precarga. */
.pagina--vacia {
  background:
    linear-gradient(110deg, var(--fondo-2) 30%, #1e1e25 45%, var(--fondo-2) 60%)
    0 0 / 300% 100%;
  animation: brillo 1.4s ease-in-out infinite;
}
@keyframes brillo { to { background-position: -300% 0; } }

/* ── Flechas de navegación ────────────────────────────────────────────── */

.nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 46px; height: 72px;
  display: grid; place-items: center;
  border: 1px solid var(--borde);
  border-radius: var(--radio);
  background: rgba(13, 13, 16, .72);
  backdrop-filter: blur(6px);
  color: var(--tinta);
  cursor: pointer;
  opacity: .55;
  transition: opacity .18s ease, background .18s ease;
  z-index: 20;
  -webkit-tap-highlight-color: transparent;
}
.nav:hover { opacity: 1; background: rgba(13, 13, 16, .92); }
.nav:focus-visible { opacity: 1; outline: 2px solid var(--oro); outline-offset: 2px; }
.nav[disabled] { opacity: .12; cursor: default; pointer-events: none; }
.nav svg {
  width: 22px; height: 22px;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
.nav--prev { left: 10px; }
.nav--next { right: 10px; }

/* En pantallas angostas las flechas taparían el arte vertical, que usa todo
   el ancho. Ahí se navega con swipe y con la barra del pie. */
@media (max-width: 700px) {
  .nav { display: none; }
}

/* ── Pie: indicador + scrubber ────────────────────────────────────────── */

.pie {
  flex: 0 0 auto;
  height: calc(var(--pie-h) + env(safe-area-inset-bottom));
  padding: 0 16px env(safe-area-inset-bottom);
  display: flex;
  align-items: center;
  gap: 14px;
  border-top: 1px solid var(--borde);
  background: linear-gradient(0deg, rgba(22, 22, 27, .96), rgba(13, 13, 16, .92));
  z-index: 30;
}

.pie__paginas {
  font-size: 13px;
  color: var(--tinta-baja);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  min-width: 76px;
}

.scrubber {
  flex: 1 1 auto;
  appearance: none;
  -webkit-appearance: none;
  height: 4px;
  border-radius: 999px;
  background: var(--borde);
  cursor: pointer;
  /* El scrubber es el ÚNICO control que quiere el pan horizontal nativo:
     sin esto, el touch-action:none del escenario lo dejaría muerto. */
  touch-action: pan-x;
}
.scrubber:disabled { opacity: .35; cursor: default; }
.scrubber::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--oro);
  border: 2px solid var(--fondo);
  cursor: grab;
}
.scrubber::-moz-range-thumb {
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--oro);
  border: 2px solid var(--fondo);
  cursor: grab;
}
.scrubber:focus-visible { outline: 2px solid var(--oro); outline-offset: 4px; }

/* ── Estado (carga / error) ───────────────────────────────────────────── */

.estado {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 14px;
  background: var(--fondo);
  z-index: 25;
  transition: opacity .3s ease;
}
.estado[hidden] { display: none; }
.estado--error .spinner { display: none; }
.estado__texto { margin: 0; font-size: 14px; color: var(--tinta-baja); text-align: center; max-width: 34ch; }
.estado--error .estado__texto { color: #e08585; }

.spinner {
  width: 26px; height: 26px;
  border: 2px solid var(--borde);
  border-top-color: var(--oro);
  border-radius: 50%;
  animation: girar .8s linear infinite;
}
@keyframes girar { to { transform: rotate(360deg); } }

/* ── Capa de zoom ─────────────────────────────────────────────────────── */

.zoom {
  position: fixed;
  inset: 0;
  background: #07070a;
  z-index: 60;
  overflow: hidden;
  touch-action: none;
  cursor: grab;
}
.zoom[hidden] { display: none; }
.zoom.zoom--arrastrando { cursor: grabbing; }

.zoom__lienzo {
  position: absolute;
  top: 0; left: 0;
  transform-origin: 0 0;
  /* will-change se pone y se saca desde JS: dejarlo fijo mantiene una capa
     de compositor del tamaño del @2x viva todo el tiempo, que en un teléfono
     es memoria de GPU que después falta para decodificar la página siguiente. */
}
.zoom__lienzo img {
  display: block;
  pointer-events: none;
  -webkit-user-drag: none;
}

.zoom__cerrar {
  position: absolute;
  top: calc(12px + env(safe-area-inset-top));
  right: 12px;
  background: rgba(13, 13, 16, .8);
  backdrop-filter: blur(6px);
  z-index: 2;
}

.zoom__ayuda {
  position: absolute;
  bottom: calc(18px + env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  padding: 7px 14px;
  border-radius: 999px;
  background: rgba(13, 13, 16, .82);
  backdrop-filter: blur(6px);
  border: 1px solid var(--borde);
  font-size: 12px;
  color: var(--tinta-baja);
  white-space: nowrap;
  pointer-events: none;
  transition: opacity .4s ease;
}
.zoom__ayuda--oculta { opacity: 0; }

/* ── Pantalla completa ────────────────────────────────────────────────── */

/* Fallback para iOS, donde requestFullscreen no existe en el iPhone: se
   simula tapando el viewport y escondiendo el chrome. */
body.pseudo-fullscreen .barra,
body.pseudo-fullscreen .pie { display: none; }

.sin-js {
  position: fixed; inset: 0;
  display: grid; place-content: center;
  margin: 0; padding: 24px;
  background: var(--fondo);
  text-align: center;
  color: var(--tinta-baja);
  z-index: 90;
}

@media (prefers-reduced-motion: reduce) {
  .pagina--vacia { animation: none; }
  .spinner { animation-duration: 2.4s; }
  .btn, .nav { transition: none; }
}
