/**
 * [flipbook] — styles for the self-hosted PDF.js + StPageFlip flipbook,
 * under its own `-pf__` namespace. Covers wahnsinn-flipbook-pf.js's
 * toolbar/stage chrome, the vendor .stf__* rules StPageFlip itself
 * requires, and the PDF.js text layer block. See
 * wahnsinn-flipbook-pf.js's own header comment for the full architecture
 * this styles.
 */

.wahnsinn-flipbook-pf {
	--wahnsinn-flipbook-pf-page-bg: #fff;
	margin: 1em auto;
	max-width: 100%;
}

.wahnsinn-flipbook-pf:fullscreen {
	display: flex;
	flex-direction: column;
	justify-content: center;
	background: #1a1a1a;
	padding: 1em 0;
	box-sizing: border-box;
	margin: 0;
	max-width: none;
}

.wahnsinn-flipbook-pf:fullscreen .wahnsinn-flipbook-pf__stage {
	flex: 1 1 auto;
	min-height: 0;
	/* Re-clips the page-turn curl (see __stage's own comment on why it's
	   deliberately unclipped otherwise) while in fullscreen — an extreme
	   corner-drag bleeding past the stage into the letterboxed black
	   background reads as broken there in a way it doesn't inline on the
	   page. Scoped to :fullscreen so normal-mode behavior is untouched.
	   Safe to hide both axes (not just Y): fullscreen sizing already fits
	   pfWrap to the viewport exactly, with no scrolling needed. */
	overflow: hidden;
}

.wahnsinn-flipbook-pf:fullscreen .wahnsinn-flipbook-pf__toolbar {
	flex: 0 0 auto;
	margin-top: 0.75em;
}

.wahnsinn-flipbook-pf:fullscreen .wahnsinn-flipbook-pf__navbtn {
	color: #fff;
}

.wahnsinn-flipbook-pf__toolbar {
	/* Deliberately no isolation/position/z-index of its own. __pageinfo
	   and __more are position:relative (for unrelated reasons — the
	   page-jump input overlay and the "..." popup anchor point) with no
	   explicit z-index, so they escape straight up to the document root's
	   stacking context and compete there directly against __stage's
	   explicit z-index:1 — losing outright, since an explicit z-index
	   always beats z-index:auto regardless of DOM order. That's what
	   keeps the resting toolbar (page count, more button, fullscreen)
	   consistently under a corner-drag's page curl. __more-popup still
	   needs to escape that same losing context when open, via its own
	   explicit z-index:10 — which only works because __toolbar itself has
	   no stacking context to trap it in (isolation:isolate on __toolbar
	   would cage the popup along with everything else, since containment
	   doesn't care what z-index a trapped descendant claims). */
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 2px;
	width: fit-content;
	margin: 0.75em auto 0;
	padding: 4px;
	background: #f7f7f7;
	border-radius: 6px;
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}

.wahnsinn-flipbook-pf__toolbtn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	padding: 0;
	background: transparent;
	border: none;
	border-radius: 4px;
	color: #888;
	cursor: pointer;
}

.wahnsinn-flipbook-pf__toolbtn:hover {
	background: #e7e7e7;
	color: #444;
}

.wahnsinn-flipbook-pf__pageinfo {
	position: relative;
	display: inline-block;
	color: #666;
	font-variant-numeric: tabular-nums;
	font-size: 12px;
	min-width: 5.5em;
	text-align: center;
	padding: 0 0.5em;
	background: rgba(0, 0, 0, 0.03);
	border-radius: 4px;
	line-height: 36px;
	cursor: pointer;
}

/* The input sits underneath pageLabel, invisible (opacity:0, color:
   transparent) until focused — clicking anywhere on the chip focuses it
   via the wrapping <label>'s native semantics (see the JS's own comment
   where these are built), no click handler needed to "open" it. Same
   technique dFlip's own .df-ui-page/label/input trio uses. */
.wahnsinn-flipbook-pf__pageinput {
	position: absolute;
	inset: 0;
	box-sizing: border-box;
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
	border: 1px solid #8f8f8f;
	border-radius: 4px;
	background: #fff;
	text-align: center;
	font: inherit;
	color: transparent;
	opacity: 0;
	z-index: -1;
}

.wahnsinn-flipbook-pf__pageinput:focus {
	opacity: 1;
	z-index: 2;
	color: inherit;
	outline: none;
}

.wahnsinn-flipbook-pf__pageinput:focus + .wahnsinn-flipbook-pf__pagelabel {
	opacity: 0;
}

.wahnsinn-flipbook-pf__more {
	position: relative;
}

.wahnsinn-flipbook-pf__more-popup {
	display: none;
	position: absolute;
	bottom: 100%;
	left: 50%;
	transform: translateX(-50%);
	margin-bottom: 8px;
	width: 200px;
	background: #f7f7f7;
	border-radius: 6px;
	box-shadow: 0 -1px 4px rgba(0, 0, 0, 0.25);
	overflow: hidden;
	z-index: 10;
}

.wahnsinn-flipbook-pf__more-popup.is-open {
	display: block;
}

.wahnsinn-flipbook-pf__more-item {
	display: flex;
	align-items: center;
	gap: 10px;
	width: 100%;
	padding: 10px 12px;
	background: transparent;
	border: none;
	border-top: 1px solid #e4e4e4;
	color: #444;
	font: inherit;
	font-size: 13px;
	text-align: left;
	cursor: pointer;
}

.wahnsinn-flipbook-pf__more-item:first-child {
	border-top: none;
}

.wahnsinn-flipbook-pf__more-item:hover {
	background: #eee;
}

.wahnsinn-flipbook-pf__more-item:disabled {
	opacity: 0.4;
	cursor: default;
	background: transparent;
}

.wahnsinn-flipbook-pf__more-item-icon {
	display: inline-flex;
	flex: 0 0 auto;
	color: #888;
}

.wahnsinn-flipbook-pf__stage {
	position: relative;
	/* Explicit (not auto) so __stage wins outright, by value, over any
	   z-index:auto sibling context (see __toolbar's own comment) rather
	   than relying on a DOM-order tiebreak — which would let a later
	   element win regardless of which one should visually sit on top.
	   This is what lets a corner-drag's page curl bleed consistently
	   over the entire toolbar underneath. */
	z-index: 1;
	width: 100%;
	/* Deliberately not clipped: StPageFlip's own soft-page turn shadow
	   (.stf__outerShadow/.stf__innerShadow, drawn by drawOuterShadow()/
	   drawInnerShadow() in page-flip.browser.js) is sized taller than
	   the page itself (height: 2 * pageHeight) and rotated to the
	   current fold angle, specifically so it can fade out past the
	   page's own edge for a realistic dog-ear curl during an extreme
	   corner drag — an overflow:hidden here clips that curl flat at the
	   page boundary instead of letting it bleed. Nothing else in this
	   viewer depends on stage clipping: the cover-centering slide
	   (setCoverShift() in the JS) never paints anything past pfWrap's
	   own footprint even unclipped, since only the active half of a
	   lone-cover spread is ever drawn. Trade-off if you ever want it
	   back: an extreme drag can now bleed sideways into whatever
	   content sits beside the widget, not just vertically.  */
	display: flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	box-sizing: border-box;
	padding: 0 45px;
	min-height: 200px;
}

.wahnsinn-flipbook-pf__navbtn {
	position: absolute;
	top: 50%;
	transform: translateY(-50%);
	background: transparent;
	border: none;
	padding: 10px;
	margin: 0;
	font-size: 48px;
	line-height: 1;
	color: #000;
	opacity: 0.3;
	cursor: pointer;
	transition: opacity 0.15s ease;
	z-index: 5;
}

.wahnsinn-flipbook-pf__navbtn:hover {
	opacity: 0.7;
	background: transparent;
}

.wahnsinn-flipbook-pf__navbtn:disabled {
	opacity: 0.1;
	cursor: default;
}

.wahnsinn-flipbook-pf__prev {
	left: 2px;
}

.wahnsinn-flipbook-pf__next {
	right: 2px;
}

/* The element StPageFlip is constructed against (wahnsinn-flipbook-pf__pf
   below) always renders at 100% of *this* wrap — rebuildFlip() in the JS
   reads this element's clientWidth as the basis for its single/double-
   mode math, and in fullscreen sets an explicit (not max-) height
   directly, the one clean lever for steering StPageFlip's layout without
   fighting its own container-width-driven auto-switch. It's also the
   element setCoverShift() (in the JS) applies its translateX to, for
   centering a lone front/back cover on the stage and sliding it back to
   flush as it opens/closes — deliberately not pfEl/.stf__parent, which
   already carries its own load-bearing transform below. Tune the two
   custom properties here to change the slide's feel; nothing else about
   it lives in the JS. */
.wahnsinn-flipbook-pf__pfwrap {
	width: 100%;
	--wahnsinn-flipbook-pf-cover-slide-duration: 700ms;
	--wahnsinn-flipbook-pf-cover-slide-easing: ease-in-out;
	transition: transform var(--wahnsinn-flipbook-pf-cover-slide-duration) var(--wahnsinn-flipbook-pf-cover-slide-easing);
}

/* Single-page mode only — the opposite call from __stage's own "don't
   clip" comment above. Clips flush on all four sides to pfEl's own box,
   which in single mode is exactly the page's own width/height, so a
   turning page's curl/shadow/fold never bleeds past the page's real
   edge, in fullscreen or normal view.
   On pfEl (.wahnsinn-flipbook-pf__pf), not pfWrap: in fullscreen, pfWrap
   stays the full wide stage width regardless of the actual page size,
   while pfEl tracks the real single-page width exactly (see
   rebuildFlip()'s own comment on the explicit width/max-width override
   for fullscreen single mode) — clipping at pfWrap's edges would leave a
   wide, unclipped gap for the page to bleed into. Outside fullscreen
   this is a no-op distinction: pfEl already equals pfWrap's width there.
   Toggled via __pfwrap--single, set in rebuildFlip() off effectiveMode()
   rather than state.mode directly, since single-page mode can also be
   reached by a plain viewport resize crossing the mobile breakpoint. */
.wahnsinn-flipbook-pf__pfwrap--single .wahnsinn-flipbook-pf__pf {
	clip-path: inset( 0 );
}

/* pfEl itself — width:100% of pfwrap above comes for free (block
   elements default to filling their parent's width), but height does
   NOT have an equivalent default, so without this rule pfEl renders at
   its own unconstrained natural height regardless of what pfWrap is
   capped to. That's what broke fullscreen auto-fit: StPageFlip's
   height math (getBlockHeight() in page-flip.browser.js) measures
   .stf__block, which is height:100% of pfEl — so pfEl needs its own
   height tied to pfWrap for that measurement to ever see pfWrap's
   fullscreen-computed height at all. Resolves to plain auto outside
   fullscreen, when pfWrap's own height is unset (percentage heights
   need a definite parent height to resolve against) — this rule is a
   no-op until rebuildFlip() gives pfWrap an explicit height. */
.wahnsinn-flipbook-pf__pf {
	height: 100%;
	/* margin:0 auto — a no-op everywhere pfEl is exactly 100% of pfWrap's
	   width, but load-bearing in fullscreen double mode: StPageFlip's
	   "fixed" size sets its own inline max-width on this element, tightly
	   wrapping it to 2x the configured page width — narrower than pfWrap
	   whenever the book is height- rather than width-constrained to the
	   fullscreen viewport. A block element narrower than its parent
	   defaults to flush-left otherwise (StPageFlip's own internal
	   centering only centers the book within this element's own box, not
	   this element within pfWrap). Auto-margins center it whenever it's
	   narrower than its container, and do nothing when it already fills
	   100% width. */
	margin: 0 auto;
}

.wahnsinn-flipbook-pf__loading {
	color: #555;
	padding: 3em 1em;
	text-align: center;
}

@media (max-width: 700px) {
	.wahnsinn-flipbook-pf__more-pagemode {
		display: none;
	}
}

/* ---- StPageFlip's own required structural CSS (vendor, copied
   near-verbatim from page-flip's src/Style/stPageFlip.css — the
   .stf__/.sft__ class names and behavior are the library's own
   contract, don't rename or "clean up" typos like sft__ vs stf__,
   they're load-bearing exactly as shipped) ---- */

.stf__parent {
	position: relative;
	display: block;
	box-sizing: border-box;
	transform: translateZ(0);
	-ms-touch-action: pan-y;
	touch-action: pan-y;
}

.sft__wrapper {
	position: relative;
	width: 100%;
	box-sizing: border-box;
}

/* Our own override, not vendor: StPageFlip's own autoSize setting
   (default true, left on) gives .sft__wrapper its height via an old
   padding-bottom aspect-ratio hack, computed as a percentage of its own
   width (100% of pfEl, i.e. the full wide fullscreen stage — not the
   actual book size). Outside fullscreen this is the only thing giving
   the book real height, since pfWrap has no explicit height of its own
   there, so it's left alone. In fullscreen there's already a real,
   definite height to hand down directly (pfWrap's own explicit JS-set
   height, cascaded through .wahnsinn-flipbook-pf__pf's height:100%) —
   scoped to :fullscreen so it overrides the width-derived padding-bottom
   guess only where a better answer actually exists. */
.wahnsinn-flipbook-pf:fullscreen .sft__wrapper {
	height: 100%;
}

.stf__parent canvas {
	position: absolute;
	width: 100%;
	height: 100%;
	left: 0;
	top: 0;
}

.stf__block {
	position: absolute;
	width: 100%;
	height: 100%;
	box-sizing: border-box;
	perspective: 2000px;
}

.stf__item {
	display: none;
	position: absolute;
	transform-style: preserve-3d;
}

.stf__outerShadow,
.stf__innerShadow,
.stf__hardShadow,
.stf__hardInnerShadow {
	position: absolute;
	left: 0;
	top: 0;
}

/* ---- Our own override, not vendor: suppresses the dark gradient
   StPageFlip fades in beside the front/back cover as it opens/closes.
   That's .stf__hardShadow/.stf__hardInnerShadow specifically — a
   separate mechanism (drawHardOuterShadow()/drawHardInnerShadow() in
   page-flip.browser.js) from .stf__outerShadow/.stf__innerShadow above,
   which still shadow ordinary interior page turns and are left alone.
   StPageFlip sets these two via inline style on every animation frame,
   so !important is required to win. To bring the cover shadow back,
   delete this rule — no JS change needed (drawShadow/maxShadowOpacity in
   the JS's PageFlip config govern both kinds together, so turning them
   off there would also remove the interior-page shadow). */
.wahnsinn-flipbook-pf .stf__hardShadow,
.wahnsinn-flipbook-pf .stf__hardInnerShadow {
	display: none !important;
}

/* ---- Our own page content ----
   This element IS the .stf__item — the exact <div> from state.pageEls
   handed to loadFromHTML() — StPageFlip adds its own stf__item/--soft/
   is-rendered/--left/--right/--simple classes and an inline style
   (position/display/height/width/left/top/z-index, or a transform for
   the actively flipping page) directly onto it, rather than wrapping it.
   That inline style gets fully rewritten whenever a flip starts, so
   anything that must persist through a flip in progress needs a class
   rule here instead, never this element's own inline style from the JS.
   Our canvas (position:absolute — the vendor ".stf__parent canvas" rule
   above already covers it, its own inline pixel width/height from
   renderPageInto() wins over that rule's width:100%/height:100% since
   inline styles beat plain class rules) and PDF.js's .textLayer (also
   position:absolute; inset:0, from its own rule below) size against
   this element's box. line-height:0 avoids the usual few pixels of
   inline-baseline whitespace a canvas/img otherwise leaves under itself
   in normal flow. */
.wahnsinn-flipbook-pf__page {
	position: relative;
	width: 100%;
	height: 100%;
	background: var(--wahnsinn-flipbook-pf-page-bg);
	box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
	box-sizing: border-box;
	line-height: 0;
}

/* ---- PDF.js TextLayer (copied from PDF.js's own pdf_viewer.css,
   identical to the sibling file's copy — see that file's own comment) ---- */

.textLayer {
	color-scheme: only light;
	position: absolute;
	text-align: initial;
	inset: 0;
	overflow: clip;
	opacity: 1;
	line-height: 1;
	letter-spacing: normal;
	word-spacing: normal;
	-webkit-text-size-adjust: none;
	-moz-text-size-adjust: none;
	text-size-adjust: none;
	forced-color-adjust: none;
	transform-origin: 0 0;
	caret-color: CanvasText;
	z-index: 1;
}

.textLayer.highlighting {
	touch-action: none;
}

.textLayer span,
.textLayer br {
	color: transparent;
	position: absolute;
	white-space: pre;
	cursor: text;
	transform-origin: 0% 0%;
	-webkit-user-select: text;
	-moz-user-select: text;
	user-select: text;
}

.textLayer {
	--min-font-size: 1;
	--text-scale-factor: calc(var(--total-scale-factor) * var(--min-font-size));
	--min-font-size-inv: calc(1 / var(--min-font-size));
}

.textLayer > :not(.markedContent),
.textLayer .markedContent span:not(.markedContent) {
	z-index: 1;
	--font-height: 0;
	font-size: calc(var(--text-scale-factor) * var(--font-height));
	--scale-x: 1;
	--rotate: 0deg;
	transform: rotate(var(--rotate)) scaleX(var(--scale-x)) scale(var(--min-font-size-inv));
}

.textLayer .markedContent {
	display: contents;
}

.textLayer span[role="img"] {
	-webkit-user-select: none;
	-moz-user-select: none;
	user-select: none;
	cursor: default;
}

.textLayer .endOfContent {
	display: block;
	position: absolute;
	inset: 100% 0 0;
	z-index: 0;
	cursor: default;
	-webkit-user-select: none;
	-moz-user-select: none;
	user-select: none;
}

.textLayer.selecting .endOfContent {
	top: 0;
}
