/* Minimal, functional styling only - intentionally undecorated. Brandon:
   swap in real branding via BRAND_PRIMARY_COLOR/SITE_LOGO_URL and whatever
   design language this client/deployment needs. */

:root {
	--brand: #0b3f2a;
	--ink: #152238;
	--muted: #657084;
	--bg: #f8f5ec;
	--border: #d8dbe2;
}

* { box-sizing: border-box; }

.site-header {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: 16px;
	max-width: 640px;
	margin: 0 auto;
	padding-top: 16px;
}
.site-branding { text-align: center; }
.site-logo { max-height: 100px; display: block; margin: 0 auto; }
.site-welcome { font-size: 1.3rem; font-weight: 700; margin: 0; }

/* Login pages only (index.html, admin/login.html). The logo/welcome header
   stays at the top like every other page; auto margins on .gate-screen push
   just the login box down into the center of the remaining space below it.
   Scoped to this class rather than a bare `body` rule so it doesn't affect
   the modules/player/admin-dashboard pages sharing this stylesheet. */
body.login-page {
	min-height: 100vh;
	display: flex;
	flex-direction: column;
}
.login-page .gate-screen {
	margin-top: auto;
	margin-bottom: auto;
}

body {
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
	background: var(--bg);
	color: var(--ink);
	margin: 0;
	padding: 24px;
}

h1 { margin-top: 0; }

form { display: flex; flex-direction: column; gap: 8px; max-width: 360px; margin: 16px 0; }

input {
	padding: 10px 12px;
	border: 1px solid var(--border);
	border-radius: 8px;
	font-size: 1rem;
}

button {
	padding: 10px 16px;
	border: none;
	border-radius: 999px;
	background: var(--brand);
	color: #fff;
	font-weight: 700;
	cursor: pointer;
}

button:disabled { opacity: 0.5; cursor: default; }

.gate-screen, .modules-screen, .player-screen {
	max-width: 640px;
	margin: 0 auto;
}

.gate-divider { color: var(--muted); text-align: center; }

#gate-message.is-error, #unlock-message.is-error { color: #b3261e; }

/* Free-preview page (preview.html) */
#preview-message.is-error { color: #b3261e; }
.preview-eyebrow { color: var(--brand); font-weight: 700; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.04em; margin: 0 0 4px; }
.consent-notice { color: var(--muted); font-size: 0.85rem; margin: 8px 0 0; }
.consent-checkbox { font-weight: 400; font-size: 0.9rem; align-items: flex-start; margin-top: 8px; }
.consent-checkbox input { margin-top: 3px; }
.turnstile-box { margin: 12px 0 4px; min-height: 0; }
.preview-signin { margin-top: 24px; font-size: 0.9rem; }
.hp-field { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }

.module-list { list-style: none; padding: 0; }
.module-list li {
	border: 1px solid var(--border);
	border-radius: 12px;
	padding: 16px;
	margin-bottom: 12px;
	background: #fff;
}
.module-list a { text-decoration: none; color: var(--ink); display: flex; justify-content: space-between; }
.module-status { color: var(--muted); font-size: 0.85rem; }

.back-link { display: inline-block; margin-bottom: 16px; color: var(--muted); }

.preview-banner {
	background: #fff3cd;
	border: 1px solid #e0c36c;
	color: #6b5300;
	border-radius: 8px;
	padding: 10px 14px;
	margin-bottom: 12px;
	font-size: 0.9rem;
}

.preview-link {
	display: inline-block;
	margin: 0 0 12px;
	color: var(--brand);
}

.slide-stage { position: relative; }
.slides-audio-player .slide-image {
	max-width: 100%;
	border-radius: 12px;
	display: block;
	margin: 0 auto;
}
.slide-controls {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	margin-top: 12px;
}
/* Overlays the slide image itself (video-player-style centered play
   button) instead of sitting as its own block below it - frees up the
   space it used to take between the image and the controls/legend below. */
.manual-play {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	max-width: calc(100% - 24px);
	margin: 0;
	padding: 14px 28px;
	border: none;
	border-radius: 999px;
	background: rgba(0, 0, 0, 0.65);
	color: #fff;
	font-size: 1rem;
	font-weight: bold;
	cursor: pointer;
	box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}
.manual-play:hover { background: rgba(0, 0, 0, 0.8); }

/* Both hints grouped into one legend, visually separated from the
   Previous/Next controls by a hairline. Row layout with generous gap so
   they read as one line with room to breathe, wrapping onto two lines
   only if the viewport is too narrow to fit both. */
.player-hints {
	margin-top: 14px;
	padding-top: 10px;
	border-top: 1px solid var(--border);
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: 10px 32px;
}
.fullscreen-hint { color: var(--muted); font-size: 0.8rem; margin: 0; }
.fullscreen-hint kbd,
.nav-hint kbd {
	font-family: inherit;
	background: #fff;
	border: 1px solid var(--border);
	border-radius: 4px;
	padding: 2px 8px;
	margin: 0 2px;
}
.nav-hint { color: var(--muted); font-size: 0.85rem; margin: 0; font-weight: bold; }

/* :fullscreen targets the element requestFullscreen() was called on
   (.slides-audio-player itself) - without this, the browser just centers
   the un-styled element in a small island of black, which looks broken
   rather than like an actual fullscreen presentation. Per spec: only the
   slide image is visible, filling the screen edge to edge - title and
   navigation are fully hidden (arrow keys/swipe still work with nothing
   visible for them, matching this player's existing keyboard/touch nav). */
.slides-audio-player:fullscreen {
	display: block;
	width: 100vw;
	height: 100vh;
	margin: 0;
	background: #000;
	padding: 0;
}
.slides-audio-player:fullscreen h1,
.slides-audio-player:fullscreen .slide-controls,
.slides-audio-player:fullscreen .manual-play,
.slides-audio-player:fullscreen .player-hints {
	opacity: 0;
	pointer-events: none;
	position: absolute;
	transition: opacity 0.2s ease;
}
.slides-audio-player:fullscreen .slide-image {
	width: 100vw;
	height: 100vh;
	max-width: none;
	max-height: none;
	object-fit: contain;
	border-radius: 0;
	margin: 0;
}

/* Mouse-only edge nav for fullscreen (requested by Pat, who navigates with
   a mouse rather than a keyboard or touch swipe) - invisible/inert outside
   fullscreen entirely (arrow keys/swipe/Escape are the only fullscreen nav
   otherwise, none of them discoverable to a mouse-only user). Faded by
   default, shown on mouse movement and re-hidden after a couple of seconds
   of no movement (JS in slides-audio.js) - pointer-events off while faded
   so an invisible edge zone never blocks a click/tap meant for something
   else. */
.fullscreen-nav { display: none; }
.slides-audio-player:fullscreen .fullscreen-nav {
	display: flex;
	align-items: center;
	position: fixed;
	top: 0;
	bottom: 0;
	width: 12%;
	min-width: 56px;
	max-width: 140px;
	margin: 0;
	appearance: none;
	-webkit-appearance: none;
	border: none;
	border-radius: 0;
	background-color: transparent;
	box-shadow: none;
	color: #fff;
	font-size: 3rem;
	line-height: 1;
	cursor: pointer;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.3s ease;
	z-index: 1;
}
.slides-audio-player:fullscreen .fullscreen-nav.is-visible {
	opacity: 1;
	pointer-events: auto;
}
.slides-audio-player:fullscreen .fullscreen-nav:disabled {
	opacity: 0 !important;
	pointer-events: none !important;
	cursor: default;
}
.slides-audio-player:fullscreen .fullscreen-nav-prev {
	left: 0;
	justify-content: flex-start;
	padding: 0 0 0 16px;
	background: linear-gradient(to right, rgba(0, 0, 0, 0.35), transparent);
}
.slides-audio-player:fullscreen .fullscreen-nav-next {
	right: 0;
	justify-content: flex-end;
	padding: 0 16px 0 0;
	background: linear-gradient(to left, rgba(0, 0, 0, 0.35), transparent);
}

.video-player video { width: 100%; display: block; }
.video-stage { position: relative; margin-top: 12px; background: #000; border-radius: 12px; overflow: hidden; }
.video-stage video { cursor: pointer; }
.video-stage:fullscreen { display: flex; align-items: center; justify-content: center; margin: 0; border-radius: 0; }
.video-stage:fullscreen video { height: 100%; object-fit: contain; }
.audio-only-player .artwork { max-width: 100%; border-radius: 12px; }

/* Shared transport bar (assets/js/transport.js) used by all three players.
   Overlay mode sits over the bottom of the slide/video and is hidden until
   the mouse moves over it (.is-visible, toggled in JS, fades out again
   after a couple of idle seconds); pointer-events are off while hidden so
   the invisible bar never swallows a click meant for the picture below.
   Plain mode (audio-only) is just an always-visible row. */
.transport {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-top: 12px;
}
.transport--overlay {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	margin: 0;
	padding: 36px 14px 12px;
	background: linear-gradient(to top, rgba(0, 0, 0, 0.75), transparent);
	color: #fff;
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.25s ease;
	z-index: 2;
}
.transport--overlay.is-visible { opacity: 1; pointer-events: auto; }

.t-btn {
	appearance: none;
	-webkit-appearance: none;
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 3px;
	min-width: 40px;
	height: 40px;
	margin: 0;
	padding: 0 12px;
	border: none;
	border-radius: 999px;
	background: var(--brand);
	color: #fff;
	font-size: 1.05rem;
	line-height: 1;
	cursor: pointer;
	flex: none;
}
.transport--overlay .t-btn { background: rgba(255, 255, 255, 0.2); }
.t-btn:hover:not(:disabled) { filter: brightness(1.25); }
.t-btn:disabled { opacity: 0.4; cursor: default; }
.t-sec { font-size: 0.7rem; font-weight: bold; }

/* Hover/focus tooltip naming the action and its keyboard key. The first
   and last buttons anchor to their own edge instead of centering, so the
   tooltip can't spill off the left/right side of a narrow screen. */
.t-btn::after {
	content: attr(data-tip);
	position: absolute;
	bottom: calc(100% + 8px);
	left: 50%;
	transform: translateX(-50%);
	white-space: nowrap;
	padding: 5px 10px;
	border-radius: 6px;
	background: #111;
	color: #fff;
	font-size: 0.78rem;
	font-weight: normal;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
	opacity: 0;
	pointer-events: none;
	transition: opacity 0.15s ease;
}
.t-btn:hover::after, .t-btn:focus-visible::after { opacity: 1; }
.t-back::after { left: 0; transform: none; }
.t-fs::after, .t-speed::after { left: auto; right: 0; transform: none; }

/* Playback speed: the button shows the current rate; the menu pops up above it.
   Dark popover in both bar modes so it reads over a slide, a video or the page. */
.t-speed-wrap { position: relative; flex: none; }
.t-speed { font-size: 0.85rem; font-weight: bold; font-variant-numeric: tabular-nums; }
.t-speed[aria-expanded="true"]::after { display: none; }
.t-speed-menu {
	position: absolute;
	right: 0;
	bottom: calc(100% + 8px);
	display: flex;
	flex-direction: column;
	min-width: 76px;
	padding: 4px;
	border-radius: 8px;
	background: #111;
	box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
	z-index: 3;
}
.t-speed-menu[hidden] { display: none; }
.t-speed-menu--down { bottom: auto; top: calc(100% + 8px); }
.t-speed-opt {
	appearance: none;
	-webkit-appearance: none;
	margin: 0;
	padding: 7px 14px;
	border: none;
	border-radius: 5px;
	background: transparent;
	color: #fff;
	font-size: 0.85rem;
	text-align: left;
	cursor: pointer;
}
.t-speed-opt:hover, .t-speed-opt:focus-visible { background: rgba(255, 255, 255, 0.18); }
.t-speed-opt[aria-checked="true"] { background: var(--brand-accent, #3fbf88); color: #000; font-weight: bold; }

.t-time { font-size: 0.8rem; font-variant-numeric: tabular-nums; min-width: 2.6em; flex: none; }
.transport:not(.transport--overlay) .t-time { color: var(--muted); }

.t-seek {
	--pct: 0%;
	flex: 1;
	min-width: 0;
	height: 6px;
	margin: 0;
	padding: 0;
	border: none;
	max-width: none;
	border-radius: 3px;
	appearance: none;
	-webkit-appearance: none;
	background: linear-gradient(to right, var(--brand-accent, #3fbf88) var(--pct), rgba(128, 128, 128, 0.45) var(--pct));
	cursor: pointer;
}
.t-seek:disabled { opacity: 0.4; cursor: default; }
.t-seek::-webkit-slider-thumb {
	-webkit-appearance: none;
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: #fff;
	border: 2px solid var(--brand);
}
.t-seek::-moz-range-thumb {
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: #fff;
	border: 2px solid var(--brand);
}

/* Fullscreen slides: the bar is anchored to the screen's bottom edge. */
.slides-audio-player:fullscreen .transport--overlay { position: fixed; }

@media (max-width: 520px) {
	.t-time { display: none; }
	.t-btn { min-width: 36px; height: 36px; padding: 0 9px; }
}

/* Two-column layout when a module has downloadable attachments - the
   presentation/player on one side, a dedicated Resources card on the
   other, instead of the resource list sitting below the player. Only
   applied when player.js finds attachments to show (see .has-sidebar). */
.player-screen.has-sidebar { max-width: 960px; }
.player-layout {
	display: grid;
	grid-template-columns: 1fr 260px;
	gap: 24px;
	align-items: start;
}
.player-main { min-width: 0; }
.attachments-card {
	border: 1px solid var(--border);
	border-radius: 12px;
	padding: 16px;
	background: #fff;
	box-shadow: 0 4px 14px rgba(21, 34, 56, 0.08);
}
.attachments-card h2 { margin-top: 0; font-size: 1.05rem; }
.attachments-card p { color: var(--muted); font-size: 0.9rem; }
.attachments-card ul { padding-left: 20px; margin: 8px 0 0; }
@media (max-width: 720px) {
	.player-layout { grid-template-columns: 1fr; }
}

/* Bookmarks card (assets/js/bookmarks.js). Above the player when the module has no Resources sidebar,
   under the Resources card when it does (.in-sidebar). */
.bookmarks-card {
	border: 1px solid var(--border);
	border-radius: 12px;
	padding: 12px 16px;
	margin-bottom: 16px;
	background: #fff;
	box-shadow: 0 4px 14px rgba(21, 34, 56, 0.08);
}
.bookmarks-card.in-sidebar { margin: 16px 0 0; }
.bookmark-add { padding: 8px 14px; font-size: 0.9rem; }
.bookmark-add kbd {
	font-family: inherit;
	font-size: 0.78rem;
	margin-left: 6px;
	padding: 0 6px;
	border: 1px solid rgba(255, 255, 255, 0.6);
	border-radius: 4px;
}
.bookmark-status { min-height: 1.3em; margin: 6px 0 0; color: var(--muted); font-size: 0.85rem; }
.bookmark-details summary { cursor: pointer; font-weight: 700; }
.bookmark-count { color: var(--muted); font-weight: normal; }
.bookmark-list { list-style: none; padding: 0; margin: 8px 0 0; }
.bookmark-list li { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; padding: 7px 0; border-top: 1px solid var(--border); }
.bookmark-go {
	appearance: none;
	-webkit-appearance: none;
	padding: 2px 0;
	border-radius: 0;
	background: none;
	color: var(--brand);
	text-align: left;
	text-decoration: underline;
}
.bookmark-note { flex: 1 1 120px; min-width: 0; overflow-wrap: anywhere; font-size: 0.9rem; }
.bookmark-edit {
	margin-left: auto;
	padding: 2px 10px;
	border: 1px solid var(--border);
	background: none;
	color: var(--muted);
	font-size: 0.78rem;
	font-weight: normal;
}
.bookmark-del { padding: 0 8px; background: none; color: var(--muted); font-size: 1.25rem; line-height: 1.2; }
.bookmark-note-input { flex: 1 1 140px; min-width: 0; padding: 5px 8px; font-size: 0.9rem; }
.bookmark-empty { margin: 8px 0 0; color: var(--muted); font-size: 0.9rem; }
.bookmark-empty kbd { font-family: inherit; padding: 0 6px; border: 1px solid var(--border); border-radius: 4px; background: #fff; }

.admin-screen { max-width: 720px; margin: 0 auto; }
.admin-header { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px; }
.button-link {
	display: inline-block;
	padding: 8px 16px;
	border-radius: 999px;
	background: var(--brand);
	color: #fff;
	text-decoration: none;
	font-weight: 700;
	margin-right: 8px;
}
.admin-table { width: 100%; border-collapse: collapse; margin-top: 16px; }
.admin-table th, .admin-table td { text-align: left; padding: 10px; border-bottom: 1px solid var(--border); }
.admin-table .delete-btn { background: none; border: 1px solid var(--border); color: #b3261e; border-radius: 6px; padding: 4px 10px; margin-left: 8px; cursor: pointer; }
.admin-table .restore-btn { margin-left: 8px; }
.admin-table .restore-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.restore-ack { display: block; margin-top: 12px; font-size: 0.9rem; color: var(--muted); }
.restore-ack input { margin-right: 6px; }

textarea { padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; font: inherit; max-width: 360px; }

fieldset { border: 1px solid var(--border); border-radius: 8px; margin: 16px 0; }
legend { padding: 0 6px; color: var(--muted); font-size: 0.85rem; }

.product-ref-row, .slide-row, .attachment-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	border: 1px solid var(--border);
	border-radius: 8px;
	padding: 12px;
	margin-bottom: 8px;
}
.slide-row { flex-direction: column; align-items: stretch; padding: 0; overflow: hidden; }
.slide-row strong { font-size: 0.9rem; color: var(--muted); }

.slide-row-header {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 10px 12px;
	background: var(--bg);
}
.slide-drag-handle {
	cursor: grab;
	font-size: 1.1rem;
	color: var(--muted);
	line-height: 1;
	padding: 4px;
	touch-action: none;
}
.slide-row.is-dragging { opacity: 0.4; }
.slide-row.drag-over { outline: 2px dashed var(--brand); outline-offset: -2px; }
.slide-collapse-toggle {
	background: none;
	border: none;
	cursor: pointer;
	font-size: 0.9rem;
	color: var(--muted);
	padding: 2px 4px;
	flex: none;
}
.slide-row-title {
	flex: 1;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.slide-row-actions { display: flex; gap: 6px; flex: none; }
.slide-row-actions button { flex: none; }
.slide-row-body { padding: 4px 12px 12px; display: flex; flex-direction: column; gap: 4px; }
.slide-row-body[hidden] { display: none; }

.upload-status { font-size: 0.85rem; color: var(--muted); }
.upload-status.is-ok { color: var(--brand); }
.upload-status.is-error { color: #b3261e; }

.dropzone {
	border: 2px dashed var(--border);
	border-radius: 12px;
	padding: 24px;
	text-align: center;
	background: #fff;
	margin-bottom: 12px;
}
.dropzone.is-dragover { border-color: var(--brand); background: #f0f7f3; }
.dropzone p { color: var(--muted); margin-top: 0; }
.file-picker-label {
	display: inline-block;
	padding: 8px 16px;
	border-radius: 999px;
	background: var(--brand);
	color: #fff;
	font-weight: 700;
	cursor: pointer;
	margin: 4px 6px;
}

.batch-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	border: 1px solid var(--border);
	border-radius: 8px;
	padding: 12px;
	margin-bottom: 8px;
	background: #fff;
}
.batch-file-name { font-size: 0.85rem; color: var(--muted); }
progress { width: 100px; height: 8px; }

.fallback-uploader { margin-top: 16px; }
.fallback-uploader summary { cursor: pointer; color: var(--muted); font-size: 0.9rem; }
#toggle-all-slides { display: block; margin: 8px 0; }

#assets-section h2 { margin-top: 32px; font-size: 1.1rem; }

/* Document (PDF) player - public/adapters/document.js. Pages are drawn onto
   canvases (inside a page-sized .doc-sheet) with an invisible PDF.js text layer on
   top for selection/search. The .textLayer rules below are the minimal subset of
   PDF.js's own pdf_viewer.css (v6.3.289) that the text layer needs; that stylesheet
   is 6,000+ lines of full-viewer UI with :root overrides, so it isn't loaded. */
.player-screen.has-document { max-width: 960px; }
.checkbox-row { display: flex; align-items: center; gap: 8px; margin-top: 16px; font-weight: 600; }
.checkbox-row input { width: auto; margin: 0; }
.field-hint { color: var(--muted); font-size: 0.85rem; margin: 4px 0 0; }

.document-player { margin-top: 12px; }
.document-player:focus { outline: none; }
.doc-toolbar {
	position: sticky;
	top: 0;
	z-index: 5;
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px;
	padding: 8px 12px;
	background: #fff;
	border: 1px solid var(--border);
	border-radius: 10px;
}
.doc-toolbar[hidden] { display: none; }
.doc-toolbar button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 40px;
	min-height: 40px;
	padding: 0 8px;
	border: 1px solid var(--border);
	border-radius: 8px;
	background: #fff;
	color: var(--ink);
	cursor: pointer;
}
.doc-toolbar button:hover { border-color: var(--brand); color: var(--brand); }
.doc-toolbar svg { display: block; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.doc-zoom { display: inline-flex; align-items: center; gap: 4px; }
.doc-zoom .doc-zoom-level { min-width: 64px; font: inherit; font-size: 0.9rem; font-weight: 600; }
.doc-toolbar button:disabled { opacity: 0.35; cursor: default; }
.doc-toolbar button:disabled:hover { border-color: var(--border); color: var(--ink); }
.doc-fullscreen .icon-exit { display: none; }
.is-fullscreen .doc-fullscreen .icon-enter { display: none; }
.is-fullscreen .doc-fullscreen .icon-exit { display: inline-flex; }
.doc-pageinfo { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); }
.doc-page-input { width: 4.5em; min-height: 40px; text-align: center; }
.doc-download { margin-left: auto; font-weight: 600; }
.doc-status { padding: 24px 0; color: var(--muted); text-align: center; }
.doc-status.is-error { color: #b3261e; }
.document-empty { color: var(--muted); }
.doc-pages { margin-top: 12px; overflow-x: auto; }
.doc-page {
	position: relative;
	margin: 0 auto 12px;
	scroll-margin-top: 64px; /* clears the sticky toolbar when jumping to a page */
	color: var(--muted);
}
.doc-page:empty { background: #fff; box-shadow: 0 0 0 1px var(--border), 0 1px 4px rgba(0, 0, 0, 0.08); }
.doc-sheet {
	position: relative;
	margin: 0 auto;
	background: #fff;
	box-shadow: 0 0 0 1px var(--border), 0 1px 4px rgba(0, 0, 0, 0.08);
	overflow: hidden;
}
.doc-sheet canvas { display: block; }
.doc-counter { display: none; }

.doc-sheet .textLayer {
	position: absolute;
	inset: 0;
	overflow: clip;
	line-height: 1;
	text-align: initial;
	transform-origin: 0 0;
	-webkit-text-size-adjust: none;
	text-size-adjust: none;
	--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));
}
.doc-sheet .textLayer :is(span, br) {
	color: transparent;
	position: absolute;
	white-space: pre;
	cursor: text;
	transform-origin: 0% 0%;
}
.doc-sheet .textLayer > :not(.markedContent),
.doc-sheet .textLayer .markedContent span:not(.markedContent) {
	--font-height: 0;
	--scale-x: 1;
	--rotate: 0deg;
	font-size: calc(var(--text-scale-factor) * var(--font-height));
	transform: rotate(var(--rotate)) scaleX(var(--scale-x)) scale(var(--min-font-size-inv));
}
.doc-sheet .textLayer .markedContent { display: contents; }
.doc-sheet .textLayer ::selection { background: rgba(0, 0, 255, 0.25); color: transparent; }
.doc-sheet .textLayer .endOfContent { display: block; position: absolute; inset: 100% 0 0; user-select: none; }
.doc-sheet .textLayer.selecting .endOfContent { top: 0; }

/* Full screen (Fullscreen API, or the full-window fallback): one page per screen,
   fitted to the display, snapping page to page; the controls fade out when idle. */
.document-player.is-fullscreen {
	position: fixed;
	inset: 0;
	z-index: 2000;
	margin: 0;
	background: #111;
	overflow-x: hidden;
	overflow-y: auto;
	scroll-snap-type: y mandatory;
	overscroll-behavior: contain;
}
.is-fullscreen .doc-pages { margin: 0; overflow: visible; }
.document-player.is-fullscreen.is-zoomed { overflow: auto; scroll-snap-type: none; }
/* Pages of different shapes have different widths when fitted and zoomed. Make the scrolling area as wide as the
   widest page and centre every page on the same axis; otherwise narrower pages sit left-aligned in it. */
.is-fullscreen.is-zoomed .doc-pages { display: flex; flex-direction: column; align-items: center; width: max-content; min-width: 100%; }
.is-fullscreen.is-zoomed .doc-page { flex: none; }
.is-fullscreen .doc-page {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: var(--slot-h, 100vh);
	margin: 0;
	scroll-snap-align: start;
	scroll-margin-top: 0;
}
.is-fullscreen .doc-page:empty { background: none; box-shadow: none; }
.is-fullscreen .doc-sheet { margin: 0; box-shadow: 0 2px 18px rgba(0, 0, 0, 0.6); }
.is-fullscreen .doc-status { color: #ccc; }
.is-fullscreen .doc-toolbar {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	border: 0;
	border-radius: 0;
	background: rgba(20, 20, 20, 0.88);
	color: #fff;
	opacity: 0;
	transform: translateY(-8px);
	pointer-events: none;
	transition: opacity 0.2s, transform 0.2s;
}
.is-fullscreen.ui-active .doc-toolbar { opacity: 1; transform: none; pointer-events: auto; }
.is-fullscreen .doc-toolbar button { background: transparent; color: #fff; border-color: rgba(255, 255, 255, 0.35); }
.is-fullscreen .doc-toolbar button:hover { border-color: #fff; color: #fff; }
.is-fullscreen .doc-toolbar button:disabled:hover { border-color: rgba(255, 255, 255, 0.35); color: #fff; }
.is-fullscreen .doc-pageinfo { color: #ddd; }
.is-fullscreen .doc-download { color: #9cf; }
.is-fullscreen .doc-counter {
	display: block;
	position: fixed;
	right: 14px;
	bottom: 10px;
	padding: 2px 10px;
	border-radius: 12px;
	background: rgba(0, 0, 0, 0.55);
	color: #ddd;
	font-size: 0.85rem;
	pointer-events: none;
}
html.doc-fullwindow, html.doc-fullwindow body { overflow: hidden; }
@media (prefers-reduced-motion: reduce) { .is-fullscreen .doc-toolbar { transition: none; } }

/* View-only: no selecting, no printing. Friction only - see document.js. */
.document-player.no-download .doc-page,
.document-player.no-download .textLayer { -webkit-user-select: none; user-select: none; }
@media print { .document-player.no-download { display: none; } }

/* Admin -> Settings */
.settings-form { max-width: 560px; }
.settings-form fieldset { padding: 12px 16px 16px; }
.settings-form legend { font-weight: 700; padding: 0 6px; }
.settings-form select, .settings-form textarea { padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px; font-size: 1rem; font-family: inherit; }
.secret-row { display: flex; gap: 8px; }
.secret-row input { flex: 1 1 auto; min-width: 0; }
.secret-clear { background: none; color: var(--muted); border: 1px solid var(--border); font-weight: normal; }
#kit-message.is-error, #settings-message.is-error { color: #b3261e; }

/* Bookmark confirmation shown over a full-screen player (the card itself is off-screen then) */
.bookmark-toast { position: fixed; left: 50%; bottom: 72px; transform: translateX(-50%); max-width: 80%; z-index: 2100; padding: 8px 16px; border-radius: 999px; background: rgba(0, 0, 0, 0.78); color: #fff; font-size: 0.95rem; pointer-events: none; text-align: center; }
