Sliding Flipbook with Navigator
.bg-primary {
display: none !important;
}
.action-buttons {
display: none !important;
}
:root {
/* DYNAMIC SIZING LOGIC */
--fb-aspect-ratio: 1.777;
--fb-max-img-h: 65vh; /* Increased standard height */
/* Fill 100% of width unless limited by the max height */
--fb-img-height: min(calc(100vw / var(--fb-aspect-ratio)), var(--fb-max-img-h));
--fb-book-width: calc(var(--fb-img-height) * var(--fb-aspect-ratio));
/* Stage height includes image + button area */
--fb-btn-area: 80px;
--fb-stage-height: calc(var(--fb-img-height) + var(--fb-stage-height));
--fb-slide-duration: 0.7s;
--fb-kb-bezier: cubic-bezier(0.65, 0, 0.35, 1);
--fb-primary: #1c427d;
--fb-playing: #1c427d;
}
/* EXTREME ISOLATION STRATEGY */
#flipbook-component-root {
all: initial;
display: flex;
justify-content: flex-start;
align-items: center;
flex-direction: column;
width: 100%;
height: auto;
min-height: fit-content;
background-color: #ffffff;
position: relative;
overflow: hidden;
font-family: Arial, Helvetica, sans-serif;
isolation: isolate;
z-index: 1;
box-sizing: border-box;
padding-bottom: 10px;
}
#flipbook-component-root:fullscreen {
justify-content: center;
padding-bottom: 0;
background-color: #f0f2f5;
/* Maximize image height in fullscreen, leaving just enough room for buttons */
--fb-max-img-h: 92vh;
--fb-btn-area: 60px;
}
#flipbook-component-root * {
box-sizing: border-box;
font-family: inherit;
}
/* The viewport for the slide */
#flipbook-component-root .stage {
position: relative;
width: var(--fb-book-width);
height: calc(var(--fb-img-height) + var(--fb-btn-area));
margin: 0 auto;
transition: width 0.3s ease, height 0.3s ease;
}
/* The sliding container for images only */
#flipbook-component-root .view-window {
position: relative;
width: 100%;
height: var(--fb-img-height);
overflow: hidden;
transition: height 0.3s ease;
}
#flipbook-component-root .roller {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: transform var(--fb-slide-duration) var(--fb-kb-bezier);
transform: translateX(0);
}
#flipbook-component-root .face {
position: absolute;
width: 100%;
height: 100%;
top: 0;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
overflow: hidden;
background-color: transparent;
}
#flipbook-component-root .face.front { left: 0; }
#flipbook-component-root .face.right { left: 100%; }
#flipbook-component-root .face.left { left: -100%; }
#flipbook-component-root .img-container {
width: 100%;
height: 100%;
overflow: hidden;
background-color: #000;
box-shadow: 0 0 40px rgba(0, 0, 0, 0.4);
}
#flipbook-component-root .face img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
user-select: none;
transition: transform 1.2s ease;
}
/* SHARED BUTTON DIMENSIONS AND ALIGNMENT */
#flipbook-component-root .secondary-btn,
#flipbook-component-root .podcast-btn {
position: absolute;
top: calc(var(--fb-img-height) + 10px);
padding: 6px 10px;
font-size: 0.7rem;
border-radius: 4px;
display: flex;
align-items: center;
gap: 6px;
cursor: pointer;
z-index: 50;
white-space: nowrap;
transition: all 0.2s ease;
box-shadow: 0 2px 5px rgba(0,0,0,0.05);
font-weight: bold;
letter-spacing: 0.02em;
text-decoration: none;
}
/* STATIC PODCAST BUTTON SPECIFICS */
#flipbook-component-root .podcast-btn {
left: 50%;
transform: translateX(-50%);
background: var(--fb-primary);
color: #ffffff;
border: none;
pointer-events: auto;
}
#flipbook-component-root .podcast-btn:hover {
background: #2656a3;
transform: translateX(-50%) translateY(-2px);
}
#flipbook-component-root .podcast-btn.playing {
background: var(--fb-playing);
}
/* SECONDARY BUTTON SPECIFICS */
#flipbook-component-root .secondary-btn {
background: rgba(255, 255, 255, 0.95);
border: 1px solid #ddd;
color: #333;
z-index: 20;
}
#flipbook-component-root .secondary-btn:hover {
background: #fff;
border-color: var(--fb-primary);
color: var(--fb-primary);
transform: translateY(-2px);
}
#flipbook-component-root .nav-toggle-btn { right: 0; }
#flipbook-component-root .fullscreen-btn { right: 115px; }
#flipbook-component-root .doc-link-btn { left: 0; }
#flipbook-component-root .roll-next { transform: translateX(-100%); }
#flipbook-component-root .roll-prev { transform: translateX(100%); }
/* Mobile specific spacing */
@media (max-width: 600px) {
#flipbook-component-root .secondary-btn,
#flipbook-component-root .podcast-btn {
padding: 5px 7px;
font-size: 0.6rem;
gap: 4px;
}
#flipbook-component-root .fullscreen-btn { right: 85px; }
}
/* GRID OVERLAY */
#flipbook-component-root .grid-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.98);
z-index: 100;
display: none;
flex-direction: column;
padding: 30px;
overflow-y: auto;
}
#flipbook-component-root .grid-overlay.active {
display: flex;
}
#flipbook-component-root .grid-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
border-bottom: 1px solid #eee;
padding-bottom: 15px;
}
#flipbook-component-root .grid-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 25px;
padding-bottom: 40px;
}
#flipbook-component-root .grid-item {
cursor: pointer;
transition: transform 0.2s ease;
text-align: center;
}
#flipbook-component-root .grid-item:hover {
transform: scale(1.03);
}
#flipbook-component-root .grid-item img {
width: 100%;
aspect-ratio: 16/9;
object-fit: cover;
border-radius: 6px;
border: 3px solid #eee;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
display: block;
background: #f0f0f0;
transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
#flipbook-component-root .grid-item:hover img {
border-color: #ccc;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
#flipbook-component-root .grid-item.current img {
border-color: #1c427d;
box-shadow: 0 0 15px rgba(28, 66, 125, 0.3);
}
#flipbook-component-root .grid-item span {
font-size: 0.85rem;
font-weight: bold;
color: #333;
display: block;
margin-top: 8px;
}
#flipbook-component-root .close-grid {
background: none;
border: none;
font-size: 2rem;
cursor: pointer;
color: #333;
line-height: 1;
}
#flipbook-component-root .controls-hint {
position: relative;
margin-bottom: 15px; /* Added spacing from bottom content */
margin-top: 5px;
color: rgba(0, 0, 0, 0.5);
font-size: 0.75rem;
pointer-events: none;
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
width: 100%;
text-align: center;
transition: opacity 1s ease, transform 1s ease;
opacity: 1;
}
#flipbook-component-root .controls-hint.fade-out {
opacity: 0;
transform: translateY(-10px);
}
#flipbook-component-root .scroll-icon {
animation: fb-nudge-horizontal 2s infinite;
}
@keyframes fb-nudge-horizontal {
0%, 20%, 50%, 80%, 100% {transform: translateX(0);}
40% {transform: translateX(-5px);}
60% {transform: translateX(5px);}
}
Select Year
×
Use Wheel or Arrows to Slide
View Journals
Full Screen
Jump to Year
Listen to Podcast
(function() {
/**
* SLIDES DATA
*/
const slides = [
{ title: "1977", src: "https://images.wbct.org.uk/upload/2026/02/11/20260211172131-5b13d5b2.png", podcast: "https://images.wbct.org.uk/upload/2026/02/19/20260219220922-17d44b97.mp3", doc: "https://view-awesome-table.com/-OoAnIzsqhstWYFnDTg0/view?filterB=1977" },
{ title: "1978", src: "https://images.wbct.org.uk/upload/2026/02/19/20260219225338-2f58685b.png", podcast: "https://images.wbct.org.uk/upload/2026/03/09/20260309180137-e7cecc28.mp3", doc: "https://view-awesome-table.com/-OoAnIzsqhstWYFnDTg0/view?filterB=1978" },
{ title: "1979", src: "https://images.wbct.org.uk/upload/2026/02/11/20260211174120-8cd009c9.png", podcast: "https://images.wbct.org.uk/upload/2026/03/12/20260312154647-f38badb9.mp3", doc: "https://view-awesome-table.com/-OoAnIzsqhstWYFnDTg0/view?filterB=1979" },
{ title: "1980", src: "https://images.wbct.org.uk/upload/2026/02/11/20260211174114-52e03054.png", podcast: "https://images.wbct.org.uk/upload/2026/03/12/20260312162035-b9b5796e.mp3", doc: "https://view-awesome-table.com/-OoAnIzsqhstWYFnDTg0/view?filterB=1980" },
{ title: "1981", src: "https://images.wbct.org.uk/upload/2026/02/11/20260211174058-baa80b19.png", podcast: "https://images.wbct.org.uk/upload/2026/03/12/20260312164558-e7e9187c.mp3", doc: "https://view-awesome-table.com/-OoAnIzsqhstWYFnDTg0/view?filterB=1981" },
{ title: "1982", src: "https://images.wbct.org.uk/upload/2026/02/11/20260211232132-cf4ab68b.png", podcast: "https://images.wbct.org.uk/upload/2026/03/12/20260312171010-e3c7fe16.mp3", doc: "https://view-awesome-table.com/-OoAnIzsqhstWYFnDTg0/view?filterB=1982" },
{ title: "1983", src: "https://images.wbct.org.uk/upload/2026/02/11/20260211234042-e64ef457.png", podcast: "https://images.wbct.org.uk/upload/2026/03/20/20260320130208-4be620fb.mp3", doc: "https://view-awesome-table.com/-OoAnIzsqhstWYFnDTg0/view?filterB=1983" },
{ title: "1984", src: "https://images.wbct.org.uk/upload/2026/03/20/20260320163356-5fd3c44d.png", podcast: "https://images.wbct.org.uk/upload/2026/03/20/20260320181442-a5ce59f2.mp3", doc: "https://view-awesome-table.com/-OoAnIzsqhstWYFnDTg0/view?filterB=1984" },
{ title: "1985", src: "https://images.wbct.org.uk/upload/2026/02/13/20260213000825-883bc44d.png", podcast: "https://images.wbct.org.uk/upload/2026/03/20/20260320201100-b9ad4c43.mp3", doc: "https://view-awesome-table.com/-OoAnIzsqhstWYFnDTg0/view?filterB=1985" },
{ title: "1986", src: "https://images.wbct.org.uk/upload/2026/03/21/20260321232115-7e635722.png", podcast: "https://images.wbct.org.uk/upload/2026/03/21/20260321235232-6643e1cf.mp3", doc: "https://view-awesome-table.com/-OoAnIzsqhstWYFnDTg0/view?filterB=1986" },
{ title: "1987", src: "https://images.wbct.org.uk/upload/2026/02/13/20260213233922-f21919d4.png", podcast: "https://images.wbct.org.uk/upload/2026/03/22/20260322174004-4045b1cd.mp3", doc: "https://view-awesome-table.com/-OoAnIzsqhstWYFnDTg0/view?filterB=1987" },
{ title: "1988", src: "https://images.wbct.org.uk/upload/2026/03/22/20260322180842-67d25e97.png", podcast: "https://images.wbct.org.uk/upload/2026/03/22/20260322182233-5f4d79d9.mp3", doc: "https://view-awesome-table.com/-OoAnIzsqhstWYFnDTg0/view?filterB=1988" },
{ title: "1989", src: "https://images.wbct.org.uk/upload/2026/02/15/20260215162315-e19d4d6b.png", podcast: "https://images.wbct.org.uk/upload/2026/03/23/20260323162728-9ce96173.mp3", doc: "https://view-awesome-table.com/-OoAnIzsqhstWYFnDTg0/view?filterB=1989" },
];
const roller = document.getElementById('roller');
const audioPlayer = document.getElementById('fb-audio-player');
const root = document.getElementById('flipbook-component-root');
const hint = document.getElementById('hint-element');
const gridOverlay = document.getElementById('grid-overlay');
const gridContainer = document.getElementById('grid-container');
const globalDocBtn = document.getElementById('active-doc-btn');
const podcastBtn = document.getElementById('main-podcast-btn');
const fsBtn = document.getElementById('fullscreen-toggle-btn');
const fsBtnText = document.getElementById('fs-btn-text');
const currImg = document.getElementById('currImg');
const nextImg = document.getElementById('nextImg');
const prevImg = document.getElementById('prevImg');
let index = 0;
let isAnimating = false;
let isHovered = false;
let currentPlayingIndex = -1;
const playSvg = '';
const pauseSvg = '';
function initGrid() {
gridContainer.innerHTML = '';
slides.forEach((slide, i) => {
const item = document.createElement('div');
item.className = `grid-item ${i === index ? 'current' : ''}`;
item.innerHTML = `
${slide.title}`;
item.onclick = () => jumpToIndex(i);
gridContainer.appendChild(item);
});
}
function jumpToIndex(newIndex) {
if (newIndex === index) {
gridOverlay.classList.remove('active');
return;
}
index = newIndex;
gridOverlay.classList.remove('active');
dismissHint();
finalizeRoll();
initGrid();
}
// Fullscreen Toggle
fsBtn.onclick = () => {
if (!document.fullscreenElement) {
root.requestFullscreen().catch(err => {
console.warn(`Fullscreen error: ${err.message}`);
});
} else {
document.exitFullscreen();
}
};
// Update Fullscreen UI
document.onfullscreenchange = () => {
const isFs = !!document.fullscreenElement;
const enterIcon = document.getElementById('fs-icon-enter');
const exitIcon = document.getElementById('fs-icon-exit');
if (isFs) {
enterIcon.style.display = 'none';
exitIcon.style.display = 'inline-block';
fsBtnText.textContent = 'Exit Full Screen';
} else {
enterIcon.style.display = 'inline-block';
exitIcon.style.display = 'none';
fsBtnText.textContent = 'Full Screen';
}
};
document.getElementById('open-grid-btn').onclick = () => {
initGrid();
gridOverlay.classList.add('active');
};
document.getElementById('close-grid-btn').onclick = () => gridOverlay.classList.remove('active');
// Initial UI Setup
currImg.src = slides[index].src;
globalDocBtn.href = slides[index].doc;
initGrid();
updateBuffer();
updateButtonState();
function dismissHint() {
if (hint && !hint.classList.contains('fade-out')) {
hint.classList.add('fade-out');
setTimeout(() => { hint.style.display = 'none'; }, 1000);
}
}
setTimeout(dismissHint, 6000);
function updateBuffer() {
if (index < slides.length - 1) {
nextImg.src = slides[index + 1].src;
nextImg.closest('.face').style.display = 'flex';
} else {
nextImg.closest('.face').style.display = 'none';
}
if (index > 0) {
prevImg.src = slides[index - 1].src;
prevImg.closest('.face').style.display = 'flex';
} else {
prevImg.closest('.face').style.display = 'none';
}
}
function updateButtonState() {
const isPlayingCurrent = (index === currentPlayingIndex && !audioPlayer.paused);
const icon = podcastBtn.querySelector('.icon');
const text = podcastBtn.querySelector('.text');
if (isPlayingCurrent) {
podcastBtn.classList.add('playing');
icon.innerHTML = pauseSvg;
text.innerText = 'Pause Podcast';
} else {
podcastBtn.classList.remove('playing');
icon.innerHTML = playSvg;
text.innerText = 'Listen to Podcast';
}
}
function toggleAudio() {
if (currentPlayingIndex === index) {
if (audioPlayer.paused) audioPlayer.play();
else audioPlayer.pause();
} else {
audioPlayer.src = slides[index].podcast;
audioPlayer.play();
currentPlayingIndex = index;
}
updateButtonState();
}
podcastBtn.onclick = (e) => {
e.stopPropagation();
toggleAudio();
};
audioPlayer.onplay = audioPlayer.onpause = updateButtonState;
audioPlayer.onended = () => { currentPlayingIndex = -1; updateButtonState(); };
function roll(direction) {
if (isAnimating) return;
dismissHint();
if (direction === 'next' && index < slides.length - 1) {
isAnimating = true;
roller.classList.add('roll-next');
setTimeout(() => { index++; finalizeRoll(); }, 700);
} else if (direction === 'prev' && index > 0) {
isAnimating = true;
roller.classList.add('roll-prev');
setTimeout(() => { index--; finalizeRoll(); }, 700);
}
}
function finalizeRoll() {
roller.style.transition = 'none';
roller.classList.remove('roll-next', 'roll-prev');
currImg.src = slides[index].src;
globalDocBtn.href = slides[index].doc;
roller.offsetHeight;
roller.style.transition = '';
updateBuffer();
updateButtonState(); // Sync button with new slide
isAnimating = false;
}
root.addEventListener('wheel', (e) => {
if (gridOverlay.classList.contains('active')) return;
if (Math.abs(e.deltaY) < 10) return;
e.preventDefault();
e.deltaY > 0 ? roll('next') : roll('prev');
}, { passive: false });
root.addEventListener('mouseenter', () => isHovered = true);
root.addEventListener('mouseleave', () => isHovered = false);
window.addEventListener('keydown', (e) => {
if (!isHovered || gridOverlay.classList.contains('active')) return;
if (['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)) return;
if (e.key === 'ArrowRight' || e.key === 'ArrowDown' || e.key === ' ') { e.preventDefault(); roll('next'); }
if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') { e.preventDefault(); roll('prev'); }
});
let touchStartX = 0;
root.addEventListener('touchstart', e => touchStartX = e.touches[0].clientX, {passive: true});
root.addEventListener('touchend', e => {
if (gridOverlay.classList.contains('active')) return;
const diff = touchStartX - e.changedTouches[0].clientX;
if (Math.abs(diff) > 50) diff > 0 ? roll('next') : roll('prev');
}, {passive: true});
roller.addEventListener('click', (e) => {
const rect = roller.getBoundingClientRect();
e.clientX - rect.left > rect.width / 2 ? roll('next') : roll('prev');
});
})();