/*
 * engine-next — the container, the stage and the sheet.
 *
 * Everything is prefixed `zn-` and scoped under `.zn-book`, so the stylesheet can be loaded
 * beside the old engine's without either touching the other. Colours come from custom
 * properties with sensible fallbacks: a host that defines the application's theme tokens gets
 * them, a bare page still looks right.
 */

.zn-book {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--zn-background, var(--reader-bg, #20232a));
  color: var(--zn-foreground, var(--text-primary, #e8eaed));
  contain: layout paint;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}

.zn-stage {
  position: absolute;
  inset: 0;
  overflow: hidden;
  cursor: pointer;
  /* Two fingers on the stage mean a pinch zoom, so the browser must not take them first. */
  touch-action: none;
  perspective: 2400px;
  perspective-origin: 50% 50%;
}

.zn-stage.zn-grabbing {
  cursor: grabbing;
}

/* The WebGL renderer's drawing buffer, and the page bitmaps of the 2D one. */
.zn-canvas {
  display: block;
  width: 100%;
  height: 100%;
}

.zn-spread {
  position: absolute;
  transform-style: preserve-3d;
}

.zn-page {
  position: absolute;
  top: 0;
  overflow: hidden;
  background: var(--zn-paper, #ffffff);
  box-shadow: 0 12px 34px rgb(0 0 0 / 38%);
}

.zn-page[hidden] {
  display: none;
}

.zn-page-left {
  border-radius: 2px 0 0 2px;
}

.zn-page-right {
  border-radius: 0 2px 2px 0;
}

.zn-sheet {
  position: absolute;
  top: 0;
  transform-style: preserve-3d;
  will-change: transform;
  pointer-events: none;
}

.zn-face {
  position: absolute;
  inset: 0;
  overflow: hidden;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  background: var(--zn-paper, #ffffff);
  box-shadow: 0 12px 34px rgb(0 0 0 / 38%);
}

.zn-face-back {
  transform: rotateY(180deg);
}

/* The document failed to open; the host application shows the message. */
.zn-failed .zn-stage {
  cursor: default;
}

@media (prefers-reduced-motion: reduce) {
  .zn-sheet {
    will-change: auto;
  }
}

/*
 * The selectable text layer. It sits over the pages, invisible: only the browser's own
 * selection highlight shows where it is. Nothing but a run of text takes pointer input, so a
 * click that lands between two lines still reaches the stage and turns the page.
 */

.zn-textlayers {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
}

.zn-textlayers[hidden] {
  display: none;
}

.zn-textlayer {
  position: absolute;
  overflow: hidden;
  line-height: 1;
}

.zn-textlayer-inner {
  position: absolute;
  inset: 0;
  transform-origin: 0 0;
}

.zn-textlayer span {
  position: absolute;
  white-space: pre;
  margin: 0;
  padding: 0;
  color: transparent;
  transform-origin: 0 0;
  cursor: text;
  pointer-events: auto;
  user-select: text;
  -webkit-user-select: text;
}

.zn-textlayer span::selection {
  background: rgb(64 138 255 / 35%);
  color: transparent;
}

/* The pointer belongs to the application's own chrome for the moment. */
.zn-stage.zn-inert {
  cursor: default;
}

.zn-stage.zn-inert .zn-textlayers {
  visibility: hidden;
}

/* Fullscreen paints its own backdrop; the container must fill it. */
.zn-book:fullscreen,
.zn-book.zn-fullscreen {
  width: 100%;
  height: 100%;
}

/* A page still being drawn */

.zn-spinners {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
}

.zn-spinner {
  position: absolute;
  width: 34px;
  height: 34px;
  margin: -17px 0 0 -17px;
  border-radius: 50%;
  border: 3px solid rgb(0 0 0 / 10%);
  border-top-color: var(--accent, #3b5bdb);
  animation: zn-spin 0.8s linear infinite;
}

.zn-spinner[hidden] {
  display: none;
}

@keyframes zn-spin {
  to {
    transform: rotate(360deg);
  }
}
