diff --git a/cds/modules/records/static/templates/cds_records/video/detail.html b/cds/modules/records/static/templates/cds_records/video/detail.html
index c5ebe4ed6..33c5bc61c 100644
--- a/cds/modules/records/static/templates/cds_records/video/detail.html
+++ b/cds/modules/records/static/templates/cds_records/video/detail.html
@@ -344,7 +344,7 @@
@@ -434,3 +434,42 @@
+
+
+
+
+
+
+
+
+
+
+
‹
+
+
+
![]()
+
+
+
›
+
+
+
+
{{ chapterModal.currentChapter.title }}
+
{{ chapterModal.currentChapter.timestamp }}
+
+
+
diff --git a/cds/modules/theme/assets/bootstrap3/js/cds_records/cdsRecord.js b/cds/modules/theme/assets/bootstrap3/js/cds_records/cdsRecord.js
index 1c865c8b2..6848b300d 100644
--- a/cds/modules/theme/assets/bootstrap3/js/cds_records/cdsRecord.js
+++ b/cds/modules/theme/assets/bootstrap3/js/cds_records/cdsRecord.js
@@ -64,12 +64,73 @@ function cdsRecordController($scope, $sce, $http, $timeout, $filter) {
$scope.shortDescription = "";
$scope.fullDescription = "";
$scope.chapterFrames = {};
+ $scope.chapterModal = {
+ open: false,
+ index: 0,
+ currentChapter: null,
+ currentFrameUrl: null,
+ };
const REQUEST_HEADERS = {
"Content-Type": "application/json",
"X-CSRFToken": getCookie("csrftoken"),
};
+ // Open modal at specific chapter index
+ $scope.openChapterModal = function (index) {
+ $scope.chapterModal.index = index;
+ $scope.chapterModal.open = true;
+ $scope.updateChapterModalContent();
+ };
+
+ // Close modal
+ $scope.closeChapterModal = function () {
+ $scope.chapterModal.open = false;
+ };
+
+ // Build IIIF frame URL
+ $scope.getFrameUrl = function (frame) {
+ console.log("Getting frame URL for", frame);
+ if (!frame) return null;
+ return `/api/iiif/v2/${frame.bucket_id}:${frame.version_id}:${frame.key}/full/full/0/default.jpg`;
+ };
+
+ // Update modal contents after navigation
+ $scope.updateChapterModalContent = function () {
+ const chapter = $scope.chapters[$scope.chapterModal.index];
+ const frame = $scope.chapterFrames[chapter.seconds];
+ $scope.chapterModal.currentChapter = chapter;
+ $scope.chapterModal.currentFrameUrl = $scope.getFrameUrl(frame);
+ };
+
+ // Navigation
+ $scope.nextChapter = function ($event) {
+ $event.stopPropagation(); // prevent closing modal
+ if ($scope.chapterModal.index < $scope.chapters.length - 1) {
+ $scope.chapterModal.index++;
+ $scope.updateChapterModalContent();
+ }
+ };
+
+ $scope.prevChapter = function ($event) {
+ $event.stopPropagation();
+ if ($scope.chapterModal.index > 0) {
+ $scope.chapterModal.index--;
+ $scope.updateChapterModalContent();
+ }
+ };
+
+ // Keyboard navigation for modal
+ document.addEventListener("keydown", function (e) {
+ if (!$scope.chapterModal.open) return;
+
+ if (e.key === "ArrowRight") {
+ $scope.$apply(() => $scope.nextChapter(e));
+ } else if (e.key === "ArrowLeft") {
+ $scope.$apply(() => $scope.prevChapter(e));
+ }
+ });
+
$scope.scrollToElement = function (id) {
setTimeout(function () {
const el = document.getElementById(id);
diff --git a/cds/modules/theme/assets/bootstrap3/scss/cds/cds.scss b/cds/modules/theme/assets/bootstrap3/scss/cds/cds.scss
index 28d5ec5a2..f4fecce65 100644
--- a/cds/modules/theme/assets/bootstrap3/scss/cds/cds.scss
+++ b/cds/modules/theme/assets/bootstrap3/scss/cds/cds.scss
@@ -1464,4 +1464,84 @@ div[cds-search-results] {
.sharelink-start:has(input[type="checkbox"]:checked) .start-time {
border-bottom: 1px solid #888;
color: #333333;
-}
\ No newline at end of file
+}
+
+/* Dark clickable overlay */
+.chapter-modal-overlay {
+ position: fixed;
+ inset: 0;
+ background: rgba(0,0,0,0.7);
+ z-index: 9998;
+}
+
+/* Centering container (also click-to-close) */
+.chapter-modal-container {
+ position: fixed;
+ inset: 0;
+ z-index: 9999;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.chapter-modal {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.chapter-modal-image {
+ max-width: 80vw;
+ max-height: 80vh;
+ object-fit: contain;
+}
+
+.chapter-modal-close {
+ position: absolute;
+ top: -40px;
+ right: -40px;
+ background: none;
+ border: none;
+ font-size: 24px;
+ color: white;
+ cursor: pointer;
+}
+
+.chapter-modal-arrow {
+ position: absolute;
+ top: 50%;
+ font-size: 48px;
+ color: white;
+ cursor: pointer;
+ transition: opacity 0.2s;
+}
+
+.chapter-modal-arrow:hover {
+ opacity: 0.6;
+}
+
+.chapter-modal-arrow.left {
+ left: -40px;
+}
+
+.chapter-modal-arrow.right {
+ right: -40px;
+}
+
+/* Caption */
+.chapter-modal-caption {
+ margin-top: 12px;
+ text-align: center;
+ color: white;
+}
+
+.chapter-modal-caption .title {
+ font-size: 18px;
+ font-weight: 600;
+}
+
+.chapter-modal-caption .time {
+ opacity: 0.8;
+ font-size: 14px;
+}