<?php
// Force login BEFORE any output
session_start();
require_once __DIR__ . '/../core/db_config.php'; // adjust if needed
if (empty($_SESSION['username'])) {
$redirect = urlencode($_SERVER['REQUEST_URI'] ?? '/');
header("Location: /core/auth/login.php?redirect={$redirect}");
exit;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Overlay Demo (Array Buttons)</title>
<style>
:root{ --bg:#0b0f14; --fg:#e6edf3; --muted:#9aa4b2; --accent:#4ea1ff; --overlay:#0b0f14f2; --btn:#1a2332; --btn-hover:#263244; --ring:0 0 0 3px rgba(78,161,255,.35); }
html,body{height:100%;}
body{ margin:0; font-family: system-ui, -apple-system, Segoe UI, Roboto, Inter, "Helvetica Neue", Arial; background: var(--bg); color: var(--fg); }
.topbar{ position: sticky; top: 0; z-index: 5; background: linear-gradient(180deg, rgba(11,15,20,.95), rgba(11,15,20,.85)); border-bottom: 1px solid #1e2633; backdrop-filter: blur(6px); }
.topbar-inner{ max-width: 1000px; margin: 0 auto; padding: .75rem; display: flex; gap: .75rem; align-items: center; overflow-x: auto; scrollbar-width: thin; }
.chip{ flex:0 0 auto; border:1px solid #2a3648; background:var(--btn); color:var(--fg); padding:.55rem .9rem; border-radius:999px; font-weight:600; font-size:.95rem; cursor:pointer; transition:background .15s ease, transform .06s ease; }
.chip:hover{ background:var(--btn-hover);} .chip:active{ transform:translateY(1px);} .chip:focus-visible{ outline:none; box-shadow:var(--ring);}
.container{ max-width:1000px; margin:1.25rem auto; padding:0 .75rem; }
.lead{ color:var(--muted); }
/* Fullscreen overlay that covers header too */
.overlay{
position: fixed !important;
top: 0 !important;
left: 0 !important;
right: 0 !important;
bottom: 0 !important;
display: none;
place-items: center;
background: var(--overlay);
z-index: 2147483647 !important; /* Maximum possible z-index */
pointer-events: none; /* Allow clicks to pass through when closed */
}
.overlay.open{
display: grid !important;
pointer-events: auto !important; /* Re-enable clicks when open */
}
.dialog{
width: min(900px, 95vw);
height: min(95vh, calc(100vh - 40px)); /* Larger but with small margins */
background: #0e1520;
border: 1px solid #1f2a3a;
border-radius: 18px;
display: grid;
grid-template-rows: auto 1fr auto;
overflow: hidden;
}
.dialog-header{ display:flex; align-items:center; justify-content:space-between; padding:.75rem .9rem; border-bottom:1px solid #1b2534; }
.dialog-title{ font-size:1rem; font-weight:700; }
.xbtn{ border:1px solid #2a3648; background:var(--btn); color:var(--fg); border-radius:10px; padding:.5rem .65rem; cursor:pointer; }
.xbtn:hover{ background:var(--btn-hover);} .xbtn:focus-visible{ outline:none; box-shadow:var(--ring);}
.dialog-body{ padding:1rem; overflow:auto; }
.slide{ display:none; } .slide.active{ display:block; animation:fade .2s ease; }
@keyframes fade{ from{opacity:0; transform:translateY(4px);} to{opacity:1; transform:translateY(0);} }
.dialog-footer{ display:flex; align-items:center; justify-content:space-between; padding:.75rem; border-top:1px solid #1b2534; }
.nav-btn{ border:1px solid #2a3648; background:var(--btn); color:var(--fg); border-radius:12px; padding:.7rem 1rem; font-weight:700; cursor:pointer; }
.nav-btn:hover{ background:var(--btn-hover);} .nav-btn:focus-visible{ outline:none; box-shadow:var(--ring);}
.index{ color:var(--muted); font-size:.95rem; }
</style>
</head>
<body>
<?php include __DIR__ . '/../core/auth/header.php'; ?>
<header class="topbar">
<div class="topbar-inner" id="buttonRow"></div>
</header>
<main class="container">
<h1>Array-based buttons → fullscreen overlay</h1>
<p class="lead">Tap a chip above to open a fullscreen overlay. Use ←/→ or swipe to move, and Esc or the × to close.</p>
</main>
<div class="overlay" id="overlay">
<section class="dialog">
<header class="dialog-header">
<div class="dialog-title" id="dialogTitle">Title</div>
<button class="xbtn" id="closeBtn">✕</button>
</header>
<div class="dialog-body" id="dialogBody"></div>
<footer class="dialog-footer">
<button class="nav-btn" id="prevBtn">← Prev</button>
<div class="index" id="indexInfo">1 / 1</div>
<button class="nav-btn" id="nextBtn">Next →</button>
</footer>
</section>
</div>
<script>
const items = [
{ title: 'Welcome', html: `<h2>Welcome 👋</h2><p>This overlay is driven entirely by an <strong>array</strong> of items.</p>` },
{ title: 'Image', html: `<img src="https://picsum.photos/800/400" alt="Random scenic" style="width:100%;border-radius:12px;"/>` },
{ title: 'Code', html: `<pre><code>// Array-based buttons
const items = [ { title: 'Welcome', html: '<p>…</p>' } ];</code></pre>` },
];
const row = document.getElementById('buttonRow');
const overlay = document.getElementById('overlay');
const titleEl = document.getElementById('dialogTitle');
const bodyEl = document.getElementById('dialogBody');
const indexEl = document.getElementById('indexInfo');
const closeBtn = document.getElementById('closeBtn');
const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn');
let current = 0;
let overlayOriginalParent = overlay.parentNode; // Store original parent
items.forEach((item, i) => {
const btn = document.createElement('button');
btn.className = 'chip';
btn.textContent = item.title;
btn.onclick = () => openOverlay(i);
row.appendChild(btn);
});
const slides = items.map(item => {
const el = document.createElement('article');
el.className = 'slide';
el.innerHTML = item.html;
bodyEl.appendChild(el);
return el;
});
function update(){
titleEl.textContent = items[current].title;
slides.forEach((s, i) => s.classList.toggle('active', i === current));
indexEl.textContent = `${current+1} / ${items.length}`;
}
function openOverlay(i=0){
current = i;
// Multiple strategies to ensure overlay is on top:
// 1. Move overlay to document root (above body)
document.documentElement.appendChild(overlay);
// 2. Force all other elements to lower z-index
const allElements = document.querySelectorAll('*:not(.overlay):not(.overlay *)');
allElements.forEach(el => {
const computedStyle = window.getComputedStyle(el);
if (computedStyle.position !== 'static' && computedStyle.zIndex !== 'auto') {
el.dataset.originalZIndex = computedStyle.zIndex;
el.style.zIndex = '1';
}
});
overlay.classList.add('open');
document.body.style.overflow = 'hidden'; // prevent background scroll
update();
closeBtn.focus();
}
function closeOverlay(){
overlay.classList.remove('open');
document.body.style.overflow = ''; // restore scroll
// Restore original z-index values
const allElements = document.querySelectorAll('[data-original-z-index]');
allElements.forEach(el => {
el.style.zIndex = el.dataset.originalZIndex;
delete el.dataset.originalZIndex;
});
// Move overlay back to its original position in the DOM
if (overlayOriginalParent && overlayOriginalParent !== document.documentElement) {
overlayOriginalParent.appendChild(overlay);
}
}
function next(){ current = (current+1)%items.length; update(); }
function prev(){ current = (current-1+items.length)%items.length; update(); }
closeBtn.onclick = closeOverlay;
nextBtn.onclick = next;
prevBtn.onclick = prev;
window.addEventListener('keydown', e => {
if (!overlay.classList.contains('open')) return;
if (e.key === 'Escape') closeOverlay();
if (e.key === 'ArrowRight') next();
if (e.key === 'ArrowLeft') prev();
});
overlay.addEventListener('click', e => { if (e.target === overlay) closeOverlay(); });
// Ensure overlay is always ready to be moved to the top
// This runs after the page loads to prepare the overlay
document.addEventListener('DOMContentLoaded', function() {
// Store the original parent for cleanup
overlayOriginalParent = overlay.parentNode;
});
</script>
</body>
</html>