Table of Contents

    Miscellaneous

    
    
    <pre><xmp>
    
    <?php require_once __DIR__ . '/../partials/header.php'; ?>
    <?php require_once __DIR__ . '/../partials/sidebar.php'; ?>
     
    <link href="https://cdn.jsdelivr.net/npm/prismjs/themes/prism-okaidia.min.css" rel="stylesheet" />
    <link href="https://fonts.googleapis.com/css2?family=Hind+Siliguri:wght@400;500;600;700&display=swap" rel="stylesheet">
    
    <script src="https://cdn.jsdelivr.net/npm/prismjs/prism.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-java.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-php.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-javascript.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-markup.min.js"></script>
     
    
     <script>if (window.Prism) {
        Prism.highlightAll();
    }</script>
    
    <style>
    :root{
        --presentation-sidebar-width: 62px;
        --presentation-panel-bg: var(--card-bg, var(--bs-body-bg, #ffffff));
        --presentation-page-bg: var(--bg-color, var(--bs-body-bg, #f6f8fb));
        --presentation-text: var(--text-color, var(--bs-body-color, #1f2937));
        --presentation-text-soft: var(--text-color-secondary, #6b7280);
        --presentation-border: var(--border-color, rgba(0,0,0,0.08));
        --presentation-shadow: 0 12px 35px rgba(0,0,0,0.08);
        --presentation-primary: var(--link-color, #0d6efd);
        --presentation-primary-hover: var(--link-hover-color, #0b5ed7);
        --presentation-sidebar-bg: var(--header-footer-bg, #111827);
        --presentation-sidebar-text: #ffffff;
        --presentation-success-bg: rgba(25, 135, 84, 0.10);
        --presentation-danger-bg: rgba(220, 53, 69, 0.10);
        --presentation-warning-bg: rgba(255, 193, 7, 0.12);
        /*--presentation-gradient-1: linear-gradient(135deg, rgba(13,110,253,0.10), rgba(111,66,193,0.12));*/
        --presentation-gradient-2: linear-gradient(135deg, rgb(63 100 53 / 92%), rgb(91 103 9 / 88%));
         --presentation-font-scale: 1;
    }
    
    .presentation-stage-title-wrap h2,
    .presentation-stage-subtitle,
    .presentation-pointer-title,
    .presentation-explanation-editor,
    .presentation-mobile-sheet-body {
        text-rendering: optimizeLegibility;
        -webkit-font-smoothing: antialiased;
    }
    
    .presentation-pointer-title pre,
    .presentation-explanation-editor pre,
    .presentation-mobile-sheet-body pre {
        margin: 12px 0 0;
        padding: 16px 18px;
        border-radius: 14px;
        overflow-x: auto;
        border: 1px solid rgba(255,255,255,0.08);
        box-shadow: inset 0 1px 0 rgba(255,255,255,0.04);
    }
    
    .presentation-pointer-title code,
    .presentation-explanation-editor code,
    .presentation-mobile-sheet-body code {
        font-family: Consolas, Monaco, 'Fira Code', monospace;
        font-size: 0.92rem;
        line-height: 1.7;
    }
    
    .presentation-explanation-editor {
        overflow: auto;
    }
    
    .presentation-explanation-editor pre[class*="language-"] {
        margin: 0;
    }
    
    .presentation-pointer-title pre[class*="language-"],
    .presentation-explanation-editor pre[class*="language-"],
    .presentation-mobile-sheet-body pre[class*="language-"] {
        background: transparent !important;
    }
    
    
    
     
    .presentation-stage::after {
        content: "";
        position: absolute;
        inset: 0;
        border-radius: 22px;
        box-shadow: 0 0 0 1px rgba(13,110,253,0.08),
                    0 20px 60px rgba(13,110,253,0.12);
        pointer-events: none;
    }
     
    .presentation-pointer-item.show {
        animation: slideFadeIn 0.5s ease forwards;
    }
    
    @keyframes slideFadeIn {
        from {
            opacity: 0;
            transform: translateY(25px) scale(0.96);
        }
        to {
            opacity: 1;
            transform: translateY(0) scale(1);
        }
    }
    
    .presentation-pointer-list.focus-mode .presentation-pointer-item {
        opacity: 0.3;
        transform: scale(0.98);
    }
    
    .presentation-pointer-list.focus-mode .presentation-pointer-item.active {
        opacity: 1;
        transform: scale(1.02);
        background: rgba(13,110,253,0.12);
    }
    
    .presentation-page-shell {
        padding: 18px;
        background: var(--presentation-page-bg);
        color: var(--presentation-text);
        min-height: calc(100vh - 100px);
    }
    
    .presentation-stage-actions {
        position: sticky;
        bottom: 10px;
        background: rgba(255,255,255,0.85);
        backdrop-filter: blur(10px);
        border-radius: 14px;
        padding: 8px 10px;
        box-shadow: 0 10px 30px rgba(0,0,0,0.12);
        display: none;
        gap: 6px;
        align-items: center;
        flex-wrap: wrap;
        justify-content: flex-end;
        margin-left: auto;
    } 
    
    .presentation-top-card {
        background: var(--presentation-panel-bg);
        border: 1px solid var(--presentation-border);
        border-radius: 22px;
        box-shadow: var(--presentation-shadow);
        padding: 18px;
        margin-bottom: 16px;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-top-card {
        display: none !important;
    }
    
    .presentation-top-grid {
        display: grid;
        grid-template-columns: 1.5fr 1fr;
        gap: 16px;
        align-items: center;
    }
    
    .presentation-title {
        font-size: 1.35rem;
        font-weight: 800;
        margin: 0 0 6px 0;
        color: var(--presentation-text);
    }
    
    .presentation-subtitle {
        margin: 0;
        color: var(--presentation-text-soft);
        font-size: 0.95rem;
        line-height: 1.75;
    }
    
    .presentation-upload-wrap {
        display: flex;
        flex-wrap: wrap;
        gap: 10px;
        align-items: center;
        justify-content: flex-end;
    }
    
    .presentation-file-input {
        min-width: 220px;
        max-width: 100%;
        padding: 11px 12px;
        border-radius: 12px;
        border: 1px solid var(--presentation-border);
        background: var(--presentation-panel-bg);
        color: var(--presentation-text);
        outline: none;
    }
    
    .presentation-btn {
        border: 0;
        outline: none;
        border-radius: 12px;
        padding: 11px 16px;
        font-weight: 700;
        cursor: pointer;
        transition: all 0.22s ease;
        box-shadow: 0 8px 18px rgba(0,0,0,0.06);
    }
    
    .presentation-btn-primary {
        background: var(--presentation-primary);
        color: #fff;
    }
    
    .presentation-btn-primary:hover {
        background: var(--presentation-primary-hover);
        transform: translateY(-1px);
    }
    
    .presentation-btn-light {
        background: var(--presentation-panel-bg);
        color: var(--presentation-text);
        border: 1px solid var(--presentation-border);
    }
    
    .presentation-btn-light:hover {
        transform: translateY(-1px);
    }
    
    .presentation-template-note {
        margin-top: 10px;
        color: var(--presentation-text-soft);
        font-size: 0.86rem;
        line-height: 1.7;
    }
    
    .presentation-feedback {
        display: none;
        margin-top: 12px;
        border-radius: 12px;
        padding: 11px 13px;
        font-size: 0.9rem;
        border: 1px solid transparent;
    }
    
    .presentation-feedback.show {
        display: block;
    }
    
    .presentation-feedback.success {
        background: var(--presentation-success-bg);
        border-color: rgba(25, 135, 84, 0.18);
    }
    
    .presentation-feedback.error {
        background: var(--presentation-danger-bg);
        border-color: rgba(220, 53, 69, 0.18);
    }
    
    .presentation-feedback.warning {
        background: var(--presentation-warning-bg);
        border-color: rgba(255, 193, 7, 0.18);
    }
    
    .presentation-main {
        display: grid;
        grid-template-columns: var(--presentation-sidebar-width) minmax(0, 1fr);
        gap: 14px;
        align-items: stretch;
    }
    
    .presentation-sidebar {
        background: var(--presentation-sidebar-bg);
        color: var(--presentation-sidebar-text);
        border-radius: 18px;
        padding: 10px 8px;
        min-height: 620px;
        box-shadow: var(--presentation-shadow);
        position: sticky;
        top: 88px;
        z-index: 9;
    }
    
    .presentation-sidebar-title {
        text-align: center;
        font-size: 0.72rem;
        opacity: 0.8;
        margin-bottom: 8px;
        font-weight: 700;
        letter-spacing: 0.3px;
    }
    
    .presentation-slide-nav {
        display: flex;
        flex-direction: column;
        gap: 8px;
        max-height: calc(100vh - 160px);
        overflow-y: auto;
        padding-right: 1px;
    }
    
    .presentation-slide-nav::-webkit-scrollbar {
        width: 4px;
    }
    
    .presentation-slide-nav::-webkit-scrollbar-thumb {
        background: rgba(255,255,255,0.18);
        border-radius: 999px;
    }
    
    .presentation-slide-nav-btn {
        width: 100%;
        min-height: 38px;
        border: 1px solid var(--border-color);
        border-radius: 10px;
        background: var(--hover-bg);
        color: var(--text-color);
        font-weight: 700;
        font-size: 0.82rem;
        padding: 8px 6px;
        cursor: pointer;
        transition: all 0.25s ease;
    }
    
    /* Hover + Active */
    .presentation-slide-nav-btn:hover,
    .presentation-slide-nav-btn.active {
        background: var(--link-color);
        color: #fff;
        border-color: var(--link-color);
        transform: translateY(-1px);
        box-shadow: 0 4px 12px var(--shadow-color);
    }
    
    .presentation-stage-frame {
        min-width: 0;
    }
    
    .presentation-workspace {
        display: grid;
        grid-template-columns: minmax(0, 1.42fr) minmax(320px, 0.58fr);
        gap: 14px;
    }
    
    .presentation-stage,
    .presentation-explanation-panel {
        background: var(--presentation-panel-bg);
        border: 1px solid var(--presentation-border);
        border-radius: 22px;
        box-shadow: var(--presentation-shadow);
    }
    
    .presentation-stage {
        padding: 18px;
        min-height: 620px;
        display: flex;
        flex-direction: column;
        position: relative;
        overflow: hidden;
        justify-content: flex-start;
        background:
        radial-gradient(circle at top right, rgba(13,110,253,0.10), transparent 35%),
        radial-gradient(circle at bottom left, rgba(34,197,94,0.08), transparent 35%),
        var(--presentation-panel-bg);
    }
    
    .presentation-stage::before {
        content: "";
        position: absolute;
        inset: 0 0 auto 0;
        height: 160px;
        background: var(--presentation-gradient-1);
        pointer-events: none;
    }
    
    .presentation-stage > * {
        position: relative;
        z-index: 1;
    }
    
    .presentation-stage-header {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        gap: 12px;
        align-items: start;
        margin-bottom: 30px;
        padding-bottom: 22px;
        border-bottom: 1px solid var(--presentation-border);
    }
    
    .presentation-stage-title-wrap {
        min-width: 0;
    }
    
    .presentation-stage-title-wrap h2 {
        font-size: 1.85rem;
        margin: 0 0 1px 0;
        font-weight: 900;
        color: var(--presentation-text);
        line-height: 1.25;
        word-break: break-word;
        letter-spacing: -0.02em;
    }
    
    .presentation-stage-subtitle {
        color: var(--presentation-text-soft);
        font-size: 1.08rem;
        line-height: 1.1;
        margin-bottom: 1px;
        word-break: break-word;
        font-weight: 600;
    }
    
    .presentation-stage-meta {
        color: var(--presentation-text-soft);
        font-size: 0.84rem;
    }
    
    .presentation-presentation-info {
        display: none;
        /*background: var(--presentation-gradient-2);*/
        color: #183d22;
        border-radius: 18px;
        padding: 16px 18px;
        margin-bottom: 16px;
        box-shadow: 0 10px 24px rgba(13,110,253,0.15);
        
    }
    
    .presentation-presentation-info.show {
        display: block;
    }
    
    .presentation-presentation-title {
        font-size: 1.12rem;
        font-weight: 900;
        margin-bottom: 10px;
        letter-spacing: 0.01em;
        padding: 120px 90px 80px
    }
    
    .presentation-presentation-meta-grid {
        display: grid;
        grid-template-columns: repeat(4, minmax(0, 1fr));
        gap: 10px;
         position: relative;
        z-index: 2;
    }
    
    .presentation-presentation-meta-card {
        /*background: rgba(255,255,255,0.12);*/
        /*border: 1px solid rgba(255,255,255,0.18);*/
        border-radius: 14px;
        padding: 10px 12px;
        min-height: 68px;
        
        backdrop-filter: blur(12px);
        background: rgba(255,255,255,0.08);
        border: 1px solid rgba(255,255,255,0.15);
    }
    
    .presentation-presentation-meta-label {
        font-size: 0.72rem;
        text-transform: uppercase;
        letter-spacing: 0.08em;
        opacity: 0.86;
        margin-bottom: 4px;
        font-weight: 700;
    }
    
    .presentation-presentation-meta-value {
        font-size: 0.96rem;
        line-height: 1.55;
        font-weight: 700;
        word-break: break-word;
    }
    
    .presentation-stage-actions.show {
        display: flex;
    }
     
    .presentation-icon-btn {
        width: 30px;
        height: 30px;
        min-width: 30px;
        border-radius: 8px;
        padding: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 0.86rem;
        border: 1px solid var(--presentation-border);
        background: var(--presentation-panel-bg);
        color: var(--presentation-text);
        cursor: pointer;
        transition: all 0.18s ease;
        box-shadow: 0 4px 12px rgba(0,0,0,0.05);
    }
    
    .presentation-icon-btn:hover {
        transform: translateY(-1px);
        border-color: rgba(13,110,253,0.22);
        color: var(--presentation-primary);
    }
    
    .presentation-icon-btn.primary {
        background: var(--presentation-primary);
        border-color: var(--presentation-primary);
        color: #fff;
    }
    
    .presentation-icon-btn.primary:hover {
        background: var(--presentation-primary-hover);
        color: #fff;
    }
    
    .presentation-layout-mini-group {
        display: none;
        gap: 6px;
        align-items: center;
        margin-right: 4px;
    }
    
    .presentation-layout-mini-group.show {
        display: flex;
    }
    
    .presentation-layout-mini-btn {
        border: 1px solid var(--presentation-border);
        background: var(--presentation-panel-bg);
        color: var(--presentation-text);
        border-radius: 8px;
        width: 30px;
        height: 30px;
        min-width: 30px;
        padding: 0;
        font-size: 0.72rem;
        font-weight: 900;
        cursor: pointer;
        transition: all 0.18s ease;
        box-shadow: 0 4px 12px rgba(0,0,0,0.05);
    }
    
    .presentation-layout-mini-btn.active,
    .presentation-layout-mini-btn:hover {
        background: var(--presentation-primary);
        color: #fff;
        border-color: var(--presentation-primary);
    }
    
    .presentation-content-area {
        display: flex;
        flex-direction: column;
        gap: 18px;
        flex: 1;
        min-height: 320px;
        justify-content: flex-start;
    }
    
    .presentation-active-view {
        display: grid;
        gap: 14px;
        min-height: 0;
        flex: 1;
    }
    
    .presentation-active-view.layout-top {
        grid-template-columns: 1fr;
        grid-template-rows: auto 1fr;
    }
    
    .presentation-active-view.layout-left {
        grid-template-columns: minmax(260px, 42%) minmax(0, 1fr);
        grid-template-rows: 1fr;
        align-items: start;
    }
    
    .presentation-active-view.layout-right {
        grid-template-columns: minmax(0, 1fr) minmax(260px, 42%);
        grid-template-rows: 1fr;
        align-items: start;
    }
    
     /* =========================================
       SPOT MODE: IMAGE LEFT + POINTER RIGHT
    ========================================= */
    
    .presentation-active-view.spotlight-mode {
        display: grid;
        grid-template-columns: minmax(0, 1.15fr) minmax(360px, 0.85fr) !important;
        grid-template-rows: 1fr !important;
        gap: 20px;
        min-height: 560px;
        align-items: stretch;
    }
    
    .presentation-active-view.spotlight-mode .presentation-active-media-box {
        display: flex !important;
        height: 100%;
        min-height: 520px;
        max-height: none;
        background:
            radial-gradient(circle at top right, rgba(13,110,253,0.10), transparent 35%),
            linear-gradient(135deg, rgba(15,23,42,0.04), rgba(34,197,94,0.06));
        border-radius: 28px;
        padding: 16px;
        border: 1px solid var(--presentation-border);
    }
    
    .presentation-active-view.spotlight-mode .presentation-active-media-box img {
        width: 100%;
        height: 100%;
        object-fit: contain;
        filter: none !important;
        opacity: 1 !important;
    }
    
    .presentation-active-view.spotlight-mode .presentation-pointer-list {
        width: 100% !important;
        display: flex !important;
        /*align-items: center;*/
        justify-content: center;
        padding: 0;
        align-items: flex-start !important;
        justify-content: center;
        padding-top: 455px;
    }
    
    .presentation-active-view.spotlight-mode .presentation-pointer-item.show {
        display: none !important;
    }
    
    .presentation-active-view.spotlight-mode .presentation-pointer-item.active {
        display: flex !important;
        width: 100%;
        min-height: 150px;
        opacity: 1 !important;
        transform: none !important;
    
        background:
            linear-gradient(135deg, rgba(255,255,255,0.98), rgba(245,248,255,0.96));
        border: 1px solid rgba(13,110,253,0.22);
        border-left: 8px solid var(--presentation-primary);
        border-radius: 28px;
        padding: 26px 28px;
    
        box-shadow:
            0 22px 55px rgba(15,23,42,0.18),
            inset 0 1px 0 rgba(255,255,255,0.8);
    }
    
    .presentation-active-view.spotlight-mode .presentation-pointer-item.active .presentation-pointer-index {
        width: 76px;
        height: 76px;
        min-width: 76px;
        border-radius: 24px;
        font-size: 1.7rem;
    }
    
    .presentation-active-view.spotlight-mode .presentation-pointer-item.active .presentation-pointer-title {
        font-size: calc(1.35rem * var(--presentation-font-scale));
        font-weight: 900;
        line-height: 1.65;
        color: var(--presentation-text);
    }
    
    /* SPOT mode: hide empty image area */
    .presentation-active-view.spotlight-mode.no-active-image .presentation-active-media-box {
        display: none !important;
    }
    
    /* SPOT mode: hide empty pointer area */
    .presentation-active-view.spotlight-mode.no-active-pointer .presentation-pointer-list {
        display: none !important;
    }
    
    /* only image exists */
    .presentation-active-view.spotlight-mode.no-active-pointer:not(.no-active-image) {
        grid-template-columns: 1fr !important;
    }
    
    /* only pointer exists */
    .presentation-active-view.spotlight-mode.no-active-image:not(.no-active-pointer) {
        grid-template-columns: 1fr !important;
    }
    
    /* nothing exists */
    .presentation-active-view.spotlight-mode.no-active-image.no-active-pointer {
        display: none !important;
    }
    
    /* Fullscreen spot mode */
    .presentation-page-shell.fullscreen-mode .presentation-active-view.spotlight-mode {
        height: calc(100vh - 155px);
        min-height: 0;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-active-view.spotlight-mode .presentation-active-media-box {
        min-height: 0;
        height: 100%;
    }
    
    .presentation-page-shell.spot-mode-active .presentation-camera-overlay {
        z-index: 99999;
    }
    
    /* =========================================
       SPOT MODE WITHOUT ACTIVE POINTER
    ========================================= */
    
    /*.presentation-active-view.spotlight-mode.no-active-pointer {*/
    /*    grid-template-columns: 1fr !important;*/
    /*}*/
    
    /*.presentation-active-view.spotlight-mode.no-active-pointer .presentation-pointer-list {*/
    /*    display: none !important;*/
    /*}*/
    
    /* DO NOT force controls visible in spot mode */
    .presentation-page-shell.spot-mode-active .presentation-camera-overlay:not(:hover) .presentation-camera-controls {
        opacity: 0;
        visibility: hidden;
        transform: translateY(6px);
    }
    
    /* Mobile fallback */
    @media (max-width: 991px) {
        .presentation-active-view.spotlight-mode {
            grid-template-columns: 1fr !important;
            grid-template-rows: minmax(0, 1fr) auto !important;
        }
    
        .presentation-page-shell.spot-mode-active .presentation-camera-overlay {
            top: auto !important;
            right: 14px !important;
            bottom: 80px !important;
            transform: none !important;
            --camera-size: 180px;
        }
    }
    
    /*full fullscreen-mode*/
    .presentation-page-shell.fullscreen-mode .presentation-active-view.spotlight-mode {
        height: calc(100vh - 155px);
        min-height: 0;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-active-view.spotlight-mode .presentation-active-media-box {
        min-height: 0;
        height: 100%;
    }
    
     
    
    /* =========================================
       FULLSCREEN IMAGE MODE FIXES
    ========================================= */
    
    .presentation-layout-mini-btn.active {
        background: var(--presentation-primary);
        color: #fff;
        border-color: var(--presentation-primary);
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-active-view.image-mode-background {
        min-height: calc(100vh - 180px);
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-active-view.image-mode-background .presentation-active-media-box {
        inset: 0;
        max-height: none;
        height: 100%;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-active-view.image-mode-focus .presentation-active-media-box {
        max-height: calc(100vh - 210px);
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-active-view.image-mode-hide {
        grid-template-rows: 1fr;
    }
    
    
    
    .presentation-active-media-box {
        display: none;
        position: relative;
        width: 100%;
        max-width: 100%;
        min-height: 280px;
        max-height: calc(100vh - 220px);
        border-radius: 24px;
        padding: 18px;
        margin: 0;
        overflow: hidden;
        align-items: center;
        justify-content: center;
        background:
            radial-gradient(circle at center, rgba(255,255,255,0.18), transparent 35%),
            linear-gradient(135deg, rgba(15,23,42,0.08), rgba(13,110,253,0.08));
        box-shadow:
            inset 0 1px 0 rgba(255,255,255,0.18),
            0 24px 55px rgba(15,23,42,0.16);
    }
     
    .presentation-active-media-box.show {
        display: flex;
    }
    
    .presentation-active-media-box img {
        max-width: 100%;
        max-height: calc(100vh - 260px);
        width: auto;
        height: auto;
        display: block;
        margin: 0 auto;
        border-radius: 22px;
        object-fit: contain;
        opacity: 0;
        transform: scale(0.96) translateY(12px);
        transition:
            opacity 0.7s ease,
            transform 0.7s ease,
            filter 0.7s ease;
        box-shadow:
            0 28px 65px rgba(0,0,0,0.26),
            0 0 80px rgba(13,110,253,0.16);
        position: relative;
        z-index: 2;
    }
    
    .presentation-active-media-box img.show {
        opacity: 1;
        transform: scale(1) translateY(0);
    }
     
    .presentation-active-media-box.has-image::before {
        content: "";
        position: absolute;
        inset: -35px;
        background-image: var(--active-slide-image);
        background-size: cover;
        background-position: center;
        filter: blur(36px);
        opacity: 0.22;
        transform: scale(1.12);
        z-index: 0;
    }
    
    .presentation-active-media-box.has-image::after {
        content: "";
        position: absolute;
        inset: 0;
        background:
            linear-gradient(180deg, rgba(255,255,255,0.12), rgba(255,255,255,0.02)),
            radial-gradient(circle at top right, rgba(13,110,253,0.18), transparent 32%);
        z-index: 1;
        pointer-events: none;
    }
    
    .presentation-active-media-box.cinematic img.show {
        animation: cinematicImageZoom 16s ease-in-out infinite alternate;
    }
    
    @keyframes cinematicImageZoom {
        from {
            transform: scale(1) translateY(0);
        }
        to {
            transform: scale(1.035) translateY(-4px);
        }
    }
     
    
    .presentation-magnifier-lens.active {
        display: block;
    }
    
    .presentation-magnifier-enabled {
        cursor: none;
    }
    
    .presentation-magnifier-lens {
        position: fixed;
        width: 180px;
        height: 180px;
        border-radius: 50%;
        overflow: hidden;
        display: none;
        z-index: 99999;
        border: 3px solid #fff;
        box-shadow: 0 10px 25px rgba(0,0,0,0.3);
        /*background: #000;*/
        pointer-events: none;
    }
    
    .presentation-magnifier-content {
        position: absolute;
        top: 0;
        left: 0;
        transform-origin: top left;
    }
    
    .presentation-magnifier-lens.active {
        display: block;
    }
    
    .presentation-magnifier-content {
        position: absolute;
        top: 0;
        left: 0;
        transform-origin: top left;
        will-change: transform;
    }
    
    .presentation-magnifier-enabled {
        cursor: none;
    }
    
    
    .presentation-pointer-list {
        list-style: none;
        padding: 0;
        margin: 0;
        display: grid;
        gap: 10px;
        align-content: start;
    }
    
    .presentation-pointer-item {
        display: flex;
        gap: calc(10px * var(--presentation-font-scale, 1));
        align-items: center;
        background: rgba(255,255,255,0.76);
        border: 1px solid var(--presentation-border);
        border-radius: 16px;
        padding: calc(5px * var(--presentation-font-scale, 1)) calc(10px * var(--presentation-font-scale, 1));
        cursor: pointer;
        transition: all 0.28s ease;
        opacity: 0;
        transform: translateY(14px) scale(0.98);
    }
    
    .presentation-pointer-item.show {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
    
    .presentation-pointer-item:hover {
        transform: translateY(-1px);
        box-shadow: 0 10px 18px rgba(0,0,0,0.05);
    }
    
    .presentation-pointer-item.active {
        border-color: rgba(13,110,253,0.38);
        box-shadow:
            0 14px 30px rgba(13,110,253,0.16),
            inset 0 1px 0 rgba(255,255,255,0.45);
        background:
            linear-gradient(135deg, rgba(13,110,253,0.10), rgba(255,255,255,0.82));
        transform: scale(1.015);
    }
    
    .presentation-pointer-list.has-active .presentation-pointer-item.show {
        opacity: 0.45;
    }
    
    .presentation-pointer-list.has-active .presentation-pointer-item.active {
        opacity: 1;
    }
    
    .presentation-pointer-index {
        width: calc(56px * var(--presentation-font-scale, 1));
        height: calc(56px * var(--presentation-font-scale, 1));
        min-width: calc(56px * var(--presentation-font-scale, 1));
    
        border-radius: 18px;
    
        display: inline-flex;
        align-items: center;
        justify-content: center;
    
        position: relative;
        overflow: hidden;
    
        color: #ffffff;
    
        font-size: calc(1.35rem * var(--presentation-font-scale));
        margin-top: 2px;
        flex-shrink: 0;
    
        background:
            linear-gradient(
                135deg,
                rgba(34, 197, 94, 0.95),
                rgba(22, 163, 74, 0.92)
            );
    
        border: 1px solid rgba(255,255,255,0.16);
    
        box-shadow:
            0 10px 25px rgba(34,197,94,0.28),
            inset 0 1px 0 rgba(255,255,255,0.18);
    
        backdrop-filter: blur(10px);
    
        transition:
            transform 0.25s ease,
            box-shadow 0.25s ease,
            filter 0.25s ease;
    }
    
    /* glossy shine */
    .presentation-pointer-index::before {
        content: "";
        position: absolute;
        inset: 0;
    
        background:
            linear-gradient(
                135deg,
                rgba(255,255,255,0.30),
                transparent 40%
            );
    
        pointer-events: none;
    }
    
    /* icon */
    .presentation-pointer-index i {
        font-size: calc(1.45rem * var(--presentation-font-scale));
        position: relative;
        z-index: 2;
    }
    
    /* hover effect */
    .presentation-pointer-item:hover .presentation-pointer-index {
        transform: translateY(-2px) scale(1.06);
    
        box-shadow:
            0 16px 35px rgba(34,197,94,0.38),
            inset 0 1px 0 rgba(255,255,255,0.24);
    
        filter: brightness(1.05);
    }
    
    /* active effect */
    .presentation-pointer-item.active .presentation-pointer-index {
        background:
            linear-gradient(
                135deg,
                rgba(13,110,253,0.96),
                rgba(99,102,241,0.92)
            );
    
        box-shadow:
            0 18px 40px rgba(13,110,253,0.34),
            inset 0 1px 0 rgba(255,255,255,0.24);
    }
    
    .presentation-icon-btn.active {
        background: var(--link-color);
        color: #fff;
        box-shadow: 0 4px 12px rgba(0,0,0,0.2);
    }
    .presentation-pointer-text {
        flex: 1;
        min-width: 0;
    }
    
    .presentation-pointer-title {
        font-weight: 700;
        line-height: 1.7;
        color: var(--presentation-text);
        word-break: break-word;
        font-size: calc(1rem * var(--presentation-font-scale));
        
    }
    
    .presentation-stage,
    .presentation-stage :not(i):not(.fa):not(.fa-solid):not(.fa-regular):not(.fa-brands),
    .presentation-explanation-panel,
    .presentation-explanation-panel :not(i):not(.fa):not(.fa-solid):not(.fa-regular):not(.fa-brands),
    .presentation-mobile-sheet,
    .presentation-mobile-sheet :not(i):not(.fa):not(.fa-solid):not(.fa-regular):not(.fa-brands) {
        font-family:
            'Hind Siliguri',
            'Segoe UI',
            Arial,
            sans-serif !important;
        letter-spacing: 0 !important;
    }
    
    .presentation-pointer-index i,
    .presentation-stage i.fa,
    .presentation-stage i.fa-solid,
    .presentation-stage i.fa-regular,
    .presentation-stage i.fa-brands {
        font-family: "Font Awesome 6 Free" !important;
        font-weight: 900 !important;
    }
    
    .presentation-explanation-panel {
        padding: 16px;
        min-height: 620px;
        display: flex;
        flex-direction: column;
    }
    
    .presentation-explanation-title-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
        margin-bottom: 12px;
        padding-bottom: 10px;
        border-bottom: 1px solid var(--presentation-border);
    }
    
    .presentation-explanation-title {
        font-size: 1rem;
        font-weight: 800;
        color: var(--presentation-text);
    }
    
    .presentation-explanation-actions {
        display: flex;
        align-items: center;
        gap: 6px;
    }
    
    .presentation-save-indicator {
        font-size: 0.78rem;
        color: var(--presentation-text-soft);
    }
    
    .presentation-explanation-editor {
        flex: 1;
        width: 100%;
        min-height: 260px;
        border: 1px solid var(--presentation-border);
        border-radius: 14px;
        padding: 12px;
        outline: none;
        resize: vertical;
        background: var(--presentation-panel-bg);
        color: var(--presentation-text);
        line-height: 1.8;
        font-size: 0.95rem;
    }
    
    .presentation-progress {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        margin-top: 16px;
        padding-top: 14px;
        border-top: 1px solid var(--presentation-border);
    }
    
    .presentation-progress-bar-wrap {
        flex: 1;
        height: 8px;
        background: rgba(0,0,0,0.06);
        border-radius: 999px;
        overflow: hidden;
    }
     
    .presentation-progress-bar {
        width: 0%;
        height: 100%;
        background: linear-gradient(90deg, var(--presentation-primary), var(--presentation-primary-hover));
        transition: width 0.3s ease;
    }
    
    .presentation-progress-text {
        font-size: 0.84rem;
        color: var(--presentation-text-soft);
        white-space: nowrap;
         margin-right: auto;
        font-weight: 700;
    }
     
    .presentation-mobile-hint {
        display: none;
        margin-top: 10px;
        font-size: 0.84rem;
        color: var(--presentation-text-soft);
    }
    
    .presentation-mobile-explanation-modal {
        position: fixed;
        inset: 0;
        background: rgba(15, 23, 42, 0.62);
        z-index: 9999;
        display: none;
        align-items: flex-end;
        justify-content: center;
        padding: 12px;
    }
    
    .presentation-mobile-explanation-modal.show {
        display: flex;
    }
    
    .presentation-mobile-sheet {
        width: 100%;
        max-width: 700px;
        background: var(--presentation-panel-bg);
        border-radius: 22px 22px 0 0;
        padding: 16px;
        max-height: 82vh;
        overflow: auto;
        box-shadow: 0 -10px 34px rgba(0,0,0,0.16);
    }
    
    .presentation-mobile-sheet-handle {
        width: 64px;
        height: 5px;
        background: rgba(0,0,0,0.14);
        border-radius: 999px;
        margin: 0 auto 12px auto;
    }
    
    .presentation-mobile-sheet-title {
        font-size: 0.98rem;
        font-weight: 800;
        margin-bottom: 9px;
        color: var(--presentation-text);
    }
    
    .presentation-mobile-sheet-body {
        color: var(--presentation-text);
        line-height: 1.85;
        white-space: pre-wrap;
    }
    
    .presentation-mobile-sheet-close {
        margin-top: 14px;
        width: 100%;
    }
    
    .presentation-page-shell.fullscreen-mode {
        padding: 0;
        min-height: 100vh;
        width: 100vw;
        height: 100vh;
        overflow: hidden;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-main {
        gap: 0;
        grid-template-columns: var(--presentation-sidebar-width) minmax(0, 1fr);
        min-height: 100vh;
        height: 100vh;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-sidebar {
        position: sticky;
        top: 0;
        border-radius: 0;
        min-height: 100vh;
        height: 100vh;
        box-shadow: none;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-slide-nav-btn {
        min-height: 42px;
        font-size: 0.9rem;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-stage-frame {
        min-height: 100vh;
        height: 100vh;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-workspace {
        grid-template-columns: minmax(0, 1fr);
        min-height: 100vh;
        height: 100vh;
        gap: 0;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-stage {
        border-radius: 0;
        border: none;
        min-height: 100vh;
        height: 100vh;
        box-shadow: none;
        padding: 14px 18px 12px 18px;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-content-area {
        flex: 1;
        min-height: 0;
        overflow: hidden;
        padding-right: 0;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-explanation-panel {
        display: none !important;
    }
    
    .presentation-stage-title-wrap .presentation-presentation-info {
        margin-top: 14px;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-stage-title-wrap .presentation-presentation-info {
        margin-top: 12px;
    }
    
    .presentation-presentation-meta-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
        gap: 10px;
    }
     
    
    @media (max-width: 1199px) {
        .presentation-workspace {
            grid-template-columns: 1fr;
        }
    
        .presentation-explanation-panel {
            min-height: 260px;
        }
    
        .presentation-active-view.layout-left,
        .presentation-active-view.layout-right {
            grid-template-columns: 1fr;
        }
    
        .presentation-presentation-meta-grid {
            grid-template-columns: repeat(2, minmax(0, 1fr));
        }
    
        .presentation-page-shell.fullscreen-mode .presentation-workspace {
            grid-template-columns: 1fr;
        }
    }
    
    @media (max-width: 991px) {
        .presentation-top-grid {
            grid-template-columns: 1fr;
        }
    
        .presentation-upload-wrap {
            justify-content: flex-start;
        }
    
        .presentation-main {
            grid-template-columns: 54px minmax(0, 1fr);
        }
    
        .presentation-sidebar {
            top: 78px;
        }
    
        .presentation-page-shell.fullscreen-mode .presentation-main {
            grid-template-columns: 54px minmax(0, 1fr);
        }
    
        .presentation-stage-title-wrap h2 {
            font-size: calc(1.85rem * var(--presentation-font-scale));
        }
    
        .presentation-stage-subtitle {
            font-size: calc(1.08rem * var(--presentation-font-scale));
        }
    }
    
    @media (max-width: 767px) {
        .presentation-page-shell {
            padding: 12px;
        }
    
        .presentation-main {
            grid-template-columns: 1fr;
        }
    
        .presentation-sidebar {
            position: static;
            min-height: auto;
            padding: 10px;
            border-radius: 14px;
        }
    
        .presentation-slide-nav {
            flex-direction: row;
            overflow-x: auto;
            overflow-y: hidden;
            max-height: unset;
            padding-bottom: 3px;
        }
    
        .presentation-slide-nav-btn {
            min-width: 42px;
            min-height: 32px;
            font-size: 0.78rem;
        }
    
        .presentation-stage,
        .presentation-explanation-panel {
            min-height: auto;
        }
    
        .presentation-explanation-panel {
            display: none;
        }
    
        .presentation-mobile-hint {
            display: block;
        }
    
        .presentation-stage-header {
            grid-template-columns: 1fr;
        }
    
        .presentation-active-view.layout-left,
        .presentation-active-view.layout-right {
            grid-template-columns: 1fr;
        }
     
        .presentation-page-shell.fullscreen-mode .presentation-main {
            grid-template-columns: 1fr;
        }
    
        .presentation-page-shell.fullscreen-mode .presentation-sidebar {
            position: static;
            min-height: auto;
            height: auto;
        }
    }
    </style>
    <div class="dashboard-main">
    <div class="presentation-page-shell" id="presentationPageShell">
        <div class="presentation-top-card" id="presentationTopCard">
            <div class="presentation-top-grid">
                <div>
                    <h1 class="presentation-title">Excel Presentation Viewer</h1>
                    <p class="presentation-subtitle">
                        Upload your Excel file, reveal pointers one by one, show point images properly, and detach explanation into a separate window for your second monitor.
                    </p>
                    <div class="presentation-template-note">
                        Optional first row:
                        <strong>Presentation Title:</strong>, value,
                        <strong>Presented by:</strong>, value,
                        <strong>Organized By:</strong>, value,
                        <strong>Date:</strong>, value.
                        <br>
                        Slide columns:
                        <strong>Slide Number</strong>,
                        <strong>Slide Title</strong>,
                        <strong>Slide Subtitle</strong>,
                        <strong>Image</strong>,
                        <strong>Pointers</strong>,
                        <strong>Explanation in Details</strong>.
                    </div>
                    <p><a href="/user/documents/presentation-template.xlsx"> Download template</a></p>
                </div>
    
                <div>
                    <!--<div class="presentation-upload-wrap">-->
                    <!--    <input type="file" id="presentationExcelFile" class="presentation-file-input" accept=".xlsx,.xls,.csv">-->
                    <!--    <button type="button" class="presentation-btn presentation-btn-primary" id="presentationLoadBtn">Load File</button>-->
                    <!--    <button type="button" class="presentation-btn presentation-btn-light" id="presentationResetBtn">Reset</button>-->
                    <!--</div>-->
                    <!--<div class="presentation-upload-wrap">-->
                    <!--    <input type="file" id="presentationExcelFile" class="presentation-file-input" accept=".xlsx,.xls,.csv">-->
                    <!--    <button type="button" class="presentation-btn presentation-btn-primary" id="presentationLoadBtn">Load File</button>-->
                    <!--    <button type="button" class="presentation-btn presentation-btn-light" id="presentationSaveToServerBtn">Save to Server</button>-->
                    <!--    <button type="button" class="presentation-btn presentation-btn-light" id="presentationResetBtn">Reset</button>-->
                    <!--</div>-->
                    <div class="presentation-upload-wrap">
                        <input type="file" id="presentationExcelFile" class="presentation-file-input" accept=".xlsx,.xls,.csv">
                        <button type="button" class="presentation-btn presentation-btn-primary" id="presentationLoadBtn">Load File</button>
                        <button type="button" class="presentation-btn presentation-btn-light" id="presentationSaveToServerBtn">Save to Server</button>
                        <button type="button" class="presentation-btn presentation-btn-light" id="presentationLoadLatestBtn">Load Latest</button>
                        <button type="button" class="presentation-btn presentation-btn-light" id="presentationAllExcelsBtn">All Excels</button>
                        <button type="button" class="presentation-btn presentation-btn-light" id="presentationResetBtn">Reset</button>
                    </div>
                    <div class="presentation-feedback" id="presentationFeedback"></div>
                    
                    <!-- All Excels Modal -->
                    <div id="presentationExcelModal" style="
                        display:none; position:fixed; inset:0; z-index:99999;
                        background:rgba(15,23,42,0.55); align-items:center; justify-content:center; padding:16px;">
                        <div style="
                            background:var(--presentation-panel-bg,#fff);
                            border-radius:22px; width:100%; max-width:620px;
                            max-height:80vh; display:flex; flex-direction:column;
                            box-shadow:0 24px 60px rgba(0,0,0,0.22);
                            border:1px solid var(--presentation-border,rgba(0,0,0,0.08));">
                    
                            <div style="
                                display:flex; align-items:center; justify-content:space-between;
                                padding:18px 20px 14px; border-bottom:1px solid var(--presentation-border,rgba(0,0,0,0.08));">
                                <div style="font-size:1.05rem; font-weight:800; color:var(--presentation-text,#1f2937);">
                                    Excel Files on Server
                                </div>
                                <button type="button" id="presentationExcelModalClose" style="
                                    border:none; background:none; font-size:1.3rem;
                                    cursor:pointer; color:var(--presentation-text-soft,#6b7280);
                                    line-height:1; padding:4px 8px; border-radius:8px;">✕</button>
                            </div>
                    
                            <div id="presentationExcelModalBody" style="
                                flex:1; overflow-y:auto; padding:14px 20px 20px;">
                                <div style="color:var(--presentation-text-soft,#6b7280); font-size:0.9rem;">Loading...</div>
                            </div>
                        </div>
                    </div>
                    <div class="presentation-feedback" id="presentationFeedback"></div>
    
                    <div class="presentation-feedback" id="presentationFeedback"></div>
                </div>
            </div>
        </div>
    
        <div class="presentation-main">
            <aside class="presentation-sidebar">
                <div class="presentation-sidebar-title">SLD</div>
                <div class="presentation-slide-nav" id="presentationSlideNav"></div>
            </aside>
    
            <div class="presentation-stage-frame" id="presentationStageFrame">
                <div class="presentation-workspace">
                    
                    <style>
    
    
    .presentation-camera-overlay.hidden {
        display: none !important;
    }
    
    /*.presentation-camera-overlay {*/
    /*    position: fixed;*/
    /*    left: 14px;*/
    /*    bottom: 14px;*/
    /*    width: auto;*/
    /*    z-index: 9999;*/
    /*    display: flex;*/
    /*    flex-direction: column;*/
    /*    align-items: center;*/
    /*    gap: 6px;*/
    /*    --camera-size: 200px;*/
    /*}*/
    .presentation-camera-overlay {
        position: fixed;
    
        top: 2px;
        left: calc(55% - 100px);
    
        width: auto;
        z-index: 9999;
    
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 6px;
    
        --camera-size: 200px;
    
        cursor: grab;
    }
    
    .presentation-camera-overlay video {
        width: var(--camera-size);
        height: var(--camera-size);
        border-radius: 50%;
        object-fit: cover;
        background: #000;
        border: 3px solid rgba(255,255,255,0.92);
        box-shadow: 0 10px 24px rgba(0,0,0,0.24);
    }
    
    .presentation-camera-controls {
        display: flex;
        align-items: center;
        gap: 4px;
        padding: 4px 6px;
        border-radius: 999px;
        background: rgba(0,0,0,0.58);
        backdrop-filter: blur(8px);
        box-shadow: 0 8px 18px rgba(0,0,0,0.18);
        flex-wrap: wrap;
        justify-content: center;
        max-width: calc(var(--camera-size) + 20px);
    }
    
    .presentation-camera-select {
        /*max-width: 90px;*/
        max-width: calc(var(--camera-size) + 20px);
        min-width: 70px;
        border: 1px solid rgba(255,255,255,0.12);
        background: rgba(255,255,255,0.14);
        color: #fff;
        border-radius: 999px;
        padding: 4px 8px;
        font-size: 10px;
        outline: none;
    }
    
    .presentation-camera-select option {
        color: #111;
    }
    
    .presentation-camera-btn {
        width: 26px;
        height: 26px;
        min-width: 26px;
        border: none;
        border-radius: 50%;
        background: rgba(255,255,255,0.14);
        color: #fff;
        font-size: 11px;
        font-weight: 700;
        line-height: 1;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        transition: all 0.18s ease;
    }
    
    .presentation-camera-btn:hover {
        transform: translateY(-1px);
        background: rgba(255,255,255,0.24);
    }
    
    .presentation-camera-btn.primary {
        background: var(--presentation-primary);
    }
    
    .presentation-camera-btn.danger {
        background: #dc3545;
    }
    
    .presentation-camera-btn.active {
        box-shadow: 0 0 0 2px rgba(255,255,255,0.18) inset;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-camera-overlay {
        left: 18px;
        bottom: 18px;
    }
    
    @media (max-width: 767px) {
        .presentation-camera-overlay {
            --camera-size: 180px;
            left: 10px;
            bottom: 10px;
        }
    
        .presentation-camera-btn {
            width: 24px;
            height: 24px;
            min-width: 24px;
            font-size: 10px;
        }
    
        .presentation-camera-select {
            max-width: 78px;
            font-size: 9px;
            padding: 3px 7px;
        }
    }
    
    .presentation-camera-overlay {
        cursor: grab;
    }
    
    .presentation-camera-overlay.dragging {
        cursor: grabbing;
    }
    
    /* Controls hidden by default */
    .presentation-camera-controls {
        opacity: 0;
        visibility: hidden;
        transform: translateY(6px);
        transition: all 0.25s ease;
    }
    
    /* Show on hover */
    .presentation-camera-overlay:hover .presentation-camera-controls {
        opacity: 1;
        visibility: visible;
        transform: translateY(0);
    }
    
    /* Also show when active via JS */
    .presentation-camera-controls.show {
        opacity: 1;
        visibility: visible;
        transform: translateY(0);
    }
    
    
    .presentation-camera-overlay.shape-circle video {
        border-radius: 50%;
        width: var(--camera-size);
        height: var(--camera-size);
    }
    
    .presentation-camera-overlay.shape-square video {
        border-radius: 18px;
        width: var(--camera-size);
        height: var(--camera-size);
    }
    
    .presentation-camera-overlay.shape-horizontal video {
        border-radius: 18px;
        width: calc(var(--camera-size) * 1.6);
        height: var(--camera-size);
    }
    
    .presentation-camera-overlay.shape-vertical video {
        border-radius: 18px;
        width: var(--camera-size);
        height: calc(var(--camera-size) * 1.45);
    }
                    </style>
                    
                        <div class="presentation-camera-overlay" id="presentationCameraOverlay">
                            <video id="presentationCameraVideo" autoplay playsinline muted></video>
                        
                            <div class="presentation-camera-controls">
                                <select id="presentationCameraSelect" class="presentation-camera-select"></select>
                        
                                <button type="button" class="presentation-camera-btn" id="presentationCameraSmallerBtn" title="Smaller">−</button>
                                <button type="button" class="presentation-camera-btn" id="presentationCameraLargerBtn" title="Larger">+</button>
                                <button type="button" class="presentation-camera-btn" id="presentationCameraShapeBtn" title="Change Shape">▣</button>
                        
                                <button type="button" class="presentation-camera-btn primary" id="presentationStartCameraBtn" title="Start">▶</button>
                                <button type="button" class="presentation-camera-btn danger" id="presentationStopCameraBtn" title="Stop">■</button>
                            </div>
                        </div>
                        
                        
                        <script>
                            
                
    document.addEventListener('DOMContentLoaded', function () {
        const cameraVideo = document.getElementById('presentationCameraVideo');
        const startCameraBtn = document.getElementById('presentationStartCameraBtn');
        const stopCameraBtn = document.getElementById('presentationStopCameraBtn');
        const cameraSelect = document.getElementById('presentationCameraSelect');
        
        const cameraOverlay = document.getElementById('presentationCameraOverlay');
        const cameraSmallerBtn = document.getElementById('presentationCameraSmallerBtn');
        const cameraLargerBtn = document.getElementById('presentationCameraLargerBtn');
        const cameraShapeBtn = document.getElementById('presentationCameraShapeBtn');
        
        let currentCameraSize = 200;
        let currentCameraStream = null;
        
        // const cameraOverlay = document.getElementById('presentationCameraOverlay');
    
        let isDragging = false;
        let offsetX = 0;
        let offsetY = 0;
        
        const controls = document.querySelector('.presentation-camera-controls');
    
        let hideTimeout;
        
        // const cameraOverlay = document.getElementById('presentationCameraOverlay');
        const cameraToggleBtn = document.getElementById('presentationCameraToggleBtn');
        
        const CAMERA_ENABLED_KEY = 'presentation_camera_enabled';
        let isCameraEnabled = localStorage.getItem(CAMERA_ENABLED_KEY) !== '0';
        
        document.addEventListener('keydown', function (e) {
            // ignore typing inside input/textarea/contenteditable
            const tag = document.activeElement.tagName;
            if (
                tag === 'INPUT' ||
                tag === 'TEXTAREA' ||
                document.activeElement.isContentEditable
            ) {
                return;
            }
            // Press S
            if (e.key.toLowerCase() === 's') {
                e.preventDefault();
                const spotlightBtn = document.getElementById('presentationSpotlightBtn');
        
                if (spotlightBtn) {
                    spotlightBtn.click();
                }
            }
        });
        
        function applyCameraVisibility() {
            if (!cameraOverlay) return;
        
            if (isCameraEnabled) {
                cameraOverlay.classList.remove('hidden');
                cameraToggleBtn.classList.add('active');
                cameraToggleBtn.title = 'Hide Camera';
            } else {
                cameraOverlay.classList.add('hidden');
                cameraToggleBtn.classList.remove('active');
                cameraToggleBtn.title = 'Show Camera';
        
                if (typeof stopCamera === 'function') {
                    stopCamera();
                }
            }
        }
        
        cameraToggleBtn.addEventListener('click', function () {
            isCameraEnabled = !isCameraEnabled;
            localStorage.setItem(CAMERA_ENABLED_KEY, isCameraEnabled ? '1' : '0');
            applyCameraVisibility();
        });
        
        // Show controls
        function showControls() {
            controls.classList.add('show');
        
            clearTimeout(hideTimeout);
        
            hideTimeout = setTimeout(() => {
                controls.classList.remove('show');
            }, 100);
        }
        
        // Show on interactions
        cameraOverlay.addEventListener('mouseenter', showControls);
        cameraOverlay.addEventListener('mousemove', showControls);
        
        // Optional: show when camera starts
        startCameraBtn.addEventListener('click', showControls);
        
        // Optional: show when size changes
        cameraLargerBtn.addEventListener('click', showControls);
        cameraSmallerBtn.addEventListener('click', showControls);
        
        // Initial show (first load)
        showControls();
        
        // Mouse down
        cameraOverlay.addEventListener('mousedown', function (e) {
            isDragging = true;
        
            const rect = cameraOverlay.getBoundingClientRect();
            offsetX = e.clientX - rect.left;
            offsetY = e.clientY - rect.top;
        
            cameraOverlay.classList.add('dragging');
        });
        
        // Mouse move
        document.addEventListener('mousemove', function (e) {
            if (!isDragging) return;
        
            let left = e.clientX - offsetX;
            let top = e.clientY - offsetY;
        
            // Keep inside screen
            left = Math.max(0, Math.min(window.innerWidth - cameraOverlay.offsetWidth, left));
            top = Math.max(0, Math.min(window.innerHeight - cameraOverlay.offsetHeight, top));
        
            cameraOverlay.style.left = left + 'px';
            cameraOverlay.style.top = top + 'px';
        
            // Remove bottom/right so it doesn't conflict
            cameraOverlay.style.right = 'auto';
            cameraOverlay.style.bottom = 'auto';
            cameraOverlay.style.transform = 'none';
        });
        
        // Mouse up
        document.addEventListener('mouseup', function () {
            isDragging = false;
            cameraOverlay.classList.remove('dragging');
        });
        
        const CAMERA_MIN_SIZE = 90;
        const CAMERA_MAX_SIZE = 1000;
        const CAMERA_STEP = 25;
        
        const CAMERA_SHAPES = ['shape-circle', 'shape-square', 'shape-horizontal', 'shape-vertical'];
        let currentCameraShapeIndex = 0;
        
        function applyCameraShape() {
            cameraOverlay.classList.remove(...CAMERA_SHAPES);
            cameraOverlay.classList.add(CAMERA_SHAPES[currentCameraShapeIndex]);
            keepCameraInsideScreen();
        }
        
        cameraShapeBtn.addEventListener('click', function () {
            currentCameraShapeIndex = (currentCameraShapeIndex + 1) % CAMERA_SHAPES.length;
            applyCameraShape();
        });
        
        function keepCameraInsideScreen() {
            if (!cameraOverlay) return;
        
            const rect = cameraOverlay.getBoundingClientRect();
        
            let left = rect.left;
            let top = rect.top;
        
            if (left + cameraOverlay.offsetWidth > window.innerWidth) {
                left = Math.max(0, window.innerWidth - cameraOverlay.offsetWidth);
            }
        
            if (top + cameraOverlay.offsetHeight > window.innerHeight) {
                top = Math.max(0, window.innerHeight - cameraOverlay.offsetHeight);
            }
        
            cameraOverlay.style.left = left + 'px';
            cameraOverlay.style.top = top + 'px';
            cameraOverlay.style.right = 'auto';
            cameraOverlay.style.bottom = 'auto';
            cameraOverlay.style.transform = 'none';
        }
        
        function applyCameraSize() {
            currentCameraSize = Math.max(
                CAMERA_MIN_SIZE,
                Math.min(CAMERA_MAX_SIZE, currentCameraSize)
            );
        
            cameraOverlay.style.setProperty('--camera-size', currentCameraSize + 'px');
            keepCameraInsideScreen();
        }
        
        cameraLargerBtn.addEventListener('click', function () {
            currentCameraSize += CAMERA_STEP;
            applyCameraSize();
        });
        
        cameraSmallerBtn.addEventListener('click', function () {
            currentCameraSize -= CAMERA_STEP;
            applyCameraSize();
        });
    
        async function loadCameraList() {
            try {
                const devices = await navigator.mediaDevices.enumerateDevices();
                const videoDevices = devices.filter(device => device.kind === 'videoinput');
    
                cameraSelect.innerHTML = '';
    
                videoDevices.forEach((device, index) => {
                    const option = document.createElement('option');
                    option.value = device.deviceId;
                    option.textContent = device.label || ('Camera ' + (index + 1));
                    cameraSelect.appendChild(option);
                });
            } catch (error) {
                console.error('Could not load camera devices:', error);
            }
        }
    
     async function startCamera() {
        try {
            if (currentCameraStream) {
                currentCameraStream.getTracks().forEach(track => track.stop());
            }
    
            let constraints;
    
            if (cameraSelect.value) {
                constraints = {
                    video: { deviceId: { exact: cameraSelect.value } },
                    audio: false
                };
            } else {
                constraints = {
                    video: true, // fallback (IMPORTANT)
                    audio: false
                };
            }
    
            currentCameraStream = await navigator.mediaDevices.getUserMedia(constraints);
            cameraVideo.srcObject = currentCameraStream;
    
            await loadCameraList();
    
        } catch (error) {
            console.error('Camera start failed:', error);
    
            // alert("Camera Error: " + error.message); // 🔥 show real error
            if (error.name === 'NotReadableError' || /device in use/i.test(error.message)) {
                alert('Your camera is already being used by another app or tab. Please close that app or tab and try again.');
            } else if (error.name === 'NotAllowedError') {
                alert('Camera permission is blocked. Please allow camera access in your browser.');
            } else if (error.name === 'NotFoundError') {
                alert('No camera was found on this device.');
            } else {
                alert('Camera Error: ' + error.name + ' - ' + error.message);
            }
        }
    }
    
        function stopCamera() {
            if (currentCameraStream) {
                currentCameraStream.getTracks().forEach(track => track.stop());
                currentCameraStream = null;
            }
    
            cameraVideo.srcObject = null;
        }
    
        startCameraBtn.addEventListener('click', startCamera);
        stopCameraBtn.addEventListener('click', stopCamera);
    
        cameraSelect.addEventListener('change', function () {
            if (cameraVideo.srcObject) {
                startCamera();
            }
        });
    
        if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
            loadCameraList();
        }
        
        applyCameraVisibility();
        applyCameraShape();
    });
    </script>
                    
                    <section class="presentation-stage">
                         <div class="presentation-stage-header">
                    <div class="presentation-stage-title-wrap">
                        <h2 id="presentationStageTitle">Slide title will appear here</h2>
                        <div class="presentation-stage-subtitle" id="presentationStageSubtitle">Slide subtitle will appear here</div>
                        <div class="presentation-stage-meta" id="presentationStageMeta">0 pointer(s) in this slide</div>
     
            
    <style>
    .presentation-presentation-info {
        display: none;
        position: relative;
        overflow: hidden;
        width: min(100%, 1280px);
        margin: 12px auto 0;
        border-radius: 32px;
        padding: 28px 30px 26px;
        /*color: #ffffff;*/
        /*background:*/
        /*    radial-gradient(circle at top right, rgba(255,255,255,0.18), transparent 28%),*/
        /*    radial-gradient(circle at bottom left, rgba(255,255,255,0.10), transparent 26%),*/
        /*    linear-gradient(135deg, rgba(22, 101, 52, 0.96), rgba(21, 128, 61, 0.92), rgba(101, 163, 13, 0.90));*/
        border: 1px solid rgba(255,255,255,0.16);
        box-shadow:
            0 18px 45px rgba(0,0,0,0.16),
            inset 0 1px 0 rgba(255,255,255,0.12);
        backdrop-filter: blur(10px);
        transform: translateY(10px) scale(0.98);
        opacity: 0;
        transition: opacity 0.35s ease, transform 0.35s ease;
    }
    
    .presentation-presentation-info.show {
        display: block;
        opacity: 1;
        transform: translateY(0) scale(1);
    }
    
    .presentation-presentation-info::before {
        content: "";
        position: absolute;
        inset: 0;
        pointer-events: none;
        /*background:*/
        /*    linear-gradient(135deg, rgba(255,255,255,0.08), transparent 35%),*/
        /*    linear-gradient(315deg, rgba(255,255,255,0.06), transparent 42%);*/
    }
    
    .presentation-presentation-info > * {
        position: relative;
        z-index: 1;
    }
    
    .presentation-presentation-hero-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 14px;
        margin-bottom: 20px;
        flex-wrap: wrap;
    }
    
    .presentation-presentation-badge {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        padding: 10px 15px;
        border-radius: 999px;
        background: rgb(96 126 87 / 14%);
        border: 1px solid rgba(255,255,255,0.16);
        font-size: 0.86rem;
        font-weight: 700;
        line-height: 1;
        white-space: nowrap;
    }
    
    .presentation-presentation-title {
        font-size: clamp(2rem, 4.2vw, 4.8rem);
        font-weight: 900;
        line-height: 1.05;
        margin: 0 0 10px 0;
        letter-spacing: -0.04em;
        word-break: break-word;
        max-width: 980px;
    }
    
    .presentation-presentation-subline {
        font-size: 1.05rem;
        line-height: 1.7;
        opacity: 0.9;
        margin: 0 0 8px 0;
    }
    
    .presentation-presentation-meta-grid {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 16px;
        align-items: stretch;
    }
    
    .presentation-presentation-meta-card {
        display: flex;
        align-items: flex-start;
        gap: 14px;
        min-height: 104px;
        padding: 18px 18px;
        border-radius: 22px;
        background: rgb(98 129 93 / 12%);
        border: 1px solid rgba(255,255,255,0.14);
        box-shadow: inset 0 1px 0 rgba(255,255,255,0.06);
        backdrop-filter: blur(8px);
        transition: transform 0.22s ease, box-shadow 0.22s ease, background 0.22s ease;
    }
    
    .presentation-presentation-meta-card:hover {
        transform: translateY(-2px);
        background: rgba(255,255,255,0.16);
        box-shadow:
            0 14px 28px rgba(0,0,0,0.10),
            inset 0 1px 0 rgba(255,255,255,0.08);
    }
    
    .presentation-presentation-meta-icon {
        width: 50px;
        height: 50px;
        min-width: 50px;
        border-radius: 16px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 1.15rem;
        line-height: 1;
        background: rgba(255,255,255,0.16);
        border: 1px solid rgba(255,255,255,0.18);
    }
    
    .presentation-presentation-meta-content {
        flex: 1;
        min-width: 0;
    }
    
    .presentation-presentation-meta-label {
        font-size: 0.76rem;
        text-transform: uppercase;
        letter-spacing: 0.09em;
        line-height: 1.4;
        opacity: 0.78;
        margin-bottom: 6px;
        font-weight: 700;
    }
    
    .presentation-presentation-meta-value {
        font-size: 1.12rem;
        line-height: 1.5;
        font-weight: 800;
        word-break: break-word;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-presentation-info {
        width: min(100%, 1420px);
        margin: 10px auto 0;
        padding: 38px 40px 34px;
        border-radius: 36px;
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-presentation-title {
        font-size: clamp(2.4rem, 5vw, 5.4rem);
    }
    
    .presentation-page-shell.fullscreen-mode .presentation-presentation-meta-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 18px;
    }
    
    @media (max-width: 991px) {
        .presentation-presentation-info {
            width: 100%;
            padding: 22px 20px 20px;
            border-radius: 24px;
        }
    
        .presentation-presentation-title {
            font-size: clamp(1.8rem, 5vw, 3rem);
        }
    
        .presentation-presentation-meta-grid {
            grid-template-columns: 1fr;
        }
    }
    
    .presentation-content-area {
        display: flex;
        flex-direction: column;
        gap: 18px;
        flex: 1;
        min-height: 320px;
        justify-content: flex-start;
    }
    
    .presentation-page-shell.intro-visible .presentation-content-area {
        justify-content: center;
    }
    
    .presentation-page-shell.intro-visible .presentation-active-view {
        min-height: 0;
    }
    
    .presentation-page-shell.intro-visible .presentation-stage {
        justify-content: flex-start;
    }
    
    /* =========================
       BACKGROUND DECOR SYSTEM
    ========================= */
    
    .presentation-presentation-info {
        position: relative;
        overflow: hidden;
    }
    
    /* container */
    .presentation-bg-decor {
        position: absolute;
        inset: 0;
        z-index: 0;
        pointer-events: none;
    }
    
    /* base circle */
    .bg-circle {
        position: absolute;
        border-radius: 50%;
        filter: blur(60px);
        opacity: 0.55;
        animation: floatMove 12s ease-in-out infinite alternate;
    }
    
    /* individual circles */
    .circle-1 {
        width: 260px;
        height: 260px;
        background: #22c55e;
        top: -180px;
        left: -60px;
    }
    
    .circle-2 {
        width: 120px;
        height: 220px;
        background: #84cc16;
        bottom: -180px;
        right: -40px;
        animation-delay: 2s;
    }
    
    .circle-3 {
        width: 1180px;
        height: 180px;
        background: #4ade80;
        top: 50%;
        left: 40%;
        transform: translate(-50%, -50%);
        animation-delay: 4s;
    }
    
    .circle-4 {
        width: 1140px;
        height: 140px;
        background: #bbf7d0;
        bottom: 20%;
        left: 20%;
        animation-delay: 6s;
    }
    
    /* animation */
    @keyframes floatMove {
        0% {
            transform: translateY(0px) scale(1);
        }
        100% {
            transform: translateY(-25px) scale(1.05);
        }
    }
    </style>
            
           
            
        </div>
    </div>
    
                        <div class="presentation-content-area">
                            
                            <div class="presentation-presentation-info" id="presentationInfoBox">
                                
                                <div class="presentation-bg-decor">
                                    <span class="bg-circle circle-1"></span>
                                    <span class="bg-circle circle-2"></span>
                                    <span class="bg-circle circle-3"></span>
                                    <span class="bg-circle circle-4"></span>
                                </div>
                                
                                <div class="presentation-presentation-hero-row">
                                    <div class="presentation-presentation-badge">
                                        <span>🎤</span>
                                        <span>Presentation Mode</span>
                                    </div>
                            
                                    <div class="presentation-presentation-badge" id="presentationStartHint">
                                        <span>✨</span>
                                        <span>Start your journey with me</span>
                                    </div>
                                </div>
                        
                            <div class="presentation-presentation-header">
                                <div class="presentation-presentation-title" id="presentationMainTitle">Presentation</div>
                                <div class="presentation-presentation-subline">Presentation overview</div>
                            </div>
                        
                            <div class="presentation-presentation-meta-grid" id="presentationMetaGrid">
                                <div class="presentation-presentation-meta-card" id="presentationPresentedByCard">
                                    <div class="presentation-presentation-meta-icon">👤</div>
                                    <div class="presentation-presentation-meta-content">
                                        <div class="presentation-presentation-meta-label">Presented By</div>
                                        <div class="presentation-presentation-meta-value" id="presentationPresentedBy">-</div>
                                    </div>
                                </div>
                        
                                <div class="presentation-presentation-meta-card" id="presentationOrganizedByCard">
                                    <div class="presentation-presentation-meta-icon">🏛️</div>
                                    <div class="presentation-presentation-meta-content">
                                        <div class="presentation-presentation-meta-label">Organized By</div>
                                        <div class="presentation-presentation-meta-value" id="presentationOrganizedBy">-</div>
                                    </div>
                                </div>
                        
                                <div class="presentation-presentation-meta-card" id="presentationDateCard">
                                    <div class="presentation-presentation-meta-icon">📅</div>
                                    <div class="presentation-presentation-meta-content">
                                        <div class="presentation-presentation-meta-label">Date</div>
                                        <div class="presentation-presentation-meta-value" id="presentationDate">-</div>
                                    </div>
                                </div>
                        
                                <div class="presentation-presentation-meta-card" id="presentationCurrentSlideCard">
                                    <div class="presentation-presentation-meta-icon">🖥️</div>
                                    <div class="presentation-presentation-meta-content">
                                        <div class="presentation-presentation-meta-label">Current Slide</div>
                                        <div class="presentation-presentation-meta-value" id="presentationCurrentSlideLabel">-</div>
                                    </div>
                                </div>
                            </div>
                        </div>
    
                            <div class="presentation-active-view layout-top" id="presentationActiveView">
                                <div class="presentation-bg-decor">
                                    <!--<span class="bg-circle circle-1"></span>-->
                                    <span class="bg-circle circle-2"></span>
                                    <span class="bg-circle circle-3"></span>
                                    <span class="bg-circle circle-4"></span>
                                </div>
                                <div class="presentation-empty-state" id="presentationEmptyState">
                                </div>
                                <div class="presentation-active-media-box" id="presentationActiveMediaBox"></div>
                                <ul class="presentation-pointer-list" id="presentationPointerList"></ul>
                            </div>
                        </div>
    
                        <div class="presentation-mobile-hint">
                            On mobile, tap any visible pointer to open its explanation.
                        </div>
    
                        <div class="presentation-progress">
                            <div class="presentation-progress-bar-wrap">
                                <div class="presentation-progress-bar" id="presentationProgressBar"></div>
                            </div>
                            <div class="presentation-progress-text" id="presentationProgressText">0 / 0 points visible</div>
                              <div class="presentation-stage-actions" id="presentationStageActions">
                                <div class="presentation-layout-mini-group" id="presentationLayoutMiniGroup">
                                   
                                    <button type="button" class="presentation-layout-mini-btn active" data-layout="top" title="Image Top">T</button>
                                    <button type="button" class="presentation-layout-mini-btn" data-layout="left" title="Image Left">L</button>
                                    <button type="button" class="presentation-layout-mini-btn" data-layout="right" title="Image Right">R</button>
                                    <button type="button" class="presentation-layout-mini-btn" id="presentationSpotlightBtn" title="Spotlight Mode">SPOT</button>
                                </div>
                                
                                <!-- Font Size Controls -->
                                <div class="presentation-layout-mini-group show" id="presentationFontSizeGroup">
                                     <button type="button" class="presentation-icon-btn" id="presentationMagnifierBtn" title="Magnifier">🔍</button>
                                    <button type="button" class="presentation-layout-mini-btn" id="presentationFontDecreaseBtn" title="Decrease Text Size">−</button>
                                    <button type="button" class="presentation-layout-mini-btn" id="presentationFontIncreaseBtn" title="Increase Text Size">+</button>
                                </div>
                                
                                <button type="button" class="presentation-icon-btn" id="presentationHtmlToggleBtn" title="Toggle HTML Rendering">Code</button>
                                <button type="button" class="presentation-icon-btn" id="presentationPrevBtn" title="Previous Point">⟨</button>
                                <button type="button" class="presentation-icon-btn primary" id="presentationNextBtn" title="Next Point">⟩</button>
                                <button type="button" class="presentation-icon-btn" id="presentationReplayBtn" title="Replay Slide">↺</button>
                                <button type="button" class="presentation-icon-btn" id="presentationCameraToggleBtn" title="Toggle Camera">📷</button>
                                <button type="button" class="presentation-icon-btn" id="presentationDetachBtn" title="Detach Explanation">⧉</button>
                                
                                <button type="button" class="presentation-icon-btn" id="presentationFullscreenBtn" title="Fullscreen">⛶</button>
                            </div>
                        </div>
                    </section>
    
                    <aside class="presentation-explanation-panel" id="presentationExplanationPanel">
                        <div class="presentation-explanation-title-row">
                            <div class="presentation-explanation-title">Explanation</div>
                            <div class="presentation-explanation-actions">
                                <span class="presentation-save-indicator" id="presentationSaveIndicator">Auto save off</span>
                            </div>
                        </div>
                        <div id="presentationExplanationEditor" class="presentation-explanation-editor" contenteditable="true"></div>
                        <!--<textarea id="presentationExplanationEditor" class="presentation-explanation-editor" placeholder="Explanation will appear here and you can edit it directly."></textarea>-->
                    </aside>
                </div>
            </div>
        </div>
    </div>
    
    <div class="presentation-mobile-explanation-modal" id="presentationMobileModal">
        <div class="presentation-mobile-sheet">
            <div class="presentation-mobile-sheet-handle"></div>
            <div class="presentation-mobile-sheet-title" id="presentationMobileSheetTitle">Explanation</div>
            <div class="presentation-mobile-sheet-body" id="presentationMobileSheetBody"></div>
            <button type="button" class="presentation-btn presentation-btn-primary presentation-mobile-sheet-close" id="presentationMobileCloseBtn">Close</button>
        </div>
    </div>
     
    
    <div id="presentationMagnifierLens" class="presentation-magnifier-lens">
        <div id="presentationMagnifierContent" class="presentation-magnifier-content"></div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/xlsx/dist/xlsx.full.min.js"></script>
    
    <script>
    (function () {
        'use strict';
    
        const LOCAL_STORAGE_KEY = 'presentation_excel_viewer_state_v6';
        const SESSION_KEY_STORAGE = 'presentation_excel_viewer_session_key_v6';
        const LAYOUT_STORAGE_KEY = 'presentation_excel_viewer_layout_v2';
        const emptyState = document.getElementById('presentationEmptyState');
        
        const magnifierBtn = document.getElementById('presentationMagnifierBtn');
        const magnifierLens = document.getElementById('presentationMagnifierLens');
        const magnifierContent = document.getElementById('presentationMagnifierContent');
        // const magnifierTarget = document.querySelector('.presentation-stage');
        // const magnifierTarget = document.body;
    
        let magnifierEnabled = false;
        const zoom = 2;
        let lensSize = 180;  
        
        
        
    function toggleMagnifier() {
        if (magnifierEnabled) {
            disableMagnifier();
            return;
        }
    
        magnifierEnabled = true;
    
        attachLensToCorrectParent();
        applyMagnifierSize();
        buildClone();
    
        magnifierLens.classList.add('active');
        magnifierLens.style.display = 'block';
        magnifierBtn.classList.add('active');
        document.body.classList.add('presentation-magnifier-enabled');
    }
    
    function disableMagnifier() {
        magnifierEnabled = false;
    
        magnifierLens.classList.remove('active');
        magnifierLens.style.display = 'none';
        magnifierLens.style.left = '-9999px';
        magnifierLens.style.top = '-9999px';
    
        magnifierBtn.classList.remove('active');
        document.body.classList.remove('presentation-magnifier-enabled');
    
        magnifierContent.innerHTML = '';
    }
    
    function buildClone() {
        magnifierContent.innerHTML = '';
    
        const target = getMagnifierTarget();
        if (!target) return;
    
        const clone = target.cloneNode(true);
    
        clone.style.pointerEvents = 'none';
        clone.style.margin = '0';
        clone.style.position = 'absolute';
        clone.style.top = '0';
        clone.style.left = '0';
    
        // ✅ IMPORTANT FIX
        clone.style.width = document.documentElement.scrollWidth + 'px';
        clone.style.height = document.documentElement.scrollHeight + 'px';
    
        magnifierContent.appendChild(clone);
    }
    
    function applyMagnifierSize() {
        magnifierLens.style.width = lensSize + 'px';
        magnifierLens.style.height = lensSize + 'px';
    }
    
    document.addEventListener('wheel', function (event) {
        if (!magnifierEnabled) return;
    
        event.preventDefault();
    
        if (event.deltaY < 0) {
            lensSize = Math.min(400, lensSize + 20); // scroll up = bigger
        } else {
            lensSize = Math.max(100, lensSize - 20); // scroll down = smaller
        }
    
        applyMagnifierSize();
    }, { passive: false });
    
    function moveMagnifier(e) {
        if (!magnifierEnabled) return;
    
        const target = getMagnifierTarget();
        if (!target) return;
    
        const rect = target.getBoundingClientRect();
    
        const x = e.clientX;
        const y = e.clientY;
    
        magnifierLens.style.left = (x - lensSize / 2) + 'px';
        magnifierLens.style.top = (y - lensSize / 2) + 'px';
    
        let relX;
        let relY;
    
        if (document.fullscreenElement) {
            relX = x - rect.left;
            relY = y - rect.top;
        } else {
            relX = x + window.scrollX;
            relY = y + window.scrollY;
        }
    
        magnifierContent.style.transform =
            `translate(${-relX * zoom + lensSize / 2}px, ${-relY * zoom + lensSize / 2}px) scale(${zoom})`;
    }
    
    document.addEventListener('fullscreenchange', function () {
    
        if (!magnifierEnabled) return;
    
        // Small delay ensures DOM is ready
        setTimeout(() => {
            attachLensToCorrectParent();
            buildClone();
        }, 100);
    
    });
    
    document.addEventListener('keydown', function (event) {
        if (event.key === 'Escape' && magnifierEnabled) {
            disableMagnifier();
        }
    });
    
    function attachLensToCorrectParent() {
        const target = getMagnifierTarget();
    
        if (!target) return;
    
        // Always move lens into correct container
        target.appendChild(magnifierLens);
    }
    
    function getMagnifierTarget() {
        return document.fullscreenElement || document.documentElement;
    }
    
    magnifierBtn.addEventListener('click', toggleMagnifier);
    document.addEventListener('mousemove', moveMagnifier);
        
        
    
        const presentationState = {
            slides: {},
            slideKeys: [],
            currentSlideKey: null,
            currentPointerIndex: 0,
            visiblePointerCount: 0,
            activeVisiblePointerIndex: null,
            sessionKey: null,
            currentLayout: localStorage.getItem(LAYOUT_STORAGE_KEY) || 'top',
            renderHtml: false,
            fontScale: 1,
            presentationMeta: {
                title: '',
                presentedBy: '',
                organizedBy: '',
                date: ''
            }
        };
    
        let detachedWindow = null;
        let saveIndicatorTimeout = null;
        let syncInterval = null;
    
        const pageShell = document.getElementById('presentationPageShell');
        const fileInput = document.getElementById('presentationExcelFile');
        const loadBtn = document.getElementById('presentationLoadBtn');
        const resetBtn = document.getElementById('presentationResetBtn');
    
        const prevBtn = document.getElementById('presentationPrevBtn');
        const nextBtn = document.getElementById('presentationNextBtn');
        const replayBtn = document.getElementById('presentationReplayBtn');
        const detachBtn = document.getElementById('presentationDetachBtn');
        const fullscreenBtn = document.getElementById('presentationFullscreenBtn');
        const stageActions = document.getElementById('presentationStageActions');
        const layoutMiniGroup = document.getElementById('presentationLayoutMiniGroup');
    
        const feedbackBox = document.getElementById('presentationFeedback');
        const slideNav = document.getElementById('presentationSlideNav');
        const stageTitle = document.getElementById('presentationStageTitle');
        const stageSubtitle = document.getElementById('presentationStageSubtitle');
        const stageMeta = document.getElementById('presentationStageMeta');
        const pointerList = document.getElementById('presentationPointerList');
        const explanationEditor = document.getElementById('presentationExplanationEditor');
        const saveIndicator = document.getElementById('presentationSaveIndicator');
        const progressBar = document.getElementById('presentationProgressBar');
        const progressText = document.getElementById('presentationProgressText');
        const explanationPanel = document.getElementById('presentationExplanationPanel');
        const activeView = document.getElementById('presentationActiveView'); 
        
     
    const spotlightBtn = document.getElementById('presentationSpotlightBtn');
    let spotlightModeEnabled = false;
    let previousLayoutBeforeSpot = null;
    let previousCameraStateBeforeSpot = null;
    
    function saveCameraStateBeforeSpot() {
        const cameraOverlay = document.getElementById('presentationCameraOverlay');
        if (!cameraOverlay) return null;
    
        return {
            left: cameraOverlay.style.left,
            right: cameraOverlay.style.right,
            top: cameraOverlay.style.top,
            bottom: cameraOverlay.style.bottom,
            transform: cameraOverlay.style.transform,
            cameraSize: cameraOverlay.style.getPropertyValue('--camera-size')
        };
    }
    
    function restoreCameraStateAfterSpot() {
        const cameraOverlay = document.getElementById('presentationCameraOverlay');
        if (!cameraOverlay || !previousCameraStateBeforeSpot) return;
    
        cameraOverlay.style.left = previousCameraStateBeforeSpot.left;
        cameraOverlay.style.right = previousCameraStateBeforeSpot.right;
        cameraOverlay.style.top = previousCameraStateBeforeSpot.top;
        cameraOverlay.style.bottom = previousCameraStateBeforeSpot.bottom;
        cameraOverlay.style.transform = previousCameraStateBeforeSpot.transform;
    
        if (previousCameraStateBeforeSpot.cameraSize) {
            cameraOverlay.style.setProperty('--camera-size', previousCameraStateBeforeSpot.cameraSize);
        } else {
            cameraOverlay.style.removeProperty('--camera-size');
        }
    }
    
    if (spotlightBtn) {
        spotlightBtn.addEventListener('click', function (event) {
            event.stopPropagation();
    
            spotlightModeEnabled = !spotlightModeEnabled;
    
            if (spotlightModeEnabled) {
                previousLayoutBeforeSpot = presentationState.currentLayout || 'top';
                previousCameraStateBeforeSpot = saveCameraStateBeforeSpot();
            
                applySpotlightMode();
                moveCameraToSpotPosition();
            } else {
                applySpotlightMode();
                restoreCameraStateAfterSpot();
                setLayout(previousLayoutBeforeSpot || 'top');
            }
    
            persistLocalState();
        });
    }
    
    function moveCameraToSpotPosition() {
        const cameraOverlay = document.getElementById('presentationCameraOverlay');
        if (!cameraOverlay) return;
    
        const size = 460;
    
        cameraOverlay.style.setProperty('--camera-size', size + 'px');
    
        // right side, like your screenshot
        cameraOverlay.style.left = 'auto';
        cameraOverlay.style.right = '250px';
    
        // little above pointer
        cameraOverlay.style.top = '170px';
    
        cameraOverlay.style.bottom = 'auto';
        cameraOverlay.style.transform = 'none';
    }
    
    function applySpotlightMode() {
        if (!activeView || !spotlightBtn) return;
    
        activeView.classList.toggle('spotlight-mode', spotlightModeEnabled);
    
        if (pageShell) {
            pageShell.classList.toggle('spot-mode-active', spotlightModeEnabled);
        }
        
        
        const activePointer = document.querySelector(
         '.presentation-pointer-item.active'
        );
        
        if (spotlightModeEnabled) {
            updateSpotModeEmptyState();
        } else {
            activeView.classList.remove('no-active-pointer', 'no-active-image');
        }
        
        if (spotlightModeEnabled) {
        
            if (!activePointer) {
                activeView.classList.add('no-active-pointer');
            } else {
                activeView.classList.remove('no-active-pointer');
            }
        
        } else {
            activeView.classList.remove('no-active-pointer');
        }
    
        spotlightBtn.classList.toggle('active', spotlightModeEnabled);
        spotlightBtn.textContent = spotlightModeEnabled ? 'FOCUS' : 'SPOT';
        spotlightBtn.title = spotlightModeEnabled ? 'Focus Mode On' : 'Focus Mode Off';
    
        document.querySelectorAll('.presentation-layout-mini-btn[data-layout]').forEach(function (btn) {
            btn.classList.toggle(
                'active',
                !spotlightModeEnabled && btn.getAttribute('data-layout') === presentationState.currentLayout
            );
        });
    }
    
    function updateSpotModeEmptyState() {
        if (!activeView) return;
    
        const activePointer = activeView.querySelector('.presentation-pointer-item.active');
        const visiblePointer = activeView.querySelector('.presentation-pointer-item.show');
        const hasPointer = !!(activePointer || visiblePointer);
    
        const hasImage =
            activeMediaBox &&
            activeMediaBox.classList.contains('show') &&
            activeMediaBox.querySelector('img');
    
        activeView.classList.toggle('no-active-pointer', !hasPointer);
        activeView.classList.toggle('no-active-image', !hasImage);
    }
        
        const activeMediaBox = document.getElementById('presentationActiveMediaBox');
     
        
        function applyCinematicImageEffect(imageUrl) {
            if (!activeMediaBox) return;
            
            if (spotlightModeEnabled) {
                updateSpotModeEmptyState();
            }
        
            if (imageUrl) {
                activeMediaBox.classList.add('has-image', 'cinematic');
                activeMediaBox.style.setProperty('--active-slide-image', `url("${imageUrl}")`);
            } else {
                activeMediaBox.classList.remove('has-image', 'cinematic');
                activeMediaBox.style.removeProperty('--active-slide-image');
            }
        }
    
        const presentationInfoBox = document.getElementById('presentationInfoBox');
        const presentationMainTitle = document.getElementById('presentationMainTitle');
        const presentationPresentedBy = document.getElementById('presentationPresentedBy');
        const presentationOrganizedBy = document.getElementById('presentationOrganizedBy');
        const presentationDate = document.getElementById('presentationDate');
        const presentationCurrentSlideLabel = document.getElementById('presentationCurrentSlideLabel');
    
        const mobileModal = document.getElementById('presentationMobileModal');
        const mobileSheetTitle = document.getElementById('presentationMobileSheetTitle');
        const mobileSheetBody = document.getElementById('presentationMobileSheetBody');
        const mobileCloseBtn = document.getElementById('presentationMobileCloseBtn');
        
        const fontIncreaseBtn = document.getElementById('presentationFontIncreaseBtn');
        const fontDecreaseBtn = document.getElementById('presentationFontDecreaseBtn');
        
        const presentationPresentedByCard = document.getElementById('presentationPresentedByCard');
        const presentationOrganizedByCard = document.getElementById('presentationOrganizedByCard');
        const presentationDateCard = document.getElementById('presentationDateCard');
        const presentationCurrentSlideCard = document.getElementById('presentationCurrentSlideCard');
        const htmlToggleBtn = document.getElementById('presentationHtmlToggleBtn');
        
        htmlToggleBtn.setAttribute('data-bs-toggle', 'tooltip');
    htmlToggleBtn.setAttribute('data-bs-placement', 'top');
        
    function updateHtmlToggleUi() {
        if (presentationState.renderHtml) {
            htmlToggleBtn.textContent = 'LIVE';
            htmlToggleBtn.title = 'HTML Rendering ON';
            htmlToggleBtn.classList.add('active');
        } else {
            htmlToggleBtn.textContent = '<>';
            htmlToggleBtn.title = 'HTML Rendering OFF';
            htmlToggleBtn.classList.remove('active');
        }
    }
    
    function containsBangla(text) {
        return /[\u0980-\u09FF]/.test(text);
    }
    
    function renderContentBySetting(value) {
        const text = value == null ? '' : String(value);
    
        const isBangla = containsBangla(text);
    
        if (presentationState.renderHtml) {
    
            if (isBangla) {
                return '<span class="bangla-text">' + text + '</span>';
            }
    
            return text;
        }
    
        const escaped = escapeHtml(text);
    
        if (isBangla) {
            return '<span class="bangla-text">' + escaped + '</span>';
        }
    
        return escaped;
    }
    
    presentationFontIncreaseBtn.addEventListener('click', function () {
        if (presentationState.fontScale < 2.5) {
            presentationState.fontScale = +(presentationState.fontScale + 0.1).toFixed(2);
            applyFontSize();
        }
    });
    
    presentationFontDecreaseBtn.addEventListener('click', function () {
        if (presentationState.fontScale > 0.6) {
            presentationState.fontScale = +(presentationState.fontScale - 0.1).toFixed(2);
            applyFontSize();
        }
    });
    
    function applyFontSize() {
        const scale = presentationState.fontScale || 1;
    
        document.documentElement.style.setProperty('--presentation-font-scale', scale);
    
        stageTitle.style.fontSize = (1.85 * scale) + 'rem';
        stageSubtitle.style.fontSize = (1.08 * scale) + 'rem';
    
        document.querySelectorAll('.presentation-pointer-title').forEach(function (el) {
            el.style.fontSize = (1.0 * scale) + 'rem';
        });
    }
        
    fontIncreaseBtn.addEventListener('click', function () {
        if (presentationState.fontScale < 2.2) {
            presentationState.fontScale = +(presentationState.fontScale + 0.1).toFixed(2);
            applyFontSize();
        }
    });
        
    fontDecreaseBtn.addEventListener('click', function () {
        if (presentationState.fontScale > 0.7) {
            presentationState.fontScale = +(presentationState.fontScale - 0.1).toFixed(2);
            applyFontSize();
        }
    });
        
        function formatPresentationDate(value) {
        const raw = normalizeString(value);
        if (!raw) {
            return '';
        }
    
        if (/^\d{2}-\d{2}-\d{4}$/.test(raw)) {
            return raw;
        }
    
        if (/^\d{4}-\d{2}-\d{2}$/.test(raw)) {
            const parts = raw.split('-');
            return parts[2] + '-' + parts[1] + '-' + parts[0];
        }
    
        if (/^\d{1,2}\/\d{1,2}\/\d{4}$/.test(raw)) {
            const parts = raw.split('/');
            const dd = parts[0].padStart(2, '0');
            const mm = parts[1].padStart(2, '0');
            const yyyy = parts[2];
            return dd + '-' + mm + '-' + yyyy;
        }
    
        if (!isNaN(raw) && Number(raw) > 20000) {
            const excelEpoch = new Date(Date.UTC(1899, 11, 30));
            const jsDate = new Date(excelEpoch.getTime() + Number(raw) * 86400000);
    
            if (!isNaN(jsDate.getTime())) {
                const dd = String(jsDate.getUTCDate()).padStart(2, '0');
                const mm = String(jsDate.getUTCMonth() + 1).padStart(2, '0');
                const yyyy = jsDate.getUTCFullYear();
                return dd + '-' + mm + '-' + yyyy;
            }
        }
    
        const parsed = new Date(raw);
        if (!isNaN(parsed.getTime())) {
            const dd = String(parsed.getDate()).padStart(2, '0');
            const mm = String(parsed.getMonth() + 1).padStart(2, '0');
            const yyyy = parsed.getFullYear();
            return dd + '-' + mm + '-' + yyyy;
        }
    
        return raw;
    }
    
    function isFirstSlide(slideKey) {
        return presentationState.slideKeys.length > 0 && presentationState.slideKeys[0] === slideKey;
    }
    
    function shouldShowPresentationInfo() {
        return (
            isFirstSlide(presentationState.currentSlideKey) &&
            presentationState.visiblePointerCount === 0 &&
            (
                normalizeString(presentationState.presentationMeta.title) ||
                normalizeString(presentationState.presentationMeta.presentedBy) ||
                normalizeString(presentationState.presentationMeta.organizedBy) ||
                normalizeString(presentationState.presentationMeta.date)
            )
        );
    }
    
        function showFeedback(message, type) {
            feedbackBox.className = 'presentation-feedback show ' + (type || 'success');
            feedbackBox.textContent = message || '';
        }
    
        function clearFeedback() {
            feedbackBox.className = 'presentation-feedback';
            feedbackBox.textContent = '';
        }
    
        function escapeHtml(value) {
            const div = document.createElement('div');
            div.textContent = value == null ? '' : String(value);
            return div.innerHTML;
        }
    
        function normalizeString(value) {
            return value == null ? '' : String(value).trim();
        }
    
        function isMobileView() {
            return window.innerWidth < 768;
        }
    
        function ensureSessionKey() {
            if (presentationState.sessionKey) {
                return presentationState.sessionKey;
            }
    
            let savedSessionKey = localStorage.getItem(SESSION_KEY_STORAGE);
            if (!savedSessionKey) {
                savedSessionKey = 'presentation_' + Date.now() + '_' + Math.random().toString(36).slice(2, 8);
                localStorage.setItem(SESSION_KEY_STORAGE, savedSessionKey);
            }
    
            presentationState.sessionKey = savedSessionKey;
            return savedSessionKey;
        }
    
        function resetSessionKey() {
            const newKey = 'presentation_' + Date.now() + '_' + Math.random().toString(36).slice(2, 8);
            presentationState.sessionKey = newKey;
            localStorage.setItem(SESSION_KEY_STORAGE, newKey);
        }
    
        function getSlideObject(slideKey) {
            return presentationState.slides[slideKey] || null;
        }
    
        function getSlideItems(slideKey) {
            return getSlideObject(slideKey)?.items || [];
        }
    
        function getCurrentItemByVisibleIndex(index) {
            const items = getSlideItems(presentationState.currentSlideKey);
            if (index == null || index < 0 || index >= items.length) {
                return null;
            }
            return items[index];
        }
    
        function setSaveIndicator(text) {
            saveIndicator.textContent = text;
            if (saveIndicatorTimeout) {
                clearTimeout(saveIndicatorTimeout);
            }
            saveIndicatorTimeout = setTimeout(function () {
                saveIndicator.textContent = 'Auto saved';
            }, 900);
        }
    
        function persistLocalState() {
            const payload = {
                slides: presentationState.slides,
                slideKeys: presentationState.slideKeys,
                currentSlideKey: presentationState.currentSlideKey,
                currentPointerIndex: presentationState.currentPointerIndex,
                visiblePointerCount: presentationState.visiblePointerCount,
                activeVisiblePointerIndex: presentationState.activeVisiblePointerIndex,
                sessionKey: presentationState.sessionKey,
                currentLayout: presentationState.currentLayout,
                presentationMeta: presentationState.presentationMeta,
                renderHtml: presentationState.renderHtml
            };
    
            try {
                localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(payload));
                localStorage.setItem(LAYOUT_STORAGE_KEY, presentationState.currentLayout);
                setSaveIndicator('Saving...');
            } catch (error) {
                console.error(error);
                saveIndicator.textContent = 'Save failed';
            }
        }
    
        function clearPersistedState() {
            try {
                localStorage.removeItem(LOCAL_STORAGE_KEY);
            } catch (error) {
                console.error(error);
            }
        }
    
        function updateProgress() {
            const total = getSlideItems(presentationState.currentSlideKey).length;
            const visible = presentationState.visiblePointerCount;
        
            const percentage = total > 0 ? (visible / total) * 100 : 0;
            progressBar.style.width = percentage + '%';
            progressText.textContent = visible + ' / ' + total + ' points visible';
        
            const slide = getSlideObject(presentationState.currentSlideKey);
            const totalPointers = slide?.items?.length || 0;
            stageMeta.textContent = totalPointers + ' pointer(s) in this slide';
            
             // ✅ ADD THIS HERE
        const emptyState = document.getElementById('presentationEmptyState');
    
        if (visible > 0) {
            emptyState.style.display = 'none';
        } else {
            emptyState.style.display = 'flex';
        }
        
            renderPresentationMeta();
        }
    
        // function setExplanationValue(text) {
        //     explanationEditor.value = text || '';
        //     syncDetachedWindow();
        // }
        
        function setExplanationValue(text) {
            if (presentationState.renderHtml) {
                explanationEditor.innerHTML = text || '';
            } else {
                explanationEditor.textContent = text || '';
            }
            syncDetachedWindow();
             Prism.highlightAll(); // 👈 ADD HERE
            
        }
    
    explanationEditor.addEventListener('input', function () {
        const item = getCurrentItemByVisibleIndex(presentationState.activeVisiblePointerIndex);
        if (!item) return;
    
        item.explanation = presentationState.renderHtml
            ? explanationEditor.innerHTML
            : explanationEditor.textContent;
    
        persistLocalState();
        syncServerState();
        syncDetachedWindow();
    });
    
    htmlToggleBtn.addEventListener('click', function () {
        presentationState.renderHtml = !presentationState.renderHtml;
        updateHtmlToggleUi();
        renderVisiblePointers();
    
        const activeItem = getCurrentItemByVisibleIndex(presentationState.activeVisiblePointerIndex);
        setExplanationValue(activeItem?.explanation || '');
    
        persistLocalState();
    });
    
        function openMobileExplanation(title, body) {
            mobileSheetTitle.textContent = title || 'Explanation';
            // mobileSheetBody.textContent = body || '';
            if (presentationState.renderHtml) {
                mobileSheetBody.innerHTML = body || '';
            } else {
                mobileSheetBody.textContent = body || '';
            }
            mobileModal.classList.add('show');
            document.body.style.overflow = 'hidden';
        }
    
        function closeMobileExplanation() {
            mobileModal.classList.remove('show');
            document.body.style.overflow = '';
        }
    
        function setLayout(layoutName) {
            const validLayouts = ['top', 'left', 'right'];
            const layout = validLayouts.includes(layoutName) ? layoutName : 'top';
        
            presentationState.currentLayout = layout;
            activeView.className = 'presentation-active-view layout-' + layout;
        
            applySpotlightMode();
        
            localStorage.setItem(LAYOUT_STORAGE_KEY, layout);
        
            document.querySelectorAll('.presentation-layout-mini-btn[data-layout]').forEach(function (btn) {
                btn.classList.toggle('active', btn.getAttribute('data-layout') === layout);
            });
        }
    
        function updateLayoutVisibility() {
            const currentItem = getCurrentItemByVisibleIndex(presentationState.activeVisiblePointerIndex);
            const hasImage = !!normalizeString(currentItem?.image || '');
    
            layoutMiniGroup.classList.toggle('show', hasImage);
    
            if (!hasImage) {
                activeMediaBox.className = 'presentation-active-media-box';
                activeMediaBox.innerHTML = '';
            }
            
            applySpotlightMode();
        }
    
    function renderPresentationMeta() {
        const meta = presentationState.presentationMeta || {
            title: '',
            presentedBy: '',
            organizedBy: '',
            date: ''
        };
    
        const formattedDate = formatPresentationDate(meta.date);
    
        presentationMainTitle.textContent = normalizeString(meta.title) || 'Presentation';
        presentationPresentedBy.textContent = normalizeString(meta.presentedBy) || '-';
        presentationOrganizedBy.textContent = normalizeString(meta.organizedBy) || '-';
        presentationDate.textContent = formattedDate || '-';
    
        const currentSlide = getSlideObject(presentationState.currentSlideKey);
        presentationCurrentSlideLabel.textContent = currentSlide?.slideNumber || '-';
    
        presentationPresentedByCard.style.display = normalizeString(meta.presentedBy) ? '' : 'none';
        presentationOrganizedByCard.style.display = normalizeString(meta.organizedBy) ? '' : 'none';
        presentationDateCard.style.display = formattedDate ? '' : 'none';
        presentationCurrentSlideCard.style.display = 'none';
    
        if (shouldShowPresentationInfo()) {
            presentationInfoBox.classList.add('show');
            pageShell.classList.add('intro-visible');
        } else {
            presentationInfoBox.classList.remove('show');
            pageShell.classList.remove('intro-visible');
        }
    }
    
    function hidePresentationIntroIfVisible() {
        if (presentationInfoBox.classList.contains('show')) {
            presentationInfoBox.classList.remove('show');
        }
    }
    
    let lastRenderedImageUrl = '';
    
    function renderActivePointImage(item) {
        const imageUrl = normalizeString(item?.image || '');
    
        if (imageUrl === '') {
            lastRenderedImageUrl = '';
            activeMediaBox.className = 'presentation-active-media-box';
            activeMediaBox.innerHTML = '';
            applyCinematicImageEffect('');
            updateLayoutVisibility();
            return;
        }
    
        // Same image: do not reload, do not fade again
        if (imageUrl === lastRenderedImageUrl && activeMediaBox.querySelector('img')) {
            updateLayoutVisibility();
            return;
        }
    
        lastRenderedImageUrl = imageUrl;
    
        activeMediaBox.className = 'presentation-active-media-box show';
        activeMediaBox.innerHTML = '';
    
        const img = document.createElement('img');
        img.alt = 'Point image';
    
        applyCinematicImageEffect(imageUrl);
    
        img.addEventListener('load', function () {
            requestAnimationFrame(function () {
                img.classList.add('show');
            });
        });
    
        img.src = imageUrl;
        activeMediaBox.appendChild(img);
    
        updateLayoutVisibility();
    }
    
        function setActivePointer(element, visibleIndex) {
            pointerList.querySelectorAll('.presentation-pointer-item').forEach(function (item) {
                item.classList.remove('active');
            });
        
            if (element) {
                element.classList.add('active');
                pointerList.classList.add('has-active');
            } else {
                pointerList.classList.remove('has-active');
            }
        
            presentationState.activeVisiblePointerIndex = visibleIndex;
        
            const currentItem = getCurrentItemByVisibleIndex(visibleIndex);
            renderActivePointImage(currentItem);
        
            persistLocalState();
            syncServerState();
        }
    
        function renderSlideNav() {
            slideNav.innerHTML = '';
    
            presentationState.slideKeys.forEach(function (slideKey, index) {
                const button = document.createElement('button');
                button.type = 'button';
                button.className = 'presentation-slide-nav-btn' + (slideKey === presentationState.currentSlideKey ? ' active' : '');
                button.textContent = index + 1;
                button.title = slideKey;
    
                button.addEventListener('click', function () {
                    loadSlideByKey(slideKey, true);
                });
    
                slideNav.appendChild(button);
            });
        }
    
        function renderSlideMeta(slideKey) {
            const slide = getSlideObject(slideKey);
            const items = slide ? slide.items : [];
    
            stageTitle.textContent = slide?.title || slideKey || 'Untitled Slide';
            stageSubtitle.textContent = slide?.subtitle || '';
            stageMeta.textContent = items.length + ' pointer(s) in this slide';
            presentationCurrentSlideLabel.textContent = slideKey || '-';
        }
    
        function buildPointerElement(item, visibleIndex) {
            const li = document.createElement('li');
            li.className = 'presentation-pointer-item';
    
            const pointerTitle = normalizeString(item.pointer) || ('Point ' + (visibleIndex + 1));
    
            // li.innerHTML =
            //     '<div class="presentation-pointer-index">' + (visibleIndex + 1) + '</div>' +
            //     '<div class="presentation-pointer-text">' +
            //         '<div class="presentation-pointer-title">' + renderContentBySetting(pointerTitle) + '</div>' +
            //     '</div>';
            const iconValue = normalizeString(item.icon);
    
            let iconHtml = '';
            
            if (iconValue) {
                iconHtml = renderExcelIcon(iconValue); // show icon
            } else {
                iconHtml = (visibleIndex + 1); // fallback number
            }
            
            li.innerHTML =
                '<div class="presentation-pointer-index">' + iconHtml + '</div>' +
                '<div class="presentation-pointer-text">' +
                    '<div class="presentation-pointer-title">' + renderContentBySetting(pointerTitle) + '</div>' +
                '</div>';
    
            li.addEventListener('click', function () {
                setActivePointer(li, visibleIndex);
    
                const currentItem = getCurrentItemByVisibleIndex(visibleIndex);
    
                if (isMobileView()) {
                    openMobileExplanation(pointerTitle, currentItem?.explanation || 'Explanation not available.');
                } else {
                    setExplanationValue(currentItem?.explanation || '');
                }
            });
    
            requestAnimationFrame(function () {
                li.classList.add('show');
            });
    
            return li;
        }
        
        
        function renderExcelIcon(iconValue) {
            const icon = normalizeString(iconValue);
        
            if (!icon) return '';
        
            // Emoji support
            if (/[\u{1F300}-\u{1FAFF}\u{2600}-\u{27BF}]/u.test(icon)) {
                return icon;
            }
        
            // Raw HTML
            if (icon.includes('<') && icon.includes('>')) {
                return icon;
            }
        
            // Font Awesome
            if (icon.includes('fa-')) {
                return '<i class="' + icon + '"></i>';
            }
        
            return icon;
        }
    
        function renderVisiblePointers() {
            pointerList.innerHTML = '';
    
            const items = getSlideItems(presentationState.currentSlideKey);
            const visibleCount = presentationState.visiblePointerCount;
    
            for (let i = 0; i < visibleCount; i++) {
                const li = buildPointerElement(items[i], i);
                li.classList.add('show');
                pointerList.appendChild(li);
            }
    
            if (visibleCount > 0) {
                const activeIndex = presentationState.activeVisiblePointerIndex != null
                    ? Math.min(presentationState.activeVisiblePointerIndex, visibleCount - 1)
                    : visibleCount - 1;
    
                const pointerElements = pointerList.querySelectorAll('.presentation-pointer-item');
                const activeElement = pointerElements[activeIndex];
                const activeItem = items[activeIndex];
    
                if (activeElement) {
                    activeElement.classList.add('active');
                }
    
                renderActivePointImage(activeItem);
    
                if (!isMobileView()) {
                    setExplanationValue(activeItem?.explanation || '');
                }
            } else {
                setExplanationValue('');
                renderActivePointImage(null);
            }
    
            updateProgress();
             Prism.highlightAll();
        }
    
        function showStageControls() {
            stageActions.classList.add('show');
        }
    
        function hideStageControls() {
            stageActions.classList.remove('show');
        }
    
        function loadSlideByKey(slideKey, resetVisibleState) {
            if (!presentationState.slides[slideKey]) {
                return;
            }
    
            presentationState.currentSlideKey = slideKey;
    
            if (resetVisibleState === true) {
                presentationState.currentPointerIndex = 0;
                presentationState.visiblePointerCount = 0;
                presentationState.activeVisiblePointerIndex = null;
            } else {
                const total = getSlideItems(slideKey).length;
                presentationState.currentPointerIndex = Math.min(presentationState.currentPointerIndex, total);
                presentationState.visiblePointerCount = Math.min(presentationState.visiblePointerCount, total);
    
                if (presentationState.visiblePointerCount === 0) {
                    presentationState.activeVisiblePointerIndex = null;
                } else {
                    presentationState.activeVisiblePointerIndex = Math.min(
                        presentationState.activeVisiblePointerIndex ?? (presentationState.visiblePointerCount - 1),
                        presentationState.visiblePointerCount - 1
                    );
                }
            }
    
            renderSlideNav();
            renderSlideMeta(slideKey);
            renderPresentationMeta();
            renderVisiblePointers();
            persistLocalState();
            syncServerState();
            syncDetachedWindow();
            updateProgress(); // added
        }
    
        function revealNextPointer() {
            const slideKey = presentationState.currentSlideKey;
            const items = getSlideItems(slideKey);
    
            if (!slideKey || !items.length) {
                return false;
            }
    
            if (presentationState.currentPointerIndex >= items.length) {
                return false;
            }
    
            const visibleIndex = presentationState.currentPointerIndex;
            const item = items[visibleIndex];
            const li = buildPointerElement(item, visibleIndex);
    
            pointerList.appendChild(li);
    
            presentationState.currentPointerIndex += 1;
            presentationState.visiblePointerCount += 1;
            presentationState.activeVisiblePointerIndex = visibleIndex;
    
            pointerList.querySelectorAll('.presentation-pointer-item').forEach(function (node) {
                node.classList.remove('active');
            });
            li.classList.add('active');
    
            renderActivePointImage(item);
    
            if (!isMobileView()) {
                setExplanationValue(item.explanation || '');
            }
    
            updateProgress();
            persistLocalState();
            syncServerState();
            syncDetachedWindow();
            clearFeedback();
    
            return true;
        }
    
        function goToNextSlideAndRevealFirstPoint() {
            const currentIndex = presentationState.slideKeys.indexOf(presentationState.currentSlideKey);
    
            if (currentIndex < presentationState.slideKeys.length - 1) {
                const nextSlideKey = presentationState.slideKeys[currentIndex + 1];
                loadSlideByKey(nextSlideKey, true);
                revealNextPointer();
                return true;
            }
    
            showFeedback('You are already on the last slide.', 'warning');
            return false;
        }
    
        function nextAction() {
            const revealed = revealNextPointer();
    
            if (!revealed) {
                goToNextSlideAndRevealFirstPoint();
            }
        }
    
        function hideLastPointer() {
            const visibleItems = pointerList.querySelectorAll('.presentation-pointer-item');
    
            if (!visibleItems.length) {
                const currentIndex = presentationState.slideKeys.indexOf(presentationState.currentSlideKey);
    
                if (currentIndex > 0) {
                    const previousSlideKey = presentationState.slideKeys[currentIndex - 1];
                    loadSlideByKey(previousSlideKey, false);
                    const total = getSlideItems(previousSlideKey).length;
                    presentationState.currentPointerIndex = total;
                    presentationState.visiblePointerCount = total;
                    presentationState.activeVisiblePointerIndex = total > 0 ? total - 1 : null;
                    renderVisiblePointers();
                    persistLocalState();
                    syncServerState();
                    syncDetachedWindow();
                    return;
                }
    
                showFeedback('No visible pointer to remove.', 'error');
                return;
            }
    
            visibleItems[visibleItems.length - 1].remove();
    
            presentationState.currentPointerIndex = Math.max(0, presentationState.currentPointerIndex - 1);
            presentationState.visiblePointerCount = Math.max(0, presentationState.visiblePointerCount - 1);
    
            if (presentationState.visiblePointerCount > 0) {
                presentationState.activeVisiblePointerIndex = presentationState.visiblePointerCount - 1;
    
                const items = getSlideItems(presentationState.currentSlideKey);
                const activeItem = items[presentationState.activeVisiblePointerIndex] || null;
                const remaining = pointerList.querySelectorAll('.presentation-pointer-item');
    
                remaining.forEach(function (node) {
                    node.classList.remove('active');
                });
    
                if (remaining.length) {
                    remaining[remaining.length - 1].classList.add('active');
                }
    
                renderActivePointImage(activeItem);
    
                if (!isMobileView()) {
                    setExplanationValue(activeItem?.explanation || '');
                }
            } else {
                presentationState.activeVisiblePointerIndex = null;
                setExplanationValue('');
                renderActivePointImage(null);
            }
    
            updateProgress();
            persistLocalState();
            syncServerState();
            syncDetachedWindow();
            clearFeedback();
        }
    
        function replayCurrentSlide() {
            if (!presentationState.currentSlideKey) {
                showFeedback('Please load a presentation first.', 'error');
                return;
            }
    
            presentationState.currentPointerIndex = 0;
            presentationState.visiblePointerCount = 0;
            presentationState.activeVisiblePointerIndex = null;
            renderVisiblePointers();
            persistLocalState();
            syncServerState();
            syncDetachedWindow();
            clearFeedback();
        }
    
        function tryParsePresentationMetaRow(row) {
            if (!row || !row.length) {
                return null;
            }
    
            const firstCell = normalizeString(row[0]).toLowerCase();
            if (firstCell !== 'presentation title:') {
                return null;
            }
    
            return {
                title: normalizeString(row[1]),
                presentedBy: normalizeString(row[3]),
                organizedBy: normalizeString(row[5]),
                date: normalizeString(row[7])
            };
        }
    
        function parseRowsToSlides(rows) {
            const slides = {};
            let meta = {
                title: '',
                presentedBy: '',
                organizedBy: '',
                date: ''
            };
    
            if (!rows || !rows.length) {
                return { slides, meta };
            }
    
            let headerRowIndex = 0;
            const maybeMeta = tryParsePresentationMetaRow(rows[0]);
    
            if (maybeMeta) {
                meta = maybeMeta;
                headerRowIndex = 1;
            }
    
            let lastSlideNumber = '';
            let lastSlideTitle = '';
            let lastSlideSubtitle = '';
    
            rows.forEach(function (row, index) {
                if (index <= headerRowIndex) return;
    
                const slideNumberCell = normalizeString(row[0]);
                const slideTitleCell = normalizeString(row[1]);
                const slideSubtitleCell = normalizeString(row[2]);
                // const imageCell = normalizeString(row[3]);
                // const pointerCell = normalizeString(row[4]);
                // const explanationCell = normalizeString(row[5]);
                const imageCell = normalizeString(row[3]);
                const iconCell = normalizeString(row[4]);        // ✅ ADD THIS
                const pointerCell = normalizeString(row[5]);     // shifted
                const explanationCell = normalizeString(row[6]); // shifted
    
                const slideNumber = slideNumberCell !== '' ? slideNumberCell : lastSlideNumber;
                const slideTitle = slideTitleCell !== '' ? slideTitleCell : lastSlideTitle;
                const slideSubtitle = slideSubtitleCell !== '' ? slideSubtitleCell : lastSlideSubtitle;
    
                if (!slideNumber) return;
    
                lastSlideNumber = slideNumber;
                lastSlideTitle = slideTitle;
                lastSlideSubtitle = slideSubtitle;
    
                if (!slides[slideNumber]) {
                    slides[slideNumber] = {
                        title: slideTitle || slideNumber,
                        subtitle: slideSubtitle || '',
                        items: []
                    };
                } else {
                    if (slideTitle) slides[slideNumber].title = slideTitle;
                    if (slideSubtitle) slides[slideNumber].subtitle = slideSubtitle;
                }
    
                if (pointerCell === '' && explanationCell === '' && imageCell === '') {
                    return;
                }
    
                // slides[slideNumber].items.push({
                //     pointer: pointerCell,
                //     explanation: explanationCell,
                //     image: imageCell
                // });
                slides[slideNumber].items.push({
                    icon: iconCell,          // ✅ ADD THIS
                    pointer: pointerCell,
                    explanation: explanationCell,
                    image: imageCell
                });
            });
    
            return { slides, meta };
        }
    
        function sortSlideKeys(slideObject) {
            return Object.keys(slideObject).sort(function (a, b) {
                const aNum = parseInt(String(a).replace(/[^\d]/g, ''), 10);
                const bNum = parseInt(String(b).replace(/[^\d]/g, ''), 10);
    
                if (!isNaN(aNum) && !isNaN(bNum) && aNum !== bNum) {
                    return aNum - bNum;
                }
    
                return String(a).localeCompare(String(b), undefined, {
                    numeric: true,
                    sensitivity: 'base'
                });
            });
        }
    
        function handleWorkbook(workbook) {
            const firstSheetName = workbook.SheetNames[0];
    
            if (!firstSheetName) {
                showFeedback('No worksheet found in the uploaded file.', 'error');
                return;
            }
    
            const worksheet = workbook.Sheets[firstSheetName];
            const rows = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: '' });
            const parsed = parseRowsToSlides(rows);
            const slides = parsed.slides;
            const slideKeys = sortSlideKeys(slides);
    
            if (!slideKeys.length) {
                showFeedback('No valid slide data found. Please check your Excel columns and values.', 'error');
                return;
            }
    
            presentationState.slides = slides;
            presentationState.slideKeys = slideKeys;
            presentationState.currentSlideKey = slideKeys[0];
            presentationState.currentPointerIndex = 0;
            presentationState.visiblePointerCount = 0;
            presentationState.activeVisiblePointerIndex = null;
            presentationState.presentationMeta = parsed.meta || {
                title: '',
                presentedBy: '',
                organizedBy: '',
                date: ''
            };
    
            ensureSessionKey();
            renderSlideNav();
            renderPresentationMeta();
            loadSlideByKey(slideKeys[0], true);
            persistLocalState();
            saveSessionToServer();
            showStageControls();
            showFeedback('Presentation loaded successfully with ' + slideKeys.length + ' slide(s).', 'success');
        }
    
        function readFileAndLoad(file) {
            if (!file) {
                showFeedback('Please choose an Excel or CSV file first.', 'error');
                return;
            }
    
            const fileName = file.name.toLowerCase();
            const reader = new FileReader();
    
            reader.onload = function (event) {
                try {
                    let workbook;
    
                    if (fileName.endsWith('.csv')) {
                        workbook = XLSX.read(event.target.result, { type: 'string' });
                    } else {
                        const data = new Uint8Array(event.target.result);
                        workbook = XLSX.read(data, { type: 'array' });
                    }
    
                    handleWorkbook(workbook);
                } catch (error) {
                    console.error(error);
                    showFeedback('Could not read the file. Please use a proper Excel or CSV template.', 'error');
                }
            };
    
            if (fileName.endsWith('.csv')) {
                reader.readAsText(file);
            } else {
                reader.readAsArrayBuffer(file);
            }
        }
    
        function restoreStateFromStorage() {
            try {
                const raw = localStorage.getItem(LOCAL_STORAGE_KEY);
                if (!raw) {
                    saveIndicator.textContent = 'Auto save off';
                    setLayout(presentationState.currentLayout);
                    renderPresentationMeta();
                    return;
                }
                
                const saved = JSON.parse(raw);
                presentationState.renderHtml = !!saved.renderHtml;
    
                if (!saved || !saved.slides || !saved.slideKeys || !saved.slideKeys.length) {
                    setLayout(presentationState.currentLayout);
                    renderPresentationMeta();
                    return;
                }
    
                presentationState.slides = saved.slides || {};
                presentationState.slideKeys = saved.slideKeys || [];
                presentationState.currentSlideKey = saved.currentSlideKey || saved.slideKeys[0];
                presentationState.currentPointerIndex = saved.currentPointerIndex || 0;
                presentationState.visiblePointerCount = saved.visiblePointerCount || 0;
                presentationState.activeVisiblePointerIndex = saved.activeVisiblePointerIndex;
                presentationState.sessionKey = saved.sessionKey || localStorage.getItem(SESSION_KEY_STORAGE) || ensureSessionKey();
                presentationState.currentLayout = saved.currentLayout || localStorage.getItem(LAYOUT_STORAGE_KEY) || 'top';
                presentationState.presentationMeta = saved.presentationMeta || {
                    title: '',
                    presentedBy: '',
                    organizedBy: '',
                    date: ''
                };
    
                setLayout(presentationState.currentLayout);
                renderPresentationMeta();
                renderSlideNav();
                loadSlideByKey(presentationState.currentSlideKey, false);
                showStageControls();
                saveIndicator.textContent = 'Auto saved';
                showFeedback('Saved presentation restored from this browser.', 'success');
            } catch (error) {
                console.error(error);
                saveIndicator.textContent = 'Restore failed';
                setLayout(presentationState.currentLayout);
                renderPresentationMeta();
            }
        }
    
        function resetPresentation() {
            presentationState.slides = {};
            presentationState.slideKeys = [];
            presentationState.currentSlideKey = null;
            presentationState.currentPointerIndex = 0;
            presentationState.visiblePointerCount = 0;
            presentationState.activeVisiblePointerIndex = null;
            presentationState.renderHtml = false;
            presentationState.presentationMeta = {
                title: '',
                presentedBy: '',
                organizedBy: '',
                date: ''
            };
    
            slideNav.innerHTML = '';
            stageTitle.textContent = 'Slide title will appear here';
            stageSubtitle.textContent = 'Slide subtitle will appear here';
            stageMeta.textContent = '0 pointer(s) in this slide';
            pointerList.innerHTML = '';
            activeMediaBox.className = 'presentation-active-media-box';
            activeMediaBox.innerHTML = '';
            explanationEditor.value = '';
            progressBar.style.width = '0%';
            progressText.textContent = '0 / 0 points visible';
            fileInput.value = '';
            clearPersistedState();
            resetSessionKey();
            clearFeedback();
            hideStageControls();
            saveIndicator.textContent = 'Auto save off';
            layoutMiniGroup.classList.remove('show');
            renderPresentationMeta();
            syncDetachedWindow();
    
            if (detachedWindow && !detachedWindow.closed) {
                detachedWindow.close();
                detachedWindow = null;
            }
    
            explanationPanel.style.display = 'flex';
            detachBtn.textContent = '⧉';
            detachBtn.title = 'Detach Explanation';
            setLayout(localStorage.getItem(LAYOUT_STORAGE_KEY) || 'top');
        }
    
        function toggleFullscreen() {
            if (!document.fullscreenElement) {
                if (pageShell.requestFullscreen) {
                    pageShell.requestFullscreen();
                } else if (pageShell.webkitRequestFullscreen) {
                    pageShell.webkitRequestFullscreen();
                }
            } else {
                if (document.exitFullscreen) {
                    document.exitFullscreen();
                } else if (document.webkitExitFullscreen) {
                    document.webkitExitFullscreen();
                }
            }
        }
    
        function syncFullscreenUi() {
            const isFs = !!document.fullscreenElement;
            pageShell.classList.toggle('fullscreen-mode', isFs);
            fullscreenBtn.textContent = isFs ? '⤢' : '⛶';
            fullscreenBtn.title = isFs ? 'Exit Fullscreen' : 'Fullscreen';
        }
    
        function toggleDetachExplanation() {
            if (detachedWindow && !detachedWindow.closed) {
                detachedWindow.close();
                detachedWindow = null;
                explanationPanel.style.display = 'flex';
                detachBtn.textContent = '⧉';
                detachBtn.title = 'Detach Explanation';
                return;
            }
    
            detachedWindow = window.open('', 'presentationExplanationWindow', 'width=700,height=900,left=100,top=60,resizable=yes,scrollbars=yes');
    
            if (!detachedWindow) {
                showFeedback('Popup window blocked by browser. Please allow popups for this page.', 'error');
                return;
            }
    
            detachedWindow.document.write(`
                <!DOCTYPE html>
                <html>
                <head>
                    <title>Presentation Explanation</title>
                    <meta charset="utf-8">
                    <style>
                        body{
                            margin:0;
                            padding:18px;
                            font-family: Arial, sans-serif;
                            background:#f8fafc;
                            color:#111827;
                        }
                        .wrap{
                            max-width:100%;
                        }
                        .title{
                            font-size:24px;
                            font-weight:700;
                            margin-bottom:8px;
                            line-height:1.4;
                        }
                        .subtitle{
                            color:#6b7280;
                            margin-bottom:10px;
                            line-height:1.7;
                        }
                        .meta{
                            font-size:13px;
                            color:#64748b;
                            margin-bottom:14px;
                        }
                        textarea{
                            width:100%;
                            min-height:360px;
                            border:1px solid #e5e7eb;
                            border-radius:14px;
                            padding:16px;
                            line-height:1.85;
                            font-size:15px;
                            resize:vertical;
                            box-sizing:border-box;
                        }
                    </style>
                </head>
                <body>
                    <div class="wrap">
                        <div class="title" id="detachedTitle"></div>
                        <div class="subtitle" id="detachedSubtitle"></div>
                        <div class="meta" id="detachedMeta"></div>
                        <textarea id="detachedExplanationEditor"></textarea>
                    </div>
                </body>
                </html>
            `);
    
            detachedWindow.document.close();
            explanationPanel.style.display = 'none';
            detachBtn.textContent = '⇲';
            detachBtn.title = 'Attach Explanation Back';
            syncDetachedWindow();
    
            // const extEditor = detachedWindow.document.getElementById('detachedExplanationEditor');
            // if (extEditor) {
            //     extEditor.addEventListener('input', function () {
            //         explanationEditor.value = extEditor.value;
            //         const item = getCurrentItemByVisibleIndex(presentationState.activeVisiblePointerIndex);
            //         if (item) {
            //             item.explanation = explanationEditor.value;
            //             persistLocalState();
            //             syncServerState();
            //         }
            //     });
            // }
            const extEditor = detachedWindow.document.getElementById('detachedExplanationEditor');
            if (extEditor) {
                extEditor.addEventListener('input', function () {
                    if (presentationState.renderHtml) {
                        explanationEditor.innerHTML = extEditor.value;
                    } else {
                        explanationEditor.textContent = extEditor.value;
                    }
            
                    const item = getCurrentItemByVisibleIndex(presentationState.activeVisiblePointerIndex);
                    if (item) {
                        item.explanation = extEditor.value;
                        persistLocalState();
                        syncServerState();
                        syncDetachedWindow();
                    }
                });
            }
    
            detachedWindow.addEventListener('beforeunload', function () {
                detachedWindow = null;
                explanationPanel.style.display = 'flex';
                detachBtn.textContent = '⧉';
                detachBtn.title = 'Detach Explanation';
            });
        }
    
        function syncDetachedWindow() {
            if (!detachedWindow || detachedWindow.closed) {
                return;
            }
    
            const slide = getSlideObject(presentationState.currentSlideKey);
            const activeItem = getCurrentItemByVisibleIndex(presentationState.activeVisiblePointerIndex);
    
            const titleEl = detachedWindow.document.getElementById('detachedTitle');
            const subtitleEl = detachedWindow.document.getElementById('detachedSubtitle');
            const metaEl = detachedWindow.document.getElementById('detachedMeta');
            const editorEl = detachedWindow.document.getElementById('detachedExplanationEditor');
    
            if (!titleEl || !subtitleEl || !metaEl || !editorEl) {
                return;
            }
    
            titleEl.textContent = slide?.title || 'Presentation Explanation';
            subtitleEl.textContent = slide?.subtitle || '';
            metaEl.textContent = activeItem?.pointer ? ('Current Pointer: ' + activeItem.pointer) : 'No pointer selected';
    
            // if (detachedWindow.document.activeElement !== editorEl) {
            //     editorEl.value = explanationEditor.value || '';
            // }
            if (detachedWindow.document.activeElement !== editorEl) {
                editorEl.value = presentationState.renderHtml
                    ? (explanationEditor.innerHTML || '')
                    : (explanationEditor.textContent || '');
            }
        }
    
        async function saveSessionToServer() {
            try {
                await fetch('/presentation/save', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        session_key: ensureSessionKey(),
                        slides: presentationState.slides
                    })
                });
            } catch (error) {
                console.error(error);
            }
        }
    
        async function syncServerState() {
            if (!presentationState.currentSlideKey || !presentationState.slideKeys.length) {
                return;
            }
    
            try {
                await fetch('/presentation/update', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        session_key: ensureSessionKey(),
                        slide: presentationState.currentSlideKey,
                        pointer_index: presentationState.currentPointerIndex,
                        visible_count: presentationState.visiblePointerCount
                    })
                });
            } catch (error) {
                console.error(error);
            }
        }
    
        async function fetchLiveState() {
            if (!presentationState.sessionKey) {
                return;
            }
    
            try {
                const response = await fetch('/presentation/state?session_key=' + encodeURIComponent(presentationState.sessionKey));
                const result = await response.json();
    
                if (!result || result.status !== 'success' || !result.data) {
                    return;
                }
    
                const serverState = result.data;
    
                if (!serverState.current_slide) {
                    return;
                }
    
                if (!presentationState.slideKeys.length) {
                    return;
                }
    
                const targetSlideKey = serverState.current_slide;
                const targetVisibleCount = parseInt(serverState.visible_pointer_count || 0, 10);
    
                if (!presentationState.slides[targetSlideKey]) {
                    return;
                }
    
                if (presentationState.currentSlideKey !== targetSlideKey) {
                    loadSlideByKey(targetSlideKey, true);
                }
    
                if (presentationState.visiblePointerCount !== targetVisibleCount) {
                    presentationState.currentPointerIndex = targetVisibleCount;
                    presentationState.visiblePointerCount = targetVisibleCount;
                    presentationState.activeVisiblePointerIndex = targetVisibleCount > 0 ? targetVisibleCount - 1 : null;
                    renderVisiblePointers();
                }
            } catch (error) {
                console.error(error);
            }
        }
    
        function startLivePolling() {
            if (syncInterval) {
                clearInterval(syncInterval);
            }
    
            syncInterval = setInterval(function () {
                fetchLiveState();
            }, 2000);
        }
    
        // explanationEditor.addEventListener('input', function () {
        //     const item = getCurrentItemByVisibleIndex(presentationState.activeVisiblePointerIndex);
        //     if (!item) return;
    
        //     item.explanation = explanationEditor.value;
        //     persistLocalState();
        //     syncServerState();
        //     syncDetachedWindow();
        // });
        explanationEditor.addEventListener('input', function () {
            const item = getCurrentItemByVisibleIndex(presentationState.activeVisiblePointerIndex);
            if (!item) return;
        
            item.explanation = presentationState.renderHtml
                ? explanationEditor.innerHTML
                : explanationEditor.textContent;
        
            persistLocalState();
            syncServerState();
            syncDetachedWindow();
        });
    
        layoutMiniGroup.addEventListener('click', function (event) {
            const btn = event.target.closest('.presentation-layout-mini-btn[data-layout]');
            if (!btn) return;
        
            spotlightModeEnabled = false;
            applySpotlightMode();
        
            setLayout(btn.getAttribute('data-layout'));
            persistLocalState();
        });
    
        loadBtn.addEventListener('click', function () {
            clearFeedback();
            readFileAndLoad(fileInput.files && fileInput.files[0] ? fileInput.files[0] : null);
        });
    
        resetBtn.addEventListener('click', resetPresentation);
    
        prevBtn.addEventListener('click', function () {
            if (!presentationState.currentSlideKey) {
                showFeedback('Please load a presentation first.', 'error');
                return;
            }
            hideLastPointer();
        });
    
        nextBtn.addEventListener('click', function () {
            if (!presentationState.currentSlideKey) {
                showFeedback('Please load a presentation first.', 'error');
                return;
            }
            nextAction();
        });
        
        document.addEventListener('keydown', function (event) {
        
            // Ignore typing inside editable/input fields
            const activeTag = document.activeElement.tagName.toLowerCase();
        
            const isTyping =
                activeTag === 'input' ||
                activeTag === 'textarea' ||
                document.activeElement.isContentEditable;
        
            if (isTyping) {
                return;
            }
        
            // RIGHT ARROW = Next Point
            if (event.key === 'ArrowRight') {
                event.preventDefault();
        
                if (!presentationState.currentSlideKey) {
                    return;
                }
        
                nextAction();
            }
        
            // LEFT ARROW = Previous Point
            if (event.key === 'ArrowLeft') {
                event.preventDefault();
        
                if (!presentationState.currentSlideKey) {
                    return;
                }
        
                hideLastPointer();
            }
        });
    
        replayBtn.addEventListener('click', replayCurrentSlide);
        detachBtn.addEventListener('click', toggleDetachExplanation);
        fullscreenBtn.addEventListener('click', toggleFullscreen);
     
    
        mobileCloseBtn.addEventListener('click', closeMobileExplanation);
        mobileModal.addEventListener('click', function (event) {
            if (event.target === mobileModal) {
                closeMobileExplanation();
            }
        });
    
        document.addEventListener('fullscreenchange', syncFullscreenUi);
        document.addEventListener('webkitfullscreenchange', syncFullscreenUi);
    
        window.addEventListener('resize', function () {
            if (!isMobileView()) {
                closeMobileExplanation();
            }
        });
        
        
        document.getElementById('presentationSaveToServerBtn').addEventListener('click', function () {
            const file = fileInput.files && fileInput.files[0] ? fileInput.files[0] : null;
        
            if (!file) {
                showFeedback('Please choose an Excel file first before saving to server.', 'error');
                return;
            }
        
            const formData = new FormData();
            formData.append('excel_file', file);
        
            const btn = document.getElementById('presentationSaveToServerBtn');
            btn.textContent = 'Saving...';
            btn.disabled = true;
        
            fetch('/presentation/upload-excel', {
                method: 'POST',
                headers: {
                    'X-Requested-With': 'XMLHttpRequest'
                },
                body: formData
            })
            .then(function (response) { return response.json(); })
            .then(function (result) {
                if (result.status === 'success') {
                    showFeedback('File saved to server: ' + result.filename, 'success');
                } else {
                    showFeedback('Server error: ' + result.message, 'error');
                }
            })
            .catch(function () {
                showFeedback('Network error. Could not reach server.', 'error');
            })
            .finally(function () {
                btn.textContent = 'Save to Server';
                btn.disabled = false;
            });
        });
        
        /* ── helpers ── */
        function formatFileSize(bytes) {
            if (bytes < 1024) return bytes + ' B';
            if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB';
            return (bytes / 1048576).toFixed(2) + ' MB';
        }
        
        function formatModifiedDate(ts) {
            const d = new Date(ts * 1000);
            return d.toLocaleDateString() + ' ' + d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
        }
        
        /* ── load a file from a URL into the viewer ── */
        function loadExcelFromUrl(url, filename) {
            showFeedback('Fetching ' + filename + ' from server...', 'success');
        
            fetch(url)
                .then(function (r) {
                    if (!r.ok) throw new Error('HTTP ' + r.status);
                    return r.arrayBuffer();
                })
                .then(function (buffer) {
                    const data = new Uint8Array(buffer);
                    let workbook;
        
                    if (filename.toLowerCase().endsWith('.csv')) {
                        const text = new TextDecoder().decode(data);
                        workbook = XLSX.read(text, { type: 'string' });
                    } else {
                        workbook = XLSX.read(data, { type: 'array' });
                    }
        
                    handleWorkbook(workbook);
                })
                .catch(function (err) {
                    showFeedback('Could not load file from server: ' + err.message, 'error');
                });
        }
        
        /* ── Save to Server ── */
        document.getElementById('presentationSaveToServerBtn').addEventListener('click', function () {
            const file = fileInput.files && fileInput.files[0] ? fileInput.files[0] : null;
        
            if (!file) {
                showFeedback('Please choose an Excel file first before saving to server.', 'error');
                return;
            }
        
            const formData = new FormData();
            formData.append('excel_file', file);
        
            const btn = document.getElementById('presentationSaveToServerBtn');
            btn.textContent = 'Saving...';
            btn.disabled = true;
        
            fetch('/presentation/upload-excel', {
                method: 'POST',
                headers: { 'X-Requested-With': 'XMLHttpRequest' },
                body: formData
            })
            .then(function (r) { return r.json(); })
            .then(function (result) {
                if (result.status === 'success') {
                    showFeedback('Saved to server: ' + result.filename, 'success');
                } else {
                    showFeedback('Server error: ' + result.message, 'error');
                }
            })
            .catch(function () {
                showFeedback('Network error. Could not reach server.', 'error');
            })
            .finally(function () {
                btn.textContent = 'Save to Server';
                btn.disabled = false;
            });
        });
        
        /* ── Load Latest ── */
        document.getElementById('presentationLoadLatestBtn').addEventListener('click', function () {
            const btn = document.getElementById('presentationLoadLatestBtn');
            btn.textContent = 'Loading...';
            btn.disabled = true;
        
            fetch('/presentation/latest-excel', {
                headers: { 'X-Requested-With': 'XMLHttpRequest' }
            })
            .then(function (r) { return r.json(); })
            .then(function (result) {
                if (result.status !== 'success') {
                    showFeedback(result.message || 'No files found on server.', 'error');
                    return;
                }
                loadExcelFromUrl(result.url, result.filename);
            })
            .catch(function () {
                showFeedback('Could not reach server.', 'error');
            })
            .finally(function () {
                btn.textContent = 'Load Latest';
                btn.disabled = false;
            });
        });
        
        /* ── All Excels modal ── */
        const excelModal     = document.getElementById('presentationExcelModal');
        const excelModalBody = document.getElementById('presentationExcelModalBody');
        
        document.getElementById('presentationAllExcelsBtn').addEventListener('click', function () {
            excelModal.style.display = 'flex';
            excelModalBody.innerHTML = '<div style="color:var(--presentation-text-soft,#6b7280);font-size:0.9rem;">Loading...</div>';
        
            fetch('/presentation/list-excels', {
                headers: { 'X-Requested-With': 'XMLHttpRequest' }
            })
            .then(function (r) { return r.json(); })
            .then(function (result) {
                if (!result.files || !result.files.length) {
                    excelModalBody.innerHTML =
                        '<div style="color:var(--presentation-text-soft,#6b7280);font-size:0.9rem;padding:20px 0;">No Excel files found on server.</div>';
                    return;
                }
        
                let html = '<div style="display:flex;flex-direction:column;gap:10px;">';
        
                result.files.forEach(function (file, index) {
                    const isLatest = index === 0;
                
                    html += '<div style="' +
                        'display:flex;align-items:center;gap:12px;' +
                        'padding:12px 14px;border-radius:14px;' +
                        'border:1px solid var(--presentation-border,rgba(0,0,0,0.08));' +
                        'background:var(--presentation-panel-bg,#fff);' +
                        (isLatest ? 'border-color:rgba(13,110,253,0.35);' : '') +
                    '">';
                
                    /* icon */
                    html += '<div style="' +
                        'width:42px;height:42px;min-width:42px;border-radius:12px;' +
                        'background:rgba(13,110,253,0.10);' +
                        'display:flex;align-items:center;justify-content:center;font-size:1.3rem;">📊</div>';
                
                    /* meta */
                    html += '<div style="flex:1;min-width:0;">' +
                        '<div style="font-weight:700;font-size:0.9rem;color:var(--presentation-text,#1f2937);' +
                        'white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" title="' + file.name + '">' +
                        file.name +
                        (isLatest
                            ? ' <span style="font-size:0.72rem;background:rgba(13,110,253,0.12);' +
                              'color:#0d6efd;padding:2px 8px;border-radius:999px;font-weight:700;">Latest</span>'
                            : '') +
                        '</div>' +
                        '<div style="font-size:0.78rem;color:var(--presentation-text-soft,#6b7280);margin-top:2px;">' +
                        formatFileSize(file.size) + '  ·  ' + formatModifiedDate(file.modified) +
                        '</div>' +
                    '</div>';
                
                    /* Load + Download buttons */
                    html += '<div style="display:flex;gap:6px;align-items:center;">';
                
                    html += '<button type="button" ' +
                        'data-url="' + file.url + '" ' +
                        'data-name="' + file.name + '" ' +
                        'class="presentation-excel-load-btn" ' +
                        'style="' +
                        'border:1px solid var(--presentation-border,rgba(0,0,0,0.08));' +
                        'background:var(--presentation-primary,#0d6efd);color:#fff;' +
                        'border-radius:10px;padding:7px 14px;font-weight:700;' +
                        'font-size:0.82rem;cursor:pointer;white-space:nowrap;' +
                        'transition:opacity 0.18s;">Load</button>';
                
                    html += '<a href="' + file.url + '" download="' + file.name + '" ' +
                        'style="' +
                        'display:inline-flex;align-items:center;gap:5px;' +
                        'border:1px solid var(--presentation-border,rgba(0,0,0,0.08));' +
                        'background:var(--presentation-panel-bg,#fff);' +
                        'color:var(--presentation-text,#1f2937);' +
                        'border-radius:10px;padding:7px 14px;font-weight:700;' +
                        'font-size:0.82rem;cursor:pointer;white-space:nowrap;' +
                        'text-decoration:none;transition:opacity 0.18s;">⬇ Download</a>';
                
                    html += '</div>';
                
                    html += '</div>';
                });
        
                html += '</div>';
                excelModalBody.innerHTML = html;
        
                /* wire up load buttons */
                excelModalBody.querySelectorAll('.presentation-excel-load-btn').forEach(function (btn) {
                    btn.addEventListener('click', function () {
                        const url  = btn.getAttribute('data-url');
                        const name = btn.getAttribute('data-name');
        
                        excelModal.style.display = 'none';
                        loadExcelFromUrl(url, name);
                    });
                });
            })
            .catch(function () {
                excelModalBody.innerHTML =
                    '<div style="color:#dc3545;font-size:0.9rem;">Could not load file list from server.</div>';
            });
        });
        
        document.getElementById('presentationExcelModalClose').addEventListener('click', function () {
            excelModal.style.display = 'none';
        });
        
        excelModal.addEventListener('click', function (e) {
            if (e.target === excelModal) excelModal.style.display = 'none';
        });
            
        resetSessionKey();
        setLayout(presentationState.currentLayout);
        renderPresentationMeta();
        restoreStateFromStorage();
        updateHtmlToggleUi();
        startLivePolling();
        presentationState.fontScale = 1.76;
        applyFontSize();
    })();
    </script>
     
    
    <?php require_once __DIR__ . '/../partials/footer.php'; ?>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/prismjs/prism.min.js"></script>
    
    <!-- Load languages you need -->
    <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-java.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-php.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-javascript.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/prismjs/components/prism-markup.min.js"></script>
    
    </pre></xmp>