<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>deBlurr – Frame TV Art</title>
<meta name="description" content="Discover curated high-resolution art for Samsung Frame TV – browse categories, search the gallery and get help.">
<link rel="canonical" href="http://deblurr.com/index.php">
<link rel="stylesheet" href="/style.css?v=3">
<!-- Explicit favicon to ensure deBlurr logo shows in tab (avoid browser default/third‑party icon) -->
<link rel="icon" type="image/png" sizes="32x32" href="/data/ProfilLogo.png">
<link rel="icon" type="image/png" sizes="16x16" href="/data/ProfilLogo.png">
<link rel="apple-touch-icon" href="/data/ProfilLogo.png">
<link rel="shortcut icon" href="/data/ProfilLogo.png">
<script>
// Set an early auth-state class on <html> to allow CSS to style before paint (minimize flicker)
(function(){
  try {
    var authorized = localStorage.getItem('deblurr_authorized') === '1';
    var root = document.documentElement;
    root.classList.add(authorized ? 'deblurr-logged-in' : 'deblurr-logged-out');
  } catch(e){}
})();
</script>
<script src="/env.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js" defer></script>
<style>
/* Defensive: hide any legacy Browse Gallery CTA that may still be present in old hero markup */
.hero .cta-buttons a[href*="/gallery"] { display:none !important; }
/* Success-style for access-open notice (global to ensure consistent look) */
.access-open-notice {
  margin-top: 1.5rem;
  font-size: 1.05rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: 12px 16px;
  border-radius: 10px;
  background: #d4edda !important; /* light green */
  color: #155724 !important;       /* dark green text */
  border: 1px solid #c3e6cb;
  max-width: 640px;
  margin-left: auto;
  margin-right: auto;
  font-weight: 600;
}
.access-open-notice .check-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #28a745 !important; /* success green */
  color: #fff !important;
  font-weight: 700;
}
/* Legal pages styling */
.legal-page { max-width: 920px; margin: 2rem auto; line-height: 1.7; }
.legal-page h2 { font-size: 2rem; margin: 0 0 .25rem; }
.legal-meta { color:#666; margin-bottom: 1rem; }
.legal-intro { background: #fafafa; border: 1px solid #eee; border-radius: 12px; padding: 14px 16px; margin: 1rem 0 1.5rem; }
.legal-card { background: #fff; border: 1px solid #eee; border-radius: 12px; padding: 16px 18px; margin: 1rem 0; box-shadow: 0 4px 12px rgba(0,0,0,0.04); }
.legal-toc { background:#f6f8fa; border:1px solid #e6e6e6; border-radius:10px; padding: 12px 14px; margin: 1rem 0 1.25rem; }
.legal-toc strong { display:block; margin-bottom:.35rem; font-size: .98rem; color:#333; }
.legal-toc a { display:inline-block; margin:.15rem .5rem .15rem 0; color:#0b79d0; text-decoration:none; }
.legal-toc a:hover { text-decoration:underline; }
.legal-section h3 { margin-top: 1.25rem; }
.legal-note { font-size: .95rem; color:#444; }
.legal-table { width:100%; border-collapse: collapse; margin: .5rem 0 1rem; }
.legal-table th, .legal-table td { border:1px solid #e9e9e9; padding:8px 10px; text-align:left; }
.legal-table th { background:#fafafa; font-weight:600; }
.meta-chip { display:inline-block; background:#eef6ff; color:#0b79d0; border:1px solid #d6e8ff; padding:3px 8px; border-radius:999px; font-size:.85rem; }
.meta-divider { margin: 0 .5rem; color:#999; }
/* Indentation and spacing for bullet lists */
.legal-page ul, .legal-page ol { margin: .5rem 0 1rem 0; padding-left: 1.25rem; }
.legal-card ul li, .legal-card ol li { margin: .25rem 0; }
.legal-card ul { list-style: disc outside; }
.legal-card ol { list-style: decimal outside; }
/* Reduce caption font size under images by 3pt total (desktop and mobile) */
.artist-caption { font-size: 9pt !important; }
.image-card .image-title { font-size: 9pt !important; }
/* Mobile layout tweaks */
@media (max-width: 640px) {
  /* Enforce two columns for image grids used on gallery/artist/set pages */
  .artist-grid, .image-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }

  /* Gallery controls: make search full-width on its own row; controls below */
  .gallery-controls { display: grid !important; grid-template-columns: 1fr !important; gap: 10px !important; }
  .gallery-controls .artist-search-wrap { grid-column: 1 !important; justify-self: stretch !important; max-width: none !important; width: 100% !important; }
  .gallery-controls .artist-search { width: 100% !important; }
  /* Ensure the controls group stacks below and can wrap */
  .gallery-controls > div { grid-column: 1 !important; }
  .gallery-controls > div:last-child { justify-self: stretch !important; white-space: normal !important; display: flex !important; flex-wrap: wrap !important; gap: 10px !important; align-items: center !important; justify-content: flex-start !important; }

  /* Pagination: avoid wrapping the page info and improve layout */
  .pagination { flex-wrap: wrap !important; justify-content: space-between !important; gap: 8px !important; }
  .pagination span { order: 2 !important; width: 100% !important; text-align: center !important; white-space: nowrap !important; }
  .pagination .btn { flex: 1 1 calc(50% - 8px) !important; }
}

  /* When logged out, strongly fade homepage feature tiles (except Help) */
  html.deblurr-logged-out .feature-cards .feature-card:not(.feature-card-help) {
    opacity: 0.22;
    filter: grayscale(100%) saturate(60%) contrast(85%);
    transition: opacity .15s ease;
  }
  html.deblurr-logged-out .feature-cards .feature-card:not(.feature-card-help):hover {
    opacity: 0.35;
  }
  /* Keep Help and Free tiles fully visible when logged out */
  html.deblurr-logged-out .feature-card-help,
  html.deblurr-logged-out .feature-card-free { opacity: 1 !important; filter: none !important; }

  /* Hide the Free tile completely once logged in */
  html.deblurr-logged-in .feature-card-free { display: none !important; }

  /* Kill-switch: hide any legacy empty-bundle notices injected by older scripts */
  #bundle-section-empty-notice, #bundle-empty-msg { display: none !important; }
</style>
<script>
// Early access gate (client-side) – redirects if protected section without authorization
(function(){
  try {
    var p = location.pathname.replace(/\/+/g,'/');
  var protectedPrefixes = ['/gallery','/classic-art','/holidays','/all-seasons','/floral','/photos','/colors','/thema-area','/inspired-by','/verticals','/download-collections'];
    var isProtected = protectedPrefixes.some(function(pref){ return p === pref || p === pref+'/' || p.indexOf(pref + '/')===0; });
    if(!isProtected) return;
    var authorized = localStorage.getItem('deblurr_authorized') === '1';
    var bundle = localStorage.getItem('deblurr_bundle');
    if(!authorized || !bundle){
      location.replace('/access-download/');
    }
  } catch(e){ /* ignore */ }
})();

// Decorate homepage: toggle hero CTA and show unlocked message when authorized
document.addEventListener('DOMContentLoaded', function(){
  try {
    var authorized = localStorage.getItem('deblurr_authorized') === '1';
    // reflect state on body for CSS hooks
    if(authorized) document.body.classList.add('logged-in'); else document.body.classList.remove('logged-in');
    var p = location.pathname.replace(/\/+/g,'/');
    if((p === '/' || p === '') && authorized){
      var hero = document.getElementById('homeHero') || document.querySelector('.hero');
      if(hero){
        var cta = hero.querySelector('#heroAccess');
        if(cta) cta.style.display = 'none';
        if(!hero.querySelector('.access-open-notice')){
          var notice = document.createElement('div');
          notice.className = 'access-open-notice';
          var check = document.createElement('span'); check.className='check-icon'; check.setAttribute('aria-hidden','true'); check.textContent='✔';
          var label = localStorage.getItem('deblurr_bundle_label');
          var baseMsg = 'Access is unlocked. Enjoy browsing the gallery.';
          if(label) baseMsg = 'Access is unlocked for '+label+'. Enjoy browsing the gallery.';
          var text = document.createElement('span'); text.textContent=baseMsg;
          notice.appendChild(check); notice.appendChild(text);
          hero.appendChild(notice);
        }
      }
    }
    // Logout link wiring
    var logout = document.getElementById('logoutLink');
    if(logout){
      // Only show when authorized
      logout.style.display = authorized ? 'inline-block' : 'none';
      logout.addEventListener('click', function(e){
        e.preventDefault();
        try {
          localStorage.removeItem('deblurr_authorized');
          localStorage.removeItem('deblurr_bundle');
          localStorage.removeItem('deblurr_bundle_label');
          localStorage.removeItem('deblurr_bundle_suffix');
          localStorage.removeItem('deblurr_bundle_suffixes');
          // clear cookie if set
          document.cookie = 'deblurr_authorized=; Max-Age=0; path=/';
        } catch(_){}
        // Redirect to homepage and force no-cache reload
        location.replace('/');
      });
    }
  } catch(e){ /* ignore */ }
  // Ensure mobile search can be submitted via Enter and shows a Search keyboard
  try {
    var searchInputs = Array.prototype.slice.call(document.querySelectorAll('.gallery-controls .artist-search'));
    searchInputs.forEach(function(inp){
      // hint mobile keyboard
      try { inp.setAttribute('type','search'); } catch(_){}
      function doSubmit(ev){
        if(ev && ev.key && ev.key !== 'Enter') return;
        if(ev) ev.preventDefault();
        var form = inp && inp.form;
        if(!form) return;
        // reset to first page if field exists
        var pageField = form.querySelector('input[name="page"]');
        if(pageField) pageField.value = '1';
        if(typeof form.requestSubmit === 'function') form.requestSubmit(); else form.submit();
      }
      inp.addEventListener('keydown', doSubmit);
      inp.addEventListener('keyup', function(ev){ if(ev.key==='Enter') doSubmit(ev); });
    });
  } catch(e){ /* ignore */ }
  // Also remove any legacy "Browse Gallery" button if present (from stale markup)
  try {
    function removeBrowseButtons(root){
      var scope = root || document;
      scope.querySelectorAll('a').forEach(function(a){
        var txt=(a.textContent||'').trim().toLowerCase();
        var href=(a.getAttribute('href')||'').toLowerCase();
        if((/browse\s+gallery/.test(txt) || href.indexOf('/gallery')===0 || href.indexOf('://www.deblurr.com/gallery')> -1)){
          // limit to hero/cta areas to avoid breaking other cards
          var inHero = a.closest('.hero') || a.closest('.cta-buttons');
          if(inHero) a.remove();
        }
      });
    }
    removeBrowseButtons(document);
    var hero = document.querySelector('.hero');
    if(hero){
      var obs=new MutationObserver(function(muts){
        muts.forEach(function(m){ (m.addedNodes||[]).forEach(function(n){ if(n.nodeType===1) removeBrowseButtons(n); }); });
      });
      obs.observe(hero,{childList:true, subtree:true});
    }
  } catch(e){ /* ignore */ }
});
</script>
</head>
<body>
<header class="header">
  <div class="container">
    <div class="brand" style="cursor:pointer;" onclick="window.location='/'">
      <div class="logo-container">
        <img id="siteLogo" src="/data/ProfilLogo.png" alt="deBlurr" class="logo" loading="eager" />
        <div class="logo-fallback" id="logoFallback" style="display:none;">
          <span class="logo-text">dB</span>
        </div>
      </div>
      <div class="brand-text"><h1>deBlurr</h1></div>
    </div>
    <nav class="nav" id="nav">
      <a href="/">Home</a>
      <a href="/help/">Help</a>
      <a href="#" id="logoutLink" class="logout-link" aria-label="Logout">Logout</a>
    </nav>
  </div>
</header>
<main class="container">
<section class="hero" id="homeHero">
  <h2>Frame TV Art</h2>
  <p>Find beautiful images for your smart TV.</p>
  <div class="hero-access" id="heroAccess">
    <a class="btn primary btn-xl" id="enterAccessBtn" href="/access-download/">Enter Access Code</a>
  </div>
  <div id="heroUnlocked" class="access-open-notice" style="display:none;">
    <span class="check-icon" aria-hidden="true">✔</span>
    <span id="heroUnlockedText">Access is unlocked. Enjoy browsing the gallery.</span>
  </div>
</section>
<style>
/* Guard: ensure any legacy Browse Gallery link inside hero is hidden */
#homeHero a[href="/gallery/"] { display:none !important; }
/* Larger access button on hero */
.btn.btn-xl { padding: 18px 36px; font-size: 1.25rem; border-radius: 14px; }
/* Access open notice styling (match success hint style) */
.access-open-notice {
  margin-top: 1.5rem;
  font-size: 1.05rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: 12px 16px;
  border-radius: 10px;
  background: #d4edda;   /* light green */
  color: #155724;        /* dark green text */
  border: 1px solid #c3e6cb;
  max-width: 640px;
  margin-left: auto;
  margin-right: auto;
  font-weight: 600;
}
.access-open-notice .check-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #28a745; /* success green */
  color: #fff;
  font-weight: 700;
}
/* New hero access container */
.hero-access { display:flex; justify-content:center; gap:1rem; margin-top:2.5rem; }
</style>
<section class="feature-cards" aria-label="Main navigation cards">
  <!-- New: Free Images tile shows when logged out, hidden when logged in -->
  <a class="feature-card feature-card-bg feature-card-free" data-bg-key="free" href="/free-images/" aria-label="Download free images here"><h3>Download free images here</h3></a>
  <!-- Search the Gallery tile points back to /gallery/ -->
  <a class="feature-card feature-card-bg" data-bg-key="search" href="/gallery/" aria-label="Search the Gallery"><h3>Search the Gallery</h3></a>
  <a class="feature-card feature-card-bg" data-bg-key="classic-art" href="/classic-art/" aria-label="Classic Art"><h3>Classic Art</h3></a>
  <a class="feature-card feature-card-bg" data-bg-key="holidays" href="/holidays/" aria-label="Holidays &amp; Special Events"><h3>Holidays &amp; Special Events</h3></a>
  <a class="feature-card feature-card-bg" data-bg-key="all-seasons" href="/all-seasons/" aria-label="All Seasons"><h3>All Seasons</h3></a>
  <a class="feature-card feature-card-bg" data-bg-key="floral" href="/floral/" aria-label="Floral"><h3>Floral</h3></a>
  <a class="feature-card feature-card-bg" data-bg-key="photos" href="/photos/" aria-label="Photos"><h3>Photos</h3></a>
  <a class="feature-card feature-card-bg" data-bg-key="colors" href="/colors/" aria-label="Colors"><h3>Colors</h3></a>
  <a class="feature-card feature-card-bg" data-bg-key="thema-area" href="/thema-area/" aria-label="Theme Area"><h3>Theme Area</h3></a>
  <a class="feature-card feature-card-bg" data-bg-key="inspired" href="/inspired-by/" aria-label="Inspired by"><h3>Inspired by ###</h3></a>
  <a class="feature-card feature-card-help" data-bg-key="download-collections" href="/download-collections/" aria-label="Download everything here!"><h3>Download everything here!</h3></a>
  <a class="feature-card feature-card-help" data-bg-key="help" href="/help/" aria-label="Help"><h3>Help</h3></a>
</section>
</main>
<footer class="footer">
  <div class="container">
    <div class="footer-content">
      <span>&copy; 2025 deBlurr</span>
      <span class="footer-divider">|</span>
      <a href="/legal/privacy-policy.php">Privacy</a>
  <span class="footer-divider">|</span>
  <a href="/legal/cookies.php">Cookies</a>
  <span class="footer-divider">|</span>
  <a href="/legal/terms.php">Terms</a>
    </div>
  </div>
</footer>
<!-- Global Download Bar (appears when any selection exists) -->
<div id="download-bar" aria-live="polite" style="display:none;">
  <button id="download-selected">Download (0)</button>
  <button id="clear-selection" type="button">Clear</button>
  <span id="download-status" aria-live="polite"></span>
  <style>
  /* More noticeable download bar while keeping the clean style */
  #download-bar {position:fixed;left:0;right:0;bottom:0;background:rgba(255,255,255,0.96);backdrop-filter:blur(8px);padding:14px 22px;z-index:5000;box-shadow:0 -6px 18px rgba(0,0,0,0.18);font-family:system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;gap:16px;align-items:center;flex-wrap:wrap;justify-content:center;text-align:center;border-top:3px solid rgb(253,209,35);opacity:0;transform:translateY(14px);transition:opacity .28s ease,transform .28s ease,box-shadow .28s ease;}
  #download-bar.visible {display:flex !important;opacity:1;transform:translateY(0);}
  #download-bar button {cursor:pointer;border:none;border-radius:6px;font-size:15px;padding:11px 20px;line-height:1;}
  #download-selected {background:#111;color:#fff;box-shadow:0 2px 0 rgba(0,0,0,0.25);} /* subtle lift */
  #clear-selection {background:#f2f2f2;color:#222;border:1px solid #ccc;}
  #clear-selection:hover {background:#e8e8e8;}
  #download-status {font-size:13px;color:#333;margin-left:4px;min-width:90px;}
  #download-status .dl-done-icon {display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:50%;background:#1fa447;color:#fff;font-size:14px;font-weight:600;box-shadow:0 0 0 2px rgba(0,0,0,0.06);}
  /* Short attention pulse when the bar becomes visible */
  #download-bar.attention {animation:barPulse 1.2s ease-out 0s 2;}
  @keyframes barPulse {0%{box-shadow:0 -6px 18px rgba(0,0,0,0.18);}50%{box-shadow:0 -12px 28px rgba(253,209,35,0.28);}100%{box-shadow:0 -6px 18px rgba(0,0,0,0.18);}}
  #download-bar.attention #download-selected {animation:btnPulse 1s ease-out 0s 2;}
  @keyframes btnPulse {0%{box-shadow:0 2px 0 rgba(0,0,0,0.25),0 0 0 0 rgba(253,209,35,0);}50%{box-shadow:0 2px 0 rgba(0,0,0,0.25),0 0 0 10px rgba(253,209,35,0.22);}100%{box-shadow:0 2px 0 rgba(0,0,0,0.25),0 0 0 0 rgba(253,209,35,0);}}
  body.download-bar-space {padding-bottom:96px;} /* avoid overlap */
  @media (max-width:640px){ #download-bar {padding:12px 12px;} #download-bar button{padding:9px 15px;font-size:14px;} }
  </style>
</div>
<script src="/script.js?v=1757686278"></script>
<script>
// Hash -> Path migration (legacy anchors)
(function(){
  const map = {
    '#gallery':'/gallery/',
    '#home':'/',
    '#privacy':'/legal/privacy-policy.php',
    '#imprint':'/legal/privacy-policy.php'
  };
  if(location.hash && map[location.hash]){
    const t = map[location.hash];
    history.replaceState(null,'',t);
  }
})();

// Global persistent selection logic
(function(){
  const STORAGE_KEY = 'deblurrSelectionV1';
  const bar = document.getElementById('download-bar');
  const btnDownload = document.getElementById('download-selected');
  const btnClear = document.getElementById('clear-selection');
  const statusEl = document.getElementById('download-status');
  const btnCollapse = null; // removed
  if(!bar || !btnDownload || !btnClear) return; // nothing to do
  const selected = new Set();
  function load(){
    try { const raw = localStorage.getItem(STORAGE_KEY); if(!raw) return; const arr=JSON.parse(raw); if(Array.isArray(arr)) arr.forEach(v=>{ if(typeof v==='string') selected.add(v); }); }
    catch(e){ console.warn('Selection load fail', e); }
  }
  function save(){ try { localStorage.setItem(STORAGE_KEY, JSON.stringify(Array.from(selected))); } catch(e){} }
  function updateBar(){
    const wasVisible = bar.classList.contains('visible');
    btnDownload.textContent = 'Download ('+selected.size+')';
    if(selected.size>0){
      bar.classList.add('visible');
      document.body.classList.add('download-bar-space');
      if(!wasVisible){
        // brief attention pulse when first shown
        bar.classList.add('attention');
        setTimeout(()=> bar.classList.remove('attention'), 1600);
      }
    } else {
      bar.classList.remove('visible');
      document.body.classList.remove('download-bar-space');
      statusEl.textContent='';
    }
  }
  function syncCheckboxes(){
    document.querySelectorAll('.artwork-select-checkbox').forEach(cb=>{
      const val = cb.value || cb.getAttribute('data-img');
      cb.checked = selected.has(val);
      if(!cb.__bound){
        cb.addEventListener('change', ()=>{
          const v = cb.value || cb.getAttribute('data-img');
          if(cb.checked) selected.add(v); else selected.delete(v);
          save(); updateBar();
        });
        cb.addEventListener('click', e=>e.stopPropagation(), true);
        cb.__bound = true;
      }
    });
  }
  async function fetchBlob(u){ const r=await fetch(u); if(!r.ok) throw new Error('HTTP '+r.status); return await r.blob(); }
  async function doZip(){
    if(selected.size===0) return;
    if(typeof JSZip==='undefined'){ statusEl.textContent='ZIP library missing'; return; }
    const zip = new JSZip();
    const list = Array.from(selected); let i=0; statusEl.textContent='Preparing...';
    for(const url of list){
      i++; statusEl.textContent='Fetching '+i+'/'+list.length;
      try { const b=await fetchBlob(url); const name=(url.split('/').pop()||'file').replace(/\?.*$/,''); zip.file(name,b); }
      catch(err){ console.error('Fetch fail',url,err); }
    }
    statusEl.textContent='Zipping...';
    const blob = await zip.generateAsync({type:'blob'});
    const a=document.createElement('a');
    a.href=URL.createObjectURL(blob);
    const d=new Date(); const pad=n=>String(n).padStart(2,'0');
    a.download=`deblurr-${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())}-${pad(d.getHours())}-${pad(d.getMinutes())}.zip`;
    document.body.appendChild(a); a.click();
  setTimeout(()=>{ URL.revokeObjectURL(a.href); a.remove(); statusEl.innerHTML='<span class="dl-done-icon" aria-label="Download complete">✓</span>'; },600);
  }
  btnDownload.addEventListener('click', e=>{ e.preventDefault(); doZip().catch(err=>{ console.error(err); statusEl.textContent='Error: '+err.message; }); });
  btnClear.addEventListener('click', ()=>{ selected.clear(); save(); syncCheckboxes(); updateBar(); });
  if(btnCollapse){ btnCollapse.addEventListener('click', ()=>{ bar.classList.remove('visible'); document.body.classList.remove('download-bar-space'); }); }
  // Observe DOM changes (if navigation injects new content dynamically)
  const mo = new MutationObserver(()=> syncCheckboxes());
  mo.observe(document.body,{subtree:true,childList:true});
  load(); syncCheckboxes(); updateBar();
  console.log('[GlobalDownload] Active, items:', selected.size);
})();
</script>
<script>
// Global bundle filter: hide images whose caption doesn't end with the active bundle suffix (e.g. (6k))
(function(){
  try {
    // Skip bundle filtering on public Free Images page
    try { if (location && /\/free-images(\/|$)?/.test(location.pathname)) return; } catch(_){}
    var authorized = localStorage.getItem('deblurr_authorized') === '1';
    var suffixes = [];
    try {
      var multi = localStorage.getItem('deblurr_bundle_suffixes');
      if(multi){ var arr = JSON.parse(multi); if(Array.isArray(arr)) suffixes = arr.map(function(s){ return String(s||'').toLowerCase(); }); }
    } catch(_){ }
    if(suffixes.length===0){
      var single = (localStorage.getItem('deblurr_bundle_suffix') || '').toLowerCase();
      if(single) suffixes = [single];
    }
    if(!authorized || suffixes.length===0) return;
    function applyFilter(root){
      var cards = (root||document).querySelectorAll('.artist-image-wrap');
      var visibleCount = 0;
      cards.forEach(function(card){
        var cap = card.querySelector('.artist-caption');
        var title = (cap && cap.textContent || '').trim();
        var low = title.toLowerCase();
        var show = suffixes.some(function(suf){ return low.endsWith(suf); });
        if(!show){
          // Try derive filename from link href as fallback
          var a = card.querySelector('a.artist-image');
          var href = a ? a.getAttribute('href') : '';
          if(href){
            try {
              var fn = href.split('/').pop() || '';
              var base = fn.replace(/\.[a-z0-9]+$/i,'').toLowerCase();
              show = suffixes.some(function(suf){ return base.endsWith(suf); });
            } catch(_){ }
          }
        }
        card.style.display = show ? '' : 'none';
        if(show) visibleCount++;
      });
      // If grid becomes empty, show a friendly message
      var grid = (root||document).querySelector('.artist-grid, .image-grid');
      if(grid){
        // Remove any previously injected empty-state message; do not show any notice
        var existing = document.getElementById('bundle-empty-msg');
        if(existing){ existing.remove(); }
      }
    }
    if(document.readyState === 'loading'){
      document.addEventListener('DOMContentLoaded', function(){ applyFilter(); });
    } else { applyFilter(); }
    // Observe dynamic changes and re-apply
    var mo = new MutationObserver(function(muts){
      for(var i=0;i<muts.length;i++){
        var m = muts[i];
        for(var j=0;j<m.addedNodes.length;j++){
          var n = m.addedNodes[j];
          if(n.nodeType===1){ applyFilter(n); }
        }
      }
    });
    mo.observe(document.body,{subtree:true,childList:true});
  } catch(e){ /* ignore */ }
})();
</script>
<script>
// Essential cookie notice as centered modal box with overlay. No tracking; uses localStorage for dismissal.
(function(){
  try {
    var KEY='deblurr_cookie_notice_dismissed_v1';
    if(window.localStorage && localStorage.getItem(KEY)==='1') return;

    function dismiss(){
      try{ localStorage.setItem(KEY,'1'); }catch(_){ }
      if(overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay);
      document.removeEventListener('keydown', onKey);
    }

    function onKey(ev){ if(ev.key==='Escape'){ dismiss(); } }

    var overlay=document.createElement('div');
    overlay.id='cookie-overlay';
    overlay.style.cssText=[
      'position:fixed','inset:0','background:rgba(0,0,0,.45)','z-index:2147483000',
      'display:flex','align-items:center','justify-content:center','padding:16px'
    ].join(';');

    var modal=document.createElement('div');
    modal.id='cookie-banner';
    modal.setAttribute('role','dialog');
    modal.setAttribute('aria-modal','true');
    modal.setAttribute('aria-label','Cookie notice');
    modal.style.cssText=[
      'background:#fff','color:#222','max-width:560px','width:100%','border-radius:12px',
      'box-shadow:0 10px 40px rgba(0,0,0,.25)','padding:16px 18px','font-size:.98rem','line-height:1.55',
      'font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif'
    ].join(';');

    var msg=document.createElement('div');
    msg.innerHTML='We only use an essential cookie to remember that you unlocked the gallery. No analytics. '+
      '<a href="/legal/privacy-policy.php" style="color:#0b79d0;text-decoration:underline">Learn more</a>';

    var actions=document.createElement('div');
    actions.style.cssText=['display:flex','gap:10px','justify-content:flex-end','margin-top:12px'].join(';');
    var ok=document.createElement('button');
    ok.type='button'; ok.textContent='OK';
    ok.setAttribute('aria-label','Dismiss cookie notice');
    ok.style.cssText=[
      'background:#111','color:#fff','border:none','padding:.6rem 1rem','border-radius:8px',
      'cursor:pointer','font-weight:600'
    ].join(';');
    ok.addEventListener('click', dismiss);

    actions.appendChild(ok);
    modal.appendChild(msg);
    modal.appendChild(actions);
    overlay.appendChild(modal);

    if(document.readyState==='loading'){
      document.addEventListener('DOMContentLoaded',function(){ document.body.appendChild(overlay); setTimeout(function(){ try{ ok.focus(); }catch(_){ } }, 0); });
    } else {
      document.body.appendChild(overlay); setTimeout(function(){ try{ ok.focus(); }catch(_){ } }, 0);
    }

    document.addEventListener('keydown', onKey);
  } catch(e) { /* noop */ }
})();
</script>
<script>
// Section-level bundle availability enforcement: if a section has no items for the active bundle, redirect to Home
(function(){
  async function loadIndex(){
    const urls=['/assets/search_index.json','/dist/assets/search_index.json','/search_index.json','assets/search_index.json','search_index.json'];
    for(const u of urls){ try{ const r=await fetch(u+(u.includes('?')?'&':'?')+'v='+Date.now(),{cache:'no-store'}); if(r&&r.ok){ const t=await r.text(); const s=(t||'').trim(); if(s && (s.startsWith('{')||s.startsWith('['))) return JSON.parse(s); } }catch(_){} }
    return null;
  }
  function pathToFolder(pathname){
    // Match actual Collection subfolder names
    const map=[
      {p:'/classic-art', f:'Classic Art/'},
      {p:'/holidays', f:'Holidays and Special Events/'},
      {p:'/all-seasons', f:'All Seasons/'},
      {p:'/floral', f:'Floral/'},
      {p:'/photos', f:'Photos/'},
      {p:'/colors', f:'Colors/'},
      {p:'/thema-area', f:'Theme Area/'},
  {p:'/inspired-by', f:'Inspired by ###/'},
  {p:'/verticals', f:'Verticals/'}
    ];
    const p = pathname.replace(/\/+/g,'/');
    for(const m of map){ if(p===m.p || p.startsWith(m.p+'/')) return (m.f||''); }
    return '';
  }
  async function enforce(){
    try{
  var authorized = localStorage.getItem('deblurr_authorized')==='1';
  var suffixes = [];
  try{ var multi = localStorage.getItem('deblurr_bundle_suffixes'); if(multi){ var arr=JSON.parse(multi); if(Array.isArray(arr)) suffixes = arr.map(function(s){ return String(s||'').toLowerCase(); }); } }catch(_){ }
  if(suffixes.length===0){ var single=(localStorage.getItem('deblurr_bundle_suffix')||'').toLowerCase(); if(single) suffixes=[single]; }
  if(!authorized || suffixes.length===0) return;
      const folder = pathToFolder(location.pathname);
      if(!folder) return; // not a protected content section or homepage
      const idx = await loadIndex();
      if(!idx) return;
      const items = Array.isArray(idx.i)? idx.i: (Array.isArray(idx)? idx: []);
      const has = items.some(function(it){
        const t = String(it.t||'').toLowerCase();
        const pFull = String(it.p||'');
        const p = pFull.toLowerCase();
        const fn = pFull.split('/').pop() || '';
        const base = fn.replace(/\.[a-z0-9]+$/i,'').toLowerCase();
        const ok = suffixes.some(function(suf){ return t.endsWith(suf) || base.endsWith(suf); });
        if(!ok) return false;
        return p.indexOf(folder.toLowerCase()) !== -1;
      });
      if(!has){
        // Do not redirect and do not show any notice to avoid confusion
        return;
      }
    }catch(e){ /* ignore */ }
  }
  function onReady(){
    // Avoid enforcing on the homepage or when tiles may still be loading
    enforce();
  }
  if(document.readyState==='loading') document.addEventListener('DOMContentLoaded', onReady); else onReady();
})();
</script>
</body>
</html>
<script>
// Hard-remove any legacy "Browse Gallery" anchor inside hero and keep it gone
document.addEventListener('DOMContentLoaded', function(){
  var hero = document.getElementById('homeHero');
  if(!hero) return;
  hero.querySelectorAll('a').forEach(a=>{
    if(/browse\s+gallery/i.test(a.textContent) || a.getAttribute('href')==='/gallery/') a.remove();
  });
  const obs=new MutationObserver(muts=>{
    muts.forEach(m=>{ (m.addedNodes||[]).forEach(n=>{ if(n.nodeType===1){ const a=n.matches? n: null; const list=(a && a.tagName==='A')? [a]: n.querySelectorAll? n.querySelectorAll('a'):[]; list.forEach(el=>{ if(/browse\s+gallery/i.test(el.textContent||'') || el.getAttribute('href')==='/gallery/'){ el.remove(); } }); } }); });
  });
  obs.observe(hero,{childList:true, subtree:true});
});

// Toggle hero CTA vs unlocked notice based on authorization and show bundle label
(function(){
  try {
    var authorized = localStorage.getItem('deblurr_authorized') === '1';
    var cta = document.getElementById('heroAccess');
    var notice = document.getElementById('heroUnlocked');
    var txt = document.getElementById('heroUnlockedText');
    if(cta && notice){
      if(authorized){
        cta.style.display='none'; notice.style.display='flex';
        try {
          var label = localStorage.getItem('deblurr_bundle_label');
          if(label && txt){ txt.textContent = 'Access is unlocked for '+label+'. Enjoy browsing the gallery.'; }
        } catch(_){ }
      }
      else { cta.style.display='flex'; notice.style.display='none'; }
    }
  } catch(e){}
})();

// Note: We no longer hide any homepage tiles here (to avoid flicker).
// Access control is enforced on target pages via redirects.

// When a bundle is active, we currently DO NOT hide tiles automatically based on index
// to avoid false negatives while bundle markers are being rolled out.
// This block is kept for future use and can be re-enabled once coverage is complete.
(function(){
  const ENABLE_TILE_GATING = false;
  if(!ENABLE_TILE_GATING) return;
  async function loadIndex(){
    const urls = ['/assets/search_index.json','/dist/assets/search_index.json','/search_index.json','assets/search_index.json','search_index.json'];
    for (const u of urls){
      try {
        const r = await fetch(u + (u.includes('?')?'&':'?') + 'v=' + Date.now(), {cache:'no-store'});
        if(r && r.ok){ const t=await r.text(); if(t && (t.trim().startsWith('{')||t.trim().startsWith('['))) return JSON.parse(t); }
      } catch(_){ }
    }
    return null;
  }
  function tileToFolder(key){
    // Match real subfolder names inside Collection/
    const map = {
      'classic-art': 'collection/classic art/',
      'holidays': 'collection/holidays and special events/',
      'all-seasons': 'collection/all seasons/',
      'floral': 'collection/floral/',
      'photos': 'collection/photos/',
      'colors': 'collection/colors/',
      'thema-area': 'collection/theme area/',
      'inspired': 'collection/inspired by ###/'
    };
    return map[key] || '';
  }
  async function applyTileGating(){
    try {
  var authorized = localStorage.getItem('deblurr_authorized') === '1';
  var suffixes=[]; try{ var multi=localStorage.getItem('deblurr_bundle_suffixes'); if(multi){ var arr=JSON.parse(multi); if(Array.isArray(arr)) suffixes=arr.map(function(s){return String(s||'').toLowerCase();}); } }catch(_){ }
  if(suffixes.length===0){ var single=(localStorage.getItem('deblurr_bundle_suffix')||'').toLowerCase(); if(single) suffixes=[single]; }
  if(!authorized || suffixes.length===0) return;
      const data = await loadIndex();
      if(!data) return;
      const items = Array.isArray(data.i)? data.i: (Array.isArray(data)?data:[]);
      if(!items || !items.length) return;
      // Overall availability for search tile
      const hasAny = items.some(it => {
        const t = String(it.t||'').toLowerCase();
        const p = String(it.p||'');
        const fn = p.split('/').pop() || '';
        const base = fn.replace(/\.[a-z0-9]+$/i,'').toLowerCase();
        return suffixes.some(function(suf){ return t.endsWith(suf) || base.endsWith(suf); });
      });
      if(!hasAny){
        var searchTile = document.querySelector('.feature-card[data-bg-key="search"]');
        if(searchTile) searchTile.style.display = 'none';
      }
      // Per-tile gating
      const keys = ['classic-art','holidays','all-seasons','floral','photos','colors','thema-area','inspired'];
      keys.forEach(function(key){
        const pref = tileToFolder(key);
        if(!pref) return;
        const has = items.some(function(it){
          const t = String(it.t||'').toLowerCase();
          const pFull = String(it.p||'');
          const p = pFull.toLowerCase();
          const fn = pFull.split('/').pop() || '';
          const base = fn.replace(/\.[a-z0-9]+$/i,'').toLowerCase();
          const titleOk = suffixes.some(function(suf){ return t.endsWith(suf) || base.endsWith(suf); });
          return titleOk && p.indexOf(pref) !== -1;
        });
        if(!has){
          var tile = document.querySelector('.feature-card[data-bg-key="'+key+'"]');
          if(tile) tile.style.display = 'none';
        }
      });
    } catch(e){ /* ignore */ }
  }
  if(document.readyState==='loading') document.addEventListener('DOMContentLoaded', applyTileGating); else applyTileGating();
})();
</script>
