/* =============================================================================
   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 splash
    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.
   Sits inside #bookZoomWrap which provides the scrollable/pannable
   overflow area when the book is zoomed in. */
.book-zoom-wrap {
  flex: 1 1 auto;
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow: hidden;
  width: 100%;
  touch-action: none;   /* pointer events handle panning when zoomed */
}

.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;
}

/* ── Zoom & pan (state applied by flipbook.js via ONE transform) ───────── */

/* Zoom + pan are rendered as a single transform on the spread:
     translate3d(panX, panY, 0) scale(zoom)
   The zoom wrapper (overflow hidden) clips whatever exceeds the book area.
   Pan is clamped so the page edge aligns exactly with the viewport edge at
   the limit — zoomed content at every edge stays readable. Drag-to-flip is
   suppressed while zoomed; dragging pans the view instead. */
.book-spread.is-zoomed {
  cursor: grab;
  transition: transform 0.28s cubic-bezier(0.25, 0.7, 0.3, 1);
  will-change: transform;
}
.book-spread.is-zoomed.is-panning {
  cursor: grabbing;
  transition: none;    /* follow the pointer 1:1 while dragging */
}

/* ── Phone / portrait screens → single-page view ─────────────────────────── */
/* Narrow the design canvas and the spread to ONE page. StPageFlip (usePortrait)
   detects the container < 2×page-width on resize and switches to portrait mode
   by itself: one page per flip, page preserved across the transition. */
@media (orientation: portrait) {
  :root {
    --viewer-w: 548px;   /* one page (476) + side padding, keeps page size */
    --page-w:   476px;   /* exactly one page → spread = page, page at [0,476] */
    /* Two-line title bar is ~67px tall (measured) — reserve 72px and grow the
       viewer so page (664) + bars fit, otherwise the page bottom is clipped */
    --viewer-h: 780px;
    --titlebar-h: 72px;
    --navbar-h:  44px;
  }
  .book-spread {
    width: var(--page-w);
  }
  /* Single page occupies the whole spread — one hotspot layer across it */
  #hsOverlayLeft  { display: none; }
  #hsOverlayRight { left: 0; width: 100%; }

  /* ── Compact title bar: TWO lines — titles on TOP, controls below ── */
  #bookTitleBar {
    flex: 0 0 auto;
    height: auto;
    flex-direction: row;          /* one controls row … */
    justify-content: space-between;
    align-items: center;
    gap: 6px;
    padding: 28px 10px 4px;       /* … with the title line reserved above */
  }
  /* titles are NESTED inside .titlebar-left, so flex order can't promote
     them to the bar's first row — pin them to the top line instead */
  .titlebar-titles {
    position: absolute;
    top: 3px;
    left: 50%;
    transform: translateX(-50%);
    flex-direction: row;          /* title + subtitle side by side */
    align-items: baseline;
    gap: 8px;
    max-width: 96%;
    white-space: nowrap;
  }
  .titlebar-left .back-btn span { display: none; }   /* "Kembali" text off */
  .titlebar-left .back-btn { padding: 3px 6px; }
  #bookTitleBar .title-logo { display: none; }
  #bookTitleText {
    font-size: 13px !important;
    max-width: 55vw;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  #bookSubtitleText { display: inline; font-size: 11px !important; }
  .company-name { display: none; }                 /* saves the most space */
  /* controls row: flex items, no absolute centring (overlap source) */
  .zoom-controls {
    position: static !important;
    transform: none !important;
  }
  /* equal side columns → the zoom pill sits dead-centre of the controls row,
     mirroring the centred page indicator in the bottom bar */
  .titlebar-left  { flex: 1 1 0; }
  .titlebar-right { flex: 1 1 0; justify-content: flex-end; }
  .titlebar-icon-btn { width: 30px; height: 30px; }
  .titlebar-icon-btn svg { width: 15px; height: 15px; }
  .zoom-btn { width: 24px !important; height: 24px !important; }
  .zoom-btn svg { width: 14px !important; height: 14px !important; }
  .zoom-level { display: none; }                        /* % label hidden */

  /* ── Compact nav bar: small icon-only Prev/Next ──
     (!important: base .nav-btn/.zoom-btn rules appear LATER in this file and
     would otherwise win the cascade at equal specificity) */
  .nav-btn { padding: 5px 9px !important; min-width: 0 !important; }
  .nav-btn .nav-label { display: none; }   /* "Sebelumnya"/"Seterusnya" text off */
  .nav-btn svg { width: 15px; height: 15px !important; }
  .nav-side-btn { padding: 4px 6px !important; }
  .nav-side-btn svg { width: 13px; height: 13px !important; }

  /* ── Page indicator: dead-centre of the bar (base rule is absolute;
     buttons are compact now, so centring no longer overlaps them) ── */
  .page-indicator {
    position: absolute !important;
    left: 50% !important;
    top: 50% !important;
    transform: translate(-50%, -50%) !important;
    gap: 4px;
  }
  .page-input {
    width: 64px !important;        /* fixed — auto inputs balloon and eat the bar */
    min-width: 64px !important;
    max-width: 64px !important;
    font-size: 12px !important;
    padding: 3px 4px !important;
  }
  .nav-grid-btn { padding: 4px !important; }
  .nav-grid-btn svg { width: 16px !important; height: 16px !important; }
}

/* ── Titlebar zoom controls (centre of the title bar) ───────────────────── */

.zoom-controls {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  z-index: 30;
}

.zoom-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 6px;
  color: var(--clr-text-dim);
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.18s, color 0.18s;
}
.zoom-btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
}
.zoom-btn:active:not(:disabled) {
  transform: scale(0.94);
}
.zoom-btn:disabled {
  opacity: 0.3;
  cursor: default;
  pointer-events: none;
}
.zoom-btn svg {
  width: 15px;
  height: 15px;
}

.zoom-level {
  min-width: 44px;
  text-align: center;
  font-size: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--clr-text);
  opacity: 0.85;
  cursor: pointer;
  user-select: none;
}
.zoom-level:hover {
  opacity: 1;
}

html.light-mode .zoom-controls {
  background: rgba(0, 0, 0, 0.05);
  border-color: rgba(0, 0, 0, 0.12);
}
html.light-mode .zoom-btn {
  color: #3a3a5a;
}
html.light-mode .zoom-btn:hover:not(:disabled) {
  background: rgba(0, 0, 0, 0.12);
  color: #1a1a3e;
}

/* ─── 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 — always dead-centre of the nav bar, regardless of the
   widths of the buttons around it (grid button added in v3.0) */
.page-indicator {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--clr-text-dim);
  justify-content: center;
  white-space: nowrap;
}

.page-indicator .sep    { color: var(--clr-text-dim); }
.page-indicator .sep-of { font-size: 11px; font-weight: 400; }

.page-input {
  width: auto;              /* grow to fit named pages (Kulit Hadapan…) */
  min-width: 52px;
  max-width: 150px;
  padding: 4px 10px;
  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;
}

/* ── Thumbnail grid button (in the bottom nav bar) ─────────────────────── */

.nav-grid-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  margin-left: auto;           /* keep grid + Seterusnya as the right cluster */
  background: var(--clr-accent);
  color: #fff;
  border-radius: var(--rad-md);
  transition: background 0.18s, transform 0.1s;
  flex-shrink: 0;
}

.nav-grid-btn:hover {
  background: var(--clr-accent-dark);
  transform: translateY(-1px);
}

.nav-grid-btn:active {
  transform: translateY(0);
}

.nav-grid-btn svg {
  width: 20px;
  height: 20px;
}

.nav-grid-btn[aria-expanded="true"] {
  background: var(--clr-accent-dark);
}

html.light-mode .nav-grid-btn {
  background: var(--clr-accent);
  color: #fff;
}

/* ─── 10b. Page Thumbnail Overlay (bottom sheet) ───────────────────────── */

/* ─── 10b. Page Thumbnail Grid Overlay ─────────────────────────────────── */

/* Keep the bottom nav bar above the thumbnail backdrop so the grid button
   stays visible and clickable while the overlay is open (click again = close) */
.book-nav {
  position: relative;
  z-index: 860;
}

.thumb-overlay {
  position: absolute;
  inset: 0;
  z-index: 850;                 /* above side menu (800) but below modal (1000) */
  pointer-events: none;         /* closed: fully click-through */
  visibility: hidden;
  transition: visibility 0s 0.3s;
}

.thumb-overlay.open {
  pointer-events: auto;
  visibility: visible;
  transition: visibility 0s;
}

.thumb-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  opacity: 0;
  transition: opacity 0.28s ease;
  will-change: opacity;
}

.thumb-overlay.open .thumb-backdrop {
  opacity: 1;
}

/* Full flipbook height: below the title bar, above the bottom nav bar.
   The slide is GPU-composited (transform + opacity only, own layer) so it
   never drops frames — no layout, paint, or image decode mid-animation. */
.thumb-panel {
  position: absolute;
  top: var(--titlebar-h);
  bottom: var(--navbar-h);
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  background: var(--clr-bg2);
  box-shadow: 0 -12px 40px rgba(0, 0, 0, 0.5);
  transform: translate3d(0, 100%, 0);   /* off-screen, own GPU layer */
  visibility: hidden;
  transition: transform 0.32s cubic-bezier(0.32, 0.72, 0.25, 1), visibility 0s 0.32s;
  will-change: transform;
  overflow: hidden;
}

.thumb-overlay.open .thumb-panel {
  transform: translate3d(0, 0, 0);
  visibility: visible;
  transition: transform 0.32s cubic-bezier(0.32, 0.72, 0.25, 1), visibility 0s;
}

.thumb-header {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  font-size: 13px;
  font-weight: 700;
  color: var(--clr-text);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.thumb-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  background: rgba(255, 255, 255, 0.08);
  border: none;
  border-radius: 6px;
  color: var(--clr-text-dim);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.18s, color 0.18s;
}

.thumb-close:hover {
  background: rgba(255, 255, 255, 0.18);
  color: #fff;
}

/* The grid: fixed-height rows, columns sized to the page ratio.
   Fixed grid-auto-rows guarantees tiles can never stack/overlap —
   every tile is exactly one cell. */
.thumb-grid {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  grid-auto-rows: 196px;        /* fixed row height = uniform grid */
  gap: 14px;
  padding: 16px 20px;
  overflow-y: auto;
  overscroll-behavior: contain;
  touch-action: pan-y;
  -webkit-overflow-scrolling: touch;
  align-content: start;
}

/* One page per tile, filling its cell completely */
.thumb-item {
  position: relative;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 2px solid rgba(255, 255, 255, 0.12);
  border-radius: var(--rad-md);
  overflow: hidden;
  background: var(--clr-page-bg);
  cursor: pointer;
  transition: border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}

.thumb-item:hover {
  border-color: var(--clr-accent-light);
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.35);
}

.thumb-item.is-current {
  border-color: var(--clr-accent);
  box-shadow: 0 0 0 2px rgba(109, 174, 232, 0.35);
}

/* Image fits inside the fixed tile — whole page always visible */
.thumb-item img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  pointer-events: none;
  user-select: none;
  content-visibility: auto;     /* decode off-screen tiles lazily */
  contain-intrinsic-size: 140px 196px;
}

.thumb-num {
  position: absolute;
  bottom: 4px;
  right: 4px;
  padding: 1px 6px;
  background: rgba(0, 0, 0, 0.65);
  border-radius: 4px;
  font-size: 10px;
  font-weight: 700;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

/* light theme */
html.light-mode .thumb-panel {
  background: #f2f2f7;
}
html.light-mode .thumb-header {
  color: #1a1a3e;
  border-bottom-color: rgba(0, 0, 0, 0.08);
}
html.light-mode .thumb-item {
  border-color: rgba(0, 0, 0, 0.15);
}
html.light-mode .thumb-num {
  background: rgba(0, 0, 0, 0.55);
}
html.light-mode .thumb-close {
  background: rgba(0, 0, 0, 0.08);
  color: #3a3a5a;
}
html.light-mode .thumb-close:hover {
  background: rgba(0, 0, 0, 0.16);
  color: #1a1a3e;
}

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 — sized by the button, which is sized from config.js hotspotDefaults */
.hs-image {
  display: block;
  width:  100%;
  height: 100%;
  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) ── */
/* Overlay padding must collapse too, or the fullscreen container sits in a
   24px-inset box and slivers of the book show around the activity. */
#modal.modal-fullscreen {
  padding: 0;
}

#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 ── */
/* Floating close overlay for iframe activities — always present so the user
   can return to the flipbook even if the activity has no close button of
   its own. Hidden automatically by activity-loader.js when the activity
   ships #close-activity-btn. */
.iframe-ext-close {
  position: absolute;
  top: max(10px, env(safe-area-inset-top, 10px));
  right: max(10px, env(safe-area-inset-right, 10px));
  width: 40px;
  height: 40px;
  border-radius: 12px;
  border: 1.5px solid rgba(255,255,255,0.35);
  background: rgba(211,47,47,0.75);
  box-shadow: 0 4px 16px rgba(229,57,53,0.4), inset 0 1px 0 rgba(255,255,255,0.25);
  color: #fff;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: border-color .25s ease, box-shadow .25s ease, transform .15s ease;
  z-index: 20;
  -webkit-tap-highlight-color: transparent;
}
.iframe-ext-close:hover {
  border-color: rgba(255,255,255,0.55);
  box-shadow: 0 4px 20px rgba(211,47,47,0.4), inset 0 1px 0 rgba(255,255,255,0.3);
}
.iframe-ext-close:active { transform: scale(0.93); }
.iframe-ext-close svg { width: 22px; height: 22px; }

.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 Splash ───────────────────────────────────────────────── */
/* All splash styling (logos, divider, progress bar, teardown state) lives
   INLINE in index.html so the splash never depends on this file loading.
   Do not reintroduce splash rules here — they lose the cascade to the
   inline styles and drift out of sync. */

/* ─── 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); }
