/* =============================================================================
   main.css  –  Buku Teks Bahasa Semai Tingkatan 1  –  Digital Flipbook Reader
   =============================================================================
   TABLE OF CONTENTS
     0.  Web Fonts (@font-face)
     1.  CSS Custom Properties (design tokens)
     2.  Reset & Base
     3.  Viewer layout (wrapper → bookViewer)
     4.  Title bar
     5.  Book container & spread
     6.  Page halves (left / right)
     7.  Page images
     8.  Book spine & page-fold shadow
     9.  3-D Flipper animation
    10.  Navigation bar
    11.  Hotspot buttons
    12.  Modal overlay
    13.  Modal content types (video, audio, iframe)
    14.  Loading spinner
    15.  Utility / accessibility
   ============================================================================= */

/* ─── 0. Web Fonts ──────────────────────────────────────────────────────────── */

/* ── Poppins (default UI font) ─────────────────────────────────────────────── */
@font-face { font-family: 'Poppins'; font-weight: 100; font-style: normal;  font-display: swap; src: url('../../assets/fonts/Poppins-Thin.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 100; font-style: italic;  font-display: swap; src: url('../../assets/fonts/Poppins-ThinItalic.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 200; font-style: normal;  font-display: swap; src: url('../../assets/fonts/Poppins-ExtraLight.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 200; font-style: italic;  font-display: swap; src: url('../../assets/fonts/Poppins-ExtraLightItalic.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 300; font-style: normal;  font-display: swap; src: url('../../assets/fonts/Poppins-Light.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 300; font-style: italic;  font-display: swap; src: url('../../assets/fonts/Poppins-LightItalic.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 400; font-style: normal;  font-display: swap; src: url('../../assets/fonts/Poppins-Regular.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 400; font-style: italic;  font-display: swap; src: url('../../assets/fonts/Poppins-Italic.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 500; font-style: normal;  font-display: swap; src: url('../../assets/fonts/Poppins-Medium.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 500; font-style: italic;  font-display: swap; src: url('../../assets/fonts/Poppins-MediumItalic.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 600; font-style: normal;  font-display: swap; src: url('../../assets/fonts/Poppins-SemiBold.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 600; font-style: italic;  font-display: swap; src: url('../../assets/fonts/Poppins-SemiBoldItalic.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 700; font-style: normal;  font-display: swap; src: url('../../assets/fonts/Poppins-Bold.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 700; font-style: italic;  font-display: swap; src: url('../../assets/fonts/Poppins-BoldItalic.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 800; font-style: normal;  font-display: swap; src: url('../../assets/fonts/Poppins-ExtraBold.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 800; font-style: italic;  font-display: swap; src: url('../../assets/fonts/Poppins-ExtraBoldItalic.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 900; font-style: normal;  font-display: swap; src: url('../../assets/fonts/Poppins-Black.ttf') format('truetype'); }
@font-face { font-family: 'Poppins'; font-weight: 900; font-style: italic;  font-display: swap; src: url('../../assets/fonts/Poppins-BlackItalic.ttf') format('truetype'); }

/* ── Azim ───────────────────────────────────────────────────────────────────── */
@font-face { font-family: 'Azim'; font-weight: 300; font-style: normal; font-display: swap; src: url('../../assets/fonts/Azim-Light.otf') format('opentype'); }
@font-face { font-family: 'Azim'; font-weight: 500; font-style: normal; font-display: swap; src: url('../../assets/fonts/Azim-Medium.otf') format('opentype'); }
@font-face { font-family: 'Azim'; font-weight: 700; font-style: normal; font-display: swap; src: url('../../assets/fonts/Azim-Bold.otf') format('opentype'); }

/* ── Display / decorative fonts ─────────────────────────────────────────────── */
@font-face { font-family: 'BarberChop';   font-weight: 400; font-style: normal; font-display: swap; src: url('../../assets/fonts/BarberChop.otf') format('opentype'); }
@font-face { font-family: 'Fredoka One';  font-weight: 400; font-style: normal; font-display: swap; src: url('../../assets/fonts/FredokaOne-Regular.ttf') format('truetype'); }
@font-face { font-family: 'Happy School'; font-weight: 400; font-style: normal; font-display: swap; src: url('../../assets/fonts/HappySchool.ttf') format('truetype'); }
@font-face { font-family: 'Mangabey';     font-weight: 400; font-style: normal; font-display: swap; src: url('../../assets/fonts/Mangabey.ttf') format('truetype'); }
@font-face { font-family: 'Milky Nice';   font-weight: 400; font-style: normal; font-display: swap; src: url('../../assets/fonts/MilkyNice.ttf') format('truetype'); }
@font-face { font-family: 'Milky Nice Clean'; font-weight: 400; font-style: normal; font-display: swap; src: url('../../assets/fonts/MilkyNice-Clean.ttf') format('truetype'); }

/* ── Language-specific fonts ────────────────────────────────────────────────── */
@font-face { font-family: 'Hanzi Kaishu';   font-weight: 400; font-style: normal; font-display: swap; src: url('../../assets/fonts/Hanzi-Kaishu Regular.ttf') format('truetype'); }
@font-face { font-family: 'HYKaishu';       font-weight: 400; font-style: normal; font-display: swap; src: url('../../assets/fonts/汉仪楷体简.ttf') format('truetype'); }
@font-face { font-family: 'Hind Madurai';   font-weight: 400; font-style: normal; font-display: swap; src: url('../../assets/fonts/HindMadurai-Regular.otf') format('opentype'); }
@font-face { font-family: 'Noto Sans Tamil';font-weight: 400; font-style: normal; font-display: swap; src: url('../../assets/fonts/NotoSansTamil-Regular.ttf') format('truetype'); }
@font-face { font-family: 'Pinyin';         font-weight: 400; font-style: normal; font-display: swap; src: url('../../assets/fonts/PINYIN.TTF') format('truetype'); }

/* ─── 1. CSS Custom Properties ─────────────────────────────────────────────── */
:root {
  /* Viewer dimensions (always 1024×768 before responsive scaling) */
  --viewer-w:      1024px;
  --viewer-h:      768px;

  /* Layout zones */
  --titlebar-h:    50px;   /* slightly taller to fit stacked title + subtitle */
  --navbar-h:      54px;
  --book-area-h:   calc(var(--viewer-h) - var(--titlebar-h) - var(--navbar-h));
                   /* 768 - 50 - 54 = 664px */

  /* Each page half width = (viewer - spine - 2× side padding) / 2 */
  --side-pad:      36px;
  --spine-w:       0px;
  --page-w:        calc((var(--viewer-w) - var(--spine-w) - var(--side-pad) * 2) / 2);
                   /* (1024 - 0 - 72) / 2 = 476px */

  /* Page content area – A4 ratio (842/595 ≈ 1.4151) centred inside page half */
  --page-content-w: var(--page-w);
  --page-content-h: calc(var(--page-content-w) * 842 / 595);
                    /* 471 × 1.4151 ≈ 666px, fits in 668px ✓ */

  /* Flip animation */
  --flip-duration: 900ms;
  --flip-ease:     linear;   /* timing controlled per-keyframe below */

  /* Colours */
  --clr-bg:           #1e1e2e;
  --clr-bg2:          #27273a;
  --clr-titlebar:     #12121f;
  --clr-navbar:       #12121f;
  --clr-spine:        #7b5e3a;
  --clr-spine-hi:     #c8a06a;
  --clr-page-bg:      #fefdf8;
  --clr-page-shadow:  rgba(0, 0, 0, 0.35);
  --clr-accent:       #3d85c8;
  --clr-accent-dark:  #2a5f90;
  --clr-accent-light: #6daee8;
  --clr-text:         #f0eee8;
  --clr-text-dim:     #8888a8;
  --clr-modal-bg:     #1a1a2e;
  --clr-modal-border: #2e2e48;

  /* Hotspot type colours */
  /* Hotspot type colours — every type has its own distinct hue */
  --clr-hs-video:       #e53935;  /* red */
  --clr-hs-audio:       #43a047;  /* green */
  --clr-hs-interactive: #fb8c00;  /* orange */
  --clr-hs-game:        #8e24aa;  /* purple */
  --clr-hs-song:        #e91e8c;  /* magenta */
  --clr-hs-tracks:      #00897b;  /* teal */
  --clr-hs-animation:   #00bcd4;  /* cyan */
  --clr-hs-3d:          #3949ab;  /* indigo */
  --clr-hs-multiple:    #607d8b;  /* slate */

  /* Border-radius */
  --rad-sm:  4px;
  --rad-md:  8px;
  --rad-lg:  14px;
  --rad-xl:  20px;
}

/* ─── 2. Reset & Base ──────────────────────────────────────────────────────── */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;    /* no scroll – viewer is always scaled to fit the viewport */
  overscroll-behavior: none;
  touch-action: manipulation;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  background: var(--clr-bg);
  font-family: 'Poppins', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  color: var(--clr-text);
  -webkit-font-smoothing: antialiased;
}

button, input {
  font-family: inherit;
  cursor: pointer;
  border: none;
  background: none;
}

img {
  display: block;
  max-width: 100%;
}

/* ─── 3. Viewer Layout ─────────────────────────────────────────────────────── */

/* Full-viewport wrapper — JS sets its height to match the scaled viewer */
#viewerWrapper {
  position: relative;
  width: 100%;
  background: transparent;
  /* height is set dynamically by JS */
}

/* The 1024×768 fixed canvas.
   Positioned absolute so its layout size (1024px) never affects the wrapper
   or causes overflow.  JS applies translateX(offset) scale(s) to visually
   centre and resize it to fit any viewport. */
#bookViewer {
  position: absolute;
  top:  0;
  left: 0;
  width:  var(--viewer-w);
  height: var(--viewer-h);
  display: flex;
  flex-direction: column;
  background: var(--clr-bg2);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.7);
  transform-origin: top left;   /* JS overrides this but set a safe default */
  overflow: hidden;
  border-radius: var(--rad-lg);
}

/* ─── 4. Title Bar ──────────────────────────────────────────────────────────── */

#bookTitleBar {
  flex: 0 0 var(--titlebar-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--clr-titlebar);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  padding: 0 16px;
  gap: 12px;
  position: relative;
  z-index: 20;
}

/* Left group: back button + logo + stacked title/subtitle */
.titlebar-left {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.back-btn {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  border-radius: 5px;
  color: var(--clr-text-dim);
  text-decoration: none;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  flex-shrink: 0;
  transition: background 0.15s, color 0.15s;
}
.back-btn:hover {
  background: rgba(255,255,255,0.08);
  color: var(--clr-text);
}
html.light-mode .back-btn:hover {
  background: rgba(0,0,0,0.06);
}

#bookTitleBar .title-logo {
  width: 22px;
  height: 22px;
  opacity: 0.7;
  flex-shrink: 0;
}

.titlebar-titles {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

#bookTitleText {
  font-size: 12px;
  font-weight: 700;
  color: var(--clr-text);
  letter-spacing: 0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#bookSubtitleText {
  font-size: 10px;
  font-weight: 400;
  color: var(--clr-text-dim);
  letter-spacing: 0.03em;
}

/* Right group: company name + theme toggle */
.titlebar-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

.company-name {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.15;
  font-size: 10px;
  font-weight: 600;
  color: var(--clr-text-dim);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  opacity: 0.8;
}
.company-version {
  font-size: 8px;
  font-weight: 500;
  letter-spacing: 0.08em;
  opacity: 0.75;
  text-transform: none;
  margin-top: 1px;
}

/* ── Titlebar icon buttons (fullscreen, audio) ───────────────────────────── */
.titlebar-icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 6px;
  color: var(--clr-text-dim);
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.18s, color 0.18s, border-color 0.18s;
}
.titlebar-icon-btn:hover {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.28);
}
.titlebar-icon-btn.is-muted {
  color: #e57373;
  border-color: rgba(229, 115, 115, 0.4);
}
html.light-mode .titlebar-icon-btn {
  background: rgba(0, 0, 0, 0.05);
  border-color: rgba(0, 0, 0, 0.12);
  color: #3a3a5a;
}
html.light-mode .titlebar-icon-btn:hover {
  background: rgba(0, 0, 0, 0.12);
  color: #1a1a3e;
}
html.light-mode .titlebar-icon-btn.is-muted {
  color: #c62828;
}

/* ── Theme toggle switch ─────────────────────────────────────────────────── */
.theme-toggle-label {
  display: flex;
  align-items: center;
  gap: 5px;
  cursor: pointer;
  user-select: none;
}

.toggle-mode-icon {
  font-size: 12px;
  line-height: 1;
}

/* Hide the native checkbox */
.theme-toggle-input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
  pointer-events: none;
}

/* Track */
.theme-toggle-switch {
  position: relative;
  display: inline-block;
  width: 30px;
  height: 16px;
  background: rgba(255,255,255,0.15);
  border: 1px solid rgba(255,255,255,0.22);
  border-radius: 100px;
  transition: background 0.22s, border-color 0.22s;
  flex-shrink: 0;
}

/* Thumb */
.theme-toggle-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 10px;
  height: 10px;
  background: rgba(255,255,255,0.7);
  border-radius: 50%;
  transition: transform 0.22s, background 0.22s;
}

/* Checked (light mode) state */
.theme-toggle-input:checked + .theme-toggle-switch {
  background: #f59e0b;
  border-color: #f59e0b;
}

.theme-toggle-input:checked + .theme-toggle-switch .theme-toggle-thumb {
  transform: translateX(14px);
  background: #fff;
}

.theme-toggle-label:hover .theme-toggle-switch {
  border-color: rgba(255,255,255,0.45);
}

/* ── Light mode overrides ────────────────────────────────────────────────── */
html.light-mode {
  --clr-bg:           #d8dcea;
  --clr-bg2:          #e8ecf8;
  --clr-titlebar:     #ffffff;
  --clr-navbar:       #f2f4fc;
  --clr-spine:        #9b7a50;
  --clr-spine-hi:     #c8a06a;
  --clr-text:         #1a1a2e;
  --clr-text-dim:     #5a5a7a;
  --clr-modal-bg:     #ffffff;
  --clr-modal-border: #d0d0e8;
  --clr-page-shadow:  rgba(0,0,0,0.12);
}

/* In light mode the title bar uses dark text */
html.light-mode #bookTitleBar {
  border-bottom-color: rgba(0,0,0,0.08);
}

html.light-mode .company-name {
  color: #3a3a5a;
  opacity: 1;
}

html.light-mode .theme-toggle-switch {
  background: rgba(0,0,0,0.12);
  border-color: rgba(0,0,0,0.18);
}

html.light-mode .theme-toggle-thumb {
  background: rgba(0,0,0,0.55);
}

html.light-mode .theme-toggle-input:checked + .theme-toggle-switch .theme-toggle-thumb {
  background: #fff;
}

html.light-mode .nav-btn:disabled {
  opacity: 0.25;
}

html.light-mode .page-input {
  color: #1a1a2e;
  background: rgba(0,0,0,0.06);
  border-color: rgba(0,0,0,0.35);
  box-shadow: 0 0 0 2px rgba(0,0,0,0.04);
}
html.light-mode .page-input:hover {
  border-color: rgba(0,0,0,0.6);
  background: rgba(0,0,0,0.1);
}
html.light-mode .page-input:focus {
  border-color: var(--clr-accent, #3a5fd5);
  background: rgba(0,0,0,0.07);
  box-shadow: 0 0 0 3px rgba(58,95,213,0.2);
}

/* ─── 5. Book Container & Spread ───────────────────────────────────────────── */

#bookContainer {
  flex: 1 1 auto;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  padding: 0;
  overflow: hidden;
}

/* The spread holds the StPageFlip canvas + hotspot overlays */
.book-spread {
  position: relative;
  width: calc(var(--page-w) * 2 + var(--spine-w));
  height: var(--book-area-h);
  flex-shrink: 0;
  filter: drop-shadow(0 8px 30px rgba(0, 0, 0, 0.55));
  cursor: default;
}

/* StPageFlip canvas container */
#stPageFlipContainer {
  position: absolute;
  top: 0; left: 0;
  width: 100%;
  height: 100%;
}

/* Hotspot overlay layers — positioned over left/right page halves of the canvas */
#hsOverlayLeft,
#hsOverlayRight {
  position: absolute;
  top: 0;
  height: 100%;
  width: 50%;
  pointer-events: none;
  z-index: 5;
}
#hsOverlayLeft  { left: 0; }
#hsOverlayRight { left: 50%; }

/* Allow touch drag-to-flip on mobile — override body's touch-action: manipulation */
#bookSpread {
  touch-action: none;
}
  user-select: none;
  pointer-events: none;
}

/* ─── 6. Page Halves ────────────────────────────────────────────────────────── */

.page-half {
  position: relative;
  flex: 0 0 var(--page-w);
  height: 100%;
  background: var(--clr-page-bg);
  overflow: hidden;
  will-change: contents;
  transform: translateZ(0);
  -webkit-transform: translateZ(0);
}

.page-half.page-left {
  border-radius: var(--rad-sm) 0 0 var(--rad-sm);
}

.page-half.page-right {
  border-radius: 0 var(--rad-sm) var(--rad-sm) 0;
}

/* Hide empty page halves (e.g. last single page) */
.page-half.page-empty {
  visibility: hidden;
}

/* Page content fills the entire half */
.page-content {
  position: relative;
  width: 100%;
  height: 100%;
}

/* ─── 7. Page Images ───────────────────────────────────────────────────────── */

.page-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: fill;     /* stretch to fill; change to contain if pages have odd aspect ratio */
  object-position: center;
  user-select: none;
  pointer-events: none;
  transform: translateZ(0);           /* promote to GPU layer */
  -webkit-transform: translateZ(0);
}

/* ─── 8. Spine & Page-fold Shadow ──────────────────────────────────────────── */

.book-spine {
  display: none;
}

.page-fold {
  position: absolute;
  top: 0;
  width: 8px;
  height: 100%;
  pointer-events: none;
  z-index: 1;
}

.page-fold-left {
  right: 0;
  background: linear-gradient(to right, transparent, rgba(114, 114, 114, 0.055));
}

.page-fold-right {
  left: 0;
  background: linear-gradient(to left, transparent, rgba(114, 114, 114, 0.055));
}

/* ─── 9. 3-D Flipper Animation ──────────────────────────────────────────────── */

.page-flipper {
  position: absolute;
  top:    0;
  width:  50%;          /* covers one page half */
  height: 100%;

  transform-style: preserve-3d;
  pointer-events: none; /* invisible when idle */
  z-index: 10;
  will-change: transform;

  /* Hidden by default (opacity trick avoids layout shift) */
  opacity: 0;
}

/* Shown during animation */
.page-flipper.flipper-visible {
  opacity: 1;
  pointer-events: none;
}

/* Precise positioning: right half starts after left page + spine */
.page-flipper.flipper-on-right {
  left: calc(var(--page-w) + var(--spine-w));
  width: var(--page-w);
  transform-origin: left center;    /* spine is the left edge */
}

/* Left half starts at 0 */
.page-flipper.flipper-on-left {
  left: 0;
  width: var(--page-w);
  transform-origin: right center;   /* spine is the right edge */
}

/* The two faces of the flipper */
.flipper-face {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  overflow: hidden;
  will-change: transform;
  transform: translateZ(0);           /* GPU compositing */
  -webkit-transform: translateZ(0);
}

/* Back face pre-rotated 180° so it appears correct after the flip */
.flipper-back {
  transform: rotateY(180deg);
}

/* ══════════════════════════════════════════════════════════════════
   THIN PAPER FLIP – keyframe breakdown
   ──────────────────────────────────────────────────────────────────
   perspective(900px) inside transform gives each page a LOCAL
   vanishing point, creating the visual curvature of thin paper.

   0%–20%  : Page peels slowly off the book  (ease-out)
   20%–80% : Page swooshes lightly through air (ease-in-out)
   80%–100%: Page floats gently down to land  (soft ease-in)
   ══════════════════════════════════════════════════════════════════ */

/* ── Forward: right half rotates -180° around left (spine) edge ── */
@keyframes flipForwardAnim {
  0%   { transform: perspective(900px) rotateY(0deg);    animation-timing-function: cubic-bezier(0.45, 0, 0.85, 0.5); }
  20%  { transform: perspective(900px) rotateY(-28deg);  animation-timing-function: cubic-bezier(0.3, 0, 0.7, 1); }
  50%  { transform: perspective(900px) rotateY(-90deg);  animation-timing-function: cubic-bezier(0.3, 0, 0.7, 1); }
  80%  { transform: perspective(900px) rotateY(-158deg); animation-timing-function: cubic-bezier(0.15, 0, 0.35, 1); }
  100% { transform: perspective(900px) rotateY(-180deg); }
}

/* ── Backward: left half rotates +180° around right (spine) edge ── */
@keyframes flipBackwardAnim {
  0%   { transform: perspective(900px) rotateY(0deg);   animation-timing-function: cubic-bezier(0.45, 0, 0.85, 0.5); }
  20%  { transform: perspective(900px) rotateY(28deg);  animation-timing-function: cubic-bezier(0.3, 0, 0.7, 1); }
  50%  { transform: perspective(900px) rotateY(90deg);  animation-timing-function: cubic-bezier(0.3, 0, 0.7, 1); }
  80%  { transform: perspective(900px) rotateY(158deg); animation-timing-function: cubic-bezier(0.15, 0, 0.35, 1); }
  100% { transform: perspective(900px) rotateY(180deg); }
}

.page-flipper.flip-forward {
  animation: flipForwardAnim var(--flip-duration) linear forwards;
}

.page-flipper.flip-backward {
  animation: flipBackwardAnim var(--flip-duration) linear forwards;
}

/* ── Shadow overlays simulating paper bending ────────────────────
   Front face: shadow grows toward the spine edge as page lifts,
               then fades as the back face takes over.
   Back face:  starts dark (facing away from light), clears as it
               settles flat on the opposite side.
   ──────────────────────────────────────────────────────────────── */

/* Shadow pseudo-element base – always present, controlled by opacity */
.flipper-face::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
}

/* ── FORWARD flip shadows ── */
/* Front face: narrow crease shadow near spine, thin paper catches light */
.page-flipper.flip-forward .flipper-front::after {
  background: linear-gradient(to right, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.25) 20%, transparent 55%);
  animation: shadowForwardFront var(--flip-duration) linear forwards;
}

/* Back face: shadow near spine, fades as page settles flat */
.page-flipper.flip-forward .flipper-back::after {
  background: linear-gradient(to left, rgba(0,0,0,0.4) 0%, rgba(0,0,0,0.18) 22%, transparent 55%);
  animation: shadowForwardBack var(--flip-duration) linear forwards;
}

/* ── BACKWARD flip shadows ── */
/* Front face: shadow on RIGHT edge */
.page-flipper.flip-backward .flipper-front::after {
  background: linear-gradient(to left, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.25) 20%, transparent 55%);
  animation: shadowForwardFront var(--flip-duration) linear forwards;
}

/* Back face: shadow on LEFT edge */
.page-flipper.flip-backward .flipper-back::after {
  background: linear-gradient(to right, rgba(0,0,0,0.4) 0%, rgba(0,0,0,0.18) 22%, transparent 55%);
  animation: shadowForwardBack var(--flip-duration) linear forwards;
}

/* Thin paper: shadow builds quickly, peaks sharp at fold, gone fast */
@keyframes shadowForwardFront {
  0%   { opacity: 0;    }
  15%  { opacity: 0.2;  }
  45%  { opacity: 0.85; }
  50%  { opacity: 1.0;  }  /* sharp peak at spine crossing */
  100% { opacity: 0;    }  /* face hidden by backface-visibility after 90° */
}

/* Back face reveals quickly after 90°, dissipates as page settles */
@keyframes shadowForwardBack {
  0%   { opacity: 0;    }
  50%  { opacity: 0;    }
  56%  { opacity: 0.72; }  /* quick snap-on as back face appears */
  78%  { opacity: 0.28; }
  100% { opacity: 0;    }
}

/* ── JS-controlled drag shadow divs (Kindle-style live flip) ────────────────
   Opacity is driven by JS via inline style.  Gradient direction is toggled
   by adding  .from-left  or  .from-right  in JS at drag-start.
   ─────────────────────────────────────────────────────────────────────────── */
.flip-shadow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  z-index: 1;
}

/* Shadow darkens toward the SPINE (left edge of a forward-flip right page) */
.flip-shadow.from-left  { background: linear-gradient(to right, rgba(0,0,0,0.72) 0%, transparent 65%); }
/* Shadow darkens toward the SPINE (right edge of a backward-flip left page) */
.flip-shadow.from-right { background: linear-gradient(to left,  rgba(0,0,0,0.72) 0%, transparent 65%); }

/* ─── 10. Navigation Bar & Footer ──────────────────────────────────────────── */

.book-nav {
  flex: 0 0 var(--navbar-h);
  width: 100%;                   /* span full viewer width */
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--side-pad);    /* inner breathing room matches spread margins */
  background: var(--clr-navbar);
  border-top: 1px solid rgba(255,255,255,0.06);
  gap: 12px;
}

.nav-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 16px;
  background: var(--clr-accent);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  border-radius: var(--rad-md);
  transition: background 0.18s, transform 0.1s, opacity 0.2s;
  min-width: 120px;
  justify-content: center;
}

.nav-btn svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}

.nav-btn:hover:not(:disabled) {
  background: var(--clr-accent-dark);
  transform: translateY(-1px);
}

.nav-btn:active:not(:disabled) {
  transform: translateY(0);
}

.nav-btn:disabled {
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}

/* Page indicator in the centre of the nav bar */
.page-indicator {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--clr-text-dim);
  justify-content: center;
}

.page-indicator .sep    { color: var(--clr-text-dim); }
.page-indicator .sep-of { font-size: 11px; font-weight: 400; }

.page-input {
  width: 52px;
  padding: 4px 6px;
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--clr-text);
  background: rgba(255,255,255,0.12);
  border: 1.5px solid rgba(255,255,255,0.45);
  border-radius: 6px;
  outline: none;
  cursor: text;
  -moz-appearance: textfield;
  appearance: textfield;
  transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
  box-shadow: 0 0 0 2px rgba(255,255,255,0.06);
}
.page-input::-webkit-inner-spin-button,
.page-input::-webkit-outer-spin-button { -webkit-appearance: none; appearance: none; margin: 0; }
.page-input:hover {
  border-color: rgba(255,255,255,0.7);
  background: rgba(255,255,255,0.17);
}
.page-input:focus {
  border-color: var(--clr-accent, #6c8fff);
  background: rgba(255,255,255,0.18);
  box-shadow: 0 0 0 3px rgba(108,143,255,0.25);
}

/* ── Side navigation buttons (Hadapan / Belakang) ───────────────────────── */

.nav-side-btn {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 5px 10px;
  background: var(--clr-accent);
  color: #fff;
  border: none;
  border-radius: var(--rad-md);
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  transition: background 0.18s, transform 0.1s, opacity 0.18s;
  opacity: 0.88;
}

.nav-side-btn:hover:not(:disabled) {
  background: var(--clr-accent-dark);
  opacity: 1;
  transform: translateY(-1px);
}

.nav-side-btn:active:not(:disabled) {
  transform: translateY(0);
}

.nav-side-btn:disabled {
  opacity: 0.28;
  cursor: default;
  pointer-events: none;
}

.nav-side-btn svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

html.light-mode .nav-side-btn:disabled {
  opacity: 0.2;
}

/* ─── 11. Hotspot Buttons ───────────────────────────────────────────────────── */

/* The hotspot layer overlays the entire page content area */
.hotspot-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;   /* layer itself transparent; children get events */
}

/* Hide all hotspot buttons instantly when a page flip is in progress */
.book-spread.is-flipping .hotspot-btn {
  visibility: hidden;
}

/* Individual hotspot button */
.hotspot-btn {
  position: absolute;
  padding: 0;
  border: none;
  background: none;
  pointer-events: all;
  cursor: pointer;
  transition: transform 0.15s, filter 0.15s;
  animation: hotspotPulse 2.4s ease-in-out infinite;
}

@keyframes hotspotPulse {
  0%, 100% { filter: drop-shadow(0 0 0px rgba(255,255,255,0.6)); }
  50%       { filter: drop-shadow(0 0 5px rgba(255,255,255,0.9)); }
}

.hotspot-btn:hover {
  transform: scale(1.06);
  animation: none;
  filter: brightness(1.12);
}

.hotspot-btn:active {
  transform: scale(0.97);
}

/* Hotspot image — 2.63 cm × 0.5 cm at 96 dpi in the 1024px viewer space */
.hs-image {
  display: block;
  width:  99px;   /* 2.63 cm × 37.795 px/cm */
  height: 19px;   /* 0.50 cm × 37.795 px/cm */
  object-fit: fill;
  pointer-events: none;
  user-select: none;
}

/* ─── 12. Modal Overlay ─────────────────────────────────────────────────────── */

#modal {
  position: fixed;
  inset: 0;
  z-index: 1000;

  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;

  background: rgba(0, 0, 0, 0);
  backdrop-filter: blur(0px);

  /* Hidden by default */
  pointer-events: none;
  transition: background 0.3s, backdrop-filter 0.3s;
}

#modal.modal-active {
  background: rgba(0, 0, 0, 0.78);
  backdrop-filter: blur(4px);
  pointer-events: all;
}

/* Prevent body scroll when modal is open */
body.modal-open {
  overflow: hidden;
}

/* Modal container card */
#modalContainer {
  position: relative;
  background: var(--clr-modal-bg);
  border: 1px solid var(--clr-modal-border);
  border-radius: var(--rad-xl);
  width: min(960px, 96vw);
  height: min(85vh, 85dvh);
  display: flex;
  flex-direction: column;
  box-shadow: 0 24px 80px rgba(0,0,0,0.8);
  overflow: hidden;

  /* Slide-in animation */
  transform: translateY(24px) scale(0.97);
  opacity: 0;
  transition: transform 0.3s var(--flip-ease), opacity 0.3s;
}

#modal.modal-active #modalContainer {
  transform: translateY(0) scale(1);
  opacity: 1;
}

/* Modal header strip */
.modal-header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 20px 14px;
  border-bottom: 1px solid var(--clr-modal-border);
  flex-shrink: 0;
}

#modalTitle {
  font-size: 16px;
  font-weight: 700;
  color: var(--clr-text);
  flex: 1;
}

/* Coloured type badge next to title */
.modal-type-tag {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 100px;
  color: #fff;
}

.type-video       { background: var(--clr-hs-video); }
.type-animation   { background: var(--clr-hs-animation); }
.type-audio       { background: var(--clr-hs-audio); }
.type-interactive { background: var(--clr-hs-interactive); }
.type-game        { background: var(--clr-hs-game); }
.type-song        { background: var(--clr-hs-song); }
.type-tracks      { background: var(--clr-hs-tracks); }
.type-3d          { background: var(--clr-hs-3d); }

/* Close button */
#modalClose {
  flex-shrink: 0;
  margin-left: auto;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(255,255,255,0.08);
  color: var(--clr-text-dim);
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, color 0.15s;
}

#modalClose:hover {
  background: rgba(220, 40, 40, 0.85);
  color: #fff;
}

/* Modal body – fills remaining space */
#modalBody {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  padding: 20px;
  display: flex;
  align-items: stretch;
  justify-content: center;
}

#modalBody::-webkit-scrollbar       { width: 6px; }
#modalBody::-webkit-scrollbar-track { background: transparent; }
#modalBody::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 3px; }

/* ─── 13. Modal Content Types ───────────────────────────────────────────────── */

/* ── Video ── */
.media-wrapper {
  width: 100%;
  max-height: 100%;
  display: flex;
  flex-direction: column;
}

.media-video {
  position: relative;
  width: 100%;
  max-height: 100%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.media-video .vp-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: var(--rad-md);
  overflow: hidden;
}

.media-video .media-player {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: var(--rad-md);
  background: #000;
  outline: none;
  cursor: pointer;
}

/* -- Video replay button (icon-only) -- */
.video-replay-btn {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 72px;
  height: 72px;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: rgba(0, 0, 0, 0.72);
  color: #fff;
  border: 2px solid rgba(255, 255, 255, 0.55);
  border-radius: 50%;
  cursor: pointer;
  z-index: 10;
  transition: background 0.2s, transform 0.15s;
}

.video-replay-btn:hover {
  background: rgba(30, 30, 30, 0.9);
  transform: scale(1.08);
}

.video-replay-btn svg { display: block; }

/* -- Custom video player controls strip (below frame) -- */
.vp-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: rgba(60, 60, 70, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 14px;
  color: #fff;
  flex-shrink: 0;
}

.vp-play-btn,
.vp-fs-btn {
  width: 36px;
  height: 36px;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 10px;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  outline: none;
  flex-shrink: 0;
  transition: background 0.15s, transform 0.15s;
}
.vp-play-btn:hover,
.vp-fs-btn:hover { background: rgba(255, 255, 255, 0.18); }
.vp-play-btn:active,
.vp-fs-btn:active { transform: scale(0.94); }
.vp-play-btn svg,
.vp-fs-btn svg { width: 18px; height: 18px; display: block; }

.vp-time {
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: rgba(255, 255, 255, 0.85);
  min-width: 36px;
  text-align: center;
}

.vp-progress {
  -webkit-appearance: none;
  appearance: none;
  flex: 1;
  height: 5px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 3px;
  outline: none;
  cursor: pointer;
  accent-color: var(--clr-hs-video);
}
.vp-progress::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 14px; height: 14px;
  background: var(--clr-hs-video);
  border-radius: 50%;
  cursor: pointer;
  border: 2px solid #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
}
.vp-progress::-moz-range-thumb {
  width: 14px; height: 14px;
  background: var(--clr-hs-video);
  border-radius: 50%;
  cursor: pointer;
  border: 2px solid #fff;
}

.vp-vol-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
}
.vp-vol-icon {
  width: 20px; height: 20px;
  color: rgba(255, 255, 255, 0.85);
  flex-shrink: 0;
}
.vp-vol-slider {
  width: 70px;
  accent-color: #fff;
}

/* -- Fullscreen layout: video fills viewport, controls overlay + auto-hide -- */
.media-video:fullscreen {
  width: 100vw;
  height: 100vh;
  max-height: none;
  margin: 0;
  padding: 0;
  background: #000;
  gap: 0;
  justify-content: center;
  position: relative;
}
.media-video:-webkit-full-screen {
  width: 100vw;
  height: 100vh;
  max-height: none;
  margin: 0;
  padding: 0;
  background: #000;
  gap: 0;
  justify-content: center;
  position: relative;
}

.media-video:fullscreen .vp-frame,
.media-video:-webkit-full-screen .vp-frame {
  flex: 1;
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  border-radius: 0;
  min-height: 0;
}

.media-video:fullscreen .media-player,
.media-video:-webkit-full-screen .media-player {
  border-radius: 0;
}

.media-video:fullscreen .vp-controls,
.media-video:-webkit-full-screen .vp-controls {
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 8px;
  z-index: 10;
  background: rgba(20, 20, 28, 0.7);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.media-video:fullscreen .vp-controls.is-hidden,
.media-video:-webkit-full-screen .vp-controls.is-hidden {
  opacity: 0;
  pointer-events: none;
  transform: translateY(20px);
}

.media-video:fullscreen .vp-controls.is-dimmed,
.media-video:-webkit-full-screen .vp-controls.is-dimmed {
  opacity: 0.4;
}

.media-video.is-cursor-hidden:fullscreen,
.media-video.is-cursor-hidden:-webkit-full-screen,
.media-video.is-cursor-hidden:fullscreen *,
.media-video.is-cursor-hidden:-webkit-full-screen * {
  cursor: none;
}

/* ── Audio Player (equalizer + controls — grey/white theme) ── */
.media-audio {
  display: flex;
  justify-content: center;
  padding: 10px 0;
  width: 100%;
  min-height: 0;
  height: 100%;
  align-self: stretch;
}

.ap-card {
  width: 100%;
  max-width: 860px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
  flex: 1;
}

/* Equalizer panel */
.ap-equalizer-panel {
  flex: 1;
  min-height: 140px;
  background: rgba(60, 60, 70, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.ap-equalizer {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 3px;
  height: 80%;
  width: 100%;
  padding: 0 10px;
}

.eq-bar {
  flex: 1;
  max-width: 16px;
  min-height: 4px;
  height: 6%;
  border-radius: 4px 4px 0 0;
  background: linear-gradient(to top, #888, #bbb, #e0e0e0);
  opacity: 0.3;
  animation: eqIdle 2.5s ease-in-out infinite;
  animation-delay: calc(var(--i) * 0.12s);
  will-change: height, opacity;
  transition: opacity 0.4s ease;
}

@keyframes eqIdle { 0%,100%{height:5%} 50%{height:12%} }

.ap-equalizer.playing .eq-bar {
  opacity: 1;
  animation-delay: calc(var(--i) * 0.06s);
}
.ap-equalizer.playing .eq-bar:nth-child(7n+1) { animation: eqB1 0.75s ease-in-out infinite; animation-delay: calc(var(--i)*0.06s); }
.ap-equalizer.playing .eq-bar:nth-child(7n+2) { animation: eqB2 1.05s ease-in-out infinite; animation-delay: calc(var(--i)*0.06s); }
.ap-equalizer.playing .eq-bar:nth-child(7n+3) { animation: eqB3 0.65s ease-in-out infinite; animation-delay: calc(var(--i)*0.06s); }
.ap-equalizer.playing .eq-bar:nth-child(7n+4) { animation: eqB4 1.2s  ease-in-out infinite; animation-delay: calc(var(--i)*0.06s); }
.ap-equalizer.playing .eq-bar:nth-child(7n+5) { animation: eqB5 0.6s  ease-in-out infinite; animation-delay: calc(var(--i)*0.06s); }
.ap-equalizer.playing .eq-bar:nth-child(7n+6) { animation: eqB6 0.9s  ease-in-out infinite; animation-delay: calc(var(--i)*0.06s); }
.ap-equalizer.playing .eq-bar:nth-child(7n)   { animation: eqB7 1.1s  ease-in-out infinite; animation-delay: calc(var(--i)*0.06s); }

@keyframes eqB1 { 0%,100%{height:12%} 25%{height:75%} 50%{height:35%} 75%{height:55%} }
@keyframes eqB2 { 0%,100%{height:8%}  30%{height:90%} 60%{height:20%} 80%{height:60%} }
@keyframes eqB3 { 0%,100%{height:15%} 20%{height:50%} 50%{height:85%} 75%{height:35%} }
@keyframes eqB4 { 0%,100%{height:10%} 35%{height:65%} 55%{height:95%} 80%{height:28%} }
@keyframes eqB5 { 0%,100%{height:18%} 25%{height:80%} 50%{height:40%} 75%{height:70%} }
@keyframes eqB6 { 0%,100%{height:6%}  20%{height:60%} 45%{height:25%} 70%{height:82%} }
@keyframes eqB7 { 0%,100%{height:14%} 30%{height:45%} 55%{height:78%} 80%{height:22%} }

/* Reactive mode — JS drives bar heights from AnalyserNode on http://; disable CSS keyframes */
.ap-equalizer.reactive .eq-bar {
  animation: none !important;
  opacity: 1;
  transition: height 0.06s linear;
}

/* Player panel */
.ap-player-panel {
  background: rgba(60, 60, 70, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 16px;
  padding: 14px 22px 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.ap-progress-wrapper {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
}

.ap-time {
  font-weight: 600;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.7);
  min-width: 34px;
  text-align: center;
}

.ap-range {
  -webkit-appearance: none;
  flex: 1;
  height: 5px;
  background: rgba(255,255,255,0.2);
  border-radius: 3px;
  outline: none;
  cursor: pointer;
}
.ap-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 16px; height: 16px;
  background: #fff;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0,0,0,0.4);
  border: 2px solid rgba(255,255,255,0.8);
}

.ap-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
}

.ap-ctrl-btn {
  width: 44px; height: 44px;
  border-radius: 12px;
  border: 2px solid rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; outline: none;
  transition: background .2s, transform .2s;
}
.ap-ctrl-btn:hover { background: rgba(255,255,255,0.22); transform: scale(1.1); }
.ap-ctrl-btn:active { transform: scale(0.93); }
.ap-ctrl-btn svg { width: 22px; height: 22px; }

.ap-play-btn {
  width: 48px; height: 48px;
  border-radius: 12px;
  background: linear-gradient(135deg, #e0e0e0, #fff);
  border: 2px solid rgba(255,255,255,0.5);
  color: #333;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; outline: none;
  box-shadow: 0 6px 20px rgba(0,0,0,0.3);
  transition: transform .2s, box-shadow .2s;
}
.ap-play-btn:hover { transform: scale(1.08); box-shadow: 0 10px 26px rgba(0,0,0,0.4); }
.ap-play-btn:active { transform: scale(0.94); }
.ap-play-btn svg { width: 22px; height: 22px; }
.ap-icon-play { margin-left: 2px; }

.ap-vol-wrap { display: flex; align-items: center; gap: 5px; }
.ap-vol-icon { width: 24px; height: 24px; color: rgba(255,255,255,0.7); flex-shrink: 0; }
.ap-vol-slider { width: 70px; }
.ap-vol-pct {
  font-size: 11px; font-weight: 600;
  color: rgba(255,255,255,0.7);
  min-width: 32px; text-align: center;
}

/* Volume control colour overrides per player theme */
.tp-controls .ap-vol-icon { color: var(--clr-hs-tracks); }
.tp-controls .ap-vol-pct  { color: var(--clr-hs-tracks); }
.tp-controls .ap-vol-slider { accent-color: var(--clr-hs-tracks); }

.sp-controls .ap-vol-icon { color: var(--clr-hs-song); }
.sp-controls .ap-vol-pct  { color: var(--clr-hs-song); }
.sp-controls .ap-vol-slider { accent-color: var(--clr-hs-song); }


/* ── Song Player (karaoke style — grey/white theme) ── */
.media-wrapper.song-player-wrap {
  width: 100%;
  height: 100%;
  min-height: 360px;
  align-self: stretch;
}

.song-player {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.sp-track-selector {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
}

.sp-track-btn {
  padding: 6px 18px;
  border-radius: 100px;
  border: 2px solid rgba(255, 255, 255, 0.25);
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.6);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.sp-track-btn.active,
.sp-track-btn:hover {
  background: #fff;
  border-color: #fff;
  color: #1a1a2e;
}

.sp-lyrics-panel {
  min-height: 80px;
  max-height: 40vh;
  display: flex;
  flex-direction: column;
  background: rgba(60, 60, 70, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 16px;
  overflow: hidden;
}

.sp-player-panel { flex-shrink: 0; }

.sp-lyrics-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.4);
  padding: 12px 20px 6px;
  text-align: center;
}

.sp-lyrics-content {
  flex: 1;
  overflow-y: auto;
  padding: 10px 24px 20px;
  font-size: 17px;
  line-height: 2.2;
  color: rgba(255, 255, 255, 0.3);
  white-space: pre-wrap;
  text-align: center;
  scroll-behavior: smooth;
  /* Anchor the persistent .k-ball absolute position. */
  position: relative;
}
.sp-lyrics-content::-webkit-scrollbar { width: 4px; }
.sp-lyrics-content::-webkit-scrollbar-track { background: transparent; }
.sp-lyrics-content::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.2); border-radius: 2px; }

.sp-lyrics-content.karaoke-mode p {
  margin: 32px 0 0;            /* gap above each line — leaves room for the bouncing ball */
  padding: 6px 0;
  transition: color 0.3s, transform 0.3s, text-shadow 0.3s;
  position: relative;
}
.sp-lyrics-content.karaoke-mode p:first-child { margin-top: 0; }
.sp-lyrics-content.karaoke-mode p.prev { color: rgba(255, 255, 255, 0.3); }
.sp-lyrics-content.karaoke-mode p.active {
  color: #fff;
  font-weight: 700;
  font-size: 20px;
  transform: scale(1.05);
  text-shadow: 0 0 20px rgba(255, 255, 255, 0.4), 0 2px 8px rgba(0,0,0,0.4);
}

.k-word {
  position: relative;
  display: inline-block;
  transition: color 0.15s;
}
.k-word.k-sung { color: #fff; }

/* Single persistent ball — travels across lines and words via top/left. */
.k-ball {
  position: absolute;
  top: 0;
  left: 0;
  margin-top: -20px;           /* sits inside the 32px line-gap (16px clear above) */
  width: 12px;
  height: 12px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 0 14px rgba(255, 255, 255, 0.7), 0 0 28px rgba(255, 215, 0, 0.5);
  transform: translateX(-50%);
  transition:
    left 0.35s cubic-bezier(0.4, 0, 0.2, 1),
    top  0.45s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
  will-change: left, top, transform;
}
.k-ball.is-hopping {
  animation: karaokeHop 0.4s cubic-bezier(0.34, 1.2, 0.64, 1);
}
@keyframes karaokeHop {
  0%   { transform: translateX(-50%) translateY(0); }
  50%  { transform: translateX(-50%) translateY(-14px); }
  100% { transform: translateX(-50%) translateY(0); }
}

.sp-player-panel {
  background: rgba(60, 60, 70, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 16px;
  padding: 14px 22px 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.sp-mode-selector {
  display: flex;
  gap: 8px;
  justify-content: center;
}
.sp-mode-btn {
  padding: 5px 18px;
  border-radius: 100px;
  border: 2px solid rgba(255, 255, 255, 0.25);
  background: transparent;
  color: rgba(255, 255, 255, 0.6);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.sp-mode-btn.active,
.sp-mode-btn:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: #fff;
  color: #fff;
}

.sp-progress-wrap {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
}
.sp-time {
  font-size: 12px;
  font-weight: 600;
  color: rgba(255, 255, 255, 0.7);
  font-variant-numeric: tabular-nums;
  min-width: 34px;
  text-align: center;
}
.sp-time-tot { text-align: right; }
.sp-progress {
  -webkit-appearance: none;
  flex: 1;
  height: 5px;
  background: rgba(255,255,255,0.2);
  border-radius: 3px;
  outline: none;
  cursor: pointer;
}
.sp-progress::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 16px; height: 16px;
  background: #fff;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(0,0,0,0.4);
  border: 2px solid rgba(255,255,255,0.8);
}

.sp-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
}
.sp-ctrl-btn {
  width: 44px; height: 44px;
  border-radius: 12px;
  border: 2px solid rgba(255, 255, 255, 0.3);
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  outline: none;
  transition: background .2s, transform .2s;
}
.sp-ctrl-btn:hover { background: rgba(255,255,255,0.22); transform: scale(1.1); }
.sp-ctrl-btn:active { transform: scale(0.93); }
.sp-play-btn {
  width: 48px; height: 48px;
  border-radius: 12px;
  background: linear-gradient(135deg, #e0e0e0, #fff);
  border: 2px solid rgba(255,255,255,0.5);
  color: #333;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  outline: none;
  box-shadow: 0 6px 20px rgba(0,0,0,0.3);
  transition: transform .2s, box-shadow .2s;
}
.sp-play-btn:hover { transform: scale(1.08); box-shadow: 0 10px 26px rgba(0,0,0,0.4); }
.sp-play-btn:active { transform: scale(0.94); }

/* ── Tracks Player ── */
.tracks-player {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.tp-playlist {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 12px;
  max-height: 200px;
  overflow-y: auto;
  border-bottom: 1px solid var(--clr-modal-border);
}
.tp-playlist::-webkit-scrollbar { width: 4px; }
.tp-playlist::-webkit-scrollbar-track { background: transparent; }
.tp-playlist::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.12); border-radius: 2px; }

.tp-track-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 8px;
  border: none;
  background: transparent;
  color: var(--clr-text-dim);
  font-size: 13px;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.tp-track-item:hover { background: rgba(255,255,255,0.06); color: var(--clr-text); }
.tp-track-item.active { background: rgba(0,137,123,0.15); color: var(--clr-hs-tracks); font-weight: 600; }
.tp-track-icon { font-size: 11px; width: 16px; flex-shrink: 0; }

.tp-now-playing {
  padding: 8px 16px 4px;
  font-size: 12px;
  font-weight: 700;
  color: var(--clr-hs-tracks);
  text-align: center;
  min-height: 28px;
}

.tp-player-panel {
  padding: 8px 16px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.tp-progress-wrap {
  display: flex;
  align-items: center;
  gap: 8px;
}
.tp-time { font-size: 11px; color: var(--clr-text-dim); font-variant-numeric: tabular-nums; min-width: 32px; }
.tp-time-tot { text-align: right; }
.tp-progress {
  flex: 1;
  accent-color: var(--clr-hs-tracks);
  height: 4px;
  cursor: pointer;
}
.tp-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
}
.tp-ctrl-btn {
  background: none;
  border: none;
  color: var(--clr-text-dim);
  cursor: pointer;
  padding: 6px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s, background 0.15s;
}
.tp-ctrl-btn:hover { color: var(--clr-text); background: rgba(255,255,255,0.08); }
.tp-play-btn {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: none;
  background: var(--clr-hs-tracks);
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, transform 0.1s;
}
.tp-play-btn:hover { background: #00695c; transform: scale(1.05); }

/* ── Modal chooser mode (compact, auto-height for button list) ── */
#modalContainer.modal-chooser {
  height: auto;
  max-height: 80vh;
  width: min(520px, 90vw);
}

/* ── Modal fullscreen mode (for interactive/game activities) ── */
#modalContainer.modal-fullscreen {
  width: 100vw;
  max-height: 100vh;
  max-height: 100dvh;
  height: 100vh;
  height: 100dvh;
  border-radius: 0;
  border: none;
  box-shadow: none;
}

#modalContainer.modal-fullscreen .modal-header {
  display: none;
}

#modalContainer.modal-fullscreen #modalBody {
  flex: 1;
  overflow: hidden;
  padding: 0;
}

#modalContainer.modal-fullscreen .iframe-wrapper {
  height: 100%;
  min-height: 0;
}

#modalContainer.modal-fullscreen .activity-iframe {
  height: 100%;
  border-radius: 0;
}

/* ── Iframe ── */
.iframe-wrapper {
  width: 100%;
  position: relative;
  min-height: 480px;
}

.activity-iframe {
  width: 100%;
  height: 540px;
  border: none;
  border-radius: var(--rad-md);
  background: #fff;
  display: block;
  opacity: 0;
  transition: opacity 0.3s;
}

.activity-iframe.iframe-loaded {
  opacity: 1;
}

/* Loading state */
.iframe-loading {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  color: var(--clr-text-dim);
  font-size: 13px;
}

.spinner {
  width: 36px;
  height: 36px;
  border: 3px solid rgba(255,255,255,0.12);
  border-top-color: var(--clr-accent-light);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.iframe-error {
  color: #e57373;
  font-size: 13px;
  text-align: center;
  line-height: 1.6;
}

.iframe-error code {
  font-size: 11px;
  background: rgba(255,255,255,0.06);
  padding: 2px 6px;
  border-radius: 3px;
}

/* Fallback / unknown type */
.media-fallback {
  font-size: 12px;
  color: var(--clr-text-dim);
  margin-top: 8px;
  text-align: center;
}

.media-unknown {
  color: var(--clr-text-dim);
  font-size: 13px;
  text-align: center;
  padding: 40px 20px;
  line-height: 1.7;
}

.media-unknown code {
  font-size: 11px;
  background: rgba(255,255,255,0.06);
  padding: 2px 6px;
  border-radius: 3px;
}

/* ─── 14. Loading Overlay ───────────────────────────────────────────────────── */

#loadingOverlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  background: var(--clr-bg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  transition: opacity 0.4s;
}

#loadingOverlay.hidden {
  opacity: 0;
  pointer-events: none;
}

.loading-spinner {
  width: 48px;
  height: 48px;
  border: 4px solid rgba(255,255,255,0.1);
  border-top-color: var(--clr-accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

.loading-text {
  font-size: 14px;
  color: var(--clr-text-dim);
  letter-spacing: 0.04em;
}

.loading-progress-wrap {
  width: 280px;
  height: 8px;
  background: rgba(255,255,255,0.1);
  border-radius: 4px;
  overflow: hidden;
  margin-top: 4px;
}

.loading-progress-bar {
  width: 0%;
  height: 100%;
  background: var(--clr-accent);
  border-radius: 4px;
  transition: width 0.15s ease-out;
}

.loading-percent {
  font-size: 13px;
  color: var(--clr-text-dim);
  margin: 0;
  letter-spacing: 0.05em;
}

/* ─── 15. Utility / Accessibility ──────────────────────────────────────────── */

/* Screen-reader only text */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
}

/* Focus ring */
:focus-visible {
  outline: 2px solid var(--clr-accent-light);
  outline-offset: 2px;
}

/* Smooth scroll within modal body */
#modalBody {
  scroll-behavior: smooth;
}

/* ─── 15. Activity Chooser (multi-activity hotspot) ────────────────────────── */

.type-chooser {
  background: var(--clr-accent);
}

.chooser-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 16px;
  width: 100%;
  padding: 8px 0;
}

.chooser-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 28px 16px 20px;
  border: 2px solid var(--clr-modal-border);
  border-radius: var(--rad-lg, 12px);
  background: rgba(255, 255, 255, 0.04);
  color: var(--clr-text);
  cursor: pointer;
  transition: transform 0.18s ease, border-color 0.18s, box-shadow 0.18s, background 0.18s;
}

.chooser-card:hover {
  transform: translateY(-4px);
  border-color: var(--clr-accent);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
  background: rgba(255, 255, 255, 0.08);
}

.chooser-card:active {
  transform: translateY(-1px) scale(0.98);
}

/* Type-specific border accent on hover */
.chooser-type-video:hover       { border-color: var(--clr-hs-video); }
.chooser-type-audio:hover       { border-color: var(--clr-hs-audio); }
.chooser-type-interactive:hover { border-color: var(--clr-hs-interactive); }
.chooser-type-game:hover        { border-color: var(--clr-hs-game); }
.chooser-type-song:hover        { border-color: var(--clr-hs-song); }
.chooser-type-tracks:hover      { border-color: var(--clr-hs-tracks); }
.chooser-type-animation:hover   { border-color: var(--clr-hs-animation); }
.chooser-type-3d:hover          { border-color: var(--clr-hs-3d); }

.chooser-icon {
  width: 56px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.chooser-icon svg {
  width: 56px;
  height: 56px;
}

/* Type-specific icon colours */
.chooser-type-video .chooser-icon       { color: var(--clr-hs-video); }
.chooser-type-audio .chooser-icon       { color: var(--clr-hs-audio); }
.chooser-type-interactive .chooser-icon { color: var(--clr-hs-interactive); }
.chooser-type-game .chooser-icon        { color: var(--clr-hs-game); }
.chooser-type-song .chooser-icon        { color: var(--clr-hs-song); }
.chooser-type-tracks .chooser-icon      { color: var(--clr-hs-tracks); }
.chooser-type-animation .chooser-icon   { color: var(--clr-hs-animation); }
.chooser-type-3d .chooser-icon          { color: var(--clr-hs-3d); }

.chooser-label {
  font-size: 14px;
  font-weight: 600;
  text-align: center;
  line-height: 1.3;
}

.chooser-badge {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 100px;
  color: #fff;
}

/* Light theme overrides */
[data-theme="light"] .chooser-card {
  background: rgba(0, 0, 0, 0.02);
}

[data-theme="light"] .chooser-card:hover {
  background: rgba(0, 0, 0, 0.04);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
}

/* ═════════════════════════════════════════════════════════════════════════════
   SIDE MENU — Collapsible activity list
   ═════════════════════════════════════════════════════════════════════════════ */

.side-menu {
  position: fixed;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 800;
  font-family: 'Poppins', 'Segoe UI', sans-serif;
}

.side-menu-toggle {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 22px;
  height: 44px;
  background: rgba(233, 30, 99, 0.75);
  border: none;
  border-radius: 0 7px 7px 0;
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 2px 2px 8px rgba(0,0,0,0.25);
  transition: background 0.2s, width 0.2s;
  z-index: 802;
  -webkit-tap-highlight-color: transparent;
}
.side-menu-toggle svg { width: 12px; height: 12px; }
.side-menu-toggle:hover { background: rgba(233, 30, 99, 1); width: 26px; }
.side-menu.open .side-menu-toggle { display: none; }

.side-menu-panel {
  position: absolute;
  left: -320px;
  top: 50%;
  transform: translateY(-50%);
  width: 300px;
  max-height: 80vh;
  background: var(--clr-surface, #1e1e2e);
  border-radius: 0 16px 16px 0;
  box-shadow: 4px 0 24px rgba(0,0,0,0.4);
  display: flex;
  flex-direction: column;
  transition: left 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
}
.side-menu.open .side-menu-panel { left: 0; }

.side-menu-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  background: rgba(233, 30, 99, 0.15);
  border-bottom: 1px solid rgba(255,255,255,0.08);
  flex-shrink: 0;
}
.side-menu-header span {
  font-weight: 700;
  font-size: 14px;
  color: var(--clr-text, #eee);
}
.side-menu-close {
  background: none;
  border: none;
  color: var(--clr-text, #eee);
  font-size: 22px;
  cursor: pointer;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
  -webkit-tap-highlight-color: transparent;
}
.side-menu-close:hover { background: rgba(255,255,255,0.1); }

.side-menu-list {
  overflow-y: auto;
  flex: 1;
  padding: 8px 0;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.side-menu-list::-webkit-scrollbar { width: 4px; }
.side-menu-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.15); border-radius: 2px; }

/* Group headers (Bidang 1, Bidang 2, etc.) */
.smenu-group {
  padding: 10px 16px 4px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: rgba(233, 30, 99, 0.8);
}

/* Activity item */
.smenu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  cursor: pointer;
  border: none;
  background: none;
  width: 100%;
  text-align: left;
  color: var(--clr-text, #eee);
  font-family: inherit;
  font-size: 13px;
  transition: background 0.15s;
  -webkit-tap-highlight-color: transparent;
}
.smenu-item:hover { background: rgba(255,255,255,0.06); }
.smenu-item:active { background: rgba(233, 30, 99, 0.15); }

/* Type icon badge */
.smenu-icon {
  width: 28px;
  height: 28px;
  border-radius: 7px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.smenu-icon svg {
  width: 16px;
  height: 16px;
  stroke: #fff;
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.smenu-icon.type-video       { background: var(--clr-hs-video); }
.smenu-icon.type-audio       { background: var(--clr-hs-audio); }
.smenu-icon.type-interactive { background: var(--clr-hs-interactive); }
.smenu-icon.type-game        { background: var(--clr-hs-game); }
.smenu-icon.type-song        { background: var(--clr-hs-song); }
.smenu-icon.type-tracks      { background: var(--clr-hs-tracks); }
.smenu-icon.type-animation   { background: var(--clr-hs-animation); }
.smenu-icon.type-3d          { background: var(--clr-hs-3d); }
.smenu-icon.type-multiple    { background: var(--clr-hs-multiple); }

.smenu-label { flex: 1; line-height: 1.3; }
.smenu-page {
  font-size: 11px;
  color: rgba(255,255,255,0.35);
  flex-shrink: 0;
}

/* Light theme overrides */
html.light-mode .side-menu-panel {
  background: #fff;
  box-shadow: 4px 0 24px rgba(0,0,0,0.12);
}
html.light-mode .side-menu-header {
  background: rgba(233, 30, 99, 0.08);
  border-bottom-color: rgba(0,0,0,0.08);
}
html.light-mode .side-menu-header span { color: #222; }
html.light-mode .side-menu-close { color: #333; }
html.light-mode .side-menu-close:hover { background: rgba(0,0,0,0.06); }
html.light-mode .smenu-group { color: #E91E63; }
html.light-mode .smenu-item { color: #222; }
html.light-mode .smenu-item:hover { background: rgba(0,0,0,0.04); }
html.light-mode .smenu-item:active { background: rgba(233, 30, 99, 0.1); }
html.light-mode .smenu-page { color: rgba(0,0,0,0.35); }
html.light-mode .side-menu-list::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.12); }
