/* FlipReader 0.4.0 — engine styles. Brand through the --fr-* variables; override them on :root in the client page.
   Layout: the client gives the reader a full-window root and sets --fr-top / --fr-bottom to leave room for its own header/footer. */
:root {
  --fr-spine: .8;               /* centre-fold shading strength, 0 turns it off */
  --fr-spine-width: 9%;         /* how far the shading reaches into each page; the engine sets it from the `spineWidth` option (Tune slider) */
  --fr-fold: .45;               /* darkness of the strong fold shadow; the engine sets it from the `shadow` option (Tune slider) */
  --fr-ink: #1d1a15;            /* window colour behind everything */
  --fr-paper: #f3ede0;          /* page colour while an image loads */
  --fr-text: #fff9ef;           /* labels, arrows */
  --fr-accent: #c05131;         /* current page in the strip */
  --fr-panel: #fff9ef;          /* tune panel background */
  --fr-panel-text: #2f2a21;
  --fr-font: system-ui, sans-serif;
  --fr-backdrop: none;          /* set by the engine from opts.backdrop.image */
  --fr-tint: rgba(0,0,0,.5);    /* darkening over the backdrop so pages stay the brightest thing */
  --fr-top: 56px;               /* space for the client's header */
  --fr-bottom: 96px;            /* footer with the page strip */
}
html, body { margin: 0; height: 100%; overflow: hidden; overscroll-behavior: none; }
html { background: var(--fr-ink) var(--fr-backdrop) center / cover no-repeat fixed; }
body { background: var(--fr-tint); color: var(--fr-text); font-family: var(--fr-font); }

.fr-root { position: fixed; inset: 0; }
.fr-root *, .fr-root *::before, .fr-root *::after { box-sizing: border-box; }

/* ---- book ---- */
.fr-stage { position: absolute; inset: var(--fr-top) 0 var(--fr-bottom); display: grid; place-items: center; padding: 8px 56px; }
.fr-stage > * { grid-area: 1 / 1; }
/* soft shadow under the book: its own layer, sized to the real pages, grows as the book opens */
.fr-shadow { pointer-events: none; position: relative; }
.fr-shadow i { position: absolute; top: 0; height: 100%; border-radius: 2px; box-shadow: 0 40px 90px rgba(0,0,0,.65), 0 6px 18px rgba(0,0,0,.35); transition: left .45s ease, width .45s ease; }
/* ---- page edges (.fr-edges on the root): a stack of sheets beside the real pages, sized by JS to the pages on each side ---- */
.fr-edge { display: none; position: absolute; top: 3px; height: calc(100% - 6px); width: 0; background-color: var(--fr-paper); transition: left .45s ease, width .45s ease, opacity .45s ease; }
.fr-edges .fr-edge { display: block; }
.fr-closed .fr-edge { opacity: 0; }   /* a closed book shows its cover alone: no stack beside it */
.fr-edge-l { border-radius: 2px 0 0 2px; background-image: linear-gradient(to left, rgba(0,0,0,.18), rgba(0,0,0,.55)), repeating-linear-gradient(to left, rgba(0,0,0,0) 0 1px, rgba(0,0,0,.35) 1px 2px); }
.fr-edge-r { border-radius: 0 2px 2px 0; background-image: linear-gradient(to right, rgba(0,0,0,.18), rgba(0,0,0,.55)), repeating-linear-gradient(to right, rgba(0,0,0,0) 0 1px, rgba(0,0,0,.35) 1px 2px); }
.fr-book { width: auto; height: auto; transition: transform 1.6s cubic-bezier(.45,.05,.2,1); }   /* closed book sits centred, slides open */
.fr-page { background: var(--fr-paper); overflow: hidden; box-shadow: none !important; }
.fr-page img { width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; -webkit-user-drag: none; }
/* the blank pages beside the covers: see-through at rest, solid only while a page turns onto them (so nothing shows through the fold) */
.fr-page.blank { background: transparent; border: 0; outline: 0; }
.fr-page.blank.solid { background: linear-gradient(var(--fr-tint), var(--fr-tint)), var(--fr-ink) var(--fr-backdrop) no-repeat; }   /* same photo, lined up by JS */
.stf__parent { margin: 0 auto; }
/* ---- spine: each page darkens toward the centre fold, so the spread reads as bound, not two cards.
   Part of the page, so it turns with it and sits under the library's own fold shadows. Fades out while the book is closed. ---- */
.fr-page::after { content: ''; position: absolute; top: 0; bottom: 0; width: var(--fr-spine-width); pointer-events: none; opacity: var(--fr-spine); transition: opacity var(--fr-slide, 1.6s); }
.fr-page.--left::after { right: 0; background: linear-gradient(to left, rgba(0,0,0,.32), rgba(0,0,0,.06) 45%, rgba(0,0,0,0)); }
.fr-page.--right::after { left: 0; background: linear-gradient(to right, rgba(0,0,0,.32), rgba(0,0,0,.06) 45%, rgba(0,0,0,0)); }
.fr-page.blank::after, .fr-closed .fr-page::after { opacity: 0; }
/* ---- strong fold shadow (.fr-fold on the root): the library's gradients fade out from the first frame of a turn, so they
   barely register. These replace them (!important beats the library's inline style) while keeping its geometry: the
   cast shadow on the page beneath and the curl shading on the turning page. --fr-fold-fade is driven by JS over the
   last part of the turn. Direction classes come from prepTurn(). ---- */
.fr-fold .stf__outerShadow, .fr-fold .stf__innerShadow { opacity: var(--fr-fold-fade, 1); }
.fr-fold.fr-fwd .stf__outerShadow { background: linear-gradient(to right, rgba(0,0,0,var(--fr-fold)), rgba(0,0,0,calc(var(--fr-fold) * .33)) 45%, rgba(0,0,0,0)) !important; }
.fr-fold.fr-back .stf__outerShadow { background: linear-gradient(to left, rgba(0,0,0,var(--fr-fold)), rgba(0,0,0,calc(var(--fr-fold) * .33)) 45%, rgba(0,0,0,0)) !important; }
.fr-fold.fr-fwd .stf__innerShadow { background: linear-gradient(to left, rgba(0,0,0,var(--fr-fold)) 0%, rgba(0,0,0,calc(var(--fr-fold) * .22)) 20%, rgba(0,0,0,0) 60%) !important; }
.fr-fold.fr-back .stf__innerShadow { background: linear-gradient(to right, rgba(0,0,0,var(--fr-fold)) 0%, rgba(0,0,0,calc(var(--fr-fold) * .22)) 20%, rgba(0,0,0,0) 60%) !important; }
/* anything the client lays over a page */
.fr-page [data-overlay] { position: absolute; display: block; }

/* ---- nav ---- */
.fr-pill { background: rgba(255,249,239,.12); border: 1px solid rgba(255,249,239,.25); color: var(--fr-text); border-radius: 999px; height: 36px; padding: 0 14px; font: 500 13px var(--fr-font); cursor: pointer; }
.fr-arrow { position: absolute; top: 50%; transform: translateY(-50%); z-index: 20; width: 44px; height: 44px; border-radius: 50%; border: 1px solid rgba(255,249,239,.25); background: rgba(29,26,21,.6); color: var(--fr-text); font-size: 22px; cursor: pointer; display: grid; place-items: center; }
.fr-prev { left: 10px; } .fr-next { right: 10px; }
.fr-arrow[disabled] { opacity: .2; cursor: default; }
/* label centred above the strip, so a long or short title never pushes the thumbnails sideways */
.fr-footer { position: absolute; left: 0; right: 0; bottom: 0; height: var(--fr-bottom); z-index: 20; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 2px; padding: 0 16px 8px; text-shadow: 0 1px 6px rgba(0,0,0,.6); }
.fr-strip { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; padding: 6px 2px; max-width: 100%; }
.fr-strip::-webkit-scrollbar { display: none; }
.fr-strip button { flex: 0 0 auto; width: 36px; height: 48px; border: 2px solid transparent; border-radius: 4px; padding: 0; background: var(--fr-paper); cursor: pointer; opacity: .55; transition: .15s; overflow: hidden; }
.fr-strip button img { display: block; width: 100%; height: 100%; object-fit: cover; pointer-events: none; transition: opacity .3s; }
.fr-strip button.pending img, .fr-strip button.failed img { opacity: 0; }
/* ---- loading shimmer: a soft band sweeping over paper, on pages and thumbnails until their image is in ---- */
@keyframes fr-shimmer { from { background-position: -200% 0; } to { background-position: 200% 0; } }
.fr-page.loading, .fr-strip button.pending { background-color: var(--fr-paper); background-image: linear-gradient(100deg, rgba(255,255,255,0) 35%, rgba(255,255,255,.55) 50%, rgba(255,255,255,0) 65%); background-size: 200% 100%; animation: fr-shimmer 1.6s ease-in-out infinite; }
.fr-page.loading img { opacity: 0; }
.fr-page img { transition: opacity .35s; }
.fr-page.failed { background-color: var(--fr-paper); }
@media (prefers-reduced-motion: reduce) { .fr-page.loading, .fr-strip button.pending { animation: none; } }
.fr-strip button.on { opacity: 1; border-color: var(--fr-accent); transform: scale(1.08); }
.fr-label { font-size: 12px; opacity: .7; white-space: nowrap; min-height: 16px; text-align: center; }

/* ---- zoom view ---- */
.fr-zoom { position: fixed; inset: 0; z-index: 50; background: var(--fr-ink); display: none; touch-action: none; overflow: hidden; }
.fr-zoom.open { display: block; }
.fr-zoom img { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; user-select: none; -webkit-user-drag: none; }
.fr-zoom .fr-close { position: fixed; top: 12px; right: 12px; z-index: 2; }
.fr-zoom .fr-hint { position: fixed; bottom: 16px; left: 50%; transform: translateX(-50%); font-size: 12px; opacity: .6; }

/* ---- toast ---- */
.fr-toast { position: fixed; left: 50%; bottom: calc(var(--fr-bottom) + 14px); transform: translate(-50%, 10px); background: var(--fr-accent); color: #fff; padding: 10px 16px; border-radius: 999px; font: 700 13px var(--fr-font); z-index: 60; opacity: 0; transition: .25s; pointer-events: none; }
.fr-toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ---- debug: tune panel ---- */
.fr-tune { position: fixed; top: calc(var(--fr-top) + 8px); right: 16px; z-index: 35; width: 260px; max-height: calc(100vh - var(--fr-top) - 24px); overflow-y: auto; overscroll-behavior: contain; background: var(--fr-panel); color: var(--fr-panel-text); border-radius: 12px; padding: 14px 16px 16px; box-shadow: 0 20px 50px rgba(0,0,0,.5); display: none; }   /* never taller than the window: scrolls inside itself */
.fr-tune.open { display: block; }
.fr-tune h3 { font: 500 18px var(--fr-font); margin: 0 0 10px; }
.fr-tune h3:not(:first-child) { margin-top: 16px; }
.fr-tune h3 small { float: right; font-size: 11px; font-weight: 400; opacity: .6; margin-top: 5px; }
.fr-tune label { display: block; font-size: 12px; margin: 10px 0 4px; opacity: .85; }
.fr-tune label span { float: right; font-weight: 700; }
.fr-tune input[type=range] { width: 100%; accent-color: var(--fr-accent); margin-top: 4px; }
.fr-tune label.row { display: flex; align-items: center; gap: 8px; font-size: 13px; opacity: 1; }
.fr-tune .fr-pill { color: var(--fr-accent); border-color: var(--fr-accent); background: none; margin-top: 12px; height: 32px; }
.fr-tune select { display: block; width: 100%; margin-top: 4px; font: 13px var(--fr-font); color: var(--fr-panel-text); }
/* live preview of the backdrop as the window shows it: same photo, same blur, same tint */
.fr-tune .fr-bg-preview { aspect-ratio: 3 / 2; border-radius: 6px; margin: 2px 0 6px; background: linear-gradient(var(--fr-tint), var(--fr-tint)), var(--fr-ink) var(--fr-backdrop) center / cover no-repeat; box-shadow: inset 0 0 0 1px rgba(0,0,0,.15); cursor: pointer; position: relative; overflow: hidden; }
.fr-tune .fr-bg-preview span { position: absolute; left: 0; right: 0; bottom: 0; display: flex; justify-content: center; gap: 18px; padding: 6px; font: 600 12px var(--fr-font); color: #fff; background: rgba(0,0,0,.55); opacity: 0; transition: opacity .15s; }
.fr-tune .fr-bg-preview:hover span { opacity: 1; }
.fr-tune .fr-bg-preview b { font-weight: 600; cursor: pointer; } .fr-tune .fr-bg-preview b:hover { text-decoration: underline; }

@media (max-width: 720px) {
  :root { --fr-top: 48px; --fr-bottom: 84px; }
  .fr-stage { padding: 4px 6px; }
  .fr-arrow { display: none; }
  .fr-label { display: none; }
}
