/* ───────────────────────────────────────────────────────────────
   Flipbook Viewer — responsive, full-viewport, dark theme
   Apple-inspired: clarity, depth, subtle glass, natural motion
   ─────────────────────────────────────────────────────────────── */

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: #0a0a0a;
  color: #f5f5f7;
  font-family:
    -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", system-ui,
    "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overscroll-behavior: none;
  overflow: hidden;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  inset: 0;
  /* Allow native pinch-to-zoom for reading body text on phones.
     StPageFlip still handles single-finger swipe gestures on the book element
     because pinch (2 fingers) and swipe (1 finger) don't conflict. */
  touch-action: pinch-zoom pan-y;
}

/* ─── Ambient Backdrop ────────────────────────────────────────────
   Two modes, controlled by JS based on manifest.backdrop:

   1. PER-PAGE (default, used by Shell Samurai et al.):
      The current page image is set as --bg-image and updated on every
      flip. Heavy blur + low brightness keeps it as ambient texture
      that won't compete with the book content.

   2. STATIC COVER (used when manifest.backdrop is set):
      The book's cover art is loaded once and never changes. Lighter
      blur + higher brightness so the cover branding stays recognizable
      while the flipbook reads cleanly above it. Triggered by the
      `static-backdrop` class on <body>.
   ─────────────────────────────────────────────────────────────── */
#backdrop-image {
  position: fixed;
  inset: -10%;
  background-color: #0a0a0a;
  background-image: var(--bg-image, none);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  /* PER-PAGE default: heavy blur, dim — pure ambient texture */
  filter: blur(100px) brightness(0.38) saturate(1.4);
  transform: scale(1.3) translateZ(0);
  z-index: 0;
  transition: filter 0.6s ease-out;
  will-change: background-image;
  pointer-events: none;
}

/* STATIC COVER mode: tuned to keep cover art recognizable as branding.
   Less blur (cover details still readable as art), higher brightness
   (cover colors come through), slight saturation boost (more alive).
   Tuned per Leo's feedback — initial 38px blur was too heavy, made
   the cover read as muddled darkness. 18px keeps it recognizable as
   the actual cover artwork while still sitting clearly behind the book. */
body.static-backdrop #backdrop-image {
  filter: blur(14px) brightness(0.62) saturate(1.18);
  transform: scale(1.05) translateZ(0);
}

#backdrop-overlay {
  position: fixed;
  inset: 0;
  background: radial-gradient(
    ellipse at center,
    rgba(10, 10, 10, 0.4) 0%,
    rgba(5, 5, 5, 0.78) 70%,
    rgba(0, 0, 0, 0.92) 100%
  );
  z-index: 1;
  pointer-events: none;
}

/* In static mode, the goal is "branded backdrop you can see," not "black
   void with hint of color." The previous radial-gradient was darkest at
   the edges (88%), which is exactly where mobile users see the cover
   (book is at center, cover-art shows around it). That made the cover
   essentially invisible on phones. Switched to a much lighter, near-
   uniform darken with subtle radial structure — book stays legible at
   center, cover comes through clearly everywhere else. */
body.static-backdrop #backdrop-overlay {
  background: radial-gradient(
    ellipse at center,
    rgba(0, 0, 0, 0.32) 0%,
    rgba(0, 0, 0, 0.42) 65%,
    rgba(0, 0, 0, 0.52) 100%
  );
}

/* Mobile static-backdrop tuning: phones have small viewports where the
   cover is mostly visible at screen edges around the book. Lighter blur
   here is also a perf win — heavy filter:blur() on position:fixed can
   cause iOS Safari to drop GPU layers entirely (cover disappears). */
@media (max-width: 768px) {
  body.static-backdrop #backdrop-image {
    filter: blur(10px) brightness(0.66) saturate(1.18);
    transform: none; /* avoid GPU layer that iOS sometimes drops */
  }
  body.static-backdrop #backdrop-overlay {
    background: rgba(0, 0, 0, 0.36);
  }
}

#app {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

/* ─── Loader ─────────────────────────────────────────────────── */
.loader {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  background: radial-gradient(
    ellipse at center,
    #1a1a1a 0%,
    #0a0a0a 70%
  );
  z-index: 100;
  transition: opacity 0.5s ease;
}

.loader.hidden {
  opacity: 0;
  pointer-events: none;
}

.loader__pulse {
  width: 56px;
  height: 56px;
  border: 2px solid rgba(255, 255, 255, 0.08);
  border-top-color: rgba(255, 255, 255, 0.85);
  border-radius: 50%;
  animation: spin 0.9s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

.loader__label {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.55);
}

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

/* ─── Book container ─────────────────────────────────────────── */
#book-container {
  width: 100%;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Reduced horizontal padding so the book takes more screen width
     on mobile (was 24px → 8px = ~14% larger book on phones) */
  padding: 12px 8px;
  padding-bottom: 90px;
  min-height: 0;
}

#book {
  max-width: 100%;
  max-height: 100%;
  filter: drop-shadow(0 25px 60px rgba(0, 0, 0, 0.6));
}

/* StPageFlip page backgrounds — covers both Canvas mode (.stf__parent .page)
   and HTML mode (direct .page children). HTML mode gives native DPR scaling
   so images render crisply on retina/HiDPI displays. */
.stf__parent .page,
#book .page {
  background: #151515;
  background-size: cover;
  background-position: center;
  overflow: hidden;
}

.stf__parent img,
#book .page img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
  image-rendering: -webkit-optimize-contrast;
}

/* ─── Controls (floating glass bar) ──────────────────────────── */
.controls {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 18px;
  background: rgba(22, 22, 22, 0.72);
  backdrop-filter: blur(24px) saturate(180%);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 100px;
  z-index: 50;
  box-shadow:
    0 12px 40px rgba(0, 0, 0, 0.5),
    inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

.ctrl {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: #f5f5f7;
  cursor: pointer;
  border-radius: 50%;
  transition:
    background 0.18s ease,
    transform 0.1s ease;
}

.ctrl:hover {
  background: rgba(255, 255, 255, 0.08);
}

.ctrl:active {
  background: rgba(255, 255, 255, 0.14);
  transform: scale(0.94);
}

.ctrl:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.ctrl--toc {
  margin-right: 2px;
}

/* ─── Zoom mode (CSS zoom property — WebKit/Blink supported) ── */
#book-container.zoomed {
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  align-items: flex-start;
  padding-top: 30px;
}

#book-container.zoomed #book {
  zoom: 1.75;
  /* Drop-shadow looks weird at zoom; soften it */
  filter: drop-shadow(0 15px 30px rgba(0, 0, 0, 0.5));
}

/* While zoomed, disable StPageFlip's hit detection so the user can
   pan around without accidentally triggering page flips. They use
   the prev/next buttons in the controls bar to flip while zoomed. */
#book-container.zoomed .stf__parent,
#book-container.zoomed .stf__parent * {
  pointer-events: none !important;
}

.page-indicator {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.88);
  min-width: 64px;
  text-align: center;
  letter-spacing: 0.03em;
}

/* ─── Table of Contents Drawer ───────────────────────────────── */
.toc-scrim {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  z-index: 2999; /* above reader-mode (2000) so TOC works in reader */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.toc-scrim.open {
  opacity: 1;
  pointer-events: auto;
}

.toc-drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(460px, 92vw);
  background: rgba(15, 15, 15, 0.88);
  backdrop-filter: blur(36px) saturate(180%);
  -webkit-backdrop-filter: blur(36px) saturate(180%);
  border-left: 1px solid rgba(255, 255, 255, 0.08);
  z-index: 3000; /* above reader-mode so user can open TOC from reader */
  transform: translateX(102%);
  transition: transform 0.42s cubic-bezier(0.32, 0.72, 0, 1);
  display: flex;
  flex-direction: column;
  box-shadow: -30px 0 80px rgba(0, 0, 0, 0.5);
}

.toc-drawer.open {
  transform: translateX(0);
}

.toc-drawer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px 18px 18px 26px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  flex-shrink: 0;
}

.toc-drawer__title {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.01em;
  margin: 0;
  color: rgba(255, 255, 255, 0.95);
}

.ctrl--toc-close {
  width: 36px;
  height: 36px;
}

.toc-drawer__list {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 10px 0 40px;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.2) transparent;
  min-height: 0;
}

.toc-drawer__list::-webkit-scrollbar {
  width: 6px;
}

.toc-drawer__list::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.18);
  border-radius: 3px;
}

.toc-drawer__list::-webkit-scrollbar-track {
  background: transparent;
}

.toc-entry {
  display: flex;
  align-items: baseline;
  width: 100%;
  text-align: left;
  padding: 10px 26px 10px 26px;
  background: transparent;
  border: none;
  color: rgba(255, 255, 255, 0.75);
  font-family: inherit;
  font-size: 13px;
  line-height: 1.45;
  cursor: pointer;
  transition:
    background 0.15s ease,
    color 0.15s ease;
  position: relative;
  gap: 12px;
}

.toc-entry:hover {
  background: rgba(255, 255, 255, 0.05);
  color: #fff;
}

.toc-entry:active {
  background: rgba(255, 255, 255, 0.1);
}

.toc-entry__page {
  flex: 0 0 36px;
  color: rgba(255, 255, 255, 0.4);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  text-align: right;
  padding-top: 1px;
}

.toc-entry__title {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.toc-entry--level-1 {
  font-size: 14px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.95);
  padding-top: 16px;
  padding-bottom: 12px;
  margin-top: 6px;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.toc-entry--level-1:first-child {
  border-top: none;
  margin-top: 0;
  padding-top: 10px;
}

.toc-entry--level-2 {
  padding-left: 44px;
  font-weight: 400;
}

.toc-entry--level-2 .toc-entry__page {
  flex-basis: 28px;
}

.toc-entry--level-3 {
  padding-left: 62px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.55);
}

.toc-entry--level-3 .toc-entry__page {
  flex-basis: 28px;
}

.toc-entry--active {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
}

.toc-entry--active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 15%;
  bottom: 15%;
  width: 3px;
  background: #fff;
  border-radius: 0 2px 2px 0;
}

/* ─── Immersive (fullscreen) mode ────────────────────────────── */
body.immersive #backdrop-overlay {
  background: radial-gradient(
    ellipse at center,
    rgba(0, 0, 0, 0.3) 0%,
    rgba(0, 0, 0, 0.85) 75%,
    rgba(0, 0, 0, 0.95) 100%
  );
}

body.immersive #book-container {
  padding: 8px;
  padding-bottom: 8px;
}

body.immersive .controls {
  opacity: 0;
  pointer-events: none;
  transform: translateX(-50%) translateY(140%);
  transition:
    opacity 0.35s ease,
    transform 0.35s cubic-bezier(0.32, 0.72, 0, 1);
}

body.immersive.ui-visible .controls {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}

/* When the TOC drawer is open in immersive mode, keep it visible */
body.immersive .toc-drawer.open ~ .controls,
body.immersive:has(.toc-drawer.open) .controls {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%) translateY(0);
}

/* Native fullscreen backdrop */
#app:fullscreen,
#app:-webkit-full-screen {
  background: #0a0a0a;
}

:fullscreen #book-container,
:-webkit-full-screen #book-container {
  padding: 8px;
}

/* ─── Read Mode (reflowable dark reader) ────────────────────── */
.reader-mode {
  position: fixed;
  inset: 0;
  background: #0a0a0a;
  color: #d4d4d4;
  z-index: 2000;
  display: flex;
  flex-direction: column;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.35s ease;
  /* Font-family: warm serif for reading comfort. Crimson Pro would be
     ideal here but we use system serif fallbacks to avoid a web font
     request. On iOS, -apple-system-serif gives "New York" on modern iOS. */
  font-family:
    "New York", "Iowan Old Style", "Palatino Linotype", Palatino,
    Georgia, "Times New Roman", serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.reader-mode.open {
  opacity: 1;
  pointer-events: auto;
}

.reader-header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  background: rgba(10, 10, 10, 0.92);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  position: sticky;
  top: 0;
  z-index: 10;
}

.reader-header__title {
  flex: 1 1 auto;
  font-family:
    -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", system-ui,
    sans-serif;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.01em;
  margin: 0;
  color: rgba(255, 255, 255, 0.92);
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.reader-ctrl {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  color: #f5f5f7;
  cursor: pointer;
  border-radius: 50%;
  transition:
    background 0.18s ease,
    transform 0.1s ease;
}

.reader-ctrl:hover {
  background: rgba(255, 255, 255, 0.08);
}

.reader-ctrl:active {
  background: rgba(255, 255, 255, 0.14);
  transform: scale(0.94);
}

.reader-font-controls {
  flex: 0 0 auto;
  display: flex;
  gap: 2px;
}

.reader-ctrl--font {
  font-family:
    -apple-system, BlinkMacSystemFont, "SF Pro Text", "Inter", system-ui,
    sans-serif;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.85);
}

.font-label {
  line-height: 1;
}

.font-label--small {
  font-size: 13px;
}

.font-label--large {
  font-size: 18px;
}

.reader-body {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
  padding: 32px 24px 120px;
  outline: none;
}

.reader-body::-webkit-scrollbar {
  width: 6px;
}

.reader-body::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.15);
  border-radius: 3px;
}

.reader-content {
  max-width: 680px;
  margin: 0 auto;
  color: #d4d4d4;
  line-height: 1.65;
}

/* Font size steps — set on .reader-mode parent, inherited down */
.reader-mode--s .reader-content {
  font-size: 15px;
}
.reader-mode--m .reader-content {
  font-size: 18px;
}
.reader-mode--l .reader-content {
  font-size: 21px;
}
.reader-mode--xl .reader-content {
  font-size: 25px;
}

.reader-paragraph {
  margin: 0 0 1em;
  text-align: left;
  hyphens: auto;
  -webkit-hyphens: auto;
  overflow-wrap: break-word;
  word-wrap: break-word;
}

.reader-heading {
  font-family:
    -apple-system, BlinkMacSystemFont, "SF Pro Display", "Inter", system-ui,
    sans-serif;
  color: #f5f5f7;
  font-weight: 700;
  letter-spacing: -0.015em;
  margin: 2.2em 0 0.8em;
}

.reader-heading--l1 {
  font-size: 1.85em;
  margin-top: 3.2em;
  padding-top: 2em;
  letter-spacing: -0.02em;
  position: relative;
  text-align: center;
}

.reader-heading--l1::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 72px;
  height: 1px;
  background: rgba(255, 255, 255, 0.22);
}

.reader-heading--l1:first-child {
  margin-top: 0.4em;
  padding-top: 0;
}

.reader-heading--l1:first-child::before {
  display: none;
}

.reader-heading--l2 {
  font-size: 1.3em;
  margin-top: 1.8em;
  color: rgba(255, 255, 255, 0.88);
}

.reader-heading--l3 {
  font-size: 1.1em;
  margin-top: 1.4em;
  color: rgba(255, 255, 255, 0.75);
}

.reader-empty {
  max-width: 420px;
  margin: 60px auto 0;
  text-align: center;
  color: rgba(255, 255, 255, 0.5);
  font-size: 14px;
  line-height: 1.5;
}

body.reader-open {
  overflow: hidden;
}

/* ─── Mobile refinements ─────────────────────────────────────── */
@media (max-width: 768px) {
  #book-container {
    padding: 12px;
    padding-bottom: 80px;
  }
  .controls {
    bottom: 16px;
    padding: 8px 14px;
    gap: 10px;
  }
  .ctrl {
    width: 44px;
    height: 44px;
  }
  .page-indicator {
    min-width: 56px;
  }
  .toc-drawer {
    width: 100%;
  }
  .toc-drawer__header {
    padding: 18px 16px 14px 22px;
  }
  .toc-entry {
    padding-top: 12px;
    padding-bottom: 12px;
  }
}

/* Safe-area padding for notched devices */
@supports (padding: env(safe-area-inset-bottom)) {
  .controls {
    bottom: max(16px, env(safe-area-inset-bottom));
  }
  #book-container {
    padding-bottom: max(
      80px,
      calc(env(safe-area-inset-bottom) + 70px)
    );
  }
}
