/* ─────────────────────────────────────────────────────────────────────────
   PDF Reader viewer styles.
   Everything is driven off CSS custom properties so the Dart side can flip
   theme / density / colours with a single command without a reload.
   ───────────────────────────────────────────────────────────────────────── */

:root {
  --pr-bg:            #f2f3f5;
  --pr-page-bg:       #ffffff;
  --pr-page-shadow:   0 1px 3px rgba(0, 0, 0, .16), 0 6px 18px rgba(0, 0, 0, .10);
  --pr-fg:            #14161a;
  --pr-muted:         #6b7280;
  --pr-accent:        #2f6df6;
  --pr-surface:       #ffffff;
  --pr-surface-brd:   rgba(0, 0, 0, .10);
  --pr-gap:           16px;
  --pr-thumb-w:       132px;
  --pr-safe-top:      env(safe-area-inset-top, 0px);
  --pr-safe-bottom:   env(safe-area-inset-bottom, 0px);
  --pr-page-filter:   none;
  --pr-select:        rgba(47, 109, 246, .32);
}

html[data-theme="dark"] {
  --pr-bg:            #0f1115;
  --pr-page-bg:       #14171d;
  --pr-page-shadow:   0 1px 3px rgba(0, 0, 0, .55);
  --pr-fg:            #e6e8ec;
  --pr-muted:         #9aa1ad;
  --pr-surface:       #1b1f27;
  --pr-surface-brd:   rgba(255, 255, 255, .12);
  /* Invert + hue-rotate keeps photos recognisable while turning paper black. */
  --pr-page-filter:   invert(1) hue-rotate(180deg) brightness(.92) contrast(1.04);
  --pr-select:        rgba(120, 165, 255, .34);
}

html[data-theme="sepia"] {
  --pr-bg:            #e8dfcc;
  --pr-page-bg:       #fbf3e2;
  --pr-fg:            #3b3323;
  --pr-page-filter:   sepia(.22) saturate(1.05);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  background: var(--pr-bg);
  color: var(--pr-fg);
  font: 14px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, "Helvetica Neue", sans-serif;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
}

/* Chrome/WebView2 gets the composited scrollbar out of the way. */
.pr-viewport::-webkit-scrollbar { width: 10px; height: 10px; }
.pr-viewport::-webkit-scrollbar-thumb {
  background: rgba(128, 128, 128, .45);            /* fallback: Safari < 16.2 */
  background: color-mix(in srgb, var(--pr-fg) 22%, transparent);
  border-radius: 6px;
  border: 3px solid transparent;
  background-clip: content-box;
}
/* Firefox has no ::-webkit-scrollbar; this is its equivalent. */
.pr-viewport { scrollbar-width: thin; scrollbar-color: rgba(128,128,128,.45) transparent; }
.pr-viewport::-webkit-scrollbar-track { background: transparent; }

/* The page surface. In browser mode it sits next to the sidebar inside
   `.pr-body`; in embedded mode it is the only thing on screen. */
.pr-root {
  position: relative;
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  height: 100%;
  width: 100%;
}

/* ── viewport ─────────────────────────────────────────────────────────── */

.pr-viewport {
  position: relative;
  flex: 1 1 auto;
  height: 100%;
  overflow: auto;
  outline: none;
  /* Hardware acceleration + momentum scrolling on WebKit. */
  -webkit-overflow-scrolling: touch;
  transform: translateZ(0);
  /* layout+paint only — `contain: strict` adds size containment, which would
     collapse the scroll container to zero height. */
  contain: layout paint;
}

.pr-pages {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--pr-gap);
  padding: calc(var(--pr-gap) + var(--pr-safe-top)) var(--pr-gap)
           calc(var(--pr-gap) + var(--pr-safe-bottom));
  min-height: 100%;
  width: max-content;
  min-width: 100%;
}

/* horizontal scroll mode */
.pr-root[data-scroll="horizontal"] .pr-pages {
  flex-direction: row;
  align-items: center;
  width: max-content;
  scroll-snap-type: x mandatory;
}
.pr-root[data-scroll="horizontal"] .pr-page { scroll-snap-align: center; }

/* two-page spread */
.pr-root[data-spread="on"] .pr-pages {
  flex-flow: row wrap;
  justify-content: center;
  align-content: flex-start;
  width: auto;
}

/* In paged mode the spread is a book: the two halves meet with no gap, share
   one drop shadow, and carry a gutter shadow down the spine. */
.pr-root[data-mode="paged"][data-spread="on"] .pr-pages {
  gap: 0;
  flex-wrap: nowrap;
  align-items: center;
}
.pr-root[data-mode="paged"][data-spread="on"] .pr-page {
  border-radius: 0;
  box-shadow: none;
}
.pr-root[data-mode="paged"][data-spread="on"] .pr-page:first-of-type {
  border-radius: 3px 0 0 3px;
  box-shadow: -3px 2px 16px rgba(0, 0, 0, .22);
}
.pr-root[data-mode="paged"][data-spread="on"] .pr-page:last-of-type {
  border-radius: 0 3px 3px 0;
  box-shadow: 3px 2px 16px rgba(0, 0, 0, .22);
}
/* The empty leaf facing a cover or a trailing odd page: it holds the space
   so the cover sits on the right, where a book's page 1 belongs. */
.pr-page--blank {
  background: transparent;
  box-shadow: none;
  pointer-events: none;
}
.pr-root:not([data-mode="paged"]) .pr-page--blank,
.pr-root:not([data-spread="on"]) .pr-page--blank { display: none !important; }

/* Paper curving into the binding. */
.pr-root[data-mode="paged"][data-spread="on"] .pr-page::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  width: 34px;
  pointer-events: none;
  z-index: 4;
}
.pr-root[data-mode="paged"][data-spread="on"] .pr-page:first-of-type::after {
  right: 0;
  background: linear-gradient(to right, rgba(0,0,0,0), rgba(0,0,0,.16));
}
.pr-root[data-mode="paged"][data-spread="on"] .pr-page:last-of-type::after {
  left: 0;
  background: linear-gradient(to left, rgba(0,0,0,0), rgba(0,0,0,.16));
}

/* ── a page ───────────────────────────────────────────────────────────── */

.pr-page {
  position: relative;
  flex: 0 0 auto;
  background: var(--pr-page-bg);
  box-shadow: var(--pr-page-shadow);
  border-radius: 2px;
  overflow: hidden;
  /* Placeholder pages must not repaint while scrolling. */
  contain: layout paint style;
}

.pr-page__canvas {
  display: block;
  width: 100%;
  height: 100%;
  filter: var(--pr-page-filter);
  /* keep the bitmap crisp while a fresh render is in flight */
  image-rendering: auto;
}

.pr-page__num {
  position: absolute;
  right: 6px;
  bottom: 4px;
  font-size: 10px;
  color: var(--pr-muted);
  background: rgba(255, 255, 255, .7);             /* fallback */
  background: color-mix(in srgb, var(--pr-page-bg) 70%, transparent);
  padding: 1px 5px;
  border-radius: 6px;
  pointer-events: none;
  opacity: 0;
  transition: opacity .18s;
}
.pr-viewport.is-scrolling .pr-page__num { opacity: 1; }

/* ── text layer ─────────────────────────────────────────────────────────
   Invisible glyphs sitting exactly on top of the rasterised ones. This is
   what makes selection behave like a native PDF viewer, so it deliberately
   mirrors PDF.js's own text_layer_builder.css — deviating from it is how
   selection ends up subtly wrong. */
.pr-page__text {
  position: absolute;
  inset: 0;
  overflow: hidden;
  line-height: 1;
  text-align: initial;
  transform-origin: 0 0;
  opacity: 1;
  color: transparent;
  z-index: 3;
  -webkit-text-size-adjust: none;
  text-size-adjust: none;
  forced-color-adjust: none;
  -webkit-user-select: text;
  user-select: text;
  cursor: text;
}
.pr-page__text span,
.pr-page__text br {
  position: absolute;
  white-space: pre;
  transform-origin: 0% 0%;
  color: transparent;
  cursor: text;
}
/* Marked-content anchors carry no glyphs; giving them size would let a drag
   land on them and select nothing. */
.pr-page__text span.markedContent { top: 0; height: 0; }

.pr-page__text ::selection      { background: var(--pr-select); }
.pr-page__text ::-moz-selection { background: var(--pr-select); }
/* A line break picking up the selection colour paints a stray block at the
   end of every selected line. */
.pr-page__text br::selection { background: transparent; }

/* See appendEndOfContent() in js/textlayer.js. Parked below the page until a
   drag starts, then raised to cover it so the selection extends through the
   text rather than snapping to whatever span is next in the DOM. */
.pr-page__text .endOfContent {
  display: block;
  position: absolute;
  inset: 100% 0 0;
  z-index: -1;
  cursor: default;
  -webkit-user-select: none;
  user-select: none;
}
.pr-page__text .endOfContent.active { top: 0; }

/* search hit boxes live in their own layer so they survive re-renders */
.pr-page__marks,
.pr-page__annots {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
}
.pr-page__annots { z-index: 1; }

.pr-mark {
  position: absolute;
  background: rgba(255, 214, 0, .38);
  border-radius: 2px;
  mix-blend-mode: multiply;
}
.pr-mark--active {
  background: rgba(255, 132, 0, .62);
  box-shadow: 0 0 0 1px rgba(255, 132, 0, .9);
}
html[data-theme="dark"] .pr-mark { mix-blend-mode: screen; }

/* annotations */
.pr-annot { position: absolute; pointer-events: auto; }
.pr-annot--highlight { border-radius: 2px; mix-blend-mode: multiply; }
html[data-theme="dark"] .pr-annot--highlight { mix-blend-mode: screen; }
.pr-annot--underline { border-bottom: 2px solid currentColor; background: none; }
.pr-annot--strikeout::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 50%;
  border-top: 2px solid currentColor;
}
.pr-annot--ink { pointer-events: none; }
.pr-annot--note {
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 2px solid var(--pr-page-bg);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .35);
  cursor: pointer;
}
.pr-annot.is-selected { outline: 2px solid var(--pr-accent); outline-offset: 1px; }

/* ── thumbnails ───────────────────────────────────────────────────────── */

.pr-thumbs {
  flex: 0 0 var(--pr-thumb-w);
  width: var(--pr-thumb-w);
  height: 100%;
  overflow-y: auto;
  background: var(--pr-bg);                        /* fallback */
  background: color-mix(in srgb, var(--pr-bg) 82%, var(--pr-fg) 4%);
  border-right: 1px solid var(--pr-surface-brd);
  padding: 8px 0 calc(8px + var(--pr-safe-bottom));
  contain: layout paint;
}
.pr-thumbs[hidden] { display: none; }
.pr-thumbs__list { display: flex; flex-direction: column; align-items: center; gap: 10px; }

.pr-thumb {
  position: relative;
  width: calc(var(--pr-thumb-w) - 24px);
  background: var(--pr-page-bg);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .22);
  border-radius: 2px;
  cursor: pointer;
  overflow: hidden;
}
.pr-thumb canvas { display: block; width: 100%; height: 100%; filter: var(--pr-page-filter); }
.pr-thumb__label {
  text-align: center;
  font-size: 11px;
  color: var(--pr-muted);
  padding: 2px 0 0;
}
.pr-thumb.is-current { outline: 2px solid var(--pr-accent); outline-offset: 1px; }

/* ── page-turn (paged mode) ───────────────────────────────────────────── */

.pr-root[data-mode="paged"] .pr-viewport { overflow: hidden; }
.pr-root[data-mode="paged"] .pr-pages { padding: 0; height: 100%; justify-content: center; }

.pr-flip {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* Shallower perspective than a UI card: a book page is large and close, so
     too much perspective makes it look like it is flying away. */
  perspective: 2200px;
  perspective-origin: 50% 50%;
  z-index: 6;
}
.pr-flip[hidden] { display: none; }

/* ── the peel ───────────────────────────────────────────────────────────
   Three positioned layers, no 3D: the half still showing the old page, the
   unturned remainder of the sheet, and the piece folded back over it. See
   the crease equation at the top of js/pageturn.js. */

.pr-peel__static,
.pr-peel__flat,
.pr-peel__fold {
  position: absolute;
  background-repeat: no-repeat;
  background-color: var(--pr-page-bg);
  filter: var(--pr-page-filter);
  pointer-events: none;
  will-change: left, width;
}
.pr-peel__static[hidden],
.pr-peel__flat[hidden],
.pr-peel__fold[hidden] { display: none; }

/* The unturned remainder. Its outer edge is the crease, so the shadow the
   lifted paper throws lands there. */
.pr-peel__flat { overflow: hidden; }
.pr-peel__flat-shade {
  position: absolute;
  inset: 0;
  opacity: 0;
  background: linear-gradient(to right,
    rgba(0, 0, 0, 0) 55%, rgba(0, 0, 0, .55) 100%);
}

/* The folded piece. Its right edge is the crease (darkest, where the paper
   bends away) and its left edge is the free edge, lifted and lit. */
.pr-peel__fold {
  overflow: hidden;
  box-shadow: -6px 3px 20px rgba(0, 0, 0, .28);
}
.pr-peel__fold-shade {
  position: absolute;
  inset: 0;
  opacity: 0;
  background: linear-gradient(to right,
    rgba(255, 255, 255, .22) 0%,
    rgba(0, 0, 0, .06) 26%,
    rgba(0, 0, 0, .30) 74%,
    rgba(0, 0, 0, .62) 100%);
}

/* Grab zones: the outer edges of the page invite a drag-to-turn. */
.pr-root[data-mode="paged"] .pr-page { cursor: auto; }

/* ── floating UI ──────────────────────────────────────────────────────── */

.pr-selbar {
  position: absolute;
  z-index: 20;
  display: flex;
  gap: 2px;
  padding: 4px;
  background: var(--pr-surface);
  border: 1px solid var(--pr-surface-brd);
  border-radius: 10px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .22);
  transform: translate(-50%, -100%);
  animation: pr-pop .12s ease-out;
}
.pr-selbar[hidden] { display: none; }
.pr-selbar button {
  all: unset;
  width: 32px; height: 32px;
  display: grid; place-items: center;
  border-radius: 7px;
  cursor: pointer;
  color: var(--pr-fg);
}
.pr-selbar button:hover  { background: rgba(128, 128, 128, .18); }
.pr-selbar button:active { background: rgba(128, 128, 128, .28); }
.pr-selbar button:focus-visible { outline: 2px solid var(--pr-accent); outline-offset: -2px; }

/* Stroke icons, so each action is identifiable at a glance rather than being
   an anonymous coloured dot. */
.pr-selbar button svg {
  width: 18px; height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* Every markup button previews the active colour, so the bar always answers
   "what will this apply?" before you click it: the marker nib is filled, and
   the underline / strikethrough rules are stroked in that colour. */
.pr-selbar button[data-act="highlight"] svg path:first-child {
  fill: var(--pr-highlight, #ffd54a);
  stroke: none;
}
.pr-selbar button[data-act="underline"] svg path:last-child,
.pr-selbar button[data-act="strike"] svg path:last-child {
  stroke: var(--pr-highlight, #ffd54a);
  stroke-width: 2.8;
}

.pr-selbar__sep {
  width: 1px;
  height: 20px;
  margin: 0 3px;
  background: var(--pr-surface-brd);
  flex: 0 0 auto;
}

.pr-selbar__colors {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 0 4px;
}
.pr-selbar__colors button {
  all: unset;
  width: 18px; height: 18px;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 0 0 1px var(--pr-surface-brd);
}
.pr-selbar__colors button:hover { transform: scale(1.15); }
.pr-selbar__colors button.is-on {
  box-shadow: 0 0 0 2px var(--pr-accent), inset 0 0 0 2px var(--pr-surface);
}

.pr-note {
  position: absolute;
  z-index: 21;
  width: 250px;
  padding: 8px;
  background: var(--pr-surface);
  border: 1px solid var(--pr-surface-brd);
  border-radius: 10px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, .26);
  transform: translate(-50%, 8px);
  animation: pr-pop .12s ease-out;
}
.pr-note[hidden] { display: none; }
.pr-note textarea {
  width: 100%;
  resize: none;
  border: 1px solid var(--pr-surface-brd);
  border-radius: 7px;
  padding: 6px;
  font: inherit;
  color: var(--pr-fg);
  background: var(--pr-bg);
  outline: none;
}
.pr-note__row { display: flex; align-items: center; gap: 6px; margin-top: 6px; }
.pr-note__swatches { display: flex; gap: 4px; flex: 1 1 auto; }
.pr-note__swatches i {
  width: 16px; height: 16px;
  border-radius: 50%;
  cursor: pointer;
  display: inline-block;
  box-shadow: 0 0 0 1px var(--pr-surface-brd);
}
.pr-note__swatches i.is-on { box-shadow: 0 0 0 2px var(--pr-accent); }
.pr-note__btn {
  all: unset;
  padding: 4px 10px;
  border-radius: 7px;
  background: var(--pr-accent);
  color: #fff;
  cursor: pointer;
  font-size: 12px;
}
.pr-note__btn--danger { background: transparent; color: #e5484d; }

@keyframes pr-pop { from { opacity: 0; transform: translate(-50%, -100%) scale(.96); } }

/* ── loading / error ──────────────────────────────────────────────────── */

.pr-loading {
  position: absolute;
  left: 0; right: 0; top: 0;
  z-index: 30;
  padding: calc(10px + var(--pr-safe-top)) 16px 10px;
  pointer-events: none;
  transition: opacity .25s;
}
.pr-loading.is-done { opacity: 0; }
.pr-loading__bar {
  height: 3px;
  border-radius: 3px;
  background: rgba(128, 128, 128, .22);
  overflow: hidden;
}
.pr-loading__bar i {
  display: block;
  height: 100%;
  width: 0%;
  background: var(--pr-accent);
  transition: width .18s ease-out;
}
.pr-loading__label { margin-top: 6px; font-size: 12px; color: var(--pr-muted); }

.pr-error {
  position: absolute;
  inset: 0;
  z-index: 40;
  display: grid;
  place-content: center;
  gap: 6px;
  text-align: center;
  padding: 24px;
  background: var(--pr-bg);
}
.pr-error[hidden] { display: none; }
.pr-error__title  { font-size: 15px; font-weight: 600; }
.pr-error__detail { font-size: 12px; color: var(--pr-muted); max-width: 380px; word-break: break-word; }

/* Respect the OS "reduce motion" switch everywhere. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}
